(https://lh4.googleusercontent.com/59CmO3oTS6gsNQVjKv_55Zf85RJJvnQSEkJ1FRdqOYo=w572-h832-no)
Bienvenidos a la tercera entrega de este taller de python.
Luego de haber visto y estudiado muchos de los elementos básicos y fundamentales que cualquier programador debe conocer para poder hacer algo, hoy comenzaremos a tratar con temas más complejos, lo cual significa más herramientas para trabajar.
¡Comencemos!
FuncionesPor fin llegó el momento de hablar de este asunto tan importante. De a poco vamos viendo nuevas formas de escribir nuestro código de manera más ordenada y eficiente. Las funciones, como podrán imaginar, contribuyen a ello.
Pero, ¿qué son, concretamente, las funciones? No son más que segmentos o bloques de código bajo un nombre específico que cumplen ciertas instrucciones predefinidas, retornando siempre un valor determinado. No se asusten si no entienden nada de esta definición. Ahora veremos bien qué significa todo esto.
No sé si lo habían notado antes pero programar no es muy diferente a escribir un papel con instrucciones. Esos archivos con la extensión .py que estuvimos guardando en las entregas anteriores se asemejan mucho a los papeles que le dejamos a la abuela para saber cómo encender la pc o entrar a una página web. Vamos con un ejemplo para que quede claro.
Supongamos que queremos explicarle a la abuela cómo entrar a su cuenta de correo, a su cuenta del banco y a la página de noticias. Por suerte, nuestra abuela es bastante despierta y ya aprendió cómo encender la pc y abrir el navegador. Para lograr que la nona cumpla con su objetivo debemos ser claros y ordenados al momento de explicar los pasos a seguir.
Primero, analicemos algunos aspectos. Vamos a tener que enseñarle, como mínimo, los siguientes puntos:
- Abrir pestañas nuevas.
- Ingresar a una página por medio de la barra de direcciones.
- Ingresar sus datos para acceder a las páginas que requieran credenciales.
A esto sigue la navegación propia de cada página que no viene al caso.
Como vemos, todos los pasos recién mencionados deberán ser repetidos en cada una de las páginas que mencionamos al principio (y en otras, si decidiéramos añadir más páginas).
Bien, ahora que ya tenemos una idea general de cuáles son los pasos necesarios para que la abuela ingrese a sus páginas sin inconvenientes, hagamos una lista con las instrucciones:
Ingresar a cuenta de correo:
1.- Identificar y clickear la barra de direcciones.
2.- Escribir "correo.com" y presionar la tecla "Enter".
3.- Identificar formulario de usuario y escribir "usuario".
4.- Identificar formulario de contraseña y escribir "contraseña".
5.- Identificar botón con la etiqueta "Iniciar sesión" y clickearlo.
Ingresar a cuenta del banco:
1.- Identificar sector de pestañas.
2.- Clickear última pestaña (la que se encuentra vacía o con el signo +).
3.- Identificar y clickear la barra de direcciones.
4.- Escribir "banco.com" y presionar la tecla "Enter".
5.- Identificar formulario de usuario y escribir "usuario".
6.- Identificar formulario de contraseña y escribir "contraseña".
7.- Identificar botón con la etiqueta "Iniciar sesión" y clickearlo.
Ingresar a página de noticias:
1.- Identificar sector de pestañas.
2.- Clickear última pestaña (la que se encuentra vacía o con el signo +).
3.- Identificar y clickear la barra de direcciones.
4.- Escribir "noticias.com" y presionar la tecla "Enter".
¡Muy bien! ¡Hemos hecho un excelente trabajo! Ahora nuestra abuela podrá ingresar a estas tres páginas sin ningún tipo de inconveniente. De todas formas, hay algo que no cierra...
Seguro que alguno de ustedes se ha dado cuenta que hemos repetido unas cuantas instrucciones. No importa ahora, sólo lo hemos hecho unas dos o tres veces. No es mucho. Pero, ¿qué sucedería si tuviéramos que hacer lo mismo con otras páginas? Imagínense el tiempo que perderíamos sólo escribiendo lo mismo una y otra vez. Realmente sería mucho trabajo de más.
Entonces, ¿cómo podemos solucionar esta gran problemática? Probemos reemplazando las notas anteriores por las que siguen:
Abrir nueva pestaña:
1.- Identificar sector de pestañas.
2.- Clickear última pestaña (se encuentra vacía o con el signo +).
Ingresar a página (nombre de página):
1.- Identificar y clickear la barra de direcciones.
2.- Escribir nombre de página y presionar la tecla "Enter".
Ingresar credenciales (usuario, contraseña):
1.- Identificar formulario de usuario y escribir usuario.
2.- Identificar formulario de contraseña y escribir contraseña.
3.- Identificar botón con la etiqueta "Iniciar sesión" y clickearlo.
Perfecto! Ahora sí nuestras notas son 100% funcionales. Lo que hicimos fue crear una acción o función por cada nota. Entonces, finalmente nos quedan tres notas: una para explicar cómo abrir una pestaña, otra para ingresar a una página (sirve para cualquier página, siempre y cuando se conozca su dirección) y, finalmente, una última nota para ingresar credenciales (sirve para cualquier página, siempre y cuando se conozcan el usuario y la contraseña). ¿Se entiende lo que hicimos?
Resumo un poco para los que todavía están en el aire. Al principio hicimos una nota para cada página a la que la abuela quería ingresar.
1 Nota = 1 Página
Por cada nota que hicimos tuvimos que desarrollar al menos 2 de los 3 puntos mencionados al comienzo (abrir pestañas, ingresar a la página e ingresar credenciales). Eso nos llevó a repetir instrucciones y, lo que es peor, a tener que volver a repetirlas en caso de querer hacer otra nota.
Para resolver ese problema, lo que hicimos fue crear notas que expliquen los 3 posibles pasos que debemos seguir en cualquier página, es decir, cada nota termina representando una función.
1 Nota = 1 Función
Entonces, nos quedaron 3 notas: una para abrir pestañas, otra para ingresar a una página y una última para ingresar credenciales. De esto surgen varias ventajas:
- No repetimos instrucciones
- Podemos aplicarlo a un número indefinido de páginas
- Es más ordenado
- Si tuviéramos que modificar alguna instrucción por cualquier razón, sólo lo haríamos en la nota correspondiente.
Este último punto es uno de los más importantes. Imagínense, por ejemplo, si repentinamente se cambiara el sistema de ingreso de credenciales por uno más seguro, que requiera acceso por reconocimiento de voz. En el primer sistema de notas (una nota = una página), estaríamos obligados a modificar esas instrucciones en cada una de las notas que tengamos hechas; si tuviéramos 100 páginas (100 notas) deberíamos modificarlas a todas. Qué trabajo, ¿no?
Gracias a nuestro segundo sistema, en cambio, podemos resolverlo fácilmente: buscamos la nota correspondiente al ingreso de credenciales y modificamos las instrucciones necesarias. Es decir, sólo debemos modificar una nota, y listo. Con esto ya podemos ingresar nuestras credenciales de forma correcta en cualquier página que lo solicite.
Características de las funcionesCuando hablamos de funciones debemos distinguir dos aspectos fundamentales que pueden confundir un poco al principio: la definición y la llamada o invocación de la función.
Definición de una funciónDe forma genérica, podemos decir que las definiciones son fundamentales para establecer con claridad y exactitud la naturaleza de una entidad cualquiera.
La programación no es la excepción. Cada elemento integrante de un lenguaje debe ser definido de forma precisa de manera tal que podamos identificarlo y distinguirlo de las demás entidades del lenguaje.
Al definir una función, lo que hacemos es determinar con exactitud cada uno de los siguientes aspectos:
- Nombre de la función.
- Información que podremos brindarle a la función (son los llamados parámetros).
- Conjunto de instrucciones que se ejecutarán al llamar a la función.
- Valor a retornar (ya lo explicaremos).
La palabra clave para indicar que estamos por definir una función es def.
Veamos, de forma abstracta, cómo debemos definir una función:
(https://lh3.googleusercontent.com/-A6HzeEe3aAU/VDng_MlFs9I/AAAAAAAACbA/Et8_N1aAgwQ/w300-h66-no/1.png)
Analicemos la imagen. En la primera línea encontramos cuatro cosas:
- La palabra clave def.
- El nombre de la función (esta se llama "nombre").
- Entre paréntesis indicamos los parámetros.
- Como con toda estructura de control, finalizamos con dos puntos ( : ).
Las siguientes líneas corresponden al bloque de código que se ejecutará cada vez que llamemos a la función. El bloque de código se encuentra indentado y se compone de una o más instrucciones.
La indentación, a diferencia de muchos lenguajes, representa en python no sólo un tipo de notación para mejorar la legibilidad del código sino que, además, sirve al intérprete para saber dónde comienza y dónde termina cada uno de los bloques de código. Es decir, permite establecer y entender la estructura del programa.
La indentación puede realizarse con espacios o tabuladores pero nunca con ambos. De combinarse los dos anteriores, nuestro intérprete nos informará que existe un error de indentación:
(https://lh6.googleusercontent.com/-xLoI__sE-SA/VDnhEBfBaVI/AAAAAAAACcQ/ATSgZY6Cay0/w337-h41-no/2.png)
De todas formas, si bien cada programador tiene su propio estilo, por convención, la indentación debería realizarse con cuatro espacios, tal y como lo indica uno de los doce mandamientos de python:
"Indenta con cuatro espacios por nivel.
Sin tabuladores.
Si rompes este mandamiento serás lapidado en la plaza del pueblo."
Llamada a una funciónLas llamadas a función no son más que las funciones en acción, es decir, si yo tengo una función determinada, ésta no se ejecutará hasta que yo la llame.
Si prestamos atención, esto nos da una enorme ventaja al momento de programar. Si tenemos un bloque de código de varias líneas que se necesitamos ejecutar en varias ocasiones, lo que hacemos es convertirlo en función y sólo empleamos una línea por cada ejecución: la correspondiente a la llamada. Como ven, el resultado es un código muchísimo más pequeño y ordenado.
Hagamos un sencillo ejemplo. Vamos a definir dos funciones: "limpiar" y "ensuciar". Ambas van a trabajar sobre una misma variable llamada "pisoLimpio" la cual puede almacenar uno de los dos valores booleanos True y False.
(https://lh6.googleusercontent.com/-VKMnfNiyNsw/VDnhIkpT50I/AAAAAAAACdw/3vN6Bfn2m7c/w309-h275-no/3.png)
Si analizamos el código, vemos que definimos dos funciones e hicimos dos llamadas, ¿no? Sin embargo, sólo una de ellas se va a ejecutar. Miren el código, analícenlo e intenten responder cuál de ellas será. En el próximo párrafo explicamos la solución.
Muy bien, primero aclaremos algunos puntos y luego veremos que la respuesta viene sola:
- Las funciones "limpiar" y "ensuciar" modifican el valor de la variable pisoLimpio.
- La variable pisoLimpio es inicializada con el valor None. A esta altura, ya sabemos que None es, en términos booleanos, falso. Por lo tanto, podemos afirmar que, inicialmente, el piso se encuentra sucio.
- Si analizamos el bloque if – else y lo traducimos al español, nos quedaría algo así: "Si el piso no está limpio, entonces llamemos a la función limpiar. De lo contrario (si está limpio), llamemos a la función ensuciar".
Ahora sí. Sabiendo lo antedicho, estamos en condiciones de practicar el recorrido mismo realizado por el intérprete: ya que el piso no está limpio, entonces llamemos a la función "limpiar". Fácil, ¿no?
Ahora que ya vimos, en términos generales, cómo definir una función y cómo llamarlas, profundicemos un poco en cada uno de sus aspectos.
Desentrañando las funcionesVolvamos un poco atrás y veamos más a fondo el tema de las definiciones.
Ya vimos que al definir una función nos encontramos con varios elementos. Ya los nombramos y sabemos cómo utilizarlos pero eso no es todo. Veamos cuánto jugo podemos sacarle a cada uno de ellos y avancemos a otro nivel.
¡Comencemos!1. Nombre. Podemos nombrar o rotular a una función como se nos ocurra, siempre y cuando no sea una palabra clave de python (para más información: https://docs.python.org/2/reference/lexical_analysis.html#keywords) y utilicen los caracteres válidos para los identificadores: las mayúsculas y minúsculas de la A a la Z, el guion bajo y, a excepción del primer carácter, los dígitos del 0 al9.
2. Parámetros. Un parámetro es una variable que puede ser recibidapor una subrutina.
Se denomina subrutina o procedimiento a un segmento de código separado del bloque principal y que puede ser invocado en cualquier momento desde éste o desde otra subrutina.
La subrutina (en nuestro caso la función) utiliza los argumentos para alterar su comportamiento en tiempo en ejecución.
Habrán notado que primero dije parámetros y, luego, argumentos. Si bien se utilizan muchas veces como sinónimos, debemos saber que no son lo mismo. Un parámetro representa un valor que el procedimiento espera que se transfiera cuando es llamado. Un argumento representa el valor que se transfiere a un parámetro del procedimiento cuando se llama al procedimiento.
(https://lh5.googleusercontent.com/-xTifVePp9tA/VDnhK8QXpiI/AAAAAAAACd8/uSQhZEdxOWQ/w337-h256-no/4.png)
Las comillas triples se utilizan en este caso como cadena de documentación, cuya función es explicar qué hace la función. Su uso no es obligatorio pero sí se considera buena práctica. En python, además, la cadena de documentación se encuentra disponible en tiempo de ejecución como atributo de la función. En caso de emplearse, debe ser lo primero que se define en la función.
Volviendo a los parámetros, y como dijimos en la definición, éstos no son obligatorios, quedando su uso determinado por nuestras necesidades al crear una función.
(https://lh6.googleusercontent.com/-6kLChesFSYY/VDnhMpUYIAI/AAAAAAAACeE/WwNMgjSnVbI/w337-h125-no/5.png)
Al ser python un lenguaje de tipado dinámico, no debemos preocuparnos por indicar en la definición el tipo de dato que almacenarán los parámetros. Es el mismo intérprete quien se encarga de verificar esto durante la llamada a la función.
(https://lh5.googleusercontent.com/-sHSmk3aPyyk/VDnhNeLaSAI/AAAAAAAACeQ/G03C0Gjhcvk/w337-h251-no/6.png)
En caso de que debamos emplear más de un parámetro en nuestra función, debemos utilizar las comas(,) para separarlos.
(https://lh5.googleusercontent.com/-7kWnuA_jEnM/VDnhN8rVXvI/AAAAAAAACeY/iGgyOBQ-4Vw/w337-h113-no/7.png)
Ahora, ¿qué sucedería si al momento de pasar los argumentos alteramos el orden? Veamos:
(https://lh6.googleusercontent.com/-JWUxqZ5Wnak/VDnhOCK6KvI/AAAAAAAACec/3FJZs9g179I/w337-h125-no/8.png)
La salida sería la siguiente:
(https://lh6.googleusercontent.com/-Q2YDhGsAEyo/VDnhOnvp1jI/AAAAAAAACek/aE6PN6olyKg/w337-h69-no/9.png)
Con esto comprobamos que esta forma de recibir múltiples parámetros está bien, siempre y cuando sepamos que el orden de los argumentos sea el correcto. De lo contrario, deberemos buscar una forma de imprimir bien la información, a pesar de que se altere el orden de los argumentos.
Para eso podemos utilizar las llamadas keywords y pasar argumentos como pares de clave=valor.
Veamos un ejemplo para que se entienda lo antedicho.
(https://lh6.googleusercontent.com/-cEFxQosHf0o/VDng_cdvVlI/AAAAAAAACbI/YGUz5SfrznE/w337-h114-no/10.png)
Otra de las características de los parámetros en python es que podemos asignarles un valor por defecto (parámetros por omisión). Esto nos sirve mucho para manejar correctamente aquellos casos en los que no se nos pasen los argumentos requeridos por la función.
(https://lh4.googleusercontent.com/-ROAxp98xHfo/VDng__TtuVI/AAAAAAAACbM/VWJc8ht_zYI/w337-h112-no/11.png)
Ahora, ¿qué sucedería si, al momento de definir la función, no supiéramos cuántos argumentos recibirá nuestra función en tiempo de ejecución?
Esto se resuelve con los denominados parámetros arbitrarios. Gracias a esta característica, todos los argumentos recibidos llegarán a la función en forma de tupla.
(https://lh3.googleusercontent.com/-ROFPuOfrctM/VDnhAfWxG_I/AAAAAAAACbU/tmc6y3Es6ic/w337-h182-no/12.png)
Los parámetros arbitrarios suceden siempre a los fijos y para indicar su uso se utiliza un asterisco(*) inmediatamente antes del nombre que le demos al parámetro.
Veamos a nuestra función en acción:
(https://lh5.googleusercontent.com/-GpK2q_ZANbE/VDnhA0pd87I/AAAAAAAACbc/78M2gnFYXlA/w337-h146-no/13.png)
Pero esto no es todo. Los argumentos arbitrarios, al igual que los fijos, también se pueden pasar en forma de keywords. Para ello, debemos utilizar dos asteriscos (**) delante del nombre del parámetro. Modifiquemos la función del ejemplo anterior para ejemplificar.
(https://lh3.googleusercontent.com/-oEiEMKAUf6Q/VDnhBvd1S0I/AAAAAAAACbo/i2K-I3u6gDQ/w337-h262-no/14.png)
Ahora veamos los resultados:
(https://lh4.googleusercontent.com/-QcR6hx5McRA/VDnhB_eSunI/AAAAAAAACbs/wjxJuS80iac/w337-h218-no/15.png)
Se podría decir que lo que hemos estado haciendo hasta ahora es empaquetar varios argumentos en uno solo: varios argumentos comunes en una tupla y varios de tipo clave en un diccionario.
Python nos permite realizar el paso inverso, es decir, una descomposición de un argumento en varios, en caso de ser necesario (desempaquetado de datos).
Al igual que en los casos anteriores, esto se aplica tanto para los argumentos comunes como para los de tipo clave y la metodología es similar: agregando uno o dos asteriscos, respectivamente, al argumento que vayamos a desempaquetar.
Volvamos a la función "imprimirDatosPersonales" para entenderlo.
(https://lh6.googleusercontent.com/-rR9Rh6E0tJc/VDnhDEA31NI/AAAAAAAACb4/brNtg-CH0pE/w337-h115-no/16.png)
Ahora veamos qué sucede al pasar como argumento la variable datos:
(https://lh5.googleusercontent.com/-kBwDV9iRtzE/VDnhDcfjZpI/AAAAAAAACb8/uhyxEthYqU0/w288-h82-no/17.png)
¡Perfecto! Como vemos, funcionó a la perfección. Lo único que tuvimos que hacer fue agregar un asterisco al argumento datos.
Para seguir con el ejemplo, intentemos ahora pasar los datos en forma de clave. Para eso nos armaremos un diccionario con los pares clave: valor.
(https://lh5.googleusercontent.com/-dTKMTTcwAIo/VDnhD1LaCTI/AAAAAAAACcM/3dYxv-_DLY4/w337-h138-no/18.png)
Ahora pasemos la variable datos con dos asteriscos y veamos qué sucede.
(https://lh3.googleusercontent.com/-UAOtbLRHjyY/VDnhEJBYDLI/AAAAAAAACcc/uZp6LtD-A6c/w298-h85-no/19.png)
Tal como esperábamos, pudimos desempaquetar los argumentos sin ningún tipo de inconveniente. Una vez más, python nos demuestra su inmenso poder.
Retorno de datosComo dijimos anteriormente, las funciones devuelven siempre, y como mínimo, un valor determinado.
En caso de no especificarse nada, el valor de retorno es None.
(https://lh6.googleusercontent.com/-o0r_04SEz6s/VDnhE-NH6XI/AAAAAAAACc4/1mpe9bp0KJ0/w291-h111-no/20.png)
Lo expuesto en la cadena de documentación podemos comprobarlo de la siguiente manera:
(https://lh5.googleusercontent.com/-9D9KDh5sXeA/VDnhEyMFvdI/AAAAAAAACck/ul-mV9h4AKo/w299-h84-no/21.png)
Para los que no entendieron nada de lo que pasó, aquí va la explicación: la función "retornarValor" devuelve, con cada ejecución, un valor None. Aprovechando esto, lo que hicimos fue asignar ese valor a la variable "valorRetornado". Es como decir: "Al valor retornado por la función retornarValor guardémoslo en la variable valorRetornado para luego imprimirlo en pantalla".
Podríamos conformarnos con lo anterior pero, siendo que estamos en un taller de python, sabemos que estamos lejos de decir basta. Python nos permite retornar cualquier tipo de dato, y no sólo eso, sino que, de hecho, pueden ser múltiples si queremos.
La manera explícita para hacer que una función retorne un dato específico es por medio de la sentencia return.
Al emplearla, la función terminará su ejecución, devolviendo el valor que le indiquemos.
(https://lh5.googleusercontent.com/-KMIgJY4dlD0/VDnhFHclOmI/AAAAAAAACcw/L6FB-gG_Z_4/w300-h156-no/22.png)
(https://lh3.googleusercontent.com/-jTMpyZXEy4Q/VDnhFsCKB7I/AAAAAAAACdA/CLvr1eWiflg/w337-h85-no/23.png)
Para retornar varios valores debemos hacerlo separándolos por medio de comas (,). A dichos valores los podemos recibir de dos maneras: por medio de una única variable o con tantas variables como valores a retornar existan.
Volvamos al ejemplo de los datos personales para ver cómo funciona todo esto.
(https://lh3.googleusercontent.com/-ZAKYzT6vHWU/VDnhFkTnnrI/AAAAAAAACc0/4bn-eyMwyV4/w283-h35-no/24.png)
Entonces, podemos recibir los datos de dos formas. Veamos ambas:
(https://lh6.googleusercontent.com/-qZe-T7Emyog/VDnhGLUUdLI/AAAAAAAACdE/FNZ_LNgQVu4/w272-h68-no/25.png)
(https://lh5.googleusercontent.com/-DYD-ICUZ4jA/VDnhHvmCa9I/AAAAAAAACdU/C8f_N_GmVIY/w337-h56-no/26.png)
Es importante recordar que cada vez que utilizamos la sentencia return, estamos dando fin a la función. En ciertas ocasiones, vamos a necesitar devolver varios valores sin detener la función. Para eso podemos utilizar la sentencia yield, la cual retorna valores pero no interfiere en la ejecución de la función.
(https://lh5.googleusercontent.com/-LbCJoCzh_2E/VDnhHn83pwI/AAAAAAAACdg/UurJBLYLL5s/w215-h52-no/27.png)
El resultado es, independientemente del número de valores que termine devolviendo la función, un objeto de tipo generator.
(https://lh6.googleusercontent.com/-36p3nbgl710/VDnhHyoKl5I/AAAAAAAACdY/gMMLzIcPw3s/w250-h67-no/28.png)
En los próximos talleres, cuando hablemos acerca de programación orientada a objetos(POO), veremos qué es un objeto. Por ahora, quedémonos con la idea de que es un tipo de dato más, tal como lo son las listas, los diccionarios, etcétera.
En cuanto al objeto generator, si analizamos su estructura, veremos que almacena cada uno de los datos en forma de nodo. Es decir, por cada dato se crea un nodo. Los nodos presentan un valor de carga (el que acaba de retornar la función) y un método next que apunta al próximo nodo (ya veremos en POO a qué nos referimos al hablar de métodos).
Sigamos con el ejemplo para entender un poco mejor el párrafo anterior.
(https://lh4.googleusercontent.com/-53BJEPtAoDI/VDnhIJSw9ZI/AAAAAAAACdo/qQu3f8TBAg4/w252-h259-no/29.png)
Esa es la forma más simple de imprimir las cargas de cada nodo.
Vamos a hacerlo ahora de forma "manual" para entender mejor esto de los nodos.
(https://lh3.googleusercontent.com/-MtQAsfWPAxw/VDnhI25_xSI/AAAAAAAACd0/qkxoRoa8bVs/w248-h259-no/30.png)
Como vemos, la instancia del objeto "retornarSinParar" siempre es la misma ("datos") pero el valor obtenido al ejecutar el método next va cambiando.
No se preocupen si no entienden nada de lo relacionado a POO. Son conceptos sencillos que los trataremos como corresponde en el taller correspondiente.
Por ahora, lo importante es que ya sabemos cómo recibir múltiples datos por medio de la sentencia yield (para no interrumpir la función) e imprimirlos por medio de un sencillo bucle for.
Codeando las notas de la abuelaMuy bien, existen muchos otros conceptos que debemos tratar en algún momento pero ya fue suficiente por hoy.
Dejemos algo de teoría para la próxima entrega y volvamos con la abuelita para poner en práctica todo lo que vimos a lo largo de este taller.
La tarea es transcribir las notas que hicimos para la abuela a puro código python.
Hasta ahora, lo único que ya sabemos es que para cumplir con este objetivo deberemos crear tres funciones: una para abrir pestañas, otra para ingresar a una página y otra para ingresar credenciales.
De más está decir que la creación de dichas funciones no intenta ser un límite sino que, por el contrario, espero que dejen volar su imaginación y codeen todo lo que se les venga a la mente.
Nos vemos en la próxima entrega con las soluciones y mucho más python para disfrutar.
DESCARGAR PDF (http://underc0de.org/talleres/Taller_Python_3.pdf)
Qué decirte WhiZ, que no te haya dicho...
La forma como formulaste el taller, me encantó. Es pedagógica.
Gracias por el esfuerzo.
Besillo.
G.
tengo una pregunta, si escribir cuatro espacios representa presionar cuatro veces la barra espaciadora por linea y asumiendo que no hablamos de una estructura dentro de otra (sino sería 8 en caso de dos, 12 en caso de 3 estructuras anidadas, etc.), y un tabulador es solo presionar una, ¿por qué razón es más conveniente utilizar cuatro espacios?, es como si yo dijera, vamos a usar 13 espacios para cada marcar lo que corresponde a cada estructura.
En ves de hacerlo rápido, parece que a los programadores de python les gusta presionar teclas por presionar teclas xD
saludos!
Buenas, he tenido algunos problemas siguiendo el curso en mi tablet con QPython, en la parte de retorno de valores he puedo el codigo tal cual en el editor, pero cuando lo ejecuto pasa esto: (http://tapatalk.imageshack.com/v2/15/02/19/cb03ee1742df23016e183635570b9e3b.jpg)
sin embargo, si lo escribo en la consola linea por linea si que funciona (http://tapatalk.imageshack.com/v2/15/02/19/6ad105ec472a387f937bc3b8e9acdb8d.jpg) Si me pudieran ayudar con esto les agradeceria mucho.
saludos y gracias!
Hola gomuNoob! Por lo que se aprecia en la imagen, el error radica en que el código es tomado como un comando para ejecutar con /system/bin/sh. Para que el código funcione, debes hacer que el mismo sea ejecutado por el intérprete de python (tal y como hiciste en la segunda imagen).
La verdad que no estoy seguro acerca de cuál es tu duda. Cualquier cosa, no dudes en comentar y vemos.
Saludos!
WhiZ
(https://lh6.googleusercontent.com/-VKMnfNiyNsw/VDnhIkpT50I/AAAAAAAACdw/3vN6Bfn2m7c/w309-h275-no/3.png)
Hola a todos,tengo una pequeña duda en esta parte:
None es falso,por lo tanto en el if no significaría que si pisolimpiuo es verdadero limpiarlo y el else:si es sucio ensuciarlo?
Me estoy confundiendo en esta parte,gracias