I am a bit new to python yet I have some skills in coding for Arduino and Matlab. But I have a question about a piece of code that I am trying to create. Some info: I would like to create a simple user interface where multiple calculations with formulas can be performed by just clicking 1 calculate button. I defined the parameters through input fields and put in the necessary formulas.
To start of, I tried with a simple calculation script, provided below:
import tkinter as tk
# Function to perform the calculation
def calculate_z():
try:
x = float(x_entry.get())
y = float(y_entry.get())
z = x * y
z_result_var.set(f"z = {z:.2f}")
except ValueError:
z_result_var.set("z = Invalid Input")
# Create the main application window
app = tk.Tk()
app.title("Simple Calculation")
# Create and place input fields with labels
x_label = tk.Label(app, text="Enter x:")
x_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
x_entry = tk.Entry(app)
x_entry.grid(row=0, column=1, padx=10, pady=5)
y_label = tk.Label(app, text="Enter y:")
y_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
y_entry = tk.Entry(app)
y_entry.grid(row=1, column=1, padx=10, pady=5)
# Create and place the Calculate button
calculate_button = tk.Button(app, text="Calculate", command=calculate_z)
calculate_button.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
# Create and place the result label (Display z)
z_result_var = tk.StringVar()
z_result_var.set("z = ")
z_result_label = tk.Label(app, textvariable=z_result_var, font=("Helvetica", 16))
z_result_label.grid(row=3, column=0, columnspan=2, padx=10, pady=5)
# Start the GUI main loop
app.mainloop()
This worked really well and I figured I could just expand the code with multiple inputs and more formulas. The fields can be put in just fine but the calculate button disappears and provides a NameError saying that calculate_button and calculate_z is not defined, when I create more formulas in the calculate_z definition. However if I create a second button and link it all the way through to another def calculate_z1 and create a separate button for it, that works too. But I want to create a code where I can just use 1 button to calculate all formulas at once.
So this is the code that I had set up for myself to have the increased amount of formulas and inputs, I know it is very inefficient (there should be a better way to define all the input fields/output results and probably some more stuff, but this way for me it was understandable. First make it work then try to make it more efficient was my thought.
I am wondering if someone could help me with the problem or advise me on some tips on where to look. I have tried to google the problem and found some codes which didn't even work as example codes. So there I got a bit stuck.
import tkinter as tk
import math
# Function to perform the calculation
def calculate_values():
try:
Te = float(Te_entry.get()) # Engine Torque [Nm]
Ix = float(Ix_entry.get()) # Primary Reduction [-]
I1 = float(I1_entry.get()) # First gear ratio [-]
Phi = float(Phi_entry.get()) # Sprocket Pressure Angle [Deg]
Nr = float(Nr_entry.get()) # Sprocket teeth rear [-]
Nf = float(Nf_entry.get()) # Sprocket teeth front [-]
# Calculate Chain Pitch (CP) in degrees
CP = 180 / Nr
# Calculate Pitch Diameter (PD) in meters
PD = CP / math.sin(CP*(math.pi/180))
# Calculate Pitch Radius (PR) in meters
PR = PD / 2
# Calculate Torque at front Sprocket (Mf) in Nm
Mf = Te * Ix * I1
# Calculate Chain Tension (CT) in N
CT = Mf / PR
# Calculate Tension in X direction (Tx) in N
Tx = T * math.cos(Phi*(math.pi/180))
# Calculate Tension in Y direction (Ty) in N
Ty = T * math.sin(Phi*(math.pi/180))
# Calculate Final Drive Ratio
If = Nr / Nf
# Calculate Torque at Rear Sprocket (Mr) in Nm
Mr = Mf * If
# Update the output results with calculated values
CP_result_var.set(f"CP = {CP:.2f}")
PD_result_var.set(f"PD = {PD:.2f}")
PR_result_var.set(f"PR = {PR:.2f}")
Mf_result_var.set(f"Mf = {Mf:.2f}")
CT_result_var.set(f"CT = {CT:.2f}")
Tx_result_var.set(f"Tx = {Tx:.2f}")
Ty_result_var.set(f"Ty = {Ty:.2f}")
If_result_var.set(f"If = {If:.2f}")
Mr_result_var.set(f"Mr = {Mr:.2f}")
except ValueError:
CP_result_var.set("CP = Invalid Input")
PD_result_var.set("PD = Invalid Input")
PR_result_var.set("PR = Invalid Input")
Mf_result_var.set("Mf = Invalid Input")
CT_result_var.set("CT = Invalid Input")
Tx_result_var.set("Tx = Invalid Input")
Ty_result_var.set("Ty = Invalid Input")
If_result_var.set("If = Invalid Input")
Mr_result_var.set("Mr = Invalid Input")
# Create the main application window
app = tk.Tk()
app.title("Simple Calculation")
# Create and place input fields with labels
Te_label = tk.Label(app, text="Engine Torque [N]:")
Te_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
Te_entry = tk.Entry(app)
Te_entry.grid(row=0, column=1, padx=10, pady=5)
Ix_label = tk.Label(app, text="Phi [deg]:")
Ix_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
Ix_entry = tk.Entry(app)
Ix_entry.grid(row=1, column=1, padx=10, pady=5)
I1_label = tk.Label(app, text="First Gear Ratio [-]:")
I1_label.grid(row=2, column=0, padx=10, pady=5, sticky="w")
I1_entry = tk.Entry(app)
I1_entry.grid(row=2, column=1, padx=10, pady=5)
Phi_label = tk.Label(app, text="Sprocket Pressure Angle [Deg]:")
Phi_label.grid(row=3, column=0, padx=10, pady=5, sticky="w")
Phi_entry = tk.Entry(app)
Phi_entry.grid(row=3, column=1, padx=10, pady=5)
Nr_label = tk.Label(app, text="Rear Sprocket Teeth [-]:")
Nr_label.grid(row=4, column=0, padx=10, pady=5, sticky="w")
Nr_entry = tk.Entry(app)
Nr_entry.grid(row=4, column=1, padx=10, pady=5)
Nf_label = tk.Label(app, text="Front Sprocket Teeth [-]:")
Nf_label.grid(row=5, column=0, padx=10, pady=5, sticky="w")
Nf_entry = tk.Entry(app)
Nf_entry.grid(row=5, column=1, padx=10, pady=5)
# Create and place the Calculate button
calculate_button = tk.Button(app, text="Calculate", command=calculate_values)
calculate_button.grid(row=10, column=1, columnspan=2, padx=10, pady=10)
# Create and place the result label (displayed at all times)
CP_result_var = tk.StringVar()
CP_result_var.set("Chain Pitch [Deg] = ")
CP_result_label = tk.Label(app, textvariable=CP_result_var)
CP_result_label.grid(row=0, column=2, columnspan=2, padx=10, pady=5)
PD_result_var = tk.StringVar()
PD_result_var.set("Pitch Diameter [m] = ")
PD_result_label = tk.Label(app, textvariable=PD_result_var)
PD_result_label.grid(row=1, column=2, columnspan=2, padx=10, pady=5)
PR_result_var = tk.StringVar()
PR_result_var.set("Pitch Radius [m] = ")
PR_result_label = tk.Label(app, textvariable=PR_result_var)
PR_result_label.grid(row=2, column=2, columnspan=2, padx=10, pady=5)
Mf_result_var = tk.StringVar()
Mf_result_var.set("Front Sprocket Torque [Nm] = ")
Mf_result_label = tk.Label(app, textvariable=Mf_result_var)
Mf_result_label.grid(row=3, column=2, columnspan=2, padx=10, pady=5)
CT_result_var = tk.StringVar()
CT_result_var.set("Chain Tension [N] = ")
CT_result_label = tk.Label(app, textvariable=CT_result_var)
CT_result_label.grid(row=4, column=2, columnspan=2, padx=10, pady=5)
Tx_result_var = tk.StringVar()
Tx_result_var.set("Chain Tension X-direction [N] = ")
Tx_result_label = tk.Label(app, textvariable=Tx_result_var)
Tx_result_label.grid(row=5, column=2, columnspan=2, padx=10, pady=5)
Ty_result_var = tk.StringVar()
Ty_result_var.set("Chain Tension Y-direction [N] = ")
Ty_result_label = tk.Label(app, textvariable=Ty_result_var)
Ty_result_label.grid(row=6, column=2, columnspan=2, padx=10, pady=5)
If_result_var = tk.StringVar()
If_result_var.set("Final Drive Ratio [-] = ")
If_result_label = tk.Label(app, textvariable=If_result_var)
If_result_label.grid(row=7, column=2, columnspan=2, padx=10, pady=5)
Mr_result_var = tk.StringVar()
Mr_result_var.set("Rear Sprocket Torque [Nm] = ")
Mr_result_label = tk.Label(app, textvariable=Mr_result_var)
Mr_result_label.grid(row=8, column=2, columnspan=2, padx=10, pady=5)
# Start the GUI main loop
app.mainloop()
From comments, it looks like you are running your code in an interactive shell. This will not work, as each time you have a blank line, the interpreter will start evaluating the code (...
changes back to >>>
). Thus, your calculate_values
function is evaluated on the first blank line in the try
block, which then has no except
and thus is a syntax error. So the function is never defined, which given an error when creating the button, thus the button is not defined in the next line, etc.
In your first code this is not a problem, since there are no blank lines in the function body (or any other indented block). To fix this, you have two options:
python3 your_file.py
Also, note that there is an indentation error and an undefined variable T
in the try
block which have to be fixed first.