Untitled

mail@pastecode.io avatar
unknown
python
2 years ago
3.7 kB
1
Indexable
Never
"""
Klasa Składnik zawiera pola nazwa składnika, waga składnika wyrażona w kilogramach oraz cena za kilogram.
Utwórz dla tej klasy settery i gettery.

Nazwa składnika musi składać się tylko i wyłącznie z małych liter.
Waga składnika oraz cena składnika to zmienna typu double o wartościach większych od zera.

Dodatkowo zaimplementuj konstruktor bezargumentowy – dane pobierane od użytkownika oraz konstruktor argumentowy.

Klasa Produkt zawiera tablicę obiektów klasy Składnik.
Konstruktor bezargumentowy klasy Produkt prosi użytkownika o podanie liczby elementów tablicy
oraz pobiera wartości pól dla kolejnych składników.
Dodatkowo klasa zawiera metodę obliczającą cenę produktu,
która jest wyznaczona jako suma cen poszczególnych składników z tablicy
powiększona o 15% marży. Przetestuj działanie klas w funkcji głównej programu.

"""

from decimal import Decimal
import re
from typing import Final

NAME_PATTERN: Final = '[a-z]+$'


class Component:
    def __init__(self, *args):
        if len(args) == 3:
            self.name = args[0]
            self.weight = args[1]
            self.price = args[2]
        else:
            self.name = Attributes.get_name_from_user()
            self.weight = Attributes.get_weight_from_user()
            self.price = Attributes.get_price_from_user()

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = Validators.validate_name(name)

    @property
    def weight(self):
        return self.__weight

    @weight.setter
    def weight(self, weight):
        self.__weight = Validators.validate_if_above_zero(weight)

    @property
    def price(self):
        return self.__price

    @price.setter
    def price(self, price):
        self.__price = Validators.validate_if_above_zero(price)


class Attributes:
    @staticmethod
    def get_name_from_user() -> str:
        while not re.match(NAME_PATTERN, (input_val := input(f'Name:\n'))):
            print(f'Only small letters')
        return input_val

    @staticmethod
    def get_weight_from_user() -> float:
        while not (input_val := input(f'Weight:\n')).isnumeric():
            print(f'not a number')
        return float(input_val)

    @staticmethod
    def get_price_from_user() -> Decimal:
        while not (input_val := input(f'Price:\n')).isnumeric():
            print(f'not a number')
        return Decimal(f'{input_val}')


class Validators:
    @staticmethod
    def validate_name(text: str) -> str:
        if re.match(NAME_PATTERN, text):
            return text
        else:
            raise ValueError('only lower case acceptable')

    @staticmethod
    def validate_if_above_zero(num: Decimal | float) -> Decimal | float:
        if num <= 0:
            ValueError('number should be above zero')
        else:
            return num


class Product:
    margin = Decimal('1.15')

    def __init__(self):
        components_number = Product.get_num_of_components('provide components number')
        self.components = [Component() for _ in range(0, components_number)]

    @staticmethod
    def get_num_of_components(message: str) -> int:
        while not re.match(r'\d+', text := input(f'{message}:\n')):
            print('Value must be a positive integer')
        return int(text)

    def calculate_price(self):
        return sum([component.price for component in self.components]) * Product.margin


def main() -> None:
    prod = Product()
    print(prod.calculate_price())
    prod2 = Product('adsa', 123, 123)


if __name__ == '__main__':
    main()