diff options
241 files changed, 24037 insertions, 9743 deletions
diff --git a/ATS.html.markdown b/ATS.html.markdown new file mode 100644 index 00000000..f290ac0f --- /dev/null +++ b/ATS.html.markdown @@ -0,0 +1,607 @@ +--- +language: ATS +contributors: + - ["Mark Barbone", "https://github.com/mb64"] +filename: learnats.dats +--- + +ATS is a low-level functional programming language. It has a powerful type +system which lets you write programs with the same level of control and +efficiency as C, but in a memory safe and type safe way. + +The ATS type system supports: + +* Full type erasure: ATS compiles to efficient C +* Dependent types, including [LF](http://twelf.org/wiki/LF) and proving + metatheorems +* Refinement types +* Linearity for resource tracking +* An effect system that tracks exceptions, mutation, termination, and other + side effects + +This tutorial is not an introduction to functional programming, dependent types, +or linear types, but rather to how they all fit together in ATS. That said, ATS +is a very complex language, and this tutorial doesn't cover it all. Not only +does ATS's type system boast a wide array of confusing features, its +idiosyncratic syntax can make even "simple" examples hard to understand. In the +interest of keeping it a reasonable length, this document is meant to give a +taste of ATS, giving a high-level overview of what's possible and how, rather +than attempting to fully explain how everything works. + +You can [try ATS in your browser](http://www.ats-lang.org/SERVER/MYCODE/Patsoptaas_serve.php), +or install it from [http://www.ats-lang.org/](http://www.ats-lang.org/). + + +```ocaml +// Include the standard library +#include "share/atspre_define.hats" +#include "share/atspre_staload.hats" + +// To compile, either use +// $ patscc -DATS_MEMALLOC_LIBC program.dats -o program +// or install the ats-acc wrapper https://github.com/sparverius/ats-acc and use +// $ acc pc program.dats + +// C-style line comments +/* and C-style block comments */ +(* as well as ML-style block comments *) + +/*************** Part 1: the ML fragment ****************/ + +val () = print "Hello, World!\n" + +// No currying +fn add (x: int, y: int) = x + y + +// fn vs fun is like the difference between let and let rec in OCaml/F# +fun fact (n: int): int = if n = 0 then 1 else n * fact (n-1) + +// Multi-argument functions need parentheses when you call them; single-argument +// functions can omit parentheses +val forty_three = add (fact 4, 19) + +// let is like let in SML +fn sum_and_prod (x: int, y: int): (int, int) = + let + val sum = x + y + val prod = x * y + in (sum, prod) end + +// 'type' is the type of all heap-allocated, non-linear types +// Polymorphic parameters go in {} after the function name +fn id {a:type} (x: a) = x + +// ints aren't heap-allocated, so we can't pass them to 'id' +// val y: int = id 7 // doesn't compile + +// 't@ype' is the type of all non-linear potentially unboxed types. It is a +// supertype of 'type'. +// Templated parameters go in {} before the function name +fn {a:t@ype} id2 (x: a) = x + +val y: int = id2 7 // works + +// can't have polymorphic t@ype parameters +// fn id3 {a:t@ype} (x: a) = x // doesn't compile + +// explicity specifying type parameters: +fn id4 {a:type} (x: a) = id {a} x // {} for non-template parameters +fn id5 {a:type} (x: a) = id2<a> x // <> for template parameters +fn id6 {a:type} (x: a) = id {..} x // {..} to explicitly infer it + +// Heap allocated shareable datatypes +// using datatypes leaks memory +datatype These (a:t@ype, b:t@ype) = This of a + | That of b + | These of (a, b) + +// Pattern matching using 'case' +fn {a,b: t@ype} from_these (x: a, y: b, these: These(a,b)): (a, b) = + case these of + | This(x) => (x, y) // Shadowing of variable names is fine; here, x shadows + // the parameter x + | That(y) => (x, y) + | These(x, y) => (x, y) + +// Partial pattern match using 'case-' +// Will throw an exception if passed This +fn {a,b:t@ype} unwrap_that (these: These(a,b)): b = + case- these of + | That(y) => y + | These(_, y) => y + + +/*************** Part 2: refinements ****************/ + +// Parameterize functions by what values they take and return +fn cool_add {n:int} {m:int} (x: int n, y: int m): int (n+m) = x + y + +// list(a, n) is a list of n a's +fun square_all {n:int} (xs: list(int, n)): list(int, n) = + case xs of + | list_nil() => list_nil() + | list_cons(x, rest) => list_cons(x * x, square_all rest) + +fn {a:t@ype} get_first {n:int | n >= 1} (xs: list(a, n)): a = + case+ xs of // '+' asks ATS to prove it's total + | list_cons(x, _) => x + +// Can't run get_first on lists of length 0 +// val x: int = get_first (list_nil()) // doesn't compile + +// in the stdlib: +// sortdef nat = {n:int | n >= 0} +// sortdef pos = {n:int | n >= 1} + +fn {a:t@ype} also_get_first {n:pos} (xs: list(a, n)): a = + let + val+ list_cons(x, _) = xs // val+ also works + in x end + +// tail-recursive reverse +fun {a:t@ype} reverse {n:int} (xs: list(a, n)): list(a, n) = + let + // local functions can use type variables from their enclosing scope + // this one uses both 'a' and 'n' + fun rev_helper {i:nat} (xs: list(a, n-i), acc: list(a, i)): list(a, n) = + case xs of + | list_nil() => acc + | list_cons(x, rest) => rev_helper(rest, list_cons(x, acc)) + in rev_helper(xs, list_nil) end + +// ATS has three context-dependent namespaces +// the two 'int's mean different things in this example, as do the two 'n's +fn namespace_example {n:int} (n: int n): int n = n +// ^^^ sort namespace +// ^ ^^^ ^ ^^^ ^ statics namespace +// ^^^^^^^^^^^^^^^^^ ^ ^ value namespace + +// a termination metric can go in .< >. +// it must decrease on each recursive call +// then ATS will prove it doesn't infinitely recurse +fun terminating_factorial {n:nat} .<n>. (n: int n): int = + if n = 0 then 1 else n * terminating_factorial (n-1) + + +/*************** Part 3: the LF fragment ****************/ + +// ATS supports proving theorems in LF (http://twelf.org/wiki/LF) + +// Relations are represented by inductive types + +// Proofs that the nth fibonacci number is f +dataprop Fib(n:int, m:int) = + | FibZero(0, 0) + | FibOne(1, 1) + | {n, f1, f2: int} FibInd(n, f1 + f2) of (Fib(n-1,f1), Fib(n-2,f2)) + +// Proved-correct fibonacci implementation +// [A] B is an existential type: "there exists A such that B" +// (proof | value) +fun fib {n:nat} .<n>. (n: int n): [f:int] (Fib(n,f) | int f) = + if n = 0 then (FibZero | 0) else + if n = 1 then (FibOne | 1) else + let + val (proof1 | val1) = fib (n-1) + val (proof2 | val2) = fib (n-2) + // the existential type is inferred + in (FibInd(proof1, proof2) | val1 + val2) end + +// Faster proved-correct fibonacci implementation +fn fib_tail {n:nat} (n: int n): [f:int] (Fib(n,f) | int f) = + let + fun loop {i:int | i < n} {f1, f2: int} .<n - i>. + (p1: Fib(i,f1), p2: Fib(i+1,f2) + | i: int i, f1: int f1, f2: int f2, n: int n + ): [f:int] (Fib(n,f) | int f) = + if i = n - 1 + then (p2 | f2) + else loop (p2, FibInd(p2,p1) | i+1, f2, f1+f2, n) + in if n = 0 then (FibZero | 0) else loop (FibZero, FibOne | 0, 0, 1, n) end + +// Proof-level lists of ints, of type 'sort' +datasort IntList = ILNil of () + | ILCons of (int, IntList) + +// ILAppend(x,y,z) iff x ++ y = z +dataprop ILAppend(IntList, IntList, IntList) = + | {y:IntList} AppendNil(ILNil, y, y) + | {a:int} {x,y,z: IntList} + AppendCons(ILCons(a,x), y, ILCons(a,z)) of ILAppend(x,y,z) + +// prfuns/prfns are compile-time functions acting on proofs + +// metatheorem: append is total +prfun append_total {x,y: IntList} .<x>. (): [z:IntList] ILAppend(x,y,z) + = scase x of // scase lets you inspect static arguments (only in prfuns) + | ILNil() => AppendNil + | ILCons(a,rest) => AppendCons(append_total()) + + +/*************** Part 4: views ****************/ + +// views are like props, but linear; ie they must be consumed exactly once +// prop is a subtype of view + +// 'type @ address' is the most basic view + +fn {a:t@ype} read_ptr {l:addr} (pf: a@l | p: ptr l): (a@l | a) = + let + // !p searches for usable proofs that say something is at that address + val x = !p + in (pf | x) end + +// oops, tried to dereference a potentially invalid pointer +// fn {a:t@ype} bad {l:addr} (p: ptr l): a = !p // doesn't compile + +// oops, dropped the proof (leaked the memory) +// fn {a:t@ype} bad {l:addr} (pf: a@l | p: ptr l): a = !p // doesn't compile + +fn inc_at_ptr {l:addr} (pf: int@l | p: ptr l): (int@l | void) = + let + // !p := value writes value to the location at p + // like !p, it implicitly searches for usable proofs that are in scope + val () = !p := !p + 1 + in (pf | ()) end + +// threading proofs through gets annoying +fn inc_three_times {l:addr} (pf: int@l | p: ptr l): (int@l | void) = + let + val (pf2 | ()) = inc_at_ptr (pf | p) + val (pf3 | ()) = inc_at_ptr (pf2 | p) + val (pf4 | ()) = inc_at_ptr (pf3 | p) + in (pf4 | ()) end + +// so there's special syntactic sugar for when you don't consume a proof +fn dec_at_ptr {l:addr} (pf: !int@l | p: ptr l): void = + !p := !p - 1 // ^ note the exclamation point + +fn dec_three_times {l:addr} (pf: !int@l | p: ptr l): void = + let + val () = dec_at_ptr (pf | p) + val () = dec_at_ptr (pf | p) + val () = dec_at_ptr (pf | p) + in () end + +// dataview is like dataprop, but linear +// A proof that either the address is null, or there is a value there +dataview MaybeNull(a:t@ype, addr) = + | NullPtr(a, null) + | {l:addr | l > null} NonNullPtr(a, l) of (a @ l) + +fn maybe_inc {l:addr} (pf: !MaybeNull(int, l) | p: ptr l): void = + if ptr1_is_null p + then () + else let + // Deconstruct the proof to access the proof of a @ l + prval NonNullPtr(value_exists) = pf + val () = !p := !p + 1 + // Reconstruct it again for the caller + prval () = pf := NonNullPtr(value_exists) + in () end + +// array_v(a,l,n) represents and array of n a's at location l +// this gets compiled into an efficient for loop, since all proofs are erased +fn sum_array {l:addr}{n:nat} (pf: !array_v(int,l,n) | p: ptr l, n: int n): int = + let + fun loop {l:addr}{n:nat} .<n>. ( + pf: !array_v(int,l,n) + | ptr: ptr l, + length: int n, + acc: int + ): int = if length = 0 + then acc + else let + prval (head, rest) = array_v_uncons(pf) + val result = loop(rest | ptr_add<int>(ptr, 1), length - 1, acc + !ptr) + prval () = pf := array_v_cons(head, rest) + in result end + in loop (pf | p, n, 0) end + +// 'var' is used to create stack-allocated (lvalue) variables +val seven: int = let + var res: int = 3 + // they can be modified + val () = res := res + 1 + // addr@ res is a pointer to it, and view@ res is the associated proof + val (pf | ()) = inc_three_times(view@ res | addr@ res) + // need to give back the view before the variable goes out of scope + prval () = view@ res := pf + in res end + +// References let you pass lvalues, like in C++ +fn square (x: &int): void = + x := x * x // they can be modified + +val sixteen: int = let + var res: int = 4 + val () = square res + in res end + +fn inc_at_ref (x: &int): void = + let + // like vars, references have views and addresses + val (pf | ()) = inc_at_ptr(view@ x | addr@ x) + prval () = view@ x := pf + in () end + +// Like ! for views, & references are only legal as argument types +// fn bad (x: &int): &int = x // doesn't compile + +// this takes a proof int n @ l, but returns a proof int (n+1) @ l +// since they're different types, we can't use !int @ l like before +fn refined_inc_at_ptr {n:int}{l:addr} ( + pf: int n @ l | p: ptr l +): (int (n+1) @ l | void) = + let + val () = !p := !p + 1 + in (pf | ()) end + +// special syntactic sugar for returning a proof at a different type +fn refined_dec_at_ptr {n:int}{l:addr} ( + pf: !int n @ l >> int (n-1) @ l | p: ptr l +): void = + !p := !p - 1 + +// legal but very bad code +prfn swap_proofs {v1,v2:view} (a: !v1 >> v2, b: !v2 >> v1): void = + let + prval tmp = a + prval () = a := b + prval () = b := tmp + in () end + +// also works with references +fn refined_square {n:int} (x: &int n >> int (n*n)): void = + x := x * x + +fn replace {a,b:vtype} (dest: &a >> b, src: b): a = + let + val old = dest + val () = dest := src + in old end + +// values can be uninitialized +fn {a:vt@ype} write (place: &a? >> a, value: a): void = + place := value + +val forty: int = let + var res: int + val () = write (res, 40) + in res end + +// viewtype: a view and a type +viewtypedef MaybeNullPtr(a:t@ype) = [l:addr] (MaybeNull(a, l) | ptr l) +// MaybeNullPtr has type 'viewtype' (aka 'vtype') +// type is a subtype of vtype and t@ype is a subtype of vt@ype + +// The most general identity function: +fn {a:vt@ype} id7 (x: a) = x + +// since they contain views, viewtypes must be used linearly +// fn {a:vt@ype} duplicate (x: a) = (x, x) // doesn't compile +// fn {a:vt@ype} ignore (x: a) = () // doesn't compile + +// arrayptr(a,l,n) is a convenient built-in viewtype +fn easier_sum_array {l:addr}{n:nat} (p: !arrayptr(int,l,n), n: int n): int = + let + fun loop {i:nat | i <= n} ( + p: !arrayptr(int,l,n), n: int n, i: int i, acc: int + ): int = + if i = n + then acc + else loop(p, n, i+1, acc + p[i]) + in loop(p, n, 0, 0) end + + +/*************** Part 5: dataviewtypes ****************/ + +// a dataviewtype is a heap-allocated non-shared inductive type + +// in the stdlib: +// dataviewtype list_vt(a:vt@ype, int) = +// | list_vt_nil(a, 0) +// | {n:nat} list_vt_cons(a, n+1) of (a, list_vt(a, n)) + +fn {a:vt@ype} length {n:int} (l: !list_vt(a, n)): int n = + let // ^ since we're not consuming it + fun loop {acc:int} (l: !list_vt(a, n-acc), acc: int acc): int n = + case l of + | list_vt_nil() => acc + | list_vt_cons(head, tail) => loop(tail, acc + 1) + in loop (l, 0) end + +// vvvvv not vt@ype, because you can't easily get rid of a vt@ype +fun {a:t@ype} destroy_list {n:nat} (l: list_vt(a,n)): void = + case l of + // ~ pattern match consumes and frees that node + | ~list_vt_nil() => () + | ~list_vt_cons(_, tail) => destroy_list tail + +// unlike a datatype, a dataviewtype can be modified: +fun {a:vt@ype} push_back {n:nat} ( + x: a, + l: &list_vt(a,n) >> list_vt(a,n+1) +): void = + case l of + | ~list_vt_nil() => l := list_vt_cons(x, list_vt_nil) + // @ pattern match disassembles/"unfolds" the datavtype's view, so you can + // modify its components + | @list_vt_cons(head, tail) => let + val () = push_back (x, tail) + // reassemble it with fold@ + prval () = fold@ l + in () end + +fun {a:vt@ype} pop_last {n:pos} (l: &list_vt(a,n) >> list_vt(a,n-1)): a = + let + val+ @list_vt_cons(head, tail) = l + in case tail of + | list_vt_cons _ => let + val res = pop_last tail + prval () = fold@ l + in res end + | ~list_vt_nil() => let + val head = head + // Deallocate empty datavtype nodes with free@ + val () = free@{..}{0} l + val () = l := list_vt_nil() + in head end + /** Equivalently: + * | ~list_vt_nil() => let + * prval () = fold@ l + * val+ ~list_vt_cons(head, ~list_vt_nil()) = l + * val () = l := list_vt_nil() + * in head end + */ + end + +// "holes" (ie uninitialized memory) can be created with _ on the RHS +// This function uses destination-passing-style to copy the list in a single +// tail-recursive pass. +fn {a:t@ype} copy_list {n:nat} (l: !list_vt(a, n)): list_vt(a, n) = + let + var res: ptr + fun loop {k:nat} (l: !list_vt(a, k), hole: &ptr? >> list_vt(a, k)): void = + case l of + | list_vt_nil() => hole := list_vt_nil + | list_vt_cons(first, rest) => let + val () = hole := list_vt_cons{..}{k-1}(first, _) + // ^ on RHS: a hole + val+list_vt_cons(_, new_hole) = hole + // ^ on LHS: wildcard pattern (not a hole) + val () = loop (rest, new_hole) + prval () = fold@ hole + in () end + val () = loop (l, res) + in res end + +// Reverse a linked-list *in place* -- no allocations or frees +fn {a:vt@ype} in_place_reverse {n:nat} (l: list_vt(a, n)): list_vt(a, n) = + let + fun loop {k:nat} (l: list_vt(a, n-k), acc: list_vt(a, k)): list_vt(a, n) = + case l of + | ~list_vt_nil() => acc + | @list_vt_cons(x, tail) => let + val rest = replace(tail, acc) + // the node 'l' is now part of acc instead of the original list + prval () = fold@ l + in loop (rest, l) end + in loop (l, list_vt_nil) end + + +/*************** Part 6: miscellaneous extras ****************/ + +// a record +// Point has type 't@ype' +typedef Point = @{ x= int, y= int } +val origin: Point = @{ x= 0, y= 0 } + +// tuples and records are normally unboxed, but there are boxed variants +// BoxedPoint has type 'type' +typedef BoxedPoint = '{ x= int, y= int } +val boxed_pair: '(int,int) = '(5, 3) + +// When passing a pair as the single argument to a function, it needs to be +// written @(a,b) to avoid ambiguity with multi-argument functions +val six_plus_seven = let + fun sum_of_pair (pair: (int,int)) = pair.0 + pair.1 + in sum_of_pair @(6, 7) end + +// When a constructor has no associated data, such as None(), the parentheses +// are optional in expressions. However, they are mandatory in patterns +fn inc_option (opt: Option int) = + case opt of + | Some(x) => Some(x+1) + | None() => None + +// ATS has a simple FFI, since it compiles to C and (mostly) uses the C ABI +%{ +// Inline C code +int scanf_wrapper(void *format, void *value) { + return scanf((char *) format, (int *) value); +} +%} +// If you wanted to, you could define a custom dataviewtype more accurately +// describing the result of scanf +extern fn scanf (format: string, value: &int): int = "scanf_wrapper" + +fn get_input_number (): Option int = + let + var x: int = 0 + in + if scanf("%d\n", x) = 1 + then Some(x) + else None + end + +// extern is also used for separate declarations and definitions +extern fn say_hi (): void +// later on, or in another file: +implement say_hi () = print "hi\n" + +// if you implement main0, it will run as the main function +// implmnt is an alias for implement +implmnt main0 () = () + +// as well as for axioms: +extern praxi view_id {a:view} (x: a): a +// you don't need to actually implement the axioms, but you could +primplmnt view_id x = x +// primplmnt is an alias for primplement + +// Some standard aliases are: +// List0(a) = [n:nat] list(a,n) and List0_vt(a) = [n:nat] list_vt(a,n) +// t0p = t@ype and vt0p = vt@ype +fun {a:t0p} append (xs: List0 a, ys: List0 a): List0 a = + case xs of + | list_nil() => ys + | list_cons(x, xs) => list_cons(x, append(xs, ys)) + +// there are many ways of doing things after one another +val let_in_example = let + val () = print "thing one\n" + val () = print "thing two\n" + in () end + +val parens_example = (print "thing one\n"; print "thing two\n") + +val begin_end_example = begin + print "thing one\n"; + print "thing two\n"; // optional trailing semicolon + end + +// and many ways to use local variables +fun times_four_let x = + let + fun times_two (x: int) = x * 2 + in times_two (times_two x) end + +local + fun times_two (x: int) = x * 2 +in + fun times_four_local x = times_two (times_two x) +end + +fun times_four_where x = times_two (times_two x) + where { + fun times_two (x: int) = x * 2 + } + +//// The last kind of comment in ATS is an end-of-file comment. + +Anything between the four slashes and the end of the file is ignored. + +Have fun with ATS! +``` + +## Learn more + +This isn't all there is to ATS -- notably, some core features like closures and +the effect system are left out, as well as other less type-y stuff like modules +and the build system. If you'd like to write these sections yourself, +contributions would be welcome! + +To learn more about ATS, visit the [ATS website](http://www.ats-lang.org/), in +particular the [documentation page](http://www.ats-lang.org/Documents.html). + diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 430ecea0..f3556efa 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -34,7 +34,7 @@ review them more effectively and/or individually. * **Use UTF-8** * For translations (or EN articles with non-ASCII characters) please ensure your file is UTF-8 encoded. - * Try to leave out the byte-order-mark at the start of the file (in Vim, use + * Leave out the byte-order-mark (BOM) at the start of the file (in Vim, use `:set nobomb`). * You can check if the file contains a BOM on Linux/Unix systems by running `file language.html.markdown` You will see this if it uses a BOM: @@ -58,7 +58,7 @@ Other fields: *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted. * **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. - * For non-English articles, *filename* should have a language-specific + * For non-English articles, *filename* should have a language-specific suffix. * **lang**: For translations, the human language this article is in. For categorization, mostly. @@ -76,7 +76,11 @@ lang: ep-ep *-- ``` -### Should I add myself as a Contributor? +### Syntax highlighter + +[Rouge](https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers) is used for syntax highlighting. + +### Should I add myself as a contributor? If you want to add yourself to contributors, keep in mind that contributors get equal billing, and the first contributor usually wrote the whole article. Please diff --git a/ada.html.markdown b/ada.html.markdown new file mode 100644 index 00000000..7191c5dc --- /dev/null +++ b/ada.html.markdown @@ -0,0 +1,416 @@ +--- +language: Ada +filename: learn.ada +contributors: + - ["Luke A. Guest", "https://github.com/Lucretia"] + - ["Fernando Oleo Blanco", "https://github.com/Irvise"] + - ["Fabien Chouteau", "https://github.com/Fabien-Chouteau"] + - ["Manuel", "https://github.com/mgrojo"] +--- + +Ada is a strong statically typed imperative, [object-oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9), [real-time](https://ada-lang.io/docs/arm/AA-D), [parallel](https://ada-lang.io/docs/arm/AA-9) and [distributed](https://ada-lang.io/docs/arm/AA-9) programming language from the Pascal/Algol family of languages, but nowadays, it only has a passing resemblance to Pascal, with the only remnants left being the ```begin/end``` keyword pair, the ```:=``` assignment symbol, records and ```if/case``` control statement structures. + +Ada was originally designed to be an [object-based](https://ada-lang.io/docs/arm/AA-3/AA-3.3) language and to replace 100's of languages in use by the US government. This means that all entities are objects, not in the object-oriented sense. The language became [Object-Oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9) in 1995, and added [interfaces](https://ada-lang.io/docs/arm/AA-3/AA-3.9#Subclause_3.9.4) derived from Java in 2005. [Contract based](https://ada-lang.io/docs/arm/AA-13/AA-13.1#Subclause_13.1.1) programming was introduced with Ada 2012. + +Ada was designed to be easy to read and learn, even for non-programmers, e.g. management within an organisation, therefore programs written in the language tend to be a bit more verbose. + +Ada is a modern programming language, and now has a package manager like other modern languages, Alire, see below. + +```ada +-- Comments are written with a double hyphen and exist until the end of +-- the line. + +-- You do not need to call the entry point "Main" or "main," you should +-- name it based on what the program does. +procedure Empty is + -- This is a declarative part. +begin + -- Statements go here. + null; -- Do nothing here. +end Empty; + +-- Ada compilers accept compilation units which can be library packages, +-- tasks, sub-programs, generics, etc. + +-- This is where "context clauses" go, these can be pragmas or "with" +-- statements. "with" is equivalent to "include" or "import" in other +-- languages. +with Ada.Text_IO; -- Get access to a library package. + +procedure Hello is +begin + Ada.Text_IO.Put_Line ("Hello, world"); + + Ada.Text_IO.Put ("Hello again, world"); + Ada.Text_IO.New_Line; +end Hello; + + +-- Ada has a real module system. Modules are called packages and are split into +-- two component parts, the specification and a body. +-- It is important to introduce packages early, as you will be using them from +-- the start. +package Stuff is + -- We could add the following line in order to tell the compiler that this + -- package does not have to run any code before the "main" procedure starts. + -- pragma Preelaborate; + + -- Packages can be nested within the same file or externally. + -- Nested packages are accessed via dot notation, e.g. Stuff.Things.My. + package Things is + My : constant Integer := 100; + end Things; + + -- If there are sub-programs declared within the specification, the body + -- of the sub-program must be declared within the package body. + procedure Do_Something; -- If a subprogram takes no parameters, empty + -- parentheses are not required, unlike other + -- languages. + + -- We can also make generic sub-programs. + generic + type Element is (<>); -- The "(<>)" notation specifies that only + -- discrete types can be passed into the generic. + procedure Swap (Left, Right : in out Element); + + -- Sometimes we want to hide how a type is defined from the outside world + -- so that nobody can mess with it directly. The full type must be defined + -- within the private section below. + type Blobs is private; + + -- We can also make types "limited" by putting this keyword after the "is" + -- keyword, this means that the user cannot copy objects of that type + -- around, like they normally could. +private + type Blobs is new Integer range -25 .. 25; +end Stuff; + + +package body Stuff is + -- Sub-program body. + procedure Do_Something is + -- We can nest sub-programs too. + -- Parameters are defined with the direction of travel, in, in out, out. + -- If the direction of travel is not specified, they are in by default. + function Times_4 (Value : in Integer) return Integer is + begin + return Value * 4; + end Times_4; + + I : Integer := 4; + begin + I := Times_4 (I); + end Do_Something; + + + -- Generic procedure body. + procedure Swap (Left, Right : in out Element) is + Temp : Element := Left; + begin + Left := Right; + Right := Temp; + end Swap; +begin + -- If we need to initialise something within the package, we can do it + -- here. + Do_Something; +end Stuff; + + +with Ada.Unchecked_Conversion; +with Ada.Text_IO; +with Stuff; + +procedure LearnAdaInY is + -- Indentation is 3 spaces. + + -- The most important feature in Ada is the type. Objects have types and an + -- object of one type cannot be assigned to an object of another type. + + -- You can, and should, define your own types for the domain you are + -- modelling. But you can use the standard types to start with and then + -- replace them later with your own types, this could be called a form of + -- gradual typing. + + -- The standard types would only really be a good starting point for binding + -- to other languages, like C. Ada is the only language with a standardised + -- way to bind with C, Fortran and COBOL! See the links in the References + -- section with more information on binding to these languages. + + type Degrees is range 0 .. 360; -- This is a type. Its underlying + -- representation is an Integer. + + type Hues is (Red, Green, Blue, Purple, Yellow); -- So is this. Here, we + -- are declaring an + -- Enumeration. + + -- This is a modular type. They behave like Integers that automatically + -- wrap around. In this specific case, the range would be 0 .. 359. + -- If we added 1 to a variable containing the value 359, we would receive + -- back 0. They are very useful for arrays. + type Degrees_Wrap is mod 360; + + -- You can restrict a type's range using a subtype, this makes them + -- compatible with each other, i.e. the subtype can be assigned to an + -- object of the type, as can be seen below. + subtype Primaries is Hues range Red .. Blue; -- This is a range. + + -- You can define variables or constants like this: + -- Var_Name : Type := Value; + + -- 10 is a universal integer. These universal numerics can be used with + -- any type which matches the base type. + Angle : Degrees := 10; + Value : Integer := 20; + -- New_Angle : Degrees := Value; -- Incompatible types won't compile. + -- New_Value : Integer := Angle; + + Blue_Hue : Primaries := Blue; -- A variable. + Red_Hue : constant Primaries := Red; -- A constant. + Yellow_Hue : constant Hues := Yellow; + Colour_1 : constant Hues := Red_Hue; + -- Colour_2 : constant Primaries := Yellow_Hue; -- uncomment to compile. + + -- You can force conversions, but then you are warned by the name of the + -- package that you may be doing something unsafe. + function Degrees_To_Int is new Ada.Unchecked_Conversion + (Source => Degrees, -- Line continuations are indented by 2 spaces. + Target => Integer); + + New_Value_2 : Integer := Degrees_To_Int (Angle); -- Note, space before (. + + -- GNAT is the GNU Ada Translator (compiler). + -- Ada has a style guide and GNAT will warn you to adhere to it, and has + -- option to check your style so that you can correct it so that all Ada + -- source looks consistent. However, the style can be customized. + + -- Yes, you can even define your own floating and fixed point types, this + -- is a very rare and unique ability. "digits" refers to the minimum + -- digit precision that the type should support. "delta" is for fixed + -- point types and refers to the smallest change that the type will support. + type Real_Angles is digits 3 range 0.0 .. 360.0; + type Fixed_Angles is delta 0.01 digits 5 range 0.0 .. 360.0; + + RA : constant Real_Angles := 36.45; + FA : constant Fixed_Angles := 360.0; -- ".0" in order to make it a Float. + + -- You can have normal Latin 1 based strings by default. + Str : constant String := "This is a constant string"; + -- When initialising from a string literal, the compiler knows the bounds, + -- so we don't have to define them. + + -- Strings are arrays. Note how parentheses are used to access elements of + -- an array? This is mathematical notation and was used because square + -- brackets were not available on all keyboards at the time Ada was + -- created. Also, because an array can be seen as a function from a + -- mathematical perspective, so it made converting between arrays and + -- functions easier. + Char : constant Character := Str (Str'First); -- "'First" is a type + -- attribute. + + -- Ada 2022 includes the use of [] for array initialisation when using + -- containers, which were added in Ada 2012. + + -- Arrays are usually always defined as a type. + -- They can be any dimension. + type My_Array_1 is array (1 .. 4, 3 .. 7, -20 .. 20) of Integer; + + -- Yes, unlike other languages, you can index arrays with other discrete + -- types such as enumerations and modular types or arbitrary ranges. + type Axes is (X, Y, Z); + + -- You can define the array's range using the 'Range attribute from + -- another type. + type Vector is array (Axes'Range) of Float; + + V1 : constant Vector := (0.0, 0.0, 1.0); + + -- A record is the same as a structure in C, C++. + type Entities is record + Name : String (1 .. 10); -- Always starts at a positive value, + -- inclusive range. + Position : Vector; + end record; + + -- In Ada, array bounds are immutable. You therefore have to provide a + -- string literal with a value for every character. + E1 : constant Entities := ("Blob ", (0.0, 0.0, 0.0)); + + -- An alternative is to use an array aggregate and assign a default value + -- to every element that wasn't previously assigned in this aggregate. + -- "others" is used to indicate anything else that has not been + -- explicitly initialized. + E2 : constant Entities := (('B', 'l', 'o', 'b', others => ' '), + (0.0, 0.0, 0.0)); + + -- There are dynamic length strings (see references section) available in + -- the standard library. + + -- We can make an object be initialised to its default values with the box + -- notation, "<>". "others" is used to indicate anything else that has not + -- been explicitly initialized. + Null_Entity : constant Entities := (others => <>); + + -- Object-orientation is accomplished via an extension of record syntax, + -- tagged records, see link above in first paragraph. + + -- We can rename objects (aliases) to make readability a bit better. + package IO renames Ada.Text_IO; +begin + -- We can output enumerations as names. + IO.Put_Line ("Blue_Hue = " & -- & is the string concatenation operator. + Blue'Image); -- ' accesses attributes on objects. + -- The Image attribute converts a value to a string. + -- Ada 2022 has extended Image to custom types too. + -- Access this with -gnat2022 compiler flag. + IO.Put_Line ("Yellow_Hue = " & + -- We can use the type's attribute. + Primaries'Image (Yellow_Hue)); + + -- We can define local variables within a declare block, this can be made + -- more readable by giving it a label. + Enum_IO : declare + package Hue_IO is new IO.Enumeration_IO (Hues); + + -- Using a package makes everything inside that package visible within + -- this block, it is good practice to only do this locally and not on + -- a whole package within the context clause. + use Hue_IO; + begin + -- We can print out the enumeration values too. + Put (Purple); -- Note we don't have to prefix the Put procedure with + -- Hue_IO. + IO.New_Line; -- We still need to prefix with IO here. + Put (Red_Hue); + IO.New_Line; + end Enum_IO; + + -- Loops have a consistent form. "<form> loop ... end loop". + -- Where "form" can be "while" or "for" or missing as below, if + -- you place the "loop ... end loop;" construct on their own lines, + -- you can comment out or experiment with different loop constructs more + -- easily. + declare + Counter : Positive := Positive'First; -- This is 1. + begin + -- We can label loops so we can exit from them more easily if we need to. + Infinite : + loop + IO.Put_Line ("[Infinite loop] Counter = " & Counter'Image); + + Counter := Counter + 1; + + -- This next line implements a repeat ... until or do ... while loop construct. + -- Comment it out for an infinite loop. + exit Infinite when Counter = 5; -- Equality tests use a single "=". + end loop Infinite; -- Useful when implementing state machines. + end; + + declare -- We don't have to have a label. + Counter : Positive := Positive'First; -- This is 1. + begin + while Counter < 10 + loop + IO.Put_Line ("Counter = " & Counter'Image); + + Counter := Counter + 1; -- There is no explicit inc/decrement. + + -- Ada 2022 introduced @ for LHS, so the above would be written as + -- Counter := @ + 1; -- Try it, -gnat2022. + end loop; + end; + + declare + package Hue_IO is new IO.Enumeration_IO (Hues); + + -- We can have multiple packages on one line, but I tend to use one + -- package per line for readability. + use IO, Hue_IO; + begin + Put ("Hues : "); -- Note, no prefix. + + -- Because we are using the 'Range attribute, the compiler knows it is + -- safe and can omit run-time checks here. + for Hue in Hues'Range + loop + Put (Hue); + + -- Types and objects know about their bounds, their First .. Last + -- values. These can be specified as range types. + if Hue /= Hues'Last then -- The /= means "not equal to" like the + -- maths symbol ≠. + Put (", "); + end if; + end loop; + + IO.New_Line; + end; + + -- All objects know their bounds, including strings. + declare + C : Character := Str (50); -- Warning caused and exception raised at + -- runtime. + -- The exception raised above can only be handled by an outer scope, + -- see wikibook link below. + begin + null; -- We will never get to this point because of the above. + end; +exception + when Constraint_Error => + IO.Put_Line ("Caught the exception"); +end LearnAdaInY; +``` + +Now, that's a lot of information for a basic intro to Ada, and I've only touched the surface, there's much more to look at in the references section below. I haven't even touched on dynamic memory allocation which includes [pools](https://ada-lang.io/docs/arm/AA-13/AA-13.11), this is because for the most part, Ada programs don't need it, you can do a lot without it. + +As I stated above, Ada barely looks like Pascal and if you look at the original [Green specification](https://apps.dtic.mil/sti/trecms/pdf/ADB950587.pdf) (Warning: Huge 4575 page scanned PDF - starting on page 460), it looks nothing like it at all (page 505 of that PDF). + +The above source code will compile, but also will give warnings showing the power of the strong static type system. + +## Download this source + +If you already have the GNAT toolchain installed, you can cut and paste the above into a new file, e.g. ```learn-ada-in-y.ada``` and then run the following: + +```bash +$ gnatchop learn-ada-in-y.ada # This breaks the program into its specification ".ads" and body ".adb". +$ gnatmake empty.adb # gnatmake takes care of compilation of all units and linking. +$ gnatmake hello.adb +$ gnatmake learnadainy.adb +``` + +Or, download [Alire](https://alire.ada.dev), copy it to somewhere in your PATH and then do the following: + +**N.B.** Alire will automatically install the toolchain for you if you don't have one installed and will ask you to select which you want to use. + +```bash +$ alr search learnadainy +$ alr get learnadainy +$ cd learnadainy +$ alr run empty +$ alr run hello +$ alr run learnadainy +``` + +## Further Reading + +* [Ada Programming Language](https://ada-lang.io) +* [Ada 2022 Reference Manual](https://ada-lang.io/docs/arm) +* [Ada Style Guide](https://ada-lang.io/docs/style-guide/Ada_Style_Guide) +* [Learn more Ada/Spark at AdaCore's site](https://learn.adacore.com) + +## References from the source above + +1. [wikibook](https://en.wikibooks.org/wiki/Ada_Programming/Exceptions#Exception_handlers) +2. [C](https://ada-lang.io/docs/arm/AA-B/AA-B.3) +3. [Fortran](https://ada-lang.io/docs/arm/AA-B/AA-B.5/) +4. [COBOL](https://ada-lang.io/docs/arm/AA-B/AA-B.4/) +5. [dynamic length strings](https://ada-lang.io/docs/arm/AA-A/AA-A.4#Subclause_A.4.5) + +### Multi-line comments + +Multi-line comments are not allowed as they are error prone. + +> Such comments would require a closing comment delimiter and this would again raise the dangers associated with the (unintentional) omission of the closing delimiter: entire sections of a program could be ignored by the compiler without the programmer realizing it +> +> [Ada 83 Rationale](http://archive.adaic.com/standards/83rat/html/ratl-02-01.html#2.1) + diff --git a/amd.html.markdown b/amd.html.markdown index d7fb41ba..fc8f20a4 100644 --- a/amd.html.markdown +++ b/amd.html.markdown @@ -1,212 +1,212 @@ ----
-category: tool
-tool: amd
-contributors:
- - ["Frederik Ring", "https://github.com/m90"]
-filename: learnamd.js
----
-
-## Getting Started with AMD
-
-The **Asynchronous Module Definition** API specifies a mechanism for defining
-JavaScript modules such that the module and its dependencies can be asynchronously
-loaded. This is particularly well suited for the browser environment where
-synchronous loading of modules incurs performance, usability, debugging, and
-cross-domain access problems.
-
-### Basic concept
-```javascript
-// The basic AMD API consists of nothing but two methods: `define` and `require`
-// and is all about module definition and consumption:
-// `define(id?, dependencies?, factory)` defines a module
-// `require(dependencies, callback)` imports a set of dependencies and
-// consumes them in the passed callback
-
-// Let's start by using define to define a new named module
-// that has no dependencies. We'll do so by passing a name
-// and a factory function to define:
-define('awesomeAMD', function(){
- var isAMDAwesome = function(){
- return true;
- };
- // The return value of a module's factory function is
- // what other modules or require calls will receive when
- // requiring our `awesomeAMD` module.
- // The exported value can be anything, (constructor) functions,
- // objects, primitives, even undefined (although that won't help too much).
- return isAMDAwesome;
-});
-
-// Now, let's define another module that depends upon our `awesomeAMD` module.
-// Notice that there's an additional argument defining our
-// module's dependencies now:
-define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
- // dependencies will be passed to the factory's arguments
- // in the order they are specified
- var tellEveryone = function(){
- if (awesomeAMD()){
- alert('This is sOoOo rad!');
- } else {
- alert('Pretty dull, isn\'t it?');
- }
- };
- return tellEveryone;
-});
-
-// As we do know how to use define now, let's use `require` to
-// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`.
-require(['loudmouth'], function(loudmouth){
- loudmouth();
-});
-
-// To make this tutorial run code, let's implement a very basic
-// (non-asynchronous) version of AMD right here on the spot:
-function define(name, deps, factory){
- // notice how modules without dependencies are handled
- define[name] = require(factory ? deps : [], factory || deps);
-}
-
-function require(deps, callback){
- var args = [];
- // first let's retrieve all the dependencies needed
- // by the require call
- for (var i = 0; i < deps.length; i++){
- args[i] = define[deps[i]];
- }
- // satisfy all the callback's dependencies
- return callback.apply(null, args);
-}
-// you can see this code in action here: http://jsfiddle.net/qap949pd/
-```
-
-### Real-world usage with require.js
-
-In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR:
-
-```javascript
-/* file: app/main.js */
-require(['modules/someClass'], function(SomeClass){
- // the callback is deferred until the dependency is loaded
- var thing = new SomeClass();
-});
-console.log('So here we are, waiting!'); // this will run first
-```
-
-By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`:
-
-* app/
- * main.js
- * modules/
- * someClass.js
- * someHelpers.js
- * ...
- * daos/
- * things.js
- * ...
-
-This means we can define `someClass` without specifying a module id:
-
-```javascript
-/* file: app/modules/someClass.js */
-define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
- // module definition, of course, will also happen asynchronously
- function SomeClass(){
- this.method = function(){/**/};
- // ...
- }
- return SomeClass;
-});
-```
-To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`:
-
-```javascript
-/* file: main.js */
-requirejs.config({
- baseUrl : 'app',
- paths : {
- // you can also load modules from other locations
- jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
- coolLibFromBower : '../bower_components/cool-lib/coollib'
- }
-});
-require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
- // a `main` file needs to call require at least once,
- // otherwise no code will ever run
- coolLib.doFancyStuffWith(helpers.transform($('#foo')));
-});
-```
-`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload:
-
-```html
-<!DOCTYPE html>
-<html>
-<head>
- <title>A hundred script tags? Never again!</title>
-</head>
-<body>
- <script src="require.js" data-main="app/main"></script>
-</body>
-</html>
-```
-
-### Optimizing a whole project using r.js
-
-Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load.
-
-`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption.
-
-Install it using `npm`:
-```shell
-$ npm install requirejs -g
-```
-
-Now you can feed it with a configuration file:
-```shell
-$ r.js -o app.build.js
-```
-
-For our above example the configuration might look like:
-```javascript
-/* file : app.build.js */
-({
- name : 'main', // name of the entry point
- out : 'main-built.js', // name of the file to write the output to
- baseUrl : 'app',
- paths : {
- // `empty:` tells r.js that this should still be loaded from the CDN, using
- // the location specified in `main.js`
- jquery : 'empty:',
- coolLibFromBower : '../bower_components/cool-lib/coollib'
- }
-})
-```
-
-To use the built file in production, simply swap `data-main`:
-```html
-<script src="require.js" data-main="app/main-built"></script>
-```
-
-An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo.
-
-### Topics not covered in this tutorial
-* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html)
-* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html)
-* [Advanced configuration](http://requirejs.org/docs/api.html#config)
-* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim)
-* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss)
-* [Using almond.js for builds](https://github.com/jrburke/almond)
-
-### Further reading:
-
-* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)
-* [Why AMD?](http://requirejs.org/docs/whyamd.html)
-* [Universal Module Definition](https://github.com/umdjs/umd)
-
-### Implementations:
-
-* [require.js](http://requirejs.org)
-* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
-* [cujo.js](http://cujojs.com/)
-* [curl.js](https://github.com/cujojs/curl)
-* [lsjs](https://github.com/zazl/lsjs)
-* [mmd](https://github.com/alexlawrence/mmd)
+--- +category: tool +tool: amd +contributors: + - ["Frederik Ring", "https://github.com/m90"] +filename: learnamd.js +--- + +## Getting Started with AMD + +The **Asynchronous Module Definition** API specifies a mechanism for defining +JavaScript modules such that the module and its dependencies can be asynchronously +loaded. This is particularly well suited for the browser environment where +synchronous loading of modules incurs performance, usability, debugging, and +cross-domain access problems. + +### Basic concept +```javascript +// The basic AMD API consists of nothing but two methods: `define` and `require` +// and is all about module definition and consumption: +// `define(id?, dependencies?, factory)` defines a module +// `require(dependencies, callback)` imports a set of dependencies and +// consumes them in the passed callback + +// Let's start by using define to define a new named module +// that has no dependencies. We'll do so by passing a name +// and a factory function to define: +define('awesomeAMD', function(){ + var isAMDAwesome = function(){ + return true; + }; + // The return value of a module's factory function is + // what other modules or require calls will receive when + // requiring our `awesomeAMD` module. + // The exported value can be anything, (constructor) functions, + // objects, primitives, even undefined (although that won't help too much). + return isAMDAwesome; +}); + +// Now, let's define another module that depends upon our `awesomeAMD` module. +// Notice that there's an additional argument defining our +// module's dependencies now: +define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ + // dependencies will be passed to the factory's arguments + // in the order they are specified + var tellEveryone = function(){ + if (awesomeAMD()){ + alert('This is sOoOo rad!'); + } else { + alert('Pretty dull, isn\'t it?'); + } + }; + return tellEveryone; +}); + +// As we do know how to use define now, let's use `require` to +// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`. +require(['loudmouth'], function(loudmouth){ + loudmouth(); +}); + +// To make this tutorial run code, let's implement a very basic +// (non-asynchronous) version of AMD right here on the spot: +function define(name, deps, factory){ + // notice how modules without dependencies are handled + define[name] = require(factory ? deps : [], factory || deps); +} + +function require(deps, callback){ + var args = []; + // first let's retrieve all the dependencies needed + // by the require call + for (var i = 0; i < deps.length; i++){ + args[i] = define[deps[i]]; + } + // satisfy all the callback's dependencies + return callback.apply(null, args); +} +// you can see this code in action here: http://jsfiddle.net/qap949pd/ +``` + +### Real-world usage with require.js + +In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR: + +```javascript +/* file: app/main.js */ +require(['modules/someClass'], function(SomeClass){ + // the callback is deferred until the dependency is loaded + var thing = new SomeClass(); +}); +console.log('So here we are, waiting!'); // this will run first +``` + +By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`: + +* app/ + * main.js + * modules/ + * someClass.js + * someHelpers.js + * ... + * daos/ + * things.js + * ... + +This means we can define `someClass` without specifying a module id: + +```javascript +/* file: app/modules/someClass.js */ +define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ + // module definition, of course, will also happen asynchronously + function SomeClass(){ + this.method = function(){/**/}; + // ... + } + return SomeClass; +}); +``` +To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`: + +```javascript +/* file: main.js */ +requirejs.config({ + baseUrl : 'app', + paths : { + // you can also load modules from other locations + jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}); +require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){ + // a `main` file needs to call require at least once, + // otherwise no code will ever run + coolLib.doFancyStuffWith(helpers.transform($('#foo'))); +}); +``` +`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload: + +```html +<!DOCTYPE html> +<html> +<head> + <title>A hundred script tags? Never again!</title> +</head> +<body> + <script src="require.js" data-main="app/main"></script> +</body> +</html> +``` + +### Optimizing a whole project using r.js + +Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load. + +`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption. + +Install it using `npm`: +```shell +$ npm install requirejs -g +``` + +Now you can feed it with a configuration file: +```shell +$ r.js -o app.build.js +``` + +For our above example the configuration might look like: +```javascript +/* file : app.build.js */ +({ + name : 'main', // name of the entry point + out : 'main-built.js', // name of the file to write the output to + baseUrl : 'app', + paths : { + // `empty:` tells r.js that this should still be loaded from the CDN, using + // the location specified in `main.js` + jquery : 'empty:', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}) +``` + +To use the built file in production, simply swap `data-main`: +```html +<script src="require.js" data-main="app/main-built"></script> +``` + +An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo. + +### Topics not covered in this tutorial +* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html) +* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html) +* [Advanced configuration](http://requirejs.org/docs/api.html#config) +* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim) +* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss) +* [Using almond.js for builds](https://github.com/jrburke/almond) + +### Further reading: + +* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD) +* [Why AMD?](http://requirejs.org/docs/whyamd.html) +* [Universal Module Definition](https://github.com/umdjs/umd) + +### Implementations: + +* [require.js](http://requirejs.org) +* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) +* [cujo.js](http://cujojs.com/) +* [curl.js](https://github.com/cujojs/curl) +* [lsjs](https://github.com/zazl/lsjs) +* [mmd](https://github.com/alexlawrence/mmd) diff --git a/ar-ar/sql-ar.html.markdown b/ar-ar/sql-ar.html.markdown new file mode 100644 index 00000000..dea20c1f --- /dev/null +++ b/ar-ar/sql-ar.html.markdown @@ -0,0 +1,135 @@ +--- +language: SQL +filename: learnsql-ar.sql +contributors: + - ["Bob DuCharme", "http://bobdc.com/"] +translators: + - ["Ahmed Omar Eissa", "https://twitter.com/AhmedOmarEissa"] +lang: ar-ar +--- +<div dir="rtl"> + +لغة الاستعلام الهيكلية +(SQL) +هي لغة قياسية +[ISO/IEC 9075](https://www.iso.org/standard/63555.html) +لإنشاء قواعد البيانات المخزنة في مجموعة من الجداول التعامل معها. عادةً ما تضيف التطبيقات +امتدادات خاصة بها إلى اللغة ؛ تعد +[مقارنة نسخ SQL المختلفة](http://troels.arvin.dk/db/rdbms/) +مرجعًا جيدًا لاختلافات النسخ. + +توفر النسخ عادةً موجه سطر أوامر +command line prompt +حيث يمكنك إدخال الأوامر المعروضة هنا بشكل تفاعلي، كما أنها توفر طريقة لتنفيذ سلسلة من هذه الأوامر المخزنة في ملف نصي. إظهار رسالة الانتهاء من العمل مع الموجه التفاعلي مثال جيد على امكانية اضافة أوامر غير قياسية، معظم النسخ تدعم أحد أوامر +QUIT , EXIT +.أو كليهما + +في الامثلة بالأسفل تعتمدالعديد من الأوامرأن قاعدة بيانات الموظفين +[MySQL employee sample database](https://dev.mysql.com/doc/employee/en/) +الموجودة على +[github](https://github.com/datacharmer/test_db) +قد تم تحميلها مسبقا. الملفات على +github +هي مجموعة من الاوامر تشبه الموجودة بالاسفل و تقوم الأوامر بإنشاء الجدوال وإدخال بيانات مجموعة من الموظفين المتخيلين في شركة. تعتمد الأوامر المستخدمة في هذا البرنامج على نسخة +SQL +التي تستخدمها، +</div> + + + + +```sql +-- تبدأ التعليقات بشرطتين. قم بإنهاء كل أمر بفاصلة منقوطة + +-- حساسة لحالة الاحرف SQL لا تعتبر +-- فقط ليسهل تمييزها عن أسماه الأعمدة والجداول وقواعد البيانات UPPER-CASE الاوامر الموجودة هنا تستخدم الحالة العليا للاحرف + +-- إنشاء ومسح قاعدة بيانات، أسماء قواعد البيانات والجداول حساسة لحالة الأحرف +CREATE DATABASE someDatabase; +DROP DATABASE someDatabase; + +-- عرض قواعد البيانات الموجودة +SHOW DATABASES; + +--استخدام قاعدة بيانات محددة +USE employees; + +-- في قاعدة البيانات المستخدمة departments ارجاع كل السطور والاعمدة في جدول +-- ستظهر النتائج على الشاشة بشكل تلقائي لتتصفحها. +SELECT * FROM departments; + +-- فقط dept_name و dept_no لكن سنسترجع عمودي departments استرجاع كل أسطر من جدول +-- لا مانع من تقسيم الاوامر بين السطور + +SELECT dept_no, + dept_name FROM departments; + +-- لكن هذه المرة سنسترجع ٥ أسطر فقط departments استرجاع كل الاعمدة من جدول +SELECT * FROM departments LIMIT 5; + +--en يحتوي علي dept_name في حالة أن عمود departments من جدول dept_name استرجاع عمود + +SELECT dept_name FROM departments WHERE dept_name LIKE '%en%'; + +-- S استرجاع كل أعمدة جدول الاقسام في حالة أن اسم القسم يبدأ بحرف +-- متبوعا بأربعة حروف + +SELECT * FROM departments WHERE dept_name LIKE 'S____'; + +-- استرجاع قيم العناوين من جدول العناوين بدون تكرار +SELECT DISTINCT title FROM titles; + +-- نفس المثال السابق مع ترتيب العناوين أبجديا +SELECT DISTINCT title FROM titles ORDER BY title; + +-- اظهار عدد السطور في جدول الأقسام +SELECT COUNT(*) FROM departments; + + +-- en اظهار عدد السطور في جدول الأقسام التي تحتوي في عمود اسم القسم علي +SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%'; + + +-- ربط المعلومات بين الجداول، جدول العناوين يظهر رقم كل موظف ومسماه الوظيفي +-- ومتي حصل على هذا المسمى وإلي متى ولكن بدلا من اظهار رقم الموظف سنستخدم هذا الرقم +-- للحصول على اسم الموظف الاول والأخير من جدول الموظفين مع إظهار ١٠ سطور فقط +SELECT employees.first_name, employees.last_name, + titles.title, titles.from_date, titles.to_date +FROM titles INNER JOIN employees ON + employees.emp_no = titles.emp_no LIMIT 10; + +-- إظهار كل الجدوال في كل قواعد البيانات +-- النسخ المختلفة تقدم اختصارات لمثل هذا الأمر لقاعدة البيانات المستخدمة + +SELECT * FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE='BASE TABLE'; + +-- يحتوى على عمودان في قاعدة البيانات المستخدمة tablename1 أنشاء جدول يسمى +-- يوجد العديد من الطرق لتعريف الاعمدة وأنواع البيانات في العمود +CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20)); + +-- هذا بافتراض ان الجدول يمكن اضافة الاسطر له .tablename1 اضافة سطر في جدول +INSERT INTO tablename1 VALUES('Richard','Mutt'); + +--John إلى fname سنغير قيمة عمود tablename1 في +-- Mutt هي lname في حالة أن قيمة العمود +UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; + + +-- 'M' تبدأ ب lname في حالة أن قيمة عمود tablename1 مسح السطور من جدول +DELETE FROM tablename1 WHERE lname like 'M%'; + +-- مع ترك الجدول فارغ tablename1 مسح جميع السطور من جدول +DELETE FROM tablename1; + +-- تماما tablename1 إزالة جدول +DROP TABLE tablename1; +``` +<div dir="rtl"> + +## اقرأ أكثر + +* [Codecademy - SQL](https://www.codecademy.com/learn/learn-sql)مقدمة جيدة للتعلم عن طريق التطبيق. +* [Database System Concepts](https://www.db-book.com) الفصل رقم ٣ من الكتاب مقدمة في (SQL) تحتوى علي شرح مفصل لمفاهيم (SQL) + +</div> diff --git a/arturo.html.markdown b/arturo.html.markdown new file mode 100644 index 00000000..c3c4dc43 --- /dev/null +++ b/arturo.html.markdown @@ -0,0 +1,432 @@ +--- +language: arturo +filename: learnarturo.art +contributors: + - ["Dr.Kameleon", "https://github.com/drkameleon"] +--- + +```red +; this is a comment +; this is another comment + +;--------------------------------- +; VARIABLES & VALUES +;--------------------------------- + +; numbers +a1: 2 +a2: 3.14 +a3: to :complex [1 2.0] ; 1.0+2.0i + +; strings +c1: "this is a string" +c2: { + this is a multiline string + that is indentation-agnostic +} +c3: {: + this is + a verbatim + multiline string + which will remain exactly + as the original +:} + +; characters +ch: `c` + +; blocks/arrays +d: [1 2 3] + +; dictionaries +e: #[ + name: "John" + surname: "Doe" + age: 34 + likes: [pizza spaghetti] +] + +; yes, functions are values too +f: function [x][ + 2 * x +] + +; dates +g: now ; 2021-05-03T17:10:48+02:00 + +; booleans +h1: true +h2: false + +;--------------------------------- +; BASIC OPERATORS +;--------------------------------- + +; simple arithmetic +1 + 1 ; => 2 +8 - 1 ; => 7 +4.2 - 1.1 ; => 3.1 +10 * 2 ; => 20 +35 / 4 ; => 8 +35 // 4 ; => 8.75 +2 ^ 5 ; => 32 +5 % 3 ; => 2 + +; bitwise operators +and 3 5 ; => 1 +or 3 5 ; => 7 +xor 3 5 ; => 6 + +; pre-defined constants +pi ; => 3.141592653589793 +epsilon ; => 2.718281828459045 +null ; => null +true ; => true +false ; => false + +;--------------------------------- +; COMPARISON OPERATORS +;--------------------------------- + +; equality +1 = 1 ; => true +2 = 1 ; => false + +; inequality +1 <> 1 ; => false +2 <> 1 ; => true + +; more comparisons +1 < 10 ; => true +1 =< 10 ; => true +10 =< 10 ; => true +1 > 10 ; => false +1 >= 10 ; => false +11 >= 10 ; => true + +;--------------------------------- +; CONDITIONALS +;--------------------------------- + +; logical operators +and? true true ; => true +and? true false ; => false +or? true false ; => true +or? false false ; => false + +and? [1=2][2<3] ; => false + ; (the second block will not be evaluated) + +; simple if statements +if 2 > 1 [ print "yes!"] ; yes! +if 3 <> 2 -> print "true!" ; true! + +; if/else statements +if? 2 > 3 -> print "2 is greater than 3" +else -> print "2 is not greater than 3" ; 2 is not greater than 3 + +; switch statements +switch 2 > 3 -> print "2 is greater than 3" + -> print "2 is not greater than 3" ; 2 is not greater than 3 + +a: (2 > 3)["yes"]["no"] ; a: "no" +a: (2 > 3)? -> "yes" -> "no" ; a: "no" (exactly the same as above) + +; case/when statements +case [1] + when? [>2] -> print "1 is greater than 2. what?!" + when? [<0] -> print "1 is less than 0. nope..." + else -> print "here we are!" ; here we are! + +;--------------------------------- +; LOOPS +;--------------------------------- + +; with `loop` +arr: [1 4 5 3] +loop arr 'x [ + print ["x =" x] +] +; x = 1 +; x = 4 +; x = 5 +; x = 3 + +; with loop and custom index +loop.with:'i arr 'x [ + print ["item at position" i "=>" x] +] +; item at position 0 => 1 +; item at position 1 => 4 +; item at position 2 => 5 +; item at position 3 => 3 + +; using ranges +loop 1..3 'x -> ; since it's a single statement + print x ; there's no need for [block] notation + ; we can wrap it up using the `->` syntactic sugar + +loop `a`..`c` 'ch -> + print ch +; a +; b +; c + +; picking multiple items +loop 1..10 [x y] -> + print ["x =" x ", y =" y] +; x = 1 , y = 2 +; x = 3 , y = 4 +; x = 5 , y = 6 +; x = 7 , y = 8 +; x = 9 , y = 10 + +; looping through a dictionary +dict: #[name: "John", surname: "Doe", age: 34] +loop dict [key value][ + print [key "->" value] +] +; name -> John +; surname -> Doe +; age -> 34 + +; while loops +i: new 0 +while [i<3][ + print ["i =" i] + inc 'i +] +; i = 0 +; i = 1 +; i = 2 + +;--------------------------------- +; STRINGS +;--------------------------------- + +; case +a: "tHis Is a stRinG" +print upper a ; THIS IS A STRING +print lower a ; this is a string +print capitalize a ; tHis Is a stRinG + +; concatenation +a: "Hello " ++ "World!" ; a: "Hello World!" + +; strings as an array +split "hello" ; => [h e l l o] +split.words "hello world" ; => [hello world] + +print first "hello" ; h +print last "hello" ; o + +; conversion +to :string 123 ; => "123" +to :integer "123" ; => 123 + +; joining strings together +join ["hello" "world"] ; => "helloworld" +join.with:"-" ["hello" "world"] ; => "hello-world" + +; string interpolation +x: 2 +print ~"x = |x|" ; x = 2 + +; interpolation with `print` +print ["x =" x] ; x = 2 + ; (`print` works by calculating the given block + ; and joining the different values as strings + ; with a single space between them) + +; templates +print render.template { + <||= switch x=2 [ ||> + Yes, x = 2 + <||][||> + No, x is not 2 + <||]||> +} ; Yes, x = 2 + +; matching +prefix? "hello" "he" ; => true +suffix? "hello" "he" ; => false + +contains? "hello" "ll" ; => true +contains? "hello" "he" ; => true +contains? "hello" "x" ; => false + +in? "ll" "hello" ; => true +in? "x" "hello" ; => false + +;--------------------------------- +; BLOCKS +;--------------------------------- + +; calculate a block +arr: [1 1+1 1+1+1] +@arr ; => [1 2 3] + +; execute a block +sth: [print "Hello world"] ; this is perfectly valid, + ; could contain *anything* + ; and will not be executed... + +do sth ; Hello world + ; (...until we tell it to) + +; array indexing +arr: ["zero" "one" "two" "three"] +print first arr ; zero +print arr\0 ; zero +print last arr ; three +print arr\3 ; three + +x: 2 +print get arr x ; two +print arr \ 2 ; two + ; (using the `\` infix alias for get - + ; notice space between the operands! + ; otherwise, it'll be parsed as a path) + +; setting an array element +arr\0: "nada" +set arr 2 "dos" +print arr ; nada one dos three + +; adding elements to an array +arr: new [] +'arr ++ "one" +'arr ++ "two" +print arr ; one two + +; remove elements from an array +arr: new ["one" "two" "three" "four"] +'arr -- "two" ; arr: ["one" "three" "four"] +remove 'arr .index 0 ; arr: ["three" "four"] + +; getting the size of an array +arr: ["one" 2 "three" 4] +print size arr ; 4 + +; getting a slice of an array +print slice ["one" "two" "three" "four"] 0 1 ; one two + +; check if array contains a specific element +print contains? arr "one" ; true +print contains? arr "five" ; false + +; sorting array +arr: [1 5 3 2 4] +sort arr ; => [1 2 3 4 5] +sort.descending arr ; => [5 4 3 2 1] + +; mapping values +map 1..10 [x][2*x] ; => [2 4 6 8 10 12 14 16 18 20] +map 1..10 'x -> 2*x ; same as above +map 1..10 => [2*&] ; same as above +map 1..10 => [2*] ; same as above + +; selecting/filtering array values +select 1..10 [x][odd? x] ; => [1 3 5 7 9] +select 1..10 => odd? ; same as above + +filter 1..10 => odd? ; => [2 4 6 8 10] + ; (now, we leave out all odd numbers - + ; while select keeps them) + +; misc operations +arr: ["one" 2 "three" 4] +reverse arr ; => [4 "three" 2 "one"] +shuffle arr ; => [2 4 "three" "one"] +unique [1 2 3 2 3 1] ; => [1 2 3] +permutate [1 2 3] ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]] +take 1..10 3 ; => [1 2 3] +repeat [1 2] 3 ; => [1 2 1 2 1 2] + +;--------------------------------- +; FUNCTIONS +;--------------------------------- + +; declaring a function +f: function [x][ 2*x ] +f: function [x]-> 2*x ; same as above +f: $[x]->2*x ; same as above (only using the `$` alias + ; for the `function`... function) + +; calling a function +f 10 ; => 20 + +; returning a value +g: function [x][ + if x < 2 -> return 0 + + res: 0 + loop 0..x 'z [ + res: res + z + ] + return res +] + +;--------------------------------- +; CUSTOM TYPES +;--------------------------------- + +; defining a custom type +define :person [ ; define a new custom type "Person" + name ; with fields: name, surname, age + surname + age +][ + ; with custom post-construction initializer + init: [ + this\name: capitalize this\name + ] + + ; custom print function + print: [ + render "NAME: |this\name|, SURNAME: |this\surname|, AGE: |this\age|" + ] + + ; custom comparison operator + compare: 'age +] + +; create a method for our custom type +sayHello: function [this][ + ensure -> is? :person this + + print ["Hello" this\name] +] + +; create new objects of our custom type +a: to :person ["John" "Doe" 34] ; let's create 2 "Person"s +b: to :person ["jane" "Doe" 33] ; and another one + +; call pseudo-inner method +sayHello a ; Hello John +sayHello b ; Hello Jane + +; access object fields +print ["The first person's name is:" a\name] ; The first person's name is: John +print ["The second person's name is:" b\name] ; The second person's name is: Jane + +; changing object fields +a\name: "Bob" +sayHello a ; Hello Bob + +; verifying object type +print type a ; :person +print is? :person a ; true + +; printing objects +print a ; NAME: John, SURNAME: Doe, AGE: 34 + +; sorting user objects (using custom comparator) +sort @[a b] ; Jane..., John... +sort.descending @[a b] ; John..., Jane... +``` + +## Additional resources + +- [Official documentation](https://arturo-lang.io/documentation/) - Arturo official documentation & reference. +- [Online playground](https://arturo-lang.io/playground/) - Online REPL for the Arturo programming language. diff --git a/asciidoc.html.markdown b/asciidoc.html.markdown index 51d0d7c9..557ed294 100644 --- a/asciidoc.html.markdown +++ b/asciidoc.html.markdown @@ -3,7 +3,7 @@ language: asciidoc contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] -filename: asciidoc.md +filename: asciidoc.adoc --- AsciiDoc is a markup language similar to Markdown and it can be used for anything from books to blogs. Created in 2002 by Stuart Rackham the language is simple but it allows for a great amount of customization. diff --git a/assemblyscript.html.markdown b/assemblyscript.html.markdown new file mode 100644 index 00000000..4433b41e --- /dev/null +++ b/assemblyscript.html.markdown @@ -0,0 +1,202 @@ +--- +language: Assemblyscript +contributors: + - ["Philippe Vlérick", "https://github.com/pvlerick"] + - ["Steve Huguenin-Elie", "https://github.com/StEvUgnIn"] + - ["Sebastian Speitel", "https://github.com/SebastianSpeitel"] + - ["Max Graey", "https://github.com/MaxGraey"] +filename: learnassemblyscript.ts +--- + +__AssemblyScript__ compiles a variant of __TypeScript__ (basically JavaScript with types) to __WebAssembly__ using __Binaryen__. It generates lean and mean WebAssembly modules while being just an `npm install` away. + +This article will focus only on AssemblyScript extra syntax, as opposed to [TypeScript](/docs/typescript) and [JavaScript](/docs/javascript). + +To test AssemblyScript's compiler, head to the +[Playground](https://bit.ly/asplayground) where you will be able +to type code, have auto completion and directly see the emitted WebAssembly. + +```ts +// There are many basic types in AssemblyScript, +let isDone: boolean = false; +let name: string = "Anders"; + +// but integer type come as signed (sized from 8 to 64 bits) +let lines8: i8 = 42; +let lines16: i16 = 42; +let lines32: i32 = 42; +let lines64: i64 = 42; + +// and unsigned (sized from 8 to 64 bits), +let ulines8: u8 = 42; +let ulines16: u16 = 42; +let ulines32: u32 = 42; +let ulines64: u64 = 42; + +// and float has two sizes possible (32/64). +let rate32: f32 = 1.0 +let rate64: f64 = 1.0 + +// But you can omit the type annotation if the variables are derived +// from explicit literals +let _isDone = false; +let _lines = 42; +let _name = "Anders"; + +// Use const keyword for constants +const numLivesForCat = 9; +numLivesForCat = 1; // Error + +// For collections, there are typed arrays and generic arrays +let list1: i8[] = [1, 2, 3]; +// Alternatively, using the generic array type +let list2: Array<i8> = [1, 2, 3]; + +// For enumerations: +enum Color { Red, Green, Blue }; +let c: Color = Color.Green; + +// Functions imported from JavaScript need to be declared as external +// @ts-ignore decorator +@external("alert") +declare function alert(message: string): void; + +// and you can also import JS functions in a namespace +declare namespace window { + // @ts-ignore decorator + @external("window", "alert") + function alert(message: string): void; +} + +// Lastly, "void" is used in the special case of a function returning nothing +export function bigHorribleAlert(): void { + alert("I'm a little annoying box!"); // calling JS function here +} + +// Functions are first class citizens, support the lambda "fat arrow" syntax + +// The following are equivalent, the compiler does not offer any type +// inference for functions yet, and same WebAssembly will be emitted. +export function f1 (i: i32): i32 { return i * i; } +// "Fat arrow" syntax +let f2 = (i: i32): i32 => { return i * i; } +// "Fat arrow" syntax, braceless means no return keyword needed +let f3 = (i: i32): i32 => i * i; + +// Classes - members are public by default +export class Point { + // Properties + x: f64; + + // Constructor - the public/private keywords in this context will generate + // the boiler plate code for the property and the initialization in the + // constructor. + // In this example, "y" will be defined just like "x" is, but with less code + // Default values are also supported + + constructor(x: f64, public y: f64 = 0) { + this.x = x; + } + + // Functions + dist(): f64 { return Math.sqrt(this.x * this.x + this.y * this.y); } + + // Static members + static origin: Point = new Point(0, 0); +} + +// Classes can be explicitly marked as extending a parent class. +// Any missing properties will then cause an error at compile-time. +export class PointPerson extends Point { + constructor(x: f64, y: f64, public name: string) { + super(x, y); + } + move(): void {} +} + +let p1 = new Point(10, 20); +let p2 = new Point(25); //y will be 0 + +// Inheritance +export class Point3D extends Point { + constructor(x: f64, y: f64, public z: f64 = 0) { + super(x, y); // Explicit call to the super class constructor is mandatory + } + + // Overwrite + dist(): f64 { + let d = super.dist(); + return Math.sqrt(d * d + this.z * this.z); + } +} + +// Namespaces, "." can be used as separator for sub namespaces +export namespace Geometry { + class Square { + constructor(public sideLength: f64 = 0) { + } + area(): f64 { + return Math.pow(this.sideLength, 2); + } + } +} + +let s1 = new Geometry.Square(5); + +// Generics +// AssemblyScript compiles generics to one concrete method or function per set +// of unique contextual type arguments, also known as [monomorphisation]. +// Implications are that a module only includes and exports concrete functions +// for sets of type arguments actually used and that concrete functions can be +// shortcutted with [static type checks] at compile time, which turned out to +// be quite useful. +// Classes +export class Tuple<T1, T2> { + constructor(public item1: T1, public item2: T2) { + } +} + +export class Pair<T> { + item1: T; + item2: T; +} + +// And functions +export function pairToTuple <T>(p: Pair<T>): Tuple<T, T> { + return new Tuple(p.item1, p.item2); +}; + +let tuple = pairToTuple<string>({ item1: "hello", item2: "world" }); + +// Including references to a TypeScript-only definition file: +/// <reference path="jquery.d.ts" /> + +// Template Strings (strings that use backticks) +// String Interpolation with Template Strings +let name = 'Tyrone'; +let greeting = `Hi ${name}, how are you?` +// Multiline Strings with Template Strings +let multiline = `This is an example +of a multiline string`; + +let numbers: Array<i8> = [0, 1, 2, 3, 4]; +let moreNumbers: Array<i8> = numbers; +moreNumbers[5] = 5; // Error, elements are read-only +moreNumbers.push(5); // Error, no push method (because it mutates array) +moreNumbers.length = 3; // Error, length is read-only +numbers = moreNumbers; // Error, mutating methods are missing + +// Type inference in Arrays +let ints = [0, 1, 2, 3, 4] // will infer as Array<i32> +let floats: f32[] = [0, 1, 2, 3, 4] // will infer as Array<f32> +let doubles = [0.0, 1.0, 2, 3, 4] // will infer as Array<f64> +let bytes1 = [0 as u8, 1, 2, 3, 4] // will infer as Array<u8> +let bytes2 = [0, 1, 2, 3, 4] as u8[] // will infer as Array<u8> +let bytes3: u8[] = [0, 1, 2, 3, 4] // will infer as Array<u8> + +``` + +## Further Reading + * [AssemblyScript Official website] (https://www.assemblyscript.org/) + * [AssemblyScript source documentation] https://github.com/AssemblyScript/website/tree/main/src) + * [Source Code on GitHub] (https://github.com/AssemblyScript/assemblyscript) diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown index a6acf54e..0739c02d 100644 --- a/asymptotic-notation.html.markdown +++ b/asymptotic-notation.html.markdown @@ -135,7 +135,7 @@ Let's look at the definition of Big-O. 3 * n^2 <= c * n ``` -Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>? +Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > n<sub>0</sub>? No, there isn't. `f(n)` is NOT O(g(n)). ### Big-Omega diff --git a/awk.html.markdown b/awk.html.markdown index dc22a2bd..e1d4a0a3 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -209,7 +209,7 @@ function string_functions( localvar, arr) { # Both return number of matches replaced localvar = "fooooobar"; sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar" - gsub("e", ".", localvar); # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar); # localvar => "M..t m. at th. bar" # Search for a string that matches a regular expression # index() does the same thing, but doesn't allow a regular expression diff --git a/ballerina.html.markdown b/ballerina.html.markdown new file mode 100644 index 00000000..7f055343 --- /dev/null +++ b/ballerina.html.markdown @@ -0,0 +1,432 @@ +--- +language: Ballerina +contributors: + - ["Anjana Fernando", "https://github.com/lafernando"] +filename: learn_ballerina.bal +--- + +[Ballerina](https://ballerina.io/) is a statically-typed programming language for making development for the cloud an enjoyable experience. + +```java +// Single-line comment + +// Import modules into the current source file +import ballerina/io; +import ballerina/time; +import ballerina/http; +import ballerinax/java.jdbc; +import ballerina/lang.'int as ints; +import ballerinax/awslambda; +// Module alias "af" used in code in place of the full module name +import ballerinax/azure.functions as af; + +http:Client clientEP = new ("https://freegeoip.app/"); +jdbc:Client accountsDB = new ({url: "jdbc:mysql://localhost:3306/AccountsDB", + username: "test", password: "test"}); + +// A service is a first-class concept in Ballerina, and is one of the +// entrypoints to a Ballerina program. +// The Ballerina platform also provides support for easy deployment to +// environments such as Kubernetes (https://ballerina.io/learn/deployment/kubernetes/). +service geoservice on new http:Listener(8080) { + + @http:ResourceConfig { + path: "/geoip/{ip}" + } + resource function geoip(http:Caller caller, http:Request request, + string ip) returns @tainted error? { + http:Response resp = check clientEP->get("/json/" + <@untainted>ip); + check caller->respond(<@untainted> check resp.getTextPayload()); + } + +} + +// Serverless Function-as-a-Service support with AWS Lambda. +// The Ballerina compiler automatically generates the final deployment +// artifact to be deployed. +@awslambda:Function +public function echo(awslambda:Context ctx, json input) returns json { + return input; +} + +@awslambda:Function +public function notifyS3(awslambda:Context ctx, + awslambda:S3Event event) returns json { + return event.Records[0].s3.'object.key; +} + +// Serverless Function-as-a-Service support with Azure Functions. +// Similar to AWS Lambda, the compiler generates the deployment artifacts. +@af:Function +public function fromQueueToQueue(af:Context ctx, + @af:QueueTrigger { queueName: "queue1" } string inMsg, + @af:QueueOutput { queueName: "queue2" } af:StringOutputBinding outMsg) { + outMsg.value = inMsg; +} + +// A custom record type +public type Person record { + string id; // required field + string name; + int age?; // optional field + string country = "N/A"; // default value +}; + +@af:Function +public function fromHttpTriggerCosmosDBInput( + @af:HTTPTrigger { route: "c1/{country}" } af:HTTPRequest httpReq, + @af:CosmosDBInput { connectionStringSetting: "CosmosDBConnection", + databaseName: "db1", collectionName: "c1", + sqlQuery: "select * from c1 where c1.country = {country}" } + Person[] dbReq) + returns @af:HTTPOutput string|error { + return dbReq.toString(); +} + +public function main() returns @tainted error? { + int a = 10; // 64-bit signed integer + float b = 1.56; // 64-bit IEEE 754-2008 binary floating point number + string c = "hello"; // a unicode string + boolean d = true; // true, false + decimal e = 15.335; // decimal floating point number + + var f = 20; // type inference with 'var' - 'f' is an int + + int[] intArray = [1, 2, 3, 4, 5, 6]; + int x = intArray.shift(); // similar to a dequeue operation + x = intArray.pop(); // removes the last element + intArray.push(10); // add to the end + + // Tuples - similar to a fixed length array with a distinct type for each slot + [string, int] p1 = ["Jack", 1990]; + [string, int] p2 = ["Tom", 1986]; + io:println("Name: ", p1[0], " Birth Year: ", p1[1]); + + string name1; + int birthYear1; + [name1, birthYear1] = p1; // tuple destructuring + + var [name2, birthYear2] = p2; // declare and assign values in the same statement + + // If statements + int ix = 10; + if ix < 10 { + io:println("value is less than 10"); + } else if ix == 10 { + io:println("value equals to 10"); + } else { + io:println("value is greater than 10"); + } + + // Loops + int count = 10; + int i = 0; + while i < 10 { + io:println(i); + } + // Loop from 0 to count (inclusive) + foreach var j in 0...count { + io:println(j); + } + // Loop from 0 to count (non-inclusive) + foreach var j in 0..<count { + io:println(j); + } + // Loop a list + foreach var j in intArray { + io:println(j); + } + + json j1 = { "name" : name1, "birthYear" : birthYear1, "zipcode" : 90210 }; + io:println(j1.name, " - ", j1.zipcode); + // New fields are added to a JSON value through "mergeJson" + var j2 = j1.mergeJson({ "id" : "90400593053"}); + + // XML namespace declaration + xmlns "http://example.com/ns1" as ns1; + xmlns "http://example.com/default"; + + // XML variable from a literal value + xml x1 = xml `<ns1:entry><name>{{name1}}</name><birthYear>{{birthYear1}}</birthYear></ns1:entry>`; + io:println(x1); + // Access specific elements in the XML value + io:println(x1/<name>); + // List all child items in the XML value + io:println(x1/*); + + // Function invocations + x = add(1, 2); + io:println(multiply(2, 4)); + // Invocation providing value for the defaultable parameter + io:println(multiply(3, 4, true)); + // Invocation with values to a rest parameter (multi-valued) + io:println(addAll(1, 2, 3)); + io:println(addAll(1, 2, 3, 4, 5)); + + // Function pointers + (function (int, int) returns int) op1 = getOperation("add"); + (function (int, int) returns int) op2 = getOperation("mod"); + io:println(op1(5, 10)); + io:println(op2(13, 10)); + + // Closures + (function (int x) returns int) add5 = getAdder(5); + (function (int x) returns int) add10 = getAdder(10); + io:println(add5(10)); + io:println(add10(10)); + + int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8]; + // Functional iteration + int[] evenNumbers = numbers.filter(function (int x) returns boolean { return x % 2 == 0; }); + + // Union types - "input" is of type either string or byte[] + string|byte[] uval = "XXX"; + + // A type test expression ("uval is string") can be used to check the + // runtime type of a variable. + if uval is string { + // In the current scope, "uval" is a string value + string data = "data:" + uval; + } else { + // Since the expression in the "if" statement ruled out that it's not a string, + // the only type left is "byte[]"; so in the current scope, "uval" will always + // be a "byte[]". + int inputLength = uval.length(); + } + + // Error handling + string input = io:readln("Enter number: "); + int|error result = ints:fromString(input); + if result is int { + io:println("Number: ", result); + } else { + io:println("Invalid number: ", input); + } + + // A check expression can be used to directly return the error from + // the current function if its subexpression evaluated to an error + // value in the runtime. + int number = check ints:fromString(input); + + // Concurrent execution using workers in a function + doWorkers(); + + // Asynchronous execution with futures + future<int> f10 = start fib(10); + var webresult = clientEP->get("/"); + int fresult = wait f10; + if webresult is http:Response { + io:println(webresult.getTextPayload()); + io:println(fresult); + } + + // Mapping types + map<int> ageMap = {}; + ageMap["Peter"] = 25; + ageMap["John"] = 30; + + int? agePeter = ageMap["Peter"]; // int? is the union type int|() - int or nill + if agePeter is int { + io:println("Peter's age is ", agePeter); + } else { + io:println("Peter's age is not found"); + } + + Person person1 = { id: "p1", name : "Anne", age: 28, country: "Sri Lanka" }; + Scores score1 = { physics : 80, mathematics: 95 }; + score1["chemistry"] = 75; + io:println(score1["chemistry"]); + + Student student1 = { id: "s1", name: "Jack", age: 25, country: "Japan" }; + student1.college = "Stanford"; + string? jacksCollege = student1?.college; // optional field access + if jacksCollege is string { + io:println("Jack's college is ", jacksCollege); + } + + // Due to the structural type system, "student1" can be assigned to "person2", + // since the student1's structure is compatible with person2's, + // where we can say, a "Student" is a "Person" as well. + Person person2 = student1; + + map<int> grades = {"Jack": 95, "Anne": 90, "John": 80, "Bill": 55}; + Person px1 = {id: "px1", name: "Jack", age: 30, country: "Canada"}; + Person px2 = {id: "px2", name: "John", age: 25}; + Person px3 = {id: "px3", name: "Anne", age: 17, country: "UK"}; + Person px4 = {id: "px4", name: "Bill", age: 15, country: "USA"}; + Person[] persons = []; + persons.push(px1); + persons.push(px2); + persons.push(px3); + persons.push(px4); + + // Query expressions used to execute complex queries for list data + Result[] results = from var person in persons + let int lgrade = (grades[person.name] ?: 0) + where lgrade > 75 + let string targetCollege = "Stanford" + select { + name: person.name, + college: targetCollege, + grade: lgrade + }; + + // Compile-time taint checking for handling untrusted data + string s1 = "abc"; + mySecureFunction(s1); + // Explicitely make "s2" a tainted value. External input to a Ballerina + // program such as command-line arguments and network input are by-default + // marked as tainted data. + string s2 = <@tainted> s1; + // "s2x" is now a tainted value, since its value is derived using a + // tainted value (s1). + string s2x = s2 + "abc"; + // The following line uncommented will result in a compilation error, + // since we are passing a tainted value (s2x) to a function which + // exepects an untainted value. + // mySecureFunction(s2x); + + // Instantiating objects + Employee emp1 = new("E0001", "Jack Smith", "Sales", 2009); + io:println("The company service duration of ", emp1.name, + " is ", emp1.serviceDuration()); + + // Supported operations can be executed in a transaction by enclosing the actions + // in a "transaction" block. + transaction { + // Executes the below database operations in a single local transactions + var r1 = accountsDB->update("UPDATE Employee SET balance = balance + ? WHERE id = ?", 5500.0, "ID001"); + var r2 = accountsDB->update("UPDATE Employee SET balance = balance + ? WHERE id = ?", 5500.0, "ID001"); + } +} + +// An object is a behavioural type, which encapsulates both data and functionality. +type Employee object { + + // Private fields are only visible within the object and its methods + private string empId; + // Public fields can be accessed by anyone + public string name; + public string department; + // The default qualifier is a "protected" field, + // which are accessible only within the module. + int yearJoined; + + // The object initialization function; automatically called when an object is instantiated. + public function __init(string empId, string name, string department, int yearJoined) { + self.empId = empId; + self.name = name; + self.department = department; + self.yearJoined = yearJoined; + } + + // An object method + public function serviceDuration() returns int { + time:Time ct = time:currentTime(); + return time:getYear(ct) - self.yearJoined; + } + +}; + +// Student is a subtype of Person +type Student record { + string id; + string name; + int age; + string college?; + string country; +}; + +type Scores record { + int physics; + int mathematics; +}; + +type Result record { + string name; + string college; + int grade; +}; + +public function getOperation(string op) returns (function (int, int) returns int) { + if op == "add" { + return add; + } else if op == "mod" { + return function (int a, int b) returns int { // anonymous function + return a % b; + }; + } else { + return (x, y) => 0; // single expression anonymous no-op function + } +} + +// Two required parameters +public function add(int a, int b) returns int { + return a + b; +} + +// 'log' is a defaultable parameter +public function multiply(int a, int b, boolean log = false) returns int { + if log { + io:println("Multiplying ", a, " with ", b); + } + return a * b; +} + +// 'numbers' is a rest parameter - it can have multiple values, +// similar to an array. +public function addAll(int... numbers) returns int { + int result = 0; + foreach int number in numbers { + result += number; + } + return result; +} + +public function getAdder(int n) returns (function (int x) returns int) { + return function (int x) returns int { // returns closure + return x + n; + }; +} + +function fib(int n) returns int { + if n <= 2 { + return 1; + } else { + return fib(n - 1) + fib(n - 2); + } +} + +// The code in worker blocks "w1" and "w2" are executed concurrency +// when this function is invoked. The "wait" expressions waits for +// the given workers to finish to retrieve their results. +public function doWorkers() { + worker w1 returns int { + int j = 10; + j -> w2; + int b; + b = <- w2; + return b * b; + } + worker w2 returns int { + int a; + a = <- w1; + a * 2 -> w1; + return a + 2; + } + record {int w1; int w2;} x = wait {w1, w2}; + io:println(x); +} + +// A function which takes in only an untainted string value. +public function mySecureFunction(@untainted string input) { + io:println(input); +} +``` + +### Further Reading + +* [Ballerina by Example](https://ballerina.io/learn/by-example/) +* [User Guide](https://ballerina.io/learn/installing-ballerina/) +* [API Documentation](https://ballerina.io/learn/api-docs/ballerina/) +* [Language Specification](https://ballerina.io/spec/) diff --git a/ca-es/asciidoc-ca.html.markdown b/ca-es/asciidoc-ca.html.markdown index a88aba52..6d387213 100644 --- a/ca-es/asciidoc-ca.html.markdown +++ b/ca-es/asciidoc-ca.html.markdown @@ -5,7 +5,7 @@ contributors: translators: - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] lang: ca-es -filename: asciidoc-ca.md +filename: asciidoc-ca.adoc --- AsciiDoc és un llenguatge de marques similar a Markdown i que pot ser usat per qualsevol ús, des de llibres fins a blogs. diff --git a/ca-es/go-ca.html.markdown b/ca-es/go-ca.html.markdown index 99f0d393..7bec4ba4 100644 --- a/ca-es/go-ca.html.markdown +++ b/ca-es/go-ca.html.markdown @@ -95,7 +95,7 @@ salts de línia.` // El mateix tipus // literals Non-ASCII literal. El tipus de Go és UTF-8. g := 'Σ' // El tipus rune, és un àlies de int32 conté un caràcter unicode. - f := 3.14195 // float64, un número de 64 bits amb coma flotant IEEE-754. + f := 3.14159 // float64, un número de 64 bits amb coma flotant IEEE-754. c := 3 + 4i // complex128, representat internament amb dos float64. // Sintaxi amb var i inicialitzadors. @@ -433,25 +433,25 @@ func requestServer() { ## Més informació L'arrel de tot en Go és la web oficial [official Go web site] -(http://golang.org/). Allà es pot seguir el tutorial, jugar interactivament +(https://go.dev/). Allà es pot seguir el tutorial, jugar interactivament i llegir molt més del que hem vist aquí.En el "tour", -[the docs](https://golang.org/doc/) conté informació sobre com escriure codi +[the docs](https://go.dev/doc/) conté informació sobre com escriure codi net i efectiu en Go, comandes per empaquetar i generar documentació, i història de les versions. És altament recomanable llegir La definició del llenguatge. És fàcil de llegir i sorprenentment curta (com la definició del llenguatge en aquests dies). -Es pot jugar amb codi a [Go playground](https://play.golang.org/p/tnWMjr16Mm). +Es pot jugar amb codi a [Go playground](https://go.dev/play/p/tnWMjr16Mm). Prova de fer canvis en el codi i executar-lo des del navegador! Es pot fer -servir [https://play.golang.org](https://play.golang.org) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi +servir [https://go.dev/play/](https://go.dev/play/) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi en el navegador sense haver d'instal·lar Go. En la llista de lectures pels estudiants de Go hi ha -[el codi font de la llibreria estàndard](http://golang.org/src/pkg/). +[el codi font de la llibreria estàndard](https://go.dev/src/). Ampliament comentada, que demostra el fàcil que és de llegir i entendre els programes en Go, l'estil de programació, i les formes de treballar-hi. O es -pot clicar en un nom de funció en [la documentació](http://golang.org/pkg/) +pot clicar en un nom de funció en [la documentació](https://go.dev/pkg/) i veure'n el codi! Un altre gran recurs per aprendre Go és diff --git a/cs-cz/css.html.markdown b/cs-cz/css.html.markdown index 54a0a08e..ed69c73a 100644 --- a/cs-cz/css.html.markdown +++ b/cs-cz/css.html.markdown @@ -220,9 +220,11 @@ p { vlastnost: hodnota !important; } ``` a tento element + ```xml <p style='/*F*/ vlastnost:hodnota;' trida='trida1 trida2' attr='hodnota' /> ``` + Priorita stylu je následující. Pamatujte, priorita pro každou **vlastnost**, ne pro celý blok. * `E` má nejvyšší prioritu kvůli slůvku `!important`. Je doporučováno se úplně vyhnout jeho použití. diff --git a/cs-cz/go.html.markdown b/cs-cz/go.html.markdown index cef8c5ab..18880a3b 100644 --- a/cs-cz/go.html.markdown +++ b/cs-cz/go.html.markdown @@ -90,7 +90,7 @@ může obsahovat nové řádky` // Opět typ řetězec. // Můžeme použít ne ASCII znaky, Go používá UTF-8. g := 'Σ' // type runa, což je alias na int32 a ukládá se do něj znak UTF-8 - f := 3.14195 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou. + f := 3.14159 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou. c := 3 + 4i // complex128, interně uložené jako dva float64. // takhle vypadá var s inicializací @@ -408,20 +408,20 @@ func requestServer() { ## Kam dále -Vše hlavní o Go se nachází na [oficiálních stránkách go](http://golang.org/). +Vše hlavní o Go se nachází na [oficiálních stránkách go](https://go.dev/). Tam najdete tutoriály, interaktivní konzolu a mnoho materiálu ke čtení. -Kromě úvodu, [dokumenty](https://golang.org/doc/) tam obsahují jak psát čistý kód v Go +Kromě úvodu, [dokumenty](https://go.dev/doc/) tam obsahují jak psát čistý kód v Go popis balíčků (package), dokumentaci příkazové řádky a historii releasů. Také doporučujeme přečíst si definici jazyka. Je čtivá a překvapivě krátká. Tedy alespoň proti jiným současným jazyků. -Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://play.golang.org/p/r46YvCu-XX). -Můžete tam spouštět programy s prohlížeče. Také můžete [https://play.golang.org](https://play.golang.org) použít jako +Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://go.dev/play/p/r46YvCu-XX). +Můžete tam spouštět programy s prohlížeče. Také můžete [https://go.dev/play/](https://go.dev/play/) použít jako [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop), kde si v rychlosti vyzkoušíte věci, bez instalace Go. -Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](http://golang.org/src/pkg/). -Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](http://golang.org/pkg/) +Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](https://go.dev/src/). +Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](https://go.dev/pkg/) tak se podíváte na dokumentaci. Dalším dobrým zdrojem informací je [Go v ukázkách](https://gobyexample.com/). diff --git a/cs-cz/markdown.html.markdown b/cs-cz/markdown.html.markdown index 50a69107..e1a96f32 100644 --- a/cs-cz/markdown.html.markdown +++ b/cs-cz/markdown.html.markdown @@ -215,7 +215,7 @@ Pro ještě hlubší odsazení můžete přidat další 4 mezery nebo další ta ```md moje_pole.each do |i| - puts i + puts i end ``` @@ -228,11 +228,13 @@ Honza neměl tušení, co dělá funkce `go_to()`! V Markdownu od GitHubu, můžete použít speciální syntaxi pro kód: -<pre><code class="highlight">```ruby +````md +```ruby def neco - puts "Ahoj světe!" + puts "Ahoj světe!" end -```</code></pre> +``` +```` Text výše nepotřebuje čtyřmezerové odsazení a parser navíc použije zvýraznění syntaxe pro zvolený jazyk. diff --git a/css.html.markdown b/css.html.markdown index b8adc886..948b70ac 100644 --- a/css.html.markdown +++ b/css.html.markdown @@ -102,19 +102,24 @@ div.some-parent.class-name { } /* There are some selectors called pseudo classes that can be used to select an element only when it is in a particular state */ -/* for example, when the cursor hovers over an element */ -selector:hover { } +/* for example, when a link hasn't been visited */ +selected:link { } /* or a link has been visited */ selector:visited { } -/* or hasn't been visited */ -selected:link { } - /* or an element is in focus */ selected:focus { } -/* any element that is the first child of its parent */ +/* or when the cursor hovers over an element */ +selector:hover { } + +/* or when a link is clicked on */ +selector:active { } + +/* These pseudo classes regarding links should always be written in the above order or the code might not work as expected */ + +/* Any element that is the first child of its parent */ selector:first-child {} /* any element that is the last child of its parent */ diff --git a/cue.html.markdown b/cue.html.markdown new file mode 100644 index 00000000..a1ff0822 --- /dev/null +++ b/cue.html.markdown @@ -0,0 +1,551 @@ +--- +name: CUE +category: language +language: CUE +filename: learncue.cue +contributors: + - ["Daniel Cox", "https://github.com/danielpcox"] + - ["Coleman McFarland", "https://github.com/dontlaugh"] +--- + +CUE is an expressive (but not Turing-complete) JSON superset, exportable to JSON or YAML. It supports optional types and many other conveniences for working with large configuration sets. The unification engine has roots in logic programming, and as such it provides a ready solution to modern configuration management problems. + +When CUE is exported to JSON, values from every processed file are unified into one giant object. Consider these two files: + +```yaml +//name.cue +name: "Daniel" +``` + +```yaml +//disposition.cue +disposition: "oblivious" +``` + +Now we can unify and export to JSON: +```bash +% cue export name.cue disposition.cue +{ + "name": "Daniel", + "disposition": "oblivious" +} +``` + +Or YAML: +```bash +% cue export --out yaml name.cue disposition.cue +name: Daniel +disposition: oblivious +``` + +Notice the C-style comments are not in the output. Also notice that the keys in CUE syntax did not require quotes. Some special characters do require quotes: + +```yaml +works_fine: true +"needs-quotes": true +``` + +Unification doesn't just unify across files, it is also a *global merge* of all types and values. The following fails, because the *types* are different. + +```yaml +//string_value.cue +foo: "baz" +``` + +```yaml +//integer_value.cue +foo: 100 +``` + +```bash +% cue export string_value.cue integer_value.cue +foo: conflicting values "baz" and 100 (mismatched types string and int): + integer_value.cue:1:6 + string_value.cue:1:6 +``` + +But even if we quote the integer, it still fails, because the *values* conflict and there is no way to unify everything into a top-level object. + +```yaml +//string_value.cue +foo: "baz" +``` + +```yaml +//integer_value.cue +foo: "100" // a string now +``` + +```bash +% cue export string_value.cue integer_value.cue +foo: conflicting values "100" and "baz": + integer_value.cue:1:6 + string_value.cue:1:6 +``` + +Types in CUE *are* values; special ones that the unification engine knows have certain behavior relative to other values. During unification it requires that values match the specified types, and when concrete values are required, you will get an error if there's only a type. So this is fine: + +```yaml +street: "1 Infinite Loop" +street: string +``` + +While `cue export` produces YAML or JSON, `cue eval` produces CUE. This is useful for converting YAML or JSON to CUE, or for inspecting the unified output in CUE itself. It's fine to be missing concrete values in CUE (though it prefers concrete values when emitting CUE when both are available and match), + +```yaml +//type-only.cue +amount: float +``` + +```bash +% cue eval type-only.cue +amount: float +``` + +but you *need* concrete values if you want to export (or if you tell `eval` to require them with `-c`): + +```bash +% cue export type-only.cue +amount: incomplete value float +``` + +Give it a value that unifies with the type, and all is well. + +```yaml +//concrete-value.cue +amount: 3.14 +``` + +```bash +% cue export type-only.cue concrete-value.cue +{ + "amount": 3.14 +} +``` + +The method of unifying concrete values with types that share a common syntax is very powerful, and much more compact than, e.g., JSON Schema. This way, schema, defaults, and data are all expressible in CUE. + +Default values may be supplied with a type using an asterisk: + +```yaml +// default-port.cue +port: int | *8080 +``` + +```bash +% cue eval default-port.cue +port: 8080 +``` + +Enum-style options ("disjunctions" in CUE) may be specified with an `|` separator: + +```yaml +//severity-enum.cue +severity: "high" | "medium" | "low" +severity: "unknown" +``` + +```bash +% cue eval severity-enum.cue +severity: 3 errors in empty disjunction: +severity: conflicting values "high" and "unknown": + ./severity-enum.cue:1:11 + ./severity-enum.cue:1:48 +severity: conflicting values "low" and "unknown": + ./severity-enum.cue:1:31 + ./severity-enum.cue:1:48 +severity: conflicting values "medium" and "unknown": + ./severity-enum.cue:1:20 + ./severity-enum.cue:1:48 +``` + +You can even have disjunctions of structs (not shown, but it works like you'd expect). + +CUE has "definitions", and you can use them like you would variable declarations in other languages. They are also for defining struct types. You can apply a struct of type definitions to some concrete value(s) with `&`. Also notice you can say "a list with type #Whatever" using `[...#Whatever]`. + +```yaml +// definitions.cue + +#DashboardPort: 1337 + +configs: { + host: "localhost" + port: #DashboardPort +} + +#Address: { + street: string + city: string + zip?: int // ? makes zip optional +} + +some_address: #Address & { + street: "1 Rocket Rd" + city: "Hawthorne" +} + +more_addresses: [...#Address] & [ + {street: "1600 Amphitheatre Parkway", city: "Mountain View", zip: "94043"}, + {street: "1 Hacker Way", city: "Menlo Park"} +] +``` + +```bash +% cue export --out yaml definitions.cue +configs: + host: localhost + port: 1337 +some_address: + street: 1 Rocket Rd + city: Hawthorne +more_addresses: + - street: 1600 Amphitheatre Parkway + city: Mountain View + zip: "94043" + - street: 1 Hacker Way + city: Menlo Park +``` + +CUE supports more complex values and validation: + +```yaml +#Country: { + name: =~"^\\p{Lu}" // Must start with an upper-case letter + pop: >800 & <9_000_000_000 // More than 800, fewer than 9 billion +} + +vatican_city: #Country & { + name: "Vatican City" + pop: 825 +} +``` + +CUE may save you quite a bit of time with all the sugar it provides on top of mere JSON. Here we're defining, "modifying", and validating a nested structure in three lines: (Notice the `[]` syntax used around `string` to signal to the engine that `string` is a constraint, not a string in this case.) + +```yaml +//paths.cue + +// path-value pairs +outer: middle1: inner: 3 +outer: middle2: inner: 7 + +// collection-constraint pair +outer: [string]: inner: int +``` + +```bash +% cue export paths.cue +{ + "outer": { + "middle1": { + "inner": 3 + }, + "middle2": { + "inner": 7 + } + } +} +``` + +In the same vein, CUE supports "templates", which are a bit like functions of a single argument. Here `Name` is bound to each string key immediately under `container` while the struct underneath *that* is evaluated. + +```yaml +//templates.cue + +container: [Name=_]: { + name: Name + replicas: uint | *1 + command: string +} + +container: sidecar: command: "envoy" + +container: service: { + command: "fibonacci" + replicas: 2 +} +``` + +```bash +% cue eval templates.cue +container: { + sidecar: { + name: "sidecar" + replicas: 1 + command: "envoy" + } + service: { + name: "service" + command: "fibonacci" + replicas: 2 + } +} +``` + +And while we're talking about references like that, CUE supports scoped references. + +```yaml +//scopes-and-references.cue +v: "top-level v" +b: v // a reference +a: { + b: v // matches the top-level v +} + +let V = v +a: { + v: "a's inner v" + c: v // matches the inner v + d: V // matches the top-level v now shadowed by a.v +} +av: a.v // matches a's v +``` + +```bash +% cue eval --out yaml scopes-and-references.cue +``` + +```yaml +v: top-level v +b: top-level v +a: + b: top-level v + v: a's inner v + c: a's inner v + d: top-level v +av: a's inner v +``` + +I changed the order of the keys in the output for clarity. Order doesn't actually matter, and notice that duplicate keys at a given level are *all* unified. + +You can hide fields be prefixing them with `_` (quote the field if you need a `_` prefix in an emitted field) + +```yaml +//hiddens.cue +"_foo": 2 +_foo: 3 +foo: 4 +_#foo: 5 +#foo : 6 +``` + +```bash +% cue eval hiddens.cue +"_foo": 2 +foo: 4 +#foo: 6 + +% cue export hiddens.cue +{ + "_foo": 2, + "foo": 4 +} +``` + +Notice the difference between `eval` and `export` with respect to definitions. If you want to hide a definition in CUE, you can prefix *that* with `_`. + +Interpolation of values and fields: + +```yaml +//interpolation.cue + +#expense: 90 +#revenue: 100 +message: "Your profit was $\( #revenue - #expense)" + +cat: { + type: "Cuddly" + "is\(type)": true +} +``` + +```bash +% cue export interpolation.cue +{ + "message": "Your profit was $10", + "cat": { + "type": "Cuddly", + "isCuddly": true + } +} +``` + +Operators, list comprehensions, conditionals, imports...: + +```yaml +//getting-out-of-hand-now.cue +import "strings" // we'll come back to this + +// operators are nice +g: 5 / 3 // CUE can do math +h: 3 * "blah" // and Python-like string repetition +i: 3 * [1, 2, 3] // with lists too +j: 8 < 10 // and supports boolean ops + +// conditionals are also nice +price: number +// Require a justification if price is too high +if price > 100 { + justification: string +} +price: 200 +justification: "impulse buy" + +// list comprehensions are powerful and compact +#items: [ 1, 2, 3, 4, 5, 6, 7, 8, 9] +comp: [ for x in #items if x rem 2 == 0 {x*x}] + +// and... well you can do this too +#a: [ "Apple", "Google", "SpaceX"] +for k, v in #a { + "\( strings.ToLower(v) )": { + pos: k + 1 + name: v + nameLen: len(v) + } +} +``` + +```bash +% cue export getting-out-of-hand-now.cue +``` + +```json +{ + "g": 1.66666666666666666666667, + "h": "blahblahblah", + "i": [1, 2, 3, 1, 2, 3, 1, 2, 3], + "j": true, + "apple": { + "pos": 1, + "name": "Apple", + "nameLen": 5 + }, + "google": { + "pos": 2, + "name": "Google", + "nameLen": 6 + }, + "price": 200, + "justification": "impulse buy", + "comp": [ + 4, + 16, + 36, + 64 + ], + "spacex": { + "pos": 3, + "name": "SpaceX", + "nameLen": 6 + } +} +``` + +At this point it's worth mentioning that CUE may not be Turing-complete, but it *is* powerful enough for you to shoot yourself in the foot, so do try to keep it clear. It's easy to go off the deep end and make your config *harder* to work with if you're not careful. Make use of those comments, at least, and/or... + +To that end, CUE supports packages and modules. CUE files are standalone by default, but if you put a package clause at the top, you're saying that file is unifiable with other files "in" the same package. + +```yaml +//a.cue +package config + +foo: 100 +bar: int +``` + +```yaml +//b.cue +package config + +bar: 200 +``` + +If you create these two files in a new directory and run `cue eval` (no arguments), it will unify them like you'd expect. It searches the current directory for .cue files, and if they all have the same package, they will be unified. + +Packages are more clear in the context of "modules". Modules are the *largest* unit of organization. Basically every time you have a project that spans multiple files, you should create a module and name it with something that looks like the domain and path of a URL, e.g., `example.com/something`. When you import anything from this module, even from *within* the module, you must do so using the fully-qualified module path which will be prefixed with this module name. + +You can create a new module like so: + +```bash +mkdir mymodule && cd mymodule +cue mod init example.com/mymodule +``` + +This creates a `cue.mod/` subdirectory within that `mymodule` directory, and `cue.mod/` contains the following file and subdirectories: + +- `module.cue` (which defines your module name, in this case with `module: "example.com/mymodule"`) +- pkg/ +- gen/ +- usr/ + +For a different perspective on this and details about what's in there, see https://cuelang.org/docs/concepts/packages/. For my purposes here, I'll say you don't need to think about the contents of this directory *at all*, except that your module name will be the prefix for all imports within your module. + +Where will your module file hierarchy go? All files and directories for your module are rooted in `mymodule/`, the directory that also contains `cue.mod/`. If you want to import a package, you'll prefix it with `example.com/mymodule`, followed by a relative path rooted in `mymodule/`. + +To make it concrete, consider the following: + +``` +mymodule +├── config +│ ├── a.cue +│ └── b.cue +├── cue.mod +│ ├── module.cue +│ ├── pkg +│ └── usr +└── main.cue +``` + +`cue.mod/` and the files underneath it were created by `cue mod init example.com/mymodule`. I then created the `config/` subdirectory with `a.cue` and `b.cue` inside. Then I created `main.cue` to act as my top-level file to rule them all. + +Running `eval` (no arguments) checks to see if there's only one package in all .cue files in the current directory, and if so, it unifies them and outputs the result. In this case, there's only main.cue with package `main` (nothing special about "main" there, it just seemed appropriate), so that's the one. + +```bash +% cue eval +configuredBar: 200 +``` + +The contents of `main.cue` is: + +```yaml +//main.cue + +package main +import "example.com/mymodule/config" + +configuredBar: config.bar +``` + +`config/a.cue` and `config/b.cue` are files from earlier, except now they've both got `package config` at the top: + +```yaml +//a.cue +package config + +foo: 100 +bar: int +``` + +```yaml +//b.cue +package config + +bar: 200 +``` + +So there you go. If you want to verify that it's actually unifying both files under `config/`, you can change `bar: int` to `bar: string` in `a.cue` and re-run `cue eval` to get a nice type error: + +``` +cue eval 2022-01-06 17:51:24 +configuredBar: conflicting values string and 200 (mismatched types string and int): + ./config/a.cue:4:6 + ./config/b.cue:3:6 + ./main.cue:5:16 +``` + +That's it for now. I understand there are more package management features coming in the future and the design decisions around `cue.mod` are looking ahead to that. + +Finally, CUE has built-in modules with powerful functionality. We saw one of these earlier, when we imported "strings" and used `strings.ToLower`. Imports without fully-qualified module names are assumed to be built-ins. The full list and documentation for each is here: https://pkg.go.dev/cuelang.org/go/pkg + +This has been a condensation of the official docs and tutorials, so go give the source material some love: https://cuelang.org/docs/tutorials/ diff --git a/dart.html.markdown b/dart.html.markdown index 69e1623d..ab3c07d2 100644 --- a/dart.html.markdown +++ b/dart.html.markdown @@ -45,7 +45,7 @@ const CONSTANT_VALUE = "I CANNOT CHANGE"; CONSTANT_VALUE = "DID I?"; //Error /// Final is another variable declaration that cannot be change once it has been instantiated. Commonly used in classes and functions /// `final` can be declared in pascalCase. -final finalValue = "value cannot be change once instantiated"; +final finalValue = "value cannot be changed once instantiated"; finalValue = "Seems not"; //Error /// `var` is another variable declaration that is mutable and can change its value. Dart will infer types and will not change its data type @@ -79,7 +79,8 @@ example1() { /// Anonymous functions don't include a name example2() { - nested1(fn) { + //// Explicit return type. + nested1(void Function() fn) { fn(); } nested1(() => print("Example2 nested 1")); diff --git a/de-de/asciidoc-de.html.markdown b/de-de/asciidoc-de.html.markdown index f7d36b41..d0a62c66 100644 --- a/de-de/asciidoc-de.html.markdown +++ b/de-de/asciidoc-de.html.markdown @@ -4,7 +4,7 @@ contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] translators: - ["Dennis Keller", "https://github.com/denniskeller"] -filename: asciidoc-de.md +filename: asciidoc-de.adoc lang: de-de --- diff --git a/de-de/crystal-de.html.markdown b/de-de/crystal-de.html.markdown new file mode 100644 index 00000000..535267ee --- /dev/null +++ b/de-de/crystal-de.html.markdown @@ -0,0 +1,561 @@ +--- +language: crystal +contributors: + - ["Vitalii Elenhaupt", "http://veelenga.com"] + - ["Arnaud Fernandés", "https://github.com/TechMagister/"] +translators: + - ["caminsha", "https://github.com/caminsha"] +filename: learncrystal-de.cr +lang: de-de +--- + +```crystal + +# Das ist ein Kommentar + +# Alles ist ein Objekt +nil.class # => Nil +100.class # => Int32 +true.class # => Bool + +# Falschwerte sind: nil, false und Nullpointer +!nil # => true : Bool +!false # => true : Bool +!0 # => false : Bool + +# Integer + +1.class # => Int32 + +# Fünf vorzeichenbehaftete Ganzzahlen +1_i8.class # => Int8 +1_i16.class # => Int16 +1_i32.class # => Int32 +1_i64.class # => Int64 +1_i128.class # => Int128 + +# Fünf vorzeichenlose Ganzzahlen +1_u8.class # => UInt8 +1_u16.class # => UInt16 +1_u32.class # => UInt32 +1_u64.class # => UInt64 +1_u128.class # => UInt128 + + +2147483648.class # => Int64 +9223372036854775808.class # => UInt64 + +# Binäre Zahlen +0b1101 # => 13 : Int32 + +# Oktalzahlen +0o123 # => 83 : Int32 + +# Hexadezimalzahlen +0xFE012D # => 16646445 : Int32 +0xfe012d # => 16646445 : Int32 + +# Gleitkommazahlen (floats) + +1.0.class # => Float64 + +# Es gibt zwei Typen von Gleitkommazahlen + +1.0_f32.class # => Float32 +1_f32.class # => Float32 + +1e10.class # => Float64 +1.5e10.class # => Float64 +1.5e-7.class # => Float64 + + +# Chars (einzelne Zeichen) + +'a'.class # => Char + +# Oktale Schreibweise +'\101' # => 'A' : Char + +# Unicode Schreibweise +'\u0041' # => 'A' : Char + +# Strings (Zeichenketten) +"s".class # => String + +# Strings sind unveränderlich +s = 'hello, " # => "hello, " : String +s.object_id # => 1234667712 : UInt64 +s += "Crystal" # => "hello, Crystal" : String +s.object_id # => 142528472 : UInt64 + +# Interpolation wird unterstützt +"sum = #{1 + 2}" # => "sum = 3" : String + +# Mehrzeilige Strings +" Dies ist ein + mehrzeiliger String." + +# String mit doppeltem Anführungszeichen +%(hello "world") # => "hello \"world\"" + +# Symbole +# Unveränderbare, wiederverwendbare Konstanten, welche intern als Int32 Integer +# Werte repräsentiert werden. +# Symbole werden oft anstelle von Strings verwendet, um bestimmte Werte zu bestimmen. + +:symbol.class # => Symbol + +sentence = :question? # :"question?" : Symbol + +sentence = :question? # => true : Bool +sentence = :exclamation! # => false : Bool +sentence = "question?" # => false : Bool + +# Arrays +[1, 2, 3].class # => Array(Int32) +[1, "hello", 'x'].class # => Array(Int32 | String | Char) + +# Leere Arrays sollten einen Typen definieren +[] # => Syntaxfehler: für leere Arrays, + # verwende `[] of ElementType` +[] of Int32 # => [] : Array(Int32) +Array(Int32).new # => [] : Array(Int32) + +# Arrays können indiziert werden +array = [1, 2, 3, 4, 5] # => [1, 2, 3, 4, 5] : Array(Int32) +array[0] # => 1 : Int32 +array[10] # führt zu einem IndexError +array[-6] # führt zu einem IndexError +array[10]? # => nil : (Int32 | Nil) +array[-6]? # => nil : (Int32 | Nil) + +# Starte am Ende des Arrays +array[-1] # => 5 + +# Mit einem Startindex und einer Länge +array[2, 4] # => [3, 4, 5] + +# oder mit einem Bereich +array[1..3] # => [2, 3, 4] + +# Füge etwas zu einem Array hinzu +array << 6 # => [1, 2, 3, 4, 5, 6] + +# Entferne Einträge am Ende des Arrays +array.pop # => 6 +array # => [1, 2, 3, 4, 5] + +# Entferne ersten Eintrag im Array +array.shift # => 1 +array # => [2, 3, 4, 5] + +# Überprüfe, ob ein Element in einem Array existiert +array.includes? 3 # => true + +# Spezielle Syntax für String-Arrays und Symbol-Arrays +%w(one two three) # => ["one", "two", "three"] : Array(String) +%i(one two three) # 0> [:one, :two, :three] : Array(Symbol) + +# Es gibt auch für andere Arrays eine spezielle Syntax, wenn die Methoden +# `.new` und `#<<` definiert werden. +set = Set{1, 2, 3} # => [1, 2, 3] +set.class # => Set(Int32) + +# Das obere ist äquivalent zu: +set = Set(typeof(1, 2, 3)).new +set << 1 +set << 2 +set << 3 + +# Hashes +{1 => 2, 3 => 4}.class # => Hash(Int32, Int32) +{1 => 2, 'a' => 3}.class # => Hash (Int32 | Char, Int32) + +# Leere Hashes sollten einen Typen spezifieren +{} # Syntaxfehler +{} of Int32 => Int32 # {} +Hash(Int32, Int32).new # {} + +# Hashes können schnell mit dem Key nachgeschaut werden +hash = {"color" => "green", "number" => 5} +hash["color"] # => "green" +hash["no_such_key"] # => Fehlender hash key: "no_such_key" (KeyError) +hash["no_such_key"]? # => nil + +# Überprüfe die Existenz eines Hashkeys +hash.has_key? "color" # => true + +# Spezielle Schreibweise für Symbol- und Stringkeys +{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'} +{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'} + +# Die spezielle Syntax für Hash-Literale gibt es auch für andere Typen, sofern +# diese die Methoden `.new` und `#[]=` Methoden definieren. +class MyType + def []=(key, value) + puts "do stuff" + end +end + +MyType{"foo" => "bar"} + +# Das obere ist äquivalent zu: +tmp = MyType.new +tmp["foo"] = "bar" +tmp + +# Ranges (Bereiche) +1..10 # => Range(Int32, Int32) +Range.new(1,10).class # => Range(Int32, Int32) + +# Ranges können inklusiv oder exklusiv sein. +(3..5).to_a # => [3, 4, 5] +(3...5).to_a # => [3, 4] + +# Überprüfe, ob ein Range einen Wert enthält oder nicht. +(1..8).includes? 2 # => true + +# Tupel sind unveränderliche, Stack-zugewiese Folgen von Werten mit fester +# Größe und möglicherweise unterschiedlichen Typen +{1, "hello", 'x'}.class # => Tuple(Int32, String, Char) + +# Erhalte den Wert eines Tupels über den Index +tuple = {:key1, :key2} +tuple[1] # => :key2 +tuple[2] # syntax error: Index out of bound + +# Können auf mehrere Variablen erweitert werden +a, b, c = {:a, 'b', "c"} +a # => :a +b # => 'b' +c # => "c" + +# Procs repräsentieren ein Funktionspointer mit einem optionalen Kontext. +# Normalerweise wird ein Proc mit einem proc-Literal erstellt. +proc = ->(x : Int32) { x.to_s } +proc.class # => Print(Int32, String) +# Außerdem kann man auch mit der Methode `new` ein Proc erstellen. +Proc(Int32, String).new { |x| x.to_s } + +# Rufe ein Proc auf mit der Methode `call` +proc.call 10 # => "10" + +# Kontrollstatements + +if true + "if statement" +elsif false + "else-f, optional" +else + "else, auch optional" +end + +puts "if as a suffix" if true # => if as a suffix + +# If als Ausdruck +a = if 2 > 1 + 3 + else + 4 + end + +a # => 3 + +# Bedingter ternärer Ausdruck +a = 1 > 2 ? 3 : 4 # => 4 + +# Case-Statement +cmd = "move" + +action = case cmd + when "create" + "Creating..." + when "copy" + "Copying..." + when "move" + "Moving..." + when "delete" + "Deleting..." +end + +action # => "Moving..." + +# Schleifen +index = 0 +while index <= 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +index = 0 +until index > 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +# Der bevorzugte Weg, ist `each` zu verwenden. +(1..3).each do |index| + puts "Index: #{index}" +end +# Index: 1 +# Index: 2 +# Index: 3 + +# Der Typ der Variablen hängt vom Typen innerhalb der Kontrollanweisung ab +if a < 3 + a = "hello" +else + a = true +end +typeof a # => (Bool | String) + +if a && b + # Hier wird garantiert, dass weder a noch b vom Typ Nil sind +end + +if a.is_a? String + a.class # => String +end + +# Funktionen +def double(x) + x * 2 +end + +# Funktionen geben implizit den Wert der letzten Anweisung zurück +# Dies ist auch bei anderen Blöcken der Fall. +double(2) # => 4 + +# Klammern müssen nicht gesetzt werden, wenn der Aufruf eindeutig ist +double 3 # => 6 +double double 3 # => 12 + +def sum(x, y) + x + y +end + +# Funktionsargumente werden mit einem Komma separiert. +sum 3, 4 # => 7 + +sum sum(3, 4), 5 # => 12 + +# yield +# Alle Methoden haben einen impliziten, optionalen Blockparameter. +# Dieser kann mit dem Schlüsselwort `yield` aufgerufen werden. + +def surround + puts '{' + yield + puts '}' +end + +surround { puts "Hallo Welt" } + +# { +# Hallo Welt +# } + +# Du kannst ein Block einer Funktion übergeben. +# "&" kennzeichnet eine Referenz zu einem übergebenen Block +def guests(&block) + block.call "some_argument" +end + +# Du kannst eine Liste von Argumenten mitgeben, welche zu einem Array +# umgewandelt werden. +# Hierfür ist der Splat-Operator ("*") +def guests(*array) + array.each { |guest| puts guest } +end + +# Wenn eine Methode ein Array zurückgibt, kann destrukturiende Zuordnung +# verwendet werden. +def foods + ["pancake", "sandwich", "quesadilla"] +end +breakfast, lunch, dinner = foods +breakfast # => "pancake" +dinner # => "quesadilla" + +# Gemäß der Konvention enden alle Methoden, welchen einen Boolean zurückgeben +# mit einem Fragezeichen. +5.even? # false +5.odd? # true + +# Und wenn eine Methode mit einem Ausrufezeichen endet, macht sie etwas +# destruktives. Zum Beispiel wird der Aufrufer verändert. Einige Methoden haben +# eine !-Version, um eine Änderung zu machen und eine Nicht-!-Version, welche +# lediglich eine neue veränderte Version zurückgibt. + +company_name = "Dunder Mifflin" +company_name.gsub "Dunder", "Donald" # => "Donald Mifflin" +company_name # => "Dunder Mifflin" +company_name.gsub! "Dunder", "Donald" +company_name # => "Donald Mifflin" + +# definiere eine Klasse mit dem Schlüsselwort `class`. +class Human + +# eine Klassenvariable. Diese wird mit allen Instanzen dieser Klasse geteilt. + @@species = "H. sapiens" + + # type of name is String + @name: String + + # Grundlegender Intialisierer + # Weise das Argument der Instanz-Variable "name" zu + # Wenn kein Alter angegeben wird, wird der Default (hier 0) genommen. + def initialize(@name, @age = 0) + end + + # Einfache Setter-Methode + def name=(name) + @name = name + end + + # einfache Getter-Methode + def name + @name + end + + # Die obere Funktionalität kann mit der property-Methode gekapselt werden: + property :name + + # Getter/Setter-Methoden können auch individuell erstellt werden: + getter :name + setter :name + + # eine Klassenmethode verwendet `self` um sich von Instanzmethoden zu + # unterscheiden. Diese kann lediglich von einer Klasse aufgerufen werden, + # nicht von einer Instanz. + def self.say(msg) + puts msg + end + + def species + @@species + end +end + + +# Eine Klasse instanzieren +jim = Human.new("Jim Halpert") + +dwight = Human.new("Dwight K. Schrute") + +# Lass uns ein paar Methoden aufrufen +jim.species # => "H. sapiens" +jim.name # => "Jim Halpert" +jim.name = "Jim Halpert II" # => "Jim Halpert II" +jim.name # => "Jim Halpert II" +dwight.species # => "H. sapiens" +dwight.name # => "Dwight K. Schrute" + +# Rufe die Klassenmethode auf +Human.say("Hi") # => gibt Hi aus und gibt `nil` zurück + +# Variablen, welche mit @ starten, sind im Scope der Instanz +class TestClass + @var = "Ich bin eine Instanzvariable" +end + +# Variablen, welche mit @@ starten, sind im Scope der Klasse +class TestClass + @@var = "Ich bin eine Klassenvariable" +end + +# Variablen, welche mit einem Großbuchstaben starten, sind Konstanten. +Var = "Ich bin eine Konstante" +Var = "Ich kann nicht aktualisiert werden." # Die Konstante Var wurde bereits + # initialisiert. + +# In Crystal ist Class auch ein Objekt. Dadurch können Klassen Instanzvariablen +# haben. Klassenvariablen werden mit der Klasse und allen Subklassen geteilt. + +# Basisklasse +class Human + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(value) + @@foo = value + end +end + +# abgeleitete Klasse +class Worker < Human +end + +Human.foo # => 0 +Worker.foo # => 0 + +Human.foo = 2 # => 2 +Worker.foo # => 0 + +Worker.foo = 3 # => 3 +Human.foo # => 2 +Worker.foo # => 3 + +module ModuleExample + def foo + "foo" + end +end + +# Wenn ein Modul mit include eingeschlossen wird, so werden die Methoden an die +# Instanzen gebunden. +# Wenn eine Klasse mit einem Modul erweitert wird, so werden die Methoden an die +# Klasse selbst gebunden. + +class Person + include ModuleExample +end + +class Book + extend ModuleExample +end + +Person.foo # => undefinierte Methode 'foo' für Person:Class +Person.new.foo # => 'foo' +Book.foo # => 'foo' +Book.new.foo # => undefinierte Methode für Book + +# Ausnahmebehandlung + +# Definiere eine neue Ausnahme +class MyException < Exception +end + +# Definiere eine weitere Ausnahme +class MyAnotherException < Exception; end + +ex = begin + raise MyException.new +rescue ex1 : IndexError + "ex1" +rescue ex2 : MyException | MyAnotherException + "ex2" +rescue ex3 : Exception + "ex3" +rescue ex4 # fange alle Ausnahmen ab + "ex4" +end + +ex # => "ex2" +``` + + +## Weitere Unterlagen + +- [offizielle Dokumentation, englisch](https://crystal-lang.org/) diff --git a/de-de/csharp-de.html.markdown b/de-de/csharp-de.html.markdown index 18a23017..662c2e76 100644 --- a/de-de/csharp-de.html.markdown +++ b/de-de/csharp-de.html.markdown @@ -1,890 +1,890 @@ ----
-language: C#
-contributors:
- - ["Irfan Charania", "https://github.com/irfancharania"]
- - ["Max Yankov", "https://github.com/golergka"]
- - ["Melvyn Laïly", "http://x2a.yt"]
- - ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
-translators:
- - ["Frederik Ring", "https://github.com/m90"]
-filename: LearnCSharp-de.cs
-lang: de-de
----
-C# ist eine elegante, typsichere und objektorientierte Sprache, mit der Entwickler eine Vielzahl sicherer und robuster Anwendungen erstellen können, die im .NET Framework ausgeführt werden.
-
-[Mehr über C# erfährst du hier.](http://msdn.microsoft.com/de-de/library/vstudio/z1zx9t92.aspx)
-
-```c#
-// Einzeilige Kommentare starten mit zwei Schrägstrichen: //
-/*
-Mehrzeile Kommentare wie in C Schrägstrich / Stern
-*/
-/// <summary>
-/// XML-Kommentare können zur automatisierten Dokumentation verwendet werden
-/// </summary>
-
-// Zu Beginn werden die in der Datei verwendeten Namespaces aufgeführt
-using System;
-using System.Collections.Generic;
-using System.Data.Entity;
-using System.Dynamic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Net;
-using System.Threading.Tasks;
-using System.IO;
-
-// definiert einen Namespace um Code in "packages" zu organisieren
-namespace Learning
-{
- // Jede .cs-Datei sollte zumindest eine Klasse mit dem Namen der Datei
- // enthalten. Das ist zwar nicht zwingend erforderlich, es anders zu
- // handhaben führt aber unweigerlich ins Chaos (wirklich)!
- public class LearnCSharp
- {
- // Zuerst erklärt dieses Tutorial die Syntax-Grundlagen,
- // wenn du bereits Java oder C++ programmieren kannst:
- // lies bei "Interessante Features" weiter!
- public static void Syntax()
- {
- // Mit Console.WriteLine kannst du einfachen Text ausgeben:
- Console.WriteLine("Hallo Welt");
- Console.WriteLine(
- "Integer: " + 10 +
- " Double: " + 3.14 +
- " Boolean: " + true);
-
- // Console.Write erzeugt keinen Zeilenumbruch
- Console.Write("Hallo ");
- Console.Write("Welt");
-
- ///////////////////////////////////////////////////
- // Typen & Variablen
- ///////////////////////////////////////////////////
-
- // Deklariere eine Variable mit <Typ> <Name>
-
- // Sbyte - Vorzeichenbehaftete 8-Bit Ganzzahl
- // (-128 <= sbyte <= 127)
- sbyte fooSbyte = 100;
-
- // Byte - Vorzeichenlose 8-Bit Ganzzahl
- // (0 <= byte <= 255)
- byte fooByte = 100;
-
- // Short - 16-Bit Ganzzahl
- // Vorzeichenbehaftet - (-32,768 <= short <= 32,767)
- // Vorzeichenlos - (0 <= ushort <= 65,535)
- short fooShort = 10000;
- ushort fooUshort = 10000;
-
- // Integer - 32-bit Ganzzahl
- int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
- uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
-
- // Long - 64-bit Ganzzahl
- long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
- ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
- // Ganze Zahlen werden standardmäßig - je nach Größe - als int oder
- // uint behandelt. Ein nachgestelltes L markiert den Wert als long
- // oder ulong.
-
- // Double - Double-precision 64-bit IEEE 754 Fließkommazahl
- double fooDouble = 123.4; // Genauigkeit: 15-16 Stellen
-
- // Float - Single-precision 32-bit IEEE 754 Fließkommazahl
- float fooFloat = 234.5f; // Genauigkeit: 7 Stellen
- // Das nachgestellte f zeigt an dass es sich um einen Wert vom Typ
- // float handelt
-
- // Decimal - ein 128-Bit-Datentyp mit größerer Genauigkeit als
- // andere Fließkommatypen, und somit bestens geeignet für
- // die Berechnung von Geld- und Finanzwerten
- decimal fooDecimal = 150.3m;
-
- // Boolean - true & false
- bool fooBoolean = true; // oder false
-
- // Char - Ein einzelnes 16-Bit Unicode Zeichen
- char fooChar = 'A';
-
- // Strings - im Gegensatz zu allen vorhergehenden Basistypen, die
- // alle Werttypen sind, ist String ein Referenztyp. Strings sind
- // somit nullable, Werttypen sind dies nicht.
- string fooString = "\"maskiere\" Anführungszeichen, und füge \n (Umbrüche) und \t (Tabs) hinzu";
- Console.WriteLine(fooString);
-
- // Jeder Buchstabe eines Strings kann über seinen Index
- // referenziert werden:
- char charFromString = fooString[1]; // => 'e'
- // Strings sind unveränderlich:
- // `fooString[1] = 'X';` funktioniert nicht
-
- // Ein Vergleich zweier Strings, unter Berücksichtigung der
- // aktuellen, sprachspezifischen Gegebenheiten (also z.B. a,ä,b,c
- // in deutschsprachigen Umgebungen), und ohne Beachtung von
- // Groß- und Kleinschreibung:
- string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
-
- // Formatierung, genau wie "sprintf"
- string fooFs = string.Format("Mikrofon Check, {0} {1}, {0} {1:0.0}", 1, 2);
-
- // Datumsangaben und Formatierung
- DateTime fooDate = DateTime.Now;
- Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
-
- // Durch ein vorangestelltes @ lässt sich ein mehrzeiliger String
- // schreiben. Um " zu maskieren benutzt man ""
- string bazString = @"Hier geht es
-zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen";
-
- // Die Keywords const oder readonly kennzeichnen eine
- // unveränderliche Variable/Konstante. Die Werte von Konstanten
- // werden übrigens bereits zur Compile-Zeit berechnet.
- const int HOURS_I_WORK_PER_WEEK = 9001;
-
- ///////////////////////////////////////////////////
- // Datenstrukturen
- ///////////////////////////////////////////////////
-
- // Arrays - Index beginnt bei Null
- // Die Größe des Arrays wird bei der Deklaration festgelegt.
- // Die syntaktische Struktur um ein neues Array zu erzeugen sieht
- // folgendermaßen aus:
- // <datatype>[] <varname> = new <datatype>[<array size>];
- int[] intArray = new int[10];
-
- // Arrays können auch über ein Array-Literal deklariert werden:
- int[] y = { 9000, 1000, 1337 };
-
- // Indizierung eines Arrays - Zugriff auf ein bestimmtes Element
- Console.WriteLine("intArray @ 0: " + intArray[0]);
- // Arrays sind veränderbar
- intArray[1] = 1;
-
- // Listen
- // Durch ihre größere Flexibilität kommen Listen in C# weit
- // häufiger zum Einsatz als Arrays. Eine Liste wird so deklariert:
- // List<datatype> <varname> = new List<datatype>();
- List<int> intList = new List<int>();
- List<string> stringList = new List<string>();
- List<int> z = new List<int> { 9000, 1000, 1337 };
- // Die <> kennzeichnen "Generics", mehr dazu unter "Coole Sachen"
-
- // Listen haben keinen Default-Wert.
- // Bevor auf einen Index zugegriffen werden kann, muss dieser
- // auch gesetzt worden sein:
- intList.Add(1);
- Console.WriteLine("intList @ 0: " + intList[0]);
-
- // Andere interessante Datenstrukturen sind:
- // Stack/Queue
- // Dictionary (entspricht einer Hash Map)
- // HashSet
- // Read-only Collections
- // Tuple (.Net 4+)
-
- ///////////////////////////////////////
- // Operatoren
- ///////////////////////////////////////
- Console.WriteLine("\n->Operatoren");
-
- // kurze Schreibweise um mehrere Deklarationen zusammenzufassen:
- // (Benutzung vom C# Styleguide aber ausdrücklich abgeraten!)
- int i1 = 1, i2 = 2;
-
- // Arithmetik funktioniert wie erwartet:
- Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
-
- // Modulo
- Console.WriteLine("11%3 = " + (11 % 3)); // => 2
-
- // Vergleiche
- Console.WriteLine("3 == 2? " + (3 == 2)); // => false
- Console.WriteLine("3 != 2? " + (3 != 2)); // => true
- Console.WriteLine("3 > 2? " + (3 > 2)); // => true
- Console.WriteLine("3 < 2? " + (3 < 2)); // => false
- Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
- Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
-
- // Bitweise Operatoren
- /*
- ~ Unäres bitweises NICHT
- << Verschieben nach links
- >> Verschieben nach rechts
- & Bitweises UND
- ^ Bitweises exklusives ODER
- | Bitweises inklusives ODER
- */
-
- // Inkremente
- int i = 0;
- Console.WriteLine("\n->Inkrement / Dekrement");
- Console.WriteLine(i++); //i = 1. Post-Inkrement
- Console.WriteLine(++i); //i = 2. Pre-Inkrement
- Console.WriteLine(i--); //i = 1. Post-Dekrement
- Console.WriteLine(--i); //i = 0. Pre-Dekrement
-
- ///////////////////////////////////////
- // Kontrollstrukturen
- ///////////////////////////////////////
- Console.WriteLine("\n->Kontrollstrukturen");
-
- // If-Statements funktionieren wie in C
- int j = 10;
- if (j == 10)
- {
- Console.WriteLine("Ich werde ausgegeben");
- }
- else if (j > 10)
- {
- Console.WriteLine("Ich nicht");
- }
- else
- {
- Console.WriteLine("Ich leider auch nicht");
- }
-
- // Ternärer Operator
- // Anstatt eines einfachen if/else lässt sich auch folgendes schreiben:
- // <condition> ? <true> : <false>
- int zumVergleich = 17;
- string isTrue = zumVergleich == 17 ? "Ja" : "Nein";
-
- // while-Schleife
- int fooWhile = 0;
- while (fooWhile < 100)
- {
- // Wird 100mal wiederholt, fooWhile 0->99
- fooWhile++;
- }
-
- // do-while-Schleife
- int fooDoWhile = 0;
- do
- {
- // Wird 100mal wiederholt, fooDoWhile 0->99
- fooDoWhile++;
- } while (fooDoWhile < 100);
-
- //for-Schleifen => for(<start_statement>; <conditional>; <step>)
- for (int fooFor = 0; fooFor < 10; fooFor++)
- {
- // Wird 10mal wiederholt, fooFor 0->9
- }
-
- // foreach-Schleife
- // Die normale Syntax für eine foreach-Schleife lautet:
- // foreach(<iteratorType> <iteratorName> in <enumerable>)
- // foreach kann mit jedem Objekt verwendet werden das IEnumerable
- // oder IEnumerable<T> implementiert. Alle Auflistungs-Typen
- // (Array, List, Dictionary...) im .NET Framework implementieren
- // eines dieser beiden Interfaces.
-
- foreach (char character in "Hallo Welt".ToCharArray())
- {
- // Ein Durchgang für jedes Zeichen im String
- }
- // (ToCharArray() könnte man hier übrigens auch weglassen,
- // da String IEnumerable bereits implementiert)
-
- // Switch Struktur
- // Ein Switch funktioniert mit byte, short, char und int Datentypen.
- // Auch Aufzählungstypen können verwendet werden, genau wie
- // die Klasse String, und ein paar Sonderklassen, die Wrapper für
- // Primitives sind: Character, Byte, Short und Integer
- int month = 3;
- string monthString;
- switch (month)
- {
- case 1:
- monthString = "Januar";
- break;
- case 2:
- monthString = "Februar";
- break;
- case 3:
- monthString = "März";
- break;
- // Man kann für mehrere Fälle auch das selbe Verhalten
- // definieren. Jeder Block muss aber mit einem break-Statement
- // abgeschlossen werden. Einzelne Fälle können über
- // `goto case x` erreicht werden
- case 6:
- case 7:
- case 8:
- monthString = "Sommer!!";
- break;
- default:
- monthString = "Irgendein anderer Monat";
- break;
- }
-
- ///////////////////////////////////////
- // Umwandlung von Datentypen und Typecasting
- ///////////////////////////////////////
-
- // Umwandlung
-
- // von String nach Integer
- // bei einem Fehler wirft diese Code eine Exception
- int.Parse("123"); //gibt die Ganzzahl 123 zurück
-
- // TryParse gibt bei einem Fehler den Default-Wert zurück
- // (im Fall von int: 0)
- int tryInt;
- if (int.TryParse("123", out tryInt)) // gibt true oder false zurück
- {
- Console.WriteLine(tryInt); // 123
- }
-
- // von Integer nach String
- // Die Klasse Convert stellt Methoden zur Konvertierung von
- // unterschiedlichsten Daten zur Verfügung:
- Convert.ToString(123); // "123"
- // oder
- tryInt.ToString(); // "123"
- }
-
- ///////////////////////////////////////
- // Klassen
- ///////////////////////////////////////
- public static void Classes()
- {
-
- // Benutze das new-Keyword um eine Instanz einer Klasse zu erzeugen
- Bicycle trek = new Bicycle();
-
- // So werden Methoden der Instanz aufgerufen
- trek.SpeedUp(3); // Es empfiehlt sich immer Getter und Setter zu benutzen
- trek.Cadence = 100;
-
- // ToString ist eine Konvention über die man üblicherweiser
- // Informationen über eine Instanz erhält
- Console.WriteLine("Infos zu trek: " + trek.ToString());
-
- // Wir instantiieren ein neues Hochrad
- PennyFarthing funbike = new PennyFarthing(1, 10);
- Console.WriteLine("Infos zu funbike: " + funbike.ToString());
-
- Console.Read();
- } // Ende der Methode main
-
- // Main als Konsolenstartpunkt
- // Eine Konsolenanwendung muss eine Methode Main als Startpunkt besitzen
- public static void Main(string[] args)
- {
- OtherInterestingFeatures();
- }
-
- ///////////////////////////////////////
- // Interessante Features
- ///////////////////////////////////////
-
- // Methodensignaturen
-
- public // Sichtbarkeit
- static // Erlaubt einen Zugriff auf der Klasse (nicht auf einer Instanz)
- int // Typ des Rückgabewerts,
- MethodSignatures(
- // Erstes Argument, erwartet int
- int maxCount,
- // setzt sich selbst auf 0 wenn kein anderer Wert übergeben wird
- int count = 0,
- int another = 3,
- // enthält alle weiteren der Methode übergebenen Parameter (quasi Splats)
- params string[] otherParams
- )
- {
- return -1;
- }
-
- // Methoden können überladen werden, solange sie eindeutige
- // Signaturen haben
- public static void MethodSignatures(string maxCount)
- {
- }
-
- // Generische Typen
- // Die Typen für TKey und TValue werden erst beim Aufruf der Methode
- // festgelegt. Diese Methode emuliert z.B. SetDefault aus Python:
- public static TValue SetDefault<TKey, TValue>(
- IDictionary<TKey, TValue> dictionary,
- TKey key,
- TValue defaultItem)
- {
- TValue result;
- if (!dictionary.TryGetValue(key, out result))
- {
- return dictionary[key] = defaultItem;
- }
- return result;
- }
-
- // Möglichen Typen lassen sich auch über ihr Interface beschränken:
- public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
- {
- // Da T ein IEnumerable ist können wir foreach benutzen
- foreach (var item in toPrint)
- {
- // Item ist ein int
- Console.WriteLine(item.ToString());
- }
- }
-
- public static void OtherInterestingFeatures()
- {
- // Optionale Parameter
- MethodSignatures(3, 1, 3, "Ein paar", "extra", "Strings");
- // setzt explizit einen bestimmten Parameter, andere werden übersprungen
- MethodSignatures(3, another: 3);
-
- // Erweiterungsmethoden
- int i = 3;
- i.Print(); // Weiter unten definiert
-
- // Nullables - perfekt für die Interaktion mit
- // Datenbanken / Rückgabewerten
- // Jeder Wert (d.h. keine Klassen) kann durch das Nachstellen eines ?
- // nullable gemacht werden: <type>? <varname> = <value>
- int? nullable = null; // Die explizite Langform wäre Nullable<int>
- Console.WriteLine("Mein Nullable: " + nullable);
- bool hasValue = nullable.HasValue; // true wenn nicht null
-
- // ?? ist "syntaktischer Zucker" um einen Defaultwert für den Fall
- // dass die Variable null ist festzulegen.
- int notNullable = nullable ?? 0; // 0
-
- // Implizit typisierte Variablen
- // Man kann auch den Typ einer Variable auch vom Compiler
- // bestimmen lassen:
- var magic = "magic ist zur Compile-Zeit ein String, folglich geht keine Typsicherheit verloren";
- magic = 9; // funktioniert nicht da magic vom Typ String ist
-
- // Generics
- var phonebook = new Dictionary<string, string>() {
- {"Resi", "08822 / 43 67"} // Fügt einen Eintrag zum Telefonbuch hinzu
- };
-
- // Hier könnte man auch unser generisches SetDefault von
- // weiter oben benutzen:
- Console.WriteLine(SetDefault<string,string>(phonebook, "Xaver", "kein Telefon")); // kein Telefon
- // TKey und TValue müssen nicht zwingend angegeben werden, da sie
- // auch implizit vom Compiler ermittelt werden können
- Console.WriteLine(SetDefault(phonebook, "Resi", "kein Telefon")); // 08822 / 43 67
-
- // Lambdas - konzise Syntax für Inline-Funktionen
- Func<int, int> square = (x) => x * x; // Das letzte Element vom Typ T ist der Rückgabewert
- Console.WriteLine(square(3)); // 9
-
- // Disposables - einfaches Management von nicht verwalteten Ressourcen
- // So gut wie alle Objekte die auf nicht verwaltete Ressourcen
- // (Dateien, Geräte, ...) zugreifen, implementieren das Interface
- // IDisposable. Das using Statement stellt sicher dass die vom
- // IDisposable benutzten Ressourcen nach der Benutzung wieder
- // freigegeben werden:
- using (StreamWriter writer = new StreamWriter("log.txt"))
- {
- writer.WriteLine("Alles bestens!");
- // Am Ende des Codeblocks werden die Ressourcen wieder
- // freigegeben - auch im Falle einer Exception
- }
-
- // Parallel Klasse
- // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
- var websites = new string[] {
- "http://www.google.com", "http://www.reddit.com",
- "http://www.shaunmccarthy.com"
- };
- var responses = new Dictionary<string, string>();
-
- // Für jeden Request wird ein neuer Thread erzeugt, der nächste
- // Schritt wird erst nach Beendigung aller Tasks ausgeführt
- Parallel.ForEach(websites,
- // maximal 3 Threads gleichzeitig
- new ParallelOptions() {MaxDegreeOfParallelism = 3},
- website =>
- {
- // Hier folgt eine langwierige, asynchrone Operation
- using (var r = WebRequest.Create(new Uri(website)).GetResponse())
- {
- responses[website] = r.ContentType;
- }
- });
-
- // Dieser Code wird erst nach Beendigung aller Requests ausgeführt
- foreach (var key in responses.Keys)
- {
- Console.WriteLine("{0}:{1}", key, responses[key]);
- }
-
- // Dynamische Objekte (gut um mit anderen Sprachen zu arbeiten)
- dynamic student = new ExpandoObject();
- // hier muss keine Typ angegeben werden
- student.FirstName = "Christian";
-
- // Einem solchen Objekt kann man sogar Methoden zuordnen.
- // Das Beispiel gibt einen String zurück und erwartet einen String
- student.Introduce = new Func<string, string>(
- (introduceTo) => string.Format("Hallo {0}, das ist {1}", student.FirstName, introduceTo));
- Console.WriteLine(student.Introduce("Bettina"));
-
- // IQueryable<T> - So gut wie alle Aufzählungstypen implementieren
- // dieses Interface, welches eine Vielzahl von funktionalen Methoden
- // wie Map / Filter / Reduce zur Verfügung stellt:
- var bikes = new List<Bicycle>();
- // sortiert die Liste
- bikes.Sort();
- // sortiert nach Anzahl Räder
- bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels));
- var result = bikes
- // diese Filter können auch aneinandergehängt werden
- .Where(b => b.Wheels > 3) // (gibt ein IQueryable des vorherigen Typs zurück)
- .Where(b => b.IsBroken && b.HasTassles)
- // diese Zuordnung gibt ein IQueryable<String> zurück
- .Select(b => b.ToString());
-
- // "Reduce" - addiert alle Räder der Aufzählung zu einem Wert
- var sum = bikes.Sum(b => b.Wheels);
-
- // So erzeugt man ein implizit typisiertes Objekt, basierend auf
- // den Parametern der Elemente:
- var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
- // Auch wenn wir es hier nicht demonstrieren können:
- // In einer IDE wie VisualStudio kriegen wir hier sogar TypeAhead,
- // da der Compiler in der Lage ist, die passenden Typen zu erkennen.
- foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
- {
- Console.WriteLine(bikeSummary.Name);
- }
-
- // AsParallel-Methode
- // Jetzt kommen die Schmankerl! Die AsParallel-Methode kombiniert
- // LINQ und parallele Operationen:
- var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
- // Diese Berechnung passiert parallel! Benötigte Threads werden
- // automatisch erzeugt, und die Rechenlast unter ihnen aufgeteilt.
- // Ein Traum für die Verarbeitung von großen Datenmengen
- // auf mehreren Cores!
-
- // LINQ - bildet einen Datenspeicher auf IQueryable<T> Objekte ab
- // LinqToSql beispielsweise speichert und liest aus einer
- // SQL-Datenbank, LinqToXml aus einem XML-Dokument.
- // LINQ-Operationen werden "lazy" ausgeführt.
- var db = new BikeRepository();
-
- // Die verzögerte Ausführung ist optimal für Datenbankabfragen
- var filter = db.Bikes.Where(b => b.HasTassles); // noch keine Abfrage
- // Es können noch mehr Filter hinzugefügt werden (auch mit
- // Bedingungen) - ideal für z.B. "erweiterte Suchen"
- if (42 > 6)
- {
- filter = filter.Where(b => b.IsBroken); // immer noch keine Abfrage
- }
-
- var query = filter
- .OrderBy(b => b.Wheels)
- .ThenBy(b => b.Name)
- .Select(b => b.Name); // auch hier: immer noch keine Abfrage
-
- // Erst hier wird die Datenbankabfrage wirklich ausgeführt,
- // limitiert auf die Elemente die der foreach-Loop verwendet
- foreach (string bike in query)
- {
- Console.WriteLine(result);
- }
-
- }
-
- } // Ende der Klasse LearnCSharp
-
- // Eine .cs-Datei kann auch mehrere Klassen enthalten
-
- public static class Extensions
- {
- // Erweiterungsmethoden
- public static void Print(this object obj)
- {
- Console.WriteLine(obj.ToString());
- }
- }
-
- // Syntax zur Deklaration einer Klasse:
- // <public/private/protected/internal> class <class name>{
- // // Datenfelder, Konstruktoren und Methoden leben alle
- // // innerhalb dieser Deklaration
- // }
-
- public class Bicycle
- {
- // Felder/Variablen der Klasse "Bicycle"
- // Das Keyword public macht das Member von überall zugänglich
- public int Cadence
- {
- get // get definiert eine Methode um die Eigenschaft abzurufen
- {
- return _cadence;
- }
- set // set definiert eine Methode um die Eigenschaft zu setzen
- {
- _cadence = value; // value ist der dem Setter übergebene Wert
- }
- }
- private int _cadence;
-
- // Das Keyword protected macht das Member nur für die Klasse selbst
- // und ihre Subklassen zugänglich
- protected virtual int Gear
- {
- get; // erzeugt eine Eigenschaft für die kein "Zwischenwert" benötigt wird
- set;
- }
-
- // Das Keyword internal macht das Member innerhalb der Assembly zugänglich
- internal int Wheels
- {
- get;
- private set; // get/set kann auch über Keywords modifiziert werden
- }
-
- int _speed; // Member ohne vorangestellte Keywords sind standardmäßig
- // private, sie sind nur innerhalb der Klasse zugänglich.
- // Man kann aber natürlich auch das Keyword private benutzen.
- private string Name { get; set; }
-
- // Ein Enum ist ein klar definierter Satz an benannten Konstanten.
- // Eigentlich ordnet es diese Konstanten nur bestimmten Werten zu
- // (einer int-Zahl, solange nicht anders angegeben). Mögliche Typen für
- // die Werte eines Enums sind byte, sbyte, short, ushort, int, uint,
- // long, oder ulong. Alle Werte in einem Enum sind eindeutig.
- public enum BikeBrand
- {
- Colnago,
- EddyMerckx,
- Bianchi = 42, // so kann man den Wert explizit setzen
- Kynast // 43
- }
- // Nachdem dieser Typ in der Klasse "Bicycle" definiert ist,
- // sollte Code ausserhalb der Klasse den Typen als Bicycle.Brand referenzieren
-
- // Nachdem das Enum deklariert ist, können wir den Typen verwenden:
- public BikeBrand Brand;
-
- // Als static gekennzeichnete Member gehören dem Typ selbst,
- // nicht seinen Instanzen. Man kann sie also ohne Referenz zu einem
- // Objekt benutzen
- // Console.WriteLine("Schon " + Bicycle.BicyclesCreated + " Fahrräder, nur für dieses Tutorial!");
- static public int BicyclesCreated = 0;
-
- // readonly-Werte werden zur Laufzeit gesetzt
- // Ihr Wert kann nur bei ihrer Deklaration, oder in einem Konstruktor
- // festgelegt werden
- readonly bool _hasCardsInSpokes = false; // readonly und private
-
- // Konstruktoren bestimmen was bei einer Instantiierung passiert.
- // Das ist ein Default-Konstruktor:
- public Bicycle()
- {
- // Member der Klasse können über das Keyword this erreicht werden
- this.Gear = 1;
- // oft ist das aber gar nicht nötig
- Cadence = 50;
- _speed = 5;
- Name = "Bonanzarad";
- Brand = BikeBrand.Kynast;
- BicyclesCreated++;
- }
-
- // Das ist ein spezifischer Konstruktor (d.h. er erwartet Argumente):
- public Bicycle(int startCadence, int startSpeed, int startGear,
- string name, bool hasCardsInSpokes, BikeBrand brand)
- : base() // ruft zuerst den "base"-Konstruktor auf
- {
- Gear = startGear;
- Cadence = startCadence;
- _speed = startSpeed;
- Name = name;
- _hasCardsInSpokes = hasCardsInSpokes;
- Brand = brand;
- }
-
- // Konstruktoren können aneinandergehängt werden:
- public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
- this(startCadence, startSpeed, 0, "richtig große Räder", true, brand)
- {
- }
-
- // Syntax für Methoden:
- // <public/private/protected> <return type> <function name>(<args>)
-
- // Klassen können Getter und Setter für Werte definieren,
- // oder diese Werte direkt als Eigenschaft implementieren
- // (in C# der bevorzugte Weg)
-
- // Parameter von Methoden können Default-Werte haben.
- // "SpeedUp" kann man also auch ohne Parameter aufrufen:
- public void SpeedUp(int increment = 1)
- {
- _speed += increment;
- }
-
- public void SlowDown(int decrement = 1)
- {
- _speed -= decrement;
- }
-
- // Eigenschaften mit get/set
- // wenn es nur um den Zugriff auf Daten geht, ist eine Eigenschaft zu
- // empfehlen. Diese können Getter und Setter haben, oder auch nur
- // einen Getter bzw. einen Setter
- private bool _hasTassles; // private Variable
- public bool HasTassles // öffentliches Interface
- {
- get { return _hasTassles; }
- set { _hasTassles = value; }
- }
-
- // Das kann man auch kürzer schreiben:
- // Dieser Syntax erzeugt automatisch einen hinterlegten Wert,
- // (entsprechend `private bool _isBroken`) der gesetzt
- // bzw. zurückgegeben wird:
- public bool IsBroken { get; private set; }
- public int FrameSize
- {
- get;
- // für Getter und Setter kann der Zugriff auch einzeln
- // beschränkt werden, FrameSize kann also nur von innerhalb
- // der Klasse "Bicycle" gesetzt werden
- private set;
- }
-
- // Diese Methode gibt eine Reihe an Informationen über das Objekt aus:
- public virtual string ToString()
- {
- return "Gang: " + Gear +
- " Kadenz: " + Cadence +
- " Geschwindigkeit: " + _speed +
- " Name: " + Name +
- " Hipster-Karten zwischen den Speichen: " + (_hasCardsInSpokes ? "Na klar!" : "Bloß nicht!") +
- "\n------------------------------\n"
- ;
- }
-
- // Auch Methoden können als static gekennzeichnet werden, nützlich
- // beispielsweise für Helper-Methoden
- public static bool DidWeCreateEnoughBicyclesYet()
- {
- // In einer statischen Methode können wir natürlich auch nur
- // statische Member der Klasse referenzieren
- return BicyclesCreated > 9000;
- }
- // Wenn eine Klasse nur statische Member enthält, kann es eine gute Idee
- // sein die Klasse selbst als static zu kennzeichnen
-
- } // Ende der Klasse "Bicycle"
-
- // "PennyFarthing" ist eine Unterklasse von "Bicycle"
- class PennyFarthing : Bicycle
- {
- // (Hochräder - englisch Penny Farthing - sind diese antiken Fahrräder
- // mit riesigem Vorderrad. Sie haben keine Gangschaltung.)
-
- // hier wird einfach der Elternkonstruktor aufgerufen
- public PennyFarthing(int startCadence, int startSpeed) :
- base(startCadence, startSpeed, 0, "Hochrad", true, BikeBrand.EddyMerckx)
- {
- }
-
- protected override int Gear
- {
- get
- {
- return 0;
- }
- set
- {
- throw new ArgumentException("Ein Hochrad hat keine Gangschaltung, doh!");
- }
- }
-
- public override string ToString()
- {
- string result = "Hochrad ";
- result += base.ToString(); // ruft die "base"-Version der Methode auf
- return result;
- }
- }
-
- // Interfaces (auch Schnittstellen genant) definieren nur die Signaturen
- // ihrer Member, enthalten aber auf keinen Fall ihre Implementierung:
- interface IJumpable
- {
- // Alle Member eines Interfaces sind implizit public
- void Jump(int meters);
- }
-
- interface IBreakable
- {
- // Interfaces können Eigenschaften, Methoden und Events definieren
- bool Broken { get; }
- }
-
- // Eine Klasse kann nur von einer Klasse erben, kann aber eine beliebige
- // Anzahl von Interfaces implementieren
- class MountainBike : Bicycle, IJumpable, IBreakable
- {
- int damage = 0;
-
- public void Jump(int meters)
- {
- damage += meters;
- }
-
- public bool Broken
- {
- get
- {
- return damage > 100;
- }
- }
- }
-
- // Das hier stellt eine Datenbankverbindung für das LinqToSql-Beispiel her.
- // EntityFramework Code First ist großartig
- // (ähnlich zu Ruby's ActiveRecord, aber bidirektional)
- // http://msdn.microsoft.com/de-de/data/jj193542.aspx
- public class BikeRepository : DbSet
- {
- public BikeRepository()
- : base()
- {
- }
-
- public DbSet<Bicycle> Bikes { get; set; }
- }
-} // Ende des Namespaces
-```
-
-## In dieser Übersicht nicht enthalten sind die Themen:
-
- * Flags
- * Attributes
- * Statische Eigenschaften
- * Exceptions, Abstraction
- * ASP.NET (Web Forms/MVC/WebMatrix)
- * Winforms
- * Windows Presentation Foundation (WPF)
-
-## Zum Weiterlesen gibt es viele gute Anlaufpunkte:
-
- * [DotNetPerls](http://www.dotnetperls.com)
- * [C# in Depth](http://manning.com/skeet2)
- * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
- * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
- * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
- * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
- * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/overview/exploring-webmatrix)
- * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
- * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
-
-[C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx)
+--- +language: C# +contributors: + - ["Irfan Charania", "https://github.com/irfancharania"] + - ["Max Yankov", "https://github.com/golergka"] + - ["Melvyn Laïly", "http://x2a.yt"] + - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] +translators: + - ["Frederik Ring", "https://github.com/m90"] +filename: LearnCSharp-de.cs +lang: de-de +--- +C# ist eine elegante, typsichere und objektorientierte Sprache, mit der Entwickler eine Vielzahl sicherer und robuster Anwendungen erstellen können, die im .NET Framework ausgeführt werden. + +[Mehr über C# erfährst du hier.](http://msdn.microsoft.com/de-de/library/vstudio/z1zx9t92.aspx) + +```c# +// Einzeilige Kommentare starten mit zwei Schrägstrichen: // +/* +Mehrzeile Kommentare wie in C Schrägstrich / Stern +*/ +/// <summary> +/// XML-Kommentare können zur automatisierten Dokumentation verwendet werden +/// </summary> + +// Zu Beginn werden die in der Datei verwendeten Namespaces aufgeführt +using System; +using System.Collections.Generic; +using System.Data.Entity; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Threading.Tasks; +using System.IO; + +// definiert einen Namespace um Code in "packages" zu organisieren +namespace Learning +{ + // Jede .cs-Datei sollte zumindest eine Klasse mit dem Namen der Datei + // enthalten. Das ist zwar nicht zwingend erforderlich, es anders zu + // handhaben führt aber unweigerlich ins Chaos (wirklich)! + public class LearnCSharp + { + // Zuerst erklärt dieses Tutorial die Syntax-Grundlagen, + // wenn du bereits Java oder C++ programmieren kannst: + // lies bei "Interessante Features" weiter! + public static void Syntax() + { + // Mit Console.WriteLine kannst du einfachen Text ausgeben: + Console.WriteLine("Hallo Welt"); + Console.WriteLine( + "Integer: " + 10 + + " Double: " + 3.14 + + " Boolean: " + true); + + // Console.Write erzeugt keinen Zeilenumbruch + Console.Write("Hallo "); + Console.Write("Welt"); + + /////////////////////////////////////////////////// + // Typen & Variablen + /////////////////////////////////////////////////// + + // Deklariere eine Variable mit <Typ> <Name> + + // Sbyte - Vorzeichenbehaftete 8-Bit Ganzzahl + // (-128 <= sbyte <= 127) + sbyte fooSbyte = 100; + + // Byte - Vorzeichenlose 8-Bit Ganzzahl + // (0 <= byte <= 255) + byte fooByte = 100; + + // Short - 16-Bit Ganzzahl + // Vorzeichenbehaftet - (-32,768 <= short <= 32,767) + // Vorzeichenlos - (0 <= ushort <= 65,535) + short fooShort = 10000; + ushort fooUshort = 10000; + + // Integer - 32-bit Ganzzahl + int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) + uint fooUint = 1; // (0 <= uint <= 4,294,967,295) + + // Long - 64-bit Ganzzahl + long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) + // Ganze Zahlen werden standardmäßig - je nach Größe - als int oder + // uint behandelt. Ein nachgestelltes L markiert den Wert als long + // oder ulong. + + // Double - Double-precision 64-bit IEEE 754 Fließkommazahl + double fooDouble = 123.4; // Genauigkeit: 15-16 Stellen + + // Float - Single-precision 32-bit IEEE 754 Fließkommazahl + float fooFloat = 234.5f; // Genauigkeit: 7 Stellen + // Das nachgestellte f zeigt an dass es sich um einen Wert vom Typ + // float handelt + + // Decimal - ein 128-Bit-Datentyp mit größerer Genauigkeit als + // andere Fließkommatypen, und somit bestens geeignet für + // die Berechnung von Geld- und Finanzwerten + decimal fooDecimal = 150.3m; + + // Boolean - true & false + bool fooBoolean = true; // oder false + + // Char - Ein einzelnes 16-Bit Unicode Zeichen + char fooChar = 'A'; + + // Strings - im Gegensatz zu allen vorhergehenden Basistypen, die + // alle Werttypen sind, ist String ein Referenztyp. Strings sind + // somit nullable, Werttypen sind dies nicht. + string fooString = "\"maskiere\" Anführungszeichen, und füge \n (Umbrüche) und \t (Tabs) hinzu"; + Console.WriteLine(fooString); + + // Jeder Buchstabe eines Strings kann über seinen Index + // referenziert werden: + char charFromString = fooString[1]; // => 'e' + // Strings sind unveränderlich: + // `fooString[1] = 'X';` funktioniert nicht + + // Ein Vergleich zweier Strings, unter Berücksichtigung der + // aktuellen, sprachspezifischen Gegebenheiten (also z.B. a,ä,b,c + // in deutschsprachigen Umgebungen), und ohne Beachtung von + // Groß- und Kleinschreibung: + string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); + + // Formatierung, genau wie "sprintf" + string fooFs = string.Format("Mikrofon Check, {0} {1}, {0} {1:0.0}", 1, 2); + + // Datumsangaben und Formatierung + DateTime fooDate = DateTime.Now; + Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + + // Durch ein vorangestelltes @ lässt sich ein mehrzeiliger String + // schreiben. Um " zu maskieren benutzt man "" + string bazString = @"Hier geht es +zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen"; + + // Die Keywords const oder readonly kennzeichnen eine + // unveränderliche Variable/Konstante. Die Werte von Konstanten + // werden übrigens bereits zur Compile-Zeit berechnet. + const int HOURS_I_WORK_PER_WEEK = 9001; + + /////////////////////////////////////////////////// + // Datenstrukturen + /////////////////////////////////////////////////// + + // Arrays - Index beginnt bei Null + // Die Größe des Arrays wird bei der Deklaration festgelegt. + // Die syntaktische Struktur um ein neues Array zu erzeugen sieht + // folgendermaßen aus: + // <datatype>[] <varname> = new <datatype>[<array size>]; + int[] intArray = new int[10]; + + // Arrays können auch über ein Array-Literal deklariert werden: + int[] y = { 9000, 1000, 1337 }; + + // Indizierung eines Arrays - Zugriff auf ein bestimmtes Element + Console.WriteLine("intArray @ 0: " + intArray[0]); + // Arrays sind veränderbar + intArray[1] = 1; + + // Listen + // Durch ihre größere Flexibilität kommen Listen in C# weit + // häufiger zum Einsatz als Arrays. Eine Liste wird so deklariert: + // List<datatype> <varname> = new List<datatype>(); + List<int> intList = new List<int>(); + List<string> stringList = new List<string>(); + List<int> z = new List<int> { 9000, 1000, 1337 }; + // Die <> kennzeichnen "Generics", mehr dazu unter "Coole Sachen" + + // Listen haben keinen Default-Wert. + // Bevor auf einen Index zugegriffen werden kann, muss dieser + // auch gesetzt worden sein: + intList.Add(1); + Console.WriteLine("intList @ 0: " + intList[0]); + + // Andere interessante Datenstrukturen sind: + // Stack/Queue + // Dictionary (entspricht einer Hash Map) + // HashSet + // Read-only Collections + // Tuple (.Net 4+) + + /////////////////////////////////////// + // Operatoren + /////////////////////////////////////// + Console.WriteLine("\n->Operatoren"); + + // kurze Schreibweise um mehrere Deklarationen zusammenzufassen: + // (Benutzung vom C# Styleguide aber ausdrücklich abgeraten!) + int i1 = 1, i2 = 2; + + // Arithmetik funktioniert wie erwartet: + Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 + + // Modulo + Console.WriteLine("11%3 = " + (11 % 3)); // => 2 + + // Vergleiche + Console.WriteLine("3 == 2? " + (3 == 2)); // => false + Console.WriteLine("3 != 2? " + (3 != 2)); // => true + Console.WriteLine("3 > 2? " + (3 > 2)); // => true + Console.WriteLine("3 < 2? " + (3 < 2)); // => false + Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true + Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true + + // Bitweise Operatoren + /* + ~ Unäres bitweises NICHT + << Verschieben nach links + >> Verschieben nach rechts + & Bitweises UND + ^ Bitweises exklusives ODER + | Bitweises inklusives ODER + */ + + // Inkremente + int i = 0; + Console.WriteLine("\n->Inkrement / Dekrement"); + Console.WriteLine(i++); //i = 1. Post-Inkrement + Console.WriteLine(++i); //i = 2. Pre-Inkrement + Console.WriteLine(i--); //i = 1. Post-Dekrement + Console.WriteLine(--i); //i = 0. Pre-Dekrement + + /////////////////////////////////////// + // Kontrollstrukturen + /////////////////////////////////////// + Console.WriteLine("\n->Kontrollstrukturen"); + + // If-Statements funktionieren wie in C + int j = 10; + if (j == 10) + { + Console.WriteLine("Ich werde ausgegeben"); + } + else if (j > 10) + { + Console.WriteLine("Ich nicht"); + } + else + { + Console.WriteLine("Ich leider auch nicht"); + } + + // Ternärer Operator + // Anstatt eines einfachen if/else lässt sich auch folgendes schreiben: + // <condition> ? <true> : <false> + int zumVergleich = 17; + string isTrue = zumVergleich == 17 ? "Ja" : "Nein"; + + // while-Schleife + int fooWhile = 0; + while (fooWhile < 100) + { + // Wird 100mal wiederholt, fooWhile 0->99 + fooWhile++; + } + + // do-while-Schleife + int fooDoWhile = 0; + do + { + // Wird 100mal wiederholt, fooDoWhile 0->99 + fooDoWhile++; + } while (fooDoWhile < 100); + + //for-Schleifen => for(<start_statement>; <conditional>; <step>) + for (int fooFor = 0; fooFor < 10; fooFor++) + { + // Wird 10mal wiederholt, fooFor 0->9 + } + + // foreach-Schleife + // Die normale Syntax für eine foreach-Schleife lautet: + // foreach(<iteratorType> <iteratorName> in <enumerable>) + // foreach kann mit jedem Objekt verwendet werden das IEnumerable + // oder IEnumerable<T> implementiert. Alle Auflistungs-Typen + // (Array, List, Dictionary...) im .NET Framework implementieren + // eines dieser beiden Interfaces. + + foreach (char character in "Hallo Welt".ToCharArray()) + { + // Ein Durchgang für jedes Zeichen im String + } + // (ToCharArray() könnte man hier übrigens auch weglassen, + // da String IEnumerable bereits implementiert) + + // Switch Struktur + // Ein Switch funktioniert mit byte, short, char und int Datentypen. + // Auch Aufzählungstypen können verwendet werden, genau wie + // die Klasse String, und ein paar Sonderklassen, die Wrapper für + // Primitives sind: Character, Byte, Short und Integer + int month = 3; + string monthString; + switch (month) + { + case 1: + monthString = "Januar"; + break; + case 2: + monthString = "Februar"; + break; + case 3: + monthString = "März"; + break; + // Man kann für mehrere Fälle auch das selbe Verhalten + // definieren. Jeder Block muss aber mit einem break-Statement + // abgeschlossen werden. Einzelne Fälle können über + // `goto case x` erreicht werden + case 6: + case 7: + case 8: + monthString = "Sommer!!"; + break; + default: + monthString = "Irgendein anderer Monat"; + break; + } + + /////////////////////////////////////// + // Umwandlung von Datentypen und Typecasting + /////////////////////////////////////// + + // Umwandlung + + // von String nach Integer + // bei einem Fehler wirft diese Code eine Exception + int.Parse("123"); //gibt die Ganzzahl 123 zurück + + // TryParse gibt bei einem Fehler den Default-Wert zurück + // (im Fall von int: 0) + int tryInt; + if (int.TryParse("123", out tryInt)) // gibt true oder false zurück + { + Console.WriteLine(tryInt); // 123 + } + + // von Integer nach String + // Die Klasse Convert stellt Methoden zur Konvertierung von + // unterschiedlichsten Daten zur Verfügung: + Convert.ToString(123); // "123" + // oder + tryInt.ToString(); // "123" + } + + /////////////////////////////////////// + // Klassen + /////////////////////////////////////// + public static void Classes() + { + + // Benutze das new-Keyword um eine Instanz einer Klasse zu erzeugen + Bicycle trek = new Bicycle(); + + // So werden Methoden der Instanz aufgerufen + trek.SpeedUp(3); // Es empfiehlt sich immer Getter und Setter zu benutzen + trek.Cadence = 100; + + // ToString ist eine Konvention über die man üblicherweiser + // Informationen über eine Instanz erhält + Console.WriteLine("Infos zu trek: " + trek.ToString()); + + // Wir instantiieren ein neues Hochrad + PennyFarthing funbike = new PennyFarthing(1, 10); + Console.WriteLine("Infos zu funbike: " + funbike.ToString()); + + Console.Read(); + } // Ende der Methode main + + // Main als Konsolenstartpunkt + // Eine Konsolenanwendung muss eine Methode Main als Startpunkt besitzen + public static void Main(string[] args) + { + OtherInterestingFeatures(); + } + + /////////////////////////////////////// + // Interessante Features + /////////////////////////////////////// + + // Methodensignaturen + + public // Sichtbarkeit + static // Erlaubt einen Zugriff auf der Klasse (nicht auf einer Instanz) + int // Typ des Rückgabewerts, + MethodSignatures( + // Erstes Argument, erwartet int + int maxCount, + // setzt sich selbst auf 0 wenn kein anderer Wert übergeben wird + int count = 0, + int another = 3, + // enthält alle weiteren der Methode übergebenen Parameter (quasi Splats) + params string[] otherParams + ) + { + return -1; + } + + // Methoden können überladen werden, solange sie eindeutige + // Signaturen haben + public static void MethodSignatures(string maxCount) + { + } + + // Generische Typen + // Die Typen für TKey und TValue werden erst beim Aufruf der Methode + // festgelegt. Diese Methode emuliert z.B. SetDefault aus Python: + public static TValue SetDefault<TKey, TValue>( + IDictionary<TKey, TValue> dictionary, + TKey key, + TValue defaultItem) + { + TValue result; + if (!dictionary.TryGetValue(key, out result)) + { + return dictionary[key] = defaultItem; + } + return result; + } + + // Möglichen Typen lassen sich auch über ihr Interface beschränken: + public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int> + { + // Da T ein IEnumerable ist können wir foreach benutzen + foreach (var item in toPrint) + { + // Item ist ein int + Console.WriteLine(item.ToString()); + } + } + + public static void OtherInterestingFeatures() + { + // Optionale Parameter + MethodSignatures(3, 1, 3, "Ein paar", "extra", "Strings"); + // setzt explizit einen bestimmten Parameter, andere werden übersprungen + MethodSignatures(3, another: 3); + + // Erweiterungsmethoden + int i = 3; + i.Print(); // Weiter unten definiert + + // Nullables - perfekt für die Interaktion mit + // Datenbanken / Rückgabewerten + // Jeder Wert (d.h. keine Klassen) kann durch das Nachstellen eines ? + // nullable gemacht werden: <type>? <varname> = <value> + int? nullable = null; // Die explizite Langform wäre Nullable<int> + Console.WriteLine("Mein Nullable: " + nullable); + bool hasValue = nullable.HasValue; // true wenn nicht null + + // ?? ist "syntaktischer Zucker" um einen Defaultwert für den Fall + // dass die Variable null ist festzulegen. + int notNullable = nullable ?? 0; // 0 + + // Implizit typisierte Variablen + // Man kann auch den Typ einer Variable auch vom Compiler + // bestimmen lassen: + var magic = "magic ist zur Compile-Zeit ein String, folglich geht keine Typsicherheit verloren"; + magic = 9; // funktioniert nicht da magic vom Typ String ist + + // Generics + var phonebook = new Dictionary<string, string>() { + {"Resi", "08822 / 43 67"} // Fügt einen Eintrag zum Telefonbuch hinzu + }; + + // Hier könnte man auch unser generisches SetDefault von + // weiter oben benutzen: + Console.WriteLine(SetDefault<string,string>(phonebook, "Xaver", "kein Telefon")); // kein Telefon + // TKey und TValue müssen nicht zwingend angegeben werden, da sie + // auch implizit vom Compiler ermittelt werden können + Console.WriteLine(SetDefault(phonebook, "Resi", "kein Telefon")); // 08822 / 43 67 + + // Lambdas - konzise Syntax für Inline-Funktionen + Func<int, int> square = (x) => x * x; // Das letzte Element vom Typ T ist der Rückgabewert + Console.WriteLine(square(3)); // 9 + + // Disposables - einfaches Management von nicht verwalteten Ressourcen + // So gut wie alle Objekte die auf nicht verwaltete Ressourcen + // (Dateien, Geräte, ...) zugreifen, implementieren das Interface + // IDisposable. Das using Statement stellt sicher dass die vom + // IDisposable benutzten Ressourcen nach der Benutzung wieder + // freigegeben werden: + using (StreamWriter writer = new StreamWriter("log.txt")) + { + writer.WriteLine("Alles bestens!"); + // Am Ende des Codeblocks werden die Ressourcen wieder + // freigegeben - auch im Falle einer Exception + } + + // Parallel Klasse + // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx + var websites = new string[] { + "http://www.google.com", "http://www.reddit.com", + "http://www.shaunmccarthy.com" + }; + var responses = new Dictionary<string, string>(); + + // Für jeden Request wird ein neuer Thread erzeugt, der nächste + // Schritt wird erst nach Beendigung aller Tasks ausgeführt + Parallel.ForEach(websites, + // maximal 3 Threads gleichzeitig + new ParallelOptions() {MaxDegreeOfParallelism = 3}, + website => + { + // Hier folgt eine langwierige, asynchrone Operation + using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + { + responses[website] = r.ContentType; + } + }); + + // Dieser Code wird erst nach Beendigung aller Requests ausgeführt + foreach (var key in responses.Keys) + { + Console.WriteLine("{0}:{1}", key, responses[key]); + } + + // Dynamische Objekte (gut um mit anderen Sprachen zu arbeiten) + dynamic student = new ExpandoObject(); + // hier muss keine Typ angegeben werden + student.FirstName = "Christian"; + + // Einem solchen Objekt kann man sogar Methoden zuordnen. + // Das Beispiel gibt einen String zurück und erwartet einen String + student.Introduce = new Func<string, string>( + (introduceTo) => string.Format("Hallo {0}, das ist {1}", student.FirstName, introduceTo)); + Console.WriteLine(student.Introduce("Bettina")); + + // IQueryable<T> - So gut wie alle Aufzählungstypen implementieren + // dieses Interface, welches eine Vielzahl von funktionalen Methoden + // wie Map / Filter / Reduce zur Verfügung stellt: + var bikes = new List<Bicycle>(); + // sortiert die Liste + bikes.Sort(); + // sortiert nach Anzahl Räder + bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); + var result = bikes + // diese Filter können auch aneinandergehängt werden + .Where(b => b.Wheels > 3) // (gibt ein IQueryable des vorherigen Typs zurück) + .Where(b => b.IsBroken && b.HasTassles) + // diese Zuordnung gibt ein IQueryable<String> zurück + .Select(b => b.ToString()); + + // "Reduce" - addiert alle Räder der Aufzählung zu einem Wert + var sum = bikes.Sum(b => b.Wheels); + + // So erzeugt man ein implizit typisiertes Objekt, basierend auf + // den Parametern der Elemente: + var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); + // Auch wenn wir es hier nicht demonstrieren können: + // In einer IDE wie VisualStudio kriegen wir hier sogar TypeAhead, + // da der Compiler in der Lage ist, die passenden Typen zu erkennen. + foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) + { + Console.WriteLine(bikeSummary.Name); + } + + // AsParallel-Methode + // Jetzt kommen die Schmankerl! Die AsParallel-Methode kombiniert + // LINQ und parallele Operationen: + var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); + // Diese Berechnung passiert parallel! Benötigte Threads werden + // automatisch erzeugt, und die Rechenlast unter ihnen aufgeteilt. + // Ein Traum für die Verarbeitung von großen Datenmengen + // auf mehreren Cores! + + // LINQ - bildet einen Datenspeicher auf IQueryable<T> Objekte ab + // LinqToSql beispielsweise speichert und liest aus einer + // SQL-Datenbank, LinqToXml aus einem XML-Dokument. + // LINQ-Operationen werden "lazy" ausgeführt. + var db = new BikeRepository(); + + // Die verzögerte Ausführung ist optimal für Datenbankabfragen + var filter = db.Bikes.Where(b => b.HasTassles); // noch keine Abfrage + // Es können noch mehr Filter hinzugefügt werden (auch mit + // Bedingungen) - ideal für z.B. "erweiterte Suchen" + if (42 > 6) + { + filter = filter.Where(b => b.IsBroken); // immer noch keine Abfrage + } + + var query = filter + .OrderBy(b => b.Wheels) + .ThenBy(b => b.Name) + .Select(b => b.Name); // auch hier: immer noch keine Abfrage + + // Erst hier wird die Datenbankabfrage wirklich ausgeführt, + // limitiert auf die Elemente die der foreach-Loop verwendet + foreach (string bike in query) + { + Console.WriteLine(result); + } + + } + + } // Ende der Klasse LearnCSharp + + // Eine .cs-Datei kann auch mehrere Klassen enthalten + + public static class Extensions + { + // Erweiterungsmethoden + public static void Print(this object obj) + { + Console.WriteLine(obj.ToString()); + } + } + + // Syntax zur Deklaration einer Klasse: + // <public/private/protected/internal> class <class name>{ + // // Datenfelder, Konstruktoren und Methoden leben alle + // // innerhalb dieser Deklaration + // } + + public class Bicycle + { + // Felder/Variablen der Klasse "Bicycle" + // Das Keyword public macht das Member von überall zugänglich + public int Cadence + { + get // get definiert eine Methode um die Eigenschaft abzurufen + { + return _cadence; + } + set // set definiert eine Methode um die Eigenschaft zu setzen + { + _cadence = value; // value ist der dem Setter übergebene Wert + } + } + private int _cadence; + + // Das Keyword protected macht das Member nur für die Klasse selbst + // und ihre Subklassen zugänglich + protected virtual int Gear + { + get; // erzeugt eine Eigenschaft für die kein "Zwischenwert" benötigt wird + set; + } + + // Das Keyword internal macht das Member innerhalb der Assembly zugänglich + internal int Wheels + { + get; + private set; // get/set kann auch über Keywords modifiziert werden + } + + int _speed; // Member ohne vorangestellte Keywords sind standardmäßig + // private, sie sind nur innerhalb der Klasse zugänglich. + // Man kann aber natürlich auch das Keyword private benutzen. + private string Name { get; set; } + + // Ein Enum ist ein klar definierter Satz an benannten Konstanten. + // Eigentlich ordnet es diese Konstanten nur bestimmten Werten zu + // (einer int-Zahl, solange nicht anders angegeben). Mögliche Typen für + // die Werte eines Enums sind byte, sbyte, short, ushort, int, uint, + // long, oder ulong. Alle Werte in einem Enum sind eindeutig. + public enum BikeBrand + { + Colnago, + EddyMerckx, + Bianchi = 42, // so kann man den Wert explizit setzen + Kynast // 43 + } + // Nachdem dieser Typ in der Klasse "Bicycle" definiert ist, + // sollte Code ausserhalb der Klasse den Typen als Bicycle.Brand referenzieren + + // Nachdem das Enum deklariert ist, können wir den Typen verwenden: + public BikeBrand Brand; + + // Als static gekennzeichnete Member gehören dem Typ selbst, + // nicht seinen Instanzen. Man kann sie also ohne Referenz zu einem + // Objekt benutzen + // Console.WriteLine("Schon " + Bicycle.BicyclesCreated + " Fahrräder, nur für dieses Tutorial!"); + static public int BicyclesCreated = 0; + + // readonly-Werte werden zur Laufzeit gesetzt + // Ihr Wert kann nur bei ihrer Deklaration, oder in einem Konstruktor + // festgelegt werden + readonly bool _hasCardsInSpokes = false; // readonly und private + + // Konstruktoren bestimmen was bei einer Instantiierung passiert. + // Das ist ein Default-Konstruktor: + public Bicycle() + { + // Member der Klasse können über das Keyword this erreicht werden + this.Gear = 1; + // oft ist das aber gar nicht nötig + Cadence = 50; + _speed = 5; + Name = "Bonanzarad"; + Brand = BikeBrand.Kynast; + BicyclesCreated++; + } + + // Das ist ein spezifischer Konstruktor (d.h. er erwartet Argumente): + public Bicycle(int startCadence, int startSpeed, int startGear, + string name, bool hasCardsInSpokes, BikeBrand brand) + : base() // ruft zuerst den "base"-Konstruktor auf + { + Gear = startGear; + Cadence = startCadence; + _speed = startSpeed; + Name = name; + _hasCardsInSpokes = hasCardsInSpokes; + Brand = brand; + } + + // Konstruktoren können aneinandergehängt werden: + public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : + this(startCadence, startSpeed, 0, "richtig große Räder", true, brand) + { + } + + // Syntax für Methoden: + // <public/private/protected> <return type> <function name>(<args>) + + // Klassen können Getter und Setter für Werte definieren, + // oder diese Werte direkt als Eigenschaft implementieren + // (in C# der bevorzugte Weg) + + // Parameter von Methoden können Default-Werte haben. + // "SpeedUp" kann man also auch ohne Parameter aufrufen: + public void SpeedUp(int increment = 1) + { + _speed += increment; + } + + public void SlowDown(int decrement = 1) + { + _speed -= decrement; + } + + // Eigenschaften mit get/set + // wenn es nur um den Zugriff auf Daten geht, ist eine Eigenschaft zu + // empfehlen. Diese können Getter und Setter haben, oder auch nur + // einen Getter bzw. einen Setter + private bool _hasTassles; // private Variable + public bool HasTassles // öffentliches Interface + { + get { return _hasTassles; } + set { _hasTassles = value; } + } + + // Das kann man auch kürzer schreiben: + // Dieser Syntax erzeugt automatisch einen hinterlegten Wert, + // (entsprechend `private bool _isBroken`) der gesetzt + // bzw. zurückgegeben wird: + public bool IsBroken { get; private set; } + public int FrameSize + { + get; + // für Getter und Setter kann der Zugriff auch einzeln + // beschränkt werden, FrameSize kann also nur von innerhalb + // der Klasse "Bicycle" gesetzt werden + private set; + } + + // Diese Methode gibt eine Reihe an Informationen über das Objekt aus: + public virtual string ToString() + { + return "Gang: " + Gear + + " Kadenz: " + Cadence + + " Geschwindigkeit: " + _speed + + " Name: " + Name + + " Hipster-Karten zwischen den Speichen: " + (_hasCardsInSpokes ? "Na klar!" : "Bloß nicht!") + + "\n------------------------------\n" + ; + } + + // Auch Methoden können als static gekennzeichnet werden, nützlich + // beispielsweise für Helper-Methoden + public static bool DidWeCreateEnoughBicyclesYet() + { + // In einer statischen Methode können wir natürlich auch nur + // statische Member der Klasse referenzieren + return BicyclesCreated > 9000; + } + // Wenn eine Klasse nur statische Member enthält, kann es eine gute Idee + // sein die Klasse selbst als static zu kennzeichnen + + } // Ende der Klasse "Bicycle" + + // "PennyFarthing" ist eine Unterklasse von "Bicycle" + class PennyFarthing : Bicycle + { + // (Hochräder - englisch Penny Farthing - sind diese antiken Fahrräder + // mit riesigem Vorderrad. Sie haben keine Gangschaltung.) + + // hier wird einfach der Elternkonstruktor aufgerufen + public PennyFarthing(int startCadence, int startSpeed) : + base(startCadence, startSpeed, 0, "Hochrad", true, BikeBrand.EddyMerckx) + { + } + + protected override int Gear + { + get + { + return 0; + } + set + { + throw new ArgumentException("Ein Hochrad hat keine Gangschaltung, doh!"); + } + } + + public override string ToString() + { + string result = "Hochrad "; + result += base.ToString(); // ruft die "base"-Version der Methode auf + return result; + } + } + + // Interfaces (auch Schnittstellen genant) definieren nur die Signaturen + // ihrer Member, enthalten aber auf keinen Fall ihre Implementierung: + interface IJumpable + { + // Alle Member eines Interfaces sind implizit public + void Jump(int meters); + } + + interface IBreakable + { + // Interfaces können Eigenschaften, Methoden und Events definieren + bool Broken { get; } + } + + // Eine Klasse kann nur von einer Klasse erben, kann aber eine beliebige + // Anzahl von Interfaces implementieren + class MountainBike : Bicycle, IJumpable, IBreakable + { + int damage = 0; + + public void Jump(int meters) + { + damage += meters; + } + + public bool Broken + { + get + { + return damage > 100; + } + } + } + + // Das hier stellt eine Datenbankverbindung für das LinqToSql-Beispiel her. + // EntityFramework Code First ist großartig + // (ähnlich zu Ruby's ActiveRecord, aber bidirektional) + // http://msdn.microsoft.com/de-de/data/jj193542.aspx + public class BikeRepository : DbSet + { + public BikeRepository() + : base() + { + } + + public DbSet<Bicycle> Bikes { get; set; } + } +} // Ende des Namespaces +``` + +## In dieser Übersicht nicht enthalten sind die Themen: + + * Flags + * Attributes + * Statische Eigenschaften + * Exceptions, Abstraction + * ASP.NET (Web Forms/MVC/WebMatrix) + * Winforms + * Windows Presentation Foundation (WPF) + +## Zum Weiterlesen gibt es viele gute Anlaufpunkte: + + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ](http://shop.oreilly.com/product/9780596519254.do) + * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) + * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) + * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/overview/exploring-webmatrix) + * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + +[C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx) diff --git a/de-de/dynamic-programming-de.html.markdown b/de-de/dynamic-programming-de.html.markdown index 58568b3b..9cf461d0 100644 --- a/de-de/dynamic-programming-de.html.markdown +++ b/de-de/dynamic-programming-de.html.markdown @@ -56,6 +56,7 @@ wie `largest_sequences_so_far` und dessen Index würde eine Menge Zeit sparen. Ein ähnliches Konzept könnte auch bei der Suche nach dem längsten Weg in gerichteten azyklischen Graphen angewandt werden. + ```python for i=0 to n-1 LS[i]=1 diff --git a/de-de/elixir-de.html.markdown b/de-de/elixir-de.html.markdown index 254cca51..4acb8e23 100644 --- a/de-de/elixir-de.html.markdown +++ b/de-de/elixir-de.html.markdown @@ -1,423 +1,423 @@ ----
-language: elixir
-contributors:
- - ["Joao Marques", "http://github.com/mrshankly"]
-translators:
- - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
-filename: learnelixir-de.ex
-lang: de-de
----
-
-Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
-kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
-viele Features mit.
-
-```ruby
-
-# Einzeilige Kommentare werden mit der Raute gesetzt.
-
-# Es gibt keine mehrzeiligen Kommentare;
-# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
-# zu setzen (so wie hier).
-
-# Mit 'iex' ruft man die Elixir-Shell auf.
-# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
-
-# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
-# installiert wurde.
-
-## ---------------------------
-## -- Basistypen
-## ---------------------------
-
-# Es gibt Nummern:
-3 # Integer
-0x1F # Integer
-3.0 # Float
-
-# Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden
-1_000_000 == 1000000 # Integer
-1_000.567 == 1000.567 # Float
-
-# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
-# ':'.
-:hello # Atom
-
-# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
-{1,2,3} # Tupel
-
-# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
-# werden:
-elem({1, 2, 3}, 0) # => 1
-
-# Listen sind als verkettete Listen implementiert.
-[1, 2, 3] # list
-
-# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
-[ kopf | rest ] = [1,2,3]
-kopf # => 1
-rest # => [2, 3]
-
-# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
-# (Musterabgleich) und keine Zuweisung.
-# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
-# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
-# werden.
-
-# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
-# zusammenpassen.
-# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
-# Elementen:
-{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
-
-# Es gibt außerdem 'binaries',
-<<1,2,3>> # binary.
-
-# Strings und 'char lists'
-"hello" # String
-'hello' # Char-Liste
-
-# ... und mehrzeilige Strings
-"""
-Ich bin ein
-mehrzeiliger String.
-"""
-#=> "Ich bin ein\nmehrzeiliger String.\n"
-
-# Alles Strings werden in UTF-8 enkodiert:
-"héllò" #=> "héllò"
-
-# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
-# Listen.
-<<?a, ?b, ?c>> #=> "abc"
-[?a, ?b, ?c] #=> 'abc'
-
-# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
-?a #=> 97
-
-# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
-[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
-'hello ' ++ 'world' #=> 'hello world'
-
-<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
-"hello " <> "world" #=> "hello world"
-
-## ---------------------------
-## -- Operatoren
-## ---------------------------
-
-# Einfache Arithmetik
-1 + 1 #=> 2
-10 - 5 #=> 5
-5 * 2 #=> 10
-10 / 2 #=> 5.0
-
-# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
-
-# Für Division mit ganzzahligen Ergebnis gibt es 'div'
-div(10, 2) #=> 5
-
-# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
-rem(10, 3) #=> 1
-
-# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
-# Operatoren erwarten einen Boolean als erstes Argument.
-true and true #=> true
-false or true #=> true
-# 1 and true #=> ** (ArgumentError) argument error
-
-# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
-# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
-1 || true #=> 1
-false && 1 #=> false
-nil && 20 #=> nil
-
-!true #=> false
-
-# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
-# `<` und `>`
-1 == 1 #=> true
-1 != 1 #=> false
-1 < 2 #=> true
-
-# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
-1 == 1.0 #=> true
-1 === 1.0 #=> false
-
-# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
-1 < :hello #=> true
-
-# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
-# number < atom < reference < functions < port < pid < tuple < list < bitstring
-
-# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
-# total ordering is well defined is important."
-
-## ---------------------------
-## -- Kontrollstrukturen
-## ---------------------------
-
-# Es gibt die `if`-Verzweigung
-if false do
- "Dies wird nie jemand sehen..."
-else
- "...aber dies!"
-end
-
-# ...und ebenso `unless`
-unless true do
- "Dies wird nie jemand sehen..."
-else
- "...aber dies!"
-end
-
-# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
-# arbeiten damit.
-
-# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
-case {:one, :two} do
- {:four, :five} ->
- "Das wird nicht passen"
- {:one, x} ->
- "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
- _ ->
- "Dieser Fall greift immer."
-end
-
-# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
-# nicht weiter verwendet wird.
-# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
-[kopf | _] = [1,2,3]
-kopf #=> 1
-
-# Für bessere Lesbarkeit können wir auch das Folgende machen:
-[kopf | _rest] = [:a, :b, :c]
-kopf #=> :a
-
-# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
-# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
-cond do
- 1 + 1 == 3 ->
- "Ich werde nie aufgerufen."
- 2 * 5 == 12 ->
- "Ich auch nicht."
- 1 + 2 == 3 ->
- "Aber ich!"
-end
-
-# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
-cond do
- 1 + 1 == 3 ->
- "Ich werde nie aufgerufen."
- 2 * 5 == 12 ->
- "Ich auch nicht."
- true ->
- "Aber ich! (dies ist im Grunde ein 'else')"
-end
-
-# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
-# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
-# egal ob zuvor ein Wert gefangen wurde.
-try do
- throw(:hello)
-catch
- nachricht -> "#{nachricht} gefangen."
-after
- IO.puts("Ich bin die 'after'-Klausel.")
-end
-#=> Ich bin die 'after'-Klausel.
-# ":hello gefangen"
-
-## ---------------------------
-## -- Module und Funktionen
-## ---------------------------
-
-# Anonyme Funktionen (man beachte den Punkt)
-square = fn(x) -> x * x end
-square.(5) #=> 25
-
-# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
-# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
-# eingeführt:
-f = fn
- x, y when x > 0 -> x + y
- x, y -> x * y
-end
-
-f.(1, 3) #=> 4
-f.(-1, 3) #=> -3
-
-# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
-# Geltungsbereich ('scope') verfügbar.
-is_number(10) #=> true
-is_list("hello") #=> false
-elem({1,2,3}, 0) #=> 1
-
-# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
-# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
-# definieren.
-defmodule Math do
- def sum(a, b) do
- a + b
- end
-
- def square(x) do
- x * x
- end
-end
-
-Math.sum(1, 2) #=> 3
-Math.square(3) #=> 9
-
-# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
-# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
-# werden: elixirc math.ex
-
-# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
-# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
-# werden; eine private Funktion kann nur lokal angesprochen werden.
-defmodule PrivateMath do
- def sum(a, b) do
- do_sum(a, b)
- end
-
- defp do_sum(a, b) do
- a + b
- end
-end
-
-PrivateMath.sum(1, 2) #=> 3
-# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
-
-# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
-defmodule Geometry do
- def area({:rectangle, w, h}) do
- w * h
- end
-
- def area({:circle, r}) when is_number(r) do
- 3.14 * r * r
- end
-end
-
-Geometry.area({:rectangle, 2, 3}) #=> 6
-Geometry.area({:circle, 3}) #=> 28.25999999999999801048
-# Geometry.area({:circle, "not_a_number"})
-#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
-
-# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
-# Bestandteil von Elixir.
-defmodule Recursion do
- def sum_list([head | tail], acc) do
- sum_list(tail, acc + head)
- end
-
- def sum_list([], acc) do
- acc
- end
-end
-
-Recursion.sum_list([1,2,3], 0) #=> 6
-
-# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
-# ist es möglich eigene Attribute hinzuzufügen.
-defmodule MyMod do
- @moduledoc """
- Dies ist ein eingebautes Attribut in einem Beispiel-Modul
- """
-
- @my_data 100 # Dies ist ein selbst-definiertes Attribut.
- IO.inspect(@my_data) #=> 100
-end
-
-## ---------------------------
-## -- 'Records' und Ausnahmebehandlung
-## ---------------------------
-
-# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
-# Namen zuzuweisen.
-defrecord Person, name: nil, age: 0, height: 0
-
-joe_info = Person.new(name: "Joe", age: 30, height: 180)
-#=> Person[name: "Joe", age: 30, height: 180]
-
-# Zugriff auf den Wert von 'name'
-joe_info.name #=> "Joe"
-
-# Den Wert von 'age' überschreiben
-joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
-
-# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
-# um Ausnahmen beziehungsweise Fehler zu behandeln.
-try do
- raise "Irgendein Fehler."
-rescue
- RuntimeError -> "Laufzeit-Fehler gefangen."
- _error -> "Und dies fängt jeden Fehler."
-end
-
-# Alle Ausnahmen haben das Attribut 'message'
-try do
- raise "ein Fehler"
-rescue
- x in [RuntimeError] ->
- x.message
-end
-
-## ---------------------------
-## -- Nebenläufigkeit
-## ---------------------------
-
-# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
-# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
-# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
-
-# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
-# wiederum eine Funktion als Argument entgegen nimmt.
-f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
-spawn(f) #=> #PID<0.40.0>
-
-# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
-# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
-# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
-# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
-# 'receive'-Mechanismus sichergestellt:
-defmodule Geometry do
- def area_loop do
- receive do
- {:rectangle, w, h} ->
- IO.puts("Area = #{w * h}")
- area_loop()
- {:circle, r} ->
- IO.puts("Area = #{3.14 * r * r}")
- area_loop()
- end
- end
-end
-
-# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
-# in der Shell mit, etwa so:
-pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
-
-# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
-# erfüllt:
-pid <- {:rectangle, 2, 3}
-#=> Area = 6
-# {:rectangle,2,3}
-
-pid <- {:circle, 2}
-#=> Area = 12.56000000000000049738
-# {:circle,2}
-
-# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
-# die aktuelle pid herausfinden.
-self() #=> #PID<0.27.0>
-
-```
-
-## Referenzen und weitere Lektüre
-
-* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
-* [Elixir Documentation](http://elixir-lang.org/docs/master/)
-* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
-* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong
+--- +language: Elixir +contributors: + - ["Joao Marques", "http://github.com/mrshankly"] +translators: + - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"] +filename: learnelixir-de.ex +lang: de-de +--- + +Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll +kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt +viele Features mit. + +```ruby + +# Einzeilige Kommentare werden mit der Raute gesetzt. + +# Es gibt keine mehrzeiligen Kommentare; +# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander +# zu setzen (so wie hier). + +# Mit 'iex' ruft man die Elixir-Shell auf. +# Zum kompilieren von Modulen dient der Befehl 'elixirc'. + +# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt +# installiert wurde. + +## --------------------------- +## -- Basistypen +## --------------------------- + +# Es gibt Nummern: +3 # Integer +0x1F # Integer +3.0 # Float + +# Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden +1_000_000 == 1000000 # Integer +1_000.567 == 1000.567 # Float + +# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem +# ':'. +:hello # Atom + +# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden. +{1,2,3} # Tupel + +# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen +# werden: +elem({1, 2, 3}, 0) # => 1 + +# Listen sind als verkettete Listen implementiert. +[1, 2, 3] # list + +# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden: +[ kopf | rest ] = [1,2,3] +kopf # => 1 +rest # => [2, 3] + +# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching' +# (Musterabgleich) und keine Zuweisung. +# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird. +# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen +# werden. + +# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht +# zusammenpassen. +# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an +# Elementen: +{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# Es gibt außerdem 'binaries', +<<1,2,3>> # binary. + +# Strings und 'char lists' +"hello" # String +'hello' # Char-Liste + +# ... und mehrzeilige Strings +""" +Ich bin ein +mehrzeiliger String. +""" +#=> "Ich bin ein\nmehrzeiliger String.\n" + +# Alles Strings werden in UTF-8 enkodiert: +"héllò" #=> "héllò" + +# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach +# Listen. +<<?a, ?b, ?c>> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück. +?a #=> 97 + +# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>' +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'hello ' ++ 'world' #=> 'hello world' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"hello " <> "world" #=> "hello world" + +## --------------------------- +## -- Operatoren +## --------------------------- + +# Einfache Arithmetik +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# In Elixir gibt der Operator '/' immer einen Float-Wert zurück. + +# Für Division mit ganzzahligen Ergebnis gibt es 'div' +div(10, 2) #=> 5 + +# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem' +rem(10, 3) #=> 1 + +# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese +# Operatoren erwarten einen Boolean als erstes Argument. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs +# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil + +!true #=> false + +# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`, +# `<` und `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# '===' und '!==' sind strikter beim Vergleich von Integern und Floats: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen: +1 < :hello #=> true + +# Die gesamte Ordnung über die Datentypen ist wie folgt definiert: +# number < atom < reference < functions < port < pid < tuple < list < bitstring + +# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a +# total ordering is well defined is important." + +## --------------------------- +## -- Kontrollstrukturen +## --------------------------- + +# Es gibt die `if`-Verzweigung +if false do + "Dies wird nie jemand sehen..." +else + "...aber dies!" +end + +# ...und ebenso `unless` +unless true do + "Dies wird nie jemand sehen..." +else + "...aber dies!" +end + +# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir +# arbeiten damit. + +# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen. +case {:one, :two} do + {:four, :five} -> + "Das wird nicht passen" + {:one, x} -> + "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen." + _ -> + "Dieser Fall greift immer." +end + +# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert +# nicht weiter verwendet wird. +# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren: +[kopf | _] = [1,2,3] +kopf #=> 1 + +# Für bessere Lesbarkeit können wir auch das Folgende machen: +[kopf | _rest] = [:a, :b, :c] +kopf #=> :a + +# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man +# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln. +cond do + 1 + 1 == 3 -> + "Ich werde nie aufgerufen." + 2 * 5 == 12 -> + "Ich auch nicht." + 1 + 2 == 3 -> + "Aber ich!" +end + +# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert. +cond do + 1 + 1 == 3 -> + "Ich werde nie aufgerufen." + 2 * 5 == 12 -> + "Ich auch nicht." + true -> + "Aber ich! (dies ist im Grunde ein 'else')" +end + +# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden. +# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird, +# egal ob zuvor ein Wert gefangen wurde. +try do + throw(:hello) +catch + nachricht -> "#{nachricht} gefangen." +after + IO.puts("Ich bin die 'after'-Klausel.") +end +#=> Ich bin die 'after'-Klausel. +# ":hello gefangen" + +## --------------------------- +## -- Module und Funktionen +## --------------------------- + +# Anonyme Funktionen (man beachte den Punkt) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben +# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when' +# eingeführt: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen +# Geltungsbereich ('scope') verfügbar. +is_number(10) #=> true +is_list("hello") #=> false +elem({1,2,3}, 0) #=> 1 + +# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines +# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu +# definieren. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex' +# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen +# werden: elixirc math.ex + +# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine +# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen +# werden; eine private Funktion kann nur lokal angesprochen werden. +defmodule PrivateMath do + def sum(a, b) do + do_sum(a, b) + end + + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +# Geometry.area({:circle, "not_a_number"}) +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 + +# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger +# Bestandteil von Elixir. +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso +# ist es möglich eigene Attribute hinzuzufügen. +defmodule MyMod do + @moduledoc """ + Dies ist ein eingebautes Attribut in einem Beispiel-Modul + """ + + @my_data 100 # Dies ist ein selbst-definiertes Attribut. + IO.inspect(@my_data) #=> 100 +end + +## --------------------------- +## -- 'Records' und Ausnahmebehandlung +## --------------------------- + +# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen +# Namen zuzuweisen. +defrecord Person, name: nil, age: 0, height: 0 + +joe_info = Person.new(name: "Joe", age: 30, height: 180) +#=> Person[name: "Joe", age: 30, height: 180] + +# Zugriff auf den Wert von 'name' +joe_info.name #=> "Joe" + +# Den Wert von 'age' überschreiben +joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180] + +# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet, +# um Ausnahmen beziehungsweise Fehler zu behandeln. +try do + raise "Irgendein Fehler." +rescue + RuntimeError -> "Laufzeit-Fehler gefangen." + _error -> "Und dies fängt jeden Fehler." +end + +# Alle Ausnahmen haben das Attribut 'message' +try do + raise "ein Fehler" +rescue + x in [RuntimeError] -> + x.message +end + +## --------------------------- +## -- Nebenläufigkeit +## --------------------------- + +# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles +# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei +# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen. + +# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die +# wiederum eine Funktion als Argument entgegen nimmt. +f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245> +spawn(f) #=> #PID<0.40.0> + +# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann +# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um +# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir +# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem +# 'receive'-Mechanismus sichergestellt: +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Area = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Area = #{3.14 * r * r}") + area_loop() + end + end +end + +# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion +# in der Shell mit, etwa so: +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> + +# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck +# erfüllt: +pid <- {:rectangle, 2, 3} +#=> Area = 6 +# {:rectangle,2,3} + +pid <- {:circle, 2} +#=> Area = 12.56000000000000049738 +# {:circle,2} + +# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man +# die aktuelle pid herausfinden. +self() #=> #PID<0.27.0> + +``` + +## Referenzen und weitere Lektüre + +* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org) +* [Elixir Documentation](http://elixir-lang.org/docs/master/) +* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert +* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong diff --git a/de-de/elm-de.html.markdown b/de-de/elm-de.html.markdown index 08832327..a6a8cd88 100644 --- a/de-de/elm-de.html.markdown +++ b/de-de/elm-de.html.markdown @@ -343,7 +343,7 @@ $ elm reactor -- Starte das REPL (read-eval-print-loop). $ elm repl --- Bibliotheken werden durch den Github-Nutzernamen und ein Repository identifiziert. +-- Bibliotheken werden durch den GitHub-Nutzernamen und ein Repository identifiziert. -- Installieren einer neuen Bibliothek. $ elm package install elm-lang/html -- Diese wird der elm-package.json Datei hinzugefügt. diff --git a/de-de/go-de.html.markdown b/de-de/go-de.html.markdown index 9409e181..1b09a1e1 100644 --- a/de-de/go-de.html.markdown +++ b/de-de/go-de.html.markdown @@ -82,7 +82,7 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ // nicht-ASCII Literal. Go Quelltext ist UTF-8 kompatibel. g := 'Σ' // Ein Runen-Typ, alias int32, gebraucht für unicode code points. - f := 3.14195 // float64, eine IEEE-754 64-bit Dezimalzahl + f := 3.14159 // float64, eine IEEE-754 64-bit Dezimalzahl c := 3 + 4i // complex128, besteht intern aus zwei float64-er // "var"-Syntax mit Initalwert @@ -308,13 +308,13 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { ``` ## Weitere Resourcen -Informationen zu Go findet man auf der [offiziellen Go Webseite](http://golang.org/). +Informationen zu Go findet man auf der [offiziellen Go Webseite](https://go.dev/). Dort gibt es unter anderem ein Tutorial und interaktive Quelltext-Beispiele, vor allem aber Dokumentation zur Sprache und den Paketen. Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr kurz und gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen -ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/) +ist außerdem der Quelltext der [Go standard Bibliothek](https://go.dev/src/) einzusehen. Dieser kann als Referenz für leicht zu verstehendes und im idiomatischen Stil verfasstes Go dienen. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen -in der [offiziellen Dokumentation von Go](http://golang.org/pkg/). +in der [offiziellen Dokumentation von Go](https://go.dev/pkg/). diff --git a/de-de/javascript-de.html.markdown b/de-de/javascript-de.html.markdown index f817ee9f..a71d4316 100644 --- a/de-de/javascript-de.html.markdown +++ b/de-de/javascript-de.html.markdown @@ -1,525 +1,525 @@ ----
-language: javascript
-contributors:
- - ["Leigh Brenecki", "https://leigh.net.au"]
-translators:
- - ["ggb", "http://www.ideen-und-soehne.de"]
-filename: learnjavascript-de.js
-lang: de-de
----
-
-(Anmerkungen des Original-Autors:)
-JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzend zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java.
-
-Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, das eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
-
-Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@excitedleigh](https://twitter.com/excitedleigh) oder [l@leigh.net.au](mailto:l@leigh.net.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.de).
-
-```js
-// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei
-// Slashes
-/* während mehrzeilige Kommentare mit einem
-Slash und einem Stern anfangen und enden */
-
-// Statements können mit einem Semikolon beendet werden
-machWas();
-
-// ...müssen sie aber nicht, weil Semikola automatisch eingefügt werden, wenn
-// eine neue Zeile beginnt, abgesehen von einigen Ausnahmen.
-machWas()
-
-// Obwohl wir uns für den Anfang nicht um diese Ausnahmen kümmern müssen ist
-// es besser die Semikola immer zu setzen.
-
-///////////////////////////////////
-// 1. Nummern, Strings und Operationen
-
-// JavaScript hat einen Nummern-Typ (64-bit IEEE 754 double).
-3; // = 3
-1.5; // = 1.5
-
-// Beinahe alle grundlegenden arithmetischen Operationen arbeiten wie erwartet.
-1 + 1; // = 2
-0.1 + 0.2; // = 0.30000000000000004
-10 * 2; // = 20
-35 / 5; // = 7
-
-// Division funktioniert auch mit einem Ergebnis nach dem Komma.
-5 / 2; // = 2.5
-
-// Bit-weise Operationen sind auch möglich; wenn eine Bit-weise Operation
-// ausgeführt wird, wird die Fließkomma-Zahl in einen 32-bit Integer (mit
-// Vorzeichen) umgewandelt.
-1 << 2; // = 4
-
-// Die Rangfolge der Operationen kann mit Klammern erzwungen werden.
-(1 + 3) * 2; // = 8
-
-// Es gibt drei spezielle, nicht-reale Nummern-Werte:
-Infinity; // Ergebnis von z. B. 1 / 0
--Infinity; // Ergebnis von z. B. -1 / 0
-NaN; // Ergebnis von z. B. 0 / 0
-
-// Es gibt auch einen Boolean-Typ (für Wahrheitswerte).
-true;
-false;
-
-// Strings werden mit ' oder " erzeugt.
-'abc';
-"Hello, world";
-
-// Für die Negation wird das ! benutzt.
-!true; // = false
-!false; // = true
-
-// Gleichheit wird mit === geprüft.
-1 === 1; // = true
-2 === 1; // = false
-
-// Ungleichheit wird mit !== überprüft.
-1 !== 1; // = false
-2 !== 1; // = true
-
-// Andere Vergleichsoperatoren sind
-1 < 10; // = true
-1 > 10; // = false
-2 <= 2; // = true
-2 >= 2; // = true
-
-// Strings können mit + verbunden
-"Hello " + "world!"; // = "Hello world!"
-
-// und mit < und > verglichen werden.
-"a" < "b"; // = true
-
-// Für den Vergleich von Werten mit "==" wird eine Typumwandlung erzwungen...
-"5" == 5; // = true
-
-// ...solange man nicht === verwendet.
-"5" === 5; // = false
-
-// Auf einzelne Buchstaben innerhalb eines Strings kann mit der Methode
-// 'charAt' zugegriffen werden
-"This is a string".charAt(0); // = "T"
-
-// Die Methode 'substring' gibt Teilbereiche eines Strings zurück
-"Hello world".substring(0, 5); // = "Hello"
-
-// 'length' ist eine Eigenschaft und wird folglich ohne '()' benutzt
-"Hello".length; // = 5
-
-// Es gibt außerdem die Werte 'null' und 'undefined'
-null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen
-undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht
- // verfügbar ist (obwohl genau genommen undefined selbst einen Wert
- // darstellt)
-
-// false, null, undefined, NaN, 0 und "" sind 'falsy', d. h. alles andere ist
-// wahr. Man beachte, dass 0 falsch und "0" wahr ist, obwohl 0 == "0".
-
-///////////////////////////////////
-// 2. Variablen, Arrays und Objekte
-
-// Variablen werden mit dem Schlüsselwort 'var' und einem frei wählbaren
-// Bezeichner deklariert. JavaScript ist dynamisch typisiert, so dass man einer
-// Variable keinen Typ zuweisen muss. Die Zuweisung verwendet ein einfaches =.
-var einWert = 5;
-
- // Wenn man das Schlüsselwort 'var' weglässt, bekommt man keinen Fehler
-einAndererWert = 10;
-
-// ...aber die Variable wird im globalen Kontext erzeugt, nicht in dem Kontext,
-// in dem sie erzeugt wurde.
-
-// Variablen die erzeugt wurden ohne ihnen einen Wert zuzuweisen, erhalten den
-// Wert 'undefined'.
-var einDritterWert; // = undefined
-
-// Es existiert eine Kurzform, um mathematische Operationen mit Variablen
-// auszuführen:
-einWert += 5; // äquivalent zu einWert = einWert + 5; einWert ist nun also 10
-einWert *= 10; // einWert ist nach dieser Operation 100
-
-// Und es existiert eine weitere, sogar noch kürzere Form, um 1 zu addieren
-// oder zu subtrahieren
-einWert++; // nun ist einWert 101
-einWert--; // wieder 100
-
-// Arrays sind geordnete Listen von Werten irgendeines Typs
-var myArray = ["Hello", 45, true];
-
-// Auf einzelne Elemente eines Arrays kann zugegriffen werden, in dem der Index
-// in eckigen Klammern hinter das Array geschrieben werden. Die Indexierung
-// beginnt bei 0.
-myArray[1]; // = 45
-
-// Arrays haben keine feste Länge
-myArray.push("World");
-myArray.length; // = 4
-
-// und sind veränderlich
-myArray[3] = "Hello";
-
-// Die Objekte in JavaScript entsprechen 'dictionaries' oder 'maps' in anderen
-// Sprachen: es handelt sich um ungeordnete Schlüssel-Wert-Paare.
-var myObj = { key1: "Hello", key2: "World" };
-
-// Schlüssel sind Strings, aber es werden keine Anführungszeichen benötigt,
-// sofern es sich um reguläre JavaScript-Bezeichner handelt. Werte können von
-// jedem Typ sein.
-var myObj = { myKey: "myValue", "my other key": 4 };
-
-// Auf Attribute von Objekten kann ebenfalls mit eckigen Klammern zugegriffen
-// werden,
-myObj["my other key"]; // = 4
-
-// ... oder in dem man die Punkt-Notation verwendet, vorausgesetzt es handelt
-// sich bei dem Schlüssel um einen validen Bezeichner.
-myObj.myKey; // = "myValue"
-
-// Objekte sind veränderlich, Werte können verändert und neue Schlüssel
-// hinzugefügt werden.
-myObj.myThirdKey = true;
-
-// Der Zugriff auf einen noch nicht definierten Schlüssel, liefert ein
-// undefined.
-myObj.myFourthKey; // = undefined
-
-///////////////////////////////////
-// 3. Logik und Kontrollstrukturen
-
-// Die if-Struktur arbeitet, wie man es erwartet.
-var count = 1;
-if (count == 3){
- // wird evaluiert, wenn count gleich 3 ist
-} else if (count == 4) {
- // wird evaluiert, wenn count gleich 4 ist
-} else {
- // wird evaluiert, wenn es weder 3 noch 4 ist
-}
-
-// Genauso 'while'.
-while (true) {
- // Eine unendliche Schleife!
-}
-
-// Do-while-Scheifen arbeiten wie while-Schleifen, abgesehen davon, dass sie
-// immer mindestens einmal ausgeführt werden.
-var input;
-do {
- input = getInput();
-} while ( !isValid( input ) )
-
-// Die for-Schleife arbeitet genau wie in C und Java:
-// Initialisierung; Bedingung, unter der die Ausführung fortgesetzt wird;
-// Iteration.
-for ( var i = 0; i < 5; i++ ) {
- // wird 5-mal ausgeführt
-}
-
-// '&&' ist das logische und, '||' ist das logische oder
-if (house.size == "big" && house.colour == "blue"){
- house.contains = "bear";
- // Die Größe des Hauses ist groß und die Farbe blau.
-}
-if (colour == "red" || colour == "blue"){
- // Die Farbe ist entweder rot oder blau.
-}
-
-// Die Auswertung von '&&' und '||' erfolgt so, dass abgebrochen wird, wenn die
-// Bedingung erfüllt ist (bei oder) oder nicht-erfüllt ist (bei und). Das ist
-// nützlich, um einen Default-Wert zu setzen.
-var name = otherName || "default";
-
-// Ein 'switch' Statement prüft Gleichheit mit ===
-// ohne ein 'break' nach jedem Fall
-// werden auch die Fälle nach dem korrekten aufgerufen
-grade = 'B';
-switch (grade) {
- case 'A':
- console.log("Great job");
- break;
- case 'B':
- console.log("OK job");
- break;
- case 'C':
- console.log("You can do better");
- break;
- default:
- console.log("Oy vey");
- break;
-}
-
-///////////////////////////////////
-// 4. Funktionen, Geltungsbereich und Closures
-
-// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert.
-function myFunction(thing){
- return thing.toUpperCase();
-}
-myFunction("foo"); // = "FOO"
-
-// Vorsicht: der Ausdruck der den Rückgabewert einer Funktion bildet muss
-// auf der selben Zeile beginnen auf der auch das 'return' Keyword steht
-// Sonst wird hier ein automatisches Semikolon eingefügt und die Funktion
-// gibt 'undefined' zurück
-function myFunction()
-{
- return // <- Hier wird automatisch ein Semikolon eingefügt
- {
- thisIsAn: 'object literal'
- }
-}
-myFunction(); // = undefined
-
-// In JavaScript sind Funktionen 'Bürger erster Klasse', also können sie wie
-// Variablen verwendet und als Parameter anderen Funktionen übergeben werden
-// - zum Beispiel, um einen 'event handler' zu 'beliefern'.
-function myFunction() {
- // wird ausgeführt, nachdem 5 Sekunden vergangen sind
-}
-setTimeout(myFunction, 5000);
-
-// Funktionen können auch deklariert werden, ohne ihnen einen Namen zuzuweisen.
-// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument
-// einer anderen Funktion zu definieren.
-setTimeout(function(){
- // wird ausgeführt, nachdem 5 Sekunden vergangen sind
-}, 5000);
-
-// JavaScript hat einen Geltungsbereich, der sich auf Funktionen erstreckt:
-// Funktionen haben ihren eigenen Geltungsbereich, andere Blöcke nicht.
-if(true) {
- var i = 5;
-}
-i; // = 5 - nicht undefined, wie man es von einer Sprache erwarten würde, die
- // ihren Geltungsbereich nach Blöcken richtet
-
-// Daraus ergibt sich ein bestimmtes Muster für sofort-ausführbare, anonyme
-// Funktionen, die es vermeiden, dass der globale Geltungsbereich von Variablen
-// 'verschmutzt' wird.
-(function(){
- var temporary = 5;
- // Auf eine Variable im globalen Geltungsbereich kann zugegriffen werden,
- // sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist
- // dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js,
- // kann das anders aussehen).
- window.permanent = 10;
-})();
-temporary; // wirft einen ReferenceError
-permanent; // = 10
-
-// Eines der mächtigsten Charakteristika von JavaScript sind Closures. Wird
-// eine Funktion innerhalb einer anderen Funktion definiert, dann hat die
-// innere Funktion Zugriff auf alle Variablen der äußeren Funktion, sogar dann,
-// wenn die äußere Funktion beendet wurde.
-function sayHelloInFiveSeconds(name){
- var prompt = "Hello, " + name + "!";
- function inner(){
- alert(prompt);
- }
- setTimeout(inner, 5000);
- // setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds
- // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
- // aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
- // Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
- // Variable prompt.
-}
-sayHelloInFiveSeconds("Adam"); // wird nach 5 Sekunden ein Popup mit der
- // Nachricht "Hello, Adam!" öffnen.
-
-///////////////////////////////////
-// 5. Mehr über Objekte, Konstruktoren und Prototypen
-
-// Objekte können Funktionen enthalten.
-var myObj = {
- myFunc: function(){
- return "Hello world!";
- }
-};
-myObj.myFunc(); // = "Hello world!"
-
-// Wenn Funktionen aufgerufen werden, die zu einem Objekt gehören, können sie
-// auf das eigene Objekt mit dem Schlüsselwort 'this' zugreifen.
-myObj = {
- myString: "Hello world!",
- myFunc: function(){
- return this.myString;
- }
-};
-myObj.myFunc(); // = "Hello world!"
-
-// Worauf 'this' gesetzt wird, ist davon abhängig, wie die Funktion aufgerufen
-// wird, nicht wo sie definiert wurde. Unsere Funktion wird daher nicht
-// funktionieren, sofern sie außerhalb des Kontextes des Objekts aufgerufen
-// wird.
-var myFunc = myObj.myFunc;
-myFunc(); // = undefined
-
-// Umgekehrt ist es möglich eine Funktion einem Objekt zuzuweisen und dadurch
-// Zugriff auf den this-Kontext zu erhalten, sogar dann, wenn die Funktion dem
-// Objekt nach dessen Definition zugewiesen wird.
-var myOtherFunc = function(){
- return this.myString.toUpperCase();
-}
-myObj.myOtherFunc = myOtherFunc;
-myObj.myOtherFunc(); // = "HELLO WORLD!"
-
-// Mit den Methoden 'call' und 'apply' kann der Kontext eines Funktionsaufrufs
-// verändert werden
-
-var anotherFunc = function(s){
- return this.myString + s;
-}
-anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
-
-// 'apply' funktioniert beiahe identisch, erwartet die übergebenen Argumente
-// aber in einem Array
-
-anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
-
-// Das ist hilfreich wenn man einer Funktion eine beliebige Zahl Argumente
-// übergeben kann
-
-Math.min(42, 6, 27); // = 6
-Math.min([42, 6, 27]); // = NaN (uh-oh!)
-Math.min.apply(Math, [42, 6, 27]); // = 6
-
-// 'call' und 'apply' beeinflussen aber nur den spezifischen Aufruf.
-// Um den Kontext einer Funktion dauerhaft zu ändern wird 'bind' benutzt.
-
-var boundFunc = anotherFunc.bind(myObj);
-boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
-
-// Mit 'bind' lassen sich Funktionen auch teilweise anwenden / "curryen".
-var product = function(a, b){ return a * b; }
-var doubler = product.bind(this, 2);
-doubler(8); // = 16
-
-// Wenn eine Funktion mit dem Schlüsselwort 'new' aufgerufen wird, dann wird
-// ein neues Objekt erzeugt. Funktionen, die darauf ausgelegt sind in dieser
-// Art aufgerufen zu werden, werden Konstruktoren genannt.
-var MyConstructor = function(){
- this.myNumber = 5;
-}
-myNewObj = new MyConstructor(); // = {myNumber: 5}
-myNewObj.myNumber; // = 5
-
-// Jedes JavaScript-Objekt hat einen Prototyp. Wenn man versucht auf eine
-// Eigenschaft des Objekts zuzugreifen, das nicht im Objekt selbst existiert,
-// schaut der Interpreter in dessen Prototyp nach.
-
-// Einige JavaScript-Implementierungen erlauben den direkten Zugriff auf den
-// Prototyp eines Objekts durch die magische Eigenschaft __proto__. Obwohl das
-// nützlich ist, um Prototypen im Allgemeinen zu erklären, ist das nicht Teil
-// des Standards; zum Standard-Weg der Nutzung von Prototypen kommen wir
-// später.
-var myObj = {
- myString: "Hello world!",
-};
-var myPrototype = {
- meaningOfLife: 42,
- myFunc: function(){
- return this.myString.toLowerCase()
- }
-};
-myObj.__proto__ = myPrototype;
-myObj.meaningOfLife; // = 42
-
-// Das funktioniert auch bei Funktionen.
-myObj.myFunc(); // = "hello world!"
-
-// Sollte die Eigenschaft nicht im Prototypen des Objekts enthalten sein, dann
-// wird im Prototypen des Prototypen nachgesehen und so weiter.
-myPrototype.__proto__ = {
- myBoolean: true
-};
-myObj.myBoolean; // = true
-
-// Dafür wird nichts hin und her kopiert; jedes Objekt speichert eine Referenz
-// auf seinen Prototypen. Das heißt wenn der Prototyp geändert wird, dann
-// werden die Änderungen überall sichtbar.
-myPrototype.meaningOfLife = 43;
-myObj.meaningOfLife; // = 43
-
-// Es wurde bereits erwähnt, dass __proto__ nicht zum Standard gehört und es
-// gibt ebenso keinen Standard-Weg, um den Prototyp eines existierenden Objekts
-// zu ändern. Es gibt dennoch zwei Wege, wie man ein neues Objekt mit einem
-// gegebenen Prototypen erzeugt.
-
-// Der erste Weg ist die Methode Object.create, die eine jüngere Ergänzung des
-// JavaScript-Standards ist und daher noch nicht in allen Implementierungen
-// verfügbar.
-var myObj = Object.create(myPrototype);
-myObj.meaningOfLife; // = 43
-
-// Der zweite Weg, der immer funktioniert, hat mit den Konstruktoren zu tun.
-// Konstruktoren haben eine Eigenschaft, die Prototyp heißt. Dabei handelt es
-// sich *nicht* um den Prototypen der Konstruktor-Funktion; stattdessen handelt
-// es sich um den Prototypen, der einem neuen Objekt mitgegeben wird, wenn es
-// mit dem Konstruktor und dem Schlüsselwort 'new' erzeugt wird.
-MyConstructor.prototype = {
- getMyNumber: function(){
- return this.myNumber
- }
-};
-var myNewObj2 = new MyConstructor();
-myNewObj2.getMyNumber(); // = 5
-
-// Alle primitiven Typen, also strings und numbers, haben auch Konstruktoren,
-// die zu dem Typ äquivalente Wrapper-Objekte erzeugen.
-var myNumber = 12;
-var myNumberObj = new Number(12);
-myNumber == myNumberObj; // = true
-
-// Genau genommen: Sie sind nicht exakt äquivalent.
-typeof myNumber; // = 'number'
-typeof myNumberObj; // = 'object'
-myNumber === myNumberObj; // = false
-if (0){
- // Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist.
-}
-
-// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen
-// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen
-// hinzuzufügen.
-String.prototype.firstCharacter = function(){
- return this.charAt(0);
-}
-"abc".firstCharacter(); // = "a"
-
-// Diese Tatsache wird häufig bei einer Methode mit dem Namen 'polyfilling'
-// verwendet: Dabei wird ein neues Feature von JavaScript in einer älteren
-// Untermenge der Sprache integriert, so dass bestimmte Funktionen auch in
-// älteren Umgebungen und Browsern verwendet werden können.
-
-// Ein Beispiel: Es wurde erwähnt, dass die Methode Object.create nicht in
-// allen Umgebungen verfügbar ist - wir können sie dennoch verwenden, mit einem
-// 'polyfill':
-if (Object.create === undefined){ // überschreib nichts, was eventuell bereits
- // existiert
- Object.create = function(proto){
- // erstelle einen vorübergehenden Konstruktor mit dem richtigen
- // Prototypen
- var Constructor = function(){};
- Constructor.prototype = proto;
- // verwende es dann, um ein neues Objekt mit einem passenden
- // Prototypen zurückzugeben
- return new Constructor();
- }
-}
-```
-
-## Zur weiteren Lektüre (englisch)
-
-Das [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) bietet eine ausgezeichnete Dokumentation für die Verwendung von JavaScript im Browser. Es ist außerdem ein Wiki und ermöglicht es damit anderen zu helfen, wenn man selbst ein wenig Wissen angesammelt hat.
-
-MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) führt sehr viele der hier vorgestellten Konzepte im Detail aus.
-
-Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den Einsatz in Websites zu lernen, ist es ein guter Start etwas über das [Document Object Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) zu lernen.
-
-[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache.
-
-[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) ist ein Klassiker unter den Referenzen.
-
-Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden.
+--- +language: javascript +contributors: + - ["Leigh Brenecki", "https://leigh.net.au"] +translators: + - ["ggb", "http://www.ideen-und-soehne.de"] +filename: learnjavascript-de.js +lang: de-de +--- + +(Anmerkungen des Original-Autors:) +JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzend zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java. + +Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, das eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer. + +Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@excitedleigh](https://twitter.com/excitedleigh) oder [l@leigh.net.au](mailto:l@leigh.net.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.de). + +```js +// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei +// Slashes +/* während mehrzeilige Kommentare mit einem +Slash und einem Stern anfangen und enden */ + +// Statements können mit einem Semikolon beendet werden +machWas(); + +// ...müssen sie aber nicht, weil Semikola automatisch eingefügt werden, wenn +// eine neue Zeile beginnt, abgesehen von einigen Ausnahmen. +machWas() + +// Obwohl wir uns für den Anfang nicht um diese Ausnahmen kümmern müssen ist +// es besser die Semikola immer zu setzen. + +/////////////////////////////////// +// 1. Nummern, Strings und Operationen + +// JavaScript hat einen Nummern-Typ (64-bit IEEE 754 double). +3; // = 3 +1.5; // = 1.5 + +// Beinahe alle grundlegenden arithmetischen Operationen arbeiten wie erwartet. +1 + 1; // = 2 +0.1 + 0.2; // = 0.30000000000000004 +10 * 2; // = 20 +35 / 5; // = 7 + +// Division funktioniert auch mit einem Ergebnis nach dem Komma. +5 / 2; // = 2.5 + +// Bit-weise Operationen sind auch möglich; wenn eine Bit-weise Operation +// ausgeführt wird, wird die Fließkomma-Zahl in einen 32-bit Integer (mit +// Vorzeichen) umgewandelt. +1 << 2; // = 4 + +// Die Rangfolge der Operationen kann mit Klammern erzwungen werden. +(1 + 3) * 2; // = 8 + +// Es gibt drei spezielle, nicht-reale Nummern-Werte: +Infinity; // Ergebnis von z. B. 1 / 0 +-Infinity; // Ergebnis von z. B. -1 / 0 +NaN; // Ergebnis von z. B. 0 / 0 + +// Es gibt auch einen Boolean-Typ (für Wahrheitswerte). +true; +false; + +// Strings werden mit ' oder " erzeugt. +'abc'; +"Hello, world"; + +// Für die Negation wird das ! benutzt. +!true; // = false +!false; // = true + +// Gleichheit wird mit === geprüft. +1 === 1; // = true +2 === 1; // = false + +// Ungleichheit wird mit !== überprüft. +1 !== 1; // = false +2 !== 1; // = true + +// Andere Vergleichsoperatoren sind +1 < 10; // = true +1 > 10; // = false +2 <= 2; // = true +2 >= 2; // = true + +// Strings können mit + verbunden +"Hello " + "world!"; // = "Hello world!" + +// und mit < und > verglichen werden. +"a" < "b"; // = true + +// Für den Vergleich von Werten mit "==" wird eine Typumwandlung erzwungen... +"5" == 5; // = true + +// ...solange man nicht === verwendet. +"5" === 5; // = false + +// Auf einzelne Buchstaben innerhalb eines Strings kann mit der Methode +// 'charAt' zugegriffen werden +"This is a string".charAt(0); // = "T" + +// Die Methode 'substring' gibt Teilbereiche eines Strings zurück +"Hello world".substring(0, 5); // = "Hello" + +// 'length' ist eine Eigenschaft und wird folglich ohne '()' benutzt +"Hello".length; // = 5 + +// Es gibt außerdem die Werte 'null' und 'undefined' +null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen +undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht + // verfügbar ist (obwohl genau genommen undefined selbst einen Wert + // darstellt) + +// false, null, undefined, NaN, 0 und "" sind 'falsy', d. h. alles andere ist +// wahr. Man beachte, dass 0 falsch und "0" wahr ist, obwohl 0 == "0". + +/////////////////////////////////// +// 2. Variablen, Arrays und Objekte + +// Variablen werden mit dem Schlüsselwort 'var' und einem frei wählbaren +// Bezeichner deklariert. JavaScript ist dynamisch typisiert, so dass man einer +// Variable keinen Typ zuweisen muss. Die Zuweisung verwendet ein einfaches =. +var einWert = 5; + + // Wenn man das Schlüsselwort 'var' weglässt, bekommt man keinen Fehler +einAndererWert = 10; + +// ...aber die Variable wird im globalen Kontext erzeugt, nicht in dem Kontext, +// in dem sie erzeugt wurde. + +// Variablen die erzeugt wurden ohne ihnen einen Wert zuzuweisen, erhalten den +// Wert 'undefined'. +var einDritterWert; // = undefined + +// Es existiert eine Kurzform, um mathematische Operationen mit Variablen +// auszuführen: +einWert += 5; // äquivalent zu einWert = einWert + 5; einWert ist nun also 10 +einWert *= 10; // einWert ist nach dieser Operation 100 + +// Und es existiert eine weitere, sogar noch kürzere Form, um 1 zu addieren +// oder zu subtrahieren +einWert++; // nun ist einWert 101 +einWert--; // wieder 100 + +// Arrays sind geordnete Listen von Werten irgendeines Typs +var myArray = ["Hello", 45, true]; + +// Auf einzelne Elemente eines Arrays kann zugegriffen werden, in dem der Index +// in eckigen Klammern hinter das Array geschrieben werden. Die Indexierung +// beginnt bei 0. +myArray[1]; // = 45 + +// Arrays haben keine feste Länge +myArray.push("World"); +myArray.length; // = 4 + +// und sind veränderlich +myArray[3] = "Hello"; + +// Die Objekte in JavaScript entsprechen 'dictionaries' oder 'maps' in anderen +// Sprachen: es handelt sich um ungeordnete Schlüssel-Wert-Paare. +var myObj = { key1: "Hello", key2: "World" }; + +// Schlüssel sind Strings, aber es werden keine Anführungszeichen benötigt, +// sofern es sich um reguläre JavaScript-Bezeichner handelt. Werte können von +// jedem Typ sein. +var myObj = { myKey: "myValue", "my other key": 4 }; + +// Auf Attribute von Objekten kann ebenfalls mit eckigen Klammern zugegriffen +// werden, +myObj["my other key"]; // = 4 + +// ... oder in dem man die Punkt-Notation verwendet, vorausgesetzt es handelt +// sich bei dem Schlüssel um einen validen Bezeichner. +myObj.myKey; // = "myValue" + +// Objekte sind veränderlich, Werte können verändert und neue Schlüssel +// hinzugefügt werden. +myObj.myThirdKey = true; + +// Der Zugriff auf einen noch nicht definierten Schlüssel, liefert ein +// undefined. +myObj.myFourthKey; // = undefined + +/////////////////////////////////// +// 3. Logik und Kontrollstrukturen + +// Die if-Struktur arbeitet, wie man es erwartet. +var count = 1; +if (count == 3){ + // wird evaluiert, wenn count gleich 3 ist +} else if (count == 4) { + // wird evaluiert, wenn count gleich 4 ist +} else { + // wird evaluiert, wenn es weder 3 noch 4 ist +} + +// Genauso 'while'. +while (true) { + // Eine unendliche Schleife! +} + +// Do-while-Scheifen arbeiten wie while-Schleifen, abgesehen davon, dass sie +// immer mindestens einmal ausgeführt werden. +var input; +do { + input = getInput(); +} while ( !isValid( input ) ) + +// Die for-Schleife arbeitet genau wie in C und Java: +// Initialisierung; Bedingung, unter der die Ausführung fortgesetzt wird; +// Iteration. +for ( var i = 0; i < 5; i++ ) { + // wird 5-mal ausgeführt +} + +// '&&' ist das logische und, '||' ist das logische oder +if (house.size == "big" && house.colour == "blue"){ + house.contains = "bear"; + // Die Größe des Hauses ist groß und die Farbe blau. +} +if (colour == "red" || colour == "blue"){ + // Die Farbe ist entweder rot oder blau. +} + +// Die Auswertung von '&&' und '||' erfolgt so, dass abgebrochen wird, wenn die +// Bedingung erfüllt ist (bei oder) oder nicht-erfüllt ist (bei und). Das ist +// nützlich, um einen Default-Wert zu setzen. +var name = otherName || "default"; + +// Ein 'switch' Statement prüft Gleichheit mit === +// ohne ein 'break' nach jedem Fall +// werden auch die Fälle nach dem korrekten aufgerufen +grade = 'B'; +switch (grade) { + case 'A': + console.log("Great job"); + break; + case 'B': + console.log("OK job"); + break; + case 'C': + console.log("You can do better"); + break; + default: + console.log("Oy vey"); + break; +} + +/////////////////////////////////// +// 4. Funktionen, Geltungsbereich und Closures + +// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert. +function myFunction(thing){ + return thing.toUpperCase(); +} +myFunction("foo"); // = "FOO" + +// Vorsicht: der Ausdruck der den Rückgabewert einer Funktion bildet muss +// auf der selben Zeile beginnen auf der auch das 'return' Keyword steht +// Sonst wird hier ein automatisches Semikolon eingefügt und die Funktion +// gibt 'undefined' zurück +function myFunction() +{ + return // <- Hier wird automatisch ein Semikolon eingefügt + { + thisIsAn: 'object literal' + } +} +myFunction(); // = undefined + +// In JavaScript sind Funktionen 'Bürger erster Klasse', also können sie wie +// Variablen verwendet und als Parameter anderen Funktionen übergeben werden +// - zum Beispiel, um einen 'event handler' zu 'beliefern'. +function myFunction() { + // wird ausgeführt, nachdem 5 Sekunden vergangen sind +} +setTimeout(myFunction, 5000); + +// Funktionen können auch deklariert werden, ohne ihnen einen Namen zuzuweisen. +// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument +// einer anderen Funktion zu definieren. +setTimeout(function(){ + // wird ausgeführt, nachdem 5 Sekunden vergangen sind +}, 5000); + +// JavaScript hat einen Geltungsbereich, der sich auf Funktionen erstreckt: +// Funktionen haben ihren eigenen Geltungsbereich, andere Blöcke nicht. +if(true) { + var i = 5; +} +i; // = 5 - nicht undefined, wie man es von einer Sprache erwarten würde, die + // ihren Geltungsbereich nach Blöcken richtet + +// Daraus ergibt sich ein bestimmtes Muster für sofort-ausführbare, anonyme +// Funktionen, die es vermeiden, dass der globale Geltungsbereich von Variablen +// 'verschmutzt' wird. +(function(){ + var temporary = 5; + // Auf eine Variable im globalen Geltungsbereich kann zugegriffen werden, + // sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist + // dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js, + // kann das anders aussehen). + window.permanent = 10; +})(); +temporary; // wirft einen ReferenceError +permanent; // = 10 + +// Eines der mächtigsten Charakteristika von JavaScript sind Closures. Wird +// eine Funktion innerhalb einer anderen Funktion definiert, dann hat die +// innere Funktion Zugriff auf alle Variablen der äußeren Funktion, sogar dann, +// wenn die äußere Funktion beendet wurde. +function sayHelloInFiveSeconds(name){ + var prompt = "Hello, " + name + "!"; + function inner(){ + alert(prompt); + } + setTimeout(inner, 5000); + // setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds + // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein' + // aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere + // Funktion bildet, hat die innere Funktion immer noch Zugriff auf die + // Variable prompt. +} +sayHelloInFiveSeconds("Adam"); // wird nach 5 Sekunden ein Popup mit der + // Nachricht "Hello, Adam!" öffnen. + +/////////////////////////////////// +// 5. Mehr über Objekte, Konstruktoren und Prototypen + +// Objekte können Funktionen enthalten. +var myObj = { + myFunc: function(){ + return "Hello world!"; + } +}; +myObj.myFunc(); // = "Hello world!" + +// Wenn Funktionen aufgerufen werden, die zu einem Objekt gehören, können sie +// auf das eigene Objekt mit dem Schlüsselwort 'this' zugreifen. +myObj = { + myString: "Hello world!", + myFunc: function(){ + return this.myString; + } +}; +myObj.myFunc(); // = "Hello world!" + +// Worauf 'this' gesetzt wird, ist davon abhängig, wie die Funktion aufgerufen +// wird, nicht wo sie definiert wurde. Unsere Funktion wird daher nicht +// funktionieren, sofern sie außerhalb des Kontextes des Objekts aufgerufen +// wird. +var myFunc = myObj.myFunc; +myFunc(); // = undefined + +// Umgekehrt ist es möglich eine Funktion einem Objekt zuzuweisen und dadurch +// Zugriff auf den this-Kontext zu erhalten, sogar dann, wenn die Funktion dem +// Objekt nach dessen Definition zugewiesen wird. +var myOtherFunc = function(){ + return this.myString.toUpperCase(); +} +myObj.myOtherFunc = myOtherFunc; +myObj.myOtherFunc(); // = "HELLO WORLD!" + +// Mit den Methoden 'call' und 'apply' kann der Kontext eines Funktionsaufrufs +// verändert werden + +var anotherFunc = function(s){ + return this.myString + s; +} +anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!" + +// 'apply' funktioniert beiahe identisch, erwartet die übergebenen Argumente +// aber in einem Array + +anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!" + +// Das ist hilfreich wenn man einer Funktion eine beliebige Zahl Argumente +// übergeben kann + +Math.min(42, 6, 27); // = 6 +Math.min([42, 6, 27]); // = NaN (uh-oh!) +Math.min.apply(Math, [42, 6, 27]); // = 6 + +// 'call' und 'apply' beeinflussen aber nur den spezifischen Aufruf. +// Um den Kontext einer Funktion dauerhaft zu ändern wird 'bind' benutzt. + +var boundFunc = anotherFunc.bind(myObj); +boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!" + +// Mit 'bind' lassen sich Funktionen auch teilweise anwenden / "curryen". +var product = function(a, b){ return a * b; } +var doubler = product.bind(this, 2); +doubler(8); // = 16 + +// Wenn eine Funktion mit dem Schlüsselwort 'new' aufgerufen wird, dann wird +// ein neues Objekt erzeugt. Funktionen, die darauf ausgelegt sind in dieser +// Art aufgerufen zu werden, werden Konstruktoren genannt. +var MyConstructor = function(){ + this.myNumber = 5; +} +myNewObj = new MyConstructor(); // = {myNumber: 5} +myNewObj.myNumber; // = 5 + +// Jedes JavaScript-Objekt hat einen Prototyp. Wenn man versucht auf eine +// Eigenschaft des Objekts zuzugreifen, das nicht im Objekt selbst existiert, +// schaut der Interpreter in dessen Prototyp nach. + +// Einige JavaScript-Implementierungen erlauben den direkten Zugriff auf den +// Prototyp eines Objekts durch die magische Eigenschaft __proto__. Obwohl das +// nützlich ist, um Prototypen im Allgemeinen zu erklären, ist das nicht Teil +// des Standards; zum Standard-Weg der Nutzung von Prototypen kommen wir +// später. +var myObj = { + myString: "Hello world!", +}; +var myPrototype = { + meaningOfLife: 42, + myFunc: function(){ + return this.myString.toLowerCase() + } +}; +myObj.__proto__ = myPrototype; +myObj.meaningOfLife; // = 42 + +// Das funktioniert auch bei Funktionen. +myObj.myFunc(); // = "hello world!" + +// Sollte die Eigenschaft nicht im Prototypen des Objekts enthalten sein, dann +// wird im Prototypen des Prototypen nachgesehen und so weiter. +myPrototype.__proto__ = { + myBoolean: true +}; +myObj.myBoolean; // = true + +// Dafür wird nichts hin und her kopiert; jedes Objekt speichert eine Referenz +// auf seinen Prototypen. Das heißt wenn der Prototyp geändert wird, dann +// werden die Änderungen überall sichtbar. +myPrototype.meaningOfLife = 43; +myObj.meaningOfLife; // = 43 + +// Es wurde bereits erwähnt, dass __proto__ nicht zum Standard gehört und es +// gibt ebenso keinen Standard-Weg, um den Prototyp eines existierenden Objekts +// zu ändern. Es gibt dennoch zwei Wege, wie man ein neues Objekt mit einem +// gegebenen Prototypen erzeugt. + +// Der erste Weg ist die Methode Object.create, die eine jüngere Ergänzung des +// JavaScript-Standards ist und daher noch nicht in allen Implementierungen +// verfügbar. +var myObj = Object.create(myPrototype); +myObj.meaningOfLife; // = 43 + +// Der zweite Weg, der immer funktioniert, hat mit den Konstruktoren zu tun. +// Konstruktoren haben eine Eigenschaft, die Prototyp heißt. Dabei handelt es +// sich *nicht* um den Prototypen der Konstruktor-Funktion; stattdessen handelt +// es sich um den Prototypen, der einem neuen Objekt mitgegeben wird, wenn es +// mit dem Konstruktor und dem Schlüsselwort 'new' erzeugt wird. +MyConstructor.prototype = { + getMyNumber: function(){ + return this.myNumber + } +}; +var myNewObj2 = new MyConstructor(); +myNewObj2.getMyNumber(); // = 5 + +// Alle primitiven Typen, also strings und numbers, haben auch Konstruktoren, +// die zu dem Typ äquivalente Wrapper-Objekte erzeugen. +var myNumber = 12; +var myNumberObj = new Number(12); +myNumber == myNumberObj; // = true + +// Genau genommen: Sie sind nicht exakt äquivalent. +typeof myNumber; // = 'number' +typeof myNumberObj; // = 'object' +myNumber === myNumberObj; // = false +if (0){ + // Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist. +} + +// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen +// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen +// hinzuzufügen. +String.prototype.firstCharacter = function(){ + return this.charAt(0); +} +"abc".firstCharacter(); // = "a" + +// Diese Tatsache wird häufig bei einer Methode mit dem Namen 'polyfilling' +// verwendet: Dabei wird ein neues Feature von JavaScript in einer älteren +// Untermenge der Sprache integriert, so dass bestimmte Funktionen auch in +// älteren Umgebungen und Browsern verwendet werden können. + +// Ein Beispiel: Es wurde erwähnt, dass die Methode Object.create nicht in +// allen Umgebungen verfügbar ist - wir können sie dennoch verwenden, mit einem +// 'polyfill': +if (Object.create === undefined){ // überschreib nichts, was eventuell bereits + // existiert + Object.create = function(proto){ + // erstelle einen vorübergehenden Konstruktor mit dem richtigen + // Prototypen + var Constructor = function(){}; + Constructor.prototype = proto; + // verwende es dann, um ein neues Objekt mit einem passenden + // Prototypen zurückzugeben + return new Constructor(); + } +} +``` + +## Zur weiteren Lektüre (englisch) + +Das [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) bietet eine ausgezeichnete Dokumentation für die Verwendung von JavaScript im Browser. Es ist außerdem ein Wiki und ermöglicht es damit anderen zu helfen, wenn man selbst ein wenig Wissen angesammelt hat. + +MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) führt sehr viele der hier vorgestellten Konzepte im Detail aus. + +Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den Einsatz in Websites zu lernen, ist es ein guter Start etwas über das [Document Object Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) zu lernen. + +[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache. + +[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) ist ein Klassiker unter den Referenzen. + +Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden. diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown index 1bae332c..3674f2f5 100644 --- a/de-de/make-de.html.markdown +++ b/de-de/make-de.html.markdown @@ -1,263 +1,263 @@ ----
-category: tool
-tool: make
-contributors:
- - ["Robert Steed", "https://github.com/robochat"]
- - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
-translators:
- - ["Martin Schimandl", "https://github.com/Git-Jiro"]
-filename: Makefile-de
-lang: de-de
----
-
-Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele)
-zu erzeugen. Es dient dazu, die geringste Menge an Arbeit zu verrichten um
-ein Ziel in Einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
-von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
-sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel
-Konkurrenz und Kritik zu Make gibt.
-
-Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich
-mit der Version GNU Make. Diese Version ist Standard auf Linux.
-
-```make
-
-# Kommentare können so geschrieben werden.
-
-# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
-# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
-# werden.
-
-# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
-# werden. Niemals Leerzeichen!
-
-#-----------------------------------------------------------------------
-# Grundlagen
-#-----------------------------------------------------------------------
-
-# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt
-# nicht existiert.
-file0.txt:
- echo "foo" > file0.txt
- # Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
- # weitergegeben. Versuche `make file0.txt` oder einfach `make`
- # die erste Regel ist die Standard-Regel.
-
-
-# Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist.
-file1.txt: file0.txt
- cat file0.txt > file1.txt
- # Verwende die selben Quoting-Regeln wie die Shell
- @cat file0.txt >> file1.txt
- # @ unterdrückt die Ausgabe des Befehls an stdout.
- -@echo 'hello'
- # - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler
- # passieren.
- # Versuche `make file1.txt` auf der Kommandozeile.
-
-# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
-file2.txt file3.txt: file0.txt file1.txt
- touch file2.txt
- touch file3.txt
-
-# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt.
-# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
-# Voraussetzungen hinzuzufügen.
-
-#-----------------------------------------------------------------------
-# Phony-Ziele
-#-----------------------------------------------------------------------
-
-# Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
-# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
-all: maker process
-
-# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
-maker:
- touch ex0.txt ex1.txt
-
-# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
-# selben namen wie ein Phony-Ziel hat:
-.PHONY: all maker process
-# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
-
-# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
-ex0.txt ex1.txt: maker
-
-# Häufige Phony-Ziele sind: all make clean install ...
-
-#-----------------------------------------------------------------------
-# Automatische Variablen & Wildcards
-#-----------------------------------------------------------------------
-
-process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen
- @echo $^ # $^ ist eine Variable die eine Liste aller
- # Voraussetzungen enthält.
- @echo $@ # Namen des Ziels ausgeben.
- #(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
- #der Regel.)
- @echo $< # Die erste Voraussetzung aus der Liste
- @echo $? # Nur die Voraussetzungen, die nicht aktuell sind.
- @echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
- #@echo $| # Alle 'order only' Voraussetzungen
-
-# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
-process: ex1.txt file0.txt
-# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
-
-#-----------------------------------------------------------------------
-# Muster
-#-----------------------------------------------------------------------
-
-# Mit Mustern kann man make beibringen wie Dateien in andere Dateien
-# umgewandelt werden.
-
-%.png: %.svg
- inkscape --export-png $^
-
-# Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das
-# Ziel zu erzeugen
-
-# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
-# Aber make wird versuchen die am besten passende Regel zu verwenden.
-small/%.png: %.svg
- inkscape --export-png --export-dpi 30 $^
-
-# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es
-# findet.
-%.png: %.svg
- @echo this rule is chosen
-
-# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das
-# Ziel erzeugen kann.
-%.png: %.ps
- @echo this rule is not chosen if *.svg and *.ps are both present
-
-# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel
-# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
-
-# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
-# Muster-Vergleichs-Regeln.
-.png.ps:
- @echo this rule is similar to a pattern rule.
-
-# Aktivieren der Suffix-Regel
-.SUFFIXES: .png
-
-#-----------------------------------------------------------------------
-# Variablen
-#-----------------------------------------------------------------------
-# auch Makros genannt.
-
-# Variablen sind im Grunde genommen Zeichenketten-Typen.
-
-name = Ted
-name2="Sarah"
-
-echo:
- @echo $(name)
- @echo ${name2}
- @echo $name # Das funktioniert nicht, wird als $(n)ame behandelt.
- @echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
-
-# Es git 4 Stellen um Variablen zu setzen.
-# In Reihenfolge der Priorität von höchster zu niedrigster:
-# 1: Befehls-Zeilen Argumente
-# 2: Makefile
-# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch.
-# 3: MAke hat einige vordefinierte Variablen.
-
-name4 ?= Jean
-# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
-# nicht gibt.
-
-override name5 = David
-# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
-
-name4 +=grey
-# Werte an eine Variable anhängen (inkludiert Leerzeichen).
-
-# Muster-Spezifische Variablen Werte (GNU Erweiterung).
-echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
- # rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
- # kann, wenn es zu kompilizert wird!)
-
-# Ein paar Variablen, die von Make automatisch definiert werden.
-echo_inbuilt:
- echo $(CC)
- echo ${CXX}
- echo $(FC)
- echo ${CFLAGS}
- echo $(CPPFLAGS)
- echo ${CXXFLAGS}
- echo $(LDFLAGS)
- echo ${LDLIBS}
-
-#-----------------------------------------------------------------------
-# Variablen 2
-#-----------------------------------------------------------------------
-
-# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet.
-# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
-# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
-
-var := hello
-var2 ::= $(var) hello
-#:= und ::= sind äquivalent.
-
-# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie
-# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache!
-
-# Das funktioniert nicht
-var3 ::= $(var4) and good luck
-var4 ::= good night
-
-#-----------------------------------------------------------------------
-# Funktionen
-#-----------------------------------------------------------------------
-
-# Make verfügt über eine Vielzahl von Funktionen.
-
-sourcefiles = $(wildcard *.c */*.c)
-objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
-
-# Das Format ist $(func arg0,arg1,arg2...)
-
-# Ein paar Beispiele
-ls: * src/*
- @echo $(filter %.txt, $^)
- @echo $(notdir $^)
- @echo $(join $(dir $^),$(notdir $^))
-
-#-----------------------------------------------------------------------
-# Direktiven
-#-----------------------------------------------------------------------
-
-# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code
-include foo.mk
-
-sport = tennis
-# Konditionale kompiliereung
-report:
-ifeq ($(sport),tennis)
- @echo 'game, set, match'
-else
- @echo "They think it's all over; it is now"
-endif
-
-# Es gibt auch ifneq, ifdef, ifndef
-
-foo = true
-
-ifdef $(foo)
-bar = 'hello'
-endif
-```
-
-
-### Mehr Resourcen
-
-+ [gnu make documentation](https://www.gnu.org/software/make/manual/)
-+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
-+ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
-
+--- +category: tool +tool: make +contributors: + - ["Robert Steed", "https://github.com/robochat"] + - ["Stephan Fuhrmann", "https://github.com/sfuhrm"] +translators: + - ["Martin Schimandl", "https://github.com/Git-Jiro"] +filename: Makefile-de +lang: de-de +--- + +Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele) +zu erzeugen. Es dient dazu, die geringste Menge an Arbeit zu verrichten um +ein Ziel in Einklang mit dem Quellcode zu bringen. Make wurde berühmterweise +von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer +sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel +Konkurrenz und Kritik zu Make gibt. + +Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich +mit der Version GNU Make. Diese Version ist Standard auf Linux. + +```make + +# Kommentare können so geschrieben werden. + +# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>` +# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet +# werden. + +# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet +# werden. Niemals Leerzeichen! + +#----------------------------------------------------------------------- +# Grundlagen +#----------------------------------------------------------------------- + +# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt +# nicht existiert. +file0.txt: + echo "foo" > file0.txt + # Selbst Kommentare in der 'Rezept' Sektion werden an die Shell + # weitergegeben. Versuche `make file0.txt` oder einfach `make` + # die erste Regel ist die Standard-Regel. + + +# Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist. +file1.txt: file0.txt + cat file0.txt > file1.txt + # Verwende die selben Quoting-Regeln wie die Shell + @cat file0.txt >> file1.txt + # @ unterdrückt die Ausgabe des Befehls an stdout. + -@echo 'hello' + # - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler + # passieren. + # Versuche `make file1.txt` auf der Kommandozeile. + +# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben. +file2.txt file3.txt: file0.txt file1.txt + touch file2.txt + touch file3.txt + +# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt. +# Leere Rezepte zählen nicht und können dazu verwendet werden weitere +# Voraussetzungen hinzuzufügen. + +#----------------------------------------------------------------------- +# Phony-Ziele +#----------------------------------------------------------------------- + +# Ein Phony-Ziel ist ein Ziel, das keine Datei ist. +# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten +all: maker process + +# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren. +maker: + touch ex0.txt ex1.txt + +# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den +# selben namen wie ein Phony-Ziel hat: +.PHONY: all maker process +# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon. + +# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet +ex0.txt ex1.txt: maker + +# Häufige Phony-Ziele sind: all make clean install ... + +#----------------------------------------------------------------------- +# Automatische Variablen & Wildcards +#----------------------------------------------------------------------- + +process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen + @echo $^ # $^ ist eine Variable die eine Liste aller + # Voraussetzungen enthält. + @echo $@ # Namen des Ziels ausgeben. + #(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung + #der Regel.) + @echo $< # Die erste Voraussetzung aus der Liste + @echo $? # Nur die Voraussetzungen, die nicht aktuell sind. + @echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich) + #@echo $| # Alle 'order only' Voraussetzungen + +# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden. +process: ex1.txt file0.txt +# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert. + +#----------------------------------------------------------------------- +# Muster +#----------------------------------------------------------------------- + +# Mit Mustern kann man make beibringen wie Dateien in andere Dateien +# umgewandelt werden. + +%.png: %.svg + inkscape --export-png $^ + +# Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das +# Ziel zu erzeugen + +# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert. +# Aber make wird versuchen die am besten passende Regel zu verwenden. +small/%.png: %.svg + inkscape --export-png --export-dpi 30 $^ + +# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es +# findet. +%.png: %.svg + @echo this rule is chosen + +# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das +# Ziel erzeugen kann. +%.png: %.ps + @echo this rule is not chosen if *.svg and *.ps are both present + +# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel +# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt. + +# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt +# Muster-Vergleichs-Regeln. +.png.ps: + @echo this rule is similar to a pattern rule. + +# Aktivieren der Suffix-Regel +.SUFFIXES: .png + +#----------------------------------------------------------------------- +# Variablen +#----------------------------------------------------------------------- +# auch Makros genannt. + +# Variablen sind im Grunde genommen Zeichenketten-Typen. + +name = Ted +name2="Sarah" + +echo: + @echo $(name) + @echo ${name2} + @echo $name # Das funktioniert nicht, wird als $(n)ame behandelt. + @echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt. + +# Es git 4 Stellen um Variablen zu setzen. +# In Reihenfolge der Priorität von höchster zu niedrigster: +# 1: Befehls-Zeilen Argumente +# 2: Makefile +# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch. +# 3: MAke hat einige vordefinierte Variablen. + +name4 ?= Jean +# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch +# nicht gibt. + +override name5 = David +# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können. + +name4 +=grey +# Werte an eine Variable anhängen (inkludiert Leerzeichen). + +# Muster-Spezifische Variablen Werte (GNU Erweiterung). +echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb + # rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören + # kann, wenn es zu kompilizert wird!) + +# Ein paar Variablen, die von Make automatisch definiert werden. +echo_inbuilt: + echo $(CC) + echo ${CXX} + echo $(FC) + echo ${CFLAGS} + echo $(CPPFLAGS) + echo ${CXXFLAGS} + echo $(LDFLAGS) + echo ${LDLIBS} + +#----------------------------------------------------------------------- +# Variablen 2 +#----------------------------------------------------------------------- + +# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet. +# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen. +# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung) + +var := hello +var2 ::= $(var) hello +#:= und ::= sind äquivalent. + +# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie +# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache! + +# Das funktioniert nicht +var3 ::= $(var4) and good luck +var4 ::= good night + +#----------------------------------------------------------------------- +# Funktionen +#----------------------------------------------------------------------- + +# Make verfügt über eine Vielzahl von Funktionen. + +sourcefiles = $(wildcard *.c */*.c) +objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) + +# Das Format ist $(func arg0,arg1,arg2...) + +# Ein paar Beispiele +ls: * src/* + @echo $(filter %.txt, $^) + @echo $(notdir $^) + @echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Direktiven +#----------------------------------------------------------------------- + +# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code +include foo.mk + +sport = tennis +# Konditionale kompiliereung +report: +ifeq ($(sport),tennis) + @echo 'game, set, match' +else + @echo "They think it's all over; it is now" +endif + +# Es gibt auch ifneq, ifdef, ifndef + +foo = true + +ifdef $(foo) +bar = 'hello' +endif +``` + + +### Mehr Resourcen + ++ [gnu make documentation](https://www.gnu.org/software/make/manual/) ++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) ++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) + diff --git a/de-de/nix-de.html.markdown b/de-de/nix-de.html.markdown index ffe8dffc..a55a91c7 100644 --- a/de-de/nix-de.html.markdown +++ b/de-de/nix-de.html.markdown @@ -356,6 +356,9 @@ with builtins; [ * [Susan Potter - Nix Cookbook - Nix By Example] (https://ops.functionalalgebra.com/nix-by-example/) - + +* [Zero to Nix - Nix Tutorial] + (https://zero-to-nix.com/) + * [Rommel Martinez - A Gentle Introduction to the Nix Family] (https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix) diff --git a/de-de/pug-de.html.markdown b/de-de/pug-de.html.markdown index c86494ce..ce31c648 100644 --- a/de-de/pug-de.html.markdown +++ b/de-de/pug-de.html.markdown @@ -162,13 +162,13 @@ case bestellungsStatus //- <p class="warn">Deine Bestellung steht noch aus</p> //- --INCLUDE-- -//- File path -> "includes/nav.png" +//- File path -> "includes/nav.pug" h1 Firmenname nav a(href="index.html") Home a(href="about.html") Über uns -//- Dateipfad -> "index.png" +//- Dateipfad -> "index.pug" html body include includes/nav.pug @@ -205,4 +205,4 @@ mixin comment(name, kommentar) ### Zusätzliche Ressourcen - [The Site](https://pugjs.org/) - [The Docs](https://pugjs.org/api/getting-started.html) -- [Github Repo](https://github.com/pugjs/pug) +- [GitHub Repo](https://github.com/pugjs/pug) diff --git a/de-de/pyqt-de.html.markdown b/de-de/pyqt-de.html.markdown index 93ee20d4..3b9b6ebb 100644 --- a/de-de/pyqt-de.html.markdown +++ b/de-de/pyqt-de.html.markdown @@ -21,7 +21,7 @@ Diese Version wurde in pyqt erstellt. ```python import sys from PyQt4 import QtGui - + def window(): # Erschafft ein Anwendungsobjekt. app = QtGui.QApplication(sys.argv) @@ -48,10 +48,10 @@ if __name__ == '__main__': Damit wir weitere fortgeschrittene Funktionen in **pyqt** verwenden können, müssen wir anfangen zusätzliche Elemente zu bauen. -Hier zeigen wir wie man eine Dialog Popup Box einführt. +Hier zeigen wir wie man eine Dialog Popup Box einführt. Diese ist nützlich, um den Benutzer eine Entscheidung zu bestätigen oder um Informationen anzuzeigen. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -70,7 +70,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Diese Funktion soll ein Dialogfenster mit einem Knopf erschaffen. # Der Knopf wartet bis er geklickt wird und beendet das Programm def showdialog(): diff --git a/de-de/rst-de.html.markdown b/de-de/rst-de.html.markdown index 072299f5..0eb2b6bf 100644 --- a/de-de/rst-de.html.markdown +++ b/de-de/rst-de.html.markdown @@ -86,14 +86,14 @@ erstellt werden, aber ich empfehle dir dafür die komplette Dokumentation zu les Es gibt mehrere Möglichkeiten um Links zu machen: -- Wenn man einen Unterstrich hinter einem Wort hinzufügt: Github_ Zusätzlich +- Wenn man einen Unterstrich hinter einem Wort hinzufügt: GitHub_ Zusätzlich muss man die Zielurl nach dem Text hinzufügen. (Dies hat den Vorteil, dass man keine unnötigen Urls in lesbaren Text einfügt. - Wenn man die vollständige Url eingibt : https://github.com/ (Dies wird automatisch in ein Link konvertiert.) -- Wenn man es mehr Markdown ähnlich eingibt: `Github <https://github.com/>`_ . +- Wenn man es mehr Markdown ähnlich eingibt: `GitHub <https://github.com/>`_ . -.. _Github https://github.com/ +.. _GitHub https://github.com/ ``` diff --git a/de-de/sql-de.html.markdown b/de-de/sql-de.html.markdown new file mode 100644 index 00000000..9cb95666 --- /dev/null +++ b/de-de/sql-de.html.markdown @@ -0,0 +1,116 @@ +--- +language: SQL +filename: learnsql-de.sql +contributors: + - ["Bob DuCharme", "http://bobdc.com/"] +translators: + - ["denniskeller", "https://github.com/denniskeller"] +lang: de-de +--- + +Die Structured Query Language (SQL) ist eine ISO Standardsprache zum Erstellen und Arbeiten mit Datenbanken, die in einem Set von Tabellen gespeichert sind. Implementiereungen fügen in der Regel eigene Erweiterungen zur Sprache hinzu; [Der Vergleich von verschiedenen SQL Implementierungen](http://troels.arvin.dk/db/rdbms/) ist eine gute Referenz für Produktunterschiede. + +Implementierungen bieten typischerweise eine Eingabeaufforderung, in den du die hier gezeigten Befehle interaktiv eingeben kannst. Sie bieten auch einen Weg, um Serien von Befehlen in einer Skript auszuführen. (Die Anzeige, dass du fertig mit der interaktiven Eingabeaufforderung bist, ist ein gutes Beispiel für etwas, was nicht standardisiert ist. Die meisten SQL Implementierungen unterstützen die Schlüsselwörter QUIT, EXIT oder beides. +Einige dieser Beispielbefehle gehen davon aus, dass sie die [MySQL employee sample database](https://dev.mysql.com/doc/employee/en/), verfügbar auf [github](https://github.com/datacharmer/test_db), schon geladen wurde. Die Github Dateien sind Skripte von Befehlen, ähnlich wie die entsprechenden Befehle unten, die Tabellen mit Daten über die Mitarbeiter einer fiktionale Firma erstellen und füllen. Die Syntax für die Ausführung dieser Skripte hängt von der verwendeten SQL-Implementierung ab. Ein Dienstprogramm, das man über die Betriebssystemeingabeaufforderung ausführen kann, ist typisch. + + +```sql +-- Kommentare starten mit zwei Bindestrichen. Jeder Befehl endet mit einem Semikolon. + +-- SQL unterscheidet nicht zwischen Groß- und Kleinschreibung bei +-- Schlüsselwörtern. Die Beispielbefehle folgen der Konvention der +-- Schreibweise in Großbuchstaben, damit sie leichter von Datebank-, +-- Tabellen- und Spaltennamen zu unterscheiden sind. + +-- Erstellen und Löschen einer Datenbank. Bei Datenbank- und Tabellennamen +-- wird zwischen Groß- und Kleinschreibung unterschieden. +CREATE DATABASE someDatabase; +DROP DATABASE someDatabase; + +-- Liste verfügbare Datenbanken. +SHOW DATABASES; + +-- Verwende eine bestimmte Datenbank. +USE employees; + +-- Wähle alle Zeilen und Spalten aus der Tabelle departmens aus der aktuellen +-- Datenbank aus. +-- Das Standardverhalten für den Interpreter ist die Ergebnisse auf +-- dem Bildschirm zu scrollen. +SELECT * FROM departments; + +-- Hole dir alle Zeilen aus der departments Tabelle, +-- aber nur die dept_no und die dept_name Spalten. +-- Das Aufteilen von Befehlen auf mehrere Zeilen ist in Ordnung. +SELECT dept_no, + dept_name FROM departments; + +-- Hole dir alle departments Spalten, aber nur 5 Zeilen. +SELECT * FROM departments LIMIT 5; + +-- Hole dir die dept_name Spaltenwerte aus der departments Tabelle, +-- in der der Wert dept_name die Teilzeichenfolge 'en' hat. +SELECT dept_name FROM departments WHERE dept_name LIKE '%en%'; + +-- Hole dir alle Spalten von der departments Tabelle, in der die dept_name +-- Spalte mit einem 'S' beginnt und exakt 4 Zeichen danach besitzt. +SELECT * FROM departments WHERE dept_name LIKE 'S____'; + +-- Wähle die Titelwerte aus der Titeltabelle, aber zeige keine Duplikate an. +SELECT DISTINCT title FROM titles; + +-- Das Gleiche wie oben, aber sortiert nach den Titelwerten, mit Beachtung +-- der Groß und Kleinschreibung. +SELECT DISTINCT title FROM titles ORDER BY title; + +-- Zeige die Anzahl der Zeilen in der departments Tabelle an. +SELECT COUNT(*) FROM departments; + +-- Zeige die Anzahl der Zeilen in der departments Tabelle an, die 'en' als +-- Teilezeichenkette des Wertes dept_name haben. +SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%'; + +-- Eine Vereinigung von Informatione von mehreren Tabellen: +-- Die titles Tabelle zeigt, wer welche Jobtitel hatte, wer welche Mitarbeiter- +-- nummer hat, von welchen Startdatum und zu welchen Enddatum +-- Wir rufen diese Information ab, aber anstelle der Mitarbeiternummer, +-- verwenden wir die Mitarbeiternummer als Querverweis auf die empoyees Tabelle +-- um die die Vor- und Nachnamen jedes Mitarbeiters zu erhalten. +-- (und nur 10 Reihen) +SELECT employees.first_name, employees.last_name, + titles.title, titles.from_date, titles.to_date +FROM titles INNER JOIN employees ON + employees.emp_no = titles.emp_no LIMIT 10; + +-- Liste alle Tabellen in allen Datenbanken auf. Verschiedene Implementierungen +-- stellen typischerweise einen eigenen Abkürzungsbefehl zur Verfügung für +-- die aktuell verwendete Datenbank. +SELECT * FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE='BASE TABLE'; + +-- Erstelle eine Tabelle in der aktuell verwedeten Datenbank +-- mit dem Namen tablename1, in der die beiden Spalten angezeigt werden +-- Es gibt viele weiteren Optionen, wie man die Spalten spezifizieren kann, +-- wie z.B. deren Datentyp. +CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20)); + +-- Füge eine Zeile mit Daten in die Tabelle tablename1. Dies setzt voraus, +-- das die Tabelle so definiert worden ist, dass sie die geeigneten +-- Werte akzeptiert. +INSERT INTO tablename1 VALUES('Richard','Mutt'); + +-- Verändere den fname Wert zu 'John' für alle Zeilen, +-- die einen lname Wert von 'Mutt' haben. +UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; + +-- Lösche Zeilen aus der tablename1 Tabelle, +-- deren lname Wert mit dem Wert 'M' beginnen. +DELETE FROM tablename1 WHERE lname like 'M%'; + +-- Lösche alle Zeilen von der tablename1 Tabelle, hinterlasse nur eine leere +-- Tabelle. +DELETE FROM tablename1; + +-- Lösche die gesamte tablename1 Tabelle. +DROP TABLE tablename1; +``` diff --git a/de-de/visualbasic-de.html.markdown b/de-de/visualbasic-de.html.markdown new file mode 100644 index 00000000..6194e906 --- /dev/null +++ b/de-de/visualbasic-de.html.markdown @@ -0,0 +1,290 @@ +--- +language: Visual Basic +contributors: + - ["Brian Martin", "http://brianmartin.biz"] +translators: + - ["Enno Nagel", "https://github.com/konfekt"] +filename: learnvisualbasic-de.vb +lang: de-de +--- + +```visualbasic +Module Modul1 + +Sub Main() + ' Ein kurzer Blick auf Visual Basic-Konsolenanwendungen + ' bevor wir tiefer in das Thema eintauchen. + ' Das Hochkomma leitet eine Kommentarzeile ein. + ' Um dieses Tutorial innerhalb des Visual Basic Compilers zu erkunden, + ' habe ich ein Navigationssystem erstellt. + ' Dieses System wird im weiteren Verlauf des Tutorials erklärt; + ' Sie werden nach und nach verstehen, was das alles bedeutet. + Console.Title = ("Lerne X in Y Minuten") + Console.WriteLine ("NAVIGATION") 'Anzeige + Console.WriteLine ("") + Console.ForegroundColor = ConsoleColor.Green + Console.WriteLine ("1. Ausgabe von 'Hallo, Welt'") + Console.WriteLine ("2. Eingabe 'Hallo, Welt'") + Console.WriteLine ("3. ganze Zahlen berechnen") + Console.WriteLine ("4. Berechne Dezimalzahlen") + Console.WriteLine ("5. ein funktionaler Taschenrechner") + Console.WriteLine ("6. 'Do While'-Schleifen verwenden") + Console.WriteLine ("7. Verwendung von 'For While'-Schleifen") + Console.WriteLine ("8. Bedingte Anweisungen") + Console.WriteLine ("9. Ein Getränk auswählen") + Console.WriteLine ("50. Über") + Console.WriteLine ("Wählen Sie eine Zahl aus der obigen Liste") + Dim selection As String = Console.Readline() + Select Case auswahl + Case "1" 'Ausgabe "Hallo, Welt" + Console.Clear() 'Löscht die Konsole und öffnet die private Subroutine + AusgabeHalloWelt() 'Öffnet die genannte private Subroutine + Case "2" 'Eingabe "hallo, Welt" + Console.Clear() + EingabeHalloWelt() + Case "3" 'Berechne ganze Zahlen + Console.Clear() + BerechneGanzeZahlen() + Case "4" 'Dezimalzahlen berechnen + Console.Clear() + BerechneDezimalZahlen() + Case "5" 'Ein funktionaler Taschenrechner + Console.Clear() + Taschenrechner() + Case "6" 'Verwendung von "Do While"-Schleifen + Console.Clear() + WhileSchleife() + Case "7" 'Verwendung von "For While"-Schleifen + Console.Clear() + ForSchleife() + Case "8" 'Bedingte Anweisungen + Console.Clear() + BedingteAnweisung() + Case "9" 'If/Else-Anweisung + Console.Clear() + IfElseAnweisung() 'Ein Getränk auswählen + Case "50" '"Über" Infobox + Console.Clear() + Console.Title = ("Lernen Sie X in Y Minuten :: Über") + MsgBox ("Tutorial geschrieben von Brian Martin (@BrianMartinn)") + Console.Clear() + Main() + Console.ReadLine() + + End Select +End Sub + +'Eins - Ich habe Zahlen verwendet, um mich durch das obige Navigationssystem zu +'führen auf das ich später zurückkomme, um es zu implementieren. + +'wir verwenden private Unterprogramme, um verschiedene Abschnitte des Programms +'zu trennen. +Private Sub AusgabeHalloWelt() + 'Titel der Konsolenanwendung + Console.Title = "Ausgabe 'Hallo, Welt' | Lerne X in Y Minuten" + 'Verwenden Sie Console.Write("") oder Console.WriteLine(""), um die Ausgabe + 'anzuzeigen, gefolgt von Console.Read(), oder Console.Readline() + 'Console.ReadLine() zeigt die Ausgabe auf der Konsole an. + Console.WriteLine ("Hallo, Welt") + Console.ReadLine() +End Sub + +'Zwei +Private Sub EingabeHalloWelt() + Console.Title = "Hallo, Welt, ich bin.. | Lerne X in Y Minuten" + 'Variablen + 'Vom Benutzer eingegebene Daten müssen gespeichert werden. + 'Variablen beginnen ebenfalls mit Dim und enden mit As VariableType. + + 'In diesem Lernprogramm wollen wir Ihren Namen wissen und das Programm + 'auf ihn antworten. + Dim nutzername As String + ' Wir verwenden "String", weil es sich um eine textbasierte Variable handelt. + Console.WriteLine ("Hallo, wie ist Ihr Name?") 'Frage nach dem Benutzernamen. + nutzername = Console.ReadLine() 'Benutzernamen speichern. + Console.WriteLine ("Hallo, " + nutzername) 'Ausgabe ist Hallo, Name + Console.ReadLine() 'Die obige Ausgabe anzeigen. + 'Der obige Code stellt Ihnen eine Frage und zeigt die Antwort an. + 'Neben anderen Variablentypen gibt es Integer, den wir für ganze Zahlen + 'verwenden werden. +End Sub + +'Drei +Private Sub BerechneGanzeZahlen() + Console.Title = "Berechne ganze Zahlen | Lerne X in Y Minuten" + Console.Write ("Erste Zahl: ") 'Schreiben Sie eine ganze Zahl, 1, 2, 104, usw + Dim a As Integer = Console.ReadLine() + Console.Write ("Zweite Zahl: ") 'Schreiben Sie eine weitere ganze Zahl. + Dim b As Integer = Console.ReadLine() + Dim c As Integer = a + b + Console.WriteLine (c) + Console.ReadLine() + 'Dies ist ein einfacher Taschenrechner +End Sub + +'Vier +Private Sub BerechneDezimalZahlen() + Console.Title = "Berechne mit dem Typ Double | Lerne X in Y Minuten" + 'Natürlich würden wir gerne Dezimalzahlen addieren. + 'Also könnten wir von Integer auf Double umstellen. + + 'Schreiben Sie eine Bruchzahl, 1.2, 2.4, 50.1, 104.9 usw + Console.Write ("Erste Zahl: ") + Dim a As Double = Console.Readline() + Console.Write ("Zweite Zahl: ") 'Schreiben Sie die zweite Zahl. + Dim b As Double = Console.Readline() + Dim c As Double = a + b + Console.WriteLine (c) + Console.ReadLine() + 'Dieses Programm kann 1.1 und 2.2 addieren +End Sub + +'Fünf +Private Sub Taschenrechner() + Console.Title = "Der Funktionsrechner | Lerne X in Y Minuten" + 'Wenn Sie aber wollen, dass der Rechner subtrahiert, dividiert, + 'multipliziert und addiert. + 'Kopieren Sie den obigen Text und fügen Sie ihn ein. + Console.Write ("Erste Zahl: ") + Dim a As Double = Console.Readline() + Console.Write ("Zweite Zahl: ") + Dim b As Integer = Console.Readline() + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + 'Mit den folgenden Zeilen können wir die Werte a und b + 'subtrahieren, multiplizieren und dividieren + Console.Write (a.ToString() + " + " + b.ToString()) + 'Wir wollen den Ergebnissen einen linken Rand von 3 Leerzeichen geben. + Console.WriteLine (" = " + c.ToString.PadLeft(3)) + Console.Write (a.ToString() + " * " + b.ToString()) + Console.WriteLine (" = " + d.ToString.PadLeft(3)) + Console.Write (a.ToString() + " - " + b.ToString()) + Console.WriteLine (" = " + e.ToString.PadLeft(3)) + Console.Write (a.ToString() + " / " + b.ToString()) + Console.WriteLine (" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + +End Sub + +'Sechs +Private Sub WhileSchleife() + 'Gleich zur vorherigen privaten Subroutine. + 'Diesmal fragen wir den Benutzer, ob er fortfahren möchte (ja oder nein?). + 'Wir verwenden die Do While-Schleife, weil wir nicht wissen, ob der Benutzer + 'das Programm mehr als einmal verwenden möchte. + Console.Title = "Do While-Schleifen verwenden | X in Y Minuten lernen" + Dim antwort As String 'Wir verwenden "String", weil die Antwort ein Text ist + Do 'Wir beginnen das Programm mit + Console.Write ("Erste Zahl: ") + Dim a As Double = Console.Readline() + Console.Write ("Zweite Zahl: ") + Dim b As Integer = Console.Readline() + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + Console.Write (a.ToString() + " + " + b.ToString()) + Console.WriteLine (" = " + c.ToString.PadLeft(3)) + Console.Write (a.ToString() + " * " + b.ToString()) + Console.WriteLine (" = " + d.ToString.PadLeft(3)) + Console.Write (a.ToString() + " - " + b.ToString()) + Console.WriteLine (" = " + e.ToString.PadLeft(3)) + Console.Write (a.ToString() + " / " + b.ToString()) + Console.WriteLine (" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + 'Fragen Sie den Benutzer, ob er fortfahren möchte. Unglücklicherweise + 'werden Groß- und Kleinschreibung unterschieden. + Console.Write ("Möchten Sie fortfahren? (j / n)") + 'Das Programm nimmt die Variable, zeigt sie an und beginnt von vorne. + antwort = Console.Readline() + 'Der Befehl, der diese Variable zum Laufen bringt, ist in diesem Fall "j" + Loop While antwort = "j" + +End Sub + +'Sieben +Private Sub ForSchleife() + 'Manchmal muss das Programm nur einmal ausgeführt werden. + 'In diesem Programm werden wir von 10 loszählen. + + Console.Title = "Mit "For"-Schleifen | X in Y Minuten lernen" + 'Deklarieren Sie die Variable und ab welcher Zahl in Schritt -1 gezählt + 'werden soll, Schritt -2, Schritt -3, usw. + For i As Integer = 10 To 0 Schritt -1 + Console.WriteLine (i.ToString) 'Zählerwert anzeigen + Next i 'Berechne den neuen Wert + Console.WriteLine ("Start") 'Starten wir das Programm, baby!!!! + Console.ReadLine() 'BANG!!!! - Vielleicht war ich zu aufgeregt :) +End Sub + +'Acht +Private Sub BedingteAnweisung() + Console.Title = "Bedingte Anweisungen | X in Y Minuten lernen" + Dim username As String = Console.Readline() + 'Aufforderung zur Eingabe des Benutzernamens. + Console.WriteLine ("Hallo, wie ist Ihr Name?") + username = Console.ReadLine() 'Benutzernamen speichern. + If username = "Adam" Then + Console.WriteLine ("Hallo, Adam") + Console.WriteLine ("Danke, dass Sie diese nützliche Website erstellt haben") + Console.ReadLine() + Else + Console.WriteLine ("Hallo, " + Benutzername) + Console.WriteLine ("Haben Sie www.learnxinyminutes.com besucht?") + Console.ReadLine() 'Beendet und zeigt die obige Anweisung an. + End If +End Sub + + 'Neun +Private Sub IfElseAnweisung() + Console.Title = "If / Else-Anweisung | X in Y Minuten lernen" + 'Manchmal ist es wichtig, mehr als zwei Alternativen in Betracht zu ziehen. + 'Manchmal sind einige von ihnen besser. + 'In diesem Fall brauchen wir mehr als eine "if"-Anweisung. + 'Eine "if"-Anweisung ist für Verkaufsautomaten geeignet. + 'Der Benutzer gibt einen Code ein (A1, A2, A3), aus dem er wählen kann. + 'Alle Auswahlmöglichkeiten können in einer einzigen "if"-Anweisung + 'kombiniert werden. + + Dim auswahl As String = Console.ReadLine 'Der Wert der Auswahl + Console.WriteLine ("A1. für 7Up") + Console.WriteLine ("A2. für Fanta") + Console.WriteLine ("A3. für Dr. Pepper") + Console.WriteLine ("A4. für Coca-Cola") + Console.ReadLine() + If auswahl = "A1" Dann + Console.WriteLine ("7up") + Console.ReadLine() + ElseIf auswahl = "A2" Then + Console.WriteLine ("fanta") + Console.ReadLine() + ElseIf auswahl = "A3" Then + Console.WriteLine ("Dr. Pfeffer") + Console.ReadLine() + ElseIf auswahl = "A4" Then + Console.WriteLine ("Coca-Cola") + Console.ReadLine() + Else + Console.WriteLine ("Ein Produkt auswählen") + Console.ReadLine() + End If + +End Sub + +End Module +``` + +## Referenzen + +Für diejenigen, die mehr wissen wollen, hat Brian Martin ein umfassenderes +[Visual Basic Tutorial](http://www.vbbootcamp.co.uk/ "Visual Basic Tutorial") +erstellt. + +Die gesamte Syntax sollte gültig sein. +Kopieren Sie den Code und fügen Sie ihn in den Visual Basic Compiler ein und +führen Sie das Programm aus (F5). + diff --git a/docker.html.markdown b/docker.html.markdown index 0e61151e..ec6abe7e 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -1,281 +1,281 @@ ----
-category: tool
-tool: docker
-filename: docker.bat
-contributors:
- - ["Ruslan López", "http://javapro.org/"]
- - ["Michael Chen", "https://github.com/ML-Chen"]
- - ["Akshita Dixit", "https://github.com/akshitadixit"]
- - ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"]
----
-
-Docker is a tool that helps you build, test, ship and run applications
-seamlessly across various machines. It replicates the environment our software
-needs on any machine. You can get Docker for your machine from
-https://docs.docker.com/get-docker/
-
-It has grown in popularity over the last decade due to being lightweight and
-fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker
-does not need a full blown OS of its own to be loaded to start and does not
-compete for resources other than what the application it is running will use.
-VMs on the other hand are pretty resource intensive on our processors, disks and
-memory hence running multiple VMs for various applications becomes a challenge
-in a limited capacity architecture.
-
-<pre>
-┌────────────────────────┐ ┌───────────────────────┐
-│ ┌───────────┐ │ │ ┌───────────┐ │
-│ │ App │ │ │ │ App │ │
-│ └───────────┘ │ │ └───────────┘ │
-│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │
-│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │
-│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │
-│ ┌───────────────────┐ │ │ ┌──────────────────┐ │
-│ │ Guest OS │ │ │ │ Guest OS │ │
-│ └───────────────────┘ │ │ └──────────────────┘ │
-│ VM1 │ │ VM2 │
-└────────────────────────┘ └───────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ Hypervisor │
-└──────────────────────────────────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ Host OS │
-└──────────────────────────────────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ Hardware Infrastructure │
-└──────────────────────────────────────────────────┘
- (VM based architecture)
-
-┌────────────────────────┐ ┌───────────────────────┐
-│ ┌───────────┐ │ │ ┌───────────┐ │
-│ │ App │ │ │ │ App │ │
-│ └───────────┘ │ │ └───────────┘ │
-│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │
-│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │
-│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │
-│ Container1 │ │ Container2 │
-└────────────────────────┘ └───────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ Docker │
-└──────────────────────────────────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ OS │
-└──────────────────────────────────────────────────┘
-┌──────────────────────────────────────────────────┐
-│ Hardware Infrastructure │
-└──────────────────────────────────────────────────┘
- (Docker based architecture)
-
-</pre>
-
-Couple of terms we will encounter frequently are Docker Images and Docker
-Containers. Images are packages or templates of containers all stored in a
-container registry such as [Docker Hub](https://hub.docker.com/). Containers
-are standalone, executable instances of these images which include code,
-runtime, system tools, system libraries and settings - everything required to
-get the software up and running. Coming to Docker, it follows a client-server
-architecture wherein the CLI client communicates with the server component,
-which here is, the Docker Engine using RESTful API to issue commands.
-
-## The Docker CLI
-```bash
-# after installing Docker from https://docs.docker.com/get-docker/
-# To list available commands, either run `docker` with no parameters or execute
-# `docker help`
-$ docker
-
->>> docker [OPTIONS] COMMAND [ARG...]
- docker [ --help | -v | --version ]
-
- A self-sufficient runtime for containers.
-
- Options:
- --config string Location of client config files (default "/root/.docker")
- -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
- -D, --debug Enable debug mode
- --help Print usage
- -H, --host value Daemon socket(s) to connect to (default [])
- -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
- --tls Use TLS; implied by --tlsverify
- --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
- --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
- --tlskey string Path to TLS key file (default "/root/.docker/key.pem")
- --tlsverify Use TLS and verify the remote
- -v, --version Print version information and quit
-
- Commands:
- attach Attach to a running container
- # […]
-
-$ docker run hello-world
-# `docker run <container-name>` is used to run a container, it will pull the
-# images from Docker Hub if they don't already exist in your system. Here the
-# docker client connects to the daemon which in turn pulls the "hello-world"
-# image from the Docker Hub. The daemon then builds a new container from the
-# image which runs the executable that produces the output streamed back to the
-# client that we see on our terminals.
-
-$ docker run -d ubuntu sleep 60s
-# The -d (or --detach) flag is when we want to run a container in the background
-# and return back to the terminal. Here we detach an ubuntu container from the
-# terminal, the output should be the id and the command exits. If we check
-# running containers, we should still see ours there:
-# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-# 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould
-
-$ docker run <container-id> -p 3000:8000
-# The -p (or --publish) flag is used to expose port 8000 inside the container to
-# port 3000 outside the container. This is because the app inside the container
-# runs in isolation, hence the port 8000 where the app runs is private to the
-# container.
-
-$ docker run -i
-# or
-$ docker run -it
-# Docker runs our containers in a non-interactive mode i.e. they do not accept
-# inputs or work dynamically while running. The -i flag keeps input open to the
-# container, and the -t flag creates a pseudo-terminal that the shell can attach
-# to (can be combined as -it)
-
-$ docker ps -a
-# The `docker ps` command only shows running containers by default. To see all
-# containers, use the -a (or --all) flag
-# Running the above command should output something similar in the terminal:
-# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-# 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet
-
-
-$ docker stop hello-world
-# or
-$ docker start hello-world
-# The stop command simply stops one or more containers, and the start command
-# starts the container(s) up again! `docker start -a ubuntu` will attach our
-# detached container back to the terminal i.e. runs in the foreground
-
-$ docker create alpine
-# `docker create` creates a new container for us with the image specified (here,
-# alpine), the container does not auto-start unlike `docker run`. This command
-# is used to set up a container configuration and then `docker start` to shoot
-# it up when required. Note that the status is "Created":
-# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-# 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie
-
-$ docker rm 82f84
-# Removes one or more containers using their container ID.
-# P.S.: we can use only the first few characters of the entire ID to identify
-# containers
-
-$ docker images
-# Displays all images and their information, created here means the latest image
-# tag updated on Docker Hub:
-# REPOSITORY TAG IMAGE ID CREATED SIZE
-# ubuntu latest a8780b506fa4 9 days ago 77.8MB
-# alpine latest 9c6f07244728 3 months ago 5.54MB
-# hello-world latest feb5d9fea6a5 13 months ago 13.3kB
-
-$ docker rmi
-# Removes one or more images from your system which do not have their instances
-# (or containers as we know them) running. If the image has an attached
-# container, either delete the container first or use the -f (or --force) flag
-# to forcefully delete both the container and image.
-
-$ docker pull busybox
-# The pull command downloads the specified image on our system from Docker Hub.
-
-$ docker exec -it 7b272 bash
-# This command is used to run a command in the running container's default
-# directory. Here 7b272 was our ubuntu container and the above command would
-# help us interact with the container by opening a bash session.
-
-$docker logs <container-id>
-# Displays the information logged by the specified container
-# root@7b27222e4bb7:/# whoami
-# root
-# root@7b27222e4bb7:/# pwd
-# /
-# root@7b27222e4bb7:/# ls
-# bin boot dev etc home lib lib32 lib64 libx3 srv sys tmp usr var
-# root@7b27222e4bb7:/# exit
-# exit
-
-# More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/
-```
-## The Dockerfile
-The Dockerfile is a blueprint of a Docker image. We can mention the artifacts
-from our application along with their configurations into this file in the
-specific syntax to let anyone create a Docker image of our application.
-
-### A few things to keep in mind:
-* It is always strictly named `Dockerfile` without any extensions
-* We have to build our custom image on top of some already available Docker base
-image. (there is an empty image called `scratch` which literally lets you build
-an image from scratch)
-* All capitalised commands are part of the syntax, they are not case-sensitive
-but used like a convention
-* Below is a sample Dockerfile but you can read in depth from the [official docs](https://docs.docker.com/engine/reference/builder/).
-
-```Dockerfile
-FROM <base-image>
-# define base image
-
-ENV USERNAME='admin'\
- PWD='****'
-# optionally define environmental variables
-
-RUN apt-get update
-# run linux commands inside container env, does not affect host env
-# This executes during the time of image creation
-
-COPY <src> <target>
-# executes on the host, copies files from src (usually on the host) to target
-# on the container
-
-ENTRYPOINT ["some-script.sh"]
-# executes an entire script as an entrypoint
-
-CMD [<args>,...]
-# always part of dockerfile, introduces entry point linux command e.g.
-# `CMD node server.js`
-# This executes after image creation only when the container from the image
-# is running.
-```
-### Build your images
-Use the `docker build` command after wrapping your application into a Docker
-image to run ( or build) it.
-
-```bash
-
-$docker build <path-to-dockerfile>
-# used to build an image from the specified Dockerfile
-# instead of path we could also specify a URL
-# -t tag is optional and used to name and tag your images for e.g.
-# `$docker build -t my-image:0.1 ./home/app`
-# rebuild images everytime you make changes in the dockerfile
-```
-
-## Push your image to DockerHub
-If you want your application's Docker image to be made publicly available for
-any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a
-registry of Docker images. Make sure you have an account with a username and
-password on Docker Hub.
-
-When pushing an image to Docker Hub, we must specify our Docker Hub username
-as part of the source image name. We need to create the target image with the
-tag name of username/image-name much like GitHub repositories.
-
-```bash
-$docker login
-# to login to Docker Hub using your username and password
-
-$docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>]
-# this tags a local src-image to a public target-image
-# e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app`
-# if tags are not specified, they're defaulted to `latest`
-
-$docker push <target-image>[:<target-tag>]
-# uploads our image to Docker Hub
-# e.g. `docker push akshitadixit/my-sample-app`
-# this image will be accessible under your profile's repositories as
-# `https://hub.docker.com/r/username/image-name`
-
-```
+--- +category: tool +tool: docker +filename: docker.bat +contributors: + - ["Ruslan López", "http://javapro.org/"] + - ["Michael Chen", "https://github.com/ML-Chen"] + - ["Akshita Dixit", "https://github.com/akshitadixit"] + - ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"] +--- + +Docker is a tool that helps you build, test, ship and run applications +seamlessly across various machines. It replicates the environment our software +needs on any machine. You can get Docker for your machine from +https://docs.docker.com/get-docker/ + +It has grown in popularity over the last decade due to being lightweight and +fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker +does not need a full blown OS of its own to be loaded to start and does not +compete for resources other than what the application it is running will use. +VMs on the other hand are pretty resource intensive on our processors, disks and +memory hence running multiple VMs for various applications becomes a challenge +in a limited capacity architecture. + +<pre> +┌────────────────────────┐ ┌───────────────────────┐ +│ ┌───────────┐ │ │ ┌───────────┐ │ +│ │ App │ │ │ │ App │ │ +│ └───────────┘ │ │ └───────────┘ │ +│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │ +│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ +│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │ +│ ┌───────────────────┐ │ │ ┌──────────────────┐ │ +│ │ Guest OS │ │ │ │ Guest OS │ │ +│ └───────────────────┘ │ │ └──────────────────┘ │ +│ VM1 │ │ VM2 │ +└────────────────────────┘ └───────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ Hypervisor │ +└──────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ Host OS │ +└──────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ Hardware Infrastructure │ +└──────────────────────────────────────────────────┘ + (VM based architecture) + +┌────────────────────────┐ ┌───────────────────────┐ +│ ┌───────────┐ │ │ ┌───────────┐ │ +│ │ App │ │ │ │ App │ │ +│ └───────────┘ │ │ └───────────┘ │ +│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │ +│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ +│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │ +│ Container1 │ │ Container2 │ +└────────────────────────┘ └───────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ Docker │ +└──────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ OS │ +└──────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────┐ +│ Hardware Infrastructure │ +└──────────────────────────────────────────────────┘ + (Docker based architecture) + +</pre> + +Couple of terms we will encounter frequently are Docker Images and Docker +Containers. Images are packages or templates of containers all stored in a +container registry such as [Docker Hub](https://hub.docker.com/). Containers +are standalone, executable instances of these images which include code, +runtime, system tools, system libraries and settings - everything required to +get the software up and running. Coming to Docker, it follows a client-server +architecture wherein the CLI client communicates with the server component, +which here is, the Docker Engine using RESTful API to issue commands. + +## The Docker CLI +```bash +# after installing Docker from https://docs.docker.com/get-docker/ +# To list available commands, either run `docker` with no parameters or execute +# `docker help` +$ docker + +>>> docker [OPTIONS] COMMAND [ARG...] + docker [ --help | -v | --version ] + + A self-sufficient runtime for containers. + + Options: + --config string Location of client config files (default "/root/.docker") + -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") + -D, --debug Enable debug mode + --help Print usage + -H, --host value Daemon socket(s) to connect to (default []) + -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") + --tls Use TLS; implied by --tlsverify + --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") + --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") + --tlskey string Path to TLS key file (default "/root/.docker/key.pem") + --tlsverify Use TLS and verify the remote + -v, --version Print version information and quit + + Commands: + attach Attach to a running container + # […] + +$ docker run hello-world +# `docker run <container-name>` is used to run a container, it will pull the +# images from Docker Hub if they don't already exist in your system. Here the +# docker client connects to the daemon which in turn pulls the "hello-world" +# image from the Docker Hub. The daemon then builds a new container from the +# image which runs the executable that produces the output streamed back to the +# client that we see on our terminals. + +$ docker run -d ubuntu sleep 60s +# The -d (or --detach) flag is when we want to run a container in the background +# and return back to the terminal. Here we detach an ubuntu container from the +# terminal, the output should be the id and the command exits. If we check +# running containers, we should still see ours there: +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould + +$ docker run <container-id> -p 3000:8000 +# The -p (or --publish) flag is used to expose port 8000 inside the container to +# port 3000 outside the container. This is because the app inside the container +# runs in isolation, hence the port 8000 where the app runs is private to the +# container. + +$ docker run -i +# or +$ docker run -it +# Docker runs our containers in a non-interactive mode i.e. they do not accept +# inputs or work dynamically while running. The -i flag keeps input open to the +# container, and the -t flag creates a pseudo-terminal that the shell can attach +# to (can be combined as -it) + +$ docker ps -a +# The `docker ps` command only shows running containers by default. To see all +# containers, use the -a (or --all) flag +# Running the above command should output something similar in the terminal: +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet + + +$ docker stop hello-world +# or +$ docker start hello-world +# The stop command simply stops one or more containers, and the start command +# starts the container(s) up again! `docker start -a ubuntu` will attach our +# detached container back to the terminal i.e. runs in the foreground + +$ docker create alpine +# `docker create` creates a new container for us with the image specified (here, +# alpine), the container does not auto-start unlike `docker run`. This command +# is used to set up a container configuration and then `docker start` to shoot +# it up when required. Note that the status is "Created": +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie + +$ docker rm 82f84 +# Removes one or more containers using their container ID. +# P.S.: we can use only the first few characters of the entire ID to identify +# containers + +$ docker images +# Displays all images and their information, created here means the latest image +# tag updated on Docker Hub: +# REPOSITORY TAG IMAGE ID CREATED SIZE +# ubuntu latest a8780b506fa4 9 days ago 77.8MB +# alpine latest 9c6f07244728 3 months ago 5.54MB +# hello-world latest feb5d9fea6a5 13 months ago 13.3kB + +$ docker rmi +# Removes one or more images from your system which do not have their instances +# (or containers as we know them) running. If the image has an attached +# container, either delete the container first or use the -f (or --force) flag +# to forcefully delete both the container and image. + +$ docker pull busybox +# The pull command downloads the specified image on our system from Docker Hub. + +$ docker exec -it 7b272 bash +# This command is used to run a command in the running container's default +# directory. Here 7b272 was our ubuntu container and the above command would +# help us interact with the container by opening a bash session. + +$ docker logs <container-id> +# Displays the information logged by the specified container +# root@7b27222e4bb7:/# whoami +# root +# root@7b27222e4bb7:/# pwd +# / +# root@7b27222e4bb7:/# ls +# bin boot dev etc home lib lib32 lib64 libx3 srv sys tmp usr var +# root@7b27222e4bb7:/# exit +# exit + +# More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ +``` +## The Dockerfile +The Dockerfile is a blueprint of a Docker image. We can mention the artifacts +from our application along with their configurations into this file in the +specific syntax to let anyone create a Docker image of our application. + +### A few things to keep in mind: +* It is always strictly named `Dockerfile` without any extensions +* We have to build our custom image on top of some already available Docker base +image. (there is an empty image called `scratch` which literally lets you build +an image from scratch) +* All capitalised commands are part of the syntax, they are not case-sensitive +but used like a convention +* Below is a sample Dockerfile but you can read in depth from the [official docs](https://docs.docker.com/engine/reference/builder/). + +```Dockerfile +FROM <base-image> +# define base image + +ENV USERNAME='admin'\ + PWD='****' +# optionally define environmental variables + +RUN apt-get update +# run linux commands inside container env, does not affect host env +# This executes during the time of image creation + +COPY <src> <target> +# executes on the host, copies files from src (usually on the host) to target +# on the container + +ENTRYPOINT ["some-script.sh"] +# executes an entire script as an entrypoint + +CMD [<args>,...] +# always part of dockerfile, introduces entry point linux command e.g. +# `CMD node server.js` +# This executes after image creation only when the container from the image +# is running. +``` +### Build your images +Use the `docker build` command after wrapping your application into a Docker +image to run ( or build) it. + +```bash + +$ docker build <path-to-dockerfile> +# used to build an image from the specified Dockerfile +# instead of path we could also specify a URL +# -t tag is optional and used to name and tag your images for e.g. +# `$ docker build -t my-image:0.1 ./home/app` +# rebuild images everytime you make changes in the dockerfile +``` + +## Push your image to DockerHub +If you want your application's Docker image to be made publicly available for +any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a +registry of Docker images. Make sure you have an account with a username and +password on Docker Hub. + +When pushing an image to Docker Hub, we must specify our Docker Hub username +as part of the source image name. We need to create the target image with the +tag name of username/image-name much like GitHub repositories. + +```bash +$ docker login +# to login to Docker Hub using your username and password + +$ docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>] +# this tags a local src-image to a public target-image +# e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app` +# if tags are not specified, they're defaulted to `latest` + +$ docker push <target-image>[:<target-tag>] +# uploads our image to Docker Hub +# e.g. `docker push akshitadixit/my-sample-app` +# this image will be accessible under your profile's repositories as +# `https://hub.docker.com/r/username/image-name` + +``` diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown index 3e3c0413..ff053384 100644 --- a/dynamic-programming.html.markdown +++ b/dynamic-programming.html.markdown @@ -59,5 +59,3 @@ for i=0 to n-1 * [Optimal Substructure Property](https://www.geeksforgeeks.org/dynamic-programming-set-2-optimal-substructure-property/) * [How to solve a DP problem](https://www.geeksforgeeks.org/solve-dynamic-programming-problem/) * [How to write DP solutions](https://www.quora.com/Are-there-any-good-resources-or-tutorials-for-dynamic-programming-DP-besides-the-TopCoder-tutorial/answer/Michal-Danilák) - -And a [quiz](https://www.commonlounge.com/discussion/cdbbfe83bcd64281964b788969247253) to test your knowledge. diff --git a/el-gr/rust-gr.html.markdown b/el-gr/rust-gr.html.markdown index 4da75b1d..d28e3c2c 100644 --- a/el-gr/rust-gr.html.markdown +++ b/el-gr/rust-gr.html.markdown @@ -62,7 +62,7 @@ fn add2(x: i32, y: i32) -> i32 { fn main() { // Αριθμοί // - // Αμετάβλητη σύνδεση + // Αμετάβλητη δέσμευση (η τιμή που αντιστοιχεί στο όνομα "x" δεν μπορεί να αλλάξει) let x: i32 = 1; // Καταλήξεις integer/float @@ -80,7 +80,8 @@ fn main() { // Πράξεις let sum = x + y + 13; - // Μη-αμετάβλητη αξία (με την έννοια ότι μπορεί να αλλάξει) + // Μεταβλητές (με την έννοια των προστακτικών γλωσσών προγραμματισμού). + // Στη Rust η αμετάβλητη δέσμευση είναι στάνταρ. Το mut δηλώνει μεταβλητότητα. let mut mutable = 1; mutable = 4; mutable += 2; @@ -96,7 +97,7 @@ fn main() { // A `String` – a heap-allocated string let s: String = "καλημέρα κόσμε".to_string(); - // Ένα κομμάτι αλφαριθμητικού (string slice) – μια μη-μεταβλητή οπτική γωνία προς ένα άλλο αλφαριθμητικό + // Ένα κομμάτι αλφαριθμητικού (string slice) – μια αμετάβλητη οπτική γωνία προς ένα άλλο αλφαριθμητικό // Το αλφαριθμητικό μπορεί να είναι στατικό όπως τα σταθερά αλφαριθμητικά, ή να περιλαμβάνεται σε ένα άλλο, // δυναμικό αντικείμενο (σε αυτή την περίπτωση τη μεταβλητή `s`) let s_slice: &str = &s; @@ -112,7 +113,7 @@ fn main() { let mut vector: Vec<i32> = vec![1, 2, 3, 4]; vector.push(5); - // Ένα κομμάτι – μια μη-μεταβλητή οπτική γωνία προς ένα διάνυσμα ή πίνακα + // Ένα κομμάτι – μια αμετάβλητη οπτική γωνία προς ένα διάνυσμα ή πίνακα // Είναι παρόμοιο με το κομμάτι αλφαριθμητικού που είδαμε προηγουμένως let slice: &[i32] = &vector; @@ -121,10 +122,10 @@ fn main() { // Tuples (πλειάδες) // - // Ένα tuple είναι μια σταθερού μεγέθους σειρά από αξίες (πιθανά διαφορετικού τύπου) + // Ένα tuple είναι μια σταθερού μεγέθους σειρά από τιμές (πιθανά διαφορετικού τύπου) let x: (i32, &str, f64) = (1, "καλημέρα", 3.4); - // Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές αξίες σε πολλές μεταβλητές ταυτόχρονα + // Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές τιμές σε πολλές μεταβλητές ταυτόχρονα // (destructuring `let`) let (a, b, c) = x; println!("{} {} {}", a, b, c); // 1 καλημέρα 3.4 @@ -185,7 +186,7 @@ fn main() { fn bar(&self) -> &T { // Δανειζόμαστε το self &self.bar } - fn bar_mut(&mut self) -> &mut T { // Δανειζόμαστε το self ως μη-αμετάβλητη αξία + fn bar_mut(&mut self) -> &mut T { // Γίνεται "μεταβλητός δανεισμός" του self (μπορούμε να το τροποποιήσουμε) &mut self.bar } fn into_bar(self) -> T { // Εδώ το self καταναλώνεται @@ -240,7 +241,7 @@ fn main() { // 4. Έλεγχος ροής // ///////////////////// - // Βρόγχοι `for` + // Βρόχοι `for` let array = [1, 2, 3]; for i in array { println!("{}", i); @@ -253,7 +254,7 @@ fn main() { println!(""); // Τυπώνει `0 1 2 3 4 5 6 7 8 9 ` - // Βρόγχοι `if` + // `if` (υπό συνθήκη διακλάδωση) if 1 == 1 { println!("Τα μαθηματικά δουλεύουν!"); } else { @@ -267,17 +268,17 @@ fn main() { "κακό" }; - // Βρόγχοι `while` + // Βρόχοι `while` while 1 == 1 { println!("Το σύμπαν λειτουργεί κανονικά."); - // Μπορούμε να βγούμε από το βρόγχο με το `break` + // Μπορούμε να βγούμε από το βρόχο με το `break` break } - // Ατέρμονος βρόχγος + // Ατέρμονος βρόχος loop { println!("Καλημέρα!"); - // Μπορούμε να βγούμε από το βρόγχο με το `break` + // Μπορούμε να βγούμε από το βρόχο με το `break` break } @@ -294,11 +295,11 @@ fn main() { *now_its_mine += 2; println!("{}", now_its_mine); // 7 - // println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανοίκει στο `now_its_mine` + // println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανήκει στο `now_its_mine` // Reference (αναφορά) – ένας αμετάβλητος δείκτης που αναφέρεται σε άλλα δεδομένα - // Όταν μια αναφορά δίνεται σε μια αξία, λέμε πως η αξία έχει "δανειστεί". - // Όταν μια αξία δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί. + // Όταν μια αναφορά δίνεται σε μια τιμή, λέμε πως η τιμή έχει "δανειστεί". + // Όταν μια τιμή δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί. // Ένας "δανεισμός" παραμένει ενεργός μέχρι την τελευταία χρήση της μεταβλητής που δανείζεται. let mut var = 4; var = 3; @@ -313,13 +314,13 @@ fn main() { var = 2; // Η `ref_var` δεν χρησιμοποιείται από εδώ και στο εξής, άρα ο "δανεισμός" τελειώνει // Μεταβλητή αναφορά - // Όσο μια αξία είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη. + // Όσο μια τιμή είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη. let mut var2 = 4; let ref_var2: &mut i32 = &mut var2; *ref_var2 += 2; // Ο αστερίσκος (*) χρησιμοποιείται ως δείκτης προς την μεταβλητά δανεισμένη `var2` println!("{}", *ref_var2); // 6 , // Αν είχαμε `var2` εδώ θα προκαλούνταν λάθος μεταγλώττισης. - // O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια αξία i32, όχι την αξία την ίδια. + // O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια τιμή i32, όχι την τιμή την ίδια. // var2 = 2; // Λάθος μεταγλώττισης, γιατί η `var2` είναι δανεισμένη. ref_var2; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον // "δανεισμό" ενεργό diff --git a/elisp.html.markdown b/elisp.html.markdown index f839dac0..5d98ceff 100644 --- a/elisp.html.markdown +++ b/elisp.html.markdown @@ -3,6 +3,7 @@ language: elisp contributors: - ["Bastien Guerry", "https://bzg.fr"] - ["Saurabh Sandav", "http://github.com/SaurabhSandav"] + - ["rilysh", "https://github.com/rilysh"] filename: learn-emacs-lisp.el --- @@ -12,11 +13,11 @@ filename: learn-emacs-lisp.el ;; First make sure you read this text by Peter Norvig: ;; http://norvig.com/21-days.html ;; -;; Then install GNU Emacs 24.3: +;; Then install latest version of GNU Emacs: ;; ;; Debian: apt-get install emacs (or see your distro instructions) -;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg -;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip +;; OSX: https://emacsformacosx.com/ +;; Windows: https://ftp.gnu.org/gnu/emacs/windows/ ;; ;; More general information can be found at: ;; http://www.gnu.org/software/emacs/#Obtaining @@ -76,12 +77,12 @@ filename: learn-emacs-lisp.el ;; `C-j' inserts the result of the evaluation in the buffer. ;; `C-xC-e' displays the same result in Emacs bottom line, -;; called the "minibuffer". We will generally use `C-xC-e', +;; called the "echo area". We will generally use `C-xC-e', ;; as we don't want to clutter the buffer with useless text. ;; `setq' stores a value into a variable: (setq my-name "Bastien") -;; `C-xC-e' => "Bastien" (displayed in the mini-buffer) +;; `C-xC-e' => "Bastien" (displayed in the echo area) ;; `insert' will insert "Hello!" where the cursor is: (insert "Hello!") @@ -343,3 +344,9 @@ filename: learn-emacs-lisp.el ;; To read an online introduction to Emacs Lisp: ;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html ``` + +### Further Reading +- [GNU Elisp Manual](https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html) +- [Emacs Wiki](https://www.emacswiki.org/emacs/LearningEmacs) +- [Emacs Docs](https://emacsdocs.org/docs/elisp/Emacs-Lisp) +- [Mpre Elisp Docs](https://www.math.utah.edu/docs/info/elisp_22.html) diff --git a/elixir.html.markdown b/elixir.html.markdown index 9f96be49..2748a983 100644 --- a/elixir.html.markdown +++ b/elixir.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "https://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -13,16 +13,15 @@ It's fully compatible with Erlang, but features a more standard syntax and many more features. ```elixir - # Single line comments start with a number symbol. # There's no multi-line comment, # but you can stack multiple comments. -# To use the elixir shell use the `iex` command. +# To use the Elixir shell use the `iex` command. # Compile your modules with the `elixirc` command. -# Both should be in your path if you installed elixir correctly. +# Both should be in your path if you installed Elixir correctly. ## --------------------------- ## -- Basic types @@ -50,7 +49,7 @@ elem({1, 2, 3}, 0) #=> 1 head #=> 1 tail #=> [2,3] -# In elixir, just like in Erlang, the `=` denotes pattern matching and +# In Elixir, just like in Erlang, the `=` denotes pattern matching and # not an assignment. # # This means that the left-hand side (pattern) is matched against a @@ -83,7 +82,7 @@ string. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` in elixir returns the ASCII integer for the letter `a` +# `?a` in Elixir returns the ASCII integer for the letter `a` ?a #=> 97 # To concatenate lists use `++`, for binaries use `<>` @@ -116,7 +115,7 @@ genders.gillian #=> "female" 5 * 2 #=> 10 10 / 2 #=> 5.0 -# In elixir the operator `/` always returns a float. +# In Elixir the operator `/` always returns a float. # To do integer division use `div` div(10, 2) #=> 5 @@ -174,7 +173,7 @@ else "This will" end -# Remember pattern matching? Many control-flow structures in elixir rely on it. +# Remember pattern matching? Many control-flow structures in Elixir rely on it. # `case` allows us to compare a value against many patterns: case {:one, :two} do @@ -307,7 +306,7 @@ Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 -# Due to immutability, recursion is a big part of elixir +# Due to immutability, recursion is a big part of Elixir defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) @@ -382,7 +381,7 @@ end ## --------------------------- # Elixir relies on the actor model for concurrency. All we need to write -# concurrent programs in elixir are three primitives: spawning processes, +# concurrent programs in Elixir are three primitives: spawning processes, # sending messages and receiving messages. # To start a new process we use the `spawn` function, which takes a function diff --git a/elm.html.markdown b/elm.html.markdown index ad80adc9..bc7ba4cc 100644 --- a/elm.html.markdown +++ b/elm.html.markdown @@ -224,7 +224,7 @@ List.map : (a -> b) -> List a -> List b -- Comparable allows you to order numbers and strings, like a < b. -- Appendable things can be combined with a ++ b. -{-- Type Aliases and Union Types --} +{-- Type Aliases and Custom Types --} -- When you write a record or tuple, its type already exists. -- (Notice that record types use colon and record values use equals.) @@ -244,28 +244,28 @@ otherOrigin = -- But it's still the same type, so you can equate them. origin == otherOrigin -- True --- By contrast, defining a union type creates a type that didn't exist before. --- A union type is so called because it can be one of many possibilities. --- Each of the possibilities is represented as a "tag". +-- By contrast, defining a custom type creates a type that didn't exist before. +-- A custom type is so called because it can be one of many possibilities. +-- Each of the possibilities is represented as a "type variant". type Direction = North | South | East | West --- Tags can carry other values of known type. This can work recursively. +-- Type variants can carry other values of known type. This can work recursively. type IntTree = Leaf | Node Int IntTree IntTree --- "Leaf" and "Node" are the tags. Everything following a tag is a type. +-- "Leaf" and "Node" are the type variants. Everything following a type variant is a type. --- Tags can be used as values or functions. +-- Type variants can be used as values or functions. root : IntTree root = Node 7 Leaf Leaf --- Union types (and type aliases) can use type variables. +-- Custom types (and type aliases) can use type variables. type Tree a = Leaf | Node a (Tree a) (Tree a) -- "The type tree-of-a is a leaf, or a node of a, tree-of-a, and tree-of-a." --- Pattern match union tags. The uppercase tags will be matched exactly. The +-- Pattern match variants in a custom type. The uppercase variants will be matched exactly. The -- lowercase variables will match anything. Underscore also matches anything, -- but signifies that you aren't using it. leftmostElement : Tree a -> Maybe a @@ -289,7 +289,7 @@ module Name where -- By default, everything is exported. You can specify exports explicitly. module Name (MyType, myValue) where --- One common pattern is to export a union type but not its tags. This is known +-- One common pattern is to export a custom type but not its type variants. This is known -- as an "opaque type", and is frequently used in libraries. -- Import code from other modules to use it in this one. diff --git a/es-es/amd-es.html.markdown b/es-es/amd-es.html.markdown index 40aa6647..83c705c3 100644 --- a/es-es/amd-es.html.markdown +++ b/es-es/amd-es.html.markdown @@ -16,6 +16,7 @@ lang: es-es El API del **Módulo de Definición Asíncrono** especifica un mecanismo para definir módulos JavaScript de manera tal que tanto el módulo como sus dependencias puedan ser cargadas de manera asíncrona. Esto es particularmente adecuado para el entorno del navegador donde la carga sincronizada de los módulos genera problemas de rendimiento, usabilidad, depuración y acceso de multi-dominios. ### Conceptos básicos + ```javascript // El API básico de AMD consiste en tan solo dos métodos: `define` y `require` // y se basa en la definición y consumo de los módulos: @@ -137,6 +138,7 @@ require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolL coolLib.doFancyStuffWith(helpers.transform($('#foo'))); }); ``` + Las aplicaciones basadas en `require.js` usualmente tendrán un solo punto de entrada (`main.js`) que se pasa a la etiqueta del script `require.js` como un atributo de datos. Será cargado y ejecutado automáticamente al cargar la página: ```html @@ -158,16 +160,19 @@ Muchas personas prefieren usar AMD para la organización del código durante el `require.js` incluye un script llamado `r.js` (el que probablemente correrás en node.js, aunque Rhino también es soportado) que puede analizar el gráfico de dependencias de tu proyecto, y armar un solo fichero que contenga todos tus módulos (adecuadamente nombrados), minificado y listo para consumo. Instálalo usando `npm`: + ```shell $ npm install requirejs -g ``` Ahora puedes alimentarlo con un fichero de configuración: + ```shell $ r.js -o app.build.js ``` Para nuestro ejemplo anterior el archivo de configuración luciría así: + ```javascript /* file : app.build.js */ ({ @@ -184,6 +189,7 @@ Para nuestro ejemplo anterior el archivo de configuración luciría así: ``` Para usar el fichero creado en producción, simplemente intercambia `data-main`: + ```html <script src="require.js" data-main="app/main-built"></script> ``` diff --git a/es-es/asciidoc-es.html.markdown b/es-es/asciidoc-es.html.markdown index 6e357915..31406ee1 100644 --- a/es-es/asciidoc-es.html.markdown +++ b/es-es/asciidoc-es.html.markdown @@ -5,7 +5,7 @@ contributors: translators: - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] lang: es-es -filename: asciidoc-es.md +filename: asciidoc-es.adoc --- AsciiDoc es un lenguaje de marcas similar a Markdown que puede ser usado para cualquier uso, desde libros a blogs. diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 725dae1d..1ee12956 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -196,7 +196,7 @@ function string_functions( localvar, arr) { # Ambas regresan el número de matches remplazados. localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" - gsub("e", ".", localvar) # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar) # localvar => "M..t m. at th. bar" # Buscar una cadena que haga match con una expresión regular # index() hace lo mismo, pero no permite expresiones regulares diff --git a/es-es/chapel-es.html.markdown b/es-es/chapel-es.html.markdown new file mode 100644 index 00000000..732ee298 --- /dev/null +++ b/es-es/chapel-es.html.markdown @@ -0,0 +1,1219 @@ +--- +language: chapel +filename: learnchapel.chpl +contributors: + - ["Ian J. Bertolacci", "https://www.cs.arizona.edu/~ianbertolacci/"] + - ["Ben Harshbarger", "https://github.com/benharsh/"] +translators: + - ["Ivan Alburquerque", "https://github.com/AlburIvan"] +lang: es-es +--- + +Puede leer todo sobre Chapel en [el sitio web oficial de Chapel de Cray](https://chapel-lang.org). +En resumen, Chapel es un lenguaje de programación paralela, código abierto, de alta productividad +desarrolladp en Cray Inc. y está diseñado para ejecutarse en PC multi-nucleos, +así como en supercomputadoras multi-kilocore. + + +Puede encontrar más información y asistencia al final de este documento. + +```chapel +// Los comentarios son de estilo de la familia C + +// comentario de una línea +/* + comentario de múltiples lineas +*/ + +// Impresión básica + +write("Hola, "); +writeln("Mundo!"); + +// write y writeln pueden tomar una lista de cosas para imprimir. +// Cada cosa está impresa justo al lado de las demás, ¡así que incluye espacios! +writeln("hay ", 3, " comas (\",\") en esta línea de código"); + +// Diferentes canales de salida: +stdout.writeln("Esto va a la salida estándar, al igual que lo hace writeln()"); +stderr.writeln("Esto va al error estándar"); + + +// Las variables no tienen que escribirse explícitamente +// mientras el compilador pueda determinar el tipo que contendrá. + +// 10 es un entero, asi que myVar es explícitamente un entero +var myVar = 10; +myVar = -10; +var mySecondVar = myVar; +// var anError; sería un error en tiempo de compilación + +// Podemos (y debemos) escribir cosas explícitamente. +var myThirdVar: real; +var myFourthVar: real = -1.234; +myThirdVar = myFourthVar; + +// Tipos + +// Hay varios tipos básicos. +var myInt: int = -1000; // Enteros firmados +var myUint: uint = 1234; // Enteros sin-firmar +var myReal: real = 9.876; // Números de punto flotante +var myImag: imag = 5.0i; // Números imaginarios +var myCplx: complex = 10 + 9i; // Números complejos +myCplx = myInt + myImag; // Otra manera de formar números complejos +var myBool: bool = false; // Booleanos +var myStr: string = "Una cadena..."; // Cadenas +var singleQuoteStr = 'Otra cadena...'; // Cadena literal con comillas simples + +// Algunos tipos pueden tener tamaños. +var my8Int: int(8) = 10; // Entero de 8 bit (one byte); +var my64Real: real(64) = 1.516; // Real de 64 bit (8 bytes) + +// Conversion de tipos. +var intFromReal = myReal : int; +var intFromReal2: int = myReal : int; + +// Alias de tipo. +type chroma = int; // Tipo de un solo tono +type RGBColor = 3*chroma; // Tipo que representa un color completo +var black: RGBColor = (0,0,0); +var white: RGBColor = (255, 255, 255); + +// Constantes y Parámetros + +// una variable const es una constante y no se puede cambiar después de +// establecerla en tiempo de ejecución. +const almostPi: real = 22.0/7.0; + +// Un parámetro es una constante cuyo valor debe conocerse estáticamente +// en tiempo de compilación. + +param compileTimeConst: int = 16; + +// El modificador de configuración permite establecer valores en la línea de comando. +// Establece valores con --varCmdLineArg=Value o --varCmdLineArg Value en tiempo de ejecución. +config var varCmdLineArg: int = -123; +config const constCmdLineArg: int = 777; + +// config param se puede configurar en tiempo de compilación. +// Establece valores con --set paramCmdLineArg=value en tiempo de compilación. +config param paramCmdLineArg: bool = false; +writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg); + +// Referencias + +// ref funciona de manera muy similar a una referencia en C ++. En Chapel, +// no se puede hacer una referencia como alias a una variable distinta +// de la variable con la que se inicializa. + +// Aquí, refToActual se refiere a actual. +var actual = 10; +ref refToActual = actual; +writeln(actual, " == ", refToActual); // imprime el mismo valor +actual = -123; // modificar actual (a lo que refToActual se refiere) +writeln(actual, " == ", refToActual); // imprime el mismo valor +refToActual = 99999999; // modificar a qué se refiere refToActual (que es actual) +writeln(actual, " == ", refToActual); // imprime el mismo valor + +// Operadores + +// Operadores matemáticos: +var a: int, thisInt = 1234, thatInt = 5678; +a = thisInt + thatInt; // Adicción +a = thisInt * thatInt; // Multiplicación +a = thisInt - thatInt; // Substracción +a = thisInt / thatInt; // División +a = thisInt ** thatInt; // Exponenciación +a = thisInt % thatInt; // residuo (módulo) + +// Operadores logicos: +var b: bool, thisBool = false, thatBool = true; +b = thisBool && thatBool; // Lógico y +b = thisBool || thatBool; // Lógico o +b = !thisBool; // Lógico negación + +// Operadores relacionales: +b = thisInt > thatInt; // Mas grande que +b = thisInt >= thatInt; // Mas grande o igual que +b = thisInt < a && a <= thatInt; // Menor que, y, Menor o igual que +b = thisInt != thatInt; // No es igual a +b = thisInt == thatInt; // es igual a + +// Operadores bit a bit: +a = thisInt << 10; // Desplazamiento de bit izquierdo por 10 bits; +a = thatInt >> 5; // Desplazamiento de bit derecho por 5 bits; +a = ~thisInt; // Negación bit a bit +a = thisInt ^ thatInt; // bit a bit exclusivo o + +// Operadores de asignación compuesta: +a += thisInt; // Adición-igual (a = a + thisInt;) +a *= thatInt; // Multiplicación-igual (a = a * thatInt;) +b &&= thatBool; // Lógico e igual (b = b && thatBool;) +a <<= 3; // Desplazamiento a la izquierda igual (a = a << 10;) + +// A diferencia de otros lenguajes de familia C, no hay operadores de +// pre / post-incremento / decremento, tales como: +// +// ++j, --j, j++, j-- + +// Operador de intercambio: +var old_this = thisInt; +var old_that = thatInt; +thisInt <=> thatInt; // Intercambia los valores de thisInt y thatInt +writeln((old_this == thatInt) && (old_that == thisInt)); + +// También se pueden definir sobrecargas del operador, como veremos con los procedimientos. + +// Tuplas + +// Las tuplas pueden ser del mismo tipo o de diferentes tipos. +var sameTup: 2*int = (10, -1); +var sameTup2 = (11, -6); +var diffTup: (int,real,complex) = (5, 1.928, myCplx); +var diffTupe2 = (7, 5.64, 6.0+1.5i); + +// Se puede acceder a las tuplas usando corchetes o paréntesis, +// y están indexadas en base 1. +writeln("(", sameTup[1], ",", sameTup(2), ")"); +writeln(diffTup); + +// Las tuplas también se pueden escribir. +diffTup(1) = -1; + +// Los valores de tupla se pueden expandir a sus propias variables. +var (tupInt, tupReal, tupCplx) = diffTup; +writeln(diffTup == (tupInt, tupReal, tupCplx)); + +// También son útiles para imprimit una lista de variables, +// como es común en la depuración. +writeln((a,b,thisInt,thatInt,thisBool,thatBool)); + +// Flujo de control + +// if - then - else funciona como cualquier otro lenguaje de la familia C. +if 10 < 100 then + writeln("All is well"); + +if -1 < 1 then + writeln("Continuando creyendo en la realidad"); +else + writeln("¡Envia un matemático!, algo está mal"); + +// Puedes usar paréntesis si lo prefieres. +if (10 > 100) { + writeln("El Universo está roto, Por favor reinicie el universo."); +} + +if a % 2 == 0 { + writeln(a, " es par."); +} else { + writeln(a, " es impar."); +} + +if a % 3 == 0 { + writeln(a, " es divisible entre 3."); +} else if a % 3 == 1 { + writeln(a, " es divisible entre 3 con un residuo de 1."); +} else { + writeln(b, " es divisible entre 3 con un residuo de 2."); +} + +// Ternario: if - then - else en una declaración. +var maximum = if thisInt < thatInt then thatInt else thisInt; + +// las declaraciones select son muy parecidas a las declaraciones switch +// en otros idiomas. Sin embargo, las declaraciones select no caen +// en cascada como en C o Java. +var inputOption = "anOption"; +select inputOption { + when "anOption" do writeln("Escoge 'anOption'"); + when "otherOption" { + writeln("Escoge 'otherOption'"); + writeln("Que tiene un cuerpo"); + } + otherwise { + writeln("Cualquier otra entrada"); + writeln("El caso otherwise no necesita hacerse si el cuerpo es de una línea"); + } +} + +// Los bucles while y do-while también se comportan como sus contrapartes en C. +var j: int = 1; +var jSum: int = 0; +while (j <= 1000) { + jSum += j; + j += 1; +} +writeln(jSum); + +do { + jSum += j; + j += 1; +} while (j <= 10000); +writeln(jSum); + +// Los bucles for son muy parecidos a los de Python porque iteran en un rango. +// Los rangos (como la expresión 1..10 a continuación) son un objeto de primera clase +// en Chapel, y como tal pueden almacenarse en variables. +for i in 1..10 do write(i, ", "); +writeln(); + +var iSum: int = 0; +for i in 1..1000 { + iSum += i; +} +writeln(iSum); + +for x in 1..10 { + for y in 1..10 { + write((x,y), "\t"); + } + writeln(); +} + +// Rangos y Dominios + +// Los bucles y matrices utilizan rangos y dominios para definir un conjunto de índices +// que se pueden iterar. Los rangos son índices enteros unidimensionales, mientras +// que los dominios pueden ser multidimensionales y representan índices +// de diferentes tipos. + +// Son tipos ciudadanos de primera clase y pueden asignarse a variables. +var range1to10: range = 1..10; // 1, 2, 3, ..., 10 +var range2to11 = 2..11; // 2, 3, 4, ..., 11 +var rangeThisToThat: range = thisInt..thatInt; // usando variables +var rangeEmpty: range = 100..-100; // esto es válido pero no contiene índices + +// Los rangos pueden ser ilimitados. +var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ; // 1, 2, 3, 4, 5, ... +var rangeNegInfTo1 = ..1; // ..., -4, -3, -2, -1, 0, 1 + +// Los rangos se pueden andar (y revertir) utilizando el operador by. +var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10 +var reverse2to10by2 = 2..10 by -2; // 10, 8, 6, 4, 2 + +var trapRange = 10..1 by -1; // No te dejes engañar, esto sigue siendo un rango vacío +writeln("Size of range ", trapRange, " = ", trapRange.length); + +// Note: range(boundedType= ...) and range(stridable= ...) solo son necesarios +// si escribimos explícitamente la variable. + +// El punto final de un rango se puede determinar utilizando el operador de conteo (#). +var rangeCount: range = -5..#12; // intervalo de -5 to 6 + +// Los operadores pueden ser mixtos. +var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5 +writeln(rangeCountBy); + +// Se pueden consultar las propiedades del rango. +// En este ejemplo, imprime el primer índice, el último índice, el número de índices, +// el paso y si 2 se incluye en el rango. +writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.length, + rangeCountBy.stride, rangeCountBy.member(2))); + +for i in rangeCountBy { + write(i, if i == rangeCountBy.last then "\n" else ", "); +} + +// Los dominios rectangulares se definen usando la misma sintaxis de rango, +// pero se requiere que estén delimitados (a diferencia de los rangos). +var domain1to10: domain(1) = {1..10}; // 1D domain from 1..10; +var twoDimensions: domain(2) = {-2..2,0..2}; // 2D domain over product of ranges +var thirdDim: range = 1..16; +var threeDims: domain(3) = {thirdDim, 1..10, 5..10}; // using a range variable + +// Los dominios también pueden ser redimensionados +var resizedDom = {1..10}; +writeln("antes, resizedDom = ", resizedDom); +resizedDom = {-10..#10}; +writeln("despues, resizedDom = ", resizedDom); + +// Los índices pueden iterarse como tuplas. +for idx in twoDimensions do + write(idx, ", "); +writeln(); + +// Estas tuplas también pueden ser deconstruidas. +for (x,y) in twoDimensions { + write("(", x, ", ", y, ")", ", "); +} +writeln(); + +// Los dominios asociativos actúan como conjuntos. +var stringSet: domain(string); // empty set of strings +stringSet += "a"; +stringSet += "b"; +stringSet += "c"; +stringSet += "a"; // Redundant add "a" +stringSet -= "c"; // Remove "c" +writeln(stringSet.sorted()); + +// Los dominios asociativos también pueden tener una sintaxis literal +var intSet = {1, 2, 4, 5, 100}; + +// Tanto los rangos como los dominios se pueden dividir para producir un rango +// o dominio con la intersección de los índices. +var rangeA = 1.. ; // range from 1 to infinity +var rangeB = ..5; // range from negative infinity to 5 +var rangeC = rangeA[rangeB]; // resulting range is 1..5 +writeln((rangeA, rangeB, rangeC)); + +var domainA = {1..10, 5..20}; +var domainB = {-5..5, 1..10}; +var domainC = domainA[domainB]; +writeln((domainA, domainB, domainC)); + +// Matrices + +// Las matrices son similares a otros lenguajes. +// Sus tamaños son definidos usndo dominions que repretsenten sus indices. +var intArray: [1..10] int; +var intArray2: [{1..10}] int; // equivalent + +// Pueden ser accedidos usando brackets o paréntesis +for i in 1..10 do + intArray[i] = -i; +writeln(intArray); + +// No podemos acceder a intArray[0] porque existe fuera del conjunto de índices, +// {1..10}, que definimos al principio. +// intArray [11] es ilegal por la misma razón. +var realDomain: domain(2) = {1..5,1..7}; +var realArray: [realDomain] real; +var realArray2: [1..5,1..7] real; // equivalent +var realArray3: [{1..5,1..7}] real; // equivalent + +for i in 1..5 { + for j in realDomain.dim(2) { // Solo use la segunda dimensión del dominio + realArray[i,j] = -1.61803 * i + 0.5 * j; // Acceso usando la lista de índice + var idx: 2*int = (i,j); // Nota: 'índice' es una palabra reservada + realArray[idx] = - realArray[(i,j)]; // Indice usando tuplas + } +} + +// Las matrices tienen dominios como miembros y pueden ser iterados de manera normal. +for idx in realArray.domain { // De nuevo, idx es una tupla 2*int + realArray[idx] = 1 / realArray[idx[1], idx[2]]; // Acceso por tupla y lista +} + +writeln(realArray); + +// Los valores de una matriz también se pueden iterar directamente. +var rSum: real = 0; +for value in realArray { + rSum += value; // Read a value + value = rSum; // Write a value +} +writeln(rSum, "\n", realArray); + +// Las matrices asociativas (diccionarios) se pueden crear utilizando dominios asociativos. +var dictDomain: domain(string) = { "one", "two" }; +var dict: [dictDomain] int = ["one" => 1, "two" => 2]; +dict["three"] = 3; // Adiciona 'three' a 'dictDomain' implícitamente +for key in dictDomain.sorted() do + writeln(dict[key]); + +// Las matrices se pueden asignar entre sí de diferentes maneras. +// Estos arreglos se usarán en el ejemplo. + +var thisArray : [0..5] int = [0,1,2,3,4,5]; +var thatArray : [0..5] int; + +// Primero, simplemente asigna uno al otro. Esto copia esta matriz en +// thatArray, en lugar de simplemente crear una referencia. Por lo tanto, modificando +// thisArray tampoco modifica thatArray. +thatArray = thisArray; +thatArray[1] = -1; +writeln((thisArray, thatArray)); + +// Asigna un segmento de una matriz a un segmento (del mismo tamaño) en el otro. +thatArray[4..5] = thisArray[1..2]; +writeln((thisArray, thatArray)); + +// Las operaciones también se pueden promover para trabajar en arreglos. +// 'thisPlusThat' también es una matriz. +var thisPlusThat = thisArray + thatArray; +writeln(thisPlusThat); + +// Continuando, las matrices y los bucles también pueden ser expresiones, donde +// la expresión del cuerpo del bucle es el resultado de cada iteración. +var arrayFromLoop = for i in 1..10 do i; +writeln(arrayFromLoop); + +// Una expresión puede resultar en nada, como cuando se filtra con una expresión if. +var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i; + +writeln(arrayFromLoop); + +// Las expresiones de matriz también se pueden escribir con una notación de paréntesis. +// Nota: esta sintaxis utiliza el concepto paralelo forall discutido más adelante. +var evensOrFivesAgain = [i in 1..10] if (i % 2 == 0 || i % 5 == 0) then i; + +// They can also be written over the values of the array. +arrayFromLoop = [value in arrayFromLoop] value + 1; + + +// Procedimientos + +// Los procedimientos de Chapel tienen funciones de sintaxis similares en otros idiomas. +proc fibonacci(n : int) : int { + if n <= 1 then return n; + return fibonacci(n-1) + fibonacci(n-2); +} + +// Los parámetros de entrada pueden estar sin tipo para crear un procedimiento genérico. +proc doublePrint(thing): void { + write(thing, " ", thing, "\n"); +} + +// Se puede inferir el tipo de retorno, siempre que el compilador pueda resolverlo. +proc addThree(n) { + return n + 3; +} + +doublePrint(addThree(fibonacci(20))); + +// También es posible tomar un número variable de parámetros. +proc maxOf(x ...?k) { + // x se refiere a una tupla de un tipo, con k elementos + var maximum = x[1]; + for i in 2..k do maximum = if maximum < x[i] then x[i] else maximum; + return maximum; +} +writeln(maxOf(1, -10, 189, -9071982, 5, 17, 20001, 42)); + +// Los procedimientos pueden tener valores de parámetros predeterminados, y +// los parámetros pueden nombrarse en la llamada, incluso fuera de orden. +proc defaultsProc(x: int, y: real = 1.2634): (int,real) { + return (x,y); +} + +writeln(defaultsProc(10)); +writeln(defaultsProc(x=11)); +writeln(defaultsProc(x=12, y=5.432)); +writeln(defaultsProc(y=9.876, x=13)); + +// El operador ? se llama operador de consulta y se usa para tomar valores +// indeterminados como tuplas o tamaños de matriz y tipos genéricos. +// Por ejemplo, tomar matrices como parámetros. + +// El operador de consulta se utiliza para determinar el dominio de A. +// Esto es útil para definir el tipo de retorno, aunque no es obligatorio. +proc invertArray(A: [?D] int): [D] int{ + for a in A do a = -a; + return A; +} + +writeln(invertArray(intArray)); + +// Podemos consultar el tipo de argumentos a los procedimientos genéricos. +// Aquí definimos un procedimiento que toma dos argumentos del mismo tipo, +// pero no definimos cuál es ese tipo. +proc genericProc(arg1 : ?valueType, arg2 : valueType): void { + select(valueType) { + when int do writeln(arg1, " and ", arg2, " are ints"); + when real do writeln(arg1, " and ", arg2, " are reals"); + otherwise writeln(arg1, " and ", arg2, " are somethings!"); + } +} + +genericProc(1, 2); +genericProc(1.2, 2.3); +genericProc(1.0+2.0i, 3.0+4.0i); + +// También podemos imponer una forma de polimorfismo con la cláusula where +// Esto permite que el compilador decida qué función usar. + +// Nota: Eso significa que toda la información debe conocerse en tiempo de compilación. +// El modificador param en el argumento se usa para imponer esta restricción. +proc whereProc(param N : int): void + where (N > 0) { + writeln("N is greater than 0"); +} + +proc whereProc(param N : int): void + where (N < 0) { + writeln("N is less than 0"); +} + +whereProc(10); +whereProc(-1); + +// whereProc(0) daría lugar a un error del compilador porque no hay funciones +// que satisfagan la condición de la cláusula where. +// Podríamos haber definido un whereProc sin una cláusula where que +// hubiera servido como captura para todos los demás casos (de los cuales solo hay uno). + +// Las cláusulas where también se pueden usar para restringir según el tipo de argumento. +proc whereType(x: ?t) where t == int { + writeln("Inside 'int' version of 'whereType': ", x); +} + +proc whereType(x: ?t) { + writeln("Inside general version of 'whereType': ", x); +} + +whereType(42); +whereType("hello"); + +// Intenciones + +/* Los modificadores de intención en los argumentos transmiten cómo esos argumentos se pasan al procedimiento. + + * in: copia arg adentro, pero no afuera + * out: copia arg, pero no dentro + * inout: copia arg adentro, copia arg afuera + * ref: pasa arg por referencia +*/ +proc intentsProc(in inarg, out outarg, inout inoutarg, ref refarg) { + writeln("Adentro antes: ", (inarg, outarg, inoutarg, refarg)); + inarg = inarg + 100; + outarg = outarg + 100; + inoutarg = inoutarg + 100; + refarg = refarg + 100; + writeln("Adentro después: ", (inarg, outarg, inoutarg, refarg)); +} + +var inVar: int = 1; +var outVar: int = 2; +var inoutVar: int = 3; +var refVar: int = 4; +writeln("Afuera antes: ", (inVar, outVar, inoutVar, refVar)); +intentsProc(inVar, outVar, inoutVar, refVar); +writeln("Afuera después: ", (inVar, outVar, inoutVar, refVar)); + +// Del mismo modo, podemos definir intentos en el tipo de retorno. +// refElement devuelve una referencia a un elemento de la matriz. Esto tiene más sentido +// práctico para los métodos de clase donde las referencias a elementos en una estructura +// de datos se devuelven a través de un método o iterador. +proc refElement(array : [?D] ?T, idx) ref : T { + return array[idx]; +} + +var myChangingArray : [1..5] int = [1,2,3,4,5]; +writeln(myChangingArray); +ref refToElem = refElement(myChangingArray, 5); // Almacena una referencia al elemento en variable de referencia +writeln(refToElem); +refToElem = -2; // modifica referencia que, a su vez, modifica el valor real en la matriz +writeln(refToElem); +writeln(myChangingArray); + +// Definiciones del operador + +// Chapel permite que los operadores se sobrecarguen. +// Podemos definir los operadores unarios: +// + - ! ~ +// y los operadores binarios: +// + - * / % ** == <= >= < > << >> & | ˆ by +// += -= *= /= %= **= &= |= ˆ= <<= >>= <=> + +// Exclusivo u operador booleano. +proc ^(left : bool, right : bool): bool { + return (left || right) && !(left && right); +} + +writeln(true ^ true); +writeln(false ^ true); +writeln(true ^ false); +writeln(false ^ false); + +// Define un operador * en cualquiera de los dos tipos que devuelve una tupla de esos tipos. +proc *(left : ?ltype, right : ?rtype): (ltype, rtype) { + writeln("\tIn our '*' overload!"); + return (left, right); +} + +writeln(1 * "a"); // Utiliza nuestro * operador. +writeln(1 * 2); // Utiliza el operador predeterminado *. + +// Note: Podrías romper todo si te descuidas con tus sobrecargas. +// Esto aquí lo romperá todo. No lo hagas + +/* + proc +(left: int, right: int): int { + return left - right; + } +*/ + +// Iteradores + +// Los iteradores son hermanas del procedimiento, y casi todo lo relacionado +// con los procedimientos también se aplica a los iteradores. Sin embargo, en lugar de +// devolver un solo valor, los iteradores pueden generar múltiples valores en un bucle. + +// Esto es útil cuando se necesita un conjunto u orden complicado de iteraciones, +// ya que permite que el código que define las iteraciones +// se separe del cuerpo del bucle. +iter oddsThenEvens(N: int): int { + for i in 1..N by 2 do + yield i; // yield values instead of returning. + for i in 2..N by 2 do + yield i; +} + +for i in oddsThenEvens(10) do write(i, ", "); +writeln(); + +// Los iteradores también pueden ceder condicionalmente, cuyo resultado puede ser nada +iter absolutelyNothing(N): int { + for i in 1..N { + if N < i { // Always false + yield i; // Yield statement never happens + } + } +} + +for i in absolutelyNothing(10) { + writeln("Woa there! absolutelyNothing yielded ", i); +} + +// Podemos comprimir dos o más iteradores (que tienen el mismo número de iteraciones) +// usando zip () para crear un solo iterador comprimido, donde cada iteración +// del iterador comprimido produce una tupla de un valor de cada iterador. +for (positive, negative) in zip(1..5, -5..-1) do + writeln((positive, negative)); + +// La iteración de la cremallera es bastante importante en la asignación de matrices, +// segmentos de matrices y expresiones de matriz / bucle. +var fromThatArray : [1..#5] int = [1,2,3,4,5]; +var toThisArray : [100..#5] int; + +// Algunas operaciones de cierre implementan otras operaciones. +// La primera declaración y el bucle son equivalentes. +toThisArray = fromThatArray; +for (i,j) in zip(toThisArray.domain, fromThatArray.domain) { + toThisArray[i] = fromThatArray[j]; +} + +// Estos dos pedazos también son equivalentes. +toThisArray = [j in -100..#5] j; +writeln(toThisArray); + +for (i, j) in zip(toThisArray.domain, -100..#5) { + toThisArray[i] = j; +} +writeln(toThisArray); + +/* + Esto es muy importante para entender por qué esta declaración + exhibe un error de tiempo de ejecución. +*/ + +/* + var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i; +*/ + +// Aunque el dominio de la matriz y la expresión de bucle son del mismo tamaño, +// el cuerpo de la expresión puede considerarse como un iterador. +// Debido a que los iteradores pueden producir nada, ese iterador produce un número +// diferente de cosas que el dominio de la matriz o bucle, que no está permitido. + +// Clases + +// Las clases son similares a las de C ++ y Java, asignadas en el montón. +class MyClass { + +// Variables miembro + var memberInt : int; + var memberBool : bool = true; + +// Inicializador definido explícitamente. +// También obtenemos el inicializador generado por el compilador, con un argumento por campo. +// Tenga en cuenta que pronto no habrá un inicializador generado por el compilador +// cuando definamos los inicializadores explícitamente. + proc init(val : real) { + this.memberInt = ceil(val): int; + } + +// Desinicializador explícitamente definido. +// Si no escribiéramos uno, obtendríamos el desinicializador generado por el compilador, +// que tiene un cuerpo vacío. + proc deinit() { + writeln("MyClass deinitializer called ", (this.memberInt, this.memberBool)); + } + +// Métodos de clase. + proc setMemberInt(val: int) { + this.memberInt = val; + } + + proc setMemberBool(val: bool) { + this.memberBool = val; + } + + proc getMemberInt(): int{ + return this.memberInt; + } + + proc getMemberBool(): bool { + return this.memberBool; + } +} // termina MyClass + +// Llame al inicializador generado por el compilador, +// utilizando el valor predeterminado para memberBool. +var myObject = new MyClass(10); + myObject = new MyClass(memberInt = 10); // Equivalente +writeln(myObject.getMemberInt()); + +// Same, but provide a memberBool value explicitly. +var myDiffObject = new MyClass(-1, true); + myDiffObject = new MyClass(memberInt = -1, memberBool = true); // Equivalente +writeln(myDiffObject); + +// Llame al inicializador que escribimos. +var myOtherObject = new MyClass(1.95); + myOtherObject = new MyClass(val = 1.95); // Equivalente +writeln(myOtherObject.getMemberInt()); + +// También podemos definir un operador en nuestra clase, +// pero la definición tiene que estar fuera de la definición de la clase. +proc +(A : MyClass, B : MyClass) : MyClass { + return new MyClass(memberInt = A.getMemberInt() + B.getMemberInt(), + memberBool = A.getMemberBool() || B.getMemberBool()); +} + +var plusObject = myObject + myDiffObject; +writeln(plusObject); + +// Destrucción. +delete myObject; +delete myDiffObject; +delete myOtherObject; +delete plusObject; + +// Las clases pueden heredar de una o más clases primarias +class MyChildClass : MyClass { + var memberComplex: complex; +} + +// Aquí hay un ejemplo de clases genéricas. +class GenericClass { + type classType; + var classDomain: domain(1); + var classArray: [classDomain] classType; + +// Constructor explícito. + proc GenericClass(type classType, elements : int) { + this.classDomain = {1..#elements}; + } + +// Copiar constructor. +// Nota: Todavía tenemos que poner el tipo como argumento, pero podemos usar +// el operador de consulta (?) como predeterminado para el tipo del otro objeto. +// Además, podemos aprovechar esto para permitir a nuestro constructor de copias +// copiar clases de diferentes tipos y emitir sobre la marcha. + proc GenericClass(other : GenericClass(?otherType), + type classType = otherType) { + this.classDomain = other.classDomain; + // Copiar y Convertir + for idx in this.classDomain do this[idx] = other[idx] : classType; + } + +// Defina la notación de corchetes en un objeto GenericClass +// para que pueda comportarse como una matriz normal +// i.e. objVar[i] or objVar(i) + proc this(i : int) ref : classType { + return this.classArray[i]; + } + +// Definir un iterador implícito para que la clase produzca +// valores de la matriz a un bucle +// i.e. for i in objVar do ... + iter these() ref : classType { + for i in this.classDomain do + yield this[i]; + } +} // end GenericClass + +// Podemos asignar a la matriz de miembros del objeto usando la notación de +// corchete que definimos. +var realList = new GenericClass(real, 10); +for i in realList.classDomain do realList[i] = i + 1.0; + +// Podemos iterar sobre los valores en nuestra lista con el iterador +// que definimos. +for value in realList do write(value, ", "); +writeln(); + +// Haga una copia de realList usando el constructor de copias. +var copyList = new GenericClass(realList); +for value in copyList do write(value, ", "); +writeln(); + +// Haga una copia de realList y cambie el tipo, también utilizando el constructor de copias. +var copyNewTypeList = new GenericClass(realList, int); +for value in copyNewTypeList do write(value, ", "); +writeln(); + + +// Módulos + +// Los módulos son la forma en que Chapel administra los espacios de nombres. +// Los archivos que contienen estos módulos no necesitan ser nombrados después +// de los módulos (como en Java), pero los archivos implícitamente nombran módulos. +// Por ejemplo, este archivo nombra implícitamente el módulo learnChapelInYMinutes + +module OurModule { + +// Podemos usar módulos dentro de otros módulos. +// Time es uno de los módulos estándar. + use Time; + +// Usaremos este procedimiento en la sección de paralelismo. + proc countdown(seconds: int) { + for i in 1..seconds by -1 { + writeln(i); + sleep(1); + } + } + +// Es posible crear nidos de módulos arbitrariamente profundos. +// i.e. submódulos de OurModule + module ChildModule { + proc foo() { + writeln("ChildModule.foo()"); + } + } + + module SiblingModule { + proc foo() { + writeln("SiblingModule.foo()"); + } + } +} // end OurModule + +// Usando OurModule también usa todos los módulos que usa. +// Como OurModule usa Time, nosotros también usamos Time. +use OurModule; + +// En este punto no hemos usado ChildModule o SiblingModule, por lo que sus símbolos +// (es decir, foo) no están disponibles para nosotros. Sin embargo, los nombres de +// los módulos están disponibles y podemos llamar explícitamente a foo () a través de ellos. +SiblingModule.foo(); +OurModule.ChildModule.foo(); + +// Ahora usamos ChildModule, que permite llamadas no calificadas. +use ChildModule; +foo(); + +// Paralelismo + +// En otros idiomas, el paralelismo generalmente se realiza con librerias complicadas +// y extrañas jerarquías de estructura de clases. +// Chapel lo tiene directamente en el idioma. + +// Podemos declarar un procedimiento principal, pero todo el código anterior +// a main todavía se ejecuta. +proc main() { + +// Una declaración de inicio hará girar el cuerpo de esa declaración en una nueva tarea. +// Una declaración de sincronización garantizará que el progreso de la tarea principal +// no avance hasta que los hijos hayan sincronizado nuevamente. + + sync { + begin { // Inicio del cuerpo de la nueva tarea. + var a = 0; + for i in 1..1000 do a += 1; + writeln("Done: ", a); + } // Fin del nuevo cuerpo de tareas + writeln("escindió una tarea!"); + } + writeln("De nuevo juntos"); + + proc printFibb(n: int) { + writeln("fibonacci(",n,") = ", fibonacci(n)); + } + +// Una declaración de cobegin girará cada declaración del cuerpo en una nueva tarea. +// Observe aquí que las impresiones de cada declaración pueden ocurrir en +// cualquier orden. + cobegin { + printFibb(20); // nueva tarea + printFibb(10); // nueva tarea + printFibb(5); // nueva tarea + { + // Este es un cuerpo de declaración anidado y, por lo tanto, es una + // declaración única para la declaración principal, ejecutada + // por una sola tarea. + writeln("esto se "); + writeln("ejecuta"); + writeln("como un todo"); + } + } + +// Un bucle coforall creará una nueva tarea para CADA iteración. +// Nuevamente vemos que las impresiones suceden en cualquier orden. +// NOTA: ¡coforall debe usarse solo para crear tareas! +// ¡Usarlo para iterar sobre una estructura es una muy mala idea! + var num_tasks = 10; // Number of tasks we want + coforall taskID in 1..#num_tasks { + writeln("Hola de tarea# ", taskID); + } + +// los bucles forall son otro bucle paralelo, pero solo crean un número +// menor de tareas, específicamente --dataParTasksPerLocale = número de tareas. + forall i in 1..100 { + write(i, ", "); + } + writeln(); + +// Aquí vemos que hay secciones que están en orden, seguidas de una sección +// que no seguiría (por ejemplo, 1, 2, 3, 7, 8, 9, 4, 5, 6,). +// Esto se debe a que cada tarea está asumiendo un fragmento del rango 1..10 +// (1..3, 4..6 o 7..9) haciendo ese fragmento en serie, pero cada tarea ocurre en paralelo. +// Sus resultados pueden depender de su máquina y configuración + +// Para los bucles forall y coforall, la ejecución de la tarea principal +// no continuará hasta que todos los hijos se sincronicen. + +// los bucles forall son particularmente útiles para la iteración paralela sobre matrices. +// Hagamos un experimento para ver qué tan rápido es un ciclo paralelo. + + use Time; // Importe el módulo Time para usar objetos de Timer + var timer: Timer; + var myBigArray: [{1..4000,1..4000}] real; // Gran matriz en la que escribiremos + +// Experimento en serie: + timer.start(); // Iniciar temporizador + for (x,y) in myBigArray.domain { // Iteración en serie + myBigArray[x,y] = (x:real) / (y:real); + } + timer.stop(); // Detener temporizador + writeln("Serial: ", timer.elapsed()); // Imprimir tiempo transcurrido + timer.clear(); // Limpia el temporizador para bucle paralelo + +// Experimento Paralelo: + timer.start(); // Iniciar temporizador + forall (x,y) in myBigArray.domain { // Iteración paralela + myBigArray[x,y] = (x:real) / (y:real); + } + timer.stop(); // Detener temporizador + writeln("Parallel: ", timer.elapsed()); // Imprimir tiempo transcurrido + timer.clear(); + +// Puede que hayas notado que (dependiendo de cuántos núcleos tengas) +// el ciclo paralelo fue más rápido que el ciclo serial. + +// La expresión de bucle estilo corchete descrita mucho antes utiliza +// implícitamente un bucle forall. + [val in myBigArray] val = 1 / val; // Operación paralela + +// Las variables atómicas, comunes a muchos idiomas, son aquellas cuyas operaciones +// ocurren sin interrupciones. Por lo tanto, varios subprocesos pueden modificar +// las variables atómicas y pueden saber que sus valores son seguros. +// Las variables atómicas de la capilla pueden ser de tipo bool, int, uint y real. + var uranium: atomic int; + uranium.write(238); // escribir atómicamente una variable + writeln(uranium.read()); // leer atómicamente una variable + +// Las operaciones atómicas se describen como funciones, por lo que puede definir +// las suyas propias. + uranium.sub(3); // restar atómicamente una variable + writeln(uranium.read()); + + var replaceWith = 239; + var was = uranium.exchange(replaceWith); + writeln("El uranio era", was, ", pero ahora es ", replaceWith); + + var isEqualTo = 235; + if uranium.compareExchange(isEqualTo, replaceWith) { + writeln("El uranio era igual a ", isEqualTo, + " pero valor reemplazado por", replaceWith); + } else { + writeln("uranio no era igual a ", isEqualTo, + " así que el valor permanece igual... sea lo que sea"); + } + + sync { + begin { // Tarea del lector + writeln("Lector: esperando que el uranio sea ", isEqualTo); + uranium.waitFor(isEqualTo); + writeln("Lector: el uranio fue configurado (por alguien) para ", isEqualTo); + } + + begin { // Tarea de escritor + writeln("Escritor: establecerá uranio en el valor ", isEqualTo, " en..."); + countdown(3); + uranium.write(isEqualTo); + } + } + +// las variables de sincronización tienen dos estados: vacío y lleno. +// Si lee una variable vacía o escribe una variable completa, +// se espera hasta que la variable esté llena o vacía nuevamente. + var someSyncVar$: sync int; // varName$ Es una convención, no una ley. + sync { + begin { // Tarea del lector + writeln("Lector: esperando leer."); + var read_sync = someSyncVar$; + writeln("Lector: el valor es ", read_sync); + } + + begin { // Tarea de escritor + writeln("Escritor: escribirá en..."); + countdown(3); + someSyncVar$ = 123; + } + } + +// las variales individuales solo se pueden escribir una vez. +// Una lectura en un solo no escrito da como resultado una espera, +// pero cuando la variable tiene un valor, puede leerse indefinidamente. + var someSingleVar$: single int; // varName$ Es una convención, no una ley. + sync { + begin { // Tarea del lector + writeln("Lector: esperando leer."); + for i in 1..5 { + var read_single = someSingleVar$; + writeln("Lector: iteración ", i,", y el valor es ", read_single); + } + } + + begin { // Tarea de escritor + writeln("Escritor: escribirá en ..."); + countdown(3); + someSingleVar$ = 5; // primero y único escrito. + } + } + +// Aquí hay un ejemplo usando atómica y una variable de sincronización +// para crear un mutex de cuenta regresiva +// (también conocido como multiplexor). + var count: atomic int; // nuestro mostrador + var lock$: sync bool; // la cerradura mutex + + count.write(2); // Solo deje dos tareas a la vez. + lock$.writeXF(true); // Establezca lock$ en completo (desbloqueado) + // Nota: el valor en realidad no importa, solo el estado + // (completo: desbloqueado / vacio: bloqueado) + // Además, writeXF() llena (F) la variable de sincronización independientemente de su estado (X) + + coforall task in 1..#5 { // Generar tareas + // Create a barrier + do { + lock$; // Leer lock$ (espera) + } while (count.read() < 1); // Sigue esperando hasta que se abra un lugar + + count.sub(1); //disminuir el contador + lock$.writeXF(true); // Establezca lock$ en completo (señal) + + // 'Trabajo' actual + writeln("Tarea #", task, " trabajando"); + sleep(2); + + count.add(1); // Incrementa el contador + lock$.writeXF(true); // Establezca lock$ en completo (señal) + } + +// Podemos definir las operaciones + * & | ^ && || min max minloc maxloc +// sobre una matriz completa usando escaneos y reducciones. +// Las reducciones aplican la operación en toda la matriz +// y dan como resultado un valor escalar. + + var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2]; + var sumOfValues = + reduce listOfValues; + var maxValue = max reduce listOfValues; // 'max' da solo el valor máximo + +// maxloc proporciona el valor máximo y el índice del valor máximo. +// Nota: Tenemos que comprimir la matriz y el dominio junto con el iterador zip. + var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues, + listOfValues.domain); + + writeln((sumOfValues, maxValue, idxOfMax, listOfValues[idxOfMax])); + +// Los escaneos aplican la operación de forma incremental y devuelven una matriz +// con los valores de la operación en ese índice a medida que avanza a través +// de la matriz desde array.domain.low hasta array.domain.high. + var runningSumOfValues = + scan listOfValues; + var maxScan = max scan listOfValues; + writeln(runningSumOfValues); + writeln(maxScan); +} // end main() +``` + +¿Para quién es este tutorial? +------------------------- + +Este tutorial es para personas que desean aprender las cuerdas de chapel sin tener +que escuchar sobre qué mezcla de fibras son las cuerdas, o cómo fueron trenzadas, +o cómo las configuraciones de trenzas difieren entre sí. No le enseñará cómo +desarrollar código increíblemente eficaz, y no es exhaustivo. +Referirse a [especificación de idioma](https://chapel-lang.org/docs/latest/language/spec.html)(en) y +a [documentación del módulo](https://chapel-lang.org/docs/latest/)(en) para más detalles. + +Ocasionalmente, vuelva aquí en el [website de Chapel](https://chapel-lang.org) +para ver si se han agregado más temas o se han creado más tutoriales. + +### Lo que le falta a este tutorial: + + * Exposición de los [módulos estándar](https://chapel-lang.org/docs/latest/modules/standard.html) + * Múltiples configuraciones regionales (sistema de memoria distribuida) + * Registros + * Iteradores paralelos + +¡Sus comentarios, preguntas y descubrimientos son importantes para los desarrolladores! +----------------------------------------------------------------------- + +El lenguaje Chapel todavía está en desarrollo activo, por lo que +ocasionalmente hay problemas con el rendimiento y +las características del lenguaje. + +Cuanta más información brinde al equipo de desarrollo de Chapel +sobre los problemas que encuentre o las características que le gustaría ver, +mejor será el lenguaje. + + +Hay varias formas de interactuar con los desarrolladores: ++ [Chat de Gitter](https://gitter.im/chapel-lang/chapel) ++ [lista de emails de Sourceforge](https://sourceforge.net/p/chapel/mailman) + +Si está realmente interesado en el desarrollo del compilador o en contribuir al proyecto, +[consulte el repositorio maestro de GitHub](https://github.com/chapel-lang/chapel). +Está bajo el [La licencia Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Instalar el compilador +----------------------- + +[La documentación oficial de Chapel detalla cómo descargar y compilar el compilador de Chapel.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html) + +Chapel se puede construir e instalar en su máquina promedio 'nix (y cygwin). +[Descargue la última versión de lanzamiento](https://github.com/chapel-lang/chapel/releases/) +y es tan fácil como + + 1. `tar -xvf chapel-<VERSION>.tar.gz` + 2. `cd chapel-<VERSION>` + 3. `source util/setchplenv.bash # or .sh or .csh or .fish` + 4. `make` + 5. `make check # optional` + +You will need to `source util/setchplenv.EXT` from within the Chapel directory +(`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop +that command in a script that will get executed on startup (like .bashrc). + +Necesitará `source util/setchplenv.EXT` desde el directorio de Chapel (`$CHPL_HOME`) +cada vez que se inicie su terminal, por lo que se sugiere que suelte ese comando +en un script que se ejecutará al inicio (como .bashrc). + +Chapel se instala fácilmente con Brew para OS X + + 1. `brew update` + 2. `brew install chapel` + +Compilando Código +-------------- + +Construye como otros compiladores: + +`chpl myFile.chpl -o myExe` + +Argumentos notables: + + * `--fast`: habilita varias optimizaciones y deshabilita las comprobaciones + de los límites de la matriz Solo debe habilitarse cuando la aplicación es estable. + * `--set <Nombre del Symbolo>=<Valor>`: establece el param de configuracion + `<Nombre del Symbolo>` a `<Valor>`en tiempo de compilación. + * `--main-module <Nombre del módulo>`: use el procedimiento main() que se encuentra en el módulo + `<Nombre del módulo>` como principal del ejecutable. + * `--module-dir <Directorio>`: incluye `<Directorio>` en la ruta de búsqueda del módulo. diff --git a/es-es/css-es.html b/es-es/css-es.html deleted file mode 100644 index 506a9467..00000000 --- a/es-es/css-es.html +++ /dev/null @@ -1,327 +0,0 @@ ---- -language: css -contributors: - - ["Mohammad Valipour", "https://github.com/mvalipour"] - - ["Marco Scannadinari", "https://github.com/marcoms"] - - ["Geoffrey Liu", "https://github.com/g-liu"] - - ["Connor Shea", "https://github.com/connorshea"] - - ["Deepanshu Utkarsh", "https://github.com/duci9y"] - - ["Brett Taylor", "https://github.com/glutnix"] - - ["Tyler Mumford", "https://tylermumford.com"] -translators: - - ["miky ackerman", "https://github.com/mikyackerman"] -lang: es-es -filename: learncss-es.css ---- - -Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina -CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica -la **apariencia** de una pagina. - -codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores - -Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3. - -**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas -Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/). -El objetivo principal de este artículo es la sintaxis y algunos consejos generales. - -## Sintaxis - -```css -/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea - no hay "comentarios en una linea"; este es el unico estilo de comentario.*/ - - -/* #################### - ## SELECTORS - #################### */ - -/* el selector es usado para apuntar a un elemento de la pagina. */ -selector { property: value; /* more properties...*/ } - -/* -Here is an example element: - -<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' /> -*/ - -/* You can target it using one of its CSS classes */ -.class1 { } - -/* or both classes! */ -.class1.class2 { } - -/* or its name */ -div { } - -/* or its id */ -#anID { } - -/* or using the fact that it has an attribute! */ -[attr] { font-size:smaller; } - -/* or that the attribute has a specific value */ -[attr='value'] { font-size:smaller; } - -/* starts with a value (CSS 3) */ -[attr^='val'] { font-size:smaller; } - -/* or ends with a value (CSS 3) */ -[attr$='ue'] { font-size:smaller; } - -/* or contains a value in a space-separated list */ -[otherAttr~='foo'] { } -[otherAttr~='bar'] { } - -/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */ -[otherAttr|='en'] { font-size:smaller; } - - -/* You can combine different selectors to create a more focused selector. Don't - put spaces between them. */ -div.some-class[attr$='ue'] { } - -/* You can select an element which is a child of another element */ -div.some-parent > .class-name { } - -/* or a descendant of another element. Children are the direct descendants of - their parent element, only one level down the tree. Descendants can be any - level down the tree. */ -div.some-parent .class-name { } - -/* Warning: the same selector without a space has another meaning. - Can you guess what? */ -div.some-parent.class-name { } - -/* You may also select an element based on its adjacent sibling */ -.i-am-just-before + .this-element { } - -/* or any sibling preceding it */ -.i-am-any-element-before ~ .this-element { } - -/* There are some selectors called pseudo classes that can be used to select an - element only when it is in a particular state */ - -/* for example, when the cursor hovers over an element */ -selector:hover { } - -/* or a link has been visited */ -selector:visited { } - -/* or hasn't been visited */ -selected:link { } - -/* or an element is in focus */ -selected:focus { } - -/* any element that is the first child of its parent */ -selector:first-child {} - -/* any element that is the last child of its parent */ -selector:last-child {} - -/* Just like pseudo classes, pseudo elements allow you to style certain parts of - a document */ - -/* matches a virtual first child of the selected element */ -selector::before {} - -/* matches a virtual last child of the selected element */ -selector::after {} - -/* At appropriate places, an asterisk may be used as a wildcard to select every - element */ -* { } /* all elements */ -.parent * { } /* all descendants */ -.parent > * { } /* all children */ - -/* #################### - ## PROPERTIES - #################### */ - -selector { - - /* Units of length can be absolute or relative. */ - - /* Relative units */ - width: 50%; /* percentage of parent element width */ - font-size: 2em; /* multiples of element's original font-size */ - font-size: 2rem; /* or the root element's font-size */ - font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */ - font-size: 2vh; /* or its height */ - font-size: 2vmin; /* whichever of a vh or a vw is smaller */ - font-size: 2vmax; /* or greater */ - - /* Absolute units */ - width: 200px; /* pixels */ - font-size: 20pt; /* points */ - width: 5cm; /* centimeters */ - min-width: 50mm; /* millimeters */ - max-width: 5in; /* inches */ - - /* Colors */ - color: #F6E; /* short hex format */ - color: #FF66EE; /* long hex format */ - color: tomato; /* a named color */ - color: rgb(255, 255, 255); /* as rgb values */ - color: rgb(10%, 20%, 50%); /* as rgb percentages */ - color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */ - color: transparent; /* equivalent to setting the alpha to 0 */ - color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */ - color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */ - - /* Borders */ - border-width:5px; - border-style:solid; - border-color:red; /* similar to how background-color is set */ - border: 5px solid red; /* this is a short hand approach for the same */ - border-radius:20px; /* this is a CSS3 property */ - - /* Images as backgrounds of elements */ - background-image: url(/img-path/img.jpg); /* quotes inside url() optional */ - - /* Fonts */ - font-family: Arial; - /* if the font family name has a space, it must be quoted */ - font-family: "Courier New"; - /* if the first one is not found, the browser uses the next, and so on */ - font-family: "Courier New", Trebuchet, Arial, sans-serif; -} -``` - -## Usage - -Save a CSS stylesheet with the extension `.css`. - -```html -<!-- You need to include the css file in your page's <head>. This is the - recommended method. Refer to http://stackoverflow.com/questions/8284365 --> -<link rel='stylesheet' type='text/css' href='path/to/style.css'> - -<!-- You can also include some CSS inline in your markup. --> -<style> - a { color: purple; } -</style> - -<!-- Or directly set CSS properties on the element. --> -<div style="border: 1px solid red;"> -</div> -``` - -## Precedence or Cascade - -An element may be targeted by multiple selectors and may have a property set on -it in more than once. In these cases, one of the rules takes precedence over -others. Rules with a more specific selector take precedence over a less specific -one, and a rule occurring later in the stylesheet overwrites a previous one -(which also means that if two different linked stylesheets contain rules for an -element and if the rules are of the same specificity, then order of linking -would take precedence and the sheet linked latest would govern styling) . - -This process is called cascading, hence the name Cascading Style Sheets. - -Given the following CSS: - -```css -/* A */ -p.class1[attr='value'] - -/* B */ -p.class1 { } - -/* C */ -p.class2 { } - -/* D */ -p { } - -/* E */ -p { property: value !important; } -``` - -and the following markup: - -```html -<p style='/*F*/ property:value;' class='class1 class2' attr='value'> -``` - -The precedence of style is as follows. Remember, the precedence is for each -**property**, not for the entire block. - -* `E` has the highest precedence because of the keyword `!important`. It is -recommended that you avoid its usage. -* `F` is next, because it is an inline style. -* `A` is next, because it is more "specific" than anything else. It has 3 - specifiers: The name of the element `p`, its class `class1`, an attribute - `attr='value'`. -* `C` is next, even though it has the same specificity as `B`. - This is because it appears after `B`. -* `B` is next. -* `D` is the last one. - -## Media Queries - -CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity. - -```css -/* A rule that will be used on all devices */ -h1 { - font-size: 2em; - color: white; - background-color: black; -} - -/* change the h1 to use less ink on a printer */ -@media print { - h1 { - color: black; - background-color: white; - } -} - -/* make the font bigger when shown on a screen at least 480px wide */ -@media screen and (min-width: 480px) { - h1 { - font-size: 3em; - font-weight: normal; - } -} -``` - -Media queries can include these features: -`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`. - -The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`. - -Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag. - -```html -<head> - <meta name="viewport" content="width=device-width; initial-scale=1.0"> -</head> -``` - -## Compatibility - -Most of the features in CSS 2 (and many in CSS 3) are available across all -browsers and devices. But it's always good practice to check before using -a new feature. - -## Resources - -* [CanIUse](http://caniuse.com) (Detailed compatibility info) -* [Dabblet](http://dabblet.com/) (CSS playground) -* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference) -* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference) - -## Further Reading - -* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) -* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/) -* [QuirksMode CSS](http://www.quirksmode.org/css/) -* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) -* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing -* [CSS-Tricks](https://css-tricks.com) - - diff --git a/es-es/css-es.html.markdown b/es-es/css-es.html.markdown index 6395f5fd..506a9467 100644 --- a/es-es/css-es.html.markdown +++ b/es-es/css-es.html.markdown @@ -1,253 +1,327 @@ --- language: css -filename: learncss-es.css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] - ["Marco Scannadinari", "https://github.com/marcoms"] + - ["Geoffrey Liu", "https://github.com/g-liu"] + - ["Connor Shea", "https://github.com/connorshea"] + - ["Deepanshu Utkarsh", "https://github.com/duci9y"] + - ["Brett Taylor", "https://github.com/glutnix"] + - ["Tyler Mumford", "https://tylermumford.com"] translators: - - ["Daniel Zendejas","https://github.com/DanielZendejas"] + - ["miky ackerman", "https://github.com/mikyackerman"] lang: es-es +filename: learncss-es.css --- -Tutorial de CSS en español +Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina +CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica +la **apariencia** de una pagina. -En los primeros días de la web no había elementos visuales, todo -era texto plano. Pero después, con el desarrollo de los navegadores, -las páginas con contenido visual empezaron a ser más comunes. -CSS es el lenguaje estándar que existe para separar el contenido -(HTML) y el aspecto visual de las páginas web. +codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores -Lo que CSS hace es proveer con una sintaxis que te permite apuntar a distintos -elementos HTML y asignarles diferentes propiedades visuales. +Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3. -CSS, como cualquier otro lenguaje, tiene múltiples versiones. Aquí nos enfocamos -en CSS 2.0. No es la versión más reciente pero sí la más soportada y compatible. +**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas +Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/). +El objetivo principal de este artículo es la sintaxis y algunos consejos generales. -**NOTA:** Como los resultados de CSS son efectos visuales, para aprenderlo, -necesitarás probar todo tipo de cosas en ambientes como -[dabblet](http://dabblet.com/). Este artículo se enfoca, principalmente, en -la sintaxis y consejos generales. +## Sintaxis ```css -/* ¡Los comentarios aparecen dentro de diagonal-asterisco, justo como esta línea! */ +/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea + no hay "comentarios en una linea"; este es el unico estilo de comentario.*/ + /* #################### - ## SELECTORES - ####################*/ - -/* Generalmente, la sentencia principal en CSS es muy simple. */ -selector { propiedad: valor; /* más propiedades separados por punto y coma...*/ } - -/* El selector es usado para apuntar a (seleccionar) un elemento en la página. + ## SELECTORS + #################### */ -¡Puedes apuntar a todos los elementos en la página con el asterisco! */ -* { color:red; } +/* el selector es usado para apuntar a un elemento de la pagina. */ +selector { property: value; /* more properties...*/ } /* -Dado un elemento como este en la página: +Here is an example element: -<div class='una-clase clase2' id='unaId' attr='valor' /> +<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' /> */ -/* puedes seleccionar el <div> por el nombre de su clase */ -.una-clase { } +/* You can target it using one of its CSS classes */ +.class1 { } -/*¡O por sus dos clases! */ -.una-clase.clase2 { } +/* or both classes! */ +.class1.class2 { } -/* O por el nombre de su elemento */ +/* or its name */ div { } -/* O por su Id */ -#unaId { } +/* or its id */ +#anID { } -/* ¡O por el hecho de que tiene un atributo! */ +/* or using the fact that it has an attribute! */ [attr] { font-size:smaller; } -/* O por el hecho de que el atributo tiene un valor determinado */ -[attr='valor'] { font-size:smaller; } +/* or that the attribute has a specific value */ +[attr='value'] { font-size:smaller; } -/* Empieza con un valor ('val' en este caso)*/ +/* starts with a value (CSS 3) */ [attr^='val'] { font-size:smaller; } -/* O termina con un valor ('or' en este caso) */ -[attr$='or'] { font-size:smaller; } +/* or ends with a value (CSS 3) */ +[attr$='ue'] { font-size:smaller; } + +/* or contains a value in a space-separated list */ +[otherAttr~='foo'] { } +[otherAttr~='bar'] { } + +/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */ +[otherAttr|='en'] { font-size:smaller; } + -/* O incluso contiene un valor ('lo' en este caso) */ -[attr~='lo'] { font-size:smaller; } +/* You can combine different selectors to create a more focused selector. Don't + put spaces between them. */ +div.some-class[attr$='ue'] { } -/*Más importante, puedes combinar estos criterios de búsqueda entre sí. -No debe existir ningún espacio entre estas partes porque hace que el -significado cambie.*/ -div.una-clase[attr$='or'] { } +/* You can select an element which is a child of another element */ +div.some-parent > .class-name { } -/* También puedes seleccionar un elemento HTML basándote en sus padres*/ +/* or a descendant of another element. Children are the direct descendants of + their parent element, only one level down the tree. Descendants can be any + level down the tree. */ +div.some-parent .class-name { } -/* Un elemento que es hijo directo de otro elemento (Seleccionado de la forma que -vimos anteriormente) */ +/* Warning: the same selector without a space has another meaning. + Can you guess what? */ +div.some-parent.class-name { } -div.un-padre > .nombre-clase {} +/* You may also select an element based on its adjacent sibling */ +.i-am-just-before + .this-element { } -/* O cualquiera de sus ancestros en la jerarquía*/ -/* La siguiente sentencia selecciona a cualquier elemento que tenga una clase -"nombre-clase" y sea hijo de un div con clase "un-padre" EN CUALQUIER PROFUNDIDAD*/ -div.un-padre .nombre-clase {} +/* or any sibling preceding it */ +.i-am-any-element-before ~ .this-element { } -/* advertencia: el mismo selector sin espacio tiene otro significado. ¿Puedes -identificar la diferencia?*/ +/* There are some selectors called pseudo classes that can be used to select an + element only when it is in a particular state */ -/* También puedes seleccionar un elemento basado en su hermano inmediato previo*/ -.yo-estoy-antes + .este-elemento { } +/* for example, when the cursor hovers over an element */ +selector:hover { } -/*o cualquier hermano previo */ -.yo-soy-cualquiera-antes ~ .estes-elemento {} +/* or a link has been visited */ +selector:visited { } -/* Existen algunas pseudo-clases que permiten seleccionar un elemento -basado en el comportamiendo de la página (a diferencia de la estructura de -la página) */ +/* or hasn't been visited */ +selected:link { } -/* Por ejemplo, para cuando pasas el mouse por encima de un elemento */ -:hover {} +/* or an element is in focus */ +selected:focus { } -/* o una liga visitada*/ -:visited {} +/* any element that is the first child of its parent */ +selector:first-child {} -/* o una liga no visitada aún*/ -:link {} +/* any element that is the last child of its parent */ +selector:last-child {} -/* o un elemento de un formulario que esté seleccionado */ -:focus {} +/* Just like pseudo classes, pseudo elements allow you to style certain parts of + a document */ +/* matches a virtual first child of the selected element */ +selector::before {} + +/* matches a virtual last child of the selected element */ +selector::after {} + +/* At appropriate places, an asterisk may be used as a wildcard to select every + element */ +* { } /* all elements */ +.parent * { } /* all descendants */ +.parent > * { } /* all children */ /* #################### - ## PROPIEDADES - ####################*/ + ## PROPERTIES + #################### */ selector { - - /* Unidades */ - width: 50%; /* en porcentaje */ - font-size: 2em; /* dos veces el tamaño de la fuente actual */ - width: 200px; /* en pixeles */ - font-size: 20pt; /* en puntos */ - width: 5cm; /* en centimetros */ - width: 50mm; /* en milimetros */ - width: 5in; /* en pulgadas */ - - /* Colores */ - background-color: #F6E; /* en hexadecimal corto */ - background-color: #F262E2; /* en hexadecimal largo */ - background-color: tomato; /* puede ser un color con nombre */ - background-color: rgb(255, 255, 255); /* en rgb */ - background-color: rgb(10%, 20%, 50%); /* en rgb percent */ - background-color: rgba(255, 0, 0, 0.3); /* en rgb semi-transparente (con valor alfa)*/ - - /* Imagenes */ - background-image: url(/ruta-a-la-imagen/imagen.jpg); - - /* Fuentes */ + + /* Units of length can be absolute or relative. */ + + /* Relative units */ + width: 50%; /* percentage of parent element width */ + font-size: 2em; /* multiples of element's original font-size */ + font-size: 2rem; /* or the root element's font-size */ + font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */ + font-size: 2vh; /* or its height */ + font-size: 2vmin; /* whichever of a vh or a vw is smaller */ + font-size: 2vmax; /* or greater */ + + /* Absolute units */ + width: 200px; /* pixels */ + font-size: 20pt; /* points */ + width: 5cm; /* centimeters */ + min-width: 50mm; /* millimeters */ + max-width: 5in; /* inches */ + + /* Colors */ + color: #F6E; /* short hex format */ + color: #FF66EE; /* long hex format */ + color: tomato; /* a named color */ + color: rgb(255, 255, 255); /* as rgb values */ + color: rgb(10%, 20%, 50%); /* as rgb percentages */ + color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */ + color: transparent; /* equivalent to setting the alpha to 0 */ + color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */ + color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */ + + /* Borders */ + border-width:5px; + border-style:solid; + border-color:red; /* similar to how background-color is set */ + border: 5px solid red; /* this is a short hand approach for the same */ + border-radius:20px; /* this is a CSS3 property */ + + /* Images as backgrounds of elements */ + background-image: url(/img-path/img.jpg); /* quotes inside url() optional */ + + /* Fonts */ font-family: Arial; - font-family: "Courier New"; /* si el nombre contiene espacios, debe ir entre comillas */ - font-family: "Courier New", Trebuchet, Arial; /* si la primera fuente no se encontró - entonces se busca la seguna, o la tercera, así recursivamente*/ + /* if the font family name has a space, it must be quoted */ + font-family: "Courier New"; + /* if the first one is not found, the browser uses the next, and so on */ + font-family: "Courier New", Trebuchet, Arial, sans-serif; } - ``` -## Uso +## Usage -Guarda cualquier CSS que quieras en un archivo con extensión `.css`. +Save a CSS stylesheet with the extension `.css`. -```xml -<!-- Necesitas incluir tu archivo CSS en el elemento <head> de tu HTML: --> -<link rel='stylesheet' type='text/css' href='ruta/archivoDeEstilos.css' /> +```html +<!-- You need to include the css file in your page's <head>. This is the + recommended method. Refer to http://stackoverflow.com/questions/8284365 --> +<link rel='stylesheet' type='text/css' href='path/to/style.css'> -<!-- -también puedes incluir CSS dentro del archivo HTML. Esta no es una buena práctica -y debe ser evitada. ---> +<!-- You can also include some CSS inline in your markup. --> <style> - selector { propiedad:valor; } + a { color: purple; } </style> -<!-- -También se pueden aplicar propiedades al elemento directamente. -Esta práctica también debe ser evitada a toda costa ---> -<div style='propiedad:valor;'> +<!-- Or directly set CSS properties on the element. --> +<div style="border: 1px solid red;"> </div> - ``` -## Preferencia y orden +## Precedence or Cascade + +An element may be targeted by multiple selectors and may have a property set on +it in more than once. In these cases, one of the rules takes precedence over +others. Rules with a more specific selector take precedence over a less specific +one, and a rule occurring later in the stylesheet overwrites a previous one +(which also means that if two different linked stylesheets contain rules for an +element and if the rules are of the same specificity, then order of linking +would take precedence and the sheet linked latest would govern styling) . -Como te habrás dado cuenta un elemento puede ser seleccionado por más -de un selector. En este caso alguna de las reglas cobra preferencia -sobre las otras: +This process is called cascading, hence the name Cascading Style Sheets. -Dado el siguiente CSS: +Given the following CSS: ```css -/*A*/ -p.clase1[attr='valor'] +/* A */ +p.class1[attr='value'] -/*B*/ -p.clase1 {} +/* B */ +p.class1 { } -/*C*/ -p.clase2 {} +/* C */ +p.class2 { } -/*D*/ -p {} +/* D */ +p { } -/*E*/ -p { propiedad: valor !important; } +/* E */ +p { property: value !important; } +``` +and the following markup: + +```html +<p style='/*F*/ property:value;' class='class1 class2' attr='value'> ``` -Y el siguiente HTML: +The precedence of style is as follows. Remember, the precedence is for each +**property**, not for the entire block. + +* `E` has the highest precedence because of the keyword `!important`. It is +recommended that you avoid its usage. +* `F` is next, because it is an inline style. +* `A` is next, because it is more "specific" than anything else. It has 3 + specifiers: The name of the element `p`, its class `class1`, an attribute + `attr='value'`. +* `C` is next, even though it has the same specificity as `B`. + This is because it appears after `B`. +* `B` is next. +* `D` is the last one. + +## Media Queries + +CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity. + +```css +/* A rule that will be used on all devices */ +h1 { + font-size: 2em; + color: white; + background-color: black; +} -```xml -<p style='/*F*/ propiedad:valor;' class='clase1 clase2' attr='valor'> -</p> +/* change the h1 to use less ink on a printer */ +@media print { + h1 { + color: black; + background-color: white; + } +} + +/* make the font bigger when shown on a screen at least 480px wide */ +@media screen and (min-width: 480px) { + h1 { + font-size: 3em; + font-weight: normal; + } +} ``` -El orden respetado es el siguiente: -Recuerda, la preferencia es por cada **property**, no para el bloque completo. +Media queries can include these features: +`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`. -* `E` tiene la preferencia más elevada gracias a la palabra `!important`. - Es recomendado evitar esto a menos que sea estrictamente necesario incluirlo. -* `F` le sigue, porque es estilo incrustado directamente en el HTML. -* `A` le sigue, porque es más específico que cualquier otra opción. - más específico = más especificadores. Aquí hay tres especificadores: elemento `p` + - nombre de la clase `clase1` + un atributo `attr='valor'` -* `C` le sigue. Aunque tiene el mismo número de especificadores como `B` - pero aparece después. -* Luego va `B` -* y al final `D`. +The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`. -## Compatibilidad +Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag. -La mayoría de las funcionalidades de CSS2 (y gradualmente de CSS3) son compatibles -en todos los navegadores y dispositivos. Pero siempre es vital tener en mente la -compatibilidad y disponibilidad del CSS que uses con respecto a los navegadores -y dispositivos para los que desarrolles. +```html +<head> + <meta name="viewport" content="width=device-width; initial-scale=1.0"> +</head> +``` + +## Compatibility -[QuirksMode CSS](http://www.quirksmode.org/css/) es una excelente referencia para esto. +Most of the features in CSS 2 (and many in CSS 3) are available across all +browsers and devices. But it's always good practice to check before using +a new feature. -## Recursos +## Resources -* Para ejecutar un test de compatibilidad, revisa [CanIUse](http://caniuse.com). -* CSS Playground [Dabblet](http://dabblet.com/). -* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS). -* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/). +* [CanIUse](http://caniuse.com) (Detailed compatibility info) +* [Dabblet](http://dabblet.com/) (CSS playground) +* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference) +* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference) -## Otras lecturas +## Further Reading -* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/). -* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/). -* [QuirksMode CSS](http://www.quirksmode.org/css/). +* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) +* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/) +* [QuirksMode CSS](http://www.quirksmode.org/css/) * [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) -* [SASS](http://sass-lang.com/) y [LESS](http://lesscss.org/) para preprocesamiento CSS. -* [CSS-Tricks](https://css-tricks.com). +* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing +* [CSS-Tricks](https://css-tricks.com) + diff --git a/es-es/docker-es.html.markdown b/es-es/docker-es.html.markdown index 93e17f02..81e3cefe 100644 --- a/es-es/docker-es.html.markdown +++ b/es-es/docker-es.html.markdown @@ -1,167 +1,167 @@ ----
-language: docker
-filename: docker-es.bat
-contributors:
- - ["Ruslan López", "http://javapro.org/"]
- - ["Michael Chen", "https://github.com/ML-Chen"]
-lang: es-es
----
-
-```bat
-:: descargar, instalar y ejecutar la imágen del hola mundo
-docker run hello-world
-
-:: Si esta es la primera vez, deberíais de poder ver el mensaje
-:: Unable to find image 'hello-world:latest' locally
-:: latest: Pulling from library/hello-world
-:: 1b930d010525: Pull complete
-:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
-:: Status: Downloaded newer image for hello-world:latest
-::
-:: Hello from Docker!
-:: This message shows that your installation appears to be working correctly.
-::
-:: To generate this message, Docker took the following steps:
-:: 1. The Docker client contacted the Docker daemon.
-:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
-:: (amd64)
-:: 3. The Docker daemon created a new container from that image which runs the
-:: executable that produces the output you are currently reading.
-:: 4. The Docker daemon streamed that output to the Docker client, which sent it
-:: to your terminal.
-::
-:: To try something more ambitious, you can run an Ubuntu container with:
-:: $ docker run -it ubuntu bash
-::
-:: Share images, automate workflows, and more with a free Docker ID:
-:: https://hub.docker.com/
-::
-:: For more examples and ideas, visit:
-:: https://docs.docker.com/get-started/
-:: El susodicho mensaje se podría traducir como:
-::
-:: Hola desde Docker!
-:: Este mensaje muestra que su instalación parece estar funcionando crrectamente.
-::
-:: Para generar este mensaje, Docker realizó los siguientes pasos:
-:: 1. El cliente de Docker contactó a Docker daemon.
-:: 2. El Docker daemon obtubo la imágen "hello-world" desde Docker Hub.
-:: (amd64)
-:: 3. El Docker daemon creó un nuevo contenedor a partir de esa imagen con la cual ejecuta el
-:: ejecutable que produce la salida que estás leyendo.
-:: 4. El Docker daemon transmitió dicha salida el cliente Docker, el cual
-:: la envió a tu terminal.
-::
-:: Para intentar algo más ambicioso, puede correr un contenedor Ubuntu mediante:
-:: $ docker run -it ubuntu bash
-::
-:: Comparte imágenes, automatice flujos y más con un Docker ID gratuito:
-:: https://hub.docker.com/
-
-:: ahora veamos las imágenes que se están ejecutando actualmente
-docker ps
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-
-:: veamos las imágenes que hemos ejecutado previamente
-docker ps -a
-
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago
-:: happy_poincare
-:: la parte del nombre se genera automáticamente, así que probablemente sea diferente para vos
-
-:: eliminemos nuestra imagen previamente generada
-docker rm happy_poincare
-
-:: verifiquemos si realmente fue borrada
-docker ps -a
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-
-:: especifiquemos un nombre personalizado para el contenedor
-docker run --name test_container hello-world
-:: Hello from Docker!
-:: This message shows that your installation appears to be working correctly.
-::
-:: To generate this message, Docker took the following steps:
-:: 1. The Docker client contacted the Docker daemon.
-:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
-:: (amd64)
-:: 3. The Docker daemon created a new container from that image which runs the
-:: executable that produces the output you are currently reading.
-:: 4. The Docker daemon streamed that output to the Docker client, which sent it
-:: to your terminal.
-::
-:: To try something more ambitious, you can run an Ubuntu container with:
-:: $ docker run -it ubuntu bash
-::
-:: Share images, automate workflows, and more with a free Docker ID:
-:: https://hub.docker.com/
-::
-:: For more examples and ideas, visit:
-:: https://docs.docker.com/get-started/
-
-docker ps -a
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago
-:: test_container
-:: tal como podeis ver el nombre es el que especificamos
-
-:: obtener los registros de un contenedor nombrado
-docker logs test_container
-:: Hello from Docker!
-:: This message shows that your installation appears to be working correctly.
-::
-:: To generate this message, Docker took the following steps:
-:: 1. The Docker client contacted the Docker daemon.
-:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
-:: (amd64)
-:: 3. The Docker daemon created a new container from that image which runs the
-:: executable that produces the output you are currently reading.
-:: 4. The Docker daemon streamed that output to the Docker client, which sent it
-:: to your terminal.
-::
-:: To try something more ambitious, you can run an Ubuntu container with:
-:: $ docker run -it ubuntu bash
-::
-:: Share images, automate workflows, and more with a free Docker ID:
-:: https://hub.docker.com/
-::
-:: For more examples and ideas, visit:
-:: https://docs.docker.com/get-started/
-
-docker rm test_container
-
-docker run ubuntu
-:: Unable to find image 'ubuntu:latest' locally
-:: latest: Pulling from library/ubuntu
-:: 2746a4a261c9: Pull complete
-:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
-:: Status: Downloaded newer image for ubuntu:latest
-
-docker ps -a
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago
-:: relaxed_nobel
-
-:: ejecutando un contenedor en modo interactivo
-docker run -it ubuntu
-:: root@e2cac48323d2:/# uname
-:: Linux
-:: root@e2cac48323d2:/# exit
-:: exit
-
-docker rm relaxed_nobel
-
-docker ps -a
-:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
-:: NAMES
-:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago
-:: nifty_goldwasser
-
-docker rm nifty_goldwasser
-```
+--- +language: docker +filename: docker-es.bat +contributors: + - ["Ruslan López", "http://javapro.org/"] + - ["Michael Chen", "https://github.com/ML-Chen"] +lang: es-es +--- + +```bat +:: descargar, instalar y ejecutar la imágen del hola mundo +docker run hello-world + +:: Si esta es la primera vez, deberíais de poder ver el mensaje +:: Unable to find image 'hello-world:latest' locally +:: latest: Pulling from library/hello-world +:: 1b930d010525: Pull complete +:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064 +:: Status: Downloaded newer image for hello-world:latest +:: +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ +:: El susodicho mensaje se podría traducir como: +:: +:: Hola desde Docker! +:: Este mensaje muestra que su instalación parece estar funcionando crrectamente. +:: +:: Para generar este mensaje, Docker realizó los siguientes pasos: +:: 1. El cliente de Docker contactó a Docker daemon. +:: 2. El Docker daemon obtubo la imágen "hello-world" desde Docker Hub. +:: (amd64) +:: 3. El Docker daemon creó un nuevo contenedor a partir de esa imagen con la cual ejecuta el +:: ejecutable que produce la salida que estás leyendo. +:: 4. El Docker daemon transmitió dicha salida el cliente Docker, el cual +:: la envió a tu terminal. +:: +:: Para intentar algo más ambicioso, puede correr un contenedor Ubuntu mediante: +:: $ docker run -it ubuntu bash +:: +:: Comparte imágenes, automatice flujos y más con un Docker ID gratuito: +:: https://hub.docker.com/ + +:: ahora veamos las imágenes que se están ejecutando actualmente +docker ps +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES + +:: veamos las imágenes que hemos ejecutado previamente +docker ps -a + +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago +:: happy_poincare +:: la parte del nombre se genera automáticamente, así que probablemente sea diferente para vos + +:: eliminemos nuestra imagen previamente generada +docker rm happy_poincare + +:: verifiquemos si realmente fue borrada +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES + +:: especifiquemos un nombre personalizado para el contenedor +docker run --name test_container hello-world +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago +:: test_container +:: tal como podeis ver el nombre es el que especificamos + +:: obtener los registros de un contenedor nombrado +docker logs test_container +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ + +docker rm test_container + +docker run ubuntu +:: Unable to find image 'ubuntu:latest' locally +:: latest: Pulling from library/ubuntu +:: 2746a4a261c9: Pull complete +:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4 +:: Status: Downloaded newer image for ubuntu:latest + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago +:: relaxed_nobel + +:: ejecutando un contenedor en modo interactivo +docker run -it ubuntu +:: root@e2cac48323d2:/# uname +:: Linux +:: root@e2cac48323d2:/# exit +:: exit + +docker rm relaxed_nobel + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago +:: nifty_goldwasser + +docker rm nifty_goldwasser +``` diff --git a/es-es/elixir-es.html.markdown b/es-es/elixir-es.html.markdown index 885165a6..37acf6ad 100644 --- a/es-es/elixir-es.html.markdown +++ b/es-es/elixir-es.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -23,10 +23,10 @@ y otras características más. # No hay comentarios multilinea, # pero se pueden apilar varios comentarios. -# Para usar el shell de elixir se usa el comando `iex`. +# Para usar el shell de Elixir se usa el comando `iex`. # Los módulos se compilan con el comando `elixirc`. -# Ambos deberían estar en la ruta si elixir se instaló correctamente. +# Ambos deberían estar en la ruta si Elixir se instaló correctamente. ## --------------------------- ## -- Tipos básicos @@ -55,7 +55,7 @@ elem({1, 2, 3}, 0) #=> 1 head #=> 1 tail #=> [2,3] -# En elixir, solo como Erlang, el `=` denota la coincidencia de patrones y +# En Elixir, solo como Erlang, el `=` denota la coincidencia de patrones y # no una asignación. # # This is how the above example of accessing the head and tail of a list works. @@ -87,7 +87,7 @@ string. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` en elixir devuelve el valor ASCII para el caracter `a` +# `?a` en Elixir devuelve el valor ASCII para el caracter `a` ?a #=> 97 # Para concatenar listas se usa `++`, para binarios `<>` @@ -120,7 +120,7 @@ genders.gillian #=> "female" 5 * 2 #=> 10 10 / 2 #=> 5.0 -# En elixir el operador `/` siempre devuelve un número flotante +# En Elixir el operador `/` siempre devuelve un número flotante # Para hacer la división de número entero se debe usar `div` div(10, 2) #=> 5 @@ -175,7 +175,7 @@ else end # Se acuerda de la coincidencia de patrones? -# Muchas estructuras de control de flujo en elixir confían en ella. +# Muchas estructuras de control de flujo en Elixir confían en ella. # `case` permite comparar un valor con muchos patrones: case {:one, :two} do @@ -305,7 +305,7 @@ Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 -# Debido a la inmutabilidad, la recursión es una gran parte de elixir +# Debido a la inmutabilidad, la recursión es una gran parte de Elixir defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) @@ -380,7 +380,7 @@ end ## --------------------------- # Elixir confía en el modelo actor para la concurrencia. Todo lo que se necesita para escribir -# programas concurrentes en elixir son tres primitivas: procesos de desove, +# programas concurrentes en Elixir son tres primitivas: procesos de desove, # envío de mensajes y recepción de mensajes. # Para empezar un nuevo proceso se usa la función `spawn`, diff --git a/es-es/forth-es.html.markdown b/es-es/forth-es.html.markdown index edc5d38c..61123151 100644 --- a/es-es/forth-es.html.markdown +++ b/es-es/forth-es.html.markdown @@ -13,7 +13,7 @@ Forth fue criado por Charles H. Moore en los 70s. Forth es un lenguaje imperativ Nota: Este articulo enfoca predominantemente en la Gforth implementación de Forth, pero casi todo de lo que esta escrito aquí debe funcionar en otro sitio. -``` +```forth \ Este es un comentario ( Este es un comentario también pero solo esta usado cuando definiendo palabras. ) diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index dc0dda30..c93584d8 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -414,4 +414,4 @@ $ git rm /directorio/del/archivo/FooBar.c * [Pro Git](http://www.git-scm.com/book/en/v2) -* [Una introducción a Git y Github para principiantes (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) +* [Una introducción a Git y GitHub para principiantes (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown index 78267695..17bf4a22 100644 --- a/es-es/go-es.html.markdown +++ b/es-es/go-es.html.markdown @@ -88,7 +88,7 @@ saltos de línea.` // mismo tipo cadena // Literal no ASCII. Los ficheros fuente de Go son UTF-8. g := 'Σ' // Tipo rune, un alias de int32, alberga un carácter unicode. - f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit. + f := 3.14159 // float64, el estándar IEEE-754 de coma flotante 64-bit. c := 3 + 4i // complex128, representado internamente por dos float64. // Sintaxis var con iniciadores. var u uint = 7 // Sin signo, pero la implementación depende del tamaño @@ -425,7 +425,7 @@ func consultaAlServidor() { ## Más información La raíz de todas las cosas sobre Go es el -[sitio web oficial de Go](http://golang.org/). +[sitio web oficial de Go](https://go.dev/). Allí puedes seguir el tutorial, jugar interactivamente y leer mucho más. La definición del lenguaje es altamente recomendada. Es fácil de leer y @@ -433,17 +433,17 @@ sorprendentemente corta (como la definición del lenguaje Go en estos días). Puedes jugar con el código en el -[parque de diversiones Go](https://play.golang.org/p/ncRC2Zevag). ¡Trata +[parque de diversiones Go](https://go.dev/play/p/ncRC2Zevag). ¡Trata de cambiarlo y ejecutarlo desde tu navegador! Ten en cuenta que puedes -utilizar [https://play.golang.org]( https://play.golang.org) como un +utilizar [https://go.dev/play/]( https://go.dev/play/) como un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) para probar cosas y el código en el navegador, sin ni siquiera instalar Go. En la lista de lecturas para estudiantes de Go está el -[código fuente de la biblioteca estándar](http://golang.org/src/pkg/). +[código fuente de la biblioteca estándar](https://go.dev/src/). Ampliamente documentado, que demuestra lo mejor del legible y comprensible Go, con su característico estilo y modismos. ¡O puedes hacer clic en un -nombre de función en [la documentación](http://golang.org/pkg/) y +nombre de función en [la documentación](https://go.dev/pkg/) y aparecerá el código fuente! Otro gran recurso para aprender Go está en diff --git a/es-es/powershell-es.html.markdown b/es-es/powershell-es.html.markdown index 9eb35967..5b12b961 100644 --- a/es-es/powershell-es.html.markdown +++ b/es-es/powershell-es.html.markdown @@ -34,7 +34,7 @@ $PSVersionTable Para obtener ayuda: -``` +```powershell # Si necesita encontrar algún comando Get-Command about_* # tiene por abreviación (o alias): gcm Get-Command -Verb Add # lista todos los comandos que tienen por verbo 'Add' @@ -51,7 +51,7 @@ Update-Help # Actualiza la ayuda (debe ser ejecutado en una consola elevada como Acá inicia el tutorial: -``` +```powershell # Como ya lo notó, los comentarios empiezan con # # Ejemplo de un simple hola mundo: @@ -299,7 +299,7 @@ $Shortcut.Save() Configurando el shell -``` +```powershell # $Profile es la ruta completa para su `Microsoft.PowerShell_profile.ps1` # Todo el código alojado allí será ejecutado cuando se ejecuta una nueva sesión de PS if (-not (Test-Path $Profile)) { diff --git a/es-es/pyqt-es.html.markdown b/es-es/pyqt-es.html.markdown index 6d4fdde7..9a5eab8c 100644 --- a/es-es/pyqt-es.html.markdown +++ b/es-es/pyqt-es.html.markdown @@ -16,7 +16,7 @@ Esta es una adaptación de la introducción a QT con C++ por [Aleksey Kholovchuk ```python import sys from PyQt4 import QtGui - + def window(): # Crear el objeto de la aplicación app = QtGui.QApplication(sys.argv) @@ -44,7 +44,7 @@ if __name__ == '__main__': Para poder hacer uso de las funciones más avanzades en **pyqt** necesitamos agregar elementos adicionales. Aquí mostramos cómo introducir una caja de diálogo popup, útil para permitir al usuario confirmar su decisión o para brindarnos información. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -63,7 +63,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Esta función debería crear una ventana de diálogo con un botón # que espera a recibir un click y luego sale del programa def showdialog(): diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index 0b21e479..a8f01089 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -421,7 +421,7 @@ map(sumar_10, [1,2,3]) #=> [11, 12, 13] filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] # Podemos usar listas por comprensión para mapeos y filtros agradables -[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] +[sumar_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] # también hay diccionarios {k:k**2 for k in range(3)} #=> {0: 0, 1: 1, 2: 4} diff --git a/es-es/r-es.html.markdown b/es-es/r-es.html.markdown index 2b710b27..850952fa 100644 --- a/es-es/r-es.html.markdown +++ b/es-es/r-es.html.markdown @@ -16,7 +16,7 @@ LaTeX. ```r -# Los comentariso inician con símbolos numéricos. +# Los comentarios inician con símbolos numéricos. # No puedes hacer comentarios de múltiples líneas # pero puedes agrupar múltiples comentarios de esta manera. diff --git a/es-es/raku-es.html.markdown b/es-es/raku-es.html.markdown index e916d0fd..09341056 100644 --- a/es-es/raku-es.html.markdown +++ b/es-es/raku-es.html.markdown @@ -1,5 +1,5 @@ --- -name: perl6 +name: Raku category: language language: Raku filename: learnraku-es.raku diff --git a/es-es/self-es.html.markdown b/es-es/self-es.html.markdown index 11972214..1f985215 100644 --- a/es-es/self-es.html.markdown +++ b/es-es/self-es.html.markdown @@ -116,6 +116,7 @@ Las expresiones múltiples son separadas por un punto. ^ retorna inmediatamente. ``` Los bloques son ejecutados al enviales el mensaje 'value' y son inherentes (delegados a) sus contextos: + ``` "returns 0" [|x| diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown index c677c20f..fb0b1d27 100644 --- a/es-es/visualbasic-es.html.markdown +++ b/es-es/visualbasic-es.html.markdown @@ -8,7 +8,7 @@ filename: learnvisualbasic-es.vb lang: es-es --- -``` +```visualbasic Module Module1 Sub Main() diff --git a/es-es/wolfram-es.html.markdown b/es-es/wolfram-es.html.markdown index 44ec9e09..6858c286 100644 --- a/es-es/wolfram-es.html.markdown +++ b/es-es/wolfram-es.html.markdown @@ -15,7 +15,7 @@ El lenguaje de Wolfram tiene varias interfaces: El código de este ejemplo se puede escribir en cualquier interfaz y editarlo con Wolfram Workbench. Cargar directamente en Matematica puede resultar incómodo porque el archivo no contiene información de formato de celda (lo que haría que el archivo sea un desastre enorme para ser leído como texto) - puede ser visto / editado pero tal vez requerira algún ajuste. -``` +```mathematica (* Esto es un comentario *) (* En Mathematica en lugar de utilizar estos comentarios, puede crear una celda de texto diff --git a/fa-ir/css-fa.html.markdown b/fa-ir/css-fa.html.markdown index 4e222eb2..93af9132 100644 --- a/fa-ir/css-fa.html.markdown +++ b/fa-ir/css-fa.html.markdown @@ -29,21 +29,21 @@ filename: learncss-fa.css <p dir='rtl'>در CSS همه توضیحات داخل ستاره-بروم نوشته میشوند زیرا CSS دستوری برای توضیحات تک خطی مثل C ندارد</p> -```CSS +```css /* comments appear inside slash-asterisk, just like this line! there are no "one-line comments"; this is the only comment style */ ``` <p dir='rtl'>به طور کلی دستورات CSS بسیار ساده هستند که در آن یک انتخابگر (selector) عنصری را در روی صفحه هدف قرار میدهد.</p> -```CSS +```css selector { property: value; /* more properties...*/ } ``` <p dir='rtl'>با استفاده از ستاره می توان برای همه عناصر روی صفحه استایل تعریف کرد</p> -```CSS +```css * { color:red; } ``` @@ -55,129 +55,129 @@ selector { property: value; /* more properties...*/ } <p dir='rtl'>شما میتوانید با استفاده از نام کلاس آنرا انتخاب کنید</p> -```CSS +```css .some-class { } ``` <p dir='rtl'>یا با استفاده از نام دو کلاس</p> -```CSS +```css .some-class.class2 { } ``` <p dir='rtl'>یا با استفاده از نام id</p> -```CSS +```css #someId { } ``` <p dir='rtl'>یا با استفاده از نام خود عنصر</p> -```CSS +```css div { } ``` <p dir='rtl'>یا با استفاده از `attr`</p> -```CSS +```css [attr] { font-size:smaller; } ``` <p dir='rtl'>یا با استفاده از ارزشی که برای `attr` مشخص شده</p> -```CSS +```css [attr='value'] { font-size:smaller; } ``` <p dir='rtl'>با استفاده از ارزشی که برای `attr` مشخص شده و آن ارزش با `val` شروع میشود در CSS3</p> -```CSS +```css [attr^='val'] { font-size:smaller; } ``` <p dir='rtl'>با استفاده از ارزشی که برای `attr` مشخص شده و آن ارزش با `ue` به پایان میرسد در CSS3</p> -```CSS +```css [attr$='ue'] { font-size:smaller; } ``` <p dir='rtl'>یا با انتخاب بوسیله یکی از ارزشهایی که در لیست `otherAttr` بوسیله فاصله از هم جدا شده اند در CSS3</p> -```CSS +```css [attr$='ue'] { font-size:smaller; } ``` <p dir='rtl'>یا ارزش(`value`) دقیقاً خود ارزش(`value`) یا بوسیله `-` که یونیکد (U+002D) از حرف بعدی جدا شود</p> -```CSS +```css [otherAttr|='en'] { font-size:smaller; } ``` <p dir='rtl'>و مهمتر از همه اینکه میتوان آنها را ترکیب کرد. نکته مهمی که در اینجا باید مد نظر داشته باشید این است که هنگام ترکیب نباید هیچگونه فاصله ای بین آنها قرار گیرد زیرا در این حالت معنای دستور تغییر میکند</p> -```CSS +```css div.some-class[attr$='ue'] { } ``` <p dir='rtl'>CSS این امکان را به شما میدهد که یک عنصر را بوسیله والدین آن انتخاب کنید</p> <p dir='rtl'>برای مثال دستور زیر همه عناصری را که نام کلاس آنها <span dir="ltr">`.class-name`</span> و دارای پدر و مادری با این مشخصه <span dir="ltr">`div.some-parent`</span> هستند را انتخاب میکند.</p> -```CSS +```css div.some-parent > .class-name {} ``` <p dir='rtl'>یا دستور زیر که همه عناصری را که نام کلاس آنها <span dir="ltr">`.class-name`</span> و داخل عنصری با مشخصه <span dir="ltr">`div.some-parent`</span> هستند را در هر عمقی که باشند (یعنی فرزندی از فرزندان <span dir="ltr">`div.some-parent`</span><span dir="ltr"> باشند) انتخاب میکند.</p> -```CSS +```css div.some-parent .class-name {} ``` <p dir='rtl'>نکته ای که در اینجا باید به آن توجه کنید این است که این رستور با فاصله ای بین نام دو کلاس همراه است و با مثال زیر که در بالا هم ذکر شد تفاوت دارد.</p> -```CSS +```css div.some-parent.class-name {} ``` <p dir='rtl'>دستور زیر همه عناصری را که نام کلاس آنها <span dir="ltr">`.this-element`</span> و بلافاصله بعد از عنصری با مشخصه <span dir="ltr">`.i-am-before`</span> قرار دارد را انتخاب میکند.</p> -```CSS +```css .i-am-before + .this-element { } ``` <p dir='rtl'>هر خواهر یا برادری که بعد از <span dir="ltr">`.i-am-before`</span> بیاید در اینجا لازم نیست بلافاصله بعد از هم قرار بگیرند ولی باید دارای پدر و مادری یکسان باشند.</p> -```CSS +```css .i-am-any-before ~ .this-element {} ``` <p dir='rtl'>در زیر چند نمونه از شبه کلاسها را معرفی میکنیم که به شما اجازه میدهد عناصر را بر اساس رفتار آنها در صفحه انتخاب کنید.</p> <p dir='rtl'>برای مثال زمانی که اشاره گر ماوس روی عنصری بر روی صفحه قرار دارد.</p> -```CSS +```css selector:hover {} ``` <p dir='rtl'>یا زمانی از یک لینک بازید کردید.</p> -```CSS +```css selected:visited {} ``` <p dir='rtl'>یا زمانی از لینکی بازید نشده است.</p> -```CSS +```css selected:link {} ``` <p dir='rtl'>یا زمانی که روی یک عنصر ورودی متمرکز شده.</p> -```CSS +```css selected:focus {} ``` <h3 dir='rtl'>واحدها</h3> -```CSS +```css selector { /* واحدها اندازه */ @@ -247,7 +247,7 @@ selector { <p dir='rtl'>به مثال زیر توجه کنید:</p> -```CSS +```css /*A*/ p.class1[attr='value'] diff --git a/fa-ir/vim-fa.html.markdown b/fa-ir/vim-fa.html.markdown new file mode 100644 index 00000000..f1864619 --- /dev/null +++ b/fa-ir/vim-fa.html.markdown @@ -0,0 +1,469 @@ +--- +category: tool +tool: vim +contributors: + - ["RadhikaG", "https://github.com/RadhikaG"] +translators: + - ["Moein Halvaei", "https://github.com/mo1ein"] +lang: fa-ir +filename: LearnVim-fa.txt +--- + +<p dir="rtl"> +[Vim](http://www.vim.org) (Vi رشدیافته) یک کلون از ادیتور مشهور vi است برای unix. ادیتورمتنیست که برای سرعت و افزایش بهرهوری طراحی شده و در همه جا به ویژه در سیستم های unix-based دیده میشود. شورتکات کلید های بیشماری برای سرعت جهتیابی به نقاط ویژهي فایل ها و تغییر سریع، دارد. +<br /> +`vimtutor` یک برنامهي عالیست که به شما چگونگی استفاده از `vim` را آموزش میدهد. +این به همراه پکیج های vim هنگام نصب کردن، نصب میشود. شما باید بتوانید با ران کردن `vimtutor` در کامندلاین از آموزش ها استفاده کنید. این همهی ویژگی های عمدهی `vim` را به شما راهنمایی میکند. +</p> +<h3> + <p dir="rtl"> +مکانیابی اولیه vim + </p> +</h3> + + +<p dir="rtl"> +باز کردن `<filename>` در ویم +</p> + +``` +vim <filename> # Open <filename> in vim +``` +<p dir="rtl"> +باز کردن help docs های `<topic>` اگر وجود داشته باشد +</p> + +``` +:help <topic> # Open up built-in help docs about <topic> if any exists +``` +``` +:q # خروج از ویم + +:w # ذخیره کردن فایل فعلی + +:wq # ذخیره کردن و خارج شدن از ویم + +ZZ # ذخیره کردن و خارج شدن از ویم + +:q! # خارج شدن بدون ذخیره کردن فایل + +! *forces* :q to execute, hence quiting vim without saving + +ZQ # خارج شدن بدون ذخیره کردن فایل +``` + +<p dir="rtl">ذخیره کردن و خارج شدن از vim ورژن خلاصه شدهی wq:</p> + +``` +:x # Save file and quit vim, shorter version of :wq +``` + +<p dir="rtl">برگشت به عقب</p> + +``` + u # Undo +``` + +<p dir="rtl">رفتن به جلو</p> + +``` +CTRL+R # Redo +``` + +<p dir="rtl">راه رفتن در صفحه</p> + +``` +h # رفتن یک کاراکتر به چپ + +j # رفتن یک کاراکتر به پایین + +k # رفتن یک کاراکتر به بالا + +l # رفتن یک کاراکتر به راست + +Ctrl+B # جابهجا شدن به عقب به اندازه یک صفحه + +Ctrl+F # جابهجا شدن به جلو به اندازه یک صفحه + +Ctrl+D # جابهجا شدن به جلو به اندازه نصف صفحه + +Ctrl+U # جابهجا شدن به عقب به اندازه نصف صفحه +``` + +<p dir="rtl"><strong>جابهجا شدن در خط</strong></p> + +``` +0 # رفتن به اول خط +$ # رفتن به آخر خط +^ # رفتن به اولین کاراکتر غیرخالی در خط +``` + +<p dir="rtl"><strong>جست و جو در متن</strong></p> + +``` +/word # هایلایت کردن همهی کلمه های بعد کِرسر + +?word # هایلایت کردن همهی کلمه های قبل کِرسر + +n # جابهجایی کِرسر به کلمه های بعدی پیدا شده + +N # جابهجایی کِرسر به کلمه های قبلی پیدا شده +``` + +<p dir="rtl">عوض کردن 'foo' به 'bar' در هر خط از فایل</p> + +``` +:%s/foo/bar/g # Change 'foo' to 'bar' on every line in the file +``` + +<p dir="rtl">عوض کردن 'foo' به 'bar' در خط فعلی</p> + +``` +:s/foo/bar/g # Change 'foo' to 'bar' on the current line +``` + +<p dir="rtl">جایگزینی کاراکتر های خط جدید با کاراکتر های خط جدید</p> + +``` +:%s/\n/\r/g # Replace new line characters with new line characters +``` + +<p dir="rtl"><strong>پرش به کاراکتر ها</strong></p> +<p dir="rtl">پرش به جلو و قرار گرفتن روی کاراکتر مورد نظر</p> + +``` +f<character> # Jump forward and land on <character> +``` + +<p dir="rtl">پرش به جلو و قرار گرفتن قبل کاراکتر مورد نظر</p> + +``` +t<character> # Jump forward and land right before <character> +``` + +<p dir="rtl"><strong>برای مثال:</strong></p> + +<p dir="rtl">پرش به جلو و قرار گرفتن روی ></p> + +``` +f< # Jump forward and land on < +``` + +<p dir="rtl">پرش به جلو و قرار گرفتن قبل از ></p> + +``` +t< # Jump forward and land right before < +``` +<p dir="rtl"><strong>جابهجا شدن با کلمه ها</strong></p> + +``` +w # رفتن به جلو به اندازهی یک کلمه +b # رفتن به عقب به اندازهی یک کلم +e # رفتن به آخر کلمهی فعلی +``` +<p dir="rtl"><strong>سایر کاراکتر ها برای جابهجایی</strong></p> +<p dir="rtl">رفتن به اول فایل</p> + +``` +gg # Go to the top of the file +``` +<p dir="rtl">رفتن به آخر فایل</p> + +``` +G # Go to the bottom of the file +``` +<p dir="rtl">رفتن به شمارهی خط مورد نظر (NUM شماره است)</p> + +``` +:NUM # Go to line number NUM (NUM is any number) +``` +<p dir="rtl">رفتن به اول صفحه</p> + +``` +H # Move to the top of the screen +``` +<p dir="rtl">رفتن به وسط صفحه</p> + +``` +M # Move to the middle of the screen +``` +<p dir="rtl">رفتن به آخر صفحه</p> + +``` +L # Move to the bottom of the screen +``` + +<h3> +<p dir="rtl"><strong> +داک های help +</strong></p> +</h3> + +<p dir="rtl"> +Vim دارای یک help doc داخلی است که میتوان با help: <topic> به آن دسترسی داشت. برای مثال help navigation: داک مربوط به مکانیابی در فضای کار را به شما نشان میدهد! <br /><br /> +help: همچنین میتواند بدون option مورد استفاده قرار گیرد. +این یه صورت یک help پیشفرض بالا میآید که شروع vim را قابل دسترس تر میکند! +</p> + +<h3> + <p dir="rtl"><strong>Modes:</strong></p> +</h3> + +<div dir="rtl"> +Vim بر پایهی مفهومیست به نام <strong>modes</strong> +<br /><br /> +<ul> + <li> + Command Mode - ویم در این حالت بالا میآید، برای مکانیابی و نوشتن دستورات استفاده میشود +</li> +<li> + Insert Mode - برای ایجاد تغییر در فایل شما استفاده میشود +</li> +<li> + Visual Mode - برای هایلایت کردن متن و انجام عملی روی آن ها استفاده میشود +</li> +<li> + Ex Mode - برای وارد کردن دستورات توسط ":" در قسمت پایین استفاده میشود +</li> +</ul> +<br /> +</div> + +<p dir="rtl">رفتن به حالت insert, پیش از جایگاه cursor</p> + +``` +i # Puts vim into insert mode, before the cursor position +``` +<p dir="rtl">رفتن به حالت insert, پس از جایگاه cursor</p> + +``` +a # Puts vim into insert mode, after the cursor position +``` + +<p dir="rtl">رفتن به حالت visual</p> + +``` +v # Puts vim into visual mode +``` +<p dir="rtl">رفتن به حالت ex</p> + +``` +: # Puts vim into ex mode +``` +<p dir="rtl">خروج از همهی حالت ها و رفتن به حالت command</p> + +``` +<esc> # 'Escapes' from whichever mode you're in, into Command mode +``` +<p dir="rtl">کپی و پیست در متن</p> + +``` +y # کپی کردن متن انتخاب شده + +yy # کپی کردن خط فعلی + +d # حذف کردن متن انتخاب شده + +dd # حذف کردن خط فعلی + +p # پیست کردن متن کپی شده پس از جایگاه فعلی کِرسر + +P # پیست کردن متن کپی شده پیش از جایگاه فعلی کِرسر + +x # حذف کردن یک کاراکتر از جایگاه کِرسر +``` + +<h3> +<p dir="rtl"><strong>گرامر (Grammer) </strong></p> +</h3> + +<div dir="rtl"> +Vim را می توان به عنوان مجموعه ای از دستورات در قالب (Verb - Modifier - Noun) تصور کرد ، جایی که: +<br /><br /> +<ul> +<li> + Verb - عمل شما +</li> +<li> + Modifier - چگونگی انجام عمل شما +</li> +<li> + Noun - شیئی که عمل شما بر اساس آن عمل می کند +</li> +</ul> +اندکی از مثال های مهم Verbs ,Modifiers, Nouns: +<br /><br /> +</div> + +<p dir="rtl"><strong>فعل ها (Verbs)</strong></p> + +``` +d # حذف +c # تغییر +y # کپی +v # انتخاب +``` +<p dir="rtl"><strong>تغییردهنده ها (Modifiers)</strong></p> + +``` +i # داخل +a # اطراف +NUM # شماره (NUM هر شمارهای است) +f # جست و جو کردن چیزی و متوقف شدن روی آن +t # جست و جو کردن چیزی و متوقف شدن قبل از آن +/ # جست و جو کردن رشتهای پس از کِرسر +? # جست و جو کردن رشتهای پیش از کِرسر +``` +<p dir="rtl"><strong>اسم ها (Nouns)</strong></p> + +``` +w # کلمه +s # جمله +p # پاراگراف +b # بلوک +``` +<p dir="rtl"><strong>جمله ها و کامند های نمونه</strong></p> + +``` +d2w # حذف دو کلمه +cis # تغییر داخل جمله +yip # کپی داخل پاراگراف (از پاراگرافی که داخل آن هستید کپی کنید) +ct< # متن را از جایی که قرار دارید به براکت باز بعدی تغییر دهید +d$ # حذف تا پایان +``` + +<h3> + <p dir="rtl">بعضی از شورتکات ها و ترفند ها</p> +</h3> + +``` +<!--TODO: Add more!--> + +> # ایجاد دندانه به اندازه یک بلوک + +< # حذف دندانه به اندازه یک بلوک + +:earlier 15m # برگرداندن همه چیز به ۱۵ دقیقه قبل + +:later 15m # برعکس کامند قبلی + +ddp # تغییر مکان خطوط متوالی(dd, then p) + +. # تکرار دستور قبلی + +:w !sudo tee % # ذخیره کردن فایل فعلی به عنوان روت + +:set syntax=c # تنظیم سینتکس هایلایتینگ روی 'c' + +:sort # مرتب کردن همهی خطوط + +:sort! # مرتب کردن همهی خطوط به صورت برعکس + +:sort u # مرتب کردن همهی خطوط و پاک کردن تکراری ها + +~ # تبدیل متن انتخاب شده به حروف (اگر بزرگ است، کوچک و اگر کوچک است، بزرگ) + +u # تبدیل متن انتخاب شده به حروف کوچک + +U # تبدیل متن انتخاب شده به حروف بزرگ + +J # اتصال خط فعلی به خط بعدی +``` +<h4> +<p dir="rtl"> +فولد (Fold) +</p> +</h4> + +``` +zf # ایجاد فولد برای متن انتخاب شده +zo # باز کردن فولد فعلی +zc # بستن فولد فعلی +zR # باز کردن همهی فولد ها +zM # بستن همهی فولد ها +``` + +<h3> +<p dir="rtl"> +ماکرو ها (Macros) +</p> +</h3> + +<p dir="rtl"> +ماکرو ها اساسا عمل های قابل ضبط هستند. زمانی که شما شروع میکنید به ضبط ماکرو، هر عمل و دستوری را که استفاده میکنید، تا زمانی که ضبط را متوقف کنید، ضبط میشود. با فراخوانی ماکرو، دقیقاً همان توالی اعمال و دستورات، دوباره روی متن انتخاب شده اعمال میشود. +</p> + +``` +qa # Start recording a macro named 'a' +q # Stop recording +@a # Play back the macro +``` +<h3> +<p dir="rtl"> +کانفیگ vimrc./~ +<p> +</h3> + +<p dir="rtl"> +vimrc. فایلیست که استفاده میشود برای کانفیگ vim هنگام بالا آمدن +<br /> +اینجا یک نمونه فایل vimrc. آورده شده: +</p> + +``` +" Example ~/.vimrc +" 2015.10 + +" Required for vim to be iMproved +set nocompatible + +" Determines filetype from name to allow intelligent auto-indenting, etc. +filetype indent plugin on + +" Enable syntax highlighting +syntax on + +" Better command-line completion +set wildmenu + +" Use case insensitive search except when using capital letters +set ignorecase +set smartcase + +" When opening a new line and no file-specific indenting is enabled, +" keep same indent as the line you're currently on +set autoindent + +" Display line numbers on the left +set number + +" Indentation options, change according to personal preference + +" Number of visual spaces per TAB +set tabstop=4 + +" Number of spaces in TAB when editing +set softtabstop=4 + +" Number of spaces indented when reindent operations (>> and <<) are used +set shiftwidth=4 +" Convert TABs to spaces +set expandtab + +" Enable intelligent tabbing and spacing for indentation and alignment +set smarttab +``` + +<h3> +<p dir="rtl">رفرنس ها</p> +</h3> + +[Vim | Home](http://www.vim.org/index.php) + +`$ vimtutor` + +[A vim Tutorial and Primer](https://danielmiessler.com/study/vim/) + +[What are the dark corners of Vim your mom never told you about? (St + +[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim) diff --git a/fi-fi/go-fi.html.markdown b/fi-fi/go-fi.html.markdown index 15acdbae..ef88a96e 100644 --- a/fi-fi/go-fi.html.markdown +++ b/fi-fi/go-fi.html.markdown @@ -90,7 +90,7 @@ voi sisältää rivinvaihtoja.` // Sama merkkijonotyyppi. // Ei-ASCII todellisarvo. Go-lähdekoodi on UTF-8. g := 'Σ' // riimutyyppi, lempinimi int32:lle, sisältää unicode-koodipisteen. - f := 3.14195 //float64, IEEE-754 64-bittinen liukuluku. + f := 3.14159 //float64, IEEE-754 64-bittinen liukuluku. c := 3 + 4i // complex128, sisäisesti ilmaistu kahdella float64:lla. // var -syntaksi alkuarvoilla. @@ -418,21 +418,21 @@ func requestServer() { ## Lisää luettavaa -Go-tietämyksen alku ja juuri on sen [virallinen verkkosivu]()(http://golang.org/). +Go-tietämyksen alku ja juuri on sen [virallinen verkkosivu]()(https://go.dev/). Siellä voit seurata oppitunteja, askarrella vuorovaikutteisesti sekä lukea paljon. -Kierroksen lisäksi [dokumentaatio](https://golang.org/doc/) pitää sisällään tietoa +Kierroksen lisäksi [dokumentaatio](https://go.dev/doc/) pitää sisällään tietoa siistin Go-koodin kirjoittamisesta, pakettien ja komentojen käytöstä sekä julkaisuhistoriasta. Kielen määritelmä itsessään on suuresti suositeltavissa. Se on helppolukuinen ja yllättävän lyhyt (niissä määrin kuin kielimääritelmät nykypäivänä ovat.) -Voit askarrella parissa kanssa [Go playgroundissa](https://play.golang.org/p/tnWMjr16Mm). -Muuttele sitä ja aja se selaimestasi! Huomaa, että voit käyttää [https://play.golang.org](https://play.golang.org) +Voit askarrella parissa kanssa [Go playgroundissa](https://go.dev/play/p/tnWMjr16Mm). +Muuttele sitä ja aja se selaimestasi! Huomaa, että voit käyttää [https://go.dev/play/](https://go.dev/play/) [REPL:na](https://en.wikipedia.org/wiki/Read-eval-print_loop) testataksesi ja koodataksesi selaimessasi, ilman Go:n asentamista. -Go:n opiskelijoiden lukulistalla on [oletuskirjaston lähdekoodi](http://golang.org/src/pkg/). +Go:n opiskelijoiden lukulistalla on [oletuskirjaston lähdekoodi](https://go.dev/src/). Kattavasti dokumentoituna se antaa parhaan kuvan helppolukuisesta ja ymmärrettävästä Go-koodista, --tyylistä ja -tavoista. Voit klikata funktion nimeä [doukumentaatiossa](http://golang.org/pkg/) ja +-tyylistä ja -tavoista. Voit klikata funktion nimeä [doukumentaatiossa](https://go.dev/pkg/) ja lähdekoodi tulee esille! Toinen loistava paikka oppia on [Go by example](https://gobyexample.com/). diff --git a/fish.html.markdown b/fish.html.markdown index edbd8909..4b70f883 100644 --- a/fish.html.markdown +++ b/fish.html.markdown @@ -3,6 +3,7 @@ category: tool tool: fish contributors: - ["MySurmise", "https://github.com/MySurmise"] + - ["Geo Maciolek", "https://github.com/GeoffMaciolek"] filename: learn.fish --- @@ -14,45 +15,64 @@ Examples of these features are autosuggestions, 24-bit colors, Man Page Completi It was released in February 2005. -[Read more](https://fishshell.com/docs/current/language.html) +- [Read more](https://fishshell.com/docs/current/language.html) +- [Installation guide](https://github.com/fish-shell/fish-shell#getting-fish) -[Installation guide](https://github.com/fish-shell/fish-shell#getting-fish) - -# Guide +## Guide Be sure you have the newest fish shell. This was made with version 3.3.0. To test, type: + +``` > fish -v +``` To start the fish shell, type: + +``` > fish +``` to exit, type: + +``` > exit +``` or press <kbd>Ctrl + D</kbd> Now, right out of the gate, there's one annoying thing in fish. It's the welcome message. Who needs that, right? When your shell is started, just type: -> set -U fish_greeting "" - -To set that to the wanted value, . +``` +> set -U fish_greeting "" +``` If you want to execute a single command written in bash, without switching to that shell, you can type: + +``` > bash -c 'echo "fish is better than bash"' +``` In fish, you can use single or double quotes. The escape character is a `\` You can change your configuration of fish either by editing the config file + +``` > vim ~/.config/fish/config.fish +``` or by opening the aforementioned web settings: ->fish_config +``` +> fish_config +``` Adding something to your fish PATH Variable is easy: + +``` > fish_path_add ~/cowsay +``` Can you do that with bash, huh? No, you always have to look it up... It's just that easy! @@ -60,21 +80,28 @@ But there's more. Most fish-specific commands start, you guessed it, with 'fish' Now you can navigate with <kbd>TAB</kbd>, <kbd>Shift + TAB</kbd> and your Arrow-Keys <kbd>←</kbd><kbd>↑</kbd><kbd>→</kbd><kbd>↓</kbd>. To get help, contact your local psychiatrist or type `man`. That will bring up the manual for that command, for example: + +``` > man set +``` If you finally tried fish, you can see something other in fish that's really cool. Everything has cool colors, if you type in something wrong, it is red, without even executing, if you put something in quotes, you see where it ends and why that quote doesn't work, because there's another qoutation mark in the quote at position 26. fish has even more cool things, like wildcards. For example, type + +``` > ls *.fish +``` That will list all fish files in your current directory. You can have multiple wildcards per command or even a recursive wildcard, `**`, which basically means it includes files and directories, that fit. For example the following command would return (in your case): -> ls ~/images/**.jpg ``` +> ls ~/images/**.jpg + ~/images/nudes/pewdiepie.jpg ~/images/nudes/peppa.jpg ~/images/screenshots/2020-42-69.jpg @@ -83,72 +110,77 @@ For example the following command would return (in your case): Of course, you can also pipe the output of a command to another command +``` >echo sick egg, nadia. no u do really goofy shit. | grep [udense] +``` write to a file: +``` >echo This\ is\ text > file.txt +``` (noticed the escape character?) Add to a file: +``` >echo This\ is\ a\ line >> file.txt - >echo This\ is\ a\ second\ line >> file.txt +``` For Autocompletion, just always press <kbd>TAB</kbd>. You will be surprised how many things fish knows. To use variables, just type `$VAR`, like in bash. +``` > echo "My home is $HOME" - -> My home is /home/myuser +My home is /home/myuser +``` Here comes a difference between single and double quotes. If you use a variable in single quotes, it will not substitute it. +``` > echo 'My home is $HOME' - -> My home is $HOME +My home is $HOME +``` More on variables later. To execute two commands, separate them with `;` + +``` > echo Lol; echo this is fun +``` The status code of the last command is stored in `$status` You can use && for two commands that depend on each other. +``` > set var lol && echo $var +``` -You can also use and, -which executes if the previous command was successful - -or -which executes if the previous command was not successful - -and not +You can also use `and` which executes if the previous command was successful, +`or` which executes if the previous command was not successful, and `not` which inverts the exit status of a command. For example: - -> if not echo It's very late I should not waste my time with this - ->> echo Nobody heard you - ->end +``` +> if not echo It's very late I should not waste my time with this + echo Nobody heard you + end +``` (You can of course do all of that in the shell) - --- -Now let's start with the scripting part of fish. +Now let's start with the scripting part of fish. As with every shell, you can not only execute commands in the shell, but also as files, saved as a `.fish` file. (You can also execute `.sh` files with fish syntax, but I always use `.fish` for fish-syntax scripts to distinguish them from bash script files) -```bash +```fish # This is a comment in fish. # # If you execute a file without specifying an interpreter, @@ -165,10 +197,9 @@ As with every shell, you can not only execute commands in the shell, but also as # for use inside a program, you can use the syntax set name = 'My Variable' - -# use +# Use... set -x name value -# to eXport +# to eXport, or set -e name # to Erase @@ -188,20 +219,21 @@ count $PATH # So $PWD for example is a list of length 1. # To make a list, just give the set command multiple arguments: set list entry1 entry2 entry3 + # that way you can also append something to an existing variable: set PATH $PATH ~/cowsay/ # But, as previously mentioned, we also have a simpler way to do that specifically in fish. # As with every Array/List, you can access it with $listvar[2] + # there's also ranges with -$listvar[1..5] +$listvar[1..5] + # and you can use negative numbers like $listvar[-1] # e.g to access the last element. - - # You can also do fancy cartesian products when you combine two list variables: set a 1 2 3 set 1 a b c @@ -239,7 +271,7 @@ else echo Got nothing end -# A little weird is that you compare stuff with one = sign , of course because we don't need it to set variables, but still... and the keyword "test": +# A little weird is that you compare stuff with one = sign, of course because we don't need it to set variables, but still... and the keyword "test": if test $var = "test" echo yes else @@ -304,10 +336,7 @@ end # Cool! # The bashrc equivalent is not fishrc, but the previously mentioned config.fish file in ~/.config/fish/ - # To add a function to fish, though, you should create a simple .fish file in that directory. Don't just paste that function in the config.fish. That's ugly. - # If you have more, just add it, but those are the most important basics. ``` - diff --git a/forth.html.markdown b/forth.html.markdown index ff094017..4e2f7599 100644 --- a/forth.html.markdown +++ b/forth.html.markdown @@ -93,8 +93,8 @@ see square \ : square dup * ; ok \ ------------------------------------ Loops ----------------------------------- -\ `do` is also a compile-only word. -: myloop ( -- ) 5 0 do cr ." Hello!" loop ; \ ok +\ `?do` is also a compile-only word. +: myloop ( -- ) 5 0 ?do cr ." Hello!" loop ; \ ok myloop \ Hello! \ Hello! @@ -102,16 +102,17 @@ myloop \ Hello! \ Hello! ok -\ `do` expects two numbers on the stack: the end number and the start number. +\ `?do` expects two numbers on the stack: the end number (exclusive) and the +\ start number (inclusive). \ We can get the value of the index as we loop with `i`: : one-to-12 ( -- ) 12 0 do i . loop ; \ ok -one-to-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok +one-to-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 ok -\ `?do` works similarly, except it will skip the loop if the end and start -\ numbers are equal. -: squares ( n -- ) 0 ?do i square . loop ; \ ok -10 squares \ 0 1 4 9 16 25 36 49 64 81 ok +\ `do` works similarly, except if start and end are exactly the same it will +\ loop forever (until arithmetic underflow). +: loop-forever 1 1 do i square . loop ; \ ok +loop-forever \ 1 4 9 16 25 36 49 64 81 100 ... \ Change the "step" with `+loop`: : threes ( n n -- ) ?do i . 3 +loop ; \ ok diff --git a/fortran90.html.markdown b/fortran.html.markdown index 2f2cfdfd..316f8c87 100644 --- a/fortran90.html.markdown +++ b/fortran.html.markdown @@ -11,9 +11,9 @@ Translation"). Despite its age, it is still used for high-performance computing such as weather prediction. However, the language has changed considerably over the years, although mostly maintaining backwards compatibility; well known versions are FORTRAN 77, Fortran 90, Fortran 95, Fortran 2003, Fortran 2008, -Fortran 2015, and Fortran 2018. +Fortran 2018 and Fortran 2023. -This overview will discuss the features of Fortran 95 since it is the most +This overview will discuss the features of Fortran 2008 since it is the most widely implemented of the more recent specifications and the later versions are largely similar (by comparison FORTRAN 77 is a very different language). @@ -21,158 +21,147 @@ largely similar (by comparison FORTRAN 77 is a very different language). ! This is a comment. - -program example !declare a program called example. +program example ! declare a program called example. ! Code can only exist inside programs, functions, subroutines or modules. ! Using indentation is not required but it is recommended. - ! Declaring Variables ! =================== ! All declarations must come before statements and expressions. - implicit none !prevents dynamic declaration of variables (recommended!) + implicit none ! prevents dynamic declaration of variables (recommended!) ! Implicit none must be redeclared in every function/program/module... ! IMPORTANT - Fortran is case insensitive. real z REAL Z2 - real :: v,x ! WARNING: default initial values are compiler dependent! - real :: a = 3, b=2E12, c = 0.01 - integer :: i, j, k=1, m - real, parameter :: PI = 3.1415926535897931 !declare a constant. - logical :: y = .TRUE. , n = .FALSE. !boolean type. - complex :: w = (0,1) !sqrt(-1) - character (len=3) :: month !string of 3 characters. + real :: v, x ! WARNING: default initial values are compiler dependent! + real :: a = 3, b = 2E12, c = 0.01 + integer :: i, j, k = 1, m + real, parameter :: PI = 3.1415926535897931 ! declare a constant. + logical :: y = .TRUE., n = .FALSE. ! boolean type. + complex :: w = (0, 1) ! sqrt(-1) + character(len=3) :: month ! string of 3 characters. - real :: array(6) !declare an array of 6 reals. - real, dimension(4) :: arrayb !another way to declare an array. - integer :: arrayc(-10:10) !an array with a custom index. - real :: array2d(3,2) !multidimensional array. + real :: array(6) ! declare an array of 6 reals. + real, dimension(4) :: arrayb ! another way to declare an array. + integer :: arrayc(-10:10) ! an array with a custom index. + real :: array2d(3, 2) ! multidimensional array. ! The '::' separators are not always necessary but are recommended. ! many other variable attributes also exist: - real, pointer :: p !declare a pointer. + real, pointer :: p ! declare a pointer. integer, parameter :: LP = selected_real_kind(20) - real (kind = LP) :: d !long precision variable. + real(kind=LP) :: d ! long precision variable. ! WARNING: initialising variables during declaration causes problems ! in functions since this automatically implies the 'save' attribute ! whereby values are saved between function calls. In general, separate ! declaration and initialisation code except for constants! - ! Strings ! ======= character :: a_char = 'i' - character (len = 6) :: a_str = "qwerty" - character (len = 30) :: str_b - character (len = *), parameter :: a_long_str = "This is a long string." + character(len=6) :: a_str = "qwerty" + character(len=30) :: str_b + character(len=*), parameter :: a_long_str = "This is a long string." !can have automatic counting of length using (len=*) but only for constants. - str_b = a_str // " keyboard" !concatenate strings using // operator. - + str_b = a_str//" keyboard" ! concatenate strings using // operator. ! Assignment & Arithmetic ! ======================= - Z = 1 !assign to variable z declared above (case insensitive). + Z = 1 ! assign to variable z declared above (case insensitive). j = 10 + 2 - 3 - a = 11.54 / (2.3 * 3.1) - b = 2**3 !exponentiation - + a = 11.54/(2.3*3.1) + b = 2**3 ! exponentiation ! Control Flow Statements & Operators ! =================================== ! Single-line if statement - if (z == a) b = 4 !condition always need surrounding parentheses. - - if (z /= a) then !z not equal to a - ! Other symbolic comparisons are < > <= >= == /= - b = 4 - else if (z .GT. a) then !z greater than a - ! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE. - b = 6 - else if (z < a) then !'then' must be on this line. - b = 5 !execution block must be on a new line. + if (z == a) b = 4 ! condition always need surrounding parentheses. + + if (z /= a) then ! z not equal to a + ! Other symbolic comparisons are < > <= >= == /= + b = 4 + else if (z .GT. a) then ! z greater than a + ! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE. + b = 6 + else if (z < a) then ! 'then' must be on this line. + b = 5 ! execution block must be on a new line. else - b = 10 - end if !end statement needs the 'if' (or can use 'endif'). - - - if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !boolean operators. - inner: if (.TRUE.) then !can name if-construct. - b = 1 - endif inner !then must name endif statement. - endif + b = 10 + end if ! end statement needs the 'if' (or can use 'endif'). + if (.NOT. (x < c .AND. v >= a .OR. z == z)) then ! boolean operators. + inner: if (.TRUE.) then ! can name if-construct. + b = 1 + end if inner ! then must name endif statement. + end if i = 20 select case (i) - case (0) !case i == 0 - j=0 - case (1:10) !cases i is 1 to 10 inclusive. - j=1 - case (11:) !all cases where i>=11 - j=2 - case default - j=3 + case (0, 1) ! cases i == 0 or i == 1 + j = 0 + case (2:10) ! cases i is 2 to 10 inclusive. + j = 1 + case (11:) ! all cases where i>=11 + j = 2 + case default + j = 3 end select - month = 'jan' ! Condition can be integer, logical or character type. ! Select constructions can also be named. - monthly: select case (month) - case ("jan") - j = 0 - case default - j = -1 + monthly:select case(month) + case ("jan") + j = 0 + case default + j = -1 end select monthly - - do i=2,10,2 !loops from 2 to 10 (inclusive) in increments of 2. - innerloop: do j=1,3 !loops can be named too. - exit !quits the loop. - end do innerloop - cycle !jump to next loop iteration. - enddo - + do i = 2, 10, 2 ! loops from 2 to 10 (inclusive) in increments of 2. + innerloop: do j = 1, 3 ! loops can be named too. + exit ! quits the loop. + end do innerloop + cycle ! jump to next loop iteration. + end do ! Goto statement exists but it is heavily discouraged though. goto 10 - stop 1 !stops code immediately (returning specified condition code). -10 j = 201 !this line is labeled as line 10 - + stop 1 ! stops code immediately (returning specified condition code). +10 j = 201 ! this line is labeled as line 10 ! Arrays ! ====== - array = (/1,2,3,4,5,6/) - array = [1,2,3,4,5,6] !using Fortran 2003 notation. - arrayb = [10.2,3e3,0.41,4e-5] - array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2]) + array = (/1, 2, 3, 4, 5, 6/) + array = [1, 2, 3, 4, 5, 6] ! using Fortran 2003 notation. + arrayb = [10.2, 3e3, 0.41, 4e-5] + array2d = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [3, 2]) ! Fortran array indexing starts from 1. ! (by default but can be defined differently for specific arrays). - v = array(1) !take first element of array. - v = array2d(2,2) + v = array(1) ! take first element of array. + v = array2d(2, 2) - print *, array(3:5) !print all elements from 3rd to 5th (inclusive). - print *, array2d(1,:) !print first column of 2d array. + print *, array(3:5) ! print all elements from 3rd to 5th (inclusive). + print *, array2d(1, :) ! print first column of 2d array. - array = array*3 + 2 !can apply mathematical expressions to arrays. - array = array*array !array operations occur element-wise. - !array = array*array2d !these arrays would not be compatible. + array = array*3 + 2 ! can apply mathematical expressions to arrays. + array = array*array ! array operations occur element-wise. + ! array = array*array2d ! these arrays would not be compatible. ! There are many built-in functions that operate on arrays. - c = dot_product(array,array) !this is the dot product. + c = dot_product(array, array) ! this is the dot product. ! Use matmul() for matrix maths. c = sum(array) c = maxval(array) @@ -188,74 +177,73 @@ program example !declare a program called example. end do ! Conditionally execute element-wise assignments. - array = [1,2,3,4,5,6] + array = [1, 2, 3, 4, 5, 6] where (array > 3) array = array + 1 - elsewhere (array == 2) + elsewhere(array == 2) array = 1 elsewhere array = 0 end where ! Implied-DO loops are a compact way to create arrays. - array = [ (i, i = 1,6) ] !creates an array of [1,2,3,4,5,6] - array = [ (i, i = 1,12,2) ] !creates an array of [1,3,5,7,9,11] - array = [ (i**2, i = 1,6) ] !creates an array of [1,4,9,16,25,36] - array = [ (4,5, i = 1,3) ] !creates an array of [4,5,4,5,4,5] - + array = [(i, i=1, 6)] ! creates an array of [1,2,3,4,5,6] + array = [(i, i=1, 12, 2)] ! creates an array of [1,3,5,7,9,11] + array = [(i**2, i=1, 6)] ! creates an array of [1,4,9,16,25,36] + array = [(4, 5, i=1, 3)] ! creates an array of [4,5,4,5,4,5] ! Input/Output ! ============ - print *, b !print the variable 'b' to the command line + print *, b ! print the variable 'b' to the command line ! We can format our printed output. - print "(I6)", 320 !prints ' 320' - print "(I6.4)", 3 !prints ' 0003' - print "(F6.3)", 4.32 !prints ' 4.320' + print "(I6)", 320 ! prints ' 320' + print "(I6.4)", 3 ! prints ' 0003' + print "(F6.3)", 4.32 ! prints ' 4.320' ! The letter indicates the expected type and the number afterwards gives ! the number of characters to use for printing the value. ! Letters can be I (integer), F (real), E (engineering format), ! L (logical), A (characters) ... - print "(I3)", 3200 !print '***' since the number doesn't fit. + print "(I3)", 3200 ! print '***' since the number doesn't fit. ! we can have multiple format specifications. print "(I5,F6.2,E6.2)", 120, 43.41, 43.41 - print "(3I5)", 10, 20, 30 !3 repeats of integers (field width = 5). - print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !repeated grouping of formats. + print "(3I5)", 10, 20, 30 ! 3 repeats of integers (field width = 5). + print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 ! repeated grouping of formats. ! We can also read input from the terminal. - read *, v - read "(2F6.2)", v, x !read two numbers + read (*, *) v + read (*, "(2F6.2)") v, x ! read two numbers - ! To read a file. - open(unit=11, file="records.txt", status="old") + ! To write a file. + open (unit=12, file="records.txt", status="replace") ! The file is referred to by a 'unit number', an integer that you pick in ! the range 9:99. Status can be one of {'old','replace','new'}. - read(unit=11, fmt="(3F10.2)") a, b, c - close(11) + write (12, "(F10.2,F10.2,F10.2)") c, b, a + close (12) - ! To write a file. - open(unit=12, file="records.txt", status="replace") - write(12, "(F10.2,F10.2,F10.2)") c, b, a - close(12) + ! To read a file. + open (newunit=m, file="records.txt", status="old") + ! The file is referred to by a 'new unit number', an integer that the compiler + ! picks for you. + read (unit=m, fmt="(3F10.2)") a, b, c + close (m) ! There are more features available than discussed here and alternative ! variants due to backwards compatibility with older Fortran versions. - ! Built-in Functions ! ================== ! Fortran has around 200 functions/subroutines intrinsic to the language. ! Examples - - call cpu_time(v) !sets 'v' to a time in seconds. - k = ior(i,j) !bitwise OR of 2 integers. - v = log10(x) !log base 10. - i = floor(b) !returns the closest integer less than or equal to x. - v = aimag(w) !imaginary part of a complex number. - + call cpu_time(v) ! sets 'v' to a time in seconds. + k = ior(i, j) ! bitwise OR of 2 integers. + v = log10(x) ! log base 10. + i = floor(b) ! returns the closest integer less than or equal to x. + v = aimag(w) ! imaginary part of a complex number. ! Functions & Subroutines ! ======================= @@ -263,70 +251,69 @@ program example !declare a program called example. ! A subroutine runs some code on some input values and can cause ! side-effects or modify the input values. - call routine(a,c,v) !subroutine call. + call routine(a, c, v) ! subroutine call. ! A function takes a list of input parameters and returns a single value. ! However the input parameters may still be modified and side effects ! executed. - m = func(3,2,k) !function call. + m = func(3, 2, k) ! function call. ! Function calls can also be evoked within expressions. - Print *, func2(3,2,k) + print *, func2(3, 2, k) ! A pure function is a function that doesn't modify its input parameters ! or cause any side-effects. - m = func3(3,2,k) - + m = func3(3, 2, k) -contains ! Zone for defining sub-programs internal to the program. +contains ! Zone for defining sub-programs internal to the program. ! Fortran has a couple of slightly different ways to define functions. - integer function func(a,b,c) !a function returning an integer value. - implicit none !best to use implicit none in function definitions too. - integer :: a,b,c !type of input parameters defined inside the function. + integer function func(a, b, c) ! a function returning an integer value. + ! implicit none ! subvariable fields can no longer declare implicit none + integer, intent(in) :: a, b, c ! type of input parameters defined inside the function. + if (a >= 2) then - func = a + b + c !the return variable defaults to the function name. - return !can return the current value from the function at any time. - endif + func = a + b + c ! the return variable defaults to the function name. + return ! can return the current value from the function at any time. + end if func = a + c + ! Don't need a return statement at the end of a function. end function func - - function func2(a,b,c) result(f) !return variable declared to be 'f'. - implicit none - integer, intent(in) :: a,b !can declare and enforce that variables - !are not modified by the function. + function func2(a, b, c) result(f) ! return variable declared to be 'f'. + integer, intent(in) :: a, b ! can declare and enforce that variables + !are not modified by the function. integer, intent(inout) :: c - integer :: f !function return type declared inside the function. - integer :: cnt = 0 !GOTCHA - initialisation implies variable is - !saved between function calls. + integer :: f ! function return type declared inside the function. + integer :: cnt = 0 ! GOTCHA - initialisation implies variable is + !saved between function calls. + f = a + b - c - c = 4 !altering the value of an input variable. - cnt = cnt + 1 !count number of function calls. - end function func2 + c = 4 ! altering the value of an input variable. + cnt = cnt + 1 ! count number of function calls. + end function func2 - pure function func3(a,b,c) !a pure function can have no side-effects. - implicit none - integer, intent(in) :: a,b,c + pure function func3(a, b, c) ! a pure function can have no side-effects. + integer, intent(in) :: a, b, c integer :: func3 + func3 = a*b*c - end function func3 + end function func3 - subroutine routine(d,e,f) - implicit none + subroutine routine(d, e, f) real, intent(inout) :: f - real, intent(in) :: d,e - f = 2*d + 3*e + f - end subroutine routine + real, intent(in) :: d, e + f = 2*d + 3*e + f -end program example ! End of Program Definition ----------------------- + end subroutine routine +end program example ! End of Program Definition ----------------------- ! Functions and Subroutines declared externally to the program listing need ! to be declared to the program using an Interface declaration (even if they @@ -338,9 +325,10 @@ elemental real function func4(a) result(res) ! but can also be used on an array where it will be separately applied to all ! of the elements of an array and return a new array. real, intent(in) :: a + res = a**2 + 1.0 -end function func4 +end function func4 ! Modules ! ======= @@ -349,22 +337,23 @@ end function func4 ! subroutines together for reusability. module fruit + real :: apple real :: pear real :: orange -end module fruit +end module fruit module fruity ! Declarations must be in the order: modules, interfaces, variables. ! (can declare modules and interfaces in programs too). use fruit, only: apple, pear ! use apple and pear from fruit module. - implicit none !comes after module imports. + implicit none ! comes after module imports. - private !make things private to the module (default is public). + private ! make things private to the module (default is public). ! Declare some variables/functions explicitly public. - public :: apple,mycar,create_mycar + public :: apple, mycar, create_mycar ! Declare some variables/functions private to the module (redundant here). private :: func4 @@ -389,13 +378,15 @@ module fruity ! ================== ! Can create custom structured data collections. type car - character (len=100) :: model - real :: weight !(kg) - real :: dimensions(3) !i.e. length-width-height (metres). + character(len=100) :: model + real :: weight ! (kg) + real :: dimensions(3) ! i.e. length-width-height (metres). character :: colour + contains + procedure :: info ! bind a procedure to a type. end type car - type(car) :: mycar !declare a variable of your custom type. + type(car) :: mycar ! declare a variable of your custom type. ! See create_mycar() routine for usage. ! Note: There are no executable statements in modules. @@ -404,35 +395,48 @@ contains subroutine create_mycar(mycar) ! Demonstrates usage of a derived data type. - implicit none - type(car),intent(out) :: mycar + type(car), intent(out) :: mycar ! Access type elements using '%' operator. mycar%model = "Ford Prefect" mycar%colour = 'r' mycar%weight = 1400 - mycar%dimensions(1) = 5.0 !default indexing starts from 1! + mycar%dimensions(1) = 5.0 ! default indexing starts from 1! mycar%dimensions(2) = 3.0 mycar%dimensions(3) = 1.5 - end subroutine + end subroutine create_mycar + + subroutine info(self) + class(car), intent(in) :: self + ! 'class' keyword used to bind a procedure to a type here. + + print *, "Model : ", self%model + print *, "Colour : ", self%colour + print *, "Weight : ", self%weight + print *, "Dimensions: ", self%dimensions - real function real_abs(x) - real :: x - if (x<0) then + end subroutine info + + real pure function real_abs(x) + real, intent(in) :: x + + if (x < 0) then real_abs = -x else real_abs = x end if + end function real_abs - real function complex_abs(z) - complex :: z + real pure function complex_abs(z) + complex, intent(in) :: z ! long lines can be continued using the continuation character '&' + complex_abs = sqrt(real(z)**2 + & - aimag(z)**2) - end function complex_abs + aimag(z)**2) + end function complex_abs end module fruity diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown index a5db24b2..bd4e1312 100644 --- a/fr-fr/awk-fr.html.markdown +++ b/fr-fr/awk-fr.html.markdown @@ -217,7 +217,7 @@ function string_functions( localvar, arr) { # Les deux renvoient le nombre de correspondances remplacées localvar = "fooooobar"; sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar" - gsub("e", ".", localvar); # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar); # localvar => "M..t m. at th. bar" # Rechercher une chaîne de caractères qui correspond à une expression # régulière index() fait la même chose, mais n'autorise pas les expressions diff --git a/fr-fr/elixir-fr.html.markdown b/fr-fr/elixir-fr.html.markdown index 90cdad7c..f8250e16 100644 --- a/fr-fr/elixir-fr.html.markdown +++ b/fr-fr/elixir-fr.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] diff --git a/fr-fr/git-fr.html.markdown b/fr-fr/git-fr.html.markdown index 00b6b6e1..a4d0c185 100644 --- a/fr-fr/git-fr.html.markdown +++ b/fr-fr/git-fr.html.markdown @@ -171,6 +171,7 @@ $ git init --help Ne plus suivre certains fichiers et dossiers de Git. Habituellement fait pour les fichiers privés et temporaires qui seraient, autrement, partagés dans le dépôt. + ```bash $ echo "temp/" >> .gitignore $ echo "cle_privee" >> .gitignore @@ -466,6 +467,7 @@ Vous pouvez maintenant pull ! ```bash git pull ``` + `...changes apply...` Vérifiez maintenant que tout est OK diff --git a/fr-fr/go-fr.html.markdown b/fr-fr/go-fr.html.markdown index 38cc3b52..5468096a 100644 --- a/fr-fr/go-fr.html.markdown +++ b/fr-fr/go-fr.html.markdown @@ -87,7 +87,7 @@ sauts de ligne.` // Chaîne de caractère. g := 'Σ' // type rune, un alias pour le type int32, contenant un caractère // unicode. - f := 3.14195 // float64, un nombre flottant IEEE-754 de 64-bit. + f := 3.14159 // float64, un nombre flottant IEEE-754 de 64-bit. c := 3 + 4i // complex128, considéré comme deux float64 par le compilateur. // Syntaxe "var" avec une valeur d'initialisation. @@ -422,18 +422,18 @@ func requestServer() { ## En savoir plus -La référence Go se trouve sur [le site officiel de Go](http://golang.org/). +La référence Go se trouve sur [le site officiel de Go](https://go.dev/). Vous pourrez y suivre le tutoriel interactif et en apprendre beaucoup plus. Une lecture de la documentation du langage est grandement conseillée. C'est facile à lire et très court (comparé aux autres langages). -Vous pouvez exécuter et modifier le code sur [Go playground](https://play.golang.org/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://play.golang.org](https://play.golang.org) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go. +Vous pouvez exécuter et modifier le code sur [Go playground](https://go.dev/play/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://go.dev/play/](https://go.dev/play/) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go. Sur la liste de lecteur des étudiants de Go se trouve le [code source de la -librairie standard](http://golang.org/src/pkg/). Bien documentée, elle démontre +librairie standard](https://go.dev/src/). Bien documentée, elle démontre le meilleur de la clarté de Go, le style ainsi que ses expressions. Sinon, vous pouvez cliquer sur le nom d'une fonction dans [la -documentation](http://golang.org/pkg/) et le code source apparaît! +documentation](https://go.dev/pkg/) et le code source apparaît! Une autre excellente ressource pour apprendre est [Go par l'exemple](https://gobyexample.com/). diff --git a/fr-fr/markdown-fr.html.markdown b/fr-fr/markdown-fr.html.markdown index 1fd22883..f5d6aacc 100644 --- a/fr-fr/markdown-fr.html.markdown +++ b/fr-fr/markdown-fr.html.markdown @@ -178,7 +178,7 @@ Vous pouvez également utiliser des sous-listes. 1. Item un 2. Item deux 3. Item trois - * Sub-item + * Sub-item * Sub-item 4. Item quatre ``` @@ -210,7 +210,7 @@ l'intérieur du bloc de code. ```md my_array.each do |item| - puts item + puts item end ``` @@ -223,13 +223,15 @@ La fonction `run()` ne vous oblige pas à aller courir! En Markdown GitHub, vous pouvez utiliser des syntaxes spécifiques. - ```ruby - def foobar - puts "Hello world!" - end - ``` +````md +```ruby +def foobar + puts "Hello world!" +end +``` +```` -Pas besoin d'indentation pour le code juste au-dessus, de plus, GitHub +Pas besoin d'indentation pour le code juste au-dessus, de plus, GitHub va utiliser une coloration syntaxique pour le langage indiqué après les <code>```</code>. ## Ligne Horizontale @@ -267,13 +269,13 @@ Markdown supporte aussi les liens relatifs. Les liens de références sont eux aussi disponibles en Markdown. -<div class="highlight"><code><pre> -[<span class="nv">Cliquez ici</span>][<span class="ss">link1</span>] pour plus d'information! -[<span class="nv">Regardez aussi par ici</span>][<span class="ss">foobar</span>] si vous voulez. +```md +[Cliquez ici][link1] pour plus d'information! +[Regardez aussi par ici][foobar] si vous voulez. -[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Cool!"</span> -[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Génial!"</span> -</pre></code></div> +[link1]: http://test.com/ "Cool!" +[foobar]: http://foobar.biz/ "Génial!" +``` Le titre peut aussi être entouré de guillemets simples, ou de parenthèses, ou absent. Les références peuvent être placées où vous voulez dans le document et @@ -282,11 +284,11 @@ les identifiants peuvent être n'importe quoi tant qu'ils sont uniques. Il y a également le nommage implicite qui transforme le texte du lien en identifiant. -<div class="highlight"><code><pre> -[<span class="nv">Ceci</span>][] est un lien. +```md +[Ceci][] est un lien. -[<span class="nv">Ceci</span>]:<span class="sx">http://ceciestunlien.com/</span> -</pre></code></div> +[Ceci]:http://ceciestunlien.com/ +``` Mais ce n'est pas beaucoup utilisé. @@ -301,12 +303,11 @@ d'un point d'exclamation! Là aussi, on peut utiliser le mode "références". +```md +![Ceci est l'attribut ALT de l'image][monimage] -<div class="highlight"><code><pre> -![<span class="nv">Ceci est l'attribut ALT de l'image</span>][<span class="ss">monimage</span>] - -[<span class="nv">monimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"si vous voulez un titre, c'est ici."</span> -</pre></code></div> +[monimage]: relative/urls/cool/image.jpg "si vous voulez un titre, c'est ici." +``` ## Divers @@ -334,7 +335,7 @@ Tapez \*ce texte\*. ### Touches de clavier -Avec le "Github Flavored Markdown", vous pouvez utiliser la balise `<kdb>` +Avec le "GitHub Flavored Markdown", vous pouvez utiliser la balise `<kdb>` pour représenter une touche du clavier. ```md @@ -348,10 +349,10 @@ Les tableaux ne sont disponibles que dans le "GitHub Flavored Markdown" et ne sont pas tres agréable d'utilisation. Mais si vous en avez besoin : ```md -| Col1 | Col2 | Col3 | -| :----------- | :------: | ------------: | -| Alignement Gauche | Centré | Alignement Droite | -| bla | bla | bla | +| Col1 | Col2 | Col3 | +| :---------------- | :------: | ----------------: | +| Alignement Gauche | Centré | Alignement Droite | +| bla | bla | bla | ``` ou bien, pour un résultat équivalent : diff --git a/fr-fr/pyqt-fr.html.markdown b/fr-fr/pyqt-fr.html.markdown index 6da9a380..7f0f018b 100644 --- a/fr-fr/pyqt-fr.html.markdown +++ b/fr-fr/pyqt-fr.html.markdown @@ -14,14 +14,14 @@ lang: fr-fr Ceci est une adaptation de l'intro C++ à QT par [Aleksey Kholovchuk](https://github.com/vortexxx192 ), certains exemples du code doivent avoir la même fonctionnalité, -cette version ayant juste été faite en utilisant pyqt! +cette version ayant juste été faite en utilisant pyqt! ```python import sys from PyQt4 import QtGui - + def window(): - # Création de l'objet application + # Création de l'objet application app = QtGui.QApplication(sys.argv) # Création d'un widget où notre label sera placé w = QtGui.QWidget() @@ -47,7 +47,7 @@ if __name__ == '__main__': Pour obtenir certaines des fonctionnalités les plus avancées de **pyqt** nous devons commencer par chercher à construire des éléments supplémentaires. Ici nous voyons comment introduire une boîte de dialogue popup, utile pour demander une confirmation à un utilisateur ou fournir des informations. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -66,7 +66,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Cette fonction devrait créer une fenêtre de dialogue avec un bouton # qui attend d'être cliqué puis quitte le programme def showdialog(): diff --git a/fr-fr/wolfram-fr.html.markdown b/fr-fr/wolfram-fr.html.markdown index 7b446259..10a37994 100644 --- a/fr-fr/wolfram-fr.html.markdown +++ b/fr-fr/wolfram-fr.html.markdown @@ -21,7 +21,7 @@ Ce code d'exemple peut être utilisé et modifié dans ces logiciels. Cependant, copier-coller directement dans Mathematica peut causer des problèmes de formatage, car il ne contient aucune information de mise en page. -``` +```mathematica (* Ceci est un commentaire *) (* Dans Mathematica, au lieu d'utiliser ces commentaires, vous pouvez créer des diff --git a/fsharp.html.markdown b/fsharp.html.markdown index c140d6b1..f1f8e95d 100644 --- a/fsharp.html.markdown +++ b/fsharp.html.markdown @@ -33,6 +33,21 @@ let myInt = 5 let myFloat = 3.14 let myString = "hello" // note that no types needed +// Mutable variables +let mutable a=3 +a <- 4 // a is now 4. + +// Somewhat mutable variables +// Reference cells are storage locations that enable you to create mutable values with reference semantics. +// See https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/reference-cells +let xRef = ref 10 +printfn "%d" xRef.Value // 10 +xRef.Value <- 11 +printfn "%d" xRef.Value // 11 + +let a=[ref 0; ref 1] // somewhat mutable list +a[0].Value <- 2 + // ------ Lists ------ let twoToFive = [2; 3; 4; 5] // Square brackets create a list with // semicolon delimiters. diff --git a/git.html.markdown b/git.html.markdown index b587e624..9d33225f 100644 --- a/git.html.markdown +++ b/git.html.markdown @@ -583,7 +583,8 @@ $ git rm /pather/to/the/file/HelloWorld.c ``` ### blame -Examine specific parts of the code's history and find out who was the last author to modify that line +Examine specific parts of the code's history and find out who was the last author to modify that line. + ```bash # find the authors on the latest modified lines $ git blame google_python_style.vim diff --git a/go.html.markdown b/go.html.markdown index fe69ed43..59ba2e4f 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -46,7 +46,7 @@ package main import ( "fmt" // A package in the Go standard library. "io/ioutil" // Implements some I/O utility functions. - "math" // Math library with local alias m. + m "math" // Math library with local alias m. "net/http" // Yes, a web server! "os" // OS functions like working with the file system "strconv" // String conversions. @@ -95,7 +95,7 @@ can include line breaks.` // Same string type. // Non-ASCII literal. Go source is UTF-8. g := 'Σ' // rune type, an alias for int32, holds a unicode code point. - f := 3.14195 // float64, an IEEE-754 64-bit floating point number. + f := 3.14159 // float64, an IEEE-754 64-bit floating point number. c := 3 + 4i // complex128, represented internally with two float64's. // var syntax with initializers. @@ -130,7 +130,7 @@ can include line breaks.` // Same string type. // Because they are dynamic, slices can be appended to on-demand. // To append elements to a slice, the built-in append() function is used. // First argument is a slice to which we are appending. Commonly, - // the array variable is updated in place, as in example below. + // the slice variable is updated in place, as in example below. s := []int{1, 2, 3} // Result is a slice of length 3. s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6. fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] @@ -357,7 +357,7 @@ func learnInterfaces() { // Functions can have variadic parameters. func learnVariadicParams(myStrings ...interface{}) { // Iterate each value of the variadic. - // The underbar here is ignoring the index argument of the array. + // The underscore here is ignoring the index argument of the array. for _, param := range myStrings { fmt.Println("param:", param) } @@ -456,21 +456,21 @@ func requestServer() { ## Further Reading -The root of all things Go is the [official Go web site](http://golang.org/). +The root of all things Go is the [official Go web site](https://go.dev/). There you can follow the tutorial, play interactively, and read lots. -Aside from a tour, [the docs](https://golang.org/doc/) contain information on +Aside from a tour, [the docs](https://go.dev/doc/) contain information on how to write clean and effective Go code, package and command docs, and release history. -The [Go language specification](https://golang.org/ref/spec) itself is highly recommended. It's easy to read +The [Go language specification](https://go.dev/ref/spec) itself is highly recommended. It's easy to read and amazingly short (as language definitions go these days.) -You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://play.golang.org](https://play.golang.org) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go. +You can play around with the code on [Go playground](https://go.dev/play/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://go.dev/play/](https://go.dev/play/) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go. On the reading list for students of Go is the [source code to the standard -library](http://golang.org/src/pkg/). Comprehensively documented, it +library](https://go.dev/src/). Comprehensively documented, it demonstrates the best of readable and understandable Go, Go style, and Go idioms. Or you can click on a function name in [the -documentation](http://golang.org/pkg/) and the source code comes up! +documentation](https://go.dev/pkg/) and the source code comes up! Another great resource to learn Go is [Go by example](https://gobyexample.com/). diff --git a/haskell.html.markdown b/haskell.html.markdown index 29712570..edb4121d 100644 --- a/haskell.html.markdown +++ b/haskell.html.markdown @@ -3,6 +3,7 @@ language: Haskell filename: learnhaskell.hs contributors: - ["Adit Bhargava", "http://adit.io"] + - ["Stanislav Modrak", "https://stanislav.gq"] --- Haskell was designed as a practical, purely functional programming @@ -602,6 +603,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater There are two popular ways to install Haskell: The traditional [Cabal-based installation](http://www.haskell.org/platform/), and the newer [Stack-based process](https://www.stackage.org/install). You can find a much gentler introduction from the excellent -[Learn you a Haskell](http://learnyouahaskell.com/), +[Learn you a Haskell](http://learnyouahaskell.com/) (or [up-to-date community version](https://learnyouahaskell.github.io/)), [Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) or [Real World Haskell](http://book.realworldhaskell.org/). diff --git a/hd-hd/amd.html.markdown b/hd-hd/amd.html.markdown index 0a6581d6..b85567c2 100644 --- a/hd-hd/amd.html.markdown +++ b/hd-hd/amd.html.markdown @@ -12,6 +12,7 @@ lang: hd जावास्क्रिप्ट मॉड्यूल ऐसे मॉड्यूल और इसकी अतुल्यकालिक निर्भरता से भरा हुआ है। यह ब्राउज़र पर्यावरण जहां के लिए विशेष रूप से अच्छी तरह से अनुकूल है, और प्रदर्शन , प्रयोज्य, डीबगिंग, और क्रॉस-डोमेन जैसे मॉड्यूल्स को जल्दी सिंक्रनाइज़ लोडिंग करता hai। ### मूल अवधारणा + ```javascript // बुनियादी एएमडी एपीआई दो तरीकों लेकिन कुछ भी नहीं होते : ` define` और` require` // और सभी मॉड्यूल परिभाषा और खपत के बारे में है : @@ -79,6 +80,7 @@ function require(deps, callback){ ### Require.js के साथ वास्तविक दुनिया के उपयोग परिचयात्मक उदाहरण के विपरीत, ` require.js` (सबसे लोकप्रिय एएमडी पुस्तकालय ) वास्तव में लागू करता है ** ** Amd ** में *A * **, आप XHR के माध्यम से मॉड्यूल और उनकी निर्भरता लोड करने के लिए सक्षम करने के लिए : + ```javascript /* file: app/main.js */ require(['modules/someClass'], function(SomeClass){ @@ -113,6 +115,7 @@ define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ return SomeClass; }); ``` + अपने ` main.js` में डिफ़ॉल्ट पथ मानचित्रण व्यवहार का उपयोग ` requirejs.config ( configObj ) ` में परिवर्तन करने के लिए: ```javascript @@ -131,6 +134,7 @@ require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolL coolLib.doFancyStuffWith(helpers.transform($('#foo'))); }); ``` + ` require.js` आधारित क्षुधा आमतौर पर एक डाटा विशेषता के रूप में ` require.js` स्क्रिप्ट टैग को पारित कर दिया है कि एक एकल प्रवेश बिंदु (` main.js` ) होगा। यह स्वचालित रूप से भरी हुई है और pageload पर क्रियान्वित किया जाएगा : ```html @@ -151,16 +155,19 @@ require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolL (राइनो भी समर्थन किया है, तो आप शायद Node.js में चलेगा ) ` require.js` ( अपनी परियोजना की निर्भरता ग्राफ का विश्लेषण , और अपने सभी मॉड्यूल युक्त एक एकल फाइल निर्माण कर सकते हैं कि ` r.js` नामक एक स्क्रिप्ट के साथ आता है ठीक से minified और उपभोग के लिए तैयार है, ) नाम दिया है। Install it using `npm`: + ```shell $ npm install requirejs -g ``` अब आप एक विन्यास फाइल के साथ फ़ीड कर सकते हैं: + ```shell $ r.js -o app.build.js ``` हमारे ऊपर के उदाहरण के लिए विन्यास की तरह लग सकता है: + ```javascript /* file : app.build.js */ ({ @@ -177,6 +184,7 @@ $ r.js -o app.build.js ``` उत्पादन में बनाया फ़ाइल का उपयोग करने के लिए, बस ` Data-main` स्वैप: + ```html <script src="require.js" data-main="app/main-built"></script> ``` diff --git a/hd-hd/d.html.markdown b/hd-hd/d.html.markdown index 96274e2b..f5e0858a 100644 --- a/hd-hd/d.html.markdown +++ b/hd-hd/d.html.markdown @@ -126,7 +126,6 @@ class Matrix(uint m, uint n, T = int) { } auto mat = new Matrix!(3, 3); - ``` Classes की बात हो रही है , एक दूसरे के लिए गुणों के बारे में बात करते हैं। एक संपत्ति @@ -176,8 +175,8 @@ class MyClass(T, U) { void main() { auto mc = new MyClass!(int, string)(7, "seven"); - करने के लिए लिखने के लिए मानक पुस्तकालय से - // आयात ' stdio ' मॉड्यूल + // करने के लिए लिखने के लिए मानक पुस्तकालय से + // आयात ' stdio ' मॉड्यूल // सांत्वना (आयात एक गुंजाइश के लिए स्थानीय हो सकता है) । import std.stdio; @@ -235,22 +234,21 @@ UFCS के साथ, हम एक विधि के रूप में ए एक विधि के रूप में ग्रुप ए की किसी भी अभिव्यक्ति पर कुछ प्रकार एक की है । मैं समानता चाहते । समानता की तरह कोई और? ज़रूर तुम करना। चलो कुछ करते हैं! + ```c import std.stdio; import std.parallelism : parallel; import std.math : sqrt; void main() { - // हम हमारे सरणी में वर्गमूल हर नंबर ले जाना चाहता हूँ , - // हम उपलब्ध है के रूप में और के रूप में कई कोर का लाभ ले। + // हम हमारे सरणी में वर्गमूल हर नंबर ले जाना चाहता हूँ , + // हम उपलब्ध है के रूप में और के रूप में कई कोर का लाभ ले। auto arr = new double[1_000_000]; - // संदर्भ के द्वारा एक सूचकांक , और एक सरणी तत्व का प्रयोग + // संदर्भ के द्वारा एक सूचकांक , और एक सरणी तत्व का प्रयोग // और सिर्फ सरणी पर समानांतर फोन! foreach(i, ref elem; parallel(arr)) { ref = sqrt(i + 1.0); } } - - ``` diff --git a/hocon.html.markdown b/hocon.html.markdown new file mode 100644 index 00000000..67ea30a2 --- /dev/null +++ b/hocon.html.markdown @@ -0,0 +1,574 @@ +--- +language: hocon +filename: learnhocon.conf +contributors: +- [TehBrian, 'https://tehbrian.xyz'] +--- + +Human-Optimized Configuration Object Notation, or HOCON, is a configuration and +data serialization format designed to be easily editable by humans. + +It's a superset of JSON, meaning that any valid JSON is valid HOCON, but it +differs in being much less pedantic and opinionated. With its flexible yet +easily determinable syntax, resulting configuration files are often much less +noisy than some other formats. + +Additionally, its support for comments makes it much better suited for +user-facing configurations than JSON. + +```hocon +// Comments can either look like this, +# or they can look like this. +// Anything after // or # is a comment. + +################## +### THE BASICS ### +################## + +# Everything in HOCON is either a key, a value, or a separator. +# : and = are separators. They separate the key from the value. +key: value +another_key = another_value + +# You can use either separator with or without whitespace on either side. +colon1:value +colon2: value +colon3 : value +equals1=value +equals2= value +equals3 = value +# As you'll see, HOCON is very nonrestrictive regarding its syntax style. + +# HOCON also isn't opinionated on how keys look. +THIS_IS_A_VALID_KEY: value +this-is-also-a-valid-key: value +keys can have spaces too: value +or even numbers like 12345: value +"you can even quote keys if you'd like!": value + +# A key, followed by any separator, and then finally a value, is called a field. +this_entire_line_is: a field + +################### +### VALUE TYPES ### +################### + +# The types that a value can be are string, number, object, array, boolean, and +# null. Every value type except for array and object are called simple values. + +## SIMPLE VALUES ## + +quoted_string: "I like quoting my strings." +unquoted_string: I don't like quoting my strings. +# Special characters that cannot be used in unquoted strings are: +# $ " { } [ ] : = , + # ` ^ ? ! @ * & +# Unquoted strings do not support any kind of escaping. If using one of those +# special characters is desired, use a quoted string. +multi-line_string: """ + This entire thing is a string! + One giant, multi-line string. + You can put 'single' and "double" quotes without it being invalid. +""" + +number: 123 +negative: -123 +fraction: 3.1415926536 +scientific_notation: 1.2e6 // same as 1.2 * (10^6) + +boolean: true # or false +empty: null + +## ARRAYS ## + +# Arrays hold lists of values. +# Values in arrays can be separated with commas.. +array: [ 1, 2, 3, 4, 5 ] +fibonacci: [1,1,2,3,5,8,13] +multiples_of_5: [5, 10, 15, 20,] # Notice the trailing comma. That's okay here. +# or newlines.. +friends: [ + "Brian" + "Sophie" + "Maya" + "Sabina" +] +# or both! +ingredients: [ + "Egg", + "Sugar", + "Oil", + "Flour", # Notice the trailing comma. That's okay here too. +] +# Once again, HOCON has a very loose syntax. Use whichever style you prefer. +no newline before or after bracket: ["This" + "is" + "an" + "array!"] + +# Just like any other value, arrays can hold other arrays. +array in array: [ [1, 2, 3], ["a", "b", "c"] ] +array in array in array: [ [ [1, 2], [8, 9] ], [ ["a", "b" ], ["y", "z"] ] ] + +## OBJECTS ## + +# Objects hold fields. +# Just like arrays, fields in objects can be separated with commas.. +object: { key: value, another_key: another_value } +server_connection: {ip: "127.0.0.1", port: 80} +first: {letter: a, number: 1,} # Notice the trailing comma. +# or newlines.. +power_grid: { + max_capacity: 15000 + current_power: 1200 +} +# or both! +food_colors: { + carrot: orange, + pear: green, + apple: red, + plum: purple, + banana: yellow, # Trailing commas are okay here too! +} + +# Arrays can hold objects just like any other value type. +coworkers: [ + { + name: Jeff + age: 27 + }, + { + name: Henry + age: 35 + }, + { + name: Timmy + age: 12 + } +] + +# The field separator may be omitted if the key is followed by { +no_separator { + key: value + speed_of_light: very fast + ten: 10 + + # Objects can go inside other objects just like any other value. + another_object { + twenty: 20 + speed_of_sound: also pretty fast + } +} + +# In fact, the entirety of any HOCON document is an actually just an object. +# That object is called the root object. The only difference between it and any +# other object is that the curly brackets at the top and bottom of the document +# may be omitted. + +# This means that HOCON documents can be formatted in the same way that +# regular objects can be formatted, including separating fields with commas +# rather than with newlines. + +# Additionally, while the entirety of a HOCON document can be and is usually an +# object, it can also be an array. If it is an array, the opening and closing +# brackets at the top and bottom of the document must be explicitly written. + +###################### +### DUPLICATE KEYS ### +###################### + +is_happy: false +# If there is a duplicate key, the new value overrides the previous value. +is_happy: true +online_users: [Jacob, Mike] +# Same with arrays. +online_users: [Jacob, Mike, Henry] + +# For objects, it's a bit different. +my_car: { + color: blue + speed: 9001 + passengers: null + + engine: { + running: true + temperature: 137 + } +} +# If there is a duplicate key and both values are objects, +# then the objects are merged. +my_car: { + // These fields are added to the old, previous object. + nickname: "My Favorite Car" + type: 2-door sedan + + // Since the value of this duplicate key is NOT an object, + // it simply overrides the previous value. + speed: 60 + // Same with arrays. They override, not merge. + passengers: ["Nate", "Ty"] + + // This object is recursively merged with the other object. + engine: { + // These two fields are added to the previous object. + type: gas + oil_level: 10 + // This field overrides the previous value. + temperature: 179 + } +} + +# Object merging is done two at a time. That is to say, the first two objects +# merge into one, then that object merges with the next object, and so on. + +# Because of this, if you set a field with an object value to a non-object value +# and then back to an object value, the new object will completely override any +# previous value. + +// Null, a non-object value, completely overrides the object value. +my_car: null + +// Then, this object completely overrides null. +my_car: { + nickname: "My New Car" + type: 4-door minivan + color: gray + speed: 90 + passengers: ["Ayden", "Liz"] +} + +########################### +### VALUE CONCATENATION ### +########################### + +## SIMPLE VALUE CONCATENATION ## + +# Simple values (all value types except objects and arrays) separated by +# whitespace are concatenated into a single string. The whitespace between +# values is preserved. +number_concatenation: 1 2 3 12.5 -3 2e5 // same as: "1 2 3 12.5 -3 2e5" +boolean_concat: true false true // "true false true" +null_concat: null null null // "null null null" +mixed_concat: 1 true null // "1 true null" + +# String value concatenation can appear anywhere that a quoted string can. +number_concat_in_array: [1 2, 3 4, 5 6] // same as: ["1 2", "3 4", "5 6"] + +# In fact, unquoted strings are actually just string value concatenations. +unquoted_string_concat: his name is jeff // same as: "his name is jeff" + +# Going further, even keys that are unquoted strings are actually just string +# value concatenations. +this is a key: value // the KEY is the same as: "this is a key" +# The following field is identical to the field above. +"this is a key": value + +# Quoted strings can also be concatenated. This will be useful later, +# when we cover substitutions. +quoted_string_concat: "her"" name" "is ""jenna" // same as: "her name is jenna" +# Notice that the whitespace (or lack thereof) between values is preserved. + +## ARRAY CONCATENATION ## + +# Arrays separated by whitespace are merged into a single array. +array_concat: [1, 2, 3] [4, 5, 6] // same as: [1, 2, 3, 4, 5, 6] + +# Arrays cannot be concatenated with a non-array value. +//array_concat: true [false] results in an error +//array_concat: 1 [2] results in an error + +## OBJECT CONCATENATION ## + +# Objects separated by whitespace are merged into a single object. +# The merge functionality is identical to that of duplicate key object merging. +lamp: {on: true} {color: tan} // same as: {on: true, color: tan} + +# Similarly to arrays, objects cannot be concatenated with a non-object value. +//object_concat: true {on: false} results in an error +//object_concat: 1 {number: 2} results in an error + +######################## +### PATH EXPRESSIONS ### +######################## + +# Path expressions are used to write out a path through the object graph. +# Think of it as navigating through objects to a specific field. +# Each object to traverse through is called an element, and each element is +# separated with a period. + +country: { + city: { + neighborhood: { + house: { + name: "My House" + address: 123 Example Dr. + } + } + } +} +# For example, the path to the address of the house could be written as: +# country.city.neighborhood.house.address +# Country, city, neighborhood, house, and address are all elements. + +# Path expressions are used in two places: substitutions (which will be +# covered in a moment), and as keys. +# That's right: keys themselves can also be path expressions. +foo: { + bar: { + baz: { + number: 12 + } + } +} +# Rather than tediously specifying each object, a path expression can be used. +# The following field represents the same object found above. +foo.bar.baz.number: 12 + +# Fields and objects specified with path expressions are merged in the same way +# that any object is usually merged. +foo.bar.baz.bool: true +// the object foo's value is: foo { bar { baz { number: 12, bool: true } } } + +##################### +### SUBSTITUTIONS ### +##################### + +# Substitutions refer to a specific value from some path expression. +# They're only allowed in values, not keys or nested inside other substitutions. + +me: { + favorite_animal: parrots + favorite_food: cookies +} +# The syntax for a substitution is either ${path_expression} or +# ${?path_expression}. The latter syntax will be discussed in a moment. +my_fav_animal: ${me.favorite_animal} +my_fav_food: ${me.favorite_food} + +# Substitutions are not parsed inside quoted strings. To get around this, +# either use an unquoted string or value concatenation. +animal_announcement: My favorite animal is ${my_fav_animal} +// the value is: My favorite animal is parrots +food_announcement: "My favorite food is "${my_fav_food}"!" +// the value is: "My favorite food is cookies!" + +# Substitutions are parsed last in the document. Because of this, you can +# reference a key that hasn't been defined yet. +color_announcement: "My favorite color is" ${my_fav_color}"!" +// the value is: "My favorite color is blue!" +my_fav_color: blue + +# Another effect of substitutions being parsed last is that substitutions will +# always use the latest, as in last, value assigned in the entire document, +# which includes merged objects. +color: green +their_favorite_color: ${color} // the value is: orange +color: orange + +random_object: { + number: 12 +} +the_number: ${random_object.number} // the value is: 15 +random_object: { + number: 15 +} + +############################### +### UNDEFINED SUBSTITUTIONS ### +############################### + +# A substitution using the ${path_expression} syntax with an undefined path +# expression, meaning a path expression that does not point to a defined value, +# is invalid and will therefore generate an error. +//${does.not.exist} will throw an error + +# However, an undefined substitution using the ${?path_expression} syntax +# has different behavior depending on what it is the value of. +request: { + # If it is the value of a field, then the field will not be created. + response: ${?does.not.exist} // this field won't be created and does not exist + type: HTTP +} + +request: { + # Additionally, if it would have overridden a previous value, then the + # previous value remains unchanged. + type: ${?does.not.exist} // request.type is still HTTP +} + +# If it is a value in an array, then it is simply not added. +values: [ 172, "Brian", ${?does.not.exist}, null, true, ] +// the value is: [ 172, "Brian", null, true ] + +# If it is part of simple value concatenation, it acts as an empty string. +final_string: "String One"${?does.not.exist}"String Two" +// the value is: "String OneString Two" + +# If it is part of array concatenation, it acts as an empty array. +final_array: [ 1, 2, 3 ] ${?does.not.exist} [ 7, 8, 9 ] +// the value is: [ 1, 2, 3, 7, 8, 9 ] + +# If it is part of object concatenation, it acts as an empty object. +final_array: { a: 1 } ${?does.not.exist} { c: 3 } +// the value is: { a: 1, c: 3 } + +###################################### +### SELF-REFERENTIAL SUBSTITUTIONS ### +###################################### + +# Substitutions normally "look forward" and use the final value defined in the +# document. However, in cases when this would create a cycle, the substitution +# looks only backwards. + +# A field which contains a substitution that points to itself or points to +# other fields that eventually point back to itself is called a +# self-referential field. +letters: "a b c" // the value is: "a b c" +letters: ${letters}" d" // "a b c d" +letters: ${letters}" e" // "a b c d e" + +PATH: [/bin] // the value is: [/bin] +PATH: ${PATH} [/usr/bin] // [/bin, /usr/bin] +PATH: ${PATH} [/usr/local/bin] // [/bin, /usr/bin, /usr/local/bin] + +x: "x" // the value is: "x" +y: ${x}"y" // "xy" +x: ${y}"z" // "xyz" + +########################## +### += FIELD SEPARATOR ### +########################## + +# In addition to : and =, there actually exists another separator: += +# A field separated with += acts as a self-referential array concatenation. +# In short, it appends an element to a previously defined array. + +a: [1] +b: [1] +# This field: +a += 2 // the value is: [1, 2] +# functions the same as: +b: ${?b} [2] // the value is: [1, 2] + +USERS: [/usr/luke] // the value is: [/usr/luke] +USERS += /usr/devon // [/usr/luke, /usr/devon] +USERS += /usr/michael // [/usr/luke, /usr/devon, /usr/michael] + +# Since += only appends elements to a previously existing array, if the previous +# value was not an array, an error will be generated. +OTHER_USERS: /usr/luke +//OTHER_USERS += /usr/devon results in an error + +# Notice that the underlying substitution syntax used is ${?path}, not ${path}. +# Recall that, using the ${?} syntax, an undefined substitution in array +# concatenation acts as an empty array. Because of this, it is perfectly +# acceptable if the field that is being set is initially undefined. +//z: [] not necessary +z += 3 // the value is: [3] +z += 4 // the value is: [3, 4] + +NEW_USERS += /usr/sandra // the value is: [/usr/sandra] +NEW_USERS += /usr/kennedy // [/usr/sandra, /usr/kennedy] +NEW_USERS += /usr/robin // [/usr/sandra, /usr/kennedy, /usr/robin] + +################ +### INCLUDES ### +################ + +# Includes allow you to "import" one HOCON document into another. + +# An include statement consists of the unquoted string "include" followed by +# whitespace and then a resource name, which is one of the following: +# - a single quoted string which is heuristically interpreted as a URL, +# filename, or a Java classpath resource. +# - url(), file(), or classpath(), with the parentheses surrounding a quoted +# string which is either a URL, filename, or classpath resource respectively. +# - required(), with the parentheses surrounding one of the above. +include "https://example.com/config.conf" +include "/foo/bar/config.conf" +include "config.conf" + +include url("https://example.com/config.conf") +include file("/foo/bar/config.conf") +include classpath("config.conf") + +# If the included file does not exist, it will be silently ignored and act as if +# it were an empty object. However, if it is wrapped around required(), then +# parsing will explicitly error if the file cannot be resolved. +//include required("doesnt_exist.conf") will error +//include required(url("https://example.com/doesnt_exist.conf")) will error +//include required(file("doesnt_exist.conf")) will error +//include required(classpath("doesnt_exist.conf")) will error + +# The file specified by the include statement is called the included file, and +# the file which contains the include statement is called the including file. + +# Including a file functions as if you directly replaced the include statement, +# wherever it may be, with the contents of the included file's root object. + +# An included file must have an object as its root value and not an array. +# If the included file has an array as its root value, then it is invalid and +# an error will be generated. + +# Pretend that the following is in a file called user_config.conf: +username: RandomUser1337 +auto_login: true +color_theme: dark +screensaver: { + image: usr/images/screensaver.jpg + turn_on_after: 1m +} + +# And then we include that file. +include file("user_config.conf") + +# We can now reference values from that file! +path_to_user_screensaver: ${screensaver.image} // +greeting: "Welcome, "${username}"!" // the value is: "Welcome, RandomUser1337!" + +# Duplicate keys override as they normally do. +status: "Auto Login: "${auto_login} // the value is: "Auto Login: true" +auto_login: false +status: "Auto Login: "${auto_login} // the value is: "Auto Login: false" + +# Object merging is also the same as usual. +screensaver: { + // This gets added to the screensaver object. + enable_during_day: false + // This overrides the previous value. + turn_on_after: 30s +} + +# Include statements can appear in place of a field. Anywhere that a field +# could appear, an include statement could appear as well. + +# Pretend that the following is in a file called server_settings.conf: +max_connections: 10 +url: example.com +port: 80 +admin_page: { + username: admin + password: pass12345 +} + +# And then we include that file nested inside another object. +websites: { + my_epic_website: { + include file("server_settings.conf") + } +} + +# Now, we can reference the contents of server_settings.conf as if they +# had been written directly into the object my_epic_website. +server_port: ${websites.my_epic_website.port} + +the_password: "The password is: "${websites.my_epic_website.admin_page.password} +// the value is: The password is: pass12345 + +max_conn: "Max Connections: "${websites.my_epic_website.max_connections} +// the value is: Max Connections: 10 +``` + +### More Resources + ++ [Official HOCON Specification](https://github.com/lightbend/config/blob/master/HOCON.md) ++ [HOCON Playground](https://hocon-playground.herokuapp.com) diff --git a/httpie.html.markdown b/httpie.html.markdown new file mode 100644 index 00000000..40481dff --- /dev/null +++ b/httpie.html.markdown @@ -0,0 +1,120 @@ +--- +category: tool +tool: httpie +contributors: + - ["Adaías Magdiel", "https://github.com/AdaiasMagdiel"] +filename: learn-httpie.sh +--- + +HTTPie is a powerful command-line HTTP client designed for easy interaction +with HTTP servers. It provides a simple and intuitive interface, making it an +excellent tool for developers, testers, and system administrators. + +## Basic Usage + +HTTPie follows a simple syntax: http [flags] [METHOD] URL [items]. + +```bash +http GET https://api.example.com/posts +``` + +You can print the request without sending it by using the `--offline` flag. + +```bash +http --offline https://api.example.com/posts +``` + +### URL shortcuts for `localhost` + +HTTPie supports a curl-like shorthand for localhost. For instance, ":3000" +expands to "http://localhost:3000". If the port is omitted, it assumes port 80. + +```bash +http :/users # http://localhost/users +http :5000/rss # http://localhost:5000/rss +``` + +### Optional GET and POST + +If you don't specify the METHOD, the HTTPie will use: + +- GET for requests without body +- POST for requests with body + +```bash +http https://api.example.com/tags # GET tags +http https://api.example.com/tags title="Tutorial" slug="tutorial" # POST a new tag +``` + +## Querystring Parameters + + +If you're manually adding query string parameters in the terminal, try the +`param==value` syntax. It avoids shell escaping for & separators and +automatically URL-escapes special characters in parameter names and values. +This differs from parameters in the full URL, which HTTPie doesn't modify. + +```bash +http https://api.example.com/search q==httpie per_page==20 +``` + +## Sending Data + +You can send data in various formats such as JSON, form data, or files. + +### JSON Data + +```bash +http POST https://api.example.com/posts title="Hello" body="World" +``` + +### Form Data + +```bash +http -f POST https://api.example.com/submit name=John email=john@example.com +``` + +### Files + +```bash +http --form POST https://api.example.com/upload file@/path/to/file.txt +``` + +## Headers and Authentication + +HTTPie allows you to set headers and handle authentication easily. + +### Headers + +```bash +http GET https://api.example.com/posts Authorization:"Bearer Token" User-Agent:"HTTPie" +``` + +### Basic Authentication + +```bash +http -a username:password GET https://api.example.com/protected +``` + +### Bearer Authentication + +```bash +https -A bearer -a token https://api.example.com/admin +``` + +## Response Handling + +HTTPie provides various options for handling responses. + +```bash +http GET https://api.example.com/data Accept:application/json # Pretty Print JSON + +http GET https://api.example.com/image --output image.png # Save Response to File + +http --follow GET https://example.com # Follow Redirects +``` + +## Further Reading + +- [Official Documentation](https://httpie.io/docs/cli). +- [GitHub](https://github.com/httpie). diff --git a/hu-hu/go-hu.html.markdown b/hu-hu/go-hu.html.markdown index 638c9489..451f9147 100644 --- a/hu-hu/go-hu.html.markdown +++ b/hu-hu/go-hu.html.markdown @@ -89,7 +89,7 @@ func learnTypes() { g := 'Σ' // rúna(rune) típus, megegyezik az uint32-vel, egy UTF-8 karaktert // tárol - f := 3.14195 // float64, az IEEE-754 szabványnak megfelelő 64-bites + f := 3.14159 // float64, az IEEE-754 szabványnak megfelelő 64-bites // lebegőpontos szám c := 3 + 4i // complex128, belsőleg két float64-gyel tárolva @@ -325,7 +325,7 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { ## További olvasmányok -Minden Go-val kapcsolatos megtaláható a [hivatalos Go weboldalon](http://golang.org/). +Minden Go-val kapcsolatos megtaláható a [hivatalos Go weboldalon](https://go.dev/). Ott követhetsz egy tutorialt, játszhatsz a nyelvvel az interneten, és sok érdekességet olvashatsz. A nyelv specifikációját kifejezetten érdemes olvasni, viszonylag rövid és sokat tanul belőle az ember. diff --git a/hu-hu/pythonlegacy-hu.html.markdown b/hu-hu/pythonlegacy-hu.html.markdown index b5922766..483784ba 100644 --- a/hu-hu/pythonlegacy-hu.html.markdown +++ b/hu-hu/pythonlegacy-hu.html.markdown @@ -20,7 +20,7 @@ bele. Tulajdonképpen futtatható pszeudokód. Szívesen fogadok visszajelzéseket! Elérsz itt: [@louiedinh](http://twitter.com/louiedinh) vagy pedig a louiedinh [kukac] [google email szolgáltatása] címen. -Figyelem: ez a leírás a Python 2.7 verziójára vonatkozok, illetve +Figyelem: ez a leírás a Python 2.7 verziójára vonatkozik, illetve általánosságban a 2.x verziókra. A Python 2.7 azonban már csak 2020-ig lesz támogatva, ezért kezdőknek ajánlott, hogy a Python 3-mal kezdjék az ismerkedést. A Python 3.x verzióihoz a [Python 3 bemutató](http://learnxinyminutes.com/docs/python/) diff --git a/hy.html.markdown b/hy.html.markdown index f6bdead0..5eddbf55 100644 --- a/hy.html.markdown +++ b/hy.html.markdown @@ -174,10 +174,10 @@ True ; => True ; create lexical bindings with `let', all variables defined thusly ; have local scope -(let [[nemesis {"superman" "lex luther" +(let [nemesis {"superman" "lex luther" "sherlock" "moriarty" - "seinfeld" "newman"}]] - (for [(, h v) (.items nemesis)] + "seinfeld" "newman"}] + (for [[h v] (.items nemesis)] (print (.format "{0}'s nemesis was {1}" h v)))) ;; classes diff --git a/id-id/asciidoc-id.html.markdown b/id-id/asciidoc-id.html.markdown index ceb56b92..2843b8be 100644 --- a/id-id/asciidoc-id.html.markdown +++ b/id-id/asciidoc-id.html.markdown @@ -4,7 +4,7 @@ contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] translators: - ["Rizky Luthfianto", "http://github.com/rilut"] -filename: asciidoc-id.md +filename: asciidoc-id.adoc lang: id-id --- diff --git a/id-id/coffeescript-id.html.markdown b/id-id/coffeescript-id.html.markdown index 7fa40bb6..fc876184 100644 --- a/id-id/coffeescript-id.html.markdown +++ b/id-id/coffeescript-id.html.markdown @@ -16,7 +16,7 @@ dan kompatibel dengan semua *runtime* JavaScript. Lihat juga [website CoffeeScript](http://coffeescript.org/) yang memiliki tutorial lengkap tentang CoffeeScript. -```CoffeeScript +```coffeescript # CoffeeScript adalah bahasa hipster. # Mengikuti tren bahasa modern lainnya. # Sehingga, seperti Ruby dan Python, untuk komentar digunakan tanda pagar. diff --git a/id-id/markdown.html.markdown b/id-id/markdown.html.markdown index 1ff1963b..22fcb17f 100644 --- a/id-id/markdown.html.markdown +++ b/id-id/markdown.html.markdown @@ -54,8 +54,8 @@ __Dan juga teks ini.__ **_Dan juga ini!_** *__Dan ini!__* -<!-- Di markdown ala Github, yang digunakan untuk me-render berkas markdown pada -Github, kita juga punya coretan: --> +<!-- Di markdown ala GitHub, yang digunakan untuk me-render berkas markdown pada +GitHub, kita juga punya coretan: --> ~~Teks ini dirender dengan coretan.~~ @@ -155,7 +155,7 @@ di dalam kode Anda --> John bahkan tidak tahu apa fungsi dari `go_to()` ! -<!-- Di Markdown ala Github, Anda dapat menggunakan syntax spesial untuk kode --> +<!-- Di Markdown ala GitHub, Anda dapat menggunakan syntax spesial untuk kode --> \`\`\`ruby <!-- kecuali hapus backlash tersebut ketika melakukannya, hanya ```ruby ! --> def foobar @@ -163,7 +163,7 @@ def foobar end \`\`\` <!-- Disini juga, tidak ada backslashes, hanya ``` --> -<!-- Teks di atas tidak membutuhkan indentasi, plus Github akan menggunakan syntax +<!-- Teks di atas tidak membutuhkan indentasi, plus GitHub akan menggunakan syntax highlighting dari bahasa yang digunakan setelah ``` --> <!-- Horizontal rule (<hr />) --> @@ -236,14 +236,14 @@ Saya ingin mengetik *teks ini dikelilingi tanda bintang* tapi saya tidak mau tek miring, jadi saya melakukan: \*teks ini dikelilingi tanda bintang\*. <!-- Tombol keyboard --> -<!-- Pada Markdown ala Github, Anda dapat menggunakan tag <kbd> untuk merepresentasikan tombol +<!-- Pada Markdown ala GitHub, Anda dapat menggunakan tag <kbd> untuk merepresentasikan tombol keyboard --> Komputer Anda hang? Coba kirim sebuah <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> <!-- Tabel --> -<!-- Tabel hanya tersedia pada Markdown ala Github dan sedikit merepotkan, namun jika Anda +<!-- Tabel hanya tersedia pada Markdown ala GitHub dan sedikit merepotkan, namun jika Anda sangat menginginkannya: --> | Kol1 | Kol2 | Kol3 | diff --git a/id-id/pyqt-id.html.markdown b/id-id/pyqt-id.html.markdown index c4833d06..a9163326 100644 --- a/id-id/pyqt-id.html.markdown +++ b/id-id/pyqt-id.html.markdown @@ -15,10 +15,10 @@ lang: id-id Tulisan ini diadaptasi dari **Intro Qt untuk C++** oleh [Aleksey Kholovchuk](https://github.com/vortexxx192). Kode-kode yang tertulis di sini akan menghasilkan fungsionalitas yang sama. Bedanya, versi ini dibangun menggunakan **PyQt**! -```Python +```python import sys from PyQt4 import QtGui - + def window(): # Buat objek aplikasi app = QtGui.QApplication(sys.argv) @@ -45,7 +45,7 @@ if __name__ == '__main__': Untuk menunjukkan beberapa fitur yang lebih canggih di **PyQt**, kita akan membangun elemen tambahan. Di sini, kita akan membuat Kotak Popup Dialog, yang berguna untuk meminta pengguna untuk mengkonfirmasi keputusan atau untuk menampilkan informasi. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * diff --git a/id-id/rst-id.html.markdown b/id-id/rst-id.html.markdown index 06d80089..a5070d64 100644 --- a/id-id/rst-id.html.markdown +++ b/id-id/rst-id.html.markdown @@ -88,14 +88,14 @@ ini :) Ada berbagai macam cara untuk membuat tautan: -- Dengan menambahkan garis bawah setelah sebuah huruf : Github_ dan dengan +- Dengan menambahkan garis bawah setelah sebuah huruf : GitHub_ dan dengan menambahkan URL target setelah teks (cara ini mempunyai kelebihan dengan tidak memasukkan URL yang tidak penting ke dalam teks yang bisa dibaca). - Dengan mengetik URL lengkap yang dapat dipahami : https://github.com (akan otomatis diubah menjadi sebuah link) -- Dengan membuat link seperti di Markdown: `Github <https://github.com/>`_ . +- Dengan membuat link seperti di Markdown: `GitHub <https://github.com/>`_ . -.. _Github https://github.com/ +.. _GitHub https://github.com/ ``` diff --git a/it-it/asciidoc-it.html.markdown b/it-it/asciidoc-it.html.markdown index 47a57349..eaa2372b 100644 --- a/it-it/asciidoc-it.html.markdown +++ b/it-it/asciidoc-it.html.markdown @@ -6,7 +6,7 @@ contributors: translators: - ["Ale46", "https://github.com/ale46"] lang: it-it -filename: asciidoc-it.md +filename: asciidoc-it.adoc --- AsciiDoc è un linguaggio di markup simile a Markdown e può essere usato per qualsiasi cosa, dai libri ai blog. Creato nel 2002 da Stuart Rackman, questo linguaggio è semplice ma permette un buon numero di personalizzazioni. diff --git a/it-it/elixir-it.html.markdown b/it-it/elixir-it.html.markdown index 48afe0c8..ce3e4535 100644 --- a/it-it/elixir-it.html.markdown +++ b/it-it/elixir-it.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Luca 'Kino' Maroni", "https://github.com/kino90"] - ["Joao Marques", "http://github.com/mrshankly"] @@ -21,11 +21,11 @@ e molte altre funzionalità. # Non esistono commenti multilinea, # ma puoi concatenare più commenti. -# Per usare la shell di elixir usa il comando `iex`. +# Per usare la shell di Elixir usa il comando `iex`. # Compila i tuoi moduli con il comando `elixirc`. # Entrambi i comandi dovrebbero già essere nel tuo PATH se hai installato -# elixir correttamente. +# Elixir correttamente. ## --------------------------- ## -- Tipi di base @@ -87,7 +87,7 @@ multi-linea. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` in elixir restituisce il valore ASCII della lettera `a` +# `?a` in Elixir restituisce il valore ASCII della lettera `a` ?a #=> 97 # Per concatenare liste si usa `++`, per binari si usa `<>` @@ -112,7 +112,7 @@ minore..maggiore = 1..10 # Puoi fare pattern matching anche sugli intervalli 5 * 2 #=> 10 10 / 2 #=> 5.0 -# In elixir l'operatore `/` restituisce sempre un decimale. +# In Elixir l'operatore `/` restituisce sempre un decimale. # Per fare una divisione intera si usa `div` div(10, 2) #=> 5 @@ -173,7 +173,7 @@ else end # Ti ricordi il pattern matching? -# Moltre strutture di controllo di flusso in elixir si basano su di esso. +# Moltre strutture di controllo di flusso in Elixir si basano su di esso. # `case` ci permette di confrontare un valore a diversi pattern: case {:uno, :due} do @@ -307,7 +307,7 @@ Geometria.area({:cerchio, 3}) #=> 28.25999999999999801048 # Geometria.area({:cerchio, "non_un_numero"}) #=> ** (FunctionClauseError) no function clause matching in Geometria.area/1 -# A causa dell'immutabilità dei dati, la ricorsione è molto frequente in elixir +# A causa dell'immutabilità dei dati, la ricorsione è molto frequente in Elixir defmodule Ricorsione do def somma_lista([testa | coda], accumulatore) do somma_lista(coda, accumulatore + testa) @@ -382,7 +382,7 @@ end ## --------------------------- # Elixir si basa sul modello degli attori per la concorrenza. -# Tutto ciò di cui abbiamo bisogno per scrivere programmi concorrenti in elixir +# Tutto ciò di cui abbiamo bisogno per scrivere programmi concorrenti in Elixir # sono tre primitive: creare processi, inviare messaggi e ricevere messaggi. # Per creare un nuovo processo si usa la funzione `spawn`, che riceve una @@ -434,7 +434,7 @@ self() #=> #PID<0.27.0> ## Referenze -* [Getting started guide](http://elixir-lang.org/getting_started/1.html) dalla [pagina web ufficiale di elixir](http://elixir-lang.org) +* [Getting started guide](http://elixir-lang.org/getting_started/1.html) dalla [pagina web ufficiale di Elixir](http://elixir-lang.org) * [Documentazione Elixir](https://elixir-lang.org/docs.html) * ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) di Dave Thomas * [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown index 2af2468d..6f974c91 100644 --- a/it-it/go-it.html.markdown +++ b/it-it/go-it.html.markdown @@ -91,7 +91,7 @@ può includere andata a capo.` // Sempre di tipo stringa. // Stringa letterale non ASCII. I sorgenti Go sono in UTF-8. g := 'Σ' // Il tipo runa, alias per int32, è costituito da un code point unicode. - f := 3.14195 // float64, un numero in virgola mobile a 64-bit (IEEE-754) + f := 3.14159 // float64, un numero in virgola mobile a 64-bit (IEEE-754) c := 3 + 4i // complex128, rappresentato internamente con due float64. @@ -422,9 +422,9 @@ func richiediServer() { ## Letture consigliate -La risorsa più importante per imparare il Go è il [sito ufficiale di Go](http://golang.org/). +La risorsa più importante per imparare il Go è il [sito ufficiale di Go](https://go.dev/). Qui puoi seguire i tutorial, scrivere codice in modo interattivo, e leggere tutti i dettagli. -Oltre al tour, [la documentazione](https://golang.org/doc/) contiene informazioni su +Oltre al tour, [la documentazione](https://go.dev/doc/) contiene informazioni su come scrivere ottimo codice in Go, documentazione sui package e sui comandi, e la cronologia delle release. @@ -432,17 +432,17 @@ Anche il documento che definisce il linguaggio è un'ottima lettura. E' semplice da leggere e incredibilmente corto (rispetto ad altri documenti riguardanti la creazione di linguaggi). -Puoi giocare con il codice visto finora nel [Go playground](https://play.golang.org/p/Am120Xe7qf). +Puoi giocare con il codice visto finora nel [Go playground](https://go.dev/play/p/Am120Xe7qf). Prova a cambiarlo e ad eseguirlo dal browser! -Osserva che puoi usare [https://play.golang.org](https://play.golang.org) come +Osserva che puoi usare [https://go.dev/play/](https://go.dev/play/) come una [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per scrivere codice all'interno del browser, senza neanche installare Go! Una lettura importante per capire Go in modo più profondo è il [codice -sorgente della libreria standard](http://golang.org/src/pkg/). Infatti è +sorgente della libreria standard](https://go.dev/src/). Infatti è molto ben documentato e costituisce quanto più chiaro e conciso ci sia riguardo gli idiomi e le buone pratiche del Go. Inoltre, clickando sul nome di una -funzione [nella documentazione](http://golang.org/pkg/) compare il relativo +funzione [nella documentazione](https://go.dev/pkg/) compare il relativo codice sorgente! Un'altra ottima risorsa per imparare è [Go by example](https://gobyexample.com/). diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown index b0a123f1..609d3bb7 100644 --- a/it-it/markdown.html.markdown +++ b/it-it/markdown.html.markdown @@ -72,7 +72,7 @@ __Come pure questo.__ *__E questo!__* ``` -In Github Flavored Markdown, che è utilizzato per renderizzare i file markdown su Github, è presente anche lo stile barrato: +In GitHub Flavored Markdown, che è utilizzato per renderizzare i file markdown su GitHub, è presente anche lo stile barrato: ```md ~~Questo testo è barrato.~~ @@ -183,7 +183,7 @@ Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vo ```md my_array.each do |item| - puts item + puts item end ``` @@ -193,14 +193,17 @@ Codice inline può essere inserito usando il carattere backtick ` Giovanni non sapeva neppure a cosa servisse la funzione `go_to()`! ``` -In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice -<pre> -<code class="highlight">```ruby +In GitHub Flavored Markdown, potete inoltre usare una sintassi speciale per il codice + +````md +```ruby def foobar - puts "Hello world!" + puts "Hello world!" end -```</code></pre> -Se usate questa sintassi, il testo non richiederà di essere indentato, inoltre Github userà l'evidenziazione della sintassi del linguaggio specificato dopo i \`\`\` iniziali +``` +```` + +Se usate questa sintassi, il testo non richiederà di essere indentato, inoltre GitHub userà l'evidenziazione della sintassi del linguaggio specificato dopo i \`\`\` iniziali ## Linea orizzontale Le linee orizzontali (`<hr/>`) sono inserite facilmente usanto tre o più asterischi o trattini, con o senza spazi. @@ -253,7 +256,7 @@ Ma non è comunemente usato. Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre! ```md -![Qeusto è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale") +![Questo è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale") ``` E la modalità a riferimento funziona esattamente come ci si aspetta @@ -282,7 +285,7 @@ Voglio inserire *questo testo circondato da asterischi* ma non voglio che venga ``` ### Combinazioni di tasti -In Github Flavored Markdown, potete utilizzare il tag `<kbd>` per raffigurare i tasti della tastiera. +In GitHub Flavored Markdown, potete utilizzare il tag `<kbd>` per raffigurare i tasti della tastiera. ```md Il tuo computer è crashato? Prova a premere @@ -290,7 +293,7 @@ Il tuo computer è crashato? Prova a premere ``` ### Tabelle -Le tabelle sono disponibili solo in Github Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue: +Le tabelle sono disponibili solo in GitHub Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue: ```md | Col1 | Col2 | Col3 | @@ -307,4 +310,4 @@ Col 1 | Col2 | Col3 ``` --- -Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](http://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). +Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](https://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). diff --git a/it-it/php-composer-it.html.markdown b/it-it/php-composer-it.html.markdown new file mode 100644 index 00000000..509ec336 --- /dev/null +++ b/it-it/php-composer-it.html.markdown @@ -0,0 +1,193 @@ +--- +category: tool +tool: composer +contributors: + - ["Brett Taylor", "https://github.com/glutnix"] +translator: + - ["Agostino Fiscale", "https://github.com/agostinofiscale"] +lang: it-it +filename: LearnComposer-it.sh +--- + +[Composer](https://getcomposer.org/) è uno strumento che ti aiuta a gestire le +dipendenze in PHP. Ti permette di dichiarare le librerie utilizzate dal tuo +progetto e di installarle/aggiornarle per te. + +# Installazione + +```sh +# Se installi l'eseguibile in una cartella... +curl -sS https://getcomposer.org/installer | php +# ...dovrai utilizzare questo approccio, invocando Composer in questo modo: +php composer.phar about + +# Se installi l'eseguibile nella directory ~/bin/composer +# Nota: assicurati che ~/bin si trovi nella variabile di ambiente PATH +curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer +``` + +Gli utenti Windows possono seguire le istruzioni per [installarlo su Windows](https://getcomposer.org/doc/00-intro.md#installation-windows). + +## Assicuriamoci che il tutto abbia funzionato correttamente + +```sh +# Controlla la versione e la lista delle opzioni disponibili +composer + +# Ottieni ulteriori informazioni riguardanti le opzioni +composer help require + +# Controlla se Composer ha tutto il necessario per funzionare come si deve +# e se è aggiornato correttamente all'ultima versione disponibile. +composer diagnose +composer diag # alias + +# Aggiorna Composer all'ultima versione disponibile +composer self-update +composer self # alias +``` + +# Cominciamo ad usare Composer + +Composer memorizza le dipendenze necessarie nel file `composer.json`. +Puoi editare questo file manualmente, ma è meglio che lasci che Composer se ne +occupi per te. + +```sh +# Crea un nuovo progetto nella cartella attuale +composer init +# ti verranno chieste delle domande interrative riguardanti il tuo progetto. +# Puoi evitare di rispondere almeno che tu non stia sviluppando altri progetti +# che che possano dipendere da questo. + +# Se il file composer.json esiste già, scarichera' le dipendenze necessarie +composer install + +# Scarica le dipendenze necessarie per l'ambiente di produzione +composer install --no-dev + +# Aggiunge una dipendenza per l'ambiente di produzione +composer require guzzlehttp/guzzle +# automaticamente selezionera' l'ultima versione, la scarichera' e la aggiungera' +# come dipendenza nell'apposito campo del file composer.json. + +composer require guzzlehttp/guzzle:6.0.* +# scarichera' l'ultima versione disponibile corrispondente al pattern (es. 6.0.2) +# e lo aggiungera' come dipendenza nell'apposito campo del file composer.json. + +composer require --dev phpunit/phpunit:~4.5.0 +# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione +# disponibile nel range >=4.5.0 e < 4.6.0. + +composer require-dev phpunit/phpunit:^4.5.0 +# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione +# disponibile nel range >=4.5.0 and < 5.0. + +# Per ulteriori dettagli riguardo le versioni, vedi [la documentazione di Composer sulle versioni](https://getcomposer.org/doc/articles/versions.md) per ulteriori dettagli + +# Per vedere quali pacchetti sono installabili e quali sono gia' stati installati +composer show + +# Per vedere solo quali pacchetti sono gia' stati installati +composer show --installed + +# Per trovare una dipendenza con 'mailgun' nel suo nome o nella descrizione. +composer search mailgun +``` + +[Packagist.org](https://packagist.org/) è il repository principale per i pacchetti +di Composer. Cerca qui pacchetti di terze-parti utili per il tuo progetto. + +## `composer.json` vs `composer.lock` + +Il file `composer.json` memorizza la versione che si preferisce per ogni dipendenza, +insieme ad altre informazioni. + +Il file `composer.lock` memorizza quale versione è stata scaricata per ogni +dipendenza. Non editare mai questo file. + +Se includi il file `composer.lock` nella tua repository git, ogni sviluppatore +andra' a installare la versione attualmente utilizzata dal tuo progetto per +ogni dipendenza. Anche quando una nuova versione è stata rilasciata, Composer +andra' a installare la versione registrata nel file lock. + +```sh +# Se vuoi aggiornare tutte le dipendenze all'ultima versione che corrisponde al pattern descritto +composer update + +# Se vuoi scaricare l'ultima versione di una particolare dipendenza: +composer update phpunit/phpunit + +# Se vuoi cambiare la versione di una una dipendenza, potresti dover rimuovere +# quello attualmente selezionato, per poi richiedere quello corretto successivamente, +# attraverso i seguenti comandi: +composer remove --dev phpunit/phpunit +composer require --dev phpunit/phpunit:^5.0 + +``` + +## Autoloader + +Composer crea una classe autoloader che puoi richiamare nella tua applicazione. +Puoi creare instanze delle classi tramite il loro namespace. + +```php +require __DIR__ . '/vendor/autoload.php'; + +$mailgun = new Mailgun\Mailgun("key"); +``` + +### PSR-4 Autoloader + +Puoi aggiungere i tuoi namespace all'autoloader. + +Nel file `composer.json`, aggiungi il campo "autoload": + +```json +{ + "autoload": { + "psr-4": {"Acme\\": "src/"} + } +} +``` +Questo dira' all'autoloader di controllare ogni risorsa che corrisponde al +namespace `\Acme\` all'interno della cartella `src`. + +In alternativa puoi usare [PSR-0, una Classmap o una lista di file da includere](https://getcomposer.org/doc/04-schema.md#autoload). +Inoltre e' possibile anche utilizzare `autoload-dev` dedicato all'ambiente di sviluppo. + +Quando aggiungi o modifichi una chiave, dovrai ricompilare l'autoload attraverso: + +```sh +composer dump-autoload +composer dump # alias + +# Ottimizza i pacchetti PSR0 e PSR4 per essere caricati anche con le classmap. +# Sara' lento, ma migliorera' le performance in produzione. +composer dump-autoload --optimize --no-dev +``` + +# La cache di Composer + +```sh +# Composer utilizzera i pacchetti scaricati anche per i progetti futuri. Per evitare che accada: +composer clear-cache +``` + +# Problemi? + +```sh +composer diagnose +composer self-update +composer clear-cache +``` + +## Argomenti che non sono stati (ancora) discussi in questo tutorial + +* Creare e distribuire pacchetti personali su Packagist.org o altrove +* Pre- e post- script hooks: eseguire operazioni quando vengono eseguiti degli eventi + +### References + +* [Composer - Dependency Manager for PHP](https://getcomposer.org/) +* [Packagist.org](https://packagist.org/) diff --git a/it-it/pyqt-it.html.markdown b/it-it/pyqt-it.html.markdown index 7238dd7b..7b5a98c2 100644 --- a/it-it/pyqt-it.html.markdown +++ b/it-it/pyqt-it.html.markdown @@ -14,12 +14,12 @@ lang: it-it Questo è un adattamento sull'introduzione di C ++ a QT di [Aleksey Kholovchuk] (https://github.com/vortexxx192 ), alcuni degli esempi di codice dovrebbero avere la stessa funzionalità -che avrebbero se fossero fatte usando pyqt! +che avrebbero se fossero fatte usando pyqt! ```python import sys from PyQt4 import QtGui - + def window(): # Crea un oggetto applicazione app = QtGui.QApplication(sys.argv) @@ -47,7 +47,7 @@ if __name__ == '__main__': Per ottenere alcune delle funzionalità più avanzate in **pyqt**, dobbiamo iniziare a cercare di creare elementi aggiuntivi. Qui mostriamo come creare una finestra popup di dialogo, utile per chiedere all'utente di confermare una decisione o fornire informazioni -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -66,7 +66,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Questa funzione dovrebbe creare una finestra di dialogo con un pulsante # che aspetta di essere cliccato e quindi esce dal programma def showdialog(): diff --git a/it-it/rst-it.html.markdown b/it-it/rst-it.html.markdown index a834e899..3885cbd8 100644 --- a/it-it/rst-it.html.markdown +++ b/it-it/rst-it.html.markdown @@ -81,11 +81,11 @@ Anche le tabelle più complesse possono essere inserite facilmente (colonne e/o Esistono diversi modi per creare collegamenti: -- Aggiungendo un underscore dopo una parola: Github_ e aggiungendo l'URL di destinazione dopo il testo (questo metodo ha il vantaggio di non inserire URL non necessari all'interno del testo leggibile). +- Aggiungendo un underscore dopo una parola: GitHub_ e aggiungendo l'URL di destinazione dopo il testo (questo metodo ha il vantaggio di non inserire URL non necessari all'interno del testo leggibile). - Digitando un URL completo: https://github.com/ (verrà automaticamente convertito in un collegamento) -- Utilizzando una sintassi simile a Markdown: `Github <https://github.com/>`_ . +- Utilizzando una sintassi simile a Markdown: `GitHub <https://github.com/>`_ . -.. _Github https://github.com/ +.. _GitHub https://github.com/ ``` diff --git a/it-it/toml-it.html.markdown b/it-it/toml-it.html.markdown index 99082048..beb63096 100644 --- a/it-it/toml-it.html.markdown +++ b/it-it/toml-it.html.markdown @@ -1,276 +1,276 @@ ----
-language: toml
-filename: learntoml-it.toml
-contributors:
- - ["Alois de Gouvello", "https://github.com/aloisdg"]
-translators:
- - ["Christian Grasso", "https://grasso.io"]
-lang: it-it
----
-
-TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la
-serializzazione di dati, progettato per i file di configurazione.
-
-È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile
-per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza
-semplice nella maggior parte dei linguaggi di programmazione, in quanto è
-progettato per essere tradotto senza ambiguità in una hash table.
-
-Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è
-ancora stabile. Questo documento utilizza TOML 0.4.0.
-
-```toml
-# I commenti in TOML sono fatti così.
-
-################
-# TIPI SCALARI #
-################
-
-# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa,
-# anche chiamata dizionario, hash o oggetto in altri linguaggi.
-
-# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga,
-# eccetto per alcuni tipi di valori.
-key = "value"
-stringa = "ciao"
-numero = 42
-float = 3.14
-boolean = true
-data = 1979-05-27T07:32:00-08:00
-notazScientifica = 1e+12
-"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure '
-"la key può contenere" = "lettere, numeri, underscore e trattini"
-
-############
-# Stringhe #
-############
-
-# Le stringhe possono contenere solo caratteri UTF-8 validi.
-# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze
-# di escape compatte. Ad esempio, \t corrisponde al TAB.
-stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"."
-
-stringaMultiriga = """
-Racchiusa da tre virgolette doppie all'inizio e
-alla fine - consente di andare a capo."""
-
-stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.'
-
-stringaMultirigaLiteral = '''
-Racchiusa da tre virgolette singole all'inizio e
-alla fine - consente di andare a capo.
-Anche in questo caso non si può fare escape.
-Il primo ritorno a capo viene eliminato.
- Tutti gli altri spazi aggiuntivi
- vengono mantenuti.
-'''
-
-# Per i dati binari è consigliabile utilizzare Base64 e
-# gestirli manualmente dall'applicazione.
-
-##########
-# Interi #
-##########
-
-## Gli interi possono avere o meno un segno (+, -).
-## Non si possono inserire zero superflui all'inizio.
-## Non è possibile inoltre utilizzare valori numerici
-## non rappresentabili con una sequenza di cifre.
-int1 = +42
-int2 = 0
-int3 = -21
-
-## Puoi utilizzare gli underscore per migliorare la leggibilità.
-## Fai attenzione a non inserirne due di seguito.
-int4 = 5_349_221
-int5 = 1_2_3_4_5 # VALIDO, ma da evitare
-
-#########
-# Float #
-#########
-
-# I float permettono di rappresentare numeri decimali.
-flt1 = 3.1415
-flt2 = -5e6
-flt3 = 6.626E-34
-
-###########
-# Boolean #
-###########
-
-# I valori boolean (true/false) devono essere scritti in minuscolo.
-bool1 = true
-bool2 = false
-
-############
-# Data/ora #
-############
-
-data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC)
-data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset
-
-######################
-# TIPI DI COLLECTION #
-######################
-
-#########
-# Array #
-#########
-
-array1 = [ 1, 2, 3 ]
-array2 = [ "Le", "virgole", "sono", "delimitatori" ]
-array3 = [ "Non", "unire", "tipi", "diversi" ]
-array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ]
-array5 = [
- "Gli spazi vuoti", "sono", "ignorati"
-]
-
-###########
-# Tabelle #
-###########
-
-# Le tabelle (o hash table o dizionari) sono collection di coppie key/value.
-# Iniziano con un nome tra parentesi quadre su una linea separata.
-# Le tabelle vuote (senza alcun valore) sono valide.
-[tabella]
-
-# Tutti i valori che si trovano sotto il nome della tabella
-# appartengono alla tabella stessa (finchè non ne viene creata un'altra).
-# L'ordine di questi valori non è garantito.
-[tabella-1]
-key1 = "una stringa"
-key2 = 123
-
-[tabella-2]
-key1 = "un'altra stringa"
-key2 = 456
-
-# Utilizzando i punti è possibile creare delle sottotabelle.
-# Ogni parte suddivisa dai punti segue le regole delle key per il nome.
-[tabella-3."sotto.tabella"]
-key1 = "prova"
-
-# Ecco l'equivalente JSON della tabella precedente:
-# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } }
-
-# Gli spazi non vengono considerati, ma è consigliabile
-# evitare di usare spazi superflui.
-[a.b.c] # consigliato
-[ d.e.f ] # identico a [d.e.f]
-
-# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella.
-# [x] queste
-# [x.y] non
-# [x.y.z] servono
-[x.y.z.w] # per creare questa tabella
-
-# Se non è stata già creata prima, puoi anche creare
-# una tabella superiore più avanti.
-[a.b]
-c = 1
-
-[a]
-d = 2
-
-# Non puoi definire una key o una tabella più di una volta.
-
-# ERRORE
-[a]
-b = 1
-
-[a]
-c = 2
-
-# ERRORE
-[a]
-b = 1
-
-[a.b]
-c = 2
-
-# I nomi delle tabelle non possono essere vuoti.
-[] # NON VALIDO
-[a.] # NON VALIDO
-[a..b] # NON VALIDO
-[.b] # NON VALIDO
-[.] # NON VALIDO
-
-##################
-# Tabelle inline #
-##################
-
-tabelleInline = { racchiuseData = "{ e }", rigaSingola = true }
-punto = { x = 1, y = 2 }
-
-####################
-# Array di tabelle #
-####################
-
-# Un array di tabelle può essere creato utilizzando due parentesi quadre.
-# Tutte le tabelle con questo nome saranno elementi dell'array.
-# Gli elementi vengono inseriti nell'ordine in cui si trovano.
-
-[[prodotti]]
-nome = "array di tabelle"
-sku = 738594937
-tabelleVuoteValide = true
-
-[[prodotti]]
-
-[[prodotti]]
-nome = "un altro item"
-sku = 284758393
-colore = "grigio"
-
-# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie
-# parentesi quadre apparterranno alla tabella più vicina sopra di esse.
-
-[[frutta]]
- nome = "mela"
-
- [frutto.geometria]
- forma = "sferica"
- nota = "Sono una proprietà del frutto"
-
- [[frutto.colore]]
- nome = "rosso"
- nota = "Sono un oggetto di un array dentro mela"
-
- [[frutto.colore]]
- nome = "verde"
- nota = "Sono nello stesso array di rosso"
-
-[[frutta]]
- nome = "banana"
-
- [[frutto.colore]]
- nome = "giallo"
- nota = "Anche io sono un oggetto di un array, ma dentro banana"
-```
-
-Ecco l'equivalente JSON dell'ultima tabella:
-
-```json
-{
- "frutta": [
- {
- "nome": "mela",
- "geometria": { "forma": "sferica", "nota": "..."},
- "colore": [
- { "nome": "rosso", "nota": "..." },
- { "nome": "verde", "nota": "..." }
- ]
- },
- {
- "nome": "banana",
- "colore": [
- { "nome": "giallo", "nota": "..." }
- ]
- }
- ]
-}
-```
-
-### Altre risorse
-
-+ [Repository ufficiale di TOML](https://github.com/toml-lang/toml)
+--- +language: toml +filename: learntoml-it.toml +contributors: + - ["Alois de Gouvello", "https://github.com/aloisdg"] +translators: + - ["Christian Grasso", "https://grasso.io"] +lang: it-it +--- + +TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la +serializzazione di dati, progettato per i file di configurazione. + +È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile +per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza +semplice nella maggior parte dei linguaggi di programmazione, in quanto è +progettato per essere tradotto senza ambiguità in una hash table. + +Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è +ancora stabile. Questo documento utilizza TOML 0.4.0. + +```toml +# I commenti in TOML sono fatti così. + +################ +# TIPI SCALARI # +################ + +# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa, +# anche chiamata dizionario, hash o oggetto in altri linguaggi. + +# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga, +# eccetto per alcuni tipi di valori. +key = "value" +stringa = "ciao" +numero = 42 +float = 3.14 +boolean = true +data = 1979-05-27T07:32:00-08:00 +notazScientifica = 1e+12 +"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure ' +"la key può contenere" = "lettere, numeri, underscore e trattini" + +############ +# Stringhe # +############ + +# Le stringhe possono contenere solo caratteri UTF-8 validi. +# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze +# di escape compatte. Ad esempio, \t corrisponde al TAB. +stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"." + +stringaMultiriga = """ +Racchiusa da tre virgolette doppie all'inizio e +alla fine - consente di andare a capo.""" + +stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.' + +stringaMultirigaLiteral = ''' +Racchiusa da tre virgolette singole all'inizio e +alla fine - consente di andare a capo. +Anche in questo caso non si può fare escape. +Il primo ritorno a capo viene eliminato. + Tutti gli altri spazi aggiuntivi + vengono mantenuti. +''' + +# Per i dati binari è consigliabile utilizzare Base64 e +# gestirli manualmente dall'applicazione. + +########## +# Interi # +########## + +## Gli interi possono avere o meno un segno (+, -). +## Non si possono inserire zero superflui all'inizio. +## Non è possibile inoltre utilizzare valori numerici +## non rappresentabili con una sequenza di cifre. +int1 = +42 +int2 = 0 +int3 = -21 + +## Puoi utilizzare gli underscore per migliorare la leggibilità. +## Fai attenzione a non inserirne due di seguito. +int4 = 5_349_221 +int5 = 1_2_3_4_5 # VALIDO, ma da evitare + +######### +# Float # +######### + +# I float permettono di rappresentare numeri decimali. +flt1 = 3.1415 +flt2 = -5e6 +flt3 = 6.626E-34 + +########### +# Boolean # +########### + +# I valori boolean (true/false) devono essere scritti in minuscolo. +bool1 = true +bool2 = false + +############ +# Data/ora # +############ + +data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC) +data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset + +###################### +# TIPI DI COLLECTION # +###################### + +######### +# Array # +######### + +array1 = [ 1, 2, 3 ] +array2 = [ "Le", "virgole", "sono", "delimitatori" ] +array3 = [ "Non", "unire", "tipi", "diversi" ] +array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ] +array5 = [ + "Gli spazi vuoti", "sono", "ignorati" +] + +########### +# Tabelle # +########### + +# Le tabelle (o hash table o dizionari) sono collection di coppie key/value. +# Iniziano con un nome tra parentesi quadre su una linea separata. +# Le tabelle vuote (senza alcun valore) sono valide. +[tabella] + +# Tutti i valori che si trovano sotto il nome della tabella +# appartengono alla tabella stessa (finchè non ne viene creata un'altra). +# L'ordine di questi valori non è garantito. +[tabella-1] +key1 = "una stringa" +key2 = 123 + +[tabella-2] +key1 = "un'altra stringa" +key2 = 456 + +# Utilizzando i punti è possibile creare delle sottotabelle. +# Ogni parte suddivisa dai punti segue le regole delle key per il nome. +[tabella-3."sotto.tabella"] +key1 = "prova" + +# Ecco l'equivalente JSON della tabella precedente: +# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } } + +# Gli spazi non vengono considerati, ma è consigliabile +# evitare di usare spazi superflui. +[a.b.c] # consigliato +[ d.e.f ] # identico a [d.e.f] + +# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella. +# [x] queste +# [x.y] non +# [x.y.z] servono +[x.y.z.w] # per creare questa tabella + +# Se non è stata già creata prima, puoi anche creare +# una tabella superiore più avanti. +[a.b] +c = 1 + +[a] +d = 2 + +# Non puoi definire una key o una tabella più di una volta. + +# ERRORE +[a] +b = 1 + +[a] +c = 2 + +# ERRORE +[a] +b = 1 + +[a.b] +c = 2 + +# I nomi delle tabelle non possono essere vuoti. +[] # NON VALIDO +[a.] # NON VALIDO +[a..b] # NON VALIDO +[.b] # NON VALIDO +[.] # NON VALIDO + +################## +# Tabelle inline # +################## + +tabelleInline = { racchiuseData = "{ e }", rigaSingola = true } +punto = { x = 1, y = 2 } + +#################### +# Array di tabelle # +#################### + +# Un array di tabelle può essere creato utilizzando due parentesi quadre. +# Tutte le tabelle con questo nome saranno elementi dell'array. +# Gli elementi vengono inseriti nell'ordine in cui si trovano. + +[[prodotti]] +nome = "array di tabelle" +sku = 738594937 +tabelleVuoteValide = true + +[[prodotti]] + +[[prodotti]] +nome = "un altro item" +sku = 284758393 +colore = "grigio" + +# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie +# parentesi quadre apparterranno alla tabella più vicina sopra di esse. + +[[frutta]] + nome = "mela" + + [frutto.geometria] + forma = "sferica" + nota = "Sono una proprietà del frutto" + + [[frutto.colore]] + nome = "rosso" + nota = "Sono un oggetto di un array dentro mela" + + [[frutto.colore]] + nome = "verde" + nota = "Sono nello stesso array di rosso" + +[[frutta]] + nome = "banana" + + [[frutto.colore]] + nome = "giallo" + nota = "Anche io sono un oggetto di un array, ma dentro banana" +``` + +Ecco l'equivalente JSON dell'ultima tabella: + +```json +{ + "frutta": [ + { + "nome": "mela", + "geometria": { "forma": "sferica", "nota": "..."}, + "colore": [ + { "nome": "rosso", "nota": "..." }, + { "nome": "verde", "nota": "..." } + ] + }, + { + "nome": "banana", + "colore": [ + { "nome": "giallo", "nota": "..." } + ] + } + ] +} +``` + +### Altre risorse + ++ [Repository ufficiale di TOML](https://github.com/toml-lang/toml) diff --git a/ja-jp/asciidoc.html.markdown b/ja-jp/asciidoc.html.markdown index 7347589a..af19850a 100644 --- a/ja-jp/asciidoc.html.markdown +++ b/ja-jp/asciidoc.html.markdown @@ -5,7 +5,7 @@ contributors: - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] translators: - ["Ryota Kayanuma", "https://github.com/PicoSushi"] -filename: asciidoc-ja.md +filename: asciidoc-ja.adoc lang: ja-jp --- diff --git a/ja-jp/python-jp.html.markdown b/ja-jp/python-jp.html.markdown index 18e7d1b8..363d00a0 100644 --- a/ja-jp/python-jp.html.markdown +++ b/ja-jp/python-jp.html.markdown @@ -11,6 +11,7 @@ contributors: translators: - ["kakakaya", "https://github.com/kakakaya"] - ["Ryota Kayanuma", "https://github.com/PicoSushi"] + - ["Kenryu Shibata", "https://github.com/kenryuS"] filename: learnpython-jp.py lang: ja-jp --- @@ -180,7 +181,7 @@ bool({}) # => False bool(()) # => False #################################################### -# 2. Variables and Collections +# 2. 変数と集合 #################################################### # Python にはprint関数があります。 @@ -400,7 +401,7 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6} #################################################### -# 3. 制御の流れとiterable +# 3. 制御の流れと反復可能オブジェクト #################################################### # まずは変数を作りましょう。 @@ -429,7 +430,7 @@ for animal in ["dog", "cat", "mouse"]: print("{} is a mammal".format(animal)) """ -"range(数値)" は、ゼロから与えられた数値までのiterableを返します。 +"range(数値)" は、ゼロから与えられた数値までのiterable(反復可能オブジェクト)を返します。 出力: 0 1 @@ -649,7 +650,7 @@ print(ceil(3.7)) # => 4.0 print(floor(3.7)) # => 3.0 # 全部の関数をモジュールからインポートすることができます。 -# Warning: この方法は推奨されません。 +# 注意: この方法は推奨されません。 from math import * # 短い名前でモジュールをインポートすることができます。 @@ -990,9 +991,9 @@ print(say()) # Can you buy me a beer? print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ``` -## Ready For More? +## さらなる学習の準備ができましたか? -### Free Online +### 無料のオンラインコンテンツ * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) * [Ideas for Python Projects](http://pythonpracticeprojects.com) diff --git a/ja-jp/yaml-jp.html.markdown b/ja-jp/yaml-jp.html.markdown new file mode 100644 index 00000000..28a5d870 --- /dev/null +++ b/ja-jp/yaml-jp.html.markdown @@ -0,0 +1,193 @@ +--- +language: yaml +filename: learnyaml-jp.yaml +contributors: +- [Leigh Brenecki, 'https://leigh.net.au'] +- [Suhas SG, 'https://github.com/jargnar'] +translators: +- [haru, 'https://haru52.com/'] +lang: ja-jp +--- + +YAMLはデータのシリアライズ用言語で、 +人間が直接読み書きしやすいようにデザインされています。 + +YAMLはJSONの厳格なスーパーセットで、 +改行とインデントが構文的に意味を持つというPythonに似た仕様を追加しています。 +しかしPythonとは異なりYAMLではインデントにタブ文字を使うことはできません。 + +```yaml +--- # ドキュメント開始 + +# YAMLのコメントはこんな感じです。 + +############## +# スカラー型 # +############## + +# (ドキュメント全体を含む)ルートオブジェクトはマップになります。 +# これは他言語における辞書型、ハッシュ、オブジェクトなどと等価です。 +キー: 値 +別のキー: 別の値。 +数値: 100 +指数表記: 1e+12 +# 1 はbooleanでなく数値として解釈されます。 +# もしbooleanとして解釈してほしい場合はtrueを使います +boolean: true +null値: null +スペースを 含む キー: 値 +# 文字列をクォートで囲う必要がないことに注意してください。 +# しかし囲うこともできます。 +しかし: 'クォートで囲まれた文字列。' +'キーもクォートで囲えます。': "keyの中で ':' を使いたいときに有用です。" +シングルクォート: 'には ''1つの'' エスケープパターンがあります' +ダブルクォート: "には多くのエスケープパターンがあります:\", \0, \t, \u263A, +\x0d\x0a == \r\n, など、他にもあります。" +# UTF-8/16/32文字はエンコードされている必要があります +上付き2: \u00B2 + +# 複数行の文字列は(| を使う)「リテラルブロック」、 +# または、('>' を使う)「折り畳みブロック」として書くことができます +リテラルブロック: | + この文章のブロック全体が「リテラルブロック」キーの値になり、 + 改行は保持されます。 + + リテラルはインデントを解除するまで続き、先頭行のインデント文字数分を + 各行のテキストの先頭から取り除きます。 + + 「よりインデントの深い」行はその分のインデントを保持します - + この2行はスペース4個分インデントされます。 +折り畳みスタイル: > + この文章のブロック全体が「折り畳みスタイル」の値になります。 + しかしこちらの場合、全ての改行がスペース1個に置き換わります。 + + 直前のような空行は改行文字に変換されます。 + + 「よりインデントの深い」行も改行を保持します - + このテキストは2行にわたって表示されます。 + +################## +# コレクション型 # +################## + +# 入れ子を表現するにはインデントを使います。 +# スペース2個のインデントが好まれます(が必須ではありません)。 +入れ子のマップ: + キー: 値 + 別のキー: 別の値 + 別の入れ子のマップ: + こんにちは: こんにちは + +# マップのキーは文字列である必要はありません。 +0.25: 小数のキー + +# 複数行オブジェクトのような複雑なキーも使用可能です。 +# ? の後にスペースを入れることで複雑なキーの開始を宣言できます。 +? | + これはキーです + 複数行あります +: そしてこれがその値です + +# YAMLではシーケンスを複雑なキー構文で使うこともできます +# しかし、言語パーサーによってはエラーになるかもしれません +# 例 +? - マンチェスター・ユナイテッド + - レアル・マドリード +: [2001-01-01, 2002-02-02] + +# シーケンス(リストや配列と等価)はこんな感じです +# ('-' はインデントとしてカウントしてください): +シーケンス: + - アイテム1 + - アイテム2 + - 0.5 # シーケンスには異なる型の値を混在させられます + - アイテム4 + - キー: 値 + 別のキー: 別の値 + - + - これはシーケンスです + - 別のシーケンス内部 + - - - 入れ子のシーケンス表記は + - 折り畳めます + +# YAMLはJSONのスーパーセットなので、 +# JSON形式のマップとシーケンスを書くこともできます: +jsonマップ: {"キー": "値"} +jsonシーケンス: [3, 2, 1, "発進"] +クォートは任意: {キー: [3, 2, 1, 発進]} + +###################### +# その他のYAMLの機能 # +###################### + +# YAMLには「アンカー」と呼ばれる便利な機能もあります。これによりコンテンツを +# ドキュメント内で簡単に複製できます。これらのキーはどちらも同じ値を持ちます: +アンカーされたコンテンツ: &anchor_name この文字列は2つのキーの値になります。 +他のアンカー: *anchor_name + +# アンカーは複製/継承プロパティとして使えます +ベース: &base + 名前: みんな同じ名前を持ちます + +# 記号 << はマージキー言語非依存型(Merge Key Language-Independent Type) +# と呼ばれます。これは指定された1つ以上のマップの全てのキーを現在のマップに +# 挿入することを示すために使われます。 + +foo: + <<: *base + 年齢: 10 + +bar: + <<: *base + 年齢: 20 + +# fooとbarも「名前: みんな同じ名前を持ちます」を持ちます + +# YAMLにはタグもあり、明示的に型を宣言できます。 +明示的な文字列: !!str 0.5 +# 言語特有のタグを実装したパーサーもあり、例えばPythonの複素数型が使えます。 +pythonの複素数型: !!python/complex 1+2j + +# YAMLの複雑なキーでは言語特有のタグも使えます +? !!python/tuple [5, 7] +: 五十七 +# Python上で {(5, 7): '五十七'} として扱われます + +#################### +# その他のYAMLの型 # +#################### + +# 文字列と数値がYAMLの理解できる唯一のスカラーではありません。 +# ISO形式の日付や日時リテラルもパースされます。 +日時: 2001-12-15T02:59:43.1Z +スペースを含む日時: 2001-12-14 21:59:43.10 -5 +日付: 2002-12-14 + +# !!binaryタグは文字列の実体がバイナリblobのbase64エンコード表現であることを +# 示します。 +gifファイル: !!binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + +# YAMLにはセット型もあり、それはこんな感じです: +セット: + ? アイテム1 + ? アイテム2 + ? アイテム3 +または: {アイテム1, アイテム2, アイテム3} + +# セットは値がnullのただのマップで、直前のセットは以下と等価です: +セット2: + アイテム1: null + アイテム2: null + アイテム3: null + +... # ドキュメント終了 +``` + +### 補足資料 + ++ [YAML公式ウェブサイト](https://yaml.org/) ++ [オンラインYAMLバリデーター](http://www.yamllint.com/) diff --git a/janet.html.markdown b/janet.html.markdown index 7b2912c2..62ed7331 100644 --- a/janet.html.markdown +++ b/janet.html.markdown @@ -29,9 +29,9 @@ nil # Typical style for symbols (identifiers-for / names-of things). do-stuff pants-on-fire! -foo->bar # Evidently for converting foos to bars. +foo->bar # Evidently for converting foos to bars. fully-charged? -_ # Usually used as a dummy variable. +_ # Usually used as a dummy variable. # Keywords are like symbols that start with a colon, are treated like # constants, and are typically used as map keys or pieces of syntax in @@ -58,10 +58,11 @@ math/e # => 2.71828 "hello" "hey\tthere" # contains a tab -# For multi-line strings, use one or more backticks. No escapes allowed. +# For multi-line strings, use one or more backticks. Backslash-escapes not +# recognized in these (bytes will be parsed literally). ``a long multi-line -string`` # => "a long\nmulti-line\nstring" +string`` # => "a long\nmulti-line\nstring" # Strings and data structures in Janet come in two varieties: mutable and # immutable. The literal for the mutable variety is written with a `@` in @@ -72,7 +73,7 @@ string`` # => "a long\nmulti-line\nstring" @`a multi-line one here` -(string "con" "cat" "enate") # => "concatenate" +(string "con" "cat" "enate") # => "concatenate" # To get a substring: (string/slice "abcdefgh" 2 5) # => "cde" @@ -81,7 +82,8 @@ one here` # See the string library for more (splitting, replacement, etc.) -# Arrays and Tuples ########################################################### +# Data Structures ############################################################# +# Arrays and Tuples # Arrays are mutable, tuples are immutable. # Arrays (mutable) @@ -91,18 +93,19 @@ one here` # Tuples (immutable) # Note that an open paren usually indicates a function call, so if you want a # literal tuple with parens, you need to "quote" it (with a starting single -# quote mark). +# quote mark)... '(4 5 6) [4 5 6] # ... or just use square brackets. -# Tables and Structs (AKA: "maps", "hashmaps", "dictionaries") +# Tables and Structs (associative data structures) @{:a 1 :b 2 :c 3} # table (mutable) {:a 1 :b 2 :c 3} # struct (immutable) +# To "pretty-print" these out, use `pp` instead of `print`. # More about how to work with arrays/tuples and tables/structs below. # Bindings #################################################################### -# ... or "Name Some Things!" (that is, bind a value to a symbol) +# Bind a value to a symbol. (def x 4.7) # Define a constant, `x`. x # => 4.7 (quote x) # => x (the symbol x) @@ -113,7 +116,7 @@ x # => 4.7 (set x 5.6) # Error, `x` is a constant. (var y 10) -(set y 12) # Works, since `y` was made var. +(set y 12) # Works, since `y` was defined using `var`. # Note that bindings are local to the scope they're called in. `let` # creates a local scope and makes some bindings all in one shot: @@ -151,29 +154,29 @@ insect-friend # => bee (% 5 3) # => 2 (remainder) (- 5) # => -5 (or you can just write `-5`) -(++ i) # increments +(++ i) # increments (modifies `i`) (-- i) # decrements (+= i 3) # add 3 to `i` (*= i 3) # triple `i` # ... and so on for the other operations on numbers. +# If you don't want to mutate `i`, use `(inc i)` and `(dec i)`. + # Comparison # = < > not= <= >= (< 2 7 12) # => true # Functions ################################################################### # Call them: -(- 5 3) # => 2 (Yes, operators and functions work the same.) +(- 5 3) # => 2 (Operators and functions work the same way.) (math/sin (/ math/pi 2)) # => 1 -(range 5) # => @[0 1 2 3 4] +(range 5) # => @[0 1 2 3 4] # Create them: (defn mult-by-2 ``First line of docstring. - Some more of the docstring. - - Possibly more!`` + Some more of the docstring.`` [x] (print "Hi.") (print "Will compute using: " x) @@ -206,7 +209,7 @@ n # => 3 # You might say that function bodies provide an "implicit do". # Operations on data structures ############################################### -# (Making all these mutable so we can ... mutate them.) +# (Making all of these mutable so we can ... mutate them.) (def s @"Hello, World!") (def a @[:a :b :c :d :e]) (def t @{:a 1 :b 2}) @@ -216,9 +219,9 @@ n # => 3 (length t) # => 2 # Getting values: -(s 7) # => 87 (which is the code point for "W") -(a 1) # => :b -(t :a) # => 1 +(s 7) # => 87 (which is the code point for "W") +(a 1) # => :b +(t :a) # => 1 (keys t) # => @[:a :b] (values t) # => @[1 2] @@ -227,14 +230,14 @@ n # => 3 (put a 2 :x) # @[:a :b :x :d :e] (put t :b 42) # @{:a 1 :b 42} -# Adding & removing values (again, for mutable data structures): +# Adding and removing values (again, for mutable data structures): (buffer/push-string s "??") # @"HeWlo, World!??" (array/push a :f) # @[:a :b :x :d :e :f] (array/pop a) # => :f, and it's also removed from `a`. (put t :x 88) # @{:a 1 :b 42 :x 88} # See the manual for a wide variety of functions for working with -# buffers/strings, arrays/tuples, and tables/struct. +# buffers/strings, arrays/tuples, and tables/structs. # Flow control ################################################################ (if some-condition @@ -282,7 +285,7 @@ n # => 3 {:yar v} (print "matches key :yar! " v) {:moo v} (print "matches key :moo! " v) {:c v} (print "matches key :c! " v) - _ (print "no match")) # => prints "matches key :c! 3" + _ (print "no match")) # => prints "matches key :c! 3" # Iterating ################################################################### # Iterate over an integer range: @@ -312,7 +315,7 @@ n # => 3 (* x x)) (range 10))) # => @[0 4 16 36 64] -(reduce + 0 (range 5)) # => 10 +(reduce + 0 (range 5)) # => 10 # ...and lots more (see the API docs). diff --git a/java.html.markdown b/java.html.markdown index 4be940be..7bf3fa0a 100644 --- a/java.html.markdown +++ b/java.html.markdown @@ -91,6 +91,9 @@ public class LearnJava { int numInt = scanner.nextInt(); // read long input + long numLong = scanner.nextLong(); + + // read float input float numFloat = scanner.nextFloat(); // read double input @@ -123,6 +126,9 @@ public class LearnJava { // <name1> = <name2> = <name3> = <val> int barInt1, barInt2, barInt3; barInt1 = barInt2 = barInt3 = 1; + // Shorthand for multiple declarations + int barInt4 = 1, barInt5 = 2; + /* * Variable types @@ -182,7 +188,7 @@ public class LearnJava { // // BigInteger is a data type that allows programmers to manipulate // integers longer than 64-bits. Integers are stored as an array of - // of bytes and are manipulated using functions built into BigInteger + // bytes and are manipulated using functions built into BigInteger // // BigInteger can be initialized using an array of bytes or a string. BigInteger fooBigInteger = new BigInteger(fooByteArray); @@ -304,8 +310,8 @@ public class LearnJava { /////////////////////////////////////// System.out.println("\n->Operators"); - int i1 = 1, i2 = 2; // Shorthand for multiple declarations - + int i1 = 1, i2 = 2; + // Arithmetic is straightforward System.out.println("1+2 = " + (i1 + i2)); // => 3 System.out.println("2-1 = " + (i2 - i1)); // => 1 @@ -314,7 +320,7 @@ public class LearnJava { System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5 // Modulo - System.out.println("11%3 = "+(11 % 3)); // => 2 + System.out.println("11%3 = " + (11 % 3)); // => 2 // Comparison operators System.out.println("3 == 2? " + (3 == 2)); // => false @@ -368,7 +374,7 @@ public class LearnJava { // While loop int fooWhile = 0; - while(fooWhile < 100) { + while (fooWhile < 100) { System.out.println(fooWhile); // Increment the counter // Iterated 100 times, fooWhile 0,1,2...99 @@ -383,7 +389,7 @@ public class LearnJava { // Increment the counter // Iterated 100 times, fooDoWhile 0->99 fooDoWhile++; - } while(fooDoWhile < 100); + } while (fooDoWhile < 100); System.out.println("fooDoWhile Value: " + fooDoWhile); // For Loop diff --git a/javascript.html.markdown b/javascript.html.markdown index ec250e45..4e7c5c09 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -105,6 +105,10 @@ false; "1, 2, " + 3; // = "1, 2, 3" "Hello " + ["world", "!"]; // = "Hello world,!" +// ...which can result in some weird behaviour... +13 + !0; // 14 +"13" + !0; // '13true' + // and are compared with < and > "a" < "b"; // = true @@ -116,10 +120,6 @@ null == undefined; // = true "5" === 5; // = false null === undefined; // = false -// ...which can result in some weird behaviour... -13 + !0; // 14 -"13" + !0; // '13true' - // You can access characters in a string with `charAt` "This is a string".charAt(0); // = 'T' @@ -405,7 +405,7 @@ myObj = { }; myObj.myFunc(); // = "Hello world!" -// What this is set to has to do with how the function is called, not where +// What `this` is set to has to do with how the function is called, not where // it's defined. So, our function doesn't work if it isn't called in the // context of the object. var myFunc = myObj.myFunc; @@ -655,7 +655,7 @@ attached terminal [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. -[Javascript:Info][11] is a modern javascript tutorial covering the basics (core language and working with a browser) +[javascript.info][11] is a modern javascript tutorial covering the basics (core language and working with a browser) as well as advanced topics with concise explanations. @@ -671,6 +671,7 @@ Mozilla Developer Network. [5]: http://bonsaiden.github.io/JavaScript-Garden/ [6]: http://www.amazon.com/gp/product/0596805527/ [7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript +[8]: https://www.javascripttutorial.net/ [8]: http://eloquentjavascript.net/ [10]: http://jstherightway.org/ [11]: https://javascript.info/ diff --git a/jinja.html.markdown b/jinja.html.markdown new file mode 100644 index 00000000..7e5b8e96 --- /dev/null +++ b/jinja.html.markdown @@ -0,0 +1,270 @@ +--- +language: Jinja +contributors: + - ["Adaías Magdiel", "https://github.com/AdaiasMagdiel"] +filename: learn-jinja.j2 +--- + +## Getting Started with Jinja + +Jinja is a fast, expressive, and extensible templating engine for Python +applications. + +Jinja includes a lot of functionalities, such as: +- Template inheritance and inclusion; +- Defining and importing macros within templates; +- Security mechanisms to prevent XSS attacks; +- A sandboxed environment that can safely render untrusted templates; +- Extensible filters, tests, functions, and even syntax. + +A Jinja template is simply a text file. Jinja doesn't require a specific +extension, but it's common to use `.j2` or `.jinja` to make it easier for +some IDEs. + +There are a few kinds of delimiters. The default Jinja delimiters are configured +as follows: + +- `{% ... %}` for Statements +- `{{ ... }}` for Expressions to print to the template output +- `{# ... #}` for Comments not included in the template output + +```jinja +{# This is an example of a comment. #} + +{# + You can use this syntax + to write multiline comments + as well. +#} +``` + + +## VARIABLES + +```jinja +{# You have the option to access variables from the context passed to the template #} + +{{ foo }} + +{# + Additionally, you can use a dot (.) to access attributes of a variable or + use Python syntax, using [] +#} + +{{ foo.bar }} +{{ foo['bar'] }} + +{# Within the template, you can define variables as well #} + +{% set name = "Magdiel" %} +{{ name }} +``` + +## Loops + +```html +<h1>Members</h1> +<ul> +{% for user in users %} + <li>{{ user.username }}</li> +{% endfor %} +</ul> + + +<div> +{% for key, value in my_dict.items() %} + <p>{{ key }}</p> - <p>{{ value }}</p> +{% endfor %} +</div> + + +<div> +{% for idx, url in enumerate(urls) %} + <a href="{{ url }}">Go to url {{ idx + 1 }}</a> +{% endfor %} +</div> +``` + +## Conditionals + +The if statement in Jinja is similar to the if statement in Python. It is +commonly used to check if a variable is defined, not empty, and not false in +its most basic form. + +```html +{% if users %} +<ul> +{% for user in users %} + <li>{{ user.username }}</li> +{% endfor %} +</ul> +{% endif %} + + +{# For multiple branches, elif and else can be used like in Python. #} + + +{% if message.status == "error" %} + <p class="text-red-400">{{ message.content }}</p> +{% elif message.status == "success" %} + <p class="text-green-400">{{ message.content }}</p> +{% else %} + <p class="text-blue-400">{{ message.content }}</p> +{% endif %} +``` + +## Template Inheritance + +One of the most powerful features of Jinja is template inheritance. You can +create a base layout with predefined blocks that you can extend in another file +and override with your own content. + +```html +{# file: base.html.j2 #} + +<!DOCTYPE html> +<html lang="en"> +<head> + {% block head %} + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{% block title %}{% endblock title %} - Learning Jinja</title> + {% endblock head %} +</head> +<body> + <main> + {% block content %}{% endblock %} + {# the endblock tag doesn't need the name of the block #} + </main> +</body> +</html> + + + +{# file: child.html.j2 #} + +{% extends "base.html.j2" %} + +{% block head %} + {{ super() }} + <script> + console.log("There's a console.log here") + </script> +{% endblock %} + +{% block title %}Home{% endblock %} + +{% block content %} + <h1>Index</h1> + <p>Welcome to my home homepage.</p> +{% endblock %} + + + +{# RESULT #} + +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Home - Learning Jinja</title> + <script> + console.log("There's a console.log here") + </script> +</head> +<body> + <main> + <h1>Index</h1> + <p>Welcome to my home homepage.</p> + </main> +</body> +</html> + +``` + +### Including Content + +You can include content from another template on your current template using +the `{% include "template/path" %}` tag. + +```html + +{# file: footer.html.j2 #} + +<footer> + <p>© 2024 - John Doe</p> +</footer> + + + +{# file: index.html.j2 #} +... +<body> + <main> + <h1>Hi! I'm John Doe!</h1> + </main> + {% include "footer.html.j2" %} +</body> +... + + + +{# RESULT #} + +... +<body> + <main> + <h1>Hi! I'm John Doe!</h1> + </main> + <footer> + <p>© 2024 - John Doe</p> + </footer> +</body> +... +``` + +Variables passed to the main template can also be used in the include, as the +included template has access to the context of the main template. + +```html +{# file: greetings.html.j2 #} + +<p>I'm the {{ name }} and i like to {{ hobby }}.</p> + + + +{# file: index.html.j2 #} + +{% set name = "Captain Nemo" %} +{% set hobby = "navigate through the depths of the ocean" %} + +<div> + {% include "greetings.html.j2" %} +</div> + + + +{# RESULT #} + +<div> + <p>I'm the Captain Nemo and i like to navigate through the depths of the ocean.</p> +</div> +``` + +## Macros + +Macros are basically like functions in another languages. You can define macros with or without arguments and reuse them in various parts of your template. + +```html +{% macro input(value="", type="text", placeholder="") -%} + <input type="{{ type }}" value="{{ value }}" placeholder="{{ placeholder }}"> +{%- endmacro %} + +<p>{{ input(placeholder="Your username") }}</p> +<p>{{ input(type="password") }}</p> +``` + +## Official Documentation + +To learn more, access the [official documentation](https://jinja.palletsprojects.com/en/). diff --git a/jq.html.markdown b/jq.html.markdown new file mode 100644 index 00000000..dded34cb --- /dev/null +++ b/jq.html.markdown @@ -0,0 +1,910 @@ +--- +category: tool +tool: jq +contributors: + - ["Jack Kuan", "https://github.com/kjkuan"] +filename: learnjq.sh +--- + +`jq` is a tool for transforming JSON inputs and generating JSON outputs. As a +programming language, jq supports boolean and arithmetic expressions, object +and array indexing; it has conditionals, functions, and even exception +handling... etc. Knowing jq enables you to easily write small programs that +can perform complex queries on JSON documents to find answers, make reports, or +to produce another JSON document for further processing by other programs. + +> **NOTE**: This guide demonstrates the use of jq from the command line, +> specifically, under an environment running the Bash shell. + +```bash +# When running jq from the command line, jq program code can be specified as the +# first argument after any options to `jq`. We often quote such jq program with +# single quotes (`'`) to prevent any special interpretation from the command line +# shell. +# +jq -n '# Comments start with # until the end of line. + # The -n option sets the input to the value, `null`, and prevents `jq` + # from reading inputs from external sources. +' + +# Output: +# null + + +# By default jq reads from *STDIN* a stream of JSON inputs (values). It +# processes each input with the jq program (filters) specified at the command +# line, and prints the outputs of processing each input with the program to +# *STDOUT*. +# +echo ' + "hello" 123 [ + "one", + "two", + "three" + ] + { "name": "jq" } +' | + jq '. # <-- the jq program here is the single dot (.), called the identity + # operator, which stands for the current input. +' + +# Output: +# "hello" +# 123 +# [ +# "one", +# "two", +# "three" +# ] +# { +# "name": "jq" +# } + + +# Notice that jq pretty-prints the outputs by default, therefore, piping +# to `jq` is a simple way to format a response from some REST API endpoint +# that returns JSON. E.g., `curl -s https://freegeoip.app/json/ | jq` + + +# Instead of processing each JSON input with a jq program, you can also +# ask jq to slurp them up as an array. +# +echo '1 "two" 3' | jq -s . + +# Output: +# [ +# 1, +# "two", +# 3 +# ] + + +# Or, treat each line as a string. +# +(echo line 1; echo line 2) | jq -R . + +# Output: +# "line 1" +# "line 2" + + +# Or, combine -s and -R to slurp the input lines into a single string. +# +(echo line 1; echo line 2) | jq -sR . + +# Output: +# "line 1\nline2\n" + + +# Inputs can also come from a JSON file specified at the command line: +# +echo '"hello"' > hello.json +jq . hello.json + +# Output: +# "hello" + + +# Passing a value into a jq program can be done with the `--arg` option. +# Below, `val` is the variable name to bind the value, `123`, to. +# The variable is then referenced as `$val`. +# +jq -n --arg val 123 '$val' # $val is the string "123" here + +# Output: +# "123" + + +# If you need to pass a JSON value, use `--argjson` +# +jq -n --argjson val 123 '$val' # $val is a number + +# Output: +# 123 + + +# Using `--arg` or `--argjson` is an useful way of building JSON output from +# existing input. +# +jq --arg text "$(date; echo "Have a nice day!")" -n '{ "today": $text }' + +# Output: +# { +# "today": "Sun Apr 10 09:53:07 PM EDT 2022\nHave a nice day!" +# } + + +# Instead of outputting values as JSON, you can use the `-r` option to print +# string values unquoted / unescaped. Non-string values are still printed as +# JSON. +# +echo '"hello" 2 [1, "two", null] {}' | jq -r . + +# Output: +# hello +# 2 +# [ +# 1, +# "two", +# null +# ] +# {} + + +# Inside a string in jq, `\(expr)` can be used to substitute the output of +# `expr` into the surrounding string context. +# +jq -rn '"1 + 2 = \(1+2)"' + +# Output: +# 1 + 2 = 3 + + +# The `-r` option is most useful for generating text outputs to be processed +# down in a shell pipeline, especially when combined with an intepolated +# string that is prefixed the `@sh` prefix operator. +# +# The `@sh` operator escapes the outputs of `\(...)` inside a string with +# single quotes so that each resulting string of `\(...)` can be evaluated +# by the shell as a single word / token / argument without special +# interpretations. +# +env_vars=$( + echo '{"var1": "value one", "var2": "value\ntwo"}' \ + | + jq -r ' + "export " + @sh "var1=\(.var1) var2=\(.var2)" + # ^^^^^^^^ ^^^^^^^^ + # "'value one'" "'value\ntwo'" + # + # NOTE: The + (plus) operator here concatenates strings. + ' +) +echo "$env_vars" +eval "$env_vars" +declare -p var1 var2 + +# Output: +# export var1='value one' var2='value +# two' +# declare -- var1="value one" +# declare -- var2="value +# two" + +# There are other string `@prefix` operators (e.g., @base64, @uri, @csv, ...) +# that might be useful to you. See `man jq` for details. + + +# The comma (`,`) operator in jq evaluates each operand and generates multiple +# outputs: +# +jq -n '"one", 2, ["three"], {"four": 4}' + +# Output: +# "one" +# 2 +# [ +# "three" +# ] +# { +# "four": 4 +# } + + +# Any JSON value is a valid jq expression that evaluates to the JSON value +# itself. +# +jq -n '1, "one", [1, 2], {"one": 1}, null, true, false' + +# Output: +# 1 +# "one" +# [ +# 1, +# 2 +# ] +# { +# "one": 1 +# } +# null +# true +# false + + +# Any jq expression can be used where a JSON value is expected, even as object +# keys. (though parenthesis might be required for object keys or values) +# +jq -n '[2*3, 8-1, 16/2], {("tw" + "o"): (1 + 1)}' + +# Output: +# [ +# 6, +# 7, +# 8 +# ] +# { +# "two": 2 +# } + + +# As a shortcut, if a JSON object key looks like a valid identifier (matching +# the regex `^[a-zA-Z_][a-zA-Z_0-9]*$`), quotes can be omitted. +# +jq -n '{ key_1: "value1" }' + +# If a JSON object's key's value is ommited, it is looked up in the current +# input using the key: (see next example for the meaning of `... | ...`) +# +jq -n '{c: 3} | {a: 1, "b", c}' + +# Output: +# { +# "a": 1, +# "b": null, +# "c": 3 +# } + + +# jq programs are more commonly written as a series of expressions (filters) +# connected by the pipe (`|`) operator, which makes the output of its left +# filter the input to its right filter. +# +jq -n '1 | . + 2 | . + 3' # first dot is 1; second dot is 3 + +# Output: +# 6 + +# If an expression evaluates to multiple outputs, then jq will iterate through +# them and propagate each output down the pipeline, and generate multiple +# outputs in the end. +# +jq -n '1, 2, 3 | ., 4 | .' + +# Output: +# 1 +# 4 +# 2 +# 4 +# 3 +# 4 + +# The flows of the data in the last example can be visualized like this: +# (number prefixed with `*` indicates the current output) +# +# *1, 2, 3 | *1, 4 | *1 +# 1, 2, 3 | 1, *4 | *4 +# 1, *2, 3 | *2, 4 | *2 +# 1, 2, 3 | 2, *4 | *4 +# 1, 2, *3 | *3, 4 | *3 +# 1, 2, 3 | 3, *4 | *4 +# +# +# To put it another way, the evaluation of the above example is very similar +# to the following pieces of code in other programming languages: +# +# In Python: +# +# for first_dot in 1, 2, 3: +# for second_dot in first_dot, 4: +# print(second_dot) +# +# In Ruby: +# +# [1, 2, 3].each do |dot| +# [dot, 4].each { |dot| puts dot } +# end +# +# In Javascript: +# +# [1, 2, 3].forEach(dot => { +# [dot, 4].forEach(dot => console.log(dot)) +# }) +# + + +# Below are some examples of array index and object attribute lookups using +# the `[expr]` operator after an expression. If `expr` is a number then it's +# an array index lookup; otherwise, it should be a string, in which case it's +# an object attribute lookup: + +# Array index lookup +# +jq -n '[2, {"four": 4}, 6][1 - 1]' # => 2 +jq -n '[2, {"four": 4}, 6][0]' # => 2 +jq -n '[2, {"four": 4}, 6] | .[0]' # => 2 + +# You can chain the lookups since they are just expressions. +# +jq -n '[2, {"four": 4}, 6][1]["fo" + "ur"]' # => 4 + +# For object attributes, you can also use the `.key` shortcut. +# +jq -n '[2, {"four": 4}, 6][1].four' # => 4 + +# Use `."key"` if the key is not a valid identifier. +# +jq -n '[2, {"f o u r": 4}, 6][1]."f o u r"' # => 4 + +# Array index lookup returns null if the index is not found. +# +jq -n '[2, {"four": 4}, 6][99]' # => null + +# Object attribute lookup returns null if the key is not found. +# +jq -n '[2, {"four": 4}, 6][1].whatever' # => null + +# The alternative operator `//` can be used to provide a default +# value when the result of the left operand is either `null` or `false`. +# +jq -n '.unknown_key // 7' # => 7 + +# If the thing before the lookup operator (`[expr]`) is neither an array +# or an object, then you will get an error: +# +jq -n '123 | .[0]' # => jq: error (at <unknown>): Cannot index number with number +jq -n '"abc" | .name' # => jq: error (at <unknown>): Cannot index string with string "name" +jq -n '{"a": 97} | .[0]' # => jq: error (at <unknown>): Cannot index object with number +jq -n '[89, 64] | .["key"]' # => jq: error (at <unknown>): Cannot index array with string "key" + +# You can, however, append a `?` to a lookup to make jq return `empty` +# instead when such error happens. +# +jq -n '123 | .[0]?' # no output since it's empty. +jq -n '"abc" | .name?' # no output since it's empty. + +# The alternative operator (`//`) also works with `empty`: +# +jq -n '123 | .[0]? // 99' # => 99 +jq -n '"abc" | .name? // "unknown"' # => "unknown" + +# NOTE: `empty` is actually a built-in function in jq. +# With the nested loop explanation we illustrated earlier before, +# `empty` is like the `continue` or the `next` keyword that skips +# the current iteration of the loop in some programming languages. + + +# Strings and arrays can be sliced with the same syntax (`[i:j]`, but no +# steppings) and semantic as found in the Python programming language: +# +# 0 1 2 3 4 5 ... infinite +# array = ["a", "b", "c", "d"] +# -infinite ... -4 -3 -2 -1 +# +jq -n '["Peter", "Jerry"][1]' # => "Jerry" +jq -n '["Peter", "Jerry"][-1]' # => "Jerry" +jq -n '["Peter", "Jerry", "Tom"][1:]' # => ["Jerry", "Tom"] +jq -n '["Peter", "Jerry", "Tom"][:1+1]' # => ["Peter", "Jerry"] +jq -n '["Peter", "Jerry", "Tom"][1:99]' # => ["Jerry", "Tom"] + + +# If the lookup index or key is ommited then jq iterates through +# the collection, generating one output value from each iteration. +# +# These examples produce the same outputs. +# +echo 1 2 3 | jq . +jq -n '1, 2, 3' +jq -n '[1, 2, 3][]' +jq -n '{a: 1, b: 2, c: 3}[]' + +# Output: +# 1 +# 2 +# 3 + + +# You can build an array out of multiple outputs. +# +jq -n '{values: [{a: 1, b: 2, c: 3}[] | . * 2]}' + +# Output: +# { +# "values": [ +# 2, +# 4, +# 6 +# ] +# } + + +# If multiple outputs are not contained, then we'd get multiple outputs +# in the end. +# +jq -n '{values: ({a: 1, b: 2, c: 3}[] | . * 2)}' + +# Output: +# { +# "values": 2 +# } +# { +# "values": 4 +# } +# { +# "values": 6 +# } + + +# Conditional `if ... then ... else ... end` in jq is an expression, so +# both the `then` part and the `else` part are required. In jq, only +# two values, `null` and `false`, are false; all other values are true. +# +jq -n 'if 1 > 2 | not and 1 <= 2 then "Makes sense" else "WAT?!" end' + +# Output +# "Makes sense" + +# Notice that `not` is a built-in function that takes zero arguments, +# that's why it's used as a filter to negate its input value. +# We'll talk about functions soon. + +# Another example using a conditional: +# +jq -n '1, 2, 3, 4, 5 | if . % 2 != 0 then . else empty end' + +# Output +# 1 +# 3 +# 5 + +# The `empty` above is a built-in function that takes 0 arguments and +# generates no outputs. Let's see more examples of built-in functions. + +# The above conditional example can be written using the `select/1` built-in +# function (`/1` indicates the number of arguments expected by the function). +# +jq -n '1, 2, 3, 4, 5 | select(. % 2 != 0)' # NOTE: % gives the remainder. + +# Output +# 1 +# 3 +# 5 + + +# Function arguments in jq are passed with call-by-name semantic, which +# means, an argument is not evaulated at call site, but instead, is +# treated as a lambda expression with the calling context of the call +# site as its scope for variable and function references used in the +# expression. +# +# In the above example, the expression `. % 2 != 0` is what's passed to +# `select/1` as the argument, not `true` or `false`, which is what would +# have been the case had the (boolean) expression was evaluated before it's +# passed to the function. + + +# The `range/1`, `range/2`, and `range/3` built-in functions generate +# integers within a given range. +# +jq -n '[range(3)]' # => [0, 1, 2] +jq -n '[range(0; 4)]' # => [0, 1, 2, 3] +jq -n '[range(2; 10; 2)]' # => [2, 4, 6, 8] + +# Notice that `;` (semicolon) is used to separate function arguments. + + +# The `map/1` function applies a given expression to each element of +# the current input (array) and outputs a new array. +# +jq -n '[range(1; 6) | select(. % 2 != 0)] | map(. * 2)' + +# Output: +# [ +# 2, +# 6, +# 10 +# ] + +# Without using `select/1` and `map/1`, we could have also written the +# above example like this: +# +jq -n '[range(1; 6) | if . % 2 != 0 then . else empty end | . * 2]' + + +# `keys/0` returns an array of keys of the current input. For an object, +# these are the object's attribute names; for an array, these are the +# array indices. +# +jq -n '[range(2; 10; 2)] | keys' # => [0, 1, 2, 3] +jq -n '{a: 1, b: 2, c: 3} | keys' # => ["a", "b", "c"] + +# `values/0` returns an array of values of the current input. For an object, +# these are the object's attribute values; for an array, these are the +# elements of the array. +# +jq -n '[range(2; 10; 2)] | values' # => [2, 4, 6, 8] +jq -n '{a: 1, b: 2, c: 3} | values' # => [1, 2, 3] + + +# `to_entries/0` returns an array of key-value objects of the current input +# object. +# +jq -n '{a: 1, b: 2, c: 3} | to_entries' + +# Output: +# [ +# { +# "key": "a", +# "value": 1 +# }, +# { +# "key": "b", +# "value": 2 +# }, +# { +# "key": "c", +# "value": 3 +# } +# ] + + +# Here's how you can turn an object's attribute into environment variables +# using what we have learned so far. +# +env_vars=$( + jq -rn '{var1: "1 2 3 4", var2: "line1\nline2\n"} + | to_entries[] + | "export " + @sh "\(.key)=\(.value)" + ' +) +eval "$env_vars" +declare -p var1 var2 + +# Output: +# declare -x var1="1 2 3 4" +# declare -x var2="line1 +# line2 +# " + + +# `from_entries/0` is the opposite of `to_entries/0` in that it takes an +# an array of key-value objects and turn that into an object with keys +# and values from the `key` and `value` attributes of the objects. +# +# It's useful together with `to_entries/0` when you need to iterate and +# do something to each attribute of an object. +# +jq -n '{a: 1, b: 2, c: 3} | to_entries | map(.value *= 2) | from_entries' + +# Output: +# { +# "a": 2, +# "b": 4, +# "c": 6 +# } + + +# The example above can be further shortened with the `with_entries/1` built-in: +# +jq -n '{a: 1, b: 2, c: 3} | with_entries(.value *= 2)' + + +# The `group_by/1` generates an array of groups (arrays) from the current +# input (array). The classification is done by applying the expression argument +# to each member of the input array. +# +# Let's look at a contrived example (Note that `tostring`, `tonumber`, +# `length` and `max` are all built-in jq functions. Feel free to look +# them up in the jq manual): +# +# Generate some random numbers. +numbers=$(echo $RANDOM{,,,,,,,,,,,,,,,,,,,,}) +# +# Feed the numbers to jq, classifying them into groups and calculating their +# averages, and finally generate a report. +# +echo $numbers | jq -rs ' # Slurp the numbers into an array. +[ + [ map(tostring) # Turn it into an array of strings. + | group_by(.[0:1]) # Group the numbers by their first digits. + | .[] # Iterate through the array of arrays (groups). + | map(tonumber) # Turn each group back to an array of numbers. + ] # Finally, contain all groups in an array. + + | sort_by([length, max]) # Sort the groups by their sizes. + # If two groups have the same size then the one with the largest + # number wins (is bigger). + + | to_entries[] # Enumerate the array, generating key-value objects. + | # For each object, generate two lines: + "Group \(.key): \(.value | sort | join(" "))" + "\n" + + "Average: \( .value | (add / length) )" + +] # Contain the group+average lines in an array. + # Join the array elements by separator lines (dashes) to produce the report. +| join("\n" + "-"*78 + "\n") +' + +# Output: +# +# Group 0: 3267 +# Average: 3267 +# ------------------------------------------------------------------------------ +# Group 1: 7854 +# Average: 7854 +# ------------------------------------------------------------------------------ +# Group 2: 4415 4447 +# Average: 4431 +# ------------------------------------------------------------------------------ +# Group 3: 681 6426 +# Average: 3553.5 +# ------------------------------------------------------------------------------ +# Group 4: 21263 21361 21801 21832 22947 23523 29174 +# Average: 23128.714285714286 +# ------------------------------------------------------------------------------ +# Group 5: 10373 12698 13132 13924 17444 17963 18934 18979 +# Average: 15430.875 + + +# The `add/1` built-in "reduces" an array of values to a single value. +# You can think of it as sticking the `+` operator in between each value of +# the collection. Here are some examples: +# +jq -n '[1, 2, 3, 4, 5] | add' # => 15 +jq -n '["a", "b", "c"] | add' # => "abc" + +# `+` concatenates arrays +jq -n '[["a"], ["b"], ["c"]] | add' + +# Output: +# [ +# "a", +# "b", +# "c" +# ] + +# `+` merges objects non-recursively. +jq -n '[{a: 1, b: {c: 3}}, {b: 2, c: 4}] | add' + +# Output: +# { +# "a": 1, +# "b": 2, +# "c": 4 +# } + + +# jq provides a special syntax for writing an expression that reduces +# the outputs generated by a given expresion to a single value. +# It has this form: +# +# reduce outputs_expr as $var (initial_value; reduction_expr) +# +# Examples: +# +jq -n 'reduce range(1; 6) as $i (0; . + $i)' # => 15 +jq -n 'reduce (1, 2, 3, 4, 5) as $i (0; . + $i)' # => 15 +jq -n '[1, 2, 3, 4, 5] | reduce .[] as $i (0; . + $i)' # => 15 +jq -n '["a", "b", "c"] | reduce .[] as $i (""; . + $i)' # => "abc" + +# Notice the `.` in the `reduction_expr` is the `initial_value` at first, +# and then it becomes the result of applying the `reduction_expr` as +# we iterate through the values of `outputs_expr`. The expression: +# +# reduce (1, 2, 3, 4, 5) as $i (0; . + $i) +# +# can be thought of as doing: +# +# 0 + 1 | . + 2 | . + 3 | . + 4 | . + 5 +# + + +# The `*` operator when used on two objects, merges both recursively. +# Therefore, to merge JSON objects recursively, you can use `reduce` +# with the `*` operator. For example: +# +echo ' + {"a": 1, "b": {"c": 3}} + { "b": {"d": 4}} + {"a": 99, "e": 5 } +' | jq -s 'reduce .[] as $m ({}; . * $m)' + +# Output: +# { +# "a": 99, +# "b": { +# "c": 3, +# "d": 4 +# }, +# "e": 5 +# } + + +# jq has variable assignment in the form of `expr as $var`, which binds +# the value of `expr` to `$var`, and `$var` is immutable. Further more, +# `... as ...` doesn't change the input of the next filter; its introduction +# in a filter pipeline is only for establishing the binding of a value to a +# variable, and its scope extends to the filters following its definition. +# (i.e., to look up a variable's definition, scan to the left of the filter +# chain from the expression using it until you find the definition) +# +jq -rn '[1, 2, 3, 4, 5] + | (.[0] + .[-1]) as $sum # Always put ( ) around the binding `expr` to avoid surprises. + | ($sum * length / 2) as $result # The current input at this step is still the initial array. + | "The result is: \($result)" # Same. +' + +# Output: +# The result is: 15 + + +# With the `expr as $var` form, if multiple values are generated by `expr` +# then jq will iterate through them and bind each value to `$var` in turn +# for the rest of the pipeline. +# +jq -rn 'range(2; 4) as $i + | range(1; 6) as $j + | "\($i) * \($j) = \($i * $j)" +' + +# Output: +# 2 * 1 = 2 +# 2 * 2 = 4 +# 2 * 3 = 6 +# 2 * 4 = 8 +# 2 * 5 = 10 +# 3 * 1 = 3 +# 3 * 2 = 6 +# 3 * 3 = 9 +# 3 * 4 = 12 +# 3 * 5 = 15 + + +# It's sometimes useful to bind the initial input to a variable at the +# start of a program, so that you can refer to it later down the pipeline. +# +jq -rn "$(cat <<'EOF' + {lookup: {a: 1, b: 2, c: 3}, + bonuses: {a: 5, b: 2, c: 9} + } + | . as $doc + | .bonuses + | to_entries[] + | "\(.key)'s total is \($doc.lookup[.key] + .value)" +EOF +)" + +# Output: +# a's total is 6 +# b's total is 4 +# c's total is 12 + + +# jq supports destructing during varible binding. This lets you extract values +# from an array or an object and bind them to variables. +# +jq -n '[range(5)] | . as [$first, $second] | $second' + +# Output: +# 1 + +jq -n '{ name: "Tom", numbers: [1, 2, 3], age: 32} + | . as { + name: $who, # bind .name to $who + $name, # shorthand for `name: $name` + numbers: [$first, $second], + } + | $name, $second, $first, $who +' + +# Output: +# "Tom" +# 2 +# 1 +# "Tom" + + +# In jq, values can be assigned to an array index or object key via the +# assignment operator, `=`. The same current input is given to both sides +# of the assignment operator, and the assignment itself evaluates to the +# current input. In other words, the assignment expression is evaluated +# for its side effect, and doesn't generate a new output. +# +jq -n '.a = 1 | .b = .a + 1' # => {"a": 1, "b": 2} + +# Note that input is `null` due to `jq -n`, so `.` is `null` in the first +# filter, and assiging to a key under `null` turns it into an object with +# the key. The same input (now an object) then gets piped to the next filter, +# which then sets the `b` key to the value of the `a` key plus `1`, which is `2`. +# + +# Another example: +# +jq -n '.a=1, .a.b=2' # => {"a": 1} {"a": {"b": 2}} + +# In the above example, two objects are generated because both assignments +# received `null` as their inputs, and each operand of the comma operator +# is evaluated independently. Notice also how you can easily generate +# nested objects. + + +# In addition to the assignment operator, jq also has operators like: +# `+=`, `-=`, `*=`, and '/=', ... etc. Basically, `a op= b` is a shorthand +# for `a = a op b`, and they are handy for updating an object attribute or +# an item in an array based on its current value. Examples: +# +jq -n '.a.b.c = 3 | .a.b.c = .a.b.c + 1' # => {"a": {"b": {"c": 4}}} +jq -n '.a.b.c = 3 | .a.b.c += 1' # => {"a": {"b": {"c": 4}}} + + +# To delete a value, use `del/1`, which takes a path expression that specifies +# the locations of the things to be deleted. Example: +# +jq -n '{a: 1, b: {c: 2}, d: [3, 4, 5]} | del(.b.c, .d[1]) | .b.x = 6' + +# Output: +# { +# "a": 1, +# "b": { +# "x": 6 +# }, +# "d": [ +# 3, +# 5 +# ] +# } + + +# Other than using jq's built-in functions, you can define your own. +# In fact, many built-in functions are defined using jq (see the link +# to jq's built-in functions at the end of the doc). +# +jq -n ' + def my_select(expr): if expr then . else empty end; + def my_map(expr): [.[] | expr]; + def sum: reduce .[] as $x (0; . + $x); + def my_range($from; $to): + if $from >= $to then + empty + else + $from, my_range($from + 1; $to) + end + ; + [my_range(1; 6)] | my_map(my_select(. % 2 != 0)) | sum +' + +# Output: +# 9 + +# Some notes about function definitons: +# +# - Functions are usually defined at the beginning, so that they are available +# to the rest of the jq program. +# +# - Each function definion should end with a `;` (semicolon). +# +# - It's also possible to define a function within another, though it's not shown here. +# +# - Function parameters are separated by `;` (semicolor). This is consistent with +# passing multiple arguments when calling a function. +# +# - A function can call itself; in fact, jq has TCO (Tail Call Optimization). +# +# - `def f($a; $b): ...;` is a shorthand for: `def f(a; b): a as $a | b as $b | ...` +``` + + +## Further Reading +- https://stedolan.github.io/jq/manual/ +- https://github.com/stedolan/jq/wiki/jq-Language-Description +- https://github.com/stedolan/jq/wiki/Cookbook +- https://github.com/stedolan/jq/blob/master/src/builtin.jq diff --git a/jquery.html.markdown b/jquery.html.markdown index 18077dca..cdcb89d9 100644 --- a/jquery.html.markdown +++ b/jquery.html.markdown @@ -12,8 +12,8 @@ jQuery is a JavaScript library that helps you "do more, write less". It makes ma Because jQuery is a JavaScript library you should [learn JavaScript first](https://learnxinyminutes.com/docs/javascript/) **NOTE**: jQuery has fallen out of the limelight in recent years, since you can achieve the same thing with the vanilla DOM (Document Object Model) API. So the only thing it is used for is a couple of handy features, such as the [jQuery date picker](https://api.jqueryui.com/datepicker) (which actually has a standard, unlike the `<input type="date">` HTML element), and the obvious decrease in the code length. -```js +```js /////////////////////////////////// // 1. Selectors diff --git a/json.html.markdown b/json.html.markdown index 1ccdb5cf..27f6bbe0 100644 --- a/json.html.markdown +++ b/json.html.markdown @@ -11,7 +11,7 @@ contributors: JSON is an extremely simple data-interchange format. As [json.org](https://json.org) says, it is easy for humans to read and write and for machines to parse and generate. -A piece of JSON must represent either: +A piece of JSON can be any value of the types listed later, but in practice almost always represents either: * A collection of name/value pairs (`{ }`). In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array. * An ordered list of values (`[ ]`). In various languages, this is realized as an array, vector, list, or sequence. diff --git a/ko-kr/go-kr.html.markdown b/ko-kr/go-kr.html.markdown index 3012c04f..aed0918e 100644 --- a/ko-kr/go-kr.html.markdown +++ b/ko-kr/go-kr.html.markdown @@ -81,7 +81,7 @@ func learnTypes() { // non-ASCII 리터럴. Go 소스는 UTF-8로 작성해야 한다. g := 'Σ' // 유니코드 코드 포인트를 담고 있고, int32 타입의 가칭(alias)인 rune 타입 - f := 3.14195 // float64, an IEEE-754 64-bit 부동소수 타입 + f := 3.14159 // float64, an IEEE-754 64-bit 부동소수 타입 c := 3 + 4i // complex128, 내부적으로는 두 개의 float64 타입으로 표현됨 // 초기값과 함께 사용하는 var 키워드. @@ -332,15 +332,15 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { ## 더 읽어볼 것들 -Go에 대한 모든 것들은 [Go 공식 웹 사이트](http://golang.org/)를 참고하자. +Go에 대한 모든 것들은 [Go 공식 웹 사이트](https://go.dev/)를 참고하자. 여기에는 따라해볼 튜토리얼, 웹 기반의 인터랙티브 실행환경과 많은 읽을거리들이 있다. Go 언어 자체에 대한 스펙도 읽어보기를 적극 추천한다. 읽기 쉽게 되어있고 그리 길지는 않다. -Go 소스코드에 대해 좀더 알아보고 싶다면 [Go 표준 라이브러리](http://golang.org/src/pkg/)를 +Go 소스코드에 대해 좀더 알아보고 싶다면 [Go 표준 라이브러리](https://go.dev/src/)를 분석해보기 바란다. 이해하기 쉽게 문서화되어 있고, Go 스타일 그리고 Go에서의 -관례 배우기에 가장 좋은 방법일 것이다. 또는 [문서](http://golang.org/pkg/) 안에서 +관례 배우기에 가장 좋은 방법일 것이다. 또는 [문서](https://go.dev/pkg/) 안에서 함수 이름 하나를 클릭해보면 소스코드를 브라우저에서 살펴볼 수도 있다. Go를 배울수 있는 또하나의 좋은 방법은 [Go by example](https://gobyexample.com/). diff --git a/ko-kr/markdown-kr.html.markdown b/ko-kr/markdown-kr.html.markdown index 397e9f30..0167f0ff 100644 --- a/ko-kr/markdown-kr.html.markdown +++ b/ko-kr/markdown-kr.html.markdown @@ -25,15 +25,18 @@ lang: ko-kr ## HTML 요소 HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다. + ```md <!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을 받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는 마크다운 문법을 사용할 수 없습니다.--> ``` + ## 제목 텍스트 앞에 붙이는 우물 정 기호(#)의 갯수에 따라 `<h1>`부터 `<h6>`까지의 HTML 요소를 손쉽게 작성할 수 있습니다. + ```md # <h1>입니다. ## <h2>입니다. @@ -42,7 +45,9 @@ HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마 ##### <h5>입니다. ###### <h6>입니다. ``` + 또한 h1과 h2를 나타내는 다른 방법이 있습니다. + ```md h1입니다. ============= @@ -50,9 +55,11 @@ h1입니다. h2입니다. ------------- ``` + ## 간단한 텍스트 꾸미기 마크다운으로 쉽게 텍스트를 기울이거나 굵게 할 수 있습니다. + ```md *기울인 텍스트입니다.* _이 텍스트도 같습니다._ @@ -64,10 +71,13 @@ __이 텍스트도 같습니다.__ **_이 텍스트도 같습니다._** *__이것도 같습니다.__* ``` + 깃헙 전용 마크다운에는 취소선도 있습니다. + ```md ~~이 텍스트에는 취소선이 그려집니다.~~ ``` + ## 문단 문단은 하나 이상의 빈 줄로 구분되는, 한 줄 이상의 인접한 텍스트입니다. @@ -103,6 +113,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어 ## 목록 순서가 없는 목록은 별표, 더하기, 하이픈을 이용해 만들 수 있습니다. + ```md * 이거 * 저거 @@ -140,6 +151,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어 1. 둘 1. 셋 ``` + (위의 예시와 똑같이 나타납니다.) 목록 안에 목록이 올 수도 있습니다. @@ -176,7 +188,7 @@ x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다. ```md my_array.each do |item| - puts item + puts item end ``` @@ -188,12 +200,13 @@ x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다. 깃헙 전용 마크다운에서는 코드를 나타내기 위해 특별한 문법을 쓸 수 있습니다. -<pre> -<code class="highlight">```ruby +````md +```ruby def foobar - puts "Hello world!" + puts "Hello world!" end -```</code></pre> +``` +```` 위의 경우에 들여쓰기가 필요없을 뿐 아니라 \`\`\` 뒤에 특정해 준 언어의 문법에 따라 색을 입혀줄 것입니다. @@ -202,12 +215,14 @@ end 수평선(`<hr/>`)은 셋 이상의 별표나 하이픈을 이용해 쉽게 나타낼 수 있습니다. 띄어쓰기가 포함될 수 있습니다. + ```md *** --- - - - **************** ``` + ## 링크 마크다운의 장점 중 하나는 링크를 만들기 쉽다는 것입니다. 대괄호 안에 나타낼 텍스트를 쓰고 @@ -231,20 +246,24 @@ end 참조하는 식으로 링크를 걸 수도 있습니다. -<pre><code class="highlight">[<span class="nv">이 </span>][<span class="ss">링크</span>]에서 더 알아보세요! -[<span class="nv">원하신다면 </span>][<span class="ss">foobar</span>]도 참고하세요. +```md +[이 ][링크]에서 더 알아보세요! +[원하신다면 ][foobar]도 참고하세요. -[<span class="nv">링크</span>]: <span class="sx">http://test.com/</span> <span class="nn">"좋아!"</span> -[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"됐다!"</span></code></pre> +[링크]: http://test.com/ "좋아!" +[foobar]: http://foobar.biz/ "됐다!" +``` 제목은 작은 따옴표나 괄호에 들어갈 수도 있고, 완전히 생략할 수도 있습니다. 참조는 문서의 어느 곳에든 올 수 있고 참조 ID는 유일하다면 무엇이든 될 수 있습니다. 링크 텍스트를 ID로 사용하는 "묵시적 이름"도 있습니다. -<pre><code class="highlight">[<span class="nv">이것</span>][]은 링크입니다. +```md +[이것][]은 링크입니다. -[<span class="nv">이것</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> +[이것]: http://thisisalink.com/ +``` 하지만 보통 그렇게 추천하지는 않습니다. @@ -257,9 +276,11 @@ end 참조 방식도 가능합니다. -<pre><code class="highlight">![<span class="nv">alt 속성</span>][<span class="ss">이미지</span>] +```md +![alt 속성][이미지] -[<span class="nv">이미지</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"제목이 필요하다면 여기에"</span></code></pre> +[이미지]: relative/urls/cool/image.jpg "제목이 필요하다면 여기에" +``` ## 기타 ### 자동 링크 @@ -270,9 +291,11 @@ end ``` ### 이메일 자동 링크 + ```md <foo@bar.com> ``` + ### 탈출 문자 ```md @@ -292,17 +315,21 @@ end ### 표 표는 깃헙 전용 마크다운에서만 쓸 수 있고 다소 복잡하지만, 정말 쓰고 싶으시다면 + ```md | 1열 | 2열 | 3열 | | :--------| :-------: | --------: | | 왼쪽 정렬 | 가운데 정렬 | 오른쪽 정렬 | | 머시기 | 머시기 | 머시기 | ``` + 혹은 + ```md 1열 | 2열 | 3열 :-- | :-: | --: 으악 너무 못생겼어 | 그만 | 둬 ``` + --- 추가 정보를 위해, 존 그루버의 공식 문법 [(영어) 문서](http://daringfireball.net/projects/markdown/syntax)와 애덤 프릿차드의 훌륭한 [(영어) 치트싯](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)을 확인하세요. diff --git a/kotlin.html.markdown b/kotlin.html.markdown index 12008074..a6fac518 100644 --- a/kotlin.html.markdown +++ b/kotlin.html.markdown @@ -26,7 +26,7 @@ any parameters. */ fun main(args: Array<String>) { /* - Declaring values is done using either "var" or "val". + Declaring variables is done using either "var" or "val". "val" declarations cannot be reassigned, whereas "vars" can. */ val fooVal = 10 // we cannot later reassign fooVal to something else @@ -297,7 +297,7 @@ fun helloWorld(val name : String) { else -> println("none of the above") } - // "when" can be used as a function that returns a value. + // "when" can be used as an expression that returns a value. var result = when (i) { 0, 21 -> "0 or 21" in 1..20 -> "in the range 1 to 20" diff --git a/lua.html.markdown b/lua.html.markdown index de71ccd4..f11d67a8 100644 --- a/lua.html.markdown +++ b/lua.html.markdown @@ -17,10 +17,7 @@ filename: learnlua.lua -- 1. Variables and flow control. ---------------------------------------------------- -num = 42 -- All numbers are doubles. --- Don't freak out, 64-bit doubles have 52 bits for --- storing exact int values; machine precision is --- not a problem for ints that need < 52 bits. +num = 42 -- Numbers can be integer or floating point. s = 'walternate' -- Immutable strings like Python. t = "double-quotes are also fine" @@ -402,7 +399,7 @@ If you need support join the official Lua [mailing list](https://www.lua.org/lua I was excited to learn Lua so I could make games with the <a href="http://love2d.org/">Love 2D game engine</a>. That's the why. -I started with <a href="https://ebens.me/post/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>. +I started with <a href="https://ebens.me/posts/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>. Next I read the official <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a> book. That's the how. diff --git a/m.html.markdown b/m.html.markdown index 87e0875e..46e7313b 100644 --- a/m.html.markdown +++ b/m.html.markdown @@ -17,8 +17,8 @@ more fits on one screen without scrolling. The M database is a hierarchical key-value store designed for high-throughput transaction processing. The database is organized into tree structures called -"globals", which are sparse data structures with parallels to modern formats -like JSON. +"globals", (for global variables) which are sparse data structures with parallels +to modern formats like JSON. Originally designed in 1966 for the healthcare applications, M continues to be used widely by healthcare systems and financial institutions for high-throughput @@ -26,7 +26,7 @@ real-time applications. ### Example -Here's an example M program to calculate the Fibonacci series: +Here's an example M program using expanded syntax to calculate the Fibonacci series: ``` fib ; compute the first few Fibonacci terms @@ -39,28 +39,38 @@ fib ; compute the first few Fibonacci terms ``` ### Comments +Comments in M need at least one space before the comment marker of semicolon. +Comments that start with at least two semicolons (;;) are guaranteed to be accessible +within a running program. ``` -; Comments start with a semicolon (;) + ; Comments start with a semicolon (;) ``` ### Data Types -M has two data types: +M has one data type (String) and three interpretations of that string.: ``` -; Numbers - no commas, leading and trailing 0 removed. -; Scientific notation with 'E'. -; Floats with IEEE 754 double-precision values (15 digits of precision) -; Examples: 20, 1e3 (stored as 1000), 0500.20 (stored as 500.2) ; Strings - Characters enclosed in double quotes. ; "" is the null string. Use "" within a string for " ; Examples: "hello", "Scrooge said, ""Bah, Humbug!""" +; +; Numbers - no commas, leading and trailing 0 removed. +; Scientific notation with 'E'. (not 'e') +; Numbers with at least with IEEE 754 double-precision values (guaranteed 15 digits of precision) +; Examples: 20 (stored as 20) , 1e3 (stored as 1000), 0500.20 (stored as 500.2), +; the US National Debt AT sometime on 12-OCT-2020 retrieved from http://www.usdebt.org is 27041423576201.15) +; (required to be stored as at least 27041422576201.10 but most implementations store as 27041432576201.15) +; +; Truthvalues - String interpreted as 0 is used for false and any string interpreted as non-zero (such as 1) for true. ``` ### Commands -Commands are case insensitive, and have a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces. +Commands are case insensitive, and have full form, and a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. This page includes programs written in this terse syntax. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces. (technically these are called argumentless commands) + +#### Common Commands from all National and International Standards of M -#### W(rite) +#### Write (abbreviated as W) Print data to the current device. @@ -68,13 +78,19 @@ Print data to the current device. WRITE !,"hello world" ``` -! is syntax for a new line. Multiple statements can be provided as additional arguments: +Output Formatting characters: + + The ! character is syntax for a new line. + The # character is syntax for a new page. + The sequence of the ? character and then a numeric expression is syntax for output of spaces until the number'th colum is printed. + +Multiple statements can be provided as additional arguments before the space separators to the next command: ``` w !,"foo bar"," ","baz" ``` -#### R(ead) +#### Read (abbreviated as R) Retrieve input from the user @@ -82,13 +98,13 @@ Retrieve input from the user READ var r !,"Wherefore art thou Romeo? ",why ``` -Multiple arguments can be passed to a read command. Constants are outputted. Variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt. +As with all M commands, multiple arguments can be passed to a read command. Constants like quoted strings, numbers, and formatting characters are output directly. Values for both global variables and local variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt. ``` r !,"Better one, or two? ",lorem," Better two, or three? ",ipsum ``` -#### S(et) +#### Set (abbreviated as S) Assign a value to a variable @@ -100,19 +116,21 @@ w !,centi,!,micro ;.01 ;.00001 ``` -#### K(ill) +#### Kill (abbreviated as K) Remove a variable from memory or remove a database entry from disk. - +A database node (global variable) is killed depending on the variable name being prefixed by the caret character (^). +If it is not, then the local variable is removed from memory. +If KILLed, automatic garbage collection occurs. ``` KILL centi k micro ``` ### Globals and Arrays -In addition to local variables, M has persistent variables stored to disk called _globals_. Global names must start with a __caret__ (__^__). Globals are the built-in database of M. +In addition to local variables, M has persistent, shared variables that are the built-in database of M. They are stored to disk and called _globals_. Global names must start with a __caret__ (__^__). -Any variable can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value. +Any variable (local or global) can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Only if data is stored will a value use memory. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value. ``` s ^cars=20 @@ -128,7 +146,7 @@ w !,^cars("Tesla",1,"Name") ; Model 3 ``` -Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value. +The index values of Arrays are automatically sorted in order. There is a catchphrase of "MUMPS means never having to say you are sorting". Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value, and then storing an empty string for that node. ``` ; A log of temperatures by date and time @@ -171,13 +189,14 @@ s ^TEMPS("11/12","1700",43)="" #### Order of operations Operations in M are _strictly_ evaluated left to right. No operator has precedence over any other. -You should use parentheses to group expressions. +For example, there is NO order of operations where multiply is evaluated before addition. +To change this order, just use parentheses to group expressions to be evaluated first. ``` w 5+3*20 ;160 ;You probably wanted 65 -w 5+(3*20) +write 5+(3*20) ``` ### Flow Control, Blocks, & Code Structure @@ -193,7 +212,7 @@ w !,$$tag^routine(a,b) M has an execution stack. When all levels of the stack have returned, the program ends. Levels are added to the stack with _do_ commands and removed with _quit_ commands. -#### D(o) +#### Do (abbreviated as D) With an argument: execute a block of code & add a level to the stack. @@ -216,12 +235,14 @@ if a=1 do w "hello" ``` -#### Q(uit) +#### Quit (abbreviated as Q) Stop executing this block and return to the previous stack level. -Quit can return a value. +Quit can return a value, following the comamnd with a single space. +Quit can stop a loop. remember to follow with two spaces. +Quit outside a loop will return from the current subroutine followed by two spaces or a linefeed -#### N(ew) -Clear a given variable's value _for just this stack level_. Useful for preventing side effects. +#### New (abbreviated as N) +Hide with a cleared value a given variable's value _for just this stack level_. Useful for preventing side effects. Putting all this together, we can create a full example of an M routine: @@ -233,20 +254,22 @@ main n length,width ; New length and width so any previous value doesn't persist w !,"Welcome to RECTANGLE. Enter the dimensions of your rectangle." r !,"Length? ",length,!,"Width? ",width - d area(length,width) ;Do a tag - s per=$$perimeter(length,width) ;Get the value of a function + d area(length,width) ;Do/Call subroutine using a tag + s per=$$perimeter(length,width) ;Get the value of a function w !,"Perimeter: ",per - q + quit area(length,width) ; This is a tag that accepts parameters. ; It's not a function since it quits with no value. w !, "Area: ",length*width - q ; Quit: return to the previous level of the stack. + q ; Quit: return to the previous level of the stack. perimeter(length,width) - q 2*(length+width) ; Quits with a value; thus a function + q 2*(length+width) ; Returns a value using Quit ; this is a function ``` + + ### Conditionals, Looping and $Order() F(or) loops can follow a few different patterns: @@ -255,13 +278,15 @@ F(or) loops can follow a few different patterns: ;Finite loop with counter ;f var=start:increment:stop -f i=0:5:25 w i," " ;0 5 10 15 20 25 +f i=0:5:25 w i," " +;0 5 10 15 20 25 ; Infinite loop with counter ; The counter will keep incrementing forever. Use a conditional with Quit to get out of the loop. ;f var=start:increment -f j=1:1 w j," " i j>1E3 q ; Print 1-1000 separated by a space +f j=1:1 w j," " i j>1E3 q +; Print 1-1000 separated by a space ;Argumentless for - infinite loop. Use a conditional with Quit. ; Also read as "forever" - f or for followed by two spaces. @@ -355,7 +380,11 @@ f s date=$ORDER(^TEMPS(date)) q:date="" d ## Further Reading -There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation. +There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation. More about M using VistA is at + +Intersystems has some products which are a super-set of the M programming language. +* [Iris Description Page][5] +* [Cache Description Page][6] To install an M interpreter / database on your computer, try a [YottaDB Docker image][2]. @@ -368,3 +397,5 @@ YottaDB and its precursor, GT.M, have thorough documentation on all the language [2]: https://yottadb.com/product/get-started/ [3]: https://docs.yottadb.com/ProgrammersGuide/langfeat.html [4]: http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/index.html +[5]: https://www.intersystems.com/products/intersystems-iris/ +[6]: https://en.wikipedia.org/wiki/InterSystems_Caché diff --git a/make.html.markdown b/make.html.markdown index eecc96bf..f5352f9e 100644 --- a/make.html.markdown +++ b/make.html.markdown @@ -1,246 +1,246 @@ ----
-category: tool
-tool: make
-contributors:
- - ["Robert Steed", "https://github.com/robochat"]
- - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
-filename: Makefile
----
-
-A Makefile defines a graph of rules for creating a target (or targets).
-Its purpose is to do the minimum amount of work needed to update a
-target to the most recent version of the source. Famously written over a
-weekend by Stuart Feldman in 1976, it is still widely used (particularly
-on Unix and Linux) despite many competitors and criticisms.
-
-There are many varieties of make in existence, however this article
-assumes that we are using GNU make which is the standard on Linux.
-
-```make
-
-# Comments can be written like this.
-
-# File should be named Makefile and then can be run as `make <target>`.
-# Otherwise we use `make -f "filename" <target>`.
-
-# Warning - only use TABS to indent in Makefiles, never spaces!
-
-#-----------------------------------------------------------------------
-# Basics
-#-----------------------------------------------------------------------
-
-# Rules are of the format
-# target: <prerequisite>
-# where prerequisites are optional.
-
-# A rule - this rule will only run if file0.txt doesn't exist.
-file0.txt:
- echo "foo" > file0.txt
- # Even comments in these 'recipe' sections get passed to the shell.
- # Try `make file0.txt` or simply `make` - first rule is the default.
-
-# This rule will only run if file0.txt is newer than file1.txt.
-file1.txt: file0.txt
- cat file0.txt > file1.txt
- # use the same quoting rules as in the shell.
- @cat file0.txt >> file1.txt
- # @ stops the command from being echoed to stdout.
- -@echo 'hello'
- # - means that make will keep going in the case of an error.
- # Try `make file1.txt` on the commandline.
-
-# A rule can have multiple targets and multiple prerequisites
-file2.txt file3.txt: file0.txt file1.txt
- touch file2.txt
- touch file3.txt
-
-# Make will complain about multiple recipes for the same rule. Empty
-# recipes don't count though and can be used to add new dependencies.
-
-#-----------------------------------------------------------------------
-# Phony Targets
-#-----------------------------------------------------------------------
-
-# A phony target. Any target that isn't a file.
-# It will never be up to date so make will always try to run it.
-all: maker process
-
-# We can declare things out of order.
-maker:
- touch ex0.txt ex1.txt
-
-# Can avoid phony rules breaking when a real file has the same name by
-.PHONY: all maker process
-# This is a special target. There are several others.
-
-# A rule with a dependency on a phony target will always run
-ex0.txt ex1.txt: maker
-
-# Common phony targets are: all make clean install ...
-
-#-----------------------------------------------------------------------
-# Automatic Variables & Wildcards
-#-----------------------------------------------------------------------
-
-process: file*.txt #using a wildcard to match filenames
- @echo $^ # $^ is a variable containing the list of prerequisites
- @echo $@ # prints the target name
- #(for multiple target rules, $@ is whichever caused the rule to run)
- @echo $< # the first prerequisite listed
- @echo $? # only the dependencies that are out of date
- @echo $+ # all dependencies including duplicates (unlike normal)
- #@echo $| # all of the 'order only' prerequisites
-
-# Even if we split up the rule dependency definitions, $^ will find them
-process: ex1.txt file0.txt
-# ex1.txt will be found but file0.txt will be deduplicated.
-
-#-----------------------------------------------------------------------
-# Patterns
-#-----------------------------------------------------------------------
-
-# Can teach make how to convert certain files into other files.
-
-%.png: %.svg
- inkscape --export-png $^
-
-# Pattern rules will only do anything if make decides to create the
-# target.
-
-# Directory paths are normally ignored when matching pattern rules. But
-# make will try to use the most appropriate rule available.
-small/%.png: %.svg
- inkscape --export-png --export-dpi 30 $^
-
-# make will use the last version for a pattern rule that it finds.
-%.png: %.svg
- @echo this rule is chosen
-
-# However make will use the first pattern rule that can make the target
-%.png: %.ps
- @echo this rule is not chosen if *.svg and *.ps are both present
-
-# make already has some pattern rules built-in. For instance, it knows
-# how to turn *.c files into *.o files.
-
-# Older makefiles might use suffix rules instead of pattern rules
-.png.ps:
- @echo this rule is similar to a pattern rule.
-
-# Tell make about the suffix rule
-.SUFFIXES: .png
-
-#-----------------------------------------------------------------------
-# Variables
-#-----------------------------------------------------------------------
-# aka. macros
-
-# Variables are basically all string types
-
-name = Ted
-name2="Sarah"
-
-echo:
- @echo $(name)
- @echo ${name2}
- @echo $name # This won't work, treated as $(n)ame.
- @echo $(name3) # Unknown variables are treated as empty strings.
-
-# There are 4 places to set variables.
-# In order of priority from highest to lowest:
-# 1: commandline arguments
-# 2: Makefile
-# 3: shell environment variables - make imports these automatically.
-# 4: make has some predefined variables
-
-name4 ?= Jean
-# Only set the variable if environment variable is not already defined.
-
-override name5 = David
-# Stops commandline arguments from changing this variable.
-
-name4 +=grey
-# Append values to variable (includes a space).
-
-# Pattern-specific variable values (GNU extension).
-echo: name2 = Sara # True within the matching rule
- # and also within its remade recursive dependencies
- # (except it can break when your graph gets too complicated!)
-
-# Some variables defined automatically by make.
-echo_inbuilt:
- echo $(CC)
- echo ${CXX}
- echo $(FC)
- echo ${CFLAGS}
- echo $(CPPFLAGS)
- echo ${CXXFLAGS}
- echo $(LDFLAGS)
- echo ${LDLIBS}
-
-#-----------------------------------------------------------------------
-# Variables 2
-#-----------------------------------------------------------------------
-
-# The first type of variables are evaluated each time they are used.
-# This can be expensive, so a second type of variable exists which is
-# only evaluated once. (This is a GNU make extension)
-
-var := hello
-var2 ::= $(var) hello
-#:= and ::= are equivalent.
-
-# These variables are evaluated procedurally (in the order that they
-# appear), thus breaking with the rest of the language !
-
-# This doesn't work
-var3 ::= $(var4) and good luck
-var4 ::= good night
-
-#-----------------------------------------------------------------------
-# Functions
-#-----------------------------------------------------------------------
-
-# make has lots of functions available.
-
-sourcefiles = $(wildcard *.c */*.c)
-objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
-
-# Format is $(func arg0,arg1,arg2...)
-
-# Some examples
-ls: * src/*
- @echo $(filter %.txt, $^)
- @echo $(notdir $^)
- @echo $(join $(dir $^),$(notdir $^))
-
-#-----------------------------------------------------------------------
-# Directives
-#-----------------------------------------------------------------------
-
-# Include other makefiles, useful for platform specific code
-include foo.mk
-
-sport = tennis
-# Conditional compilation
-report:
-ifeq ($(sport),tennis)
- @echo 'game, set, match'
-else
- @echo "They think it's all over; it is now"
-endif
-
-# There are also ifneq, ifdef, ifndef
-
-foo = true
-
-ifdef $(foo)
-bar = 'hello'
-endif
-```
-
-### More Resources
-
-+ [gnu make documentation](https://www.gnu.org/software/make/manual/)
-+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
-+ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
+--- +category: tool +tool: make +contributors: + - ["Robert Steed", "https://github.com/robochat"] + - ["Stephan Fuhrmann", "https://github.com/sfuhrm"] +filename: Makefile +--- + +A Makefile defines a graph of rules for creating a target (or targets). +Its purpose is to do the minimum amount of work needed to update a +target to the most recent version of the source. Famously written over a +weekend by Stuart Feldman in 1976, it is still widely used (particularly +on Unix and Linux) despite many competitors and criticisms. + +There are many varieties of make in existence, however this article +assumes that we are using GNU make which is the standard on Linux. + +```make + +# Comments can be written like this. + +# File should be named Makefile and then can be run as `make <target>`. +# Otherwise we use `make -f "filename" <target>`. + +# Warning - only use TABS to indent in Makefiles, never spaces! + +#----------------------------------------------------------------------- +# Basics +#----------------------------------------------------------------------- + +# Rules are of the format +# target: <prerequisite> +# where prerequisites are optional. + +# A rule - this rule will only run if file0.txt doesn't exist. +file0.txt: + echo "foo" > file0.txt + # Even comments in these 'recipe' sections get passed to the shell. + # Try `make file0.txt` or simply `make` - first rule is the default. + +# This rule will only run if file0.txt is newer than file1.txt. +file1.txt: file0.txt + cat file0.txt > file1.txt + # use the same quoting rules as in the shell. + @cat file0.txt >> file1.txt + # @ stops the command from being echoed to stdout. + -@echo 'hello' + # - means that make will keep going in the case of an error. + # Try `make file1.txt` on the commandline. + +# A rule can have multiple targets and multiple prerequisites +file2.txt file3.txt: file0.txt file1.txt + touch file2.txt + touch file3.txt + +# Make will complain about multiple recipes for the same rule. Empty +# recipes don't count though and can be used to add new dependencies. + +#----------------------------------------------------------------------- +# Phony Targets +#----------------------------------------------------------------------- + +# A phony target. Any target that isn't a file. +# It will never be up to date so make will always try to run it. +all: maker process + +# We can declare things out of order. +maker: + touch ex0.txt ex1.txt + +# Can avoid phony rules breaking when a real file has the same name by +.PHONY: all maker process +# This is a special target. There are several others. + +# A rule with a dependency on a phony target will always run +ex0.txt ex1.txt: maker + +# Common phony targets are: all make clean install ... + +#----------------------------------------------------------------------- +# Automatic Variables & Wildcards +#----------------------------------------------------------------------- + +process: file*.txt #using a wildcard to match filenames + @echo $^ # $^ is a variable containing the list of prerequisites + @echo $@ # prints the target name + #(for multiple target rules, $@ is whichever caused the rule to run) + @echo $< # the first prerequisite listed + @echo $? # only the dependencies that are out of date + @echo $+ # all dependencies including duplicates (unlike normal) + #@echo $| # all of the 'order only' prerequisites + +# Even if we split up the rule dependency definitions, $^ will find them +process: ex1.txt file0.txt +# ex1.txt will be found but file0.txt will be deduplicated. + +#----------------------------------------------------------------------- +# Patterns +#----------------------------------------------------------------------- + +# Can teach make how to convert certain files into other files. + +%.png: %.svg + inkscape --export-png $^ + +# Pattern rules will only do anything if make decides to create the +# target. + +# Directory paths are normally ignored when matching pattern rules. But +# make will try to use the most appropriate rule available. +small/%.png: %.svg + inkscape --export-png --export-dpi 30 $^ + +# make will use the last version for a pattern rule that it finds. +%.png: %.svg + @echo this rule is chosen + +# However make will use the first pattern rule that can make the target +%.png: %.ps + @echo this rule is not chosen if *.svg and *.ps are both present + +# make already has some pattern rules built-in. For instance, it knows +# how to turn *.c files into *.o files. + +# Older makefiles might use suffix rules instead of pattern rules +.png.ps: + @echo this rule is similar to a pattern rule. + +# Tell make about the suffix rule +.SUFFIXES: .png + +#----------------------------------------------------------------------- +# Variables +#----------------------------------------------------------------------- +# aka. macros + +# Variables are basically all string types + +name = Ted +name2="Sarah" + +echo: + @echo $(name) + @echo ${name2} + @echo $name # This won't work, treated as $(n)ame. + @echo $(name3) # Unknown variables are treated as empty strings. + +# There are 4 places to set variables. +# In order of priority from highest to lowest: +# 1: commandline arguments +# 2: Makefile +# 3: shell environment variables - make imports these automatically. +# 4: make has some predefined variables + +name4 ?= Jean +# Only set the variable if environment variable is not already defined. + +override name5 = David +# Stops commandline arguments from changing this variable. + +name4 +=grey +# Append values to variable (includes a space). + +# Pattern-specific variable values (GNU extension). +echo: name2 = Sara # True within the matching rule + # and also within its remade recursive dependencies + # (except it can break when your graph gets too complicated!) + +# Some variables defined automatically by make. +echo_inbuilt: + echo $(CC) + echo ${CXX} + echo $(FC) + echo ${CFLAGS} + echo $(CPPFLAGS) + echo ${CXXFLAGS} + echo $(LDFLAGS) + echo ${LDLIBS} + +#----------------------------------------------------------------------- +# Variables 2 +#----------------------------------------------------------------------- + +# The first type of variables are evaluated each time they are used. +# This can be expensive, so a second type of variable exists which is +# only evaluated once. (This is a GNU make extension) + +var := hello +var2 ::= $(var) hello +#:= and ::= are equivalent. + +# These variables are evaluated procedurally (in the order that they +# appear), thus breaking with the rest of the language ! + +# This doesn't work +var3 ::= $(var4) and good luck +var4 ::= good night + +#----------------------------------------------------------------------- +# Functions +#----------------------------------------------------------------------- + +# make has lots of functions available. + +sourcefiles = $(wildcard *.c */*.c) +objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) + +# Format is $(func arg0,arg1,arg2...) + +# Some examples +ls: * src/* + @echo $(filter %.txt, $^) + @echo $(notdir $^) + @echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Directives +#----------------------------------------------------------------------- + +# Include other makefiles, useful for platform specific code +include foo.mk + +sport = tennis +# Conditional compilation +report: +ifeq ($(sport),tennis) + @echo 'game, set, match' +else + @echo "They think it's all over; it is now" +endif + +# There are also ifneq, ifdef, ifndef + +foo = true + +ifdef $(foo) +bar = 'hello' +endif +``` + +### More Resources + ++ [gnu make documentation](https://www.gnu.org/software/make/manual/) ++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) ++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) diff --git a/markdown.html.markdown b/markdown.html.markdown index fefb60f6..ee213083 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -207,7 +207,7 @@ inside your code. ```md my_array.each do |item| - puts item + puts item end ``` @@ -219,12 +219,13 @@ John didn't even know what the `go_to()` function did! In GitHub Flavored Markdown, you can use a special syntax for code. -<pre> -<code class="highlight">```ruby +````md +```ruby def foobar - puts "Hello world!" + puts "Hello world!" end -```</code></pre> +``` +```` The above text doesn't require indenting, plus GitHub will use syntax highlighting of the language you specify after the opening <code>```</code>. @@ -264,11 +265,13 @@ Relative paths work too. Markdown also supports reference style links. -<pre><code class="highlight">[<span class="nv">Click this link</span>][<span class="ss">link1</span>] for more info about it! -[<span class="nv">Also check out this link</span>][<span class="ss">foobar</span>] if you want to. +```md +[Click this link][link1] for more info about it! +[Also check out this link][foobar] if you want to. -[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Cool!"</span> -[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Alright!"</span></code></pre> +[link1]: http://test.com/ "Cool!" +[foobar]: http://foobar.biz/ "Alright!" +``` The title can also be in single quotes or in parentheses, or omitted entirely. The references can be anywhere in your document and the reference IDs @@ -276,9 +279,11 @@ can be anything so long as they are unique. There is also "implicit naming" which lets you use the link text as the id. -<pre><code class="highlight">[<span class="nv">This</span>][] is a link. +```md +[This][] is a link. -[<span class="nv">This</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> +[This]: http://thisisalink.com/ +``` But it's not that commonly used. @@ -311,9 +316,11 @@ Images are done the same way as links but with an exclamation point in front! And reference style works as expected. -<pre><code class="highlight">![<span class="nv">This is the alt-attribute.</span>][<span class="ss">myimage</span>] +```md +![This is the alt-attribute.][myimage] -[<span class="nv">myimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"if you need a title, it's here"</span></code></pre> +[myimage]: relative/urls/cool/image.jpg "if you need a title, it's here" +``` ## Miscellany diff --git a/mercury.html.markdown b/mercury.html.markdown index f749bac4..6d278ce0 100644 --- a/mercury.html.markdown +++ b/mercury.html.markdown @@ -254,7 +254,7 @@ received(crypto(Type, _Wallet, Amount)) = S :- % _Wallet is named throwaway * [Mercury Tutorial](https://mercurylang.org/documentation/papers/book.pdf) (pdf link) - a more traditional tutorial with a more relaxed pace * [Mercury Crash Course](https://mercury-in.space/crash.html) - a dense example-driven tutorial with Q&A format -* [Github Wiki Tutorial](https://github.com/Mercury-Language/mercury/wiki/Tutorial) +* [GitHub Wiki Tutorial](https://github.com/Mercury-Language/mercury/wiki/Tutorial) * [Getting Started with Mercury](https://bluishcoder.co.nz/2019/06/23/getting-started-with-mercury.html) - installation and your first steps ### Documentation diff --git a/mongodb.html.markdown b/mongodb.html.markdown index 306f361c..f4e7d709 100644 --- a/mongodb.html.markdown +++ b/mongodb.html.markdown @@ -228,7 +228,7 @@ db.engineers.update({ name: 'Foo Baz' }, ) /////////////////////// Delete ///////////////////////// -// Queries are in the form of db.collectionName.find(<filter>) +// Queries are in the form of db.collectionName.delete(<filter>) // Delete first document matching query, always returns deletedCount db.engineers.deleteOne({ name: 'Foo Baz' }) @@ -252,20 +252,21 @@ db.engineers.deleteMany({ gender: 'Male' }) //////////////// Comparison Operators /////////////////// // Find all greater than or greater than equal to some condition -db.engineers.find({ $gt: { age: 25 }}) -db.engineers.find({ $gte: { age: 25 }}) +db.engineers.find({ age: { $gt: 25 }}) +db.engineers.find({ age: { $gte: 25 }}) // Find all less than or less than equal to some condition -db.engineers.find({ $lt: { age: 25 }}) -db.engineers.find({ $lte: { age: 25 }}) +db.engineers.find({ age: { $lt: 25 }}) +db.engineers.find({ age: { $lte: 25 }}) // Find all equal or not equal to // Note: the $eq operator is added implicitly in most queries -db.engineers.find({ $eq: { age: 25 }}) -db.engineers.find({ $ne: { age: 25 }}) +db.engineers.find({ age: { $eq: 25 }}) +db.engineers.find({ age: { $ne: 25 }}) -// Find all that match any element in the array -db.engineers.find({ age: ${ in: [ 20, 23, 24, 25 ]}}) +// Find all that match any element in the array, or not in the array +db.engineers.find({ age: { $in: [ 20, 23, 24, 25 ]}}) +db.engineers.find({ age: { $nin: [ 20, 23, 24, 25 ]}}) //////////////// Logical Operators /////////////////// diff --git a/montilang.html.markdown b/montilang.html.markdown index 483dc5a5..14b45d31 100644 --- a/montilang.html.markdown +++ b/montilang.html.markdown @@ -230,4 +230,4 @@ DEL 1 PRINT . /# [1, 3] #/ ## Extra information - [MontiLang.ml](http://montilang.ml/) -- [Github Page](https://github.com/lduck11007/MontiLang) +- [GitHub Page](https://github.com/lduck11007/MontiLang) diff --git a/neat.html.markdown b/neat.html.markdown deleted file mode 100644 index f02461ee..00000000 --- a/neat.html.markdown +++ /dev/null @@ -1,297 +0,0 @@ ---- -language: neat -contributors: - - ["Feep", "https://github.com/FeepingCreature"] -filename: LearnNeat.nt ---- - -Neat is basically a smaller version of D1 with some experimental syntax and a focus on terseness without losing the basic C-like syntax. - -[Read more here.](https://github.com/FeepingCreature/fcc/wiki) - -```c -// single line comments start with // -/* - multiline comments look like this -*/ -/+ - or this - /+ these can be nested too, same as D +/ -+/ - -// Module name. This has to match the filename/directory. -module LearnNeat; - -// Make names from another module visible in this one. -import std.file; -// You can import multiple things at once. -import std.math, std.util; -// You can even group up imports! -import std.(process, socket); - -// Global functions! -void foo() { } - -// Main function, same as in C. -// string[] == "array of strings". -// "string" is just an alias for char[], -void main(string[] args) { - // Call functions with "function expression". - writeln "Hello World"; - // You can do it like in C too... if you really want. - writeln ("Hello World"); - // Declare a variable with "type identifier" - string arg = ("Hello World"); - writeln arg; - // (expression, expression) forms a tuple. - // There are no one-value tuples though. - // So you can always use () in the mathematical sense. - // (string) arg; <- is an error - - /* - byte: 8 bit signed integer - char: 8 bit UTF-8 byte component. - short: 16 bit signed integer - int: 32 bit signed integer - long: 64 bit signed integer - - float: 32 bit floating point - double: 64 bit floating point - real: biggest native size floating point (80 bit on x86). - - bool: true or false - */ - int a = 5; - bool b = true; - // as in C, && and || are short-circuit evaluating. - b = b && false; - assert(b == false); - // "" are "format strings". So $variable will be substituted at runtime - // with a formatted version of the variable. - writeln "$a"; - // This will just print $a. - writeln `$a`; - // you can format expressions with $() - writeln "$(2+2)"; - // Note: there is no special syntax for characters. - char c = "a"; - // Cast values by using type: expression. - // There are three kinds of casts: - // casts that just specify conversions that would be happening automatically - // (implicit casts) - float f = float:5; - float f2 = 5; // would also work - // casts that require throwing away information or complicated computation - - // those must always be done explicitly - // (conversion casts) - int i = int:f; - // int i = f; // would not work! - // and, as a last attempt, casts that just reinterpret the raw data. - // Those only work if the types have the same size. - string s = "Hello World"; - // Arrays are (length, pointer) pairs. - // This is a tuple type. Tuple types are (type, type, type). - // The type of a tuple expression is a tuple type. (duh) - (int, char*) array = (int, char*): s; - // You can index arrays and tuples using the expression[index] syntax. - writeln "pointer is $(array[1]) and length is $(array[0])"; - // You can slice them using the expression[from .. to] syntax. - // Slicing an array makes another array. - writeln "$(s[0..5]) World"; - // Alias name = expression gives the expression a name. - // As opposed to a variable, aliases do not have an address - // and can not be assigned to. (Unless the expression is assignable) - alias range = 0 .. 5; - writeln "$(s[range]) World"; - // You can iterate over ranges. - for int i <- range { - write "$(s[i])"; - } - writeln " World"; - // Note that if "range" had been a variable, it would be 'empty' now! - // Range variables can only be iterated once. - // The syntax for iteration is "expression <- iterable". - // Lots of things are iterable. - for char c <- "Hello" { write "$c"; } - writeln " World"; - // For loops are "for test statement"; - alias test = char d <- "Hello"; - for test write "$d"; - writeln " World\t\x05"; // note: escapes work - // Pointers: function the same as in C, btw. The usual. - // Do note: the pointer star sticks with the TYPE, not the VARIABLE! - string* p; - assert(p == null); // default initializer - p = &s; - writeln "$(*p)"; - // Math operators are (almost) standard. - int x = 2 + 3 * 4 << 5; - // Note: XOR is "xor". ^ is reserved for exponentiation (once I implement that). - int y = 3 xor 5; - int z = 5; - assert(z++ == 5); - assert(++z == 7); - writeln "x $x y $y z $z"; - // As in D, ~ concatenates. - string hewo = "Hello " ~ "World"; - // == tests for equality, "is" tests for identity. - assert (hewo == s); - assert !(hewo is s); - // same as - assert (hewo !is s); - - // Allocate arrays using "new array length" - int[] integers = new int[] 10; - assert(integers.length == 10); - assert(integers[0] == 0); // zero is default initializer - integers = integers ~ 5; // This allocates a new array! - assert(integers.length == 11); - - // This is an appender array. - // Instead of (length, pointer), it tracks (capacity, length, pointer). - // When you append to it, it will use the free capacity if it can. - // If it runs out of space, it reallocates - but it will free the old array automatically. - // This makes it convenient for building arrays. - int[auto~] appender; - appender ~= 2; - appender ~= 3; - appender.free(); // same as {mem.free(appender.ptr); appender = null;} - - // Scope variables are automatically freed at the end of the current scope. - scope int[auto~] someOtherAppender; - // This is the same as: - int[auto~] someOtherAppender2; - onExit { someOtherAppender2.free; } - - // You can do a C for loop too - // - but why would you want to? - for (int i = 0; i < 5; ++i) { } - // Otherwise, for and while are the same. - while int i <- 0..4 { - assert(i == 0); - break; // continue works too - } then assert(false); // if we hadn't break'd, this would run at the end - // This is the height of loopdom - the produce-test-consume loop. - do { - int i = 5; - } while (i == 5) { - assert(i == 5); - break; // otherwise we'd go back up to do { - } - - // This is a nested function. - // Nested functions can access the surrounding function. - string returnS() { return s; } - writeln returnS(); - - // Take the address of a function using & - // The type of a global function is ReturnType function(ParameterTypeTuple). - void function() foop = &foo; - - // Similarly, the type of a nested function is ReturnType delegate(ParameterTypeTuple). - string delegate() returnSp = &returnS; - writeln returnSp(); - // Class member functions and struct member functions also fit into delegate variables. - // In general, delegates are functions that carry an additional context pointer. - // ("fat pointers" in C) - - // Allocate a "snapshot" with "new delegate". - // Snapshots are not closures! I used to call them closures too, - // but then my Haskell-using friends yelled at me so I had to stop. - // The difference is that snapshots "capture" their surrounding context - // when "new" is used. - // This allows things like this - int delegate(int) add(int a) { - int add_a(int b) { return a + b; } - // This does not work - the context of add_a becomes invalid - // when add returns. - // return &add_a; - // Instead: - return new &add_a; - } - int delegate(int) dg = add 2; - assert (dg(3) == 5); - // or - assert (((add 2) 3) == 5); - // or - assert (add 2 3 == 5); - // add can also be written as - int delegate(int) add2(int a) { - // this is an implicit, nameless nested function. - return new λ(int b) { return a + b; } - } - // or even - auto add3(int a) { return new λ(int b) -> a + b; } - // hahahaaa - auto add4 = λ(int a) -> new λ(int b) -> a + b; - assert(add4 2 3 == 5); - // If your keyboard doesn't have a λ (you poor sod) - // you can use \ too. - auto add5 = \(int a) -> new \(int b) -> a + b; - // Note! - auto nestfun = λ() { } // There is NO semicolon needed here! - // "}" can always substitute for "};". - // This provides syntactic consistency with built-in statements. - - - // This is a class. - // Note: almost all elements of Neat can be used on the module level - // or just as well inside a function. - class C { - int a; - void writeA() { writeln "$a"; } - // It's a nested class - it exists in the context of main(). - // so if you leave main(), any instances of C become invalid. - void writeS() { writeln "$s"; } - } - C cc = new C; - // cc is a *reference* to C. Classes are always references. - cc.a = 5; // Always used for property access. - auto ccp = &cc; - (*ccp).a = 6; - // or just - ccp.a = 7; - cc.writeA(); - cc.writeS(); // to prove I'm not making things up - // Interfaces work same as in D, basically. Or Java. - interface E { void doE(); } - // Inheritance works same as in D, basically. Or Java. - class D : C, E { - override void writeA() { writeln "hahahahaha no"; } - override void doE() { writeln "eeeee"; } - // all classes inherit from Object. (toString is defined in Object) - override string toString() { return "I am a D"; } - } - C cd = new D; - // all methods are always virtual. - cd.writeA(); - E e = E:cd; // dynamic class cast! - e.doE(); - writeln "$e"; // all interfaces convert to Object implicitly. - - // Templates! - // Templates are parameterized namespaces, taking a type as a parameter. - template Templ(T) { - alias hi = 5, hii = 8; - // Templates always have to include something with the same name as the template - // - this will become the template's _value_. - // Static ifs are evaluated statically, at compile-time. - // Because of this, the test has to be a constant expression, - // or something that can be optimized to a constant. - static if (types-equal (T, int)) { - alias Templ = hi; - } else { - alias Templ = hii; - } - } - assert(Templ!int == 5); - assert(Templ!float == 8); -} -``` - -## Topics Not Covered - - * Extended iterator types and expressions - * Standard library - * Conditions (error handling) - * Macros diff --git a/nim.html.markdown b/nim.html.markdown index b10bd75a..81662630 100644 --- a/nim.html.markdown +++ b/nim.html.markdown @@ -3,7 +3,7 @@ language: Nim filename: learnNim.nim contributors: - ["Jason J. Ayala P.", "http://JasonAyala.com"] - - ["Dennis Felsing", "http://felsin9.de/nnis/"] + - ["Dennis Felsing", "https://dennis.felsing.org"] --- Nim (formerly Nimrod) is a statically typed, imperative programming language diff --git a/nix.html.markdown b/nix.html.markdown index 1d5a7778..677aaf54 100644 --- a/nix.html.markdown +++ b/nix.html.markdown @@ -305,6 +305,9 @@ with builtins; [ ({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; } #=> "a-b" + # The entire set can be bound to a variable using `@` + (args@{x, y}: args.x + "-" + args.y) { x = "a"; y = "b"; } + #=> "a-b" # Errors #========================================= @@ -355,7 +358,7 @@ with builtins; [ # its contents. You can read files from anywhere. In this example, # we write a file into the store, and then read it back out. (let filename = toFile "foo.txt" "hello!"; in - [filename (builtins.readFile filename)]) + [filename (readFile filename)]) #=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ] # We can also download files into the Nix store. @@ -375,6 +378,9 @@ with builtins; [ * [Susan Potter - Nix Cookbook - Nix By Example] (https://ops.functionalalgebra.com/nix-by-example/) - + +* [Zero to Nix - Nix Tutorial] + (https://zero-to-nix.com/) + * [Rommel Martinez - A Gentle Introduction to the Nix Family] (https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix) diff --git a/nl-nl/markdown-nl.html.markdown b/nl-nl/markdown-nl.html.markdown index b5b4681c..0af78d88 100644 --- a/nl-nl/markdown-nl.html.markdown +++ b/nl-nl/markdown-nl.html.markdown @@ -52,7 +52,7 @@ __En deze tekst ook!__ *__En zelfs deze!__* <!-- In de github versie van markdown, die gebruikt wordt om markdown te renderen -op Github, is er ook doorstrepen --> +op GitHub, is er ook doorstrepen --> ~~Deze tekst wordt doorstreept.~~ @@ -142,7 +142,7 @@ Dit item zal aangevinkt zijn in de gerenderde html. John wist zelfs niet dat de `go_to()` functie bestond! -<!-- In Github Markdown kan je een speciale syntax gebruiken die aangeeft welke +<!-- In GitHub Markdown kan je een speciale syntax gebruiken die aangeeft welke taal gebruikt wordt in het code blok. --> \`\`\`ruby <!-- Wis de backslashes om dit te doen, juist ```ruby ! --> @@ -151,7 +151,7 @@ def foobar end \`\`\` <!-- Hier ook, geen backslashes, juist ``` --> -<!-- Voor bovenstaande tekst moet geen tab gebruikt worden. Plus, Github zal syntax +<!-- Voor bovenstaande tekst moet geen tab gebruikt worden. Plus, GitHub zal syntax highlighting gebruiken voor deze specifieke taal. Hier, Ruby. <!-- Horizontale lijn (<hr />) --> @@ -215,13 +215,13 @@ worden. Dit kan je oplossen met backslashes: \*dit\* staat tussen sterretjes <!-- Toetsenbord toetsen --> -<!-- In Github Markdown, kan je <kbd> gebruiken om toetsenbord toetsen weer te geven --> +<!-- In GitHub Markdown, kan je <kbd> gebruiken om toetsenbord toetsen weer te geven --> Loopt je computer vast? Probeer volgende toetsen combinatie: <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> <!-- Tabellen --> -<!-- Tabellen zijn momenteel enkel beschikbaar in Github Markdown en zijn redelijk omslachtig. +<!-- Tabellen zijn momenteel enkel beschikbaar in GitHub Markdown en zijn redelijk omslachtig. Maar als je er echt wilt toevoegen: --> | Col1 | Col2 | Col3 | diff --git a/objective-c.html.markdown b/objective-c.html.markdown index c029c5fb..c179c295 100644 --- a/objective-c.html.markdown +++ b/objective-c.html.markdown @@ -387,7 +387,7 @@ if ([myClass respondsToSelector:selectorVar]) { // Checks if class contains meth // Implement the methods in an implementation (MyClass.m) file: @implementation MyClass { long distance; // Private access instance variable - NSNumber height; + NSNumber *height; } // To access a public variable from the interface file, use '_' followed by variable name: diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 70668611..2c5e13d5 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -3,26 +3,31 @@ language: OCaml filename: learnocaml.ml contributors: - ["Daniil Baturin", "http://baturin.org/"] + - ["Stanislav Modrak", "https://stanislav.gq/"] + - ["Luke Tong", "https://lukert.me/"] --- - OCaml is a strictly evaluated functional language with some imperative features. -Along with StandardML and its dialects it belongs to ML language family. +Along with Standard ML and its dialects it belongs to ML language family. F# is also heavily influenced by OCaml. -Just like StandardML, OCaml features both an interpreter, that can be +Just like Standard ML, OCaml features both an interpreter, that can be used interactively, and a compiler. -The interpreter binary is normally called "ocaml" and the compiler is "ocamlopt". -There is also a bytecode compiler, "ocamlc", but there are few reasons to use it. +The interpreter binary is normally called `ocaml` and the compiler is `ocamlopt`. +There is also a bytecode compiler, `ocamlc`, but there are few reasons to use it. + +It also includes a package manager, `opam`, and a build system, `dune`. It is strongly and statically typed, but instead of using manually written -type annotations, it infers types of expressions using Hindley-Milner algorithm. +type annotations, it infers types of expressions using the +[Hindley-Milner](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system) +algorithm. It makes type annotations unnecessary in most cases, but can be a major source of confusion for beginners. When you are in the top level loop, OCaml will print the inferred type -after you enter an expression. +after you enter an expression ``` # let inc x = x + 1 ;; @@ -31,8 +36,8 @@ val inc : int -> int = <fun> val a : int = 99 ``` -For a source file you can use "ocamlc -i /path/to/file.ml" command -to print all names and type signatures. +For a source file you can use the `ocamlc -i /path/to/file.ml` command +to print all names and type signatures ``` $ cat sigtest.ml @@ -48,12 +53,12 @@ val a : int ``` Note that type signatures of functions of multiple arguments are -written in curried form. A function that takes multiple arguments can be +written in [curried](https://en.wikipedia.org/wiki/Currying) form. +A function that takes multiple arguments can be represented as a composition of functions that take only one argument. -The "f(x,y) = x + y" function from the example above applied to -arguments 2 and 3 is equivalent to the "f0(y) = 2 + y" function applied to 3. -Hence the "int -> int -> int" signature. - +The `f(x,y) = x + y` function from the example above applied to +arguments 2 and 3 is equivalent to the `f0(y) = 2 + y` function applied to 3. +Hence the `int -> int -> int` signature. ```ocaml (*** Comments ***) @@ -65,13 +70,14 @@ Hence the "int -> int -> int" signature. (*** Variables and functions ***) -(* Expressions can be separated by a double semicolon symbol, ";;". +(* Expressions can be separated by a double semicolon ";;". In many cases it's redundant, but in this tutorial we use it after every expression for easy pasting into the interpreter shell. Unnecessary use of expression separators in source code files is often considered to be a bad style. *) -(* Variable and function declarations use "let" keyword. *) +(* Variable and function declarations use the "let" keyword. *) +(* Variables are immutable by default in OCaml *) let x = 10 ;; (* OCaml allows single quote characters in identifiers. @@ -109,42 +115,42 @@ let sqr2 = sqr (-2) ;; "unit" type for it that has the only one value written as "()" *) let print_hello () = print_endline "hello world" ;; -(* Note that you must specify "()" as argument when calling it. *) +(* Note that you must specify "()" as the argument when calling it. *) print_hello () ;; -(* Calling a function with insufficient number of arguments +(* Calling a function with an insufficient number of arguments does not cause an error, it produces a new function. *) let make_inc x y = x + y ;; (* make_inc is int -> int -> int *) let inc_2 = make_inc 2 ;; (* inc_2 is int -> int *) inc_2 3 ;; (* Evaluates to 5 *) -(* You can use multiple expressions in function body. +(* You can use multiple expressions in the function body. The last expression becomes the return value. All other expressions must be of the "unit" type. This is useful when writing in imperative style, the simplest - form of it is inserting a debug print. *) + form of which is inserting a debug print. *) let print_and_return x = print_endline (string_of_int x); x ;; (* Since OCaml is a functional language, it lacks "procedures". - Every function must return something. So functions that - do not really return anything and are called solely for their - side effects, like print_endline, return value of "unit" type. *) + Every function must return something. So functions that do not + really return anything and are called solely for their side + effects, like print_endline, return a value of "unit" type. *) -(* Definitions can be chained with "let ... in" construct. - This is roughly the same to assigning values to multiple +(* Definitions can be chained with the "let ... in" construct. + This is roughly the same as assigning values to multiple variables before using them in expressions in imperative languages. *) let x = 10 in let y = 20 in x + y ;; -(* Alternatively you can use "let ... and ... in" construct. +(* Alternatively you can use the "let ... and ... in" construct. This is especially useful for mutually recursive functions, - with ordinary "let .. in" the compiler will complain about + with ordinary "let ... in" the compiler will complain about unbound values. *) let rec is_even = function @@ -186,9 +192,9 @@ let my_lambda = fun x -> x * x ;; ~-. 3.4 (* Float only *) (* You can define your own operators or redefine existing ones. - Unlike SML or Haskell, only selected symbols can be used - for operator names and first symbol defines associativity - and precedence rules. *) + Unlike Standard ML or Haskell, only certain symbols can be + used for operator names and the operator's first symbol determines + its associativity and precedence rules. *) let (+) a b = a - b ;; (* Surprise maintenance programmers. *) (* More useful: a reciprocal operator for floats. @@ -223,6 +229,10 @@ List.filter (fun x -> x mod 2 = 0) [1; 2; 3; 4] ;; often referred to as "cons". *) 1 :: [2; 3] ;; (* Gives [1; 2; 3] *) +(* Remember that the cons :: constructor can only cons a single item to the front + of a list. To combine two lists use the append @ operator *) +[1; 2] @ [3; 4] ;; (* Gives [1; 2; 3; 4] *) + (* Arrays are enclosed in [| |] *) let my_array = [| 1; 2; 3 |] ;; @@ -258,7 +268,7 @@ let ocaml = (String.make 1 'O') ^ "Caml" ;; (* There is a printf function. *) Printf.printf "%d %s" 99 "bottles of beer" ;; -(* Unformatted read and write functions are there too. *) +(* There's also unformatted read and write functions. *) print_string "hello world\n" ;; print_endline "hello world" ;; let line = read_line () ;; @@ -291,15 +301,59 @@ let my_point = Point (2.0, 3.0) ;; type 'a list_of_lists = 'a list list ;; type int_list_list = int list_of_lists ;; +(* These features allow for useful optional types *) +type 'a option = Some of 'a | None ;; +let x = Some x ;; +let y = None ;; + (* Types can also be recursive. Like in this type analogous to - built-in list of integers. *) + a built-in list of integers. *) type my_int_list = EmptyList | IntList of int * my_int_list ;; let l = IntList (1, EmptyList) ;; +(* or Trees *) +type 'a tree = + | Empty + | Node of 'a tree * 'a * 'a tree + +let example_tree: int tree = + Node ( + Node (Empty, 7, Empty), + 5, + Node (Empty, 9, Empty) + ) +(* + 5 + / \ + 7 9 +*) + +(*** Records ***) + +(* A collection of values with named fields *) + +type animal = + { + name: string; + color: string; + legs: int; + } +;; + +let cow = + { name: "cow"; + color: "black and white"; + legs: 4; + } +;; +val cow : animal + +cow.name ;; +- : string = "cow" (*** Pattern matching ***) -(* Pattern matching is somewhat similar to switch statement in imperative +(* Pattern matching is somewhat similar to the switch statement in imperative languages, but offers a lot more expressive power. Even though it may look complicated, it really boils down to matching @@ -311,7 +365,7 @@ let l = IntList (1, EmptyList) ;; let is_zero x = match x with | 0 -> true - | _ -> false (* The "_" pattern means "anything else". *) + | _ -> false (* The "_" means "anything else". *) ;; (* Alternatively, you can use the "function" keyword. *) @@ -342,6 +396,19 @@ let say x = say (Cat "Fluffy") ;; (* "Fluffy says meow". *) +(* However, pattern matching must be exhaustive *) +type color = Red | Blue | Green ;; +let what_color x = + match x with + | Red -> "color is red" + | Blue -> "color is blue" + (* Won't compile! You have to add a _ case or a Green case + to ensure all possibilities are accounted for *) +;; +(* Also, the match statement checks each case in order. + So, if a _ case appears first, none of the + following cases will be reached! *) + (** Traversing data structures with pattern matching **) (* Recursive types can be traversed with pattern matching easily. @@ -369,9 +436,75 @@ let rec sum_int_list l = let t = Cons (1, Cons (2, Cons (3, Nil))) ;; sum_int_list t ;; +(* Heres a function to tell if a list is sorted *) +let rec is_sorted l = + match l with + | x :: y :: tail -> x <= y && is_sorted (y :: tail) + | _ -> true +;; + +is_sorted [1; 2; 3] ;; (* True *) +(* OCaml's powerful type inference guesses that l is of type int list + since the <= operator is used on elements of l *) + +(* And another to reverse a list *) +let rec rev (l: 'a list) : 'a list = + match l with + | [] -> [] + | x::tl -> (rev tl) @ [x] +;; + +rev [1; 2; 3] ;; (* Gives [3; 2; 1] *) +(* This function works on lists of any element type *) + +(*** Higher Order Functions ***) + +(* Functions are first class in OCaml *) + +let rec transform (f: 'a -> 'b) (l: 'a list) : 'b list = + match l with + | [] -> [] + | head :: tail -> (f head) :: transform f tail +;; + +transform (fun x -> x + 1) [1; 2; 3] ;; (* Gives [2; 3; 4] *) + +(** Lets combine everything we learned! **) +let rec filter (pred: 'a -> bool) (l: 'a list) : 'a list = + begin match l with + | [] -> [] + | x :: xs -> + let rest = filter pred xs in + if pred x then x :: rest else rest + end +;; + +filter (fun x -> x < 4) [3; 1; 4; 1; 5] ;; (* Gives [3; 1; 1]) *) + +(*** Mutability ***) + +(* Records and variables are immutable: you cannot change where a variable points to *) + +(* However, you can create mutable polymorphic fields *) +type counter = { mutable num : int } ;; + +let c = { num: 0 } ;; +c.num ;; (* Gives 0 *) +c.num <- 1 ;; (* <- operator can set mutable record fields *) +c.num ;; (* Gives 1 *) + +(* OCaml's standard library provides a ref type to make single field mutability easier *) +type 'a ref = { mutable contents : 'a } ;; +let counter = ref 0 ;; +!counter ;; (* ! operator returns x.contents *) +counter := !counter + 1 ;; (* := can be used to set contents *) ``` ## Further reading -* Visit the official website to get the compiler and read the docs: <http://ocaml.org/> -* Try interactive tutorials and a web-based interpreter by OCaml Pro: <http://try.ocamlpro.com/> +* Visit the official website to get the compiler and read the docs: [http://ocaml.org/](http://ocaml.org/) +* Quick tutorial on OCaml: [https://ocaml.org/docs/up-and-running](https://ocaml.org/docs/up-and-running) +* Complete online OCaml v5 playground: [https://ocaml.org/play](https://ocaml.org/play) +* An up-to-date (2022) book (with free online version) "Real World OCaml": [https://www.cambridge.org/core/books/real-world-ocaml-functional-programming-for-the-masses/052E4BCCB09D56A0FE875DD81B1ED571](https://www.cambridge.org/core/books/real-world-ocaml-functional-programming-for-the-masses/052E4BCCB09D56A0FE875DD81B1ED571) +* Online interactive textbook "OCaml Programming: Correct + Efficient + Beautiful" from Cornell University: [https://cs3110.github.io/textbook/cover.html](https://cs3110.github.io/textbook/cover.html) +* Try interactive tutorials and a web-based interpreter by OCaml Pro: [http://try.ocamlpro.com/](http://try.ocamlpro.com/) diff --git a/opencv.html.markdown b/opencv.html.markdown index 5d860eca..b083feb8 100644 --- a/opencv.html.markdown +++ b/opencv.html.markdown @@ -114,13 +114,15 @@ eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') img = cv2.imread('human.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) -aces = face_cascade.detectMultiScale(gray, 1.3, 5) +faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: + # Draw a rectangle around detected face cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex,ey,ew,eh) in eyes: + # Draw a rectangle around detected eyes cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2) cv2.imshow('img',img) diff --git a/opengl.html.markdown b/opengl.html.markdown index 993402f7..f6a9085f 100644 --- a/opengl.html.markdown +++ b/opengl.html.markdown @@ -1,765 +1,765 @@ ----
-category: tool
-tool: OpenGL
-filename: learnopengl.cpp
-contributors:
- - ["Simon Deitermann", "s.f.deitermann@t-online.de"]
----
-
-**Open Graphics Library** (**OpenGL**) is a cross-language cross-platform application programming interface
-(API) for rendering 2D computer graphics and 3D vector graphics.<sup>[1]</sup> In this tutorial we will be
-focusing on modern OpenGL from 3.3 and above, ignoring "immediate-mode", Displaylists and
-VBO's without use of Shaders.
-I will be using C++ with SFML for window, image and context creation aswell as GLEW
-for modern OpenGL extensions, though there are many other librarys available.
-
-```cpp
-// Creating an SFML window and OpenGL basic setup.
-#include <GL/glew.h>
-#include <GL/gl.h>
-#include <SFML/Graphics.h>
-#include <iostream>
-
-int main() {
- // First we tell SFML how to setup our OpenGL context.
- sf::ContextSettings context{ 24, // depth buffer bits
- 8, // stencil buffer bits
- 4, // MSAA samples
- 3, // major opengl version
- 3 }; // minor opengl version
- // Now we create the window, enable VSync
- // and set the window active for OpenGL.
- sf::Window window{ sf::VideoMode{ 1024, 768 },
- "opengl window",
- sf::Style::Default,
- context };
- window.setVerticalSyncEnabled(true);
- window.setActive(true);
- // After that we initialise GLEW and check if an error occurred.
- GLenum error;
- glewExperimental = GL_TRUE;
- if ((err = glewInit()) != GLEW_OK)
- std::cout << glewGetErrorString(err) << std::endl;
- // Here we set the color glClear will clear the buffers with.
- glClearColor(0.0f, // red
- 0.0f, // green
- 0.0f, // blue
- 1.0f); // alpha
- // Now we can start the event loop, poll for events and draw objects.
- sf::Event event{ };
- while (window.isOpen()) {
- while (window.pollEvent(event)) {
- if (event.type == sf::Event::Closed)
- window.close;
- }
- // Tell OpenGL to clear the color buffer
- // and the depth buffer, this will clear our window.
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Flip front- and backbuffer.
- window.display();
- }
- return 0;
-}
-```
-
-## Loading Shaders
-
-After creating a window and our event loop we should create a function,
-that sets up our shader program.
-
-```cpp
-GLuint createShaderProgram(const std::string& vertexShaderPath,
- const std::string& fragmentShaderPath) {
- // Load the vertex shader source.
- std::stringstream ss{ };
- std::string vertexShaderSource{ };
- std::string fragmentShaderSource{ };
- std::ifstream file{ vertexShaderPath };
- if (file.is_open()) {
- ss << file.rdbuf();
- vertexShaderSource = ss.str();
- file.close();
- }
- // Clear the stringstream and load the fragment shader source.
- ss.str(std::string{ });
- file.open(fragmentShaderPath);
- if (file.is_open()) {
- ss << file.rdbuf();
- fragmentShaderSource = ss.str();
- file.close();
- }
- // Create the program.
- GLuint program = glCreateProgram();
- // Create the shaders.
- GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
- GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- // Now we can load the shader source into the shader objects and compile them.
- // Because glShaderSource() wants a const char* const*,
- // we must first create a const char* and then pass the reference.
- const char* cVertexSource = vertexShaderSource.c_str();
- glShaderSource(vertexShader, // shader
- 1, // number of strings
- &cVertexSource, // strings
- nullptr); // length of strings (nullptr for 1)
- glCompileShader(vertexShader);
- // Now we have to do the same for the fragment shader.
- const char* cFragmentSource = fragmentShaderSource.c_str();
- glShaderSource(fragmentShader, 1, &cFragmentSource, nullptr);
- glCompileShader(fragmentShader);
- // After attaching the source and compiling the shaders,
- // we attach them to the program;
- glAttachShader(program, vertexShader);
- glAttachShader(program, fragmentShader);
- glLinkProgram(program);
- // After linking the shaders we should detach and delete
- // them to prevent memory leak.
- glDetachShader(program, vertexShader);
- glDetachShader(program, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- // With everything done we can return the completed program.
- return program;
-}
-```
-
-If you want to check the compilation log you can add the following between <code>glCompileShader()</code> and <code>glAttachShader()</code>.
-
-```cpp
-GLint logSize = 0;
-std::vector<GLchar> logText{ };
-glGetShaderiv(vertexShader, // shader
- GL_INFO_LOG_LENGTH, // requested parameter
- &logSize); // return object
-if (logSize > 0) {
- logText.resize(logSize);
- glGetShaderInfoLog(vertexShader, // shader
- logSize, // buffer length
- &logSize, // returned length
- logText.data()); // buffer
- std::cout << logText.data() << std::endl;
-}
-```
-
-The same is possible after <code>glLinkProgram()</code>, just replace <code>glGetShaderiv()</code> with <code>glGetProgramiv()</code>
-and <code>glGetShaderInfoLog()</code> with <code>glGetProgramInfoLog()</code>.
-
-```cpp
-// Now we can create a shader program with a vertex and a fragment shader.
-// ...
-glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-
-GLuint program = createShaderProgram("vertex.glsl", "fragment.glsl");
-
-sf::Event event{ };
-// ...
-// We also have to delete the program at the end of the application.
-// ...
- }
- glDeleteProgram(program);
- return 0;
-}
-// ...
-```
-
-Ofcourse we have to create the vertex and fragment shader before we can load them,
-so lets create two basic shaders.
-
-**Vertex Shader**
-
-```glsl
-// Declare which version of GLSL we use.
-// Here we declare, that we want to use the OpenGL 3.3 version of GLSL.
-#version 330 core
-// At attribute location 0 we want an input variable of type vec3,
-// that contains the position of the vertex.
-// Setting the location is optional, if you don't set it you can ask for the
-// location with glGetAttribLocation().
-layout(location = 0) in vec3 position;
-// Every shader starts in it's main function.
-void main() {
- // gl_Position is a predefined variable that holds
- // the final vertex position.
- // It consists of a x, y, z and w coordinate.
- gl_Position = vec4(position, 1.0);
-}
-```
-
-**Fragment Shader**
-
-```glsl
-#version 330 core
-// The fragment shader does not have a predefined variable for
-// the vertex color, so we have to define a output vec4,
-// that holds the final vertex color.
-out vec4 outColor;
-
-void main() {
- // We simply set the output color to red.
- // The parameters are red, green, blue and alpha.
- outColor = vec4(1.0, 0.0, 0.0, 1.0);
-}
-```
-
-## VAO and VBO
-Now we need to define some vertex position we can pass to our shaders. Lets define a simple 2D quad.
-
-```cpp
-// The vertex data is defined in a counter-clockwise way,
-// as this is the default front face.
-std::vector<float> vertexData {
- -0.5f, 0.5f, 0.0f,
- -0.5f, -0.5f, 0.0f,
- 0.5f, -0.5f, 0.0f,
- 0.5f, 0.5f, 0.0f
-};
-// If you want to use a clockwise definition, you can simply call
-glFrontFace(GL_CW);
-// Next we need to define a Vertex Array Object (VAO).
-// The VAO stores the current state while its active.
-GLuint vao = 0;
-glGenVertexArrays(1, &vao);
-glBindVertexArray(vao);
-// With the VAO active we can now create a Vertex Buffer Object (VBO).
-// The VBO stores our vertex data.
-GLuint vbo = 0;
-glGenBuffers(1, &vbo);
-glBindBuffer(GL_ARRAY_BUFFER, vbo);
-// For reading and copying there are also GL_*_READ and GL_*_COPY,
-// if your data changes more often use GL_DYNAMIC_* or GL_STREAM_*.
-glBufferData(GL_ARRAY_BUFFER, // target buffer
- sizeof(vertexData[0]) * vertexData.size(), // size
- vertexData.data(), // data
- GL_STATIC_DRAW); // usage
-// After filling the VBO link it to the location 0 in our vertex shader,
-// which holds the vertex position.
-// ...
-// To ask for the attribute location, if you haven't set it:
-GLint posLocation = glGetAttribLocation(program, "position");
-// ..
-glEnableVertexAttribArray(0);
-glVertexAttribPointer(0, 3, // location and size
- GL_FLOAT, // type of data
- GL_FALSE, // normalized (always false for floats)
- 0, // stride (interleaved arrays)
- nullptr); // offset (interleaved arrays)
-// Everything should now be saved in our VAO and we can unbind it and the VBO.
-glBindVertexArray(0);
-glBindBuffer(GL_ARRAY_BUFFER, 0);
-// Now we can draw the vertex data in our render loop.
-// ...
-glClear(GL_COLOR_BUFFER_BIT);
-// Tell OpenGL we want to use our shader program.
-glUseProgram(program);
-// Binding the VAO loads the data we need.
-glBindVertexArray(vao);
-// We want to draw a quad starting at index 0 of the VBO using 4 indices.
-glDrawArrays(GL_QUADS, 0, 4);
-glBindVertexArray(0);
-window.display();
-// ...
-// Ofcource we have to delete the allocated memory for the VAO and VBO at
-// the end of our application.
-// ...
-glDeleteBuffers(1, &vbo);
-glDeleteVertexArrays(1, &vao);
-glDeleteProgram(program);
-return 0;
-// ...
-```
-
-You can find the current code here: [OpenGL - 1](https://pastebin.com/W8jdmVHD).
-
-## More VBO's and Color
-Let's create another VBO for some colors.
-
-```cpp
-std::vector<float> colorData {
- 1.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 0.0f
-};
-```
-
-Next we can simply change some previous parameters to create a second VBO for our colors.
-
-```cpp
-// ...
-GLuint vbo[2];
-glGenBuffers(2, vbo);
-glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
-// ...
-glDeleteBuffers(2, vbo);
-/ ...
-// With these changes made we now have to load our color data into the new VBO
-// ...
-glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
-
-glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
-glBufferData(GL_ARRAY_BUFFER, sizeof(colorData[0]) * colorData.size(),
- colorData.data(), GL_STATIC_DRAW);
-glEnableVertexAttribArray(1);
-glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
-
-glBindVertexArray(0);
-// ...
-```
-
-Next we have to change our vertex shader to pass the color data to the fragment shader.<br>
-**Vertex Shader**
-
-```glsl
-#version 330 core
-
-layout(location = 0) in vec3 position;
-// The new location has to differ from any other input variable.
-// It is the same index we need to pass to
-// glEnableVertexAttribArray() and glVertexAttribPointer().
-layout(location = 1) in vec3 color;
-
-out vec3 fColor;
-
-void main() {
- fColor = color;
- gl_Position = vec4(position, 1.0);
-}
-```
-
-**Fragment Shader**
-
-```glsl
-#version 330 core
-
-in vec3 fColor;
-
-out vec4 outColor;
-
-void main() {
- outColor = vec4(fColor, 1.0);
-}
-```
-
-We define a new input variable ```color``` which represents our color data, this data
-is passed on to ```fColor```, which is an output variable of our vertex shader and
-becomes an input variable for our fragment shader.
-It is imporatant that variables passed between shaders have the exact same name
-and type.
-
-## Handling VBO's
-
-```cpp
-// If you want to completely clear and refill a VBO use glBufferData(),
-// just like we did before.
-// ...
-// There are two mains ways to update a subset of a VBO's data.
-// To update a VBO with existing data
-std::vector<float> newSubData {
- -0.25f, 0.5f, 0.0f
-};
-glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
-glBufferSubData(GL_ARRAY_BUFFER, // target buffer
- 0, // offset
- sizeof(newSubData[0]) * newSubData.size(), // size
- newSubData.data()); // data
-// This would update the first three values in our vbo[0] buffer.
-// If you want to update starting at a specific location just set the second
-// parameter to that value and multiply by the types size.
-// ...
-// If you are streaming data, for example from a file,
-// it is faster to directly pass the data to the buffer.
-// Other access values are GL_READ_ONLY and GL_READ_WRITE.
-glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
-// You can static_cast<float*>() the void* to be more safe.
-void* Ptr = glMapBuffer(GL_ARRAY_BUFFER, // buffer to map
- GL_WRITE_ONLY); // access to buffer
-memcpy(Ptr, newSubData.data(), sizeof(newSubData[0]) * newSubData.size());
-// To copy to a specific location add a destination offset to memcpy().
-glUnmapBuffer(GL_ARRAY_BUFFER);
-// ...
-// There is also a way to copy data from one buffer to another,
-// If we have two VBO's vbo[0] and vbo[1], we can copy like so
-// You can also read from GL_ARRAY_BUFFER.
-glBindBuffer(GL_COPY_READ_BUFFER, vbo[0]);
-// GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are specifically for
-// copying buffer data.
-glBindBuffer(GL_COPY_WRITE_BUFFER, vbo[1]);
-glCopyBufferSubData(GL_COPY_READ_BUFFER, // read buffer
- GL_COPY_WRITE_BUFFER, // write buffer
- 0, 0, // read and write offset
- sizeof(vbo[0]) * 3); // copy size
-// This will copy the first three elements from vbo[0] to vbo[1].
-```
-
-## Uniforms
-
-**Fragment Shader**
-
-```glsl
-// Uniforms are variables like in and out, however,
-// we can change them easily by passing new values with glUniform().
-// Lets define a time variable in our fragment shader.
-#version 330 core
-// Unlike a in/out variable we can use a uniform in every shader,
-// without the need to pass it to the next one, they are global.
-// Don't use locations already used for attributes!
-// Uniform layout locations require OpenGL 4.3!
-layout(location = 10) uniform float time;
-
-in vec3 fColor;
-
-out vec4 outColor;
-
-void main() {
- // Create a sine wave from 0 to 1 based on the time passed to the shader.
- float factor = (sin(time * 2) + 1) / 2;
- outColor = vec4(fColor.r * factor, fColor.g * factor, fColor.b * factor, 1.0);
-}
-```
-
-Back to our source code.
-
-```cpp
-// If we haven't set the layout location, we can ask for it.
-GLint timeLocation = glGetUniformLocation(program, "time");
-// ...
-// Also we should define a Timer counting the current time.
-sf::Clock clock{ };
-// In out render loop we can now update the uniform every frame.
- // ...
- window.display();
- glUniform1f(10, // location
- clock.getElapsedTime().asSeconds()); // data
-}
-// ...
-```
-
-With the time getting updated every frame the quad should now be changing from
-fully colored to pitch black.
-There are different types of glUniform() you can find simple documentation here:
-[glUniform - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniform.xhtml)
-
-## Indexing and IBO's
-
-Element Array Buffers or more commonly Index Buffer Objects (IBO) allow us to use the
-same vertex data again which makes drawing a lot easier and faster. here's an example:
-
-```cpp
-// Lets create a quad from two rectangles.
-// We can simply use the old vertex data from before.
-// First, we have to create the IBO.
-// The index is referring to the first declaration in the VBO.
-std::vector<unsigned int> iboData {
- 0, 1, 2,
- 0, 2, 3
-};
-// That's it, as you can see we could reuse 0 - the top left
-// and 2 - the bottom right.
-// Now that we have our data, we have to fill it into a buffer.
-// Note that this has to happen between the two glBindVertexArray() calls,
-// so it gets saved into the VAO.
-GLuint ibo = 0;
-glGenBufferrs(1, &ibo);
-glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
-glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iboData[0]) * iboData.size(),
- iboData.data(), GL_STATIC_DRAW);
-// Next in our render loop, we replace glDrawArrays() with:
-glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr);
-// Remember to delete the allocated memory for the IBO.
-```
-
-You can find the current code here: [OpenGL - 2](https://pastebin.com/R3Z9ACDE).
-
-## Textures
-
-To load out texture we first need a library that loads the data, for simplicity I will be
-using SFML, however there are a lot of librarys for loading image data.
-
-```cpp
-// Lets save we have a texture called "my_tex.tga", we can load it with:
-sf::Image image;
-image.loadFromFile("my_tex.tga");
-// We have to flip the texture around the y-Axis, because OpenGL's texture
-// origin is the bottom left corner, not the top left.
-image.flipVertically();
-// After loading it we have to create a OpenGL texture.
-GLuint texture = 0;
-glGenTextures(1, &texture);
-glBindTexture(GL_TEXTURE_2D, texture);
-// Specify what happens when the coordinates are out of range.
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-// Specify the filtering if the object is very large.
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-// Load the image data to the texture.
-glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
-// Unbind the texture to prevent modifications.
-glBindTexture(GL_TEXTURE_2D, 0);
-// Delete the texture at the end of the application.
-// ...
-glDeleteTextures(1, &texture);
-```
-
-Ofcourse there are more texture formats than only 2D textures,
-You can find further information on parameters here:
-[glBindTexture - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindTexture.xhtml)<br>
-[glTexImage2D - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml)<br>
-[glTexParameter - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexParameter.xhtml)<br>
-
-```cpp
-// With the texture created, we now have to specify the UV,
-// or in OpenGL terms ST coordinates.
-std::vector<float> texCoords {
- // The texture coordinates have to match the triangles/quad
- // definition.
- 0.0f, 1.0f, // start at top-left
- 0.0f, 0.0f, // go round counter-clockwise
- 1.0f, 0.0f,
- 1.0f, 1.0f // end at top-right
-};
-// Now we increase the VBO's size again just like we did for the colors.
-// ...
-GLuint vbo[3];
-glGenBuffers(3, vbo);
-// ...
-glDeleteBuffers(3, vbo);
-// ...
-// Load the texture coordinates into the new buffer.
-glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
-glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords[0]) * texCoords.size(),
- texCoords.data(), GL_STATIC_DRAW);
-glEnableVertexAttribArray(2);
-glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
-// Because the VAO does not store the texture we have to bind it before drawing.
-// ...
-glBindVertexArray(vao);
-glBindTexture(GL_TEXTURE_2D, texture);
-glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr);
-// ...
-```
-
-Change the shaders to pass the data to the fragment shader.<br>
-
-**Vertex Shader**
-
-```glsl
-#version 330 core
-
-layout(location = 0) in vec3 position;
-layout(location = 1) in vec3 color;
-layout(location = 2) in vec2 texCoords;
-
-out vec3 fColor;
-out vec2 fTexCoords;
-
-void main() {
- fColor = color;
- fTexCoords = texCoords;
- gl_Position = vec4(position, 1.0);
-}
-```
-
-**Fragment Shader**
-
-```glsl
-#version 330 core
-// sampler2D represents our 2D texture.
-uniform sampler2D tex;
-uniform float time;
-
-in vec3 fColor;
-in vec2 fTexCoords;
-
-out vec4 outColor;
-
-void main() {
- // texture() loads the current texure data at the specified texture coords,
- // then we can simply multiply them by our color.
- outColor = texture(tex, fTexCoords) * vec4(fColor, 1.0);
-}
-```
-
-You can find the current code here: [OpenGL - 3](https://pastebin.com/u3bcwM6q)
-
-## Matrix Transformation
-
-**Vertex Shader**
-
-```glsl
-#version 330 core
-
-layout(location = 0) in vec3 position;
-layout(location = 1) in vec3 color;
-layout(location = 2) in vec2 texCoords;
-// Create 2 4x4 matricies, 1 for the projection matrix
-// and 1 for the model matrix.
-// Because we draw in a static scene, we don't need a view matrix.
-uniform mat4 projection;
-uniform mat4 model;
-
-out vec3 fColor;
-out vec2 fTexCoords;
-
-void main() {
- fColor = color;
- fTexCoords = texCoords;
- // Multiplay the position by the model matrix and then by the
- // projection matrix.
- // Beware order of multiplication for matricies!
- gl_Position = projection * model * vec4(position, 1.0);
-}
-```
-
-In our source we now need to change the vertex data, create a model- and a projection matrix.
-
-```cpp
-// The new vertex data, counter-clockwise declaration.
-std::vector<float> vertexData {
- 0.0f, 1.0f, 0.0f, // top left
- 0.0f, 0.0f, 0.0f, // bottom left
- 1.0f, 0.0f, 0.0f, // bottom right
- 1.0f, 1.0f, 0.0f // top right
-};
-// Request the location of our matricies.
-GLint projectionLocation = glGetUniformLocation(program, "projection");
-GLint modelLocation = glGetUniformLocation(program, "model");
-// Declaring the matricies.
-// Orthogonal matrix for a 1024x768 window.
-std::vector<float> projection {
- 0.001953f, 0.0f, 0.0f, 0.0f,
- 0.0f, -0.002604f, 0.0f, 0.0f,
- 0.0f, 0.0f, -1.0f, 0.0f,
- -1.0f, 1.0f, 0.0f, 1.0f
-};
-// Model matrix translating to x 50, y 50
-// and scaling to x 200, y 200.
-std::vector<float> model {
- 200.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 200.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 50.0f, 50.0f, 0.0f, 1.0f
-};
-// Now we can send our calculated matricies to the program.
-glUseProgram(program);
-glUniformMatrix4fv(projectionLocation, // location
- 1, // count
- GL_FALSE, // transpose the matrix
- projection.data()); // data
-glUniformMatrix4fv(modelLocation, 1, GL_FALSE, model.data());
-glUseProgram(0);
-// The glUniform*() calls have to be done, while the program is bound.
-```
-
-The application should now display the texture at the defined position and size.<br>
-You can find the current code here: [OpenGL - 4](https://pastebin.com/9ahpFLkY)
-
-```cpp
-// There are many math librarys for OpenGL, which create
-// matricies and vectors, the most used in C++ is glm (OpenGL Mathematics).
-// Its a header only library.
-// The same code using glm would look like:
-glm::mat4 projection{ glm::ortho(0.0f, 1024.0f, 768.0f, 0.0f) };
-glUniformMatrix4fv(projectionLocation, 1, GL_FALSE,
- glm::value_ptr(projection));
-// Initialise the model matrix to the identity matrix, otherwise every
-// multiplication would be 0.
-glm::mat4 model{ 1.0f };
-model = glm::translate(model, glm::vec3{ 50.0f, 50.0f, 0.0f });
-model = glm::scale(model, glm::vec3{ 200.0f, 200.0f, 0.0f });
-glUniformMatrix4fv(modelLocation, 1, GL_FALSE,
- glm::value_ptr(model));
-```
-
-## Geometry Shader
-
-Geometry shaders were introduced in OpenGL 3.2, they can produce vertices
-that are send to the rasterizer. They can also change the primitive type e.g.
-they can take a point as an input and output other primitives.
-Geometry shaders are inbetween the vertex and the fragment shader.
-
-**Vertex Shader**
-
-```glsl
-#version 330 core
-
-layout(location = 0) in vec3 position;
-layout(location = 1) in vec3 color;
-// Create an output interface block passed to the next shadaer stage.
-// Interface blocks can be used to structure data passed between shaders.
-out VS_OUT {
- vec3 color;
-} vs_out;
-
-void main() {
- vs_out.color = color
- gl_Position = vec4(position, 1.0);
-}
-```
-
-**Geometry Shader**
-
-```glsl
-#version 330 core
-// The geometry shader takes in points.
-layout(points) in;
-// It outputs a triangle every 3 vertices emitted.
-layout(triangle_strip, max_vertices = 3) out;
-// VS_OUT becomes an input variable in the geometry shader.
-// Every input to the geometry shader in treated as an array.
-in VS_OUT {
- vec3 color;
-} gs_in[];
-// Output color for the fragment shader.
-// You can also simply define color as 'out vec3 color',
-// If you don't want to use interface blocks.
-out GS_OUT {
- vec3 color;
-} gs_out;
-
-void main() {
- // Each emit calls the fragment shader, so we set a color for each vertex.
- gs_out.color = mix(gs_in[0].color, vec3(1.0, 0.0, 0.0), 0.5);
- // Move 0.5 units to the left and emit the new vertex.
- // gl_in[] is the current vertex from the vertex shader, here we only
- // use 0, because we are receiving points.
- gl_Position = gl_in[0].gl_Position + vec4(-0.5, 0.0, 0.0, 0.0);
- EmitVertex();
- gs_out.color = mix(gs_in[0].color, vec3(0.0, 1.0, 0.0), 0.5);
- // Move 0.5 units to the right and emit the new vertex.
- gl_Position = gl_in[0].gl_Position + vec4(0.5, 0.0, 0.0, 0.0);
- EmitVertex();
- gs_out.color = mix(gs_in[0].color, vec3(0.0, 0.0, 1.0), 0.5);
- // Move 0.5 units up and emit the new vertex.
- gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.75, 0.0, 0.0);
- EmitVertex();
- EndPrimitive();
-}
-```
-
-**Fragment Shader**
-
-```glsl
-in GS_OUT {
- vec3 color;
-} fs_in;
-
-out vec4 outColor;
-
-void main() {
- outColor = vec4(fs_in.color, 1.0);
-}
-```
-
-If you now store a single point with a single color in a VBO and draw them,
-you should see a triangle, with your color mixed half way between
-red, green and blue on each vertex.
-
-
-## Quotes
-<sup>[1]</sup>[OpenGL - Wikipedia](https://en.wikipedia.org/wiki/OpenGL)
-
-## Books
-
-- OpenGL Superbible - Fifth Edition (covering OpenGL 3.3)
-- OpenGL Programming Guide - Eighth Edition (covering OpenGL 4.3)
+--- +category: tool +tool: OpenGL +filename: learnopengl.cpp +contributors: + - ["Simon Deitermann", "s.f.deitermann@t-online.de"] +--- + +**Open Graphics Library** (**OpenGL**) is a cross-language cross-platform application programming interface +(API) for rendering 2D computer graphics and 3D vector graphics.<sup>[1]</sup> In this tutorial we will be +focusing on modern OpenGL from 3.3 and above, ignoring "immediate-mode", Displaylists and +VBO's without use of Shaders. +I will be using C++ with SFML for window, image and context creation aswell as GLEW +for modern OpenGL extensions, though there are many other librarys available. + +```cpp +// Creating an SFML window and OpenGL basic setup. +#include <GL/glew.h> +#include <GL/gl.h> +#include <SFML/Graphics.h> +#include <iostream> + +int main() { + // First we tell SFML how to setup our OpenGL context. + sf::ContextSettings context{ 24, // depth buffer bits + 8, // stencil buffer bits + 4, // MSAA samples + 3, // major opengl version + 3 }; // minor opengl version + // Now we create the window, enable VSync + // and set the window active for OpenGL. + sf::Window window{ sf::VideoMode{ 1024, 768 }, + "opengl window", + sf::Style::Default, + context }; + window.setVerticalSyncEnabled(true); + window.setActive(true); + // After that we initialise GLEW and check if an error occurred. + GLenum error; + glewExperimental = GL_TRUE; + if ((err = glewInit()) != GLEW_OK) + std::cout << glewGetErrorString(err) << std::endl; + // Here we set the color glClear will clear the buffers with. + glClearColor(0.0f, // red + 0.0f, // green + 0.0f, // blue + 1.0f); // alpha + // Now we can start the event loop, poll for events and draw objects. + sf::Event event{ }; + while (window.isOpen()) { + while (window.pollEvent(event)) { + if (event.type == sf::Event::Closed) + window.close; + } + // Tell OpenGL to clear the color buffer + // and the depth buffer, this will clear our window. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Flip front- and backbuffer. + window.display(); + } + return 0; +} +``` + +## Loading Shaders + +After creating a window and our event loop we should create a function, +that sets up our shader program. + +```cpp +GLuint createShaderProgram(const std::string& vertexShaderPath, + const std::string& fragmentShaderPath) { + // Load the vertex shader source. + std::stringstream ss{ }; + std::string vertexShaderSource{ }; + std::string fragmentShaderSource{ }; + std::ifstream file{ vertexShaderPath }; + if (file.is_open()) { + ss << file.rdbuf(); + vertexShaderSource = ss.str(); + file.close(); + } + // Clear the stringstream and load the fragment shader source. + ss.str(std::string{ }); + file.open(fragmentShaderPath); + if (file.is_open()) { + ss << file.rdbuf(); + fragmentShaderSource = ss.str(); + file.close(); + } + // Create the program. + GLuint program = glCreateProgram(); + // Create the shaders. + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + // Now we can load the shader source into the shader objects and compile them. + // Because glShaderSource() wants a const char* const*, + // we must first create a const char* and then pass the reference. + const char* cVertexSource = vertexShaderSource.c_str(); + glShaderSource(vertexShader, // shader + 1, // number of strings + &cVertexSource, // strings + nullptr); // length of strings (nullptr for 1) + glCompileShader(vertexShader); + // Now we have to do the same for the fragment shader. + const char* cFragmentSource = fragmentShaderSource.c_str(); + glShaderSource(fragmentShader, 1, &cFragmentSource, nullptr); + glCompileShader(fragmentShader); + // After attaching the source and compiling the shaders, + // we attach them to the program; + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + // After linking the shaders we should detach and delete + // them to prevent memory leak. + glDetachShader(program, vertexShader); + glDetachShader(program, fragmentShader); + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + // With everything done we can return the completed program. + return program; +} +``` + +If you want to check the compilation log you can add the following between <code>glCompileShader()</code> and <code>glAttachShader()</code>. + +```cpp +GLint logSize = 0; +std::vector<GLchar> logText{ }; +glGetShaderiv(vertexShader, // shader + GL_INFO_LOG_LENGTH, // requested parameter + &logSize); // return object +if (logSize > 0) { + logText.resize(logSize); + glGetShaderInfoLog(vertexShader, // shader + logSize, // buffer length + &logSize, // returned length + logText.data()); // buffer + std::cout << logText.data() << std::endl; +} +``` + +The same is possible after <code>glLinkProgram()</code>, just replace <code>glGetShaderiv()</code> with <code>glGetProgramiv()</code> +and <code>glGetShaderInfoLog()</code> with <code>glGetProgramInfoLog()</code>. + +```cpp +// Now we can create a shader program with a vertex and a fragment shader. +// ... +glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + +GLuint program = createShaderProgram("vertex.glsl", "fragment.glsl"); + +sf::Event event{ }; +// ... +// We also have to delete the program at the end of the application. +// ... + } + glDeleteProgram(program); + return 0; +} +// ... +``` + +Ofcourse we have to create the vertex and fragment shader before we can load them, +so lets create two basic shaders. + +**Vertex Shader** + +```glsl +// Declare which version of GLSL we use. +// Here we declare, that we want to use the OpenGL 3.3 version of GLSL. +#version 330 core +// At attribute location 0 we want an input variable of type vec3, +// that contains the position of the vertex. +// Setting the location is optional, if you don't set it you can ask for the +// location with glGetAttribLocation(). +layout(location = 0) in vec3 position; +// Every shader starts in it's main function. +void main() { + // gl_Position is a predefined variable that holds + // the final vertex position. + // It consists of a x, y, z and w coordinate. + gl_Position = vec4(position, 1.0); +} +``` + +**Fragment Shader** + +```glsl +#version 330 core +// The fragment shader does not have a predefined variable for +// the vertex color, so we have to define a output vec4, +// that holds the final vertex color. +out vec4 outColor; + +void main() { + // We simply set the output color to red. + // The parameters are red, green, blue and alpha. + outColor = vec4(1.0, 0.0, 0.0, 1.0); +} +``` + +## VAO and VBO +Now we need to define some vertex position we can pass to our shaders. Lets define a simple 2D quad. + +```cpp +// The vertex data is defined in a counter-clockwise way, +// as this is the default front face. +std::vector<float> vertexData { + -0.5f, 0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.5f, 0.5f, 0.0f +}; +// If you want to use a clockwise definition, you can simply call +glFrontFace(GL_CW); +// Next we need to define a Vertex Array Object (VAO). +// The VAO stores the current state while its active. +GLuint vao = 0; +glGenVertexArrays(1, &vao); +glBindVertexArray(vao); +// With the VAO active we can now create a Vertex Buffer Object (VBO). +// The VBO stores our vertex data. +GLuint vbo = 0; +glGenBuffers(1, &vbo); +glBindBuffer(GL_ARRAY_BUFFER, vbo); +// For reading and copying there are also GL_*_READ and GL_*_COPY, +// if your data changes more often use GL_DYNAMIC_* or GL_STREAM_*. +glBufferData(GL_ARRAY_BUFFER, // target buffer + sizeof(vertexData[0]) * vertexData.size(), // size + vertexData.data(), // data + GL_STATIC_DRAW); // usage +// After filling the VBO link it to the location 0 in our vertex shader, +// which holds the vertex position. +// ... +// To ask for the attribute location, if you haven't set it: +GLint posLocation = glGetAttribLocation(program, "position"); +// .. +glEnableVertexAttribArray(0); +glVertexAttribPointer(0, 3, // location and size + GL_FLOAT, // type of data + GL_FALSE, // normalized (always false for floats) + 0, // stride (interleaved arrays) + nullptr); // offset (interleaved arrays) +// Everything should now be saved in our VAO and we can unbind it and the VBO. +glBindVertexArray(0); +glBindBuffer(GL_ARRAY_BUFFER, 0); +// Now we can draw the vertex data in our render loop. +// ... +glClear(GL_COLOR_BUFFER_BIT); +// Tell OpenGL we want to use our shader program. +glUseProgram(program); +// Binding the VAO loads the data we need. +glBindVertexArray(vao); +// We want to draw a quad starting at index 0 of the VBO using 4 indices. +glDrawArrays(GL_QUADS, 0, 4); +glBindVertexArray(0); +window.display(); +// ... +// Ofcource we have to delete the allocated memory for the VAO and VBO at +// the end of our application. +// ... +glDeleteBuffers(1, &vbo); +glDeleteVertexArrays(1, &vao); +glDeleteProgram(program); +return 0; +// ... +``` + +You can find the current code here: [OpenGL - 1](https://pastebin.com/W8jdmVHD). + +## More VBO's and Color +Let's create another VBO for some colors. + +```cpp +std::vector<float> colorData { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f +}; +``` + +Next we can simply change some previous parameters to create a second VBO for our colors. + +```cpp +// ... +GLuint vbo[2]; +glGenBuffers(2, vbo); +glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); +// ... +glDeleteBuffers(2, vbo); +/ ... +// With these changes made we now have to load our color data into the new VBO +// ... +glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + +glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); +glBufferData(GL_ARRAY_BUFFER, sizeof(colorData[0]) * colorData.size(), + colorData.data(), GL_STATIC_DRAW); +glEnableVertexAttribArray(1); +glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + +glBindVertexArray(0); +// ... +``` + +Next we have to change our vertex shader to pass the color data to the fragment shader.<br> +**Vertex Shader** + +```glsl +#version 330 core + +layout(location = 0) in vec3 position; +// The new location has to differ from any other input variable. +// It is the same index we need to pass to +// glEnableVertexAttribArray() and glVertexAttribPointer(). +layout(location = 1) in vec3 color; + +out vec3 fColor; + +void main() { + fColor = color; + gl_Position = vec4(position, 1.0); +} +``` + +**Fragment Shader** + +```glsl +#version 330 core + +in vec3 fColor; + +out vec4 outColor; + +void main() { + outColor = vec4(fColor, 1.0); +} +``` + +We define a new input variable ```color``` which represents our color data, this data +is passed on to ```fColor```, which is an output variable of our vertex shader and +becomes an input variable for our fragment shader. +It is imporatant that variables passed between shaders have the exact same name +and type. + +## Handling VBO's + +```cpp +// If you want to completely clear and refill a VBO use glBufferData(), +// just like we did before. +// ... +// There are two mains ways to update a subset of a VBO's data. +// To update a VBO with existing data +std::vector<float> newSubData { + -0.25f, 0.5f, 0.0f +}; +glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); +glBufferSubData(GL_ARRAY_BUFFER, // target buffer + 0, // offset + sizeof(newSubData[0]) * newSubData.size(), // size + newSubData.data()); // data +// This would update the first three values in our vbo[0] buffer. +// If you want to update starting at a specific location just set the second +// parameter to that value and multiply by the types size. +// ... +// If you are streaming data, for example from a file, +// it is faster to directly pass the data to the buffer. +// Other access values are GL_READ_ONLY and GL_READ_WRITE. +glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); +// You can static_cast<float*>() the void* to be more safe. +void* Ptr = glMapBuffer(GL_ARRAY_BUFFER, // buffer to map + GL_WRITE_ONLY); // access to buffer +memcpy(Ptr, newSubData.data(), sizeof(newSubData[0]) * newSubData.size()); +// To copy to a specific location add a destination offset to memcpy(). +glUnmapBuffer(GL_ARRAY_BUFFER); +// ... +// There is also a way to copy data from one buffer to another, +// If we have two VBO's vbo[0] and vbo[1], we can copy like so +// You can also read from GL_ARRAY_BUFFER. +glBindBuffer(GL_COPY_READ_BUFFER, vbo[0]); +// GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are specifically for +// copying buffer data. +glBindBuffer(GL_COPY_WRITE_BUFFER, vbo[1]); +glCopyBufferSubData(GL_COPY_READ_BUFFER, // read buffer + GL_COPY_WRITE_BUFFER, // write buffer + 0, 0, // read and write offset + sizeof(vbo[0]) * 3); // copy size +// This will copy the first three elements from vbo[0] to vbo[1]. +``` + +## Uniforms + +**Fragment Shader** + +```glsl +// Uniforms are variables like in and out, however, +// we can change them easily by passing new values with glUniform(). +// Lets define a time variable in our fragment shader. +#version 330 core +// Unlike a in/out variable we can use a uniform in every shader, +// without the need to pass it to the next one, they are global. +// Don't use locations already used for attributes! +// Uniform layout locations require OpenGL 4.3! +layout(location = 10) uniform float time; + +in vec3 fColor; + +out vec4 outColor; + +void main() { + // Create a sine wave from 0 to 1 based on the time passed to the shader. + float factor = (sin(time * 2) + 1) / 2; + outColor = vec4(fColor.r * factor, fColor.g * factor, fColor.b * factor, 1.0); +} +``` + +Back to our source code. + +```cpp +// If we haven't set the layout location, we can ask for it. +GLint timeLocation = glGetUniformLocation(program, "time"); +// ... +// Also we should define a Timer counting the current time. +sf::Clock clock{ }; +// In out render loop we can now update the uniform every frame. + // ... + window.display(); + glUniform1f(10, // location + clock.getElapsedTime().asSeconds()); // data +} +// ... +``` + +With the time getting updated every frame the quad should now be changing from +fully colored to pitch black. +There are different types of glUniform() you can find simple documentation here: +[glUniform - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniform.xhtml) + +## Indexing and IBO's + +Element Array Buffers or more commonly Index Buffer Objects (IBO) allow us to use the +same vertex data again which makes drawing a lot easier and faster. here's an example: + +```cpp +// Lets create a quad from two rectangles. +// We can simply use the old vertex data from before. +// First, we have to create the IBO. +// The index is referring to the first declaration in the VBO. +std::vector<unsigned int> iboData { + 0, 1, 2, + 0, 2, 3 +}; +// That's it, as you can see we could reuse 0 - the top left +// and 2 - the bottom right. +// Now that we have our data, we have to fill it into a buffer. +// Note that this has to happen between the two glBindVertexArray() calls, +// so it gets saved into the VAO. +GLuint ibo = 0; +glGenBufferrs(1, &ibo); +glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); +glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iboData[0]) * iboData.size(), + iboData.data(), GL_STATIC_DRAW); +// Next in our render loop, we replace glDrawArrays() with: +glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr); +// Remember to delete the allocated memory for the IBO. +``` + +You can find the current code here: [OpenGL - 2](https://pastebin.com/R3Z9ACDE). + +## Textures + +To load out texture we first need a library that loads the data, for simplicity I will be +using SFML, however there are a lot of librarys for loading image data. + +```cpp +// Lets save we have a texture called "my_tex.tga", we can load it with: +sf::Image image; +image.loadFromFile("my_tex.tga"); +// We have to flip the texture around the y-Axis, because OpenGL's texture +// origin is the bottom left corner, not the top left. +image.flipVertically(); +// After loading it we have to create a OpenGL texture. +GLuint texture = 0; +glGenTextures(1, &texture); +glBindTexture(GL_TEXTURE_2D, texture); +// Specify what happens when the coordinates are out of range. +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +// Specify the filtering if the object is very large. +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// Load the image data to the texture. +glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, + 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr()); +// Unbind the texture to prevent modifications. +glBindTexture(GL_TEXTURE_2D, 0); +// Delete the texture at the end of the application. +// ... +glDeleteTextures(1, &texture); +``` + +Ofcourse there are more texture formats than only 2D textures, +You can find further information on parameters here: +[glBindTexture - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindTexture.xhtml)<br> +[glTexImage2D - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml)<br> +[glTexParameter - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexParameter.xhtml)<br> + +```cpp +// With the texture created, we now have to specify the UV, +// or in OpenGL terms ST coordinates. +std::vector<float> texCoords { + // The texture coordinates have to match the triangles/quad + // definition. + 0.0f, 1.0f, // start at top-left + 0.0f, 0.0f, // go round counter-clockwise + 1.0f, 0.0f, + 1.0f, 1.0f // end at top-right +}; +// Now we increase the VBO's size again just like we did for the colors. +// ... +GLuint vbo[3]; +glGenBuffers(3, vbo); +// ... +glDeleteBuffers(3, vbo); +// ... +// Load the texture coordinates into the new buffer. +glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); +glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords[0]) * texCoords.size(), + texCoords.data(), GL_STATIC_DRAW); +glEnableVertexAttribArray(2); +glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr); +// Because the VAO does not store the texture we have to bind it before drawing. +// ... +glBindVertexArray(vao); +glBindTexture(GL_TEXTURE_2D, texture); +glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr); +// ... +``` + +Change the shaders to pass the data to the fragment shader.<br> + +**Vertex Shader** + +```glsl +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 color; +layout(location = 2) in vec2 texCoords; + +out vec3 fColor; +out vec2 fTexCoords; + +void main() { + fColor = color; + fTexCoords = texCoords; + gl_Position = vec4(position, 1.0); +} +``` + +**Fragment Shader** + +```glsl +#version 330 core +// sampler2D represents our 2D texture. +uniform sampler2D tex; +uniform float time; + +in vec3 fColor; +in vec2 fTexCoords; + +out vec4 outColor; + +void main() { + // texture() loads the current texure data at the specified texture coords, + // then we can simply multiply them by our color. + outColor = texture(tex, fTexCoords) * vec4(fColor, 1.0); +} +``` + +You can find the current code here: [OpenGL - 3](https://pastebin.com/u3bcwM6q) + +## Matrix Transformation + +**Vertex Shader** + +```glsl +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 color; +layout(location = 2) in vec2 texCoords; +// Create 2 4x4 matricies, 1 for the projection matrix +// and 1 for the model matrix. +// Because we draw in a static scene, we don't need a view matrix. +uniform mat4 projection; +uniform mat4 model; + +out vec3 fColor; +out vec2 fTexCoords; + +void main() { + fColor = color; + fTexCoords = texCoords; + // Multiplay the position by the model matrix and then by the + // projection matrix. + // Beware order of multiplication for matricies! + gl_Position = projection * model * vec4(position, 1.0); +} +``` + +In our source we now need to change the vertex data, create a model- and a projection matrix. + +```cpp +// The new vertex data, counter-clockwise declaration. +std::vector<float> vertexData { + 0.0f, 1.0f, 0.0f, // top left + 0.0f, 0.0f, 0.0f, // bottom left + 1.0f, 0.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right +}; +// Request the location of our matricies. +GLint projectionLocation = glGetUniformLocation(program, "projection"); +GLint modelLocation = glGetUniformLocation(program, "model"); +// Declaring the matricies. +// Orthogonal matrix for a 1024x768 window. +std::vector<float> projection { + 0.001953f, 0.0f, 0.0f, 0.0f, + 0.0f, -0.002604f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f +}; +// Model matrix translating to x 50, y 50 +// and scaling to x 200, y 200. +std::vector<float> model { + 200.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 200.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 50.0f, 50.0f, 0.0f, 1.0f +}; +// Now we can send our calculated matricies to the program. +glUseProgram(program); +glUniformMatrix4fv(projectionLocation, // location + 1, // count + GL_FALSE, // transpose the matrix + projection.data()); // data +glUniformMatrix4fv(modelLocation, 1, GL_FALSE, model.data()); +glUseProgram(0); +// The glUniform*() calls have to be done, while the program is bound. +``` + +The application should now display the texture at the defined position and size.<br> +You can find the current code here: [OpenGL - 4](https://pastebin.com/9ahpFLkY) + +```cpp +// There are many math librarys for OpenGL, which create +// matricies and vectors, the most used in C++ is glm (OpenGL Mathematics). +// Its a header only library. +// The same code using glm would look like: +glm::mat4 projection{ glm::ortho(0.0f, 1024.0f, 768.0f, 0.0f) }; +glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, + glm::value_ptr(projection)); +// Initialise the model matrix to the identity matrix, otherwise every +// multiplication would be 0. +glm::mat4 model{ 1.0f }; +model = glm::translate(model, glm::vec3{ 50.0f, 50.0f, 0.0f }); +model = glm::scale(model, glm::vec3{ 200.0f, 200.0f, 0.0f }); +glUniformMatrix4fv(modelLocation, 1, GL_FALSE, + glm::value_ptr(model)); +``` + +## Geometry Shader + +Geometry shaders were introduced in OpenGL 3.2, they can produce vertices +that are send to the rasterizer. They can also change the primitive type e.g. +they can take a point as an input and output other primitives. +Geometry shaders are inbetween the vertex and the fragment shader. + +**Vertex Shader** + +```glsl +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 color; +// Create an output interface block passed to the next shadaer stage. +// Interface blocks can be used to structure data passed between shaders. +out VS_OUT { + vec3 color; +} vs_out; + +void main() { + vs_out.color = color + gl_Position = vec4(position, 1.0); +} +``` + +**Geometry Shader** + +```glsl +#version 330 core +// The geometry shader takes in points. +layout(points) in; +// It outputs a triangle every 3 vertices emitted. +layout(triangle_strip, max_vertices = 3) out; +// VS_OUT becomes an input variable in the geometry shader. +// Every input to the geometry shader in treated as an array. +in VS_OUT { + vec3 color; +} gs_in[]; +// Output color for the fragment shader. +// You can also simply define color as 'out vec3 color', +// If you don't want to use interface blocks. +out GS_OUT { + vec3 color; +} gs_out; + +void main() { + // Each emit calls the fragment shader, so we set a color for each vertex. + gs_out.color = mix(gs_in[0].color, vec3(1.0, 0.0, 0.0), 0.5); + // Move 0.5 units to the left and emit the new vertex. + // gl_in[] is the current vertex from the vertex shader, here we only + // use 0, because we are receiving points. + gl_Position = gl_in[0].gl_Position + vec4(-0.5, 0.0, 0.0, 0.0); + EmitVertex(); + gs_out.color = mix(gs_in[0].color, vec3(0.0, 1.0, 0.0), 0.5); + // Move 0.5 units to the right and emit the new vertex. + gl_Position = gl_in[0].gl_Position + vec4(0.5, 0.0, 0.0, 0.0); + EmitVertex(); + gs_out.color = mix(gs_in[0].color, vec3(0.0, 0.0, 1.0), 0.5); + // Move 0.5 units up and emit the new vertex. + gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.75, 0.0, 0.0); + EmitVertex(); + EndPrimitive(); +} +``` + +**Fragment Shader** + +```glsl +in GS_OUT { + vec3 color; +} fs_in; + +out vec4 outColor; + +void main() { + outColor = vec4(fs_in.color, 1.0); +} +``` + +If you now store a single point with a single color in a VBO and draw them, +you should see a triangle, with your color mixed half way between +red, green and blue on each vertex. + + +## Quotes +<sup>[1]</sup>[OpenGL - Wikipedia](https://en.wikipedia.org/wiki/OpenGL) + +## Books + +- OpenGL Superbible - Fifth Edition (covering OpenGL 3.3) +- OpenGL Programming Guide - Eighth Edition (covering OpenGL 4.3) diff --git a/osl.html.markdown b/osl.html.markdown new file mode 100644 index 00000000..1fe010ec --- /dev/null +++ b/osl.html.markdown @@ -0,0 +1,751 @@ +--- +language: osl +filename: learnosl.osl +contributors: + - ["Preetham Pemmasani", "https://github.com/Preetham-ai"] +--- + +OSL (Open Shading Language) is a programming language designed by Sony for Arnold Renderer used for creating shaders. + +[Read more here.](https://raw.githubusercontent.com/imageworks/OpenShadingLanguage/master/src/doc/osl-languagespec.pdf) + +```c + + +// Single-line comments start with // + +/* Multi line comments are preserved. */ + +// Statements can be terminated by ; +divide(1,2); + +/////////////// +// 1. Basics // +/////////////// + +// Declating variables +color Blue; // Initializing a variable +int _num = 3; +float Num = 3.00; +float c[3] = {0.1, 0.2, 3.14}; // Array + +// Math works as you would expect +3 + 1; // 4 +74 - 3; // 71 +20 * 2; // 40 +75/3; // 25.0 + +// And modulo division only works with integers +10 % 2; // 0 +31 % 4; // 1 + +// Bitwise operations only works with integers +- 0 // 1 (Unary Negation) +~ 00100011 // 11011100 (bitwise Compliment) +1 << 2; // 4 (shift Left) +12 >> 1; // 3 (shift Right) +1 & 0; // 0 (bitwise AND) +1 | 0; // 1 (bitwise OR) +1 ^ 1; // 0 (bitwise XOR) + +// We also have booleans +true; +false; + +// Booleans can't be compared to integers +true == 1 // Error +false == 0 // Error + +// Negation uses the ! symbol +!0; // 1 +!1; // 0 +!2; // 0 +//... and so on + +// Relation Operators are defined like: +0 == 0 // true (equal to) +0 != 1 // true (not equal to) +5 < 3 // false (less then) +3 <= 3 // true (less than or equal to) +69 > 69 // false (greater than) +99 >= 52 // true (greater than or equal) + + +// Functions are same as C and C++ +float sum(float a, float b){ + return a+b; +} + +int subtract(int a, int b){ + return a-b; +} + +sum(2,3); // 5 + +//////////////// +// 2. Shaders // +//////////////// + +// Shaders explain the custom behavior of materials and light +// Shader's syntax is similar to the main function in C +// The inputs and the outputs should be initialized to default types +shader multiply(float a = 0.0, + float b = 0.0, + output float c = 0.0){ + c = a*b; +} + +// Double brackets[[ ]] is used to classify metadata of a shader +surface plastic + [[ string help = "Realistic wood shader" ]] +( + color Plastic = color (0.7, 0.5, 0.3) [[ string help = "Base color" ]], + float Reflectivity = 0.5 [[ float min = 0, float max = 1 ]], +){...} + +/////////////////////////////////////// +// Metadata Types +/////////////////////////////////////// + +[[ string label = "IOR" ]] // Display-name in UI of the parameter +[[ string help = "Change Refractive Index" ]] // Info about the parameter +[[ string help = "widget" // Gives widgets to input the parameter + string widget = "number" ]] // input float or int + string widget = "string" ]] // String input + string widget = "boolean" ]] // yes/no (or) 1/0 + string widget = "popup", options = "smooth|rough" ]] // Drop-down list + // enum Drop-down list can also be made + string widget = "mapper", options = "smooth:0|rough:1" ]] + string widget = "filename" ]] // Input files externally + string widget = "null" ]] // null input + +[[ float min = 0.0 ]] // Minimum value of parameter +[[ float max = 0.5 ]] // Maximum value of parameter +[[ int slider = 3.0 // Adds a slider as an input + int slidermin = -1]] // minimum value of the slider + int slidermax = 3]] // maximum value of the slider + int slidercenter = 2]] // origin value of the slider + +[[ float sensitivity = 0.5 ]] // step size for incrementing the parameter +[[ string URL = www.example.com/ ]] // URL of shader's documentation + + + +// There are different types of shaders + +/* Surface shaders determine the basic material properties of a surface and +how it reacts to light */ +// Light shaders are a type of SURFACE shaders used for emissive objects. +// Displacement shaders alter the geometry using position and normals. +// Volume shaders adds a medium like air/smoke/dust into the scene. + +volume multiply(float a = 0.0, float b = 0.0, output float c = 0.0){ + c = 2*a+b; +} + +//////////////////////////////////////// +// 3. Data Types and Global Variables // +//////////////////////////////////////// + +// Data Types + +// 1. The void type indicates a function that doesn't return any value + +// 2. int (Integer) + int x = -12; // Minimum size of 32-bits + int new2 = 0x01cf; // Hexadecimal can also be specified + + /////////////////////////////////////// + // Order of Evaluation + /////////////////////////////////////// + + // From top to bottom, top has higher precedence + //--------------------------// + // Operators // + //--------------------------// + // int++, int-- // + // ++ int --int - ~ ! // + // * / % // + // + - // + // << >> // + // < <= > >= // + // == != // + // & // + // ^ // + // | // + // && // + // || // + // ?: // + // = += -= *= /= // + //--------------------------// + +// 3. float (Floating-point number) + float A = 2.3; // minimum IEEE 32-bit float + float Z = -4.1e2; // Z = -4.1 * 10^2 + + // Order of evaluation is similar to int. + // Operations like ( ~ ! % << >> ^ | & && || ) aren't available in float + +// 4. string + // The syntax is similar to C + string new = "Hello World"; + // some Special characters: + /* + '\"'; // double quote + '\n'; // newline character + '\t'; // tab character (left justifies text) + '\v'; // vertical tab + '\\'; // back slash + '\r'; // carriage return + '\b'; // backspace character + */ + + // Strings are concatenated with whitespace + "Hello " "world!"; // "Hello world!" + // concat function can also be used + string concat ("Hello ","World!"); // "Hello world!" + + // printf function is same as C + int i = 18; + printf("I am %d years old",i); // I am 18 years old + + // String functions can alse be used + int strlen (string s); // gives the length of the string + int len = strlen("Hello, World!"); // len = 13 + + // startswith returns 1 if string starts with prefix, else returns 0 + int starts = startswith("The quick brown fox", "The"); // starts = 1 + + // endswith returns 1 if string starts with suffix, else returns 0 + int ends = endswith("The quick brown fox", "fox"); // ends will be 1 + +// 5. color (Red, Green, Blue) + color p = color(0,1,2); // black + color q = color(1); // white ( same as color(1,1,1) ) + color r = color("rgb", 0.23, 0.1, 0.8); // explicitly specify in RGB + color s = color("hsv", 0.23, 0.1, 0.8); // specify in HSV + // HSV stands for (Hue, Saturation, Luminance) + // HSL stands for (Hue, Saturation, Lightness) + // YIQ, XYZ and xyY formats can also be used + // We can also access the indivudual values of (R,G,B) + float Red = p[0]; // 0 (access the red component) + float Green = p[1]; // 1 (access the green component) + float Blue = p[2]; // 2 (access the blue component) + + // They can also be accessed like this + float Red = p.r; // 0 (access the red component) + float Green = p.g; // 1 (access the green component) + float Blue = p.b; // 2 (access the blue component) + + // Math operators work like this with decreasing precedence + color C = (3,2,3) * (1,0,0); // (3, 0, 0) + color D = (1,1,1) * 255; // (255, 255, 255) + color E = (25,5,125) / 5; // (5, 1, 25) + color F = (30,40,50) / (3,4,5); // (10, 10, 10) + color A = (1,2,3) + (1,0,0); // (2, 2, 3) + color B = (1,2,3) - (1,0,0); // (0, 2, 3) + // Operators like ( - == != ) are also used + + // Color Functions + color blackbody (1500) // Gives color based on temperature (in Kelvin) + float luminance (0.5, 0.3, 0.8) // 0.37 gives luminance cd/m^2 + // Luminance is calculated by 0.2126R+0.7152G+0.0722B + color wavelength color (700) // (1, 0, 0) Gives color based on wavelength + color transformc ("hsl", "rgb") // converts one system to another + +// 6. point (x,y,z) is position of a point in the 3D space +// 7. vector (x,y,z) has length and direction but no position +// 8. normal (x,y,z) is a special vector perpendicular to a surface + // These Operators are the same as color and have the same precedence + L = point(0.5, 0.6, 0.7); + M = vector(30, 100, 70); + N = normal(0, 0, 1); + + // These 3 types can be assigned to a coordinate system + L = point("object", 0.5, 0.6, 0.7); // relative to local space + M = vector("common", 30, 100, 70); // relative to world space + // There's also ("shader", "world", "camera", "screen", "raster", "NDC") + + float x = L[0]; // 0.5 (access the x-component) + float y = L[1]; // 0.6 (access the y-component) + float z = L[2]; // 0.7 (access the z-component) + + // They can also be accessed like this + float x = M.x; // 30 (access the x-component) + float y = M.y; // 100 (access the y-component) + float z = M.z; // 70 (access the z-component) + + float a = dot ((1,2,3), (1,2,3)); // 14 (Dot Product) + vector b = cross ((1,2,3), (1,2,3)); // (0,0,0) (Cross Product) + float l = length(L); // 1.085 (length of vector) + vector normalize (vector L); // (0.460, 0.552, 0.644) Normalizes the vector + + point p0 = point(1, 2, 3); + point p1 = point(4, 5, 6); + point Q = point(0, 0, 0); + + // Finding distance between two points + float len = distance(point(1, 2, 3), point(4, 5, 6)); // 5.196 + // Perpendicular distance from Q to line joining P0 and P1 + float distance (point P0, point P1, point Q); // 2.45 + + +// 9. matrix + // Used for transforming vectors between different coordinate systems. + // They are usually 4x4 (or) 16 floats + matrix zero = 0; // makes a 4x4 zero matrix + /* 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0 */ + + matrix ident = 1; // makes a 4x4 identity matrix + /* 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 */ + + matrix m = 7; // Maked a 4x4 scalar matrix with scaling factor of 7 + /* 7.0, 0.0, 0.0, 0.0, + 0.0, 7.0, 0.0, 0.0, + 0.0, 0.0, 7.0, 0.0, + 0.0, 0.0, 0.0, 7.0 */ + + float x = m[1][1]; // 7 + + // matrices can be constructed using floats in row-major order + // matrices are usually 4x4 with 16 elements + matrix myMatrix = matrix(1.0, 0.0, 0.0, 0.0, // Row 1 + 0.0, 2.0, 0.0, 0.0, // Row 2 + 0.0, 0.0, 3.0, 0.0, // Row 3 + 0.0, 0.0, 0.0, 4.0); // Row 4 + + // matrix transformations are easy to implement + matrix a = matrix ("shader", 1); // converted shader to common + matrix m = matrix ("object", "world"); // converted object to world + + // Operations that can be used with decreasing precedence are: + // ( - * / == !=) + + float determinant (matrix M) // 24 (returns the determinant of the matrix) + float transpose (matrix M) // returns the transpose of the matrix + /* 1.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 3.0, 0.0, + 0.0, 0.0, 0.0, 4.0 */ + +// 10. array + // Arrays in OSL are similar to C + float a[5]; // initialize array a with size 5 + int b[3] = {90,80,70}; // declare array with size 3 + int len = arraylength(b); // 3 + int f = b[1]; // 80 + float anotherarray[3] = b; // arrays can be copied if same type + +// 11. struct (Structures) + // Structures in OSL are similar to C and C++. + struct RGBA { // Defining a structure + color rgb; + float alpha; + }; + + + RGBA col; // Declaring a structure + RGBA b = { color(0.1, 0.2, 0.3), 1 }; // Can also be declared like this + + r.rgb = color (1, 0, 0); // Assign to one field + color c = r.rgb; // Read from a structure field + +// 12. closure + // Closure is used to store data that aren't considered when it executes. + // It cannot be manipulated or read. + // A null closure can always be assigned. + // OSL currently only supports color as their closure. + + // A few examples of closures are: + + // Diffuse BSDF closures: + closure color oren_nayar_diffuse_bsdf(normal N, color alb, float roughness) + closure color burley_diffuse_bsdf(normal N, color alb, float roughness); + + // Dielectric BSDF closure: + closure color dielectric_bsdf(normal N, vector U, color reflection_tint, + color transmission_tint, float roughness_x, float roughness_y, + float ior, string distribution); + + // Conductor BSDF closure: + closure color conductor_bsdf(normal N, vector U, float roughness_x, + float roughness_y, color ior, color extinction, string distribution); + + // Generalized Schlick BSDF closure: + closure color generalized_schlick_bsdf(normal N, vector U, + color reflection_tint, color transmission_tint, + float roughness_x, float roughness_y, color f0, color f90, + float exponent, string distribution); + + // Translucent BSDF closure: + closure color translucent_bsdf(normal N, color albedo); + + // Transparent BSDF closure: + closure color transparent_bsdf(); + + // Subsurface BSSRDF closure: + closure color subsurface_bssrdf(); + + // Sheen BSDF closure: + closure color sheen_bsdf(normal N, color albedo, float roughness); + + // Anisotropic VDF closure: (Volumetric) + closure color anisotropic_vdf(color albedo, color extinction, + float anisotropy); + + // Medium VDF closure: (Volumetric) + closure color medium_vdf(color albedo, float transmission_depth, + color transmission_color, float anisotropy, float ior, int priority); + + closure color uniform edf(color emittance); // Emission closure + closure color holdout(); // Holdout Hides objects beneath it + + // BSDFs can be layered using this closure + closure color layer (closure color top, closure color base); + + + +// Global Variables +// Contains info that the renderer knows +// These variables need not be declared + +point P // Position of the point you are shading +vector I // Incident ray direction from viewing position to shading position +normal N // Normal of the surface at P +normal Ng // Normal of the surface at P irrespective of bump mapping +float u // UV 2D x - parametric coordinate of geometry +float v // UV 2D y - parametric coordinate of geometry +vector dPdu // change of P with respect to u tangent to the surface +vector dPdv // change of P with respect to v tangent to the surface +float time // Current time +float dtime // Time covered +vector dPdtime // change of P with respect to time + +///////////////////// +// 4. Control flow // +///////////////////// + +// Conditionals in OSL are just like in C or C++. + +// If/Else +if (5>2){ + int x = s; + int l = x; +} +else{ + int x = s + l; +} + +// 'while' loop +int i = 0; +while (i < 5) { + i += 1; + printf("Current value of i: %d\n", i); +} + +// 'do-while' loop is where test happens after the body of the loop +int i = 0; +do { + printf("Current value of i: %d\n", i); + i += 1; +} while (i < 5); + +// 'for' loop +for (int i = 0; i < 5; i += 1) { + printf("Current value of i: %d\n", i); +} + +///////////////////// +// 5. Functions // +///////////////////// + +// Math Constants + M_PI // π + M_PI_35 // π/35 + m_E // e + M_LN2 // ln 2 + M_SQRT2 // √2 + M_SQRT1_2 // √(1/2) + +// Geometry Functions + vector N = vector(0.1, 1, 0.2); // Normal vector + vector I = vector(-0.5, 0.2, 0.8); // Incident vector + + // Faceforward tells the direction of vector + vector facing_dir = faceforward(N, I); // facing_dir = (-0.5, 0.2, 0.8) + + // faceforward with three arguments + vector ref = vector(0.3, -0.7, 0.6); // Reference normal + facing_dir = faceforward(N, I, ref); // facing_dir = (0.5, -0.2, -0.8) + + // reflect gives the reflected vector along normal + vector refl = reflect(I, N); // refl = (-0.7, -0.4, 1.4)\ + + // refract gives the refracted vector along normal + float ior = 1.5; // Index of refraction + vector refr = refract(I, N, ior); // refr = (-0.25861, 0.32814, 0.96143) + + /* Fresnel computes the Reflection (R) and Transmission (T) vectors, along + with the scaling factors for reflected (Kr) and transmitted (Kt) light. */ + float Kr, Kt; + vector R, T; + fresnel(I, N, ior, Kr, Kt, R, T); +/* Kr = 0.03958, Kt = 0.96042 + R = (-0.19278, -0.07711, 0.33854) + T = (-0.25861, 0.32814, 0.96143) */ + + // Rotating a point along a given axis + point Q = point(1, 0, 0); + float angle = radians(90); // 90 degrees + vector axis = vector(0, 0, 1); + point rotated_point = rotate(Q, angle, axis); + // rotated_point = point(0, 1, 0) + + // Rotating a point along a line made by 2 points + point P0 = point(0, 0, 0); + point P1 = point(1, 1, 0); + angle = radians(45); // 45 degrees + Q = point(1, 0, 0); + rotated_point = rotate(Q, angle, P0, P1); + // rotated_point = point(0.707107, 0.707107, 0) + + // Calculating normal of surface at point p + point p1 = point(1, 0, 0); // Point on the sphere of radius 1 + vector normal1 = calculatenormal(p1); + // normal1 = vector(1, 0, 0) + + // Transforming units is easy + float transformu ("cm", float x) // converts to cm + float transformu ("cm", "m", float y) // converts cm to m + +// Displacement Functions + void displace (float 5); // Displace by 5 amp units + void bump (float 10); // Bump by 10 amp units + + +// Noise Generation + + type noise (type noise (string noisetype, float u, float v, ...)); // noise + type noise (string noisetype, point p,...); // point instead of coordinates + /* some noises are ("perlin", "snoise", "uperlin", "noise", "cell", "hash" + "simplex", "usimplex", "gabor", etc) */ + + // Noise Names + + // 1. Perlin Noise (perlin, snoise): + // Creates smooth, swirling noise often used for textures. + // Range: [-1, 1] (signed) + color cloud_texture = noise("perlin", P); + + // 2. Simplex Noise (simplex, usimplex): + // Similar to Perlin noise but faster. + // Range: [-1, 1] (signed) for simplex, [0, 1] (unsigned) for usimplex + float bump_amount = 0.2 * noise("simplex", P * 5.0); + + // 3. UPerlin Noise (uperlin, noise): + // Similar to peril + // Range: [0, 1] (unsigned) + color new_texture = noise("uperlin", P); + + // 4. Cell Noise (cell): + // Creates a blocky, cellular and constant values within each unit block + // Range: [0, 1] (unsigned) + color new_texture = noise("cell", P); + + // 5. Hash Noise (hash): + // Generates random, uncorrelated values at each point. + // Range: [0, 1] (unsigned) + color new_texture = noise("hash", P); + + // Gabor Noise (gabor) + // Gabor Noise is advanced version of Perin noies and gives more control + // Range: [-1, 1] (signed) + // Gabor Noise Parameters + + // Anisotropic (default: 0) + // Controls anisotropy: + // 0: Isotropic (equal frequency in all directions) + // 1: Anisotropic with user-defined direction vector (defaults to (1,0,0)) + /* 2: Hybrid mode,anisotropic along direction vector but radially isotropic + perpendicularly. */ + + // Direction (default: (1,0,0)) + // Specifies the direction of anisotropy (used only if anisotropic is 1). + + // bandwidth (default: 1.0) + // Controls the frequency range of the noise. + + // impulses (default: 16) + // Controls the number of impulses used per cell, affecting detail level. + + // do_filter (default: 1) + // Enables/disables antialiasing (filtering). + + result = noise( + "gabor", + P, + "anisotropic", anisotropic, + "direction", direction, + "bandwidth", bandwidth, + "impulses", impulses, + "do_filter", do_filter + ); + + // Specific noises can also be used instead of passing them as types + // pnoise is periodic noise + float n1 = pnoise("perlin", 0.5, 1.0); + // 2D periodic noise with Gabor type + float n2 = pnoise("gabor", 0.2, 0.3, 2.0, 3.0); + // 2D non-periodic simplex noise + float n3 = snoise(0.1, 0.7); + // 2D periodic simplex noise + type psnoise (float u, float v, float uperiod, float vperiod); + float n4 = psnoise(0.4, 0.6, 0.5, 0.25); + // 2D cellular noise + float n5 = cellnoise(0.2, 0.8); + // 2D hash noise + int n6 = hash(0.7, 0.3); + +// Step Function + // Step Functions are used to compare input and threshold + + // The type may be of float, color, point, vector, or normal. + type step (type edge, type x); // Returns 1 if x ≥ edge, else 0 + color checker = step(0.5, P); // P is a point on the surface + /* Pixels with P values below 0.5 will be black, those above or equal will + be white */ + float visibility = step(10, distance(P, light_position)); + // Light is fully visible within 10 units, completely invisible beyond + + type linearstep (type edge0, type edge1, type x); /* Linearstep Returns 0 + if x ≤ edge0, and 1 if x ≥ edge1, with linear interpolation */ + color gradient = linearstep(0, 1, P); + // P is a point on the surface between 0 and 1 + // Color will graduate smoothly from black to white as P moves from 0 to 1 + float fade = linearstep(0.85, 1, N.z); // N.z is the z-component + // Object edges with normals close to vertical (N.z near 1) will fade out + + type smoothstep (type edge0, type edge1, type x); /* smoothstep Returns 0 + if x ≤ edge0, and 1 if x ≥ edge1, with Hermite interpolation */ + float soft_mask = smoothstep(0.2, 0.8, noise(P)); /* noise(P) is a noisy + value between 0 and 1. soft_mask will vary smoothly between 0 and 1 based + on noise(P), with a smoother curve than linearstep */ + +// Splines + // Splines are smooth curves based on a set of control points + + /* The type of interpolation ranges from "catmull-rom", "bezier", + "bspline", "hermite", "linear", or "constant" */ + + // Spline with knot vector + float[] knots = {0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1}; + point[] controls = {point(0),point(1, 2, 1),point(2, 1, 2),point(3, 3, 1)}; + spline curve1 = spline("bezier", 0.5, len(knots), controls); + // curve1 is a Bezier spline evaluated at u = 0.5 + + // Spline with control points + spline curve2 = spline("catmull-rom", 0.25, point(0, 0, 0), point(1, 2, 1), + point(2, 1, 2), point(3, 3, 1)); + // curve2 is a Catmull-Rom spline evaluated at u = 0.25 + + // Constant spline with a single float value + float value = 10; + u = 0.1; + spline curve5 = spline("constant", u, value); + // curve5 is a constant spline with value 10 evaluated at u = 0.1 + + // Hermite spline with point and vector controls + point q0 = point(0, 0, 0), q1 = point(3, 3, 3); + vector t0 = vector(1, 0, 0), t1 = vector(-1, 1, 1); + u = 0.75; + spline curve3 = spline("hermite", u, q0, t0, q1, t1); + // curve3 is a Hermite spline evaluated at u = 0.75 + + // Linear spline with float controls + float f0 = 0, f1 = 1, f2 = 2, f3 = 3; + u = 0.4; + spline curve4 = spline("linear", u, f0, f1, f2, f3); + // curve4 is a linear spline evaluated at u = 0.4 + + // InverseSplines also exist + + // Inverse spline with control values + float y0 = 0, y1 = 1, y2 = 2, y3 = 3; + float v = 1.5; + float u1 = splineinverse("linear", v, y0, y1, y2, y3); + // u1 = 0.5 (linear interpolation between y1 and y2) + + // Inverse spline with knot vector + float[] knots = {0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1}; + float[] values = {0, 1, 4, 9}; + v = 6; + float u2 = splineinverse("bezier", v, len(knots), values); + // u2 = 0.75 (Bezier spline inverse evaluated at v = 6) + + // Inverse spline with constant value + v = 10; + float u3 = splineinverse("constant", v, 10); + // u3 = 0 (since the constant spline always returns 10) + + // Inverse spline with periodic values + float y4 = 0, y5 = 1, y6 = 0; + v = 0.5; + float u4 = splineinverse("periodic", v, y4, y5, y6); + // u4 = 0.75 (periodic spline inverse evaluated at v = 0.5) + + + +// Calculus Operators + // Partial derivative of f with respect to x, y and z using Dx, Dy, Dz + float a = 3.14; + float dx = Dx(a); // partial derivative of a with respect to x + + point p = point(1.0, 2.0, 3.0); + vector dp_dx = Dx(p); // partial derivative of p with respect to x + + vector dv_dy = Dy(N); // partial derivative of normal with respect to y + + color c = color(0.5, 0.2, 0.8); + color dc_dz = Dz(c); // partial derivative of c with respect to z + + + float area (point p) // gives the surface area at the position p + + float filterwidth (float x) // gives the changes of x in adjacent samples + +// Texture Functions + // lookup for a texture at coordinates (x,y) + color col1 = texture("texture.png", 0.5, 0.2); + // Lookup color at (0.5, 0.2) in texture.png + + // 3D lookup for a texture at coordinates (x,y) + color col3 = texture3d("texture3d.vdb", point(0.25, 0.5, 0.75)); + + // parameters are ("blur","width","wrap","fill","alpha","interp", ...) + color col2 = texture("texture.png",1.0,0.75,"blur",0.1,"wrap", "periodic"); + // Lookup color at (1.0, 0.75) with blur 0.1 and periodic wrap mode + +// Light Functions + + float surfacearea (); // Returns the surface area of area light covers + int backfacing (); // Outputs 1 if the normals are backfaced, else 0 + int raytype (string name); // returns 1 if the ray is a particular raytype + + // Tracing a ray from a position in a direction + point pos = point(0, 0, 0); // Starting position of the ray + vector dir = vector(0, 0, 1); // Direction of the ray + int hit = trace(pos, dir); // returns 1 if it hits, else 0 + +``` +### Further reading + +* [Blender Docs for OSL](https://docs.blender.org/manual/en/latest/render/shader_nodes/osl.html) +* [C4D Docs for OSL](https://docs.otoy.com/cinema4d//OpenShadingLanguageOSL.html) +* Open Shading Language on [GitHub](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage) +* [Official OSL Documentation](https://open-shading-language.readthedocs.io/en/main/)
\ No newline at end of file diff --git a/p5.html.markdown b/p5.html.markdown index d36d417f..2588ffc6 100644 --- a/p5.html.markdown +++ b/p5.html.markdown @@ -10,40 +10,142 @@ filename: p5.js p5.js is a JavaScript library that starts with the original goal of [Processing](https://processing.org), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web. Since p5 is a JavaScript library, you should learn [Javascript](https://learnxinyminutes.com/docs/javascript/) first. +To run p5.js code, you can go to [the online editor](https://editor.p5js.org/). + ```js /////////////////////////////////// // p5.js has two important functions to work with. function setup() { - // the setup function gets executed just once when the window is loaded + // the setup function gets executed just once when the window is loaded } function draw() { - // the draw function gets called every single frame. This means that for a frameRate(30) it would get called 30 times per second. + // the draw function gets called every single frame + // if the framerate is set to 30, it would get called 30 times every second } // the following code explains all features function setup() { - createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height - background(128); // changes the background color of the canvas, can accept rgb values like background(100,200,20) else grayscale values like background(0) = black or background(255) = white + createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height + background(128); // sets the background color to rgb(128, 128, 128) + // background('#aaf') // you can use hex codes and color names too } function draw() { - ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width and height as 50 each, so its basically a circle. - //remember in p5.js the origin is at the top-left corner of the canvas + background('#f2f2fc'); // usually, you call `background` in draw to clear the screen + // creates an ellipse at 10px from the top and 10px from the left, with width and height 37 + ellipse(10, 10, 37, 37); + // remember in p5.js the origin is at the top-left corner of the canvas + + if (mouseIsPressed) { + // mouseIsPressed is a boolean variable that is true when the mouse is down, and false otherwise + + fill(0); // fill sets the fill color, which will stay until it is changed + } else { + fill(255, 255, 255, 240); // fill(a, b, c, d) sets the fill color to rgba(a, b, c, d) + } + + ellipse(mouseX, mouseY, 80, 80); + // mouseX and mouseY are the x and y position of the mouse, respectively + // the above code creates and ellipse under the mouse, and fills it with white or black + + + // some other 2d primitives (shapes) you can draw: + rect(9, 3, 23, 26); // x, y, width, height + noFill(); // sets the fill color to transparent + triangle(100, 400, 130, 200, 200, 300); // x1, y1, x2, y2, x3, y3 + point(100, 300); // create a point at x, y + // there are more, but they are more complex. +} - if (mouseIsPressed) { - // mouseIsPressed is a boolean variable that changes to true if the mouse button is pressed down at that instant +/** Bouncing balls animation + * You can copy-paste this code into the online editor at + * https://editor.p5js.org/ + */ +class Ball { + constructor(x, y, xvel, yvel, radius, col) { + this.position = createVector(x, y); // create a p5.Vector object which stores the x and y + this.velocity = createVector(xvel, yvel); // make a p5.Vector storing the velocity + this.radius = radius; + this.col = col; // p5 already uses the word color, so we use col instead + } - fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next - } else { - fill(255); // you can give in rgb values like fill(72, 240, 80) to get colors, else a single values determines the grayscale where fill(255) stands for #FFF(white) and fill(0) stands for #000(black) + update() { + this.position.add(this.velocity); // you can add vectors with p5.Vector.add(p5.Vector) + if (this.position.x + this.radius > width) { + // flip the direction the ball is going in if it touches the edge + this.velocity.x *= -1; } + if (this.position.x - this.radius < 0) { + this.velocity.x *= -1; + } + if (this.position.y + this.radius > height) { + this.velocity.y *= -1; + } + if (this.position.y - this.radius < 0) { + this.velocity.y *= -1; + } + } + + render() { + // you can figure out what this does by now + fill(this.col); + ellipse(this.position.x, this.position.y, this.radius); + } +} + +let numBalls = 23; +let balls = []; + +function setup() { + createCanvas(400, 400); // width, height + for (let i = 0; i < numBalls; i++) { + let r = random(255); // random number between 0 and 255 + let g = random(255); + let b = random(255); + + balls.push( + new Ball( + random(30, width), // x position + random(height), // y position + random(-4, 4), // x velocity + random(-4, 4), // y velocity + random(4, 10), // radius + color(r, g, b) // fill color for the ball + ) + ); + } +} + +function draw() { + background(255); + for (let ball of balls) { + ball.update(); + ball.render(); + } +} + +// So far, we have only seen the default rendering mode. +// This time, we will use the 'webgl' renderer - ellipse(mouseX, mouseY, 80, 80); - // mouseX is the x-coordinate of the mouse's current position and mouseY is the y-coordinate of the mouse's current position +function setup() { + createCanvas(400, 400, WEBGL); // width, height, rendering mode +} + +function draw() { + background(0); - // the above code creates a circle wherever mouse's current position and fills it either black or white based on the mouseIsPressed + stroke('#000'); + fill('#aaf'); + + // rotate around the x, y, and z axes by the frame count divided by 50 + rotateX(frameCount / 50); + rotateY(frameCount / 50); + rotateZ(frameCount / 50); + // frameCount is a p5.js variable that stores the amount of frames that have passed + + box(50, 50, 50); // width, height, depth } ``` @@ -51,3 +153,9 @@ function draw() { - [p5.js | get started](http://p5js.org/get-started/) The official documentation - [Code! Programming for Beginners with p5.js - YouTube](https://www.youtube.com/watch?v=yPWkPOfnGsw&vl=en) Introduction and Coding challenges using Processing and p5.js by Coding Train +- [The Coding Train](https://codingtra.in/) A website with sketches made in p5 and processing + +## Source + +- [p5's source code](https://github.com/processing/p5.js) +- [p5.sound.js source](https://github.com/processing/p5.js-sound) diff --git a/php.html.markdown b/php.html.markdown index 61f1c00c..1ef52f68 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -92,9 +92,10 @@ $escaped = "This contains a \t tab character."; $unescaped = 'This just contains a slash and a t: \t'; // Enclose a variable in curly braces if needed -$apples = "I have {$number} apples to eat."; -$oranges = "I have ${number} oranges to eat."; -$money = "I have $${number} in the bank."; +$number = 23; +$apples = "I have {$number} apples to eat."; // => I have 23 apples to eat. +$oranges = "I have ${number} oranges to eat."; // => I have 23 oranges to eat. +$money = "I have $${number} in the bank."; // => I have $23 in the bank. // Since PHP 5.3, nowdocs can be used for uninterpolated multi-liners $nowdoc = <<<'END' @@ -109,7 +110,7 @@ $sgl_quotes END; // String concatenation is done with . -echo 'This string ' . 'is concatenated'; +echo 'This string ' . 'is concatenated'; // Returns 'This string is concatenated' // Strings can be passed in as parameters to echo echo 'Multiple', 'Parameters', 'Valid'; // Returns 'MultipleParametersValid' diff --git a/powershell.html.markdown b/powershell.html.markdown index 033d6c25..50e1e27e 100644 --- a/powershell.html.markdown +++ b/powershell.html.markdown @@ -118,14 +118,15 @@ $False - 5 # => -5 2 -lt 3 -and 3 -lt 2 # => False # (-is vs. -eq) -is checks if two objects are the same type. -# -eq checks if the objects have the same values. +# -eq checks if the objects have the same values, but sometimes doesn't work +# as expected. # Note: we called '[Math]' from .NET previously without the preceeding # namespaces. We can do the same with [Collections.ArrayList] if preferred. [System.Collections.ArrayList]$a = @() # Point a at a new list $a = (1,2,3,4) $b = $a # => Point b at what a is pointing to $b -is $a.GetType() # => True, a and b equal same type -$b -eq $a # => True, a and b values are equal +$b -eq $a # => None! See below [System.Collections.Hashtable]$b = @{} # => Point a at a new hash table $b = @{'one' = 1 'two' = 2} @@ -154,6 +155,13 @@ $age = 22 "$name's name is $($name.Length) characters long." # => "Steve's name is 5 characters long." +# Strings can be compared with -eq, but are case insensitive. We can +# force with -ceq or -ieq. +"ab" -eq "ab" # => True +"ab" -eq "AB" # => True! +"ab" -ceq "AB" # => False +"ab" -ieq "AB" # => True + # Escape Characters in Powershell # Many languages use the '\', but Windows uses this character for # file paths. Powershell thus uses '`' to escape characters @@ -274,6 +282,10 @@ $array.AddRange($otherArray) # Now $array is [1, 2, 3, 4, 5, 6] # Examine length with "Count" (Note: "Length" on arrayList = each items length) $array.Count # => 6 +# -eq doesn't compare array but extract the matching elements +$array = 1,2,3,1,1 +$array -eq 1 # => 1,1,1 +($array -eq 1).Count # => 3 # Tuples are like arrays but are immutable. # To use Tuples in powershell, you must use the .NET tuple class. @@ -574,7 +586,7 @@ Get-Process | Foreach-Object ProcessName | Group-Object 1..10 | ForEach-Object { "Loop number $PSITEM" } 1..10 | Where-Object { $PSITEM -gt 5 } | ConvertTo-Json -# A notable pitfall of the pipeline is it's performance when +# A notable pitfall of the pipeline is its performance when # compared with other options. # Additionally, raw bytes are not passed through the pipeline, # so passing an image causes some issues. @@ -665,7 +677,7 @@ Powershell as a Tool: Getting Help: -```Powershell +```powershell # Find commands Get-Command about_* # alias: gcm Get-Command -Verb Add @@ -682,7 +694,7 @@ Update-Help # Run as admin If you are uncertain about your environment: -```Powershell +```powershell Get-ExecutionPolicy -List Set-ExecutionPolicy AllSigned # Execution policies include: @@ -696,7 +708,7 @@ help about_Execution_Policies # for more info $PSVersionTable ``` -```Powershell +```powershell # Calling external commands, executables, # and functions with the call operator. # Exe paths with arguments passed or containing spaces can create issues. diff --git a/pt-br/amd-pt.html.markdown b/pt-br/amd-pt.html.markdown index 40c7cd09..886cb253 100644 --- a/pt-br/amd-pt.html.markdown +++ b/pt-br/amd-pt.html.markdown @@ -19,6 +19,7 @@ módulos de forma síncrona fica sujeito a problemas de performance, usabilidade debugging e problemas de acesso em requisições cross-domain. ### Conceito básico + ```javascript // O básico da API de AMD consiste de nada mais que dois métodos: `define` e `require` // e isso é tudo sobre a definição de módulo e consumo: @@ -122,6 +123,7 @@ define(['daos/coisas', 'modules/algunsHelpers'], function(coisasDao, helpers){ return AlgumaClasse; }); ``` + Para alterar o comportamento padrão de mapeamento de caminho de pastas utilize `requirejs.config(configObj)` em seu `main.js`: @@ -141,6 +143,7 @@ require(['jquery', 'coolLibFromBower', 'modules/algunsHelpers'], function($, coo coolLib.facaAlgoDoidoCom(helpers.transform($('#foo'))); }); ``` + Apps baseados em `require.js` geralmente terão um único ponto de acesso (`main.js`) que é passado à tag script do `require.js` como um data-attribute. Ele vai ser automaticamente carregado e executado com o carregamento da página: ```html @@ -162,16 +165,19 @@ Muitas pessoas preferem usar AMD para sanar a organização do código durante o `require.js` vem com um script chamado `r.js` (que você vai provavelmente rodar em node.js, embora Rhino suporte também) que você pode analisar o gráfico de dependências de seu projeto, e fazer em um único arquivo contendo todos os seus módulos (corretamente nomeados), minificados e prontos para serem consumidos. Instale-o utilizando `npm`: + ```shell $ npm install requirejs -g ``` Agora você pode alimentá-lo com um arquivo de configuração: + ```shell $ r.js -o app.build.js ``` Para o nosso exemplo acima a configuração pode ser essa: + ```javascript /* file : app.build.js */ ({ @@ -188,6 +194,7 @@ Para o nosso exemplo acima a configuração pode ser essa: ``` Para usar o arquivo gerado, em produção, simplesmente troque o `data-main`: + ```html <script src="require.js" data-main="app/main-built"></script> ``` diff --git a/pt-br/asciidoc-pt.html.markdown b/pt-br/asciidoc-pt.html.markdown index b12c0693..9fca5af0 100644 --- a/pt-br/asciidoc-pt.html.markdown +++ b/pt-br/asciidoc-pt.html.markdown @@ -5,7 +5,7 @@ contributors: translators: - ["David Lima", "https://github.com/davelima"] lang: pt-br -filename: asciidoc-pt.md +filename: asciidoc-pt.adoc --- AsciiDoc é uma linguagem de marcação similar ao Markdown e pode ser diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown index 597b0e7a..02bffc41 100644 --- a/pt-br/awk-pt.html.markdown +++ b/pt-br/awk-pt.html.markdown @@ -202,7 +202,7 @@ function string_functions( localvar, arr) { # Ambas retornam o número de instâncias substituídas localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" - gsub("e", ".", localvar) # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar) # localvar => "M..t m. at th. bar" # Localiza um texto que casa com uma expressão regular # index() faz a mesma coisa, mas não permite uma expressão regular diff --git a/pt-br/bc-pt.html.markdown b/pt-br/bc-pt.html.markdown new file mode 100644 index 00000000..2a412806 --- /dev/null +++ b/pt-br/bc-pt.html.markdown @@ -0,0 +1,104 @@ +--- +language: bc +contributors: + - ["Btup"] +translators: + - ["David Lima", "https://github.com/davelima"] +lang: pt-br +filename: learnbc-pt.bc +--- +```c +/*Este é um comentário +multi-linhas*/ +# Este é um comentário de uma única linha! (em bc GNU). + + /*1. Variáveis e estruturas de controle*/ +num = 45 /*Todas as variáveis apenas salvam dados do tipo double, e + você não pode salvar strings diretamente em constantes.*/ +num 45; /*Você pode adicionar ponto-e-vírgula após cada linha. + Isto é opcional*/ +/*Blocos são denotados usando os operadores {} (similar ao C):*/ +while(num < 50) { + num += 1 /*equivalente a num=num+1. + a = a op b é equivalente a a op= b.*/ +} +/*E existem os operadores ++ (incrementar) e -- (decrementar).*/ +/* Existem 3 tipos especiais de variáveis: +scale: define a escala de números double. +ibase: define a base de da entrada. +obase: define a base da saída. +*/ +/*Cláusulas If:*/ +hora = read() /*Lê a entrada de um número*/ + +if(hora < 12) { /*Os operadores são idênticos ao C.*/ + print "Bom dia\n" /*"print" imprime strings ou variáveis + separados por vírgula (,).*/ +} else if(hora == 12) { + print "Olá\n" + /*Para escapar strings, inicie a string com \. + Para deixar o escape de strings mais claros, + aqui está uma lista simplificada das strings escapadas + que funcionarão com bc: + \b: backspace + \c: carriage return (enter) + \n: newline (nova linha) + \t: tab + \\: backslash (barra inertida)*/ +} else { + /*Variáveis são globais por padrão.*/ + istoEGlobal = 5 + /*Para tornar uma variável local, use a palavra-chave "auto" em uma função.*/ +} + +/*Todas as variáveis por padrão tem o valor 0*/ +num = variavelEmBranco /*num é igual a 0.*/ + +/*Assim como no C, "0" é considerado "false"*/ +if(!num) {print "false\n"} + +/*Diferente do C, bc não tem o operador ?:. Por exemplo, +este bloco de código causaria um erro: +a = (num) ? 1 : 0 +Entretanto, você pode simular da seguinte forma: +a = (num) && (1) || (0) /*&& é "E", || é "OU"*/ +*/ + +/*Loops For*/ +num = 0 +for(i = 1; i <= 100; i++) {/*Similar ao loop For do C.*/ + num += i +} + + /*2.Funções e arrays*/ +define fac(n) { /*para definir uma função, use "define".*/ + if(n == 1 || n == 0) { + return 1 /*retorna um valor*/ + } + return n * fac(n - 1) /*recursão é permitido*/ +} + +/*Closures e funções anônimas não são permitidas*/ + +num = fac(4) /*24*/ + +/*Exemplo de variáveis locais:*/ +define x(n) { + auto x + x = 1 + return n + x +} +x(3) /*4*/ +print x /*A variável "x" não será acessível de fora da função*/ +/*Arrays são equivalentes aos arrays em C.*/ +for(i = 0; i <= 3; i++) { + a[i] = 1 +} +/*Para acessar um array, faça assim:*/ +print a[0], " ", a[1], " ", a[2], " ", a[3], "\n" +quit /*Adicione essa linha no final do código +para garantir que o programa encerre. Essa linha é opcional.*/ +``` +Aproveite bem essa simples calculadora! (Ou essa linguagem de programação, para ser exato.) + +Este programa inteiro foi escrito em GNU bc. Para rodá-lo, use ```bc learnbc-pt.bc``` diff --git a/pt-br/c++-pt.html.markdown b/pt-br/c++-pt.html.markdown index 7d8b75f1..ca289001 100644 --- a/pt-br/c++-pt.html.markdown +++ b/pt-br/c++-pt.html.markdown @@ -363,7 +363,7 @@ void OwnedDog::print() const { Dog::print(); // Chame a função de impressão na classe Dog base de std::cout << "Dog is owned by " << owner << "\n"; - // Prints "Dog is <name> and weights <weight>" + // Imprime "Dog is <name> and weights <weight>" // "Dog is owned by <owner>" } diff --git a/pt-br/c-pt.html.markdown b/pt-br/c-pt.html.markdown index c3f62bc6..22a86376 100644 --- a/pt-br/c-pt.html.markdown +++ b/pt-br/c-pt.html.markdown @@ -384,7 +384,6 @@ int main() { // Por exemplo, quando um array é passado para uma função ou é atribuído a um // ponteiro, ele transforma-se (convertido implicitamente) em um ponteiro. // Exceções: quando o array é o argumento de um operador `&` (endereço-de): - // Exceptions: when the array is the argument of the `&` (address-of) operator: int arr[10]; int (*ptr_to_arr)[10] = &arr; // &arr não é do tipo `int *`! // É do tipo "ponteiro para array" (de `int`s). diff --git a/pt-br/css-pt.html.markdown b/pt-br/css-pt.html.markdown index e4f55276..4c52942a 100644 --- a/pt-br/css-pt.html.markdown +++ b/pt-br/css-pt.html.markdown @@ -8,33 +8,36 @@ contributors: - ["Connor Shea", "https://github.com/connorshea"] - ["Deepanshu Utkarsh", "https://github.com/duci9y"] translators: + - ["Adaías Magdiel", "https://adaiasmagdiel.com/"] - ["Gabriel Gomes", "https://github.com/gabrielgomesferraz"] - ["Gabriele Luz", "https://github.com/gabrieleluz"] - lang: pt-br --- -No início da web não havia elementos visuais, apenas texto puro. Mas com maior desenvolvimento de navegadores da web, páginas web totalmente visuais também se tornaram comuns. - -CSS ajuda a manter a separação entre o conteúdo (HTML) e o visual de uma página web. +Páginas web são feitas utilizando HTML para demarcar o conteúdo. +O CSS (Cascading Style Sheets) é uma linguagem separada que é responsável +especificamente pela **aparência** da página. -CSS permite atingir diferentes elementos em uma página HTML e atribuir diferentes propriedades visuais para eles. +Códigos CSS são construídos utilizando várias regras estáticas. Cada regra aceita um ou mais *seletores* +e aplica *valores* específicos de propriedades visuais. Essas propriedades são aplicadas +nos elementos da página indicados pelos seletores. -Este guia foi escrito para CSS2, embora CSS3 esteja rapidamente se tornando popular. +Este guia foi escrito com o CSS 2 em mente, complementado pelas novas +funcionalidades do CSS 3. -**NOTA:** Porque CSS produz resultados visuais, a fim de aprender, você precisa treinar em um playground CSS como [dabblet](http://dabblet.com/). -O foco principal deste artigo é sobre a sintaxe e algumas dicas gerais. +**NOTA:** Devido ao fato do CSS produzir resultados visuais, a fim de aprender, você precisa treinar em um playground CSS como [dabblet](http://dabblet.com/). +O foco principal deste artigo é a sintaxe e algumas dicas gerais. ```css -/* Comentários aparecem dentro do slash-asterisk, tal como esta linha! - Não há "comentários de uma linha"; este é o único estilo de comentário * / +/* Comentários aparecem dentro de blocos com / e *, tal como esta linha! + Não há "comentários de uma linha"; este é o único estilo de comentário. * / /* #################### ## SELETORES #################### */ -/* O seletor é usado para direcionar um elemento em uma página. - seletor { propriedade: valor; / * Mais propriedades ... * / } +/* O seletor é usado para selecionar um elemento em uma página. */ +seletor { propriedade: valor; /* Mais propriedades... */ } /* Abaixo um elemento de exemplo: @@ -42,63 +45,62 @@ Abaixo um elemento de exemplo: <div class='class1 class2' id='anID' attr='value' otherAttr='pt-br foo bar' /> */ -/* Você pode direcioná-lo usando uma das suas classes CSS */ +/* Você pode seleciona-lo usando uma das suas classes CSS */ .class1 { } -/* ou ambas as classes! */ +/* Ou ambas as classes! */ .class1.class2 { } -/* ou o seu nome */ +/* Ou o seu nome */ div { } -/* ou o seu id */ +/* Ou o seu id */ #anID { } -/* ou utilizando o fator de que tem um atributo!*/ -[attr] { font-size:smaller; } +/* Ou através de um dos seus atributos! */ +[attr] { font-size: smaller; } -/* ou que o atributo tem um valor específico */ -[attr='value'] { font-size:smaller; } +/* Ou utilizando um atributo com um valor específico */ +[attr='value'] { font-size: smaller; } -/* começa com um valor (CSS 3) */ +/* Um atributo que começa com um valor (CSS 3) */ [attr^='val'] { font-size:smaller; } -/* ou terminando com um valor (CSS 3) */ -[attr$='ue'] { font-size:smaller; } - +/* Ou termina com um valor (CSS 3) */ +[attr$='ue'] { font-size: smaller; } /* Ou contém um valor em uma lista separada por espaços */ -[otherAttr ~ = 'foo'] {} -[otherAttr ~ = 'bar'] {} +[otherAttr~='foo'] {} +[otherAttr~='bar'] {} /* Ou contém um valor em uma lista separada por hífen, ou seja, "-" (U + 002D) */ -[otherAttr | = 'en'] {font-size: smaller; } +[otherAttr|='pt'] {font-size: smaller; } -/* Você pode concatenar diferentes seletores para criar um seletor mais estreito. Não - colocar espaços entre eles. */ -classe div.some [attr $ = 'ue'] {} +/* Você pode combinar diferentes seletores para criar um seletor mais específica. Lembre-se + de não colocar espaço entre eles */ +div.some-class[attr$='ue'] {} -/* Você pode selecionar um elemento que é filho de outro elemento */ -div.some-parent> .class-name {} +/* Você pode selecionar um elemento que está diretamento dentro de outro elemento */ +div.some-parent > .class-name {} -/* Ou um descendente de um outro elemento. Os filhos são os descendentes diretos de - seu elemento pai, apenas um nível abaixo da árvore. Pode ser quaisquer descendentes - nivelados por baixo da árvore. */ -div.some-parent class-name {} +/* Ou um descendente desse elemento. Os filhos são os descendentes diretos de + um elemento pai, apenas um nível abaixo. Da seguinte forma, você pode seleciona qualquer + elemento que esteja dentro do elemento principal. */ +div.some-parent .class-name {} /* Atenção: o mesmo seletor sem espaço tem um outro significado. - Você consegue adivinhar o que? */ + Dessa forma você estará selecionando um elemento que contenha as duas classes. */ div.some-parent.class-name {} -/* Você também pode selecionar um elemento com base em seu irmão adjacente */ -.i am just-antes + .Este elemento {} +/* Você também pode selecionar um elemento com base em seu irmão mais próximo */ +.i-am-just-before + .this-element {} /* Ou qualquer irmão que o precede */ -.i am-qualquer-elemento antes ~ .Este elemento {} +.i-am-any-element-before ~ .this-element { } -/* Existem alguns seletores chamados pseudo classes que podem ser usados para selecionar um - elemento quando ele está em um determinado estado */ +/* Existem alguns seletores, chamados pseudo classes, que podem ser usados para selecionar um + elemento quando ele está em um determinado estado */ /* Por exemplo, quando o cursor passa sobre um elemento */ seletor:hover {} @@ -112,10 +114,10 @@ seletor:link {} /* Ou um elemento em foco */ seletor:focus {} -/* Qualquer elemento que é o primeiro filho de seu pai */ +/* Qualquer elemento que é o primeiro filho */ seletor:first-child {} -/* Qualquer elemento que é o último filho de seu pai */ +/* Qualquer elemento que é o último filho */ seletor:last-child {} /* Assim como pseudo classes, pseudo elementos permitem que você estilize certas partes de um documento */ @@ -126,88 +128,91 @@ seletor::before {} /* Corresponde a um último filho virtual do elemento selecionado */ seletor::after {} -/* Nos locais apropriados, um asterisco pode ser utilizado como um curinga para selecionar todos - os elementos */ -* {} /* */ Todos os elementos -.parent * {} /* */ todos os descendentes -.parent> * {} /* */ todos os filhos +/* Nos locais apropriados, um asterisco pode ser utilizado como um curinga para selecionar + todos os elementos */ + +* {} /* Todos os elementos */ +.parent * {} /* todos os descendentes */ +.parent > * {} /* todos os filhos */ /* #################### - ## PROPRIEDADES - #################### */ + ## PROPRIEDADES + #################### */ seletor { - - /* Unidades de comprimento pode ser absoluta ou relativa. */ - - /* Unidades relativas */ - width: 50%; /* Percentagem de largura do elemento pai */ - font-size: 2em; /* Múltiplos de font-size original de elemento */ - font-size: 2rem; /* Ou do elemento raiz font-size */ - font-size: 2vw; /* Múltiplos de 1% da largura da janela de exibição (CSS 3) */ - font-size: 2vh; /* Ou a sua altura */ - font-size: 2vmin; /* Qualquer um de VH ou um VW é menor */ - font-size: 2vmax; /* Ou superior */ - - /* Unidades absolutas */ - width: 200px; /* píxeis */ - font-size: 20pt; /* Pontos */ - width: 5cm; /* Centímetros */ - min-width: 50mm; /* Milímetros */ - max-width: 5 polegadas; /* Polegadas */ - - /* Cores */ - color: # F6E; /* Formato hexadecimal curto */ - color: # FF66EE; /* Formato hexadecimal longo */ - color: tomato; /* Uma cor nomeada */ - color: rgb (255, 255, 255); /* Como valores rgb */ - color: RGB (10%, 20%, 50%); /* Como porcentagens rgb */ - color: rgba (255, 0, 0, 0,3); /* Como valores RGBA (CSS 3) NOTA: 0 <a <1 */ - color: transparent; /* Equivale a definir o alfa a 0 */ - color: HSL (0, 100%, 50%); /* Como porcentagens HSL (CSS 3) */ - color: HSLA (0, 100%, 50%, 0,3); /* Como porcentagens HSLA com alfa */ - - /* Imagens como fundos de elementos */ - background-image: url (/img-path/img.jpg); /* Citações dentro url () opcional */ - - /* Fontes */ - font-family: Arial; - /* Se o nome da família de fonte tem um espaço, deve ser citado */ - font-family: "Courier New"; - /* Se o primeiro não for encontrada, o navegador usa o próximo, e assim por diante */ - font-family: "Courier New", Trebuchet, Arial, sans-serif; + /* Unidades de comprimento pode ser absoluta ou relativa. */ + + /* Unidades relativas */ + width: 50%; /* Percentagem de largura do elemento pai */ + font-size: 2em; /* Múltiplos de font-size original de elemento */ + font-size: 2rem; /* Ou do elemento raiz font-size */ + font-size: 2vw; /* Múltiplos de 1% da largura da janela de exibição (CSS 3) */ + font-size: 2vh; /* Ou a sua altura */ + font-size: 2vmin; /* Qualquer um de VH ou um VW é menor */ + font-size: 2vmax; /* Ou superior */ + + /* Unidades absolutas */ + width: 200px; /* Píxeis */ + font-size: 20pt; /* Pontos */ + width: 5cm; /* Centímetros */ + min-width: 50mm; /* Milímetros */ + max-width: 5 polegadas; /* Polegadas */ + + /* Cores */ + color: #F6E; /* Formato hexadecimal curto */ + color: #FF66EE; /* Formato hexadecimal longo */ + color: tomato; /* Uma cor nomeada */ + color: rgb(255, 255, 255); /* Como valores rgb */ + color: RGB(10%, 20%, 50%); /* Como porcentagens rgb */ + color: rgba(255, 0, 0, 0,3); /* Como valores RGBA (CSS 3) NOTA: 0 <a <1 */ + color: transparent; /* Equivale a definir o alfa a 0 */ + color: HSL(0, 100%, 50%); /* Como porcentagens HSL (CSS 3) */ + color: HSLA(0, 100%, 50%, 0,3); /* Como porcentagens HSLA com alfa */ + + /* Imagens como fundos de elementos */ + background-image: url(/img-path/img.jpg); /* O uso das aspas dentro de url() é opcional */ + + /* Fontes */ + font-family: Arial; + /* Se o nome da família de fonte tem um espaço, deve estar entre aspas */ + font-family: "Courier New"; + /* Se o primeiro não for encontrada, o navegador usa a próxima, e assim por diante */ + font-family: "Courier New", Trebuchet, Arial, sans-serif; } ``` ## Uso -Salvar uma folha de estilo CSS com a extensão `.css`. +Salve o arquivo de estilos CSS com a extensão `.css`. -```xml -<!-- Você precisa incluir o arquivo css no da sua página <head>. Isto é o - método recomendado. Consulte http://stackoverflow.com/questions/8284365 --> -<link rel='stylesheet' type='text/css' href='path/to/style.css' /> +```html +<!-- Você precisa incluir o arquivo css dentro da tag <head>. Esse é o + método recomendado. Consulte http://stackoverflow.com/questions/8284365 --> +<link rel="stylesheet" type="text/css" href="path/to/style.css" /> -<!-- Você também pode incluir alguns CSS inline na sua marcação. --> +<!-- Você também pode incluir alguns CSS inline no seu HTML. --> <style> - a { color: purple; } + a { color: purple; } </style> -<!-- Ou diretamente definir propriedades CSS no elemento. --> +<!-- Ou definir propriedades CSS diretamente no elemento. --> <div style="border: 1px solid red;"> </div> ``` ## Precedência ou Cascata -Um elemento pode ser alvo de vários seletores e pode ter um conjunto de propriedades em que mais de uma vez. Nestes casos, uma das regras tem precedência sobre as outras. Geralmente, uma regra em um seletor mais específico têm precedência sobre um menos específico, e uma regra que ocorre mais tarde na folha de estilo substitui uma anterior. +Um elemento pode ser alvo de vários seletores e pode ter um conjunto de propriedades que +são adicionados mais de uma vez. Nestes casos, uma das regras tem precedência sobre as +outras. Geralmente, uma regra em um seletor mais específico têm precedência sobre um +menos específico, e uma regra que ocorre mais tarde na folha de estilo substitui uma anterior. -Este processo é chamado de cascata, portanto, as Fichas de nome de estilo em cascata. +Este processo é chamado de cascata, daí vem o nome: Cascading Style Sheets (Folhas de Estilo em Cascata). Dado o seguinte CSS: ```css -/* UMA */ +/* A */ p.class1[attr="value"] /* B */ @@ -225,20 +230,22 @@ p { property: value !important; } e a seguinte marcação: -```xml +```html <p style='/*F*/ property:value;' class='class1 class2' attr='value' /> ``` -A precedência de estilo é a seguinte. Lembre-se, a precedência é para cada **propriedade**, não para todo o bloco. +A precedência de estilo é a seguinte: Lembre-se, a precedência se aplica a +cada **propriedade**, não ao bloco como um todo. -* `E` tem a precedência mais alta por causa de uma palavra-chave`!important`. É recomendável que você evitar seu uso. -* `F` é a próxima, porque é um estilo interno. -* `A` é a próxima, porque é mais" específico "do que qualquer outra coisa. Tem 3 especificadores: O nome do elemento `p`, o seu `class1` classe, um atributo `attr='value'`. -* `C` está próximo, mesmo que ele tenha a mesma especificidade que `B`. Isso é porque ele aparece depois de `B`. -* `B` é o próximo. -* `D` é a última. +* `E` tem a precedência mais alta por causa de uma palavra-chave`!important`. É recomendado evitar seu uso. +* `F` é o seguinte, porque é um estilo interno. +* `A` é o seguinte, porque é "mais específico" do que os outros. Tem 3 especificadores: O nome do elemento `p`, a sua classe `class1` e um atributo `attr="value"`. +* `C` é o seguinte, mesmo que ele tenha a mesma especificidade que `B`. Isso acontece porque ele aparece logo após o `B`. +* `B` é o seguinte. +* `D` é o último. ## Media Queries + Media queries são recursos do CSS3 que permitem especificar quando determinadas regras de CSS devem ser aplicadas; é possível aplicar regras diferentes quando a página é impressa, quando a tela possui determinadas dimensões ou densidade de pixels e quando é lida por um leitor de tela. Media queries não adicionam especificidade ao seletor. ```css @@ -265,7 +272,8 @@ h1 { } } ``` -Media queries podem incluir os seguintes atributos: `width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. A maioria desses atributos pode ser prefixada com `min-` ou `max-`. + +Media queries podem incluir os seguintes atributos: `width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan` e `grid`. A maioria desses atributos pode ser prefixada com `min-` ou `max-`. O atributo `resolution` não é suportado em dispositivos mais antigos. Em vez disso, use `device-pixel-ratio`. @@ -279,20 +287,22 @@ Muitos smartphones e tablets tentarão renderizar a página como se estivesse nu ## Compatibilidade -A maior parte dos recursos do CSS 2 (e muitos em CSS 3) estão disponíveis em todos os navegadores e dispositivos. Mas é sempre boa prática verificar antes de usar um novo recurso. +A maioria dos recursos do CSS 2 (e muitos do CSS 3) está disponível em todos os navegadores +e dispositivos. -## Recursos +## Recursos Adicionais * Para executar uma verificação de compatibilidade rápida, [CanIUse](http://caniuse.com). * CSS Playground [Dabblet](http://dabblet.com/). -* [Documentação CSS Mozilla Developer Rede](https://developer.mozilla.org/en-US/docs/Web/CSS) -* [Codrops 'Referência CSS](http://tympanus.net/codrops/css_reference/) +* [Documentação CSS Mozilla Developer](https://developer.mozilla.org/en-US/docs/Web/CSS) +* [Codrops Referência CSS](http://tympanus.net/codrops/css_reference/) +* [DevTips CSS Basics](https://www.youtube.com/playlist?list=PLqGj3iMvMa4IOmy04kDxh_hqODMqoeeCy) (Tutorials) ## Leitura adicional * [Entendendo Estilo Precedência em CSS: Especificidade, Herança, e o Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) * [Selecionando elementos usando atributos](https://css-tricks.com/almanac/selectors/a/attribute/) * [QuirksMode CSS](http://www.quirksmode.org/css/) -* [Z-Index - O empilhamento context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) -* [SASS](http://sass-lang.com/) e [Less](http://lesscss.org/) para CSS pré-processamento +* [Z-Index - O contexto de empilhamento](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) +* [SASS](http://sass-lang.com/) e [Less](http://lesscss.org/) para pré-processamento do CSS * [CSS-Tricks](https://css-tricks.com) diff --git a/pt-br/d-pt.html.markdown b/pt-br/d-pt.html.markdown new file mode 100644 index 00000000..ae4bab22 --- /dev/null +++ b/pt-br/d-pt.html.markdown @@ -0,0 +1,262 @@ +--- +language: D +filename: learnd-pt.d +contributors: + - ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"] +translators: + - ["Julio Vanzelli", "https://github.com/JulioVanzelli"] +lang: pt-br +--- + +```d +// Você sabe o que está por vir... +module hello; + +import std.stdio; + +// args é opcional +void main(string[] args) { + writeln("Hello, World!"); +} +``` + +Se você é como eu e passa muito tempo na Internet, é provável que tenha ouvido +sobre [D] (http://dlang.org/). A linguagem de programação D é moderna, de uso geral, +linguagem multiparadigma com suporte para tudo, desde recursos de baixo nível até +abstrações expressivas de alto nível. + +D é desenvolvido ativamente por um grande grupo de pessoas super-inteligentes e é liderado por +[Walter Bright] (https://en.wikipedia.org/wiki/Walter_Bright) e +[Andrei Alexandrescu] (https://en.wikipedia.org/wiki/Andrei_Alexandrescu). +Com tudo isso fora do caminho, vamos dar uma olhada em alguns exemplos! + +```d +import std.stdio; + +void main() { + + // Condicionais e loops funcionam como esperado. + for(int i = 0; i < 10000; i++) { + writeln(i); + } + + // 'auto' pode ser usado para inferir tipos. + auto n = 1; + + // literais numéricos podem usar '_' como um separador de dígitos para maior clareza. + while(n < 10_000) { + n += n; + } + + do { + n -= (n / 2); + } while(n > 0); + + // Por e enquanto são bons, mas em D-land preferimos loops 'foreach'. + // O '..' cria um intervalo contínuo, incluindo o primeiro valor + // mas excluindo o último. + foreach(n; 1..1_000_000) { + if(n % 2 == 0) + writeln(n); + } + + // Há também 'foreach_reverse' quando você deseja fazer um loop para trás. + foreach_reverse(n; 1..int.max) { + if(n % 2 == 1) { + writeln(n); + } else { + writeln("No!"); + } + } +} +``` + +Podemos definir novos tipos com `struct`,` class`, `union` e` enum`. Estruturas e uniões +são passados para funções por valor(ou seja, copiados) e as classes são passadas por referência. Além disso, +podemos usar modelos para parametrizar tudo isso em tipos e valores! + +```d +// Aqui, 'T' é um parâmetro de tipo. Pense '<T>' em C++/C#/Java. +struct LinkedList(T) { + T data = null; + + // Usar '!' para instanciar um tipo parametrizado. Mais uma vez, pense '<T>'. + LinkedList!(T)* next; +} + +class BinTree(T) { + T data = null; + + // Se houver apenas um parâmetro de modelo, podemos omitir os parênteses. + BinTree!T left; + BinTree!T right; +} + +enum Day { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, +} + +// Use o alias para criar abreviações para tipos. +alias IntList = LinkedList!int; +alias NumTree = BinTree!double; + +// Também podemos criar modelos de funções! +T max(T)(T a, T b) { + if(a < b) + return b; + + return a; +} + +// Use a palavra-chave ref para garantir a passagem por referência. Ou seja, mesmo que 'a' +// e 'b' sejam tipos de valor, eles sempre serão passados por referência a 'swap ()'. +void swap(T)(ref T a, ref T b) { + auto temp = a; + + a = b; + b = temp; +} + +// Com os modelos, também podemos parametrizar valores, não apenas tipos. +class Matrix(uint m, uint n, T = int) { + T[m] rows; + T[n] columns; +} + +auto mat = new Matrix!(3, 3); // O tipo 'T' foi padronizado como 'int'. + +``` + +Falando em aulas, vamos falar sobre propriedades por um segundo. Uma propriedade +é aproximadamente uma função que pode agir como um valor I, para que possamos +ter a sintaxe das estruturas POD (`structure.x = 7`) com a semântica de +métodos getter e setter (`object.setX (7)`)! + +```d +// Considere uma classe parametrizada nos tipos 'T' e 'U'. +class MyClass(T, U) { + T _data; + U _other; +} + +// E os métodos "getter" e "setter", assim: +class MyClass(T, U) { + T _data; + U _other; + + // Os construtores sempre são chamados de 'this'. + this(T t, U u) { + // This will call the setter methods below. + data = t; + other = u; + } + + // getters + @property T data() { + return _data; + } + + @property U other() { + return _other; + } + + // setters + @property void data(T t) { + _data = t; + } + + @property void other(U u) { + _other = u; + } +} + +// E nós os usamos desta maneira: +void main() { + auto mc = new MyClass!(int, string)(7, "seven"); + + // Importe o módulo 'stdio' da biblioteca padrão para gravar no + // console (as importações podem ser locais para um escopo). + import std.stdio; + + // Ligue para os getters para buscar os valores. + writefln("Earlier: data = %d, str = %s", mc.data, mc.other); + + // Ligue para os setters para atribuir novos valores. + mc.data = 8; + mc.other = "eight"; + + // Ligue para os getters novamente para buscar os novos valores. + writefln("Later: data = %d, str = %s", mc.data, mc.other); +} +``` + +Com propriedades, podemos adicionar qualquer quantidade de lógica para +nossos métodos getter e setter, e mantenha a sintaxe limpa de +acessando membros diretamente! + +Outras guloseimas orientadas a objetos à nossa disposição, +incluem interfaces, classes abstratas, +e métodos de substituição. D faz herança como Java: +Estenda uma classe, implemente quantas interfaces você desejar. + +Vimos as instalações OOP de D, mas vamos mudar de marcha. D oferece +programação funcional com funções de primeira classe, `pura` +funções e dados imutáveis. Além disso, todos os seus favoritos +algoritmos funcionais (mapear, filtrar, reduzir e amigos) podem ser +encontrado no maravilhoso módulo `std.algorithm`! + +```d +import std.algorithm : map, filter, reduce; +import std.range : iota; // cria uma gama exclusiva de final + +void main() { + // Queremos imprimir a soma de uma lista de quadrados de ints pares + // de 1 a 100. Fácil! + + // Basta passar expressões lambda como parâmetros de modelo! + // Você pode passar qualquer função que desejar, mas as lambdas são convenientes aqui. + auto num = iota(1, 101).filter!(x => x % 2 == 0) + .map!(y => y ^^ 2) + .reduce!((a, b) => a + b); + + writeln(num); +} +``` + +Observe como conseguimos construir um bom pipeline haskelliano para calcular num? +Isso se deve a uma inovação em D, conhecida como Uniform Function Call Syntax (UFCS). +Com o UFCS, podemos optar por escrever uma chamada de função como método +ou chamada de função grátis! Walter escreveu um bom artigo sobre isso +[aqui.] (http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394) +Em resumo, você pode chamar funções cujo primeiro parâmetro +é de algum tipo A em qualquer expressão do tipo A como método. + +Eu gosto de paralelismo. Alguém mais gosta de paralelismo? Com certeza. Vamos fazer um pouco! + +```d +// Digamos que queremos preencher uma matriz grande com a raiz quadrada de todos +// os números inteiros consecutivos começando de 1 (até o tamanho da matriz), e queremos +// fazer isso simultaneamente, aproveitando o número de núcleos que temos +// disponível. + +import std.stdio; +import std.parallelism : parallel; +import std.math : sqrt; + +void main() { + // Crie sua grande variedade + auto arr = new double[1_000_000]; + + // Use um índice, acesse todos os elementos da matriz por referência (porque vamos + // mudar cada elemento) e apenas chame paralelo na matriz! + foreach(i, ref elem; parallel(arr)) { + elem = sqrt(i + 1.0); + } +} +``` diff --git a/pt-br/elixir-pt.html.markdown b/pt-br/elixir-pt.html.markdown index 4ba78f52..18441ff7 100644 --- a/pt-br/elixir-pt.html.markdown +++ b/pt-br/elixir-pt.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -20,7 +20,7 @@ e muitos outros recursos. # Não há comentários de múltiplas linhas, # mas você pode empilhar os comentários. -# Para usar o shell do elixir use o comando `iex`. +# Para usar o shell do Elixir use o comando `iex`. # Compile seus módulos com o comando `elixirc`. # Ambos devem estar em seu path se você instalou o Elixir corretamente. @@ -51,7 +51,7 @@ elem({1, 2, 3}, 0) #=> 1 head #=> 1 tail #=> [2,3] -# Em elixir, bem como em Erlang, o sinal `=` denota pattern match, +# Em Elixir, bem como em Erlang, o sinal `=` denota pattern match, # e não uma atribuição. # # Isto significa que o que estiver à esquerda (pattern) é comparado com o que @@ -85,7 +85,7 @@ linhas. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` em elixir retorna o valor ASCII para a letra `a` +# `?a` em Elixir retorna o valor ASCII para a letra `a` ?a #=> 97 # Para concatenar listas use `++`, para binários use `<>` @@ -98,7 +98,7 @@ linhas. # Ranges são representados como `início..fim` (ambos inclusivos) 1..10 #=> 1..10 menor..maior = 1..10 # Pattern matching pode ser usada em ranges também -[lower, upper] #=> [1, 10] +[menor, maior] #=> [1, 10] ## --------------------------- ## -- Operadores @@ -110,7 +110,7 @@ menor..maior = 1..10 # Pattern matching pode ser usada em ranges também 5 * 2 #=> 10 10 / 2 #=> 5.0 -# Em elixir o operador `/` sempre retorna um float. +# Em Elixir o operador `/` sempre retorna um float. # Para divisão de inteiros use `div` div(10, 2) #=> 5 @@ -167,7 +167,7 @@ else "Isso será" end -# Lembra do patter matching? Muitas estruturas de fluxo de controle em elixir contam com ela. +# Lembra do pattern matching? Muitas estruturas de fluxo de controle em Elixir contam com ela. # `case` nos permite comparar um valor com muitos patterns: case {:um, :dois} do @@ -296,7 +296,7 @@ Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 -# Devido à imutabilidade, recursão é uma grande parte do elixir +# Devido à imutabilidade, recursão é uma grande parte do Elixir defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) @@ -309,7 +309,7 @@ end Recursion.sum_list([1,2,3], 0) #=> 6 -# Módulos do elixir suportam atributos, hpa atributos embutidos e você +# Módulos do Elixir suportam atributos, hpa atributos embutidos e você # pode também adicionar os seus próprios. defmodule MyMod do @moduledoc """ @@ -361,7 +361,7 @@ end ## --------------------------- # Elixir conta com o modelo de ator para concorrência. Tudo o que precisamos para -# escrever programas concorrentes em elixir são três primitivos: spawning processes, +# escrever programas concorrentes em Elixir são três primitivos: spawning processes, # sending messages e receiving messages. # Para iniciar um novo processo usamos a função `spawn`, a qual leva uma função diff --git a/pt-br/emacs-pt.html.markdown b/pt-br/emacs-pt.html.markdown new file mode 100644 index 00000000..7a86a119 --- /dev/null +++ b/pt-br/emacs-pt.html.markdown @@ -0,0 +1,60 @@ +--- +category: tool +tool: emacs +filename: emacs.txt +contributors: + - ["Joseph Riad", "https://github.com/Joseph-Riad"] +translators: + - ["André de Santa Gabriel", "https://github.com/andredesanta"] +lang: pt-br +--- + +O Emacs começou sua vida como (https://www.gnu.org/software/emacs/emacs-paper.html) e cresceu +ao longo dos anos em um ecossistema completo. Muitas tarefas, geralmente +relegado a um conjunto diversificado de ferramentas pode ser realizado de dentro +Emacs em uma interface consistente e familiar. Exemplos incluem +gerenciamento de diretório, visualização de documentos PDF, edição de arquivos via SSH, gerenciamento de +repos git. Em suma, o Emacs é seu para fazer +o que você quiser: o espectro de usuários varia daqueles que o usam para +editar arquivos de texto para puristas extremos que o usam para substituir virtualmente seu +sistema operacional. + +O Emacs é extensível através de um dialeto especializado do Lisp conhecido como Emacs +Lisp (Elisp), que possui muitas macros voltadas para a edição de texto e +gerenciamento de buffers de texto. Qualquer tecla (combinação) usada no Emacs está vinculada +para uma função Emacs Lisp e pode ser remapeado para qualquer outra função, +incluindo aqueles que você escreve +você mesmo. + +# Conceitos básicos de Emacs + +Aqui, discuto alguns conceitos e terminologia básicos do Emacs que podem ser +confusos para os recém-chegados (especialmente para as pessoas acostumadas à terminologia do Vim): + + - O texto que o Emacs está editando é conhecido como **buffer** + + - Um buffer não corresponde necessariamente a um arquivo real no disco. Pode ser apenas texto na memória. + + - Quando um buffer corresponde a um arquivo no disco, dizemos que o buffer está **visitando** esse arquivo. + + - O Emacs normalmente possui muitos buffers abertos ao mesmo tempo. + + - A exibição do Emacs pode ser dividida em diferentes **windows**. + + - Uma janela do sistema operacional para o Emacs é chamada de **frame**. Assim, quando o manual do Emacs fala sobre a abertura de um novo frame, esse essencialmente significa abrir uma nova janela do SO contendo uma (outra) instância do Emacs. + + - Os conceitos convencionalmente conhecidos como recortar e colar são referido como **killing** e **yanking**, respectivamente no Emacs. + + - A posição atual do cursor é chamada de **point** no Emacs. Tecnicamente, **point** é definido como a posição imediatamente antes do caractere onde o cursor está atualmente. + + - Finalmente, cada buffer pode ter vários **modes** associados: o **major mode** e possivelmente vários **minor modes**. + + - O **major mode** define o principal comportamento do Emacs no buffer atualmente selecionado. Isso pode ser pensado como o tipo de arquivo. Por exemplo, se você estiver editando um arquivo Python, os principais modes é (por padrão) `python-mode`, que faz com que o Emacs destaque a sintaxe Python e idente automaticamente seus blocos de código conforme exigido sintaticamente pelo seu código Python. + + - **Minor modes** definem mudanças sutis no comportamento e várias alterações menores Os modos podem estar ativos ao mesmo tempo no mesmo buffer. Um exemplo menor modo é o modo flyspell, que destaca automaticamente os erros de ortografia no seu buffer. + +# Recursos adicionais + + - [The GNU Emacs Manual](https://www.gnu.org/software/emacs/manual/emacs.html) + - [Emacs Stack Exchange](https://emacs.stackexchange.com/) + - [Emacs Wiki](https://www.emacswiki.org/emacs/EmacsWiki) diff --git a/pt-br/go-pt.html.markdown b/pt-br/go-pt.html.markdown index f68d63eb..ce10e079 100644 --- a/pt-br/go-pt.html.markdown +++ b/pt-br/go-pt.html.markdown @@ -77,7 +77,7 @@ pode incluir quebras de linha.` // mesmo tipo string // literal não-ASCII. A linguagem Go utiliza de raiz a codificação UTF-8. g := 'Σ' // tipo rune, um alias para int32, que contém um código unicode - f := 3.14195 // float64, número de vírgula flutuante de 64bit (IEEE-754) + f := 3.14159 // float64, número de vírgula flutuante de 64bit (IEEE-754) c := 3 + 4i // complex128, representado internamente com dois float64s // Declaração de variáveis, com inicialização. @@ -295,17 +295,17 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { ## Leitura Recomendada -A principal fonte de informação é o [web site oficial Go](http://golang.org/). +A principal fonte de informação é o [web site oficial Go](https://go.dev/). Lá é possível seguir o tutorial, experimentar de forma iterativa, e ler muito. A própria especificação da linguagem é altamente recomendada. É fácil de ler e incrivelmente curta (em relação ao que é habitual hoje em dia). Na lista de leitura para os aprendizes de Go deve constar o [código fonte da -biblioteca padrão](http://golang.org/src/pkg/). Exaustivamente documentado, é +biblioteca padrão](https://go.dev/src/). Exaustivamente documentado, é a melhor demonstração de código fácil de ler e de perceber, do estilo Go, e da sua escrita idiomática. Ou então clique no nome de uma função na [documentação] -(http://golang.org/pkg/) e veja o código fonte aparecer! +(https://go.dev/pkg/) e veja o código fonte aparecer! Outra ótima fonte para aprender Go é o [Go by example](https://gobyexample.com/). Apesar de ser em inglês, é possível recodificar os exemplos para aprender sobre diff --git a/pt-br/httpie-pt.html.markdown b/pt-br/httpie-pt.html.markdown new file mode 100644 index 00000000..f81919fe --- /dev/null +++ b/pt-br/httpie-pt.html.markdown @@ -0,0 +1,122 @@ +--- +category: tool +tool: httpie +filename: learn-httpie-pt.sh +contributors: + - ["Adaías Magdiel", "https://github.com/AdaiasMagdiel"] +translators: + - ["Adaías Magdiel", "https://adaiasmagdiel.com/"] +lang: pt-br +--- + +HTTPie é um poderoso cliente HTTP para linha de comando, projetado para uma +integração suave com servidores HTTP. Oferece uma interface simples e intuitiva, +tornando-se uma excelente ferramenta para desenvolvedores, testadores e administradores de sistemas. + +## Uso Básico + +HTTPie possui uma sintaxe simples: http [flags] [MÉTODO] URL [itens]. + +```bash +http GET https://api.example.com/posts +``` + +Você pode exibir a requisição sem executá-la, de fato, usando a flag `--offline`. + +```bash +http --offline https://api.example.com/posts +``` + +### Encurtando URLs `localhost` + +HTTPie fornece suporte a atalhos para o localhost, similares aos do `curl`. Por exemplo, ":3000" +expande para "http://localhost:3000". Se a porta for omitida, o padrão será a porta 80. + +```bash +http :/users # http://localhost/users +http :5000/rss # http://localhost:5000/rss +``` + +### Métodos Opcionais GET e POST + +Se você não especificar o método, o HTTPie usará o seguinte: + +- GET para requisições sem corpo +- POST para requisições com corpo + +```bash +http https://api.example.com/tags # GET - Seleciona as tags +http https://api.example.com/tags title="Tutorial" slug="tutorial" # POST - Cria uma nova tag +``` + +## Parâmetros Querystring + +Se você adiciona querystrings manualmente no terminal, tente a seguinte sintaxe: +`param==value`. Isso evita que o shell tente reconhecer o operador & como comando +e automaticamente escape caracteres especiais nos parâmetros. +Isso difere dos parâmetros na URL completa, que o HTTPie não modifica. + +```bash +http https://api.example.com/search q==httpie per_page==20 +``` + +## Enviando Dados + +Você pode enviar dados nos mais diversos formatos, como JSON, formulários ou arquivos. + +### Enviando JSON + +```bash +http POST https://api.example.com/posts title="Olá" body="Mundo" +``` + +### Enviando Formulário + +```bash +http -f POST https://api.example.com/submit name=John email=john@example.com +``` + +### Enviando Arquivos + +```bash +http --form POST https://api.example.com/upload file@/caminho/do/arquivo.txt +``` + +## Headers e Autenticação + +HTTPie permite que você adicione headers e lide com autenticação de uma forma fácil. + +### Headers + +```bash +http GET https://api.example.com/posts Authorization:"Bearer Token" User-Agent:"HTTPie" +``` + +### Autenticação Básica + +```bash +http -a usuario:senha GET https://api.example.com/protected +``` + +### Autenticação Bearer + +```bash +https -A bearer -a token https://api.example.com/admin +``` + +## Lidando com Respostas + +HTTPie fornece várias opções para lidar com respostas. + +```bash +http GET https://api.example.com/data Accept:application/json # Exibe o JSON de uma forma legível + +http GET https://api.example.com/image --output image.png # Grava a resposta em um arquivo + +http --follow GET https://example.com # Segue redirecionamentos +``` + +## Leitura Adicional + +- [Documentação Oficial](https://httpie.io/docs/cli). +- [GitHub](https://github.com/httpie). diff --git a/pt-br/make-pt.html.markdown b/pt-br/make-pt.html.markdown index 40ac733a..d908435a 100644 --- a/pt-br/make-pt.html.markdown +++ b/pt-br/make-pt.html.markdown @@ -1,245 +1,245 @@ ----
-category: tool
-tool: make
-contributors:
- - ["Robert Steed", "https://github.com/robochat"]
- - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
-translators:
- - ["Rogério Gomes Rio", "https://github.com/rogerlista"]
-filename: Makefile-pt
-
-lang: pt-br
----
-
-Um Makefile define um gráfico de regras para criar um alvo (ou alvos). Sua finalidade é fazer o mínimo de trabalho necessário para atualizar um alvo para a versão mais recente da fonte. Famosamente escrito ao longo de um fim de semana por Stuart Feldman em 1976, ainda é amplamente usada (particularmente no Unix e no Linux) apesar de muitos concorrentes e críticas.
-
-Existem muitas variedades de make na existência, no entanto, este artigo pressupõe que estamos usando o GNU make, que é o padrão no Linux.
-
-```make
-
-# Comentários podem ser escritos assim.
-
-# O arquivo deve ser nomeado Makefile e então pode ser executado como `make <alvo>`.
-# Caso contrário, nós usamos `make -f "nome-do-arquivo" <alvo>`.
-
-# Aviso - use somente TABS para identar em Makefiles, nunca espaços!
-
-#-----------------------------------------------------------------------
-# Noções básicas
-#-----------------------------------------------------------------------
-
-# Regras são do formato
-# alvo: <pré-requisito>
-# onde os pré-requisitos são opcionais.
-
-# Uma regra - esta regra só será executada se o arquivo0.txt não existir.
-arquivo0.txt:
- echo "foo" > arquivo0.txt
- # Mesmo os comentários nestas seções da 'receita' são passados para o shell.
- # Experimentar `make arquivo0.txt` or simplyou simplesmente `make` - primeira regra é o padrão.
-
-# Esta regra só será executada se arquivo0.txt for mais recente que arquivo1.txt.
-arquivo1.txt: arquivo0.txt
- cat arquivo0.txt > arquivo1.txt
- # se as mesmas regras de citação do shell.
- @cat arquivo0.txt >> arquivo1.txt
- # @ pára o comando de ser ecoado para stdout.
- -@echo 'hello'
- # - significa que make continuará em caso de erro.
- # Experimentar `make arquivo1.txt` na linha de comando.
-
-# Uma regra pode ter vários alvos e vários pré-requisitos
-arquivo2.txt arquivo3.txt: arquivo0.txt arquivo1.txt
- touch arquivo2.txt
- touch arquivo3.txt
-
-# Make vai reclamar sobre várias receitas para a mesma regra. Esvaziar
-# receitas não contam e podem ser usadas para adicionar novas dependências.
-
-#-----------------------------------------------------------------------
-# Alvos falsos
-#-----------------------------------------------------------------------
-
-# Um alvo falso. Qualquer alvo que não seja um arquivo.
-# Ele nunca será atualizado, portanto, o make sempre tentará executá-lo.
-all: maker process
-
-# Podemos declarar as coisas fora de ordem.
-maker:
- touch ex0.txt ex1.txt
-
-# Pode evitar quebrar regras falsas quando um arquivo real tem o mesmo nome
-.PHONY: all maker process
-# Este é um alvo especial. Existem vários outros.
-
-# Uma regra com dependência de um alvo falso sempre será executada
-ex0.txt ex1.txt: maker
-
-# Alvos falsos comuns são: todos fazem instalação limpa ...
-
-#-----------------------------------------------------------------------
-# Variáveis Automáticas e Curingas
-#-----------------------------------------------------------------------
-
-process: Arquivo*.txt # Usando um curinga para corresponder nomes de arquivos
- @echo $^ # $^ é uma variável que contém a lista de pré-requisitos
- @echo $@ # imprime o nome do alvo
- #(fpara várias regras alvo, $@ é o que causou a execução da regra)
- @echo $< # o primeiro pré-requisito listado
- @echo $? # somente as dependências que estão desatualizadas
- @echo $+ # todas as dependências, incluindo duplicadas (ao contrário do normal)
- #@echo $| # todos os pré-requisitos 'somente pedidos'
-
-# Mesmo se dividirmos as definições de dependência de regra, $^ vai encontrá-los
-process: ex1.txt arquivo0.txt
-# ex1.txt será encontrado, mas arquivo0.txt será desduplicado.
-
-#-----------------------------------------------------------------------
-# Padrões
-#-----------------------------------------------------------------------
-
-# Pode ensinar make a converter certos arquivos em outros arquivos.
-
-%.png: %.svg
- inkscape --export-png $^
-
-# As regras padrões só farão qualquer coisa se decidirem criar o alvo.
-
-# Os caminhos de diretório são normalmente ignorados quando as regras de
-# padrões são correspondentes. Mas make tentará usar a regra mais
-# apropriada disponível.
-small/%.png: %.svg
- inkscape --export-png --export-dpi 30 $^
-
-# make utilizará a última versão para uma regra de padrão que encontrar.
-%.png: %.svg
- @echo esta regra é escolhida
-
-# No entanto, o make usará a primeira regra padrão que pode se tornar o alvo
-%.png: %.ps
- @echo esta regra não é escolhida se *.svg and *.ps estão ambos presentes
-
-# make já tem algumas regras padrões embutidas. Por exemplo, ele sabe
-# como transformar arquivos *.c em arquivos *.o.
-
-# Makefiles antigos podem usar regras de sufixo em vez de regras padrões
-.png.ps:
- @echo essa regra é semelhante a uma regra de padrão.
-
-# make sobre a regra de sufixo
-.SUFFIXES: .png
-
-#-----------------------------------------------------------------------
-# Variáveis
-#-----------------------------------------------------------------------
-# aka. macros
-
-# As variáveis são basicamente todos os tipos de string
-
-name = Ted
-name2="Sarah"
-
-echo:
- @echo $(name)
- @echo ${name2}
- @echo $name # Isso não funcionará, tratado como $ (n)ame.
- @echo $(name3) # Variáveis desconhecidas são tratadas como strings vazias.
-
-# Existem 4 lugares para definir variáveis.
-# Em ordem de prioridade, do maior para o menor:
-# 1: argumentos de linha de comando
-# 2: Makefile
-# 3: variáveis de ambiente do shell - faça importações automaticamente.
-# 4: make tem algumas variáveis predefinidas
-
-name4 ?= Jean
-# Somente defina a variável se a variável de ambiente ainda não estiver definida.
-
-override name5 = David
-# Pára os argumentos da linha de comando de alterar essa variável.
-
-name4 +=grey
-# Anexar valores à variável (inclui um espaço).
-
-# Valores variáveis específicos de padrões (extensão GNU).
-echo: name2 = Sara # Verdadeiro dentro da regra de correspondência
- # e também dentro de suas recursivas dependências
- # (exceto que ele pode quebrar quando seu gráfico ficar muito complicado!)
-
-# Algumas variáveis definidas automaticamente pelo make
-echo_inbuilt:
- echo $(CC)
- echo ${CXX}
- echo $(FC)
- echo ${CFLAGS}
- echo $(CPPFLAGS)
- echo ${CXXFLAGS}
- echo $(LDFLAGS)
- echo ${LDLIBS}
-
-#-----------------------------------------------------------------------
-# Variáveis 2
-#-----------------------------------------------------------------------
-
-# O primeiro tipo de variáveis é avaliado a cada vez que elas são usadas.
-# TIsso pode ser caro, então existe um segundo tipo de variável que é
-# avaliado apenas uma vez. (Esta é uma extensão do GNU make)
-
-var := hello
-var2 ::= $(var) hello
-#:= e ::= são equivalentes.
-
-# Essas variáveis são avaliadas procedimentalmente (na ordem em que
-# aparecem), quebrando assim o resto da línguagem!
-
-# Isso não funciona
-var3 ::= $(var4) and good luck
-var4 ::= good night
-
-#-----------------------------------------------------------------------
-# Funções
-#-----------------------------------------------------------------------
-
-# make tem muitas funções disponíveis.
-
-sourcefiles = $(wildcard *.c */*.c)
-objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
-
-# O formato é $(func arg0,arg1,arg2...)
-
-# Alguns exemplos
-ls: * src/*
- @echo $(filter %.txt, $^)
- @echo $(notdir $^)
- @echo $(join $(dir $^),$(notdir $^))
-
-#-----------------------------------------------------------------------
-# Diretivas
-#-----------------------------------------------------------------------
-
-# Inclua outros makefiles, úteis para código específico da plataforma
-include foo.mk
-
-sport = tennis
-# Compilação condicional
-report:
-ifeq ($(sport),tennis)
- @echo 'game, set, match'
-else
- @echo "They think it's all over; it is now"
-endif
-
-# Há também ifneq, ifdef, ifndef
-
-foo = true
-
-ifdef $(foo)
-bar = 'hello'
-endif
-```
-
-### More Resources
-
-+ [documentação gnu make](https://www.gnu.org/software/make/manual/)
-+ [tutorial de carpintaria de software](http://swcarpentry.github.io/make-novice/)
-+ aprenda C da maneira mais difícil [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
+--- +category: tool +tool: make +contributors: + - ["Robert Steed", "https://github.com/robochat"] + - ["Stephan Fuhrmann", "https://github.com/sfuhrm"] +translators: + - ["Rogério Gomes Rio", "https://github.com/rogerlista"] +filename: Makefile-pt + +lang: pt-br +--- + +Um Makefile define um gráfico de regras para criar um alvo (ou alvos). Sua finalidade é fazer o mínimo de trabalho necessário para atualizar um alvo para a versão mais recente da fonte. Famosamente escrito ao longo de um fim de semana por Stuart Feldman em 1976, ainda é amplamente usada (particularmente no Unix e no Linux) apesar de muitos concorrentes e críticas. + +Existem muitas variedades de make na existência, no entanto, este artigo pressupõe que estamos usando o GNU make, que é o padrão no Linux. + +```make + +# Comentários podem ser escritos assim. + +# O arquivo deve ser nomeado Makefile e então pode ser executado como `make <alvo>`. +# Caso contrário, nós usamos `make -f "nome-do-arquivo" <alvo>`. + +# Aviso - use somente TABS para identar em Makefiles, nunca espaços! + +#----------------------------------------------------------------------- +# Noções básicas +#----------------------------------------------------------------------- + +# Regras são do formato +# alvo: <pré-requisito> +# onde os pré-requisitos são opcionais. + +# Uma regra - esta regra só será executada se o arquivo0.txt não existir. +arquivo0.txt: + echo "foo" > arquivo0.txt + # Mesmo os comentários nestas seções da 'receita' são passados para o shell. + # Experimentar `make arquivo0.txt` or simplyou simplesmente `make` - primeira regra é o padrão. + +# Esta regra só será executada se arquivo0.txt for mais recente que arquivo1.txt. +arquivo1.txt: arquivo0.txt + cat arquivo0.txt > arquivo1.txt + # se as mesmas regras de citação do shell. + @cat arquivo0.txt >> arquivo1.txt + # @ pára o comando de ser ecoado para stdout. + -@echo 'hello' + # - significa que make continuará em caso de erro. + # Experimentar `make arquivo1.txt` na linha de comando. + +# Uma regra pode ter vários alvos e vários pré-requisitos +arquivo2.txt arquivo3.txt: arquivo0.txt arquivo1.txt + touch arquivo2.txt + touch arquivo3.txt + +# Make vai reclamar sobre várias receitas para a mesma regra. Esvaziar +# receitas não contam e podem ser usadas para adicionar novas dependências. + +#----------------------------------------------------------------------- +# Alvos falsos +#----------------------------------------------------------------------- + +# Um alvo falso. Qualquer alvo que não seja um arquivo. +# Ele nunca será atualizado, portanto, o make sempre tentará executá-lo. +all: maker process + +# Podemos declarar as coisas fora de ordem. +maker: + touch ex0.txt ex1.txt + +# Pode evitar quebrar regras falsas quando um arquivo real tem o mesmo nome +.PHONY: all maker process +# Este é um alvo especial. Existem vários outros. + +# Uma regra com dependência de um alvo falso sempre será executada +ex0.txt ex1.txt: maker + +# Alvos falsos comuns são: todos fazem instalação limpa ... + +#----------------------------------------------------------------------- +# Variáveis Automáticas e Curingas +#----------------------------------------------------------------------- + +process: Arquivo*.txt # Usando um curinga para corresponder nomes de arquivos + @echo $^ # $^ é uma variável que contém a lista de pré-requisitos + @echo $@ # imprime o nome do alvo + #(fpara várias regras alvo, $@ é o que causou a execução da regra) + @echo $< # o primeiro pré-requisito listado + @echo $? # somente as dependências que estão desatualizadas + @echo $+ # todas as dependências, incluindo duplicadas (ao contrário do normal) + #@echo $| # todos os pré-requisitos 'somente pedidos' + +# Mesmo se dividirmos as definições de dependência de regra, $^ vai encontrá-los +process: ex1.txt arquivo0.txt +# ex1.txt será encontrado, mas arquivo0.txt será desduplicado. + +#----------------------------------------------------------------------- +# Padrões +#----------------------------------------------------------------------- + +# Pode ensinar make a converter certos arquivos em outros arquivos. + +%.png: %.svg + inkscape --export-png $^ + +# As regras padrões só farão qualquer coisa se decidirem criar o alvo. + +# Os caminhos de diretório são normalmente ignorados quando as regras de +# padrões são correspondentes. Mas make tentará usar a regra mais +# apropriada disponível. +small/%.png: %.svg + inkscape --export-png --export-dpi 30 $^ + +# make utilizará a última versão para uma regra de padrão que encontrar. +%.png: %.svg + @echo esta regra é escolhida + +# No entanto, o make usará a primeira regra padrão que pode se tornar o alvo +%.png: %.ps + @echo esta regra não é escolhida se *.svg and *.ps estão ambos presentes + +# make já tem algumas regras padrões embutidas. Por exemplo, ele sabe +# como transformar arquivos *.c em arquivos *.o. + +# Makefiles antigos podem usar regras de sufixo em vez de regras padrões +.png.ps: + @echo essa regra é semelhante a uma regra de padrão. + +# make sobre a regra de sufixo +.SUFFIXES: .png + +#----------------------------------------------------------------------- +# Variáveis +#----------------------------------------------------------------------- +# aka. macros + +# As variáveis são basicamente todos os tipos de string + +name = Ted +name2="Sarah" + +echo: + @echo $(name) + @echo ${name2} + @echo $name # Isso não funcionará, tratado como $ (n)ame. + @echo $(name3) # Variáveis desconhecidas são tratadas como strings vazias. + +# Existem 4 lugares para definir variáveis. +# Em ordem de prioridade, do maior para o menor: +# 1: argumentos de linha de comando +# 2: Makefile +# 3: variáveis de ambiente do shell - faça importações automaticamente. +# 4: make tem algumas variáveis predefinidas + +name4 ?= Jean +# Somente defina a variável se a variável de ambiente ainda não estiver definida. + +override name5 = David +# Pára os argumentos da linha de comando de alterar essa variável. + +name4 +=grey +# Anexar valores à variável (inclui um espaço). + +# Valores variáveis específicos de padrões (extensão GNU). +echo: name2 = Sara # Verdadeiro dentro da regra de correspondência + # e também dentro de suas recursivas dependências + # (exceto que ele pode quebrar quando seu gráfico ficar muito complicado!) + +# Algumas variáveis definidas automaticamente pelo make +echo_inbuilt: + echo $(CC) + echo ${CXX} + echo $(FC) + echo ${CFLAGS} + echo $(CPPFLAGS) + echo ${CXXFLAGS} + echo $(LDFLAGS) + echo ${LDLIBS} + +#----------------------------------------------------------------------- +# Variáveis 2 +#----------------------------------------------------------------------- + +# O primeiro tipo de variáveis é avaliado a cada vez que elas são usadas. +# TIsso pode ser caro, então existe um segundo tipo de variável que é +# avaliado apenas uma vez. (Esta é uma extensão do GNU make) + +var := hello +var2 ::= $(var) hello +#:= e ::= são equivalentes. + +# Essas variáveis são avaliadas procedimentalmente (na ordem em que +# aparecem), quebrando assim o resto da línguagem! + +# Isso não funciona +var3 ::= $(var4) and good luck +var4 ::= good night + +#----------------------------------------------------------------------- +# Funções +#----------------------------------------------------------------------- + +# make tem muitas funções disponíveis. + +sourcefiles = $(wildcard *.c */*.c) +objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) + +# O formato é $(func arg0,arg1,arg2...) + +# Alguns exemplos +ls: * src/* + @echo $(filter %.txt, $^) + @echo $(notdir $^) + @echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Diretivas +#----------------------------------------------------------------------- + +# Inclua outros makefiles, úteis para código específico da plataforma +include foo.mk + +sport = tennis +# Compilação condicional +report: +ifeq ($(sport),tennis) + @echo 'game, set, match' +else + @echo "They think it's all over; it is now" +endif + +# Há também ifneq, ifdef, ifndef + +foo = true + +ifdef $(foo) +bar = 'hello' +endif +``` + +### More Resources + ++ [documentação gnu make](https://www.gnu.org/software/make/manual/) ++ [tutorial de carpintaria de software](http://swcarpentry.github.io/make-novice/) ++ aprenda C da maneira mais difícil [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) diff --git a/pt-br/markdown-pt.html.markdown b/pt-br/markdown-pt.html.markdown index 7960a59a..fca864bb 100644 --- a/pt-br/markdown-pt.html.markdown +++ b/pt-br/markdown-pt.html.markdown @@ -8,7 +8,7 @@ translators: - ["Monique Baptista", "https://github.com/bfmonique"] - ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"] -lang: pt-br +lang: pt-br filename: learnmarkdown-pt.md --- @@ -213,8 +213,8 @@ adicionais) para indentação no seu código. ```md my_array.each do |item| - puts item - end + puts item + end ``` Código embutido pode ser criado usando o caractere de crase `` ` ``. @@ -225,13 +225,13 @@ John não sabia nem o que a função `go_to()` fazia! No GitHub Flavored Markdown, você pode usar uma sintaxe especial para código. -<pre> -<code class="highlight">```ruby +````md +```ruby def foobar - puts "Olá mundo!" + puts "Olá mundo!" end -```</code></pre> - +``` +```` O texto acima não requer indentação, além disso o GitHub vai usar o destaque de sintaxe da linguagem qeu você especificar após a tag <code>```</code>. @@ -272,11 +272,13 @@ Caminhos relativos funcionam também. O Markdown também suporta links para referências no texto. -<pre><code class="highlight">[<span class="nv">Clique nesse link</span>][<span class="ss">link1</span>] para mais informações! -[<span class="nv">Também cheque esse link</span>][<span class="ss">foobar</span>] se você quiser. +```md +[Clique nesse link][link1] para mais informações! +[Também cheque esse link][foobar] se você quiser. -[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Legal!"</span> -[<span class="nv">link2r</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Certo!"</span></code></pre> +[link1]: http://test.com/ "Legal!" +[link2r]: http://foobar.biz/ "Certo!" +``` O título também pode estar entre aspas simples ou entre parênteses, ou omitido inteiramente. As referências podem estar em qualquer lugar no documento e os @@ -285,10 +287,11 @@ IDs de referência podem ser qualquer um, desde que eles sejam únicos. Existe também a "nomeação implícita", que permite que você use o texto do link como o id: -<pre><code class="highlight">[<span class="nv">Isso</span>][] é um link. - -[<span class="nv">Isso</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> +```md +[Isso][] é um link. +[Isso]: http://thisisalink.com/ +``` Mas geralmente não são usados. @@ -322,9 +325,11 @@ exclamação na frente! E estilo de referência funciona como esperado -<pre><code class="highlight">![<span class="nv">Esse é o alt-attribute.</span>][<span class="ss">myimage</span>] +```md +![Esse é o alt-attribute.][myimage] -[<span class="nv">Minha imagem</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"se precisar de um título, está aqui"</span></code></pre> +[Minha imagem]: relative/urls/cool/image.jpg "se precisar de um título, está aqui" +``` ## Miscelânea diff --git a/pt-br/pug-pt.html.markdown b/pt-br/pug-pt.html.markdown new file mode 100644 index 00000000..52eda86a --- /dev/null +++ b/pt-br/pug-pt.html.markdown @@ -0,0 +1,211 @@ +--- +language: Pug +contributors: + - ["Michael Warner", "https://github.com/MichaelJGW"] +filename: index-pt.pug +translators: + - ["Adaías Magdiel", "https://adaiasmagdiel.com/"] +lang: pt-br +--- + +## Começando com Pug + +Pug é uma pequena linguagem que compila para HTML. Possui uma sintaxe limpa +com algumas funcionalidades adicionais, como declarações if e loops. Também pode ser utilizada +como uma linguagem de templates no lado do servidor para tecnologias como o Node.js. + +### The Language +```pug + +//- Comentário de uma linha + +//- Comentário de + várias linhas + +//- ---TAGS--- +//- Básico +div +//- <div></div> +h1 +//- <h1></h1> +minha-propriaTag +//- <minha-propriaTag></minha-propriaTag> + +//- Tags irmãs +div +div +//- <div></div> + <div></div> + +//- Tags aninhadas +div + div +//- <div> + <div></div> + </div> + +//- Textos +h1 Olá, pessoas +//- <h1>Olá, pessoas</h1> + +//- Texto de várias linhas +div. + Oi, + tudo bem? +//- <div> + Oi, + tudo bem? + </div> + +//- ---ATRIBUTOS--- +div(class="minha-class" id="meu-id" meu-proprio-atributo="data" enabled) +//- <div class="minha-class" id="meu-id" meu-proprio-atributo="data" enabled></div> + +//- Abreviações +span.minha-class +//- <span class="minha-class"></span> +.minha-class +//- <div class="minha-class"></div> +div#meu-id +//- <div id="meu-id"></div> +div#meu-id.minha-class +//- <div class="minha-class" id="meu-id"></div> + + +//- ---JAVASCRIPT--- +- const lang = "pug"; + +//- Javascript em várias linhas +- + const lang = "pug"; + const awesome = true; + +//- Classes com Javascript +- const myClass = ['class1', 'class2', 'class3'] +div(class=myClass) +//- <div class="class1 class2 class3"></div> + +//- Estilos com Javascript +- const myStyles = {'color':'white', 'background-color':'blue'} +div(styles=myStyles) +//- <div styles="{"color":"white","background-color":"blue"}"></div> + +//- Atributos com Javascript +- const myAttributes = {"src": "photo.png", "alt": "My Photo"} +img&attributes(myAttributes) +//- <img src="photo.png" alt="My Photo"> +- let disabled = false +input(type="text" disabled=disabled) +//- <input type="text"> +- disabled = true +input(type="text" disabled=disabled) +//- <input type="text" disabled> + +//- Templates com Javascript +- const name = "Bob"; +h1 Olá, #{name} +h1= name +//- <h1>Olá, Bob</h1> +//- <h1>Bob</h1> + +//- ---LOOPS--- + +//- 'each' e 'for' tem a mesma função, aqui nós usaremos apenas 'each'. + +each value, i in [1,2,3] + p=value +//- + <p>1</p> + <p>2</p> + <p>3</p> + +each value, index in [1,2,3] + p=value + '-' + index +//- + <p>1-0</p> + <p>2-1</p> + <p>3-2</p> + +each value in [] + p=value +//- + +each value in [] + p=value +else + p Sem valores + +//- <p>Sem valores</p> + +//- ---CONDICIONAIS--- + +- const number = 5 +if number < 5 + p o número é menor do que 5 +else if number > 5 + p o número é maior do que 5 +else + p o número é 5 +//- <p>o número é 5</p> + +- const orderStatus = "Aguardando"; +case orderStatus + when "Aguardando" + p.warn Seu pedido está em espera + when "Completado" + p.success Seu pedido foi completado. + when -1 + p.error Ocorreu algum erro + default + p Nenhum registro de pedido encontrado +//- <p class="warn">Seu pedido está em espera</p> + +//- --INCLUINDO CONTEÚDOS-- +//- Caminho do arquivo -> "includes/nav.pug" +h1 Indústrias ACME +nav + a(href="index.html") Início + a(href="about.html") Sobre Nós + +//- Caminho do arquivo -> "index.pug" +html + body + include includes/nav.pug +//- + <html> + <body> + <h1>Indústrias ACME</h1> + <nav><a href="index.html">Início</a><a href="about.html">Sobre Nós</a></nav> + </body> + </html> + +//- Importando Javascript e CSS +script + include scripts/index.js +style + include styles/theme.css + +//- ---MIXIN--- +mixin basic + div Olá ++basic +//- <div>Olá</div> + +mixin comment(nome, comentario) + div + span.comment-name= nome + div.comment-text= comentario ++comment("Gil", "Tudo é divino, tudo é maravilhoso") +//- + <div> + <span class="comment-name">Gil</span> + <div class="comment-text">Tudo é divino, tudo é maravilhoso</div> + </div> + +``` + + +### Saiba Mais +- [Site Oficial](https://pugjs.org/) +- [Documentação](https://pugjs.org/api/getting-started.html) +- [Repositório no GitHub](https://github.com/pugjs/pug) diff --git a/pt-br/pyqt-pt.html.markdown b/pt-br/pyqt-pt.html.markdown index 40fe82d5..42f744e2 100644 --- a/pt-br/pyqt-pt.html.markdown +++ b/pt-br/pyqt-pt.html.markdown @@ -24,7 +24,7 @@ o pyqt! ```python import sys from PyQt4 import QtGui - + def window(): # Cria um objeto para a aplicação app = QtGui.QApplication(sys.argv) @@ -54,7 +54,7 @@ outros elementos. Aqui mostraremos como criar uma janela popup, muito útil para perguntar ao usuário qual decisão tomar ou exibir alguma informação. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -73,7 +73,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Essa função deve criar uma janela de diálogo com um botão, # aguarda ser clicado e encerra o programa def showdialog(): diff --git a/pt-br/sass-pt.html.markdown b/pt-br/sass-pt.html.markdown index 28df3c59..e5175857 100644 --- a/pt-br/sass-pt.html.markdown +++ b/pt-br/sass-pt.html.markdown @@ -4,6 +4,7 @@ filename: learnsass-pt.scss contributors: - ["Laura Kyle", "https://github.com/LauraNK"] - ["Sean Corrales", "https://github.com/droidenator"] + - ["Thalles Augusto", "https://github.com/Theslladev"] translators: - ["Gabriel Gomes", "https://github.com/gabrielgomesferraz"] - ["Cássio Böck", "https://github.com/cassiobsilva"] @@ -16,7 +17,7 @@ Sass (e outros pré-processadores, como [Less](http://lesscss.org/)) ajudam os d Sass tem duas opções de sintaxe diferentes para escolher. SCSS, que tem a mesma sintaxe de CSS, mas com os recursos adicionais de Sass. Ou Sass (a sintaxe original), que usa o recuo, em vez de chaves e ponto e vírgula. Este tutorial é escrito usando SCSS. -Se você já está familiarizado com CSS3, você será capaz de pegar Sass de forma relativamente rápida. Ele não fornece quaisquer novas opções de estilo, mas sim as ferramentas para escrever sua CSS de forma mais eficiente e fazer a manutenção mais fácilmente. +Se você já está familiarizado com CSS3, você será capaz de pegar Sass de forma relativamente rápida. Ele não fornece quaisquer novas opções de estilo, mas sim as ferramentas para escrever sua CSS de forma mais eficiente e fazer a manutenção mais facilmente. ```scss @@ -249,7 +250,7 @@ ul { /* '&' será substituído pelo selector pai (parent). */ /* Você também pode aninhar pseudo-classes. */ /* Tenha em mente que o excesso de nidificação vai fazer seu código menos sustentável. -Essas práticas também recomendam não vai mais de 3 níveis de profundidade quando nidificação. +Essas práticas também recomendam não mais de 3 níveis de profundidade quando nidificação. Por exemplo: */ @@ -379,7 +380,7 @@ body { /* Sass fornece os seguintes operadores: +, -, *, /, e %. estes podem ser úteis para calcular os valores diretamente no seu arquivos Sass em vez - de usar valores que você já calculados manualmente. O exemplo abaixo é + de usar valores que você já calcula manualmente. O exemplo abaixo é de um projeto simples de duas colunas. */ $content-area: 960px; diff --git a/pt-br/self-pt.html.markdown b/pt-br/self-pt.html.markdown index eb821474..0fadf58d 100644 --- a/pt-br/self-pt.html.markdown +++ b/pt-br/self-pt.html.markdown @@ -117,6 +117,7 @@ Múltiplas expressões são separadas por ponto final. ^ retorna imediatamente. ``` Blocos são realizados (completados) ao enviá-los a mensagem 'value' e herdando (imcumbir a) seus contextos: + ``` "retorna 0" [|x| diff --git a/pt-br/set-theory-pt.html.markdown b/pt-br/set-theory-pt.html.markdown new file mode 100644 index 00000000..58fd7979 --- /dev/null +++ b/pt-br/set-theory-pt.html.markdown @@ -0,0 +1,129 @@ +--- +category: Algorithms & Data Structures +name: Set theory +lang: pt-br +contributors: + - ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"] +translators: + - ["Bárbara Luz", "https://github.com/barbluz"] +--- + +Teoria de conjuntos é uma área da matemática que estuda conjuntos, suas operações e propriedades. +- Um conjunto é uma coleção de itens disjuntos. + +## Símbolos básicos + +### Operações +- a operação de união `∪`, significa "ou" +- a operação de interseção `∩`, que significa "e" +- a operação de exclusão `\`, significa "sem" ou "menos" +- a operação de conjunto complementar `'`, que significa "o inverso de" +- a operação de produto cartesiano `×`,que significa "o produto cartesiano de" + +### Outros símbolos +- `:` ou `|`, símbolos que significam "tal que" +- o símbolo de pertencimento `∈`, que significa "pertence a" +- o símbolo `⊆`, que significa "subconjunto de" (neste caso, o subconjunto pode ser igual ao conjunto) +- o símbolo `⊂`, que significa "subconjunto próprio" (neste caso, o subconjunto não pode ser igual ao conjunto) + +### Conjuntos canônicos +- `∅`, o conjunto vazio, isto é, o conjunto que não possui itens +- `ℕ`, o conjunto de todos os números naturais +- `ℤ`, o conjunto de todos os números inteiros +- `ℚ`, o conjunto de todos os números racionais +- `ℝ`, o conjunto de todos os números reais + +Existem algumas ressalvas sobre os conjuntos canônicos: +- Apesar de o conjunto vazio não conter itens, o conjunto vazio é subconjunto de si mesmo (e portanto de todos os outros conjuntos) +- Matemáticos geralmente não concordam sobre o zero ser um número natural e os livros tipicamente explicitam se o autor considera ou não o zero como um número natural + + +### Cardinalidade +A cardinalidade (ou tamanho) de um conjunto é determinado pela quantidade de itens no conjunto. O operador de cardinalidade é `|...|` + +Por exemplo, se `S = {1, 2, 4}`, então `|S| = 3`. + +### O Conjunto Vazio +- o conjunto vazio pode ser contruído em notação de conjuntos utilizando condições impossíveis, como por exemplo: `∅ = { x : x ≠ x }`, ou `∅ = { x : x ∈ N, x < 0 }` +- o conjunto vazio é sempre único (ou seja, existe um e apenas um conjunto vazio) +- o conjunto vazio é subconjunto de todos os conjuntos +- a cardinalidade do conjunto vazio é `0`, ou seja, `|∅| = 0`. + +## Representando conjuntos + +### Definição Literal +Um conjunto pode ser contruído literalmente fornecendo uma lista completa dos itens contigos no conjunto. Por exemplo `S = { a, b, c, d }` + +Listas longas podem ser encurtadas com reticências, desde que o contexto seja claro. Por exemplo, `E = { 2, 4, 6, 8, ... }` é claramente o conjunto de todos os números pares, contendo um número infinito de objetos, embora só tenhamos escrito explicitamente quatro deles. + +### Definição por compreensão +Conjuntos também podem ser descritos de uma maneira mais descritiva, baseando-se em sujeito e predicado, de forma tal que `S = {sujeito : predicado}`. Por exemplo: + +``` +A = { x : x é uma vogal } = { a, e, i, o, u } (lê-se x, tal que x é uma vogal) +B = { x : x ∈ N, x < 10 } = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } +C = { x : x = 2k, k ∈ N } = { 0, 2, 4, 6, 8, ... } +``` + +Ou pode-se também aplicar uma função ao sujeito, ex: +``` +D = { 2x : x ∈ N } = { 0, 2, 4, 6, 8, ... } +``` + +## Relações + +### Pertencimento +- Se um valor `a` está contido num conjunto `A`, então dizemos que `a` pertence a `A` e denotamos por `a ∈ A` +- Se o valor `a` não está contido no conjunto `A`, então dizemos que `a` não pertence a `A` e denotamos por `a ∉ A` + +### Igualdade +- Se dois conjuntos contém os mesmos itens, então dizemos que os conjuntos são iguals, ex. `A = B` +- A ordenação não importa quando vamos avaliar a igualdade, ex: `{ 1, 2, 3, 4 } = { 2, 3, 1, 4 }` +- Conjuntos são disjuntos, o que significa que os elementos não podem ser repetidos, ex: `{ 1, 2, 2, 3, 4, 3, 4, 2 } = { 1, 2, 3, 4 }` +- Dois conjuntos `A` e `B` são iguais se, e somente se, `A ⊆ B` e `B ⊆ A` + +### Conjuntos especiais +O Conjunto das Partes +- Seja `A` um conjunto qualquer. O conjunto que contém todos os possíveis subconjuntos de `A` é chamado "conjunto das partes" e é denotado como `P(A)`. Se o conjunto `A` contém `n` elementos, então o conjunto das partes conterá `2^n` elementos. +``` +P(A) = { x : x ⊆ A } +``` + +## Operações entre dois conjuntos + +### União +Dados dois conjuntos `A` e `B`, a união entre esses dois conjuntos são os itens que aparecem em `A` ou em `B`, denotado por `A ∪ B`. + +``` +A ∪ B = { x : x ∈ A ∪ x ∈ B } +``` + +### Interseção +Dados dois conjuntos `A` e `B`, a interseção entre esses dois conjuntos são os itens que aparecem em `A` e em `B`, denotado por `A ∩ B`. + +``` +A ∩ B = { x : x ∈ A, x ∈ B } +``` + +### Diferença +Dados dois conjuntos `A` e `B`, o conjunto da diferença entre `A` e `B` são todos os itens de `A` que não pertencem a `B`. +``` +A \ B = { x : x ∈ A, x ∉ B } +``` + +### Diferença simétrica +Dados dois conjuntos `A` e `B`, a diferença simétrica são todos os itens entre `A` e `B` que não aparecem na interseção desses dois conjuntos. + +``` +A △ B = { x : ((x ∈ A) ∩ (x ∉ B)) ∪ ((x ∈ B) ∩ (x ∉ A)) } + +A △ B = (A \ B) ∪ (B \ A) +``` + +### Produto Cartesiano +Dados dois conjuntos `A` e `B`, o produto cartesiano de `A` e `B` consiste no conjunto contendo todas as combinações dos itens de `A` e `B`. +``` +A × B = { (x, y) | x ∈ A, y ∈ B } +``` + + diff --git a/pt-br/stylus-pt.html.markdown b/pt-br/stylus-pt.html.markdown index 40c3c02c..40c3c02c 100755..100644 --- a/pt-br/stylus-pt.html.markdown +++ b/pt-br/stylus-pt.html.markdown diff --git a/pt-br/toml-pt.html.markdown b/pt-br/toml-pt.html.markdown new file mode 100644 index 00000000..bdb1decf --- /dev/null +++ b/pt-br/toml-pt.html.markdown @@ -0,0 +1,232 @@ +--- +language: toml +filename: learntoml-pt.toml +contributors: + - ["Alois de Gouvello", "https://github.com/aloisdg"] +translators: + - ["Adaías Magdiel", "https://adaiasmagdiel.com/"] +lang: pt-br +--- + +TOML significa Tom's Obvious, Minimal Language. É uma linguagem de serialização de dados projetada para ser um formato de arquivo de configuração mínimo que é fácil de ler devido à semântica óbvia. + +É uma alternativa ao YAML e JSON. Tem como objetivo ser mais amigável para humanos do que JSON e mais simples que YAML. TOML é projetado para mapear de forma inequívoca para uma tabela de hash e deve ser fácil de converter em estruturas de dados em uma ampla variedade de linguagens. + +Cuidado, a especificação do TOML ainda passa por muitas mudanças. Até que seja marcado como 1.0, você deve assumir que é instável e agir de acordo. Este documento segue o TOML v0.4.0. + +```toml +# Comentários em TOML são feitos desta forma. + +################### +# TIPOS ESCALARES # +################### + +# Nosso objeto raiz (que continuará por todo o documento) será um mapa, +# que é equivalente a um dicionário, hash ou objeto em outras linguagens. + +# A chave, o sinal de igual e o valor precisam estar na mesma linha +# (embora alguns valores possam ser quebrados em várias linhas). +chave = "valor" +string = "Olá" +number = 42 +float = 3.14 +boolean = true +dateTime = 2002-07-16T20:32:00-03:00 +scientificNotation = 1e+12 +"chaves podem estar entre aspas" = true # Tanto " quanto ' são aceitáveis +"chaves podem conter" = "letras, números, underscores e hífens" + +# Uma chave não pode ser vazia, mas uma chave vazia entre aspas é permitido +"" = "blank" # VÁLIDO mas não é recomendado +'' = 'blank' # VÁLIDO mas não é recomendado + +########## +# String # +########## + +# Todas as strings precisam ter apenas caracteres UTF-8 válidos. +# Podemos escapar caracteres e alguns deles têm uma sequência de escape compacta. +# Por exemplo: \t adiciona uma tabulação. Leia a spec para conhecer todos. +basicString = "São cercadas por aspas. \"Sou digno de citação\". Nome\tJosé." + +multiLineString = """ +são cercadas por três aspas +em cada lado e permitem novas linhas.""" + +literalString = 'são cercadas por aspas simples. Escape de caracteres não é permitido.' + +multiLineString = ''' +são cercadas por três aspas simples em cada lado +e permitem novas linhas. Escape de caracteres também não é permitido. +A primeira quebra de linha é removida em strings brutas + Todo outro espaço em branco + é preservado. #! foi preservado? +''' + +# Para dados binários é recomendado que você use Base64, outra codificação ASCII ou UTF8. +# A manipulação dessa codificação será específico da aplicação. + +############ +# Inteiros # +############ + +## Inteiros podem começar com um +, um -, ou nada. +## Zeros à frente não são permitidos. +## Formatos em hexadecimal, octal e binário são permitidos. +## Não são permitidos valores que não podem ser expressados como uma série de dígitos. +int1 = +42 +int2 = 0 +int3 = -21 +int4 = 0xcafebabe +int5 = 0o755 +int6 = 0b11011100 +integerRange = 64 + +## Você pode usar underscores para melhorar a legibilidade. +## Cada underscore precisa estar entre, pelo menos, um dígito. +int7 = 5_349_221 +int8 = 1_2_3_4_5 # VÁLIDO, mas não é recomendado + +######### +# Float # +######### + +# Floats são inteiros seguidos por uma fração e/ou de um expoente. +flt1 = 3.1415 +flt2 = -5e6 +flt3 = 6.626E-34 + +############# +# Booleanos # +############# + +bool1 = true +bool2 = false +booleanosPrecisamEstarEmMinusculo = true + +############ +# Datetime # +############ + +date1 = 1979-05-27T07:32:00Z # Tempo UTC, seguindo especificação RFC 3339/ISO 8601 +date2 = 1979-05-26T15:32:00+08:00 # com um deslocamento segundo a RFC 3339/ISO 8601 +date3 = 1979-05-27T07:32:00 # sem deslocamento +date4 = 1979-05-27 # sem as horas e sem deslocamento + +#################### +# TIPOS DE COLEÇÃO # +#################### + +######### +# Array # +######### + +array1 = [ 1, 2, 3 ] +array2 = [ "Vírgulas", "são", "delimitadores" ] +array3 = [ "Não misture", "tipos", "diferentes" ] +array4 = [ [ 1.2, 2.4 ], ["todas as", 'strings', """são do mesmo""", '''tipo'''] ] +array5 = [ + "Espaços em branco", "são", "ignorados" +] + +########## +# Tabela # +########## + +# Tabelas (ou tabelas de hash, ou dicionários) é uma coleção de pares chave/valor. +# Eles aparecem entre colchetes em uma linha separada. +# Tabelas vazias são permitidas e simplesmente não possuem chave/valor associado. +[tabela] + +# Abaixo disso, e até a próxima tabela ou final do arquivo, estão as chaves/valores dessa tabela. +# Os pares de chave/valor dentro das tabelas não têm garantia de estar em nenhuma ordem específica. +[table-1] +chave1 = "algum texto" +chave2 = 123 + +[table-2] +chave1 = "outro texto" +chave2 = 456 + +# Pontos são proibidos em chaves simples porque são usados para indicar tabelas aninhadas. +# As regras de nomenclatura para cada parte separada por ponto são as mesmas que para chaves. +[dog."tater.man"] +type = "pug" + +# Na terra do JSON, você teria a seguinte estrutura: +# { "dog": { "tater.man": { "type": "pug" } } } + +# Espaços em branco em torno das partes separadas por pontos são ignorados, de qualquer forma, +# é sempre recomendado não utilizar espaços em branco desnecessários. +[a.b.c] # isso é o recomendado +[ d.e.f ] # mesmo que [d.e.f] +[ j . "ʞ" . 'l' ] # mesmo que [j."ʞ".'l'] + +# Você não precisa especificar todas as super-tabelas se não quiser. TOML sabe +# como lidar com isso para você. +# [x] você +# [x.y] não precisa +# [x.y.z] disso +[x.y.z.w] # para isso funcionar + +# Mesmo que uma super-tabela não tenha sido definida diretamente e não tenha definido uma +# chave específica, ainda é possível escrever nela. +[a.b] +c = 1 + +[a] +d = 2 + +# Irá gerar o seguinte JSON: +# { "a": {"b": {"c": 1}, "d": 2 } } + +# Você não pode definir uma chave ou tabela mais de uma vez. É inválido fazer isso. + +# NÃO FAÇA ISSO +[a] +b = 1 + +[a] +c = 2 + +# NEM MESMO ISSO +[a] +b = 1 + +[a.b] +c = 2 + +# O nome de todas as tabelas não pode ser vazio. +[] # INVÁLIDO +[a.] # INVÁLIDO +[a..b] # INVÁLIDO +[.b] # INVÁLIDO +[.] # INVÁLIDO + +#################### +# Tabelas em linha # +#################### + +tabelasEmLinha = { sãoFechadasCom = "{ e }", precisamEstarEmUmaLinha = true } +ponto = { x = 1, y = 2 } + +#################### +# Array de Tabelas # +#################### + +# Um array de tabelas pode ser expresso usando um nome de tabela entre colchetes duplos. +# Cada tabela com o mesmo nome entre colchetes duplos será um item no array. +# As tabelas são inseridas na ordem em que são encontradas. + +[[produtos]] +nome = "array de tabelas" +sku = 738594937 +tabelasVaziasSaoPermitidas = true + +[[produtos]] + +[[produtos]] +nome = "Unhas" +sku = 284758393 +color = "cinza" +``` diff --git a/pt-br/visualbasic-pt.html.markdown b/pt-br/visualbasic-pt.html.markdown index 81292798..dcc72c04 100644 --- a/pt-br/visualbasic-pt.html.markdown +++ b/pt-br/visualbasic-pt.html.markdown @@ -8,7 +8,7 @@ lang: pt-br filename: learnvisualbasic-pt.vb --- -``` +```visualbasic Module Module1 module Module1 diff --git a/pt-pt/kotlin-pt.html.markdown b/pt-pt/kotlin-pt.html.markdown new file mode 100644 index 00000000..47dbb44d --- /dev/null +++ b/pt-pt/kotlin-pt.html.markdown @@ -0,0 +1,473 @@ +--- +language: kotlin +filename: LearnKotlin-pt.kt +lang: pt-pt +contributors: + - ["S Webber", "https://github.com/s-webber"] +translators: + - ["André Martins", "https://github.com/chriptus13"] +--- + +Kotlin é uma linguagem de programação de tipificação estática para a JVM, Android e browser. Ela é 100% interoperável com Java. +[Lê mais aqui.](https://kotlinlang.org/) + +```kotlin +// Comentários de linha começam com // +/* +Comentários de múltiplas linhas são assim. +*/ + +// A palavra-chave "package" funciona da mesma forma que em Java. +package com.learnxinyminutes.kotlin + +/* +O ponto de entrada de um programa em Kotlin é a função chamada "main". +Esta função tem como único parâmetro um array contendo todos os argumentos passados na linha de comandos. +Desde a versão 1.3 que esta pode também ser definida sem parâmetros. +*/ +fun main(args: Array<String>) { + /* + A declaração de variáveis é feita usando "var" ou "val". + Variáveis declaradas com "val" não podem ser redefinidas, já as declaradas com "var" podem. + */ + val fooVal = 10 // não podemos redefinir mais tarde o valor de fooVal para algo diferente + var fooVar = 10 + fooVar = 20 // fooVar pode ser redefinida + + /* + Na maioria dos casos, o Kotlin pode determinar (inferir) o tipo de uma variável, + assim não precisamos de o dizer explicitamente sempre. + Para especificar o tipo explicitamente fazemos assim: + */ + val foo: Int = 7 + + /* + As Strings são representadas de uma forma semelhante ao Java. + O escape é feito com barras invertidas. + */ + val fooString = "A minha String está aqui!" + val barString = "Imprimir numa nova linha?\nSem problemas!" + val bazString = "Adicionar um tab?\tSem problemas!" + println(fooString) + println(barString) + println(bazString) + + /* + Uma raw string é delimitada por aspas triplas ("""). + Raw strings podem conter caracteres de nova linha ou qualquer outro. + */ + val fooRawString = """ +fun helloWorld(val name : String) { + println("Hello, world!") +} +""" + println(fooRawString) + + /* + As strings podem também conter template expressions. + Uma template expression começa com o símbolo do dollar ($). + */ + val fooTemplateString = "$fooString tem ${fooString.length} caracteres" + println(fooTemplateString) // => A minha String está aqui! tem 25 caracteres + + /* + Para que uma variável possa ter o valor de null esta tem de ser + especificada explicitamente como nullable. + Uma variável pode ser marcada como nullable adicionando um ? ao seu tipo. + A variable can be specified as nullable by appending a ? to its type. + Usando o operador ?. podemos facilmente aceder a propriedades de + uma variável nullable, se esta for null o resultado da expressão será também ele null. + Podemos também usar o operador ?: para especificar um valor alternativo + no caso da variavél ser null. + */ + var fooNullable: String? = "abc" + println(fooNullable?.length) // => 3 + println(fooNullable?.length ?: -1) // => 3 + fooNullable = null + println(fooNullable?.length) // => null + println(fooNullable?.length ?: -1) // => -1 + + /* + As funções são declaradas usando a palavra-chave "fun". + Os parâmetros da função são especificados entre parênteses a seguir ao nome da função. + Estes parâmetros podem opcionalmente ter um valor por omissão. + O tipo de retorno da função, se necessário, é especificado após os parâmetros. + */ + fun hello(name: String = "world"): String { + return "Hello, $name!" + } + println(hello("foo")) // => Hello, foo! + println(hello(name = "bar")) // => Hello, bar! + println(hello()) // => Hello, world! + + /* + Para que uma função receba um número variável de parâmetros podemos + marcar um, e apenas um, parâmetro com a palavra-chave "vararg". + */ + fun varargExample(vararg names: Int) { + println("Argument has ${names.size} elements") + } + varargExample() // => A chamada à função tem 0 argumentos + varargExample(1) // => A chamada à função tem 1 argumentos + varargExample(1, 2, 3) // => A chamada à função tem 3 argumentos + + /* + Quando uma função consiste em apenas uma expressão as chavetas podem ser omitidas + O corpo da mesma é especificado após o símbolo de igual (=). + */ + fun odd(x: Int): Boolean = x % 2 == 1 + println(odd(6)) // => false + println(odd(7)) // => true + + // Se o tipo de retorno da função pode ser inferido então não é necessário especificá-lo. + fun even(x: Int) = x % 2 == 0 + println(even(6)) // => true + println(even(7)) // => false + + // As funções podem ter outras funções como parâmetros e/ou como retorno. + fun not(f: (Int) -> Boolean): (Int) -> Boolean { + return {n -> !f.invoke(n)} + } + // O operador :: pode ser usado para referênciar funções existentes. + val notOdd = not(::odd) + val notEven = not(::even) + /* + Expressões lambda podem ser usadas da seguinte forma. + Os lambdas quando passados a outras funções podem estar + fora dos parênteses da chamada, caso sejam o último parâmetro. + */ + val notZero = not {n -> n == 0} + /* + Se o lambda apenas tiver um parâmetro então a sua + declaração pode ser omitida (em conjunto com "->"). + O nome por omissão do parâmetro será "it". + */ + val notPositive = not {it > 0} + for (i in 0..4) { + println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") + } + + // Para declararmos classes usa-se a palavra-chave "class". + class ExampleClass(val x: Int) { + fun aMethod(y: Int): Int { + return x + y + } + + infix fun infixMemberFunction(y: Int): Int { + return x * y + } + } + /* + Para se instanciar uma classe usamos o constructor. + De notar que em Kotlin não existe a palavra-chave "new" como no Java. + */ + val fooExampleClass = ExampleClass(7) + // Os métodos da classe podem então ser chamados usando o ponto. + println(fooExampleClass.aMethod(4)) // => 11 + /* + Uma função marcada com a palavra-chave "infix" pode ser chamada + usando a notação infixa. + */ + println(fooExampleClass infixMemberFunction 4) // => 28 + + /* + Data classes são uma forma concisa de criar classes que apenas contêm dados. + Neste tipo de classes os métodos "hashCode"/"equals" e "toString" são gerados + automáticamente. + */ + data class DataClassExample (val x: Int, val y: Int, val z: Int) + val fooData = DataClassExample(1, 2, 4) + println(fooData) // => DataClassExample(x=1, y=2, z=4) + + // Instâncias deste tipo de classes têm acesso ao método "copy". + val fooCopy = fooData.copy(y = 100) + println(fooCopy) // => DataClassExample(x=1, y=100, z=4) + + // Os objectos podem ser desconstruídos para variáveis. + val (a, b, c) = fooCopy + println("$a $b $c") // => 1 100 4 + + // desconstrucção dentro de um ciclo "for" + for ((a, b, c) in listOf(fooData)) { + println("$a $b $c") // => 1 2 4 + } + + val mapData = mapOf("a" to 1, "b" to 2) + // Instâncias de Map.Entry podem também ser desconstruídas. + for ((key, value) in mapData) { + println("$key -> $value") + } + + // A função "with" é semelhante ao bloco "with" do JavaScript. + data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) + val fooMutableData = MutableDataClassExample(7, 4, 9) + with (fooMutableData) { + x -= 2 + y += 2 + z-- + } + println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) + + /* + Podemos criar listas usando a função "listOf". + No Kotlin, por padrão, as listas são imútaveis - não podendo + assim adicionar ou remover elementos das mesmas. + */ + val fooList = listOf("a", "b", "c") + println(fooList.size) // => 3 + println(fooList.first()) // => a + println(fooList.last()) // => c + // Os elementos de uma lista podem ser acedidos usando o seu índice. + println(fooList[1]) // => b + + // Listas mútaveis podem ser criadas usando a função "mutableListOf". + val fooMutableList = mutableListOf("a", "b", "c") + fooMutableList.add("d") + println(fooMutableList.last()) // => d + println(fooMutableList.size) // => 4 + + // Podemos criar conjuntos usando a função "setOf". + val fooSet = setOf("a", "b", "c") + println(fooSet.contains("a")) // => true + println(fooSet.contains("z")) // => false + + // Podemos criar mapas usando a função "mapOf" e através da função infixa "to". + val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) + // Os valores do mapa podem ser acedidos usando a sua chave. + println(fooMap["a"]) // => 8 + + /* + No Kotlin as sequências representam collecções de dados avaliadas de forma lazy. + Podemos cirar uma sequência usando a função "generateSequence". + */ + val fooSequence = generateSequence(1, { it + 1 }) + val x = fooSequence.take(10).toList() + println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + // Um exemplo de uso das sequências para gerar os números de Fibonacci: + fun fibonacciSequence(): Sequence<Long> { + var a = 0L + var b = 1L + + fun next(): Long { + val result = a + b + a = b + b = result + return a + } + + return generateSequence(::next) + } + val y = fibonacciSequence().take(10).toList() + println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + + // O Kotlin fornece funções de ordem superior convenientes para a manipulação de colecções. + val z = (1..9).map {it * 3} + .filter {it < 20} + .groupBy {it % 2 == 0} + .mapKeys {if (it.key) "even" else "odd"} + println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} + + // Um ciclo "for" pode ser usado com qualquer coisa que forneça um iterador. + for (c in "hello") { + println(c) + } + + // Um ciclo "while" funciona da mesma forma que em outras linguagens. + var ctr = 0 + while (ctr < 5) { + println(ctr) + ctr++ + } + do { + println(ctr) + ctr++ + } while (ctr < 10) + + /* + Um "if" pode ser usado como uma expressão que produz um valor. + Por esta razão o operador ternário não é necessário no Kotlin. + */ + val num = 5 + val message = if (num % 2 == 0) "even" else "odd" + println("$num is $message") // => 5 is odd + + // O bloco "when" pode ser usado como alternativa para cadeias de "if-else if". + val i = 10 + when { + i < 7 -> println("first block") + fooString.startsWith("hello") -> println("second block") + else -> println("else block") + } + + // O "when" pode ser usado como um "switch" do Java. + when (i) { + 0, 21 -> println("0 or 21") + in 1..20 -> println("in the range 1 to 20") + else -> println("none of the above") + } + + // O "when" pode também ser usado como expressão para produzir um valor. + var result = when (i) { + 0, 21 -> "0 or 21" + in 1..20 -> "in the range 1 to 20" + else -> "none of the above" + } + println(result) + + /* + Podemos utilizar o operador "is" para verificar se um objecto é de um certo tipo. + Se um objecto passar a verificação do tipo pode ser usado como sendo desse tipo + sem conversão explicita, sendo isto chamado de smart cast. + */ + fun smartCastExample(x: Any) : Boolean { + if (x is Boolean) { + // x is automatically cast to Boolean + return x + } else if (x is Int) { + // x is automatically cast to Int + return x > 0 + } else if (x is String) { + // x is automatically cast to String + return x.isNotEmpty() + } else { + return false + } + } + println(smartCastExample("Hello, world!")) // => true + println(smartCastExample("")) // => false + println(smartCastExample(5)) // => true + println(smartCastExample(0)) // => false + println(smartCastExample(true)) // => true + + // Os smart casts funcionam também com o bloco "when". + fun smartCastWhenExample(x: Any) = when (x) { + is Boolean -> x + is Int -> x > 0 + is String -> x.isNotEmpty() + else -> false + } + + /* + Extensões são uma forma de adicionar funcionalidade a classes existentes. + Isto é semelhante aos métodos de extensão do C#. + */ + fun String.remove(c: Char): String { + return this.filter {it != c} + } + println("Hello, world!".remove('l')) // => Hello, world! +} + +// Enum classes são o equivalente aos tipos enum do Java. +enum class EnumExample { + A, B, C // As constantes da enumeração são separadas por vírgula. +} +fun printEnum() = println(EnumExample.A) // => A + +/* +Como cada constante é uma instância da classe enum, +estas podem ser inicializadas da seguinte forma: +*/ +enum class EnumExample(val value: Int) { + A(value = 1), + B(value = 2), + C(value = 3) +} +fun printProperty() = println(EnumExample.A.value) // => 1 + +/* +Cada constante de enumerações tem propriedades para +obter o nome e o ordinal (posição) na respectiva classe. +*/ +fun printName() = println(EnumExample.A.name) // => A +fun printPosition() = println(EnumExample.A.ordinal) // => 0 + +/* +A palavra-chave "object" pode ser usada para criar objectos singleton. +Estes não podem ser instânciados, porém podem ser referênciados como uma +única instância através do seu nome. +São semelhantes aos objectos singleton do Scala. +*/ +object ObjectExample { + fun hello(): String { + return "hello" + } + + override fun toString(): String { + return "Hello, it's me, ${ObjectExample::class.simpleName}" + } +} + + +fun useSingletonObject() { + println(ObjectExample.hello()) // => hello + // Em Kotlin o tipo "Any" é a raíz da hierárquia de classes, tal como o tipo "Object" em Java. + val someRef: Any = ObjectExample + println(someRef) // => Hello, it's me, ObjectExample +} + + +/* +O operador !! serve para realizar um assert de not-null. Este converte qualquer +valor nullable para non-null ou lança exceção se o mesmo for null. +*/ +var b: String? = "abc" +val l = b!!.length // lançaria exceção caso "b" fosse null + +// O modificador "operator" permite fazer overload dos operadores +// [Ver lista de operadores](https://kotlinlang.org/docs/operator-overloading.html) +data class Counter(var value: Int) { + // overload para Counter += Int + operator fun plusAssign(increment: Int) { + this.value += increment + } + + // overload para Counter++ e ++Counter + operator fun inc() = Counter(value + 1) + + // overload para Counter + Counter + operator fun plus(other: Counter) = Counter(this.value + other.value) + + // overload para Counter * Counter + operator fun times(other: Counter) = Counter(this.value * other.value) + + // overload para Counter * Int + operator fun times(value: Int) = Counter(this.value * value) + + // overload para Counter in Counter + operator fun contains(other: Counter) = other.value == this.value + + // overload para Counter[Int] = Int + operator fun set(index: Int, value: Int) { + this.value = index + value + } + + // overload para invocação da instância Counter + operator fun invoke() = println("The value of the counter is $value") +} +/* Podemos também dar overload dos operadores através de métodos de extensão */ +// overload para -Counter +operator fun Counter.unaryMinus() = Counter(-this.value) + +fun operatorOverloadingDemo() { + var counter1 = Counter(0) + var counter2 = Counter(5) + counter1 += 7 + println(counter1) // => Counter(value=7) + println(counter1 + counter2) // => Counter(value=12) + println(counter1 * counter2) // => Counter(value=35) + println(counter2 * 2) // => Counter(value=10) + println(counter1 in Counter(5)) // => false + println(counter1 in Counter(7)) // => true + counter1[26] = 10 + println(counter1) // => Counter(value=36) + counter1() // => The value of the counter is 36 + println(-counter2) // => Counter(value=-5) +} +``` + +### Leituras Adicionais + +* [Tutoriais de Kotlin](https://kotlinlang.org/docs/tutorials/) +* [Experimenta Kotlin no browser](https://play.kotlinlang.org/) +* [Recursos adicionais](http://kotlin.link/)
\ No newline at end of file diff --git a/pug.html.markdown b/pug.html.markdown index 1bc49f64..21d8db9f 100644 --- a/pug.html.markdown +++ b/pug.html.markdown @@ -158,13 +158,13 @@ case orderStatus //- <p class="warn">Your order is pending</p> //- --INCLUDE-- -//- File path -> "includes/nav.png" +//- File path -> "includes/nav.pug" h1 Company Name nav a(href="index.html") Home a(href="about.html") About Us -//- File path -> "index.png" +//- File path -> "index.pug" html body include includes/nav.pug @@ -205,4 +205,4 @@ mixin comment(name, comment) ### Additional Resources - [The Site](https://pugjs.org/) - [The Docs](https://pugjs.org/api/getting-started.html) -- [Github Repo](https://github.com/pugjs/pug) +- [GitHub Repo](https://github.com/pugjs/pug) diff --git a/pyqt.html.markdown b/pyqt.html.markdown index 6bdb6488..2b331874 100644 --- a/pyqt.html.markdown +++ b/pyqt.html.markdown @@ -11,25 +11,25 @@ contributors: This is an adaption on the C++ intro to QT by [Aleksey Kholovchuk](https://github.com/vortexxx192 ), some of the code examples should result in the same functionality -this version just having been done using pyqt! +this version just having been done using pyqt! ```python import sys from PyQt4 import QtGui - + def window(): - # Create an application object + # Create an application object app = QtGui.QApplication(sys.argv) # Create a widget where our label will be placed in w = QtGui.QWidget() - # Add a label to the widget + # Add a label to the widget b = QtGui.QLabel(w) - # Set some text for the label + # Set some text for the label b.setText("Hello World!") - # Give some size and placement information + # Give some size and placement information w.setGeometry(100, 100, 200, 50) b.move(50, 20) - # Give our window a nice title + # Give our window a nice title w.setWindowTitle("PyQt") # Have everything display w.show() @@ -41,10 +41,10 @@ if __name__ == '__main__': ``` -In order to get some of the more advanced features in **pyqt** we need to start looking at building additional elements. +In order to get some of the more advanced features in **pyqt** we need to start looking at building additional elements. Here we show how to introduce a dialog popup box, useful for asking the user to confirm a decision or to provide information. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -63,7 +63,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # This function should create a dialog window with a button # that waits to be clicked and then exits the program def showdialog(): diff --git a/python.html.markdown b/python.html.markdown index d9eda60c..9d97e64d 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -185,7 +185,7 @@ print("Hello, World", end="!") # => Hello, World! input_string_var = input("Enter some data: ") # Returns the data as a string # There are no declarations, only assignments. -# Convention is to use lower_case_with_underscores +# Convention in naming variables is snake_case style some_var = 5 some_var # => 5 @@ -226,7 +226,7 @@ li[4] # Raises an IndexError li[1:3] # Return list from index 1 to 3 => [2, 4] li[2:] # Return list starting from index 2 => [4, 3] li[:3] # Return list from beginning until index 3 => [1, 2, 4] -li[::2] # Return list selecting every second entry => [1, 4] +li[::2] # Return list selecting elements with a step size of 2 => [1, 4] li[::-1] # Return list in reverse order => [3, 4, 2, 1] # Use any combination of these to make advanced slices # li[start:end:step] @@ -501,20 +501,20 @@ with open("myfile.txt") as f: # Writing to a file contents = {"aa": 12, "bb": 21} -with open("myfile1.txt", "w+") as file: +with open("myfile1.txt", "w") as file: file.write(str(contents)) # writes a string to a file import json -with open("myfile2.txt", "w+") as file: +with open("myfile2.txt", "w") as file: file.write(json.dumps(contents)) # writes an object to a file # Reading from a file -with open('myfile1.txt', "r+") as file: +with open('myfile1.txt', "r") as file: contents = file.read() # reads a string from a file print(contents) # print: {"aa": 12, "bb": 21} -with open('myfile2.txt', "r+") as file: +with open('myfile2.txt', "r") as file: contents = json.load(file) # reads a json object from a file print(contents) # print: {"aa": 12, "bb": 21} @@ -603,7 +603,7 @@ all_the_args(1, 2, a=3, b=4) prints: """ # When calling functions, you can do the opposite of args/kwargs! -# Use * to expand tuples and use ** to expand kwargs. +# Use * to expand args (tuples) and use ** to expand kwargs (dictionaries). args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} all_the_args(*args) # equivalent: all_the_args(1, 2, 3, 4) @@ -655,6 +655,22 @@ def create_adder(x): add_10 = create_adder(10) add_10(3) # => 13 +# Closures in nested functions: +# We can use the nonlocal keyword to work with variables in nested scope which shouldn't be declared in the inner functions. +def create_avg(): + total = 0 + count = 0 + def avg(n): + nonlocal total, count + total += n + count += 1 + return total/count + return avg +avg = create_avg() +avg(3) # => 3.0 +avg(5) # (3+5)/2 => 4.0 +avg(7) # (8+7)/3 => 5.0 + # There are also anonymous functions (lambda x: x > 2)(3) # => True (lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 @@ -685,8 +701,8 @@ print(math.sqrt(16)) # => 4.0 # You can get specific functions from a module from math import ceil, floor -print(ceil(3.7)) # => 4.0 -print(floor(3.7)) # => 3.0 +print(ceil(3.7)) # => 4 +print(floor(3.7)) # => 3 # You can import all functions from a module. # Warning: this is not recommended @@ -733,7 +749,9 @@ class Human: self.name = name # Initialize property - self._age = 0 + self._age = 0 # the leading underscore indicates the "age" property is + # intended to be used internally + # do not rely on this to be enforced: it's a hint to other devs # An instance method. All methods take "self" as the first argument def say(self, msg): @@ -876,7 +894,8 @@ if __name__ == '__main__': if type(sup) is Superhero: print('I am a superhero') - # Get the Method Resolution search Order used by both getattr() and super() + # Get the "Method Resolution Order" used by both getattr() and super() + # (the order in which classes are searched for an attribute or method) # This attribute is dynamic and can be updated print(Superhero.__mro__) # => (<class '__main__.Superhero'>, # => <class 'human.Human'>, <class 'object'>) @@ -958,8 +977,7 @@ class Batman(Superhero, Bat): if __name__ == '__main__': sup = Batman() - # Get the Method Resolution search Order used by both getattr() and super(). - # This attribute is dynamic and can be updated + # The Method Resolution Order print(Batman.__mro__) # => (<class '__main__.Batman'>, # => <class 'superhero.Superhero'>, # => <class 'human.Human'>, @@ -1016,31 +1034,67 @@ gen_to_list = list(values) print(gen_to_list) # => [-1, -2, -3, -4, -5] -# Decorators -# In this example `beg` wraps `say`. If say_please is True then it -# will change the returned message. -from functools import wraps +# Decorators are a form of syntactic sugar. +# They make code easier to read while accomplishing clunky syntax. +# Wrappers are one type of decorator. +# They're really useful for adding logging to existing functions without needing to modify them. -def beg(target_function): - @wraps(target_function) +def log_function(func): def wrapper(*args, **kwargs): - msg, say_please = target_function(*args, **kwargs) - if say_please: - return "{} {}".format(msg, "Please! I am poor :(") - return msg - + print("Entering function", func.__name__) + result = func(*args, **kwargs) + print("Exiting function", func.__name__) + return result return wrapper +@log_function # equivalent: +def my_function(x,y): # def my_function(x,y): + return x+y # return x+y + # my_function = log_function(my_function) +# The decorator @log_function tells us as we begin reading the function definition +# for my_function that this function will be wrapped with log_function. +# When function definitions are long, it can be hard to parse the non-decorated +# assignment at the end of the definition. + +my_function(1,2) # => "Entering function my_function" + # => "3" + # => "Exiting function my_function" + +# But there's a problem. +# What happens if we try to get some information about my_function? + +print(my_function.__name__) # => 'wrapper' +print(my_function.__code__.co_argcount) # => 0. The argcount is 0 because both arguments in wrapper()'s signature are optional. + +# Because our decorator is equivalent to my_function = log_function(my_function) +# we've replaced information about my_function with information from wrapper + +# Fix this using functools + +from functools import wraps + +def log_function(func): + @wraps(func) # this ensures docstring, function name, arguments list, etc. are all copied + # to the wrapped function - instead of being replaced with wrapper's info + def wrapper(*args, **kwargs): + print("Entering function", func.__name__) + result = func(*args, **kwargs) + print("Exiting function", func.__name__) + return result + return wrapper -@beg -def say(say_please=False): - msg = "Can you buy me a beer?" - return msg, say_please +@log_function +def my_function(x,y): + return x+y + +my_function(1,2) # => "Entering function my_function" + # => "3" + # => "Exiting function my_function" +print(my_function.__name__) # => 'my_function' +print(my_function.__code__.co_argcount) # => 2 -print(say()) # Can you buy me a beer? -print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ``` ### Free Online diff --git a/qsharp.html.markdown b/qsharp.html.markdown index 10015d7f..04e697a4 100644 --- a/qsharp.html.markdown +++ b/qsharp.html.markdown @@ -9,7 +9,7 @@ filename: LearnQSharp.qs Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers. -```C# +```c# // Single-line comments start with // diff --git a/ro-ro/elixir-ro.html.markdown b/ro-ro/elixir-ro.html.markdown index 10fec3c5..60500d64 100644 --- a/ro-ro/elixir-ro.html.markdown +++ b/ro-ro/elixir-ro.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -22,7 +22,7 @@ posibilități. # Pentru comentarii pe mai multe linii nu există sintaxă separată, # de aceea folosiți mai multe linii cu comentarii. -# Pentru a folosi shell-ul elixir utilizați comanda `iex`. +# Pentru a folosi shell-ul Elixir utilizați comanda `iex`. # Compilați modulele cu comanda `elixirc`. # Ambele comenzi vor lucra în terminal, dacă ați instalat Elixir corect. diff --git a/rst.html.markdown b/rst.html.markdown index c177fdb4..c68c1d54 100644 --- a/rst.html.markdown +++ b/rst.html.markdown @@ -8,7 +8,7 @@ filename: restructuredtext.rst RST, Restructured Text, is a file format created by the Python community to write documentation. It is part of [Docutils](https://docutils.sourceforge.io/rst.html). -RST is a markdown language like HTML but is much more lightweight and easier to read. +RST is a markup language like HTML but is much more lightweight and easier to read. ## Installation @@ -84,11 +84,11 @@ More complex tables can be done easily (merged columns and/or rows) but I sugges There are multiple ways to make links: -- By adding an underscore after a word : Github_ and by adding the target URL after the text (this way has the advantage of not inserting unnecessary URLs in the visible text). +- By adding an underscore after a word : GitHub_ and by adding the target URL after the text (this way has the advantage of not inserting unnecessary URLs in the visible text). - By typing a full comprehensible URL : https://github.com/ (will be automatically converted to a link). -- By making a more Markdown-like link: `Github <https://github.com/>`_ . +- By making a more Markdown-like link: `GitHub <https://github.com/>`_ . -.. _Github: https://github.com/ +.. _GitHub: https://github.com/ ``` diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown index 7fd02c47..02ebd205 100644 --- a/ru-ru/asymptotic-notation-ru.html.markdown +++ b/ru-ru/asymptotic-notation-ru.html.markdown @@ -1,225 +1,225 @@ ----
-category: Algorithms & Data Structures
-name: Asymptotic Notation
-contributors:
- - ["Jake Prather", "http://github.com/JakeHP"]
- - ["Divay Prakash", "http://github.com/divayprakash"]
-translators:
- - ["pru-mike", "http://github.com/pru-mike"]
-lang: ru-ru
----
-
-# О-символика
-
-## Что это такое?
-
-О-символика, или асимптотическая запись, — это система символов, позволяющая
-оценить время выполнения алгоритма, устанавливая зависимость времени выполнения
-от увеличения объёма входных данных. Она также известна как оценка
-сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда
-объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро,
-если объём входных данных возрастёт? О-символика позволяет ответить на эти
-вопросы.
-
-## Можно ли по-другому найти ответы на эти вопросы?
-
-Один способ — это подсчитать число элементарных операций в зависимости от
-различных объёмов входных данных. Хотя это и приемлемое решение, тот объём
-работы, которого оно потребует, даже для простых алгоритмов делает его
-использование неоправданным.
-
-Другой способ — это измерить, какое время алгоритм потребует для завершения на
-различных объёмах входных данных. В то же время, точность и относительность
-этого метода (полученное время будет относиться только к той машине, на которой
-оно вычислено) зависит от среды выполнения: компьютерного аппаратного
-обеспечения, мощности процессора и т.д.
-
-## Виды О-символики
-
-В первом разделе этого документа мы определили, что О-символика
-позволяет оценивать алгоритмы в зависимости от изменения размера входных
-данных. Представим, что алгоритм — это функция f, n — размер входных данных и
-f(n) — время выполнения. Тогда для данного алгоритма f с размером входных
-данных n получим какое-то результирующее время выполнения f(n).
-Из этого можно построить график, где ось y — время выполнения, ось x — размер входных
-данных, а точки на графике — это время выполнения для заданного размера входных
-данных.
-
-С помощью О-символики можно оценить функцию или алгоритм
-несколькими различными способами. Например, можно оценить алгоритм исходя
-из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
-анализ на основе верхней оценки. Как правило не используется нижняя оценка,
-потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
-сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
-большинства таких алгоритмов может быть дана как одна операция. В то время как в
-большинстве случаев добавляемые элементы должны быть отсортированы
-соответствующим образом при помощи дерева, что может потребовать обхода целой
-ветви. Это и есть худший случай, для которого планируется верхняя оценка.
-
-### Виды функций, пределы и упрощения
-
-```
-Логарифмическая функция — log n
-Линейная функция — an + b
-Квадратичная функция — an^2 + bn +c
-Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа
-Показательная функция — a^n, где a — константа
-```
-
-Приведены несколько базовых функций, используемых при определении сложности в
-различных оценках. Список начинается с самой медленно возрастающей функции
-(логарифм, наиболее быстрое время выполнения) и следует до самой быстро
-возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
-что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций,
-результат намного быстрее возрастает в квадратичной, степенной
-и показательной по сравнению с логарифмической и линейной.
-
-Крайне важно понимать, что при использовании описанной далее нотации необходимо
-использовать упрощённые выражения.
-Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
-потому что если размер входных данных (n в функции f(n) нашего примера)
-увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
-и константы становятся пренебрежительно малыми. Таким образом, если есть
-константа, например, размера 2^9001 или любого другого невообразимого размера,
-надо понимать, что её упрощение внесёт значительные искажения в точность
-оценки.
-
-Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу...
-
-```
-Логарифм — log n
-Линейная функция — n
-Квадратичная функция — n^2
-Степенная функция — n^z, где z — константа
-Показательная функция — a^n, где a — константа
-```
-
-### О Большое
-О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего
-случая, или для ограничения заданной функции сверху. Это позволяет сделать
-_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
-алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная
-сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если
-существуют действительные константы c (c > 0) и n<sub>0</sub>, такие,
-что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
-
-*Пример 1*
-
-```
-f(n) = 3log n + 100
-g(n) = log n
-```
-
-Является ли `f(n)` O(g(n))?
-Является ли `3 log n + 100` O(log n)?
-Посмотрим на определение О Большого:
-
-```
-3log n + 100 <= c * log n
-```
-
-Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
-
-```
-3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1)
-```
-
-Да! По определению О Большого `f(n)` является O(g(n)).
-
-*Пример 2*
-
-```
-f(n) = 3 * n^2
-g(n) = n
-```
-
-Является ли `f(n)` O(g(n))?
-Является ли `3 * n^2` O(n)?
-Посмотрим на определение О Большого:
-
-```
-3 * n^2 <= c * n
-```
-
-Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
-Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
-
-### Омега Большое
-Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки
-лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать
-_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
-алгоритма.
-
-`f(n)` является Ω(g(n)), если существуют действительные константы
-c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
-
-### Примечание
-
-Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут
-как являться, так и не являться точными. Для того, чтобы обозначить, что границы не
-являются асимптотически точными, используются записи О Малое и Омега Малое.
-
-### О Малое
-O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней
-границы времени выполнения алгоритма при условии, что граница не является
-асимптотически точной.
-
-`f(n)` является o(g(n)), если можно подобрать такие действительные константы,
-что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
-что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
-
-Определения О-символики для О Большого и О Малого похожи. Главное отличие в том,
-что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_
-константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
-для _**всех**_ констант c > 0.
-
-### Омега Малое
-Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки
-верхней границы времени выполнения алгоритма при условии, что граница не является
-асимптотически точной.
-
-`f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
-что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
-что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
-
-Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
-если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_
-константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
-выполняется для _**всех**_ констант c > 0.
-
-### Тета
-Тета, записывается как **Θ**, — это асимптотическая запись для оценки
-_***асимптотически точной границы***_ времени выполнения алгоритма.
-
-`f(n)` является Θ(g(n)), если для некоторых действительных
-констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0)
-`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
-
-∴ `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n))
-и `f(n)` является Ω(g(n)).
-
-О Большое — основной инструмент для анализа сложности алгоритмов.
-Также см. примеры по ссылкам.
-
-### Заключение
-Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
-посмотреть дополнительную литературу. В ней даётся более глубокое описание с
-определениями и примерами.
-
-
-## Дополнительная литература
-
-* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
-* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
-
-## Ссылки
-
-* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php)
-* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
-
-## Ссылки (англ.)
-
-* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
-* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
-* [Cheatsheet 2](http://bigocheatsheet.com/)
-
+--- +category: Algorithms & Data Structures +name: Asymptotic Notation +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] + - ["Divay Prakash", "http://github.com/divayprakash"] +translators: + - ["pru-mike", "http://github.com/pru-mike"] +lang: ru-ru +--- + +# О-символика + +## Что это такое? + +О-символика, или асимптотическая запись, — это система символов, позволяющая +оценить время выполнения алгоритма, устанавливая зависимость времени выполнения +от увеличения объёма входных данных. Она также известна как оценка +сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда +объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро, +если объём входных данных возрастёт? О-символика позволяет ответить на эти +вопросы. + +## Можно ли по-другому найти ответы на эти вопросы? + +Один способ — это подсчитать число элементарных операций в зависимости от +различных объёмов входных данных. Хотя это и приемлемое решение, тот объём +работы, которого оно потребует, даже для простых алгоритмов делает его +использование неоправданным. + +Другой способ — это измерить, какое время алгоритм потребует для завершения на +различных объёмах входных данных. В то же время, точность и относительность +этого метода (полученное время будет относиться только к той машине, на которой +оно вычислено) зависит от среды выполнения: компьютерного аппаратного +обеспечения, мощности процессора и т.д. + +## Виды О-символики + +В первом разделе этого документа мы определили, что О-символика +позволяет оценивать алгоритмы в зависимости от изменения размера входных +данных. Представим, что алгоритм — это функция f, n — размер входных данных и +f(n) — время выполнения. Тогда для данного алгоритма f с размером входных +данных n получим какое-то результирующее время выполнения f(n). +Из этого можно построить график, где ось y — время выполнения, ось x — размер входных +данных, а точки на графике — это время выполнения для заданного размера входных +данных. + +С помощью О-символики можно оценить функцию или алгоритм +несколькими различными способами. Например, можно оценить алгоритм исходя +из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается +анализ на основе верхней оценки. Как правило, не используется нижняя оценка, +потому что она не подходит под планируемые условия. Отличный пример — алгоритмы +сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка +большинства таких алгоритмов может быть дана как одна операция. В то время как в +большинстве случаев добавляемые элементы должны быть отсортированы +соответствующим образом при помощи дерева, что может потребовать обхода целой +ветви. Это и есть худший случай, для которого планируется верхняя оценка. + +### Виды функций, пределы и упрощения + +``` +Логарифмическая функция — log n +Линейная функция — an + b +Квадратичная функция — an^2 + bn +c +Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа +Показательная функция — a^n, где a — константа +``` + +Приведены несколько базовых функций, используемых при определении сложности в +различных оценках. Список начинается с самой медленно возрастающей функции +(логарифм, наиболее быстрое время выполнения) и следует до самой быстро +возрастающей функции (экспонента, самое медленное время выполнения). Отметим, +что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций, +результат намного быстрее возрастает в квадратичной, степенной +и показательной по сравнению с логарифмической и линейной. + +Крайне важно понимать, что при использовании описанной далее нотации необходимо +использовать упрощённые выражения. +Это означает, что необходимо отбрасывать константы и слагаемые младших порядков, +потому что если размер входных данных (n в функции f(n) нашего примера) +увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков +и константы становятся пренебрежительно малыми. Таким образом, если есть +константа, например, размера 2^9001 или любого другого невообразимого размера, +надо понимать, что её упрощение внесёт значительные искажения в точность +оценки. + +Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу... + +``` +Логарифм — log n +Линейная функция — n +Квадратичная функция — n^2 +Степенная функция — n^z, где z — константа +Показательная функция — a^n, где a — константа +``` + +### О Большое +О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего +случая, или для ограничения заданной функции сверху. Это позволяет сделать +_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения +алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная +сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если +существуют действительные константы c (c > 0) и n<sub>0</sub>, такие, +что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>). + +*Пример 1* + +``` +f(n) = 3log n + 100 +g(n) = log n +``` + +Является ли `f(n)` O(g(n))? +Является ли `3 log n + 100` O(log n)? +Посмотрим на определение О Большого: + +``` +3log n + 100 <= c * log n +``` + +Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>? + +``` +3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1) +``` + +Да! По определению О Большого `f(n)` является O(g(n)). + +*Пример 2* + +``` +f(n) = 3 * n^2 +g(n) = n +``` + +Является ли `f(n)` O(g(n))? +Является ли `3 * n^2` O(n)? +Посмотрим на определение О Большого: + +``` +3 * n^2 <= c * n +``` + +Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>? +Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)). + +### Омега Большое +Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки +лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать +_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения +алгоритма. + +`f(n)` является Ω(g(n)), если существуют действительные константы +c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>. + +### Примечание + +Асимптотические оценки, сделанные при помощи О Большого и Омега Большого, могут +как являться, так и не являться точными. Для того чтобы обозначить, что границы не +являются асимптотически точными, используются записи О Малое и Омега Малое. + +### О Малое +O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней +границы времени выполнения алгоритма при условии, что граница не является +асимптотически точной. + +`f(n)` является o(g(n)), если можно подобрать такие действительные константы, +что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так +что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>). + +Определения О-символики для О Большого и О Малого похожи. Главное отличие в том, +что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_ +константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется +для _**всех**_ констант c > 0. + +### Омега Малое +Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки +верхней границы времени выполнения алгоритма при условии, что граница не является +асимптотически точной. + +`f(n)` является ω(g(n)), если можно подобрать такие действительные константы, +что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так +что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>). + +Определения Ω-символики и ω-символики похожи. Главное отличие в том, что +если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_ +константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n) +выполняется для _**всех**_ констант c > 0. + +### Тета +Тета, записывается как **Θ**, — это асимптотическая запись для оценки +_***асимптотически точной границы***_ времени выполнения алгоритма. + +`f(n)` является Θ(g(n)), если для некоторых действительных +констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0) +`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>). + +∴ `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n)) +и `f(n)` является Ω(g(n)). + +О Большое — основной инструмент для анализа сложности алгоритмов. +Также см. примеры по ссылкам. + +### Заключение +Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и +посмотреть дополнительную литературу. В ней даётся более глубокое описание с +определениями и примерами. + + +## Дополнительная литература + +* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/) +* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/) + +## Ссылки + +* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php) +* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903) + +## Ссылки (англ.) + +* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) +* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf) +* [Cheatsheet 2](http://bigocheatsheet.com/) + diff --git a/ru-ru/binary-search-ru.html.markdown b/ru-ru/binary-search-ru.html.markdown index 9ed62cb8..ab1a1585 100644 --- a/ru-ru/binary-search-ru.html.markdown +++ b/ru-ru/binary-search-ru.html.markdown @@ -55,7 +55,7 @@ def search(arr, x): ### На заметку -Существует и другая форма двоичного поиска, которая можеть быть полезна. +Существует и другая форма двоичного поиска, которая может быть полезна. ## На почитать diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown index fad1b434..43e9e6a3 100644 --- a/ru-ru/c++-ru.html.markdown +++ b/ru-ru/c++-ru.html.markdown @@ -17,7 +17,7 @@ C++ - компилируемый, статически типизированн - "лучшая замена C" - язык с поддержкой абстракции данных -- язык с поддержкой объектно-ориентированого программирования +- язык с поддержкой объектно-ориентированного программирования - язык с поддержкой обобщенного программирования Хотя его синтаксис может показаться более трудным или сложным для понимания, чем в более современных языках, diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown index eb5de011..a146a76b 100644 --- a/ru-ru/c-ru.html.markdown +++ b/ru-ru/c-ru.html.markdown @@ -476,7 +476,7 @@ void str_reverse_through_pointer(char *str_in) { Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com). Очень важно использовать правильные отступы и ставить пробелы в нужных местах. -Читаемый код лучше чем красивый или быстрый код. +Читаемый код лучше, чем красивый или быстрый код. Чтобы научиться писать хороший код, почитайте [Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle). Также не забывайте, что [Google](http://google.com) и [Яндекс](http://yandex.ru) – ваши хорошие друзья. diff --git a/ru-ru/common-lisp-ru.html.markdown b/ru-ru/common-lisp-ru.html.markdown index d5f9bf0e..0490ee30 100644 --- a/ru-ru/common-lisp-ru.html.markdown +++ b/ru-ru/common-lisp-ru.html.markdown @@ -14,7 +14,8 @@ Common Lisp - мультипарадигменный язык программи спектра задач. Его частенько называют программируемым языком программирования. -Идеальная отправная точка - книга [Common Lisp на практике (перевод)](http://lisper.ru/pcl/). +Идеальная отправная точка - книга +[Common Lisp на практике (перевод)](https://github.com/pcl-ru/pcl-ru/releases/download/v1.1/pcl-ru.pdf). Ещё одна популярная книга [Land of Lisp](http://landoflisp.com/). И одна из последних книг [Common Lisp Recipes](http://weitz.de/cl-recipes/) вобрала в себя лучшие архитектурные решения на основе опыта коммерческой работки автора. @@ -674,7 +675,7 @@ nil ; ложь; а ещё пустой список () тож ## Для чтения На русском -- [Practical Common Lisp](http://www.gigamonkeys.com/book/) +- [Practical Common Lisp](https://github.com/pcl-ru/pcl-ru/releases/download/v1.1/pcl-ru.pdf) На английском - [Practical Common Lisp](http://www.gigamonkeys.com/book/) @@ -685,7 +686,7 @@ nil ; ложь; а ещё пустой список () тож На русском -- [Lisper.ru](http://lisper.ru/) +- [Сообщество в Telegram](https://t.me/lisp_forever) На английском diff --git a/ru-ru/css-ru.html.markdown b/ru-ru/css-ru.html.markdown index e0e5e30b..b543bfeb 100644 --- a/ru-ru/css-ru.html.markdown +++ b/ru-ru/css-ru.html.markdown @@ -20,12 +20,12 @@ HTML элементы и определять их внешний вид. **ВАЖНО:** Так как результатом применения CSS является изменение внешнего вида элементов, постарайтесь использовать CSS-песочницы при изучении языка. -Например [dabblet](http://dabblet.com/). +Например, [dabblet](http://dabblet.com/). В данной статье рассматриваются в первую очередь синтаксис и общие рекомендации. ```css -/* Для комментариев используется слеш-астериск, как на этой строчке. +/* Для комментариев используется слэш-астериск, как на этой строчке. В CSS нет однострочных комментариев; все комментарии записываются таким способом */ /* #################### @@ -104,7 +104,7 @@ div.some-parent.class-name {} .i-am-any-before ~ .this-element {} -/* Существуют псевдо-классы, позволяющие изменять внешний вид элемента +/* Существуют псевдоклассы, позволяющие изменять внешний вид элемента в зависимости от событий, произошедших с элементом */ /* например, когда курсор наведен на элемент */ diff --git a/ru-ru/elixir-ru.html.markdown b/ru-ru/elixir-ru.html.markdown index c8c2c060..8dd48ba7 100644 --- a/ru-ru/elixir-ru.html.markdown +++ b/ru-ru/elixir-ru.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] diff --git a/ru-ru/forth-ru.html.markdown b/ru-ru/forth-ru.html.markdown index 2fc4ad7c..96fa0941 100644 --- a/ru-ru/forth-ru.html.markdown +++ b/ru-ru/forth-ru.html.markdown @@ -10,10 +10,10 @@ lang: ru-ru Форт создан Чарлзом Муром в 70-е годы. Это императивный, стековый язык программирования и среда исполнения программ. Использовался в таких проектах как Open Firmware. Продолжает применятся в проектах. Применяется в НАСА. -Внимание: эта материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах. +Внимание: этот материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах. -``` +```forth \ Это комментарий ( Это тоже комментарий, но используется для предоределённых слов ) diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown index 8d2eac90..22249a6e 100644 --- a/ru-ru/go-ru.html.markdown +++ b/ru-ru/go-ru.html.markdown @@ -82,7 +82,7 @@ func learnTypes() { // Символ не из ASCII. Исходный код Go в кодировке UTF-8. g := 'Σ' // тип rune, это алиас для типа int32, содержит символ юникода. - f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754). + f := 3.14159 // float64, 64-х битное число с плавающей точкой (IEEE-754). c := 3 + 4i // complex128, внутри себя содержит два float64. // Синтаксис var с инициализациями. @@ -334,12 +334,12 @@ func requestServer() { ## Что дальше -Основа всех основ в Go это [официальный веб сайт](http://golang.org/). +Основа всех основ в Go это [официальный веб сайт](https://go.dev/). Там можно пройти туториал, поиграться с интерактивной средой Go и почитать объёмную документацию. Для живого ознакомления рекомендуется почитать исходные коды [стандартной -библиотеки Go](http://golang.org/src/pkg/). Отлично задокументированная, она +библиотеки Go](https://go.dev/src/). Отлично задокументированная, она является лучшим источником для чтения и понимания Go, его стиля и идиом. Либо -можно, кликнув на имени функции в [документации](http://golang.org/pkg/), +можно, кликнув на имени функции в [документации](https://go.dev/pkg/), перейти к ее исходным кодам. diff --git a/ru-ru/haml-ru.html.markdown b/ru-ru/haml-ru.html.markdown index c2f8852e..ed823496 100644 --- a/ru-ru/haml-ru.html.markdown +++ b/ru-ru/haml-ru.html.markdown @@ -39,7 +39,7 @@ $ haml input_file.haml output_file.html / Комментарии / ------------------------------------------- -/ Комментари начинается с символа косой черты. +/ Комментарии начинается с символа косой черты. / Для написания многострочного комментария расположите ваш комментарий @@ -94,7 +94,7 @@ $ haml input_file.haml output_file.html / выведет 'Да & да' / - Чтобы выполнять Ruby-код без экранрования, можно использовать + Чтобы выполнять Ruby-код без экранирования, можно использовать "восклицательный знак" и "равно" (!=) %p @@ -196,13 +196,13 @@ $ haml input_file.haml output_file.html / ------------------------------------------- / - Фильтры передают связанный блок текста в соотвествующую + Фильтры передают связанный блок текста в соответствующую фильтрующую программу и возвращают результат в Haml Фильтр обозначается двоеточием и названием фильтра: / Markdown filter :markdown - # Заголовк + # Заголовок Текст **внутри** *блока* @@ -221,7 +221,7 @@ $ haml input_file.haml output_file.html </script> / - Существует множество типов фильров (:markdown, :javascript, :coffee, + Существует множество типов фильтров (:markdown, :javascript, :coffee, :css, :ruby и так далее). Вы можете определить собственный фильтр c помощью Haml::Filters. diff --git a/ru-ru/haskell-ru.html.markdown b/ru-ru/haskell-ru.html.markdown index b1b8eb79..aada30c1 100644 --- a/ru-ru/haskell-ru.html.markdown +++ b/ru-ru/haskell-ru.html.markdown @@ -8,7 +8,7 @@ translators: lang: ru-ru --- -Haskell разрабатывался, как чистый функциональный язык программирования, применимый на практике. Язык известен благодаря своей системе типов, и "знаменит" благодаря монадам. [Меня][autor] же Haskell заставляет возвращаться к себе снова и снова именно своей элегантностью и [я][autor] получаю истинное удовольствие, программируя на Haskell. +Haskell разрабатывался, как чистый функциональный язык программирования, применимый на практике. Язык известен благодаря своей системе типов, и "знаменит" благодаря монадам. [Меня][author] же Haskell заставляет возвращаться к себе снова и снова именно своей элегантностью и [я][author] получаю истинное удовольствие, программируя на Haskell. ```haskell -- Однострочные комментарии начинаются с двух дефисов @@ -172,7 +172,7 @@ fib x первое определение, к образцу которого "подойдет" набор аргументов -} fib 1 = 1 -fib 2 = 2 +fib 2 = 1 fib x = fib (x - 1) + fib (x - 2) -- Pattern matching для кортежей выглядит так @@ -544,4 +544,4 @@ Haskell прост в установке, забирайте [здесь](http:/ [Learn you a Haskell](http://learnyouahaskell.com/) и [Real World Haskell](http://book.realworldhaskell.org/). -[autor]: http://adit.io имеется в виду автор оригинального текста Adit Bhargava *(примечание переводчика)* +[author]: http://adit.io имеется в виду автор оригинального текста Adit Bhargava *(примечание переводчика)* diff --git a/ru-ru/html-ru.html.markdown b/ru-ru/html-ru.html.markdown index 120981b9..e18fb8a0 100644 --- a/ru-ru/html-ru.html.markdown +++ b/ru-ru/html-ru.html.markdown @@ -8,28 +8,28 @@ translators: lang: ru-ru --- -HTML расшифровывается как Hypertext Markup Language(гипертекстовый язык разметки). -Это язык используют для написания страниц для World Wide Web(всемирной паутины). -Это язык разметки позволяет писать веб-страниц с помощью кода, чтобы определять, -как должны быть отображены текст и данные. +HTML расшифровывается как Hypertext Markup Language (гипертекстовый язык разметки). +Этот язык используют для написания страниц для World Wide Web (всемирной паутины). +Этот язык разметки позволяет описать веб-страницу с помощью кода, чтобы определить, +как на ней должны быть отображены текст и данные. На самом деле, HTML файлы представляют собой простые текстовые файлы. -Что такое разметка? Это способ организации данных страницы, -путем открытия и закрытия тегов(помещая данные внутрь этих тегов). -Эта разметка служит, чтобы придать значение тексту, который он окружает. +Что такое разметка? Это способ организации данных страницы +путем открытия и закрытия тегов и помещения данных внутрь этих тегов. +Эта разметка служит, чтобы придать значение тексту, который она окружает. Как и в других языках программирования, HTML имеет много версий. Здесь мы будем говорить о HTML5. **Примечание:** Вы можете тестировать различные теги и элементы по мере продвижения -через учебник на сайте, как [codepen](http://codepen.io/pen/) для того, чтобы увидеть +через учебник на сайте [codepen](http://codepen.io/pen/) для того, чтобы увидеть их влияние, понять, как они работают и ознакомиться с языком. -В данной статье рассматривается в основном HTML синтаксис и некоторые полезные советы. +В данной статье рассматривается в основном HTML-синтаксис и некоторые полезные советы. ```html -<!-- Комментарии заключаются как эта лини\! --> +<!-- Это комментарий. --> <!-- #################### Теги #################### --> -<!-- Ниже приведен пример HTML-файл, который мы будем анализировать. --> +<!-- Ниже приведен пример HTML-файла, который мы будем анализировать. --> <!doctype html> <html> @@ -39,7 +39,7 @@ HTML расшифровывается как Hypertext Markup Language(гипе <body> <h1>Привет, мир!</h1> <a href = "http://codepen.io/anon/pen/xwjLbZ"> - Переходите сюда, чтоб посмотреть как это выглядит. + Переходите сюда, чтобы посмотреть, как это выглядит. </a> <p>Это параграф.</p> <p>Это другой параграф.</p> @@ -51,41 +51,41 @@ HTML расшифровывается как Hypertext Markup Language(гипе </body> </html> -<!-- HTML-файл всегда начинается с указанием браузеру, что страница это HTML. --> +<!-- HTML-файл всегда начинается с указания браузеру, что страница — это HTML. --> <!doctype html> -<!-- После этого, страница начинается с <html> тега. --> +<!-- После этого страница начинается с <html> тега. --> <html> -<!-- страница будет закрыта в конце с помощью тега </html>. --> +<!-- Страница будет закрыта в конце с помощью тега </html>. --> </html> <!-- Ничто не должно появиться после этого заключительного тега. --> -<!-- Внутри (между открывающим и закрывающим тегами <html> </ html>), мы находим: --> +<!-- Внутри (между открывающим и закрывающим тегами <html> </ html>) мы находим: --> -<!-- Заголовок определяется <head> (it он должен быть закрыт </head>). --> +<!-- Заголовок определяется <head> (и он должен быть закрыт </head>). --> <!-- Заголовок содержит описание и дополнительную информацию, которая не отображается; это метаданные. --> <head> - <title>Мой сайт</title><!-- Тег <title> указывает браузеру заголовок, чтобы показать в строке заголовка названия и вкладки браузера окна. --> + <title>Мой сайт</title><!-- Тег <title> указывает браузеру заголовок, который следует показать в строке заголовка названия и вкладки браузера окна. --> </head> -<!-- После секция <head>, находится секция - <body> --> -<!-- До этого момента, ничего описаное не будет отображаться в окне браузера. --> -<!-- Мы должны наполнить <body> содержанием, которое будет отображаться. --> +<!-- После секции <head>, находится секция - <body> --> +<!-- До этого момента, ничего из описанного не будет отображаться в окне браузера. --> +<!-- Мы должны наполнить <body> содержанием, которое будет отображаться. --> <body> <h1>Hello, world!</h1> <!-- Тег h1 создает заголовок. --> - <!-- Так же существуют другие заголовки от имеющего большее значение <h1> по убыванию к <h6>. --> - <a href = "http://codepen.io/anon/pen/xwjLbZ">Переходите сюда, чтоб посмотреть как это выглядит.</a> - <!--гиперссылка на URL, заданнf атрибутом href="" --> - <p>Это параграф.</p> <!-- Тег <p> позволяет нам добавдять текст на странице HTML. --> + <!-- Также существуют другие заголовки от имеющего большее значение <h1> до меньшего <h6>. --> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Переходите сюда, чтобы посмотреть, как это выглядит.</a> + <!--гиперссылка на URL, заданная атрибутом href="" --> + <p>Это параграф.</p> <!-- Тег <p> позволяет нам добавлять текст на странице HTML. --> <p>Это другой параграф.</p> <ul> <!-- Тег <ul> создает маркированный список. --> - <!-- Для того, чтобы иметь пронумерованный список лучше использовать <ol> - тогда первый элемент будет иметь значение 1. для второго элемента, 2. и так далее. --> - <li>Это элемент в не нумерованном списке (маркированный список)</li> + <!-- Для того, чтобы иметь пронумерованный список, лучше использовать <ol> + тогда первый элемент будет иметь значение 1., для второго элемента 2. и так далее. --> + <li>Это элемент в ненумерованном списке (маркированный список)</li> <li>Это еще один элемент</li> <li>И это последний пункт в списке</li> </ul> @@ -124,6 +124,6 @@ HTML файлы имеют окончание(расширение) `.html`. ## Узнать больше -* [википедиа](https://ru.wikipedia.org/wiki/HTML) +* [википедия](https://ru.wikipedia.org/wiki/HTML) * [HTML учебник](https://developer.mozilla.org/ru/docs/Web/HTML) * [htmlbook](http://htmlbook.ru/) diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown index 4556b425..4c4fa503 100644 --- a/ru-ru/javascript-ru.html.markdown +++ b/ru-ru/javascript-ru.html.markdown @@ -504,7 +504,7 @@ if (Object.create === undefined) { // не перезаписываем мето [Mozilla Developer Network](https://developer.mozilla.org/ru/docs/Web/JavaScript) — предоставляет отличную документацию для JavaScript, как он используется в браузерах. -Кроме того, это вики, поэтому, если вы знаете больше, вы можете помочь другим, +Кроме того, это вики. Поэтому, если вы знаете больше, вы можете помочь другим, делясь своими знаниями. [JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) — это diff --git a/ru-ru/learnvisualbasic-ru.html.markdown b/ru-ru/learnvisualbasic-ru.html.markdown index 72e1358c..6242fc42 100644 --- a/ru-ru/learnvisualbasic-ru.html.markdown +++ b/ru-ru/learnvisualbasic-ru.html.markdown @@ -8,7 +8,7 @@ filename: learnvisualbasic-ru.vb lang: ru-ru --- -```vbnet +```visualbasic Module Module1 Sub Main() diff --git a/ru-ru/linker-ru.html.markdown b/ru-ru/linker-ru.html.markdown index 7df29c23..14cfd229 100644 --- a/ru-ru/linker-ru.html.markdown +++ b/ru-ru/linker-ru.html.markdown @@ -34,11 +34,11 @@ lang: ru-ru # Определяем точку входа в программу ENTRY(Reset_Handler) -# Определяем перемнную которая содержит адрес вершины стека +# Определяем переменную которая содержит адрес вершины стека _estack = 0x20020000; -# Определяем перемнную которая содержит значение размера кучи +# Определяем переменную которая содержит значение размера кучи _Min_Heap_Size = 0x200; -# Определяем перемнную которая содержит значение размера стека +# Определяем переменную которая содержит значение размера стека _Min_Stack_Size = 0x400; # Описание карты памяти доступной для данного процессора @@ -50,7 +50,7 @@ _Min_Stack_Size = 0x400; # RAM - начинается с адреса 0x20000000 и занимает 128 Кбайт; # CCMRAM - начинается с адреса 0x10000000и занимает 64 Кбайт; # FLASH - начинается с адреса 0x8000000 занимает 1024 Кбайт; -# Причем RAM память доступка для чтения, записи и исполнения. +# Причем RAM память доступна для чтения, записи и исполнения. # CCMRAM память доступна только на чтение и запись. # FLASH память доступна на чтение и исполнение. MEMORY @@ -70,7 +70,7 @@ SECTIONS . = ALIGN(4); # Существует опция --gc-sections, которая позволяет собирать мусор из неиспользуемых - # входных разделов. И если есть разделы, которые сборщик муссора не должен трогать, + # входных разделов. И если есть разделы, которые сборщик мусора не должен трогать, # то их необходимо указать в качестве аргумента функции KEEP() (аналог ключевого слова # volatile). # Запись (*(.isr_vector)) означает разделы .isr_vector во всех объектных файлах. Т.к. @@ -80,8 +80,8 @@ SECTIONS # Выравниваем текущую позицию на границу 4-х байт. . = ALIGN(4); - # Выражение ">ОБЛАСТЬ_ПАМЯТИ" указывает в какую именно область памяти будет помещенна - # данная секция. В нашем слущае секция .isr_vector будет размещена во FLASH памяти. + # Выражение ">ОБЛАСТЬ_ПАМЯТИ" указывает в какую именно область памяти будет помещена + # данная секция. В нашем случае секция .isr_vector будет размещена во FLASH памяти. } >FLASH # ИТОГО: Секция .isr_vector, которая содержит таблицу векторов прерываний выравнивается @@ -125,7 +125,7 @@ SECTIONS # Выравниваем текущую позицию на границу 4-х байт. . = ALIGN(4); - # Указываем, что в данной секции будут хранится области .rodataвсех + # Указываем, что в данной секции будут хранится области .rodata всех # объектных файлов *(.rodata) *(.rodata*) @@ -158,13 +158,13 @@ SECTIONS _edata = .; # Функция AT указывает на то, что данный сектор хранится в одной области памяти - # (в нашем случае FLASH), а исполняться будет из другой обасти памяти (в нашем случае RAM). - # Есть два типа адрессов: - # * VMA (Virtual memory address) - это run-time адрес по которому уомпилятор ожидает + # (в нашем случае FLASH), а исполняться будет из другой области памяти (в нашем случае RAM). + # Есть два типа адресов: + # * VMA (Virtual memory address) - это run-time адрес по которому компилятор ожидает # видеть данные. # * LMA (Load memory address) - это адрес по которому линкер хранит данные. - #Startup должен код скопировать секцию .data из адрессов LMA в адресса VMA. + #Startup должен код скопировать секцию .data из адресов LMA в адреса VMA. } >RAM AT> FLASH diff --git a/ru-ru/markdown-ru.html.markdown b/ru-ru/markdown-ru.html.markdown index 579a9a20..fc8614c4 100644 --- a/ru-ru/markdown-ru.html.markdown +++ b/ru-ru/markdown-ru.html.markdown @@ -45,7 +45,7 @@ Markdown является надмножеством HTML, поэтому люб HTML-элементов --> ``` -## Заголовки +## Заголовки HTML-элементы от <h1> до <h6> размечаются очень просто: текст, который должен стать заголовком, предваряется @@ -85,7 +85,7 @@ __И этот тоже.__ *__И даже здесь!__* ``` -В Github Flavored Markdown, стандарте, который используется в Github, +В GitHub Flavored Markdown, стандарте, который используется в GitHub, текст также можно сделать зачёркнутым: ```md @@ -110,7 +110,7 @@ __И этот тоже.__ Для вставки принудительных переносов можно завершить абзац двумя дополнительными пробелами: ```md -Эта строка завершается двумя пробелами (выделите, чтобы увидеть!). +Эта строка завершается двумя пробелами (выделите, чтобы увидеть!). Над этой строкой есть <br />! ``` @@ -208,7 +208,7 @@ __И этот тоже.__ ```md my_array.each do |item| - puts item + puts item end ``` @@ -220,18 +220,17 @@ __И этот тоже.__ Ваня даже не знал, что делает функция `go_to()`! ``` -В Github Flavored Markdown для блоков кода можно использовать +В GitHub Flavored Markdown для блоков кода можно использовать специальный синтаксис: -<pre> -<code class="highlight">```ruby +```ruby def foobar - puts "Привет, мир!" + puts "Привет, мир!" end -```</code></pre> +``` Во фрагменте, приведённом выше, отступ не требуется. -Кроме того, Github подсветит синтаксис языка, указанного после \`\`\` +Кроме того, GitHub подсветит синтаксис языка, указанного после \`\`\` ## Горизонтальный разделитель @@ -255,6 +254,7 @@ end ```md [Ссылка!](http://test.com/) ``` + Также для ссылки можно указать всплывающую подсказку (`title`), используя кавычки внутри круглых скобок: @@ -269,11 +269,13 @@ end Markdown также позволяет размечать ссылку в виде сноски: -<pre><code class="highlight">[<span class="nv">Щёлкните эту ссылку</span>][<span class="ss">link1</span>] для подробной информации! -[<span class="nv">Также посмотрите эту ссылку,</span>][<span class="ss">foobar</span>] если хотите. +```md +[Щёлкните эту ссылку][link1] для подробной информации! +[Также посмотрите эту ссылку,][foobar] если хотите. -[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Круто!"</span> -[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Нормально!"</span></code></pre> +[link1]: http://test.com/ "Круто!" +[foobar]: http://foobar.biz/ "Нормально!" +``` `Title` также может быть в одинарных кавычках или круглых скобках, а также отсутствовать вовсе. Ссылки на сноски могут быть в любом месте документа, @@ -281,9 +283,11 @@ Markdown также позволяет размечать ссылку в вид Существует также неявное именование, когда ссылка является идентификатором. -<pre><code class="highlight">[<span class="nv">Это</span>][] ссылка. +```md +[Это][] ссылка. -[<span class="nv">это</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> +[это]: http://thisisalink.com/ +``` Правда, эта возможность не очень распространена. @@ -294,11 +298,15 @@ Markdown также позволяет размечать ссылку в вид ```md ![Альтернативный текст для изображения](http://imgur.com/myimage.jpg "Подсказка") ``` -Изображения тоже могут быть оформлены, как сноски. -<pre><code class="highlight">![<span class="nv">Это альтернативный текст.</span>][<span class="ss">myimage</span>] +Изображения тоже могут быть оформлены как сноски. + +```md +![Это альтернативный текст.][myimage] + +[myimage]: relative/urls/cool/image.jpg "Если нужна подсказка, её можно добавить" +``` -[<span class="nv">myimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"Если нужна подсказка, её можно добавить"</span></code></pre> ## Разное ### Автоссылки @@ -322,7 +330,7 @@ Markdown также позволяет размечать ссылку в вид ``` ### Клавиши на клавиатуре -В Github Flavored Markdown для представления клавиш на клавиатуре +В GitHub Flavored Markdown для представления клавиш на клавиатуре вы можете использовать тег `<kbd>`. ```md @@ -341,6 +349,7 @@ Markdown также позволяет размечать ссылку в вид | Выравнивание | Выравнивание | Выравнивание | | влево | по центру | вправо | ``` + Или более компактно ```md diff --git a/ru-ru/nim-ru.html.markdown b/ru-ru/nim-ru.html.markdown index 0e08f1bf..09784792 100644 --- a/ru-ru/nim-ru.html.markdown +++ b/ru-ru/nim-ru.html.markdown @@ -3,7 +3,7 @@ language: Nim filename: learnNim-ru.nim contributors: - ["Jason J. Ayala P.", "http://JasonAyala.com"] - - ["Dennis Felsing", "http://felsin9.de/nnis/"] + - ["Dennis Felsing", "https://dennis.felsing.org"] translators: - ["Nomadic", "https://github.com/n0madic"] - ["dvska", "https://github.com/dvska"] diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown index af77a9ca..4a508cfc 100644 --- a/ru-ru/php-ru.html.markdown +++ b/ru-ru/php-ru.html.markdown @@ -125,7 +125,7 @@ echo 'Multiple', 'Parameters', 'Valid'; // печатает 'MultipleParametersV // и никогда не может быть изменена во время выполнения программы! // Правильное имя константы начинается с буквы или символа подчеркивания -// и содержит любое колличество букв, цифр или символов подчеркивания. +// и содержит любое количество букв, цифр или символов подчеркивания. define("FOO", "something"); // Доступ к константе возможен через прямое указание её имени без знака $ @@ -224,7 +224,7 @@ assert($c > $b); // больше assert($a <= $b); // меньше или равно assert($c >= $d); // больше или равно -// Следующие утверждения истинны, если переменные имеют одинаковые тип. +// Следующие утверждения истинны, если переменные имеют одинаковый тип. assert($c === $d); assert($a !== $d); assert(1 == '1'); @@ -251,7 +251,7 @@ echo $string + $string; // => 2 (строка превращается в чис $string = 'one'; echo $string + $string; // => 0 -// Приведение типов (type casting) может быть использовано для преобразование +// Приведение типов (type casting) может быть использовано для преобразования // переменной в другой тип $boolean = (boolean) 1; // => true @@ -458,7 +458,7 @@ include_once 'my-file.php'; require 'my-file.php'; require_once 'my-file.php'; -// Действует также как и include(), но если файл не удалось подключить, +// Действует так же как и include(), но если файл не удалось подключить, // функция выдает фатальную ошибку // Содержимое файла my-include.php: @@ -497,7 +497,7 @@ class MyClass // Конструктор описывается с помощью __construct public function __construct($instanceProp) { - // Доступ к эземпляру класса с помощью $this + // Доступ к экземпляру класса с помощью $this $this->instanceProp = $instanceProp; } @@ -661,7 +661,7 @@ $cls->myTraitMethod(); // Напечатает "I have MyTrait" <?php // По умолчанию, классы существуют в глобальном пространстве имен и могут быть -// вызваны с обратным слешем. +// вызваны с обратным слэшем. $cls = new \MyClass(); @@ -762,7 +762,7 @@ echo "Current method is " . __METHOD__; echo "Current namespace is " . __NAMESPACE__; // Возвращает имя текущего трейта. -// Возвращает только если испольщуется внутри трейта. +// Возвращает только если используется внутри трейта. echo "Current namespace is " . __TRAIT__; @@ -771,7 +771,7 @@ echo "Current namespace is " . __TRAIT__; * */ -// Простую обработку ошибок можно произвести спомощью try catch блока. +// Простую обработку ошибок можно произвести с помощью try catch блока. try { // Выполняем что-то @@ -779,7 +779,7 @@ try { // Обработка исключения } -// При использовании try catch блока в области вилимости, стоит использовать +// При использовании try catch блока в области видимости, стоит использовать // следующий подход: try { @@ -788,7 +788,7 @@ try { // Обработка исключения } -// Специальное(кастомное) исключение - exceptions +// Специальное (кастомное) исключение - exceptions class MyException extends Exception {} @@ -797,7 +797,7 @@ try { $condition = true; if ($condition) { - throw new MyException('Something just happend'); + throw new MyException('Something just happened'); } } catch (MyException $e) { diff --git a/ru-ru/pyqt-ru.html.markdown b/ru-ru/pyqt-ru.html.markdown index 24afc03d..a7e14c02 100644 --- a/ru-ru/pyqt-ru.html.markdown +++ b/ru-ru/pyqt-ru.html.markdown @@ -11,7 +11,7 @@ translators: **Qt** - широко известный кросс-платформенный фреймворк для разработки программного обеспечения, который может быть использован на различных софтварных и хардварных платформах без какого-либо -изменения в коде. Данный фреймворк при этом обладает мощью и скоростью нативных приложений. +изменения в коде. Данный фреймворк при этом обладает мощью и скоростью нативных приложений. Qt и был изначально написан на *C++*. Данный текст является адаптацией введения в Qt на C++ под авторством Алексея Ковальчука для pyqt. @@ -20,7 +20,7 @@ Qt и был изначально написан на *C++*. ```python def window(): - # Создайте объект приложения + # Создайте объект приложения app = QtGui.QApplication(sys.argv) # Создайте виджет, где будет находиться наш лейбл w = QtGui.QWidget() @@ -28,10 +28,10 @@ def window(): b = QtGui.QLabel(w) # Задайте текст для лейбла b.setText("Hello World!") - # Задайте информация о размере и расположении + # Задайте информация о размере и расположении w.setGeometry(100, 100, 200, 50) b.move(50, 20) - # Задайте заголовок окна + # Задайте заголовок окна w.setWindowTitle("PyQt") # Все ранее написанное выводится на экран w.show() @@ -43,11 +43,11 @@ if __name__ == '__main__': ``` -Для того, чтобы получить более продвинутые функции приложения в pyqt, нам необходимо -обратить внимание на создание дополнительных элементов. Ниже представлено создание всплывающего диалогового окна, которое просит пользователя подтвердить его решение или предоставить какую-либо +Для того чтобы получить более продвинутые функции приложения в pyqt, нам необходимо +обратить внимание на создание дополнительных элементов. Ниже представлено создание всплывающего диалогового окна, которое просит пользователя подтвердить его решение или предоставить какую-либо информацию. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -67,7 +67,7 @@ def window(): w.show() sys.exit(app.exec_()) -Данная функция должна создавать диалоговое окно с кнопкой, которая ждет клика по себе +Данная функция должна создавать диалоговое окно с кнопкой, которая ждет клика по себе и затем завершает программу. def showdialog(): diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown index e0e53b9c..e088593e 100644 --- a/ru-ru/python-ru.html.markdown +++ b/ru-ru/python-ru.html.markdown @@ -353,7 +353,6 @@ empty_set = set() # Да, оно выглядит примерно как словарь. Ну извините, так уж вышло. filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} -# Similar to keys of a dictionary, elements of a set have to be immutable. # Как и ключи словаря, элементы множества должны быть неизменяемыми. invalid_set = {[1], 1} # => Выбрасывает ошибку TypeError: unhashable type: 'list' valid_set = {(1,), 1} diff --git a/ru-ru/qt-ru.html.markdown b/ru-ru/qt-ru.html.markdown index 5fbcc3b4..15e2c775 100644 --- a/ru-ru/qt-ru.html.markdown +++ b/ru-ru/qt-ru.html.markdown @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) { ``` Обратите внимание на метод *QObject::connect*. Этот метод соединяет *СИГНАЛЫ* одного объекта со *СЛОТАМИ* другого. -**Сигналы** отправляются когда с объектами происходят отпределённые события, например, сигнал *нажатие* отправляется когда пользователь нажимает на объект типа QPushButton. +**Сигналы** отправляются когда с объектами происходят определённые события, например, сигнал *нажатие* отправляется, когда пользователь нажимает на объект типа QPushButton. **Слоты** это *действия*, которые могут быть выполнены в ответ на полученные сигналы. diff --git a/ru-ru/sql-ru.html.markdown b/ru-ru/sql-ru.html.markdown index 7353a175..702a8102 100644 --- a/ru-ru/sql-ru.html.markdown +++ b/ru-ru/sql-ru.html.markdown @@ -22,9 +22,9 @@ lang: ru-ru поддерживают ключевые слова QUIT, EXIT или оба). Некоторые команды ниже предполагают использование -[демонстрационного образца базы данных сотрудников от MySQL](https://dev.mysql.com/doc/employee/en/), доступного на [Github](https://github.com/datacharmer/test_db). +[демонстрационного образца базы данных сотрудников от MySQL](https://dev.mysql.com/doc/employee/en/), доступного на [GitHub](https://github.com/datacharmer/test_db). Следовательно, для повторения команд в локальном окружении он должен быть загружен. -Файлы на github — это скрипты с командами, которые схожи с командами ниже, +Файлы на github — это скрипты с командами, схожие с командами ниже, которые создают и манипулируют таблицами и данными о сотрудниках вымышленной компании. Синтаксис для запуска этих скриптов будет зависеть от используемой вами реализации SQL. Обычно используется утилита, запускаемая из командной @@ -50,7 +50,7 @@ SHOW DATABASES; USE employees; -- Выбрать все строки и колонки из таблицы «departments» (отделы) текущей базы. --- В интерактивном режиме обыч но результат будет выведен на экран. +-- В интерактивном режиме обычно результат будет выведен на экран. SELECT * FROM departments; -- Тот же запрос, что и выше, но выбор только колонок «dept_no» и «dept_name». diff --git a/ru-ru/tcl-ru.html.markdown b/ru-ru/tcl-ru.html.markdown new file mode 100644 index 00000000..380d7b05 --- /dev/null +++ b/ru-ru/tcl-ru.html.markdown @@ -0,0 +1,584 @@ +--- +language: Tcl +lang: ru-ru +contributors: + - ["Poor Yorick", "https://pooryorick.com/"] +translators: + - ["Viktor Sokhranov", "https://github.com/weirdvic"] +filename: learntcl-ru.tcl +--- + +Tcl был создан [Джоном Оустерхаутом](https://ru.wikipedia.org/wiki/Оустерхаут,_Джон) +в качестве скриптового языка в своих инструментах проектирования электрических цепей. +В 1997 году за разработку языка Tcl автор получил [ACM](https://ru.wikipedia.org/wiki/ACM) + Software System Award. Tcl может использоваться и как встраиваемый скриптовый язык, +и как язык программирования общего назначения. Кроме того, он может быть использован как +библиотека в программах на C, даже в случаях когда не требуется написание скриптов, +поскольку Tcl может предоставить программе на C различные типы данных, такие как +динамические строки, списки и хэш-таблицы. Также с помощью этой библиотеки возможно +использовать форматирование строк, операции с файловой системой, работу с кодировками и +динамически загружаемые библиотеки. К другим особенностям Tcl относятся: + +* Удобный кроссплатформенный API для работы с сетью + +* Поддержка виртуальной файловой системы (VFS) + +* Стекируемые каналы ввода-вывода + +* Асинхронность в ядре языка + +* Поддержка корутин + +* Простая и надёжная модель потоков выполнения + +Tcl имеет много общего с Lisp, но в отличие от списков, в Tcl "валютой" языка +являются строки. Все значения являются строками. Список в Tcl это просто строка в +определённом формате, а тело процедуры (скрипт) это ещё одна строка, а не блок. +С целью увеличения производительности, интерпретатор Tcl использует кэшированные +внутренние представления различных типов данных. Например, рутины (routines), работающие +со списками, фактически используют внутреннее представление списков, а интерпретатор +Tcl обновляет строковое представление в том случае если оно используется в скрипте. +В Tcl используется подход copy-on-write, позволяющий оперировать большими объёмами +данных без дополнительного оверхеда. Процедуры в Tcl автоматически компилируются +в байткод, кроме случаев когда в процедуре используются динамические рутины, такие +как `uplevel`, `upvar` и `trace`. + +Программировать на Tcl приятно. Его находят привлекательным хакеры, которым интересны +Lisp, Forth или Smalltalk, а также инженеры и учёные, которым просто необходим +гибкий инструмент для выполнения их задач. В Tcl языковые конструкции, включая +циклы и математические операторы, представлены в виде изменяемых рутин, в отличие +от других языков программирования, где они закреплены в синтаксисе, что позволяет +синтаксису Tcl не мешать работать с предметной областью проекта. Синтаксис Tcl в этом +смысле даже более минималистичен чем у Lisp. + +```tcl +#! /bin/env tclsh + +############################################################################### +## 1. Рекомендации +############################################################################### + +# Tcl это не shell или C! Этот момент требует уточнения, поскольку привычки +# написания shell-скриптов почти работают в Tcl и часто люди начинают +# изучать Tcl со знанием синтаксиса других языков. Поначалу это работает, но +# когда скрипты становятся сложнее, наступает фрустрация. + +# Фигурные скобки {} в Tcl используются не для построения блоков кода или +# списков, а как механизм экранирования (quoting) для кода. Фактически в Tcl +# нет ни списков, ни блоков кода. Фигурные скобки использутся для +# экранирования специальных символов и потому подходят для представления +# тела процедур и строк, которые должны интерпретироваться как списки. + + +############################################################################### +## 2. Синтаксис +############################################################################### + +# Скрипт состоит из команд, разделённых символами перевода строки или символами +# точки с запятой. Каждая команда представляет собой вызов рутины. Первое слово +# это имя вызываемой рутины, а последующие слова это аргументы. Слова разделены +# пробелами. Так как каждый аргумент это слово в команде, он является строкой и +# может быть неэкранирован: +set part1 Sal +set part2 ut; set part3 ations + + +# символ доллара используется для подставления значения переменных: +set greeting $part1$part2$part3 + + +# Когда "set" получает только имя переменной, возвращается значение переменной: +set part3 ;# Возвращает значение переменной + + +# Содержимое квадратных скобок заменяется на результат выполнения: +set greeting $part1$part2[set part3] + + +# Встроенный таким образов скрипт может состоять из нескольких команд, но +# результат подстановки определяется последней командой: +set greeting $greeting[ + incr i + incr i + incr i +] +puts $greeting ;# Выведет "Salutations3" + +# Каждое слово в команде является строкой, включая имя рутины, поэтому +# подстановки могут быть использованы и таким образом: +set action pu + +# следующие команды эквивалентны: +puts $greeting +${action}ts $greeting +[set action]ts $greeting + + +# Обратный слэш экранирует специальные символы: +set amount \$16.42 + + +# и он же используется для ввода специальных символов: +puts lots\nof\n\n\n\n\n\nnewlines + + +# Слово в фигурных скобках никак не интерпретируется и в нём не работают +# никакие подстановки, за исключением экранирования закрывающей скобки: +set somevar { + Это литерал знака $, а это \} экранированная закрывающая скобка +} + + +# В слове внутри двойных кавычек, пробельные символы теряют своё +# специальное значение: +set name Neo +set greeting "Hello, $name" + + +# Имя переменной может быть любой строкой: +set {first name} New + + +# Фигурные скобки используются для доступа к переменным с составными именами: +set greeting "Hello, ${first name}" + + +# "set" всегда можно использовать вместо подстановки переменной: +set greeting "Hello, [set {first name}]" + + +# Чтобы "распаковать" список в команду используется оператор расширения "{*}" +# Эти две команды эквивалентны: +set name Neo +set {*}{name Neo} + + +# Массив это особая переменная, являющаяся контейнером для других переменных. +set person(name) Neo +set person(destiny) {The One} +set greeting "Hello, $person(name)" + + +# "variable" может быть использована для объявления или установки переменных. +# В отличие от "set", которая использует глобальное и локальное пространство +# имён, "variable" работает только с локальным пространством: +variable name New + + +# "namespace eval" создаёт новое пространство имён, если его не существует. +# Пространство имён может содержать рутины и переменные: +namespace eval people { + namespace eval person1 { + variable name Neo + } +} + + +# Двумя или более двоеточиями в именах переменных отделяется название +# пространства имён: +namespace eval people { + set greeting "Hello $person1::name" +} + +# Два или более двоеточия также отделяют название пространства имён +# в имени рутины: +proc people::person1::speak {} { + puts {I am The One.} +} + +# Полные(fully-qualified) имена начинаются с двух двоеточий: +set greeting "Hello $::people::person1::name" + + + +############################################################################### +## 3. Больше никакого синтаксиса +############################################################################### + +# Все остальные функции реализованы посредством рутин. С этого момента и далее +# больше нет нового синтаксиса. Всё остальное что можно изучить о Tcl это +# поведение отдельных рутин и какие значения они присваивают своим аргументам. + + + +############################################################################### +## 4. Переменные и пространства имён +############################################################################### + +# Каждая переменная и рутина связана с пространством имён. + +# Чтобы получить интерпретатор, который не может сделать ничего, достаточно +# удалить глобальное пространство имён. Особой пользы в этом нет, но это хорошо +# иллюстрирует природу Tcl. Фактически имя глобального пространства имён это +# пустая строка, но единственный способ представить её -- в виде полного имени: +proc delete_global_namespace {} { + namespace delete :: +} + +# Поскольку "set" всегда учитывает и глобальное, и текущее пространства имён, +# более безопасно использовать "variable" чтобы объявить новую переменную или +# задать значение переменной. Если переменная с именем "name" уже существует +# в глобальном пространстве имён, использование "set" задаст значение +# глобальной переменной, тогда как "variable" работает только с текущим +# пространством имён. + +namespace eval people { + namespace eval person1 { + variable name Neo + } +} + +# После объявления переменной в пространстве имён, [set] видит её, а не +# одноимённую переменную в глобальном пространстве имён: + +namespace eval people { + namespace eval person1 { + variable name + set name Neo + } +} + +# Но если "set" приходится создать новую переменную, он всегда делает это +# с учётом текущего пространства имён: +unset name +namespace eval people { + namespace eval person1 { + set name neo + } + +} +set people::person1::name + + +# Абсолютное имя всегда начинается с имени глобального пространства имён, то +# есть с пустой строки, за которой следует два двоеточия: +set ::people::person1::name Neo + + +# В пределах процедуры "variable" связывает перменную в текущем пространстве +# имён с локальной областью видимости: +namespace eval people::person1 { + proc fly {} { + variable name + puts "$name is flying!" + } +} + + + + +############################################################################### +## 5. Встроенные рутины +############################################################################### + +# Математические операции можно выполнять при помощи "expr": +set a 3 +set b 4 +set c [expr {$a + $b}] + +# Поскольку "expr" самостоятельно занимается подстановкой значений переменных, +# математическое выражение нужно оборачивать в фигурные скобки чтобы отключить +# подстановку значений переменных интерпретатором Tcl. +# Подробнее об этом можно прочесть здесь: +# "https://wiki.tcl-lang.org/page/Brace+your+expr-essions" + + +# "expr" выполняет подстановку переменных и результатов команд: +set c [expr {$a + [set b]}] + + +# "expr" предоставляет разные математические функции: +set c [expr {pow($a,$b)}] + + +# Математические операторы сами по себе доступны в виде рутин в +# пространстве имён ::tcl::mathop +::tcl::mathop::+ 5 3 + +# Рутины могут быть импортированы из других пространств имён: +namespace import ::tcl::mathop::+ +set result [+ 5 3] + + +# Не числовые значения должны быть квотированы. Такие операторы как "eq" +# Могут быть использованы чтобы провести строковое сравнение: +set name Neo +expr {{Bob} eq $name} + +# Общие операторы сравнения тоже работают со строками если числовое значение +# операнда недоступно: +expr {{Bob} == $name} + + +# "proc" создаёт новые рутины: +proc greet name { + return "Hello, $name!" +} + +# можно указать несколько параметров: +proc greet {greeting name} { + return "$greeting, $name!" +} + + +# Как было отмечено ранее, фигурные скобки не обозначают блок кода. +# Любое значение, даже третий аргумент "proc", является строкой. +# Предыдущая команда может быть переписана без использования фигурных скобок: +proc greet greeting\ name return\ \"\$greeting,\ \$name!\" + + + +# Если последний параметр называется "args", все дополнительные аргументы, +# переданные рутине, собираются в список и передаются как "args": +proc fold {cmd first args} { + foreach arg $args { + set first [$cmd $first $arg] + } + return $first +} +fold ::tcl::mathop::* 5 3 3 ;# -> 45 + + +# Условное выполнение тоже реализовано как рутина: +if {3 > 4} { + puts {This will never happen} +} elseif {4 > 4} { + puts {This will also never happen} +} else { + puts {This will always happen} +} + + +# Циклы реализованы как рутины. Первый и третий аргумент для "for" +# обрабатываются как скрипты, а второй аргумент как выражение: +set res 0 +for {set i 0} {$i < 10} {incr i} { + set res [expr {$res + $i}] +} +unset res + + +# Первый аргумент для "while" тоже обрабатывается как выражение: +set i 0 +while {$i < 10} { + incr i 2 +} + + +# Список это строка, а элементы списка разделены пробелами: +set amounts 10\ 33\ 18 +set amount [lindex $amounts 1] + +# Если элемент списка содержит пробел, его надо экранировать: +set inventory {"item 1" item\ 2 {item 3}} + + +# Хорошая практика использовать списковые рутины для обработки списков: +lappend inventory {item 1} {item 2} {item 3} + + +# Фигурные скобки и бэкслеш могут быть использованы чтобы хранить более +# комплексные структуры внутри списков. Список выглядит как скрипт, за +# исключением того, что перевод строки и точка с запятой теряют своё +# специальное значение, а также не производится подстановка значений. +# Эта особенность Tcl называется гомоиконичность +# https://ru.wikipedia.org/wiki/Гомоиконичность +# В приведённом списке есть три элемента: +set values { + + one\ two + + {three four} + + five\{six + +} + + +# Поскольку как и все значения, список является строкой, строковые +# операции могут выполняться и над списком, с риском повреждения: +set values {one two three four} +set values [string map {two \{} $values] ;# $values больше не \ + правильно отформатированный список + + +# Безопасный способ работать со списками — использовать "list" рутины: +set values [list one \{ three four] +lappend values { } ;# добавить символ пробела как элемент в список + + +# Использование "eval" для вычисления значения скрипта: +eval { + set name Neo + set greeting "Hello, $name" +} + + +# Список всегда можно передать в "eval" как скрипт, содержащий одну команду: +eval {set name Neo} +eval [list set greeting "Hello, $name"] + + +# Следовательно, когда используется "eval", используйте "list" чтобы собрать +# необходимую команду: +set command {set name} +lappend command {Archibald Sorbisol} +eval $command + + +# Частая ошибка: не использовать списковые функции для построения команды: +set command {set name} +append command { Archibald Sorbisol} +try { + eval $command ;# Здесь будет ошибка, превышено количество аргументов \ + к "set" в {set name Archibald Sorbisol} +} on error {result eoptions} { + puts [list {received an error} $result] +} + +# Эта ошибка запросто может произойти с "subst": + +set replacement {Archibald Sorbisol} +set command {set name $replacement} +set command [subst $command] +try { + eval $command ;# Та же ошибка, лишние аргументы к \ + {set name Archibald Sorbisol} +} trap {TCL WRONGARGS} {result options} { + puts [list {received another error} $result] +} + + +# "list" корректно форматирует значение для подстановки: +set replacement [list {Archibald Sorbisol}] +set command {set name $replacement} +set command [subst $command] +eval $command + + +# "list" обычно используется для форматирования значений для подстановки в +# скрипты, вот несколько примеров: + + +# "apply" вычисляет список из двух элементов как рутину: +set cmd {{greeting name} { + return "$greeting, $name!" +}} +apply $cmd Whaddup Neo + +# Третий элемент может быть использован для указания пространства имён рутины: +set cmd [list {greeting name} { + return "$greeting, $name!" +} [namespace current]] +apply $cmd Whaddup Neo + + +# "uplevel" вычисляет скрипт на уровень выше в списке вызовов: +proc greet {} { + uplevel {puts "$greeting, $name"} +} + +proc set_double {varname value} { + if {[string is double $value]} { + uplevel [list variable $varname $value] + } else { + error [list {not a double} $value] + } +} + + +# "upvar" связывает переменную на текущем уровне вызовов с переменной на +# более высоком уровне: +proc set_double {varname value} { + if {[string is double $value]} { + upvar 1 $varname var + set var $value + } else { + error [list {not a double} $value] + } +} + + +# Избавляемся от встроенной рутины "while" и используем "proc" чтобы написать +# свою версию: +rename ::while {} +# обработка оставлена как упражнение: +proc while {condition script} { + if {[uplevel 1 [list expr $condition]]} { + uplevel 1 $script + tailcall [namespace which while] $condition $script + } +} + + +# "coroutine" создаёт новый стек вызовов, новую рутину для входа в этот стек +# и вызывает эту рутину. "yield" приостанавливает вычисления в этом стеке и +# возвращает управление вызывавшему стеку: +proc countdown count { + # отправить что-нибудь обратно создателю корутины, фактически + # останавливая стек вызовов на время. + yield [info coroutine] + + while {$count > 1} { + yield [incr count -1] + } + return 0 +} +coroutine countdown1 countdown 3 +coroutine countdown2 countdown 5 +puts [countdown1] ;# -> 2 +puts [countdown2] ;# -> 4 +puts [countdown1] ;# -> 1 +puts [countdown1] ;# -> 0 +catch { + puts [coundown1] ;# -> invalid command name "countdown1" +} cres copts +puts $cres +puts [countdown2] ;# -> 3 + + +# Стеки корутин могут передавать контроль друг другу: + +proc pass {whom args} { + return [yieldto $whom {*}$args] +} + +coroutine a apply {{} { + yield + set result [pass b {please pass the salt}] + puts [list got the $result] + set result [pass b {please pass the pepper}] + puts [list got the $result] +}} + +coroutine b apply {{} { + set request [yield] + while 1 { + set response [pass c $request] + puts [list [info coroutine] is now yielding] + set request [pass a $response] + } +}} + +coroutine c apply {{} { + set request [yield] + while 1 { + if {[string match *salt* $request]} { + set request [pass b salt] + } else { + set request [pass b huh?] + } + } +}} + + + +``` + +## Ссылки + +[Официальная документация Tcl](https://www.tcl-lang.org) + +[Tcl Wiki](https://wiki.tcl-lang.org) + +[Tcl на Reddit](http://www.reddit.com/r/Tcl) diff --git a/ru-ru/tmux-ru.html.markdown b/ru-ru/tmux-ru.html.markdown index aa7545cc..643c48b0 100644 --- a/ru-ru/tmux-ru.html.markdown +++ b/ru-ru/tmux-ru.html.markdown @@ -249,4 +249,4 @@ set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | [Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux) -[Отображение CPU/MEM % в статусбаре](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) +[Отображение CPU/MEM % в статус баре](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) diff --git a/ru-ru/typescript-ru.html.markdown b/ru-ru/typescript-ru.html.markdown index 09bbb2d1..ad931599 100644 --- a/ru-ru/typescript-ru.html.markdown +++ b/ru-ru/typescript-ru.html.markdown @@ -9,8 +9,8 @@ translators: filename: learntypescript-ru.ts --- -TypeScript — это язык программирования, целью которого является лёгкая разработка широкомасштабируемых JavaScript-приложений. -TypeScript добавляет в Javascript общие концепции, такие, как классы, модули, интерфейсы, обобщённое программирование и (опционально) статическую типизацию. +TypeScript — это язык программирования, целью которого является лёгкая разработка широко масштабируемых JavaScript-приложений. +TypeScript добавляет в Javascript общие концепции, такие как классы, модули, интерфейсы, обобщённое программирование и (опционально) статическую типизацию. Это надмножество языка JavaScript: весь JavaScript-код является валидным TypeScript-кодом, следовательно, может быть добавлен бесшовно в любой проект. Компилятор TypeScript генерирует JavaScript-код. diff --git a/ru-ru/vim-ru.html.markdown b/ru-ru/vim-ru.html.markdown index f43f99eb..60b381e7 100644 --- a/ru-ru/vim-ru.html.markdown +++ b/ru-ru/vim-ru.html.markdown @@ -10,7 +10,7 @@ lang: ru-ru --- [Vim](http://www.vim.org) -(Vi IMproved) это клон полулярного текстового редактора для Unix. Он разработан +(Vi IMproved) это клон популярного текстового редактора для Unix. Он разработан с целью повышения скорости и продуктивности и повсеместно используется в большинство Юникс-подобных систем. В нем имеется множество клавиатурных сочетаний для быстрой навигации к определенным точкам в файле и быстрого @@ -167,8 +167,8 @@ Vim можно рассматривать как набор команд в фо ## Макросы Макросы это просто записываемые действия. -Во время записи макросы запоминают **все** действия и команды до тех пор пока -запись не будет остановлена.При вызове макрос применяет ту же самую последовательность +Во время записи макросы запоминают **все** действия и команды до тех пор, пока +запись не будет остановлена. При вызове макрос применяет ту же самую последовательность действий и команд на выделенном тексте. ``` diff --git a/ru-ru/xml-ru.html.markdown b/ru-ru/xml-ru.html.markdown index bf3f22b0..34e17b9b 100644 --- a/ru-ru/xml-ru.html.markdown +++ b/ru-ru/xml-ru.html.markdown @@ -15,7 +15,7 @@ XML - это язык разметки, предназначенный для х * XML-Синтаксис ```xml -<!-- Комментарии в XML выглядят вот так --> +<!-- Это комментарий. --> <?xml version="1.0" encoding="UTF-8"?> <bookstore> diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown index ddaed2b6..693848fc 100644 --- a/ru-ru/yaml-ru.html.markdown +++ b/ru-ru/yaml-ru.html.markdown @@ -12,7 +12,7 @@ lang: ru-ru YAML как язык сериализации данных предназначен прежде всего для использования людьми. Это строгое надмножество JSON с добавлением синтаксически значимых переносов строк и -отступов как в Python. Тем не менее, в отличие от Python, YAML запрещает +отступов как в Python. Тем не менее в отличие от Python, YAML запрещает использование табов для отступов. ```yaml @@ -53,7 +53,7 @@ literal_block: | Любые строки с большим отступом сохраняют остатки своего отступа - эта строка будет содержать дополнительно 4 пробела. folded_style: > - Весь блок этого тектса будет значением 'folded_style', но в данном случае + Весь блок этого текста будет значением 'folded_style', но в данном случае все символы новой строки будут заменены пробелами. Пустые строки будут преобразованы в перенос строки. @@ -76,7 +76,7 @@ a_nested_map: 0.25: a float key # Ключи также могут быть сложными, например многострочными. -# Мы используем ? с последующим пробелом чтобы обозначить начало сложного ключа. +# Мы используем ? с последующим пробелом, чтобы обозначить начало сложного ключа. ? | Этот ключ который содержит несколько строк @@ -124,7 +124,7 @@ base: &base name: Каждый будет иметь одинаковое имя # Регулярное выражение << называется ключом объединения независимо от типа языка. -# Он используется чтобы показать что все ключи одного или более словарей должны быть +# Он используется, чтобы показать что все ключи одного или более словарей должны быть # добавлены в текущий словарь. foo: &foo @@ -185,5 +185,5 @@ set2: ### Больше информации -+ [YAML оффициальный вебсайт](http://yaml.org/) ++ [YAML официальный вебсайт](http://yaml.org/) + [YAML онлайн валидатор](http://www.yamllint.com/) diff --git a/ru-ru/zfs-ru.html.markdown b/ru-ru/zfs-ru.html.markdown new file mode 100644 index 00000000..46a3fbb5 --- /dev/null +++ b/ru-ru/zfs-ru.html.markdown @@ -0,0 +1,406 @@ +--- +category: tool +tool: zfs +contributors: + - ["sarlalian", "http://github.com/sarlalian"] + - ["A1EF", "https://github.com/A1EF"] +filename: LearnZfs-ru.txt +translators: + - ["A1EF", "https://github.com/A1EF"] +lang: ru-ru +--- + + +[ZFS](http://open-zfs.org/wiki/Main_Page) +представляет собой переосмысление системы хранения данных, комбинирующее в едином инструменте +традиционные файловые системы и системы управления томами. ZFS обладает некоторой специфичной +терминологией, которая отличает её от более традиционных систем хранения данных, однако имеет +отличный набор возможностей, акцентированных на удобстве использования системными администраторами. + + +## Концепции ZFS + +### Виртуальные устройства + +Виртуальное устройство (VDEV) подобно устройству RAID, представляемого RAID-контроллером. +Есть несколько типов виртуальных устройств (VDEV), которые предлагают различные преимущества, +включая отказоустойчивость и скорость доступа. В основном виртуальные устройства (VDEV) +предоставляют лучшую отказоустойчивость и безопасность, нежели RAID-контроллеры. Не рекомендуется +использовать установку RAID с ZFS, поскольку ZFS рассчитывает непосредственно управлять дисками. + +Типы виртуальных устройств (VDEV) + +* mirror (поддерживается n-кратное зеркалирование) +* raidz + * raidz1 (1-диск четности, аналог RAID 5) + * raidz2 (2-диска четности, аналог RAID 6) + * raidz3 (3-диска четности, нет имеет аналогичного RAID-массива) +* disk +* file (не рекомендовано для промышленного применения из-за добавления нежелательного промежуточного слоя иной файловой системы) + +Ваши данные распределяются среди всех виртуальных устройств (VDEV), представленных в пуле хранения, +так что увеличив число виртуальных устройств (VDEV), вы увеличите количество IOPS. + +### Пулы хранения + +ZFS использует пулы хранения как абстракцию над нижним уровнем провайдера хранения (VDEV), позволяя вам отделить видимые пользователю +файловые системы от физического их размещения. + +### ZFS датасеты + +ZFS датасеты подобны традиционным файловым системам, но имеют гораздо больше возможностей, обеспечивающих обилие преимуществ ZFS. +Датасеты поддерживают [Copy on Write](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%B8_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D0%B8), снапшоты, квоты, сжатие и дедубликацию. + + +### Ограничения + +Один каталог может содержать до 2^48 файлов, каждый до 16 эксабайт. Один пул хранения может содержать до 256 зеттабайт (2^78) данных +и может быть распределён по 2^64 устройствам. А один хост может иметь 2^64 пула хранения. Лимиты огромны. + + +## Команды + +### Пулы хранения + +Действия: + +* Просмотр +* Статус +* Удаление +* Получение/установка свойств + +Просмотр пулов + +```bash +# Создание пула типа raidz +$ zpool create zroot raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2 + +# Просмотр пулов +$ zpool list +NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT +zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE - + +# Просмотр детализованной информации о конкретном пуле +$ zpool list -v zroot +NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT +zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE - + gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 141G 106G 35.2G - 43% 75% +``` + +Статус пулов + +```bash +# Получение информации о статусе пулов +$ zpool status + pool: zroot + state: ONLINE + scan: scrub repaired 0 in 2h51m with 0 errors on Thu Oct 1 07:08:31 2015 +config: + + NAME STATE READ WRITE CKSUM + zroot ONLINE 0 0 0 + gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0 + +errors: No known data errors + +# Скрабинг пула для исправления любых ошибок +$ zpool scrub zroot +$ zpool status -v zroot + pool: zroot + state: ONLINE + scan: scrub in progress since Thu Oct 15 16:59:14 2015 + 39.1M scanned out of 106G at 1.45M/s, 20h47m to go + 0 repaired, 0.04% done +config: + + NAME STATE READ WRITE CKSUM + zroot ONLINE 0 0 0 + gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0 + +errors: No known data errors +``` + +Свойства пулов + +```bash + +# Получение свойств пула, свойства могут быть заданы пользователем или системой. +$ zpool get all zroot +NAME PROPERTY VALUE SOURCE +zroot size 141G - +zroot capacity 75% - +zroot altroot - default +zroot health ONLINE - +... + +# Установка значения свойства пула +$ zpool set comment="Storage of mah stuff" zroot +$ zpool get comment +NAME PROPERTY VALUE SOURCE +tank comment - default +zroot comment Storage of mah stuff local +``` + +Удаление пула + +```bash +$ zpool destroy test +``` + + +### Датасеты + +Действия: + +* Создание +* Просмотр +* Переименование +* Удаление +* Получение/установка свойств + +Создание датасетов + +```bash +# Создание датасета +$ zfs create zroot/root/data +$ mount | grep data +zroot/root/data on /data (zfs, local, nfsv4acls) + +# Создание дочернего датасета +$ zfs create zroot/root/data/stuff +$ mount | grep data +zroot/root/data on /data (zfs, local, nfsv4acls) +zroot/root/data/stuff on /data/stuff (zfs, local, nfsv4acls) + + +# Создание тома +$ zfs create -V zroot/win_vm +$ zfs list zroot/win_vm +NAME USED AVAIL REFER MOUNTPOINT +zroot/win_vm 4.13G 17.9G 64K - +``` + +Просмотр датасетов + +```bash +# Просмотр всех датасетов +$ zfs list +NAME USED AVAIL REFER MOUNTPOINT +zroot 106G 30.8G 144K none +zroot/ROOT 18.5G 30.8G 144K none +zroot/ROOT/10.1 8K 30.8G 9.63G / +zroot/ROOT/default 18.5G 30.8G 11.2G / +zroot/backup 5.23G 30.8G 144K none +zroot/home 288K 30.8G 144K none +... + +# Просмотр конкретного датасета +$ zfs list zroot/home +NAME USED AVAIL REFER MOUNTPOINT +zroot/home 288K 30.8G 144K none + +# Просмотр снапшотов +$ zfs list -t snapshot +zroot@daily-2015-10-15 0 - 144K - +zroot/ROOT@daily-2015-10-15 0 - 144K - +zroot/ROOT/default@daily-2015-10-15 0 - 24.2G - +zroot/tmp@daily-2015-10-15 124K - 708M - +zroot/usr@daily-2015-10-15 0 - 144K - +zroot/home@daily-2015-10-15 0 - 11.9G - +zroot/var@daily-2015-10-15 704K - 1.42G - +zroot/var/log@daily-2015-10-15 192K - 828K - +zroot/var/tmp@daily-2015-10-15 0 - 152K - +``` + +Переименование датасетов + +```bash +$ zfs rename zroot/root/home zroot/root/old_home +$ zfs rename zroot/root/new_home zroot/root/home +``` + +Удаление датасета + +```bash +# Датасеты не могут быть удалены, если у них имеются какие-то снапшоты +$ zfs destroy zroot/root/home +``` + +Получение / установка свойств датасета + +```bash +# Получение всех свойств +$ zfs get all zroot/usr/home +NAME PROPERTY VALUE SOURCE +zroot/home type filesystem - +zroot/home creation Mon Oct 20 14:44 2014 - +zroot/home used 11.9G - +zroot/home available 94.1G - +zroot/home referenced 11.9G - +zroot/home mounted yes - +... + +# Получения свойства для датасета +$ zfs get compression zroot/usr/home +NAME PROPERTY VALUE SOURCE +zroot/home compression off default + +# Установка значения свойства на датасете +$ zfs set compression=lz4 zroot/lamb + +# Получение значений выбранных свойств всех датасетов +$ zfs list -o name,quota,reservation +NAME QUOTA RESERV +zroot none none +zroot/ROOT none none +zroot/ROOT/default none none +zroot/tmp none none +zroot/usr none none +zroot/home none none +zroot/var none none +... +``` + + +### Снапшоты + +ZFS снапшоты -- одна из очень важных особенностей zfs + +* Место, которое они занимают, равно разнице данных между файловой системой и её снапшотом +* Время создания занимает считанные секунды +* Восстановление настолько быстро, насколько позволяет вам запись данных +* Они очень просты в автоматизации + +Действия: + +* Создание +* Удаление +* Переименование +* Получение доступа к снапшотам +* Отправка / Получение +* Клонирование + + +Создание снапшотов + +```bash +# Создание снапшота единственного датасета +zfs snapshot zroot/home/sarlalian@now + +# Создание снапшота для родительского и дочерних датасетов +$ zfs snapshot -r zroot/home@now +$ zfs list -t snapshot +NAME USED AVAIL REFER MOUNTPOINT +zroot/home@now 0 - 26K - +zroot/home/sarlalian@now 0 - 259M - +zroot/home/alice@now 0 - 156M - +zroot/home/bob@now 0 - 156M - +... +``` + +Удаление снапшотов + +```bash +# Как удалить снапшот +$ zfs destroy zroot/home/sarlalian@now + +# Удаление снапшота в родительском и дочерних датасетах +$ zfs destroy -r zroot/home/sarlalian@now + +``` + +Переименование снапшотов + +```bash +# Переименование снапшота +$ zfs rename zroot/home/sarlalian@now zroot/home/sarlalian@today +$ zfs rename zroot/home/sarlalian@now today + +$ zfs rename -r zroot/home@now @yesterday +``` + +Получение доступа к спапшотам + +```bash +# CD в каталог снапшота +$ cd /home/.zfs/snapshot/ +``` + +Отправка и получение + +```bash +# Сохранение снапшота в файл +$ zfs send zroot/home/sarlalian@now | gzip > backup_file.gz + +# Отправка снапшота в другой датасет +$ zfs send zroot/home/sarlalian@now | zfs recv backups/home/sarlalian + +# Отправка снапшота на удаленный хост +$ zfs send zroot/home/sarlalian@now | ssh root@backup_server 'zfs recv zroot/home/sarlalian' + +# Отправка полного датасета со снапшотами на новый хост +$ zfs send -v -R zroot/home@now | ssh root@backup_server 'zfs recv zroot/home' +``` + +Клонирование снапшотов + +```bash +# Клонирование снапшота +$ zfs clone zroot/home/sarlalian@now zroot/home/sarlalian_new + +# Повышение клона, чтобы он больше не зависел от снапшота +$ zfs promote zroot/home/sarlalian_new +``` + +### Собираем всё вместе + +Нижеследующий скрипт использует FreeBSD, jails и ZFS для автоматизации +подготовки чистой копии стейджинговой базы mysql с живой реплики слейв-ноды. + +```bash +#!/bin/sh + +echo "==== Остановка стейджингового сервера баз данных ====" +jail -r staging + +echo "==== Очистка существующих стейджингового сервера и снапшота ====" +zfs destroy -r zroot/jails/staging +zfs destroy zroot/jails/slave@staging + +echo "==== Фиксация базы на слейве ====" +echo "FLUSH TABLES WITH READ LOCK;" | /usr/local/bin/mysql -u root -pmyrootpassword -h slave + +echo "==== Сохранение снапшота файлов базы слейва как zroot/jails/slave@staging ====" +zfs snapshot zroot/jails/slave@staging + +echo "==== Запуск слейв-ноды сервера баз данных ====" +jail -c slave + +echo "==== Клонирование снапшота слейва на стейджинговый сервер ====" +zfs clone zroot/jails/slave@staging zroot/jails/staging + +echo "==== Установка конфига стейджингово mysql ====" +mv /jails/staging/usr/local/etc/my.cnf /jails/staging/usr/local/etc/my.cnf.slave +cp /jails/staging/usr/local/etc/my.cnf.staging /jails/staging/usr/local/etc/my.cnf + +echo "==== Настройка стейджингового файла rc.conf ====" +mv /jails/staging/etc/rc.conf.local /jails/staging/etc/rc.conf.slave +mv /jails/staging/etc/rc.conf.staging /jails/staging/etc/rc.conf.local + +echo "==== Запуск стейджингово сервера баз данных ====" +jail -c staging + +echo "==== Отключение синхронизации стейджинговой базы с мастером ====" +echo "STOP SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging +echo "RESET SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging +``` + + +### Почитать дополнительно + +* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs) +* [FreeBSD Handbook on ZFS](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/zfs.html) +* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs) +* [Oracle's Tuning Guide](http://www.oracle.com/technetwork/articles/servers-storage-admin/sto-recommended-zfs-settings-1951715.html) +* [OpenZFS Tuning Guide](http://open-zfs.org/wiki/Performance_tuning) +* [FreeBSD ZFS Tuning Guide](https://wiki.freebsd.org/ZFSTuningGuide) diff --git a/rust.html.markdown b/rust.html.markdown index c677ed96..526d20d5 100644 --- a/rust.html.markdown +++ b/rust.html.markdown @@ -30,6 +30,9 @@ Rust not only fast, but also easy and efficient to code in. // This is a comment. Line comments look like this... // and extend multiple lines like this. +/* Block comments + /* can be nested. */ */ + /// Documentation comments look like this and support markdown notation. /// # Examples /// diff --git a/sed.html.markdown b/sed.html.markdown new file mode 100644 index 00000000..3e6d8fc8 --- /dev/null +++ b/sed.html.markdown @@ -0,0 +1,285 @@ +--- +category: tool +tool: sed +filename: learnsed.sed +contributors: + - ["Diomidis Spinellis", "https://www.spinellis.gr"] + +--- + +__Sed__ is a standard tool on every POSIX-compliant UNIX system. +It's like an editor, such as Vim, Visual Studio Code, Atom, or Sublime. +However, rather than typing the commands interactively, you +provide them on the command line or in a file. + +_Sed_'s advantages over an interactive editor is that it can be easily +used to automate text processing tasks, and that it can process +efficiently huge (terabyte-sized) files. +It can perform more complex tasks than _grep_ and for many text +processing tasks its commands are much shorter than what you would +write in _awk_, _Perl_, or _Python_. + +_Sed_ works by reading a line of text (by default from its standard +input, unless some files are specified as arguments), processing +it with the specified commands, and then outputting the result +on its standard output. +You can suppress the default output by specifying the `-n` command-line +argument. + +```perl +#!/usr/bin/sed -f +# Files that begin with the above line and are given execute permission +# can be run as regular scripts. + +# Comments are like this. + +# Commands consist of a single letter and many can be preceded +# by a specification of the lines to which they apply. + +# Delete the input's third line. +3d + +# The same command specified the command line as an argument to sed: +# sed 3d + +# For many commands the specification can consist of two addresses, +# which select an inclusive range. +# Addresses can be specified numerically ($ is the last line) or through +# regular expressions delimited by /. + +# Delete lines 1-10 +1,10d + +# Lines can also be specified as regular expressions, delimited by /. + +# Delete empty lines. +/^$/d + +# Delete blocks starting with SPOILER-BEGIN and ending with SPOILER-END. +/SPOILER-BEGIN/,/SPOILER-END/d + +# A command without an address is applied to all lines. + +# List lines in in a visually unambiguous form (e.g. tab appears as \t). +l + +# A command prefixed by ! will apply to non-matching lines. +# Keep only lines starting with a #. +/^#/!d + +# Below are examples of the most often-used commands. + +# Substitute the first occurence in a line of John with Mary. +s/John/Mary/ + +# Remove all underscore characters (global substitution). +s/_//g + +# Remove all HTML tags. +s/<[^>]*>//g + +# In the replacement string & is the regular expression matched. + +# Put each line inside double quotes. +s/.*/"&"/ + +# In the matched regular expression \(pattern\) is used to store +# a pattern into a buffer. +# In the replacement string \1 refers to the first pattern, \2 to the second +# and so on. \u converts the following character to uppercase \l to lowercase. + +# Convert snake_case_identifiers into camelCaseIdentifiers. +s/_\(.\)/\u\1/g + + +# The p (print) command is typically used together with the -n +# command-line option, which disables the print by default functionality. +# Output all lines between ``` and ```. +/```/,/```/p + + +# The y command maps characters from one set to another. +# Swap decimal and thousand separators (1,234,343.55 becomes 1.234.343,55). +y/.,/,./ + +# Quit after printing the line starting with END. +/^END/q + +# You can stop reading here, and still get 80% of sed's benefits. +# Below are examples of how you can specify multiple sed commands. + +# You can apply multiple commands by separating them with a newline or +# a semicolon. + +# Delete the first and the last line. +1d +$d + +# Delete the first and the last line. +1d;$d + + +# You can group commands in { } blocks. + +# Convert first line to uppercase and print it. +1 { + s/./\u&/g + p +} + +# Convert first line to uppercase and print it (less readable one-liner). +1{s/./\u&/g;p;} + + +# You can also stop reading here, if you're not interested in creating +# sed script files. + +# Below are more advanced commands. You typically put these in a file +# rather than specify them on a command line. If you have to use +# many of these commands in a script, consider using a general purpose +# scripting language, such as Python or Perl. + +# Append a line containing "profile();" after each line ending with ";". +/;$/a\ +profile(); + +# Insert a line containing "profile();" before each line ending with ";". +/;$/i\ +profile(); + +# Change each line text inside REDACTED blocks into [REDACTED]. +/REDACTED-BEGIN/,/REDACTED-END/c\ +[REDACTED] + +# Replace the tag "<ourstyle>" by reading and outputting the file style.css. +/<ourstyle>/ { + r style.css + d +} + +# Change each line inside REDACTED blocks into [REDACTED]. +# Also write (append) a copy of the redacted text in the file redacted.txt. +/REDACTED-BEGIN/,/REDACTED-END/ { + w redacted.txt + c\ + [REDACTED] +} + +# All operations described so far operate on a buffer called "pattern space". +# In addition, sed offers another buffer called "hold space". +# The following commands operate on the two, and can be used to keep +# state or combine multiple lines. + +# Replace the contents of the pattern space with the contents of +# the hold space. +g + +# Append a newline character followed by the contents of the hold +# space to the pattern space. +G + +# Replace the contents of the hold space with the contents of the +# pattern space. +h + +# Append a newline character followed by the contents of the +# pattern space to the hold space. +H + +# Delete the initial segment of the pattern space through the first +# newline character and start the next cycle. +D + +# Replace the contents of the pattern space with the contents of +# the hold space. +g + +# Append a newline character followed by the contents of the hold +# space to the pattern space. +G + +# Replace the contents of the hold space with the contents of the +# pattern space. +h + +# Append a newline character followed by the contents of the +# pattern space to the hold space. +H + +# Write the pattern space to the standard output if the default +# output has not been suppressed, and replace the pattern space +# with the next line of input. +n + +# Append the next line of input to the pattern space, using an +# embedded newline character to separate the appended material from +# the original contents. Note that the current line number +# changes. +N + +# Write the pattern space, up to the first newline character to the +# standard output. +P + +# Swap the contents of the pattern and hold spaces. +x + +# Here is a complete example of some of the buffer commands. +# Move the file's first line to its end. +1 { + h + d +} + +$ { + p + x +} + + +# Three sed commands influence a script's control flow + +# Name this script position "my_label", to which the "b" and +# "t" commands may branch. +:my_label + +# Continue executing commands from the position of my_label. +b my_label + +# Branch to the end of the script. +b + +# Branch to my_label if any substitutions have been made since the most +# recent reading of an input line or execution of a "t" (test) function. +t my_label + +# Here is a complete example of branching +# Join lines that end with a backspace into a single space-separated one + +# Name this position "loop" +: loop +# On lines ending with a backslash +/\\$/ { + # Read the next line and append it to the pattern space + N + # Substitute backslash newline with a space + s/\\\n/ / + # Branch to the top for testing this line's ending + b loop +} +``` + +Further Reading: + +* [The Open Group: sed - stream editor](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html) + The POSIX standard regarding sed. + Follow this for maximum portability. +* [FreeBSD sed -- stream editor](https://www.freebsd.org/cgi/man.cgi?query=sed&sektion=&n=1) + The BSD manual page. + This version of sed runs on BSD systems and macOS. +* [Project GNU: sed, a stream editor](https://www.gnu.org/software/sed/manual/sed.html) + The GNU manual page. GNU sed is found on most Linux systems. +* [Lee E. McMahon: SED -- A Non-interactive Text Editor](https://wolfram.schneider.org/bsd/7thEdManVol2/sed/sed.pdf) + The original sed documentation +* [A collection of sed resources](http://sed.sourceforge.net/) +* [The sed FAQ](http://sed.sourceforge.net/sedfaq.html) diff --git a/set-theory.html.markdown b/set-theory.html.markdown index f89345c0..144b4bbf 100644 --- a/set-theory.html.markdown +++ b/set-theory.html.markdown @@ -2,7 +2,9 @@ category: Algorithms & Data Structures name: Set theory contributors: + - ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"] --- + Set theory is a branch of mathematics that studies sets, their operations, and their properties. * A set is a collection of disjoint items. @@ -59,7 +61,7 @@ Long lists may be shortened with ellipses as long as the context is clear. For e Set builder notation is a more descriptive way of constructing a set. It relies on a _subject_ and a _predicate_ such that `S = { subject : predicate }`. For example, ``` -A = { x : x is a vowel } = { a, e, i, o, u, y} +A = { x : x is a vowel } = { a, e, i, o, u } B = { x : x ∈ N, x < 10 } = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } C = { x : x = 2k, k ∈ N } = { 0, 2, 4, 6, 8, ... } ``` diff --git a/sk-sk/elixir-sk.html.markdown b/sk-sk/elixir-sk.html.markdown index 2401f92e..c9522b49 100644 --- a/sk-sk/elixir-sk.html.markdown +++ b/sk-sk/elixir-sk.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -14,7 +14,7 @@ Elixir je moderný funkcionálny jazyk vytvorený nad Erlang VM (virtuálnym strojom). Je plne kompatibilný s Erlangom, ale ponúka viac štandardnú syntax a množstvo funkcií. -```Elixir +```elixir # Jednoriadkový komentár začína symbolom # @@ -24,7 +24,7 @@ a množstvo funkcií. # Pre spustenie Elixir shellu zadajte príkaz `iex` # Kompiláciu zdrojových kódov vykonáte príkazom `elixirc` -# Obe príkazy by sa už mali nachádzať v path pokiaľ ste nainštalovali elixir +# Obe príkazy by sa už mali nachádzať v path pokiaľ ste nainštalovali Elixir # správne. ## --------------------------- @@ -86,7 +86,7 @@ reťazec. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` v elixire vráti ASCII číselnú reprezentáciu pre znak `a` +# `?a` v Elixir vráti ASCII číselnú reprezentáciu pre znak `a` ?a #=> 97 # Pre spájanie zoznamov sa používa `++`, pre binárne typy `<>` @@ -119,7 +119,7 @@ pohlavia.gillian #=> "žena" 5 * 2 #=> 10 10 / 2 #=> 5.0 -# V elixire operátor `/` vždy vráti float (reálne číslo). +# V Elixir operátor `/` vždy vráti float (reálne číslo). # Pre celočíselné delenie sa používa `div` div(10, 2) #=> 5 @@ -182,7 +182,7 @@ else end # Pamätáte sa na pattern matching? Mnoho štruktúr pre riadenie toku v -# elixire sa spoliehajú práve na pattern matching. +# Elixir sa spoliehajú práve na pattern matching. # `case` dovolí nám porovnať hodnotu oproti mnohým vzorom: case {:one, :two} do @@ -314,7 +314,7 @@ Geometria.oblast({:kruh, 3}) #=> 28.25999999999999801048 # Geometria.oblast({:kruh, "nie_je_cislo"}) #=> ** (FunctionClauseError) no function clause matching in Geometria.oblast/1 -# Vďaka nemeniteľnosti (immutability) je rekurzia významnou časťou elixiru +# Vďaka nemeniteľnosti (immutability) je rekurzia významnou časťou Elixir defmodule Rekurzia do def sumuj_zoznam([hlavicka | schvost], acc) do sumuj_zoznam(chvost, acc + hlavicka) @@ -389,7 +389,7 @@ end ## --------------------------- # Elixir sa pri konkurencii spolieha na Actor model. Všetko čo je -# potrebné na písanie konkuretných programov v elixire sú tri primitívy: +# potrebné na písanie konkuretných programov v Elixir sú tri primitívy: # spawning procesy, posielanie a prijímanie správ. # Na spustnenie nového procesu použijeme `spawn` funkciu, ktorá má ako diff --git a/sk-sk/git-sk.html.markdown b/sk-sk/git-sk.html.markdown index ddcd9658..1187abc5 100644 --- a/sk-sk/git-sk.html.markdown +++ b/sk-sk/git-sk.html.markdown @@ -139,6 +139,7 @@ $ git init --help ### ignoruj súbory Zámerne prestaneš sledovať súbor(y) a zložky. Typicky sa používa pre súkromné a dočasné súbory, ktoré by boli inak zdieľané v repozitári. + ```bash $ echo "temp/" >> .gitignore $ echo "private_key" >> .gitignore @@ -172,6 +173,7 @@ $ git add /cesta/k/súboru/HelloWorld.c # Môžeš použiť regulárne výrazy! $ git add ./*.java ``` + Tento príkaz len pridáva súbory do staging indexu, necommituje ich do repozitára. ### branch @@ -476,6 +478,7 @@ $ git reset 31f2bb1 # a zosúladí ju s pracovným adresárom (vymaže nekomitnuté zmeny). $ git reset --hard 31f2bb1 ``` + ### revert Vezme naspäť ("od-urobí") commit. Nezamieňaj s resetom, ktorý obnoví stav diff --git a/sk-sk/latex-sk.html.markdown.tex b/sk-sk/latex-sk.html.markdown index 5e2f9c7f..5e2f9c7f 100644 --- a/sk-sk/latex-sk.html.markdown.tex +++ b/sk-sk/latex-sk.html.markdown diff --git a/sk-sk/learn-latex-sk.tex b/sk-sk/learn-latex-sk.tex deleted file mode 100644 index 5cc7b11f..00000000 --- a/sk-sk/learn-latex-sk.tex +++ /dev/null @@ -1,209 +0,0 @@ -% Všetky komentáre začínajú s % -% Viac-riadkové komentáre sa nedajú urobiť - -% LaTeX NIE JE WYSIWY ("What You See Is What You Get") software ako MS Word, alebo OpenOffice Writer - -% Každý LaTeX príkaz začína s opačným lomítkom (\) - -% LaTeX dokumenty začínajú s definíciou typu kompilovaného dokumentu -% Ostatné typy sú napríklad kniha (book), správa (report), prezentácia (presentation), atď. -% Možnosti dokumentu sa píšu do [] zátvoriek. V tomto prípade tam upresňujeme veľkosť (12pt) fontu. -\documentclass[12pt]{article} - -% Ďalej definujeme balíčky, ktoré dokuemnt používa. -% Ak chceš zahrnúť grafiku, farebný text, či zdrojový kód iného jazyka, musíš rozšíriť možnosti LaTeXu dodatočnými balíčkami. -% Zahŕňam float a caption. Na podporu slovenčiny treba zahrnúť aj utf8 balíček. -\usepackage{caption} -\usepackage{float} -\usepackage[utf8]{inputenc} -% Tu môžme definovať ostatné vlastnosti dokumentu! -% Autori tohto dokumentu, "\\*" znamená "choď na nový riadok" -\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu, \\*Preklad: Terka Slanináková} -% Vygeneruje dnešný dátum -\date{\today} -\title{Nauč sa LaTeX za Y Minút!} -% Teraz môžme začať pracovať na samotnom dokumente. -% Všetko do tohto riadku sa nazýva "Preambula" ("The Preamble") -\begin{document} -% ak zadáme položky author, date a title, LaTeX vytvorí titulnú stranu. -\maketitle - -% Väčšina odborných článkov má abstrakt, na jeho vytvorenie môžeš použiť preddefinované príkazy. -% Ten by sa mal zobraziť v logickom poradí, teda po hlavičke, -% no pred hlavnými sekciami tela.. -% Tento príkaz je tiež dostupný v triedach article a report. -% Tzv. makro "abstract" je fixnou súčasťou LaTeXu, ak chceme použiť abstract -% a napísať ho po slovensky, musíme ho redefinovať nasledujúcim príkazom -\renewcommand\abstractname{Abstrakt} - -\begin{abstract} -LaTeX dokumentácia v LaTeXe! Aké netradičné riešenie cudzieho nápadu! -\end{abstract} - -% Príkazy pre sekciu sú intuitívne -% Všetky nadpisy sekcií sú pridané automaticky do obsahu. -\section{Úvod} -Čaute, volám sa Colton a spoločne sa pustíme do skúmania LaTeXu (toho druhého)! - -\section{Ďalšia sekcia} -Toto je text ďalšej sekcie. Myslím, že potrebuje podsekciu. - -\subsection{Toto je podsekcia} % Podsekcie sú tiež intuitívne. -Zdá sa mi, že treba ďalšiu. - -\subsubsection{Pytagoras} -To je ono! -\label{subsec:pytagoras} - -% Použitím '*' môžeme potlačiť zabudované číslovanie LaTeXu. -% Toto funguje aj na iné príkazy. -\section*{Toto je nečíslovaná sekcia} -Všetky číslované byť nemusia! - -\section{Nejaké poznámočky} -Zarovnávať veci tam, kde ich chceš mať, je všeobecne ľahké. Ak -potrebuješ \\ nový \\ riadok \\ pridaj \textbackslash\textbackslash do -zdrojového kódu. \\ - -\section{Zoznamy} -Zoznamy sú jednou z najjednoduchších vecí vôbec! Treba mi zajtra nakúpiť, urobím si zoznam. -\begin{enumerate} % "enumerate" spustí číslovanie prvkov. - % \item povie LaTeXu, ako že treba pripočítať 1 - \item Vlašský šalát. - \item 5 rožkov. - \item 3 Horalky. - % číslovanie môžeme pozmeniť použitím [] - \item[koľko?] Stredne veľkých guličkoviek. - - Ja už nie som položka zoznamu, no stále som časť "enumerate". - -\end{enumerate} % Všetky prostredia končia s "end". - -\section{Matika} - -Jedným z primárnych použití LaTeXu je písanie akademických, či technických prác. Zvyčajne za použitia matematiky a vedy. Podpora špeciálnych symbolov preto nemôže chýbať!\\ - -Matematika má veľa symbolov, omnoho viac, než by klávesnica mohla reprezentovať; -Množinové a relačné symboly, šípky, operátory a Grécke písmená sú len malou ukážkou.\\ - -Množiny a relácie hrajú hlavnú rolu v mnohých matematických článkoch. -Takto napíšeš, že niečo platí pre všetky x patriace do X, $\forall$ x $\in$ X. \\ -% Všimni si, že som pridal $ pred a po symboloch. Je to -% preto, lebo pri písaní sme v textovom móde, -% no matematické symboly existujú len v matematickom. -% Vstúpime doňho z textového práve '$' znamienkami. -% Platí to aj opačne. Premenná môže byť zobrazená v matematickom móde takisto. -% Do matematického módu sa dá dostať aj s \[\] - -\[a^2 + b^2 = c^2 \] - -Moje obľúbené Grécke písmeno je $\xi$. Tiež sa mi pozdávajú $\beta$, $\gamma$ a $\sigma$. -Ešte som neprišiel na Grécke písmeno, ktoré by LaTeX nepoznal! - -Operátory sú dôležitou súčasťou matematických dokumentov: -goniometrické funkcie ($\sin$, $\cos$, $\tan$), -logaritmy and exponenciálne výrazy ($\log$, $\exp$), -limity ($\lim$), atď. -majú pred-definované LaTeXové príkazy. -Napíšme si rovnicu, nech vidíme, ako to funguje: \\ - -$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ - -Zlomky(Čitateľ-menovateľ) sa píšu v týchto formách: - -% 10 / 7 -$^{10}/_{7}$ - -% Relatívne komplexné zlomky sa píšu ako -% \frac{čitateľ}{menovateľ} -$\frac{n!}{k!(n - k)!}$ \\ - -Rovnice tiež môžeme zadať v "rovnicovom prostredí". - -% Takto funguje rovnicové prostredie -\begin{equation} % vstúpi do matematického módu - c^2 = a^2 + b^2. - \label{eq:pythagoras} % na odkazovanie -\end{equation} % všetky \begin príkazy musia mať konečný príkaz. - -Teraz môžeme odkázať na novovytvorenú rovnicu! -Rovn.~\ref{eq:pythagoras} je tiež známa ako Pytagorova Veta, ktorá je tiež predmetom Sekc.~\ref{subsec:pytagoras}. Odkazovať môžme na veľa vecí, napr na: čísla, rovnice, či sekcie. - -Sumácie a Integrály sa píšu príkazmi sum a int: - -% Niektoré prekladače LaTeXu sa môžu sťažovať na prázdne riadky (ak tam sú) -% v rovnicovom prostredí. -\begin{equation} - \sum_{i=0}^{5} f_{i} -\end{equation} -\begin{equation} - \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x -\end{equation} - -\section{Obrázky} - -Vloženie obrázku môže byť zložitejšie. Ja si vždy možnosti vloženia pozerám pre každý obrázok. -\renewcommand\figurename{Obrázok} -\begin{figure}[H] % H značí možnosť zarovnania. - \centering % nacentruje obrázok na stránku - % Vloží obrázok na 80% šírky stránky. - %\includegraphics[width=0.8\linewidth]{right-triangle.png} - % Zakomentované kvôli kompilácií, použi svoju predstavivosť :). - \caption{Pravouhlý trojuholník so stranami $a$, $b$, $c$} - \label{fig:right-triangle} -\end{figure} -% Opäť, fixné makro "table" nahradíme slovenskou tabuľkou. Pokiaľ preferuješ table, nasledujúci riadok nepridávaj -\renewcommand\tablename{Tabuľka} - -\subsection{Tabuľky} -Tabuľky sa vkládajú podobne ako obrázky. - -\begin{table}[H] - \caption{Nadpis tabuľky.} - % zátvorky: {} hovoria ako sa vykreslí každý riadok. - % Toto si nikdy nepamätám a vždy to musím hľadať. Všetko. Každý. Jeden. Raz! - \begin{tabular}{c|cc} - Číslo & Priezvisko & Krstné meno \\ % Stĺpce sú rozdelené $ - \hline % horizontálna čiara - 1 & Ladislav & Meliško \\ - 2 & Eva & Máziková - \end{tabular} -\end{table} - -% \section{Hyperlinks} % Už čoskoro :) - -\section{Prikáž LaTeXu nekompilovať (napr. Zdrojový Kód)} -Povedzme, že chceme do dokumentu vložiť zdrojový kód, budeme musieť LaTeXu povedať, nech sa ho nesnaží skompilovať, ale nech s ním pracuje ako s textom. -Toto sa robí vo verbatim prostredí. - -% Tiež sú na to špeciálne balíčky, (napr. minty, lstlisting, atď.) -% ale verbatim je to najzákladnejšie, čo môžeš použiť. -\begin{verbatim} - print("Hello World!") - a%b; pozri! Vo verbatime môžme použiť % znamienka. - random = 4; #priradené randomným hodom kockou -\end{verbatim} - -\section{Kompilácia} - -Už by bolo načase túto nádheru skompilovať a zhliadnuť jej úžasnú úžasnosť v podobe LaTeX pdfka, čo povieš? -(áno, tento dokument sa musí kompilovať). \\ -Cesta k finálnemu dokumentu pomocou LaTeXu pozostáva z nasledujúcich krokov: - \begin{enumerate} - \item Napíš dokument v čistom texte (v "zdrojáku"). - \item Skompiluj zdroják na získanie pdfka. - Kompilácia by mala vyzerať nasledovne (v Linuxe): \\ - \begin{verbatim} - $pdflatex learn-latex.tex learn-latex.pdf - \end{verbatim} - \end{enumerate} - -Mnoho LaTeX editorov kombinuje Krok 1 a Krok 2 v jednom prostredí. Krok 1 teda uvidíš, krok 2 už nie. -Ten sa deje za oponou. Kompilácia v 2. kroku sa postará o produkciu dokumentu v tebou zadanom formáte. - -\section{Koniec} - -To je zatiaľ všetko! - -% koniec dokumentu -\end{document} diff --git a/sl-si/asciidoc-sl.html.markdown b/sl-si/asciidoc-sl.html.markdown index 52f30fbd..84bb85a1 100644 --- a/sl-si/asciidoc-sl.html.markdown +++ b/sl-si/asciidoc-sl.html.markdown @@ -6,7 +6,7 @@ contributors: translators: - ["Filip Štamcar", "https://github.com/filips123"] lang: sl-si -filename: asciidoc-sl.md +filename: asciidoc-sl.adoc --- AsciiDoc je označevalni jezik, ki je podoben Markdownu in ga je mogoče uporabiti za vse od knjig do spletnih dnevnikov. Jezik, ki ga je leta 2002 ustvaril Stuart Rackham, je preprost, vendar omogoča veliko prilagoditev. diff --git a/smalltalk.html.markdown b/smalltalk.html.markdown index d4016ecf..9c2e870e 100644 --- a/smalltalk.html.markdown +++ b/smalltalk.html.markdown @@ -2,16 +2,15 @@ language: Smalltalk filename: smalltalk.st contributors: - - ["Jigyasa Grover", "https://github.com/jigyasa-grover"] + - ["Jigyasa Grover", "https://jigyasa-grover.github.io"] - ["tim Rowledge", "tim@rowledge.org"] --- +<blockquote>Every effort has been made in the preparation of this material to ensure the accuracy and completeness of the information presented. However, no guarantee is given nor responsibility taken for errors or omissions. In case of any error, questions or suggestions on reach out to me at <a href="https://jigyasa-grover.github.io" target="_blank">jigyasa-grover.github.io</a> or drop me an e-mail at <a href="mailto:grover.jigyasa1@gmail.com" target="_blank">grover[dot]jigyasa1[at]gmail.com</a>.</blockquote> - Smalltalk is a fully object-oriented, dynamically typed, reflective programming language with no 'non-object' types. - Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." - It was designed and created in part for educational use, more so for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Scott Wallace, and others during the 1970s. -`Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at grover.jigyasa1@gmail.com.` - ## The Basics ### Everything is an object @@ -162,7 +161,7 @@ b := (x < 5) xor: (y > 1). "test if one true and other false" b := 5 between: 3 and: 12. "between (inclusive)" b := 123 isKindOf: Number. "test if object is class or subclass of" b := 123 isMemberOf: SmallInteger. "test if object is type of class" -b := 123 respondsTo: sqrt. "test if object responds to message" +b := 123 respondsTo: #sqrt. "test if object responds to message" b := x isNil. "test if object is nil" b := x isZero. "test if number is zero" b := x positive. "test if number is positive" diff --git a/sorbet.html.markdown b/sorbet.html.markdown new file mode 100644 index 00000000..9c2e809b --- /dev/null +++ b/sorbet.html.markdown @@ -0,0 +1,1040 @@ +--- +language: sorbet +filename: learnsorbet.rb +contributors: + - ["Jeremy Kaplan", "https://jdkaplan.dev"] +--- + +Sorbet is a type checker for Ruby. It adds syntax for method signatures that +enable both static and runtime type checking. + +The easiest way to see it in action is in the playground at +[sorbet.run](https://sorbet.run). + +Try copying in one of the sections below! Each top-level `class` or `module` +is independent from the others. + +```ruby +# Every file should have a "typed sigil" that tells Sorbet how strict to be +# during static type checking. +# +# Strictness levels (lax to strict): +# +# ignore: Sorbet won't even read the file. This means its contents are not +# visible during type checking. Avoid this. +# +# false: Sorbet will only report errors related to constant resolution. This is +# the default if no sigil is included. +# +# true: Sorbet will report all static type errors. This is the sweet spot of +# safety for effort. +# +# strict: Sorbet will require that all methods, constants, and instance +# variables have static types. +# +# strong: Sorbet will no longer allow anything to be T.untyped, even +# explicitly. Almost nothing satisfies this. + +# typed: true + +# Include the runtime type-checking library. This lets you write inline sigs +# and have them checked at runtime (instead of running Sorbet as RBI-only). +# These runtime checks happen even for files with `ignore` or `false` sigils. +require 'sorbet-runtime' + +class BasicSigs + # Bring in the type definition helpers. You'll almost always need this. + extend T::Sig + + # Sigs are defined with `sig` and a block. Define the return value type with + # `returns`. + # + # This method returns a value whose class is `String`. These are the most + # common types, and Sorbet calls them "class types". + sig { returns(String) } + def greet + 'Hello, World!' + end + + # Define parameter value types with `params`. + sig { params(n: Integer).returns(String) } + def greet_repeat(n) + (1..n).map { greet }.join("\n") + end + + # Define keyword parameters the same way. + sig { params(n: Integer, sep: String).returns(String) } + def greet_repeat_2(n, sep: "\n") + (1..n).map { greet }.join(sep) + end + + # Notice that positional/keyword and required/optional make no difference + # here. They're all defined the same way in `params`. + + # For lots of parameters, it's nicer to use do..end and a multiline block + # instead of curly braces. + sig do + params( + str: String, + num: Integer, + sym: Symbol, + ).returns(String) + end + def uhh(str:, num:, sym:) + 'What would you even do with these?' + end + + # For a method whose return value is useless, use `void`. + sig { params(name: String).void } + def say_hello(name) + puts "Hello, #{name}!" + end + + # Splats! Also known as "rest parameters", "*args", "**kwargs", and others. + # + # Type the value that a _member_ of `args` or `kwargs` will have, not `args` + # or `kwargs` itself. + sig { params(args: Integer, kwargs: String).void } + def no_op(*args, **kwargs) + if kwargs[:op] == 'minus' + args.each { |i| puts(i - 1) } + else + args.each { |i| puts(i + 1) } + end + end + + # Most initializers should be `void`. + sig { params(name: String).void } + def initialize(name:) + # Instance variables must have annotated types to participate in static + # type checking. + + # The value in `T.let` is checked statically and at runtime. + @upname = T.let(name.upcase, String) + + # Sorbet can infer this one! + @name = name + end + + # Constants also need annotated types. + SORBET = T.let('A delicious frozen treat', String) + + # Class variables too. + @@the_answer = T.let(42, Integer) + + # Sorbet knows about the `attr_*` family. + sig { returns(String) } + attr_reader :upname + + sig { params(write_only: Integer).returns(Integer) } + attr_writer :write_only + + # You say the reader part and Sorbet will say the writer part. + sig { returns(String) } + attr_accessor :name +end + +module Debugging + extend T::Sig + + # Sometimes it's helpful to know what type Sorbet has inferred for an + # expression. Use `T.reveal_type` to make type-checking show a special error + # with that information. + # + # This is most useful if you have Sorbet integrated into your editor so you + # can see the result as soon as you save the file. + + sig { params(obj: Object).returns(String) } + def debug(obj) + T.reveal_type(obj) # Revealed type: Object + repr = obj.inspect + + # Remember that Ruby methods can be called without arguments, so you can + # save a couple characters! + T.reveal_type repr # Revealed type: String + + "DEBUG: " + repr + end +end + +module StandardLibrary + extend T::Sig + # Sorbet provides some helpers for typing the Ruby standard library. + + # Use T::Boolean to catch both `true` and `false`. + # + # For the curious, this is equivalent to + # + # T.type_alias { T.any(TrueClass, FalseClass) } + # + sig { params(str: String).returns(T::Boolean) } + def confirmed?(str) + str == 'yes' + end + + # Remember that the value `nil` is an instance of NilClass. + sig { params(val: NilClass).void } + def only_nil(val:); end + + # To avoid modifying standard library classes, Sorbet provides wrappers to + # support common generics. + # + # Here's the full list: + # * T::Array + # * T::Enumerable + # * T::Enumerator + # * T::Hash + # * T::Range + # * T::Set + sig { params(config: T::Hash[Symbol, String]).returns(T::Array[String]) } + def merge_values(config) + keyset = [:old_key, :new_key] + config.each_pair.flat_map do |key, value| + keyset.include?(key) ? value : 'sensible default' + end + end + + # Sometimes (usually dependency injection), a method will accept a reference + # to a class rather than an instance of the class. Use `T.class_of(Dep)` to + # accept the `Dep` class itself (or something that inherits from it). + class Dep; end + + sig { params(dep: T.class_of(Dep)).returns(Dep) } + def dependency_injection(dep:) + dep.new + end + + # Blocks, procs, and lambdas, oh my! All of these are typed with `T.proc`. + # + # Limitations: + # 1. All parameters are assumed to be required positional parameters. + # 2. The only runtime check is that the value is a `Proc`. The argument types + # are only checked statically. + sig do + params( + data: T::Array[String], + blk: T.proc.params(val: String).returns(Integer), + ).returns(Integer) + end + def count(data, &blk) + data.sum(&blk) + end + + sig { returns(Integer) } + def count_usage + count(["one", "two", "three"]) { |word| word.length + 1 } + end + + # If the method takes an implicit block, Sorbet will infer `T.untyped` for + # it. Use the explicit block syntax if the types are important. + sig { params(str: String).returns(T.untyped) } + def implicit_block(str) + yield(str) + end + + # If you're writing a DSL and will execute the block in a different context, + # use `bind`. + sig { params(num: Integer, blk: T.proc.bind(Integer).void).void } + def number_fun(num, &blk) + num.instance_eval(&blk) + end + + sig { params(num: Integer).void } + def number_fun_usage(num) + number_fun(10) { puts digits.join } + end + + # If the block doesn't take any parameters, don't include `params`. + sig { params(blk: T.proc.returns(Integer)).returns(Integer) } + def doubled_block(&blk) + 2 * blk.call + end +end + +module Combinators + extend T::Sig + # These methods let you define new types from existing types. + + # Use `T.any` when you have a value that can be one of many types. These are + # sometimes known as "union types" or "sum types". + sig { params(num: T.any(Integer, Float)).returns(Rational) } + def hundreds(num) + num.rationalize + end + + # `T.nilable(Type)` is a convenient alias for `T.any(Type, NilClass)`. + sig { params(val: T.nilable(String)).returns(Integer) } + def strlen(val) + val.nil? ? -1 : val.length + end + + # Use `T.all` when you have a value that must satisfy multiple types. These + # are sometimes known as "intersection types". They're most useful for + # interfaces (described later), but can also describe helper modules. + + module Reversible + extend T::Sig + sig { void } + def reverse + # Pretend this is actually implemented + end + end + + module Sortable + extend T::Sig + sig { void } + def sort + # Pretend this is actually implemented + end + end + + class List + include Reversible + include Sortable + end + + sig { params(list: T.all(Reversible, Sortable)).void } + def rev_sort(list) + # reverse from Reversible + list.reverse + # sort from Sortable + list.sort + end + + def rev_sort_usage + rev_sort(List.new) + end + + # Sometimes, actually spelling out the type every time becomes more confusing + # than helpful. Use type aliases to make them easier to work with. + JSONLiteral = T.type_alias { T.any(Float, String, T::Boolean, NilClass) } + + sig { params(val: JSONLiteral).returns(String) } + def stringify(val) + val.to_s + end +end + +module DataClasses + extend T::Sig + # Use `T::Struct` to create a new class with type-checked fields. It combines + # the best parts of the standard Struct and OpenStruct, and then adds static + # typing on top. + # + # Types constructed this way are sometimes known as "product types". + + class Matcher < T::Struct + # Use `prop` to define a field with both a reader and writer. + prop :count, Integer + # Use `const` to only define the reader and skip the writer. + const :pattern, Regexp + # You can still set a default value with `default`. + const :message, String, default: 'Found one!' + + # This is otherwise a normal class, so you can still define methods. + + # You'll still need to bring `sig` in if you want to use it though. + extend T::Sig + + sig { void } + def reset + self.count = 0 + end + end + + sig { params(text: String, matchers: T::Array[Matcher]).void } + def awk(text, matchers) + matchers.each(&:reset) + text.lines.each do |line| + matchers.each do |matcher| + if matcher.pattern =~ line + Kernel.puts matcher.message + matcher.count += 1 + end + end + end + end + + # Gotchas and limitations + + # 1. `const` fields are not truly immutable. They don't have a writer method, + # but may be changed in other ways. + class ChangeMe < T::Struct + const :list, T::Array[Integer] + end + + sig { params(change_me: ChangeMe).returns(T::Boolean) } + def whoops!(change_me) + change_me = ChangeMe.new(list: [1, 2, 3, 4]) + change_me.list.reverse! + change_me.list == [4, 3, 2, 1] + end + + # 2. `T::Struct` inherits its equality method from `BasicObject`, which uses + # identity equality (also known as "reference equality"). + class Coordinate < T::Struct + const :row, Integer + const :col, Integer + end + + sig { returns(T::Boolean) } + def never_equal! + p1 = Coordinate.new(row: 1, col: 2) + p2 = Coordinate.new(row: 1, col: 2) + p1 != p2 + end + + # Define your own `#==` method to check the fields, if that's what you want. + class Position < T::Struct + extend T::Sig + + const :x, Integer + const :y, Integer + + sig { params(other: Object).returns(T::Boolean) } + def ==(other) + # There's a real implementation here: + # https://github.com/tricycle/sorbet-struct-comparable + true + end + end + + # Use `T::Enum` to define a fixed set of values that are easy to reference. + # This is especially useful when you don't care what the values _are_ as much + # as you care that the set of possibilities is closed and static. + class Crayon < T::Enum + extend T::Sig + + # Initialize members with `enums`. + enums do + # Define each member with `new`. Each of these is an instance of the + # `Crayon` class. + Red = new + Orange = new + Yellow = new + Green = new + Blue = new + Violet = new + Brown = new + Black = new + # The default value of the enum is its name in all-lowercase. To change + # that, pass a value to `new`. + Gray90 = new('light-gray') + end + + sig { returns(String) } + def to_hex + case self + when Red then '#ff0000' + when Green then '#00ff00' + # ... + else '#ffffff' + end + end + end + + sig { params(crayon: Crayon, path: T::Array[Position]).void } + def draw(crayon:, path:) + path.each do |pos| + Kernel.puts "(#{pos.x}, #{pos.y}) = " + crayon.to_hex + end + end + + # To get all the values in the enum, use `.values`. For convenience there's + # already a `#serialize` to get the enum string value. + + sig { returns(T::Array[String]) } + def crayon_names + Crayon.values.map(&:serialize) + end + + # Use the "deserialize" family to go from string to enum value. + + sig { params(name: String).returns(T.nilable(Crayon)) } + def crayon_from_name(name) + if Crayon.has_serialized?(name) + # If the value is not found, this will raise a `KeyError`. + Crayon.deserialize(name) + end + + # If the value is not found, this will return `nil`. + Crayon.try_deserialize(name) + end +end + +module FlowSensitivity + extend T::Sig + # Sorbet understands Ruby's control flow constructs and uses that information + # to get more accurate types when your code branches. + + # You'll see this most often when doing nil checks. + sig { params(name: T.nilable(String)).returns(String) } + def greet_loudly(name) + if name.nil? + 'HELLO, YOU!' + else + # Sorbet knows that `name` must be a String here, so it's safe to call + # `#upcase`. + "HELLO, #{name.upcase}!" + end + end + + # The nils are a special case of refining `T.any`. + sig { params(id: T.any(Integer, T::Array[Integer])).returns(T::Array[String]) } + def database_lookup(id) + if id.is_a?(Integer) + # `ids` must be an Integer here. + [id.to_s] + else + # `ids` must be a T::Array[Integer] here. + id.map(&:to_s) + end + end + + # Sorbet recognizes these methods that narrow type definitions: + # * is_a? + # * kind_of? + # * nil? + # * Class#=== + # * Class#< + # * block_given? + # + # Because they're so common, it also recognizes these Rails extensions: + # * blank? + # * present? + # + # Be careful to maintain Sorbet assumptions if you redefine these methods! + + # Have you ever written this line of code? + # + # raise StandardError, "Can't happen" + # + # Sorbet can help you prove that statically (this is known as + # "exhaustiveness") with `T.absurd`. It's extra cool when combined with + # `T::Enum`! + + class Size < T::Enum + extend T::Sig + + enums do + Byte = new('B') + Kibibyte = new('KiB') + Mebibyte = new('MiB') + # "640K ought to be enough for anybody" + end + + sig { returns(Integer) } + def bytes + case self + when Byte then 1 << 0 + when Kibibyte then 1 << 10 + when Mebibyte then 1 << 20 + else + # Sorbet knows you've checked all the cases, so there's no possible + # value that `self` could have here. + # + # But if you _do_ get here somehow, this will raise at runtime. + T.absurd(self) + + # If you're missing a case, Sorbet can even tell you which one it is! + end + end + end + + # We're gonna need `puts` and `raise` for this next part. + include Kernel + + # Sorbet knows that no code can execute after a `raise` statement because it + # "never returns". + sig { params(num: T.nilable(Integer)).returns(Integer) } + def decrement(num) + raise ArgumentError, '¯\_(ツ)_/¯' unless num + + num - 1 + end + + class CustomError < StandardError; end + + # You can annotate your own error-raising methods with `T.noreturn`. + sig { params(message: String).returns(T.noreturn) } + def oh_no(message = 'A bad thing happened') + puts message + raise CustomError, message + end + + # Infinite loops also don't return. + sig { returns(T.noreturn) } + def loading + loop do + %q(-\|/).each_char do |c| + print "\r#{c} reticulating splines..." + sleep 1 + end + end + end + + # You may run into a situation where Sorbet "loses" your type refinement. + # Remember that almost everything you do in Ruby is a method call that could + # return a different value next time you call it. Sorbet doesn't assume that + # any methods are pure (even those from `attr_reader` and `attr_accessor`). + sig { returns(T.nilable(Integer)) } + def answer + rand > 0.5 ? 42 : nil + end + + sig { void } + def bad_typecheck + if answer.nil? + 0 + else + # But answer might return `nil` if we call it again! + answer + 1 + # ^ Method + does not exist on NilClass component of T.nilable(Integer) + end + end + + sig { void } + def good_typecheck + ans = answer + if ans.nil? + 0 + else + # This time, Sorbet knows that `ans` is non-nil. + ans + 1 + end + end +end + +module InheritancePatterns + extend T::Sig + + # If you have a method that always returns the type of its receiver, use + # `T.self_type`. This is common in fluent interfaces and DSLs. + # + # Warning: This feature is still experimental! + class Logging + extend T::Sig + + sig { returns(T.self_type) } + def log + pp self + self + end + end + + class Data < Logging + extend T::Sig + + sig { params(x: Integer, y: String).void } + def initialize(x: 0, y: '') + @x = x + @y = y + end + + # You don't _have_ to use `T.self_type` if there's only one relevant class. + sig { params(x: Integer).returns(Data) } + def setX(x) + @x = x + self + end + + sig { params(y: String).returns(Data) } + def setY(y) + @y = y + self + end + end + + # Ta-da! + sig { params(data: Data).void } + def chaining(data) + data.setX(1).log.setY('a') + end + + # If it's a class method (a.k.a. singleton method), use `T.attached_class`. + # + # No warning here. This one is stable! + class Box + extend T::Sig + + sig { params(contents: String, weight: Integer).void } + def initialize(contents, weight) + @contents = contents + @weight = weight + end + + sig { params(contents: String).returns(T.attached_class) } + def self.pack(contents) + new(contents, contents.chars.uniq.length) + end + end + + class CompanionCube < Box + extend T::Sig + + sig { returns(String) } + def pick_up + "♥#{@contents}🤍" + end + end + + sig { returns(String) } + def befriend + CompanionCube.pack('').pick_up + end + + # Sorbet has support for abstract classes and interfaces. It can check that + # all the concrete classes and implementations actually define the required + # methods with compatible signatures. + + # Here's an abstract class: + + class WorkflowStep + extend T::Sig + + # Bring in the inheritance helpers. + extend T::Helpers + + # Mark this class as abstract. This means it cannot be instantiated with + # `.new`, but it can still be subclassed. + abstract! + + sig { params(args: T::Array[String]).void } + def run(args) + pre_hook + execute(args) + post_hook + end + + # This is an abstract method, which means it _must_ be implemented by + # subclasses. Add a signature with `abstract` to an empty method to tell + # Sorbet about it. + # + # If this implementation of the method actually gets called at runtime, it + # will raise `NotImplementedError`. + sig { abstract.params(args: T::Array[String]).void } + def execute(args); end + + # The following non-abstract methods _can_ be implemented by subclasses, + # but they're optional. + + sig { void } + def pre_hook; end + + sig { void } + def post_hook; end + end + + class Configure < WorkflowStep + extend T::Sig + + sig { void } + def pre_hook + puts 'Configuring...' + end + + # To implement an abstract method, mark the signature with `override`. + sig { override.params(args: T::Array[String]).void } + def execute(args) + # ... + end + end + + # And here's an interface: + + module Queue + extend T::Sig + + # Bring in the inheritance helpers. + extend T::Helpers + + # Mark this module as an interface. This adds the following restrictions: + # 1. All of its methods must be abstract. + # 2. It cannot have any private or protected methods. + interface! + + sig { abstract.params(num: Integer).void } + def push(num); end + + sig { abstract.returns(T.nilable(Integer)) } + def pop; end + end + + class PriorityQueue + extend T::Sig + + # Include the interface to tell Sorbet that this class implements it. + # Sorbet doesn't support implicitly implemented interfaces (also known as + # "duck typing"). + include Queue + + sig { void } + def initialize + @items = T.let([], T::Array[Integer]) + end + + # Implement the Queue interface's abstract methods. Remember to use + # `override`! + + sig { override.params(num: Integer).void } + def push(num) + @items << num + @items.sort! + end + + sig { override.returns(T.nilable(Integer)) } + def pop + @items.shift + end + end + + # If you use the `included` hook to get class methods from your modules, + # you'll have to use `mixes_in_class_methods` to get them to type-check. + + module Mixin + extend T::Helpers + interface! + + module ClassMethods + extend T::Sig + + sig { void } + def whisk + 'fskfskfsk' + end + end + + mixes_in_class_methods(ClassMethods) + end + + class EggBeater + include Mixin + end + + EggBeater.whisk # Meringue! +end + +module EscapeHatches + extend T::Sig + + # Ruby is a very dynamic language, and sometimes Sorbet can't infer the + # properties you already know to be true. Although there are ways to rewrite + # your code so Sorbet can prove safety, you can also choose to "break out" of + # Sorbet using these "escape hatches". + + # Once you start using `T.nilable`, Sorbet will start telling you _all_ the + # places you're not handling nils. Sometimes, you know a value can't be nil, + # but it's not practical to fix the sigs so Sorbet can prove it. In that + # case, you can use `T.must`. + sig { params(maybe_str: T.nilable(String)).returns(String) } + def no_nils_here(maybe_str) + # If maybe_str _is_ actually nil, this will error at runtime. + str = T.must(maybe_str) + str.downcase + end + + # More generally, if you know that a value must be a specific type, you can + # use `T.cast`. + sig do + params( + str_or_ary: T.any(String, T::Array[String]), + idx_or_range: T.any(Integer, T::Range[Integer]), + ).returns(T::Array[String]) + end + def slice2(str_or_ary, idx_or_range) + # Let's say that, for some reason, we want individual characters from + # strings or sub-arrays from arrays. The other options are not allowed. + if str_or_ary.is_a?(String) + # Here, we know that `idx_or_range` must be a single index. If it's not, + # this will error at runtime. + idx = T.cast(idx_or_range, Integer) + [str_or_ary.chars.fetch(idx)] + else + # Here, we know that `idx_or_range` must be a range. If it's not, this + # will error at runtime. + range = T.cast(idx_or_range, T::Range[Integer]) + str_or_ary.slice(range) || [] + end + end + + # If you know that a method exists, but Sorbet doesn't, you can use + # `T.unsafe` so Sorbet will let you call it. Although we tend to think of + # this as being an "unsafe method call", `T.unsafe` is called on the receiver + # rather than the whole expression. + sig { params(count: Integer).returns(Date) } + def the_future(count) + # Let's say you've defined some extra date helpers that Sorbet can't find. + # So `2.decades` is effectively `(2*10).years` from ActiveSupport. + Date.today + T.unsafe(count).decades + end + + # If this is a method on the implicit `self`, you'll have to make that + # explicit to use `T.unsafe`. + sig { params(count: Integer).returns(Date) } + def the_past(count) + # Let's say that metaprogramming defines a `now` helper method for + # `Time.new`. Using it would normally look like this: + # + # now - 1234 + # + T.unsafe(self).now - 1234 + end + + # There's a special type in Sorbet called `T.untyped`. For any value of this + # type, Sorbet will allow it to be used for any method argument and receive + # any method call. + + sig { params(num: Integer, anything: T.untyped).returns(T.untyped) } + def nothing_to_see_here(num, anything) + anything.digits # Is it an Integer... + anything.upcase # ... or a String? + + # Sorbet will not be able to infer anything about this return value because + # it's untyped. + BasicObject.new + end + + def see_here + # It's actually nil! This will crash at runtime, but Sorbet allows it. + nothing_to_see_here(1, nil) + end + + # For a method without a sig, Sorbet infers the type of each argument and the + # return value to be `T.untyped`. +end + +# The following types are not officially documented but are still useful. They +# may be experimental, deprecated, or not supported. + +module ValueSet + extend T::Sig + + # A common pattern in Ruby is to have a method accept one value from a set of + # options. Especially when starting out with Sorbet, it may not be practical + # to refactor the code to use `T::Enum`. In this case, you can use `T.enum`. + # + # Note: Sorbet can't check this statically becuase it doesn't track the + # values themselves. + sig do + params( + data: T::Array[Numeric], + shape: T.enum([:circle, :square, :triangle]) + ).void + end + def plot_points(data, shape: :circle) + data.each_with_index do |y, x| + Kernel.puts "#{x}: #{y}" + end + end +end + +module Generics + extend T::Sig + + # Generics are useful when you have a class whose method types change based + # on the data it contains or a method whose method type changes based on what + # its arguments are. + + # A generic method uses `type_parameters` to declare type variables and + # `T.type_parameter` to refer back to them. + sig do + type_parameters(:element) + .params( + element: T.type_parameter(:element), + count: Integer, + ).returns(T::Array[T.type_parameter(:element)]) + end + def repeat_value(element, count) + count.times.each_with_object([]) do |elt, ary| + ary << elt + end + end + + sig do + type_parameters(:element) + .params( + count: Integer, + block: T.proc.returns(T.type_parameter(:element)), + ).returns(T::Array[T.type_parameter(:element)]) + end + def repeat_cached(count, &block) + elt = block.call + ary = [] + count.times do + ary << elt + end + ary + end + + # A generic class uses `T::Generic.type_member` to define type variables that + # can be like regular type names. + class BidirectionalHash + extend T::Sig + extend T::Generic + + Left = type_member + Right = type_member + + sig { void } + def initialize + @left_hash = T.let({}, T::Hash[Left, Right]) + @right_hash = T.let({}, T::Hash[Right, Left]) + end + + # Implement just enough to make the methods below work. + + sig { params(lkey: Left).returns(T::Boolean) } + def lhas?(lkey) + @left_hash.has_key?(lkey) + end + + sig { params(rkey: Right).returns(T.nilable(Left)) } + def rget(rkey) + @right_hash[rkey] + end + end + + # To specialize a generic type, use brackets. + sig do + params( + options: BidirectionalHash[Symbol, Integer], + choice: T.any(Symbol, Integer), + ).returns(T.nilable(String)) + end + def lookup(options, choice) + case choice + when Symbol + options.lhas?(choice) ? choice.to_s : nil + when Integer + options.rget(choice).to_s + else + T.absurd(choice) + end + end + + # To specialize through inheritance, re-declare the `type_member` with + # `fixed`. + class Options < BidirectionalHash + Left = type_member(fixed: Symbol) + Right = type_member(fixed: Integer) + end + + sig do + params( + options: Options, + choice: T.any(Symbol, Integer), + ).returns(T.nilable(String)) + end + def lookup2(options, choice) + lookup(options, choice) + end + + # There are other variance annotations you can add to `type_member`, but + # they're rarely used. +end +``` + +## Additional resources + +- [Official Documentation](https://sorbet.org/docs/overview) +- [sorbet.run](https://sorbet.run) - Playground diff --git a/sql.html.markdown b/sql.html.markdown index 685e522d..834cf00b 100644 --- a/sql.html.markdown +++ b/sql.html.markdown @@ -95,7 +95,7 @@ UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; -- Delete rows from the tablename1 table -- where the lname value begins with 'M'. -DELETE FROM tablename1 WHERE lname like 'M%'; +DELETE FROM tablename1 WHERE lname LIKE 'M%'; -- Delete all rows from the tablename1 table, leaving the empty table. DELETE FROM tablename1; diff --git a/sv-se/nix-sv.html.markdown b/sv-se/nix-sv.html.markdown index 647575fe..9069c286 100644 --- a/sv-se/nix-sv.html.markdown +++ b/sv-se/nix-sv.html.markdown @@ -366,6 +366,9 @@ with builtins; [ * [Susan Potter - Nix Cookbook - Nix By Example] (https://ops.functionalalgebra.com/nix-by-example/) - + +* [Zero to Nix - Nix Tutorial] + (https://zero-to-nix.com/) + * [Rommel Martinez - A Gentle Introduction to the Nix Family] (https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix) diff --git a/swift.html.markdown b/swift.html.markdown index e46dcc75..36124e11 100644 --- a/swift.html.markdown +++ b/swift.html.markdown @@ -679,6 +679,9 @@ class Rect: Shape { // A simple class `Square` extends `Rect` class Square: Rect { + // Use a convenience initializer to make calling a designated initializer faster and more "convenient". + // Convenience initializers call other initializers in the same class and pass default values to one or more of their parameters. + // Convenience initializers can have parameters as well, which are useful to customize the called initializer parameters or choose a proper initializer based on the value passed. convenience init() { self.init(sideLength: 5) } diff --git a/tact.html.markdown b/tact.html.markdown new file mode 100644 index 00000000..2cb650ee --- /dev/null +++ b/tact.html.markdown @@ -0,0 +1,603 @@ +--- +language: Tact +filename: tact.tc +contributors: + - ["Tal Kol", "https://www.orbs.com/"] + - ["Kirill Malev", "https://fslabs.io"] + - ["Yash Garg", "https://github.com/yash0501"] +--- + +Tact language is used to program smart contracts on the +[The Open Network](https://ton.org) blockchain. Contract logic is executed in +TVM, the stack-based TON Virtual Machine. + +Tact is a statically typed, but language was designed to be friendly for +developers with JS and Python background. + +This page is based on [Tact-by-Example](https://tact-by-example.org/). +You can use this resource to play around with contracts and check out +the interactive features. + +# Basic syntax, function definition + +```c +// Single line comment + + // This is a multi-line comment + // this is a comment in the comment + + get fun greeting(): String { + // This is a function that returns "hello world" message + // Return type is specified after a colon : + return "hello world"; + } +``` + +# A Simple Counter contract + +This is a simple counter contract that allows users to increment its value. + +This contract has a state variable `val` that persists between contract calls + +- the counter value. When persisted, this variable is encoded as `uint32` - + a 32-bit unsigned integer. Contracts pay rent in proportion to the amount + of persistent space they consume, so compact representations are encouraged. + +State variables should be initialized in `init()` that runs on deployment of +the contract. + +## Messages + +The actor model is a model of concurrent computation and is at the heart of TON +smart contracts. Each smart contract can process one message at a time, change +its own state, or send one or several messages. Processing of the message +occurs in one transaction, that is, it cannot be interrupted. Messages to one +contract are processed consequently one by one. As a result, the execution of +each transaction is local and can be parallelized at the blockchain level, +which allows for on-demand throughput horizontal scaling and hosting an +unlimited number of users and transactions. + +## Receiving messages + +This contract can receive messages from users. Unlike getters that are just +read-only, messages can do write operations and change the contract's +persistent state. Incoming messages are processed in receive() methods as +transactions and cost gas for the sender. + +After deploying the contract, send the increment message by pressing the Send +increment button in order to increase the counter value by one. Afterwards, +call the getter value() to see that the value indeed changed. + +```c +contract Counter { +// Tact allows to create a contract + // persistent state variable of type Int to hold the counter value + val: Int as uint32; + + // initialize the state variable when contract is deployed + init() { + self.val = 0; + } + + // handler for incoming increment messages that change the state + receive("increment") { + self.val = self.val + 1; + } + + // read-only getter for querying the counter value + get fun value(): Int { + return self.val; + } +} +``` + +# The Deployable Trait + +Tact doesn't support classical class inheritance, but contracts can implement +traits. One of the commonly used traits is `Deployable`. It implements a simple +receiver for the Deploy message which helps deploy contracts in a standard way. + +All contracts are deployed by sending them a message. This can be any message, +but best practice is to designate the special `Deploy` +message for this purpose. + +This message has a single field, `queryId`, which is provided by the deployer +(normally zero). If the deploy succeeds, the contract will reply with the +message `DeployOk` and echo the same `queryId` in the response. + +If you're using Tact's [auto-generated](https://docs.tact-lang.org/tools/typescript#tact-contract-in-typescript) TypeScript +classes to deploy, sending the deploy message should look like: + +```c +const msg = { $$type: "Deploy", queryId: 0n }; + await contract.send(sender, { value: toNano(1) }, msg); +``` + +You can see the implementation of the trait [here](https://github.com/tact-lang/tact/blob/main/stdlib/libs/deploy.tact). +Notice that the file deploy.tact needs to be imported from the standard +library using the import keyword. + +```c +// this trait has to be imported +import "@stdlib/deploy"; + +// the Deployable trait adds a default receiver for the "Deploy" message +contract Counter with Deployable { + + val: Int as uint32; + + init() { + self.val = 0; + } + + receive("increment") { + self.val = self.val + 1; + } + + get fun value(): Int { + return self.val; + } +} +``` + +# Integers + +Tact supports a number of primitive data types that are tailored for +smart contract use. + +`Int` is the primary number type. Math in smart contracts is always done +with integers and never with floating points since floats are [unpredictable](https://learn.microsoft.com/en-us/cpp/build/why-floating-point-numbers-may-lose-precision). + +The runtime type `Int` is always 257-bit signed, so all runtime calculations +are done at 257-bit. This should be large enough for pretty much anything you +need as it's large enough to hold the number of atoms in the universe. + +Persistent state variables can be initialized inline or inside `init()`. +If you forget to initialize a state variable, the code will not compile. + +## State costs + +When encoding `Int` to persistent state, we will usually use smaller +representations than 257-bit to reduce storage cost. +The persistent state size is specified in every declaration of +a state variable after the `as` keyword. + +Storing 1000 257-bit integers in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about +0.184 TON per year. Storing 1000 32-bit integers only costs +0.023 TON per year by comparison. + +```c +import "@stdlib/deploy"; + +contract Integers with Deployable { + + // contract persistent state variables + // integers can be persisted in state in various sizes + // range -2^256 to 2^256 - 1 (takes 257 bit = 32 bytes + 1 bit) + i1: Int as int257 = 3001; + i2: Int as uint256; // range 0 to 2^256 - 1 (takes 256 bit = 32 bytes) + // range -2^255 to 2^255 - 1 (takes 256 bit = 32 bytes) + i3: Int as int256 = 17; + i4: Int as uint128; // range 0 to 2^128 - 1 (takes 128 bit = 16 bytes) + // range -2^127 to 2^127 - 1 (takes 128 bit = 16 bytes) + i5: Int as int128; + i6: Int as coins; // range 0 to 2^120 - 1 (takes 120 bit = 15 bytes) + // range 0 to 18,446,744,073,709,551,615 (takes 64 bit = 8 bytes) + i7: Int as uint64 = 0x1c4a; + // range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // (takes 64 bit = 8 bytes) + i8: Int as int64 = -203; + i9: Int as uint32 = 0; // range 0 to 4,294,967,295 (takes 32 bit = 4 bytes) + // range -2,147,483,648 to 2,147,483,647 (takes 32 bit = 4 bytes) + i10: Int as int32 = 0; + i11: Int as uint16 = 0; // range 0 to 65,535 (takes 16 bit = 2 bytes) + i12: Int as int16 = 0; // range -32,768 to 32,767 (takes 16 bit = 2 bytes) + i13: Int as uint8 = 0; // range 0 to 255 (takes 8 bit = 1 byte) + i14: Int as int8 = 0; // range -128 to 127 (takes 8 bit = 1 byte) + + init() { + // we can define numbers in hex (base 16) + self.i2 = 0x83dfd552e6372; + self.i4 = 1507998500293440234999; // we can define numbers in decimal + self.i5 = pow(10, 9); // this is 10^9 = 1,000,000,000 + self.i6 = ton("1.23"); // easy to read coin balances + // (coins type is nano-tons, like cents, just with 9 decimals) + } + + receive("show all") { + dump(self.i1); + dump(self.i2); + dump(self.i3); + dump(self.i4); + dump(self.i5); + dump(self.i6); + dump(self.i7); + dump(self.i8); + } + + get fun result(): Int { + return self.i1; + } +} +``` + +## Bools, Addresses, Strings, Operators and Constants + +### Bool + +Bool can be used for boolean variables + +```js +b1: Bool = true; +b2: Bool = false; +``` + +### Address + +Address is another primitive data type. It represents standard addresses on +the TON blockchain. +TON is divided into multiple chains called workchains. One of the internal +fields of the address is the workchain id: +0 - The standard workchain, for regular users. Your contracts will be here. +-1 - The masterchain, usually for validators. + +```js +// bouncable (same foundation wallet) +a1: Address = address("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N"); +// non-bounceable (same foundation wallet) +a2: Address = address("UQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqEBI"); +``` + +### String + +Tact has basic support for strings. Strings support unicode and don't +have any special escape characters like \n. +Strings are immutable. Once a sequence of characters is created, this +sequence cannot be modified. +If you need to concatenate strings in run-time, you can use a StringBuilder. +This object handles gas efficiently and supports append() of various types to +the string. + +```js +s1: String = "hello world"; +sb: StringBuilder = beginString(); +sb.append(self.s1); +``` + +### Integer Operations + +Addition, subtraction, multiplication, division, modulo, +shift left and right, minimum and maximum numbers, absolute value + +```js +i: Int = -12; // temporary variable, runtime Int type is always int257 +i = i1 * 3 + (i2 - i); // basic math expressions +i = i1 % 10; // modulo (remainder after division), 3001 % 10 = 1 +i = i1 / 1000; // integer division (truncation toward zero), 3001 / 1000 = 3 +i = i1 >> 3; // shift right (multiply by 2^n) +i = i1 << 2; // shift left (divide by 2^n) +i = min(i2, 11); // minimum between two numbers +i = max(i2, 66); // maximum between two numbers +i = abs(-1 * i2); // absolute value +``` + +### Constants + +Unlike variables, constants cannot change. Their values are +calculated in compile-time and cannot change during execution. + +```js +const StateUnpaid: Int = 0; +``` + +## Getters, Receivers and Messages + +### Getters + +Getters are special contract functions that allow users to query +information from the contract. +Contract methods starting with the prefix get fun are all getters. +Calling getters is free and does not cost gas. +Getters are read-only, they cannot change the contract persistent state. +A contract cannot execute a getter of another contract. Getters are only +executable by end-users off-chain. + +```js +count: Int as uint32 = 17; + +get fun counter(): Int { + return self.count; +} +``` + +### Receivers + +Contract methods named receive() are the handlers that process +each incoming message type. +Tact will automatically route every incoming message to the correct receiver +listening for it according to its type. A message is only handled by one receiver. + +Handler for "increment" textual message - this is a textual string message, +these cannot carry input arguments + +```js +receive("increment") { + self.val = self.val + 1; +} +``` + +### Messages + +Messages are defined using the message keyword. They can carry input +arguments. For integers, you must define the encoding size, just like in +state variables. + +Handler for the "Add" message - this is a binary message that has an input +argument (amount) + +```js +receive(msg: Add) { + self.val = self.val + msg.amount; +} +``` + +## Structs + +Structs allow you to combine multiple primitives together in a more semantic way. +Structs can define complex data types that contain multiple fields of +different types. They can also be nested. + +```js +// Normal struct +struct Point { + x: Int as int64; + y: Int as int64; +} + +// Nested struct +struct Params { + name: String = "Satoshi"; // default value + age: Int? = null; // optional field + point: Point; // nested structs +} +``` + +## Message Sender and Throwing Errors + +### Message Sender + +Every incoming message is sent from some contract that has +an address. You can query the address of the message sender by calling sender() + +```js +deployer: Address = sender(); +``` + +### Errors + +When an error is thrown, the transaction reverts. By writing a +require() on a condition that isn't met + +```js +require(self.val < 5, "Counter is too high"); +``` + +## Messages Between Contracts, Sending and Receiving TON Coins + +### Messages Between Contracts + +Different contracts can only communicate with +each other by sending each other messages. + +This example sends a message to the to address with value of 1 TON and body +of a comment with a string "Hello, World!". +SendIgnoreErrors means that even when error occurs during message sending +next messages would be sent anyway. + +```js +let to: Address = ...; +let value: Int = ton("1"); +send(SendParameters{ + to: to, // address of receiver + value: value, // amount of TON you want to send + mode: SendIgnoreErrors, // 8-bit flag configuring how to send message + bounce: true, // if set to true (default) then message + // will be bounced back to sender + body: "Hello, World!".asComment() // message body as Cell +}); +``` + +### Receiving TONs + +You can query the contract balance with myBalance() - note +that the value is in nano-tons (like cents, just with 9 decimals). The balance +already contains the incoming message value. +You can also get the incoming TON balance with context().value + +```js +val: Int as int64 = myBalance() +// or +// print how much TON coin were sent with this message +dump(context().value); +``` + +### Sending TONs + +We can send any amount of TON to any address just like we created +a send call between different contracts + +Send mode SendRemainingValue will add to the outgoing value any excess left +from the incoming message after all gas costs are deducted from it. + +```js +amount: Int as coins = ton("1"); +send(SendParameters{ + to: sender(), + bounce: true, + value: amount, + mode: SendRemainingValue + SendIgnoreErrors +}); +``` + +## If/Else statements and Loops + +### If + +Tact supports if statements in a similar syntax to most programming +languages. Curly braces are required. +We can have the else and else if similar to other programming languages. + +```js +if (val > 1000) { + dump("larger than 1000"); +} else if (val > 500) { + dump("between 500 and 1000"); +} else { + dump("smaller than 500"); +} +``` + +### Loops + +Tact does not support traditional 'for' loops, 'break' and 'continue' +statements in loops. +The repeat loop statement input number must fit within an int32. + +```js +// repeat exactly 10 times + +repeat (10) { + i = i + 1; + sum = sum + i; +} + +// While loop + +let x: Int = 10; +while(x > 0) { + x = x - 1; +} + +// do-until loop + +let x: Int = 10; +do { + x = x - 1; +} until (x <= 0); +``` + +## Functions + +Functions in Tact start with the fun keyword. Functions can receive multiple +input arguments and can optionally return a single output value. You can +return a struct if you want to return multiple values. + +```js +fun average(a: Int, b: Int): Int { + return (a + b) / 2; +} +``` + +## Maps and Arrays + +### Maps + +Maps are a dictionary type that can hold an arbitrary number of items, +each under a different key. +The keys in maps can either be an Int type or an Address type. +You can check if a key is found in the map by calling the get() method. +Replace the value under a key by calling the set() method. + +```js +mi1: map<Int, TokenInfo>; // maps with Int as key +ma1: map<Address, TokenInfo>; // maps with Address as key +``` + +### Arrays + +To create an array, define a map with 'Int' type as key as well as value. + +```js +arr: map<Int, Int>; // this is our array implemented with a map +``` + +## Ownable Standard Library + +The Ownable trait allows the contract to set an owner role, which can have +higher priviliges from everybody else. +For this you would need to import the "@stdlib/ownable" library and inherit +it in your contract + +- Use the self.requireOwner() call to verify that the person making that + function call is the owner of contract +- 'ChangeOwner{newOwner: Address}' message which allows the owner to + transfer ownership. +- Define state variables named 'owner: Address' and 'stopped: Bool' and + call 'self.requireNotStopped()' on actions that should be stopped. +- Define state variables named 'owner: Address' and "stopped: Bool' and + call 'self.requireNotStopped()' on actions that should be stopped. + +```js +import "@stdlib/ownable"; +import "@stdlib/deploy"; + +contract Counter with Deployable, Ownable { + owner: Address; + + init() { // initialize a contract with default values like 'constructor' + self.owner = sender(); // we can initialize owner to any value we want, the deployer in this case + self.val = 0; + } + + // this message in only available to the owner + receive("double") { + self.requireOwner(); + self.val = self.val * 2; + } + + // this message will only work until the contract was stopped + receive("increment") { + self.requireNotStopped(); + self.val = self.val + 1; + } + + // this message will only work as long as the contract is not stopped + receive("increment2") { + self.requireNotStopped(); + self.val = self.val + 1; + } +} + +``` + +## Additional resources + +- [TON Documentation](https://ton.org/docs/#/) +- [Tact Docs](https://docs.tact-lang.org/) +- [Tact by Example](https://tact-by-example.org/) +- [Community portal](https://society.ton.org) +- [Blockchain portal](https://ton.org) +- [Stackoverflow](https://stackoverflow.com/questions/tagged/ton) + +## Social + +- [Tact community](https://t.me/tactlang) +- [Developer community](https://t.me/tondev_eng) +- [TON Learn](https://t.me/ton_learn) +- [Tondev News](https://t.me/tondevnews) +- [TON Technical Updates](https://t.me/thetontech) + +## Useful blogposts + +- [Setting up a TON Development Environment](https://society.ton.org/setting-up-a-ton-development-environment) +- [Hello World on TON](https://society.ton.org/ton-hello-world-step-by-step-guide-for-writing-your-first-smart-contract-in-func) + +## Future To Dos + +- Add smart contracts examples +- Add more links to documentations + +This file is based on [Tact By Example](https://tact-by-example.org). + +P.S. If by any chance you're familiar with [Forth](https://learnxinyminutes.com/docs/forth/), +you can also take a look at [Fift](https://ton-blockchain.github.io/docs/fiftbase.pdf). diff --git a/tailspin.html.markdown b/tailspin.html.markdown new file mode 100644 index 00000000..89ccdb1f --- /dev/null +++ b/tailspin.html.markdown @@ -0,0 +1,383 @@ +--- +language: tailspin +filename: learntailspin.tt +contributors: + - ["Torbjörn Gannholm", "https://github.com/tobega/"] + +--- + +**Tailspin** works with streams of values in pipelines. You may often feel +that your program is the machine and that the input data is the program. + +While Tailspin is unlikely to become mainstream, or even production-ready, +it will change the way you think about programming in a good way. + +```c +// Comment to end of line + +// Process data in a pipeline with steps separated by -> +// String literals are delimited by single quotes +// A bang (!) indicates a sink, or end of the pipe +// OUT is the standard output object, ::write is the message to write output +'Hello, World!' -> !OUT::write + +// Output a newline by just entering it in the string (multiline strings) +' +' -> !OUT::write +// Or output the decimal unicode value for newline (10) between $# and ; +'$#10;' -> !OUT::write + +// Define an immutable named value. Value syntax is very literal. +def names: ['Adam', 'George', 'Jenny', 'Lucy']; + +// Stream the list to process each name. Note the use of $ to get the value. +// The current value in the pipeline is always just $ +// String interpolation starts with a $ and ends with ; +$names... -> 'Hello $;! +' -> !OUT::write + +// You can also stream in the interpolation and nest interpolations +// Note the list indexing with parentheses and the slice extraction +// Note the use of ~ to signify an exclusive bound to the range +// Outputs 'Hello Adam, George, Jenny and Lucy!' +'Hello $names(first);$names(first~..~last)... -> ', $;'; and $names(last);! +' -> !OUT::write + +// Conditionally say different things to different people +// Matchers (conditional expressions) are delimited by angle brackets +// A set of matchers, evaluated top down, must be in templates (a function) +// Here it is an inline templates delimited by \( to \) +// Note the doubled '' and $$ to get a literal ' and $ +$names... -> \( + when <='Adam'> do 'What''s up $;?' ! + when <='George'> do 'George, where are the $$10 you owe me?' ! + otherwise 'Hello $;!' ! +\) -> '$;$#10;' -> !OUT::write + +// You can also define templates (functions) +// A lone ! emits the value into the calling pipeline without returning control +// The # sends the value to be matched by the matchers +// Note that templates always take one input value and emit 0 or more outputs +templates collatz-sequence + when <..0> do 'The start seed must be a positive integer' ! + when <=1> do $! +// The ?( to ) allows matching a computed value. Can be concatenated as "and" + when <?($ mod 2 <=1>)> do + $ ! + 3 * $ + 1 -> # + otherwise + $ ! + $ ~/ 2 -> # +end collatz-sequence + +// Collatz sequence from random start on one line separated by spaces +1000 -> SYS::randomInt -> $ + 1 -> collatz-sequence -> '$; ' -> !OUT::write +' +' -> !OUT::write + +// Collatz sequence formatted ten per line by an indexed list template +// Note the square brackets creates a list of the enclosed pipeline results +// The \[i]( to \) defines a templates to apply to each value of a list, +// the i (or whatever identifier you choose) holds the index +[1000 -> SYS::randomInt -> $ + 1 -> collatz-sequence] +-> \[i]( + when <=1|?($i mod 10 <=0>)> do '$;$#10;' ! + otherwise '$; ' ! +\)... -> !OUT::write + +// A range can have an optional stride +def odd-numbers: [1..100:2]; + +// Use mutable state locally. One variable per templates, always called @ +templates product + @: $(first); + $(first~..last)... -> @: $@ * $; + $@ ! +end product + +$odd-numbers(6..8) -> product -> !OUT::write +' +' -> !OUT::write + +// Use processor objects to hold mutable state. +// Note that the outer @ must be referred to by name in inner contexts +// A sink templates gives no output and is called prefixed by ! +// A source templates takes no input and is called prefixed by $ +processor Product + @: 1; + sink accumulate + @Product: $@Product * $; + end accumulate + source result + $@Product ! + end result +end Product + +// The processor is a constructor templates. This one called with $ (no input) +def multiplier: $Product; + +// Call object templates by sending messages with :: +1..7 -> !multiplier::accumulate +-1 -> !multiplier::accumulate +$multiplier::result -> 'The product is $; +' -> !OUT::write + +// Syntax sugar for a processor implementing the collector interface +1..7 -> ..=Product -> 'The collected product is $;$#10;' -> !OUT::write + +// Symbol sets (essentially enums) can be defined for finite sets of values +data colour #{green, red, blue, yellow} + +// Use processor typestates to model state cleanly. +// The last named mutable state value set determines the typestate +processor Lamp + def colours: $; + @Off: 0; + state Off + source switchOn + @On: $@Off mod $colours::length + 1; + 'Shining a $colours($@On); light$#10;' ! + end switchOn + end Off + state On + source turnOff + @Off: $@On; + 'Lamp is off$#10;' ! + end turnOff + end On +end Lamp + +def myLamp: [colour#green, colour#blue] -> Lamp; + +$myLamp::switchOn -> !OUT::write // Shining a green light +$myLamp::turnOff -> !OUT::write // Lamp is off +$myLamp::switchOn -> !OUT::write // Shining a blue light +$myLamp::turnOff -> !OUT::write // Lamp is off +$myLamp::switchOn -> !OUT::write // Shining a green light + +// Use regular expressions to test strings +['banana', 'apple', 'pear', 'cherry']... -> \( + when <'.*a.*'> do '$; contains an ''a''' ! + otherwise '$; has no ''a''' ! +\) -> '$; +' -> !OUT::write + +// Use composers with regular expressions and defined rules to parse strings +composer parse-stock-line + {inventory-id: <INT> (<WS>), name: <'\w+'> (<WS>), currency: <'.{3}'>, + unit-price: <INT> (<WS>?) <parts>?} + rule parts: associated-parts: [<part>+] + rule part: <'[A-Z]\d+'> (<=','>?) +end parse-stock-line + +'705 gizmo EUR5 A67,G456,B32' -> parse-stock-line -> !OUT::write +// {associated-parts: [A67, G456, B32], currency: EUR, +// inventory-id: 705, name: gizmo, unit-price: 5} +' +' -> !OUT::write + +// Stream a string to split it into glyphs. +// A list can be indexed/sliced by an array of indexes +// Outputs ['h','e','l','l','o'], indexing arrays/lists starts at 1 +['abcdefghijklmnopqrstuvwxyz'...] -> $([8,5,12,12,15]) -> !OUT::write +' +' -> !OUT::write + +// We have used only raw strings above. +// Strings can have different types as determined by a tag. +// Comparing different types is an error, unless a wider type bound is set +// Type bound is given in ´´ and '' means any string value, tagged or raw +templates get-string-type + when <´''´ '.*'> do '$; is a raw string' ! + when <´''´ id´'\d+'> do '$; is a numeric id string' ! + when <´''´ =id´'foo'> do 'id foo found' ! + when <´''´ id´'.*'> do '$; is an id' ! + when <´''´ name´'.+'> do '$; is a name' ! + otherwise '$; is not a name or id, nor a raw string' ! +end get-string-type + +[name´'Anna', 'foo', id´'789', city´'London', id´'xzgh', id´'foo']... +-> get-string-type -> '$; +' -> !OUT::write + +// Numbers can be raw, tagged or have a unit of measure +// Type .. is any numeric value, tagged, measure or raw +templates get-number-type + when <´..´ =inventory-id´86> do 'inventory-id 86 found' ! + when <´..´ inventory-id´100..> do '$; is an inventory-id >= 100' ! + when <´..´ inventory-id´0..|..inventory-id´0> do '$; is an inventory-id' ! + when <´..´ 0"m"..> do '$; is an m-measure >= 0"m"' ! + when <´..´ ..0|0..> do '$; is a raw number' ! + otherwise '$; is not a positive m-measure nor an inventory-id, nor raw' ! +end get-number-type + +[inventory-id´86, inventory-id´6, 78"m", 5"s", 99, inventory-id´654]... +-> get-number-type -> '$; +' -> !OUT::write + +// Measures can be used in arithmetic, "1" is the scalar unit +// When mixing measures you have to cast to the result measure +4"m" + 6"m" * 3"1" -> ($ ~/ 2"s")"m/s" -> '$; +' -> !OUT::write + +// Tagged identifiers must be made into raw numbers when used in arithmetic +// Then you can cast the result back to a tagged identifier if you like +inventory-id´300 -> inventory-id´($::raw + 1) -> get-number-type -> '$; +' -> !OUT::write + +// Fields get auto-typed, tagging raw strings or numbers by default +// You cannot assign the wrong type to a field +def item: { inventory-id: 23, name: 'thingy', length: 12"m" }; + +'Field inventory-id $item.inventory-id -> get-number-type; +' -> !OUT::write +'Field name $item.name -> get-string-type; +' -> !OUT::write +'Field length $item.length -> get-number-type; +' -> !OUT::write + +// You can define types and use as type-tests. This also defines a field. +// It would be an error to assign a non-standard plate to a standard-plate field +data standard-plate <'[A-Z]{3}[0-9]{3}'> + +[['Audi', 'XYZ345'], ['BMW', 'I O U']]... -> \( + when <?($(2) <standard-plate>)> do {make: $(1), standard-plate: $(2)}! + otherwise {make: $(1), vanity-plate: $(2)}! +\) -> '$; +' -> !OUT::write + +// You can define union types +data age <"years"|"months"> + +[ {name: 'Cesar', age: 20"years"}, + {name: 'Francesca', age: 19"years"}, + {name: 'Bobby', age: 11"months"}]... +-> \( +// Conditional tests on structures look a lot like literals, with field tests + when <{age: <13"years"..19"years">}> do '$.name; is a teenager'! + when <{age: <"months">}> do '$.name; is a baby'! +// You don't need to handle all cases, 'Cesar' will just be ignored +\) -> '$; +' -> !OUT::write + +// Array/list indexes start at 1 by default, but you can choose +// Slices return whatever overlaps with the actual array +[1..5] -> $(-2..2) -> '$; +' -> !OUT::write // Outputs [1,2] +0:[1..5] -> $(-2..2) -> '$; +' -> !OUT::write // Outputs [1,2,3] +-2:[1..5] -> $(-2..2) -> '$; +' -> !OUT::write // Outputs [1,2,3,4,5] + +// Arrays can have indexes of measures or tagged identifiers +def game-map: 0"y":[ + 1..5 -> 0"x":[ + 1..5 -> level´1:[ + 1..3 -> { + level: $, + terrain-id: 6 -> SYS::randomInt, + altitude: (10 -> SYS::randomInt)"m" + } + ] + ] +]; + +// Projections (indexing) can span several dimensions +$game-map(3"y"; 1"x"..3"x"; level´1; altitude:) -> '$; +' -> !OUT::write // Gives a list of three altitude values + +// Flatten and do a grouping projection to get stats +// Count and Max are built-in collector processors +[$game-map... ... ...] -> $(collect { + occurences: Count, + highest-on-level: Max&{by: :(altitude:), select: :(level:)} + } by $({terrain-id:})) +-> !OUT::write +' +' -> !OUT::write + +// Relations are sets of structures/records. +// Here we get all unique {level:, terrain-id:, altitude:} combinations +def location-types: {|$game-map... ... ...|}; + +// Projections can re-map structures. Note § is the relative accessor +$location-types({terrain-id:, foo: §.level::raw * §.altitude}) +-> '$; +' -> !OUT::write + +// Relational algebra operators can be used on relations +($location-types join {| {altitude: 3"m"} |}) +-> !OUT::write +' +' -> !OUT::write + +// Define your own operators for binary operations +operator (left dot right) + $left -> \[i]($ * $right($i)!\)... -> ..=Sum&{of: :()} ! +end dot + +([1,2,3] dot [2,5,8]) -> 'dot product: $; +' -> !OUT::write + +// Supply parameters to vary templates behaviour +templates die-rolls&{sides:} + 1..$ -> $sides::raw -> SYS::randomInt -> $ + 1 ! +end die-rolls + +[5 -> die-rolls&{sides:4}] -> '$; +' -> !OUT::write + +// Pass templates as parameters, maybe with some parameters pre-filled +source damage-roll&{first:, second:, third:} + (1 -> first) + (1 -> second) + (1 -> third) ! +end damage-roll + +$damage-roll&{first: die-rolls&{sides:4}, + second: die-rolls&{sides:6}, third: die-rolls&{sides:20}} +-> 'Damage done is $; +' -> !OUT::write + +// Write tests inline. Run by --test flag on command line +// Note the ~ in the matcher means "not", +// and the array content matcher matches elements < 1 and > 4 +test 'die-rolls' + assert [100 -> die-rolls&{sides: 4}] <~[<..~1|4~..>]> 'all rolls 1..4' +end 'die-rolls' + +// Provide modified modules to tests (aka test doubles or mocks) +// IN is the standard input object and ::lines gets all lines +source read-numbers + $IN::lines -> # + when <'\d+'> do $! +end read-numbers + +test 'read numbers from input' + use shadowed core-system/ + processor MockIn + source lines + [ + '12a', + '65', + 'abc' + ]... ! + end lines + end MockIn + def IN: $MockIn; + end core-system/ + assert $read-numbers <=65> 'Only 65 is read' +end 'read numbers from input' + +// You can work with byte arrays +composer hexToBytes + <HEX> +end hexToBytes + +'1a5c678d' -> hexToBytes -> ($ and [x 07 x]) -> $(last-1..last) -> '$; +' -> !OUT::write // Outputs 0005 + +``` + +## Further Reading + +- [Main Tailspin site](https://github.com/tobega/tailspin-v0/) +- [Tailspin language reference](https://github.com/tobega/tailspin-v0/blob/master/TailspinReference.md) diff --git a/tcsh.html.markdown b/tcsh.html.markdown index 05954442..8f8429bc 100644 --- a/tcsh.html.markdown +++ b/tcsh.html.markdown @@ -28,23 +28,23 @@ Some more files: ```tcsh #!/bin/tcsh -# First line of the script is shebang which tells the system how to execute the -# script: http://en.wikipedia.org/wiki/Shebang_(Unix) -# TCSH emulates the shebang on systems which don't understand it. +# The first line of the script is a shebang which tells the system how to execute +# the script: http://en.wikipedia.org/wiki/Shebang_(Unix) +# TCSH emulates the shebang on systems that don't understand it. -# In most cases you'll use `#!/bin/tcsh -f', because `-f' option does not load +# In most cases you'll use `#!/bin/tcsh -f`, because `-f` option does not load # any resource or start-up files, or perform any command hashing, and thus # starts faster. # --- the echo command -------------------------------------------------------- -# The `echo' writes each word to the shell's standard output, separated by +# The `echo` writes each word to the shell's standard output, separated by # spaces and terminated with a newline. The echo_style shell variable may be # set to emulate (or not) the flags and escape sequences. # Display the value of echo_style echo $echo_style -# Enable `echo' to support backslashed characters and `-n' option (no new line) +# Enable `echo` to support backslashed characters and `-n` option (no new line) # This is the default for tcsh, but your distro may change it. Slackware has # done so. set echo_style = both @@ -65,17 +65,17 @@ echo 'two\nlines' # --- Basic Syntax ------------------------------------------------------------ # A special character (including a blank or tab) may be prevented from having -# its special meaning by preceding it with a backslash `\'. -# this will display the last history commands +# its special meaning by preceding it with a backslash `\`. +# This will display the last history commands echo !! -# this will not +# This will not echo \!\! -# Single quotes prevents expanding special characters too, but some -# characters like `!' and backslash have higher priority -# `$' (variable value) will not expands +# Single quotes prevent expanding special characters too, but some +# characters like `!` and backslash have higher priority +# `$` (variable value) will not expand echo '$1 tip' -# `!' (history) will expands +# `!` (history) will expand echo '!!' # Strings enclosed by back-quotes will be executed and replaced by the result. @@ -85,16 +85,16 @@ echo `ls` echo 'first line'; echo 'second line' # There is also conditional execution -echo "Always executed" || echo "Only executed if first command fails" -echo "Always executed" && echo "Only executed if first command does NOT fail" +echo "Always executed" || echo "Only executed if the first command fails" +echo "Always executed" && echo "Only executed if the first command does NOT fail" # Parenthesised commands are always executed in a subshell, -# example: create a project and then informs you that it finished while +# example: creates a project and then informs you that it finished while # it does the installation. make && ( espeak "BOSS, compilation finished"; make install ) -# prints the home directory but leaving you where you were +# prints the home directory but leaves you where you were (cd; pwd); pwd # Read tcsh man-page documentation @@ -103,10 +103,10 @@ man tcsh # --- Variables --------------------------------------------------------------- # The shell maintains a list of variables, each of which has as value a list of # zero or more words. The values of shell variables can be displayed and -# changed with the `set' and `unset' commands. -# The system maintains its own list of ``environment'' variables. -# These can be displayed and changed with `printenv', `setenv' and `unsetenv'. -# The syntax of setenv is similar to POSIX sh. +# changed with the `set` and `unset` commands. +# The system maintains its own list of "environment" variables. +# These can be displayed and changed with `printenv`, `setenv`, and `unsetenv`. +# The syntax of `setenv` is similar to POSIX sh. # Assign a value or nothing will create a variable # Assign nothing @@ -122,7 +122,7 @@ set var = `ls` # Remove a variable unset var -# Prints 1 (true) if the variable `var' exists otherwise prints 0 (false) +# Prints 1 (true) if the variable `var` exists otherwise prints 0 (false) echo $?var # Print all variables and their values set @@ -130,10 +130,10 @@ set # Prints the contents of 'var' echo $var; echo "$var"; -# Prints the string `$var' +# Prints the string `$var` echo \$var echo '$var' -# braces can be used to separate variable from the rest when its needed +# Braces can be used to separate variables from the rest when it is needed set num = 12; echo "There ${num}th element" # Prints the number of characters of the value: 6 @@ -147,7 +147,7 @@ echo $var echo $var[*] # Print the count of elements: 5 echo $#var -# Print indexed element; prints the second element: two +# Print the indexed element; This prints the second element: two echo $var[2] # Print range of elements; prints 2nd up to 3rd: two, three echo $var[2-3] @@ -165,8 +165,8 @@ echo $var[-3] # $! the PID of the last background process started by this shell # $$ script's PID -# $path, $PATH the list of directories that will search for executable to run -# $home, $HOME user's home directory, also the `~' can be used instead +# $path, $PATH the list of directories that will search for an executable to run +# $home, $HOME user's home directory, also the `~` can be used instead # $uid user's login ID # $user user's login name # $gid the user's group ID @@ -174,24 +174,24 @@ echo $var[-3] # $cwd, $PWD the Current/Print Working Directory # $owd the previous working directory # $tcsh tcsh version -# $tty the current tty; ttyN for linux console, pts/N for terminal +# $tty the current tty; ttyN for Linux console, pts/N for terminal # emulators under X # $term the terminal type # $verbose if set, causes the words of each command to be printed. -# can be set by the `-v' command line option too. +# can be set by the `-v` command line option too. # $loginsh if set, it is a login shell # TIP: $?0 is always false in interactive shells # TIP: $?prompt is always false in non-interactive shells -# TIP: if `$?tcsh' is unset; you run the original `csh' or something else; -# try `echo $shell' -# TIP: $verbose this is useful to debugging scripts -# NOTE: $PWD and $PATH are synchronised with $cwd and $pwd automatically. +# TIP: if `$?tcsh` is unset; you run the original `csh` or something else; +# try `echo $shell` +# TIP: `$verbose` is useful for debugging scripts +# NOTE: `$PWD` and `$PATH` are synchronised with `$cwd` and `$pwd` automatically. # --- Variable modifiers ------------------------------------------------------ # Syntax: ${var}:m[:mN] # Where <m> is: -# h : the directory t : the filenane r : remove extension e : the extension +# h : the directory t : the filename r : remove extension e : the extension # u : uppercase the first lowercase letter # l : lowercase the first uppercase letter # p : print but do not execute it (hist) @@ -199,8 +199,8 @@ echo $var[-3] # x : like q, but break into words at white spaces # g : apply the following modifier once to each word # a : apply the following modifier as many times as possible to single word -# s/l/r/ : search for `l' and replace with `r', not regex; the `&' in the r is -# replaced by l +# s/l/r/ : search for `l` and replace with `r`, not regex; the `&` in the `r` is +# replaced by `l` # & : Repeat the previous substitution # start with this file @@ -232,7 +232,7 @@ echo 'this string' >> file.txt echo 'this string' >>& file.txt # Redirect the standard input from file.txt cat < file.txt -# Input from keyboard; this stores the input line to variable `x' +# Input from keyboard; this stores the input line to variable `x` set x = $< # Document here; cat << LABEL @@ -243,7 +243,7 @@ LABEL (grep 'AGP' /usr/src/linux/Documentation/* > output-file.txt) >& error-file.txt # example: read a name from standard input and display a greetings message -echo -n "Enter your name? " +echo -n "Enter your name: " set name = $< echo "Greetings $name" @@ -266,15 +266,15 @@ if ( $name != $user ) echo "Your name isn't your username" # NOTE: if $name is empty, tcsh sees the above condition as: # if ( != $user ) ... # which is invalid syntax -# so the "safe" way to use potentially empty variables in tcsh is: +# The "safe" way to use potentially empty variables in tcsh is: # if ( "$name" != $user ) ... # which, when $name is empty, is seen by tcsh as: # if ( "" != $user ) ... # which works as expected # There is also conditional execution -echo "Always executed" || echo "Only executed if first command fails" -echo "Always executed" && echo "Only executed if first command does NOT fail" +echo "Always executed" || echo "Only executed if the first command fails" +echo "Always executed" && echo "Only executed if the first command does NOT fail" # To use && and || with if statements, you don't need multiple pairs of # square brackets: @@ -286,14 +286,14 @@ if ( "$name" == "Daniya" || "$name" == "Zach" ) then echo "This will run if $name is Daniya OR Zach." endif -# String matching operators ( `=~' and `!~' ) +# String matching operators ( `=~` and `!~` ) # The ‘==’ ‘!=’ ‘=~’ and ‘!~’ operators compare their arguments as strings; # all others operate on numbers. The operators ‘=~’ and ‘!~’ are like ‘!=’ # and ‘==’ except that the right hand side is a glob-pattern against which -# the left hand operand is matched. +# the left-hand operand is matched. if ( $user =~ ni[ck]* ) echo "Greetings Mr. Nicholas." -if ( $user !~ ni[ck]* ) echo "Hey, get out of Nicholas PC." +if ( $user !~ ni[ck]* ) echo "Hey, get out of Nicholas' PC." # Arithmetic expressions are denoted with the following format: @ result = 10 + 5 @@ -302,16 +302,16 @@ echo $result # Arithmetic Operators # +, -, *, /, % # -# Arithmetic Operators which must be parenthesised +# Arithmetic Operators which must be parenthesized # !, ~, |, &, ^, ~, <<, >>, # Compare and logical operators # -# All operators are same as in C. +# All operators are the same as in C. # It is non so well documented that numeric expressions require spaces -# in-between; Also, `@' has its own parser, it seems that work well when the -# expression is parenthesised otherwise the primary parser seems it is active. -# Parenthesis require spaces around, this is documented. +# in-between; Also, `@` has its own parser, it seems that it works well when +# the expression is parenthesized, otherwise the primary parser seems to be +# active. Parentheses require spaces around, this is documented. # wrong @ x = $y+1 @@ -330,32 +330,32 @@ echo $result # C's operators ++ and -- are supported if there is not assignment @ result ++ -# None shell created to do mathematics; +# No shell was created to do mathematics; # Except for the basic operations, use an external command with backslashes. # # I suggest the calc as the best option. # (http://www.isthe.com/chongo/tech/comp/calc/) # -# The standard Unix's bc as second option +# The standard Unix's bc as the second option # (https://www.gnu.org/software/bc/manual/html_mono/bc.html) # -# The standard Unix's AWK as third option +# The standard Unix's AWK as the third option # (https://www.gnu.org/software/gawk/manual/gawk.html) -# You can also use `perl', `php' or even several BASICs, but prefer the -# above utilities for faster load-and-run results. +# You can also use `Perl`, `PHP`, `python`, or even several BASICs, but prefer +# the above utilities for faster load-and-run results. # real example: (that I answer in StackExchange) # REQ: x := 1001b OR 0110b -# in `tcsh' expression (by using octal) +# in `tcsh` expression (by using octal) @ x = ( 011 | 06 ); echo $x -# the same by using `calc' (and using binary as the original req) +# the same by using `calc` (and using binary as the original req) set x = `calc '0b1001 | 0b110'`; echo $x # --- File Inquiry Operators -------------------------------------------------- -# NOTE: The builtin `filetest' command do the same thing. +# NOTE: The built-in `filetest` command does the same thing. #### Boolean operators # -r read access -w write access -x execute access -e existence @@ -366,23 +366,23 @@ set x = `calc '0b1001 | 0b110'`; echo $x # -b block device -c char device # -t file (digit) is an open file descriptor for a terminal device -# if the file `README' exists, displays a message +# If the file `README` exists, display a message if ( -e README ) echo "I have already README file" -# if the `less' program is installed, use this instead of `more' +# If the `less` program is installed, use it instead of `more` if ( -e `where less` ) then - alias more 'less' + alias more 'less' endif #### Non-boolean operators # -Z returns the file size in bytes # -M returns the modification time (mtime) -M: returns mtime string -# -A returns the lass access time (atime) -A: returns atime string -# -U returns the owners user ID -U: returns the owners user-name -# -G returns the group ID -G: returns the group-name +# -A returns the last access time (atime) -A: returns atime string +# -U returns the owner's user ID -U: returns the owner's user name +# -G returns the owner's group ID -G: returns the owner's group name # -P returns the permissions as octal number -Pmode returns perm. AND mode -# this will display the date as Unix-time integer: 1498511486 +# this will display the date as a Unix-time integer: 1498511486 filetest -M README.md # This will display "Tue Jun 27 00:11:26 2017" @@ -390,14 +390,14 @@ filetest -M: README.md # --- Basic Commands ---------------------------------------------------------- -# Navigate though file system with `chdir' (cd) +# Navigate through the filesystem with `chdir` (cd) cd path # change working directory -cd # change to home directory -cd - # change to previous directory +cd # change to the home directory +cd - # change to the previous directory cd .. # go up one directory # Examples: -cd ~/Downloads # go to my `Downloads' directory +cd ~/Downloads # go to my `Downloads` directory # Use `mkdir` to create new directories. mkdir newdir @@ -413,7 +413,7 @@ where csh # --- Pipe-lines -------------------------------------------------------------- # A pipeline is a sequence of processes chained together by their standard # streams, so that the output of each process (stdout) feeds directly as input -# (stdin) to the next one. This `pipes' are created with the `|' special +# (stdin) to the next one. These `pipes` are created with the `|` special # character and it is one of the most powerful characteristics of Unix. # example: @@ -422,18 +422,18 @@ ls -l | grep key | less # input (stdin) of the process for "grep key"; and likewise for the process # for "less". -# the `ls', the `grep' and the `less' are programs of Unix and they have their -# own man-page. The `pipe' mechanism is part of the kernel but the syntax -# and the control is job of the shell, the tcsh in our case. +# the `ls`, the `grep`, and the `less` are Unix programs and they have their +# own man-page. The `pipe` mechanism is part of the kernel but the syntax +# and the control is the shell's job, the tcsh in our case. -# NOTE: `pipe' mechanism has Windows too, but it is buggy and I sign it for all -# versions until Windows XP SP3 API32 which was the last one that I worked on. -# Microsoft still denied it but is well known bug since it is a common method -# for inter-process communication. For small I/O it will work well. -# tcsh, along with grep, gcc and perl is one of the first Unix programs that +# NOTE: Windows has the `pipe` mechanism too, but it is buggy and I signed it +# for all versions until Windows XP SP3 API32 which was the last one that I +# worked on. Microsoft denied it, but it is a well-known bug since it is a +# common method for inter-process communication. For small I/O it will work well. +# tcsh, along with grep, GCC, and Perl is one of the first Unix programs that # ported to DOS (with EMX DOS extender) and later to Windows (1998). -# example: this will convert tcsh to PostScript and will show it with okular +# example: this will convert tcsh to PostScript and will show it with Okular zcat /usr/man/man1/tcsh.1.gz | groff -Tps -man | okular - # a better version @@ -451,10 +451,10 @@ set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz"); set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz"); zcat `eval $loc` | groff -Tps -man | ps2pdf - ${page}.pdf && okular tcsh.pdf -# NOTE: `okular' is the default application of KDE environment and it shows -# postcript and pdf files. You can replace it with your lovely pdf viewer. -# zcat, locate, groff, are common programs in all Unices. `ps2pdf' program -# is part of `ghostscript' package that is widely used. +# NOTE: `okular` is the default application of the KDE environment and it shows +# postcript and pdf files. You can replace it with your lovely PDF viewer. +# `zcat`, `locate`, `groff`, are common programs in all Unixes. The `ps2pdf` +# program is part of the `ghostscript` package that is widely used. # --- Control Flow ------------------------------------------------------------ @@ -468,8 +468,8 @@ set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz"); # ...] # endif # -# If the specified expr is true then the commands to the first else are -# executed; otherwise if expr2 is true then the commands to the second else +# If the specified `expr` is true then the commands to the first else are +# executed; otherwise if `expr2` is true then the commands to the second else # are executed, etc. # Any number of else-if pairs are possible; only one endif is needed. # @@ -477,24 +477,24 @@ set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz"); # # if ( expr ) command # -# If `expr' evaluates true, then command is executed. -# `command' must be a simple command, not an alias, a pipeline, a command list -# or a parenthesized command list. With few words, avoid to use it. +# If `expr` evaluates to true, then the command is executed. +# `command` must be a simple command, not an alias, a pipeline, a command list +#, or a parenthesized command list. With a few words, avoid using it. # -# BUG: Input/output redirection occurs even if expr is false and command is -# thus not executed. +# BUG: Input/output redirection occurs even if expr is false and the command +# is thus not executed. # -# check if we are in non-interactive shell and quit if true +# check if we are in a non-interactive shell and quit if true if ( $?USER == 0 || $?prompt == 0 ) exit # check if we are a login shell if ( $?loginsh ) then - # check if you are on linux console (not X's terminal) - if ( $tty =~ tty* ) then - # enable keypad application keys (man console_codes) - echo '\033=' - endif + # check if you are on linux console (not X's terminal) + if ( $tty =~ tty* ) then + # enable keypad application keys (man console_codes) + echo '\033=' + endif endif #### SWITCH-ENDSW @@ -509,37 +509,37 @@ endif # # tcsh uses a case statement that works similarly to switch in C. # Each case label is successively matched, against the specified string which -# is first command and filename expanded. The file metacharacters `*', `?' -# and `[...]' may be used in the case labels. If none of the labels match the -# execution begins after the default label if its defined. -# The command `breaksw' causes execution to continue after the endsw. Otherwise +# is first command and filename expanded. The file metacharacters `*`, `?` +# and `[...]` may be used in the case labels. If none of the labels match the +# execution begins after the default label if it's defined. +# The command `breaksw` causes execution to continue after the endsw. Otherwise, # control may fall through case labels and default labels as in C. switch ( $var ) case *.[1-9]: case *.[1-9].gz: - echo "$var is a man-page." - breaksw + echo "$var is a man-page." + breaksw case *gz: - echo "$var is gzipped" - breaksw + echo "$var is gzipped" + breaksw default: - file $var + file $var endsw #### FOREACH-END # Syntax: # foreach name ( wordlist ) -# ... +# ... # [break | continue] # end # -# Successively sets the variable `name' to each member of `wordlist' and +# Successively sets the variable `name` to each member of `wordlist` and # executes the sequence of commands between this command and the matching -# `end' keyword. The `continue' keyword jump to the next element back to -# top; and the `break' keyword terminates the loop. +# `end` keyword. The `continue` keyword jumps to the next element back to +# top, and the `break` keyword terminates the loop. # -# BUG: `foreach' doesn't ignore here documents when looking for its end. +# BUG: `foreach` doesn't ignore here documents when looking for its end. # example: counting 1 to 10 foreach i ( `seq 1 10` ) @@ -548,12 +548,12 @@ end # example: type all files in the list foreach f ( a.txt b.txt c.txt ) - cat $f + cat $f end # example: convert wma to ogg foreach f ( *.wma ) - ffmpeg -i "$f" "$f:r".ogg + ffmpeg -i "$f" "$f:r".ogg end #### WHILE-END @@ -562,22 +562,22 @@ end # [break | continue] # end # -# Executes the commands between the `while' and the matching `end' while `expr' -# evaluates non-zero. `break' and `continue' may be used to terminate or +# Executes the commands between the `while` and the matching `end` while `expr` +# evaluates non-zero. `break` and `continue` may be used to terminate or # continue the loop prematurely. # count from 1 to 10 set num = 1 while ( $num <= 10 ) - echo $num - @ num ++ + echo $num + @ num ++ end # print all directories of CWD set lst = ( * ) while ( $#lst ) - if ( -d $lst[1] ) echo $lst[1] is directory - shift lst + if ( -d $lst[1] ) echo $lst[1] is directory + shift lst end # separate command-line arguments to options or parameters @@ -585,12 +585,12 @@ set options set params set lst = ( $* ) while ( $#lst ) - if ( "$lst[1]" =~ '-*' ) then - set options = ( $options $lst[1] ) - else - set params = ( $params $lst[1] ) - endif - shift lst + if ( "$lst[1]" =~ '-*' ) then + set options = ( $options $lst[1] ) + else + set params = ( $params $lst[1] ) + endif + shift lst end echo 'options =' $options echo 'parameters =' $params @@ -599,16 +599,16 @@ echo 'parameters =' $params # Syntax: repeat count command # # The specified command, which is subject to the same restrictions as the -# command in the one line if statement above, is executed count times. -# I/O redirections occur exactly once, even if count is 0. +# command in the one line `if` statement above, is executed count times. +# I/O redirections occur exactly once, even if `count` is 0. # -# TIP: in most cases prefer `while' +# TIP: in most cases prefer `while` repeat 3 echo "ding dong" # --- Functions --------------------------------------------------------------- # tcsh has no functions but its expression syntax is advanced enough to use -# `alias' as functions. Another method is recursion +# `alias` as functions. Another method is recursion # Alias argument selectors; the ability to define an alias to take arguments # supplied to it and apply them to the commands that it refers to. @@ -637,48 +637,48 @@ alias cd 'cd \!* && ls' #!/bin/tcsh -f set todo = option1 if ( $#argv > 0 ) then - set todo = $argv[1] + set todo = $argv[1] endif switch ( $todo ) case option1: -# ... - $0 results - breaksw +# ... + $0 results + breaksw case option2: -# ... - $0 results - breaksw +# ... + $0 results + breaksw case results: - echo "print the results here" -# ... - breaksw + echo "print the results here" +# ... + breaksw default: - echo "Unknown option: $todo" -# exit 0 + echo "Unknown option: $todo" +# exit 0 endsw # --- Recursion method --- end --- # --- examples ---------------------------------------------------------------- # this script prints available power-states if no argument is set; -# otherwise it set the state of the $argv[1] +# otherwise it sets the state of the $argv[1] # --- power-state script --- begin -------------------------------------------- #!/bin/tcsh -f # get parameter ("help" for none) set todo = help if ( $#argv > 0 ) then - set todo = $argv[1] + set todo = $argv[1] endif # available options set opts = `cat /sys/power/state` # is known? foreach o ( $opts ) - if ( $todo == $o ) then - # found; execute it - echo -n $todo > /sys/power/state - break - endif + if ( $todo == $o ) then + # found; execute it + echo -n $todo > /sys/power/state + break + endif end # print help and exit echo "usage: $0 [option]" @@ -691,19 +691,19 @@ echo "available options on kernel: $opts" set secret=`shuf -i1-100 -n1` echo "I have a secret number from 1 up to 100" while ( 1 ) - echo -n "Guess: " - set guess = $< - if ( $secret == $guess ) then - echo "You found it" - exit 1 - else - if ( $secret > $guess ) then - echo "its greater" - else if ( $secret < $guess ) then - echo "its lesser" - endif - endif - endif + echo -n "Guess: " + set guess = $< + if ( $secret == $guess ) then + echo "You found it" + exit 1 + else + if ( $secret > $guess ) then + echo "its greater" + else if ( $secret < $guess ) then + echo "its lesser" + endif + endif + endif end # --- secretnum.csh --- end --------------------------------------------------- @@ -711,36 +711,36 @@ end # Appendices #### About [T]CSH: -# * CSH is notorious about its bugs; -# * It was also famous about its advanced interactive mode. -# * TCSH is famous that have the most advanced completion subsystem. -# * TCSH is famous that have the most advanced aliases subsystem; aliases -# can take parameters and often used as functions! -# * TCSH is well known that preferred by people (me too) because of better -# syntax. All shells are using Thomson's syntax with exception of [t]csh, -# fish and plan9's shells (rc, ex). -# * It is smaller and consume far less memory than bash, zsh even mksh! +# * CSH is notorious for its bugs; +# * It is also famous for its advanced interactive mode. +# * TCSH is famous for having the most advanced completion subsystem. +# * TCSH is famous for having the most advanced aliases subsystem; aliases +# can take parameters and often be used as functions! +# * TCSH is well known and preferred by people (me too) because of better +# syntax. All shells are using Thomson's syntax with the exception of +# [t]csh, fish, and plan9's shells (rc, ex). +# * It is smaller and consumes far less memory than bash, zsh, and even mksh! # (memusage reports) -# * TCSH still has bugs; less but have; if you write readable clean code you'll -# find none; well almost none... This has to do with the implementation of -# csh; that no means the other shells has good implementation. -# * no one well known shell is capable for regular programming; if your script -# getting big, use a programming language, or at least PHP or Perl (good -# script languages). +# * TCSH still has bugs; fewer, but it does; if you write readable clean code +# you'll find none; well almost none... This has to do with the implementation +# of csh; that doesn't mean the other shells have a good implementation. +# * no well-known shell is capable of regular programming; if your script +# is getting big, use a programming language, like Python, PHP, or Perl (good +# scripting languages). # -# Advises: -# 1. Do not use redirection in single-line if (it is well documented bug) -# In most cases avoid to use single-line IFs. -# 2. Do not mess up with other shells code, c-shell is not compatible with +# Advice: +# 1. Do not use redirection in single-line IFs (it is well documented bug) +# In most cases avoid using single-line IFs. +# 2. Do not mess up with other shells' code, c-shell is not compatible with # other shells and has different abilities and priorities. # 3. Use spaces as you'll use them to write readable code in any language. -# A bug of csh was `set x=1' worked, `set x = 1' worked, `set x =1' did not! -# 4. It is well documented that numeric expressions require spaces in-between; -# also parenthesise all bit-wise and unary operators. -# 5. Do not write a huge weird expression with several quotes, backslashes etc +# A bug of csh was `set x=1` and `set x = 1` worked, but `set x =1` did not! +# 4. It is well documented that numeric expressions require spaces in between; +# also parenthesize all bit-wise and unary operators. +# 5. Do not write a huge weird expression with several quotes, backslashes, etc # It is bad practice for generic programming, it is dangerous in any shell. # 6. Help tcsh, report the bug here <https://bugs.gw.com/> -# 7. Read the man page, `tcsh' has huge number of options, and variables. +# 7. Read the man page, `tcsh` has a huge number of options and variables. # # I suggest the following options enabled by default # -------------------------------------------------- @@ -770,14 +770,14 @@ end # unset time # unset tperiod # -# NOTE: If the `backslash_quote' is set, it may create compatibility issues -# with other tcsh scripts which was written without it. +# NOTE: If the `backslash_quote` is set, it may create compatibility issues +# with other tcsh scripts that were written without it. # -# NOTE: The same for `parseoctal', but it is better to fix the problematic +# NOTE: The same for `parseoctal`, but it is better to fix the problematic # scripts. # # NOTE: **for beginners only** -# This enable automatically rescan `path' directories if need to. (like bash) +# This enables automatic rescanning of `path` directories if needed. (like bash) # set autorehash #### common aliases diff --git a/toml.html.markdown b/toml.html.markdown index 79aa544c..69dfd754 100755..100644 --- a/toml.html.markdown +++ b/toml.html.markdown @@ -69,11 +69,15 @@ The first newline is trimmed in raw strings. ########### ## Integers can start with a +, a - or nothing. -## Leading zeros are not allowed. Hex, octal, and binary forms are not allowed. +## Leading zeros are not allowed. +## Hex, octal, and binary forms are allowed. ## Values that cannot be expressed as a series of digits are not allowed. int1 = +42 int2 = 0 int3 = -21 +int4 = 0xdeadbeef +int5 = 0o755 +int6 = 0b11011100 integerRange = 64 ## You can use underscores to enhance readability. Each diff --git a/tr-tr/git-tr.html.markdown b/tr-tr/git-tr.html.markdown index c6979468..ad2f2e95 100644 --- a/tr-tr/git-tr.html.markdown +++ b/tr-tr/git-tr.html.markdown @@ -591,4 +591,4 @@ $ git rm /pather/to/the/file/HelloWorld.c * [Pro Git](http://www.git-scm.com/book/en/v2) -* [Yeni başlayanlar için Git ve Github](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) +* [Yeni başlayanlar için Git ve GitHub](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) diff --git a/tr-tr/sql-tr.html.markdown b/tr-tr/sql-tr.html.markdown index 54007d32..2e91e9f8 100644 --- a/tr-tr/sql-tr.html.markdown +++ b/tr-tr/sql-tr.html.markdown @@ -1,125 +1,125 @@ ----
-language: SQL
-contributors:
- - ["Metin Yalçınkaya", "https://github.com/mtnylnky"]
-lang: tr-tr
-filename: learnsql-tr.sql
----
-
-
-```sql
--- Yorumlar iki tire ile başlar
-
--- KISITLAR
-Not null -- Bir kolon asla boş olamaz
-default -- Boş olan yerlere varsayılan bir değer atar
-unique -- Bir kolondaki tüm değerlerin farklı olması kısıtlaması
-primary key -- Bir tablodaki her veri için kimlik bilgisi niteliğindedir
-check -- Bir kolondaki değerlerin belli bir kısıtlamayı sağlamasını sağlar
-
--- Tablo oluşturulur
-CREATE TABLE tablo1 ();
-
--- Tabloyu içerisinde kolonlar ile oluşturma
-CREATE TABLE tablo1(id INTEGER PRIMARY KEY NOT NULL UNIQUE, ad TEXT, soyad TEXT, yas INTEGER);
-
--- TABLO varlığını kontrol eder
-.table
-
--- Veri tabanında olan bütün tabloları görüntüler.
-.schema
-
--- Satır ekle
-INSERT INTO tablo1 ( ad, soyad) VALUES ("Deger1","Deger2");
-
--- Veritabanında tablo üzerindeki verileri görüntüle
--- Sadece 'ad' gibi sınırlı bir veri için
-SELECT ad FROM tablo1;
--- Bütün veriler için
-SELECT * FROM tablo1;
-
--- Veri güncelleme
-UPDATE tablo1 SET ad = "deger1-2"; WHERE name = "Deger1";
-
--- Satır sil
-DELETE FROM tablo1 WHERE id = 1;
-DELETE FROM tablo1 WHERE ad = "Deger1" OR ad = "Deger2";
-
--- Tabloya sonradan kolon ekleme
-ALTER TABLE tablo1 ADD COLUMN email TEXT;
-
--- Tablodaki kolon adı değiştirme
-EXEC sp_rename ' tablo1.[ad]', Ad, 'COLUMN';
-
--- Tablo adı değiştirme
-ALTER TABLE table1 RENAME TO Table1;
-
--- Tabloyu silme
-DROP TABLE Table1;
-
--- BİR TABLOYU BAŞKA TABLO KULLANARAK DOLDURMAK
-INSERT INTO Tablo2 SELECT id,ad, soyad, email from Tablo1;
-
--- LIKE KOMUTU
--- Belirli bir kritere göre arama yaparken kullanılır
--- Adı 'A' ile başlayan veriler
-SELECT * FROM tablo1 WHERE adi LIKE "A%";
--- İçinde 'A' olan veriler
-SELECT * FROM tablo1 WHERE adi LIKE "%A%";
-
--- LIMIT KOMUTU
--- Gösterilen satır sayısını sınırlamak için
-SELECT * FROM Tablo1 LIMIT 6;
--- Gösterilen satırları belirli bir noktadan başlamak üzere sınırlamak için
-SELECT * FROM Tablo1 LIMIT 6 OFFSET 3;
-
--- ORDER BY KOMUTU
--- Herhangi bir kolona göre gösterilen değerleri azalan veya artan şekilde sıralamak için
-SELECT kolon FROM tablo1 WHERE yas ORDER BY column1, column2, .. columnN] [ASC | DESC];
-SELECT * FROM Tablo1 ORDER BY yas ASC
-SELECT * FROM Tablo1 ORDER BY yas DESC
-
--- DISTINCT ANAHTAR SÖZCÜĞÜ
--- Bu anahtar sözcükle sadece farklı değerler gösterilir.
-SELECT DISTINCT yas FROM tablo1;
-
--- JOIN KOMUTU
--- CROSS JOIN
--- Cross join bir tablodaki her satırı ikinci tablodaki bir satır ile eşleştirmek için kulanılır.
--- Eğer birinci tabloda x satır ikinci tabloda y satır varsa sonuçta x*y satır olur.
-SELECT ... FROM table1 CROSS JOIN table2 …
-SELECT ad, yas FROM Tablo1 CROSS JOIN Tablo2;
-
--- INNER JOIN
--- Inner join iki tablodaki ortak kolon değerlerini kullanarak bir sonuç üretir.
-SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression …
-SELECT ad, yas FROM Tablo1 INNER JOIN Tablo2 ON Tablo1.ad = Tablo2.soyad;
-
--- OUTER JOIN
--- Outer join iki tablodaki ortak kolon değerlerinin dışında kalanları kullanarak bir sonuç üretir.
-SELECT isci_num, isim, dept FROM Tablo1 LEFT OUTER JOIN Tablo2 ON Tablo1.id = Tablo2.isci_num;
-
--- ÇEKİRDEK FONKSİYONLAR
-COUNT -- Sayma
-AVG -- Ortalama
-ABS -- Mutlak değer
-SUM -- Toplam
-RANDOM -- Rastgele
-ROUND -- Yuvarlama
-MAX -- Maksimim
-MIN -- Minimum
-UPPER -- Büyük Harf
-LOWER -- Küçük Harf
-LENGTH -- Uzunluk
-CURRENT_TIMESTAMP -- Zaman
-
-SELECT max(yas) FROM Table1;
-SELECT min(yas) FROM Table1;
-SELECT avg(yas) FROM Table1;
-SELECT * From Table1 WHERE yas ==18;
-SELECT sum(yas) FROM Table1;
-SELECT random() AS Random;
-SELECT upper(ad) FROM Table1;
-SELECT lower(ad) FROM Table1;
-SELECT ad, length(ad) FROM Table1;
+--- +language: SQL +contributors: + - ["Metin Yalçınkaya", "https://github.com/mtnylnky"] +lang: tr-tr +filename: learnsql-tr.sql +--- + + +```sql +-- Yorumlar iki tire ile başlar + +-- KISITLAR +Not null -- Bir kolon asla boş olamaz +default -- Boş olan yerlere varsayılan bir değer atar +unique -- Bir kolondaki tüm değerlerin farklı olması kısıtlaması +primary key -- Bir tablodaki her veri için kimlik bilgisi niteliğindedir +check -- Bir kolondaki değerlerin belli bir kısıtlamayı sağlamasını sağlar + +-- Tablo oluşturulur +CREATE TABLE tablo1 (); + +-- Tabloyu içerisinde kolonlar ile oluşturma +CREATE TABLE tablo1(id INTEGER PRIMARY KEY NOT NULL UNIQUE, ad TEXT, soyad TEXT, yas INTEGER); + +-- TABLO varlığını kontrol eder +.table + +-- Veri tabanında olan bütün tabloları görüntüler. +.schema + +-- Satır ekle +INSERT INTO tablo1 ( ad, soyad) VALUES ("Deger1","Deger2"); + +-- Veritabanında tablo üzerindeki verileri görüntüle +-- Sadece 'ad' gibi sınırlı bir veri için +SELECT ad FROM tablo1; +-- Bütün veriler için +SELECT * FROM tablo1; + +-- Veri güncelleme +UPDATE tablo1 SET ad = "deger1-2"; WHERE name = "Deger1"; + +-- Satır sil +DELETE FROM tablo1 WHERE id = 1; +DELETE FROM tablo1 WHERE ad = "Deger1" OR ad = "Deger2"; + +-- Tabloya sonradan kolon ekleme +ALTER TABLE tablo1 ADD COLUMN email TEXT; + +-- Tablodaki kolon adı değiştirme +EXEC sp_rename ' tablo1.[ad]', Ad, 'COLUMN'; + +-- Tablo adı değiştirme +ALTER TABLE table1 RENAME TO Table1; + +-- Tabloyu silme +DROP TABLE Table1; + +-- BİR TABLOYU BAŞKA TABLO KULLANARAK DOLDURMAK +INSERT INTO Tablo2 SELECT id,ad, soyad, email from Tablo1; + +-- LIKE KOMUTU +-- Belirli bir kritere göre arama yaparken kullanılır +-- Adı 'A' ile başlayan veriler +SELECT * FROM tablo1 WHERE adi LIKE "A%"; +-- İçinde 'A' olan veriler +SELECT * FROM tablo1 WHERE adi LIKE "%A%"; + +-- LIMIT KOMUTU +-- Gösterilen satır sayısını sınırlamak için +SELECT * FROM Tablo1 LIMIT 6; +-- Gösterilen satırları belirli bir noktadan başlamak üzere sınırlamak için +SELECT * FROM Tablo1 LIMIT 6 OFFSET 3; + +-- ORDER BY KOMUTU +-- Herhangi bir kolona göre gösterilen değerleri azalan veya artan şekilde sıralamak için +SELECT kolon FROM tablo1 WHERE yas ORDER BY column1, column2, .. columnN] [ASC | DESC]; +SELECT * FROM Tablo1 ORDER BY yas ASC +SELECT * FROM Tablo1 ORDER BY yas DESC + +-- DISTINCT ANAHTAR SÖZCÜĞÜ +-- Bu anahtar sözcükle sadece farklı değerler gösterilir. +SELECT DISTINCT yas FROM tablo1; + +-- JOIN KOMUTU +-- CROSS JOIN +-- Cross join bir tablodaki her satırı ikinci tablodaki bir satır ile eşleştirmek için kulanılır. +-- Eğer birinci tabloda x satır ikinci tabloda y satır varsa sonuçta x*y satır olur. +SELECT ... FROM table1 CROSS JOIN table2 … +SELECT ad, yas FROM Tablo1 CROSS JOIN Tablo2; + +-- INNER JOIN +-- Inner join iki tablodaki ortak kolon değerlerini kullanarak bir sonuç üretir. +SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression … +SELECT ad, yas FROM Tablo1 INNER JOIN Tablo2 ON Tablo1.ad = Tablo2.soyad; + +-- OUTER JOIN +-- Outer join iki tablodaki ortak kolon değerlerinin dışında kalanları kullanarak bir sonuç üretir. +SELECT isci_num, isim, dept FROM Tablo1 LEFT OUTER JOIN Tablo2 ON Tablo1.id = Tablo2.isci_num; + +-- ÇEKİRDEK FONKSİYONLAR +COUNT -- Sayma +AVG -- Ortalama +ABS -- Mutlak değer +SUM -- Toplam +RANDOM -- Rastgele +ROUND -- Yuvarlama +MAX -- Maksimim +MIN -- Minimum +UPPER -- Büyük Harf +LOWER -- Küçük Harf +LENGTH -- Uzunluk +CURRENT_TIMESTAMP -- Zaman + +SELECT max(yas) FROM Table1; +SELECT min(yas) FROM Table1; +SELECT avg(yas) FROM Table1; +SELECT * From Table1 WHERE yas ==18; +SELECT sum(yas) FROM Table1; +SELECT random() AS Random; +SELECT upper(ad) FROM Table1; +SELECT lower(ad) FROM Table1; +SELECT ad, length(ad) FROM Table1; ```
\ No newline at end of file diff --git a/uk-ua/bash-ua.html.markdown b/uk-ua/bash-ua.html.markdown index c6e9ebb1..9375d5f3 100644 --- a/uk-ua/bash-ua.html.markdown +++ b/uk-ua/bash-ua.html.markdown @@ -19,7 +19,7 @@ lang: uk-ua Bash - командна оболонка unix (unix shell), що також розповсюджувалась як оболонка для операційної системи GNU і зараз використовується як командна оболонка за замовчуванням -для Linux i Max OS X. +для Linux i Mac OS X. Майже всі приклади, що наведені нижче можуть бути частиною shell-скриптів або виконані в оболонці @@ -52,9 +52,9 @@ VARIABLE= 'Просто рядок' # виконання команди 'Просто рядок') # Використання змінних: -echo $VARIABLE -echo "$VARIABLE" -echo '$VARIABLE' +echo $VARIABLE # Просто рядок +echo "$VARIABLE" # Просто рядок +echo '$VARIABLE' # $VARIABLE # Коли ви використовуєте змінну - присвоюєте значення, експортуєте і т.д. - # пишіть її імя без $. А для отримання значення змінної використовуйте $. # Одинарні лапки ' не розкривають значення змінних @@ -96,12 +96,12 @@ else echo "Ім’я збігаєтьяс з іменем користувача" fi -# Зауважте! якщо $Name пуста, bash інтерпретує код вище як: +# Зауважте! якщо $NAME пуста, bash інтерпретує код вище як: if [ -ne $USER ] # що є неправильним синтаксисом # тому безпечний спосіб використання потенційно пустих змінних має вигляд: -if [ "$Name" -ne $USER ] ... -# коли $Name пуста, інтерпретується наступним чином: +if [ "$NAME" -ne $USER ] ... +# коли $NAME пуста, інтерпретується наступним чином: if [ "" -ne $USER ] ... # що працює як і очікувалося @@ -205,7 +205,7 @@ do echo $a done -# Цикл for можно використати, щоб виконувати дії над файлами. +# Цикл for можна використати, щоб виконувати дії над файлами. # Цей код запустить команду 'cat' для файлів file1 и file2 for VARIABLE in file1 file2 do @@ -259,12 +259,12 @@ uniq -d file.txt cut -d ',' -f 1 file.txt # замінити кожне 'okay' на 'great' у файлі file.txt (підтримується regex) sed -i 's/okay/great/g' file.txt -# вивести в stdout всі рядки з file.txt, що задовольняють шаблону regex; +# вивести в stdout всі рядки з file.txt, що відповідають шаблону regex; # цей приклад виводить рядки, що починаються на foo і закінчуються на bar: grep "^foo.*bar$" file.txt # використайте опцію -c, щоб вивести кількість входжень grep -c "^foo.*bar$" file.txt -# щоб здійснити пошук по рядку, а не по шаблону regex, використовуйте fgrea (або grep -F) +# щоб здійснити пошук по рядку, а не по шаблону regex, використовуйте fgrep (або grep -F) fgrep "^foo.*bar$" file.txt # Читайте вбудовану документацію Bash командою 'help': diff --git a/uk-ua/go-ua.html.markdown b/uk-ua/go-ua.html.markdown index f980f7b1..6f294b1f 100644 --- a/uk-ua/go-ua.html.markdown +++ b/uk-ua/go-ua.html.markdown @@ -434,15 +434,15 @@ func requestServer() { ## Подальше вивчення -Основним джерелом всієї інформації про Go залишається [офіційна веб-сторінка](http://golang.org/). Там можна знайти уроки, інтерактивно пограти та багато про що почитати. -Окрім туру, у [документації](https://golang.org/doc/) міститься інформація як писати чистий та ефективний код на Go, документація пакетів та окремих команд, а також історія релізів. +Основним джерелом всієї інформації про Go залишається [офіційна веб-сторінка](https://go.dev/). Там можна знайти уроки, інтерактивно пограти та багато про що почитати. +Окрім туру, у [документації](https://go.dev/doc/) міститься інформація як писати чистий та ефективний код на Go, документація пакетів та окремих команд, а також історія релізів. Надзвичайно рекомендується ознайомитись із визначенням мови. Вона легко читається та на диво коротка (в порівнянні з іншими сучасними мовами). -Можна погратись з кодом вище на [Go playground](https://play.golang.org/p/tnWMjr16Mm). Спробуй змінити його та запустити із свого браузера. Поміть, що можна використовувати [https://play.golang.org](https://play.golang.org) як [REPL](https://uk.wikipedia.org/wiki/REPL) до тестів та коду в твоєму браузері, без встановлення Go. +Можна погратись з кодом вище на [Go playground](https://go.dev/play/p/tnWMjr16Mm). Спробуй змінити його та запустити із свого браузера. Поміть, що можна використовувати [https://go.dev/play/](https://go.dev/play/) як [REPL](https://uk.wikipedia.org/wiki/REPL) до тестів та коду в твоєму браузері, без встановлення Go. -В списку для прочитання новачкам в Go - [вихідний код стандартної бібліотеки](http://golang.org/src/pkg/). Код всеосяжно задокоментований, тому є найкращим прикладом з боку зручного для прочитання та швидкості розуміння коду на цій мові програмування. Приведений стиль та ідіоми Go. -Крім того, можна просто натиснути на назву функції в [документації](http://golang.org/pkg/), щоб перейти до її реалізації. +В списку для прочитання новачкам в Go - [вихідний код стандартної бібліотеки](https://go.dev/src/). Код всеосяжно задокоментований, тому є найкращим прикладом з боку зручного для прочитання та швидкості розуміння коду на цій мові програмування. Приведений стиль та ідіоми Go. +Крім того, можна просто натиснути на назву функції в [документації](https://go.dev/pkg/), щоб перейти до її реалізації. Іншим прекрасним посиланням для вивчення Go є [Go by example](https://gobyexample.com/). diff --git a/v.html.markdown b/v.html.markdown new file mode 100644 index 00000000..4f698184 --- /dev/null +++ b/v.html.markdown @@ -0,0 +1,229 @@ +--- +language: v +filename: vlang.v +contributors: + - ["Maou Shimazu", "https://github.com/Maou-Shimazu"] +--- + +V is a statically typed compiled programming language +designed for building maintainable software. + +It's similar to Go and its design has also been influenced by +Oberon, Rust, Swift, Kotlin, and Python. + +The language promotes writing +simple and clear code with minimal abstraction. + +Despite being simple, V gives the developer a lot of power. +Anything you can do in other languages, you can do in V. + +```v +// Single Line Comment. +/* + Multi Line Comment +*/ + +struct User { // Cannot be defined in main, explained later. + age int + name string + pos int = -1 // custom default value +} +// struct method +fn (u User) can_register() bool { + return u.age > 16 +} + +struct Parser { + token Token +} + +// c like enums +enum Token { + plus + minus + div + mult +} + +// 1. functions +// language does not use semi colons +fn add(x int, y int) int { + return x + y +} +// can return multiple values +fn foo() (int, int) { + return 2, 3 +} + +// function visibility +pub fn public_function() { // pub can only be used from a named module. +} + +fn private_function() { +} + + + +// Main function +fn main() { + // Anonymous functions can be declared inside other functions: + double_fn := fn (n int) int { + return n + n + } + // 2. Variables: they are immutable by default + // implicitly typed + x := 1 + // x = 2 // error + mut y := 2 + y = 4 + name := "John" + large_number := i64(9999999999999) + println("$x, $y, $name, $large_number") // 1, 4, John, 9999999999999 + + // unpacking values from functions. + a, b := foo() + println("$a, $b") // 2, 3 + c, _ := foo() // ignore values using `_` + println("$c") // 2 + + // Numbers + u := u16(12) + v := 13 + u // v is of type `u16` + r := f32(45.6) + q := r + 3.14 // x is of type `f32` + s := 75 // a is of type `int` + l := 14.7 // b is of type `f64` + e := u + s // c is of type `int` + d := l + r // d is of type `f64` + + // Strings + mut bob := 'Bob' + assert bob[0] == u8(66) // indexing gives a byte, u8(66) == `B` + assert bob[1..3] == 'ob' // slicing gives a string 'ob' + bobby := bob + 'by' // + is used to concatenate strings + println(bobby) // "Bobby" + bob += "by2" // += is used to append to strings + println(bob) // "Bobby2" + + //String values are immutable. You cannot mutate elements: + //mut s := 'hello 🌎' + //s[0] = `H` // not allowed + + //For raw strings, prepend r. Escape handling is not done for raw strings: + rstring := r'hello\nworld' // the `\n` will be preserved as two characters + println(rstring) // "hello\nworld" + + // string interpolation + println('Hello, $bob!') // Hello, Bob! + println('Bob length + 10: ${bob.len + 10}!') // Bob length + 10: 13! + + // 3. Arrays + mut numbers := [1, 2, 3] + println(numbers) // `[1, 2, 3]` + numbers << 4 // append elements with << + println(numbers[3]) // `4` + numbers[1] = 5 + println(numbers) // `[1, 5, 3]` + // numbers << "John" // error: `numbers` is an array of numbers + numbers = [] // array is now empty + arr := []int{len: 5, init: -1} + // `arr == [-1, -1, -1, -1, -1]`, arr.cap == 5 + + number_slices := [0, 10, 20, 30, 40] + println(number_slices[1..4]) // [10, 20, 30] + println(number_slices[..4]) // [0, 10, 20, 30] + println(number_slices[1..]) // [10, 20, 30, 40] + + // 4. structs and enums + // struct User { + // age int + // name string + // pos int = -1 // custom default value + // } + mut users := User{21, 'Bob', 0} + println(users.age) // 21 + + // enum Token { + // plus + // minus + // div + // mult + // } + + // struct Parser { + // token Token + // } + parser := Parser{} + if parser.token == .plus || parser.token == .minus + || parser.token == .div || parser.token == .mult { + // ... + } + + + // 5. Maps + number_map := { + 'one': 1 + 'two': 2 + } + println(number_map) // {'one': 1, 'two': 2} + println(number_map["one"]) // 1 + mut m := map[string]int{} // a map with `string` keys and `int` values + m['one'] = 1 + m['two'] = 2 + println(m['one']) // "1" + println(m['bad_key']) // "0" + m.delete('two') + + // 6. Conditionals + a_number := 10 + b_number := 20 + if a_number < b { + println('$a_number < $b_number') + } else if a_number > b { + println('$a_number > $b_number') + } else { + println('$a_number == $b_number') + } + num := 777 + even_odd := if num % 2 == 0 { 'even' } else { 'odd' } + println(even_odd) + + match even_odd { + 'even' { println('even') } + 'odd' { println('odd') } + else { println('unknown') } + } + + // 7. Loops + loops := [1, 2, 3, 4, 5] + for lp in loops { + println(lp) + } + loop_names := ['Sam', 'Peter'] + for i, lname in loop_names { + println('$i) $lname') + // Output: 0) Sam + // 1) Peter + } + // You can also use break and continue followed by a + // label name to refer to an outer for loop: + outer: for i := 4; true; i++ { + println(i) + for { + if i < 7 { + continue outer + } else { + break outer + } + } + } +} + +``` +## Further reading + +There are more complex concepts to be learnt in V which are available at the +official [V documentation](https://github.com/vlang/v/blob/master/doc/docs.md). + +You can also find more information about the V language at the [official website](https://vlang.io/) +or check it out at the [v playground](https://v-wasm.vercel.app/).
\ No newline at end of file diff --git a/vala.html.markdown b/vala.html.markdown index 739e0fda..739e0fda 100755..100644 --- a/vala.html.markdown +++ b/vala.html.markdown diff --git a/vi-vn/git-vi.html.markdown b/vi-vn/git-vi.html.markdown index f5454ebf..47485bd9 100644 --- a/vi-vn/git-vi.html.markdown +++ b/vi-vn/git-vi.html.markdown @@ -1,328 +1,328 @@ ----
-category: tool
-tool: git
-contributors:
+--- +category: tool +tool: git +contributors: - ["Jake Prather", "http://github.com/JakeHP"] - - ["Vinh Nguyen", "https://twitter.com/vinhnx"]
-filename: LearnGit-vi.txt
-lang: vi-vn
----
-
-Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system).
-
-Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, và nó hoạt động
-với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và
-quản lý mã nguồn của bạn.
-
-## Khái Niệm Versioning
-
-### Version Control là gì?
-
-Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian.
-
-### So sánh giữa Centralized Versioning và Distributed Versioning
-
-* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin.
-* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất.
-* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git.
-
-[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
-
-### Tại Sao Dùng Git?
-
-* Có thể hoạt động offline.
-* Cộng tác với nhau rất dễ dàng!
-* Phân nhánh dễ dàng!
-* Trộn (Merging)
-* Git nhanh.
-* Git linh hoạt.
-
-## Kiến Trúc Git
-
-
-### Repository
-
-Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn,
-với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác.
-
-Một git repository bao gồm thư mục .git & tree đang làm việc.
-
-### Thư mục .git (thành phần của một repository)
-
-Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa.
-[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
-
-### Tree Đang Làm (thành phần của một repository)
-
-Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu
-thư mục đang làm việc của bạn
-
-### Chỉ mục (thành phần của một thư mục .git)
-
-Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn
-từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git
-repository.
-
-### Commit
-
-Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn.
-Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong
-một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không!
-
-### Nhánh
-
-Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit,
-con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất.
-
-### HEAD và head (thành phần của thư mục .git)
-
-HEAD là một con trỏ đến branch hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
-head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head.
-
-### Các Tài Nguyên Mang Tính Khái Niệm
-
-* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
-* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
-
-
-## Các Lệnh
-
-
-### init
-
-Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git
-được lưu ở một thư mục tên là ".git".
-
-```bash
-$ git init
-```
-
-### config
-
-Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh
-toàn cục (global)
-
-
-
-```bash
-# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global)
-$ git config --global user.email
-$ git config --global user.name
-
-$ git config --global user.email "MyEmail@Zoho.com"
-$ git config --global user.name "My Name"
-```
-
-[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config)
-
-### help
-
-Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để
-nhắc bạn một số cú pháp.
-
-```bash
-# Xem nhanh các lệnh có sẵn
-$ git help
-
-# Xem tất các các lệnh
-$ git help -a
-
-# Lệnh help riêng biệt - tài liệu người dùng
-# git help <command_here>
-$ git help add
-$ git help commit
-$ git help init
-```
-
-### status
-
-Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit
-hiện tại.
-
-
-```bash
-# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác
-$ git status
-
-# Để xem các "tid bits" về git status
-$ git help status
-```
-
-### add
-
-Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến
-tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit!
-
-```bash
-# thêm một file vào thư mục hiện tại
-$ git add HelloWorld.java
-
-# thêm một file vào một thư mục khác
-$ git add /path/to/file/HelloWorld.c
-
-# Hỗ trợ Regular Expression!
-$ git add ./*.java
-```
-
-### branch
-
-Quản lý nhánh (branch). Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
-
-```bash
-# liệt kê các branch đang có và ở remote
-$ git branch -a
-
-# tạo branch mới
-$ git branch myNewBranch
-
-# xóa một branch
-$ git branch -d myBranch
-
-# đặt tên lại một branch
-# git branch -m <oldname> <newname>
-$ git branch -m myBranchName myNewBranchName
-
-# chỉnh sửa diễn giải của một branch
-$ git branch myBranchName --edit-description
-```
-
-### checkout
-
-Cập nhật tất cả các file trong tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
-
-```bash
-# Checkout (chuyển) một repo - mặc định là nhánh master
-$ git checkout
-# Checkout một nhánh cụ thể
-$ git checkout branchName
-# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>"
-$ git checkout -b newBranch
-```
-
-### clone
-
-Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm
-các branch có remote-tracking cho mỗi branch trong một repo được nhân bản, mà
-cho phép bạn push đến một remote branch.
-
-```bash
-# Nhân bản learnxinyminutes-docs
-$ git clone https://github.com/adambard/learnxinyminutes-docs.git
-```
-
-### commit
-
-Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một ghi chú tạo ra bởi người dùng.
-
-```bash
-# commit với một ghi chú
-$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
-```
-
-### diff
-
-Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits.
-
-```bash
-# Hiển thị sự khác biệt giữa thư mục hiện tại và index
-$ git diff
-
-# Hiển thị khác biệt giữa index và commit mới nhất.
-$ git diff --cached
-
-# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất
-$ git diff HEAD
-```
-
-### grep
-
-Cho phép bạn tìm kiếm nhanh một repo.
-
-Các tinh chỉnh tùy chọn:
-
-```bash
-# Cảm ơn Travis Jeffery vì những lệnh này
-# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep
-$ git config --global grep.lineNumber true
-
-# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm
-$ git config --global alias.g "grep --break --heading --line-number"
-```
-
-```bash
-# Tìm "variableName" trong tất cả các file Java
-$ git grep 'variableName' -- '*.java'
-
-# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove"
-$ git grep -e 'arrayListName' --and \( -e add -e remove \)
-```
-
-Google để xem thêm các ví dụ
-[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
-
-### log
-
-Hiển thị các commit đến repo.
-
-```bash
-# Hiện tất cả các commit
-$ git log
-
-# Hiện X commit
-$ git log -n 10
-
-# Chỉ hiện các commit đã merge merge commits
-$ git log --merges
-```
-
-### merge
-
-"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại.
-
-```bash
-# Merge branch cụ thể vào branch hiện tại.
-$ git merge branchName
-
-# Luôn khởi tạo một merge commit khi trộn (merge)
-$ git merge --no-ff branchName
-```
-
-### mv
-
-Đặt lại tên hoặc di chuyển một file
-
-```bash
-# Đặt lại tên một file
-$ git mv HelloWorld.c HelloNewWorld.c
-
-# Di chuyển một file
-$ git mv HelloWorld.c ./new/path/HelloWorld.c
-
-# Buộc đặt lại tên hoặc di chuyển
-# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè
-$ git mv -f myFile existingFile
-```
-
-### pull
-
-Pull về từ một repo và merge nó vào branch khác.
-
-```bash
-# Cập nhật repo local của bạn, bằng cách merge các thay đổi mới
-# từ remote "origin" và nhánh "master".
-# git pull <remote> <branch>
-# git pull => hoàn toàn mặc định như => git pull origin master
-$ git pull origin master
-
-# Merge các thay đổi từ remote branch và rebase
-# các commit trong branch lên trên local repo, như sau: "git pull <remote> <branch>, git rebase <branch>"
-$ git pull origin master --rebase
-```
-
-### push
-
-push và merge các thay đổi từ một branch đến một remote & branch.
-
+ - ["Vinh Nguyen", "https://twitter.com/vinhnx"] +filename: LearnGit-vi.txt +lang: vi-vn +--- + +Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system). + +Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, và nó hoạt động +với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và +quản lý mã nguồn của bạn. + +## Khái Niệm Versioning + +### Version Control là gì? + +Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian. + +### So sánh giữa Centralized Versioning và Distributed Versioning + +* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin. +* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất. +* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git. + +[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control) + +### Tại Sao Dùng Git? + +* Có thể hoạt động offline. +* Cộng tác với nhau rất dễ dàng! +* Phân nhánh dễ dàng! +* Trộn (Merging) +* Git nhanh. +* Git linh hoạt. + +## Kiến Trúc Git + + +### Repository + +Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn, +với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác. + +Một git repository bao gồm thư mục .git & tree đang làm việc. + +### Thư mục .git (thành phần của một repository) + +Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa. +[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) + +### Tree Đang Làm (thành phần của một repository) + +Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu +thư mục đang làm việc của bạn + +### Chỉ mục (thành phần của một thư mục .git) + +Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn +từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git +repository. + +### Commit + +Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn. +Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong +một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không! + +### Nhánh + +Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit, +con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất. + +### HEAD và head (thành phần của thư mục .git) + +HEAD là một con trỏ đến branch hiện tại. Một repo chỉ có một HEAD *đang hoạt động*. +head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head. + +### Các Tài Nguyên Mang Tính Khái Niệm + +* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) +* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html) + + +## Các Lệnh + + +### init + +Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git +được lưu ở một thư mục tên là ".git". + +```bash +$ git init +``` + +### config + +Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh +toàn cục (global) + + + +```bash +# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global) +$ git config --global user.email +$ git config --global user.name + +$ git config --global user.email "MyEmail@Zoho.com" +$ git config --global user.name "My Name" +``` + +[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config) + +### help + +Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để +nhắc bạn một số cú pháp. + +```bash +# Xem nhanh các lệnh có sẵn +$ git help + +# Xem tất các các lệnh +$ git help -a + +# Lệnh help riêng biệt - tài liệu người dùng +# git help <command_here> +$ git help add +$ git help commit +$ git help init +``` + +### status + +Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit +hiện tại. + + +```bash +# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác +$ git status + +# Để xem các "tid bits" về git status +$ git help status +``` + +### add + +Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến +tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit! + +```bash +# thêm một file vào thư mục hiện tại +$ git add HelloWorld.java + +# thêm một file vào một thư mục khác +$ git add /path/to/file/HelloWorld.c + +# Hỗ trợ Regular Expression! +$ git add ./*.java +``` + +### branch + +Quản lý nhánh (branch). Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này. + +```bash +# liệt kê các branch đang có và ở remote +$ git branch -a + +# tạo branch mới +$ git branch myNewBranch + +# xóa một branch +$ git branch -d myBranch + +# đặt tên lại một branch +# git branch -m <oldname> <newname> +$ git branch -m myBranchName myNewBranchName + +# chỉnh sửa diễn giải của một branch +$ git branch myBranchName --edit-description +``` + +### checkout + +Cập nhật tất cả các file trong tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể. + +```bash +# Checkout (chuyển) một repo - mặc định là nhánh master +$ git checkout +# Checkout một nhánh cụ thể +$ git checkout branchName +# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>" +$ git checkout -b newBranch +``` + +### clone + +Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm +các branch có remote-tracking cho mỗi branch trong một repo được nhân bản, mà +cho phép bạn push đến một remote branch. + +```bash +# Nhân bản learnxinyminutes-docs +$ git clone https://github.com/adambard/learnxinyminutes-docs.git +``` + +### commit + +Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một ghi chú tạo ra bởi người dùng. + +```bash +# commit với một ghi chú +$ git commit -m "Added multiplyNumbers() function to HelloWorld.c" +``` + +### diff + +Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits. + +```bash +# Hiển thị sự khác biệt giữa thư mục hiện tại và index +$ git diff + +# Hiển thị khác biệt giữa index và commit mới nhất. +$ git diff --cached + +# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất +$ git diff HEAD +``` + +### grep + +Cho phép bạn tìm kiếm nhanh một repo. + +Các tinh chỉnh tùy chọn: + +```bash +# Cảm ơn Travis Jeffery vì những lệnh này +# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep +$ git config --global grep.lineNumber true + +# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm +$ git config --global alias.g "grep --break --heading --line-number" +``` + +```bash +# Tìm "variableName" trong tất cả các file Java +$ git grep 'variableName' -- '*.java' + +# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove" +$ git grep -e 'arrayListName' --and \( -e add -e remove \) +``` + +Google để xem thêm các ví dụ +[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) + +### log + +Hiển thị các commit đến repo. + +```bash +# Hiện tất cả các commit +$ git log + +# Hiện X commit +$ git log -n 10 + +# Chỉ hiện các commit đã merge merge commits +$ git log --merges +``` + +### merge + +"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại. + +```bash +# Merge branch cụ thể vào branch hiện tại. +$ git merge branchName + +# Luôn khởi tạo một merge commit khi trộn (merge) +$ git merge --no-ff branchName +``` + +### mv + +Đặt lại tên hoặc di chuyển một file + +```bash +# Đặt lại tên một file +$ git mv HelloWorld.c HelloNewWorld.c + +# Di chuyển một file +$ git mv HelloWorld.c ./new/path/HelloWorld.c + +# Buộc đặt lại tên hoặc di chuyển +# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè +$ git mv -f myFile existingFile +``` + +### pull + +Pull về từ một repo và merge nó vào branch khác. + +```bash +# Cập nhật repo local của bạn, bằng cách merge các thay đổi mới +# từ remote "origin" và nhánh "master". +# git pull <remote> <branch> +# git pull => hoàn toàn mặc định như => git pull origin master +$ git pull origin master + +# Merge các thay đổi từ remote branch và rebase +# các commit trong branch lên trên local repo, như sau: "git pull <remote> <branch>, git rebase <branch>" +$ git pull origin master --rebase +``` + +### push + +push và merge các thay đổi từ một branch đến một remote & branch. + ```bash # Push và merge các thay đổi từ một repo local đến một # remote có tên là "origin" và nhánh "master". @@ -334,68 +334,68 @@ $ git push origin master $ git push -u origin master # Từ lúc này, bất cứ khi nào bạn muốn push từ cùng một nhánh local đó, sử dụng lối tắt: $ git push -```
-
-### rebase (thận trọng)
-
-Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác.
-*Không rebase các commit mà bạn đã push đến một repo công khai*.
-
-```bash
-# Rebase experimentBranch lên master
-# git rebase <basebranch> <topicbranch>
-$ git rebase master experimentBranch
-```
-
-[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing)
-
-### reset (thận trọng)
-
-Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges,
-pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không
-biết mình đang làm gì.
-
-```bash
-# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi)
-$ git reset
-
-# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại
-$ git reset --hard
-
-# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi)
-# tất cả thay đổi vẫn duy trì trong thư mục.
-$ git reset 31f2bb1
-
-# Di chuyển nhánh hiện tại lùi về một commit cụ thể
-# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit
-# sau một commit cụ thể).
-$ git reset --hard 31f2bb1
-```
-
-### rm
-
-Ngược lại với git add, git rm xóa file từ tree đang làm việc.
-
-```bash
-# xóa HelloWorld.c
-$ git rm HelloWorld.c
-
-# Xóa file từ thư mục khác
-$ git rm /pather/to/the/file/HelloWorld.c
-```
-
-## Thông tin thêm
-
-* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
-
-* [git-scm - Video Tutorials](http://git-scm.com/videos)
-
-* [git-scm - Documentation](http://git-scm.com/docs)
-
-* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
-
-* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
-
+``` + +### rebase (thận trọng) + +Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác. +*Không rebase các commit mà bạn đã push đến một repo công khai*. + +```bash +# Rebase experimentBranch lên master +# git rebase <basebranch> <topicbranch> +$ git rebase master experimentBranch +``` + +[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing) + +### reset (thận trọng) + +Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges, +pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không +biết mình đang làm gì. + +```bash +# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi) +$ git reset + +# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại +$ git reset --hard + +# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi) +# tất cả thay đổi vẫn duy trì trong thư mục. +$ git reset 31f2bb1 + +# Di chuyển nhánh hiện tại lùi về một commit cụ thể +# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit +# sau một commit cụ thể). +$ git reset --hard 31f2bb1 +``` + +### rm + +Ngược lại với git add, git rm xóa file từ tree đang làm việc. + +```bash +# xóa HelloWorld.c +$ git rm HelloWorld.c + +# Xóa file từ thư mục khác +$ git rm /pather/to/the/file/HelloWorld.c +``` + +## Thông tin thêm + +* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1) + +* [git-scm - Video Tutorials](http://git-scm.com/videos) + +* [git-scm - Documentation](http://git-scm.com/docs) + +* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/) + +* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) + * [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html) -
+ diff --git a/vi-vn/markdown-vi.html.markdown b/vi-vn/markdown-vi.html.markdown index 89b59253..696fe465 100644 --- a/vi-vn/markdown-vi.html.markdown +++ b/vi-vn/markdown-vi.html.markdown @@ -48,6 +48,7 @@ bằng cách thêm số lượng dấu thăng (#) đằng trước chuỗi cần ##### Đây là đầu mục <h5> ###### Đây là đầu mục <h6> ``` + Markdown còn cung cấp cách khác để tạo đầu mục hạng nhất h1 và hạng nhì h2. ```md @@ -79,6 +80,7 @@ Trong cài đặt Markdown để hiển thị file của GitHub,ta còn có gạ ```md ~~Đoạn văn bản này được gạch ngang.~~ ``` + ## Đoạn văn Đoạn văn bao gồm một hay nhiều dòng văn bản liên tiếp nhau được phân cách @@ -153,6 +155,7 @@ Ta không nhất thiết phải điền số thứ thự cho chỉ mục đúng 1. Mục thứ hai 1. Mục thứ ba ``` + (Sẽ hiển thị như ví dụ trước đó) Ta còn có thể sử dụng danh sách con @@ -189,7 +192,7 @@ Ta còn có thể thêm dấu nhảy (hoặc thêm vào bốn dấu cách nữa) ```md my_array.each do |item| - puts item + puts item end ``` @@ -201,12 +204,13 @@ John didn't even know what the `go_to()` function did! Trong Markdown của GitHub, ta còn có thêm cách để hiển thị code: -<pre> -<code class="highlight">```ruby +````md +```ruby def foobar - puts "Hello world!" + puts "Hello world!" end -```</code></pre> +``` +```` The above text doesn't require indenting, plus GitHub will use syntax highlighting of the language you specify after the \`\`\` @@ -231,11 +235,13 @@ Một trong những thứ tốt nhất khi làm việc với Markdown là khả ```md [Click me!](http://test.com/) ``` + Ta còn có thể tạo tiêu đề cho liên kết sử dụng cặp ngoặc nháy bên trong cặp ngoặc tròn ```md [Click me!](http://test.com/ "Link to Test.com") ``` + Đường dẫn tương đối cũng hoạt động. ```md @@ -244,19 +250,23 @@ Ta còn có thể tạo tiêu đề cho liên kết sử dụng cặp ngoặc nh Markdown còn hỗ trợ liên kết kiểu tham chiếu. -<pre><code class="highlight">[<span class="nv">Nhấn vào đây</span>][<span class="ss">link1</span>] để xem thêm! -[<span class="nv">Ngoài ra nhấn vào đây</span>][<span class="ss">foobar</span>] nếu bạn muốn xem qua. +```md +[Nhấn vào đây][link1] để xem thêm! +[Ngoài ra nhấn vào đây][foobar] nếu bạn muốn xem qua. -[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Tuyệt!"</span> -[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Tốt!"</span></code></pre> +[link1]: http://test.com/ "Tuyệt!" +[foobar]: http://foobar.biz/ "Tốt!" +``` Tiêu đề có thể được đóng trong dấu nháy hay ngoặc đơn, hoặc có thể được bỏ qua. Tham chiếu có thể được đặt bất kì đâu trong văn bản và ID của tham chiếu có thể là bất kì gì miễn là nó độc nhất. Ngoài ra còn có kiểu đặt tên ngầm cho phép ta sử dụng đường dẫn làm ID. -<pre><code class="highlight">[<span class="nv">This</span>][] is a link. +```md +[This][] is a link. -[<span class="nv">this</span>]: <span class="sx">http://thisisalink.com/</span></code></pre> +[this]: http://thisisalink.com/ +``` Nhưng nó không được sử dụng rộng rãi. @@ -270,9 +280,11 @@ Hiển thị ảnh tương tự như liên kết nhưng có thêm dấu chấm t Và kiểu tham chiếu cũng hoạt động như vậy. -<pre><code class="highlight">![<span class="nv">Đây là thuộc tính alt.</span>][<span class="ss">myimage</span>] +```md +![Đây là thuộc tính alt.][myimage] -[<span class="nv">myimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"Đây là tiêu đề"</span></code></pre> +[myimage]: relative/urls/cool/image.jpg "Đây là tiêu đề" +``` ## Khác @@ -297,12 +309,13 @@ Khi ta muốn viết *đoạn văn bản này có dấu sao bao quanh* nhưng ta ### Phím bàn phím -Trong Markdown của Github, ta có thể sử dụng thẻ `<kbd>` để thay cho phím trên bàn phím. +Trong Markdown của GitHub, ta có thể sử dụng thẻ `<kbd>` để thay cho phím trên bàn phím. ```md Máy treo? Thử bấm tổ hợp <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> ``` + ### Bảng biểu Bảng biểu được hỗ trợ trên Markdown của GitHub, Jira, Trello, v.v và khá khó viết: @@ -313,6 +326,7 @@ Bảng biểu được hỗ trợ trên Markdown của GitHub, Jira, Trello, v.v | Căn trái | Căn giữa | Căn phải | | blah | blah | blah | ``` + Hoặc có thể sử dụng kết quả dưới đây ```md diff --git a/vi-vn/objective-c-vi.html.markdown b/vi-vn/objective-c-vi.html.markdown index 4656cf38..b01ce806 100644 --- a/vi-vn/objective-c-vi.html.markdown +++ b/vi-vn/objective-c-vi.html.markdown @@ -1,316 +1,316 @@ ----
-language: Objective-C
-contributors:
- - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
- - ["Yannick Loriot", "https://github.com/YannickL"]
-lang: vi-vn
-filename: LearnObjectiveC-vi.m
----
-
-Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành macOS, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch.
-Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
-
-```objective-c
-// Chú thích dòng đơn bắt đầu với //
-
-/*
-Chú thích đa dòng trông như thế này.
-*/
-
-// Nhập các headers của framework Foundation với cú pháp #import
-#import <Foundation/Foundation.h>
-#import "MyClass.h"
-
-// Đầu vào chương trình của bạn là một hàm gọi là
-// main với một kiểu trả về kiểu integer.
-int main (int argc, const char * argv[])
-{
- // Tạo một autorelease pool để quản lý bộ nhớ vào chương trình
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- // Sử dụng hàm NSLog() để in ra các dòng lệnh vào console
- NSLog(@"Hello World!"); // Print the string "Hello World!"
-
- ///////////////////////////////////////
- // Kiểu & Biến (Types & Variables)
- ///////////////////////////////////////
-
- // Khai báo số nguyên
- int myPrimitive1 = 1;
- long myPrimitive2 = 234554664565;
-
- // Khai báo đối tượng
- // Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong
- MyClass *myObject1 = nil; // Strong
- id myObject2 = nil; // Weak
- // %@ là một đối tượng
- // 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng
- NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)"
-
- // Chuỗi
- NSString *worldString = @"World";
- NSLog(@"Hello %@!", worldString); // In ra "Hello World!"
-
- // Ký tự literals
- NSNumber *theLetterZNumber = @'Z';
- char theLetterZ = [theLetterZNumber charValue];
- NSLog(@"%c", theLetterZ);
-
- // Số nguyên literals
- NSNumber *fortyTwoNumber = @42;
- int fortyTwo = [fortyTwoNumber intValue];
- NSLog(@"%i", fortyTwo);
-
- NSNumber *fortyTwoUnsignedNumber = @42U;
- unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
- NSLog(@"%u", fortyTwoUnsigned);
-
- NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
- short fortyTwoShort = [fortyTwoShortNumber shortValue];
- NSLog(@"%hi", fortyTwoShort);
-
- NSNumber *fortyTwoLongNumber = @42L;
- long fortyTwoLong = [fortyTwoLongNumber longValue];
- NSLog(@"%li", fortyTwoLong);
-
- // Dấu phẩy động (floating point) literals
- NSNumber *piFloatNumber = @3.141592654F;
- float piFloat = [piFloatNumber floatValue];
- NSLog(@"%f", piFloat);
-
- NSNumber *piDoubleNumber = @3.1415926535;
- double piDouble = [piDoubleNumber doubleValue];
- NSLog(@"%f", piDouble);
-
- // BOOL literals
- NSNumber *yesNumber = @YES;
- NSNumber *noNumber = @NO;
-
- // Đối tượng Mảng
- NSArray *anArray = @[@1, @2, @3, @4];
- NSNumber *thirdNumber = anArray[2];
- NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3"
-
- // Đối tượng Từ điển
- NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
- NSObject *valueObject = aDictionary[@"A Key"];
- NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)"
-
- ///////////////////////////////////////
- // Toán Tử (Operators)
- ///////////////////////////////////////
-
- // Các toán tử cũng hoạt động giống như ngôn ngữ C
- // Ví dụ:
- 2 + 5; // => 7
- 4.2f + 5.1f; // => 9.3f
- 3 == 2; // => 0 (NO)
- 3 != 2; // => 1 (YES)
- 1 && 1; // => 1 (Logical and)
- 0 || 1; // => 1 (Logical or)
- ~0x0F; // => 0xF0 (bitwise negation)
- 0x0F & 0xF0; // => 0x00 (bitwise AND)
- 0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1))
-
- /////////////////////////////////////////////
- // Cấu Trúc Điều Khiển (Controls Structures)
- /////////////////////////////////////////////
-
- // Câu lệnh If-Else
- if (NO)
- {
- NSLog(@"I am never run");
- } else if (0)
- {
- NSLog(@"I am also never run");
- } else
- {
- NSLog(@"I print");
- }
-
- // Câu lệnh Switch
- switch (2)
- {
- case 0:
- {
- NSLog(@"I am never run");
- } break;
- case 1:
- {
- NSLog(@"I am also never run");
- } break;
- default:
- {
- NSLog(@"I print");
- } break;
- }
-
- // Câu lệnh vòng lặp While
- int ii = 0;
- while (ii < 4)
- {
- NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó.
- } // => in ra "0,"
- // "1,"
- // "2,"
- // "3,"
-
- // Câu lệnh vòng lặp For
- int jj;
- for (jj=0; jj < 4; jj++)
- {
- NSLog(@"%d,", jj);
- } // => in ra "0,"
- // "1,"
- // "2,"
- // "3,"
-
- // Câu lệnh Foreach
- NSArray *values = @[@0, @1, @2, @3];
- for (NSNumber *value in values)
- {
- NSLog(@"%@,", value);
- } // => in ra "0,"
- // "1,"
- // "2,"
- // "3,"
-
- // Câu lệnh Try-Catch-Finally
- @try
- {
- // Your statements here
- @throw [NSException exceptionWithName:@"FileNotFoundException"
- reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil];
- } @catch (NSException * e)
- {
- NSLog(@"Exception: %@", e);
- } @finally
- {
- NSLog(@"Finally");
- } // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống"
- // "Finally"
-
- ///////////////////////////////////////
- // Đối Tượng (Objects)
- ///////////////////////////////////////
-
- // Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó.
- // Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành
- MyClass *myObject = [[MyClass alloc] init];
-
- // Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message)
- // và các thực thể đối tượng với nhau.
- // Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp.
- [myObject instanceMethodWithParameter:@"Steve Jobs"];
-
- // Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình
- [pool drain];
-
- // Kết thúc chương trình
- return 0;
-}
-
-///////////////////////////////////////
-// Lớp và Hàm (Classes & Functions)
-///////////////////////////////////////
-
-// Khai báo lớp của bạn ở một tập tin header (MyClass.h):
-// Cú pháp Khai Báo Lớp:
-// @interface ClassName : ParentClassName <ImplementedProtocols>
-// {
-// Khai báo biến thành viên;
-// }
-// -/+ (type) Khai báo method;
-// @end
-@interface MyClass : NSObject <MyProtocol>
-{
- int count;
- id data;
- NSString *name;
-}
-// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter
-@property int count;
-@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán.
-@property (readonly) id data; // Chỉ khai báo phương thức getter.
-
-// Phương thức
-+/- (return type)methodSignature:(Parameter Type *)parameterName;
-
-// dấu '+' cho phương thức lớp
-+ (NSString *)classMethod;
-
-// dấu '-' cho phương thức thực thể
-- (NSString *)instanceMethodWithParameter:(NSString *)string;
-- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
-
-@end
-
-// Thực thi các phương thức trong một tập tin thực thi (MyClass.m):
-
-@implementation MyClass
-
-// Gọi khi đối tượng được release
-- (void)dealloc
-{
-}
-
-// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp
-// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo
-- (id)init
-{
- if ((self = [super init]))
- {
- self.count = 1;
- }
- return self;
-}
-
-+ (NSString *)classMethod
-{
- return [[self alloc] init];
-}
-
-- (NSString *)instanceMethodWithParameter:(NSString *)string
-{
- return @"New string";
-}
-
-- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
-{
- return @42;
-}
-
-// Các phương thức được khai báo vào MyProtocol
-- (void)myProtocolMethod
-{
- // câu lệnh
-}
-
-@end
-
-/*
- * Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào.
- * Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface)
- * mà các đối tượng khác có trách nhiệm sẽ thực thi.
- */
-@protocol MyProtocol
- - (void)myProtocolMethod;
-@end
-
-
-
-```
-## Xem Thêm
-
-+ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
-
-+ Apple Docs':
- + [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
-
- + [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
-
- + [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)
-
- + [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
-
-+ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
+--- +language: Objective-C +contributors: + - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] + - ["Yannick Loriot", "https://github.com/YannickL"] +lang: vi-vn +filename: LearnObjectiveC-vi.m +--- + +Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành macOS, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch. +Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C. + +```objective-c +// Chú thích dòng đơn bắt đầu với // + +/* +Chú thích đa dòng trông như thế này. +*/ + +// Nhập các headers của framework Foundation với cú pháp #import +#import <Foundation/Foundation.h> +#import "MyClass.h" + +// Đầu vào chương trình của bạn là một hàm gọi là +// main với một kiểu trả về kiểu integer. +int main (int argc, const char * argv[]) +{ + // Tạo một autorelease pool để quản lý bộ nhớ vào chương trình + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + // Sử dụng hàm NSLog() để in ra các dòng lệnh vào console + NSLog(@"Hello World!"); // Print the string "Hello World!" + + /////////////////////////////////////// + // Kiểu & Biến (Types & Variables) + /////////////////////////////////////// + + // Khai báo số nguyên + int myPrimitive1 = 1; + long myPrimitive2 = 234554664565; + + // Khai báo đối tượng + // Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong + MyClass *myObject1 = nil; // Strong + id myObject2 = nil; // Weak + // %@ là một đối tượng + // 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng + NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)" + + // Chuỗi + NSString *worldString = @"World"; + NSLog(@"Hello %@!", worldString); // In ra "Hello World!" + + // Ký tự literals + NSNumber *theLetterZNumber = @'Z'; + char theLetterZ = [theLetterZNumber charValue]; + NSLog(@"%c", theLetterZ); + + // Số nguyên literals + NSNumber *fortyTwoNumber = @42; + int fortyTwo = [fortyTwoNumber intValue]; + NSLog(@"%i", fortyTwo); + + NSNumber *fortyTwoUnsignedNumber = @42U; + unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; + NSLog(@"%u", fortyTwoUnsigned); + + NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; + short fortyTwoShort = [fortyTwoShortNumber shortValue]; + NSLog(@"%hi", fortyTwoShort); + + NSNumber *fortyTwoLongNumber = @42L; + long fortyTwoLong = [fortyTwoLongNumber longValue]; + NSLog(@"%li", fortyTwoLong); + + // Dấu phẩy động (floating point) literals + NSNumber *piFloatNumber = @3.141592654F; + float piFloat = [piFloatNumber floatValue]; + NSLog(@"%f", piFloat); + + NSNumber *piDoubleNumber = @3.1415926535; + double piDouble = [piDoubleNumber doubleValue]; + NSLog(@"%f", piDouble); + + // BOOL literals + NSNumber *yesNumber = @YES; + NSNumber *noNumber = @NO; + + // Đối tượng Mảng + NSArray *anArray = @[@1, @2, @3, @4]; + NSNumber *thirdNumber = anArray[2]; + NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3" + + // Đối tượng Từ điển + NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; + NSObject *valueObject = aDictionary[@"A Key"]; + NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)" + + /////////////////////////////////////// + // Toán Tử (Operators) + /////////////////////////////////////// + + // Các toán tử cũng hoạt động giống như ngôn ngữ C + // Ví dụ: + 2 + 5; // => 7 + 4.2f + 5.1f; // => 9.3f + 3 == 2; // => 0 (NO) + 3 != 2; // => 1 (YES) + 1 && 1; // => 1 (Logical and) + 0 || 1; // => 1 (Logical or) + ~0x0F; // => 0xF0 (bitwise negation) + 0x0F & 0xF0; // => 0x00 (bitwise AND) + 0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1)) + + ///////////////////////////////////////////// + // Cấu Trúc Điều Khiển (Controls Structures) + ///////////////////////////////////////////// + + // Câu lệnh If-Else + if (NO) + { + NSLog(@"I am never run"); + } else if (0) + { + NSLog(@"I am also never run"); + } else + { + NSLog(@"I print"); + } + + // Câu lệnh Switch + switch (2) + { + case 0: + { + NSLog(@"I am never run"); + } break; + case 1: + { + NSLog(@"I am also never run"); + } break; + default: + { + NSLog(@"I print"); + } break; + } + + // Câu lệnh vòng lặp While + int ii = 0; + while (ii < 4) + { + NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó. + } // => in ra "0," + // "1," + // "2," + // "3," + + // Câu lệnh vòng lặp For + int jj; + for (jj=0; jj < 4; jj++) + { + NSLog(@"%d,", jj); + } // => in ra "0," + // "1," + // "2," + // "3," + + // Câu lệnh Foreach + NSArray *values = @[@0, @1, @2, @3]; + for (NSNumber *value in values) + { + NSLog(@"%@,", value); + } // => in ra "0," + // "1," + // "2," + // "3," + + // Câu lệnh Try-Catch-Finally + @try + { + // Your statements here + @throw [NSException exceptionWithName:@"FileNotFoundException" + reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil]; + } @catch (NSException * e) + { + NSLog(@"Exception: %@", e); + } @finally + { + NSLog(@"Finally"); + } // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống" + // "Finally" + + /////////////////////////////////////// + // Đối Tượng (Objects) + /////////////////////////////////////// + + // Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó. + // Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành + MyClass *myObject = [[MyClass alloc] init]; + + // Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message) + // và các thực thể đối tượng với nhau. + // Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp. + [myObject instanceMethodWithParameter:@"Steve Jobs"]; + + // Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình + [pool drain]; + + // Kết thúc chương trình + return 0; +} + +/////////////////////////////////////// +// Lớp và Hàm (Classes & Functions) +/////////////////////////////////////// + +// Khai báo lớp của bạn ở một tập tin header (MyClass.h): +// Cú pháp Khai Báo Lớp: +// @interface ClassName : ParentClassName <ImplementedProtocols> +// { +// Khai báo biến thành viên; +// } +// -/+ (type) Khai báo method; +// @end +@interface MyClass : NSObject <MyProtocol> +{ + int count; + id data; + NSString *name; +} +// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter +@property int count; +@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán. +@property (readonly) id data; // Chỉ khai báo phương thức getter. + +// Phương thức ++/- (return type)methodSignature:(Parameter Type *)parameterName; + +// dấu '+' cho phương thức lớp ++ (NSString *)classMethod; + +// dấu '-' cho phương thức thực thể +- (NSString *)instanceMethodWithParameter:(NSString *)string; +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; + +@end + +// Thực thi các phương thức trong một tập tin thực thi (MyClass.m): + +@implementation MyClass + +// Gọi khi đối tượng được release +- (void)dealloc +{ +} + +// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp +// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo +- (id)init +{ + if ((self = [super init])) + { + self.count = 1; + } + return self; +} + ++ (NSString *)classMethod +{ + return [[self alloc] init]; +} + +- (NSString *)instanceMethodWithParameter:(NSString *)string +{ + return @"New string"; +} + +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number +{ + return @42; +} + +// Các phương thức được khai báo vào MyProtocol +- (void)myProtocolMethod +{ + // câu lệnh +} + +@end + +/* + * Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào. + * Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface) + * mà các đối tượng khác có trách nhiệm sẽ thực thi. + */ +@protocol MyProtocol + - (void)myProtocolMethod; +@end + + + +``` +## Xem Thêm + ++ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C) + ++ Apple Docs': + + [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/) + + + [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html) + + + [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149) + + + [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html) + ++ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started) diff --git a/vi-vn/xml-vi.html.markdown b/vi-vn/xml-vi.html.markdown new file mode 100644 index 00000000..7a74c154 --- /dev/null +++ b/vi-vn/xml-vi.html.markdown @@ -0,0 +1,170 @@ +--- +language: xml +filename: learnxml.xml +contributors: + - ['João Farias', 'https://github.com/JoaoGFarias'] + - ['Rachel Stiyer', 'https://github.com/rstiyer'] + - ['Deepanshu Utkarsh', 'https://github.com/duci9y'] +translators: + - ['Thanh Duy Phan', 'https://github.com/thanhpd'] +lang: vi-vn +--- + +XML là ngôn ngữ đánh dấu được thiết kế để lưu trữ và truyền tải dữ liệu. Nó có thể được đọc hiểu bởi cả người và máy. + +Không giống như HTML, XML không biểu đạt cách hiển thị hoặc định dạng dữ liệu, chỉ chứa dữ liệu mà thôi. + +Có những sự khác biệt rõ ràng giữa **nội dung** và **các đánh dấu**. Nói vắn tắt thì nội dung có thể là bất cứ gì trong khi các đánh dấu được định nghĩa trước. + +## Một số định nghĩa và giới thiệu + +Các XML Document (Văn bản XML) được cấu thành bởi các _elements (phần tử)_ và chúng có thể có các _attributes (thuộc tính)_ để mô tả, đồng thời cũng có thể chứa các nội dung theo ngữ cảnh và một hoặc nhiều phần tử con. Tất cả XML document phải có một phần tử gốc đóng vai trò tổ tiên cho tất cả các phần tử khác trong văn bản. + +Các trình phân tích cú pháp XML (XML Parser) được thiết kế để phân tích rất chặt chẽ, và sẽ dừng phân tích các văn bản không đúng định dạng. Vì vậy cần đảm bảo tất cả văn bản XML tuân theo [Các luật cú pháp XML](http://www.w3schools.com/xml/xml_syntax.asp). + +```xml +<!-- Đây là một bình luận. Nó không được phép chứa hai dấu gạch ngang (-) liên tiếp --> +<!-- Comments can span + trải dài nhiều dòngmultiple lines --> + +<!-- Element - Phần tử --> +<!-- Một element là thành phần XML cơ bản nhất. Có hai loại, thử nhất là rỗng nô --> +<element1 thuoc-tinh="gia trialue" /> <Các element rỗng không chứa bất kì nội dung gìtent --> +<!-- và không rỗng nội dung: --> +<element2 thuoc-tinh="gia tri">Nội dung</element2> +<!-- Tên của element chỉ được phép chứa chữ cái và chữ số --> + +<empty /> <!-- Một element có thể là một element với tag rỗng… --> +<!-- …không chứa bất cứ nội dung gì và chỉ là markup đơn thuần. --> + +<notempty> <!-- Hoặc nó chứa một tag bắt đầu… --> + <!-- …nội dung… --> +</notempty> <!-- và kết thúc với tag đóng. --> + +<!-- Tên element phân biệt chữ hoa và thường. --> +<element /> +<!-- không giống như --> +<eLEMENT /> + +<!-- Attribute - Thuộc tính --> +<!-- Một thuộc tính là một cặp key-value và tồn tại bên trong element. --> +<element thuoctinh="giatri" thuoctinhkhac="giatrikhac" nhieugiatri="danhsach phanbiet bangdaucach" /> +<!-- Một thuộc tính chỉ xuất hiện một lần trong một element. Nó chỉ chứa một giá trị. + Một cách giải quyết là sử dụng danh sách giá trị được phân biệt bởi dấu cách. --> + +<!-- Nesting element - Phần tử lồng nhau --> +<!-- Nội dung một element có thể chứa các element khác --> +<cha> + <con>Text</con> + <elementrong /> +</cha> +<!-- Danh pháp cây tiêu chuẩn được tuân theo. Mỗi phần tử được gọi là một nút. + Phần tử cấp trên là cha, phần tử cấp dưới là con. + Các element trong cùng một element cha có mức tương đương nhau như anh chị em. --> + +<!-- XML bảo lưu dấu cách. --> +<child> + Văn bản +</child> +<!-- sẽ không giống như --> +<child>Văn bản</child> +``` + +## Một văn bản XML - XML document + +Đây là thứ làm cho XML rất linh hoạt do nó giúp con người cũng đọc được. Văn bản sau đây cho ta biết nó định nghĩa một hiệu sách bản ba quyển sách, trong đó có một cuốn tên Learning XML bởi Erik T. Ray. Tất cả những việc này chưa cần phải sử dụng XML Parser. + +```xml +<?xml version="1.0" encoding="UTF-8"?> +<!-- Đây là phần mở đầu, không bắt buộc cần nhưng nên có --> +<hieusach> + <sach danhmuc="NAUAN"> + <tieude lang="en">Everyday Italian</tieude> + <tacgia>Giada De Laurentiis</tacgia> + <nam>2005</nam> + <giaban>30.00</giaban> + </sach> + <sach danhmuc="TREEM"> + <tieude lang="en">Harry Potter</tieude> + <tacgia>J K. Rowling</tacgia> + <nam>2005</nam> + <giaban>29.99</giaban> + </sach> + <sach danhmuc="WEB"> + <tieude lang="en">Learning XML</tieude> + <tacgia>Erik T. Ray</tacgia> + <nam>2003</nam> + <giaban>39.95</giaban> + </sach> +</hieusach> +``` + +## Tính đúng đắn và việc xác minh + +Một văn bản XML là _đúng đắn (well-formed)_ nếu nó có cú pháp chính xác. Ty nhiên, ta có thể thêm nhiều ràng buộc vào văn bản, sử dụng Document Type Definition (DTD) - Định dạng loại văn bản. Một văn bản mà các phần tử và thuộc tính được khai báo trong một DTĐ và tuân theo ngữ pháp được đưa ra trong DTD đó được gọi là _valid - được chấp nhận_ và tuân theo DTD bên cạnh việc đúng đắn. + +```xml +<!-- Khai báo DTD lấy từ tệp bên ngoài: --> +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE hieusach SYSTEM "Hieusach.dtd"> +<!-- Khai báo hieusach là phần tử gốc và 'Hieusach.dtd' là đường dẫn + tới tệp DTD. --> +<hieusach> + <sach danhmuc="NAUAN"> + <tieude lang="en">Everyday Italian</tieude> + <tacgia>Giada De Laurentiis</tacgia> + <nam>2005</nam> + <giaban>30.00</giaban> + </sach> +</hieusach> + +<!-- Tệp DTD: --> +<!ELEMENT hieusach (sach+)> +<!-- Element hieusach có thể chứa một hoặc nhiều element sach. --> +<!ELEMENT sach (tieude, giaban)> +<!-- Mỗi sach cần có các element con tên tieude và giaban. --> +<!ATTLIST sach danhmuc CDATA "Vanhoc"> +<!-- Mỗi sach cần có một thuộc tính danhmuc. Nếu không có, giá trị mặc định + sẽ là 'Vanhoc'. --> +<!ELEMENT tieude (#PCDATA)> +<!-- Element tieude chỉ được chứa nội dung dữ liệu kĩ tự được phân tích. +Nói cách khác, nó có thể + chỉ chứa văn bản được phân tích bởi parser và không được phép chứa element con + So sánh với CDATA, hay dữ liệu kí tự --> +<!ELEMENT giaban (#PCDATA)> +]> + +<!-- DTD có thể được khai báo bên trong chính tệp XML.--> + +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE hieusach [ +<!ELEMENT hieusach (sach+)> +<!ELEMENT sach (tieude, giaban)> +<!ATTLIST sach danhmuc CDATA "Vanhoc"> +<!ELEMENT tieude (#PCDATA)> +<!ELEMENT giaban (#PCDATA)> +]> + +<hieusach> + <sach danhmuc="NAUAN"> + <tieude lang="en">Everyday Italian</tieude> + <giaban>30.00</giaban> + </sach> +</hieusach> +``` + +## DTD Compatibility and XML Schema Definitions (Tương thích DTD và định nghĩa XML Schema) + +Hỗ trợ cho DTD khá nhiều do chúng đã quá cũ. Tuy nhiên, nhiều tính năng hiện đại của XML như namespace không được hỗ trợ bởi DTD. XML Schema Definition (XSD) - Định nghĩa lược đồ XML được coi như sẽ thay thế DTD để định nghĩa cấu trúc ngữ pháp của văn bản XML. + +## Tra cứu + +- [Validate your XML (Xác minh XML)](http://www.xmlvalidation.com) + +## Đọc thêm + +- [Hướng dẫn XML Schema Definitions](http://www.w3schools.com/schema/) +- [Hướng dẫn DTD](http://www.w3schools.com/xml/xml_dtd_intro.asp) +- [Hướng dẫn XML](http://www.w3schools.com/xml/default.asp) +- [Dùng XPath queries để phân tích cú pháp XML](http://www.w3schools.com/xml/xml_xpath.asp) diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown index a253af48..b79017dc 100644 --- a/visualbasic.html.markdown +++ b/visualbasic.html.markdown @@ -5,7 +5,7 @@ contributors: filename: learnvisualbasic.vb --- -``` +```visualbasic Module Module1 Sub Main() diff --git a/wolfram.html.markdown b/wolfram.html.markdown index 5fddbc82..fa8ee078 100644 --- a/wolfram.html.markdown +++ b/wolfram.html.markdown @@ -14,7 +14,7 @@ Wolfram Language has several interfaces: The code in this example can be typed in to any interface and edited with Wolfram Workbench. Loading directly into Mathematica may be awkward because the file contains no cell formatting information (which would make the file a huge mess to read as text) - it can be viewed/edited but may require some setting up. -``` +```mathematica (* This is a comment *) (* In Mathematica instead of using these comments you can create a text cell diff --git a/xml.html.markdown b/xml.html.markdown index 2a258d94..630e4c90 100644 --- a/xml.html.markdown +++ b/xml.html.markdown @@ -165,7 +165,7 @@ Support for DTDs is ubiquitous because they are so old. Unfortunately, modern XM ## Further Reading -* [XML Schema Definitions Tutorial](http://www.w3schools.com/schema/) +* [XML Schema Definitions Tutorial](https://www.w3schools.com/xml/schema_intro.asp) * [DTD Tutorial](http://www.w3schools.com/xml/xml_dtd_intro.asp) * [XML Tutorial](http://www.w3schools.com/xml/default.asp) * [Using XPath queries to parse XML](http://www.w3schools.com/xml/xml_xpath.asp) diff --git a/yaml.html.markdown b/yaml.html.markdown index 135213d2..6901695c 100644 --- a/yaml.html.markdown +++ b/yaml.html.markdown @@ -44,8 +44,8 @@ key with spaces: value # Yes and No (doesn't matter the case) will be evaluated to boolean # true and false values respectively. # To use the actual value use single or double quotes. -no: no # evaluates to "false": false -yes: No # evaluates to "true": false +no: no # evaluates to "no": false +yes: No # evaluates to "yes": false not_enclosed: yes # evaluates to "not_enclosed": true enclosed: "yes" # evaluates to "enclosed": yes @@ -165,7 +165,7 @@ other_anchor: *anchor_name base: &base name: Everyone has same name -# The regexp << is called 'Merge Key Language-Independent Type'. It is used to +# The expression << is called 'Merge Key Language-Independent Type'. It is used to # indicate that all the keys of one or more specified maps should be inserted # into the current map. # NOTE: If key already exists alias will not be merged diff --git a/zfs.html.markdown b/zfs.html.markdown index 6795b1fa..3f5a76b5 100644 --- a/zfs.html.markdown +++ b/zfs.html.markdown @@ -3,6 +3,7 @@ category: tool tool: zfs contributors: - ["sarlalian", "http://github.com/sarlalian"] + - ["A1EF", "https://github.com/A1EF"] filename: LearnZfs.txt --- @@ -25,7 +26,6 @@ RAID setup with ZFS, as ZFS expects to directly manage the underlying disks. Types of VDEV's -* stripe (a single disk, no redundancy) * mirror (n-way mirrors supported) * raidz * raidz1 (1-disk parity, similar to RAID 5) @@ -71,7 +71,7 @@ List zpools ```bash # Create a raidz zpool -$ zpool create bucket raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2 +$ zpool create zroot raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2 # List ZPools $ zpool list @@ -160,22 +160,22 @@ Create datasets ```bash # Create dataset -$ zfs create tank/root/data +$ zfs create zroot/root/data $ mount | grep data -tank/root/data on /data (zfs, local, nfsv4acls) +zroot/root/data on /data (zfs, local, nfsv4acls) # Create child dataset -$ zfs create tank/root/data/stuff +$ zfs create zroot/root/data/stuff $ mount | grep data -tank/root/data on /data (zfs, local, nfsv4acls) -tank/root/data/stuff on /data/stuff (zfs, local, nfsv4acls) +zroot/root/data on /data (zfs, local, nfsv4acls) +zroot/root/data/stuff on /data/stuff (zfs, local, nfsv4acls) # Create Volume $ zfs create -V zroot/win_vm $ zfs list zroot/win_vm NAME USED AVAIL REFER MOUNTPOINT -tank/win_vm 4.13G 17.9G 64K - +zroot/win_vm 4.13G 17.9G 64K - ``` List datasets @@ -213,28 +213,28 @@ zroot/var/tmp@daily-2015-10-15 Rename datasets ```bash -$ zfs rename tank/root/home tank/root/old_home -$ zfs rename tank/root/new_home tank/root/home +$ zfs rename zroot/root/home zroot/root/old_home +$ zfs rename zroot/root/new_home zroot/root/home ``` Delete dataset ```bash # Datasets cannot be deleted if they have any snapshots -$ zfs destroy tank/root/home +$ zfs destroy zroot/root/home ``` Get / set properties of a dataset ```bash # Get all properties -$ zfs get all zroot/usr/home │157 # Create Volume -NAME PROPERTY VALUE SOURCE │158 $ zfs create -V zroot/win_vm -zroot/home type filesystem - │159 $ zfs list zroot/win_vm -zroot/home creation Mon Oct 20 14:44 2014 - │160 NAME USED AVAIL REFER MOUNTPOINT -zroot/home used 11.9G - │161 tank/win_vm 4.13G 17.9G 64K - -zroot/home available 94.1G - │162 ``` -zroot/home referenced 11.9G - │163 +$ zfs get all zroot/usr/home +NAME PROPERTY VALUE SOURCE +zroot/home type filesystem - +zroot/home creation Mon Oct 20 14:44 2014 - +zroot/home used 11.9G - +zroot/home available 94.1G - +zroot/home referenced 11.9G - zroot/home mounted yes - ... @@ -244,7 +244,7 @@ NAME PROPERTY VALUE SOURCE zroot/home compression off default # Set property on dataset -$ zfs set compression=gzip-9 mypool/lamb +$ zfs set compression=lz4 zroot/lamb # Get a set of properties from all datasets $ zfs list -o name,quota,reservation @@ -283,16 +283,16 @@ Create snapshots ```bash # Create a snapshot of a single dataset -zfs snapshot tank/home/sarlalian@now +zfs snapshot zroot/home/sarlalian@now # Create a snapshot of a dataset and its children -$ zfs snapshot -r tank/home@now +$ zfs snapshot -r zroot/home@now $ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT -tank/home@now 0 - 26K - -tank/home/sarlalian@now 0 - 259M - -tank/home/alice@now 0 - 156M - -tank/home/bob@now 0 - 156M - +zroot/home@now 0 - 26K - +zroot/home/sarlalian@now 0 - 259M - +zroot/home/alice@now 0 - 156M - +zroot/home/bob@now 0 - 156M - ... ``` @@ -300,10 +300,10 @@ Destroy snapshots ```bash # How to destroy a snapshot -$ zfs destroy tank/home/sarlalian@now +$ zfs destroy zroot/home/sarlalian@now # Delete a snapshot on a parent dataset and its children -$ zfs destroy -r tank/home/sarlalian@now +$ zfs destroy -r zroot/home/sarlalian@now ``` @@ -311,10 +311,10 @@ Renaming Snapshots ```bash # Rename a snapshot -$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today -$ zfs rename tank/home/sarlalian@now today +$ zfs rename zroot/home/sarlalian@now zroot/home/sarlalian@today +$ zfs rename zroot/home/sarlalian@now today -$ zfs rename -r tank/home@now @yesterday +$ zfs rename -r zroot/home@now @yesterday ``` Accessing snapshots @@ -328,26 +328,26 @@ Sending and Receiving ```bash # Backup a snapshot to a file -$ zfs send tank/home/sarlalian@now | gzip > backup_file.gz +$ zfs send zroot/home/sarlalian@now | gzip > backup_file.gz # Send a snapshot to another dataset -$ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian +$ zfs send zroot/home/sarlalian@now | zfs recv backups/home/sarlalian # Send a snapshot to a remote host -$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian' +$ zfs send zroot/home/sarlalian@now | ssh root@backup_server 'zfs recv zroot/home/sarlalian' # Send full dataset with snapshots to new host -$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home' +$ zfs send -v -R zroot/home@now | ssh root@backup_server 'zfs recv zroot/home' ``` Cloning Snapshots ```bash # Clone a snapshot -$ zfs clone tank/home/sarlalian@now tank/home/sarlalian_new +$ zfs clone zroot/home/sarlalian@now zroot/home/sarlalian_new # Promoting the clone so it is no longer dependent on the snapshot -$ zfs promote tank/home/sarlalian_new +$ zfs promote zroot/home/sarlalian_new ``` ### Putting it all together diff --git a/zh-cn/asciidoc-cn.html.markdown b/zh-cn/asciidoc-cn.html.markdown index 74eed445..0709e8c1 100644 --- a/zh-cn/asciidoc-cn.html.markdown +++ b/zh-cn/asciidoc-cn.html.markdown @@ -1,6 +1,6 @@ --- language: asciidoc -filename: asciidoc-cn.md +filename: asciidoc-cn.adoc contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] diff --git a/zh-cn/awk-cn.html.markdown b/zh-cn/awk-cn.html.markdown index bac833a6..02f1f7d5 100644 --- a/zh-cn/awk-cn.html.markdown +++ b/zh-cn/awk-cn.html.markdown @@ -179,7 +179,7 @@ function string_functions( localvar, arr) { # 都是返回替换的个数 localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" - gsub("e", ".", localvar) # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar) # localvar => "M..t m. at th. bar" # 搜索匹配正则的字符串 # index() 也是搜索, 不支持正则 diff --git a/zh-cn/c++-cn.html.markdown b/zh-cn/c++-cn.html.markdown index a6a61949..db36ebc4 100644 --- a/zh-cn/c++-cn.html.markdown +++ b/zh-cn/c++-cn.html.markdown @@ -1,572 +1,572 @@ ----
-language: C++
-filename: learncpp-cn.cpp
-contributors:
- - ["Steven Basart", "http://github.com/xksteven"]
- - ["Matt Kline", "https://github.com/mrkline"]
-translators:
- - ["Arnie97", "https://github.com/Arnie97"]
-lang: zh-cn
----
-
-C++是一种系统编程语言。用它的发明者,
-[Bjarne Stroustrup的话](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)来说,C++的设计目标是:
-
-- 成为“更好的C语言”
-- 支持数据的抽象与封装
-- 支持面向对象编程
-- 支持泛型编程
-
-C++提供了对硬件的紧密控制(正如C语言一样),
-能够编译为机器语言,由处理器直接执行。
-与此同时,它也提供了泛型、异常和类等高层功能。
-虽然C++的语法可能比某些出现较晚的语言更复杂,它仍然得到了人们的青睞——
-功能与速度的平衡使C++成为了目前应用最广泛的系统编程语言之一。
-
-```c++
-////////////////
-// 与C语言的比较
-////////////////
-
-// C++_几乎_是C语言的一个超集,它与C语言的基本语法有许多相同之处,
-// 例如变量和函数的声明,原生数据类型等等。
-
-// 和C语言一样,在C++中,你的程序会从main()开始执行,
-// 该函数的返回值应当为int型,这个返回值会作为程序的退出状态值。
-// 不过,大多数的编译器(gcc,clang等)也接受 void main() 的函数原型。
-// (参见 http://en.wikipedia.org/wiki/Exit_status 来获取更多信息)
-int main(int argc, char** argv)
-{
- // 和C语言一样,命令行参数通过argc和argv传递。
- // argc代表命令行参数的数量,
- // 而argv是一个包含“C语言风格字符串”(char *)的数组,
- // 其中每个字符串代表一个命令行参数的内容,
- // 首个命令行参数是调用该程序时所使用的名称。
- // 如果你不关心命令行参数的值,argc和argv可以被忽略。
- // 此时,你可以用int main()作为函数原型。
-
- // 退出状态值为0时,表示程序执行成功
- return 0;
-}
-
-// 然而,C++和C语言也有一些区别:
-
-// 在C++中,字符字面量的大小是一个字节。
-sizeof('c') == 1
-
-// 在C语言中,字符字面量的大小与int相同。
-sizeof('c') == sizeof(10)
-
-
-// C++的函数原型与函数定义是严格匹配的
-void func(); // 这个函数不能接受任何参数
-
-// 而在C语言中
-void func(); // 这个函数能接受任意数量的参数
-
-// 在C++中,用nullptr代替C语言中的NULL
-int* ip = nullptr;
-
-// C++也可以使用C语言的标准头文件,
-// 但是需要加上前缀“c”并去掉末尾的“.h”。
-#include <cstdio>
-
-int main()
-{
- printf("Hello, world!\n");
- return 0;
-}
-
-///////////
-// 函数重载
-///////////
-
-// C++支持函数重载,你可以定义一组名称相同而参数不同的函数。
-
-void print(char const* myString)
-{
- printf("String %s\n", myString);
-}
-
-void print(int myInt)
-{
- printf("My int is %d", myInt);
-}
-
-int main()
-{
- print("Hello"); // 解析为 void print(const char*)
- print(15); // 解析为 void print(int)
-}
-
-///////////////////
-// 函数参数的默认值
-///////////////////
-
-// 你可以为函数的参数指定默认值,
-// 它们将会在调用者没有提供相应参数时被使用。
-
-void doSomethingWithInts(int a = 1, int b = 4)
-{
- // 对两个参数进行一些操作
-}
-
-int main()
-{
- doSomethingWithInts(); // a = 1, b = 4
- doSomethingWithInts(20); // a = 20, b = 4
- doSomethingWithInts(20, 5); // a = 20, b = 5
-}
-
-// 默认参数必须放在所有的常规参数之后。
-
-void invalidDeclaration(int a = 1, int b) // 这是错误的!
-{
-}
-
-
-///////////
-// 命名空间
-///////////
-
-// 命名空间为变量、函数和其他声明提供了分离的的作用域。
-// 命名空间可以嵌套使用。
-
-namespace First {
- namespace Nested {
- void foo()
- {
- printf("This is First::Nested::foo\n");
- }
- } // 结束嵌套的命名空间Nested
-} // 结束命名空间First
-
-namespace Second {
- void foo()
- {
- printf("This is Second::foo\n")
- }
-}
-
-void foo()
-{
- printf("This is global foo\n");
-}
-
-int main()
-{
- // 如果没有特别指定,就从“Second”中取得所需的内容。
- using namespace Second;
-
- foo(); // 显示“This is Second::foo”
- First::Nested::foo(); // 显示“This is First::Nested::foo”
- ::foo(); // 显示“This is global foo”
-}
-
-////////////
-// 输入/输出
-////////////
-
-// C++使用“流”来输入输出。<<是流的插入运算符,>>是流提取运算符。
-// cin、cout、和cerr分别代表
-// stdin(标准输入)、stdout(标准输出)和stderr(标准错误)。
-
-#include <iostream> // 引入包含输入/输出流的头文件
-
-using namespace std; // 输入输出流在std命名空间(也就是标准库)中。
-
-int main()
-{
- int myInt;
-
- // 在标准输出(终端/显示器)中显示
- cout << "Enter your favorite number:\n";
- // 从标准输入(键盘)获得一个值
- cin >> myInt;
-
- // cout也提供了格式化功能
- cout << "Your favorite number is " << myInt << "\n";
- // 显示“Your favorite number is <myInt>”
-
- cerr << "Used for error messages";
-}
-
-/////////
-// 字符串
-/////////
-
-// C++中的字符串是对象,它们有很多成员函数
-#include <string>
-
-using namespace std; // 字符串也在std命名空间(标准库)中。
-
-string myString = "Hello";
-string myOtherString = " World";
-
-// + 可以用于连接字符串。
-cout << myString + myOtherString; // "Hello World"
-
-cout << myString + " You"; // "Hello You"
-
-// C++中的字符串是可变的,具有“值语义”。
-myString.append(" Dog");
-cout << myString; // "Hello Dog"
-
-
-/////////////
-// 引用
-/////////////
-
-// 除了支持C语言中的指针类型以外,C++还提供了_引用_。
-// 引用是一种特殊的指针类型,一旦被定义就不能重新赋值,并且不能被设置为空值。
-// 使用引用时的语法与原变量相同:
-// 也就是说,对引用类型进行解引用时,不需要使用*;
-// 赋值时也不需要用&来取地址。
-
-using namespace std;
-
-string foo = "I am foo";
-string bar = "I am bar";
-
-
-string& fooRef = foo; // 建立了一个对foo的引用。
-fooRef += ". Hi!"; // 通过引用来修改foo的值
-cout << fooRef; // "I am foo. Hi!"
-
-// 这句话的并不会改变fooRef的指向,其效果与“foo = bar”相同。
-// 也就是说,在执行这条语句之后,foo == "I am bar"。
-fooRef = bar;
-
-const string& barRef = bar; // 建立指向bar的常量引用。
-// 和C语言中一样,(指针和引用)声明为常量时,对应的值不能被修改。
-barRef += ". Hi!"; // 这是错误的,不能修改一个常量引用的值。
-
-///////////////////
-// 类与面向对象编程
-///////////////////
-
-// 有关类的第一个示例
-#include <iostream>
-
-// 声明一个类。
-// 类通常在头文件(.h或.hpp)中声明。
-class Dog {
- // 成员变量和成员函数默认情况下是私有(private)的。
- std::string name;
- int weight;
-
-// 在这个标签之后,所有声明都是公有(public)的,
-// 直到重新指定“private:”(私有继承)或“protected:”(保护继承)为止
-public:
-
- // 默认的构造器
- Dog();
-
- // 这里是成员函数声明的一个例子。
- // 可以注意到,我们在此处使用了std::string,而不是using namespace std
- // 语句using namespace绝不应当出现在头文件当中。
- void setName(const std::string& dogsName);
-
- void setWeight(int dogsWeight);
-
- // 如果一个函数不对对象的状态进行修改,
- // 应当在声明中加上const。
- // 这样,你就可以对一个以常量方式引用的对象执行该操作。
- // 同时可以注意到,当父类的成员函数需要被子类重写时,
- // 父类中的函数必须被显式声明为_虚函数(virtual)_。
- // 考虑到性能方面的因素,函数默认情况下不会被声明为虚函数。
- virtual void print() const;
-
- // 函数也可以在class body内部定义。
- // 这样定义的函数会自动成为内联函数。
- void bark() const { std::cout << name << " barks!\n" }
-
- // 除了构造器以外,C++还提供了析构器。
- // 当一个对象被删除或者脱离其定义域时,它的析构函数会被调用。
- // 这使得RAII这样的强大范式(参见下文)成为可能。
- // 为了衍生出子类来,基类的析构函数必须定义为虚函数。
- virtual ~Dog();
-
-}; // 在类的定义之后,要加一个分号
-
-// 类的成员函数通常在.cpp文件中实现。
-void Dog::Dog()
-{
- std::cout << "A dog has been constructed\n";
-}
-
-// 对象(例如字符串)应当以引用的形式传递,
-// 对于不需要修改的对象,最好使用常量引用。
-void Dog::setName(const std::string& dogsName)
-{
- name = dogsName;
-}
-
-void Dog::setWeight(int dogsWeight)
-{
- weight = dogsWeight;
-}
-
-// 虚函数的virtual关键字只需要在声明时使用,不需要在定义时重复
-void Dog::print() const
-{
- std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
-}
-
-void Dog::~Dog()
-{
- std::cout << "Goodbye " << name << "\n";
-}
-
-int main() {
- Dog myDog; // 此时显示“A dog has been constructed”
- myDog.setName("Barkley");
- myDog.setWeight(10);
- myDog.print(); // 显示“Dog is Barkley and weighs 10 kg”
- return 0;
-} // 显示“Goodbye Barkley”
-
-// 继承:
-
-// 这个类继承了Dog类中的公有(public)和保护(protected)对象
-class OwnedDog : public Dog {
-
- void setOwner(const std::string& dogsOwner)
-
- // 重写OwnedDogs类的print方法。
- // 如果你不熟悉子类多态的话,可以参考这个页面中的概述:
- // http://zh.wikipedia.org/wiki/%E5%AD%90%E7%B1%BB%E5%9E%8B
-
- // override关键字是可选的,它确保你所重写的是基类中的方法。
- void print() const override;
-
-private:
- std::string owner;
-};
-
-// 与此同时,在对应的.cpp文件里:
-
-void OwnedDog::setOwner(const std::string& dogsOwner)
-{
- owner = dogsOwner;
-}
-
-void OwnedDog::print() const
-{
- Dog::print(); // 调用基类Dog中的print方法
- // "Dog is <name> and weights <weight>"
-
- std::cout << "Dog is owned by " << owner << "\n";
- // "Dog is owned by <owner>"
-}
-
-/////////////////////
-// 初始化与运算符重载
-/////////////////////
-
-// 在C++中,通过定义一些特殊名称的函数,
-// 你可以重载+、-、*、/等运算符的行为。
-// 当运算符被使用时,这些特殊函数会被调用,从而实现运算符重载。
-
-#include <iostream>
-using namespace std;
-
-class Point {
-public:
- // 可以以这样的方式为成员变量设置默认值。
- double x = 0;
- double y = 0;
-
- // 定义一个默认的构造器。
- // 除了将Point初始化为(0, 0)以外,这个函数什么都不做。
- Point() { };
-
- // 下面使用的语法称为初始化列表,
- // 这是初始化类中成员变量的正确方式。
- Point (double a, double b) :
- x(a),
- y(b)
- { /* 除了初始化成员变量外,什么都不做 */ }
-
- // 重载 + 运算符
- Point operator+(const Point& rhs) const;
-
- // 重载 += 运算符
- Point& operator+=(const Point& rhs);
-
- // 增加 - 和 -= 运算符也是有意义的,但这里不再赘述。
-};
-
-Point Point::operator+(const Point& rhs) const
-{
- // 创建一个新的点,
- // 其横纵坐标分别为这个点与另一点在对应方向上的坐标之和。
- return Point(x + rhs.x, y + rhs.y);
-}
-
-Point& Point::operator+=(const Point& rhs)
-{
- x += rhs.x;
- y += rhs.y;
- return *this;
-}
-
-int main () {
- Point up (0,1);
- Point right (1,0);
- // 这里使用了Point类型的运算符“+”
- // 调用up(Point类型)的“+”方法,并以right作为函数的参数
- Point result = up + right;
- // 显示“Result is upright (1,1)”
- cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
- return 0;
-}
-
-///////////
-// 异常处理
-///////////
-
-// 标准库中提供了一些基本的异常类型
-// (参见http://en.cppreference.com/w/cpp/error/exception)
-// 但是,其他任何类型也可以作为一个异常被拋出
-#include <exception>
-
-// 在_try_代码块中拋出的异常可以被随后的_catch_捕获。
-try {
- // 不要用 _new_关键字在堆上为异常分配空间。
- throw std::exception("A problem occurred");
-}
-// 如果拋出的异常是一个对象,可以用常量引用来捕获它
-catch (const std::exception& ex)
-{
- std::cout << ex.what();
-// 捕获尚未被_catch_处理的所有错误
-} catch (...)
-{
- std::cout << "Unknown exception caught";
- throw; // 重新拋出异常
-}
-
-///////
-// RAII
-///////
-
-// RAII指的是“资源获取就是初始化”(Resource Allocation Is Initialization),
-// 它被视作C++中最强大的编程范式之一。
-// 简单说来,它指的是,用构造函数来获取一个对象的资源,
-// 相应的,借助析构函数来释放对象的资源。
-
-// 为了理解这一范式的用处,让我们考虑某个函数使用文件句柄时的情况:
-void doSomethingWithAFile(const char* filename)
-{
- // 首先,让我们假设一切都会顺利进行。
-
- FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
-
- doSomethingWithTheFile(fh);
- doSomethingElseWithIt(fh);
-
- fclose(fh); // 关闭文件句柄
-}
-
-// 不幸的是,随着错误处理机制的引入,事情会变得复杂。
-// 假设fopen函数有可能执行失败,
-// 而doSomethingWithTheFile和doSomethingElseWithIt会在失败时返回错误代码。
-// (虽然异常是C++中处理错误的推荐方式,
-// 但是某些程序员,尤其是有C语言背景的,并不认可异常捕获机制的作用)。
-// 现在,我们必须检查每个函数调用是否成功执行,并在问题发生的时候关闭文件句柄。
-bool doSomethingWithAFile(const char* filename)
-{
- FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
- if (fh == nullptr) // 当执行失败是,返回的指针是nullptr
- return false; // 向调用者汇报错误
-
- // 假设每个函数会在执行失败时返回false
- if (!doSomethingWithTheFile(fh)) {
- fclose(fh); // 关闭文件句柄,避免造成内存泄漏。
- return false; // 反馈错误
- }
- if (!doSomethingElseWithIt(fh)) {
- fclose(fh); // 关闭文件句柄
- return false; // 反馈错误
- }
-
- fclose(fh); // 关闭文件句柄
- return true; // 指示函数已成功执行
-}
-
-// C语言的程序员通常会借助goto语句简化上面的代码:
-bool doSomethingWithAFile(const char* filename)
-{
- FILE* fh = fopen(filename, "r");
- if (fh == nullptr)
- return false;
-
- if (!doSomethingWithTheFile(fh))
- goto failure;
-
- if (!doSomethingElseWithIt(fh))
- goto failure;
-
- fclose(fh); // 关闭文件
- return true; // 执行成功
-
-failure:
- fclose(fh);
- return false; // 反馈错误
-}
-
-// 如果用异常捕获机制来指示错误的话,
-// 代码会变得清晰一些,但是仍然有优化的余地。
-void doSomethingWithAFile(const char* filename)
-{
- FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
- if (fh == nullptr)
- throw std::exception("Could not open the file.");
-
- try {
- doSomethingWithTheFile(fh);
- doSomethingElseWithIt(fh);
- }
- catch (...) {
- fclose(fh); // 保证出错的时候文件被正确关闭
- throw; // 之后,重新抛出这个异常
- }
-
- fclose(fh); // 关闭文件
- // 所有工作顺利完成
-}
-
-// 相比之下,使用C++中的文件流类(fstream)时,
-// fstream会利用自己的析构器来关闭文件句柄。
-// 只要离开了某一对象的定义域,它的析构函数就会被自动调用。
-void doSomethingWithAFile(const std::string& filename)
-{
- // ifstream是输入文件流(input file stream)的简称
- std::ifstream fh(filename); // 打开一个文件
-
- // 对文件进行一些操作
- doSomethingWithTheFile(fh);
- doSomethingElseWithIt(fh);
-
-} // 文件已经被析构器自动关闭
-
-// 与上面几种方式相比,这种方式有着_明显_的优势:
-// 1. 无论发生了什么情况,资源(此例当中是文件句柄)都会被正确关闭。
-// 只要你正确使用了析构器,就_不会_因为忘记关闭句柄,造成资源的泄漏。
-// 2. 可以注意到,通过这种方式写出来的代码十分简洁。
-// 析构器会在后台关闭文件句柄,不再需要你来操心这些琐事。
-// 3. 这种方式的代码具有异常安全性。
-// 无论在函数中的何处拋出异常,都不会阻碍对文件资源的释放。
-
-// 地道的C++代码应当把RAII的使用扩展到各种类型的资源上,包括:
-// - 用unique_ptr和shared_ptr管理的内存
-// - 各种数据容器,例如标准库中的链表、向量(容量自动扩展的数组)、散列表等;
-// 当它们脱离作用域时,析构器会自动释放其中储存的内容。
-// - 用lock_guard和unique_lock实现的互斥
-```
-扩展阅读:
-
-* [CPP Reference](http://cppreference.com/w/cpp) 提供了最新的语法参考。
-* 可以在 [CPlusPlus](http://cplusplus.com) 找到一些补充资料。
-* 可以在 [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb)上找到涵盖语言基础和设置编码环境的教程。
+--- +language: C++ +filename: learncpp-cn.cpp +contributors: + - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] +translators: + - ["Arnie97", "https://github.com/Arnie97"] +lang: zh-cn +--- + +C++是一种系统编程语言。用它的发明者, +[Bjarne Stroustrup的话](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)来说,C++的设计目标是: + +- 成为“更好的C语言” +- 支持数据的抽象与封装 +- 支持面向对象编程 +- 支持泛型编程 + +C++提供了对硬件的紧密控制(正如C语言一样), +能够编译为机器语言,由处理器直接执行。 +与此同时,它也提供了泛型、异常和类等高层功能。 +虽然C++的语法可能比某些出现较晚的语言更复杂,它仍然得到了人们的青睞—— +功能与速度的平衡使C++成为了目前应用最广泛的系统编程语言之一。 + +```c++ +//////////////// +// 与C语言的比较 +//////////////// + +// C++_几乎_是C语言的一个超集,它与C语言的基本语法有许多相同之处, +// 例如变量和函数的声明,原生数据类型等等。 + +// 和C语言一样,在C++中,你的程序会从main()开始执行, +// 该函数的返回值应当为int型,这个返回值会作为程序的退出状态值。 +// 不过,大多数的编译器(gcc,clang等)也接受 void main() 的函数原型。 +// (参见 http://en.wikipedia.org/wiki/Exit_status 来获取更多信息) +int main(int argc, char** argv) +{ + // 和C语言一样,命令行参数通过argc和argv传递。 + // argc代表命令行参数的数量, + // 而argv是一个包含“C语言风格字符串”(char *)的数组, + // 其中每个字符串代表一个命令行参数的内容, + // 首个命令行参数是调用该程序时所使用的名称。 + // 如果你不关心命令行参数的值,argc和argv可以被忽略。 + // 此时,你可以用int main()作为函数原型。 + + // 退出状态值为0时,表示程序执行成功 + return 0; +} + +// 然而,C++和C语言也有一些区别: + +// 在C++中,字符字面量的大小是一个字节。 +sizeof('c') == 1 + +// 在C语言中,字符字面量的大小与int相同。 +sizeof('c') == sizeof(10) + + +// C++的函数原型与函数定义是严格匹配的 +void func(); // 这个函数不能接受任何参数 + +// 而在C语言中 +void func(); // 这个函数能接受任意数量的参数 + +// 在C++中,用nullptr代替C语言中的NULL +int* ip = nullptr; + +// C++也可以使用C语言的标准头文件, +// 但是需要加上前缀“c”并去掉末尾的“.h”。 +#include <cstdio> + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +/////////// +// 函数重载 +/////////// + +// C++支持函数重载,你可以定义一组名称相同而参数不同的函数。 + +void print(char const* myString) +{ + printf("String %s\n", myString); +} + +void print(int myInt) +{ + printf("My int is %d", myInt); +} + +int main() +{ + print("Hello"); // 解析为 void print(const char*) + print(15); // 解析为 void print(int) +} + +/////////////////// +// 函数参数的默认值 +/////////////////// + +// 你可以为函数的参数指定默认值, +// 它们将会在调用者没有提供相应参数时被使用。 + +void doSomethingWithInts(int a = 1, int b = 4) +{ + // 对两个参数进行一些操作 +} + +int main() +{ + doSomethingWithInts(); // a = 1, b = 4 + doSomethingWithInts(20); // a = 20, b = 4 + doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// 默认参数必须放在所有的常规参数之后。 + +void invalidDeclaration(int a = 1, int b) // 这是错误的! +{ +} + + +/////////// +// 命名空间 +/////////// + +// 命名空间为变量、函数和其他声明提供了分离的的作用域。 +// 命名空间可以嵌套使用。 + +namespace First { + namespace Nested { + void foo() + { + printf("This is First::Nested::foo\n"); + } + } // 结束嵌套的命名空间Nested +} // 结束命名空间First + +namespace Second { + void foo() + { + printf("This is Second::foo\n") + } +} + +void foo() +{ + printf("This is global foo\n"); +} + +int main() +{ + // 如果没有特别指定,就从“Second”中取得所需的内容。 + using namespace Second; + + foo(); // 显示“This is Second::foo” + First::Nested::foo(); // 显示“This is First::Nested::foo” + ::foo(); // 显示“This is global foo” +} + +//////////// +// 输入/输出 +//////////// + +// C++使用“流”来输入输出。<<是流的插入运算符,>>是流提取运算符。 +// cin、cout、和cerr分别代表 +// stdin(标准输入)、stdout(标准输出)和stderr(标准错误)。 + +#include <iostream> // 引入包含输入/输出流的头文件 + +using namespace std; // 输入输出流在std命名空间(也就是标准库)中。 + +int main() +{ + int myInt; + + // 在标准输出(终端/显示器)中显示 + cout << "Enter your favorite number:\n"; + // 从标准输入(键盘)获得一个值 + cin >> myInt; + + // cout也提供了格式化功能 + cout << "Your favorite number is " << myInt << "\n"; + // 显示“Your favorite number is <myInt>” + + cerr << "Used for error messages"; +} + +///////// +// 字符串 +///////// + +// C++中的字符串是对象,它们有很多成员函数 +#include <string> + +using namespace std; // 字符串也在std命名空间(标准库)中。 + +string myString = "Hello"; +string myOtherString = " World"; + +// + 可以用于连接字符串。 +cout << myString + myOtherString; // "Hello World" + +cout << myString + " You"; // "Hello You" + +// C++中的字符串是可变的,具有“值语义”。 +myString.append(" Dog"); +cout << myString; // "Hello Dog" + + +///////////// +// 引用 +///////////// + +// 除了支持C语言中的指针类型以外,C++还提供了_引用_。 +// 引用是一种特殊的指针类型,一旦被定义就不能重新赋值,并且不能被设置为空值。 +// 使用引用时的语法与原变量相同: +// 也就是说,对引用类型进行解引用时,不需要使用*; +// 赋值时也不需要用&来取地址。 + +using namespace std; + +string foo = "I am foo"; +string bar = "I am bar"; + + +string& fooRef = foo; // 建立了一个对foo的引用。 +fooRef += ". Hi!"; // 通过引用来修改foo的值 +cout << fooRef; // "I am foo. Hi!" + +// 这句话的并不会改变fooRef的指向,其效果与“foo = bar”相同。 +// 也就是说,在执行这条语句之后,foo == "I am bar"。 +fooRef = bar; + +const string& barRef = bar; // 建立指向bar的常量引用。 +// 和C语言中一样,(指针和引用)声明为常量时,对应的值不能被修改。 +barRef += ". Hi!"; // 这是错误的,不能修改一个常量引用的值。 + +/////////////////// +// 类与面向对象编程 +/////////////////// + +// 有关类的第一个示例 +#include <iostream> + +// 声明一个类。 +// 类通常在头文件(.h或.hpp)中声明。 +class Dog { + // 成员变量和成员函数默认情况下是私有(private)的。 + std::string name; + int weight; + +// 在这个标签之后,所有声明都是公有(public)的, +// 直到重新指定“private:”(私有继承)或“protected:”(保护继承)为止 +public: + + // 默认的构造器 + Dog(); + + // 这里是成员函数声明的一个例子。 + // 可以注意到,我们在此处使用了std::string,而不是using namespace std + // 语句using namespace绝不应当出现在头文件当中。 + void setName(const std::string& dogsName); + + void setWeight(int dogsWeight); + + // 如果一个函数不对对象的状态进行修改, + // 应当在声明中加上const。 + // 这样,你就可以对一个以常量方式引用的对象执行该操作。 + // 同时可以注意到,当父类的成员函数需要被子类重写时, + // 父类中的函数必须被显式声明为_虚函数(virtual)_。 + // 考虑到性能方面的因素,函数默认情况下不会被声明为虚函数。 + virtual void print() const; + + // 函数也可以在class body内部定义。 + // 这样定义的函数会自动成为内联函数。 + void bark() const { std::cout << name << " barks!\n" } + + // 除了构造器以外,C++还提供了析构器。 + // 当一个对象被删除或者脱离其定义域时,它的析构函数会被调用。 + // 这使得RAII这样的强大范式(参见下文)成为可能。 + // 为了衍生出子类来,基类的析构函数必须定义为虚函数。 + virtual ~Dog(); + +}; // 在类的定义之后,要加一个分号 + +// 类的成员函数通常在.cpp文件中实现。 +void Dog::Dog() +{ + std::cout << "A dog has been constructed\n"; +} + +// 对象(例如字符串)应当以引用的形式传递, +// 对于不需要修改的对象,最好使用常量引用。 +void Dog::setName(const std::string& dogsName) +{ + name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} + +// 虚函数的virtual关键字只需要在声明时使用,不需要在定义时重复 +void Dog::print() const +{ + std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; +} + +void Dog::~Dog() +{ + std::cout << "Goodbye " << name << "\n"; +} + +int main() { + Dog myDog; // 此时显示“A dog has been constructed” + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.print(); // 显示“Dog is Barkley and weighs 10 kg” + return 0; +} // 显示“Goodbye Barkley” + +// 继承: + +// 这个类继承了Dog类中的公有(public)和保护(protected)对象 +class OwnedDog : public Dog { + + void setOwner(const std::string& dogsOwner) + + // 重写OwnedDogs类的print方法。 + // 如果你不熟悉子类多态的话,可以参考这个页面中的概述: + // http://zh.wikipedia.org/wiki/%E5%AD%90%E7%B1%BB%E5%9E%8B + + // override关键字是可选的,它确保你所重写的是基类中的方法。 + void print() const override; + +private: + std::string owner; +}; + +// 与此同时,在对应的.cpp文件里: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // 调用基类Dog中的print方法 + // "Dog is <name> and weights <weight>" + + std::cout << "Dog is owned by " << owner << "\n"; + // "Dog is owned by <owner>" +} + +///////////////////// +// 初始化与运算符重载 +///////////////////// + +// 在C++中,通过定义一些特殊名称的函数, +// 你可以重载+、-、*、/等运算符的行为。 +// 当运算符被使用时,这些特殊函数会被调用,从而实现运算符重载。 + +#include <iostream> +using namespace std; + +class Point { +public: + // 可以以这样的方式为成员变量设置默认值。 + double x = 0; + double y = 0; + + // 定义一个默认的构造器。 + // 除了将Point初始化为(0, 0)以外,这个函数什么都不做。 + Point() { }; + + // 下面使用的语法称为初始化列表, + // 这是初始化类中成员变量的正确方式。 + Point (double a, double b) : + x(a), + y(b) + { /* 除了初始化成员变量外,什么都不做 */ } + + // 重载 + 运算符 + Point operator+(const Point& rhs) const; + + // 重载 += 运算符 + Point& operator+=(const Point& rhs); + + // 增加 - 和 -= 运算符也是有意义的,但这里不再赘述。 +}; + +Point Point::operator+(const Point& rhs) const +{ + // 创建一个新的点, + // 其横纵坐标分别为这个点与另一点在对应方向上的坐标之和。 + return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () { + Point up (0,1); + Point right (1,0); + // 这里使用了Point类型的运算符“+” + // 调用up(Point类型)的“+”方法,并以right作为函数的参数 + Point result = up + right; + // 显示“Result is upright (1,1)” + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +/////////// +// 异常处理 +/////////// + +// 标准库中提供了一些基本的异常类型 +// (参见http://en.cppreference.com/w/cpp/error/exception) +// 但是,其他任何类型也可以作为一个异常被拋出 +#include <exception> + +// 在_try_代码块中拋出的异常可以被随后的_catch_捕获。 +try { + // 不要用 _new_关键字在堆上为异常分配空间。 + throw std::exception("A problem occurred"); +} +// 如果拋出的异常是一个对象,可以用常量引用来捕获它 +catch (const std::exception& ex) +{ + std::cout << ex.what(); +// 捕获尚未被_catch_处理的所有错误 +} catch (...) +{ + std::cout << "Unknown exception caught"; + throw; // 重新拋出异常 +} + +/////// +// RAII +/////// + +// RAII指的是“资源获取就是初始化”(Resource Allocation Is Initialization), +// 它被视作C++中最强大的编程范式之一。 +// 简单说来,它指的是,用构造函数来获取一个对象的资源, +// 相应的,借助析构函数来释放对象的资源。 + +// 为了理解这一范式的用处,让我们考虑某个函数使用文件句柄时的情况: +void doSomethingWithAFile(const char* filename) +{ + // 首先,让我们假设一切都会顺利进行。 + + FILE* fh = fopen(filename, "r"); // 以只读模式打开文件 + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + + fclose(fh); // 关闭文件句柄 +} + +// 不幸的是,随着错误处理机制的引入,事情会变得复杂。 +// 假设fopen函数有可能执行失败, +// 而doSomethingWithTheFile和doSomethingElseWithIt会在失败时返回错误代码。 +// (虽然异常是C++中处理错误的推荐方式, +// 但是某些程序员,尤其是有C语言背景的,并不认可异常捕获机制的作用)。 +// 现在,我们必须检查每个函数调用是否成功执行,并在问题发生的时候关闭文件句柄。 +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // 以只读模式打开文件 + if (fh == nullptr) // 当执行失败是,返回的指针是nullptr + return false; // 向调用者汇报错误 + + // 假设每个函数会在执行失败时返回false + if (!doSomethingWithTheFile(fh)) { + fclose(fh); // 关闭文件句柄,避免造成内存泄漏。 + return false; // 反馈错误 + } + if (!doSomethingElseWithIt(fh)) { + fclose(fh); // 关闭文件句柄 + return false; // 反馈错误 + } + + fclose(fh); // 关闭文件句柄 + return true; // 指示函数已成功执行 +} + +// C语言的程序员通常会借助goto语句简化上面的代码: +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); + if (fh == nullptr) + return false; + + if (!doSomethingWithTheFile(fh)) + goto failure; + + if (!doSomethingElseWithIt(fh)) + goto failure; + + fclose(fh); // 关闭文件 + return true; // 执行成功 + +failure: + fclose(fh); + return false; // 反馈错误 +} + +// 如果用异常捕获机制来指示错误的话, +// 代码会变得清晰一些,但是仍然有优化的余地。 +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // 以只读模式打开文件 + if (fh == nullptr) + throw std::exception("Could not open the file."); + + try { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) { + fclose(fh); // 保证出错的时候文件被正确关闭 + throw; // 之后,重新抛出这个异常 + } + + fclose(fh); // 关闭文件 + // 所有工作顺利完成 +} + +// 相比之下,使用C++中的文件流类(fstream)时, +// fstream会利用自己的析构器来关闭文件句柄。 +// 只要离开了某一对象的定义域,它的析构函数就会被自动调用。 +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream是输入文件流(input file stream)的简称 + std::ifstream fh(filename); // 打开一个文件 + + // 对文件进行一些操作 + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // 文件已经被析构器自动关闭 + +// 与上面几种方式相比,这种方式有着_明显_的优势: +// 1. 无论发生了什么情况,资源(此例当中是文件句柄)都会被正确关闭。 +// 只要你正确使用了析构器,就_不会_因为忘记关闭句柄,造成资源的泄漏。 +// 2. 可以注意到,通过这种方式写出来的代码十分简洁。 +// 析构器会在后台关闭文件句柄,不再需要你来操心这些琐事。 +// 3. 这种方式的代码具有异常安全性。 +// 无论在函数中的何处拋出异常,都不会阻碍对文件资源的释放。 + +// 地道的C++代码应当把RAII的使用扩展到各种类型的资源上,包括: +// - 用unique_ptr和shared_ptr管理的内存 +// - 各种数据容器,例如标准库中的链表、向量(容量自动扩展的数组)、散列表等; +// 当它们脱离作用域时,析构器会自动释放其中储存的内容。 +// - 用lock_guard和unique_lock实现的互斥 +``` +扩展阅读: + +* [CPP Reference](http://cppreference.com/w/cpp) 提供了最新的语法参考。 +* 可以在 [CPlusPlus](http://cplusplus.com) 找到一些补充资料。 +* 可以在 [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb)上找到涵盖语言基础和设置编码环境的教程。 diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown index dd4445f7..851f2981 100644 --- a/zh-cn/c-cn.html.markdown +++ b/zh-cn/c-cn.html.markdown @@ -474,7 +474,7 @@ void testFunc() { // 用户自定义类型和结构 /////////////////////////////////////// -// Typedefs可以创建类型别名 +// typedef 可以创建类型别名 typedef int my_type; my_type my_type_var = 0; diff --git a/zh-cn/cobol-cn.html.markdown b/zh-cn/cobol-cn.html.markdown new file mode 100644 index 00000000..08eb36fb --- /dev/null +++ b/zh-cn/cobol-cn.html.markdown @@ -0,0 +1,192 @@ +--- +language: COBOL +filename: learn-cn.COB +contributors: + - ["Hyphz", "http://github.com/hyphz/"] +translators: + - ["GOLGO11", "https://github.com/GOLGO11/"] +lang: zh-cn +--- +COBOL是一门面向商业的语言,它从1960年最初设计以来被修订过数次。它被宣称仍然有超过80%的机构在使用它。 + +```cobol + *COBOL. 最好是按照它1985年的标准来编程。 + *用附带GnuCOBOL编译器的OpenCobolIDE 4.7.6来编译。 + + *COBOL在老版(COBOL-85)和新版(COBOL-2002以及COBOL-2014)之间有明显的差别。 + *老版COBOL要求编码的前一到六列是空着的(它们被用来存储穿孔卡片的序列号... + *第七列的一个“*”符号表示注释的开始。 + *在老版COBOL中,一条以*开头的注释最长只能占一行, + *新版COBOL不需要额外的列来补序列号,并且用“*>" 来注释,允许在行中开始注释 + *老版COBOL也强加了对最大行长度的限制 + *关键字在老版COBOL中必须大写, + *但在新版COBOL中不区分大小写 + *虽然新版COBOL允许你编写大小写混合的代码 + *但是在大多数情况下编写COBOL代码时全用大写字符 + *大多数专业的COBOL开发者都是这么做的。 + *COBOL语句以句点结尾。 + + *COBOL代码被拆成了四个部。 + *各部按顺序,它们是: + *IDENTIFICATION DIVSION.(标识部) + *ENVIRONMENT DIVISION.(环境部) + *DATA DIVISION.(数据部) + *PROCEDURE DIVISION.(过程部) + + *第一步,我们必须给我们的程序一个ID。 + *Identification division 也能包含其他的值, + *但它们都只是程序的元数据。Program-id是唯一一个必须给出的值。 + IDENTIFICATION DIVISION. + PROGRAM-ID. LEARN. + AUTHOR. JOHN DOE. + DATE-WRITTEN. 05/02/2020. + + *让我们来声明一些变量。 + *我们要在DATA DIVISION的WORKING-STORAGE节来完成这个事情。 + *每个数据项(又名变量)从一个级别编号开始。 + *然后是数据项的名字,后边再跟着一个picture关键字, + *来描述这个变量将要包含的数据的类型。 + *几乎所有的COBOL开发者都会把PICTURE简写为PIC。 + *A代表字母,X代表字母和数字,9代表数字。 + + *举例: + 01 MYNAME PIC xxxxxxxxxx. *> 十个字符的字符串。 + + *但是逐个数那些x会导致错误, + *所以以上代码可以,并且应该 + *这样重写: + 01 MYNAME PIC X(10). + + *这是几个更多的例子: + 01 AGE PIC 9(3). *> 数字最多三位 + 01 LAST_NAME PIC X(10). *> 字符串最多十个字符 + + *在COBOL里,一行中多个空格和一个空格的效果是一样的, 所以通常 + *情况下都用多个空格排列代码来便于 + *其他的开发者阅读。 + 01 inyear picture s9(7). *> S 使数字为正数. + *> 括号里意思是重复7次9, + *> 即六位数字(不是数组) + + *现在让我们来写一点儿代码。这是一个简单的Hello World程序。 + IDENTIFICATION DIVISION. + PROGRAM-ID. HELLO. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 THE-MESSAGE PIC X(20). + PROCEDURE DIVSION. + DISPLAY "STARTING PROGRAM". + MOVE "HELLO WORLD" TO THE-MESSAGE. + DISPLAY THE-MESSAGE. + STOP RUN. + + *以上的代码会输出: + *STARTING PROGRAM + *HELLO WORLD + + + + ********用COBOL可以做数学运算*************** + ADD 1 TO AGE GIVING NEW-AGE. + SUBTRACT 1 FROM COUNT. + DIVIDE VAR-1 INTO VAR-2 GIVING VAR-3. + COMPUTE TOTAL-COUNT = COUNT1 PLUS COUNT2. + + + *********PERFORM******************** + *PERFORM关键字允许你跳到代码中其他特殊的代码段, + *当这段特殊的代码被执行完后继续回来执行下面的可执行语句。 + *你必须把PERFORM这个词写完整,不可以缩写它。 + + IDENTIFICATION DIVISION. + PROGRAM-ID. HELLOCOBOL. + + PROCEDURE DIVISION. + FIRST-PARA. + DISPLAY 'THIS IS IN FIRST-PARA'. + PERFORM THIRD-PARA THRU FOURTH-PARA. *>跳过second-para,执行3rd&4th + *> 之后当third和fourth执行完, + *> 回到这里继续往下执行直到遇到STOP RUN. + + SECOND-PARA. + DISPLAY 'THIS IS IN SECOND-PARA'. + STOP RUN. + + THIRD-PARA. + DISPLAY 'THIS IS IN THIRD-PARA'. + + FOURTH-PARA. + DISPLAY 'THIS IS IN FOURTH-PARA'. + + + *当你编译执行以上程序时,它会生成以下结果: + THIS IS IN FIRST-PARA + THIS IS IN THIRD-PARA + THIS IS IN FOURTH-PARA + THIS IS IN SECOND-PARA + + + **********用STRING关键字把变量组合到一起************ + + *现在是时候学习两个类似的COBOL动词了:string和unstring。. + + *string动词经常被用来连接两个或多个字符串(把它们拼在一起)。 + *没什么特别的,Unstring被用来把一个字符串拆分成两个或多个更小的字符串。 + *当你在程序中使用string或unstring时不要忘记使用”delimited by“,这个很重要。 + + IDENTIFICATION DIVISION. + PROGRAM-ID. LEARNING. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FULL-NAME PIC X(20). + 01 FIRST-NAME PIC X(13) VALUE "BOB GIBBERISH". + 01 LAST-NAME PIC X(5) VALUE "COBB". + PROCEDURE DIVISION. + STRING FIRST-NAME DELIMITED BY SPACE + " " + LAST-NAME DELIMITED BY SIZE + INTO FULL-NAME + END-STRING. + DISPLAY "THE FULL NAME IS: "FULL-NAME. + STOP RUN. + + + *以上代码将会输出: + THE FULL NAME IS: BOB COBB + + + *让我们来看看为什么是这样。 + + *首先,我们在DATA DIVISION声明了所有的变量, + *包括我们想存储string命令生成的新字符串用到的的变量。 + + *这个操作过程在PROCEDURE DIVISION完成。 + *我们从STRING 关键字开始,到END-STRING结束。 + *在它们之间我们列出我们想要组合变量形成更大的主变量的过程。 + *这里,我们组合了FIRST-NAME, 一个空格和LAST-NAME。 + + *跟在FIRST-NAME和LAST-NAME后面的DELIMITED BY短语告诉程序我们想要在各自变量上截取字符的规则。 + *DELIMITED BY SPACE告诉程序从最开始截取字符直到遇到一个空格。 + *DELIMITED BY SIZE告诉程序截取字符的完整长度。 + *我们在FIRST-NAME后面使用DELIMITED BY SPACE,字符串中的GIBBERISH部分就被忽略了。 + + *为了更清楚,改变代码中的第10行如下: + + STRING FIRST-NAME DELIMITED BY SIZE + + *然后重新执行程序. 这次的输出变成: + + THE FULL NAME IS: BOB GIBBERISH COBB + + + + + + +``` + +## 想了解更多吗? + +* [GnuCOBOL](https://sourceforge.net/projects/open-cobol/) + diff --git a/zh-cn/crystal-cn.html.markdown b/zh-cn/crystal-cn.html.markdown index 14805114..b69ce688 100644 --- a/zh-cn/crystal-cn.html.markdown +++ b/zh-cn/crystal-cn.html.markdown @@ -564,4 +564,4 @@ ex #=> "ex2" - [官方网站](https://crystal-lang.org/) - [官方文档](https://crystal-lang.org/docs/overview/) - [在线运行代码](https://play.crystal-lang.org/#/cr) -- [Github仓库](https://github.com/crystal-lang/crystal) +- [GitHub仓库](https://github.com/crystal-lang/crystal) diff --git a/zh-cn/csharp-cn.html.markdown b/zh-cn/csharp-cn.html.markdown index 0bad34ce..b6cc70c0 100644 --- a/zh-cn/csharp-cn.html.markdown +++ b/zh-cn/csharp-cn.html.markdown @@ -5,45 +5,64 @@ contributors: - ["Max Yankov", "https://github.com/golergka"] - ["Melvyn Laïly", "http://x2a.yt"] - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] + - ["Wouter Van Schandevijl", "http://github.com/laoujin"] + - ["Jo Pearce", "http://github.com/jdpearce"] + - ["Chris Zimmerman", "https://github.com/chriszimmerman"] + - ["Shawn McGuire", "https://github.com/bigbash"] translators: - ["Jakukyo Friel", "http://weakish.github.io"] + - ["CatfishWen", "http://catfishwen.github.io"] filename: LearnCSharp-cn.cs lang: zh-cn --- +C#是一种优雅且类型安全的面向对象的语言,使开发人员能够构建运行在跨平台的.NET框架上,安全且健壮的应用程序。 -C#是一个优雅的、类型安全的面向对象语言。使用C#,开发者可以在.NET框架下构建安全、健壮的应用程序。 - -[更多关于C#的介绍](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx) +[更多关于C#的介绍](https://learn.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/) ```c# // 单行注释以 // 开始 /* 多行注释是这样的 */ + /// <summary> -/// XML文档注释 +/// 这是 XML文档注释 +/// 可用于生成外部文档或在 IDE 中提供上下文帮助 /// </summary> +/// <param name="firstParam">这是 firstParam 参数的文档</param> +/// <returns>这是函数返回值的信息</returns> +public void MethodOrClassOrOtherWithParsableHelp(string firstParam) { } -// 声明应用用到的命名空间 +// 声明这段源码使用到的命名空间 +// 下面的命名空间都是标准 .NET Framework 类库的一部分 using System; using System.Collections.Generic; -using System.Data.Entity; using System.Dynamic; using System.Linq; -using System.Linq.Expressions; using System.Net; using System.Threading.Tasks; using System.IO; -// 定义作用域,将代码组织成包 +// 但是这个并不是标准类库: +using System.Data.Entity; +// 为了在下方使用它,你需要添加一个 dll 引用 +// 你可以使用 NuGet 包管理器进行安装 +// `Install-Package EntityFramework` + +// 命名空间 Namespaces 可用于将一定的代码组织为 “包” 或者 “模块” +// 你可以在其他文件中这样引用:using Learning.CSharp; + +// 在 C# 10 以后,你也可以这样定义命名空间。这被称为 file-scoped namespaces(文件范围的命名空间). +// namespace Learning.CSharp; + namespace Learning { // 每个 .cs 文件至少需要包含一个和文件名相同的类 - // 你可以不这么干,但是这样不好。 + // 你可以不这么干,但是这样并不推荐。 public class LearnCSharp { - // 基本语法 - 如果你以前用过 Java 或 C++ 的话,可以直接跳到后文「有趣的特性」 + // 基本语法 - 如果你以前用过 Java 或 C++ 的话,可以直接跳到后文「有趣的特性」 public static void Syntax() { // 使用 Console.WriteLine 打印信息 @@ -53,7 +72,7 @@ namespace Learning " Double: " + 3.14 + " Boolean: " + true); - // 使用 Console.Write 打印,不带换行符号 + // 使用 Console.Write 打印将不会换行 Console.Write("Hello "); Console.Write("World"); @@ -113,7 +132,7 @@ namespace Learning char charFromString = fooString[1]; // => 'e' // 字符串不可修改: fooString[1] = 'X' 是行不通的; - // 根据当前的locale设定比较字符串,大小写不敏感 + // 根据当前的区域格式设置比较字符串,大小写不敏感 string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); // 基于sprintf的字符串格式化 @@ -123,12 +142,13 @@ namespace Learning DateTime fooDate = DateTime.Now; Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); - // 使用 @ 符号可以创建跨行的字符串。使用 "" 来表示 " + // 逐字字符串 + // 使用 @ 符号可以创建跨行的字符串。使用 "" 来表示 " string bazString = @"Here's some stuff on a new line! ""Wow!"", the masses cried"; - // 使用const或read-only定义常量 - // 常量在编译期演算 + // 使用 const 或 read-only 定义常量 + // 常量在编译阶段演算 const int HOURS_I_WORK_PER_WEEK = 9001; /////////////////////////////////////////////////// @@ -136,7 +156,7 @@ on a new line! ""Wow!"", the masses cried"; /////////////////////////////////////////////////// // 数组 - 从0开始计数 - // 声明数组时需要确定数组长度 + // 声明数组时需要指定数组长度 // 声明数组的格式如下: // <datatype>[] <var name> = new <datatype>[<array size>]; int[] intArray = new int[10]; @@ -155,8 +175,8 @@ on a new line! ""Wow!"", the masses cried"; // List<datatype> <var name> = new List<datatype>(); List<int> intList = new List<int>(); List<string> stringList = new List<string>(); - List<int> z = new List<int> { 9000, 1000, 1337 }; // i - // <>用于泛型 - 参考下文 + List<int> z = new List<int> { 9000, 1000, 1337 }; // 初始化 + // <> 用于泛型 - 参考下文 // 列表无默认值 // 访问列表元素时必须首先添加元素 @@ -164,18 +184,18 @@ on a new line! ""Wow!"", the masses cried"; Console.WriteLine("intList @ 0: " + intList[0]); // 其他数据结构: - // 堆栈/队列 - // 字典 (哈希表的实现) - // 哈希集合 - // 只读集合 - // 元组 (.Net 4+) + // Stack 堆栈 / Queue 队列 + // Dictionary 字典 (哈希表的实现) + // HashSet 哈希集合 + // Read-only Collections 只读集合 + // Tuple 元组 (.Net 4+) /////////////////////////////////////// // 操作符 /////////////////////////////////////// Console.WriteLine("\n->Operators"); - int i1 = 1, i2 = 2; // 多重声明的简写形式 + int i1 = 1, i2 = 2; // 声明多个变量的简写形式 // 算术直截了当 Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 @@ -214,7 +234,7 @@ on a new line! ""Wow!"", the masses cried"; /////////////////////////////////////// Console.WriteLine("\n->Control Structures"); - // 类似C的if语句 + // 类似 C 的 if 语句 int j = 10; if (j == 10) { @@ -239,7 +259,7 @@ on a new line! ""Wow!"", the masses cried"; int fooWhile = 0; while (fooWhile < 100) { - //迭代 100 次, fooWhile 0->99 + // 迭代 100 次, fooWhile 0->99 fooWhile++; } @@ -247,14 +267,21 @@ on a new line! ""Wow!"", the masses cried"; int fooDoWhile = 0; do { - //迭代 100 次, fooDoWhile 0->99 + // 迭代 100 次, fooDoWhile 0->99 + if (false) + continue; // 跳过本次迭代 + fooDoWhile++; + + if (fooDoWhile == 50) + break; // 结束整个循环 + } while (fooDoWhile < 100); - //for 循环结构 => for(<初始条件>; <条件>; <步>) + // for 循环结构 => for(<初始条件>; <条件>; <步>) for (int fooFor = 0; fooFor < 10; fooFor++) { - //迭代10次, fooFor 0->9 + // 迭代10次, fooFor 0->9 } // foreach循环 @@ -269,7 +296,7 @@ on a new line! ""Wow!"", the masses cried"; } // Switch 语句 - // switch 适用于 byte、short、char和int 数据类型。 + // switch 适用于 byte、short、char 和 int 数据类型。 // 同样适用于可枚举的类型 // 包括字符串类, 以及一些封装了原始值的类: // Character、Byte、Short和Integer。 @@ -307,46 +334,63 @@ on a new line! ""Wow!"", the masses cried"; // 转换字符串为整数 // 转换失败会抛出异常 - int.Parse("123");//返回整数类型的"123" + int.Parse("123"); // 返回整数类型的"123" - // TryParse会尝试转换类型,失败时会返回缺省类型 + // TryParse 会尝试转换类型,失败时会返回缺省类型 // 例如 0 int tryInt; if (int.TryParse("123", out tryInt)) // Funciton is boolean Console.WriteLine(tryInt); // 123 // 转换整数为字符串 - // Convert类提供了一系列便利转换的方法 + // Convert 类提供了一系列方便转换类型的方法 + + // 比如 字符串 与 int 之间 + + // 最佳方法 + bool result = int.TryParse(string, out var integer) + int.Parse(string); + + // 不推荐 Convert.ToString(123); - // or + + // Int 到字符串 tryInt.ToString(); + + // 转换 + // 显式转换 decimal 类型的 15 为 int 类型 + // 然后隐式转换为 long 类型 + long x = (int) 15M; } /////////////////////////////////////// - // 类 + // 类 - 请参阅文件末尾的定义 /////////////////////////////////////// public static void Classes() { // 参看文件尾部的对象声明 - // 使用new初始化对象 + // 使用 new 初始化对象 Bicycle trek = new Bicycle(); // 调用对象的方法 - trek.SpeedUp(3); // 你应该一直使用setter和getter方法 + trek.SpeedUp(3); // 你应该一直使用 setter 和 getter 方法 trek.Cadence = 100; // 查看对象的信息. Console.WriteLine("trek info: " + trek.Info()); - // 实例化一个新的Penny Farthing + // 实例化一个新的 Penny Farthing 对象 PennyFarthing funbike = new PennyFarthing(1, 10); Console.WriteLine("funbike info: " + funbike.Info()); Console.Read(); } // 结束main方法 - // 终端程序 终端程序必须有一个main方法作为入口 + // record 在 C# 9 及以后可用, 这基本上是类的语法糖. record 对象是不可变的 immutable*. + public record ARecord(string Csharp); + + // 终端程序入口 终端程序必须有一个 main 方法作为入口 public static void Main(string[] args) { OtherInterestingFeatures(); @@ -359,11 +403,11 @@ on a new line! ""Wow!"", the masses cried"; // 默认方法签名 public // 可见性 - static // 允许直接调用类,无需先创建实例 - int, //返回值 + static // 允许从类直接调用,无需先创建实例 + int // 返回值类型 MethodSignatures( - int maxCount, // 第一个变量,类型为整型 - int count = 0, // 如果没有传入值,则缺省值为0 + int maxCount, // 第一个参数,类型为整型 + int count = 0, // 如果没有传入值,则缺省值为 0 int another = 3, params string[] otherParams // 捕获其他参数 ) @@ -371,17 +415,22 @@ on a new line! ""Wow!"", the masses cried"; return -1; } - // 方法可以重名,只要签名不一样 - public static void MethodSignature(string maxCount) + // 方法可以重名,只要方法签名不一样 + // 一个只有返回值类型不同的方法 + public static void MethodSignatures( + ref int maxCount, // 通过引用传递 + out int count) { + // 通过 'count' 参数传入的值将在该方法外保留值 15 + count = 15; // 必须在离开方法之前为 out 参数赋值 } - //泛型 - // TKey和TValue类由用用户调用函数时指定。 - // 以下函数模拟了Python的SetDefault + // 泛型 + // TKey 和 TValue 由用户调用方法时指定 + // 以下函数模拟了 Python 的 SetDefault public static TValue SetDefault<TKey, TValue>( - IDictionary<TKey, TValue> dictionary, - TKey key, + IDictionary<TKey, TValue> dictionary, + TKey key, TValue defaultItem) { TValue result; @@ -393,55 +442,125 @@ on a new line! ""Wow!"", the masses cried"; // 你可以限定传入值的范围 public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int> { - // 我们可以进行迭代,因为T是可枚举的 + // 我们可以进行迭代,因为 T 是可枚举的 foreach (var item in toPrint) - // ittm为整数 + // item 为整数 Console.WriteLine(item.ToString()); } + // YIELD + // 使用 "yield" 关键字表明它出现的方法是一个迭代器 Iterator + // (这意味着你可以在 foreach 循环中使用它) + public static IEnumerable<int> YieldCounter(int limit = 10) + { + for (var i = 0; i < limit; i++) + yield return i; + } + + // 你可以这样调用它 + public static void PrintYieldCounterToConsole() + { + foreach (var counter in YieldCounter()) + Console.WriteLine(counter); + } + + // 你可以在一个方法中使用多个 "yield return" + public static IEnumerable<int> ManyYieldCounter() + { + yield return 0; + yield return 1; + yield return 2; + yield return 3; + } + + // 你也可以使用 "yield break" 停止该迭代器 + // 此方法只会返回从 0 到 limit 的一半值。 + public static IEnumerable<int> YieldCounterWithBreak(int limit = 10) + { + for (var i = 0; i < limit; i++) + { + if (i > limit / 2) yield break; + yield return i; + } + } + public static void OtherInterestingFeatures() { - // 可选参数 + // 可选参数 MethodSignatures(3, 1, 3, "Some", "Extra", "Strings"); MethodSignatures(3, another: 3); // 显式指定参数,忽略可选参数 + // 使用 ref 和 out 参数 + int maxCount = 0, count; // ref 参数必须有值 + MethodSignatures(ref maxCount, out count); + // 扩展方法 int i = 3; - i.Print(); // 参见下面的定义 + i.Print(); // 参见下面的定义 - // 可为null的类型 对数据库交互、返回值很有用 + // 可为 null 的类型 对数据库交互、返回值很有用 // 任何值类型 (i.e. 不为类) 添加后缀 ? 后会变为可为null的值 // <类型>? <变量名> = <值> int? nullable = null; // Nullable<int> 的简写形式 Console.WriteLine("Nullable variable: " + nullable); bool hasValue = nullable.HasValue; // 不为null时返回真 + // ?? 是用于指定默认值的语法糖 // 以防变量为null的情况 int notNullable = nullable ?? 0; // 0 + // ?. 是另一个可空类型的操作符 - 简写 null 检查 + nullable?.Print(); // 当可空类型值不为 null 的时候调用 Print() 拓展方法 + // 变量类型推断 - 你可以让编译器推断变量类型: var magic = "编译器确定magic是一个字符串,所以仍然是类型安全的"; - // magic = 9; // 不工作,因为magic是字符串,而不是整数。 + // magic = 9; // 不工作,因为magic是字符串,而不是整数。 // 泛型 // - var phonebook = new Dictionary<string, string>() { + var phonebook = new Dictionary<string, string>() { {"Sarah", "212 555 5555"} // 在电话簿中加入新条目 }; - // 调用上面定义为泛型的SETDEFAULT - Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // 没有电话 - // 你不用指定TKey、TValue,因为它们会被隐式地推导出来 + // 调用上面定义为泛型的 SETDEFAULT + Console.WriteLine(SetDefault<string, string>(phonebook, "Shaun", "No Phone")); // No Phone + // 你不用指定 TKey、TValue 的类型 + // 因为它们会被隐式地推导出来 Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555 // lambda表达式 - 允许你用一行代码搞定函数 Func<int, int> square = (x) => x * x; // 最后一项为返回值 Console.WriteLine(square(3)); // 9 - // 可抛弃的资源管理 - 让你很容易地处理未管理的资源 - // 大多数访问未管理资源 (文件操作符、设备上下文, etc.)的对象 - // 都实现了IDisposable接口。 - // using语句会为你清理IDisposable对象。 + // 错误处理 - 应对不确定的世界 + try + { + var funBike = PennyFarthing.CreateWithGears(6); + + // 将不再执行,因为 CreateWithGears 抛出异常 + string some = ""; + if (true) some = null; + some.ToLower(); // 抛出 NullReferenceException + } + catch (NotSupportedException) + { + Console.WriteLine("Not so much fun now!"); + } + catch (Exception ex) // 捕获所有其他异常 + { + throw new ApplicationException("It hit the fan", ex); + // throw; // 重新抛出异常并保留调用堆栈 + } + // catch { } // 捕获所有没有捕获的异常 + finally + { + // 在 try 或 catch 之后执行 + } + + // 可抛弃的资源管理 - 让你很容易地处理未托管的资源 + // 大多数访问未托管资源 (文件句柄、设备上下文, etc.) 的对象 + // 都实现了 IDisposable 接口。 + // using语句会为你清理 IDisposable 对象 using (StreamWriter writer = new StreamWriter("log.txt")) { writer.WriteLine("这里没有什么可疑的东西"); @@ -450,29 +569,23 @@ on a new line! ""Wow!"", the masses cried"; } // 并行框架 - // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx - var websites = new string[] { - "http://www.google.com", "http://www.reddit.com", - "http://www.shaunmccarthy.com" - }; - var responses = new Dictionary<string, string>(); - - // 为每个请求新开一个线程 - // 在运行下一步前合并结果 - Parallel.ForEach(websites, - new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads - website => - { - // Do something that takes a long time on the file - using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + // https://learn.microsoft.com/zh-cn/dotnet/standard/parallel-programming/data-parallelism-task-parallel-library + + var words = new List<string> {"dog", "cat", "horse", "pony"}; + + Parallel.ForEach(words, + new ParallelOptions() { MaxDegreeOfParallelism = 4 }, + word => { - responses[website] = r.ContentType; + Console.WriteLine(word); } - }); + ); - // 直到所有的请求完成后才会运行下面的代码 - foreach (var key in responses.Keys) - Console.WriteLine("{0}:{1}", key, responses[key]); + // 运行它会产生不同的输出 + // 因为每个线程在不同的时间完成 + // 一些可能的输出是: + // cat dog horse pony + // dog horse pony cat // 动态对象(配合其他语言使用很方便) dynamic student = new ExpandoObject(); @@ -486,10 +599,10 @@ on a new line! ""Wow!"", the masses cried"; // IQUERYABLE<T> - 几乎所有的集合都实现了它, // 带给你 Map / Filter / Reduce 风格的方法 var bikes = new List<Bicycle>(); - bikes.Sort(); // Sorts the array + bikes.Sort(); // 排序 array bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // 根据车轮数排序 var result = bikes - .Where(b => b.Wheels > 3) // 筛选 - 可以连锁使用 (返回IQueryable) + .Where(b => b.Wheels > 3) // 筛选 - 可以连锁使用 (返回 IQueryable) .Where(b => b.IsBroken && b.HasTassles) .Select(b => b.ToString()); // Map - 这里我们使用了select,所以结果是IQueryable<string> @@ -502,19 +615,19 @@ on a new line! ""Wow!"", the masses cried"; Console.WriteLine(bikeSummary.Name); // ASPARALLEL - // 邪恶的特性 —— 组合了linq和并行操作 + // 这就是事情开始棘手的地方 —— 组合了 linq 和并行操作 var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); // 以上代码会并发地运行。会自动新开线程,分别计算结果。 // 适用于多核、大数据量的场景。 - // LINQ - 将IQueryable<T>映射到存储,延缓执行 + // LINQ - 映射一组 IQueryable<T> 对象,并延迟执行 // 例如 LinqToSql 映射数据库, LinqToXml 映射XML文档 var db = new BikeRespository(); - // 执行被延迟了,这对于查询数据库来说很好 + // 执行被延迟了,这对于查询数据库来说非常好 var filter = db.Bikes.Where(b => b.HasTassles); // 不运行查询 if (42 > 6) // 你可以不断地增加筛选,包括有条件的筛选,例如用于“高级搜索”功能 - filter = filter.Where(b => b.IsBroken); // 不运行查询 + filter = filter.Where(b => b.IsBroken); // 不运行查询 var query = filter .OrderBy(b => b.Wheels) @@ -541,15 +654,64 @@ on a new line! ""Wow!"", the masses cried"; Console.WriteLine(obj.ToString()); } } + + + // 委托 和 事件 + public class DelegateTest + { + public static int count = 0; + public static int Increment() + { + // 增加 count 然后返回它 + return ++count; + } + + // 委托是一个方法的引用. + // 要引用 Increment 方法, + // 首先声明一个具有相同签名的委托, + // i.e. 不带参数并返回 int + public delegate int IncrementDelegate(); + + // 事件也可用于触发委托 + // 使用委托类型创建事件 + public static event IncrementDelegate MyEvent; + + static void Main(string[] args) + { + // 通过实例化委托来引用 Increment 方法 + // 并将方法本身作为参数传递 + IncrementDelegate inc = new IncrementDelegate(Increment); + Console.WriteLine(inc()); // => 1 + + // 委托可以用 + 运算符组合 + IncrementDelegate composedInc = inc; + composedInc += inc; + composedInc += inc; + + // composedInc 将执行 Increment 3 次 + Console.WriteLine(composedInc()); // => 4 + + + // 为事件订阅与委托 + MyEvent += new IncrementDelegate(Increment); + MyEvent += new IncrementDelegate(Increment); + + // 触发事件 + // ie. 运行这个事件所有的委托订阅 + Console.WriteLine(MyEvent()); // => 6 + } + } + + // 声明类的语法: // <public/private/protected/internal> class <类名>{ - // //数据字段, 构造器, 内部函数. - / // 在Java中函数被称为方法。 + // // 数据字段, 构造器, 内部函数 + // // 在Java中函数被称为方法 // } public class Bicycle { - // 自行车的字段、变量 + // 自行车的字段/变量 public int Cadence // Public: 任何地方都可以访问 { get // get - 定义获取属性的方法 @@ -558,30 +720,35 @@ on a new line! ""Wow!"", the masses cried"; } set // set - 定义设置属性的方法 { - _cadence = value; // value是被传递给setter的值 + _cadence = value; // value 是被传递给 setter 的值 } } private int _cadence; - protected virtual int Gear // 类和子类可以访问 + protected virtual int Gear // Protected: 类和子类可以访问 { get; // 创建一个自动属性,无需成员字段 set; } - internal int Wheels // Internal:在同一程序集内可以访问 + internal int Wheels // Internal: 在同一程序集内可以访问 { get; - private set; // 可以给get/set方法添加修饰符 + private set; // 可以给 get/set 方法添加修饰符 } - int _speed; // 默认为private: 只可以在这个类内访问,你也可以使用`private`关键词 + int _speed; // 类中的任何内容默认为 private: 只可以在这个类内访问 + // 你也可以使用 `private` 关键词显式指定 public string Name { get; set; } - // enum类型包含一组常量 + // 当您想要一个仅返回表达式结果的只读属性时, + // 属性还具有特殊的语法 + public string LongName => Name + " " + _speed + " speed"; + + // enum 枚举是一种值类型,由一组命名常量组成 // 它将名称映射到值(除非特别说明,是一个整型) - // enmu元素的类型可以是byte、sbyte、short、ushort、int、uint、long、ulong。 - // enum不能包含相同的值。 + // enmu 元素的类型可以是 byte、sbyte、short、ushort、int、uint、long、ulong + // enum 不能包含相同的值 public enum BikeBrand { AIST, @@ -589,13 +756,32 @@ on a new line! ""Wow!"", the masses cried"; Electra = 42, //你可以显式地赋值 Gitane // 43 } - // 我们在Bicycle类中定义的这个类型,所以它是一个内嵌类型。 - // 这个类以外的代码应当使用`Bicycle.Brand`来引用。 + // 我们在 Bicycle 类中定义的这个类型,所以它是一个内嵌类型 + // 这个类以外的代码应当使用 `Bicycle.Brand` 来引用 + + public BikeBrand Brand; // 声明一个 enum 类型之后,我们可以声明这个类型的字段 + + // 使用 FlagsAttribute 定义枚举,表示有多个值可以被匹配 + // 任何从 Attribute 派生的类都可以用来修饰类型、方法、参数等 + // 位运算符 & 和 | 可用于 和/或 操作 + + [Flags] + public enum BikeAccessories + { + None = 0, + Bell = 1, + MudGuards = 2, // 需要手动设定值! + Racks = 4, + Lights = 8, + FullPackage = Bell | MudGuards | Racks | Lights + } - public BikeBrand Brand; // 声明一个enum类型之后,我们可以声明这个类型的字段 + // 用法: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell) + // 在 .NET 4 之前: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell + public BikeAccessories Accessories { get; set; } - // 静态方法的类型为自身,不属于特定的对象。 - // 你无需引用对象就可以访问他们。 + // 静态方法属于类型自身,不属于特定的对象 + // 你无需通过对象就可以访问他们 // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); static public int BicyclesCreated = 0; @@ -607,7 +793,7 @@ on a new line! ""Wow!"", the masses cried"; // 下面是一个默认的构造器 public Bicycle() { - this.Gear = 1; // 你可以使用关键词this访问对象的成员 + this.Gear = 1; // 你可以使用关键词 this 访问对象的成员 Cadence = 50; // 不过你并不总是需要它 _speed = 5; Name = "Bontrager"; @@ -618,7 +804,7 @@ on a new line! ""Wow!"", the masses cried"; // 另一个构造器的例子(包含参数) public Bicycle(int startCadence, int startSpeed, int startGear, string name, bool hasCardsInSpokes, BikeBrand brand) - : base() // 首先调用base + : base() // 显式调用基类的无参构造方法 { Gear = startGear; Cadence = startCadence; @@ -637,8 +823,9 @@ on a new line! ""Wow!"", the masses cried"; // 函数语法 // <public/private/protected> <返回值> <函数名称>(<参数>) - // 类可以为字段实现 getters 和 setters 方法 for their fields - // 或者可以实现属性(C#推荐使用这个) + // 类可以为其字段实现 getters 和 setters 方法 + // 或者可以使用属性封装字段(C#推荐使用这个) + // 方法的参数可以有默认值 // 在有默认值的情况下,调用方法的时候可以省略相应的参数 public void SpeedUp(int increment = 1) @@ -652,8 +839,8 @@ on a new line! ""Wow!"", the masses cried"; } // 属性可以访问和设置值 - // 当只需要访问数据的时候,考虑使用属性。 - // 属性可以定义get和set,或者是同时定义两者 + // 当只需要外部访问数据的时候,考虑使用属性。 + // 属性可以定义 get 和 set,或者是同时定义两者 private bool _hasTassles; // private variable public bool HasTassles // public accessor { @@ -663,7 +850,7 @@ on a new line! ""Wow!"", the masses cried"; // 你可以在一行之内定义自动属性 // 这个语法会自动创建后备字段 - // 你可以给getter或setter设置访问修饰符 + // 你可以给 getter 或 setter 设置访问修饰符 // 以便限制它们的访问 public bool IsBroken { get; private set; } @@ -671,12 +858,29 @@ on a new line! ""Wow!"", the masses cried"; public int FrameSize { get; - // 你可以给get或set指定访问修饰符 - // 以下代码意味着只有Bicycle类可以调用Framesize的set + // 你可以给 get 或 set 指定访问修饰符 + // 以下代码意味着只有 Bicycle 类可以调用 Framesize 的 set private set; } - //显示对象属性的方法 + // 还可以在对象上定义自定义索引器 + // 尽管这在本例中并不完全有用, you + // 你可以使用 bicycle[0] 返回 "chris" 来获得第一项 + // 或者 bicycle[1] = "lisa" 来设定值 + private string[] passengers = { "chris", "phil", "darren", "regina" }; + + public string this[int i] + { + get { + return passengers[i]; + } + + set { + passengers[i] = value; + } + } + + // 显示对象属性的方法 public virtual string Info() { return "Gear: " + Gear + @@ -698,7 +902,7 @@ on a new line! ""Wow!"", the masses cried"; } // Bicycle类结束 - // PennyFarthing是Bicycle的一个子类 + // PennyFarthing 是 Bicycle 的一个子类 class PennyFarthing : Bicycle { // (Penny Farthings是一种前轮很大的自行车。没有齿轮。) @@ -717,10 +921,17 @@ on a new line! ""Wow!"", the masses cried"; } set { - throw new ArgumentException("你不可能在PennyFarthing上切换齿轮"); + throw new ArgumentException("你不可能在 PennyFarthing 上切换齿轮"); } } + public static PennyFarthing CreateWithGears(int gears) + { + var penny = new PennyFarthing(1, 1); + penny.Gear = gears; // 你不能这样做! + return penny; + } + public override string Info() { string result = "PennyFarthing bicycle "; @@ -732,7 +943,7 @@ on a new line! ""Wow!"", the masses cried"; // 接口只包含成员的签名,而没有实现。 interface IJumpable { - void Jump(int meters); // 所有接口成员是隐式地公开的 + void Jump(int meters); // 所有接口成员是隐式地公开的 public } interface IBreakable @@ -741,6 +952,8 @@ on a new line! ""Wow!"", the masses cried"; } // 类只能继承一个类,但是可以实现任意数量的接口 + // 但是基类名称必须是列表中的第一个,所有接口都在后面 + class MountainBike : Bicycle, IJumpable, IBreakable { int damage = 0; @@ -759,41 +972,374 @@ on a new line! ""Wow!"", the masses cried"; } /// <summary> - /// 连接数据库,一个 LinqToSql的示例。 + /// 连接数据库,一个 LinqToSql 的示例。 /// EntityFramework Code First 很棒 (类似 Ruby的 ActiveRecord, 不过是双向的) - /// http://msdn.microsoft.com/en-us/data/jj193542.aspx + /// https://learn.microsoft.com/zh-cn/ef/ef6/modeling/code-first/workflows/new-database /// </summary> - public class BikeRespository : DbSet + public class BikeRepository : DbContext { - public BikeRespository() + public BikeRepository() : base() { } public DbSet<Bicycle> Bikes { get; set; } } + + // 一个类可以通过 partial 关键字分别写在多个 .cs 文件中 + // A1.cs + public partial class A + { + public static void A1() + { + Console.WriteLine("Method A1 in class A"); + } + } + + // A2.cs + public partial class A + { + public static void A2() + { + Console.WriteLine("Method A2 in class A"); + } + } + + // 使用 partial 类 "A" + public class Program + { + static void Main() + { + A.A1(); + A.A2(); + } + } + + // 通过在字符串前加上 $ 前缀来进行字符串插值 + // 并用 { 大括号 } 包裹要插值的表达式 + // 您还可以将插值字符串和逐字字符串与 $@ 组合起来 + public class Rectangle + { + public int Length { get; set; } + public int Width { get; set; } + } + + class Program + { + static void Main(string[] args) + { + Rectangle rect = new Rectangle { Length = 5, Width = 3 }; + Console.WriteLine($"The length is {rect.Length} and the width is {rect.Width}"); + + string username = "User"; + Console.WriteLine($@"C:\Users\{username}\Desktop"); + } + } + + // C# 6 新特性 + class GlassBall : IJumpable, IBreakable + { + // 自动属性设置初始值 + public int Damage { get; private set; } = 0; + + // 为仅有 getter 的自动属性设定初始值 + public string Name { get; } = "Glass ball"; + + // 在构造函数中初始化的仅有 getter 的自动属性 + public string GenieName { get; } + + public GlassBall(string genieName = null) + { + GenieName = genieName; + } + + public void Jump(int meters) + { + if (meters < 0) + // 新的 nameof() 表达式; 编译器将检查标识符是否存在 + // nameof(x) == "x" + // 预防 例如 参数名称已更改但错误消息中未更新 + throw new ArgumentException("Cannot jump negative amount!", nameof(meters)); + + Damage += meters; + } + + // 表达式主体 expression-bodied 属性 ... + public bool Broken + => Damage > 100; + + // ... 刚发 + public override string ToString() + // 插值字符串 + => $"{Name}. Damage taken: {Damage}"; + + public string SummonGenie() + // Null 条件运算符 + // x?.y 如果 x 为 null 将立即返回 null; y 将不会求值 + => GenieName?.ToUpper(); + } + + static class MagicService + { + private static bool LogException(Exception ex) + { + // 记录某处的异常 + return false; + } + + public static bool CastSpell(string spell) + { + try + { + // 假设我们在这里调用 API + throw new MagicServiceException("Spell failed", 42); + + // Spell succeeded + return true; + } + // 仅当 Code 为 42(Spell failed)时才捕获 + catch(MagicServiceException ex) when (ex.Code == 42) + { + // Spell failed + return false; + } + // 其他异常,或 MagicServiceException 的 Code 不是 42 + catch(Exception ex) when (LogException(ex)) + { + // 永远不会执行到这块代码 + // 堆栈未展开 + } + return false; + // 请注意,捕获 MagicServiceException + // 并在 Code 不是 42 或 117 时重新抛出是不同的 + // 因为最终的 catch-all 块将不会捕获重新抛出的异常 + } + } + + public class MagicServiceException : Exception + { + public int Code { get; } + + public MagicServiceException(string message, int code) : base(message) + { + Code = code; + } + } + + public static class PragmaWarning { + // 过时的属性 + [Obsolete("Use NewMethod instead", false)] + public static void ObsoleteMethod() + { + // obsolete code + } + + public static void NewMethod() + { + // new code + } + + public static void Main() + { + ObsoleteMethod(); // CS0618: 'ObsoleteMethod 已过时:使用 NewMethod 代替' +#pragma warning disable CS0618 + ObsoleteMethod(); // no warning +#pragma warning restore CS0618 + ObsoleteMethod(); // CS0618: 'ObsoleteMethod 已过时:使用 NewMethod 代替' + } + } } // 结束 Namespace + +using System; +// C# 6, 静态引用 +using static System.Math; + +namespace Learning.More.CSharp +{ + class StaticUsing + { + static void Main() + { + // 不使用静态引用时.. + Console.WriteLine("The square root of 4 is {}.", Math.Sqrt(4)); + // 使用时 + Console.WriteLine("The square root of 4 is {}.", Sqrt(4)); + } + } +} + +// C# 7 新特性 +// 使用 Nuget 安装 Microsoft.Net.Compilers 最新版 +// 使用 Nuget 安装 System.ValueTuple 最新版 +using System; +namespace Csharp7 +{ + // 元组 TUPLES, 析构 DECONSTRUCTION 和 弃元 DISCARDS + class TuplesTest + { + public (string, string) GetName() + { + // 元组中的字段默认命名为 Item1、Item2... + var names1 = ("Peter", "Parker"); + Console.WriteLine(names1.Item2); // => Parker + + // 字段可以显式命名 + // 第 1 种声明 + (string FirstName, string LastName) names2 = ("Peter", "Parker"); + + // 第 2 种声明 + var names3 = (First:"Peter", Last:"Parker"); + + Console.WriteLine(names2.FirstName); // => Peter + Console.WriteLine(names3.Last); // => Parker + + return names3; + } + + public string GetLastName() { + var fullName = GetName(); + + // 元组可以被析构 + (string firstName, string lastName) = fullName; + + // 析构获得的字段可以使用 弃元 _ 丢弃 + var (_, last) = fullName; + return last; + } + + // 通过指定析构方法, + // 可以以相同的方式解构任何类型 + public int randomNumber = 4; + public int anotherRandomNumber = 10; + + public void Deconstruct(out int randomNumber, out int anotherRandomNumber) + { + randomNumber = this.randomNumber; + anotherRandomNumber = this.anotherRandomNumber; + } + + static void Main(string[] args) + { + var tt = new TuplesTest(); + (int num1, int num2) = tt; + Console.WriteLine($"num1: {num1}, num2: {num2}"); // => num1: 4, num2: 10 + + Console.WriteLine(tt.GetLastName()); + } + } + + // 模式匹配 + class PatternMatchingTest + { + public static (string, int)? CreateLogMessage(object data) + { + switch(data) + { + // 使用 when 进行附加过滤 + case System.Net.Http.HttpRequestException h when h.Message.Contains("404"): + return (h.Message, 404); + case System.Net.Http.HttpRequestException h when h.Message.Contains("400"): + return (h.Message, 400); + case Exception e: + return (e.Message, 500); + case string s: + return (s, s.Contains("Error") ? 500 : 200); + case null: + return null; + default: + return (data.ToString(), 500); + } + } + } + + // Reference 变量 / ref 局部变量 + // 允许返回对象的引用而不仅仅是其值 + class RefLocalsTest + { + // 返回值前标明 ref + public static ref string FindItem(string[] arr, string el) + { + for(int i=0; i<arr.Length; i++) + { + if(arr[i] == el) { + // 返回引用 + return ref arr[i]; + } + } + throw new Exception("Item not found"); + } + + public static void SomeMethod() + { + string[] arr = {"this", "is", "an", "array"}; + + // 要在所有地方使用 ref + ref string item = ref FindItem(arr, "array"); + item = "apple"; + Console.WriteLine(arr[3]); // => apple + } + } + + // 本地函数 LOCAL FUNCTIONS + class LocalFunctionTest + { + private static int _id = 0; + public int id; + public LocalFunctionTest() + { + id = generateId(); + + // 这个本地函数只能在此作用域中被访问 + int generateId() + { + return _id++; + } + } + + public static void AnotherMethod() + { + var lf1 = new LocalFunctionTest(); + var lf2 = new LocalFunctionTest(); + Console.WriteLine($"{lf1.id}, {lf2.id}"); // => 0, 1 + + int id = generateId(); + // error CS0103: 当前上下文中不存在名称“generateId” + } + } +} + ``` ## 没有涉及到的主题 +✨ 新的, 👍 旧的, 🎈 长期支持的, 🔥 跨平台的, 🎁 只支持Windows的 + + * 特性 Attributes + + * 异步编程 + + * Web 开发 + * ASP.NET Core ✨ + + * 桌面应用开发 Development + * Windows Presentation Foundation (WPF) 👍 🎈 🎁 + * Universal Windows Platform (UWP) ✨ 🎁 + * Uno Platform 🔥 ✨ + * WinForms 👍 🎈 🎁 + * Avalonia 🔥 ✨ + * WinUI ✨ 🎁 - * Flags - * Attributes - * 静态属性 - * Exceptions, Abstraction - * ASP.NET (Web Forms/MVC/WebMatrix) - * Winforms - * Windows Presentation Foundation (WPF) + * 跨平台开发 + * Xamarin.Forms 👍 + * MAUI ✨ ## 扩展阅读 + * [C# language reference](https://docs.microsoft.com/dotnet/csharp/language-reference/) + * [Learn .NET](https://dotnet.microsoft.com/learn) + * [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) * [DotNetPerls](http://www.dotnetperls.com) * [C# in Depth](http://manning.com/skeet2) - * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) - * [LINQ](http://shop.oreilly.com/product/9780596519254.do) - * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) - * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) - * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) - * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254.do) * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) - * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx) + * [freeCodeCamp - C# Tutorial for Beginners](https://www.youtube.com/watch?v=GhQdlIFylQ8) diff --git a/zh-cn/elisp-cn.html.markdown b/zh-cn/elisp-cn.html.markdown index 3f6ccbcf..a429fcbc 100644 --- a/zh-cn/elisp-cn.html.markdown +++ b/zh-cn/elisp-cn.html.markdown @@ -1,345 +1,345 @@ ----
-language: elisp
-contributors:
- - ["Bastien Guerry", "http://bzg.fr"]
-translators:
- - ["Chenbo Li", "http://binarythink.net"]
-filename: learn-emacs-lisp-zh.el
-lang: zh-cn
----
-
-```scheme
-;; 15分钟学会Emacs Lisp (v0.2a)
-;;(作者:bzg,https://github.com/bzg
-;; 译者:lichenbo,http://douban.com/people/lichenbo)
-;;
-;; 请先阅读Peter Norvig的一篇好文:
-;; http://norvig.com/21-days.html
-;; (译者注:中文版请见http://blog.youxu.info/21-days/)
-;;
-;; 之后安装GNU Emacs 24.3:
-;;
-;; Debian: apt-get install emacs (视具体发行版而定)
-;; MacOSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
-;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
-;;
-;; 更多信息可以在这里找到:
-;; http://www.gnu.org/software/emacs/#Obtaining
-
-;; 很重要的警告:
-;;
-;; 按照这个教程来学习并不会对你的电脑有任何损坏
-;; 除非你自己在学习的过程中愤怒地把它砸了
-;; 如果出现了这种情况,我不会承担任何责任
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; 打开emacs
-;;
-;; 按'q'消除欢迎界面
-;;
-;; 现在请注意窗口底部的那一个灰色长条
-;;
-;; "*scratch*" 是你现在编辑界面的名字。
-;; 这个编辑界面叫做一个"buffer"。
-;;
-;; 每当你打开Emacs时,都会默认打开这个scratch buffer
-;; 此时你并没有在编辑任何文件,而是在编辑一个buffer
-;; 之后你可以将这个buffer保存到一个文件中。
-;;
-;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令
-;;
-;; Emacs在每个buffer中都有一组内置的命令
-;; 而当你激活某种特定的模式时,就可以使用相应的命令
-;; 这里我们使用`lisp-interaction-mode',
-;; 这样我们就可以使用内置的Emacs Lisp(以下简称Elisp)命令了。
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; 分号是注释开始的标志
-;;
-;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"):
-(+ 2 2)
-
-;; 这个s式的意思是 "对2进行加2操作".
-
-;; s式周围有括号,而且也可以嵌套:
-(+ 2 (+ 1 1))
-
-;; 一个s式可以包含原子符号或者其他s式
-;; 在上面的例子中,1和2是原子符号
-;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式.
-
-;; 在 `lisp-interaction-mode' 中你可以计算s式.
-;; 把光标移到闭括号后,之后按下ctrl+j(以后简写为'C-j')
-
-(+ 3 (+ 1 2))
-;; ^ 光标放到这里
-;; 按下`C-j' 就会输出 6
-
-;; `C-j' 会在buffer中插入当前运算的结果
-
-;; 而`C-xC-e' 则会在emacs最底部显示结果,也就是被称作"minibuffer"的区域
-;; 为了避免把我们的buffer填满无用的结果,我们以后会一直用`C-xC-e'
-
-;; `setq' 可以将一个值赋给一个变量
-(setq my-name "Bastien")
-;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示)
-
-;; `insert' 会在光标处插入字符串:
-(insert "Hello!")
-;; `C-xC-e' 输出 "Hello!"
-
-;; 在这里我们只传给了insert一个参数"Hello!", 但是
-;; 我们也可以传给它更多的参数,比如2个:
-
-(insert "Hello" " world!")
-;; `C-xC-e' 输出 "Hello world!"
-
-;; 你也可以用变量名来代替字符串
-(insert "Hello, I am " my-name)
-;; `C-xC-e' 输出 "Hello, I am Bastien"
-
-;; 你可以把s式嵌入函数中
-(defun hello () (insert "Hello, I am " my-name))
-;; `C-xC-e' 输出 hello
-
-;; 现在执行这个函数
-(hello)
-;; `C-xC-e' 输出 Hello, I am Bastien
-
-;; 函数中空括号的意思是我们不需要接受任何参数
-;; 但是我们不能一直总是用my-name这个变量
-;; 所以我们现在使我们的函数接受一个叫做"name"的参数
-
-(defun hello (name) (insert "Hello " name))
-;; `C-xC-e' 输出 hello
-
-;; 现在我们调用这个函数,并且将"you"作为参数传递
-
-(hello "you")
-;; `C-xC-e' 输出 "Hello you"
-
-;; 成功!
-
-;; 现在我们可以休息一下
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer:
-
-(switch-to-buffer-other-window "*test*")
-;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内
-
-;; 用鼠标单击上面的buffer就会使光标移回。
-;; 或者你可以使用 `C-xo' 使得光标跳到另一个窗口中
-
-;; 你可以用 `progn'命令将s式结合起来:
-(progn
- (switch-to-buffer-other-window "*test*")
- (hello "you"))
-;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you"
-
-;; 现在为了简洁,我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了
-
-;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。
-
-;; 清除当前buffer也是常用操作之一:
-(progn
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- (hello "there"))
-
-;; 也可以回到其他的窗口中
-(progn
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- (hello "you")
- (other-window 1))
-
-;; 你可以用 `let' 将一个值和一个局部变量绑定:
-(let ((local-name "you"))
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- (hello local-name)
- (other-window 1))
-
-;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。
-
-;; 格式化字符串的方法:
-(format "Hello %s!\n" "visitor")
-
-;; %s 是字符串占位符,这里被"visitor"替代.
-;; \n 是换行符。
-
-;; 现在我们用格式化的方法再重写一下我们的函数:
-(defun hello (name)
- (insert (format "Hello %s!\n" name)))
-
-(hello "you")
-
-;; 我们再用`let'新建另一个函数:
-(defun greeting (name)
- (let ((your-name "Bastien"))
- (insert (format "Hello %s!\n\nI am %s."
- name ; the argument of the function
- your-name ; the let-bound variable "Bastien"
- ))))
-
-;; 之后执行:
-(greeting "you")
-
-;; 有些函数可以和用户交互:
-(read-from-minibuffer "Enter your name: ")
-
-;; 这个函数会返回在执行时用户输入的信息
-
-;; 现在我们让`greeting'函数显示你的名字:
-(defun greeting (from-name)
- (let ((your-name (read-from-minibuffer "Enter your name: ")))
- (insert (format "Hello!\n\nI am %s and you are %s."
- from-name ; the argument of the function
- your-name ; the let-bound var, entered at prompt
- ))))
-
-(greeting "Bastien")
-
-;; 我们让结果在另一个窗口中显示:
-(defun greeting (from-name)
- (let ((your-name (read-from-minibuffer "Enter your name: ")))
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- (insert (format "Hello %s!\n\nI am %s." your-name from-name))
- (other-window 1)))
-
-;; 测试一下:
-(greeting "Bastien")
-
-;; 第二节结束,休息一下吧。
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; 我们将一些名字存到列表中:
-(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
-
-;; 用 `car'来取得第一个名字:
-(car list-of-names)
-
-;; 用 `cdr'取得剩下的名字:
-(cdr list-of-names)
-
-;; 用 `push'把名字添加到列表的开头:
-(push "Stephanie" list-of-names)
-
-;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 却会对列表本身进行操作.
-;; 这个区别是很重要的: 有些函数没有任何副作用(比如`car')
-;; 但还有一些却是有的 (比如 `push').
-
-;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数:
-(mapcar 'hello list-of-names)
-
-;; 将 `greeting' 改进,使的我们能够对`list-of-names'中的所有名字执行:
-(defun greeting ()
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- (mapcar 'hello list-of-names)
- (other-window 1))
-
-(greeting)
-
-;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。
-;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello'
-
-;; 现在我们对显示的buffer中的内容进行一些更改:
-
-(defun replace-hello-by-bonjour ()
- (switch-to-buffer-other-window "*test*")
- (goto-char (point-min))
- (while (search-forward "Hello")
- (replace-match "Bonjour"))
- (other-window 1))
-
-;; (goto-char (point-min)) 将光标移到buffer的开始
-;; (search-forward "Hello") 查找字符串"Hello"
-;; (while x y) 当x返回某个值时执行y这个s式
-;; 当x返回`nil' (空), 退出循环
-
-(replace-hello-by-bonjour)
-
-;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour"
-
-;; 你也会得到以下错误提示: "Search failed: Hello".
-;;
-;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在
-;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示
-
-;; (search-forward "Hello" nil t) 可以达到这个要求:
-
-;; `nil' 参数的意思是 : 查找并不限于某个范围内
-;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示
-
-;; 在下面的函数中,我们用到了s式,并且不给出任何错误提示:
-
-(defun hello-to-bonjour ()
- (switch-to-buffer-other-window "*test*")
- (erase-buffer)
- ;; 为`list-of-names'中的每个名字调用hello
- (mapcar 'hello list-of-names)
- (goto-char (point-min))
- ;; 将"Hello" 替换为"Bonjour"
- (while (search-forward "Hello" nil t)
- (replace-match "Bonjour"))
- (other-window 1))
-
-(hello-to-bonjour)
-
-;; 给这些名字加粗:
-
-(defun boldify-names ()
- (switch-to-buffer-other-window "*test*")
- (goto-char (point-min))
- (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
- (add-text-properties (match-beginning 1)
- (match-end 1)
- (list 'face 'bold)))
- (other-window 1))
-
-;; 这个函数使用了 `re-search-forward':
-;; 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式
-
-;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是:
-;; 字符串 "Bonjour ", 之后跟着
-;; 一组 | \\( ... \\) 结构
-;; 任意字符 | . 的含义
-;; 有可能重复的 | + 的含义
-;; 之后跟着 "!" 这个字符串
-
-;; 准备好了?试试看。
-
-(boldify-names)
-
-;; `add-text-properties' 可以添加文字属性, 比如文字样式
-
-;; 好的,我们成功了!
-
-;; 如果你想对一个变量或者函数有更多的了解:
-;;
-;; C-h v 变量 回车
-;; C-h f 函数 回车
-;;
-;; 阅读Emacs Lisp官方文档:
-;;
-;; C-h i m elisp 回车
-;;
-;; 在线阅读Emacs Lisp文档:
-;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
-
-;; 感谢以下同学的建议和反馈:
-;; - Wes Hardaker
-;; - notbob
-;; - Kevin Montuori
-;; - Arne Babenhauserheide
-;; - Alan Schmitt
-;; - spacegoing
-```
-
+--- +language: elisp +contributors: + - ["Bastien Guerry", "http://bzg.fr"] +translators: + - ["Chenbo Li", "http://binarythink.net"] +filename: learn-emacs-lisp-zh.el +lang: zh-cn +--- + +```scheme +;; 15分钟学会Emacs Lisp (v0.2a) +;;(作者:bzg,https://github.com/bzg +;; 译者:lichenbo,http://douban.com/people/lichenbo) +;; +;; 请先阅读Peter Norvig的一篇好文: +;; http://norvig.com/21-days.html +;; (译者注:中文版请见http://blog.youxu.info/21-days/) +;; +;; 之后安装GNU Emacs 24.3: +;; +;; Debian: apt-get install emacs (视具体发行版而定) +;; MacOSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg +;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip +;; +;; 更多信息可以在这里找到: +;; http://www.gnu.org/software/emacs/#Obtaining + +;; 很重要的警告: +;; +;; 按照这个教程来学习并不会对你的电脑有任何损坏 +;; 除非你自己在学习的过程中愤怒地把它砸了 +;; 如果出现了这种情况,我不会承担任何责任 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 打开emacs +;; +;; 按'q'消除欢迎界面 +;; +;; 现在请注意窗口底部的那一个灰色长条 +;; +;; "*scratch*" 是你现在编辑界面的名字。 +;; 这个编辑界面叫做一个"buffer"。 +;; +;; 每当你打开Emacs时,都会默认打开这个scratch buffer +;; 此时你并没有在编辑任何文件,而是在编辑一个buffer +;; 之后你可以将这个buffer保存到一个文件中。 +;; +;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令 +;; +;; Emacs在每个buffer中都有一组内置的命令 +;; 而当你激活某种特定的模式时,就可以使用相应的命令 +;; 这里我们使用`lisp-interaction-mode', +;; 这样我们就可以使用内置的Emacs Lisp(以下简称Elisp)命令了。 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 分号是注释开始的标志 +;; +;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"): +(+ 2 2) + +;; 这个s式的意思是 "对2进行加2操作". + +;; s式周围有括号,而且也可以嵌套: +(+ 2 (+ 1 1)) + +;; 一个s式可以包含原子符号或者其他s式 +;; 在上面的例子中,1和2是原子符号 +;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式. + +;; 在 `lisp-interaction-mode' 中你可以计算s式. +;; 把光标移到闭括号后,之后按下ctrl+j(以后简写为'C-j') + +(+ 3 (+ 1 2)) +;; ^ 光标放到这里 +;; 按下`C-j' 就会输出 6 + +;; `C-j' 会在buffer中插入当前运算的结果 + +;; 而`C-xC-e' 则会在emacs最底部显示结果,也就是被称作"minibuffer"的区域 +;; 为了避免把我们的buffer填满无用的结果,我们以后会一直用`C-xC-e' + +;; `setq' 可以将一个值赋给一个变量 +(setq my-name "Bastien") +;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示) + +;; `insert' 会在光标处插入字符串: +(insert "Hello!") +;; `C-xC-e' 输出 "Hello!" + +;; 在这里我们只传给了insert一个参数"Hello!", 但是 +;; 我们也可以传给它更多的参数,比如2个: + +(insert "Hello" " world!") +;; `C-xC-e' 输出 "Hello world!" + +;; 你也可以用变量名来代替字符串 +(insert "Hello, I am " my-name) +;; `C-xC-e' 输出 "Hello, I am Bastien" + +;; 你可以把s式嵌入函数中 +(defun hello () (insert "Hello, I am " my-name)) +;; `C-xC-e' 输出 hello + +;; 现在执行这个函数 +(hello) +;; `C-xC-e' 输出 Hello, I am Bastien + +;; 函数中空括号的意思是我们不需要接受任何参数 +;; 但是我们不能一直总是用my-name这个变量 +;; 所以我们现在使我们的函数接受一个叫做"name"的参数 + +(defun hello (name) (insert "Hello " name)) +;; `C-xC-e' 输出 hello + +;; 现在我们调用这个函数,并且将"you"作为参数传递 + +(hello "you") +;; `C-xC-e' 输出 "Hello you" + +;; 成功! + +;; 现在我们可以休息一下 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer: + +(switch-to-buffer-other-window "*test*") +;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内 + +;; 用鼠标单击上面的buffer就会使光标移回。 +;; 或者你可以使用 `C-xo' 使得光标跳到另一个窗口中 + +;; 你可以用 `progn'命令将s式结合起来: +(progn + (switch-to-buffer-other-window "*test*") + (hello "you")) +;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you" + +;; 现在为了简洁,我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了 + +;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。 + +;; 清除当前buffer也是常用操作之一: +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "there")) + +;; 也可以回到其他的窗口中 +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "you") + (other-window 1)) + +;; 你可以用 `let' 将一个值和一个局部变量绑定: +(let ((local-name "you")) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello local-name) + (other-window 1)) + +;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。 + +;; 格式化字符串的方法: +(format "Hello %s!\n" "visitor") + +;; %s 是字符串占位符,这里被"visitor"替代. +;; \n 是换行符。 + +;; 现在我们用格式化的方法再重写一下我们的函数: +(defun hello (name) + (insert (format "Hello %s!\n" name))) + +(hello "you") + +;; 我们再用`let'新建另一个函数: +(defun greeting (name) + (let ((your-name "Bastien")) + (insert (format "Hello %s!\n\nI am %s." + name ; the argument of the function + your-name ; the let-bound variable "Bastien" + )))) + +;; 之后执行: +(greeting "you") + +;; 有些函数可以和用户交互: +(read-from-minibuffer "Enter your name: ") + +;; 这个函数会返回在执行时用户输入的信息 + +;; 现在我们让`greeting'函数显示你的名字: +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (insert (format "Hello!\n\nI am %s and you are %s." + from-name ; the argument of the function + your-name ; the let-bound var, entered at prompt + )))) + +(greeting "Bastien") + +;; 我们让结果在另一个窗口中显示: +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (insert (format "Hello %s!\n\nI am %s." your-name from-name)) + (other-window 1))) + +;; 测试一下: +(greeting "Bastien") + +;; 第二节结束,休息一下吧。 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 我们将一些名字存到列表中: +(setq list-of-names '("Sarah" "Chloe" "Mathilde")) + +;; 用 `car'来取得第一个名字: +(car list-of-names) + +;; 用 `cdr'取得剩下的名字: +(cdr list-of-names) + +;; 用 `push'把名字添加到列表的开头: +(push "Stephanie" list-of-names) + +;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 却会对列表本身进行操作. +;; 这个区别是很重要的: 有些函数没有任何副作用(比如`car') +;; 但还有一些却是有的 (比如 `push'). + +;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数: +(mapcar 'hello list-of-names) + +;; 将 `greeting' 改进,使的我们能够对`list-of-names'中的所有名字执行: +(defun greeting () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (mapcar 'hello list-of-names) + (other-window 1)) + +(greeting) + +;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。 +;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello' + +;; 现在我们对显示的buffer中的内容进行一些更改: + +(defun replace-hello-by-bonjour () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (search-forward "Hello") + (replace-match "Bonjour")) + (other-window 1)) + +;; (goto-char (point-min)) 将光标移到buffer的开始 +;; (search-forward "Hello") 查找字符串"Hello" +;; (while x y) 当x返回某个值时执行y这个s式 +;; 当x返回`nil' (空), 退出循环 + +(replace-hello-by-bonjour) + +;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour" + +;; 你也会得到以下错误提示: "Search failed: Hello". +;; +;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在 +;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示 + +;; (search-forward "Hello" nil t) 可以达到这个要求: + +;; `nil' 参数的意思是 : 查找并不限于某个范围内 +;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示 + +;; 在下面的函数中,我们用到了s式,并且不给出任何错误提示: + +(defun hello-to-bonjour () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + ;; 为`list-of-names'中的每个名字调用hello + (mapcar 'hello list-of-names) + (goto-char (point-min)) + ;; 将"Hello" 替换为"Bonjour" + (while (search-forward "Hello" nil t) + (replace-match "Bonjour")) + (other-window 1)) + +(hello-to-bonjour) + +;; 给这些名字加粗: + +(defun boldify-names () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (re-search-forward "Bonjour \\(.+\\)!" nil t) + (add-text-properties (match-beginning 1) + (match-end 1) + (list 'face 'bold))) + (other-window 1)) + +;; 这个函数使用了 `re-search-forward': +;; 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式 + +;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是: +;; 字符串 "Bonjour ", 之后跟着 +;; 一组 | \\( ... \\) 结构 +;; 任意字符 | . 的含义 +;; 有可能重复的 | + 的含义 +;; 之后跟着 "!" 这个字符串 + +;; 准备好了?试试看。 + +(boldify-names) + +;; `add-text-properties' 可以添加文字属性, 比如文字样式 + +;; 好的,我们成功了! + +;; 如果你想对一个变量或者函数有更多的了解: +;; +;; C-h v 变量 回车 +;; C-h f 函数 回车 +;; +;; 阅读Emacs Lisp官方文档: +;; +;; C-h i m elisp 回车 +;; +;; 在线阅读Emacs Lisp文档: +;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html + +;; 感谢以下同学的建议和反馈: +;; - Wes Hardaker +;; - notbob +;; - Kevin Montuori +;; - Arne Babenhauserheide +;; - Alan Schmitt +;; - spacegoing +``` + diff --git a/zh-cn/elixir-cn.html.markdown b/zh-cn/elixir-cn.html.markdown index daee8d3c..0ed1d823 100644 --- a/zh-cn/elixir-cn.html.markdown +++ b/zh-cn/elixir-cn.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] translators: diff --git a/zh-cn/fortran-cn.html.markdown b/zh-cn/fortran-cn.html.markdown new file mode 100644 index 00000000..ab521e0a --- /dev/null +++ b/zh-cn/fortran-cn.html.markdown @@ -0,0 +1,444 @@ +--- +language: Fortran +filename: learnfortran-cn.f90 +contributors: + - ["Robert Steed", "https://github.com/robochat"] +translators: + - ["Corvusnest", "https://github.com/Corvusnest"] +lang: zh-cn +--- + +Fortran 是最古老的计算机语言之一。它由 IBM 开发于 1950 年用于数值运算(Fortran 为 "Formula +Translation" 的缩写)。虽然该语言已年代久远,但目前仍用于高性能计算,如天气预报。 +该语言仍在持续发展,并且基本保持向下兼容。知名的版本为 Fortran 77, Fortran 90, +Fortran 95, Fortran 2008, Fortran 2015 和 Fortran 2023。 + +这篇概要将讨论 Fortran 2008 的一些特征。因为它是目前所广泛采用的标准版本,并且与最新版本的内容 +也基本相同(而 Fortran 77 则是一个非常不同的版本)。 + +```fortran +! 这是一个注释 + +program example ! 声明一个名为 example 的程序 + + ! 代码只能存在于程序、函数、子程序或模块中 + ! 使用缩进不是必需的,但推荐使用 + + ! 声明变量 + ! ========= + + ! 所有的声明必须在语句和表达式之前 + + implicit none ! 防止动态声明变量(推荐!) + ! implicit none 推荐在每个函数/程序/模块中重新声明... + + ! 注意 - Fortran 中对大小写不敏感 + real z + REAL Z2 + + real :: v, x ! 警告:默认的初始值取决于编译器! + real :: a = 3, b = 2E12, c = 0.01 + integer :: i, j, k = 1, m + real, parameter :: PI = 3.1415926535897931 ! 声明一个常数 + logical :: y = .TRUE., n = .FALSE. ! 布尔类型 + complex :: w = (0, 1) ! 单位虚数 + character(len=3) :: month ! 字符串,长度为 3 个字符 + + real :: array(6) ! 声明一个包含 6 个实数的数组 + real, dimension(4) :: arrayb ! 另一种声明数组的方式 + integer :: arrayc(-10:10) ! 具有自定义索引的数组 + real :: array2d(3, 2) ! 多维数组 + + ! 这些分隔符 '::' 并不总是必需的,但推荐使用 + + ! 还有许多其他的变量属性: + real, pointer :: p ! 声明一个指针 + + integer, parameter :: LP = selected_real_kind(20) + real(kind=LP) :: d ! 长精度变量 + + ! 警告:在声明过程中初始化变量会在函数中造成问题, + ! 因为这会自动暗示 'save' 属性, + ! 在函数调用之间保存变量的值一般情况下, + ! 除了常量外,声明和初始化的代码应该分开! + + ! 字符串 + ! ======= + + character :: a_char = 'i' + character(len=6) :: a_str = "qwerty" + character(len=30) :: str_b + character(len=*), parameter :: a_long_str = "This is a long string." + ! 使用 (len=*) 可以自动计算长度,但只适用于常量 + + str_b = a_str//" keyboard" ! 使用 // 运算符连接字符串 + + ! 赋值和算术 + ! ============= + + Z = 1 ! 对上面声明的变量 z 进行赋值(对大小写不敏感) + j = 10 + 2 - 3 + a = 11.54/(2.3*3.1) + b = 2**3 ! 幂运算 + + ! 流程控制语句和操作符 + ! =================== + + ! 单行 if 语句 + if (z == a) b = 4 ! 条件始终需要在括号中 + + if (z /= a) then ! z 不等于 a + ! 其他的比较操作符包括 < > <= >= == /= + b = 4 + else if (z .GT. a) then ! z 大于 a + ! 文本等价于符号操作符中的 .LT. .GT. .LE. .GE. .EQ. .NE. + b = 6 + else if (z < a) then ! 'then' 必须在本行上 + b = 5 ! 执行块必须在新的一行上 + else + b = 10 + end if ! end 语句后需要 'if'(或可以使用 'endif') + + if (.NOT. (x < c .AND. v >= a .OR. z == z)) then ! 布尔运算符 + inner: if (.TRUE.) then ! 可以对 if 结构命名 + b = 1 + end if inner ! then 必须命名对应的 endif 语句 + end if + + i = 20 + select case (i) + case (0, 1) ! 当 i == 0 或 i == 1 时 + j = 0 + case (2:10) ! 当 i 在 2 到 10 之间(包括边界)时 + j = 1 + case (11:) ! 当 i >= 11 时 + j = 2 + case default + j = 3 + end select + + month = 'jan' + ! 条件可以是整数、逻辑、或字符类型 + ! Select 结构也可以命名 + monthly:select case(month) + case ("jan") + j = 0 + case default + j = -1 + end select monthly + + do i = 2, 10, 2 ! 循环从 2 到 10(包括)以 2 为步长 + innerloop: do j = 1, 3 ! 循环也可以命名 + exit ! 退出循环 + end do innerloop + cycle ! 跳到下一个循环迭代 + end do + + ! 虽然存在 Goto 语句,但它被强烈不推荐 + goto 10 + stop 1 ! 立即停止代码(并返回指定的条件代码) +10 j = 201 ! 这一行被标记为 10 行 + + ! 数组 + ! ===== + array = (/1, 2, 3, 4, 5, 6/) + array = [1, 2, 3, 4, 5, 6] ! 使用 Fortran 2003 的表示法 + arrayb = [10.2, 3e3, 0.41, 4e-5] + array2d = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [3, 2]) + + ! Fortran 数组索引从 1 开始 + ! (默认情况下,但对于特定数组可以定义不同的索引) + v = array(1) ! 取数组的第一个元素 + v = array2d(2, 2) + + print *, array(3:5) ! 打印从第三个到第五个元素(包括) + print *, array2d(1, :) ! 打印二维数组的第一列 + + array = array*3 + 2 ! 可以对数组应用数学表达式 + array = array*array ! 数组操作是逐元素进行的 + ! array = array*array2d ! 这两个数组是不兼容的 + + ! 有许多内置函数可用于数组 + c = dot_product(array, array) ! 这是点积 + ! 使用 matmul() 进行矩阵运算 + c = sum(array) + c = maxval(array) + print *, minloc(array) + c = size(array) + print *, shape(array) + m = count(array > 0) + + ! 循环数组(通常使用 product() 函数) + v = 1 + do i = 1, size(array) + v = v*array(i) + end do + + ! 条件性地执行逐元素赋值 + array = [1, 2, 3, 4, 5, 6] + where (array > 3) + array = array + 1 + elsewhere(array == 2) + array = 1 + elsewhere + array = 0 + end where + + ! 隐含 do 循环是创建数组的紧凑方式 + array = [(i, i=1, 6)] ! 创建一个数组 [1,2,3,4,5,6] + array = [(i, i=1, 12, 2)] ! 创建一个数组 [1,3,5,7,9,11] + array = [(i**2, i=1, 6)] ! 创建一个数组 [1,4,9,16,25,36] + array = [(4, 5, i=1, 3)] ! 创建一个数组 [4,5,4,5,4,5] + + ! 输入/输出 + ! ========= + + print *, b ! 将变量 'b' 打印到命令行 + + ! 可以对打印的输出进行格式化 + print "(I6)", 320 ! 打印 ' 320' + print "(I6.4)", 3 ! 打印 ' 0003' + print "(F6.3)", 4.32 ! 打印 ' 4.320' + + ! 字母表示预期的类型,后面的数字表示用于打印值的字符数 + ! 字母可以是 I(整数),F(实数),E(工程表示法), + ! L(逻辑),A(字符串)... + print "(I3)", 3200 ! 打印 '***',因为该数字不适合 + + ! 可以有多个格式规范 + print "(I5,F6.2,E6.2)", 120, 43.41, 43.41 + print "(3I5)", 10, 20, 30 ! 整数的三次重复(字段宽度为 5) + print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 ! 格式重复组合 + + ! 我们还可以从终端读取输入 + read (*, *) v + read (*, "(2F6.2)") v, x ! 读取两个数字 + + ! 写入文件 + open (unit=12, file="records.txt", status="replace") + ! 文件通过 'unit number' 引用,这个数字可以在 9:99 范围内选择 + ! Status 可以是 {'old','replace','new'} 中的一个 + write (12, "(F10.2,F10.2,F10.2)") c, b, a + close (12) + + ! 读取文件 + open (newunit=m, file="records.txt", status="old") + ! 文件通过 'new unit number' 引用,编译器为您选择一个整数 + read (unit=m, fmt="(3F10.2)") a, b, c + close (m) + + ! 还有更多功能可用,超出了本文所讨论的范围, + ! 还有由于与旧版本的 Fortran 的向后兼容性而存在的替代方案 + + ! 内置函数 + ! =========== + + ! Fortran 大约有 200 个语言内部的函数/子程序 + ! 例如 - + call cpu_time(v) ! 将 'v' 设置为以秒为单位的时间 + k = ior(i, j) ! 两个整数的位 OR 运算 + v = log10(x) ! 以 10 为底的对数 + i = floor(b) ! 返回小于或等于 x 的最接近的整数 + v = aimag(w) ! 复数的虚部 + + ! 函数和子程序 + ! ============== + + ! 子程序运行一些代码,并可以对输入值产生副作用或修改输入值 + + call routine(a, c, v) ! 子程序调用 + + ! 函数采用一系列输入参数,并返回一个单个值 + ! 不过,输入参数可能仍会被修改,并且会执行副作用 + + m = func(3, 2, k) ! 函数调用 + + ! 函数调用还可以在表达式中使用 + print *, func2(3, 2, k) + + ! 一个纯函数是一个不修改其输入参数, + ! 也不会引起任何副作用的函数 + m = func3(3, 2, k) + +contains ! 包含程序内部定义的子程序的区域 + + ! Fortran 有几种稍微不同的方式来定义函数 + + integer function func(a, b, c) ! 函数返回一个整数值 + ! implicit none ! 子变量域可以不再声明 implicit none + integer, intent(in) :: a, b, c ! 在函数内部定义输入参数的类型 + + if (a >= 2) then + func = a + b + c ! 返回变量默认为函数名 + return ! 随时可以从函数返回当前值 + end if + func = a + c + + ! 在函数的末尾不需要 return 语句 + end function func + + function func2(a, b, c) result(f) ! 返回变量声明为 'f' + integer, intent(in) :: a, b ! 可以声明和强制约定变量 + ! 不会被函数修改 + integer, intent(inout) :: c + integer :: f ! 函数返回类型在函数内部声明 + integer :: cnt = 0 ! 注意:初始化暗示变量在函数调用之间保存 + ! + + f = a + b - c + c = 4 ! 修改输入变量的值 + cnt = cnt + 1 ! 计算函数调用的次数 + + end function func2 + + pure function func3(a, b, c) ! 纯函数不能有副作用 + integer, intent(in) :: a, b, c + integer :: func3 + + func3 = a*b*c + + end function func3 + + subroutine routine(d, e, f) + real, intent(inout) :: f + real, intent(in) :: d, e + + f = 2*d + 3*e + f + + end subroutine routine + +end program example ! 程序定义结束-------------------------- + +! 函数和子程序在程序列表之外声明,在程序之间以及模块中声明时,需要使用 interface 声明(即使它们在同一源文件中)(见下面)将它们定义在模块或程序的 'contains' 部分更容易 + +elemental real function func4(a) result(res) +! elemental 函数是一个纯函数,它采用标量输入变量, +! 但也可以在数组上独立应用,并返回一个新的数组 + real, intent(in) :: a + + res = a**2 + 1.0 + +end function func4 + +! 模块 +! ======= + +! 模块是在可重用性中将相关的声明、函数和子程序结合在一起的有用方式 + +module fruit + + real :: apple + real :: pear + real :: orange + +end module fruit + +module fruity + ! 声明的顺序必须是:模块、接口、变量 + !(也可以在程序中声明模块和接口) + + use fruit, only: apple, pear ! 使用 fruit 模块中的 apple 和 pear + implicit none ! 导入模块之后 + + private ! 将一些内容私有化(默认为公共) + ! 显式将一些变量/函数声明为公共 + public :: apple, mycar, create_mycar + ! 将一些变量/函数声明为模块私有(本例中是多余的) + private :: func4 + + ! 接口 + ! ======== + ! 在模块内部(最好放在 'contains' 部分)显式声明外部函数/过程 + interface + elemental real function func4(a) result(res) + real, intent(in) :: a + end function func4 + end interface + + ! 可以使用命名接口定义重载函数 + interface myabs + ! 可以使用 'module procedure' 关键字包括模块内已经定义的函数 + module procedure real_abs, complex_abs + end interface + + ! 派生数据类型 + ! ================== + ! 可以创建自定义的结构化数据集合 + type car + character(len=100) :: model + real :: weight !(千克) + real :: dimensions(3) ! 即,长度-宽度-高度(米) + character :: colour + contains + procedure :: info ! 将过程绑定到类型 + end type car + + type(car) :: mycar ! 声明自定义类型的变量 + ! 请查看 create_mycar() 程序的用法 + + ! 注意:模块中没有可以执行的语句 + +contains + + subroutine create_mycar(mycar) + ! 演示派生数据类型的用法 + type(car), intent(out) :: mycar + + ! 使用 '%' 运算符访问类型元素 + mycar%model = "Ford Prefect" + mycar%colour = 'r' + mycar%weight = 1400 + mycar%dimensions(1) = 5.0 ! 默认索引从 1 开始! + mycar%dimensions(2) = 3.0 + mycar%dimensions(3) = 1.5 + + end subroutine create_mycar + + subroutine info(self) + class(car), intent(in) :: self + ! 使用 'class' 关键字将过程绑定到类型 + + print *, "Model : ", self%model + print *, "Colour : ", self%colour + print *, "Weight : ", self%weight + print *, "Dimensions: ", self%dimensions + + end subroutine info + + real pure function real_abs(x) + real, intent(in) :: x + + if (x < 0) then + real_abs = -x + else + real_abs = x + end if + + end function real_abs + + real pure function complex_abs(z) + complex, intent(in) :: z + ! 长行可以使用继续字符 '&' 进行延续 + + complex_abs = sqrt(real(z)**2 + & + aimag(z)**2) + + end function complex_abs + +end module fruity + +``` + +### 更多资源 + +了解更多的 Fortran 信息: + ++ [wikipedia](https://en.wikipedia.org/wiki/Fortran) ++ [Fortran-lang Organization](https://fortran-lang.org/) ++ [Fortran_95_language_features](https://en.wikipedia.org/wiki/Fortran_95_language_features) ++ [fortranwiki.org](http://fortranwiki.org) ++ [www.fortran90.org/](http://www.fortran90.org) ++ [list of Fortran 95 tutorials](http://www.dmoz.org/Computers/Programming/Languages/Fortran/FAQs%2C_Help%2C_and_Tutorials/Fortran_90_and_95/) ++ [Fortran wikibook](https://en.wikibooks.org/wiki/Fortran) ++ [Fortran resources](http://www.fortranplus.co.uk/resources/fortran_resources.pdf) ++ [Mistakes in Fortran 90 Programs That Might Surprise You](http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html) diff --git a/zh-cn/fortran95-cn.html.markdown b/zh-cn/fortran95-cn.html.markdown deleted file mode 100644 index e28d309f..00000000 --- a/zh-cn/fortran95-cn.html.markdown +++ /dev/null @@ -1,435 +0,0 @@ ---- -language: Fortran -filename: learnfortran-cn.f95 -contributors: - - ["Robert Steed", "https://github.com/robochat"] -translators: - - ["Corvusnest", "https://github.com/Corvusnest"] -lang: zh-cn ---- - -Fortran 是最古老的计算机语言之一。它由IBM开发于1950年用于数值运算(Fortran 为 "Formula -Translation" 的缩写)。虽然该语言已年代久远,但目前仍用于高性能计算,如天气预报。 -该语言仍在持续发展,并且基本保持向下兼容。知名的版本为 Fortran 77, Fortran 90, -Fortran 95, Fortran 2003, Fortran 2008 与 Fortran 2015。 - -这篇概要将讨论 Fortran 95 的一些特征。因为它是目前所广泛采用的标准版本,并且与最新版本的内容 -也基本相同(而 Fortran 77 则是一个非常不同的版本)。 - -```fortran - -! 这是一行注释 - - -program example !声明一个叫做 example 的程序 - - ! 代码只能放在程序、函数、子程序或者模块内部 - ! 推荐使用缩进,但不是必须的。 - - ! 声明变量 - ! =================== - - ! 所有的声明必须放在语句与表达式之前 - - implicit none !阻止变量的隐式声明 (推荐!) - ! Implicit none 必须在每一个 函数/程序/模块 中进行声明 - - ! 重要 - Fortran 对大小写不敏感 - real z - REAL Z2 - - real :: v,x ! 警告: 默认值取决于编译器! - real :: a = 3, b=2E12, c = 0.01 - integer :: i, j, k=1, m - real, parameter :: PI = 3.1415926535897931 !声明一个常量 - logical :: y = .TRUE. , n = .FALSE. !布尔值 - complex :: w = (0,1) !sqrt(-1) (译注: 定义复数,此为-1的平方根) - character (len=3) :: month !长度为3的字符串 - - real :: array(6) !声明长度为6的浮点数数组 - real, dimension(4) :: arrayb !声明数组的另一种方法 - integer :: arrayc(-10:10) !有着自定义索引的数组 - real :: array2d(3,2) !多维数组 - - ! 分隔符 '::' 并不总是必要的,但推荐使用 - - ! 还存在很多其他的变量特征: - real, pointer :: p !声明一个指针 - - integer, parameter :: LP = selected_real_kind(20) - real (kind = LP) :: d !长精度变量 - - ! 警告:在声明期间初始化变量将导致在函数内发生问题,因为这将自动具备了 “save” 属性, - ! 因此变量的值在函数的多次调用期间将被存储。一般来说,除了常量,应分开声明与初始化! - - ! 字符串 - ! ======= - - character :: a_char = 'i' - character (len = 6) :: a_str = "qwerty" - character (len = 30) :: str_b - character (len = *), parameter :: a_long_str = "This is a long string." - !可以通过使用 (len=*) 来自动判断长度,但只对常量有效 - - str_b = a_str // " keyboard" !通过 // 操作符来连接字符串 - - - ! 任务与计算 - ! ======================= - - Z = 1 !向之前声明的变量 z 赋值 (大小写不敏感). - j = 10 + 2 - 3 - a = 11.54 / (2.3 * 3.1) - b = 2**3 !幂 - - - ! 控制流程语句 与 操作符 - ! =================================== - - !单行 if 语句 - if (z == a) b = 4 !判别句永远需要放在圆括号内 - - if (z /= a) then !z 不等于 a - ! 其他的比较运算符: < > <= >= == /= - b = 4 - else if (z .GT. a) then !z 大于(Greater) a - ! 文本形式的比较运算符: .LT. .GT. .LE. .GE. .EQ. .NE. - b = 6 - else if (z < a) then !'then' 必须放在该行 - b = 5 !执行部分必须放在新的一行里 - else - b = 10 - end if !结束语句需要 'if' (也可以用 'endif'). - - - if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !布尔操作符 - inner: if (.TRUE.) then !可以为 if 结构命名 - b = 1 - endif inner !接下来必须命名 endif 语句. - endif - - - i = 20 - select case (i) - case (0) !当 i == 0 - j=0 - case (1:10) !当 i 为 1 到 10 之内 ( 1 <= i <= 10 ) - j=1 - case (11:) !当 i>=11 - j=2 - case default - j=3 - end select - - - month = 'jan' - ! 状态值可以为整数、布尔值或者字符类型 - ! Select 结构同样可以被命名 - monthly: select case (month) - case ("jan") - j = 0 - case default - j = -1 - end select monthly - - do i=2,10,2 !从2到10(包含2和10)以2为步进值循环 - innerloop: do j=1,3 !循环同样可以被命名 - exit !跳出循环 - end do innerloop - cycle !重复跳入下一次循环 - enddo - - - ! Goto 语句是存在的,但强烈不建议使用 - goto 10 - stop 1 !立即停止程序 (返回一个设定的状态码). -10 j = 201 !这一行被标注为 10 行 (line 10) - - - ! 数组 - ! ====== - array = (/1,2,3,4,5,6/) - array = [1,2,3,4,5,6] !当使用 Fortran 2003 版本. - arrayb = [10.2,3e3,0.41,4e-5] - array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2]) - - ! Fortran 数组索引起始于 1 - ! (默认下如此,也可以为数组定义不同的索引起始) - v = array(1) !获取数组的第一个元素 - v = array2d(2,2) - - print *, array(3:5) !打印从第3到第五5之内的所有元素 - print *, array2d(1,:) !打印2维数组的第一列 - - array = array*3 + 2 !可为数组设置数学表达式 - array = array*array !数组操作支持元素级(操作) (element-wise) - !array = array*array2d !这两类数组并不是同一个维度的 - - ! 有很多内置的数组操作函数 - c = dot_product(array,array) !点乘 (点积) - ! 用 matmul() 来进行矩阵运算. - c = sum(array) - c = maxval(array) - print *, minloc(array) - c = size(array) - print *, shape(array) - m = count(array > 0) - - ! 遍历一个数组 (一般使用 Product() 函数). - v = 1 - do i = 1, size(array) - v = v*array(i) - end do - - ! 有条件地执行元素级操作 - array = [1,2,3,4,5,6] - where (array > 3) - array = array + 1 - elsewhere (array == 2) - array = 1 - elsewhere - array = 0 - end where - - ! 隐式DO循环可以很方便地创建数组 - array = [ (i, i = 1,6) ] !创建数组 [1,2,3,4,5,6] - array = [ (i, i = 1,12,2) ] !创建数组 [1,3,5,7,9,11] - array = [ (i**2, i = 1,6) ] !创建数组 [1,4,9,16,25,36] - array = [ (4,5, i = 1,3) ] !创建数组 [4,5,4,5,4,5] - - - ! 输入/输出 - ! ============ - - print *, b !向命令行打印变量 'b' - - ! 我们可以格式化输出 - print "(I6)", 320 !打印 ' 320' - print "(I6.4)", 3 !打印 ' 0003' - print "(F6.3)", 4.32 !打印 ' 4.320' - - - ! 该字母与数值规定了给定的数值与字符所用于打印输出的类型与格式 - ! 字母可为 I (整数), F (浮点数), E (工程格式), - ! L (逻辑/布尔值), A (字符) ... - print "(I3)", 3200 !如果数值无法符合格式将打印 '***' - - ! 可以同时设定多种格式 - print "(I5,F6.2,E6.2)", 120, 43.41, 43.41 - print "(3I5)", 10, 20, 30 !连续打印3个整数 (字段宽度 = 5). - print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !连续分组格式 - - ! 我们也可以从终端读取输入 - read *, v - read "(2F6.2)", v, x !读取2个数值 - - ! 读取文件 - open(unit=11, file="records.txt", status="old") - ! 文件被引用带有一个单位数 'unit', 为一个取值范围在9-99的整数 - ! 'status' 可以为 {'old','replace','new'} 其中之一 - read(unit=11, fmt="(3F10.2)") a, b, c - close(11) - - ! 写入一个文件 - open(unit=12, file="records.txt", status="replace") - write(12, "(F10.2,F10.2,F10.2)") c, b, a - close(12) - ! 在讨论范围之外的还有更多的细节与可用功能,并于老版本的 Fortran 保持兼容 - - - ! 内置函数 - ! ================== - - ! Fortran 拥有大约 200 个内置函数/子程序 - ! 例子 - call cpu_time(v) !以秒为单位设置时间 - k = ior(i,j) !2个整数的位或运算 - v = log10(x) !以10为底的log运算 - i = floor(b) !返回一个最接近的整数小于或等于x (地板数) - v = aimag(w) !复数的虚数部分 - - - ! 函数与子程序 - ! ======================= - - ! 一个子程序会根据输入值运行一些代码并会导致副作用 (side-effects) 或修改输入值 - ! (译者注: 副作用是指对子程序/函数外的环境产生影响,如修改变量) - - call routine(a,c,v) !调用子程序 - - ! 一个函数会根据输入的一系列数值来返回一个单独的值 - ! 但输入值仍然可能被修改以及产生副作用 - - m = func(3,2,k) !调用函数 - - ! 函数可以在表达式内被调用 - Print *, func2(3,2,k) - - ! 一个纯函数不会去修改输入值或产生副作用 - m = func3(3,2,k) - - -contains ! 用于定义程序内部的副程序(sub-programs)的区域 - - ! Fortran 拥有一些不同的方法去定义函数 - - integer function func(a,b,c) !一个返回一个整数的函数 - implicit none !最好也在函数内将含蓄模式关闭 (implicit none) - integer :: a,b,c !输入值类型定义在函数内部 - if (a >= 2) then - func = a + b + c !返回值默认为函数名 - return !可以在函数内任意时间返回当前值 - endif - func = a + c - ! 在函数的结尾不需要返回语句 - end function func - - - function func2(a,b,c) result(f) !将返回值声明为 'f' - implicit none - integer, intent(in) :: a,b !可以声明让变量无法被函数修改 - integer, intent(inout) :: c - integer :: f !函数的返回值类型在函数内声明 - integer :: cnt = 0 !注意 - 隐式的初始化变量将在函数的多次调用间被存储 - f = a + b - c - c = 4 !变动一个输入变量的值 - cnt = cnt + 1 !记录函数的被调用次数 - end function func2 - - - pure function func3(a,b,c) !一个没有副作用的纯函数 - implicit none - integer, intent(in) :: a,b,c - integer :: func3 - func3 = a*b*c - end function func3 - - - subroutine routine(d,e,f) - implicit none - real, intent(inout) :: f - real, intent(in) :: d,e - f = 2*d + 3*e + f - end subroutine routine - - -end program example ! 函数定义完毕 ----------------------- - -! 函数与子程序的外部声明对于生成程序清单来说,需要一个接口声明(即使它们在同一个源文件内)(见下) -! 使用 'contains' 可以很容易地在模块或程序内定义它们 - -elemental real function func4(a) result(res) -! 一个元函数(elemental function) 为一个纯函数使用一个标量输入值 -! 但同时也可以用在一个数组并对其中的元素分别处理,之后返回一个新的数组 - real, intent(in) :: a - res = a**2 + 1.0 -end function func4 - - -! 模块 -! ======= - -! 模块十分适合于存放与复用相关联的一组声明、函数与子程序 - -module fruit - real :: apple - real :: pear - real :: orange -end module fruit - - -module fruity - - ! 声明必须按照顺序: 模块、接口、变量 - ! (同样可在程序内声明模块和接口) - - use fruit, only: apple, pear ! 使用来自于 fruit 模块的 apple 和 pear - implicit none !在模块导入后声明 - - private !使得模块内容为私有(private)(默认为公共 public) - ! 显式声明一些变量/函数为公共 - public :: apple,mycar,create_mycar - ! 声明一些变量/函数为私有(在当前情况下没必要)(译注: 因为前面声明了模块全局 private) - private :: func4 - - ! 接口 - ! ========== - ! 在模块内显式声明一个外部函数/程序 - ! 一般最好将函数/程序放进 'contains' 部分内 - interface - elemental real function func4(a) result(res) - real, intent(in) :: a - end function func4 - end interface - - ! 重载函数可以通过已命名的接口来定义 - interface myabs - ! 可以通过使用 'module procedure' 关键词来包含一个已在模块内定义的函数 - module procedure real_abs, complex_abs - end interface - - ! 派生数据类型 - ! ================== - ! 可创建自定义数据结构 - type car - character (len=100) :: model - real :: weight !(公斤 kg) - real :: dimensions(3) !例: 长宽高(米) - character :: colour - end type car - - type(car) :: mycar !声明一个自定义类型的变量 - ! 用法具体查看 create_mycar() - - ! 注: 模块内没有可执行的语句 - -contains - - subroutine create_mycar(mycar) - ! 展示派生数据类型的使用 - implicit none - type(car),intent(out) :: mycar - - ! 通过 '%' 操作符来访问(派生数据)类型的元素 - mycar%model = "Ford Prefect" - mycar%colour = 'r' - mycar%weight = 1400 - mycar%dimensions(1) = 5.0 !索引默认起始值为 1 ! - mycar%dimensions(2) = 3.0 - mycar%dimensions(3) = 1.5 - - end subroutine - - real function real_abs(x) - real :: x - if (x<0) then - real_abs = -x - else - real_abs = x - end if - end function real_abs - - real function complex_abs(z) - complex :: z - ! 过长的一行代码可通过延续符 '&' 来换行 - complex_abs = sqrt(real(z)**2 + & - aimag(z)**2) - end function complex_abs - - -end module fruity - -``` - -### 更多资源 - -了解更多的 Fortran 信息: - -+ [wikipedia](https://en.wikipedia.org/wiki/Fortran) -+ [Fortran_95_language_features](https://en.wikipedia.org/wiki/Fortran_95_language_features) -+ [fortranwiki.org](http://fortranwiki.org) -+ [www.fortran90.org/](http://www.fortran90.org) -+ [list of Fortran 95 tutorials](http://www.dmoz.org/Computers/Programming/Languages/Fortran/FAQs%2C_Help%2C_and_Tutorials/Fortran_90_and_95/) -+ [Fortran wikibook](https://en.wikibooks.org/wiki/Fortran) -+ [Fortran resources](http://www.fortranplus.co.uk/resources/fortran_resources.pdf) -+ [Mistakes in Fortran 90 Programs That Might Surprise You](http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html) diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown index 0123c0a6..a2b71761 100644 --- a/zh-cn/go-cn.html.markdown +++ b/zh-cn/go-cn.html.markdown @@ -78,7 +78,7 @@ func learnTypes() { // 非ascii字符。Go使用UTF-8编码。 g := 'Σ' // rune类型,int32的别名,使用UTF-8编码 - f := 3.14195 // float64类型,IEEE-754 64位浮点数 + f := 3.14159 // float64类型,IEEE-754 64位浮点数 c := 3 + 4i // complex128类型,内部使用两个float64表示 // var变量可以直接初始化。 @@ -392,15 +392,15 @@ func requestServer() { ## 更进一步 -关于Go的一切你都可以在[Go官方网站](http://golang.org/)找到。 +关于Go的一切你都可以在[Go官方网站](https://go.dev/)找到。 在那里你可以获得教程参考,在线试用,和更多的资料。 -在简单的尝试过后,在[官方文档](https://golang.org/doc/)那里你会得到你所需要的所有资料、关于编写代码的规范、库和命令行工具的文档与Go的版本历史。 +在简单的尝试过后,在[官方文档](https://go.dev/doc/)那里你会得到你所需要的所有资料、关于编写代码的规范、库和命令行工具的文档与Go的版本历史。 强烈推荐阅读语言定义部分,很简单而且很简洁!(赶时髦!) -你还可以前往[Go在线体验中心](https://play.golang.org/p/tnWMjr16Mm)进,在浏览器里修改并运行这些代码,一定要试一试哦!你可以将[https://play.golang.org](https://play.golang.org)当作一个[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop),在那里体验语言特性或运行自己的代码,连环境都不用配! +你还可以前往[Go在线体验中心](https://go.dev/play/p/tnWMjr16Mm)进,在浏览器里修改并运行这些代码,一定要试一试哦!你可以将[https://go.dev/play/](https://go.dev/play/)当作一个[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop),在那里体验语言特性或运行自己的代码,连环境都不用配! -学习Go还要阅读Go[标准库的源代码](http://golang.org/src/),全部文档化了,可读性非常好,可以学到go,go style和go idioms。在[文档](http://golang.org/pkg/)中点击函数名,源代码就出来了! +学习Go还要阅读Go[标准库的源代码](https://go.dev/src/),全部文档化了,可读性非常好,可以学到go,go style和go idioms。在[文档](https://go.dev/pkg/)中点击函数名,源代码就出来了! [Go by example](https://gobyexample.com/)也是一个学习的好地方。 diff --git a/zh-cn/json-cn.html.markdown b/zh-cn/json-cn.html.markdown index 73d3eb57..f5842c07 100644 --- a/zh-cn/json-cn.html.markdown +++ b/zh-cn/json-cn.html.markdown @@ -8,24 +8,30 @@ filename: learnjson-cn.json lang: zh-cn --- -因为JSON是一个极其简单的数据交换格式,本教程最有可能成为有史以来最简单的 -Learn X in Y Minutes。 +JSON是一个极其简单的数据交换格式。按[json.org](https://json.org)说的,它对人类易读易写,对机器易解析易生成。 -纯正的JSON实际上没有注释,但是大多数解析器都 -接受C-风格(//, /\* \*/)的注释。为了兼容性,最好不要在其中写这样形式的注释。 +一段JSON可以是下文列出的类型的任意值,但实际一般按以下两种方式之一呈现: + +* 一个键值对的集合(`{ }`)。按不同语言,这可能被理解为对象/记录/结构体/字典/哈希表/有键列表/关联数组 +* 一个有序的值列表(`[ ]`)。按不同语言,这可能被理解为数组/向量/列表/序列 + +纯正的JSON实际上没有注释,但是大多数解析器都接受C-风格(//, /\* \*/)的注释。一些解析器还容许trailing comma,即最后一个数组元素或最后一个对象属性之后的逗号。不过为了兼容性最好避免。 因此,本教程的一切都会是100%有效的JSON。幸亏,它的表达能力很丰富。 支持的数据类型: -- 字符串: "hello", "\"A quote.\"", "\u0abe", "Newline.\n" -- 数字: 23, 0.11, 12e10, 3.141e-10, 1.23e+4 -- 对象: { "key": "value" } -- 数组: ["Values"] -- 其他: true, false, null +* 字符串:`"hello"`、`"\"A quote.\""`、`"\u0abe"`、`"Newline.\n"` +* 数字:`23`、`0.11`、`12e10`、`3.141e-10`、`1.23e+4` +* 对象:`{ "key": "value" }` +* 数组:`["Values"]` +* 其它:`true`、`false`、`null` ```json { + "key": "value", + + "keys": "must always be enclosed in double quotes", "numbers": 0, "strings": "Hellø, wørld. All unicode is allowed, along with \"escaping\".", "has bools?": true, @@ -55,6 +61,23 @@ Learn X in Y Minutes。 ] ], - "that was short": "And, you're done. You now know everything JSON has to offer." + "alternative style": { + "comment": "check this out!" + , "comma position": "doesn't matter, if it's before the next key, it's valid" + , "another comment": "how nice" + }, + + + + "whitespace": "Does not matter.", + + + + "that was short": "And done. You now know everything JSON has to offer." } ``` + +## 进一步阅读 + +* [JSON.org](https://www.json.org/json-zh.html) 完美图解JSON的一切 +* [JSON Tutorial](https://www.youtube.com/watch?v=wI1CWzNtE-M) 简要介绍 diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown index 707d6927..23f27dda 100644 --- a/zh-cn/markdown-cn.html.markdown +++ b/zh-cn/markdown-cn.html.markdown @@ -147,7 +147,6 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以 - 项目 - 项目 - 最后一个项目 - ``` 有序序列可由数字加上点 `.` 来实现 @@ -188,6 +187,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以 下面这个选择框将会是选中状态 - [x] 这个任务已经完成 ``` + - [ ] 你看完了这个任务(注:此选择框是无法直接更改的,即禁用状态。) ## 代码块 @@ -204,7 +204,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以 ```md my_array.each do |item| - puts item + puts item end ``` @@ -216,12 +216,13 @@ John 甚至不知道 `go_to()` 函数是干嘛的! 在GitHub的 Markdown(GitHub Flavored Markdown)解析器中,你可以使用特殊的语法表示代码块 -<pre> -<code class="highlight">```ruby +````md +```ruby def foobar - puts "Hello world!" + puts "Hello world!" end -```</code></pre> +``` +```` 以上代码不需要缩进,而且 GitHub 会根据\`\`\`后指定的语言来进行语法高亮显示 @@ -246,7 +247,6 @@ Markdown 最棒的地方就是便捷的书写链接。把链接文字放在中 ```md [点我点我!](http://test.com/) - ``` 你也可以在小括号内使用引号,为链接加上一个标题(title) @@ -345,6 +345,7 @@ Markdown同样支持引用形式的链接 | 我是左对齐 | 居个中 | 右对齐 | | 注意 | 冒 | 号 | ``` + 好吧,强行对齐字符是很难的。但是,至少比下面这种写法好一点—— ```md @@ -352,6 +353,7 @@ Markdown同样支持引用形式的链接 :-- | :-: | --: 这真的太丑了 | 药不能 | 停!!!! ``` + 真的是*看着令人头晕* diff --git a/zh-cn/matlab-cn.html.markdown b/zh-cn/matlab-cn.html.markdown index ca08b36b..bb1ab79a 100644 --- a/zh-cn/matlab-cn.html.markdown +++ b/zh-cn/matlab-cn.html.markdown @@ -1,504 +1,504 @@ ----
-language: MATLAB
-filename: matlab-cn.m
-contributors:
- - ["mendozao", "http://github.com/mendozao"]
- - ["jamesscottbrown", "http://jamesscottbrown.com"]
-translators:
- - ["sunxb10", "https://github.com/sunxb10"]
-lang: zh-cn
-
----
-
-MATLAB 是 MATrix LABoratory(矩阵实验室)的缩写。
-它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
-
-如果您有任何需要反馈或交流的内容,请联系本教程作者:
-[@the_ozzinator](https://twitter.com/the_ozzinator)
-或 [osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
-
-```matlab
-% 以百分号作为注释符
-
-%{
-多行注释
-可以
-这样
-表示
-%}
-
-% 指令可以随意跨行,但需要在跨行处用 '...' 标明:
- a = 1 + 2 + ...
- + 4
-
-% 可以在MATLAB中直接向操作系统发出指令
-!ping google.com
-
-who % 显示内存中的所有变量
-whos % 显示内存中的所有变量以及它们的类型
-clear % 清除内存中的所有变量
-clear('A') % 清除指定的变量
-openvar('A') % 在变量编辑器中编辑指定变量
-
-clc % 清除命令窗口中显示的所有指令
-diary % 将命令窗口中的内容写入本地文件
-ctrl-c % 终止当前计算
-
-edit('myfunction.m') % 在编辑器中打开指定函数或脚本
-type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
-
-profile on % 打开 profile 代码分析工具
-profile off % 关闭 profile 代码分析工具
-profile viewer % 查看 profile 代码分析工具的分析结果
-
-help command % 在命令窗口中显示指定命令的帮助文档
-doc command % 在帮助窗口中显示指定命令的帮助文档
-lookfor command % 在所有 MATLAB 内置函数的头部注释块的第一行中搜索指定命令
-lookfor command -all % 在所有 MATLAB 内置函数的整个头部注释块中搜索指定命令
-
-
-% 输出格式
-format short % 浮点数保留 4 位小数
-format long % 浮点数保留 15 位小数
-format bank % 金融格式,浮点数只保留 2 位小数
-fprintf('text') % 在命令窗口中显示 "text"
-disp('text') % 在命令窗口中显示 "text"
-
-
-% 变量与表达式
-myVariable = 4 % 命令窗口中将新创建的变量
-myVariable = 4; % 加上分号可使命令窗口中不显示当前语句执行结果
-4 + 6 % ans = 10
-8 * myVariable % ans = 32
-2 ^ 3 % ans = 8
-a = 2; b = 3;
-c = exp(a)*sin(pi/2) % c = 7.3891
-
-
-% 调用函数有两种方式:
-% 标准函数语法:
-load('myFile.mat', 'y') % 参数放在括号内,以英文逗号分隔
-% 指令语法:
-load myFile.mat y % 不加括号,以空格分隔参数
-% 注意在指令语法中参数不需要加引号:在这种语法下,所有输入参数都只能是文本文字,
-% 不能是变量的具体值,同样也不能是输出变量
-[V,D] = eig(A); % 这条函数调用无法转换成等价的指令语法
-[~,D] = eig(A); % 如果结果中只需要 D 而不需要 V 则可以这样写
-
-
-
-% 逻辑运算
-1 > 5 % 假,ans = 0
-10 >= 10 % 真,ans = 1
-3 ~= 4 % 不等于 -> ans = 1
-3 == 3 % 等于 -> ans = 1
-3 > 1 && 4 > 1 % 与 -> ans = 1
-3 > 1 || 4 > 1 % 或 -> ans = 1
-~1 % 非 -> ans = 0
-
-% 逻辑运算可直接应用于矩阵,运算结果也是矩阵
-A > 5
-% 对矩阵中每个元素做逻辑运算,若为真,则在运算结果的矩阵中对应位置的元素就是 1
-A( A > 5 )
-% 如此返回的向量,其元素就是 A 矩阵中所有逻辑运算为真的元素
-
-% 字符串
-a = 'MyString'
-length(a) % ans = 8
-a(2) % ans = y
-[a,a] % ans = MyStringMyString
-b = '字符串' % MATLAB目前已经可以支持包括中文在内的多种文字
-length(b) % ans = 3
-b(2) % ans = 符
-[b,b] % ans = 字符串字符串
-
-
-% 元组(cell 数组)
-a = {'one', 'two', 'three'}
-a(1) % ans = 'one' - 返回一个元组
-a{1} % ans = one - 返回一个字符串
-
-
-% 结构体
-A.b = {'one','two'};
-A.c = [1 2];
-A.d.e = false;
-
-
-% 向量
-x = [4 32 53 7 1]
-x(2) % ans = 32,MATLAB中向量的下标索引从1开始,不是0
-x(2:3) % ans = 32 53
-x(2:end) % ans = 32 53 7 1
-
-x = [4; 32; 53; 7; 1] % 列向量
-
-x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
-
-
-% 矩阵
-A = [1 2 3; 4 5 6; 7 8 9]
-% 以分号分隔不同的行,以空格或逗号分隔同一行中的不同元素
-% A =
-
-% 1 2 3
-% 4 5 6
-% 7 8 9
-
-A(2,3) % ans = 6,A(row, column)
-A(6) % ans = 8
-% (隐式地将 A 的三列首尾相接组成一个列向量,然后取其下标为 6 的元素)
-
-
-A(2,3) = 42 % 将第 2 行第 3 列的元素设为 42
-% A =
-
-% 1 2 3
-% 4 5 42
-% 7 8 9
-
-A(2:3,2:3) % 取原矩阵中的一块作为新矩阵
-%ans =
-
-% 5 42
-% 8 9
-
-A(:,1) % 第 1 列的所有元素
-%ans =
-
-% 1
-% 4
-% 7
-
-A(1,:) % 第 1 行的所有元素
-%ans =
-
-% 1 2 3
-
-[A ; A] % 将两个矩阵上下相接构成新矩阵
-%ans =
-
-% 1 2 3
-% 4 5 42
-% 7 8 9
-% 1 2 3
-% 4 5 42
-% 7 8 9
-
-% 等价于
-vertcat(A, A);
-
-
-[A , A] % 将两个矩阵左右相接构成新矩阵
-
-%ans =
-
-% 1 2 3 1 2 3
-% 4 5 42 4 5 42
-% 7 8 9 7 8 9
-
-% 等价于
-horzcat(A, A);
-
-
-A(:, [3 1 2]) % 重新排布原矩阵的各列
-%ans =
-
-% 3 1 2
-% 42 4 5
-% 9 7 8
-
-size(A) % 返回矩阵的行数和列数,ans = 3 3
-
-A(1, :) =[] % 删除矩阵的第 1 行
-A(:, 1) =[] % 删除矩阵的第 1 列
-
-transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
-ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数),等价于 A'
-
-
-% 元素运算 vs. 矩阵运算
-% 单独运算符就是对矩阵整体进行矩阵运算
-% 在运算符加上英文句点就是对矩阵中的元素进行元素计算
-% 示例如下:
-A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
-A .* B % 元素乘法,要求 A 和 B 形状一致,即两矩阵行列数完全一致
- % 元素乘法的结果是与 A 和 B 形状一致的矩阵
- % 其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
-
-% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
-exp(A) % 对矩阵中每个元素做指数运算
-expm(A) % 对矩阵整体做指数运算
-sqrt(A) % 对矩阵中每个元素做开方运算
-sqrtm(A) % 对矩阵整体做开方运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
-
-
-% 绘图
-x = 0:0.1:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi
- % 其中 pi 为圆周率
-y = sin(x);
-plot(x,y)
-xlabel('x axis')
-ylabel('y axis')
-title('Plot of y = sin(x)')
-axis([0 2*pi -1 1]) % x 轴范围是从 0 到 2*pi,y 轴范围是从 -1 到 1
-
-plot(x,y1,'-',x,y2,'--',x,y3,':') % 在同一张图中绘制多条曲线
-legend('Line 1 label', 'Line 2 label') % 为图片加注图例
-% 图例数量应当小于或等于实际绘制的曲线数目,从 plot 绘制的第一条曲线开始对应
-
-% 在同一张图上绘制多条曲线的另一种方法:
-% 使用 hold on,令系统保留前次绘图结果并在其上直接叠加新的曲线,
-% 如果没有 hold on,则每个 plot 都会首先清除之前的绘图结果再进行绘制。
-% 在 hold on 和 hold off 中可以放置任意多的 plot 指令,
-% 它们和 hold on 前最后一个 plot 指令的结果都将显示在同一张图中。
-plot(x, y1)
-hold on
-plot(x, y2)
-plot(x, y3)
-plot(x, y4)
-hold off
-
-loglog(x, y) % 对数—对数绘图
-semilogx(x, y) % 半对数(x 轴对数)绘图
-semilogy(x, y) % 半对数(y 轴对数)绘图
-
-fplot (@(x) x^2, [2,5]) % 绘制函数 x^2 在 [2, 5] 区间的曲线
-
-grid on % 在绘制的图中显示网格,使用 grid off 可取消网格显示
-axis square % 将当前坐标系设定为正方形(保证在图形显示上各轴等长)
-axis equal % 将当前坐标系设定为相等(保证在实际数值上各轴等长)
-
-scatter(x, y); % 散点图
-hist(x); % 直方图
-
-z = sin(x);
-plot3(x,y,z); % 绘制三维曲线
-
-pcolor(A) % 伪彩色图(热图)
-contour(A) % 等高线图
-mesh(A) % 网格曲面图
-
-h = figure % 创建新的图片对象并返回其句柄 h
-figure(h) % 将句柄 h 对应的图片作为当前图片
-close(h) % 关闭句柄 h 对应的图片
-close all % 关闭 MATLAB 中所用打开的图片
-close % 关闭当前图片
-
-shg % 显示图形窗口
-clf clear % 清除图形窗口中的图像,并重置图像属性
-
-% 图像属性可以通过图像句柄进行设定
-% 在创建图像时可以保存图像句柄以便于设置
-% 也可以用 gcf 函数返回当前图像的句柄
-h = plot(x, y); % 在创建图像时显式地保存图像句柄
-set(h, 'Color', 'r')
-% 颜色代码:
-% 'y' 黄色,'m' 洋红,'c' 青色
-% 'r' 红色,'g' 绿色,'b' 蓝色
-% 'w' 白色,'k' 黑色
-set(h, 'Color', [0.5, 0.5, 0.4])
-% 也可以使用 RGB 值指定颜色
-set(h, 'LineStyle', '--')
-% 线型代码:'--' 实线,'---' 虚线,':' 点线,'-.' 点划线,'none' 不划线
-get(h, 'LineStyle')
-% 获取当前句柄的线型
-
-
-% 用 gca 函数返回当前图像的坐标轴句柄
-set(gca, 'XDir', 'reverse'); % 令 x 轴反向
-
-% 用 subplot 指令创建平铺排列的多张子图
-subplot(2,3,1); % 选择 2 x 3 排列的子图中的第 1 张图
-plot(x1); title('First Plot') % 在选中的图中绘图
-subplot(2,3,2); % 选择 2 x 3 排列的子图中的第 2 张图
-plot(x2); title('Second Plot') % 在选中的图中绘图
-
-
-% 要调用函数或脚本,必须保证它们在你的当前工作目录中
-path % 显示当前工作目录
-addpath /path/to/dir % 将指定路径加入到当前工作目录中
-rmpath /path/to/dir % 将指定路径从当前工作目录中删除
-cd /path/to/move/into % 以制定路径作为当前工作目录
-
-
-% 变量可保存到 .mat 格式的本地文件
-save('myFileName.mat') % 保存当前工作空间中的所有变量
-load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间
-
-
-% .m 脚本文件
-% 脚本文件是一个包含多条 MATLAB 指令的外部文件,以 .m 为后缀名
-% 使用脚本文件可以避免在命令窗口中重复输入冗长的指令
-
-
-% .m 函数文件
-% 与脚本文件类似,同样以 .m 作为后缀名
-% 但函数文件可以接受用户输入的参数并返回运算结果
-% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
-% 函数文件的名称应当与其所定义的函数的名称一致
-% 比如下面例子中函数文件就应命名为 double_input.m
-% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
-function output = double_input(x)
- % double_input(x) 返回 x 的 2 倍
- output = 2*x;
-end
-double_input(6) % ans = 12
-
-
-% 同样还可以定义子函数和内嵌函数
-% 子函数与主函数放在同一个函数文件中,且只能被这个主函数调用
-% 内嵌函数放在另一个函数体内,可以直接访问被嵌套函数的各个变量
-
-
-% 使用匿名函数可以不必创建 .m 函数文件
-% 匿名函数适用于快速定义某函数以便传递给另一指令或函数(如绘图、积分、求根、求极值等)
-% 下面示例的匿名函数返回输入参数的平方根,可以使用句柄 sqr 进行调用:
-sqr = @(x) x.^2;
-sqr(10) % ans = 100
-doc function_handle % find out more
-
-
-% 接受用户输入
-a = input('Enter the value: ')
-
-
-% 从文件中读取数据
-fopen(filename)
-% 类似函数还有 xlsread(excel 文件)、importdata(CSV 文件)、imread(图像文件)
-
-
-% 输出
-disp(a) % 在命令窗口中打印变量 a 的值
-disp('Hello World') % 在命令窗口中打印字符串
-fprintf % 按照指定格式在命令窗口中打印内容
-
-% 条件语句(if 和 elseif 语句中的括号并非必需,但推荐加括号避免混淆)
-if (a > 15)
- disp('Greater than 15')
-elseif (a == 23)
- disp('a is 23')
-else
- disp('neither condition met')
-end
-
-% 循环语句
-% 注意:对向量或矩阵使用循环语句进行元素遍历的效率很低!!
-% 注意:只要有可能,就尽量使用向量或矩阵的整体运算取代逐元素循环遍历!!
-% MATLAB 在开发时对向量和矩阵运算做了专门优化,做向量和矩阵整体运算的效率高于循环语句
-for k = 1:5
- disp(k)
-end
-
-k = 0;
-while (k < 5)
- k = k + 1;
-end
-
-
-% 程序运行计时:'tic' 是计时开始,'toc' 是计时结束并打印结果
-tic
-A = rand(1000);
-A*A*A*A*A*A*A;
-toc
-
-
-% 链接 MySQL 数据库
-dbname = 'database_name';
-username = 'root';
-password = 'root';
-driver = 'com.mysql.jdbc.Driver';
-dburl = ['jdbc:mysql://localhost:8889/' dbname];
-javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); % 此处 xx 代表具体版本号
-% 这里的 mysql-connector-java-5.1.xx-bin.jar 可从 http://dev.mysql.com/downloads/connector/j/ 下载
-conn = database(dbname, username, password, driver, dburl);
-sql = ['SELECT * from table_name where id = 22'] % SQL 语句
-a = fetch(conn, sql) % a 即包含所需数据
-
-
-% 常用数学函数
-sin(x)
-cos(x)
-tan(x)
-asin(x)
-acos(x)
-atan(x)
-exp(x)
-sqrt(x)
-log(x)
-log10(x)
-abs(x)
-min(x)
-max(x)
-ceil(x)
-floor(x)
-round(x)
-rem(x)
-rand % 均匀分布的伪随机浮点数
-randi % 均匀分布的伪随机整数
-randn % 正态分布的伪随机浮点数
-
-% 常用常数
-pi
-NaN
-inf
-
-% 求解矩阵方程(如果方程无解,则返回最小二乘近似解)
-% \ 操作符等价于 mldivide 函数,/ 操作符等价于 mrdivide 函数
-x=A\b % 求解 Ax=b,比先求逆再左乘 inv(A)*b 更加高效、准确
-x=b/A % 求解 xA=b
-
-inv(A) % 逆矩阵
-pinv(A) % 伪逆矩阵
-
-
-% 常用矩阵函数
-zeros(m, n) % m x n 阶矩阵,元素全为 0
-ones(m, n) % m x n 阶矩阵,元素全为 1
-diag(A) % 返回矩阵 A 的对角线元素
-diag(x) % 构造一个对角阵,对角线元素就是向量 x 的各元素
-eye(m, n) % m x n 阶单位矩阵
-linspace(x1, x2, n) % 返回介于 x1 和 x2 之间的 n 个等距节点
-inv(A) % 矩阵 A 的逆矩阵
-det(A) % 矩阵 A 的行列式
-eig(A) % 矩阵 A 的特征值和特征向量
-trace(A) % 矩阵 A 的迹(即对角线元素之和),等价于 sum(diag(A))
-isempty(A) % 测试 A 是否为空
-all(A) % 测试 A 中所有元素是否都非 0 或都为真(逻辑值)
-any(A) % 测试 A 中是否有元素非 0 或为真(逻辑值)
-isequal(A, B) % 测试 A 和 B是否相等
-numel(A) % 矩阵 A 的元素个数
-triu(x) % 返回 x 的上三角这部分
-tril(x) % 返回 x 的下三角这部分
-cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
-dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
-transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
-fliplr(A) % 将一个矩阵左右翻转
-flipud(A) % 将一个矩阵上下翻转
-
-% 矩阵分解
-[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
-[P, D] = eig(A) % 特征值分解:AP = PD
- % D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
-[U, S, V] = svd(X) % 奇异值分解:XV = US
- % U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
-
-% 常用向量函数
-max % 最大值
-min % 最小值
-length % 元素个数
-sort % 按升序排列
-sum % 各元素之和
-prod % 各元素之积
-mode % 众数
-median % 中位数
-mean % 平均值
-std % 标准差
-perms(x) % x 元素的全排列
-
-```
-
-## 相关资料
-
-* 官方网页:[MATLAB - 技术计算语言 - MATLAB & Simulink](https://ww2.mathworks.cn/products/matlab.html)
-* 官方论坛:[MATLAB Answers - MATLAB Central](https://ww2.mathworks.cn/matlabcentral/answers/)
+--- +language: MATLAB +filename: matlab-cn.m +contributors: + - ["mendozao", "http://github.com/mendozao"] + - ["jamesscottbrown", "http://jamesscottbrown.com"] +translators: + - ["sunxb10", "https://github.com/sunxb10"] +lang: zh-cn + +--- + +MATLAB 是 MATrix LABoratory(矩阵实验室)的缩写。 +它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。 + +如果您有任何需要反馈或交流的内容,请联系本教程作者: +[@the_ozzinator](https://twitter.com/the_ozzinator) +或 [osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。 + +```matlab +% 以百分号作为注释符 + +%{ +多行注释 +可以 +这样 +表示 +%} + +% 指令可以随意跨行,但需要在跨行处用 '...' 标明: + a = 1 + 2 + ... + + 4 + +% 可以在MATLAB中直接向操作系统发出指令 +!ping google.com + +who % 显示内存中的所有变量 +whos % 显示内存中的所有变量以及它们的类型 +clear % 清除内存中的所有变量 +clear('A') % 清除指定的变量 +openvar('A') % 在变量编辑器中编辑指定变量 + +clc % 清除命令窗口中显示的所有指令 +diary % 将命令窗口中的内容写入本地文件 +ctrl-c % 终止当前计算 + +edit('myfunction.m') % 在编辑器中打开指定函数或脚本 +type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码 + +profile on % 打开 profile 代码分析工具 +profile off % 关闭 profile 代码分析工具 +profile viewer % 查看 profile 代码分析工具的分析结果 + +help command % 在命令窗口中显示指定命令的帮助文档 +doc command % 在帮助窗口中显示指定命令的帮助文档 +lookfor command % 在所有 MATLAB 内置函数的头部注释块的第一行中搜索指定命令 +lookfor command -all % 在所有 MATLAB 内置函数的整个头部注释块中搜索指定命令 + + +% 输出格式 +format short % 浮点数保留 4 位小数 +format long % 浮点数保留 15 位小数 +format bank % 金融格式,浮点数只保留 2 位小数 +fprintf('text') % 在命令窗口中显示 "text" +disp('text') % 在命令窗口中显示 "text" + + +% 变量与表达式 +myVariable = 4 % 命令窗口中将新创建的变量 +myVariable = 4; % 加上分号可使命令窗口中不显示当前语句执行结果 +4 + 6 % ans = 10 +8 * myVariable % ans = 32 +2 ^ 3 % ans = 8 +a = 2; b = 3; +c = exp(a)*sin(pi/2) % c = 7.3891 + + +% 调用函数有两种方式: +% 标准函数语法: +load('myFile.mat', 'y') % 参数放在括号内,以英文逗号分隔 +% 指令语法: +load myFile.mat y % 不加括号,以空格分隔参数 +% 注意在指令语法中参数不需要加引号:在这种语法下,所有输入参数都只能是文本文字, +% 不能是变量的具体值,同样也不能是输出变量 +[V,D] = eig(A); % 这条函数调用无法转换成等价的指令语法 +[~,D] = eig(A); % 如果结果中只需要 D 而不需要 V 则可以这样写 + + + +% 逻辑运算 +1 > 5 % 假,ans = 0 +10 >= 10 % 真,ans = 1 +3 ~= 4 % 不等于 -> ans = 1 +3 == 3 % 等于 -> ans = 1 +3 > 1 && 4 > 1 % 与 -> ans = 1 +3 > 1 || 4 > 1 % 或 -> ans = 1 +~1 % 非 -> ans = 0 + +% 逻辑运算可直接应用于矩阵,运算结果也是矩阵 +A > 5 +% 对矩阵中每个元素做逻辑运算,若为真,则在运算结果的矩阵中对应位置的元素就是 1 +A( A > 5 ) +% 如此返回的向量,其元素就是 A 矩阵中所有逻辑运算为真的元素 + +% 字符串 +a = 'MyString' +length(a) % ans = 8 +a(2) % ans = y +[a,a] % ans = MyStringMyString +b = '字符串' % MATLAB目前已经可以支持包括中文在内的多种文字 +length(b) % ans = 3 +b(2) % ans = 符 +[b,b] % ans = 字符串字符串 + + +% 元组(cell 数组) +a = {'one', 'two', 'three'} +a(1) % ans = 'one' - 返回一个元组 +a{1} % ans = one - 返回一个字符串 + + +% 结构体 +A.b = {'one','two'}; +A.c = [1 2]; +A.d.e = false; + + +% 向量 +x = [4 32 53 7 1] +x(2) % ans = 32,MATLAB中向量的下标索引从1开始,不是0 +x(2:3) % ans = 32 53 +x(2:end) % ans = 32 53 7 1 + +x = [4; 32; 53; 7; 1] % 列向量 + +x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10 + + +% 矩阵 +A = [1 2 3; 4 5 6; 7 8 9] +% 以分号分隔不同的行,以空格或逗号分隔同一行中的不同元素 +% A = + +% 1 2 3 +% 4 5 6 +% 7 8 9 + +A(2,3) % ans = 6,A(row, column) +A(6) % ans = 8 +% (隐式地将 A 的三列首尾相接组成一个列向量,然后取其下标为 6 的元素) + + +A(2,3) = 42 % 将第 2 行第 3 列的元素设为 42 +% A = + +% 1 2 3 +% 4 5 42 +% 7 8 9 + +A(2:3,2:3) % 取原矩阵中的一块作为新矩阵 +%ans = + +% 5 42 +% 8 9 + +A(:,1) % 第 1 列的所有元素 +%ans = + +% 1 +% 4 +% 7 + +A(1,:) % 第 1 行的所有元素 +%ans = + +% 1 2 3 + +[A ; A] % 将两个矩阵上下相接构成新矩阵 +%ans = + +% 1 2 3 +% 4 5 42 +% 7 8 9 +% 1 2 3 +% 4 5 42 +% 7 8 9 + +% 等价于 +vertcat(A, A); + + +[A , A] % 将两个矩阵左右相接构成新矩阵 + +%ans = + +% 1 2 3 1 2 3 +% 4 5 42 4 5 42 +% 7 8 9 7 8 9 + +% 等价于 +horzcat(A, A); + + +A(:, [3 1 2]) % 重新排布原矩阵的各列 +%ans = + +% 3 1 2 +% 42 4 5 +% 9 7 8 + +size(A) % 返回矩阵的行数和列数,ans = 3 3 + +A(1, :) =[] % 删除矩阵的第 1 行 +A(:, 1) =[] % 删除矩阵的第 1 列 + +transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点) +ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数),等价于 A' + + +% 元素运算 vs. 矩阵运算 +% 单独运算符就是对矩阵整体进行矩阵运算 +% 在运算符加上英文句点就是对矩阵中的元素进行元素计算 +% 示例如下: +A * B % 矩阵乘法,要求 A 的列数等于 B 的行数 +A .* B % 元素乘法,要求 A 和 B 形状一致,即两矩阵行列数完全一致 + % 元素乘法的结果是与 A 和 B 形状一致的矩阵 + % 其每个元素等于 A 对应位置的元素乘 B 对应位置的元素 + +% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算: +exp(A) % 对矩阵中每个元素做指数运算 +expm(A) % 对矩阵整体做指数运算 +sqrt(A) % 对矩阵中每个元素做开方运算 +sqrtm(A) % 对矩阵整体做开方运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵) + + +% 绘图 +x = 0:0.1:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi + % 其中 pi 为圆周率 +y = sin(x); +plot(x,y) +xlabel('x axis') +ylabel('y axis') +title('Plot of y = sin(x)') +axis([0 2*pi -1 1]) % x 轴范围是从 0 到 2*pi,y 轴范围是从 -1 到 1 + +plot(x,y1,'-',x,y2,'--',x,y3,':') % 在同一张图中绘制多条曲线 +legend('Line 1 label', 'Line 2 label') % 为图片加注图例 +% 图例数量应当小于或等于实际绘制的曲线数目,从 plot 绘制的第一条曲线开始对应 + +% 在同一张图上绘制多条曲线的另一种方法: +% 使用 hold on,令系统保留前次绘图结果并在其上直接叠加新的曲线, +% 如果没有 hold on,则每个 plot 都会首先清除之前的绘图结果再进行绘制。 +% 在 hold on 和 hold off 中可以放置任意多的 plot 指令, +% 它们和 hold on 前最后一个 plot 指令的结果都将显示在同一张图中。 +plot(x, y1) +hold on +plot(x, y2) +plot(x, y3) +plot(x, y4) +hold off + +loglog(x, y) % 对数—对数绘图 +semilogx(x, y) % 半对数(x 轴对数)绘图 +semilogy(x, y) % 半对数(y 轴对数)绘图 + +fplot (@(x) x^2, [2,5]) % 绘制函数 x^2 在 [2, 5] 区间的曲线 + +grid on % 在绘制的图中显示网格,使用 grid off 可取消网格显示 +axis square % 将当前坐标系设定为正方形(保证在图形显示上各轴等长) +axis equal % 将当前坐标系设定为相等(保证在实际数值上各轴等长) + +scatter(x, y); % 散点图 +hist(x); % 直方图 + +z = sin(x); +plot3(x,y,z); % 绘制三维曲线 + +pcolor(A) % 伪彩色图(热图) +contour(A) % 等高线图 +mesh(A) % 网格曲面图 + +h = figure % 创建新的图片对象并返回其句柄 h +figure(h) % 将句柄 h 对应的图片作为当前图片 +close(h) % 关闭句柄 h 对应的图片 +close all % 关闭 MATLAB 中所用打开的图片 +close % 关闭当前图片 + +shg % 显示图形窗口 +clf clear % 清除图形窗口中的图像,并重置图像属性 + +% 图像属性可以通过图像句柄进行设定 +% 在创建图像时可以保存图像句柄以便于设置 +% 也可以用 gcf 函数返回当前图像的句柄 +h = plot(x, y); % 在创建图像时显式地保存图像句柄 +set(h, 'Color', 'r') +% 颜色代码: +% 'y' 黄色,'m' 洋红,'c' 青色 +% 'r' 红色,'g' 绿色,'b' 蓝色 +% 'w' 白色,'k' 黑色 +set(h, 'Color', [0.5, 0.5, 0.4]) +% 也可以使用 RGB 值指定颜色 +set(h, 'LineStyle', '--') +% 线型代码:'--' 实线,'---' 虚线,':' 点线,'-.' 点划线,'none' 不划线 +get(h, 'LineStyle') +% 获取当前句柄的线型 + + +% 用 gca 函数返回当前图像的坐标轴句柄 +set(gca, 'XDir', 'reverse'); % 令 x 轴反向 + +% 用 subplot 指令创建平铺排列的多张子图 +subplot(2,3,1); % 选择 2 x 3 排列的子图中的第 1 张图 +plot(x1); title('First Plot') % 在选中的图中绘图 +subplot(2,3,2); % 选择 2 x 3 排列的子图中的第 2 张图 +plot(x2); title('Second Plot') % 在选中的图中绘图 + + +% 要调用函数或脚本,必须保证它们在你的当前工作目录中 +path % 显示当前工作目录 +addpath /path/to/dir % 将指定路径加入到当前工作目录中 +rmpath /path/to/dir % 将指定路径从当前工作目录中删除 +cd /path/to/move/into % 以制定路径作为当前工作目录 + + +% 变量可保存到 .mat 格式的本地文件 +save('myFileName.mat') % 保存当前工作空间中的所有变量 +load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间 + + +% .m 脚本文件 +% 脚本文件是一个包含多条 MATLAB 指令的外部文件,以 .m 为后缀名 +% 使用脚本文件可以避免在命令窗口中重复输入冗长的指令 + + +% .m 函数文件 +% 与脚本文件类似,同样以 .m 作为后缀名 +% 但函数文件可以接受用户输入的参数并返回运算结果 +% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突 +% 函数文件的名称应当与其所定义的函数的名称一致 +% 比如下面例子中函数文件就应命名为 double_input.m +% 使用 'help double_input.m' 可返回函数定义中第一行注释信息 +function output = double_input(x) + % double_input(x) 返回 x 的 2 倍 + output = 2*x; +end +double_input(6) % ans = 12 + + +% 同样还可以定义子函数和内嵌函数 +% 子函数与主函数放在同一个函数文件中,且只能被这个主函数调用 +% 内嵌函数放在另一个函数体内,可以直接访问被嵌套函数的各个变量 + + +% 使用匿名函数可以不必创建 .m 函数文件 +% 匿名函数适用于快速定义某函数以便传递给另一指令或函数(如绘图、积分、求根、求极值等) +% 下面示例的匿名函数返回输入参数的平方根,可以使用句柄 sqr 进行调用: +sqr = @(x) x.^2; +sqr(10) % ans = 100 +doc function_handle % find out more + + +% 接受用户输入 +a = input('Enter the value: ') + + +% 从文件中读取数据 +fopen(filename) +% 类似函数还有 xlsread(excel 文件)、importdata(CSV 文件)、imread(图像文件) + + +% 输出 +disp(a) % 在命令窗口中打印变量 a 的值 +disp('Hello World') % 在命令窗口中打印字符串 +fprintf % 按照指定格式在命令窗口中打印内容 + +% 条件语句(if 和 elseif 语句中的括号并非必需,但推荐加括号避免混淆) +if (a > 15) + disp('Greater than 15') +elseif (a == 23) + disp('a is 23') +else + disp('neither condition met') +end + +% 循环语句 +% 注意:对向量或矩阵使用循环语句进行元素遍历的效率很低!! +% 注意:只要有可能,就尽量使用向量或矩阵的整体运算取代逐元素循环遍历!! +% MATLAB 在开发时对向量和矩阵运算做了专门优化,做向量和矩阵整体运算的效率高于循环语句 +for k = 1:5 + disp(k) +end + +k = 0; +while (k < 5) + k = k + 1; +end + + +% 程序运行计时:'tic' 是计时开始,'toc' 是计时结束并打印结果 +tic +A = rand(1000); +A*A*A*A*A*A*A; +toc + + +% 链接 MySQL 数据库 +dbname = 'database_name'; +username = 'root'; +password = 'root'; +driver = 'com.mysql.jdbc.Driver'; +dburl = ['jdbc:mysql://localhost:8889/' dbname]; +javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); % 此处 xx 代表具体版本号 +% 这里的 mysql-connector-java-5.1.xx-bin.jar 可从 http://dev.mysql.com/downloads/connector/j/ 下载 +conn = database(dbname, username, password, driver, dburl); +sql = ['SELECT * from table_name where id = 22'] % SQL 语句 +a = fetch(conn, sql) % a 即包含所需数据 + + +% 常用数学函数 +sin(x) +cos(x) +tan(x) +asin(x) +acos(x) +atan(x) +exp(x) +sqrt(x) +log(x) +log10(x) +abs(x) +min(x) +max(x) +ceil(x) +floor(x) +round(x) +rem(x) +rand % 均匀分布的伪随机浮点数 +randi % 均匀分布的伪随机整数 +randn % 正态分布的伪随机浮点数 + +% 常用常数 +pi +NaN +inf + +% 求解矩阵方程(如果方程无解,则返回最小二乘近似解) +% \ 操作符等价于 mldivide 函数,/ 操作符等价于 mrdivide 函数 +x=A\b % 求解 Ax=b,比先求逆再左乘 inv(A)*b 更加高效、准确 +x=b/A % 求解 xA=b + +inv(A) % 逆矩阵 +pinv(A) % 伪逆矩阵 + + +% 常用矩阵函数 +zeros(m, n) % m x n 阶矩阵,元素全为 0 +ones(m, n) % m x n 阶矩阵,元素全为 1 +diag(A) % 返回矩阵 A 的对角线元素 +diag(x) % 构造一个对角阵,对角线元素就是向量 x 的各元素 +eye(m, n) % m x n 阶单位矩阵 +linspace(x1, x2, n) % 返回介于 x1 和 x2 之间的 n 个等距节点 +inv(A) % 矩阵 A 的逆矩阵 +det(A) % 矩阵 A 的行列式 +eig(A) % 矩阵 A 的特征值和特征向量 +trace(A) % 矩阵 A 的迹(即对角线元素之和),等价于 sum(diag(A)) +isempty(A) % 测试 A 是否为空 +all(A) % 测试 A 中所有元素是否都非 0 或都为真(逻辑值) +any(A) % 测试 A 中是否有元素非 0 或为真(逻辑值) +isequal(A, B) % 测试 A 和 B是否相等 +numel(A) % 矩阵 A 的元素个数 +triu(x) % 返回 x 的上三角这部分 +tril(x) % 返回 x 的下三角这部分 +cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积) +dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长 +transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点) +fliplr(A) % 将一个矩阵左右翻转 +flipud(A) % 将一个矩阵上下翻转 + +% 矩阵分解 +[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵 +[P, D] = eig(A) % 特征值分解:AP = PD + % D 是由特征值构成的对角阵,P 的各列就是对应的特征向量 +[U, S, V] = svd(X) % 奇异值分解:XV = US + % U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵 + +% 常用向量函数 +max % 最大值 +min % 最小值 +length % 元素个数 +sort % 按升序排列 +sum % 各元素之和 +prod % 各元素之积 +mode % 众数 +median % 中位数 +mean % 平均值 +std % 标准差 +perms(x) % x 元素的全排列 + +``` + +## 相关资料 + +* 官方网页:[MATLAB - 技术计算语言 - MATLAB & Simulink](https://ww2.mathworks.cn/products/matlab.html) +* 官方论坛:[MATLAB Answers - MATLAB Central](https://ww2.mathworks.cn/matlabcentral/answers/) diff --git a/zh-cn/nim-cn.html.markdown b/zh-cn/nim-cn.html.markdown index dc662b1e..fa7d8259 100644 --- a/zh-cn/nim-cn.html.markdown +++ b/zh-cn/nim-cn.html.markdown @@ -3,7 +3,7 @@ language: Nim filename: learnNim-cn.nim contributors: - ["Jason J. Ayala P.", "http://JasonAyala.com"] - - ["Dennis Felsing", "http://felsin9.de/nnis/"] + - ["Dennis Felsing", "https://dennis.felsing.org"] translators: - ["lzw-723", "https://github.com/lzw-723"] lang: zh-cn diff --git a/zh-cn/pyqt-cn.html.markdown b/zh-cn/pyqt-cn.html.markdown index 55e5bbe3..04041c83 100644 --- a/zh-cn/pyqt-cn.html.markdown +++ b/zh-cn/pyqt-cn.html.markdown @@ -19,7 +19,7 @@ lang: zh-cn ```python import sys from PyQt4 import QtGui - + def window(): # 创建应用对象 app = QtGui.QApplication(sys.argv) @@ -44,7 +44,7 @@ if __name__ == '__main__': 为了运用 pyqt 中一些更高级的功能,我们需要开始学习使用其他控件。下文演示了如何弹出对话框,该对话框在用户确认操作或输入信息等情况下经常用到。 -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -62,7 +62,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # 对话框窗口创建函数 # 当窗口中的按钮被点击时退出本程序 def showdialog(): diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown index 63adab64..b0b8b58c 100644 --- a/zh-cn/ruby-cn.html.markdown +++ b/zh-cn/ruby-cn.html.markdown @@ -430,7 +430,7 @@ def guests(*array) array.each { |guest| puts guest } end -# 结构 +# 解构 # 如果函数返回一个数组,在赋值时可以进行拆分: def foods @@ -449,7 +449,7 @@ end best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus. -# 结构操作符也可放在参数里面 +# 解构操作符也可放在参数里面 def best(first, second, third, *others) puts "Winners are #{first}, #{second}, and #{third}." puts "There were #{others.count} other participants." diff --git a/zh-cn/visualbasic-cn.html.markdown b/zh-cn/visualbasic-cn.html.markdown index e30041b3..cda7b864 100644 --- a/zh-cn/visualbasic-cn.html.markdown +++ b/zh-cn/visualbasic-cn.html.markdown @@ -8,7 +8,7 @@ lang: zh-cn filename: learnvisualbasic-cn.vb --- -``` +```visualbasic Module Module1 Sub Main() diff --git a/zh-cn/wolfram-cn.html.markdown b/zh-cn/wolfram-cn.html.markdown index 9d6ef54f..64990234 100644 --- a/zh-cn/wolfram-cn.html.markdown +++ b/zh-cn/wolfram-cn.html.markdown @@ -18,7 +18,7 @@ Wolfram 语言有几个界面。 本例中的代码可以在任何界面中输入,并使用 Wolfram Workbench 进行编辑。直接加载到 Mathematica 中可能会很不方便,因为该文件不包含单元格格式化信息(这将使该文件作为文本阅读时变得一团糟)--它可以被查看/编辑,但可能需要一些设置。 -```mma +```mathematica (* 这是一个注释 *) (* 在Mathematica中,您可以创建一个文本单元格,用排版好的文本和图像来注释您的代码,而不是使用这些注释 *) diff --git a/zh-cn/zfs-cn.html.markdown b/zh-cn/zfs-cn.html.markdown index fdf5277e..80688fbe 100644 --- a/zh-cn/zfs-cn.html.markdown +++ b/zh-cn/zfs-cn.html.markdown @@ -288,6 +288,7 @@ tank/home/sarlalian@now 0 - 259M - tank/home/alice@now 0 - 156M - tank/home/bob@now 0 - 156M - ... +``` Destroy snapshots (删除快照) @@ -297,7 +298,6 @@ $ zfs destroy tank/home/sarlalian@now # 删除某一数据集及其子集的快照 $ zfs destroy -r tank/home/sarlalian@now - ``` Renaming Snapshots (重命名) diff --git a/zh-tw/elixir-tw.html.markdown b/zh-tw/elixir-tw.html.markdown index c15f90c1..3dba95b3 100644 --- a/zh-tw/elixir-tw.html.markdown +++ b/zh-tw/elixir-tw.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -19,10 +19,10 @@ Elixir 是一門建構在 Erlang 虛擬機上的現代函數式語言。它完 # 沒有多行註解的功能 # 但你可以連續使用多個單行 -# 用 `iex` 來進入 elixir shell +# 用 `iex` 來進入 Elixir shell # 用 `elixirc` 來編譯你的模組 -# 如果你已成功安裝 elixir 的話,這兩個命令應已在你的 path 下。 +# 如果你已成功安裝 Elixir 的話,這兩個命令應已在你的 path 下。 ## --------------------------- ## -- 基本型別 @@ -50,7 +50,7 @@ elem({1, 2, 3}, 0) #=> 1 head #=> 1 tail #=> [2,3] -# 在 elixir 中,就如同 Erlang 裡一樣,`=` 代表的是模式比對,而非指派。 +# 在 Elixir 中,就如同 Erlang 裡一樣,`=` 代表的是模式比對,而非指派。 # # 這代表將使用左手邊的模式 (pattern) 去與右手邊的值進行比對。 # @@ -80,7 +80,7 @@ string. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` 在 elixir 中會回傳字母 `a` 的 ASCII 整數 +# `?a` 在 Elixir 中會回傳字母 `a` 的 ASCII 整數 ?a #=> 97 # 用 `++` 來合併串列,而合併二進位則要用 `<>` @@ -105,7 +105,7 @@ lower..upper = 1..10 # 可以對 range 進行模式比對 5 * 2 #=> 10 10 / 2 #=> 5.0 -# 在 elixir 中, `/` 運算元永遠回傳浮點數。 +# 在 Elixir 中, `/` 運算元永遠回傳浮點數。 # 若需要回傳整數的除法,用 `div` div(10, 2) #=> 5 @@ -290,7 +290,7 @@ Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 -# 由於不可變特性 (immutability),遞迴在 elixir 中扮演重要的角色。 +# 由於不可變特性 (immutability),遞迴在 Elixir 中扮演重要的角色。 defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) @@ -356,7 +356,7 @@ end ## -- 平行處理 ## --------------------------- -# Elixir 依靠 actor 模式來進行平行處理。在 elixir 中要寫出平行處理程式, +# Elixir 依靠 actor 模式來進行平行處理。在 Elixir 中要寫出平行處理程式, # 只需要三個基本要素:建立行程,發送訊息及接收訊息。 # 我們用 `spawn` 函式來建立行程,它接收一個函式當參數。 diff --git a/zig.html.markdown b/zig.html.markdown index f8c866e5..65fd1e6b 100644 --- a/zig.html.markdown +++ b/zig.html.markdown @@ -5,24 +5,19 @@ contributors: - ["Philippe Pittoli", "https://karchnu.fr/"] --- - [Zig][ziglang] aims to be a replacement for the C programming language. **WARNING**: this document expects you to understand a few basic concepts in computer science, such as pointers, stack and heap memory, etc. **WARNING**: Zig isn't considered as ready for production. Bugs are expected. -DO NOT TRY ZIG AS YOUR FIRST PROGRAMMING EXPERIENCE. -The compiler, even the language and its libraries aren't ready, yet. -You've been warned. Prior knowledge of C is recommended. - ## Quick overview: Zig compared to C - Syntax is mostly the same, with some improvements (less ambiguity). - Zig introduces namespaces. -- Try and catch mechanism, which is both convenient, efficient and optional. +- `try` and `catch` mechanism, which is both convenient, efficient and optional. - Most of the C undefined behaviors (UBs) are fixed. - Compared to C, raw pointers are safer to use and less likely to be needed. * The type system distinguishes between a pointer to a single value, or multiple values, etc. @@ -38,8 +33,7 @@ Prior knowledge of C is recommended. ## Zig language - -``` +```zig //! Top-level documentation. /// Documentation comment. @@ -47,9 +41,9 @@ Prior knowledge of C is recommended. // Simple comment. ``` - ### Hello world. -``` + +```zig // Import standard library, reachable through the "std" constant. const std = @import("std"); @@ -67,7 +61,8 @@ pub fn main() void { ``` ### Booleans, integers and float. -``` + +```zig // Booleans. // Keywords are preferred to operators for boolean operations. print("{}\n{}\n{}\n", .{ @@ -109,7 +104,8 @@ i <<| 8 == 255 // u8: won't go higher than 255 ``` ### Arrays. -``` + +```zig // An array is a well-defined structure with a length attribute (len). // 5-byte array with undefined content (stack garbage). @@ -156,8 +152,8 @@ try some_integers[i]; // Runtime error 'index out of bounds'. ``` ### Multidimensional arrays. -``` +```zig const mat4x4 = [4][4]f32{ [_]f32{ 1.0, 0.0, 0.0, 0.0 }, [_]f32{ 0.0, 1.0, 0.0, 1.0 }, @@ -177,8 +173,8 @@ for (mat4x4) |row, row_index| { ``` ### Strings. -``` +```zig // Simple string constant. const greetings = "hello"; // ... which is equivalent to: @@ -195,8 +191,8 @@ print("string: {s}\n", .{greetings}); ``` ### Slices. -``` +```zig // A slice is a pointer and a size, an array without compile-time known size. // Slices have runtime out-of-band verifications. @@ -206,8 +202,8 @@ const slice = array[0..array.len]; // "slice" represents the whole array. ``` ### Pointers. -``` +```zig // Pointer on a value can be created with "&". const x: i32 = 1; const pointer: *i32 = &x; // "pointer" is a pointer on the i32 var "x". @@ -223,7 +219,8 @@ const foo = pointer.?; // Get the pointed value, otherwise crash. ``` ### Optional values (?<type>). -``` + +```zig // An optional is a value than can be of any type or null. // Example: "optional_value" can either be "null" or an unsigned 32-bit integer. @@ -239,7 +236,8 @@ if (x) |value| { ``` ### Errors. -``` + +```zig // Zig provides an unified way to express errors. // Errors are defined in error enumerations, example: @@ -299,7 +297,7 @@ var value = try some_function(); ### Control flow. -``` +```zig // Conditional branching. if (condition) { @@ -384,8 +382,8 @@ const result = for (items) |value| { ``` ### Labels. -``` +```zig // Labels are a way to name an instruction, a location in the code. // Labels can be used to "continue" or "break" in a nested loop. outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| { @@ -434,8 +432,8 @@ const result = for (items) |value| { // First: loop. ``` ### Switch. -``` +```zig // As a switch in C, but slightly more advanced. // Syntax: // switch (value) { @@ -454,15 +452,15 @@ var x = switch(value) { // A slightly more advanced switch, accepting a range of values: const foo: i32 = 0; const bar = switch (foo) { - 0 => "zero", - 1...std.math.maxInt(i32) => "positive", - else => "negative", + 0 => "zero", + 1...std.math.maxInt(i32) => "positive", + else => "negative", }; ``` ### Structures. -``` +```zig // Structure containing a single value. const Full = struct { number: u16, @@ -564,7 +562,8 @@ print("p.y: {}\n", .{p.y}); // 30 ``` ### Tuples. -``` + +```zig // A tuple is a list of elements, possibly of different types. const foo = .{ "hello", true, 42 }; @@ -572,33 +571,33 @@ const foo = .{ "hello", true, 42 }; ``` ### Enumerations. -``` +```zig const Type = enum { ok, not_ok }; const CardinalDirections = enum { North, South, East, West }; const direction: CardinalDirections = .North; const x = switch (direction) { - // shorthand for CardinalDirections.North - .North => true, - else => false + // shorthand for CardinalDirections.North + .North => true, + else => false }; // Switch statements need exhaustiveness. // WARNING: won't compile. East and West are missing. const x = switch (direction) { - .North => true, - .South => true, + .North => true, + .South => true, }; // Switch statements need exhaustiveness. // Won't compile: East and West are missing. const x = switch (direction) { - .North => true, - .South => true, - .East, // Its value is the same as the following pattern: false. - .West => false, + .North => true, + .South => true, + .East, // Its value is the same as the following pattern: false. + .West => false, }; @@ -606,12 +605,12 @@ const x = switch (direction) { ``` ### Unions. -``` +```zig const Bar = union { - boolean: bool, - int: i16, - float: f32, + boolean: bool, + int: i16, + float: f32, }; // Both syntaxes are equivalent. @@ -622,8 +621,8 @@ const foo: Bar = .{ .int = 42 }; ``` ### Tagged unions. -``` +```zig // Unions can be declared with an enum tag type, allowing them to be used in // switch expressions. @@ -653,8 +652,8 @@ switch (nay) { ``` ### Defer and errdefer. -``` +```zig // Make sure that an action (single instruction or block of code) is executed // before the end of the scope (function, block of code). // Even on error, that action will be executed. @@ -695,24 +694,25 @@ Thus, the standard library lets developers handle memory as they need, through s **NOTE**: the choice of the allocator isn't in the scope of this document. A whole book could be written about it. However, here are some examples, to get an idea of what you can expect: -- page_allocator. +- `page_allocator`. Allocate a whole page of memory each time we ask for some memory. Very simple, very dumb, very wasteful. -- GeneralPurposeAllocator. +- `GeneralPurposeAllocator`. Get some memory first and manage some buckets of memory in order to reduce the number of allocations. A bit complex. Can be combined with other allocators. Can detect leaks and provide useful information to find them. -- FixedBufferAllocator. +- `FixedBufferAllocator`. Use a fixed buffer to get its memory, don't ask memory to the kernel. Very simple, limited and wasteful (can't deallocate), but very fast. -- ArenaAllocator. +- `ArenaAllocator`. Allow to free all allocated memory at once. To use in combinations with another allocator. Very simple way of avoiding leaks. A first example. -``` + +```zig // "!void" means the function doesn't return any value except for errors. // In this case we try to allocate memory, and this may fail. fn foo() !void { @@ -735,8 +735,8 @@ fn foo() !void { ``` ### Memory allocation combined with error management and defer. -``` +```zig fn some_memory_allocation_example() !void { // Memory allocation may fail, so we "try" to allocate the memory and // in case there is an error, the current function returns it. @@ -759,8 +759,8 @@ fn some_memory_allocation_example() !void { ``` ### Memory allocators: a taste of the standard library. -``` +```zig // Allocators: 4 main functions to know // single_value = create (type) // destroy (single_value) @@ -846,8 +846,8 @@ fn gpa_arena_allocator_fn() !void { ``` ### Comptime. -``` +```zig // Comptime is a way to avoid the pre-processor. // The idea is simple: run code at compilation. @@ -883,7 +883,8 @@ list.items[0] = 10; ``` ### Conditional compilation. -``` + +```zig const available_os = enum { OpenBSD, Linux }; const myos = available_os.OpenBSD; @@ -905,7 +906,8 @@ const myprint = switch(myos) { ``` ### Testing our functions. -``` + +```zig const std = @import("std"); const expect = std.testing.expect; @@ -936,45 +938,44 @@ There are more than a hundred built-ins, allowing very low-level stuff: - etc. Example: enums aren't integers, they have to be converted with a built-in. -``` + +```zig const Value = enum { zero, stuff, blah }; if (@enumToInt(Value.zero) == 0) { ... } if (@enumToInt(Value.stuff) == 1) { ... } if (@enumToInt(Value.blah) == 2) { ... } ``` - ### A few "not yourself in the foot" measures in the Zig language. -- Namespaces: names conflicts are easily avoided. - In practice, that means an unified API between different structures (data types). +- Namespaces: name conflicts are easily avoided. + In practice, that means a unified API between different structures (data types). - Enumerations aren't integers. Comparing an enumeration to an integer requires a conversion. - Explicit casts, coercion exists but is limited. Types are slightly more enforced than in C, just a taste: Pointers aren't integers, explicit conversion is necessary. - You won't lose precision by accident, implicit coercions are only authorized in case no precision can be lost. - Unions cannot be reinterpreted (in an union with an integer and a float, one cannot take a value for another by accident). + You won't lose precision by accident, implicit coercions are only authorized in cases where no precision can be lost. + Unions cannot be reinterpreted (in a union with an integer and a float, one cannot take a value for another by accident). Etc. - Removing most of the C undefined behaviors (UBs), and when the compiler encounters one, it stops. - Slice and Array structures are preferred to pointers. Types enforced by the compiler are less prone to errors than pointer manipulations. - Numerical overflows produce an error, unless explicitly accepted using wrapping operators. -- Try and catch mechanism. +- `try` and `catch` mechanism. It's both handy, trivially implemented (simple error enumeration), and it takes almost no space nor computation time. -- Unused variables are considered as errors by the compiler. -- Many pointer types exist in order to represent what is pointed. +- Unused variables are considered to be errors by the compiler. +- Many pointer types exist in order to represent what is pointed to. Example: is this a single value or an array, is the length known, etc. -- Structures need a value for their attributes, and it still is possible to give an undefined value (stack garbage), but at least it is explicitly undefined. +- Structures need a value for their attributes, and it is still possible to give an undefined value (stack garbage), but at least it is explicitly undefined. ## Further Reading -For a start, some concepts are presented on the [Zig learn website][ziglearn]. - -The [official website][zigdoc] provides a reference documentation to the language. +For a start, some concepts are presented on [zig.guide][zigguide]. -For now, documentation for standard library is WIP. +The [official website][zigdoc] provides the reference documentation of the language. The standard library [has its own documentation][zigstd]. [ziglang]: https://ziglang.org -[ziglearn]: https://ziglearn.org/ +[zigguide]: https://zig.guide/ [zigdoc]: https://ziglang.org/documentation/ +[zigstd]: https://ziglang.org/documentation/master/std/ |