Write a Python class that extends the Progression class sothat each value in the progression is the square root of theprevious value. (Note that you can no longer represent each valuewith an integer.) Your constructor should accept an optionalparameter specifying the start value, using 65,536 as adefault. 2. Develop an inheritance hierarchy based upon a Polygon classthat has abstract methods area( ) and perimeter( ). Implementclasses Triangle, Quadrilateral, Pentagon, Hexagon, and Octagonthat extend this base class, with the obvious meanings for thearea( ) and perimeter( ) methods. Also implement classes,IsoscelesTriangle, EquilateralTriangle, Rectangle, and Square, thathave the appropriate inheritance relationships. Finally, write asimple program that allows users to create polygons of the varioustypes and input their geometric dimensions, and the program thenoutputs their area and perimeter. 3. Write a Python class that extends the Progression class sothat each value in the progression is the absolute value of thedifference between the previous two values. You should include aconstructor that accepts a pair of numbers as the first two values,using 2 and 200 as the defaults. 4. Implement the mul method for the Vector class of Section2.3.3, so that the expression u v returns a scalar that representsthe dot product of the vectors, that is, ∑d i=1 ui · vi. 5. Our Range class, from Section 2.3.5, relies on the formulamax(0, (stop − start + step − 1) // step) to compute the number ofelements in the range. It is not immediately evident why thisformula provides the correct calculation, even if assuming apositive step size. Justify this formula, in your own words. Attached
The Correct Answer and Explanation is :
Certainly! Let’s address each of your tasks in detail.
1. Extending the Progression Class for Square Root Progression
To create a Python class that extends a Progression class where each value is the square root of the previous value, we can define a SqrtProgression class. Assuming the Progression class has an initializer that sets the first value and a method to advance to the next value, our subclass will override the method responsible for progressing to the next value.
Here’s how you can implement it:
import math
class Progression:
def __init__(self, start=1):
self.current = start
def advance(self):
self.current += 1
def __iter__(self):
return self
def __next__(self):
if self.current is None:
raise StopIteration()
else:
answer = self.current
self.advance()
return answer
class SqrtProgression(Progression):
def __init__(self, start=65536):
super().__init__(start)
def advance(self):
self.current = math.sqrt(self.current)
# Example usage:
sqrt_prog = SqrtProgression()
for _ in range(10):
print(next(sqrt_prog))
In this implementation:
- The
SqrtProgressionclass inherits fromProgression. - The
__init__method sets the starting value, defaulting to 65,536. - The
advancemethod updates the current value to its square root usingmath.sqrt().
2. Developing an Inheritance Hierarchy for Polygons
We’ll create an inheritance hierarchy based on a Polygon class with abstract methods area() and perimeter(). Then, we’ll implement specific polygon classes: Triangle, Quadrilateral, Pentagon, Hexagon, and Octagon. Further, we’ll define specialized classes like IsoscelesTriangle, EquilateralTriangle, Rectangle, and Square.
Here’s the implementation:
from abc import ABC, abstractmethod
class Polygon(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Triangle(Polygon):
def __init__(self, side1, side2, side3):
self.side1 = side1
self.side2 = side2
self.side3 = side3
def perimeter(self):
return self.side1 + self.side2 + self.side3
def area(self):
s = self.perimeter() / 2
return (s * (s - self.side1) * (s - self.side2) * (s - self.side3)) ** 0.5
class Quadrilateral(Polygon):
def __init__(self, side1, side2, side3, side4):
self.side1 = side1
self.side2 = side2
self.side3 = side3
self.side4 = side4
def perimeter(self):
return self.side1 + self.side2 + self.side3 + self.side4
def area(self):
# This is a placeholder; specific quadrilateral types should override this method
pass
class Rectangle(Quadrilateral):
def __init__(self, width, height):
super().__init__(width, height, width, height)
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
class IsoscelesTriangle(Triangle):
def __init__(self, equal_side, base):
super().__init__(equal_side, equal_side, base)
class EquilateralTriangle(Triangle):
def __init__(self, side):
super().__init__(side, side, side)
# Example usage:
shapes = [
EquilateralTriangle(3),
IsoscelesTriangle(5, 8),
Rectangle(4, 6),
Square(5)
]
for shape in shapes:
print(f"{shape.__class__.__name__} - Area: {shape.area()}, Perimeter: {shape.perimeter()}")
In this hierarchy:
Polygonis an abstract base class with abstract methodsarea()andperimeter().TriangleandQuadrilateralinherit fromPolygonand implement the required methods.RectangleandSquareinherit fromQuadrilateral, withSquarebeing a specializedRectangle.IsoscelesTriangleandEquilateralTriangleinherit fromTriangle.
3. Extending the Progression Class for Absolute Difference Progression
To create a progression where each value is the absolute difference between the previous two values, we can define a AbsDiffProgression class. This class will maintain the last two values and compute the next value as their absolute difference.
Here’s the implementation:
class AbsDiffProgression(Progression):
def __init__(self, first=2, second=200):
self.prev = first
self.current = second
def advance(self):
next_value = abs(self.current - self.prev)
self.prev = self.current
self.current = next_value
# Example usage:
abs_diff_prog = AbsDiffProgression()
for _ in range(10):
print(next(abs_diff_prog))
In this implementation:
- The
AbsDiffProgressionclass inherits fromProgression. - The
__init__method initializes the first two values, defaulting to 2 and 200. - The
advancemethod computes the next value as the absolute difference between the current and previous values.
4. Implementing the __mul__ Method for the Vector Class
To implement the __mul__ method for a Vector class to compute the dot product, we can define the method to take another Vector as an argument and return the sum of the products of corresponding components.
Here’s the implementation:
class Vector:
def __init__(self, components):
self.components = components
def __mul__(self, other):
if len(self.components) != len(other.components):
raise ValueError("Vectors must be of same length")
return sum(x * y for x, y in zip(self.components, other.components))
# Example usage:
v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])
print(v1 * v2) # Output: 32
In this implementation:
- The
Vectorclass has an initializer that takes a list of components. - The
__mul__method computes the dot product by multiplying corresponding components and summing the results.
5. Justifying the Formula in the Range Class
The formula max(0, (stop - start + step - 1) // step) is used to compute the number of elements in a range with a positive step size. Here’s a breakdown:
stop - start: Calculates the difference between the stop and start values.stop - start + step - 1: Adjusts the difference to ensure that any remainder when divided bystepis accounted for,