Sunday 6 January 2013

AWOL (Absent due to Work OverLoad)

Work has kept me away from blogging the Python Learning, but that isn't to say that I've not been picking up new skills.  Just that I've not documented them here, as I'd originally planned.

Coming soon:

  1. Application development scheme
  2. Class Notes
  3. PyQt4 GUI development

Saturday 14 July 2012

Testing Times

Testing testing

Quick round up: we've built a development environment, got version control working, set up some project management, but we still aren't ready to dive in.  No, we are missing the most vital component of our development tool chain.  Testing. Really good code is code that we know works.  Mostly, code written for the 'job in hand' is poor.  Top down imperative coding is wasteful, counter-productive, and generally very expensive.  OK so I'm generalizing, and viewing the world from a very narrow perspective.  There are plenty occasions when imperative is fine.  Here we define a problem and write lines of code that solve the problem.  The code executes from the top of the script, runs procedurally to the bottom, and finishes by spewing out some result.  Its a hard wired solution that rarely holds up to scrutiny.  We want to be writing test driven functional code (more formerly, test driven declarative code.  So where does testing fit in, and why the big deal anyway?

Imperative vs. declarative coding.  Its all about structure, and testing.

When you are learning to program what you want to be able to do is write code that performs a task, solves a problem and returns a result all in isolation from the rest of the program.  That way your elementary instruction won't topple your program if it fails.  It will also be easier to maintain and test, and will lend itself to code reuse.  To implement this style of code we need to declare functions that solve discrete components of our problem, in isolation.  Therefore central to declarative, or functional programming, is the skill of being able to reduce a larger problem to bite sized chunks. We need to be focussed on building self contained functions, rather than the ordering of task execution, which is the concept that drives imperative programs.  The really neat thing about a self contained function, is that it is suited to testing.  In fact, when we consider a problem that we are going to solve with a function, we should be asking ourselves how do we know if our function is returning the right answer.  Better still, lets write the rules to test our function, before (or at least at the same time) as we build the function.  That is, writing a function is dependent up on the test.  Successful testing guarantees workable functions,  not the other way around.  When we code using this paradigm, we are subscribing to the notion of Test Driven Development.

Its about time we wrote some code.  So next time we'll produce the Hello World program.  But rather than the classic one-line, we'll undertake a full development cycle, making it a bit more interesting!

Here's the tools list we will need:
  1. Project structure - we'll use redmine to specify our program. We'll set objectives, define a  time frame, and the issues
  2. Code repository - we'll use SVN to keep our code safe
  3. Python environment - we'll use a virtual environment to ring fence our code, and provide a sand pit.
  4. Unit testing - we'll use nose, a python test suit to provide the function testing
  5. A good sense of humour - not essential, but it might help.

Thursday 5 July 2012

Project management

Plan for the now.

When it comes to building an application its never a good idea to just go and write something.  More often than not success is usually routed in forward planning.  After all, how are you going to know you are heading in the right direction if you've not laid out goals, or tackle problems if you have no means to record them when they crop up.  They will crop up.  You'll most likely need some way of documenting what you are doing, and communicating ideas with collaborators.  All these things may be summed up in Project Management.  People generally view this as scary.  Too professional for me, or just plain old fun sucking.  Wrong, wrong & wrong.  Project Management is easy, rewarding and adds an extra dimension to your coding.  Lets review some terms. When we talk about heading in the right direction we are thinking in terms of a roadmap, those objectives along the way are milestones, and those problems are issues.  Issues are resolved by setting and completing tasks.

We should never start out by thinking of the end program.  Instead we should consider the problem, and build the project around it.  The solution may manifest as a program, but that's a consequence of the problem solving exercise.  You've got good project management skills if you are able to solve  a problem by breaking it down in to self contained (testable) chunks, recognizing when each chunk is resolved, guesstimating the length of time required to full fill each task, consolidating the jobs, and reacting to unforeseen problems along the way.

Numerous frameworks embody the project management philosophy, and when it comes to software development most are built around version control systems.  The most popular at present is Github, go on sign up and have a poke around.  On the other-hand you may not be up for facing the public with your trials and tribulations, so why not install a system locally, just to try it out?  That's what we are going to do now, with Redmine.

Getting ready for Redmine

We may experience limited joy in this endeavour.  A fully functional Redmine requires several medium to heavy-weight services to be up and running, its probably unrealistic to assume that our Pi will cope.   With this in mind, I strongly advise that you install Redmine on a regular PC, if on the other hand you like a fools errand, then head over to my Pi page to investigate the installation.

Wednesday 4 July 2012

Forgot to mention the Pi

Just in case you are reading this and wondering why I'm doing it all Linux like, its because of the Raspberry Pi.  Check out my Pi blog for some background.  Those of you who don't have any interest in the Pi, but still want to tinker with the code below should look to install a Linux Distro.  You can do it without breaking your Windows, just be aware that there are more flavours of Linux than there are varieties at Heinz.   The Pi I'm playing with runs Debian, so that's what I've used in the examples.  However, Fedora Core is nice, and Ubuntu is cool.  Note the package managers commands used for downloading and installing add-on software are very different between many Linux Distros.  Ubuntu and Debian use apt, whereas Suse uses RPM and Fedora / RedHat goes for RPM and yum.  Grab yourself a Linux Live DVD or install a virtual linux in Vbox, I won't say more about it here.

Tuesday 3 July 2012

Creating an environment

Getting started

By the end of today we will have all the tools we need to do just about any and everything we want.  I promise.

Step 1 - virtualenv We need to create the space for our work.  Its no more than a directory in your home, but you should treat it with some respect.  Use it only for housing your code, and don't litter it with random files.  I like to work at the top level of my home, so that's where I'm going to create PythonDev
cd
mkdir PythonDev
cd PythonDev
Now we need to install the tools that will set up our development environment for us. We will need:
  • pip - the python package installer
  • virtualenv - the scripts for building virtual environments
  • virtualenvwrapper - scripts that take the complexity out of working with virtual environments
You'll need admin rights for the next few steps

cd
sudo apt-get install python-pip
sudo pip install virtualenv virtualenvwrapper
That's it as far as getting the tools. We won't be needing admin rights for a while. Now we set up virtualenv. First we need to give it the location of our working directory, as this is where it will store relevant files. It gets the location out of our .bash_profile file. You may not have one, either way use nano to create it, or edit it if you have got one to hand. In the following code snippet, replace PythonDev with the full path to your preferred working directory.
You may need to edit the path to virtualenwrapper.sh script. If its not in /usr/local/bin, try /usr/bin
nano ~/.bash_profile

export WORKON_HOME="$HOME/PythonDev"
source /usr/local/bin/virtualenvwrapper.sh
Activate your wrapper script by sourcing your .bash_profile
source ~/.bash_profile
If all is going well you'll get some messages appearing about setting your virtualenv working space. Now go wild. Create a virtual environment. I'm going to call my pydev.
mkvirtualenv pydev
Some more crazy messages follow, then hey presto, your new virtualenv is ready. You'll know this because your prompt will have changed. Note the virtualenv name in parentheses before your regular prompt.
(pydev)ian@raspberrypi:~$ 
So now what can we do. We'll we've got a bunch of new commands to learn:

  1. workon <name of virtual environment e.g. pydev> # activates virtualenv
  2. deactivate # turns of virtualenv
  3. cdvirtualenv # change to virtualenv working directory
  4. mkvirtualenv <name> # create a new virtualenv of <name>
  5. rmvirtualenv <name> # delete virtualenv <name>
  6. lsvirtualenv # get a listing of virtualenvs
These half dozen commands cover the mainstay of operations, but as you may imagine there are a whole host more.

With our pydev env up and running, lets install an improved python interpretor ipython. This interpretor boasts a whole host of useful features not present in the system default python.  In ipython we can access shell commands from within the interpretor, as well as use readline to gain command history features etc.

pip install ipython

Note we don't need sudo anymore because we are working in our virtualenv

Step 2 - Version control

Right one more  setup task for the day, and then its bedtime for me.
Lets install and configure a source version control system. What the ... why?
If we are going to write code, then we need to protect it from accidental damage.  What better way to track our progress, secure our work and generally be truly professional about our business than  checking it in.  What's more, we can impress our friends when we pass them the URLs to check out our work.

We will use Subversion. Its a lot easier than you may image.

Back to admin.
sudo apt-get install subversion


Now we need a place to set up our repository - the fancy name for the home that will store our files.  I suggest sticking SVN_Repo at the root of your home directory.
cd
svnadmin create SVN_Repo

We will set up ourselves as a user. We specify this in a config file.  Use nano to enter the following text in ~/SVN_Repo/svnserve.conf
anon-access = none
nano ~/SVN_Repo/svnserve.conf
auth-access = write
password-db = passwd

Our user needs a password to be associated with it.  Enter the authorization details in ~/SVN_Repo/conf/passwd.  Its simply a file of user = password
nano ~/SVN_Repo/conf/passwd
ian = mypassword
So how do we know this is all working then? Lets create a pyhthon project to test it out. The steps will be:
  1. workon pydev - activate our virtual environment
  2. cdvirtualenv and create the source directory
  3. make project subdirectory, move in and write script
  4. import the project in to our subversion repository
  5. blow the original project directory away
  6. checkout our project from the repo
  7. experiment with making and reverting changes
  8. go to bed with a sense of satisfaction

Testing out virtual env and subversion

I'm going to assume you called directories the same names as me, otherwise you'll need to change the recipe accordingly.

workon pydev
cdvirtualenv
mkdir src
cd src
mkdir my_test_project
cd my_test_project
nano hello_world.py
 
Type the follwoing hello_world.py listing in nano.

"""
Testing virtualenv and subversion
Hello World
"""
msg = 'Hello World'
for x in range(5):
    print msg

# end
 
  1. Test your script by running it in ipython (you can execute it directly or import it into the interpreter
ipython hello_world.py
or

ipython
import hello_world
exit
Both should yield satisfactory results (note when you import the file you miss off the .py). So lets check that bad boy in. In the following recipe we need to give the full path to our SVN_Repo, clearly substitute my username for your own!
cd .. # move back to src directory
ls # ensure you can see the directory containing our project - my_test_project
svn import file:///home/ian/SVN_Repo/my_project
Subversion asks for a message. Tradition has it that this message is always 'First commit', although you can call yours whatever you like. It may even fire up an editor that lets you type one in. Either way ensure you get a message across.
rm -rf my_test_project # Bye - bye unversioned inferior directory
svn co file:///home/ian/SVN_Repo/my_project # welcome back new and improved working directory now under version control
cd my_test_project # move inside project directory
svn status -v # get status pf files under version control
That's it as far as setting up version control. Clearly there is much to learn about how you work with files that are being tracked for changes. In fact you'll need to master a whole bunch of new command.
  1. svn add <name> # put a new file under version control
  2. svn rm <name>  # delete a versioned file
  3. svn commit -m 'message to log in commit'
  4. svn up # Update the working copy with changes that have been commited
  5. svn status # get status of versioned files.
  6. svn revert #recover drop uncommited changes and revert to head
  7. svn co # check out a new working copy
  8. svn diff <name># find out what changes exist between your file and the repo's version of the file
  9. svn log # get a print out of the log entries accompanying commits
  10. svn blame
  11. svn merge -r downgrade / upgrade working copy revision x to / from y#
The general strategy goes like this.
  1. Create a new file in your favourite text editor.  Enter some text etc.
  2. Add (some people call it staging) the file to version control.  Note this doesn't physically commit the changes 
  3. Commit the file together with some message describing your edits
Now when you make subsequent changes to these files, you'll need to commit any edits.  Its important to remember not to simply rm a file under version control, you need to tell subversion that you no longer want the file to be tracked. Do that with svn rm.

Testing out. 

Move back into our project and edit the file in nano.  Lets change the msg variable to something else.

"""
Testing virtualenv and subversion
Hello World
"""
msg = 'Goodbye World'
for x in range(5):
    print msg

# end
Ok so its not a radical edit, but it is a change. We can know that the file is modified from that which is in the repo (known as the head copy) with svn status
svn  status
M     hello_world.py
We can also review the changes using svn diff. This literally creates a diff file that would patch the head, making it the same as the working copy.
svn diff hello.py 
Index: hello.py
===================================================================
--- hello.py (revision 6)
+++ hello.py (working copy)
@@ -2,7 +2,7 @@
 Testing virtualenv and subversion
 """
 
-msg = "Hello World!"
+msg = "Goodby World!"
 
 for f in range(5):
  print msg

The values between @@s give us the code for where the changes are. It says delete (-) offset two lines below @@ (at line 7 in file this is Hello) and replace (+) with Goodby. Effectively swap the print msg statements. So we commit the change
 svn commit -m 'Edited message'
Hit enter and realise we've made a terrible mistake. Don't Panic. The file is under version control. We can check the logs to find out what revision we need to recover, then pull it back. Before we can do the reverting we need to update our local cache (working copy) with any changes that we (and anyone else) working on the project may have checked in, we use svn up for this purpose.
svn up 
Now we can check the logs and find out what version number we need to revert to.
------------------------------------------------------------------------
r2 | ian | 2012-07-02 23:40:46 +0100 (Mon, 02 Jul 2012) | 1 line

Edited message
------------------------------------------------------------------------
r1 | ian | 2012-07-02 23:36:35 +0100 (Mon, 02 Jul 2012) | 2 lines

First commit

------------------------------------------------------------------------
Well we've only made one commit above first commit, so lets go back to r1.
svn merge -r 2:1 hello_world.py
You can now commit downgraded hello_world, and it will take the next revision number in the change r3 in this case. The important thing to understand is that the diffs that made up the journey are still in the repo, and its possible to walk backwards and forwards through them. That's the beauty of version control Next time I want to skirt through Project Management.

Monday 2 July 2012

Starting Out

Learning Python

Started learning python about a year ago.  Feels apt that I should report the process, more for my own documentation, but also to share the experience, and pass on gems that other's shared with me.

Development environments aren't just for Gurus

If you are going to learn a language and program anything more then Hello World you need a place to store your code.  A place that is bomb proof, and a place where you keep all your tools.  When we are talking about coding this safe place is called a Development Environment.  It may sound over priced, but its well worth investing the time in creating one.  Think of it as part of the learning journey.

What do I get for my money?
  • Protection from destroying the System's own Python Installation
  • A space to code without the need for SysAdmin Rights.
  • Unlimited experimentation.  If you don't like what you've done, blow it away and start again
  • All the tools in one place.  Things just work better.
I'm sold.  So tell me what I need
  • Version control
  • Python virtual environment
  • A darn good text editor, one that knows how to code.
  • Project Management
  • Time to learn, time to play.
Tomorrow I'll walk through the process of building a bullet proof virtual environment, and break the ground with version control.  Look out GitHub, here we come!