Denarnica

Denarnica

Avtor: Nina Jug

Besedilo problema

Sestavi razred Denarnica, ki vsebuje tri komponente:
- celoštevilsko spremenljivko, ki predstavlja količino evrov v njej
- celoštevilsko spremenljivko, ki predstavlja količino centov v njej
- spremenljivko tipa string, ki vsebuje ime lastnika denarnice.
Napišite konstruktor, ki sprejme koliko evrov in centov naj bo v denarnici in ime lastnika denarnice. Privzeto naj bo v denarnici 100€, ime lastnika pa naj bo "NEZNAN".
Napišite tudi ustrezne get/set metode. V set metodi za evre in cente preveri smiselnost podatka - če je količina denarja, ki naj bo v denarnici, manjša od 0, naj se vrednost komponente ne spremeni.
Napiši tudi metodo _str_(self), ki vrne niz V denarnici, katere lastnik je #ime_lastnika, je #st_evrov evrov in #st_centov centov.
Napišite tudi metodi:
- DodajNaDatoteko(self, imeDatoteke), ki objekt self zapiše (doda – glej domačo nalogo 6) vrstico, kjer doda vse podatke objekta, med sabo ločene z znakom ';'
- PreberiZDatoteke(self, imeDatoteke), ki vrne tabelo objektov, kjer posamezni objekt vsebuje podatke, ki so zapisani v posamezni vrstici datoteke, med sabo ločeni z znakom '; (torej v obliki, kot jih zapiše prejšnja metoda).

Ideja rešitve

Nalogo bomo najbolj enostavno rešili, če bomo ustvarili razred. Tako bo naš objekt denarnica, podatki tega objekta pa bodo: količina evrov ter količina centov v njej in ime lastnika posamezne denarnice. Da bomo lahko podatke obdelovali, bomo morali ustvariti ustrezne metode. Pozorni bomo morali biti na smiselnost podatkov (verjetno nebi bilo smiselno, da hranimo -21 evrov ali -230 centov).

Koda razreda v python-u

import types

class Denarnica:

    def __init__(self, evri = 100, centi = 0, lastnik = 'NEZNAN'):
        """
Konstruktor s komponentami količina evrov, centov in imenom lastnika.
Ob ustvarjanju objekta brez parametrov, se ustvari objekt s privzetimi
vrednostmi.
"""
        assert type(evri) == int and evri >= 0, 'Količina evrov mora biti pozitivno celo število'
        assert type(centi) == int and centi >= 0, 'Količina centov mora biti pozitivno celo število'
        assert type(lastnik) == str, 'Ime mora biti vnešeno kot niz'
        self.evri = evri
        self.centi = centi
        self.lastnik = lastnik

    def getEvri(self):
        """
Metoda vrne količino evrov v denarnici.
"""
        return self.evri
    def setEvri(self, evri):
        """
Metoda nastavi količino evrov na podano količino.
"""
        assert type(evri) == int, 'Količina evrov mora biti celo število'
        if evri < 0:
            self.evri = self.evri
        else:
            self.evri = evri

    def getCenti(self):
        """
Metoda vrne količino centov.
"""
        return self.centi
    def setCenti(self, centi):
        """
Metoda nastavi količino centov na podano količino.
"""
        assert type(centi) == int, 'Količina centov mora biti celo število'
        if centi < 0:
            self.centi = self.centi
        else:
            self.centi = centi

    def getLastnik(self):
        """
Metoda vrne ime lastnika.
"""
        return self.lastnik
    def setLastnik(self, lastnik):
        """
Metoda nastavi ime lastnika na podano ime.
"""
        assert type(lastnik) == str, 'Ime lastnika mora biti podano kot niz'
        self.lastnik = lastnik

    def __str__(self):
        """
Metoda vrne niz, ki opiše denarnico.
"""
        return 'V denarnici, katere lastnik je '+self.lastnik+', je '+str(self.evri)+' evrov in '+str(self.centi)+' centov.'

    def __repr__(self):
        """
Metoda vrne niz, ki predstavi denarnico.
"""
        return self.lastnik+';'+str(self.evri)+';'+str(self.centi)

    def DodajNaDatoteko(self, imeDatoteke):
        """
Metoda doda predstavitev denarnice na datoteko.
"""
        with open(imeDatoteke, 'a')as dat:
            dat.write(self.__repr__()+'\n')

def PreberiZDatoteke(imeDatoteke):
    """
Metoda vrne tabelo objektov, kjer posamezni objekt vsebuje podatke, ki so zapisani v posamezni vrstici datoteke.
"""
    sez = []
    with open(imeDatoteke, 'r') as dat:
        for vrstica in dat:
            novaV = str(vrstica.strip())
            sez.append(novaV)
        return sez

koda

Naprej na komentar kode

Komentar kode

Najprej ustvarimo konstruktor. S tem imamo napisan opis, kako je določena poljubna denarnica. Naš konstruktor bo sestavljen iz treh komponent: količine evrov (evri), količine centov (centi) in ime lastnika (lastnik). Tem trem komponentam določimo vrednosti in tako se nam bo pri ustvarjanju objekta brez konkretnih spremenljivk, ustvarila denarnica z lastnikom NEZNAN in količino 100 evrov v njej. Da pri ustvarjanju objekta nebi pisali neumnosti, zapišemo ukaze assert, ki poskrbijo za napake. Tako mora biti količina evrov podana kot celo pozitivno število. Prav tako moramo podati tudi količino centov. Pri vnašanju imena lastnika pa moramo le tega vnesti kot niz. V konstruktorju samo še komponentam določimo imena in že lahko ustvarjamo objekte. Za predstavitev in nastavljanje novih vrednosti ustvarimo ustrezne get in set metode. Pri get metodah samo vračamo, pri set metodah pa spreminjamo vrednosti. Pri količinah moramo biti pozorni, da vnašamo smiselna števila. V primeru da vnesemo negativno število, mora konstruktor ostati enak. Če pa vnesemo smiselno vrednost, pa vrednost spremenljivke samo spremenimo na podano količino. Metoda _str_ nam bo objekt predstavila, zato samo napišemo ustrezno vrstico, ki želimo da nam jo metoda vrne. Ustvarimo tudi metodo _repr_, ki pa bo vrnila niz v nekoliko drugačni obliki. To obliko bomo potrebovali, ko bomo objekte zapisovali na datoteko. Pri metodi DodajNaDatoteko podamo ime datoteke, na katero želimo shraniti predstavitve denarnic. Datoteko najprej odpremo, a le za dodajanje. Doda naj jo v takšni obliki, kot nam jo metoda _repr_ predstavi. Ne smemo pozabiti na skok v novo vrsto, saj se nam bo drugače vse zapisovalo v eno vrsto. Metoda PreberiZDatoteke ni potrebno da je objektna metoda (vse metode do sedaj so bile). Najprej moramo ustvariti nek prazen seznam. Nato odpremo datoteko za branje. Pogledamo najprej prvo vrstico, jo shranimo kot niz v spremenljivko novaV (znebimo se tudi vseh belih znakov na začetku in koncu) in ta niz pripnemo v naš prazen seznam. Tako naredimo za vsako vrstico. Na koncu ta seznam samo še vrnemo.

Nazaj na kodo

Testni primeri

V testnem programu bi poizkusili preveriti naslednje tvorbe objektov:

  • Denarnica('12', 10, 'Nina') … kaj program naredi, ko za parameter evri vnesemo niz namesto število
  • Denarnica(12, '10', 'Nina') … kaj program naredi, ko za parameter centi vnesemo niz namesto število
  • Denarnica(12, 10, Nina) … kaj program naredi, ko za parameter lastnik ne vnesemo niza
  • Denarnica(-12, 10, 'Nina') … kaj program naredi, ko za parameter evri vnesemo negativno število
  • Denarnica(12, -10, 'Nina') … kaj program naredi, ko za parameter centi vnesemo negativno število
  • Potem bi ustvarili denarnico brez parametrov. Ob klicanju get metod bi morali dobiti privzete vrednosti.
  • Nazadnje ustvarimo določeno denarnico. Preizkusimo vse get metode. Potem na tej denarnici uporabimo set metode. Po vsaki izvedbi le te, preizkusimo še get metode. Preizkusimo tudi _str_ in _repr_ metodi. Nazadnje pa še metodi za zapisovanje na datoteko in branje iz datoteke.

testni primeri

Filmček

Naloge

Sestavite tabelo objektov tipa Denarnica z naključnimi, a smiselnimi podatki. Rešite naslednje naloge:

  1. Izračunaj, koliko denarja imajo skupaj osebe v tabeli objektov tipa Denarnica.
  2. Cela skupina (beri vsi v tabeli) lastnikov denarnic se je odpravila v banko. Tam so vse svoje cente "pretopili" v evre (kolikor je šlo, seveda). Če je nekdo imel prej 6€ in 245 centov, ima sedaj v denarnici 8€ in 45 centov.
  3. Izpiši imena vseh tistih oseb, ki si lahko privoščijo nakup banjice sladoleda, ki stane 4€ 45 centov. Seveda so vse osebe, ki to lahko, opravile nakup. Pazi, da bodo njihove denarnice odražale to stanje.
  4. Božiček je vsem lastnikom denarnic prinesel 6€ in 55 centov. Ustrezno popravi stanje vseh denarnic.
  5. Cela skupina lastnikov denarnic se odloči, da bo igrala športne stave. Vsak izmed njih bo vplačal 1€. Na datoteki Stave je napisano, ali je lastnik stave zadel ali ne (da, ne). Če je odgovor da, je zraven napisano tudi, koliko denarja je zadel. Spremeni stanje denarnic po odigranih stavah.

Koda nalog v python-u

import denarnica
import random

imena = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
denarnice = []
for i in imena:
    evri = random.randint(1,20)
    centi = random.randint(0,300)
    denarnice.append(denarnica.Denarnica(evri, centi, i))
print(denarnice)

#1. naloga
def kolikoSkupaj():
    """
Metoda nam izračuna koliko denarja imajo skupaj osebe v tabeli.
"""
    evri = 0
    centi = 0
    for i in denarnice:
        evri += i.evri
        centi += i.centi
    cVe = centi//100
    vsota = evri + cVe + (centi%100*0.01)
    return str(vsota)+' €'

#2. naloga
def pretopitev():
    """
Metoda nam "pretopi" cente v evre.
"""
    for i in denarnice:
        if i.centi > 99:
            i.evri += i.centi//100
            i.centi = i.centi%100
        else:
            i.centi = i.centi
            i.evri = i.evri
    print(denarnice)


#3. naloga
def banjica():
    """
Metoda izpiše imena tistih oseb, ki si lahko privoščijo nakup, ki stane 4€
45centov. Metoda mora tudi popraviti število centov in evrov po opravljenem
nakupu.
"""
    for i in denarnice:
        celotenDenar = i.evri*100 + i.centi
        if celotenDenar >= 445:
            print(i.lastnik)
            celotenDenar -= 445
            i.evri = celotenDenar//100
            i.centi = celotenDenar%100
    print(denarnice)

#4. naloga
def bozicek():
    """
Metoda vsem lastnikom doda 6€ 55centov.
"""
    for i in denarnice:
        celotenDenar = i.evri*100 + i.centi
        celotenDenar += 655
        i.evri = celotenDenar//100
        i.centi = celotenDenar%100
    print(denarnice)

#5. naloga
def stave():
    """
Metoda izpiše novo stanje denarnic po vplačanih in izplačanih stavah. Podatke
o dobitkih, dobi metoda na datoteki stave.txt.
"""
    sez = []
    with open('stave.txt', 'r') as dat:
        for vrstica in dat:
            sez.append(vrstica.strip().split(';'))
        for i in sez:
            if i[0] == 'da':
                indeks = sez.index(i)
                denarnice[indeks].evri += int(i[1])
                denarnice[indeks].centi += int(i[2])
    for osebe in denarnice:
        osebe.evri -= 1
    return denarnice

Naloge

Reševanje nalog

Da bomo lahko reševali nalogo s pomočjo metod, ki smo jih ustvarili v razredu, moramo najprej uvoziti razred Denarnica. Za reševanje nalog moramo najprej ustvariti tabelo objektov. V spremenljivko imena shranimo seznam črk od A do J (to bodo naši lastniki denarnic). Ustvarimo tudi prazen seznam v katerega bomo shranili objekte. S for zanko gremo čez seznam imen in v spremenljivki evri in centi shranimo naključno število med 1 in 20 oz. 0 in 300 (tako bo lahko oseba imela največ 20 evrov 300 centov in najmanj 1 evro 0 centov). V naš prazen seznam pripnemo objekte, ki jih ustvarimo s pomočjo uvoženega razreda. Ta seznam naj se ob zagonu modula tudi izpiše (da bomo lahko preverjali pravilnost metod).

  1. Ustvarimo spremenljivki evri in centi, ki naj imata začetno vrednost 0. S for zanko gremo čez seznam denarnice. Za vse evre, ki jih oseba ima, naj se spremenljivka evri poveča. Prav tako naj se poveča število centov. Tako bomo v obeh spremenljivkah dobili, koliko centov in koliko evrov imajo vse osebe skupaj. Da bo izpis celotnega denarja bolj pregleden, cente pretvorimo v evre. Na koncu samo še seštejemo evre, cente pretvorjene v evre in ostanek centov, ki ga ni bilo mogoče spremeniti v cente (pomeni, da je bil manjši kot 99). Poskrbimo še, da funkcija vrne skupen denar z znakom €.
  2. Spet gremo s for zanko čez celoten seznam denarnic. Če je v posamezni denarnici število centov večje kot 99, jih moramo spremeniti v evre. To storimo tako, da evre povečamo za število centov, ki ga dobimo pri celoštevilskem deljenju le teh s 100. Število centov pa je sedaj enako ostanku pri deljenju le teh s 100. Če pa v posamezni denarnici ni več kot 99 centov ohranimo število evrov in centov. Na koncu še izpišemo novi seznam denarnic.
  3. Kot vedno do sedaj, gremo tudi tokrat čez celoten seznam denarnic. Količino denarja v posamezni denarnici pretvorimo v cente. Če je ta količina večja/enaka od 445 centov (4 € 45 centov), potem naj se ime lastnika izpiše na zaslon. Ker je bil nakup opravljen, celotni količini denarja odštejemo 445 centov. Na koncu samo še cente pretvorimo v evre in cente, ter izpišemo seznam denarnic, da se res prepričamo, da je nakup bil opravljen.
  4. Spet gremo čez celoten seznam denarnic. Tako kot prej, evre pretvorimo v cente in jih seštejemo z centi, da dobimo celoten denar v centih. Ta denar povečamo za 655 centov (6€ 55 centov). In z že znanim postopkom spremenimo cente v evre in ostanek pustimo v centih. Ta novi popravljeni seznam izpišemo, da se res prepričamo o spremenjenih cenah.
  5. Podatke o dobitkih, dobi metoda na datoteki Stave. Najprej ustvarimo prazen seznam v katerega bomo izpisali rezultate dobljenih/nedobljenih stav. Odpremo datoteko na kateri so stave za branje. Gremo čez celotno datoteko in za vsako vrstico v datoteki, v naš prazen seznam dodamo to vrstico brez belih znakov in razdeljeno glede na znak ;. Tako imamo seznam, sestavljen iz podseznamov, katerih elementi so vrstice naše datoteke. S for zanko se sprehodim čez ta naš seznam. Če je prvi element vsakega podseznama enak nizu da, potem v spremenljivko indeks shranimo indeks pojavitve podseznama, v katerem so bile stave dobljene. Na indekstem mestu v seznamu denarnice, evre povečamo za število, ki se pojavi ob besedi da v datoteki. Prav tako povečamo tudi cente za število, ki je zadnje v dobitni vrstici. Na koncu pa samo še vsem lastnikom denarnic zmanjšamo število evrov za 1, saj so vsi vplačali 1€. Vrnemo seznam novih vrednosti denarnic.

Filmček

0%
0%