Optymilizacja kodu, przerobienie kodu na funkcje

1

Podpisuję się pod wypowiedzią @twoj_stary_pijany, co prawda nie zwracałbym w funkcji tekstu, a wrzucił do słownika operacji lub utworzył drugi na teksty tak by były w jednym miejscu.
W funkcjach wykonujących poszczególne operacje w sumie możesz usunąć rzutowanie na int, bo funkcja "gra" dba o to by trafiały tam int'y. Twój print wyniku lepiej by wyglądał w ten sposób:

print(f"Suma wynosi: {liczba1} + {liczba2} = {suma}")

i faktycznie ... widać że break i continue umiesz już używać, więc teraz przestań to robić :)

0

@twoj_stary_pijany: Przy lini koncowej

print(f"{liczba1} {wyborek} {liczba2} == {operation(liczba1, liczba2)}")

dostaję bład: 'str' object is not callable. Wyszukałem w internecie, ze jest to wyjatek błędu. Poczytałem sobie o tym błędzie i są przykłady jak rozwiązać ten problem, ale mi coś nie wychodzi....

mnozenie = '*'
dodawanie = '+'
odejmowanie = '-'
dzielenie = '/'

operations = {
    '*': mnozenie,
    '+': dodawanie,
    '-': odejmowanie,
    '/': dzielenie
}

def wybory_menu():
    while True:
        
        wyborek = input ("Podaj wybór działania matematycznego:   '"+ "' '".join(operations) +"' : ")
        if wyborek not in operations :
            print('Nic nie wpisałeś lub podałeś nieprawidłowe dzialanie matematyczne! - Podaj prawidłowe dane! ')
            return wybory_menu()
        else:
            return wyborek

def gra(gracze):

    while True: 
        try:
            podaj = int(input(f' Wybierz dwie liczby, które możesz dodać, odjąć, pomnożyć, lub podzielić: \n Podaj {gracze} ')) 
            break
        except ValueError:
            print('Blad wpisywania wartosi! Podaj wartość liczbową: ')
    return podaj

def dodawanie(liczba1,liczba2):

    return liczba1 + liczba2, dodawanie

def odejmowanie(liczba1,liczba2):
    return liczba1 - liczba2, odejmowanie    

def mnozenie(liczba1,liczba2):
    return liczba1 * liczba2, mnozenie

def dzielenie(liczba1,liczba2):
    return liczba1 / liczba2, dzielenie

liczba1 = gra('liczbę pierwszą: ')
liczba2 = gra('liczbę drugą: ')
   

wyborek = wybory_menu()
operation = operations[wyborek]
print (f"{liczba1}  {wyborek} {liczba2} == {operation(liczba1, liczba2)}")

Przed operations musiałem zdefiniować zmienne: mnozenie, dodawanie, dzielenie itp...., bo miałem błąd w kodzie..Jak dojdę z tym błedem co i jak, to dalej będę "upraszczał" ten program :)

0

Nie chcę tu nikogo w żaden sposób dołować, czy zniechęcać do czegokolwiek, ale mam wrażenie, że programowanie może nie być dla Ciebie. Albo poziom koncentracji przy nauce jest u Ciebie zbyt niski, albo poświęcasz jednak na to zbyt mało czasu, bo te początki u Ciebie idą strasznie ciężko. Nie każdy ma "talent" do programowania, tak jak jest to z każdym innym złożonym zajęciem jak np. gotowaniem czy malowaniem. Każdy może się tego nauczyć, ale niektórzy nauczą się szybko, a niektórzy będą ćwiczyć godzinami by osiągnąć jakikolwiek sukces. Wałkujesz funkcje, stringi i print od ponad miesiąca i nadal masz problem ze zrozumieniem dość prostego problemu, przy którym komunikat o błędzie, dokładnie mówi Ci gdzie i jaki masz błąd. Do tego ten błąd występuje w Twoim własnym kodzie, który powinieneś dobrze znać i rozumieć jak działa, ale z jakiejś przyczyny tak nie jest. Uczysz się dla siebie, by rozprostować szare komórki, na to jest bardzo wiele sposobów, nie musisz się na siłę trzymać programowania. Jeżeli jednak mimo wszystko chcesz dalej w to brnąć to najlepiej chyba kupić jakąś książkę do nauki Pythona, rozplanować sobie naukę i ją całą przerobić od deski do deski, zanim weźmiesz się za jakieś swoje własne konstrukcje i projekty, w których ciężko jest Ci zrozumieć co, kiedy i dlaczego się dzieje. Jest to moja osobista ocena tego co tu się dzieje na podstawie własnych obserwacji, Ty i nikt inny nie musi się z nią zgadzać, ale może coś w tym jest? ;)

0

@twoj_stary_pijany:

Edit:
I przestań używać break i continue. Zastanów się jak przepisać ten kod w taki sposób, żeby ich nie było w kodzie. Używanie break to jest bardzo zła praktyka. Używaj return wartosc_do_zwrocenia, żeby wyskoczyć z pętli/funkcji. Jeżeli nie jesteś w funkcji to najwidoczniej musisz opakować swój kod w funkcję.

Zrobiłem kod bez używania break i continue, opakowałem to we funkcję. Krótko i na temat: czy może tak to wyglądać?

opcje = ['T','t','N','n']
wybor = 't' 

def gra(gracze):
    while True: 
        try:
            podaj = int(input(f' Wybierz dwie liczby, które możesz dodać, odjąć, pomnożyć, lub podzielić: \n Podaj {gracze} ')) 
            break
        except ValueError:
            print('Blad wpisywania wartosi! Podaj wartość liczbową: ')
    return podaj 

def wybory_menu():
    while True:
        wyborek = input ("Podaj wybór działania matematycznego:   '"+ "' '".join(operations) +"' : ")
        if wyborek not in operations :
            print('Nic nie wpisałeś lub podałeś nieprawidłowe dzialanie matematyczne! - Podaj prawidłowe dane! ')
            return wybory_menu()
        else:
            return wyborek

def czy_liczysz_dalej():
    wejscie = input('Grasz dalej t/n : ')
    if wejscie not in opcje:
        print('Zle wpisałes!, wpisz poprawną odpowiedz!')
        return czy_liczysz_dalej()
    if (wejscie == 'n') or (wejscie =='N'):
        print('Zakonczono liczenie.')
        return exit()

while wybor == 't' or 'T' :
    def dodawanie(liczba1,liczba2):
        return liczba1 + liczba2

    def odejmowanie(liczba1,liczba2):
        return liczba1 - liczba2  

    def mnozenie(liczba1,liczba2):
        return liczba1 * liczba2

    def dzielenie(liczba1,liczba2):
        return liczba1 / liczba2

    liczba1 = gra('liczbę pierwszą: ')
    liczba2 = gra('liczbę drugą: ')


    operations = {
    '*': mnozenie,
    '+': dodawanie,
    '-': odejmowanie,
    '/': dzielenie
    }


    wyborek = wybory_menu()
    operation = operations[wyborek]
    print (f"{liczba1}  {wyborek} {liczba2} == {operation(liczba1, liczba2)}")
    czy_liczysz_dalej() 



I ostatnie pytanko z mojej strony, dlaczego uzywanie break , continue to zła praktyka?, jak w uczeniu się pythona te instrukcje często występują? Pytam z ciekawości :) Pozdrawiam

0

Czy zrobiłeś kod bez break? Nie.
Czy może to tak wyglądać? tak, kod nie jest jakoś przesadnie długi czy skomplikowany i działa.
Czy jest to kod, który jest śliczny? Nie. Mnie drażni nawet brak spacji po przecinku ;)
Używanie break i continue moim zdaniem nie zawsze jest złą praktyką, ale zazwyczaj są po prostu ładniejsze (czytelniejsze i praktyczniejsze) rozwiązania.

1

@pythonowiec74: Kilka rzeczy

  1. Spójrz na ten przykład
>>> wybor = "t"
>>> wybor == "t" or "T"
True
>>> wybor = "n"
>>> wybor == "t" or "T"
'T'
>>> bool(wybor == "t" or "T")
True

Przypisałeś do zmiennej wybor "t" i nigdzie tego nie zmieniasz. A w dodatku ten warunek jest błędny. Prawidłowy warunek powinien wyglądać:

while wybor in ["t", "T"]:

a następnie w pętli powinieneś zrobić coś w stylu:

wybor = input("Grasz dalej t/n : ")
  1. Robiąc coś takiego
while wybor == 't' or 'T' :
    def dodawanie(liczba1,liczba2):
        return liczba1 + liczba2
    ...

za każdą iteracją pętli przedefiniowujesz swoje funkcje. Zamiast tego możesz je wyciągnąć na zewnątrz. Np. tak:

def dodawanie(liczba1,liczba2):
    return liczba1 + liczba2
...

while wybor == 't' or 'T' :
    liczba1 = gra('liczbę pierwszą: ')
    liczba2 = gra('liczbę drugą: ')
    ...
  1. Spróbuj sobie opakować wszystko w funkcję. Spróbuj czegoś takiego:
def gra(gracze):
    ...

def wybory_menu():
    ...

def czy_liczysz_dalej():
    ...

def dodawanie(...):
    ...

def odejmowanie(...):
    ...
...
def main():
    while ...
      ...

main()

(zepsuło mi wcięcia w tym snippecie, nie wiem jak to naprawić, próbowałem na kilka sposobów, tym na górze też zepsuło)

Spróbuj zrobić tak, żebyś miał cały swój kod do uruchomienia w funkcji main(). Ostatnią linijką w programie daj wywołanie tej funkcji.

  1. Dalej używasz break. Używasz też exit, które jest czymś podobnym.

  2. Dlaczego break, continue są złe?
    Przede wszystkim chodzi o to, że kod assemblerowy, imperatywny wygląda mniej więcej tak, źródło - https://ww2.ii.uj.edu.pl/~kapela/pn/print-lecture-and-sources.php

        cmp eax, ebx
        jle else_
        mov ecx, ebx
        jmp koniec
else_:  mov ecx, eax
        sub ecx, ebx
koniec:

W pierwszej linijce robisz jakieś porównanie, później w zależności od wyniku skaczesz pod etykietę else_. Następnie jest jakaś linijka z przenoszeniem danych z jednego rejestru do drugiego, później znowu jakiś skok. Najlepsze jest to, że te skoki mogą być w miejsca, które są kompletnie z czapy. Jeżeli napiszesz kiedyś program w asemblerze dłuższy niż 1000 linijek to zrozumiesz, że trzeba się nieźle nagłowić, żeby to ładnie napisać.

Powyższy kod w pythonie wygląda tak:

if first_var == second_var:
    do_sth()
else:
    do_sth_else()

W programowaniu obiektowym definiujesz sobie jakieś funkcje, obiekty, modyfikatory dostępu i nie możesz sobie już skakać gdzie chcesz. Odpalasz jakieś funkcje, które masz w swoim zasięgu, dzięki temu kod jest czytelniejszy i łatwiejszy w utrzymaniu bo nie możesz już sobie skakać gdzie chcesz. Łatwiej szuka się błędów. Od czasu asemblera wyewoluowaliśmy jako gatunek ludzki, powstała amfetamina, samoloty i programowanie funkcyjne oraz obiektowe, ale co z tego skoro ludzie w językach wysokiego poziomu, który kładzie nacisk na czytelność kodu piszą jak w asemblerze?

0

Dalej popelniasz te same bledy. Juz kilka stron temu bylo Ci cos wyjasnione a teraz znowu wklejasz taki sam kod (while true... Itd)

0

@Arthan: Gdzie tu panowie widzicie w kodzie : break, continue itp...., bo normalnie albo ja niedowidzę.... , nie widzę u w kodzie żebym stawiał break itp... Stosowałem return. (ok, jeden break jest w funkcji gra). Ale to może być wyjątek chyba :)
@twoj_stary_pijany Cóż pokombinuję w wolnej chwili, choć dla mnie kod powinien przede wszystkim działać bez problemu :) , poprawcie mnie jeśli się mylę :) Jak się domyślam chodzi pewnie o czytelność kodu dla innych, i czas pewnie :) Jesli chodzi o tzw skoki w trakcie wykonywania kodu, to sprawdzam to samym debugerem , i robię podgląd "skoku" z lini do lini w trakcie działania kodu jak się domyślam... I prawidłowy "skok" powinien być z miejsca do miejsca uporządkowany , ze tak to nazwę...?

0
  1. Przestań używać debuggera podczas pisania kodu.
  2. Jeden break to wciąż jeden break za dużo.
  3. Masz jeszcze exit zamiast którego też powinieneś zrobić return.
  4. Pokazałem Ci już przy while wybor == 't' or 'T', że ten kod nie działa tak jak myślisz, że działa.
  5. Gdyby nie chodziło o czytelność kodu to pisalibyśmy w asemblerze.
  6. Ja już się nie udzielam, przekazałem już swoje wskazówki. Zrób sobie przysługę, przeskocz od razu fazę wyparcia i je przeanalizuj szybciej niż później to zaoszczędzisz sporo swojego i naszego czasu.
0

Witam ponownie. Wklejam ostatni raz juz moją poprawkę. Uwagi mile widziane cały czas. Co do break, są tu rózne opinie na temat stosowania tej instrukcji break, continue. Rozumiem , jakbym tych break'ów miał trochę w kodzie, ale jeden chyba nie zaszkodzi, tym bardziej że jest stosowany w wyjątku. Program działa bez problemu. Jeśli byłaby możliwość , dajcie swój kod , jakbyście to trochę przerobili czy to z break czy bez... Przy okazji mam takie pytanie, lepiej jest tworzyć kod w strukturalnym czy obiektówce? Co jest praktyczniejsze , czytelniejsze itp...

opcje = ['T','t','N','n']
wybor = 't' 


def gra(gracze):
    while True: 
        try:
            podaj = int(input(f' Wybierz dwie liczby, które możesz dodać, odjąć, pomnożyć, lub podzielić: \n Podaj {gracze} ')) 
            break
        except ValueError:
            print('Blad wpisywania wartosi! Podaj wartość liczbową: ')
    return podaj 

def wybory_menu():
    while True:
        wyborek = input ("Podaj wybór działania matematycznego:   '"+ "' '".join(operations) +"' : ")
        if wyborek not in operations :
            print('Nic nie wpisałeś lub podałeś nieprawidłowe dzialanie matematyczne! - Podaj prawidłowe dane! ')
            return wybory_menu()
        else:
            return wyborek
    

def czy_liczysz_dalej():
    wejscie = input('Grasz dalej t/n : ')
    if wejscie not in opcje:
        print('Zle wpisałes!, wpisz poprawną odpowiedz!')
        return czy_liczysz_dalej()
    if (wejscie == 'n') or (wejscie =='N'):
        print('Zakonczyles liczenie')
        return exit()
    
def dodawanie(liczba1,liczba2):
    return liczba1 + liczba2

def odejmowanie(liczba1,liczba2):
    return liczba1 - liczba2  

def mnozenie(liczba1,liczba2):
    return liczba1 * liczba2

def dzielenie(liczba1,liczba2):
    return liczba1 / liczba2

operations = {
'*': mnozenie,
'+': dodawanie,
'-': odejmowanie,
'/': dzielenie
}
def main():
    
    while wybor in ['T','t']:
        liczba1 = gra('liczbę pierwszą: ')
        liczba2 = gra('liczbę drugą: ')
        wyborek = wybory_menu()
        operation = operations[wyborek]
        print (f"{liczba1}  {wyborek} {liczba2} == {operation(liczba1, liczba2)}")
        czy_liczysz_dalej() 
main()






0
def gra(gracze):
    while True: 
        try:
            podaj = int(input(f' Wybierz dwie liczby, które możesz dodać, odjąć, pomnożyć, lub podzielić: \n Podaj {gracze} ')) 
            return podaj
        except ValueError:
            print('Blad wpisywania wartosi! Podaj wartość liczbową: ')

Serio ten break był tam tak potrzebny? Oszukujesz sam siebie.

0

@twoj_stary_pijany:

Serio ten break był tam tak potrzebny? Oszukujesz sam siebie.

Ile ludzi tyle opinii na temat break'a. Ale będę miał na uwadze, żeby ewentualnie breaka returnem zastąpić w przyszłych moich kodach. Fakt, nie wiedziałm, że w wyjątku mogę breaka zastąpic returnem. Muszę Wam powiedzieć, że naprawdę pomogliście mi trochę zrozumieć tego "Pythona". Idzie mi jak idzie, widać to po waszych komentarzach :), ale jednak pomagacie mi podpowiedziami :) Dzięki szczerze. Jeszcze trochę poćwiczę na strukturze, a potem obiektówka. Pozdrawiam

0

Tak po prawdzie to nie jest tak do konca kod strukturalny a raczej proceduralny.

https://pl.wikipedia.org/wiki/Programowanie_strukturalne#Wczesne_wyj%C5%9Bcie


def wybory_menu():
    while True:
        wyborek = input ("Podaj wybór działania matematycznego:   '"+ "' '".join(operations) +"' : ")
        if wyborek not in operations :
            print('Nic nie wpisałeś lub podałeś nieprawidłowe dzialanie matematyczne! - Podaj prawidłowe dane! ')
            return wybory_menu()
        else:
            return wyborek

czy moglbys prosze skonczyc pisac wszedzie gdzie sie da while true?

0

@pythonowiec74:

pythonowiec74 napisał(a):

Ile ludzi tyle opinii na temat break'a. Ale będę miał na uwadze, żeby ewentualnie breaka returnem zastąpić w przyszłych moich kodach.

Breaka można używać, ale Ty robisz to kompletnie źle, głównie przez ten while True.
Wrzuć aktualną, poprawioną wersję.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.