Skip to content

Instantly share code, notes, and snippets.

@kantale
Last active April 3, 2020 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kantale/b726b3ac17fbb00eb21fec8e262967ec to your computer and use it in GitHub Desktop.
Save kantale/b726b3ac17fbb00eb21fec8e262967ec to your computer and use it in GitHub Desktop.
Προγραμματισμός με τη γλώσσα python

Επικοινωνία

Ώρες/τόπος μαθήματος

  • 8 Νοεμβρίου 2018 . 11:00 - 14:00, 7A-02
  • 22 Νοεμβρίου 2018 . 11:00 - 14:00, 7Α-04
  • 23 Νοεμβρίου 2018 . 10:00 - 13:00, 7Α-02
  • 29 Νοεμβρίου 2018 . 11:00 - 14:00, 7Α-01
  • 6 Δεκεμβρίου 2018 . 9:00 - 12:00, 7Α-01 (ίσως ΔΙΕΠ)
  • 13 δεκεμβρίου 2018 . 9:00 - 12:00, 7Α-01 (ίσως ΔΙΕΠ)
  • 18 Δεκεμβρίου 2018. 12:00 - 15:00

Προηγούμενες χρονιές

Επιπλέον υλικό

Βαθμολογία

  • Θα δωθούν 5 σειρές ασκήσεων, μία κάθε 2 εβδομάδες περίπου. Η κάθε σειρά μετράει στο 10% του βαθμού (συνολικά 50%).
  • Στο τέλος της χρονιάς θα δωθεί ένα project. Το project θα μετρήσει για το 60% του βαθμού.

Διαλέξεις 2018-2019

Ασκήσεις

Γενικά

Όλες οι ερωτήσεις των ασκήσεων είναι ισοδύναμες. Η τελική ημερομηνία παράδοσης είναι 28 Φεβρουαρίου 2019. Προσοχή: Η τελική ημερομηνία παράδοσης είναι μακριά ακριβώς για να κάνετε τον δικό σας σχεδιασμό χρόνου. ΔΕΝ ΘΑ ΔΟΘΕΙ ΠΑΡΆΤΑΣΗ ΓΙΑ ΜΕΤΑ ΤΙΣ 28 ΦΕΒΡΟΥΑΡΙΟΥ. Επίσης θα πρέπει να έχετε στείλει τουλάχιστον μία προσπάθεια για τις ασκήσεις μέχρι την ημερομηνία που αναγράφεται στη λίστα. Μπορείτε να στέλνετε τις απαντήσεις σταδιακά. Δηλαδή μπορείτε να στείλετε μόνο τις απαντήσεις συγκεκριμμένων ερωτημάτων τώρα και τις υπόλοιπες μετά από 1 μήνα ή όποτε θέλετε. Επίσης αν στείλετε μία απάντηση λάθος επειδή δεν καταλάβατε την εκφώνηση μπορείτε να τη ξαναστείλετε. Μπορεί να φαίνονται ελαστικά τα παραπάνω αλλά πρέπει να έχετε υπόψην σας ότι κάθε σειρά ασκήσεων θα έχει πολλά ερωτήματα. Κάντε σωστό πλάνο. Συμβουλέυω να δουλεύετε τις ασκήσεις σε εβδομαδιαία βάση και να στέλνετε ό,τι έχετε έτοιμο στο τέλος της εβδομάδας.

Η χρήση google επιτρέπεται και ενθαρρύνεται. Απλά, θα πρέπει να βάζετε σε σχόλια τα links τα οποία θεωρείτε ότι σας βοήθησαν στη λύση σας. Μη κάνετε copy/paste λύσεις που βρίσκετε στο Internet. Αν βρείτε μία λύση, μελετήστε τη, δείτε "πως το έκανε" και ξαναγράφτε τη λύση με το δικό σας τρόπο. Αν έχετε κολήσει, στείλτε μέιλ!

Περί αντιγραφής: Δεν πρόκειται να κάνω κάποιον σοβαρό έλεγχο για αντιγραφή και ποινές (μηδενισμός) θα υπάρξουν μόνο για πολύ κραυγαλέες περιπτώσεις. Για ό,τι δεν μπορείτε να λύσετε, δεν "βγαίνει", δεν έχετε καταλάβει στείλτε mail να το δούμε μαζί! Εκμεταλευτείτε το μάθημα στο έπακρο για να μάθετε ένα εργαλείο που θα σας είναι απαραίτητο στο μέλλον!

Mail με απορίες

Mail με απορίες είναι ευπρόσδεκτα. Αν είσαστε στο δίλημμα αν πρέπει ή δεν πρέπει να στείλετε mail, τότε στείλτε mail! Απλά βοηθήστε με να σας βοηθήσω. Το mail σας θα πρέπει να περιέχει απαραίτητα τον κώδικα που έχετε δοκιμάσει και δεν δούλεψε. Μην στέλνετε mail "δοκίμασα να κάνω list comprehension αλλά δεν δούλεψε". Επίσης στείλετε είτε το error που πετάει είτε τη λάθος λύση.

Πως στέλνονται οι ασκήσεις

Οι ασκήσεις μπορούν να παραδοθούν στέλνοντας τις λύσεις με email στο kantale@ics.forth.gr με έναν από τους παρακάτω τρόπους:

  • Στείλτε ένα .ipynb (jupyter notebook) αρχείο ως attachment με τις λύσεις.
  • Στείλτε ένα .py (python) αρχείο ως attachment με τις λύσεις.
  • Στείλτε ένα link στο gist με το jupyter notebook με τις λύσεις.
  • Στείλτε ένα link στο gist με τον python κώδικα με τις λύσεις.

Σε κάθε περίπτωση βάζετε σε σχόλια (ή σε markdown) τον αριθμό της άσκησης που λύνετε

Λίστα με τις ασκήσεις

Πως βαθμολογείται μία άσκηση

  1. Η άσκηση βγάζει λάθος αποτέλεσμα και κάποια ψήγματα υλοποίησης έχουν γίνει.
  2. Η άσκηση βγάζει λάθος αποτέλεσμα αλλά έχει υλοποιηθεί ένα μικρό κομμάτι της λύσης.
  3. Η άσκηση βγάζει λάθος αποτέλεσμα αλλά έχει υλοποιηθεί ένα σημαντικό κομμάτι της λύσης.
  4. Η άσκηση βγάζει λάθος αποτελέσματα λόγω πολύ σημαντικών λαθών στη λογική.
  5. Η άσκηση βγάζει λάθος αποτέλεσμα λογω λαθών στη λογική
  6. Η άσκηση βγάζει λάθος αποτέλεσμα λόγω μικρών λαθών στη λογική.
  7. H άσκηση βγάζει σωστό αποτέλεσμα, αλλά όχι για όλα τα πιθανά σενάρια/inputs.
  8. Η άσκηση βγάζει σωστό αποτέλεσμα, αλλά η λογική σας έχει κάποιο λάθος (συμβαίνει πολλές φορές..).
  9. Η άσκηση βγάζει σωστό αποτέλεσμα, αλλά υπάρχει μία προφανής πιο γρήγορη/σύντομη λύση.
  10. Η άσκηση είναι αλάνθαστη. Μπράβο!

Λίστα με κοινά λάθη που θα πρέπει να αποφεύγετε

  1. Αποφεύγετε να βάζετε κενά (spaces) σε ονόματα αρχείων. Δυσκολεύουν (κάνουν πιο πολύπλοκα) τα scripts που τα αναλύουν
  2. Μη χρησιμοποιείτε λέξεις που είναι ονόματα global συναρτήσεων της python για ονόματα μεταβλητών. Δηλαδή αποφεύγουμε:
sum=0
min=1

Δοκιμάστε και το εξής:

print (sum([1,2,3,]) # Prints 6
sum = 0
print (sum([1,2,3,]) # Petaei error! H sum sunarthsh xa8hke!!!
  1. Αυτά τα 2 είναι ισοδύναμα:
if a>b:
   return True
else:
   return False
return a>b

Το δεύτερο εννοείται είναι προτιμότερο.

  1. H python δεν απαιτεί παρενθέσεις σε if και return. Τα παρακάτω είναι ισοδύναμα:
if (a>b):
if a>b:

To ίδιο και στη return.

  1. To ξέρω ότι ακούγεται αυτιστικό, αλλά στη python ΔΕΝ χρησιμοποιούμε camel case, χρησιμοποιούμε snake case (και καλά python, snake κ'έτσ'). Δηλαδή προτιμάμε: optimal_solution από optimalSolution. Θυμηθείτε: readability counts!

  2. Όταν χρησιμοποιείτε boolean μεταβλητές (True/False) μην τις βάζετε τιμές 0 και 1 (μπορείτε, αλλά είναι άσχημο). Χρησιμοποιήστε True και False.

This is ugly:

found = 0
# Add amazing code here
if found == 1:
   print ("Found!")

This is pretty:

found = False
# Add amazing code here
if found:
   print ("Found!")
  1. Προσπαθήστε να χρησιμοποιείτε όσο το δυνατόν λιγότερο global μεταβλητές. Προσπαθήστε οι λύσεις σας να βρίσκονται σε self contained συναρτήσεις. Η python επιτρέπει σε μία συνάρτηση να προσπελαύνει μεταβλητές που έχουν οριστεί έξω από τη συνάρτηση. Στις υλοποιήσεις σας θα πρέπει να αποφεύγετε όσο μπορείτε αυτό. Κάθε μεταβλητή θα πρέπει να δημιουργείται σε μία συνάρτηση. Επίσης κάθε συνάρτηση δεν πρέπει να "εξαρτάται" από μεταβλητές που έχουν οριστεί έξω από αυτή. Ιδανικά αν κάποιος κάνει copy-paste τη συνάρτησή σας θα πρέπει να τρέχει. Μία καλή τακτική είναι να μην υπάρχει ΚΑΜΙΑ μεταβλητή που να μην έχει δηλωθεί σε κάποια συνάρτηση. Αυτό κάνει τον κώδικα πολύ πιο ευανάγνωστο!

Για παράδειγμα: Φτιάξτε μία συνάρτηση που παίρνει μία λίστα και επιστρέφει μία νέα λίστα που περιέχει μόνο τους άρτιους αριθμούς της πρώτης λίστας. Λάθος τρόπος:

new_list = []
def f(l)
   for i in l:
      if i % 2 == 0:
         new_list.append(i)

Σωστός τρόπος:

def f(l):
   new_list = []
   for i in l:
      if i % 2 == 0:
         new_list.append(i)
    return new_list

Ακόμα πιο σωστός τρόπος:

def f(l):
   return [i for i in l if i%2==0]
  1. Don't repeat yourself. Μαθαίνουμε προγραμματισμό για να κάνουμε τη ζωή μας πιο εύκολη και πιο ενδιαφέρουσα. Με τον προγραμματισμό βάζουμε τον υπολογιστή να κάνει τα βαρετά πράγματα για να επικεντρωθούμε εμείς στα ενδιαφέροντα. Αν βρείτε τον εαυτό σας να επαναλαμβάνει ή να κάνει copy/paste τις ίδιες γραμμές κώδικα, τότε κάτι έχετε κάνει λάθος.

Παράδειγμα: Βρείτε το άθροισμα όλων των αριθμών από το 1 μέχρι το 20.

RY (Repeat Yourself) λύση:

print (1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20)

DRY λύση:

print (sum(range(1,21))
  1. (Λίγο ψαγμένο αυτό). Πολλές φορές χρησιμοποιούμε μία boolean μεταβλητή για να δούμε αν ο αλγόριθμός μας έχει κάνει break από μία loop. π.χ, Έστω ότι ψάχνουμε να βρούμε αν μία λίστα έχει έναν άρτιο(ζυγό) αριθμό (δεν μας νοιάζει πόσους άρτιους έχει, αρκεί να έχει έναν)
found = False
for x in my_list:
   if x%2==0:
      found = True
      break
if not found:
   print ("Did not found even")

Μπορούμε να υλοποιήσουμε αυτό χωρίς τη found? Ναι, με την else!.

for x in my_list:
   if x%2 == 0:
      break
else:
   print ("Did not found even")

Διαβάστε περισσότερα εδώ

  1. Είναι εντυπωσιακό άλλα πάρα πολλές φορές βλέπω το εξής: Ζητάω να βρω το μεγαλύτερο (ή μικρότερο) σε μία λίστα και φτιάχνετε μία for η οποία ελέγχει όλα τα στοιχεία αν είναι ίσα με το μικρότερο. Αφού έχετε βρεί το μικρότερο γιατί δεν το.. τελειώνετε εκεί; Για παράδειγμα. Βρείτε το μικρότερο στοιχεία της λίστας a = [5,6,4,7]

Λάθος τρόπος:

m = min(a)
for x in a:
   if x == m:
      print (x)

Επίσης λάθος τρόπος:

for x in a:
   m = min(a)
   if x == m:
      print (x)

Σωστός τρόπος:

min(a)
  1. Προσπαθήστε οι υλοποιήσεις σας είναι σε μικρές και χαριτωμένες συναρτησούλες. Κάθε συναρτησούλα πρέπει να είναι (όσο το δυνατόν) αυτόνομη. Αποφύγεται τα "σεντόνια κώδικα".

  2. Προσπαθήστε ο κώδικάς σας να έχει όσο το δυνατόν λιγότερο identation. Ένας κώδικας που έχει if μέσα σε for μέσα σε μια άλλη if κτλ, δεν είναι ευανάγνωστος.

Παραδείγματα 1: Μία συνάρτηση που παίρνει ένα string του οποίου το μήκος πρέπει να διαιρείται με 3:

Λάθος:

def f(s):
   if len(s)%3==0:
      papades..
   else:
      raise Exception('The length of s is not divided exactly to 3')

Σωστό:

def f(s):
   if len(s)%3:
      raise Exception('The length of s is not divided exactly to 3')
   papades..

Προσέξτε και οι δύο κάνουν ακριβώς το ίδιο, αλλά η στη 2η η papades... είναι ένα identation πιο μέσα.

2ο Παράδειγμα. Παρσάρετε ένα αρχείο. Αν η γραμμή του αρχίζει από '#' τότε θεωρήστε ότι είναι σχόλιο και αγνοήστε τη.

Λάθος:

with open(file) as f:
   for line in f:
      if line[0] != '#':
         papades...

Σωστό:

with open(file) as f:
   for line in f:
      if line[0] == '#':
         continue
      papades...

Πάλι προσέξτε ότι η papades... είναι ένα identation πιο μέσα.

  1. Όταν λέμε υλοποιήστε κάτι με numpy δεν εννοούμε αντί να χρησιμοποιήσετε λίστες, να χρησιμοποιήσετε numpy arrays! Αλλά να χρησιμοποιήσετε τους μηχανισμούς της numpy που κάνουν γρήγορα υπολογισμούς. Ένας πολύ καλός τρόπος να το κάνετε αυτό είναι απλά, να μη χρησιμοποιήσετε for και while όταν δουλεύετε με numpy. Αν βάλετε for και while σε numpy ΔΕΝ εκμεταλευόσαστε τη τεράστια ταχύτητα που έχει.

  2. Προσπαθήστε οι επιλογές στα if, else κτλ να είναι όσο το δυνατόν πιο συγκεκριμμένες. Δεν πειράζει να βάλετε 2-3 γραμμές παραπάνω για να είστε σίγουροι ότι θα εκτελεστεί ο σωστός κώδικας. Για παράδειγμα, ας υποθέσουμε ότι το x μπορεί να πάρει μόνο 3 τιμές 1,2,3 και ανάλογα με τη τιμη του x, το πρόγραμμά μας κάτι κάνει.

Λάθος:

if x == 1:
   # actions for when x==1
elif x == 2:
   # actions for when x==2
else:
   # actions for when x==3

Το πρόβλημα με το παραπάνω είναι ότι αν για κάποιο λόγο το x πάρει τιμή διαφορετικό από το 1,2,3 (συμβαίνει πιο συχνά απ' ό,τι νομίζετε..) τότε το πρόγραμμά σας θα θεωρείσει ότι το x είναι 3.

Σωστό:

if x == 1:
   # actions for when x==1
elif x == 2:
   # actions for when x==2
elif x == 3
   # actions for when x==3
else:
   raise Exception('Invalid x value')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment