» »

Python - težava s slovarji - vnos

Python - težava s slovarji - vnos

RatedR ::

Zdravo, prosim vas za nasvet kako naj popravim spodaj omenjeno napako.
junaki = {}

class Junak:
    def __init__(self, ime, zdravje, moc, obramba):          #junak ima ime, moc, zdravje, obrambo
        self.ime = ime
        self.zdravje = zdravje
        self.moc = moc
        self.obramba = obramba
    
    def kreacija(self, ime, zdravje, moc, obramba):
        if self.zdravje < 1:
               return "Zdravje mora biti pozitivno"
          
        junaki[i] = [self.ime, self.zdravje, self.moc, self.obramba]

    def __str__(self):
        return "Ime: {i}, zdravje: {z}, moc: {m}, obramba: {o}" .format(i=self.ime, z = self.zdravje, m = self.moc, o = self.obramba)


k = int(input("\nVnesite stevilo bojevnikov: "))

for i in range(0, k):
     ime = input("Vnesite ime junaka: ")
     zdravje = int(input("Vnesite zdravje junaka: "))
     moc = int(input("Vnesite moc junaka: "))
     obramba = int(input("Vnesite obrambo junaka: "))
     junaki[i] = junaki[i].kreacija(ime, zdravje, moc, obramba)

Napisat moram program v stilu "igre" z razredi. Za začetek imam razred Junak, v katerem imam metodo kreacija za ustvarjanje lika igre.
S for zanko spodaj vnašam posamezne vrednosti vsakega junaka v slovar junaki

Dobim napako:
line 27, in module junaki[i] = junaki[i].kreacija(ime, zdravje, moc, obramba)
KeyError: 0


Moja ideja je taka, da je ključ posameznega polja tudi indeks posameznega bojevnika, a izgleda da se to ne da?
Torej, če vnesem dva bojevnika, bi se moralo izpisat nekako takole (podajam primer):
print(junaki)
{1: ['Bojevnik1', 1000, 350, 100], 2: ['Bojevnik2', 1500, 200, 150]}


Prosim za nasvet, hvala!

jype ::

Funkcija "kreacija" je tisto, čemur se v angleščini reče "factory". Ta funkcija ni del razreda Junak - zgolj vrne objekte iz razreda Junak, zato parametra "self" ne potrebuje.

http://python-3-patterns-idioms-test.re...

Nehigienično je tudi, da funkcija vrne niz v primeru napake, namesto da bi sprožila izjemo, ker programer, ki bo uporabil tvojo funkcijo "kreacija", praviloma ne bo pričakoval, da je po uspešnem klicu vrnjena vrednost niz s sporočilom o napaki. V primeru spodaj sem to popravil.

class Junak:
    def __init__(self, ime, zdravje, moc, obramba):          #junak ima ime, moc, zdravje, obrambo
        self.ime = ime
        self.zdravje = zdravje
        self.moc = moc
        self.obramba = obramba
    def kreacija(ime, zdravje, moc, obramba):
        if self.zdravje < 1:
            raise Exception("Zdravje mora biti pozitivno")
        return Junak(ime, zdravje, moc, obramba)


Tale koda:

     junaki[i] = junaki[i].kreacija(ime, zdravje, moc, obramba)


je napačna: junaki[i] se v izrazu zgoraj sklicuje na polje, ki še ne obstaja. Pravilno bi bilo bodisi takole:

     junaki[i] = Junak(ime, zdravje, moc, obramba)


Ali pa takole:

     junaki[i] = Junak.kreacija(ime, zdravje, moc, obramba)

Zgodovina sprememb…

  • spremenilo: jype ()

RatedR ::

Kot prvo hvala za pomoč, zdaj deluje in pride vsaj čez vnos, izpis mi še dela nekaj težav (prilagam screen):


Koda: http://pastebin.com/GR495f9u

Glede tega:

jype je izjavil:

Funkcija "kreacija" je tisto, čemur se v angleščini reče "factory". Ta funkcija ni del razreda Junak - zgolj vrne objekte iz razreda Junak, zato parametra "self" ne potrebuje.

me pa zanima, če to velja samo za tiste metode kjer definiramo npr. spremenljivko, ob spreminjanju se pa uporabi self?

jype ::

RatedR> me pa zanima, če to velja samo za tiste metode kjer definiramo npr. spremenljivko, ob spreminjanju se pa uporabi self?

To je v resnici zgolj dogovor, razumeti pa moraš izraze:

Junak je razred (class), to je neke vrste "načrt" oziroma "štampiljka". Ko class definiraš, lahko potem ustvarjaš "odtise" oziroma "primerke razreda" (class instance oziroma object), ki so v pomnilniku ločeni.

Funkcija, ki vrne instanco

junaki je v tvojem primeru slovar, kar je nenavadno, ker so indeksi cela števila. Za takšno strukturo se običajno uporablja list (ki se ga definira z junaki = []). List sam poskrbi, da ne vsebuje lukenj, če izbrišeš vmesni indeks (vsi višji se premaknejo za eno število nižje). Če je to naloga, kjer moraš delat s slovarji, gre za nenavadno nalogo, ki ne uči dobre prakse.

Tvoj izpis je OK, ampak za izpis, kakršnega želiš, moraš definirati še posebno funkcijo __str__(self), ki določa pretvorbo instance razreda Junak v niz znakov, takole:

    def __str__(self):
        return str([self.ime, self.zdravje, self.moc, self.obramba])

jype ::

OK, zdaj vidim, da __str__ že imaš, uporabljaš pa Python 3, zato moraš v tvojem primeru definirat še funckijo __repr__(self), ki vrne niz, ki naj bi objekt opisal v pythonu, najlažje takole:

    def __str__(self):
        return "Ime: {i}, zdravje: {z}, moc: {m}, obramba: {o}" .format(i=self.ime, z = self.zdravje, m = self.moc, o = self.obramba)
        __repr__ = __str__


lahko pa, če si vljuden, takole:

    def __repr__(self):
        return "Junak({i}, {z}, {m}, {o})" .format(i=repr(self.ime), z = self.zdravje, m = self.moc, o = self.obramba)


ki pravilno vrne reprezentacijo junaka v pythonu. Če izpis prilepiš v python ukazno vrstico, dobiš nazaj enak objekt, kot si ga sprintal.

Zgodovina sprememb…

  • spremenilo: jype ()

RatedR ::

Hvala za pomoč, ko si omenil če moramo uporabljat slovarje, načeloma lahko tudi ne. Kljub temu da je naloga precej obsežna in je ne razumem v celoti ter ne določa kako moramo naredit npr. shranjevanje bojevnikov pa probavam nekaj po svoje.

Za razred Junak moram napisat določene metode, za metodo kreacija je napisano samo to:
kreacija - Metoda mora poleg shranjevanja podatkov preveriti tudi, če so vse vrednosti veljavne (največje zdravje in obe največji moči morata biti pozitivna števila, večja od ena). Če kakšna vrednost ni veljavna, naj sproži napako. Ob tem mora metoda nastaviti trenutno zdravje kot enako največjemu zdravju in zadnjo posodobitev na trenutni čas.

Tudi drugje ne piše kako naj izvedem shranjevanje, kako ti to razumeš?

Zgodovina sprememb…

  • spremenilo: RatedR ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

python-rabim pomoč

Oddelek: Programiranje
162033 (263) rnla1973
»

Python - pomoč (strani: 1 2 3 )

Oddelek: Programiranje
10313932 (4680) black ice
»

[Python]Naloga z razredi in dedovanjem

Oddelek: Programiranje
10813 (565) ktka
»

Python, prosim za pomoc pri programiranju (strani: 1 2 3 )

Oddelek: Programiranje
10410605 (6707) lenika
»

python pomoč

Oddelek: Programiranje
111222 (1042) jype

Več podobnih tem