I’ve got this code from GitHub that prints out bingo cards based on song titles. I try to run the script but I get this error and can’t work out why:
TypeError: integer argument expected, got float
The line that’s bringing up the error is:
sheet.insert(math.ceil(len(sheet)/2), center_figure)
Is the problem with the center_figure image file?
The full code is below.
import random
import csv
import math
numbersheets = 300
gridsize = 5
stepping = 16
save_path = './cards.html'
input_file = './disco_bingo_1.csv'
center_figure = '<img src="https://raw.githubusercontent.com/florisdenhengst/music-bingo/master/center-img-small.png"/>'
input_words = []
input_ids = []
with open(input_file, 'r') as f:
r = csv.reader(f, delimiter=',', quotechar='"')
_ = next(r)
for row in r:
input_words.append(row[2])
input_ids.append(row[1])
print('Creating bingo cards for: ' + str(len(input_words)) + ' words')
n_words = len(input_words)
words = []
for i, w in enumerate(input_words):
words.append('{}: {}'.format(input_ids[i], w))
sheets = set()
with open(save_path, 'w') as f:
f.write("<html>")
f.write("""
<head>
<style>
td {
width: 120px;
height: 50px;
padding: 2px;
overflow: hidden;
text-align: center;
vertical-align: middle;
border: 1px solid black;
font-size: 9pt;
font-family: Arial, Helvetica, sans-serif;
}
img {
max-height: 50px;
}
br.space{
margin-top: 70px;
}
@media print{
br.page{
page-break-before: always;
}
}
</style>
</head>
<body>
""")
for i in range(numbersheets):
f.write('\n')
bingosheet = []
duplicate = True
while duplicate:
sheet = random.sample(words, gridsize**2 - 1)
o_sheet = '~'.join(sheet)
duplicate = o_sheet in sheets
if duplicate:
print('Duplicate, retrying')
sheets.add(o_sheet)
sheet.insert(math.ceil(len(sheet)/2), center_figure)
f.write("<table>")
f.write("<tr>")
bingo = ["<th>{}</th>".format(l) for l in list('BINGO')]
for th in bingo:
f.write(th)
f.write("</tr>")
for r in range(gridsize):
f.write("<tr>")
for c in range(gridsize):
cell = r * gridsize + c
cell = sheet[cell]
columnstring = '<td>' + cell + "</td>"
f.write(columnstring)
f.write("</tr>\n")
f.write("</table>")
if (i+1) % 2 == 0:
f.write("<br class='page'/>")
else:
f.write("<br class='space'/>")
f.write("\n")
>Solution :
You must be running Python 2.X rather than 3.x, in which case you have to add a cast to convert a float to an int to solve your problem.
What the error message is saying is that some function being called in that line is expecting an int but is getting a float. Three functions are being called. len is being passed a list.
math.ceil() accepts a float. insert expects an int as its first parameter, so it must be the insert call that is causing this problem, and it must be the case that math.ceil() is returning a float.
But in Python 3, math.ceil() returns an int, so this can’t be the problem either. So this particular line of code can’t throw that error if you are running Python 3.X. However, in Python 2, math.ceil() returns a float. So you must be running Python 2.
Any 2.X version of Python is very old and is no longer maintained. In general, you should upgrade to Python 3.X, which might require some changes to your code.
But, for now, all you have to do is cast the result of the call to math.ceil() to an int:
sheet.insert(int(math.ceil(len(sheet)/2)), center_figure)
This version of the line should work with any version of Python.
The reason for this change is that in Python 2, the float type can store larger integer values than the int type can. So math.ceil() returns a float to avoid this issue when it was passed a vary large value. In Python 3, int values have no maximum size, so it then makes sense to have math.ceil() return an int.