lab02 : Next steps with github, Python functions, testing

num ready? description assigned due
lab02 true Next steps with github, Python functions, testing Fri 08/11 09:30AM Tue 08/15 05:00PM

If you find typos or problems with the lab instructions, please report them on Piazza. Please note that unit test will be covered on Monday 8/14 so you can leave the unit test part to Monday. But you can work on other part of this lab at this time.

Overview

The main purpose of this lab is to practice, as pair, a few skills involving Python, Unix, and github.

More specific Learning Objectives

The most important thing we want you to get out of this lab is the ability to

Here’s a more complete list of our learning objectives:

Step-by-Step through lab02

Step 1: Create a ~/github directory on your ACMS account

The following article explains how to create a ~/github directory on your ACMS account.

It also covers some basics of the commands you can use at the bash shell prompt—commands such as pwd, cd, mkdir, and others that you’ll need to know for SPIS (and in your later UCSD CSE courses) for working with your ACMS account.

If both you and your pair partner are already thoroughly familiar with Unix command basics—that is, you know how to create ~/github, and you are throughly familiar with everything in the table below, you can just create ~/mkdir, and skip the tutorial.

But if either or both of you has any doubt, you are strongly encourage to go through this page carefully and slowly, to learn some of the basics of working with Unix commands at the bash shell. That is one of the most fundamental skills you’ll need throughout all of the courses that use the ACMS unix accounts during your entire stay at UCSD.

We would encourage you to go through the entire tutorial at least once in one pair partner’s account, and then repeat it briefly in the second pair partner’s account so that each partner has a ~/github subdirectory.

To help you review whether you got all of the necessary learning from the tutorial, here is a brief overview (it is contained in the tutorial as well.)

Unix shell commmands:

Unix Command Brief explanation
date Show current date and time
history Show history of recent unix commands
pwd Print working directory
ls List files
mkdir foo Create subdirectory (folder) foo in current directory
mkdir ~/bar Create subdirectory (folder) bar under home directory (~)
cd Change directory to home directory (1st option)
cd ~ Change directory to home directory (2nd option)
cd foo Change directory to foo inside current directory
cd .. Change directory to parent of current directory (go up)
cd ~/fum Change directory to fum inside home directory (~)

You should also learn the following concepts:

When both partners have a ~/github directory and are comfortable with shell basics, move on to Step 2.

Step 2: Create your shared lab02 repo

There are three steps involved here. First, we’ll give you an overview, and then the details:

  1. One of the two pair partners should log into github.com to create an empty private repo in a particular way, namely, pre-populated only with a README.md, and a .gitignore for Python.
  2. The first pair partner will then invite the second to be a collaborator with Admin access.
  3. Finally, the second pair partner needs to accept the invitation to be a collaborator.

Note: it doesn’t matter which pair partner creates the repo—it can be the one listed first, or the one listed second in the pair name. For example, if the pair is listed as Alex_Chris in the Pair Name column on the SPIS 2017 list of pairs, it doesn’t matter whether Chris creates and then invites Alex, or Alex creates and then invites Chris.

For purposes of the rest of these instructions, though, we’ll refer to “first” as the partner under whose github account the repo is initially created, and “second” as the partner that gets invited to collaborate.

And regardless of who creates and who invites, please name the repo according to the pair order that is listed in the Pair Name column on the SPIS 2017 list of pairs. That makes it MUCH easier for us to find your work!

Step 2a: Create a private repo with a README.md and a .gitignore file for Python.

Choose which pair partner is going to create the repo—that pair partner should be the one that is logged into github.com.

To create the repo follow the instructions at the link: github create repo Method 2.

As you follow these instructions, create:

The Pair Name column in the SPIS 2017 Pairs List page corresponds to this First-Second part of your repo name.

An example correct repo name for the ficticious SPIS students Alex Triton and Chris La Jolla would be:

spis17-lab02-Alex-Chris.

Step 2b: First pair partner invites second pair partner to be a collaborator

The pair partner that created the repo will automatically have access. That partner needs to invite the second partner to be a collaborator with admin access.

The instructions to do that are found here: Github: Adding collaborators

Step 2c: Second pair partner accepts the invitation

The second pair partner should accept the invitation. This is usually straightforward: there is an invitation in the second pair partner’s incoming email with a link to click, and it is clear what to do.

If the email doesn’t arrive, though, or anything is not clear, there are troubleshooting instructions later on the same page you accessed in the previous step to add the partner as a collaborator:
Github: Adding collaborators

Step 3: One time steps for configurating your ACMS account for git

There are a few steps that we only have to do one time in order to get our ACMS account ready for use with git and github.

Those steps are outlined here. Please repeat these steps under each pair partner’s account.

TIME-SAVING TIP: You do not have to log “all the way out” and log back in to be able to do these steps for both pair partners. Instead, if the first pair partner is logged in, they can just allow the second pair partner to drive for a moment, and ssh into their account from a terminal window. This article explains how:

Step 4: Cloning a private repo at the bash (Unix) command line

Next, you need to clone your private repo into the ~/github directory of one of your ACMS accounts (either one will do.)

The instructions to do that are here: cloning your first repo.

When you’ve done that, we are finally ready for some Python programming!

Step 5: How to store a Python file in a repo

To review what you’ve done so far:

What you will do now is put some Python code into the local repo—or more precisely, you’ll put some Python code into the directory that corresponds to that repo. You won’t actually commit it to the repo until the next step.

So, what we want to do first is make ~/github/spis17-lab02-Name-Name (except with your pair’s names, not literally Name-Name) be your current directory. Use the cd command to make that happen.

When you’ve done it, you should be able to type pwd and see that your current directory path ends in github/spis17-lab02-Name-Name, just like in the example output below:

[spis17t3@ieng6-240]:spis17-lab02-Alex-Chris:118$ pwd
/home/linux/ieng6/spis17/spis17t3/github/spis17-lab02-Alex-Chris
[spis17t3@ieng6-240]:spis17-lab02-Alex-Chris:119$ 

Then, start up IDLE by typing idle3:

[spis17t3@ieng6-240]:spis17-lab02-Alex-Chris:119$ idle3

Once you do, use the File -> New File menu item twice to open two windows in which you can type Python code.

In the first window, enter this function definition. This function converts Fahrenheit temperatures to Celsius.

It should make sense to you based on what you’ve learned about Python functions so far.

# tempFuncs.py
def ftoc(fTemp):
   return (fTemp - 32)*(5.0/9.0)

In the second window, enter this code. Don’t just copy and paste it; read through it and try to understand it.

If you would like a more detailed, line-by-line explanation of this code, plus some background on unit testing in general, read the article Python: Unit Testing.

# test_tempFuncs.py

import unittest
from tempFuncs import ftoc

class Test_tempFuncs(unittest.TestCase):

   def test_ftoc_1(self):
      self.assertAlmostEqual(ftoc(212.0),100.0)

   def test_ftoc_2(self):
      self.assertAlmostEqual(ftoc(32.0),0.0)

   def test_ftoc_3(self):
      self.assertAlmostEqual(ftoc(-40.0),-40.0)

   def test_ftoc_4(self):
      self.assertAlmostEqual(ftoc(67.0),19.4444,places=3)

if __name__ == '__main__':
    unittest.main()      

Save each of the files by choosing ‘File -> Save’ from the Idle menu.

Save them with the exact names: tempFuncs.py and test_tempFuncs.py. It is important to get the upper vs. lowercase, and the punctuation correct.

When you save, the save dialog should indicate that they are being saved inside the ~/github/spis16-lab02-Name-Name folder that corresponds to your local github repo (you should see a .git directory already present). It is important that they are saved there, and not somewhere else. If you save them in another place, the next few steps of the lab won’t work properly.

Onve you have saved both files, with IDLE still open, open a second terminal window and navigate in that window into the ~/github/spis17-lab02-Name-Name folder, and do an ls command as shown here. You should see both the files, with names exactly as shown here.

Note that if you also have a .pyc file, that’s fine (or if you don’t, that’s fine too). You don’t need to worry about that one, or remove it. Files ending in .pyc are “compiled Python” code. They are temporary files used to speed up the execution of your Python code. Mostly, just leave them alone and they’ll come and go as needed.

[spis17t3@ieng6-240]:spis17-lab02-Alex-Chris:170$ ls
README.md  tempFuncs.py  tempFuncs.pyc  test_tempFuncs.py
[spis17t3@ieng6-240]:spis17-lab02-Alex-Chris:170$ 

Now try running the test_tempFuncs.py file.

Now, in the window with the test_tempFuncs.py file, try selecting “Run -> Run Module” from the menu.

You should get output that looks like this:

>>> ================================ RESTART ================================
>>> 
....
----------------------------------------------------------------------
Ran 4 tests in 0.031s

OK
>>> 

What if the names are not exactly right? mv and rm to the rescue

If the names of your tempFuncs.py and test_tempFuncs.py are not exactly right, you can use the unix mv command, which functions both as a move command as as a rename command. The syntax is:

mv oldname newname

For example to change temp_funcs.py to tempFuncs.py, you would type:

mv temp_funcs.py tempFuncs.py

If you end up with extra files, you can use the rm command to delete files you dont want. For example, to remove the file temp_Fenks.py that you perhaps saved by mistake, you can type:

rm temp_Fenks.py

Ok, so now you have a Python file with a function definition in it, and you have some test cases.

What’s next? We want to get this Python code into your local git repo, and then push the changes up to github.com.

Step 6: The basic git workflow of git add..., git commit..., git push...

So, having the code in the directory isn’t enough to get it into the git repo.

You actually have to go through a series of two steps to get the code into your local repo, and then a third step to update the origin repo on github.com with that code.

The process is described in two articles:

Essentially, though here’s what you are going to do:

  1. Make sure you are in your ~/github/spis16-lab02-Name-Name directory
  2. Type git status and read what it says
  3. Type git add tempFuncs.py test_tempFuncs.py to stage these two files (get them ready to be added to the repo)
  4. Type git status and read what it says
  5. Type git commit -m "ftoc function and tests" to commit the changes and provide an explanation of what you did
  6. Type git status and read the messages
  7. Type git push origin master to push the changes from your local repo to the origin repo (on github.com)
  8. Type git status and read the messages
  9. Navigate to your repo’s page at https://github.com and see that the two files now appear there, along with your commit message. You may need to refresh the page if you were already on it.

Congratulations, you’ve just done your first of many dozens of git commits you’ll do during SPIS, and the first of hundreds or thousands you’ll do during your four years at UCSD.

Step 7: Testing of Python functions

Now, in this case, we had some code that already worked right out of the gate. But the normal case is that we

  1. Start with a stub, and some test cases and make sure they fail.
  2. Replace the stub with working code so that the test cases pass.
  3. See if there is any way to refactor the code to improve it.

In this step, you’ll:

Ok, so let’s get started:

Step 7a: Add a stub for ctof(cTemp) to tempFuncs.py

Add a stub for a second function to the tempFuncs.py file by adding this code to the file:

def ctof(cTemp):
   return "stub"

This code is “always” the wrong answer, so it should fail every test. That’s what we want from a stub. It helps us “test the test” to make sure that it is successful at detecting bad code.

After adding this code, save the file tempFuncs.py. Then at the command prompt, inside the ~/github/spis16-lab02-Name-Name` direcory, type:

Then check the repo’s page on github.com to see that the changes appear.

Step 7b: Add import, and test cases for ctof to test_tempFuncs.py

Next, edit the test_tempFuncs.py file in IDLE3, and after the line

from tempFuncs import ftoc

add this line:

from tempFuncs import ctof

This line is needed so that we can pull the definition of ctof from the file tempFuncs.py and run our tests on it.

Now add some test cases for the cToF function.

We’ll give you the first one, but the rest you must come up with on your own:

   def test_ctof_1(self):
      self.assertAlmostEqual(ctof(100.0),212.0)

Add at least four more so that you have a total of five tests.

Once you are done and saved the file, its time to commit the changes:

Then check the repo’s page on github.com to see that the changes appear.

Step 7c: See the test cases fail

Now, run the test cases by selecting “Run -> Run Module” from the menu in the window for test_tempFuncs.py.

What you want to see is that the test cases for ftoc passed, but that the ones you added for ctof fail. In general, test cases where you have a “stub” function should fail either because:

You could also use a stub with a value of something like return -99999.999 if you like; then you’ll get a slightly different error, but the test will still fail—which is want you want for a stub. Note that this case is reported as a ‘failure’ rather than an ‘error’.

Are the tests failing the expected way?

If the tests are failing in the way we are hoping for, you can move on to the next step.

If on the other hand, there were errors of another kind (e.g. indentation errors, missing :, etc.) then you’ll want to fix those. And if that involves change either, or both of the two files, you’ll want to do another round of the steps to do a commit.

If the commit involves changes to both files, you can combine those into a single commit. Here’s how:

Step 7d: Replace the stub in ctof with correct code so that the tests pass

Now, you should write a correct version of the ctof function so that tests pass.

That will be a line of code that starts with return and ends with an expression involving the variable cTemp, and some math operations to convert that to an equivalent Fahrenheit value.

Try running the tests, and when all of your tests pass, you are ready to commit. What you are looking for is this:

.........
----------------------------------------------------------------------
Ran 9 tests in 0.000s

OK

If you get part-way done, and some of your tests pass, but not others, or you are in the middle of working when it is time for a break, that is STILL a good time to do a commit. Add the letters “WIP” to the start of your commit message so you know that this is not a finished product. “WIP” stands for “Work in Progress”. For example:

git status
git add tempFuncs.py
git status
git commit -m "WIP CL/AT  Some ctof tests passing, others failing"
git status
git push origin master

When you have all the tests passing, do one more commit with the commit message "CL/AT all tests passing".

A note about the exclamation point (!) in commit messages

One note: You may be tempted to put exclamation points in your commit messages, because getting the tests to pass is so very, very exciting. If you do, though, you’ll have to remember to put a backslash in front of them, like this:

git commit -m "CL/AT All tests passing \!"

Otherwise, the bash shell may get confused about the meaning of the ! symbol, and you’ll get this error:

[spis16t3@ieng6-240]:spis16-lab02-Alex-Chris:140$ git commit -m "CL/AT All tests passing!"
-bash: !": event not found
[spis16t3@ieng6-240]:spis16-lab02-Alex-Chris:141$

We can go into why that’s the case some other time (what is this “event” that is not found?)

For now, though it may be better to just avoid the ! symbol in your commit messages unless you remember the backslash.

All tests passing? Then you are done!

Congratulations!