From brand guide: https://flsouthern.mediavalet.com/portals/fsc-brand-guidelines
CSC 2280: Intro Programming
(Fall 2024)

Syllabus

LMS

Teachers

Assignments
Assignments


Other Pages

Project 2:
Interface Design


Assigned: Mon Sep 02 2024
Due: 11:59:00 PM on Sun Sep 08 2024
Team Size: 1
Language: Python
Out of: 20 points


In this project, you'll do some things with Turtle World and learn to use your functions even better.

Part 0, 1 points: Write a new function, print_length_sum, that takes two string parameters and prints out the sum of their lengths. You can include extra parameters by separating them by commas in the function header. (Each parameter must have it's own unique name.) Thus, the header for this one could be:

def print_length_sum(string_0, string_1):
This function should print only a number and no extra text.
>>> print_length_sum("Barb", "pizza-eater")
15
>>> print_length_sum("2", "Stickney")
9
Tester.

Part 1, 1 points: Let's update print_animal_sounds by replacing it with a better version. (You should go back and change your old code for this one.) Function calls to this new version will be able to take four arguments, each describing the number of a different animal. This time the order matters, so make sure your header looks like this:

def print_animal_sounds(num_horses, num_ducks, num_cows, num_goats):
Wait! There's a problem! This function has the same name as the old version. If you try to run your tests with the old version, the code won't run because the function's been replaced by this one, and this one requires four arguments. We can fix that problem by creating default values for our parameters. After you get it working, change the header to this:
def print_animal_sounds(num_horses = 3, num_ducks = 4, num_cows = 2, num_goats = 1):
Hooray! Now the old tests should work with the new stuff!
>>> print_animal_sounds()
neighneighneighquackquackquackquackmoomoobleat
>>> print_animal_sounds(1, 2, 3, 4)
neighquackquakmoomoomoobleatbleatbleatbleat
>>> print_animal_sounds(1, 1)
neighquackmoomoobleat
Tester.

Part 2, 2 points: Write a new function, print_average, that takes two numeric parameters and prints out their average. This function should only print one number and no extra text.

>>> print_average(0, 0)
0.0
>>> print_average(10, 20)
15.0
>>> print_average(1.5, 4.5)
3.0
>>> print_average(1.2, 2.3)
1.75
Tester.

Part 3, 0 points: Exercise 3.2

Part 4, 0 points: Expert Practice: Write a function, do_seven_times(f): that executes f seven times. The hard part: write this function in only three lines.

Part 5, 2 points: Write a new function, print_hypotenuse_length, that takes two numeric parameters, say leg_a, and leg_b and prints out the length of the hypotenuse in a right triangle with legs of the given lengths. Again, this should only print out the value, no extra text. Hint: Pythagorean Theorem! Double-hint: the math package has the math.sqrt function. Here's an example:

>>> print_hypotenuse_length(3, 4)
5.0
Tester.

Part 6, 0 points: The next parts use the turtle package, which you should have seen in the homework. That means you're going to want to import the turtle package up at the top of your file, something like this:

'''My CSC 2280 functions.
   author: <Your name here>'''
import math
import turtle
Here you're going to write functions that use turtles to draw things. Your functions are going to take turtles as parameters. Let's start by making a function where we draw a square:
def draw_square(t):
    '''Draws a square with sides of length 100 with the given Turtle t.'''
    for i in range(4):
        #This loop is executed 4 times
        t.fd(100)
        t.rt(90)
Note that t is a (Turtle) parameter, so we need to create it before we call the function. Run your code, then try this out to test it:
>>> raphael = turtle.Turtle()
>>> draw_square(raphael)
Just like in the homework, let's improve the function so that you can specify how big of a square you want. Modify your function like this:
def draw_square(t, side):
    '''Draws a square with sides of the given length with the given Turtle t.'''
    for i in range(4):
        #This loop is executed 4 times
        t.fd(side)
        t.rt(90)
Now you can test it this way:
>>> leonardo = turtle.Turtle()
>>> draw_square(leonardo, 150)
Make sure that when you run your file alone no turtle windows pop up!

Part 7, 3 points:

Write a function, draw_box_row, that makes a Turtle draw a row of boxes (squares). Your function will take three parameters (in this order): the Turtle to draw with, the size of the squares to draw, and the number of boxes. Your function should use that Turtle to draw that many squares (of the given size) in a row. (The squares should be directly next to each other.) I don't have a tester file for this because I need to check it visually, but you can test you call in a similar way as the previous one:
>>> mike = turtle.Turtle()
>>> draw_box_row(mike, 125, 5)
If this is running too slow for you, you can speed it up by using the delay function:
>>> mike = turtle.Turtle()
>>> screen = mike.getscreen()
>>> screen.delay(1)
>>> draw_box_row(mike, 125, 5)
Remember to make sure your code doesn't pop up a turtle at all!

Part 8, 2 points:

Do the same as in the previous part, except that instead of drawing a single row of boxes, draw an entire grid of boxes. Write a function named draw_box_grid(t, size, width, height). It should draw a grid of width x height boxes. I definitely recommend setting the delay for this one!

Part 9, 2 points: Write a new function, draw_baseball_diamond(t, size) that uses the given turtle to draw a baseball-diamond-type shape with sides of that size. Your diamond can look like either of these: (The right-hand one with the pentagonal home plate is more difficult to draw. Give that one a try!)
Possible output for draw_baseball_diamond().
To test it, first create the turtle, then call the function.

Part 10, 0 points: I recommend trying exercises 4.2 and 4.3.

Part 11, 0 points: Expert Practice: Try exercise 4.4.

Part 12, 0 points:

Let's write some code to pop up a window that a user could interact with. We'll use the tkinter package for this, so start by importing that near the top of your file after the header:
'''My CSC 2280 functions.
   author: <Your name here>'''
import math
import turtle
import tkinter
Let's write a simple function, nothing_window that just pops up a window. In order to open a window, you're going to create that by creating a Tk object, like this:
def nothing_window():
    window = tkinter.Tk()
There are parentheses after that because you're creating a new object, just like with the turtles. (We'll learn a lot more about that later in the course.) If you want to add your own title to the window, you can do that with another line:
    window = tkinter.Tk()
    window.title('monkeys!')
If you run this in its own file and not in interactive mode, it will automatically close. If we want to hold the window open, we can add another line of code at the end of the function, window.mainloop(). This calls a function that never stops on it's own and instead lets the user interact with the window and its elements. When you close the window, then the function will complete (and the thread of computation will continue). Putting everything together, your function should look like this:
def nothing_window():
    '''Creates the most boring window.'''
    window = tkinter.Tk('My Favorite Window')
    window.mainloop()
For our little functions, we won't worry about that line, but it would be important if you were writing a large application that used GUI windows.

Part 13, 0 points:

A window like what we're creating is known as a GUI, for Graphical User Interface. (A non-graphical UI would include something like using a terminal where you enter commands via text.) When running this natively (on your own computer directly) then in order to close the GUI window, you'll either need to click the X on the box or hit Ctrl+C in whatever window you executed the program. (It might be Command+C for Macs.) Remember this for when you get stuck.

Part 14, 2 points:

If we want to add a message in our window, that's done by adding a label. Creating a label is similar to creating a window:
label = tkinter.Label(text = "This is my first GUI.")
When creating that object, there are a lot of optional parameters, so specifying text in there tells it which one you want to give a specific value for. (All the others will stick to the default values.) Write a new function, label_window that creates your own label that includes a message no one else will pick. To add the label to the window, use the pack method like this after you create it (still inside the function):
label.pack()
If your label is not showing up, you may have to create it and call that pack method in a different spot from your first instinct. Please don't call the mainloop() function inside your function!

Part 15, 0 points:

So far we don't have anything that's actually interactive about our GUI, so let's add a button. Write a new function, hello_button(), that creates a window with a button. You can create a button and add it to the window in much the same way you create a label.

Part 16, 0 points:

I know, clicking that button is very satisfying. Let's make it even more satisfying by having it do something! When a button is clicked, it tries to call a function that has been bound to it. We can do that by using the bind operation (method) for that button. It calls that with a parameter that provides information about the click, usually named event. You'll want to define the function you want to call ahead of time, and give it that event parameter (even if you don't use it). Here's an example of me printing 'monkey':
def print_monkey(event):
    '''Prints the string 'monkey'.'''
    print('monkey')

def hello_button():
    button = tkinter.Button(text = 'Press me!')
    button.bind('<Button-1>', print_monkey)
    button.pack()
The <Button-1> string is used for buttons, so you'll need to include that. (I found out about it online.) The function that is bound to the button is called an event handler. Update hello_button() so that the button prints out Hello, World! when pressed.

Part 17, 2 points:

We can also modify properties of the elements using the config operation. For example, we can change the text in a button like this:
def say_bye(event):
    '''Changes the text of a button to be 'Bye'.'''
    button = event.widget
    button.config(text = 'Bye')

def hi_button():
    button = tkinter.Button(text = 'Hi')
    button.bind('<Button-1>', say_bye)
    button.pack()
You do need to include the text = part, just like when creating the button or label. Notice that inside the say_bye function, Python doesn't know what the button is until after you fetch it from the event. That's because the variable button defined in hi_button only exists in the body of that function. Write a function, my_changing_text_button, that creates a GUI with a button and a label. The label should start with text that changes when the button is pressed the first time. Since the label isn't part of the event, you'll need to link it to the button first. I recommend doing that like this:
    ...
    button = tkinter. ...
    label = tkinter. ...
    button.target_label = label
    ...
Now in the event handler, once you have the button, you can get the label from it by accessing that same field:
    ...
    button = event.widget
    label = button.target_label
    ...
Use text for this part that no one else in the class will use. Please remember not to use the mainloop() function in this one!

Part 18, 0 points:

You can also access the text stored in a button by calling the cget operation. Using that function looks like this:
    x = button.cget('text')
Write a function, print_from_label, that creates a window with a button that gets the text from a label and prints it out in the terminal.

Part 19, 3 points:

Let's put it all together. Write a new function, three_buttons, that creates a window with a label and three buttons. The buttons should have different text on them. Every time you click a button, it should add the string on it to the label. This means that as you continue to click buttons, the label text will get longer and longer. You should pick strings that no one else will pick. Please remember not to use the mainloop() function here!

Submitting your Project:

Some of your functions should create windows and others will create turtles that do things, but your file shouldn't do that on it's own without calling any of those functions! Before you submit, try running your file and make sure that nothing like that pops up! If you're not sure how to stop those from popping up, please let me know so I can help you out. (Make sure you name your file correctly, just like in the past projects.) If things pop up, I may not be able to grade that version of your code and you'll have to wait for the next iteration. If you make sure nothing pops up, Kyle will be happy like Fluttershy:

Happy Fluttershy