Class assignments will be aggregated on this page.
This is the multi-page printable view of this section. Click here to print.
Assignments
- 1: Assignment 1 - Problem Statements
- 2: Assignment 2 - Unit testing
- 3: Assignment 3 - Information Literacy
- 4: Assignment 4 - AI is a Tool, not a Solution
- 5: Assignment 5 - Simple Git
- 6: Assignment 6 - GitHub Flow
- 7: Assignment 7 - Meteoric Design, Implementation, and Test
1 - Assignment 1 - Problem Statements
“Programming all too often begins without a clear understanding of the problem.”
– J.M. Yohe1
Class video on problem statements
A good problem statement has the following structure in clearly-labeled sections2:
Concise and precise statement of the problem you are trying to solve.
- If appropriate, include relevant calculations or computations provided by your customer/boss/instructor.
- Do not write the precise algorithm you will implement.
Clearly specified input format. What does the input data look like? For example:
- three integer values separated by spaces on a line.
- each bank record consists of the id number (integer), a name (string), and current balance (a float). These values are read from a file. Each line corresponds to a single record, and the values are separated by commas.
- the user will be prompted to enter their first name, last name, and date of birth in the console as strings.
Clearly specified output format.
- Output could be printed to the screen, text written to a file, or the values returned from a function.
- As with input, describe what does this data look like?
Define exceptional conditions, e.g., things you should check for (like invalid values) and what you should do if they occur. For example:
- The user enters a float when an integer is expected. What will you do?
- The user provides a filename to read that doesn’t exist. What will you do?
Sample inputs. This needs to be as exact and precise as possible.
- Provide sample inputs for “normal”, expected functioning of the program.
- Provide sample inputs that would cause each exceptional condition.
Sample outputs. Exact and precise as possible. You must have a sample output for each sample input from #5.
Here are two examples:
- Problem statement for simple bank record balance reader
- Problem statement for a Caesar cipher encryptor
Part A - write a problem statement
This will be completed in class.
With a partner (required): Write a problem statement using the best practices described in class. Here is the high-level problem:
Write a program where the user enters three side lengths and the program says if they can form a triangle or not. This is the Triangle Inequality Theorem.
Suppose we label the numbers
a,b, andc. They can form a triangle if:a + b ≥ c, andb + c ≥ a, anda + c ≥ b.
There are a lot of missing details, and you have some freedom in your implementation. But you must solve this central problem.
Use this plain text template to write your problem statement. You must save it as a plain .txt file, not Word or anything else.
Grading
I expect that each spec.txt will be different, and that is okay. I am looking for the completion of the problem statement sections that address the functionality required.
Rubric
- (6 pts) All elements of the template are completed. Sample input values and sample output values must include normal and exceptional behaviors.
- (1 pts) At least two exceptional conditions are specified.
- (3 pts) Correct spelling and grammar.
Submission due by Wednesday, September 10
Each partner submits their team’s spec.txt to the Canvas assignment 1.A page.
Part B - Implementation
Individually create triangle.py and implement the problem you specified in spec.txt.
The goal is to warm-up your Python skills, and to see how the implementations of two people working from the same spec will be different.
You may not share code under any circumstances. Getting answers to simple Python questions from your peers is fine. Review the Syllabus section on Collaboration and Cheating for what is allowed and not allowed. If in doubt, ask me – I promise I won’t be mad if you ask.
Grading
You are graded on the correctness of your code, not the correctness of the spec.txt. If you discover an error in your spec.txt, you may communicate it with your partner.
Rubric
- (10 pts): Functionally correct implementation that (a) accepts user input according to the format in your spec, and (b) produces correct output as to whether the input can form a triangle or not for several valid input values.
- (5 pts): The program detects and handles at least two exceptional conditions you specified in
spec.txt. “Handling” means it does not crash with an exception, but terminates or continues gracefully.
You will receive 0 points if your program does not run due to syntax errors or does not complete under “normal” conditions.
Submission due by Sunday, September 14
Submit your triangle.py file to the Canvas assignment 1.B page.
2 - Assignment 2 - Unit testing
Objective
The goal of this assignment is to gain more practice with the tools we have used so far, including implementing a unit test with pytest.
Setup
- Create a new project directory named
assn2/or something similar. - Download
grades.pyto theassn2/folder
Instructions
The assignment is to be completed alone. Refer to the Syllabus for policies on what is allowed and what is not.
Implementation
- Put your name at the top.
- You may not change the
main()function in any way. - You may add to the
__main__block to help test if you want. - Complete the functions
calculate_average()anddetermine_grade()according to their docstring descriptions:- The docstring tells you what the function must do, the parameters passed to it, the type that must be returned, and any exceptions you need to raise.
- You may not add any parameters, change the return type, or add to or alter the exceptions required.
- You must not call
print()orinput()from these functions.
Testing
- Create a test file for
grades.py. - Put your name at the top of your test file in a comment.
- Write one or more test cases in your test file for
calculate_average().- The test case must invoke
calculate_average()by providing a list, e.g.,calculate_average([1,2,6]). Useassertstatements to ensure the computed value is correct. You should have multiple asserts to check the calculation. - You must write test cases that check the exceptional conditions that raise value errors. Refer to the lab on testing for exceptions.
- The test case must invoke
- Write one or more test cases in your test file for
determine_grade(). This function does not knowingly raise exceptions, so you do not need to test for them. Test only for expected output given an input. - Run your test file using pytest.
Rubric
- (15 pts): Your implementation of
calculate_average()passes my test cases, which exercises all the details of the function’s docstring. - (10 pts): Your implementation of
determine_grade()passes my test cases, which exercises all the details of the function’s docstring. - (15 pts): Create a control flow graph (CFG) for each of your implementations of
calculate_average()anddetermine_grade()following the rules from class.- You may use an online flow chart tool such as draw.io, Canva, or Lucidchart.
- You may draw your CFG on paper and take a picture. Ensure it is legible.
- In both cases, export your CFG image to a PDF to submit to Canvas.
- (25 pts): Your test file can be run using
pytest, has multiple test cases, and thoroughly tests the parameters, returns, computations, and exceptions raised of the functions as specified by their docstrings. - Your assignment will receive a score of 0 pts for any of the following:
print()orinput()statements incalculate_average()ordetermine_grade()- Changing
main()in any way - Changing the method signature of
calculate_average()ordetermine_grade() - Your code or tests fail due to syntax error.
Submission due Sep 23
Submit your grades.py, your test file, and your CFG PDF file to the Canvas assignment page.
3 - Assignment 3 - Information Literacy
Accompanying video
Objectives
- Write effective Internet search queries and use official documentation to research answers.
- Examine and compare information from various sources to evaluate its accuracy, authority, currency, and relevance.
- Properly cite and apply the researched information to help solve software engineering problems.
Overview
Software engineers constantly use the Internet to learn how to achieve functionality and to help debug errors.
You will find plenty of wrong or misleading answers on the Internet. Who has time for that? You need to be able to discern between good sources from time wasters.
Instructions
Download and complete assignment_3.docx. Complete it with a partner in class and submit to Canvas.
Code for Task 1
Run the following Python code. You will get an error and stack trace:
| |
Submission due Friday Sep 26 @ 11:59pm via Canvas
Upload your completed assignment_3.docx to the Canvas assignment page.
4 - Assignment 4 - AI is a Tool, not a Solution
Objectives
To demonstrate why your software engineering and programming knowledge is indispensible in the world of AI code assistants.
Instructions
This assignment is to be completed individually.
Be prepared to discuss your findings in class.
- Download
assn4-ai-eval.zipand unzip it. This should create a directory namedassn4-ai-eval/with several files in it. Place that directory in yourseng-201/folder. - Open the
assn4-ai-eval/directory in PyCharm. Make sure all the files are in the root of the project space (left-hand side) when you open it, not in a subdirectory. - Download
assignment_4.docxand open it in a word processor. - Follow the instructions in
assignment_4.docx.
Submission due Monday, Sep 29 @ 11:59pm via Canvas
Upload these three files only to the Canvas assignment page:
- Your completed
assignment_4.docxas adocxorpdffile only. - The completed
birds_gpt.py - The completed
birds_gpt_eff.py
Do not upload anything else.
Come prepared to discuss your findings in class!
5 - Assignment 5 - Simple Git
Objectives
- Practice the basic Git commands:
init,addandcommit.
Setup
- You must have completed the Lab: Git and GitHub setup.
- Create a new directory named
git-calc/. - Download
calc.pyand put it in thegit-calc/directory. - Create a new file named only
.gitignorein thegit-calc/directory. Note the.at the beginning! Paste in the following text:# This will ignore files we don't need but may show up. venv/ .venv/ __pycache__/ .idea/ .DS_Store .vscode/ - Open the
git-calc/directory in PyCharm.
Instructions
Run calc.py and to try it out with the options. You are going to add to the functionality.
Follow the style in the code. Do not worry about unit testing or error handling for this assignment.
- Run the
git initcommand to initialize a new local repository. - Add a “power” option to raise one number to the power of another. Add it to the user menu. Add and commit your changes using git with a meaningful commit message.
- Add a “logarithm” option that computes the
log(x, base). Import the standardmathlibrary and use thelog()function. Add it to the user menu. Add and commit your changes using git with a meaningful commit message. - Add one more mathematical operation of your choice. Again, add and commit your changes using git with a meaningful commit message.
- All pre-existing options must continue to work, including “Quit”.
Rubric
Partial credit is not awarded for these items: all or nothing.
- (5 pts) Version history (
git log) of submission shows a minimum of three new commits. - (5 pts) Commit messages are meaningful, concise, and accurate messages.
- (5 pts) All options (original features + your additions) correctly work in the final commit.
Submission due October 15
Zip/compress your git-calc/ folder and upload the zip to the Canvas assignment page.
6 - Assignment 6 - GitHub Flow
Objectives
- More practice with Git branching and merging
- Practice of a proper Git workflow to handle merge conflicts properly in a team environment
Interactive class
The Setup, Part A, and Part B of this assignment were worked on in an interactive class.
Setup
- You must have completed Lab: GitHub CLI setup prior to starting this assignment.
- Run the command
git config pull.rebase merge - Click this link: https://classroom.github.com/a/SIP7ZMX7
- Teams:
- The first teammate: Create a name like “alice-bob” using your first names.
- The second (and third) teammate: Join the team your partner made.
- Finally, accept the assignment.
- Click the link to your team repo on the confirmation page.
- You will see a repo like the following:

git clonethe repository to your computer, and open the directory in PyCharm.- Configure
pytest:- If you do not have a
.venv/folder, click the bottom right of PyCharm where your Python version is listed. SelectAdd New Interpreter -> Add Local Interpreter, then hit Okay on the pop-up. - Open an Integrated Terminal window in PyCharm.
- Run
pip install pytest pytest-cov
- If you do not have a
PAUSE HERE and wait for the instructor
Part A - race to main
- Run
main.py, which won’t do much, but may create some additional files in your workspace. - You should be on the
mainbranch. Add a comment with only your name to the top ofmain.pyin a comment, e.g.,# Alice Bobberton. - Stage, commit, and push the change. Some of you will not be able to…
PAUSE HERE and wait for the instructor
What happens? How do you fix the problem?
- The partners need to pull, resolve the conflicts, add, commit, and push the changes.
- Make sure that each partner has added, committed, and pushed their name.
- Once done, all partners
git pullthe main branch.
PAUSE HERE and wait for the instructor
Committing to the same branch in a remote repository is a race. Two, three, five, or 10 people committing to the same branch is chaos.
Part B - proper git flow
B.1 - Group discussion
- Make sure that
main.pyin the remote repo’smainbranch contains all team members’ names. - Make sure everyone’s local
mainbranch is up to date with the remotemainbranch by runninggit pull. - Open
string_stuff.pyand discuss:- Who will implement
reverse_words() - Who will implement
count_vowels() - (If you have a 3-person team): who will implement
is_palindrome() - You do not need to edit
main.pyfor this assignment.
- Who will implement
- Each person creates a new feature branch to work in. Use a descriptive branch name reflective of the work you will be doing, not your name.
PAUSE HERE and wait for the instructor
B.2 - Individual work
- Each person implements their function in their branch – not in the
main/masterbranch. Talk to and help one another. You can use internet resources, but cite them in a comment if you do.- All of your work should be in
string_stuff.py - Do not worry about writing test code yet.
- All of your work should be in
- Remember to do small, incremental commits when appropriate.
- Run
main.pyand manually test your work. - Stage, commit, and
pushyour changes to the remote. Pay attention to the console because you may have to run a variant of thegit pushcommand.
PAUSE HERE and wait for the instructor
Integrate your work with main
Now it is time to integrate your changes into main. It will not be painless as there is still a race, but there is a right way and a wrong way to do it. We already did the wrong way. Here is the right way:
git switch maingit pull: make sure you have the latest changes from themainbranch in case someone else committed something.git switch <your-branch>git merge main: this merges the changes frommaininto your branch.- Resolve any conflicts in your branch and commit the changes to your branch.
git switch main: now we switch back tomaingit merge <your-branch>: bring the changes from your branch into main. This should be smooth because you already resolved merge conflicts between your-branch and main.git push: now push the updatedmainto the remote.
This flow will help ensure that main is “good, clean, code”. Merge conflicts will usually only happen in your branch, which is where you want to deal with them.
If each person completes steps 1-7 before anyone else pushes to main, the process will be smooth. If main changes while you are in the middle of these steps, you will not be allowed to push in step 7. You will have to pull main and resolve the merge conflicts either in main or in your-branch.
Good communication helps
A simple heads-up to your partner of, “Hey, I just pushed some changes to main. Make sure to integrate them into your branch” goes a long way.
And “I’m getting ready to integrate to main. Please don’t push anything yet” also helps.
B.3 - Integrate group work
Ensure that everyone’s changes to their branches are integrated into the main branch using proper merging. Make sure main.py runs and works properly for the completed functions.
Part C - for homework due Monday
Part C will add tests to the project to give you some more practice writing test cases in addition to practicing your Git workflow. Code really isn’t complete until it is tested, and developers write unit tests for the code they implement.
Preparation
- Complete Part B first.
- Ensure that your
mainremote branch is up-to-date, correct, and “good code”. - Ensure that each partner has checked out and pulled the
mainbranch updates. - Ensure that each partner has merged
maininto their branch.
At this point, all branches and main should be at the same version, so everyone is starting from the same place.
Instructions
You will write pytest unit test cases in test_string_stuff.py for each of the functions. Refer to the testing labs as necessary. Work with your partners.
- Individual work
- The partner who wrote a function also writes the tests for that same function in
test_string_stuff.py. - Each partner must write a minimum of two test cases: (1) testing “normal” input, (2) verifying the assertions are raised correctly.
- Commit and push your work to the same branch you worked on while implementing the function, not to
main. - You do not need to write test cases for
main.py.
- The partner who wrote a function also writes the tests for that same function in
- Group integration: Follow the Git Flow from your worksheet to integrate your work into
main. Each person:git switch maingit pull: make sure you have the latest changes from themainbranch in case someone else committed something.git switch <your-branch>git merge main: this merges the changes frommaininto your branch.- Resolve any conflicts in your branch and commit the changes to your branch.
git switch main: now we switch back tomaingit merge <your-branch>: bring the changes from your branch into main. This should be smooth because you already resolved merge conflicts between your-branch and main.git push: now push the updatedmainto the remote.
- Finishing up:
- Make sure that all functions and tests work in the
mainbranch. - Ensure that you have total branch coverage of the functions you implemented in
string_stuff.py.- You do not need to commit any coverage information to your repo. The
.gitignorefile should be ignoring these files, and that’s okay!
- You do not need to commit any coverage information to your repo. The
- Make sure that your “final” version of
mainis pushed to GitHub.
- Make sure that all functions and tests work in the
Assignment 6 Rubric
- (15pts)
git loghistory shows multiple commits to each partner’s branch and integration into main following the prescribed Git Flow - (15pts) Final version of
maincontains functionally correct implementations and test cases achieving 100% branch coverage of all functions implemented instring_stuff.py.
Final submission due Sunday, October 26
You will push all your branches and finished code to GitHub.
7 - Assignment 7 - Meteoric Design, Implementation, and Test
Code resources
Submitting code or other solutions from anywhere other than your own brains is cheating.
- Can you research how to use a particular function or library such as pytest? Yes.
- Can you get code that solves all or part of your homework? No.
- When in doubt, ask. I will not be upset if you ask.
Refer to the full details in the Syllabus on Canvas.
Setup
- Click this link: https://classroom.github.com/a/VLhFcyMu
- The first teammate: Create a name like “alice-bob” using your first names.
- The second (and third) teammate: Join the team your partner made.
- Accept the assignment.
- Click the link to your team repo on the confirmation page.
git clonethe repository to your computer, and open the directory in PyCharm.- Configure
pytest:- Click the bottom right of PyCharm where your Python version is listed. Select
Add New Interpreter -> Add Local Interpreter, then hit Okay on the pop-up. - Open a new Integrated Terminal window in PyCharm.
- Run
pip install pytest pytest-cov
- Click the bottom right of PyCharm where your Python version is listed. Select
Introduction and Problem Statement
You will complete a program to analyze the NASA Meteorite Landings dataset: https://data.nasa.gov/dataset/meteorite-landings-api. You will work with your partner(s) to design, implement, and test your solution.
You may only collaborate with your partner(s). All partners must contribute equally to the assignment. Each person is responsible for implementing and testing part of the solution.
Read the Problem Statement: PDF or web. Paper hand-outs will be provided in class.
Part A) Design
In class, discuss the organization of your code with your partner(s). Discuss the Problem Statement, and then think of a sensible design in terms of the functions and optionally the modules (files) you will create.
Follow the 5 low level design rules:
- Avoid magic literals.
- Functions should have a single responsibility.
- DRY (Don’t Repeat Yourself) and the Rule of Three.
- Handle errors at the lowest sensible level, and re-raise/re-throw them otherwise.
- Raise specific errors and define your own if needed.
There are many ways to solve this problem while adhering to the design rules. You may evolve your design during Implementation and Test.
Your focus at this stage (prior to writing code) should be on the Single Responsibility Principle. By the end of class, show the instructor:
- Function signatures you have stubbed (only written the
defline) inmeteoric.py. - Docstrings that (i) explain each function, and (ii) specify which partner is responsible for implementing and testing the function.
Part B) Implementation & Test
This part is completed as homework. Coordinate your work via Slack, email, or text, and contribute your work to your team’s GitHub repo.
Implementation requirements
- Implement a solution to the Problem Statement in
meteoric.py. - Each person must work in a branch in git, then merge into
mainwhen appropriate. I will only look at themainbranch when grading. Review the content from Assignment 6 on proper Git workflow. - Put your names at the top of
meteoric.pyin the module docstring. - You may create classes and files and use imported libraries, but these things are not necessary.
- Your solution must adhere to the 5 rules of low-level program design.
- You are free to modify the provided code, including
load_data()code. - You will need to implement the haversine formula. You may use code from the web, but include the link to the source website in a code comment.
- Add docstrings following our conventions to any functions, classes, and files you create.
- The code must adhere to the PEP8 coding conventions discussed in class.
Testing requirements
- Add test cases to
test_meteoric.pyto verify your new code. - You must achieve 90% branch coverage in all source files except for the
main()function. - If you create additional source files, you must also create a corresponding
test_*.pyunit test. - All test cases must run from the CLI with
pytest. - Use
pytest --cov --cov-branch --cov-report=htmlto generate a branch coverage HTML report in your project directory.- note: the
htmlcov/and.coveragefiles generated by pytest are ignored by Git and will not appear in your repos. This is intentional.
- note: the
Rubric
- (5pts) PEP8 coding conventions followed
- (5pts) Docstring conventions followed for modules (files), classes (if any), and functions.
- (25pts) User commands are correctly implemented, including exception handling of user input errors.
- (10pts) Adherence to our 6 low level design rules.
- (15pts) Multiple test cases with proper test structure for your source code.
pytestbranch coverage HTML report demonstrating ≥90% branch coverage of all source code except formain().
Submission due Nov 17
Commit and push your code to GitHub following the prescribed workflow when working with git from Assignment 6.
- Each person must work in a branch in git, then merge into
mainwhen appropriate. - Make sure to push your branches to GitHub.
- I will only look at the
mainbranch when grading, so your branches must be properly merged into main.
You do not submit anything to Canvas.
7.1 -
Problem Statement
Problem outline
Write a program the analyzes the NASA Meteorite Landings dataset available at https://data.nasa.gov/widgets/gh4g-9sfh. The program runs from the Terminal/CLI. The program will have two primary capabilities. The first is to display all meteorites discovered in a given year. The second is to display the meteorite geographically closest to a provided latitude and longitude.
The program must run from the CLI as python meteoric.py <command> <argument>. See the input format and sample inputs for examples of running the program.
Input format
The program must understand the following commands:
year <integer>: Print out the meteorite name, latitude, and longitude for all meteorites discovered in the<integer>year. It is possible that no meteorites were discovered in a given year. Example usage:python meteoric.py year 1999geopoint <latitude,longitude>: Print out the meteorite name, latitude, and longitude for the meteorite with the closest great-circle distance to the coordinates. Latitude is a float in the range [-90.0, 90.0]. Longitude is a float in the range [-180.0, 180.0]. Example usage:python meteoric.py geopoint 34.2257,-77.9447
The data in meteorite_landings.csv looks like this:
name,id,year,reclat,reclong
Aachen,1,1880,50.775,6.08333
Aarhus,2,1951,56.18333,10.23333
Abee,6,1952,54.21667,-113
Acapulco,10,1976,16.88333,-99.9
...
| Field | Description |
|---|---|
name | A name for the specific meteorite. |
id | A unique integer identifier for the meteorite. |
year | The year the meteorite was found or observed. Years are positive 4-digit integers. |
reclat | The latitude at which the meteorite was found. Latitudes are floats in the range [-90.0,90.0]. |
reclong | The longitude at which the meteorite was found. Longitudes are floats in the range [-180.0,180.0]. |
Important: a load_data() function is provided in meteoric.py that loads the data from meteorite_landings.csv into a list of lists. You do not need to validate the data in the CSV file, however, some fields may be blank if the information is missing.
Output format
- Print meteorite data to the console in a human-friendly format.
- When searching for all meteorites that were discovered in a given year the program will either: (a) display a list of meteorites discovered, or (b) display a message stating no meteorites were found for the given year.
- When searching for the closest meteorite landing from a specific location, the program will display the name (or names if two or more meteorites have an equal distance from the specified location) of the meteorite closest to the location given by the user.
- If the user fails to provide a valid command or valid arguments, the console displays an error message indicating what the user did incorrectly.
Exceptional conditions
Do not assume the <command> or <argument> are present or valid. The program must print an error message, not an exception or stack trace, if given bad arguments.
- user can put in an invalid command keyword
- user does not give an argument
- user gives an invalid data type with the year keyword
- user enters a year with no meteorite
- user inputs latitude and longitude incorrectly
- user enters multiple arguments
- user gives an out of range latitude or longitude
Sample input
python meteoric.py test: invalid commandpython meteoric.py year: missing argumentpython meteoric.py geopoint: missing argumentpython meteoric.py year s: invalid argumentpython meteoric.py geopoint abcdef: invalid argumentpython meteoric.py year 1999 2001 asd: invalid argumentspython meteoric.py geopoint 120.884,300.475: invalid latitude and longitudepython meteoric.py geopoint 32.558,78.854: valid search by geopointpython meteoric.py year 1818: valid search by yearpython meteoric.py year 55: valid search by year, no meteorites match that year
Sample output
You may change these to be more precised if you like, but not less precise.
Invalid command and argument. Correct format is python meteoric.py <command> <argument>.Invalid command and argument. Correct format is python meteoric.py <command> <argument>.Invalid command and argument. Correct format is python meteoric.py <command> <argument>.Invalid argument. year argument must be an integer.Invalid argument. geopoint argument must be latitude,longitude.Invalid command and argument. Correct format is python meteoric.py <command> <argument>.Invalid argument. geopoint latitude or longitude out of range.Meteorite(s) discovered closest to 32.4, 103.92: Guangyuan, latitude: 32.4, longitude: 105.9Meteorite(s) discovered in 1818: Seres, latitude: 41.05, longitude: 23.56667 Slobodka, latitude: 55, longitude: 35 Zaborzika, latitude: 50.28333, longitude: 27.68333 Cambria, latitude: 43.2, longitude: -78.8 Cape York, latitude: 76.13333, longitude: -64.93333No meteorites found for the year 55.