Introduction to Computer Science II
Homework 2
Due by 3:10pm on Tuesday, January 20
Reading
Read sections 8.1-3 and the first 31 slides of the week 2 PPT.
Problems
Solve the following by implementing the corresponding functions in homework2.py. When
done, submit that file through D2L.
1. You will augment the Point
class discussed in class by adding and implementing the following
methods:
- method distance(other) that takes another object of
type point and returns the distance between other and the point
invoking the method.
- methods up(), down(), left(),
and right() that move the point by one unit in the
specified direction. Your implementation must use the existing
method move rather than changing the instance
variables x and y directly.
- method equals(other) that takes another object of
type point and returns True if other and the point invoking the
method are equal (i.e., they have the same coordinates) and
False otherwise.
Usage:
>>> p = Point(1,4)
>>> q = Point(5,1)
>>> p.distance(q)
5.0
>>> q.distance(p)
5.0
>>> p.up()
>>> p.get()
(1, 5)
>>> p.down()
>>> p.left()
>>> p.right()
>>> p.get()
(1, 4)
>>> p.equals(q)
False
>>> q.move(-4,3)
>>> p.equals(q)
True
>>> q.get()
(1, 4)
2. Implement class Triangle that
models a triangle that is specified using three points in the plane.
The class uses the Point class above and it should support
the following methods:
- method __init__() that initializes the three
vertices of the Triangle object to the three Point
objects passed as arguments.
- method area() that computes and returns the area of
the triangle.
- method perimeter() that computes and returns the
perimeter of the triangle. Your implementation should use the Point
class method distance that you implemented in Problem
1.a.
Usage:
>>> p = Point()
>>> q = Point(0,4)
>>> r = Point(3,0)
>>> p.get()
(0, 0)
>>> t = Triangle(p, q, r)
>>> t.area()
6.0
>>> t.perimeter()
12.0
3. Develop a class BankAccount that
supports these methods:
- __init__(): Initializes the bank account balance to
the value of the input argument, or to 0 if no input
argument is given
- withdraw(): Takes an amount as input and withdraws it
from the balance
- deposit(): Takes an amount as input and adds it to
the balance
- balance(): Returns the balance on the account
Usage:
>>> x = BankAccount(700)
>>> x.balance()
700
>>> x.withdraw(70)
>>> x.balance()
630
>>> x.deposit(7)
>>> x.balance()
637
4. Develop a class Craps that allows
you to play craps on your computer. (The craps rules are described
in homework assignment 1.) Your class will support methods:
- __init__(): Starts by rolling a pair of dice. If the
value of the roll (i.e., the sum of the two dice) is 7
or 11, then a winning message is printed. If the value
of the roll is 2, 3, or 12, then a
losing message is printed. For all other roll values, a message
telling the user to throw for point is printed.
- forPoint(): Generates a roll of a pair of dice and,
depending on the value of the roll, prints one of three messages
as appropriate (and as shown):
Usage:
>>> c = Craps()
Throw total: 11. You won!
>>> c = Craps()
Throw total: 2. You lost!
>>> c = Craps()
Throw total: 5. Throw for Point.
>>> c.forPoint()
Throw total: 6. Throw for Point.
>>> c.forPoint()
Throw total: 5. You won!
>>> c = Craps()
Throw total: 4. Throw for Point.
>>> c.forPoint()
Throw total: 7. You lost!
5. Implement class Random that
implements a linear congruential pseudorandom number generator. In
other words, it is used to generate a sequence of pseudorandom
integers using a linear congruential generator approach.
The linear congruential method generates a sequence of numbers (or
seeds) starting from a given seed number x. Each number
(seed) in the sequence will be obtained by applying a (math)
function f (x) on the previous number (seed) x in
the sequence. The precise function f (x) is defined by three
numbers: a (the multiplier), c (the increment), and
m (the modulus):
f(x) = (ax + c) mod m
For example, if m = 31, a = 17, and c = 7,
the linear congruential method would generate the next sequence of
numbers (seeds) starting from seed x = 12:
12,25,29,4,13,11,8,19,20, . . .
because f (12) = 25, f (25) = 29, f (29) = 4,
and so on.
The class Random should support methods:
- __init__(): Constructor that takes as input the
values a, x, c, and m
and initializes the Pseudorandom object.
- rand(): Generates and returns the next number (seed)
in the pseudorandom sequence
Usage:
>>> r = Random(12, 17, 7, 31)
>>> r.rand()
25
>>> r.rand()
29
>>> r.rand()
4
>>> r.rand()
13
>>> r.rand()
11
6. The numbers 17, 7, and 31
used for a (the multiplier), c (the increment), and
m (the modulus) in the above example do not result in a good
pseudorandom number generator. Much better values, used by the gcc C
compiler library, are a=1103515245, c=12345, and m=231
(2 to the power 31). These number will generate pseudorandom numbers
in the range from 0 to 231-1
with very good "random properties". Also, while good for debugging
your implementation, it is inconvenient to have to provide a seed to
the pseudorandom number generator. Much better would be to use an
integer related to the current time, in nanoseconds. The time()
function in the Python standard library module time gives
the number of seconds since January 1, 1970:
>>> import time
>>> time.time()
1579100035.550304
>>> time.time()
1579100036.813396
To get the number of nanoseconds since January 1, 1970 as an integer
we need to multiply time.time() by a billion and convert
to int:
>>> int(time.time()*10**9)
1579099881394504960
>>> int(time.time()*10**9)
1579099882719621888
Modify your class Random so that default values, as
specified above, for the seed, the multiplier, the increment, and
the modulus are used when no values are passed when constructing the
Random object.
Usage:
>>> r = Random()
>>> r.rand()
1435472185
>>> r.rand()
2004247422
>>> r.rand()
1630335199
>>> r.rand()
592381941
(NOTE: because the seed will be a function of the current
time when executing the constructor, your output will necessarily
be different)
7. Augment your Random class with
two additional methods:
- randint(a, b) that returns a random integer in the
range from a to b (included), uniformly
distributed at random. Your implementation must use the existing
Random method rand() to generate a number
between 0 and 231-1 and
then perform some arithmetic operations on it to obtain a number
in the range from a to b. (Hint: use %
modulus operator)
- random() that returns a random float in the range
from 0 to 1 (not included), uniformly
distributed at random. Your implementation must use the existing
Random method rand() to generate a number
between 0 and 231-1 and
then perform some arithmetic operations on it to obtain a float
in the range from 0 to 1. (Hint: use / division operator)
Usage:
>>> r.randint(1, 6)
4
>>> r.randint(1, 6)
3
>>> r.randint(1, 6)
6
>>> r.randint(1, 6)
5
>>> r.randint(1, 6)
4
>>> r.random()
0.2017026348039508
>>> r.random()
0.4628330278210342
>>> r.random()
0.09002611227333546
>>> r.random()
0.34171303221955895
>>> r.random()
0.2796304449439049
>>> r.random()
0.9617379498668015
>>> r.random()
0.37306692358106375
>>> r.random()
0.5769595871679485
>>> r.random()
0.18874327652156353