Creare clasa fermier

Salut,

Ma puteti ajuta cu o continuare a urmatorului script?
Un fermier vrea sa stie suprafata totala a terenurilor lui, am presupus ca aceste terenuri au suprafete regulate (cerc, patrat, dreptunghi). Am facut o clasa pentru fiecare suprata dar nu stiu cum sa creez clasa fermier.

P.S. Daca un teren ar avea suprafata neregulata cum ar trebui sa creez clasa? Asta nu e ceva care arde, clasa Fermier e mai importanta.
Multumesc!

import math

class Circle:
    def __init__(self,radius):
        self.radius = radius
    
    def area_circle(self):
        return math.pi*(self.radius**2)

class Square:
    def __init__(self, side):
        self.side = side

    def area_square(self):
        return self.latura**2

class RightAngle:
    def __init__(self, width, length):
        self.width = width
        self.length = length
    
    def area_right_angle(self):
        return self.length * self.width

class Farmer:
     def __init__(self,):

Nu cred că e bine cum ai făcut, cum o sa aduni Circle cu Square, de exemplu?

Ar trebui ca fiecare clasa sa aiba o functie care sa se numeaasca la fel peste tot (de exemplu computeArea), care sa stie cum se calculeaza suprafața pentru propria-i formă.

Clasa Fermier probabil nu-i necesară, dar dacă ții neaparat, bănuiesc că ar trebui să permită să adaugi în ea diverse terenuri, de diverse forme.

Ar trebui sa fie ceva de genul asta:

class Fermier:
    def __init__(self):
        self.terenuri = []

    def adaugaTeren(self, teren):
        self.terenuri.append(teren)

    def totalSuprafata(self):
        total = 0
        for teren in self.terenuri:
            total += teren.computeArea()
       return total
fermier = Fermier()
fermier.adaugaTeren(Square(100))
fermier.adaugaTeren(Circle(200))

total_suprafata = fermier.totalSuprafata()
print('Total suprafata=', total_suprafata)

PS În C++ ar fi trebuit sa faci o clasa de baza de genul “TipSuprafata” si să derivezi din ea cerc, poligon etc. În python probabil nu este necesar.

1 Like

Ca o completare la ce a zis @serghei mai sus: ce cauți principiile SOLID. Astea două se potrivesc aici:

  • O → open closed principle îți permite să adaugi funcționalitate fără a edita sursa. Concret, poți adăuga o formă de teren nouă fără a modifica clasa Farmer.
  • L → Liskov substitution principle îți permite să schimbi implementarea unei clase fără ca utilizatorii implementării să știe treaba asta. Altfel spus, poți face Farmer să „știe” suprafața unui teren, dar să nu știe ce tip de teren este acela

Altfel spus, ai nevoie de un contract între implementări (Square, Circle etc) și utilizatori (Farmer).

În alte limbaje, contractul ăsta se numește interfață, iar utilizatorii vor folosi implementările respectivei interfețe.

(nu știu python altfel decât nivel de bază, deci ia asta mai mult ca pseudocod)

Python 3.5 adaugă type hinting, ceea ce înseamnă că, la codul lui @serghei de mai sus, putem face așa:

class Fermier:
-    def adaugaTeren(self, teren):
+    def adaugaTeren(self, teren: Teren):

Apoi folosești Protocol (python 3.8) (cod furat de aici, nu știu cum/dacă merge):

class Teren(Protocol): # asta e interfața
    def computeArea(): raise NotImplementedError

class TerenPatrat(): # asta e implementarea
    def computeArea():
        ...

class TerenTriunghi(): # asta e altă implementare
    def computeArea():
        ...
2 Likes

Eu zic ca, fiind în python ar trebui sa o faci cu ml și sa poți suporta și suprafețe neregulate. Nu o să-ți dea valori exacte dar pe acolo. :grin:

Creezi o clasă de bază teren cu metoda abstractă get_area, implementezi fiecare teren după clasa asta și definești get_area, iar în clasa fermierului adaugi prin compoziție fiecare teren (self.terenuri = []; self.terenuri.append(teren) ) și implementezi o metodă care să calculeze suma tuturor terenurilor (for teren in self.terenuri: self.suma_terenuri += teren.get_area).