Difference between revisions of "CSC111 Homework 9 2015"
(18 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
<showafterdate after="20150402 16:00" before="20150601 00:00"> | <showafterdate after="20150402 16:00" before="20150601 00:00"> | ||
<bluebox> | <bluebox> | ||
− | This assignment is due the evening of Tuesday 4/7/15, at 11:55 p.m. | + | This assignment is due the evening of Tuesday 4/7/15, at 11:55 p.m. You will be able to evaluate Problem 1, but not Problem 2. |
</bluebox> | </bluebox> | ||
<br /> | <br /> | ||
Line 22: | Line 22: | ||
<br /> | <br /> | ||
<source lang="python"> | <source lang="python"> | ||
+ | # hw9_1.py | ||
+ | # your name goes here | ||
+ | # and a description of the program | ||
+ | |||
+ | |||
# | # | ||
# missing class goes here... | # missing class goes here... | ||
# | # | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
def display( catList, caption ): | def display( catList, caption ): | ||
Line 51: | Line 44: | ||
# Garfield, 4, Yes, Yes, Orange Tabby""" | # Garfield, 4, Yes, Yes, Orange Tabby""" | ||
− | file = open( " | + | file = open( "cats1.csv", "r" ) |
text = file.read() | text = file.read() | ||
file.close() | file.close() | ||
Line 84: | Line 77: | ||
display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) | display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) | ||
− | + | if __name__=="__main__": | |
− | main() | + | main() |
+ | |||
</source> | </source> | ||
<br /> | <br /> | ||
− | ==Example | + | ==Example cats1.csv File == |
+ | <br /> | ||
+ | Here is an example of the format of the csv file. | ||
<br /> | <br /> | ||
::<source lang="text"> | ::<source lang="text"> | ||
Line 102: | Line 98: | ||
List of cats: | List of cats: | ||
============= | ============= | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Cat: Minou, age: 3, vaccinated, neutered (stray) | Cat: Minou, age: 3, vaccinated, neutered (stray) | ||
Cat: Max, age: 1, vaccinated, not neutered (Burmese) | Cat: Max, age: 1, vaccinated, not neutered (Burmese) | ||
Line 122: | Line 111: | ||
<br /> | <br /> | ||
;Question | ;Question | ||
− | Recreate the original program with its Cat class. Make sure that | + | Recreate the original program with its Cat class. <font color="red">You cannot modify the main program!</font>. Make sure that your program with the reconstituted class generates the same output as the one shown above, when fed the same CSV file. |
− | Document your code well, including the ''main()'', | + | Document your code well, including the ''main()'', and ''display()'' functions. Document the class using the same approach as in Part 2, below. |
<br > | <br > | ||
Store your program in a file called '''hw9_1.py''' and submit it to the Moodle HW9 PB1 section. | Store your program in a file called '''hw9_1.py''' and submit it to the Moodle HW9 PB1 section. | ||
+ | <br /> | ||
+ | ==Testing== | ||
+ | <br /> | ||
+ | Your program will be tested using your '''Cat''' class, and the '''main()''' function shown in the code above. Whatever modification you bring to '''your''' main function will not be used. For this reason, make sure ''you do not modify the code of the main() function that is given to you.'' | ||
<br /> | <br /> | ||
<!-- | <!-- | ||
Line 175: | Line 168: | ||
(image from [http://naturesmightypictures.blogspot.com/2006/10/people-and-dogs.html naturesmightypictures.blogspot.com]) | (image from [http://naturesmightypictures.blogspot.com/2006/10/people-and-dogs.html naturesmightypictures.blogspot.com]) | ||
<br /> | <br /> | ||
+ | ==Preparation== | ||
+ | <br /> | ||
+ | For this assignment, you need to create a CSV file containing some information about people and dogs. Create a csv file called '''peopledog.csv''' in the same folder where you keep your python programs, and save the following lines in it: | ||
+ | <br /> | ||
+ | ::<source lang="text"> | ||
+ | Joe, 23, Fido, vaccinated | ||
+ | Debra, 30, Rex, not vaccinated | ||
+ | Frida, 10, Ralph, vaccinated | ||
+ | Maria, 21, Gizmo, vaccinated | ||
+ | Frank, 31, , | ||
+ | Millie, 25, Maxi, not vaccinated | ||
+ | </source> | ||
+ | <br /> | ||
+ | * The information above contains the name and age of people, and the name of their dog, as well as its vaccinated status, if they own a dog. If they do not own a dog, then their age is followed by two empty strings (see Frank above). | ||
+ | <br /> | ||
+ | ==The Main Program== | ||
<br /> | <br /> | ||
Create a new program with the code below. Call it '''hw9_2.py'''. | Create a new program with the code below. Call it '''hw9_2.py'''. | ||
<br /> | <br /> | ||
− | <source lang="python"> | + | ::<source lang="python"> |
# hw9_2start.py | # hw9_2start.py | ||
− | # | + | # your name here |
# This program maintains 2 classes, one for a person | # This program maintains 2 classes, one for a person | ||
# and the other for a dog. | # and the other for a dog. | ||
Line 311: | Line 320: | ||
</source> | </source> | ||
<br /> | <br /> | ||
+ | * Run the program. Verify that it outputs a list of people and dogs, nicely formatted. | ||
+ | <br /> | ||
+ | |||
==Your Assignment== | ==Your Assignment== | ||
<br /> | <br /> | ||
− | * | + | * Modify the main program only (not the classes), so that your new program will output: |
*# the list of people who have unvaccinated dogs | *# the list of people who have unvaccinated dogs | ||
*# the list of people without dogs | *# the list of people without dogs | ||
Line 319: | Line 331: | ||
<br /> | <br /> | ||
− | + | * Your output should match '''exactly''' the output of the solution program, so play close attention to the formatting of your output. | |
+ | * The output of the solution program for three different csv files are shown in the section below. | ||
+ | <br /> | ||
+ | Store your program in a file called ''' hw9_2.py''' and submit it to Moodle, in the HW9 PB2 section. | ||
+ | <br /> | ||
+ | <br /> | ||
+ | ==Example Outputs for Different CSV Files (added 4/4/15)== | ||
<br /> | <br /> | ||
− | <source lang="text"> | + | ::<source lang="text"> |
− | Joe, 23 years old has a dog: | + | ------------ Example 1 ------------------ |
− | Debra, 30 years old has a dog: | + | peopledog.csv file |
− | Frida, 10 years old has a dog: | + | Joe, 23, Fido, vaccinated |
− | Maria, 21 years old has a dog: | + | Debra, 30, Rex, vaccinated |
− | Frank, 31 years old does not have a dog | + | Frida, 10, Ralph, vaccinated |
− | Millie, 25 years old has a dog: | + | Maria, 21, Gizmo, not vaccinated |
+ | Frank, 31, , | ||
+ | Millie, 25, Maxi, vaccinated | ||
+ | |||
+ | Output of the Solution Program | ||
+ | |||
+ | Joe, 23 years old, has a dog: Fido (vaccinated) | ||
+ | Debra, 30 years old, has a dog: Rex (vaccinated) | ||
+ | Frida, 10 years old, has a dog: Ralph (vaccinated) | ||
+ | Maria, 21 years old, has a dog: Gizmo (not vaccinated) | ||
+ | Frank, 31 years old, does not have a dog | ||
+ | Millie, 25 years old, has a dog: Maxi (vaccinated) | ||
+ | |||
+ | Maria, 21 years old, has a dog: Gizmo (not vaccinated) | ||
+ | |||
+ | Frank, 31 years old, does not have a dog | ||
+ | |||
+ | Debra, 30 years old, is the oldest person owning a dog. | ||
+ | |||
+ | ------------ Example 2 ------------------ | ||
+ | peopledog.csv file | ||
+ | Joe, 23, Fido, vaccinated | ||
+ | Debra, 30, Rex, not vaccinated | ||
+ | Frida, 10, Ralph, vaccinated | ||
+ | Maria, 21, Gizmo, vaccinated | ||
+ | Millie, 25, Maxi, not vaccinated | ||
+ | |||
+ | Output of the Solution Program | ||
+ | |||
+ | Joe, 23 years old, has a dog: Fido (vaccinated) | ||
+ | Debra, 30 years old, has a dog: Rex (not vaccinated) | ||
+ | Frida, 10 years old, has a dog: Ralph (vaccinated) | ||
+ | Maria, 21 years old, has a dog: Gizmo (vaccinated) | ||
+ | Millie, 25 years old, has a dog: Maxi (not vaccinated) | ||
+ | |||
+ | Debra, 30 years old, has a dog: Rex (not vaccinated) | ||
+ | Millie, 25 years old, has a dog: Maxi (not vaccinated) | ||
+ | |||
+ | |||
+ | Debra, 30 years old, is the oldest person owning a dog. | ||
+ | |||
+ | ------------ Example 3 ------------------ | ||
+ | peopledog.csv file | ||
+ | Joe, 23, , | ||
+ | Debra, 30, , | ||
+ | Frida, 10, , | ||
+ | Maria, 21, , | ||
+ | Frank, 31, , | ||
+ | Millie, 25, , | ||
+ | |||
+ | |||
+ | Output of the Solution Program | ||
+ | |||
+ | Joe, 23 years old, does not have a dog | ||
+ | Debra, 30 years old, does not have a dog | ||
+ | Frida, 10 years old, does not have a dog | ||
+ | Maria, 21 years old, does not have a dog | ||
+ | Frank, 31 years old, does not have a dog | ||
+ | Millie, 25 years old, does not have a dog | ||
+ | |||
+ | |||
+ | Joe, 23 years old, does not have a dog | ||
+ | Debra, 30 years old, does not have a dog | ||
+ | Frida, 10 years old, does not have a dog | ||
+ | Maria, 21 years old, does not have a dog | ||
+ | Frank, 31 years old, does not have a dog | ||
+ | Millie, 25 years old, does not have a dog | ||
− | + | Nobody in the list has dogs. | |
− | |||
− | |||
− | |||
</source> | </source> | ||
<br /> | <br /> | ||
− | + | ||
+ | |||
+ | </showafterdate> | ||
+ | <!-- =================================================================== --> | ||
+ | <!-- =================================================================== --> | ||
+ | <!-- =================================================================== --> | ||
+ | <!-- =================================================================== --> | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
+ | <showafterdate after="20150408 00:00" before="20150601 00:00"> | ||
+ | =Solution Programs= | ||
<br /> | <br /> | ||
+ | ==Part 1== | ||
<br /> | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # hw9_1sol.py | ||
+ | # Originally by Joyce Xue ( aa ) | ||
+ | # (slightly edited by D. Thiebaut) | ||
+ | # 04.15.2014 | ||
+ | # | ||
+ | # This program contains a class Cat that describe a cat with its name, age, | ||
+ | # being vaccinated or not, being neutered or not and breed | ||
+ | # | ||
+ | # To create an object of this type, simply use the constructor, as follows: | ||
+ | # | ||
+ | # cat = Cat(name, age, vaccinated, neutered, breed) | ||
+ | # | ||
+ | # The methods supported are: | ||
+ | # | ||
+ | # isVaccinated(): returns if the cat is vaccinated | ||
+ | # | ||
+ | # isNeutered(): returns the name of the planet with the largest diameter | ||
+ | # | ||
+ | # __str__(): convert the object to a string | ||
+ | # ------------------------------------------------------------------------------------------------------ | ||
+ | class Cat: | ||
+ | # contructor. Initialize all memebers. | ||
+ | def __init__( self,name, age, vaccinated, neutered, breed): | ||
+ | self._name=name | ||
+ | self._age=age | ||
+ | self._vac=vaccinated | ||
+ | self._neu=neutered | ||
+ | self._breed=breed | ||
+ | |||
+ | #================================================================== | ||
+ | # __str__() : When call print(cat), this function | ||
+ | # automatically converts the cat to a string | ||
+ | #================================================================== | ||
+ | def __str__(self): | ||
+ | # make up the return string by following the required format | ||
+ | temp = "Cat: "+self._name+","+" age: "+str(self._age)+", " | ||
+ | |||
+ | # convert boolean value to string | ||
+ | if self._vac: temp=temp+"vaccinated, " | ||
+ | else: temp=temp+"not vaccinated, " | ||
+ | |||
+ | if self._neu: temp=temp+"neutered " | ||
+ | else: temp=temp+"not neutered " | ||
+ | |||
+ | temp=temp+"("+self._breed+")" | ||
+ | |||
+ | return temp | ||
+ | |||
+ | #================================================================== | ||
+ | # isVaccinated(): return if the cat is vaccinated | ||
+ | #================================================================== | ||
+ | def isVaccinated(self): | ||
+ | return self._vac | ||
+ | |||
+ | #================================================================== | ||
+ | # isNeutered(): return if the cat is neutered | ||
+ | #================================================================== | ||
+ | def isNeutered(self): | ||
+ | return self._neu | ||
+ | |||
+ | |||
+ | #================================================================== | ||
+ | # getNewCat(): ask for user input to create a new | ||
+ | # cat and return it | ||
+ | #================================================================== | ||
+ | def getNewCat(): | ||
+ | # user input for name, age, if vaccinated, if neutered and breed | ||
+ | print( "\nPlease enter the information for the new cat:") | ||
+ | name = input( "Cat name? " ) | ||
+ | age = int( input( "Age, in years? " ) ) | ||
+ | vac = input( "Vaccinated (Y/N)? " ).strip().lower() | ||
+ | vac = vac in ['y', 'yes'] | ||
+ | neut = input( "Neutered (Y/N)? " ).strip().lower() | ||
+ | neut = neut in ['y', 'yes' ] | ||
+ | breed= input( "Breed? " ).strip() | ||
+ | |||
+ | return Cat( name, age, vac, neut, breed ) | ||
+ | #================================================================== | ||
+ | # display(): print each cat in a Cat collection | ||
+ | # L - a list of cats | ||
+ | # caption - the subject of the list to be printed | ||
+ | #================================================================== | ||
+ | def display( L, caption ): | ||
+ | # print the subject | ||
+ | print( "\n\n"+caption ) | ||
+ | print( "=" * len( caption ) ) | ||
+ | # go over the list and print each cat's info | ||
+ | for cat in L: | ||
+ | print( cat ) | ||
+ | |||
+ | #================================================================== | ||
+ | # main(): | ||
+ | # * creates a list of cat objects, displays it. | ||
+ | # | ||
+ | #================================================================== | ||
+ | def main(): | ||
+ | # get the contents of cats.csv | ||
+ | file = open( "cats2.csv", "r" ) | ||
+ | text = file.read() | ||
+ | file.close() | ||
+ | |||
+ | # use the text as the initial data, generate cats | ||
+ | for line in text.split( "\n" ): | ||
+ | # split each line into items | ||
+ | words = line.strip().split( "," ) | ||
+ | # if data is not exactly 5, skip | ||
+ | if len( words ) != 5: | ||
+ | continue | ||
+ | |||
+ | # set items to variables | ||
+ | name, age, vaccinated, neutered, breed = words | ||
+ | # convert age to int | ||
+ | age = int( age.strip() ) | ||
+ | # convert user inputs to booleans | ||
+ | if vaccinated.strip().lower() == "yes": | ||
+ | vaccinated = True | ||
+ | else: | ||
+ | vaccinated = False | ||
+ | |||
+ | neutered = neutered.strip().lower() == "yes" | ||
+ | |||
+ | # construct a cat | ||
+ | cat = Cat( name.strip(), age, vaccinated, neutered, breed.strip() ) | ||
+ | |||
+ | try: | ||
+ | # add the cat to the list | ||
+ | cats.append( cat ) | ||
+ | except NameError: | ||
+ | # if the cats list is not initialized, initialize it and append the first cat | ||
+ | cats = [] | ||
+ | cats.append( cat ) | ||
+ | |||
+ | # output the cat list | ||
+ | display( cats, "List of cats:" ) | ||
+ | |||
+ | |||
+ | # Go through each cat and add those who is both vaccinated and neutered into a list | ||
+ | vaccinatedNeuteredCats = [] | ||
+ | for cat in cats: | ||
+ | if cat.isVaccinated() and cat.isNeutered(): | ||
+ | vaccinatedNeuteredCats.append( cat ) | ||
+ | |||
+ | # output the cats in this new list (both vaccinated and neutered) | ||
+ | display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) | ||
+ | |||
+ | |||
+ | # Main entry point for the program | ||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==Part 2== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # hw9_2start.py | ||
+ | # your name here | ||
+ | # This program maintains 2 classes, one for a person | ||
+ | # and the other for a dog. | ||
+ | # A person object is defined by a name, an age, and a dog. | ||
+ | # If a person does not own a dog, then that person's dog field is set to None. | ||
+ | # A dog is defined by a tag (its name) and a boolean indicating if it is | ||
+ | # vaccinated or not. | ||
+ | # The main program outputs various lists of people. | ||
+ | # | ||
+ | |||
+ | class Person: | ||
+ | # a class containing 4 private member variables: | ||
+ | # - name of the person (string) | ||
+ | # - age (integer) | ||
+ | # - gpa (float) | ||
+ | # - major (string, uppercase) | ||
+ | # methods: | ||
+ | # getName(): returns the name of the person (string) | ||
+ | # getAge(): returns the age of the person (int) | ||
+ | # setAge(x): sets the age of the person to x (int) | ||
+ | |||
+ | # constructor: intializes a person with all fields | ||
+ | def __init__(self, n, a, dg ): | ||
+ | self.name = n | ||
+ | self.age = a | ||
+ | self.dog = dg | ||
+ | |||
+ | def getDog( self ): | ||
+ | return self.dog | ||
+ | |||
+ | # returns a string with the name and age. | ||
+ | def __str__( self ): | ||
+ | return "{0:1}, {1:1} years old".format( self.name, self.age ) | ||
+ | |||
+ | # returns the name | ||
+ | def getName( self ): | ||
+ | return self.name | ||
+ | |||
+ | # set the age to a new value x | ||
+ | def setAge( self, x ): | ||
+ | self.age = x | ||
+ | |||
+ | # returns the age of the person | ||
+ | def getAge( self ): | ||
+ | return self.age | ||
+ | |||
+ | |||
+ | class Dog: | ||
+ | # a class containing 2 private member variables: | ||
+ | # - name-tag of the dog (string) | ||
+ | # - whether the dog is vaccinated or not (boolean) | ||
+ | # methods: | ||
+ | # isVaccinated(): returns True if the dog is vaccinated, False otherwise | ||
+ | # getName(): returns the name-tag of the dog | ||
+ | # setName(x): sets the name-tag of the dog | ||
+ | # constructor | ||
+ | def __init__( self, tag, vaccinated ): | ||
+ | self.tag = tag | ||
+ | self.vaccinated = vaccinated | ||
+ | |||
+ | # default string representation for the dog | ||
+ | def __str__( self ): | ||
+ | if self.vaccinated==True: | ||
+ | return "{0:1} (vaccinated)".format( self.tag ) | ||
+ | return "{0:1} (not vaccinated)".format( self.tag ) | ||
+ | |||
+ | # isVaccinated: returns True if the dog is vaccinated, False otherwise | ||
+ | def isVaccinated( self ): | ||
+ | return self.vaccinated | ||
+ | |||
+ | # returns the name of the dog | ||
+ | def getNameTag( self ): | ||
+ | return self.tag | ||
+ | |||
+ | # changes the name-tag | ||
+ | def setNameTag( self, tag ): | ||
+ | self.tag = tag | ||
+ | |||
+ | # readCSVFile. Reads the contents of a CSV file and return | ||
+ | # a list of strings containing all the lines. | ||
+ | def readCSVFile( fileName ): | ||
+ | file = open( fileName, "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | return lines | ||
+ | |||
+ | |||
+ | # ================================================ | ||
+ | # main | ||
+ | # ================================================ | ||
+ | def main(): | ||
+ | # get the contents of the file | ||
+ | lines = readCSVFile( "peopledog.csv" ) | ||
+ | |||
+ | # create a list of people, and their dog (if they own one) | ||
+ | people = [] | ||
+ | |||
+ | # parse the text and add it as people-dog pairs in the list | ||
+ | for line in lines: | ||
+ | |||
+ | # reject lines that are not formatted correctly | ||
+ | if len( line.split(',') ) != 4: | ||
+ | continue | ||
+ | |||
+ | # parse line | ||
+ | name, age, tag, vacc = line.split(',') | ||
+ | name = name.strip() | ||
+ | age = int( age.strip() ) | ||
+ | tag = tag.strip() | ||
+ | vacc = "not" not in vacc.lower() | ||
+ | |||
+ | if len( tag )==0: | ||
+ | p = Person(name, age, None ) | ||
+ | else: | ||
+ | p = Person(name, age, Dog( tag, vacc ) ) | ||
+ | |||
+ | # add this new person to the list | ||
+ | people.append( p ) | ||
+ | |||
+ | # Display the list | ||
+ | for person in people: | ||
+ | |||
+ | if person.getDog() != None: | ||
+ | print( person, ", has a dog: ", person.getDog(), sep="" ) | ||
+ | else: | ||
+ | print( person, ", does not have a dog", sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # Display the list of people with unvaccinated dogs | ||
+ | for person in people: | ||
+ | if person.getDog() != None and person.getDog().isVaccinated()==False: | ||
+ | print( person, ", has a dog: ", person.getDog(), sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # Display the list of people without dogs | ||
+ | for person in people: | ||
+ | if person.getDog() == None: | ||
+ | print( person, ", does not have a dog", sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # display the oldest person who has a dog | ||
+ | oldest = None | ||
+ | oldestAge = 0 | ||
+ | for person in people: | ||
+ | if person.getAge() > oldestAge: | ||
+ | oldestAge = person.getAge() | ||
+ | oldest = person | ||
+ | |||
+ | if oldest.getDog()==None: | ||
+ | print( "Nobody in the list has dogs." ) | ||
+ | else: | ||
+ | print( oldest, ", is the oldest person owning a dog." ) | ||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
</showafterdate> | </showafterdate> | ||
+ | <br /> | ||
<!-- =================================================================== --> | <!-- =================================================================== --> | ||
<!-- =================================================================== --> | <!-- =================================================================== --> | ||
Line 350: | Line 756: | ||
<!-- =================================================================== --> | <!-- =================================================================== --> | ||
<br /> | <br /> | ||
+ | <onlydft> | ||
+ | =VPL Part 1 = | ||
+ | |||
+ | ==vpl_run.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | #! /bin/bash | ||
+ | |||
+ | cat > vpl_execution <<EOF | ||
+ | #! /bin/bash | ||
+ | |||
+ | # --- Python ---- | ||
+ | if [[ `hostname -s` = "beowulf2" ]]; then | ||
+ | python=/usr/bin/python3.3 | ||
+ | else | ||
+ | python=/usr/local/bin/python3.4 | ||
+ | fi | ||
+ | |||
+ | prog=hw9_1.py | ||
+ | |||
+ | \$python createCatCSV.py | ||
+ | |||
+ | echo "CSV file:" | ||
+ | cat cats1.csv | ||
+ | |||
+ | echo "" | ||
+ | echo "Your program output" | ||
+ | \$python \$prog | ||
+ | |||
+ | EOF | ||
+ | |||
+ | chmod +x vpl_execution | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_debug.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_evaluate.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | |||
+ | #! /bin/bash | ||
+ | |||
+ | cat > vpl_execution <<EOF | ||
+ | #! /bin/bash | ||
+ | |||
+ | # --- Python ---- | ||
+ | if [[ `hostname -s` = "beowulf2" ]]; then | ||
+ | python=/usr/bin/python3.3 | ||
+ | else | ||
+ | python=/usr/local/bin/python3.4 | ||
+ | fi | ||
+ | |||
+ | |||
+ | |||
+ | \$python evaluate.py | ||
+ | |||
+ | EOF | ||
+ | |||
+ | chmod +x vpl_execution | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_evaluate.cases== | ||
+ | <br /> | ||
+ | <source lang="text"> | ||
+ | </source> | ||
<br /> | <br /> | ||
+ | ==hw9_1sol.py== | ||
<br /> | <br /> | ||
+ | <source lang="python"> | ||
+ | # hw9_1sol.py | ||
+ | # Originally by Joyce Xue ( aa ) | ||
+ | # (slightly edited by D. Thiebaut) | ||
+ | # 04.15.2014 | ||
+ | # | ||
+ | # This program contains a class Cat that describe a cat with its name, age, | ||
+ | # being vaccinated or not, being neutered or not and breed | ||
+ | # | ||
+ | # To create an object of this type, simply use the constructor, as follows: | ||
+ | # | ||
+ | # cat = Cat(name, age, vaccinated, neutered, breed) | ||
+ | # | ||
+ | # The methods supported are: | ||
+ | # | ||
+ | # isVaccinated(): returns if the cat is vaccinated | ||
+ | # | ||
+ | # isNeutered(): returns the name of the planet with the largest diameter | ||
+ | # | ||
+ | # __str__(): convert the object to a string | ||
+ | # ------------------------------------------------------------------------------------------------------ | ||
+ | class Cat: | ||
+ | # contructor. Initialize all memebers. | ||
+ | def __init__( self,name, age, vaccinated, neutered, breed): | ||
+ | self._name=name | ||
+ | self._age=age | ||
+ | self._vac=vaccinated | ||
+ | self._neu=neutered | ||
+ | self._breed=breed | ||
+ | |||
+ | #================================================================== | ||
+ | # __str__() : When call print(cat), this function | ||
+ | # automatically converts the cat to a string | ||
+ | #================================================================== | ||
+ | def __str__(self): | ||
+ | # make up the return string by following the required format | ||
+ | temp = "Cat: "+self._name+","+" age: "+str(self._age)+", " | ||
+ | |||
+ | # convert boolean value to string | ||
+ | if self._vac: temp=temp+"vaccinated, " | ||
+ | else: temp=temp+"not vaccinated, " | ||
+ | |||
+ | if self._neu: temp=temp+"neutered " | ||
+ | else: temp=temp+"not neutered " | ||
+ | |||
+ | temp=temp+"("+self._breed+")" | ||
+ | |||
+ | return temp | ||
+ | |||
+ | #================================================================== | ||
+ | # isVaccinated(): return if the cat is vaccinated | ||
+ | #================================================================== | ||
+ | def isVaccinated(self): | ||
+ | return self._vac | ||
+ | |||
+ | #================================================================== | ||
+ | # isNeutered(): return if the cat is neutered | ||
+ | #================================================================== | ||
+ | def isNeutered(self): | ||
+ | return self._neu | ||
+ | |||
+ | |||
+ | #================================================================== | ||
+ | # getNewCat(): ask for user input to create a new | ||
+ | # cat and return it | ||
+ | #================================================================== | ||
+ | def getNewCat(): | ||
+ | # user input for name, age, if vaccinated, if neutered and breed | ||
+ | print( "\nPlease enter the information for the new cat:") | ||
+ | name = input( "Cat name? " ) | ||
+ | age = int( input( "Age, in years? " ) ) | ||
+ | vac = input( "Vaccinated (Y/N)? " ).strip().lower() | ||
+ | vac = vac in ['y', 'yes'] | ||
+ | neut = input( "Neutered (Y/N)? " ).strip().lower() | ||
+ | neut = neut in ['y', 'yes' ] | ||
+ | breed= input( "Breed? " ).strip() | ||
+ | |||
+ | return Cat( name, age, vac, neut, breed ) | ||
+ | |||
+ | #================================================================== | ||
+ | # display(): print each cat in a Cat collection | ||
+ | # L - a list of cats | ||
+ | # caption - the subject of the list to be printed | ||
+ | #================================================================== | ||
+ | def display( L, caption ): | ||
+ | # print the subject | ||
+ | print( "\n\n"+caption ) | ||
+ | print( "=" * len( caption ) ) | ||
+ | # go over the list and print each cat's info | ||
+ | for cat in L: | ||
+ | print( cat ) | ||
+ | |||
+ | #================================================================== | ||
+ | # main(): | ||
+ | # * creates a list of cat objects, displays it. | ||
+ | # | ||
+ | #================================================================== | ||
+ | def main(): | ||
+ | # get the contents of cats.csv | ||
+ | file = open( "cats1.csv", "r" ) | ||
+ | text = file.read() | ||
+ | file.close() | ||
+ | |||
+ | # use the text as the initial data, generate cats | ||
+ | for line in text.split( "\n" ): | ||
+ | # split each line into items | ||
+ | words = line.strip().split( "," ) | ||
+ | # if data is not exactly 5, skip | ||
+ | if len( words ) != 5: | ||
+ | continue | ||
+ | |||
+ | # set items to variables | ||
+ | name, age, vaccinated, neutered, breed = words | ||
+ | # convert age to int | ||
+ | age = int( age.strip() ) | ||
+ | # convert user inputs to booleans | ||
+ | if vaccinated.strip().lower() == "yes": | ||
+ | vaccinated = True | ||
+ | else: | ||
+ | vaccinated = False | ||
+ | |||
+ | neutered = neutered.strip().lower() == "yes" | ||
+ | |||
+ | # construct a cat | ||
+ | cat = Cat( name.strip(), age, vaccinated, neutered, breed.strip() ) | ||
+ | |||
+ | try: | ||
+ | # add the cat to the list | ||
+ | cats.append( cat ) | ||
+ | except NameError: | ||
+ | # if the cats list is not initialized, initialize it and append the first cat | ||
+ | cats = [] | ||
+ | cats.append( cat ) | ||
+ | |||
+ | # output the cat list | ||
+ | display( cats, "List of cats:" ) | ||
+ | |||
+ | |||
+ | # Go through each cat and add those who is both vaccinated and neutered into a list | ||
+ | vaccinatedNeuteredCats = [] | ||
+ | for cat in cats: | ||
+ | if cat.isVaccinated() and cat.isNeutered(): | ||
+ | vaccinatedNeuteredCats.append( cat ) | ||
+ | |||
+ | # output the cats in this new list (both vaccinated and neutered) | ||
+ | display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) | ||
+ | |||
+ | |||
+ | # Main entry point for the program | ||
+ | main() | ||
+ | |||
+ | </source> | ||
<br /> | <br /> | ||
+ | ==testHw9.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | # testHw9.py | ||
+ | # ------------------------------------------------------------------------------------------------------ | ||
+ | from hw9_1 import * | ||
+ | |||
+ | #================================================================== | ||
+ | # display(): print each cat in a Cat collection | ||
+ | # L - a list of cats | ||
+ | # caption - the subject of the list to be printed | ||
+ | #================================================================== | ||
+ | def display( L, caption ): | ||
+ | # print the subject | ||
+ | print( "\n\n"+caption ) | ||
+ | print( "=" * len( caption ) ) | ||
+ | # go over the list and print each cat's info | ||
+ | for cat in L: | ||
+ | print( cat ) | ||
+ | |||
+ | #================================================================== | ||
+ | # main(): | ||
+ | # * creates a list of cat objects, displays it. | ||
+ | # | ||
+ | #================================================================== | ||
+ | def main(): | ||
+ | # get the contents of cats.csv | ||
+ | file = open( "cats1.csv", "r" ) | ||
+ | text = file.read() | ||
+ | file.close() | ||
+ | |||
+ | # use the text as the initial data, generate cats | ||
+ | for line in text.split( "\n" ): | ||
+ | # split each line into items | ||
+ | words = line.strip().split( "," ) | ||
+ | # if data is not exactly 5, skip | ||
+ | if len( words ) != 5: | ||
+ | continue | ||
+ | |||
+ | # set items to variables | ||
+ | name, age, vaccinated, neutered, breed = words | ||
+ | # convert age to int | ||
+ | age = int( age.strip() ) | ||
+ | # convert user inputs to booleans | ||
+ | if vaccinated.strip().lower() == "yes": | ||
+ | vaccinated = True | ||
+ | else: | ||
+ | vaccinated = False | ||
+ | |||
+ | neutered = neutered.strip().lower() == "yes" | ||
+ | |||
+ | # construct a cat | ||
+ | cat = Cat( name.strip(), age, vaccinated, neutered, breed.strip() ) | ||
+ | |||
+ | try: | ||
+ | # add the cat to the list | ||
+ | cats.append( cat ) | ||
+ | except NameError: | ||
+ | # if the cats list is not initialized, initialize it and append the first cat | ||
+ | cats = [] | ||
+ | cats.append( cat ) | ||
+ | |||
+ | # output the cat list | ||
+ | display( cats, "List of cats:" ) | ||
+ | |||
+ | |||
+ | # Go through each cat and add those who is both vaccinated and neutered into a list | ||
+ | vaccinatedNeuteredCats = [] | ||
+ | for cat in cats: | ||
+ | if cat.isVaccinated() and cat.isNeutered(): | ||
+ | vaccinatedNeuteredCats.append( cat ) | ||
+ | |||
+ | # output the cats in this new list (both vaccinated and neutered) | ||
+ | display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) | ||
+ | |||
+ | |||
+ | # Main entry point for the program | ||
+ | main() | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==createCatCSV.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | import random | ||
+ | |||
+ | def createCatCSV( fileName ): | ||
+ | names = ["Minou", "Max", "Gizmo", "Garfield", "Silky", "Winston", "Bob", "Black" ] | ||
+ | breeds= ["stray", "stray", "Siemese", "Burmese", "Bengal", "Orange Tabby","stray", "Bengal" ] | ||
+ | N = len( names ) | ||
+ | file = open( fileName, "w" ) | ||
+ | for i in range( N ): | ||
+ | name = random.choice( names ) | ||
+ | names.remove( name ) | ||
+ | vac = random.choice( [ "Yes", "No" ] ) | ||
+ | tat = random.choice( [ "Yes", "No" ] ) | ||
+ | breed = random.choice( breeds ) | ||
+ | breeds.remove( breed ) | ||
+ | age = random.choice( [1, 1, 2, 3, 4, 1] ) | ||
+ | file.write( "%s, %d, %s, %s, %s\n" % ( name, age, vac, tat, breed ) ) | ||
+ | file.close() | ||
+ | |||
+ | def main(): | ||
+ | createCatCSV( "cats1.csv" ) | ||
+ | #print( "cats1.csv created!" ) | ||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==evaluate.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | # evaluate.py | ||
+ | # D. Thiebaut | ||
+ | # This program is used to test a student's python program on Moodle. | ||
+ | |||
+ | import sys | ||
+ | import random | ||
+ | import subprocess | ||
+ | |||
+ | |||
+ | #--- GLOBALS --- | ||
+ | #--- define what the student program is called, and what the solution | ||
+ | #--- program name is. | ||
+ | |||
+ | |||
+ | module = "testHw9" | ||
+ | studentModule = "hw9_1" | ||
+ | solutionModule = "hw9_1sol" # module + "sol" | ||
+ | |||
+ | userOutSplitPattern = "" # pattern used to start recording the user | ||
+ | # output. Useful when program does several | ||
+ | # input() statements, and user output starts | ||
+ | # after that. | ||
+ | stripOutputsBeforeCompare = True | ||
+ | # set to True if extra spaces at beginning or | ||
+ | # end of user output is ok | ||
+ | stripDoubleSpaceBeforeCompare = True | ||
+ | # set to True if double spaces must be removed in | ||
+ | # outputs | ||
+ | removeIfName = False | ||
+ | addIfName = False # controls whether we want "if __name__=="__main__": | ||
+ | # statement in the student and/or solution program | ||
+ | |||
+ | interpreter = sys.executable | ||
+ | |||
+ | |||
+ | def commentLong( line ): | ||
+ | print( "<|--\n" + line + "\n --|>" ) | ||
+ | |||
+ | def commentShort( text ): | ||
+ | print( "Comment :=>> " + text ) | ||
+ | |||
+ | def printGrade( grade ): | ||
+ | print( "Grade :=>> ", grade ) | ||
+ | |||
+ | # generateInputFileWithRandomInputs | ||
+ | # generate a file with name "inputFileName" with some random input | ||
+ | # for the program. | ||
+ | # MAKE SURE TO EDIT THIS TO MATCH THE PROGRAM BEING TESTED | ||
+ | def generateInputFileWithRandomInputs( inputFileName ): | ||
+ | #--- we don't need an input file for stdin, but we'll generate a | ||
+ | #--- dummy one nonetheless | ||
+ | #--- generate random inputs --- | ||
+ | import createCatCSV | ||
+ | text = open( "cats1.csv", "r" ).read() | ||
+ | return text | ||
+ | |||
+ | # removeIf__name__: remove the if __name__=="__main__": statement | ||
+ | def removeIf__name__( moduleName ): | ||
+ | |||
+ | file = open( moduleName + ".py", "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | |||
+ | newLines = [] | ||
+ | for line in lines: | ||
+ | if line.find( "if __name__" ) != -1: | ||
+ | line = "if True:\n" | ||
+ | newLines.append( line.rstrip() ) | ||
+ | |||
+ | file = open( moduleName + ".py", "w" ) | ||
+ | file.write( "\n".join( newLines ) ) | ||
+ | file.close() | ||
+ | |||
+ | # addIf__name__: adds the if __name__=="__main__": statement | ||
+ | def addIf__name__( moduleName ): | ||
+ | file = open( moduleName + ".py", "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | |||
+ | newLines = [] | ||
+ | for line in lines: | ||
+ | if line.find( "main(" ) == 0: | ||
+ | line = "if __name__==\"__main__\":\n main()" | ||
+ | newLines.append( line.rstrip() ) | ||
+ | |||
+ | file = open( moduleName + ".py", "w" ) | ||
+ | file.write( "\n".join( newLines ) ) | ||
+ | file.close() | ||
+ | |||
+ | |||
+ | |||
+ | # checkForFunctionPresence | ||
+ | # checks that "functionName" is defined and called in the program. | ||
+ | # MAKE SURE TO EDIT TO MATCH PROGRAM BEING TESTED | ||
+ | def checkForFunctionPresence( module, functionName ): | ||
+ | foundDef = False | ||
+ | foundCall = False | ||
+ | |||
+ | for line in open( module+".py", "r" ).readlines(): | ||
+ | # remove comments | ||
+ | idx = line.find( "#" ) | ||
+ | if ( idx >=0 ): line = line[0:idx] | ||
+ | |||
+ | if line.startswith( "def " + functionName + "(" ): | ||
+ | foundDef = True | ||
+ | continue | ||
+ | if line.startswith( "def " + functionName + " (" ): | ||
+ | foundDef = True | ||
+ | continue | ||
+ | if line.find( functionName+"(" ) != -1: | ||
+ | foundCall = True | ||
+ | continue | ||
+ | |||
+ | return (foundDef, foundCall) | ||
+ | |||
+ | |||
+ | |||
+ | # ================================================================== | ||
+ | # NO EDITS NEEDED BELOW! | ||
+ | # ================================================================== | ||
+ | |||
+ | def clearLog(): | ||
+ | open( "log.txt", "w" ).write( "" ) | ||
+ | |||
+ | def log( message ): | ||
+ | file = open( "log.txt", "a" ) | ||
+ | file.write( message + "\n" ) | ||
+ | file.flush() | ||
+ | file.close() | ||
+ | |||
+ | |||
+ | # checkModuleRunsOK: runs the module as a shell subprocess and | ||
+ | # look for errors in the output. This is required, because otherwise | ||
+ | # importing the module in this program will make this program crash. | ||
+ | # It's not possible (as far as I can tell0 to catch exceptions from | ||
+ | # the import or __module__ statements. | ||
+ | # returns True, none if no errors, otherwise False, string if there's | ||
+ | # an exception, and the error message (string) is in the returned 2nd | ||
+ | # arg. | ||
+ | # The module name is assumed to not include ".py" | ||
+ | def checkModuleRunsOk( module, inputFileName ): | ||
+ | global interpreter | ||
+ | p = subprocess.Popen( [ interpreter, module+".py" ], | ||
+ | stdout=subprocess.PIPE, | ||
+ | stderr=subprocess.PIPE, | ||
+ | stdin=subprocess.PIPE) | ||
+ | |||
+ | #print( "inputFileName = ", inputFileName ) | ||
+ | #print( "open( inputFileName, r).read() = ", open( inputFileName, "r" ).read() ) | ||
+ | |||
+ | p.stdin.write( bytes( open( inputFileName, "r" ).read(), 'UTF-8' ) ) | ||
+ | data = p.communicate( ) | ||
+ | p.stdin.close() | ||
+ | |||
+ | error = data[1].decode( 'UTF-8' ) | ||
+ | if len( error ) > 1: | ||
+ | return False, error | ||
+ | return True, None | ||
+ | |||
+ | |||
+ | # extractTextFromErrorMessage( sys_exc_info ): | ||
+ | def extractTextFromErrorMessage( sys_exc_info ): | ||
+ | print( "sys_exec_info = ", sys_exc_info ) | ||
+ | text = "" | ||
+ | for field in sys_exc_info: | ||
+ | if type( field )==type( " " ): | ||
+ | text += field + "\n" | ||
+ | return text | ||
+ | |||
+ | # runModule: | ||
+ | # runs the module, passes it data from the input file on its stdin | ||
+ | # and get its output on stdout captured in outputFileName. | ||
+ | # We assume the module will not crash, because we already tested | ||
+ | # it with checkModuleRunsOk(). | ||
+ | def runModule( module, inputFileName, outputFileName ): | ||
+ | global userOutSplitPattern | ||
+ | global removeIfName, addIfName | ||
+ | |||
+ | # remove the if __name__=="__main__": statement | ||
+ | if removeIfName: removeIf__name__( module ) | ||
+ | if addIfName: addIf__name__( module ) | ||
+ | |||
+ | error = False | ||
+ | |||
+ | #--- make stdin read information from the text file | ||
+ | #sys.stdin = open( inputFileName, "r" ) | ||
+ | |||
+ | #--- capture the stdout of the program to test into a file | ||
+ | saveStdOut = sys.stdout | ||
+ | saveStdErr = sys.stderr | ||
+ | |||
+ | sys.stdout = open( outputFileName, "w" ) | ||
+ | sys.stderr = open( "errorOut", "w" ) | ||
+ | |||
+ | #--- run the student program --- | ||
+ | try: | ||
+ | _module = __import__( module ) | ||
+ | except: | ||
+ | error = True | ||
+ | sys.stderr.close() | ||
+ | sys.stderr = saveStdErr | ||
+ | sys.stdout.close() | ||
+ | sys.stdout = saveStdOut | ||
+ | text = sys.exc_info()[0] | ||
+ | text = extractTextFromErrorMessage( text ) | ||
+ | print( "*** sys.exc_info() = ", text ) | ||
+ | text = open( outputFileName, "r" ).read() + "\n" + text | ||
+ | return text | ||
+ | |||
+ | #--- filter out junk from output of program --- | ||
+ | sys.stdout.close() | ||
+ | sys.stdout = saveStdOut | ||
+ | sys.stderr.close() | ||
+ | sys.stderr = saveStdErr | ||
+ | |||
+ | file = open( outputFileName, "r" ) | ||
+ | text = file.read() | ||
+ | #print( module, " output = ", text ) | ||
+ | file.close() | ||
+ | return text | ||
+ | |||
+ | def removeBlankLines( lines ): | ||
+ | newLines = [] | ||
+ | log( "removeBlankLines: lines = " + str( lines ) ) | ||
+ | for line in lines.split( "\n" ): | ||
+ | if len( line )==0: | ||
+ | continue | ||
+ | newLines.append( line ) | ||
+ | |||
+ | return ( "\n".join( newLines ) ) + "\n" | ||
+ | |||
+ | def compareUserExpected( inputLines, userOutText, expectedOutText ): | ||
+ | import re | ||
+ | global stripOutputsBeforeCompare | ||
+ | |||
+ | userOutText = removeBlankLines( userOutText ) | ||
+ | expectedOutText = removeBlankLines( expectedOutText ) | ||
+ | misMatchLineNumbers = [] | ||
+ | userTextOutLines = userOutText.split( "\n" ) | ||
+ | expectedOutTextLines = expectedOutText.split( "\n" ) | ||
+ | |||
+ | |||
+ | for i in range( len( userTextOutLines ) ): | ||
+ | lineNo = i+1 | ||
+ | userLine = userTextOutLines[i] | ||
+ | if i >= len( expectedOutTextLines ): | ||
+ | misMatchLineNumbers.append( lineNo ) | ||
+ | break | ||
+ | expectedLine = expectedOutTextLines[i] | ||
+ | log( "comparing:\n "+userLine+"\n "+expectedLine ) | ||
+ | |||
+ | if stripOutputsBeforeCompare: | ||
+ | userLine = userLine.strip() | ||
+ | expectedLine = expectedLine.strip() | ||
+ | |||
+ | if stripDoubleSpaceBeforeCompare: | ||
+ | userLine = re.sub(' +',' ', userLine ) | ||
+ | expectedLine = re.sub( ' +', ' ', expectedLine ) | ||
+ | |||
+ | if userLine != expectedLine: | ||
+ | log( "\ndifference: user >" + userTextOutLines[i] + "<" ) | ||
+ | log( "expected >" + expectedOutTextLines[i] + "<" ) | ||
+ | misMatchLineNumbers.append( lineNo ) | ||
+ | |||
+ | return misMatchLineNumbers | ||
+ | |||
+ | |||
+ | |||
+ | def main(): | ||
+ | global module | ||
+ | global solutionModule | ||
+ | |||
+ | #--- make sure we don't run the main of the student's module | ||
+ | addIf__name__( studentModule ) | ||
+ | |||
+ | #--- clear debug log --- | ||
+ | clearLog() | ||
+ | |||
+ | #--- check that the main module uses a main() function | ||
+ | """ | ||
+ | foundDef, foundCall = checkForFunctionPresence( module, "main" ) | ||
+ | |||
+ | if (not foundDef) or (not foundCall): | ||
+ | commentShort( "-Missing main() program" ) | ||
+ | commentShort( "Your program must use a main() function." ) | ||
+ | commentShort( "(make sure you spell it exactly \"main()\"!" ) | ||
+ | printGrade( 40 ) | ||
+ | return | ||
+ | """ | ||
+ | inputFileName = "cats1.csv" | ||
+ | |||
+ | #--- generate input file with random data --- | ||
+ | inputLines = generateInputFileWithRandomInputs( inputFileName ) | ||
+ | |||
+ | #print( "inputLines = ", inputLines ) | ||
+ | |||
+ | Ok, errorMessage = checkModuleRunsOk( module, inputFileName ) | ||
+ | if not Ok: | ||
+ | commentLong( "- Your program crashed...\n" | ||
+ | + "Error message:\n" | ||
+ | + errorMessage + "\n" ) | ||
+ | printGrade( 50 ) | ||
+ | return | ||
+ | |||
+ | expectedOutText = runModule( solutionModule, inputFileName, "expectedOut" ) | ||
+ | userOutText = runModule( module, inputFileName, "userOut" ) | ||
+ | |||
+ | #print( "expectedOutText = ", expectedOutText ) | ||
+ | #print( "userOutText = ", userOutText ) | ||
+ | |||
+ | missMatches = compareUserExpected( inputLines, userOutText, expectedOutText ) | ||
+ | |||
+ | if len( missMatches ) != 0: | ||
+ | commentLong( "- Incorrect output...\n" | ||
+ | +"Differences found on line(s): " | ||
+ | + (", ".join( [str(k) for k in missMatches] )) + "\n" | ||
+ | +"Expected output:\n" | ||
+ | +expectedOutText + "\n" | ||
+ | +"Your output:\n" | ||
+ | +userOutText + "\n" ) | ||
+ | printGrade( 75 ) | ||
+ | else: | ||
+ | commentLong( "- Your program passes the test\n" ) | ||
+ | printGrade( 100 ) | ||
+ | |||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==VPL: Part 2== | ||
+ | ==vpl_run.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | #! /bin/bash | ||
+ | |||
+ | cat > vpl_execution <<EOF | ||
+ | #! /bin/bash | ||
+ | |||
+ | # --- Python ---- | ||
+ | if [[ `hostname -s` = "beowulf2" ]]; then | ||
+ | python=/usr/bin/python3.3 | ||
+ | else | ||
+ | python=/usr/local/bin/python3.4 | ||
+ | fi | ||
+ | |||
+ | prog=hw9_2.py | ||
+ | |||
+ | \$python createPeopleDogCSV.py | ||
+ | |||
+ | echo "CSV file:" | ||
+ | cat peopledog.csv | ||
+ | |||
+ | echo "" | ||
+ | echo "Your program output" | ||
+ | \$python \$prog | ||
+ | |||
+ | EOF | ||
+ | |||
+ | chmod +x vpl_execution | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_debug.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_evaluate.sh== | ||
+ | <br /> | ||
+ | <source lang="bash"> | ||
+ | #! /bin/bash | ||
+ | |||
+ | cat > vpl_execution <<EOF | ||
+ | #! /bin/bash | ||
+ | |||
+ | # --- Python ---- | ||
+ | if [[ `hostname -s` = "beowulf2" ]]; then | ||
+ | python=/usr/bin/python3.3 | ||
+ | else | ||
+ | python=/usr/local/bin/python3.4 | ||
+ | fi | ||
+ | |||
+ | |||
+ | |||
+ | \$python evaluate.py | ||
+ | |||
+ | EOF | ||
+ | |||
+ | chmod +x vpl_execution | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==vpl_evaluate.cases== | ||
+ | <br /> | ||
+ | <source lang="text"> | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==evaluate.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | # evaluate.py | ||
+ | # D. Thiebaut | ||
+ | # This program is used to test a student's python program on Moodle. | ||
+ | |||
+ | import sys | ||
+ | import random | ||
+ | import subprocess | ||
+ | |||
+ | |||
+ | #--- GLOBALS --- | ||
+ | #--- define what the student program is called, and what the solution | ||
+ | #--- program name is. | ||
+ | |||
+ | |||
+ | module = "hw9_2" | ||
+ | solutionModule = module + "sol" | ||
+ | |||
+ | userOutSplitPattern = "" # pattern used to start recording the user | ||
+ | # output. Useful when program does several | ||
+ | # input() statements, and user output starts | ||
+ | # after that. | ||
+ | stripOutputsBeforeCompare = True | ||
+ | # set to True if extra spaces at beginning or | ||
+ | # end of user output is ok | ||
+ | stripDoubleSpaceBeforeCompare = True | ||
+ | # set to True if double spaces must be removed in | ||
+ | # outputs | ||
+ | removeIfName = True | ||
+ | addIfName = False # controls whether we want "if __name__=="__main__": | ||
+ | # statement in the student and/or solution program | ||
+ | |||
+ | interpreter = sys.executable | ||
+ | |||
+ | |||
+ | def commentLong( line ): | ||
+ | print( "<|--\n" + line + "\n --|>" ) | ||
+ | |||
+ | def commentShort( text ): | ||
+ | print( "Comment :=>> " + text ) | ||
+ | |||
+ | def printGrade( grade ): | ||
+ | print( "Grade :=>> ", grade ) | ||
+ | |||
+ | # generateInputFileWithRandomInputs | ||
+ | # generate a file with name "inputFileName" with some random input | ||
+ | # for the program. | ||
+ | # MAKE SURE TO EDIT THIS TO MATCH THE PROGRAM BEING TESTED | ||
+ | def generateInputFileWithRandomInputs( inputFileName ): | ||
+ | #--- we don't need an input file for stdin, but we'll generate a | ||
+ | #--- dummy one nonetheless | ||
+ | #--- generate random inputs --- | ||
+ | import createPeopleDogCSV | ||
+ | text = open( "peopledog.csv", "r" ).read() | ||
+ | return text | ||
+ | |||
+ | # removeIf__name__: remove the if __name__=="__main__": statement | ||
+ | def removeIf__name__( moduleName ): | ||
+ | |||
+ | file = open( moduleName + ".py", "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | |||
+ | newLines = [] | ||
+ | for line in lines: | ||
+ | if line.find( "if __name__" ) != -1: | ||
+ | line = "if True:\n" | ||
+ | newLines.append( line.rstrip() ) | ||
+ | |||
+ | file = open( moduleName + ".py", "w" ) | ||
+ | file.write( "\n".join( newLines ) ) | ||
+ | file.close() | ||
+ | |||
+ | # addIf__name__: adds the if __name__=="__main__": statement | ||
+ | def addIf__name__( moduleName ): | ||
+ | file = open( moduleName + ".py", "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | |||
+ | newLines = [] | ||
+ | for line in lines: | ||
+ | if line.find( "main(" ) == 0: | ||
+ | line = "if __name__==\"__main__\":\n main()" | ||
+ | newLines.append( line.rstrip() ) | ||
+ | |||
+ | file = open( moduleName + ".py", "w" ) | ||
+ | file.write( "\n".join( newLines ) ) | ||
+ | file.close() | ||
+ | |||
+ | # checkForFunctionPresence | ||
+ | # checks that "functionName" is defined and called in the program. | ||
+ | # MAKE SURE TO EDIT TO MATCH PROGRAM BEING TESTED | ||
+ | def checkForFunctionPresence( module, functionName ): | ||
+ | foundDef = False | ||
+ | foundCall = False | ||
+ | |||
+ | for line in open( module+".py", "r" ).readlines(): | ||
+ | # remove comments | ||
+ | idx = line.find( "#" ) | ||
+ | if ( idx >=0 ): line = line[0:idx] | ||
+ | |||
+ | if line.startswith( "def " + functionName + "(" ): | ||
+ | foundDef = True | ||
+ | continue | ||
+ | if line.startswith( "def " + functionName + " (" ): | ||
+ | foundDef = True | ||
+ | continue | ||
+ | if line.find( functionName+"(" ) != -1: | ||
+ | foundCall = True | ||
+ | continue | ||
+ | |||
+ | return (foundDef, foundCall) | ||
+ | |||
+ | |||
+ | |||
+ | # ================================================================== | ||
+ | # NO EDITS NEEDED BELOW! | ||
+ | # ================================================================== | ||
+ | |||
+ | def clearLog(): | ||
+ | open( "log.txt", "w" ).write( "" ) | ||
+ | |||
+ | def log( message ): | ||
+ | file = open( "log.txt", "a" ) | ||
+ | file.write( message + "\n" ) | ||
+ | file.flush() | ||
+ | file.close() | ||
+ | |||
+ | |||
+ | # checkModuleRunsOK: runs the module as a shell subprocess and | ||
+ | # look for errors in the output. This is required, because otherwise | ||
+ | # importing the module in this program will make this program crash. | ||
+ | # It's not possible (as far as I can tell0 to catch exceptions from | ||
+ | # the import or __module__ statements. | ||
+ | # returns True, none if no errors, otherwise False, string if there's | ||
+ | # an exception, and the error message (string) is in the returned 2nd | ||
+ | # arg. | ||
+ | # The module name is assumed to not include ".py" | ||
+ | def checkModuleRunsOk( module, inputFileName ): | ||
+ | global interpreter | ||
+ | p = subprocess.Popen( [ interpreter, module+".py" ], | ||
+ | stdout=subprocess.PIPE, | ||
+ | stderr=subprocess.PIPE, | ||
+ | stdin=subprocess.PIPE) | ||
+ | |||
+ | #print( "inputFileName = ", inputFileName ) | ||
+ | #print( "open( inputFileName, r).read() = ", open( inputFileName, "r" ).read() ) | ||
+ | |||
+ | p.stdin.write( bytes( open( inputFileName, "r" ).read(), 'UTF-8' ) ) | ||
+ | data = p.communicate( ) | ||
+ | p.stdin.close() | ||
+ | |||
+ | error = data[1].decode( 'UTF-8' ) | ||
+ | if len( error ) > 1: | ||
+ | return False, error | ||
+ | return True, None | ||
+ | |||
+ | |||
+ | # extractTextFromErrorMessage( sys_exc_info ): | ||
+ | def extractTextFromErrorMessage( sys_exc_info ): | ||
+ | print( "sys_exec_info = ", sys_exc_info ) | ||
+ | text = "" | ||
+ | for field in sys_exc_info: | ||
+ | if type( field )==type( " " ): | ||
+ | text += field + "\n" | ||
+ | return text | ||
+ | |||
+ | # runModule: | ||
+ | # runs the module, passes it data from the input file on its stdin | ||
+ | # and get its output on stdout captured in outputFileName. | ||
+ | # We assume the module will not crash, because we already tested | ||
+ | # it with checkModuleRunsOk(). | ||
+ | def runModule( module, inputFileName, outputFileName ): | ||
+ | global userOutSplitPattern | ||
+ | global removeIfName, addIfName | ||
+ | |||
+ | # remove the if __name__=="__main__": statement | ||
+ | if removeIfName: removeIf__name__( module ) | ||
+ | if addIfName: addIf__name__( module ) | ||
+ | |||
+ | error = False | ||
+ | |||
+ | #--- make stdin read information from the text file | ||
+ | #sys.stdin = open( inputFileName, "r" ) | ||
+ | |||
+ | #--- capture the stdout of the program to test into a file | ||
+ | saveStdOut = sys.stdout | ||
+ | saveStdErr = sys.stderr | ||
+ | |||
+ | sys.stdout = open( outputFileName, "w" ) | ||
+ | sys.stderr = open( "errorOut", "w" ) | ||
+ | |||
+ | #--- run the student program --- | ||
+ | try: | ||
+ | _module = __import__( module ) | ||
+ | except: | ||
+ | error = True | ||
+ | sys.stderr.close() | ||
+ | sys.stderr = saveStdErr | ||
+ | sys.stdout.close() | ||
+ | sys.stdout = saveStdOut | ||
+ | text = sys.exc_info()[0] | ||
+ | text = extractTextFromErrorMessage( text ) | ||
+ | print( "*** sys.exc_info() = ", text ) | ||
+ | text = open( outputFileName, "r" ).read() + "\n" + text | ||
+ | return text | ||
+ | |||
+ | #--- filter out junk from output of program --- | ||
+ | sys.stdout.close() | ||
+ | sys.stdout = saveStdOut | ||
+ | sys.stderr.close() | ||
+ | sys.stderr = saveStdErr | ||
+ | |||
+ | file = open( outputFileName, "r" ) | ||
+ | text = file.read() | ||
+ | #print( module, " output = ", text ) | ||
+ | file.close() | ||
+ | return text | ||
+ | |||
+ | def removeBlankLines( lines ): | ||
+ | newLines = [] | ||
+ | log( "removeBlankLines: lines = " + str( lines ) ) | ||
+ | for line in lines.split( "\n" ): | ||
+ | if len( line )==0: | ||
+ | continue | ||
+ | newLines.append( line ) | ||
+ | |||
+ | return ( "\n".join( newLines ) ) + "\n" | ||
+ | |||
+ | def compareUserExpected( inputLines, userOutText, expectedOutText ): | ||
+ | import re | ||
+ | global stripOutputsBeforeCompare | ||
+ | |||
+ | userOutText = removeBlankLines( userOutText ) | ||
+ | expectedOutText = removeBlankLines( expectedOutText ) | ||
+ | misMatchLineNumbers = [] | ||
+ | userTextOutLines = userOutText.split( "\n" ) | ||
+ | expectedOutTextLines = expectedOutText.split( "\n" ) | ||
+ | |||
+ | |||
+ | for i in range( len( userTextOutLines ) ): | ||
+ | lineNo = i+1 | ||
+ | userLine = userTextOutLines[i] | ||
+ | if i >= len( expectedOutTextLines ): | ||
+ | misMatchLineNumbers.append( lineNo ) | ||
+ | break | ||
+ | expectedLine = expectedOutTextLines[i] | ||
+ | log( "comparing:\n "+userLine+"\n "+expectedLine ) | ||
+ | |||
+ | if stripOutputsBeforeCompare: | ||
+ | userLine = userLine.strip() | ||
+ | expectedLine = expectedLine.strip() | ||
+ | |||
+ | if stripDoubleSpaceBeforeCompare: | ||
+ | userLine = re.sub(' +',' ', userLine ) | ||
+ | expectedLine = re.sub( ' +', ' ', expectedLine ) | ||
+ | |||
+ | if userLine != expectedLine: | ||
+ | log( "\ndifference: user >" + userTextOutLines[i] + "<" ) | ||
+ | log( "expected >" + expectedOutTextLines[i] + "<" ) | ||
+ | misMatchLineNumbers.append( lineNo ) | ||
+ | |||
+ | return misMatchLineNumbers | ||
+ | |||
+ | |||
+ | |||
+ | def main(): | ||
+ | global module | ||
+ | global solutionModule | ||
+ | |||
+ | #--- make sure we don't run the main of the student's module | ||
+ | #addIf__name__( module ) | ||
+ | |||
+ | #--- clear debug log --- | ||
+ | clearLog() | ||
+ | |||
+ | #--- check that the main module uses a main() function | ||
+ | """ | ||
+ | foundDef, foundCall = checkForFunctionPresence( module, "main" ) | ||
+ | |||
+ | if (not foundDef) or (not foundCall): | ||
+ | commentShort( "-Missing main() program" ) | ||
+ | commentShort( "Your program must use a main() function." ) | ||
+ | commentShort( "(make sure you spell it exactly \"main()\"!" ) | ||
+ | printGrade( 40 ) | ||
+ | return | ||
+ | """ | ||
+ | inputFileName = "peopledog.csv" | ||
+ | |||
+ | #--- generate input file with random data --- | ||
+ | inputLines = generateInputFileWithRandomInputs( inputFileName ) | ||
+ | |||
+ | #print( "inputLines = ", inputLines ) | ||
+ | |||
+ | Ok, errorMessage = checkModuleRunsOk( module, inputFileName ) | ||
+ | if not Ok: | ||
+ | commentLong( "- Your program crashed...\n" | ||
+ | + "Error message:\n" | ||
+ | + errorMessage + "\n" ) | ||
+ | printGrade( 50 ) | ||
+ | return | ||
+ | |||
+ | expectedOutText = runModule( solutionModule, inputFileName, "expectedOut" ) | ||
+ | userOutText = runModule( module, inputFileName, "userOut" ) | ||
+ | |||
+ | #print( "expectedOutText = ", expectedOutText ) | ||
+ | #print( "userOutText = ", userOutText ) | ||
+ | |||
+ | missMatches = compareUserExpected( inputLines, userOutText, expectedOutText ) | ||
+ | |||
+ | if len( missMatches ) != 0: | ||
+ | commentLong( "- Incorrect output...\n" | ||
+ | + ( "Differences found on %d line(s)\n" % len( missMatches ) ) | ||
+ | +"Expected output:\n" | ||
+ | +expectedOutText + "\n" | ||
+ | +"Your output:\n" | ||
+ | +userOutText + "\n" ) | ||
+ | printGrade( 100 - (len( missMatches )-1) * 10 ) | ||
+ | else: | ||
+ | commentLong( "- Your program passes the test\n" ) | ||
+ | printGrade( 100 ) | ||
+ | |||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==createPeopleDogCSV.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | import random | ||
+ | |||
+ | def createCSV( fileName ): | ||
+ | pnames = ["Valerie", "Maria", "Lujun", "Fang", "Danielle", "June" ] | ||
+ | dnames = ["Rex", "Ralph", "Woof", "Wolf", "Blue", "Medor", "Blake", "Madrigor" ] | ||
+ | ages = [18, 17, 23, 35, 49, 19, 21, 29, 32, 76, 55, 69] | ||
+ | N = len( pnames ) | ||
+ | file = open( fileName, "w" ) | ||
+ | loner = False | ||
+ | |||
+ | for i in range( N ): | ||
+ | name = random.choice( pnames ) | ||
+ | pnames.remove( name ) | ||
+ | age = random.choice( ages ) | ||
+ | ages.remove( age ) | ||
+ | |||
+ | if random.randrange( 0, 100 ) < 70: | ||
+ | dog = random.choice( dnames ) | ||
+ | dnames.remove( dog ) | ||
+ | vac = random.choice( ["vaccinated", "not vaccinated" ] ) | ||
+ | else: | ||
+ | dog = "" | ||
+ | vac = "" | ||
+ | loner = True | ||
+ | file.write( "%s, %d, %s, %s\n" % ( name, age, dog, vac ) ) | ||
+ | |||
+ | if loner==False: | ||
+ | file.write( "%s, %d, %s, %s\n" % ( "Kate", random.choice( ages ), "", "" ) ) | ||
+ | file.close() | ||
+ | |||
+ | def main(): | ||
+ | createCSV( "peopledog.csv" ) | ||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==hw9_2sol.py== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | # hw9_2start.py | ||
+ | # your name here | ||
+ | # This program maintains 2 classes, one for a person | ||
+ | # and the other for a dog. | ||
+ | # A person object is defined by a name, an age, and a dog. | ||
+ | # If a person does not own a dog, then that person's dog field is set to None. | ||
+ | # A dog is defined by a tag (its name) and a boolean indicating if it is | ||
+ | # vaccinated or not. | ||
+ | # The main program outputs various lists of people. | ||
+ | # | ||
+ | |||
+ | class Person: | ||
+ | # a class containing 4 private member variables: | ||
+ | # - name of the person (string) | ||
+ | # - age (integer) | ||
+ | # - gpa (float) | ||
+ | # - major (string, uppercase) | ||
+ | # methods: | ||
+ | # getName(): returns the name of the person (string) | ||
+ | # getAge(): returns the age of the person (int) | ||
+ | # setAge(x): sets the age of the person to x (int) | ||
+ | |||
+ | # constructor: intializes a person with all fields | ||
+ | def __init__(self, n, a, dg ): | ||
+ | self.name = n | ||
+ | self.age = a | ||
+ | self.dog = dg | ||
+ | |||
+ | def getDog( self ): | ||
+ | return self.dog | ||
+ | |||
+ | # returns a string with the name and age. | ||
+ | def __str__( self ): | ||
+ | return "{0:1}, {1:1} years old".format( self.name, self.age ) | ||
+ | |||
+ | # returns the name | ||
+ | def getName( self ): | ||
+ | return self.name | ||
+ | |||
+ | # set the age to a new value x | ||
+ | def setAge( self, x ): | ||
+ | self.age = x | ||
+ | |||
+ | # returns the age of the person | ||
+ | def getAge( self ): | ||
+ | return self.age | ||
+ | |||
+ | |||
+ | class Dog: | ||
+ | # a class containing 2 private member variables: | ||
+ | # - name-tag of the dog (string) | ||
+ | # - whether the dog is vaccinated or not (boolean) | ||
+ | # methods: | ||
+ | # isVaccinated(): returns True if the dog is vaccinated, False otherwise | ||
+ | # getName(): returns the name-tag of the dog | ||
+ | # setName(x): sets the name-tag of the dog | ||
+ | # constructor | ||
+ | def __init__( self, tag, vaccinated ): | ||
+ | self.tag = tag | ||
+ | self.vaccinated = vaccinated | ||
+ | |||
+ | # default string representation for the dog | ||
+ | def __str__( self ): | ||
+ | if self.vaccinated==True: | ||
+ | return "{0:1} (vaccinated)".format( self.tag ) | ||
+ | return "{0:1} (not vaccinated)".format( self.tag ) | ||
+ | |||
+ | # isVaccinated: returns True if the dog is vaccinated, False otherwise | ||
+ | def isVaccinated( self ): | ||
+ | return self.vaccinated | ||
+ | |||
+ | # returns the name of the dog | ||
+ | def getNameTag( self ): | ||
+ | return self.tag | ||
+ | |||
+ | # changes the name-tag | ||
+ | def setNameTag( self, tag ): | ||
+ | self.tag = tag | ||
+ | |||
+ | # readCSVFile. Reads the contents of a CSV file and return | ||
+ | # a list of strings containing all the lines. | ||
+ | def readCSVFile( fileName ): | ||
+ | file = open( fileName, "r" ) | ||
+ | lines = file.readlines() | ||
+ | file.close() | ||
+ | return lines | ||
+ | |||
+ | |||
+ | # ================================================ | ||
+ | # main | ||
+ | # ================================================ | ||
+ | def main(): | ||
+ | # get the contents of the file | ||
+ | lines = readCSVFile( "peopledog.csv" ) | ||
+ | |||
+ | # create a list of people, and their dog (if they own one) | ||
+ | people = [] | ||
+ | |||
+ | # parse the text and add it as people-dog pairs in the list | ||
+ | for line in lines: | ||
+ | |||
+ | # reject lines that are not formatted correctly | ||
+ | if len( line.split(',') ) != 4: | ||
+ | continue | ||
+ | |||
+ | # parse line | ||
+ | name, age, tag, vacc = line.split(',') | ||
+ | name = name.strip() | ||
+ | age = int( age.strip() ) | ||
+ | tag = tag.strip() | ||
+ | vacc = "not" not in vacc.lower() | ||
+ | |||
+ | if len( tag )==0: | ||
+ | p = Person(name, age, None ) | ||
+ | else: | ||
+ | p = Person(name, age, Dog( tag, vacc ) ) | ||
+ | |||
+ | # add this new person to the list | ||
+ | people.append( p ) | ||
+ | |||
+ | # Display the whole list | ||
+ | for person in people: | ||
+ | |||
+ | if person.getDog() != None: | ||
+ | print( person, ", has a dog: ", person.getDog(), sep="" ) | ||
+ | else: | ||
+ | print( person, ", does not have a dog", sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # Display the list of people with unvaccinated dogs | ||
+ | for person in people: | ||
+ | if person.getDog() != None and person.getDog().isVaccinated()==False: | ||
+ | print( person, ", has a dog: ", person.getDog(), sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # Display the list of people without dogs | ||
+ | for person in people: | ||
+ | if person.getDog() == None: | ||
+ | print( person, ", does not have a dog", sep="" ) | ||
+ | |||
+ | print() | ||
+ | |||
+ | # display the oldest person who has a dog | ||
+ | index = -1 | ||
+ | oldestAge = -1 | ||
+ | for i in range(len( people ) ): | ||
+ | person = people[i] | ||
+ | if person.getDog() == None: | ||
+ | continue | ||
+ | if person.getAge() > oldestAge: | ||
+ | oldestAge = person.getAge() | ||
+ | index = i | ||
+ | |||
+ | if index == -1: | ||
+ | print( "Nobody in the list has dogs." ) | ||
+ | else: | ||
+ | oldest = people[index] | ||
+ | print( oldest, ", is the oldest person owning a dog.", sep="" ) | ||
+ | |||
+ | main() | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </onlydft> | ||
<br /> | <br /> | ||
[[Category:CSC111]][[Category:Python]][[Category:Homework]] | [[Category:CSC111]][[Category:Python]][[Category:Homework]] |
Latest revision as of 15:30, 1 November 2015
--D. Thiebaut (talk) 22:47, 30 March 2015 (EDT)
<showafterdate after="20150402 16:00" before="20150601 00:00">
This assignment is due the evening of Tuesday 4/7/15, at 11:55 p.m. You will be able to evaluate Problem 1, but not Problem 2.
Contents
Problem #1: Lost Cat
(image from nicepixy.net)
The program below is missing its class! And it is also missing its documentation! It used to contain a class defined, with methods and member variables, and a fully developped documentation, but unfortunately all of them got erased.
We do have the output of a run of the program, though, when it still had its class definition. Both the incomplete code and the output are shown below.
# hw9_1.py
# your name goes here
# and a description of the program
#
# missing class goes here...
#
def display( catList, caption ):
print( "\n\n"+caption )
print( "=" * len( caption ) )
for cat in catList:
print( cat )
def main():
#comments below are for debugging purpose
#text="""Minou, 3, Yes, Yes, stray
# Max, 1, Yes, No, Burmese
# Gizmo, 2, No, No, Bengal
# Garfield, 4, Yes, Yes, Orange Tabby"""
file = open( "cats1.csv", "r" )
text = file.read()
file.close()
for line in text.split( "\n" ):
words = line.strip().split( "," )
if len( words ) != 5:
continue
name, age, vaccinated, neutered, breed = words
age = int( age.strip() )
if vaccinated.strip().lower() == "yes":
vaccinated = True
else:
vaccinated = False
neutered = neutered.strip().lower() == "yes"
cat = Cat( name.strip(), age, vaccinated, neutered, breed.strip() )
try:
cats.append( cat )
except NameError:
cats = []
cats.append( cat )
display( cats, "List of cats:" )
vaccinatedNeuteredCats = []
for cat in cats:
if cat.isVaccinated() and cat.isNeutered():
vaccinatedNeuteredCats.append( cat )
display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" )
if __name__=="__main__":
main()
Example cats1.csv File
Here is an example of the format of the csv file.
Minou, 3, Yes, Yes, stray Max, 1, Yes, No, Burmese Gizmo, 2, No, No, Bengal Garfield, 4, Yes, Yes, Orange Tabby
Corresponding Output
List of cats:
=============
Cat: Minou, age: 3, vaccinated, neutered (stray)
Cat: Max, age: 1, vaccinated, not neutered (Burmese)
Cat: Gizmo, age: 2, not vaccinated, not neutered (Bengal)
Cat: Garfield, age: 4, vaccinated, neutered (Orange Tabby)
Vaccinated and neutered cats:
=============================
Cat: Minou, age: 3, vaccinated, neutered (stray)
Cat: Garfield, age: 4, vaccinated, neutered (Orange Tabby)
- Question
Recreate the original program with its Cat class. You cannot modify the main program!. Make sure that your program with the reconstituted class generates the same output as the one shown above, when fed the same CSV file.
Document your code well, including the main(), and display() functions. Document the class using the same approach as in Part 2, below.
Store your program in a file called hw9_1.py and submit it to the Moodle HW9 PB1 section.
Testing
Your program will be tested using your Cat class, and the main() function shown in the code above. Whatever modification you bring to your main function will not be used. For this reason, make sure you do not modify the code of the main() function that is given to you.
Problem #2: Of dogs and people...
(image from naturesmightypictures.blogspot.com)
Preparation
For this assignment, you need to create a CSV file containing some information about people and dogs. Create a csv file called peopledog.csv in the same folder where you keep your python programs, and save the following lines in it:
Joe, 23, Fido, vaccinated Debra, 30, Rex, not vaccinated Frida, 10, Ralph, vaccinated Maria, 21, Gizmo, vaccinated Frank, 31, , Millie, 25, Maxi, not vaccinated
- The information above contains the name and age of people, and the name of their dog, as well as its vaccinated status, if they own a dog. If they do not own a dog, then their age is followed by two empty strings (see Frank above).
The Main Program
Create a new program with the code below. Call it hw9_2.py.
# hw9_2start.py # your name here # This program maintains 2 classes, one for a person # and the other for a dog. # A person object is defined by a name, an age, and a dog. # If a person does not own a dog, then that person's dog field is set to None. # A dog is defined by a tag (its name) and a boolean indicating if it is # vaccinated or not. # The main program outputs various lists of people. # class Person: # a class containing 4 private member variables: # - name of the person (string) # - age (integer) # - gpa (float) # - major (string, uppercase) # methods: # getName(): returns the name of the person (string) # getAge(): returns the age of the person (int) # setAge(x): sets the age of the person to x (int) # constructor: intializes a person with all fields def __init__(self, n, a, dg ): self.name = n self.age = a self.dog = dg def getDog( self ): return self.dog # returns a string with the name and age. def __str__( self ): return "{0:1}, {1:1} years old".format( self.name, self.age ) # returns the name def getName( self ): return self.name # set the age to a new value x def setAge( self, x ): self.age = x # returns the age of the person def getAge( self ): return self.age class Dog: # a class containing 2 private member variables: # - name-tag of the dog (string) # - whether the dog is vaccinated or not (boolean) # methods: # isVaccinated(): returns True if the dog is vaccinated, False otherwise # getName(): returns the name-tag of the dog # setName(x): sets the name-tag of the dog # constructor def __init__( self, tag, vaccinated ): self.tag = tag self.vaccinated = vaccinated # default string representation for the dog def __str__( self ): if self.vaccinated==True: return "{0:1} (vaccinated)".format( self.tag ) return "{0:1} (not vaccinated)".format( self.tag ) # isVaccinated: returns True if the dog is vaccinated, False otherwise def isVaccinated( self ): return self.vaccinated # returns the name of the dog def getNameTag( self ): return self.tag # changes the name-tag def setNameTag( self, tag ): self.tag = tag # readCSVFile. Reads the contents of a CSV file and return # a list of strings containing all the lines. def readCSVFile( fileName ): file = open( fileName, "r" ) lines = file.readlines() file.close() return lines # ================================================ # main # ================================================ def main(): # get the contents of the file lines = readCSVFile( "peopledog.csv" ) # create a list of people, and their dog (if they own one) people = [] # parse the text and add it as people-dog pairs in the list for line in lines: # reject lines that are not formatted correctly if len( line.split(',') ) != 4: continue # parse line name, age, tag, vacc = line.split(',') name = name.strip() age = int( age.strip() ) tag = tag.strip() vacc = "not" not in vacc.lower() if len( tag )==0: p = Person(name, age, None ) else: p = Person(name, age, Dog( tag, vacc ) ) # add this new person to the list people.append( p ) # Display the list for person in people: if person.getDog() != None: print( person, ", has a dog: ", person.getDog(), sep="" ) else: print( person, ", does not have a dog", sep="" ) main()
- Run the program. Verify that it outputs a list of people and dogs, nicely formatted.
Your Assignment
- Modify the main program only (not the classes), so that your new program will output:
- the list of people who have unvaccinated dogs
- the list of people without dogs
- the oldest person who has a dog
- Your output should match exactly the output of the solution program, so play close attention to the formatting of your output.
- The output of the solution program for three different csv files are shown in the section below.
Store your program in a file called hw9_2.py and submit it to Moodle, in the HW9 PB2 section.
Example Outputs for Different CSV Files (added 4/4/15)
------------ Example 1 ------------------ peopledog.csv file Joe, 23, Fido, vaccinated Debra, 30, Rex, vaccinated Frida, 10, Ralph, vaccinated Maria, 21, Gizmo, not vaccinated Frank, 31, , Millie, 25, Maxi, vaccinated Output of the Solution Program Joe, 23 years old, has a dog: Fido (vaccinated) Debra, 30 years old, has a dog: Rex (vaccinated) Frida, 10 years old, has a dog: Ralph (vaccinated) Maria, 21 years old, has a dog: Gizmo (not vaccinated) Frank, 31 years old, does not have a dog Millie, 25 years old, has a dog: Maxi (vaccinated) Maria, 21 years old, has a dog: Gizmo (not vaccinated) Frank, 31 years old, does not have a dog Debra, 30 years old, is the oldest person owning a dog. ------------ Example 2 ------------------ peopledog.csv file Joe, 23, Fido, vaccinated Debra, 30, Rex, not vaccinated Frida, 10, Ralph, vaccinated Maria, 21, Gizmo, vaccinated Millie, 25, Maxi, not vaccinated Output of the Solution Program Joe, 23 years old, has a dog: Fido (vaccinated) Debra, 30 years old, has a dog: Rex (not vaccinated) Frida, 10 years old, has a dog: Ralph (vaccinated) Maria, 21 years old, has a dog: Gizmo (vaccinated) Millie, 25 years old, has a dog: Maxi (not vaccinated) Debra, 30 years old, has a dog: Rex (not vaccinated) Millie, 25 years old, has a dog: Maxi (not vaccinated) Debra, 30 years old, is the oldest person owning a dog. ------------ Example 3 ------------------ peopledog.csv file Joe, 23, , Debra, 30, , Frida, 10, , Maria, 21, , Frank, 31, , Millie, 25, , Output of the Solution Program Joe, 23 years old, does not have a dog Debra, 30 years old, does not have a dog Frida, 10 years old, does not have a dog Maria, 21 years old, does not have a dog Frank, 31 years old, does not have a dog Millie, 25 years old, does not have a dog Joe, 23 years old, does not have a dog Debra, 30 years old, does not have a dog Frida, 10 years old, does not have a dog Maria, 21 years old, does not have a dog Frank, 31 years old, does not have a dog Millie, 25 years old, does not have a dog Nobody in the list has dogs.
</showafterdate>
<showafterdate after="20150408 00:00" before="20150601 00:00">
Solution Programs
Part 1
# hw9_1sol.py # Originally by Joyce Xue ( aa ) # (slightly edited by D. Thiebaut) # 04.15.2014 # # This program contains a class Cat that describe a cat with its name, age, # being vaccinated or not, being neutered or not and breed # # To create an object of this type, simply use the constructor, as follows: # # cat = Cat(name, age, vaccinated, neutered, breed) # # The methods supported are: # # isVaccinated(): returns if the cat is vaccinated # # isNeutered(): returns the name of the planet with the largest diameter # # __str__(): convert the object to a string # ------------------------------------------------------------------------------------------------------ class Cat: # contructor. Initialize all memebers. def __init__( self,name, age, vaccinated, neutered, breed): self._name=name self._age=age self._vac=vaccinated self._neu=neutered self._breed=breed #================================================================== # __str__() : When call print(cat), this function # automatically converts the cat to a string #================================================================== def __str__(self): # make up the return string by following the required format temp = "Cat: "+self._name+","+" age: "+str(self._age)+", " # convert boolean value to string if self._vac: temp=temp+"vaccinated, " else: temp=temp+"not vaccinated, " if self._neu: temp=temp+"neutered " else: temp=temp+"not neutered " temp=temp+"("+self._breed+")" return temp #================================================================== # isVaccinated(): return if the cat is vaccinated #================================================================== def isVaccinated(self): return self._vac #================================================================== # isNeutered(): return if the cat is neutered #================================================================== def isNeutered(self): return self._neu #================================================================== # getNewCat(): ask for user input to create a new # cat and return it #================================================================== def getNewCat(): # user input for name, age, if vaccinated, if neutered and breed print( "\nPlease enter the information for the new cat:") name = input( "Cat name? " ) age = int( input( "Age, in years? " ) ) vac = input( "Vaccinated (Y/N)? " ).strip().lower() vac = vac in ['y', 'yes'] neut = input( "Neutered (Y/N)? " ).strip().lower() neut = neut in ['y', 'yes' ] breed= input( "Breed? " ).strip() return Cat( name, age, vac, neut, breed ) #================================================================== # display(): print each cat in a Cat collection # L - a list of cats # caption - the subject of the list to be printed #================================================================== def display( L, caption ): # print the subject print( "\n\n"+caption ) print( "=" * len( caption ) ) # go over the list and print each cat's info for cat in L: print( cat ) #================================================================== # main(): # * creates a list of cat objects, displays it. # #================================================================== def main(): # get the contents of cats.csv file = open( "cats2.csv", "r" ) text = file.read() file.close() # use the text as the initial data, generate cats for line in text.split( "\n" ): # split each line into items words = line.strip().split( "," ) # if data is not exactly 5, skip if len( words ) != 5: continue # set items to variables name, age, vaccinated, neutered, breed = words # convert age to int age = int( age.strip() ) # convert user inputs to booleans if vaccinated.strip().lower() == "yes": vaccinated = True else: vaccinated = False neutered = neutered.strip().lower() == "yes" # construct a cat cat = Cat( name.strip(), age, vaccinated, neutered, breed.strip() ) try: # add the cat to the list cats.append( cat ) except NameError: # if the cats list is not initialized, initialize it and append the first cat cats = [] cats.append( cat ) # output the cat list display( cats, "List of cats:" ) # Go through each cat and add those who is both vaccinated and neutered into a list vaccinatedNeuteredCats = [] for cat in cats: if cat.isVaccinated() and cat.isNeutered(): vaccinatedNeuteredCats.append( cat ) # output the cats in this new list (both vaccinated and neutered) display( vaccinatedNeuteredCats, "Vaccinated and neutered cats:" ) # Main entry point for the program main()
Part 2
# hw9_2start.py # your name here # This program maintains 2 classes, one for a person # and the other for a dog. # A person object is defined by a name, an age, and a dog. # If a person does not own a dog, then that person's dog field is set to None. # A dog is defined by a tag (its name) and a boolean indicating if it is # vaccinated or not. # The main program outputs various lists of people. # class Person: # a class containing 4 private member variables: # - name of the person (string) # - age (integer) # - gpa (float) # - major (string, uppercase) # methods: # getName(): returns the name of the person (string) # getAge(): returns the age of the person (int) # setAge(x): sets the age of the person to x (int) # constructor: intializes a person with all fields def __init__(self, n, a, dg ): self.name = n self.age = a self.dog = dg def getDog( self ): return self.dog # returns a string with the name and age. def __str__( self ): return "{0:1}, {1:1} years old".format( self.name, self.age ) # returns the name def getName( self ): return self.name # set the age to a new value x def setAge( self, x ): self.age = x # returns the age of the person def getAge( self ): return self.age class Dog: # a class containing 2 private member variables: # - name-tag of the dog (string) # - whether the dog is vaccinated or not (boolean) # methods: # isVaccinated(): returns True if the dog is vaccinated, False otherwise # getName(): returns the name-tag of the dog # setName(x): sets the name-tag of the dog # constructor def __init__( self, tag, vaccinated ): self.tag = tag self.vaccinated = vaccinated # default string representation for the dog def __str__( self ): if self.vaccinated==True: return "{0:1} (vaccinated)".format( self.tag ) return "{0:1} (not vaccinated)".format( self.tag ) # isVaccinated: returns True if the dog is vaccinated, False otherwise def isVaccinated( self ): return self.vaccinated # returns the name of the dog def getNameTag( self ): return self.tag # changes the name-tag def setNameTag( self, tag ): self.tag = tag # readCSVFile. Reads the contents of a CSV file and return # a list of strings containing all the lines. def readCSVFile( fileName ): file = open( fileName, "r" ) lines = file.readlines() file.close() return lines # ================================================ # main # ================================================ def main(): # get the contents of the file lines = readCSVFile( "peopledog.csv" ) # create a list of people, and their dog (if they own one) people = [] # parse the text and add it as people-dog pairs in the list for line in lines: # reject lines that are not formatted correctly if len( line.split(',') ) != 4: continue # parse line name, age, tag, vacc = line.split(',') name = name.strip() age = int( age.strip() ) tag = tag.strip() vacc = "not" not in vacc.lower() if len( tag )==0: p = Person(name, age, None ) else: p = Person(name, age, Dog( tag, vacc ) ) # add this new person to the list people.append( p ) # Display the list for person in people: if person.getDog() != None: print( person, ", has a dog: ", person.getDog(), sep="" ) else: print( person, ", does not have a dog", sep="" ) print() # Display the list of people with unvaccinated dogs for person in people: if person.getDog() != None and person.getDog().isVaccinated()==False: print( person, ", has a dog: ", person.getDog(), sep="" ) print() # Display the list of people without dogs for person in people: if person.getDog() == None: print( person, ", does not have a dog", sep="" ) print() # display the oldest person who has a dog oldest = None oldestAge = 0 for person in people: if person.getAge() > oldestAge: oldestAge = person.getAge() oldest = person if oldest.getDog()==None: print( "Nobody in the list has dogs." ) else: print( oldest, ", is the oldest person owning a dog." ) main()
</showafterdate>