• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Zabezpieczenie programu przed wprowadzeniem STR (przeciwdziałanie CRASHOWI) - Python

Object Storage Arubacloud
0 głosów
1,527 wizyt
pytanie zadane 4 czerwca 2019 w Python przez Ventre90 Obywatel (1,170 p.)
zamknięte 6 czerwca 2019 przez Ventre90

Cześć drodzy pasjonaci. Mam do Was pytanie odnośnie zabezpieczania programów przed wprowadzeniem przez użytkownika tzw ,,Invalid Input" w postaci string, co skutkuje ValueErrorem i wykrzaczeniem programu, w sytuacji kiedy program wymaga wprowadzenie np: zmiennych typu INT. Szczególnie w przypadkach gdy program ma dalej coś policzyć na podstawie zmiennych int. Poniżej wkleiłem 2 krótkie kody gdzie starałem się wymyślić jak uniknąć ,,crashu" na skutek błędnego wprowadzenia zmiennej string. 

Czy istnieje możliwość zabezpieczenia programu tylko za pomocą komend try: / except, bez konieczności wprowadzania jakiejś dodatkowej ,,logiki zabezpieczającej w postaci IFów lub/i pętli.

1. To program który losuje liczbę od 1-100 i daje 5 szans na odgadnięcie. Pomimo, że zabezpieczyłem try/except przy wprowadzaniu zmiennych to i tak mi go wywalało gdy program dochodził do momentu określenia czy liczba jest większa / mniejsza od wprowadzonej ( if x > num:). Dodałem więc ifa na sprawdzenie typu zmiennej (chyba to tak działa) no i nie wykrzacza się. Jednak mam wątpliwości czy jest to rozwiązanie optymalne i czy nie da się tego zrobić samym try / except ?

x = random.randint(1,100)

num = ""
chance = 0

while x != num and chance != 5:

    chance += 1
    chan_rate = 5 - chance

    try:
        num = int(input("Wprowadz liczbę: "))
    except ValueError as err:
        print("Wprowadź liczbę!", err)


    if x == num:
        print ("BRAWO WYGRYWASZ !!!")
        break
                
    if chance < 5:
        print("Dostępne Szanse: {}" .format(chan_rate))

        if num:
            if x > num:
                print("Wylosowana Liczba jest większa. Próbuj dalej.")
            else:
                print("Wylosowana liczba jest mniejsza. Próbuj dalej.")
        elif not num:
            print("Podaj liczbę całkowitą! - ValueError.")
    else:
        print("BRAK SZANS.")

if x != num:
    print("PRZEGRANA !!! Komputer wylosowal: {}" . format (x))

2 program na spełnianie warunków budowy trójkąta / wyznaczenie trójkąta pitagorejskiego. Tutaj z try / except mi kompletnie nie wychodziło, bo z racji tego ze są 3 zmienne to program zawsze sie gdzieś wykrzaczył, a nawet jak nie to zamykał się po wyświetleniu komunikatu błędu, bez poproszenia o kolejny Input. Zbudowałem więc taką pętle while i teoretycznie działa. Znów rodzi się pytanie czy to nie powinno być zrobione samym try / exceptem.

a = ""
b = ""
c = ""

while not a or not b or not c:
    try:
        a = int(input("Podaj bok pierwszy: "))
        b = int(input("Podaj bok drugi: "))
        c = int(input("Podaj bok trzeci: "))
    except ValueError as err:
        print("Wprowadzaj TYLKO liczby CAŁKOWITE!")
    

if c < a: # mozna to zrobic tez ze zmienną. ('temp')
     c,a = a,c
if c < b:
    c,b = b,c
if b < a:
    b,a = a,b

print (a , b, c)


if (a + b > c):
    print("Trójkąt jest mozliwy")
    trigle = True
else:
    print("Z tych bokow NIE bedzie Trójkąta")
    trigle = False

if (trigle and a**2 + b**2 == c**2):
    print("Trójkąt Pitagorejski.")
    if ( a/3 == b/4 == c/5):
        print("Trójkąt Egipski")
elif(trigle):
    print("Trójkąt NIE Pitagorejski"

PS. Przepraszam za długi wątek ale staram się uczyć kodowania z przyzwoitymi standardami i zabezpieczać programy przed crashem w taki sposób jak przychodzi mi to do głowy.

Pozdrawiam i dzięki za wyrozumiałość.

komentarz zamknięcia: Rozwiązanie tematu.
komentarz 4 czerwca 2019 przez mrspock1 Mądrala (6,420 p.)
To chyba program konsolowy bez GUI? Bo inaczej pętla nie byłaby potrzebna. Myślałem że programy konsolowe przestały być robione wiele lat temu.
komentarz 5 czerwca 2019 przez Ventre90 Obywatel (1,170 p.)
Tak to program konsolowy. Rezultaty o których pisałem są z PowerShella.

3 odpowiedzi

+1 głos
odpowiedź 4 czerwca 2019 przez mokrowski Mędrzec (155,460 p.)
wybrane 6 czerwca 2019 przez Ventre90
 
Najlepsza
#!/usr/bin/env python3

def read_int(prompt, err_msg):
    while True:
        try:
            value = int(input(prompt))
            return value
        except ValueError as e:
            print(err_msg)
        else:
            return value

if __name__ == '__main__':
    value = read_int("Wprowadź liczbę: ", "Nieprawidłowe dane, spróbuj jeszcze raz")

 

0 głosów
odpowiedź 4 czerwca 2019 przez adrian17 Ekspert (344,860 p.)

Bez pętli się nie da.

Najprościej pewnie powtarzać pętlę, póki parsowanie się nie udaje, czyli coś w stylu:

while True:
    try:
        a = int(input("Podaj bok pierwszy: "))
        b = int(input("Podaj bok drugi: "))
        c = int(input("Podaj bok trzeci: "))
        break
    except ValueError as err:
        print("Wprowadzaj TYLKO liczby CAŁKOWITE!")
        continue

Można by też całą tą logikę wyrzucić do funkcji, gdyby ten kod się powtarzał.

0 głosów
odpowiedź 5 czerwca 2019 przez Ventre90 Obywatel (1,170 p.)

adrian17 i mokrowski, przede wszystkim serdecznie dziękuje za odpowiedzi. Obie bardzo mi pomogły.

@Adrian - dzieki za ten pomysł z continue. Teraz to powstawiałem, kod jest bardziej czytelny i wszystko hula. Dzięki!

@Mokrowski - Dziękuję za ten pomysł z 2 parametrami w funkcji. nie pomyślałem o tym. To wiele ułatwia i jest super rozwiązaniem. Czy możesz mi jednak wyjaśnić o co chodzi z zapisem:

if __name__ == '__main__':

Dowiedziałem się, że to coś związane z modułami, że rozpoznaje jakieś zmienne w kodzie, czy coś i wykonuje jakiś blok funkcji. Generalnie nic z tego nie rozumiem. Czy możesz lub ktokolwiek inny mógłby, wyjaśnić to łopatologicznie - co to robi, do czego się przydaje i do czego się to używa.

PS. Jak wyhaszowałem tą linijkę z tym if-em, z napisanego przez ciebie kodu, to to zabezpieczanie dalej działa jak należy.

komentarz 5 czerwca 2019 przez mokrowski Mędrzec (155,460 p.)
Każdy program/skrypt w języku Python może działać w 2 trybach:

1. Jako samodzielny program.

2. Jako moduł.

W trakcie uruchamiania skryptu jako samodzielny program, zmienna __name__ (dwa podkreślniki name dwa podkreślniki), ma wartość '__main__' (dwa podkreślniki main dwa podkreślniki). Jeśli skrypt wczytujesz jako moduł, name ma wartość taką jak nazwa modułu. W ten sposób tworzysz poprawne i kontrolowane wejście do skryptu w tym języku a jednocześnie pozwalasz w przyszłości wczytać skrypt jako moduł.

Często ta sekcja służy także do uruchamiania testów modułu.
komentarz 5 czerwca 2019 przez Ventre90 Obywatel (1,170 p.)
Ok nie powiem ze jest to dla mnie całkowicie jasne ale chociaż wiem w którym kościele dzwoni. O ile w przypadku modułów jestem w stanie sobotę wyobrazić funkcjonalność tej sekcji, to jaką ona rolę spełnia gdy skrypt jest samodzielnym programem? Jaką funkcje spełnia np. w twoim kodzie?
komentarz 5 czerwca 2019 przez mokrowski Mędrzec (155,460 p.)

Kontrolowane, jasne, 1 wejście do programu.

Dodatkowo możesz go sobie zapisać w pliku np. read_int.py i importować przez

from read_int import read_int

To jest dobra praktyka której po prostu jeszcze nie znasz.

komentarz 6 czerwca 2019 przez Ventre90 Obywatel (1,170 p.)
OK bardzo dziękuje za wyjaśnienia. Będę się starał to stosować w przyszłości.

Podobne pytania

0 głosów
1 odpowiedź 1,623 wizyt
0 głosów
1 odpowiedź 148 wizyt
+1 głos
1 odpowiedź 169 wizyt

92,538 zapytań

141,377 odpowiedzi

319,456 komentarzy

61,923 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...