Python Forum
Splitting code into several files
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Splitting code into several files
#1
Hi Everyone ..
I am trying to split a large .py program into a number of smaller .py files to make maintenance and editing easier ..
I have moved a block of the code into a separate .py file, and when I try running the Main program, I start getting all manner of errors, such as, "tkinter is not defined", frames I defined (in the main) are not defined in the child .py file .. In the Main program I have either "Import Reporting" or "from Reporting import *", and neither statement changes the errors I'm getting ..
I feel I'm missing a basic concept or hint here, but I cannot see it right now ..
If it's a help, I'm working on this inside PyCharm 2021.3 .. Personally, I'm fairly new to Python, but I have a fair bit of programming experience over the years ..
Any suggestions would be useful ..
Thanks in advance ..
thomas
Reply
#2
Have you imported the new file into the old?

In old file: import newfile (drop the .py from import statement)

Please show code.
Reply
#3
Hi there ..
I've included the essentials of the code I'm dealing with .. Where you see <snip>, I've removed tracts of code that doesn't need to be here ..
When I run the code, first error I get is the call to 'setup_reporting_frame', then "name 'tk' is not defined" .. If I define tkinter inside the reporting.py code, next it will complain that 'root' is not defined .. and so on ..
My thinking was that each of the .py modules was compiled, and then the linker would resolve all the naming issues .. Or am I mistaken on that ??
Code follows .. .. ..


*********************************************************
main.py
*********************************************************
#  Call Schedule Program -- v0.1a
#  Here we go ..

import tkinter as tk
import tkinter.font as font

from reporting import *				# bring in the stuff from reporting.py


def center_window_on_screen():
# This centres the window when it is not maximised.

    x_cord = int((screen_width / 2) - (width / 2))
    y_cord = int((screen_height / 2) - (height / 2))
    root.geometry(f"{width}x{height}+{x_cord}+{y_cord}")
<<snip!>>

def change_main_to_report():
# changes from main frame to schedule management frame

    reporting_frame.pack(fill='both', expand=1)
    main_frame.forget()


def change_report_to_main():
# changes from schedule management frame back to main frame
    main_frame.pack(fill='both', expand=1)
    reporting_frame.forget()
<<snip!>>

# ---------------< Begin the real work >---------------
# Let's set up the window ...

root = tk.Tk()
root.title("The Dreaded Call Schedule v0.1a")
root.configure(bg='lightyellow')

width, height = 800, 600
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
center_window_on_screen()

# Here, we create frames which we will swap between 
main_frame = tk.Canvas(root, width=800, height=600)
file_maint_frame = tk.Canvas(root, width=800, height=600)
phys_maint_frame = tk.Canvas(root, width=800, height=600)
reporting_frame = tk.Canvas(root, width=800, height=600)		# setup reporting frame

# Let's create the fonts that we need.
font_large = font.Font(family='Candara',
                       size=24,
                       weight='bold')
font_small = font.Font(family='Candara',
                       size=12)

# ---------------< Main Frame >---------------
# The widgets needed for the Main frame.
# First, let's display the logo.
<<snip!>>

# ---------------< Reporting Frame >---------------
# The widgets needed for the File Maintenance frame.

setup_reporting_frame()			# this code got moved into reporting.py (below)


# ---------------< Open and Read data files >---------------

# Open the files and set those up
#  Physician, Special Characters, Calendar, Main Schedule
<<snip!>>


# ---------------< Main Routine >---------------
# 

main_frame.pack(fill='both', expand=1)

root.mainloop()



*********************************************************
reporting.py
*********************************************************


# ---------------< Reporting Frame >---------------
# The widgets needed for the reporting frame.

def setup_reporting_frame():

    reporting_frame = tk.Canvas(root, width=800, height=600)

    img_logo_report = tk.PhotoImage(file='logo.png')
    lbl_logo_report = tk.Label(reporting_frame, image=img_logo_report)
    lbl_logo_report.place(x=680, y=8)

# add a heading.
    lbl_heading_report = tk.Label(reporting_frame,
                            text='Reporting Menu',
                            font=font_large)
    lbl_heading_report.place(x=150, y=100)

# button for main availability
    btn_change_report_to_main_avail_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Main Availability',
                               command=change_report_to_main_avail_rpt)
    btn_change_report_to_main_avail_rpt.place(x=150, y=200)

# button for surgical avail
    btn_change_report_to_sx_avail_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Surgical Availability',
                               command=change_report_to_sx_avail_rpt)
    btn_change_report_to_sx_avail_rpt.place(x=350, y=200)

# button to generate main schedule
    btn_change_report_to_main_sched_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Main Call Schedule',
                               command=change_report_to_main_sched_rpt)
    btn_change_report_to_main_sched_rpt.place(x=150, y=250)

# button to generate surgical schedule
    btn_change_report_to_sx_sched_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Surgical Schedule',
                               command=change_report_to_sx_sched_rpt)
    btn_change_report_to_sx_sched_rpt.place(x=350, y=250)

# button to swap back to the main frame.
    btn_change_to_main = tk.Button(reporting_frame,
                               font=font_small,
                               text='Exit',
                               command=change_report_to_main)
    btn_change_to_main.place(x=150, y=350)
Larz60+ write Jun-24-2022, 03:00 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Fixed for you this time. Please use BBCode tags on future posts.
Reply
#4
I have to go out for several hours, If this post remains unanswered when I return, I'll show you how to proceed.
Reply
#5
Alright .. Below is the code -- all of it .. I fully know it's not the greatest, but I'm learning ..

#  Call Schedule Program -- v0.1a
#  Here we go ..

import tkinter as tk
import tkinter.font as font
import csv as csv
import numpy as np

from reporting import *


def center_window_on_screen():
# This centres the window when it is not maximised.

    x_cord = int((screen_width / 2) - (width / 2))
    y_cord = int((screen_height / 2) - (height / 2))
    root.geometry(f"{width}x{height}+{x_cord}+{y_cord}")


def change_main_to_filem():
# changes from main frame to file management frame

    file_maint_frame.pack(fill='both', expand=1)
    main_frame.forget()


def change_filem_to_main():
# changes from file management frame back to main frame
    main_frame.pack(fill='both', expand=1)
    file_maint_frame.forget()


def change_main_to_schedm():
# changes from main frame to schedule management frame

    sched_maint_frame.pack(fill='both', expand=1)
    main_frame.forget()


def change_schedm_to_main():
# changes from schedule management frame back to main frame
    main_frame.pack(fill='both', expand=1)
    sched_maint_frame.forget()


def change_main_to_report():
# changes from main frame to schedule management frame

    reporting_frame.pack(fill='both', expand=1)
    main_frame.forget()


def change_report_to_main():
# changes from schedule management frame back to main frame
    main_frame.pack(fill='both', expand=1)
    reporting_frame.forget()


def change_filem_to_physm():
# changes from file maint frame to physican management frame

    phys_maint_frame.pack(fill='both', expand=1)
    file_maint_frame.forget()


def change_filem_to_charm():
# changes from file maint frame to special character management frame

    char_maint_frame.pack(fill='both', expand=1)
    file_maint_frame.forget()


def change_filem_to_calm():
# changes from file maint frame to calendar management frame

    cal_maint_frame.pack(fill='both', expand=1)
    file_maint_frame.forget()


def change_physm_to_filem():
# changes from physician maint frame back to file maint
    file_maint_frame.pack(fill='both', expand=1)
    phys_maint_frame.forget()


def change_charm_to_filem():
# changes from character maint frame back to file maint
    file_maint_frame.pack(fill='both', expand=1)
    char_maint_frame.forget()


def change_calm_to_filem():
# changes from calendar maint frame back to file maint
    file_maint_frame.pack(fill='both', expand=1)
    cal_maint_frame.forget()


def change_report_to_main_avail_rpt():
# changes from reporting frame to main availability report frame

    main_avail_frame.pack(fill='both', expand=1)
    reporting_frame.forget()


def change_main_avail_rpt_to_report():
# changes from main availability frame back to reporting frame
    reporting_frame.pack(fill='both', expand=1)
    main_avail_frame.forget()


def change_report_to_sx_avail_rpt():
# changes from reporting frame to surgical availability report frame

    sx_avail_frame.pack(fill='both', expand=1)
    reporting_frame.forget()


def change_sx_avail_rpt_to_report():
# changes from surgical availability frame back to reporting frame
    reporting_frame.pack(fill='both', expand=1)
    sx_avail_frame.forget()


def change_report_to_main_sched_rpt():
# changes from reporting frame to main schedule reporting frame

    main_sched_rpt_frame.pack(fill='both', expand=1)
    reporting_frame.forget()


def change_main_sched_rpt_to_report():
# changes from schedule management frame back to main frame
    reporting_frame.pack(fill='both', expand=1)
    main_sched_rpt_frame.forget()


def change_report_to_sx_sched_rpt():
# changes from reporting frame to surgical reporting frame

    sx_sched_rpt_frame.pack(fill='both', expand=1)
    reporting_frame.forget()


def change_sx_sched_rpt_to_report():
# changes from surgical reporting frame back to main frame
    reporting_frame.pack(fill='both', expand=1)
    sx_sched_rpt_frame.forget()


def save_rtn():
    print("Save and Exit")
    file_save()
    exit()

def exit_rtn():
    print("Quit")
    exit()

# save all our files...
def file_save():
    temp_file = open("Physician.sch", 'w')
    rows = len(df_phys)
    cols = len(df_phys[0])
    print("Phys : ", rows, cols)
    for i in range(rows):
        for j in range(cols):
            temp_file.write(df_phys[i][j] + "\n")
    temp_file.close()

    temp_file = open("Calendar.sch", 'w')
    rows = len(df_cal)
    cols = len(df_cal[0])
    print("Cal  : ", rows, cols)
    for i in range(rows):
        for j in range(cols):
            temp_file.write(df_cal[i][j] + "\n")
    temp_file.close()

    temp_file = open("Schedule.sch", 'w')
    rows = len(df_sched)
    cols = len(df_sched[0])
    print("Sched: ", rows, cols)
    for i in range(rows):
        for j in range(cols):
            temp_file.write(df_sched[i][j] + "\n")
    temp_file.close()


# ---------------< Begin the real work >---------------

# Let's set up the window ...

root = tk.Tk()
root.title("The Dreaded Call Schedule v0.1a")
root.configure(bg='lightyellow')
# Set the icon used for your program
# root.PhotoImage(file='info.png'))

width, height = 800, 600
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
center_window_on_screen()

# Here, we create frames which we will swap between 
# main_frame = tk.Frame(root)
main_frame = tk.Canvas(root, width=800, height=600)
file_maint_frame = tk.Canvas(root, width=800, height=600)
phys_maint_frame = tk.Canvas(root, width=800, height=600)
char_maint_frame = tk.Canvas(root, width=800, height=600)
cal_maint_frame = tk.Canvas(root, width=800, height=600)
sched_maint_frame = tk.Canvas(root, width=800, height=600)
reporting_frame = tk.Canvas(root, width=800, height=600)
main_avail_frame = tk.Canvas(root, width=800, height=600)
sx_avail_frame = tk.Canvas(root, width=800, height=600)
main_sched_rpt_frame = tk.Canvas(root, width=800, height=600)
sx_sched_rpt_frame = tk.Canvas(root, width=800, height=600)

# Let's create the fonts that we need.
font_large = font.Font(family='Candara',
                       size=24,
                       weight='bold')
font_small = font.Font(family='Candara',
                       size=12)

# ---------------< Main Frame >---------------
# The widgets needed for the Main frame.
# First, let's display the logo.

img_logo_main = tk.PhotoImage(file='logo.png')
lbl_logo_main_frame = tk.Label(main_frame,
                               image=img_logo_main)
lbl_logo_main_frame.place(x=680, y=8)

# Next, comes the heading for this frame.
lbl_heading_main_frame = tk.Label(main_frame,
                            text='Welcome to the Call Schedule',
                            font=font_large)
lbl_heading_main_frame.place(x=200, y=100)

btn_change_to_work = tk.Button(main_frame,
                               text='File Maintenance',
                               font=font_small,
                               command=change_main_to_filem)
btn_change_to_work.place(x=250, y=200)

btn_change_to_sched = tk.Button(main_frame,
                               text='Schedule Work',
                               font=font_small,
                               command=change_main_to_schedm)
btn_change_to_sched.place(x=400, y=200)

btn_change_to_report = tk.Button(main_frame,
                               text='Produce Reports',
                               font=font_small,
                               command=change_main_to_report)
btn_change_to_report.place(x=250, y=250)

btn_change_to_stuff = tk.Button(main_frame,
                               text='?? future ??',
                               font=font_small,
                               command=change_main_to_schedm)
btn_change_to_stuff.place(x=400, y=250)

btn_save_work = tk.Button(main_frame,
                          font=font_small,
                          text='Save and Exit',
                          command=save_rtn)
btn_save_work.place(x=250, y=350)

btn_exit_work = tk.Button(main_frame,
                          font=font_small,
                          text='Quit - no Save',
                          command=exit_rtn)
btn_exit_work.place(x=400, y=350)

main_frame.create_line(700, 200, 750, 400, width=3, fill='orange')

# ---------------< File Maintenance Frame >---------------
# The widgets needed for the File Maintenance frame.

# First the image gets added.
img_logo_filem = tk.PhotoImage(file='logo.png')
lbl_logo_file_maint = tk.Label(file_maint_frame,
                         image=img_logo_filem)
lbl_logo_file_maint.place(x=680, y=8)

# Next, we'll add a heading.
lbl_heading_file_maint = tk.Label(file_maint_frame,
                            text='File Maintenance',
                            font=font_large)
lbl_heading_file_maint.place(x=150, y=100)

# We need the button for Physician Maintenance
btn_change_to_phys_maint = tk.Button(file_maint_frame,
                               font=font_small,
                               text='Physician Maintenance',
                               command=change_filem_to_physm)
btn_change_to_phys_maint.place(x=150, y=200)

# We need the button for Special Character Maintenance
btn_change_to_char_maint = tk.Button(file_maint_frame,
                               font=font_small,
                               text='Character Maintenance',
                               command=change_filem_to_charm)
btn_change_to_char_maint.place(x=350, y=200)

# We need the button for Calender Maintenance
btn_change_to_cal_maint = tk.Button(file_maint_frame,
                               font=font_small,
                               text='Calender Maintenance',
                               command=change_filem_to_calm)
btn_change_to_cal_maint.place(x=150, y=250)

# We need the button to swap back to the main frame.
btn_change_to_main = tk.Button(file_maint_frame,
                               font=font_small,
                               text='Exit',
                               command=change_filem_to_main)
btn_change_to_main.place(x=150, y=300)

file_maint_frame.create_line(750, 300, 700, 400, width=3, fill='purple')

# ---------------< reporting frame >---------------

setup_reporting_frame()

## import Reporting
## from Reporting import *

# ---------------< Open and Read data files >---------------

# Open the files and set those up
#  Physician, Special Characters, Calendar, Main Schedule

# ---------------< Physician File >---------------

#Counts the number of lines in the File
temp_file = open("physician.sch", 'r')
count = 0
for x in temp_file:
    count = count + 1
temp_file.close()

#Calculating number of rows (Total lines / columns)
rows = int(count / 11)

#Initializing Lists
df_phys = []
temp_list = []

#The actual code
temp_file = open("physician.sch", 'r')
for i in range(rows):
    for j in range(11):
        x = temp_file.readline()
        temp_list = temp_list + x.splitlines()
    print(temp_list)
    df_phys.append(temp_list)
    temp_list = []

print(df_phys)
temp_file.close()

# ---------------< Calendar File >---------------

#Counts the number of lines in the File
temp_file = open("calendar.sch", 'r')
count = 0
for x in temp_file:
    count = count + 1
temp_file.close()

#Calculating number of rows (Total lines / columns)
rows = int(count / 3)

#Initializing Lists
df_cal = []
temp_list = []

#The actual code
temp_file = open("calendar.sch", 'r')
for i in range(rows):
    for j in range(3):
        x = temp_file.readline()
        temp_list = temp_list + x.splitlines()
    print(temp_list)
    df_cal.append(temp_list)
    temp_list = []

print(df_cal)
temp_file.close()


# ---------------< Schedule File >---------------

#Counts the number of lines in the File
temp_file = open("schedule.sch", 'r')
count = 0
for x in temp_file:
    count = count + 1
temp_file.close()

#Calculating number of rows (Total lines / columns)
rows = int(count / 15)

#Initializing Lists
df_sched = []
temp_list = []

#The actual code
temp_file = open("schedule.sch",'r')
for i in range(rows):
    for j in range(15):
        x = temp_file.readline()
        temp_list = temp_list + x.splitlines()
    print(temp_list)
    df_sched.append(temp_list)
    temp_list = []

print(df_sched)
temp_file.close()

# ---------------< Physician Maintenance Frame >---------------
# The widgets needed for the File Maintenance frame.

# First the image gets added.
img_logo_phys = tk.PhotoImage(file='info.png')
lbl_logo_phys_maint = tk.Label(phys_maint_frame,
                         image=img_logo_phys)
lbl_logo_phys_maint.place(x=680, y=8)

# Next, we'll add a heading.
lbl_heading_phys_maint = tk.Label(phys_maint_frame,
                            text='Physician Maintenance',
                            font=font_large)
lbl_heading_phys_maint.place(x=150, y=100)

# We need the button to swap back to the main frame.
btn_change_to_filem = tk.Button(phys_maint_frame,
                               font=font_small,
                               text='Exit',
                               command=change_physm_to_filem)
btn_change_to_filem.place(x=150, y=300)

phys_maint_frame.create_line(750, 300, 700, 400, width=3, fill='green')


# ---------------< Calendar Maintenance Frame >---------------
# The widgets needed for the File Maintenance frame.

# First the image gets added.
img_logo_cal = tk.PhotoImage(file='info.png')
lbl_logo_cal_maint = tk.Label(cal_maint_frame,
                         image=img_logo_cal)
lbl_logo_cal_maint.place(x=680, y=8)

# Next, we'll add a heading.
lbl_heading_cal_maint = tk.Label(cal_maint_frame,
                            text='Calendar Maintenance',
                            font=font_large)
lbl_heading_cal_maint.place(x=150, y=100)

# We need the button to swap back to the main frame.
btn_change_to_filem = tk.Button(cal_maint_frame,
                               font=font_small,
                               text='Exit',
                               command=change_calm_to_filem)
btn_change_to_filem.place(x=150, y=300)

cal_maint_frame.create_line(750, 300, 700, 400, width=3, fill='gold')

# ---------------< Schedule Maintenance Frame >---------------
# The widgets needed for the Schedule Maintenance frame.

# First the image gets added.
img_logo_char = tk.PhotoImage(file='info.png')
lbl_logo_char_maint = tk.Label(sched_maint_frame,
                         image=img_logo_char)
lbl_logo_char_maint.place(x=680, y=8)

# Next, we'll add a heading.
lbl_heading_char_maint = tk.Label(sched_maint_frame,
                            text='Main Schedule Maintenance',
                            font=font_large)
lbl_heading_char_maint.place(x=150, y=100)

# We need the button to swap back to the main frame.
btn_change_to_filem = tk.Button(sched_maint_frame,
                               font=font_small,
                               text='Exit',
                               command=change_schedm_to_main)
btn_change_to_filem.place(x=150, y=300)

char_maint_frame.create_line(750, 300, 700, 400, width=3, fill='light green')

# ---------------< Main Routine >---------------
# Only the quiz frame needs to be shown
# when the program starts.  The work frame
# will only appear when the Change button
# is clicked.
main_frame.pack(fill='both', expand=1)

root.mainloop()
And reporting.py

# ---------------< Reporting Frame >---------------
# The widgets needed for the File Maintenance frame.

def setup_reporting_frame():

## main_frame = tk.Canvas(root, width=800, height=600)
    reporting_frame = tk.Canvas(root, width=800, height=600)

    img_logo_report = tk.PhotoImage(file='logo.png')
    lbl_logo_report = tk.Label(reporting_frame, image=img_logo_report)
    lbl_logo_report.place(x=680, y=8)

# Next, we'll add a heading.
    lbl_heading_report = tk.Label(reporting_frame,
                            text='Reporting Menu',
                            font=font_large)
    lbl_heading_report.place(x=150, y=100)

# We need the button for main availability
    btn_change_report_to_main_avail_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Main Availability',
                               command=change_report_to_main_avail_rpt)
    btn_change_report_to_main_avail_rpt.place(x=150, y=200)

# We need the button for surgical avail
    btn_change_report_to_sx_avail_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Surgical Availability',
                               command=change_report_to_sx_avail_rpt)
    btn_change_report_to_sx_avail_rpt.place(x=350, y=200)

# We need the button to generate main schedule
    btn_change_report_to_main_sched_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Main Call Schedule',
                               command=change_report_to_main_sched_rpt)
    btn_change_report_to_main_sched_rpt.place(x=150, y=250)

# We need the button to generate surgical schedule
    btn_change_report_to_sx_sched_rpt = tk.Button(reporting_frame,
                               font=font_small,
                               text='Surgical Schedule',
                               command=change_report_to_sx_sched_rpt)
    btn_change_report_to_sx_sched_rpt.place(x=350, y=250)

# We need the button to swap back to the main frame.
    btn_change_to_main = tk.Button(reporting_frame,
                               font=font_small,
                               text='Exit',
                               command=change_report_to_main)
    btn_change_to_main.place(x=150, y=350)

    reporting_frame.create_line(750, 300, 700, 400, width=3, fill='aqua')
Error message that comes out ..

Error:
C:\Users\Thomas\PycharmProjects\Sched_v01a\venv\Scripts\python.exe C:/Users/Thomas/PycharmProjects/Sched_v01a/main.py Traceback (most recent call last): File "C:\Users\Thomas\PycharmProjects\Sched_v01a\main.py", line 432, in <module> setup_reporting_frame() File "C:\Users\Thomas\PycharmProjects\Sched_v01a\reporting.py", line 15, in setup_reporting_frame reporting_frame = tk.Canvas(root, width=800, height=600) NameError: name 'tk' is not defined Process finished with exit code 1
As I mentioned in my earlier post, if I try defining tkinter inside of reporting.py, then the error moves to 'root' not being defined, and so on ..
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  "pythonic" way of splitting up my code? liggisten 4 697 Dec-30-2023, 08:23 PM
Last Post: Gribouillis
  splitting file into multiple files by searching for string AlphaInc 2 908 Jul-01-2023, 10:35 PM
Last Post: Pedroski55
  Split gps files based on time (text splitting) dervast 0 1,896 Nov-09-2020, 09:19 AM
Last Post: dervast
Question Code golfing: splitting a list Ofnuts 7 6,186 Jan-12-2017, 11:01 PM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020