Crimson
Crimson

Reputation: 155

How to validate class parameters in __init__?

I've been searching a lot for this type of problem, haven't found a single similar question on SO yet.

I have tried using a for loop to put some validation in the train's init that would disregard those passengers although with no success.

tl;dr - How do I validate which passengers will be in the passengers list when I know that some of the passengers in the passengers list are ineligble to be in the train, due to seat_nr out of range or the carriage_nr out of range.

"""Train."""


class Train:
    def __init__(self, passengers: list, carriages: int, seats_in_carriage: int):
        

        #--Insert validation for passengers allowed on train--#        

        self._passengers = passengers
        self._carriages = carriages
        self._seats_in_carriage = seats_in_carriage

    @property
    def passengers(self) -> list:
        return self._passengers

    @property
    def carriages(self) -> int:
        return self._carriages

    @property
    def seats_in_carriage(self) -> int:
        return self._seats_in_carriage

    def get_seats_in_train(self) -> int:
        return self._seats_in_carriage * self._carriages

    def get_number_of_passengers(self) -> int:
        return len(self._passengers)

    def get_passengers_in_carriages(self) -> dict:
        return {}

    @passengers.setter
    def passengers(self, value_list: list):
        self._passengers = value_list

    @carriages.setter
    def carriages(self, value: int):
        self._carriages = value

    @seats_in_carriage.setter
    def seats_in_carriage(self, value: int):
        self._seats_in_carriage = value


class Passenger:
    def __init__(self, passenger_id: str, seat: str):
        self.carriage_number = seat.split("-")[0]
        self.seat_number = seat.split("-")[1]
        self._seat = seat
        self._passenger_id = passenger_id

    def __dict__(self):
        if str(2) >= self.seat_number > str(0) and self.carriage_number <= str(3):
            passenger_dct = {'id': str(self._passenger_id), 'seat': str(self._seat)}
            return passenger_dct


if __name__ == '__main__':
    passengers = [
        Passenger('test', '1-2'),   #--"test"= passenger_id, "x-y" : x= carriage_nr, y= seat_nr// valid
        Passenger('test2', '2-3'),  #-- invalid, seat_nr=3, train carriage has only 2 seats.
        Passenger('test3', '4-2'),  #-- invalid, carriage_nr = 4, train only has 3 carriages.
        Passenger('test4', '3-2'),  #-- valid
        Passenger('test5', '1-1'),  #-- valid
        Passenger('test6', '1-0'),  #-- invalid, no seat_nr 0 on train carriage
    ]
    assert passengers[0].__dict__() == {'id': 'test', 'seat': '1-2'}

    t = Train(passengers, 3, 2)  #--passengers list, number of carriages, number of seats in carriage.
    
    print(t.get_number_of_passengers()) # -- Should print 3, instead prints all 6.


Any info regarding to the topic is much appreciated, thanks in advance!

Upvotes: 1

Views: 310

Answers (1)

Bugbeeb
Bugbeeb

Reputation: 2161

I think the solution is pretty straightforward and I'm not sure why this wouldn't work: "I have tried using a for loop to put some validation in the train's init that would disregard those passengers although with no success." Essentially you can just loop through the passenger list and filter out invalid passenger objects as such:

self._passengers = list(filter(lambda p: p.seat_number is valid, passengers))

This uses a lambda function to check certain criteria for including them in the final list. Also your getters and setters don't currently do anything so they are kind of pointless.

Upvotes: 1

Related Questions