Transcribed TextTranscribed Text

Homework 6: GUIs and Recursion Assignment goals This assignment will include defining classes, user interfaces using Tkinter and recursion. Testing GUIS: It is hard to test a GUI program using a testing function. Instead, you should thoroughly exercise your code by running it repeatedly, and maybe even trying random inputs. What happens if you just start typing random things, or clicking random buttons? Where possible, make a list of things to test, and be sure you have checked them all. Preparing and turning in the assignment Download the file to use with this assignment. Put all your programming answers into Be sure that each function or method you write is preceded by a hash-marked comment that indicates the problem number, and inside it a triple quoted comment that describes the function/method’s purpose, and its inputs and outputs. All code should be inside a function or inside the if __name__ == “__main__” statement. Homework questions 1. Building a GUI! Create a GUI program using the tkinter module, and use a style similar to those you learned in the in-class activity and reading. There is an outline of your program in the file, including some helper methods. Your task is to fill in the missing methods. This program was inspired by a recent article about Game of Thrones, talking about how the actors do not get paper scripts, in an attempt to keep the plot a secret. Instead, the actors work with a tablet app to learn their lines. The purpose of this GUI program is to read in a (slightly formatted) text file containing a script, and to display one stage direction or character’s line at a time, allowing the user to move forward or backward through the script. The program should include two Label widgets for the filename of the script file, plus a Label widget to display the text, and 4 Button widgets: to load a script file, to go to the previous or next line, and to quit. Step 1: Fill in the __init__ method for the class definition for LineGUI, such that it: (1) creates a Tk window object (setting its title to be “Line Presenter”) (2) creates and places the 7 required widgets on the grid to implement a GUI that looks like the picture below (3) defines and initializes the instance variables that will hold the name of the file, the text of the file, and the index into the file text (see notes below) Notes about the __init__ method: ● You can use whatever font you’d like. If you want to match this color scheme, the code used "dark green", "light green", and "floral white". You may use something else if your computer doesn’t support those colors.. ● Use external padding by setting padx and pady values of 10 or 5 in the call to the grid method for each widget. ● I placed widgets in rows 0 and 1, and in columns 0, 1, 2, and 3, with the big label box spanning 2 columns. ● Set the labels to have fixed width and height (experiment!). ● Each button should have its own callback function assigned to it: loadFile, doQuit, previousLine, and nextLine. You will implement some of those later. ● Set up instance variables self.filename, self.lines, and self.lineIndex, to hold the script information. The first will eventually hold the filename the user selects; in __init__ set it to be an empty string. The second will be a list of strings, where each string is a multiline string holding one line of dialogue or stage direction. That will be done later, in __init__ set it to be an empty list. The third will be the index of the currently-displayed line in the script. Set this to be None initially, so we can distinguish when no script has been loaded, versus when one is in place. Before moving on to implement callbacks for the Prev and Next buttons (and their helper), test your program and see if it looks right and displays values where you want them. Step two: Complete the displayLine helper method. This method is used by three of the Button callback methods (loadFile, previousLine, nextLine). This method should do the following: ● Check to see if the line index (self.lineIndex) is a number. ● If it is, set the big label’s text to be the line at the current index. ● If it is not a number, then set the big label’s text to the empty string. To test this function, you can use the Load File button, which calls it. See what happens when the user cancels out of the file-loading dialog box without selecting a file. Step three: Complete the previousLine and nextLine methods. These are callback methods bound to the Prev and Next buttons. As button callbacks, they should take no inputs other than the required self input all methods have. The previousLine method should do this: ● Check if the line index instance variable is None ○ If so, do nothing ● If the line index instance variable is zero, then there is no previous line, ○ do nothing ● Otherwise: ○ update the index variable to be one less than before ○ call self.displayLine The nextLine callback method is similar Test these functions on more than one of the text files provided to you: the program should now be complete. 2. More GUIs – this time with a Canvas! For this question you are going to debug two methods that are part of another GUI program. This program has a class, WallGUI, which creates a window with a title label, a quit button, a “reset game” button, and a big canvas. On the canvas is drawn a simple maze, and a blue square that the user controls. There is a goal rectangle in the maze as well. The user must move the square from its starting location to the goal without touching any walls. If the square touches a wall, the user loses the game. If the square touches the goal rectangle, the user wins! At any point the user may click the quit button to end the program, or the “reset game” button to reset the game back to the beginning. First of all, uncomment the entire class declaration. There are seven methods in this class/program: __init__, go, drawMaze, moveToward, checkForEndOfGame, resetGame, and doQuit. The __init__ method and the moveToward method are buggy, the rest are not. ● First, debug the __init__ method. This sets up the window and the four widgets. When it is working correctly, it should look produce something like this: There are two bugs in this method. More than one bug per line is possible. Find the two bugs, mark them and explain them, and correct them! ● Next, debug the moveToward callback method. This method is called when the user clicks on the canvas widget. We can get the location in the canvas where the mouse was clicked from the method’s input, event. The (x, y) coordinates in the canvas are in event.x and event.y. This method then determines whether the user clicked mostly to the right, above, to the left, or below the rectangle, and it moves the rectangle 10 pixels in that direction. Finally, it checks to see whether the game is over, win or loss. There are three bugs in moveToward. More than one bug per line is possible. Find the three bugs, mark them, explain them, and fix them. When it is working, you should be able to play the game as shown in the demo video. interleave. This function takes in two lists, and it combines them by alternating the elements of the two lists. Any extra elements are tacked on to the end. Below are some calls to the interleave function, and what they should return. >>> interleave([10, 20], [4, 8]) [10, 4, 20, 8] >>> interleave(['a', 'e', 'i', 'o', 'u'], ['x', 'y']) ['a', 'x', 'e', 'y', 'i', 'o', 'u'] >>> interleave([19], []) [19] >>> interleave([], ['one']) ['one'] The base case for this function occurs when one or the other input list is empty. In that case, it returns a copy of the other input list. When both lists are non-empty, the function calls itself recursively, removing the first element from each list. It then adds those elements to the answer from the recursion to complete the work required. Your task is to draw a diagram that shows the sequence of recursive calls that would be made, and partial results returned, for a call to this function Be sure to indicate the values of the input parameters in each call, and the returned value passed back to the previous call. Here is the call: interleave([6, 8, 10], [-10, -20, -30, -40]) 4. I have written a recursive function to determine whether a string is a palindrome. The base case is when the input string is empty. The empty string is definitely a palindrome. Otherwise, the function compares the first and last elements of the string. If they are different, then the string isn't a palindrome. Otherwise, it removes first and last, and repeats for the remaining elements of the string. Note that this function, to keep it simple, it does not work with varying capitalization, or with punctuation or spaces that complicate the strings. Here are some examples of what the function should do, further examples are in the testing file. >>> isPalindrome('anna') True >>> isPalindrome('lionOil') False >>> isPalindrome('racecar') True >>> isPalindrome('palindrome') False The isPalindrome function I've given you has three bugs in it. Find the bugs, label the lines they are on, and fix them. Use the testing function in to check for correctness.

Solution PreviewSolution Preview

These solutions may offer step-by-step problem-solving explanations or good writing examples that include modern styles of formatting and construction of bibliographies out of text citations and references. Students may use these solutions for personal skill-building and practice. Unethical use is strictly forbidden.



# -----------------
# Put import statements here

import random
from tkinter import *
import turtle
import time
import tkinter.filedialog as tkFileDialog

# =========================================================================
# Question 1
# Add code for the LineGUI class below

class LineGUI(object):

    def __init__(self):
       """Sets up the instance variables that will hold the lines of text, and also the GUI elements.
       All instance variables are initialized in this method."""
       self.filename = ""
       self.lines = []
       self.lineIndex = None
       self.mainWin = Tk()
       self.mainWin.title("Line Presenter")
       self.mainWin.config(bg='dark green')
       self.loadButton = Button(self.mainWin, text="Load File", command=self.loadFile, font="Arial 10 bold")
       self.loadButton.grid(row=0, column=0, padx=10, pady=10)
       self.fileLabel = Label(self.mainWin, text="File:", font="Arial 10 bold")
       self.fileLabel.grid(row=0, column=1, padx=10, pady=10)
       self.fileLabel.config(bg='light green')
       self.fileNameLabel = Label(self.mainWin, text=self.filename, width=50, font="Arial 10 bold")
       self.fileNameLabel.grid(row=0, column=2, columnspan=2, padx=10, pady=10)
       self.fileNameLabel.config(bg='floral white')
       self.quitButton = Button(self.mainWin, text="Quit", command=self.doQuit, font="Arial 10 bold")
       self.quitButton.grid(row=0, column=4, padx=10, pady=10)
       self.prevButton = Button(self.mainWin, text="Prev", command=self.previousLine, font="Arial 10 bold")
       self.prevButton.grid(row=1, column=0, padx=10, pady=10)
       self.lineLabel = Label(self.mainWin, text="", width=60, height=20, wraplength=500, font="Arial 12 bold")
       self.lineLabel.grid(row=1, col...

By purchasing this solution you'll be able to access the following files: and Part2OUTPUT.png.

for this solution

or FREE if you
register a new account!

PayPal, G Pay, ApplePay, Amazon Pay, and all major credit cards accepted.

Find A Tutor

View available Python Programming Tutors

Get College Homework Help.

Are you sure you don't want to upload any files?

Fast tutor response requires as much info as possible.

Upload a file
Continue without uploading

We couldn't find that subject.
Please select the best match from the list below.

We'll send you an email right away. If it's not in your inbox, check your spam folder.

  • 1
  • 2
  • 3
Live Chats