Wyjątek ValueError a pętla for

Wyjątek ValueError a pętla for
Sevy
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Katowice
  • Postów:20
0

Cześć. Na początku chciałbym się przywitać bo to mój pierwszy post. :)

Napisałem krótki quiz z tabliczki mnożenia. Pięć pytań, licznik punktów, itd.
W odpowiedzi należy podać liczbę, ale liczę się z tym, że ktoś może wpisać coś innego, więc nie chcę, żeby wyskakiwał mi błąd, dlatego chciałem dodać wyjątek "ValueError".
Próbowałem w niego wsadzić całą pętlę, ale po wpisaniu pięciokrotnie błędu pętla się kończy i tyle. Chciałbym, żeby zadawało pytanie dopóki użytkownik nie wpisze liczby.

Kopiuj
import random

points = 0

for answers in range(0, 5):
    numberA = random.randint(1, 10)
    numberB = random.randint(1, 10)
    result = numberA * numberB
    print('Ile to jest', numberA,'razy', str(numberB) + '?')
    answer = int(input('Odpowiedź: '))
    if answer == result:
        points+=1
        print('Dobrze! Zdobyłeś punkt!')
    else:
        print('Błąd!')
print('Twój wynik to:', str(points) +'/5 punktów')

@Edit:

Chyba dałem radę w inny sposób, ale jakoś nie jestem do tego przekonany.

Kopiuj
import random

points = 0
a = 1

while a <= 5:
    numberA = random.randint(1, 10)
    numberB = random.randint(1, 10)
    result = numberA * numberB
    print('Ile to jest', numberA,'razy', str(numberB) + '?')
    try:
        answer = int(input('Odpowiedź: '))
        if answer == result:
            points+=1
            a+=1
            print('Dobrze! Zdobyłeś punkt!')
        else:
            a+=1
            print('Błąd!')
    except ValueError:
        print('Nieprawidłowa wartość!')
        continue
print('Twój wynik to:', str(points) +'/5 punktów')
edytowany 1x, ostatnio: Sevy
AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:38 minut
  • Postów:973
1

Ładniej i czytelniej by było jakbyś stworzył funkcję do pobierania odpowiedzi użytkownika i to w niej zawarł właśnie wyjątek


Zdalna praca dla Senior Python Developerów --> PW
SI
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 2 godziny
2

Ja bym w przypadku podania nie inta zapytał jeszcze raz, i o mnożenie przez jeden nie pytał. Dodatkowo for zamiast twojego while

Kopiuj
import random

points = 0


for a in range(5):
    numberA = random.randint(2, 10)
    numberB = random.randint(2, 10)
    result = numberA * numberB
    print('Ile to jest', numberA,'razy', str(numberB) + '?')
    while 1:
        try:
            answer = int(input('Odpowiedź: '))
            if answer == result:
                points+=1
                a+=1
                print('Dobrze! Zdobyłeś punkt!')

            else:
                a+=1
                print('Błąd!')
            break
        except ValueError:
            print('Nieprawidłowa wartość! wpisz jeszcze raz')

print('Twój wynik to:', str(points) +'/5 punktów')
edytowany 2x, ostatnio: sig
NieUmiemProgramować
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 4 lata
  • Postów:17
0
sig napisał(a):

Ja bym w przypadku podania nie inta zapytał jeszcze raz, i o mnożenie przez jeden nie pytał. Dodatkowo for zamiast twojego while

Kopiuj
import random

points = 0


for a in range(5):
    numberA = random.randint(2, 10)
    numberB = random.randint(2, 10)
    result = numberA * numberB
    print('Ile to jest', numberA,'razy', str(numberB) + '?')
    while 1:
        try:
            answer = int(input('Odpowiedź: '))
            if answer == result:
                points+=1
                a+=1
                print('Dobrze! Zdobyłeś punkt!')

            else:
                a+=1
                print('Błąd!')
            break
        except ValueError:
            print('Nieprawidłowa wartość! wpisz jeszcze raz')

print('Twój wynik to:', str(points) +'/5 punktów')

@sig
jestem 'noobem' w programowanie dlatego pytam.
Czy jeśli zmieniłeś pętle while na for to zwiększanie zmiennej a nie traci sensu? pętla for chyba i tak wykona się 5 razy?

Pytam bo nie wiem, czy to przeoczenie, czy ja czegoś nie rozumiem.

Guaz
Słusznie zauważyłeś, czasem przerabiając cudze kody pomija się takie fragmenty, po prostu zmieniasz fragmenty interesujące cię w perspektywie problemu, nie żeby go całego przerabiać i usuwać zbędne rzeczy. To z reguły pozostaje pytającemu zauważyć, jak tobie słusznie się udało :)
Sevy
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Katowice
  • Postów:20
0

co tu robi while 1? jak on działa?

sig napisał(a):

Ja bym w przypadku podania nie inta zapytał jeszcze raz, i o mnożenie przez jeden nie pytał. Dodatkowo for zamiast twojego while

Kopiuj
import random

points = 0


for a in range(5):
    numberA = random.randint(2, 10)
    numberB = random.randint(2, 10)
    result = numberA * numberB
    print('Ile to jest', numberA,'razy', str(numberB) + '?')
    while 1:
        try:
            answer = int(input('Odpowiedź: '))
            if answer == result:
                points+=1
                a+=1
                print('Dobrze! Zdobyłeś punkt!')

            else:
                a+=1
                print('Błąd!')
            break
        except ValueError:
            print('Nieprawidłowa wartość! wpisz jeszcze raz')

print('Twój wynik to:', str(points) +'/5 punktów')
Guaz
while 1: to tyle samo co while True:, bardzo popularny zapis dla piszących w C (? Tak coś mi świta). Jest to nieskończona pętla, kończy się tylko i wyłącznie jak dojdzie do kodu break.
SI
Znam ją faktycznie z c++, ale jest chyba popularna w wszystkich językach.
Guaz
PS: Jeszcze skończy się ta pętla w wyniku błędu którego nie przechwycisz poprzez try/except, oraz kilka bardziej zaawansowanych rzeczy z wątkami. No względnie tak, chociaż o ile pamięć mnie nie myli w Javie nie ma bata, while (1): nie zadziała :D. Ogólnie można tak pisać, nie jest to żaden błąd, ot początkowy zamysł while (warunek) jest najczytelniejsze, natomiast True/False z reguły zwracają wszelkie warunki. Ale w pythonie to i tak można robić cuda, dawać while (lista) a wewnątrz pętli usuwać elementy ;d. Jak struktura będzie pusta, to zostanie zrzutuowana na False.
SI
Kolejna pozostałość po jego kodzie, zwykle w takich przypadkach stosuję samo except bez "kategorii".
SI
  • Rejestracja:prawie 14 lat
  • Ostatnio:około 2 godziny
0

Skoro już poprawiamy, to może by tak w przypadku błędu podać prawidłową odpowiedź? Użytkownik szybciej się nauczy. A także pytać aż poda 5 poprawnych odpowiedzi, i podać mu ilu prób potrzebował żeby to osiągnąć.

AN
  • Rejestracja:prawie 11 lat
  • Ostatnio:38 minut
  • Postów:973
2

Kilka uwag co do kodu.

Po 1. staramy się zawsze żeby wyjątki obejmowały tylko obszar kodu, w którym ten wyjątek faktycznie może wystąpić.

Więc kod

Kopiuj
      try:
           answer = int(input('Odpowiedź: '))
           if answer == result:
               points+=1
               a+=1
               print('Dobrze! Zdobyłeś punkt!')

           else:
               a+=1
               print('Błąd!')
           break
       except ValueError:
           print('Nieprawidłowa wartość! wpisz jeszcze raz')

zamieniamy na np.

Kopiuj
        try:
            answer = int(input('Odpowiedź: '))
        except ValueError:
            print('Nieprawidłowa wartość! wpisz jeszcze raz')
            continue
            
        if answer == result:
            points+=1
            a+=1
            print('Dobrze! Zdobyłeś punkt!')
        else:
            a+=1
            print('Błąd!')
        break

Co też można pozmieniać. Po 1. zmienna a już nie będzie potrzebna. Po 2. można skorzystać tu z funkcji. Zmienić nazwy zmiennych. numberA zmienić albo na numer_a albo na samo a. Jednoliterowe zmienne generalnie są potępiane ale w tym przypadku mogę być zastosowane bo są jednoznaczne.
Możemy skorzystać z formatowania tekstu zamiast kleić string jak w czasach prehistorycznych czyli:

print('Ile to jest', a ,'razy', str(b) + '?') zmieniamy na np. print(f'Ile to jest {a} razy {b}?') lub korzystamy z format jeśli nie nasza wersja Pythona nie wspiera f-stringów.

Więc poprawiony kod mógłby wyglądać tak:

Kopiuj
import random

points = 0

def get_answer():
    while True:
        try:
            return int(input('Odpowiedź: '))
        except ValueError:
            print('Nieprawidłowa wartość! wpisz jeszcze raz')


for _ in range(5):
    a = random.randint(2, 10)
    b = random.randint(2, 10)
    result = a * b
    
    print(f'Ile to jest {a} razy {b}?')
    answer = get_answer()
    
    if answer == result:
        points += 1
        print('Dobrze! Zdobyłeś punkt!')
    else:
        print('Błąd!')


print(f'Twój wynik to: {points}/5 punktów')

Dodatkowo można by jeszcze pokusić się o dodatkową zmienną przechowującą ile prób powinien mieć użytkownik. Chodzi tu o liczbę 5 bo jest ona dosyć magiczna (magic number). Wtedy w jednym miejscu zmieniamy ile użytkownik ma prób. Aktualnie żeby z 5 zrobić 6 musisz to zmienić w dwóch miejscach (w pętli oraz przy wyświetleniu wyników)


Zdalna praca dla Senior Python Developerów --> PW
edytowany 2x, ostatnio: anonimowy
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)