ICS 32A Fall 2023
Exercise Set 1

Due date and time: Friday, October 13, 11:59pm


Getting started

First of all, be sure that you've read the Reinforcement Exercises page, which explains everything you'll need to know, generally, about how the reinforcement exercises will work this quarter. Make sure you read that page before you continue with this one.


Problem 1 (1 point)

First, download the following Python script. Save it somewhere that you can find it again easily.

Now, run that script and notice that it doesn't run to completion; instead, it terminates because of an error.

As precisely as possible — by which I mean "stay on message," rather than "write as much as you possibly can in hopes that some part might be relevant" — explain why the script doesn't run successfully to completion. What would you have to change in the script so that it would run successfully to completion and achieve its stated goal (i.e., so it does what it says in its comments)? Prefer fewer changes over more changes, if you can think of more than one way to fix what ails this script.

What to submit

Submit one PDF file named problem1.pdf, which contains your explanation of what's broken and how you would fix it.

Note that we're not asking you to submit a modified copy of the script. What we want here is prose explaining your understanding of why it's broken and, briefly, how you would fix it.


Problem 2 (2 points)

Write a Python function partial_print, which takes one parameter, a string, and prints the first, third, fifth (and so on) characters of the strings, with each character both preceded and followed by the ^ symbol, and with a newline appearing after the last ^ symbol. The function returns no value; its goal is to print its output, but not to return it.

Here is an example of how the function should behave when it's finished.


>>> partial_print('0123456789')
    ^0^^2^^4^^6^^8^ 
>>> partial_print('BooIsHappyToday!')
    ^B^^o^^s^^a^^p^^T^^d^^y^

What to submit

Submit one Python script named problem2.py, which contains your partial_print function. A docstring is not required, since we've all agreed already on what problem we're solving here.

The function and any additional functions you've written that it calls (if any) are all you need to write in the module; we don't need you to write automated tests and we haven't discussed in class how to do that, though you can, as long as importing the module can be done without generating any output or other effects, so that we can run automated tests of our own. (One way to meet that last requirement is for your automated tests to appear in a separate function, so they only run if you call it explicitly. If you're not sure how to meet this requirement, the safest thing is not to submit any automated tests; if we can't run our automated tests, you may not receive full credit here.)


Problem 3 (2 points)

We saw in class that Python offers three seemingly similar, if not entirely interchangeable, data structures: a range, a tuple and a list. All three represent a sequence of values, but they offer different (though sometimes overlapping) abilities and are each meant to solve problems of a decidedly different shape. The most important thing to understand when learning the set of tools provided by a programming language is what kinds of problems each of those tools is best used for, so let's consider ranges, tuples, and lists in those terms.

Suppose that you were solving each of the following programming problems.

  1. In a function, users will enter the names of all of the students enrolled in a course, continuing to read them until the user enters an empty one. You'd like to return all of the names from the function.
  2. Given an integer n, generate the first n integers in the Fibonacci sequence. The first integer in the sequence is 0, the second is 1, and each subsequent integer in the sequence is the sum of the two integers that precede it.
  3. Given two Cartesian points in either two-dimensional or three-dimensional space, determine the distance between them. Any two-dimensional point will be treated as though its z-coordinate is 0. What you'll need to decide is how to represent each point.

For each of them, would you use a range, a tuple, or a list? Briefly explain, in a sentence or two, why you made the choice you did. (Note that an answer without any explanation is neither correct nor an honest attempt; the important thing here, as is so often the case in real-world programming, is the "why.")

What to submit

Submit one PDF file named problem3.pdf, which contains your explanation of which data structure you'd use to solve each kind of problem and why.

Note that you're not being asked to write any code here; the goal here is to consider what tools you might use, but not to put your idea into action.


Problem 4 (2 points)

We've seen that Python is a dynamically typed language, which is a fancy way of saying "If you make a mistake in a program that has to do with objects' types, you won't know until the program runs." Variables don't have types; a function's parameters and return values don't, either. Depending on what programming language(s) you learned in the past, you may feel right at home, or you may find that to be a huge departure from what you've seen previously.

Recent versions of Python have presented a sort of middle ground called type annotations, in which we're allowed to specify our intentions around types — what type of object we expect a variable to store, a function to be passed as an argument, or a function to return as a result. Even though type annotations aren't checked (before or while the program runs), there is the upside is that we've communicated our intentions to a human reader of our program, which has enough value that we might find that it's worth using type annotations, even if they have no other practical impact besides readability.

Like many programming language features, though, there's a flip side to this argument. In no more than a few sentences, describe a disadvantage of using type annotations in a Python program.

What to submit

Submit one PDF file named problem4.pdf, which contains your description of a disadvantage of using type annotations.


Problem 5 (3 points)

Write a Python function called lines_of_code that takes a Path object as a parameter, which is expected to be the path to a Python script. It returns how many lines of Python code are contained within the script. Note that not all lines of text are considered to be "lines of code." We'll want to skip a few things, so we aren't counting lines that lack meaning; do not count lines that have these characteristics:

(Note that when I refer to "comments" here, I'm referring only to Python comments, i.e., the portions of a line that begin with a # character. Some people use string literals as comments — most notably, they use multiline string literals, because Python lacks multiline comments and a string literal "floating" in one's code turns out to be legal, though it's not a comment, because it still gets evaluated at run-time — but these aren't comments, so you would want to count them.)

The function returns an integer that indicates how many lines of code are in the Python script.

If the file cannot be opened successfully, or if the file contains something other than text, the function should raise an exception, though it's not important what kind of exception is raised — any exception will do, and it's fine if you raise different kinds of exceptions in different scenarios. However, the file is required to be closed in any case in which it had been opened.

What to submit

Submit one Python script named problem5.py, which contains your lines_of_code function. A docstring is not required, since we've all agreed already on what problem we're solving here.

The function and any additional functions you've written that it calls (if any) are all you need to write in the module; we don't need you to write automated tests and we haven't discussed in class how to do that, though you can, as long as importing the module can be done without generating any output or other effects, so that we can run automated tests of our own. (One way to meet that last requirement is for your automated tests to appear in a separate function, so they only run if you call it explicitly. If you're not sure how to meet this requirement, the safest thing is not to submit any automated tests; if we can't run our automated tests, you may not receive full credit here.)


Deliverables

In Canvas, you'll find a separate submission area for each problem. Submit your solution to each problem into the appropriate submission area. Be sure that you're submitting the correct file into the correct area (i.e., submitting your Problem 1 solution to the area for Problem 1, and so on). Under no circumstances will we offer credit for files submitted in the incorrect area.

Submit each file as-is, without putting it into a Zip file or arranging it in any other way. If we asked for a PDF, for example, all we want is a PDF; no more, no less. If you submit something other than what we asked for (e.g., a text file when we asked for a PDF, even if its filename ends in .pdf), we will not be offering you any credit on the submission. There are no exceptions to this rule.

Of course, you should also be aware that you're responsible for submitting precisely the version of your work that you want graded. We won't regrade an exercise simply because you submitted the wrong version accidentally.

Can I submit after the deadline?

Unlike some of the projects in this course, the reinforcement exercises cannot be submitted after the deadline; there is no late policy for these. Each is worth only 3% of your grade, with the lowest score dropped — see the Reinforcement Exercises page for details — so it's not a disaster if you miss one of them along the way.

You're responsible for making a submission in order to receive credit, which means you'll want to be sure that you've remembered to submit your work and verify in Canvas that it's been received. A later claim of having forgotten to submit your work or having misremembered the due date will not be grounds for a resubmission under any circumstances.

What do I do if Canvas adjusts my filename?

Canvas will sometimes modify your filenames when you submit them (e.g., by adding a numbering scheme like -1 or a long sequence of hexadecimal digits to its name). In general, this is fine; as long as the file you submitted has the correct name prior to submission, we'll be able to obtain it with that same name, even if Canvas adjusts it.