עבודה עם קבצים (File Handling)

עבודה עם קבצים היא יכולת מרכזית בתכנות.
היא מאפשרת לנו לקרוא נתונים מקובץ (למשל, שאלות או תשובות) ולכתוב נתונים חדשים לקובץ (למשל, תוצאות משחק).

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

  1. קריאה וכתיבה לקבצים (Reading and Writing to Files):
    איך לפתוח, לקרוא, ולכתוב לקבצים.
  2. טיפול בשגיאות (Handling Errors):
    איך להתמודד עם בעיות שעלולות להתרחש, כמו ניסיון לפתוח קובץ שאינו קיים.

דוגמת קוד

# Writing to a file
try:
    with open("example.txt", "w") as file:  # Open a file in write mode
        file.write("Hello, Python World!\n")  # Write a line to the file
        file.write("This is a second line.\n")  # Write another line
    print("File written successfully!")
except Exception as e:
    print("An error occurred:", e)

# Reading from a file
try:
    with open("example.txt", "r") as file:  # Open a file in read mode
        content = file.read()  # Read the entire file content
        print("\nFile content:")
        print(content)
except FileNotFoundError:
    print("The file does not exist.")
except Exception as e:
    print("An error occurred:", e)

הסבר על הקוד

כתיבה לקובץ (Writing to a File):

  • open("example.txt", "w"): פותח את הקובץ example.txt במצב כתיבה (w).
    • אם הקובץ לא קיים, הוא ייווצר.
    • אם הקובץ קיים, התוכן שלו יימחק לפני הכתיבה.
  • file.write: כותב מחרוזת לתוך הקובץ.
  • with מבטיח שהקובץ ייסגר אוטומטית לאחר סיום העבודה.

קריאה מקובץ (Reading from a File):

  • open("example.txt", "r"): פותח את הקובץ example.txt במצב קריאה (r).
    • אם הקובץ לא קיים, תזרק שגיאת FileNotFoundError.
  • file.read: קורא את כל תוכן הקובץ כמחרוזת.

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

  • try...except: מוודא שאם מתרחשת שגיאה (למשל, הקובץ לא קיים), התוכנית לא תתרסק.
  • FileNotFoundError: נתפסת כאשר מנסים לקרוא קובץ שאינו קיים.

תרגילים

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

תרגיל 2:
כתבו תוכנית שקוראת מקובץ שורה אחר שורה ומדפיסה כל שורה בנפרד.

תרגיל 3:
כתבו תוכנית שמבקשת מהמשתמש להוסיף שלושה משפטים חדשים לקובץ קיים.

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

תרגיל 5:
אתגר: כתבו תוכנית שמקבלת שם קובץ מהמשתמש, מוודאת שהקובץ קיים, ומעתיקה את התוכן שלו לקובץ חדש.

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

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

# Global data structures
questions_file = "questions.txt"  # File to store questions
scores_file = "scores.txt"  # File to store scores
players = set()  # Set to track player names

# Function to load questions from a file
def load_questions():
    """Load questions from a file."""
    questions = {}
    try:
        with open(questions_file, "r") as file:
            for line in file:
                question, answer = line.strip().split("||")  # Split by separator
                questions[question] = answer
    except FileNotFoundError:
        print("Questions file not found. Starting with an empty question list.")
    return questions

# Function to save questions to a file
def save_questions(questions):
    """Save questions to a file."""
    with open(questions_file, "w") as file:
        for question, answer in questions.items():
            file.write(f"{question}||{answer}\n")  # Use "||" as separator

# Function to save scores to a file
def save_score(name, score):
    """Save the player's score to a file."""
    with open(scores_file, "a") as file:  # Append mode
        file.write(f"{name}: {score}\n")

# Function to welcome the player and handle admin or regular user flow
def welcome():
    """Welcome the player and check if they are admin."""
    print("Welcome to the Quiz Game!")
    name = input("What is your name? ").strip()  # Clean up input
    players.add(name)  # Add the player to the set of players

    if name.lower() == "admin":
        print("Hello, Admin! You can manage the quiz.")
        manage_quiz()
    else:
        print(f"Hello, {name}, let's start the game!")
        play_quiz(name)

# Function to add or remove questions
def manage_quiz():
    """Allow the admin to add or remove questions."""
    global questions  # Use the global dictionary
    
    while True:
        action = input("Do you want to 'add', 'remove', or 'done'? ").lower().strip()
        if action == "done":
            break
        elif action == "add":
            new_question = input("Enter a new question: ").strip()
            new_answer = input("Enter the correct answer: ").strip()
            questions[new_question] = new_answer  # Add to the dictionary
            print("Question added!")
        elif action == "remove":
            question_to_remove = input("Enter the question to remove: ").strip()
            if question_to_remove in questions:
                del questions[question_to_remove]  # Remove from the dictionary
                print("Question removed!")
            else:
                print("Question not found.")
        else:
            print("Invalid option. Try again.")
    
    save_questions(questions)
    print("\nUpdated questions saved!")

# Function to play the quiz
def play_quiz(name="Player"):
    """Play the quiz game using the global questions dictionary."""
    global questions  # Use the global dictionary
    score = 0  # Initialize score

    # Loop through the questions
    for question, correct_answer in questions.items():
        print("\n" + question)
        user_answer = input("Your answer: ").strip()  # Clean up user input

        if str(user_answer).lower() == str(correct_answer).lower():
            print("Correct!")
            score += 1
        else:
            print("Wrong! The correct answer was:", correct_answer)

    print("\nGame over!")
    print(name, "your final score is:", score)
    save_score(name, score)

# Load initial questions
questions = load_questions()

# Start the program
welcome()

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

  1. טעינת שאלות מקובץ:
    • פונקציה load_questions טוענת שאלות מקובץ וממירה אותן למילון.
    • פורמט הקובץ: שאלה||תשובה.
  2. שמירת שאלות לקובץ:
    • פונקציה save_questions שומרת את רשימת השאלות המעודכנת לקובץ.
  3. שמירת ניקוד השחקנים:
    • פונקציה save_score שומרת את הניקוד של כל שחקן בקובץ נפרד.
  4. עבודה בטוחה עם קבצים:
    • טיפול בשגיאה אם קובץ השאלות לא קיים.