How to avoid circular imports?

twelfth

Overview

EDIT: ALTERED FOLLOWING @IjonTichy's ANSWER

I am trying to import two variables across files. I have a GUI file using tkinter and another file storing a number of variables. The problem specifically is that the GUI file has a tk.Entry field, so the value of the variable is dynamic and changes depending on what is input. I would rather not use a button here. I am using a tk.StringVar object to hold the data (perhaps clearer in the code below.

The second variable is just a float based on a calculation so pretty easy to assign there. The problem I am having is this file requires the tk.StringVar value to perform a calculation.

What I have tried

So firstly I tried simply taking variables from each file, using import [filename] and then [filename].[variable] when I needed to call it. Predictably this caused an error due to circular imports, which makes sense.

Subsequently, I tried dumping all this data into a config file and allowing both files to pull from this third file but that also results in the same.

Code

vitals.py

from datetime import date
from decimal import Decimal

birth = date(1992, 6, 22)
today = date.today()

age = today.year - birth.year - ((today.month, today.day) < (birth.month, birth.day))
weight = 0
height = 177.5
activity = 1.2
#tdee = bmr * activity

def bmr(weight, height, age):
    return Decimal(((10 * float(weight)) + (6.25 * height) - (5 * age) + 5))

GUI.py

import tkinter as tk
import config

app = tk.Tk()
defaultColour = "beige"

mainFrame = tk.Frame(width=200, height=200, bg=defaultColour)
mainFrame.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)

weightLabel = tk.Label(master=mainFrame,text='weight', bg=defaultColour)
weightLabel.pack()

weightVar = tk.DoubleVar() #NEW LINE

weightEntry = tk.Entry(mainFrame, textvariable=weightVar)
weightEntry.pack()
weightEntry.focus_set()

vitals.weight = weightVar.get()
print(vitals.bmr(vitals.weight, vitals.height, vitals.age))

ageLabel = tk.Label(master=mainFrame,text='age: ' + str(config.age), bg=defaultColour)
ageLabel.pack()

app.bind("<Escape>", lambda e: app.destroy())

app.mainloop()

Question

I am at a bit of a loss as to how I might structure this properly. So would someone be able to tell me where I am going wrong? Alternatively if you could point me in the direction of some resources that teach good coding structure. This is my first time coding an application so apologies for the inanity of this question.

Thanks very much.

IjonTichy

Dump the config.py file. initialize your variables in vitals.py and change the variables from GUI.py.

i.e. inside vitals.py:

weight = 0

and inside GUI.py

import vitals
vitals.weight = weightVar.get()

Edit:

the new problem you now have is because your value of bmr depends on weight.

when you do

import vitals

bmr gets calculated with initialized value. When you want to have bmr calculated dynamically you need to change it to a function. So in vitals.py:

def bmr(weight, height, age):
    return Decimal(((10 * float(weight)) + (6.25 * height) - (5 * age) + 5))
    

And then you call it from GUI.py:

import vitals
vitals.weight = weightVar.get()
print(vitals.bmr(vitals.weight, vitals.height, vitals.age))

edit2:

you need to do this for all values that are dependent on other variables

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related