IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
David Mikšaník:9.6.2017 18:56

Ahoj, nechal jsem si inspirovat jednou hrou tady na forum, jen jsem si řekl, že si to udělám podle sebe a že ta "hra" bude mít víc funkcí, ale zasekl jsem se v jednom bodě. Strávil jsem nad tím minimálně 2-3 hodiny, a zkoušel jsem to nějak obejít, ale neúspěšně tak doufám, že mi tady někdo poradí

Jedná se o třídu "Set_skills"
"help_var" je proměnná, které by měla reprezentovat počet bodů, který můžu rozdělit do tří schopností.
Cyklem "while" kontroluji, jestli mi nějaké body zbývají, jenže když si tedy vyberu z možností 1-3, dále si rozhodnu kolik bodů si dám do dané schopnosti. A pak se tedy vratím a kontroluji zda jsem vyčerpal všechny body, jenže to proměnné "help_var" se mi opět vloží "10", takže vlastně je to nekonečný cyklus.
Tedy otázka zní: jak by jsem mohl to nějak opatřit, aby si mi to pomocné proměnné "help_var" neustalé neukládala hodnota "10"

PS: angličtinu neřešte :)

   class Fighther():

    def __init__(self, name, strength, health, agility):
        self.name = name
        self.strength = strength
        self.health = health
        self.agility = agility

    def ability(self):
        Set_skills.choice(Set_skills)


class Set_skills(Fighther):


    def choice(self):
        help_var = 10
        print('Skills: ', help_var,
              '\n================'
              '\n1 - Strength'
              '\n2 - Health'
              '\n3 - Agility'
              '\n================')
        while help_var > 0:
            print('Count skills:', help_var)
            choice = int(input('Your choice [1--3]: '))
            if choice == 1:
                self.strength(help_var)
            elif choice == 2:
                self.health(help_var)
            elif choice == 3:
                self.agility(help_var)
            else:
                print('Invalid choice!')

    @staticmethod
    def strength(help_var):
        print('Count skills:', help_var)
        x = int(input('How many points skill zou want add for STRENGTH:'))
        help_var = help_var - x
        print('Count skills:', help_var)
        return help_var

    @staticmethod
    def health(help_var):
        print('Count skills:', help_var)
        x = int(input('How many points skill zou want add for HEALTH:'))
        help_var = help_var - x
        return help_var

    @staticmethod
    def agility(help_var):
        print('Count skills:', help_var)
        x = int(input('How many points skill zou want add for AGILITY:'))
        help_var = help_var - x
        return help_var




my_hero = Fighther('David', strength=1, health=50, agility=1)

my_hero.ability()
 
Odpovědět
9.6.2017 18:56
Avatar
rdaek
Člen
Avatar
rdaek:9.6.2017 19:32

Nevim syntaxi pythonu (neznám ho), ale myslim ze bys mel do metod strength, health a agility předávat help_var odkazem a ne hodnotou - dojde tim ke "zkopírování" promene na nove místo v paměti a změny se po opuštění funkce nepromítnou do help_var. Pokud ji předáš jako odkaz, dojde ke změně i v hlavním while cyklu a pojede to ;) Zkus pohledat tady nebi na netu předání odkazem vs předání hodnotou ;)

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
9.6.2017 19:32
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na David Mikšaník
gcx11:9.6.2017 20:36

Myslím, že zatím pořád nechápeš OOP v Pythonu.

Toto je třída, která reprezentuje abstrakci objektu z reálného světa (například psa):

class Pes: pass

Díky ní můžeme vyrábět konkrétní objekty, psy Azora a Alíka:

alik = Pes()
azor = Pes()

Ale každý pes (objekt) se drobně liší v určitých vlastnostech (atributy objektu), takže upravíme třídu:

class Pes:

      def __init__(self, jmeno, vek, majitel):
            self.jmeno = jmeno
            self.vek = vek
            self.majitel = majitel

A použití:

alik = Pes("Alík", 2, "Novák")
azor = Pes("Azor", 5, "Notovný")

Do třídy jsme přidali metodu konstruktoru pro objekty. Konstuktor se zavolá, když se vytváří nový objekt dané třídy. Parametr self je právě ten nový objekt, kterému postupně přidáváme atributy a nastavujeme jejich výchozí hodnoty.

Bez metody konstruktoru by kód vypadal takto:

alik = Pes()
alik.jmeno = "Alik"
alik.vek = 2
alik.majitel = "Novák"

Na objektech stejné třídy můžeme mít volat nějaké metody. Například zaštěkej, zestárni...
Metody pro objekty se ve třídě definují takto:

class Pes:

      def __init__(self, jmeno, vek, majitel):
            self.jmeno = jmeno
            self.vek = vek
            self.majitel = majitel

      def zestarni(self, pocet):
            self.vek = self.vek + pocet

Alík zestárne o 24 let, zatímco Azor, co létá kolem černé díry, zestárne o jeden rok.

alik.zestarni(24)
azor.zestarni(1)

Možná stále není jasné, proč musíme do metod ve třídě psát self. Je to proto, že Python ve skutečnosti volá toto:

Pes.zestarni(alik, 24)
Pes.zestarni(azor, 1)

Tudíž je třeba do metod objektů vkládat jako první parametr self. A přes něj pak můžeme přistupovat na jednotlivé atributy objektu (jelikož self = objekt, na kterém metodu voláme).

A nakonec, statické metody a atributy. Statické metody a atrubitu patří ke třídě, ne k objektu! Tudíž pro každý objekt jsou stejné.

Deklarují se takto:

class Pes:

          druhove_jmeno = "Canis lupus familiaris"

          ...

Na ně se pak přistupuje převážně přes třídu:

print(Pes.druhove_jmeno) # vypíše Canis lupus familiaris

Ale lze i přes objekt:

print(alik.druhove_jmeno)
print(azor.druhove_jmeno)

Statické metody nemají parametr self, protože nedostávájí instanci objektu, jelikož se volají na třídě.

@staticmethod
def vrat_druhove_jmeno(): return druhove_jmeno
 
Nahoru Odpovědět
9.6.2017 20:36
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na David Mikšaník
gcx11:9.6.2017 20:42

Proto je kód z větší části špatně.

Zbytečné závorky:

class Fighther():

Na třídě Set_skills voláš choice a jako parametr dáš tu samou třídu? O_o

def ability(self):
        Set_skills.choice(Set_skills)

V této metodě sice změněné help_var vracíš, ale už s ním nic neděláš.

self.strength(help_var)
 
Nahoru Odpovědět
9.6.2017 20:42
Avatar
David Mikšaník:9.6.2017 21:50

gcx11↑, ok díky ti za lepší vysvětliení, podívu se tedy znovu a zkusím to předělat

rdeak ↑, díky ti za takový postřeh. Hledal jsem na netu, rozdíl mě napadl hnedka, ale horší bylo to jak to napsat tak, aby to v Pythonu fungovalo.

Ještě sem potom nad tím dumal, a přišel jsem na toto. Ale je to takové látaní...

Nechci zde, dělat reklamu, ale kdo by řešil podobný problém tak jsem čerpal z těchto infromací
https://edux.fit.cvut.cz/…funkceii.pdf

Takže, jsem vlastně udělal jen změnu, že jsem začal předávat parametr odkazem místo hodnotou (viz str. 7 ↑)
Změnu kódu posílám, kdyby někdo někdy řešil podobný problém

class Set_skills(Fighther):


    def choice(self):
        help_var = [10]
        print('Skills: ', help_var[0],
              '\n================'
              '\n1 - Strength'
              '\n2 - Health'
              '\n3 - Agility'
              '\n4 - End (I do not extra skills :])'
              '\n================')
        while help_var[0] > 0:
            print('Count skills:', help_var[0])
            choice = int(input('Your choice [1--4]: '))
            if choice == 1:
                self.strength(help_var)
            elif choice == 2:
                self.health(help_var)
            elif choice == 3:
                self.agility(help_var)
            elif choice == 4:
                break
            else:
                print('Invalid choice!')

    @classmethod
    def strength(cls, help_var):
        print('Count skills:', help_var[0])
        x = [int(input('How many points skill you want add for STRENGTH:'))]
        help_var[0] = help_var[0] - x[0]
        print('Count skills:', help_var[0])
        return help_var[0]

    @classmethod
    def health(cls, help_var):
        print('Count skills:', help_var[0])
        x = [int(input('How many points skill you want add for HEALTH:'))]
        help_var[0] = help_var[0] - x[0]
        print('Count skills:', help_var[0])
        return help_var[0]

    @classmethod
    def agility(cls, help_var):
        print('Count skills:', help_var[0])
        x = [int(input('How many points skill you want add for AGILITY:'))]
        help_var[0] = help_var[0] - x[0]
        print('Count skills:', help_var[0])
        return help_var[0]]
 
Nahoru Odpovědět
9.6.2017 21:50
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na David Mikšaník
gcx11:10.6.2017 1:12

Což je strašný humus, předávat to jako pole. Úplně jednoduše by stačilo používat tu hodnotu, co si vracíš returnem.

 
Nahoru Odpovědět
10.6.2017 1:12
Avatar
rdaek
Člen
Avatar
Odpovídá na gcx11
rdaek:10.6.2017 9:58

Jo, každopádně jsem přehlédl to co zmiňuje gcx11. Vracíš si z funkcí změněnou help_var pomoci return help_var. Takze by do původního kódu mělo stačit změnit help_var = self.strength(hel­p_var) a podobně u ostatních ;)

Nahoru Odpovědět
10.6.2017 9:58
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.