Στην άσκηση αυτή θα συμπληρώσετε τον κώδικα Python που βρίσκεται στο αρχείo hw3.py ακολουθώντας τις ίδιες οδηγίες (δείτε και εδώ) με αυτές που δόθηκαν στη Σειρά Ασκήσεων 1. (Αυτόματοι έλεγχοι ορθότητας βρίσκονται στο hw3_tests.txt.)

Τρόπος παράδοσης:

Θα παραδώσετε το αρχείο hw3.py.

  1. Οι φοιτητές που έχουν εγγραφεί στο eclass θα παραδόσουν την εργασία από εκεί.
  2. Οι φοιτητές που δεν έχουν εγγραφεί στο eclass θα την παραδώσουν με email στο dimakis@aueb.gr με θέμα (subject): [2023 - ΑΣΚΗΣΗ 3] (με τις αγκύλες) που επίσης περιέχει το ονοματεπώνυμο τους στο σώμα του μηνύματος και σε σχόλιο μέσα στο hw3.py.

Άσκηση 1

Θα πρέπει να υλοποιήσετε ένα σύνθετο τύπο δεδομένου (όπως ο rational στη Διάλεξη 6) που αναπαριστά μια "γεωγραφική τοποθεσία", συμπληρώνοντας τον κώδικα στα κενά _________ του κατασκευαστή (constructor) location και των συναρτήσεων επιλογής (selectors) name, longitude, lattitude, type.

Η κλήση στον κατασκευαστή location(name, lat, lon, type) πρέπει να επιστρέφει το σύνθετο δεδομένο τοποθεσίας με τοπωνύμιο name, το οποίο βρίσκεται στο γεωγραφικό πλάτος και μήκος lat και lon αντίστοιχα, και το είδος της τοποθεσίας δίνεται στη συμβολοσειρά (str) type, πχ., 'monument' (μνημείο), 'park' (πάρκο).

Συμπληρώστε τα κενά των συναρτήσεων επιλογής του δεδομένου location, δηλαδή στις συναρτήσεις name, longitude, latitude και type, έτσι ώστε για μια τοποθεσία loc (δηλ., δεδομένο location):

def location(name, lat, lon, type):
"""Kataskeuazei syn8eto dedomeno topo8esias (location).

name -- onoma (str)
lat -- gewfrafiko platos (se moires)
lon -- gewgrafiko mikos (se moires)
type -- eidos topo8esias (str)

Epistrefei dedomeno pou anaparista tin topo8esia me onoma name h opoia
brisketai sto gewgrafiko platos kai mikos lat kai lon antistoixa. To type
einai string pou perigrafei to eidos tis topo8esias, p.x., 'monument',
'bus station'.
"""
return ______________________________


def name(loc):
"""Epistrefei to onoma mias topo8esias.

loc -- topo8esia (typou location)

Epistrefei to onoma (str) tis topo8esias loc.

>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> name(monast)
'Monastiraki'
"""
return _________________


def longitude(loc):
"""Gewgrafiko mikos.

loc -- dedomeno location

Epistrefei gewgrafiko mikos tis topo8esias loc

>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> longitude(monast)
23.725947
"""
return _________________


def lattitude(loc):
"""Gewgrafiko platos.

loc -- dedomeno location

Epistrefei gewgrafiko mikos tis topo8esias loc

>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> lattitude(monast)
37.976362
"""
return _________________


def type(loc):
"""Eidos topo8esias.

loc -- dedomeno location

Epistrefei string pou perigrafei to eidos tis topo8esias loc, p.x.,
'monument', 'bus station'.

>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> type(monast)
'square'
"""
return _________________

Άσκηση 2

Συμπληρώστε τον κώδικα ή τα κενά _________ στις συναρτήσεις distance, print_location και nearest_location, έτσι ώστε να δίνουν τα επιθυμητά αποτελέσματα, χωρίς όμως να κάνετε χρήση της αναπαράστασης των δεδομένων location που βρίσκεται εσωτερικά στον κώδικα κατασκευαστή και συναρτήσεων επιλογής στην Άσκηση 1Ο κώδικας των συναρτήσεων θα πρέπει να χρησιμοποιεί τα σύνθετα δεδομένα location μόνο μέσω κλήσεων στον κατασκευαστή και στις συναρτήσεις επιλογής της Άσκησης 1 . (Σημειώστε ότι οι συναρτήσεις αυτές θα πρέπει να εξακολουθούν να λειτουργούν σωστά -και χωρίς να χρειαστεί να αλλάξουν- ακόμη και αν οι συναρτήσεις location, name, longitude, lattitude στην Άσκηση 1 είχαν υλοποιηθεί με διαφορετικό τρόπο.)

Η κλήση distance(a, b) επιστρέφει την απόσταση (σε χιλιόμετρα) μεταξύ των τοποθεσιών που αναπαριστάνουν τα δεδομένα a, b τύπου location. Η print_location(loc) εμφανίζει στοιχεία για την τοποθεσία loc. Η nearest_location(loc, loc_list, loc_type) επιστρέφει το δεδομένο location που βρίσκεται στη λίστα με τοποθεσίες loc_list το οποίο απέχει τη μικρότερη απόσταση από την τοποθεσία loc και είναι τύπου loc_type. Εάν το είδος της τοποθεσίας παραληφθεί, πχ., καλώντας nearest_location(loc, loc_list), τότε επιστρέφεται η κοντινότερη τοποθεσία ανάμεσα σε αυτές στη loc_list ανεξάρτητα από το είδος της.

def distance(a, b):
"""Apostasi meta3y topo88esiwn.

a -- topo8esia A (afirimeno dedomeno typou location)
b -- topo8esia B (afirimeno dedomeno typou location)

Epistrefei tin apostasi
meta3y ths topo8esias A kai B se xiliometra.

>>> aueb = location('AUEB', 37.994097, 23.732253, 'university campus')
>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> distance(aueb, monast)
2.5224714882938657
>>> distance(aueb, aueb)
0.0
"""
a_lat = _____________________ # gewgrafiko platos (lattitude) a
a_lon = _____________________ # gewgrafiko mikos (longitude) a
b_lat = _____________________ # gewgrafiko platos (lattitude) b
b_lon = _____________________ # gewgrafiko mikos (longitude) b

from math import pi, cos
phi_m = pi/180 * (a_lat + b_lat) / 2
k1 = 111.13209 - 0.56605 * cos(2*phi_m) + 0.00120 * cos(4*phi_m)
k2 = 111.41513 * cos(phi_m) - 0.0945 * cos(3*phi_m) + 0.00012*cos(5*phi_m)
lat_dist = (a_lat - b_lat) * k1
lon_dist = (a_lon - b_lon) * k2
return abs(lon_dist) + abs(lat_dist)


def print_location(loc):
"""Emfanizei stoixeia topo8esias.

loc -- dedomeno location

Emfanizei stoixeia gia tin topo8esia loc opws sta paradeigmata:

>>> monast = location('Monastiraki', 37.976362, 23.725947, 'square')
>>> print_location(monast)
Monastiraki (square) at coordinates 37.976362, 23.725947
>>> print_location(location('North Pole', 90.0, 135.0, 'pole'))
North Pole (pole) at coordinates 90.0, 135.0
"""
"""GRAPSTE TON KWDIKA SAS APO KATW."""


def nearest_location(loc, loc_list, loc_type=None):
"""Epistrefei plisiesteri topo8esia.

loc -- topo8esia (dedomeno typoy location)
loc_list -- lista pou periexei topo8esies (dedomena location)
loc_type -- eidos topo8esias (str)

Epistrefei tin plisiesteri topo8esia stin loc apo autes pou briskonai sti
lista loc_list tou eidous loc_type.

Paradeigmata:
>>> llist = [location('AUEB', 37.994097, 23.732253, 'university campus'),\
location('Acropolis', 37.971584, 23.725912, 'monument'), \
location('Syntagma', 37.975560, 23.734691, 'square'), \
location('National Garden', 37.973116, 23.736483, 'park'), \
location('Monastiraki', 37.976362, 23.725947, 'square')]
>>> name(nearest_location(llist[2], llist, 'monument'))
'Acropolis'
>>> name(nearest_location(llist[1], llist, 'square'))
'Monastiraki'
>>> name(nearest_location(llist[2], llist))
'National Garden'
>>> name(nearest_location(llist[2], llist, 'square'))
'Monastiraki'
"""
"""GRAPSTE TON KWDIKA SAS APO KATW."""

Άσκηση 3

Συμπληρώστε τα κενά _________ ώστε η κλήση pick_cherries_only() να έχει το αποτέλεσμα που περιγράφεται στα σχόλια.

def pick_cherries_only():
"""Emfanizei string pou briskontai se fwliasmenes listes.

Prepei na exei to akolou8o apotelesma:

>>> pick_cherries_only()
cherry1
cherry2
cherry3
cherry4
Yay!!!
"""
""" SYMPLHRWSTE TA KENA APO KATW."""
fruits = ['cherry1', 'orange', \
['grape', 'cherry2', ['cherry3'], 'banana'], \
None, 'cherry4', [[['Yay!!!']]]]

print(fruits[0])
print(fruits__________________)
print(fruits__________________)
print(fruits__________________)
print(fruits__________________)

Άσκηση 4

Συμπληρώστε τα κενά ώστε η κλήση pick_cherries_onebyone() να έχει το αποτέλεσμα που περιγράφεται στα σχόλια, χωρίς να χρησιμοποιήσετε πρωταρχικές εκφράσεις όπως 'cherry2', 'cherry3', κτλ.  

def pick_cherries_onebyone():
"""Emfanizei string pou briskontai se fwliasmenes listes.

Prepei na exei to akolou8o apotelesma:

>>> pick_cherries_onebyone()
cherry1
cherry2
cherry3
cherry4
last cherry
"""
""" SYMPLHRWSTE TA KENA APO KATW."""
cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['last cherry', None]]]]]

print(cherry_field[0])
______________________________
print(cherry_field[0])
______________________________
print(cherry_field[0])
______________________________
print(cherry_field[0])
______________________________
print(cherry_field[0])

Άσκηση 5

Συμπληρώστε τα κενά ώστε η κλήση pick_cherries(field) να εμφανίζει τις συμβολοσειρές (str) οι οποίες βρίσκονται στην πρώτη θέση των φωλιασμένων λιστών που δίνονται στο όρισμα field, όπως στα παραδείγματα των σχολίων.

Θεωρήστε ότι το όρισμα field είναι μια φωλιασμένη λίστα της ίδιας μορφής με την cherry_field της Άσκησης 4, με αυθαίρετα πολλές φωλιασμένες λίστες που όμως πάντα το πρώτο τους στοιχείο είναι συμβολοσειρά (str). Το δεύτερο στοιχείο της τελευταίας λίστας (δηλ., αυτής που περιέχεται σε όλες τις άλλες) έχει τιμή None.

Η υλοποίησή σας πρέπει να χρησιμοποιεί την εντολή while στο σώμα της pick_cherries. (Σημειώστε ότι το πλήθος των γραμμών με κενά είναι ενδεικτικό μόνο: μπορείτε να χρησιμοποιήσετε περισσότερες ή λιγότερες τέτοιες γραμμές.)

def pick_cherries(field):
"""Emfanizei string pou briskontai se fwliasmenes listes.

field -- lista me fwliasmena string. Ka8e lista exei dyo stoixeia:
to prwto einai string kai to deutero einai eite lista ths idias
morfhs 'h None. (Opws kai h cherry_field sto swma ths synarthshs
pick_cherries_onebyone()).

Leitoyrgei opws i pick_cherries_onebyone, omws gia au8aireta polles
fwliasmenes listes stin field.

Paradeigmata:

>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['last cherry', None]]]]]
>>> pick_cherries(cherry_field)
cherry1
cherry2
cherry3
cherry4
last cherry
>>> pick_cherries(['Hello', ['world', None]])
Hello
world
"""
""" SYMPLHRWSTE TA KENA APO KATW."""
________________
________________
while ______________:
____________________
print(______________)
____________________

 Άσκηση 6

Συμπληρώστε τον κώδικα στη συνάρτηση all_iter έτσι ώστε η κλήση all_iter(func, ls) να επιστρέφει True εάν και μόνο εάν η κλήση func(x) έχει τιμή True για όλα τα στοιχεία x της λίστας ls. 

Η υλοποίησή σας θα πρέπει να χρησιμοποιεί επαναληπτικό υπολογισμό, δηλ., την εντολή while ή for, χωρίς comprehensions ή αναδρομικό υπολογισμό. (Στις ασκήσεις 7 εως 9 θα υλοποιήσετε την ίδια συνάρτηση με τους άλλους τρόπους.)

def all_iter(func, ls):
"""True mono ean i klisi func(x) epistrefei True
gia ola ta stoixeia x tis ls.

func -- synartisi enos orismatos
ls -- lista

Paradeigmata:
>>> all_iter(lambda x: x >= 0, [1, 2, 3, 0, 4])
True
>>> all_iter(lambda x: x >= 0, [1, 2, -3, 0, 4])
False
>>> all_iter(lambda x: x % 2 == 0, [100, 10, 2022, 12])
True
"""
"""XRHSIMOPOIHSTE EPANALHPTIKO YPOLOGISMO (for 'h while).
MHN XRHSIMOPOIHSETE LIST COMPREHENSIONS 'h ANADROMI."""
"""GRAPSTE TON KWDIKA SAS APO KATW."""

Άσκηση 7

Συμπληρώστε τον κώδικα στη συνάρτηση all_rec έτσι ώστε η κλήση all_rec(func, ls) να επιστρέφει True εάν και μόνο εάν η κλήση func(x) έχει τιμή True για όλα τα στοιχεία x της λίστας ls. 

Η υλοποίησή σας θα πρέπει να χρησιμοποιεί αναδρομικό υπολογισμό, χωρίς επαναληπτικό υπολογισμό, (δηλ., την εντολή while ή fo)r ή comprehensions . (Στις ασκήσεις 6 εως 9 θα υλοποιήσετε την ίδια συνάρτηση με τους άλλους τρόπους.)

def all_rec(func, ls):
"""True mono ean i klisi func(x) epistrefei True
gia ola ta stoixeia x tis ls.

func -- synartisi enos orismatos
ls -- lista

Paradeigmata:
>>> all_rec(lambda x: x >= 0, [1, 2, 3, 0, 4])
True
>>> all_rec(lambda x: x >= 0, [1, 2, -3, 0, 4])
False
>>> all_rec(lambda x: x % 2 == 0, [100, 10, 2022, 12])
True
"""
"""XRHSIMOPOIHSTE ANADROMH.
MHN XRHSIMOPOIHSETE LIST COMPREHENSIONS 'h EPANALHPTIKO YPOLOGISMO
(for 'h while)."""
"""GRAPSTE TON KWDIKA SAS APO KATW."""

 Άσκηση 8

Συμπληρώστε τον κώδικα στη συνάρτηση all_lc έτσι ώστε η κλήση all_lc(func, ls) να επιστρέφει True εάν και μόνο εάν η κλήση func(x) έχει τιμή True για όλα τα στοιχεία x της λίστας ls. 

Η υλοποίησή σας θα πρέπει να χρησιμοποιεί επεξεργασία ακολουθιών με list comprehensions, χωρίς αναδρομικό ή επαναληπτικό υπολογισμό, (δηλ., την εντολή while ή for) . (Στις ασκήσεις 6 εως 9 θα υλοποιήσετε την ίδια συνάρτηση με τους άλλους τρόπους.)

def all_lc(func, ls):
"""True mono ean i klisi func(x) epistrefei True
gia ola ta stoixeia x tis ls.

func -- synartisi enos orismatos
ls -- lista

Paradeigmata:
>>> all_lc(lambda x: x >= 0, [1, 2, 3, 0, 4])
True
>>> all_lc(lambda x: x >= 0, [1, 2, -3, 0, 4])
False
>>> all_lc(lambda x: x % 2 == 0, [100, 10, 2022, 12])
True
"""
"""XRHSIMOPOIHSTE EPE3ERGASIA AKOLOU8IWN ME LIST COMPREHENSIONS.
MHN XRHSIMOPOIHSETE ANADROMH 'h EPANALHPTIKO YPOLOGISMO
(for 'h while)."""
"""GRAPSTE TON KWDIKA SAS APO KATW."""

Άσκηση 9

Συμπληρώστε τον κώδικα στη συνάρτηση all_hof έτσι ώστε η κλήση all_hof(func, ls) να επιστρέφει True εάν και μόνο εάν η κλήση func(x) έχει τιμή True για όλα τα στοιχεία x της λίστας ls. 

Η υλοποίησή σας θα πρέπει να χρησιμοποιεί επεξεργασία ακολουθιών με συναρτήσεις ανώτερου επιπέδου (map, filter, reduce), χωρίς αναδρομικό ή επαναληπτικό υπολογισμό, (δηλ., την εντολή while ή for) ή comprehensions . (Στις ασκήσεις 6 εως 8 θα υλοποιήσετε την ίδια συνάρτηση με τους άλλους τρόπους.)

def all_hof(func, ls):
"""True mono ean i klisi func(x) epistrefei True
gia ola ta stoixeia x tis ls.

func -- synartisi enos orismatos
ls -- lista

Paradeigmata:
>>> all_hof(lambda x: x >= 0, [1, 2, 3, 0, 4])
True
>>> all_hof(lambda x: x >= 0, [1, 2, -3, 0, 4])
False
>>> all_hof(lambda x: x % 2 == 0, [100, 10, 2022, 12])
True
"""
"""XRHSIMOPOIHSTE EPE3ERGASIA AKOLOU8IWN ME SYNARTHSEIS ANWTEROY EPIPEDOY
(map, filter, reduce).
MHN XRHSIMOPOIHSETE ANADROMH, EPANALHPTIKO YPOLOGISMO (for 'h while)
'h LIST COMPREHENSIONS."""
"""GRAPSTE TON KWDIKA SAS APO KATW."""

Άσκηση 10

Συμπληρώστε τον κώδικα στη συνάρτηση primes_up_to έτσι ώστε η κλήση primes_up_to(n) να επιστρέφει λίστα που περιέχει όλους τους πρώτους αριθμούς μικρότερους ή ίσους του n. (Ένας αριθμός είναι πρώτος εάν είναι μεγαλύτερος ή ίσος του 2 και δεν έχει άλλους διαιρέτες εκτός φυσικά το 1 και τον ίδιο.)

Η υλοποίησή σας θα πρέπει να χρησιμοποιεί το "κόσκινο του Ερατοσθένη" με επαναληπτικό φιλτράρισμα ακολουθιών, όπως περιγράφεται στη διάλεξη 7, με επεξεργασία ακολουθιών (list comprehensions ή συναρτήσεις ανώτερου επιπέδου). Χρησιμοποιήστε εντολή επανάληψης για την επαναληπτική εφαρμογή του φιλτραρίσματος.

def primes_up_to(n):
"""Prwtoi ari8moi ews to n.

n -- akeraios >= 2

Epistrefei lista me olous tous prwtous ari8mous mikroterous 'h isous me n.

Paradeigmata:
>>> primes_up_to(10)
[2, 3, 5, 7]
>>> primes_up_to(20)
[2, 3, 5, 7, 11, 13, 17, 19]
>>> len(primes_up_to(10000))
1229
"""
"""XRHSIMOPOIHSTE EPE3ERGASIA AKOLOU8IWN ME LIST COMPREHENSIONS 'h
SYNARTHSEIS ANWTEROY EPIPEDOY (map, reduce, filter)."""
"""GRAPSTE TON KWDIKA SAS APO KATW."""