Pomoc w kodzie napisanym własnoręcznie.

3

Witam, mam 47 lat i na stare lata postanowiłem nauczyć się kodowania (dla siebie tylko, żeby rozprostować szare komórki) . Wybrałem Pythona. Mam problemik z małym programikiem utworzonym przeze mnie. To jest kod programu:

opcje = [1,2,3]
def petla(gracz):
    while True:
        wybor = input(f'{gracz}podaj liczbę od 1 do 3: ')
        if wybor in opcje:
            return wybor

def zgadnij_liczbe(piotr, adam):
    if piotr == 1 or adam == 1:
        print('Wygrales samochod')
    elif piotr == 2 or adam == 2:
        print('Wygrales 10000 PLN')
    elif piotr ==3 or adam ==3:
        print('Wygrales wycieczke na Majorkę!!!')

piotr = petla('Piotr: ')
adam = petla('Adam: ')

Mam wywołanie tyko: Piotr: podaj liczbę od 1 do 3:
Jak podaję jakąś liczbę, to zamiast pytać o drugiego gracza Pawła, to pętluje mi na Piotr cały czas! Gdzie robię bład. Wcięcia mam dobrze porobione, jak myślę.

Piotr: podaj liczbę od 1 do 3: 5
Piotr: podaj liczbę od 1 do 3: 6
Piotr: podaj liczbę od 1 do 3: 3
Piotr: podaj liczbę od 1 do 3: 2
Piotr: podaj liczbę od 1 do 3: 1
Piotr: podaj liczbę od 1 do 3:

Z góry dziękuję za podpowiedzi. Na stare lata chciało mi się uczyć programonia :)

1

Bo python tekstu nie odnajduje wśród liczb. Input zwraca tekst (str).

3

input zwraca ci stringa, więc if wybor in opcje: sprawdza czy dany string (np. "1", "2", "3") jest w liście. Ponieważ w liście nie ma stringów, tylko są liczby, to nigdy nie będzie to prawdziwe.

Musisz to przekonwertować do liczby najpierw np. za pomocą funkcji int, która zwróci ci liczbę albo rzuci wyjątkiem, jeśli użytkownik wpisał np. "abc", czy coś innego, co się nie da przekonwertować do inta.

Alternatywnie możesz zamiast listy liczb zrobić listę stringów: ["1", "2", "3"], wtedy nie będzie wymagana konwersja (ale wtedy wszędzie musisz to traktować jak string, bo np. 1 == "1" zwróci False).

0

@LukeJL: Dzięki za pomoc. Zrobiłem listę stringów. Jeśli wpisuję 1 przy Piotrze i 1 przy Adamie to nie mam info ,ze wygrałem samochód... Pokombinuję jeszcze

1

No ale tam masz w kodzie:
if piotr == 1 or adam == 1:
więc jeśli zamieniłeś na listę stringów, to tu też musisz poprawić, żeby sprawdzał stringa:
if piotr == "1" or adam == "1":

0

@LukeJL: Zrobiłem tak w if również... '1' , ale i tak nie mam info o tym ze wygralem auto.... Pokombinuje

6

A zgadnij_liczbe() to się magicznie samo nie wywoła. Bo ty nigdzie nie wołasz

0

@AnyKtokolwiek: Racja, dzieki za podpowiedz :)

piotr = petla('Piotr: ')
adam = petla('Adam: ')
wynik = zgadnij_liczbe(piotr,adam)

Teraz działa :)

1

Po pierwsze bardzo fajnie, że wpadłeś na taki pomysł, od siebie polecam też planszówki, na rynku jest masa tytułów, które nieźle potrafią zmusić do myślenia :) Programowanie jest o tyle fajne że można je łączyć z innymi, w zasadzie dowolnymi zainteresowaniami, lubisz sudoku, albo inne łamigłówki? Zawsze możesz stworzyć własną wersję tej gry (sudoku robiłem kiedyś w wersji konsolowej i spokojnie znając podstawy można coś takiego zrobić).

Wracając do Twojego kodu ...
Mógłbyś zrobić tablicę nagród, a nie samych liczb.
Trochę to wszystko dziwnie zaprojektowane, na końcu mamy komunikat, że ktoś wygrał, nie wiadomo kto, obaj gracze grają drużynowo czy jak? Nie bardzo da się w to pograć, bo nagrody są zawsze pod tymi samymi wyborami.
Funkcja "petla" dba o to by użytkownik wprowadził prawidłowy wybór, to może niech też mówi o tym że ktoś wprowadził nieprawidłowy?

Nudziło mi się trochę, więc stworzyłem taką wariację Twojego programu...

from random import shuffle

# tablica z nagrodami
nagrody = [
    'samochód',
    '10000 PLN',
    'wycieczke na Majorkę!!!',
    'miesięczny zapas kabanosów',
]

# tablica z graczami biorącymi udział w grze
gracze = [
    'Piotr',
    'Adam',
    'Wiechu',
]

# ile łącznie jest bramek z których gracze mogą losować nagrody
ilosc_bramek = 7

# mamy tyle bramek z nagrodami ile jest nagród + puste bramki,
# tak by razem było ich tyle ile jest w ilosc_bramek
bramki = nagrody + ['nic']*(ilosc_bramek-len(nagrody))

# przemieszanie kolejności bramek
shuffle(bramki)

# pobieranie wyboru bramki od użytkownika
def wybierz(gracz):
    while True:
        wybor = input(f'{gracz} wybierz jedną z {ilosc_bramek} bramek: ')
        if not wybor.isnumeric():
            print('To nie jest liczba!')
            continue
        wybor = int(wybor)
        if 1 <= wybor <= ilosc_bramek:
            return wybor
        else:
            print('Nieprawidłowy wybór!')

# wyświetlanie informacji o tym co wygrał dany gracz
def co_wygral(imie, wybor):
    print(f'{imie} wygrales {bramki[wybor-1]}')

# pobieranie wyborów od wszystkich graczy
wybory_graczy = []
for gracz in gracze:
    wybory_graczy.append(wybierz(gracz))

# wyświetlanie wyników wszystkich graczy
for nr, gracz in enumerate(gracze):
    co_wygral(gracz, wybory_graczy[nr])
    
print('Bramki z nagrodami wyglądały tak:')
for nr, bramka in enumerate(bramki):
  print(f'Bramka {nr+1}: {bramki[nr]}')

Można by też zrobić tak by każda bramka mogłaby być wybrana tylko raz.

0

@Arthan: Dzięki za dopracowanie kodu. W tym moim programiku chodził mi o zrozumnie jak działają funkcje, a mniejsza z samym zrozumieniem tego działającego programu :) Uczę się z samych tutoriali wideo z netu.. A potem sam sobie tworzę , modyfikuję swoje programy w praktyce. Żadnych książek nie uzywam, nie mam zamiaru. Uczę się tylko praktycznie robić kod na własnych błedach. Wiem, że sam sens tego programu jest trochę bez ładu ( jak sam Polski Ład :) ) Przestudiuję twój kod linijka po linijce:) Tu mam jeszcze pytanie, programiku Tabliczki mnożenie i dodawania w , który utworzyłem w kodzie. Wszystko działa bez problemu. Pytanie, czy nie można prościej tego kodu zrobić?, bardziej go zaoptymilizować? Wszystko zmieścić w jednej funkcji?? Cóż może za rok, dwa, zacznę sobie dorabiać, jeśli chodzi o Pythona ha ha ha

#tabliczka mnożenie sposób 2
a = 0
while a < 3:

    def gracze(gracz):
        wybor_liczb = input(f' {gracz} podaj liczbę: ')
        return wybor_liczb
    def mnozenie(Gracz1,Gracz2):
        return int(Gracz1) * int(Gracz2)
    Gracz1 = gracze('Adam')
    Gracz2 = gracze('Piotr') 
    wynik = mnozenie(Gracz1,Gracz2)
    print('Wynik mnożenia to: ',wynik)

    #Dodawanie
    def gracze(gracze):
        wybor_liczb = input(f' {gracze} podaj liczbę: ')
        return wybor_liczb
    def dodawanie(Gracz1,Gracz2):
        return int(Gracz1) + int(Gracz2)
    Gracz1 = gracze('Adam')
    Gracz2 = gracze('Piotr') 
    wynik = dodawanie(Gracz1,Gracz2)
    print('Wynik dodawania to: ',wynik)

Co do twojego zmodyfikowanego kodu, to nie wszystko jeszcze w nim rozumiem :), niektóre zmienne są dla mnie nowością. Ale chętnie przestudiuję ten kod w wolnej chwili. Niestety , praca,(nie związana z programowaniem) , dom(obowiązki) , programowanie(hobby) to trzeba jakoś pogodzić :) A wiadomo jak jest z czasem :)

1

Ja wychodzę z założenia, że jak coś już robić to niech to ma jakikolwiek sens ;)

Jeśli to cały kod, to nie, nie działa on dobrze ;) Bo nigdzie nie zwiększasz licznika pętli, nigdzie nie zwiększasz "a".
Kodu jest w sumie niewiele, ale co można by tu zmienić?

Sama pętla - while używamy gdy nie wiemy tak naprawdę ile razy wykonujemy daną pętlę, czyli np. mógłbyś po wykonaniu pętli zapytać się użytkownika czy chce on wykonać obliczenia ponownie, jeśli nie to przerwać pętlę. Jeżeli wiesz ile razy pętla ma się wykonać. Np. chcesz żeby zawsze wykonywała się 3 razy to daj pętlę for.

Definicje funkcji umieściłbym przed samą pętlą. Definiujesz teraz dwa razy taką samą funkcję "gracze", raz wystarczy. Czym więcej funkcji tym lepiej, pod warunkiem, że kod się nie powtarza.

Nazwy mogłyby być bardziej intuicyjne: funkcja z założenia ma wykonywać jakąś czynność, więc ja bym to nazwał np.: "pobierz_liczbe", "wykonaj_mnozenie", a Gracz1, Gracz2 zmieniłbym na liczba1, liczba2. Ogólnie z dużych liter to się podaje tylko nazwy klas w Pythonie.

Dobrą praktyką też jest zwracanie uwagi na takie szczegóły jak spacje, przecinki itd. po przecinku dajemy spację.

Ucz się z czego chcesz, tylko pisz, pisz jak najwięcej :)

0

@Arthan: Tego za bardzo nie mogę zrozumieć? Mógłbyś mnie w kodzie poprawić?

Definicje funkcji umieściłbym przed samą pętlą. Definiujesz teraz dwa razy taką samą funkcję "gracze", raz wystarczy. Czym więcej funkcji tym lepiej, pod warunkiem, że kod się nie powtarza.

Poprawiłem trochę kod o twoje sugestie:

#tabliczka mnożenie sposób 2
for i in range(3):  #Program wykona się 3 razy
   

    print('Mnożenie: ')
    def gracze(gracz):
        pobierz_liczbe = input(f' {gracz} podaj liczbę: ')
        return pobierz_liczbe
    def wykonaj_mnozenie(liczba1,liczba2):
        return int(liczba1) * int(liczba2)
    liczba1 = gracze('Adam')
    liczba2 = gracze('Piotr') 
    wynik = wykonaj_mnozenie(liczba1, liczba2)
    print('Wynik mnożenia to: ', wynik)

    #Dodawanie
    print('Dodawanie: ')
    def gracze(gracze):
        pobierz_liczbe = input(f' {gracze} podaj liczbę: ')
        return pobierz_liczbe
    def wykonaj_dodawanie(liczba1, liczba2):
        return int(liczba1) + int(liczba2)
    liczba1 = gracze('Adam')
    liczba2 = gracze('Piotr') 
    wynik = wykonaj_dodawanie(liczba1, liczba2)
    print('Wynik dodawania to: ', wynik)
    

Mam nadzieję, ze trochę to lepiej wygląda... :)

1

teraz robisz coś takiego ....
zaczynasz pętlę a w niej:

  • definiujesz funkcje "gracze" i "wykonaj_mnozenie"
  • pobierasz liczby
  • obliczasz i wyświetlasz wynik
  • przechodzisz do dodawania i ...
  • znów definiujesz taką samą funkcję "gracze", którą już masz zdefiniowane i robi ona to samo
  • potem robisz wszystko inne co dotyczy dodawania
  • gdy kończy się iteracja, czyli gdy dochodzisz do końca wykonywania kodu w danym powtórzeniu pętli, to Python "zapomina" o wszystkich funkcjach, zmiennych, obiektach itd., które zostały w niej utworzone.
    Za drugim i trzecim powtórzeniem znów dzieje się to samo do początku.
    Możesz wyciągnąć funkcje przed pętlę, a w pętli tylko się do nich odwoływać.
#tabliczka mnożenie sposób 2

def gracze(gracz):
    pobierz_liczbe = input(f' {gracz} podaj liczbę: ')
    return pobierz_liczbe

def wykonaj_mnozenie(liczba1,liczba2):
    return int(liczba1) * int(liczba2)

def wykonaj_dodawanie(liczba1, liczba2):
    return int(liczba1) + int(liczba2)

for i in range(3):  #Program wykona się 3 razy

    print('Mnożenie: ')
    liczba1 = gracze('Adam')
    liczba2 = gracze('Piotr') 
    wynik = wykonaj_mnozenie(liczba1, liczba2)
    print('Wynik mnożenia to: ', wynik)

    #Dodawanie
    print('Dodawanie: ')
    liczba1 = gracze('Adam')
    liczba2 = gracze('Piotr') 
    wynik = wykonaj_dodawanie(liczba1, liczba2)
    print('Wynik dodawania to: ', wynik)
0

@Arthan: Dzięki, nie wiedziałem nawet , ze można, też w taki sposób. Fakt , że kod wygląda lepiej, no i nie mam podwójnych "graczy". Duuuzo nauki przede mną jest , jak widzę :) Porównując samo wykonanie kodu w obydwóch programach ( ten mój , i ten twój z modyfikacją) to różnicy w samym wykonaniu programu nie robi moim zdaniem. Identycznie jak zauważyłem się programy wywołują jeśli chodzi o mnożenie i dodawanie....Jeszcze raz dzięki za "rozjasnianie" tematu w tym :) Pozdrawiam serdecznie

1 użytkowników online, w tym zalogowanych: 0, gości: 1