Praktikum 13¶

Allolevad ülesanded on kursuse "Sissejuhatus programmeerimisse Pythoni baasil" YFX0500 praktikumis koos kursusega ja kodus iseseisvalt lahendamiseks. Kuidas lahendada allolevaid ülesandeid? Uuri ja kasuta loengus kommenteeritud süntaksi näiteid, abiinfot (Pythoni sisseehitatud funktsioon help, jne.), Internetti ja enda aju. Küsimuste korral, mis tekivad praktikumi ajal, pöördu õppejõu või õppejõudude poole. Iganädalaselt peale praktikumi toimumist avaldatakse ülesannete lahendused kursuse kodulehel.

Viimati uuendatud 24.11.2025.

Inimintellekti loodud ülesanded¶

Ülesanne 0:

Kirjuta klass MyInt mis loob täisarvu objekte:

  1. Defineeri meetod __mul__.
  2. Veendu, et klassi objekti sõnena esitus oleks kujul 2 kui arvu väärtus on 2, jne.
  3. Veendu, et kahe arvu korrutise tulemus on andmetüübiga MyInt.
  4. Loo kaks objekti n1 ja n2. Teosta järgmised tehted: n1 * n2 ja n1 * n2 * n2. Kontrolli kas leitud vastused on esitatavad sõnena ja kas nende andmetüüp on MyInt.

Ülesanne 1:

Loo klass mis loob kahemõõtmelisi punkte:

  1. Defineeri punktide liitmise meetod. Kirjuta üle meetod __add__.
  2. Veendu, et objekti esitus sõnena oleks kujul (x, y) kui kasutad funktsioone str ja print ning kujul ((x, y)) kui kasutad funktsiooni repr. Siin x ja y on punkti koordinaadid.

Ülesanne 2:

Loo klass Punkt mis defineerib kahemõõtmelisi punkte $A = (A_x, A_y)$. Kirjuta meetod kaugus_punktist mis leiab punkti kauguse teisest meelevaldselt valitud punktist. Kahe punkti vahelise vahemaa $D$ leidmiseks kasuta valemit

$$D = \sqrt{ (A_x - B_x)^2 + (A_y - B_y)^2},$$

kus $B = (B_x, B_y)$ on punkt ja kus omakorda $B_x$ ja $B_y$ on punkti koordinaadid. Lisaks loo meetod liiga_ligidal mis hoiatab kasutajat juhul kui punktid on teineteisele liiga lähedal. Minimaalne lubatud vahemaa edasta meetodile argumendina.

Ülesanne 3:

Muuda allolevas klassis meetod milline dünaamiliseks objektimuutujaks. Kasuta dekoraatorit property.

class Olend:
    
    def __init__(self, jalgu, tiibu):
        self.jalgu = jalgu  # täisarv
        self.tiibu = tiibu  # täisarv
        
    def milline(self):
        if self.jalgu == 2: 
            if self.tiibu == 1:
                print('Kahejalgne olend kellel on üks tiib.')
            elif self.tiibu == 0:
                print('Kahejalgne olend kellel pole tiibu.')
            else:    
                print(f'Kahejalgne olend kellel on {self.tiibu} tiiba.')
        elif self.jalgu == 4:
            if self.tiibu == 1:
                print('Neljajalgne olend kellel on üks tiib.')
            elif self.tiibu == 0:
                print('Neljajalgne olend kellel pole tiibu.')
            else:
                print(f'Neljajalgne olend kellel on {self.tiibu} tiiba')
        else:
            if self.tiibu == 1:
                print('Mitte kahe- või neljajalgne olend kellele on üks tiib.')
            elif self.tiibu == 0:
                print('Mitte kahe- või neljajalgne olend kellel pole tiibu.')
            else:
                print(f'Mitte kahe- või neljajalgne olend kellele on {self.tiibu} tiiba.')

Ülesanne 4:

Uuri alljärgnevat koodi.

class Imetaja:
    
    def __init__(self, nimi):
        print(nimi, "on imetaja.")
         

class OskabLennata(Imetaja):
    
    def __init__(self, oskabLennata_nimi):
        print(oskabLennata_nimi, "ei oska lennata.")
        super().__init__(oskabLennata_nimi)
        
                  
class OskabUjuda(Imetaja):
    
    def __init__(self, oskabUjuda_nimi):
        print(oskabUjuda_nimi, "ei oska ujuda.")
        super().__init__(oskabUjuda_nimi)
        
               
class Loom(OskabLennata, OskabUjuda):
    
    pass
        
        
tom = Loom("Koer")

Koodi interpreteerimisel trükitakse konsooli väljund:

Koer ei oska lennata.
Koer ei oska ujuda.
Koer on imetaja.

Miks just sellises järjekorras?

Ülesanne 5:

Tutvu alljärgneva klassiga.

class Loomad:
    
    def __init__(self):
        self.jalad = 4
        self.kodustatud = True
        self.saba = True
        self.imetaja = True
        
    def on_imetaja(self):
        if self.imetaja:
            print("On imetaja.")
     
    def on_kodustatud(self):
        if self.kodustatud:
            print("On kodustatud loom.")

Loo kaks alamklassi, klass Koerad ja klass Hobused. Mõlemad klassid peavad pärima kogu superklassi Loomad sisu. Klass Hobused peab sisaldama, lisaks superklassi meetoditele, ka meetodit mis kontrollib kas loomal on saba ja neli jalga. Peale kontrolli peab meetod väljastama sellekohase teate.

Esita kaks lahendust. Kasuta nii superklassi nime Loomad kui ka funktsiooni super.

Ülesanne 6:

Kasuta eelmises ülesandes kasutatud superklassi Loomad. Lisa sellele staatiline meetod mis leiab sellele etteantud meelevaldse arvu numbrite summa naturaallogaritmi:

$$\ln\! \left(\! \sum_i^n \xi_i \!\right),$$

kus $\xi$ on etteantud number ja $n$ on nende arv.

Ülesanne 7:

Tutvu klassiga Tudeng. Klass Tudeng on kujul:

class Tudeng:
    kursus = 'Python YFX0500'
    hinne = None

Lisa sellele kaks meetodit:

  1. Meetod prindi mis väljastab konsooli kursuse nime ja
  2. meetodi lisahinne mis omistab klassimuutujale hinne hinde (arvu) ja väljastab sellekohase teate.

Vihje: Kasuta dekoraatorit classmethod.

Ülesanne 8:

Kapselda allolevad koodis kõik peale meetodi data:

class A:
    cls_a = 1
    cls_b = 22

    def __init__(self, obj_a, obj_b):
        self.obj_a = obj_a
        self.obj_b = obj_b

    def method(self):
        return 'obj_a = {} and obj_b = {}.'.format(self.obj_a, self.obj_b)

    def data(self):  # Avalik meetod.
        obj_b_id = id(self.obj_b)
        return 'obj_b = {}, obj_b id = {}.'.format(self.obj_b, obj_b_id)


obj = A(3, 44)

print(obj.data())

Ülesanne 9:

Loo klass mis defineerib tudengeid. Tudengiga peavad olema seotud järgmised andmed:

  • nimi,
  • perekonna nimi,
  • sugu,
  • kaal,
  • õppekava ja
  • info selle kohata kas tudeng on HIV positiivne või mitte.

Kapselda tudengiga seotus andmed. Tudengi objekti esitus sõnena (meetod __repr__) peab sõltuma tudengi HIV staatusest:

  • HIV negatiivne Tudeng <nimi> <perekonna nimi> kes kaalub <kaal> kg on jumala ingel.
  • HIV positiivne Tudeng <nimi> <perekonna nimi> kes kaalub <kaal> kg on ka jumala ingel!

Ülesanne 10:

Paranda eelmises ülesandes kirjutatud klass. Muuda meetod __repr__ viisakaks, see võiks väljastada sõne kujul:

  • Tudeng <nimi> <perekonna nimi> kes õpib <oppekava> õppekaval.

Lisaks loo uus meetod hiv_staatus mis väljastab (või prindib) sõne mis sõltub tudengi HIV staatusest:

  • HIV negatiivne Tudeng <nimi> <perekonna nimi> kes kaalub <kaal> kg on jumala ingel.
  • HIV positiivne Tudeng <nimi> <perekonna nimi> kes kaalub <kaal> kg on ka jumala ingel!

Ülesanne 11:

Täiusta eelmises ülesandes loodud klassi. Muuda HIV staatusest sõltuv meetod hiv_staatus privaatseks (kapselda see). Loo uus avalik (kapseldamata) meetod saladus mis väljastab tudengi HIV staatuse booli tõeväärtusena (True või False).

Ülesanne 12: *

Kirjuta klass Juurjalg mis loob juurjalgu. Juurjalg on amööb kes saab olla kas punane või roheline. Juurjalg oskab teha ainult kolme asja:

  1. Toituda mille tulemusena juurjala kehakaal kasvab söödud toidu kaalu võrra. Toitumisele järgneb alati väljaheitmine ja mõnikord juurjalg ka paljuned peale söömist ja väljaheitmist. Paljunemine juhtub kui juurjala kaal saab kolm või rohkem korda suuremaks tema algsest sünnikaalust.
  2. Väljaheidet tekitades väheneb juurjala kaal näiteks 20% võrra tema kehakaalust.
  3. Paljunemine tähendab seda, et tekib uus juurjalg kelle sünnikaal on meie just vanemaks saanud juurjala algne kaal ja kelle väljaheite kaalu protsent kehakaalust saab olema vanema omast omakorda 10% suurem. Sündinud juurjala värv on määratud juba olemasolevate juurjalgade värvist. Kui populatsioonis on rohken punaseid siis sünnib alati roheline juurjalg ja vastupidi. Paljunemeise tagajärjel väheneb vanema kaal pooldunud juurjala kaalu võrra ehk vanema algse kaalu võrra.

Anna kasutajale juurjalga luues võimalus määrata selle algne kaal, värvus ja protsentides seda kui palju moodustab ühe väljaheite kaal juurjala kehakaalust.

Ülesanne 13: (vt. vrd. Praktikum 12)

Koosta programm pangakontode loomiseks kasutades Pythoni klassi.

Programmiga peab saama:

  • Luua uusi kontosid (objekt), andes kontole nime ja mingi hulga raha.
  • Kanda kontole raha (meetod).
    • Kontole ei saa kanda negatiivset summat.
  • Võtta kontolt raha (meetod).
    • Kontolt ei saa võtta negatiivset summat.
    • Kontolt ei saa võtta rohkem raha kui kontol on.

Ülesanne 14:

Koosta programm pangakontode loomiseks kasutades Pythoni klassi.

Programmiga peab saama (kaldkirjas olev tekst on sama mis eelmises ülesandes):

  • Luua uusi kontosid (objekt), andes kontole nime ja mingi hulga raha.
  • Kanda kontole raha (meetod).
    • Kontole ei saa kanda negatiivset summat.
  • Võtta kontolt raha (meetod).
    • Kontolt ei saa võtta negatiivset summat.
    • Kontolt ei saa võtta rohkem raha kui kontol on.
  • Kanda ühelt kontolt raha teisele.
    • Kehtivad samad reeglid, mis kontole raha kandmisel ja välja võtmisel.

Ülesanne 15:

Lisaks deebetkaardi kontole (eelmised kaks ülesannet) loo krediitkaardi konto. Krediitkaardi kontode loomiseks kasuta uut klassi, mis pärib vajamineva deebetkaardi konto klassist, st. väldi atribuutide ja meetodite ilmutatud kujul dubleerimist.

Krediitkaardi kontoga peab saama:

  • Luua uusi kontosid, andes kontole nime ja mingi hulga raha ja valides krediidi koguse (vaikimisi €1000).
  • Kanda kontole raha.
    • Kontole ei saa kanda negatiivset summat.
  • Võtta kontolt raha.
    • Kontolt ei saa võtta negatiivset summat.
    • Kontolt ei saa võtta rohkem raha kui konto jääk + krediit.

Ülesanne 16:

Pythonis pole kapseldamine päriselt lokaliseeriv. Uusi koodi:

class A:
    aliens_exist = True
    __aliens_here = 4
    __alien = "  .-.\n (0 o)\n  |=|\n /   \ \n '---'"
    
    def __Area51(self):
        for _ in range(A.__aliens_here):
            print(A.__alien)


a = A()

Demonstreeri globaalses skoobis, et klassimuutujad __aliens_here, __alien ja meetod __Area51 pole täielikultm lokaliseeritud (kaitstud).

Meetodi __Area51 väljatrükk on kujul:

  .-.
 (0 o)
  |=|
 /   \ 
 '---'
  .-.
 (0 o)
  |=|
 /   \ 
 '---'
  .-.
 (0 o)
  |=|
 /   \ 
 '---'
  .-.
 (0 o)
  |=|
 /   \ 
 '---'

Ülesanne 17:

Uuri allolevat koodi. Lisa sellele tüübiviited (type hints).

class Bank:
    
    def __init__(self, name, balance):
        self.name = name
        self.balance = balance

    def get_balance(self):
        return self.balance

    def deposit(self, amount):
        if amount < 0:
            return False
        self.balance += amount
        return True

    def withdraw(self, amount):
        if amount < 0 or self.balance - amount < 0:
            return False
        self.balance -= amount
        return True
    
    def transfer(self, to_account, amount):
        if self.name == to_account.name:
            return False
        return self.withdraw(amount) and to_account.deposit(amount)

Ülesanne 18:

Kasuta eelmise ülessande vastust. Muuda tüübiviited (type hints) programmi täitmise ajal kontrollitavateks. Kasuta nt. moodulit typeguard. Moodulis oleva dekoraator typechecked tõstatab erisused TypeCheckError (või TypeError) kui programm eksib eeldatud andmetüüpide vastu.


Tehisintellekti loodud ülesanded¶

Järgnevad ülesanded on loodud 23.11.2025 juturoboti OpenAI ChatGPT (GPT-5) poolt.

Ülesanne TI-1:

Pokémoni lahingu simulatsioon

Kujuta Pokemon klass, millel on järgmised objektimuutujad ja meetodid:

  • nimi name: Pokémoni nimi, tüübiga str.
  • elupunktid hp: tervisepunktid, tüübiga int või float.
  • meetod attack(teine, kahju) — vähendab teise Pokémoni elupunkte vastavalt määratud kahju väärtusele.
  • meetod is_alive() — tagastab True, kui Pokémoni elupunkte on rohkem kui null, vastasel juhul False.

Looge kaks Pokémoni objekti ning simuleerige nende vahelist rünnakut, dokumenteerides muutunud oleku väärtused.

Ülesanne TI-2:

Coffee Machine and User

Scenario: Users can order coffee from a coffee machine. The coffee machine keeps track of its coffee beans, water, and cups. If the machine runs out of any ingredient, it refuses to serve coffee.

Task:

  1. Create a CoffeeMachine class with:
    • Object variables or attributes: beans, water, cups (all integers).
    • Method brew(user, size) that reduces ingredients depending on size ("small", "medium", "large") and returns a message to the user.
  2. Create a User class with:
    • Object variables or attributes: name, coffee_drank (integer).
    • Method order_coffee(machine, size) that calls machine.brew(self, size) and updates coffee_drank.

Simulate at least two users ordering coffee from the same machine.

Funny twist: If a user tries to order coffee when ingredients are low, the machine should respond with a humorous message like "No coffee for you! Go sleep!".

Ülesanne TI-3:

Zombie and Scientist Game

Scenario: A scientist tries to cure zombies. Zombies have health points, and scientists have a limited number of antidotes. Scientists can attempt to cure zombies; if successful, the zombie is healed. Otherwise, the zombie groans angrily.

Task:

  1. Create a Zombie class:
    • Attributes: name, hp.
    • Method: groan() prints a funny zombie sound.
  2. Create a Scientist class:
    • Attributes: name, antidotes.
    • Method: cure(zombie) attempts to reduce zombie hp by 50. If hp reaches 0 or less, the zombie is healed and prints a success message. Otherwise, the zombie groans.

Simulate at least two scientists interacting with two zombies.

Funny twist: Zombies complain humorously if the scientist fails, e.g., "Brains still needed!".


Kodus¶

Ülesanne 19: *

Uuri alljärgnevat lähtekoodi. Püüa aru saada mis toimub.

class ObjectWithWeight:

    def __init__(self, weight):
        self.weight = weight

        
class ObjectWithNameAndWeight(ObjectWithWeight):

    def __init__(self, name, weight):
        ObjectWithWeight.__init__(self, weight)
        self.name = name
        
    def __repr__(self):
        return '{}({}, {})'.format(type(self).__name__, self.name, self.weight)


class Fruit(ObjectWithNameAndWeight):

    def take_a_bite(self, weight):
        actual_weight = min(self.weight, weight)
        self.weight -= actual_weight
        return weight - actual_weight


class Basket(list, ObjectWithWeight):

    @property
    def weight(self):
        return sum(o.weight for o in self)

    def take_a_bite(self, weight):
        shortage = weight
        for o in self:
            shortage = o.take_a_bite(shortage)
        return shortage


class Animal(ObjectWithNameAndWeight):

    def feed(self, food, meal_weight):
        shortage = food.take_a_bite(meal_weight)
        self.weight += meal_weight - shortage
        if shortage > 0:
            return 'still hungry'
        return 'fed up'


a = Fruit('Apple', 200)
b = Fruit('Banana', 100)
fruits = Basket([a, b])
dog = Animal('Muki', 5000)

print(dog, fruits)
# --> Animal(Muki, 5000) [Fruit(Apple, 200), Fruit(Banana, 100)]

print(dog.feed(fruits, 150))
# --> fed up

print(dog, fruits)
# --> Animal(Muki, 5150) [Fruit(Apple, 50), Fruit(Banana, 100)]

















☻   ☻   ☻