תרגילים נוספים: שבוע 5

מחברת #1 (פִּרְקָנים)

תרגיל 1: *****__*_*_*__*** (נגה אוסין)

ממשו פונקציה אשר מקבלת מחרוזת, ועובדת לפי החוקיות הבאה –

עבור כל אות:

  1. אם האות מופיעה יותר מפעם אחת, החליפו אותה בתו *.
  2. אחרת, החליפו אותה בתו _.

הפונקציה אינה case sensitive, כלומר, מבחינת הפונקציה אין הבדל בין אותיות גדולות ואותיות קטנות.

דוגמאות:

  • עבור הקלט ABBA יוחזר ****.
  • עבור הקלט Ali Baba, יוחזר *___****.
  • עבור הקלט CatDog, יוחזר ______.

מחברת #2 (פונקציות – חלק 2)

תרגיל 1: מלך הפלאפל (נגה אוסין)

כתבו פונקציה בשם print_recipe המסייעת למוכר הפלאפל השכונתי שלכם.

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

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

דוגמאות:

  • עבור הקריאה:
    print_recipe(2, True, tahini='a bucket', parsley='a lot', amba='a little bit')

יודפס:

Hey, nice to see you again!
2 servings of falafel for you!
With a bucket of tahini!
With a lot of parsley!
With a little bit of amba!

  • עבור הקריאה:
    print_recipe(4, tahini='tons', Tabasco='a bottle')

יודפס:

4 servings of falafel for you!
With tons of tahini!
With a bottle of Tabasco!

מחברת #3 (מחוֹללים)

תרגיל 1: (נגה אוסין)

התבוננו בשני קטעי הקוד שלפניכם. הוציאו דף ועט וכתבו: אם נריץ את הגנרטורים הבאים באמצעות לולאת for, מה לדעתכם יהיה הפלט של כל yield? מה יהיה ה־type של כל אחד מהם?

def foo(*args, **kwargs):
    for key, value in kwargs.items():
        yield key, value
    for i in args:
        yield i

def other_foo(*args, **kwargs):
    for key, value in kwargs.items():
        for i in args:
            yield i
        yield key, value

יש בעיה בקוד הבא. מה היא?

def completely_different_foo(optional=None, *args, **kwargs):
    if optional:
        yield optional
    for key, value in kwargs.items():
        for i in args:
            yield i
        yield key, value

תרגיל 2: הראשוני לשמו (נגה אוסין)

2 הוא המספר הראשוני הראשון. 3 הוא השני. 541 נמצא במקום המאה.
כתבו פונקציה אשר מקבלת מהמשתמש את מיקום המספר הראשוני, ומחזירה את המספר עצמו.
מהו המספר הראשוני במקום ה־4,000?

נסו להשתמש ב־generators.
הבהרה: המיקום של המספר הראשוני הראשון הוא 1, של השני הוא 2, וכן הלאה.

תרגיל 3: התחלק על הכובע (נגה אוסין)

א. מספר כלשהו (נקרא לו T) יהיה “מספר משולשי” אם ניתן לסדר T עצמים כמשולש שווה צלעות, כך:
image
המספר המשולשי הראשון הוא 1, המספר המשולשי השני הוא 1+2, השלישי הוא 1+2+3, הרביעי הוא 1+2+3+4, וכן הלאה.

ממשו גנרטור אשר מניב (yield) מספרים משולשיים.

ב. מחלקים של מספר שלם הם כל המספרים בהם הוא מתחלק ללא שארית.
המספר 3, למשל, מתחלק רק בעצמו וב־1 (מספר ראשוני), ולכן כמות המחלקים שלו היא 2. 4 מתחלק בעצמו, ב־1 וב־2, ולכן כמות המחלקים שלו היא 3. כמות המחלקים של 300 היא 18.

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

תרגיל 4: The Library (ים מסיקה)

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

2 לייקים

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

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

לייק 1

בנתיים:

מחברת 1: תרגיל 1
from collections import Counter


def noga_encoding(my_string):
    my_string = my_string.lower()
    char_list = Counter(my_string)
    
    encrypted_string = ""
    for character in my_string:
        if char_list.get(character, 0) == 1:
            encrypted_string += "_"
        else:
            encrypted_string += "*"
    return encrypted_string


print(noga_encoding("ABBA"))
print(noga_encoding("Ali Baba"))
print(noga_encoding("CatDog"))
מחברת 2: תרגיל 1
def print_recipe(number_of_servings, is_regular=False, **toppings):
    if is_regular:
        print("Hey, nice to see you again!")
    
    print(f'{number_of_servings} servings of falafel for you!')

    for topping, amount in toppings.items():
        print(f'With {amount} of {topping}!')


print_recipe(2, True, tahini='a bucket', parsley='a lot', amba='a little bit')
print()
print_recipe(4, tahini='tons', Tabasco='a bottle')
מחברת 3: תרגיל 2
def get_prime_number(number):
    for divider in range(2, int((number / 2) + 1)):
        if number % divider == 0:
            return None
    return number


def get_prime_numbers(index):
    counter = 0
    number = 2
    while counter != index:
        prime_number = get_prime_number(number)
        if prime_number:
            yield prime_number
            counter += 1
        number += 1


def get_prime_number_by_index(index):
    counter = 1
    for item in get_prime_numbers(index):
        if counter != index:
            counter += 1
        else:
            print(item)


get_prime_number_by_index(10)
get_prime_number_by_index(4000)
מחברת 3: תרגיל 3
def get_t_numbers():
    num_list = []
    current_num = 1
    while True:
        num_list.append(current_num)
        yield sum(num_list)
        current_num += 1


def get_number_with_n_number_of_dividers(number, number_of_dividers):
    dividers = 0
    for i in range(1, int(number / 2) + 1):
        if number % i == 0:
            dividers += 1
    return dividers == (number_of_dividers - 1)
     

def main():
    for number in get_t_numbers():
        is_equal = get_number_with_n_number_of_dividers(number, 120)
        if is_equal:
            print(number)

main()

פתרונות שלי (יעודכן):

מחברת 3: תרגיל 4
import os


def is_all_words(file_name, words):
    counter = 0
    is_all_match = True
    while is_all_match and counter < len(words):
        if words[counter] in file_name:
            counter += 1
        else:
            is_all_match = False
    return is_all_match


def all_files_with_words(path, words):
    for directory in os.walk(path):
        files = directory[2]
        if len(files) > 0:
            for file in files:
                if is_all_words(file, words):
                    yield file


words = ['python', 'hello']
path = r'\Users\Aviad\Desktop\test'

for file in all_files_with_words(path, words):
    print(file)  
מחברת 3: תרגיל 3
def number_of_triangles():
    i = 1
    while True:
        number = 0
        for j in range(1, i + 1):
            number += j
        yield number
        i += 1


def number_of_dividers(number):
    if number == 1:
        return 1
    else:
        dividers = 2
        counter = 2
        while counter <= number // 2:
            if number % counter == 0:
                dividers += 1
            counter += 1
        return dividers


limit = 120
is_found = False
generator = number_of_triangles()
while not is_found:
    result = next(generator)
    if number_of_dividers(result) == limit:
        is_found = True
        print(result)

גנרטורים אהמאהמ :thinking:
למי יש כוח לחכות עד שזה יסיים לחפש בכל המחשב :stuck_out_tongue:

לייק 1

:rofl: פספסתי את הכותרת של זה… חחחחח
אעשה עדכון :slight_smile:

עודכן :slight_smile:


אפשר ש-@Noga_o תגיב פה, כדי שאני אעשה לב לה ולא רק לך?

מרגיש ממש לא פיירי, כל הדבר הזה!

2 לייקים

בטוח שהמספר 1 מוגדר כראשוני?

כתוב במפורש שלא :slight_smile:

לייק 1

אפתור לפי ההגדרות של התרגיל.

אבל רק הבהרה למי שמתעניין:
image

@orronai

למען הסר ספק הסוגריים פה חוזרים למספר 3 ולא למספר 1… גם לפי הגדרות התרגיל 1 אינו מספר ראשוני.

3 לייקים

עכשיו שמתי לב. נפלא.

תרגילים ממש טובים

פיתרונות שלי:

מחברת 1 תרגיל 1
import collections


# Returns a string - if a letter is existed more than one time - change each apperance of it to '*', otherwise to - '_'
def make_weird_string(string):
    string = string.lower()
    words_counter = collections.Counter(string)
    final_string = ""
    for letter in string:
        if words_counter[letter] > 1:
            final_string += '*'
        else:
            final_string += '_'
    return final_string


print(make_weird_string("Ali Baba"))
מחברת 2 תרגיל 1
# Prints the recipe of the falafel
def print_recipe(num_of_dishes, regular_customer=False, **extras):
    if regular_customer:
        print("Hey, nice to see you again!")
    print(f"{num_of_dishes} servings of falafel for you!")
    for each in extras:
        print(f"With {extras[each]} of {each}!")


print_recipe(2, True, tahini='a bucket', parsley='a lot', amba='a little bit')
print_recipe(4, tahini='tons', Tabasco='a bottle')
מחברת 3 תרגיל 2
# Checks if n is a prime number
def is_prime_number(n):
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    limit = int(n ** 0.5) + 1    # Divisors that are bigger than sqrt(n) can be eliminated
    for divisor in range (3, limit, 2):
        if n % divisor == 0:
            return False
    return True


# Generates all the prime numbers
def get_prime_numbers():
    yield 2
    number = 3
    while True:
        if is_prime_number(number):
            yield number
        number += 2

# Returns the 'index' prime number
def get_prime_number_by_index(index):
    generator_iterator = get_prime_numbers()
    for _ in range(index - 1):
        next(generator_iterator)
    return next(generator_iterator)


print(get_prime_number_by_index(100))    # => 541
print(get_prime_number_by_index(4000))   # => 37,813
מחברת 3 תרגיל 3
# Generates all the triangle numbers
def triangle_number():
    number = 1
    next_organ = 2
    while True:
        yield number
        number += next_organ
        next_organ += 1


# Returns the number of divisors of a number
def get_num_of_divisors(number):
    limit = number // 2    # We can eliminate all the numbers that are bigger than the half of the number
    num_of_divisors = 2    # Every number divides by himself and also '1'
    current_divisor = 2
    while current_divisor <= limit:
        if number % current_divisor == 0:
            num_of_divisors += 1
        current_divisor += 1
    return num_of_divisors


# Returns the first triangle number that his number of divisors is as the paramather
def get_triangle_number_by_num_of_divisors(num_of_divisors):
    generator_iterator = triangle_number()
    for number in generator_iterator:
        if get_num_of_divisors(number) == num_of_divisors:
            return number


print(get_triangle_number_by_num_of_divisors(120))
מחברת 3 תרגיל 4 (2 דרכים)
import os


# Gets a file-name and checks if all the searching words are included in his name
def include_words(filename, *searching_words):
    for word in searching_words:
        if word not in filename:
            return False
    return True


# Generates all the files that have all the searching words in their names
def search_files(path, *searching_words):
    for route in os.walk(path):
        files = route[-1]
        for filename in files:
            if include_words(filename, *searching_words):
                yield filename

# Generates in a recursive way the files that have all the searching words in their names
def search_files_recursive(path, *searching_words):
    for file in os.listdir(path):
        if os.path.isdir(file):
            iterator = search_files_recursive(os.path.join(path, file), *searching_words)
            for each in iterator:
                if include_words(each, *searching_words):
                    yield each
        if include_words(file, *searching_words):
            yield file


PATH = r"I:\Python Course\week5"

searching_iterator = search_files(PATH, "1", "Pt")
for file in searching_iterator:
    print(file)
print('-' * 50)
searching_recursive_iterator = search_files_recursive(PATH, "1", "Pt")
for file in searching_recursive_iterator:
    print(file)

תרגיל 1 מחברת 2-
,rdhl

אפשר להניח בתרגיל האחרון שמצופה לפתוח רק קבצי TXT?
כלומר לא לחפש מילים בתוך תמונות :stuck_out_tongue_winking_eye:

ובנוסף - להחזיר את הקבצים, מה מצופה להחזיר בדיוק?

מחברת 3 תרגיל 4:
import os


def are_words_in_file(file_path, *words):
    words_list = list(words)
    with open(file_path, 'r', encoding="utf8") as file_handler:
        for line in file_handler:
            line = line.lower()
            for word in words_list:
                if word in line:
                    words_list.remove(word)
    if not words_list:
        return True

    else:
        return False


def files_generator(path):
    for dirpath, dirnames, filenames in os.walk(path):
        for name in filenames:
            file_path = os.path.join(dirpath, name)
            if name.endswith('.txt'):
                yield file_path


def return_files_with_words(path, *words):
    for file_path in files_generator(path):
        print(file_path)
        print(are_words_in_file(file_path, *words))
        if are_words_in_file(file_path, *words):
            return file_path

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

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