por Juanjo Conti
jjconti@gmail.com - @jjconti
PyDay Litoral 2015
por Juanjo Conti
jjconti@gmail.com - @jjconti
PyDay Litoral 2015
Balada de la primera novia, Alejandro Dolina
(El libro del fantasma)
El poeta Jorge Allen tuvo su primera novia a la edad de doce años. Guarden las personas mayores sus sonrisas condescendientes. Porque en la vida de un hombre hay pocas cosas más serias que su amor inaugural.
Después de una triste fiestita de fin de curso, ya no volvió a verla ni a tener noticias de ella. Sin embargo siguió queriéndola a lo largo de sus años. Jorge Allen se hizo hombre y vivió formidables gestas amorosas. Pero jamas dejo de llorar por la morocha ausente.
PHP: el feo
Ruby: el gemelo malvado
Swift: el nuevo
Clojure: el raro
El feo.
Necesidad de terminar las líneas con ;
No todos los objetos pueden ser representados como strings
Antes de 5.4 no se podía desreferenciar llamadas a funciones
$a[1]()
Extraño una sintaxis simple para rebanar arrays
(y otras operaciones con arrays)
$a = array("a", "b", "c", "d", "e"); array_slice($a, 2); // "c", "d", "e" array_slice($a, -2, 1); // "d" array_slice($a, 0, 3); // "a", "b", "c"
En Python:
a = ["a", "b", "c", "d", "e"] a[2:] # ['c', 'd', 'e'] a[-2:-1] # ['d'] a[:3] # ['a', 'b', 'c'] a[::2] # ['a', 'c', 'e']
Algo parecido pasa con los strings
substr("abcdef", -1); // "f" substr("abcdef", -2); // "ef" substr("abcdef", -3, 1); // "d"
En Python:
"abcdef"[-1:] # 'f' "abcdef"[-2:] # 'ef' "abcdef"[-3:-2] # 'd' "abcdef"[::-2] # 'fdb'
Listas por comprensión
[x*x for x in range(10)]
array_map(function($x) { return $x*$x; }, range(0, 9))
Listas por comprensión
[x*x for x in range(10) if x > 4]
array_filter( array_map(...) )
Python puede hacerte un mejor programador porque el lenguaje es consistente, toma buenas ideas de la programación funcional, es limpio, fácil de leer y tiene un montón de constructores útiles como decoradores, iteradores, y listas por comprensión.
Basado en la charla Ruby para programadores Python de PyConAr 2014.
http://nbviewer.ipython.org/github/jjconti/aprendiendo-ruby/blob/master/RubyDesdePython.ipynb
Todo tiene valor de verdad true excepto false y nil
Los strings son mutables
Arrays, Hashes
Símbolos
Bloques
Cuestiones sintácticas
Todo tiene valor de verdad true excepto false y nil
def que_es obj obj ? "#{obj} es true" : "#{obj} es false" end
que_es [] # "[] es true" que_es 1 # "1 es true" que_es false # "false es false"
s = "Cactus" s[0] = 'KKKK'
"KKKKactus"
Arrays y sus índices
a = [] a[2] = 1
[nil, nil, 1]
a[10] # nil
array = [1, 2, 3, 4, 100] array * 2 [1, 2, 3, 4, 100, 1, 2, 3, 4, 100]
array * '|' "1|2|3|4|100"
[1, [2,3], 4, [[[5]]]] * ',' "1,2,3,4,5"
Recuerdan el orden de inserción.
h = {} h[1] = "a" h[2] = "b" h[3] = "c" h.delete(1) h[1] = "A" h.keys
[2, 3, 1]
Se pueden usar objetos mutables como claves
a = []; h = {a => 2} h.default = 'defecto' a << 1 {[1]=>2}
h[a] # "defecto"
h.rehash; h[a] 2
:simbolo :"Con espacios" "hola".object_id # 70262217568780 "hola".object_id # 70262213790460 :hola.object_id # 1171208 :hola.object_id # 1171208
<expresion> if <condición>
a = 1 if true
api_key = "zzzzzzz" if env.production?
if true puts "no no no no" end if false
El parser ve aunque no ejecute.
q.nil? # NameError q = 1 if q.nil? # 1
if false f = 1 end f.inspect # nil
Parámetros con valores por defecto referenciando parámetros previos.
def parametros a, b=a*2 [a, b] end parametros 10
[10, 20]
Captura genérica de parámetros no necesariamente al final.
def ejemplo(a, *b, c) puts [a, b, c] end ejemplo 1, 2, 3, 4, 5
[1, [2, 3, 4], 5]
Es un lenguaje compilado y de tipado estático, pero tiene inferencia de tipos.
var s = "Hola" var s : String = "Hola"
Permite definir constantes: let
Los enteros tienen límite (en Python no)
Nombres de métodos más largos/dificiles de recordar
upper / uppercaseString
startswith / hasPrefix
Usar listas o diccionarios con distintos tipos de datos puede llevar a complicaciones
Swift tiene bloques como Ruby
Intenta ser un lenguaje seguro, evitando excepciones de punteros nulos
var str = "Hola, PyDay" str = nil // Cannot assign a value of type 'nil' // to a value of type 'String'
var str : String? = "Hola, PyDay"
Referencias a nil?
El signo de pregunta luego del tipo indica que la variable str es un opcional
Su valor puede o no existir
Uso
en un contexto que espere un opcional
explícitamente "unwrapped"
print(str) // Optional("Hola, PyDay") print(str!) // "Hola, PyDay" str + ", Bienvenido" // Value of optional type 'String?' // not unwrapped
str! + ", Bienvenido" str = nil str! + ", Bienvenido" // Error en tiempo de ejecución if str { str! + ", Bienvenido" }
Copiar como no opcional en un scope
if let str = str { str + ", Bienvenido" } if let nombre = persona.nombre_completo { nombre + ", Bienvenido" }
Se puede usar var en lugar de let para hacer una copia mutable
if var producto = producto_sel { producto.baja() print(producto.stock()) }
Una variable declarada como opcional, no se puede asignar a una no declarada como opcional
var n: String = str // produce un error en tiempo // de compilación
Al igual que si se trata de asignar nil a una variable no declarada como opcional
if object.other?.more?.property { // existe la propiedad } else { // NO existe la propiedad }
Más información sobre opcionales en el capítulo Optionals de Swift pocket reference
Funcional.
Todos los valores son inmutables.
(+ 1 1) (conj '(1 2 3) (+ 2 2))
2 '(1 2 3 4)
(defmacro postfix-notation "I'm too indie for prefix notation" [expression] (conj (butlast expression) (last expression))) (postfix-notation (1 1 +)) ; 2 (macroexpand '(postfix-notation (1 1 +))) ; (+ 1 1)
assert_difference("User.count()", 1) do add_user_to_database() end assert_difference("User.count()", 0) do modify_user_on_the_database() end assert_difference("User.count()", -1) do remove_user_from_the_database() end
(assert-difference (users-count) 1 (add-user 'ramon2)) (assert-difference (users-count) 0 (update-user 'ramon)) (assert-difference (users-count) -1 (remove-user 'ramon))
(defmacro assert-difference [form delta & body] `(let [count# ~form] ~@body (is (= (+ count# ~delta) ~form))))
Ruby: http://nbviewer.ipython.org/github/jjconti/aprendiendo-ruby/blob/master/RubyDesdePython.ipynb
Swift: Swift pocket reference y Swift development with Cocoa (O'Reilly)