﻿<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>GreekTuts &#187; krap</title> <atom:link href="http://greektuts.net/author/akritikos/feed/" rel="self" type="application/rss+xml" /><link>http://greektuts.net</link> <description>Ελληνικά Βοηθήματα</description> <lastBuildDate>Mon, 30 Jan 2012 13:52:21 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Μαθαίνοντας Python – Μέρος 7ο (γ)</title><link>http://greektuts.net/python-part7c/</link> <comments>http://greektuts.net/python-part7c/#comments</comments> <pubDate>Thu, 17 Mar 2011 07:51:40 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[part 7]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[μέρος 7γ]]></category> <category><![CDATA[μέρος 7ο]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4800</guid> <description><![CDATA[Συνεχίζοντας το 7ο μέρος του οδηγού μας είμαστε έτοιμοι να δούμε ακόμη μια θεμελιώδη δομή δεδομένων, την ουρά. Για όσους έφθασαν στο άρθρο κατά τύχη, ακολουθεί μικρή περίληψη του αντικειμένου του 7ου μέρους του οδηγού καθώς και μικρή αναφορά στην δομή του άρθρου.]]></description> <content:encoded><![CDATA[<p>Εν γένει, στην συγκεκριμένη κατηγορία εμπίπτουν διάφορα θέματα τα σημαντικότερα από τα οποία συνοψίζονται στα εξής:</p><ul><li>Λίστες      (Lists)</li><li>Πλειάδες      και ακολουθίες (Tuples      &amp; Sequences)</li><li>Σετ (Sets)</li><li>Λεξικά      (Dictionaries)</li></ul><p>Και κάποια εξεζητημένα ζητήματα όπως:</p><ul><li>Τεχνικές      επανάληψης (Looping      Techniques)</li><li>Συνθήκες      επιλογής (Conditions)      – προχωρημένα θέματα –</li></ul><p><strong>Προαπαιτούμενα</strong></p><p><a
href="../../../../../category/programming/python/">Μαθαίνοντας Python</a></p><p><strong>Πριν ξεκινήσουμε…</strong></p><p>… θα ήθελα να επισημάνω ένα – δύο πρακτικά ζητήματα.</p><p>Στη συνέχεια παρουσιάζεται ο τρόπος για να επιτευχθούν οι στόχοι που περιγράψαμε στην εισαγωγή. Θα παρατηρήσετε ότι το άρθρο ακολουθεί τη δομή:</p><div><blockquote><p><em>Μικρή περιγραφή του τι θέλουμε να επιτύχουμε (+ επιπλέον σχόλια)</em></p></blockquote><pre name="code" class="py">
Παράδειγμα κώδικα
</pre></div><p>Για να τα χρησιμοποιήσετε, αντιγράφετε το εκάστοτε παράδειγμα σε ένα νέο αρχείο python και το εκτελείτε (βλ. <a
title="Permanent Link to Μαθαίνοντας Python – Μέρος 1ο" href="../../../../../archives/1571">Μαθαίνοντας Python – Μέρος 1ο</a> ). Τα παραδείγματα είναι φτιαγμένα με τέτοιον τρόπο ώστε να τυπώνουν τα αποτελέσματα στην οθόνη ώστε να μπορείτε να πιστοποιήσετε εύκολα τη λειτουργικότητά τους. Για διευκόλυνσή σας έχουμε χωρίσει τα παραδείγματα με σχόλια που δίνουν μια μικρή περιγραφή του τι επιχειρούμε κάθε φορά.</p><p>Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><h1><strong>( ΒΛΕΠΟΝΤΑΣ ΤΙΣ ΛΙΣΤΕΣ ΜΕ «ΑΛΛΟ ΜΑΤΙ» )</strong></h1><p><strong><em> </em></strong></p><p>Στο σημερινό άρθρο θα μας απασχολήσουν πιο προχωρημένα θέματα που έχουν να κάνουν με λίστες.</p><p><span
style="text-decoration: underline;">Χρησιμοποιώντας τις λίστες σαν ουρές</span></p><p>Αδυνατώ να φανταστώ κάποιον αναγνώστη που να μην είναι εξοικειωμένος με την έννοια της ουράς. Αν συμφωνήσουμε ότι αφήνουμε απ’ έξω την έννοια της ουράς ως λειτουργικό τμήμα του σώματος ενός ζώου, μας μένει το στερεότυπο μιας σειράς ανθρώπων που, ο ένας πίσω από τον άλλον περιμένουν κάτι. Να  πάρουν λεφτά από κάποιο μηχάνημα αυτόματης ανάληψης, να εξυπηρετηθούν σε κάποια δημόσια υπηρεσία (!), να πληρώσουν στο ταμείο κάποιου καταστήματος, να πάρουν φαγητό.</p><p>Μια ουρά δηλαδή, είναι ένα σύνολο αντικειμένων στοιχισμένα το ένα πίσω από το άλλο. Κάθε νέο αντικείμενο που προστίθεται στην ουρά καταλαμβάνει την τελευταία θέση (μπαίνει πίσω από κάθε άλλο προϋπάρχον στοιχείο). Επίσης, όταν πάρουμε ένα αντικείμενο από την ουρά, θα  είναι το στοιχείο που βρίσκεται στην πρώτη θέση. Η παραπάνω σκέψη μας οδηγεί στο συμπέρασμα ότι μια ουρά λειτουργεί με τη λογική «το πρώτο στοιχείο που εισάγουμε, είναι το πρώτο που εξάγουμε». Στη βιβλιογραφία αυτή η διαπίστωση και, κατ’ επέκταση η φύση λειτουργίας της ουράς, ως δομή δεδομένων, αναφέρεται ως &#8220;FIRST IN, FIRST OUT&#8221; ή, εν συντομία, “FIFO”.</p><p>Πως το υλοποιούμε σε Python όμως;</p><p>Σε αντίθεση με την δομή δεδομένων της στοίβας, με την οποία ασχοληθήκαμε στο προηγούμενο άρθρο μας, η Python περιλαμβάνει κάποιες εντολές που βολεύουν ιδιαίτερα για την υλοποίηση της ουράς. Ας τις δούμε αναλυτικά:</p><pre name="code" class="py">
&gt;&gt;&gt; from collections import deque
</pre><p>Εδώ χρειάζεται  μια μικρή προσοχή μιας και την παραπάνω εντολή την συναντούμε για πρώτη φορά στον οδηγό μας. Ο αναγνώστης που έχει εμπειρία στον προγραμματισμό αναγνωρίζει απευθείας ότι η παραπάνω εντολή «φορτώνει» μία βιβλιοθήκη, κάνει δηλαδή δυνατή τη χρήση μιας βιβλιοθήκης από το πρόγραμμά μας.</p><blockquote><p><span
style="text-decoration: underline;">TIP</span>: Ο όρος “collections” συναντάται σε πολλές γλώσσες προγραμματισμού. Συνήθως αποτελεί μια συλλογή από δομές δεδομένων υλοποιημένες για την εκάστοτε γλώσσα.</p></blockquote><p>Τώρα που γνωρίζουμε τα παραπάνω μπορούμε εύκολα να αντιληφθούμε ότι η εντολή που μόλις πληκτρολογήσαμε «φορτώνει» από την βιβλιοθήκη «collections» τη δομή «deque» – η οποία αποτελεί προφανώς υλοποίηση της ουράς –.</p><p>Ο λόγος που αυτή τη φορά δεν χρησιμοποιούμε εντολές της Python για να «κατασκευάσουμε» τη δική μας ουρά αλλά χρησιμοποιούμε κάτι έτοιμο είναι ο εξής. Το να κάνουμε προσθήκες και ανακτήσεις στο τέλος μιας λίστας (δείτε <em>Μαθαίνοντας </em><em>Python – Μέρος 7<sup>ο</sup> (β)</em>) είναι γενικά μια διαδικασία που δεν κοστίζει πολύ από άποψη πόρων. Δυστυχώς όμως, η δομή της ουράς εμπλέκει το  τέλος της λίστας. Οι διαδικασίες της προσθήκης και ανάκτησης στο τέλος της λίστας είναι πράξεις που κοστίζουν στη γλώσσα Python.</p><p>Ας δούμε τώρα τι δυνατότητες διαχείρισης μας προσφέρονται.</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue = deque(["The tale of Sir Robin", "The tale of Sir Lancelot", "The tale of Sir Bedevir"])
</pre><p>Με την εντολή deque(LIST) δημιουργούμε μια ουρά. Παρατηρήστε ότι το όρισμα που δέχεται η deque είναι μια λίστα (η οποία μπορεί να περιέχει όλα όσα έχουμε δει ότι μπορεί να περιέχει μια λίστα σε προηγούμενα άρθρα μας).</p><p>Η συγκεκριμένη εντολή δημιουργεί μία ουρά με αντικείμενα, τα αντικείμενα της λίστας που έχουμε δώσει σαν όρισμα (στην συγκεκριμένη περίπτωση LIST).</p><p>Οι διαδικασίες εισαγωγής και ανάκτησης γίνονται με τον ίδιο τρόπο που συναντήσαμε όταν μελετούσαμε τη δομή στοίβας (stuck). Αναλυτικότερα:</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue.append("The tail of Sir Arthur")
</pre><p>Με την εντολή αυτή ένα νέο στοιχείο εισέρχεται στην ουρά (δηλαδή καταλαμβάνει την τελευταία θέση).</p><p>Όσων αφορά την υλοποίηση της ανάκτησης, θα χρησιμοποιήσουμε μια παραλλαγή της γνωστής μας, από την υλοποίηση της στοίβας, pop().</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue.popleft()
</pre><p>Εκτελώντας την παραπάνω εντολή, η κονσόλα μας επιστρέφει:</p><p>&#8220;The tale of Sir Robin&#8221;</p><p>… που είναι το πρώτο στοιχείο που εισήχθηκε στη λίστα. Επαληθεύουμε με:</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue
</pre><p>και παίρνουμε:</p><p>["The tale of Sir Lancelot", "The tale of Sir Bedevir"]</p><p>Εκτελώντας ξανά</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue.popleft()
</pre><p>(σωστά μαντεύετε)</p><p>&#8220;The tale of Sir Lancelot&#8221;</p><p>και έτσι η ουρά μας έχει πλέον τη μορφή:</p><pre name="code" class="py">
&gt;&gt;&gt; myQueue
["The tale of Sir Bedevir"]
</pre><p>Η ουρά, όπως και η στοίβα αποτελούν μια από τις βασικότερες δομές δεδομένων στον τομέα της Πληροφορικής. Πολλοί προγραμματιστές βρίσκουν της δομές αυτές πλέον ξεπερασμένες. Η αλήθεια είναι ότι στις σύγχρονες σουίτες προγραμματισμού, δομές όπως η στοίβα ή η ουρά προσφέρονται μέσω κάποιων βιβλιοθηκών.</p><p>Το ίδιο ακριβώς συναντήσαμε στο σημερινό μας άρθρο. Η δομή της ουράς, για την Python, υπάρχει υλοποιημένη σε μία κλάση που  ονομάζεται deque και εμπεριέχεται μέσα στην βιβλιοθήκη collections. Αυτή η υλοποίηση, επιτρέπει στον προγραμματιστή, να μπορεί να χρησιμοποιεί τη δομή της ουράς, αφενός χωρίς να χρειάζεται να μπει στον κόπο να την υλοποιήσει από το μηδέν και αφετέρου, του δίνει τη διαπίστευση ότι η υλοποίηση της εν λόγω δομής, έχει γίνει με τέτοιο τρόπο ώστε να επιτυγχάνει την μέγιστη λειτουργικότητα και αποτελεσματικότητα.</p><p>Μένουν ελάχιστα ακόμη πράγματα που πρέπει να εξετάσουμε όσον αφορά τα προχωρημένα θέματα που αφορούν τη χρήση λιστών στην Python. Θα τα δούμε στο επόμενο άρθρο μας.</p><p>Μέχρι τότε, να μην ξεχνάτε…</p><p><em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em>.</p> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part7c/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Μαθαίνοντας Python – Μέρος 7ο (β2)</title><link>http://greektuts.net/python-part7b2/</link> <comments>http://greektuts.net/python-part7b2/#comments</comments> <pubDate>Fri, 25 Feb 2011 09:20:45 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[part 7]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[μέρος 7β]]></category> <category><![CDATA[μέρος 7ο]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4723</guid> <description><![CDATA[Στο έβδομο μέρος του οδηγού θα ασχοληθούμε με δομές δεδομένων. Η αλήθεια είναι ότι κάποια από τα πράγματα τα οποία θα μας απασχολήσουν τα έχουμε ήδη δει εξ απαλών ονύχων σε περασμένα άρθρα. Τώρα ήρθε η ώρα να εμβαθύνουμε και να εμπλουτίσουμε με νέα στοιχεία και λειτουργικότητες. ]]></description> <content:encoded><![CDATA[<p>Εν γένει, στην συγκεκριμένη κατηγορία εμπίπτουν διάφορα θέματα τα σημαντικότερα από τα οποία συνοψίζονται στα εξής:</p><ul><li>Λίστες      (Lists)</li><li>Πλειάδες      και ακολουθίες (Tuples      &amp; Sequences)</li><li>Σετ (Sets)</li><li>Λεξικά      (Dictionaries)</li></ul><p>Και κάποια εξεζητημένα ζητήματα όπως:</p><ul><li>Τεχνικές      επανάληψης (Looping      Techniques)</li><li>Συνθήκες      επιλογής (Conditions)      – προχωρημένα θέματα –</li></ul><p>Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><p><strong>( ΒΛΕΠΟΝΤΑΣ ΤΙΣ ΛΙΣΤΕΣ ΜΕ ΑΛΛΟ ΜΑΤΙ )</strong></p><p><strong><em> </em></strong></p><p>Στο σημερινό άρθρο θα μας απασχολήσουν πιο προχωρημένα θέματα που έχουν να κάνουν με λίστες.</p><p>Χρησιμοποιώντας τις λίστες σαν στοίβες</p><p>Η έννοια της στοίβας είναι βασική όσων αφορά το αντικείμενο των δομών δεδομένων και αποτελεί συνήθως το εισαγωγικό μάθημα στο εν λόγω αντικείμενο σε μια σχολή Πληροφορικής.  Η στοίβα, ως δομή δεδομένων, δε διαφέρει ιδιαίτερα από την κοινή στοίβα που συναντούμε στην καθημερινή μας ζωή (μια στοίβα βιβλία, μια στοίβα CD ή DVD,  η στοίβα με τα άπλυτα, κλπ.).</p><p>Ας συμφωνήσουμε ότι μια στοίβα είναι ένα σύνολο αντικειμένων το ένα πάνω στο άλλο. Κάθε νέο αντικείμενο που προστίθεται στην στοίβα καταλαμβάνει την ανώτερη θέση. Επίσης όταν πάρουμε ένα αντικείμενο από τη στοίβα, μοιραία θα  είναι το στοιχείο που βρίσκεται στην ανώτερη θέση. Η παραπάνω σκέψη μας οδηγεί στο συμπέρασμα ότι μια στοίβα λειτουργεί με τη λογική «το τελευταίο στοιχείο που εισάγουμε, είναι το πρώτο που εξάγουμε». Στη βιβλιογραφία αυτή η διαπίστωση και, κατ’ επέκταση η φύση λειτουργίας της στοίβας ως δομή δεδομένων, αναφέρεται ως &#8220;LAST IN, FIRST OUT&#8221; ή, εν συντομία, “LIFO”.</p><p>Μετά τη σύντομη εισαγωγή στη σχετική με τις στοίβες θεωρία, ας περάσουμε σε πιο διασκεδαστικά αντικείμενα όπως, πως το υλοποιούμε σε Python.</p><p>Εάν είστε σαν και εμένα, σε αυτό το σημείο θα πρέπει να περιμένετε να δείτε ποιες είναι οι ειδικές εντολές τις Python που υλοποιούν τη λειτουργικότητα μιας στοίβας. Η πικρή αλήθεια είναι πως δεν υπάρχουν ειδικές εντολές. Η λειτουργικότητα της στοίβας υλοποιείται με τη χρήση εντολών Python που ήδη έχουμε μάθει.</p><p>Ας υποθέσουμε ότι έχουμε την παρακάτω λίστα στοιχείων (<span
style="text-decoration: underline;">πληκτρολογούμε τον κώδικα απευθείας στην κονσόλα</span>).</p><pre name="code" class="py">
&gt;&gt;&gt; myStack = [‘Monty Python and the holy grail’, ‘The life of Brian’, ‘The meaning of life’]
</pre><p>Σε αυτό το σημείο θα ήθελα να επικαλεστώ την φαντασία σας. Σκεφτείτε το παραπάνω σετ στοιχείων ως στοίβα… οπτικά θα έμοιαζε κάπως έτσι:</p><p>‘The meaning of life’<br
/> ‘The life of Brian’<br
/> ‘Monty Python and the holy grail’</p><p>Σωστά;</p><p>Ας υλοποιήσουμε τώρα την εισαγωγή ενός καινούριου στοιχείου στη στοίβα. Σύμφωνα με τη θεωρία κάθε νέο στοιχείο που εισέρχεται στη στοίβα καταλαμβάνει την ανώτερη θέση. Θέλουμε δηλαδή το νέο στοιχείο που θα προστεθεί στην παραπάνω στοίβα που δημιουργήσαμε, να τοποθετηθεί πάνω από το ‘The meaning of life’. Θυμάστε την append(); Αν όχι, ανατρέξτε σε προηγούμενα άρθρα του οδηγού και θυμηθείτε την γιατί είναι η λύση στο πρόβλημά μας <img
src='http://greektuts.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><pre name="code" class="py">
&gt;&gt;&gt; myStack.append(‘And now for something completely different’)
</pre><p>η στοίβα μας έχει τώρα  την ακόλουθη μορφή:</p><p>‘And now for something completely different’<br
/> ‘The meaning of life’<br
/> ‘The life of Brian’<br
/> ‘Monty Python and the holy grail’</p><p>Φυσικά η Python δεν μπορεί να απεικονίσει την στοίβα με τον παραπάνω τρόπο. Για την Python μια στοίβα θα είναι πάντοτε μια λίστα. Επομένως αν δώσουμε στην κονσόλα…</p><pre name="code" class="py">
&gt;&gt;&gt; myStack
</pre><p>…θα δούμε</p><p>[‘Monty Python and the holy grail’, ‘The life of Brian’, ‘The meaning of life’, ‘And now for something completely different’]</p><p>(σε μία γραμμή – γιατί πρέπει να χρησιμοποιώ πάντα τόσο μεγάλα παραδείγματα; <img
src='http://greektuts.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> – )</p><p>Ομοίως:</p><pre name="code" class="py">
&gt;&gt;&gt; myStack.append(‘Brazil’)
</pre><p>και η στοίβα μας έχει πάρει τη μορφή:</p><p>‘Brazil’<br
/> ‘And now for something completely different’<br
/> ‘The meaning of life’<br
/> ‘The life of Brian’<br
/> ‘Monty Python and the holy grail’</p><p>ή</p><p>[‘Monty Python and the holy grail’, ‘The life of Brian’, ‘The meaning of life’, ‘And now for something completely different’, ‘Brazil’]</p><p>Τώρα ήρθε η ώρα να υλοποιήσουμε το δεύτερο κομμάτι λειτουργικότητας που αποτελεί την ανάκτηση των στοιχείων της λίστας. Όπως είπαμε, «πρώτο στοιχείο» σε μια στοίβα θεωρείται το στοιχείο που βρίσκεται στην κορυφή σωστά μαντεύετε, στην συγκεκριμένη περίπτωση είναι το ‘Brazil’). Πως το υλοποιούμε όμως σε Python;</p><p>Θα χρησιμοποιήσουμε μία ακόμη γνωστή μας εντολή:</p><pre name="code" class="py">
&gt;&gt;&gt; myStack.pop()
</pre><p>…η κονσόλα μας επιστρέφει:</p><p>‘Brazil’</p><p>Ο κύβος ερρίφθη <img
src='http://greektuts.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Ας σιγουρευτούμε ότι όλα πήγαν κατ’ ευχήν βλέποντας την τρέχουσα κατάσταση στην οποία έχει περιέλθει η λίστα μας:</p><pre name="code" class="py">
&gt;&gt;&gt; myStack
</pre><p>[‘Monty Python and the holy grail’, ‘The life of Brian’, ‘The meaning of life’, ‘And now for something completely different’]</p><p>Ομοίως…</p><pre name="code" class="py">
&gt;&gt;&gt; myStack.pop()
</pre><p>…και η κονσόλα μας επιστρέφει:</p><p>‘And now for something completely different’</p><pre name="code" class="py">
&gt;&gt;&gt; myStack
</pre><p>[‘Monty Python and the holy grail’, ‘The life of Brian’, ‘The meaning of life’]</p><p>Πολλοί από εσάς θα παρατήρησαν ότι στο  σημερινό άρθρο δεν δουλέψαμε πάνω σε κάποιο Python script, όπως συνήθως. Αντίθετα χρησιμοποιήσαμε εντολές απ’ ευθείας στην κονσόλα. Αυτό συμβαίνει διότι σήμερα δεν μάθαμε κάτι καινούριο. Χρησιμοποιήσαμε προϋπάρχουσα γνώση για να μπορέσουμε να υλοποιήσουμε μία από τις πιο θεμελιώδεις δομές δεδομένων στην θεωρία της Πληροφορικής. Τη στοίβα.</p><p>Αν το συγκεκριμένο άρθρο σας φάνηκε άχρηστο, ξανασκεφθείτε το. Στο σημερινό άρθρο παρουσιάσαμε κάτι πολύ σημαντικό. Καμία γνώση δεν αποκτάται για να χρησιμοποιείται ακριβώς όπως τη γνωρίζουμε. Η αγορά εργασίας απαιτεί από τον προγραμματιστή να είναι εφευρετικός. Το να μπορεί κανείς να βρει εναλλακτικούς τρόπους χρήσης παλαιάς γνώσης… είναι αν μη τι άλλο εφευρετικότητα. Μείνετε συντονισμένοι γιατί στο επόμενο άρθρο θα υλοποιήσουμε μια ακόμη σημαντική δομή δεδομένων. Την ουρά.</p><p>Μέχρι τότε, να μην ξεχνάτε…</p><p><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span>.</p> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part7b2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Μαθαίνοντας Python – Μέρος 7ο (β)</title><link>http://greektuts.net/python-part7b/</link> <comments>http://greektuts.net/python-part7b/#comments</comments> <pubDate>Thu, 02 Dec 2010 07:37:52 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[part 7]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[μέρος 7β]]></category> <category><![CDATA[μέρος 7ο]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4493</guid> <description><![CDATA[Στο δεύετερο κομμάτι του έβδομου μέρος του οδηγού θα ασχοληθούμε με δομές δεδομένων. Η αλήθεια είναι ότι κάποια από τα πράγματα τα οποία θα μας απασχολήσουν τα έχουμε ήδη δει εξ απαλών ονύχων σε περασμένα άρθρα. Τώρα ήρθε η ώρα να εμβαθύνουμε και να εμπλουτίσουμε με νεά στοιχεία και λειτουργικότητες.]]></description> <content:encoded><![CDATA[<p>Εν γένει, στην συγκεκριμένη κατηγορία εμπίπτουν διάφορα θέματα τα σημαντικότερα από τα οποία συνοψίζονται στα εξής:</p><ul><li>Λίστες      (Lists)</li><li>Πλειάδες      και ακολουθίες (Tuples      &amp; Sequences)</li><li>Σετ (Sets)</li><li>Λεξικά      (Dictionaries)</li></ul><p>Και κάποια εξεζητημένα ζητήματα όπως:</p><ul><li>Τεχνικές      επανάληψης (Looping      Techniques)</li><li>Συνθήκες      επιλογής (Conditions)      – προχωρημένα θέματα –</li></ul><p><strong>Προαπαιτούμενα</strong></p><p><a
href="http://greektuts.net/category/programming/python/">Μαθαίνοντας Python</a></p><p><strong>Πριν ξεκινήσουμε…</strong><br
/> … θα ήθελα να επισημάνω ένα – δύο πρακτικά ζητήματα.</p><p>Στη συνέχεια παρουσιάζεται ο τρόπος για να επιτευχθούν οι στόχοι που περιγράψαμε στην εισαγωγή. Θα παρατηρήσετε ότι το άρθρο ακολουθεί τη δομή:</p><blockquote><p>Μικρή περιγραφή του τι θέλουμε να επιτύχουμε (+ επιπλέον σχόλια)</p></blockquote><pre name="code" class="py">
Παράδειγμα κώδικα</em>
</pre><p>Στο τέλος του αρχείου θα βρείτε συνημμένο ένα python script που περιέχει συγκεντρωμένα όλα τα παραδείγματα.</p><p>Για να τα χρησιμοποιήσετε, αντιγράφετε το εκάστοτε παράδειγμα σε ένα νέο αρχείο python και το εκτελείτε (βλ. <a
title="Permanent Link to Μαθαίνοντας Python – Μέρος 1ο" href="http://greektuts.net/python-part-1/">Μαθαίνοντας Python – Μέρος 1ο</a> ). Τα παραδείγματα είναι φτιαγμένα με τέτοιον τρόπο ώστε να τυπώνουν τα αποτελέσματα στην οθόνη ώστε να μπορείτε να πιστοποιήσετε εύκολα τη λειτουργικότητά τους. Για διευκόλυνσή σας έχουμε χωρίσει τα παραδείγματα με σχόλια που δίνουν μια μικρή περιγραφή του τι επιχειρούμε κάθε φορά.</p><p>Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><p><strong>( ΦΡΕΣΚΑΡΟΝΤΑΣ ΤΑ ΒΑΣΙΚΑ… )</strong></p><p>Στο σημερινό άρθρο θα μας απασχολήσουν και πάλι θέματα που έχουν να κάνουν με λίστες. Ας θυμηθούμε τα βασικά:</p><p><span
style="text-decoration: underline;">Ορισμός Λίστας</span></p><pre name="code" class="py">
myList = ['monty', 'python', 999, 222]
</pre><p><span
style="text-decoration: underline;">Επιλογή Στοιχείου Λίστας</span></p><pre name="code" class="py">
myList[0]
myList[-1]
</pre><p><span
style="text-decoration: underline;">Εισαγωγή Στοιχείου σε Λίστα</span></p><pre name="code" class="py">
myList[3] = 'foo'
</pre><p><span
style="text-decoration: underline;">Διαγραφή Στοιχείου από Λίστα</span></p><pre name="code" class="py">
myList[2] = []
</pre><p><span
style="text-decoration: underline;">Καθαρισμός Λίστας</span></p><pre name="code" class="py">
myList[:] = []
</pre><p><span
style="text-decoration: underline;">Μέγεθος Λίστας</span></p><pre name="code" class="py">
Len(myList)
</pre><p>Αφού θυμηθήκαμε τα βασικά, μπορούμε να προχωρήσουμε σε μια σειρά από προχωρημένες λειτουργίες που αφορούν λίστες.</p><p><span
style="text-decoration: underline;">Προσθήκη στοιχείου στο τέλος της λίστας</span></p><pre name="code" class="py">
myList.append("Team")
</pre><p>εδώ προστίθεται το στοιχείο Team στην τελευταία θέση</p><p><span
style="text-decoration: underline;">Επέκταση μιας λίστας με τα στοιχεία μιας άλλης</span></p><pre name="code" class="py">
anotherList = ['foo', 'foo2']
myList.extend( anotherList )
</pre><p>Η λίστα myList επεκτείνεται με τα στοιχεία της λίστας anotherList τα οποία και τοποθετούνται στο τέλος της myList</p><p><span
style="text-decoration: underline;">Εισαγωγή στοιχείου σε συγκεκριμένη θέση της λίστας</span></p><pre name="code" class="py">
myList.insert(0, 'inserted')
</pre><p>Εδώ το στοιχέιο &#8216;inserted&#8217; θα εισαχθεί στη θέση 0 (δηλαδή την πρώτη)</p><p><span
style="text-decoration: underline;">Αφαίρεση στοιχείου με συγκεκριμένη τιμή</span></p><pre name="code" class="py">
myList.remove('inserted')
</pre><p>Εδώ θα αφαιρεθεί το στοιχείο με τιμή &#8216;inserted&#8217;</p><p><span
style="text-decoration: underline;">Ανάγνωση του τελευταίου στοιχείου της λίστας</span></p><pre name="code" class="py">
print(myList.pop())
</pre><p>Εδώ θα επιστραφεί το τελευταίο στοιχείο της λίστας και θα διαγραφεί ταυτόχρονα από αυτή</p><p><span
style="text-decoration: underline;">Ανάγνωση του στοιχείου στη θέση </span><span
style="text-decoration: underline;">X</span></p><pre name="code" class="py">
print(myList.pop(0))
</pre><p>Εδώ θα επιστρέφει το στοιχείο στη θέση 0 και θα διαγραφεί από αυτήν</p><p><span
style="text-decoration: underline;">Εύρεση της θέσης στοιχείου με τιμή ‘τιμή’</span></p><pre name="code" class="py">
print(myList.index('Monty'))
</pre><p>Εδώ θα επιστραφεί η θέση του στοιχείου με τιμή &#8216;Monty&#8217;</p><p><span
style="text-decoration: underline;">Ταξινόμηση λίστας</span><br
/> <span
style="text-decoration: underline;">numList = [1, 15, 25, 2, 8, 19, 1012, 3]</span></p><pre name="code" class="py">
numList.sort()
</pre><p>Εδώ ταξινομούνται τα στοιχεία της λίστας σε αύξουσα σειρά</p><p><span
style="text-decoration: underline;">Αντιστροφή λίστας σε επίπεδο στοιχείων</span></p><pre name="code" class="py">
numList.reverse()
</pre><p>Εδώ η λίστα θα αντιστραφεί (αν η λίστα δεν είναι ταξινομημένη εξ’ αρχής, η λίστα που θα προκύψει θα είναι απλά η ανάστροφη της αρχικής).</p><p>Για την καλύτερη κατανόηση των παραπάνω ειδικών λειτουργιών με λίστες σας συμβουλεύουμε να ανατρέξετε στο παράδειγμα κώδικα που θα βρείτε στο τέλος του άρθρου.</p><p>Σε αυτό το άρθρο ξεκινούμε να γνωρίζουμε πιο προχωρημένα θέματα της γλώσσας Python. Μείνετε μαζί μας και θα ανακαλύψετε πολύ σύντομα ότι τη δύναμη της συγκεκριμένης γλώσσας προγραμματισμού είναι μεγαλύτερη από όσο φανταζόσασταν.</p><p>Μέχρι την επόμενη φορά ωστόσο, να μην ξεχνάτε…<br
/> <em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em></p><blockquote><p
style="text-align: center;"><em><strong>Μπορείτε να κατεβάσετε τα αρχεία του βοηθήματος εδώ</strong></em></p><p
style="text-align: center;"><em><strong><a
href="http://static.greektuts.net/uploads3/2010/12/py_tuts_part_7b.zip" ><img
src="../wp-content/uploads/2009/10/membersdownload1.png" alt="download" width="200" height="200" /></a></strong></em></p></blockquote> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part7b/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Μαθαίνοντας Python – Παράγοντας Ποιοτικό Κώδικα (α)</title><link>http://greektuts.net/python-part7/</link> <comments>http://greektuts.net/python-part7/#comments</comments> <pubDate>Wed, 17 Nov 2010 07:31:07 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[part7]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[Μέρος 7]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4469</guid> <description><![CDATA[Έχοντας αρχίσει να γράφουμε μεγάλα τμήματα κώδικα σε Python είναι απαραίτητο να μάθουμε να παράγουμε ποιοτικό κώδικα. Για τον λόγο αυτό, αποφασίσαμε να κάνουμε ένα διάλειμμα από τα τεχνικά χαρακτηριστικά και να δούμε κάποια πολύ βασικά πράγματα που πρέπει να προσέχει ένας Python προγραμματιστής.]]></description> <content:encoded><![CDATA[<h1><strong>Τι είναι «ποιοτικός κώδικας»;</strong></h1><p>Όταν μιλούμε για ποιοτικό κώδικα εννοούμε, στην γενική περίπτωση, κώδικα ο οποίος κάνει σωστά και αποτελεσματικά αυτό για το οποίο προορίζεται, ενώ παράλληλα είναι ευανάγνωστος, καλογραμμένος και σωστά τεκμηριωμένος.</p><p>Στα πλαίσια του οδηγού που εκκινεί το συγκεκριμένο άρθρο θα μας απασχολήσει το κομμάτι που αφορά κυρίως το πόσο καλογραμμένος, ευανάγνωστο και καλά τεκμηριωμένος είναι ο κώδικάς μας. Με γνώμονα αυτό θα δώσουμε κάποια προγραμματιστικά τρικ που βοηθούν στο να επιτευχθούν οι παραπάνω στόχοι.</p><h1><strong>Προαπαιτούμενα;</strong></h1><p><strong> </strong></p><p>Η καλή συγγραφή κώδικα είναι κάτι το οποίο αφορά όλες τις γλώσσες προγραμματισμού. Αυτό σημαίνει ότι πολλά από τα τρικ που θα παρουσιάσουμε εδώ αποτελούν καλές πρακτικές είτε προγραμματίζουμε σε Python, είτε σε οποιαδήποτε άλλη γλώσσα.</p><p>Ωστόσο, επειδή ορισμένες συμβουλές αφορούν σε συγκεκριμένα χαρακτηριστικά της γλώσσας Python, είναι καλό να γνωρίζει κανείς τα βασικά. Συνοψίζοντας, η πληροφορία που θα παρουσιαστεί στον εν λόγω οδηγό είναι γενικής φύσης και αφορά όλους όσους σκέπτονται να ασχοληθούν ή ήδη ασχολούνται με τον προγραμματισμό, ωστόσο προτείνεται να έχετε δει (έστω και εν τάχει) όλα τα άρθρα της σειράς «Μαθαίνοντας την Python» για να επιτύχετε το μέγιστο δυνατό κέρδος.</p><h1><strong>ΟΚ με έπεισες… Ποιος υπογράφει τα τρικ;</strong></h1><p><strong> </strong></p><p>Προσπαθώντας να μεταφέρουμε κόλπα και τεχνικές από επαγγελματίες που γνωρίζουν το αντικείμενο στο μεγαλύτερο δυνατό βαθμό αποφασίσαμε να ακολουθήσουμε τον <a
href="http://www.python.org/dev/peps/pep-0008/">οδηγό συγγραφής κώδικα Python</a> που φιλοξενείται online στην επίσημη ιστοσελίδα της Python.</p><p>Το link που δώσαμε εξυπηρετεί στο να μπορέσει να διαβάσει, όποιος ενδιαφέρεται, το πλήρες αγγλικό κείμενο του οδηγού. Εμείς θα κάνουμε ένα φιλτράρισμα της πληροφορίας περιλαμβάνοντας μόνον έννοιες που έχουμε καλύψει ως τώρα, ακολουθώντας το ύφος και την οργάνωση του προαναφερθέντα οδηγού.</p><p>Εφόσον είστε έτοιμοι να ανακαλύψετε τις καλές πρακτικές συγγραφής Python κώδικα, βεβαιωθείτε ότι το μάτι της κουζίνας είναι κλειστό, ετοιμάστε μια κούπα καφέ ή τσάι… και ξεκινάμε.</p><h1><strong>Ζήτημα 1<sup>ο</sup> – Πότε πρέπει να ακολουθώ τους κανόνες συγγραφής και πότε όχι;</strong></h1><p><strong> </strong></p><p>Εν γένει είναι καλό να ακολουθούνται πάντοτε οι κανόνες συγγραφείς. Ωστόσο αν αυτό τύγχανε καθολικής αποδοχής τότε δεν θα είχε ποτέ δημιουργηθεί η φράση «οι κανόνες υπάρχουν για να παραβιάζονται». Όσο ριζοσπαστικό και αν ακούγεται αυτό σαν φράση εμπεριέχει μια μεγάλη αλήθεια. Οι κανόνες, τουλάχιστον σε ότι αφορά τον προγραμματισμό, έχουν δημιουργηθεί ώστε να λύνουν δύο μεγάλα προβλήματα:</p><ul><li>Να      παρέχουν μια κοινή γραμμή σε όλους τους προγραμματιστές μιας ομάδας (είτε      πρόκειται για παρέα, είτε για εταιρικό σχήμα, είτε για ομάδα φοιτητών)</li><li>Να      προλαμβάνουν κοινά προγραμματιστικά λάθη (ναι, η μη συμμόρφωση με τους      κανόνες μπορεί να καταλήξει σε προγραμματιστικά λάθη)</li></ul><p>Ένας πιο σημαντικός όμως λόγος, για να ακολουθήσει κάποιος του κανόνες συγγραφής κώδικα, είναι η πειθαρχία στην παραγωγή καλογραμμένου και άρα εν μέρει, ποιοτικού κώδικα.</p><p>Είπαμε τους λόγου για τους οποίους είναι καλό αν  ακολουθούμε τους κανόνες. Ας δούμε τώρα πότε επιτρέπεται, αν όχι επιβάλλεται, να τους σπάμε (είμαι σίγουρος ότι οι περισσότεροι πρόκειται να το διαβάσετε αυτό).</p><ol><li><em>Όταν το να εφαρμόσουμε τον κανόνα κάνει      το αποτέλεσμα λιγότερο ευανάγνωστο, ακόμη και για κάποιον που έχει      συνηθίσει να γράφει κώδικα ακολουθώντας τους κανόνες.</em></li><li><em>Για να είναι ο κώδικάς μας συμβατός με      άλλον, περιβάλλοντα κώδικα που επίσης δεν ακολουθεί κανόνες συγγραφείς –      αν και αυτή η περίπτωση αποτελεί μια καλή ευκαιρία να διορθώσουμε «παλιές      αμαρτίες». </em></li></ol><p>Εν γένει οι κανόνες καλής συγγραφής είναι καλό να ακολουθούνται. Ωστόσο, σε κάποιες περιπτώσεις είναι καλύτερο να αποφεύγονται. Η διάκριση μεταξύ των δύο περιπτώσεων είναι, τις περισσότερες φορές θέμα διαισθητικό και καθώς ο προγραμματιστής κερδίζει όλο και μεγαλύτερη εμπειρία, γίνεται όλο και πιο ξεκάθαρο το τι πρέπει να κάνει και πότε.</p><h1><strong>Ζήτημα 2<sup>ο</sup> – Αν πρόκειται να γράψεις κώδικα, κάντο με στυλ!</strong></h1><p>Ας δούμε μερικά απλά, αλλά σημαντικά θέματα που αφορούν στο στυλ του κώδικα όταν γράφουμε Python.</p><h2>Στοίχιση</h2><p><em> </em></p><p>Όπως έχουμε τονίσει από το πρώτο κιόλας άρθρο μας για την Python, η στοίχιση των εντολών αποτελεί ένα από τα σημαντικότερα «βίτσια» της γλώσσας. Η οδηγία λέει ότι στοιχίζουμε κάθε μπλοκ κώδικα κατά έναν <em>αριθμό κενών χαρακτήρων</em> πιο μέσα από το μπλοκ κώδικα στο οποίο περιέχεται.</p><p>Πόσοι όμως πρέπει να είναι αυτοί οι χαρακτήρες; Εδώ υπάρχουν δύο σχολές σκέψεις:</p><ul><li>Τέσσερις      (4). Αυτό σημαίνει ότι κάθε φορά που πάμε να γράψουμε ένα μπλοκ κώδικα που      περιέχεται μέσα σε ένα άλλο, κάθε εντολή του νέου μπλοκ θα γράφεται      τέσσερις χαρακτήρες πιο μέσα από ότι το εξωτερικό.</li><li>Ένα TAB κενοί      χαρακτήρες (δηλαδή 8). Αυτό σημαίνει ότι αντί να αφήνουμε 4 κενά, όπως      είπαμε παραπάνω για κάθε νέα εσοχή, αφήνουμε ένα TAB (το οποίο παράγεται με τον      πλήκτρο TAB). Όπως      ήδη τονίσαμε, αυτό ισοδυναμεί με 8 κενούς χαρακτήρες.</li></ul><p>Υποθέτω ότι οι περισσότεροι θα βρήκατε τον δεύτερο τρόπο ευκολότερο και πιο συμφέρον από τον πρώτο. Σε αυτήν την περίπτωση κάνατε λάθος. Αν και αμφότεροι οι τρόποι είναι σωστοί, σύμφωνα με τον οδηγό καλής συγγραφής κώδικα που αναφέραμε στην εισαγωγή του άρθρου ο καλύτερος τρόπος αντιμετώπισης είναι ο πρώτος. Ο ίδιος οδηγός προτείνει την πολιτική των TABs ως συμφέρουσα μόνον όταν δουλεύουμε πάνω σε κώδικα που έχει φτιαχτεί εξ’ αρχής (και προφανώς από κάποιον άλλο) με τη χρήση TABs. Σε κάθε περίπτωση που ξεκινούμε να φτιάχνουμε δικό μας κώδικα, προτείνεται η χρήση των 4 κενών χαρακτήρων.</p><blockquote><p><strong><span
style="text-decoration: underline;">ΠΡΟΣΟΧΗ</span></strong>: Οι παραπάνω δυο πολιτικές είναι αμφότερες σωστές. Η μίξη τους ωστόσο, δηλαδή η χρήση άλλοτε τεσσάρων κενών χαρακτήρων και άλλοτε TABs <strong>απαγορεύεται αυστηρα</strong>.</p></blockquote><h2>Μέγιστο μήκος γραμμής</h2><p>Αυτό είναι κάτι που οι περισσότεροι προγραμματιστές (τόσο νέοι όσο και παλαιοί) συνήθως αγνοούν ή έχουν ξεχάσει με τον καιρό. Στην Python, αλλά και στις περισσότερες γλώσσες προγραμματισμού εφαρμόζονται όρια στο μήκος γραμμής κώδικα. Αυτό σημαίνει ότι κάθε γραμμή δεν πρέπει να ξεπερνά συγκεκριμένο αριθμό χαρακτήρων.</p><p>Σύμφωνα με τον οδηγό που ακολουθούμε, αυτό το όριο για την Python είναι οι 79 χαρακτήρες.</p><p>Ανάλογα λοιπόν με τον επεξεργαστή κειμένου που χρησιμοποιείται θα πρέπει να ρυθμίσετε (εφόσον το υποστηρίζει) να αλλάζει γραμμή όταν η εντολή σας υπερβεί τους 79 χαρακτήρες. Εάν αυτό δεν υποστηρίζεται από τον κειμενογράφο σας θα πρέπει να έχετε το νου σας και να το κάνετε με το χέρι. Μην πανικοβάλλεστε! Ακόμη και στη δεύτερη περίπτωση τα πράγματα δεν είναι τραγικά. Όλοι οι κειμενογράφοι έχουν δύο μετρητές, έναν για τις γραμμές και έναν για τις στήλες (δηλαδή τους χαρακτήρες ανά γραμμή). Επομένως το μόνο που έχετε να κάνετε είναι καθώς γράφετε κώδικα να παρατηρείτε τον μετρητή των στηλών και μόλις φθάσει τους 79 χαρακτήρες να αλλάξετε γραμμή.</p><p>Η επίσημη αιτιολογία ύπαρξης του παραπάνω κανόνα είναι ότι ακόμη υπάρχουν μηχανήματα που δεν μπορούν να προβάλλουν γραμμές με περισσότερους των 80 χαρακτήρες, ωστόσο η πρακτική αξία του κανόνα είναι ο πηγαίος κώδικας να μην περιλαμβάνει πολύ μακριές γραμμές υποχρεώνοντας τον προγραμματιστή να χρησιμοποιεί τον οριζόντιο κέρσορα για να τις παρακολουθεί από την αρχή ως το τέλος.</p><p>Ακολουθεί ένα δείγμα κώδικα που ακολουθεί την πολιτική των 80 χαρακτήρων παρμένο από τον οδηγό που αναφέραμε στην αρχή του άρθρου. Δε χρειάζεται να τον καταλάβετε, απλά δείτε πως είναι δομημένος.</p><pre name="code" class="py">
class Rectangle(Blob):
       def __init__(self, width, height,
              color='black', emphasis=None, highlight=0):
       if width == 0 and height == 0 and \
              color == 'red' and emphasis == 'strong' or \
              highlight &gt; 100:
               raise ValueError("sorry, you lose")
       if width == 0 and height == 0 and (color == 'red' or
                                                     emphasis is None):
              raise ValueError("I don't think so -- values are %s, %s" %
                                   (width, height))
       Blob.__init__(self, width, height,
                            color, emphasis, highlight)
</pre><p>Στο παραπάνω δείγμα κώδικα η μεγαλύτερη γραμμή φθάνει τους 74 χαρακτήρες. Παρατηρήστε επίσης ότι οι πολύ μακριές γραμμές χωρίζονται με τον χαρακτήρα ‘\’.</p><h2>Κενές γραμμές</h2><ul><li>Οι      κλάσεις πρέπει να χωρίζονται μεταξύ τους με δύο κενές γραμμές</li><li>Η πρώτη      μέθοδος μιας κλάσης πρέπει να χωρίζεται από τα χαρακτηριστικά της κλάσης      με δύο κενές γραμμές</li><li>Έξτρα      κενές γραμμές μπορούν να χρησιμοποιηθούν σε μεγάλες (σε μέγεθος      συναρτήσεις) ώστε να χωρίζουν τη λογική της συνάρτησης σε τμήματα.</li></ul><h1><strong>Κωδικοποίηση χαρακτήρων (</strong><strong>encoding)</strong></h1><p><strong> </strong></p><p>Ο κώδικας του πυρήνα της διανομής της Python πρέπει υποχρεωτικά να είναι κωδικοποιημένος σε ASCII Latin-1 κωδικοποίηση χαρακτήρων (ISO-8859-1). Για εκδόσεις της Python από 3.0 και επάνω, η κωδικοποίηση χαρακτήρων UTF-8 προτιμάται τις Latin-1. Για περισσότερες πληροφορίες σχετικά με την οδηγία για την κωδικοποίηση χαρακτήρων μπορείτε να ανατρέξετε στο <a
href="http://www.python.org/dev/peps/pep-3120">PEP 3120</a> που βρίσκεται στο επίσημο site της Python.</p><p>Σε αυτό το άρθρο πήραμε μια πρώτη γεύση μερικών από τους κανόνες που αφορούν τον προγραμματισμό σε Python. Μείνετε συντονισμένοι για την συνέχεια του οδηγού καλής συγγραφής κώδικα.</p><p>Μέχρι την επόμενη φορά…</p><p><em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em>.</p> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part7/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Μαθαίνοντας Python – Μέρος 6ο (γ)</title><link>http://greektuts.net/python-part-6c/</link> <comments>http://greektuts.net/python-part-6c/#comments</comments> <pubDate>Thu, 11 Nov 2010 10:00:22 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4458</guid> <description><![CDATA[Με το σημερινό άρθρο ολοκληρώνουμε το κεφάλαιο των συναρτήσεων σε Python. Σε μια προσπάθεια να καλύψουμε όσο πιο σφαιρικά το αντικείμενο μπορούμε θα ασχοληθούμε με κάποια θέματα που έχουν απομείνει και θα κλείσουμε με τον τρόπο με τον οποίο τεκμηριώνουμε μια συνάρτηση σε Python γράφοντας σχόλια.]]></description> <content:encoded><![CDATA[<p>Αναλυτικότερα λοιπόν σήμερα θα μάθουμε:</p><ul><li>Να δημιουργήσουμε ανώνυμες συναρτήσεις τύπου lambda</li><li>Να τεκμηριώνουμε σωστά τις συναρτήσεις μας</li></ul><p><strong>Προαπαιτούμενα</strong></p><p><strong> </strong></p><p>Μαθαίνοντας Python:  <a
href="../python-part-1/" target="_blank">Μέρος Ι</a>, <a
href="../python-part-2/" target="_blank">Μέρος  ΙΙ</a>, <a
href="../python-part-3/" target="_blank">Μέρος ΙΙΙ</a>, <a
href="../python-part-4/" target="_blank">Μέρος IV</a>, <a
href="../python-part5/" target="_blank">Μέρος V</a>, <a
href="../python-part-6a/" target="_blank">Μερος VI  (α)</a><a
href="../../../../../python-part-6a/"></a>, <a
href="http://greektuts.net/python-part-6b/" target="_blank">Μερος VI  (β)</a></p><p><strong>Πριν ξεκινήσουμε…</strong></p><p><strong> </strong></p><p>… θα ήθελα να επισημάνω ένα – δύο πρακτικά ζητήματα.</p><p>Στη συνέχεια παρουσιάζεται ο τρόπος για να επιτευχθούν οι στόχοι που περιγράψαμε στην εισαγωγή. Θα παρατηρήσετε ότι το άρθρο ακολουθεί τη δομή</p><blockquote><p><em>Μικρή περιγραφή του τι θέλουμε να επιτύχουμε (+ επιπλέον σχόλια)</em></p></blockquote><pre name="code" class="py">
<em>Παράδειγμα κώδικα</em>
</pre><p>Στο τέλος του αρχείου θα βρείτε συνημμένο ένα python script που περιέχει συγκεντρωμένα όλα τα παραδείγματα.</p><p>Για να τα χρησιμοποιήσετε, αντιγράφετε το εκάστοτε παράδειγμα σε ένα νέο αρχείο python και το εκτελείτε (βλ. <a
title="Permanent Link to Μαθαίνοντας Python – Μέρος 1ο" href="http://greektuts.net/python-part-1/">Μαθαίνοντας Python – Μέρος 1ο</a> ). Τα παραδείγματα είναι φτιαγμένα με τέτοιον τρόπο ώστε να τυπώνουν τα αποτελέσματα στην οθόνη ώστε να μπορείτε να πιστοποιήσετε εύκολα τη λειτουργικότητά τους. Για διευκόλυνσή σας έχουμε χωρίσει τα παραδείγματα με σχόλια που δίνουν μια μικρή περιγραφή του τι επιχειρούμε κάθε φορά.</p><p>Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><p>( ΦΡΕΣΚΑΡΟΝΤΑΣ ΤΑ ΒΑΣΙΚΑ… )</p><p><strong><em>Σύνταξη μιας συνάρτησης</em></strong></p><pre name="code" class="py">
def triangle_area(a, b):
area = a * b / 2
print("Το εμβαδό του τριγώνου είναι:", area)
</pre><p><strong><em>Καλώντας μια συνάρτηση</em></strong></p><pre name="code" class="py">
triangle_area(66, 2010)
</pre><p>και χωρίς παραμέτρους αν χρειαστεί…</p><pre name="code" class="py">
def no_params_function():
print("Αυτή η συνάρτηση δε δέχεται παραμέτρους...")
</pre><p>Έχοντας στο μυαλό μας τα παραπάνω πάμε να δούμε τις περαιτέρω λειτουργίες που μπορεί να προσφέρει μια συνάρτηση γραμμένη σε γλώσσα Python.</p><p><strong>Lambda </strong><strong>forms</strong></p><p><strong> </strong></p><p>Ο όρος “Lambda form” προέρχεται από παλαιότερες συναρτησιακές γλώσσες (όπως η Lisp) και φαίνεται πως οι δημιουργοί της Python θεώρησαν καλό να την συμπεριλάβουν σαν δυνατότητα και στην δική τους γλώσσα προγραμματισμού.</p><p>Μια Lambda form δεν είναι τίποτε άλλο από μια mini <strong>ανώνυμη </strong>συνάρτηση που ορίζεται μέσα σε μία μεγαλύτερη ώστε  να επιτελεί κάποια συγκεκριμένη, απλή συνήθως διαδικασία.</p><p>Ας δούμε μαζί το ακόλουθο παράδειγμα</p><pre name="code" class="py">
def counter(n):
return lambda x: x + n
</pre><p>με το οποίο, αν μη τι άλλο απομυθοποιείται η φήμη του ότι οι lambda forms είναι κάτι το περίπλοκο. Η παραπάνω συνάρτηση (counter) δέχεται σαν όρισμα έναν αριθμό n και επιστρέφεται (μέσω μιας lambda form που ορίζεται στο σώμα της counter) ο αριθμός n αυξημένος κατά x.</p><p>Ας το δούμε στην πράξη.</p><p>Για να χρησιμοποιήσουμε την συνάρτηση counter θα πρέπει με κάποιο τρόπο να καταφέρουμε να ζητήσουμε από τον χρήστη την τιμή της παραμέτρου x. Επομένως…</p><pre name="code" class="py">
myCounter = counter(5)
</pre><p>αναθέτουμε μια κλήση της συνάρτησης counter με παράμετρο 5 (για το συγκεκριμένο παράδειγμα) σε μια μεταβλητή που ονομάζουμε myCounter.</p><blockquote><p><strong><em>?: </em></strong><em>Υπενθυμίζουμε σε αυτό το σημείο ότι οι μεταβλητές της </em><em>Python </em></p></blockquote><ul><li><em>Δεν έχουν τύπο </em></li><li><em>Μπορούν να φιλοξενήσουν υπό μορφήν      τιμής ακόμη  και ολόκληρες      συναρτήσεις</em></li></ul><p>Έτσι πλέον μπορούμε να καλούμε την myCounter με όρισμα κάποιον αριθμό (ο οποίος, αν επιστρέψουμε στον ορισμό της counter, θα αντιπροσωπεύει τον x).</p><pre name="code" class="py">
print( myCounter( 1 ) )
</pre><p>η παραπάνω κλήση έχει σαν αποτέλεσμα η συνάρτηση myCounter να εκτελέσει εσωτερικά την συνάρτηση counter με x = 1 και n = 5 (το n έχει οριστεί απαξ στο σημείο που αναθέσαμε στην myCounter το counter(5)).</p><p>Έτσι το αποτέλεσμα της παραπάνω κλήσης θα είναι το x το οποίο μέσα στην lambda form ορίζεται ως x: x + n άρα x: 1 + 5. Δηλαδή η παραπάνω κλήση θα εκτυπώσει στην οθόνη 6.</p><pre name="code" class="py">
print( myCounter( 30 ) )
</pre><p>Όμοια η κλήση αυτή θα δώσει… (αφήνεται ως άσκηση στον αναγνώστη).</p><p><strong>Τεκμηρίωση / σχολιασμός συναρτήσεων</strong></p><p><strong> </strong></p><p>Οι συναρτήσει αποτελούν ένα πολύ δυνατό χαρακτηριστικό της γλώσσας Python. Όπως όμως συμβαίνει με όλα τα δυνατά εργαλεία είναι άχρηστες αν κάποιος δεν γνωρίζει πώς να τις χρησιμοποιεί. Όταν γράφουμε κομμάτια κώδικα που επιτελούν συγκεκριμένες διαδικασίες είναι πολύ πιθανό να συμβεί ένα από τα παρακάτω σενάρια.</p><ol><li>Κατασκευάζουμε      το κομμάτι κώδικα που επιτελεί μια συγκεκριμένη διαδικασία χωρίς λάθη.      Χρησιμοποιούμε για ένα διάστημα των κώδικα αυτό και στη συνέχεια τον      εγκαταλείπουμε για λίγο. Αν ο κώδικάς μας δεν είναι καλά ή καθόλου      τεκμηριωμένος υπάρχει πολύ μεγάλη πιθανότητα, όταν τον ανοίξουμε μετά από      μερικούς μήνες να μην μπορούμε να θυμηθούμε τι ακριβώς κάνει.</li><li>Κατασκευάζουμε      το κομμάτι κώδικα που επιτελεί μια συγκεκριμένη διαδικασία χωρίς λάθη. Στη      συνέχεια μας ζητά τον κώδικα αυτόν κάποιος συνεργάτης. Αν ο κώδικάς μας      δεν είναι τεκμηριωμένος υπάρχει πολύ μεγάλη πιθανότητα ο συνεργάτης να μην      καταλάβει περί τίνος πρόκειται και, είτε να χάσει σημαντικό χρόνο      προσπαθώντας να τον ερμηνεύσει, είτε να μην ασχοληθεί και να επιλέξει να      τον ξαναγράψει από το μηδέν.</li></ol><p>Η τεκμηρίωση των συναρτήσεών, όπως και κάθε γραμμής κώδικα, είναι σημαντικότατη. Ας δούμε πως το κάνουμε σε Python.</p><pre name="code" class="py">
def hello():
""" Αυτή είναι μια απλή hello world συνάρτηση... """
print('Hello world')
</pre><p>Όπως εύκολα αντιλαμβάνεστε, το μόνο που χρειάζεται να κάνετε είναι να περικλείεται τα σχόλιά σας σε τριπλά διπλά εισαγωγικά J “”” … “””.</p><p>Χωρίς να βλέπω ιδιαίτερη χρησιμότητα, οφείλω να πω ότι υπάρχει τρόπος (με κώδικα) να εμφανίζεται τα σχόλια των συναρτήσεών σας.</p><pre name="code" class="py">
hello()
print("Σχόλια: '" + hello.__doc__ + "'")
</pre><p>Η πρώτη γραμμή είναι η κλήση της συνάρτησης hello() ενώ η δεύτερη εκτυπώνει στην κονσόλα τα σχόλια της συνάρτησης hello.</p><p>Στην γενική της μορφή η εντολή εμφάνισης των σχολίων είναι η ακόλουθη:</p><pre name="code" class="py">
&lt;ΟΝΟΜΑ_ΣΥΝΑΡΤΗΣΗΣ&gt;.__doc__
</pre><p>Με αυτό το άρθρο ολοκληρώσαμε το οδοιπορικό μας στον χώρο των συναρτήσεων σε Python. Πριν περάσουμε στο επόμενο αντικείμενο θα ξοδέψουμε λίγο χρόνο για ένα ειδικό θέμα.</p><p>Μέχρι τότε να μην ξεχνάτε…</p><p><em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em>.</p><blockquote><p
style="text-align: center;"><em><strong>Μπορείτε να κατεβάσετε τα       αρχεία του βοηθήματος εδώ</strong></em></p><p
style="text-align: center;"><em><strong><a
href="http://static.greektuts.net/uploads3/2010/11/py_tuts_part_6c.zip" ><img
src="../wp-content/uploads/2009/10/membersdownload1.png" alt="download" width="200" height="200" /></a></strong></em></p></blockquote> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part-6c/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Μαθαίνοντας Python – Μέρος 6ο  (β)</title><link>http://greektuts.net/python-part-6b/</link> <comments>http://greektuts.net/python-part-6b/#comments</comments> <pubDate>Mon, 01 Nov 2010 07:55:16 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Python]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[απόστολος κρητικός]]></category> <category><![CDATA[Γλώσσα Προγραμματισμού]]></category> <category><![CDATA[Προγραμματισμός]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4387</guid> <description><![CDATA[Αν και ελαφρώς καθυστερημένα (apologies!) ήρθε η στιγμή να προχωρήσουμε στο κεφάλαιο των συναρτήσεων σε Python. Την τελευταία φορά είδαμε τα βασικά όσον αφορά στη δημιουργία και κλήση συναρτήσεων ενώ προχωρήσαμε και σε διάφορα ενδιαφέροντα «τρικ» όπως χρήση μιας συνάρτησης σαν παράμετρο με μία άλλη συνάρτηση.]]></description> <content:encoded><![CDATA[<p><strong> </strong></p><p>Αναλυτικότερα λοιπόν σήμερα θα μάθουμε:</p><ul><li>Να ορίσουμε συναρτήσεις με παραμέτρους που αποτελούν λέξεις &#8211; κλειδιά</li><li>Να ορίσουμε συναρτήσεις με λίστες για παραμέτρους</li></ul><h1><strong>Προαπαιτούμενα</strong></h1><p><strong> </strong></p><p>Μαθαίνοντας Python:  <a
href="http://greektuts.net/python-part-1/" target="_blank">Μέρος Ι</a>, <a
href="http://greektuts.net/python-part-2/" target="_blank">Μέρος  ΙΙ</a>, <a
href="http://greektuts.net/python-part-3/" target="_blank">Μέρος ΙΙΙ</a>, <a
href="http://greektuts.net/python-part-4/" target="_blank">Μέρος IV</a>, <a
href="http://greektuts.net/python-part5/" target="_blank">Μέρος V</a>, <a
href="http://greektuts.net/python-part-6a/" target="_blank">Μερος VI (α)</a></p><h1><strong>Πριν ξεκινήσουμε…</strong></h1><p><strong> </strong></p><p>… θα ήθελα να επισημάνω ένα – δύο πρακτικά ζητήματα.</p><p>Στη συνέχεια παρουσιάζεται ο τρόπος για να επιτευχθούν οι στόχοι που περιγράψαμε στην εισαγωγή. Θα παρατηρήσετε ότι το άρθρο ακολουθεί τη δομή:</p><p><em>Μικρή περιγραφή του τι θέλουμε να επιτύχουμε (+ επιπλέον σχόλια)</em></p><pre name="code" class="python">
Παράδειγμα κώδικα
</pre><p>Στο τέλος του αρχείου θα βρείτε συνημμένο ένα python script που περιέχει συγκεντρωμένα όλα τα παραδείγματα.</p><p>Για να τα χρησιμοποιήσετε, αντιγράφετε το εκάστοτε παράδειγμα σε ένα νέο αρχείο python και το εκτελείτε (βλ. <a
title="Permanent Link to Μαθαίνοντας Python – Μέρος 1ο" href="http://greektuts.net/python-part-1/">Μαθαίνοντας Python – Μέρος 1ο</a> ). Τα παραδείγματα είναι φτιαγμένα με τέτοιον τρόπο ώστε να τυπώνουν τα αποτελέσματα στην οθόνη ώστε να μπορείτε να πιστοποιήσετε εύκολα τη λειτουργικότητά τους. Για διευκόλυνσή σας έχουμε χωρίσει τα παραδείγματα με σχόλια που δίνουν μια μικρή περιγραφή του τι επιχειρούμε κάθε φορά.</p><p>Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><p>( ΦΡΕΣΚΑΡΟΝΤΑΣ ΤΑ ΒΑΣΙΚΑ… )</p><h1><strong>Σύνταξη μιας συνάρτησης</strong></h1><pre name="code" class="python">
def triangle_area(a, b):
area = a * b / 2
print("Το εμβαδό του τριγώνου είναι:", area)
</pre><h1><strong>Καλώντας μια συνάρτηση</strong></h1><pre name="code" class="python">
triangle_area(66, 2010)
</pre><p>και χωρίς παραμέτρους αν χρειαστεί…</p><pre name="code" class="python">
def no_params_function():
print("Αυτή η συνάρτηση δε δέχεται παραμέτρους...")
</pre><p>Έχοντας στο μυαλό μας τα παραπάνω πάμε να δούμε τις περαιτέρω λειτουργίες που μπορεί να προσφέρει μια συνάρτηση γραμμένη σε γλώσσα Python.</p><h1><strong>Ορίζοντας προεπιλεγμένες τιμές στις παραμέτρους μιας συνάρτησης</strong></h1><p>Πολλές φορές η πληροφορία που ζητούμε από τον χρήστη μπορεί να είναι ελλιπείς (δηλαδή ο χρήστης να μη γνωρίζει τι πρέπει να δώσει σαν τιμή σε κάποιο από τα ζητούμενα). Συνήθως οι εφαρμογές απαιτούν να δοθεί τιμή σε όλες τις μεταβλητές και, αν αυτό δε συμβεί, εμφανίζουν προειδοποιητικά μηνύματα στον χρήστη μέχρις ότου να «γεμίσει» όλα τα πεδία με τιμές.</p><p>Στην Python, όπως και σε άλλες γλώσσες προγραμματισμού δίνεται η δυνατότητα στον προγραμματιστή να καθορίσει προεπιλεγμένες τιμές σε κάποιες από τις παραμέτρους της συνάρτησης έτσι ώστε:</p><ul><li>Αν ο      χρήστης δώσει τιμή, το σύστημα θα αναγνώσει και θα χρησιμοποιήσει την τιμή      αυτή.</li><li>Αν ο      χρήστης δε δώσει τιμή, το σύστημα θα χρησιμοποιήσει την τιμή που έχει      οριστεί ως προεπιλογή.</li></ul><p>Στην πράξη αυτό συμβαίνει ως εξής:</p><pre name="code" class="python">
def dbConnect(username, password, database, server='localhost', port='3306'):
print('Το string σύνδεσης για την MySQL είναι: ')
print()
print('driver={MySQL};server=' + server + ':port=' + port + ';uid=' + username + ';pwd=' + password + ';database=' + database + ';')
</pre><blockquote><p><strong><em>?:</em></strong><em> Η συνάρτηση </em><em>dbConnect</em><em> αναλαμβάνει να κατασκευάσει ενα </em><em>MySQL</em><em> </em><em>connection</em><em> </em><em>string</em><em> ζητώντας μια σειρά από παραμέτρους από τον χρήστη. Όπως εύκολα μπορεί να δει κανείς, κάποιες από τις παραμέτρους έχουν λάβει προεπιλεγμένες τιμές.</em></p></blockquote><p>Το σώμα της συνάρτησης δεν περιλαμβάνει κάτι διαστημικό. Δομεί ένα αλφαριθμητικό με βάση τις τιμές που παίρνει σαν παραμέτρους και το τυπώνει στην οθόνη. Η αξία του παραδείγματος στην πραγματικότητα έγκειται στην λίστα των παραμέτρων. Ας δούμε μερικά παραδείγματα  χρήσης για να αποσαφηνίσουμε την κατάσταση:</p><pre name="code" class="python">
dbConnect('akritiko', '123456', 'myDB', '127.0.0.1', '3333')
</pre><p>Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές για όλες τις παραμέτρους της. Σε αυτήν την περίπτωση η Python θα αγνοήσει τελείως τις προεπιλεγμένες τιμές.</p><pre name="code" class="python">
dbConnect('akritiko', '123456', 'myDB', '127.0.0.1')
</pre><p>Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές για κάποιες μόνον από τις παραμέτρους της. Σε αυτήν την περίπτωση η Python θα αγνοήσει τις προεπιλεγμένες τιμές για τις παραμέτρους για τις οποίες δίδονται τιμές κατά την κλήση της και θα χρησιμοποιήσει τις προεπιλεγμένες για τις υπόλοιπες.</p><pre name="code" class="python">
dbConnect('akritiko', '123456', 'myDB')
</pre><p>Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές μόνον για τις παραμέτρους που δεν έχουν προεπιλεγμένες τιμές. Όπως και πάνω, για τις παραμέτρους για τις οποίες δεν δίνονται τιμές, θα χρησιμοποιηθούν οι προεπιλεγμένες.</p><pre name="code" class="python">
dbConnect('akritiko', '123456', 'myDB', port = '3333')
</pre><p>Εδώ, κατά την κλήση της συνάρτησης, θέλουμε να δώσουμε τιμή, εκτός των παραμέτρων που δεν έχουν προεπιλεγμένες τιμές και στην παράμετρο port. Είναι προφανές ότι αν γράφαμε</p><pre name="code" class="python">
dbConnect('akritiko', '123456', 'myDB', '3333')
</pre><p>η τιμή 3333 θα καταχωρούνταν στην παράμετρο server εφόσον προηγείται της port. Επομένως θα πρέπει με κάποιον τρόπο να δώσουμε στην Python να καταλάβει για ποια παράμετρο μιλάμε. Αυτό συμβαίνει χρησιμοποιώντας τη λέξη κλειδί (keyword) της παραμέτρου, που στην προκειμένη περίπτωση είναι το port, στη συνέχεια τον τελεστή ‘=’ και τέλος την επιθυμητή τιμή.</p><h1><strong>Προεπιλεγμένες τιμές και δυναμικά εξελισσόμενες παράμετροι</strong></h1><p>Είδαμε τι συμβαίνει με τις προεπιλεγμένες τιμές στις παραμέτρους – ορίσματα μιας συνάρτησης. Τι συμβαίνει όμως αν οι παράμετροι αυτοί είναι περισσότεροι πολύπλοκες (ως τύποι;). Ας ρίξουμε μια ματιά στον παρακάτω κώδικα:</p><pre name="code" class="python">
def wishlist(item, Wishlist=[]):
Wishlist.append(item)
return Wishlist
</pre><p>Πρόκειται για μια συνάρτηση η οποία προσθέτει αντικείμενα σε μία Wishlist (λειτουργία που μπορείτε να βρείτε – σε μία ομολογουμένως πιο εξεζητημένη υλοποίηση <img
src='http://greektuts.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> – στο Amazon.com). Εν ολίγοις ο κώδικας απλά παίρνει σαν παραμέτρους το αντικείμενο (item) και την λίστα (Wishlist) και κάθε φορά που εκτελείται συμπεριλαμβάνει το εκάστοτε αντικείμενο στην λίστα.</p><blockquote><p><strong><em>?: </em></strong><em>Παρατηρήστε ότι η </em><em>Wishlist έχει προεπιλεγμένη τιμή την κενή λίστα ( [] ). </em></p></blockquote><p><em> </em></p><p>Ας δούμε τώρα μια σειρά εκτελέσεων:</p><ol><li>print(wishlist(&#8216;Nokia N8&#8242;))</li><li>print(wishlist(&#8216;Harry Potter      and the Deathly Hallows&#8217;))</li><li>print(wishlist(&#8216;Monty Python      and The Holy Grail Blu-Ray Edition&#8217;))</li></ol><p>Σε κάθε εκτέλεση η λίστα διαμορφώνεται ως ακολούθως</p><ol><li>['Nokia N8']</li><li>['Nokia N8', 'Harry Potter and      the Deathly Hallows']</li><li>['Nokia N8', 'Harry Potter and      the Deathly Hallows', 'Monty Python and The Holy Grail Blu-Ray Edition']</li></ol><p>Παρατηρούμε λοιπόν ότι παρόλο που η λίστα έχει σαν προεπιλεγμένη τιμή την κενή λίστα καθώς συμβαίνουν διαδοχικές εκτελέσεις τα αντικείμενα προστίθενται κανονικά. Αυτό συμβαίνει γιατί η προεπιλεγμένη τιμή ισχύει μόνον για την πρώτη εκτέλεση.</p><p>Επιπλέον, αξίζει να σημειωθεί ότι παρότι σε κάθε κλήση εκτελείται εκ νέου η συνάρτηση, η κατάσταση της λίστας διατηρείται. Καταλαβαίνουμε λοιπόν ότι η φύση των δυναμικών παραμέτρων δεν επηρεάζεται από τις προεπιλεγμένες τιμές.</p><p>Στο επόμενο άρθρο θα κλείσουμε το κεφάλαιο των συναρτήσεων σε Python. Μείνετε συντονισμένοι γιατί το τρίτο μέρος του οδηγού σχετικά με συναρτήσεις στην Python πρόκειται να συνοδεύεται από πρακτικές καλής συγγραφής συναρτήσεων.</p><p>Μέχρι την ερχόμενη φορά λοιπόν…</p><p><em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em>.</p><blockquote><p
style="text-align: center;"><em><strong>Μπορείτε να κατεβάσετε τα      αρχεία του βοηθήματος εδώ</strong></em></p><p
style="text-align: center;"><a
href="http://static.greektuts.net/uploads3/2010/11/py_tuts_part_6b.zip" target="_blank"><em><strong><img
class="aligncenter" style="border: 0pt none;" src="../wp-content/uploads/2009/10/membersdownload1.png" alt="download" width="200" height="200" /></strong></em></a></p></blockquote><div
id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;"><!--[if gte mso 9]><xml> <o:OfficeDocumentSettings> <o:TargetScreenSize>800&#215;600</o:TargetScreenSize> </o:OfficeDocumentSettings> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves /> <w:TrackFormatting /> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF /> <w:LidThemeOther>EL</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> <w:SplitPgBreakAndParaMark /> <w:EnableOpenTypeKerning /> <w:DontFlipMirrorIndents /> <w:OverrideTableStyleHps /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathPr> <m:mathFont m:val="Cambria Math" /> <m:brkBin m:val="before" /> <m:brkBinSub m:val="&#45;-" /> <m:smallFrac m:val="off" /> <m:dispDef /> <m:lMargin m:val="0" /> <m:rMargin m:val="0" /> <m:defJc m:val="centerGroup" /> <m:wrapIndent m:val="1440" /> <m:intLim m:val="subSup" /> <m:naryLim m:val="undOvr" /> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"   DefSemiHidden="true" DefQFormat="false" DefPriority="99"   LatentStyleCount="267"> <w:LsdException Locked="false" Priority="0" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Normal" /> <w:LsdException Locked="false" Priority="9" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="heading 1" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8" /> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9" /> <w:LsdException Locked="false" Priority="39" Name="toc 1" /> <w:LsdException Locked="false" Priority="39" Name="toc 2" /> <w:LsdException Locked="false" Priority="39" Name="toc 3" /> <w:LsdException Locked="false" Priority="39" Name="toc 4" /> <w:LsdException Locked="false" Priority="39" Name="toc 5" /> <w:LsdException Locked="false" Priority="39" Name="toc 6" /> <w:LsdException Locked="false" Priority="39" Name="toc 7" /> <w:LsdException Locked="false" Priority="39" Name="toc 8" /> <w:LsdException Locked="false" Priority="39" Name="toc 9" /> <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption" /> <w:LsdException Locked="false" Priority="10" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Title" /> <w:LsdException Locked="false" Priority="0" Name="Default Paragraph Font" /> <w:LsdException Locked="false" Priority="0" Name="Body Text" /> <w:LsdException Locked="false" Priority="11" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtitle" /> <w:LsdException Locked="false" Priority="22" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Strong" /> <w:LsdException Locked="false" Priority="20" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Emphasis" /> <w:LsdException Locked="false" Priority="59" SemiHidden="false"    UnhideWhenUsed="false" Name="Table Grid" /> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text" /> <w:LsdException Locked="false" Priority="1" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="No Spacing" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 1" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 1" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 1" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 1" /> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision" /> <w:LsdException Locked="false" Priority="34" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="List Paragraph" /> <w:LsdException Locked="false" Priority="29" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Quote" /> <w:LsdException Locked="false" Priority="30" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Quote" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 1" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 1" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 1" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 1" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 1" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 2" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 2" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 2" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 2" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 2" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 2" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 2" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 2" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 2" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 3" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 3" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 3" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 3" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 3" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 3" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 3" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 3" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 3" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 4" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 4" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 4" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 4" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 4" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 4" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 4" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 4" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 4" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 5" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 5" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 5" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 5" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 5" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 5" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 5" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 5" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 5" /> <w:LsdException Locked="false" Priority="60" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Shading Accent 6" /> <w:LsdException Locked="false" Priority="61" SemiHidden="false"    UnhideWhenUsed="false" Name="Light List Accent 6" /> <w:LsdException Locked="false" Priority="62" SemiHidden="false"    UnhideWhenUsed="false" Name="Light Grid Accent 6" /> <w:LsdException Locked="false" Priority="63" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6" /> <w:LsdException Locked="false" Priority="64" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6" /> <w:LsdException Locked="false" Priority="65" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 1 Accent 6" /> <w:LsdException Locked="false" Priority="66" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium List 2 Accent 6" /> <w:LsdException Locked="false" Priority="67" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6" /> <w:LsdException Locked="false" Priority="68" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6" /> <w:LsdException Locked="false" Priority="69" SemiHidden="false"    UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6" /> <w:LsdException Locked="false" Priority="70" SemiHidden="false"    UnhideWhenUsed="false" Name="Dark List Accent 6" /> <w:LsdException Locked="false" Priority="71" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Shading Accent 6" /> <w:LsdException Locked="false" Priority="72" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful List Accent 6" /> <w:LsdException Locked="false" Priority="73" SemiHidden="false"    UnhideWhenUsed="false" Name="Colorful Grid Accent 6" /> <w:LsdException Locked="false" Priority="19" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis" /> <w:LsdException Locked="false" Priority="21" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis" /> <w:LsdException Locked="false" Priority="31" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference" /> <w:LsdException Locked="false" Priority="32" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Intense Reference" /> <w:LsdException Locked="false" Priority="33" SemiHidden="false"    UnhideWhenUsed="false" QFormat="true" Name="Book Title" /> <w:LsdException Locked="false" Priority="37" Name="Bibliography" /> <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading" /> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <mce:style><!   /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-priority:99; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman","serif";} --> <!--[endif]--></p><p
class="MsoBodyText" style="text-align: right;">30/10/2010</p><p
class="MsoNormal" style="text-align: justify;"><strong><span
style="font-size: 14pt;">Μαθαίνοντας </span></strong><strong><span
style="font-size: 14pt;" lang="EN-US">Python</span></strong><strong><span
style="font-size: 14pt;"> – Μέρος 6<sup>ο</sup> (β)</span></strong></p><p
class="MsoNormal" style="text-align: justify;"><strong><span
style="font-size: 14pt;"> </span></strong></p><p
class="MsoNormal" style="text-align: justify;">«<span
lang="EN-US">title</span>.<span
lang="EN-US">png</span>» <strong><span
style="font-size: 14pt;"></span></strong></p><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US"> </span></p><p
class="MsoNormal" style="text-align: justify;">Αν και ελαφρώς καθυστερημένα (<span
lang="EN-US">apologies</span>!) ήρθε η στιγμή να προχωρήσουμε στο κεφάλαιο των συναρτήσεων σε <span
lang="EN-US">Python</span>. Την τελευταία φορά είδαμε τα βασικά όσον αφορά στη δημιουργία και κλήση συναρτήσεων ενώ προχωρήσαμε και σε διάφορα ενδιαφέροντα «τρικ» όπως χρήση μιας συνάρτησης σαν παράμετρο με μία άλλη συνάρτηση.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Αναλυτικότερα λοιπόν σήμερα θα μάθουμε:</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoListParagraphCxSpFirst" style="text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--><span
style="font-family: Symbol;"><span>·<span
style="font: 7pt &amp;quot;Times New Roman&amp;quot;;"> </span></span></span><!--[endif]-->Να ορίσουμε συναρτήσεις με παραμέτρους που αποτελούν λέξεις &#8211; κλειδιά</p><p
class="MsoListParagraphCxSpLast" style="text-align: justify; text-indent: -18pt;"><!--[if !supportLists]--><span
style="font-family: Symbol;"><span>·<span
style="font: 7pt &amp;quot;Times New Roman&amp;quot;;"> </span></span></span><!--[endif]-->Να ορίσουμε συναρτήσεις με λίστες για παραμέτρους</p><p
class="MsoNormal" style="text-align: justify;"><strong>Προαπαιτούμενα</strong></p><p
class="MsoNormal" style="text-align: justify;"><strong> </strong></p><p
class="MsoNormal">Μαθαίνοντας Python: <span> </span><a
href="../archives/1571">Μέρος Ι</a>, <a
href="../archives/1713">Μέρος<span> </span>ΙΙ</a>, <a
href="../archives/1838">Μέρος ΙΙΙ</a>, <a
href="../archives/1930">Μέρος <span
lang="EN-US">IV</span></a>, <a
href="../python-part5/">Μέρος <span
lang="EN-US">V</span></a>, <a
href="../python-part-6a/">Μερος <span
lang="EN-US">VI</span> (α)</a></p><p
class="MsoNormal"><p
class="MsoNormal"><p
class="MsoNormal"><strong>Πριν ξεκινήσουμε…</strong></p><p
class="MsoNormal"><strong> </strong></p><p
class="MsoNormal" style="text-align: justify;">… θα ήθελα να επισημάνω ένα – δύο πρακτικά ζητήματα.</p><p
class="MsoNormal" style="text-align: justify;">Στη συνέχεια παρουσιάζεται ο τρόπος για να επιτευχθούν οι στόχοι που περιγράψαμε στην εισαγωγή. Θα παρατηρήσετε ότι το άρθρο ακολουθεί τη δομή:</p><p
class="MsoNormal" style="text-align: justify;"><div
style="border: 1pt solid windowtext; padding: 1pt 4pt;"><p
class="MsoNormal" style="border: medium none; padding: 0cm;"><em>Μικρή περιγραφή του τι θέλουμε να επιτύχουμε (+ επιπλέον σχόλια)</em></p><p
class="MsoNormal" style="border: medium none; padding: 0cm;"><em>Παράδειγμα κώδικα</em></p></div><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Στο τέλος του αρχείου θα βρείτε συνημμένο ένα <span
lang="EN-US">python</span><span
lang="EN-US"> </span><span
lang="EN-US">script</span><span
lang="EN-US"> </span>που περιέχει συγκεντρωμένα όλα τα παραδείγματα.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Για να τα χρησιμοποιήσετε, αντιγράφετε το εκάστοτε παράδειγμα σε ένα νέο αρχείο <span
lang="EN-US">python</span><span
lang="EN-US"> </span>και το εκτελείτε (βλ. <a
title="Permanent Link to Μαθαίνοντας Python – Μέρος 1ο" href="../archives/1571">Μαθαίνοντας Python – Μέρος 1ο</a> ). Τα παραδείγματα είναι φτιαγμένα με τέτοιον τρόπο ώστε να τυπώνουν τα αποτελέσματα στην οθόνη ώστε να μπορείτε να πιστοποιήσετε εύκολα τη λειτουργικότητά τους. Για διευκόλυνσή σας έχουμε χωρίσει τα παραδείγματα με σχόλια που δίνουν μια μικρή περιγραφή του τι επιχειρούμε κάθε φορά.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Βεβαιωθείτε ότι δεν ξεχάσατε το μάτι της κουζίνας ανοικτό, ετοιμάστε μία κούπα καφέ ή τσάι, βάλτε απαλή μουσική και ξεκινάμε…</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">( ΦΡΕΣΚΑΡΟΝΤΑΣ ΤΑ ΒΑΣΙΚΑ… )</p><p
class="MsoNormal" style="text-align: justify;"><strong><em> </em></strong></p><p
class="MsoNormal" style="text-align: justify;"><strong><em>Σύνταξη μιας συνάρτησης</em></strong></p><p
class="MsoNormal" style="text-align: justify;"><strong><em> </em></strong></p><p
class="MsoNormal" style="text-align: justify;"><em><span
lang="EN-US">def</span><span
lang="EN-US"> </span></em><em><span
lang="EN-US">triangle</span>_</em><em><span
lang="EN-US">area</span>(</em><em><span
lang="EN-US">a</span>, </em><em><span
lang="EN-US">b</span>):<span> </span></em></p><p
class="MsoNormal" style="text-align: justify;"><em><span> </span>area = a * b / 2</em></p><p
class="MsoNormal" style="text-align: justify;"><em><span> </span>print(&#8220;Το εμβαδό του τριγώνου είναι:&#8221;, area)</em></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><strong><em>Καλώντας μια συνάρτηση</em></strong></p><p
class="MsoNormal" style="text-align: justify;">triangle_area(66, 2010)</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">και χωρίς παραμέτρους αν χρειαστεί…</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">def no_params_function():</p><p
class="MsoNormal" style="text-align: justify;"><span> </span>print(&#8220;Αυτή η συνάρτηση δε δέχεται παραμέτρους&#8230;&#8221;)</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Έχοντας στο μυαλό μας τα παραπάνω πάμε να δούμε τις περαιτέρω λειτουργίες που μπορεί να προσφέρει μια συνάρτηση γραμμένη σε γλώσσα <span
lang="EN-US">Python</span>.<span
lang="EN-US"></span></p><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US"> </span></p><p
class="MsoNormal" style="text-align: justify;"><strong>Ορίζοντας προεπιλεγμένες τιμές στις παραμέτρους μιας συνάρτησης</strong></p><p
class="MsoNormal" style="text-align: justify;"><strong> </strong></p><p
class="MsoNormal" style="text-align: justify;">Πολλές φορές η πληροφορία που ζητούμε από τον χρήστη μπορεί να είναι ελλιπείς (δηλαδή ο χρήστης να μη γνωρίζει τι πρέπει να δώσει σαν τιμή σε κάποιο από τα ζητούμενα). Συνήθως οι εφαρμογές απαιτούν να δοθεί τιμή σε όλες τις μεταβλητές και, αν αυτό δε συμβεί, εμφανίζουν προειδοποιητικά μηνύματα στον χρήστη μέχρις ότου να «γεμίσει» όλα τα πεδία με τιμές.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Στην <span
lang="EN-US">Python</span>, όπως και σε άλλες γλώσσες προγραμματισμού δίνεται η δυνατότητα στον προγραμματιστή να καθορίσει προεπιλεγμένες τιμές σε κάποιες από τις παραμέτρους της συνάρτησης έτσι ώστε:</p><p
class="MsoNormal" style="text-align: justify;"><ul
style="margin-top: 0cm;" type="disc"><li
class="MsoNormal" style="text-align: justify;">Αν ο      χρήστης δώσει τιμή, το σύστημα θα αναγνώσει και θα χρησιμοποιήσει την τιμή      αυτή.</li><li
class="MsoNormal" style="text-align: justify;">Αν ο      χρήστης δε δώσει τιμή, το σύστημα θα χρησιμοποιήσει την τιμή που έχει      οριστεί ως προεπιλογή.</li></ul><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Στην πράξη αυτό συμβαίνει ως εξής:</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal"><span
lang="EN-US">def dbConnect(username, password, database, server=&#8217;localhost&#8217;, port=&#8217;3306&#8242;):</span></p><p
class="MsoNormal"><span
lang="EN-US"><span> </span>print</span><span>(&#8216;Το </span><span
lang="EN-US">string</span><span> σύνδεσης για την </span><span
lang="EN-US">MySQL</span><span> είναι: &#8216;)</span></p><p
class="MsoNormal"><span><span> </span></span><span
lang="EN-US">print</span><span>()</span></p><p
class="MsoNormal"><span><span> </span></span><span
lang="EN-US">print</span><span>(&#8216;</span><span
lang="EN-US">driver</span><span>={</span><span
lang="EN-US">MySQL</span><span>};</span><span
lang="EN-US">server</span><span>=&#8217; + </span><span
lang="EN-US">server</span><span> + &#8216;:</span><span
lang="EN-US">port</span><span>=&#8217; + </span><span
lang="EN-US">port</span><span> + &#8216;;</span><span
lang="EN-US">uid</span><span>=&#8217; + </span><span
lang="EN-US">username</span><span> + &#8216;;</span><span
lang="EN-US">pwd</span><span>=&#8217; + </span><span
lang="EN-US">password</span><span> + &#8216;;</span><span
lang="EN-US">database</span><span>=&#8217; + </span><span
lang="EN-US">database</span><span> + &#8216;;&#8217;)</span><span
lang="EN-US"></span></p><p
class="MsoNormal" style="text-align: justify;"><strong><em><span>?:</span></em></strong><em><span> Η συνάρτηση </span></em><em><span
lang="EN-US">dbConnect</span></em><em><span> αναλαμβάνει να κατασκευάσει ενα </span></em><em><span
lang="EN-US">MySQL</span></em><em><span
lang="EN-US"> </span></em><em><span
lang="EN-US">connection</span></em><em><span
lang="EN-US"> </span></em><em><span
lang="EN-US">string</span></em><em><span> ζητώντας μια σειρά από παραμέτρους από τον χρήστη. Όπως εύκολα μπορεί να δει κανείς, κάποιες από τις παραμέτρους έχουν λάβει προεπιλεγμένες τιμές.</span></em></p><p
class="MsoNormal" style="text-align: justify;"><em> </em></p><p
class="MsoNormal" style="text-align: justify;">Το σώμα της συνάρτησης δεν περιλαμβάνει κάτι διαστημικό. Δομεί ένα αλφαριθμητικό με βάση τις τιμές που παίρνει σαν παραμέτρους και το τυπώνει στην οθόνη. Η αξία του παραδείγματος στην πραγματικότητα έγκειται στην λίστα των παραμέτρων. Ας δούμε μερικά παραδείγματα<span> </span>χρήσης για να αποσαφηνίσουμε την κατάσταση:</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">dbConnect(&#8216;akritiko&#8217;, &#8217;123456&#8242;, &#8216;myDB&#8217;, &#8217;127.0.0.1&#8242;, &#8217;3333&#8242;)</span></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές για όλες τις παραμέτρους της. Σε αυτήν την περίπτωση η <span
lang="EN-US">Python</span><span
lang="EN-US"> </span>θα αγνοήσει τελείως τις προεπιλεγμένες τιμές.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">dbConnect(&#8216;akritiko&#8217;, &#8217;123456&#8242;, &#8216;myDB&#8217;, &#8217;127.0.0.1&#8242;)</span></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές για κάποιες μόνον από τις παραμέτρους της. Σε αυτήν την περίπτωση η <span
lang="EN-US">Python</span><span
lang="EN-US"> </span>θα αγνοήσει τις προεπιλεγμένες τιμές για τις παραμέτρους για τις οποίες δίδονται τιμές κατά την κλήση της και θα χρησιμοποιήσει τις προεπιλεγμένες για τις υπόλοιπες.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">dbConnect(&#8216;akritiko&#8217;, &#8217;123456&#8242;, &#8216;myDB&#8217;)</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Εδώ, κατά την κλήση της συνάρτησης, δίνονται τιμές μόνον για τις παραμέτρους που δεν έχουν προεπιλεγμένες τιμές. Όπως και πάνω, για τις παραμέτρους για τις οποίες δεν δίνονται τιμές, θα χρησιμοποιηθούν οι προεπιλεγμένες.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">dbConnect(&#8216;akritiko&#8217;, &#8217;123456&#8242;, &#8216;myDB&#8217;, port = &#8217;3333&#8242;)</span></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Εδώ, κατά την κλήση της συνάρτησης, θέλουμε να δώσουμε τιμή, εκτός των παραμέτρων που δεν έχουν προεπιλεγμένες τιμές και στην παράμετρο <span
lang="EN-US">port</span>. Είναι προφανές ότι αν γράφαμε</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">dbConnect(&#8216;akritiko&#8217;, &#8217;123456&#8242;, &#8216;myDB&#8217;, &#8217;3333&#8242;)</span></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">η τιμή 3333 θα καταχωρούνταν στην παράμετρο <span
lang="EN-US">server</span><span
lang="EN-US"> </span>εφόσον προηγείται της <span
lang="EN-US">port</span>. Επομένως θα πρέπει με κάποιον τρόπο να δώσουμε στην <span
lang="EN-US">Python</span><span
lang="EN-US"> </span>να καταλάβει για ποια παράμετρο μιλάμε. Αυτό συμβαίνει χρησιμοποιώντας τη λέξη κλειδί (<span
lang="EN-US">keyword</span>) της παραμέτρου, που στην προκειμένη περίπτωση είναι το <span
lang="EN-US">port</span>, στη συνέχεια τον τελεστή ‘=’ και τέλος την επιθυμητή τιμή.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><strong>Προεπιλεγμένες τιμές και δυναμικά εξελισσόμενες παράμετροι</strong></p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Είδαμε τι συμβαίνει με τις προεπιλεγμένες τιμές στις παραμέτρους – ορίσματα μιας συνάρτησης. Τι συμβαίνει όμως αν οι παράμετροι αυτοί είναι περισσότεροι πολύπλοκες (ως τύποι;). Ας ρίξουμε μια ματιά στον παρακάτω κώδικα:</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">def wishlist(item, Wishlist=[]):</span></p><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US"><span> </span>Wishlist.append(item)</span></p><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US"><span> </span></span>return Wishlist</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Πρόκειται για μια συνάρτηση η οποία προσθέτει αντικείμενα σε μία <span
lang="EN-US">Wishlist</span><span
lang="EN-US"> </span>(λειτουργία που μπορείτε να βρείτε – σε μία ομολογουμένως πιο εξεζητημένη υλοποίηση :<span
lang="EN-US">P</span><span
lang="EN-US"> </span>– στο <span
lang="EN-US">Amazon</span>.<span
lang="EN-US">com</span>). Εν ολίγοις ο κώδικας απλά παίρνει σαν παραμέτρους το αντικείμενο (<span
lang="EN-US">item</span>) και την λίστα (<span
lang="EN-US">Wishlist</span>) και κάθε φορά που εκτελείται συμπεριλαμβάνει το εκάστοτε αντικείμενο στην λίστα.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><strong><em>?: </em></strong><em>Παρατηρήστε ότι η </em><em><span
lang="EN-US">Wishlist</span><span
lang="EN-US"> </span>έχει προεπιλεγμένη τιμή την κενή λίστα ( [] ). </em></p><p
class="MsoNormal" style="text-align: justify;"><em><span
lang="EN-US"> </span></em></p><p
class="MsoNormal" style="text-align: justify;">Ας δούμε τώρα μια σειρά εκτελέσεων:</p><p
class="MsoNormal" style="text-align: justify;"><ol
style="margin-top: 0cm;" type="1"><li
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">print(wishlist(&#8216;Nokia N8&#8242;))</span></li><li
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">print(wishlist(&#8216;Harry Potter      and the Deathly Hallows&#8217;))</span></li><li
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">print(wishlist(&#8216;Monty Python      and The Holy Grail Blu-Ray Edition&#8217;)) </span></li></ol><p
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US"> </span></p><p
class="MsoNormal" style="text-align: justify;">Σε κάθε εκτέλεση η λίστα διαμορφώνεται ως ακολούθως</p><p
class="MsoNormal" style="text-align: justify;"><ol
style="margin-top: 0cm;" type="1"><li
class="MsoNormal" style="text-align: justify;">[<span
lang="EN-US">'Nokia N8'</span>]</li><li
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">['Nokia N8', 'Harry Potter and      the Deathly Hallows']</span></li><li
class="MsoNormal" style="text-align: justify;"><span
lang="EN-US">['Nokia N8', 'Harry Potter and      the Deathly Hallows', 'Monty Python and The Holy Grail Blu-Ray Edition']</span></li></ol><p
class="MsoNormal" style="text-align: justify;">Παρατηρούμε λοιπόν ότι παρόλο που η λίστα έχει σαν προεπιλεγμένη τιμή την κενή λίστα καθώς συμβαίνουν διαδοχικές εκτελέσεις τα αντικείμενα προστίθενται κανονικά. Αυτό συμβαίνει γιατί η προεπιλεγμένη τιμή ισχύει μόνον για την πρώτη εκτέλεση.</p><p
class="MsoNormal" style="text-align: justify;">Επιπλέον, αξίζει να σημειωθεί ότι παρότι σε κάθε κλήση εκτελείται εκ νέου η συνάρτηση, η κατάσταση της λίστας διατηρείται. Καταλαβαίνουμε λοιπόν ότι η φύση των δυναμικών παραμέτρων δεν επηρεάζεται από τις προεπιλεγμένες τιμές.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Στο επόμενο άρθρο θα κλείσουμε το κεφάλαιο των συναρτήσεων σε <span
lang="EN-US">Python</span>. Μείνετε συντονισμένοι γιατί το τρίτο μέρος του οδηγού σχετικά με συναρτήσεις στην <span
lang="EN-US">Python</span><span
lang="EN-US"> </span>πρόκειται να συνοδεύεται από πρακτικές καλής συγγραφής συναρτήσεων.</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;">Μέχρι την ερχόμενη φορά λοιπόν…</p><p
class="MsoNormal" style="text-align: justify;"><p
class="MsoNormal" style="text-align: justify;"><em><span
style="text-decoration: underline;">να είστε καλά και να φροντίζεται τον εαυτό σας</span></em>.</p></div> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/python-part-6b/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>WordPress Plug-ins: Από τη θεωρία στην πράξη (μέρος 2)</title><link>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part2/</link> <comments>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part2/#comments</comments> <pubDate>Wed, 04 Aug 2010 07:00:15 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Plugins-Πρόσθετα]]></category> <category><![CDATA[Wordpress]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[newsfilter]]></category> <category><![CDATA[part1]]></category> <category><![CDATA[plugins-πρόσθετα]]></category> <category><![CDATA[press]]></category> <category><![CDATA[theory]]></category> <category><![CDATA[word]]></category> <category><![CDATA[WordPress Plug-ins: Από τη θεωρία στην πράξη (μέρος 1)]]></category> <category><![CDATA[wordpress plugin]]></category> <category><![CDATA[wordpress plugin creation]]></category> <category><![CDATA[wordpress plugin from theory to reality]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4149</guid> <description><![CDATA[Σε αυτό το δεύτερο και τελευταίο μέρος της σειράς «WordPress Plug-ins: Από τη θεωρία στην πράξη» θα εμπλουτίσουμε τον σκελετό που κατασκευάσαμε στο προηγούμενο άρθρο μας ώστε να επιτυγχάνει την λειτουργικότητα που αναζητούμε.]]></description> <content:encoded><![CDATA[<p>Πριν ξεκινήσουμε ας θυμηθούμε τα σημαντικότερα σημεία του εγχειρήματός μας όπως τα περιγράψαμε στο πρώτο μέρος της σειράς μας.</p><h1><strong>Το πρόβλημα</strong></h1><p>Επιθυμούμε να κατασκευάσουμε ένα WordPress Plug-in το οποίο θα προσθέτει έναν αύξοντα αριθμό μπροστά από τα μη αριθμημένα ψευδώνυμα των  συγγραφέων σχολίων του blog μας.</p><h1><strong>Γιατί να μην πειράξω το </strong><strong>theme;</strong></h1><p>Ο έμπειρος αναγνώστης μπορεί να αναρωτηθεί: «Μα τα WordPress themes δεν είναι και αυτά ένα σύνολο αρχείων σε κώδικα php, css, html, κλπ.; Δεν θα μπορούσαν να επέμβουν εκεί και να τροποποιήσουν τον τρόπο παρουσίασης των σχολίων;». Και θα είχε δίκαιο! Θα μπορούσαμε.</p><p>Ωστόσο…</p><ul><li>Το να μελετήσουμε υπάρχον κώδικα και να ανακαλύψουμε τι πρέπει να αλλάξει ώστε να έχουμε το επιθυμητό αποτέλεσμα είναι σαφώς δυσκολότερο από το να δημιουργήσουμε ένα μικρό κομμάτι κώδικα από το μηδέν.</li><li>Εν γένει, όταν κανείς πειράζει υπάρχοντα κώδικα, επιβάλλεται μετά την αλλαγή να εκτελέσει εξαντλητικούς ελέγχους για να σιγουρευτεί ότι όλα λειτουργούν όπως πριν, δηλαδή ότι οι αλλαγές δεν επηρέασαν τον προϋπάρχοντα κώδικα.</li></ul><h1><strong>Ο στόχος μας με εικόνες</strong></h1><p>Στην παρούσα φάση, τα σχόλια στα άρθρα μας έχουν την παρακάτω μορφή</p><blockquote><p
style="text-align: center;"><img
class="size-full wp-image-4150 aligncenter" src="http://static.greektuts.net/uploads3/2010/08/noNumbers1.png" alt="" width="600" height="550" /></p></blockquote><p>Θα θέλαμε να προσθέσουμε έναν αύξοντα αριθμό μπροστά από κάθε ψευδώνυμο χρήστη. Το αποτέλεσμα δηλαδή του plug-in μας θα πρέπει να κάνει το τμήμα των σχολίων να φαίνεται ως εξής:</p><blockquote><p
style="text-align: center;"><img
class="size-full wp-image-4151 aligncenter" src="http://static.greektuts.net/uploads3/2010/08/withNumbers1.png" alt="" width="600" height="581" /></p></blockquote><h1><strong>Ο σκελετός που έχουμε κατασκευάσει εμπλουτισμένος</strong></h1><pre name="code" class="php">
&lt;?php
/*
Plugin Name: numberedAuthorsComments
Plugin URI: http://www.newsfilter.gr
Version: v0.5
Author: &lt;a href=”http://krap.gr/”&gt;Apostolos Kritikos&lt;/a&gt;
Description: This is my first plugin. Please don't be too hard on me if it crushes...
*/
if(!class_exists('numberedAuthorsComments')) {
class numberedAuthorsComments {
var $i;
function numberedAuthorsComments() { //κατασκευαστής
$this-&gt;i = 0;
}
function addNumber($author='') {
$this-&gt;i++;
return "(".$this-&gt;i.") ".$author;
}
}
} //τέλος κλάσης
if(class_exists('numberedAuthorsComments')) {
$myplugin = new numberedAuthorsComments();
}
if(isset($myplugin))  {
//Actions
//Filters
add_filter('get_comment_author',array(&amp;$myplugin, 'addNumber'));
}
?&gt;
</pre><p>Αυτός είναι ο κώδικας του plug-in ολοκληρωμένος. Όπως μπορείτε να δείτε η διαφοροποίησή του από τον σκελετό που είχαμε κατασκευάσει στο προηγούμενο άρθρο μας είναι μόλις της τάξεως των 5 γραμμών. Αυτό δηλώνει ακριβώς την δύναμη και συνάμα την απλότητα της δημιουργίας WordPress plug-ins. Ας δούμε όμως αναλυτικά τη λειτουργικότητα των γραμμών κώδικα που προσθέσαμε.</p><pre name="code" class="php">
var $i;
</pre><p>Πρόκειται για μια μεταβλητή που θα αποτελέσει τον απαριθμητή των σχολίων μας. Σε αυτή τη μεταβλητή θα κρατείται ο τελευταίος αριθμός που δόθηκε σε σχόλιο ώστε στο επόμενο σχόλιο, να δοθεί ο επόμενος αριθμός. Στη θεωρία του αντικειμενοστραφούς προγραμματισμού η συγκεκριμένη μεταβλητή ονομάζεται χαρακτηριστικό της κλάσης.</p><pre name="code" class="php">
$this-&gt;i = 0;
</pre><p>Ως χαρακτηριστικό της κλάσης numberedAuthorsComments, η $i οφείλει να αρχικοποιηθεί στον κατασκευαστή (ή δημιουργό) της κλάσης. Αυτό συμβαίνει με την παραπάνω εντολή (η σύνταξη πρέπει να γίνει με αυτόν ακριβώς τον τρόπο). Το 0 εδώ αποτελεί μία σύμβαση. Θεωρώ ότι αρχικοποιώ το μετρητή με 0 ώστε σε κάθε σχόλιο που θα εμφανίζεται να αυξάνω κατά 1.</p><pre name="code" class="php">
function addNumber($author='') {
$this-&gt;i++;
return "(".$this-&gt;i.") ".$author;
}
</pre><p>Η μέθοδος addNumbers αποτελεί το κλειδί του plug-in. Αρχικά, η μεταβλητή $i αυξάνει κατά 1 και στη συνέχεια επιστρέφεται ένα αλφαριθμητικό το οποίο περιλαμβάνει τη μεταβλητή $i κλεισμένη σε παρενθέσεις ακολουθούμενη από το όνομα του εκάστοτε συγγραφέα σχολίου για το εκάστοτε άρθρο.</p><p>Σημαντική λεπτομέρεια αποτελεί η μεταβλητή $author=” που ζητείται σαν όρισμα από την μέθοδο addNumbers. Εδώ, το WordPress τροφοδοτεί το όνομα του εκάστοτε συγγραφέα σχολίου (με τρόπο που θα περιγράψουμε παρακάτω).</p><pre name="code" class="php">
add_filter('get_comment_author',array(&amp;$myplugin, 'addNumber'));
</pre><p>Η τελευταία  και σπουδαιότερη γραμμή / προσθήκη στο plug-in μας. Αν και έχουμε ασχοληθεί αναλυτικά με τις γραμμές αυτού του τύπου στα πρώτα μας άρθρα, ας κάνουμε μια μικρή επανάληψη.</p><p>Η κλήση add_filter κάνει ουσιαστικά την  χρήση hooks για να επιβάλει το επιθυμητό φίλτρο στα επιθυμητά δεδομένα. Στην παρούσα φάση το hook είναι η δήλωση get_comment_author και όπως είναι φανερό από το όνομα, αναλαμβάνει να επιστρέψει τα ονόματα των συγγραφέων των σχολίων ανά άρθρο του blog στο οποίο έχει εγκατασταθεί το plug-in που κατασκευάζουμε.</p><p>Με απλά λόγια: Το προαναφερθέν hook στέλνει υπό τη μορφή ορίσματος το όνομα των συγγραφέων των σχολίων του εκάστοτε άρθρου στην μέθοδο addNumber του αντικειμένου myPlugin (η χρήση των &amp;$ είναι υποχρεωτική). Στη συνέχεια η μέθοδος addNumbers προσθέτει τον αύξοντα αριθμό μπροστά από το όνομα του συγγραφέα του εκάστοτε σχολίου, με τον τρόπο που περιγράψαμε και το επιστρέφει, πρακτικά, πίσω στη μηχανή του WordPress.</p><p>Στο τέλος του άρθρου μπορείτε να βρείτε την τελική, ολοκληρωμένη έκδοση του plug-in και να το εγκαταστήσετε στο blog σας κατά τα γνωστά. Αν σε κάποιο άρθρο υπάρχουν σχόλια, μετά την ενεργοποίηση του plug-in θα πρέπει να εμφανίζεται μία extra πληροφορία δίπλα από το ψευδώνυμο κάθε συγγραφέα σχολίου που θα έχει τη μορφή:</p><pre name="code" class="php">
( ΑΡΙΘΜΟΣ ΣΧΟΛΙΟΥ ) ΨΕΥΔΩΝΥΜΟ
</pre><p>Φυσικά, αν το theme σας ήδη υποστηρίζει αριθμούς σχολίων, μετά την ενεργοποίηση του plug-in, απλά θα βλέπετε τον αριθμό 2 φορές.</p><p>Με αυτό το άρθρο ολοκληρώνεται η πρώτη απόπειρα εφαρμογής της θεωρίας μας σε ένα πραγματικό plug-in. Παρά την απλότητά του, θεωρώ ότι είναι σημαντικό βήμα κυρίως για τους αρχάριους στον χώρο. Μείνετε συντονισμένοι, υπάρχει μέλλον.</p><p>Μέχρι τότε μη ξεχνάτε&#8230;</p><p><em>να είστε καλά και να προσέχετε τον εαυτό σας!</em></p><blockquote><p
style="text-align: center;">Μπορείτε να κατεβάσετε τα αρχεία του βοηθήματος εδώ</p><p
style="text-align: center;"><a
href="http://static.greektuts.net/uploads3/2010/08/numberedAuthorsComments1.zip"><img
class="size-full wp-image-4135 aligncenter" src="http://static.greektuts.net/uploads/2009/10/membersdownload1.png" alt="" /></a></p></blockquote> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part2/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>WordPress Plug-ins: Από τη θεωρία στην πράξη (μέρος 1)</title><link>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part1/</link> <comments>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part1/#comments</comments> <pubDate>Mon, 02 Aug 2010 07:00:19 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Plugins-Πρόσθετα]]></category> <category><![CDATA[Wordpress]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[newsfilter]]></category> <category><![CDATA[part1]]></category> <category><![CDATA[press]]></category> <category><![CDATA[theory]]></category> <category><![CDATA[word]]></category> <category><![CDATA[WordPress Plug-ins: Από τη θεωρία στην πράξη (μέρος 1)]]></category> <category><![CDATA[wordpress plugin]]></category> <category><![CDATA[wordpress plugin creation]]></category> <category><![CDATA[wordpress plugin from theory to reality]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4132</guid> <description><![CDATA[Προτού αρχίσουμε να κολυμπάμε σε βαθύτερα νερά, όσον αφορά την δημιουργία WordPress plug-ins τι θα λέγατε να εφαρμόσουμε όσα μάθαμε σε ένα απτό παράδειγμα. Θα ξεκινήσουμε (σε αυτό το άρθρο) ορίζοντας το πρόβλημα το οποίο θέλουμε να αντιμετωπίσουμε και θα δημιουργήσουμε τον σκελετό του plug-in που χρειαζόμαστε.]]></description> <content:encoded><![CDATA[<h1><strong>Το πρόβλημα</strong></h1><p>Όπως μπορεί να έχετε προσέξει στο μίνι κειμενάκι / βιογραφικό μου στο <a
href="http://www.greektuts.net/">GreekTuts</a> είμαι συνιδρυτής ενός ενημερωτικού blog με έδρα τη Θεσσαλονίκη (αν σας ενδιαφέρει ποιο είναι αυτό, μπορείτε να βρείτε πληροφορίες στο <a
href="../author/akritikos/">http://greektuts.net/author/akritikos/</a>).</p><p>Όπως συμβαίνει στα περισσότερα blogs αυτού του τύπου, πολύ συχνά φιλοξενούμε διαγωνισμούς. Εν τάχει, η λογική είναι η ακόλουθη:</p><ul><li>Οι ενδιαφερόμενοι αφήνουν από ένα σχόλιο στο άρθρο του διαγωνισμού</li><li>Την ημέρα της κλήρωσης χρησιμοποιούμε κάποια υπηρεσία παραγωγής τυχαίων αριθμών (π.χ. <a
href="http://www.random.org/">http://www.random.org/</a>)</li><li>Το σχόλιο με τον αριθμό που προήλθε από την παραπάνω γεννήτρια τυχαίων αριθμών κερδίζει</li></ul><p>Μέχρι πρόσφατα δεν είχαμε κανένα πρόβλημα διότι το theme που χρησιμοποιούσαμε υποστήριζε αρίθμηση σχολίων ανά άρθρο. Ωστόσο, το νέο theme που έχει τεθεί σε λειτουργία εδώ και λίγο καιρό δεν υποστηρίζει αρίθμηση σχολίων.</p><h1><strong>Πιθανές λύσεις</strong></h1><p>Ο έμπειρος αναγνώστης μπορεί να αναρωτηθεί: «Μα τα WordPress themes δεν είναι και αυτά ένα σύνολο αρχείων σε κώδικα php, css, html, κλπ.; Δεν θα μπορούσαν να επέμβουν εκεί και να τροποποιήσουν τον τρόπο παρουσίασης των σχολίων;». Και θα είχε δίκαιο! Θα μπορούσαμε.</p><p>Ωστόσο…</p><ul><li>Το να μελετήσουμε υπάρχον κώδικα και να ανακαλύψουμε τι πρέπει να αλλάξει ώστε να έχουμε το επιθυμητό αποτέλεσμα είναι σαφώς δυσκολότερο από το να δημιουργήσουμε ένα μικρό κομμάτι κώδικα από το μηδέν.</li><li>Εν γένει, όταν κανείς πειράζει υπάρχοντα κώδικα, επιβάλλεται μετά την αλλαγή να εκτελέσει εξαντλητικούς ελέγχους για να σιγουρευτεί ότι όλα λειτουργούν όπως πριν, δηλαδή ότι οι αλλαγές δεν επηρέασαν τον προϋπάρχοντα κώδικα.</li></ul><p>Επομένως…</p><p>Η λύση του WordPress plug-in φαίνεται να είναι η πιο έξυπνη κίνηση. Έχοντας λοιπόν τις απαιτήσεις για την ανάπτυξη του plug-in, πάμε να το υλοποιήσουμε με βάση τα όσα έχουμε μάθει ως τώρα.</p><h1><strong>WordPress Plug-in: Numbered Author Comments</strong></h1><p>Στην παρούσα φάση, τα σχόλια στα άρθρα μας έχουν την παρακάτω μορφή</p><blockquote><p
style="text-align: center;"><img
class="size-full wp-image-4135 aligncenter" src="http://static.greektuts.net/uploads3/2010/08/noNumbers.png" alt="" width="600" height="550" /></p></blockquote><p>Θα θέλαμε να προσθέσουμε έναν αύξοντα αριθμό μπροστά από κάθε ψευδώνυμο χρήστη. Το αποτέλεσμα δηλαδή του plug-in μας θα πρέπει να κάνει το τμήμα των σχολίων να φαίνεται ως εξής:</p><blockquote><p
style="text-align: center;"><img
class="size-full wp-image-4136 aligncenter" src="http://static.greektuts.net/uploads3/2010/08/withNumbers.png" alt="" width="600" height="581" /></p></blockquote><p>Ας σκεφθούμε τώρα πως μπορεί να υλοποιηθεί ένα plug-in που θα επιφέρει το επιθυμητό αποτέλεσμα. Μας ενδιαφέρει, μετά την ενεργοποίηση του plug-in μας, να προστεθεί ένας αύξον αριθμός μπροστά από κάθε ψευδώνυμο χρήστη. Πρακτικά, θέλουμε να <strong><em>φιλτράρουμε</em></strong> τα ψευδώνυμα των σχολίων των άρθρων μας και να αλλάξουμε την εμφάνισή τους. Η λέξη κλειδί είναι προφανώς το «φιλτράρουμε» και συνδυάζεται με τα όσα έχουμε πει ως τώρα (προφανώς) με τα filters των WordPress plug-ins.</p><p>Άρα λοιπόν θέλουμε να δημιουργήσουμε ένα filter στο WordPress plug-in που πρόκειται να κάνουμε το οποίο θα κάνει τη δουλειά που προαναφέραμε.</p><h1><strong>Ο σκελετός</strong></h1><p>Επειδή η μεθοδικότητα είναι το κλειδί σε κάθε επιτυχημένη διαδικασία θα πάμε να δημιουργήσουμε προσεκτικά τον σκελετό του plug-in μας. Προς αποφυγήν παρεξηγήσεων τονίζω ότι ο σκελετός που θα δημιουργηθεί, μπορεί να αποτελέσει τον σκελετό για οποιοδήποτε plug-in θα επιχειρήσουμε να κάνουμε από εδώ και πέρα (δώστε προσοχή, μπορεί να το θεωρήσω δεδομένο στο μέλλον J ).</p><p>Α. <span
style="text-decoration: underline;">Δομή του </span><span
style="text-decoration: underline;">plug</span><span
style="text-decoration: underline;">-</span><span
style="text-decoration: underline;">in</span><span
style="text-decoration: underline;"> (σε επίπεδο συστήματος αρχείων)</span></p><p>Δημιουργούμε τους κατάλληλους καταλόγους και αρχέια</p><p>numberedAuthorComments/ (κατάλογος)</p><p>css/ (κατάλογος)</p><p>images/ (κατάλογος)</p><p>js/ (κατάλογος)</p><p>php/ (κατάλογος)</p><p>numberedAuthorsComments.php</p><p><span
style="text-decoration: underline;">ΠΡΟΣΟΧΗ</span>:</p><ul><li>Η ονομασία του εξωτερικού φακέλου πρέπει να συμφωνεί με την ονομασία του αρχείου php</li><li>Για τις ανάγκες του plug-in που πάμε να υλοποιήσουμε δεν θα χρειαστεί να χρησιμοποιήσουμε τους καταλόγους css, images, js, php. Παρόλα αυτά είναι καλή πρακτική να συνηθίσετε να χρησιμοποιείται αυτή την αρχιτεκτονική καταλόγων και αρχείων που δύναται να φιλοξενήσει το μεγαλύτερο μέρος των αναγκών ενός WordPress plug-in, εν γένει.</li></ul><p>Β. <span
style="text-decoration: underline;">Δομή και αρχιτεκτονική του </span><span
style="text-decoration: underline;">numberedAuthorComments</span><span
style="text-decoration: underline;">.</span><span
style="text-decoration: underline;">php</span></p><p>Το numberedAuthorComments.php θα είναι το αρχείο που θα φιλοξενήσει την συνολική λειτουργικότητα του plug-in μας. Ας δούμε τη δομή του:</p><pre name="code" class="php">
&lt;?php
/*
Plugin Name: numberedAuthorsComments
Plugin URI: http://www.newsfilter.gr
Version: v0.5
Author: &lt;a href=”http://krap.gr/”&gt;Apostolos Kritikos&lt;/a&gt;
Description: This is my first plugin. Please don't be too hard on me if it crushes...
*/
</pre><p>Σε αυτό το σημείο δηλώνεται η ταυτότητα του plug-in (όνομα, ιστοσελίδα του plug-in, έκδοση, συγγραφέας και περιγραφή). Είναι απαραίτητο όλες αυτές οι πληροφορίες να εσωκλείονται σε /* … */.</p><pre name="code" class="php">
if(!class_exists('numberedAuthorsComments')) {
class numberedAuthorsComments {
function numberedAuthorsComments() { //κατασκευαστής
}
function addNumbers($author='') {
}
}
} //τέλος κλάσης
</pre><p>Ο παραπάνω έλεγχος if(…) έχει διπλό χαρακτήρα. Αφενός ελέγχει αν υπάρχει άλλο plug-in με την ίδια ονομασία (ώστε να αποφευχθούν συγκρούσεις) και, αν δεν υπάρχει εκτελεί το περιεχόμενο της κλάσης numberedAuthorComments.</p><pre name="code" class="php">
if(class_exists('numberedAuthorsComments')) {
$myplugin = new numberedAuthorsComments();
}
</pre><p>Αντιστοίχως, με έναν δεύτερο έλεγχο, τσεκάρουμε αν η κλάση numberedAuthorsComments υπάρχει και αν ναι, δημιουργούμε ένα αντικείμενό της, το οποίο στο παράδειγμά μας ονομάσαμε myplugin. Εν γένει, το αντικείμενο αυτό συγκεντρώνει μέσα του όλη τη λειτουργικότητα που περιλαμβάνει το plug-in που κατασκευάσαμε.</p><pre name="code" class="php">
if(isset($myplugin))  {
//Actions
//. . .
//Filters
//. . .
}
?&gt;
</pre><p>Ο τελευταίος αυτός έλεγχος εξετάζει αν το αντικείμενο στο οποίο αναφερθήκαμε πριν και, αν υπάρχει, αναλαμβάνει να εκτελέσει τη λειτουργικότητα του plug-in. Εφόσον, μέχρι στιγμής έχουμε δει μόνον τη χρήση actions και filters, η λειτουργικότητα στην οποία αναφερθήκαμε μπορεί να περιλαμβάνει μόνον αυτές τις δύο ομάδες χαρακτηριστικών. Αργότερα θα εμπλουτίσουμε με περισσότερα.</p><p>Στο συγκεκριμένο plug-in που προσπαθούμε να κατασκευάσουμε, χρειαζόμαστε ένα φίλτρο που θα προσθέτει έναν αριθμό μπροστά από το ψευδώνυμο κάθε συγγραφέα σχολίου σε κάθε άρθρο του blog μας. Στο επόμενο άρθρο θα δούμε πως υλοποιείται το φίλτρο αυτό, τι πρέπει να δηλωθεί και σε ποια σημεία του σκελετού που κατασκευάσαμε σήμερα.</p><p>Μέχρι τότε&#8230;</p><p><em>να είστε καλά και να προσέχετε τον εαυτό σας!</em></p><blockquote><p
style="text-align: center;">Μπορείτε να κατεβάσετε τα αρχεία του βοηθήματος εδώ</p><p
style="text-align: center;"><a
href="http://static.greektuts.net/uploads3/2010/08/numberedAuthorsComments.zip"><img
class="size-full wp-image-4135 aligncenter" src="http://static.greektuts.net/uploads/2009/10/membersdownload1.png" alt="" /></a></p></blockquote> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/wordpress-plugins-from-threory-to-reality-part1/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>WordPress Plug-in: Actions και Filters</title><link>http://greektuts.net/wordpress-plugin-actions-and-filters/</link> <comments>http://greektuts.net/wordpress-plugin-actions-and-filters/#comments</comments> <pubDate>Sun, 18 Jul 2010 09:00:36 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Wordpress]]></category> <category><![CDATA[filters]]></category> <category><![CDATA[krap]]></category> <category><![CDATA[plugin]]></category> <category><![CDATA[wordpress plugin]]></category> <category><![CDATA[απόστολος]]></category> <category><![CDATA[δημιουργία πρόσθετου]]></category> <category><![CDATA[κρητικός]]></category> <category><![CDATA[πρόσθετο]]></category> <category><![CDATA[φίλτρα]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4076</guid> <description><![CDATA[Στο προηγούμενο εισαγωγικό άρθρο, κάναμε την εισαγωγή στην διαδικασία δημιουργίας ενός Plugin για το Wordpress. Σε αυτό το μέρος θα πάρουμε μια γεύση από την πραγματική δύναμη των WordPress plugins ελέγχοντας το περιεχόμενο της WordPress εγκατάστασής μας.]]></description> <content:encoded><![CDATA[<p>Έχοντας μάθει πως να κατασκευάζουμε τον σκελετό ενός WordPress plug-in ήρθε η ώρα να συνεχίσουμε με πιο ενδιαφέροντα πράγματα.</p><h1><strong>Actions και Filters. Πως αρχικοποιώ;</strong></h1><pre name="code" class="php">
if(isset($myPlugin))  {
//Actions
//Filters
}
</pre><p>Απλό έτσι; Το μόνο που χρειάζεται κάνετε είναι να ελέγξετε ότι ένα αντικείμενο τύπου myTestPlugin έχει δημιουργηθεί (κατ&#8217; επέκταση φυσικά ελέγχετε και ότι το plug-in έχει εγκατασταθεί και αρχικοποιηθεί σωστά).</p><h1><strong>WordPress Actions</strong></h1><p>Ας προσπαθήσουμε να γεμίσουμε τα κενά κάτω από τα σχόλια. Ξεκινούμε με τις Actions (//Actions).</p><p>Για να δημιουργήσουμε μία action θα πρέπει σε πρώτη φάση να κατασκευάσουμε μία συνάρτηση (function) για το plug-in μας.</p><pre name="code" class="php">
function testFunction() {
?&gt;
&lt;!-- just a comment --&gt;
&lt;?php
}
</pre><p>Όπως μπορείτε να καταλάβετε η παραπάνω συνάρτηση απλά προσθέτει ένα comment&#8230; και τίποτε άλλο. Ας δούμε πως την καλούμε.</p><p>Χρειαζόμαστε μία action. Επομένως&#8230;</p><pre name="code" class="php">
if(isset($myPlugin)) {
//Actions
add_action('wp_head', array(&amp;$myPlugin, 'testFunction'), 1);
//Filters
}
</pre><p>δηλαδή&#8230;</p><p>η πλήρης σύνταξη της add_action() σύμφωνα με το WordPress Plugin API είναι add_action(&#8216;hook_name&#8217;, array(&amp;$myPlugin,&#8217;myFunction&#8217;), PRIORITY);</p><ul><li>hook_name: το όνομα με το οποίο θέλουμε να καλούμε την action (σε κάποιο σημείο της wordpress εγκατάστασής μας).</li><li>array(&#8230;): πίνακας με την ταυτότητα του action</li><li>&amp;$myPlugin: αναφορά στην μεταβλητή / αντικείμενο της κλάσης που αντιπροσωπεύει το plug-in μας</li><li>MyFunction: η συνάρτηση που επιθυμούμε να καλέσουμε</li><li>PRIORITY: προτεραιότητα εκτέλεσης. Τα μικρά νούμερα εκτελούνται γρηγορότερα</li></ul><h1><strong>Πως το τρέχω;</strong></h1><p>Όπως αναφέραμε στο προηγούμενο άρθρο μας. Αφότου το plugin εγκατασταθεί χωρίς πρόβλημα, ενεργοποιώντας το, το σχόλιο που περιλαμβάνεται στην testFunction θα εμφανιστεί στο πάνω μέρος της κεντρικής ιστοσελίδας της WordPress εγκατάστασής μας.</p><h1><strong>Αφαίρεση των actions</strong></h1><p>Οι actions μπορούν να αφαιρούνται δυναμικά, ακριβώς όπως δημιουργούνται κάνοντας χρήση της ακόλουθης σύνταξης:</p><pre name="code" class="php">
remove_action('action_hook','action_function')
</pre><ul><li>hook_name: το όνομα με το οποίο θέλουμε να καλούμε την action (σε κάποιο σημείο της wordpress εγκατάστασής μας).</li><li>MyFunction: η συνάρτηση που επιθυμούμε να καλέσουμε</li></ul><h1><strong>WordPress Filters</strong></h1><p>Τα WordPress filters αποτελούν συναρτήσεις που είναι υπεύθυνες για αλλαγές κειμένου. Η ανάγκη για την αλλαγή κειμένου πηγάζει είτε από την ανάγκη να το εισάγουμε σε μία βάση δεδομένων, είτε από την ανάγκη να το εμφανίσουμε στον χρήστη.</p><h1><strong>Τι μπορώ να αλλάξω χρησιμοποιώντας filters;</strong></h1><ul><li>Άρθρα</li><li>Σχόλια</li><li>Feeds, κ.α.</li></ul><h1><strong>Filter περιεχομένου</strong></h1><p>Είπαμε ότι τα filters αποτελούν ουσιαστικά συναρτήσεις. Ένα πολυ ενδιαφέρον filter είναι το &#8216;the_content&#8217;. Αυτό που ουσιαστικά κάνει είναι να επεμβαίνει στο κείμενο ενός άρθρου. Στο παράδειγμα που ακολουθεί θα χρησιμοποιήσουμε το filter περιεχομένου για να προσθέτουμε μία γραμμή στο τέλος κάθε άρθρου.</p><p>Σύμφωνα με το WordPress Plugin API η σύνταξη της add_filter είναι η ακόλουθη:</p><pre name="code" class="php">
add_filter('hook_name','my_filter',[priority],[accepted_args]);
</pre><p>Ας φτιάξουμε για αρχή την συνάρτηση που θα προσθέτει την έξτρα γραμμή:</p><pre name="code" class="php">
function addLine($content=”) {
$content .= “&lt;p&gt;My text goes here&lt;/p&gt;”;
return $content;
}
</pre><ul><li>Αρχικά δηλώνεται η συνάρτηση η οποία παίρνει σαν όρισμα μία μεταβλητή</li><li>Αν δεν δοθεί κείμενο κατά την κλήση της, δίδεται μία default τιμή</li><li>Στο κείμενο που δόθηκε (ή η default τιμή αν δε δόθηκε τίποτε) προστίθεται η γραμμή που θέλουμε να τελειώνει το post (στην περίπτωσή μας  “My text goes here”)</li><li>Τέλος, επιστρέφεται το αλφαριθμητικό στην τελική του μορφή.</li></ul><p>Στην συνέχεια θα πρέπει να εκτελέσουμε την συνάρτηση μας αυτή κάνοντας χρήση του filter &#8216;the_content&#8217;. Κάνοντας χρήση του κώδικα που έχουμε ως τώρα, μετά την προσθήκη του filter θα μοιάζει κάπως έτσι:</p><pre name="code" class="php">
if(isset($myPlugin)) {
//Actions
add_action('wp_head', array(&amp;$myPlugin, 'testFunction'), 1);
//Filters
add_filter('the_content', array(&amp;$myPlugin,'addLine'));
}
</pre><p>Εφόσον το plugin εγκατασταθεί και ενεργοποιηθεί, στο τέλος κάθε άρθρου θα πρέπει να βλέπετε τουλάχιστον ( <img
src='http://greektuts.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) την έξτρα γραμμή.</p><h1><strong>Filter συγγραφεά</strong></h1><p>Όπως είπαμε τα filters μπορούν να προσφέρουν μεγάλη λειτουργικότητα. Πριν κλείσουμε λοιπόν το άρθρο θα δημιουργήσουμε ακόμη ένα φίλτρο, προσανατολισμένο στους συγγραφείς σχολίων αυτή τη φορά.</p><p>Όπως και πριν, χρειαζόμαστε μία συνάρτηση:</p><pre name="code" class="php">
function authorFunction($author=”) {
return strtoupper($author);
}
</pre><ul><li>Αρχικά δηλώνεται η συνάρτηση η οποία παίρνει σαν όρισμα μία μεταβλητή  (στην συγκεκριμένη περίπτωση το όνομα το συγγραφέα)</li><li>Αν δεν δοθεί κείμενο κατά την κλήση της, δίδεται μία default τιμή</li><li>Το περιεχόμενο της μεταβλητής (στην συγκεκριμένη περίπτωση ο συγγραφέας του σχολίου, επιστρέφεται με κεφαλαία γράμματα</li></ul><p>Αυτό που πρέπει να κάνουμε τώρα είναι να επιβάλουμε στην παραπάνω συνάρτηση να τρέξει κατά την συγγραφή ενός σχολίου από κάποιον συγγραφέα. Για τον λόγο αυτό θα χρησιμοποιήσουμε το get_comment_author filter.</p><pre name="code" class="php">
if(isset($myPlugin)) {
//Actions
add_action('wp_head', array(&amp;$myPlugin, 'testFunction'), 1);
//Filters
add_filter('the_content', array(&amp;$myPlugin,'addLine'));
add_filter('get_comment_author',array(&amp;$myPlugin, authorFunction));
}
</pre><p>Ως συνήθως, αν εγκαταστήσετε και ενεργοποιήσετε το plugin, στο εξής, θα πρέπει τα ονόματα των συγγραφέων των σχολίων από εδώ και στο εξής να εμφανίζονται σε κεφαλαία γράμματα.</p><p>Στο σημερινό μας άρθρο, πήραμε μια γεύση από την πραγματική δύναμη των WordPress plugins ελέγχοντας το περιεχόμενο της WordPress εγκατάστασής μας. Ωστόσο, βρισκόμαστε ακόμη στην αρχή. Μείνετε συντονισμένοι για το επόμενο άρθρο της σειράς. Μέχρι τότε&#8230;</p><p><em>να είστε καλά και να προσέχετε τον εαυτό σας!</em></p><p><em>[<strong>Πηγή</strong>:</em><a
href="http://www.devlounge.net/extras/how-to-write-a-wordpress-plugin" target="_blank"><em>Devlounge</em></a><em>]</em></p> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/wordpress-plugin-actions-and-filters/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>WordPress Plug-in: Δομή &amp; Αρχιτεκτονική</title><link>http://greektuts.net/wordpress-plugin-structure-and-architecture/</link> <comments>http://greektuts.net/wordpress-plugin-structure-and-architecture/#comments</comments> <pubDate>Wed, 14 Jul 2010 07:18:35 +0000</pubDate> <dc:creator>krap</dc:creator> <category><![CDATA[Plugins-Πρόσθετα]]></category> <category><![CDATA[Wordpress]]></category> <category><![CDATA[plugin]]></category> <category><![CDATA[wordpress plugin]]></category> <category><![CDATA[wordpress-plugin-structure-and-architecture]]></category> <category><![CDATA[δημιουργία πρόσθετου]]></category> <category><![CDATA[πρόσθετο]]></category> <guid
isPermaLink="false">http://greektuts.net/?p=4064</guid> <description><![CDATA[“Η αρχή είναι το ήμισυ του παντός”. Έχοντας αυτό το μότο στο μυαλό μας θα κάνουμε σήμερα την πρώτη μας εισαγωγή στην δημιουργία προσθέτων (plug-ins) στο WordPress από το μηδέν. Σε αργότερα βοηθήματα θα δούμε όλα όσα χρειάζεται να ξέρουμε για να δημιουργήσουμε το δικό μας Plugin]]></description> <content:encoded><![CDATA[<p>Στην παρούσα φάση δεν υπάρχουν προαπαιτούμενα.</p><h1><strong>Πως λειτουργεί;</strong></h1><p>Ας ξεκινήσουμε με μια μίνι αναφορά στο πως εγκαθιστούμε ένα WordPress plug-in το οποίο έχουμε κατασκευάσει (μπορεί να σας φαίνεται ότι προτρέχω, αλλά πιστέψτε με είναι πολύ σημαντικό να γνωρίζεται πως λειτουργεί πραγματικά αυτή η διαδικασία πριν ξεκινήσετε να κατασκευάζετε το πρώτο σας plug-in).</p><ol><li>Τοποθετούμε το plug-in στον φάκελο “wp-content/plugins/” (μετά από αυτό το βήμα το plug-in μας πρέπει να είναι έτοιμο για εγκατάσταση – να φαίνεται  δηλαδή στη λίστα με τα διαθέσιμα προς εγκατάσταση plug-ins – ).</li><li>Όταν το plug-in ενεργοποιείται πρακτικά ζητά από το WordPress να φορτώσει τον κώδικα σε κάθε μια από τις σελίδες (συμπεριλαμβανομένης και αυτής του διαχειριστή). <span
style="text-decoration: underline;">ΠΡΟΣΟΧΗ</span>: Όταν ενεργοποιείται πολλά plug-ins, η εγκατάσταση του WordPress σας ενδέχεται να λειτουργεί πολύ πιο αργά.</li></ol><p>Αφότου εκτελεστούν τα δύο ανωτέρω βήματα θα πρέπει το plug-in σας να είναι εγκατεστημένο και σε λειτουργία.</p><p>Πριν προχωρήσουμε στα ζητήματα δομής και αρχιτεκτονικής ενός WordPress plug-in θεωρούμε δόκιμο να αναφέρουμε μερικές ακόμη ενδιαφέρουσες λειτουργίες που μπορούν να επιτευχθούν από ένα WordPress plug-in.</p><ul><li>Δεδομένου ότι το WordPress  plug-in φορτώνει τον κώδικά σας αυτόματα, σας επιτρέπει να επιτύχετε διάδραση τόσο με το WordPress plug-in API όσο και με τα tags των WordPress Templates (δυνατότητα χρήσης των υπαρχόντων ή / και δημιουργία νέων).</li><li>Αν σκοπεύετε να εκτελέσετε αλλαγές στο περιεχόμενο των άρθρων ή στα σχόλια, θα πρέπει να μελετήσετε τα σχετικά με το <a
href="http://codex.wordpress.org/The_Loop">WordPress Loop</a>. Μπορείτε να ελέγξετε τη συμπεριφορά του κώδικα και που αυτός τρέχει κάθε φορά, χρησιμοποιώντας actions και filters (για τα οποία θα μιλήσουμε αναλυτικότερα σε επόμενο άρθρο).</li></ul><h1><strong>Δομή του plug-in: Αρχείο ή φάκελος;</strong></h1><p>Η αλήθεια είναι ότι δεν υπάρχει σωστό και λάθος. Ένα WordPress plug-in μπορεί να αποτελείται απλά από ένα αρχείο php ή από μία πιο σύνθετη δομή, ένα κατάλογο αρχείων. Ας δούμε ένα παράδειγμα ενός τέτοιου καταλόγου:</p><ul><li>ΟΝΟΜΑ_ΚΑΤΑΛΟΓΟΥ (δηλαδή το όνομα του plug-in)</li><li>◦          ΟΝΟΜΑ_ΚΑΤΑΛΟΓΟΥ.php (υποχρεωτικά)</li><li>◦          ΦΑΚΕΛΟΣ js (φάκελος που θα περιέχει αρχεία javascript &#8211; προαιρετικά)</li><li>◦          ΦΑΚΕΛΟΣ css (φάκελος που θα περιέχει αρχεία css – προαιρετικά)</li><li>◦          ΦΑΚΕΛΟΣ php (φάκελος που θα περιέχει άλλα αρχεία php – προαιρετικά)</li><li>◦          ΦΑΚΕΛΟΣ images (φάκελος που θα περιέχει εικόνες &#8211; προαιρετικά)</li></ul><p>ή</p><ul><li>myTestPlugin/</li><li>◦          myTestPlugin.php</li><li>◦          js/</li><li>◦          css/</li><li>◦          php/</li><li>◦          images/</li></ul><h1><strong>Κυρίως αρχείο (δομή)</strong></h1><p>Όσοι έχετε μία κάποια οικειότητα με το WordPress θα έχετε προσέξει ότι στον τομέα των plug-ins (λίστα με τα διαθέσιμα plug-ins) παρέχονται διάφορες πληροφορίες για τα plug-ins αυτά (όνομα, έκδοση, περιγραφή, κατάσταση). Αν δεν ξέρετε ήδη πως παρέχονται αυτές οι πληροφορίες στη μηχανή του WordPress δεν θα το μαντέψετε ποτέ:</p><pre name="code" class="php">
&lt;?php
/*
Plugin Name: My Fiirst Plug-In
Plugin URI: <a href="http://www.mypersonalsite.gr/">http://www.mypersonalsite.gr</a>
Version: v1.00
Author: &lt;a href=”<a href="http://krap.gr/">http://krap.gr/</a>”&gt;Apostolos Kritikos&lt;/a&gt;
Description: This is my first plugin. Please don't be too hard on me if it crushes.
</pre><p>Ναι! Είναι σχόλια! Με τις παραπάνω 7 γραμμές οφείλει να αρχίζει κάθε WordPress Plug-in που σέβεται τον εαυτό του.</p><h1><strong>Σχόλια; ΟΚ&#8230; Και το plug-in πότε το κατασκευάζω;</strong></h1><p>Για την δημιουργία του λειτουργικού τμήματος του plug-in απαιτείται χρήση κλάσεων PHP. Αν και η πρότερη γνώση προγραμματισμού PHP κλάσεων θα βοηθούσε πολύ, δεν θεωρείται απαραίτητη γνώση για την παρακολούθηση του παρόντος άρθρου.</p><p>Για αρχή απαιτείται να εξασφαλίσουμε ότι δεν υπάρχει άλλο plug-in με το  ίδιο όνομα εγκατεστημένο στο WordPress σύστημά μας. Ο συγκεκριμένος έλεγχος επιτυγχάνεται με τον παρακάτω κώδικα:</p><pre name="code" class="php">
if(!class_exists(“myTestPlugin”)) {
class myTestPlugin {
function myTestPlugin() { //κατασκευαστής
}
}
} //τέλος κλάσης
</pre><p>Εφόσον λοιπόν μια κλάση με όνομα ταυτόσημο με αυτό του δικού μας plug-in  δεν υπάρχει, δημιουργείται.</p><pre name="code" class="php">
if(class_exists(“myTestPlugin”)) {
$myPlugin = new myTestPlugin();
}
</pre><p>Ο παραπάνω κώδικας  αναλαμβάνει να αρχικοποιήσει ένα στιγμιότυπο της κλάσης που δημιουργήσαμε νωρίτερα. Μετά την εκτέλεση του τμήματος αυτού η  μεταβλητή $myPlugin αποτελεί ένα αντικειμένο τύπου myTestPlugin δήλαδή της κλάσης που υλοποιεί την λειτουργικότητα του plugin μας.</p><p>Όπως είπαμε στην αρχή του άρθρου, η αρχή είναι το ήμισυ του παντός. Με τον κώδικα που παρουσιάσαμε σε αυτό το άρθρο ο αναγνώστης καταλήγει με έναν πλήρες σκελετό ο οποίος μπορεί να χρησιμοποιηθεί για την υλοποίηση ενός εντελώς λειτουργικού plugin.</p><p>Την επόμενη φορά (spoiler alert <img
src='http://greektuts.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) θα μιλήσουμε  για το πως υλοποιούμε actions και  filters για αυτό, μείνετε συντονισμένοι. Μέχρι τότε&#8230;</p><p><em>να είστε καλά και να προσέχετε τον εαυτό σας!</em></p><p><em>[<strong>Πηγή</strong>:</em><a
href="http://www.devlounge.net/extras/how-to-write-a-wordpress-plugin"><em>Devlounge</em></a><em>]</em></p> ]]></content:encoded> <wfw:commentRss>http://greektuts.net/wordpress-plugin-structure-and-architecture/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
