1 - Assignment 1 - Problem Statements

Practice creating a well-defined problem statement, and then implementing it.

You are getting the first edition of all these pages. Please let me know if you find an error!

“Programming all too often begins without a clear understanding of the problem.”

– J.M. Yohe1

A good problem statement contains2:

  1. Concise and precise statement of the problem
  2. Clearly specified input format. What does the data look like?
    • Input could come as function arguments, file contents, or user console input.
    • The “format” is what this data looks like, e.g., three integer values separated by spaces on a line.
  3. 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, what does this data look like?
  4. Indication of any exceptional conditions, e.g., things you should check for (like invalid values) and what you should do if they occur.
  5. Sample input
  6. Sample output

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, and c. They can form a triangle if:
a + b ≥ c, and
b + c ≥ a, and
a + c ≥ b.

The program can accept a single set of input values, produce a result, and then terminate. Or, you can include a loop that allows the user to repeat the process multiple times before quitting. It’s up to you.

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

You and your partner have complete freedom in specifying your problem so long as the following criteria are met:

  • It accepts user input and produces output for the user.
  • It correctly calculates the result.
  • The statement identifies at least two exceptional conditions and how they will be handled.

Rubric

  • (6 pts) All elements of the template are completed.
  • (1 pts) At least two exceptional conditions are specified.
  • (3 pts) Correct spelling and grammar.

Submission due Sep 3

Each partner submits their team’s spec.txt to the Canvas assignment 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 Sep 5

Submit the following to the Canvas assignment page:

  1. your triange.py file
  2. your spec.txt file (again) including any changes

  1. Yohe, J. M. (1974). An Overview of Programming Practices. ACM Computing Surveys (CSUR), 6(4), 221–245. ↩︎

  2. Ledgard, Henry F. (1975). Programming Proverbs. Hayden Book Co. ↩︎

2 - Assignment 2 - Unit testing

Practice implementing and testing simple functions.

You are getting the first edition of all these pages. Please let me know if you find an error!

Updates - Sep 23

  • Due date extended to Sunday, Sep 29
  • Added requirement to create control flow graphs (CFGs) for source functions.

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.

Instructions

The assignment is to be completed alone. Refer to the Syllabus for policies on what is allowed and what is not.

Setup

  1. Create an assn2/ subdirectory in your seng-201/ directory using the CLI.
  2. Download grades.py.
    • If using WSL, use the Explorer to drag to grades.py to your home folder on the Ubuntu side.
  3. Use the CLI to move grades.py into the new assn2/ directory.

Implementation

  1. Put your name at the top.
  2. You may not change the main() function in any way.
  3. You may add to the __main__ block to help test if you want.
  4. Complete the functions calculate_average() and determine_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() or input() from these functions.

Testing

You will be create a test file and run it using pytest.

  1. Create a test file for grades.py.
  2. Put your name at the top of your test file in a comment.
  3. 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]). Use assert statements 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.
  4. 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.

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): (NEW REQUIREMENT) Create a control flow graph (CFG) for each of your implementations of calculate_average() and determine_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 CVG 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() or input() statements in calculate_average() or determine_grade()
    • Changing main() in any way
    • Changing the method signature of calculate_average() or determine_grade()
    • Your code or tests fail due to syntax error.

Submission due Sep 29

Submit your grades.py, your test file, and your CFG PDF file to the Canvas assignment page.

3 - Assignment 3.a - Meteoric

Write the problem statement and plan the design of an application with a partner.

Group work

You will complete all parts of Assignment 3 with a partner. Partners will be paired up in class on Oct 15. You may look up your partner on the Canvas People tab and searching for your name.

You may collaborate with your partner(s) only. You will be working together to submit one assignment. Equal contribution is required.

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

You will complete a program to analyze the NASA Meteorite Landings dataset: https://data.nasa.gov/widgets/gh4g-9sfh.

  1. Create an assignment3/ directory in your seng-201/ directory.
  2. Download spec.txt and meteorite_landings.csv. Place them in the assignment3/ directory.
  3. An implementation file, meteoric.py will be made available on Thursday.

Dataset

Open meteorite_landings.csv in a text editor or spreadsheet application such as Excel or Google Sheets to view the data. The data 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
...
FieldDescription
nameA name for the specific meteorite.
idA unique integer identifier for the meteorite.
yearThe year the meteorite was found or observed. Years are positive 4-digit integers.
reclatThe latitude at which the meteorite was found. Latitudes are floats in the range [-90.0,90.0].
reclongThe longitude at which the meteorite was found. Longitudes are floats in the range [-180.0,180.0].

Part A - problem statement

With your partner, write a problem statement as you did for Assignment 1. Copy the text below verbatim into the problem outline section of spec.txt. Remember that problem statements do not specify design or implementation details.

Do not implement anything yet; you will be given starter code on Thursday.

Problem outline

This program analyzes the NASA Meteorite Landings dataset available at https://data.nasa.gov/widgets/gh4g-9sfh.

The program must run in two ways:

  1. Run from the CLI as python meteoric.py <command> <argument>
  2. Run or debug meteoric.py without arguments and it will prompt the user to input the <command> <argument> in the console.

The program must understand the following commands:

  • year <integer>: Print out the meteorite data 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 1999
  • geopoint <latitude,longitude>: Print out the meteorite data 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

Print meteorite data to the console in a human-friendly format.

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. Some examples of bad program calls:

  • python meteoric.py test: invalid command
  • python meteoric.py year: missing argument
  • python meteoric.py year s: invalid argument
  • python meteoric.py year 1999 2001 asd: invalid arguments

Important: Code will be provided for you that loads the data from meteorite_landings.csv into a data structure. You do not need to validate the data in the CSV file, however, some fields may be blank if the information is missing.

Rubric

Complete the spec.txt template:

  • (8 pts) Sample outputs covering all requirements.
  • (8 pts) At least eight distinct exceptional conditions.
  • (4 pts) All other elements of the problem statement template are completed.

Submission due Oct 16

One partner submits their team’s spec.txt to the Canvas assignment page.

4 - Assignment 3.b - Meteoric Design, Implementation, and Test

Apply low-level design rules to implement and test your application.

Part B - design, implementation, and test

You will work with your partner(s) to design, implement, and test your solution to Assignment 3, Part A. Download meteoric.py and test_meteoric.py to your assignment3/ folder.

You must identify a way to communicate and collaborate on the assignment:

  1. Meeting in person to work together
  2. Chatting and sharing code over a tool like Discord, Slack, or Teams. You may use the class Slack workspace.
  3. Emailing back and forth and texting.

You may only collaborate with your partner(s). You will submit one final solution. Review the section of the course policies on collaboration, cheating, and personal proficiency.

All partners must contribute equally to the assignment. Design will be done collaboratively in class. Implementation and testing tasks must be divided equally among the partners. Make each person responsible for implementing and testing part of the solution.

Design - in class

In class on October 17, discuss the organization of your code with your partner(s). You must come to an agreement on the design.

Follow the 6 low level design rules:

  1. Separate input/output logic from business logic.
  2. Functions should have a single responsibility.
  3. Handle errors at the lowest sensible level, and re-raise/re-throw them otherwise.
  4. Raise specific errors and define your own if needed.
  5. Avoid magic literals.
  6. DRY (Don’t Repeat Yourself) and the Rule of Three.

Rules 3-4 require your judgment. There are many ways to solve this problem while adhering to the design rules. Be prepared to justify your design decisions!

You may evolve your design during Implementation and Test.

By the end of class, show the instructor:

  • The function signatures you have decided on in meteoric.py
  • Comments or docstrings that (i) define each function, and (ii) which partner is responsible for implementing and testing the function.

Implementation

  1. Put your names at the top of meteoric.py in the module docstring.
  2. You may create classes and files and use imported libraries, but these things are not necessary.
  3. You may evolve your design as you go along. This is a natural part of implementation.
  4. You are free to modify the provided code, including load_data() code.
  5. You may use a Python implementation of the haversine formula from the web. If you do, add a comment to the code containing a link to the website.
  6. Add docstrings following our conventions to any functions, classes, and files you create. Additionally, identify the partner primarily responsible for implementing and testing each function.
  7. The code must adhere to the PEP8 coding conventions discussed in class. You are free to use a Visual Studio Code extension that helps you achieve compliance.

Testing

  1. If you are a WSL or Linux user, set up pytest for the project.
  2. Add test cases to test_meteoric.py. Any additional source files you create must also have a test_*.py test.
  3. All test cases must run from the CLI with pytest.
  4. Use pytest --cov --cov-branch --cov-report=html to generate a branch coverage HTML report in your project directory.
  5. You must achieve 90% branch coverage in all source files except for main().

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. pytest branch coverage HTML report demonstrating ≥90% branch coverage of all source code except for main().

Submission due Oct 21

Zip your project directory, including spec.txt, all Python files, and your coverage report. Upload the .zip file to Assignment 3, Part B on Canvas.

5 - Assignment 3.c - Meteoric Maintenance

Extending code functionality.

Part c - maintenance

Software maintenance is the term for updating software code to provide new functionality, change existing functionality, fix bugs, or implement a better design. Good software design makes maintaining long-lived code easier.

You will work with your partner(s) update your meteoric.py implementation. Start with code you submitted for Assignment 3.b. Review the collaboration, cheating, and personal proficiency section of the course syllabus.

Instructions

You must design, implement, and test your expanded solution. Review the changes in this section, then look at the rubric for what is expected.

Clarification: You do not use Git or GitHub with this assignment.

a) Changing data

Researchers have been hard at work and added new information to the meteorite data. Download meteorite_landings_full.csv.

New fields have been inserted for each meteorite:

name,id,nametype,recclass,mass (g),fall,year,reclat,reclong
Aachen,1,Valid,L5,21,Fell,1880,50.775,6.08333
Aarhus,2,Valid,H6,720,Fell,1951,56.18333,10.23333
Abee,6,Valid,EH4,107000,Fell,1952,54.21667,-113
Acapulco,10,Valid,Acapulcoite,1914,Fell,1976,16.88333,-99.9

Alter meteoric.py so that it loads data from meteorite_landings_full.csv. You no longer use the old meteorite_landings.csv.

The year and geopoint commands must continue to work. Update these commands to print the new fields of nametype, recclass, mass (g), and fall.

b) New commands

Your meteoric.py must support the following new commands in addition to year and geopoint:

  • class <string>: print all meteorites whose recclass matches the provided string. The match must be case insensitive:
    • a search for h6 will match all meteorites with type H6 or h6
    • a search for aCupuLCOITE will match Acapulcoite.
  • (Extra Credit) heaviest <n>: print the top <n> heaviest meteorites according to their mass (g). The list must be sorted so that the heaviest is printed first and the least heavy is printed last. <n> is an integer greater than 0. For example heaviest 5.
    • You need to implement the sorting logic, you cannot just hardcode a list of heaviest meteorites.
  • (Extra Credit) count-fall: print the number of meteorites for each unique value of the fall field. The command ignores any arguments.
    • There are only two values in the data: Fell and Found, but your algorithm MUST account for the possibility that new values will be added, so you cannot hardcode these values in your algorithm. Example output:
      Fell 1107
      Found 44609
    

Rubric

  • (5pts) Update your problem statement in spec.txt to account for the new commands, including input samples, exceptional conditions. Update all output samples to include the new fields.
  • (5pts) PEP8 coding conventions and Docstring conventions followed.
  • (15pts) class command implemented and old commands are updated to correctly use the expanded CSV file, including exception handling of user input errors.
  • (5pts) Adherence to our 6 low level design rules.
  • (10pts) pytest branch coverage HTML report demonstrating 90% branch coverage of all source code except for main().
  • (10pts each) Correct implementation and test of heaviest and/or fall commands.

Submission due Oct 27

Zip your project directory, including spec.txt, all Python files, and your coverage report. Upload the .zip file to Assignment 3, Part C on Canvas.

6 - Assignment 4 - Simple Git

Practicing basic Git commands

Objectives

  • Practice the basic Git commands: add and commit and, if necessary, reset
  • Practice with Git branching and merging

Setup

Have a Terminal open with your seng-201/ as the working directory. Run the command:

git clone https://github.com/llayman/assn4-git-calc

This will create a new subdirectory named assn4-git-calc that is a “clone” of a Git repository I created.

Open the assn4-git-calc/ directory in Visual Studio Code. You will see two files, calc.py and .gitignore. You will do all your work in calc.py.

Cloning, GitHub, and the .gitignore file will be explained in an upcoming lab. You can run the clone command again if you need to delete the directory and start over for some reason.

Instructions

Run calc.py and to try it out with the options. You are going to add to the functionality.

Part A: Small, incremental commits

Follow the style in the code. Do not worry about our design rules, unit testing, input validation, or error handling.

  1. Create and checkout a new branch named more-options.
  2. Create a separate commit with a brief, meaningful message for each option below. You must have at least two commits to the more-options branch:
    1. Add a “power” option to raise one number to the power of another. Stage and commit it.
    2. Add a “logarithm” option that computes the log(x, base). Import the standard math library and use the log() function.
    3. The options must be incorporated into the user menu.
  3. All pre-existing options must continue to work, including “Quit”.

Part B: Merge your work into main

  1. Checkout the main branch and use the merge command to merge your more-options branch into main.
  2. Draw a sketch of your branch history after completing the merge in a style similar to the example below from our labs. Use git log to help put it together.
    1. Clearly mark the main and more-options branches and the position of the HEAD.
    2. Take a picture or draw the history in a file. Put the file in your assn4-git-calc/ directory, stage it, and commit it to main.

Part C: Resolving merge conflicts

I have created another branch, rand, that adds random number generation to calc.py. Unfortunately, this will generate merge conflicts with your changes.

  1. Make sure main is the active branch.
  2. Run git merge origin/rand
  3. You must resolve the merge conflicts correctly, meaning:
    1. All of your new options still work.
    2. My random number generation option works.
    3. The user menu and all logic is updated to include all options and quit properly.
  4. Manually run and check all the options.
  5. Stage and commit to main once the merge conflicts are resolved.
  6. Draw a second sketch showing your current branch history.
    1. Clearly mark all three the branches and the position of the HEAD.
    2. Take a picture or draw the history in a file. Put the file in your assn4-git-calc/ directory, stage it, and commit it to main. You can combine it with the previous picture into one file if convenient.

Rubric

Partial credit is not awarded for these items: all or nothing.

  • (5 pts) Two drawings showing correct Git history.
  • (5 pts) Version history of submission shows:
    • a minimum of two commits to the more-options branch
    • a merge commit on the main branch incorporating the changes from the rand branch
  • (5 pts) All options (original features, your additions, and random numbers) correctly work in the final commit.

Submission due November 10

Zip the entire assn4-git-calc/ directory and upload it to Canvas, which will include the hidden .git/ directory containing the local repository. To do this:

  1. Navigate to the directory containing the assn4-git-calc/ folder.
  2. Right-click the folder and select Compress "assn4-git-calc"
  3. Upload the assn4-git-calc.zip to Canvas.
  1. Open the Windows File Explorer
  2. In the Navigation Pane on the left of the Filer Explorer, scroll down until you see “Linux”. Double-click it and then double-click the “Ubuntu” or similarly-named folder.
  3. Navigate to the directory containing your assn4-git-calc/ directory. It should be something like home -> your_name -> seng-201
  4. Right-click the assn4-git-calc/ directory and select Send to... then Compressed (zipped) folder.
  5. Right click in the Explorer window and select Refresh. You should see the zip file.
  6. Upload assn4-git-calc.zip to Canvas.
  1. Open the Files app.
  2. Navigate to the directory contains your assn4-git-calc/ directory.
  3. Right-click the assn4-git-calc/ directory and select Compress..., then click Create.
  4. Upload assn4-git-calc.zip to Canvas.

7 - Assignment 5 - Remote Git

Practice setting up and using a remote Git repo

Objectives

  • Practice the basic Git commands: add and commit and, if necessary, reset
  • Practice with Git branching and merging

Setup

  1. You must have completed Lab: GitHub CLI setup prior to starting this assignment.
  2. Click this link: https://classroom.github.com/a/JGEq7HZ2
  3. Select your name on the “Join the classroom” page and continue.
  4. Select “Accept this assignment” on the next page.

You will see a confirmation screen similar to the one below. Refresh the page if you don’t see it.

Classroom assignment confirmation

Click on the link to your assignment repository. You will see a GitHub remote repository containing a README.md file:

starting point of the repo for the assignment

Instructions

  1. Clone the project to your seng-201/ directory or wherever you are gathering your assignments.
  2. Option 1: Create some content for your project. I don’t care what it is: Python files, text files, etc. Make at least two, small, incremental commits to the main branch that change your project content.
  3. Option 2: Complete Assignment 4 using this repo instead of creating your own.
  4. git push your completed code.

Rubric

No partial credit.

  • (10 pts) Your remote repo’s version history show that you contributes a minimum of two versions on the main branch.

Submission due November 11

Push your version to GitHub by the deadline. No Canvas submission.

8 - Assignment 6 - Git/GitHub Flow

Properly using Git to collaborate on teams

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. The video of that class is below:

Setup

  1. You must have completed Lab: GitHub CLI setup prior to starting this assignment.
  2. Click this link: https://classroom.github.com/a/hl0Jq6SR
  3. Teams:
    • The first teammate: Create a name like “Team A” that reflects the team assignment in class.
    • The second (and third) teammate: Join the team your partner made.
  4. Finally, accept the assignment.
  5. Click the link to your team repo on the confirmation page.
  6. You will see a repo like the following:
    Assignment 6 repo
  7. git clone the repository to your computer, and open the directory in Visual Studio Code.

PAUSE HERE and wait for the instructor

Part A - race to main

  1. Run main.py, which won’t do much, but may create some additional files in your workspace.
  2. You should be on the main branch. Add a comment with only your name to the top of main.py in a comment, e.g., # Alice Bobberton.
  3. 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?

  1. The partners need to pull, resolve the conflicts, add, commit, and push the changes.
  2. Make sure that each partner has added, committed, and pushed their name.
  3. Once done, all partners git pull the 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

  1. Make sure that main.py in the remote repo’s main branch contains all team members’ names.
  2. Make sure everyone’s local main branch is up to date with the remote main branch by running git pull.
  3. Open string_stuff.py and discuss:
    1. Who will implement reverse_words()
    2. Who will implement count_vowels()
    3. (If you have a 3-person team): who will implement is_palindrome()

B.2 - Individual work

  1. Each person creates a new 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

  1. Each person implements their function on their branch. 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.
  2. Remember to do small, incremental commits when appropriate.
  3. Run main.py and manually test your work.
  4. Stage, commit, and push your changes to the remote. Pay attention to the console because you may have to run a variant of the git push command.

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:

  1. git checkout main
  2. git pull: make sure you have the latest changes from the main branch in case someone else committed something.
  3. git checkout <your-branch>
  4. git merge main: this merges the changes from main into your branch.
  5. Resolve any conflicts in your branch and commit the changes to your branch.
  6. git checkout main: now we switch back to main
  7. git 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.
  8. git push: now push the updated main to 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 - In class on Thursday

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

  1. Complete Part B first.
  2. Ensure that your main remote branch is up-to-date, correct, and “good code”.
  3. Ensure that each partner has checked out and pulled the main branch updates.
  4. Ensure that each partner has merged main into 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.
  • Group integration: Follow the Git Flow from your worksheet to integrate your work into main. Each person:
    1. git checkout main
    2. git pull: make sure you have the latest changes from the main branch in case someone else committed something.
    3. git checkout <your-branch>
    4. git merge main: this merges the changes from main into your branch.
    5. Resolve any conflicts in your branch and commit the changes to your branch.
    6. git checkout main: now we switch back to main
    7. git 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.
    8. git push: now push the updated main to the remote.
  • Finishing up:
    • Make sure that all functions and tests work in the main branch.
    • 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 .gitignore file should be ignoring these files, and that’s okay!
    • Make sure that your “final” version of main is pushed to GitHub.

Assignment 6 Rubric

  • (15pts) git log history shows multiple commits to each partner’s branch and integration into main following the prescribed Git Flow
  • (15pts) Final version of main contains functionally correct implementations and test cases achieving 100% branch coverage of all functions implemented in string_stuff.py.

Final submission due Sunday, Nov 17

You will push all your branches and finished code to GitHub.

An optional, individual Extra Credit Assignment is due at the same time.

9 - Extra Credit Assignment - More Git/GitHub Flow

More practice with Git and GitHub

Instructions

This is an individual assignment. You may not collaborate.

I will not grade incomplete Extra Credit, so you must complete all steps below at a minimum. You may earn partial extra credit if something is incorrect.

You may find it useful to refer to Scenario 1 of the lab on remote repos.

  1. Make a new public GitHub repository.
  2. Create a new Python project with the file math_ops.py containing the following:
    # math_operations.py
    
    def divide_numbers(a, b):
        """Divides two numbers and returns the result."""
        return a / b  # Potential division by zero error
    
    if __name__ == "__main__":
        x = 10
        y = 0
        result = divide_numbers(x, y)
        print(f"The result of division is: {result}")
    
  3. Connect your project to your GitHub repository. Add, commit, and push the first version to the main branch.
  4. Create two branches off the first version: bug-fix and new-feature.
  5. In bug-fix: make it so that an attempt to call divide_numbers with a 0 in the denominator results in a nice message printed to the screen saying “Cannot divide by 0” rather than throwing an exception.
    • Commit and push your changes to the bug-fix branch.
  6. In new-feature: add a function of your choice to the program and call it from the main block.
    • Commit and push your changes to the new-feature branch.
  7. Merge bug-fix into main first.
  8. Merge new-feature into main second. Follow the Git Flow.
  9. Ensure that main correctly incorporates both branches and push it to your remote repository.

Rubric

  • 15pts total:
    • All branches are created, committed to, and pushed as specified above.
    • Functionality is implemented as specified above.
    • Feature branches are merged into main following the Git Flow, and merged functionality works correctly in main.

Final submission due Sunday, Nov 17

Two items:

  1. Push all your branches and finished code to GitHub.
  2. Enter the URL to your public GitHub repository containing the assignment on the Canvas assignment page.

10 - Assignment 7 - Deployment

Deploying a simple webapp to a remote server

Objectives

  • More practice working with remote servers.
  • Practicing extending an existing application, albeit simply.

Setup

  1. If not done already, complete the Labs on working with remote servers so that you can connect to the ada.cis.uncw.edu server.
  2. If not done already, complete Lab: Flask server app to sign-up for, check out, and run the assignment.

Part A - extend the web app

Work on your computer to extend and test the assn7 app.

  1. Create and work in a new branch.
  2. Open the file templates/index.html and the header line to <h1>Welcome to [YOUR_NAME]'s Flask Quizzer!</h1>
  3. Add at least three more MultipleChoiceQuestions to the list in questions.py.
  4. Start the server app on your computer using flask --app app run --debug. Full setup and running instructions are in Lab: Flask server app.
  5. (See note below) Test your changes using a web browser as a client, i.e., navigate to http://127.0.0.1:5000.
  6. Commit and push your branch.
  7. Merge your branch into main. Commit and push main to GitHub.

Testing the server app locally

You test your app by calling the API endpoints. Do this by putting an endpoint URL into the address bar of your browser.

You will need to get the unique id (UUID) of the question you want to check. The UUIDs will change every time you start your server. You can get them by trying random questions, like in the video below, or (even better) you can add a print() statement to the loop in questions.py to print them out when they’re made.

Like below:

Part B - deploy and run your app on ada

You must be on the hawkwifi, a UNCW lab computer, or the VPN to connect to ada.cis.uncw.edu.

Setup on ada

  1. Connect to the ada server and clone your assn7 GitHub repo there as described in Lab: Working on ada.
  2. cd into your project directory
  3. Create the virtual environment needed to run flask with the following commands:
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    
    You should see several libraries install.

Running on ada

  1. Make sure you are in the project directory.
  2. Your ada Terminal must show the text (.venv) before you can run the server. If you do not see (.venv), run source .venv/bin/activate to activate the virtual environment.
  3. flask --app app run -h 0.0.0.0 -p [5-digit]  # put a number between 20000-50000
    
    Use a different port number if you see an error like Port 23456 is in use by another program. Either identify and stop that program, or start the server with a different port.

Updating your code on ada

If you find a bug, or want to change something in your code, work on it on your local computer first. Commit and push to GitHub. Then connect to ada, pull your changes, and try them there.

Submission due Monday, December 2

  1. Commit and push all your changes to GitHub.
  2. Permanently run your server on ada by doing the following:
    nohup flask --app app run -h 0.0.0.0 -p [5-digit port number]
    
    You will see different output.
  3. Hit CTRL-Z to suspend the server
  4. Run the command bg to put the server in the background.
  5. Run cat nohup.out. Note the URL in that file.
  6. Open a browser and put in your URL address to verify that can accessing the app remotely.
  7. Submit your server’s URL including the port on the Canvas assignment page: https://uncw.instructure.com/courses/83039/assignments/1258974

Assignment 7 Rubric

  • (10pts) git log history shows commits to a feature branch and merge into main with required changed to the app.
  • (15pts) Final version deployed, accessible, and functional on ada with URL submitted to the Canvas assignment.

11 - Assignment 8 - Information Literacy

Putting your information literacy skills to the test.

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_8.docx.

  • Tasks 1 and 2 are completed with a partner in class, or by yourself if you missed class.
  • Task 3 is completed individually.

Code for Task 1

Run the following Python code. You will get an error and stack trace:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def calculate_cart_total(cart_items, tax_rate):
    """Calculate total cart cost including tax."""
    subtotal = sum(item["price"] * item["quantity"] for item in cart_items)
    return subtotal + (subtotal * tax_rate)

def display_cart_summary(cart_items, tax_rate):
    """Display a summary of the cart."""
    total_cost = calculate_cart_total(cart_items, tax_rate)
    print(f"Total cost (including tax): ${total_cost:.2f}")

def main():
    """Main function to simulate a shopping cart."""
    cart = [
        {"name": "Laptop", "price": 1000.0, "quantity": 1.0},
        {"name": "Headphones", "price": 200.0, "quantity": 2.0},
        {"name": "Mouse", "price": 50.0, "quantity": 1.0},
        {"name": "Keyboard", "price": 150.0, "quantity": 1.0},
        {"name": "Monitor", "price": 300.0, "quantity": 1.0},
        {"name": "HDMI Cable", "price": 10.0, "quantity": 2.0},
        {"name": "USB Drive", "price": "20.0", "quantity": 3.0},
        {"name": "External Hard Drive", "price": 100.0, "quantity": 1.0},
    ]
    tax_rate = 0.07  # 7% sales tax
    display_cart_summary(cart, tax_rate)

if __name__ == "__main__":
    main()

Submission due December 3 @ 2pm (before class)

Upload your completed assignment_8.docx to the Canvas assignment page prior to the start of class on December 3.

12 - Extra Credit Assignment - PyGame or Flask

Researching and implementing a PyGame or Flask application.

Instructions

This is an individual assignment. You may not collaborate. You will need to do your own research for this, and you may use AI to assist you. You may not communicate or obtain human help.

You have two options:

  1. Add more pages to the Flask app from Lab: Flask server app to create a browser-based quiz experience.
  2. Add more functionality to the game from Lab: Pygame client app and continue to interact with the question server.

You may earn credit for either the Flask option or the PyGame option, but not both.

Citations

In your code, clearly indicate any code that you obtained from an external source. Put the URL of the source in your code. Copying code without citing your source is plagiarism.

Option 1: Extend Flask

To earn any credit:

  • You must have a total of 10 questions in the system.
  • You must use the Flask quizzer app from Lab: Flask server app and Assignment 7. Run the server app on your local machine, not ada.
  • You must use the existing API and backend functions. You can extend those functions and add your own.

Each item below is worth points. You earn the points by fulfilling all the requirements of an item. Partial credit for an item will not be awarded. You deliver some or all of the items.

  1. (5pt item): Add a “Show All Questions” option to the homepage. This takes the user to a page where all of the questions are shown. The question test and choices must have separate HTML styles. The correct answer must be highlighted among the choices. No interactivity is required.
  2. (5pt item): Add a “Random question” option to the homepage. This takes the user to a page where they a random question and the question choices. The user can select an answer and is told if they chose the correct answer or not.
  3. (5pt item): An anonymous user can “Start a Quiz” from the home page. The quiz is 10 random questions (sampling with replacement). The user is shown how many questions they answered correctly at the end. The user must be able to return to the homepage and start a new quiz after completing the previous one.
  4. (5-10pt item): You may propose an 1-2 additional features of your choosing to the instructor. You must receive approval for each feature beforehand to receive credit.

Option 2: Extend Pygame app

To earn any credit:

  • You must have a total of 10 questions in the system.
  • You must use the Flask quizzer app from Lab: Flask server app and Assignment 7. Run the server app on your local machine, not ada.
  • You must use the existing API and backend functions. You can extend those functions and add your own.

Each item below is worth points. You earn the points by fulfilling all the requirements of an item. Partial credit for an item will not be awarded. You deliver some or all of the items.

  1. (5pt item): Fix the scorekeeping such that each question answered correctly is worth 2 points, and each incorrect choice deducts 1 point with no minimum. The score must be shown when the user quits the game, and on each question page (a running score).
  2. (5pt item): Add an “Incorrect” message, styled red at a minimum, when the user chooses the incorrect option for a question. Add a “Correct” message, styled green at a minimum, when the user chooses the correct option. When correct, either add a 2 second delay before showing the next question, or add a button on the screen the user must click to proceed. Do not allow the user to proceed to the next question until they get the current question correct.
  3. (5pt item): Add a main menu showing a Quit and Start Quiz option with instructions for how to choose each option. On Starting a Quiz, show 10 random questions (sampling with replacement). The user is shown their score at the end. The user must be able to return to the homepage and start a new quiz after completing the previous one.
  4. (5-10pt item): You may propose an 1-2 additional features of your choosing to the instructor. You must receive approval for each feature beforehand to receive credit.

Final submission due Sunday, Dec 8

  1. Indicate on Canvas which extra credit option you chose.
  2. For both Flask and PyGame: Ensure that all of your changes are merged into the main branch.
  3. For both Flask and PyGame: Push the latest version of your Flask server app to your Assignment 7 GitHub repository.
  4. PyGame option only: Push the latest version of your PyGame app to your PyGame GitHub Repo from Lab: PyGame client app.