1

I am an A-level student writing his coursework for computing. A small part of my codes takes in inputs are turns them into a time. 8 o'clock in the morning is shown like this: 08 , Because that's how SQLite likes it. However when converting it into a date I get the error message in the title:

_tkinter.TclError: expected floating-point number but got "08" (looks like invalid octal number)

This also happens with 09 , but not with 06 or 07.

Code:

variable_start = IntVar(root)
variable_start.set("Select Start Time")

option_add_start =  ttk.Combobox(window1, textvariable = variable_start,width = 20, state = 'readonly')
option_add_start['values'] = ("06", "07", "08", "09", "10", "11", "12", "13", "14", "15",
"16", "17", "18","19", "20")

hour1 = variable_start.get()
min1 = variable_start_min.get()
starttimehour = str(datetime.time(hour1,min1,second))

Is it something to do with my datatype? I'm not to sure how to fix it.

Mia
  • 2,466
  • 22
  • 38
coder188642
  • 145
  • 2
  • 5
  • 15
  • Can you please post your full code, including how you defined the variables `hour1`, `min1` etc.? – Mia Apr 14 '17 at 13:26
  • @pkqxdd both hour1 and min1 aren't specifically defined as a certain datatype, so I'm guessing they are characters. My code isn't very tidy, and this is what is causing the problem I think. This is only part of my program, with other modules not affecting this, but if you would like my full code then ill provide a link to it as its very long. – coder188642 Apr 14 '17 at 15:34
  • Are you 100% sure you're working in Python 3.x? Python 2 had `0` as a prefix representing octal numbers (see [here](http://stackoverflow.com/questions/11620151/what-do-numbers-starting-with-0-mean-in-python)), but 3.x does not recognize this form as valid (it instead uses `0o` for octal). – Delioth Apr 14 '17 at 20:31
  • @Delioth Yes, I am 100% working in python 3, python 3.6.1 to be excact. – coder188642 Apr 15 '17 at 13:12

2 Answers2

2

It's your IntVar. I don't know if it's a bug or for backwards compatibility, but IntVar.get() does type conversion for you. In Python 2, numbers prefixed by 0 would be interpreted in octal (i.e. 010 equals 8). You're setting the value just fine, but it blows up when it tries to get() "08".

Searching through the code, the problem stems from the actual Tcl interpreter, since the get() method is sent to the Tcl interpreter as globalgetvar(), and from there it's not even interpreted by Python. In reality, it isn't even a bug- Tcl is supposed to recognize 0### as octal, and this is considered one of the gotcha's of the language.

The proper workaround for this problem is to use a good data access object- use it to send and retrieve data to and from sqlite. This way you can encapsulate code to transform an integer 8 to the 08 that sqlite wants. The slightly more hacky way is to call a single function before you send data to sqlite, which looks something like:

anInt = variable_start.get()
serialInt = serialize(anInt)
send_to_sqlite(serialInt) // I've not worked with SQLite, so this line is pseudocode.

serialize(int):
    new = str(int)
    if(new < 10):
        new = "0" + new
    return new
Delioth
  • 1,564
  • 10
  • 16
  • Thanks you for the explanation, it really helped. I modified some of your code to make it easier to understand for me, but it didn't change the way it worked. I was also getting some errors, so changed the str(int) to 2 different commands, as making it a string before comparing it to an integer didn't work, so I converted it to a string if it met the conditions, by thanks! – coder188642 Apr 16 '17 at 11:48
0

Instead of:

variable_start = IntVar(root)

Use:

variable_start = StringVar(root)

That way there is no problem, because it is clear in advance that it is a string and not an integer.

Then, when you want to use the number data, convert that string to an integer using the standard string to integer conversion function - int.

For example:

hour1 = int(variable_start.get())
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83