CS 111
Spring 2018

Old version

This is the CS 111 site as it appeared on May 10, 2018.

Problem Set 1

Preliminaries

In your work on this assignment, make sure to abide by the collaboration policies of the course.

If you have questions while working on this assignment, please come to office hours, post them on Piazza, or email cs111-staff@cs.bu.edu.

Make sure to submit your work on Apollo, following the procedures found at the end of the assignment.


Part I

due by 11:59 p.m. on Thursday, February 1, 2018

Problem 0: Reading and response

5 points; individual-only

Using folders

We strongly encourage you to create a separate folder for each assignment, so that you can more easily keep track of your work. For example, you could create a folder called ps1 for your work on this assignment, and put all of the files for PS 1 in that folder.

In class, we’ve been exploring various types of data in Python. As you’ve probably heard, we’re currently living in the age of big data, in which massive amounts of data are being collected, analyzed, and used to guide decisions in a wide range of occupations and fields of study. This week’s reading, which comes from Wired, discusses the ways in which data is affecting science.

The reading is available here.

After you have read the article, write a response that addresses only one of the following prompts. (Important: Put your response in a file named ps1pr0.txt. Don’t forget that the file that you submit must be a plain-text file.)

  1. The author refers to one’s “MySpace” page. This is a clear, if superficial, way in which this article (which was written in 2008) shows its age. What is a deeper way in which the ideas of this article betray thinking that has moved on since 2008? Contrast one of its ideas with more recent thinking, which can be your own, others’, or both.

  2. The article states that, whether in science or business, we “don’t have to settle for models at all.” Do you agree or disagree with this statement? How? And why? Certainly feel free to articulate a more nuanced or hybrid view, if you’d like.

You only need to write a short paragraph (4-6 sentences). The important thing is that your response uses and extends (or alters or refutes) ideas from the article.

Python Fundamentals

Problem 1: Indexing and slicing puzzles

18 points; individual-only

This problem will give you practice with indexing and slicing. Begin by downloading this file: ps1pr1.py. Open it in IDLE, following the procedure outlined in Task 2 of Lab 1.

Highly recommended

  • Use the screen layout mentioned in Lab 1, which we’ve reproduced below.
  • Modify IDLE’s settings following the instructions from Task 6 of Lab 0. Doing so will allow you to use the Up Arrow and Down Arrow keys to scroll through the expressions that you’ve already entered in the Shell, and will thus save you a lot of unnecessary typing!

IDLE

List puzzles
The first half of the problem focuses on lists. In particular, you will be constructing new lists from the following:

pi = [3, 1, 4, 1, 5, 9]
e = [2, 7, 1]

We’ve given you these lines in ps1pr1.py. In addition, we’ve provided the answer to the first puzzle (puzzle 0). You should add in the answers for the remaining puzzles, following the format that we’ve given you for puzzle 0.

The expressions that you construct must only use pi and e and the following list operations:

We encourage you to try using as few operations as possible, to keep your answers elegant and efficient. However, you will get full credit for any expression that follows the rules above and produces the correct result.

Before getting started, you should run ps1pr1.py in IDLE using F5. This will make the lists pi and e available to you in the Python Shell.

Here are the puzzles:

  1. Use pi and/or e to create the list [2, 5, 9], and assign it to the variable answer0. We’ve given you the code for this puzzle.

  2. Use pi and/or e to create the list [2, 7] and assign it to the variable answer1. Your answer should follow the format that we’ve given you for problem 0. In other words, it should look like this:

    # Puzzle 1:
    # Creating the list [2, 7] from pi and e
    answer1 = 
    print(answer1)
    

    where you put the appropriate expression to the right of the assignment operator (=). Please leave a blank line between puzzles to make things more readable.

  3. Use pi and/or e to create the list [5, 4, 3], and assign it to the variable answer2. Here again, make sure to follow the correct format, and to leave a blank line between puzzles.

  4. Use pi and/or e to create the list [3, 5, 7], and assign it to the variable answer3.

  5. Use pi and/or e to create the list [1, 2, 3, 4, 5], and assign it to the variable answer4. (Optional challenge: See if you can do this with just three list operations!)

String puzzles
The second half of the problem focuses on strings. In particular, you will be working with the following strings:

b = 'boston'
u = 'university'
t = 'terriers'

We’ve given you these lines in ps1pr1.py, along with the answer to the first string puzzle (puzzle 5). Run the file as needed so that the strings will be available for you to experiment with in IDLE.

The expressions that you construct for the remaining puzzles must only use the above strings and the following string operations:

Here again, you will get full credit for any expression that follows the rules above and produces the correct result, but we encourage you to try using as few operations as possible.

Here are the puzzles:

  1. Use b, u, and/or t to create the string 'bossy', and assign it to the variable answer5. We’ve given you the following code for this puzzle:

    # Puzzle 5:
    # Creating the string 'bossy'
    answer5 = b[:3] + t[-1] + u[-1]
    print(answer5)
    

    Note that our answer involves 5 operations: 2 uses of indexing, 1 slice, and 2 concatenations with +. (It’s actually possible to solve this puzzle using only 3 operations. Give it a try if you have time!)

  2. Use b, u, and/or t to create the string 'universe', and assign it to the variable answer6. (Our best answer uses 3 ops.) Here again, make sure to follow the correct format, and to leave a blank line between puzzles.

  3. Use b, u, and/or t to create the string 'roster', and assign it to the variable answer7. (Our best: 5 ops.)

  4. Use b, u, and/or t to create the string 'boisterous', and assign it to the variable answer8. (Our best: 8 ops.)

  5. Use b, u, and/or t to create the string 'yesyesyes', and assign it to the variable answer9. (Our best: 4 ops.)

  6. Use b, u, and/or t to create the string 'trist', and assign it to the variable answer10. (Our best: 3 ops.)

After finishing all of the puzzles, make sure to run your ps1pr1.py file to check that the correct outputs are printed.

Problem 2: Understanding statements, program flow and variable scope

20 points; individual-only

Open up a text editor (e.g., Notepad or TextEdit) and create a plain-text file named ps1pr2.txt. Put all of your work for this problem in that file.

  1. Consider the following Python program:

    x = 11
    y = 5
    x = x + 6
    z = y + x
    x = x // 7
    y = z % 3
    

    Copy the table shown below into your text file for this problem, and fill in the missing values to illustrate how the values of the variables change over the course of the program. We’ve given you the values of the variables after the first two lines of code. You should complete the remaining rows of the table.

    line of code   | x  | y  | z  |
    --------------------------------
    x = 11         | 11 |    |    |
    y = 5          | 11 | 5  |    |
    x = x + 6      |    |    |    |
    z = y + x      |    |    |    |
    x = x // 7     |    |    |    |
    y = z % 3      |    |    |    |
    
  2. Assume that you have two variables a and b that have each been assigned an integer value. Construct the assignment statements and expressions specified below.

    Important: Assignment statements should assign a value to a variable using either the assignment operator (=) or one of the shortcut operators (e.g., +=). Expressions should not assign anything.

    Sample assignment statements include:

    • a = b * 2
    • b = b + 1
    • a = a + 2

    Sample expressions include:

    • a < b
    • a * b

    Here are your tasks:

    1. Write an assignment statement that increases the value of a by 5.

    2. Write an expression that raises b to the ath power.

    3. Write an assignment statement that gives b a value that is one-third of the value of a

    4. Write an expression that tests if a is equal to b.

    5. Write an expression that tests if a is a multiple of 3.

      • Hint: recall how we checked to see if a number is even.
      • For this expression and the next one, you should not include an if statement. Simply provide an appropriate boolean expression.
    6. Write an expression that tests if b is outside the set of integers from 6 to 16 inclusive.

  3. Consider the following Python program:

    def foo(a, b):
        a = a + 2
        b = a - b
        print('foo', a, b)
        return a
    
    a = 7
    b = 4
    print(a, b)
    b = foo(a, b)
    print(a, b)
    foo(b, a)
    print(a, b)
    

    Copy the tables shown below into your text file for this problem, and complete them to illustrate the execution of the program.

    global variables (ones that belong to the global scope)
      a  |  b  
    -----------
      7  |  4     
         |
    
    local variables (ones that belong to foo)
      a  |  b  
    -----------
         |       
         |
    
    output (the lines printed by the program)
    ------
    7 4
    

    Note that you must include three tables: one for the global variables (the ones that belong to the global scope), one for the local variables (the ones that belong to the function foo), and one for the output of the program. Don’t forget that the global variables and local variables are two separate sets of variables, even though they happen to have the same names.

    We have started the first and third tables for you. You should:

    • complete the first and second tables so that they illustrate how the values of the variables change over time
    • complete the third table so that it shows the output of the program (i.e., the values that are printed).

    You should add rows to the tables as needed.

Problem 3: Functions with numeric inputs

12 points; pair-optional

This is the only problem of Part I of the assignment that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.

In this problem you will write a collection of simple functions that operate on numeric inputs.

Begin by downloading this file: ps1pr3.py. Open it in IDLE, following the procedure outlined in Task 2 of Lab 1. Here again, we encourage you to use the screen layout mentioned in that lab.

Important guidelines:

  • Your functions must have the exact names that we have specified, or we won’t be able to test them. Note in particular that the case of the letters matters (all of them should be lowercase), and that you should use an underscore character (_) wherever we have specified one (e.g., in convert_from_inches).

  • If a function takes more than one input, you must keep the inputs in the order that we have specified.

  • Each of your functions should include a docstring that describes what your function does and what its inputs are. See our example function for a model.

  • Make sure that your functions return the specified value, rather than printing it. None of these functions should use a print statement.

  • You should not use any Python features that we have not discussed in lecture or read about in the textbook.

  • Your functions do not need to handle bad inputs – inputs with a type or value that doesn’t correspond to the description of the inputs provided in the problem.

  • Test each function after you write it. Here are two ways to do so:

    • Run your ps1pr3.py file after you finish a given function. Doing so will bring you to the Shell, where you can call the function using different inputs and check to see that you obtain the correct outputs.
    • Add test calls to the test function that we have provided at the bottom of your ps1pr3.py file. We have given you an example of one such test call in the starter file. After running your ps1pr3.py file, you can call the test function (by entering test()) to see the results of all of the test calls.
    • To facilitate grading, please put any test code inside a function like the test function that we have given you. Do not add any lines of code that belong to the global scope of the program (i.e., lines that are outside of any function).

Here are the descriptions of the functions:

  1. (example) Write a function opposite(x) that takes a number x as its input and returns the opposite of its input. We have given you this example function in the starter file.

  2. Write a function cube(x) that takes a number x as its input and returns the cube of its input (i.e., x raised to the power of 3). For example:

    >>> cube(2)
    8
    >>> print(cube(-5))
    -125
    

    Warning

    Make sure that your function returns the correct value rather than printing it. If your function is printing the return value, you will see the word None as part of the output for the second test above. If you are seeing None in your output, you must fix your function so that it uses a return statement rather than a print statement. This same warning applies to all of the functions that you will write for this assignment.

    Note: You should leave one or two blank lines between functions to make things more readable, and make sure to include a docstring like the one in our example function.

    Warning

    Make sure that you use the correct amount of indentation. In particular, your docstrings should be indented by 4 spaces as shown in our code for opposite, so that they line up with the code inside the function.

  3. Write a function compare(num1, num2) that takes two numeric inputs num1 and num2 and returns a value that is based on how the numbers compare. More specifically, it should:

    • return 1 if num1 is greater than num2

    • return -1 if num1 is less than num2

    • return 0 if num1 is equal to num2

    Here are some examples of how it should work:

    >>> compare(5, 2)
    1
    >>> compare(2, 5)
    -1
    >>> print(compare(2, 2))
    0
    
  4. Write a function convert_from_inches(inches) that takes a nonnegative integer inches that represents a length in inches and returns a list of three integers in which that length has been broken up into yards, feet, and inches. For example:

    >>> convert_from_inches(67)
    [1, 2, 7]                       # 67 inches = 1 yard, 2 feet, 7 inches
    >>> print(convert_from_inches(75))
    [2, 0, 3]                       # 75 inches = 2 yards, 0 feet, 3 inches
    

    Here’s one possible template that you could use:

    def convert_from_inches(inches):
        """ put your docstring here
        """
        yards =                     # number of yards
        inches =                    # the leftover number of inches
        feet =                      # number of feet
        inches =                    # final number of inches
        return [yards, feet, inches]
    

    Hints:

    • 1 foot is 12 inches, and 1 yard is 3 feet or 36 inches.
    • The integer division (//) and modulus (%) operators will come in handy for this problem.

Don’t forget to test your functions using the approaches mentioned at the start of the problem.

You may also find it helpful to use the Python Tutor Visualizer to trace through the execution of your functions – either to verify that they’re working as expected, or to determine why they’re not working! Paste your function definition into the Visualizer’s code box, and follow the definition with code that calls the function. Then click the Visualize Execution button below the code box to begin the visualization. For example, to test the circle_area function that we discussed in lecture, you could paste the following into the Visualizer:

def circle_area(diam):
    radius = diam / 2
    area = 3.14159 * (radius**2)
    return area

test = circle_area(10)
print('test is', test)

Part II

due by 11:59 p.m. on Sunday, February 4, 2018

Problem 4: Understanding program flow and variable scope

10 points; individual-only

Open up a text editor (e.g., Notepad or TextEdit) and create a plain-text file named ps1pr4.txt. Put all of your work for this problem in that file.

  1. Consider the following Python program:

    def hello(a, b, c, d):
        if b < d:
            b = a + 2
        elif a < d:
            a = b + 2
        print(a, b)
    
        c = goodbye(d, b)
        c = c * d
    
        adios(c, d, b, a)
        print('hello', a, b, c, d)
        return a
    
    def goodbye(a, c):
        if a < c:
            c = c - a
        if b > c:
            a = b // c
        else:
            a = c // b
        return a
    
    def adios(a, b, c, d):
        print(a, b, c, d)
    
    a = 1
    b = 4
    c = 2
    d = 7
    
    print(a, b, c, d)
    d = hello(a, b, c, d)
    print(a, b, c, d)
    

    Copy the tables shown below into your text file for this problem, and complete them to illustrate the execution of the program.

    global variables (ones that belong to the global scope)
      a  |  b  |  c  |  d
    -----------------------
      1  |  4  |  2  |  7
         |     |     |
    
    hello's local variables
      a  |  b  |  c  |  d
    -----------------------
         |     |     |
    
    goodbye's local variables
      a  |  c  
    ------------
         |
    
    adios's local variables
      a  |  b  |  c  |  d
    -----------------------
         |     |     |
    
    output (the lines printed by the program)
    -------
    1 4 2 7
    

    Note that you must include five tables: one for the global variables (the ones that belong to the global scope), one for the local variables that belong to the function hello, one for the local variables that belong to the function goodbye, one for the local variables that belong to the function adios, and one for the output of the program. Don’t forget to follow the rules for variable scope.

    We have started the first and last tables for you. You should:

    • complete the first four tables so that they illustrate how the values of the variables change over time
    • complete the last table so that it shows the output of the program (i.e., the values that are printed).

    You should add rows to the tables as needed.

Problem 5: Functions on strings and lists, part I

15 points; individual-only

This problem involves more practice in writing functions.

In IDLE, use the File -> New Window menu option to open a new editor window for your program, and save it using the the name ps1pr5.py. Make sure to specify the .py extension.

Include comments at the top of the file that are similar to the ones that we gave you at the top of ps1pr3.py.

Follow the same guidelines that we gave you for problem 3.

  1. Write a function front3(s) that takes an input string s and follows the specifications given in the problem of that name on the CodingBat website. Here is a screenshot of the problem:

    CodingBat

    Write this function in your ps1pr5.py file. In addition, we encourage you to try entering your function into the CodingBat website, because it will test your function for you. (Note: You may need to remove your docstring when testing the function on CodingBat.)

    In general, CodingBat is a great way to reinforce what you have learned. If you would like some additional practice on the material that we’ve covered thus far, you can find some (entirely optional!) additional problems here.

  2. Write a function shorter_len(l1, l2) that takes as inputs two lists l1 and l2, and that returns the length of the shorter (of the two) lists. For example:

    >>> shorter_len(['computers', 'compute'],['humans', 'have', 'intelligence'])
    2
    >>> shorter_len([5, 'abc', '123', ['cs', 111]], ['I', 'Love', 'cs'])
    3
    >>> print(shorter_len(['begin', 'end'], [['begin', 'middle','end']]))
    1
    

    You should start by understanding the answers to each example!!

    Your function must use conditional execution, and it should not use Python’s built-in min function. You may use other built-in functions as needed.

  3. Write a function ends_with(word, suffix) that takes as inputs two string values word and suffix, and that returns True if the string word ends with the string suffix, and False otherwise. For example:

    >>> ends_with('computer', 'ter')
    True
    >>> ends_with('computer', 'tar')
    False
    >>> ends_with('begin', 'in')
    True
    >>> print(ends_with('begin', 'on'))
    False
    

    Warning

    Your function should return a boolean value – either True or False, without any quotes around them.

    Remember that you should not use Python features that we have not discussed in lecture. In particular, you should not use the built-in Python endswith method!

    Hint: Begin by computing the length of suffix and storing it in an appropriately named variable. Then use that variable as part of a test to determine if word ends with suffix.

Don’t forget to test your functions using the approaches mentioned at the start of Problem 3. You may also find it helpful to use the Python Tutor visualizer to trace through the execution of your functions, as described at the end of Problem 3.

Problem 6: Functions on strings and lists, part II

20 points; individual-only

This problem involves more practice in writing functions and manipulating strins.

In IDLE, use the File -> New Window menu option to open a new editor window for your program, and save it using the the name ps1pr6.py. Make sure to specify the .py extension.

Follow the same guidelines that we gave you for problem 3.

  1. Write a function replace_prefix(word, prefix) that takes as inputs a string word and a string prefix, and that returns a string in which the character in prefix replace the characters of word (up to the length of prefix). For example:

    >>> replace_prefix('undo','re')
    'redo'
    >>> replace_prefix('this!ismyword','cs111')
    'cs111ismyword'
    

    Note that the number of characters replaced in the word depends on the length of prefix.

    Special case: If prefix (the second input) is larger than the length of word (the first input), then the function should simply return prefix:

    Warning

    Remember that you should not use Python features that we have not discussed in lecture. In particular, you should not use the built-in Python replace method!

  2. Write a function swap_halves(s) that takes a string input s and returns a string whose first half is s‘s second half and whose second half is s‘s first half. If len(s) (the length of s) is odd, the first half of the input string should have one fewer character than the second half, and thus the second half of the output string will be one character shorter in such cases. For example:

    >>> swap_halves('homework')
    'workhome'
    >>> print(swap_halves('carpets'))
    petscar
    

    Hint: We strongly recommend computing len(s)//2 (using the integer-division operator //) and storing the result in an appropriately named variable. You will need to use that value twice in your function, and using the variable in both places with save you from recomputing it.

  3. Write a function statistics(list_of_int) that takes as input a list of (exactly) three integers and returns a list of the following statistics: sum, average value, smallest value, largest value (in that order). For example:

    >>> statistics([2, 8, 7])
    [17, 5.666666666666667, 2, 8]
    >>> statistics([11, 2, 11])
    [24, 8.0, 2, 11]
    

    Hint: To compute the largest and smallest value, you will have to use the logical connective and along with conditional execution to compute the correct answer. Also remember that the computed value for average should be a floating point value.

    Warning

    Remember that you should not use Python features that we have not discussed in lecture. In particular, you should not use the built-in Python min or max!

Don’t forget to test your functions using the approaches mentioned at the start of Problem 3. You may also find it helpful to use the Python Tutor Visualizer to trace through the execution of your functions, as described at the end of Problem 3.


Submitting Your Work

You should use Apollo to submit the following files:

Warnings

  • Make sure to use these exact file names, or Apollo will not accept your files. If Apollo reports that a file does not have the correct name, you should rename the file using the name listed in the assignment or on the Apollo upload page.

  • Before submitting your files, make sure that your BU username is visible at the top of the Apollo page. If you don’t see your username, click the Log out button and login again.

  • If you make any last-minute changes to one of your Python files (e.g., adding additional comments), you should run the file in IDLE after you make the changes to ensure that it still runs correctly. Even seemingly minor changes can cause your code to become unrunnable.

  • If you submit an unrunnable file, Apollo will accept your file, but it will print a warning message. If time permits, you are strongly encouraged to fix your file and resubmit. Otherwise, your code will fail most if not all of our tests.

  • If you encounter problems with Apollo, click the Log Out button, close your browser and try again. If possible, you may also want to wait an hour or two before retrying. If you are unable to submit and it is close to the deadline, email your homework before the deadline to cs111-staff@cs.bu.edu

Here are the steps:

  1. Login to Apollo, using the link in the left-hand navigation bar. You will need to use your Kerberos user name and password.
  2. Check to see that your BU username is at the top of the Apollo page. If it isn’t, click the Log out button and login again.
  3. Find the appropriate problem set section on the main page and click Upload files.
  4. For each file that you want to submit, find the matching upload section for the file. Make sure that you use the right section for each file. You may upload any number of files at a time.
  5. Click the Upload button at the bottom of the page.
  6. Review the upload results. If Apollo reports any issues, return to the upload page by clicking the link at the top of the results page, and try the upload again, per Apollo’s advice.
  7. Once all of your files have been successfully uploaded, return to the upload page by clicking the link at the top of the results page. The upload page will show you when you uploaded each file, and it will give you a way to view or download the uploaded file. Click on the link for each file so that you can ensure that you submitted the correct file.

Warning

Apollo will automatically close submissions for a given file when its final deadline has passed. We will not accept any file after Apollo has disabled its upload form, so please check your submission carefully following the instructions in Step 7 above.