├── .github ├── FUNDING.yml └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── 00_package_main └── package_main.go ├── 01_data_type_math └── data_type_math.go ├── 02_const_string_bool_printf └── const_string_bool_printf.go ├── 03_logic_for_loops └── logic_for_loops.go ├── 04_if_else_if_switch └── if_else_if_switch.go ├── 05_arrays_slice_range_append_copy_make_len-cap └── arrays_slice_range_append_copy_make_len-cap.go ├── 06_maps └── maps.go ├── 07_func_recursion_closure_recover_defer_panic └── func_recursion_recover_defer_panic.go ├── 08_go_pointers └── go_pointers.go ├── 09_struct └── struct.go ├── 10_structs_interfaces └── structs_interfaces.go ├── 11_strings_excepting_input_casting └── strings_excepting_input_casting.go ├── 12_create_http_server └── create_http_server.go ├── 13_http_serve_static_html ├── http_serve_static_html.go └── static │ ├── LICENSE.txt │ ├── assets │ ├── css │ │ ├── font-awesome.min.css │ │ └── main.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── js │ │ ├── breakpoints.min.js │ │ ├── browser.min.js │ │ ├── jquery.min.js │ │ ├── main.js │ │ └── util.js │ └── sass │ │ ├── base │ │ ├── _page.scss │ │ ├── _reset.scss │ │ └── _typography.scss │ │ ├── components │ │ ├── _actions.scss │ │ ├── _box.scss │ │ ├── _button.scss │ │ ├── _form.scss │ │ ├── _grid.scss │ │ ├── _highlights.scss │ │ ├── _icon.scss │ │ ├── _icons.scss │ │ ├── _image.scss │ │ ├── _inner.scss │ │ ├── _list.scss │ │ ├── _table.scss │ │ ├── _testimonials.scss │ │ └── _wrapper.scss │ │ ├── layout │ │ ├── _banner.scss │ │ ├── _cta.scss │ │ ├── _footer.scss │ │ ├── _header.scss │ │ ├── _heading.scss │ │ ├── _main.scss │ │ └── _menu.scss │ │ ├── libs │ │ ├── _breakpoints.scss │ │ ├── _flexgrid.scss │ │ ├── _functions.scss │ │ ├── _grid.scss │ │ ├── _mixins.scss │ │ ├── _vars.scss │ │ └── _vendor.scss │ │ └── main.scss │ ├── elements.html │ ├── generic.html │ ├── images │ ├── banner.jpg │ ├── banner.mp4 │ ├── bg.jpg │ ├── cta01.jpg │ ├── pic01.jpg │ ├── pic02.jpg │ └── pic03.jpg │ └── index.html ├── 14_go_routines └── go_routines.go ├── 15_go_channels └── go_channels-ping-pong.go ├── 16_go_select_buffered └── go_select_buffered.go ├── 17_open_create_read_files ├── files │ ├── cerebrux.pdf │ ├── edit.txt │ ├── greece_covid19.csv │ ├── problems.csv │ ├── sample.txt │ └── yunus.txt └── open_create_read_files.go ├── LICENSE ├── README.md ├── go.mod ├── go.sum └── main.go /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: cerebrux # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: cerebrux # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ["https://www.paypal.me/cerebrux"] 13 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '17 11 * * 2' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'go', 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /00_package_main/package_main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Καλώς ήρθες! 3 | 4 | Για να βρίσκεσαι εδώ σημαίνει ότι έχεις εγκαταστήσει με επιτυχία την Go στον 5 | υπολογιστή σου σύμφωνα με τις οδηγίες στο https://wp.me/pq2ce-hNG . 6 | Έχεις επίσης βρει το "go workspace" το οποίο είναι 7 | ο βασικός χώρος εργασίας της Go που βρίσκεται στη διαδρομή "~/go/src". 8 | Τέλος έχεις μπει και στο συγκεκριμένο φάκελο του πρώτου μαθήματος ο οποίος 9 | ονομάζεται "00_package_main" και περιλαμβάνει το αρχείο "00_package_main.go" 10 | που αυτή τη στιγμή διαβάζεις. 11 | 12 | Το μάθημα ξεκινάει ! 13 | 14 | Τι θα μάθουμε: 15 | - Στοιχεία της Go 16 | - Πως τρέχουμε τον κώδικά μας 17 | - Πως δημιουργούμε ένα εκτελέσιμο απο τον κώδικά μας 18 | - Πως μπορούμε να κάνουμε compile τον κώδικά μας για όλα τα λειτουργικά συστήματα 19 | 20 | Πακέτα 21 | 22 | Οι εφαρμογές Go είναι οργανωμένες σε πακέτα. Ένα πακέτο είναι μια 23 | συλλογή αρχείων κώδικα που βρίσκονται μέσα στον ίδιο φάκελο. 24 | 25 | Όλα τα αρχεία κώδικα σε έναν φάκελο πρέπει να έχουν το ίδιο όνομα πακέτου με εξαίερεση 26 | το αρχείο main.go 27 | 28 | Όπως θα δούμε σε επόμενα μαθήματα, όταν εισάγεται (import) ένα πακέτο, μόνο οι 29 | οντότητες του (συναρτήσεις, τύποι, μεταβλητές, σταθερές) των οποίων το όνομα 30 | αρχίζει με κεφαλαίο γράμμα μπορούν να χρησιμοποιηθούν και να έχουμε πρόσβαση 31 | στις μεθόδους τους. 32 | 33 | Το συνιστώμενο στυλ ονομασίας οντοτήτων (ονόματα μεταβλητών, συναρτησεων κλπ) 34 | στη Go είναι να ονομάζονται χρησιμοποιώντας το "camelCase" στύλ όπου τα ονόματα 35 | ξεκινάνε με μικρό γράμμα, με εξαίρεση όπως είπαμε πιο πάνω, αυτά που προορίζονται 36 | να είναι προσβάσιμα σε όλα τα πακέτα και θα πρέπει να ξεκινάνε με κεφαλαίο το 37 | πρώτο γράμμα. Δηλαδή "CamelCase". 38 | 39 | Κάθε πρόγραμμα (αρχείο) go αποτελείται σχεδόν πάντα απο 4 στοιχεία: 40 | 41 | (1) Package declaration 42 | (2) Imports 43 | (3) Function (main) 44 | (4) Code 45 | 46 | (1) Το πρώτο πράγμα που χρειάζεται κάθε πρόγραμμα Go είναι 47 | ένα "package declaration". Το βασικό μας πρόγραμμα θα είναι πάντα 48 | το "main", με το οποίο λέμε στην ουσία στον compiler (μεταγλωττιστή) 49 | να το μεταγλωττίσει ως αυτόνομο εκτελέσιμο πρόγραμμα. Όλα τα 50 | υπόλοιπα Go προγράμματα που θα γράψουμε και δε θα τους δώσουμε 51 | το "main" declaration, χρησιμοποιούνται ως κοινόχρηστες βιβλιοθήκες, 52 | τις οποίες μπορούμε να καλέσουμε στο πρόγραμμά μας με το "import". 53 | 54 | Επομένως, κάθε εκτελέσιμο που θέλουμε να γράψουμε χρειάζεται το "package main" 55 | ως την πρώτη γραμμή κώδικα. 56 | 57 | (2) Το επόμενο πράγμα που χρειαζόμαστε είναι το import (εισαγωγή) με το οποίο μπορούμε 58 | να καλέσουμε τρίτες βιβλιοθήκες στο πρόγραμμά μας, Είτε τις έχουμε γράψει εμείς, 59 | είτε έρχονται από τις έτοιμες βιβλιοθήκες της Go (Go Standard Libraries). 60 | Στην περίπτωσή μας έχουμε μόνο την "fmt". Τα περισσότερα IDE εισάγουν/αφαιρούν 61 | αυτόματα τις βιβλιοθήκες με βάση τον κώδικα που έχουμε γράψει. 62 | 63 | (3) Το τρίτο πράγμα που χρειαζόμαστε είναι μια main function (κύρια συνάρτηση). 64 | Μέσα στη συνάρτηση main (func main) βρίσκεται η ουσία της εφαρμογής μας και εκεί 65 | βρίσκεται ο βασικός κώδικας που εκτελείται όταν την τρέχουμε. Έτσι, αυτός ο συνδυασμός 66 | "main package" και "func main()" είναι αυτό που ενεργοποιεί, δίνει ζωή και λειτουργεί 67 | το πρόγραμμά μας. 68 | 69 | Άρα ότι έχουμε μέσα στο main package αρχείο μας είναι το σημείο εισόδου του εκτελέσιμου 70 | προγράμματος μας. Φυσικά το πρόγραμμά μας μπορεί να μην αποτελείται μόνο απο αυτό το 71 | αρχείο αλλά και πάρα πολλά άλλα αρχεία, βιβλιοθήκες κλπ. Στην περίπτωση όμως 72 | του προγράμματος "package_main", αυτό αποτελείται μόνο απο το "package_main.go" αρχείο. 73 | 74 | (4) Όταν εκτελούμε απο το τερματικό το πρόγραμμά μας (θα δείτε παρακάτω πώς), αυτό 75 | μπαίνει στο main package και βρίσκει την main function για να εκτελέσει το 76 | Code (κώδικα) που περιλαμβάνει. Για τις functions θα μιλήσουμε εκτενώς 77 | αργότερα οπότε εδώ το πρόγραμμά μας το μόνο που κάνει είναι να λέει το 78 | κλασσικό "Γειά σου κόσμε". 79 | 80 | */ 81 | package main // (1) Package declaration 82 | 83 | import "fmt" // (2) Imports 84 | 85 | func main() { //(3) Function (main) η κύρια συνάρτηση που εκτελεί την εφαρμογή 86 | 87 | fmt.Println("Γεια σου κόσμε") // (4) εκτελούμε την Println function που βρίσκεται 88 | // μέσα στην fmt βιβλιοθήκη που εισάγαμε στο (2). 89 | } 90 | 91 | /* 92 | Ένα πρόγραμμα όπως αυτό, μπορούμε να το τρέξουμε σε τερματικό γράφοντας: 93 | 94 | $ go run package_main.go 95 | 96 | Η απάντηση που θα πάρουμε από το τερματικό είναι: 97 | 98 | Γεια σου κόσμε 99 | 100 | Για να φτιάξουμε ένα εκτελέσιμο αρχείο απο το πρόγραμμά μας και να το 101 | μοιράσουμε με άλλους, θα πρέπει να το κάνουμε compile (μεταγλώττιση) ως εξής: 102 | 103 | $ go build package_main.go 104 | 105 | Δίνουμε την ακόλουθη εντολή για να δούμε τα αρχεία που δημιουργήσαμε: 106 | 107 | $ ls 108 | 109 | Το τερματικό θα μας απαντήσει το εξής: 110 | 111 | package_main package_main.go 112 | 113 | Το εκτελέσιμο αρχείο μας είναι το "package_main" και μπορούμε να το 114 | τρέξουμε με την εντολή: 115 | 116 | $ ./package_main 117 | 118 | Η απάντηση που θα πάρουμε είναι: 119 | 120 | Γεια σου κόσμε 121 | 122 | Η Go υποστηρίζει seamless cross compilation για Windows, macOS, Linux και BSD. 123 | Επομένως, δεν έχει σημασία σε ποια πλατφόρμα αναπτύσσουμε και μεταγλωττίζουμε τον κώδικα. 124 | Ακολουθεί ένα παράδειγμα της σύνταξης που χρησιμοποιούμε για να δημιουργήσουμε 125 | εκτελέσιμα αρχεία για Windows και Linux σε macOS περιβάλλον: 126 | 127 | Για Windows 32bit μπορούμε να δημιουργήσουμε εκτελέσιμα ως εξής: 128 | 129 | $ GOOS=windows GOARCH=386 go build -o appname.exe 130 | 131 | Για Linux 64bit μπορούμε να δημιουργήσουμε εκτελέσιμα ως εξής: 132 | 133 | $ GOOS=linux GOARCH=amd64 go build -o appname.linux 134 | 135 | Περισσότερα σχετικά με τα λειτουργικά συστήματα και τις αρχιτεκτονικές 136 | για τις οποίες μπορούμε να δημιουργήσουμε εκτελέσιμα 137 | προγράμματα μπορείτε να διαβάστε εδώ: https://golang.org/doc/install/source#environment 138 | 139 | */ 140 | -------------------------------------------------------------------------------- /01_data_type_math/data_type_math.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε: 3 | - Πως βάζουμε σχόλια στον κώδικά της Go. 4 | - Πως κάνουμε import απο standard library αλλά και αυτές που δεν είναι 5 | στην standard library αλλά έχουν φτιαχτεί απο άλλους. 6 | - Πως φτιάχνουμε νέες function εντολές (συναρτήσεις) 7 | - Printf, Println 8 | - Πως δηλώνουμε μεταβλητές (Variables), δηλαδή λέξεις που αποθηκεύουν τιμές 9 | - Πως κάνουμε αριθμητικές πράξεις 10 | 11 | */ 12 | 13 | // ============== Σχόλια στον κώδικα ======================== 14 | 15 | // Μην σχολιάζετε κακό κώδικα — ξαναγράψτε τον 16 | // — Brian Wilson Kernighan (Unix, C, Awk, Go) 17 | // https://en.wikipedia.org/wiki/Brian_Kernighan 18 | 19 | //Ξεκινώντας μια γραμμή με τα "//" μπορούμε να προσθέσουμε ένα προσωπικό σχόλιο σε μια γραμμή 20 | /* 21 | Αν θέλουμε πολλαπλές γραμμές όπως αυτό που διαβάζετε τώρα, 22 | τότε βάζουμε το σχόλιο μας ανάμεσα σε αυτά τα 23 | */ 24 | /* 25 | Στη Go, τα σχόλια παίζουν τόσο, εξαιρετικά συμπαντικό ρόλο στην 26 | τεκμηρίωση του κώδικα, που χρησιμοποιούνται από την εντολή 27 | "godoc", η οποία εξάγει αυτά τα σχόλια για τη δημιουργία 28 | τεκμηρίωσης σχετικά με τα πακέτα Go. 29 | 30 | Ένα σχόλιο τεκμηρίωσης θα πρέπει να είναι μια πλήρης πρόταση 31 | που ξεκινά με το όνομα της οντότητας που περιγράφεται και 32 | τελειώνει με τελεία. 33 | 34 | Τα σχόλια θα πρέπει να προηγούνται των πακέτων καθώς και των 35 | εξαγόμενων οντοτήτων (π.χ. εξαγόμενων συναρτήσεων, μεθόδων, 36 | μεταβλητών πακέτων, σταθερών και δομών), για τα οποία θα 37 | μάθετε περισσότερα στα επόμενα μαθήματα. 38 | 39 | Τα σχόλια του πακέτου πρέπει να γράφονται απευθείας πριν 40 | από μια δήλωση πακέτου (package x) και να ξεκινούν με το 41 | package x ... ως εξής: 42 | 43 | // Package kelvin παρέχει εργαλεία για μετατροπή 44 | // θερμοκρασιών από και προς Kelvin. 45 | package kelvin 46 | 47 | 48 | Μια μεταβλητή σε επίπεδο πακέτου μπορεί να μοιάζει με αυτό: 49 | 50 | // TemperatureCelsius αντιπροσωπεύει μια ορισμένη 51 | // θερμοκρασία σε βαθμούς Κελσίου. 52 | var TemperatureCelsius float64 53 | 54 | Ένα σχόλιο συνάρτησης θα πρέπει να γράφεται ακριβώς πριν 55 | από τη δήλωση συνάρτησης. Θα πρέπει να είναι μια πλήρης πρόταση 56 | που ξεκινά με το όνομα της συνάρτησης. 57 | Για παράδειγμα, ένα εξαγόμενο σχόλιο για τη συνάρτηση Calculate 58 | θα πρέπει να έχει τη μορφή // Calculate ... . Θα πρέπει επίσης 59 | να εξηγεί ποια ορίσματα - παραμέτρους παίρνει η συνάρτηση, 60 | τι κάνει με αυτά και τι σημαίνουν οι επιστρεφόμενες τιμές της, 61 | που τελειώνουν σε τελεία . : 62 | 63 | // CelsiusFreezingTemp επιστρέφει μια ακέραια τιμή 64 | // ίση με τη θερμοκρασία στην οποία το νερό παγώνει 65 | // σε βαθμούς Κελσίου. 66 | func CelsiusFreezingTemp() int { 67 | return 0 68 | } 69 | 70 | Διαβάστε : https://golang.org/doc/effective_go#commentary 71 | Διαβάστε επίσης κάποιους κανόνες καλής πρακτικής για σχόλια 72 | στον κώδικα https://dave.cheney.net/practical-go/presentations/qcon-china.html#_comments 73 | */ 74 | 75 | /* 76 | Επανάληψη : 77 | Κάθε πρόγραμμα Go ξεκινά με μια "Package Declaration" (δήλωση πακέτου) 78 | που παρέχει έναν τρόπο για επαναχρησιμοποίηση του κώδικα. 79 | 80 | Η 'main' είπαμε οτι είναι ο "πυρήνας" του προγράμματος απο όπου 81 | ξεκινάει η εφαρμογή μας. Έτσι αφού οι εφαρμογές αποτελούνται απο αρχεία κώδικα 82 | που ανήκουν σε πακέτα, όλες οι εφαρμογές έχουν μια και μόνο main. 83 | Είναι η πύλη εισόδου της εφαρμογής απο όπου ξεκινάει η εκτέλεση της. 84 | Όλα τα υπόλοιπα αρχεία έχουν και αυτά δήλωση για το σε ποιο package ανήκουν 85 | */ 86 | package main 87 | 88 | import ( 89 | "fmt" // προφέρεται ως "φαμτ" ή formatter 90 | "runtime" // την χρειαζόμαστε για να προβάλουμε πληροφορίες 91 | // του συστήματος στο οποίο τρέχει η εφαρμογή μας. 92 | ) 93 | 94 | // Το import επιτρέπει την εισαγωγή βιβλιοθηκών και την εισαγωγή κώδικα από 95 | // άλλα πακέτα (π.χ. απο github θα γράφαμε << import "github.com/CerebruxCode/Go" >>) 96 | // Εδώ η βιβλιοθήκη fmt που περιλαμβάνεται στην standrad 97 | // library και που εισάγουμε μας παρέχει εργαλεία μορφοποίησης - προβολής 98 | // δεδομένων. Επειδή είναι στην standrad library την καλούμε με το όνομά 99 | // της και όχι με την online διεύθυνσή της. Το ίδιο ισχύει και για την runtime 100 | 101 | // Όπως και σε άλλες γλώσσες, έτσι και στην Go μπορούμε να συνδυάσουμε 102 | // ενσωματωμένες εντολές ώστε να δημιουργήσουμε νέες μεθόδους και λειτουργίες. 103 | // Αυτές ονομάζονται functions 104 | 105 | func add(x int, y int) int { // δημιουργούμε μια δικιά μας function (συνάρτηση) ξεκινώντας την εντολή με την 106 | // λέξη func και με ένα όνομα (π.χ. add) η οποία εδώ θα κάνει μια απλή αριθμητική 107 | // πράξη προσθήκης δύο αριθμών. Η εντολή add που φτιάχνουμε παίρνει 2 ορίσματα x και y 108 | // τύπου integer (int - ακέραιος αριθμός) και δίνουν έξοδο (αποτέλεσμα πράξης) πάλι int 109 | // πηγή: https://blog.golang.org/gos-declaration-syntax 110 | 111 | return x + y // Η έξοδος: προσθέτει δυο αριθμούς τύπου int που θα δοθούν στο add(x,y) 112 | 113 | /* TIP: εφόσον τα ορίσματα είναι καί τα δύο int θα μπορούσαμε επίσης να τα γράψουμε με ένα int 114 | όπως π.χ. 115 | 116 | func add(x, y int) int { 117 | return x + y 118 | } 119 | 120 | */ 121 | 122 | } 123 | 124 | // Οι functions του προγράμματός μας ξεκινούν όπως είπαμε με τη λέξη κλειδί 125 | // "func" και περιβάλλουν τον κώδικα μέσα σε { } 126 | // Η main είναι η function που εκτελείται όταν τρέχετε το πρόγραμμά σας. 127 | // Θα εκτελεστεί αυτόματα το πρόγραμμα, χωρίς να χρειάζεται να το ξεκινήσετε 128 | // γράφοντας π.χ. main() στο τέλος του κώδικα όπως απαιτείται σε άλλες γλώσσες. 129 | 130 | func main() { // η κύρια συνάρτηση που εκτελεί την εφαρμογή 131 | 132 | fmt.Printf("Το Λειτουργικό σου σύστημα: %s\nΗ Αρχιτεκτονική του: %s\n", runtime.GOOS, runtime.GOARCH) 133 | // εκτελούμε την Printf που βρίσκεται μέσα στην fmt βιβλιοθήκη 134 | // που εισάγαμε και αντικαθιστά τα %s %s με τα αποτελέσματα των 135 | // εντολών GOOS και GOARCH της βιβλιοθήκης runtime. 136 | // η εντολή \n λέει στην Printf να τυπώσει το αμέσως επόμενο στοιχείο σε νέα γραμμή 137 | 138 | fmt.Println("Γεια σου κόσμε") // εκτελούμε την Println function που βρίσκεται 139 | // μέσα στην fmt βιβλιοθήκη που εισάγαμε. 140 | /* Println 141 | 142 | Η Println είναι και αυτή μια function μέσα απο το πακέτο fmt 143 | που "φορμάρει"- διαμορφώνει - εξάγει - τυπώνει 144 | μια συμβολοσειρά (strings), η οποία περιβάλλεται από διπλά εισαγωγικά 145 | π.χ. "Γεια σου κόσμε", σε μια νέα γραμμή στην οθόνη 146 | */ 147 | 148 | fmt.Println(add(42, 13)) 149 | /* 150 | εδώ καλούμε την δικιά μας function (add) που είχαμε 151 | δημιουργήσει και την χρησιμοποιούμε για να προσθέσουμε τους δύο int αριθμούς x,y 152 | και με την βοήθεια της fmt.Println να προβάλουμε το αποτέλεσμα στην οθόνη 153 | 154 | Μπορείτε να μάθετε για την Println αλλά και άλλες "built-in functions of standard library" 155 | πληκτρολογώντας σε ένα τερματικό: 156 | 157 | go doc fmt Println 158 | 159 | */ 160 | 161 | /* VARIABLES 162 | 163 | Οι μεταβλητές (Variables) γράφονται στατικά (statically typed), πράγμα που σημαίνει ότι ο τύπος 164 | (type - είδος - π.χ αριθμός/γράμμα/δεκαδικό κλπ) τους δεν μπορεί να αλλάξει (static). 165 | Τα ονόματα μεταβλητών πρέπει να ξεκινούν με ένα γράμμα και μπορεί να περιέχουν γράμματα, 166 | αριθμούς ή την κάτω παύλα _ 167 | 168 | Για τους αριθμούς έχουμε τους παρακάτω τύπους: 169 | Μια int (integer - ακέραιος) είναι ένας θετικός ή αρνητικός αριθμός χωρίς δεκαδικά ψηφία 170 | 171 | int8 : ονομάζεται signed 8-bit integers (-128 έως 127) 172 | int16 : ονομάζεται signed 16-bit integers (-32768 έως 32767) 173 | int32 : ονομάζεται signed 32-bit integers (-2147483648 έως 2147483647) 174 | int64 : ονομάζεται signed 64-bit integers (-9223372036854775808 έως 9223372036854775807) 175 | το int σε 32bit επεξεργαστές είναι int32 και int64 σε 64bit 176 | 177 | uint8 : ονομάζεται unsigned 8-bit integers (0 έως 255) 178 | uint16 : ονομάζεται unsigned 16-bit integers (0 έως 65535) 179 | uint32 : ονομάζεται unsigned 32-bit integers (0 έως 4294967295) 180 | uint64 : ονομάζεται unsigned 64-bit integers (0 έως 18446744073709551615) 181 | uint, uintptr σε 32bit επεξεργαστές είναι uint32 και uint64 σε 64bit 182 | */ 183 | 184 | // παράδειγμα δήλωσης μιας variable τύπου int64 185 | var age int64 = 40 186 | 187 | // Αντίθετα ένας float τύπου αριθμός είναι με δεκαδικά ψηφία: 188 | // float32, float64 189 | // παράδειγμα δήλωσης μιας variable τύπου float64 190 | var favNum float64 = 1.61803398875 191 | 192 | fmt.Println(age, " ", favNum) // Στην Println εκτός απο strings μπορείτε 193 | // να χρησιμοποιήσετε και μεταβλητές 194 | // (το κενό διάστημα προστίθεται αυτόματα οπότε δεν χρειάζεται) 195 | 196 | // Στην πραγματικότητα δε χρειάζεται να καθορίσετε τον τύπο δεδομένων, ούτε χρειάζεστε 197 | // ερωτηματικό στο τέλος όπως ίσως έχετε δει σε άλλες γλώσσες προγραμματισμού 198 | /* 199 | Δεν μπορείτε, ωστόσο αργότερα, να εκχωρήσετε έναν μη συμβατό τύπο στην μεταβλητή 200 | π.χ. να αλλάξετε το υφιστάμενο randNum που το ξεκινήσατε ως int να το κάνετε string 201 | 202 | randNum = "Hello" 203 | */ 204 | 205 | randNum := 1 // Η Go καταλαβαίνει οτι πρόκειται για var τύπου int οπότε 206 | // με τον τελεστή := χρησιμοποιήσαμε την συντομογραφία που μας παρέχει η Go 207 | // Αντί λοιπόν να γράψουμε "var randNum int", με το := 208 | // δηλώνουμε και ταυτόχρονα αρχικοποιούμε την μεταβλητή randNum 209 | 210 | fmt.Println(randNum) 211 | 212 | /* 213 | ΑΡΙΘΜΗΤΙΚΕΣ ΠΡΑΞΕΙΣ 214 | 215 | Μπορείτε επίσης να κάνετε αριθμητικές πράξεις μέσα σε Println 216 | (Σημειώστε ότι οι float αριθμοί δεν είναι ακριβείς) 217 | 218 | Διαθέσιμες αριθμητικές πράξεις : +, -, *, /, % 219 | το % ή αλλιώς modulus - modulo ή remainder είναι 220 | το υπόλοιπο μιας ακέραιας διαίρεσης 221 | */ 222 | var numOne = 1.000 // Η Go όπως είπαμε καταλαβαίνει οτι πρόκειται για float 223 | var num99 = .999 // Η Go όπως είπαμε καταλαβαίνει οτι πρόκειται για float 224 | fmt.Println(numOne - num99) 225 | 226 | a := 6 227 | b := 4.0 // float 228 | fmt.Println("6 + 4 =", 6+4) 229 | fmt.Println("6 - 4 =", 6-4) 230 | fmt.Println("6 * 4 =", 6*4) 231 | fmt.Println("6 / 4 =", 6/4) 232 | fmt.Println("6 % 4 =", 6%4) 233 | // το % operator (ακέραιας διαίρεσης) είναι διαθέσιμο μόνο για integers. 234 | // Άρα θα πρέπει να μετατρέψουμε το float σε int όπως παρακάτω. 235 | 236 | fmt.Println("6 % int(4.0) =", a%int(b)) 237 | // χρησιμοποιώ την function int() για να μετατρέψω το 4.0 (float) σε 4 (int) 238 | 239 | } 240 | -------------------------------------------------------------------------------- /03_logic_for_loops/logic_for_loops.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε: 3 | - Θα δούμε πως δηλώνουμε λογικές συνθήκες, 4 | όπως "αληθείς", "ψευδής", "και", "ή", "είναι", "δεν είναι" κ.α. 5 | - Πως φτιάχνουμε επαναλαμβανόμενες λειτουργίες με βρόγχους for 6 | */ 7 | 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "time" 13 | ) 14 | 15 | func main() { 16 | 17 | // Λογικοί τελεστές χρησιμοποιούνται για να ελέγξουμε αν μια κατάσταση 18 | // είναι αληθής (true) ή ψευδής (false) 19 | // Τα αποτελέσματα χρήσης των τελεστών παριστάνονται παρακάτω: 20 | fmt.Println(" === Λογικοί τελεστές ===") 21 | fmt.Println("true && false =", true && false) // && το οποίο σημαίνει "και" 22 | fmt.Println("true || false =", true || false) // || το οποίο σημαίνει "ή" 23 | fmt.Println("!true =", !true) // ! το οποίο σημαίνει "δεν είναι" 24 | /* 25 | Η προτεραιότητα υπολογισμού των τελεστών ορίζεται 26 | απο πάνω (υψηλή) προς τα κάτω (χαμηλή) ως εξής: 27 | () 28 | ! + - 29 | * / % 30 | + - 31 | < <= > >= 32 | == != 33 | && 34 | || 35 | */ 36 | 37 | /* 38 | Η Go έχει μόνο μία δομή (construct) βρόχου, την "for" loop και δεν 39 | διαθέτει "while" loop. Μπορεί να ακούγεται λίγο παραπλανητικό αλλά 40 | αυτό που θα πρέπει να καταλάβετε είναι ότι η Go έχει μόνο μία 41 | εντολή (μία λέξη -κλειδί) που χρησιμοποιείται για την "επανάληψη" 42 | μιας διεργασίας. 43 | 44 | Μην σας προβληματίζει αυτό διότι στην Go, η for είναι αρκετά ευέλικτη, 45 | οπότε μπορούμε να το χρησιμοποιήσουμε σε infinite loop βρόχους, 46 | μπορούμε να το χρησιμοποιήσουμε σε βρόχο λογικής όπως όταν μια 47 | έκφραση Boole (λογική συνθήκη) αποτιμάται ως αληθής, μπορούμε 48 | να το χρησιμοποιήσουμε σε βρόχο που μοιάζει με "while" και 49 | μπορούμε να το χρησιμοποιήσουμε για να εξετάσουμε μια λίστα τιμών, 50 | όπως έναν πίνακα ή μια slice ή map (θα τα δούμε σε επόμενο μάθημα). 51 | 52 | Περιλαμβάνει δύο μορφές. 53 | 54 | Η βασική μορφή του βρόχου έχει τρία συστατικά χωρισμένα με ερωτηματικά: 55 | 56 | 1) την init statement (αρχική κατάσταση): εκτελείται πριν 57 | από την πρώτη επανάληψη. 58 | 2) η condition expression (συνθήκη): αξιολογείται πριν από κάθε επανάληψη 59 | 3) η post statement(αποτέλεσμα): εκτελείται στο τέλος κάθε επανάληψης 60 | 61 | Σημείωση: Σε αντίθεση με άλλες γλώσσες, όπως C, Java ή JavaScript, 62 | δεν υπάρχουν παρενθέσεις που να περιβάλλουν τα τρία στοιχεία της δήλωσης for 63 | και οι αγκύλες {} απαιτούνται πάντα. 64 | 65 | Η init statement είναι συχνά μια σύντομη δήλωση μεταβλητής και οι μεταβλητές 66 | που δηλώνονται εκεί είναι ορατές μόνο στο πεδίο της δήλωσης for. 67 | Ο βρόχος θα σταματήσει την επανάληψη όταν η κατάσταση boolean εκτιμάται ως ψευδής. 68 | Με άλλα λόγια όσο η συνθήκη που έχουμε δώσει είναι αληθείς, 69 | το for θα επαναλαμβάνει την διεργασία του. 70 | 71 | Διαδικασίες ελέγχου μιας σχέσης μεταβλητών περιλαμβάνουν : 72 | - == (είναι) 73 | - != (δεν είναι) 74 | - < (μικρότερο απο) 75 | - > (μεγαλύτερο από) 76 | - <=(μικρότερο ή ίσο με) 77 | - >=(μεγαλύτερο ή ίσο με) 78 | */ 79 | fmt.Println(" \n === For Loop ===") 80 | fmt.Println(" \n === απο 1 έως 10 ===") 81 | 82 | i := 1 83 | // Εδώ βλέπουμε την απλή μορφή με μία συνθήκη που μοιάζει με (while i <= 10) 84 | for i <= 10 { // Η συνθήκη μας εδώ είναι: 85 | // "όσο το i είναι μικρότερο ή ίσο με το 10" 86 | 87 | /* Προσοχή: αν γράψουμε την for χωρίς συνθήκες: 88 | 89 | for { 90 | } 91 | 92 | τότε θα έχουμε φτιάξει έναν βρόγχο που θα εκτελείται 93 | στο άπειρο διότι η Go θεωρεί οτι εφόσον έχουμε κενή 94 | συνθήκη, έχουμε μια bool συνθήκη (αληθής για πάντα): 95 | 96 | */ 97 | fmt.Println(i) // Ζητάμε να τυπώσει την νέα κατάσταση του i 98 | 99 | i++ // όσο το i 100 | // είναι μικρότερο ή ίσο με το 10, θα προσθέτουμε 1 στο i. 101 | // δηλαδή i = i + 1 το οποίο είναι συντομογραφία του i++ 102 | } 103 | 104 | fmt.Println(" \n === For Loop ===") 105 | fmt.Println(" \n === απο 1 έως 10 ===") 106 | // Αντίθετα, παρακάτω βλέπουμε τη βασική μορφή της for 107 | // Ας φτιάξουμε ένα ψεύτικο πρόγραμμα αυτοκαταστροφής 108 | 109 | for j := 10; j >= 0; j-- { 110 | // init statement (αρχική κατάσταση) όπου το j είναι 0 111 | // condition expression (συνθήκη), όπου λέμε οτι όσο το j είναι μικρότερο του 5 112 | // post statement(αποτέλεσμα),τότε αυξάνουμε το j κατα μια μονάδα 113 | fmt.Println(" \n αυτοκαταστροφή σε:") 114 | fmt.Println(j) 115 | 116 | pafsi := time.Second // ορίζουμε μια μεταβλητή "pafsi" και του δίνουμε τιμή δευτερολέπτου 117 | time.Sleep(pafsi) // του λέμε να περιμένει (time.Sleep) με βάση την τιμή που έχει η "pafsi" 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /04_if_else_if_switch/if_else_if_switch.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε: 3 | - Ομαδοποίηση πολλών import 4 | - Εσωτερικές, εξωτερικές μεταβλητές 5 | - Πως παράγουμε τυχαίους αριθμούς 6 | - Σύνταξη της if else (συνθήκες) 7 | - Σύνταξη της Switch 8 | - Πληροφορίες λειτουργικούς συστήματος 9 | */ 10 | 11 | package main 12 | 13 | import ( 14 | "fmt" 15 | "math" 16 | "math/rand" 17 | "runtime" 18 | "time" 19 | /* 20 | Όταν χρειαζόμαστε περισσότερες λειτουργίες μπορούμε να εισάγουμε 21 | βιβλιοθήκες (έτοιμες functions). 22 | 23 | Εδώ τις ομαδοποιούμε σε μια import χρησιμοποιώντας την παρένθεση 24 | */) 25 | 26 | func power(x, n, lim float64) float64 { // Φτιάχνουμε μια variable με όνομα power 27 | // που παίρνει 3 τιμές τύπου float64 και επιστρέφει αποτέλεσμα float64 28 | 29 | /* Όπως σε άλλες γλώσσες, όταν θέλουμε να εξετάσουμε μια συνθήκη 30 | η να εκτελέσουμε υπο προυποθέσεις κάποια εργασία, τότε μπορούμε 31 | να το κάνουμε με την "if". 32 | 33 | Η βασική της χρήση είναι για να αξιολογούμε μια κατάσταση. 34 | Αν αυτή είναι αληθής, διακλαδίζουμε σε έναν τρόπο όπου 35 | εκτελούμε κάποιο συγκεκριμένο κώδικα. Αν όμως είναι ψευδής ή μη αληθής, 36 | διακλαδίζουμε σε έναν άλλο τρόπο. 37 | Επομένως στην Go, η συνθήκη που αξιολογούμε πρέπει να αξιολογηθεί ως 38 | συνθήκη Boolean (true ή false). Δεν μπορούμε να χρησιμοποιήσουμε 39 | ακέραιους αριθμούς ή συμβολοσειρές για να αντιπροσωπεύσουμε 40 | μια αληθής ή ψευδής συνθήκη και στη συνέχεια να ελπίζουμε 41 | ότι η Go θα τα μετατρέψει σε Booleans. 42 | 43 | Οι δηλώσεις "if" της Go είναι όπως και οι βρόχοι "for". 44 | 45 | Η δήλωση (statement) δε χρειάζεται να περιβάλλεται από παρενθέσεις () 46 | αλλά απαιτούνται τα αγκύλες {}. 47 | 48 | Όπως και στην for, το if μπορεί να ξεκινήσει με μια σύντομη δήλωση 49 | variable που θα εκτελεστεί πριν από την συνθήκη δηλαδή χωρίς να 50 | χρειαστεί να της δημιουργήσουμε εκ των προτέρων. 51 | Όμως οι variables που ορίζονται στην δήλωση ισχύουν μόνο μέχρι το 52 | τέλος του if και δεν μπορούν να χρησιμοποιηθούν εκτός. 53 | Στο παράδειγμά μας μπορείτε να δοκιμάσετε να χρησιμοποιήσετε 54 | το v στην τελευταία δήλωση επιστροφής (εκτός του βρόγχου if) 55 | */ 56 | 57 | if v := math.Pow(x, n); v < lim { // ο αριθμός v που θα δώσουμε ισούται 58 | // με τον αριθμό x εις την n αλλά και μικρότερο του αριθμού lim 59 | // επέστρεψε μου τον αριθμο v 60 | return v 61 | } 62 | return lim // Δοκίμασε να βάλεις "v" 63 | /* Σημείωση: Θα παρατηρήσατε οτι κάποια variable ξεκινάνε με κεφαλαίο το 64 | πρώτο γράμμα, ενώ άλλα με μικρά. Αυτά ονομάζονται exported/un-exported: 65 | Όταν ξεκινάει με κεφαλαία τότε η μέθοδος είναι προσβάσιμη από άλλα 66 | αρχεία της go. Αυτό θα το δούμε και σε επόμενα μαθήματα 67 | */ 68 | } 69 | 70 | func power2(x, n, lim float64) float64 { 71 | /* 72 | Οι μεταβλητές όμως που δηλώνονται μέσα σε μια σύντομη δήλωση 73 | if είναι διαθέσιμες μέσα σε οποιοδήποτε άλλο μπλοκ. 74 | (Και οι δύο κλήσεις προς την "power2" επιστρέφουν 75 | τα αποτελέσματά τους πριν την κλήση στο fmt.Println της main). 76 | */ 77 | if v := math.Pow(x, n); v < lim { 78 | return v 79 | } else { 80 | fmt.Printf("%g >= %g\n", v, lim) 81 | } 82 | return lim 83 | } 84 | 85 | func main() { 86 | // Ας εκτελέσουμε τις power, power2 που φτιάξαμε παραπάνω, τροφοδοτόντας τις 87 | // με 3 αριθμούς 88 | fmt.Println( // μπορούμε να ομαδοποιήσουμε σε ένα fmt.Println με παρένθεση 89 | "this power:", power(3, 2, 10), 90 | "\nand that power:", power(3, 3, 20), 91 | "\nthis power2:", power2(3, 2, 10), 92 | "\nand that power2:", power2(3, 3, 20), 93 | ) 94 | fmt.Println("Η ημερομηνία και η ώρα είναι:", time.Now()) 95 | // εκτελούμε την υπορουτίνα Now της time 96 | fmt.Println("Ο τυχαίος αριθμός μου είναι το:", rand.Intn(10)) 97 | // η Intn επιστρέφει έναν ακέραιο (integer) ψευδο-τυχαίο αριθμό απο 0 έως n 98 | // για να εμφανίζουμε πραγματικό τυχαίο αριθμό κάθε φορά 99 | // που τρέχουμε το πρόγραμμα μας, θα χρειαστεί να τροφοδοτήσουμε (rand.Seed) 100 | // την εφαρμογή με πραγματική τυχαιότητα π.χ. τον χρόνο (time.Now().UnixNano()) 101 | // πηγή: https://pkg.go.dev/math/rand 102 | 103 | rand.Seed(time.Now().UnixNano()) // τροφοδοτούμε τυχαιότητα 104 | fmt.Println("Ο πραγματικά τυχαίος μου αριθμός είναι το:", rand.Intn(10)) 105 | 106 | // το %g είναι θέση που θα πάρει το αποτέλεσμα της εκτέλεσης Sqrt στον αριθμό 7 107 | fmt.Printf("Τώρα έχεις %g προβλήματα.\n", math.Sqrt(7)) 108 | fmt.Println("Ο αριθμός π =", math.Pi) // η math περιλαμβάνει και άλλες υπορουτίνες 109 | // προσβάσιμες με math.κάτι πηγή: https://pkg.go.dev/math#pkg-examples 110 | 111 | // Ας δούμε ένα παράδειγμα με if για να ελέγξουμε αν είσαι ενήλικας 112 | // και μπορείς να οδηγήσεις αυτοκίνητο: 113 | yourAge := 19 // αλλάξτε το σε ότι αριθμό ηλικίας θέλετε 114 | fmt.Println("\n === Πρώτη if ===") 115 | if yourAge >= 18 { 116 | fmt.Println("Μπορείς να οδηγήσεις (πρώτο if)") 117 | } else { 118 | fmt.Println("Δεν μπορείς να οδηγήσεις") 119 | } 120 | 121 | // Μπορείτε να χρησιμοποιήσετε την "else if" όπως παρακάτω για να 122 | // ελέγξετε και άλλες περιπτώσεις-συνθήκες, αλλά μόλις μία απο αυτές 123 | // συμβεί να είναι αληθής τότε οι υπόλοιπες συνθήκες θα αγνοηθούν: 124 | fmt.Println("\n === Δεύτερη if ===") 125 | if yourAge >= 18 { 126 | fmt.Println("Μπορείς να οδηγήσεις (δεύτερο if)") 127 | } else if yourAge >= 19 { 128 | fmt.Println("Μπορείς να ψηφίσεις") 129 | } else { 130 | fmt.Println("Μπορείς να διασκεδάσεις") 131 | } 132 | 133 | /* Ας δούμε όμως πως μπορούμε να γράψουμε το παραπάνω με 134 | την Switch. 135 | 136 | Μια εντολή switch (διακόπτης) είναι ένας συντομότερος 137 | τρόπος για να γράψετε μια ακολουθία if-else statements. 138 | Εκτελεί την πρώτη περίπτωση της οποίας η τιμή είναι 139 | ίση με την έκφραση της κατάστασης. 140 | Αν δεν ισχύει καμία τότε εκτελείται η "default" συνθήκη. 141 | 142 | Η switch της Go είναι ίδια με αυτήν στην C, C ++, Java, 143 | JavaScript και PHP, με εξαίρεση ότι η Go εκτελεί μόνο την 144 | επιλεγμένη περίπτωση, όχι όλες τις περιπτώσεις που ακολουθούν. 145 | Επίσης σε αντίθεση με τις γλώσσες αυτές, στη Go δεν είναι 146 | απαραίτητη η ύπαρξη εντολής διακοπής (brake) 147 | του βρόχου switch γιατί εφόσον πληρείται η συνθήκη, 148 | ο βρόχος τερματίζει αυτόματα. 149 | 150 | Μια άλλη σημαντική διαφορά είναι ότι οι περιπτώσεις switch της Go 151 | δεν χρειάζεται να είναι σταθερές και οι τιμές που απαιτούνται 152 | δεν πρέπει να είναι ακέραιοι. Η switch συγκρίνει την αποθηκευμένη τιμή 153 | στην switch με αυτή στα case και ψάχνει κάποιο που ταιριάζει, οπότε το 154 | type του switch με το type του case πρέπει να είναι ίδια και δεν μπορεί 155 | π.χ. το switch να ψάχνει int αριθμό ενώ τα case μιλάνε για strings. 156 | */ 157 | fmt.Println("\n === Switch ===") 158 | switch yourAge { 159 | /* 160 | Οι switch εντολές εναλλαγής περιπτώσεων διαβάζονται από 161 | αριστερά προς τα δεξιά και από πάνω προς τα κάτω, 162 | με εξαίρεση το default μπλοκ, το οποίο μπορεί να πάει οπουδήποτε, 163 | (πρώτη, μεσαία ή τελευταία θέση. Συνηθίζεται όμως να το βάζουμε τελευταίο. 164 | */ 165 | case 18: 166 | fmt.Println("Μπορείς να οδηγήσεις μέσω switch") 167 | case 19: 168 | fmt.Println("Μπορείς να ψηφίσεις μέσω switch") 169 | default: // Η default είναι σε περίπτωση καμία απο τις άλλες δεν ισχύει 170 | fmt.Println("Μπορείς να διασκεδάσεις μέσω switch") 171 | } 172 | 173 | // Όπως θα δείτε, εδω καλούμε την myOS() ενώ έχει 174 | // δημιουργηθεί μετά την "func main". Στην Go δεν έχει σημασία 175 | // αν οι δικές σας συναρτήσεις θα μπούνε πριν η μετά την "func main()" 176 | // σε αντίθεση με άλλες γλώσσες που πρέπει να δηλώνονται στην αρχή 177 | // του προγράμματος 178 | myOS() 179 | 180 | } 181 | 182 | func myOS() { 183 | fmt.Print("Η Go τρέχει σε ") 184 | arch := runtime.GOARCH 185 | fmt.Printf("%s / ", arch) 186 | switch os := runtime.GOOS; os { 187 | // για να δεις όλα τα διαθέσιμα λειτουργικά της GOOS τρέξε "go tool dist list" 188 | case "darwin": 189 | fmt.Println("OS X.") 190 | case "linux": 191 | fmt.Println("Linux.") 192 | default: 193 | // freebsd, openbsd, 194 | // plan9, windows... 195 | fmt.Printf("%s\n", os) 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /06_maps/maps.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε 3 | - Θα δούμε τι είναι και πως φτιάχνουμε maps 4 | - πως προσθέτουμε, να επικαιροποιούμε ή και αφαιρούμε στοιχεία 5 | - να αποθηκεύουμε μια τιμή του map σε μεταβλητή 6 | - να κάνουμε αναζήτηση αν υπάρχει κάποιο στοιχείο στο map 7 | - Εντολές, make, delete, 8 | */ 9 | 10 | package main 11 | 12 | import "fmt" 13 | 14 | func main() { 15 | 16 | /* 17 | Maps - Χάρτες 18 | 19 | Τα "Map" είναι μία δομή δεδομένων η οποία αποθηκεύει 20 | ζευγάρια της μορφής "κλειδί,τιμή" όπως μια βάση δεδομένων. 21 | Μοιάζουν με τα array και slices στο γεγονός οτι είναι λίστες. 22 | 23 | Εναλλακτικά ονόματά του είναι 24 | - πίνακας κατακερματισμού (hash table) 25 | - ή λεξικό (dictionary) 26 | - ή χάρτης/συσχετιστικός πίνακας (map/associative array) 27 | 28 | είναι μία πιο ευέλικτη παραλλαγή της εγγραφής δεδομένων, στην οποία 29 | τα ζευγάρια κλειδιού-τιμής μπορούν να εισαχθούν και να διαγραφούν ελεύθερα. 30 | 31 | οι χάρτες χρησιμοποιούνται για να αναζητήσετε μια 32 | τιμή από το αντίστοιχο κλειδί της (σαν μια μικρή βάση δεδομένων). 33 | 34 | Η μηδενική τιμή ενός χάρτη είναι "nil". Ένας "nil" χάρτης 35 | δεν έχει κλειδιά, ούτε μπορούν να προστεθούν κλειδιά. 36 | Θα πρέπει πάντα να δηλώνουμε το keyType αλλά και το valueType όταν φτιάχνουμε 37 | ένα map. Επίσης keyType πρέπει να είναι "συγκρίσιμου" τύπου. Δηλαδή ένας τύπος 38 | που μπορεί να συγκριθεί με το "ίσο με - όχι ίσο με" των Boolean comparison operators. 39 | Αρα, θα είναι τύπου Bool, string, αριθμητικοί τύποι και οποιοςδήποτε άλλος τύπος αλλά 40 | όχι τύπου slices 41 | 42 | var name map[string]int 43 | 44 | */ 45 | 46 | /* 47 | Έστω ότι θέλουμε ένα map xartis 48 | 49 | var parking map[string]int 50 | fmt.Println(parking) 51 | 52 | xartis["Mercedes"] = 15 53 | fmt.Println(xartis) 54 | 55 | Ο κώδικας αυτός όμως θα σας εμφανίσει σφάλμα στην μεταγλώττιση 56 | διότι τα maps πρέπει να αρχικοποιηθούν πριν μας επιτραπεί 57 | να τα χρησιμοποιήσουμε 58 | */ 59 | // Άρα θα χρησιμοποιήσουμε την make για να αρχικοποιήσουμε ένα map μας 60 | presAge := make(map[string]int) // Δημιουργούμε ένα map με keyType string 61 | // και valueType intiger 62 | // varName := make(map[keyType] valueType) 63 | 64 | presAge["Molybdenum"] = 42 // Η εντολή αυτή είναι παρόμοια με αυτή που 65 | // είδαμε στα arrays, αλλά το κλειδί αντί να είναι ένας intiger (ακέραιος), 66 | // είναι ένα string επειδή ο τύπος του κλειδιού του map είναι string. 67 | 68 | fmt.Println(presAge["Molybdenum"]) 69 | fmt.Println("Τι έχουμε εδώ: ", presAge) 70 | 71 | fmt.Println(len(presAge)) // Λήψη αριθμού των στοιχείων στο χάρτη 72 | 73 | presAge["Technetium"] = 43 // Το μέγεθος του "presAge" map 74 | // αλλάζει όταν προστίθεται ένα νέο στοιχείο 75 | fmt.Println("Νεο μήκος = ", len(presAge)) 76 | fmt.Println("Τι έχουμε εδώ: ", presAge) 77 | 78 | delete(presAge, "Technetium") // Μπορούμε να διαγράψουμε 79 | // χρησιμοποιώντας την function "delete()" 80 | fmt.Println("Νεο μήκος = ", len(presAge)) 81 | fmt.Println("Τι έχουμε εδώ: ", presAge) 82 | 83 | fmt.Println("\n== myCustomMap ==") 84 | myCustomMap() 85 | } 86 | 87 | func myCustomMap() { 88 | 89 | m := make(map[string]int) // δημιουργούμε έναν 90 | // nil ("άδειο") Map, έτοιμο για χρήση 91 | fmt.Println("Η αρχική τιμή είναι:", m["Answer"]) // άδειος άρα 0 92 | 93 | m["Answer"] = 42 // παίρνει τιμή 42 94 | fmt.Println("Η νέα τιμή είναι:", m["Answer"]) 95 | 96 | m["Answer"] = 48 // Αλλάζω το 42 σε 48 χρησιμοποιώντας την ίδια θέση "Answer" 97 | fmt.Println("Η αλλαγμένη τιμή είναι:", m["Answer"]) 98 | 99 | timi := m["Answer"] // αντιγράφω την τιμή σε 100 | // μια νεα μεταβλητή "timi" 101 | fmt.Println("Η τιμή της timi είναι:", timi) 102 | fmt.Println("Το διπλάσιο της timi είναι: ", timi+timi) // μπορούμε να 96 103 | 104 | delete(m, "Answer") // η πρώτη παράμετρος πρέπει 105 | // να είναι Map η δεύτερη το Κλειδί 106 | fmt.Println("Μετά την διαγραφή η τιμή του map είναι:", m["Answer"]) // διαγράφεται το 48, αρα 0 107 | 108 | fmt.Println("\n== Ένα map τύπου int ") 109 | intMap := make(map[int]int) 110 | fmt.Println("Αρχική τιμή του intMap:", intMap[0]) 111 | intMap[0] = 5 112 | fmt.Println("Νεα τιμή του intMap:", intMap[0]) 113 | 114 | /* 115 | Ελέγξτε ότι υπάρχει ένα κλειδί με μια εκχώρηση δύο τιμών: 116 | 117 | elem, ok = m[key] 118 | 119 | Αν το κλειδί είναι σε m, είναι αληθές. 120 | Αν όχι, το ok είναι ψευδές. 121 | 122 | Αν το κλειδί δε βρίσκεται στο map, 123 | τότε το elem είναι η μηδενική τιμή για τον τύπο του στοιχείου του χάρτη. 124 | */ 125 | fmt.Println("\n== Αναζήτηση στοιχείων ==") 126 | elem, ok := m["Answer"] 127 | fmt.Println("Η τιμή:", elem, "Υπάρχει;", ok) 128 | 129 | // Μπορούμε επίσης να αποθηκεύσουμε πολλαπλά στοιχεία σε ένα χάρτη 130 | fmt.Println("\n== Πολλαπλά στοιχεία ==") 131 | // Φτιάχνουμε μια μικρή "βάση δεδομένων" με όνομα : 132 | // superhero 133 | // Η δομή της θυμοίζει με πίνακα με σειρές και στήλες : 134 | 135 | /* 136 | __Superman_____Batman_____Wonder Woman__ 137 | realname |Clark Kent |Bruce Wayne |Diana Prince | 138 | city |Metropolis |Gotham City |Themyscira | 139 | 140 | */ 141 | 142 | superhero := map[string]map[string]string{ 143 | // Ο εξωτερικός χάρτης χρησιμοποιείται ως ένας πίνακας αναζήτησης 144 | // με βάση το όνομα του ήρωα, ενώ οι εσωτερικοί χάρτες χρησιμοποιούνται 145 | // για την αποθήκευση γενικών πληροφοριών σχετικά με τους ήρωες 146 | 147 | "Superman": { 148 | "realname": "Clark Kent", 149 | "city": "Metropolis", 150 | "origin": "Krypton", // τα maps δεν είναι διαδοχικά 151 | // οπότε τα στοιχεία δεν αποθηκεύονται με αριθμητική σειρά. 152 | // Εδώ τα String θα προβληθούν με αλφαβητική 153 | // σειρά του ονόματος του κλειδιού 154 | // (πρώτα το city, μετά το origin, τέλος το realname) 155 | }, 156 | 157 | "Batman": { 158 | "realname": "Bruce Wayne", 159 | "city": "Gotham City", 160 | }, 161 | 162 | "Wonder Woman": { 163 | "realname": "Diana Prince", 164 | "city": "Themyscira", 165 | }, 166 | } 167 | 168 | // Μπορούμε να εξάγουμε δεδομένα όπου το κλειδί ταιριάζει με το Superman 169 | fmt.Println("Η δομή του map Superhero είναι: ", superhero) 170 | 171 | // Αν ψάξουμε κάποιον ήρωα που δεν υπάρχει : 172 | fmt.Println(superhero["Flash"]) // θα εμφανίσει απλά οτι είναι ένα κενό map 173 | /* 174 | Εδώ το map θα επέστρεφε την τιμή μηδέν για τον 175 | τύπο της τιμής αλλά επειδή το map μας περιλαμβάνει strings 176 | τότε είναι το κενό string. 177 | 178 | Παρόλο που θα μπορούσαμε να ελέγξουμε τη μηδενική τιμή 179 | στην περίπτωση μας (superhero["Flash"] == "") 180 | η Go παρέχει έναν καλύτερο τρόπο: 181 | 182 | temp, ok := superhero["Flash"] 183 | fmt.Println(temp, ok) 184 | */ 185 | // Η πρόσβαση σε ένα στοιχείο ενός χάρτη μπορεί 186 | // να επιστρέψει δύο τιμές αντί για μια. Η πρώτη τιμή 187 | // είναι το αποτέλεσμα της αναζήτησης, η δεύτερη μας λέει 188 | // αν ήταν ή όχι η αναζήτηση επιτυχής 189 | 190 | if element, ok := superhero["Superman"]; ok { // πρώτα παίρνουμε την τιμή 191 | // απο το map, στη συνέχεια αν είναι επιτυχείς τρέχει ο παρακάτω κώδικας 192 | fmt.Println("ψάξατε για", element, "η αναζήτηση ήταν επιτυχής;", ok) 193 | } 194 | // Εναλλακτικά μπορούμε να εμφανίσουμε απευθείας τα στοιχεία 195 | if temp, hero := superhero["Superman"]; hero { 196 | fmt.Println(temp["realname"], "of", temp["city"]) 197 | } 198 | // Ας τα εμφανίσουμε σε 3 σειρές 199 | for key, value := range superhero { 200 | fmt.Println("Key:", key, " - Values:", value) 201 | } 202 | /* 203 | Είναι σημαντικό να γίνει κατανοητό οτι, όπως και με τα slices, τα maps 204 | είναι τύποι αναφοράς. Αυτό σημαίνει ότι τα maps παραλαμβάνονται (κλήσεις) 205 | απο άλλα func με παραπομπή και όχι απευθείας με τις τιμές τους. 206 | 207 | Έτσι, κατά τη κλήση των maps σε functions, η Go δεν δημιουργεί ξεχωριστό αντίγραφο 208 | των τιμών των maps τοποθετώντας τα σε μια αντίγραφη στοίβα για χρήση απο την εν λόγω 209 | function. Έτσι, οι αλλαγές που κάνετε σε ένα map είναι ορατές και στις κλήσεις που γίνονται 210 | σε αυτό αλλά και σε οποιεσδήποτε άλλες functions που αναφέρονται σε αυτό. 211 | 212 | Για αυτό τον λόγο τα maps δεν είναι ασφαλείς για concurency αφού η ταυτόχρονη 213 | ανάγνωση και εγγραφή σε maps μπορεί να οδηγήσει σε προβλήματα. 214 | Είναι απλά δείκτες και όχι τα πραγματικά δεδομένα που μεταφέρονται. 215 | 216 | Τέλος θεωρείται μια καλή πρακτική να καθορίζουμε το μέγεθος 217 | ενός map όποτε είναι δυνατόν. Δεν είναι μεν υποχρεωτικό, αλλά μπορεί 218 | να βελτιώσει την απόδοση, ειδικά αν πρόκειται να εργαστείτε με μεγάλα maps. 219 | Επειδή μοιάζουνε με τα slices όσον αφορά τον τρόπο που μεγαλώνουν, προσπαθήστε 220 | να δώσετε μια ιδέα στην Go για το πόσο μεγάλο περιμένετε να γίνει το map σας. 221 | Μπορεί να συμβάλει στη βελτίωση της απόδοσης του. 222 | */ 223 | } 224 | -------------------------------------------------------------------------------- /07_func_recursion_closure_recover_defer_panic/func_recursion_recover_defer_panic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε: 3 | - Θα εστιάσουμε στις συναρτήσεις (functions ή func) 4 | - Πως φτιάχνουμε func που δέχονται πολλαπλές εισόδους και εξόδους 5 | - Πως φτιάχνουμε func που δέχονται απροσδιόριστο αριθμό τιμών, όταν 6 | δεν ξέρουμε εξαρχής πόσες εισόδους θα λάβει 7 | - Πως αλλάζουμε το πρώτο γράμμα μιας λέξης σε κεφαλαίο ή 8 | όλη την λέξη σε κεφαλαία 9 | - Πως βρίσκουμε τον μικρότερο αριθμό απο ένα σύνολο αριθμών 10 | - Πως φτιάχνουμε func αναδρομής (recursion), όταν η function 11 | καλεί τον εαυτό της 12 | - Πως φτιάχνουμε μια αναμονή αποτελέσματος (defer) 13 | - Πως ανακτούμε την συνέχεια λειτουργίας μετά απο σφάλμα με την recover() 14 | 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | ) 23 | 24 | /* 25 | Όπως είδαμε οι συναρτήσεις (func, functions) μας επιτρέπουν 26 | την επαναχρησιμοποίηση κώδικα και συμβάλουν στην δημιουργία 27 | μιας λειτουργικής δομής στον κώδικά μας. 28 | 29 | Οι συναρτήσεις είναι επίσης γνωστές ως διαδικασίες (procedures) 30 | ή υπορουτίνες (subroutines) 31 | 32 | Μπορούμε να χρησιμοποιήσουμε τις συναρτήσεις ως παράμετροι, 33 | να τις αναθέσουμε σε variables και άλλες δομές δεδομένων κλπ. 34 | 35 | Μέχρι τώρα στα προγράμματα που έχουμε γράψει στη Go, έχουμε 36 | χρησιμοποιήσει μόνο μία συνάρτηση : 37 | 38 | func main() {} 39 | Τώρα θα δούμε πως γράφουμε προγράμματα που χρησιμοποιούν περισσότερες 40 | από μία συναρτήσεις 41 | Σε γενικές γραμμές είναι της μορφής: 42 | 43 | func onomafunc (parametersPassed) returnType { 44 | .... // σώμα της συνάρτησης, το οποίο είναι 45 | //μια σειρά από εντολές μεταξύ των αγκυλών 46 | } 47 | 48 | οι variables που χρησιμοποιούνται εντός της συνάρτησης 49 | δε δύναται να χρησιμοποιηθούν εκτός αυτής 50 | 51 | Παρακάτω ξεκινάμε δημιουργώντας μερικές δικές μας func 52 | */ 53 | 54 | func addThemUp(numbers []float64) float64 { 55 | /* 56 | H addThemUp λαμβάνει μια Array τύπου float64 και επιστρέφει float64 57 | Η επιστροφή θα μπορούσε να έχει και όνομα π.χ. rtrnNumbers float64 58 | αλλά επειδή δεν την χρειαζόμαστε και δεν θα τα χρησιμοποιήσουμε αλλού, 59 | δεν την ονομάζουμε. 60 | Οι παράμετροι - ορίσματα (parametersPassed) που λαμβάνει μια function 61 | ως είσοδο και φυσικά επιστρέφει ως έξοδο ονομάζονται function signature 62 | */ 63 | sum := 0.0 // Δηλώνουμε μια variable sum με τιμή εκκίνησης 0.0 64 | 65 | for _, val := range numbers { 66 | /* 67 | η range μας δίνει key:value 68 | αλλά εμάς δεν μας ενδιαφέρει η key οπότε δεν την αποθηκεύουμε 69 | σε κάποια variable αλλά την αγνοούμε με την "_" 70 | 71 | */ 72 | 73 | sum += val // Συντομογραφία για sum = sum + val 74 | 75 | } 76 | 77 | return sum // Παρατηρούμε ότι αντικαταστήσαμε την fmt.Println 78 | // με την return. Η εντολή return σταματάει τη συνάρτηση 79 | // αμέσως και μετά επιστρέφει την τιμή στην συνάρτηση που την κάλεσε αυτή. 80 | // Διαβάστε αναλυτικά https://golang.org/ref/spec#Return_statements 81 | 82 | } 83 | 84 | // Οι Go functions μπορούν να επιστρέψουν πολλές τιμές 85 | // Εδώ οι επιστροφές είναι ανώνυμες αφού όπως είπαμε δεν 86 | // την χρειαζόμαστε και δεν θα τα χρησιμοποιήσουμε αλλού, 87 | // δεν την ονομάζουμε. 88 | func next2Values(number int) (int, int) { // επιστρέφει 2 αριθμούς 89 | 90 | return number + 1, number + 2 // επιστρέφει 2 αριθμούς 91 | 92 | } 93 | 94 | func converter(epaggelma, onomatEponimo string) (s1, s2 string) { 95 | /* 96 | Λέμε στην function να αποδεχτεί δύο strings ως είσοδο και να επιστρέψει 97 | δύο strings σε αυτό που την καλεί. Στη συνέχεια, μέσα στην function, 98 | αλλάζουμε την περίπτωση των δύο μεταβλητών που χρησιμοποιηθηκαν ως είσοδο, 99 | την μία σε titleCase (Κεφαλαίο αρχικό γράμμα) και την άλλη σε κεφαλαία 100 | τα οποία και επιστρέφουμε με τις τροποποιημένες τους συμβολοσειρές. 101 | 102 | */ 103 | s1 = strings.Title(epaggelma) 104 | s2 = strings.ToUpper(onomatEponimo) 105 | /* 106 | Όταν θα καλούμε τη "converter" συνάρτηση μας, εδώ διαβιβάζουμε αντίγραφα της μεταβλητής 107 | "epaggelma" και την variable "onomatEponimo", ενώ στην function signature, 108 | αν θέλουμε, μπορούμε να τις αντιστοιχίσουμε με διαφορετικά ονόματα, 109 | ας πούμε s1 και s2. Το μόνο που πρέπει να γνωρίζουμε εδώ 110 | είναι η σειρά με την οποία πέρασαν. 111 | Έτσι, στο s1 πρόκειται να εκχωρηθεί η τιμή από το αλλαγμένο "epaggelma" και στην 112 | s2 η τιμή από το αλλαγμένο "onomatEponimo". 113 | */ 114 | return s1, s2 115 | 116 | //return epaggelma, onomatEponimo 117 | } 118 | 119 | // Μπορείτε να λάβετε έναν απροσδιόριστο αριθμό τιμών 120 | // με τις 3 τελείες "args ... int" 121 | // Αυτά ονομάζονται variadic functions 122 | func subtractThem(args ...int) int { 123 | 124 | finalValue := 0 125 | 126 | for _, value := range args { 127 | finalValue -= value 128 | } 129 | 130 | return finalValue 131 | 132 | } 133 | 134 | func mikroterosArithmos(kapoioiArithmoi ...int) int { 135 | /* 136 | Δημιουργούμε μια μεταβλητή εδώ "mikroteros" και της δίνουμε την τιμή του 137 | πρώτου στοιχείου στη λίστα (slice) των αριθμών που θα δοθούν ως είσοδο. 138 | */ 139 | mikroteros := kapoioiArithmoi[0] // θέση πρώτη (ήτοι θέση 0) απο την 140 | // λίστα (slice) που θα δοθεί 141 | for _, i := range kapoioiArithmoi { 142 | // Στη συνέχεια, τραβάμε κάθε τιμή "i" από τη λίστα, μία 143 | // απο κάθε θεση "_" ώστε να αναζητήσουμε και να βρούμε 144 | // ποιο είναι το μικρότερο 145 | if i < mikroteros { 146 | // Εάν η τιμή που πήραμε είναι η μικρότερη 147 | // από αυτήν που είχαμε δώσει στο "mikroteros" τότε έχουμε 148 | // αυτό που θέλουμε και το αναθέτουμε στο "mikroteros". 149 | // Εάν είναι υψηλότερος δεν το κάνουμε. 150 | mikroteros = i 151 | } 152 | } 153 | 154 | return mikroteros 155 | } 156 | 157 | // Παράδειγμα αναδρομής (recursion): Όταν η function καλεί τον εαυτό της 158 | // Εδώ βλέπουμε υπολογισμό παραγοντικού 159 | // Παραγοντικό του 4: factorial(4) 160 | // 4 * factorial(3) == 4 * 3 * 2 * 1 161 | // 3 * factorial(2) == 3 * 2 * 1 162 | // 2 * factorial(1) == 2 * 1 163 | // factorial(0) == 1 164 | 165 | func factorial(num int) int { 166 | if num == 0 { 167 | return 1 168 | } 169 | return num * factorial(num-1) 170 | } 171 | 172 | /* 173 | Μια defer αναβάλλει την εκτέλεση μιας λειτουργίας 174 | μέχρι να γίνει η επιστροφή της περιβάλλουσας function. 175 | 176 | Οι παράμετροι της αναβαλλόμενης κλήσης αξιολογούνται αμέσως, 177 | αλλά η κλήση της δεν εκτελείται μέχρι να γίνει η επιστροφή 178 | της περιβάλλουσας function. 179 | 180 | Παράδειγμα : 181 | 182 | func main() { 183 | defer fmt.Println("γεια σου") 184 | fmt.Println("κόσμε") 185 | } 186 | 187 | θα επιστρέψει "κόσμε γεια " αντί "γεια σου κόσμε" 188 | Τα παρακάτω printOne και printTwo θα χρησιμοποιηθούν στην main() ως defer 189 | */ 190 | 191 | func printOne() { 192 | fmt.Println(1) 193 | } 194 | 195 | func printTwo() { 196 | fmt.Println(2) 197 | } 198 | 199 | // Εάν εμφανιστεί ένα σφάλμα, μπορούμε να πιάσουμε το σφάλμα 200 | // με την recover ώστε να επιτρέψουμε 201 | // στον κώδικα μας να συνεχίσει να εκτελείται 202 | 203 | func safeDiv(num1, num2 int) int { 204 | defer func() { 205 | fmt.Println(recover()) 206 | }() 207 | solution := num1 / num2 208 | return solution 209 | } 210 | 211 | // Εδώ δείχνουμε μια function που θα καλέσει την "panic" και 212 | // θα τη διαχειριστεί με τη "recover" 213 | 214 | func demPanic() { 215 | 216 | defer func() { 217 | 218 | // Εάν δεν κάναμε εκτύπωση του μηνύματος, τίποτα δε θα έδειχνε 219 | 220 | fmt.Println(recover()) 221 | 222 | }() 223 | panic("PANIC") 224 | 225 | } 226 | 227 | /* 228 | Οι αναβαλλόμενες κλήσεις εντός της συνάρτησης μας 229 | στοιχίζονται σε μια στοίβα. 230 | Όταν η συνάρτηση επιστρέψει προκειμένου να τις εκτελέσει, 231 | οι αναβαλλόμενες κλήσεις της εκτελούνται με διάταξη 232 | last-in-first-out (η τελευταία αναβληθείσα κλήση εκτελείται πρώτη). 233 | 234 | Για να μάθετε περισσότερα σχετικά με τις αναβλητικές δηλώσεις, 235 | διαβάστε αυτήν την ανάρτηση : 236 | https://blog.golang.org/defer-panic-and-recover 237 | */ 238 | func countDefer() { 239 | // πρώτη προβολή 240 | fmt.Println("Θα εμφανιστώ πρώτα εγώ") 241 | 242 | for i := 0; i < 10; i++ { 243 | // /τέταρτη προβολή 244 | defer fmt.Println("Τέταρτο μήνυμα εγώ", i) 245 | } 246 | // τρίτη προβολή 247 | defer fmt.Println("Τρίτο μήνυμα εγώ:") 248 | // δεύτερη προβολή 249 | fmt.Println("Δεύτερο μήνυμα εγώ") 250 | } 251 | 252 | func main() { /* 253 | Ξεκινάμε το πρόγραμμά μας χρησιμοποιώντας 254 | εσωτερικά της main, όλες τις function που φτιάξαμε. 255 | 256 | Η main επίσης δεν παίρνει ορίσματα - παραμέτρους, 257 | δεν μπορεί και δεν επιστρέφει καμία τιμή. 258 | στην πραγματικότητα όταν η main τερματίσει, ολόκληρο 259 | το πρόγραμμα τερματίζεται και αν υποθέσουμε τερματίσει 260 | χωρίς σφάλματα, τότε θα επιστρέψει τον κωδικό εξόδου 0 261 | στο λειτουργικό σύστημα. Για παράδειγμα στο VSCode 262 | όταν το τρέξετε με Ctrl+F5 θα δείτε στο output : 263 | 264 | Process 149355 has exited with status 0 265 | dlv dap (149278) exited with code: 0 266 | */ 267 | 268 | listOfNums := []float64{1, 2, 3, 4, 5} 269 | 270 | fmt.Println("Άθροισμα των τιμών :", addThemUp(listOfNums)) 271 | fmt.Println("Αφαίρεση τιμών των τιμών :", subtractThem(1, 2, 3, 4, 5)) 272 | num1, num2 := next2Values(5) // Δίνουμε σε 2 variables, τιμές από μια function 273 | fmt.Println("Οι επόμενοι δύο αριθμοί μετά το 5 : ", num1, num2) 274 | 275 | epaggelma := "δάσκαλος" 276 | onomatEponimo := "αγνωστος αγνώστου" 277 | fmt.Println(converter(epaggelma, onomatEponimo)) 278 | // Στείλτε έναν αόριστο αριθμό τιμών σε μια function 279 | // https://en.wikipedia.org/wiki/Variadic_function (Variadic Function) 280 | 281 | // Μπορείτε να δημιουργήσετε μια func μέσα σε μια func. Έχει πρόσβαση στις 282 | // τοπικές variables της func στην οποία περιλαμβάνεται 283 | 284 | num3 := 3 285 | doubleNum := func() int { // Μια func όπως αυτή, χωρίς 286 | // τοπικές variables είναι ένα "closure" 287 | num3 *= 2 288 | return num3 289 | } 290 | fmt.Println("Πρώτο doubleNum", doubleNum()) 291 | fmt.Println("Δευτερο doubleNum", doubleNum()) 292 | 293 | deuteroClosure := func(h, m int) int { 294 | return h + m 295 | } 296 | fmt.Println("To deuteroClosure 10 + 10: ", deuteroClosure(10, 10)) 297 | // Ψάχνουμε με το variadic function μας τον μικρότερο αριθμό 298 | kapoioiArithmoi := mikroterosArithmos(13, 5, 10, 13, 17, 14, 16) 299 | fmt.Println("Ο μικρότερος απο 13, 5, 10, 13, 17, 14, 16 είναι το", kapoioiArithmoi) 300 | 301 | // Εδώ έχουμε μια αναδρομική συνάρτηση (recursive function) 302 | 303 | fmt.Println(factorial(4)) 304 | 305 | // Η Defer όπως είπαμε εκτελεί μια λειτουργία μετά την 306 | // ολοκλήρωση της func στην οποία καλείται 307 | // Η Defer μπορεί να χρησιμοποιηθεί για να 308 | // δημιουργήσουμε μια func με ένα λογικό τρόπο 309 | // αλλά ταυτόχρονα για να εκτελέσουμε μια τελευταία 310 | // λειτουργία ως λειτουργία καθαρισμού 311 | // π.χ. Θα κάνουμε defer το κλείσιμο ενός αρχείου αφού 312 | // πρώτα το ανοίξουμε και εκτελέσουμε εργασίες 313 | 314 | defer printTwo() 315 | printOne() 316 | 317 | // Καλούμε μια δικιά μας defer 318 | countDefer() 319 | 320 | // Εδω χρησιμοποιούμε τη recover() για να πιάσουμε 321 | // το error που θα προκαλούσε η διαίρεση με 0 322 | // και να αποτρέψουμε το "κρασάριμα/σταμάτημα" της εφαρμογής μας 323 | 324 | fmt.Println(safeDiv(3, 0)) 325 | fmt.Println(safeDiv(3, 2)) 326 | 327 | // Μπορούμε να αποτρέψουμε τα δικά μας error και 328 | // να επανέλθουμε με panic & recover 329 | 330 | demPanic() 331 | 332 | } 333 | -------------------------------------------------------------------------------- /08_go_pointers/go_pointers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Δείκτες 6 | // "Go passes arguments by value, and not by reference" 7 | /* 8 | Όταν θέτουμε ένα variable ως όρισμα σε μια function, 9 | στην πραγματικότητα η Go κάνει ένα αντίγραφο της τιμής 10 | που μεταβιβάζεται απο το όρισμα και τοποθετεί αυτήν 11 | την τιμή στη στοίβα για χρήση από τη function που καλείται. 12 | Δεν βάζει την ίδια τη variable στη στοίβα, μόνο ένα αντίγραφο 13 | της τιμής του. 14 | 15 | Όταν δημιουργούμε τη variable η Go ανοίγει μια περιοχή στη μνήμη για αυτήν την variable. Ας υποθέσουμε 16 | ότι η διεύθυνση για αυτήν τη περιοχή μνήμης είναι η 0xAA και η τιμή που τοποθετούμε σε αυτήν είναι μια string type, 17 | Αν τώρα δώσουμε αυτή την variable ως όρισμα/παράμετρο σε μια function, η Go όπως είπαμε δημιουργεί στην πραγματικότητα ένα 18 | νέο αντίγραφο αυτής της variable σε μια διαφορετική διεύθυνση π.χ. 0xBB. Τυχόν αλλαγές που πραγματοποιούνται 19 | από τη function που καλούμε γίνονται μόνο στο αντίγραφο της variable, αυτή δηλαδή που βρίσκεται στη διεύθυνση 0xBB, 20 | οπότε η αρχική τιμή στο 0xAA είναι αμετάβλητη. 21 | 22 | "Pointers must be used to pass arguments by reference" 23 | Για να μπορούμε να διαχειριστούμε την τιμή στην αρχική variable θα χρησιμοποιήσουμε τους δείκτες 24 | 25 | Ένας δείκτης διατηρεί τη διεύθυνση μνήμης μιας τιμής. Οι δείκτες, 26 | αντί να αναφέρονται στην ίδια την τιμή, αναφέρονται σε μια τοποθεσία 27 | στη μνήμη όπου είναι αποθηκευμένη μια τιμή. 28 | 29 | Στη Go ένας δείκτης αναπαρίσταται χρησιμοποιώντας το χαρακτήρα * 30 | ακολουθούμενος από το τύπο της αποθηκευμένης τιμής. Ο * χρησιμοποιείται 31 | επίσης για να αναφερθούμε στις variables των δεικτών. Όταν 32 | αναφερόμαστε σε ένα δείκτη έχουμε πρόσβαση στην τιμή που αυτός δείχνει 33 | 34 | var p *int 35 | Ο τύπος *T (αστερίσκος Τ) είναι δείκτης σε τιμή της variable Τ. Η μηδενική τιμή του είναι η nil. 36 | 37 | Όταν π.χ. γράφουμε *xPtr = 0 εννοούμε “βάλε τον int 0 στη θέση μνήμης που δείχνει ο xPtr”. 38 | Αν αντίθετα γράψουμε xPtr = 0 θα πάρουμε ένα λάθος απ το μεταγλωττιστή επειδή 39 | xPtr δεν είναι int, είναι *int, που μπορεί να μας δώσει μόνο ένα άλλο *int. 40 | 41 | Επίσης χρησιμοποιούμε τον τελεστή & για να βρούμε τη διεύθυνση μιας variable. 42 | Π.χ η &x επιστρέφει *int (pointer to an int) επειδή x είναι int. 43 | Αυτό είναι που μας επιτρέπει να μετατρέψουμε την αρχική variable. 44 | 45 | Συνοψίζοντας, τα δύο σύμβολα * και & χρησιμοποιούνται: 46 | 47 | & <-- Δείξε προς την διεύθυνση μνήμης μιας variable π.χ. dieuthinsi = &dedomena 48 | * <-- Διάβασε Από / Διαμέσου της διεύθυνσης μνήμης μιας variable *dieuthinsi 49 | 50 | Έστω: 51 | 52 | i, j := 42, 2701 53 | p = &i // Το & εδώ δημιουργεί έναν δείκτη στον τελεστή του. 54 | 55 | fmt.Println(*p) // διαβάζω την i μέσω της διεύθυνσης μνήμης του δείκτη p 56 | *p = 21 // θέτω την i μέσω του δείκτη p 57 | Ο τελεστής * υποδηλώνει την υποκείμενη τιμή του δείκτη. Αυτό είναι γνωστό 58 | ως "dereferencing" ή "indirecting". 59 | 60 | Σε αντίθεση με τη C, η Go δεν έχει αριθμητικό pointer. 61 | 62 | p = &j // δείκτης στο j 63 | *p = *p / 37 // διαίρεσε το j μέσω του δείκτη 64 | fmt.Println(j) // δες την νέα τιμή του j 65 | 66 | */ 67 | /* 68 | 69 | */ 70 | func dontChangeXVal(x int) { 71 | // Δεν έχει επίδραση στην τιμή του x στην main() 72 | x = 2 73 | } 74 | 75 | // * δηλώνει ότι στέλνουμε μια αναφορά στην τιμή 76 | func nowChangeXVal(x *int) { 77 | // Αλλάξτε την τιμή στη διεύθυνση μνήμης που αναφέρεται από το δείκτη 78 | // * μας δίνει πρόσβαση στην τιμή που αναφέρεται ο δείκτης 79 | *x = 2 // Αποθηκεύστε 2 στη διεύθυνση μνήμης που αναφέρεται το x 80 | } 81 | 82 | func nowChangeYVal(yPtr *int) { 83 | *yPtr = 100 84 | } 85 | 86 | func changeCerebrux(site *string) string { 87 | /* Στην Go, οι τιμές επιστροφής μπορούν να ονοματίζονται ή όχι 88 | Με άλλα λόγια θα μπορουσε να γραφτεί : 89 | func changeCerebrux(site *string) epistrofi string { 90 | 91 | } 92 | */ 93 | 94 | // Αυτός ο * αστερίσκος στο *site λέει στην Go ότι το site εδώ είναι 95 | // ένας δείκτης σε μια string που θα δοθεί όταν κληθεί η func δηλαδή 96 | // στο (site *string) 97 | *site = "https://cerebrux.net" 98 | /* 99 | Θα παρατηρήσετε εδώ ότι κατά την εκχώρηση της νέας τιμής 100 | στο function μας εδώ, απλά χρησιμοποιούμε τον τελεστή "=" 101 | και όχι το ":=" Αυτό συμβαίνει επειδή δεν δηλώνουμε 102 | μια νέα μεταβλητή εδώ, απλώς εκχωρούμε μια νέα τιμή σε μια 103 | υπάρχουσα μεταβλητή που θα μας δοθεί όταν θα κληθεί η function 104 | πάνω σε αυτή την υπάρχουσα μεταβλητή. 105 | */ 106 | fmt.Println("Αλλάζω το site σε", *site) 107 | 108 | return *site 109 | } 110 | 111 | func main() { 112 | // Περνάμε την τιμή μιας variable στη function 113 | x := 0 114 | dontChangeXVal(x) // Δεν θα αλλάξει τίποτα 115 | fmt.Println("Το dontChangeXVal δεν θα αλλάξει τιμή στο x σε 2 αφού είναι", x) 116 | 117 | // Αν περάσουμε μια reference στη variable μπορούμε 118 | // να αλλάξουμε την τιμή σε μια function 119 | 120 | nowChangeXVal(&x) 121 | // Θυμηθείτε, πρόκειται να φτιαχτεί ένα αντίγραφο της μεταβλητής 122 | // μας το οποίο αντίγραφο θα μεταβιβάσετε στη συνάρτηση, 123 | // οπότε δεν πρόκειται να περάσει η ίδια η μεταβλητή. 124 | 125 | fmt.Println("Το nowChangeXVal θα αλλάξει τιμή στο x σε", x) 126 | 127 | // Πάρτε τη διεύθυνση του x στην οποία δείχνει, με το & 128 | fmt.Println("Διεύθυνση μνήμης του x είναι", &x) // pointer στην διεύθυνση του x 129 | 130 | // Μπορούμε επίσης να δημιουργήσουμε ένα δείκτη με την new 131 | yPtr := new(int) 132 | nowChangeYVal(yPtr) 133 | fmt.Println("Το nowChangeΥVal θα αλλάξει τιμή στο y σε", *yPtr) 134 | 135 | site := "www.cerebrux.net" 136 | fmt.Println("Το site είναι", site) 137 | 138 | changeCerebrux(&site) // pointer στο site 139 | fmt.Println("Το site τώρα είναι", site) 140 | } 141 | -------------------------------------------------------------------------------- /09_struct/struct.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // STRUCTS 6 | 7 | /* 8 | Πέρα απο τους προκαθορισμένους, εσωτερικούς τύπους δεδομένων που διαθέτει η Go, 9 | μπορούμε να φτιάξουμε και δικούς μας τύπους με τις δομές. 10 | 11 | Μια δομή "struct" είναι μια συλλογή πεδίων. ε την λέξη-κλειδί "type" ξεκινάμε ένα νέο τύπο. 12 | Αυτό ακολουθείται από το όνομα του τύπου (π.χ. Circle), τη λέξη-κλειδί struct για να δείξει 13 | ότι έχουμε ορίσει ένα τύπο struct και τέλος μια λίστα με τα πεδία στο εσωτερικό των αγκύλων 14 | που περιγράφει τις ιδιότητες της struct μας. 15 | Κάθε πεδίο έχει ένα όνομα και έναν τύπο. Όπως και με τις functions έτσι και εδώ 16 | μπορούμε να συμπτύξουμε πεδία που έχουν τον ίδιο τύπο 17 | 18 | */ 19 | 20 | /* 21 | ΣΗΜΕΊΩΣΗ: Όταν φτιάχνουμε μια struct, ο έλεγχος (go-lint) του κώδικα που κάνει ο GO compiler, 22 | πιθανόν να μας παραπονεθεί με το παρακάτω μήνυμα: 23 | 24 | comment on exported type Rectangle should be of the form \"Rectangle ...\" (with optional leading article) 25 | 26 | Επειδή ο τύπος που φτιάχνουμε ξεκινάει με κεφαλαία (exported), Το μόνο που χρειάζεται 27 | είναι να αφήσετε ένα σχόλιο πάνω απο την struct σας το οποίο να ξεκινάει 28 | με το όνομα της Struct, ένα κενό, στην συνέχεια μια ":", ένα κενό και 29 | τέλος το σχόλιο που περιγράφει τι κάνει η struct σας. 30 | Π.χ. Rectangle : Περιγράφω ένα ορθογώνιο 31 | Αυτά τα σχόλια μπορούν να χρησιμοποιηθούν απο την εντολή "go doc" για να δημιουργήσετε μια τεκμηρίωση 32 | */ 33 | 34 | // Rectangle : μπορούμε να ορίσουμε τους δικούς μας τύπους χρησιμοποιώντας 35 | // μια struct π.χ. εδώ περιγράφουμε ένα ορθογώνιο 36 | type Rectangle struct { 37 | leftX float64 38 | TopY float64 39 | height float64 40 | width float64 41 | // εναλλακτικά μπορούμε να τα γράψουμε σε μια γραμμή "leftX, TopY, height, width float64" 42 | } 43 | 44 | // VertexΒ : αποτελείται από δύο τύπους int Χ,Υ 45 | type VertexΒ struct { 46 | X, Y int 47 | } 48 | 49 | // Vertex : αποτελείται από δύο τύπους int Χ,Υ 50 | type Vertex struct { 51 | X int 52 | Y int 53 | } 54 | 55 | // Μπορούμε να καθορίσουμε μεθόδους για το ορθογώνιο μας προσθέτοντας το δέκτη (receiver) 56 | // rect *Rectangle μεταξύ της func και του ονόματος της function ώστε να μπορούμε να τον καλέσουμε 57 | // με τον τελεστή "." Γενικά τα πεδία της Struct είναι προσπελάσιμα χρησιμοποιώντας μια τελεία. 58 | 59 | func (rect *Rectangle) area() float64 { 60 | 61 | return rect.width * rect.height 62 | 63 | } 64 | 65 | func main() { 66 | 67 | // Ορίζουμε ένα ορθογώνιο 68 | rect1 := Rectangle{leftX: 0, TopY: 50, height: 10, width: 10} 69 | 70 | // αν γνωρίζουμε τη σειρά μπορούμε να παραλείψουμε τα ονόματα των χαρακτηριστικών 71 | // π.χ. 72 | // rect1 := Rectangle{0, 50, 10, 10} 73 | 74 | // Έχουμε πρόσβαση σε τιμές των πεδίων με την . (τελεία) 75 | /* 76 | Για να αποκτήσουμε πρόσβαση στο πεδίο Χ ενός struct όταν έχουμε τον δείκτη struct p 77 | μπορούμε να γράψουμε (*p).X 78 | Ωστόσο, ο τρόπος αυτός είναι δύσχρηστος, οπότε η γλώσσα μας επιτρέπει αντ 'αυτού 79 | να γράψουμε μόνο p.X, χωρίς τη ρητή δήλωση. 80 | 81 | */ 82 | fmt.Println("Το Ορθογώνιο έχει", rect1.width, "πλάτος") 83 | 84 | // Καλούμε την μέθοδο "area" για το ορθογώνιο που φτιάξαμε 85 | fmt.Println("Το εμβαδόν του ορθογωνίου είναι =", rect1.area()) 86 | 87 | accessVertex() 88 | /* 89 | Παρακάτω βλέπουμε την δημιουργία variable με Struct Literal. 90 | Οι γλώσσες προγραμματισμού χρησιμοποιούν τη λέξη "Literal" 91 | όταν γίνεται αναφορά σε συντακτικούς τρόπους για την κατασκευή 92 | κάποιας struct δεδομένων. Αυτό σημαίνει ότι δεν έχει κατασκευαστεί 93 | ένα κενό struct στο οποίο αργότερα προσθέτουμε ή αφαιρούμε πεδία. 94 | 95 | Μια struct literal υποδηλώνει μια νέα εκχώρηση τιμής σε struct, 96 | καταγράφοντας τις τιμές των πεδίων της. 97 | 98 | 99 | */ 100 | 101 | var ( 102 | v1 = Vertex{1, 2} // είναι type Vertex 103 | // Μπορείτε να καταχωρίσετε ένα υποσύνολο πεδίων χρησιμοποιώντας τη σύνταξη "Name:" 104 | // (Η σειρά των ονομάτων είναι άσχετη.) 105 | v2 = Vertex{X: 1} // Το Y:0 υπονοείται 106 | v3 = Vertex{} // X:0 και Y:0 107 | v4 = Vertex{Y: 10} // X:0 και Y:10 108 | // Το πρόθεμα & επιστρέφει ένα δείκτη στην τιμή struct. 109 | p = &Vertex{1, 2} //είναι type *Vertex 110 | 111 | ) 112 | fmt.Println("v1=", v1, "\nv2=", v2, "\nv3=", v3, "\nv4=", v4, "\np=", p) 113 | 114 | } 115 | 116 | /* 117 | Τα πεδία Struct μπορούν να προσπελαστούν μέσω ενός struct pointer. 118 | 119 | Για να αποκτήσουμε πρόσβαση στο πεδίο Χ ενός struct όταν έχουμε τον δείκτη struct p 120 | μπορούμε να γράψουμε (*p).X 121 | Ωστόσο, ο τρόπος αυτός είναι δύσχρηστος, οπότε η γλώσσα μας επιτρέπει αντ 'αυτού 122 | να γράψουμε μόνο p.X, χωρίς τη ρητή δήλωση. 123 | */ 124 | func accessVertex() { 125 | v := Vertex{1, 2} 126 | p := &v 127 | p.X = 1e9 // αντί (*p).X το γράφουμε p.X 128 | fmt.Println(v) 129 | } 130 | -------------------------------------------------------------------------------- /10_structs_interfaces/structs_interfaces.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | // STRUCTS AND INTERFACES 9 | 10 | /* 11 | Η Go δεν έχει κλάσεις (classes). Ωστόσο, μπορείτε να ορίσετε μεθόδους σε τύπους. 12 | Μια μέθοδος είναι μια συνάρτηση με μία ειδική παράμετρο που είναι παραλήπτης. 13 | Ο παραλήπτης εμφανίζεται στη δική του λίστα παραμέτρων μεταξύ της λέξης "func" 14 | και του ονόματος της μεθόδου. 15 | */ 16 | 17 | // Vertex : κορυφή τρίγωνου 18 | type Vertex struct { 19 | X, Y float64 20 | } 21 | 22 | // Shape : Σχήμα 23 | type Shape interface { 24 | area() float64 25 | } 26 | 27 | // Rectangle : Ορθογώνιο 28 | type Rectangle struct { 29 | height float64 30 | width float64 31 | } 32 | 33 | // Circle : Κύκλος 34 | type Circle struct { 35 | radius float64 36 | } 37 | 38 | // INTERFACES 39 | 40 | // Μια διεπαφή (interface) ορίζει μια λίστα με τις μεθόδους που πρέπει να εφαρμόσει ένας τύπος (type) 41 | // Εάν αυτός ο τύπος εφαρμόζει αυτές τις μεθόδους, η κατάλληλη μέθοδος εκτελείται 42 | // ακόμα και το πρωτότυπο στο οποίο αναφέρεται είναι με το όνομα διεπαφής 43 | 44 | // Abs : με την μέθοδο αυτή, ορίζουμε τι θα κάνουμε τα Χ, Υ που έχει ο τύπος Vertex που φτιάξαμε 45 | // Abs : (Vertex.Abs) η μέθοδος Abs έχει έναν δέκτη τύπου Vertex που ονομάζεται v, άρα δέχεται 46 | // την func Vertex με τις 2 τιμές που λαμβάνει 47 | func (v Vertex) Abs() float64 { 48 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 49 | } 50 | 51 | func (r Rectangle) area() float64 { 52 | return r.height * r.width 53 | } 54 | 55 | func (c Circle) area() float64 { 56 | 57 | return math.Pi * math.Pow(c.radius, 2) 58 | } 59 | 60 | func getArea(shape Shape) float64 { 61 | 62 | return shape.area() 63 | 64 | } 65 | 66 | func main() { 67 | 68 | v := Vertex{3, 4} // εδώ αρχικοποιούμε τη v που είχαμε δημιουργήσει επάνω 69 | fmt.Println("v.Abs()=", v.Abs()) // εδώ εφαρμόζουμε την Abs στις τιμές που έλαβε το v 70 | 71 | rect := Rectangle{20, 50} 72 | circ := Circle{4} 73 | 74 | fmt.Println("Rectangle Area =", getArea(rect)) 75 | fmt.Println("Circle Area =", getArea(circ)) 76 | 77 | } 78 | -------------------------------------------------------------------------------- /11_strings_excepting_input_casting/strings_excepting_input_casting.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | 12 | // Συναρτήσεις με STRING 13 | 14 | // Ας δούμε μερικές μεθόδους με τις οποίες μπορούμε διαχειριστούμε 15 | // strings 16 | 17 | sampString := "Hello World" 18 | 19 | // Επιστρέφει αληθής εάν υπάρχει η φράση "lo" στην variable sampString 20 | fmt.Println(strings.Contains(sampString, "lo")) 21 | 22 | // Επιστρέφει το index (θέση) της φράσης 23 | fmt.Println(strings.Index(sampString, "lo")) 24 | 25 | // Επιστρέφει αριθμό που μας λέει το πόσες φορές εμφανίζεται το "l" στην variable sampString 26 | fmt.Println(strings.Count(sampString, "l")) 27 | 28 | // Αντικαθιστά το πρώτο γράμμα με το δεύτερο όσες φορές καθορίζετε (εδώ 3 φορές) 29 | fmt.Println(strings.Replace(sampString, "l", "x", 3)) 30 | 31 | // Επιστρέψτε μια λίστα που χωρίζει με τον καθορισμένο διαχωριστή 32 | csvString := "1,2,3,4,5,6" 33 | fmt.Println(strings.Split(csvString, ",")) 34 | 35 | listOfLetters := []string{"c", "a", "b"} 36 | sort.Strings(listOfLetters) 37 | fmt.Println("Γράμματα:", listOfLetters) 38 | 39 | // Επιστρέφει μια συμβολοσειρά χρησιμοποιώντας τις τιμές που πέρασαν χωρισμένες με διαχωριστικό 40 | listOfNums := strings.Join([]string{"3", "2", "1"}, ", ") 41 | 42 | fmt.Println(listOfNums) 43 | 44 | // Αναμονή για είσοδο 45 | 46 | /* 47 | Παρακάτω, χρησιμοποιούμε την scan μέθοδο η οποία περιμένει απο τον χρήστη να εισάγει κάτι 48 | */ 49 | 50 | fmt.Println("Πως σε λένε; ") 51 | 52 | var name string 53 | 54 | fmt.Scan(&name) 55 | 56 | fmt.Println("Γεια σου", name, "!!") 57 | 58 | // CASTING 59 | /* 60 | Το type casting είναι ένας τρόπος για τη μετατροπή μιας variable από 61 | έναν τύπο δεδομένων σε έναν άλλο τύπο δεδομένων. 62 | */ 63 | 64 | randInt := 5 65 | randFloat := 10.5 66 | randString := "100" 67 | randString2 := "250.5" 68 | 69 | // Μετατροπή των τύπων των αριθμών 70 | fmt.Println(float64(randInt)) 71 | fmt.Println(int(randFloat)) 72 | 73 | // Μετατρέψτε μια συμβολοσειρά σε ένα int 74 | newInt, _ := strconv.ParseInt(randString, 0, 64) 75 | fmt.Println(newInt) 76 | 77 | // Μετατρέψτε μια συμβολοσειρά σε ένα float 78 | newFloat, _ := strconv.ParseFloat(randString2, 64) 79 | fmt.Println(newFloat) 80 | 81 | } 82 | -------------------------------------------------------------------------------- /12_create_http_server/create_http_server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | // Δημιουργία Web Server 9 | 10 | /* 11 | Στην Go, η δημιουργία ενός web server (εξυπηρετητής ιστοσελίδων) χρησιμοποιώντας το πακέτο net/http 12 | είναι αρκετά εύκολη 13 | Φυσικά το Web Development με την Go είναι ένας κλάδος απο μόνος του, οπότε εδώ θα αρκεστούμε 14 | απλά στην δημιουργία μιας στατικής σελίδας. 15 | Θα επικεντρωθούμε στην κατασκευή ενός απλού διακομιστή ο οποίος μπορεί να εξυπηρετήσει 16 | ένα πολύ απλό περιεχόμενο σε έναν πελάτη που κάνει αιτήσεις σε αυτόν τον εξυπηρετητή μας. 17 | */ 18 | 19 | // Ας φτιάξουμε δυο func που θα προβάλουν το καθένα κάτι διαφορετικό ανάλογα με την 20 | // διεύθυνση που θα πληκτρολογεί ο χρήστης. Στο παρόν παράδειγμα έστω ότι έχουμε 21 | // μια κεντρική σελίδα και μια υποσελίδα με όνομα "earth". Αυτές οι σελίδες φυσικά 22 | // δεν υπάρχουν στο σύστημα μας και τις φανταζόμαστε ως φακέλους τον έναν μέσα στον άλλον. 23 | // Άρα όταν ο χρήστης θα πάει στην κεντρική σελίδα "localhost/" ("/") θα δει "Γεια σου Κόσμε" 24 | // Όταν θα πάει στην "localhost/earth" ("/earth") θα δει "Γεια σου ΓΗ" 25 | 26 | // Aπο το πακέτο http χρησιμοποιούμε τις: 27 | 28 | // Η http.ResponseWriter συγκεντρώνει στην "w" την απάντηση που θα δώσει ο server μας και τι θα 29 | // γράφει στην οθόνη του επισκέπτη (client) 30 | // Η http.Request διαχειρίζεται το αίτημα του επισκέπτη (client) και την αποθηκεύει στην "r" 31 | // Παραδοσιακά δίνονται τα ονόματα w, r, και υπονοούν variable write και read 32 | func handler(w http.ResponseWriter, r *http.Request) { 33 | 34 | fmt.Fprintf(w, "Γειά σου Κόσμε\n") 35 | } 36 | 37 | func handler2(w http.ResponseWriter, r *http.Request) { 38 | fmt.Fprintf(w, "Γεια σου ΓΗ\n") 39 | } 40 | 41 | func main() { 42 | 43 | // Εδω χρησιμοποιούμε την http.HandleFunc και του λέμε τι να κάνει αν ο επισκέπτης 44 | // θέλει κάτι απο τον κατάλογο / (κεντρική σελίδα). ήτοι να τρέξει την handler 45 | http.HandleFunc("/", handler) 46 | 47 | // Εδω χρησιμοποιούμε την http.HandleFunc και του λέμε τι να κάνει αν ο επισκέπτης 48 | // θέλει κάτι απο τον κατάλογο /earth ήτοι να τρέξει την handler 49 | http.HandleFunc("/earth", handler2) 50 | 51 | // Με την http.ListenAndServe, όπως δηλώνει και το όνομά του, ξεκινάει ο server 52 | // να "ακούει" και να "εξυπηρετεί" τα αιτήματα στην port 8080 ήτοι localhost:8080/ 53 | http.ListenAndServe(":8080", nil) 54 | } 55 | 56 | /* 57 | Μόλις τρέξετε τον κώδικα π.χ. με go run create_http_server.go, θα δείτε οτι δεν εμφανίζεται κάτι στο τερματικό. 58 | Ανοίξτε τον browser σας και επισκεφτείτε την σελίδα localhost:8080/ έπειτα και την σελίδα localhost:8080/earth 59 | Για να σταματήσετε την εφαρμογή (τον διακομιστή) πατήστε τον συνδυασμό πλήκτρων CTRL+C 60 | */ 61 | -------------------------------------------------------------------------------- /13_http_serve_static_html/http_serve_static_html.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | ) 7 | 8 | // Δημιουργία HTTP Server 9 | /* 10 | Στο παρόν πρόγραμμά μας φτιάχνουμε έναν εξυπηρετητή ο οποίος θα "σερβίρει" στους επισκέπτες μας, 11 | μια έτοιμη στατική ιστοσελίδα που βρίσκεται στον φάκελο ./static (η τελεία ./ είναι για να πούμε οτι 12 | ο φάκελος βρίσκεται εδώ που τρέχει και ο κώδικάς μας.) 13 | 14 | */ 15 | 16 | func main() { 17 | // Εδώ χρησιμοποιούμε ένα handle στο οποίο λέμε κάλεσε την http.FileServer για να 18 | // προβάλει ότι βρίσκεται στον φάκελο ./static 19 | // Σημείωση: Η ιστοσελίδα που παρέχουμε διαθέτει και βίντεο που εκτελείται αυτόματα. Θα χρειαστεί 20 | // να το επιτρέψετε στον browser σας για να το δείτε. 21 | http.Handle("/", http.FileServer(http.Dir("./static"))) 22 | // Καλούμε την log.Fatal για να καταγράψει σφάλματα αφού ξεκινήσει ο server μας να περιμένει τους 23 | // επισκέπτες του 24 | log.Fatal(http.ListenAndServe(":8081", nil)) 25 | } 26 | 27 | /* Σχετικά με την log.Fatal και γιατί την χρησιμοποιούμε 28 | 29 | Σύμφωνα με τις UNIX συμβάσεις, μια διαδικασία που αντιμετωπίζει ένα σφάλμα θα πρέπει 30 | "να αποτύχει όσο το δυνατόν νωρίτερα, με μη μηδενικό κωδικό εξόδου". 31 | Αυτό μας οδηγεί στις ακόλουθες οδηγίες για να χρησιμοποιήσω το log.Fatal όταν: 32 | 33 | 1) ... ένα σφάλμα συμβαίνει σε οποιοδήποτε από τα func, καθώς αυτά συμβαίνουν 34 | όταν επεξεργάζονται οι import ή πριν την func main() αντίστοιχα. 35 | Για παράδειγμα, έχω ρυθμίσει την καταγραφή σφαλμάτων για να ελέγξω ότι έχουμε 36 | ένα φυσιολογικό περιβάλλον και παραμέτρους. Οπότε δεν έχουμε σωστές παραμέτρους 37 | τότε δεν χρειάζεται να τρέχουμε το func main() οπότε θα πρέπει να το πούμε νωρίς 38 | στο χρήστη οτι δεν έχει δώσει σωστές παραμέτρους. 39 | 40 | 2)... συμβαίνει ένα σφάλμα το οποίο γνωρίζω ότι δεν μπορεί λόγο εξωγενών παραγόντων 41 | να παραμερίσει. Ας υποθέσουμε ότι έχουμε ένα πρόγραμμα που δημιουργεί μια μικρογραφία 42 | ενός μεγάλου αρχείου εικόνας που δίνεται η διαδρομή του αρχείου αυτού στη γραμμή εντολών. 43 | Εάν αυτό το αρχείο δεν υπάρχει ή είναι ακατάλληλο για ανάγνωση λόγω π.χ. ανεπαρκών δικαιωμάτων, 44 | δεν υπάρχει λόγος να συνεχιστεί το πρόγραμμα. Συνεπώς, τηρούμε τις UNIX συμβάσεις 45 | και αποτυγχάνουμε. 46 | 47 | 3)... εμφανίζεται ένα σφάλμα κατά τη διάρκεια μιας διαδικασίας που μπορεί να 48 | μην είναι αναστρέψιμη. Ας υποθέσουμε ότι έχουμε μια "μη διαδραστική/αυτόματη" 49 | εφαρμογή αντιγραφής φακέλων σε κάποιον προορισμό. Τώρα, ας υποθέσουμε 50 | ότι το πρόγραμμά μας συναντάει ένα αρχείο στον φάκελο προορισμού που έχει το ίδιο όνομα 51 | (αλλά διαφορετικό περιεχόμενο) με το αρχείο που θα αντιγραφεί εκεί. 52 | Δεδομένου ότι δεν μπορούμε να ζητήσουμε από τον χρήστη να αποφασίσει τι 53 | να κάνει το πρόγραμμά μας με αυτό το αρχείο (μη διαδραστική/αυτόματη) και δεν μπορούμε 54 | να αντιγράψουμε αυτό το αρχείο, έχουμε ένα πρόβλημα. 55 | Επειδή όταν τελειώσει το πρόγραμμά μας θα γίνει μηδενικό κωδικό εξόδου (επιτυχώς), 56 | ο χρήστης θα υποθέσει ότι οι πηγές και οι φάκελοι προορισμού είναι ακριβή αντίγραφα 57 | μεταξύ τους, αφού δεν μπορούμε απλά να παραλείψουμε το εν λόγω αρχείο. 58 | Επίσης, δεν μπορούμε απλά να το αντικαταστήσουμε, δεδομένου ότι αυτό 59 | θα μπορούσε ενδεχομένως να καταστρέψει τις πληροφορίες. 60 | Αυτή είναι μια κατάσταση που είναι μη αναστρέψιμη από κάθε ρητό αίτημα του χρήστη 61 | και γι 'αυτό θα χρησιμοποιούσα το log.Fatal για να εξηγήσω την κατάσταση, 62 | υπακούοντας έτσι στην UNIX αρχή να αποτύχει όσο το δυνατόν νωρίτερα. 63 | πηγή: https://stackoverflow.com/questions/33885235/should-a-go-package-ever-use-log-fatal-and-when 64 | */ 65 | -------------------------------------------------------------------------------- /13_http_serve_static_html/static/LICENSE.txt: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | All templates are licensed under the Creative Commons Attribution 3.0 license. 4 | 5 | .. which means you can use them for both personal and commercial projects – for free! Just visibly credit us for the template somewhere on your site and you're good to go. Questions about how all this works? Feel free to get in touch. 6 | 7 | Note: If your use case makes it difficult to credit us or you'd rather just exclude it, contact us to work out a special licensing arrangement. 8 | 9 | Contact: hello @ templated.co 10 | 11 | # Image Credits 12 | 13 | All images courtesy of Unsplash (https://unsplash.com). 14 | 15 | - Martin Grincevschi (https://unsplash.com/photos/uCnOENPOBxM) 16 | - Pete Bellis (https://unsplash.com/photos/eDVQwVMLMgU) 17 | - Ciprian Lipenschi (https://unsplash.com/photos/OULAwYI3AGs) 18 | - Michael Dam (https://unsplash.com/photos/mEZ3PoFGs_k) 19 | - rawpixel.com (https://unsplash.com/photos/izTZ-TtdwCs) 20 | 21 | # Video Credits 22 | 23 | Video courtesy of Coverr (http://coverr.co). 24 | -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/js/breakpoints.min.js: -------------------------------------------------------------------------------- 1 | /* breakpoints.js v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | var breakpoints = (function() { "use strict"; var _ = { 4 | 5 | /** 6 | * List. 7 | * @var {array} 8 | */ 9 | list: null, 10 | 11 | /** 12 | * Media cache. 13 | * @var {object} 14 | */ 15 | media: {}, 16 | 17 | /** 18 | * Events. 19 | * @var {array} 20 | */ 21 | events: [], 22 | 23 | /** 24 | * Initialize. 25 | * @param {array} list List. 26 | */ 27 | init: function(list) { 28 | 29 | // Set list. 30 | _.list = list; 31 | 32 | // Add event listeners. 33 | window.addEventListener('resize', _.poll); 34 | window.addEventListener('orientationchange', _.poll); 35 | window.addEventListener('load', _.poll); 36 | window.addEventListener('fullscreenchange', _.poll); 37 | 38 | }, 39 | 40 | /** 41 | * Determines if a given query is active. 42 | * @param {string} query Query. 43 | * @return {bool} True if yes, false if no. 44 | */ 45 | active: function(query) { 46 | 47 | var breakpoint, op, media, 48 | a, x, y, units; 49 | 50 | // Media for this query doesn't exist? Generate it. 51 | if (!(query in _.media)) { 52 | 53 | // Determine operator, breakpoint. 54 | 55 | // Greater than or equal. 56 | if (query.substr(0, 2) == '>=') { 57 | 58 | op = 'gte'; 59 | breakpoint = query.substr(2); 60 | 61 | } 62 | 63 | // Less than or equal. 64 | else if (query.substr(0, 2) == '<=') { 65 | 66 | op = 'lte'; 67 | breakpoint = query.substr(2); 68 | 69 | } 70 | 71 | // Greater than. 72 | else if (query.substr(0, 1) == '>') { 73 | 74 | op = 'gt'; 75 | breakpoint = query.substr(1); 76 | 77 | } 78 | 79 | // Less than. 80 | else if (query.substr(0, 1) == '<') { 81 | 82 | op = 'lt'; 83 | breakpoint = query.substr(1); 84 | 85 | } 86 | 87 | // Not. 88 | else if (query.substr(0, 1) == '!') { 89 | 90 | op = 'not'; 91 | breakpoint = query.substr(1); 92 | 93 | } 94 | 95 | // Equal. 96 | else { 97 | 98 | op = 'eq'; 99 | breakpoint = query; 100 | 101 | } 102 | 103 | // Build media. 104 | if (breakpoint && breakpoint in _.list) { 105 | 106 | a = _.list[breakpoint]; 107 | 108 | // Range. 109 | if (Array.isArray(a)) { 110 | 111 | x = parseInt(a[0]); 112 | y = parseInt(a[1]); 113 | 114 | if (!isNaN(x)) 115 | units = a[0].substr(String(x).length); 116 | else if (!isNaN(y)) 117 | units = a[1].substr(String(y).length); 118 | else 119 | return; 120 | 121 | // Max only. 122 | if (isNaN(x)) { 123 | 124 | switch (op) { 125 | 126 | // Greater than or equal (>= 0 / anything) 127 | case 'gte': 128 | media = 'screen'; 129 | break; 130 | 131 | // Less than or equal (<= y) 132 | case 'lte': 133 | media = 'screen and (max-width: ' + y + units + ')'; 134 | break; 135 | 136 | // Greater than (> y) 137 | case 'gt': 138 | media = 'screen and (min-width: ' + (y + 1) + units + ')'; 139 | break; 140 | 141 | // Less than (< 0 / invalid) 142 | case 'lt': 143 | media = 'screen and (max-width: -1px)'; 144 | break; 145 | 146 | // Not (> y) 147 | case 'not': 148 | media = 'screen and (min-width: ' + (y + 1) + units + ')'; 149 | break; 150 | 151 | // Equal (<= y) 152 | default: 153 | media = 'screen and (max-width: ' + y + units + ')'; 154 | break; 155 | 156 | } 157 | 158 | } 159 | 160 | // Min only. 161 | else if (isNaN(y)) { 162 | 163 | switch (op) { 164 | 165 | // Greater than or equal (>= x) 166 | case 'gte': 167 | media = 'screen and (min-width: ' + x + units + ')'; 168 | break; 169 | 170 | // Less than or equal (<= inf / anything) 171 | case 'lte': 172 | media = 'screen'; 173 | break; 174 | 175 | // Greater than (> inf / invalid) 176 | case 'gt': 177 | media = 'screen and (max-width: -1px)'; 178 | break; 179 | 180 | // Less than (< x) 181 | case 'lt': 182 | media = 'screen and (max-width: ' + (x - 1) + units + ')'; 183 | break; 184 | 185 | // Not (< x) 186 | case 'not': 187 | media = 'screen and (max-width: ' + (x - 1) + units + ')'; 188 | break; 189 | 190 | // Equal (>= x) 191 | default: 192 | media = 'screen and (min-width: ' + x + units + ')'; 193 | break; 194 | 195 | } 196 | 197 | } 198 | 199 | // Min and max. 200 | else { 201 | 202 | switch (op) { 203 | 204 | // Greater than or equal. 205 | case 'gte': 206 | media = 'screen and (min-width: ' + x + units + ')'; 207 | break; 208 | 209 | // Less than or equal. 210 | case 'lte': 211 | media = 'screen and (max-width: ' + y + units + ')'; 212 | break; 213 | 214 | // Greater than. 215 | case 'gt': 216 | media = 'screen and (min-width: ' + (y + 1) + units + ')'; 217 | break; 218 | 219 | // Less than. 220 | case 'lt': 221 | media = 'screen and (max-width: ' + (x - 1) + units + ')'; 222 | break; 223 | 224 | // Not. 225 | case 'not': 226 | media = 'screen and (max-width: ' + (x - 1) + units + '), screen and (min-width: ' + (y + 1) + units + ')'; 227 | break; 228 | 229 | // Equal. 230 | default: 231 | media = 'screen and (min-width: ' + x + units + ') and (max-width: ' + y + units + ')'; 232 | break; 233 | 234 | } 235 | 236 | } 237 | 238 | } 239 | 240 | // String. 241 | else { 242 | 243 | // Missing a media type? Prefix with "screen". 244 | if (a.charAt(0) == '(') 245 | media = 'screen and ' + a; 246 | 247 | // Otherwise, use as-is. 248 | else 249 | media = a; 250 | 251 | } 252 | 253 | } 254 | 255 | // Cache. 256 | _.media[query] = (media ? media : false); 257 | 258 | } 259 | 260 | return ( 261 | _.media[query] === false 262 | ? false 263 | : window.matchMedia(_.media[query]).matches 264 | ); 265 | 266 | }, 267 | 268 | /** 269 | * Registers an event. 270 | * @param {string} query Query. 271 | * @param {function} handler Handler. 272 | */ 273 | on: function(query, handler) { 274 | 275 | // Register event. 276 | _.events.push({ 277 | query: query, 278 | handler: handler, 279 | state: false 280 | }); 281 | 282 | // Query active *right now*? Call handler. 283 | if (_.active(query)) 284 | (handler)(); 285 | 286 | }, 287 | 288 | /** 289 | * Polls for events. 290 | */ 291 | poll: function() { 292 | 293 | var i, e; 294 | 295 | // Step through events. 296 | for (i=0; i < _.events.length; i++) { 297 | 298 | // Get event. 299 | e = _.events[i]; 300 | 301 | // Active? 302 | if (_.active(e.query)) { 303 | 304 | // Hasn't been called yet? 305 | if (!e.state) { 306 | 307 | // Mark as called. 308 | e.state = true; 309 | 310 | // Call handler. 311 | (e.handler)(); 312 | 313 | } 314 | 315 | } 316 | 317 | // Otherwise ... 318 | else { 319 | 320 | // Previously called? 321 | if (e.state) { 322 | 323 | // Unmark as called. 324 | e.state = false; 325 | 326 | } 327 | 328 | } 329 | 330 | } 331 | 332 | }, 333 | 334 | }; function __(list) { _.init(list); }; __._ = _; __.on = function(query, handler) { _.on(query, handler); }; __.active = function(query) { return _.active(query); }; return __; })(); 335 | 336 | // UMD Wrapper (github.com/umdjs/umd/blob/master/returnExports.js | @umdjs + @nason) 337 | (function(root, factory) { 338 | 339 | // AMD. 340 | if (typeof define === 'function' && define.amd) 341 | define([], factory); 342 | 343 | // Node. 344 | else if (typeof exports === 'object') 345 | module.exports = factory(); 346 | 347 | // Breakpoints global. 348 | else 349 | root.breakpoints = factory(); 350 | 351 | }(this, function() { return breakpoints; })); -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/js/browser.min.js: -------------------------------------------------------------------------------- 1 | /* browser.js v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | var browser = (function() { "use strict"; var _ = { 4 | 5 | /** 6 | * Name. 7 | * @var {string} 8 | */ 9 | name: null, 10 | 11 | /** 12 | * Version. 13 | * @var {float} 14 | */ 15 | version: null, 16 | 17 | /** 18 | * OS. 19 | * @var {string} 20 | */ 21 | os: null, 22 | 23 | /** 24 | * OS version. 25 | * @var {float} 26 | */ 27 | osVersion: null, 28 | 29 | /** 30 | * Touch. 31 | * @var {bool} 32 | */ 33 | touch: null, 34 | 35 | /** 36 | * Mobile. 37 | * @var {bool} 38 | */ 39 | mobile: null, 40 | 41 | /** 42 | * Temporary element for canUse() 43 | * @var {DOMElement} 44 | */ 45 | _canUse: null, 46 | 47 | /** 48 | * Determines if the browser supports a given property. 49 | * @param {string} p Property. 50 | * @return {bool} True if property is supported, false if not. 51 | */ 52 | canUse: function(p) { 53 | 54 | // Create temporary element if it doesn't already exist. 55 | if (!_._canUse) 56 | _._canUse = document.createElement('div'); 57 | 58 | // Check for property. 59 | var e = _._canUse.style, 60 | up = p.charAt(0).toUpperCase() + p.slice(1); 61 | 62 | return ( 63 | p in e 64 | || ('Moz' + up) in e 65 | || ('Webkit' + up) in e 66 | || ('O' + up) in e 67 | || ('ms' + up) in e 68 | ); 69 | 70 | }, 71 | 72 | /** 73 | * Initialize. 74 | */ 75 | init: function() { 76 | 77 | var x, y, a, i, ua = navigator.userAgent; 78 | 79 | // name, version. 80 | x = 'other'; 81 | y = 0; 82 | a = [ 83 | ['firefox', /Firefox\/([0-9\.]+)/], 84 | ['bb', /BlackBerry.+Version\/([0-9\.]+)/], 85 | ['bb', /BB[0-9]+.+Version\/([0-9\.]+)/], 86 | ['opera', /OPR\/([0-9\.]+)/], 87 | ['opera', /Opera\/([0-9\.]+)/], 88 | ['edge', /Edge\/([0-9\.]+)/], 89 | ['safari', /Version\/([0-9\.]+).+Safari/], 90 | ['chrome', /Chrome\/([0-9\.]+)/], 91 | ['ie', /MSIE ([0-9]+)/], 92 | ['ie', /Trident\/.+rv:([0-9]+)/] 93 | ]; 94 | 95 | for (i=0; i < a.length; i++) { 96 | 97 | if (ua.match(a[i][1])) { 98 | 99 | x = a[i][0]; 100 | y = parseFloat(RegExp.$1); 101 | 102 | break; 103 | 104 | } 105 | 106 | } 107 | 108 | _.name = x; 109 | _.version = y; 110 | 111 | // os, osVersion. 112 | x = 'other'; 113 | y = 0; 114 | a = [ 115 | ['ios', /([0-9_]+) like Mac OS X/, function(v) { return v.replace('_', '.').replace('_', ''); }], 116 | ['ios', /CPU like Mac OS X/, function(v) { return 0 }], 117 | ['wp', /Windows Phone ([0-9\.]+)/, null], 118 | ['android', /Android ([0-9\.]+)/, null], 119 | ['mac', /Macintosh.+Mac OS X ([0-9_]+)/, function(v) { return v.replace('_', '.').replace('_', ''); }], 120 | ['windows', /Windows NT ([0-9\.]+)/, null], 121 | ['bb', /BlackBerry.+Version\/([0-9\.]+)/, null], 122 | ['bb', /BB[0-9]+.+Version\/([0-9\.]+)/, null] 123 | ]; 124 | 125 | for (i=0; i < a.length; i++) { 126 | 127 | if (ua.match(a[i][1])) { 128 | 129 | x = a[i][0]; 130 | y = parseFloat( a[i][2] ? (a[i][2])(RegExp.$1) : RegExp.$1 ); 131 | 132 | break; 133 | 134 | } 135 | 136 | } 137 | 138 | _.os = x; 139 | _.osVersion = y; 140 | 141 | // touch. 142 | _.touch = (_.os == 'wp' ? (navigator.msMaxTouchPoints > 0) : !!('ontouchstart' in window)); 143 | 144 | // mobile. 145 | _.mobile = (_.os == 'wp' || _.os == 'android' || _.os == 'ios' || _.os == 'bb'); 146 | 147 | }, 148 | 149 | }; _.init(); return _; })(); 150 | 151 | // UMD Wrapper (github.com/umdjs/umd/blob/master/returnExports.js | @umdjs + @nason) 152 | (function(root, factory) { 153 | 154 | // AMD. 155 | if (typeof define === 'function' && define.amd) 156 | define([], factory); 157 | 158 | // Node. 159 | else if (typeof exports === 'object') 160 | module.exports = factory(); 161 | 162 | // Browser global. 163 | else 164 | root.browser = factory(); 165 | 166 | }(this, function() { return browser; })); -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Industrious by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | (function($) { 7 | 8 | var $window = $(window), 9 | $banner = $('#banner'), 10 | $body = $('body'); 11 | 12 | // Breakpoints. 13 | breakpoints({ 14 | default: ['1681px', null ], 15 | xlarge: ['1281px', '1680px' ], 16 | large: ['981px', '1280px' ], 17 | medium: ['737px', '980px' ], 18 | small: ['481px', '736px' ], 19 | xsmall: ['361px', '480px' ], 20 | xxsmall: [null, '360px' ] 21 | }); 22 | 23 | // Play initial animations on page load. 24 | $window.on('load', function() { 25 | window.setTimeout(function() { 26 | $body.removeClass('is-preload'); 27 | }, 100); 28 | }); 29 | 30 | // Menu. 31 | $('#menu') 32 | .append('') 33 | .appendTo($body) 34 | .panel({ 35 | target: $body, 36 | visibleClass: 'is-menu-visible', 37 | delay: 500, 38 | hideOnClick: true, 39 | hideOnSwipe: true, 40 | resetScroll: true, 41 | resetForms: true, 42 | side: 'right' 43 | }); 44 | 45 | })(jQuery); -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/base/_page.scss: -------------------------------------------------------------------------------- 1 | /* Basic */ 2 | 3 | // MSIE: Required for IEMobile. 4 | @-ms-viewport { 5 | width: device-width; 6 | } 7 | 8 | // MSIE: Prevents scrollbar from overlapping content. 9 | body { 10 | -ms-overflow-style: scrollbar; 11 | } 12 | 13 | // Ensures page width is always >=320px. 14 | @include breakpoint('<=xsmall') { 15 | html, body { 16 | min-width: 320px; 17 | } 18 | } 19 | 20 | // Set box model to border-box. 21 | // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice 22 | html { 23 | box-sizing: border-box; 24 | } 25 | 26 | *, *:before, *:after { 27 | box-sizing: inherit; 28 | } 29 | 30 | body { 31 | background: _palette(bg); 32 | 33 | // Stops initial animations until page loads. 34 | &.is-preload { 35 | *, *:before, *:after { 36 | @include vendor('animation', 'none !important'); 37 | @include vendor('transition', 'none !important'); 38 | } 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/base/_reset.scss: -------------------------------------------------------------------------------- 1 | // Reset. 2 | // Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain) 3 | 4 | html, body, div, span, applet, object, 5 | iframe, h1, h2, h3, h4, h5, h6, p, blockquote, 6 | pre, a, abbr, acronym, address, big, cite, 7 | code, del, dfn, em, img, ins, kbd, q, s, samp, 8 | small, strike, strong, sub, sup, tt, var, b, 9 | u, i, center, dl, dt, dd, ol, ul, li, fieldset, 10 | form, label, legend, table, caption, tbody, 11 | tfoot, thead, tr, th, td, article, aside, 12 | canvas, details, embed, figure, figcaption, 13 | footer, header, hgroup, menu, nav, output, ruby, 14 | section, summary, time, mark, audio, video { 15 | margin: 0; 16 | padding: 0; 17 | border: 0; 18 | font-size: 100%; 19 | font: inherit; 20 | vertical-align: baseline; 21 | } 22 | 23 | article, aside, details, figcaption, figure, 24 | footer, header, hgroup, menu, nav, section { 25 | display: block; 26 | } 27 | 28 | body { 29 | line-height: 1; 30 | } 31 | 32 | ol, ul { 33 | list-style:none; 34 | } 35 | 36 | blockquote, q { 37 | quotes: none; 38 | 39 | &:before, 40 | &:after { 41 | content: ''; 42 | content: none; 43 | } 44 | } 45 | 46 | table { 47 | border-collapse: collapse; 48 | border-spacing: 0; 49 | } 50 | 51 | body { 52 | -webkit-text-size-adjust: none; 53 | } 54 | 55 | mark { 56 | background-color: transparent; 57 | color: inherit; 58 | } 59 | 60 | input::-moz-focus-inner { 61 | border: 0; 62 | padding: 0; 63 | } 64 | 65 | input, select, textarea { 66 | -moz-appearance: none; 67 | -webkit-appearance: none; 68 | -ms-appearance: none; 69 | appearance: none; 70 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/base/_typography.scss: -------------------------------------------------------------------------------- 1 | /* Typography */ 2 | 3 | html { 4 | font-size: 13pt; 5 | 6 | @include breakpoint('<=xlarge') { 7 | font-size: 11pt; 8 | } 9 | 10 | @include breakpoint('<=medium') { 11 | font-size: 12pt; 12 | } 13 | 14 | @include breakpoint('<=xsmall') { 15 | font-size: 11pt; 16 | } 17 | } 18 | 19 | body { 20 | background-color: _palette(bg); 21 | color: _palette(fg); 22 | } 23 | 24 | body, input, select, textarea { 25 | font-family: _font(family); 26 | font-weight: _font(weight); 27 | font-size: 1rem; 28 | line-height: 1.65; 29 | } 30 | 31 | a { 32 | @include vendor('transition', 'color #{_duration(transition)} ease-in-out'); 33 | text-decoration: underline; 34 | 35 | &:hover { 36 | text-decoration: none; 37 | } 38 | } 39 | 40 | strong, b { 41 | font-weight: _font(weight-bold); 42 | } 43 | 44 | em, i { 45 | font-style: italic; 46 | } 47 | 48 | p { 49 | margin: 0 0 _size(element-margin) 0; 50 | } 51 | 52 | header { 53 | &.special { 54 | text-align:center; 55 | margin-bottom: _size(element-margin) * 2; 56 | 57 | p { 58 | max-width: 75%; 59 | margin-left: auto; 60 | margin-right: auto; 61 | } 62 | } 63 | } 64 | 65 | h1, h2, h3, h4, h5, h6 { 66 | font-weight: _font(weight-light); 67 | line-height: 1.5; 68 | text-transform: uppercase; 69 | margin: 0 0 (_size(element-margin) * 0.75) 0; 70 | 71 | a { 72 | color: inherit; 73 | text-decoration: none; 74 | } 75 | } 76 | 77 | h1 { 78 | font-size: 3rem; 79 | line-height: 1.2; 80 | } 81 | 82 | h2 { 83 | font-size: 2.25rem; 84 | line-height: 1.3; 85 | } 86 | 87 | h3 { 88 | font-size: 1.25rem; 89 | } 90 | 91 | h4 { 92 | font-size: 1rem; 93 | } 94 | 95 | h5 { 96 | font-size: 0.9rem; 97 | } 98 | 99 | h6 { 100 | font-size: 0.7rem; 101 | } 102 | 103 | @include breakpoint('<=small') { 104 | h1 { 105 | font-size: 2.75rem; 106 | line-height: 1.3; 107 | } 108 | 109 | h2 { 110 | font-size: 1.75rem; 111 | line-height: 1.5; 112 | } 113 | 114 | h3 { 115 | font-size: 1.25rem; 116 | } 117 | } 118 | 119 | sub { 120 | font-size: 0.8rem; 121 | position: relative; 122 | top: 0.5rem; 123 | } 124 | 125 | sup { 126 | font-size: 0.8rem; 127 | position: relative; 128 | top: -0.5rem; 129 | } 130 | 131 | blockquote { 132 | border-left: solid 0.5rem; 133 | font-style: italic; 134 | margin: 0 0 _size(element-margin) 0; 135 | padding: (_size(element-margin) * 0.5) 0 (_size(element-margin) * 0.5) _size(element-margin); 136 | } 137 | 138 | code { 139 | border-radius: _size(border-radius); 140 | border: solid 1px; 141 | font-family: _font(family-fixed); 142 | font-size: 0.9rem; 143 | margin: 0 0.25rem; 144 | padding: 0.25rem 0.65rem; 145 | } 146 | 147 | pre { 148 | -webkit-overflow-scrolling: touch; 149 | font-family: _font(family-fixed); 150 | font-size: 0.9rem; 151 | margin: 0 0 _size(element-margin) 0; 152 | 153 | code { 154 | display: block; 155 | line-height: 1.75; 156 | padding: 1rem 1.5rem; 157 | overflow-x: auto; 158 | } 159 | } 160 | 161 | hr { 162 | border: 0; 163 | border-bottom: solid 1px; 164 | margin: _size(element-margin) 0; 165 | 166 | &.major { 167 | margin: (_size(element-margin) * 2) 0; 168 | } 169 | } 170 | 171 | @mixin color-typography($p: null) { 172 | $highlight: _palette($p, highlight); 173 | 174 | @if $p != null { 175 | background-color: _palette($p, bg); 176 | color: _palette($p, fg); 177 | } 178 | 179 | input, select, textarea { 180 | color: _palette($p, fg-bold); 181 | } 182 | 183 | a { 184 | @if $p == $highlight { 185 | color: _palette($p, fg-bold); 186 | } 187 | @else { 188 | color: _palette(accent1, bg); 189 | } 190 | } 191 | 192 | strong, b { 193 | color: _palette($p, fg-bold); 194 | } 195 | 196 | h1, h2, h3, h4, h5, h6 { 197 | color: _palette($p, fg-bold); 198 | } 199 | 200 | blockquote { 201 | border-left-color: _palette($p, border); 202 | } 203 | 204 | code { 205 | background: _palette($p, border-bg); 206 | border-color: _palette($p, border); 207 | } 208 | 209 | hr { 210 | border-bottom-color: _palette($p, border); 211 | } 212 | } 213 | 214 | @include color-typography; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_actions.scss: -------------------------------------------------------------------------------- 1 | /* Actions */ 2 | 3 | ul.actions { 4 | @include vendor('display', 'flex'); 5 | cursor: default; 6 | list-style: none; 7 | margin-left: (_size(element-margin) * -0.5); 8 | padding-left: 0; 9 | 10 | li { 11 | padding: 0 0 0 (_size(element-margin) * 0.5); 12 | vertical-align: middle; 13 | } 14 | 15 | &.special { 16 | @include vendor('justify-content', 'center'); 17 | width: calc(100% + #{_size(element-margin) * 0.5}); 18 | } 19 | 20 | &.stacked { 21 | @include vendor('flex-direction', 'column'); 22 | margin-left: 0; 23 | 24 | li { 25 | padding: (_size(element-margin) * 0.65) 0 0 0; 26 | 27 | &:first-child { 28 | padding-top: 0; 29 | } 30 | } 31 | } 32 | 33 | &.fit { 34 | width: calc(100% + #{_size(element-margin) * 0.5}); 35 | 36 | li { 37 | @include vendor('flex-grow', '1'); 38 | @include vendor('flex-shrink', '1'); 39 | width: 100%; 40 | 41 | > * { 42 | width: 100%; 43 | } 44 | } 45 | 46 | &.stacked { 47 | width: 100%; 48 | } 49 | } 50 | 51 | @include breakpoint('<=xsmall') { 52 | &:not(.fixed) { 53 | @include vendor('flex-direction', 'column'); 54 | margin-left: 0; 55 | width: 100% !important; 56 | 57 | li { 58 | @include vendor('flex-grow', '1'); 59 | @include vendor('flex-shrink', '1'); 60 | padding: (_size(element-margin) * 0.5) 0 0 0; 61 | text-align: center; 62 | width: 100%; 63 | 64 | > * { 65 | width: 100%; 66 | } 67 | 68 | &:first-child { 69 | padding-top: 0; 70 | } 71 | 72 | input[type="submit"], 73 | input[type="reset"], 74 | input[type="button"], 75 | button, 76 | .button { 77 | width: 100%; 78 | 79 | &.icon { 80 | &:before { 81 | margin-left: -0.5rem; 82 | } 83 | } 84 | } 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_box.scss: -------------------------------------------------------------------------------- 1 | /* Box */ 2 | 3 | .box { 4 | border-radius: _size(border-radius); 5 | box-shadow: 0px 0px 4px 1px _palette(border-lt); 6 | padding: 3rem; 7 | 8 | > :last-child { 9 | margin-bottom: 0; 10 | } 11 | 12 | &.alt { 13 | border: 0; 14 | border-radius: 0; 15 | padding: 0; 16 | } 17 | 18 | @include breakpoint('<=medium') { 19 | padding: 2rem; 20 | } 21 | } 22 | 23 | @mixin color-box($p: null) { 24 | .box { 25 | border-color: _palette($p, border); 26 | } 27 | } 28 | 29 | @include color-box; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_button.scss: -------------------------------------------------------------------------------- 1 | /* Button */ 2 | 3 | input[type="submit"], 4 | input[type="reset"], 5 | input[type="button"], 6 | button, 7 | .button { 8 | @include vendor('appearance', 'none'); 9 | @include vendor('transition', ( 10 | 'background-color #{_duration(transition)} ease-in-out', 11 | 'box-shadow #{_duration(transition)} ease-in-out', 12 | 'color #{_duration(transition)} ease-in-out' 13 | )); 14 | border: 0; 15 | border-radius: _size(border-radius); 16 | cursor: pointer; 17 | display: inline-block; 18 | font-weight: _font(weight-bold); 19 | height: _size(element-height); 20 | line-height: _size(element-height); 21 | padding: 0 1.75rem; 22 | text-align: center; 23 | text-decoration: none; 24 | white-space: nowrap; 25 | 26 | &.small { 27 | font-size: 0.8rem; 28 | height: _size(element-height) * 0.75; 29 | line-height: _size(element-height) * 0.75; 30 | padding: 0 1.25rem; 31 | } 32 | 33 | &.large { 34 | font-size: 1.35rem; 35 | height: _size(element-height) * 1.25; 36 | line-height: _size(element-height) * 1.25; 37 | padding: 0 2rem; 38 | } 39 | 40 | &.wide { 41 | min-width: 13rem; 42 | } 43 | 44 | &.icon { 45 | &:before { 46 | margin-right: 0.5rem; 47 | } 48 | } 49 | 50 | &.fit { 51 | width: 100%; 52 | } 53 | 54 | &.disabled, 55 | &:disabled { 56 | @include vendor('pointer-events', 'none'); 57 | opacity: 0.25; 58 | } 59 | } 60 | 61 | @mixin color-button($p: null) { 62 | $highlight: _palette($p, highlight); 63 | 64 | input[type="submit"], 65 | input[type="reset"], 66 | input[type="button"], 67 | button, 68 | .button { 69 | background-color: transparent; 70 | box-shadow: inset 0 0 0 1px _palette($p, fg-bold); 71 | color: _palette($p, fg-bold) !important; 72 | 73 | @if ($p == $highlight) { 74 | &:hover { 75 | background-color: transparentize(_palette($p, fg-bold), 0.9); 76 | 77 | &:active { 78 | background-color: transparentize(_palette($p, fg-bold), 0.75); 79 | } 80 | } 81 | } 82 | @else { 83 | &:hover { 84 | box-shadow: inset 0 0 0 1px _palette($highlight, bg); 85 | color: _palette($highlight, bg) !important; 86 | 87 | &:active { 88 | background-color: transparentize(_palette($highlight, bg), 0.75); 89 | } 90 | } 91 | } 92 | 93 | &.primary { 94 | box-shadow: none; 95 | 96 | @if $p == $highlight { 97 | background-color: _palette($p, fg-bold); 98 | color: _palette($p, bg) !important; 99 | 100 | &:hover { 101 | background-color: transparentize(_palette($p, fg-bold), 0.125); 102 | box-shadow: none; 103 | 104 | &:active { 105 | background-color: transparentize(_palette($p, fg-bold), 0.5); 106 | } 107 | } 108 | } 109 | @else { 110 | background-color: _palette($highlight, bg); 111 | color: _palette($highlight, fg-bold) !important; 112 | 113 | &:hover { 114 | background-color: lighten(_palette($highlight, bg), 5); 115 | box-shadow: none; 116 | 117 | &:active { 118 | background-color: darken(_palette($highlight, bg), 5); 119 | } 120 | } 121 | } 122 | } 123 | } 124 | } 125 | 126 | @include color-button; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_form.scss: -------------------------------------------------------------------------------- 1 | /* Form */ 2 | 3 | form { 4 | margin: 0 0 _size(element-margin) 0; 5 | } 6 | 7 | input[type="text"], 8 | input[type="password"], 9 | input[type="email"], 10 | input[type="tel"], 11 | input[type="search"], 12 | input[type="url"], 13 | select, 14 | textarea { 15 | @include vendor('appearance', 'none'); 16 | border-radius: _size(border-radius); 17 | border: none; 18 | border: solid 1px; 19 | color: inherit; 20 | display: block; 21 | outline: 0; 22 | padding: 0 1rem; 23 | text-decoration: none; 24 | width: 100%; 25 | 26 | &:invalid { 27 | box-shadow: none; 28 | } 29 | } 30 | 31 | label { 32 | display: block; 33 | font-size: 1rem; 34 | font-weight: _font(weight-bold); 35 | margin: 0 0 (_size(element-margin) * 0.5) 0; 36 | } 37 | 38 | input[type="text"], 39 | input[type="password"], 40 | input[type="email"], 41 | input[type="tel"], 42 | input[type="search"], 43 | input[type="url"] { 44 | height: _size(element-height); 45 | } 46 | 47 | select { 48 | background-size: 1.25rem; 49 | background-repeat: no-repeat; 50 | background-position: calc(100% - 1rem) center; 51 | height: _size(element-height); 52 | padding-right: _size(element-height); 53 | text-overflow: ellipsis; 54 | 55 | &:focus { 56 | &::-ms-value { 57 | background-color: transparent; 58 | } 59 | } 60 | 61 | &::-ms-expand { 62 | display: none; 63 | } 64 | } 65 | 66 | textarea { 67 | padding: 0.75rem 1rem; 68 | } 69 | 70 | input[type="checkbox"], 71 | input[type="radio"], { 72 | @include vendor('appearance', 'none'); 73 | display: block; 74 | float: left; 75 | margin-right: -2rem; 76 | opacity: 0; 77 | width: 1rem; 78 | z-index: -1; 79 | 80 | & + label { 81 | @include icon; 82 | cursor: pointer; 83 | display: inline-block; 84 | font-size: 1rem; 85 | font-weight: _font(weight); 86 | padding-left: (_size(element-height) * 0.6) + 0.875rem; 87 | padding-right: 0.875rem; 88 | position: relative; 89 | 90 | &:before { 91 | border-radius: _size(border-radius); 92 | border: solid 1px; 93 | content: ''; 94 | display: inline-block; 95 | height: (_size(element-height) * 0.6); 96 | left: 0; 97 | line-height: (_size(element-height) * 0.575); 98 | position: absolute; 99 | text-align: center; 100 | top: (_size(element-height) * -0.05); 101 | width: (_size(element-height) * 0.6); 102 | } 103 | } 104 | 105 | &:checked + label { 106 | &:before { 107 | content: '\f00c'; 108 | } 109 | } 110 | } 111 | 112 | input[type="checkbox"] { 113 | & + label { 114 | &:before { 115 | border-radius: _size(border-radius); 116 | } 117 | } 118 | } 119 | 120 | input[type="radio"] { 121 | & + label { 122 | &:before { 123 | border-radius: 100%; 124 | } 125 | } 126 | } 127 | 128 | ::-webkit-input-placeholder { 129 | opacity: 1.0; 130 | } 131 | 132 | :-moz-placeholder { 133 | opacity: 1.0; 134 | } 135 | 136 | ::-moz-placeholder { 137 | opacity: 1.0; 138 | } 139 | 140 | :-ms-input-placeholder { 141 | opacity: 1.0; 142 | } 143 | 144 | @mixin color-form($p: null) { 145 | $highlight: _palette($p, highlight); 146 | 147 | label { 148 | color: _palette($p, fg-bold); 149 | } 150 | 151 | input[type="text"], 152 | input[type="password"], 153 | input[type="email"], 154 | input[type="tel"], 155 | input[type="search"], 156 | input[type="url"], 157 | select, 158 | textarea { 159 | background-color: _palette($p, border-bg); 160 | border-color: _palette($p, border); 161 | 162 | &:focus { 163 | @if $p == $highlight { 164 | border-color: _palette($p, fg-bold); 165 | box-shadow: 0 0 0 1px _palette($p, fg-bold); 166 | } 167 | @else { 168 | border-color: _palette(accent1, bg); 169 | box-shadow: 0 0 0 1px _palette(accent1, bg); 170 | } 171 | } 172 | } 173 | 174 | select { 175 | background-image: svg-url(""); 176 | 177 | option { 178 | color: _palette($p, fg); 179 | background-color: _palette($p, bg); 180 | } 181 | } 182 | 183 | input[type="checkbox"], 184 | input[type="radio"], { 185 | & + label { 186 | color: _palette($p, fg); 187 | 188 | &:before { 189 | background: _palette($p, border-bg); 190 | border-color: _palette($p, border); 191 | } 192 | } 193 | 194 | &:checked + label { 195 | &:before { 196 | @if $p == $highlight { 197 | background-color: _palette($p, fg-bold); 198 | border-color: _palette($p, fg-bold); 199 | color: _palette($p, bg); 200 | } 201 | @else { 202 | background-color: _palette(accent1, bg); 203 | border-color: _palette(accent1, bg); 204 | color: _palette(accent1, fg-bold); 205 | } 206 | } 207 | } 208 | 209 | &:focus + label { 210 | &:before { 211 | @if $p == $highlight { 212 | border-color: _palette($p, fg-bold); 213 | box-shadow: 0 0 0 1px _palette($p, fg-bold); 214 | } 215 | @else { 216 | border-color: _palette(accent1, bg); 217 | box-shadow: 0 0 0 1px _palette(accent1, bg); 218 | } 219 | } 220 | } 221 | } 222 | 223 | ::-webkit-input-placeholder { 224 | color: _palette($p, fg-light) !important; 225 | } 226 | 227 | :-moz-placeholder { 228 | color: _palette($p, fg-light) !important; 229 | } 230 | 231 | ::-moz-placeholder { 232 | color: _palette($p, fg-light) !important; 233 | } 234 | 235 | :-ms-input-placeholder { 236 | color: _palette($p, fg-light) !important; 237 | } 238 | } 239 | 240 | @include color-form; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_grid.scss: -------------------------------------------------------------------------------- 1 | /* Grid */ 2 | 3 | @include grid(3rem); 4 | 5 | @include breakpoint('<=xlarge') { 6 | @include grid(3rem, 'xlarge'); 7 | } 8 | 9 | @include breakpoint('<=large') { 10 | @include grid(1.5rem, 'large'); 11 | } 12 | 13 | @include breakpoint('<=medium') { 14 | @include grid(1.5rem, 'medium'); 15 | } 16 | 17 | @include breakpoint('<=small') { 18 | @include grid(1.25rem, 'small'); 19 | } 20 | 21 | @include breakpoint('<=xsmall') { 22 | @include grid(1.25rem, 'xsmall'); 23 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_highlights.scss: -------------------------------------------------------------------------------- 1 | /* Highlights */ 2 | 3 | .highlights { 4 | width: 100%; 5 | margin: (_size(element-margin) * 1.25) 0; 6 | 7 | @include flexgrid(( 8 | columns: 3, 9 | gutters: 3rem, 10 | vertical-align: stretch 11 | )); 12 | 13 | .content { 14 | border-radius: _size(border-radius); 15 | height: 100%; 16 | padding: 3rem; 17 | text-align: center; 18 | 19 | .icon { 20 | font-size: 5rem; 21 | } 22 | } 23 | 24 | > div { 25 | 26 | > :last-child { 27 | margin-bottom: 0; 28 | } 29 | 30 | } 31 | 32 | @include breakpoint('<=medium') { 33 | @include flexgrid-resize(( 34 | columns: 2, 35 | gutters: 2rem, 36 | prev-columns: 3 37 | )); 38 | 39 | .content { 40 | padding: 2rem; 41 | } 42 | } 43 | 44 | @include breakpoint('<=small') { 45 | @include flexgrid-resize(( 46 | columns: 1, 47 | gutters: 2rem, 48 | prev-columns: (3, 2) 49 | )); 50 | 51 | } 52 | } 53 | 54 | @mixin color-highlights($p: null) { 55 | $highlight: _palette($p, highlight); 56 | 57 | .highlights { 58 | .content { 59 | background: _palette($p, bg); 60 | box-shadow: 0px 0px 4px 1px _palette($p, border-lt); 61 | } 62 | } 63 | } 64 | 65 | @include color-highlights; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_icon.scss: -------------------------------------------------------------------------------- 1 | /* Icon */ 2 | 3 | .icon { 4 | @include icon; 5 | border-bottom: none; 6 | position: relative; 7 | 8 | > .label { 9 | display: none; 10 | } 11 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_icons.scss: -------------------------------------------------------------------------------- 1 | /* Icons */ 2 | 3 | ul.icons { 4 | cursor: default; 5 | list-style: none; 6 | padding-left: 0; 7 | 8 | li { 9 | display: inline-block; 10 | padding: 0 1rem 0 0; 11 | 12 | &:last-child { 13 | padding-right: 0; 14 | } 15 | 16 | .icon { 17 | &:before { 18 | font-size: 2rem; 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_image.scss: -------------------------------------------------------------------------------- 1 | /* Image */ 2 | 3 | .image { 4 | border-radius: _size(border-radius); 5 | border: 0; 6 | display: inline-block; 7 | position: relative; 8 | 9 | img { 10 | border-radius: _size(border-radius); 11 | display: block; 12 | } 13 | 14 | &.left, 15 | &.right { 16 | max-width: 40%; 17 | 18 | img { 19 | width: 100%; 20 | } 21 | } 22 | 23 | &.left { 24 | float: left; 25 | margin: 0 2rem 2rem 0; 26 | top: 0.25rem; 27 | } 28 | 29 | &.right { 30 | float: right; 31 | margin: 0 0 2rem 2rem; 32 | top: 0.25rem; 33 | } 34 | 35 | &.fit { 36 | display: block; 37 | margin: 0 0 _size(element-margin) 0; 38 | width: 100%; 39 | 40 | img { 41 | width: 100%; 42 | } 43 | } 44 | 45 | &.main { 46 | display: block; 47 | margin: 0 0 (_size(element-margin) * 1.5) 0; 48 | width: 100%; 49 | 50 | img { 51 | width: 100%; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_inner.scss: -------------------------------------------------------------------------------- 1 | /* Inner */ 2 | 3 | .inner { 4 | margin: 0 auto; 5 | width: _size(inner-width); 6 | max-width: calc(100% - 6rem); 7 | 8 | @include breakpoint('<=xsmall') { 9 | max-width: calc(100% - 3rem); 10 | } 11 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_list.scss: -------------------------------------------------------------------------------- 1 | /* List */ 2 | 3 | ol { 4 | list-style: decimal; 5 | margin: 0 0 _size(element-margin) 0; 6 | padding-left: 1.25rem; 7 | 8 | li { 9 | padding-left: 0.25rem; 10 | } 11 | } 12 | 13 | ul { 14 | list-style: disc; 15 | margin: 0 0 _size(element-margin) 0; 16 | padding-left: 1rem; 17 | 18 | li { 19 | padding-left: 0.325rem; 20 | } 21 | 22 | &.plain { 23 | list-style: none; 24 | padding-left: 0; 25 | 26 | li { 27 | margin-bottom: 1rem; 28 | 29 | .icon { 30 | border-radius: _size(border-radius); 31 | color: _palette(accent1,fg-bold); 32 | display: inline-block; 33 | margin-right: 1rem; 34 | text-align:center; 35 | width: 2rem; 36 | height: 2rem; 37 | line-height: 2rem; 38 | background: rgba(0,0,0,0.5); 39 | } 40 | 41 | } 42 | } 43 | 44 | &.alt { 45 | list-style: none; 46 | padding-left: 0; 47 | 48 | li { 49 | border-top: solid 1px; 50 | padding: 0.75rem 0; 51 | 52 | &:first-child { 53 | border-top: 0; 54 | padding-top: 0; 55 | } 56 | 57 | &:last-child { 58 | padding-bottom: 0; 59 | } 60 | } 61 | } 62 | } 63 | 64 | dl { 65 | margin: 0 0 _size(element-margin) 0; 66 | 67 | dt { 68 | display: block; 69 | font-weight: _font(weight-bold); 70 | margin: 0 0 (_size(element-margin) * 0.5) 0; 71 | } 72 | 73 | dd { 74 | margin-left: (_size(element-margin) * 0.75); 75 | } 76 | } 77 | 78 | @mixin color-list($p: null) { 79 | ul { 80 | &.alt { 81 | li { 82 | border-top-color: _palette($p, border); 83 | } 84 | } 85 | } 86 | } 87 | 88 | @include color-list; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_table.scss: -------------------------------------------------------------------------------- 1 | /* Table */ 2 | 3 | .table-wrapper { 4 | -webkit-overflow-scrolling: touch; 5 | overflow-x: auto; 6 | } 7 | 8 | table { 9 | margin: 0 0 _size(element-margin) 0; 10 | width: 100%; 11 | 12 | tbody { 13 | tr { 14 | border: solid 1px; 15 | border-left: 0; 16 | border-right: 0; 17 | } 18 | } 19 | 20 | td { 21 | padding: 0.75rem 0.75rem; 22 | } 23 | 24 | th { 25 | font-size: 0.9rem; 26 | font-weight: _font(weight-bold); 27 | padding: 0 0.75rem 0.75rem 0.75rem; 28 | text-align: left; 29 | } 30 | 31 | thead { 32 | border-bottom: solid 2px; 33 | } 34 | 35 | tfoot { 36 | border-top: solid 2px; 37 | } 38 | 39 | &.alt { 40 | border-collapse: separate; 41 | 42 | tbody { 43 | tr { 44 | td { 45 | border: solid 1px; 46 | border-left-width: 0; 47 | border-top-width: 0; 48 | 49 | &:first-child { 50 | border-left-width: 1px; 51 | } 52 | } 53 | 54 | &:first-child { 55 | td { 56 | border-top-width: 1px; 57 | } 58 | } 59 | } 60 | } 61 | 62 | thead { 63 | border-bottom: 0; 64 | } 65 | 66 | tfoot { 67 | border-top: 0; 68 | } 69 | } 70 | } 71 | 72 | @mixin color-table($p: null) { 73 | table { 74 | tbody { 75 | tr { 76 | border-color: _palette($p, border); 77 | 78 | &:nth-child(2n + 1) { 79 | background-color: _palette($p, border-bg); 80 | } 81 | } 82 | } 83 | 84 | th { 85 | color: _palette($p, fg-bold); 86 | } 87 | 88 | thead { 89 | border-bottom-color: _palette($p, border); 90 | } 91 | 92 | tfoot { 93 | border-top-color: _palette($p, border); 94 | } 95 | 96 | &.alt { 97 | tbody { 98 | tr { 99 | td { 100 | border-color: _palette($p, border); 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | 108 | @include color-table; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_testimonials.scss: -------------------------------------------------------------------------------- 1 | /* Testimonials */ 2 | 3 | .testimonials { 4 | margin: (_size(element-margin) * 1.25) 0; 5 | width: 100%; 6 | 7 | @include flexgrid(( 8 | columns: 3, 9 | gutters: 3rem, 10 | vertical-align: stretch, 11 | )); 12 | 13 | .content { 14 | border-radius: _size(border-radius); 15 | height: 100%; 16 | padding: 3rem; 17 | 18 | .author { 19 | @include vendor('display','flex'); 20 | @include vendor('align-items','center'); 21 | 22 | blockquote { 23 | margin: 0; 24 | } 25 | 26 | .image { 27 | margin-right: 2rem; 28 | width: 20%; 29 | 30 | img { 31 | border-radius: 100%; 32 | max-width: 100%; 33 | } 34 | } 35 | } 36 | 37 | .credit { 38 | font-size: 0.75rem; 39 | } 40 | 41 | p { 42 | &:last-child { 43 | margin: 0; 44 | } 45 | } 46 | } 47 | 48 | > div { 49 | > :last-child { 50 | margin-bottom: 0; 51 | } 52 | } 53 | 54 | @include breakpoint('<=medium') { 55 | @include flexgrid-resize(( 56 | columns: 2, 57 | gutters: 2rem, 58 | prev-columns: 3 59 | )); 60 | 61 | .content { 62 | padding: 2rem; 63 | } 64 | } 65 | 66 | @include breakpoint('<=small') { 67 | @include flexgrid-resize(( 68 | columns: 1, 69 | gutters: 2rem, 70 | prev-columns: (3, 2) 71 | )); 72 | } 73 | } 74 | 75 | @mixin color-testimonials($p: null) { 76 | $highlight: _palette($p, highlight); 77 | 78 | .testimonials { 79 | .content { 80 | background: _palette($p, bg); 81 | box-shadow: 0px 0px 4px 1px _palette($p, border-lt); 82 | 83 | .credit { 84 | strong { 85 | color: _palette($highlight,bg); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | 92 | @include color-testimonials; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/components/_wrapper.scss: -------------------------------------------------------------------------------- 1 | /* Wrapper */ 2 | 3 | .wrapper { 4 | @include padding(8rem, 0); 5 | position: relative; 6 | z-index: 1; 7 | 8 | @include breakpoint('<=large') { 9 | @include padding(4rem, 0); 10 | } 11 | 12 | @include breakpoint('<=small') { 13 | @include padding(3rem, 0); 14 | } 15 | 16 | @include breakpoint('<=xsmall') { 17 | @include padding(2rem, 0); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_banner.scss: -------------------------------------------------------------------------------- 1 | /* Banner */ 2 | 3 | #banner { 4 | -ms-flex-align: center; 5 | -ms-flex-pack: center; 6 | @include color(accent2); 7 | @include vendor('align-items', 'center'); 8 | @include vendor('display', 'flex'); 9 | @include vendor('justify-content', 'center'); 10 | background-image: url('../../images/banner.jpg'); 11 | background-position: center; 12 | background-repeat: no-repeat; 13 | background-size: cover; 14 | border-top: 0; 15 | display: -ms-flexbox; 16 | height: 35rem !important; 17 | min-height: 35rem; 18 | overflow: hidden; 19 | position: relative; 20 | text-align: center; 21 | width: 100%; 22 | 23 | > .inner { 24 | @include vendor('transform', 'scale(1.0)'); 25 | @include vendor('transition', ( 26 | 'opacity #{_duration(banner)} ease', 27 | 'transform #{_duration(banner)} ease' 28 | )); 29 | opacity: 1; 30 | position: relative; 31 | z-index: 3; 32 | 33 | > :last-child { 34 | margin-bottom: 0; 35 | } 36 | } 37 | 38 | h1 { 39 | font-size: 4rem; 40 | margin-bottom: 1rem; 41 | } 42 | 43 | p { 44 | font-size: 1.5rem; 45 | } 46 | 47 | a { 48 | color: _palette(accent2, fg); 49 | text-decoration: none; 50 | 51 | &:hover { 52 | color: _palette(accent2, fg-bold); 53 | } 54 | } 55 | 56 | video { 57 | @include vendor('transform', 'translateX(50%) translateY(50%)'); 58 | bottom: 50%; 59 | height: auto; 60 | min-height: 100%; 61 | min-width: 100%; 62 | overflow: hidden; 63 | position: absolute; 64 | right: 50%; 65 | width: auto; 66 | } 67 | 68 | &:before { 69 | @include vendor('transition', 'opacity 3s ease'); 70 | @include vendor('transition-delay', '#{_duration(banner) * 1.25}'); 71 | background: _palette(accent2,bg); 72 | content: ''; 73 | display: block; 74 | height: 100%; 75 | left: 0; 76 | opacity: 0.45; 77 | position: absolute; 78 | top: 0; 79 | width: 100%; 80 | z-index: 1; 81 | } 82 | 83 | &:after { 84 | background: linear-gradient(135deg, _palette(accent1,bg) 0%,_palette(accent2,bg) 74%); 85 | content: ' '; 86 | display: block; 87 | height: 100%; 88 | left: 0; 89 | opacity: 0.6; 90 | position: absolute; 91 | top: 0; 92 | webkit-linear-gradientidth: 100%; 93 | width: 100%; 94 | z-index: 1; 95 | } 96 | 97 | &.small { 98 | height: 30vh !important; 99 | min-height: 30vh; 100 | } 101 | 102 | @include breakpoint('<=large') { 103 | video { 104 | display: none; 105 | } 106 | } 107 | 108 | @include breakpoint('<=small') { 109 | height: auto !important; 110 | min-height: 0; 111 | padding: 4rem 2rem 4rem 2rem; 112 | 113 | .inner { 114 | width: 100%; 115 | } 116 | 117 | h1 { 118 | font-size: 1.75rem; 119 | margin-bottom: 0.5rem; 120 | padding-bottom: 0; 121 | } 122 | 123 | p { 124 | font-size: 1.25rem; 125 | } 126 | 127 | br { 128 | display: none; 129 | } 130 | 131 | .button { 132 | width: 100%; 133 | } 134 | } 135 | 136 | @include breakpoint('<=xsmall') { 137 | p { 138 | font-size: 1rem; 139 | } 140 | } 141 | 142 | body.is-preload & { 143 | .inner { 144 | @include vendor('transform', 'scale(0.99)'); 145 | opacity: 0; 146 | } 147 | 148 | &:before { 149 | opacity: 1; 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_cta.scss: -------------------------------------------------------------------------------- 1 | /* CTA */ 2 | 3 | #cta { 4 | @include color(accent1); 5 | background-attachment: fixed; 6 | background-image: linear-gradient(transparentize(_palette(accent1,bg), 0.75), transparentize(_palette(accent1,bg), 0.75)), url(../../images/cta01.jpg); 7 | background-position: bottom; 8 | background-repeat: no-repeat; 9 | background-size: cover; 10 | position: relative; 11 | text-align: center; 12 | z-index: 1; 13 | 14 | .inner { 15 | position: relative; 16 | z-index: 3; 17 | } 18 | 19 | @include breakpoint('<=medium') { 20 | background-attachment: scroll; 21 | } 22 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_footer.scss: -------------------------------------------------------------------------------- 1 | /* Footer */ 2 | 3 | #footer { 4 | @include color(accent2); 5 | @include padding(8rem, 0); 6 | 7 | a { 8 | color: _palette(accent2, fg); 9 | text-decoration: none; 10 | 11 | &:hover { 12 | color: _palette(accent1, bg); 13 | } 14 | } 15 | 16 | .content { 17 | @include vendor('display', 'flex'); 18 | 19 | section { 20 | width: 25%; 21 | 22 | &:first-child { 23 | width: 50%; 24 | padding-right: _size(element-margin) * 2; 25 | } 26 | 27 | &:last-child { 28 | padding-left: _size(element-margin) * 2; 29 | } 30 | } 31 | } 32 | 33 | .copyright { 34 | border-top: 1px solid; 35 | font-size: 0.8rem; 36 | opacity: 0.5; 37 | padding: _size(element-margin) 0; 38 | text-align: center; 39 | } 40 | 41 | @include breakpoint('<=large') { 42 | @include padding(4rem, 0); 43 | } 44 | 45 | @include breakpoint('<=medium') { 46 | .content { 47 | @include vendor('flex-wrap', 'wrap'); 48 | 49 | section { 50 | width: 50%; 51 | 52 | &:first-child { 53 | width: 100%; 54 | padding-right: 0; 55 | } 56 | } 57 | } 58 | } 59 | 60 | @include breakpoint('<=small') { 61 | @include padding(3rem, 0); 62 | 63 | .content { 64 | section { 65 | width: 100%; 66 | 67 | &:last-child { 68 | padding-left: 0; 69 | } 70 | } 71 | } 72 | } 73 | 74 | @include breakpoint('<=xsmall') { 75 | @include padding(2rem, 0); 76 | } 77 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_header.scss: -------------------------------------------------------------------------------- 1 | /* Header */ 2 | 3 | $accent: accent2; 4 | 5 | body { 6 | 7 | padding-top: _size(header-height); 8 | 9 | &:before { 10 | content: ' '; 11 | background-image: url(../../images/bg.jpg); 12 | background-size: cover; 13 | background-repeat: no-repeat; 14 | background-attachment: fixed; 15 | display: block; 16 | position: fixed; 17 | left: 0; 18 | top: 0; 19 | width: 100%; 20 | height: 100%; 21 | z-index: -1; 22 | opacity: 0.05; 23 | } 24 | } 25 | 26 | #header { 27 | @include vendor('align-items', 'center'); 28 | @include vendor('display', 'flex'); 29 | @include vendor('justify-content', 'space-between'); 30 | background: _palette($accent, bg); 31 | color: _palette($accent, fg); 32 | cursor: default; 33 | height: _size(header-height); 34 | left: 0; 35 | line-height: _size(header-height); 36 | position: fixed; 37 | top: 0; 38 | width: 100%; 39 | z-index: _misc(z-index-base) + 1; 40 | 41 | > .logo { 42 | color: _palette($accent, fg-bold); 43 | font-size: 1rem; 44 | font-weight: _font(weight-bold); 45 | height: inherit; 46 | line-height: inherit; 47 | padding: 0 1.25rem; 48 | text-decoration: none; 49 | } 50 | 51 | > nav { 52 | > a { 53 | color: inherit; 54 | display: inline-block; 55 | padding: 0 0.75rem; 56 | text-decoration: none; 57 | 58 | &:hover { 59 | color: _palette($accent, fg-bold); 60 | } 61 | 62 | &[href="#menu"] { 63 | @include icon; 64 | -webkit-tap-highlight-color: rgba(0,0,0,0); 65 | 66 | &:before { 67 | content: '\f0c9'; 68 | margin: 0 0.5rem 0 0; 69 | } 70 | } 71 | 72 | & + a[href="#menu"]:last-child { 73 | border-left: solid 1px _palette($accent, border); 74 | margin-left: 0.5rem; 75 | padding-left: 1.25rem; 76 | } 77 | 78 | &:last-child { 79 | padding-right: 1.25rem; 80 | } 81 | 82 | @include breakpoint('<=small') { 83 | padding: 0 0.5rem; 84 | 85 | & + a[href="#menu"]:last-child { 86 | margin-left: 0.25rem; 87 | padding-left: 1rem; 88 | } 89 | 90 | &:last-child { 91 | padding-right: 1rem; 92 | } 93 | } 94 | } 95 | } 96 | } 97 | 98 | @include breakpoint('<=medium') { 99 | body { 100 | padding-top: 44px; 101 | } 102 | 103 | #header { 104 | height: 44px; 105 | line-height: 44px; 106 | } 107 | } 108 | 109 | @include breakpoint('<=xsmall') { 110 | #header { 111 | min-width: 320px; 112 | } 113 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_heading.scss: -------------------------------------------------------------------------------- 1 | /* Heading */ 2 | 3 | #heading { 4 | -ms-flex-align: center; 5 | -ms-flex-pack: center; 6 | @include color(accent2); 7 | @include vendor('align-items', 'center'); 8 | @include vendor('display', 'flex'); 9 | @include vendor('justify-content', 'center'); 10 | background-image: linear-gradient(transparentize(_palette(accent2,bg), 0.75), transparentize(_palette(accent2,bg), 0.75)), url('../../images/banner.jpg'); 11 | background-position: center; 12 | background-repeat: no-repeat; 13 | background-size: cover; 14 | border-top: 0; 15 | display: -ms-flexbox; 16 | height: 15rem !important; 17 | min-height: 15rem; 18 | overflow: hidden; 19 | position: relative; 20 | text-align: center; 21 | width: 100%; 22 | 23 | &:before { 24 | background: linear-gradient(135deg, _palette(accent1,bg) 0%,_palette(accent2,bg) 74%); 25 | content: ' '; 26 | display: block; 27 | height: 100%; 28 | left: 0; 29 | opacity: 0.6; 30 | position: absolute; 31 | top: 0; 32 | width: 100%; 33 | z-index: 1; 34 | } 35 | 36 | h1 { 37 | margin-bottom: 0; 38 | position: relative; 39 | z-index: 2; 40 | } 41 | 42 | @include breakpoint('<=medium') { 43 | padding: 2rem; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_main.scss: -------------------------------------------------------------------------------- 1 | /* Main */ 2 | 3 | #main { 4 | .content { 5 | background: _palette(bg); 6 | border-radius: _size(border-radius); 7 | box-shadow: 0px 0px 4px 1px _palette(border-lt); 8 | margin-bottom: _size(element-margin); 9 | padding: 3rem; 10 | 11 | @include breakpoint('<=medium') { 12 | padding: 2rem; 13 | } 14 | 15 | @include breakpoint('<=xsmall') { 16 | padding: 1.5rem; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/layout/_menu.scss: -------------------------------------------------------------------------------- 1 | /* Menu */ 2 | 3 | $accent: accent2; 4 | 5 | #menu { 6 | @include color-typography($accent); 7 | @include color-button($accent); 8 | @include vendor('transform', 'translateX(#{_size(menu-width)})'); 9 | @include vendor('transition', ( 10 | 'transform #{_duration(menu)} ease', 11 | 'box-shadow #{_duration(menu)} ease', 12 | 'visibility #{_duration(menu)}' 13 | )); 14 | -webkit-overflow-scrolling: touch; 15 | box-shadow: none; 16 | height: 100%; 17 | max-width: 80%; 18 | overflow-y: auto; 19 | padding: 3rem 2rem; 20 | position: fixed; 21 | right: 0; 22 | top: 0; 23 | visibility: hidden; 24 | width: _size(menu-width); 25 | z-index: _misc(z-index-base) + 2; 26 | 27 | > ul { 28 | margin: 0 0 (_size(element-margin) * 0.5) 0; 29 | 30 | &.links { 31 | list-style: none; 32 | padding: 0; 33 | 34 | > li { 35 | padding: 0; 36 | 37 | > a { 38 | border: 0; 39 | border-top: solid 1px _palette($accent, border); 40 | color: inherit; 41 | display: block; 42 | letter-spacing: _size(letter-spacing-alt); 43 | line-height: 3.5rem; 44 | text-decoration: none; 45 | 46 | &:hover { 47 | color: _palette($accent, fg-bold); 48 | } 49 | } 50 | 51 | &:first-child { 52 | > a { 53 | border-top: 0; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | .close { 61 | @include icon; 62 | @include vendor('transition', 'color #{_duration(transition)} ease-in-out'); 63 | -webkit-tap-highlight-color: rgba(0,0,0,0); 64 | border: 0; 65 | color: _palette($accent, fg-light); 66 | cursor: pointer; 67 | display: block; 68 | height: 3.25rem; 69 | line-height: 3.25rem; 70 | padding-right: 1.25rem; 71 | position: absolute; 72 | right: 0; 73 | text-align: right; 74 | top: 0; 75 | vertical-align: middle; 76 | width: 7rem; 77 | 78 | &:before { 79 | content: '\f00d'; 80 | font-size: 1.25rem; 81 | } 82 | 83 | &:hover { 84 | color: _palette($accent, fg-bold); 85 | } 86 | 87 | @include breakpoint('<=small') { 88 | height: 4rem; 89 | line-height: 4rem; 90 | } 91 | } 92 | 93 | @include breakpoint('<=small') { 94 | padding: 2.5rem 1.75rem; 95 | } 96 | } 97 | 98 | body.is-menu-visible { 99 | #menu { 100 | @include vendor('transform', 'translateX(0)'); 101 | box-shadow: 0 0 1.5rem 0 rgba(0,0,0,0.2); 102 | visibility: visible; 103 | } 104 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_breakpoints.scss: -------------------------------------------------------------------------------- 1 | // breakpoints.scss v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | // Vars. 4 | 5 | /// Breakpoints. 6 | /// @var {list} 7 | $breakpoints: () !global; 8 | 9 | // Mixins. 10 | 11 | /// Sets breakpoints. 12 | /// @param {map} $x Breakpoints. 13 | @mixin breakpoints($x: ()) { 14 | $breakpoints: $x !global; 15 | } 16 | 17 | /// Wraps @content in a @media block targeting a specific orientation. 18 | /// @param {string} $orientation Orientation. 19 | @mixin orientation($orientation) { 20 | @media screen and (orientation: #{$orientation}) { 21 | @content; 22 | } 23 | } 24 | 25 | /// Wraps @content in a @media block using a given query. 26 | /// @param {string} $query Query. 27 | @mixin breakpoint($query: null) { 28 | 29 | $breakpoint: null; 30 | $op: null; 31 | $media: null; 32 | 33 | // Determine operator, breakpoint. 34 | 35 | // Greater than or equal. 36 | @if (str-slice($query, 0, 2) == '>=') { 37 | 38 | $op: 'gte'; 39 | $breakpoint: str-slice($query, 3); 40 | 41 | } 42 | 43 | // Less than or equal. 44 | @elseif (str-slice($query, 0, 2) == '<=') { 45 | 46 | $op: 'lte'; 47 | $breakpoint: str-slice($query, 3); 48 | 49 | } 50 | 51 | // Greater than. 52 | @elseif (str-slice($query, 0, 1) == '>') { 53 | 54 | $op: 'gt'; 55 | $breakpoint: str-slice($query, 2); 56 | 57 | } 58 | 59 | // Less than. 60 | @elseif (str-slice($query, 0, 1) == '<') { 61 | 62 | $op: 'lt'; 63 | $breakpoint: str-slice($query, 2); 64 | 65 | } 66 | 67 | // Not. 68 | @elseif (str-slice($query, 0, 1) == '!') { 69 | 70 | $op: 'not'; 71 | $breakpoint: str-slice($query, 2); 72 | 73 | } 74 | 75 | // Equal. 76 | @else { 77 | 78 | $op: 'eq'; 79 | $breakpoint: $query; 80 | 81 | } 82 | 83 | // Build media. 84 | @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) { 85 | 86 | $a: map-get($breakpoints, $breakpoint); 87 | 88 | // Range. 89 | @if (type-of($a) == 'list') { 90 | 91 | $x: nth($a, 1); 92 | $y: nth($a, 2); 93 | 94 | // Max only. 95 | @if ($x == null) { 96 | 97 | // Greater than or equal (>= 0 / anything) 98 | @if ($op == 'gte') { 99 | $media: 'screen'; 100 | } 101 | 102 | // Less than or equal (<= y) 103 | @elseif ($op == 'lte') { 104 | $media: 'screen and (max-width: ' + $y + ')'; 105 | } 106 | 107 | // Greater than (> y) 108 | @elseif ($op == 'gt') { 109 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 110 | } 111 | 112 | // Less than (< 0 / invalid) 113 | @elseif ($op == 'lt') { 114 | $media: 'screen and (max-width: -1px)'; 115 | } 116 | 117 | // Not (> y) 118 | @elseif ($op == 'not') { 119 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 120 | } 121 | 122 | // Equal (<= y) 123 | @else { 124 | $media: 'screen and (max-width: ' + $y + ')'; 125 | } 126 | 127 | } 128 | 129 | // Min only. 130 | @else if ($y == null) { 131 | 132 | // Greater than or equal (>= x) 133 | @if ($op == 'gte') { 134 | $media: 'screen and (min-width: ' + $x + ')'; 135 | } 136 | 137 | // Less than or equal (<= inf / anything) 138 | @elseif ($op == 'lte') { 139 | $media: 'screen'; 140 | } 141 | 142 | // Greater than (> inf / invalid) 143 | @elseif ($op == 'gt') { 144 | $media: 'screen and (max-width: -1px)'; 145 | } 146 | 147 | // Less than (< x) 148 | @elseif ($op == 'lt') { 149 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 150 | } 151 | 152 | // Not (< x) 153 | @elseif ($op == 'not') { 154 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 155 | } 156 | 157 | // Equal (>= x) 158 | @else { 159 | $media: 'screen and (min-width: ' + $x + ')'; 160 | } 161 | 162 | } 163 | 164 | // Min and max. 165 | @else { 166 | 167 | // Greater than or equal (>= x) 168 | @if ($op == 'gte') { 169 | $media: 'screen and (min-width: ' + $x + ')'; 170 | } 171 | 172 | // Less than or equal (<= y) 173 | @elseif ($op == 'lte') { 174 | $media: 'screen and (max-width: ' + $y + ')'; 175 | } 176 | 177 | // Greater than (> y) 178 | @elseif ($op == 'gt') { 179 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 180 | } 181 | 182 | // Less than (< x) 183 | @elseif ($op == 'lt') { 184 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 185 | } 186 | 187 | // Not (< x and > y) 188 | @elseif ($op == 'not') { 189 | $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')'; 190 | } 191 | 192 | // Equal (>= x and <= y) 193 | @else { 194 | $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')'; 195 | } 196 | 197 | } 198 | 199 | } 200 | 201 | // String. 202 | @else { 203 | 204 | // Missing a media type? Prefix with "screen". 205 | @if (str-slice($a, 0, 1) == '(') { 206 | $media: 'screen and ' + $a; 207 | } 208 | 209 | // Otherwise, use as-is. 210 | @else { 211 | $media: $a; 212 | } 213 | 214 | } 215 | 216 | } 217 | 218 | // Output. 219 | @media #{$media} { 220 | @content; 221 | } 222 | 223 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_flexgrid.scss: -------------------------------------------------------------------------------- 1 | // flexgrid.scss v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | // Mixins. 4 | 5 | /// Initializes base flexgrid classes. 6 | /// @param {string} $vertical-align Vertical alignment of cells. 7 | /// @param {string} $horizontal-align Horizontal alignment of cells. 8 | @mixin flexgrid-base($vertical-align: null, $horizontal-align: null) { 9 | 10 | // Grid. 11 | @include vendor('display', 'flex'); 12 | @include vendor('flex-wrap', 'wrap'); 13 | 14 | // Vertical alignment. 15 | @if ($vertical-align == top) { 16 | @include vendor('align-items', 'flex-start'); 17 | } 18 | @else if ($vertical-align == bottom) { 19 | @include vendor('align-items', 'flex-end'); 20 | } 21 | @else if ($vertical-align == center) { 22 | @include vendor('align-items', 'center'); 23 | } 24 | @else { 25 | @include vendor('align-items', 'stretch'); 26 | } 27 | 28 | // Horizontal alignment. 29 | @if ($horizontal-align != null) { 30 | text-align: $horizontal-align; 31 | } 32 | 33 | // Cells. 34 | > * { 35 | @include vendor('flex-shrink', '1'); 36 | @include vendor('flex-grow', '0'); 37 | } 38 | 39 | } 40 | 41 | /// Sets up flexgrid columns. 42 | /// @param {integer} $columns Columns. 43 | @mixin flexgrid-columns($columns) { 44 | 45 | > * { 46 | $cell-width: 100% / $columns; 47 | width: #{$cell-width}; 48 | } 49 | 50 | } 51 | 52 | /// Sets up flexgrid gutters. 53 | /// @param {integer} $columns Columns. 54 | /// @param {number} $gutters Gutters. 55 | @mixin flexgrid-gutters($columns, $gutters) { 56 | 57 | // Apply padding. 58 | > * { 59 | $cell-width: 100% / $columns; 60 | 61 | padding: ($gutters * 0.5); 62 | width: $cell-width; 63 | } 64 | 65 | } 66 | 67 | /// Sets up flexgrid gutters (flush). 68 | /// @param {integer} $columns Columns. 69 | /// @param {number} $gutters Gutters. 70 | @mixin flexgrid-gutters-flush($columns, $gutters) { 71 | 72 | // Apply padding. 73 | > * { 74 | $cell-width: 100% / $columns; 75 | $cell-width-pad: $gutters / $columns; 76 | 77 | padding: ($gutters * 0.5); 78 | width: calc(#{$cell-width} + #{$cell-width-pad}); 79 | } 80 | 81 | // Clear top/bottom gutters. 82 | > :nth-child(-n + #{$columns}) { 83 | padding-top: 0; 84 | } 85 | 86 | > :nth-last-child(-n + #{$columns}) { 87 | padding-bottom: 0; 88 | } 89 | 90 | // Clear left/right gutters. 91 | > :nth-child(#{$columns}n + 1) { 92 | padding-left: 0; 93 | } 94 | 95 | > :nth-child(#{$columns}n) { 96 | padding-right: 0; 97 | } 98 | 99 | // Adjust widths of leftmost and rightmost cells. 100 | > :nth-child(#{$columns}n + 1), 101 | > :nth-child(#{$columns}n) { 102 | $cell-width: 100% / $columns; 103 | $cell-width-pad: ($gutters / $columns) - ($gutters / 2); 104 | 105 | width: calc(#{$cell-width} + #{$cell-width-pad}); 106 | } 107 | 108 | } 109 | 110 | /// Reset flexgrid gutters (flush only). 111 | /// Used to override a previous set of flexgrid gutter classes. 112 | /// @param {integer} $columns Columns. 113 | /// @param {number} $gutters Gutters. 114 | /// @param {integer} $prev-columns Previous columns. 115 | @mixin flexgrid-gutters-flush-reset($columns, $gutters, $prev-columns) { 116 | 117 | // Apply padding. 118 | > * { 119 | $cell-width: 100% / $prev-columns; 120 | $cell-width-pad: $gutters / $prev-columns; 121 | 122 | padding: ($gutters * 0.5); 123 | width: calc(#{$cell-width} + #{$cell-width-pad}); 124 | } 125 | 126 | // Clear top/bottom gutters. 127 | > :nth-child(-n + #{$prev-columns}) { 128 | padding-top: ($gutters * 0.5); 129 | } 130 | 131 | > :nth-last-child(-n + #{$prev-columns}) { 132 | padding-bottom: ($gutters * 0.5); 133 | } 134 | 135 | // Clear left/right gutters. 136 | > :nth-child(#{$prev-columns}n + 1) { 137 | padding-left: ($gutters * 0.5); 138 | } 139 | 140 | > :nth-child(#{$prev-columns}n) { 141 | padding-right: ($gutters * 0.5); 142 | } 143 | 144 | // Adjust widths of leftmost and rightmost cells. 145 | > :nth-child(#{$prev-columns}n + 1), 146 | > :nth-child(#{$prev-columns}n) { 147 | $cell-width: 100% / $columns; 148 | $cell-width-pad: $gutters / $columns; 149 | 150 | padding: ($gutters * 0.5); 151 | width: calc(#{$cell-width} + #{$cell-width-pad}); 152 | } 153 | 154 | } 155 | 156 | /// Adds debug styles to current flexgrid element. 157 | @mixin flexgrid-debug() { 158 | 159 | box-shadow: 0 0 0 1px red; 160 | 161 | > * { 162 | box-shadow: inset 0 0 0 1px blue; 163 | position: relative; 164 | 165 | > * { 166 | position: relative; 167 | box-shadow: inset 0 0 0 1px green; 168 | } 169 | } 170 | 171 | } 172 | 173 | /// Initializes the current element as a flexgrid. 174 | /// @param {integer} $columns Columns (optional). 175 | /// @param {number} $gutters Gutters (optional). 176 | /// @param {bool} $flush If true, clears padding around the very edge of the grid. 177 | @mixin flexgrid($settings: ()) { 178 | 179 | // Settings. 180 | 181 | // Debug. 182 | $debug: false; 183 | 184 | @if (map-has-key($settings, 'debug')) { 185 | $debug: map-get($settings, 'debug'); 186 | } 187 | 188 | // Vertical align. 189 | $vertical-align: null; 190 | 191 | @if (map-has-key($settings, 'vertical-align')) { 192 | $vertical-align: map-get($settings, 'vertical-align'); 193 | } 194 | 195 | // Horizontal align. 196 | $horizontal-align: null; 197 | 198 | @if (map-has-key($settings, 'horizontal-align')) { 199 | $horizontal-align: map-get($settings, 'horizontal-align'); 200 | } 201 | 202 | // Columns. 203 | $columns: null; 204 | 205 | @if (map-has-key($settings, 'columns')) { 206 | $columns: map-get($settings, 'columns'); 207 | } 208 | 209 | // Gutters. 210 | $gutters: 0; 211 | 212 | @if (map-has-key($settings, 'gutters')) { 213 | $gutters: map-get($settings, 'gutters'); 214 | } 215 | 216 | // Flush. 217 | $flush: true; 218 | 219 | @if (map-has-key($settings, 'flush')) { 220 | $flush: map-get($settings, 'flush'); 221 | } 222 | 223 | // Initialize base grid. 224 | @include flexgrid-base($vertical-align, $horizontal-align); 225 | 226 | // Debug? 227 | @if ($debug) { 228 | @include flexgrid-debug; 229 | } 230 | 231 | // Columns specified? 232 | @if ($columns != null) { 233 | 234 | // Initialize columns. 235 | @include flexgrid-columns($columns); 236 | 237 | // Gutters specified? 238 | @if ($gutters > 0) { 239 | 240 | // Flush gutters? 241 | @if ($flush) { 242 | 243 | // Initialize gutters (flush). 244 | @include flexgrid-gutters-flush($columns, $gutters); 245 | 246 | } 247 | 248 | // Otherwise ... 249 | @else { 250 | 251 | // Initialize gutters. 252 | @include flexgrid-gutters($columns, $gutters); 253 | 254 | } 255 | 256 | } 257 | 258 | } 259 | 260 | } 261 | 262 | /// Resizes a previously-initialized grid. 263 | /// @param {integer} $columns Columns. 264 | /// @param {number} $gutters Gutters (optional). 265 | /// @param {list} $reset A list of previously-initialized grid columns (only if $flush is true). 266 | /// @param {bool} $flush If true, clears padding around the very edge of the grid. 267 | @mixin flexgrid-resize($settings: ()) { 268 | 269 | // Settings. 270 | 271 | // Columns. 272 | $columns: 1; 273 | 274 | @if (map-has-key($settings, 'columns')) { 275 | $columns: map-get($settings, 'columns'); 276 | } 277 | 278 | // Gutters. 279 | $gutters: 0; 280 | 281 | @if (map-has-key($settings, 'gutters')) { 282 | $gutters: map-get($settings, 'gutters'); 283 | } 284 | 285 | // Previous columns. 286 | $prev-columns: false; 287 | 288 | @if (map-has-key($settings, 'prev-columns')) { 289 | $prev-columns: map-get($settings, 'prev-columns'); 290 | } 291 | 292 | // Flush. 293 | $flush: true; 294 | 295 | @if (map-has-key($settings, 'flush')) { 296 | $flush: map-get($settings, 'flush'); 297 | } 298 | 299 | // Resize columns. 300 | @include flexgrid-columns($columns); 301 | 302 | // Gutters specified? 303 | @if ($gutters > 0) { 304 | 305 | // Flush gutters? 306 | @if ($flush) { 307 | 308 | // Previous columns specified? 309 | @if ($prev-columns) { 310 | 311 | // Convert to list if it isn't one already. 312 | @if (type-of($prev-columns) != list) { 313 | $prev-columns: ($prev-columns); 314 | } 315 | 316 | // Step through list of previous columns and reset them. 317 | @each $x in $prev-columns { 318 | @include flexgrid-gutters-flush-reset($columns, $gutters, $x); 319 | } 320 | 321 | } 322 | 323 | // Resize gutters (flush). 324 | @include flexgrid-gutters-flush($columns, $gutters); 325 | 326 | } 327 | 328 | // Otherwise ... 329 | @else { 330 | 331 | // Resize gutters. 332 | @include flexgrid-gutters($columns, $gutters); 333 | 334 | } 335 | 336 | } 337 | 338 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_functions.scss: -------------------------------------------------------------------------------- 1 | // skel-baseline v3.0.1 | (c) n33 | skel.io | MIT licensed 2 | 3 | /// Removes a specific item from a list. 4 | /// @author Hugo Giraudel 5 | /// @param {list} $list List. 6 | /// @param {integer} $index Index. 7 | /// @return {list} Updated list. 8 | @function remove-nth($list, $index) { 9 | 10 | $result: null; 11 | 12 | @if type-of($index) != number { 13 | @warn "$index: #{quote($index)} is not a number for `remove-nth`."; 14 | } 15 | @else if $index == 0 { 16 | @warn "List index 0 must be a non-zero integer for `remove-nth`."; 17 | } 18 | @else if abs($index) > length($list) { 19 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; 20 | } 21 | @else { 22 | 23 | $result: (); 24 | $index: if($index < 0, length($list) + $index + 1, $index); 25 | 26 | @for $i from 1 through length($list) { 27 | 28 | @if $i != $index { 29 | $result: append($result, nth($list, $i)); 30 | } 31 | 32 | } 33 | 34 | } 35 | 36 | @return $result; 37 | 38 | } 39 | 40 | /// Gets a value from a map. 41 | /// @author Hugo Giraudel 42 | /// @param {map} $map Map. 43 | /// @param {string} $keys Key(s). 44 | /// @return {string} Value. 45 | @function val($map, $keys...) { 46 | 47 | @if nth($keys, 1) == null { 48 | $keys: remove-nth($keys, 1); 49 | } 50 | 51 | @each $key in $keys { 52 | $map: map-get($map, $key); 53 | } 54 | 55 | @return $map; 56 | 57 | } 58 | 59 | /// Gets a duration value. 60 | /// @param {string} $keys Key(s). 61 | /// @return {string} Value. 62 | @function _duration($keys...) { 63 | @return val($duration, $keys...); 64 | } 65 | 66 | /// Gets a font value. 67 | /// @param {string} $keys Key(s). 68 | /// @return {string} Value. 69 | @function _font($keys...) { 70 | @return val($font, $keys...); 71 | } 72 | 73 | /// Gets a misc value. 74 | /// @param {string} $keys Key(s). 75 | /// @return {string} Value. 76 | @function _misc($keys...) { 77 | @return val($misc, $keys...); 78 | } 79 | 80 | /// Gets a palette value. 81 | /// @param {string} $keys Key(s). 82 | /// @return {string} Value. 83 | @function _palette($keys...) { 84 | @return val($palette, $keys...); 85 | } 86 | 87 | /// Gets a size value. 88 | /// @param {string} $keys Key(s). 89 | /// @return {string} Value. 90 | @function _size($keys...) { 91 | @return val($size, $keys...); 92 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_grid.scss: -------------------------------------------------------------------------------- 1 | // grid.scss v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | // Mixins. 4 | 5 | /// Initializes grid classes. 6 | /// @param {mixed} $gutters Gutters (either a single number to set both column/row gutters, or a list to set them individually). 7 | /// @param {string} $suffix Optional column class suffix. 8 | /// @param {list} $override Optional list of column classes to override. 9 | @mixin grid($gutters: 1.5em, $suffix: '', $override: ()) { 10 | 11 | // Initialize. 12 | $cols: 12; 13 | $multipliers: 0, 0.25, 0.5, 1, 1.50, 2.00; 14 | $unit: 100% / $cols; 15 | $suffixes: join($override, ($suffix)); 16 | 17 | // Gutters. 18 | $guttersCols: null; 19 | $guttersRows: null; 20 | 21 | @if (type-of($gutters) == 'list') { 22 | 23 | $guttersCols: nth($gutters, 1); 24 | $guttersRows: nth($gutters, 2); 25 | 26 | } 27 | @else { 28 | 29 | $guttersCols: $gutters; 30 | $guttersRows: 0; 31 | 32 | } 33 | 34 | // Row. 35 | .row { 36 | display: flex; 37 | flex-wrap: wrap; 38 | box-sizing: border-box; 39 | 40 | // Columns. 41 | > * { 42 | box-sizing: border-box; 43 | } 44 | 45 | // Gutters. 46 | &.gtr-uniform { 47 | > * { 48 | > :last-child { 49 | margin-bottom: 0; 50 | } 51 | } 52 | } 53 | 54 | } 55 | 56 | // Step through suffixes. 57 | @each $suffix in $suffixes { 58 | 59 | // Suffix. 60 | @if ($suffix != '') { 61 | $suffix: '-' + $suffix; 62 | } 63 | @else { 64 | $suffix: ''; 65 | } 66 | 67 | // Row. 68 | .row { 69 | 70 | // Important. 71 | > .imp#{$suffix} { 72 | order: -1; 73 | } 74 | 75 | // Columns, offsets. 76 | @for $i from 1 through $cols { 77 | > .col-#{$i}#{$suffix} { 78 | width: $unit * $i; 79 | } 80 | 81 | > .off-#{$i}#{$suffix} { 82 | margin-left: $unit * $i; 83 | } 84 | } 85 | 86 | // Step through multipliers. 87 | @each $multiplier in $multipliers { 88 | 89 | // Gutters. 90 | $class: null; 91 | 92 | @if ($multiplier != 1) { 93 | $class: '.gtr-' + ($multiplier * 100); 94 | } 95 | 96 | &#{$class} { 97 | margin-top: ($guttersRows * $multiplier * -1); 98 | margin-left: ($guttersCols * $multiplier * -1); 99 | 100 | > * { 101 | padding: ($guttersRows * $multiplier) 0 0 ($guttersCols * $multiplier); 102 | } 103 | 104 | // Uniform. 105 | &.gtr-uniform { 106 | margin-top: $guttersCols * $multiplier * -1; 107 | 108 | > * { 109 | padding-top: $guttersCols * $multiplier; 110 | } 111 | } 112 | 113 | } 114 | 115 | } 116 | 117 | } 118 | 119 | } 120 | 121 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_mixins.scss: -------------------------------------------------------------------------------- 1 | /// Makes an element's :before pseudoelement a FontAwesome icon. 2 | /// @param {string} $content Optional content value to use. 3 | /// @param {string} $where Optional pseudoelement to target (before or after). 4 | @mixin icon($content: false, $where: before) { 5 | 6 | text-decoration: none; 7 | 8 | &:#{$where} { 9 | 10 | @if $content { 11 | content: $content; 12 | } 13 | 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-font-smoothing: antialiased; 16 | font-family: FontAwesome; 17 | font-style: normal; 18 | font-weight: normal; 19 | text-transform: none !important; 20 | 21 | } 22 | 23 | } 24 | 25 | /// Applies padding to an element, taking the current element-margin value into account. 26 | /// @param {mixed} $tb Top/bottom padding. 27 | /// @param {mixed} $lr Left/right padding. 28 | /// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left) 29 | /// @param {bool} $important If true, adds !important. 30 | @mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) { 31 | 32 | @if $important { 33 | $important: '!important'; 34 | } 35 | 36 | $x: 0.1em; 37 | 38 | @if unit(_size(element-margin)) == 'rem' { 39 | $x: 0.1rem; 40 | } 41 | 42 | padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important}; 43 | 44 | } 45 | 46 | /// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp). 47 | /// @param {string} $svg SVG data URL. 48 | /// @return {string} Encoded SVG data URL. 49 | @function svg-url($svg) { 50 | 51 | $svg: str-replace($svg, '"', '\''); 52 | $svg: str-replace($svg, '%', '%25'); 53 | $svg: str-replace($svg, '<', '%3C'); 54 | $svg: str-replace($svg, '>', '%3E'); 55 | $svg: str-replace($svg, '&', '%26'); 56 | $svg: str-replace($svg, '#', '%23'); 57 | $svg: str-replace($svg, '{', '%7B'); 58 | $svg: str-replace($svg, '}', '%7D'); 59 | $svg: str-replace($svg, ';', '%3B'); 60 | 61 | @return url("data:image/svg+xml;charset=utf8,#{$svg}"); 62 | 63 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_vars.scss: -------------------------------------------------------------------------------- 1 | // Misc. 2 | $misc: ( 3 | z-index-base: 10000 4 | ); 5 | 6 | // Duration. 7 | $duration: ( 8 | menu: 0.5s, 9 | banner: 1s, 10 | transition: 0.2s 11 | ); 12 | 13 | // Size. 14 | $size: ( 15 | border-radius: 4px, 16 | element-height: 3.25rem, 17 | element-margin: 2rem, 18 | container-width: 80rem, 19 | header-height: 3.25rem, 20 | inner-width: 75rem, 21 | menu-width: 20rem 22 | ); 23 | 24 | // Font. 25 | $font: ( 26 | family: ('Raleway', Arial, Helvetica, sans-serif), 27 | family-fixed: ('Courier New', monospace), 28 | weight: 400, 29 | weight-light: 300, 30 | weight-xlite: 200, 31 | weight-bold: 600 32 | ); 33 | 34 | // Palette. 35 | $palette: ( 36 | bg: #ffffff, 37 | fg: #444444, 38 | fg-bold: #555555, 39 | fg-light: #bbbbbb, 40 | border: rgba(0,0,0,0.25), 41 | border-bg: rgba(0,0,0,0.075), 42 | border-lt: rgba(0,0,0,0.025), 43 | highlight: accent1, 44 | 45 | accent1: ( 46 | bg: #ce1b28, 47 | fg: rgba(255,255,255,0.75), 48 | fg-bold: #ffffff, 49 | fg-light: rgba(255,255,255,0.4), 50 | border: rgba(255,255,255,0.25), 51 | border-bg: rgba(255,255,255,0.075), 52 | border-lt: rgba(255,255,255,0.025), 53 | highlight: accent1 54 | ), 55 | 56 | accent2: ( 57 | bg: #111111, 58 | fg: rgba(255,255,255,0.5), 59 | fg-bold: #ffffff, 60 | fg-light: rgba(255,255,255,0.4), 61 | border: rgba(255,255,255,0.25), 62 | border-bg: rgba(255,255,255,0.075), 63 | border-lt: rgba(255,255,255,0.025), 64 | highlight: accent1 65 | ) 66 | ); -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/libs/_vendor.scss: -------------------------------------------------------------------------------- 1 | // vendor.scss v0.1-dev | @ajlkn | MIT licensed */ 2 | 3 | // Vars. 4 | 5 | /// Vendor prefixes. 6 | /// @var {list} 7 | $vendor-prefixes: ( 8 | '-moz-', 9 | '-webkit-', 10 | '-ms-', 11 | '' 12 | ); 13 | 14 | /// Properties that should be vendorized. 15 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org 16 | /// @var {list} 17 | $vendor-properties: ( 18 | 19 | // Animation. 20 | 'animation', 21 | 'animation-delay', 22 | 'animation-direction', 23 | 'animation-duration', 24 | 'animation-fill-mode', 25 | 'animation-iteration-count', 26 | 'animation-name', 27 | 'animation-play-state', 28 | 'animation-timing-function', 29 | 30 | // Appearance. 31 | 'appearance', 32 | 33 | // Backdrop filter. 34 | 'backdrop-filter', 35 | 36 | // Background image options. 37 | 'background-clip', 38 | 'background-origin', 39 | 'background-size', 40 | 41 | // Box sizing. 42 | 'box-sizing', 43 | 44 | // Clip path. 45 | 'clip-path', 46 | 47 | // Filter effects. 48 | 'filter', 49 | 50 | // Flexbox. 51 | 'align-content', 52 | 'align-items', 53 | 'align-self', 54 | 'flex', 55 | 'flex-basis', 56 | 'flex-direction', 57 | 'flex-flow', 58 | 'flex-grow', 59 | 'flex-shrink', 60 | 'flex-wrap', 61 | 'justify-content', 62 | 'order', 63 | 64 | // Font feature. 65 | 'font-feature-settings', 66 | 'font-language-override', 67 | 'font-variant-ligatures', 68 | 69 | // Font kerning. 70 | 'font-kerning', 71 | 72 | // Fragmented borders and backgrounds. 73 | 'box-decoration-break', 74 | 75 | // Grid layout. 76 | 'grid-column', 77 | 'grid-column-align', 78 | 'grid-column-end', 79 | 'grid-column-start', 80 | 'grid-row', 81 | 'grid-row-align', 82 | 'grid-row-end', 83 | 'grid-row-start', 84 | 'grid-template-columns', 85 | 'grid-template-rows', 86 | 87 | // Hyphens. 88 | 'hyphens', 89 | 'word-break', 90 | 91 | // Masks. 92 | 'mask', 93 | 'mask-border', 94 | 'mask-border-outset', 95 | 'mask-border-repeat', 96 | 'mask-border-slice', 97 | 'mask-border-source', 98 | 'mask-border-width', 99 | 'mask-clip', 100 | 'mask-composite', 101 | 'mask-image', 102 | 'mask-origin', 103 | 'mask-position', 104 | 'mask-repeat', 105 | 'mask-size', 106 | 107 | // Multicolumn. 108 | 'break-after', 109 | 'break-before', 110 | 'break-inside', 111 | 'column-count', 112 | 'column-fill', 113 | 'column-gap', 114 | 'column-rule', 115 | 'column-rule-color', 116 | 'column-rule-style', 117 | 'column-rule-width', 118 | 'column-span', 119 | 'column-width', 120 | 'columns', 121 | 122 | // Object fit. 123 | 'object-fit', 124 | 'object-position', 125 | 126 | // Regions. 127 | 'flow-from', 128 | 'flow-into', 129 | 'region-fragment', 130 | 131 | // Scroll snap points. 132 | 'scroll-snap-coordinate', 133 | 'scroll-snap-destination', 134 | 'scroll-snap-points-x', 135 | 'scroll-snap-points-y', 136 | 'scroll-snap-type', 137 | 138 | // Shapes. 139 | 'shape-image-threshold', 140 | 'shape-margin', 141 | 'shape-outside', 142 | 143 | // Tab size. 144 | 'tab-size', 145 | 146 | // Text align last. 147 | 'text-align-last', 148 | 149 | // Text decoration. 150 | 'text-decoration-color', 151 | 'text-decoration-line', 152 | 'text-decoration-skip', 153 | 'text-decoration-style', 154 | 155 | // Text emphasis. 156 | 'text-emphasis', 157 | 'text-emphasis-color', 158 | 'text-emphasis-position', 159 | 'text-emphasis-style', 160 | 161 | // Text size adjust. 162 | 'text-size-adjust', 163 | 164 | // Text spacing. 165 | 'text-spacing', 166 | 167 | // Transform. 168 | 'transform', 169 | 'transform-origin', 170 | 171 | // Transform 3D. 172 | 'backface-visibility', 173 | 'perspective', 174 | 'perspective-origin', 175 | 'transform-style', 176 | 177 | // Transition. 178 | 'transition', 179 | 'transition-delay', 180 | 'transition-duration', 181 | 'transition-property', 182 | 'transition-timing-function', 183 | 184 | // Unicode bidi. 185 | 'unicode-bidi', 186 | 187 | // User select. 188 | 'user-select', 189 | 190 | // Writing mode. 191 | 'writing-mode', 192 | 193 | ); 194 | 195 | /// Values that should be vendorized. 196 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org 197 | /// @var {list} 198 | $vendor-values: ( 199 | 200 | // Cross fade. 201 | 'cross-fade', 202 | 203 | // Element function. 204 | 'element', 205 | 206 | // Filter function. 207 | 'filter', 208 | 209 | // Flexbox. 210 | 'flex', 211 | 'inline-flex', 212 | 213 | // Grab cursors. 214 | 'grab', 215 | 'grabbing', 216 | 217 | // Gradients. 218 | 'linear-gradient', 219 | 'repeating-linear-gradient', 220 | 'radial-gradient', 221 | 'repeating-radial-gradient', 222 | 223 | // Grid layout. 224 | 'grid', 225 | 'inline-grid', 226 | 227 | // Image set. 228 | 'image-set', 229 | 230 | // Intrinsic width. 231 | 'max-content', 232 | 'min-content', 233 | 'fit-content', 234 | 'fill', 235 | 'fill-available', 236 | 'stretch', 237 | 238 | // Sticky position. 239 | 'sticky', 240 | 241 | // Transform. 242 | 'transform', 243 | 244 | // Zoom cursors. 245 | 'zoom-in', 246 | 'zoom-out', 247 | 248 | ); 249 | 250 | // Functions. 251 | 252 | /// Removes a specific item from a list. 253 | /// @author Hugo Giraudel 254 | /// @param {list} $list List. 255 | /// @param {integer} $index Index. 256 | /// @return {list} Updated list. 257 | @function remove-nth($list, $index) { 258 | 259 | $result: null; 260 | 261 | @if type-of($index) != number { 262 | @warn "$index: #{quote($index)} is not a number for `remove-nth`."; 263 | } 264 | @else if $index == 0 { 265 | @warn "List index 0 must be a non-zero integer for `remove-nth`."; 266 | } 267 | @else if abs($index) > length($list) { 268 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; 269 | } 270 | @else { 271 | 272 | $result: (); 273 | $index: if($index < 0, length($list) + $index + 1, $index); 274 | 275 | @for $i from 1 through length($list) { 276 | 277 | @if $i != $index { 278 | $result: append($result, nth($list, $i)); 279 | } 280 | 281 | } 282 | 283 | } 284 | 285 | @return $result; 286 | 287 | } 288 | 289 | /// Replaces a substring within another string. 290 | /// @author Hugo Giraudel 291 | /// @param {string} $string String. 292 | /// @param {string} $search Substring. 293 | /// @param {string} $replace Replacement. 294 | /// @return {string} Updated string. 295 | @function str-replace($string, $search, $replace: '') { 296 | 297 | $index: str-index($string, $search); 298 | 299 | @if $index { 300 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); 301 | } 302 | 303 | @return $string; 304 | 305 | } 306 | 307 | /// Replaces a substring within each string in a list. 308 | /// @param {list} $strings List of strings. 309 | /// @param {string} $search Substring. 310 | /// @param {string} $replace Replacement. 311 | /// @return {list} Updated list of strings. 312 | @function str-replace-all($strings, $search, $replace: '') { 313 | 314 | @each $string in $strings { 315 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace)); 316 | } 317 | 318 | @return $strings; 319 | 320 | } 321 | 322 | // Mixins. 323 | 324 | /// Wraps @content in vendorized keyframe blocks. 325 | /// @param {string} $name Name. 326 | @mixin keyframes($name) { 327 | 328 | @-moz-keyframes #{$name} { @content; } 329 | @-webkit-keyframes #{$name} { @content; } 330 | @-ms-keyframes #{$name} { @content; } 331 | @keyframes #{$name} { @content; } 332 | 333 | } 334 | 335 | /// Vendorizes a declaration's property and/or value(s). 336 | /// @param {string} $property Property. 337 | /// @param {mixed} $value String/list of value(s). 338 | @mixin vendor($property, $value) { 339 | 340 | // Determine if property should expand. 341 | $expandProperty: index($vendor-properties, $property); 342 | 343 | // Determine if value should expand (and if so, add '-prefix-' placeholder). 344 | $expandValue: false; 345 | 346 | @each $x in $value { 347 | @each $y in $vendor-values { 348 | @if $y == str-slice($x, 1, str-length($y)) { 349 | 350 | $value: set-nth($value, index($value, $x), '-prefix-' + $x); 351 | $expandValue: true; 352 | 353 | } 354 | } 355 | } 356 | 357 | // Expand property? 358 | @if $expandProperty { 359 | @each $vendor in $vendor-prefixes { 360 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 361 | } 362 | } 363 | 364 | // Expand just the value? 365 | @elseif $expandValue { 366 | @each $vendor in $vendor-prefixes { 367 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 368 | } 369 | } 370 | 371 | // Neither? Treat them as a normal declaration. 372 | @else { 373 | #{$property}: #{$value}; 374 | } 375 | 376 | } -------------------------------------------------------------------------------- /13_http_serve_static_html/static/assets/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import 'libs/vars'; 2 | @import 'libs/functions'; 3 | @import 'libs/mixins'; 4 | @import 'libs/vendor'; 5 | @import 'libs/breakpoints'; 6 | @import 'libs/grid'; 7 | @import 'libs/flexgrid'; 8 | @import 'font-awesome.min.css'; 9 | @import url('https://fonts.googleapis.com/css?family=Raleway:200,300,400,500,600'); 10 | 11 | /* 12 | Industrious by TEMPLATED 13 | templated.co @templatedco 14 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 15 | */ 16 | 17 | // Breakpoints. 18 | @include breakpoints(( 19 | default: (1681px, null ), 20 | xlarge: (1281px, 1680px ), 21 | large: (981px, 1280px ), 22 | medium: (737px, 980px ), 23 | small: (481px, 736px ), 24 | xsmall: (361px, 480px ), 25 | xxsmall: (null, 360px ) 26 | )); 27 | 28 | // Color. 29 | @mixin color($p) { 30 | @include color-typography($p); 31 | @include color-button($p); 32 | @include color-form($p); 33 | @include color-list($p); 34 | @include color-table($p); 35 | @include color-highlights($p); 36 | @include color-testimonials($p); 37 | } 38 | 39 | // Base. 40 | @import 'base/page'; 41 | @import 'base/reset'; 42 | @import 'base/typography'; 43 | 44 | // Component. 45 | @import 'components/inner'; 46 | @import 'components/button'; 47 | @import 'components/form'; 48 | @import 'components/list'; 49 | @import 'components/table'; 50 | @import 'components/highlights'; 51 | @import 'components/testimonials'; 52 | @import 'components/actions'; 53 | @import 'components/grid'; 54 | @import 'components/icon'; 55 | @import 'components/icons'; 56 | @import 'components/image'; 57 | @import 'components/wrapper'; 58 | 59 | // Layout. 60 | @import 'layout/banner'; 61 | @import 'layout/cta'; 62 | @import 'layout/footer'; 63 | @import 'layout/header'; 64 | @import 'layout/heading'; 65 | @import 'layout/main'; 66 | @import 'layout/menu'; -------------------------------------------------------------------------------- /13_http_serve_static_html/static/generic.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Generic Page - Industrious by TEMPLATED 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 34 | 35 | 36 |
37 |

Generic Page

38 |
39 | 40 | 41 |
42 |
43 |
44 |
45 |

Feugiat consequat

46 |
47 |

Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Magna et cursus lorem faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod tempus. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac sed amet praesent. Nunc lacinia ante nunc ac gravida lorem ipsum dolor sit amet dolor feugiat consequat.

48 |

Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Magna et cursus lorem faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod tempus. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac sed amet praesent. Nunc lacinia ante nunc ac gravida lorem ipsum dolor sit amet dolor feugiat consequat.

49 |
50 |

Magna odio tempus commodo

51 |

In arcu accumsan arcu adipiscing accumsan orci ac. Felis id enim aliquet. Accumsan ac integer lobortis commodo ornare aliquet accumsan erat tempus amet porttitor. Ante commodo blandit adipiscing integer semper orci eget. Faucibus commodo adipiscing mi eu nullam accumsan morbi arcu ornare odio mi adipiscing nascetur lacus ac interdum morbi accumsan vis mi accumsan ac praesent.

52 |

Felis sagittis eget tempus primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Magna sed etiam ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus lorem ipsum dolor sit amet nullam.

53 |
54 |
55 |
56 | 57 | 58 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/banner.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/banner.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/banner.mp4 -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/bg.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/cta01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/cta01.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/pic01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/pic01.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/pic02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/pic02.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/images/pic03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/13_http_serve_static_html/static/images/pic03.jpg -------------------------------------------------------------------------------- /13_http_serve_static_html/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Industrious by TEMPLATED 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 34 | 35 | 36 | 44 | 45 | 46 |
47 |
48 |
49 |

Sem turpis amet semper

50 |

In arcu accumsan arcu adipiscing accumsan orci ac. Felis id enim aliquet. Accumsan ac integer lobortis commodo ornare aliquet accumsan erat tempus amet porttitor.

51 |
52 |
53 |
54 |
55 |
56 | Icon 57 |

Feugiat consequat

58 |
59 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

60 |
61 |
62 |
63 |
64 |
65 | Icon 66 |

Ante sem integer

67 |
68 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

69 |
70 |
71 |
72 |
73 |
74 | Icon 75 |

Ipsum consequat

76 |
77 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

78 |
79 |
80 |
81 |
82 |
83 | Icon 84 |

Interdum gravida

85 |
86 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

87 |
88 |
89 |
90 |
91 |
92 | Icon 93 |

Faucibus consequat

94 |
95 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

96 |
97 |
98 |
99 |
100 |
101 | Icon 102 |

Accumsan viverra

103 |
104 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

105 |
106 |
107 |
108 |
109 |
110 | 111 | 112 |
113 |
114 |

Curabitur ullamcorper ultricies

115 |

Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing. Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing sed feugiat eu faucibus. Integer ac sed amet praesent. Nunc lacinia ante nunc ac gravida.

116 |
117 |
118 | 119 | 120 |
121 |
122 |
123 |

Faucibus consequat lorem

124 |

In arcu accumsan arcu adipiscing accumsan orci ac. Felis id enim aliquet. Accumsan ac integer lobortis commodo ornare aliquet accumsan erat tempus amet porttitor.

125 |
126 |
127 |
128 |
129 |
130 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

131 |
132 |
133 |
134 | 135 |
136 |

- Jane Doe CEO - ABC Inc.

137 |
138 |
139 |
140 |
141 |
142 |
143 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

144 |
145 |
146 |
147 | 148 |
149 |

- John Doe CEO - ABC Inc.

150 |
151 |
152 |
153 |
154 |
155 |
156 |

Nunc lacinia ante nunc ac lobortis ipsum. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus.

157 |
158 |
159 |
160 | 161 |
162 |

- Janet Smith CEO - ABC Inc.

163 |
164 |
165 |
166 |
167 |
168 |
169 | 170 | 171 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /14_go_routines/go_routines.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // GO ROUTINES 9 | 10 | /* 11 | Ένας διακομιστής ιστοσελίδων λαμβάνει αιτήσεις που υποβάλλονται από προγράμματα 12 | περιήγησης των χρηστών στο διαδίκτυο και παρέχει HTML ιστοσελίδες ως απάντηση. 13 | Κάθε αίτημα λαμβάνεται σαν ένα μικρό πρόγραμμα. 14 | 15 | Θα ήταν ιδανικό για προγράμματα όπως αυτά να είναι σε θέση να τρέξουν μικρότερα 16 | στοιχεία τους την ίδια χρονική στιγμή (στην περίπτωση του διακομιστή ιστοσελίδων 17 | να λαμβάνει πολλαπλές αιτήσεις).Η επίτευξη προόδου σε περισσότερες από μία 18 | εργασίες ταυτόχρονα είναι γνωστό ως ταυτοχρονισμός. Η Go έχει εγγενής υποστήριξη 19 | για τον ταυτοχρονισμό (concurency) χρησιμοποιώντας go-ρουτίνες και κανάλια channels 20 | 21 | */ 22 | 23 | // Φτιάχνουμε μια ρουτίνα εργασίας που μετράει απο το 0 έως το 10 24 | func count(id int) { 25 | for i := 0; i < 10; i++ { 26 | fmt.Println(id, ":", i) 27 | 28 | // Παύση της λειτουργίας για 1 δευτερόλεπτο για να επιτραπεί 29 | // η εκτέλεση άλλων λειτουργιών 30 | time.Sleep(time.Millisecond * 1000) 31 | } 32 | } 33 | 34 | func main() { 35 | 36 | // Μια go ρουτίνα είναι μια func που τρέχει ταυτόχρονα με άλλες func 37 | // Ορίζουμε παρακάτω μια τέτοια, χρησιμοποιώντας την λέξη κλειδί "go" 38 | // ακολουθούμενη από το όνομα της func που θα τρέξει. 39 | // Εδω λοιπόν η go-ρουτίνα είναι μία συνάρτηση που είναι ικανή να εκτελεί 40 | // ταυτόχρονα και άλλες συναρτήσεις (την count(i)). 41 | 42 | for i := 0; i < 10; i++ { 43 | go count(i) 44 | } 45 | 46 | // Ας προσθέσουμε κάποια καθυστέρηση στη συνάρτηση με το time.Sleep 47 | // για να βεβαιωθούμε ότι η go ρουτίνα έχει χρόνο για να τελειώσει, 48 | // ειδάλλως το πρόγραμμα θα τελειώσει πριν συμβεί αυτό 49 | time.Sleep(time.Millisecond * 11000) 50 | } 51 | 52 | // Σημείωση: Όταν τρέξετε το πρόγραμμα η count εμφανίζει τους αριθμούς από 0 έως 10, με αναμονή 1 δευτερολέπτου μετά 53 | // από κάθε εκτέλεση. Η go-ρουτίνα με αυτό τον τρόπο εκτελείται ταυτόχρονα. 54 | -------------------------------------------------------------------------------- /15_go_channels/go_channels-ping-pong.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // CHANNELS 9 | /* 10 | Τα κανάλια παρέχουν έναν τρόπο για δύο go-routines να επικοινωνούν μεταξύ τους 11 | ώστε να στέλνουν δεδομένα τους αμφότερα και να συγχρονίζουν την εκτέλεσή τους. 12 | */ 13 | 14 | /* 15 | Αυτό το πρόγραμμα θα εκτυπώνει "ping", "pong" για πάντα (πατήστε enter για να 16 | σταματήσει). Ένας τύπος κανάλι (type chanel) εκπροσωπείται με την λέξη-κλειδί chan που 17 | ακολουθείται από τον τύπο των πραγμάτων που έχουν εισαχθεί στο κανάλι (στην παρακάτω 18 | περίπτωση εισάγαμε string). 19 | Ο τελεστής <- (αριστερό βέλος) χρησιμοποιείται για την αποστολή και λήψη 20 | μηνυμάτων στο κανάλι. 21 | 22 | */ 23 | 24 | // Δημιουργούμε δυο funcs "ping" και "pong" κανάλια που θα προβάλλονται ασταμάτητα 25 | 26 | func pinger(c chan string) { 27 | for i := 0; ; i++ { 28 | c <- "ping" // σημαίνει αποστολή "ping" στο κανάλι c. 29 | } 30 | } 31 | 32 | func ponger(c chan string) { 33 | for i := 0; ; i++ { 34 | c <- "pong" // σημαίνει αποστολή "pong" στο κανάλι c 35 | } 36 | } 37 | 38 | // Δημιουργούμε μια func "printer" κανάλι που θα προβάλει τα ping/pong ανα 1 δευτερόλεπτο 39 | 40 | func printer(c chan string) { 41 | for { // Βλέπουμε οτι η for εδω θα εκτελείται για πάντα μέχρι να πατήσουμε 42 | // enter στο πληκτρολόγιο 43 | msg := <-c // msg := <- c σημαίνει λήψη ενός μηνύματος απο το κανάλι c 44 | // και αποθήκευση του στην μεταβλητή msg 45 | fmt.Println(msg) // Η fmt γραμμή θα μπορούσε επίσης να έχει γραφτεί 46 | // όπως αυτό: fmt.Println(<-c) οπότε θα μπορούσαμε να 47 | // καταργήσουμε την γραμμή msg := <-c 48 | time.Sleep(time.Second * 1) 49 | } 50 | } 51 | 52 | /* 53 | Χρησιμοποιώντας ένα κανάλι σαν αυτό συγχρονίζουμε τις go-ρουτίνες. Όταν ο 54 | pinger και ο ponger προσπαθούν να στείλουν ένα μήνυμα στο κανάλι, θα περιμένουν μέχρι ο printer να 55 | είναι έτοιμος να λάβει το μήνυμα. (αυτό είναι γνωστό ως blocking) 56 | */ 57 | 58 | func main() { 59 | // Η make δημιουργεί το κανάλι c που μπορεί να κρατήσει μια συμβολοσειρά 60 | // int κανάλι intChan: = make (chan int) 61 | var c chan string = make(chan string) 62 | 63 | go pinger(c) 64 | go ponger(c) 65 | go printer(c) 66 | 67 | var input string 68 | fmt.Scanln(&input) // πατάμε enter στο πληκτρολόγιο για να σταματήσει το πρόγραμμα 69 | 70 | } 71 | 72 | /* 73 | Σημείωση: Κατεύθυνση καναλιού 74 | 75 | Μπορούμε να καθορίσουμε μια κατεύθυνση σε έναν τύπο καναλιού περιορίζοντάς 76 | τον έτσι ώστε να κάνει αποστολή ή λήψη. Για παράδειγμα η συνάρτηση pinger 77 | μπορεί να αλλάξει σε αυτό: 78 | 79 | func pinger(c chan<- string) 80 | 81 | Τώρα το c μπορεί μόνο να αποσταλεί. Προσπαθώντας να λάβει από to c θα οδηγήσει 82 | σε ένα σφάλμα μεταγλώττισης. Ομοίως μπορούμε να αλλάξουμε την συνάρτηση 83 | printer σε αυτό: 84 | 85 | func printer(c <-chan string) 86 | 87 | Ένα κανάλι που δεν έχει αυτούς τους περιορισμούς είναι γνωστό ως διπλής 88 | κατεύθυνσης. Ένα κανάλι διπλής κατεύθυνσης μπορεί να περάσει σε μια συνάρτηση 89 | η οποία παίρνει κανάλια που μόνο στέλνουν ή μόνο λαμβάνουν, αλλά το αντίστροφο 90 | δεν ισχύει 91 | 92 | */ 93 | -------------------------------------------------------------------------------- /16_go_select_buffered/go_select_buffered.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | /* 9 | 10 | Όταν θέλουμε να έχουμε περιπτώσεις επιλογών σε go routines η Go έχει μια ειδική 11 | εντολή που ονομάζεται "select" η οποία λειτουργεί σαν την switch 12 | αλλά για τα κανάλια 13 | 14 | Το παρακάτω πρόγραμμα εμφανίζει "Από 1" και "Απο 3". Η select 15 | παίρνει το πρώτο κανάλι που είναι έτοιμο και λαμβάνει από αυτό δεδομένα 16 | (ή στέλνει σε αυτό). Αν περισσότερα από ένα κανάλια είναι έτοιμα 17 | τότε επιλέγει τυχαία ένα από το οποίο θα λαμβάνει. Εάν κανένα 18 | από τα κανάλια δεν είναι έτοιμο, τότε η διαδικασία σταματάει μέχρι 19 | κάποιο να γίνει διαθέσιμο. 20 | 21 | */ 22 | 23 | func main() { 24 | 25 | c1 := make(chan string, 1) 26 | c2 := make(chan string, 3) 27 | /* 28 | Είναι επίσης δυνατόν να περάσουμε μια δεύτερη παράμετρο στη 29 | συνάρτηση make, που είδαμε όταν δημιουργούμε ένα κανάλι 30 | Το πρώτο δημιουργεί ένα buffered κανάλι με χωρητικότητα 1 και το δεύτερο 31 | με χωρητικότητα 3. 32 | Κανονικά τα κανάλια είναι συγχρονισμένα δηλαδή οι δύο πλευρές του 33 | καναλιού θα περιμένουν έως ότου η άλλη πλευρά να είναι έτοιμη. 34 | Ένα buffered κανάλι απο την άλλη, είναι ασύγχρονο δηλαδή στην αποστολή 35 | ή στη λήψη ενός μηνύματος δεν θα περιμένει, εκτός αν το κανάλι 36 | είναι ήδη πλήρες. 37 | */ 38 | 39 | go func() { 40 | for { 41 | c1 <- "Απο 1" 42 | time.Sleep(time.Second * 1) 43 | } 44 | }() 45 | 46 | go func() { 47 | for { 48 | c2 <- "Απο 3" 49 | time.Sleep(time.Second * 3) 50 | 51 | } 52 | }() 53 | 54 | go func() { 55 | for { 56 | select { 57 | case msg1 := <-c1: 58 | fmt.Println("Είσαι καλά;", msg1) 59 | case msg2 := <-c2: 60 | fmt.Println("Είμαι μια χαρά", msg2) 61 | /* Η εντολή select χρησιμοποιείται συχνά για 62 | να εφαρμόσει ένα timeout. 63 | Το time.After δημιουργεί ένα κανάλι και μετά τη δοθείσα 64 | διάρκεια, θα στείλει τον τρέχον χρόνο σε αυτό. 65 | (εμείς δεν ενδιαφερόμαστε για το χρόνο γιαυτό δεν τον 66 | αποθηκεύουμε σε μια μεταβλητή)*/ 67 | case <-time.After(time.Second): 68 | fmt.Println("Λήξη χρόνου") 69 | default: // Η default case θα συμβεί αμέσως αν 70 | // κανένα από τα κανάλια δεν είναι έτοιμα. 71 | fmt.Println("Κανένα έτοιμο") 72 | //time.Sleep(time.Millisecond * 11000) 73 | } 74 | time.Sleep(time.Millisecond * 11000) 75 | } 76 | }() 77 | 78 | var input string 79 | fmt.Scanln(&input) // Περιμένει να πατήσουμε ENTER για να τερματίσει το πρόγραμμα 80 | } 81 | -------------------------------------------------------------------------------- /17_open_create_read_files/files/cerebrux.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CerebruxCode/Go/664bf107ee7cfcf85a75ba280e525e6277df7b7f/17_open_create_read_files/files/cerebrux.pdf -------------------------------------------------------------------------------- /17_open_create_read_files/files/edit.txt: -------------------------------------------------------------------------------- 1 | Αυτό είναι ένα τυχαίο κείμενο -------------------------------------------------------------------------------- /17_open_create_read_files/files/greece_covid19.csv: -------------------------------------------------------------------------------- 1 | date,people_fully_vaccinated,total_vaccinations,location 2 | 2020-12-31,0,2339,Greece 3 | 2021-01-30,38888,271287,Greece 4 | 2021-02-27,313647,885821,Greece 5 | 2021-03-31,607167,1699807,Greece 6 | 2021-04-30,944123,3097693,Greece 7 | 2021-05-31,2058287,5597624,Greece 8 | 2021-06-30,3788906,8391535,Greece 9 | 2021-07-31,5165666,10536457,Greece 10 | 2021-08-31,5738106,11408609,Greece 11 | 2021-09-30,6124452,12133980,Greece 12 | 2021-10-26,6350932,12603840,Greece 13 | -------------------------------------------------------------------------------- /17_open_create_read_files/files/problems.csv: -------------------------------------------------------------------------------- 1 | 5+2,7 2 | 1+1,2 3 | 8+1,9 4 | 1+2,3 5 | 8+5,13 6 | 3-1,2 7 | 1+4,5 8 | 5+1,6 9 | 2+3,5 10 | 3+3,6 11 | 2+4,6 12 | 5-2,3 13 | -------------------------------------------------------------------------------- /17_open_create_read_files/files/sample.txt: -------------------------------------------------------------------------------- 1 | Ἄνδρα μοι ἔννεπε, Μοῦσα, πολύτροπον, ὃς μάλα πολλὰ 2 | πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσε· 3 | πολλῶν δ’ ἀνθρώπων ἴδεν ἄστεα καὶ νόον ἔγνω, 4 | πολλὰ δ’ ὅ γ’ ἐν πόντῳ πάθεν ἄλγεα ὃν κατὰ θυμόν, 5 | ἀρνύμενος ἥν τε ψυχὴν καὶ νόστον ἑταίρων. 6 | ἀλλ' οὐδ' ὧς ἑτάρους ἐρρύσατο, ἱέμενός περ· 7 | αὐτῶν γὰρ σφετέρῃσιν ἀτασθαλίῃσιν ὄλοντο, 8 | νήπιοι, οἳ κατὰ βοῦς Ὑπερίονος Ἠελίοιο 9 | ἤσθιον· αὐτὰρ ὁ τοῖσιν ἀφείλετο νόστιμον ἦμαρ. 10 | τῶν ἁμόθεν γε, θεά, θύγατερ Διός, εἰπὲ καὶ ἡμῖν. α 10 11 | ἔνθ' ἄλλοι μὲν πάντες, ὅσοι φύγον αἰπὺν ὄλεθρον, 12 | οἴκοι ἔσαν, πόλεμόν τε πεφευγότες ἠδὲ θάλασσαν· 13 | τὸν δ' οἶον, νόστου κεχρημένον ἠδὲ γυναικός, 14 | νύμφη πότνι' ἔρυκε Καλυψώ, δῖα θεάων, 15 | ἐν σπέεσι γλαφυροῖσι, λιλαιομένη πόσιν εἶναι. 16 | ἀλλ' ὅτε δὴ ἔτος ἦλθε περιπλομένων ἐνιαυτῶν, 17 | τῷ οἱ ἐπεκλώσαντο θεοὶ οἶκόνδε νέεσθαι 18 | εἰς Ἰθάκην, οὐδ' ἔνθα πεφυγμένος ἦεν ἀέθλων 19 | καὶ μετὰ οἷσι φίλοισι· θεοὶ δ' ἐλέαιρον ἅπαντες 20 | νόσφι Ποσειδάωνος· -------------------------------------------------------------------------------- /17_open_create_read_files/files/yunus.txt: -------------------------------------------------------------------------------- 1 | Γιουνούς Εμρέ είναι το όνομά μου 2 | Η φωτιά μου μεγαλώνει μέρα με τη μέρα 3 | Στους δύο κόσμους, ο στόχος μου είναι τούτος 4 | Εσενα είναι που χρειάζομαι, Εσένα. 5 | 6 | Εγώ περπατώ και καίγομαι, 7 | μέσα στο αίμα μ’ έβαψε η αγάπη, 8 | μου ’μεινε και δε μου ’μεινε μυαλό, 9 | έλα να δεις πως μ’ έκανε η αγάπη -------------------------------------------------------------------------------- /17_open_create_read_files/open_create_read_files.go: -------------------------------------------------------------------------------- 1 | /* 2 | Τι θα μάθουμε: 3 | - Να ανοίγουμε αρχεία txt, csv, pdf 4 | - Το workflow στην διαχείριση των αρχείων 5 | - Τα πακέτα που μας παρέχουν λειτουργίες 6 | διαχείρισης αρχείων 7 | */ 8 | 9 | package main 10 | 11 | import ( 12 | "bufio" 13 | "encoding/csv" 14 | "fmt" 15 | "io" 16 | "io/ioutil" 17 | "log" 18 | "os" 19 | 20 | "github.com/go-gota/gota/dataframe" 21 | "rsc.io/pdf" 22 | ) 23 | 24 | func main() { 25 | // FILE I/O 26 | /* 27 | Η μεθοδολογία διαχείρισης αρχείων ακολουθεί τα παρακάτω βήματα: 28 | - Ανοίγω το αρχείο 29 | - Αναλύω / Επεξεργάζομαι (parse/process) 30 | - Κλείνω το αρχείο (στις περισσότερες των περιπτώσεων) 31 | 32 | Τα πακέτα που χρησιμοποιούνται συνήθως είναι : 33 | - io/ioutil 34 | - os 35 | - bufio 36 | - encoding/csv 37 | - rsc.io/pdf 38 | - etc 39 | 40 | */ 41 | 42 | /*== Πρώτη μέθοδος ανοίγματος αρχείου == 43 | <= Βήμα 1: Άνοιγμα αρχείου >= 44 | 45 | Με την ioutil. συνηθίζεται να ανοίγουμε αρχεία 46 | με λίγα δεδομένα 47 | 48 | Η πρότυπη βιβλιοθήκη "io" της Go περιλαμβάνει 49 | πολλές υλοποιήσεις των διεπαφών διαχείρισης 50 | αρχείων για εισαγωγή και εγγραφή δεδομένων, 51 | συνδέσεων δικτύου, συμπιεστών, κρυπτογράφησης και άλλων. 52 | 53 | */ 54 | 55 | // Προσπάθησε να ανοίξεις το αρχείο. 56 | content, err := ioutil.ReadFile("files/yunus.txt") 57 | if err != nil { // Αν δεν το καταφέρεις πρόβαλε το σφάλμα 58 | log.Fatal(err) 59 | } 60 | // <= Βήμα 2: Parse/Process αρχείου >= 61 | 62 | // Μετατρέψτε το περιεχόμενο σε μια συμβολοσειρά 63 | // διότι η ioutil ανοίγει το αρχείο σε byte format 64 | // Δοκίμασε να αφαιρέσεις την μετατροπή string() 65 | 66 | fmt.Printf("\n\n== Πρώτη μέθοδος ανοίγματος αρχείου ==\n\n") 67 | fmt.Println(string(content)) 68 | 69 | /*== Δεύτερη μέθοδος ανοίγματος αρχείων == 70 | <= Βήμα 1: Άνοιγμα αρχείου >= 71 | 72 | Με την os.* συχνά να χρησιμοποιείται σε 73 | μεγάλα αρχεία. 74 | 75 | */ 76 | f, err := os.Open("files/sample.txt") 77 | if err != nil { // Αν δεν το καταφέρεις πρόβαλε το σφάλμα 78 | log.Fatal(err) 79 | } 80 | defer f.Close() // με την os.Open πρέπει να έχουμε 81 | // το κλείσιμο του αρχείου σε αναμονή 82 | 83 | // <= Βήμα 2: Parse/Process αρχείου >= 84 | 85 | // με την os. πρέπει να φτιάξουμε και σαρωτή του 86 | // περιεχομένου πριν την ανάγνωση 87 | scanner := bufio.NewScanner(f) 88 | fmt.Printf("\n\n== Δεύτερη μέθοδος ανοίγματος αρχείου ==\n\n") 89 | for scanner.Scan() { // σαρώνει κάθε γραμμη 90 | fmt.Println(scanner.Text()) // τυπώνει κείμενο 91 | // αν όλα πήγαν καλά εκτελείται η defer f.Close*() 92 | } 93 | // αν προκύψει αδυναμία ανάγνωσης, εμφάνισε σφάλμα 94 | if err := scanner.Err(); err != nil { 95 | log.Fatal(err) 96 | } 97 | 98 | //-------------------------------------------------// 99 | /* == Μέθοδος δημιουργίας αρχείου και ανοίγματος == 100 | 101 | Παρακάτω, αντί να ανοίγουμε υπάρχον αρχείο, 102 | δημιουργούμε το αρχείο με όνομα edit.txt 103 | στην διαδρομή απο όπου εκτελείται η εφαρμογή 104 | π.χ. αν τρέξουμε την εφαρμογή 105 | <> 106 | τότε το αρχείο θα δημιουργηθεί δίπλα απο τον φάκελο 107 | "enas-fakelos" και όχι μέσα στον φάκελο δίπλα απο 108 | το "kodikas.go" 109 | 110 | */ 111 | 112 | fmt.Printf("\n== Μέθοδος δημιουργίας και ανοίγματος αρχείου ==\n") 113 | createdfile, err := os.Create("files/edit.txt") 114 | if err != nil { // Πρόβαλε τυχόν σφάλματα 115 | log.Fatal(err) 116 | } 117 | // Γράψτε μια συμβολοσειρά στο αρχείο 118 | createdfile.WriteString("Αυτό είναι ένα τυχαίο κείμενο") 119 | // Κλείστε το αρχείο 120 | createdfile.Close() 121 | // αφού το κλείσουμε ας το ανοίξουμε με την πιο απλή 122 | // μέθοδο που μάθαμε και να προβάλουμε το κείμενο του 123 | openedited, err := ioutil.ReadFile("files/edit.txt") 124 | if err != nil { 125 | log.Fatal(err) 126 | } 127 | fmt.Printf("\n %v", string(openedited)) 128 | 129 | //-------------------------------------------------// 130 | fmt.Printf("\n\n== Μέθοδος ανοίγματος αρχείου CSV ==\n\n") 131 | // == Πρώτη μέθοδος ανοίγματος CSV == 132 | // με την βιβλιοθήκη csv 133 | 134 | // Προσπάθησε να ανοίξεις το αρχείο 135 | csvfile, err := os.Open("files/problems.csv") 136 | // Αν δεν το καταφέρεις, θέλω να μου το πεις 137 | if err != nil { 138 | log.Fatal(err) 139 | } 140 | // περίμενες τις επόμενες εργασίες 141 | defer csvfile.Close() // και μετά κλείσε το αρχείο 142 | // Χρησιμοποίησε την βιβλιοθήκη csv. και 143 | // φτιάξε έναν νέο αναγνώστη του αρχείου csvfile 144 | // και ονόμασε αυτό τον αναγνώστη csvreader 145 | csvreader := csv.NewReader(csvfile) 146 | 147 | for { // Την χρησιμοποιούμε όταν δεν ξέρουμε 148 | // τον συνολικό αριθμό γραμμών/στηλών που έχει το CSV 149 | // Για κάθε εγγραφή να διαβαστεί και να 150 | // αποθηκευτεί στην record 151 | record, err := csvreader.Read() 152 | // αν το σφάλμα είναι επειδή 153 | // έφτασες στο τέλος του αρχείου 154 | // απλά σταμάτα 155 | if err == io.EOF { 156 | break 157 | } 158 | // για οποιοδήποτε άλλο λόγο 159 | // σφάλματος πες μου ποιο ήταν το σφάλμα 160 | if err != nil { 161 | log.Fatal(err) 162 | } 163 | // αν δεν υπάρχει κανένα σφάλμα τότε 164 | // εμφάνισε μια μια τις εγγραφές 165 | fmt.Println(record) 166 | // αν θέλω μονο την 2 στήλη τότε το τρέχω με τον 167 | // παρακάτω τρόπο: 168 | //fmt.Println(record[1]) 169 | } 170 | // == Δεύτερη μέθοδος ανοίγματος CSV == 171 | //με εξωτερική βιβλιοθήκη π.χ. gota, qframes, dataframe-go 172 | /* 173 | Οι εξωτερικές βιβλιοθήκες είναι αρκετές φορές πιο 174 | εξειδικευμένες παρότι δεν ανοίκουν στην ενσωματωμένη 175 | standard library της Go. Συντηρούνται όμως απο 176 | την κοινότητα της go. 177 | 178 | Πριν χρησιμοποιήσουμε την βιβλιοθήκη θα πρέπει να τρέξουμε 179 | go get github.com/go-gota/gota/dataframe 180 | για να κατέβει στo στον υπολογιστή μας και να 181 | μπορούμε να τον κάνουμε import 182 | */ 183 | fmt.Printf("\n\n== Βιβλιοθήκη ανοίγματος αρχείου CSV ==\n\n") 184 | 185 | // Ακολουθούμε το ίδιο μοτίβο, άνοιξε, επεξεργάσου, κλείσε 186 | csvfilelib, err := os.Open("files/greece_covid19.csv") 187 | if err != nil { 188 | log.Fatal(err) 189 | } 190 | defer csvfilelib.Close() 191 | // αφού εισάγαμε την νέα βιβλιοθήκη, χρησιμοποιούμε την ReadCSV 192 | // μέθοδό της και αποθηκεύουμε το αποτέλεσμά της στην df 193 | df := dataframe.ReadCSV(csvfilelib) 194 | fmt.Println(df) 195 | 196 | //-------------------------------------------------// 197 | fmt.Printf("\n\n== Μέθοδος ανοίγματος αρχείου PDF ==\n\n") 198 | /* 199 | Πριν χρησιμοποιήσουμε την βιβλιοθήκη rsc.io/pdf 200 | θα πρέπει να τρέξουμε: 201 | 202 | go get rsc.io/pdf 203 | 204 | για να κατέβει στo στον υπολογιστή μας και να 205 | μπορούμε να τον κάνουμε import 206 | */ 207 | pdfile, err := pdf.Open("files/cerebrux.pdf") 208 | if err != nil { 209 | log.Fatal(err) 210 | } 211 | fmt.Println(pdfile.NumPage()) // μας εμφανίζει το σύνολο σελίδων 212 | fmt.Println(pdfile.Page(1).Content()) // πήγαινε στην 1 σελίδα και 213 | // εμφάνισε το περιεχόμενό της κωδικοποίησης της 214 | 215 | } 216 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020 Salih Emin, 2015 Derek Banas, 2011 The Go Authors. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go (Golang) Σε απλά ελληνικά 2 | Εισαγωγή στην γλώσσα προγραμματισμού Go (Golang) μέσα απο την χρήση έτοιμου κώδικα για ανάγνωση. 3 | 4 | ## Σε ποιούς απευθύνεται; 5 | 6 | Προσπαθήσαμε να κάνουμε την εισαγωγή όσο πιο εύχρηστη και απλή γίνεται. 7 | Όποιος έχει έστω και μια ελάχιστη επαφή με κώδικα, μεταβλητές, συναρτήσεις κλπ πιστεύουμε οτι δεν θα δυσκολευτεί ιδιαίτερα. 8 | 9 | Αυτοί που θα το βρούν ακόμα πιο εύκολο είναι όσοι έχουν έστω και ελάχιστη επαφή με γλώσσες προγραμματισμού, ιδιαίτερα σε Python, java ή C++. 10 | 11 | ## Πως θα μάθω; 12 | 13 | Κάποιες παραδοχές: 14 | - Έχεις εγκαταστήσει σύμφωνα με τις οδηγίες μας στο άρθρο [Go - Εισαγωγή στον προγραμματισμό με Golang](https://cerebrux.net/2020/04/08/go-%cf%80%cf%81%ce%bf%ce%b3%cf%81%ce%b1%ce%bc%ce%bc%ce%b1%cf%84%ce%b9%cf%83%ce%bc%cf%8c%cf%82-golang/) ένα IDE και 15 | φυσικά είναι ρυθμισμένο το σύστημά σου να αντιλαμβάνεται που είναι το Go Workspace (Setup Go Environment) 16 | - Γνωρίζεις Αγγλικά, διότι θα χρησιμοποιούμε κυρίως τους αγγλικούς όρους τις περισσότερες φορές, για να μπορείς να αναζητήσεις περισσότερες πληροφορίες στο internet για αυτά που αναλύουμε στον κώδικα. 17 | 18 | Αφού έχεις διαβάσει την εισαγωγή στην Go που παραθέσαμε πιο πάνω θα είδες οτι τρέχεις την παρακάτω εντολή για να κατεβάσεις τα μαθήματα: 19 | 20 | ``` 21 | cd ~/ 22 | go get github.com/CerebruxCode/Go 23 | ``` 24 | Για να μπεις στο φάκελο των μαθημάτων που μόλις κατέβασες δίνεις την εντολή: 25 | ``` 26 | cd ~/go/src/github.com/CerebruxCode/Go 27 | ``` 28 | Για να δεις μια λίστα με τα διαθέσιμα μαθήματα τρέχεις: 29 | ``` 30 | ls 31 | ``` 32 | Για να μπεις στο εκάστοτε μάθημα (π.χ. στο "00_package_main"): 33 | ``` 34 | cd 00_package_main 35 | ``` 36 | Μπορείς πλέον να ανοίξεις τον κώδικα με το αγαπημένο σου πρόγραμμα επεξεργασίας κώδικα. Αν ακολούθησες τον αναλυτικό οδηγό με το VSCode που έχουμε στο εισαγωγικό άρθρο για την Go, μπορείς να ανοίξεις τον κώδικα με: 37 | ``` 38 | code package_main.go 39 | ``` 40 | Η ανοίγεις το VSCode και απο το μενού `File --> Open Folder` ανοίγεις τον φάκελο `Go` που κατέβασες στην διαδρομή `go/src/github.com/CerebruxCode/Go`. 41 | 42 | Έπειτα διαβάζεις τα σχόλια που έχουμε κάνει μέσα στον κώδικα, τρέχεις το προγράμματα και πειραματίζεσαι αλλάζοντας τιμές, παραμέτρους κλπ για να δεις τα αποτελέσματα που περιμένεις. Η σειρά τον μαθημάτων είναι αριθμημένη σε φακέλους οπότε ξεκινάς απο το πρώτο (0) και συνεχίζεις μέχρι και το τελευταίο. 43 | 44 | ## Βρήκα ένα λάθος, ή έχω μια πρόταση να κάνω 45 | 46 | Τέλεια, διότι αυτά τα μαθήματα είναι σε "work in progress" κατάσταση διότι η μάθηση δεν τελειώνει. 47 | Άνοιξε λοιπόν ένα issue στη σχετική καρτέλα αναφέροντας αναλυτικά το πρόβλημα σου, ή την πρότασή σου. 48 | 49 | Αν κάνεις και διόρθωση απευθείας και μας στείλεις και pull request, ακόμα καλύτερα. Ο κώδικας που ανεβάινει στο αποθετήριο, ελέγχεται αυτοματοποιημένα για κενά ασφαλείας μέσω του [CodeQL](https://github.com/github/codeql-action). 50 | 51 | Αν θεωρείς οτι η δουλειά μας σου φάνηκε χρήσιμη και επωφελήθηκες απο αυτήν, μπορείς να πατήσεις το κουμπί "Sponsor" και να μας κάνεις μια δωρεά. 52 | 53 | ## Μπορώ να χρησιμοποιήσω τον κώδικά σου; 54 | 55 | Αν δεν καταλαβαίνεις απο άδειες ανοιχτού κώδικα, διάβασε αυτό το άρθρο: https://wp.me/pq2ce-giG 56 | Ο κώδικας είναι υπό την ανοιχτού κώδικα άδεια BSD (Δες το αρχείο LICENSE). 57 | Είναι μια συλλογή απο διάφορες πηγές στις οποίες έχουν προστεθεί επιπλέον στοιχεία ή παραμέτρους για καλύτερη κατανόηση. 58 | 59 | Πηγές: 60 | 61 | * [Golang.org/tour](https://tour.golang.org/welcome/1) 62 | * [Βασικές συναρτήσεις της γλώσσας προγραμματισμού GO - ΤΕΙ Κρήτης 2013](http://nefeli.lib.teicrete.gr/browse/sefe/hlk/2013/MoutzourisGeorgios,ZacharakisKonstantinos/attached-document-1372933587-47018-10437/MoutzourisGeorgios_ZacharakisKonstantinos2013.pdf) 63 | * [GO PROGRAMMING TUTORIAL by Derek Banas on Feb 15, 2015](https://web.archive.org/web/20200120114047/https://www.newthinktank.com/2015/02/go-programming-tutorial/) 64 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/CerebruxCode/Go 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/go-gota/gota v0.12.0 7 | rsc.io/pdf v0.1.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.38.0 // indirect 12 | gonum.org/v1/gonum v0.9.3 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 2 | gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= 3 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 4 | github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= 5 | github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= 6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 8 | github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 9 | github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= 10 | github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= 11 | github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= 12 | github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= 13 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 14 | github.com/go-gota/gota v0.12.0 h1:T5BDg1hTf5fZ/CO+T/N0E+DDqUhvoKBl+UVckgcAAQg= 15 | github.com/go-gota/gota v0.12.0/go.mod h1:UT+NsWpZC/FhaOyWb9Hui0jXg0Iq8e/YugZHTbyW/34= 16 | github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= 17 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 18 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 19 | github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 20 | github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 21 | github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= 22 | github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= 23 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 24 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 26 | github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= 27 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 28 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 29 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 30 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 31 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 32 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 33 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= 34 | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 35 | golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= 36 | golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 37 | golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 38 | golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 39 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 40 | golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs= 41 | golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= 42 | golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 43 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 44 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 45 | golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 46 | golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 47 | golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 48 | golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 49 | golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 50 | golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 51 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 52 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 53 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 54 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 55 | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 56 | golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 57 | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 58 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 59 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 60 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 61 | golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 62 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 63 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 64 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 65 | golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 66 | golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= 67 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 68 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 69 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 70 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 71 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 72 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 73 | golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 74 | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 75 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 76 | golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 77 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 78 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 79 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 80 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 81 | golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 82 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 83 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 84 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 85 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 86 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 87 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 88 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 89 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 90 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 91 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 92 | golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 93 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 94 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 95 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 96 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 97 | golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 98 | golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= 99 | golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 100 | golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 101 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 102 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 103 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 104 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 105 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 106 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 107 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 108 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 109 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 110 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 111 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 112 | golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 113 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 114 | golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 115 | golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 116 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 117 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 118 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 119 | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 120 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 121 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 122 | gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= 123 | gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= 124 | gonum.org/v1/gonum v0.9.1/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= 125 | gonum.org/v1/gonum v0.9.3 h1:DnoIG+QAMaF5NvxnGe/oKsgKcAc6PcUyl8q0VetfQ8s= 126 | gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= 127 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= 128 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= 129 | gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= 130 | gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= 131 | rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= 132 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 133 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Γεια σου από Go") 9 | } 10 | --------------------------------------------------------------------------------