Reputation: 190
I've been asked to write a simulator, the end goal being to see how much ink ends up on a cylinder at the end of a chain of maybe 15 or so rollers. I'm currently trying to set-up a dictionary which defines the rollers. From this i wanted to write a function which will take user input, 'roller_diameter', find the ratio of the given diameter to a fixed diameter and convert this into an integer number of 'segments'. I'm not a programmer (i'm learning Python[2.7] using internet resources) and am struggling with the TypeError: can't multipy sequence by non-int type 'float' I'm sure this is a trivial issue and I have looked at the related answers but have been unable to understand what specifically I'm doing wrong...Any suggestions would be greatly appreciated, here's the code (with only a few 'rollers'), please don't laugh...
Rubber = True
Copper = False
CW = 1
ACW = -1
num_rollers = 4
plate_diameter = 406.4
rollers = [{} for i in range(num_rollers)]
rollers[0] = {'top_seg': 0, 'roller_diameter': [], 'segments': [], 'material': Copper, 'direction': ACW, 'ink': []}
rollers[1] = {'top_seg': 0, 'roller_diameter': [], 'segments': [], 'material': Rubber, 'direction': CW, 'ink': []}
rollers[2] = {'top_seg': 0, 'roller_diameter': [], 'segments': [], 'material': Copper, 'direction': ACW, 'ink': []}
rollers[3] = ['top_seg': 0, 'roller_diameter': [], 'segments': [], 'material': Rubber, 'direction': CW, 'ink': []}
R = rollers[i]
def roller_data():
global roller_diameter
roller_diameter = float(raw_input("Enter the roller diameter" + str(i) + ': '))
for i in range(num_rollers):
roller_data()
R['segments'] = int(round(rollers[3]['segments']*roller_diameter/plate_diameter))
R['angle'] = (360.0/R['segments'])
print rollers[3]['segments']
The TraceBack is:
Traceback (most recent call last):
File "\\datasvr\users\rioliver\Python2.7\dict_test_v2.py", line 24, in <module>
R['segments'] = int(round(rollers[3]['segments']*roller_diameter/plate_diameter))
TypeError: can't multiply sequence by non-int of type 'float'
When you run this code it doesn't matter what you enter for diameter (I have been using 85, 95, 110, 120) but it makes no difference what numbers are used. I would like it to take any number (integer or floating point) and round any floating points.
Upvotes: 1
Views: 3684
Reputation: 353409
In this line:
R['segments'] = int(round(rollers[3]['segments']*roller_diameter/plate_diameter))
You take rollers[3]['segments']
, multiply it by roller_diameter
, and then divide by plate_diameter
. This gives you the error message
TypeError: can't multiply sequence by non-int of type 'float'
This tells me that you're trying to multiply a sequence -- say, a list or a tuple -- by a float. And if I understand correctly, rollers[3]['segments']
is still an empty list, and you're trying to multiply it by roller_diameter
, which is a float. I'm not sure what you're trying to do here, because you never assign anything to the segments
key, as near as I can tell.
Some other notes:
rollers[3] = ['top_seg': 0, 'roller_diameter': [], 'segments': [], 'material': Rubber, 'direction': CW, 'ink': []}
This line gives a SyntaxError, so obviously it's not the code you ran. Please always copy and paste the code you actually ran into the box, otherwise people have to distinguish between "the bugs in the OP's code" and "the bugs in how the OP edited the code on StackOverflow".
R = rollers[i]
I think you think this means that R
will now always point to the i
-th element in rollers
, but that's not how Python works. What it means is "tell the name R
that it now refers to whatever object rollers[i]
currently describes". i
is 3 at this point (a leftover from the list comprehension you used), so R = rollers[3]
. If you change for i in range(num_rollers)
to for j in..
, you'll get
R = rollers[i]
NameError: name 'i' is not defined
because it's trying to get the value of i
at that moment, and there is no i
.
def roller_data():
global roller_diameter
print i
roller_diameter = float(raw_input("Enter the roller diameter" + str(i) + ': '))
You don't need a global variable here. If you want to make the input a function, just return a value:
def read_diameter(i):
return float(raw_input("Enter the roller diameter # {}: ".format(i)))
and then assign it somewhere when you get it back, like
rollers[i]['roller_diameter'] = read_diameter(i)
and use that value in the calculation, not the global roller_diameter
.
I think there's an indentation error in your last few lines and you wanted the R['segments']
bit to be indented -- but then you hardcode rollers[3]
rather than use rollers[i]
, so maybe I'm wrong -- but remember that your R
is always rollers[3]
. Either use rollers[i]
in the loop or set R = rollers[i]
inside the loop so that that line is getting a new value of i
each time it executes.
Upvotes: 2
Reputation: 1516
The Error output is showing
R['segments'] = int(round(rollers[i]['segments']*roller_diameter/plate_diameter))
where as in your code you have R['segments'] = float(round(rollers[3]['segments']*roller_diameter/plate_diameter))
Are you, perhaps, running the correct or the most up to date version of your code? Is the code chunk you have here the same as the code that you are getting this error from?
Regards
Upvotes: 0