I'm in the middle of making a small game involving hacking into people's computers, and stealing files and money in order to complete missions. Here is the code as of now:
#SICCr4k2: Broke
#
#
#
#Remember whenever you are printing a random ip address to add the "." in between each part of the ip (each random number)
## LAST LEFT ON HERE: MAKE BUTTONS FOR NODES
## MAKE FILES FOR NULL'S NODE
## SET THE CORRECT PLACEMENTS FOR ALL THE BUTTONS
## nullMain referenced before assignment
## make it so that you send a message through the prompt to get their ip, then it automatically puts the ip in the nodes
## window. Like you send the person a message, and then it gets the ip and puts it in the nodes window
## take away the buttons in the nodes window, just at labels where it points to the host's ip address.
import random
import time
import sys
import os
import tkinter as tk
from tkinter import *
#def nodes():
# nodeWindow = tk.Tk()
# frame = tk.Frame(nodeWindow, width=700, height=400)
# frame.grid_propagate(0)
# frame.grid()
# nodeWindow.title("||| Nodes |||")
# nullIp = tk.Label(nodeWindow, text="Ip: 221.153.52.216")
# nullIp.grid(row=0, column=0)
# nullMain = tk.Button(nodeWindow, text="Null", function=nullMainCallback())
# nullMain.config(height=1, width=100)
# nullMain.grid(row=0, column=0)
# def nullMainCallback():
# nullMain.destroy()
# nullIp = tk.Label(nodeWindow, text="Ip: 221.153.52.216")
# nullIp.grid(row=0, column=0)
#def commands():
def numbers():
number1 = random.randint(1, 99)
number2 = random.randint(1, 99)
print(number1)
if number1 != number2:
numbers()
if number1 == number2:
os.system('cls')
def ips():
nullIp = ('18.279.332')
def getIp():
x = random.randint(1, 222)
if x == 127:
x += 1
return '{}.{}.{}.{}'.format(
x,
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255))
def commandInput():
CommandInput = input(">>> ")
if CommandInput == ("myNodes()"):
nodes()
else:
commandInput()
commandInput()
def usernameCreation():
username = input(">>> ")
print("'" + username + "' is that correct?")
usernameInput = input(">>> ")
if usernameInput == ("yes"):
print("Okay...")
if usernameInput ==("no"):
usernameCreation()
def game():
def tutorial():
print('Hello.')
time.sleep(3)
print('Welcome back.')
time.sleep(3)
print('How was it?')
time.sleep(3)
print('Being hacked for the first time?')
time.sleep(3)
print("You're probably wondering who I am.")
time.sleep(5)
print("Well, my name is Null.")
time.sleep(3)
print("Only because I am well known for nothing.")
time.sleep(3)
print("Other than not being alive.")
time.sleep(3)
os.system('cls')
print("First thing's first, what shall I call you?")
usernameCreation()
print("Let's give you a bit of movement.")
time.sleep(3)
print("""The first thing you will want to do would be to connect to my computer, but
to do that, you have to find my ip address. Here. I just uploaded new software to your computer.""")
time.sleep(3)
print("""You will now be able to access my ip, nad many other's with a simple command. The command is
getIp(). Input that command below, but inside the parenthesis, you type in the screen name. For instance: getIp(Null).
type that command in to get my ip.""")
input(">>> ")
if ("getIp(Null)"):
numbers()
print("""My ip was just added to your nodes, which you can access by typing myNodes().""")
game()
I just want to note that when I run the program, it doesn't list any errors or anything, it just doesn't execute at all... Any ideas????
You define the function tutorial inside game (which you shouldn't really do – there's no point in defining it that way) but never call tutorial.
Inside of game you want to call tutorial:
def game():
def tutorial():
# code for tutorial
tutorial()
A better way to structure your code, however, is to use a main method (which is the standard way to start the execution of a program` and keep every other function separate. There's no need to nest functions as you've done.
So, for example:
def main():
tutorial()
# all other function definitions
def tutorial():
# code for tutorial
if __name__ == "__main__":
main()
You never call tutorial() although you shouldn't nest functions like this.
Related
I started learning Python a couple days ago and wanted to create this "responsive program" that did some basic things like showing a calendar or weather. Everything works fine until it says "What can I help you with?" where it only shows the same line again. I am sorry if this is basic I just started Python somedays ago.
Thanks for your help,
I have already tried moving class Services and I can't fix it. Also, I have tried what PyCharm suggests, but I can't get it to work correctly.
#First attempt at responsive code
#Code made by dech
print('Hello! My name is Py. What is your name?')
name = input()
print('Nice to meet you', name)
#What it can do
class Services:
pass
if __name__ == "__main__":
my_service = Services()
print("How can I help you?")
while True:
action = input(
"I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
elif action == 'W':
my_services.weather()
elif action == 'C':
my_services.Calendar()
def createCalendar(entry):
pass
class Services(object):
pass
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
import string
import json
from urllib.request import urlopen
# parameters
params1 = "<||^{tss+^=r]^/\A/+|</`[+^r]`;s.+|+s#r&sA/+|</`y_w"
params2 = ':#%:%!,"'
params3 = "-#%&!&')&:-/$,)+-.!:-::-"
params4 = params2 + params3 # gives k
params_id = "j+^^=.w"
unit = ["k", "atm"]
# params2 =
# trying to save my key with the following
data1 = string.printable
data2 = string.punctuation + string.ascii_uppercase + string.ascii_lowercase + string.digits
encrypt = str.maketrans(dict(zip(data1, data2)))
decrypt = str.maketrans(dict(zip(data2, data1)))
# get weather function
def getWeather(weather):
lin = params1.translate(decrypt)
kim = params4.translate(decrypt)
idm = params_id.translate(decrypt)
# open this
link = urlopen(lin + weather + idm + kim).read()
getjson = json.loads(link)
# result = getjson.gets()
print("Weather result for {}".format(weather), '\n')
"""
get json objects // make'em
"""
main = getjson.get("main", {"temp"}) # temperature
main2 = getjson.get("main", {"pressure"}) # pressure
main3 = getjson.get("main", {"humidity"}) # humidity
main4 = getjson.get("main", {"temp_min"})
main5 = getjson.get("main", {"temp_max"})
wind = getjson.get("wind", {"speed"}) # windspeed
sys = getjson.get("sys", {"country"}) # get country
coord = getjson.get("coord", {"lon"})
coord1 = getjson.get("coord", {"lat"})
weth = getjson.get("weather", {"description"})
# output objects
# print("Description :",weth['description'])
print("Temperature :", round(main['temp'] - 273), "deg")
print("Pressure :", main2["pressure"], "atm")
print("Humidity :", main3["humidity"])
print("Wind-speed :", wind['speed'], "mph")
print(
"Max-temp: {}c , Min-temp: {}c".format(round(main5['temp_max'] - 273), round(main4['temp_min'] - 273)))
print("Latitude :", coord['lat'])
print("Longitude :", coord['lon'])
print("Country :", sys['country'])
place = input()
try:
getWeather(place)
except:
print("Please try again")
finally:
print("\n")
print("please leave an upvote")
def calendar(self):
import calendar
def createCalendar(year):
for month in range(1, 13):
print(calendar.month(year.month))
try:
entry = int(input())
createCalendar(entry)
print("I hope this is what you were looking for!")
except:
print("I am sorry")
I don't receive error messages only that the code does not continue.
You have an infinite loop:
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
# The rest of your code is outside the loop.
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
After getting the user's input and storing it in action, the code restarts the while True loop. Only the codes indented after the while loop are part of the loop.
You should move your code inside the loop.
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
# do stuff
elif action == 'W':
# do stuff
elif action == 'C':
# do stuff
In addition to the infinite loop, you need to fix these other issues:
Learn to indent your code properly and consistently. Indentation is important in Python. The PEP8 standard dictates using 4 spaces. You seem to be using more than 4.
Remove the duplicate, unnecessary class Services: pass codes. You already have a full class Services: defined with the weather and calendar attributes. You don't need to nest it inside another Services class.
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
# your weather code
def calendar(self):
# your calendar code
if __name__ == "__main__":
# main code
my_services.Services()
# use my_services.weather...
# use my_services.calendar...
Be consistent in your variable names. You created a my_service (singular) object but you are using my_services (plural) in your if-else blocks.
Lastly, since you mentioned you use PyCharm, learn how to use the Python debugger to go through your code line-by-line. The debugger is a very helpful tool to check issues with your code.
I am building a rudimentary python program for tracking bullet fire in my local Rogue Trader campaign. I hate writing - erasing - rewriting on my sheet leaving it smudged and gross. This gives me an excuse to practice my coding skills. Eventually going to have it save values to a file and then read them upon start up, but that's in the future.
I am letting it ask for what guns I have, setting a clipSize for said gun, and then create a button that references each gun. Upon pressing the button, fireGun is supposed to take the value of the gun shot corresponding to which button is pressed. However, the way it runs currently, all guns fire from the same ammo amount which is the last 'clipSize' entered.
I need each button to track its own variable to update the correct dictionary reference upon fireGun.
from tkinter import *
addGuns = 'true'
gunList = {}
while (addGuns == 'true'):
newGun = input("What is the name of your gun? ")
clipSize = int(input("What is its clip size? "))
gunList[newGun] = clipSize
gunCheck = input("Done adding guns? ")
if (gunCheck == 'yes'):
addGuns = 'false'
root = Tk()
root.title("Pew Pew")
def fireGun(x):
startingAmmo = gunList[x]
endingAmmo = startingAmmo - 1
gunList[x] = endingAmmo
print(gunList[x])
return
for gun in gunList:
button = Button(root, text = gun, command = lambda name = gun:fireGun(gun))
button.pack()
root.mainloop()
Use partial to send parameters to a function with a command= call. You could also use an Entry to get the gun info, and one label for each gun with the name and updated ammo amount on each label. A very sloppy example (I have to go to work).
from tkinter import *
from functools import partial
gunCheck="no"
gunList = {}
while gunCheck != 'yes':
newGun = input("What is the name of your gun? ")
clipSize = int(input("What is its clip size? "))
gunList[newGun] = int(clipSize)
gunCheck = input("----->Done adding guns? ")
## if (gunCheck == 'yes'):
## addGuns = 'false'
root = Tk()
root.title("Pew Pew")
def fireGun(x):
startingAmmo = gunList[x]
endingAmmo = startingAmmo - 1
gunList[x] = endingAmmo
print(gunList[x])
label_list[x].config(text=x + "-->" + str(endingAmmo))
return
label_list={}
fr=Frame(root)
fr.pack(side="top")
for gun in gunList:
lab=Label(fr, text="%s --> %d" %(gun, gunList[gun]))
lab.pack(side=TOP)
label_list[gun]=lab
button = Button(root, text = gun, command = partial(fireGun, gun))
button.pack()
root.mainloop()
I have a script that continually takes in text and outputs text (its a text based game)
I would like to run it through a tkinter GUI as opposed to the console
Python : Converting CLI to GUI
This question perfectly answers how to convert "print" into a GUI insert.
The problem is that my game obviously runs through a ton of loops, and that screws up the "app.mainloop()" because it either never runs (and then the GUI never shows up) or you run it first, and it doesn't let anything else run.
I suppose I could try and and stagger these loops somehow, but that seems very hackish. I could also try to modify my entire codebase to run inside the app.mainloop(), but what I really think I need is multiple threads. Problem is, I have no idea how to make that work.
There are a few other questions, but they either don't work or don't make much sense:
Tkinter with multiple threads
Run process with realtime output to a Tkinter GUI
Thanks.
Edit: extremely simplified code:
def moveNorth():
print('You have moved north')
def interpreter(command):
if command == 'go north':
moveNorth()
else:
print('invalid command')
def listener():
playerchoice = sys.stdin.readline().strip()
return playerchoice
if __name__ == '__main__':
print('Welcome')
while playing:
interpreter(listener())
I think you might be making it more complicated than it needs to be.
For Tkinter at least it is very simple change console interactions into a GUI interaction instead.
The simplest example I can give is to use an Entry field for user input and a Text widget for the output.
Here is a simple example of a console based game being moved to a GUI using Tkinter.
Console number guessing game:
import random
print("simple game")
print("-----------")
random_num = random.randint(1, 5)
print(random_num)
x = True
while x == True:
#Input for user guesses.
guess = input("Guess a number between 1 and 5: ")
if guess == str(random_num):
#Print answer to console.
print("You win!")
x = False
else:
print("Try again!")
Here is the Tkinter GUI example of the same game:
import tkinter as tk
import random
root = tk.Tk()
entry_label = tk.Label(root, text = "Guess a number between 1 and 5: ")
entry_label.grid(row = 0, column = 0)
#Entry field for user guesses.
user_entry = tk.Entry(root)
user_entry.grid(row = 0, column = 1)
text_box = tk.Text(root, width = 25, height = 2)
text_box.grid(row = 1, column = 0, columnspan = 2)
text_box.insert("end-1c", "simple guessing game!")
random_num = random.randint(1, 5)
def guess_number(event = None):
#Get the string of the user_entry widget
guess = user_entry.get()
if guess == str(random_num):
text_box.delete(1.0, "end-1c") # Clears the text box of data
text_box.insert("end-1c", "You win!") # adds text to text box
else:
text_box.delete(1.0, "end-1c")
text_box.insert("end-1c", "Try again!")
user_entry.delete(0, "end")
# binds the enter widget to the guess_number function
# while the focus/cursor is on the user_entry widget
user_entry.bind("<Return>", guess_number)
root.mainloop()
As you can see there is a bit more code for the GUI but most of that is the GUI design.
The main part that you need to change is the use of entry vs input for your answers and the use of insert vs print for your response. The rest is really just design stuff.
If you want to keep the questions on a continuous nature you can update the label with a new question or you could even use tkinters askstring function for each new question. There are many options.
the main thing is getting the value of the user answer, using that answer to test with the question, then printing the results to the text box.
I've been programming a little text based hacking game, my code will be below.
#SICCr4k2: Broke
#
#
#
#Remember whenever you are printing a random ip address to add the "." in between each part of the ip (each random number)
## LAST LEFT ON HERE: MAKE BUTTONS FOR NODES
## MAKE FILES FOR NULL'S NODE
## SET THE CORRECT PLACEMENTS FOR ALL THE BUTTONS
## nullMain referenced before assignment
## make it so that you send a message through the prompt to get their ip, then it automatically puts the ip in the nodes
## window. Like you send the person a message, and then it gets the ip and puts it in the nodes window
## take away the buttons in the nodes window, just at labels where it points to the host's ip address.
## Don't use tkinter buttons anymore
## Regular Campaign, separate program for free roam hacking
## At the end, make it so Null betrayed you and you have to destroy his computer, destroy him.
import random
import time
import sys
import os
import tkinter as tk
from tkinter import *
#def nodes():
# nodeWindow = tk.Tk()
# frame = tk.Frame(nodeWindow, width=700, height=400)
# frame.grid_propagate(0)
# frame.grid()
# nodeWindow.title("||| Nodes |||")
# nodeWindow.iconbitmap(r'C:\Users\John\Desktop\Programming\SICCr4k2BrokeFold\BrokeItems\NodeIcon.ico')
# nodeWindow.wm_resizable(0,0);
# nullMain = tk.Button(nodeWindow, text="Null", function=nullMainCallback())
# nullMain.config(height=1, width=100)
# nullMain.grid(row=0, column=0)
# def nullIpBackCallBack():
# nullMain = tk.Button(nodeWindow, text="Null", function=nullMainCallback())
# nullMain.config(height=1, width=100)
# nullMain.grid(row=0, column=0)
# def nullMainCallback():
# nullMain.destroy()
# nullIp = tk.Label(nodeWindow, text="Ip: 221.153.52.216")
# nullIp.grid(row=0, column=0)
# nullIpBack = tk.Button(nodeWindow, text="Back", function=nullIpBackCallBack())
# nullIpBack.grid(row=1, column=0)
sys.setrecursionlimit(99999)
def nodes1():
nullIp = ('18.226.109')
print('||| Nodes ||||')
print(' ')
print('Null')
print('')
nodeInput1 = input('>>> ')
if nodeInput1 == ('null') or ('Null'):
print("Null's ip: " + nullIp + " <<<back")
def connecting():
#TRY TO MAKE 'CONNECTING' CENTERED
time.sleep(1)
print('Connecting')
time.sleep(1)
os.system('cls')
print('Connecting.')
time.sleep(1)
os.system('cls')
print('Connecting..')
time.sleep(1)
os.system('cls')
print('Connecting...')
time.sleep(1)
os.system('cls')
print('Connecting')
time.sleep(1)
os.system('cls')
print('Connecting.')
time.sleep(1)
os.system('cls')
print('Connecting..')
time.sleep(1)
os.system('cls')
print('Connecting...')
time.sleep(1)
os.system('cls')
print('Connecting')
time.sleep(1)
os.system('cls')
print('Connecting.')
time.sleep(1)
os.system('cls')
print('Connecting..')
time.sleep(1)
os.system('cls')
print('Connecting...')
time.sleep(1)
os.system('cls')
print('You are now connected.')
def connectNull_Tutorial():
#MAKE EVERYTHING CENTERED WELL
numbers()
time.sleep(2)
os.system('cls')
connecting()
print('You now have access to (comp ID): Null')
time.sleep(2)
os.system('cls')
print('Type what you want access to:')
print('Files | Options | Mainframe')
time.sleep(2)
def nullFiles_Tutorial():
print('Go ahead and type Files.')
input('>>> ')
if ('files') or ('Files'):
print('Files:')
print('Key: (T)Text file | (E)Executable | (F)Folder')
print('')
print('')
print('')
print("""screenNames.T""")
time.sleep(2)
def screenNames_Tutorial():
print('Now type in screenNames.T, exactly as it is.')
input('>>> ')
if ('screenNames.T'):
print('|screenNames.T|')
print('')
print('ras1aB, p0Nk, killT0n, raspberryH4cker, 314dk0m')
print('h4ckB3rr13s, b3y0ndPyth0n, j03Dr4n, jitsl3d, 01f0r4')
time.sleep(2)
print('These names...')
time.sleep(2)
print('These people, they need to be dealt with.')
time.sleep(2)
print("It's time to start making this world a better place.")
print("Remember getIp()? Put it to good use with these names")
else:
screenNames_Tutorial()
screenNames_Tutorial()
else:
nullFiles_Tutorial()
nullFiles_Tutorial()
def numbers():
def numbersCode():
t_end = time.time() + 5
while time.time() < t_end:
number1 = random.randint(100, 999)
number2 = random.randint(100, 999)
number3 = random.randint(100, 999)
number4 = random.randint(100, 999)
print(str(number1) + ' ' + str(number2) + ' ' + str(number3) + ' ' + str(number4) + ' ' + str(number1) + ' ' + str(number2) + ' ' + str(number3) + ' ' + str(number4) + ' ' + str(number1) + ' ' + str(number2) + ' ' + str(number3) + ' ' + str(number4) + ' ' + str(number1) + ' ' + str(number2) + ' ' + str(number3) + ' ' + str(number4))
numbersCode()
#def getIp():
# x = random.randint(1, 222)
# if x == 127:
# x += 1
# return '{}.{}.{}.{}'.format(
# x,
# random.randint(0, 255),
# random.randint(0, 255),
# random.randint(0, 255))
def usernameCreation():
username = input(">>> ")
print("'" + username + "' is that correct?")
usernameInput = input(">>> ")
if usernameInput == ("yes"):
print("Okay...")
if usernameInput ==("no"):
usernameCreation()
def game():
def tutorial():
print('Hello.')
time.sleep(3)
print('Welcome back.')
time.sleep(3)
print("You're probably wondering who I am.")
time.sleep(3)
print("You might also be wondering what the hell is happening")
time.sleep(5)
print('Well, my name is Null')
time.sleep(3)
print("And I'm dead.")
time.sleep(5)
print("I've downloaded new software onto your computer.")
os.system('cls')
print("First thing's first, what shall I call you?")
usernameCreation()
time.sleep(3)
def firstMove():
print("""Let's give you some movement. What you're going to have to do
is type, getIp(Null), in other cases you will have to replace Null with
the person's screen name. It IS case sensitive""")
firstMove()
def repeatCommand1():
print('Go right ahead, getIp(Null)')
commandInput = input(">>> ")
if ('getIp(Null)'):
numbers()
time.sleep(3)
print('Ip address added to your nodes.')
time.sleep(2)
os.system('cls')
print("""Now you will need to type myNodes(), which will give you access to all the
ip addresses you have found out so far. Then you will need to type in the
screen name of the person you need the ip of.""")
def myNodes1():
print("So go ahead. myNodes()")
input(">>> ")
if ('myNodes()'):
nodes1()
print("""I just downloaded a bypasser and a password decrypter to your computer. I want you to try
to hack into my computer. First use, connectIp(18.226.109)""")
input(">>> ")
if ('connectIp(18.226.109)'):
connectNull_Tutorial()
else:
print('That is an incorrect command.')
myNodes1()
myNodes1()
else:
repeatCommand1()
repeatCommand1()
tutorial()
game()
The problem with the program, is that where there is an if/else command, it doesn't work. I tested out the program just now, to see that when I enter in any sort of input (wherever in the code it says input('>>> ') and then:
if ('blah'):
print('blah')
then:
else:
commandThatgoesBack
I'll try clarifying. Where it says:
def repeatCommand1():
print('Go right ahead, getIp(Null)')
commandInput = input(">>> ")
if ('getIp(Null)'):
numbers()
time.sleep(3)
print('Ip address added to your nodes.')
time.sleep(2)
os.system('cls')
print("""Now you will need to type myNodes(), which will give you access to all the
ip addresses you have found out so far. Then you will need to type in the
screen name of the person you need the ip of.""")
def myNodes1():
print("So go ahead. myNodes()")
input(">>> ")
if ('myNodes()'):
nodes1()
print("""I just downloaded a bypasser and a password decrypter to your computer. I want you to try
to hack into my computer. First use, connectIp(18.226.109)""")
input(">>> ")
if ('connectIp(18.226.109)'):
connectNull_Tutorial()
else:
print('That is an incorrect command.')
myNodes1()
myNodes1()
else:
repeatCommand1()
It clearly, or somewhat clearly states that if you input blah, do this, if you enter anything else, start from the beginning, and input again, over and over until you input the correct thing. Such as:
def goBack():
print('Enter getIp(Null)')
input()
if ('getIp(Null)'):
print('Good job mate')
else:
goBack()
goBack()
(Do note that the code above is used as an example and not necessarily exactly how my code in the actual program is). The program seems to take any input that I enter, and still (using the example above) prints 'Good job mate', even if I don't enter getIp(Null). Every single place in my code where something like the code above appears, the same error pops up. I can literally run the program, and play the whole (current) game just by pressing enter. Anyone know what to do?
result = input(">>>")
if result == "Something":
do_something()
this is pretty basic ... you should probably be running your code more often ...
This is my first app ever. It is working well but I would like to separate the UI concerns like getting input and creating labels, from the translation logic. I would then like to remove the output from the previous translation, i.e., only showing one translation on the screen at a time.
How can I separate the translation logic from my Tkinter GUI?
from Tkinter import *
import tkMessageBox
def start():
inputg = input.get()
if len(inputg) >= 2 and inputg.isalpha():
new_word_out = Label(text=(inputg[1:] + (inputg[0] + "ay")).lower().title()).pack()
out_message = Label(text="Cool! Try another!").pack()
# restart()
elif len(inputg) <= 1 and inputg.isalpha():
show_error(message="Whoops! I need 2 or more characters to translate! Try again!")
return
elif len(inputg) >= 1 and not inputg.isalpha():
show_error(message="Whoops! No numbers or symbols please! Try again!")
return
elif len(inputg) == 0:
show_error(message="It seems you haven't given me anything to translate!")
return
def show_error(message):
tkMessageBox.showerror(title="Error", message=message)
return
def quit():
ask_exit = tkMessageBox.askyesno(title="Quit", message="Are you sure you want to quit?")
if ask_exit > 0:
root.destroy()
return
root = Tk()
input = StringVar() # stores user input into this variable as a string.
root.title("The Pig Translator")
root.protocol("WM_DELETE_WINDOW", quit)
labeltitle1 = Label(text="Hello there! This is my Pig Latin Translator!").pack()
labeltitle2 = Label(text="Please enter a word to continue!", fg='darkgreen', bg='grey').pack()
original_entry = Entry(textvariable=input, bd=5, fg='darkgreen').pack()
translate_button = Button(text="Translate", command=start).pack()
root.bind('<Return>', lambda event: start()) # essentially binds 'Return' keyboard event to translate_button
root.mainloop()
There are many ways you can separate logic from GUI. generally I would recommend using classes and callback functions. Thus, I made a class that generates the gui. However, the translation is performed by external function called do_translation.
MyFrame does not know much about how do_translation. It only knows it returns translated_str, message and takes string as argument. do_translation does not relay on any gui as well. The do_translation takes only an input string, does what it wants, and returns translated string and message. The MyFrame take this function as a callback. You can make any other translation function, and as long as the input and output are same, it will work.
I rely here on a "Cool" in a massage which indicates that translation was ok. Its poor idea to make it relay on 'Cool' word, but did not want to change your code too much. Probably better to raise some error, or use message codes, etc.
from Tkinter import *
import tkMessageBox
class MyFrame(Frame):
def __init__(self, master, input_callback=None, **kwargs):
Frame.__init__(self, master)
self.set_input_callback(input_callback)
self.create_widgets()
self.pack()
def create_widgets(self):
self.input = StringVar() # stores user input into this variable as a string.
self.labeltitle1 = Label(text="Hello there! This is my Pig Latin Translator!")
self.labeltitle1.pack()
self.labeltitle2 = Label(text="Please enter a word to continue!", fg='darkgreen', bg='grey')
self.labeltitle2.pack()
self.original_entry = Entry(textvariable=self.input, bd=5, fg='darkgreen')
self.original_entry.pack()
self.translate_button = Button(text="Translate", command=self.start)
self.translate_button.pack()
self.new_word_out = Label(text='')
self.out_message = Label(text='')
def set_input_callback(self, some_fun):
self.input_callback = some_fun
def show_error(self, message):
tkMessageBox.showerror(title="Error", message=message)
return
def start(self):
inputg = self.input.get()
if self.input_callback:
translated_str, message = self.input_callback(inputg)
if 'Cool' in message:
self.new_word_out['text'] = translated_str
self.new_word_out.pack()
self.out_message['text'] = message
self.out_message.pack()
else:
self.show_error(message)
def do_translation(inputg):
translated_str = message = ''
if len(inputg) >= 2 and inputg.isalpha():
translated_str = (inputg[1:] + (inputg[0] + "ay")).lower()
message = "Cool! Try another!"
elif len(inputg) <= 1 and inputg.isalpha():
message = "Whoops! I need 2 or more characters to translate! Try again!"
elif len(inputg) >= 1 and not inputg.isalpha():
message = "Whoops! No numbers or symbols please! Try again!"
elif len(inputg) == 0:
message = "It seems you haven't given me anything to translate!"
return translated_str, message
def quit():
ask_exit = tkMessageBox.askyesno(title="Quit", message="Are you sure you want to quit?")
if ask_exit > 0:
root.destroy()
return
root = Tk()
root.title("The Pig Translator")
root.protocol("WM_DELETE_WINDOW", quit)
mf = MyFrame(root)
mf.set_input_callback(do_translation)
root.bind('<Return>', lambda event: start()) # essentially binds 'Return' keyboard event to translate_button
root.mainloop()
Hopefully this will be useful. I know, that there is not too much explanation what is happening here, but, don't have much time to write it. Your problem is very general.