Musical game - looking for assistance

Hi everyone,
I’m relatively new to python. I’m a music teacher looking to create a drill exercise where students can practice filling out the circle of fifths with the aim of memorizing it. For a while now, rather than teaching it as a circle, I’ve been having students right it out as a grid. In general they’ve found that easier. It occurred to me that this would be something that could be turned into a python fill in the blank game. I began learning to use the code and now have a rudimentary understanding of Python. I decided, given my rudimentary knowledge of python, that I’d get chat gpt to give me a hand to create the code. I could tell right away that there were some coding issues and I was able to find and fix the initial errors. However I’ve reached a point where I’m stuck. I’ll include the code below but I thought it might be helpful to include the brief I have to chatgpt as well so you could conceptualize what I’m looking to do:

“Create for me a python script fill in the blank grid. The grid will have 15 columns and two rows. Initially, the grid will be blank. The user will use their keyboard to fill in the blanks in the grid. The correct answer for cell A1 will be Cb, for cell B1 the correct answer will be Gb, the correct answer for cell C1 will be Db, the correct answer for cell D1 will be Eb, the correct answer for cell E1 will be Bb, the correct answer for cell F1 will be F, the correct answer for cell G1 will be C, the correct answer for cell H1 will be G, the correct answer for cell I1 will be D, the correct answer for cell J1 will be A, the correct answer for cell K1 will be E, the correct answer for cell L1, will be B, there correct answer for cell M1 will be F#, the correct answer for cell N1 will be C#, the correct answer for cell A2 will be 7b, the correct answer for cell B2 will be 6b, the correct answer for cell C2 will be 5b, the correct answer for cell D2 will be 3b, the correct answer for cell E2 will be 2b, the correct answer for cell F2 will be 1b, the correct answer for cell G2 will be 0, the correct answer for cell H2 will be 1#, the correct answer for cell I2 will be 2#, the correct answer for cell J2 will be 3#, the correct answer for cell K2 will be 4#, the correct answer for cell L2 will be 5#, the correct answer for cell M2 will be 6#, and the correct answer for cell N2 will be 7#. Allow the user to input their answers into the grid. When they are finished they are to press a SUBMIT button. Compare their answers to the correct answers and then present them with a screen that gives them a total of their correct answers out of 29. Also present them with this score as a percentage.”

The following is the code it created (with the corrections I’ve already made):

import tkinter as tk
from tkinter import messagebox

# Define constants for grid size and cell size
GRID_ROWS = 2
GRID_COLS = 15
CELL_WIDTH = 3

# Define correct answers in a dictionary
Correct_answers = {
    "A1": "Cb",
    "B1": "Gb",
    "C1": "Db",
    "D1": "Eb",
    "E1": "Bb",
    "F1": "F",
    "G1": "C",
    "H1": "G",
    "I1": "D",
    "J1": "A",
    "K1": "E",
    "L1": "B",
    "M1": "F#",
    "N1": "C#",
    "A2": "7b",
    "B2": "6b",
    "C2": "5b",
    "D2": "3b",
    "E2": "2b",
    "F2": "1b",
    "G2": "0",
    "H2": "1#",
    "I2": "2#",
    "J2": "3#",
    "K2": "4#",
    "L2": "5#",
    "M2": "6#",
    "N2": "7#",
}

# Create a root window
root = tk.Tk()
root.title("Fill in the blank grid")

# Create a frame to hold the grid of entry widgets
frame = tk.Frame(root)
frame.pack()

# Create a list to store the entry widgets
entries = []

# Loop through the rows and columns of the grid
for i in range(GRID_ROWS):
# Create a sublist for each row
	entries.append([])
    
# Loop through each column in the row 
for j in range(GRID_COLS):
# Create an entry widget with fixed width and center alignment 
	entry = tk.Entry(frame, width=CELL_WIDTH, justify="center")
        
# Place the entry widget in the frame using grid layout 
	entry.grid(row=i, column=j)
        
# Append the entry widget to the sublist 
	entries[i].append(entry)

# Define a function to check the user's input and display the score 
def check_answers():
    
 # Initialize variables to count correct answers and total questions 
	correct = 0 
	total = GRID_ROWS * GRID_COLS
     
# Loop through the rows and columns of the grid 
	for i in range(GRID_ROWS): 
        
# Loop through each column in the row 
		for j in range(GRID_COLS): 
            
# Get the user's input from the entry widget 
			user_input = entries[i][j].get()
             
# Get the cell name from its row and column index 
			cell_name = chr(ord("A") + j) + str(i + 1)
             
# Get the correct answer from the dictionary using cell name as key 
			correct_answer = correct_answers[cell_name]
             
# Compare user's input with correct answer (case insensitive) 
			if user_input.upper() == correct_answer.upper():  
                
# Increment correct count by one if they match  
				correct += 1 
    
 # Calculate score as percentage of correct answers out of total questions  
				score = round(correct / total *100 , ndigits=0)
     
# Display score and percentage in a message box  
				messagebox.showinfo("Result", f"You got {correct} out of {total} questions right.\nYour score is {score}%.")

# Create a button to submit answers and call check_answers function when clicked  
submit_button = tk.Button(root, text="SUBMIT", command=check_answers)
submit_button.pack()

# Start main loop of root window  
root.mainloop()

The issues are:
1.The grid is meant to be 2 columns high, but on my phone/tablet it only ever displays one column
2. There’s meant to be an instruction at the beginning that reads " Fill in the Blank Grid". That also doesn’t display
3. I get an error which according to pydroid (the app I’m using) is occurring at line 83. It reads: Exception in Tkinter callback
Traceback (most recent call last):

    return self.func(*args)
  File "/storage/emulated/0/Documents/5new.py", line 83, in check_answers
    user_input = entries[i][j].get()
IndexError: list index out of range

I’m hoping to eventually add a third column where students can also add the relative minors to the grid but I thought I’d start with a bit simpler version first.

Any help would be greatly appreciated!

These are the mistakes:

  • The first occurrence of the name correct_answers starts with an uppercase letter instead of a lowercase letter as elsewhere.

  • The indentation is incorrect on the lines that report the score.

  • It doesn’t handle the fact that not all of the boxes are used.

Also, there are 28 answers, as in the brief, not 29.

This is the corrected code:

import tkinter as tk
from tkinter import messagebox

# Define constants for grid size and cell size
GRID_ROWS = 2
GRID_COLS = 15
CELL_WIDTH = 3

# Define correct answers in a dictionary
correct_answers = {
    "A1": "Cb",
    "B1": "Gb",
    "C1": "Db",
    "D1": "Eb",
    "E1": "Bb",
    "F1": "F",
    "G1": "C",
    "H1": "G",
    "I1": "D",
    "J1": "A",
    "K1": "E",
    "L1": "B",
    "M1": "F#",
    "N1": "C#",
    "A2": "7b",
    "B2": "6b",
    "C2": "5b",
    "D2": "3b",
    "E2": "2b",
    "F2": "1b",
    "G2": "0",
    "H2": "1#",
    "I2": "2#",
    "J2": "3#",
    "K2": "4#",
    "L2": "5#",
    "M2": "6#",
    "N2": "7#",
}

# Create a root window
root = tk.Tk()
root.title("Fill in the blank grid")

# Create a frame to hold the grid of entry widgets
frame = tk.Frame(root)
frame.pack()

# Create a list to store the entry widgets
entries = []

# Loop through the rows and columns of the grid
for i in range(GRID_ROWS):
    # Create a sublist for each row
    entries.append([])

    # Loop through each column in the row
    for j in range(GRID_COLS):
        # Create an entry widget with fixed width and center alignment
        entry = tk.Entry(frame, width=CELL_WIDTH, justify="center")

        # Place the entry widget in the frame using grid layout
        entry.grid(row=i, column=j)

        # Append the entry widget to the sublist
        entries[i].append(entry)

# Define a function to check the user's input and display the score
def check_answers():
    # Initialize variables to count correct answers and total questions
    correct = 0
    total = len(correct_answers)

    # Loop through the rows and columns of the grid
    for i in range(GRID_ROWS):

    # Loop through each column in the row
        for j in range(GRID_COLS):
            # Get the user's input from the entry widget
            user_input = entries[i][j].get()

            # Get the cell name from its row and column index
            cell_name = chr(ord("A") + j) + str(i + 1)

            # Get the correct answer from the dictionary using cell name as key
            correct_answer = correct_answers.get(cell_name)

            # Compare user's input with correct answer (case insensitive)
            if correct_answer is not None and user_input.upper() == correct_answer.upper():
                # Increment correct count by one if they match
                correct += 1

     # Calculate score as percentage of correct answers out of total questions
    score = round(correct / total *100 , ndigits=0)

    # Display score and percentage in a message box
    messagebox.showinfo("Result", f"You got {correct} out of {total} questions right.\nYour score is {score}%.")

# Create a button to submit answers and call check_answers function when clicked
submit_button = tk.Button(root, text="SUBMIT", command=check_answers)
submit_button.pack()

# Start main loop of root window
root.mainloop()

Wow! Thank you! That worked out great! All the best!