-1

So this is pretty simple I', sure I just can't seem to figure it out.

Using Tk module to create a GUI, I have an entry field that requires a float input to do math with.

At the moment I get this error

floatval1 = float(val1)

could not convert string to float

The code section looks like this:

val1 = entry1.get()
val2 = entry2.get()
floatval1 = float(val1)
floatval2 = float(val2)
formula12 = (((((((floatval1/100)*(floatval2)/100))*86.67)+bevel+44)*2.4)*1.1)
bevel = (((floatval1/100)*2)+((floatval2/100)*2))*3.5
glprice12 = formula12 + bevel

Obviously I've tried to convert the entry fields, entries to a float so it can be used in this formula.

I cant see a reason why it would not allow this, any help would be greatly appreciated.

Kind Regards,

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
LMCT
  • 43
  • 6
  • 3
    `print val1` and tell us what you see (a wild guess - it is **not** a string that can represent a floating-point value, nor can it represent a fixed-point value). – barak manos Aug 15 '14 at 10:54
  • Sorry im not sure i follow. printing val1 will give nothing as the program is not running and the entry field has nothing inputted. – LMCT Aug 15 '14 at 10:56
  • 1
    What's there to follow??? Add `print val1` after `val1 = entry1.get()`, and tell what what you see. – barak manos Aug 15 '14 at 10:56
  • @LMCT after the `val1 = ...` and `val2 = ...` lines, add `print val1, val2`, then run the program. That will show you what is in the fields. When it crashes, you will see the values that make it crash. – will Aug 15 '14 at 10:58
  • added "print val1" and got invalid syntax... fml – LMCT Aug 15 '14 at 11:01
  • 2
    Let's put in in simple words (as simple as can possibly be conceived in this case): `could not convert string to float` - why on earth would someone not be able to convert a string into a float? Hmmmm.... let's try a few wild guesses: 1. The string does not represent a numeric value. 2. Hmmmm... well... I kinda ran out of guesses... Why don't we print that string and try to understand what's this all about then??? – barak manos Aug 15 '14 at 11:01
  • Add it in a separate row, and make sure that the indentation of that row is correctly aligned with the rest of your code. Oh, and use regular spaces, not tabs. – barak manos Aug 15 '14 at 11:02
  • 1
    @LMCT In Python3 it's `print(val1)` – Tobias Kienzler Aug 15 '14 at 11:03
  • "printing val1 will give nothing as the program is not running and the entry field has nothing inputted." Then exactly what value are you expecting to get when you convert the contents of the field to float, if there are no contents yet? – Karl Knechtel Aug 15 '14 at 11:03
  • I bet this has to do with the locale, i.e. using `,` instead of `.` as decimal separator. Or some whitespace that shouldn't be there – Tobias Kienzler Aug 15 '14 at 11:04
  • Put it in between `val1 = entry1.get()` and `floatval1 = float(val1)`. – barak manos Aug 15 '14 at 11:04
  • Tried this:- val1 = (entry1.get()) val2 = (entry2.get()) print(val1) floatval1 = float(val1) same error message. I will admit im new to python, and perhaps its trying to float a value for variable that doesnt have any figure assigned yet, which it doesnt, but when i press a button and it executes this formula i need it to take the values from the user entry fields as floats. – LMCT Aug 15 '14 at 11:08
  • 1
    It's unrelated to the question, but i'd really advise getting rid of as many of those brackets as possible, it makes the maths very difficult to follow. – will Aug 15 '14 at 11:12
  • I tried, tbh i was kinda lazy and basically copied out the formula from my excel spreadsheet. but i think without the parentheses it gives the wrong figure output. Unless you have any suggestions. – LMCT Aug 15 '14 at 11:14
  • @KarlKnechtel Is locale not taken into account? I once had this exact issue with java, but the problem was someone in germany was entering "0.123" when they should have been entering "0,123" - it was reversed from how i'd have expected it to be, java got the correct locale, but they decided to use the wrong one! Does python deal with locale settings for you? or is it `.` decimal points everywhere (unless you're using the `locale` module)? – will Aug 15 '14 at 11:18
  • `formula12 = 2.4 * 1.1 * (bevel + 44 + 86.67 * floatval1 * floatval2 / 10000)` and `bevel = 3.5 * 2 * (floatval1 + floatval2) / 100` – will Aug 15 '14 at 11:18
  • i just realised, you also need to move the definition of `bevel` above that of `formula12`, or it will be undefined when it gets there. – will Aug 15 '14 at 11:19
  • @LMCT the `print` should really output something before the conversion error. Did you check the _entire_ console output? – Tobias Kienzler Aug 15 '14 at 11:19
  • I have asked it to print values but will print nothing as nothing is present in the value because the entry field has nothing in it. – LMCT Aug 15 '14 at 11:23
  • @will thankyou that helps, i hope it provides the same answer still. Im thinking that there must be a better tkinter module for receiving numbers rather than just text, unless there is a way to specify the entry form to only accept numbers, or if there is a way to have the default entry as a figure so that it can always be convert to float? – LMCT Aug 15 '14 at 11:31
  • *facepalm* that's your problem. you really shouldn't be running this code unless the boxes have numbers in them. – will Aug 15 '14 at 11:31
  • @will how can i make the boxes have numbers in them if the program wont even launch, and as far as i know there is no way to make the entry forms have a default figure – LMCT Aug 15 '14 at 11:33
  • @LMCT you need to validate the fields, [here](http://wiki.tcl.tk/768) is what you're after. – will Aug 15 '14 at 11:34
  • @LMCT the program shouldn't be running this code until it needs to, you should probably make it so this function is only run when the user has finished editing the box. – will Aug 15 '14 at 11:36
  • @will That sounds right, how would i go about doing that? – LMCT Aug 15 '14 at 11:37
  • i've never used tkinter, only `PySide` and `Qt` (which imo are superior, but that's another topic) – will Aug 15 '14 at 11:51
  • I have managed to resolve the issue by pushing all float related calculations to the button command lines. Thereby not being executed until the entry forms are filled, which seems to work, except now i have annoying little { } encapsulating each piece of information which is diabolically annoying as i cant seem to get rid of them. – LMCT Aug 15 '14 at 12:09

3 Answers3

2

Are you certain that the strings contained by your input fields are valid numbers?

That is, input fields normally start out as empty. If you try to parse an empty string ("") as a number then you will get an error. What number does "" represent?

It's possible that the string in the field is not a valid number so you should right code for that possibility.

eg.

import tkMessageBox

...

# in your function
val1 = entry1.get()
val2 = entry2.get()
try:
    floatval1 = float(val1)
    floatval2 = float(val2)
except ValueError:
    message = "Either val1 ({!r}) or val2 ({!r}) is not a valid number".format(val1, 
        val2)
    print("Error!", message)
    tkMessageBox.showerror("Invalid Inputs", message)
    return # or reraise the error or something sensible
# continue rest of function as normal
Dunes
  • 37,291
  • 7
  • 81
  • 97
  • Well this is just it, this execution would only happen once the program was open and once someone had inputted figures, the entry field before the program is open, i presume is '' and therefore cannot be converted into a float. after following your instruction, attempting to run the program immediately provides the error message. which it would do because it cant seem to convert nothing into a float, is there a way to set the entry fields with a default value to circumvent this? – LMCT Aug 15 '14 at 11:20
  • @LMCT what you want is to `validate` the fields. It's easy in `Qt` (which has python bindings, but in `tk`, it doesn't seem to be the case - look [here](http://stackoverflow.com/questions/4140437/python-tkinter-interactively-validating-entry-widget-content). – will Aug 15 '14 at 11:32
  • It would be better to find out why the function is running if the user hasn't clicked the submit/enter button. Look here for setting a default value -- http://effbot.org/tkinterbook/entry.htm – Dunes Aug 15 '14 at 11:44
1

If you have PySide installed on your machine, the following will create a dialog that does what you want.

IMO, PySide is much easier to use than Tk, and you can very quickly create little applications like this which work quite nicely.

enter image description here

from PySide import QtGui, QtCore
import sys

"""
This class just sets up the actual dialog widget, and puts everything in place. 
It was mostly just generated by Qt Designer & pyside-uic though, so there's 
no real need to understand it all.
"""
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(402, 182)
        self.gridLayout = QtGui.QGridLayout(Dialog)
        self.gridLayout.setObjectName("gridLayout")
        self.label_formula12 = QtGui.QLabel(Dialog)
        self.label_formula12.setObjectName("label_formula12")
        self.gridLayout.addWidget(self.label_formula12, 3, 0, 1, 2)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 2)
        self.label_v1 = QtGui.QLabel(Dialog)
        self.label_v1.setObjectName("label_v1")
        self.gridLayout.addWidget(self.label_v1, 0, 0, 1, 1)
        self.lineEdit_v1 = QtGui.QLineEdit(Dialog)
        self.lineEdit_v1.setObjectName("lineEdit_v1")
        self.gridLayout.addWidget(self.lineEdit_v1, 0, 1, 1, 1)
        self.label_v2 = QtGui.QLabel(Dialog)
        self.label_v2.setObjectName("label_v2")
        self.gridLayout.addWidget(self.label_v2, 1, 0, 1, 1)
        self.lineEdit_v2 = QtGui.QLineEdit(Dialog)
        self.lineEdit_v2.setObjectName("lineEdit_v2")
        self.gridLayout.addWidget(self.lineEdit_v2, 1, 1, 1, 1)
        self.label_bevel = QtGui.QLabel(Dialog)
        self.label_bevel.setObjectName("label_bevel")
        self.gridLayout.addWidget(self.label_bevel, 2, 0, 1, 2)
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem, 4, 0, 1, 2)
        self.label_v1.setBuddy(self.lineEdit_v1)
        self.label_v2.setBuddy(self.lineEdit_v2)

        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle("Formula 12")
        self.label_formula12.setText("Formula 12")
        self.label_v1.setText("Value &1:")
        self.label_v2.setText("Vaule &2:")
        self.label_bevel.setText("Bevel")


"""
Here we add the actual functionality to the widgets in the dialog. The
functionality it simple, there are just a few differences from Tk, namely the
use of `signals` and `slots`. The 
"""
class MainWindow(QtGui.QDialog):
    def __init__(self,parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        self.ui.lineEdit_v1

        qDoubleValidator = QtGui.QDoubleValidator()

        self.ui.lineEdit_v1.setText("0.0")
        self.ui.lineEdit_v2.setText("0.0")

        """
        Here's the magic that forces the numbers in the `lineEdit`s to be 
        real numbers.
        """
        self.ui.lineEdit_v1.setValidator(qDoubleValidator)
        self.ui.lineEdit_v2.setValidator(qDoubleValidator)

        """
        Signals and Slots. The first set wait until editing is finished - i.e.
        when foucs leaves the box. The second set offer real time updating.        
        """
        #self.ui.lineEdit_v1.editingFinished.connect(self.updateValues)
        #self.ui.lineEdit_v2.editingFinished.connect(self.updateValues)

        self.ui.lineEdit_v1.textEdited.connect(self.updateValues)
        self.ui.lineEdit_v2.textEdited.connect(self.updateValues)

        self.updateValues()        

    def updateValues(self):
        try:
            self.value1 = float(self.ui.lineEdit_v1.text())
            self.value2 = float(self.ui.lineEdit_v2.text())

            self.bevel = self.calculateBevel()
            self.formula12 = self.calculateFormula12()

            self.ui.label_bevel.setText("Bevel = %10.5f" % self.bevel)
            self.ui.label_formula12.setText("Formula12 = %10.5f" % self.formula12)
        except ValueError:
            print "one of the values could not be cast to a float"

    def calculateBevel(self):
        return 3.5 * 2 * (self.value1 + self.value2) / 100

    def calculateFormula12(self):
        return 2.4 * 1.1 * (self.bevel + 44 + 86.67 * self.value1 * self.value2 / 10000)

def main():

    app = QtGui.QApplication(sys.argv)
    myapp = MainWindow()

    myapp.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
will
  • 10,260
  • 6
  • 46
  • 69
  • Thankyou will, i like the look, i may consider using it or converting to it instead of tk after ive completed the program in tk. As i explained im very new, i am so new that you probably wouldnt believe me if i told you, i only started learning to program in python 2 weeks ago, and i have had absoloutely no prior training in anything even remotely related to programming. Steep learning curve. – LMCT Aug 15 '14 at 13:18
  • @LMCT if that is the case, i would not dive into GUIs straight away, strating with simple command line programs is IMO an easier start. – will Aug 15 '14 at 13:19
  • I have already done that though, i have burned through all the material i can find on Python and am now trying to apply it to create a program useful to my job. Im finding that there is alot more to learn aside from the learning materials once you start trying to take what you know and apply it in an abstract fashion to achieve new goals. – LMCT Aug 15 '14 at 13:24
0

In the end the reason for the error, was because the float value was being derived from an entry field that upon its creation was blank.

A blank field in float form does not translate hence the valueerror.

It is possible to create validation rules on Tkinter forms here

However in my specific example, i moved the calculation that involved the float numbers to be inside the code block for the button itself, making it so that the float values were not being defined until after the fields had been filled.

A further try except block was added to handle incorrect values being entered.

Thankyou to everyone who helped, especially "will""Reza-S4"Dunes" and "barak manos".

Community
  • 1
  • 1
LMCT
  • 43
  • 6