This exercise has two deadlines. The first deadline is 3/8 for the only_evens
function and its tests. The second deadline is 3/19 for all three functions and their tests.
Art students intentionally reproduce great works of art to develop their own skills and techniques. The purpose isn’t to become an imitator, but to deepen an understanding of important work and styles developed before you.
Reverse engineering algorithms and abstractions in computer science is of the same spirit! In this exercise you will implement algorithms to practice computational thinking. You will gain familiarity with the names and behaviors of commonly useful functions.
Since the work you do is reproducing tried and true abstractions of the past, in the future you can and should use your language’s preferred functions, methods, and idioms instead.
In this exercise, you will also gain practice writing unit tests for your functions which gives you confidence in their correctness and simplifies checking your work and progress. Your function implementations may only make use of the built-in len
function, and a list
object’s methods append
and pop
.
Specifically off-limits in this exercise are the following capabilities. Making use of any of the following will result in no credit for the function you use them in:
- Cannot use other built-in function besides
len
- specifically notmax
,min
,slice
- Cannot use slice notation in conjunction with the subscription operator (we have not taught this in class)
- Cannot use the
in
operator of Python with lists (should only usewhile
loops as a looping construct) - Cannot use the
list
class’s+
or==
operators on an entire list (you can still use+
withint
andstr
types, though!) nor any other built-inlist
methods beyondappend
andpop
(so, don’t usecopy
in this exercise!)- Note: You can use + and == for individual items and values, just not entire
list
objects.
- Note: You can use + and == for individual items and values, just not entire
Assignment Outline
only_evens
– 25 Points Autograded- Unit Tests – 5 Points Autograded
concat
– 25 Points Autograded- Unit Tests – 5 Points Autograded
sub
– 25 Points Autograded- Unit Tests – 5 Points Autograded
- Style, Linting, Typing – 10 Points Autograded
Note: Even if your functions are not 100% correct or finished, you can get full credit for the unit tests if you set up a function skeleton and write your tests assuming correct functionality.
0. Upgrade Trailhead to 0.1.15
Before starting work on this project you will need to upgrade Trailhead to version 0.1.15
using the following steps:
- Open your course workspace in the VSCode DevContainer
- Open the file
.devcontainer/devcontainer.json
and look for line #11 that begins with"image"
- Update the version number at the end of the string to be
0.1.15
. The line should read:"image": "krisjordan/trailhead:0.1.15",
- Save this file and then, when prompted, click the “Rebuild” button that pops up. If you are not prompted, save the file again and then open the command pallete (View -> Command Palette) and select Rebuild and Reopen in Container.
- It will take a few minutes for the upgrade to complete, but once done you should be back in Trailhead with the latest bug fixes and features in place. The newest feature is in the REPL you are now able to press the up arrow after running commands to reuse/reload a previous command run.
1. Skeleton Code and Testing Setup
Create a new directory inside of the exercises
directory named ex04
.
Inside the exercises/ex04
directory, create a file named utils.py
. Add a docstring and establish an __author__
variable to be assigned a string with the digits of your PID. This is where you will implement your function skeletons and implementations below.
Unit Tests
Also inside the exercises/ex04
directory, create a file named utils_test.py
. Add a docstring and establish an __author__
in this file as well.
For each function from below (only_evens
, sub
, concat
), you will need to define at least 3x unit test functions. Remember that a unit test function starts with test_
in its name and must have a unique, descriptive function name.
The 3 unit tests should consist of:
- One edge case
- Two use cases
Include descriptive function names and docstrings, so that it captures what is being tested.
The command to run your tests is pytest exercises/ex04
or you can run them using the beaker tab in VSCode, as shown in class.
Once you’re ready to import and begin testing your skeleton function implementations, you can add the following import lines, one-by-one, corresponding to the functions you have defined.
from exercises.ex04.utils import only_evens
from exercises.ex04.utils import sub
from exercises.ex04.utils import concat
Once you have completed all functions, you can reduce the three import lines down into a single one for less redundancy in your testing code:
from exercises.ex04.utils import only_evens, sub, concat
If your screen is large enough, you are encouraged to open your utils.py
and utils_test.py
files side-by-side in VSCode by dragging the tab of one to the right side of VSCode so that it changes to a split pane view. Closing your file explorer can help give you additional horizontal space.
1. only_evens
– 30 Points
This is the first function you will write in utils.py
. The other two functions will also be defined in this file.
Given a list
of ints
, only_evens
should return a new list
containing only the elements of the input list that were even. The only_evens
function must not modify the list it is given a reference to as a parameter. Example usage:
>>> only_evens([1, 2, 3])
[2]
>>> only_evens([1, 5, 3])
[]
>>> only_evens([4, 4, 4])
[4, 4, 4]
Continue by defining a skeleton function with the following signature:
- Name:
only_evens
- Arguments: A list of integers.
- Returns: A list of integers, containing only the even elements of the input parameter.
Reminder: You must write at least 3 meaningful unit tests to “prove” or verify your only_evens
function is implemented following these specifications, as described in Part 1.
2. concat
– 30 Points
In this exercise you will write a function named concat
. Given two Lists
of ints
, concat
should generate a new List which contains all of the elements of the first list followed by all of the elements of the second list. Your concat
function may not mutate (“modify”) either of its list parameters.
Define your function with the following signature.
- Name:
concat
- Parameters: Two lists of ints.
- Returns: A
list
containing all elements of the first list, followed by all elements of the second list.
concat
must NOT mutate (modify) either of the arguments passed to it.
2. sub
– 30 Points
In this exercise you will write a function named sub
. Given a list
of ints
, a start index, and an end index (not inclusive), sub
should generate a List which is a subset of the given list, between the specified start index and the end index - 1. This function should not mutate its input list.
Example usage:
>>> a_list = [10, 20, 30, 40]
>>> sub(a_list, 1, 3)
[20, 30]
Next, define a skeleton function with the following signature in ex04/utils.py
:
- Name:
sub
- Parameters: A list and two ints, where the first int serves as a start index and the second int serves as an end index (not inclusive).
- Returns: A List which is a subset of the given list, between the specified start index and the end index - 1.
If the start index is negative, start from the beginning of the list. If the end index is greater than the length of the list, end with the end of the list.
If the length of the list is 0, start is greater than the length of the list, or end is at most 0, return the empty list.
4. Make a Backup Checkpoint “Commit”
As you make progress on this exercise, making backups is encouraged.
- Open the Source Control panel (Command Palette: “Show SCM” or click the icon with three circles and lines on the activity panel).
- Notice the files listed under Changes. These are files you’ve made modifications to since your last backup.
- Move your mouse’s cursor over the word Changes and notice the + symbol that appears. Click that plus symbol to add all changes to the next backup. You will now see the files listed under “Staged Changes”.
- If you do not want to backup all changed files, you can select them individually. For this course you’re encouraged to back everything up.
- In the Message box, give a brief description of what you’ve changed and are backing up. This will help you find a specific backup (called a “commit”) if needed. In this case a message such as, “Progress on Exercise” will suffice.
- Press the Check icon to make a Commit (a version) of your work.
- Finally, press the Ellipses icon (…), look for “Pull/Push” submenu, and select “Push to…”, and in the dropdown select your backup repository.
5. Submit to Gradescope for Grading
Login to Gradescope and select the assignment named “EX04 - List Utils and Unit Tests”. You’ll see an area to upload a zip file. To produce a zip file for autograding, return back to Visual Studio Code.
If you do not see a Terminal at the bottom of your screen, open the Command Palette and search for “View: Toggle Integrated Terminal”.
Type the following command (all on a single line):
python -m tools.submission exercises/ex04
In the file explorer pane, look to find the zip file named “yy.mm.dd-hh.mm-exercises-ex04.zip”. The “yy”, “mm”, “dd”, and so on, are timestamps with the current year, month, day, hour, minute. If you right click on this file and select “Reveal in File Explorer” on Windows or “Reveal in Finder” on Mac, the zip file’s location on your computer will open. Upload this file to Gradescope to submit your work for this exercise.
Autograding will take a few moments to complete. If there are issues reported, you are encouraged to try and resolve them and resubmit. If for any reason you aren’t receiving full credit and aren’t sure what to try next, come give us a visit in office hours!