mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-11 17:24:29 +02:00
Merge branch 'master' of https://github.com/adambard/learnxinyminutes-docs
This commit is contained in:
@@ -155,7 +155,7 @@ Small-o, commonly written as **o**, is an Asymptotic Notation to denote the
|
|||||||
upper bound (that is not asymptotically tight) on the growth rate of runtime
|
upper bound (that is not asymptotically tight) on the growth rate of runtime
|
||||||
of an algorithm.
|
of an algorithm.
|
||||||
|
|
||||||
`f(n)` is o(g(n)), if for some real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)`
|
`f(n)` is o(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)`
|
||||||
for every input size n (n > n<sub>0</sub>).
|
for every input size n (n > n<sub>0</sub>).
|
||||||
|
|
||||||
The definitions of O-notation and o-notation are similar. The main difference
|
The definitions of O-notation and o-notation are similar. The main difference
|
||||||
@@ -168,7 +168,7 @@ Small-omega, commonly written as **ω**, is an Asymptotic Notation to denote
|
|||||||
the lower bound (that is not asymptotically tight) on the growth rate of
|
the lower bound (that is not asymptotically tight) on the growth rate of
|
||||||
runtime of an algorithm.
|
runtime of an algorithm.
|
||||||
|
|
||||||
`f(n)` is ω(g(n)), if for some real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)`
|
`f(n)` is ω(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)`
|
||||||
for every input size n (n > n<sub>0</sub>).
|
for every input size n (n > n<sub>0</sub>).
|
||||||
|
|
||||||
The definitions of Ω-notation and ω-notation are similar. The main difference
|
The definitions of Ω-notation and ω-notation are similar. The main difference
|
||||||
|
@@ -25,7 +25,7 @@ Nearly all examples below can be a part of a shell script or executed directly i
|
|||||||
[Read more here.](http://www.gnu.org/software/bash/manual/bashref.html)
|
[Read more here.](http://www.gnu.org/software/bash/manual/bashref.html)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# First line of the script is shebang which tells the system how to execute
|
# First line of the script is shebang which tells the system how to execute
|
||||||
# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
|
# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
|
||||||
# As you already figured, comments start with #. Shebang is also a comment.
|
# As you already figured, comments start with #. Shebang is also a comment.
|
||||||
|
212
citron.html.markdown
Normal file
212
citron.html.markdown
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
---
|
||||||
|
language: citron
|
||||||
|
filename: learncitron.ctr
|
||||||
|
contributors:
|
||||||
|
- ["AnotherTest", ""]
|
||||||
|
lang: en-us
|
||||||
|
---
|
||||||
|
```ruby
|
||||||
|
# Comments start with a '#'
|
||||||
|
# All comments encompass a single line
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
## 1. Primitive Data types and Operators
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# You have numbers
|
||||||
|
3. # 3
|
||||||
|
|
||||||
|
# Numbers are all doubles in interpreted mode
|
||||||
|
|
||||||
|
# Mathematical operator precedence is not respected.
|
||||||
|
# binary 'operators' are evaluated in ltr order
|
||||||
|
1 + 1. # 2
|
||||||
|
8 - 4. # 4
|
||||||
|
10 + 2 * 3. # 36
|
||||||
|
|
||||||
|
# Division is always floating division
|
||||||
|
35 / 2 # 17.5.
|
||||||
|
|
||||||
|
# Integer division is non-trivial, you may use floor
|
||||||
|
(35 / 2) floor # 17.
|
||||||
|
|
||||||
|
# Booleans are primitives
|
||||||
|
True.
|
||||||
|
False.
|
||||||
|
|
||||||
|
# Boolean messages
|
||||||
|
True not. # False
|
||||||
|
False not. # True
|
||||||
|
1 = 1. # True
|
||||||
|
1 !=: 1. # False
|
||||||
|
1 < 10. # True
|
||||||
|
|
||||||
|
# Here, `not` is a unary message to the object `Boolean`
|
||||||
|
# Messages are comparable to instance method calls
|
||||||
|
# And they have three different forms:
|
||||||
|
# 1. Unary messages: Length > 1, and they take no arguments:
|
||||||
|
False not.
|
||||||
|
# 2. Binary Messages: Length = 1, and they take a single argument:
|
||||||
|
False & True.
|
||||||
|
# 3. Keyword messages: must have at least one ':', they take as many arguments
|
||||||
|
# as they have `:` s
|
||||||
|
False either: 1 or: 2. # 2
|
||||||
|
|
||||||
|
# Strings
|
||||||
|
'This is a string'.
|
||||||
|
'There are no character types exposed to the user'.
|
||||||
|
# "You cannot use double quotes for strings" <- Error
|
||||||
|
|
||||||
|
# Strins can be summed
|
||||||
|
'Hello, ' + 'World!'. # 'Hello, World!'
|
||||||
|
|
||||||
|
# Strings allow access to their characters
|
||||||
|
'This is a beautiful string' at: 0. # 'T'
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
## intermission: Basic Assignment
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# You may assign values to the current scope:
|
||||||
|
var name is value. # assignes `value` into `name`
|
||||||
|
|
||||||
|
# You may also assign values into the current object's namespace
|
||||||
|
my name is value. # assigns `value` into the current object's `name` property
|
||||||
|
|
||||||
|
# Please note that these names are checked at compile (read parse if in interpreted mode) time
|
||||||
|
# but you may treat them as dynamic assignments anyway
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
## 2. Lists(Arrays?) and Tuples
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# Arrays are allowed to have multiple types
|
||||||
|
Array new < 1 ; 2 ; 'string' ; Nil. # Array new < 1 ; 2 ; 'string' ; Nil
|
||||||
|
|
||||||
|
# Tuples act like arrays, but are immutable.
|
||||||
|
# Any shenanigans degrade them to arrays, however
|
||||||
|
[1, 2, 'string']. # [1, 2, 'string']
|
||||||
|
|
||||||
|
# They can interoperate with arrays
|
||||||
|
[1, 'string'] + (Array new < 'wat'). # Array new < 1 ; 'string' ; 'wat'
|
||||||
|
|
||||||
|
# Indexing into them
|
||||||
|
[1, 2, 3] at: 1. # 2
|
||||||
|
|
||||||
|
# Some array operations
|
||||||
|
var arr is Array new < 1 ; 2 ; 3.
|
||||||
|
|
||||||
|
arr head. # 1
|
||||||
|
arr tail. # Array new < 2 ; 3.
|
||||||
|
arr init. # Array new < 1 ; 2.
|
||||||
|
arr last. # 3
|
||||||
|
arr push: 4. # Array new < 1 ; 2 ; 3 ; 4.
|
||||||
|
arr pop. # 4
|
||||||
|
arr pop: 1. # 2, `arr` is rebound to Array new < 1 ; 3.
|
||||||
|
|
||||||
|
# List comprehensions
|
||||||
|
[x * 2 + y,, arr, arr + [4, 5],, x > 1]. # Array ← 7 ; 9 ; 10 ; 11
|
||||||
|
# fresh variable names are bound as they are encountered,
|
||||||
|
# so `x` is bound to the values in `arr`
|
||||||
|
# and `y` is bound to the values in `arr + [4, 5]`
|
||||||
|
#
|
||||||
|
# The general format is: [expr,, bindings*,, predicates*]
|
||||||
|
|
||||||
|
|
||||||
|
####################################
|
||||||
|
## 3. Functions
|
||||||
|
####################################
|
||||||
|
|
||||||
|
# A simple function that takes two variables
|
||||||
|
var add is {:a:b ^a + b.}.
|
||||||
|
|
||||||
|
# this function will resolve all its names except the formal arguments
|
||||||
|
# in the context it is called in.
|
||||||
|
|
||||||
|
# Using the function
|
||||||
|
add applyTo: 3 and: 5. # 8
|
||||||
|
add applyAll: [3, 5]. # 8
|
||||||
|
|
||||||
|
# Also a (customizable -- more on this later) pseudo-operator allows for a shorthand
|
||||||
|
# of function calls
|
||||||
|
# By default it is REF[args]
|
||||||
|
|
||||||
|
add[3, 5]. # 8
|
||||||
|
|
||||||
|
# To customize this behaviour, you may simply use a compiler pragma:
|
||||||
|
#:callShorthand ()
|
||||||
|
|
||||||
|
# And then you may use the specified operator.
|
||||||
|
# Note that the allowed 'operator' can only be made of any of these: []{}()
|
||||||
|
# And you may mix-and-match (why would anyone do that?)
|
||||||
|
|
||||||
|
add(3, 5). # 8
|
||||||
|
|
||||||
|
# You may also use functions as operators in the following way:
|
||||||
|
|
||||||
|
3 `add` 5. # 8
|
||||||
|
# This call binds as such: add[(3), 5]
|
||||||
|
# because the default fixity is left, and the default precedance is 1
|
||||||
|
|
||||||
|
# You may change the precedence/fixity of this operator with a pragma
|
||||||
|
#:declare infixr 1 add
|
||||||
|
|
||||||
|
3 `add` 5. # 8
|
||||||
|
# now this binds as such: add[3, (5)].
|
||||||
|
|
||||||
|
# There is another form of functions too
|
||||||
|
# So far, the functions were resolved in a dynamic fashion
|
||||||
|
# But a lexically scoped block is also possible
|
||||||
|
var sillyAdd is {\:x:y add[x,y].}.
|
||||||
|
|
||||||
|
# In these blocks, you are not allowed to declare new variables
|
||||||
|
# Except with the use of Object::'letEqual:in:`
|
||||||
|
# And the last expression is implicitly returned.
|
||||||
|
|
||||||
|
# You may also use a shorthand for lambda expressions
|
||||||
|
var mul is \:x:y x * y.
|
||||||
|
|
||||||
|
# These capture the named bindings that are not present in their
|
||||||
|
# formal parameters, and retain them. (by ref)
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
## 5. Control Flow
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# inline conditional-expressions
|
||||||
|
var citron is 1 = 1 either: 'awesome' or: 'awful'. # citron is 'awesome'
|
||||||
|
|
||||||
|
# multiple lines is fine too
|
||||||
|
var citron is 1 = 1
|
||||||
|
either: 'awesome'
|
||||||
|
or: 'awful'.
|
||||||
|
|
||||||
|
# looping
|
||||||
|
10 times: {:x
|
||||||
|
Pen writeln: x.
|
||||||
|
}. # 10. -- side effect: 10 lines in stdout, with numbers 0 through 9 in them
|
||||||
|
|
||||||
|
# Citron properly supports tail-call recursion in lexically scoped blocks
|
||||||
|
# So use those to your heart's desire
|
||||||
|
|
||||||
|
# mapping most data structures is as simple as `fmap:`
|
||||||
|
[1, 2, 3, 4] fmap: \:x x + 1. # [2, 3, 4, 5]
|
||||||
|
|
||||||
|
# You can use `foldl:accumulator:` to fold a list/tuple
|
||||||
|
[1, 2, 3, 4] foldl: (\:acc:x acc * 2 + x) accumulator: 4. # 90
|
||||||
|
|
||||||
|
# That expression is the same as
|
||||||
|
(2 * (2 * (2 * (2 * 4 + 1) + 2) + 3) + 4)
|
||||||
|
|
||||||
|
###################################
|
||||||
|
## 6. IO
|
||||||
|
###################################
|
||||||
|
|
||||||
|
# IO is quite simple
|
||||||
|
# With `Pen` being used for console output
|
||||||
|
# and Program::'input' and Program::'waitForInput' being used for console input
|
||||||
|
|
||||||
|
Pen writeln: 'Hello, ocean!' # prints 'Hello, ocean!\n' to the terminal
|
||||||
|
|
||||||
|
Pen writeln: Program waitForInput. # reads a line and prints it back
|
||||||
|
```
|
@@ -16,7 +16,7 @@ popular and recent book is [Land of Lisp](http://landoflisp.com/). A new book ab
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
```common-lisp
|
```lisp
|
||||||
|
|
||||||
;;;-----------------------------------------------------------------------------
|
;;;-----------------------------------------------------------------------------
|
||||||
;;; 0. Syntax
|
;;; 0. Syntax
|
||||||
|
@@ -13,7 +13,7 @@ Markdown byl vytvořen Johnem Gruberem v roce 2004. Je zamýšlen jako lehce či
|
|||||||
a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha
|
a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha
|
||||||
dalších formátů)
|
dalších formátů)
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown je nadstavba nad HTML, takže jakýkoliv kód HTML je validní
|
<!-- Markdown je nadstavba nad HTML, takže jakýkoliv kód HTML je validní
|
||||||
Markdown, to znamená, že můžeme používat HTML elementy, třeba jako komentář, a
|
Markdown, to znamená, že můžeme používat HTML elementy, třeba jako komentář, a
|
||||||
nebudou ovlivněny parserem Markdownu. Avšak, pokud vytvoříte HTML element v
|
nebudou ovlivněny parserem Markdownu. Avšak, pokud vytvoříte HTML element v
|
||||||
|
@@ -16,19 +16,19 @@ Nodes
|
|||||||
|
|
||||||
**Represents a record in a graph.**
|
**Represents a record in a graph.**
|
||||||
|
|
||||||
```()```
|
`()`
|
||||||
It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query.
|
It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query.
|
||||||
|
|
||||||
```(n)```
|
`(n)`
|
||||||
It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase.
|
It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase.
|
||||||
|
|
||||||
```(p:Person)```
|
`(p:Person)`
|
||||||
You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase.
|
You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase.
|
||||||
|
|
||||||
```(p:Person:Manager)```
|
`(p:Person:Manager)`
|
||||||
A node can have many *labels*.
|
A node can have many *labels*.
|
||||||
|
|
||||||
```(p:Person {name : 'Théo Gauchoux', age : 22})```
|
`(p:Person {name : 'Théo Gauchoux', age : 22})`
|
||||||
A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase.
|
A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase.
|
||||||
|
|
||||||
The types allowed in properties :
|
The types allowed in properties :
|
||||||
@@ -40,7 +40,7 @@ The types allowed in properties :
|
|||||||
|
|
||||||
*Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.*
|
*Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.*
|
||||||
|
|
||||||
```p.name```
|
`p.name`
|
||||||
You can access to a property with the dot style.
|
You can access to a property with the dot style.
|
||||||
|
|
||||||
|
|
||||||
@@ -49,16 +49,16 @@ Relationships (or Edges)
|
|||||||
|
|
||||||
**Connects two nodes**
|
**Connects two nodes**
|
||||||
|
|
||||||
```[:KNOWS]```
|
`[:KNOWS]`
|
||||||
It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE.
|
It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE.
|
||||||
|
|
||||||
```[k:KNOWS]```
|
`[k:KNOWS]`
|
||||||
The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary.
|
The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary.
|
||||||
|
|
||||||
```[k:KNOWS {since:2017}]```
|
`[k:KNOWS {since:2017}]`
|
||||||
The same *relationship*, with *properties* (like *node*), here **since**.
|
The same *relationship*, with *properties* (like *node*), here **since**.
|
||||||
|
|
||||||
```[k:KNOWS*..4]```
|
`[k:KNOWS*..4]`
|
||||||
It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times.
|
It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times.
|
||||||
|
|
||||||
|
|
||||||
@@ -67,16 +67,16 @@ Paths
|
|||||||
|
|
||||||
**The way to mix nodes and relationships.**
|
**The way to mix nodes and relationships.**
|
||||||
|
|
||||||
```(a:Person)-[:KNOWS]-(b:Person)```
|
`(a:Person)-[:KNOWS]-(b:Person)`
|
||||||
A path describing that **a** and **b** know each other.
|
A path describing that **a** and **b** know each other.
|
||||||
|
|
||||||
```(a:Person)-[:MANAGES]->(b:Person)```
|
`(a:Person)-[:MANAGES]->(b:Person)`
|
||||||
A path can be directed. This path describes that **a** is the manager of **b**.
|
A path can be directed. This path describes that **a** is the manager of **b**.
|
||||||
|
|
||||||
```(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)```
|
`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)`
|
||||||
You can chain multiple relationships. This path describes the friend of a friend.
|
You can chain multiple relationships. This path describes the friend of a friend.
|
||||||
|
|
||||||
```(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)```
|
`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)`
|
||||||
A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**.
|
A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**.
|
||||||
|
|
||||||
Patterns often used (from Neo4j doc) :
|
Patterns often used (from Neo4j doc) :
|
||||||
@@ -230,13 +230,13 @@ DELETE n, r
|
|||||||
Other useful clauses
|
Other useful clauses
|
||||||
---
|
---
|
||||||
|
|
||||||
```PROFILE```
|
`PROFILE`
|
||||||
Before a query, show the execution plan of it.
|
Before a query, show the execution plan of it.
|
||||||
|
|
||||||
```COUNT(e)```
|
`COUNT(e)`
|
||||||
Count entities (nodes or relationships) matching **e**.
|
Count entities (nodes or relationships) matching **e**.
|
||||||
|
|
||||||
```LIMIT x```
|
`LIMIT x`
|
||||||
Limit the result to the x first results.
|
Limit the result to the x first results.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ fácilmente a HTML (y, actualmente, otros formatos también).
|
|||||||
¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests!
|
¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests!
|
||||||
|
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown está basado en HTML, así que cualquier archivo HTML es Markdown
|
<!-- Markdown está basado en HTML, así que cualquier archivo HTML es Markdown
|
||||||
válido, eso significa que podemos usar elementos HTML en Markdown como, por
|
válido, eso significa que podemos usar elementos HTML en Markdown como, por
|
||||||
ejemplo, el comentario y no serán afectados por un parseador Markdown. Aún
|
ejemplo, el comentario y no serán afectados por un parseador Markdown. Aún
|
||||||
|
@@ -13,7 +13,7 @@ Objective C es el lenguaje de programación principal utilizado por Apple para l
|
|||||||
Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk".
|
Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk".
|
||||||
|
|
||||||
|
|
||||||
```objective_c
|
```objectivec
|
||||||
// Los comentarios de una sola línea inician con //
|
// Los comentarios de una sola línea inician con //
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -10,7 +10,7 @@ filename: learnvisualbasic-es.vb
|
|||||||
lang: es-es
|
lang: es-es
|
||||||
---
|
---
|
||||||
|
|
||||||
```vb
|
```
|
||||||
Module Module1
|
Module Module1
|
||||||
|
|
||||||
Sub Main()
|
Sub Main()
|
||||||
|
@@ -10,7 +10,7 @@ lang: fi-fi
|
|||||||
|
|
||||||
John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi).
|
John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi).
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme
|
<!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme
|
||||||
käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown
|
käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown
|
||||||
-jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia
|
-jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia
|
||||||
|
@@ -138,5 +138,5 @@ $('p').each(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
``
|
```
|
||||||
|
|
||||||
|
@@ -15,15 +15,15 @@ contributors:
|
|||||||
---
|
---
|
||||||
|
|
||||||
Go was created out of the need to get work done. It's not the latest trend
|
Go was created out of the need to get work done. It's not the latest trend
|
||||||
in computer science, but it is the newest fastest way to solve real-world
|
in programming language theory, but it is a way to solve real-world
|
||||||
problems.
|
problems.
|
||||||
|
|
||||||
It has familiar concepts of imperative languages with static typing.
|
It draws concepts from imperative languages with static typing.
|
||||||
It's fast to compile and fast to execute, it adds easy-to-understand
|
It's fast to compile and fast to execute, it adds easy-to-understand
|
||||||
concurrency to leverage today's multi-core CPUs, and has features to
|
concurrency because multi-core CPUs are now common, and it's used successfully
|
||||||
help with large-scale programming.
|
in large codebases (~100 million loc at Google, Inc.).
|
||||||
|
|
||||||
Go comes with a great standard library and an enthusiastic community.
|
Go comes with a good standard library and a sizeable community.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Single line comment
|
// Single line comment
|
||||||
@@ -48,7 +48,7 @@ import (
|
|||||||
// executable program. Love it or hate it, Go uses brace brackets.
|
// executable program. Love it or hate it, Go uses brace brackets.
|
||||||
func main() {
|
func main() {
|
||||||
// Println outputs a line to stdout.
|
// Println outputs a line to stdout.
|
||||||
// Qualify it with the package name, fmt.
|
// It comes from the package fmt.
|
||||||
fmt.Println("Hello world!")
|
fmt.Println("Hello world!")
|
||||||
|
|
||||||
// Call another function within this package.
|
// Call another function within this package.
|
||||||
|
@@ -13,7 +13,7 @@ Markdown dibuat oleh John Gruber pada tahun 2004. Tujuannya untuk menjadi syntax
|
|||||||
Beri masukan sebanyak-banyaknya! / Jangan sungkan untuk melakukan fork dan pull request!
|
Beri masukan sebanyak-banyaknya! / Jangan sungkan untuk melakukan fork dan pull request!
|
||||||
|
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown adalah superset dari HTML, jadi setiap berkas HTML adalah markdown yang
|
<!-- Markdown adalah superset dari HTML, jadi setiap berkas HTML adalah markdown yang
|
||||||
valid, ini berarti kita dapat menggunakan elemen HTML dalam markdown, seperti elemen
|
valid, ini berarti kita dapat menggunakan elemen HTML dalam markdown, seperti elemen
|
||||||
komentar, dan ia tidak akan terpengaruh parser markdown. Namun, jika Anda membuat
|
komentar, dan ia tidak akan terpengaruh parser markdown. Namun, jika Anda membuat
|
||||||
|
@@ -28,7 +28,7 @@ Markdown varia nelle sue implementazioni da un parser all'altro. Questa guida ce
|
|||||||
## Elementi HTML
|
## Elementi HTML
|
||||||
Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido.
|
Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido.
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti,
|
<!-- Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti,
|
||||||
e questi non saranno modificati dal parser di Markdown. State attenti però,
|
e questi non saranno modificati dal parser di Markdown. State attenti però,
|
||||||
se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi
|
se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi
|
||||||
|
@@ -400,8 +400,8 @@ else: # Anche else è opzionale
|
|||||||
print("some_var è 10.")
|
print("some_var è 10.")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
I cicli for iterano sulle liste, cioé ripetono un codice per ogni elemento
|
I cicli for iterano sulle liste, cioè ripetono un codice per ogni elemento
|
||||||
# di una lista.
|
di una lista.
|
||||||
Il seguente codice scriverà:
|
Il seguente codice scriverà:
|
||||||
cane è un mammifero
|
cane è un mammifero
|
||||||
gatto è un mammifero
|
gatto è un mammifero
|
||||||
@@ -409,7 +409,7 @@ Il seguente codice scriverà:
|
|||||||
"""
|
"""
|
||||||
for animale in ["cane", "gatto", "topo"]:
|
for animale in ["cane", "gatto", "topo"]:
|
||||||
# Puoi usare format() per interpolare le stringhe formattate.
|
# Puoi usare format() per interpolare le stringhe formattate.
|
||||||
print("{} is a mammal".format(animal))
|
print("{} è un mammifero".format(animale))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
"range(numero)" restituisce una lista di numeri da zero al numero dato
|
"range(numero)" restituisce una lista di numeri da zero al numero dato
|
||||||
|
@@ -600,10 +600,6 @@ of the language.
|
|||||||
[Eloquent Javascript][8] by Marijn Haverbeke is an excellent JS book/ebook with
|
[Eloquent Javascript][8] by Marijn Haverbeke is an excellent JS book/ebook with
|
||||||
attached terminal
|
attached terminal
|
||||||
|
|
||||||
[Eloquent Javascript - The Annotated Version][9] by Gordon Zhu is also a great
|
|
||||||
derivative of Eloquent Javascript with extra explanations and clarifications for
|
|
||||||
some of the more complicated examples.
|
|
||||||
|
|
||||||
[Javascript: The Right Way][10] is a guide intended to introduce new developers
|
[Javascript: The Right Way][10] is a guide intended to introduce new developers
|
||||||
to JavaScript and help experienced developers learn more about its best practices.
|
to JavaScript and help experienced developers learn more about its best practices.
|
||||||
|
|
||||||
@@ -624,6 +620,5 @@ Mozilla Developer Network.
|
|||||||
[6]: http://www.amazon.com/gp/product/0596805527/
|
[6]: http://www.amazon.com/gp/product/0596805527/
|
||||||
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
|
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
|
||||||
[8]: http://eloquentjavascript.net/
|
[8]: http://eloquentjavascript.net/
|
||||||
[9]: http://watchandcode.com/courses/eloquent-javascript-the-annotated-version
|
|
||||||
[10]: http://jstherightway.org/
|
[10]: http://jstherightway.org/
|
||||||
[11]: https://javascript.info/
|
[11]: https://javascript.info/
|
||||||
|
@@ -2,17 +2,17 @@
|
|||||||
language: Julia
|
language: Julia
|
||||||
contributors:
|
contributors:
|
||||||
- ["Leah Hanson", "http://leahhanson.us"]
|
- ["Leah Hanson", "http://leahhanson.us"]
|
||||||
- ["Pranit Bauva", "http://github.com/pranitbauva1997"]
|
- ["Pranit Bauva", "https://github.com/pranitbauva1997"]
|
||||||
- ["Daniel YC Lin", "http://github.com/dlintw"]
|
- ["Daniel YC Lin", "https://github.com/dlintw"]
|
||||||
filename: learnjulia.jl
|
filename: learnjulia.jl
|
||||||
---
|
---
|
||||||
|
|
||||||
Julia is a new homoiconic functional language focused on technical computing.
|
Julia is a new homoiconic functional language focused on technical computing.
|
||||||
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
|
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
|
||||||
|
|
||||||
This is based on Julia 0.6.4
|
This is based on Julia 1.0.0
|
||||||
|
|
||||||
```ruby
|
```julia
|
||||||
|
|
||||||
# Single line comments start with a hash (pound) symbol.
|
# Single line comments start with a hash (pound) symbol.
|
||||||
#= Multiline comments can be written
|
#= Multiline comments can be written
|
||||||
@@ -27,38 +27,38 @@ This is based on Julia 0.6.4
|
|||||||
# Everything in Julia is an expression.
|
# Everything in Julia is an expression.
|
||||||
|
|
||||||
# There are several basic types of numbers.
|
# There are several basic types of numbers.
|
||||||
3 # => 3 (Int64)
|
3 # => 3 (Int64)
|
||||||
3.2 # => 3.2 (Float64)
|
3.2 # => 3.2 (Float64)
|
||||||
2 + 1im # => 2 + 1im (Complex{Int64})
|
2 + 1im # => 2 + 1im (Complex{Int64})
|
||||||
2//3 # => 2//3 (Rational{Int64})
|
2 // 3 # => 2 // 3 (Rational{Int64})
|
||||||
|
|
||||||
# All of the normal infix operators are available.
|
# All of the normal infix operators are available.
|
||||||
1 + 1 # => 2
|
1 + 1 # => 2
|
||||||
8 - 1 # => 7
|
8 - 1 # => 7
|
||||||
10 * 2 # => 20
|
10 * 2 # => 20
|
||||||
35 / 5 # => 7.0
|
35 / 5 # => 7.0
|
||||||
5 / 2 # => 2.5 # dividing an Int by an Int always results in a Float
|
5 / 2 # => 2.5 # dividing integers always results in a Float64
|
||||||
div(5, 2) # => 2 # for a truncated result, use div
|
div(5, 2) # => 2 # for a truncated result, use div
|
||||||
5 \ 35 # => 7.0
|
5 \ 35 # => 7.0
|
||||||
2 ^ 2 # => 4 # power, not bitwise xor
|
2^2 # => 4 # power, not bitwise xor
|
||||||
12 % 10 # => 2
|
12 % 10 # => 2
|
||||||
|
|
||||||
# Enforce precedence with parentheses
|
# Enforce precedence with parentheses
|
||||||
(1 + 3) * 2 # => 8
|
(1 + 3) * 2 # => 8
|
||||||
|
|
||||||
# Bitwise Operators
|
# Bitwise Operators
|
||||||
~2 # => -3 # bitwise not
|
~2 # => -3 # bitwise not
|
||||||
3 & 5 # => 1 # bitwise and
|
3 & 5 # => 1 # bitwise and
|
||||||
2 | 4 # => 6 # bitwise or
|
2 | 4 # => 6 # bitwise or
|
||||||
xor(2, 4) # => 6 # bitwise xor
|
xor(2, 4) # => 6 # bitwise xor
|
||||||
2 >>> 1 # => 1 # logical shift right
|
2 >>> 1 # => 1 # logical shift right
|
||||||
2 >> 1 # => 1 # arithmetic shift right
|
2 >> 1 # => 1 # arithmetic shift right
|
||||||
2 << 1 # => 4 # logical/arithmetic shift left
|
2 << 1 # => 4 # logical/arithmetic shift left
|
||||||
|
|
||||||
# You can use the bits function to see the binary representation of a number.
|
# Use the bitstring function to see the binary representation of a number.
|
||||||
bits(12345)
|
bitstring(12345)
|
||||||
# => "0000000000000000000000000000000000000000000000000011000000111001"
|
# => "0000000000000000000000000000000000000000000000000011000000111001"
|
||||||
bits(12345.0)
|
bitstring(12345.0)
|
||||||
# => "0100000011001000000111001000000000000000000000000000000000000000"
|
# => "0100000011001000000111001000000000000000000000000000000000000000"
|
||||||
|
|
||||||
# Boolean values are primitives
|
# Boolean values are primitives
|
||||||
@@ -66,48 +66,38 @@ true
|
|||||||
false
|
false
|
||||||
|
|
||||||
# Boolean operators
|
# Boolean operators
|
||||||
!true # => false
|
!true # => false
|
||||||
!false # => true
|
!false # => true
|
||||||
1 == 1 # => true
|
1 == 1 # => true
|
||||||
2 == 1 # => false
|
2 == 1 # => false
|
||||||
1 != 1 # => false
|
1 != 1 # => false
|
||||||
2 != 1 # => true
|
2 != 1 # => true
|
||||||
1 < 10 # => true
|
1 < 10 # => true
|
||||||
1 > 10 # => false
|
1 > 10 # => false
|
||||||
2 <= 2 # => true
|
2 <= 2 # => true
|
||||||
2 >= 2 # => true
|
2 >= 2 # => true
|
||||||
# Comparisons can be chained
|
# Comparisons can be chained
|
||||||
1 < 2 < 3 # => true
|
1 < 2 < 3 # => true
|
||||||
2 < 3 < 2 # => false
|
2 < 3 < 2 # => false
|
||||||
|
|
||||||
# Strings are created with "
|
# Strings are created with "
|
||||||
try
|
|
||||||
"This is a string."
|
"This is a string."
|
||||||
catch ; end
|
|
||||||
|
|
||||||
# Julia has several types of strings, including ASCIIString and UTF8String.
|
|
||||||
# More on this in the Types section.
|
|
||||||
|
|
||||||
# Character literals are written with '
|
# Character literals are written with '
|
||||||
try
|
|
||||||
'a'
|
'a'
|
||||||
catch ; end
|
|
||||||
|
|
||||||
# Some strings can be indexed like an array of characters
|
# Strings are UTF8 encoded. Only if they contain only ASCII characters can
|
||||||
try
|
# they be safely indexed.
|
||||||
"This is a string"[1] # => 'T' # Julia indexes from 1
|
ascii("This is a string")[1] # => 'T' # Julia indexes from 1
|
||||||
catch ; end
|
# Otherwise, iterating over strings is recommended (map, for loops, etc).
|
||||||
# However, this is will not work well for UTF8 strings,
|
|
||||||
# so iterating over strings is recommended (map, for loops, etc).
|
|
||||||
|
|
||||||
# $ can be used for string interpolation:
|
# $ can be used for string interpolation:
|
||||||
try
|
|
||||||
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
|
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
|
||||||
catch ; end
|
|
||||||
# You can put any Julia expression inside the parentheses.
|
# You can put any Julia expression inside the parentheses.
|
||||||
|
|
||||||
# Another way to format strings is the printf macro.
|
# Another way to format strings is the printf macro from the stdlib Printf.
|
||||||
@printf "%d is less than %f" 4.5 5.3 # 4 is less than 5.300000
|
using Printf
|
||||||
|
@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000
|
||||||
|
|
||||||
# Printing is easy
|
# Printing is easy
|
||||||
println("I'm Julia. Nice to meet you!")
|
println("I'm Julia. Nice to meet you!")
|
||||||
@@ -115,29 +105,29 @@ println("I'm Julia. Nice to meet you!")
|
|||||||
# String can be compared lexicographically
|
# String can be compared lexicographically
|
||||||
"good" > "bye" # => true
|
"good" > "bye" # => true
|
||||||
"good" == "good" # => true
|
"good" == "good" # => true
|
||||||
"1 + 2 = 3" == "1 + 2 = $(1+2)" # => true
|
"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
## 2. Variables and Collections
|
## 2. Variables and Collections
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
# You don't declare variables before assigning to them.
|
# You don't declare variables before assigning to them.
|
||||||
some_var = 5 # => 5
|
some_var = 5 # => 5
|
||||||
some_var # => 5
|
some_var # => 5
|
||||||
|
|
||||||
# Accessing a previously unassigned variable is an error
|
# Accessing a previously unassigned variable is an error
|
||||||
try
|
try
|
||||||
some_other_var # => ERROR: some_other_var not defined
|
some_other_var # => ERROR: UndefVarError: some_other_var not defined
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Variable names start with a letter or underscore.
|
# Variable names start with a letter or underscore.
|
||||||
# After that, you can use letters, digits, underscores, and exclamation points.
|
# After that, you can use letters, digits, underscores, and exclamation points.
|
||||||
SomeOtherVar123! = 6 # => 6
|
SomeOtherVar123! = 6 # => 6
|
||||||
|
|
||||||
# You can also use certain unicode characters
|
# You can also use certain unicode characters
|
||||||
☃ = 8 # => 8
|
☃ = 8 # => 8
|
||||||
# These are especially handy for mathematical notation
|
# These are especially handy for mathematical notation
|
||||||
2 * π # => 6.283185307179586
|
2 * π # => 6.283185307179586
|
||||||
|
|
||||||
@@ -156,165 +146,168 @@ SomeOtherVar123! = 6 # => 6
|
|||||||
# functions are sometimes called mutating functions or in-place functions.
|
# functions are sometimes called mutating functions or in-place functions.
|
||||||
|
|
||||||
# Arrays store a sequence of values indexed by integers 1 through n:
|
# Arrays store a sequence of values indexed by integers 1 through n:
|
||||||
a = Int64[] # => 0-element Int64 Array
|
a = Int64[] # => 0-element Int64 Array
|
||||||
|
|
||||||
# 1-dimensional array literals can be written with comma-separated values.
|
# 1-dimensional array literals can be written with comma-separated values.
|
||||||
b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
|
b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
|
||||||
b = [4; 5; 6] # => 3-element Int64 Array: [4, 5, 6]
|
b = [4; 5; 6] # => 3-element Int64 Array: [4, 5, 6]
|
||||||
b[1] # => 4
|
b[1] # => 4
|
||||||
b[end] # => 6
|
b[end] # => 6
|
||||||
|
|
||||||
# 2-dimensional arrays use space-separated values and semicolon-separated rows.
|
# 2-dimensional arrays use space-separated values and semicolon-separated rows.
|
||||||
matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
|
matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
|
||||||
|
|
||||||
# Arrays of a particular Type
|
# Arrays of a particular type
|
||||||
b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6]
|
b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6]
|
||||||
|
|
||||||
# Add stuff to the end of a list with push! and append!
|
# Add stuff to the end of a list with push! and append!
|
||||||
push!(a,1) # => [1]
|
push!(a, 1) # => [1]
|
||||||
push!(a,2) # => [1,2]
|
push!(a, 2) # => [1,2]
|
||||||
push!(a,4) # => [1,2,4]
|
push!(a, 4) # => [1,2,4]
|
||||||
push!(a,3) # => [1,2,4,3]
|
push!(a, 3) # => [1,2,4,3]
|
||||||
append!(a,b) # => [1,2,4,3,4,5,6]
|
append!(a, b) # => [1,2,4,3,4,5,6]
|
||||||
|
|
||||||
# Remove from the end with pop
|
# Remove from the end with pop
|
||||||
pop!(b) # => 6 and b is now [4,5]
|
pop!(b) # => 6 and b is now [4,5]
|
||||||
|
|
||||||
# Let's put it back
|
# Let's put it back
|
||||||
push!(b,6) # b is now [4,5,6] again.
|
push!(b, 6) # b is now [4,5,6] again.
|
||||||
|
|
||||||
a[1] # => 1 # remember that Julia indexes from 1, not 0!
|
a[1] # => 1 # remember that Julia indexes from 1, not 0!
|
||||||
|
|
||||||
# end is a shorthand for the last index. It can be used in any
|
# end is a shorthand for the last index. It can be used in any
|
||||||
# indexing expression
|
# indexing expression
|
||||||
a[end] # => 6
|
a[end] # => 6
|
||||||
|
|
||||||
# we also have shift and unshift
|
# we also have popfirst! and pushfirst!
|
||||||
shift!(a) # => 1 and a is now [2,4,3,4,5,6]
|
popfirst!(a) # => 1 and a is now [2,4,3,4,5,6]
|
||||||
unshift!(a,7) # => [7,2,4,3,4,5,6]
|
pushfirst!(a, 7) # => [7,2,4,3,4,5,6]
|
||||||
|
|
||||||
# Function names that end in exclamations points indicate that they modify
|
# Function names that end in exclamations points indicate that they modify
|
||||||
# their argument.
|
# their argument.
|
||||||
arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
|
arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
|
||||||
sort(arr) # => [4,5,6]; arr is still [5,4,6]
|
sort(arr) # => [4,5,6]; arr is still [5,4,6]
|
||||||
sort!(arr) # => [4,5,6]; arr is now [4,5,6]
|
sort!(arr) # => [4,5,6]; arr is now [4,5,6]
|
||||||
|
|
||||||
# Looking out of bounds is a BoundsError
|
# Looking out of bounds is a BoundsError
|
||||||
try
|
try
|
||||||
a[0] # => ERROR: BoundsError() in getindex at array.jl:270
|
a[0]
|
||||||
a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
|
# => BoundsError: attempt to access 7-element Array{Int64,1} at index [0]
|
||||||
|
a[end + 1]
|
||||||
|
# => BoundsError: attempt to access 7-element Array{Int64,1} at index [8]
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Errors list the line and file they came from, even if it's in the standard
|
# Errors list the line and file they came from, even if it's in the standard
|
||||||
# library. If you built Julia from source, you can look in the folder base
|
# library. You can look in the folder share/julia inside the julia folder to
|
||||||
# inside the julia folder to find these files.
|
# find these files.
|
||||||
|
|
||||||
# You can initialize arrays from ranges
|
# You can initialize arrays from ranges
|
||||||
a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
|
a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
|
||||||
|
|
||||||
# You can look at ranges with slice syntax.
|
# You can look at ranges with slice syntax.
|
||||||
a[1:3] # => [1, 2, 3]
|
a[1:3] # => [1, 2, 3]
|
||||||
a[2:end] # => [2, 3, 4, 5]
|
a[2:end] # => [2, 3, 4, 5]
|
||||||
|
|
||||||
# Remove elements from an array by index with splice!
|
# Remove elements from an array by index with splice!
|
||||||
arr = [3,4,5]
|
arr = [3,4,5]
|
||||||
splice!(arr,2) # => 4 ; arr is now [3,5]
|
splice!(arr, 2) # => 4 ; arr is now [3,5]
|
||||||
|
|
||||||
# Concatenate lists with append!
|
# Concatenate lists with append!
|
||||||
b = [1,2,3]
|
b = [1,2,3]
|
||||||
append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
|
append!(a, b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
|
||||||
|
|
||||||
# Check for existence in a list with in
|
# Check for existence in a list with in
|
||||||
in(1, a) # => true
|
in(1, a) # => true
|
||||||
|
|
||||||
# Examine the length with length
|
# Examine the length with length
|
||||||
length(a) # => 8
|
length(a) # => 8
|
||||||
|
|
||||||
# Tuples are immutable.
|
# Tuples are immutable.
|
||||||
tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
|
tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
|
||||||
tup[1] # => 1
|
tup[1] # => 1
|
||||||
try:
|
try
|
||||||
tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
|
tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Many list functions also work on tuples
|
# Many array functions also work on tuples
|
||||||
length(tup) # => 3
|
length(tup) # => 3
|
||||||
tup[1:2] # => (1,2)
|
tup[1:2] # => (1,2)
|
||||||
in(2, tup) # => true
|
in(2, tup) # => true
|
||||||
|
|
||||||
# You can unpack tuples into variables
|
# You can unpack tuples into variables
|
||||||
a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
|
a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
|
||||||
|
|
||||||
# Tuples are created even if you leave out the parentheses
|
# Tuples are created even if you leave out the parentheses
|
||||||
d, e, f = 4, 5, 6 # => (4,5,6)
|
d, e, f = 4, 5, 6 # => (4,5,6)
|
||||||
|
|
||||||
# A 1-element tuple is distinct from the value it contains
|
# A 1-element tuple is distinct from the value it contains
|
||||||
(1,) == 1 # => false
|
(1,) == 1 # => false
|
||||||
(1) == 1 # => true
|
(1) == 1 # => true
|
||||||
|
|
||||||
# Look how easy it is to swap two values
|
# Look how easy it is to swap two values
|
||||||
e, d = d, e # => (5,4) # d is now 5 and e is now 4
|
e, d = d, e # => (5,4) # d is now 5 and e is now 4
|
||||||
|
|
||||||
|
|
||||||
# Dictionaries store mappings
|
# Dictionaries store mappings
|
||||||
empty_dict = Dict() # => Dict{Any,Any}()
|
empty_dict = Dict() # => Dict{Any,Any}()
|
||||||
|
|
||||||
# You can create a dictionary using a literal
|
# You can create a dictionary using a literal
|
||||||
filled_dict = Dict("one"=> 1, "two"=> 2, "three"=> 3)
|
filled_dict = Dict("one" => 1, "two" => 2, "three" => 3)
|
||||||
# => Dict{ASCIIString,Int64}
|
# => Dict{String,Int64}
|
||||||
|
|
||||||
# Look up values with []
|
# Look up values with []
|
||||||
filled_dict["one"] # => 1
|
filled_dict["one"] # => 1
|
||||||
|
|
||||||
# Get all keys
|
# Get all keys
|
||||||
keys(filled_dict)
|
keys(filled_dict)
|
||||||
# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
# => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys:
|
||||||
|
# "two", "one", "three"
|
||||||
# Note - dictionary keys are not sorted or in the order you inserted them.
|
# Note - dictionary keys are not sorted or in the order you inserted them.
|
||||||
|
|
||||||
# Get all values
|
# Get all values
|
||||||
values(filled_dict)
|
values(filled_dict)
|
||||||
# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
# => Base.ValueIterator{Dict{String,Int64}} with 3 entries. Values: 2, 1, 3
|
||||||
# Note - Same as above regarding key ordering.
|
# Note - Same as above regarding key ordering.
|
||||||
|
|
||||||
# Check for existence of keys in a dictionary with in, haskey
|
# Check for existence of keys in a dictionary with in, haskey
|
||||||
in(("one" => 1), filled_dict) # => true
|
in(("one" => 1), filled_dict) # => true
|
||||||
in(("two" => 3), filled_dict) # => false
|
in(("two" => 3), filled_dict) # => false
|
||||||
haskey(filled_dict, "one") # => true
|
haskey(filled_dict, "one") # => true
|
||||||
haskey(filled_dict, 1) # => false
|
haskey(filled_dict, 1) # => false
|
||||||
|
|
||||||
# Trying to look up a non-existent key will raise an error
|
# Trying to look up a non-existent key will raise an error
|
||||||
try
|
try
|
||||||
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
|
filled_dict["four"] # => KeyError: key "four" not found
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Use the get method to avoid that error by providing a default value
|
# Use the get method to avoid that error by providing a default value
|
||||||
# get(dictionary,key,default_value)
|
# get(dictionary, key, default_value)
|
||||||
get(filled_dict,"one",4) # => 1
|
get(filled_dict, "one", 4) # => 1
|
||||||
get(filled_dict,"four",4) # => 4
|
get(filled_dict, "four", 4) # => 4
|
||||||
|
|
||||||
# Use Sets to represent collections of unordered, unique values
|
# Use Sets to represent collections of unordered, unique values
|
||||||
empty_set = Set() # => Set{Any}()
|
empty_set = Set() # => Set{Any}()
|
||||||
# Initialize a set with values
|
# Initialize a set with values
|
||||||
filled_set = Set([1,2,2,3,4]) # => Set{Int64}(1,2,3,4)
|
filled_set = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1])
|
||||||
|
|
||||||
# Add more values to a set
|
# Add more values to a set
|
||||||
push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
|
push!(filled_set, 5) # => Set([4, 2, 3, 5, 1])
|
||||||
|
|
||||||
# Check if the values are in the set
|
# Check if the values are in the set
|
||||||
in(2, filled_set) # => true
|
in(2, filled_set) # => true
|
||||||
in(10, filled_set) # => false
|
in(10, filled_set) # => false
|
||||||
|
|
||||||
# There are functions for set intersection, union, and difference.
|
# There are functions for set intersection, union, and difference.
|
||||||
other_set = Set([3, 4, 5, 6]) # => Set{Int64}(6,4,5,3)
|
other_set = Set([3, 4, 5, 6]) # => Set([4, 3, 5, 6])
|
||||||
intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
|
intersect(filled_set, other_set) # => Set([4, 3, 5])
|
||||||
union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
|
union(filled_set, other_set) # => Set([4, 2, 3, 5, 6, 1])
|
||||||
setdiff(Set([1,2,3,4]),Set([2,3,5])) # => Set{Int64}(1,4)
|
setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1])
|
||||||
|
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
@@ -337,7 +330,7 @@ end
|
|||||||
|
|
||||||
# For loops iterate over iterables.
|
# For loops iterate over iterables.
|
||||||
# Iterable types include Range, Array, Set, Dict, and AbstractString.
|
# Iterable types include Range, Array, Set, Dict, and AbstractString.
|
||||||
for animal=["dog", "cat", "mouse"]
|
for animal = ["dog", "cat", "mouse"]
|
||||||
println("$animal is a mammal")
|
println("$animal is a mammal")
|
||||||
# You can use $ to interpolate variables or expression into strings
|
# You can use $ to interpolate variables or expression into strings
|
||||||
end
|
end
|
||||||
@@ -355,15 +348,16 @@ end
|
|||||||
# cat is a mammal
|
# cat is a mammal
|
||||||
# mouse is a mammal
|
# mouse is a mammal
|
||||||
|
|
||||||
for a in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal")
|
for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
|
||||||
println("$(a[1]) is a $(a[2])")
|
from, to = pair
|
||||||
|
println("$from is a $to")
|
||||||
end
|
end
|
||||||
# prints:
|
# prints:
|
||||||
# dog is a mammal
|
# dog is a mammal
|
||||||
# cat is a mammal
|
# cat is a mammal
|
||||||
# mouse is a mammal
|
# mouse is a mammal
|
||||||
|
|
||||||
for (k,v) in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal")
|
for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
|
||||||
println("$k is a $v")
|
println("$k is a $v")
|
||||||
end
|
end
|
||||||
# prints:
|
# prints:
|
||||||
@@ -372,10 +366,11 @@ end
|
|||||||
# mouse is a mammal
|
# mouse is a mammal
|
||||||
|
|
||||||
# While loops loop while a condition is true
|
# While loops loop while a condition is true
|
||||||
x = 0
|
let x = 0
|
||||||
while x < 4
|
while x < 4
|
||||||
println(x)
|
println(x)
|
||||||
x += 1 # Shorthand for x = x + 1
|
x += 1 # Shorthand for x = x + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# prints:
|
# prints:
|
||||||
# 0
|
# 0
|
||||||
@@ -385,9 +380,9 @@ end
|
|||||||
|
|
||||||
# Handle exceptions with a try/catch block
|
# Handle exceptions with a try/catch block
|
||||||
try
|
try
|
||||||
error("help")
|
error("help")
|
||||||
catch e
|
catch e
|
||||||
println("caught it $e")
|
println("caught it $e")
|
||||||
end
|
end
|
||||||
# => caught it ErrorException("help")
|
# => caught it ErrorException("help")
|
||||||
|
|
||||||
@@ -407,15 +402,15 @@ function add(x, y)
|
|||||||
x + y
|
x + y
|
||||||
end
|
end
|
||||||
|
|
||||||
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
|
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
|
||||||
|
|
||||||
# Compact assignment of functions
|
# Compact assignment of functions
|
||||||
f_add(x, y) = x + y # => "f (generic function with 1 method)"
|
f_add(x, y) = x + y # => "f (generic function with 1 method)"
|
||||||
f_add(3, 4) # => 7
|
f_add(3, 4) # => 7
|
||||||
|
|
||||||
# Function can also return multiple values as tuple
|
# Function can also return multiple values as tuple
|
||||||
fn(x, y) = x + y, x - y
|
fn(x, y) = x + y, x - y
|
||||||
fn(3, 4) # => (7, -1)
|
fn(3, 4) # => (7, -1)
|
||||||
|
|
||||||
# You can define functions that take a variable number of
|
# You can define functions that take a variable number of
|
||||||
# positional arguments
|
# positional arguments
|
||||||
@@ -425,41 +420,41 @@ function varargs(args...)
|
|||||||
end
|
end
|
||||||
# => varargs (generic function with 1 method)
|
# => varargs (generic function with 1 method)
|
||||||
|
|
||||||
varargs(1,2,3) # => (1,2,3)
|
varargs(1, 2, 3) # => (1,2,3)
|
||||||
|
|
||||||
# The ... is called a splat.
|
# The ... is called a splat.
|
||||||
# We just used it in a function definition.
|
# We just used it in a function definition.
|
||||||
# It can also be used in a function call,
|
# It can also be used in a function call,
|
||||||
# where it will splat an Array or Tuple's contents into the argument list.
|
# where it will splat an Array or Tuple's contents into the argument list.
|
||||||
add([5,6]...) # this is equivalent to add(5,6)
|
add([5,6]...) # this is equivalent to add(5,6)
|
||||||
|
|
||||||
x = (5,6) # => (5,6)
|
x = (5, 6) # => (5,6)
|
||||||
add(x...) # this is equivalent to add(5,6)
|
add(x...) # this is equivalent to add(5,6)
|
||||||
|
|
||||||
|
|
||||||
# You can define functions with optional positional arguments
|
# You can define functions with optional positional arguments
|
||||||
function defaults(a,b,x=5,y=6)
|
function defaults(a, b, x=5, y=6)
|
||||||
return "$a $b and $x $y"
|
return "$a $b and $x $y"
|
||||||
end
|
end
|
||||||
|
|
||||||
defaults('h','g') # => "h g and 5 6"
|
defaults('h', 'g') # => "h g and 5 6"
|
||||||
defaults('h','g','j') # => "h g and j 6"
|
defaults('h', 'g', 'j') # => "h g and j 6"
|
||||||
defaults('h','g','j','k') # => "h g and j k"
|
defaults('h', 'g', 'j', 'k') # => "h g and j k"
|
||||||
try
|
try
|
||||||
defaults('h') # => ERROR: no method defaults(Char,)
|
defaults('h') # => ERROR: no method defaults(Char,)
|
||||||
defaults() # => ERROR: no methods defaults()
|
defaults() # => ERROR: no methods defaults()
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# You can define functions that take keyword arguments
|
# You can define functions that take keyword arguments
|
||||||
function keyword_args(;k1=4,name2="hello") # note the ;
|
function keyword_args(;k1=4, name2="hello") # note the ;
|
||||||
return Dict("k1"=>k1,"name2"=>name2)
|
return Dict("k1" => k1, "name2" => name2)
|
||||||
end
|
end
|
||||||
|
|
||||||
keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
|
keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
|
||||||
keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
|
keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
|
||||||
keyword_args() # => ["name2"=>"hello","k1"=>4]
|
keyword_args() # => ["name2"=>"hello","k1"=>4]
|
||||||
|
|
||||||
# You can combine all kinds of arguments in the same function
|
# You can combine all kinds of arguments in the same function
|
||||||
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
|
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
|
||||||
@@ -483,7 +478,7 @@ function create_adder(x)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# This is "stabby lambda syntax" for creating anonymous functions
|
# This is "stabby lambda syntax" for creating anonymous functions
|
||||||
(x -> x > 2)(3) # => true
|
(x -> x > 2)(3) # => true
|
||||||
|
|
||||||
# This function is identical to create_adder implementation above.
|
# This function is identical to create_adder implementation above.
|
||||||
function create_adder(x)
|
function create_adder(x)
|
||||||
@@ -499,16 +494,17 @@ function create_adder(x)
|
|||||||
end
|
end
|
||||||
|
|
||||||
add_10 = create_adder(10)
|
add_10 = create_adder(10)
|
||||||
add_10(3) # => 13
|
add_10(3) # => 13
|
||||||
|
|
||||||
|
|
||||||
# There are built-in higher order functions
|
# There are built-in higher order functions
|
||||||
map(add_10, [1,2,3]) # => [11, 12, 13]
|
map(add_10, [1,2,3]) # => [11, 12, 13]
|
||||||
filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
||||||
|
|
||||||
# We can use list comprehensions for nicer maps
|
# We can use list comprehensions
|
||||||
[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
|
[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13]
|
||||||
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
|
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
|
||||||
|
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
## 5. Types
|
## 5. Types
|
||||||
@@ -517,11 +513,11 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
|||||||
# Julia has a type system.
|
# Julia has a type system.
|
||||||
# Every value has a type; variables do not have types themselves.
|
# Every value has a type; variables do not have types themselves.
|
||||||
# You can use the `typeof` function to get the type of a value.
|
# You can use the `typeof` function to get the type of a value.
|
||||||
typeof(5) # => Int64
|
typeof(5) # => Int64
|
||||||
|
|
||||||
# Types are first-class values
|
# Types are first-class values
|
||||||
typeof(Int64) # => DataType
|
typeof(Int64) # => DataType
|
||||||
typeof(DataType) # => DataType
|
typeof(DataType) # => DataType
|
||||||
# DataType is the type that represents types, including itself.
|
# DataType is the type that represents types, including itself.
|
||||||
|
|
||||||
# Types are used for documentation, optimizations, and dispatch.
|
# Types are used for documentation, optimizations, and dispatch.
|
||||||
@@ -529,78 +525,77 @@ typeof(DataType) # => DataType
|
|||||||
|
|
||||||
# Users can define types
|
# Users can define types
|
||||||
# They are like records or structs in other languages.
|
# They are like records or structs in other languages.
|
||||||
# New types are defined using the `type` keyword.
|
# New types are defined using the `struct` keyword.
|
||||||
|
|
||||||
# type Name
|
# struct Name
|
||||||
# field::OptionalType
|
# field::OptionalType
|
||||||
# ...
|
# ...
|
||||||
# end
|
# end
|
||||||
type Tiger
|
struct Tiger
|
||||||
taillength::Float64
|
taillength::Float64
|
||||||
coatcolor # not including a type annotation is the same as `::Any`
|
coatcolor # not including a type annotation is the same as `::Any`
|
||||||
end
|
end
|
||||||
|
|
||||||
# The default constructor's arguments are the properties
|
# The default constructor's arguments are the properties
|
||||||
# of the type, in the order they are listed in the definition
|
# of the type, in the order they are listed in the definition
|
||||||
tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
|
tigger = Tiger(3.5, "orange") # => Tiger(3.5,"orange")
|
||||||
|
|
||||||
# The type doubles as the constructor function for values of that type
|
# The type doubles as the constructor function for values of that type
|
||||||
sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
|
sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6,"fire")
|
||||||
|
|
||||||
# These struct-style types are called concrete types
|
# These struct-style types are called concrete types
|
||||||
# They can be instantiated, but cannot have subtypes.
|
# They can be instantiated, but cannot have subtypes.
|
||||||
# The other kind of types is abstract types.
|
# The other kind of types is abstract types.
|
||||||
|
|
||||||
# abstract Name
|
# abstract Name
|
||||||
abstract type Cat end # just a name and point in the type hierarchy
|
abstract type Cat end # just a name and point in the type hierarchy
|
||||||
|
|
||||||
# Abstract types cannot be instantiated, but can have subtypes.
|
# Abstract types cannot be instantiated, but can have subtypes.
|
||||||
|
using InteractiveUtils # defines the subtype and supertype function
|
||||||
# For example, Number is an abstract type
|
# For example, Number is an abstract type
|
||||||
subtypes(Number) # => 2-element Array{Any,1}:
|
subtypes(Number) # => 2-element Array{Any,1}:
|
||||||
# Complex{T<:Real}
|
# Complex{T<:Real}
|
||||||
# Real
|
# Real
|
||||||
subtypes(Cat) # => 0-element Array{Any,1}
|
subtypes(Cat) # => 0-element Array{Any,1}
|
||||||
|
|
||||||
# AbstractString, as the name implies, is also an abstract type
|
# AbstractString, as the name implies, is also an abstract type
|
||||||
subtypes(AbstractString) # 6-element Array{Union{DataType, UnionAll},1}:
|
subtypes(AbstractString) # 4-element Array{Any,1}:
|
||||||
# Base.SubstitutionString
|
# String
|
||||||
# Base.Test.GenericString
|
# SubString
|
||||||
# DirectIndexString
|
# SubstitutionString
|
||||||
# RevString
|
# Test.GenericString
|
||||||
# String
|
|
||||||
# SubString
|
|
||||||
|
|
||||||
# Every type has a super type; use the `supertype` function to get it.
|
# Every type has a super type; use the `supertype` function to get it.
|
||||||
typeof(5) # => Int64
|
typeof(5) # => Int64
|
||||||
supertype(Int64) # => Signed
|
supertype(Int64) # => Signed
|
||||||
supertype(Signed) # => Integer
|
supertype(Signed) # => Integer
|
||||||
supertype(Integer) # => Real
|
supertype(Integer) # => Real
|
||||||
supertype(Real) # => Number
|
supertype(Real) # => Number
|
||||||
supertype(Number) # => Any
|
supertype(Number) # => Any
|
||||||
supertype(supertype(Signed)) # => Real
|
supertype(supertype(Signed)) # => Real
|
||||||
supertype(Any) # => Any
|
supertype(Any) # => Any
|
||||||
# All of these type, except for Int64, are abstract.
|
# All of these type, except for Int64, are abstract.
|
||||||
typeof("fire") # => String
|
typeof("fire") # => String
|
||||||
supertype(String) # => AbstractString
|
supertype(String) # => AbstractString
|
||||||
# Likewise here with String
|
# Likewise here with String
|
||||||
supertype(DirectIndexString) # => AbstractString
|
supertype(SubString) # => AbstractString
|
||||||
|
|
||||||
# <: is the subtyping operator
|
# <: is the subtyping operator
|
||||||
type Lion <: Cat # Lion is a subtype of Cat
|
struct Lion <: Cat # Lion is a subtype of Cat
|
||||||
mane_color
|
mane_color
|
||||||
roar::AbstractString
|
roar::AbstractString
|
||||||
end
|
end
|
||||||
|
|
||||||
# You can define more constructors for your type
|
# You can define more constructors for your type
|
||||||
# Just define a function of the same name as the type
|
# Just define a function of the same name as the type
|
||||||
# and call an existing constructor to get a value of the correct type
|
# and call an existing constructor to get a value of the correct type
|
||||||
Lion(roar::AbstractString) = Lion("green",roar)
|
Lion(roar::AbstractString) = Lion("green", roar)
|
||||||
# This is an outer constructor because it's outside the type definition
|
# This is an outer constructor because it's outside the type definition
|
||||||
|
|
||||||
type Panther <: Cat # Panther is also a subtype of Cat
|
struct Panther <: Cat # Panther is also a subtype of Cat
|
||||||
eye_color
|
eye_color
|
||||||
Panther() = new("green")
|
Panther() = new("green")
|
||||||
# Panthers will only have this constructor, and no default constructor.
|
# Panthers will only have this constructor, and no default constructor.
|
||||||
end
|
end
|
||||||
# Using inner constructors, like Panther does, gives you control
|
# Using inner constructors, like Panther does, gives you control
|
||||||
# over how values of the type can be created.
|
# over how values of the type can be created.
|
||||||
@@ -618,35 +613,35 @@ end
|
|||||||
|
|
||||||
# Definitions for Lion, Panther, Tiger
|
# Definitions for Lion, Panther, Tiger
|
||||||
function meow(animal::Lion)
|
function meow(animal::Lion)
|
||||||
animal.roar # access type properties using dot notation
|
animal.roar # access type properties using dot notation
|
||||||
end
|
end
|
||||||
|
|
||||||
function meow(animal::Panther)
|
function meow(animal::Panther)
|
||||||
"grrr"
|
"grrr"
|
||||||
end
|
end
|
||||||
|
|
||||||
function meow(animal::Tiger)
|
function meow(animal::Tiger)
|
||||||
"rawwwr"
|
"rawwwr"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Testing the meow function
|
# Testing the meow function
|
||||||
meow(tigger) # => "rawwr"
|
meow(tigger) # => "rawwr"
|
||||||
meow(Lion("brown","ROAAR")) # => "ROAAR"
|
meow(Lion("brown", "ROAAR")) # => "ROAAR"
|
||||||
meow(Panther()) # => "grrr"
|
meow(Panther()) # => "grrr"
|
||||||
|
|
||||||
# Review the local type hierarchy
|
# Review the local type hierarchy
|
||||||
issubtype(Tiger,Cat) # => false
|
Tiger <: Cat # => false
|
||||||
issubtype(Lion,Cat) # => true
|
Lion <: Cat # => true
|
||||||
issubtype(Panther,Cat) # => true
|
Panther <: Cat # => true
|
||||||
|
|
||||||
# Defining a function that takes Cats
|
# Defining a function that takes Cats
|
||||||
function pet_cat(cat::Cat)
|
function pet_cat(cat::Cat)
|
||||||
println("The cat says $(meow(cat))")
|
println("The cat says $(meow(cat))")
|
||||||
end
|
end
|
||||||
|
|
||||||
pet_cat(Lion("42")) # => prints "The cat says 42"
|
pet_cat(Lion("42")) # => prints "The cat says 42"
|
||||||
try
|
try
|
||||||
pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
|
pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
@@ -656,129 +651,132 @@ end
|
|||||||
# In Julia, all of the argument types contribute to selecting the best method.
|
# In Julia, all of the argument types contribute to selecting the best method.
|
||||||
|
|
||||||
# Let's define a function with more arguments, so we can see the difference
|
# Let's define a function with more arguments, so we can see the difference
|
||||||
function fight(t::Tiger,c::Cat)
|
function fight(t::Tiger, c::Cat)
|
||||||
println("The $(t.coatcolor) tiger wins!")
|
println("The $(t.coatcolor) tiger wins!")
|
||||||
end
|
end
|
||||||
# => fight (generic function with 1 method)
|
# => fight (generic function with 1 method)
|
||||||
|
|
||||||
fight(tigger,Panther()) # => prints The orange tiger wins!
|
fight(tigger, Panther()) # => prints The orange tiger wins!
|
||||||
fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
|
fight(tigger, Lion("ROAR")) # => prints The orange tiger wins!
|
||||||
|
|
||||||
# Let's change the behavior when the Cat is specifically a Lion
|
# Let's change the behavior when the Cat is specifically a Lion
|
||||||
fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
|
fight(t::Tiger, l::Lion) = println("The $(l.mane_color)-maned lion wins!")
|
||||||
# => fight (generic function with 2 methods)
|
# => fight (generic function with 2 methods)
|
||||||
|
|
||||||
fight(tigger,Panther()) # => prints The orange tiger wins!
|
fight(tigger, Panther()) # => prints The orange tiger wins!
|
||||||
fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
|
fight(tigger, Lion("ROAR")) # => prints The green-maned lion wins!
|
||||||
|
|
||||||
# We don't need a Tiger in order to fight
|
# We don't need a Tiger in order to fight
|
||||||
fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
|
fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))")
|
||||||
# => fight (generic function with 3 methods)
|
# => fight (generic function with 3 methods)
|
||||||
|
|
||||||
fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
|
fight(Lion("balooga!"), Panther()) # => prints The victorious cat says grrr
|
||||||
try
|
try
|
||||||
fight(Panther(),Lion("RAWR"))
|
fight(Panther(), Lion("RAWR"))
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
# => MethodError(fight, (Panther("green"), Lion("green", "RAWR")), 0x000000000000557b)
|
# => MethodError(fight, (Panther("green"), Lion("green", "RAWR")),
|
||||||
|
# 0x000000000000557b)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Also let the cat go first
|
# Also let the cat go first
|
||||||
fight(c::Cat,l::Lion) = println("The cat beats the Lion")
|
fight(c::Cat, l::Lion) = println("The cat beats the Lion")
|
||||||
|
|
||||||
# This warning is because it's unclear which fight will be called in:
|
# This warning is because it's unclear which fight will be called in:
|
||||||
try
|
try
|
||||||
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
|
fight(Lion("RAR"), Lion("brown", "rarrr"))
|
||||||
|
# => prints The victorious cat says rarrr
|
||||||
catch e
|
catch e
|
||||||
println(e)
|
println(e)
|
||||||
# => MethodError(fight, (Lion("green", "RAR"), Lion("brown", "rarrr")), 0x000000000000557c)
|
# => MethodError(fight, (Lion("green", "RAR"), Lion("brown", "rarrr")),
|
||||||
|
# 0x000000000000557c)
|
||||||
end
|
end
|
||||||
# The result may be different in other versions of Julia
|
# The result may be different in other versions of Julia
|
||||||
|
|
||||||
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
|
fight(l::Lion, l2::Lion) = println("The lions come to a tie")
|
||||||
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie
|
fight(Lion("RAR"), Lion("brown", "rarrr")) # => prints The lions come to a tie
|
||||||
|
|
||||||
|
|
||||||
# Under the hood
|
# Under the hood
|
||||||
# You can take a look at the llvm and the assembly code generated.
|
# You can take a look at the llvm and the assembly code generated.
|
||||||
|
|
||||||
square_area(l) = l * l # square_area (generic function with 1 method)
|
square_area(l) = l * l # square_area (generic function with 1 method)
|
||||||
|
|
||||||
square_area(5) #25
|
square_area(5) # => 25
|
||||||
|
|
||||||
# What happens when we feed square_area an integer?
|
# What happens when we feed square_area an integer?
|
||||||
code_native(square_area, (Int32,))
|
code_native(square_area, (Int32,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1 # Prologue
|
# Source line: 1 # Prologue
|
||||||
# push RBP
|
# push RBP
|
||||||
# mov RBP, RSP
|
# mov RBP, RSP
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# movsxd RAX, EDI # Fetch l from memory?
|
# movsxd RAX, EDI # Fetch l from memory?
|
||||||
# imul RAX, RAX # Square l and store the result in RAX
|
# imul RAX, RAX # Square l and store the result in RAX
|
||||||
# pop RBP # Restore old base pointer
|
# pop RBP # Restore old base pointer
|
||||||
# ret # Result will still be in RAX
|
# ret # Result will still be in RAX
|
||||||
|
|
||||||
code_native(square_area, (Float32,))
|
code_native(square_area, (Float32,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# push RBP
|
# push RBP
|
||||||
# mov RBP, RSP
|
# mov RBP, RSP
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
|
# vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
|
|
||||||
code_native(square_area, (Float64,))
|
code_native(square_area, (Float64,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# push RBP
|
# push RBP
|
||||||
# mov RBP, RSP
|
# mov RBP, RSP
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
|
# vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
#
|
#
|
||||||
# Note that julia will use floating point instructions if any of the
|
# Note that julia will use floating point instructions if any of the
|
||||||
# arguments are floats.
|
# arguments are floats.
|
||||||
# Let's calculate the area of a circle
|
# Let's calculate the area of a circle
|
||||||
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
|
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
|
||||||
circle_area(5) # 78.53981633974483
|
circle_area(5) # 78.53981633974483
|
||||||
|
|
||||||
code_native(circle_area, (Int32,))
|
code_native(circle_area, (Int32,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# push RBP
|
# push RBP
|
||||||
# mov RBP, RSP
|
# mov RBP, RSP
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
|
# vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
|
||||||
# movabs RAX, 4593140240 # Load pi
|
# movabs RAX, 4593140240 # Load pi
|
||||||
# vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
|
# vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
|
||||||
# vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
|
# vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
#
|
#
|
||||||
|
|
||||||
code_native(circle_area, (Float64,))
|
code_native(circle_area, (Float64,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# push RBP
|
# push RBP
|
||||||
# mov RBP, RSP
|
# mov RBP, RSP
|
||||||
# movabs RAX, 4593140496
|
# movabs RAX, 4593140496
|
||||||
# Source line: 1
|
# Source line: 1
|
||||||
# vmulsd XMM1, XMM0, QWORD PTR [RAX]
|
# vmulsd XMM1, XMM0, QWORD PTR [RAX]
|
||||||
# vmulsd XMM0, XMM1, XMM0
|
# vmulsd XMM0, XMM1, XMM0
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
#
|
#
|
||||||
```
|
```
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/#Manual-1)
|
You can get a lot more detail from the [Julia Documentation](https://docs.julialang.org/)
|
||||||
|
|
||||||
The best place to get help with Julia is the (very friendly) [Discourse forum](https://discourse.julialang.org/).
|
The best place to get help with Julia is the (very friendly) [Discourse forum](https://discourse.julialang.org/).
|
||||||
|
@@ -689,14 +689,14 @@ first each (1 2 3;4 5 6;7 8 9)
|
|||||||
|
|
||||||
/ each-left (\:) and each-right (/:) modify a two-argument function
|
/ each-left (\:) and each-right (/:) modify a two-argument function
|
||||||
/ to treat one of the arguments and individual variables instead of a list
|
/ to treat one of the arguments and individual variables instead of a list
|
||||||
1 2 3 +\: 1 2 3
|
1 2 3 +\: 11 22 33
|
||||||
/ => 2 3 4
|
/ => 12 23 34
|
||||||
/ => 3 4 5
|
/ => 13 24 35
|
||||||
/ => 4 5 6
|
/ => 14 25 36
|
||||||
1 2 3 +/: 1 2 3
|
1 2 3 +/: 11 22 33
|
||||||
/ => 2 3 4
|
/ => 12 13 14
|
||||||
/ => 3 4 5
|
/ => 23 24 25
|
||||||
/ => 4 5 6
|
/ => 34 35 36
|
||||||
|
|
||||||
/ The true alternatives to loops in q are the adverbs scan (\) and over (/)
|
/ The true alternatives to loops in q are the adverbs scan (\) and over (/)
|
||||||
/ their behaviour differs based on the number of arguments the function they
|
/ their behaviour differs based on the number of arguments the function they
|
||||||
|
@@ -25,7 +25,7 @@ lang: ko-kr
|
|||||||
|
|
||||||
## HTML 요소
|
## HTML 요소
|
||||||
HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다.
|
HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다.
|
||||||
```markdown
|
```md
|
||||||
<!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을
|
<!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을
|
||||||
받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는
|
받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는
|
||||||
마크다운 문법을 사용할 수 없습니다.-->
|
마크다운 문법을 사용할 수 없습니다.-->
|
||||||
|
@@ -197,7 +197,7 @@ inside your code
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
Inline code can be created using the backtick character `
|
Inline code can be created using the backtick character `` ` ``
|
||||||
|
|
||||||
```md
|
```md
|
||||||
John didn't even know what the `go_to()` function did!
|
John didn't even know what the `go_to()` function did!
|
||||||
|
366
mips.html.markdown
Normal file
366
mips.html.markdown
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
---
|
||||||
|
language: "MIPS Assembly"
|
||||||
|
filename: MIPS.asm
|
||||||
|
contributors:
|
||||||
|
- ["Stanley Lim", "https://github.com/Spiderpig86"]
|
||||||
|
---
|
||||||
|
|
||||||
|
The MIPS (Microprocessor without Interlocked Pipeline Stages) Assembly language
|
||||||
|
is designed to work with the MIPS microprocessor paradigm designed by J. L.
|
||||||
|
Hennessy in 1981. These RISC processors are used in embedded systems such as
|
||||||
|
gateways and routers.
|
||||||
|
|
||||||
|
[Read More](https://en.wikipedia.org/wiki/MIPS_architecture)
|
||||||
|
|
||||||
|
```assembly
|
||||||
|
# Comments are denoted with a '#'
|
||||||
|
|
||||||
|
# Everything that occurs after a '#' will be ignored by the assembler's lexer.
|
||||||
|
|
||||||
|
# Programs typically contain a .data and .text sections
|
||||||
|
|
||||||
|
.data # Section where data is stored in memory (allocated in RAM), similar to
|
||||||
|
# variables in higher level languages
|
||||||
|
|
||||||
|
# Declarations follow a ( label: .type value(s) ) form of declaration
|
||||||
|
hello_world: .asciiz "Hello World\n" # Declare a null terminated string
|
||||||
|
num1: .word 42 # Integers are referred to as words
|
||||||
|
# (32 bit value)
|
||||||
|
|
||||||
|
arr1: .word 1, 2, 3, 4, 5 # Array of words
|
||||||
|
arr2: .byte 'a', 'b' # Array of chars (1 byte each)
|
||||||
|
buffer: .space 60 # Allocates space in the RAM
|
||||||
|
# (not cleared to 0)
|
||||||
|
|
||||||
|
# Datatype sizes
|
||||||
|
_byte: .byte 'a' # 1 byte
|
||||||
|
_halfword: .half 53 # 2 bytes
|
||||||
|
_word: .word 3 # 4 bytes
|
||||||
|
_float: .float 3.14 # 4 bytes
|
||||||
|
_double: .double 7.0 # 8 bytes
|
||||||
|
|
||||||
|
.align 2 # Memory alignment of data, where
|
||||||
|
# number indicates byte alignment in
|
||||||
|
# powers of 2. (.align 2 represents
|
||||||
|
# word alignment since 2^2 = 4 bytes)
|
||||||
|
|
||||||
|
.text # Section that contains instructions
|
||||||
|
# and program logic
|
||||||
|
.globl _main # Declares an instruction label as
|
||||||
|
# global, making it accessible to
|
||||||
|
# other files
|
||||||
|
|
||||||
|
_main: # MIPS programs execute instructions
|
||||||
|
# sequentially, where the code under
|
||||||
|
# this label will be executed firsts
|
||||||
|
|
||||||
|
# Let's print "hello world"
|
||||||
|
la $a0, hello_world # Load address of string stored in
|
||||||
|
# memory
|
||||||
|
li $v0, 4 # Load the syscall value (indicating
|
||||||
|
# type of functionality)
|
||||||
|
syscall # Perform the specified syscall with
|
||||||
|
# the given argument ($a0)
|
||||||
|
|
||||||
|
# Registers (used to hold data during program execution)
|
||||||
|
# $t0 - $t9 # Temporary registers used for
|
||||||
|
# intermediate calculations inside
|
||||||
|
# subroutines (not saved across
|
||||||
|
# function calls)
|
||||||
|
|
||||||
|
# $s0 - $s7 # Saved registers where values are
|
||||||
|
# saved across subroutine calls.
|
||||||
|
# Typically saved in stack
|
||||||
|
|
||||||
|
# $a0 - $a3 # Argument registers for passing in
|
||||||
|
# arguments for subroutines
|
||||||
|
# $v0 - $v1 # Return registers for returning
|
||||||
|
# values to caller function
|
||||||
|
|
||||||
|
# Types of load/store instructions
|
||||||
|
la $t0, label # Copy the address of a value in
|
||||||
|
# memory specified by the label into
|
||||||
|
# register $t0
|
||||||
|
lw $t0, label # Copy a word value from memory
|
||||||
|
lw $t1, 4($s0) # Copy a word value from an address
|
||||||
|
# stored in a register with an offset
|
||||||
|
# of 4 bytes (addr + 4)
|
||||||
|
lb $t2, label # Copy a byte value to the lower order
|
||||||
|
# portion of the register $t2
|
||||||
|
lb $t2, 0($s0) # Copy a byte value from the source
|
||||||
|
# address in $s0 with offset 0
|
||||||
|
# Same idea with 'lh' for halfwords
|
||||||
|
|
||||||
|
sw $t0, label # Store word value into memory address
|
||||||
|
# mapped by label
|
||||||
|
sw $t0, 8($s0) # Store word value into address
|
||||||
|
# specified in $s0 and offset of 8 bytes
|
||||||
|
# Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist
|
||||||
|
|
||||||
|
### Math ###
|
||||||
|
_math:
|
||||||
|
# Remember to load your values into a register
|
||||||
|
lw $t0, num # From the data section
|
||||||
|
li $t0, 5 # Or from an immediate (constant)
|
||||||
|
li $t1, 6
|
||||||
|
add $t2, $t0, $t1 # $t2 = $t0 + $t1
|
||||||
|
sub $t2, $t0, $t1 # $t2 = $t0 - $t1
|
||||||
|
mul $t2, $t0, $t1 # $t2 = $t0 * $t1
|
||||||
|
div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Might not be
|
||||||
|
# supported in some versons of MARS)
|
||||||
|
div $t0, $t1 # Performs $t0 / $t1. Get the quotient
|
||||||
|
# using 'mflo' and remainder using 'mfhi'
|
||||||
|
|
||||||
|
# Bitwise Shifting
|
||||||
|
sll $t0, $t0, 2 # Bitwise shift to the left with
|
||||||
|
# immediate (constant value) of 2
|
||||||
|
sllv $t0, $t1, $t2 # Shift left by a variable amount in
|
||||||
|
# register
|
||||||
|
srl $t0, $t0, 5 # Bitwise shift to the right (does
|
||||||
|
# not sign preserve, sign-extends with 0)
|
||||||
|
srlv $t0, $t1, $t2 # Shift right by a variable amount in
|
||||||
|
# a register
|
||||||
|
sra $t0, $t0, 7 # Bitwise arithmetic shift to the right
|
||||||
|
# (preserves sign)
|
||||||
|
srav $t0, $t1, $t2 # Shift right by a variable amount
|
||||||
|
# in a register
|
||||||
|
|
||||||
|
# Bitwise operators
|
||||||
|
and $t0, $t1, $t2 # Bitwise AND
|
||||||
|
andi $t0, $t1, 0xFFF # Bitwise AND with immediate
|
||||||
|
or $t0, $t1, $t2 # Bitwise OR
|
||||||
|
ori $t0, $t1, 0xFFF # Bitwise OR with immediate
|
||||||
|
xor $t0, $t1, $t2 # Bitwise XOR
|
||||||
|
xori $t0, $t1, 0xFFF # Bitwise XOR with immediate
|
||||||
|
nor $t0, $t1, $t2 # Bitwise NOR
|
||||||
|
|
||||||
|
## BRANCHING ##
|
||||||
|
_branching:
|
||||||
|
# The basic format of these branching instructions typically follow <instr>
|
||||||
|
# <reg1> <reg2> <label> where label is the label we want to jump to if the
|
||||||
|
# given conditional evaluates to true
|
||||||
|
# Sometimes it is easier to write the conditional logic backwards, as seen
|
||||||
|
# in the simple if statement example below
|
||||||
|
|
||||||
|
beq $t0, $t1, reg_eq # Will branch to reg_eq if
|
||||||
|
# $t0 == $t1, otherwise
|
||||||
|
# execute the next line
|
||||||
|
bne $t0, $t1, reg_neq # Branches when $t0 != $t1
|
||||||
|
b branch_target # Unconditional branch, will always execute
|
||||||
|
beqz $t0, req_eq_zero # Branches when $t0 == 0
|
||||||
|
bnez $t0, req_neq_zero # Branches when $t0 != 0
|
||||||
|
bgt $t0, $t1, t0_gt_t1 # Branches when $t0 > $t1
|
||||||
|
bge $t0, $t1, t0_gte_t1 # Branches when $t0 >= $t1
|
||||||
|
bgtz $t0, t0_gt0 # Branches when $t0 > 0
|
||||||
|
blt $t0, $t1, t0_gt_t1 # Branches when $t0 < $t1
|
||||||
|
ble $t0, $t1, t0_gte_t1 # Branches when $t0 <= $t1
|
||||||
|
bltz $t0, t0_lt0 # Branches when $t0 < 0
|
||||||
|
slt $s0, $t0, $t1 # Instruction that sends a signal when
|
||||||
|
# $t0 < $t1 with reuslt in $s0 (1 for true)
|
||||||
|
|
||||||
|
# Simple if statement
|
||||||
|
# if (i == j)
|
||||||
|
# f = g + h;
|
||||||
|
# f = f - i;
|
||||||
|
|
||||||
|
# Let $s0 = f, $s1 = g, $s2 = h, $s3 = i, $s4 = j
|
||||||
|
bne $s3, $s4, L1 # if (i !=j)
|
||||||
|
add $s0, $s1, $s2 # f = g + h
|
||||||
|
|
||||||
|
L1:
|
||||||
|
sub $s0, $s0, $s3 # f = f - i
|
||||||
|
|
||||||
|
# Below is an example of finding the max of 3 numbers
|
||||||
|
# A direct translation in Java from MIPS logic:
|
||||||
|
# if (a > b)
|
||||||
|
# if (a > c)
|
||||||
|
# max = a;
|
||||||
|
# else
|
||||||
|
# max = c;
|
||||||
|
# else
|
||||||
|
# max = b;
|
||||||
|
# else
|
||||||
|
# max = c;
|
||||||
|
|
||||||
|
# Let $s0 = a, $s1 = b, $s2 = c, $v0 = return register
|
||||||
|
ble $s0, $s1, a_LTE_b # if (a <= b) branch(a_LTE_b)
|
||||||
|
ble $s0, $s2, max_C # if (a > b && a <=c) branch(max_C)
|
||||||
|
move $v0, $s1 # else [a > b && a > c] max = a
|
||||||
|
j done # Jump to the end of the program
|
||||||
|
|
||||||
|
a_LTE_b: # Label for when a <= b
|
||||||
|
ble $s1, $s2, max_C # if (a <= b && b <= c) branch(max_C)
|
||||||
|
move $v0, $s1 # if (a <= b && b > c) max = b
|
||||||
|
j done # Jump to done
|
||||||
|
|
||||||
|
max_C:
|
||||||
|
move $v0, $s2 # max = c
|
||||||
|
|
||||||
|
done: # End of program
|
||||||
|
|
||||||
|
## LOOPS ##
|
||||||
|
_loops:
|
||||||
|
# The basic structure of loops is having an exit condition and a jump
|
||||||
|
instruction to continue its execution
|
||||||
|
li $t0, 0
|
||||||
|
while:
|
||||||
|
bgt $t0, 10, end_while # While $t0 is less than 10, keep iterating
|
||||||
|
addi $t0, $t0, 1 # Increment the value
|
||||||
|
j while # Jump back to the beginning of the loop
|
||||||
|
end_while:
|
||||||
|
|
||||||
|
# 2D Matrix Traversal
|
||||||
|
# Assume that $a0 stores the address of an integer matrix which is 3 x 3
|
||||||
|
li $t0, 0 # Counter for i
|
||||||
|
li $t1, 0 # Counter for j
|
||||||
|
matrix_row:
|
||||||
|
bgt $t0, 3, matrix_row_end
|
||||||
|
|
||||||
|
matrix_col:
|
||||||
|
bgt $t1, 3, matrix_col_end
|
||||||
|
|
||||||
|
# Do stuff
|
||||||
|
|
||||||
|
addi $t1, $t1, 1 # Increment the col counter
|
||||||
|
matrix_col_end:
|
||||||
|
|
||||||
|
# Do stuff
|
||||||
|
|
||||||
|
addi $t0, $t0, 1
|
||||||
|
matrix_row_end:
|
||||||
|
|
||||||
|
## FUNCTIONS ##
|
||||||
|
_functions:
|
||||||
|
# Functions are callable procedures that can accept arguments and return
|
||||||
|
values all denoted with labels, like above
|
||||||
|
|
||||||
|
main: # Programs begin with main func
|
||||||
|
jal return_1 # jal will store the current PC in $ra
|
||||||
|
# and then jump to return_1
|
||||||
|
|
||||||
|
# What if we want to pass in args?
|
||||||
|
# First we must pass in our parameters to the argument registers
|
||||||
|
li $a0, 1
|
||||||
|
li $a1, 2
|
||||||
|
jal sum # Now we can call the function
|
||||||
|
|
||||||
|
# How about recursion?
|
||||||
|
# This is a bit more work since we need to make sure we save and restore
|
||||||
|
# the previous PC in $ra since jal will automatically overwrite on each call
|
||||||
|
li $a0, 3
|
||||||
|
jal fact
|
||||||
|
|
||||||
|
li $v0, 10
|
||||||
|
syscall
|
||||||
|
|
||||||
|
# This function returns 1
|
||||||
|
return_1:
|
||||||
|
li $v0, 1 # Load val in return register $v0
|
||||||
|
jr $ra # Jump back to old PC to continue exec
|
||||||
|
|
||||||
|
|
||||||
|
# Function with 2 args
|
||||||
|
sum:
|
||||||
|
add $v0, $a0, $a1
|
||||||
|
jr $ra # Return
|
||||||
|
|
||||||
|
# Recursive function to find factorial
|
||||||
|
fact:
|
||||||
|
addi $sp, $sp, -8 # Allocate space in stack
|
||||||
|
sw $s0, ($sp) # Store reg that holds current num
|
||||||
|
sw $ra, 4($sp) # Store previous PC
|
||||||
|
|
||||||
|
li $v0, 1 # Init return value
|
||||||
|
beq $a0, 0, fact_done # Finish if param is 0
|
||||||
|
|
||||||
|
# Otherwise, continue recursion
|
||||||
|
move $s0, $a0 # Copy $a0 to $s0
|
||||||
|
sub $a0, $a0, 1
|
||||||
|
jal fact
|
||||||
|
|
||||||
|
mul $v0, $s0, $v0 # Multiplication is done
|
||||||
|
|
||||||
|
fact_done:
|
||||||
|
lw $s0, ($sp)
|
||||||
|
lw $ra, ($sp) # Restore the PC
|
||||||
|
addi $sp, $sp, 8
|
||||||
|
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
## MACROS ##
|
||||||
|
_macros:
|
||||||
|
# Macros are extremly useful for substituting repeated code blocks with a
|
||||||
|
# single label for better readability
|
||||||
|
# These are in no means substitutes for functions
|
||||||
|
# These must be declared before it is used
|
||||||
|
|
||||||
|
# Macro for printing new lines (since these can be very repetitive)
|
||||||
|
.macro println()
|
||||||
|
la $a0, newline # New line string stored here
|
||||||
|
li $v0, 4
|
||||||
|
syscall
|
||||||
|
.end_macro
|
||||||
|
|
||||||
|
println() # Assembler will copy that block of
|
||||||
|
# code here before running
|
||||||
|
|
||||||
|
# Parameters can be passed in through macros.
|
||||||
|
# These are denoted by a '%' sign with any name you choose
|
||||||
|
.macro print_int(%num)
|
||||||
|
li $v0, 1
|
||||||
|
lw $a0, %num
|
||||||
|
syscall
|
||||||
|
.end_macro
|
||||||
|
|
||||||
|
li $t0, 1
|
||||||
|
print_int($t0)
|
||||||
|
|
||||||
|
# We can also pass in immediates for macros
|
||||||
|
.macro immediates(%a, %b)
|
||||||
|
add $t0, %a, %b
|
||||||
|
.end_macro
|
||||||
|
|
||||||
|
immediates(3, 5)
|
||||||
|
|
||||||
|
# Along with passing in labels
|
||||||
|
.macro print(%string)
|
||||||
|
la $a0, %string
|
||||||
|
li $v0, 4
|
||||||
|
syscall
|
||||||
|
.end_macro
|
||||||
|
|
||||||
|
print(hello_world)
|
||||||
|
|
||||||
|
## ARRAYS ##
|
||||||
|
.data
|
||||||
|
list: .word 3, 0, 1, 2, 6 # This is an array of words
|
||||||
|
char_arr: .asciiz "hello" # This is a char array
|
||||||
|
buffer: .space 128 # Allocates a block in memory, does
|
||||||
|
# not automatically clear
|
||||||
|
# These blocks of memory are aligned
|
||||||
|
# next each other
|
||||||
|
|
||||||
|
.text
|
||||||
|
la $s0, list # Load address of list
|
||||||
|
li $t0, 0 # Counter
|
||||||
|
li $t1, 5 # Length of the list
|
||||||
|
|
||||||
|
loop:
|
||||||
|
bgt $t0, $t1, end_loop
|
||||||
|
|
||||||
|
lw $a0, ($s0)
|
||||||
|
li $v0, 1
|
||||||
|
syscall # Print the number
|
||||||
|
|
||||||
|
addi $s0, $s0, 4 # Size of a word is 4 bytes
|
||||||
|
addi $t0, $t0, 1 # Increment
|
||||||
|
j loop
|
||||||
|
end_loop:
|
||||||
|
|
||||||
|
## INCLUDE ##
|
||||||
|
# You do this to import external files into your program (behind the scenes,
|
||||||
|
# it really just takes whatever code that is in that file and places it where
|
||||||
|
# the include statement is)
|
||||||
|
.include "somefile.asm"
|
||||||
|
|
||||||
|
```
|
@@ -12,7 +12,7 @@ Markdown is gecreëerd door John Gruber in 2004. Het is bedoeld om met een gemak
|
|||||||
schrijven syntax te zijn die gemakkelijk omgevormd kan worden naar HTML (en op heden verschillende
|
schrijven syntax te zijn die gemakkelijk omgevormd kan worden naar HTML (en op heden verschillende
|
||||||
andere formaten)
|
andere formaten)
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown erft over van HTML, dus ieder HTML bestand is een geldig Markdown
|
<!-- Markdown erft over van HTML, dus ieder HTML bestand is een geldig Markdown
|
||||||
bestand. Dit betekend ook dat html elementen gebruikt kunnen worden in Markdown
|
bestand. Dit betekend ook dat html elementen gebruikt kunnen worden in Markdown
|
||||||
zoals het commentaar element. Echter, als je een html element maakt in een Markdown
|
zoals het commentaar element. Echter, als je een html element maakt in een Markdown
|
||||||
|
@@ -19,7 +19,7 @@ Outro livro recente e popular é o
|
|||||||
[Land of Lisp](http://landoflisp.com/).
|
[Land of Lisp](http://landoflisp.com/).
|
||||||
|
|
||||||
|
|
||||||
```common-lisp
|
```lisp
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; 0. Sintaxe
|
;;; 0. Sintaxe
|
||||||
|
@@ -14,7 +14,7 @@ escrever sintaxe que converte facilmente em HTML (hoje, suporta outros formatos
|
|||||||
Dê-me feedback tanto quanto você quiser! / Sinta-se livre para a garfar (fork) e
|
Dê-me feedback tanto quanto você quiser! / Sinta-se livre para a garfar (fork) e
|
||||||
puxar o projeto (pull request)
|
puxar o projeto (pull request)
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é
|
<!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é
|
||||||
um arquivo Markdown válido, isso significa que nós podemos usar elementos HTML
|
um arquivo Markdown válido, isso significa que nós podemos usar elementos HTML
|
||||||
em Markdown, como o elemento de comentário, e eles não serão afetados pelo analisador
|
em Markdown, como o elemento de comentário, e eles não serão afetados pelo analisador
|
||||||
|
@@ -8,7 +8,7 @@ lang: pt-br
|
|||||||
filename: learnvisualbasic-pt.vb
|
filename: learnvisualbasic-pt.vb
|
||||||
---
|
---
|
||||||
|
|
||||||
```vb
|
```
|
||||||
Module Module1
|
Module Module1
|
||||||
|
|
||||||
module Module1
|
module Module1
|
||||||
|
@@ -7,6 +7,7 @@ contributors:
|
|||||||
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
||||||
- ["evuez", "http://github.com/evuez"]
|
- ["evuez", "http://github.com/evuez"]
|
||||||
- ["Rommel Martinez", "https://ebzzry.io"]
|
- ["Rommel Martinez", "https://ebzzry.io"]
|
||||||
|
- ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
|
||||||
filename: learnpython3.py
|
filename: learnpython3.py
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -352,6 +353,8 @@ valid_set = {(1,), 1}
|
|||||||
# Add one more item to the set
|
# Add one more item to the set
|
||||||
filled_set = some_set
|
filled_set = some_set
|
||||||
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
|
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
|
||||||
|
# Sets do not have duplicate elements
|
||||||
|
filled_set.add(5) # it remains as before {1, 2, 3, 4, 5}
|
||||||
|
|
||||||
# Do set intersection with &
|
# Do set intersection with &
|
||||||
other_set = {3, 4, 5, 6}
|
other_set = {3, 4, 5, 6}
|
||||||
|
@@ -36,7 +36,7 @@ lang: ru-ru
|
|||||||
Markdown является надмножеством HTML, поэтому любой HTML-файл является
|
Markdown является надмножеством HTML, поэтому любой HTML-файл является
|
||||||
корректным документом Markdown.
|
корректным документом Markdown.
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Это позволяет использовать напрямую
|
<!-- Это позволяет использовать напрямую
|
||||||
любые элементы HTML-разметки, такие, например, как этот комментарий.
|
любые элементы HTML-разметки, такие, например, как этот комментарий.
|
||||||
Встроенные в документ HTML-элементы не затрагиваются парсером Markdown
|
Встроенные в документ HTML-элементы не затрагиваются парсером Markdown
|
||||||
|
@@ -16,19 +16,20 @@ contributors:
|
|||||||
- ["Persa Zula", "http://persazula.com"]
|
- ["Persa Zula", "http://persazula.com"]
|
||||||
- ["Jake Faris", "https://github.com/farisj"]
|
- ["Jake Faris", "https://github.com/farisj"]
|
||||||
- ["Corey Ward", "https://github.com/coreyward"]
|
- ["Corey Ward", "https://github.com/coreyward"]
|
||||||
|
- ["Jannik Siebert", "https://github.com/janniks"]
|
||||||
---
|
---
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# This is a comment
|
# This is a comment
|
||||||
|
|
||||||
# In Ruby, (almost) everything is an object.
|
# In Ruby, (almost) everything is an object.
|
||||||
# This includes numbers…
|
# This includes numbers...
|
||||||
3.class #=> Integer
|
3.class #=> Integer
|
||||||
|
|
||||||
# …strings…
|
# ...and strings...
|
||||||
"Hello".class #=> String
|
"Hello".class #=> String
|
||||||
|
|
||||||
# …even methods!
|
# ...and even methods!
|
||||||
"Hello".method(:class).class #=> Method
|
"Hello".method(:class).class #=> Method
|
||||||
|
|
||||||
# Some basic arithmetic
|
# Some basic arithmetic
|
||||||
@@ -67,7 +68,7 @@ false.class #=> FalseClass
|
|||||||
1 != 1 #=> false
|
1 != 1 #=> false
|
||||||
2 != 1 #=> true
|
2 != 1 #=> true
|
||||||
|
|
||||||
# apart from false itself, nil is the only other 'falsey' value
|
# Apart from false itself, nil is the only other 'falsey' value
|
||||||
|
|
||||||
!!nil #=> false
|
!!nil #=> false
|
||||||
!!false #=> false
|
!!false #=> false
|
||||||
@@ -111,33 +112,33 @@ placeholder = 'use string interpolation'
|
|||||||
'hello ' + 3.to_s #=> "hello 3"
|
'hello ' + 3.to_s #=> "hello 3"
|
||||||
"hello #{3}" #=> "hello 3"
|
"hello #{3}" #=> "hello 3"
|
||||||
|
|
||||||
# Combine strings and operators
|
# ...or combine strings and operators
|
||||||
'hello ' * 3 #=> "hello hello hello "
|
'hello ' * 3 #=> "hello hello hello "
|
||||||
|
|
||||||
# Append to string
|
# ...or append to string
|
||||||
'hello' << ' world' #=> "hello world"
|
'hello' << ' world' #=> "hello world"
|
||||||
|
|
||||||
# print to the output with a newline at the end
|
# You can print to the output with a newline at the end
|
||||||
puts "I'm printing!"
|
puts "I'm printing!"
|
||||||
#=> I'm printing!
|
#=> I'm printing!
|
||||||
#=> nil
|
#=> nil
|
||||||
|
|
||||||
# print to the output without a newline
|
# ...or print to the output without a newline
|
||||||
print "I'm printing!"
|
print "I'm printing!"
|
||||||
#=> I'm printing! => nil
|
#=> "I'm printing!" => nil
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
x = 25 #=> 25
|
x = 25 #=> 25
|
||||||
x #=> 25
|
x #=> 25
|
||||||
|
|
||||||
# Note that assignment returns the value assigned
|
# Note that assignment returns the value assigned.
|
||||||
# This means you can do multiple assignment:
|
# This means you can do multiple assignment.
|
||||||
|
|
||||||
x = y = 10 #=> 10
|
x = y = 10 #=> 10
|
||||||
x #=> 10
|
x #=> 10
|
||||||
y #=> 10
|
y #=> 10
|
||||||
|
|
||||||
# By convention, use snake_case for variable names
|
# By convention, use snake_case for variable names.
|
||||||
snake_case = true
|
snake_case = true
|
||||||
|
|
||||||
# Use descriptive variable names
|
# Use descriptive variable names
|
||||||
@@ -146,7 +147,7 @@ m = '/bad/name/'
|
|||||||
|
|
||||||
# Symbols are immutable, reusable constants represented internally by an
|
# Symbols are immutable, reusable constants represented internally by an
|
||||||
# integer value. They're often used instead of strings to efficiently convey
|
# integer value. They're often used instead of strings to efficiently convey
|
||||||
# specific, meaningful values
|
# specific, meaningful values.
|
||||||
|
|
||||||
:pending.class #=> Symbol
|
:pending.class #=> Symbol
|
||||||
|
|
||||||
@@ -158,82 +159,82 @@ status == 'pending' #=> false
|
|||||||
|
|
||||||
status == :approved #=> false
|
status == :approved #=> false
|
||||||
|
|
||||||
Strings can be converted into symbols and vice versa:
|
# Strings can be converted into symbols and vice versa.
|
||||||
|
|
||||||
status.to_s #=> "pending"
|
status.to_s #=> "pending"
|
||||||
"argon".to_sym #=> :argon
|
"argon".to_sym #=> :argon
|
||||||
|
|
||||||
# Arrays
|
# Arrays
|
||||||
|
|
||||||
# This is an array
|
# This is an array.
|
||||||
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
# Arrays can contain different types of items
|
# Arrays can contain different types of items.
|
||||||
|
|
||||||
[1, 'hello', false] #=> [1, "hello", false]
|
[1, 'hello', false] #=> [1, "hello", false]
|
||||||
|
|
||||||
# Arrays can be indexed
|
# Arrays can be indexed.
|
||||||
# From the front
|
# From the front...
|
||||||
array[0] #=> 1
|
array[0] #=> 1
|
||||||
array.first #=> 1
|
array.first #=> 1
|
||||||
array[12] #=> nil
|
array[12] #=> nil
|
||||||
|
|
||||||
# Like arithmetic, [var] access
|
# ...or from the back...
|
||||||
# is just syntactic sugar
|
|
||||||
# for calling a method [] on an object
|
|
||||||
array.[] 0 #=> 1
|
|
||||||
array.[] 12 #=> nil
|
|
||||||
|
|
||||||
# From the end
|
|
||||||
array[-1] #=> 5
|
array[-1] #=> 5
|
||||||
array.last #=> 5
|
array.last #=> 5
|
||||||
|
|
||||||
# With a start index and length
|
# ...or with a start index and length...
|
||||||
array[2, 3] #=> [3, 4, 5]
|
array[2, 3] #=> [3, 4, 5]
|
||||||
|
|
||||||
# Reverse an Array
|
# ...or with a range...
|
||||||
|
array[1..3] #=> [2, 3, 4]
|
||||||
|
|
||||||
|
# You can reverse an Array.
|
||||||
a = [1,2,3]
|
a = [1,2,3]
|
||||||
a.reverse! #=> [3,2,1]
|
a.reverse! #=> [3,2,1]
|
||||||
|
|
||||||
# Or with a range
|
# Like arithmetic, [var] access is just syntactic sugar
|
||||||
array[1..3] #=> [2, 3, 4]
|
# for calling a method '[]' on an object.
|
||||||
|
array.[] 0 #=> 1
|
||||||
|
array.[] 12 #=> nil
|
||||||
|
|
||||||
# Add to an array like this
|
# You can add to an array...
|
||||||
array << 6 #=> [1, 2, 3, 4, 5, 6]
|
array << 6 #=> [1, 2, 3, 4, 5, 6]
|
||||||
# Or like this
|
# Or like this
|
||||||
array.push(6) #=> [1, 2, 3, 4, 5, 6]
|
array.push(6) #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
# Check if an item exists in an array
|
# ...and check if an item exists in an array
|
||||||
array.include?(1) #=> true
|
array.include?(1) #=> true
|
||||||
|
|
||||||
# Hashes are Ruby's primary dictionary with key/value pairs.
|
# Hashes are Ruby's primary dictionary with key/value pairs.
|
||||||
# Hashes are denoted with curly braces:
|
# Hashes are denoted with curly braces.
|
||||||
hash = { 'color' => 'green', 'number' => 5 }
|
hash = { 'color' => 'green', 'number' => 5 }
|
||||||
|
|
||||||
hash.keys #=> ['color', 'number']
|
hash.keys #=> ['color', 'number']
|
||||||
|
|
||||||
# Hashes can be quickly looked up by key:
|
# Hashes can be quickly looked up by key.
|
||||||
hash['color'] #=> 'green'
|
hash['color'] #=> "green"
|
||||||
hash['number'] #=> 5
|
hash['number'] #=> 5
|
||||||
|
|
||||||
# Asking a hash for a key that doesn't exist returns nil:
|
# Asking a hash for a key that doesn't exist returns nil.
|
||||||
hash['nothing here'] #=> nil
|
hash['nothing here'] #=> nil
|
||||||
|
|
||||||
# When using symbols for keys in a hash, you can use this alternate syntax:
|
# When using symbols for keys in a hash, you can use an alternate syntax.
|
||||||
|
|
||||||
new_hash = { defcon: 3, action: true }
|
hash = { :defcon => 3, :action => true }
|
||||||
|
hash.keys #=> [:defcon, :action]
|
||||||
|
|
||||||
new_hash.keys #=> [:defcon, :action]
|
hash = { defcon: 3, action: true }
|
||||||
|
hash.keys #=> [:defcon, :action]
|
||||||
|
|
||||||
# Check existence of keys and values in hash
|
# Check existence of keys and values in hash
|
||||||
new_hash.key?(:defcon) #=> true
|
hash.key?(:defcon) #=> true
|
||||||
new_hash.value?(3) #=> true
|
hash.value?(3) #=> true
|
||||||
|
|
||||||
# Tip: Both Arrays and Hashes are Enumerable
|
# Tip: Both Arrays and Hashes are Enumerable!
|
||||||
# They share a lot of useful methods such as each, map, count, and more
|
# They share a lot of useful methods such as each, map, count, and more.
|
||||||
|
|
||||||
# Control structures
|
# Control structures
|
||||||
|
|
||||||
|
# Conditionals
|
||||||
if true
|
if true
|
||||||
'if statement'
|
'if statement'
|
||||||
elsif false
|
elsif false
|
||||||
@@ -242,28 +243,26 @@ else
|
|||||||
'else, also optional'
|
'else, also optional'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loops
|
||||||
# In Ruby, traditional `for` loops aren't very common. Instead, these
|
# In Ruby, traditional `for` loops aren't very common. Instead, these
|
||||||
# basic loops are implemented using enumerable, which hinges on `each`:
|
# basic loops are implemented using enumerable, which hinges on `each`.
|
||||||
|
|
||||||
(1..5).each do |counter|
|
(1..5).each do |counter|
|
||||||
puts "iteration #{counter}"
|
puts "iteration #{counter}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Which is roughly equivalent to this, which is unusual to see in Ruby:
|
# Which is roughly equivalent to the following, which is unusual to see in Ruby.
|
||||||
|
|
||||||
for counter in 1..5
|
for counter in 1..5
|
||||||
puts "iteration #{counter}"
|
puts "iteration #{counter}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# The `do |variable| ... end` construct above is called a “block”. Blocks are similar
|
# The `do |variable| ... end` construct above is called a 'block'. Blocks are similar
|
||||||
# to lambdas, anonymous functions or closures in other programming languages. They can
|
# to lambdas, anonymous functions or closures in other programming languages. They can
|
||||||
# be passed around as objects, called, or attached as methods.
|
# be passed around as objects, called, or attached as methods.
|
||||||
#
|
#
|
||||||
# The "each" method of a range runs the block once for each element of the range.
|
# The 'each' method of a range runs the block once for each element of the range.
|
||||||
# The block is passed a counter as a parameter.
|
# The block is passed a counter as a parameter.
|
||||||
|
|
||||||
# You can also surround blocks in curly brackets:
|
# You can also surround blocks in curly brackets.
|
||||||
(1..5).each { |counter| puts "iteration #{counter}" }
|
(1..5).each { |counter| puts "iteration #{counter}" }
|
||||||
|
|
||||||
# The contents of data structures can also be iterated using each.
|
# The contents of data structures can also be iterated using each.
|
||||||
@@ -274,8 +273,8 @@ hash.each do |key, value|
|
|||||||
puts "#{key} is #{value}"
|
puts "#{key} is #{value}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# If you still need an index you can use "each_with_index" and define an index
|
# If you still need an index you can use 'each_with_index' and define an index
|
||||||
# variable
|
# variable.
|
||||||
array.each_with_index do |element, index|
|
array.each_with_index do |element, index|
|
||||||
puts "#{element} is number #{index} in the array"
|
puts "#{element} is number #{index} in the array"
|
||||||
end
|
end
|
||||||
@@ -291,9 +290,9 @@ end
|
|||||||
#=> iteration 4
|
#=> iteration 4
|
||||||
#=> iteration 5
|
#=> iteration 5
|
||||||
|
|
||||||
# There are a bunch of other helpful looping functions in Ruby,
|
# There are a bunch of other helpful looping functions in Ruby.
|
||||||
# for example "map", "reduce", "inject", the list goes on. Map,
|
# For example: 'map', 'reduce', 'inject', the list goes on.
|
||||||
# for instance, takes the array it's looping over, does something
|
# Map, for instance, takes the array it's looping over, does something
|
||||||
# to it as defined in your block, and returns an entirely new array.
|
# to it as defined in your block, and returns an entirely new array.
|
||||||
array = [1,2,3,4,5]
|
array = [1,2,3,4,5]
|
||||||
doubled = array.map do |element|
|
doubled = array.map do |element|
|
||||||
@@ -304,6 +303,7 @@ puts doubled
|
|||||||
puts array
|
puts array
|
||||||
#=> [1,2,3,4,5]
|
#=> [1,2,3,4,5]
|
||||||
|
|
||||||
|
# Case construct
|
||||||
grade = 'B'
|
grade = 'B'
|
||||||
|
|
||||||
case grade
|
case grade
|
||||||
@@ -322,7 +322,7 @@ else
|
|||||||
end
|
end
|
||||||
#=> "Better luck next time"
|
#=> "Better luck next time"
|
||||||
|
|
||||||
# cases can also use ranges
|
# Cases can also use ranges
|
||||||
grade = 82
|
grade = 82
|
||||||
case grade
|
case grade
|
||||||
when 90..100
|
when 90..100
|
||||||
@@ -334,9 +334,9 @@ else
|
|||||||
end
|
end
|
||||||
#=> "OK job"
|
#=> "OK job"
|
||||||
|
|
||||||
# exception handling:
|
# Exception handling
|
||||||
begin
|
begin
|
||||||
# code here that might raise an exception
|
# Code here that might raise an exception
|
||||||
raise NoMemoryError, 'You ran out of memory.'
|
raise NoMemoryError, 'You ran out of memory.'
|
||||||
rescue NoMemoryError => exception_variable
|
rescue NoMemoryError => exception_variable
|
||||||
puts 'NoMemoryError was raised', exception_variable
|
puts 'NoMemoryError was raised', exception_variable
|
||||||
@@ -354,10 +354,10 @@ def double(x)
|
|||||||
x * 2
|
x * 2
|
||||||
end
|
end
|
||||||
|
|
||||||
# Methods (and blocks) implicitly return the value of the last statement
|
# Methods (and blocks) implicitly return the value of the last statement.
|
||||||
double(2) #=> 4
|
double(2) #=> 4
|
||||||
|
|
||||||
# Parentheses are optional where the interpretation is unambiguous
|
# Parentheses are optional where the interpretation is unambiguous.
|
||||||
double 3 #=> 6
|
double 3 #=> 6
|
||||||
|
|
||||||
double double 3 #=> 12
|
double double 3 #=> 12
|
||||||
@@ -366,15 +366,14 @@ def sum(x, y)
|
|||||||
x + y
|
x + y
|
||||||
end
|
end
|
||||||
|
|
||||||
# Method arguments are separated by a comma
|
# Method arguments are separated by a comma.
|
||||||
sum 3, 4 #=> 7
|
sum 3, 4 #=> 7
|
||||||
|
|
||||||
sum sum(3, 4), 5 #=> 12
|
sum sum(3, 4), 5 #=> 12
|
||||||
|
|
||||||
# yield
|
# yield
|
||||||
# All methods have an implicit, optional block parameter
|
# All methods have an implicit, optional block parameter.
|
||||||
# it can be called with the 'yield' keyword
|
# Tt can be called with the 'yield' keyword.
|
||||||
|
|
||||||
def surround
|
def surround
|
||||||
puts '{'
|
puts '{'
|
||||||
yield
|
yield
|
||||||
@@ -383,45 +382,43 @@ end
|
|||||||
|
|
||||||
surround { puts 'hello world' }
|
surround { puts 'hello world' }
|
||||||
|
|
||||||
# {
|
#=> {
|
||||||
# hello world
|
#=> hello world
|
||||||
# }
|
#=> }
|
||||||
|
|
||||||
|
# Blocks can be converted into a 'proc' object, which wraps the block
|
||||||
# Blocks can be converted into a `proc` object, which wraps the block
|
|
||||||
# and allows it to be passed to another method, bound to a different scope,
|
# and allows it to be passed to another method, bound to a different scope,
|
||||||
# or manipulated otherwise. This is most common in method parameter lists,
|
# or manipulated otherwise. This is most common in method parameter lists,
|
||||||
# where you frequently see a trailing `&block` parameter that will accept
|
# where you frequently see a trailing '&block' parameter that will accept
|
||||||
# the block, if one is given, and convert it to a `Proc`. The naming here is
|
# the block, if one is given, and convert it to a 'Proc'. The naming here is
|
||||||
# convention; it would work just as well with `&pineapple`:
|
# convention; it would work just as well with '&pineapple'.
|
||||||
def guests(&block)
|
def guests(&block)
|
||||||
block.class #=> Proc
|
block.class #=> Proc
|
||||||
block.call(4)
|
block.call(4)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The `call` method on the Proc is similar to calling `yield` when a block is
|
# The 'call' method on the Proc is similar to calling 'yield' when a block is
|
||||||
# present. The arguments passed to `call` will be forwarded to the block as arugments:
|
# present. The arguments passed to 'call' will be forwarded to the block as arugments.
|
||||||
|
|
||||||
guests { |n| "You have #{n} guests." }
|
guests { |n| "You have #{n} guests." }
|
||||||
# => "You have 4 guests."
|
# => "You have 4 guests."
|
||||||
|
|
||||||
# You can pass a list of arguments, which will be converted into an array
|
# You can pass a list of arguments, which will be converted into an array.
|
||||||
# That's what splat operator ("*") is for
|
# That's what splat operator ("*") is for.
|
||||||
def guests(*array)
|
def guests(*array)
|
||||||
array.each { |guest| puts guest }
|
array.each { |guest| puts guest }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Destructuring
|
# Destructuring
|
||||||
|
|
||||||
# Ruby will automatically destructure arrays on assignment to multiple variables:
|
# Ruby will automatically destructure arrays on assignment to multiple variables.
|
||||||
a, b, c = [1, 2, 3]
|
a, b, c = [1, 2, 3]
|
||||||
a #=> 1
|
a #=> 1
|
||||||
b #=> 2
|
b #=> 2
|
||||||
c #=> 3
|
c #=> 3
|
||||||
|
|
||||||
# In some cases, you will want to use the splat operator: `*` to prompt destructuring
|
# In some cases, you will want to use the splat operator: `*` to prompt destructuring
|
||||||
# of an array into a list:
|
# of an array into a list.
|
||||||
|
|
||||||
ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
|
ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
|
||||||
|
|
||||||
def best(first, second, third)
|
def best(first, second, third)
|
||||||
@@ -430,7 +427,7 @@ end
|
|||||||
|
|
||||||
best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
|
best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
|
||||||
|
|
||||||
# The splat operator can also be used in parameters:
|
# The splat operator can also be used in parameters.
|
||||||
def best(first, second, third, *others)
|
def best(first, second, third, *others)
|
||||||
puts "Winners are #{first}, #{second}, and #{third}."
|
puts "Winners are #{first}, #{second}, and #{third}."
|
||||||
puts "There were #{others.count} other participants."
|
puts "There were #{others.count} other participants."
|
||||||
@@ -440,21 +437,23 @@ best *ranked_competitors
|
|||||||
#=> Winners are John, Sally, and Dingus.
|
#=> Winners are John, Sally, and Dingus.
|
||||||
#=> There were 2 other participants.
|
#=> There were 2 other participants.
|
||||||
|
|
||||||
# By convention, all methods that return booleans end with a question mark
|
# By convention, all methods that return booleans end with a question mark.
|
||||||
5.even? # false
|
5.even? #=> false
|
||||||
5.odd? # true
|
5.odd? #=> true
|
||||||
|
|
||||||
# And if a method ends with an exclamation mark, it does something destructive
|
# By convention, if a method name ends with an exclamation mark, it does something destructive
|
||||||
# like mutate the receiver. Many methods have a ! version to make a change, and
|
# like mutate the receiver. Many methods have a ! version to make a change, and
|
||||||
# a non-! version to just return a new changed version
|
# a non-! version to just return a new changed version.
|
||||||
company_name = "Dunder Mifflin"
|
company_name = "Dunder Mifflin"
|
||||||
company_name.upcase #=> "DUNDER MIFFLIN"
|
company_name.upcase #=> "DUNDER MIFFLIN"
|
||||||
company_name #=> "Dunder Mifflin"
|
company_name #=> "Dunder Mifflin"
|
||||||
company_name.upcase! # we're mutating company_name this time!
|
# We're mutating company_name this time.
|
||||||
|
company_name.upcase! #=> "DUNDER MIFFLIN"
|
||||||
company_name #=> "DUNDER MIFFLIN"
|
company_name #=> "DUNDER MIFFLIN"
|
||||||
|
|
||||||
|
# Classes
|
||||||
|
|
||||||
# Define a class with the class keyword
|
# You can define a class with the 'class' keyword.
|
||||||
class Human
|
class Human
|
||||||
|
|
||||||
# A class variable. It is shared by all instances of this class.
|
# A class variable. It is shared by all instances of this class.
|
||||||
@@ -462,7 +461,7 @@ class Human
|
|||||||
|
|
||||||
# Basic initializer
|
# Basic initializer
|
||||||
def initialize(name, age = 0)
|
def initialize(name, age = 0)
|
||||||
# Assign the argument to the "name" instance variable for the instance
|
# Assign the argument to the 'name' instance variable for the instance.
|
||||||
@name = name
|
@name = name
|
||||||
# If no age given, we will fall back to the default in the arguments list.
|
# If no age given, we will fall back to the default in the arguments list.
|
||||||
@age = age
|
@age = age
|
||||||
@@ -478,10 +477,10 @@ class Human
|
|||||||
@name
|
@name
|
||||||
end
|
end
|
||||||
|
|
||||||
# The above functionality can be encapsulated using the attr_accessor method as follows
|
# The above functionality can be encapsulated using the attr_accessor method as follows.
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
|
||||||
# Getter/setter methods can also be created individually like this
|
# Getter/setter methods can also be created individually like this.
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
attr_writer :name
|
attr_writer :name
|
||||||
|
|
||||||
@@ -496,13 +495,11 @@ class Human
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Instantiating of a class
|
||||||
# Instantiate a class
|
|
||||||
jim = Human.new('Jim Halpert')
|
jim = Human.new('Jim Halpert')
|
||||||
|
|
||||||
dwight = Human.new('Dwight K. Schrute')
|
dwight = Human.new('Dwight K. Schrute')
|
||||||
|
|
||||||
# Let's call a couple of methods
|
# You can call the methods of the generated object.
|
||||||
jim.species #=> "H. sapiens"
|
jim.species #=> "H. sapiens"
|
||||||
jim.name #=> "Jim Halpert"
|
jim.name #=> "Jim Halpert"
|
||||||
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
|
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
|
||||||
@@ -510,30 +507,30 @@ jim.name #=> "Jim Halpert II"
|
|||||||
dwight.species #=> "H. sapiens"
|
dwight.species #=> "H. sapiens"
|
||||||
dwight.name #=> "Dwight K. Schrute"
|
dwight.name #=> "Dwight K. Schrute"
|
||||||
|
|
||||||
# Call the class method
|
# Calling of a class method
|
||||||
Human.say('Hi') #=> "Hi"
|
Human.say('Hi') #=> "Hi"
|
||||||
|
|
||||||
# Variable's scopes are defined by the way we name them.
|
# Variable's scopes are defined by the way we name them.
|
||||||
# Variables that start with $ have global scope
|
# Variables that start with $ have global scope.
|
||||||
$var = "I'm a global var"
|
$var = "I'm a global var"
|
||||||
defined? $var #=> "global-variable"
|
defined? $var #=> "global-variable"
|
||||||
|
|
||||||
# Variables that start with @ have instance scope
|
# Variables that start with @ have instance scope.
|
||||||
@var = "I'm an instance var"
|
@var = "I'm an instance var"
|
||||||
defined? @var #=> "instance-variable"
|
defined? @var #=> "instance-variable"
|
||||||
|
|
||||||
# Variables that start with @@ have class scope
|
# Variables that start with @@ have class scope.
|
||||||
@@var = "I'm a class var"
|
@@var = "I'm a class var"
|
||||||
defined? @@var #=> "class variable"
|
defined? @@var #=> "class variable"
|
||||||
|
|
||||||
# Variables that start with a capital letter are constants
|
# Variables that start with a capital letter are constants.
|
||||||
Var = "I'm a constant"
|
Var = "I'm a constant"
|
||||||
defined? Var #=> "constant"
|
defined? Var #=> "constant"
|
||||||
|
|
||||||
# Class is also an object in ruby. So class can have instance variables.
|
# Class is also an object in ruby. So a class can have instance variables.
|
||||||
# Class variable is shared among the class and all of its descendants.
|
# A class variable is shared among the class and all of its descendants.
|
||||||
|
|
||||||
# base class
|
# Base class
|
||||||
class Human
|
class Human
|
||||||
@@foo = 0
|
@@foo = 0
|
||||||
|
|
||||||
@@ -546,18 +543,17 @@ class Human
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# derived class
|
# Derived class
|
||||||
class Worker < Human
|
class Worker < Human
|
||||||
end
|
end
|
||||||
|
|
||||||
Human.foo # 0
|
Human.foo #=> 0
|
||||||
Worker.foo # 0
|
Worker.foo #=> 0
|
||||||
|
|
||||||
Human.foo = 2 # 2
|
Human.foo = 2
|
||||||
Worker.foo # 2
|
Worker.foo #=> 2
|
||||||
|
|
||||||
# Class instance variable is not shared by the class's descendants.
|
|
||||||
|
|
||||||
|
# A class instance variable is not shared by the class's descendants.
|
||||||
class Human
|
class Human
|
||||||
@bar = 0
|
@bar = 0
|
||||||
|
|
||||||
@@ -573,8 +569,8 @@ end
|
|||||||
class Doctor < Human
|
class Doctor < Human
|
||||||
end
|
end
|
||||||
|
|
||||||
Human.bar # 0
|
Human.bar #=> 0
|
||||||
Doctor.bar # nil
|
Doctor.bar #=> nil
|
||||||
|
|
||||||
module ModuleExample
|
module ModuleExample
|
||||||
def foo
|
def foo
|
||||||
@@ -582,9 +578,8 @@ module ModuleExample
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Including modules binds their methods to the class instances
|
# Including modules binds their methods to the class instances.
|
||||||
# Extending modules binds their methods to the class itself
|
# Extending modules binds their methods to the class itself.
|
||||||
|
|
||||||
class Person
|
class Person
|
||||||
include ModuleExample
|
include ModuleExample
|
||||||
end
|
end
|
||||||
@@ -593,13 +588,12 @@ class Book
|
|||||||
extend ModuleExample
|
extend ModuleExample
|
||||||
end
|
end
|
||||||
|
|
||||||
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
|
Person.foo #=> NoMethodError: undefined method `foo' for Person:Class
|
||||||
Person.new.foo # => 'foo'
|
Person.new.foo #=> "foo"
|
||||||
Book.foo # => 'foo'
|
Book.foo #=> "foo"
|
||||||
Book.new.foo # => NoMethodError: undefined method `foo'
|
Book.new.foo #=> NoMethodError: undefined method `foo'
|
||||||
|
|
||||||
# Callbacks are executed when including and extending a module
|
# Callbacks are executed when including and extending a module
|
||||||
|
|
||||||
module ConcernExample
|
module ConcernExample
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
base.extend(ClassMethods)
|
base.extend(ClassMethods)
|
||||||
@@ -623,10 +617,10 @@ class Something
|
|||||||
include ConcernExample
|
include ConcernExample
|
||||||
end
|
end
|
||||||
|
|
||||||
Something.bar # => 'bar'
|
Something.bar #=> "bar"
|
||||||
Something.qux # => NoMethodError: undefined method `qux'
|
Something.qux #=> NoMethodError: undefined method `qux'
|
||||||
Something.new.bar # => NoMethodError: undefined method `bar'
|
Something.new.bar #=> NoMethodError: undefined method `bar'
|
||||||
Something.new.qux # => 'qux'
|
Something.new.qux #=> "qux"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Additional resources
|
## Additional resources
|
||||||
|
@@ -12,7 +12,7 @@ It is an alternative to YAML and JSON. It aims to be more human friendly than JS
|
|||||||
Be warned, TOML's spec is still changing a lot. Until it's marked as 1.0, you
|
Be warned, TOML's spec is still changing a lot. Until it's marked as 1.0, you
|
||||||
should assume that it is unstable and act accordingly. This document follows TOML v0.4.0.
|
should assume that it is unstable and act accordingly. This document follows TOML v0.4.0.
|
||||||
|
|
||||||
```toml
|
```
|
||||||
# Comments in TOML look like this.
|
# Comments in TOML look like this.
|
||||||
|
|
||||||
################
|
################
|
||||||
|
@@ -11,7 +11,7 @@ filename: markdown-tr.md
|
|||||||
Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır.
|
Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır.
|
||||||
|
|
||||||
|
|
||||||
```markdown
|
```md
|
||||||
<!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir
|
<!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir
|
||||||
ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve
|
ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve
|
||||||
markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız,
|
markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız,
|
||||||
|
818
uk-ua/python-ua.html.markdown
Normal file
818
uk-ua/python-ua.html.markdown
Normal file
@@ -0,0 +1,818 @@
|
|||||||
|
---
|
||||||
|
language: python
|
||||||
|
lang: uk-ua
|
||||||
|
contributors:
|
||||||
|
- ["Louie Dinh", "http://ldinh.ca"]
|
||||||
|
- ["Amin Bandali", "https://aminb.org"]
|
||||||
|
- ["Andre Polykanine", "https://github.com/Oire"]
|
||||||
|
- ["evuez", "http://github.com/evuez"]
|
||||||
|
- ["asyne", "https://github.com/justblah"]
|
||||||
|
- ["habi", "http://github.com/habi"]
|
||||||
|
translators:
|
||||||
|
- ["Oleg Gromyak", "https://github.com/ogroleg"]
|
||||||
|
filename: learnpython-ua.py
|
||||||
|
---
|
||||||
|
|
||||||
|
Мову Python створив Гвідо ван Россум на початку 90-х. Наразі це одна з
|
||||||
|
найбільш популярних мов. Я закохався у Python завдяки простому і зрозумілому
|
||||||
|
синтаксису. Це майже як виконуваний псевдокод.
|
||||||
|
|
||||||
|
З вдячністю чекаю ваших відгуків: [@louiedinh](http://twitter.com/louiedinh)
|
||||||
|
або louiedinh [at] [поштовий сервіс від Google]
|
||||||
|
|
||||||
|
Примітка: Ця стаття стосується Python 2.7, проте має працювати і
|
||||||
|
у інших версіях Python 2.x. Python 2.7 підходить до кінця свого терміну,
|
||||||
|
його підтримку припинять у 2020, тож наразі краще починати вивчення Python
|
||||||
|
з версії 3.x.
|
||||||
|
Аби вивчити Python 3.x, звертайтесь до статті по Python 3.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Однорядкові коментарі починаються з символу решітки.
|
||||||
|
|
||||||
|
""" Текст, що займає декілька рядків,
|
||||||
|
може бути записаний з використанням 3 знаків " і
|
||||||
|
зазвичай використовується у якості
|
||||||
|
вбудованої документації
|
||||||
|
"""
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 1. Примітивні типи даних та оператори
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# У вас є числа
|
||||||
|
3 # => 3
|
||||||
|
|
||||||
|
# Математика працює досить передбачувано
|
||||||
|
1 + 1 # => 2
|
||||||
|
8 - 1 # => 7
|
||||||
|
10 * 2 # => 20
|
||||||
|
35 / 5 # => 7
|
||||||
|
|
||||||
|
# А ось з діленням все трохи складніше. Воно цілочисельне і результат
|
||||||
|
# автоматично округлюється у меншу сторону.
|
||||||
|
5 / 2 # => 2
|
||||||
|
|
||||||
|
# Аби правильно ділити, спершу варто дізнатися про числа
|
||||||
|
# з плаваючою комою.
|
||||||
|
2.0 # Це число з плаваючою комою
|
||||||
|
11.0 / 4.0 # => 2.75 ох... Так набагато краще
|
||||||
|
|
||||||
|
# Результат цілочисельного ділення округлюється у меншу сторону
|
||||||
|
# як для додатніх, так і для від'ємних чисел.
|
||||||
|
5 // 3 # => 1
|
||||||
|
5.0 // 3.0 # => 1.0 # Працює і для чисел з плаваючою комою
|
||||||
|
-5 // 3 # => -2
|
||||||
|
-5.0 // 3.0 # => -2.0
|
||||||
|
|
||||||
|
# Зверніть увагу, що ми також можемо імпортувати модуль для ділення,
|
||||||
|
# див. розділ Модулі
|
||||||
|
# аби звичне ділення працювало при використанні лише '/'.
|
||||||
|
from __future__ import division
|
||||||
|
|
||||||
|
11 / 4 # => 2.75 ...звичне ділення
|
||||||
|
11 // 4 # => 2 ...цілочисельне ділення
|
||||||
|
|
||||||
|
# Залишок від ділення
|
||||||
|
7 % 3 # => 1
|
||||||
|
|
||||||
|
# Піднесення до степеня
|
||||||
|
2 ** 4 # => 16
|
||||||
|
|
||||||
|
# Приорітет операцій вказується дужками
|
||||||
|
(1 + 3) * 2 # => 8
|
||||||
|
|
||||||
|
# Логічні оператори
|
||||||
|
# Зверніть увагу: ключові слова «and» і «or» чутливі до регістру букв
|
||||||
|
True and False # => False
|
||||||
|
False or True # => True
|
||||||
|
|
||||||
|
# Завважте, що логічні оператори також використовуються і з цілими числами
|
||||||
|
0 and 2 # => 0
|
||||||
|
-5 or 0 # => -5
|
||||||
|
0 == False # => True
|
||||||
|
2 == True # => False
|
||||||
|
1 == True # => True
|
||||||
|
|
||||||
|
# Для заперечення використовується not
|
||||||
|
not True # => False
|
||||||
|
not False # => True
|
||||||
|
|
||||||
|
# Рівність — це ==
|
||||||
|
1 == 1 # => True
|
||||||
|
2 == 1 # => False
|
||||||
|
|
||||||
|
# Нерівність — це !=
|
||||||
|
1 != 1 # => False
|
||||||
|
2 != 1 # => True
|
||||||
|
|
||||||
|
# Ще трохи порівнянь
|
||||||
|
1 < 10 # => True
|
||||||
|
1 > 10 # => False
|
||||||
|
2 <= 2 # => True
|
||||||
|
2 >= 2 # => True
|
||||||
|
|
||||||
|
# Порівняння можуть бути записані ланцюжком!
|
||||||
|
1 < 2 < 3 # => True
|
||||||
|
2 < 3 < 2 # => False
|
||||||
|
|
||||||
|
# Рядки позначаються символом " або '
|
||||||
|
"Це рядок."
|
||||||
|
'Це теж рядок.'
|
||||||
|
|
||||||
|
# І рядки також можна додавати!
|
||||||
|
"Привіт " + "світ!" # => "Привіт світ!"
|
||||||
|
# Рядки можна додавати і без '+'
|
||||||
|
"Привіт " "світ!" # => "Привіт світ!"
|
||||||
|
|
||||||
|
# ... або множити
|
||||||
|
"Привіт" * 3 # => "ПривітПривітПривіт"
|
||||||
|
|
||||||
|
# З рядком можна працювати як зі списком символів
|
||||||
|
"Це рядок"[0] # => 'Ц'
|
||||||
|
|
||||||
|
# Ви можете дізнатися довжину рядка
|
||||||
|
len("Це рядок") # => 8
|
||||||
|
|
||||||
|
# Символ % використовується для форматування рядків, наприклад:
|
||||||
|
"%s можуть бути %s" % ("рядки", "інтерпольовані")
|
||||||
|
|
||||||
|
# Новий спосіб форматування рядків — використання методу format.
|
||||||
|
# Це бажаний спосіб.
|
||||||
|
"{} є {}".format("Це", "заповнювач")
|
||||||
|
"{0} можуть бути {1}".format("рядки", "форматовані")
|
||||||
|
# Якщо ви не хочете рахувати, то можете скористатися ключовими словами.
|
||||||
|
"{name} хоче з'істи {food}".format(name="Боб", food="лазанью")
|
||||||
|
|
||||||
|
# None - це об'єкт
|
||||||
|
None # => None
|
||||||
|
|
||||||
|
# Не використовуйте оператор рівності '=='' для порівняння
|
||||||
|
# об'єктів з None. Використовуйте для цього «is»
|
||||||
|
"etc" is None # => False
|
||||||
|
None is None # => True
|
||||||
|
|
||||||
|
# Оператор 'is' перевіряє ідентичність об'єктів. Він не
|
||||||
|
# дуже корисний при роботі з примітивними типами, проте
|
||||||
|
# незамінний при роботі з об'єктами.
|
||||||
|
|
||||||
|
# None, 0 і порожні рядки/списки рівні False.
|
||||||
|
# Всі інші значення рівні True
|
||||||
|
bool(0) # => False
|
||||||
|
bool("") # => False
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 2. Змінні та колекції
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# В Python є оператор print
|
||||||
|
print "Я Python. Приємно познайомитись!" # => Я Python. Приємно познайомитись!
|
||||||
|
|
||||||
|
# Отримати дані з консолі просто
|
||||||
|
input_string_var = raw_input(
|
||||||
|
"Введіть щось: ") # Повертає дані у вигляді рядка
|
||||||
|
input_var = input("Введіть щось: ") # Працює з даними як з кодом на python
|
||||||
|
# Застереження: будьте обережні при використанні методу input()
|
||||||
|
|
||||||
|
# Оголошувати змінні перед ініціалізацією не потрібно.
|
||||||
|
some_var = 5 # За угодою використовується нижній_регістр_з_підкресленнями
|
||||||
|
some_var # => 5
|
||||||
|
|
||||||
|
# При спробі доступу до неініціалізованої змінної
|
||||||
|
# виникне виняткова ситуація.
|
||||||
|
# Див. розділ Потік управління, аби дізнатись про винятки більше.
|
||||||
|
some_other_var # Помилка в імені
|
||||||
|
|
||||||
|
# if може використовуватися як вираз
|
||||||
|
# Такий запис еквівалентний тернарному оператору '?:' у мові С
|
||||||
|
"yahoo!" if 3 > 2 else 2 # => "yahoo!"
|
||||||
|
|
||||||
|
# Списки зберігають послідовності
|
||||||
|
li = []
|
||||||
|
# Можна одразу створити заповнений список
|
||||||
|
other_li = [4, 5, 6]
|
||||||
|
|
||||||
|
# Об'єкти додаються у кінець списку за допомогою методу append
|
||||||
|
li.append(1) # li тепер дорівнює [1]
|
||||||
|
li.append(2) # li тепер дорівнює [1, 2]
|
||||||
|
li.append(4) # li тепер дорівнює [1, 2, 4]
|
||||||
|
li.append(3) # li тепер дорівнює [1, 2, 4, 3]
|
||||||
|
# І видаляються з кінця методом pop
|
||||||
|
li.pop() # => повертає 3 і li стає рівним [1, 2, 4]
|
||||||
|
# Повернемо елемент назад
|
||||||
|
li.append(3) # li тепер знову дорівнює [1, 2, 4, 3]
|
||||||
|
|
||||||
|
# Поводьтесь зі списком як зі звичайним масивом
|
||||||
|
li[0] # => 1
|
||||||
|
# Присвоюйте нові значення вже ініціалізованим індексам за допомогою =
|
||||||
|
li[0] = 42
|
||||||
|
li[0] # => 42
|
||||||
|
li[0] = 1 # Зверніть увагу: повертаємось до попереднього значення
|
||||||
|
# Звертаємось до останнього елементу
|
||||||
|
li[-1] # => 3
|
||||||
|
|
||||||
|
# Спроба вийти за границі масиву призводить до помилки в індексі
|
||||||
|
li[4] # помилка в індексі
|
||||||
|
|
||||||
|
# Можна звертатися до діапазону, використовуючи так звані зрізи
|
||||||
|
# (Для тих, хто любить математику: це називається замкнуто-відкритий інтервал).
|
||||||
|
li[1:3] # => [2, 4]
|
||||||
|
# Опускаємо початок
|
||||||
|
li[2:] # => [4, 3]
|
||||||
|
# Опускаємо кінець
|
||||||
|
li[:3] # => [1, 2, 4]
|
||||||
|
# Вибираємо кожен другий елемент
|
||||||
|
li[::2] # => [1, 4]
|
||||||
|
# Перевертаємо список
|
||||||
|
li[::-1] # => [3, 4, 2, 1]
|
||||||
|
# Використовуйте суміш вищеназваного для більш складних зрізів
|
||||||
|
# li[початок:кінець:крок]
|
||||||
|
|
||||||
|
# Видаляємо довільні елементи зі списку оператором del
|
||||||
|
del li[2] # li тепер [1, 2, 3]
|
||||||
|
|
||||||
|
# Ви можете додавати списки
|
||||||
|
li + other_li # => [1, 2, 3, 4, 5, 6]
|
||||||
|
# Зверніть увагу: значення li та other_li при цьому не змінились.
|
||||||
|
|
||||||
|
# Поєднувати списки можна за допомогою методу extend
|
||||||
|
li.extend(other_li) # Тепер li дорівнює [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
# Видалити перше входження значення
|
||||||
|
li.remove(2) # Тепер li дорівнює [1, 3, 4, 5, 6]
|
||||||
|
li.remove(2) # Помилка значення, оскільки у списку li немає 2
|
||||||
|
|
||||||
|
# Вставити елемент за вказаним індексом
|
||||||
|
li.insert(1, 2) # li знову дорівнює [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
# Отримати індекс першого знайденого елементу
|
||||||
|
li.index(2) # => 1
|
||||||
|
li.index(7) # Помилка значення, оскільки у списку li немає 7
|
||||||
|
|
||||||
|
# Перевірити елемент на входження у список можна оператором in
|
||||||
|
1 in li # => True
|
||||||
|
|
||||||
|
# Довжина списку обчислюється за допомогою функції len
|
||||||
|
len(li) # => 6
|
||||||
|
|
||||||
|
# Кортежі схожі на списки, лише незмінні
|
||||||
|
tup = (1, 2, 3)
|
||||||
|
tup[0] # => 1
|
||||||
|
tup[0] = 3 # Виникає помилка типу
|
||||||
|
|
||||||
|
# Все те ж саме можна робити і з кортежами
|
||||||
|
len(tup) # => 3
|
||||||
|
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
|
||||||
|
tup[:2] # => (1, 2)
|
||||||
|
2 in tup # => True
|
||||||
|
|
||||||
|
# Ви можете розпаковувати кортежі (або списки) у змінні
|
||||||
|
a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
|
||||||
|
d, e, f = 4, 5, 6 # дужки можна опустити
|
||||||
|
# Кортежі створюються за замовчуванням, якщо дужки опущено
|
||||||
|
g = 4, 5, 6 # => (4, 5, 6)
|
||||||
|
# Дивіться, як легко обміняти значення двох змінних
|
||||||
|
e, d = d, e # тепер d дорівнює 5, а e дорівнює 4
|
||||||
|
|
||||||
|
# Словники містять асоціативні масиви
|
||||||
|
empty_dict = {}
|
||||||
|
# Ось так описується попередньо заповнений словник
|
||||||
|
filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||||
|
|
||||||
|
# Значення можна отримати так само, як і зі списку
|
||||||
|
filled_dict["one"] # => 1
|
||||||
|
|
||||||
|
# Можна отримати всі ключі у виді списку за допомогою методу keys
|
||||||
|
filled_dict.keys() # => ["three", "two", "one"]
|
||||||
|
# Примітка: збереження порядку ключів у словників не гарантується
|
||||||
|
# Ваші результати можуть не співпадати з цими.
|
||||||
|
|
||||||
|
# Можна отримати і всі значення у вигляді списку, використовуйте метод values
|
||||||
|
filled_dict.values() # => [3, 2, 1]
|
||||||
|
# Те ж зауваження щодо порядку ключів діє і тут
|
||||||
|
|
||||||
|
# Отримуйте всі пари ключ-значення у вигляді списку кортежів
|
||||||
|
# за допомогою "items()"
|
||||||
|
filled_dict.items() # => [("one", 1), ("two", 2), ("three", 3)]
|
||||||
|
|
||||||
|
# За допомогою оператору in можна перевіряти ключі на входження у словник
|
||||||
|
"one" in filled_dict # => True
|
||||||
|
1 in filled_dict # => False
|
||||||
|
|
||||||
|
# Спроба отримати значення за неіснуючим ключем викине помилку ключа
|
||||||
|
filled_dict["four"] # помилка ключа
|
||||||
|
|
||||||
|
# Аби уникнути цього, використовуйте метод get()
|
||||||
|
filled_dict.get("one") # => 1
|
||||||
|
filled_dict.get("four") # => None
|
||||||
|
# Метод get також приймає аргумент за замовчуванням, значення якого буде
|
||||||
|
# повернуто при відсутності вказаного ключа
|
||||||
|
filled_dict.get("one", 4) # => 1
|
||||||
|
filled_dict.get("four", 4) # => 4
|
||||||
|
# Зверніть увагу, що filled_dict.get("four") все ще => None
|
||||||
|
# (get не встановлює значення елементу словника)
|
||||||
|
|
||||||
|
# Присвоюйте значення ключам так само, як і в списках
|
||||||
|
filled_dict["four"] = 4 # тепер filled_dict["four"] => 4
|
||||||
|
|
||||||
|
# Метод setdefault() вставляє пару ключ-значення лише
|
||||||
|
# за відсутності такого ключа
|
||||||
|
filled_dict.setdefault("five", 5) # filled_dict["five"] повертає 5
|
||||||
|
filled_dict.setdefault("five", 6) # filled_dict["five"] все ще повертає 5
|
||||||
|
|
||||||
|
|
||||||
|
# Множини містять... ну, загалом, множини
|
||||||
|
# (які схожі на списки, проте в них не може бути елементів, які повторюються)
|
||||||
|
empty_set = set()
|
||||||
|
# Ініціалізація множини набором значень
|
||||||
|
some_set = set([1,2,2,3,4]) # some_set тепер дорівнює set([1, 2, 3, 4])
|
||||||
|
|
||||||
|
# Порядок не гарантовано, хоча інколи множини виглядають відсортованими
|
||||||
|
another_set = set([4, 3, 2, 2, 1]) # another_set тепер set([1, 2, 3, 4])
|
||||||
|
|
||||||
|
# Починаючи з Python 2.7, ви можете використовувати {}, аби створити множину
|
||||||
|
filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
|
||||||
|
|
||||||
|
# Додавання нових елементів у множину
|
||||||
|
filled_set.add(5) # filled_set тепер дорівнює {1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
# Перетин множин: &
|
||||||
|
other_set = {3, 4, 5, 6}
|
||||||
|
filled_set & other_set # => {3, 4, 5}
|
||||||
|
|
||||||
|
# Об'єднання множин: |
|
||||||
|
filled_set | other_set # => {1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
|
# Різниця множин: -
|
||||||
|
{1,2,3,4} - {2,3,5} # => {1, 4}
|
||||||
|
|
||||||
|
# Симетрична різниця множин: ^
|
||||||
|
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
|
||||||
|
|
||||||
|
# Перевіряємо чи множина зліва є надмножиною множини справа
|
||||||
|
{1, 2} >= {1, 2, 3} # => False
|
||||||
|
|
||||||
|
# Перевіряємо чи множина зліва є підмножиною множини справа
|
||||||
|
{1, 2} <= {1, 2, 3} # => True
|
||||||
|
|
||||||
|
# Перевірка на входження у множину: in
|
||||||
|
2 in filled_set # => True
|
||||||
|
10 in filled_set # => False
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 3. Потік управління
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Для початку створимо змінну
|
||||||
|
some_var = 5
|
||||||
|
|
||||||
|
# Так виглядає вираз if. Відступи у python дуже важливі!
|
||||||
|
# результат: «some_var менше, ніж 10»
|
||||||
|
if some_var > 10:
|
||||||
|
print("some_var набагато більше, ніж 10.")
|
||||||
|
elif some_var < 10: # Вираз elif є необов'язковим.
|
||||||
|
print("some_var менше, ніж 10.")
|
||||||
|
else: # Це теж необов'язково.
|
||||||
|
print("some_var дорівнює 10.")
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Цикли For проходять по спискам
|
||||||
|
|
||||||
|
Результат:
|
||||||
|
собака — це ссавець
|
||||||
|
кішка — це ссавець
|
||||||
|
миша — це ссавець
|
||||||
|
"""
|
||||||
|
for animal in ["собака", "кішка", "миша"]:
|
||||||
|
# Можете використовувати оператор {0} для інтерполяції форматованих рядків
|
||||||
|
print "{0} — це ссавець".format(animal)
|
||||||
|
|
||||||
|
"""
|
||||||
|
"range(число)" повертає список чисел
|
||||||
|
від нуля до заданого числа
|
||||||
|
Друкує:
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
"""
|
||||||
|
for i in range(4):
|
||||||
|
print(i)
|
||||||
|
"""
|
||||||
|
"range(нижня_границя, верхня_границя)" повертає список чисел
|
||||||
|
від нижньої границі до верхньої
|
||||||
|
Друкує:
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
"""
|
||||||
|
for i in range(4, 8):
|
||||||
|
print i
|
||||||
|
|
||||||
|
"""
|
||||||
|
Цикли while продовжуються до тих пір, поки вказана умова не стане хибною.
|
||||||
|
Друкує:
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
"""
|
||||||
|
x = 0
|
||||||
|
while x < 4:
|
||||||
|
print(x)
|
||||||
|
x += 1 # Короткий запис для x = x + 1
|
||||||
|
|
||||||
|
# Обробляйте винятки блоками try/except
|
||||||
|
|
||||||
|
# Працює у Python 2.6 і вище:
|
||||||
|
try:
|
||||||
|
# Аби створити виняток, використовується raise
|
||||||
|
raise IndexError("Помилка у індексі!")
|
||||||
|
except IndexError as e:
|
||||||
|
pass # pass — оператор, який нічого не робить. Зазвичай тут відбувається
|
||||||
|
# відновлення після помилки.
|
||||||
|
except (TypeError, NameError):
|
||||||
|
pass # Винятки можна обробляти групами, якщо потрібно.
|
||||||
|
else: # Необов'язковий вираз. Має слідувати за останнім блоком except
|
||||||
|
print("Все добре!") # Виконається лише якщо не було ніяких винятків
|
||||||
|
finally: # Виконується у будь-якому випадку
|
||||||
|
print "Тут ми можемо звільнити ресурси"
|
||||||
|
|
||||||
|
# Замість try/finally для звільнення ресурсів
|
||||||
|
# ви можете використовувати вираз with
|
||||||
|
with open("myfile.txt") as f:
|
||||||
|
for line in f:
|
||||||
|
print line
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 4. Функції
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Використовуйте def для створення нових функцій
|
||||||
|
def add(x, y):
|
||||||
|
print "x дорівнює {0}, а y дорівнює {1}".format(x, y)
|
||||||
|
return x + y # Повертайте результат за допомогою ключового слова return
|
||||||
|
|
||||||
|
|
||||||
|
# Виклик функції з аргументами
|
||||||
|
add(5, 6) # => друкує «x дорівнює 5, а y дорівнює 6» і повертає 11
|
||||||
|
|
||||||
|
# Інший спосіб виклику функції — виклик з іменованими аргументами
|
||||||
|
add(y=6, x=5) # Іменовані аргументи можна вказувати у будь-якому порядку
|
||||||
|
|
||||||
|
|
||||||
|
# Ви можете визначити функцію, яка приймає змінну кількість аргументів,
|
||||||
|
# які будуть інтерпретовані як кортеж, за допомогою *
|
||||||
|
def varargs(*args):
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
varargs(1, 2, 3) # => (1,2,3)
|
||||||
|
|
||||||
|
|
||||||
|
# А також можете визначити функцію, яка приймає змінне число
|
||||||
|
# іменованих аргументів, котрі будуть інтерпретовані як словник, за допомогою **
|
||||||
|
def keyword_args(**kwargs):
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
# Давайте подивимось що з цього вийде
|
||||||
|
keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
|
||||||
|
|
||||||
|
# Якщо хочете, можете використовувати обидва способи одночасно
|
||||||
|
def all_the_args(*args, **kwargs):
|
||||||
|
print(args)
|
||||||
|
print(kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
all_the_args(1, 2, a=3, b=4) друкує:
|
||||||
|
(1, 2)
|
||||||
|
{"a": 3, "b": 4}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Коли викликаєте функції, то можете зробити навпаки!
|
||||||
|
# Використовуйте символ * аби розпакувати позиційні аргументи і
|
||||||
|
# ** для іменованих аргументів
|
||||||
|
args = (1, 2, 3, 4)
|
||||||
|
kwargs = {"a": 3, "b": 4}
|
||||||
|
all_the_args(*args) # еквівалентно foo(1, 2, 3, 4)
|
||||||
|
all_the_args(**kwargs) # еквівалентно foo(a=3, b=4)
|
||||||
|
all_the_args(*args, **kwargs) # еквівалентно foo(1, 2, 3, 4, a=3, b=4)
|
||||||
|
|
||||||
|
# ви можете передавати довільне число позиційних або іменованих аргументів
|
||||||
|
# іншим функціям, які їх приймають, розпаковуючи за допомогою
|
||||||
|
# * або ** відповідно
|
||||||
|
def pass_all_the_args(*args, **kwargs):
|
||||||
|
all_the_args(*args, **kwargs)
|
||||||
|
print varargs(*args)
|
||||||
|
print keyword_args(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# Область визначення функцій
|
||||||
|
x = 5
|
||||||
|
|
||||||
|
|
||||||
|
def set_x(num):
|
||||||
|
# Локальна змінна x - не те ж саме, що глобальна змінна x
|
||||||
|
x = num # => 43
|
||||||
|
print x # => 43
|
||||||
|
|
||||||
|
|
||||||
|
def set_global_x(num):
|
||||||
|
global x
|
||||||
|
print x # => 5
|
||||||
|
x = num # глобальна змінна x тепер дорівнює 6
|
||||||
|
print x # => 6
|
||||||
|
|
||||||
|
|
||||||
|
set_x(43)
|
||||||
|
set_global_x(6)
|
||||||
|
|
||||||
|
# В Python функції є об'єктами першого класу
|
||||||
|
def create_adder(x):
|
||||||
|
def adder(y):
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
return adder
|
||||||
|
|
||||||
|
|
||||||
|
add_10 = create_adder(10)
|
||||||
|
add_10(3) # => 13
|
||||||
|
|
||||||
|
# Також є і анонімні функції
|
||||||
|
(lambda x: x > 2)(3) # => True
|
||||||
|
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
|
||||||
|
|
||||||
|
# Присутні вбудовані функції вищого порядку
|
||||||
|
map(add_10, [1, 2, 3]) # => [11, 12, 13]
|
||||||
|
map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
|
||||||
|
|
||||||
|
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
||||||
|
|
||||||
|
# Для зручного відображення і фільтрації можна використовувати
|
||||||
|
# включення у вигляді списків
|
||||||
|
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
|
||||||
|
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
|
||||||
|
|
||||||
|
# Ви також можете скористатися включеннями множин та словників
|
||||||
|
{x for x in 'abcddeef' if x in 'abc'} # => {'a', 'b', 'c'}
|
||||||
|
{x: x ** 2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 5. Класи
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Аби отримати клас, ми наслідуємо object.
|
||||||
|
class Human(object):
|
||||||
|
# Атрибут класу. Він розділяється всіма екземплярами цього класу.
|
||||||
|
species = "H. sapiens"
|
||||||
|
|
||||||
|
# Звичайний конструктор, буде викликаний при ініціалізації екземпляру класу
|
||||||
|
# Зверніть увагу, що подвійне підкреслення на початку та наприкінці імені
|
||||||
|
# використовується для позначення об'єктів та атрибутів,
|
||||||
|
# які використовуються Python, але знаходяться у просторах імен,
|
||||||
|
# якими керує користувач. Не варто вигадувати для них імена самостійно.
|
||||||
|
def __init__(self, name):
|
||||||
|
# Присвоєння значення аргумента атрибуту класу name
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
# Ініціалізуємо властивість
|
||||||
|
self.age = 0
|
||||||
|
|
||||||
|
# Метод екземпляру. Всі методи приймають self у якості першого аргументу
|
||||||
|
def say(self, msg):
|
||||||
|
return "%s: %s" % (self.name, msg)
|
||||||
|
|
||||||
|
# Методи класу розділяються між усіма екземплярами
|
||||||
|
# Вони викликаються з вказанням викликаючого класу
|
||||||
|
# у якості першого аргументу
|
||||||
|
@classmethod
|
||||||
|
def get_species(cls):
|
||||||
|
return cls.species
|
||||||
|
|
||||||
|
# Статичний метод викликається без посилання на клас або екземпляр
|
||||||
|
@staticmethod
|
||||||
|
def grunt():
|
||||||
|
return "*grunt*"
|
||||||
|
|
||||||
|
# Властивість.
|
||||||
|
# Перетворює метод age() в атрибут тільки для читання
|
||||||
|
# з таким же ім'ям.
|
||||||
|
@property
|
||||||
|
def age(self):
|
||||||
|
return self._age
|
||||||
|
|
||||||
|
# Це дозволяє змінювати значення властивості
|
||||||
|
@age.setter
|
||||||
|
def age(self, age):
|
||||||
|
self._age = age
|
||||||
|
|
||||||
|
# Це дозволяє видаляти властивість
|
||||||
|
@age.deleter
|
||||||
|
def age(self):
|
||||||
|
del self._age
|
||||||
|
|
||||||
|
|
||||||
|
# Створюємо екземпляр класу
|
||||||
|
i = Human(name="Данило")
|
||||||
|
print(i.say("привіт")) # Друкує: «Данило: привіт»
|
||||||
|
|
||||||
|
j = Human("Меланка")
|
||||||
|
print(j.say("Привіт")) # Друкує: «Меланка: привіт»
|
||||||
|
|
||||||
|
# Виклик методу класу
|
||||||
|
i.get_species() # => "H. sapiens"
|
||||||
|
|
||||||
|
# Зміна розділюваного атрибуту
|
||||||
|
Human.species = "H. neanderthalensis"
|
||||||
|
i.get_species() # => "H. neanderthalensis"
|
||||||
|
j.get_species() # => "H. neanderthalensis"
|
||||||
|
|
||||||
|
# Виклик статичного методу
|
||||||
|
Human.grunt() # => "*grunt*"
|
||||||
|
|
||||||
|
# Оновлюємо властивість
|
||||||
|
i.age = 42
|
||||||
|
|
||||||
|
# Отримуємо значення
|
||||||
|
i.age # => 42
|
||||||
|
|
||||||
|
# Видаляємо властивість
|
||||||
|
del i.age
|
||||||
|
i.age # => виникає помилка атрибуту
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 6. Модулі
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Ви можете імпортувати модулі
|
||||||
|
import math
|
||||||
|
|
||||||
|
print(math.sqrt(16)) # => 4
|
||||||
|
|
||||||
|
# Ви можете імпортувати окремі функції з модуля
|
||||||
|
from math import ceil, floor
|
||||||
|
|
||||||
|
print(ceil(3.7)) # => 4.0
|
||||||
|
print(floor(3.7)) # => 3.0
|
||||||
|
|
||||||
|
# Можете імпортувати всі функції модуля.
|
||||||
|
# Попередження: краще так не робіть
|
||||||
|
from math import *
|
||||||
|
|
||||||
|
# Можете скорочувати імена модулів
|
||||||
|
import math as m
|
||||||
|
|
||||||
|
math.sqrt(16) == m.sqrt(16) # => True
|
||||||
|
# Ви також можете переконатися, що функції еквівалентні
|
||||||
|
from math import sqrt
|
||||||
|
|
||||||
|
math.sqrt == m.sqrt == sqrt # => True
|
||||||
|
|
||||||
|
# Модулі в Python — це звичайні Python-файли. Ви
|
||||||
|
# можете писати свої модулі та імпортувати їх. Назва
|
||||||
|
# модуля співпадає з назвою файлу.
|
||||||
|
|
||||||
|
# Ви можете дізнатися, які функції та атрибути визначені
|
||||||
|
# в модулі
|
||||||
|
import math
|
||||||
|
|
||||||
|
dir(math)
|
||||||
|
|
||||||
|
|
||||||
|
# Якщо у вас є Python скрипт з назвою math.py у тій же папці, що
|
||||||
|
# і ваш поточний скрипт, то файл math.py
|
||||||
|
# може бути завантажено замість вбудованого у Python модуля.
|
||||||
|
# Так трапляється, оскільки локальна папка має перевагу
|
||||||
|
# над вбудованими у Python бібліотеками.
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 7. Додатково
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Генератори
|
||||||
|
# Генератор "генерує" значення тоді, коли вони запитуються, замість того,
|
||||||
|
# щоб зберігати все одразу
|
||||||
|
|
||||||
|
# Метод нижче (*НЕ* генератор) подвоює всі значення і зберігає їх
|
||||||
|
# в `double_arr`. При великих розмірах може знадобитися багато ресурсів!
|
||||||
|
def double_numbers(iterable):
|
||||||
|
double_arr = []
|
||||||
|
for i in iterable:
|
||||||
|
double_arr.append(i + i)
|
||||||
|
return double_arr
|
||||||
|
|
||||||
|
|
||||||
|
# Тут ми спочатку подвоюємо всі значення, потім повертаємо їх,
|
||||||
|
# аби перевірити умову
|
||||||
|
for value in double_numbers(range(1000000)): # `test_non_generator`
|
||||||
|
print value
|
||||||
|
if value > 5:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# Натомість ми можемо скористатися генератором, аби "згенерувати"
|
||||||
|
# подвійне значення, як тільки воно буде запитане
|
||||||
|
def double_numbers_generator(iterable):
|
||||||
|
for i in iterable:
|
||||||
|
yield i + i
|
||||||
|
|
||||||
|
|
||||||
|
# Той самий код, але вже з генератором, тепер дозволяє нам пройтися по
|
||||||
|
# значенням і подвоювати їх одне за одним якраз тоді, коли вони обробляються
|
||||||
|
# за нашою логікою, одне за одним. А як тільки ми бачимо, що value > 5, ми
|
||||||
|
# виходимо з циклу і більше не подвоюємо більшість значень,
|
||||||
|
# які отримали на вхід (НАБАГАТО ШВИДШЕ!)
|
||||||
|
for value in double_numbers_generator(xrange(1000000)): # `test_generator`
|
||||||
|
print value
|
||||||
|
if value > 5:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Між іншим: ви помітили використання `range` у `test_non_generator` і
|
||||||
|
# `xrange` у `test_generator`?
|
||||||
|
# Як `double_numbers_generator` є версією-генератором `double_numbers`, так
|
||||||
|
# і `xrange` є аналогом `range`, але у вигляді генератора.
|
||||||
|
# `range` поверне нам масив з 1000000 значень
|
||||||
|
# `xrange`, у свою чергу, згенерує 1000000 значень для нас тоді,
|
||||||
|
# коли ми їх запитуємо / будемо проходитись по ним.
|
||||||
|
|
||||||
|
# Аналогічно включенням у вигляді списків, ви можете створювати включення
|
||||||
|
# у вигляді генераторів.
|
||||||
|
values = (-x for x in [1, 2, 3, 4, 5])
|
||||||
|
for x in values:
|
||||||
|
print(x) # друкує -1 -2 -3 -4 -5
|
||||||
|
|
||||||
|
# Включення у вигляді генератора можна явно перетворити у список
|
||||||
|
values = (-x for x in [1, 2, 3, 4, 5])
|
||||||
|
gen_to_list = list(values)
|
||||||
|
print(gen_to_list) # => [-1, -2, -3, -4, -5]
|
||||||
|
|
||||||
|
# Декоратори
|
||||||
|
# Декоратор – це функція вищого порядку, яка приймає та повертає функцію.
|
||||||
|
# Простий приклад використання – декоратор add_apples додає елемент 'Apple' в
|
||||||
|
# список fruits, який повертає цільова функція get_fruits.
|
||||||
|
def add_apples(func):
|
||||||
|
def get_fruits():
|
||||||
|
fruits = func()
|
||||||
|
fruits.append('Apple')
|
||||||
|
return fruits
|
||||||
|
return get_fruits
|
||||||
|
|
||||||
|
@add_apples
|
||||||
|
def get_fruits():
|
||||||
|
return ['Banana', 'Mango', 'Orange']
|
||||||
|
|
||||||
|
# Друкуємо список разом з елементом 'Apple', який знаходиться в ньому:
|
||||||
|
# Banana, Mango, Orange, Apple
|
||||||
|
print ', '.join(get_fruits())
|
||||||
|
|
||||||
|
# У цьому прикладі beg обертає say
|
||||||
|
# Beg викличе say. Якщо say_please дорівнюватиме True, то повідомлення,
|
||||||
|
# що повертається, буде змінено.
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def beg(target_function):
|
||||||
|
@wraps(target_function)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
msg, say_please = target_function(*args, **kwargs)
|
||||||
|
if say_please:
|
||||||
|
return "{} {}".format(msg, "Будь ласка! Я бідний :(")
|
||||||
|
return msg
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@beg
|
||||||
|
def say(say_please=False):
|
||||||
|
msg = "Ви можете купити мені пива?"
|
||||||
|
return msg, say_please
|
||||||
|
|
||||||
|
|
||||||
|
print say() # Ви можете купити мені пива?
|
||||||
|
print say(say_please=True) # Ви можете купити мені пива? Будь ласка! Я бідний :(
|
||||||
|
```
|
||||||
|
|
||||||
|
## Готові до більшого?
|
||||||
|
|
||||||
|
### Безкоштовні онлайн-матеріали
|
||||||
|
|
||||||
|
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
|
||||||
|
* [Dive Into Python](http://www.diveintopython.net/)
|
||||||
|
* [Официальная документация](http://docs.python.org/2.6/)
|
||||||
|
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||||
|
* [Python Module of the Week](http://pymotw.com/2/)
|
||||||
|
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
|
||||||
|
|
||||||
|
### Платні
|
||||||
|
|
||||||
|
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||||
|
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||||
|
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
||||||
|
|
@@ -5,7 +5,7 @@ contributors:
|
|||||||
filename: learnvisualbasic.vb
|
filename: learnvisualbasic.vb
|
||||||
---
|
---
|
||||||
|
|
||||||
```vbnet
|
```
|
||||||
Module Module1
|
Module Module1
|
||||||
|
|
||||||
Sub Main()
|
Sub Main()
|
||||||
|
@@ -41,7 +41,7 @@ enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
|
|||||||
void function_1(char c);
|
void function_1(char c);
|
||||||
void function_2(void);
|
void function_2(void);
|
||||||
|
|
||||||
// 如果函数出现在main()之后,那么必须在main()之前
|
// 如果函数调用在main()之后,那么必须在main()之前
|
||||||
// 先声明一个函数原型
|
// 先声明一个函数原型
|
||||||
int add_two_ints(int x1, int x2); // 函数原型
|
int add_two_ints(int x1, int x2); // 函数原型
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ lang: zh-cn
|
|||||||
filename: learnvisualbasic-cn.vb
|
filename: learnvisualbasic-cn.vb
|
||||||
---
|
---
|
||||||
|
|
||||||
```vbnet
|
```
|
||||||
Module Module1
|
Module Module1
|
||||||
|
|
||||||
Sub Main()
|
Sub Main()
|
||||||
|
Reference in New Issue
Block a user