From f98b6c99aa76d4d9fc72ee2af3246c34d40f373b Mon Sep 17 00:00:00 2001 From: waltercjunior Date: Tue, 20 Oct 2020 23:18:37 -0300 Subject: Create pythonstatcomp.html.markdown Create pythonstatcomp.html.markdown with translate to pt-br --- pt-br/pythonstatcomp.html.markdown | 248 +++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 pt-br/pythonstatcomp.html.markdown diff --git a/pt-br/pythonstatcomp.html.markdown b/pt-br/pythonstatcomp.html.markdown new file mode 100644 index 00000000..36659cb0 --- /dev/null +++ b/pt-br/pythonstatcomp.html.markdown @@ -0,0 +1,248 @@ +--- +category: tool +tool: Computação estatística com Python +contributors: + - ["e99n09", "https://github.com/e99n09"] +translators: + - ["waltercjunior", "https://github.com/waltercjunior"] +filename: pythonstatcomp-py.py +--- + +Este é um tutorial sobre como fazer algumas tarefas típicas de programação estatística usando Python. +É destinado basicamente à pessoas familizarizadas com Python e experientes com programação estatística em linguagens como R, +Stata, SAS, SPSS ou MATLAB. + +```python + + + +# 0. Preparando-se ==== + +""" Para começar, instale o seguinte : jupyther, numpy, scipy, pandas, + matplotlib, seaborn, requests. + Certifique-se de executar este tutorial utilizando o Jupyther notebook para + que você utilize os gráficos embarcados e ter uma fácil consulta à + documentação. + O comando para abrir é simplesmente '`jupyter notebook`, quando abrir então + clique em 'New -> Python'. +""" + +# 1. Aquisição de dados ==== + +""" A única razão das pessoas optarem por Python no lugar de R é que pretendem + interagir com o ambiente web, copiando páginas diretamente ou solicitando + dados utilizando uma API. Você pode fazer estas coisas em R, mas no + contexto de um projeto já usando Python, há uma vantagem em se ater uma + linguágem única. +""" + +import requests # para requisições HTTP (web scraping, APIs) +import os + +# web scraping +r = requests.get("https://github.com/adambard/learnxinyminutes-docs") +r.status_code # se retornou código 200, a requisição foi bem sucedida +r.text # código fonte bruto da página +print(r.text) # formatado bonitinho +# salve a o código fonte d apágina em um arquivo: +os.getcwd() # verifique qual é o diretório de trabalho +with open("learnxinyminutes.html", "wb") as f: + f.write(r.text.encode("UTF-8")) + +# Baixar um arquivo csv +fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/" +fn = "pets.csv" +r = requests.get(fp + fn) +print(r.text) +with open(fn, "wb") as f: + f.write(r.text.encode("UTF-8")) + +""" para mais informações sobre o módulo de solicitações, incluindo API's, veja em + http://docs.python-requests.org/en/latest/user/quickstart/ +""" + +# 2. Lendo um arquivo formato CSV ==== + +""" Um pacote de pandas da Wes McKinney lhe dá um objeto 'DataFrame' em Python. + Se você já usou R, já deve estar familiarizado com a ideia de "data.frame". +""" + +import pandas as pd +import numpy as np +import scipy as sp +pets = pd.read_csv(fn) +pets +# name age weight species +# 0 fluffy 3 14 cat +# 1 vesuvius 6 23 fish +# 2 rex 5 34 dog + +""" Usuários R: observe que o Python, como a maioria das linguagens de programação + influenciada pelo C, a indexação começa de 0. Em R, começa a indexar em 1 + devido à influência do Fortran. +""" + +# duas maneiras diferentes de imprimir uma coluna +pets.age +pets["age"] + +pets.head(2) # imprima as 2 primeiras linhas +pets.tail(1) # imprima a última linha + +pets.name[1] # 'vesuvius' +pets.species[0] # 'cat' +pets["weight"][2] # 34 + +# Em R, você esperaria obter 3 linhas fazendo isso, mas aqui você obtem 2: +pets.age[0:2] +# 0 3 +# 1 6 + +sum(pets.age) * 2 # 28 +max(pets.weight) - min(pets.weight) # 20 + +""" Se você está fazendo alguma álgebra linear séria e processamento de + números você pode desejar apenas arrays, não DataFrames. DataFrames são + ideais para combinar colunas de diferentes tipos de dados. +""" + +# 3. Gráficos ==== + +import matplotlib as mpl +import matplotlib.pyplot as plt +%matplotlib inline + +# Para fazer a visualiação de dados em Python, use matplotlib + +plt.hist(pets.age); + +plt.boxplot(pets.weight); + +plt.scatter(pets.age, pets.weight) +plt.xlabel("age") +plt.ylabel("weight"); + +# seaborn utiliza a biblioteca do matplotlib e torna os enredos mais bonitos + +import seaborn as sns + +plt.scatter(pets.age, pets.weight) +plt.xlabel("age") +plt.ylabel("weight"); + +# também existem algumas funções de plotagem específicas do seaborn +# observe como o seaborn automaticamenteo o eixto x neste gráfico de barras +sns.barplot(pets["age"]) + +# Veteranos em R ainda podem usar o ggplot +from ggplot import * +ggplot(aes(x="age",y="weight"), data=pets) + geom_point() + labs(title="pets") +# fonte: https://pypi.python.org/pypi/ggplot + +# há até um d3.js veja em: https://github.com/mikedewar/d3py + +# 4. Limpeza de dados simples e análise exploratória ==== + +""" Aqui está um exemplo mais complicado que demonstra dados básicos + fluxo de trabalho de limpeza levando à criação de algumas parcelas + e a execução de uma regressão linear. + O conjunto de dados foi transcrito da Wikipedia à mão. Contém + todos os sagrados imperadores romanos e os marcos importantes em suas vidas + (birth, death, coronation, etc.). + O objetivo da análise será explorar se um relacionamento existe + entre o ano de nascimento (birth year) e a expectativa de vida (lifespam) + do imperador. + Fonte de dados: https://en.wikipedia.org/wiki/Holy_Roman_Emperor +""" + +# carregue alguns dados dos sagrados imperadores romanos +url = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/hre.csv" +r = requests.get(url) +fp = "hre.csv" +with open(fp, "wb") as f: + f.write(r.text.encode("UTF-8")) + +hre = pd.read_csv(fp) + +hre.head() +""" + Ix Dynasty Name Birth Death +0 NaN Carolingian Charles I 2 April 742 28 January 814 +1 NaN Carolingian Louis I 778 20 June 840 +2 NaN Carolingian Lothair I 795 29 September 855 +3 NaN Carolingian Louis II 825 12 August 875 +4 NaN Carolingian Charles II 13 June 823 6 October 877 + + Coronation 1 Coronation 2 Ceased to be Emperor +0 25 December 800 NaN 28 January 814 +1 11 September 813 5 October 816 20 June 840 +2 5 April 823 NaN 29 September 855 +3 Easter 850 18 May 872 12 August 875 +4 29 December 875 NaN 6 October 877 +""" + +# limpar as colunas Birth e Death + +import re # módulo para expressões regulares + +rx = re.compile(r'\d+$') # conincidir com os códigos finais + +""" Esta função aplia a expressão reguar a uma coluna de entrada (here Birth, + Death), nivela a lista resultante, converte-a em uma lista de objetos, e + finalmente converte o tipo do objeto da lista de String para inteiro. para + mais informações sobre o que as diferentes partes do código fazer, veja em: + - https://docs.python.org/2/howto/regex.html + - http://stackoverflow.com/questions/11860476/how-to-unlist-a-python-list + - http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html +""" + +from functools import reduce + +def extractYear(v): + return(pd.Series(reduce(lambda x, y: x + y, map(rx.findall, v), [])).astype(int)) + +hre["BirthY"] = extractYear(hre.Birth) +hre["DeathY"] = extractYear(hre.Death) + +# faça uma coluna infomrnado a idade estimada ("EstAge") +hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int) + +# gráfico de dispersão simples, sem linha de tendência, cor representa dinastia +sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False) + +# use o scipy para executar uma regrassão linear +from scipy import stats +(slope, intercept, rval, pval, stderr) = stats.linregress(hre.BirthY, hre.EstAge) +# código fonte: http://wiki.scipy.org/Cookbook/LinearRegression + +# varifique o declive (slope) +slope # 0.0057672618839073328 + +# varifique o valor R^2: +rval**2 # 0.020363950027333586 + +# varifique o valor p-value +pval # 0.34971812581498452 + +# use o seaborn para fazer um gráfico de dispersão e traçar a linha de tendência de regrassão linear +sns.lmplot("BirthY", "EstAge", data=hre) + +""" Para mais informações sobre o seaborn, veja + - http://web.stanford.edu/~mwaskom/software/seaborn/ + - https://github.com/mwaskom/seaborn + Para mais informações sobre o SciPy, veja + - http://wiki.scipy.org/SciPy + - http://wiki.scipy.org/Cookbook/ + Para ver uma versão da análise dos sagrados imperadores romanos usando R, consulte + - http://github.com/e99n09/R-notes/blob/master/holy_roman_emperors_dates.R +""" + +``` + +Se você quiser saber mais, obtenha o Python para análise de dados de Wes McKinney. É um excelente recurso e usei-o como referência ao escrever este tutorial. + +Você também pode encontrar muitos tutoriais interativos de IPython sobre assuntos específicos de seus interesses, como Cam Davidson-Pilon's Programação Probabilística e Métodos Bayesianos para Hackers. + +Mais alguns módulos para pesquisar: + - análise de texto e processamento de linguagem natural: nltk, http://www.nltk.org + - análise de rede social: igraph, http://igraph.org/python/ -- cgit v1.2.3 From 27f7f03401ff747a61a912fdf73549b1788b13e1 Mon Sep 17 00:00:00 2001 From: Adnane Hmunna <32016785+Ahmunna@users.noreply.github.com> Date: Sun, 13 Dec 2020 15:29:18 +0100 Subject: Update r.html.markdown Following R best practices, it's recommened to use only double-quotes. --- r.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/r.html.markdown b/r.html.markdown index 3e855602..2aedf625 100644 --- a/r.html.markdown +++ b/r.html.markdown @@ -211,10 +211,10 @@ c(1,2,3,1,2,3) * c(1,2,1,2,1,2) # There's no difference between strings and characters in R "Horatio" # "Horatio" class("Horatio") # "character" -class('H') # "character" +class("H") # "character" # Those were both character vectors of length 1 # Here is a longer one: -c('alef', 'bet', 'gimmel', 'dalet', 'he') +c("alef", "bet", "gimmel", "dalet", "he") # => # "alef" "bet" "gimmel" "dalet" "he" length(c("Call","me","Ishmael")) # 3 @@ -250,8 +250,8 @@ c(TRUE,FALSE,TRUE) & c(FALSE,TRUE,TRUE) # FALSE FALSE TRUE # You can test if x is TRUE isTRUE(TRUE) # TRUE # Here we get a logical vector with many elements: -c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE -c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE +c("Z", "o", "r", "r", "o") == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c("Z", "o", "r", "r", "o") == "Z" # TRUE FALSE FALSE FALSE FALSE # FACTORS # The factor class is for categorical data -- cgit v1.2.3 From c1f78eaf8b2a95724b6ddeb7fdcbc274ac7982e9 Mon Sep 17 00:00:00 2001 From: azev77 Date: Wed, 24 Feb 2021 23:08:35 -0500 Subject: Update julia.html.markdown Assignment vs copy: see https://discourse.julialang.org/t/is-it-worth-introducing-copy-into-learnxiny/55965/2 --- julia.html.markdown | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/julia.html.markdown b/julia.html.markdown index 4d8eb497..336cd2b8 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -356,6 +356,20 @@ intersect(filledSet, otherSet) # => Set([4, 3, 5]) union(filledSet, otherSet) # => Set([4, 2, 3, 5, 6, 1]) setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1]) +# Assignment with `=` attaches a new label to the same value without copying +a = [1, 2, 3] +b = a +# Now `b` and `a` point to the same value, so changing one affects the other: +a[3] = 5 +b[3] # => 5 + +# The `copy()` function can create a shallow copy of an array, dictionary, +# or other container +a = [1, 2, 3] +c = copy(a) +a[3] = 5 +c[3] # => 3 + #################################################### ## 3. Control Flow #################################################### -- cgit v1.2.3 From 56c80785dfb6e26ec211c17d52315a93c7da5775 Mon Sep 17 00:00:00 2001 From: Thomas Preston Date: Wed, 4 Aug 2021 12:00:11 +0100 Subject: [openscad/en] Add OpenSCAD learnxinyminutes --- openscad.html.markdown | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 openscad.html.markdown diff --git a/openscad.html.markdown b/openscad.html.markdown new file mode 100644 index 00000000..b2f46562 --- /dev/null +++ b/openscad.html.markdown @@ -0,0 +1,120 @@ +--- +language: openscad +filename: leanopenscad.scad +contributors: + - ["Thomas Preston", "https://github.com/tompreston/"] +--- + +Draw 3D models with code using [OpenSCAD](https://openscad.org/). + +```openscad +// Single-line comments start with // + +/* +Multi-line comments look like this. +*/ + +/* 3D Primitives */ +cube(10); +cube([5, 10, 20]); +sphere(10); + +/* Transformations */ +translate([20, 0, 0]) cube(10); +rotate([0, 20, 30]) cube(10); + +translate([20, 0, 0]) rotate([0, 20, 30]) cube(10); +rotate([0, 20, 30]) translate([20, 0, 0]) cube(10); + +/* Modifiers + * * disable + * ! show only + * # highlight / debug + * % transparent / background + */ +/* For example, show only the rotated cube at the origin, before we translate it. */ +translate([20, 0, 0]) !rotate([0, 20, 30]) cube(10); + +/* Formatting + * The following models are the same. The official docs prefer the second. + */ +rotate([0, 20, 30]) translate([20, 0, 0]) cube(10); + +rotate([0, 20, 30]) + translate([20, 0, 0]) + cube(10); + +rotate([0, 20, 30]) { + translate([20, 0, 0]) { + cube(10); + } +} + +/* Loops */ +num_cubes = 5; +r = 20; +cube_len = 5; + +for (i = [0:num_cubes]) { + echo(str("Plot cube ", i)); + rotate([0, i * 360 / num_cubes, 0]) + translate([r, 0, 0]) + cube(cube_len, center=true); +} + +/* Boolean operations. + * union() - the sum of both shapes + * difference() - the first shape, minus the second shape + * intersection() - only parts of both shapes which intersect + */ +cube_l = 20; +cube_w = 10; +cube_h = 10; + +hole_pos_l = 10; +hole_pos_h = 5; +hole_r = 3; + +difference() { + cube([cube_l, cube_w, cube_h]); + translate([hole_pos_l, 0, hole_pos_h]) + rotate([-90, 0, 0]) + cylinder(cube_w, r=hole_r); +} + +/* Functions calculate values. */ +function inch2mm(i) = i * 25.4; + +cube(inch2mm(2)); + +/* Modules create objects you want to use later. */ +module house(roof="flat", paint=[1,0,0]) { + color(paint) + if (roof=="flat") { + translate([0,-1,0]) cube(); + } else if (roof=="pitched") { + rotate([90,0,0]) + linear_extrude(height=1) + polygon(points=[[0,0],[0,1],[0.5,1.5],[1,1],[1,0]]); + } + else if (roof=="domical") { + translate([0,-1,0]) { + translate([0.5,0.5,1]) + sphere(r=0.5,$fn=20); + cube(); + } + } +} + +house("pitched"); +translate([2, 0, 0]) house("domical"); + +/* Import modules and function from other files. */ +include /* Import the content of the file as if they were written in this file. */ +use /* Import modules and functions, but do not execute any commands. */ +``` + +## Further Reading +* Official docs https://openscad.org/documentation.html +* Cheat sheet https://openscad.org/cheatsheet/index.html +* Vim bindings https://github.com/sirtaj/vim-openscad -- cgit v1.2.3 From 077c01cdf358e8d832c0ac720744e061e276c815 Mon Sep 17 00:00:00 2001 From: Karchnu Date: Sat, 25 Dec 2021 23:42:15 +0100 Subject: [zig/en] Introduce the Zig programming language. --- zig.html.markdown | 980 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 980 insertions(+) create mode 100644 zig.html.markdown diff --git a/zig.html.markdown b/zig.html.markdown new file mode 100644 index 00000000..3825e0b4 --- /dev/null +++ b/zig.html.markdown @@ -0,0 +1,980 @@ +--- +language: "zig" +filename: learnzig.zig +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. +- Most of the C undefined behaviors (UBs) are fixed. +- Raw pointers are safer to use and aren't nearly as used as before. + * The type system distinguishes between a pointer to a single value, or multiple values, etc. + * Slices are preferred, which is a structure with a pointer and a runtime known size, which characterizes most uses of pointers in the first place. +- Some arbitrary language limitations are removed. For example, enumerations, structures and unions can have functions. +- Simple access to SIMD operations (basic maths on vectors). +- Zig provides both low-level features of C and the one provided through compiler extensions. + For example: packed structures. +- An extensive standard library, including data structures and algorithms. +- Cross-compilation capability is provided by default, without any dependency. + Different libc are provided to ease the process. + Cross-compilation works from, and to, any operating system and architecture. + +## Zig language + + +```zig +//! Top-level documentation. + +/// Documentation comment. + +// Simple comment. +``` + + +### Hello world. +```zig +// Import standard library, reachable through the "std" constant. +const std = @import("std"); + +// "info" now refers to the "std.log.info" function. +const info = std.log.info; + +// Usual hello world. +// syntax: [pub] fn () { } +pub fn main() void { + // Contrary to C functions, Zig functions have a fixed number of arguments. + // In C: "printf" takes any number of arguments. + // In Zig: std.log.info takes a format and a list of elements to print. + info("hello world", .{}); // .{} is an empty anonymous tuple. +} +``` + +### Booleans, integers and float. +```zig +// Booleans. +// Keywords are prefered to operators for boolean operations. +print("{}\n{}\n{}\n", .{ + true and false, + true or false, + !true, +}); + +// Integers. +const one_plus_one: i32 = 1 + 1; +print("1 + 1 = {}\n", .{one_plus_one}); // 2 + +// Floats. +const seven_div_three: f32 = 7.0 / 3.0; +print("7.0 / 3.0 = {}\n", .{seven_div_three}); // 2.33333325e+00 + +// Integers have arbitrary value lengths. +var myvar: u10 = 5; // 10-bit unsigned integer +// Useful for example to read network packets, or complex binary formats. + +// Number representation is greatly improved compared to C. +const one_billion = 1_000_000_000; // Decimal. +const binary_mask = 0b1_1111_1111; // Binary. Ex: network mask. +const permissions = 0o7_5_5; // Octal. Ex: Unix permissions. +const big_address = 0xFF80_0000_0000_0000; // Hexa. Ex: IPv6 address. + + +// Overflow operators: tell the compiler when it's okay to overflow. +var i: u8 = 0; // "i" is an unsigned 8-bit integer +i -= 1; // runtime overflow error (unsigned value always are positive) +i -%= 1; // okay (wrapping operator), i == 255 + +// Saturation operators: values will stick to their lower and upper bounds. +var i: u8 = 200; // "i" is an unsigned 8-bit integer (values: from 0 to 255) +i +| 100 == 255 // u8: won't go higher than 255 +i -| 300 == 0 // unsigned, won't go lower than 0 +i *| 2 == 255 // u8: won't go higher than 255 +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). +var array1: [5]u8 = undefined; + +// 5-byte array with defined content. +var array2 = [_]u8{ 1, 2, 3, 4, 5 }; +// [_] means the compiler knows the length at compile-time. + +// 1000-byte array with defined content (0). +var array3 = [_]u8{0} ** 1000; + +// Another 1000-byte array with defined content. +// The content is provided by the "foo" function, called at compile-time and +// allows complex initializations. +var array4 = [_]u8{foo()} ** 1000; + +// In any case, array.len gives the length of the array, +// array1.len and array2.len produce 5, array3.len and array4.len produce 1000. + + +// Modifying and accessing arrays content. + +// Array of 10 32-bit undefined integers. +var some_integers: [10]i32 = undefined; + +some_integers[0] = 30; // first element of the array is now 30 + +var x = some_integers[0]; // "x" now equals to 30, its type is infered. +var y = some_integers[1]; // Second element of the array isn't defined. + // "y" got a stack garbage value (no runtime error). + +// Array of 10 32-bit undefined integers. +var some_integers: [10]i32 = undefined; + +var z = some_integers[20]; // index > array size, compilation error. + +// At runtime, we loop over the elements of "some_integers" with an index. +// Index i = 20, then we try: +try some_integers[i]; // Runtime error 'index out of bounds'. + // "try" keyword is necessary when accessing an array with + // an index, since there is a potential runtime error. + // More on that later. +``` + +### 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 }, + [_]f32{ 0.0, 0.0, 1.0, 0.0 }, + [_]f32{ 0.0, 0.0, 0.0, 1.0 }, +}; + +// Access the 2D array then the inner array through indexes. +try expect(mat4x4[1][1] == 1.0); + +// Here we iterate with for loops. +for (mat4x4) |row, row_index| { + for (row) |cell, column_index| { + // ... + } +} +``` + +### Strings. +```zig + +// Simple string constant. +const greetings = "hello"; +// ... which is equivalent to: +const greetings: *const [5:0]u8 = "hello"; +// In words: "greetings" is a constant value, a pointer on a constant array of 5 +// elements (8-bit unsigned integers), with an extra '0' at the end. +// The extra "0" is called a "sentinel value". + +print("string: {s}\n", .{greetings}); + +// This represents rather faithfully C strings. Although, Zig strings are +// structures, no need for "strlen" to compute their size. +// greetings.len == 5 +``` + +### Slices. +```zig + +// A slice is a pointer and a size, an array without compile-time known size. +// Slices have runtime out-of-band verifications. + +const array = [_]u8{1,2,3,4,5}; // [_] = array with compile-time known size. +const slice = array[0..array.len]; // "slice" represents the whole array. + // slice[10] gives a runtime error. +``` + +### 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". +print("1 = {}, {}\n", .{x, pointer}); + +// Pointer values are accessed and modified with ".*". +if (pointer.* == 1) { + print("x value == {}\n", .{pointer.*}); +} + +// ".?" is a shortcut for "orelse unreachable". +const foo = pointer.?; // Get the pointed value, otherwise crash. +``` + +### Optional values (?). +```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. +var optional_value: ?u32 = null; // optional_value == null +optional_value = 42; // optional_value != null + +// "some_function" returns ?u32 +var x = some_function(); +if (x) |value| { + // In case "some_function" returned a value. + // Do something with 'value'. +} +``` + +### Errors. +```zig +// Zig provides an unified way to express errors. + +// Errors are defined in error enumerations, example: +const Error = error { + WatchingAnyNetflixTVShow, + BeOnTwitter, +}; + +// Normal enumerations are expressed the same way, but with "enum" keyword. +const SuccessStory = enum { + DoingSport, + ReadABook, +}; + + +// Error union (!). +// Either the value "mylife" is an an error or a normal value. +var mylife: Error!SuccessStory = Error.BeOnTwitter; +// mylife is an error. Sad. + +mylife = SuccessStory.ReadABook; +// Now mylife is an enum. + + +// Zig ships with many pre-defined errors. Example: +const value: anyerror!u32 = error.Broken; + + +// Handling errors. + +// Some error examples. +const Error = error { + UnExpected, + Authentication, +}; + +// "some_function" can either return an "Error" or an integer. +fn some_function() Error!u8 { + return Error.UnExpected; // It returns an error. +} + +// Errors can be "catch" without intermediate variable. +var value = some_function() catch |err| switch(err) { + Error.UnExpected => return err, // Returns the error. + Error.Authentication => unreachable, // Not expected. Crashes the program. + else => unreachable, +}; + +// An error can be "catch" without giving it a name. +const unwrapped = some_function() catch 1234; // "unwrapped" = 1234 + +// "try" is a very handy shortcut for "catch |err| return err". +var value = try some_function(); +// If "some_function" fails, the current function stops and returns the error. +// "value" can only have a valid value, the error already is handled with "try". +``` + +### Control flow. + +```zig +// Conditional branching. + +if (condition) { + ... +} +else { + ... +} + +// Ternary. +var value = if (condition) x else y; + +// Shortcut for "if (x) x else 0" +var value = x orelse 0; + +// If "a" is an optional, which may contain a value. +if (a) |value| { + print("value: {}\n", .{value}); +} +else { + print("'a' is null\n", .{}); +} + +// Get a pointer on the value (if it exists). +if (a) |*value| { value.* += 1; } + + +// Loops. + +// Syntax examples: +// while (condition) statement +// while (condition) : (end-of-iteration-statement) statement +// +// for (iterable) statement +// for (iterable) |capture| statement +// for (iterable) statement else statement + +// Note: loops work the same way over arrays or slices. + +// Simple "while" loop. +while (i < 10) { i += 1; } + +// While loop with a "continue expression" +// (expression executed as the last expression of the loop). +while (i < 10) : (i += 1) { ... } +// Same, with a more complex continue expression (block of code). +while (i * j < 2000) : ({ i *= 2; j *= 3; }) { ... } + +// To iterate over a portion of a slice, reslice. +for (items[0..1]) |value| { sum += value; } + +// Loop over every item of an array (or slice). +for (items) |value| { sum += value; } + +// Iterate and get pointers on values instead of copies. +for (items) |*value| { value.* += 1; } + +// Iterate with an index. +for (items) |value, i| { print("val[{}] = {}\n", .{i, value}); } + +// Iterate with pointer and index. +for (items) |*value, i| { print("val[{}] = {}\n", .{i, value}); value.* += 1; } + + +// Break and continue are supported. +for (items) |value| { + if (value == 0) { continue; } + if (value >= 10) { break; } + // ... +} + +// For loops can also be used as expressions. +// Similar to while loops, when you break from a for loop, +// the else branch is not evaluated. +var sum: i32 = 0; +// The "for" loop has to provide a value, which will be the "else" value. +const result = for (items) |value| { + if (value != null) { + sum += value.?; // "result" will be the last "sum" value. + } +} else 0; // Last 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 }) |_| { + for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { + count += 1; + continue :outer; // "continue" for the first loop. + } +} // count = 8 +outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| { + for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { + count += 1; + break :outer; // "break" for the first loop. + } +} // count = 1 + + +// Labels can also be used to return a value from a block. +var y: i32 = 5; +const x = blk: { + y += 1; + break :blk y; // Now "x" equals 6. +}; +// Relevant in cases like "for else" expression (explained in the following). + +// For loops can be used as expressions. +// When you break from a for loop, the else branch is not evaluated. +// WARNING: counter-intuitive. +// The "for" loop will run, then the "else" block will run. +// The "else" keyword has to be followed by the value to give to "result". +// See later for another form. +var sum: u8 = 0; +const result = for (items) |value| { + sum += value; +} else 8; // result = 8 + +// In this case, the "else" keyword is followed by a value, too. +// However, the syntax is different: it is labeled. +// Instead of a value, there is a label followed by a block of code, which +// allows to do stuff before returning the value (see the "break" invocation). +const result = for (items) |value| { // First: loop. + sum += value; +} else blk: { // Second: "else" block. + std.log.info("executed AFTER the loop!", .{}); + break :blk sum; // The "sum" value will replace the label "blk". +}; +``` + +### Switch. +```zig + +// As a switch in C, but slightly more advanced. +// Syntax: +// switch (value) { +// pattern => expression, +// pattern => expression, +// else => expression +// }; + +// A switch only checking for simple values. +var x = switch(value) { + Error.UnExpected => return err, + Error.Authentication => unreachable, + else => unreachable, +}; + +// 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", +}; +``` + +### Structures. +```zig + +// Structure containing a single value. +const Full = struct { + number: u16, +}; + +// Packed structure, with guaranteed in-memory layout. +const Divided = packed struct { + half1: u8, + quarter3: u4, + quarter4: u4, +}; + +// Point is a constant representing a structure containing two u32, "x" and "y". +// "x" has a default value, which wasn't possible in C. +const Point = struct { + x: u32 = 1, // default value + y: u32, +}; + +// Variable "p" is a new Point, with x = 1 (default value) and y = 2. +var p = Point{ .y = 2 }; + +// Fields are accessed as usual with the dot notation: variable.field. +print("p.x: {}\n", .{p.x}); // 1 +print("p.y: {}\n", .{p.y}); // 2 + + +// A structure can also contain public constants and functions. +const Point = struct { + pub const some_constant = 30; + + x: u32, + y: u32, + + // This function "init" creates a Point and returns it. + pub fn init() Point { + return Point{ .x = 0, .y = 0 }; + } +}; + + +// How to access a structure public constant. +// The value isn't accessed from an "instance" of the structure, but from the +// constant representing the structure definition (Point). +print("constant: {}\n", .{Point.some_constant}); + +// Having an "init" function is rather idiomatic in the standard library. +// More on that later. +var p = Point.init(); +print("p.x: {}\n", .{p.x}); // p.x = 0 +print("p.y: {}\n", .{p.y}); // p.y = 0 + + +// Structures often have functions to modify their state, similar to +// object-oriented programming. +const Point = struct { + const Self = @This(); // Refers to its own type (later called "Point"). + + x: u32, + y: u32, + + // Take a look at the signature. First argument is of type *Self: "self" is + // a pointer on the instance of the structure. + // This allows the same "dot" notation as in OOP, like "instance.set(x,y)". + // See the following example. + pub fn set(self: *Self, x: u32, y: u32) void { + self.x = x; + self.y = y; + } + + // Again, look at the signature. First argument is of type Self (not *Self), + // this isn't a pointer. In this case, "self" refers to the instance of the + // structure, but can't be modified. + pub fn getx(self: Self) u32 { + return self.x; + } + + // PS: two previous functions may be somewhat useless. + // Attributes can be changed directly, no need for accessor functions. + // It was just an example. +}; + +// Let's use the previous structure. +var p = Point{ .x = 0, .y = 0 }; // "p" variable is a Point. + +p.set(10, 30); // x and y attributes of "p" are modified via the "set" function. +print("p.x: {}\n", .{p.x}); // 10 +print("p.y: {}\n", .{p.y}); // 30 + +// In C: +// 1. We would have written something like: point_set(p, 10, 30). +// 2. Since all functions are in the same namespace, it would have been +// very cumbersome to create functions with different names for different +// structures. Many long names, painful to read. +// +// In Zig, structures provide namespaces for their own functions. +// Different structures can have the same names for their functions, +// which brings clarity. +``` + +### Tuples. +```zig +// A tuple is a list of elements, possibly of different types. + +const foo = .{ "hello", true, 42 }; +// foo.len == 3 +``` + +### 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 +}; + +// Switch statements need exhaustiveness. +// WARNING: won't compile. East and West are missing. +const x = switch (direction) { + .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, +}; + + +// Enumerations are like structures: they can have functions. +``` + +### Unions. +```zig + +const Bar = union { + boolean: bool, + int: i16, + float: f32, +}; + +// Both syntaxes are equivalent. +const foo = Bar{ .int = 42 }; +const foo: Bar = .{ .int = 42 }; + +// Unions, like enumerations and structures, can have functions. +``` + +### Tagged unions. +```zig + +// Unions can be declared with an enum tag type, allowing them to be used in +// switch expressions. + +const MaybeEnum = enum { + success, + failure, +}; + +const Maybe = union(MaybeEnum) { + success: u8, + failure: []const u8, +}; + +// First value: success! +const yay = Maybe{ .success = 42 }; +switch (yay) { + .success => |value| std.log.info("success: {}", .{value}), + .failure => |err_msg| std.log.info("failure: {}", .{err_msg}), +} + +// Second value: failure! :( +const nay = Maybe{ .failure = "I was too lazy" }; +switch (nay) { + .success => |value| std.log.info("success: {}", .{value}), + .failure => |err_msg| std.log.info("failure: {}", .{err_msg}), +} +``` + +### 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. +// Useful for memory allocations, and resource management in general. + +pub fn main() void { + // Should be executed at the end of the function. + defer print("third!\n", .{}); + + { + // Last element of its scope: will be executed right away. + defer print("first!\n", .{}); + } + + print("second!\n", .{}); +} + +fn hello_world() void { + defer print("end of function\n", .{}); // after "hello world!" + + print("hello world!\n", .{}); +} + +// errdefer executes the instruction (or block of code) only on error. +fn second_hello_world() !void { + errdefer print("2. something went wrong!\n", .{}); // if "foo" fails. + defer print("1. second hello world\n", .{}); // executed after "foo" + + try foo(); +} +// Defer statements can be seen as stacked: first one is executed last. +``` + +### Memory allocators. +Memory isn't managed directly in the standard library, instead an "allocator" is asked every time an operation on memory is required. +Thus, the standard library lets developers handle memory as they need, through structures called "allocators", handling all memory operations. + +**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. + Allocate a whole page of memory each time we ask for some memory. + Very simple, very dumb, very wasteful. +- 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. + 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. + Allow to free all allocted memory at once. + To use in combinaison 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 { + // In this example we use a page allocator. + var allocator = std.heap.page_allocator; + + // "list" is an ArrayList of 8-bit unsigned integers. + // An ArrayList is a contiguous, growable list of elements in memory. + var list = try ArrayList(u8).initAllocated(allocator); + defer list.deinit(); // Free the memory at the end of the scope. Can't leak. + // "defer" allows to express memory release right after its allocation, + // regardless of the complexity of the function (loops, conditions, etc.). + + list.add(5); // Some memory is allocated here, with the provided allocator. + + for (list.items) |item| { + std.debug.print("item: {}\n", .{item}); + } +} +``` + +### 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. + var buf = try page_allocator.alloc(u8, 10); + // Defer memory release right after the allocation. + // Will happen even if an error occurs. + defer page_allocator.free(buf); + + // Second allocation. + // In case of a failure, the first allocation is correctly released. + var buf2 = try page_allocator.alloc(u8, 10); + defer page_allocator.free(buf2); + + // In case of failure, both previous allocations are correctly deallocated. + try foo(); + try bar(); + + // ... +} +``` + +### Memory allocators: a taste of the standard library. +```zig + +// Allocators: 4 main functions to know +// single_value = create (type) +// destroy (single_value) +// slice = alloc (type, size) +// free (slice) + +// Page Allocator +fn page_allocator_fn() !void { + var slice = try std.heap.page_allocator.alloc(u8, 3); + defer std.heap.page_allocator.free(slice); + + // playing_with_a_slice(slice); +} + +// GeneralPurposeAllocator +fn general_purpose_allocator_fn() !void { + // GeneralPurposeAllocator has to be configured. + // In this case, we want to track down memory leaks. + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + + const allocator = gpa.allocator(); + + var slice = try allocator.alloc(u8, 3); + defer allocator.free(slice); + + // playing_with_a_slice(slice); +} + +// FixedBufferAllocator +fn fixed_buffer_allocator_fn() !void { + var buffer = [_]u8{0} ** 1000; // array of 1000 u8, all initialized at zero. + var fba = std.heap.FixedBufferAllocator.init(buffer[0..]); + // Side note: buffer[0..] is a way to create a slice from an array. + // Since the function takes a slice and not an array, this makes + // the type system happy. + + var allocator = fba.allocator(); + + var slice = try allocator.alloc(u8, 3); + // No need for "free", memory cannot be freed with a fixed buffer allocator. + // defer allocator.free(slice); + + // playing_with_a_slice(slice); +} + +// ArenaAllocator +fn arena_allocator_fn() !void { + // Reminder: arena doesn't allocate memory, it uses an inner allocator. + // In this case, we combine the arena allocator with the page allocator. + var arena = std.heap.arena_allocator.init(std.heap.page_allocator); + defer arena.deinit(); // end of function = all allocations are freed. + + var allocator = arena.allocator(); + + const slice = try allocator.alloc(u8, 3); + // No need for "free", memory will be freed anyway. + + // playing_with_a_slice(slice); +} + + +// Combining the general purpose and arena allocators. Both are very useful, +// and their combinaison should be in everyone's favorite cookbook. +fn gpa_arena_allocator_fn() !void { + const config = .{.safety = true}; + var gpa = std.heap.GeneralPurposeAllocator(config){}; + defer _ = gpa.deinit(); + + const gpa_allocator = gpa.allocator(); + + var arena = arena_allocator.init(gpa_allocator); + defer arena.deinit(); + + const allocator = arena.allocator(); + + var slice = try allocator.alloc(u8, 3); + defer allocator.free(slice); + + // playing_with_a_slice(slice); +} +``` + +### Comptime. +```zig + +// Comptime is a way to avoid the pre-processor. +// The idea is simple: run code at compilation. + +inline fn max(comptime T: type, a: T, b: T) T { + return if (a > b) a else b; +} + +var res = max(u64, 1, 2); +var res = max(f32, 10.50, 32.19); + + +// Comptime: creating generic structures. + +fn List(comptime T: type) type { + return struct { + items: []T, + + fn init() ... { ... } + fn deinit() ... { ... } + fn do() ... { ... } + }; +} + +const MyList = List(u8); + + +// use +var list = MyList{ + .items = ... // memory allocation +}; + +list.items[0] = 10; +``` + +### Conditional compilation. +```zig +const available_os = enum { OpenBSD, Linux }; +const myos = available_os.OpenBSD; + + +// The following switch is based on a constant value. +// This means that the only possible outcome is known at compile-time. +// Thus, there is no need to build the rest of the possibilities. +// Similar to the "#ifdef" in C, but without requiring a pre-processor. +const string = switch (myos) { + .OpenBSD => "OpenBSD is awesome!", + .Linux => "Linux rocks!", +}; + +// Also works in this case. +const myprint = switch(myos) { + .OpenBSD => std.debug.print, + .Linux => std.log.info, +} +``` + +### Testing our functions. +```zig +const std = @import("std"); +const expect = std.testing.expect; + +// Function to test. +pub fn some_function() bool { + return true; +} + +// This "test" block can be run with "zig test". +// It will test the function at compile-time. +test "returns true" { + expect(false == some_function()); +} +``` + +### Compiler built-ins. +The compiler has special functions called "built-ins", starting with an "@". +There are more than a hundred built-ins, allowing very low-level stuff: +- compile-time errors, logging, verifications +- type coercion and convertion, even in an unsafe way +- alignment management +- memory tricks (such as getting the byte offset of a field in a struct) +- calling functions at compile-time +- including C headers to transparently call C functions +- atomic operations +- embed files into the executable (@embedFile) +- frame manipulations (for async functions, for example) +- 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). +- 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). + Etc. +- Removing most of the C undefined behaviors (UBs), and when the compiler encounters one, it stops. +- Slice and Array structures are prefered 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. + 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. + 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 explicitely 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 now, documentation for standard library is WIP. + +[ziglang]: https://ziglang.org +[ziglearn]: https://ziglearn.org/ +[zigdoc]: https://ziglang.org/documentation/ -- cgit v1.2.3 From daace78911f19e452acf09919015dd49c953a006 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Sat, 8 Jan 2022 11:17:52 +0100 Subject: [zig/en] rephrasing the sentence on raw pointers. --- zig.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zig.html.markdown b/zig.html.markdown index 3825e0b4..814f4bda 100644 --- a/zig.html.markdown +++ b/zig.html.markdown @@ -24,7 +24,7 @@ Prior knowledge of C is recommended. - Zig introduces namespaces. - Try and catch mechanism, which is both convenient, efficient and optional. - Most of the C undefined behaviors (UBs) are fixed. -- Raw pointers are safer to use and aren't nearly as used as before. +- 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. * Slices are preferred, which is a structure with a pointer and a runtime known size, which characterizes most uses of pointers in the first place. - Some arbitrary language limitations are removed. For example, enumerations, structures and unions can have functions. -- cgit v1.2.3 From 442f4a679cb2ba653725ee894bcbf2eb94cae1fb Mon Sep 17 00:00:00 2001 From: taivlam <47955724+taivlam@users.noreply.github.com> Date: Sun, 16 Jan 2022 02:47:26 +0000 Subject: [nim/en] Fix typo in comment [nim/en] Fixed typo in comment by deleting extra apostrophe --- nim.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nim.html.markdown b/nim.html.markdown index 9730e579..b10bd75a 100644 --- a/nim.html.markdown +++ b/nim.html.markdown @@ -142,7 +142,7 @@ when compileBadCode: # Arrays type - RollCounter = array[DieFaces, int] # Array's are fixed length and + RollCounter = array[DieFaces, int] # Arrays are fixed length and DirNames = array[Direction, string] # indexed by any ordinal type. Truths = array[42..44, bool] var -- cgit v1.2.3 From a667cf999793aef05e509c85effcfd2453f9a66a Mon Sep 17 00:00:00 2001 From: taivlam <47955724+taivlam@users.noreply.github.com> Date: Sun, 16 Jan 2022 02:57:16 +0000 Subject: [rst/en] Make formatting in comments consistent Made formatting in comments consistent by adding 2 periods --- rst.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rst.html.markdown b/rst.html.markdown index 56d54501..c177fdb4 100644 --- a/rst.html.markdown +++ b/rst.html.markdown @@ -33,7 +33,7 @@ $ pip install docutils A simple example of the file syntax: ``` -.. Lines starting with two dots are special commands. But if no command can be found, the line is considered as a comment +.. Lines starting with two dots are special commands. But if no command can be found, the line is considered as a comment. ========================================================= Main titles are written using equals signs over and under @@ -80,12 +80,12 @@ France Paris Japan Tokyo =========== ======== -More complex tables can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this :) +More complex tables can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this. :) 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 typing a full comprehensible URL : https://github.com/ (will be automatically converted to a link) +- By typing a full comprehensible URL : https://github.com/ (will be automatically converted to a link). - By making a more Markdown-like link: `Github `_ . .. _Github: https://github.com/ -- cgit v1.2.3 From 22861c5c74292180f9f9fdadaafa7afb4455d2f6 Mon Sep 17 00:00:00 2001 From: taivlam <47955724+taivlam@users.noreply.github.com> Date: Sun, 16 Jan 2022 03:43:14 +0000 Subject: [markdown/en] Fixed minor typos & backticks * Added some periods at end of sentences for consistent style * Line 238 previously rendered as "` - even though GitHub preview correctly displayed 3 consecutive backticks, i.e.: ``` (hopefully this fix will work) * Line 281 missed the capitalization of "This" --- markdown.html.markdown | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/markdown.html.markdown b/markdown.html.markdown index 60ca1323..a6000910 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -169,9 +169,9 @@ render the numbers in order, but this may not be a good idea. 1. Item three ``` -(This renders the same as the above example) +(This renders the same as the example above.) -You can also use sublists +You can also use sublists. ```md 1. Item one @@ -203,7 +203,7 @@ a line with four spaces or a tab. ``` You can also re-tab (or add an additional four spaces) for indentation -inside your code +inside your code. ```md my_array.each do |item| @@ -211,13 +211,13 @@ inside your code end ``` -Inline code can be created using the backtick character `` ` `` +Inline code can be created using the backtick character `` ` ``. ```md John didn't even know what the `go_to()` function did! ``` -In GitHub Flavored Markdown, you can use a special syntax for code +In GitHub Flavored Markdown, you can use a special syntax for code.
 ```ruby
@@ -227,7 +227,7 @@ end
 ```
The above text doesn't require indenting, plus GitHub will use syntax -highlighting of the language you specify after the \`\`\` +highlighting of the language you specify after the opening ```. ## Horizontal rule @@ -278,7 +278,7 @@ There is also "implicit naming" which lets you use the link text as the id.
[This][] is a link.
 
-[this]: http://thisisalink.com/
+[This]: http://thisisalink.com/ But it's not that commonly used. -- cgit v1.2.3 From 09694f73dbfd89743e4d9726c8bf53f97cd017b5 Mon Sep 17 00:00:00 2001 From: Gabriel Sroka Date: Tue, 1 Feb 2022 19:38:03 -0800 Subject: Update bash.html.markdown fix minor typo --- bash.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash.html.markdown b/bash.html.markdown index 8fdfdf08..c9a805ba 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -112,7 +112,7 @@ echo ${array0[@]} # => "one two three four five six" echo ${#array0[@]} # => "6" # Print number of characters in third element echo ${#array0[2]} # => "5" -# Print 2 elements starting from forth +# Print 2 elements starting from fourth echo ${array0[@]:3:2} # => "four five" # Print all elements. Each of them on new line. for i in "${array0[@]}"; do -- cgit v1.2.3 From fd8d3b8960eff57d710909431704dda563335591 Mon Sep 17 00:00:00 2001 From: zacryol <60046681+zacryol@users.noreply.github.com> Date: Mon, 14 Feb 2022 08:51:26 -0700 Subject: [GDScript/en] Fix usage of `its` "it's" is a contraction of "it is" "its" is the possessive --- gdscript.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdscript.html.markdown b/gdscript.html.markdown index 25af0974..550a874e 100644 --- a/gdscript.html.markdown +++ b/gdscript.html.markdown @@ -95,7 +95,7 @@ func doing_math(): func control_flow(): x = 8 y = 2 # y was originally a float, - # but we can change it's type to int + # but we can change its type to int # using the power of dynamic typing! if x < y: @@ -319,4 +319,4 @@ signal example(arg: int) # ERROR! Signals can't take typed arguments! * [NodePath](https://docs.godotengine.org/en/stable/classes/class_nodepath.html) * [Signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) * [GDQuest](https://www.gdquest.com/) -* [GDScript.com](https://gdscript.com/) \ No newline at end of file +* [GDScript.com](https://gdscript.com/) -- cgit v1.2.3 From 6a600f71202e52bdc2553f56c963edcf6014414f Mon Sep 17 00:00:00 2001 From: zacryol <60046681+zacryol@users.noreply.github.com> Date: Mon, 14 Feb 2022 08:58:43 -0700 Subject: [GDScript/en] add example of iterating over an int with `for` --- gdscript.html.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gdscript.html.markdown b/gdscript.html.markdown index 25af0974..93f49ba6 100644 --- a/gdscript.html.markdown +++ b/gdscript.html.markdown @@ -114,6 +114,9 @@ func control_flow(): for i in range(20): # GDScript's range is similar to Python's print(i) # so this will print numbers from 0 to 19 + for i in 20: # unlike Python, you can loop over an int directly + print(i) # so this will also print numbers from 0 to 19 + for i in ["two", 3, 1.0]: # iterating over an array print(i) @@ -319,4 +322,4 @@ signal example(arg: int) # ERROR! Signals can't take typed arguments! * [NodePath](https://docs.godotengine.org/en/stable/classes/class_nodepath.html) * [Signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) * [GDQuest](https://www.gdquest.com/) -* [GDScript.com](https://gdscript.com/) \ No newline at end of file +* [GDScript.com](https://gdscript.com/) -- cgit v1.2.3 From 231388888838b8a00880a431bbc949f525293b88 Mon Sep 17 00:00:00 2001 From: Crystal-RainSlide <16851802+Crystal-RainSlide@users.noreply.github.com> Date: Tue, 8 Mar 2022 16:56:31 +0800 Subject: [R/en] Format R code --- r.html.markdown | 279 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 139 insertions(+), 140 deletions(-) diff --git a/r.html.markdown b/r.html.markdown index e90d5a97..66e9ba74 100644 --- a/r.html.markdown +++ b/r.html.markdown @@ -29,13 +29,13 @@ R is a statistical computing language. It has lots of libraries for uploading an # R without understanding anything about programming. Do not worry # about understanding everything the code does. Just enjoy! -data() # browse pre-loaded data sets -data(rivers) # get this one: "Lengths of Major North American Rivers" -ls() # notice that "rivers" now appears in the workspace -head(rivers) # peek at the data set +data() # browse pre-loaded data sets +data(rivers) # get this one: "Lengths of Major North American Rivers" +ls() # notice that "rivers" now appears in the workspace +head(rivers) # peek at the data set # 735 320 325 392 524 450 -length(rivers) # how many rivers were measured? +length(rivers) # how many rivers were measured? # 141 summary(rivers) # what are some summary statistics? # Min. 1st Qu. Median Mean 3rd Qu. Max. @@ -91,14 +91,15 @@ stem(log(rivers)) # Notice that the data are neither normal nor log-normal! # 82 | 2 # make a histogram: -hist(rivers, col="#333333", border="white", breaks=25) # play around with these parameters -hist(log(rivers), col="#333333", border="white", breaks=25) # you'll do more plotting later +hist(rivers, col = "#333333", border = "white", breaks = 25) +hist(log(rivers), col = "#333333", border = "white", breaks = 25) +# play around with these parameters, you'll do more plotting later # Here's another neat data set that comes pre-loaded. R has tons of these. data(discoveries) -plot(discoveries, col="#333333", lwd=3, xlab="Year", +plot(discoveries, col = "#333333", lwd = 3, xlab = "Year", main="Number of important discoveries per year") -plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", +plot(discoveries, col = "#333333", lwd = 3, type = "h", xlab = "Year", main="Number of important discoveries per year") # Rather than leaving the default ordering (by year), @@ -109,7 +110,7 @@ sort(discoveries) # [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 # [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 -stem(discoveries, scale=2) +stem(discoveries, scale = 2) # # The decimal point is at the | # @@ -134,7 +135,7 @@ summary(discoveries) # 0.0 2.0 3.0 3.1 4.0 12.0 # Roll a die a few times -round(runif(7, min=.5, max=6.5)) +round(runif(7, min = .5, max = 6.5)) # 1 4 6 1 4 6 4 # Your numbers will differ from mine unless we set the same random.seed(31337) @@ -157,69 +158,68 @@ rnorm(9) # INTEGERS # Long-storage integers are written with L -5L # 5 -class(5L) # "integer" +5L # 5 +class(5L) # "integer" # (Try ?class for more information on the class() function.) # In R, every single value, like 5L, is considered a vector of length 1 -length(5L) # 1 +length(5L) # 1 # You can have an integer vector with length > 1 too: -c(4L, 5L, 8L, 3L) # 4 5 8 3 -length(c(4L, 5L, 8L, 3L)) # 4 -class(c(4L, 5L, 8L, 3L)) # "integer" +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" # NUMERICS # A "numeric" is a double-precision floating-point number -5 # 5 -class(5) # "numeric" +5 # 5 +class(5) # "numeric" # Again, everything in R is a vector; # you can make a numeric vector with more than one element -c(3,3,3,2,2,1) # 3 3 3 2 2 1 +c(3, 3, 3, 2, 2, 1) # 3 3 3 2 2 1 # You can use scientific notation too -5e4 # 50000 -6.02e23 # Avogadro's number -1.6e-35 # Planck length +5e4 # 50000 +6.02e23 # Avogadro's number +1.6e-35 # Planck length # You can also have infinitely large or small numbers -class(Inf) # "numeric" -class(-Inf) # "numeric" +class(Inf) # "numeric" +class(-Inf) # "numeric" # You might use "Inf", for example, in integrate(dnorm, 3, Inf); # this obviates Z-score tables. # BASIC ARITHMETIC # You can do arithmetic with numbers # Doing arithmetic on a mix of integers and numerics gives you another numeric -10L + 66L # 76 # integer plus integer gives integer -53.2 - 4 # 49.2 # numeric minus numeric gives numeric -2.0 * 2L # 4 # numeric times integer gives numeric -3L / 4 # 0.75 # integer over numeric gives numeric -3 %% 2 # 1 # the remainder of two numerics is another numeric +10L + 66L # 76 # integer plus integer gives integer +53.2 - 4 # 49.2 # numeric minus numeric gives numeric +2.0 * 2L # 4 # numeric times integer gives numeric +3L / 4 # 0.75 # integer over numeric gives numeric +3 %% 2 # 1 # the remainder of two numerics is another numeric # Illegal arithmetic yields you a "not-a-number": -0 / 0 # NaN -class(NaN) # "numeric" +0 / 0 # NaN +class(NaN) # "numeric" # You can do arithmetic on two vectors with length greater than 1, # so long as the larger vector's length is an integer multiple of the smaller -c(1,2,3) + c(1,2,3) # 2 4 6 +c(1, 2, 3) + c(1, 2, 3) # 2 4 6 # Since a single number is a vector of length one, scalars are applied # elementwise to vectors -(4 * c(1,2,3) - 2) / 2 # 1 3 5 +(4 * c(1, 2, 3) - 2) / 2 # 1 3 5 # Except for scalars, use caution when performing arithmetic on vectors with # different lengths. Although it can be done, -c(1,2,3,1,2,3) * c(1,2) # 1 4 3 2 2 6 -# Matching lengths is better practice and easier to read -c(1,2,3,1,2,3) * c(1,2,1,2,1,2) +c(1, 2, 3, 1, 2, 3) * c(1, 2) # 1 4 3 2 2 6 +# Matching lengths is better practice and easier to read most times +c(1, 2, 3, 1, 2, 3) * c(1, 2, 1, 2, 1, 2) # 1 4 3 2 2 6 # CHARACTERS # There's no difference between strings and characters in R -"Horatio" # "Horatio" -class("Horatio") # "character" -class('H') # "character" +"Horatio" # "Horatio" +class("Horatio") # "character" +class('H') # "character" # Those were both character vectors of length 1 # Here is a longer one: c('alef', 'bet', 'gimmel', 'dalet', 'he') -# => -# "alef" "bet" "gimmel" "dalet" "he" +# => "alef" "bet" "gimmel" "dalet" "he" length(c("Call","me","Ishmael")) # 3 # You can do regex operations on character vectors: -substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." # R has several built-in character vectors: letters @@ -230,32 +230,33 @@ month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "D # LOGICALS # In R, a "logical" is a boolean -class(TRUE) # "logical" -class(FALSE) # "logical" + +class(TRUE) # "logical" +class(FALSE) # "logical" # Their behavior is normal -TRUE == TRUE # TRUE -TRUE == FALSE # FALSE -FALSE != FALSE # FALSE -FALSE != TRUE # TRUE +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE # Missing data (NA) is logical, too -class(NA) # "logical" +class(NA) # "logical" # Use | and & for logic operations. # OR -TRUE | FALSE # TRUE +TRUE | FALSE # TRUE # AND -TRUE & FALSE # FALSE +TRUE & FALSE # FALSE # Applying | and & to vectors returns elementwise logic operations -c(TRUE,FALSE,FALSE) | c(FALSE,TRUE,FALSE) # TRUE TRUE FALSE -c(TRUE,FALSE,TRUE) & c(FALSE,TRUE,TRUE) # FALSE FALSE TRUE +c(TRUE, FALSE, FALSE) | c(FALSE, TRUE, FALSE) # TRUE TRUE FALSE +c(TRUE, FALSE, TRUE) & c(FALSE, TRUE, TRUE) # FALSE FALSE TRUE # You can test if x is TRUE -isTRUE(TRUE) # TRUE +isTRUE(TRUE) # TRUE # Here we get a logical vector with many elements: -c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE -c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE # FACTORS # The factor class is for categorical data -# Factors can be ordered (like childrens' grade levels) or unordered (like colors) +# Factors can be ordered (like grade levels) or unordered (like colors) factor(c("blue", "blue", "green", NA, "blue")) # blue blue green blue # Levels: blue green @@ -263,31 +264,27 @@ factor(c("blue", "blue", "green", NA, "blue")) # Note that missing data does not enter the levels levels(factor(c("green", "green", "blue", NA, "blue"))) # "blue" "green" # If a factor vector has length 1, its levels will have length 1, too -length(factor("green")) # 1 +length(factor("green")) # 1 length(levels(factor("green"))) # 1 # Factors are commonly seen in data frames, a data structure we will cover later -data(infert) # "Infertility after Spontaneous and Induced Abortion" +data(infert) # "Infertility after Spontaneous and Induced Abortion" levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" # NULL # "NULL" is a weird one; use it to "blank out" a vector -class(NULL) # NULL +class(NULL) # NULL parakeet = c("beak", "feathers", "wings", "eyes") -parakeet -# => -# [1] "beak" "feathers" "wings" "eyes" +parakeet # "beak" "feathers" "wings" "eyes" parakeet <- NULL -parakeet -# => -# NULL +parakeet # NULL # TYPE COERCION # Type-coercion is when you force a value to take on a different type -as.character(c(6, 8)) # "6" "8" -as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE # If you put elements of different types into a vector, weird coercions happen: -c(TRUE, 4) # 1 4 -c("dog", TRUE, 4) # "dog" "TRUE" "4" +c(TRUE, 4) # 1 4 +c("dog", TRUE, 4) # "dog" "TRUE" "4" as.numeric("Bilbo") # => # [1] NA @@ -309,14 +306,15 @@ as.numeric("Bilbo") # VARIABLES # Lots of way to assign stuff: -x = 5 # this is possible -y <- "1" # this is preferred -TRUE -> z # this works but is weird +x = 5 # this is possible +y <- "1" # this is preferred traditionally +TRUE -> z # this works but is weird +# Refer to the Internet for the behaviors and preferences about them. # LOOPS # We've got for loops for (i in 1:4) { - print(i) + print(i) } # We've got while loops a <- 10 @@ -341,11 +339,11 @@ if (4 > 3) { # FUNCTIONS # Defined like so: jiggle <- function(x) { - x = x + rnorm(1, sd=.1) #add in a bit of (controlled) noise + x = x + rnorm(1, sd=.1) # add in a bit of (controlled) noise return(x) } # Called like any other R function: -jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043 +jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043 @@ -357,39 +355,39 @@ jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043 # Let's start from the very beginning, and with something you already know: vectors. vec <- c(8, 9, 10, 11) -vec # 8 9 10 11 +vec # 8 9 10 11 # We ask for specific elements by subsetting with square brackets # (Note that R starts counting from 1) -vec[1] # 8 -letters[18] # "r" -LETTERS[13] # "M" -month.name[9] # "September" -c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 # We can also search for the indices of specific components, -which(vec %% 2 == 0) # 1 3 +which(vec %% 2 == 0) # 1 3 # grab just the first or last few entries in the vector, -head(vec, 1) # 8 -tail(vec, 2) # 10 11 +head(vec, 1) # 8 +tail(vec, 2) # 10 11 # or figure out if a certain value is in the vector -any(vec == 10) # TRUE +any(vec == 10) # TRUE # If an index "goes over" you'll get NA: -vec[6] # NA +vec[6] # NA # You can find the length of your vector with length() -length(vec) # 4 +length(vec) # 4 # You can perform operations on entire vectors or subsets of vectors -vec * 4 # 32 36 40 44 -vec[2:3] * 5 # 45 50 -any(vec[2:3] == 8) # FALSE +vec * 4 # 32 36 40 44 +vec[2:3] * 5 # 45 50 +any(vec[2:3] == 8) # FALSE # and R has many built-in functions to summarize vectors -mean(vec) # 9.5 -var(vec) # 1.666667 -sd(vec) # 1.290994 -max(vec) # 11 -min(vec) # 8 -sum(vec) # 38 +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 # Some more nice built-ins: -5:15 # 5 6 7 8 9 10 11 12 13 14 15 -seq(from=0, to=31337, by=1337) +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from = 0, to = 31337, by = 1337) # => # [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 # [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 @@ -397,7 +395,7 @@ seq(from=0, to=31337, by=1337) # TWO-DIMENSIONAL (ALL ONE CLASS) # You can make a matrix out of entries all of the same type like so: -mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat <- matrix(nrow = 3, ncol = 2, c(1, 2, 3, 4, 5, 6)) mat # => # [,1] [,2] @@ -405,13 +403,13 @@ mat # [2,] 2 5 # [3,] 3 6 # Unlike a vector, the class of a matrix is "matrix", no matter what's in it -class(mat) # => "matrix" +class(mat) # "matrix" # Ask for the first row -mat[1,] # 1 4 +mat[1, ] # 1 4 # Perform operation on the first column -3 * mat[,1] # 3 6 9 +3 * mat[, 1] # 3 6 9 # Ask for a specific cell -mat[3,2] # 6 +mat[3, 2] # 6 # Transpose the whole matrix t(mat) @@ -437,14 +435,14 @@ mat2 # [2,] "2" "cat" # [3,] "3" "bird" # [4,] "4" "dog" -class(mat2) # matrix +class(mat2) # matrix # Again, note what happened! # Because matrices must contain entries all of the same class, # everything got converted to the character class -c(class(mat2[,1]), class(mat2[,2])) +c(class(mat2[, 1]), class(mat2[, 2])) # rbind() sticks vectors together row-wise to make a matrix -mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 <- rbind(c(1, 2, 4, 5), c(6, 7, 0, 4)) mat3 # => # [,1] [,2] [,3] [,4] @@ -458,11 +456,11 @@ mat3 # This data structure is so useful for statistical programming, # a version of it was added to Python in the package "pandas". -students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"), - c(3,2,2,1,0,-1), - c("H", "G", "G", "R", "S", "G")) +students <- data.frame(c("Cedric", "Fred", "George", "Cho", "Draco", "Ginny"), + c( 3, 2, 2, 1, 0, -1), + c( "H", "G", "G", "R", "S", "G")) names(students) <- c("name", "year", "house") # name the columns -class(students) # "data.frame" +class(students) # "data.frame" students # => # name year house @@ -472,21 +470,21 @@ students # 4 Cho 1 R # 5 Draco 0 S # 6 Ginny -1 G -class(students$year) # "numeric" -class(students[,3]) # "factor" +class(students$year) # "numeric" +class(students[,3]) # "factor" # find the dimensions -nrow(students) # 6 -ncol(students) # 3 -dim(students) # 6 3 +nrow(students) # 6 +ncol(students) # 3 +dim(students) # 6 3 # The data.frame() function converts character vectors to factor vectors # by default; turn this off by setting stringsAsFactors = FALSE when # you create the data.frame ?data.frame # There are many twisty ways to subset data frames, all subtly unalike -students$year # 3 2 2 1 0 -1 -students[,2] # 3 2 2 1 0 -1 -students[,"year"] # 3 2 2 1 0 -1 +students$year # 3 2 2 1 0 -1 +students[, 2] # 3 2 2 1 0 -1 +students[, "year"] # 3 2 2 1 0 -1 # An augmented version of the data.frame structure is the data.table # If you're working with huge or panel data, or need to merge a few data @@ -503,19 +501,19 @@ students # note the slightly different print-out # 4: Cho 1 R # 5: Draco 0 S # 6: Ginny -1 G -students[name=="Ginny"] # get rows with name == "Ginny" +students[name == "Ginny"] # get rows with name == "Ginny" # => # name year house # 1: Ginny -1 G -students[year==2] # get rows with year == 2 +students[year == 2] # get rows with year == 2 # => # name year house # 1: Fred 2 G # 2: George 2 G # data.table makes merging two data sets easy # let's make another data.table to merge with students -founders <- data.table(house=c("G","H","R","S"), - founder=c("Godric","Helga","Rowena","Salazar")) +founders <- data.table(house = c("G" , "H" , "R" , "S"), + founder = c("Godric", "Helga", "Rowena", "Salazar")) founders # => # house founder @@ -526,8 +524,8 @@ founders setkey(students, house) setkey(founders, house) students <- founders[students] # merge the two data sets by matching "house" -setnames(students, c("house","houseFounderName","studentName","year")) -students[,order(c("name","year","house","houseFounderName")), with=F] +setnames(students, c("house", "houseFounderName", "studentName", "year")) +students[, order(c("name", "year", "house", "houseFounderName")), with = F] # => # studentName year house houseFounderName # 1: Fred 2 G Godric @@ -538,7 +536,7 @@ students[,order(c("name","year","house","houseFounderName")), with=F] # 6: Draco 0 S Salazar # data.table makes summary tables easy -students[,sum(year),by=house] +students[, sum(year), by = house] # => # house V1 # 1: G 3 @@ -571,7 +569,7 @@ students[studentName != "Draco"] # 5: R Cho 1 # Using data.frame: students <- as.data.frame(students) -students[students$house != "G",] +students[students$house != "G", ] # => # house houseFounderName studentName year # 4 H Helga Cedric 3 @@ -583,13 +581,13 @@ students[students$house != "G",] # Arrays creates n-dimensional tables # All elements must be of the same type # You can make a two-dimensional table (sort of like a matrix) -array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +array(c(c(1, 2, 4, 5), c(8, 9, 3, 6)), dim = c(2, 4)) # => # [,1] [,2] [,3] [,4] # [1,] 1 4 8 3 # [2,] 2 5 9 6 # You can use array to make three-dimensional matrices too -array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +array(c(c(c(2, 300, 4), c(8, 9, 0)), c(c(5, 60, 0), c(66, 7, 847))), dim = c(3, 2, 2)) # => # , , 1 # @@ -609,7 +607,7 @@ array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) # Finally, R has lists (of vectors) list1 <- list(time = 1:40) -list1$price = c(rnorm(40,.5*list1$time,4)) # random +list1$price = c(rnorm(40, .5*list1$time, 4)) # random list1 # You can get items in the list like so list1$time # one way @@ -682,7 +680,7 @@ write.csv(pets, "pets2.csv") # to make a new .csv file ######################### # Linear regression! -linearModel <- lm(price ~ time, data = list1) +linearModel <- lm(price ~ time, data = list1) linearModel # outputs result of regression # => # Call: @@ -719,7 +717,7 @@ summary(linearModel)$coefficients # another way to extract results # Estimate Std. Error t value Pr(>|t|) # (Intercept) 0.1452662 1.50084246 0.09678975 9.234021e-01 # time 0.4943490 0.06379348 7.74920901 2.440008e-09 -summary(linearModel)$coefficients[,4] # the p-values +summary(linearModel)$coefficients[, 4] # the p-values # => # (Intercept) time # 9.234021e-01 2.440008e-09 @@ -728,8 +726,7 @@ summary(linearModel)$coefficients[,4] # the p-values # Logistic regression set.seed(1) list1$success = rbinom(length(list1$time), 1, .5) # random binary -glModel <- glm(success ~ time, data = list1, - family=binomial(link="logit")) +glModel <- glm(success ~ time, data = list1, family=binomial(link="logit")) glModel # outputs result of logistic regression # => # Call: glm(formula = success ~ time, @@ -745,8 +742,10 @@ glModel # outputs result of logistic regression summary(glModel) # more verbose output from the regression # => # Call: -# glm(formula = success ~ time, -# family = binomial(link = "logit"), data = list1) +# glm( +# formula = success ~ time, +# family = binomial(link = "logit"), +# data = list1) # Deviance Residuals: # Min 1Q Median 3Q Max @@ -780,7 +779,7 @@ plot(linearModel) # Histograms! hist(rpois(n = 10000, lambda = 5), col = "thistle") # Barplots! -barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) +barplot(c(1, 4, 5, 1, 2), names.arg = c("red", "blue", "purple", "green", "yellow")) # GGPLOT2 # But these are not even the prettiest of R's plots @@ -788,10 +787,10 @@ barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) install.packages("ggplot2") require(ggplot2) ?ggplot2 -pp <- ggplot(students, aes(x=house)) +pp <- ggplot(students, aes(x = house)) pp + geom_bar() ll <- as.data.table(list1) -pp <- ggplot(ll, aes(x=time,price)) +pp <- ggplot(ll, aes(x = time, price)) pp + geom_point() # ggplot2 has excellent documentation (available http://docs.ggplot2.org/current/) -- cgit v1.2.3 From 0f6e59d349808350e2253716f4e402c28d7e5824 Mon Sep 17 00:00:00 2001 From: dannyloxavier Date: Mon, 28 Mar 2022 12:25:28 -0300 Subject: Some fixes - Updated to latest EN version (with respective translation) - Fixed some pt-BR typos - Fixed indentations to be equal to the original EN version --- pt-br/yaml-pt.html.markdown | 150 ++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 53 deletions(-) diff --git a/pt-br/yaml-pt.html.markdown b/pt-br/yaml-pt.html.markdown index 21e9b4bb..6e8fddb3 100644 --- a/pt-br/yaml-pt.html.markdown +++ b/pt-br/yaml-pt.html.markdown @@ -2,6 +2,7 @@ language: yaml contributors: - ["Leigh Brenecki", "https://github.com/adambrenecki"] + - [Suhas SG, 'https://github.com/jargnar'] translators: - ["Rodrigo Russo", "https://github.com/rodrigozrusso"] filename: learnyaml-pt.yaml @@ -14,6 +15,8 @@ legível por seres humanos. É um superconjunto de JSON, com a adição de identação e quebras de linhas sintaticamente significativas, como Python. Ao contrário de Python, entretanto, YAML não permite o caracter literal tab para identação. ```yaml +--- # início do documento + # Comentários em YAML são como este. ################### @@ -30,28 +33,32 @@ boleano: true valor_nulo: null chave com espaco: valor # Observe que strings não precisam de aspas. Porém, elas podem ter. -porem: "Uma string, entre aspas." -"Chaves podem estar entre aspas tambem.": "É útil se você quiser colocar um ':' na sua chave." +porem: 'Uma string, entre aspas.' +'Chaves podem estar entre aspas tambem.': "É útil se você quiser colocar um ':' na sua chave." +aspas simples: 'possuem ''um'' padrão de escape' +aspas duplas: "possuem vários: \", \0, \t, \u263A, \x0d\x0a == \r\n, e mais." +# Caracteres UTF-8/16/32 precisam ser codificados +Superscript dois: \u00B2 # Seqüências de várias linhas podem ser escritas como um 'bloco literal' (utilizando |), # ou em um 'bloco compacto' (utilizando '>'). bloco_literal: | - Todo esse bloco de texto será o valor da chave 'bloco_literal', - preservando a quebra de com linhas. + Todo esse bloco de texto será o valor da chave 'bloco_literal', + preservando a quebra de com linhas. - O literal continua até de-dented, e a primeira identação é - removida. + O literal continua até 'des-indentar', e a primeira identação é + removida. - Quaisquer linhas que são 'mais identadas' mantém o resto de suas identações - - estas linhas serão identadas com 4 espaços. + Quaisquer linhas que são 'mais identadas' mantém o resto de suas identações - + estas linhas serão identadas com 4 espaços. estilo_compacto: > - Todo esse bloco de texto será o valor de 'estilo_compacto', mas esta - vez, todas as novas linhas serão substituídas com espaço simples. + Todo esse bloco de texto será o valor de 'estilo_compacto', mas esta + vez, todas as novas linhas serão substituídas com espaço simples. - Linhas em branco, como acima, são convertidas em um carater de nova linha. + Linhas em branco, como acima, são convertidas em um carater de nova linha. - Linhas 'mais-indentadas' mantém suas novas linhas também - - este texto irá aparecer em duas linhas. + Linhas 'mais-indentadas' mantém suas novas linhas também - + este texto irá aparecer em duas linhas. #################### # TIPOS DE COLEÇÃO # @@ -59,54 +66,84 @@ estilo_compacto: > # Texto aninhado é conseguido através de identação. um_mapa_aninhado: - chave: valor - outra_chave: Outro valor - outro_mapa_aninhado: - ola: ola + chave: valor + outra_chave: Outro valor + outro_mapa_aninhado: + ola: ola # Mapas não tem que ter chaves com string. 0.25: uma chave com valor flutuante # As chaves podem ser também objetos multi linhas, utilizando ? para indicar o começo de uma chave. ? | - Esta é uma chave - que tem várias linhas + Esta é uma chave + que tem várias linhas : e este é o seu valor -# também permite tipos de coleção de chaves, mas muitas linguagens de programação -# vão reclamar. +# YAML também permite o mapeamento entre sequências com a sintaxe chave complexa +# Alguns analisadores de linguagem de programação podem reclamar +# Um exemplo +? - Manchester United + - Real Madrid +: [2001-01-01, 2002-02-02] # Sequências (equivalente a listas ou arrays) semelhante a isso: uma_sequencia: - - Item 1 - - Item 2 - - 0.5 # sequencias podem conter tipos diferentes. - - Item 4 - - chave: valor - outra_chave: outro_valor - - - - Esta é uma sequencia - - dentro de outra sequencia + - Item 1 + - Item 2 + - 0.5 # sequencias podem conter tipos diferentes. + - Item 4 + - chave: valor + outra_chave: outro_valor + - + - Esta é uma sequencia + - dentro de outra sequencia + - - - Indicadores de sequência aninhadas + - podem ser recolhidas # Como YAML é um super conjunto de JSON, você também pode escrever mapas JSON de estilo e -# sequencias: +# sequências: mapa_json: {"chave": "valor"} json_seq: [3, 2, 1, "decolar"] +e aspas são opcionais: {chave: [3, 2, 1, decolar]} -########################## -# RECURSOS EXTRA DO YAML # -########################## +########################### +# RECURSOS EXTRAS DO YAML # +########################### # YAML também tem um recurso útil chamado "âncoras", que permitem que você facilmente duplique # conteúdo em seu documento. Ambas estas chaves terão o mesmo valor: -conteudo_ancora: & nome_ancora Essa string irá aparecer como o valor de duas chaves. -outra_ancora: * nome_ancora +conteudo_ancora: &nome_ancora Essa string irá aparecer como o valor de duas chaves. +outra_ancora: *nome_ancora + +# Âncoras podem ser usadas para dubplicar/herdar propriedades +base: &base + name: Todos possuem o mesmo nome + +# O regexp << é chamado Mesclar o Tipo Chave Independente-de-Idioma. É usado para +# indicar que todas as chaves de um ou mais mapas específicos devam ser inseridos +# no mapa atual. + +foo: + <<: *base + age: 10 + +bar: + <<: *base + age: 20 + +# foo and bar would also have name: Everyone has same name # YAML também tem tags, que você pode usar para declarar explicitamente os tipos. -string_explicita: !! str 0,5 +string_explicita: !!str 0.5 # Alguns analisadores implementam tags específicas de linguagem, como este para Python de # Tipo de número complexo. -numero_complexo_em_python: !! python / complex 1 + 2j +numero_complexo_em_python: !!python/complex 1+2j + +# Podemos utilizar chaves YAML complexas com tags específicas de linguagem +? !!python/tuple [5, 7] +: Fifty Seven +# Seria {(5, 7): 'Fifty Seven'} em Python #################### # YAML TIPOS EXTRA # @@ -114,27 +151,34 @@ numero_complexo_em_python: !! python / complex 1 + 2j # Strings e números não são os únicos que escalares YAML pode entender. # Data e 'data e hora' literais no formato ISO também são analisados. -datetime: 2001-12-15T02: 59: 43.1Z -datetime_com_espacos 2001/12/14: 21: 59: 43.10 -5 -Data: 2002/12/14 +datetime: 2001-12-15T02:59:43.1Z +datetime_com_espaços: 2001-12-14 21:59:43.10 -5 +date: 2002-12-14 # A tag !!binary indica que a string é na verdade um base64-encoded (codificado) # representação de um blob binário. gif_file: !!binary | - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= # YAML também tem um tipo de conjunto, o que se parece com isso: -set: - ? item1 - ? item2 - ? item3 +conjunto: + ? item1 + ? item2 + ? item3 +ou: {item1, item2, item3} # Como Python, são apenas conjuntos de mapas com valors nulos; o acima é equivalente a: -set2: - item1: nulo - item2: nulo - item3: nulo +conjunto2: + item1: null + item2: null + item3: null + +... # fim do documento ``` +### Mais Recursos + ++ [Site Oficial do YAML](https://yaml.org/) ++ [Validador YAML Online](http://www.yamllint.com/) -- cgit v1.2.3 From 19feebccf78803819082940de94d1881b117d105 Mon Sep 17 00:00:00 2001 From: dannyloxavier Date: Mon, 28 Mar 2022 14:18:45 -0300 Subject: foo bar translation Forgot to traslate this part --- pt-br/yaml-pt.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pt-br/yaml-pt.html.markdown b/pt-br/yaml-pt.html.markdown index 6e8fddb3..732a36ad 100644 --- a/pt-br/yaml-pt.html.markdown +++ b/pt-br/yaml-pt.html.markdown @@ -126,13 +126,13 @@ base: &base foo: <<: *base - age: 10 + idade: 10 bar: <<: *base - age: 20 + idade: 20 -# foo and bar would also have name: Everyone has same name +# foo e bar terão o mesmo nome: Todos possuem o mesmo nome # YAML também tem tags, que você pode usar para declarar explicitamente os tipos. string_explicita: !!str 0.5 -- cgit v1.2.3 From e06ea4b82f2b8177ca9fcbad0a9518b636cd86a5 Mon Sep 17 00:00:00 2001 From: Jovino Guerrero Toledo Date: Sun, 3 Apr 2022 01:31:40 -0300 Subject: [sql/pt-br] adding sql for pt-br language --- pt-br/sql-pt.html.markdown | 114 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 pt-br/sql-pt.html.markdown diff --git a/pt-br/sql-pt.html.markdown b/pt-br/sql-pt.html.markdown new file mode 100644 index 00000000..accdac4d --- /dev/null +++ b/pt-br/sql-pt.html.markdown @@ -0,0 +1,114 @@ +--- +language: SQL +filename: learnsql-pt.sql +contributors: + - ["Bob DuCharme", "http://bobdc.com/"] +translators: + - ["jovinoguerrero", "https://github.com/jovinoguerrero"] +lang: pt-br +--- + +A linguagem de consulta estruturada (SQL em inglês) é uma linguagem padrão ISO para criar e trabalhar com bancos de dados armazenados num conjunto de tabelas. As implementações geralmente adicionam suas próprias extensões à linguagem; [Comparação entre diferentes implementações de SQL](http://troels.arvin.dk/db/rdbms/) é uma boa referência sobre as diferenças entre os diferentes produtos. + +As implementações normalmente fornecem uma linha de comando onde se pode digitar os comandos mostrados aqui de forma interativa, e também oferecem uma maneira de executar uma série desses comandos armazenados em um arquivo de script (mostrar que é feito com o prompt interativo é um bom exemplo de algo que não é padronizado - a maioria das implementações SQL suporta as palavras-chave QUIT, EXIT ou ambas). + +Vários desses comandos de exemplo assumem que o [banco de dados de funcionários de exemplo MySQL](https://dev.mysql.com/doc/employee/en/) disponível em [github](https://github.com/datacharmer/test_db) já foi carregado. Os arquivos do GitHub são scripts de comandos, semelhantes aos comandos abaixo, que criam e carregam tabelas de dados sobre os funcionários de uma empresa fictícia. A sintaxe para executar esses scripts dependerá da implementação SQL que você está usando. Um aplicativo executado a partir do prompt do sistema operacional geralmente é o normal. + + +```sql +-- Os comentários começam com dois hífens. Cada comando é encerrado com um +-- ponto e vírgula. + +-- SQL não diferencia maiúsculas de minúsculas em palavras-chave. Os +-- comandos de exemplo mostrados aqui seguem a convenção de serem escritos +-- em maiúsculas porque torna mais fácil distingui-los dos nomes dos bancos +-- de dados, tabelas e colunas. + +-- Em seguida, um banco de dados é criado e excluído. Os nomes do banco de +-- dados e da tabela são sensíveis a maiúsculas de minúsculas. +CREATE DATABASE someDatabase; +DROP DATABASE someDatabase; + +-- Mostra numa lista todos os bancos de dados disponíveis. +SHOW DATABASES; + +-- Usa um determinado banco de dados existente. +USE employees; + +-- Seleciona todas as filas e colunas da tabela de departamentos no banco +-- de dados atual. A atividade padrão é o intérprete rolar os resultados +-- na tela. +SELECT * FROM departments; + +-- Recupera todas as filas da tabela de departamentos, mas apenas as colunas +-- dept_no e dept_name. +-- A separação de comandos em várias linhas é permitida. +SELECT dept_no, + dept_name FROM departments; + +-- Obtém todas as colunas de departments, mas é limitado a 5 filas. +SELECT * FROM departments LIMIT 5; + +-- Obtém os valores da coluna dept_name da tabela de departments quando +-- dept_name tem como valor a substring 'en'. +SELECT dept_name FROM departments WHERE dept_name LIKE '%en%'; + +-- Recupera todas as colunas da tabela de departments onde a coluna +-- dept_name começa com um 'S' e tem exatamente 4 caracteres depois dele. +SELECT * FROM departments WHERE dept_name LIKE 'S____'; + +-- Seleciona os valores dos títulos da tabela de titles, mas não mostra +-- duplicatas. +SELECT DISTINCT title FROM titles; + +-- Igual ao anterior, mas ordenado por valores de da coluna title (diferencia +-- maiúsculas de minúsculas). +SELECT DISTINCT title FROM titles ORDER BY title; + +-- Mostra o número de filas da tabela departments. +SELECT COUNT(*) FROM departments; + +-- Mostra o número de filas da tabela departments que contém 'en' como +-- substring na coluna dept_name. +SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%'; + +-- Uma união (JOIN) de informações de várias tabelas: a tabela titles mostra +-- quem tem quais cargos laborais, de acordo com seu número de funcionários, +-- e desde que data até que data. Esta informação é obtida, mas em vez do +-- número do funcionário é usada como referência cruzada a tabela employee +-- para obter o nome e sobrenome de cada funcionário (e limita os resultados +-- a 10 filas). +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; + +-- São listadas todas as tabelas de todas os bancos de dados. As implementações +-- normalmente fornecem seus próprios comandos para fazer isso com o banco de +-- dados atualmente em uso. +SELECT * FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE='BASE TABLE'; + +-- Cria uma tabela chamada tablename1, com as duas colunas mostradas, a partir +-- do banco de dados em uso. Há muitas outras opções dísponiveis para a forma +-- em que se especificam as colunas, por ex. seus tipos de dados. +CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20)); + +-- Insere uma fila de dados na tabela tablename1. É assumido que a tabela foi +-- definida para aceitar esses valores como adequados. +INSERT INTO tablename1 VALUES('Richard','Mutt'); + +-- Em tablename1, se altera o valor de fname para 'John' em todas as filas que +-- contenham um valor em lname igual a 'Mutt'. +UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; + +-- Se excluem as filas da tabela tablename1 em que o valor de lname começa +-- com 'M'. +DELETE FROM tablename1 WHERE lname like 'M%'; + +-- Se excluem as filas da tabela tablename1, deixando a tabla vazia. +DELETE FROM tablename1; + +-- A tabela tablename1, é excluída completamente. +DROP TABLE tablename1; +``` -- cgit v1.2.3 From 54ce5e4774d90d9b6d8028a04b737d842967667d Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Mon, 4 Apr 2022 02:02:42 +0200 Subject: [r/pt-br] Translate R Markdown Translation of the markdown file of R to Brazilian Portuguese and update of the header with some information regarding the translator. --- pt-br/r-pt.html.markdown | 786 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 786 insertions(+) create mode 100644 pt-br/r-pt.html.markdown diff --git a/pt-br/r-pt.html.markdown b/pt-br/r-pt.html.markdown new file mode 100644 index 00000000..2bbafe17 --- /dev/null +++ b/pt-br/r-pt.html.markdown @@ -0,0 +1,786 @@ +--- +language: R +contributors: + - ["e99n09", "http://github.com/e99n09"] + - ["isomorphismes", "http://twitter.com/isomorphisms"] + - ["kalinn", "http://github.com/kalinn"] +translators: + - ["Marcel Ribeiro-Dantas", "http://github.com/mribeirodantas"] +lang: pt-br +filename: learnr.r +--- + +R é uma linguagem de programação estatística. Ela tem muitas bibliotecas para carregar e limpar conjuntos de dados, executar análises estatísticos e produzir gráficos. Você também pode executar comandos do `R` dentro de um documento LaTeX. + +```r + +# Comentários começam com o símbolo de Cerquilha, também conhecido como +# jogo da velha + +# Não existe um símbolo especial para comentários em várias linhas +# mas você pode escrever várias linhas de comentários adicionando a +# cerquilha (#) ao início de cada uma delas. + +# No Windows e Linux, você pode usar CTRL-ENTER para executar uma linha. +# No MacOS o equivalente é COMMAND-ENTER + + + +############################################################################# +# Coisas que você pode fazer sem entender nada sobre programação +############################################################################# + +# Nesta seção, mostramos algumas das coisas legais que você pode fazer em +# R sem entender nada de programação. Não se preocupe em entender tudo o +# que o código faz. Apenas aproveite! + +data() # navegue pelos conjuntos de dados pré-carregados +data(rivers) # carregue este: "Comprimentos dos principais rios norte-americanos" +ls() # observe que "rivers" apareceu na área de trabalho (workspace) +head(rivers) # dê uma espiada no conjunto de dados +# 735 320 325 392 524 450 + +length(rivers) # quantos rios foram medidos? +# 141 +summary(rivers) # consulte um sumário de estatísticas básicas +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 135.0 310.0 425.0 591.2 680.0 3710.0 + +# faça um diagrama de ramos e folhas (uma visualização de dados semelhante a um histograma) +stem(rivers) + +# A vírgula está 2 dígito(s) à direita do símbolo | +# +# 0 | 4 +# 2 | 011223334555566667778888899900001111223333344455555666688888999 +# 4 | 111222333445566779001233344567 +# 6 | 000112233578012234468 +# 8 | 045790018 +# 10 | 04507 +# 12 | 1471 +# 14 | 56 +# 16 | 7 +# 18 | 9 +# 20 | +# 22 | 25 +# 24 | 3 +# 26 | +# 28 | +# 30 | +# 32 | +# 34 | +# 36 | 1 + +stem(log(rivers)) # Observe que os dados não são normais nem log-normais! +# Tome isso, fundamentalistas da curva normal! + +# O ponto decimal está 1 dígito(s) à esquerda do símbolo | +# +# 48 | 1 +# 50 | +# 52 | 15578 +# 54 | 44571222466689 +# 56 | 023334677000124455789 +# 58 | 00122366666999933445777 +# 60 | 122445567800133459 +# 62 | 112666799035 +# 64 | 00011334581257889 +# 66 | 003683579 +# 68 | 0019156 +# 70 | 079357 +# 72 | 89 +# 74 | 84 +# 76 | 56 +# 78 | 4 +# 80 | +# 82 | 2 + +# faça um histograma: +hist(rivers, col="#333333", border="white", breaks=25) # brinque com estes parâmetros +hist(log(rivers), col="#333333", border="white", breaks=25) # você fará mais gráficos mais tarde + +# Aqui está outro conjunto de dados que vem pré-carregado. O R tem toneladas deles. +data(discoveries) +plot(discoveries, col="#333333", lwd=3, xlab="Ano", + main="Número de descobertas importantes por ano") +plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Ano", + main="Número de descobertas importantes por ano") + +# Em vez de deixar a ordenação padrão (por ano), +# também podemos ordenar para ver o que é mais comum: +sort(discoveries) +# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 +# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 +# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 +# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 + +stem(discoveries, scale=2) +# +# O ponto decimal está no símbolo | +# +# 0 | 000000000 +# 1 | 000000000000 +# 2 | 00000000000000000000000000 +# 3 | 00000000000000000000 +# 4 | 000000000000 +# 5 | 0000000 +# 6 | 000000 +# 7 | 0000 +# 8 | 0 +# 9 | 0 +# 10 | 0 +# 11 | +# 12 | 0 + +max(discoveries) +# 12 +summary(discoveries) +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 0.0 2.0 3.0 3.1 4.0 12.0 + +# Role um dado algumas vezes +round(runif(7, min=.5, max=6.5)) +# 1 4 6 1 4 6 4 +# Seus números serão diferentes dos meus, a menos que definamos a mesma semente aleatória com o set.seed + +# Obtenha 9 números de forma aleatória a partir de uma distribuição normal +rnorm(9) +# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271 +# [7] -0.59975593 0.57629164 1.08455362 + + + +################################################## +# Tipos de dados e aritmética básica +################################################## + +# Agora para a parte orientada a programação do tutorial. +# Nesta seção você conhecerá os tipos de dados importantes do R: +# integers, numerics, characters, logicals, e factors. +# Existem outros, mas estes são o mínimo que você precisa para +# iniciar. + +# INTEGERS +# Os inteiros de armazenamento longo são escritos com L +5L # 5 +class(5L) # "integer" +# (Experimente ?class para obter mais informações sobre a função class().) +# Em R, todo e qualquer valor, como 5L, é considerado um vetor de comprimento 1 +length(5L) # 1 +# Você pode ter um vetor inteiro com comprimento > 1 também: +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" + +# NUMERICS +# Um "numeric" é um número de ponto flutuante de precisão dupla +5 # 5 +class(5) # "numeric" +# De novo, tudo em R é um vetor; +# você pode fazer um vetor numérico com mais de um elemento +c(3,3,3,2,2,1) # 3 3 3 2 2 1 +# Você também pode usar a notação científica +5e4 # 50000 +6.02e23 # Número de Avogadro +1.6e-35 # Comprimento de Planck +# Você também pode ter números infinitamente grandes ou pequenos +class(Inf) # "numeric" +class(-Inf) # "numeric" +# Você pode usar "Inf", por exemplo, em integrate(dnorm, 3, Inf) +# isso evita as tabelas de escores-Z. + +# ARITMÉTICA BÁSICA +# Você pode fazer aritmética com números +# Fazer aritmética com uma mistura de números inteiros (integers) e com +# ponto flutuante (numeric) resulta em um numeric +10L + 66L # 76 # integer mais integer resulta em integer +53.2 - 4 # 49.2 # numeric menos numeric resulta em numeric +2.0 * 2L # 4 # numeric vezes integer resulta em numeric +3L / 4 # 0.75 # integer dividido por numeric resulta em numeric +3 %% 2 # 1 # o resto de dois numeric é um outro numeric +# Aritmética ilegal produz um "não-é-um-número" (do inglês Not-a-Number): +0 / 0 # NaN +class(NaN) # "numeric" +# Você pode fazer aritmética em dois vetores com comprimento maior que 1, +# desde que o comprimento do vetor maior seja um múltiplo inteiro do menor +c(1,2,3) + c(1,2,3) # 2 4 6 +# Como um único número é um vetor de comprimento um, escalares são aplicados +# elemento a elemento com relação a vetores +(4 * c(1,2,3) - 2) / 2 # 1 3 5 +# Exceto para escalares, tenha cuidado ao realizar aritmética em vetores com +# comprimentos diferentes. Embora possa ser feito, +c(1,2,3,1,2,3) * c(1,2) # 1 4 3 2 2 6 +# ter comprimentos iguais é uma prática melhor e mais fácil de ler +c(1,2,3,1,2,3) * c(1,2,1,2,1,2) + +# CHARACTERS +# Não há diferença entre strings e caracteres em R +"Horatio" # "Horatio" +class("Horatio") # "character" +class('H') # "character" +# São ambos vetores de caracteres de comprimento 1 +# Aqui está um mais longo: +c('alef', 'bet', 'gimmel', 'dalet', 'he') +# "alef" "bet" "gimmel" "dalet" "he" +length(c("Call","me","Ishmael")) # 3 +# Você pode utilizar expressões regulares (regex) em vetores de caracteres: +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." +# R tem vários vetores de caracteres embutidos: +letters +# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" +# [20] "t" "u" "v" "w" "x" "y" "z" +month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" + +# LOGICALS +# Em R, um "logical" é um booleano +class(TRUE) # "logical" +class(FALSE) # "logical" +# O comportamento deles é normal +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE +# Dados ausentes (NA) são logical, também +class(NA) # "logical" +# Use | e & para operações lógicas. +# OR +TRUE | FALSE # TRUE +# AND +TRUE & FALSE # FALSE +# Aplicar | e & a vetores retorna operações lógicas elemento a elemento +c(TRUE,FALSE,FALSE) | c(FALSE,TRUE,FALSE) # TRUE TRUE FALSE +c(TRUE,FALSE,TRUE) & c(FALSE,TRUE,TRUE) # FALSE FALSE TRUE +# Você pode testar se x é TRUE +isTRUE(TRUE) # TRUE +# Aqui obtemos um vetor logical com muitos elementos: +c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE + +# FACTORS +# A classe factor é para dados categóricos +# Os fatores podem ser ordenados (como as avaliações de crianças) ou +# não ordenados (como as cores) +factor(c("azul", "azul", "verde", NA, "azul")) +# azul azul verde azul +# Levels: azul verde +# Os "levels" são os valores que os dados categóricos podem assumir +# Observe que os dados ausentes não entram nos levels +levels(factor(c("verde", "verde", "azul", NA, "azul"))) # "azul" "verde" +# Se um vetor de factor tem comprimento 1, seus levels também terão comprimento 1 +length(factor("green")) # 1 +length(levels(factor("green"))) # 1 +# Os fatores são comumente vistos em data frames, uma estrutura de dados que abordaremos +# mais tarde +data(infert) # "Infertilidade após aborto espontâneo e induzido" +levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" + +# NULL +# "NULL" é um valor estranho; use-o para "apagar" um vetor +class(NULL) # NULL +parakeet = c("bico", "penas", "asas", "olhos") +parakeet +# [1] "bico" "penas" "asas" "olhos" +parakeet <- NULL +parakeet +# NULL + +# COERÇÃO DE TIPO +# Coerção de tipo é quando você força um valor a assumir um tipo diferente +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +# Se você colocar elementos de diferentes tipos em um vetor, coerções estranhas acontecem: +c(TRUE, 4) # 1 4 +c("cachorro", TRUE, 4) # "cachorro" "TRUE" "4" +as.numeric("Bilbo") +# [1] NA +# Warning message: +# NAs introduced by coercion + +# Observe também: esses são apenas os tipos de dados básicos +# Existem muitos outros tipos de dados, como datas, séries temporais, etc. + + + +################################################## +# Variáveis, laços, expressões condicionais +################################################## + +# Uma variável é como uma caixa na qual você armazena um valor para uso posterior. +# Chamamos isso de "atribuir" o valor à variável. +# Ter variáveis nos permite escrever laços, funções e instruções com condição + +# VARIÁVEIS +# Existem muitas maneiras de atribuir valores: +x = 5 # é possível fazer assim +y <- "1" # mas é preferível fazer assim +TRUE -> z # isso funciona, mas é estranho + +# LAÇOS +# Nós temos laços com for +for (i in 1:4) { + print(i) +} +# [1] 1 +# [1] 2 +# [1] 3 +# [1] 4 +# Nós temos laços com while +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} +# 10...9...8...7...6...5... +# Tenha em mente que os laços for e while são executados lentamente em R +# Operações em vetores inteiros (por exemplo, uma linha inteira, uma coluna inteira) +# ou funções do tipo apply() (discutiremos mais tarde) são mais indicadas + +# IF/ELSE +# Novamente, bastante padrão +if (4 > 3) { + print("4 é maior que 3") +} else { + print("4 não é maior que 3") +} +# [1] "4 é maior que 3" + +# FUNÇÕES +# Definidas assim: +jiggle <- function(x) { + x = x + rnorm(1, sd=.1) # adicione um pouco de ruído (controlado) + return(x) +} +# Chamada como qualquer outra função R: +jiggle(5) # 5±ε. Após set.seed(2716057), jiggle(5)==5.005043 + + + +########################################################################### +# Estruturas de dados: Vetores, matrizes, data frames, and arranjos +########################################################################### + +# UNIDIMENSIONAL + +# Vamos começar do início, e com algo que você já sabe: vetores. +vec <- c(8, 9, 10, 11) +vec # 8 9 10 11 +# Consultamos elementos específicos utilizando colchetes +# (Observe que R começa a contar a partir de 1) +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +# Também podemos pesquisar os índices de componentes específicos, +which(vec %% 2 == 0) # 1 3 +# pegue apenas as primeiras ou últimas entradas no vetor, +head(vec, 1) # 8 +tail(vec, 2) # 10 11 +# ou descubra se um determinado valor está no vetor +any(vec == 10) # TRUE +# Se um índice for além do comprimento de um vetor, você obterá NA: +vec[6] # NA +# Você pode encontrar o comprimento do seu vetor com length() +length(vec) # 4 +# Você pode realizar operações em vetores inteiros ou subconjuntos de vetores +vec * 4 # 32 36 40 44 +vec[2:3] * 5 # 45 50 +any(vec[2:3] == 8) # FALSE +# e R tem muitas funções internas para sumarizar vetores +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 +# Mais alguns recursos embutidos: +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from=0, to=31337, by=1337) +# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 +# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 + +# BIDIMENSIONAL (ELEMENTOS DA MESMA CLASSE) + +# Você pode fazer uma matriz com entradas do mesmo tipo assim: +mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Ao contrário de um vetor, a classe de uma matriz é "matrix" independente do que ela contém +class(mat) # "matrix" +# Consulte a primeira linha +mat[1,] # 1 4 +# Execute uma operação na primeira coluna +3 * mat[,1] # 3 6 9 +# Consulte uma célula específica +mat[3,2] # 6 + +# Transponha toda a matriz +t(mat) +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# Multiplicação de matrizes +mat %*% t(mat) +# [,1] [,2] [,3] +# [1,] 17 22 27 +# [2,] 22 29 36 +# [3,] 27 36 45 + +# cbind() une vetores em colunas para formar uma matriz +mat2 <- cbind(1:4, c("cachorro", "gato", "passaro", "cachorro")) +mat2 +# [,1] [,2] +# [1,] "1" "cachorro" +# [2,] "2" "gato" +# [3,] "3" "passaro" +# [4,] "4" "cachorro" +class(mat2) # matrix +# Mais uma vez, observe o que aconteceu! +# Como as matrizes devem conter todas as entradas da mesma classe, +# tudo foi convertido para a classe character +c(class(mat2[,1]), class(mat2[,2])) + +# rbind() une vetores linha a linha para fazer uma matriz +mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Ah, tudo da mesma classe. Sem coerções. Muito melhor. + +# BIDIMENSIONAL (CLASSES DIFERENTES) + +# Para colunas de tipos diferentes, use um data frame +# Esta estrutura de dados é tão útil para programação estatística, +# que uma versão dela foi adicionada ao Python através do pacote "pandas". + +estudantes <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"), + c(3,2,2,1,0,-1), + c("H", "G", "G", "R", "S", "G")) +names(estudantes) <- c("nome", "ano", "casa") # nomeie as colunas +class(estudantes) # "data.frame" +estudantes +# nome ano casa +# 1 Cedric 3 H +# 2 Fred 2 G +# 3 George 2 G +# 4 Cho 1 R +# 5 Draco 0 S +# 6 Ginny -1 G +class(estudantes$ano) # "numeric" +class(estudantes[,3]) # "factor" +# encontre as dimensões +nrow(estudantes) # 6 +ncol(estudantes) # 3 +dim(estudantes) # 6 3 +# A função data.frame() converte vetores de caracteres em vetores de fator +# por padrão; desligue isso definindo stringsAsFactors = FALSE quando +# você criar um data frame +?data.frame + +# Existem muitas maneiras particulares de consultar partes de um data frame, +# todas sutilmente diferentes +estudantes$ano # 3 2 2 1 0 -1 +estudantes[,2] # 3 2 2 1 0 -1 +estudantes[,"ano"] # 3 2 2 1 0 -1 + +# Uma versão extendida da estrutura data.frame é a data.table +# Se você estiver trabalhando com dados enormes ou em painel, ou precisar mesclar +# alguns conjuntos de dados, data.table pode ser uma boa escolha. Aqui está um tour +# relâmpago: +install.packages("data.table") # baixe o pacote a partir do CRAN +require(data.table) # carregue ele +estudantes <- as.data.table(estudantes) +estudantes # observe a saída ligeiramente diferente +# nome ano casa +# 1: Cedric 3 H +# 2: Fred 2 G +# 3: George 2 G +# 4: Cho 1 R +# 5: Draco 0 S +# 6: Ginny -1 G +estudantes[nome=="Ginny"] # Consulte estudantes com o nome == "Ginny" +# nome ano casa +# 1: Ginny -1 G +estudantes[ano==2] # Consulte estudantes com o ano == 2 +# nome ano casa +# 1: Fred 2 G +# 2: George 2 G +# data.table facilita a fusão de dois conjuntos de dados +# vamos fazer outro data.table para mesclar com os alunos +fundadores <- data.table(casa=c("G","H","R","S"), + fundador=c("Godric","Helga","Rowena","Salazar")) +fundadores +# casa fundador +# 1: G Godric +# 2: H Helga +# 3: R Rowena +# 4: S Salazar +setkey(estudantes, casa) +setkey(fundadores, casa) +estudantes <- fundadores[estudantes] # mescle os dois conjuntos de dados com base na "casa" +setnames(estudantes, c("casa","nomeFundadorCasa","nomeEstudante","ano")) +estudantes[,order(c("nome","ano","casa","nomeFundadorCasa")), with=F] +# nomeEstudante ano casa nomeFundadorCasa +# 1: Fred 2 G Godric +# 2: George 2 G Godric +# 3: Ginny -1 G Godric +# 4: Cedric 3 H Helga +# 5: Cho 1 R Rowena +# 6: Draco 0 S Salazar + +# O data.table torna as tabelas de sumário fáceis +estudantes[,sum(ano),by=casa] +# casa V1 +# 1: G 3 +# 2: H 3 +# 3: R 1 +# 4: S 0 + +# Para remover uma coluna de um data.frame ou data.table, +# atribua a ela o valor NULL +estudantes$nomeFundadorCasa <- NULL +estudantes +# nomeEstudante ano casa +# 1: Fred 2 G +# 2: George 2 G +# 3: Ginny -1 G +# 4: Cedric 3 H +# 5: Cho 1 R +# 6: Draco 0 S + +# Remova uma linha consultando parte dos dados +# Usando data.table: +estudantes[nomeEstudante != "Draco"] +# casa estudanteNome ano +# 1: G Fred 2 +# 2: G George 2 +# 3: G Ginny -1 +# 4: H Cedric 3 +# 5: R Cho 1 +# Usando data.frame: +estudantes <- as.data.frame(estudantes) +estudantes[estudantes$casa != "G",] +# casa nomeFundadorCasa nomeEstudante ano +# 4 H Helga Cedric 3 +# 5 R Rowena Cho 1 +# 6 S Salazar Draco 0 + +# MULTIDIMENSIONAL (TODOS OS ELEMENTOS DE UM TIPO) + +# Arranjos criam tabelas n-dimensionais +# Todos os elementos devem ser do mesmo tipo +# Você pode fazer uma tabela bidimensional (como uma matriz) +array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# Você pode usar array para fazer matrizes tridimensionais também +array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +# , , 1 +# +# [,1] [,2] +# [1,] 2 8 +# [2,] 300 9 +# [3,] 4 0 +# +# , , 2 +# +# [,1] [,2] +# [1,] 5 66 +# [2,] 60 7 +# [3,] 0 847 + +# LISTAS (MULTIDIMENSIONAIS, POSSIVELMENTE IMPERFEITAS, DE DIFERENTES TIPOS) + +# Finalmente, R tem listas (de vetores) +lista1 <- list(tempo = 1:40) +lista1$preco = c(rnorm(40,.5*lista1$tempo,4)) # aleatória +lista1 +# Você pode obter itens na lista assim +lista1$tempo # um modo +lista1[["tempo"]] # um outro modo +lista1[[1]] # e ainda um outro modo +# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +# [34] 34 35 36 37 38 39 40 +# Você pode obter itens de uma lista como qualquer outro vetor +lista1$preco[4] + +# Listas não são a estrutura de dados mais eficiente para se trabalhar em R; +# a menos que você tenha um bom motivo, você deve se ater a data.frames +# As listas geralmente são retornadas por funções que realizam regressões lineares + +################################################## +# A família de funções apply() +################################################## + +# Lembra de mat? +mat +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Use apply(X, MARGIN, FUN) para aplicar a função FUN a uma matriz X +# sobre linhas (MARGIN = 1) ou colunas (MARGIN = 2) +# Ou seja, R faz FUN para cada linha (ou coluna) de X, muito mais rápido que um +# laço for ou while faria +apply(mat, MAR = 2, jiggle) +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# Outras funções: ?lappy, ?sapply + +# Não as deixe te intimidar; todos concordam que essas funções são bem confusas + +# O pacote plyr visa substituir (e melhorar!) a família *apply(). +install.packages("plyr") +require(plyr) +?plyr + + + +######################### +# Carregando dados +######################### + +# "pets.csv" é um arquivo hospedado na internet +# (mas também poderia tranquilamente ser um arquivo no seu computador) +require(RCurl) +pets <- read.csv(textConnection(getURL("https://learnxinyminutes.com/docs/pets.csv"))) +pets +head(pets, 2) # primeiras duas linhas +tail(pets, 1) # última linha + +# Para salvar um data frame ou matriz como um arquivo .csv: +write.csv(pets, "pets2.csv") # to make a new .csv file +# Define o diretório de trabalho com setwd(), confirme em qual você está com getwd() + +# Experimente ?read.csv e ?write.csv para obter mais informações + + + +######################### +# Análise estatística +######################### + +# Regressão linear! +modeloLinear <- lm(preco ~ tempo, data = lista1) +modeloLinear # imprime na tela o resultado da regressão +# Call: +# lm(formula = preco ~ tempo, data = lista1) +# +# Coefficients: +# (Intercept) tempo +# 0.1453 0.4943 +summary(modeloLinear) # saída mais detalhada da regressão +# Call: +# lm(formula = preco ~ tempo, data = lista1) +# +# Residuals: +# Min 1Q Median 3Q Max +# -8.3134 -3.0131 -0.3606 2.8016 10.3992 +# +# Coefficients: +# Estimate Std. Error t value Pr(>|t|) +# (Intercept) 0.14527 1.50084 0.097 0.923 +# tempo 0.49435 0.06379 7.749 2.44e-09 *** +# --- +# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 +# +# Residual standard error: 4.657 on 38 degrees of freedom +# Multiple R-squared: 0.6124, Adjusted R-squared: 0.6022 +# F-statistic: 60.05 on 1 and 38 DF, p-value: 2.44e-09 +coef(modeloLinear) # extrai os parâmetros estimados +# (Intercept) tempo +# 0.1452662 0.4943490 +summary(modeloLinear)$coefficients # um outro meio de extrair os resultados +# Estimate Std. Error t value Pr(>|t|) +# (Intercept) 0.1452662 1.50084246 0.09678975 9.234021e-01 +# tempo 0.4943490 0.06379348 7.74920901 2.440008e-09 +summary(modeloLinear)$coefficients[,4] # the p-values +# (Intercept) tempo +# 9.234021e-01 2.440008e-09 + +# MODELOS LINEARES GERAIS +# Regressão logística +set.seed(1) +lista1$sucesso = rbinom(length(lista1$tempo), 1, .5) # binário aleatório +modeloLg <- glm(sucesso ~ tempo, data = lista1, + family=binomial(link="logit")) +modeloLg # imprime na tela o resultado da regressão logística +# Call: glm(formula = sucesso ~ tempo, +# family = binomial(link = "logit"), data = lista1) +# +# Coefficients: +# (Intercept) tempo +# 0.17018 -0.01321 +# +# Degrees of Freedom: 39 Total (i.e. Null); 38 Residual +# Null Deviance: 55.35 +# Residual Deviance: 55.12 AIC: 59.12 +summary(modeloLg) # saída mais detalhada da regressão +# Call: +# glm(formula = sucesso ~ tempo, +# family = binomial(link = "logit"), data = lista1) + +# Deviance Residuals: +# Min 1Q Median 3Q Max +# -1.245 -1.118 -1.035 1.202 1.327 +# +# Coefficients: +# Estimate Std. Error z value Pr(>|z|) +# (Intercept) 0.17018 0.64621 0.263 0.792 +# tempo -0.01321 0.02757 -0.479 0.632 +# +# (Dispersion parameter for binomial family taken to be 1) +# +# Null deviance: 55.352 on 39 degrees of freedom +# Residual deviance: 55.121 on 38 degrees of freedom +# AIC: 59.121 +# +# Number of Fisher Scoring iterations: 3 + + +######################### +# Gráficos +######################### + +# FUNÇÕES DE PLOTAGEM INTEGRADAS +# Gráficos de dispersão! +plot(lista1$tempo, lista1$preco, main = "dados falsos") +# Trace a linha de regressão em um gráfico existente! +abline(modeloLinear, col = "red") +# Obtenha uma variedade de diagnósticos legais +plot(modeloLinear) +# Histogramas! +hist(rpois(n = 10000, lambda = 5), col = "thistle") +# Gráficos de barras! +barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) + +# GGPLOT2 +# Mas estes não são nem os mais bonitos dos gráficos no R +# Experimente o pacote ggplot2 para gráficos diferentes e mais bonitos +install.packages("ggplot2") +require(ggplot2) +?ggplot2 +pp <- ggplot(estudantes, aes(x=casa)) +pp + geom_bar() +ll <- as.data.table(lista1) +pp <- ggplot(ll, aes(x=tempo,preco)) +pp + geom_point() +# ggplot2 tem uma excelente documentação (disponível em http://docs.ggplot2.org/current/) + + + +``` + +## Como faço para obter R? + +* Obtenha o R e uma interface gráfica para o R em [http://www.r-project.org/](http://www.r-project.org/) +* [RStudio](http://www.rstudio.com/ide/) é uma outra interface gráfica -- cgit v1.2.3 From 835d077573fea060406ca6e5096779526ae96760 Mon Sep 17 00:00:00 2001 From: MapleinCode Date: Fri, 8 Apr 2022 20:06:22 +0800 Subject: [python/zh-cn]Complete Translation (#4351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 谭九鼎 <109224573@qq.com> --- zh-cn/python-cn.html.markdown | 739 +++++++++++++++++++++++++++++++++--------- 1 file changed, 577 insertions(+), 162 deletions(-) diff --git a/zh-cn/python-cn.html.markdown b/zh-cn/python-cn.html.markdown index 4469443f..a4e53c1b 100644 --- a/zh-cn/python-cn.html.markdown +++ b/zh-cn/python-cn.html.markdown @@ -6,8 +6,10 @@ contributors: - ["Andre Polykanine", "https://github.com/Oire"] translators: - ["Geoff Liu", "http://geoffliu.me"] + - ["Maple", "https://github.com/mapleincode"] filename: learnpython-cn.py lang: zh-cn + --- Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。 @@ -19,7 +21,6 @@ Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。 注意:这篇教程是基于 Python 3 写的。如果你想学旧版 Python 2,我们特别有[另一篇教程](http://learnxinyminutes.com/docs/pythonlegacy/)。 ```python - # 用井字符开头的是单行注释 """ 多行字符串用三个引号 @@ -35,50 +36,66 @@ Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。 3 # => 3 # 算术没有什么出乎意料的 -1 + 1 # => 2 -8 - 1 # => 7 +1 + 1 # => 2 +8 - 1 # => 7 10 * 2 # => 20 # 但是除法例外,会自动转换成浮点数 35 / 5 # => 7.0 -5 / 3 # => 1.6666666666666667 +10.0 / 3 # => 3.3333333333333335 # 整数除法的结果都是向下取整 -5 // 3 # => 1 -5.0 // 3.0 # => 1.0 # 浮点数也可以 --5 // 3 # => -2 --5.0 // 3.0 # => -2.0 +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # 浮点数也可以 +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 # 浮点数的运算结果也是浮点数 3 * 2.0 # => 6.0 # 模除 7 % 3 # => 1 +# i % j 结果的正负符号会和 j 相同,而不是和 i 相同 +-7 % 3 # => 2 -# x的y次方 +# x 的 y 次方 2**4 # => 16 # 用括号决定优先级 +1 + 3 * 2 # => 7 (1 + 3) * 2 # => 8 -# 布尔值 -True -False +# 布尔值 (注意: 首字母大写) +True # => True +False # => False -# 用not取非 -not True # => False +# 用 not 取非 +not True # => False not False # => True -# 逻辑运算符,注意and和or都是小写 +# 逻辑运算符,注意 and 和 or 都是小写 True and False # => False False or True # => True -# 整数也可以当作布尔值 -0 and 2 # => 0 --5 or 0 # => -5 +# True 和 False 实质上就是数字 1 和0 +True + True # => 2 +True * 8 # => 8 +False - 5 # => -5 + +# 数值与 True 和 False 之间的比较运算 0 == False # => True 2 == True # => False 1 == True # => True +-5 != False # => True + +# 使用布尔逻辑运算符对数字类型的值进行运算时,会把数值强制转换为布尔值进行运算 +# 但计算结果会返回它们的强制转换前的值 +# 注意不要把 bool(ints) 与位运算的 "按位与"、"按位或" (&, |) 混淆 +bool(0) # => False +bool(4) # => True +bool(-6) # => True +0 and 2 # => 0 +-5 or 0 # => -5 # 用==判断相等 1 == 1 # => True @@ -94,43 +111,66 @@ False or True # => True 2 <= 2 # => True 2 >= 2 # => True +# 判断一个值是否在范围里 +1 < 2 and 2 < 3 # => True +2 < 3 and 3 < 2 # => False # 大小比较可以连起来! 1 < 2 < 3 # => True 2 < 3 < 2 # => False -# 字符串用单引双引都可以 +# (is 对比 ==) is 判断两个变量是否引用同一个对象, +# 而 == 判断两个对象是否含有相同的值 +a = [1, 2, 3, 4] # 变量 a 是一个新的列表, [1, 2, 3, 4] +b = a # 变量 b 赋值了变量 a 的值 +b is a # => True, a 和 b 引用的是同一个对象 +b == a # => True, a 和 b 的对象的值相同 +b = [1, 2, 3, 4] # 变量 b 赋值了一个新的列表, [1, 2, 3, 4] +b is a # => False, a 和 b 引用的不是同一个对象 +b == a # => True, a 和 b 的对象的值相同 + + +# 创建字符串可以使用单引号(')或者双引号(") "这是个字符串" '这也是个字符串' -# 用加号连接字符串 +# 字符串可以使用加号连接成新的字符串 "Hello " + "world!" # => "Hello world!" +# 非变量形式的字符串甚至可以在没有加号的情况下连接 +"Hello " "world!" # => "Hello world!" # 字符串可以被当作字符列表 -"This is a string"[0] # => 'T' +"Hello world!"[0] # => 'H' -# 用.format来格式化字符串 -"{} can be {}".format("strings", "interpolated") +# 你可以获得字符串的长度 +len("This is a string") # => 16 +# 你可以使用 f-strings 格式化字符串(python3.6+) +name = "Reiko" +f"She said her name is {name}." # => "She said her name is Reiko" +# 你可以在大括号内几乎加入任何 python 表达式,表达式的结果会以字符串的形式返回 +f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long." + +# 用 .format 来格式化字符串 +"{} can be {}".format("strings", "interpolated") # 可以重复参数以节省时间 "{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") # => "Jack be nimble, Jack be quick, Jack jump over the candle stick" - # 如果不想数参数,可以用关键字 "{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna" -# 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法 +# 如果你的 Python3 程序也要在 Python2.5 以下环境运行,也可以用老式的格式化语法 "%s can be %s the %s way" % ("strings", "interpolated", "old") # None是一个对象 None # => None -# 当与None进行比较时不要用 ==,要用is。is是用来比较两个变量是否指向同一个对象。 +# 当与 None 进行比较时不要用 ==,要用 is。is 是用来比较两个变量是否指向同一个对象。 "etc" is None # => False None is None # => True -# None,0,空字符串,空列表,空字典,空元组都算是False -# 所有其他值都是True +# None,0,空字符串,空列表,空字典,空元组都算是 False +# 所有其他值都是 True bool(0) # => False bool("") # => False bool([]) # => False @@ -145,16 +185,26 @@ bool(()) # => False # print是内置的打印函数 print("I'm Python. Nice to meet you!") +# 默认情况下,print 函数会在输出结果后加入一个空行作为结尾 +# 可以使用附加参数改变输出结尾 +print("Hello, World", end="!") # => Hello, World! + +# 可以很简单的从终端获得输入数据 +input_string_var = input("Enter some data: ") # 返回字符串数值 + # 在给变量赋值前不用提前声明 -# 传统的变量命名是小写,用下划线分隔单词 +# 习惯上变量命名是小写,用下划线分隔单词 some_var = 5 some_var # => 5 # 访问未赋值的变量会抛出异常 # 参考流程控制一段来学习异常处理 -some_unknown_var # 抛出NameError +some_unknown_var # 抛出 NameError + +# "if" 可以用作表达式,它的作用等同于 C 语言的三元运算符 "?:" +"yay!" if 0 > 1 else "nay!" # => "nay!" -# 用列表(list)储存序列 +# 用列表 (list) 储存序列 li = [] # 创建列表时也可以同时赋给元素 other_li = [4, 5, 6] @@ -174,128 +224,177 @@ li[0] # => 1 # 取出最后一个元素 li[-1] # => 3 -# 越界存取会造成IndexError -li[4] # 抛出IndexError +# 越界存取会造成 IndexError +li[4] # 抛出 IndexError # 列表有切割语法 -li[1:3] # => [2, 4] +li[1:3] # => [2, 4] # 取尾 -li[2:] # => [4, 3] +li[2:] # => [4, 3] # 取头 -li[:3] # => [1, 2, 4] +li[:3] # => [1, 2, 4] # 隔一个取一个 -li[::2] # =>[1, 4] +li[::2] # =>[1, 4] # 倒排列表 li[::-1] # => [3, 4, 2, 1] # 可以用三个参数的任何组合来构建切割 # li[始:终:步伐] -# 用del删除任何一个元素 -del li[2] # li is now [1, 2, 3] +# 简单的实现了单层数组的深度复制 +li2 = li[:] # => li2 = [1, 2, 4, 3] ,但 (li2 is li) 会返回 False + +# 用 del 删除任何一个元素 +del li[2] # li 现在为 [1, 2, 3] + +# 删除第一个匹配的元素 +li.remove(2) # li 现在为 [1, 3] +li.remove(2) # 抛出错误 ValueError: 2 is not in the list + +# 在指定索引处插入一个新的元素 +li.insert(1, 2) # li is now [1, 2, 3] again + +# 获得列表第一个匹配的值的索引 +li.index(2) # => 1 +li.index(4) # 抛出一个 ValueError: 4 is not in the list # 列表可以相加 -# 注意:li和other_li的值都不变 +# 注意:li 和 other_li 的值都不变 li + other_li # => [1, 2, 3, 4, 5, 6] -# 用extend拼接列表 -li.extend(other_li) # li现在是[1, 2, 3, 4, 5, 6] +# 用 "extend()" 拼接列表 +li.extend(other_li) # li 现在是[1, 2, 3, 4, 5, 6] -# 用in测试列表是否包含值 +# 用 "in" 测试列表是否包含值 1 in li # => True -# 用len取列表长度 +# 用 "len()" 取列表长度 len(li) # => 6 -# 元组是不可改变的序列 +# 元组类似列表,但是不允许修改 tup = (1, 2, 3) tup[0] # => 1 -tup[0] = 3 # 抛出TypeError +tup[0] = 3 # 抛出 TypeError + +# 如果元素数量为 1 的元组必须在元素之后加一个逗号 +# 其他元素数量的元组,包括空元组,都不需要 +type((1)) # => +type((1,)) # => +type(()) # => -# 列表允许的操作元组大都可以 +# 列表允许的操作元组大多都可以 len(tup) # => 3 tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) tup[:2] # => (1, 2) 2 in tup # => True # 可以把元组合列表解包,赋值给变量 -a, b, c = (1, 2, 3) # 现在a是1,b是2,c是3 +a, b, c = (1, 2, 3) # 现在 a 是 1,b 是 2,c 是 3 +# 也可以做扩展解包 +a, *b, c = (1, 2, 3, 4) # 现在 a 是 1, b 是 [2, 3], c 是 4 # 元组周围的括号是可以省略的 -d, e, f = 4, 5, 6 +d, e, f = 4, 5, 6 # 元组 4, 5, 6 通过解包被赋值给变量 d, e, f # 交换两个变量的值就这么简单 -e, d = d, e # 现在d是5,e是4 +e, d = d, e # 现在 d 是 5,e 是 4 -# 用字典表达映射关系 +# 字典用来存储 key 到 value 的映射关系 empty_dict = {} # 初始化的字典 filled_dict = {"one": 1, "two": 2, "three": 3} +# 字典的 key 必须为不可变类型。 这是为了确保 key 被转换为唯一的哈希值以用于快速查询 +# 不可变类型包括整数、浮点、字符串、元组 +invalid_dict = {[1,2,3]: "123"} # => 抛出 TypeError: unhashable type: 'list' +valid_dict = {(1,2,3):[1,2,3]} # 然而 value 可以是任何类型 + # 用[]取值 filled_dict["one"] # => 1 - # 用 keys 获得所有的键。 -# 因为 keys 返回一个可迭代对象,所以在这里把结果包在 list 里。我们下面会详细介绍可迭代。 -# 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。 -list(filled_dict.keys()) # => ["three", "two", "one"] +# 因为 keys 返回一个可迭代对象,所以我们需要把它包在 "list()" 里才能转换为列表。 +# 我们下面会详细介绍可迭代。 +# 注意: 对于版本 < 3.7 的 python, 字典的 key 的排序是无序的。你的运行结果 +# 可能与下面的例子不符,但是在 3.7 版本,字典中的项会按照他们被插入到字典的顺序进行排序 +list(filled_dict.keys()) # => ["three", "two", "one"] Python 版本 <3.7 +list(filled_dict.keys()) # => ["one", "two", "three"] Python 版本 3.7+ +# 用 "values()" 获得所有的值。跟 keys 一样也是可迭代对象,要使用 "list()" 才能转换为列表。 +# 注意: 排序顺序和 keys 的情况相同。 -# 用values获得所有的值。跟keys一样,要用list包起来,顺序也可能不同。 -list(filled_dict.values()) # => [3, 2, 1] +list(filled_dict.values()) # => [3, 2, 1] Python 版本 < 3.7 +list(filled_dict.values()) # => [1, 2, 3] Python 版本 3.7+ # 用in测试一个字典是否包含一个键 "one" in filled_dict # => True 1 in filled_dict # => False -# 访问不存在的键会导致KeyError +# 访问不存在的键会导致 KeyError filled_dict["four"] # KeyError -# 用get来避免KeyError -filled_dict.get("one") # => 1 -filled_dict.get("four") # => None -# 当键不存在的时候get方法可以返回默认值 +# 用 "get()" 来避免KeyError +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None +# 当键不存在的时候 "get()" 方法可以返回默认值 filled_dict.get("one", 4) # => 1 -filled_dict.get("four", 4) # => 4 +filled_dict.get("four", 4) # => 4 -# setdefault方法只有当键不存在的时候插入新值 -filled_dict.setdefault("five", 5) # filled_dict["five"]设为5 -filled_dict.setdefault("five", 6) # filled_dict["five"]还是5 +# "setdefault()" 方法只有当键不存在的时候插入新值 +filled_dict.setdefault("five", 5) # filled_dict["five"] 设为5 +filled_dict.setdefault("five", 6) # filled_dict["five"] 还是5 # 字典赋值 filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} -filled_dict["four"] = 4 # 另一种赋值方法 +filled_dict["four"] = 4 # 另一种赋值方法 -# 用del删除 -del filled_dict["one"] # 从filled_dict中把one删除 +# 用 del 删除项 +del filled_dict["one"] # 从 filled_dict 中把 one 删除 -# 用set表达集合 +# 用 set 表达集合 empty_set = set() # 初始化一个集合,语法跟字典相似。 -some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4} +some_set = {1, 1, 2, 2, 3, 4} # some_set现在是 {1, 2, 3, 4} + +# 类似字典的 keys,set 的元素也必须是不可变类型 +invalid_set = {[1], 1} # => Raises a TypeError: unhashable type: 'list' +valid_set = {(1,), 1} # 可以把集合赋值于变量 filled_set = some_set # 为集合添加元素 -filled_set.add(5) # filled_set现在是{1, 2, 3, 4, 5} +filled_set.add(5) # filled_set 现在是 {1, 2, 3, 4, 5} +# set 没有重复的元素 +filled_set.add(5) # filled_set 依然是 {1, 2, 3, 4, 5} -# & 取交集 +# "&" 取交集 other_set = {3, 4, 5, 6} filled_set & other_set # => {3, 4, 5} -# | 取并集 +# "|" 取并集 filled_set | other_set # => {1, 2, 3, 4, 5, 6} -# - 取补集 +# "-" 取补集 {1, 2, 3, 4} - {2, 3, 5} # => {1, 4} +# "^" 取异或集(对称差) +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# 判断左边的集合是否是右边集合的超集 +{1, 2} >= {1, 2, 3} # => False + +# 判断左边的集合是否是右边集合的子集 +{1, 2} <= {1, 2, 3} # => True + # in 测试集合是否包含元素 2 in filled_set # => True 10 in filled_set # => False +# 单层集合的深度复制 +filled_set = some_set.copy() # filled_set 是 {1, 2, 3, 4, 5} +filled_set is some_set # => False #################################################### ## 3. 流程控制和迭代器 @@ -304,28 +403,30 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6} # 先随便定义一个变量 some_var = 5 -# 这是个if语句。注意缩进在Python里是有意义的 -# 印出"some_var比10小" +# 这是个if语句。注意缩进在Python里是有意义的! +# 缩进要使用 4 个空格而不是 tabs。 +# 这段代码会打印 "some_var is smaller than 10" if some_var > 10: - print("some_var比10大") -elif some_var < 10: # elif句是可选的 - print("some_var比10小") -else: # else也是可选的 - print("some_var就是10") + print("some_var is totally bigger than 10.") +elif some_var < 10: # elif 语句是可选的 + print("some_var is smaller than 10.") +else: # else 也是可选的 + print("some_var is indeed 10.") """ -用for循环语句遍历列表 +用 for 循环语句遍历列表 打印: dog is a mammal cat is a mammal mouse is a mammal """ for animal in ["dog", "cat", "mouse"]: + # 你可以使用 format() 格式化字符串并插入值 print("{} is a mammal".format(animal)) """ -"range(number)"返回数字列表从0到给的数字 +"range(number)" 返回数字列表从 0 到 number 的数字 打印: 0 1 @@ -334,9 +435,41 @@ for animal in ["dog", "cat", "mouse"]: """ for i in range(4): print(i) + +""" +"range(lower, upper)" 会返回一个包含从 lower 到 upper 的数字迭代器 +prints: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print(i) """ -while循环直到条件不满足 +"range(lower, upper, step)" 会返回一个,从 lower 到 upper、并且间隔值为 step 的迭代器。 +如果 step 未传入则会使用默认值 1 +prints: + 4 + 6 +""" +for i in range(4, 8, 2): + print(i) + +""" +遍历列表,并且同时返回列表里的每一个元素的索引和数值。 +prints: + 0 dog + 1 cat + 2 mouse +""" +animals = ["dog", "cat", "mouse"] +for i, value in enumerate(animals): + print(i, value) + +""" +while 循环直到条件不满足 打印: 0 1 @@ -348,20 +481,51 @@ while x < 4: print(x) x += 1 # x = x + 1 的简写 -# 用try/except块处理异常状况 + +# 用 try/except 块处理异常状况 try: - # 用raise抛出异常 + # 用 raise 抛出异常 raise IndexError("This is an index error") except IndexError as e: - pass # pass是无操作,但是应该在这里处理错误 + pass # pass 是无操作,但是应该在这里处理错误 except (TypeError, NameError): - pass # 可以同时处理不同类的错误 -else: # else语句是可选的,必须在所有的except之后 + pass # 可以同时处理不同类的错误 +else: # else语句是可选的,必须在所有的except之后 print("All good!") # 只有当try运行完没有错误的时候这句才会运行 +finally: # 在任何情况下都会执行 + print("We can clean up resources here") + +# 你可以使用 with 语句来代替 try/finally 对操作进行结束的操作 +with open("myfile.txt") as f: + for line in f: + print(line) + +# 写入文件 +contents = {"aa": 12, "bb": 21} +with open("myfile1.txt", "w+") as file: + file.write(str(contents)) # 写入字符串到文件 + +with open("myfile2.txt", "w+") as file: + file.write(json.dumps(contents)) # 写入对象到文件 + +# Reading from a file +with open("myfile1.txt", "r+") as file: + contents = file.read() # 从文件读取字符串 +print(contents) +# print: {"aa": 12, "bb": 21} + +with open("myfile2.txt", "r+") as file: + contents = json.load(file) # 从文件读取 json 对象 +print(contents) +# print: {"aa": 12, "bb": 21} + +# Windows 环境调用 open() 读取文件的默认编码为 ANSI,如果需要读取 utf-8 编码的文件, +# 需要指定 encoding 参数: +# open("myfile3.txt", "r+", encoding = "utf-8") -# Python提供一个叫做可迭代(iterable)的基本抽象。一个可迭代对象是可以被当作序列 -# 的对象。比如说上面range返回的对象就是可迭代的。 +# Python 提供一个叫做可迭代 (iterable) 的基本抽象。一个可迭代对象是可以被当作序列 +# 的对象。比如说上面 range 返回的对象就是可迭代的。 filled_dict = {"one": 1, "two": 2, "three": 3} our_iterable = filled_dict.keys() @@ -378,19 +542,24 @@ our_iterable[1] # 抛出TypeError our_iterator = iter(our_iterable) # 迭代器是一个可以记住遍历的位置的对象 -# 用__next__可以取得下一个元素 -our_iterator.__next__() # => "one" +# 用 "next()" 获得下一个对象 +next(our_iterator) # => "one" -# 再一次调取__next__时会记得位置 -our_iterator.__next__() # => "two" -our_iterator.__next__() # => "three" +# 再一次调取 "next()" 时会记得位置 +next(our_iterator) # => "two" +next(our_iterator) # => "three" -# 当迭代器所有元素都取出后,会抛出StopIteration -our_iterator.__next__() # 抛出StopIteration +# 当迭代器所有元素都取出后,会抛出 StopIteration +next(our_iterator) # 抛出 StopIteration -# 可以用list一次取出迭代器所有的元素 -list(filled_dict.keys()) # => Returns ["one", "two", "three"] +# 我们可以通过遍历还访问所有的值,实际上,for 内部实现了迭代 +our_iterator = iter(our_iterable) +for i in our_iterator: + print(i) # 依次打印 one, two, three +# 可以用 list 一次取出迭代器或者可迭代对象所有的元素 +list(filled_dict.keys()) # => 返回 ["one", "two", "three"] +list(our_iterator) # => 返回 [] 因为迭代的位置被保存了 #################################################### @@ -400,10 +569,10 @@ list(filled_dict.keys()) # => Returns ["one", "two", "three"] # 用def定义新函数 def add(x, y): print("x is {} and y is {}".format(x, y)) - return x + y # 用return语句返回 + return x + y # 用 return 语句返回 # 调用函数 -add(5, 6) # => 印出"x is 5 and y is 6"并且返回11 +add(5, 6) # => 打印 "x is 5 and y is 6" 并且返回 11 # 也可以用关键字参数来调用函数 add(y=6, x=5) # 关键字参数可以用任何顺序 @@ -434,33 +603,43 @@ all_the_args(1, 2, a=3, b=4) prints: {"a": 3, "b": 4} """ -# 调用可变参数函数时可以做跟上面相反的,用*展开序列,用**展开字典。 +# 调用可变参数函数时可以做跟上面相反的,用 * 展开元组,用 ** 展开字典。 args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} all_the_args(*args) # 相当于 all_the_args(1, 2, 3, 4) all_the_args(**kwargs) # 相当于 all_the_args(a=3, b=4) all_the_args(*args, **kwargs) # 相当于 all_the_args(1, 2, 3, 4, a=3, b=4) +# 使用返回多个数值(返回值为元组类型) +def swap(x, y): + return y, x # 用不带括号的元组的格式来返回多个数值 + # (注意: 括号不需要加,但是也可以加) + +x = 1 +y = 2 +x, y = swap(x, y) # => x = 2, y = 1 +# (x, y) = swap(x,y) # 同上,括号不需要加,但是也可以加 + # 函数作用域 x = 5 def setX(num): - # 局部作用域的x和全局域的x是不同的 + # 局部作用域的 x 和全局域的 x 是不同的 x = num # => 43 print (x) # => 43 def setGlobalX(num): global x print (x) # => 5 - x = num # 现在全局域的x被赋值 + x = num # 现在全局域的 x 被赋值 print (x) # => 6 setX(43) setGlobalX(6) -# 函数在Python是一等公民 +# 函数在 Python 是一等公民 def create_adder(x): def adder(y): return x + y @@ -470,39 +649,90 @@ add_10 = create_adder(10) add_10(3) # => 13 # 也有匿名函数 -(lambda x: x > 2)(3) # => True +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 # 内置的高阶函数 -map(add_10, [1, 2, 3]) # => [11, 12, 13] -filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] +list(map(add_10, [1, 2, 3])) # => [11, 12, 13] +list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] + +list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] # 用列表推导式可以简化映射和过滤。列表推导式的返回值是另一个列表。 [add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] +# 你也可以用这种方式实现对集合和字典的构建 +{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} +{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + #################################################### -## 5. 类 +## 5. 模块 #################################################### +# 导入模块 +import math +print(math.sqrt(16)) # => 4.0 + +# 你可以导入模块中具体的函数 +from math import ceil, floor +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 + +# 你可以导入模块中的所有的函数 +# 警告: 此操作不推荐 +from math import * + +# 你可以对模块名进行简化 +import math as m +math.sqrt(16) == m.sqrt(16) # => True + +# Python 模块实质上是 Python 文件 +# 你可以自己编写自己的模块,然后导入 +# 模块的名称和文件名相同 + +# 你可以用 "dir()" 查看模块中定义的函数和字段 +import math +dir(math) + +# 当你的脚本文件所在的文件夹也包含了一个名为 math.py 的 Python 文件 +# 这个 math.p 文件会被代替引入,而不是引入 Python 內建模块中的 math +# 出现这个情况的原因是本地文件夹的引入优先级要比 Python 內建库引入优先级要高 + + +#################################################### +## 6. 类 +#################################################### -# 定义一个继承object的类 -class Human(object): +# 我们使用 "class" 语句来创建类 +class Human: - # 类属性,被所有此类的实例共用。 + # 一个类的字段。 这个字段共享给这个类的所有实例。 species = "H. sapiens" - # 构造方法,当实例被初始化时被调用。注意名字前后的双下划线,这是表明这个属 - # 性或方法对Python有特殊意义,但是允许用户自行定义。你自己取名时不应该用这 - # 种格式。 + # 构造方法,当实例被初始化时被调用。注意名字前后的双下划线,这是表明这个属性 + # 或方法对 Python 有特殊意义,但是允许用户自行定义。 + # 方法(可能是对象或者属性) 类似: __init__, __str__,__repr__ etc + # 都是特殊的方法 + # 你自己取名时不应该用这种格式 def __init__(self, name): - # Assign the argument to the instance's name attribute + # 将参数赋值给实例的 name 字段 self.name = name - # 实例方法,第一个参数总是self,就是这个实例对象 + # 初始化属性 + self._age = 0 + + # 实例方法,第一个参数总是self,也就是这个实例对象 def say(self, msg): - return "{name}: {message}".format(name=self.name, message=msg) + print("{name}: {message}".format(name=self.name, message=msg)) + + # 另一个实例方法 + def sing(self): + return 'yo... yo... microphone check... one two... one two...' - # 类方法,被所有此类的实例共用。第一个参数是这个类对象。 + # 类方法,被所有此类的实例共用。 + # 第一个参数是这个类对象。 @classmethod def get_species(cls): return cls.species @@ -512,53 +742,225 @@ class Human(object): def grunt(): return "*grunt*" + # property 有点类似 getter + # 它把方法 age() 转换为同名并且只读的属性 + # 通常情况下,可以不需要编写复杂的 getter 和 setter。 + @property + def age(self): + return self._age + + # 允许属性被修改 + @age.setter + def age(self, age): + self._age = age + + # 允许属性被删除 + @age.deleter + def age(self): + del self._age + +# 当 Python 解释器在读取源文件的时候,就会执行文件中所有的代码 +# 对 __name__ 的检查可以保证这块代码只会在执行这个模块是住程序情况下被运行(而不是在引用时运行) +if __name__ == '__main__': + # + i = Human(name="Ian") + i.say("hi") # "Ian: hi" + j = Human("Joel") + j.say("hello") # "Joel: hello" + # i 和 j 都是 Human 实例化后的对象,换一句话说,它们都是 Human 实例 + + # 运行类方法 (classmethod) + i.say(i.get_species()) # "Ian: H. sapiens" + # 修改共享的类属性 + Human.species = "H. neanderthalensis" + i.say(i.get_species()) # => "Ian: H. neanderthalensis" + j.say(j.get_species()) # => "Joel: H. neanderthalensis" + + # 运行静态方法 (staticmethod) + print(Human.grunt()) # => "*grunt*" + + # 实例上也可以执行静态方法 + print(i.grunt()) # => "*grunt*" + + # 更新实例的属性 + i.age = 42 + # 访问实例的属性 + i.say(i.age) # => "Ian: 42" + j.say(j.age) # => "Joel: 0" + # 删除实例的属性 + del i.age + # i.age # => 这会抛出一个错误: AttributeError + + +#################################################### +## 6.1 类的继承 +#################################################### + +# 继承机制允许子类可以继承父类上的方法和变量。 +# 我们可以把 Human 类作为一个基础类或者说叫做父类, +# 然后定义一个名为 Superhero 的子类来继承父类上的比如 "species"、 "name"、 "age" 的属性 +# 和比如 "sing" 、"grunt" 这样的方法,同时,也可以定义它自己独有的属性 + +# 基于 Python 文件模块化的特点,你可以把这个类放在独立的文件中,比如说,human.py。 + +# 要从别的文件导入函数,需要使用以下的语句 +# from "filename-without-extension" import "function-or-class" + +from human import Human + +# 指定父类作为类初始化的参数 +class Superhero(Human): + + # 如果子类需要继承所有父类的定义,并且不需要做任何的修改, + # 你可以直接使用 "pass" 关键字(并且不需要其他任何语句) + # 但是在这个例子中会被注释掉,以用来生成不一样的子类。 + # pass + + # 子类可以重写父类定义的字段 + species = 'Superhuman' + + # 子类会自动的继承父类的构造函数包括它的参数,但同时,子类也可以新增额外的参数或者定义, + # 甚至去覆盖父类的方法比如说构造函数。 + # 这个构造函数从父类 "Human" 上继承了 "name" 参数,同时又新增了 "superpower" 和 + # "movie" 参数: + def __init__(self, name, movie=False, + superpowers=["super strength", "bulletproofing"]): + + # 新增额外类的参数 + self.fictional = True + self.movie = movie + # 注意可变的默认值,因为默认值是共享的 + self.superpowers = superpowers + + # "super" 函数让你可以访问父类中被子类重写的方法 + # 在这个例子中,被重写的是 __init__ 方法 + # 这个语句是用来运行父类的构造函数: + super().__init__(name) + + # 重写父类中的 sing 方法 + def sing(self): + return 'Dun, dun, DUN!' + + # 新增一个额外的方法 + def boast(self): + for power in self.superpowers: + print("I wield the power of {pow}!".format(pow=power)) + + +if __name__ == '__main__': + sup = Superhero(name="Tick") + + # 检查实例类型 + if isinstance(sup, Human): + print('I am human') + if type(sup) is Superhero: + print('I am a superhero') -# 构造一个实例 -i = Human(name="Ian") -print(i.say("hi")) # 印出 "Ian: hi" + # 获取方法解析顺序 MRO,MRO 被用于 getattr() 和 super() + # 这个字段是动态的,并且可以被修改 + print(Superhero.__mro__) # => (, + # => , ) -j = Human("Joel") -print(j.say("hello")) # 印出 "Joel: hello" + # 调用父类的方法并且使用子类的属性 + print(sup.get_species()) # => Superhuman -# 调用一个类方法 -i.get_species() # => "H. sapiens" + # 调用被重写的方法 + print(sup.sing()) # => Dun, dun, DUN! -# 改一个共用的类属性 -Human.species = "H. neanderthalensis" -i.get_species() # => "H. neanderthalensis" -j.get_species() # => "H. neanderthalensis" + # 调用 Human 的方法 + sup.say('Spoon') # => Tick: Spoon -# 调用静态方法 -Human.grunt() # => "*grunt*" + # 调用 Superhero 独有的方法 + sup.boast() # => I wield the power of super strength! + # => I wield the power of bulletproofing! + + # 继承类的字段 + sup.age = 31 + print(sup.age) # => 31 + + # Superhero 独有的字段 + print('Am I Oscar eligible? ' + str(sup.movie)) #################################################### -## 6. 模块 +## 6.2 多重继承 #################################################### -# 用import导入模块 -import math -print(math.sqrt(16)) # => 4.0 +# 定义另一个类 +# bat.py +class Bat: -# 也可以从模块中导入个别值 -from math import ceil, floor -print(ceil(3.7)) # => 4.0 -print(floor(3.7)) # => 3.0 + species = 'Baty' -# 可以导入一个模块中所有值 -# 警告:不建议这么做 -from math import * + def __init__(self, can_fly=True): + self.fly = can_fly -# 如此缩写模块名字 -import math as m -math.sqrt(16) == m.sqrt(16) # => True + # 这个类同样有 say 的方法 + def say(self, msg): + msg = '... ... ...' + return msg -# Python模块其实就是普通的Python文件。你可以自己写,然后导入, -# 模块的名字就是文件的名字。 + # 新增一个独有的方法 + def sonar(self): + return '))) ... (((' -# 你可以这样列出一个模块里所有的值 -import math -dir(math) +if __name__ == '__main__': + b = Bat() + print(b.say('hello')) + print(b.fly) + +# 现在我们来定义一个类来同时继承 Superhero 和 Bat +# superhero.py +from superhero import Superhero +from bat import Bat + +# 定义 Batman 作为子类,来同时继承 SuperHero 和 Bat +class Batman(Superhero, Bat): + + def __init__(self, *args, **kwargs): + # 通常要继承属性,你必须调用 super: + # super(Batman, self).__init__(*args, **kwargs) + # 然而在这里我们处理的是多重继承,而 super() 只会返回 MRO 列表的下一个基础类。 + # 因此,我们需要显式调用初始类的 __init__ + # *args 和 **kwargs 传递参数时更加清晰整洁,而对于父类而言像是 “剥了一层洋葱” + Superhero.__init__(self, 'anonymous', movie=True, + superpowers=['Wealthy'], *args, **kwargs) + Bat.__init__(self, *args, can_fly=False, **kwargs) + # 重写了 name 字段 + self.name = 'Sad Affleck' + + def sing(self): + return 'nan nan nan nan nan batman!' + + +if __name__ == '__main__': + sup = Batman() + + # 获取方法解析顺序 MRO,MRO 被用于 getattr() 和 super() + # 这个字段是动态的,并且可以被修改 + print(Batman.__mro__) # => (, + # => , + # => , + # => , ) + + # 调用父类的方法并且使用子类的属性 + print(sup.get_species()) # => Superhuman + + # 调用被重写的类 + print(sup.sing()) # => nan nan nan nan nan batman! + + # 调用 Human 上的方法,(之所以是 Human 而不是 Bat),是因为继承顺序起了作用 + sup.say('I agree') # => Sad Affleck: I agree + + # 调用仅存在于第二个继承的父类的方法 + print(sup.sonar()) # => ))) ... ((( + + # 继承类的属性 + sup.age = 100 + print(sup.age) # => 100 + + # 从第二个类上继承字段,并且其默认值被重写 + print('Can I fly? ' + str(sup.fly)) # => Can I fly? False #################################################### @@ -583,6 +985,10 @@ for i in double_numbers(range_): print(i) if i >= 30: break +# 你也可以把一个生成器推导直接转换为列表 +values = (-x for x in [1,2,3,4,5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] # 装饰器(decorators) @@ -612,18 +1018,27 @@ print(say()) # Can you buy me a beer? print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ``` -## 想继续学吗? -### 线上免费材料(英文) -* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) -* [Dive Into Python](http://www.diveintopython.net/) -* [Ideas for Python Projects](http://pythonpracticeprojects.com) +## 想继续学吗? -* [The Official Docs](http://docs.python.org/3/) -* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) -* [Python Module of the Week](http://pymotw.com/3/) -* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) +### 在线免费材料(英文) + +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com/) +* [Ideas for Python Projects](http://pythonpracticeprojects.com/) +* [The Official Docs](https://docs.python.org/3/) +* [Hitchhiker’s Guide to Python](https://docs.python-guide.org/en/latest/) +* [Python Course](https://www.python-course.eu/) +* [Free Interactive Python Course](http://www.kikodo.io/) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) +* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python) +* [30 Python Language Features and Tricks You May Not Know About](https://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html) +* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/) +* [Python 3 Computer Science Circles](https://cscircles.cemc.uwaterloo.ca/) +* [Dive Into Python 3](https://www.diveintopython3.net/index.html) +* [A Crash Course in Python for Scientists](https://nbviewer.jupyter.org/gist/anonymous/5924718) +* [Python Tutorial for Intermediates](https://pythonbasics.org/) +* [Build a Desktop App with Python](https://pythonpyqt.com/) ### 书籍(也是英文) -- cgit v1.2.3 From fbdc0115e9d53cf1b57f0bacd85094402b5af608 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sat, 9 Apr 2022 00:14:18 +0200 Subject: Update return of class(mat) according to R 4.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A matrix is the special case of a two-dimensional ‘array’. Since R 4.0.0, ‘inherits(m, "array")’ is true for a ‘matrix’ ‘m’, which makes class(mat) return "matrix" "array", not only "matrix" as before. --- r.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r.html.markdown b/r.html.markdown index e90d5a97..c3422d2d 100644 --- a/r.html.markdown +++ b/r.html.markdown @@ -405,7 +405,7 @@ mat # [2,] 2 5 # [3,] 3 6 # Unlike a vector, the class of a matrix is "matrix", no matter what's in it -class(mat) # => "matrix" +class(mat) # => "matrix" "array" # Ask for the first row mat[1,] # 1 4 # Perform operation on the first column -- cgit v1.2.3 From c4c53cc95eeb792e25e04871ca7d7b13b11193e9 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sat, 9 Apr 2022 00:21:01 +0200 Subject: Fix warning about stringsAsFactors In R 4.0.0, stringsAsFactors default value changed from TRUE to FALSE. This commit fixes the warning message in the current file to make this clear for readers. This commit also updates the list of contributors for this file. --- r.html.markdown | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/r.html.markdown b/r.html.markdown index c3422d2d..e42b1f5e 100644 --- a/r.html.markdown +++ b/r.html.markdown @@ -4,6 +4,7 @@ contributors: - ["e99n09", "http://github.com/e99n09"] - ["isomorphismes", "http://twitter.com/isomorphisms"] - ["kalinn", "http://github.com/kalinn"] + - ["mribeirodantas", "http://github.com/mribeirodantas"] filename: learnr.r --- @@ -478,9 +479,10 @@ class(students[,3]) # "factor" nrow(students) # 6 ncol(students) # 3 dim(students) # 6 3 -# The data.frame() function converts character vectors to factor vectors -# by default; turn this off by setting stringsAsFactors = FALSE when -# you create the data.frame +# The data.frame() function used to convert character vectors to factor +# vectors by default; This has changed in R 4.0.0. If your R version is +# older, turn this off by setting stringsAsFactors = FALSE when you +# create the data.frame ?data.frame # There are many twisty ways to subset data frames, all subtly unalike -- cgit v1.2.3 From b05a7b07a858119bcdefc5d887fc5d80c4e22c2f Mon Sep 17 00:00:00 2001 From: Ishan Madhusanka Date: Sat, 9 Apr 2022 09:06:21 +0530 Subject: [solidity/en] fix minor typos --- solidity.html.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solidity.html.markdown b/solidity.html.markdown index 5f8ef407..c52d2002 100644 --- a/solidity.html.markdown +++ b/solidity.html.markdown @@ -214,7 +214,7 @@ assert(c >= a); // assert tests for internal invariants; require is used for use // https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol -// No random functions built in, you can get a pseduo-random number by hashing the current blockhash, or get a truely random number using something like Chainlink VRF. +// No random functions built in, you can get a pseduo-random number by hashing the current blockhash, or get a truly random number using something like Chainlink VRF. // https://docs.chain.link/docs/get-a-random-number // Type casting @@ -396,13 +396,13 @@ function increment(uint x) returns (uint) { return x; } -// Functions can return many arguments, and by specifying returned arguments -// name don't need to explicitly return +// Functions can return many arguments, +// and by specifying returned arguments name explicit return is not needed function increment(uint x, uint y) returns (uint x, uint y) { x += 1; y += 1; } -// Call previous functon +// Call previous function uint (a,b) = increment(1,1); // 'view' (alias for 'constant') @@ -654,7 +654,7 @@ reveal(100, "mySecret"); // Time-based implementations of contracts are also done through oracles, as // contracts need to be directly called and can not "subscribe" to a time. // Due to smart contracts being decentralized, you also want to get your data -// in a decentralized manner, other your run into the centralized risk that +// in a decentralized manner, otherwise you run into the centralized risk that // smart contract design matter prevents. // To easiest way get and use pre-boxed decentralized data is with Chainlink Data Feeds -- cgit v1.2.3 From 0b4d87af6131021fdaa99ced7c1f5f10785425a1 Mon Sep 17 00:00:00 2001 From: tobycm <62174797+tobycm@users.noreply.github.com> Date: Sun, 10 Apr 2022 19:03:47 -0700 Subject: Add a missing comma In json/vi-vn --- vi-vn/json-vi.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vi-vn/json-vi.html.markdown b/vi-vn/json-vi.html.markdown index 257216ff..f709b838 100644 --- a/vi-vn/json-vi.html.markdown +++ b/vi-vn/json-vi.html.markdown @@ -37,7 +37,7 @@ kiểu dữ liệu cũng như quy chuẩn cú pháp chặt chẽ sử dụng DTD "các khóa": "phải luôn được đặt trong dấu ngoặc kép", "số": 0, - "chuỗi kí tự": "Xin chàø. Tất cả kí tự unicode đều được chấp nhận, sử dụng với dạng \"kí tự\"." + "chuỗi kí tự": "Xin chàø. Tất cả kí tự unicode đều được chấp nhận, sử dụng với dạng \"kí tự\".", "có đúng không?": true, "không có gì": null, -- cgit v1.2.3 From ba98061fc0c2d9306971495d14ae35f4779113fc Mon Sep 17 00:00:00 2001 From: Maou-Shimazu Date: Mon, 18 Apr 2022 17:37:23 -0600 Subject: Adding markdown file for V --- v.html.markdown | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 v.html.markdown 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 -- cgit v1.2.3 From 667174e0caf6fbbb67aa70c9b39060706e568ae6 Mon Sep 17 00:00:00 2001 From: agbohub <14964685+agbohub@users.noreply.github.com> Date: Wed, 20 Apr 2022 18:12:47 +0800 Subject: =?UTF-8?q?Delete=20repeated=20word=20"one"=20in=20=C2=A7Intro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vimscript.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vimscript.html.markdown b/vimscript.html.markdown index c2934af8..5bcaad45 100644 --- a/vimscript.html.markdown +++ b/vimscript.html.markdown @@ -11,7 +11,7 @@ contributors: " ############## " " Vim script (also called VimL) is the subset of Vim's ex-commands which -" supplies a number of features one one would expect from a scripting language, +" supplies a number of features one would expect from a scripting language, " such as values, variables, functions or loops. Always keep in the back of " your mind that a Vim script file is just a sequence of ex-commands. It is " very common for a script to mix programming-language features and raw -- cgit v1.2.3 From 0576f1e9b757b69cf8f297276a70757a6103fea1 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 25 May 2022 22:06:01 +0200 Subject: [latex/en] add learnlatex.org as resource --- latex.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/latex.html.markdown b/latex.html.markdown index 34c4b78d..5165e8cd 100644 --- a/latex.html.markdown +++ b/latex.html.markdown @@ -320,3 +320,4 @@ That's all for now! * The amazing LaTeX Wikibook: [https://en.wikibooks.org/wiki/LaTeX](https://en.wikibooks.org/wiki/LaTeX) * An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) * A quick guide for learning LaTeX: [Learn LaTeX in 30 minutes](https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes) +* An interactive platform to learn LaTeX (installationfree) [learnlatex.org/](https://www.learnlatex.org/) -- cgit v1.2.3 From c43348a7f6041e6916303ef06d2429c383ef2371 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 25 May 2022 22:08:07 +0200 Subject: [latex/en] add tex.stackexchange as resource --- latex.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/latex.html.markdown b/latex.html.markdown index 5165e8cd..9edc057e 100644 --- a/latex.html.markdown +++ b/latex.html.markdown @@ -321,3 +321,4 @@ That's all for now! * An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) * A quick guide for learning LaTeX: [Learn LaTeX in 30 minutes](https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes) * An interactive platform to learn LaTeX (installationfree) [learnlatex.org/](https://www.learnlatex.org/) +* Stack Exchange's question and answer site about TeX, LaTeX, ConTeXt, etc. [tex.stackexchange.com](https://tex.stackexchange.com/) -- cgit v1.2.3 From 095e771a2a2d60484025f852f15ea902d5885cc7 Mon Sep 17 00:00:00 2001 From: norwid Date: Fri, 27 May 2022 15:49:40 +0200 Subject: vim/de remove duplicated line The line duplicated was the English pattern already translated into German. --- de-de/vim-de.html.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 8abf9a14..93fd9773 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -21,7 +21,6 @@ einer Datei. ``` vim # Öffne in Vim - :help # Open up built-in help docs about if any exists :help # Öffne die eingebaute Hilfe zum Thema , wenn # es existiert :q # Schließe vim -- cgit v1.2.3 From 52cc58a5edb34910a33e1daa328955c47c23e194 Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Thu, 2 Jun 2022 00:26:23 -0400 Subject: [jq/en] Add jq. --- jq.html.markdown | 750 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 750 insertions(+) create mode 100644 jq.html.markdown diff --git a/jq.html.markdown b/jq.html.markdown new file mode 100644 index 00000000..5aa03b91 --- /dev/null +++ b/jq.html.markdown @@ -0,0 +1,750 @@ +--- +category: tool +tool: jq +contributors: + - ["Jack Kuan", "https://github.com/kjkuan"] +filename: learnjq.sh +translators: +--- + +`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. + +```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 --arg val 123 -n '$val' # $val is the string "123" here + +# Output: +# "123" + + +# If you need to pass a JSON value, use `--argjson` +# +jq --arg val 123 -n '$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" }' + +# Output: +# +# 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 ): Cannot index number with number +jq -n '"abc" | .name' # => jq: error (at ): Cannot index string with string "name" +jq -n '{"a": 97} | .[0]' # => jq: error (at ): Cannot index object with number +jq -n '[89, 64] | .["key"]' # => jq: error (at ): 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. +# +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. + +# 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 think 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 + + +# 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. + + +# FIXME: Cover more topics +# - update +# - deletion +# - function definition +# - ... +``` + +## Further Reading +- https://stedolan.github.io/jq/manual/ +- https://github.com/stedolan/jq/wiki/jq-Language-Description -- cgit v1.2.3 From f9b949fbf8980d4d47fabadcc6669425d41eb454 Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Thu, 2 Jun 2022 00:54:50 -0400 Subject: Add parts missing due to copy&paste. --- jq.html.markdown | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/jq.html.markdown b/jq.html.markdown index 5aa03b91..31ce4d43 100644 --- a/jq.html.markdown +++ b/jq.html.markdown @@ -245,8 +245,37 @@ jq -n '[2*3, 8-1, 16/2], {("tw" + "o"): (1 + 1)}' # 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: +# +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 -- cgit v1.2.3 From ee7c1918b47774c4534d9ac3fe450ffc662b8b0e Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Thu, 2 Jun 2022 01:02:03 -0400 Subject: Reformat long lines. --- jq.html.markdown | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/jq.html.markdown b/jq.html.markdown index 31ce4d43..2178820f 100644 --- a/jq.html.markdown +++ b/jq.html.markdown @@ -132,8 +132,9 @@ jq --arg text "$(date; echo "Have a nice day!")" -n '{ "today": $text }' # } -# 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. +# 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 . @@ -157,13 +158,14 @@ jq -rn '"1 + 2 = \(1+2)"' # 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 `-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. +# 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"}' \ @@ -187,11 +189,12 @@ declare -p var1 var2 # 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. +# 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: +# The comma (`,`) operator in jq evaluates each operand and generates multiple +# outputs: # jq -n '"one", 2, ["three"], {"four": 4}' @@ -206,7 +209,9 @@ jq -n '"one", 2, ["three"], {"four": 4}' # } -# Any JSON value is a valid jq expression that evaluates to the JSON value itself. +# 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: @@ -224,8 +229,8 @@ jq -n '1, "one", [1, 2], {"one": 1}, null, true, false' # 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) +# 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)}' @@ -259,8 +264,8 @@ jq -n '{ c: 3} | { a: 1, "b", c }' # 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. +# 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 @@ -292,8 +297,8 @@ jq -n '1, 2, 3 | ., 4 | .' # 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: +# 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: # @@ -376,8 +381,8 @@ jq -n '"abc" | .name? // "unknown"' # => "unknown" # 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: +# 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"] @@ -596,7 +601,8 @@ echo $numbers | jq -rs ' # Slurp the numbers into an array. ] # 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). + # 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: -- cgit v1.2.3 From 2257d6bae2960c436295ce7c6da45151ea7a7d3d Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Fri, 3 Jun 2022 01:00:10 -0400 Subject: Fix typo and talk about updating and deleting. --- jq.html.markdown | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/jq.html.markdown b/jq.html.markdown index 2178820f..3691baaf 100644 --- a/jq.html.markdown +++ b/jq.html.markdown @@ -107,7 +107,7 @@ jq . hello.json # Below, `val` is the variable name to bind the value, `123`, to. # The variable is then referenced as `$val`. # -jq --arg val 123 -n '$val' # $val is the string "123" here +jq -n --arg val 123 '$val' # $val is the string "123" here # Output: # "123" @@ -115,7 +115,7 @@ jq --arg val 123 -n '$val' # $val is the string "123" here # If you need to pass a JSON value, use `--argjson` # -jq --arg val 123 -n '$val' # $val is a number +jq -n --argjson val 123 '$val' # $val is a number # Output: # 123 @@ -773,9 +773,33 @@ jq -n '.a=1, .a.b=2' # => {"a": 1} {"a": {"b": 2}} # 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 +# ] +# } + # FIXME: Cover more topics -# - update -# - deletion # - function definition # - ... ``` @@ -783,3 +807,5 @@ jq -n '.a=1, .a.b=2' # => {"a": 1} {"a": {"b": 2}} ## 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 -- cgit v1.2.3 From 0ef85542ef8d8d3f744fa94d1d9e03feb04c6b6d Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Sat, 4 Jun 2022 02:56:47 -0400 Subject: Introduce function definition, and add more examples. --- jq.html.markdown | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/jq.html.markdown b/jq.html.markdown index 3691baaf..3b756890 100644 --- a/jq.html.markdown +++ b/jq.html.markdown @@ -362,7 +362,7 @@ jq -n '.unknown_key // 7' # => 7 jq -n '123 | .[0]' # => jq: error (at ): Cannot index number with number jq -n '"abc" | .name' # => jq: error (at ): Cannot index string with string "name" jq -n '{"a": 97} | .[0]' # => jq: error (at ): Cannot index object with number -jq -n '[89, 64] | .["key"]' # => jq: error (at ): Cannot index array with string "key" +jq -n '[89, 64] | .["key"]' # => jq: error (at ): Cannot index array with string "key" # You can, however, append a `?` to a lookup to make jq return `empty` # instead when such error happens. @@ -443,7 +443,19 @@ jq -n '{ values: ({ a: 1, b: 2, c: 3 }[] | . * 2) }' # Conditional `if ... then ... else ... end` in jq is an expression, so -# both the `then` part and the `else` part are required. +# 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' @@ -608,7 +620,7 @@ echo $numbers | jq -rs ' # Slurp the numbers into an array. | # 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") @@ -682,7 +694,7 @@ jq -n '["a", "b", "c"] | reduce .[] as $i (""; . + $i)' # => "abc" # # reduce (1, 2, 3, 4, 5) as $i (0; . + $i) # -# can be think of as doing: +# can be think of as doing: # # 0 + 1 | . + 2 | . + 3 | . + 4 | . + 5 # @@ -730,7 +742,7 @@ jq -rn '[1, 2, 3, 4, 5] # 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)" @@ -749,6 +761,26 @@ jq -rn 'range(2; 4) as $i # 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 + + # 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 @@ -761,7 +793,7 @@ jq -n '.a = 1 | .b = .a + 1' # => {"a": 1, "b": 2} # 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: # @@ -799,9 +831,43 @@ jq -n '{a: 1, b: {c: 2}, d: [3, 4, 5]} | del(.b.c, .d[1]) | .b.x = 6' # ] # } -# FIXME: Cover more topics -# - function definition -# - ... + +# 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. +# +# - `def f($a; $b): ...;` is a shorthand for: `def f(a; b): a as $a | b as $b | ...` +# + ``` ## Further Reading -- cgit v1.2.3 From 2b1cfc6ab6d86747c30e412cbb0754035f5f7253 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sat, 4 Jun 2022 19:57:32 +0200 Subject: Apply suggestions from code review This commit includes suggestions originally proposed by @halian-vilela Co-authored-by: Halian Vilela --- pt-br/r-pt.html.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pt-br/r-pt.html.markdown b/pt-br/r-pt.html.markdown index 2bbafe17..eeaa4eab 100644 --- a/pt-br/r-pt.html.markdown +++ b/pt-br/r-pt.html.markdown @@ -10,7 +10,7 @@ lang: pt-br filename: learnr.r --- -R é uma linguagem de programação estatística. Ela tem muitas bibliotecas para carregar e limpar conjuntos de dados, executar análises estatísticos e produzir gráficos. Você também pode executar comandos do `R` dentro de um documento LaTeX. +R é uma linguagem de programação estatística. Ela tem muitas bibliotecas para carregar e limpar conjuntos de dados, executar análises estatísticas e produzir gráficos. Você também pode executar comandos do `R` dentro de um documento LaTeX. ```r @@ -22,7 +22,7 @@ R é uma linguagem de programação estatística. Ela tem muitas bibliotecas par # cerquilha (#) ao início de cada uma delas. # No Windows e Linux, você pode usar CTRL-ENTER para executar uma linha. -# No MacOS o equivalente é COMMAND-ENTER +# No MacOS, o equivalente é COMMAND-ENTER @@ -357,7 +357,7 @@ jiggle(5) # 5±ε. Após set.seed(2716057), jiggle(5)==5.005043 ########################################################################### -# Estruturas de dados: Vetores, matrizes, data frames, and arranjos +# Estruturas de dados: Vetores, matrizes, data frames e arranjos (arrays) ########################################################################### # UNIDIMENSIONAL @@ -573,7 +573,7 @@ estudantes[estudantes$casa != "G",] # MULTIDIMENSIONAL (TODOS OS ELEMENTOS DE UM TIPO) -# Arranjos criam tabelas n-dimensionais +# Arranjos (arrays) criam tabelas n-dimensionais # Todos os elementos devem ser do mesmo tipo # Você pode fazer uma tabela bidimensional (como uma matriz) array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) @@ -658,7 +658,7 @@ head(pets, 2) # primeiras duas linhas tail(pets, 1) # última linha # Para salvar um data frame ou matriz como um arquivo .csv: -write.csv(pets, "pets2.csv") # to make a new .csv file +write.csv(pets, "pets2.csv") # para criar um novo arquivo .csv # Define o diretório de trabalho com setwd(), confirme em qual você está com getwd() # Experimente ?read.csv e ?write.csv para obter mais informações -- cgit v1.2.3 From 0801451fd75e8d59b960897fe7f3c30eddaa06e1 Mon Sep 17 00:00:00 2001 From: Jack Kuan Date: Sun, 5 Jun 2022 18:48:08 -0400 Subject: Final touch. --- jq.html.markdown | 72 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/jq.html.markdown b/jq.html.markdown index 3b756890..55b20126 100644 --- a/jq.html.markdown +++ b/jq.html.markdown @@ -8,12 +8,15 @@ translators: --- `jq` is a tool for transforming JSON inputs and generating JSON outputs. As a -programming language,`jq` supports boolean and arithmetic expressions, object +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 +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 @@ -251,9 +254,9 @@ jq -n '[2*3, 8-1, 16/2], {("tw" + "o"): (1 + 1)}' 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: +# input using the key: (see next example for the meaning of `... | ...`) # -jq -n '{ c: 3} | { a: 1, "b", c }' +jq -n '{c: 3} | {a: 1, "b", c}' # Output: # { @@ -321,35 +324,35 @@ jq -n '1, 2, 3 | ., 4 | .' # 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 +# 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 +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 +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 +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 +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 +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 +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`. @@ -403,7 +406,7 @@ jq -n '["Peter", "Jerry", "Tom"][1:99]' # => ["Jerry", "Tom"] echo 1 2 3 | jq . jq -n '1, 2, 3' jq -n '[1, 2, 3][]' -jq -n '{ a: 1, b: 2, c: 3 }[]' +jq -n '{a: 1, b: 2, c: 3}[]' # Output: # 1 @@ -413,7 +416,7 @@ jq -n '{ a: 1, b: 2, c: 3 }[]' # You can build an array out of multiple outputs. # -jq -n '{ values: [{ a: 1, b: 2, c: 3 }[] | . * 2] }' +jq -n '{values: [{a: 1, b: 2, c: 3}[] | . * 2]}' # Output: # { @@ -428,7 +431,7 @@ jq -n '{ values: [{ a: 1, b: 2, c: 3 }[] | . * 2] }' # 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) }' +jq -n '{values: ({a: 1, b: 2, c: 3}[] | . * 2)}' # Output: # { @@ -483,6 +486,12 @@ jq -n '1, 2, 3, 4, 5 | select(. % 2 != 0)' # NOTE: % gives the remainder. # 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. @@ -694,7 +703,7 @@ jq -n '["a", "b", "c"] | reduce .[] as $i (""; . + $i)' # => "abc" # # reduce (1, 2, 3, 4, 5) as $i (0; . + $i) # -# can be think of as doing: +# can be thought of as doing: # # 0 + 1 | . + 2 | . + 3 | . + 4 | . + 5 # @@ -781,6 +790,30 @@ EOF # 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 @@ -865,11 +898,12 @@ jq -n ' # - Function parameters are separated by `;` (semicolor). This is consistent with # passing multiple arguments when calling a function. # -# - `def f($a; $b): ...;` is a shorthand for: `def f(a; b): a as $a | b as $b | ...` +# - 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 -- cgit v1.2.3 From 82fc4e830eb2fb1a5b526b665e894ea33d10ff52 Mon Sep 17 00:00:00 2001 From: Benjamin Porter Date: Fri, 17 Jun 2022 13:56:04 -0600 Subject: fix typo: pacing -> placing --- vimscript.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vimscript.html.markdown b/vimscript.html.markdown index c2934af8..c32faee9 100644 --- a/vimscript.html.markdown +++ b/vimscript.html.markdown @@ -42,7 +42,7 @@ pwd " Displays the current working directory " comment (echo assumes that the quotation mark begins a string) echo 'Hello world!' | " Displays a message -" Line breaks can be escaped by pacing a backslash as the first non-whitespace +" Line breaks can be escaped by placing a backslash as the first non-whitespace " character on the *following* line. Only works in script files, not on the " command line echo " Hello -- cgit v1.2.3 From e617660ad5c1885e524bcdb82df5bf3f7c2c14ee Mon Sep 17 00:00:00 2001 From: Alexey Berezuev Date: Wed, 15 Jun 2022 12:17:20 +0300 Subject: Fix some typos of russian translations --- ru-ru/asymptotic-notation-ru.html.markdown | 6 +++--- ru-ru/binary-search-ru.html.markdown | 2 +- ru-ru/c++-ru.html.markdown | 2 +- ru-ru/c-ru.html.markdown | 2 +- ru-ru/css-ru.html.markdown | 6 +++--- ru-ru/forth-ru.html.markdown | 2 +- ru-ru/haml-ru.html.markdown | 10 +++++----- ru-ru/haskell-ru.html.markdown | 4 ++-- ru-ru/html-ru.html.markdown | 16 ++++++++-------- ru-ru/javascript-ru.html.markdown | 2 +- ru-ru/linker-ru.html.markdown | 24 ++++++++++++------------ ru-ru/markdown-ru.html.markdown | 2 +- ru-ru/php-ru.html.markdown | 22 +++++++++++----------- ru-ru/pyqt-ru.html.markdown | 2 +- ru-ru/qt-ru.html.markdown | 2 +- ru-ru/sql-ru.html.markdown | 4 ++-- ru-ru/tmux-ru.html.markdown | 2 +- ru-ru/typescript-ru.html.markdown | 4 ++-- ru-ru/vim-ru.html.markdown | 6 +++--- ru-ru/xml-ru.html.markdown | 2 +- ru-ru/yaml-ru.html.markdown | 10 +++++----- 21 files changed, 66 insertions(+), 66 deletions(-) diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown index 7fd02c47..cb276ec1 100644 --- a/ru-ru/asymptotic-notation-ru.html.markdown +++ b/ru-ru/asymptotic-notation-ru.html.markdown @@ -48,7 +48,7 @@ f(n) — время выполнения. Тогда для данного ал С помощью О-символики можно оценить функцию или алгоритм несколькими различными способами. Например, можно оценить алгоритм исходя из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается -анализ на основе верхней оценки. Как правило не используется нижняя оценка, +анализ на основе верхней оценки. Как правило, не используется нижняя оценка, потому что она не подходит под планируемые условия. Отличный пример — алгоритмы сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка большинства таких алгоритмов может быть дана как одна операция. В то время как в @@ -155,8 +155,8 @@ c (c > 0) и n0 (n0 > 0), такие, что `f(n)` >= `c ### Примечание -Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут -как являться, так и не являться точными. Для того, чтобы обозначить, что границы не +Асимптотические оценки, сделанные при помощи О Большого и Омега Большого, могут +как являться, так и не являться точными. Для того чтобы обозначить, что границы не являются асимптотически точными, используются записи О Малое и Омега Малое. ### О Малое 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 3acfafa3..787d31e8 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 cc68d620..2d06a2d0 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/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/forth-ru.html.markdown b/ru-ru/forth-ru.html.markdown index 2fc4ad7c..90936b19 100644 --- a/ru-ru/forth-ru.html.markdown +++ b/ru-ru/forth-ru.html.markdown @@ -10,7 +10,7 @@ lang: ru-ru Форт создан Чарлзом Муром в 70-е годы. Это императивный, стековый язык программирования и среда исполнения программ. Использовался в таких проектах как Open Firmware. Продолжает применятся в проектах. Применяется в НАСА. -Внимание: эта материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах. +Внимание: этот материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах. ``` 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 / - Существует множество типов фильров (: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..a090ab65 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 -- Однострочные комментарии начинаются с двух дефисов @@ -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..4220902e 100644 --- a/ru-ru/html-ru.html.markdown +++ b/ru-ru/html-ru.html.markdown @@ -25,7 +25,7 @@ HTML расшифровывается как Hypertext Markup Language(гипе В данной статье рассматривается в основном HTML синтаксис и некоторые полезные советы. ```html - + @@ -71,19 +71,19 @@ HTML расшифровывается как Hypertext Markup Language(гипе Мой сайт - - - + + +

Hello, world!

Переходите сюда, чтоб посмотреть как это выглядит. - -

Это параграф.

+ +

Это параграф.

Это другой параграф.