Πέμπτη 23 Μαρτίου 2017

Ενημέρωση του τεύχους 21 του εγχειριδίου

Καθώς συνεχίζω την ανανέωση του μικρού εγχειριδίου έκανα και μια αλλαγή στο απ' ευθείας εγχειρίδιο στο blog, στο παράδειγμα που στέλνoyme ένα πίνακα στο Ecxel (χωρίς να χειριστούμε το Excel ως αντικείμενο αλλά μέσω ενός csv αρχείου).
Η τροποποίηση δίνει την δυνατότητα να σώσουμε από το Excel το csv και να πάρουμε από την γραμμή με τους τύπους που είχαμε στο csv τα αποτελέσματα.
Το παράδειγμα φτιάχνει το csv με χώρισμα Tab ανά στοιχείο και με ότι είχουμε τοπικά σε χαρακτήρα δεκαδικού (στα ελληνικά έχουμε το κόμμα).
Όσο το αρχείο είναι ανοικτό στο Excel μπορούμε με να το διαβάσουμε αλλά δεν μπορούμε να το τροποποιήσουμε. Με αυτόν τον τρόπο, δοκιμάζοντας να το ανοίξει για συμπλήρωση (append), περιμένει να ελευθερωθεί, να κλείσει από το Excel. Υπάρχουν δυο περιπτώσεις. Να το έχουμε σώσει από το Excel, ή όχι. Αν όχι τότε θα είναι όπως το στείλαμε, αν ναι τότε δείτε τι κάνει το Excel. Δεν βάζει εισαγωγικά στα πεδία με αλφαριθμητικά. Οπότε πρέπει να βάλουμε εμείς. Επιπλέον αλλάζει τους τύπους (τα κελιά με = στην αρχή)  με το αποτέλεσμα. Για την τελευταία γραμμή κάνουμε το εξής: Παίρνουμε όλη τη γραμμή με Γραμμή Εισαγωγής (θα είναι τα αλφαριθμητικά με εισαγωγικά και οι αριθμοί με δεκαδικό τη τελεία, αφού κάναμε την μετατροπή πιο πριν). Όπως είναι η γραμμή εισαγωγής πηγαίνει στο σωρό με την εντολή Σωρός και οι τιμές μπαίνουν στη κορυφή του, οπότε δοκιμάζουμε να διαβάσουμε αλφαριθμητικά, αν δεν βγει η δοκιμή διαβάζουμε αριθμητικές τιμές!
άλλος τρόπος θα ήταν να κοιτάμε μια προς μια τις τιμές στο σωρό και ανάλογα να κάνουμε με την χρήση της Ειναρ (που γυρνάει -1 αν είναι αριθμός).

Μπήκε η εντολή Τοπικό 1032 (σε περίπτωση που έχουμε επιλέξει αγγλικά στην Μ2000 το τοπικό είναι το 1033, οπότε λαμβάνει από εκεί την τελεία ως  τοπικο$(0xE) ενώ θέλουμε το ελληνικό, επειδή έχουμε το Excel στα ελληνικά, οπότε λέμε τοπικό 1032.
Μπήκε επιπλέον μια εντολή Αναμονή 5000 για να δώσουμε 5 δευτερόλεπτα στο σύστημα να ανοίξει το αρχείο (αλλιώς το πρόγραμμα προχωράει στην ανάγνωσή του)

κ=1
\\ με χρήση BOM (ενδεικτικού χαρακτήρα)
\\ το 0xE δίνει το σύμβολο για τα δεκαδικά - μπορεί να είναι το κόμμα ή η τελεία.
Τοπικό 1032
Κάνε ΑλλαξεΤελεία$(α$)=αλλαγη$(".",τοπικο$(0xE),α$)
Δες οκ {
Άνοιξε "αλφα.csv" για ευρεία εξαγωγή ως κ
}
Αν όχι οκ Τότε Λάθος "Δεν μπορώ να ανοίξω το αρχείο αλφα.csv"
      Τύπωσε #κ, χαρκωδ$(0xFEFF);  \\ λέγεται BOM και μαρκάρει το κείμενο ως UTF-16LE
      \\ οι αριθμοί στο κώδικα γράφονται πάντα με τελεία για δεκαδικό
      \\ στην εμφάνιση στην Τύπωσε βγαίνουν βάσει του τοπικού
      Γράψε με χαρ$(9), τοπικο$(0xE)
      Γράψε #κ, "Τιμή Α", "Τιμή Β","Αποτέλεσμα Κ"
      Γράψε #κ, 12.24, 213.23, 213.23+12.24
      Γράψε #κ, 15.24, 215.23, 215.23+15.24
      Γράψε #κ, ΑλλαξεΤελεία$("=A2+A3*2.5"),ΑλλαξεΤελεία$("=B2+B3*2.5"),ΑλλαξεΤελεία$("=C2+C3*2.5")
Κλείσε #κ
Γράψε με "",""  \\ κάνουμε επιστροφή στις τιμές κόμμα και τελεία
Σύστημα "Excel.exe "+παράθεση$(κατ$+"αλφα.csv")
Έγγραφο Excel$
Αναμονή 5000
{
      Δες οκ {
            \\ αν είναι ανοιχτό με το Excel είναι για αποκλειστική χρήση
            \\ οπότε βγαίνει λάθος η συμπλήρωση (append)
            Άνοιξε "αλφα.csv" για συμπλήρωση ως κ
            Κλείσε #κ
            Φόρτωσε.Έγγραφο Excel$, "αλφα.csv"
      }
            αν λάθος ή οχι οκ τότε αναμονή 100 : κυκλικα
      }
Σώσε.Έγγραφο Excel$, "αλφα0.csv", 0
Σημ 1 : Σύστημα "Excel.exe "+παράθεση$(κατ$+"αλφα0.csv")

Αναφορά Excel$
\\ Μετατροπή από εξαγωγή του excel στο βασικό csv με κόμμα και τελεία.
Αν τοπικο$(0xE)<>"." Τότε {
      Για ι=1 έως Εγγράφου.Παρ(Excel$) {
            καθ$=παράγραφος$(Excel$,ι)+χαρ$(9)
            Έγγραφο τελικο$
            Ενώ καθ$<>"" {
                  καθ1$=αριστερομερος$(καθ$, χαρ$(9)) : καθ$=δεξιμερος$(καθ$, χαρ$(9))
                  καθ1$=αλλαγη$(τοπικο$(0xE),".",καθ1$)
                  Αν Εγγράφου.Μήκος(τελικο$)=0 τότε {
                        τελικο$=καθ1$
                  } Αλλιώς τελικο$=","+καθ1$
            }
            καθ$=τελικο$+"," : Καθαρό τελικο$
            Ενώ καθ$<>"" {
                  καθ1$=αριστερομερος$(καθ$, ",") : καθ$=δεξιμερος$(καθ$, ",")
                  \\ βάζουμε εισαγωγικά με την Παράθεση$() αν χρειάζεται
                  Αν όχι Δεξι$(καθ1$,1) ~ "[+-1234567890"+Χαρ$(34)+"]" τότε καθ1$=Παράθεση$(καθ1$)
                  Αν Εγγράφου.Μήκος(τελικο$)=0 τότε {
                        τελικο$=καθ1$
                  } Αλλιώς τελικο$=","+καθ1$
            }

            Καταχώρηση ι Excel$=τελικο$
            Καθαρό τελικο$ \\ καθαρίζουμε το έγγραφο
      }
}
Αναφορά Excel$
Σώσε.έγγραφο Excel$, "αλφα1.csv", 0

\\ Άνοιγμα του τροποποιημένου αρχείου, με κόμμα και τελείες.
Άνοιξε "αλφα1.csv" για ευρεία εισαγωγή ως κ
      Εισαγωγή #κ, τ1$, τ2$, τ3$
      Τύπωσε τ1$, τ2$, τ3$
      Για ι=1 έως 2 {
            Εισαγωγή #κ, τ1, τ2, τ3
            Τύπωσε τ1, τ2, τ3
      }
      Γραμμή Εισαγωγής #κ, ολα$
      Σωρός ολα$ \\ μεταφέρει στην κορυφή ότι έχει η γραμμή
      Δες Οκ {
            Διάβασε τ1$, τ2$, τ3$
            Τύπωσε τ1$, τ2$, τ3$
      }
      Αν όχι Οκ τότε {
            Διάβασε τ1, τ2, τ3
            Τύπωσε τ1, τ2, τ3
      }
Κλείσε #κ

Τρίτη 21 Μαρτίου 2017

Αναθεώρηση 2 'Εκδοση 8.6


Σε αυτή την αναθεώρηση δεν υπήρξε διόρθωση λάθους. Απλά μπήκε κάτι που δεν είχε μπει στην 8.6 αναθ. 1, ο τρόπος να γνωρίζουμε τι έχει ο σωρός πριν κάνουμε κάποια ενέργεια. Αυτό γίνεται με την Ταύτιση() και στην 8.6 αναθ. 1 το σύστημα γύρναγε το U (undefined) και στην Ταύτιση() δεν υπήρχε γράμμα για αντικείμενο σωρού. Τώρα έχουμε το C και το Σ.


Η φάκελος τυπώνει πάντα το αγγλικό C. Η εντολή Σωρός χωρίς όρισμα δείχνει την λίστα περιεχομένων του σωρού, και εκεί εμφανίζει το *[mStiva].

Άδειασε \\ αδειάζει το σωρό
Σ1=Σωρός:=1,2,"Γεια",14
Βάλε Σ1
Τύπωσε Μέγεθος.Σωρού
Σωρός
Τύπωσε Φάκελος$() , Ταύτιση("C"), Ταύτιση("Σ"


 Η Μέγεθος.Σωρού δουλεύει για τον τρέχον σωρό, ενώ η Μήκος() για τους "Επώνυμους" σωρούς!

Ενημέρωσα τη βοήθεια για την Σωρός και την Κάθε(). Όταν είχε γραφτεί το πρώτο αρχείο βοήθειας, τα προγράμματα ήταν στα κεφαλαία...και εδώ το συνέχισα! Κάποια στιγμή θα τα ωραιοποιήσω! Το αντιγράφουμε σε ένα τμήμα έστω Α (με εντολή Σ Α και μετά ctrl+V, ή με drag n' drop, βγαίνουμε με Esc, και γράφουμε Α και τρέχει!).



      ΑΔΕΙΑΣΕ
      ΣΕΙΡΑ 1,2,3,4
      Α=ΣΩΡΟΣ:=20,10,1,2
      ΣΩΡΟΣ Α {
            ΣΩΡΟΣ
            ΠΕΤΑ 2
            ΣΩΡΟΣ
      }
      ΣΩΡΟΣ
      ΤΥΠΩΣΕ ΤΙΜΗΣΩΡΟΥ(Α), ΜΗΚΟΣ(Α) \\ 1   2
      ΣΩΡΟΣ Α {
            ΔΙΑΒΑΣΕ Χ, Υ
            ΓΙΑ ΑΥΤΟ { \\ ΠΡΟΣΩΡΙΝΟΙ ΟΡΙΣΜΟΙ
                  ΠΙΝΑΚΑΣ Μ(10)=5
                  ΒΑΛΕ Μ()
            }
      }
      Ν=ΣΩΡΟΣ(Α) \\ ΑΝΤΙΓΡΑΦΟ
      ΣΩΡΟΣ Ν {
            ΓΙΑ ΑΥΤΟ {
                  ΔΙΑΒΑΣΕ Κ \\ ΠΙΝΑΚΑΣ ΣΕ ΜΕΤΑΒΛΗΤΗ
                  Κ+=100
                  ΒΑΛΕ Κ
                  ΤΥΠΩΣΕ Κ \\ ΟΛΑ 105
                  ΣΩΡΟΣ Α {
                        ΔΙΑΒΑΣΕ Μ()
                        ΤΥΠΩΣΕ Μ() \\ ΟΛΑ 5
                  }
                  ΤΥΠΩΣΕ ΜΗΚΟΣ(Α) \\ 0
            }
      }
      Α=ΣΩΡΟΣ:="ΑΛΦΑ","ΒΗΤΑ", 100
      ΤΥΠΩΣΕ ΜΗΚΟΣ(Α), ΜΗΚΟΣ(Ν) \\ 3 & 1
      Ν=ΣΩΡΟΣ(Α,Ν) \\ ΝΕΟΣ ΣΩΡΟΣ ΩΣ Α+Β
      ΣΩΡΟΣ Ν {
            ΣΩΡΟΣ    \\ ΜΑΣ ΔΕΙΧΝΕΙ ΤΙ ΣΤΟΙΧΕΙΑ ΕΧΕΙ
      }
      ΣΩΡΟΣ Α {
            ΣΩΡΟΣ
      }
      Α=ΣΩΡΟΣ(Α,-3) \\ ΑΝΑΣΤΡΟΦΗ, ΤΟ ΤΕΛΕΥΤΑΙΟ ΓΙΝΕΤΑΙ ΠΡΩΤΟ
      ΣΩΡΟΣ Α {
            ΣΩΡΟΣ   \\ ΜΑΣ ΔΕΙΧΝΕΙ ΤΙ ΣΤΟΙΧΕΙΑ ΕΧΕΙ
      }
      ΣΩΡΟΣ ΣΩΡΟΣ(Α,-2) { \\ ΒΓΑΖΕΙ ΑΝΤΙΓΡΑΦΟ ΤΟΥ Α
      \\ ΤΑ ΔΥΟ ΤΕΛΕΥΤΑΙΑ ΣΤΟΙΧΕΙΑ ΕΙΝΑΙ ΣΕ ΑΝΑΣΤΡΟΦΗ
      \\ Ο Α ΠΑΡΑΜΕΝΕΙ ΩΣ ΕΧΕ
            ΣΩΡΟΣ
      }
      ΣΩΡΟΣ Α {ΠΕΤΑ} \\ ΠΕΤΑΕΙ ΤΗ ΚΟΡΥΦΗ
      Α=ΣΩΡΟΣ(Α,-ΜΗΚΟΣ(Α))
      ΝΝ=ΚΑΘΕ(Α)
      ΕΝΩ ΝΝ {
            ΤΥΠΩΣΕ ΤΙΜΗΣΩΡΟΥ$(ΝΝ)
      }




 

M2000 for Linux

Ο διερμηνευτής της Μ2000 μπορεί να τρέξει σε Linux. Υπάρχουν κάποια θέματα όπως με το κέρσορα (δεν αναβοσβήνει όπως θα έπρεπε όταν έχουμε σκοτεινά φόντα, ενώ δουλεύει με άσπρο φόντο καλά). Επίσης όταν ανοίγει ένα παράθυρο τύπου διαλόγου, πάνω από τη κονσόλα της Μ2000, τότε για ανεξήγητο λόγο νομίζει το Wine ότι θέλουμε κάτι από την γραμμή εκκίνησης και όχι μόνο την φέρνει στο προσκήνιο, παράλληλα παίρνει και το focus...οπότε η λύση είναι το Ctrl Tab, και κλικ στη φόρμα της Μ2000.

Η εγκατάσταση δεν είναι δύσκολη, όμως απαιτείται να οριστούν κάποιες βιβλιοθήκες με επιλογή native.
Στο στιγμιότυπο παρακάτω φαίνεται ο Task Manager του Wine, οι επιλογές στα dll, το πρόγραμμα σε Μ2000 Note1 (Notepad γραμμένο σε M2000), και ο διαχειριστής εργασιών του Linux (Ubuntu Studio 16.04 με Xfce)


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





Υπάρχει τρόπος να δούμε αν το πρόγραμμα τρέχει σε περιβάλλον Wine, σε Linux. Στην παρακάτω εικόνα βλέπουμε ότι εμφανίζει το λειτουργικό Windows 7, αλλά θα μπορούσε να ήταν και κάτι άλλο! Αυτό το αλλάζει το Wine. Υπάρχει όμως μια συνάρτηση στο ntdll που δεν την έχουν τα κανονικά ntdll, την wine_get_version. Η Μ2000 μπορεί να ενώσει μια δική της συνάρτηση με αυτήν και αν γίνει ...τότε ξέρουμε ότι τρέχει το πρόγραμμα σε Wine.  

Για να αντιγράψω τις παρακάτω δυο γραμμές, και να διατηρηθεί το χρώμα...πρέπει πρώτα να το φέρω στο Libreoffice, μετά να κάνω πάλι αντιγραφή και να το βάλω στο firefox, στο πλαίσιο του Blogger


declare Wine_Get_version lib "ntdll.wine_get_version" {}
report str$(uint(Wine_Get_version()) mod 0x80000)




Αρχεία κειμένου μπορούμε να ανοίγουμε χωρίς να τα φορτώσουμε στο περιβάλλον της Μ2000.

To note1.gsb  άνοιξε με την εντολή "note1.gsb". Αν κάναμε load note1.gsb θα έτρεχε άμεσα, γιατί τελευταίες εντολές έχει τις A : End  (καλεί το A και μόλις αυτό ολοκληρώσει κλείνει τον διερμηνευτή). Μάλιστα αν προσέξει κανείς τη πρώτη εικόνα...δεν βλέπει την κονσόλα γιατί την αφαιρούμε με την εντολή Title ή Τίτλος!

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

Μια άλλη ευκολία που "παίζει" και στο Linux είναι αλλαγή μεγέθους κονσόλας (αλλάζει και τα πλάτος/ύψος, αλλά εδώ θέλουμε να πιάνει όλη την οθόνη). Η κονσόλα έχει δυο εμφανή επίπεδα, το Περιθώριο και την Οθόνη. Στο περιθώριο γράφουμε με την εντολή Περιθώριο { } και μεσα στο μπλοκ όλες οι εντολές προς οθόνη πάνε στο Περιθώριο. Ομοίως και η Επίπεδο { } στέλνει στην οθόνη μέσα από την Περιθώριο { }. Η αλλαγή μεγέθους γραμμάτων γίνεται με τρεις τρόπους Mode ή Τύπος, Window ή Παράθυρο και Form ή Φόρμα. Ειδικά η τελευταία καθορίζει αυτόματα το linespace, ή διάστιχο δηλαδή το κενό μεταξύ των γραμμών.
Με form 40,20 δημιουργούμε ένα πλαίσιο οθόνης για 40 χαρακτήρες -  εσωτερικά η ρουτίνα υπολογίζει το πλάτος χαρακτήρα με βάσει το μέγεθος του W σε bold και Italic, και ψάχνει ανάστροφα, να δει σε ποιο μέγεθος χαρακτήρων έχει το βέλτιστο πλάτος. Αφού βρει το πλάτος και δει ότι οι γραμμές του φτάνουν, τότε υπολογίζει το διάστιχο.


Φαίνεται στη παραπάνω εικόνα το ευρύ διάστιχο! Δείτε ότι στη αριστερή πλευρά του τίτλου βλέπουμε το όνομα του αρχείου note1gsb (ενώ αν διορθώναμε το τμήμα Α θα έλεγε Τμήμα Α η Module A ανάλογα με τι γλώσσα έχουμε επιλέξει στις ρυθμίσεις (εντολή Ρυθμίσεις ή Ctrl+U στην γραμμή εντολών της κονσόλας της Μ2000)

Με form 30,20 μεγαλώνουν τα γράμματα και μειώνεται το διάστιχο, ενώ παραμένουν οι γραμμές κειμένου στις 20. Βλέπουμε το περιθώριο πιο μεγάλο. Τα νούμερα παίζουν από 10,2 και όσο θέλουμε ..(απλά δεν θα βλέπουμε αν το μέγεθος πέσει κάτω από το 6  - το τι είναι το έξι είναι μια άλλη συζήτηση)



Με πάτημα και ολίσθηση προς τα πάνω μετακινούμαστε στο κείμενο, με βελάκια, με σελίδα πάνω και κάτω, με την κρυφή μπάρα ολίσθησης (ανοίγει με το δείκτη του ποντικιού), και με το ροδελάκι στο ποντίκι.

Ο διορθωτής έχει λειτουργία αναδίπλωσης λέξης, και εδώ βλέπουμε μια τεράστια λέξη (δεν έχει κενό να βρει λέξη) αλλά δεν υπάρχει θέμα, κόβεται κατάλληλα. Με το F1 αλλάζουμε όποτε θέλουμε σε αναδίπλωση ή μη. Και ο διορθωτής πάντα μας εμφανίζει με τη κατάλληλη ολίσθηση τον δρομέα.


Στην παρακάτω εικόνα που έχουμε αφαιρέσει την αναδίπλωση λέξεων βλέπουμε στην άκρη τον δρομέα (σε Windows θα ήταν φωτεινός, εδώ δεν είναι), και πάνω στην γραμμή πληροφοριών, βλέπουμε το 474, δηλαδή πίσω από το δρομέα υπάρχουν 474 χαρακτήρες!

Με Home /End πάμε αριστερά πρώτο ή δεξιά τελευταίο (για την ακρίβεια το Home μια φορά πάει στην θέση 1 και μια φορά στη θέση του πρώτου γράμματος μη διαστήματος (διάστημα είναι και ο χαρακτήρας 160, non-breaking space). Μπορούμε να δούμε τους κρυφούς χαρακτήρες με το F10, να δούμε τον αριθμό λέξεων με F9, να βγάλουμε/βάλουμε το χρωματισμό με το F11. Τα F6-F7-F8 είναι σελιδοδείκτες και δουλεύουν με ένα πάτημα ρύθμιση/επιλογή/απορύθμιση (αν έχουμε κάνει επιλογή η δεύτερη επιλογή κάνει απορύθμιση δηλαδή απελευθέρωση)
Τα F2 και F3 (δουλεύουν και με τα Shift) κάνουν αναζητήσεις πάνω και κάτω, Το F4 κάνει αλλαγή σε όλο το κείμενο σε λέξη που έχουμε αλλάξει γράμματα από πεζά σε κεφαλαίο ή και το ανάποδο, ώστε να κάνει όλες τις λέξεις το ίδιο. Το F5 κάνει αλλαγή σε όλο το κείμενο μιας λέξης με μια άλλη και μπορούμε να χρησιμοποιήσουμε το ctrl-z ως undo για να πάρουμε πίσω μερικές αλλαγές, και ctrl-y για redo.





Οι εντολές που γράφουμε στην κονσόλα φαίνονται με το edit (ή σ ή συγγραφή) χωρίς όρισμα. Εκεί μπορούμε να δούμε τις εντολές με χρώμα και να διορθώσουμε (παίζει και η βοήθεια, αλλά στο Linux το ctrl+F1 κάνει κάτι άλλο, οπότε υπάρχει στο μενού με δεξί κλικ ή με αριστερό στο τίτλο, κάτω - κάνει ολίσθηση το μενού- η επιλογή βοήθεια για εκείνη την λέξη που έχουμε επιλέξει)

Ο χρωματισμός του κειμένου από το αρχείο note1 γίνεται στον διορθωτή. Μάλιστα μόλις βγούμε από τον διορθωτή οι πληροφορίες του χρωματισμού χάνονται.

Στη παρακάτω εικόνα καλούμε με την εντολή Win το notepad (βγήκε αυτό του Wine, και ανοίγουμε το note1.gsb (αφού πάμε στο φάκελο UserName, Application Data, Μ2000 και επιλέξουμε όλα τα αρχεία, utf-8 κωδικοποίηση.


Παρατηρήστε τα αρχεία bck. Όταν σώνουμε ένα πρόγραμμα το παλιό δεν χάνεται, μέχρι την επόμενη φορά που θα ξανασώσουμε! Δείτε επίσης ότι το Wine δίνει δικό του διάλογο για άνοιγμα αρχείου που μοιάζει με τα windows, με ψειράκια γράμματα!




Ως προς το θέμα της ταχύτητας, στο WIne σαφώς ο διερμηνευτής είναι περίπου στο 70% από τον διερμηνευτή που τρέχει σε VirtualBox στο ίδιο μηχάνημα.

Καλές δοκιμές στο Linux!



Fibonacci Παράδειγμα.

Το πρόγραμμα δείχνει διάφορους τρόπους που βγαίνει η ακολουθία Fibonacci.
Παλαιότερα είχα δώσει ένα μικρό απλό πρόγραμμα, όπου το δείχνω μαζεμένο εδώ:


a=0 : b=1
fibonacci(20)
sub fibonacci(x)
if X>1 then fibonacci(X-1)
Print a, x : swap a, b :b+=a:x++
end sub


Υπάρχει και νεότερη εκδοχή ως παράδειγμα δυναμικού προγραμματισμού εδώ


Υπάρχει τρόπος με απλή επανάληψη και χρήση δυο μεταβλητών, ο τρόπος να μας δίνει μια συνάρτηση λάμδα τις επόμενες τιμές σε κάθε εκτέλεση, και τρόποι με αναδρομή.
Στη λάμδα συνάρτηση δεν έχουμε όνομα να καλέσουμε, και καλούμε με το γενικό όνομα λάμδα() ή για επιστροφή αλφαριθμητικού την λάμδα$(). Μετά ακολουθεί η fib() όπου εκεί καλούμε με το όνομα fib() μέσα από την fib()
Τέλος έχουμε μια υπορουτίνα, όπου και αυτή έχει δυνατότητα αναδρομής αλλά εδώ κάνουμε το εξής αφήνουμε αποτελέσματα στο σωρό και παίρνουμε από εκεί. Δηλαδή χρησιμοποιούμε μια τοπική  μεταβλητή τη χ και το σωρό τιμών (με Push βάζουμε στη κορυφή, με Διάβασε τη σηκώνουμε, αλλά εδώ χρησιμοποιώ την Αριθμός/Number και με μια Push Number+Number, τραβάμε τα δυο πρώτα τα προσθέτουμε και βάζουμε το αποτέλεσμα στη κορυφή του σωρού)

Recursion.limit  \\ just infrorm about the limits
\\ limit for function can't be change from program
\\ we can change limit for subs


\\ A loop in a function
Fibonacci=lambda (x)-> {
      Let A=0, B=1
      If x<=1 then =0 : exit
      For i=1 to x-1 {
            Push B : B=A+B: Read A
      }
      =A
}
\\ Same as before but without loop
\\ Also lambda capture A and B
FibonacciNext=lambda A=0, B=1-> {
      =A
      Push B : B=A+B: Read A
}
Print Fibonacci(5)
\\ A is a copy lambda with A and B zero
A=FibonacciNext
For I=1 to 10 { Print A(), } \\ print using columns
Print   \\ new line


\\ Recursion  (max 3375 level of recursion)
FibonacciRecursion=lambda (x) ->{
            if x<=1 then =0 : exit
            if x=2 then =1 : exit
            =lambda(x-1)+lambda(x-2)
}
Print FibonacciRecursion(5), Fibonacci(5)
Print FibonacciRecursion(10), Fibonacci(10)
Function Fib (x) {
      if x<=1 then =0 : exit
      if x=2 then =1 : exit
      =Fib(x-1)+Fib(x-2)
}
Print Fib(15),FibonacciRecursion(15), Fibonacci(15)
Print "Press a key"
A$=Key$
S=stack.size
FibonacciSub(15)
Print Number \\ pop value from stack


\\ sub with recursion, using M2000 stack for values/Parameters
\\ If we don't call subs between blocks of code in brackets { } then
\\ we get high recursion depth level
Rem : Recursion.Limit 500000
Sub FibonacciSub(x)
      if x<=1 then Push 0: Exit Sub
      if x=2 then Push 1: Exit Sub
      FibonacciSub(x-1)
      FibonacciSub(x-2)
      Push Number+Number \\ Number is pop
      \\ Unhide Stack to see stack values
      \\ Stack size as a bar graph
      Print String$("*",stack.size-S)
End Sub


Δευτέρα 20 Μαρτίου 2017

Έκδοση 8.6 αναθεώρηση 1

Διορθώθηκε Bug στην προηγούμενη έκδοση (είχε λάθος στα ελληνικά στην ιδιότητα όταν χρησιμοποιούσαμε παράμετρο σε παρένθεση.

(η Δείκτης είναι μεταβλητή μόνο ανάγνωσης - και δείχνει πιο κουμπί του ποντικού έχει πατηθεί, οπότε εδώ χρησιμοποιώ την Δείκτης1)

Κλάση Δες_Ιδιότητα {
Ιδιωτικό:
      Πίνακας Βάση 1, Α(3)
Δημόσιο:
      Ιδιότητα Όνομα$ {Αξία} = "Δες_Ιδιότητα"
      Ομάδα Άλφα {
            Ιδιότητα Όνομα$ {Αξία}= "Άλφα(δείκτης) - Μόνο για ανάγνωση"
      }
      Ιδιότητα Άλφα {
            Αξία (δείκτης1) {
                  Ένωσε γονικό Α() στο Α()
                  Δες οκ {
                        Αξία=Α(δείκτης1)
                  }
                  Άδειασε Λάθος \\ για να κρατήσει μόνο το τελευταίο που δίνουμε αμέσως μετά
                  Αν όχι Οκ τότε Λάθος "Δείκτης εκτός ορίων"
            }
      }
Κλάση:
      Τμήμα Δες_Ιδιότητα {
            .Α():=100,450,1890
      }
}
Μ=Δες_Ιδιότητα()
Τύπωσε Μ.Άλφα(1),Μ.Άλφα(2),Μ.Άλφα(3)
Τύπωσε Μ.Άλφα.Όνομα$
Δες Οκ {
      Τύπωσε Μ.Άλφα(10)
}
Τύπωσε "Το όνομά μου είναι:";Μ.Όνομα$
Αν όχι Οκ τότε Τύπωσε "Λάθος"+Λάθος$


Η έκδοση πήρε νέο αριθμό 8.6 γιατί τώρα τα τμήματα, οι συναρτήσεις και οι λάμδα συναρτήσεις μπορούν στον ορισμό τους να έχουν σε παρενθέσεις μια λίστα παραμέτρων (εσωτερικά γράφεται σε μια γραμμή το Διάβασε ή Read και ακολουθεί η λίστα παραμέτρων). Η λίστα παραμέτρων έχει ένα διάστημα που την ξεχωρίζει από το όνομα των συναρτήσεων και τμημάτων

Συνάρτηση Γενική ΜΜ (Χ,Υ) {
      =Χ**Υ
}
Τμήμα Γενικό ΚΛΜ (Ι) {
Τύπωσε Ι
}
Ομάδα Άλφα {
      Συνάρτηση ΜΜ (Χ,Υ) {
            =Χ**Υ
      }
      Τμήμα ΚΛΜ (Ι) {
      Τύπωσε Ι
      }
}
Τύπωσε Άλφα.ΜΜ(2,4)
Άλφα.ΚΛΜ 5
Τύπωσε ΜΜ(2,4)
ΚΛΜ 5


και για τις λάμδα:

Α=Λαμδα (Χ1)->Χ1**2
Τύπωσε Α(3)
Β=Λαμδα Χ=(1,2,3,4) (Υ)-> {
            =Πίνακας(Χ,Υ)
}
Τύπωσε Β(3)




Eσωτερικά δεν άλλαξε τίποτα, αλλά για το κώδικα φαίνεται πιο καθαρό το τι ζητάμε σε ορίσματα. Όμως υπάρχουν περιπτώσεις που το Read ή Διάβασε πρέπει να γίνει προοδευτικά ή μετά από καποιες εντολές. Σε άλλες γλώσσες αυτό είναι δύσκολο να γίνει, ή δεν γίνεται καθόλου!

Στην έκδοση 8.6 (αναθ 1) μπορούμε να έχουμε σε μεταβλητές το αντικείμενο Σωρός. Η Διάβασε διαβάζει από το σωρό του Τμήματος/Συνάρτησης και μπορεί να βάζουμε κιόλας με την Push/Βάλε στη κορυφή και την Data/Σειρά στο τέλος. Πάντα διαβάζουμε από την κορυφή, αφαιρόντας το στοιχείο, ή μπορούμε να διαβάσουμε με αριθμό, από το 1 για την κορυφή. Με τις μεταβλητές τύπου σωρού (ο τύπος αναφέρεται ως mStiva).

Στο πρώτο παράδειγμα βλέπουμε ότι μπορούμε να ταξινομήσουμε με ξεχωριστή ρουτίνα (έχει ενδιαφέρον η ρουτίνα, γιατί είναι μια quicksort σε λίστα που κάθε εισαγωγή γίνεται στη κορυφή και υπάρχουν δυο εντολές η Shft και η Shiftback που μεταφέρουν από και προς τη θέση που θέλουμε (εσωτερικά η mStiva είναι συνδεδεμένη λίστα αντικειμένων, τα οποία φέρουν τις τιμές που βάζουμε, και για το παράδειγμα είναι αλφαριθμητικά). Η quicksort έχει γραφτεί με ρουτίνα, και χρησιμοποιεί τον τρέχον σωρό, τον οποίο άλλαξε πρόσκαιρα η Stack .a { }. Σε προηγούμενες εκδόσεις υπήρχε μόνο η Stack New { } που έφτιαχνε έναν προσωρινό σωρό, αλλά τώρα μπορούμε να τον κρατάμε και εδώ μάλιστα τον έχουμε σε μια μεταβλητή σε ένα αντικείμενο Alpha.

Στην DisplayAll έχουμε την Each() που φτιάχνει ένα αντικείμενο με αναφορά στο σωρό (και αυτό είναι ο σωρός .a) και λέμε να μας δείξει κάθε στοιχείο από το τέλος ως την αρχή. Εδώ κοιτάμε το σωρό χωρίς να τον ενώσουμε προσωρινά με το σωρό του τμήματος. Φαίνονται εντολές για να παρεμβάλουμε τιμές στη θέση που θέλουμε.

Ο σωρός δεν έχει κλειδιά για αναζήτηση (όπως η Κατάσταση). Υποτίθεται ότι βάζουμε κάτι για να μαζευτεί ώστε μετά να το διαβάσουμε, ως LIFO ή FIFO. Ο τρόπος που βάζουμε, στη κορυφή ή στο πυθμέναν καθοριζει ποιος από τους δύο τύπους εκτελούμε,  ή το πρώτο που μπαίνει βγαίνει πρώτο (άρα βάζουμε στο πυθμένα) ή το τελευταίο που μπαίνει βγαίνει πρώτο, δηλαδή βάζουμε στη κορυφή. (διαβάζουμε πάντα από την κορυφή)

Πρόσθεσα στο παράδειγμα τα Private: και Public:

Class Alpha1 {
Private:
      a=stack:="hello","there","and","good","bye"    
Public:
      module DisplayAll {
            n=each(.a End to Start) \\ each(a,-1,1)
                  While n {
                        Print stackitem$(n), n^+1
                  }
      }
      Property Stacklen {
            Value {
                  Link parent a to a
                  value=Len(a)
            }
      }
      Module PushToBack (Word$) {
            Stack .a { Data Word$ }
      }
      Module PushToFront (Word$) {
            Stack .a { Push Word$ }
      }
      Module ClearStack {
            Stack .a {Flush}
      }
      Module Insert (word$, position) {
            Stack .a {
                  Push word$
                  Shiftback position
            }
      }
      Module Sort {
      Stack .a {
            qsort(1, stack.size)
      }
      Sub qsort(st, ed)
            Local thing$, i=st, lim=ed+1
            If lim >2 Then Shift (lim+i) Div 2
            Read thing$
            lim--
            While i<lim {
                  If thing$<StackItem$(i) Then {
                        lim--
                        If i>1 Then Shift i
                        ShiftBack lim
                  }  Else i++
            }
            If i>lim Then i=lim
            Push thing$ : ShiftBack i
            If i>st Then qsort(st,i-1)
            If ed>i Then qsort(i,ed)
      End Sub
      }
}
Alpha=Alpha1()
Alpha.DisplayAll
Alpha.Insert "zzzzzzzzzzz", 4
Alpha.DisplayAll
Alpha.Sort
Alpha.DisplayAll
Alpha.PushtoBack "Back"
Alpha.PushtoFront "Front"
Print alpha.StackLen


Στο δεύτερο μικρό παράδειγμα φαίνεται ότι μπορούμε να βάζουμε σωρούς και σε πίνακες.

Alfa=Stack
Print Type$(Alfa)
dim a(10)
a(1)=stack
Stack Alfa {
    Push 10, 20
    stack
}
Stack
Stack a(1) {
     Push 1,2,3
}
Stack a(1) {
      stack
      Read A, B
      Stack Alfa {
            Push B, A
            Stack
      }
   
}
list  \\ list of variables


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

flush
Dim a$(10)
a$(1)=stack$(1,"Hello",3,4,5)
stack a$(1), "NS"
Print a$(1)
Stack


Στο επόμενο παράδειγμα βλέπουμε πως βγάζουμε αντίγραφο ενός αντικειμένου σωρού: Η συνάρτηση Stack( ) με ένα όρισμα δίνει το αντικείμενο ως αντίγραφο.

A=stack
Stack A {
      Data 1,2,3,4,5
}
B=Stack(A)
Stack B {
      Print "This is B"
      Stack
      flush
      Print Empty
}
Stack A {
      Print "This is A"
      Stack
}


Το δεύτερο προαιρετικό όρισμα στη Stack() δηλώνει αν είναι αριθμός αν θα πάρουμε ένα αριθμό από την αρχή ή αν είναι αρνητικό από το τέλος με το τελευταίο ως πρώτο, το προτελευταίο ως δεύτερο κ.ο.κ. Αν το όρισμα είναι και αυτό σωρός τότε η Stack() δίνει ένα νέο αντικείμενο με τα στοιχεία του δεύτερου στο τέλος του πρώτου. Ένα απλό Β=Α κάνει το Β να δείχνει το Α

Στο τελευταίο παράδειγμα η b παίρνει ένα νέο σωρό με  ίδια με τα 4 πρώτα στοιχεία του a. Η εντολή Stack χωρίς όρισμα δείχνει τα στοιχεία του σωρού. Μπορούμε να έχουμε φωλιασμένα While (Ενώ) και να διατρέχουμε τον σωρό με ανεξάρτητους κέρσορες (όπως στις Καταστάσεις και στους Πίνακες).

a=stack:=1,2,3,4,5
b=stack:=6,7,8
a=stack(a,b)
Stack a {
      stack
}
b=stack(a, 4)
Stack b {
      stack
}
b=stack(a, -4)
Stack b {
      stack
}
N=each(a, 2, 5)
D=each(a, 6,7)
k=0
While N {
      While D {
            Print stackitem(N), stackitem(D)
      }
}