תרגול נוסף: שבוע 7

תגיות:

ספר טלפונים

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

  • שם פרטי ומשפחה
  • עיר מגורים
  • מספר טלפון

ממשו דרך לקבל מרשימת הטלפונים:

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

השתמשו ב־Faker כדי לבנות ספר טלפונים, ובדקו שכל המתודות שכתבתן עובדות.

שיר עשירים

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

  • הוספת שיר
  • מחיקת שיר
  • הדלקת או כיבוי מצב Shuffle
  • ניגון שיר
  • מעבר לשיר הראשון
  • מעבר לשיר הקודם
  • מעבר לשיר הבא
  • מעבר לשיר האחרון
  • טעינת הסוללה של הווקמן
  • להגביר את עוצמת השמע בכמות שבין 1 ל־100
  • להנמיך את עוצמת השמע בכמות שבין 1 ל־100

לכל שיר יש את התכונות הבאות:

  • שם אמן
  • שם יצירה
  • שנת הוצאה
  • סוגה (ז'אנר)

הוראות ההפעלת של הווקמן הן כדלהלן:

  • כל מכשיר מגיע עם סוללה טעונה במלואה (100% סוללה).
  • כל שיר שמתנגן, מוריד למכשיר 1% סוללה ומעביר את הנגן לשיר הבא.
  • שיר לא יתנגן אם מצב הסוללה של המכשיר הוא 0%. במקרה זה, תודפס הודעת שגיאה.
  • במקרה של מצב Shuffle, יבחר שיר באופן אקראי מהרשימה שהוא לא השיר שכבר הושמע.
  • אם מצב ה־Shuffle כבוי, יתנגן השיר הבא ברשימה לפי סדר השירים שהוכנסו.
  • במצב של סיום רשימת השירים, הווקמן יעצר.
  • עוצמת השמע לא תהיה נמוכה מ־0 או גדולה מ־100.

פגישה חצי פגישה

צרו שני רובוטים.
לכל רובוט יש את הפעולות הבאות:

  • סע קדימה צעד אחד
  • הסתובב 90 מעלות לימין

בזמן יצירת הרובוט, ניתן לספק לו קורדיטה (x ו־y) שבה הוא יוצב.
בזמן יצירתו, פניו של הרובוט יופנו כלפי מעלה.

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

לדוגמה, עבור רשימת הקורדינטות [(0, 5), (1, 5), (2, 5), (3, 5), (3, 6), (3, 7)], כאשר הרובוט הראשון מתחיל מהנקודה (1, 5) והרובוט השני מהנקודה (3, 7), יתבצעו הצעדים הבאים:

  1. הרובוט הראשון יסתובב כך שפניו מופנות לימין, והרובוט השני יסתובב כך שפניו מופנות לימין.
  2. הרובוט הראשון יתקדם ל־(2, 5), והרובוט השני יסתובב כך שפניו מופנות למטה.
  3. הרובוט הראשון יתקדם ל־(3, 5), והרובוט השני יתקדם ל־(3, 6).
  4. הרובוט הראשון יסתובב כך שפניו מופנות למטה. הרובוט השני יתקדם ל־(3, 5).

לכן ערך ההחזרה של הפונקציה הוא שהרובוטים נפגשו בנקודה (3, 5).

אם הרובוטים לעולם לא יפגשו, החזירו False.


ראו עוד תרגולים כאן:

2 לייקים

כשהתרגול הנוסף יוצא לפני המחברת :joy: (don’t shoot me!)

:open_mouth: :gun: :cowboy_hat_face:

ספר טלפונים
from faker import Faker


class Person:
    """A class of a person.

    Args:
        name (str): The person's name.
        city (str): The person's residence city.
        phone (str): The person's phone number.

    Attributes:
        name (str): The person's name.
        city (str): The person's residence city.
        phone (str): The person's phone number.
    """
    def __init__(self, name, city, phone):
        self.name = name
        self.city = city
        self.phone = phone

    def __str__(self):
        return f'Name: {self.name}, residence city: {self.city}, phone number: {self.phone}.'


class Contacts:
    """A class of contacts.

    Attributes:
        contacts (list): A list of Persons.
    """
    def __init__(self):
        self.contacts = []

    def add_contact(self, name, city, phone):
        """Add contact to the contacts list."""
        person = Person(name, city, phone)
        self.contacts.append(person)

    def search_persons(self, searching_name):
        """Search if a person name in the contacts contains the searching name."""
        for contact in self.contacts:
            if searching_name.lower() in contact.name.lower():
                yield contact

    def start_with_search_persons(self, starting_with_name_search):
        """Search if a pseron name in the contacts starts with the searching name."""
        for contact in self.contacts:
            for each_name in contact.name.split():
                if each_name.lower().startswith(starting_with_name_search.lower()):
                    yield contact

    def print_page(self, page_number, num_in_one_page=20):
        """Print a page in the contacts.

        Args:
            page_number (int): The page the user would like to print.
            num_in_one_page (int, optional): How many contacts in one page.
        """
        contacts_index = (page_number - 1) * num_in_one_page
        for contact in self.contacts[contacts_index:contacts_index + num_in_one_page]:
            print(contact)


def build_contacts(num_of_contacts):
    fake = Faker()
    contacts = Contacts()
    for _ in range(num_of_contacts):
        contacts.add_contact(fake.name(), fake.city(), fake.ssn())
    contacts.print_page(1)
    print("Persons that contain 'dan':")
    generator_iterator = contacts.search_persons('dan')
    for person in generator_iterator:
        print(person)
    print("Persons that start with 'dan':")
    generator_iterator = contacts.start_with_search_persons('dan')
    for person in generator_iterator:
        print(person)


build_contacts(100)
פגישה חצי פגישה
from operator import add, sub
import random


class Robot:
    """A class of robot. Robot is represented by his point location
    and direction where he looks.

    Args:
        point (tuple): Robot's starting location point.

    Attributes:
        point (tuple): Robot's starting location point.
        direction (tuple): The direction where the robot looks.
    """
    _DIRECTIONS = [(0, 1), (1, 0), (0, -1), (-1, 0)]

    def __init__(self, point):
        self.point = point
        self.direction = self._DIRECTIONS[0]

    def turn(self):
        """Turn the robot 90 degrees right."""
        self.direction = self._DIRECTIONS[(self._DIRECTIONS.index(self.direction) + 1) % 4]

    def go_forward(self):
        """Make the robot go forward in the direction he looks."""
        self.point = tuple(map(add, self.point, self.direction))

    def check_move(self, point):
        """Check if the point is the way forward to the robot."""
        return tuple(map(add, self.point, self.direction)) == point


def find_meeting_point(route):
    """Find the meeting point of 2 robots in the route.

    Args:
        route (list): A list of tuples (points).

    Example:
        >>> find_meeting_point([(0, 5), (1, 5), (2, 5), (3, 5), (3, 6), (3, 7)])
        (3, 5)
    """
    if check_route(route):
        robocop_index = 0
        robotric_index = len(route) - 1
        robocop = Robot(route[robocop_index])
        robotric = Robot(route[robotric_index])
        while robocop_index < len(route) - 1 and robotric_index > 0:
            if robocop.point == robotric.point:
                return robocop.point
            if robocop.check_move(route[robocop_index + 1]):
                robocop.go_forward()
                robocop_index += 1
            else:
                robocop.turn()
            if robotric.check_move(route[robotric_index - 1]):
                robotric.go_forward()
                robotric_index -= 1
            else:
                robotric.turn()
    return False


def check_route(route):
    """Check if the route is not faulty."""
    if not route:
        return False
    first_point = route[0]
    for next_point in route[1:]:
        if abs(sum(map(sub, first_point, next_point))) != 1:
            return False
        first_point = next_point
    return True


find_meeting_point([(0, 5), (1, 5), (2, 5), (3, 5), (3, 6), (3, 7)])
ספר טלפונים
class Contact:
    def __init__(self, fullname, city, phone_number):
        self.fullname = fullname
        self.city = city
        self.phone_number = phone_number

    def __str__(self):
        return f'{self.fullname}, {self.city}: {self.phone_number}'

class PhoneBook:
    MAX_CONTACTS_PER_PAGE = 20

    def __init__(self, contacts=None):
        if contacts is None:
            self.contacts = []
        else:
            self.contacts = contacts
        self.pages = {}
        self.rearrange()

    def __str__(self):
        message = ''
        for page in self.pages:
            message += f'Page: {page}\n'
            for contacts in self.pages[page]:
                message += f'{contact}\n'
            message += '-' * 50 + '\n'
        return message.rstrip('\n')

    def rearrange(self):
        self.contacts = sorted(self.contacts, key=lambda x: x.fullname)
        if len(self.contacts) % self.MAX_CONTACTS_PER_PAGE == 0:
            range_fix = 0
        else:
            range_fix = 1
        for i in range(len(self.contacts) // self.MAX_CONTACTS_PER_PAGE + range_fix):
            start = i * self.MAX_CONTACTS_PER_PAGE
            end = start + self.MAX_CONTACTS_PER_PAGE
            self.pages[i + 1] = self.contacts[start:end]
        

    def add_contacts(self, contact, *contacts):
        self.contacts.append(contact)
        self.contacts.extend(contacts)
        self.rearrange()

    def search_name(self, name):
        contacts = ''
        for contact in self.contacts:
            if name.lower() in contact.fullname.lower():
                contacts += str(contact) + '\n'
        return contacts.rstrip('\n')

    def search_by_string(self, string):
        contacts = ''
        for contact in self.contacts:
            if contact.fullname.lower().startswith(string.lower()):
                contacts += str(contact) + '\n'
        return contacts.rstrip('\n')

    def print_page(self, page):
        for contact in self.pages[page]:
            print(contact)
שיר עשירים
import random


class Song:
    def __init__(self, artist, title, year, genre):
        self.artist = artist
        self.title = title
        self.year = year
        self.genre = genre

    def __str__(self):
        return f'{self.title.title()} by {self.artist.title()} ({self.year})'

    def __eq__(self, other):
        if (self.artist != other.artist
           or self.title != other.title
           or self.year != other.year
           or self.genre != other.genre):
            return False
        return True


class Walkman:
    MAX = 100
    MIN = 0

    def __init__(self, *songs):
        self.songs = list(songs)
        self.battery = self.MAX
        self.volume = self.MAX
        self.shuffle = False
        self.current_song = None

    def _sort_songs(self):
        self.songs.sort(key=lambda song: song.title.lower())

    def add_song(self, song):
        if song not in self.songs:
            self.songs.append(song)
        self._sort_songs()

    def remove_song(self, song):
        if song in self.songs:
            self.songs.remove(song)

    def toggle_shuffle(self):
        if self.shuffle:
            self.shuffle = False
        else:
            self.shuffle = True

    def play_song(self):
        if not self.songs:
            print('Song library empty.')
            return
        if not self.battery:
            print('Battery dead.')
            return
        if self.battery <= 10:
            print('Low battery.')
        if self.shuffle:
            current = self.current_song
            while self.current_song == current:
                self.current_song = random.choice(self.songs)
        else:
            if self.current_song is None:
                self.first_song()
            else:
                index = self.songs.index(self.current_song) + 1
                if index < len(self.songs):
                    self.current_song = self.songs[index]
                else:
                    print('Last song.')
                    return
        print(f'Now playing: {self.current_song}')
        self.battery -= 1
        return self.current_song

    def first_song(self):
        if self.current_song is None:
            self.current_song = self.songs[0]
        else:
            self.current_song = None

    def last_song(self):
        self.current_song = self.songs[-1]

    def previous_song(self):
        if self.current_song == self.songs[0]:
            print('First song.')
        else:
            index = self.songs.index(self.current_song) - 2
            self.current_song = self.songs[index]
            if self.current_song == self.songs[-1]:
                self.first_song()
            

    def next_song(self):
        if self.current_song == self.songs[-1]:
            print('Last song.')
        else:
            index = self.songs.index(self.current_song) + 1
            self.current_song = self.songs[index]

    def charge(self):
        self.battery = self.MAX

    def raise_volume(self, amount):
        self.volume += amount
        if self.volume >= self.MAX:
            self.volume = self.MAX
            print('Max volume')
        else:
            print(f'Volume: {self.volume}')

    def lower_volume(self, amount):
        self.volume -= amount
        if self.volume <= self.MIN:
            self.volume = self.MIN
            print('Mute')
        else:
            print(f'Volume: {self.volume}')
פגישה חצי פגישה

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

class Robot:
    DIRECTIONS = {'left': lambda x, y: (x - 1, y),
                  'down': lambda x, y: (x, y - 1),
                  'right': lambda x, y: (x + 1, y), 
                  'up': lambda x, y: (x, y + 1),
                 }
    def __init__(self, coordinate):
        self.position = coordinate
        self.direction = 'up'
        self._trail = []

    def __str__(self):
        return f'Position: {self.position}, Direction: {self.direction.title()}'

    def turn(self):
        self.direction = list(self.DIRECTIONS)[list(self.DIRECTIONS).index(self.direction) - 1]

    def advance(self):
        self._trail.append(self.position)
        self.position = self._get_next_position()

    def _get_next_position(self):
        return self.DIRECTIONS[self.direction](*self.position)

    def route(route):
        if not Robot._check_route(route):
            return False
        robots = [Robot(start_point) for start_point in [route[0], route[-1]]]
        while robots[0].position != robots[1].position:
            if sorted(robots[0]._trail) == sorted(route) == sorted(robots[1]._trail):
                return False
            for robot in robots:
                step = robot._get_next_position()
                if step in route and step not in robot._trail:
                    robot.advance()
                else:
                    robot.turn()
        
        return robots[0].position

    def _check_route(route):
        if not route:
            return False
        for pos in route:
            index = route.index(pos) + 1
            if index < len(route):
                next_pos = route[index]
                if abs(sum(map(lambda x, y: x - y, pos, next_pos))) != 1:
                    return False
        return True

למי שנהנה מכל ישומי הקלפים למיניהם יכול לבנות משחק BLACK JACK כך שהמחשב הוא הדילר ואפשר לשחק נגדו

3 לייקים