Please critique my python3.4/tkinter code (short program)
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Please critique my python3.4/tkinter code (short program)
This is a die roller program I wrote to learn python. Everything does work, but I do intend on making some modifications, mostly just to make the output easier to read. The first version simply rolled a single die with a user defined number of sides and gave the output in a label, so I think I have come a long way since then considering this is my first python program.
I'm not a part of a class or having any formal training in programming and know few people that do any programming. So I'm curious if there are better ways of doing things than what I have done, both looking a functionality of the final program and the quality of the code itself.
Are there things that I have grouped together and should have separated?
Are there things that I separated and should have grouped together?
Are there shorter ways of accomplishing the same functionality (without having to completely re-write it to make changes later)?
Again I am wanting to make some changes, but I thought that I would go ahead and post this before the code got too long.
Code:
#!/usr/bin/python3.4
import tkinter as tk
from tkinter import ttk
from random import randrange
def roll_loop(bonus, die, sides):
try:
total = int(0)
if bonus != 0: #Check if a bonus should be added
#The loop runs 1 less time than the number of dice
#This is done for formating
for totalrolls in range(0, die):
rolled = int(randrange(1, sides)) #Calculate die roll
result_entry.insert(tk.END, rolled) #These print the results
result_entry.insert(tk.END, " + ")
result_entry.insert(tk.END, bonus)
result_entry.insert(tk.END, " + ")
rollplusbonusloop = int(rolled + bonus) #Add the bonus
total += rollplusbonusloop #Generate a cumulative total
else:
#Run the calculation loop one more time
#This gets to the appropriate number of dice
#While keeping formating
rolled = int(randrange(1, sides))
result_entry.insert(tk.END, rolled)
result_entry.insert(tk.END, " + ")
result_entry.insert(tk.END, bonus)
result_entry.insert(tk.END, " = ")
rollplusbonusloop = int(rolled + bonus)
total += rollplusbonusloop
return total #Return the final total of all rolls
else:
#Run this loop if no bonus is to be added
#Otherwise done the same as above loop
#Separated for formating
for totalrolls2 in range(0, die):
rolled = int(randrange(1, sides))
result_entry.insert(tk.END, rolled)
result_entry.insert(tk.END, " + ")
total += rolled
else:
rolled = int(randrange(1, sides))
result_entry.insert(tk.END, rolled)
result_entry.insert(tk.END, " = ")
total += rolled
return total
except ValueError:
pass
def give_total(*args):
try:
#Pull numbers for calculations
addbonus = int(bonus.get())
numberofdice = int(die.get())
numberofdice -= 1 #Subtracted for formating in the loops
numberofsides = int(sides.get())
numberofsides += 1 #Added to give full range of possibilities
#Calculate total by calling the appropriate loop
total = int(roll_loop(addbonus, numberofdice, numberofsides))
#Print total, equal sign printed at end of loops prior to this
result_entry.insert(tk.END, total)
result_entry.insert(tk.END, "\n") #Add line break at end of rolls
except ValueError:
pass
#Create root
root = tk.Tk()
root.title("Die Roller")
#List of variables
sides = tk.StringVar()
result = tk.StringVar()
die = tk.StringVar()
bonus = tk.StringVar()
#Create main window in root
mainframe = ttk.Frame(root, padding="10")
mainframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
#Create labels
ttk.Label(mainframe, text="Sides").grid(column=4, row=1, sticky=tk.NW)
ttk.Label(mainframe, text="Results").grid(columnspan=6, row=3, sticky=tk.NE)
ttk.Label(mainframe, text="Dice").grid(column=1, row=1, sticky=tk.NW)
ttk.Label(mainframe, text="Bonus").grid(column=6, row=1, stick=tk.NW)
#These labels are for showing order of operations to user
ttk.Label(mainframe, text="X").grid(column=2, row=2, sticky=tk.NW)
ttk.Label(mainframe, text="+").grid(column=5, row=2, sticky=tk.NW)
ttk.Label(mainframe, text="(").grid(column=3, row=2, sticky=tk.NW)
ttk.Label(mainframe, text=")").grid(column=7, row=2, sticky=tk.NW)
#Create buttons
ttk.Button(mainframe, text="Roll", command=give_total).grid(column=8, row=2, sticky=tk.NW)
#Create entry boxes
side_entry = ttk.Entry(mainframe, width=3, textvariable=sides)
side_entry.grid(column=4, row=2, sticky=tk.NW)
die_entry = ttk.Entry(mainframe, width=3, textvariable=die)
die_entry.grid(column=1, row=2, sticky=tk.NW)
die_entry.insert(0, "1")
bonus_entry = ttk.Entry(mainframe, width=3, textvariable=bonus)
bonus_entry.grid(column=6, row=2, sticky=tk.NW)
bonus_entry.insert(0, "0")
#Create a frame to house the result field and scrollbars
result_frame = tk.Frame(mainframe, width=53, height=13)
result_frame.grid(columnspan=9, row=5)
#Create scrollbars for results field
resultyscroll = tk.Scrollbar(result_frame)
resultyscroll.grid(column=2, row=1, sticky=tk.W+tk.N+tk.S)
resultxscroll = tk.Scrollbar(result_frame, orient=tk.HORIZONTAL)
resultxscroll.grid(column=1, row=2, sticky=tk.N+tk.W+tk.E)
#Create text field for listing results
result_entry = tk.Text(result_frame, width=50, height=10, wrap="none")
result_entry.grid(column=1, row=1)
result_entry.config(xscrollcommand=resultxscroll.set, yscrollcommand=resultyscroll.set)
#Connect scrollbars with text field now that both are created
resultyscroll.config(command=result_entry.yview)
resultxscroll.config(command=result_entry.xview)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
#Give focus to side_entry on open
side_entry.focus()
#Bind the return/enter key to give the "give_total" command
root.bind('<Return>', give_total)
root.mainloop()
I have a tip for you; try using pylint. It actually gets you out of bad habits pretty quickly!
If you don't want to install that, you can check your code online: http://pep8online.com/
As nothing to be passed to the script obviously not really a help command required to tell you anything, however, I found that if I blanked / deleted values from one of the entry points (say 'dice'),
instead of being told that it cannot be empty or that empty does not equate to 0 it simply sits there and looks at me and i have no way of knowing if anything happened until I try again. This is
of course being a little pedantic, but some people really like to be spoon fed what is going on
Another usery type thing, if I drag the window to try and see more of the results assuming I picked say 10 dice and want to see all on screen at once, it appears the outer shell gets dragged and made bigger
but not the inner window which is attached to it
Last one from me ... you created the variable 'result', but as far as I can see it is never used. I am not a python guru so it may be needed??
HMW: I had not heard of pep8online or the docstrings. It seems the only complaint from pep8 is with the spacing, but it still runs. I'll still try to fix those just to tidy things up. I just used gedit for writing this and run it in terminal to find errors, there is a gedit plugin for using pylint so I'll try to get that set up as it will be faster than constantly copying code into pep8.
Grail: I have not put in any error messages yet, I probably should start doing that so that it becomes habit. With the resizing I just haven't bothered looking up how to get that to work, what I initially saw for using grid in tkinter was that it should just work, but obviously it doesn't. And the result variable had been used before, but moved away from it when adding in the bonus option and apparently I just didn't delete it from the code.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.