Menu
Coddy logo textTech

סיכום – מחשבון צורות

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 27 מתוך 64.

challenge icon

אתגר

בינוני

באתגר הזה תממשו מערכת לחישוב צורות המדגימה פולימורפיזם.

ממשו את המחלקות הנדרשות בקבצים הבאים (חפשו הערות TODO בכל קובץ):

  • shape.py - הגדירו את מחלקת הבסיס המופשטת Shape
  • circle.py - ממשו את המחלקה Circle
  • rectangle.py - ממשו את המחלקה Rectangle
  • triangle.py - ממשו את המחלקה Triangle
  • unknownshape.py - צרו מחלקה שאינה יורשת ממחלקה אחרת ומדגימה duck typing
  • shapecalculator.py - ממשו את הפונקציונליות של המחשבון

פעלו לפי הערות TODO בכל קובץ לקבלת הנחיות שלב אחר שלב. חבילת הבדיקות המקיפה תעזור לכם להבין את ההתנהגות הצפויה ולוודא שהמימוש שלכם עומד בכל הדרישות.

נסו בעצמכם

from circle import Circle
from rectangle import Rectangle
from triangle import Triangle
from unknownshape import UnknownShape
from shapecalculator import ShapeCalculator
import math

# מטפל במקרי בדיקה
test_case = input()

def test_basic_functionality():
    calculator = ShapeCalculator()
    
    # בדיקה עם Circle
    circle = Circle(5)
    print(f"Testing {circle}")
    results = calculator.process_shape(circle)
    print(f"Results: {results}")
    print()
    
    # בדיקה עם Rectangle
    rectangle = Rectangle(4, 6)
    print(f"Testing {rectangle}")
    results = calculator.process_shape(rectangle)
    print(f"Results: {results}")
    print()
    
    # בדיקה עם Triangle
    triangle = Triangle(3, 4, 5)
    print(f"Testing {triangle}")
    results = calculator.process_shape(triangle)
    print(f"Results: {results}")
    print()
    
    # בדיקה עם UnknownShape (טיפוס ברווזי)
    unknown = UnknownShape("Custom", 10)
    print(f"Testing {unknown}")
    results = calculator.process_shape(unknown)
    print(f"Results: {results}")

def test_edge_cases():
    calculator = ShapeCalculator()
    
    # בדיקה עם ערכי אפס
    print("Testing zero values:")
    circle = Circle(0)
    print(f"Circle(0) area: {circle.area()}, perimeter: {circle.perimeter()}")
    
    rectangle = Rectangle(0, 5)
    print(f"Rectangle(0, 5) area: {rectangle.area()}, perimeter: {rectangle.perimeter()}")
    
    # בדיקה עם ערכים גדולים מאוד
    print("\
Testing large values:")
    large_circle = Circle(1000000)
    print(f"Circle(1000000) area: {large_circle.area():.2e}, perimeter: {large_circle.perimeter():.2e}")
    
    # בדיקה עם ערכים עשרוניים
    print("\
Testing decimal values:")
    decimal_circle = Circle(0.5)
    print(f"Circle(0.5) area: {decimal_circle.area()}, perimeter: {decimal_circle.perimeter()}")
    
    decimal_triangle = Triangle(2.5, 3.5, 4.5)
    print(f"Triangle(2.5, 3.5, 4.5) area: {decimal_triangle.area()}, perimeter: {decimal_triangle.perimeter()}")

def test_inheritance():
    # יצירת מופעים של כל צורה
    circle = Circle(5)
    rectangle = Rectangle(4, 6)
    triangle = Triangle(3, 4, 5)
    unknown = UnknownShape("Custom", 10)
    
    # בדיקת קשרי ירושה
    from shape import Shape
    print(f"Circle is a Shape: {isinstance(circle, Shape)}")
    print(f"Rectangle is a Shape: {isinstance(rectangle, Shape)}")
    print(f"Triangle is a Shape: {isinstance(triangle, Shape)}")
    print(f"UnknownShape is a Shape: {isinstance(unknown, Shape)}")
    
    # בדיקת זמינות המתודות
    print("\
Method availability:")
    for shape_name, shape_obj in [("Circle", circle), ("Rectangle", rectangle), 
                                ("Triangle", triangle), ("UnknownShape", unknown)]:
        print(f"{shape_name} has area(): {hasattr(shape_obj, 'area')}")
        print(f"{shape_name} has perimeter(): {hasattr(shape_obj, 'perimeter')}")
        print(f"{shape_name} has describe(): {hasattr(shape_obj, 'describe')}")

def test_polymorphism():
    calculator = ShapeCalculator()
    
    # יצירת רשימה של צורות שונות
    shapes = [
        Circle(5),
        Rectangle(4, 6),
        Triangle(3, 4, 5),
        UnknownShape("Custom", 10)
    ]
    
    print("Testing polymorphic behavior:")
    for i, shape in enumerate(shapes, 1):
        print(f"\
Shape {i}: {shape.__class__.__name__}")
        results = calculator.process_shape(shape)
        print(f"Results: {results}")

def test_duck_typing():
    calculator = ShapeCalculator()
    
    # יצירת מחלקה חדשה לגמרי עם המתודות הנדרשות
    class CustomDuckShape:
        def __init__(self, name, factor):
            self.name = name
            self.factor = factor
        
        def area(self):
            return self.factor * 3
        
        def perimeter(self):
            return self.factor * 12
        
        def describe(self):
            return f"This is a {self.name} duck-typed shape with area {self.area()} and perimeter {self.perimeter()}"
        
        def __str__(self):
            return f"Custom {self.name} with factor {self.factor}"
    
    # בדיקה עם הצורה המותאמת אישית בשיטת duck typing
    duck_shape = CustomDuckShape("DuckTyped", 5)
    print(f"Testing duck typing with: {duck_shape}")
    results = calculator.process_shape(duck_shape)
    print(f"Results: {results}")
    
    # השוואה לצורה רגילה
    circle = Circle(5)
    print(f"\
Comparing with regular shape: {circle}")
    results = calculator.process_shape(circle)
    print(f"Results: {results}")

def test_invalid_inputs():
    calculator = ShapeCalculator()
    
    try:
        # בדיקה עם רדיוס שלילי
        print("Testing Circle with negative radius:")
        negative_circle = Circle(-5)
        results = calculator.process_shape(negative_circle)
        print(f"Results: {results}")
    except Exception as e:
        print(f"Error with negative circle: {e}")
    
    try:
        # בדיקה עם משולש לא תקין (צלעות שאינן יכולות ליצור משולש)
        print("\
Testing invalid Triangle (1, 1, 10):")
        invalid_triangle = Triangle(1, 1, 10)  # מפר את אי־שוויון המשולש
        results = calculator.process_shape(invalid_triangle)
        print(f"Results: {results}")
        # בדיקה אם חישוב השטח מחזיר תוצאה תקינה
        area = invalid_triangle.area()
        if math.isnan(area) or not isinstance(area, float) or area <= 0:
            print(f"Invalid triangle area: {area}")
    except Exception as e:
        print(f"Error with invalid triangle: {e}")

# הרצת הבדיקה המתאימה לפי הקלט
if test_case == "basic_functionality":
    test_basic_functionality()
elif test_case == "edge_cases":
    test_edge_cases()
elif test_case == "inheritance":
    test_inheritance()
elif test_case == "polymorphism":
    test_polymorphism()
elif test_case == "duck_typing":
    test_duck_typing()
elif test_case == "invalid_inputs":
    test_invalid_inputs()
else:
    # מקרה בדיקה המוגדר כברירת מחדל
    test_basic_functionality()

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Python אונליין