5.6. Solutions: Lecture 5#
5.6.1. Exercise 5.1#
fraction.py
#!/usr/bin/python
'''
a simple class to handle fractions of integer numbers
'''
from math import gcd
import sys
def lcm (a, b) :
'''
least common multiple
'''
return a * b / gcd (a,b)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
class Fraction :
'''
a simple class implementing a high-level object
to handle fractions and their operations
'''
def __init__ (self, numerator, denominator) :
'''
the constructor: initialises all the variables needed
for the high-level object functioning
'''
if denominator == 0 :
print ('Denominator cannot be zero')
sys.exit (1)
# this allows to avoid calculating the LCM in the sum and subtraction
common_divisor = gcd (numerator, denominator) # greatest common divisor
self.numerator = numerator // common_divisor
self.denominator = denominator // common_divisor
def print (self) :
'''
prints the value of the fraction on screen
'''
print (str (self.numerator) + '/' + str (self.denominator))
def ratio (self) :
'''
calculates the actual ratio between numerator and denominator,
practically acting as a casting to float
'''
return self.numerator / self.denominator
def __add__ (self, other) :
'''
implements the addition of two fractions.
Note that this function will be callable with the + symbol
in the program
'''
new_numerator = self.numerator * other.denominator + other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __sub__ (self, other) :
'''
implements the subtraction of two fractions.
Note that this function will be callable with the - symbol
in the program
'''
new_numerator = self.numerator * other.denominator - other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __mul__ (self, other) :
'''
implements the multiplications of two fractions.
Note that this function will be callable with the * symbol
in the program
'''
new_numerator = self.numerator * other.numerator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __truediv__ (self, other) :
'''
implements the ratio of two fractions.
Note that this function will be callable with the / symbol
in the program
'''
if other.numerator == 0 :
print ('Cannot divide by zero')
sys.exit (1)
new_numerator = self.numerator * other.denominator
new_denominator = self.denominator * other.numerator
return Fraction (new_numerator, new_denominator)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_1 () :
'''
Function to test the class behaviour, called in the main program, ex. 2
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac1.print ()
print ('numerator: ', frac1.numerator )
print ('denominator: ', frac1.denominator )
print ('ratio: ', frac1.ratio ())
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_2 () :
'''
Function to test the class behaviour, called in the main program, ex. 3
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac2 = Fraction (1, 2)
frac1.print ()
frac2.print ()
sum_frac = frac1 + frac2
print ('\nSum :')
sum_frac.print ()
diff_frac = frac1 - frac2
print ('\nDifference:')
diff_frac.print ()
prod_frac = frac1 * frac2
print ('\nProduct:')
prod_frac.print ()
div_frac = frac1 / frac2
print ('\nDivision:')
div_frac.print ()
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__" :
testing_1 ()
testing_2 ()
5.6.2. Exercise 5.2#
fraction.py
#!/usr/bin/python
'''
a simple class to handle fractions of integer numbers
'''
from math import gcd
import sys
def lcm (a, b) :
'''
least common multiple
'''
return a * b / gcd (a,b)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
class Fraction :
'''
a simple class implementing a high-level object
to handle fractions and their operations
'''
def __init__ (self, numerator, denominator) :
'''
the constructor: initialises all the variables needed
for the high-level object functioning
'''
if denominator == 0 :
print ('Denominator cannot be zero')
sys.exit (1)
# this allows to avoid calculating the LCM in the sum and subtraction
common_divisor = gcd (numerator, denominator) # greatest common divisor
self.numerator = numerator // common_divisor
self.denominator = denominator // common_divisor
def print (self) :
'''
prints the value of the fraction on screen
'''
print (str (self.numerator) + '/' + str (self.denominator))
def ratio (self) :
'''
calculates the actual ratio between numerator and denominator,
practically acting as a casting to float
'''
return self.numerator / self.denominator
def __add__ (self, other) :
'''
implements the addition of two fractions.
Note that this function will be callable with the + symbol
in the program
'''
new_numerator = self.numerator * other.denominator + other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __sub__ (self, other) :
'''
implements the subtraction of two fractions.
Note that this function will be callable with the - symbol
in the program
'''
new_numerator = self.numerator * other.denominator - other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __mul__ (self, other) :
'''
implements the multiplications of two fractions.
Note that this function will be callable with the * symbol
in the program
'''
new_numerator = self.numerator * other.numerator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __truediv__ (self, other) :
'''
implements the ratio of two fractions.
Note that this function will be callable with the / symbol
in the program
'''
if other.numerator == 0 :
print ('Cannot divide by zero')
sys.exit (1)
new_numerator = self.numerator * other.denominator
new_denominator = self.denominator * other.numerator
return Fraction (new_numerator, new_denominator)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_1 () :
'''
Function to test the class behaviour, called in the main program, ex. 2
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac1.print ()
print ('numerator: ', frac1.numerator )
print ('denominator: ', frac1.denominator )
print ('ratio: ', frac1.ratio ())
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_2 () :
'''
Function to test the class behaviour, called in the main program, ex. 3
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac2 = Fraction (1, 2)
frac1.print ()
frac2.print ()
sum_frac = frac1 + frac2
print ('\nSum :')
sum_frac.print ()
diff_frac = frac1 - frac2
print ('\nDifference:')
diff_frac.print ()
prod_frac = frac1 * frac2
print ('\nProduct:')
prod_frac.print ()
div_frac = frac1 / frac2
print ('\nDivision:')
div_frac.print ()
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__" :
testing_1 ()
testing_2 ()
5.6.3. Exercise 5.3#
fraction.py
#!/usr/bin/python
'''
a simple class to handle fractions of integer numbers
'''
from math import gcd
import sys
def lcm (a, b) :
'''
least common multiple
'''
return a * b / gcd (a,b)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
class Fraction :
'''
a simple class implementing a high-level object
to handle fractions and their operations
'''
def __init__ (self, numerator, denominator) :
'''
the constructor: initialises all the variables needed
for the high-level object functioning
'''
if denominator == 0 :
print ('Denominator cannot be zero')
sys.exit (1)
# this allows to avoid calculating the LCM in the sum and subtraction
common_divisor = gcd (numerator, denominator) # greatest common divisor
self.numerator = numerator // common_divisor
self.denominator = denominator // common_divisor
def print (self) :
'''
prints the value of the fraction on screen
'''
print (str (self.numerator) + '/' + str (self.denominator))
def ratio (self) :
'''
calculates the actual ratio between numerator and denominator,
practically acting as a casting to float
'''
return self.numerator / self.denominator
def __add__ (self, other) :
'''
implements the addition of two fractions.
Note that this function will be callable with the + symbol
in the program
'''
new_numerator = self.numerator * other.denominator + other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __sub__ (self, other) :
'''
implements the subtraction of two fractions.
Note that this function will be callable with the - symbol
in the program
'''
new_numerator = self.numerator * other.denominator - other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __mul__ (self, other) :
'''
implements the multiplications of two fractions.
Note that this function will be callable with the * symbol
in the program
'''
new_numerator = self.numerator * other.numerator
new_denominator = self.denominator * other.denominator
return Fraction (new_numerator, new_denominator)
def __truediv__ (self, other) :
'''
implements the ratio of two fractions.
Note that this function will be callable with the / symbol
in the program
'''
if other.numerator == 0 :
print ('Cannot divide by zero')
sys.exit (1)
new_numerator = self.numerator * other.denominator
new_denominator = self.denominator * other.numerator
return Fraction (new_numerator, new_denominator)
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_1 () :
'''
Function to test the class behaviour, called in the main program, ex. 2
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac1.print ()
print ('numerator: ', frac1.numerator )
print ('denominator: ', frac1.denominator )
print ('ratio: ', frac1.ratio ())
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def testing_2 () :
'''
Function to test the class behaviour, called in the main program, ex. 3
'''
print ('Initial fractions:')
frac1 = Fraction (3, 4)
frac2 = Fraction (1, 2)
frac1.print ()
frac2.print ()
sum_frac = frac1 + frac2
print ('\nSum :')
sum_frac.print ()
diff_frac = frac1 - frac2
print ('\nDifference:')
diff_frac.print ()
prod_frac = frac1 * frac2
print ('\nProduct:')
prod_frac.print ()
div_frac = frac1 / frac2
print ('\nDivision:')
div_frac.print ()
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__" :
testing_1 ()
testing_2 ()
5.6.4. Exercise 5.4#
fraction.py
#!/usr/bin/python
'''
* Write a python program that reads the sample file [```eventi_gauss.txt```](https://github.com/UnimibFisicaLaboratori/UnimibFisicaLabStatPython/blob/main/book/lectures/Lecture_03/exercises/eventi_gauss.txt):
of Exercise 3.3 and, using the map function,
creates the distribution of the squares and cubes of random Gaussian numbers, respectively,
using `lambda` functions in the process.
* Plot the distribution of them, together with the original sample one, all in the same frame.
'''
import sys
import matplotlib.pyplot as plt
import numpy as np
from math import ceil, floor
def sturges (N_events) :
return ceil (1 + np.log2 (N_events))
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def main () :
'''
Function implementing the main program
'''
# read the file
with open ('../../Lecture_03/exercises/eventi_gauss.txt') as input_file :
sample = [float (x) for x in input_file.readlines ()]
for elem in sample[:10]:
print (elem)
sample_sq = list (map (lambda x: x**2, sample))
sample_cu = list (map (lambda x: pow (x, 3), sample))
xMin = floor (min (min (sample), min (sample_sq), min (sample_cu)))
xMax = ceil (max (max (sample), max (sample_sq), max (sample_cu)))
N_bins = sturges (len (sample)) * 5
bin_edges = np.linspace (xMin, xMax, N_bins)
fig, ax = plt.subplots (nrows = 1, ncols = 1)
ax.hist (sample,
bins = bin_edges,
color = 'orange',
histtype= 'stepfilled'
)
ax.hist (sample_sq,
bins = bin_edges,
color = 'red',
histtype= 'step'
)
ax.hist (sample_cu,
bins = bin_edges,
color = 'blue',
histtype= 'step'
)
ax.set_yscale ('log')
ax.set_title ('Histogram example', size=14)
ax.set_xlabel ('variable')
ax.set_ylabel ('event counts per bin')
plt.savefig ('ex_4.5.png')
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__" :
main ()
5.6.5. Exercise 5.5#
fraction.py
#!/usr/bin/python
'''
* Write a python program that reads the sample file [```eventi_gauss.txt```](https://github.com/UnimibFisicaLaboratori/UnimibFisicaLabStatPython/blob/main/book/lectures/Lecture_03/exercises/eventi_gauss.txt):
of Exercise 3.3 and, using the map function,
creates the distribution of the squares and cubes of random Gaussian numbers, respectively,
using `lambda` functions in the process.
* Plot the distribution of them, together with the original sample one, all in the same frame.
'''
import sys
import matplotlib.pyplot as plt
import numpy as np
from math import ceil, floor
def sturges (N_events) :
return ceil (1 + np.log2 (N_events))
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
def main () :
'''
Function implementing the main program
'''
# read the file
with open ('../../Lecture_03/exercises/eventi_gauss.txt') as input_file :
sample = [float (x) for x in input_file.readlines ()]
for elem in sample[:10]:
print (elem)
sample_sq = list (map (lambda x: x**2, sample))
sample_cu = list (map (lambda x: pow (x, 3), sample))
xMin = floor (min (min (sample), min (sample_sq), min (sample_cu)))
xMax = ceil (max (max (sample), max (sample_sq), max (sample_cu)))
N_bins = sturges (len (sample)) * 5
bin_edges = np.linspace (xMin, xMax, N_bins)
fig, ax = plt.subplots (nrows = 1, ncols = 1)
ax.hist (sample,
bins = bin_edges,
color = 'orange',
histtype= 'stepfilled'
)
ax.hist (sample_sq,
bins = bin_edges,
color = 'red',
histtype= 'step'
)
ax.hist (sample_cu,
bins = bin_edges,
color = 'blue',
histtype= 'step'
)
ax.set_yscale ('log')
ax.set_title ('Histogram example', size=14)
ax.set_xlabel ('variable')
ax.set_ylabel ('event counts per bin')
plt.savefig ('ex_4.5.png')
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
if __name__ == "__main__" :
main ()