Celsius to Fahrenheit-- Write a GUI program that converts Celsius temperatures to Fahrenheit temperatures. The user should be able to enter a Celsius temperature, click a button, and then see the equivalent Fahrenheit temperature. Use the following formula to make the conversion:
F = 9/5C +32
F is the Fahrenheit temperature and C is the Celsius temperature.
THIS IS THE CODE I HAVE SO FAR, THE ERROR I GET says "invalid literal for int() with base 10: ''" I need help getting it to run correctly.
#import
#main function
from tkinter import *
def main():
root=Tk()
root.title("Some GUI")
root.geometry("400x700")
#someothersting=""
someotherstring=""
#enter Celcius
L1=Label(root,text="Enter a Celcius temperature.")
E1=Entry(root,textvariable=someotherstring)
somebutton=Button(root, text="Total", command=convert(someotherstring))
somebutton.pack()
E1.pack()
L1.pack()
root.mainloop()#main loop
#convert Celcius to Fahrenheit
def convert(somestring):
thestring=""
thestring=somestring
cel=0
far=0
cel=int(thestring)
far=(9/5*(cel))+32
print(far)
Your main problem is this line;
somebutton=Button(root, text="Total", command=convert(someotherstring))
...which will call convert(someotherstring) immediately and assign the result to command. Since someotherstring is empty when this line is reached, it will fail to convert the value and fail the program.
If you don't want it evaluated immediately but instead on button press, you can use a lambda as a command;
somebutton=Button(root, text="Total", command=lambda: convert(E1.get()))
...which will eliminate the use of someotherstring completely and just call convert with the contents of E1 when the button is clicked.
This could be due to int("")
In main(), do
def main():
# ...
someotherstring = 0 # Since its trying to get int
Or you can check if its empty in convert():
def convert(somestring):
if somestring != "":
# cel=0 dont need these in python
# far=0
cel=int(somestring)
far=(9/5*(cel))+32
print(far)
Note: Check if you are using someotherstring properly with Entry widget. I believe you are supposed to use StringVar() and do stringvar.get() to get the text inside widget.
Related
I am currently in an intro cs class and have a question about simple GUI and more specifically how to take a number (ex 6,7,8) input and when a button is pressed take the input number and determine if it is even or odd so far below is what I have and I get the error message that states: "button_handler() takes exactly 1 arguments (0 given)" Can someone explain to me what I am doing wrong?
import simplegui
global text_input
frame = simplegui.create_frame('Testing', 250, 250)
label = frame.add_label('Divisable by 6?')
def input_handler(text_input):
print "You entered,", text_input
def button_handler(num):
if float(num) / 6 == 0:
print "divisable by six"
else:
print "Not divisable by 6"
button1 = frame.add_button('divisable by 6?', button_handler)
inp = frame.add_input('Please insert number', input_handler, 50)
frame.start()
(BTW the formatting is weird when copied and pasted from code skulptor)
I am familiar with with tkinter and have not used simplegui, but from the error message, I can guess the problem.
button_handler is a callback that is called without any arguments when the button is clicked. But you define it with a parameter number. You have to re-write button_handler to get the number from the input some other way. I know how to do that with tkinter, but not for simplegui. Perhapsinput_handlershould write a global thatbutton_handler` can access.
In this line here:
button1 = frame.add_button('divisable by 6?', button_handler)
you are not feeding anything to button_handler. In other words, it has no arguments. But elsewhere in your code you mandate that button_handler has exactly one argument. So, you need to update your reference to button_handler in the line above to account for that fact.
(That's the fundamental bit, anyway: I don't want to comment on the rest of your code, since you say it is under construction.)
From the CodeSculptor documentation for frame.add_button():
The handler should be defined with no parameters
You can grab the content of an input field with get_text(). Here is a simple example that prints the content of an input field when a button is pressed:
import simplegui
def input_handler(text_input):
pass
def button_handler():
print inp.get_text()
frame = simplegui.create_frame("Demonstration of input and button", 300, 300)
inp = frame.add_input("Input:", input_handler, 100)
frame.add_button("Print", button_handler, 100)
frame.start()
I am trying to understand the codes wrote by someone else so that I can build my own GUI.
Here is the code.
MODEL: temperatureconvert.py
class TemperatureConvert:
"""
class TemperatureCovert is the MODEL for a simple program. It just converts temperature
in Celisus into Fahrenheit and vice versa.
"""
def __init__(self):
self.fahrenheitEntrySpace = 0
self.celsiusEntrySpace = 0
def convertTempF2C(self):
fahrenheit = self.fahrenheitEntrySpace
if fahrenheit != 0.0:
celsius = (fahrenheit - 32) * 5 / 9
else:
celsius = -17.7777778
def convertTempC2F(self):
celsius = self.celsiusEntrySpace
if celsius != 0.0:
fahrenheit = (celsius * 9.0/5.0 + 32)
else:
fahrenheit = 32
def __str__(self):
return str(self.counter)
VIEW: myFrame10.py
import tkinter
class MyFrame(tkinter.Frame): #creates window for controls in an object made
#from a class called "tkinter.Frame"
"""
Class myFrame is the VIEW for a simple program that contains two buttons, two entry areas, and four labels:
one button a converter;
one button quits the program;
one entry is for celsius;
one entry is for fahrenheit;
and the labels prompt user for input, and label the entry values as needed.
"""
def __init__(self, controller):
"""
places the controls on the frame
"""
tkinter.Frame.__init__(self) #initilizes the superclass
self.pack() #required for the buttons to show up properly.
self.controller = controller #saves ref to controller to call methods on
#contoller object when user generates events
#Fahrenheit Input Prompt
self.fahrenheitLabel = tkinter.Label(self)
self.fahrenheitLabel["text"] = "Enter Fahrenheit Value:"
self.fahrenheitLabel.pack({"side":"left"})
#Fahrenheit Entry Space
self.fahrenheitEntrySpace = tkinter.Entry(self)
self.fahrenheitEntrySpace.insert(0, "FahrenheitTemperature")
self.fahrenheitEntrySpace.pack({"side":"left"})
#Fahrenheit Value label
self.fahrenheitLabel = tkinter.Label(self)
self.fahrenheitLabel["text"] = ("Fahrenheit Degrees")
self.fahrenheitLabel.pack({"side":"left"})
#Converter button
self.convertButton=tkinter.Button(self)
self.convertButton["text"]= "Convert"
self.convertButton["command"]=self.controller.buttonPressed
# an object that remembers both self and reply when later called
self.convertButton.pack({"side":"left"})
#Quit button
self.quitButton = tkinter.Button(self)
self.quitButton["text"] = "QUIT"
self.quitButton["command"] = self.quit
#the statement above attaches the event handler
#self.quit() to the quit button
self.quitButton.pack({"side":"right"})
#Celsius Value label
self.celsiusLabel = tkinter.Label(self)
self.celsiusLabel["text"] = ("Celsius Degrees")
self.celsiusLabel.pack({"side":"right"})
#Celsius Entry Space
self.celsiusEntrySpace = tkinter.Entry(self)
self.celsiusEntrySpace.insert(0, "CelsiusTemperature")
self.celsiusEntrySpace.pack({"side":"right"})
#Celsius Input Prompt
self.celsiusLabel = tkinter.Label(self)
self.celsiusLabel["text"] = ("Enter Celsius Value:")
self.celsiusLabel.pack({"side":"right"})
CONTROLLER: controller10.py
import tkinter
import myFrame10 #the VIEW
import temperatureconvert #the MODEL
class Controller:
"""
The CONTROLLER for an app that follows the MODEL/VIEW/CONTROLLER architecture.
When the user presses a button on the VIEW,
this controller calls the appropriate methods in the model.
The controller handles all the communication between the model and the view.
"""
def __init__(self):
"""
This starts the TK framework up;
instantiates the model;
instantiates the VIEW;
and states the event loop that waits for the user to press a button on the view
"""
root = tkinter.Tk() #This starts the TK framework up;
self.model = temperatureconvert.TemperatureConvert() #instantiates the model
self.view = myFrame10.MyFrame(self) #instantiates the VIEW
self.view.mainloop() # states event loop waits for user to press button on view
root.destroy() #lets user quit
def buttonPressed(self):
"""
Convert F --> C
"""
self.model.convertTempF2C(self.view.fahrenheitEntrySpace.get)
#MODEL creates new celsius temp from(fahrenheit input)
self.view.celsiusEntrySpace.clear()
#replaces VIEW's old default celsius value
self.view.celsiusEntrySpace.insert(self.model.celsius)
#and insert's MODEL's newly converted (celsius) value
"""
Convert C --> F
"""
self.model.convertTempC2F(self.view.celsiusEntrySpace.get)
#MODEL creates new fahrenheit temp from (celsius input)
self.view.fahrenheitEntrySpace.pop()
#replaces VIEW's old default 0 fahrenheit value
self.view.fahrenheitEntrySpace.insert(self.model.fahrenheit)
#and insert's MODEL's newly converted (fahrenheit) value
if __name__=="__main__":
c = Controller()
First of all, I got an TypeError as below.
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/tkinter/__init__.py", line 1533, in __call__
return self.func(*args)
File "/Users/adrian/Desktop/10X Genomics/Python exercise/controller10.py", line 36, in buttonPressed
self.model.convertTempF2C(self.view.fahrenheitEntrySpace.get)
TypeError: convertTempF2C() takes 1 positional argument but 2 were given
However, I don't know what part goes wrong under method of convertTempF2c().
Second, how could I remove the "celsiusEntrySpace" default value (in this case, it is CelsiusTemperature) with the new value obtain from converting Fahrenheit? .pop is not working in this case since it only works on the list, and it gave the error below.
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/tkinter/__init__.py", line 1533, in __call__
return self.func(*args)
File "/Users/adrian/Desktop/10X Genomics/Python exercise/controller10.py", line 39, in buttonPressed
self.view.celsiusEntrySpace.pop()
AttributeError: 'Entry' object has no attribute 'pop'
So, how could I fix those 2 errors above? Please help! Thanks~
convertTempF2C looks like the following; notice that it takes no positional parameters other than self:
def convertTempF2C(self):
However, you're calling it like this:
self.model.convertTempF2C(self.view.fahrenheitEntrySpace.get)
There are two things wrong with that line. First, you're passing an extra parameter which the function isn't expecting. Second, you're not actually calling the get function, you're merely referencing it. You should call it like this:
value = self.view.fahrenheitEntrySpace.get()
self.model.convertTempF2C(value)
Note the trailing parenthesis on that first line.
Why two steps instead of one? It makes the code clearer, and it makes it easier to debug because you can print out the value before doing the conversion to verify it is what you think it is.
Finally, you are doing this:
self.view.celsiusEntrySpace.pop()
Just as the error message is telling you, self.view.celsiusEntrySpace is an Entry widget, and Entry widgets don't have a pop method. I don't know why you think it does, unless you're going by some incorrect documentation. I also don't quite understand what you think this is doing, so I can't offer an alternative.
import tkinter
import tkinter.messagebox
import sys
top=tkinter.Tk()
from tkinter import*
def clear():
e1.delete(0,END)
return
def seven():
v.set(v.get()+str("7"))
v.get()
def eight():
v.set(v.get()+str("8"))
v.get()
def nine():
v.set(v.get()+str("9"))
v.get()
def four():
v.set(v.get()+str("4"))
v.get()
def five():
v.set(v.get()+str("5"))
v.get()
def six():
v.set(v.get()+str("6"))
v.get()
def one():
v.set(v.get()+str("1"))
v.get()
def two():
v.set(v.get()+str("2"))
v.get()
def three():
v.set(v.get()+str("3"))
v.get()
def zero():
v.set(v.get()+str("0"))
v.get()
def add():
global op1
op1=v.get()
e1.delete(0,END)
def equals():
v.set(int(op1)+int(v.get()))
v.get()
top.title("D & R Calculator")
top.geometry("290x240")
from tkinter import*
frame=Frame(top)
frame.grid(column=0,row=0)
framenum=Frame(top,height=265)
framenum.grid()
v=StringVar()
from tkinter import*
e1=Entry(frame,width=30,textvariable=v)
e1.grid(row=0,column=0,sticky=W+E)
b7=tkinter.Button(framenum,text="7",height=3,width=9,command=seven)
b7.grid(row=0,column=1)
b8=tkinter.Button(framenum,text="8",height=3,width=9,command=eight)
b8.grid(row=0,column=2)
b9=tkinter.Button(framenum,text="9",height=3,width=9,command=nine)
b9.grid(row=0,column=3)
b4=tkinter.Button(framenum,text="4",height=3,width=9,command=four)
b4.grid(row=1,column=1)
b5=tkinter.Button(framenum,text="5",height=3,width=9,command=five)
b5.grid(row=1,column=2)
b6=tkinter.Button(framenum,text="6",height=3,width=9,command=six)
b6.grid(row=1,column=3)
b1=tkinter.Button(framenum,text="1",height=3,width=9,command=one)
b1.grid(row=2,column=1)
b2=tkinter.Button(framenum,text="2",height=3,width=9,command=two)
b2.grid(row=2,column=2)
b3=tkinter.Button(framenum,text="3",height=3,width=9,command=three)
b3.grid(row=2,column=3)
b0=tkinter.Button(framenum,text="0",height=3,width=9,command=zero)
b0.grid(row=3,column=2)
f1=tkinter.Button(framenum,text="+",height=3,width=9,command=add)
f1.grid(row=2,column=4)
f2=tkinter.Button(framenum,text="-",height=3,width=9)
f2.grid(row=1,column=4)
f3=tkinter.Button(framenum,text="X",height=3,width=9)
f3.grid(row=0,column=4)
f4=tkinter.Button(framenum,text="/",height=3,width=9)
f4.grid(row=3,column=4)
eq=tkinter.Button(framenum,text="=",height=3,width=9,command=equals)
eq.grid(row=3,column=3)
c=tkinter.Button(framenum,text="CE",height=3,width=9,command=clear)
c.grid(row=3,column=1)
top.mainloop
I challenged myself to make a tkinter calculator WITHOUT using a tutorial. I've finally made it work but there is one problem. It can only do one function. Be it addition,multiplication,division or taking away it can only do one operation.All I want to know is how would I make the calculator remember which button was pressed/ which command so it could differentiate between different functions. Basically, I need help or guidance in making the calculator do all operations, instead of just having it do one operations and having to manually go and edit it to make it do another operation. Help or even just a push in the right direction would be great, I am very new to Python.
Alright so there are a few of things wrong with you code:
You are missing the parentheses after top.mainloop()
You have the line from tkinter import * heaps of times, this
doesn't matter really, but you only need it once at the top, and can
do away with all the other imports at the top as well.
You need to globalise op1 in the equals function.
You haven't written functions for the divide, subtract and multiply
buttons, so how could they work? When I try 9 - 6 and hit equals I
get a NameError op1 is not defined it tries to equal something but
can't as the subtract button doesn't do anything yet.
This means that you can only start with the adding button, so I try 5 + 4 and hit equals, which
works sweet and gives me 9, but if you the try to minus 5 from the result it will put a 5 in the text box and add five again when you hit equals.
When I try to start with 9 - 6 as mentioned earlier, it won't work. To get around this issue with how op1 relates to adding, and in the equals function op1 is used in a way it will only work for the adding function you need a try/except loop:
def equals():
try:
v.set(int(op1)+int(v.get()))
v.get()
del op1
except NameError:
try:
# Whatever needs to be written for subtraction to work
# (using op2 as variable?) something like this:
v.set(int(op2)-int(v.get()))
v.get()
del op2
except NameError:
try:
# etc. etc. until you have done all four equals methods...
where op2 is set in the subtracting function etc.
This should give you some help to be able to continue, if you want I can fix program for you, but only if you don't want to do it yourself?
I'm working on a GUI for a project in school. All the buttons that I have in my GUI are bound with functions that I have created. These functions call for already predefined functions. For some of the predefined functions, I need one or two arguments and I have solved that with entries. I type in the arguments in the right entries that are connected to the specific button and when I press the button, the function will run with the corresponding arguments.
The thing I want to do is to in some way when I press a button, the function should be saved to a list instead of being executed right away. And when I push the "run" button(a new button that I will create) everything in my list will be executed. I have been thinking about using a list box but I don't know exactly how they work or if its even possible to run a list box that contains a number of functions. Does someone have any ideas or solutions for me? Can I use the list box for this or is there something else that is better to use?
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.entry1 = IntVar()
self.entry2 = IntVar()
def do_something():
value1 = self.entry1.get()
value2 = self.entry2.get()
self.listbox.insert(END, "predefined_function(value1, value2)")
def run_listbox_contents():
pass
self.button = Button(frame, text="Move", command=lambda: do_something())
self.button.pack(side=TOP)
self.entry1.set("value1")
self.entry = Entry(frame, textvariable=self.entry1)
self.entry.pack(side=TOP)
self.entry2.set("value2")
self.entry = Entry(frame, textvariable=self.entry2)
self.entry.pack(side=TOP)
self.listbox = Listbox(master)
self.listbox.pack(side=TOP)
root = Tk()
app = App(root)
root.title("Mindstorms GUI")
root.geometry("800x1200")
root.mainloop()
root.destroy()
Just use a standard list.
something like this
def hest(txt):
print "hest: " +txt
def horse(txt):
print "horse: " + txt
funcList = []
funcList.append(hest)
funcList.append(horse)
for x in funcList:
x("Wow")
This outputs
hest: Wow
horse: Wow
Was this what you wanted?
If I were you, I wouldn't want to save functions to a list. I would suggest another solution for you.
I suppose you have heard of the principle of MVC (Model-View-Controller). In your case, the list box is a part of view, and the process that saves functions and then calls them at once is a part of controller. Separate them.
You might want to save and display any string in the list box to let the users know that the corresponding functions have been enlisted and ready to run. For example, save a string "Function1 aug1 aug2 aug3" or "Funtion2 aug1 aug2" or whatever you like as a handle of the corresponding function.
And for the controller part, write a function (let's say conductor()). It reads the handle strings from the list, parses them and calls the corresponding functions. Where you want to run the enlisted functions, there you just call conductor().
Update:
Due to your comment I understand that you are pretty new to program. Let me show you how to write a simplest parser with your given variable names.
def run_listbox():
to_do_list = #get the list of strings
for handle_string in to_do_list:
#Let's say you got
#handle_string = "Predfined_function1 value1 value2"
#by here
handle = handle_string.split(" ")
#Split the string by space, so you got
#handle = ["Predfined_function1", "value1", "value2"]
#by here
if handle[0] == "Predfined_function1":
Predfined_function1(handle[1], handle[2]) #Call Predfined_function1(value1, value2)
elif handle[0] == "Predfined_function2":
Predfined_function2(handle[1], handle[2])
#elif ...
#...
#elif ...
#...
#elif ...
#...
This is not a perfect parser, but I hope it could let you know what does a parser look like.
If I create an entry box like so:
myentry = Entry ()
myentry.place (x = 54,y = 104)
the value that the user enters is a string value. What do I have to add so that the entry is a float? I have tried to write "float" in the parentheses beside Entry but it didn't work and showed me an error saying that tk() does not support float. Any help would be appreciated!
I wrote a simple script to demonstrate how to do what you want:
from Tkinter import Tk, Button, Entry, END
root = Tk()
def click():
"""Handle button click"""
# Get the input
val = myentry.get()
try:
# Try to make it a float
val = float(val)
print val
except ValueError:
# Print this if the input cannot be made a float
print "Bad input"
# Clear the entrybox
myentry.delete(0, END)
# Made this to demonstrate
Button(text="Print input", command=click).grid()
myentry = Entry()
myentry.grid()
root.mainloop()
When you click the button, the program tries to make the text in the entrybox a float. If it can't, it prints "Bad input". Otherwise, it prints the float in the terminal.