Δευτέρα, 19 Φεβρουαρίου 2018

Αναθεώρηση 47 Έκδοση 9,0

Σε αυτήν την αναθεώρηση έφτιαξα το σύστημα για τις βάσεις δεδομένων να αλλάζει αυτόματα αν δεν μπορεί να φορτώσει μια βάση δεδομένων από Access 97 (αλλάζει αυτόματα το τρόπο σύνδεσης).
Με αυτόν τον τρόπο διαβάζονται και οι παλιές βάσεις δεδομένων που ήταν φτιαγμένες σε Jet.
Δουλεύει και σε Wine 1.8 σε 64 bit (όχι όμως σε Wine 3.0 64bit)


Σε Linux εκτελούμε από κονσόλα αυτό:
wine odbcad32.exe


 Αυτό μας δείνχει τι υποστηρίζει το σύστημα!
Εδώ είναι ένα παράδειγμα χρήσης της παραπάνω φόρμας για σύνδεση με βάση δεδομένων. Θα δούμε πώς γίνεται να συνδεθούμε μέσω ODBC με την Μ2000. Δουλεύει σε wine 1.8 και σε Windows (οποιαδήποτε έκδοση αρκεί να βλέπουμε στο odbcad32.exe ότι υποστηρίζει την Access Database).
Προσπαθήστε να εκτελέσεται το παράδειγμα. Σε ένα τμήμα Α θα φτιάξουμε τη βάση και σε ένα τμήμα Β αφού μεταφέρουμε τη βάση (σε wine δεν χρειάζεται) θα την συνδέσουμε μέσω ODBC.
Βάζοντας το accdb δημιουργούμε βάση νέου τύπου, και μπορούμε να βάζουμε τα πεδία με την Εκτέλεση.


ΒΑΣΗ "ΑΛΦΑ.accdb"  ' ΔΙΑΓΡΑΦΟΥΜΕ ΑΝ ΒΡΟΥΜΕ ΤΟ ΟΝΟΜΑ
ΕΚΤΕΛΕΣΗ "ΑΛΦΑ.accdb", { CREATE TABLE Employees(ID autoincrement primary key,  LastName   VARCHAR(40) ,  FirstName  VARCHAR(40)  NOT NULL, MyMemo TEXT )}
ΠΡΟΣΘΗΚΗ "ΑΛΦΑ.accdb","Employees",,"George","йваоаптаЭЭ","Γεια χαρά από Ελλάδα"
ΑΝΑΚΤΗΣΗ "ΑΛΦΑ.accdb", "Employees", 1,"",""
ΔΙΑΒΑΣΕ ΠΟΣΑ, ΑΝΑΓΝΩΡΙΣΤΙΚΟ, ΕΠΙΘΕΤΟ$, ΟΝΟΜΑ$, ΣΤΟΙΧΕΙΑ$
ΤΥΠΩΣΕ $(4, 6),  "Βάση:","ΑΛΦΑ.accdb"
ΤΥΠΩΣΕ  "ΟΝΟΜΑ:",ΟΝΟΜΑ$ + " " + ΕΠΙΘΕΤΟ$
ΤΥΠΩΣΕ "ΣΤΟΙΧΕΙΑ:"
ΤΥΠΩΣΕ "",
ΑΝΑΦΟΡΑ ΣΤΟΙΧΕΙΑ$
ΚΛΕΙΣΕ ΒΑΣΗ "ΑΛΦΑ.accdb"
ΤΥΠΩΣΕ


Τώρα μπορούμε σε ένα τμήμα Β (το προηγούμενο έστω ότι ήταν το Α) να δώσουμε αυτό:

ΒΑΣΗ.ΠΑΡΟΧΟΣ "dsn=testthis;Uid=a;Pwd=b;","ODBC","100101"
ΑΝΑΚΤΗΣΗ "(any)", "Employees", 1,"",""
ΔΙΑΒΑΣΕ ΠΟΣΑ, ΑΝΑΓΝΩΡΙΣΤΙΚΟ, ΕΠΙΘΕΤΟ$, ΟΝΟΜΑ$, ΣΤΟΙΧΕΙΑ$
ΤΥΠΩΣΕ $(4, 6),  "Βάση"
ΤΥΠΩΣΕ  "ΟΝΟΜΑ:",ΟΝΟΜΑ$ + " " + ΕΠΙΘΕΤΟ$
ΤΥΠΩΣΕ "ΣΤΟΙΧΕΙΑ:"
ΤΥΠΩΣΕ "",
ΑΝΑΦΟΡΑ ΣΤΟΙΧΕΙΑ$
ΚΛΕΙΣΕ ΒΑΣΗ "(any)"
ΤΥΠΩΣΕ
ΒΑΣΗ.ΠΑΡΟΧΟΣ ""

Το 100101 είναι το βασικό "συνθηματικό" για την Μ2000. Όμως μπορούμε να φτιάξουμε μια σύνδεση ODBC. Αυτό κάνει το πρόγραμμα παραπάνω. Το testthis το φτιάχνουμε στο odbcad32.exe
Δείτε ότι το όνομα της βάσης στην Ανάκτηση έγινε κάτι σε παρένθεση. Ότι και να βάλουμε από τη στιγμή που βλέπει την παρένθεση ο διερμηνευτής καταλαβαίνει ότι έχουμε σύνδεση έμμεση μέσω ODBC, που σημαίνει ότι έχει ήδη δοθεί στο ΒΑΣΗ.ΠΑΡΟΧΟΣ τα τρία απαιτούμενα στοιχεία (το τελευταίο αν η βάση δεν είναι κλειδωμένη θα πρέπει να είναι "", για τις βάσεις της Μ2000 δεν ισχύει αυτό, είναι κλειδωμένες για να μπορεί να ξέρει η Μ2000 ποιες βάσεις είναι δικές της- έχουν το ίδιο κλειδί- ώστε να μην διαγράφει μια ξένη βάση).
Σε Windows 7 πρέπει να αντιγράψουμε το αρχείο ΑΛΦΑ.accdb σε ένα φάκελο που να μπορεί να το διαβάσει το  odbcad32.exe. Σε wine το διαβάζει στο φάκελο που βάζει η M2000 τα αρχεία προγραμμάτων και άλλων βοηθητικών όπως αυτών των βάσεων δεδομένων.
Με την εντολή WIN DIR$ μας ανοίγει το φάκελο αυτό. Το Dir$ έχει το φάκελο. Ελληνικά είναι το Κατ$
σε Wine αν ο χρήστης λέγεται person τότε είναι αυτό
c:\users\person\application data\m2000\
αλλά για να το δούμε με του linux τον file explorer (πχ το thunar) θα το βρούμε έτσι: /home/person/.wine/drive_c/users/person/Application Data/m2000/
(οι φάκελοι με την τελεία είναι κρυφοί, και για να εμφανιστούν πατάμε το ctrl + H)
Ακόμα και αν δεν είναι φανερός ο .wine φάκελος μπορούμε να δώσουμε το παραπάνω και θα μας ανοίξει το φάκελο.
Σε Windows 7 θα πάμε στο φάκελο και θα αντιγράψουμε το ΑΛΦΑ.accdb σε έναν φάκελο όπως C:\myfiles\
Σε Wine 1.8 θα γράψουμε σε κονσόλα το wine odbcad32.exe και στη φόρμα USER DSN θα κάνουμε Add.
Εκεί δίνουμε το όνομα testthis
Μετά επιλέγουμε Select και εκεί βρίσκουμε το αρχείο στο users/person/Application Data/m2000/  (όπου person το user name στα Ubuntu)
Αφού κάνουμε επιλογή πατάμε το Advance και βάζουμε ένα user id και ένα password για την σύνδεση αυτή. Θα βάλουμε τα a και b, είναι αυτά που δίνουμε στα Uid και Pwd στην εντολή Βάση.Πάροχος

Τώρα είναι έτοιμη Μ2000 να τρέξει το τμήμα Β και να μας δείξει το περιεχόμενο που ζητάμε μέσω ODBC.
To $() στην τύπωσε παίρνει δυο αριθμούς, τον τρόπο εμφάνισης (0 το εξ ορισμού) και το πλάτος στήλης (εδώ 6). Η εντολή Φόρμα 60, 40 θα γυρίσει την στήλη στο στανταρ (το βγάζει με τύπο, εδώ θα είναι το δέκα)
Η Τύπωσε Στήλη μας δίνει το πλάτος στήλης.
Το 4 είναι ο τρόπος εμφάνισης μέσω της Τύπωσε με αναλογική γραφή. Το 0 είναι με μη αναλογική γραφή. Τα νούμερα είναι από 0 έως 9 και αλλάζουν τον τρόπο στοίχισης στις στήλες. Δείτε την βοήθεια στο $(). Επειδή το $() δεν είναι αναγνωριστικό κοινό, θα δώσουμε αυτό (με εισαγωγικά):
βοήθεια "$("
η βοήθεια βγαίνει ελληνική επειδή όταν δεν βγάζει άκρη από το όνομα, τότε κοιτάει τι γλώσσα ήταν το βοήθεια - μπορεί να ήταν Help "$(". Αν το δώσουμε πρώτα στα ελληνικά και μετά στα αγγλικά δεν θα αλλάξει, επειδή ήδη δείχνει το $(. Πρέπει να πάμε σε κάτι άλλο, πχ βοήθεια Τύπωσε και μετά να δώσουμε το Help "$("


Κυριακή, 18 Φεβρουαρίου 2018

M2000 Installation in Ubuntu

A new revision 46 with a new help2000.mdb is ready. This revision is same as 45 except for the new file and use ACE.12 not JET.4 as provider for ADO to connect.

To get mdb support in M2000 in ubuntu (help system has a mdb file) you have to use wine 1.8 (wine 3.0 can run M2000 but has no mdb support, or if anyone find a way just write bellow)

From console:
sudo apt-get install wine1.8 winetricks
wine wineboot
winetricks winecfg

Now open a dialog:
           1. choose windows 7 or 8.1
           2.library override oleaut32 (native)

From console:
winetricks vb6run art2kmin mdac28

From Menu Wine -> Explore C
Place M20000language.exe and execute it








For Installation in Windows we have to download Access 2007 runtime, from Microsoft.
Revision 46 is same as 45 except for the way that access help file. Revision 44 works using Jet.4 and Help2000.mdb has mdb version Access 97.


Πέμπτη, 15 Φεβρουαρίου 2018

Base64 Using Crypt32 in M2000 (rev 2)

This is an example of using functions of Windows to perform Base64 convertion for data. This code can run in Wine, Linux, but we can't use CRYPT_STRING_BASE64HEADER for CryptBinaryToString, so we turn it to
CRYPT_STRING_BASE64 (0x1)

We use Buffer, a special object which hold memory block, and return addresses to be used as pointers

We make module a from console typing Edit a and copy this:


Declare CryptStringToBinary Lib "Crypt32.CryptStringToBinaryW" {pszString$, Long cchString, Long dwFlags, Long pbBinary, Long pcbBinary, Long pdwSkip, long pdwFlags}
Declare CryptBinaryToString Lib "Crypt32.CryptBinaryToStringW" {Long pbBinary, Long cbBinary, Long dwFlags, Long pszString, Long pcchString}

Buffer Clear Buf1 as integer*1000
\\ Buf2 for output delcared after evaluation of output length
Buffer Clear Buf3 as Long
' so we get value at Buf3(2)-8 bytes in Buf3(0)
A$={Hello There, this is M2000 Interpreter,
            Yes No
            Hello There too
            Anything
            }
LengthInTchars=Len(A$)*2 ' as 2 bytes
Return Buf1, 0:=A$
CRYPT_STRING_BASE64HEADER=0x0
If IsWine then CRYPT_STRING_BASE64HEADER=0x1 ' no header - Wine has fault
\\ read length for output buffer
Print CryptBinaryToString(Buf1(0), LengthInTchars, CRYPT_STRING_BASE64HEADER, 0, Buf3(0))
Print Eval(Buf3, 0)
Buffer Clear Buf2 as Integer*Eval(Buf3, 0)
Print CryptBinaryToString(Buf1(0), LengthInTchars, CRYPT_STRING_BASE64HEADER, Buf2(0), Buf3(0))
ClipBoard Eval$(Buf2, 0, Eval(Buf3, 0)*2)
Report Eval$(Buf2, 0, Eval(Buf3, 0)*2)+"_Next Line_"    ' third parameter is size in bytes
M$=Eval$(Buf2, 0, Eval(Buf3, 0)*2)
Clear Buf1
Rem 1 : Print Len(Buf1) , " len is 0", Buf1(0)=0 ' is null
Buffer Clear Buf1 as integer*1000 ' now Buf1 cleared
Rem 2 : Print Len(Buf1) , " len is 2000", Buf1(0) ' is not null
Clear Buf3
Buffer Clear Buf3 as Long
Return Buf3, 0:=1000*2 ' number of bytes
Print CryptStringToBinary(M$, Len(M$), CRYPT_STRING_BASE64HEADER, Buf1(0), Buf3(0), 0,0)
Report Eval$(Buf1, 0,Eval(Buf3,0)*2)+"_Next Line_"


The above module make in buf2 the convertion the convertion of buf1 binary data. Here out data are text, but can be anything. So we place text in Buf1 and first we call CryptBinaryToString() to get the length of output buffer. So we define Buf2 as output buffer. And then we call again
CryptBinaryToString() and we get the result. We place result to clipboard for later use and we print the result to console. After that we clear buffers buf1 and buf3 and make the reverse operation.

We can make a second module, say b, using edit b and place this code:

Declare CryptStringToBinary Lib "Crypt32.CryptStringToBinaryW" {pszString$, Long cchString, Long dwFlags, Long pbBinary, Long pcbBinary, Long pdwSkip, long pdwFlags}
const CRYPT_STRING_BASE64HEADER=0x0


A$={-----BEGIN CERTIFICATE-----
SABlAGwAbABvACAAVABoAGUAcgBlACwAIAB0AGgAaQBzACAAaQBzACAATQAyADAA
MAAwACAASQBuAHQAZQByAHAAcgBlAHQAZQByACwADQAKAFkAZQBzACAATgBvAA0A
CgBIAGUAbABsAG8AIABUAGgAZQByAGUAIAB0AG8AbwANAAoAQQBuAHkAdABoAGkA
bgBnAA0ACgA=
-----END CERTIFICATE-----
}
Buffer Clear Buf1 as integer*1000
Buffer Clear Buf3 as Long
Return Buf3, 0:=1000*2 ' number of bytes
\\ CryptStringToBinary() return 1 or 0. Not 0 is true for M2000
If CryptStringToBinary(A$, Len(A$), CRYPT_STRING_BASE64HEADER, Buf1(0), Buf3(0), 0,0) Then {
      Report Eval$(Buf1, 0,Eval(Buf3,0)*2)
}


For the above code we make a paste from clipboard and place Base64 string in A$. So we can make them back as binary data, and finally the string as for this example.

Κυριακή, 11 Φεβρουαρίου 2018

Αναθεώρηση 45 (Έκδοση 9.0)


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

Μπορούμε στα τμήματα και στις συναρτήσεις να βάζουμε κολλητά στα ονόματα την λίστα παραμέτρων (που είναι σε παρενθέσεις). Ουσιαστικά ότι βάζουμε εκεί θα γίνει μια Διάβασε και θα μπει σαν πρώτη γραμμή. Δείτε στο παράδειγμα στο τέλος την κανονική μορφή.
Ο Διερμηνευτής δεν ελέγχει τον αριθμό και τύπο παραμέτρων στην κλήση. Ο έλεγχος είναι θέμα αυτού που καλούμε να γίνει. Αν η Διάβασε έχει επιτυχία τότε προχωράει η εκτέλεση αλλιώς βγαίνει λάθος. Αυτό σημαίνει ότι μπορούμε να κάνουμε επιλογές βάσει αυτού που μας στέλνει η κλήση. Τα ορίσματα βρίσκονται στο σωρό τιμών και μπορούμε να τον επιθεωρήσουμε προγραμματιστικά. Πχ η συνάρτηση Ταύτιση("ΑΑ") γυρίζει -1 (Αληθές) αν στην κορυφή του σωρού υπάρχουν δυο αριθμοί. Δείτε το Βοήθεια Ταύτιση() για να δείτε όλα τα γράμματα που μπορούμε να χρησιμοποιήσουμε.
Στις συναρτήσεις βολεύει το κόλλημα, ενώ στα τμήματα δεν βολεύει γιατί υπάρχει αναζήτηση με τα F2 (πάνω) και F3 (κάτω) και όταν επιλέξουμε τμήμα θα επιλεγεί χωρίς παρένθεση, άρα θέλουμε με το πάνω να βρούμε τον ορισμό χωρίς παρένθεση. Στη συνάρτηση βολεύει να έχουμε παρένθεση γιατί συνήθως τις χρησιμοποιούμε με παρενθέσεις σε εκφράσεις ή στη Κάλεσε (καλείται σαν τμήμα). Υπάρχει μια διαμόρφωση της Κάλεσε που λέγεται Κάλεσε Συνάρτηση και ακολουθεί το όνομα χωρίς παρενθέσεις.

Συνάρτηση πέντε {
      Τύπωσε αριθμός*5, αριθμός*5
}
Κάλεσε Συνάρτηση Πέντε, 10,20

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

Βάλε 20, 10
Κάλεσε Συνάρτηση Πέντε

Τώρα περνάμε στο σωρό τιμές και μετά καλούμε τη συνάρτηση. Στην ουσία με την Κάλεσε ο τρέχον σωρός γίνεται και σωρός της συνάρτησης, κάτι που ισχύει στα τμήματα αλλά όχι στις συναρτήσεις αν τις καλέσουμε μέσα σε εκφράσεις, όπως παρακάτω η Δύο(). Αν στην Δύο() βάλουμε δέκα ορίσματα ακόμα, πχ Τύπωσε Δύο(3,1,2,3,4,5,6,7,8,9,10) τα επιπλέον θα περάσουν μόνο στο σωρό της συνάρτησης, και στην επιστροφή θα χαθούν, επειδή θα διαγραφεί και ο σωρός της συνάρτησης.
Και οι ρουτίνες χρησιμοποιούν το σωρό του τμήματος ή της συνάρτησης όπου βρίσκονται. Οι ρουτίνες επιπλέον έχουν θέαση στις μεταβλητές εκεί που βρίσκονται. Σε αντίθεση τα τμήματα και οι συναρτήσεις βλέπουν τις δικές τους μεταβλητές και τις γενικές. Υπάρχει δυνατότητα να δώσουμε θέαση στα τμήματα και τις συναρτήσεις (το έχουμε δει σε άλλες αναρτήσεις, και θα το ξαναδούμε και σε νεότερες). Παράδειγμα με θέαση που δίνουμε σε συνάρτηση:


Κ=10
Συνάρτηση Κ(Χ) {
      Τύπωσε Κ*Χ
}
Κάλεσε Τοπικά Κ(3)



Δεν μπορούμε να χρησιμοποιήσουμε σε εκφράσεις συναρτήσεις που πρέπει να κληθούν "τοπικά". Έκφραση λέμε την μαθηματική παράσταση πχ Κ(Χ)*3, αυτή θα γύρναγε 0 (αφού λείπει το = για την επιστροφή) αλλά θα βγάλει λάθος γιατί το Κ είναι άγνωστο. Αν το ορίσουμε ως γενική τότε θα το βλέπει. Εδώ κάνουμε μάλιστα την επιστροφή να γυρίζει και όχι να τυπώνεται, και την Κ(3) την δίνουμε στην Τύπωσε. Οι γενικές στην Μ2000 έχουν περιορισμένη ζωή. Μόλις το τμήμα που την δημιούργησε τερματίσει τότε χάνεται. Αν ένα τμήμα που καλούμε θέλει να έχει δική του τοπική Χ ή γενική Χ τότε σκιάζεται η υπάρχουσα Χ. Για να εκχωρήσουμε τιμή στη γενική Χ χρειάζεται το <= ενώ το απλό = θα φτιάξει μια τοπική Χ. Με το τρόπο αυτό οι γενικές δεν μπερδεύονται με τις τοπικές. Μπορούμε να ελέγχουμε αν υπάρχει μια μεταβλητή με την Έγκυρο(Χ) που θα δώσει -1 αν η Χ είναι θεατή.


Γενική Κ=10
Συνάρτηση Κ(Χ) {
      =Κ*Χ
}
Τύπωσε Κ(3)


Το παράδειγμα για την αναθεώρηση 45:



\\ Νέο από την αναθεώρηση 45
\\ Μπορούμε να κολλάμε την παρένθεση με το όνομα
Τμήμα Ένα(Χ) {
      Τύπωσε Χ+1
}
\\ καλούμε χωρίς παρένθεση
Ένα 3
Συνάρτηση Δύο(Χ) {
      =Χ*20
}
\\ Καλούμε με παρένθεση
Τύπωσε Δύο(3)
\\ Η Κάνε φτιάχνει συναρτήσεις μιας γραμμής, ήθελε και στις παλαιότερες αναθεωρήσεις να έχει κολλητά τις παρενθέσεις
Κάνε Τρια(Χ)=3*Χ
Τύπωσε Τρια(10)

\\ Πριν την αναθεώρηση 45, ισχύει ακόμα:
Τμήμα Ένα (Χ) {
      Τύπωσε Χ+1
}
Ένα 3
Συνάρτηση Δύο (Χ) {
      =Χ*20
}
Τύπωσε Δύο(3)

\\ Στην πραγματικότητα ο διερμηνευτής παίρνει τις παραμέτρους και βάζει μια Διάβασε
\\ Μπορούμε να τα φτιάξουμε και έτσι:
Τμήμα Ένα {
      Διάβασε Χ
      Τύπωσε Χ+1
}
Ένα 3
Συνάρτηση Δύο {
      Διάβασε Χ
      =Χ*20
}
Τύπωσε Δύο(3)




Πέμπτη, 8 Φεβρουαρίου 2018

Γρήγορη Ταξινόμηση ΙΙ (χρήση ρουτινών, προχωρημένο)

Η γρήγορη ταξινόμηση όπως δόθηκε σε προηγούμενη ανάρτηση έχει γραφτεί πιο κοντά σε άλλες γλώσσες προγραμματισμού. Στη Μ2000 μπορούμε να επιλέξουμε τι μεταβλητές θα σκιάσουμε. Εκτός από την "κλήση τοπικά" για μια συνάρτηση έχουμε και την κλήση ρουτίνας. Οι ρουτίνες έχουν εξ ορισμού θέαση μεταβλητών στο τμήμα που καλούνται. Επιπλέον επειδή είναι "ελαφρύτερες" από μια συνάρτηση ή ένα τμήμα, μπορούν να κληθούν με χρήση της μνήμης ως "στοίβα επιστροφής". Έτσι το όριο αναδρομής μπορεί να μεγαλώσει (αφού ουσιαστικά η στοίβα είναι δομή στη μνήμη με "τεμάχια" και όχι συνεχόμενη). Ορίζουμε όριο αναδρομής μόνο για τυπικούς λόγους, δηλαδή να υπάρχει τρόπος αν έχουμε λάθος στο πρόγραμμα να τερματίσει με λάθος, και όχι όταν πάρει όλη την μνήμη!

Αν προσέξουμε λίγο το κώδικα θα δούμε ότι μόνο δυο μεταβλητές, η Μ1 και Λ, δηλαδή τα σημεία που ορίζουν το άνω όριο στις δυο λίστες που χωρίζουν την λίστα, χρειάζεται να μπαίνουν σε σκίαση. Σκίαση σημαίνει ότι αποθηκεύονται ενώ δημιουργούνται στην ίδια θέαση νέες μεταβλητές. Οι ρουτίνες όταν τερματίζουν διαγράφουν ότι νέο φτιάχτηκε, έτσι επαναφέρουν τις προηγούμενες τιμές.

Μέσα στη ρουτίνα ΓρήγορηΤαξινόμηση(λ) το π είναι ένα και μοναδικό. Προς το τέλος καλούμε πάλι τη ρουτίνα, σε δυο φάσεις. Στην πρώτη το π το αφήνουμε ως έχει, και μας ενδιαφέρει μόνο μια φορά να είναι το σωστό μέχρι να καλέσουμε πάλι τη πρώτη εσωτερική. Στη δεύτερη το Μ1 έχει ξεκινήσει από το π και κοιτάμε αν είναι μικρότερο του λ και αν είναι τότε καλούμε τη συνάρτηση με την λ, άρα και εδώ η σκίαση της λ είναι πλεονασμός και θα μπορούσαμε να είχαμε μια δεύτερη ρουτίνα (ίδια με την ΓρήγορηΤαξινόμηση αλλά χωρίς να παίρνει το λ, δεν βάζω αυτή την ρουτίνα και την αφήνω να το κάνει ο αναγνώστης, και να αλλάξει κατάλληλα τη δεύτερη κλήση και στις δυο πια ρουτίνες)



\\ Πρόγραμμα Γρήγορη Ταξινόμηση  ΙΙ
\\ 1) Χρήση του συστήματος σκίασης, έτσι ώστε μόνο ορισμένες μεταβλητές να σκιάζονται
\\ 2) Χρήση ρουτινών για αναδρομή
\\ Για τις ρουτίνες το όριο αναδρομής ξεφεύγει από τις μερικές χιλιάδες και φτάνει στα εκατομμύρια.
Όριο.Αναδρομής 1000000 'μπορούμε να ορίσουμε όριο ακόμα και ένα εκατομμύριο κλήσεις.

Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ2, ρ, π
            ' όλα τα ρ τα ελέγχουμε επιτόπου
            ' όλα τα Μ2 σχετίζονται με το Λ και τα δημιουργούμε πριν την αναδρομή
            ' Τα π ξεκινούν από το 0 και μετά παίρνουν τιμές μια φορά ως έχει και μια φορά από το Μ1
            Τρόπος$="ΑΥΞΟΥΣΑ"
            ' αν δώδουμε ? τότε θα παραμείνει η τιμή ως έχει
            ' ακόμα και αν δεν δώσουμε κάτι δεν πειράζει την Μ2000, αρκεί να μη έχει κάτι άλλο ο σωρός τιμών.
            ' για το λόγο αυτό καλό είναι αν θέλουμε την εξ ορισμού τιμή να δώσουμε το ? στην κλήση
            ' Στις συναρτήσεις όταν καλούνται ως συναρτήσεις δεν υπάρχει θέμα γιατί έχουν δικό τους σωρό τιμών
            ' εδώ όμως είναι τμήμα και το τμήμα κληρονομεί το σωρό τιμών αυτού που το καλεί.
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε ΓρήγορηΤαξινόμηση(.πόσα-1)

            \\ υπάρχει μια ρουτίνα εδώ, και όταν ο διερμηνευτής φτάσει στον ορισμό τότε κάνει έξοδο!
            \\ οι ρουτίνες γράφονται στο τέλος του τμήματος.
            \\ Γίνεται αναζήτηση μια φορά και μετά καταγράφεται για να τρέχει άμεσα.
            \\ Οι ρουτίνες έχουν μεγάλο αριθμό κλήσεων με αναδρομή γιατί χρησιμοποιούν την μνήμη, και όχι το σωρό επιστροφής.
            \\ αρκεί να μην μεσολαβούν μπλοκ μνήμης.
            \\ εδώ δεν υπάρχει μπλοκ, οι κλήσεις γίνονται απ΄ευθείας μετά από μια Αν Τότε.
            Ρουτίνα ΓρήγορηΤαξινόμηση(λ)
                  '  το (λ)  στο όνομα ισοδυναμεί με αυτό: Διάβασε Νέο λ
                  ' το οποίο σκιάζει την υπάρχουσα λ με την χρήση του Νέο
                  Αν λ-π=1 Τότε {
                        Κάλεσε Γεγονός .ΘέσεΈνα λ
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                        Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
                        Έξοδος Ρουτίνας ' βγαίνουμε από την ρουτίνα με την Έξοδο Ρουτίνας παρόλο που είμαστε σε μπλοκ.
                  }
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Τοπική Μ1=π ' σκιάζει την υπάρχουσα Μ1 όταν ορίζεται ως Τοπική
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  ' Εδώ τα βρήκαμε!
                  Αν π<Μ2 Τότε ΓρήγορηΤαξινόμηση(Μ2)
                  π=Μ1 ' δεν μας ενδιαφέρει να κρατήσουμε το π
                  Αν Μ1<λ Τότε ΓρήγορηΤαξινόμηση(λ)
      Τέλος Ρουτίνας
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}

Με αναδρομή με χρήση απλών ρουτινών. Οι απλές ρουτίνες καλούνται με όνομα ή με αριθμό και επιστρέφουν με την Επιστροφή. Η βασική διαφορά τους με τις ρουτίνες με παρενθέσεις είναι ότι δεν σβήνουν ότι δημιουργούν άρα δεν μπορούμε να χρησιμοποιήσουμε σκίαση μεταβλητών. Εδώ λοιπόν φτιάχνουμε δυο μεταβλητές ως δείκτες σε σωρούς τιμών. Αντί να κάνουμε σκίαση τιμών, κάνουμε καταχώρηση σε σωρούς τιμών (ειδικές στοίβες), όπου με Βάλε βάζουμε στην κορυφή και με Διάβασε διαβάζουμε από τη κορυφή - αφαιρώντας αυτό που διαβάζουμε.
Εδώ η αναδρομή συνίσταται στο ότι καλεί η ρουτίνα τον εαυτό της. Η στοίβα επιστροφής τώρα είναι μικρότερη γιατί έχει μόνο την θέση επιστροφής, και όχι τα στοιχεία (δυο νούμερα στην ουσία επιπλέον) που διαγράφουν από ένα σημείο και μετά τα στοιχεία στις λίστες μεταβλητών και τμημάτων/συνάρτησεων (έτσι αφαιρεί την σκίαση η κλήση ρουτίνας με παρενθέσεις, ενώ η συνάρτηση και το τμήμα κρατούν στην πραγματική στοίβα επιστροφής τα στοιχεία αυτά. Η πραγματική στοίβα επιστροφής είναι αυτή του εκτελέσιμου αρχείου, του διερμηνευτή, της γλώσσας μηχανής δηλαδή).



Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ1, Μ2, ρ, π, λ, σΜ1, σλ
            σΜ1=Σωρός
            σλ=Σωρός
            Τρόπος$="ΑΥΞΟΥΣΑ"
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε λ=.πόσα-1: Διαμέσου ΓρήγορηΤαξινόμηση
            Έξοδος
ΓρήγορηΤαξινόμηση:
                  Αν λ-π=1 Τότε Διαμέσου 3000 : Επιστροφή
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Σωρός σΜ1 { Βάλε Μ1}
                  Μ1=π
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  ' Εδώ τα βρήκαμε!
                  Αν π<Μ2 Τότε Σωρός σλ { Βάλε λ} : λ=Μ2: Διαμέσου ΓρήγορηΤαξινόμηση : Σωρός σλ { Διάβασε λ}
                  π=Μ1 ' δεν μας ενδιαφέρει να κρατήσουμε το π
                  Αν Μ1<λ Τότε Διαμέσου ΓρήγορηΤαξινόμηση
                  Σωρός σΜ1 { Διάβασε Μ1}
                  Επιστροφή
      3000 Κάλεσε Γεγονός .ΘέσεΈνα λ
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                  Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
               Επιστροφή
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}



Χωρίς καμία αναδρομή. Χρησιμοποιούμε ένα αντικείμενο σωρός για να κρατήσουμε το που θα ανακατευθύνουμε την ροή εκτέλεσης, με Από Προς (On Goto). Στο Τμήμα ΓρήγορηΤαξινόμηση έχουμε ένα σύστημα με τρεις σωρούς τιμών (κάθε σωρός είναι μια ειδική στοίβα και στην ουσία μια λίστα συνδεδεμένων στοιχείων), και όλες οι αλλαγές ροής γίνονται με Προς ετικέτα (παραμένει μια Διαμέσου για ευκολία). Ουσιαστικά εδώ δεν υπάρχει αναδρομή. Σε κάθε περίπτωση αυτό που θα λέγαμε βάθος κλήσης, είναι στην ουσία το μέγεθος του αντικειμένου που δείχνει ο δείκτης επ, ο σωρός επιστροφής. Εκεί αντί να βάζουμε τα νούμερα 5000, 1000, 2000, βάζουμε έμμεσα νούμερα, τα 1, 2 και 3 (επειδή η Μ2000 δεν έχει άλμα με μεταβλητή, χρησιμοποιούμε τον έμμεσο τρόπο τα 1,2,3 που γίνονται 5000,1000,2000 με την Από αριθμός Προς. Υπάρχει και η Από Αριθμός Διαμέσου για απλές ρουτίνες με επιστροφή).


 
Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ1, Μ2, ρ, π, λ, σΜ1, σλ, επ, επ1
            σΜ1=Σωρός
            σλ=Σωρός
            επ=Σωρός:=1
            Τρόπος$="ΑΥΞΟΥΣΑ"
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε λ=.πόσα-1: Προς ΓρήγορηΤαξινόμηση
            Έξοδος
ΓρήγορηΤαξινόμηση:
                  Αν λ-π=1 Τότε Διαμέσου 4000 : Σωρός επ {Διάβασε επ1} : Από επ1 Προς 5000, 1000, 3000
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Σωρός σΜ1 { Βάλε Μ1}
                  Μ1=π
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  Αν π>=Μ2 Τότε 2000
                  Σωρός σλ { Βάλε λ} : λ=Μ2
                  Σωρός επ {Βάλε 2} : Προς ΓρήγορηΤαξινόμηση
      1000 Σωρός σλ { Διάβασε λ}
      2000 π=Μ1
                  Αν Μ1<λ Τότε Σωρός επ {Βάλε 3} : Προς ΓρήγορηΤαξινόμηση
      3000 Σωρός σΜ1 {Διάβασε Μ1}
                  Σωρός επ {Διάβασε επ1}
                  Από επ1 Προς 5000, 1000, 3000
      4000 Κάλεσε Γεγονός .ΘέσεΈνα λ
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                  Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
                  Επιστροφή
        5000  ' τερματισμός
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}


Παράρτημα Σύγκριση Αλφαριθμητικών

Εδώ είναι μερικά παραδείγματα για τη σύγκριση αλφαριθμητικών. Έχει σημασία η θέση των διακοπτών. Στα προγράμματα παραπάνω όμως χρησιμοποιούμε την Τάξη() η οποία είναι σε κάθε περίπτωση του διακόπτη "txt" ίδια. Επιπλέον η Τάξη() κάνει διαχωρισμό αριθμών μέσα στα αλφαριθμητικά και έτσι το "αλφα 100" είναι μεγαλύτερο από το "αλφα 90", όπως και το "αλφα 100 βήτα 50" είναι μεγαλύτερο από το "αλφα 100 βήτα 8" (ενώ και τα δύο αν τα συγκρίνουμε απλά ως αλφαριθμητικά θα είναι το ανάποδο, επειδή στα μεν δυο πρώτα η σύγκριση στο 1 και 9 δίνει το 9 μεγαλύτερο, ενώ στο δεύτερο η σύγκριση στα 5 και 8 δίνει το 8 μεγαλύτερο).

Σε Xp, Windows 7 και Windows 8, Windows 10



Θέσε διακόπτες "+txt"
' εκτός από το ότι οι συγκρίσεις γίνονται αλφαβητικά, παίζει ρόλο και το Locale ή Τοπικό
' Μπορούμε να το ορίσουμε αν θέλουμε ώστε να αλλάξει η σειρά βάσει αλφαβήτου συγκεκριμένης γλώσσας, αν οι χαρακτήρες ανήκουν σε αυτήν, αλλιώς βάσει της γλώσσας που ανήκουν.
' Αυτό μετράει σε γλώσσες που διαχειρίζονται ίδιους χαρακτήρες.
Τύπωσε "α"="ά", "α">"ά" 'δίνει 0 και 0
Στη α$="α", β$="ά"
\\ η σύγκρινε παίρνει μόνο μεταβλητές (και αριθμητικές)
Τύπωσε Σύγκρινε(α$, β$) ' δίνει -1
\\ ο τελεστής "διαστημόπλοιο" ή "spaceship" παίρνει και αριθμητικές παραστάσεις
\\ και γυρίζει 1 ή 0 ή -1  (1 αν η πρώτη έκφραση έχει μεγαλύτερο αποτέλεσμα από τη δεύτερη)
Τύπωσε "α"<=>"ά"  ' ΄δίνει -1
\\ Η Συνάρτηση Τάξη δουλεύει μόνο για αλφαριθμητικά, πάντα σαν να έχουμε το διακόπτη στο "+txt"
Τύπωσε Τάξη(α$, β$) ' δίνει -1
Τύπωσε Τάξη("α","ά") ' δίνει -1
θέσε διακόπτες "-txt"
Τύπωσε "α"="ά", "α">"ά" ' δίνει 0 και -1
Στη α$="α", β$="ά"  
Τύπωσε Σύγκρινε(α$, β$) '1 δηλαδή α$>β$
Τύπωσε "α"<=>"ά"  ' 1
Τύπωσε Τάξη(α$, β$) ' δίνει -1
Τύπωσε Τάξη("α","ά") ' δίνει -1
\\ Ο κωδικός χαρακτήρων είναι πάντα ίδιος για οποιαδήποτε διακόπτη σύγκρισης, ή οποιοδήποτε τοπικό και αν έχουμε επιλέξει.
Τύπωσε ΧαρΚωδ("α"), ΧαρΚωδ("ά") ' 945 και 940
\\ Η Μ2000 μπορεί να κάνει μετατροπές.
\\ δουλεύει και σε Wine και σε Windows
\\ Κωδικός κατά Ansi
Τύπωσε Κωδ("α"), Κωδ("ά") ' 225   και 220
Τοπικό 1033
Τύπωσε Χαρ$(225) ' Δίνει á
Τοπικό 1032
Τύπωσε Χαρ$(225) ' Δίνει α
Τύπωσε Χαρ$(225, 1033) ' Δίνει á
Τύπωσε Χαρ$(225, 1032) ' Δίνει α
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1033) ' δίνει á
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1032) ' δίνει α



Σε  Wine σε Ubuntu Studio υπάρχει διαφορά. Το "α"="ά" δίνει αληθές. Επειδή όμως η Τάξη() δουλεύει σωστά, το πρόγραμμα ταξινόμησης δουλεύει σωστά. Οι μετατροπές με την Χαρ$() δουλεύει σωστά, όπως και στα Windows.


Θέσε διακόπτες "+txt"
' εκτός από το ότι οι συγκρίσεις γίνονται αλφαβητικά, παίζει ρόλο και το Locale ή Τοπικό
' Μπορούμε να το ορίσουμε αν θέλουμε ώστε να αλλάξει η σειρά βάσει αλφαβήτου συγκεκριμένης γλώσσας, αν οι χαρακτήρες ανήκουν σε αυτήν, αλλιώς βάσει της γλώσσας που ανήκουν.
' Αυτό μετράει σε γλώσσες που διαχειρίζονται ίδιους χαρακτήρες.
Τύπωσε "α"="ά", "α">"ά" 'δίνει -1  και 0
Στη α$="α", β$="ά"
\\ η σύγκρινε παίρνει μόνο μεταβλητές (και αριθμητικές)
Τύπωσε Σύγκρινε(α$, β$) ' δίνει 0
\\ ο τελεστής "διαστημόπλοιο" ή "spaceship" παίρνει και αριθμητικές παραστάσεις
\\ και γυρίζει 1 ή 0 ή -1  (1 αν η πρώτη έκφραση έχει μεγαλύτερο αποτέλεσμα από τη δεύτερη)
Τύπωσε "α"<=>"ά"  ' ΄δίνει 0
\\ Η Συνάρτηση Τάξη δουλεύει μόνο για αλφαριθμητικά, πάντα σαν να έχουμε το διακόπτη στο "+txt"
Τύπωσε Τάξη(α$, β$) ' δίνει 0
Τύπωσε Τάξη("α","ά") ' δίνει 0
θέσε διακόπτες "-txt"
Τύπωσε "α"="ά", "α">"ά"  ' δίνει 0 και -1
Στη α$="α", β$="ά"
Τύπωσε Σύγκρινε(α$, β$) '1 δηλαδή α$>β$
Τύπωσε "α"<=>"ά"  ' 1
Τύπωσε Τάξη(α$, β$) ' δίνει 0
Τύπωσε Τάξη("α","ά") ' δίνει 0
\\ Ο κωδικός χαρακτήρων είναι πάντα ίδιος για οποιαδήποτε διακόπτη σύγκρισης, ή οποιοδήποτε τοπικό και αν έχουμε επιλέξει.
Τύπωσε ΧαρΚωδ("α"), ΧαρΚωδ("ά") ' 945 και 940
\\ Η Μ2000 μπορεί να κάνει μετατροπές.
\\ δουλεύει και σε Wine και σε Windows
\\ Κωδικός κατά Ansi
Τύπωσε Κωδ("α"), Κωδ("ά") ' 225   και 220
Τοπικό 1033
Τύπωσε Χαρ$(225) ' Δίνει á
Τοπικό 1032
Τύπωσε Χαρ$(225) ' Δίνει α
Τύπωσε Χαρ$(225, 1033) ' Δίνει á
Τύπωσε Χαρ$(225, 1032) ' Δίνει α
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1033) ' δίνει á
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1032) ' δίνει α