Διαδρομές
/
Python
Python
/
Ασκήσεις
/
Τα υπέροχα λαζάνια του Guido
Τα υπέροχα λαζάνια του Guido

Τα υπέροχα λαζάνια του Guido

Άσκηση εκμάθησης

Εισαγωγή

Η Python είναι μια γλώσσα προγραμματισμού με δυναμική και ισχυρή τυποποίηση. Χρησιμοποιεί τόσο duck typing όσο και gradual typing μέσω των type hints.

Ενώ η Python υποστηρίζει πολλά διαφορετικά στιλ προγραμματισμού, εσωτερικά τα πάντα στην Python είναι ένα αντικείμενο. Αυτό περιλαμβάνει αριθμούς, συμβολοσειρές, λίστες και ακόμη και συναρτήσεις.

Θα εμβαθύνουμε περισσότερο στο τι σημαίνουν όλα αυτά καθώς προχωράμε στη διαδρομή.

Αυτή η πρώτη άσκηση παρουσιάζει 4 σημαντικά χαρακτηριστικά της γλώσσας Python:

  1. Ανάθεση ονόματος (μεταβλητές και σταθερές),
  2. Συναρτήσεις (η λέξη-κλειδί def και η λέξη-κλειδί return),
  3. Σχόλια, και
  4. Docstrings.

Note

Σε γενικές γραμμές, το περιεχόμενο, τα τεστ και τα εργαλεία ανάλυσης για τη διαδρομή Python ακολουθούν τις συμβάσεις στυλ που περιγράφονται στα PEP 8 και PEP 257 για το στυλ κώδικα Python, με την επιπλέον (ισχυρή) σύσταση να μην υπάρχουν ονόματα μεταβλητών με ένα μόνο γράμμα ή μεταβλητές με όνομα "_".

Στη διαδρομή Python, οι μεταβλητές γράφονται πάντα με snake_case, και οι σταθερές με SCREAMING_SNAKE_CASE.


Ανάθεση ονόματος (Μεταβλητές & σταθερές)

Οι προγραμματιστές μπορούν να δεσμεύσουν ονόματα (που ονομάζονται επίσης μεταβλητές) σε οποιονδήποτε τύπο αντικειμένου χρησιμοποιώντας τον τελεστή ανάθεσης =: <name> = <value>. Ένα όνομα μπορεί να ανατεθεί εκ νέου (ή να δεσμευτεί ξανά) σε διαφορετικές τιμές (διαφορετικούς τύπους αντικειμένων) κατά τη διάρκεια της ζωής του.

>>> my_first_variable = 1  #<-- my_first_variable bound to an integer object of value one.
>>> my_first_variable = 2  #<-- my_first_variable re-assigned to integer value 2.

>>> print(type(my_first_variable))
<class 'int'>

>>> print(my_first_variable)
2

>>> my_first_variable = "Now, I'm a string." #<-- You may re-bind a name to a different object type and value.
>>> print(type(my_first_variable))
<class 'str'>

>>> my_first_variable = 'You can call me "str".' #<-- Strings can be declared using single or double quote marks.
>>> print(my_first_variable)
You can call me "str".

Σταθερές

Οι σταθερές είναι ονόματα που προορίζονται να ανατεθούν μόνο μία φορά σε ένα πρόγραμμα. Θα πρέπει να ορίζονται σε επίπεδο module (αρχείου) και είναι συνήθως ορατές σε όλες τις συναρτήσεις και τις κλάσεις του προγράμματος. Η χρήση του SCREAMING_SNAKE_CASE σηματοδοτεί ότι το όνομα δεν πρέπει να ανατεθεί εκ νέου ούτε η τιμή του να μεταβληθεί.

Συναρτήσεις

Η λέξη-κλειδί def ξεκινά έναν ορισμό συνάρτησης. Κάθε συνάρτηση μπορεί να έχει μηδέν ή περισσότερες τυπικές παραμέτρους μέσα σε () παρενθέσεις, ακολουθούμενες από : άνω και κάτω τελεία. Οι εντολές για το σώμα της συνάρτησης ξεκινούν από τη γραμμή που ακολουθεί το def και πρέπει να είναι με εσοχή μέσα σε μπλοκ.

# The body of a function is indented by 2 spaces, & prints the sum of the numbers.
def add_two_numbers(number_one, number_two):
  total = number_one + number_two
  print(total)  

>>> add_two_numbers(3, 4)
7


# Inconsistent indentation in your code blocks will raise an error.
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
...     result = number_one + number_two + number_three   # This was indented by 4 spaces.
...    print(result)     #this was only indented by 3 spaces
...
...
  File "<stdin>", line 3
    print(result)
    ^
IndentationError: unindent does not match any outer indentation level

Οι συναρτήσεις επιστρέφουν ρητά μια τιμή ή ένα αντικείμενο μέσω της λέξης-κλειδιού return:

# Function definition on first line, explicit return used on final line.
>>> def add_two_numbers(number_one, number_two):
        return number_one + number_two   


# Calling the function in the Python shell returns the sum of the numbers.
>>> add_two_numbers(3, 4)
7

# Assigning the function call to a variable and printing it 
# will also return the value.
>>> sum_with_return = add_two_numbers(5, 6)
>>> print(sum_with_return)
11

Οι συναρτήσεις που δεν έχουν μια ρητή έκφραση μετά το return επιστρέφουν σιωπηρά το αντικείμενο None. Οι λεπτομέρειες του None θα καλυφθούν σε επόμενη άσκηση. Για τους σκοπούς αυτής της άσκησης και της εξήγησης, το None είναι ένα σύμβολο κράτησης θέσης που αντιπροσωπεύει το τίποτα, ή το null:


# This function will return `None`
def square_a_number(number):
    square = number * number
    return # <-- note that this return is not followed by an expression

# Calling the function in the Python shell appears 
# to not return anything at all.
>>> square_a_number(2)
>>>


# Using print() with the function call shows that 
# the function is actually returning the **None** object.
>>> print(square_a_number(2))
None

Οι συναρτήσεις που παραλείπουν το return επιστρέφουν επίσης σιωπηρά το αντικείμενο None. Αυτό σημαίνει ότι αν δεν χρησιμοποιείς το return μέσα σε μια συνάρτηση, η Python επιστρέφει το αντικείμενο None για σένα.

# This function omits a return keyword altogether.
def add_two_numbers(number_one, number_two):
  result = number_one + number_two

>>> add_two_numbers(5, 7)
>>> print(add_two_numbers(5, 7))
None

# Assigning the function call to a variable and printing 
# the variable will also show None.
>>> sum_without_return = add_two_numbers(5, 6)
>>> print(sum_without_return)
None

Κλήση συναρτήσεων

Οι συναρτήσεις καλούνται ή ενεργοποιούνται χρησιμοποιώντας το όνομά τους ακολουθούμενο από (). Ο συμβολισμός με τελεία (.) χρησιμοποιείται για την κλήση συναρτήσεων που έχουν οριστεί μέσα σε μια κλάση ή ένα module.

>>> def raise_to_power(number, power):
...     return number ** power
...

>>> raise_to_power(3,3) # <--Invoking the function with the arguments 3 and 3.
27


# A mismatch between the number of parameters and the number of arguments will raise an error.
>>> raise_to_power(4,)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: raise_to_power() missing 1 required positional argument: 'power'


# Calling methods or functions in classes and modules.
>>> start_text = "my silly sentence for examples."
>>> str.upper(start_text)  # <--Calling the upper() method from the built-in str class on start_text.
'MY SILLY SENTENCE FOR EXAMPLES.'


# Importing the math module
>>> import math

>>> math.pow(2,4)  # <--Calling the pow() function from the math module.
16.0

Σχόλια

Τα σχόλια στην Python ξεκινούν με ένα # που δεν αποτελεί μέρος μιας συμβολοσειράς και τελειώνουν στο τέλος της γραμμής. Σε αντίθεση με πολλές άλλες γλώσσες προγραμματισμού, η Python δεν υποστηρίζει σημάδια σχολίων πολλών γραμμών. Κάθε γραμμή ενός μπλοκ σχολίων πρέπει να ξεκινά με τον χαρακτήρα #.

Docstrings

Η πρώτη εντολή του σώματος μιας συνάρτησης μπορεί προαιρετικά να είναι ένα docstring, το οποίο συνοψίζει περιεκτικά τον σκοπό της συνάρτησης ή του αντικειμένου. Τα docstrings δηλώνονται με τριπλά διπλά εισαγωγικά (""") με εσοχή στο ίδιο επίπεδο με το μπλοκ κώδικα:


# An example from PEP257 of a multi-line docstring
# reformatted to use Google style non-type hinted docstrings.
# Some additional details can be found in the Sphinx documentation:
# https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#getting-started

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword Arguments:
        real (float): The real part of the number (default 0.0)
        imag (float): The imaginary part of the number (default 0.0)
        
    """

    if imag == 0.0 and real == 0.0:
        return complex_zero

Τα docstrings διαβάζονται από αυτοματοποιημένα εργαλεία τεκμηρίωσης, όπως το Sphinx, και επιστρέφονται καλώντας το ειδικό χαρακτηριστικό .__doc__ στο όνομα της συνάρτησης, της μεθόδου ή της κλάσης. Οι γενικές συμβάσεις για τα docstrings περιγράφονται στο PEP257, αλλά οι ακριβείς μορφές ποικίλλουν ανάλογα με το project και την ομάδα. Οι ασκήσεις εννοιών του Exercism προσπαθούν να ακολουθούν το στυλ Google για κώδικα χωρίς type hints.

Τα docstrings μπορούν επίσης να λειτουργήσουν ως ελαφριά unit tests, τα οποία θα καλυφθούν σε επόμενη άσκηση.

# An example on a user-defined function using a Google style docstring. 
>>> def raise_to_power(number, power):
    """Raise a number to an arbitrary power.

    Parameters:
        number (int): The base number.
        power (int): The power to raise the base number to.
    
    Returns:
        int: The number raised to the specified power.
    
    Takes a number and raises it to the specified power, returning the result.

    """

    return number ** power
...

# Calling the .__doc__ attribute of the function and printing the result.
>>> print(raise_to_power.__doc__)
Raise a number to an arbitrary power.

Parameters:
    number (int): The base number.
    power (int): The power to raise the base number to.

Returns:
    int: The number raised to the specified power.

Takes a number and raises it to the specified power, returning the result.

Οδηγίες

Θα γράψεις λίγο κώδικα για να σε βοηθήσει να μαγειρέψεις μια υπέροχη λαζάνια από το αγαπημένο σου βιβλίο μαγειρικής.

Έχεις πέντε εργασίες, όλες σχετικές με το μαγείρεμα της συνταγής σου.


Note

Έχουμε ξεκινήσει την πρώτη δήλωση συνάρτησης για σένα στο αρχείο stub, αλλά θα χρειαστεί να γράψεις τις υπόλοιπες δηλώσεις συναρτήσεων μόνος σου. Θα χρειαστεί επίσης να ορίσεις μόνος σου τυχόν σταθερές. Διάβασε προσεκτικά τις γραμμές σχολίων #TODO στο αρχείο stub. Όταν τελειώσεις με μια εργασία, αφαίρεσε το σχόλιο TODO.


1. Όρισε τον αναμενόμενο χρόνο ψησίματος σε λεπτά ως σταθερά

Όρισε τη σταθερά EXPECTED_BAKE_TIME που αντιπροσωπεύει πόσα λεπτά πρέπει να ψηθεί η λαζάνια στον φούρνο. Σύμφωνα με το βιβλίο μαγειρικής σου, η λαζάνια πρέπει να είναι στον φούρνο για 40 λεπτά:

>>> print(EXPECTED_BAKE_TIME)
40

2. Υπολόγισε τον χρόνο ψησίματος που απομένει σε λεπτά

Ολοκλήρωσε τη συνάρτηση bake_time_remaining() που παίρνει ως όρισμα τα πραγματικά λεπτά που βρίσκεται η λαζάνια στον φούρνο και επιστρέφει πόσα λεπτά χρειάζεται ακόμη να ψηθεί η λαζάνια με βάση τη σταθερά EXPECTED_BAKE_TIME.

>>> bake_time_remaining(30)
10

3. Υπολόγισε τον χρόνο προετοιμασίας σε λεπτά

Όρισε τη συνάρτηση preparation_time_in_minutes() που παίρνει ως όρισμα το number_of_layers, τον αριθμό των στρώσεων που θέλεις να προσθέσεις στη λαζάνια, και επιστρέφει πόσα λεπτά θα χρειαστείς για να τις φτιάξεις. Θεώρησε ότι κάθε στρώση χρειάζεται 2 λεπτά για να προετοιμαστεί.

>>> def preparation_time_in_minutes(number_of_layers):
        ...
        ...
        
>>> preparation_time_in_minutes(2)
4

4. Υπολόγισε τον συνολικό χρόνο που έχει περάσει (προετοιμασία + ψήσιμο) σε λεπτά

Όρισε τη συνάρτηση elapsed_time_in_minutes() που δέχεται δύο παραμέτρους ως ορίσματα:

  • number_of_layers (ο αριθμός των στρώσεων που προστέθηκαν στη λαζάνια)
  • elapsed_bake_time (ο αριθμός των λεπτών που έχει περάσει η λαζάνια ψήνοντας στον φούρνο μέχρι τώρα).

Αυτή η συνάρτηση θα πρέπει να επιστρέφει τα συνολικά λεπτά που έχεις περάσει στην κουζίνα μαγειρεύοντας: τον χρόνο προετοιμασίας για τις στρώσεις συν τον χρόνο που έχει περάσει η λαζάνια ψήνοντας στον φούρνο.

>>> def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
        ...
        ...
        
>>> elapsed_time_in_minutes(3, 20)
26

5. Ενημέρωσε τη συνταγή με σημειώσεις

Ξαναδές τη συνταγή, προσθέτοντας "σημειώσεις" με τη μορφή docstrings συναρτήσεων.

def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
    """Calculate the elapsed cooking time.
    
    Parameters:
        number_of_layers (int): The number of layers in the lasagna.
        elapsed_bake_time (int): Time the lasagna has been baking in the oven.
    
    Returns:
        int: The total time elapsed (in minutes) preparing and baking.

    This function takes two integers representing the number of lasagna 
    layers and the time already spent baking the lasagna. It calculates 
    the total elapsed minutes spent cooking (preparing + baking).
    
    """
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Python Exercism

Έτοιμος να ξεκινήσεις την άσκηση Τα υπέροχα λαζάνια του Guido;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Python με 17 έννοιες146 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.