טיפול בשגיאות (Error Handling)

שגיאות בתוכניות הן חלק בלתי נפרד מתהליך הפיתוח.
פייתון מספקת כלים להתמודד עם שגיאות בצורה מסודרת, כך שהתוכנית לא תתרסק ותוכל להמשיך לפעול.

בשיעור זה נלמד:

  1. בלוקים try, except, ו-finally:
    מאפשרים לטפל בשגיאות צפויות בצורה מבוקרת. השימוש ב-finally הוא פחות נפוץ.
  2. עקרונות בסיסיים לניפוי שגיאות (Debugging):
    איך למצוא ולתקן באגים בתוכנית.

דוגמת קוד

# Handling errors with try, except, finally
try:
    print("Let's divide two numbers.")
    numerator = int(input("Enter numerator: "))  # Get numerator
    denominator = int(input("Enter denominator: "))  # Get denominator
    result = numerator / denominator  # Perform division
    print(f"The result is: {result}")
except ValueError:
    print("Invalid input! Please enter numbers only.")
except ZeroDivisionError:
    print("You cannot divide by zero!")
except Exception as e:
    print("An unexpected error occurred:", e)
finally:
    print("Thank you for using the division program.")

הסבר על הקוד

טיפול בשגיאות:

  1. try:
    • הקוד שבבלוק try הוא הקוד הראשי שאנו מנסים להריץ.
    • במקרה של שגיאה, הפקודה תדלג על שאר הבלוק ותעבור לבלוק except.
  2. except:
    • except ValueError: מטפל בשגיאות קלט לא חוקי, כאשר המשתמש מכניס משהו שאינו מספר.
    • except ZeroDivisionError: מטפל במצב שבו המשתמש מנסה לחלק ב-0.
    • except Exception as e: תופס כל שגיאה אחרת ומציג אותה.
  3. finally:
    • הקוד בבלוק finally מתבצע תמיד, בין אם התרחשה שגיאה ובין אם לא.
    • משמש לפעולות ניקוי (כמו סגירת קבצים) או הודעות סיום.

תרגילים

תרגיל 1:
כתבו תוכנית שמבקשת מהמשתמש להכניס שני מספרים ומחלקת אותם. השתמשו ב-try ו-except לטפל במצבים בהם הקלט אינו חוקי או שיש ניסיון לחלק ב-0.

תרגיל 2:
צרו פונקציה שקוראת מקובץ. השתמשו ב-try כדי לטפל במצבים שבהם הקובץ לא קיים.

תרגיל 3:
כתבו תוכנית שמבקשת מהמשתמש להכניס מספרים עד שהוא מזין "done". השתמשו ב-try כדי לוודא שהקלט הוא מספר.

תרגיל 4:
אתגר: כתבו תוכנית שמבקשת מהמשתמש להכניס מספר ולבדוק אם הוא ראשוני. אם המשתמש מזין משהו שאינו מספר, הדפיסו הודעת שגיאה מתאימה.

תרגיל 5:
כתבו פונקציה עם try, except, ו-finally שמחברת שני מספרים. בבלוק finally, הדפיסו הודעה כמו "חישוב הסתיים".

הפרויקט הגדול: משחק הטריוויה

בשלב הזה נוסיף טיפול בשגיאות כדי להבטיח שהמשחק לא יתרסק במקרים של קלט שגוי או בעיות בקבצים.

עדכון קובץ quiz_questions.py

# quiz_questions.py
import os

questions_file = "questions.txt"

def load_questions():
    """Load questions from a file."""
    questions = {}
    try:
        if not os.path.exists(questions_file):  # Check if the file exists
            print(f"{questions_file} not found. Creating an empty file.")
            with open(questions_file, "w") as file:
                pass  # Create an empty file
        else:
            with open(questions_file, "r") as file:
                for line in file:
                    try:
                        question, answer = line.strip().split("||")  # Split by separator
                        questions[question] = answer
                    except ValueError:
                        print(f"Skipping invalid line: {line.strip()}")
    except Exception as e:
        print("An error occurred while loading questions:", e)
    return questions

def save_questions(questions):
    """Save questions to a file."""
    try:
        with open(questions_file, "w") as file:
            for question, answer in questions.items():
                file.write(f"{question}||{answer}\n")
    except Exception as e:
        print("An error occurred while saving questions:", e)

עדכון קובץ quiz_game.py

# quiz_game.py
import random

def play_quiz(name, questions):
    """Play the quiz game."""
    score = 0
    randomized_questions = list(questions.items())
    random.shuffle(randomized_questions)  # Shuffle the list

    for question, correct_answer in randomized_questions:
        try:
            print("\n" + question)
            user_answer = input("Your answer: ").strip()

            if str(user_answer).lower() == str(correct_answer).lower():
                print("Correct!")
                score += 1
            else:
                print("Wrong! The correct answer was:", correct_answer)
        except Exception as e:
            print("An error occurred while processing your answer:", e)

    print("\nGame over!")
    print(name, "your final score is:", score)
    return score
עדכון קובץ main.py
# main.py
from quiz_questions import load_questions, save_questions
from quiz_game import play_quiz

def welcome():
    """Welcome the player and handle user flow."""
    try:
        questions = load_questions()
        print("Welcome to the Quiz Game!")
        name = input("What is your name? ").strip()

        if name.lower() == "admin":
            manage_quiz(questions)
        else:
            play_quiz(name, questions)
    except Exception as e:
        print("An unexpected error occurred:", e)

def manage_quiz(questions):
    """Allow admin to manage questions."""
    while True:
        action = input("Do you want to 'add', 'remove', or 'done'? ").lower().strip()
        if action == "done":
            break
        elif action == "add":
            try:
                new_question = input("Enter a new question: ").strip()
                new_answer = input("Enter the correct answer: ").strip()
                questions[new_question] = new_answer
                print("Question added!")
            except Exception as e:
                print("An error occurred while adding the question:", e)
        elif action == "remove":
            try:
                question_to_remove = input("Enter the question to remove: ").strip()
                if question_to_remove in questions:
                    del questions[question_to_remove]
                    print("Question removed!")
                else:
                    print("Question not found.")
            except Exception as e:
                print("An error occurred while removing the question:", e)
        else:
            print("Invalid option. Try again.")

    save_questions(questions)

# Start the program
welcome()

שיפורים שנוספו לפרויקט:

  1. טיפול בשגיאות בקבצים:
    • אם הקובץ לא קיים, הוא נוצר אוטומטית.
    • שורות לא חוקיות בקובץ השאלות נזנחות עם הודעה מתאימה.
  2. טיפול בקלט שגוי:
    • הקוד תופס שגיאות קלט כמו ערכים לא צפויים או רווחים מיותרים.
  3. תוכנית יציבה יותר:
    • בעיות בקבצים או בתשובות לא מפסיקות את המשחק אלא מטופלות בצורה מסודרת.