Testi

Testi: testi-avtobusi.py

Naloga

Podan je razred Potnik, ki opisuje nesrečnika, ki so mu ukradli kolo in se mora voziti z ljubljanskim avtobusom. Potnik vsebuje podatek o zaporedni številki postaje, na kateri bo vstopil (če bo na avtobusu kaj prostora) in izstopil (prek trupel, če bo treba).

class Potnik:
    def __init__(self, vstop, izstop):
        self.vstop = vstop
        self.izstop = izstop

Razred Potnik pusti pri miru.

Obvezna naloga

Sprogramiraj razred Avtobus.

  • Konstruktor sprejme en argument, namreč maksimalno število potnikov.
  • Metoda kapaciteta() vrne maksimalno število potnikov (torej tisto, kar smo podali konstruktorju).
  • Metoda zasedenost() vrne število potnikov, ki so se uspeli stlačiti na avtobus.
  • Metoda stevilka_avtobusa() vrne 18.
  • Metoda vstop(potniki) sprejme seznam potniki, ki vsebuje objekta tipa Potnik. Na avtobus natovori toliko potnikov z začetka seznama, kolikor jih še gre nanj. Kot rezultat vrne seznam potnikov, ki so ostali na postaji.
  • Metoda izstop(stevilka_postaje) iz avtobusa odstrani potnike, ki izstopijo na postaji s podano številko.
  • Metoda postaja(stevilka_postaje, potniki) prejme številko postaje in potnike, ki čakajo na njej. Iz avtobusa odstrani potnike, ki gredo ven in vanj doda potnike, ki uspejo priti noter. (Pri tem se razume, da pokliče prejšnji dve metodi.) Kot rezultat vrne seznam potnikov, ki se niso uspeli stlačiti na avtobus.

Rešitev

Razred Avtobus bo moral imeti dva atributa: največje dovoljeno število potnikov (self.maks_potnikov), in seznam vseh potnikov, ki so trenutno na njem (self.potniki). Prvi podatek dobi konstruktor kot argument, seznam potnikov pa je v začetku vedno prazen.

Ko to vemo, je ostanek preprost.

class Avtobus:
    def __init__(self, maks_potnikov):
        self.maks_potnikov = maks_potnikov
        self.potniki = []

    def stevilka_avtobusa(self):
        return 18

    def zasedenost(self):
        return len(self.potniki)

    def kapaciteta(self):
        return self.maks_potnikov

    def vstop(self, potniki):
        prostor = self.maks_potnikov - len(self.potniki)
        self.potniki += potniki[:prostor]
        return potniki[prostor:]

    def izstop(self, postaja):
        self.potniki = [potnik for potnik in self.potniki
                        if potnik.izstop != postaja]

    def postaja(self, stevilka_postaje, potniki):
        self.izstop(stevilka_postaje)
        return self.vstop(potniki)

Trenutna zasedenost je dolžina seznama trenutnih potnikov, len(self.potniki).

Metoda vstop izračuna, koliko potnikov lahko še sprejmemo (prostor = self.maks_potnikov - len(self.potniki). Toliko potnikov doda na seznam trenutnih potnikov (self.potniki += potniki[:prostor]), te, ki ostanejo na postaji, pa vrne (return potniki[prostor:]).

Metoda izstop obdrži na seznamu potnikov vse, ki ne izstopijo. Tu se ne bomo zafrkavali z remove, temveč bomo raje naredili kar nov seznam, self.potniki = [potnik for potnik in self.potniki if potnik.izstop != postaja].

Metoda postaja pa izgleda tako, da najprej eni izstopijo self.izstop(stevilka_postaje), nato pa eni vstopijo, s tem da mora postaja vrniti tiste, ki niso uspeli priti na avtobus, zato torej return self.vstop(potniki).

Dodatna naloga

Sprogramiraj funkcijo simulacija(potniki, avtobusi, postaje), ki dobi seznam potnikov, ki čakajo po različnih postajah (vsak potnik čaka tam, kjer namerava vstopiti), seznam avtobusov in seznam številk postaj. Avtobusi vozijo v takšnem vrstnem redu, kot so podani v seznamu. Potniki vstopajo v takšnem vrstnem redu, kot so podani v seznamih; predstavljaj si, da tako kot v nekaterih drugih državah, čakajo v vrsti.

Funkcija naj izvede simulacijo voženj in vrne seznam potnikov, ki so ostali na postajah.

Rešitev

def simulacija(potniki, avtobusi, postaje):
    jezni = []
    for postaja in postaje:
        na_postaji = [potnik for potnik in potniki if potnik.vstop == postaja]
        for avtobus in avtobusi:
            na_postaji = avtobus.postaja(postaja, na_postaji)
        jezni += na_postaji
    return jezni

Najprej pripravimo seznam jezni, ki bo vseboval vse, ki obtičijo na posamezni postaji takrat, ko gredo mimo postaje vsi avtobusi. Gremo čez vse postaje in pripravimo seznam potnikov na tej postaji. Čez postajo spustimo vse avtobuse: vsak pobira potnike in pove, kdo je še ostal na postaji, ko je ta avtobus mimo. Na koncu so na_postaji tisti potniki, ki jih noben avtobus ni pobral, in ti se pridružijo seznamu jeznih.

Last modified: Thursday, 25 March 2021, 9:26 PM