代做ELEC0021 Programming 2023-24代写留学生Python程序

- 首页 >> C/C++编程

ELEC0021 Programming 2023-24

1st PROGRAMMING ASSIGNMENT – Part 1A

Virtual Dice Throwing

This is an introductory programming exercise in order to refresh your last year’s knowledge of programming and get you introduced to Python. The program to write should emulate virtual dice throwing. It should get from the keyboard the number of sides of the virtual dice and the number  of times  to be  thrown,  the  latter  should  be  a  multiple  of the  number  of  sides.  The program should then throw the dice and print out the number of times each side occurred. Given that random numbers will be used, you  should be  able to  see that the higher the number  of throws, the closer the results will be towards approximately equal occurrence of all sides (same probability).  The  program  should  deal  gracefully  with  incorrect  type  of  arguments  through checks and exceptions.

This program can be in fact an extension of the coin thrower program which can be found on the Week 2 Random Number Generation lecture material. You may implement it in a similar manner to the coin thrower program, i.e. if any user input is incorrect you could print out a diagnostic message and terminate the program. But the most sophisticated implementation is one in which you keep asking the user for a correct value when her input is wrong. In this case, you could use separate functions getNFaces() and getNThrows(nfaces) which use a loop to get the  value  correctly – see for example the getNDataFromKeyboard() static method of assignment part 1B.

You should start working on this assignment in the first lab session of the week commencing 15 January.

1st PROGRAMMING ASSIGNMENT – Part 1B

Calculating the Mean and Variance of a Data Set – “the Long Way

This is another introductory programming exercise so that you start getting familiar with some more  sophisticated  aspects  of  Python.  “The  long  way”  is  mentioned  above  because   the description  of this  assignment  also  serves  as   a  tutorial  introduction to various   aspects  of structured and object-oriented programming in Python, and for this reason this description is 5 pages long. It also includes a good part of the assignment already implemented in order to show how things should be done properly. So please go through this description very carefully as it constitutes effectively an additional complementary lecture.

The program to be developed in this exercise should calculate the mean and variance of a set of numbers,  i.e.  “the  data  set”.  This  is  something  that  could  be  easily  done  in  C  through  a program that would have the following structure: two C functions mean and variance and a main program that initialises an array of numbers, invokes the two functions bypassing to them the array as parameter and prints the respective results. The “signature” of the two functions would be the following:

float mean      (int ndata, float data[])

float variance (int ndata, float data[])

Note that in C we need to pass the size of the array, i.e. ndata, as a separate parameter, as the array is effectively only a pointer to its first element, no more than that.

We could write a similar program in Python by mirroring exactly the structure of the C program, but given that this year you will learn about object-oriented (O-O) programming, we will do it slightly differently. We will create a reusable class for the data set which will include various functions (or, more precisely, methodsin O-O terminology) for initialising the data in a number of ways: by getting it from the keyboard, by generating random values in a particular specified range or by reading the data values from a file. After the assignment, this class could be put aside and be possibly used in other contexts.

We will also write the mean and variance functions, which in Python will have the following simpler signature:

def mean (data)

def variance (data)

Finally, we will write a main program which will allow the initialisation of the data  set in a number of ways and will then compute the mean and standard deviation.

We are now ready to implement our first simple object-oriented class and program in Python in  an incremental manner,  showing  basic  parts  of it  and  its  overall  layout  but  omitting  the complete implementation, which you should do.

import random # for Random class methods in the full version

class NumberList:

def__init__ (self): # the class constructor

self.__data = [] # initialises the __data “private” instance variable to an empty list

def getData (self):

return self.__data;            # returns the contained data list to users of the class

def setData (self, data): # initialises the list with “externally-created” data

self.__data = data

# end class

def mean (data):

# function implementation goes here, you should do this

def variance (data):

# function implementation goes here, you should do this

def main ():

mydata = [0.1, 1.1, 2.1, 3.1, 4.1]      # hardcoded data set values, list with 5 elements

nlist = NumberList()                        # create new empty NumberList object instance

nlist.setData(mydata)                       # fill it in with the data set

print("Numbers: " + str(nlist.getData()))                  # print the data set

print("Mean: " + str(mean(nlist.getData())))               # calculate and print mean

print("Variance: " + str(variance(nlist.getData())))  # calculate and print variance

if__name__ == "__main__":

main()

Note: in the main function above we could have passed directly mydata to the mean & variance functions. But we did it in an object-oriented manner by creating a NumberList object instance which contains mydata and then retrieved the contained data using the getData() method in order to to pass it to the mathematical functions. In a more complex program, such a data set object could have been created and filled in elsewhere and passed as parameter to a function in order to calculate the data set mean & variance, so we used this more general approach.

We have now implemented our first Python program which calculates the mean and variance of a data  set with  “hard-coded”  values, with the  data  set  implemented  in  an  object-oriented manner through the NumberList class. It would be nice to extend this class to be able to get the data set  size and values in various ways: by a human user from the keyboard, by randomly producing the values within  a particular range, or by reading a  file which  contains the  data values, one per line.

Considering  the  data-from-keyboard  approach,  we  introduce  the  getNDataFromKeyboard() method which will read the number of data elements expected from the keyboard. It will also need to check that the number specified by the user is >= 2 as otherwise there is no point in running the program. This method should be private, given that it will be only called by another class method getDataFromKeyboard() which we will subsequently introduce. Hence we name the  former  __  getNDataFromKeyboard()  according to  the Python  convention   for  naming private class members. We include the complete method implementation overleaf.

# additional NumberList class methods

def__getNDataFromKeyboard (self):  # “private” method names in Python start with __ print("Enter the number of data set elements: ")

ndata = 0

gotNDataCorrectly = False              # a flag to loop until we get ndata correctly

while gotNDataCorrectly == False:

try:

ndata = float(input())                # read from the keyboard, accept also strings & convert

if ndata % 1 == 0 and ndata >= 2:     # check for integer input >= 2

gotNDataCorrectly = True

else:

print("__getNDataFromKeyboard: ndata should be >=2")

except (ValueError, SyntaxError):

print("__getNDataFromKeyboard: ndata should be an integer!")

# end while loop

return int(ndata)  # return ndata as int

def getDataFromKeyboard (self):

ndata = self.__getNDataFromKeyboard()

# here you should write code that gets exactly ndata numbers from the keyboard # and adds them to the __data instance variable using the list append method;

# you will need a while loop in similar fashion to __getNDataFromKeyboard

Note that the getNDataFromKeyboard method does not use the __data instance variable. It could be made in fact a static class method, static methods are those that do not have access to the class instance variables and, in fact, can be called without creating an object instance by simply preceding them with the class name, e.g. NumberList. getNDataFromKeyboard(). In order to make this method static, we need to use the @staticmethod decorator and in this case the  method  would  not  take  the  self parameter  while  everything else would stay the same. Although it does not make any difference when running the program, it is better programming practice and you should do it that way.

@staticmethod         # this decorator tells the interpreter that the following method is static

def__getNDataFromKeyboard ():  # note the absence of self, static methods do not have it # normal method implementation follows

Let’s now introduce the getRandomData(ndata, range1, range2) method which will produce a random data set in [range1..range2). In Python, random numbers in [0..1) are produced by the random() method of the Random class which is accessible through the “hidden” random object reference  - hidden means that it exists in the background without having to create it explicitly, i.e. random = Random(). See also lecture 2 on Random Number Generation.

By implementing this method, we will also get to learn another Python feature, that of optional parameters. By assigning the “default value” 0 to range2, it means that the range2 parameter maybe omitted by calling the method using getRandomData(ndata, range1) and its value will be  0;  the  method  will  then  produce  values  in  [0..range1). If  on  the  other  hand  the  range2 parameter  is  included  by using getRandomData(ndata, range1, range2), then the method should produce values in  [range1..range2); note  it should be range1 < range2, otherwise the method should print out an error message and do nothing. Also note that the parameters ndata, range1 and range2 could be either integers or stringified integers, e.g. 10 or “10”, and the method code should cater for both cases.

def getRandomData (self, ndata, range1, range2=0):

# here you should write code that first checks the validity of the parameters

# then sets two variables low and high according to the range1 and range2 values # and finally produces random values and adds them to __data using list append

Finally, we can also add a final method to our NumberList class to initialise the data set by reading values from a file. By doing this, you will learn some elementary file manipulation, although more elaborate file handling will be taught in the second part of the term. You should use the open function to open the file in read mode and then in a for loop you should go through every line of the file, using the strip method of every text line by doing strip(‘\n’) to remove any spaces and the newline character and convert the resulting value to float, making sure that you catch exceptions if the value cannot be converted. The signature of the method will be:

def getDataFromFile (self, fileName):

# method implementation follows

Having  introduced  all  these methods, we have now created a useful class NumberList.  It includes the methods getDataFromKeyboard, getRandomData and getDataFromFile which can be easily reused in different contexts, saving development time.

We can now rewrite our main program to use the getDatatFromKeyboard method and make it more flexible than using a fixed size list with hard-coded values, which we did before:

def main ():

nlist = NumberList()

nlist.getDataFromKeyboard()

print("Numbers: " + str(nlist.getData()))

print("Mean: " + str(mean(nlist.getData())))

print("Variance: " + str(variance(nlist.getData())))

We can also rewrite our main program to use either the getRandomDataSet or getDataFromFile methods; in the first case, we will hardwire the values for ndata and upper bound while in the second case we will hardwire the name of the data file. In order to save space, we use one main function in which as can comment in/out the right method accordingly:

def main ():

nlist = NumberList()

# this version uses getRandomData, could comment out and comment in getDataFromFile nlist.getRandomData2(5, 10)                 # produce 5 random values in the [0,  10) range

# nlist.getDataFromFile(“dataFile”)   # read values from file with name dataFile

print("Numbers: " + str(nlist.getData()))

print("Mean: " + str(mean(nlist.getData())))

print("Variance: " + str(variance(nlist.getData())))

So we implemented the two different main programs above in only a few lines of code by using the   class  NumberList   which  we   can reuse   anywhere.   A   key   aspect   of  object-oriented programming is to design and implement highly reusable classes and this exercise demonstrated the benefit of doing this.

But in order to also demonstrate some other aspects of Python and programming languages in general, we will create a more sophisticated version of the main program. This will combine the three options we used above; it will also allow the user to pass the size and low/high of the random data set from the command line. So when the program is invoked with no arguments at all it will get the values from the keyboard; when it is invoked with one argument this should be the name of a file and it will read the data from a file; and when it is invoked with two or three arguments, it should produce the data set values randomly.

Also as NumberList is a reusable class, we will leave it in file NumberList.py which we have used until now and we will put the more sophisticated main program described above in file MeanAndVariance.py - see implementation below.

from NumberList import NumberList     # NumberList class is in file NumberList.py import sys                                                 # for sys.argv and sys.exit()

def main ():

nlist = NumberList()      # create an empty NumberList instance

nargs = len(sys.argv)      # argv contains the program name and arguments, as in C

if nargs == 1:                 # no arguments, actually only the program name hence value  1

nlist.getDataFromKeyboard()

elifnargs == 2:                 # filename argument, get data from file

nlist.getDataFromFile(sys.argv[1])

elifnargs == 3 or nargs == 4:    # produce data set randomly

if nargs == 3:

nlist.getRandomData(sys.argv[1], sys.argv[2])

else:  # nargs = 4

nlist.getRandomData(sys.argv[1], sys.argv[2], sys.argv[3])

else:

print(“incorrect number of arguments, try again”);

sys.exit()                    # terminate program

print("Numbers: " + str(nlist.getData()))

print("Mean: " + str(mean(nlist.getData())))

print("Variance: " + str(variance(nlist.getData())))

By studying carefully the description of this assignment and by implementing this program you will  get  familiar  with  a  number of  Python   features  and  get  introduced to   object-oriented programming. As already stated in the beginning, the detailed description of this assignment serves  as  an  introductory  tutorial to   object-oriented  programming. Another  aspect   of  this assignment  is  that it introduces “incremental development”:  you  first implement a  simple program that works with a fixed size / hard-coded values data set, then extend it to work with a data set that the user provides from the keyboard, then extend it to also work by producing the data set randomly with a user-specified size and range; then extend it to also work by reading the data  set values  from  a  file;  and  finally enhance the main  function to  enable running the program with all these options.

1st PROGRAMMING ASSIGNMENT – Part 1C

Shape Inheritance

This exercise has the purpose first to get you to implement the Shape, Point, Circle and Cylinder classes as in the lecture notes in order to get to understand better, assimilate and actually code the inheritance features taught in the lectures. Although you can simply copy the code from the notes, it would be certainly more beneficial to write the code yourselves by looking at the notes in  order  to  realise  how  object-oriented  features  related  to  inheritance  are  exercised  and understand / assimilate the relevant principles. In addition to the classes in the notes, you should also   design   and   implement   the   following   shape  classes  exploiting   inheritance:    Sphere, Rectangle, Square and Cube.

Having  implemented  these  classes,  you  should  write a  program  which gets input from the user/keyboard to create an instance of any one of these. The user should be able to create as many of these  shapes  and  s/he wants.  The menu  should  also  allow the user to print  out the created objects, either selecting a particular one or printing all of them. The user should also be allowed to remove/delete an existing shape from the list. Finally, the user should be allowed to modify a particular shape. The program should print the objects it keeps by using only the Shape getName(),  toString(),   getArea()  and  getVolume()  methods,   i.e.  treating   all  these  objects “polymorphically” as “shapes”. Note that modifying a shape cannot be done polymorphically, specific  functions  will  be required to modify each type  of shape.  The program  should  deal gracefully with incorrect type of arguments through checks and exceptions.

ASSIGNMENT SUBMISSION AND EXAMINATION

You should also submit the following code files on Moodle by 9am on Monday 5 February:

1.   VDiceThrower.py - the virtual dice thrower program

2.   NumberList.py - the reusable NumberList class

3.   MeanAndVariance.py - the mean and variance program

4.   Shapes.py - the shape classes and the test program in one file

The file names above are indicative, you may use alternative names if you wish.

You should demonstrate the working programs to the lab TAs in a session during the week starting  5  February.  You  will  be also asked questions about your code.  Nicely structured, presented and commented code is very important and will affect the overall mark.


站长地图