a side-by-side reference sheet
sheet one:version |grammar and execution |variables and expressions |arithmetic and logic |strings |regexes |dates and time |arrays |dictionaries |functions |execution control |exceptions |threads
sheet two:streams |asynchronous events |files |file formats |directories |processes and environment |option parsing |libraries and namespaces |objects |reflection |net and web |databases |unit tests |debugging
| version | ||||
|---|---|---|---|---|
| node.js | python | php | ruby | |
| version used | 6.11 | 3.6 | 7.0 | 2.3 |
| show version | $ node--version | $ python -V $ python--version | $ php--version | $ ruby--version |
| implicit prologue | // npm install lodash const _ = require('lodash'); | import os, re, sys | # sudo apt install php-mbstring | none |
| grammar and execution | ||||
| node.js | python | php | ruby | |
| interpreter | $ node foo.js | $ python foo.py | $ php -f foo.php | $ ruby foo.rb |
| repl | $ node | $ python | $ php -a | $ irb |
| command line program | $ node -e "console.log('hi!');" | $ python -c 'print("hi!")' | $ php -r 'echo "hi!\n";' | $ ruby -e 'puts "hi!"' |
| block delimiters | {} | :and offside rule | {} | {} do end |
| statement separator | ; or newline newline not separator inside (), [], {}, "", '', or after binary operator newline sometimes not separator when following line would not parse as a valid statement | newline or ; newlines not separators inside (), [], {}, triple quote literals, or after backslash:\ | ; statements must be semicolon terminated inside {} | newline or ; newlines not separators inside (), [], {},``, '', "", or after binary operator or backslash:\ |
| source code encoding | source is always UTF-8 | Python 3 source is UTF-8 by default; Python 2 source is US-ASCII # -*- coding: us-ascii -*- | none | Ruby 2.0 source is UTF-8 by default # -*- coding: utf-8 -*- |
| end-of-line comment | // comment | # comment | // comment # comment | # comment |
| multiple line comment | /* line another line */ | use triple quote string literal: '''comment line another line''' | /* comment line another line */ | =begin comment line another line =end |
| variables and expressions | ||||
| node.js | python | php | ruby | |
| local variable | // new in ES6: let x = 1; let y = 2, z = 3; // older alternative to let: var x = 1; // let local scope is nearest // enclosing block; var local scope // is nearest function body. // var variables are visible to all code // in the function body; even code // preceding the var statement. | # in function body: x = 1 y, z = 2, 3 | # in function body: $x = 1; list($y, $z) = [2, 3]; | x = 1 y, z = 2, 3 |
| file scope variable | // outside any function body: let n = 1; incrFileVar () { n++; } | none | none | none |
| global variable | global.g = 1; incrGlobal () { global.g++; } | g = 1 def incr_global(): global g g += 1 | $g = 1; function incr_global() { global $g; ++$g; } | $g = 1 def incr_global $g += 1 end |
| constant | // new in ES6 const PI = 3.14; | # uppercase identifiers # constant by convention PI = 3.14 | define("PI", 3.14); const PI = 3.14; | # warning if capitalized # identifier is reassigned PI = 3.14 |
| assignment | v = 1; | # assignments can be chained # but otherwise don't return values: v = 1 | $v = 1; | v = 1 |
| parallel assignment | // new in ES6: let [x, y, z] = [1, 2, 3]; | x, y, z = 1, 2, 3 # raises ValueError: x, y = 1, 2, 3 # raises ValueError: x, y, z = 1, 2 | list($x, $y, $z) = [1 ,2, 3]; # 3 is discarded: list($x, $y) = [1, 2, 3]; # $z set to NULL: list($x, $y, $z) = [1, 2]; | x, y, z = 1, 2, 3 # 3 is discarded: x, y = 1, 2, 3 # z set to nil: x, y, z = 1, 2 |
| swap | // new in ES6: [x, y] = [y, x]; | x, y = y, x | list($x, $y) = [$y, $x]; | x, y = y, x |
| compound assignment arithmetic, string, logical, bit | += -= *= /=none %= += none <<= >>= &= |= ^= | # do not return values: += -= *= /=//= %=**= += *= &=|= ^= <<= >>= &= |= ^= | += -= *=none /= %=**= .=none &= |=none <<= >>= &= |= ^= | += -= *= /=none %=**= += *= &&=||= ^= <<= >>= &= |= ^= |
| increment and decrement | let x = 1; let y = ++x; let z =--y; | none | $x = 1; $y = ++$x; $z =--$y; | x = 1 # x and y not mutated: y = x.succ z = y.pred |
| null | null | None | NULL# case insensitive | nil |
| null test | v === null | v is None | is_null($v) ! isset($v) | v == nil v.nil? |
| undefined variable | Evaluates as undefined Use the triple equality ===operator to test for this value. | raises NameError | Evaluates as NULL | raises NameError |
| conditional expression | x > 0 ? x : -x | x if x > 0 else -x | $x > 0 ? $x : -$x | x > 0 ? x : -x |
| arithmetic and logic | ||||
| node.js | python | php | ruby | |
| true and false | true false | True False | TRUE FALSE# case insensitive | true false |
| falsehoods | false null undefined '' 0 NaN | False None 0 0.0 '' [] {} | FALSE NULL 0 0.0 "" "0" [] | false nil |
| logical operators | && || ! | and or not | &&|| ! lower precedence: and or xor | &&|| ! lower precedence: and or not |
| relational operators | === !== < > >= <= perform type coercion: == != | relational operators are chainable: == != > < >= <= | == !=or <> > < >= <= no conversion: === !== | == != > < >= <= |
| min and max | Math.min(1, 2, 3) Math.max(1, 2, 3) Math.min.apply(Math, [1, 2, 3]) Math.max.apply(Math, [1, 2, 3]) | min(1, 2, 3) max(1, 2, 3) min([1, 2, 3]) max([1, 2, 3]) | min(1, 2, 3) max(1, 2, 3) $a = [1, 2, 3] min($a) max($a) | [1, 2, 3].min [1, 2, 3].max |
| arithmetic operators addition, subtraction, multiplication, float division, quotient, remainder | + - * /none % | + - * / // % In Python 2, / performs integer division. | + - * /none % | + - * x.fdiv(y) / % |
| integer division | Math.floor(22 / 7) | 22 // 7 | (int)(22 / 7) | 22 / 7 |
| divmod | none | q, r = divmod(22, 7) | none | q, r = 22.divmod(7) |
| integer division by zero | Returns Infinity, NaN, or -Infinity depending upon sign of dividend. There are literals for Infinity and NaN. | raises ZeroDivisionError | returns FALSEwith warning | raises ZeroDivisionError |
| float division | 22 / 7 | 22 / 7 # Python 2: float(22) / 7 | 22 / 7 | 22.to_f / 7 22.fdiv(7) |
| float division by zero | same behavior as for integers | raises ZeroDivisionError | returns FALSEwith warning | returns -Infinity, NaN,or Infinity |
| power | Math.pow(2, 32) | 2** 32 | pow(2, 32) | 2** 32 |
| sqrt | Math.sqrt(2) | import math math.sqrt(2) | sqrt(2) | include Math sqrt(2) |
| sqrt -1 | NaN | # raises ValueError: import math math.sqrt(-1) # returns complex float: import cmath cmath.sqrt(-1) | NaN | Math.sqrt(-1) raises Math::DomainError unless require 'complex' is in effect. (-1) ** 0.5 is (0+1.0i) |
| transcendental functions | Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | from math import exp, log, \ sin, cos, tan, asin, acos, atan, atan2 | exp log sin cos tan asin acos atan atan2 | include Math exp log sin cos tan asin acos atan atan2 |
| transcendental constants π and e | Math.PI Math.E | import math math.pi math.e | M_PI M_E | include Math PI E |
| float truncation | none Math.round(3.1) Math.floor(3.1) Math.ceil(3.1) | import math int(x) int(round(x)) math.ceil(x) math.floor(x) | (int)$x round($x) ceil($x) floor($x) | x.to_i x.round x.ceil x.floor |
| absolute value | Math.abs(-3) | abs(x) | abs($x) | x.abs |
| integer overflow | all numbers are floats | becomes arbitrary length integer of type long | converted to float | becomes arbitrary length integer of type Bignum |
| float overflow | Infinity | raises OverflowError | INF | Infinity |
| rational construction | none | from fractions import Fraction x = Fraction(22, 7) | none | 22 / 7r 22r / 7 |
| rational decomposition | none | x.numerator x.denominator | none | (22 / 7r).numerator (22 / 7r).denominator |
| complex construction | none | z = 1 + 1.414j | none | z = 1 + 1.414i |
| complex decomposition real and imaginary component, argument, absolute value, conjugate | none | import cmath z.real z.imag cmath.phase(z) abs(z) z.conjugate() | none | (1 + 3i).real (1 + 3i).imag (1 + 3i).arg (1 + 3i).abs (1 + 3i).conj |
| random number uniform integer, uniform float, normal float | Math.floor(Math.random() * 100) Math.random() none | import random random.randint(0, 99) random.random() random.gauss(0, 1) | rand(0,99) lcg_value() none | rand(100) rand none |
| random seed set, get, restore | none | import random random.seed(17) seed = random.getstate() random.setstate(seed) | srand(17); none | srand(17) seed = srand srand(seed) |
| bit operators | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ |
| binary, octal, and hex literals | none 052// deprecated 0x2a | 0b101010 0o52 # also 052 in Python 2 0x2a | 0b101010 052 0x2a | 0b101010 052 0x2a |
| radix convert integer to and from string with radix | (42).toString(7) parseInt('60', 7) | none int('60', 7) | base_convert("42", 10, 7); base_convert("60", 7, 10); | 42.to_s(7) "60".to_i(7) |
| strings | ||||
| node.js | python | php | ruby | |
| string type | String | str # Python 2: unicode | # array of bytes: string | String |
| string literal | 'don\'t say "no"' "don't say \"no\"" | 'don\'t say "no"' "don't say \"no\"" "don't " 'say "no"' # Python 2 (and Python 3): u'lorem' u"ipsum" | "don't say \"no\"" 'don\'t say "no"' | "don't say \"no\"" 'don\'t say "no"' "don't " 'say "no"' |
| newline in literal | // backquote literals only: `first line second line` // Backslashes can be used to break // long strings. | # triple quote literals only: '''first line second line''' """first line second line""" | 'first line second line' "first line second line" | 'first line second line' "first line second line" |
| literal escapes | single and double quotes: \b \f \n \r \t \v \xhh \" \' \\ \uhhhh \u{hhhhh} | \newline \\ \' \" \a \b \f \n \r \t \v \ooo \xhh \uhhhh \Uhhhhhhhh In Python 2, \uand \Uonly available in string literals with uprefix | double quoted: \f \n \r \t \v \xhh \$ \" \\ \ooo single quoted: \' \\ | double quoted: \a \b \cx \e \f \n \r \s \t \v \xhh \ooo \uhhhh \u{hhhhh} single quoted: \' \\ |
| here document | none | none | $word = "amet"; $s =<<<EOF lorem ipsum dolor sit $word EOF; | word = "amet" s =<<EOF lorem ipsum dolor sit #{word} EOF |
| variable interpolation | let count = 3; let item = 'ball'; let s =`${count} ${item}s`; | count = 3 item = 'ball' print('{count} {item}s'.format( **locals())) # Python 3.6: print(f'{count} {item}s') | $count = 3; $item = "ball"; echo "$count ${item}s\n"; | count = 3 item = "ball" puts "#{count} #{item}s" |
| expression interpolation | `1 + 1 = ${1 + 1}` | '1 + 1 = {}'.format(1 + 1) # Python 3.6: f'1 + 1 = {1 + 1}' | none | "1 + 1 = #{1 + 1}" |
| format string | // None; use string concatenation. // Evaluates to "12.35": 12.3456.toFixed(2) | 'lorem %s %d %f' % ('ipsum', 13, 3.7) fmt = 'lorem {0} {1} {2}' fmt.format('ipsum', 13, 3.7) | $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum", 13, 3.7); | "lorem %s %d %f" % ["ipsum", 13, 3.7] |
| are strings mutable? | no | no | $s = "bar"; $s2 = $s; # sets s to "baz"; s2 is unchanged: $s[2] = "z"; | s = "bar" s2 = s # sets s and s2 to "baz": s[2] = "z" |
| copy string | none | none | $s2 = $s; | s = "bar" s2 = s.clone # s2 is not altered: s[2] = "z" |
| concatenate | s = 'Hello, ' + 'World!'; | s = 'Hello, ' s2 = s + 'World!' # juxtaposition can be used to # concatenate literals: s2 = 'Hello, ' "World!" | $s = "Hello, "; $s2 = $s . "World!"; | s = "Hello, " s2 = s + "World!" # juxtaposition can be used to # concatenate literals: s2 = "Hello, " 'World!' |
| replicate | let hbar = _.repeat('-', 80); | hbar = '-' * 80 | $hbar = str_repeat("-", 80); | hbar = "-" * 80 |
| translate case to upper, to lower | 'lorem'.toUpperCase() 'LOREM'.toLowerCase() | 'lorem'.upper() 'LOREM'.lower() | mb_strtoupper("lorem") mb_strtolower("LOREM") # strtoupper/strtolower are ASCII only | "lorem".upcase "LOREM".downcase |
| capitalize string, words | _.capitalize('lorem'); none | import string 'lorem'.capitalize() string.capwords('lorem ipsum') | # ASCII only: ucfirst(strtolower("lorem")) ucwords(strtolower("lorem ipsum")) # Unicode title case: mb_convert_case("lorem ipsum", MB_CASE_TITLE) | "lorem".capitalize none |
| trim both sides, left, right | ' lorem '.trim() ' lorem'.trimLeft() 'lorem '.trimRight() | ' lorem '.strip() ' lorem'.lstrip() 'lorem '.rstrip() | trim(" lorem ") ltrim(" lorem") rtrim("lorem ") | " lorem ".strip " lorem".lstrip "lorem ".rstrip |
| pad on right, on left, centered | _.padStart('lorem', 10) _.padEnd('lorem', 10) _.pad('lorem', 10) | 'lorem'.ljust(10) 'lorem'.rjust(10) 'lorem'.center(10) | $s = "lorem"; $delta = strlen($s) - mb_strlen($s); str_pad($s, 10 + $delta) str_pad("$s, 10 + $delta, " ", STR_PAD_LEFT) str_pad($s, 10 + $delta, " ", STR_PAD_BOTH) | "lorem".ljust(10) "lorem".rjust(10) "lorem".center(10) |
| number to string | 'value: ' + 8 | 'value: ' + str(8) | "value: " . 8 | "value: " + 8.to_s |
| format float | '' + Math.round(Math.PI * 100) / 100 | import math '%.2f' % math.pi '{:.3}'.format(math.pi) # Python 3.6: f'{math.pi:.{3}}' | number_format(M_PI, 2) | include Math '%.2f' % PI "#{PI.round(2)}" |
| string to number | 7 + parseInt('12;, 10) 73.9 + parseFloat('.037') // 12: parseInt('12A') // NaN: parseInt('A') | 7 + int('12') 73.9 + float('.037') # raises ValueError: int('12A') # raises ValueError: int('A') | 7 + "12" 73.9 + ".037" # 12: 0 + "12A" # 0: 0 + "A" | 7 + "12".to_i 73.9 + ".037".to_f # 12: "12A".to_i # 0: "A".to_i |
| string join | ['do', 're', 'mi'].join(' ') | ' '.join(['do', 're', 'mi', 'fa']) # raises TypeError: ' '.join([1, 2, 3]) | $a = ["do", "re", "mi", "fa"]; implode(" ", $a) | %w(do re mi fa).join(' ') # implicitly converted to strings: [1, 2, 3].join(' ') |
| split | // [ 'do', 're', '', 'mi', '' ]: 'do re mi '.split(' ') // [ 'do', 're', 'mi', '' ]: 'do re mi '.split(/\s+/) | # ['do', 're', '', 'mi', '']: 'do re mi '.split(' ') # ['do', 're', 'mi']: 'do re mi '.split() | # [ "do", "re", "", "mi", "" ]: explode(" ", "do re mi ") # [ "do", "re", "mi", "" ]: preg_split('/\s+/', "do re mi ") | # ["do", "re", "", "mi"]: "do re mi ".split(/ /) # ["do", "re", "mi"]: "do re mi ".split |
| split in two | 'do re mi fa'.split(/\s+/, 2) | 'do re mi fa'.split(None, 1) | preg_split('/\s+/', "do re mi fa", 2) | "do re mi fa".split(/\s+/, 2) |
| split and keep delimiters | none | re.split('(\s+)', 'do re mi fa') | preg_split('/(\s+)/', "do re mi fa", NULL, PREG_SPLIT_DELIM_CAPTURE) | "do re mi fa".split(/(\s+)/) |
| prefix and suffix test | 'foobar'.startsWith('foo') 'foobar'.endsWith('bar') | 'foobar'.startswith('foo') 'foobar'.endswith('bar') | 'foobar'.start_with?('foo') 'foobar'.end_with?('bar') | |
| length | 'lorem'.length | len('lorem') | mb_strlen("lorem") # strlen() counts bytes | "lorem".length "lorem".size |
| index of substring first, last | // returns -1 if not found: 'lorem ipsum'.indexOf('ipsum') | # raises ValueError if not found: 'do re re'.index('re') 'do re re'.rindex('re') # returns -1 if not found: 'do re re'.find('re') 'do re re'.rfind('re') | # returns FALSE if not found: mb_strpos("do re re", "re") mb_strrpos("do re re", "re") | # returns nil if not found: "do re re".index("re") "do re re".rindex("re") |
| extract substring by start and length, by start and end, by successive starts | 'lorem ipsum'.substr(6, 5) 'lorem ipsum'.substring(6, 11) | none none 'lorem ipsum'[6:11] | mb_substr("lorem ipsum", 6, 5) none none | "lorem ipsum"[6, 5] "lorem ipsum"[6..10] "lorem ipsum"[6...11] |
| byte array type | Buffer | bytes # In Python 2, str also byte array type | string | Arrayof Fixnum |
| byte array to string | let a = Buffer.from([0xce, 0xbb]); let s = a.toString('utf-8'); | s = b'\xce\xbb'.decode('utf-8') | strings are byte arrays | a = "\u03bb".bytes s = a.pack("C*").force_encoding('utf-8') |
| string to byte array | a = Buffer.from('\u03bb') | a = '\u03bb'.encode('utf-8') # Python 2: a = u'\u03bb'.encode('utf-8') | strings are byte arrays | a = "\u03bb".bytes |
| character lookup | 'lorem ipsum'[6] | 'lorem ipsum'[6] | mb_substr("lorem ipsum", 6, 1) # byte lookup: "lorem ipsum"[6] | "lorem ipsum"[6] |
| chr and ord | String.fromCharCode(65) 'A'.charCodeAt(0) | chr(65) ord('A') | # ASCII only: chr(65) ord("A") | 65.chr('UTF-8') "A".ord |
| to array of characters | 'abcd'.split('') | list('abcd') | str_split("abcd") | "abcd".split("") |
| translate characters | none | from string import ascii_lowercase ins = ascii_lowercase outs = ins[13:] + ins[:13] table = str.maketrans(ins, outs) 'hello'.translate(table) | $ins = implode(range("a", "z")); $outs = substr($ins, 13, 13) . substr($ins, 0, 13); strtr("hello", $ins, $outs) | "hello".tr("a-z", "n-za-m") |
| delete characters | none | table = {ord(ch): None for ch in "aeiou"} "disemvowel me".translate(table) | $vowels = str_split("aeiou"); $s = "disemvowel me"; $s = str_replace($vowels, "", $s); | "disemvowel me".delete("aeiou") |
| squeeze characters | none | re.sub('(\s)+', r'\1', 'too much space') | $s = "too much space"; $s = = preg_replace('/(\s)+/', '\1', $s); | "too much space".squeeze(" ") |
| regular expressions | ||||
| node.js | python | php | ruby | |
| literal, custom delimited literal | /lorem|ipsum/ | re.compile(r'lorem|ipsum') none | '/lorem|ipsum/' '(/etc/hosts)' | /lorem|ipsum/ %r(/etc/hosts) # double quoted string escapes # and #{} substitution can be used |
| ascii character class abbreviations | . [^\n] \d [0-9] \D [^0-9] \s [ \t\r\n\f] \S [^ \t\r\n\f] \w [A-Za-z0-9_] \W [^A-Za-z0-9_] | . [^\n] with re.Smodifier matches all chars \d [0-9] \D [^0-9] \s [ \t\r\n\f] \S [^ \t\r\n\f] \w [A-Za-z0-9_] \W [^A-Za-z0-9_] In Python 3, the above definitions are used when re.Ais in effect. | . [^\n] \d [0-9] \D [^0-9] \h [ \t] \H [^ \t] \s [ \t\r\n\f] \S [^ \t\r\n\f] \w [A-Za-z0-9_] \W [^A-Za-z0-9_] | . [^\n] with mmodifier matches all chars \d [0-9] \D [^0-9] \h [0-9a-fA-F] \H [^0-9a-fA-F] \s [ \t\r\n\f] \S [^ \t\r\n\f] \w [A-Za-z0-9_] \W [^A-Za-z0-9_] |
| unicode character class abbreviations | none | . [^\n] with re.Smodifier matches all chars \d [Nd] Nd:Number, decimal digit \D [^Nd] \s [Z\t\n\r\f\v\x1c\x1d\x1e\x1f\x85] \S [^Z\t\n\r\f\v\x1c\x1d\x1e\x1f\x85] \w [LN_] L:Letter; N:Number \W [^LN_] In Python 2, the above definitions are used when re.Uis in effect. | POSIX character classes such as [[:alpha:]]are available, but they match sets of ASCII characters. General category values (e.g. \p{L}, \p{Lu}) can be used. Morever, they can be used inside character classes (.e.g. [\p{L}\p{N}]). | . \p{Digit} \p{^Digit} \p{Space} \p{^Space} \p{Word} \p{^Word} POSIX character classes (e.g.[[:alpha:]]), general category values (e.g. \p{L}, \p{Lu}), and script names (e.g. \p{Greek})also supported. |
| anchors | ^ start of string or line with mmodifier $ end of string or line with mmodifier \b word boundary: \w\Wor \W\w \B non word boundary | ^ start of string or line with re.M $ end of string or line with re.M \A start of string \b word boundary: \w\Wor \W\w \B non word boundary \Z end of string | ^ start of string or line with mmodifier $ end of string or line with mmodifier \A start of string \b word boundary: \w\Wor \W\w \B non word boundary \z end of string \Z end of string, excluding final newline | ^ start of line $ end of line \A start of string \b unicode-aware word boundary \B unicode-aware non word boundary \z end of string \Z end of string, excluding final newline |
| match test | if (s.match(/1999/)) { console.log('party!'); } | if re.search('1999', s): print('party!') | if (preg_match('/1999/', $s)) { echo "party!\n"; } | if /1999/.match(s) puts "party!" end |
| case insensitive match test | 'Lorem'.match(/lorem/i) | re.search('lorem', 'Lorem', re.I) | preg_match('/lorem/i', "Lorem") | /lorem/i.match("Lorem") |
| modifiers | g used for global substitution and scanning i make case insensitive m change meaning of ^and $ u \u{}syntax and astral character support y used to scan in loop | re.A change meaning of \b \B \d \D \s \S \w \W re.I make case insensitive re.M change meaning of ^and $ re.S change meaning of . re.X ignore whitespace outside char class | i make case insensitive m change meaning of ^and $ s change meaning of . x ignore whitespace outside char class | i make case insensitive o interpolate #{} in literal once m change meaning of . x ignore whitespace outside char class |
| substitution | s = 'do re mi mi mi'; s.replace(/mi/g, 'ma'); | s = 'do re mi mi mi' s = re.compile('mi').sub('ma', s) | $s = "do re mi mi mi"; $s = preg_replace('/mi/', "ma", $s); | s = "do re mi mi mi" s.gsub!(/mi/, "ma") |
| match, prematch, postmatch | m = /\d{4}/.exec(s); if (m) { match = m[0]; // no prematch or postmatch } | m = re.search('\d{4}', s) if m: match = m.group() prematch = s[0:m.start(0)] postmatch = s[m.end(0):len(s)] | none | m = /\d{4}/.match(s) if m match = m[0] prematch = m.pre_match postmatch = m.post_match end |
| group capture | rx = /^(\d{4})-(\d{2})-(\d{2})$/; m = rx.exec('2009-06-03'); yr = m[1]; mo = m[2]; dy = m[3]; | rx = '(\d{4})-(\d{2})-(\d{2})' m = re.search(rx, '2010-06-03') yr, mo, dy = m.groups() | $s = "2010-06-03"; $rx = '/(\d{4})-(\d{2})-(\d{2})/'; preg_match($rx, $s, $m); list($_, $yr, $mo, $dy) = $m; | rx = /(\d{4})-(\d{2})-(\d{2})/ m = rx.match("2010-06-03") yr, mo, dy = m[1..3] |
| named group capture | none | rx = '^(?P<file>.+)\.(?P<suffix>.+)$' m = re.search(rx, 'foo.txt') m.groupdict()['file'] m.groupdict()['suffix'] | $s = "foo.txt"; $rx = '/^(?P<file>.+)\.(?P<suffix>.+)$/'; preg_match($rx, $s, $m); $m["file"] $m["suffix"] | rx = /^(?<file>.+)\.(?<suffix>.+)$/ m = rx.match('foo.txt') m["file"] m["suffix"] |
| scan | let a = 'dolor sit amet'.match(/\w+/g); | s = 'dolor sit amet' a = re.findall('\w+', s) | $s = "dolor sit amet"; preg_match_all('/\w+/', $s, $m); $a = $m[0]; | a = "dolor sit amet".scan(/\w+/) |
| backreference in match and substitution | /(\w+) \1/.exec('do do') 'do re'.replace(/(\w+) (\w+)/, '$2 $1') | none rx = re.compile('(\w+) (\w+)') rx.sub(r'\2 \1', 'do re') | preg_match('/(\w+) \1/', "do do") $s = "do re"; $rx = '/(\w+) (\w+)/'; $s = preg_replace($rx, '\2 \1', $s); | /(\w+) \1/.match("do do") "do re".sub(/(\w+) (\w+)/, '\2 \1') |
| recursive regex | none | none | '/\(([^()]*|($R))\)/' | /(?<foo>\(([^()]*|\g<foo>)*\))/ |
| dates and time | ||||
| node.js | python | php | ruby | |
| broken-down datetime type | Date | datetime.datetime | DateTime | Time |
| current datetime | let t = new Date(); | import datetime t = datetime.datetime.now() utc = datetime.datetime.utcnow() | $t = new DateTime("now"); $utc_tmz = new DateTimeZone("UTC"); $utc = new DateTime("now", $utc_tmz); | t = Time.now utc = Time.now.utc |
| current unix epoch | (new Date()).getTime() / 1000 | import datetime t = datetime.datetime.now() epoch = int(t.strftime("%s")) | $epoch = time(); | epoch = Time.now.to_i |
| broken-down datetime to unix epoch | Math.round(t.getTime() / 1000) | from datetime import datetime as dt epoch = int(t.strftime("%s")) | $epoch = $t->getTimestamp(); | epoch = t.to_i |
| unix epoch to broken-down datetime | let epoch = 1315716177; let t2 = new Date(epoch * 1000); | t = dt.fromtimestamp(1304442000) | $t2 = new DateTime(); $t2->setTimestamp(1304442000); | t = Time.at(1304442000) |
| format datetime | // npm install moment let moment = require('moment'); let t = moment(new Date()); let fmt = 'YYYY-MM-DD HH:mm:ss'; console.log(t.format(fmt)); | t.strftime('%Y-%m-%d %H:%M:%S') | strftime("%Y-%m-%d %H:%M:%S", $epoch); date("Y-m-d H:i:s", $epoch); $t->format("Y-m-d H:i:s"); | t.strftime("%Y-%m-%d %H:%M:%S") |
| parse datetime | // npm install moment let moment = require('moment'); let fmt = 'YYYY-MM-DD HH:mm:ss'; let s = '2011-05-03 10:00:00'; let t = moment(s, fmt); | from datetime import datetime s = '2011-05-03 10:00:00' fmt = '%Y-%m-%d %H:%M:%S' t = datetime.strptime(s, fmt) | $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $t = DateTime::createFromFormat($fmt, $s); | require 'date' s = "2011-05-03 10:00:00" fmt = "%Y-%m-%d %H:%M:%S" t = DateTime.strptime(s, fmt).to_time |
| parse datetime w/o format | let t = new Date('July 7, 1999'); | # pip install python-dateutil import dateutil.parser s = 'July 7, 1999' t = dateutil.parser.parse(s) | $epoch = strtotime("July 7, 1999"); | require 'date' s = "July 7, 1999" t = Date.parse(s).to_time |
| date parts | t.getFullYear() t.getMonth() + 1 t.getDate()// getDay() is day of week | t.year t.month t.day | (int)$t->format("Y") (int)$t->format("m") (int)$t->format("d") | t.year t.month t.day |
| time parts | t.getHours() t.getMinutes() t.getSeconds() | t.hour t.minute t.second | (int)$t->format("H") (int)$t->format("i") (int)$t->format("s") | t.hour t.min t.sec |
| build broken-down datetime | let yr = 1999; let mo = 9; let dy = 10; let hr = 23; let mi = 30; let ss = 0; let t = new Date(yr, mo - 1, dy, hr, mi, ss); | import datetime yr = 1999 mo = 9 dy = 10 hr = 23 mi = 30 ss = 0 t = datetime.datetime(yr, mo, dy, hr, mi, ss) | yr = 1999 mo = 9 dy = 10 hr = 23 mi = 30 ss = 0 t = Time.new(yr, mo, dy, hr, mi, ss) | |
| datetime subtraction | numbercontaining time difference in milliseconds | datetime.timedeltaobject use total_seconds()method to convert to float representing difference in seconds | # DateInterval object if diff method used: $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $then = DateTime::createFromFormat($fmt, $s); $now = new DateTime("now"); $interval = $now->diff($then); | Floatcontaining time difference in seconds |
| add duration | let t1 = new Date(); let delta = (10 * 60 + 3) * 1000; let t2 = new Date(t1.getTime() + delta); | import datetime delta = datetime.timedelta( minutes=10, seconds=3) t = datetime.datetime.now() + delta | $now = new DateTime("now"); $now->add(new DateInterval("PT10M3S"); | require 'date/delta' s = "10 min, 3 s" delta = Date::Delta.parse(s).in_secs t = Time.now + delta |
| local time zone determination | TZ environment variable or host time zone | a datetimeobject has no time zone information unless a tzinfoobject is provided when it is created | # DateTime objects can be instantiated # without specifying the time zone # if a default is set: $s = "America/Los_Angeles"; date_default_timezone_set($s); | if no time zone is specified the local time zone is used |
| nonlocal time zone | # pip install pytz import pytz import datetime tmz = pytz.timezone('Asia/Tokyo') utc = datetime.datetime.utcnow() utc_dt = datetime.datetime( *utc.timetuple()[0:6], tzinfo=pytz.utc) jp_dt = utc_dt.astimezone(tmz) | # gem install tzinfo require 'tzinfo' tmz = TZInfo::Timezone.get("Asia/Tokyo") jp_time = tmz.utc_to_local(Time.now.utc) | ||
| time zone info name and UTC offset | import time tm = time.localtime() time.tzname[tm.tm_isdst] (time.timezone / -3600) + tm.tm_isdst | $tmz = date_timezone_get($t); timezone_name_get($tmz); date_offset_get($t) / 3600; | t.zone t.utc_offset / 3600 | |
| daylight savings test | // npm install moment let moment = require('moment'); moment(new Date()).isDST() | import time tm = time.localtime() tm.tm_isdst | $t->format("I"); | t.dst? |
| microseconds | t.getMilliseconds() * 1000 // [sec, nanosec] since system boot: process.hrtime() | t.microsecond | list($frac, $sec) = explode(" ", microtime()); $usec = $frac * 1000 * 1000; | t.usec |
| arrays | ||||
| node.js | python | php | ruby | |
| literal | a = [1, 2, 3, 4] | a = [1, 2, 3, 4] | $a = [1, 2, 3, 4]; # older syntax: $a = array(1, 2, 3, 4); | a = [1, 2, 3, 4] # a = ['do', 're', 'mi'] a = %w(do re mi) |
| size | a.length | len(a) | count($a) | a.size a.length |
| empty test | // TypeError if a is null or undefined: a.length === 0 | # None tests as empty: not a | # NULL tests as empty: !$a | # NoMethodError if a is nil: a.empty? |
| lookup | a[0] | a[0] # returns last element: a[-1] | $a[0] # PHP uses the same type for arrays and # dictionaries; indices can be negative # integers or strings | a[0] # returns last element: a[-1] |
| update | a[0] = 'lorem' | a[0] = 'lorem' | $a[0] = "lorem"; | a[0] = "lorem" |
| out-of-bounds behavior | returns undefined | a = [] # raises IndexError: a[10] # raises IndexError: a[10] = 'lorem' | $a = []; # evaluates as NULL: $a[10]; # increases array size to one: $a[10] = "lorem"; | a = [] # evaluates as nil: a[10] # increases array size to 11: a[10] = "lorem" |
| element index first and last occurrence | // return -1 if not found: [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) | a = ['x', 'y', 'y', 'z'] # raises ValueError if not found: a.index('y') none | $a = ["x", "y", "y", "z"]; # returns FALSE if not found: $i = array_search("y", $a, TRUE); none | a = %w(x y y z) # return nil if not found: a.index('y') a.rindex('y') |
| slice by endpoints, by length | // select 3rd and 4th elements: ['a', 'b', 'c', 'd'].slice(2, 4) none | # select 3rd and 4th elements: a[2:4] a[2:2 + 2] | # select 3rd and 4th elements: none array_slice($a, 2, 2) | # select 3rd and 4th elements: a[2..3] a[2, 2] |
| slice to end | ['a', 'b', 'c', 'd'].slice(1) | a[1:] | array_slice($a, 1) | a[1..-1] |
| manipulate back | a = [6, 7, 8]; a.push(9); i = a.pop(); | a = [6, 7, 8] a.append(9) a.pop() | $a = [6, 7, 8]; array_push($a, 9); $a[] = 9;# same as array_push array_pop($a); | a = [6, 7, 8] a.push(9) a<< 9# same as push a.pop |
| manipulate front | a = [6, 7, 8]; a.unshift(5); i = a.shift(); | a = [6, 7, 8] a.insert(0, 5) a.pop(0) | $a = [6, 7, 8]; array_unshift($a, 5); array_shift($a); | a = [6, 7, 8] a.unshift(5) a.shift |
| concatenate | a = [1, 2, 3].concat([4, 5, 6]); | a = [1, 2, 3] a2 = a + [4, 5, 6] a.extend([4, 5, 6]) | $a = [1, 2, 3]; $a2 = array_merge($a, [4, 5, 6]); $a = array_merge($a, [4, 5, 6]); | a = [1, 2, 3] a2 = a + [4, 5, 6] a.concat([4, 5, 6]) |
| replicate | Array(10).fill(null) | a = [None] * 10 a = [None for i in range(0, 10)] | $a = array_fill(0, 10, NULL); | a = [nil] * 10 a = Array.new(10, nil) |
| copy address copy, shallow copy, deep copy | a = [1, 2, [3, 4]]; a2 = a; a3 = a.slice(0); a4 = JSON.parse(JSON.stringify(a)); | import copy a = [1,2,[3,4]] a2 = a a3 = list(a) a4 = copy.deepcopy(a) | $a = [1, 2, [3, 4]]; $a2 =& $a; none $a4 = $a; | a = [1,2,[3,4]] a2 = a a3 = a.dup a4 = Marshal.load(Marshal.dump(a)) |
| array as function argument | parameter contains address copy | parameter contains address copy | parameter contains deep copy | parameter contains address copy |
| iterate over elements | [6, 7, 8].forEach((n) => { console.log(n); }); // new in ES6: for (let n of [6, 7, 8]) { console.log(n); } | for i in [1, 2, 3]: print(i) | foreach ([1, 2, 3] as $i) { echo "$i\n"; } | [1, 2, 3].each { |i| puts i } |
| iterate over indices and elements | for (let i = 0; i < a.length; ++i) { console.log(a[i]); } // indices not guaranteed to be in order: for (let i in a) { console.log(a[i]); } | a = ['do', 're', 'mi', 'fa'] for i, s in enumerate(a): print('%s at index %d' % (s, i)) | $a = ["do", "re", "mi" "fa"]; foreach ($a as $i => $s) { echo "$s at index $i\n"; } | a = %w(do re mi fa) a.each_with_index do |s, i| puts "#{s} at index #{i}" end |
| iterate over range | not space efficient; use C-style for loop | # use range() in Python 3: for i in xrange(1, 1000001): code | not space efficient; use C-style for loop | (1..1_000_000).each do |i| code end |
| instantiate range as array | let a = _.range(1, 11); | a = range(1, 11) Python 3: a = list(range(1, 11)) | $a = range(1, 10); | a = (1..10).to_a |
| reverse non-destructive, in-place | let a = [1, 2, 3]; let a2 = a.slice(0).reverse(); a.reverse(); | a = [1, 2, 3] a[::-1] a.reverse() | $a = [1, 2, 3]; array_reverse($a); $a = array_reverse($a); | a = [1, 2, 3] a.reverse a.reverse! |
| sort non-destructive, in-place, custom comparision | let a = [3, 1, 4, 2]; let a2 = a.slice(0).sort(); a.sort(); | a = ['b', 'A', 'a', 'B'] sorted(a) a.sort() # custom binary comparision # removed from Python 3: a.sort(key=str.lower) | $a = ["b", "A", "a", "B"]; none sort($a); none, but usortsorts in place | a = %w(b A a B) a.sort a.sort! a.sort do |x, y| x.downcase <=> y.downcase end |
| dedupe non-destructive, in-place | let a = [1, 2, 2, 3]; let a2 = _.uniq(a); a = _.uniq(a); | a = [1, 2, 2, 3] a2 = list(set(a)) a = list(set(a)) | $a = [1, 2, 2, 3]; $a2 = array_unique($a); $a = array_unique($a); | a = [1, 2, 2, 3] a2 = a.uniq a.uniq! |
| membership | a.includes(7) | 7 in a | in_array(7, $a) | a.include?(7) |
| intersection | _.intersection([1, 2], [2, 3, 4]) | {1, 2} & {2, 3, 4} | $a = [1, 2]; $b = [2, 3, 4] array_intersect($a, $b) | [1, 2] & [2 ,3, 4] |
| union | _.union([1, 2], [2, 3, 4]) | {1, 2} | {2, 3, 4} | $a1 = [1, 2]; $a2 = [2, 3, 4]; array_unique(array_merge($a1, $a2)) | [1, 2] | [2, 3, 4] |
| relative complement, symmetric difference | _.difference([1, 2, 3], [2]) none | {1, 2, 3} - {2} {1, 2} ^ {2, 3, 4} | $a1 = [1, 2, 3]; $a2 = [2]; array_values(array_diff($a1, $a2)) none | require 'set' [1, 2, 3] - [2] Set[1, 2] ^ Set[2 ,3, 4] |
| map | // callback gets 3 args: // value, index, array a.map((x) => x * x) | map(lambda x: x * x, [1, 2, 3]) # or use list comprehension: [x * x for x in [1, 2, 3]] | array_map(function ($x) { return $x * $x; }, [1, 2, 3]) | [1, 2, 3].map { |o| o * o } |
| filter | a.filter((x) => x > 1) | filter(lambda x: x > 1, [1, 2, 3]) # or use list comprehension: [x for x in [1, 2, 3] if x > 1] | array_filter([1, 2, 3], function ($x) { return $x>1; }) | [1, 2, 3].select { |o| o > 1 } |
| reduce | a.reduce((m, o) => m + o, 0) | # import needed in Python 3 only from functools import reduce reduce(lambda x, y: x + y, [1, 2, 3], 0) | array_reduce([1, 2, 3], function($x,$y) { return $x + $y; }, 0) | [1, 2, 3].inject(0) { |m, o| m + o } |
| universal and existential tests | let a = [1, 2, 3, 4]; a.every((n) => n % 2 === 0) a.some((n) => n % 2 === 0) | all(i % 2 == 0 for i in [1, 2, 3, 4]) any(i % 2 == 0 for i in [1, 2, 3, 4]) | use array_filter | [1, 2, 3, 4].all? {|i| i.even? } [1, 2, 3, 4].any? {|i| i.even? } |
| shuffle and sample | let a = [1, 2, 3, 4]; a = _.shuffle(a); let samp = _.sampleSize([1, 2, 3, 4], 2); | from random import shuffle, sample a = [1, 2, 3, 4] shuffle(a) samp = sample([1, 2, 3, 4], 2) | $a = [1, 2, 3, 4]; shuffle($a); $samp = array_rand(|[1, 2, 3, 4], 2); | [1, 2, 3, 4].shuffle! samp = [1, 2, 3, 4].sample(2) |
| flatten one level, completely | let a = [1, [2, [3, 4]]]; let a2 = _.flatten(a); let a3 = _.flattenDeep(a); | none | none | a = [1, [2, [3, 4]]] a2 = a.flatten(1) a3 = a.flatten |
| zip | let a = _.zip([1, 2, 3], ['a', 'b', 'c']); // shorter array padded with undefined: _.zip([1, 2, 3], ['a', 'b']) | list(zip([1, 2, 3], ['a', 'b', 'c'])) # extras in longer array dropped: list(zip([1, 2, 3], ['a', 'b'])) | $a = array_map(NULL, [1, 2, 3], ["a", "b", "c"]); # shorter array padded with NULLs | [1, 2, 3].zip(["a", "b", "c"]) # shorter array padded with nil: [1, 2, 3].zip(["a", "b"]) |
| dictionaries | ||||
| node.js | python | php | ruby | |
| literal | d = {t: 1, f: 0}; // keys do not need to be quoted if they // are a legal JavaScript variable name // and not a reserved word | d = {'t': 1, 'f': 0} | $d = ["t" => 1, "f" => 0]; # older syntax: $d = array("t" => 1, "f" => 0); | d = {'t' => 1, 'f' => 0} # keys are symbols: symbol_to_int = {t: 1, f: 0} |
| size | _.size(d) Object.getOwnPropertyNames(d).length | len(d) | count($d) | d.size d.length |
| lookup | d.hasOwnProperty("t") ? d["t"] : undefined d.hasOwnProperty("t") ? d.t : undefined // JavaScript dictionaries are objects // and inherit properties from Object. | d['t'] | $d["t"] | d['t'] |
| update | d['t'] = 2; d.t = 2; | d['t'] = 2 # provide default to avoid KeyError: d.get('t', None) | $d["t"] = 2; | d['t'] = 2 |
| missing key behavior | let d = {}; // undefined: d["lorem"]; // adds key/value pair: d["lorem"] = "ipsum"; | d = {} # raises KeyError: d['lorem'] # adds key/value pair: d['lorem'] = 'ipsum' | $d = []; # NULL: $d["lorem"]; # adds key/value pair: $d["lorem"] = "ipsum"; | d = {} # nil: d['lorem'] # adds key/value pair: d['lorem'] = 'ipsum' |
| is key present | d.hasOwnProperty("t"); | 'y' in d | array_key_exists("y", $d); | d.key?('y') |
| delete | delete d["t"]; delete d.t; | d = {1: True, 0: False} del d[1] | $d = [1 => "t", 0 => "f"]; unset($d[1]); | d = {1 => true, 0 => false} d.delete(1) |
| from array of pairs, from even length array | let a = [['a', 1], ['b', 2], ['c', 3]]; let d = _.fromPairs(a); none | a = [['a', 1], ['b', 2], ['c', 3]] d = dict(a) a = ['a', 1, 'b', 2, 'c', 3] d = dict(zip(a[::2], a[1::2])) | a = [['a', 1], ['b', 2], ['c', 3]] d = Hash[a] a = ['a', 1, 'b', 2, 'c', 3] d = Hash[*a] | |
| merge | let d1 = {a: 1, b: 2}; let d2 = {b: 3, c: 4}; // d2 overwrites shared keys in d1: d1 = _.assignIn(d1, d2); | d1 = {'a': 1, 'b': 2} d2 = {'b': 3, 'c': 4} d1.update(d2) | $d1 = ["a" => 1, "b" => 2]; $d2 = ["b" => 3, "c" => 4]; $d1 = array_merge($d1, $d2); | d1 = {'a' => 1, 'b' => 2} d2 = {'b' => 3, 'c' => 4} d1.merge!(d2) |
| invert | let let2num = {t: 1, f: 0}; let num2let = _.invert(let2num); | to_num = {'t': 1, 'f': 0} # dict comprehensions added in 2.7: to_let = {v: k for k, v in to_num.items()} | $to_num = ["t" => 1, "f" => 0]; $to_let = array_flip($to_num); | to_num = {'t' => 1, 'f' => 0} to_let = to_num.invert |
| iterate | for (let k in d) { console.log(`value at ${k} is ${d[k]}`); } | for k, v in d.items(): print('value at {} is {}'.format(k, v) # Python 2: use iteritems() | foreach ($d as $k => $v) { echo "value at ${k} is ${v}"; } | d.each do |k,v| puts "value at #{k} is #{v}" end |
| keys and values as arrays | Object.keys(d) _.values(d) | list(d.keys()) list(d.values()) # keys() and values return iterators # in Python 3 and lists in Python 2 | array_keys($d) array_values($d) | d.keys d.values |
| sort by values | let cmp = (a, b) => a[1] - b[1]; let d = {t: 1, f: 0}; for (let p of _.toPairs(d).sort(cmp)) { console.log(p); } | from operator import itemgetter pairs = sorted(d.items(), key=itemgetter(1)) for k, v in pairs: print('{}: {}'.format(k, v)) | asort($d); foreach ($d as $k => $v) { print "$k: $v\n"; } | d.sort_by { |k, v| v }.each do |k, v| puts "#{k}: #{v}" end |
| default value, computed value | none | from collections import defaultdict counts = defaultdict(lambda: 0) counts['foo'] += 1 class Factorial(dict): def__missing__(self, k): if k > 1: return k * self[k-1] else: return 1 factorial = Factorial() | $counts = []; $counts['foo'] += 1; # For computed values and defaults other than # zero or empty string, extend ArrayObject. | counts = Hash.new(0) counts['foo'] += 1 factorial = Hash.new do |h,k| k > 1 ? k * h[k-1] : 1 end |
| functions | ||||
| node.js | python | php | ruby | |
| define | function add3 (x1, x2, x3) { return x1 + x2 + x3; } | def add3(x1, x2, x3): return x1 + x2 + x3 | function add3($x1, $x2, $x3) { return $x1 + $x2 + $x3; } | def add3(x1, x2, x3) x1 + x2 + x3 end # parens are optional and customarily # omitted when defining functions # with no parameters |
| invoke | add3(1, 2, 3) | add3(1, 2, 3) | add3(1, 2, 3); # function names are case insensitive: ADD3(1, 2, 3); | add3(1, 2, 3) # parens are optional: add3 1, 2, 3 |
| missing argument behavior | set to undefined | raises TypeErrorif number of arguments doesn't match function arity | set to NULLwith warning | raises ArgumentErrorif number of arguments doesn't match function arity |
| extra argument behavior | ignored | raises TypeErrorif number of arguments doesn't match function arity | ignored | raises ArgumentErrorif number of arguments doesn't match function arity |
| default argument | // new in ES6: function myLog (x, base = 10) { return Math.log(x) / Math.log(base); } | import math def my_log(x, base=10): return math.log(x) / math.log(base) my_log(42) my_log(42, math.e) | function my_log($x, $base=10) { return log($x) / log($base); } my_log(42); my_log(42, M_E); | def my_log(x, base=10) Math.log(x) / Math.log(base) end my_log(42) my_log(42, Math::E) |
| variadic function | function firstAndLast() { if (arguments.length >= 1) { console.log('first: ' + arguments[0]); } if (arguments.length >= 2) { console.log('last: ' + arguments[1]); } } // ... operator new in ES6: function firstAndLast(...a) { if (a.length >= 1) { console.log('first: ' + a[0]); } if (a.length >= 2) { console.log('last: ' + a[1]); } } | def first_and_last(*a): if len(a) >= 1: print('first: ' + str(a[0])) if len(a) >= 2: print('last: ' + str(a[-1])) | function first_and_last() { $arg_cnt = func_num_args(); if ($arg_cnt >= 1) { $n = func_get_arg(0); echo "first: " . $n . "\n"; } if ($arg_cnt >= 2) { $a = func_get_args(); $n = $a[$arg_cnt-1]; echo "last: " . $n . "\n"; } } | def first_and_last(*a) if a.size >= 1 puts "first: #{a[0]}" end if a.size >= 2 puts "last: #{a[-1]}" end end |
| pass array elements as separate arguments | let a = [1, 2, 3]; let sum = add3(...a); | a = [2, 3] add3(1, *a) # splat operator can only be used once # and must appear after other # unnamed arguments | $a = [1, 2, 3]; call_user_func_array("add3", $a); | a = [2, 3] add3(1, *a) # splat operator can be used multiple # times and can appear before regular # arguments |
| parameter alias | none | none | function first_and_second(&$a) { return [$a[0], $a[1]]; } | none |
| named parameters | none | def fequal(x, y, eps=0.01): return abs(x - y) < eps fequal(1.0, 1.001) fequal(1.0, 1.001, eps=0.1**10) | none | def fequals(x, y, eps: 0.01) (x - y).abs < eps end fequals(1.0, 1.001) fequals(1.0, 1.001, eps: 0.1**10) |
| return value | returnarg or undefined. If invoked with newand returnvalue not an object, returns this. | returnarg or None | returnarg or NULL | returnarg or last expression evaluated |
| multiple return values | function firstAndSecond(a) { return [a[0], a[1]]; } let [x, y] = firstAndSecond([6, 7, 8]); | def first_and_second(a): return a[0], a[1] x, y = first_and_second([6, 7, 8]) | function first_and_second(&$a) { return [$a[0], $a[1]]; } $a = [6, 7, 8]; list($x, $y) = first_and_second($a); | def first_and_second(a) return a[0], a[1] end x, y = first_and_second([6, 7, 8]) |
| anonymous function literal | let square = function (x) { return x * x; }; // => new in ES6: let square = (x) => { return x * x; }; // expression body variant: let square = (x) => x * x; | # body must be an expression: square = lambda x: x * x | $square = function ($x) { return $x * $x; }; | square = lambda { |x| x * x } |
| invoke anonymous function | square(2) ((x) => (x * x)(2) | square(2) (lambda x: x * x)(2) | $square(2) | square.call(2) # alternative syntax: square[2] |
| function as value | let func = add3; | func = add3 | $func = "add3"; | func = lambda { |*args| add3(*args) } |
| function with private state | function counter() { counter.i += 1; return counter.i; } counter.i = 0; console.log(counter()); | # state not private: def counter(): counter.i += 1 return counter.i counter.i = 0 print(counter()) | function counter() { static $i = 0; return ++$i; } echo counter(); | none |
| closure | function makeCounter () { let i = 0; return function () { i += 1; return i; }; } let nays = makeCounter(); console.log(nays()); | def make_counter(): i = 0 def counter(): # new in Python 3: nonlocal i i += 1 return i return counter nays = make_counter() print(nays()) | function make_counter() { $i = 0; return function () use (&$i) { return ++$i; }; } $nays = make_counter(); echo $nays(); | def make_counter i = 0 return lambda { i +=1; i } end nays = make_counter puts nays.call |
| generator | function * makeCounter () { let i = 0; while (true) { yield ++i; } } let nays = makeCounter(); for (let cnt of nays) { console.log(cnt); if (cnt > 100) { break; } } | # cf. itertools library def make_counter(): i = 0 while True: i += 1 yield i nays = make_counter() # Python 2: nays.next() print(next(nays)) for cnt in nays: print(cnt) if cnt > 100: break # Returning without yielding raises # StopIteration exception. | # PHP 5.5: function make_counter() { $i = 0; while (1) { yield ++$i; } } $nays = make_counter(); # does not return a value: $nays->next(); # runs generator if generator has not # yet yielded: echo $nays->current(); | def make_counter return Fiber.new do i = 0 while true i += 1 Fiber.yield i end end end nays = make_counter puts nays.resume |
| decorator | none | def logcall(f): def wrapper(*a, **opts): print('calling ' + f.__name__) f(*a, **opts) print('called ' + f.__name__) return wrapper @logcall def square(x): return x * x | ||
| invoke operator like function | none | import operator operator.mul(3, 7) a = ['foo', 'bar', 'baz'] operator.itemgetter(2)(a) | 3.*(7) a = ['foo', 'bar', 'baz'] a.[](2) | |
| execution control | ||||
| node.js | python | php | ruby | |
| if | if (n === 0) { console.log('no hits'); } else if (n === 1) { console.log('1 hit'); } else { console.log(n + ' hits'); } | if 0 == n: print('no hits') elif 1 == n: print('one hit') else: print(str(n) + ' hits') | if ( 0 == $n ) { echo "no hits\n"; } elseif ( 1 == $n ) { echo "one hit\n"; } else { echo "$n hits\n"; } | if n == 0 puts "no hits" elsif 1 == n puts "one hit" else puts "#{n} hits" end |
| switch | switch (n) { case 0: console.log('no hits\n;); break; case 1: console.log('one hit\n'); break; default: console.log(n + ' hits\n'); } | none | switch ($n) { case 0: echo "no hits\n"; break; case 1: echo "one hit\n"; break; default: echo "$n hits\n"; } | case n when 0 puts "no hits" when 1 puts "one hit" else puts "#{n} hits" end |
| while | while (i < 100) { i += 1; } | while i < 100: i += 1 | while ( $i < 100 ) { $i++; } | while i < 100 do i += 1 end |
| for | for (let i = 0; i < 10; ++i) { console.log(i); } | for i in range(1, 11): print(i) | for ($i = 1; $i <= 10; $i++) { echo "$i\n"; } | none |
| break | for (let i = 30; i < 50; ++i) { if (i % 7 === 0) { console.log('first multiple: ' + i); break; } } | break | break | break |
| continue | for (let i = 30; i < 50; ++i) { if (i % 7 === 0) { continue; } console.log('not divisible: ' + i); } | continue | continue | next |
| statement modifiers | none | none | none | puts "positive" if i > 0 puts "nonzero" unless i == 0 |
| exceptions | ||||
| node.js | python | php | ruby | |
| base exception | Any value can be thrown. | BaseException User-defined exceptions should subclass Exception. In Python 2 old-style classes can be thrown. | Exception | Exception User-defined exceptions should subclass StandardError. |
| predefined exceptions | Error EvalError RangeError ReferenceError SyntaxError TypeError URIError | BaseException Exception TypeError ImportError AssertionError ArithmeticError FloatingPointError OverflowError ZeroDivisionError SyntaxError OSError MemoryError StopIteration Error SystemError ValueError UnicodeError UnicodeEncodeError UnicodeDecodeError UnicodeTranslateError UnsupportedOperation NameError AttributeError RuntimeError LookupError IndexError KeyError EOFError GeneratorExit KeyboardInterrupt SystemExit | Exception LogicException BadFunctionCallException BadMethodCallException DomainException InvalidArgumentException LengthException OutOfRangeException RuntimeException OutOfBoundsException OverflowException RangeException UnderflowException UnexpectedValueException | Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SignalException StandardError ArgumentError IOError EOFError IndexError LocalJumpError NameError RangeError RegexpError RuntimeError SecurityError SocketError SystemCallError Errno::* SystemStackError ThreadError TypeError ZeroDivisionError SystemExit fatal |
| raise exception | throw new Error("bad arg"); | raise Exception('bad arg') | throw new Exception("bad arg"); | # raises RuntimeError raise "bad arg" |
| catch-all handler | try { risky(); } catch (e) { console.log( 'risky failed: ' + e.message); } | try: risky() except: print('risky failed') | try { risky(); } catch (Exception $e) { echo "risky failed: ", $e->getMessage(), "\n"; } | # catches StandardError begin risky rescue print "risky failed: " puts $!.message end |
| re-raise exception | try { throw new Error("bam!"); } catch (e) { console.log('re-raising...'); throw e; } | try: raise Exception('bam!') except: print('re-raising...') raise | begin raise "bam!" rescue puts "re-raising…" raise end # if rescue clause raises different exception, # original exception preserved at e.cause | |
| global variable for last exception | none | last exception: sys.exc_info()[1] | none | last exception: $! backtrace array of exc.: $@ exit status of child: $? |
| define exception | function Bam(msg) { this.message = msg; } Bam.prototype = new Error; | class Bam(Exception): def__init__(self): super(Bam, self).__init__('bam!') | class Bam extends Exception { function__construct() { parent::__construct("bam!"); } } | class Bam < Exception def initialize super("bam!") end end |
| handle exception | try { throw new Bam("bam!"); } catch (e) { if (e instanceof Bam) { console.log(e.message); } else { throw e; } } | try: raise Bam() except Bam as e: print(e) | try { throw new Bam; } catch (Bam $e) { echo $e->getMessage(), "\n"; } | begin raise Bam.new rescue Bam => e puts e.message end |
| finally block | acquireResource(); try { risky(); } finally { releaseResource(); } | acquire_resource() try: risky() finally: release_resource() | PHP 5.5: acquire_resource(); try { risky(); } finally { release_resource(); } | acquire_resource begin risky ensure release_resource end |
| threads | ||||
| node.js | python | php | ruby | |
| start thread | class sleep10(threading.Thread): def run(self): time.sleep(10) thr = sleep10() thr.start() | thr = Thread.new { sleep 10 } | ||
| wait on thread | thr.join() | thr.join | ||
| sleep | import time time.sleep(0.5) | # a float argument will be truncated # to an integer: sleep(1); | sleep(0.5) | |
| timeout | import signal, time class Timeout(Exception): pass def timeout_handler(signo, fm): raise Timeout() signal.signal(signal.SIGALRM, timeout_handler) try: signal.alarm(5) might_take_too_long() except Timeout: pass signal.alarm(0) | use set_time_limitto limit execution time of the entire script; use stream_set_timeoutto limit time spent reading from a stream opened with fopenor fsockopen | require 'timeout' begin Timeout.timeout(5) do might_take_too_long end rescue Timeout::Error end | |
| _____________________________________________________ | _____________________________________________________ | _____________________________________________________ | _____________________________________________________ | |
sheet two:streams |asynchronous events |files |directories |processes and environment |option parsing |libraries and namespaces |objects |inheritance and polymorphism |reflection |net and web |gui |databases |unit tests |logging |debugging
The versions used for testing code in the reference sheet.
How to get the version.
php:
The functionphpversion() will return the version number as a string.
python:
The following function will return the version number as a string:
import platformplatform.python_version()ruby:
Also available in the global constantRUBY_VERSION.
Code which examples in the sheet assume to have already been executed.
#"http://cdnjs.com/libraries/underscore.js">cdnjs hosts underscore.js and other JavaScript libraries for situations where it is inconvenient to have the webserver host the libraries.
When usingunderscore.js with the Node REPL, there is a conflict, since the Node REPL uses the underscore_ variable to store the result of the last evaluation.
$ npm install underscore$ node> var us = require('underscore'); _> us.keys({"one": 1, "two": 2});[ 'one', 'two' ]php:
Thembstring package adds UTF-8 aware string functions withmb_ prefixes.
python:
We assume thatos,re, andsys are always imported.
The customary name of the interpreter and how to invoke it.
php:
php -f will only execute portions of the source file within a <?phpphp code ?> tag as php code. Portions of the source file outside of such tags is not treated as executable code and is echoed to standard out.
If short tags are enabled, then php code can also be placed inside <?php code ?> and <?=php code ?> tags.
<?=php code ?> is identical to <?php echophp code ?>.
The customary name of the repl.
php:
Thephp -a REPL does not save or display the result of an expression.
python:
The python repl saves the result of the last statement in_.
ruby:
irb saves the result of the last statement in_.
How to pass the code to be executed to the interpreter as a command line argument.
How blocks are delimited.
python:
Python blocks begin with a line that ends in a colon. The block ends with the first line that is not indented further than the initial line. Python raises an IndentationError if the statements in the block that are not in a nested block are not all indented the same. Using tabs in Python source code is unrecommended and many editors replace them automatically with spaces. If the Python interpreter encounters a tab, it is treated as 8 spaces.
The python repl switches from a>>> prompt to a … prompt inside a block. A blank line terminates the block.
Colons are also used to separate keys from values in dictionary literals and in sequence slice notation.
ruby:
Curly brackets {} delimit blocks. A matched curly bracket pair can be replaced by thedo andend keywords. By convention curly brackets are used for one line blocks.
Theend keyword also terminates blocks started bydef,class, ormodule.
Curly brackets are also used for hash literals, and the #{ } notation is used to interpolate expressions into strings.
How the parser determines the end of a statement.
php:
Inside braces statements must be terminated by a semicolon. The following causes a parse error:
<? if (true) { echo "true" } ?>The last statement inside<?= ?> or<? ?> tags does not need to be semicolon terminated, however. The following code is legal:
<?= $a = 1 ?><? echo $a ?>python:
Newline does not terminate a statement when:
Python single quote '' and double quote "" strings cannot contain newlines except as the two character escaped form \n. Putting a newline in these strings results in a syntax error. There is however a multi-line string literal which starts and ends with three single quotes ''' or three double quotes: """.
A newline that would normally terminate a statement can be escaped with a backslash.
ruby:
Newline does not terminate a statement when:
Ruby permits newlines in array [] or hash literals, but only after a comma , or associator =>. Putting a newline before the comma or associator results in a syntax error.
A newline that would normally terminate a statement can be escaped with a backslash.
How to identify the character encoding for a source code file.
Setting the source code encoding makes it possible to safely use non-ASCII characters in string literals and regular expression literals.
How to create a comment that ends at the next newline.
How to comment out multiple lines.
python:
The triple single quote ''' and triple double quote """ syntax is a syntax for string literals.
How to declare variables which are local to the scope defining region which immediately contain them.
php:
Variables do not need to be declared and there is no syntax for declaring a local variable. If a variable with no previous reference is accessed, its value isNULL.
python:
A variable is created by assignment if one does not already exist. If the variable is inside a function or method, then its scope is the body of the function or method. Otherwise it is a global.
ruby:
Variables are created by assignment. If the variable does not have a dollar sign ($) or ampersand (@) as its first character then its scope is scope defining region which most immediately contains it.
A lower case name can refer to a local variable or method. If both are defined, the local variable takes precedence. To invoke the method make the receiver explicit: e.g. self.name. However, outside of class and modules local variables hide functions because functions are private methods in the classObject. Assignment toname will create a local variable if one with that name does not exist, even if there is a methodname.
How to define a variable with scope bound by the source file.
How to declare and access a variable with global scope.
php:
A variable is global if it is used at the top level (i.e. outside any function definition) or if it is declared inside a function with theglobal keyword. A function must use theglobal keyword to access the global variable.
python:
A variable is global if it is defined at the top level of a file (i.e. outside any function definition). Although the variable is global, it must be imported individually or be prefixed with the module name prefix to be accessed from another file. To be accessed from inside a function or method it must be declared with theglobal keyword.
ruby:
A variable is global if it starts with a dollar sign: $.
How to declare a constant.
php:
A constant can be declared inside a class:
class Math { const pi = 3.14;}Refer to a class constant like this:
Math::piruby:
Capitalized variables contain constants and class/module names. By convention, constants are all caps and class/module names are camel case. The ruby interpreter does not prevent modification of constants, it only gives a warning. Capitalized variables are globally visible, but a full or relative namespace name must be used to reach them: e.g. Math::PI.
How to assign a value to a variable.
python:
If the variable on the left has not previously been defined in the current scope, then it is created. This may hide a variable in a containing scope.
Assignment does not return a value and cannot be used in an expression. Thus, assignment cannot be used in a conditional test, removing the possibility of using assignment (=) when an equality test (==) was intended. Assignments can nevertheless be chained to assign a value to multiple variables:
a = b = 3ruby:
Assignment operators have right precedence and evaluate to the right argument, so they can be chained. If the variable on the left does not exist, then it is created.
How to assign values to variables in parallel.
python:
The r-value can be a list or tuple:
nums = [1, 2, 3]a, b, c = numsmore_nums = (6, 7, 8)d, e, f = more_numsNested sequences of expression can be assigned to a nested sequences of l-values, provided the nesting matches. This assignment will set a to 1, b to 2, and c to 3:
(a,[b,c]) = [1,(2,3)]This assignment will raise aTypeError:
(a,(b,c)) = ((1,2),3)In Python 3 the splat operator* can be used to collect the remaining right side elements in a list:
x, y, *z = 1, 2 # assigns [] to zx, y, *z = 1, 2, 3 # assigns [3] to zx, y, *z = 1, 2, 3, 4 # assigns [3, 4] to zruby:
The r-value can be an array:
nums = [1, 2, 3]a,b,c = numsHow to swap the values held by two variables.
Compound assignment operators mutate a variable, setting it to the value of an operation which takes the previous value of the variable as an argument.
If<OP> is a binary operator and the language has the compound assignment operator<OP>=, then the following are equivalent:
x <OP>= yx = x <OP> yThe compound assignment operators are displayed in this order:
First row: arithmetic operator assignment: addition, subtraction, multiplication, (float) division, integer division, modulus, and exponentiation.
Second row: string concatenation assignment and string replication assignment
Third row: logical operator assignment: and, or, xor
Fourth row: bit operator assignment: left shift, right shift, and, or, xor.
python:
Python compound assignment operators do not return a value and hence cannot be used in expressions.
The C-style increment and decrement operators can be used to increment or decrement values. They return values and thus can be used in expressions. The prefix versions return the value in the variable after mutation, and the postfix version return the value before mutation.
Incrementing a value two or more times in an expression makes the order of evaluation significant:
x = 1;foo(++x, ++x); // foo(2, 3) or foo(3, 2)?x = 1;y = ++x/++x; // y = 2/3 or y = 3/2?Python avoids the problem by not having an in-expression increment or decrement.
Ruby mostly avoids the problem by providing a non-mutating increment and decrement. However, here is a Ruby expression which is dependent on order of evaluation:
x = 1y = (x += 1)/(x += 1)php:
The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:
$x = 1;$x++;$x--;ruby:
The Integer class definessucc,pred, andnext, which is a synonym forsucc.
The String class definessucc,succ!,next, andnext!.succ! andnext! mutate the string.
The null literal.
How to test if a variable contains null.
php:
$v == NULL does not imply that$v isNULL, since any comparison betweenNULL and a falsehood will return true. In particular, the following comparisons are true:
$v = NULL;if ($v == NULL) { echo "true"; }$v = 0;if ($v == NULL) { echo "sadly true"; }$v = '';if ($v == NULL) { echo "sadly true"; }The result of attempting to access an undefined variable.
python:
Because a class can implement aneq method to change the implementation ofv == None, the expression can beTrue whenv is notNone.
php:
PHP does not provide the programmer with a mechanism to distinguish an undefined variable from a variable which has been set to NULL.
A test showing thatisset is the logical negation ofis_null.
python:
How to test if a variable is defined:
not_defined = Falsetry: vexcept NameError: not_defined = Trueruby:
How to test if a variable is defined:
! defined?(v)How to write a conditional expression. A ternary operator is an operator which takes three arguments. Since
condition ?true value :false value
is the only ternary operator in C, it is unambiguous to refer to it asthe ternary operator.
python:
The Python conditional expression comes from Algol.
ruby:
The Rubyif statement is also an expression:
x = if x > 0 xelse -xendLiterals for the booleans.
These are the return values of the relational operators.
php:
Any identifier which matches TRUE case-insensitive can be used for the TRUE boolean. Similarly for FALSE.
In general, PHP variable names are case-sensitive, but function names are case-insensitive.
When converted to a string for display purposes, TRUE renders as "1" and FALSE as "". The equality testsTRUE == 1 andFALSE == "" evaluate as TRUE but the equality testsTRUE === 1 andFALSE === "" evaluate as FALSE.
Values which behave like the false boolean in a conditional context.
Examples of conditional contexts are the conditional clause of anif statement and the test of awhile loop.
python:
Whether a object evaluates to True or False in a boolean context can be customized by implementing a__nonzero__ (Python 2) or__bool__ (Python 3) instance method for the class.
Logical and, or, and not.
php, ruby:
&& and|| have higher precedence than assignment, compound assignment, and the ternary operator (?:), which have higher precedence thanand andor.
Equality, inequality, greater than, less than, greater than or equal, less than or equal.
php:
Most of the relational operators will convert a string to a number if the other operand is a number. Thus 0 == "0" is true. The operators === and !== do not perform this conversion, so 0 === "0" is false.
python:
Relational operators can be chained. The following expressions evaluate to true:
1 < 2 < 31 == 1 != 2In general ifAi are expressions andopi are relational operators, then
A1 op1 A2 op2 A3 … An opn An+1
is true if and only if each of the following is true
A1 op1 A2
A2 op2 A3
…
An opn An+1
How to get the min and max.
The operators for addition, subtraction, multiplication, float division, integer division, modulus, and exponentiation.
How to get the integer quotient of two integers.
How to get the quotient and remainder with single function call.
What happens when an integer is divided by zero.
How to perform floating point division, even if the operands might be integers.
What happens when a float is divided by zero.
How to get the value of a number raised to a power.
The square root function.
The result of taking the square root of negative one.
Some mathematical functions. Trigonometric functions are in radians unless otherwise noted. Logarithms are natural unless otherwise noted.
python:
Python also hasmath.log10. To compute the log ofx for baseb, use:
math.log(x)/math.log(b)ruby:
Ruby also hasMath.log2,Math.log10. To compute the log ofx for baseb, use
Math.log(x)/Math.log(b)Constants for π and Euler's constant.
How to truncate a float to the nearest integer towards zero; how to round a float to the nearest integer; how to find the nearest integer above a float; how to find the nearest integer below a float; how to take the absolute value.
How to get the absolute value of a number.
What happens when the largest representable integer is exceeded.
What happens when the largest representable float is exceeded.
How to create rational numbers and get the numerator and denominator.
ruby:
Require the librarymathn and integer division will yield rationals instead of truncated integers.
python:
Most of the functions inmath have analogues incmath which will work correctly on complex numbers.
How to generate a random integer between 0 and 99, include, float between zero and one in a uniform distribution, or a float in a normal distribution with mean zero and standard deviation one.
How to set the random seed; how to get the current random seed and later restore it.
All the languages in the sheet set the seed automatically to a value that is difficult to predict. The Ruby MRI interpreter uses the current time and process ID, for example. As a result there is usually no need to set the seed.
Setting the seed to a hardcoded value yields a random but repeatable sequence of numbers. This can be used to ensure that unit tests which cover code using random numbers doesn't intermittently fail.
The seed is global state. If multiple functions are generating random numbers then saving and restoring the seed may be necessary to produce a repeatable sequence.
The bit operators for left shift, right shift, and, inclusive or, exclusive or, and negation.
Binary, octal, and hex integer literals
How to convert integers to strings of digits of a given base. How to convert such strings into integers.
python
Python has the functionsbin,oct, andhex which take an integer and return a string encoding the integer in base 2, 8, and 16.
bin(42)oct(42)hex(42)The type for a string of Unicode characters.
php:
PHP assumes all strings have single byte characters.
python:
In Python 2.7 thestr type assumes single byte characters. A separateunicode type is available for working with Unicode strings.
In Python 3 thestr type supports multibtye characters and theunicode type has been removed.
There is a mutablebytearray type and an immutablebytes type for working with sequences of bytes.
ruby:
TheString type supports multibtye characters. All strings have an explicitEncoding.
The syntax for string literals.
python:
String literals may have au prefix
u'lorem ipsum'u"lorem ipsum"u'''loremipsum'''u"""loremipsum"""In Python 3, these are identical to literals without theu prefix.
In Python 2, these createunicode strings instead ofstr strings. Since the Python 2unicode type corresponds to the Python 3str type, portable code will use theu prefix.
ruby:
How to specify custom delimiters for single and double quoted strings. These can be used to avoid backslash escaping. If the left delimiter is (, [, or { the right delimiter must be ), ], or }, respectively.
s1 = %q(lorem ipsum)s2 = %Q(#{s1} dolor sit amet)Whether newlines are permitted in string literals.
python:
Newlines are not permitted in single quote and double quote string literals. A string can continue onto the following line if the last character on the line is a backslash. In this case, neither the backslash nor the newline are taken to be part of the string.
Triple quote literals, which are string literals terminated by three single quotes or three double quotes, can contain newlines:
'''This istwo lines'''"""This is alsotwo lines"""Backslash escape sequences for inserting special characters into string literals.
| unrecognized backslash escape sequence | ||
|---|---|---|
| double quote | single quote | |
| JavaScript | ||
| PHP | preserve backslash | preserve backslash |
| Python | preserve backslash | preserve backslash |
| Ruby | drop backslash | preserve backslash |
python:
When string literals have anr orR prefix there are no backslash escape sequences and any backslashes thus appear in the created string. The delimiter can be inserted into a string if it is preceded by a backslash, but the backslash is also inserted. It is thus not possible to create a string with anr orR prefix that ends in a backslash. Ther andR prefixes can be used with single or double quotes:
r'C:\Documents and Settings\Admin'r"C:\Windows\System32"The \uhhhh escapes are also available inside Python 2 Unicode literals. Unicode literals have au prefiix:
u'lambda: \u03bb'This syntax is also available in Python 3.3, but not Python 3.2. In Python 3.3 it creates a string of typestr which has the same features as theunicode type of Python 2.7.
Here documents are strings terminated by a custom identifier. They perform variable substitution and honor the same backslash escapes as double quoted strings.
python:
Triple quotes honor the same backslash escape sequences as regular quotes, so triple quotes can otherwise be used like here documents:
s = '''here documentthere computer'''ruby:
Put the customer identifier in single quotes to prevent variable interpolation and backslash escape interpretation:
s = <<'EOF'Ruby code uses #{var} type syntaxto interpolate variables into strings.EOFHow to interpolate variables into strings.
python:
The f'1 + 1 = {1 + 1}' and f"1 + 1 = {1 + 1}" literals, which support variable interpolation and expression interpolation, are new in Python 3.6.
str.format will take named or positional parameters. When used with named parametersstr.format can mimic the variable interpolation feature of the other languages.
A selection of variables in scope can be passed explicitly:
count = 3item = 'ball'print('{count} {item}s'.format( count=count, item=item))Python 3 hasformat_map which accepts adict as an argument:
count = 3item = 'ball'print('{count} {item}s'.format_map(locals()))How to interpolate the result of evaluating an expression into a string.
How to create a string using a printf style format.
python:
The % operator will interpolate arguments into printf-style format strings.
Thestr.format with positional parameters provides an alternative format using curly braces {0}, {1}, … for replacement fields.
The curly braces are escaped by doubling:
'to insert parameter {0} into a format, use {{{0}}}'.format(3)If the replacement fields appear in sequential order and aren't repeated, the numbers can be omitted:
'lorem {} {} {}'.format('ipsum', 13, 3.7)Are strings mutable?
How to copy a string such that changes to the original do not modify the copy.
The string concatenation operator.
The string replication operator.
How to put a string into all caps or all lower case letters.
How to capitalize a string and the words in a string.
The examples lowercase non-initial letters.
php:
How to define a UTF-8 aware version ofucfirst. This version also puts the rest of the string in lowercase:
function mb_ucfirst($string, $encoding = "UTF-8"){ $strlen = mb_strlen($string, $encoding); $firstChar = mb_substr($string, 0, 1, $encoding); $then = mb_substr(mb_strtolower($string), 1, $strlen - 1, $encoding); return mb_strtoupper($firstChar, $encoding) . $then;}ruby:
Rails monkey patches theString class with thetitleize method for capitalizing the words in a string.
How to remove whitespace from the ends of a string.
How to pad the edge of a string with spaces so that it is a prescribed length.
How to convert numeric data to string data.
How to control the number of digits in a float when converting it to a string.
python:
The number after the decimal controls the number of digits after the decimal:
>>> '%.2f' % math.pi'3.14'The number after the decimal controls the total number of digits:
>>> '{:.3}'.format(math.pi)'3.14'How to convert string data to numeric data.
php:
PHP converts a scalar to the desired type automatically and does not raise an error if the string contains non-numeric data. If the start of the string is not numeric, the string evaluates to zero in a numeric context.
python:
float and int raise an error if called on a string and any part of the string is not numeric.
ruby:
to_i and to_f always succeed on a string, returning the numeric value of the digits at the start of the string, or zero if there are no initial digits.
How to concatenate the elements of an array into a string with a separator.
How to split a string containing a separator into an array of substrings.
See alsoscan.
python:
str.split() takes simple strings as delimiters; usere.split() to split on a regular expression:
re.split('\s+', 'do re mi fa')re.split('\s+', 'do re mi fa', 1)How to split a string in two.
#"split-keep-delimiters-note">
How to split a string with the delimiters preserved as separate elements.
How to test whether a string begins or ends with a substring.
How to get the length in characters of a string.
How to find the index of the leftmost occurrence of a substring in a string; how to find the index of the rightmost occurrence.
How to extract a substring from a string by index.
The type for an array of bytes.
How to convert an array of bytes to a string of Unicode characters.
How to convert a string of Unicode characters to an array of bytes.
How to look up the character in a string at an index.
Converting characters to ASCII codes and back.
The languages in this reference sheet do not have character literals, so characters are represented by strings of length one.
How to split a string into an array of single character strings.
How to apply a character mapping to a string.
python:
In Python 2, the string of lowercase letters is instring.lowercase instead ofstring.ascii_lowercase.
In Python 2, themaketrans function is in the modulestring instead ofstr.
How to remove all specified characters from a string; how to remove all but the specified characters from a string.
How to replace multiple adjacent occurrences of a character with a single occurrence.
Regular expressions or regexes are a way of specifying sets of strings. If a string belongs to the set, the string and regex "match". Regexes can also be used to parse strings.
The modern notation for regexes was introduced by Unix command line tools in the 1970s. POSIX standardized the notation into two types: extended regexes and the more archaic basic regexes. Perl regexes are extended regexes augmented by new character class abbreviations and a few other features introduced by the Perl interpreter in the 1990s. All the languages in this sheet use Perl regexes.
Any string that doesn't contain regex metacharacters is a regex which matches itself. The regex metacharacters are:[ ] . | ( ) * + ? { } ^ $ \
character classes: [ ] .
A character class is a set of characters in brackets:[ ]. When used in a regex it matches any character it contains.
Character classes have their own set of metacharacters:^ - \ ]
The^ is only special when it is the first character in the character class. Such a character class matches its complement; that is, any character not inside the brackets. When not the first character the^ refers to itself.
The hyphen is used to specify character ranges: e.g.0-9 orA-Z. When the hyphen is first or last inside the brackets it matches itself.
The backslash can be used to escape the above characters or the terminal character class delimiter:]. It can be used in character class abbreviations or string backslash escapes.
The period. is a character class abbreviation which matches any character except for newline. In all languages the period can be made to match all characters. PHP uses them modifier. Python uses there.M flag. Ruby uses thes modifier.
character class abbreviations:
| abbrev | name | character class |
|---|---|---|
| \d | digit | [0-9] |
| \D | nondigit | [^0-9] |
| \h | PHP: horizontal whitespace character Ruby: hex digit | PHP: [ \t] Ruby: [0-9a-fA-F] |
| \H | PHP: not a horizontal whitespace character Ruby: not a hex digit | PHP: [^ \t] Ruby: [^0-9a-fA-F] |
| \s | whitespace character | [ \t\r\n\f] |
| \S | non whitespace character | [^ \t\r\n\f] |
| \v | vertical whitespace character | [\r\n\f] |
| \V | not a vertical whitespace character | [^\r\n\f] |
| \w | word character | [A-Za-z0-9_] |
| \W | non word character | [^A-Za-z0-9_] |
alternation and grouping: | ( )
The vertical pipe | is used for alternation and parens () for grouping.
A vertical pipe takes as its arguments everything up to the next vertical pipe, enclosing paren, or end of string.
Parentheses control the scope of alternation and the quantifiers described below. They are also used for capturing groups, which are the substrings which matched parenthesized parts of the regular expression. Each language numbers the groups and provides a mechanism for extracting them when a match is made. A parenthesized subexpression can be removed from the groups with this syntax:(?:expr)
quantifiers: * + ? { }
As an argument quantifiers take the preceding regular character, character class, or group. The argument can itself be quantified, so that^a{4}*$ matches strings with the letter a in multiples of 4.
| quantifier | # of occurrences of argument matched |
|---|---|
| * | zero or more, greedy |
| + | one or more, greedy |
| ? | zero or one, greedy |
| {m,n} | m ton, greedy |
| {n} | exactlyn |
| {m,} | m or more, greedy |
| {,n} | zero ton, greedy |
| *? | zero or more, lazy |
| +? | one or more, lazy |
| {m,n}? | m ton, lazy |
| {m,}? | m or more, lazy |
| {,n}? | zero ton, lazy |
When there is a choice, greedy quantifiers will match the maximum possible number of occurrences of the argument. Lazy quantifiers match the minimum possible number.
anchors: ^ $
| anchor | matches |
|---|---|
| ^ | beginning of a string. In Ruby or whenm modifier is used also matches right side of a newline |
| $ | end of a string. In Ruby or whenm modifier is used also matches left side of a newline |
| \A | beginning of the string |
| \b | word boundary. In between a \w and a \W character or in between a \w character and the edge of the string |
| \B | not a word boundary. In between two \w characters or two \W characters |
| \z | end of the string |
| \Z | end of the string unless it is a newline, in which case it matches the left side of the terminal newline |
escaping: \
To match a metacharacter, put a backslash in front of it. To match a backslash use two backslashes.
php:
PHP 5.3 still supports the EREG engine, though the functions which use it are deprecated. These include thesplit function and functions which start withereg. The preferred functions arepreg_split and the other functions with apreg prefix.
The literal for a regular expression; the literal for a regular expression with a custom delimiter.
#"ascii-char-class-abbrev-note">
The supportedcharacter class abbreviations.
Note that\h refers to horizontal whitespace (i.e. a space or tab) in PHP and a hex digit in Ruby. Similarly\H refers to something that isn't horizontal whitespace in PHP and isn't a hex digit in Ruby.
The supported character class abbreviations for sets of Unicode characters.
Each Unicode character belongs to one of these major categories:
| C | Other |
| L | Letter |
| M | Mark |
| N | Number |
| P | Punctuation |
| S | Symbol |
| Z | Separator |
Each major category is subdivided into multiple minor categories. Each minor category has a two letter code, where the first letter is the major category. For example,Nd is "Number, decimal digit".
DownloadUnicodeData.txt to find out which major and minor category and character belongs to.
The supported anchors.
How to test whether a string matches a regular expression.
python:
There.match function returns true only if the regular expression matches the beginning of the string.re.search returns true if the regular expression matches any substring of the of string.
ruby:
match is a method of bothRegexp andString so can match with both
/1999/.match("1999")and
"1999".match(/1999/)When variables are involved it is safer to invoke theRegexp method because string variables are more likely to containnil.
How to perform a case insensitive match test.
Modifiers that can be used to adjust the behavior of a regular expression.
The lists are not comprehensive. For all languages except Ruby there are additional modifiers.
| modifier | behavior | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| e | PHP: when used with preg_replace, the replacement string, after backreferences are substituted, is eval'ed as PHP code and the result is used as the replacement. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| g | #"subst-note">substitutionHow to replace all occurrences of a matching pattern in a string with the provided substitution string. php: The number of occurrences replaced can be controlled with a 4th argument topreg_replace: If no 4th argument is provided, all occurrences are replaced. python: The 3rd argument tosub controls the number of occurrences which are replaced. If there is no 3rd argument, all occurrences are replaced. ruby: Thegsub operator returns a copy of the string with the substitution made, if any. Thegsub! performs the substitution on the original string and returns the modified string. Thesub andsub! operators only replace the first occurrence of the match pattern. match, prematch, postmatchHow to get the substring that matched the regular expression, as well as the part of the string before and after the matching substring. ruby: The special variables$&,$`, and$' also contain the match, prematch, and postmatch. group captureHow to get the substrings which matched the parenthesized parts of a regular expression. ruby: Ruby has syntax for extracting a group from a match in a single expression. The following evaluates to "1999": named group captureHow to get the substrings which matched the parenthesized parts of a regular expression and put them into a dictionary. For reference, we call the(?P<foo>...) notationPython-style and the(?<foo>...) notationPerl-style. php: PHP originally supported Python-style named groups since that was the style that was added to the PCRE regex engine. Perl-style named groups were added to PHP 5.2. python: The Python interpreter was the first to support named groups. scanHow to return all non-overlapping substrings which match a regular expression as an array. backreference in match and substitutionHow to use backreferences in a regex; how to use backreferences in the replacement string of substitution. recursive regexAn examples of a recursive regex. The example matches substrings containing balanced parens. Date and TimeIn ISO 8601 terminology, adate specifies a day in the Gregorian calendar and atime does not contain date information; it merely specifies a time of day. A data type which combines both date and time information is convenient, but ISO 8601 doesn't provide a name for such an entity. PHP, Python, and C# use the compound noundatetime for combined date and time values and we adopt it here as a generic term. An useful property ofISO 8601 dates, times, and datetimes is that they are correctly ordered by a lexical sort on their string representations. This is because they are big-endian (the year is the leftmost element) and they used fixed-length, zero-padded fields with numerical values for each term in the string representation. The C standard library provides two methods for representing dates. The first is theUnix epoch, which is the seconds since the beginning of January 1, 1970 in UTC. If such a time were stored in a 32-bit signed integer, the rollover would happen on January 18, 2038. The Unix epoch is an example of aserial datetime, in which the value is stored as a single numeric value representing the difference in time in some unit from a specially designated datetime called the epoch. Another serial datetime is theWindows file time, which is the number of 100 nanosecond intervals since the beginning of January 1, 1601 UTC. It was introduced when journaling was added to NTFS as part of the Windows 2000 launch. Some serial datetimes use days as the unit. The Excelserial number is the number of days since December 31, 1899. TheJulian day number, used in astronomy, is the number of days since November 24, 4714 BCE in the proleptic Gregorian calendar. Julian days start at noon GMT. Abroken-down datetime uses multiple numeric values to represent the components of a calendar date and time. An example from the C standard library is thetm struct, a definition of which can be found on Unix systems in/usr/include/time.h: The Linux man pages call thetm struct a "broken-down" date and time, whereas the BSD man pages call it a "broken-out" date and time. The first day in the Gregorian calendar was 15 October 1582. Theproleptic Gregorian calendar is an extension of the Gregorian calendar to earlier dates. When such dates are used, they should be called out to be precise. The epoch in the proleptic Gregorian calendar is the year 0001, also written 1 AD or 1 CE. The previous year is the year 0000, also written 1 BC or 1 BCE. The year before that is the year -0001, also written 2 BC or 2 BCE. The ISO 8601 standard recommends that years before 0000 or after 9999 be written with a plus or minus sign prefix. Anordinal date is a broken-down date consisting of a year, followed by the day of the year. The ISO 8601 standard recommends that it be written inYYYY-DDD orYYYYDDD format. The correspondingstrftime formats are%Y-%j and%Y%j. Aweek date is a type of calendar which uses the year, week of the year, and day of the week to refer to to dates. In the ISO 8601 week date, the first week of the year is the week starting from Monday which contains January 4th. An ISO 8601 week date can thus have a different year number than the corresponding Gregorian date. The first week of the year is numbered01, and the first day of the week, Monday, is numbered1. Weeks are written inYYYY-Www-D orYYYYWwwD format, where the upper case W is literal. The correspondingstrftime literals are%G-W%V-%u and%GW%V%u. Common years have 365 days and leap years have 366 days. The extra day in February 29th. Leap years are years divisible by 4 but not 100, or years divisible by 400. In 1967, the definition of a second was changed from 1/86,400 of a solar day to a value expressed in terms of radiation produced by133Cs. Because the length of a solar day is irregular, leap seconds are occasionally used to keep things in sync. This is accomplished by occasionally adding a leap second to the end of June 30th or December 31st. The system also allows for removing the last second of June 30th or December 31st, though as of 2014 this hasn't been done. broken-down datetime typeThe data type used to hold a combined date and time. python: Python uses and exposes thetm struct of the C standard library. Python has a module calledtime which is a thin wrapper to the standard library functions which operate on this struct. Here is how get atm struct in Python: current datetimeHow to get the combined date and time for the present moment in both local time and UTC. current unix epochHow to get the current time as a Unix epoch timestamp. broken-down datetime to unix epochHow to convert a datetime type to the Unix epoch which is the number of seconds since the start of January 1, 1970 UTC. python: The Python datetime object created bynow() andutcnow() has no timezone information associated with it. Thestrftime() method assumes a receiver with no time zone information represents a local time. Thus it is an error to callstrftime() on the return value ofutcnow(). Here are two different ways to get the current Unix epoch. The second way is faster: Replacingnow() withutcnow() in the first way, orutcnow() withnow() in the second way produces an incorrect value. unix epoch to broken-down datetimeHow to convert the Unix epoch to a broken-down datetime. format datetimeHow to format a datetime as a string using using a string of format specifiers. The format specifiers used by thestrftime function from the standard C library and the Unixdate command:
php: PHP supports strftime but it also has its own time formatting system used bydate,DateTime::format, andDateTime::createFromFormat. The letters used in the PHP time formatting system aredescribed here. parse datetimeHow to parse a datetime using the format notation of thestrptime function from the standard C library. parse datetime w/o formatHow to parse a date without providing a format string. date partsHow to get the year, month, and day of month from a datetime. time partsHow to the hour, minute, and second from a datetime. build broken-down datetimeHow to build a broken-down datetime from the date parts and the time parts. datetime subtractionThe data type that results when subtraction is performed on two combined date and time values. add durationHow to add a duration to a datetime. A duration can easily be added to a datetime value when the value is a Unix epoch value. ISO 8601 distinguishes between a time interval, which is defined by two datetime endpoints, and a duration, which is the length of a time interval and can be defined by a unit of time such as '10 minutes'. A time interval can also be defined by date and time representing the start of the interval and a duration. ISO 8601 definesnotation for durations. This notation starts with a 'P' and uses a 'T' to separate the day and larger units from the hour and smaller units. Observing the location relative to the 'T' is important for interpreting the letter 'M', which is used for both months and minutes. local time zone determinationDo datetime values include time zone information. When a datetime value for the local time is created, how the local time zone is determined. On Unix systems processes determine the local time zone by inspecting the binary file/etc/localtime. To examine it from the command line usezdump: On Windows the time zone name is stored in the registry atHKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName. php: The default time zone can also be set in thephp.ini file. Here is the list oftimezones supported by PHP. nonlocal time zoneHow to convert a datetime to the equivalent datetime in an arbitrary time zone. time zone infoHow to get the name of the time zone and the offset in hours from UTC. Timezones are often identified bythree or four letter abbreviations. Many of the abbreviations do not uniquely identify a time zone. Furthermore many of the time zones have been altered in the past. TheOlson database (aka Tz database) decomposes the world into zones in which the local clocks have all been set to the same time since 1970; it gives these zones unique names. ruby: TheTime class has azone method which returns the time zone abbreviation for the object. There is atzinfo gem which can be used to create time zone objects using the Olson database name. This can in turn be used to convert between UTC times and local times which are daylight saving aware. daylight savings testIs a datetime in daylight savings time? microsecondsHow to get the microseconds component of a combined date and time value. The SI abbreviations for milliseconds and microseconds arems andμs, respectively. The C standard library uses the letteru as an abbreviation formicro. Here is a struct defined in/usr/include/sys/time.h: sleepHow to put the process to sleep for a specified number of seconds. In Python and Ruby the default version ofsleep supports a fractional number of seconds. php: PHP providesusleep which takes an argument in microseconds: timeoutHow to cause a process to timeout if it takes too long. Techniques relying on SIGALRM only work on Unix systems. ArraysWhat the languages call their basic container types:
#"array-literal-note"> literalArray literal syntax. ruby: The%w operator splits the following string on whitespace and creates an array of strings from the words. The character following the%w is the string delimiter. If the following character is (, [, or {, then the character which terminates the string must be ), ], or }. The%W operator is like the%w operator, except that double-quote style#{ } expressions will be interpolated. quote wordsThe quote words operator, which is a literal for arrays of strings where each string contains a single word. sizeHow to get the number of elements in an array. empty testHow to test whether an array is empty. lookupHow to access a value in an array by index. python: A negative index refers to thelength - index element. ruby: A negative index refers to to thelength - index element. updateHow to update the value at an index. out-of-bounds behaviorWhat happens when the value at an out-of-bounds index is referenced. element indexHow to get the index of an element in an array. php: Setting the 3rd argument ofarray_search to true makes the search use=== for an equality test. Otherwise the== test is performed, which makes use of implicit type conversions. sliceHow to slice a subarray from an array by specifying a start index and an end index; how to slice a subarray from an array by specifying an offset index and a length index. python: Slices can leave the first or last index unspecified, in which case the first or last index of the sequence is used: Python has notation for taking every nth element: The third argument in the colon-delimited slice argument can be negative, which reverses the order of the result: slice to endHow to slice to the end of an array. The examples take all but the first element of the array. manipulate backHow to add and remove elements from the back or high index end of an array. These operations can be used to use the array as a stack. manipulate frontHow to add and remove elements from the front or low index end of an array. These operations can be used to use the array as a stack. They can be used with the operations that manipulate the back of the array to use the array as a queue. concatenateHow to create an array by concatenating two arrays; how to modify an array by concatenating another array to the end of it. replicateHow to create an array containing the same value replicatedn times. copyHow to make an address copy, a shallow copy, and a deep copy of an array. After an address copy is made, modifications to the copy also modify the original array. After a shallow copy is made, the addition, removal, or replacement of elements in the copy does not modify of the original array. However, if elements in the copy are modified, those elements are also modified in the original array. A deep copy is a recursive copy. The original array is copied and a deep copy is performed on all elements of the array. No change to the contents of the copy will modify the contents of the original array. python: The slice operator can be used to make a shallow copy: list(v) always returns a list, butv[:] returns a value of the same asv. The slice operator can be used in this manner on strings and tuples but there is little incentive to do so since both are immutable. copy.copy can be used to make a shallow copy on types that don't support the slice operator such as a dictionary. Like the slice operatorcopy.copy returns a value with the same type as the argument. array as function argumentHow an array is passed to a function when provided as an argument. iterate over elementsHow to iterate over the elements of an array. iterate over indices and elementsHow to iterate over the element-index pairs. iterate over rangeIterate over a range without instantiating it as a list. instantiate range as arrayHow to convert a range to an array. Python 3 ranges and Ruby ranges implement some of the functionality of arrays without allocating space to hold all the elements. python: In Python 2range() returns a list. In Python 3range() returns an object which implements the immutable sequence API. ruby: The Range class includes the Enumerable module. reverseHow to create a reversed copy of an array, and how to reverse an array in place. python: reversed returns an iterator which can be used in afor/in construct: reversed can be used to create a reversed list: sortHow to create a sorted copy of an array, and how to sort an array in place. Also, how to set the comparison function when sorting. php: usort sorts an array in place and accepts a comparison function as a 2nd argument: python: In Python 2 it is possible to specify a binary comparision function when callingsort: In Python 3 thecmp parameter was removed. One can achieve the same effect by definingcmp method on the class of the list element. dedupeHow to remove extra occurrences of elements from an array. python: Python sets support thelen,in, andfor operators. It may be more efficient to work with the result of the set constructor directly rather than convert it back to a list. membershipHow to test for membership in an array. intersectionHow to compute an intersection. python: Python has literal notation for sets: Useset andlist to convert lists to sets and vice versa: ruby: The intersect operator& always produces an array with no duplicates. unionruby: The union operator| always produces an array with no duplicates. relative complement, symmetric differenceHow to compute the relative complement of two arrays or sets; how to compute the symmetric difference. ruby: If an element is in the right argument, then it will not be in the return value even if it is contained in the left argument multiple times. mapCreate an array by applying a function to each element of a source array. ruby: Themap! method applies the function to the elements of the array in place. collect andcollect! are synonyms formap andmap!. filterCreate an array containing the elements of a source array which match a predicate. ruby: The in place version isselect!. reject returns the complement ofselect.reject! is the in place version. Thepartition method returns two arrays: reduceReturn the result of applying a binary operator to all the elements of the array. python: reduce is not needed to sum a list of numbers: ruby: The code for the reduction step can be provided by name. The name can be a symbol or a string: universal and existential testsHow to test whether a condition holds for all members of an array; how to test whether a condition holds for at least one member of any array. A universal test is always true for an empty array. An existential test is always false for an empty array. A existential test can readily be implemented with a filter. A universal test can also be implemented with a filter, but it is more work: one must set the condition of the filter to the negation of the predicate and test whether the result is empty. shuffle and sampleHow to shuffle an array. How to extract a random sample from an array. php: Thearray_rand function returns a random sample of the indices of an array. The result can easily be converted to a random sample of array values: flattenHow to flatten nested arrays by one level or completely. When nested arrays are flattened by one level, the depth of each element which is not in the top level array is reduced by one. Flattening nested arrays completely leaves no nested arrays. This is equivalent to extracting the leaf nodes of a tree. php, python: To flatten by one level use reduce. Remember to handle the case where an element is not array. To flatten completely write a recursive function. zipHow to interleave arrays. In the case of two arrays the result is an array of pairs or an associative list. DictionariesliteralThe syntax for a dictionary literal. sizeHow to get the number of dictionary keys in a dictionary. lookupHow to lookup a dictionary value using a dictionary key. missing key behaviorWhat happens when a lookup is performed on a key that is not in a dictionary. python: Usedict.get() to avoid handlingKeyError exceptions: is key presentHow to check for the presence of a key in a dictionary without raising an exception. Distinguishes from the case where the key is present but mapped to null or a value which evaluates to false. deleteHow to remove a key/value pair from a dictionary. from array of pairs, from even length arrayHow to create a dictionary from an array of pairs; how to create a dictionary from an even length array. mergeHow to merge the values of two dictionaries. In the examples, if the dictionariesd1 andd2 share keys then the values fromd2 will be used in the merged dictionary. invertHow to turn a dictionary into its inverse. If a key 'foo' is mapped to value 'bar' by a dictionary, then its inverse will map the key 'bar' to the value 'foo'. However, if multiple keys are mapped to the same value in the original dictionary, then some of the keys will be discarded in the inverse. iterationHow to iterate through the key/value pairs in a dictionary. python: In Python 2.7dict.items() returns a list of pairs anddict.iteritems() returns an iterator on the list of pairs. In Python 3dict.items() returns an iterator anddict.iteritems() has been removed. keys and values as arraysHow to convert the keys of a dictionary to an array; how to convert the values of a dictionary to an array. python: In Python 3dict.keys() anddict.values() return read-only views into the dict. The following code illustrates the change in behavior: sort by valuesHow to iterate through the key-value pairs in the order of the values. default value, computed valueHow to create a dictionary with a default value for missing keys; how to compute and store the value on lookup. php: ExtendArrayObject to compute values on lookup: FunctionsPython has both functions and methods. Ruby only has methods: functions defined at the top level are in fact methods on a special main object. Perl subroutines can be invoked with a function syntax or a method syntax. defineHow to define a function. invokeHow to invoke a function. python: Parens are mandatory, even for functions which take no arguments. Omitting the parens returns the function or method as an object. Whitespace can occur between the function name and the following left paren. In Python 3 print is a function instead of a keyword; parens are mandatory around the argument. ruby: Ruby parens are optional. Leaving out the parens results in ambiguity when function invocations are nested. The interpreter resolves the ambiguity by assigning as many arguments as possible to the innermost function invocation, regardless of its actual arity. It is mandatory that the left paren not be separated from the method name by whitespace. apply function to arrayHow to apply a function to an array. perl: Perl passes the elements of arrays as individual arguments. In the following invocation, the functionfoo() does not know which arguments came from which array. For that matter it does not know how many arrays were used in the invocation: If the elements must be kept in their respective arrays the arrays must be passed by reference: When hashes are used as arguments, each key and value becomes its own argument. missing argument behaviorWhat happens when a function is invoked with too few arguments. extra argument behaviorWhat happens when a function is invoked with too many arguments. default argumentHow to declare a default value for an argument. variadic functionHow to write a function which accepts a variable number of argument. python: This function accepts one or more arguments. Invoking it without any arguments raises aTypeError: ruby: This function accepts one or more arguments. Invoking it without any arguments raises anArgumentError: parameter aliasHow to make a parameter an alias of a variable in the caller. named parametersHow to write a function which uses named parameters and how to invoke it. python: The caller can use named parameter syntax at the point of invocation even if the function was defined using positional parameters. The splat operator * collects the remaining arguments into a list. In a function invocation, the splat can be used to expand an array into separate arguments. The double splat operator ** collects named parameters into a dictionary. In a function invocation, the double splat expands a dictionary into named parameters. A double splat operator can be used to force the caller to use named parameter syntax. This method has the disadvantage that spelling errors in the parameter name are not caught: In Python 3 named parameters can be made mandatory: ruby: In Ruby 2.1 named parameters can be made mandatory: return valueHow the return value of a function is determined. multiple return valuesHow to return multiple values from a function. anonymous function literalThe syntax for an anonymous function literal; i.e. a lambda function. python: Python lambdas cannot contain newlines or semicolons, and thus are limited to a single statement or expression. Unlike named functions, the value of the last statement or expression is returned, and areturn is not necessary or permitted. Lambdas are closures and can refer to local variables in scope, even if they are returned from that scope. If a closure function is needed that contains more than one statement, use a nested function: Python closures are read only. A nested function can be returned and hence be invoked outside of its containing function, but it is not visible by its name outside of its containing function. ruby: The following lambda and Proc object behave identically: With respect to control words, Proc objects behave like blocks and lambdas like functions. In particular, when the body of a Proc object contains areturn orbreak statement, it acts like areturn orbreak in the code which invoked the Proc object. Areturn in a lambda merely causes the lambda to exit, and abreak inside a lambda must be inside an appropriate control structure contained with the lambda body. Ruby are alternate syntax for defining lambdas and invoking them: invoke anonymous functionThe syntax for invoking an anonymous function. function as valueHow to store a function in a variable and pass it as an argument. php: If a variable containing a string is used like a function then PHP will look for a function with the name in the string and attempt to invoke it. python: Python function are stored in variables by default. As a result a function and a variable with the same name cannot share the same scope. This is also the reason parens are mandatory when invoking Python functions. function with private stateHow to create a function with private state which persists between function invocations. python: Here is a technique for creating private state which exploits the fact that the expression for a default value is evaluated only once: closureHow to create a first class function with access to the local variables of the local scope in which it was created. python: Python 2 has limited closures: access to local variables in the containing scope is read only and the bodies of anonymous functions must consist of a single expression. Python 3 permits write access to local variables outside the immediate scope when declared withnonlocal. generatorHow to create a function which can yield a value back to its caller and suspend execution. python: A Python generator is a function which returns an iterator. An iterator is an object with two methods:iter(), which returns the iterator itself, andnext(), which returns the next item or raises aStopIteration exception. Python sequences, of which lists are an example, define aniter() for returned an iterator which traverses the sequence. Python iterators can be used infor/in statements and list comprehensions. In the table below,p andq are variables for iterators.
ruby: Ruby generators are called fibers. decoratorA decorator replaces an invocation of one function with another in a way that that is imperceptible to the client. Normally a decorator will add a small amount of functionality to the original function which it invokes. A decorator can modify the arguments before passing them to the original function or modify the return value before returning it to the client. Or it can leave the arguments and return value unmodified but perform a side effect such as logging the call. invoke operator like functionHow to call an operator using the function invocation syntax. This is useful when dealing with an API which accepts a function as an argument. python: Theoperator module provides functions which perform the same operations as the various operators. Using these functions is more efficient than wrapping the operators in lambdas. ruby: All operators can be invoked with method invocation syntax. The binary operator invocation syntax can be regarded as syntactic sugar. Execution ControlifThe conditional branch statement. php: PHP has the following alternate syntax forif statements: ruby: If anif statement is the last statement executed in a function, the return value is the value of the branch that executed. Rubyif statements are expressions. They can be used on the right hand side of assignments: switchA statement which branches based on the value of an expression. whileHow to loop over a block while a condition is true. php: PHP provides ado-while loop. The body of such a loop is guaranteed to execute at least once. ruby: Ruby provides a loop with no exit condition: Ruby also provides theuntil loop. Ruby loops can be used in expression contexts but they always evaluate tonil. forHow to write a C-style for loop. breakAbreak statement exits awhile orfor loop immediately. continueAcontinue statement skips ahead to the next iteration of awhile orfor loop. ruby: There is also aredo statement, which restarts the current iteration of a loop. statement modifiersClauses added to the end of a statement to control execution. Ruby has conditional statement modifiers. Ruby also has looping statement modifiers. ruby: Ruby has the looping statement modifierswhile anduntil: Exceptionsbase exceptionThe base exception type or class that can be used to catch all exceptions. predefined exceptionsA list of the more commonly encountered exceptions. python: Code for inspecting the descendants of a base class: The complete Python 3.5 exception hierarchy: raise exceptionHow to raise exceptions. ruby: Ruby has athrow keyword in addition toraise.throw can have a symbol as an argument, and will not convert a string to a RuntimeError exception. catch-all handlerHow to catch exceptions. php: PHP code must specify a variable name for the caught exception.Exception is the top of the exception hierarchy and will catch all exceptions. Internal PHP functions usually do not throw exceptions. They can be converted to exceptions with this signal handler: ruby: Arescue Exception clause will catch any exception. Arescue clause with no exception type specified will catch exceptions that are subclasses ofStandardError. Exceptions outsideStandardError are usually unrecoverable and hence not handled in code. In arescue clause, theretry keyword will cause thebegin clause to be re-executed. In addition tobegin andrescue, ruby hascatch: re-raise exceptionHow to re-raise an exception preserving the original stack trace. python: If the exception is assigned to a variable in theexcept clause and the variable is used as the argument toraise, then a new stack trace is created. ruby: If the exception is assigned to a variable in therescue clause and the variable is used as the argument toraise, then the original stack trace is preserved. global variable for last exceptionThe global variable name for the last exception raised. define exceptionHow to define a new variable class. handle exceptionHow to catch exceptions of a specific type and assign the exception a name. php: PHP exceptions when caught must always be assigned a variable name. finally blockA block of statements that is guaranteed to be executed even if an exception is thrown or caught. Threadsstart threadruby: Ruby MRI threads are operating system threads, but a global interpreter lock prevents more than one thread from executing Ruby code at a time. wait on threadHow to make a thread wait for another thread to finish. page revision: 5556, last edited:31 Oct 2018 20:50 Powered byWikidot.com Unless otherwise stated, the content of this page is licensed underCreative Commons Attribution-ShareAlike 3.0 License Click here to edit contents of this page. Click here to toggle editing of individual sections of the page (if possible). Watch headings for an "edit" link when available. Append content without editing the whole page source. Check out how this page has evolved in the past. If you want to discuss contents of this page - this is the easiest way to do it. View and manage file attachments for this page. A few useful tools to manage this Site. See pages that link to and include this page. Change the name (also URL address, possibly the category) of the page. View wiki source for this page without editing. View/set parent page (used for creating breadcrumbs and structured layout). Notify administrators if there is objectionable content in this page. Something does not work as expected? Find out what you can do. General Wikidot.com documentation and help section. Wikidot.com Terms of Service - what you can, what you should not etc. Wikidot.com Privacy Policy. [8]ページ先頭 ©2009-2025 Movatter.jp
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||