This lab introduces the mechanics and practices of the CP164 labs. We assume that you have a basic grounding in using email and a web browser and working with Eclipse. If you need extra help for anything related to a lab, please talk to an IA or the Lab Instructor.
In order to work effectively in this course, you must have the following:
Part of the course work involves building a series of related programs over a number of labs and assignments. The work for one week builds on the work of previous weeks. This year's project involves writing a program to administer a food database.
A class is an object-oriented way of defining an ADT. Data and methods on the data are defined in the class. Classes provide modularity, encapsulation, information hiding, and an interface, fitting all the requirements of an ADT. We shall define classes for data (storage classes) and for data structures.
A minimum Python class definition requires only two parts:
initsurrounded by two pairs of underscores. (Underscores play an important role in Python variable in method naming, as we will see.)
class Name: def __init__(self[, param,]): ...
Import a class with the following syntax:
from module import class
In CP164 we generally make the module name match the class name. Thus
Student class is defined in a PyDev module named
The constructor, like all class methods (and Python functions in
general), starts with the keyword
def. All class methods
must have at least one parameter, the
self parameter. Other
parameters can be defined as required, and are generally used to
initialize class attributes. Class methods are indented within the
definition in order to show that they belong to the class.
The constructor is called not by using the name
but by using the name of the class. Thus you create a new object with
object = Name([argument,])
Note that even though
self is shown as the first parameter
to the constructor,
self is never actually used as an
argument. Only the rest of the constructor parameters require matching
Class attributes are generally defined within the class constructor. An
attribute is defined by putting the class keyword
front of it, as in the following example. The file
contains the definition of the
class Number def __init__(self, value): self.value = value return
and this definition can be imported into another Python module and used to define an object:
from Number import Number example = Number(0)
This attribute may now be used anywhere within the class, but must be
self. . Without
self , the named
value is treated as a simple variable instead. Note that in this example
the parameter name
value matches the attribute name.
However, Python can distinguish them because the attribute is always
preceded by the
In Python most class methods are declared and used the same way as standard Python functions with the following special requirements:
selfas the first (or only) parameter
The following example defines an method for the
def square(self): result = self.value * self.value return result
then calls it from the
answer = example.square()
Note that the method needs no further parameters because it is squaring
and returning the value of its
Object attributes can be accessed simply by using the syntax:
The Eclipse IDE helps here by providing a drop down list of all
available attributes (and methods) after typing
, just as it does with function libraries.
You may access or change an attribute with this syntax, as in the following examples:
print(example.value) example.value = 0 example.value = int(input("Enter a new value: ")) answer = example.value * 2
Note: There is one important exception to this. Attributes and
methods that begin with '
_ ' or '
__ ' (i.e.
either single or double underscores), should generally not be accessed
from outside the class definition. By convention they are considered to
be private attributes and methods accessible only by other
class methods. We will see and use such attributes and methods when we
begin working with data structures.
(Python does not have any way to make attributes and methods truly private or inaccessible from outside the class. This naming convention merely designates a status that you as a programmer should respect, in the same way that naming a constant with all capital letters does not make a Python variable truly constant, but does require you to treat it as a constant.
As we work through the term we will be creating a number of different
data structures and adding more functionality to the Food library
already written. Making sure that each new project has the latest
version of a data structure or Food library is difficult to do if we are
reduced to copying and pasting our PyDev modules into each new project.
Fortunately, Eclipse provides a much better mechanism to reference code.
Setting up Project References allows you to link one PyDev
project to another, and to use the code from one project in another with
from ... import *
statements already shown. Nothing needs to be changed in your source
To make a reference from one project to another in Eclipse, right click on a project name in the Navigator pane. From the resulting pop-up menu click on Properties and then on Project References in the resulting dialog box. You should now see the following dialog box:
Click on the check box of all projects that you wish to reference from
the current project. In this example the project album is
already selected, and the project data_structures will be added
as a reference. Once this is done all of the classes in both album
and data_structures will be available through
A few things to keep in mind when using project references:
All referenced projects must be open when attempting to run a program. Eclipse automatically opens any referenced projects when a top-level project is opened.
Submit all referenced projects as part of your Eclipse archive (.zip) file when submitting exercises or the markers will not be able to run your programs. You may select multiple projects to include in an Eclipse archive file.
Do not use the same PyDev module names in two different referenced
projects or Eclipse will not know which one an
statement is referring to.
lab02_stacksreferences the project
data_structuresshould not reference
lab02_stacks. Circular references are a very bad idea.
Upon occasion referenced projects may become 'out of sync' with the project that references them. To fix this, right-click on the project and choose Refresh to update Eclipse from the file system.
At the end of this lab, you should have the following project structure in your workspace:
(Of course, the projects should be using your login.)
The assignment validator assumes you will have a
project in your .zip file.
This term we will be writing programs and functions related to running a food database, working with information about food, its name, origin, etc.
For these tasks use the food class on the basis of the information given
class code and the
module. Import these modules into another file for testing. (You do not
have to complete all of the utility functions in the lab, but you should
eliminate any errors or warnings in the code.)
Food_utilities.py in your
project so that you have only one copy of each file, and so that
they can be referenced from other projects.
origins method for the
__str__ method for the
get_food function for the
Use the following input format:
Name: Origin 0 Canadian 1 Chinese 2 Indian … : Vegetarian (Y/N): Calories:
Test this function by printing out the resulting Food object.
read_food function for the
read_foods function for the
Test this function with the file foods.txt.
write_foods function for the
The resulting file should have the same format as the file
. In Eclipse, right click on the lab 1 project name and choose,
in order to see the new file in the project manage.
Test this function by writing the contents of the list from the previous task to a file named new_foods.txt.
get_vegetarian function for the
Test this function by selecting and printing all the vegetarian foods in the foods.txt file.