קורס Python 3 שיעור תרגיל לולאות ותנאים


זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/python/lessons/11-syntax-lab

היי @ynonp

הינה התשובות לשאלות 1 - 6 לא כולל 5 כי לא הבנתי את השאלה החמישית כל כך :

שאלה 1 :

list = []
for _ in range(10):
    number = int(input("hello please enter some number\n"))
    list.append(number)
print(max(list))

שאלה 2 :

def age_in_month(user_age):
    while True:
        age = user_age * 12
        print(f"your age in month is {age}")
        break


while True:
    try:
        age_in_month(int(input("Hello user,Please enter your age\n")))
    except ValueError:
        print("The input have to be a number")
        age_in_month(int(input("Hello user,Please enter your age\n")))

שאלה 3 :

while True:
    try :
        print("Hello User, Please Write something\n")
        user_input = input()
        print(f"You have written : {user_input[::-1]}")
    except ValueError:
        print("You have to write somethings")

שאלה 4 :

from random import randint

while True:
    Number = (randint(1, 1000000))
    if Number % 7 == 0 and Number % 13 == 0 and Number % 15 == 0:
        print(f"The number {Number} is divided by 7 and 13 and 15")
        print(f"Divided by 7 : {Number / 7}")
        print(f"Divided by 13 : {Number / 13}")
        print(f"Divided by 15 : {Number / 15}")
        break
    else:
        print(f"The number {Number} is not divided by 7 and 13 and 15 ")
        continue

שאלה 5 :

לא הבנתי אותה כל כך

שאלה 6 :

from random import randint

def check_user_input(user_number):

    number = randint(1, 100)
    
    if user_number > number :
        print("The number is you choose is higher than the number which is being raffled")
    elif user_number < number :
        print("The number is you choose is Lower than the number which is being raffled")
    else:
        print("The number is you choose is same number as is being raffled")


while True:
    try :
        print("Hello User, Which number is being raffled?")
        check_user_input(int(input()))
    except ValueError:
        print("Please enter a number")

הי כאן יש הסבר יותר מקיף על ״כפולה משותפת קטנה ביותר״ (לשאלה 5)

הי,

גדול אתה.

לגבי שאלה 2 - לא הכי הבנתי למה צריך גם את הפונקציה וגם פעמיים לולאת while. אני חושב שאפשר לכתוב את זה קצת יותר מדויק.

את הפיתרון של 4 אהבתי ממש. אני חושב שלא צריך שם גם break וגם else. תראה על מי מהם אתה רוצה לוותר. הרבה פעמים כשכותבים קוד כזה נוח להפוך את התנאי כלומר ליצור מבנה כזה:

while True:
  if not ...:
    continue

  print("found it")

ובשאלה 6 מה עם הבונוס?

כיף לקרוא ומחכה לסיבוב שני

קוד לתוכנית שמכילה את ששת התרגילים (כולל תפריט בחירה בינהם):

"""
Implementing 6 exercises from chapter 11.
A menu for selecting the exercise to run is shown on start and after
exercise has ended. If no valid exercise number was selected more
than the number of specified tries, program will exit (with code 1).
"""

import re
from random import randint
from math import gcd


def get_int_input(prompt='Please enter integer:\n', tries=3):
    """
    Get user input for an integer, checking it has only digits and
    an optional +/- as prefix. Converting the input string to integer.
    Note - if no valid input (integer) is received from user in more
    than the allowed "tries", program will exit (with code 1).
    :param prompt: message string to display.
    :param tries: number of tries, for invalid input, before aborting.
    :return: the given integer.
    """
    while tries > 0:
        tries -= 1
        user_input = input(prompt)
        if not re.search('^-?\d+$', user_input):
            print(f'Not a valid number. Please use digits only and the optional +/- as prefix. You have {tries} more tries.')
            continue
        else:
            return int(user_input)

    print('You failed to enter a valid integer. No more tries. Aborting.')
    exit(1)


def biggest_of_10_numbers():
    """
    Asking user to enter 10 numbers, then outputting the biggest
    :return: None
    """
    print("Enter 10 numbers and we'll tell you which is the biggest.")
    numbers = []
    for i in range(1, 11):
        new_input = get_int_input(f'{i}. Please enter number: ')
        numbers.append(new_input)
    print('Maximal entered number is: ', max(numbers))


def age_in_months():
    """
    Prompting for age in years. Calculate and print age in months.
    :return: None
    """
    age_in_years = get_int_input('Please enter your age in years: ')
    print(f'Your age in months is [at least] {age_in_years * 12} months.')


def revers_lines():
    """
    Asking user to enter multiple lines of text, ending with blank line.
    Output given lines in revers order.
    :return: None
    """
    print('''
Please enter lines of text.
Finish by entering a blank line, then we'll print them in reverse order''')
    lines = []
    while True:
        line = input()
        if '' == line:
            break
        lines.append(line)

    # option #1 lines.reverse()
    # option #2 revers range
    # for i in range(len(lines) - 1, -1, -1):
    #    print(lines[i])
    # option #3 reverse list inline
    for i in lines[::-1]:
        print(i)


def find_random_divides_by(to_divide_by=[7, 13, 15], min_range=1, max_range=1000000, max_iterations=1000000):
    """
    Given a few numbers, fined and return a random number that can be divided by them.
    :param to_divide_by: a list of numbers the number should be divided by.
    :param min_range: minimal range for the random number.
    :param max_range: maximal range for the random number.
    :param max_iterations: maximal number of iterations before calling it quits (and returning 0).
    :return: None
    """
    tested = []
    iterations = 0
    while max_iterations > iterations:
        iterations += 1
        cur_num = randint(min_range, max_range)
        if cur_num in tested:
            continue
        tested.append(cur_num)
        for i in to_divide_by:
            if 0 != cur_num % i:
                break
        else:
            print('{} can be divided by: {} (found after {} '
                  'iterations).'.format(cur_num, ", ".join(str(i) for i in to_divide_by), iterations))
            return None

    print('Found no number that can be divided by: {} '
          '(after {} iterations).'.format(", ".join(str(i) for i in to_divide_by), iterations))


def find_lcm_of_random_numbers(min_range=1, max_range=10):
    """
    Randomly generate 2 numbers and find their LCM
    :param min_range: minimal range for the random numbers.
    :param max_range: maximal range for the random numbers.
    :return: None
    """
    num1 = randint(min_range, max_range)
    num2 = randint(min_range, max_range)
    gcd_of_nums = gcd(num1, num2)
    lcm_of_nums = num1 * num2 / gcd_of_nums
    print(f'The LCM of {num1} and {num2} is: {lcm_of_nums:g}.')


def number_guessing_game(min_range=1, max_range=100, max_tries=7, glitch_percentage=10):
    """
    A number guessing game where the user is asked to guess
    a randomly generated number within a fixed number of tries.
    :param min_range: minimal range for the random number.
    :param max_range: maximal range for the random number.
    :param max_tries: maximal number of tries before game is lost.
    :param glitch_percentage: the chance percentage for a "glitch" in the feedback.
    :return: None
    """
    num_to_guess = randint(min_range, max_range)
    print(f'A random number between {min_range} and {max_range} was generated.')
    while max_tries > 0:
        glitch = True if randint(1, 100) <= glitch_percentage else False
        guess = get_int_input('You have {} {}, guess: '.format(max_tries, 'try' if 1 == max_tries else 'tries'))
        max_tries -= 1
        if guess == num_to_guess:
            print(f'Great success! You found the number with {max_tries}', 'try' if 1 == max_tries else 'tries', 'remaining.')
            return None
        elif guess > num_to_guess:
            print(f'{guess} is too', 'small IMHO.' if glitch else 'big.')
        else:
            print(f'{guess} is too', 'big IMHO.' if glitch else 'small.')

    print(f'No more tries. You failed to guess the number. It was: {num_to_guess}.')


tries = 3
while True:
    print('''
Please select the exercise to run:
1. The biggest of 10 numbers.
2. Age in months.
3. Reverse lines.
4. Find a random number (range: 1-1,000,000) that divides by 7, 13 and 15.
5. Find least common multiple of 2 random numbers (range: 1-10).
6. Number guessing game.
0. Exit.''')
    selected_task = get_int_input('')
    if 0 == selected_task:
        print('Goodbye. Exiting.')
        exit()
    elif 1 == selected_task:
        biggest_of_10_numbers()
    elif 2 == selected_task:
        age_in_months()
    elif 3 == selected_task:
        revers_lines()
    elif 4 == selected_task:
        find_random_divides_by()  # ([2, 3, 7], 1, 100, 8)
    elif 5 == selected_task:
        find_lcm_of_random_numbers()
    elif 6 == selected_task:
        number_guessing_game()
    else:
        tries -= 1
        print('No valid option was selected.', end=' ')
        if tries > 0:
            print(f'You have {tries} more', 'tries.' if tries > 1 else 'try.')
            continue
        else:
            print('You have no more tries.')
            exit(1)
לייק 1

יפה! שווה לבדוק גם את הספריה הזאת:

שתעזור לך להציג תפריטים מתוקתקים יותר

תודה @ynonp

אם אני מבין נכון הספרייה הזו לא נתמכת בחלונות בלי להתקין את החבילות הלא רשמיות מכאן:
https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses
האם זה מומלץ?

בהקשר עקיף, האם אתה מכיר נוחה בפייטון ל-GetOptions של מודול Getopt::Long משפת פרל (לקבלת משתנים משורת בפקודה)?

הי,

לגבי Getopt יש לפייתון את argparse שעושה עבודה דומה:
https://docs.python.org/3/library/argparse.html

לגבי curses אני חושב שכן. זו ספריה ותיקה וטובה. אין לי ניסיון איתה על Windows אבל ממשחקים עם מק ו Linux היא עובדת טוב ויש הרבה אופציות. ובכל מקרה בקורס המתקדם פה באתר תלמד על Qt ואז תכתוב יישומי פייתון עם UI גרפי של ממש

היי ינון
האם יש דרך קיצור ב-PyCharm לבצע הזחות? (כמו format document in vs)

כן ברור זה נקרא Reformat Code. הנה הוידאו שלהם בנושא:

def read_until_number(prompt):
    while True:
        try:
            return int(input('what is your age?'))
        except ValueError:
            print('only numbers, please try agine')

x = read_until_number('what is your age?')
total = x*12
print(total)

הי,
נראה מעולה - רק שתי הערות קטנות:

  1. שים לב שכדאי להשתמש בסימן גרש הפוך ` שלוש פעמים כדי שהקוד בפורום יראה יפה. עשיתי תיקון בהודעה המקורית שלך ואתה יכול ללחוץ על העיפרון לעריכת ההודעה כדי לראות איך צריך לכתוב את זה.

  2. לגבי פייתון - מקובל לרשום רווח מסביב לסימן הכפול כלומר total = x * 12

התשובה לתרגיל הראשון

x=[1,2,3,4,9,6,7,8,5,0]
e=[1,2,3,4,9,5,7,8,6,0]

for t in e:
    def read_until_number(prompt):
        while True:
            try:
                return int(input(prompt))
            except ValueError:
                print('Please try again')

    x[t] = read_until_number("please select a number->")
big_number = 0
for y in x:
    if big_number <= y:
        big_number = y
    for i in x:
        if (y <= i) & (big_number <= i):
            big_number = i

print(big_number)

הי @learner וברוכה הבאה לקורס

בשביל להדביק קטעי קוד כאן בפורום אנחנו משתמשים בסימן ״שלום פעמים גרש הפוך״. עדכנתי לך את הקוד ואת יכולה ללחוץ על העיפרון כדי לראות איך גרמתי לקוד להיראות כמו קוד - ויש גם תיעוד עם כל הסימנים האפשריים כאן:
https://commonmark.org/help/

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

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

from random import randint
"""
first exercise
"""
num = 10
biggest_number = 0
print(f"Please choose {num} numbers")
current_number = 0
while current_number < 10:
    try:
        current_number += 1
        number = int(input(f"Enter a number {current_number}: "))
        if number >= biggest_number:
            biggest_number = number
    except ValueError:
        print("Please write in numbers")
        current_number -= 1
        num -= 1
print(f"The biggest number is: {biggest_number}")

"""
second exercise
"""


def age_to_months(user_age):
    user_age = int(input("What is your age?"))
    try:
        print(f"Your age in months is: {user_age * 12}")
    except ValueError:
        print("Please write your age in numbers")

age_to_months(int())

"""
third exercise
"""
lines = []
print("please write something")
while True:
    line = input()
    if line == '':
        break
    lines.append(line)
print(f"you have writen {lines[::-1]}")

"""
fourth exercise
"""
while True:
    random_number1 = randint(1, 1000000)
   if random_number1 % 7 == 0 & random_number1 % 13 == 0 & random_number1 % 15 == 0:
        print(f"I found it, it is {random_number1}")
        break
"""
fifth exercise
"""
num1 = randint(1, 10)
num2 = randint(1, 10)
y = max(num1, num2)
while not (y % num1 == 0) & (y % num2 == 0):
    y += 1
print(f"The smallest multiplier of {num1} and {num2} is  {y}")
"""
sixth exercise
"""
random_number = randint(1, 100)
user_input = 1
while True:
    try:
        user_input = int(input("Guess the number from 1 to 100:"))
    except ValueError:
        print("Oops!  That was no valid number.  Try again...")
        if 1 == 1:
            continue
    if user_input == random_number:
        print("You got it right!")
    else:
        random_number2 = randint(1,4)
        if random_number2 == 2:
            if user_input > random_number:
                print("your number is smaller")
            else:
                print("Your number is bigger")
        else:
            if user_input < random_number:
                print("your number is smaller")
            else:
                print("Your number is bigger")

הי בגדול נראה טוב,

בתרגיל הראשון אני חושב שפיתרון עם לולאת for היה יוצא יותר קל,
ואת התרגיל השלישי אפשר לפתור בלי להשתמש ברשימה - נסה להתאמץ ולמצוא איך

היי, בתרגיל 5 אני מרנדם פעמיים ערכים בין 0-10 אך 2 הערכים יוצאים לי זהים…

הי,

יכול להדביק כאן את הקוד?

from random import randint
def my_funct():
    while True:
        rand_num1= randint(0,10)
        rand_num2= randint(0,10)
        print (f" rand_num1: {rand_num1} rand_num2: {rand_num1}")
        return  
my_funct()

משום מה ההזחות נעלמות לאחר השליחה.

הי אני רואה שאתה מדפיס פעמיים את הערך של המשתנה הראשון. שים לב טוב לשורת ההדפסה