Untitled

 avatar
unknown
plain_text
a month ago
15 kB
9
Indexable
''' Exercise #5. Python for Engineers.'''


#########################################
# Question 1 - do not delete this comment
#########################################
class Minibar:
    def __init__(self, drinks, snacks):
        self.drinks = drinks
        self.snacks = snacks
        self.bill = 0

    def __repr__(self):
        result = []
        if self.drinks:
            drinks_list = ", ".join([f"{name} ({quantity})" for name, quantity in self.drinks.items()])
            result.append(f"Drinks: {drinks_list}")
        else:
            result.append('No drinks left')

        if self.snacks:
            snacks_list = ", ".join([f"{name} ({price})" for name, price in self.snacks.items()])
            result.append(f"Snacks: {snacks_list}")
        else:
            result.append('No snacks left')

        if self.bill == 0:
            result.append("No bill yet")
        else:
            result.append(f"Bill: {self.bill}")
        return "\n".join(result)

    def eat(self, snack):
        snack_lower = snack.lower()
        for i in list(self.snacks.keys()):
            if i.lower() == snack_lower:
                self.bill += self.snacks[i]
                del self.snacks[i]
                return
        print(f"The snack {snack} was not found.")

    def drink(self, drink):
        drink_lower = drink.lower()
        for i in list(self.drinks.keys()):
            if i.lower() == drink_lower:
                self.bill += 21
                self.drinks[i] -= 1
                if self.drinks[i] == 0:
                    del self.drinks[i]
                return
        print(f"The drink {drink} was not found.")


#########################################
# Question 2 - do not delete this comment
#########################################
class Room:
    def __init__(self, minibar, number, guests, clean_level, is_suite, satisfaction=0.5):
        if not isinstance(minibar, Minibar):
            print("type error")
            return

        if not isinstance(clean_level, int):
            print("type error")
            return

        if not isinstance(is_suite, bool):
            print("type error")
            return

        if not isinstance(satisfaction, (float, int)):
            print("type error")
            return

        if not isinstance(number, int):
            print("type error")
            return

        satisfaction = float(satisfaction)
        if not (0.0 <= satisfaction <= 1.0):
            print("value error")
            return

        if not (101 <= number <= 940 and 1 <= number % 100 <= 40):
            print("value error")
            return

        self.clean_level = clean_level
        self.is_suite = is_suite
        self.satisfaction = satisfaction
        self.minibar = minibar
        self.number = number
        self.guests = guests

    def __repr__(self):

        guests = ', '.join(sorted(guest.lower() for guest in self.guests)) if self.guests else 'empty'

        return (
            f"Room number: {self.number}\n"
            f"Guests: {guests}\n"
            f"Clean level: {self.clean_level}\n"
            f"Is suite: {self.is_suite}\n"
            f"Satisfaction: {self.satisfaction:.1f}\n"
            f"Minibar:\n{repr(self.minibar)}"
        )

    def is_occupied(self):
        return len(self.guests) > 0

    def clean(self):
        if self.is_suite:
            self.clean_level = min(10, self.clean_level + 2)
        else:
            self.clean_level = min(10, self.clean_level + 1)

    def better_than(self, other):
        if self.is_suite and not other.is_suite:
            return True
        elif self.is_suite and other.is_suite:
            if (self.number // 100 >= other.number // 100):
                return True
        else:
            if self.clean_level >= other.clean_level:
                return True
        return False

    def check_in(self, guests):
        if not self.is_occupied():
            self.guests = [guest.lower() for guest in guests]
            self.satisfaction = 0.5
            self.minibar.bill = 0
        else:
            print(f"Cannot check-in new guests to an occupied room.")

    def check_out(self):
        if len(self.guests) == 0:
            print(f"Cannot check-out an empty room")
        else:
            self.guests = []

    def move_to(self, other):
        if not self.is_occupied():
            print(f"Cannot move guests from an empty room")
            return
        if other.is_occupied():
            print(f"Cannot move guests into an occupied room")
            return

        other.guests.extend(self.guests)

        other.minibar.bill = self.minibar.bill

        if other.better_than(self):
            other.satisfaction = min(1.0, self.satisfaction + 0.1)
        else:
            other.satisfaction = self.satisfaction

        self.guests = []


#########################################
# Question 3 - do not delete this comment
#########################################
class Hotel:
    def __init__(self, name, rooms):
        self.name = name
        self.rooms = rooms

    def __repr__(self):
        reserved_rooms = []
        for i in range(len(self.rooms)):
            if self.rooms[i].is_occupied():
                reserved_rooms.append(self.rooms[i].number)
        rm = len(reserved_rooms)
        urm = len(self.rooms)
        return (f"{self.name} Hotel has: {rm}/{urm} occupied rooms.")

    def check_in(self, guests, is_suite):
        available_rooms = [room for room in self.rooms if not room.is_occupied()]

        for room in available_rooms:
            if room.is_suite == is_suite:
                room.check_in(guests)
                return room

        return None

    def check_out(self, guest):

        the_guest = guest.lower()
        for room in self.rooms:
            if room.is_occupied() and any(g.lower() == the_guest for g in room.guests):
                room.check_out()
                return room.number

        return None

    def upgrade(self, guest):
        current_room = next((room for room in self.rooms if guest in room.guests), None)

        if not current_room:
            return None

        better_room = next(
            (room for room in self.rooms if not room.is_occupied() and room.better_than(current_room)),
            None)


        if not better_room:
            return None

    def send_cleaner(self, guest):
        guest_room = next((room for room in self.rooms if guest.lower() in [g.lower() for g in room.guests]), None)
        if not guest_room:
            return None
        guest_room.clean()
        return guest_room

#########################################
# Question 4 - do not delete this comment
#########################################
class Polynomial:
    def __init__(self, coefficients):
        self.coefficients = coefficients or [0]
        self.verify_zero()

    def __repr__(self):
        # explanation for my self to remember
        """
        first we did the init which was understandable
        then moving forwards we needed to define the constraints we had, which are shown in the second part
        we had the 0 polynomial which had to be pointed out and then moving forwards, knowing the length of the list (which contains the coeff allowed
        us to know the degree (power) and reducing by one each time.
        """
        if self.coefficients == 0:
            return "0"
        poly = []
        power = len(self.coefficients) - 1
        for coeff in self.coefficients:
            if coeff == 0:
                power -= 1
                continue

            if power == 0:
                poly.append(f"{coeff}")
            elif power == 1:
                if coeff == 1:
                    poly.append(f"x")
                else:
                    poly.append(f"{coeff}x")
            else:
                if coeff == 1:
                    poly.append(f"x^{power}")
                else:
                    poly.append(f"{coeff}x^{power}")
            power -= 1
        return "+".join(poly).replace("+ -", "- ")

    def __add__(self, other):
        # Now we are looking to add 2 polynomials which is done by comparing the coeff of both, and then adding corresponding to that
        # We need to find the list with the bigger length in order to know what we are looking at in terms of degrees so we use "max"

        max_len = max(len(self.coefficients), len(other.coefficients))

        # We need to add zeros to each one so that they are equal in length, which allows us to compare between them

        first = [0] * (max_len - len(self.coefficients)) + self.coefficients
        second = [0] * (max_len - len(other.coefficients)) + other.coefficients
        result = []
        for i, j in zip(first, second):
            result.append(i + j)
        return Polynomial(result)

    def __sub__(self, other):
        max_len = max(len(self.coefficients), len(other.coefficients))

        first = [0] * (max_len - len(self.coefficients)) + self.coefficients
        second = [0] * (max_len - len(other.coefficients)) + other.coefficients
        result = []
        for i, j in zip(first, second):
            if (i - j) == 0:
                return [0]
            else:
                result.append(i - j)

        return Polynomial(result)

    def __mul__(self, other):
        result = [0] * (len(self.coefficients) + len(other.coefficients) - 1)
        for i in range(len(self.coefficients)):
            for j in range(len(other.coefficients)):
                result[i + j] += self.coefficients[i] * other.coefficients[j]
        return Polynomial(result)

    def __gt__(self, other):
        if len(self.coefficients) > len(other.coefficients):
            return True
        elif len(self.coefficients) < len(other.coefficients):
            return False
        max_len = max(len(self.coefficients), len(other.coefficients))
        first = [0] * (max_len - len(self.coefficients)) + self.coefficients
        second = [0] * (max_len - len(other.coefficients)) + other.coefficients

        for i, j in zip(first, second):
            if i > j:
                return True
            elif i < j:
                return False
        return False

    def verify_zero(self):
        while len(self.coefficients) > 1 and self.coefficients[0] == 0:
            self.coefficients.pop(0)

    def calc(self, x):
        return sum(j * (x ** (len(self.coefficients) - 1 - i)) for i, j in enumerate(self.coefficients))



if __name__ == '__main__':
    def test_hotel():
        m1 = Minibar({'Coke': 10, 'Lemonade': 1}, {'Bamba': 8, 'Mars': 12})
        m2 = Minibar({'Beer': 10, 'Lemonade':4}, {'m&m': 6})
        rooms = [Room(m2, 514, [], 5, True),
                 Room(m2, 210, ["Ronen", "Shir"], 6, True),
                 Room(m1, 102, ["Liat"], 7, False),
                 Room(m2, 223, [], 6, True)]
        h = Hotel("Dan", rooms)
        test_sep = '\n------------------'
        print('PRINT m1:\n', m1, test_sep, sep="")
        print('PRINT m2:\n', m2, test_sep, sep="")
        print('PRINT h:\n', h, test_sep, sep="")
        liat_room = h.send_cleaner('Liat')
        print('CALL: h.send_cleaner("Liat")\n', liat_room, test_sep, sep="")
        print('CALL: liat_room.eat("bamba")\n', liat_room.minibar.eat("bamba"), test_sep, sep="")
        print('PRINT liat_room.minibar:\n', liat_room.minibar, test_sep, sep="")
        print('CALL: liat_room.drink("lemonade")\n', liat_room.minibar.drink("lemonade"), test_sep, sep="")
        print('PRINT liat_room.minibar:\n', liat_room.minibar, test_sep, sep="")
        print('CALL: h.upgrade("Liat")\n', h.upgrade("Liat"), test_sep, sep="")

        print('CALL: h.check_out("Ronen")\n', h.check_out("Ronen"), test_sep, sep="")
        print('CALL: h.check_out("Ronen")\n', h.check_out("Ronen"), test_sep, sep="")
        print('CALL: h.check_in(["Alice", "Wonder"], True)\n',
              h.check_in(["Alice", "Wonder"], True), test_sep, sep="")
        print('CALL: h.check_in(["Alex"], True)\n', h.check_in(["Alex"], True), test_sep,
              sep="")
        print('PRINT h:\n', h, test_sep, sep="")
        print('CALL: h.check_in(["Oded", "Shani"], False)\n',
              h.check_in(["Oded", "Shani"], False), test_sep, sep="")
        print('CALL: h.check_in(["Oded", "Shani"], False)\n',
              h.check_in(["Oded", "Shani"], False), test_sep, sep="")
        print('CALL: h.check_out("Liat")\n', h.check_out("Liat"), test_sep, sep="")
        print('CALL: h.check_out("Liat")\n', h.check_out("Liat"), test_sep, sep="")
        print('PRINT h:\n', h, test_sep, sep="")
    

    print('==== Q1: Part a Basic tests/output====')
    drinks1 = {'Coke': 3, 'BEER': 5, 'WaTeR': 10}
    snacks1 = {'M&M': 10, 'Cake': 40, 'cookies': 23}

    m1 = Minibar(drinks1, snacks1)
    print(m1.drinks == drinks1 and m1.snacks == snacks1 and m1.bill == 0)
    print(Minibar({}, {}).snacks == {})

    print('==== Q1: Part b Basic tests/output====')
    m2 = Minibar({'Coke': 3, 'BEER': 5, 'WaTeR': 10}, {'M&M': 10, 'Cake': 40, 'cookies': 23})
    m2.eat('m&m')
    print('M&M' not in m2.snacks and m2.bill == 10)
    m2.drink('coke')
    print(m2.drinks.get('Coke') == 2 and m2.bill == 31)

    print('==== Q1: Part c Basic tests/output====')
    print(repr(Minibar({}, {})) == 'No drinks left\nNo snacks left\nNo bill yet')
    print(repr(m2) == 'Drinks: Coke (2), BEER (5), WaTeR (10)\nSnacks: Cake (40), cookies (23)\nBill: 31')


    print('==== Q2: Part b Basic tests/output====')
    room1 = Room(Minibar({}, {}), 922, [], 9, True, 1)
    print(repr(room1) == 'Room number: 922\nGuests: empty\nClean level: 9\nIs suite: True\nSatisfaction: 1.0\nMinibar:\nNo drinks left\nNo snacks left\nNo bill yet')
    room2 = Room(Minibar({}, {}), 923, ['Eyal', 'Rinat', 'Amit'], 2, True)
    print(repr(room2) == 'Room number: 923\nGuests: amit, eyal, rinat\nClean level: 2\nIs suite: True\nSatisfaction: 0.5\nMinibar:\nNo drinks left\nNo snacks left\nNo bill yet')

    print('==== Q2: Part c Basic tests/output====')
    print(not room1.is_occupied())
    print(room2.is_occupied())

    room1.clean()
    print(room1.clean_level == 10)
    room2.clean()
    print(room2.clean_level == 4)

    print(room1.better_than(room2))

    room1.check_in(['Omer', 'Liav', 'Eden'])
    print(room1.guests == ['omer', 'liav', 'eden'])
    print(room1.satisfaction == 0.5)

    room1.check_out()
    print(room1.guests == [])

    room2.move_to(room1)
    print(room2.guests == [])
    print(room1.guests == ['eyal', 'rinat', 'amit'])
    print(room1.satisfaction == 0.6)

    # Question 3 - compare by yourself to 'test_hotel_output.txt'
    # After you are done implementing all classes and methods, you may call to test_hotel() and
    # compare the results with the file test_hotel_output.txt
    # you should get the same text printed between START and END of Q3 (not including the start and end message)
    print('==== Q3: test hotel START (not included)====')
    test_hotel()
    print('==== Q3: test hotel END (not included)====')



    print('==== Q4: Basic tests/output====')
    p1 = Polynomial([3, 2, 1])
    p2 = Polynomial([1, 2])
    p3 = Polynomial([2, 0, 6, 0])

    print(p1)
    print(p2)
    print(p3)
    print(p1 + p2)
    print(p1 - p2)
    print(p3 - p3)
    print(p1 * p2)
    print(p1 > p2)
    print(p1 > p3)
    print(p1.calc(2))
    print(p2.calc(2))
    print(p3.calc(2))
Leave a Comment