Reputation: 13
So I was trying to write a program that converts various metric units to other units. (i.e. Cm to Mm) My Professor was adamant about not using global
s and having all of our code be in either a function or a class. With the code as shown below, it gives me a:
ValueError (*line 18, in __init__ self.intNtry = int(self.ntryAnswer) ValueError: invalid literal for int() with base 10: ''*)
Is there any way to have the variables not activate as soon as the program starts? I'm new to programming, please don't bully me
class Converter(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.txt = tk.Text(self, height=1, width=45)
self.txt1 = tk.Text(self, height=1, width=45)
self.txt2 = tk.Text(self, height=1, width=45)
self.txt3 = tk.Text(self, height=3, width=45)
self.unit1 = tk.Entry(self)
self.unit2 = tk.Entry(self)
self.num1 = tk.Entry(self)
self.btn = tk.Button(self, text="Calculate", padx=15, pady=15, command=self.buttonClick)
**self.ntryAnswer = self.num1.get()
self.intNtry = int(self.ntryAnswer)**
self.initWindow()
def buttonClick(self):
if self.unit1 == "cm" and self.unit2 == "m":
ans1 = float(self.intNtry) / 100
print(ans1)
Upvotes: 1
Views: 57
Reputation: 531918
Your class doesn't need an intNTry
attribute. The value returned by self.num1.get()
isn't interesting until you are ready for it, namely when you actually click the button.
class Converter(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.txt = tk.Text(self, height=1, width=45)
self.txt1 = tk.Text(self, height=1, width=45)
self.txt2 = tk.Text(self, height=1, width=45)
self.txt3 = tk.Text(self, height=3, width=45)
self.unit1 = tk.Entry(self)
self.unit2 = tk.Entry(self)
self.num1 = tk.Entry(self)
self.btn = tk.Button(self, text="Calculate", padx=15, pady=15, command=self.buttonClick)
self.initWindow()
def buttonClick(self):
if self.unit1 == "cm" and self.unit2 == "m":
answer = self.num1.get()
entry = int(answer)
ans1 = entry / 100
print(ans1)
If there are multiple places where it would be interesting to retrieve the value (or if you just want to use more encapsulation), a property as suggested by @modesitt would be appropriate.
class Converter(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.txt = tk.Text(self, height=1, width=45)
self.txt1 = tk.Text(self, height=1, width=45)
self.txt2 = tk.Text(self, height=1, width=45)
self.txt3 = tk.Text(self, height=3, width=45)
self.unit1 = tk.Entry(self)
self.unit2 = tk.Entry(self)
self.num1 = tk.Entry(self)
self.btn = tk.Button(self, text="Calculate", padx=15, pady=15, command=self.buttonClick)
self.initWindow()
@property
def field1(self):
return int(self.num.get()) / 100
def buttonClick(self):
if self.unit1 == "cm" and self.unit2 == "m":
print(self.field1)
Upvotes: 2
Reputation: 342
You could always assign that variable to None and then create an additional method which sets it:
def __init__(self, parent):
self.intNtry = None
def foo(self):
self.intNtry = int(self.ntryAnswer)
Upvotes: 0
Reputation: 7210
Use property
class Converter(Frame):
...
@property
def intNtry(self):
ntryAnswer = self.num1.get()
return int(self.ntryAnswer)
which will dynamically evaluate when .intNtry
is called. There is no reason to store this variable though - .self.num.get()
can be called when you need the value during buttonClick
. In general though, computed properties should use @property
.
Upvotes: 1