Saltar a contenido

Álvaro Castillo

¿Cómo instalar Packet Tracer 7.3 en Linux?

NOTA: He vuelto a revisar el procedimiento para PT 7.3 en Fedora 32 y funciona perfectamente. He visto varios comentarios indicando que pueden obtener el software de servidores como Mediafire. Os pido que lo descarguéis directamente desde la página web de Cisco. El hecho de que no ponga el enlace de descarga a este software, es que Cisco no permite su difusión, por lo que os añado en este post una manera de cómo obtenerlo, gracias por vuestros reportes y aportes.

Packet Tracer es un software desarrollado por Cisco en su división de educación NetAcad. Este software de "simulación" permite diseñar múltiples escenarios en el ámbito de redes, ya que permite elaborar diferentes tipos de redes como LAN, MAN, WAN con medios alámbricos e inalámbricos; permite utilizar protocolos de enrutamiento dinámicos como OSPF, IGRP, EIGRP, BGP, RIP y estáticos.

También permite la elaboración de redes convergentes implementando equipos con múltiples servicios que actúen de servidor, todos los paquetes transmitidos y retransmitidos (protocolo TCP) se pueden visualizar con un analizador de tráfico que incorpora el programa, este permite ver cómo se establecen los procesos de negociación con los diferentes protocolos de transmisión y de enrutamiento facilitando la comprensión de los mismos.

Packet Tracer se encuentra disponible para diferentes sistemas como Windows (32 y 64 bits), Linux (solo 64 bits), Android e iOS. Hay que estar previamente logeado para acceder a su contenido.

La instalación tanto en Android, iOS y Windows no requieren de pasos adicionales, más que de descargar su instalador desde el market de aplicaciones correspondiente (Google Play Store, App Store_) o el ejecutable para Windows desde la página Web.

Requisitos

Primeramente, hay que tener usuari@ en la NetAcad para poder descargar su software, (no ponemos un enlace directo ya que no se permite redistribuir el software). Antes era más complicado acceder si no se hacía un curso concertado, pero ahora basta con hacer un curso introductorio para poder descargarlo.

Puedes inscribirte en el curso pulsando aquí.

¿Linux? ¿Complicado?

En Linux los pasos no son tan "sencillos", ya que en primer lugar, el software viene comprimido en un comprimido .tar.gz, en segundo lugar, hay que realizar la instalación haciendo uso de un script en línea de comandos, en tercer lugar el script de instalación está mejor adaptado a distribuciones como Ubuntu que el resto, y en cuarto lugar, el software hace uso de una librería SSL poco utilizada en distribuciones modernas, y tenemos que hacer un "apaño" con lo que hace este proceso un poco engorroso.

Pasos a seguir

Descargamos y descomprimimos el Packet Tracer.

cd /DIRECTORIO_DESCARGA_PT/
mkdir PT
tar xfv Packet\ Tracer\ 7.2\ for\ Linux\ 64\ bit.tar.gz -C PT
cd PT

Instalamos

sudo ./install

[salida]
Welcome to Cisco Packet Tracer 7.2 Installation

Read the following End User License Agreement "EULA" carefully. You must accept the terms of this EULA to install and use Cisco Packet Tracer.
Press the Enter key to read the EULA.
[...]

Pulsamos Espacio para hacer más rápida la lectura, cuando nos pregunte, escribimos y, dejamos todo por defecto.

Do you accept the terms of the EULA? (Y)es/(N)o y
Enter location to install Cisco Packet Tracer or press enter for default [/opt/pt]: 
Installing into /opt/pt
Copied all files successfully to /opt/pt


Should we create a symbolic link "packettracer" in /usr/local/bin for easy Cisco Packet Tracer startup? [Yn] y
Type "packettracer" in a terminal to start Cisco Packet Tracer
Writing PT7HOME environment variable to /etc/profile
Writing QT_DEVICE_PIXEL_RATIO environment variable to /etc/profile

Cisco Packet Tracer 7.2 installed successfully
Please restart you computer for the Packet Tracer settings to take effect

Cuando queramos arrancar el software, no aparecerá nada. Si no fijamos veremos que falta una librería.

ldd /opt/pt/bin/PacketTracer7
[...]
libcrypto.so.1.0.0 => not found
[...]

Para solucionar este inconveniente descargamos libcrypto.so.1.0.0 y libssl.so.1.0.0. y lo copiamos a /opt/pt/bin o clonamos el repositorio y ejecutamos el script sencillo con el que copiará directamente los archivos descargados al directorio dónde tienen que ir.

git clone https://github.com/sincorchetes/packettracer
cd packettracer
chmod +x bootstrap.sh
./bootstrap.sh

Una vez hecho esto, si lanzamos packettracer (un alias que instaló el instalador) desde terminal veremos una ventana como la siguiente:

Troubleshooting

No veo Packet Tracer en el menú de aplicaciones. Si no lo ves, solo bastará con copiar el archivo .desktop a /usr/share/applications

sudo cp /opt/pt/bin/Cisco-PacketTracer.desktop /usr/share/applications/

Referencias

¿Cómo obtener ayuda en sistemas UNIX-like?

¿Qué pasa cuando tenemos algún problema con algún comando, no tenemos muy clara el parámetro que tendríamos que utilizar, saber bien si es realmente ese comando..etc?

Bien los sistemas UNIX-like como FreeBSD, Linux... por excelencia poseen una serie de herramientas como el comando man(1), info(1), help(1)... que vienen con el sistema operativo que podemos utilizarlos para salvarnos de un buen apuro. Si bien son conocidos estos sistemas son por su extensa y grande documentación otorgándoles muchísima profesionalidad y calidad.

man

El comando man(1) es un interfaz en modo texto escrito por John W. Eaton entre el 1990 y 1993. Este nos permite visualizar los manuales de los comandos y programas que tengamos instalados en el sistema. Por lo general suelen contener multitud de ejemplos, descripciones sobre lo qué hace el comando o programa así como también explica para qué sirve cada parámetro que queramos utilizar. Es como un biblia en verso. man(1) dispone de una base de datos dónde almacena las rutas de la documentación para facilitar un acceso casi instantáneo a los archivos, la configuración de ésta se encuentra en el directorio /etc/man_db.conf y para regenerarla o crearle se utiliza el comando mandb(8)

Su sintaxis más básica es la siguiente:

man [n] comando
* man es el nombre del comando
* n es el número de categoría que puede tener el programa en el sistema, ya que pueden haber dos comandos iguales y pueden despitarnos a la hora de obtener el manual correcto.
* comando nos permitirá visualizar el manual para este

Categorías

Nº cat Descripción
1 Ejecutables o comandos que tienen que ver con el shell
2 Llamadas al sistema que son funciones provistas por el kernel
3 Llamadas a librerías que son funciones dentro de las librerías de los programas
4 Ficheros especiales que suelen encontrarse en /dev
5 Formatos y convenciones de archivos como por ejemplo /etc/passwd
6 Juegos
7 Miscelánea que también incluye macro paquetes y sus convenciones como man(7), groff(7)
8 Comandos de administración del sistema que suele utilizar el usuario root
9 Rutinas del kernel que no son estándar

¿Cómo funciona man?

Seguramente que nos lo preguntemos por la cantidad de categorías que hay y sobre todo porque hay muchos comandos que posiblemente se encuentren repetidos. Bien, cuando nosotros llamamos a man(1) sin especificar una categoría, lo que hace es buscar en todas las categorías pero de forma consecutiva, es decir, 1 1p 8 2 3 3p 4 5 6 7 9 0p n lp o 1x 2x 3x 4x 5x 6x 7x 8x.

¿Qué secciones contiene cada manual?

Cada página de manual contiene una serie de secciones que nos permiten organizar la información de tal forma que no se mezcle y siendo bastante útil y práctica. También es verdad que muchas páginas de los manuales no contienen todas las secciones e incluso pueden que tengan secciones personalizadas como es el caso del comando info(1) que contiene una sección llamada COPYRIGHT y REPORTING BUGS.

Sección Descripción
NAME Nombre del programa, comando...
SYNOPSIS Sintaxis, parámetros y un poco cómo utilizar el comando
CONFIGURATION Apartado de configuración
DESCRIPTION En este apartado se explica qué hace el comando, finalidad...
OPTIONS Explicación intensiva de cada una de las opciones y parámetros del software
EXIT STATUS Número de salida de ejecución de un comando, script...
RETURN VALUE Tipo de valor que devuelve X cosa, generalmente suelen ser funciones
ERRORS Se explica por qué pueden producirse determinados errores controlados
ENVIRONMENT Variables de entorno
FILES Ficheros involucrados en el funcionamiento del comando o aplicación
VERSIONS Cambios añadidos en las versiones del software
CONFORMING TO Citando estándares o información en concreto
NOTES Información adicional
BUGS Aparta de información para reportar errores tipo Bugzilla
EXAMPLE Ejemplos de cómo habría que ejecutarse o configurarse determinado software
AUTHORS Responsables del diseño del programa
SEE ALSO Tipo README adicional

Preformateo en las secciones:

Según el man del comando man, en la sección de SYNOPSIS si o sí, debería hacer uso de un estándar de formato para diferenciar parámetros o argumentos obligatorios y que este, puede extenderse en el resto de secciones.

  • texto en negrita: Exactamente como se muestra
  • texto en cursiva: Reemplazar con un argumento apropiado
  • [-abc]: Cualquiera o todos los argumentos que se encuentren dentro de los corchetes son opcionales
  • -a|-b: Opciones delimitadas por el caracter | o que se no se pueden utilizar en conjunto
  • argumento: Argumento que se puede repetir
  • [expresion]: Toda la expresión que se encuentre dentro de unos corchetes pueden repetirse

Este tipo de formato se puede interpretar de una forma diferente devido al dispositivo que se esté utilizando, ya que hay intérpretes de comandos que no pueden reproducir un subrayado, palabras en cursiva...etc

¿Cómo manejar info?

Para interactuar con man(1), podemos hacer uso de las flechas direccionales, no obstante, en la siguiente tabla resumiremos un poco algunos atajos que nos servirán para empezar a manejarlo:

Atajo Descripción
h H Muestra la ayuda de navegación
q :q Q :Q ZZ Sale del man
j e Desplaza la información hacia arriba línea a línea
k Mueve la información hacia abajo línea a línea
d z f Desplaza unas cuántas líneas hacia arriba
b y Desplaza unas cuántas líneas hacia abajo
g w Comienzo de página
1,20,200... Corre el texto tantos caracteres se le comunique
/expresión Busca en el texto alguna coincidencia con lo escrito
n Permite volver a buscar una misma coincidencia con lo buscado con /

¿Dónde se encuentra la documentación?

En general, toda la documentación se encuentra en el directorio /usr/share/man, también puede encontrarse en /usr/local/share/man o en directorios ya facilitados por el propio software a la hora de compilarse o empaquetarse.

Encontrar información relacionada

Si no nos acordamos del comando podemos buscarlo mediante relación de coincidencias haciendo uso del parámetro -k

man -k download

ascii-xfr (1)        - upload/download files using the ASCII protocol
dnf.plugin.download (8) - DNF download Plugin
git-fetch (1)        - Download objects and refs from another repository
git-http-fetch (1)   - Download from a remote Git repository via HTTP
repotrack (1)        - track a package and its dependencies and download them
smbget (1)           - wget-like utility for download files over SMB
update-pciids (8)    - download new version of the PCI ID list
wget (1)             - The non-interactive network downloader.
XkbSetIndicatorMap (3) - Downloads the changes to the server based on modific...
yumdownloader (1)    - download RPM packages from Yum repositories

Regenerando la base de datos

Para regenerar la base de datos de man, simplemente ejecutaremos:

sudo mandb

Comando info

El comando info(1) desarrollado por la Free Software Foundation (FSF) nos provee un lector de documentación elaborada en formato info. Por lo generla, si ejecutamos info(1) a secas, nos saldrá como una especie de página con hipervínculos por dónde podemos navegar entre las diferentes páginas disponibles como si de una página Web en modo texto se tratase.

Si nos dirigimos a los vínculos que se encuentran subrayados y pulsamos enter, accedemos directamente a dicha página. Las páginas pueden contener un índice facilitando la navegación.

Para más información sobre el comando info, info info

Comandos con parámetro de ayuda

Por regla general, cada comando suele tener una pequeña ayuda que describe un poco para qué sirve cada parámetro en resumidas líneas.

Por ejemplo, veamos la salida del comando ls(1) NOTA: Recortaremos la salida del comando porque es muy largo

Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

Mandatory arguments to long options are mandatory for short options too.
  -a, --all                  do not ignore entries starting with .
  -A, --almost-all           do not list implied . and ..
      --author               with -l, print the author of each file
  -b, --escape               print C-style escapes for nongraphic characters
      --block-size=SIZE      with -l, scale sizes by SIZE when printing them;
                               e.g., '--block-size=M'; see SIZE format below
  -B, --ignore-backups       do not list implied entries ending with ~

Como podemos ver nos da una breve explicación de lo que hace cada parámetro.

Si no hacen uso de --help, otros comandos también disponen de -h como dmesg(1): NOTA: También hemos recortado la salida de este comando debido al tamaño de su salida

Usage:
 dmesg [options]

Display or control the kernel ring buffer.

Options:
 -C, --clear                 clear the kernel ring buffer
 -c, --read-clear            read and clear all messages
 -D, --console-off           disable printing messages to console
 -E, --console-on            enable printing messages to console
 -F, --file <file>           use the file instead of the kernel log buffer
 -f, --facility <list>       restrict output to defined facilities
 -H, --human                 human readable output

Comando help

Este comando provee de información sobre comandos integrados en la shell como los condicionales, bucles, variables... veamos un ejemplo:

function: function name { COMMANDS ; } or name () { COMMANDS ; }
    Define shell function.

    Create a shell function named NAME.  When invoked as a simple command,
    NAME runs COMMANDs in the calling shell's context.  When NAME is invoked,
    the arguments are passed to the function as $1...$n, and the function's
    name is in $FUNCNAME.

    Exit Status:
    Returns success unless NAME is readonly.

Veamos otro:

variables: variables - Names and meanings of some shell variables
    Common shell variable names and usage.

    BASH_VERSION    Version information for this Bash.
    CDPATH  A colon-separated list of directories to search
            for directories given as arguments to `cd'.
    GLOBIGNORE  A colon-separated list of patterns describing filenames to
            be ignored by pathname expansion.
    HISTFILE    The name of the file where your command history is stored.
    HISTFILESIZE    The maximum number of lines this file can contain.
    HISTSIZE    The maximum number of history lines that a running

Como vemos en uno nos explica la sintaxis de una función (que veremos más adelante) y de las variables de entorno, con una salida recortada ya que esta es muy larga.

Y esto es todo compañer@s, no se olviden de que cada proyecto, software, aplicación, comandos...etc suelen tener a disposición al menos un pequeño manual de como utilizarse además de que dependiendo de su envergadura, puede estar sustentado por una comunidad que favorezca el intercambio de información y se impulsen más características, más documentación y más de todo.

¡Espero que les haya gustado!

Fuentes

  • man(1) pages
  • info(1) pages

¿Cómo solucionar el problema de Netflix y Vivaldi en Linux?

En el post anterior, estuvimos hablando sobre Vilvadi. Un navegador que se liberó en contraposición del rumbo que tomó Opera con su comunidad dando origen a su primera versión el 12 de abril del 2016.

Sin embargo, hemos tenido problemas al reproducir videos con Netflix o Atres Player porque al parecer hay un problema con los códecs. Fedora por ejemplo no incorpora códecs propietarios a menos que instales un repositorio adicional y los instales. No obstante, hemos hecho un sondeo por sus foros y hemos encontrado bastantes post que ocurrían en diferentes distribuciones de Linux. * Netflix and Vivaldi on Linux? * Netflix only works when Chrome is installed * Netflix videos doesn't work :( * Netflix don't find widevine and I'm pretty desperate now * Movie Sites Won't Play

...etc

¿Cómo solucionarlo?

Pues bien, uno de estos post, indicaban la instalación de una librería (libffmpeg.so) que viene dentro de un paquete que se obtiene de los repositorios de Ubuntu

Linux 32 Bits

wget -c http://security.ubuntu.com/ubuntu/pool/universe/c/chromium-browser/chromium-browser_67.0.3396.99-0ubuntu1_i386.deb
ar vx chromium-browser_67.0.3396.99-0ubuntu1_i386.deb
tar -xjvf data.tar.xz 
sudo cp usr/lib/chromium-browser/libffmpeg.so /opt/vivaldi/lib
rm -rf usr/

Linux 64 bits

wget -c http://security.ubuntu.com/ubuntu/pool/universe/c/chromium-browser/chromium-codecs-ffmpeg-extra_67.0.3396.99-0ubuntu1_amd64.deb
ar vx chromium-codecs-ffmpeg-extra_67.0.3396.99-0ubuntu1_amd64.deb
tar -xjvf data.tar.xz 
sudo cp usr/lib/chromium-browser/libffmpeg.so /opt/vivaldi/lib
rm -rf usr/

Reiniciamos el navegador y ¡ya tendría que estar solucionado! Hay otras alternativas como un script que sacó un usuario de la comunidad de Vivaldi llamado @ruario que es de donde hemos sacado la URL del paquete necesario.

¡Sin duda alguna le agradecemos el aporte desde Echemos un bitstazo!

¿Qué es la conversión de números?

En informática tendremos que enfrentarnos con varios problemas que requieren de soluciones distintas haciendo uso de la capacidad resolutiva para según que problemas con los que nos podamos encontrar en el ámbito de sistemas, haciendo uso de algoritmos para sacarnos de apuros en desarrollo Web, e incluso, haciendo un proceso de descartes en base a pruebas de rendimiento.

Aquí todo es posible, sin embargo, también debemos aprender las unidades básicas con la que las máquinas trabajan para enviar información a bajo nivel, obtener un color para nuestros desarrollos Web...etc Todo esto lo aprenderemos aquí.

Binario

Los números binarios son aquellos que están comprendidos entre 0 y 1 utilizando como base el 2. Esto representa la condición eléctrica, es decir, 0 es apagado y 1 es encendido.

Binario => Decimal BIN->DEC

Para convertir de binario a decimal tenemos dos formas de hacerlo.

  • Mediante el uso de una tabla exponencial
  • Tabla de exponentes

Mediante posición

Para convertir mediante posición, lo único que deberemos hacer, es saber en qué posición tenemos cada número y utilizar las potencias.

110101(2) => Decimal

((1*2⁵)+(1*2⁴)+(0*2³)+(1*2²)+(0*2¹)+(1*2⁰)) =
((1*2⁵)+(1*2⁴)+(1*2²)+(1*2⁰)) = 53(10)

53(10) es nuestro número decimal.

Tabla de exponentes

Dibujamos una tabla en relación al número que creemos que podamos obtener.

128 64 32 16 8 4 2 1
2⁷ 2⁶ 2⁵ 2⁴ 2⁰

Y en base al número que nos den, comenzamos a comparar de menor a mayor. Por ejemplo:

128 64 32 16 8 4 2 1
105 0 1 1 0 1 0 0 1

Binario => Hexadecimal

Tenemos que tener en cuenta la siguiente equivalencia:

Hexadecimal Binario
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Para convertir tan solo necesitaremos traducir cifra por cifra en base a esta tabla. Por ejemplo: 1010111101100100

1010 = A
1111 = F
0110 = 6
0100 = 4

Nuestro número es: AF64

Binario -> Octal

Tenemos que tener presente la siguiente equivalencia:

Decimal Binario
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

El octal solo hace uso de 3 bits, y no de 4 como el decimal o hexadecimal. Tomaremos los 3 primeros bits y los separamos para hacer la conversión.

1 010 010 111(2) = x(8)

1 010 111 => Vemos como el 1 está solo, por ello, le añadimos 2 ceros para normalizarlo.
001 010 111.

Nuestro número es: 127(8)

Decimal

Son números comprendidos entre 0 y 9, hacen uso de base 10. Estos se suelen utilizar mucho para representar la numeración IPv4, obtener un color para aplicarlo en desarrollo Web mediante la función rgb/rgba()...etc

Decimal => Binario DEC->BIN

Para convertir de binario a decimal tenemos dos formas de hacerlo.

  • Mediante división
  • Tabla exponencial

División

Para convertir de decimal a binario, simplemente tenemos que tener en cuenta el resto de la división, ignorar los decimales y continuar dividiendo el número del cociente hasta que ya no pueda dividirse más. Para reconstruir el número, se seleccionan de derecha a izquierda.

Por ejemplo:

362|2 = 0
181|2 = 1
 90|2 = 0
 45|2 = 1
 22|2 = 0
 11|2 = 1
  5|2 = 1
  2|2 = 0
  0|2 = 1

101101010

Tabla de exponentes

Dibujamos una tabla en relación al número que creemos que podamos obtener.

128 64 32 16 8 4 2 1
2⁷ 2⁶ 2⁵ 2⁴ 2⁰

Y en base al número que nos den, comenzamos a comparar de menor a mayor. Por ejemplo:

128 64 32 16 8 4 2 1
105 0 1 1 0 1 0 0 1

Decimal -> Hexadecimal

Dividimos el número entre 16 utilizamos el cociente para seguir dividiendo sin utilizar los decimales resultantes. Posteriormente, para obtener el resto, se multiplica el decimal obtenido de la división por 16 que es la base para obtener el resto.

Por ejemplo: 2937(10) -> x(16)

2937|16 = 183.5625 -> Resto = 0.5625*16 = 9
 183|16 = 11.4375 -> Re = 0.4375*16 = 7
  11|16 = 0.6875 -> Re = 0.6875*16 = B

Con lo que nuestro nº es: B79(16)

Decimal -> Octal

Se divide el número decimal entre 8, se desestiman los decimales, y el último número que ya no puede ser divisible se queda tal cual como resto formando parte del nº. Se lee de derecha hacia la izquierda.

210(10) = x(8)

210|8 = Resto =2
 26|8 = Re = 2
  3|8 = Re =3

Nuestro número es: 322.

Hexadecimal

Estos números son muy utilizados sobre todo cuando queremos manipular cierta información de archivos, contemplan un rango entre 0 y F, siendo F el número 15, hace uso de base 16.

Hexadecimal => Decimal

Para convertir de hexadecimal a decimal

Utilizamos las posiciones de los números y los multiplicamos por el resultado de su base.

B79(16) = x(12)

B*16² + 7*16¹ + 9*16⁰ =
11*256 + 7*16 + 9*1 =
2816+112+9 = 2937(10)

Hexadecimal => Binario

Tenemos que tener en cuenta la siguiente equivalencia:

Hexadecimal Binario
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Para convertir tan solo necesitaremos traducir cifra por cifra en base a esta tabla. Por ejemplo: A7F0

A = 1010
7 = 0111
F = 1111
0 = 0000

Nuestro número es: 1010011111110000

Hexadecimal -> Octal

Realizar este proceso de conversión no es un método directo. Primero hay que traducir de HEX->BIN y luego de BIN->OCT para obtener el valor.

E67(16) = x(8)

E(16) = 1110(2)
6(16) = 0110(2)
7(16) = 0111(2)

Nº convertido= 111001100111

Una vez obtenido el binario, lo pasamos a octal.

111001100111(2) = x(8)

111 001 100 111 = 7147(8)

Nuestro número es 7147(8)

Octal

Útil pero menos visto, nos permite obtener un número comprendido entre 0-7, hace uso de base 8.

Octal -> Decimal

Se tiene en cuenta la posición de la cifra, ya que luego se multiplica por su base, y a su vez, la base se multiplica por sí misma tantas veces tenga n en el exponente.

7147(8) = x(10)

7*8³ + 1*8² + 4*8¹ + 7*8⁰ = 3584 + 64 + 32 + 7

Nuestro número es: 3,687

Octal -> Binario

Básicamente utilizamos 3 bits por dígito, hay que tener en cuenta la siguiente equivalencia:

Tenemos que tener presente la siguiente equivalencia:

Decimal Binario
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

7420(8) -> x(2)

7 = 111
4 = 100
2 = 010
0 = 000

Nuestro número es: 111100010000(2)

Octal -> Hexadecimal

Como hemos dicho anteriormente, es un proceso que no se hace directo y hay que hacer uso del paso anterior para obtener el número hexadecimal.

7456(8) -> x(2)

7 = 111
4 = 100
5 = 101
6 = 110

Nº binario: 111100101110

Para obtener el número hexadecimal, bastará con separar 4 bits los dígitos del nº binario.

1111 0010 1110(2) -> x(16)

1111 = F
0010 = 2
1110 = E

Nuestro número es: F2E

Finalizando

¡Espero que aprendáis mucho! Al principio puede costar, pero con la práctica terminas haciendo las operaciones casi al instante.

¡Un saludo!

Fuentes

Conversor HDMI-VGA Aukey

Hemos adquirido a través de Amazon, un conversor HDMI-VGA debido a que tenemos un portátil que no tiene toma VGA, solo un puerto HDMI y 2 micro-HDMI. Queriamos tan solo compartir lo bien que nos funciona este dispositivo y por lo que recomendamos su compra. 100% compatible con Linux. El conversor viene dentro de una caja de cartón fino, con un pequelo manual, una pegatina y el conversor con el puerto HDMI cubierto por un protector de plástico duro para evitar que se deteriore.

Aukey

Resultado de xrandr(1):

$ xrandr
Screen 0: minimum 8 x 8, current 3200 x 1080, maximum 32767 x 32767
DP-0 disconnected (normal left inverted right x axis y axis)
DP-1 disconnected (normal left inverted right x axis y axis)
eDP-1-1 connected primary 1920x1080+1280+0 (normal left inverted right x axis y axis) 344mm x 194mm
   1920x1080     60.02*+
   1400x1050     59.98  
   1280x1024     60.02  
   1280x960      60.00  
   1024x768      60.04    60.00  
   960x720       60.00  
   928x696       60.05  
   896x672       60.01  
   800x600       60.00    60.32    56.25  
   700x525       59.98  
   640x512       60.02  
   640x480       60.00    59.94  
   512x384       60.00  
   400x300       60.32    56.34  
   320x240       60.05  
DP-1-1 disconnected (normal left inverted right x axis y axis)
HDMI-1-1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
   1280x1024     60.02*+  75.02  
   1920x1080     60.00    59.94  
   1280x960      60.00  
   1152x864      75.00  
   1280x720      60.00    59.94  
   1024x768      75.03    70.07    60.00  
   832x624       74.55  
   800x600       72.19    75.00    60.32    56.25  
   640x480       75.00    72.81    66.67    60.00    59.94  
   720x400       70.08  

Curso de Python - Controles de flujo, condicionales y bucles

Los controles de flujo se utilizan para definir cómo va actuar un script, aplicación... y qué va aplicarse inmediatamente después de evaluar la condición cuando se compare.

if

Esta estructura de control te permite evaluar una condición y ejecutar un trozo de código si la cumple.

>>> if (condición):
>>>  Bloque de código

if-else

El if-else es una estructura de control que permite hacer 1 cosa si se cumple la condicioń, si esta no se cumple, únicamente se ejecutará un bloque de código sin contemplar otras posibilidades.

if (condición 1):
  Bloque de código
else:
  Bloque de código

Veamos un ejemplo, Si tenemos un coche de marca Opel, emitirás un mensaje que diga "Tienes un Opel", si no es así, mostraremos un mensaje que diga que "No tienes un coche Opel".

>>> marca = "Citröen"
>>> if (marca == "Opel"):
>>>   print("Tienes un Opel")
>>> else:
>>>  print("No tienes un coche Opel")
'No tienes un coche Opel'

if-elif-else

¿Pero qué pasa cuando queremos comprobar múltiples condiciones? No podemos estar anidando if-else como si no hubiese un mañana uno dentro del otro. Para eso tenemos la estructura if-elif-else. Esta estructura nos permite hacer 1 cosa u otra en base a una condición, la cuál estará compuesto por uno o múltiples operadores como aritméticos, lógicos...

if (ondición 1):
  Bloque de código
elif (condición3):
  Bloque de código
elif (condición2):
  Bloque de código
else:
  Bloque de código

Veamos un ejemplo, Si tenemos un coche de marca Opel, emitirás un mensaje que diga "Tienes un Opel", si no es así, mostraremos un mensaje que diga que "No tienes un coche Opel".

>>> marca = "Citröen"
>>> if (marca == "Opel")
>>>   print("Tienes un Opel")
>>> elif (marca == "Citröen")
>>>   print("Tienes un coche Opel")
>>> elif (marca == "Audi"):
>>>   print("Tienes un Audi")
>>> else:
>>>   print("Tu marca de coche no está registrada")
Tienes un coche Citröen

Todo esto se puede complicar aún más haciendo uso de otros operadores y de otros if-elif-else anidados, por ejemplo, utilizaremos los operadores de comparación con lógicos tal que así:

>>> marca_coche = "Toyota"
>>> modelo_coche = "AE87"
>>> motor_coche = 1600
>>> if (marca_coche == "Toyota" and modelo_coche == "AE92"):
>>>   if (motor_coche == 1600):
>>>     print("Perfecto")
>>>   elif (motor_coche == 1400):
>>>     print("Bien")
>>>   elif (motor_coche == 1200):
>>>     print("Cuidado con las cuestas")
>>>   else:
>>>     print("Esto huele a chasis")
>>> elif (marca_coche == "Citröen" and modelo_coche == "Saxo"):
>>>   print("Enhorabuena, tienes un coche que pesa poco y corre mucho.")
>>> else:
>>>   print("Error 404, Tu coche no encontrado.")

Error 404, Tu coche no encontrado.

Este mensaje se produce porque en el primer condicional estamos esperando recibir el modelo AE92, y sin embargo, recibimos el AE87; como en la segunda condición (elif) requiere del modelo "Citröen" también queda descartado imprimiendo el mensaje "Error 404, Tu coche no encontrado.". No obstante, si cambiamos modelo_coche por AE92 y volvemos a ejecutar las sentencias, veremos que recibiremos el mensaje de: "Perfecto".

Bucle for

¿Qué ocurre si queremos recorrer una lista o generar múltiples ejecuciones de código? Pues evidetenmente con un if no nos vale, ya que solo nos permite validar una condicioń, y cuando la valide, esta dejará de ejecutarse.

for variable_interactiva in secuencia:
  Bloque código

¿Cómo funciona? En secuencia va una condición, podemos poner que recorra todos los valores de una lista y nos lo imprima por variable_interactiva.

>>> frutas = [ "Peras", "Manzanas", "Arándanos", "Pomelo"]
>>> for fruta in frutas:
>>>   print(fruta)
Peras
Manzanas
Arándanos
Pomelo

También se puede hacer ejecuciones por el tamaño de la lista:

>>> frutas = [ "Peras", "Manzanas", "Arándanos", "Pomelo"]
>>> for fruta in range(0 ,len(frutas)):
>>>   print("Esta es la posición", fruta,"de la fruta: ",frutas[fruta])
Esta es la posición 0 de la fruta:  Peras
Esta es la posición 1 de la fruta:  Manzanas
Esta es la posición 2 de la fruta:  Arándanos
Esta es la posición 3 de la fruta:  Pomelo

¿Cómo podemos hacer, que se hagan n ejecuciones para hacer tal cosa? Con la función range().

>>> for x in range(0,100):
>>>   print(x)
0
1
2
3
4
[... Corto aquí porque llega hasta 99 ...]

¿Por qué hasta 99 y no 100? Porque recordemos que el valor 0 es una posición que se cuenta, realmente es n - 1.

¿Cómo puedo romper una ejecución?

Tenemos el comando break que rompe la ejecución del código, por lo que me han enseñado, es mejor finalizar las cosas como tocan en vez de usar este tipo de "cañones". Pero que sepamos que lo podemos usar. Normalmente se usan cuando hay condicionales añadidos, esto no quiere decir que se siga ejecutándo el resto del programa que tengamos, solo se frena el bucle for que hemos invocado en nuestro fragmento de código.

>>> for x in range(0,100):
>>>   print(x)
>>>   if (x == 4):
>>>     break
0
1
2
3
4
[... Se para la ejecución ...]

Bucle while

Este bucle se repetirá hasta que la condición se cumpla.

>>> while ( condicion ):
>>>   # Bloque de código

Un ejemplo sencillo puede ser:

>>> a = 1
>>> while a < 10:
>>>   print(a)
>>>   a += 2
0
2
4
6
8

break, continue, pass

Estas tres sentencias permiten modificar la interacción de los bucles. break: Rompe toda la ejecución de un bucle.

for x in range(0,10):
  if x == 5:
    break
  print(x)

Veremos que la ejecución cuando llega a 5 el bucle se para a pesar de que le hemos dicho que el bucle vaya de 0 a 10 e imprimirá como último valor 4.

continue: Se salta la ejecución en ese momento de la condición del bucle, pero sigue iterando el resto de elementos del bucle hasta finalizar.

for x in range(0,10):
  if x == 5:
    continue
  print(x)

En este caso, observamos que cuando detecte que x = 5, el valor 5 no se imprimirá, pero continuará realizando el resto de condición.

pass: No ejecuta nada y deja que continue el flujo del bucle.

for x in range(0,10):
  if x == 5:
    pass
  print(x)

Se ejecutará como si no existiera la palabra reservada pass.

Juego, Dragón VS Personaje

Un dragón nos estará golpeando hasta que nosotros matemos al dragón o el dragón nos mate a nosotros:

NOTA: Vamos a llamar al módulo random y lo llamaremos como TirarDados que más tarde utilizaremos el método .random() para generar números aleatorios que están comprendidos entre 0.n y 1.n y que, haciendo uso del método .round() aproximaremos el número a favor del 1 o del 0.

#!/usr/bin/env python3
#
# Juego elaborado por Álvaro Castillo
# GPLv2
#
from random import random as TirarDados
dragon_hp = 100
personaje_hp = 100
hit_dragon = 5
hit_personaje = 5

while True: 
  if personaje_hp == 0:
    print("Hemos ganado :)")
    break
  elif dragon_hp == 0:
    print("Ganó el Dragón :(")
    break
  else:
    pass
  dados=round(TirarDados())
  if ( dados == 0 ):
    dragon_hp -= hit_dragon
    print("¡Hemos golpeado al dragón!, le queda: ", dragon_hp, "de vida.")
  elif ( dados == 1):
   personaje_hp -= hit_personaje
   print("¡El dragón nos ha golpeado!, tenemos de vida:", personaje_hp,".")
  else:
   print("Hubo un fallo")

Este es el análisis resumido de este juego: 1. La vida de ambos duelistas están asignadas en una variable 2. El daño que quita cada uno de ellos también 3. La condición siempre es True por lo que siempre se ejecutará originando un bucle infinito infinityLoop 4. Si la vida de alguno de los duelistas llega a 0, se interrumpe el bucle usando break 5. La variable dados obtiene un número aproximado a 1|0 dependiendo lo que salga. 6. Hay un condicional que dice si datos=1 ataca el dragón, si dados=0 atacamos nosotros. 7. Haciendo uso de los operadores de asignación, restamos el valor de afección a la vida del duelista afectado y se imprime un mensaje indicando quién ha golpeado a quién y cuánta vida le queda al duelista contrario. 8. Se repite el proceso hasta llegar al punto 4

Dando como resultado algo parecido a esto:

¡El dragón nos ha golpeado!, tenemos de vida: 95 .
¡Hemos golpeado al dragón!, le queda:  95 de vida.
¡Hemos golpeado al dragón!, le queda:  90 de vida.
¡Hemos golpeado al dragón!, le queda:  85 de vida.
¡El dragón nos ha golpeado!, tenemos de vida: 90 .
¡Hemos golpeado al dragón!, le queda:  80 de vida.
¡Hemos golpeado al dragón!, le queda:  75 de vida.
[...]

Espero que os haya gustado, en ya hemos aprendido hacer un montón de cosas con estos cursos: * Qué es Python * Cómo declarar variables * Qué y cuáles son los tipos de datos * Cómo trabajar con los tipos de datos * Cómo utilizar módulos * Cómo elaborar un control de flujo

En las siguientes entregas hablaremos de más cosas que tengo preparadas como las funciones, cómo imprimir datos utilizando diversas formas de hacerlo y algunos ejercicios de ejemplo. ¡Espero que cómo siempre os haya gustado!

Curso de Python - Encapsulamiento y polimorfismo

En este post haré una breve introducción a lo que es el encapsulamiento en Python y el poliformismo.

Encapsulamiento

Encapsular permite abstraer cierta información al mundo y mostrar solo aquella que interese. Por ejemplo, cuando enviamos un paquete por correos, el personal de correos no puede ver el contenido del paquete, pero si que puede ver el destinatario y el remitente, pudiendo identificar a las dos personas implicadas y saber sus direcciones de correo postal.

¿Cómo encapsular?

Para encapsular, básicamente tendremos que añadirle dos guiones bajos "_ __ _ " delante de la propiedad que queremos ocultar.

class A:
  self._propiedad = valor

Veamos un ejemplo:

class Persona:
  def __init__(self):
    self.nombre  = "Susana"
    self.__apellidos = "Bramura"
    self._tlfno = "777 777 777"

Carlos = Persona()

print(Carlos.apellidos)

Veremos un error parecido a este:

Traceback (most recent call last):
  File "main.py", line 9, in <module>
    print(Carlos.apellidos)
AttributeError: 'Persona' object has no attribute 'apellidos'

Y nos preguntaremos... Pero, si llamamos a Carlos.apellidos y nosotros hemos puesto: Carlos.__apellidos, ¿no sería más correcto para querer obtener el valor de los apellidos de la clase Persona? Bueno, aunque pensemos esto, si utilizamos __ igualmente dará el mismo error porque no se puede acceder desde fuera a una propiedad o método encapsulado.

print(Carlos.__apellidos)
Traceback (most recent call last):
  File "main.py", line 8, in <module>
    print(Carlos.__apellidos)
AttributeError: 'Persona' object has no attribute '__apellidos'

¿Cómo podemos acceder o modificar las variables, propiedades, o los métodos de ámbito privado?

Tendremos que crear métodos específicos que puedan acceder a esas variables, propiedades o métodos.

class A:
  # Constructor de clase
  def __init__(self):

    # Asignamos 20 a esta propiedad privada
    self.__propiedad = 20

  def __metodo(self):
    print("Soy un método privado.")

  # Soy un método público que leerá y ejecutará contenido privado.
  def mostrar(self):
    self.__metodo()
    print(self.__variable)

   def cambiar(self,propiedad):
     self.__propiedad = propiedad
     print("Esta es la nueva propiedad %i % (self.__propiedad))

# Instanciamos el objeto
obj = A()

# Ejecutamos el método público mostrar()
obj.mostrar()

# Modificamos el valor propiedad
obj.cambiar(300)

Polimorfismo

Es la capacidad que tiene un objeto para ser y poder ser otra cosa al mismo tiempo. Por ejemplo, un pájaro. Un pájaro puede ser un pingüino y un gorrión, ambos tienen propiedades en común como las patas, ojos, orejas; el color de las plumas, de los ojos, de los picos. También, tienen una serie de métodos similares como volar, poner huevos, comer, dormir... ¿Qué tienen en común todos ellos? Que son pájaros. Por lo tanto, un pájaro puede ser un gorrión o puede ser un pingüino al mismo tiempo sin perder lo que es su esencia, que es ser un pájaro.

# Creamos la clase Pájaro
class Pajaro:

  # Método volar
  def nadar(self):
    print("Puedo nadar.")

  def volar(self):
    print("Puedo volar.")

class Pinguino(Pajaro):
  def nadar(self):
    print("Puedo nadar.")

  def volar(self):
    print("No puedo volar.")

def ver_volar(birds)
  birds.volar()

gorrion=Pajaro()
pinguino=Pinguino()

# Este imprimirá que pude volar
ver_volar(gorrion)

# Este imprimirá que no puede volar
ver_volar(pinguino)

Curso de Python - Fecha y hora

¿Qué tal mis queridos/as lectores/as? hace bastante tiempo que no redactaba en el blog, últimamente he estado ocupándome de tener un poco de tiempo para mí, como si tuviera unas mini vacaciones. Pero no importa, aquí vuelvo cargado de más conocimientos para todos.

En este pequeño post, aprenderás a trabajar con la fecha y la hora de una forma breve y sencilla antes de hacer la introducción a la programación por objetos o POO.

Fecha y hora

Hay un módulo llamado time que te permitirá trabajar con la fecha y la hora, estos son algunos métodos.

import time
print(time.ctime())

Devolverá:

Mon Apr 13 21:58:46 2020

No es muy práctico si quieres hacer otras cosas, como asignar una fecha y hora a un archivo que quieras crear, por suerte, puedes preformatear con .strftime().

import time
fecha_log = time.strftime("%d-%m-%Y_%H-%M-%S")
fecha_humano = time.strftime("%A %d %B %Y %H:%M:%S")

# Imprimirá una fecha como esta:
# 13-04-2020_22-23-06    
print(fecha_log)

# Imprimirá una fecha como esta:
# Monday 13 April 2020 22:23:06
print(fecha_humano)

Puedes ver más información sobre los parámetros para formatear aquí.

Este es un ejemplo de como almacenar el resultado del comando dmesg del sistema operativo Linux, y que se almacene el resultado en un archivo con la fecha preformateada.

import subprocess
dmesg = subprocess.Popen(["dmesg"], shell=False,stdout=subprocess.PIPE)

from time import strftime as ConvertirTiempoLog
fecha_log = ConvertirTiempoLog("%d-%m-%Y_%H-%M-%S")
archivo_log = "dmesg_log_%s.log" % (fecha_log)

with open(archivo_log,'w') as dmesg_log:
   dmesg_log.write(dmesg.stdout.read().decode('utf-8'))
   dmesg_log.close()

calendar

Muestra un calendario como el comando cal de Linux.

import calendar
calendar.month(2020,1)
# Nos mostrará:
    January 2020
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Puedes hacer una combinación con el módulo time y calendar.

import time,calendar
anyo = int(time.strftime("%Y"))
mes = int(time.strftime("%m"))

#Imprimirá el calendario del año y me introducido.
print(calendar.month(anyo,mes))

O también puedes hacer que devuelva un calendario con valores específicos:

import calendar
anyo = int(input("Introduzca el año a consultar: "))
mes = int(input("Introduzca el mes: "))

#Imprimirá el calendario del año y me introducido.
print(calendar.month(anyo,mes))

Más información, en la documentación oficial.

Curso de Python - Herencia

Vamos a tratar un poco la herencia de que pueden tener los objetos, que es una de las características que tienen los objetos.

Herencia

Una de las propiedades que mencionamos que podían tener los objetos es la herencia, por lo que una clase hija puede contener propiedades y métodos de una clase padre. Veamos un ejemplo:

# Definimos la clase padre:
class ClasePadre:
# Decimos que se ejecute el código sin hacer nada.
  pass

# Y aquí la clase hija:
class ClaseHija(ClasePadre):
  pass

# Creamos el objeto
Objeto = ClaseHija()

Este es un ejemplo:

# Definimos la clase Familia
class Familia():

  # Con sus propiedades que se rellenarán cuando se inicialice el objeto.
  def __init__(self, miembros, apellidos):
    self.miembros = miembros
    self.apellidos = apellidos

    # Cuando se cree la clase, mostrará el apellido que ha recibido.
    print("Apellidos: %s" % (self.apellidos))

# Creamos la clase Hijo que hereda de Familia
class Hijo(Familia):

  # Se rellenarán propiedades para este objeto.
  def __init__(self, nombre, apellidos):

# Si queremos heredar propiedades y métodos, tendremos que hacer uso de la función super()
# super() lo explicaremos más adelante.
# Aquí llamamos la propiedad específica de Familia, Familia.apellidos y la inicializamos
    super().__init__(self,apellidos)

    # Definimos aquí los valores que tendrán estas propiedades
    self.nombre = nombre
    self.apellidos = apellidos

# Añadimos un método para el Hijo
  def mostrar_info(self):

    # Decimos que imprima self.nombre y self.apellidos.
    print("Soy %s y soy de la familia %s" % (self.nombre,self.apellidos))

# Creamos el objeto
Pugsley = Hijo("Pugsley","Adams")

# Llamamos al método mostrar_info()
Pugsley.mostrar_info()

Seguro que te preguntas sobre super().__init__(...), esta función como comentamos permite heredar propiedades y métodos de otra clase. Vendría a ser lo mismo que:

class A:
  def __init__(self, ejemplo):
    self.ejemplo = ejemplo

class B(A):
  def __init__(self, x, y, z):

    # Este procedimiento es más complicado y más tedioso de hacer.
    self.guardar_info = A(x)

obj = B(2,3,4)
print(obj.guardar_info.ejemplo)
Sobreescribiendo métodos en clases hijas

Se puede hacer evidentemente, si en la clase A tenemos un método llamado saludar(), y la clase B que hereda de la clase A, le podemos definir el contenido del mensaje que devolverá el método saludar().

class A:
  def saludar(self):
    print("Hola mundo")

class B(A):
  def saludar(self):
    print("Hello everybody")

obj = B
obj.saludar()

Y devolverá "Hello everybody".

Tipos de herencia

Bien, habiendo visto un ejemplo de herencia, también os cuento, que hay distintos ejemplos de herencia: * Simple * Múltiple * Multi nivel * Jerárquica * Híbrida

Simple

Es el tipo de herencia que hemos visto hasta ahora.

class A:
  pass
class B(A):
  pass

Múltiple

Es una clase que hereda desde otras clases, por lo que tendrá propiedades y métodos de ambas clases (A y B).

class A:
  pass
class B:
  pass
class C(A,B):
  pass

# Establecemos una comparación para ver si realmente son subclases o no.
# Devolverá True o False dependiendo de si es correcto o no.
issubclass(C,A) and issubclass(C,B)

Multinivel

Esto se refiere, a que tenemos una clase abuelo, de la cuál hereda una clase padre, del cuál hereda una clase hijo.

class A:
  pass
class B(A):
  pass
class C(B):
  pass

Como vemos, la clase C hereda de la clase B, la clase B de la clase A, y A es la clase principial de primer nivel. Por lo tanto, la clase C herederá propiedades y métodos de todas sus clases superiores a menos que se establezca qué propiedades o métodos se podrán heredar, esto forma parte del encapsulamiento que veremos más tarde.

Jerárquica

Tenemos múltiples clases que heredan de una sola clase, es decir.

class A:
  pass
class B(A):
  pass
class C(A):
  pass
class D(A):
  pass

Un ejemplo puede ser, clase Jefe/Jefa de una empresa que tiene el rol más alto de una organización y que por debajo de ellos hay otros roles acordes a la labor de la empresa que tienen menos privilegios, otras funciones...etc

Híbrido

Es la combinación de una o múltiples clases con una o múltiples clases por ejemplo: Imaginamos que tenemos 5 clases (A,B,C,D,E). * Clase A es una clase padre. * Clase B,C,D heredan de la clase A * Clase E, hereda de la clase B y D. * Clase E es la clase padre de B y D.

Aquí podemos identificar varios tipos de herencia: * A, B, C, D, C = Herencia híbrida * B, C, D que heredan de A = Herencia jerárquica * E que hereda de B y D = Herencia múltiple * C hereda de A = Herencia simple

Un ejemplo de sintaxis:

class A:
  pass
class B(A):
  pass
class C(A):
  pass
class D(A):
  pass
class E(B,D)

Si añadimos una variable en la clase A, creamos un objeto que referencie a E:

class A:
  hello_world = "Hola Mundo"
class B(A):
  pass
class C(A):
  pass
class D(A):
  pass
class E(B,D):
  pass
obj = E()
print(obj.hello_world)

´objhabrá impreso"Hola Mundo".`

Función super()

Se utiliza para llamar a métodos de una clase padre, hemos visto en un ejemplo anterior como llamábamos a super().__init__(self, nombre, apellidos) en el ejemplo de la Familia Adams. Aquí estábamos llamando al método inicializador de la clase Familia. Pero podemos llamar a otros métodos también. super().método().

class Vehiculo:
  def arrancar(self):
    print("Arrancamos el coche")
  def parar(self):
    print("Paramos el coche")

class Conductor(Vehiculo):
  def soplar(self):
    print("Soplando, soplando y soplando...")

  def control_policia(self):
    super().parar()
    print("Persona - Hola agente, buenos días")
    print("Policía - Hola, vamos hacerle una prueba de alcoholemia, por favor, sople en la boquilla")
    print("Persona - Vale")
    self.soplar()
    print("Policía - Genial, puede usted proseguir")
    super().arrancar()

Antonio = Conductor()
Antonio.control_policia()

Como vemos, no hace falta que llamemos a __init__ porque no estamos inicializando ningún valor en ninguna propiedad y como se ejecutan los métodos parar() y arrancar() que forman parte de la clase Vehiculo.

Curso de Python - Imprimir valores y funciones

En esta entrega veremos: * Cómo imprimir valores de múltiples formas * Iteradores * Cómo trabajar con una función básica * Estamentos de return, yield * Asignando variables a la función * Asignando valores por defecto en dichas variables * Closures * Generadores * Función lambda

Sustitución de tipos de datos en sentencias print()

Cuando queremos incluir un valor que proviene de variables, listas, sets, tuplas... se pueden hacer de múltiples formas. Por ejemplo:

variable = "Susana"
print("Hola me llamo:", variable)
Hola me llamo Susana.

Podemos hacerlo de esta forma:

variable = "Susana"
print("Hola me llamo: %s" % variable)
Hola me llamo Susana.

Tenemos que tener en cuenta que de esta manera, hay que definir si el dato que vamos a sustituir es str = %s%, int = %i, float = %f. NOTA: Los valores de tipo complex = %c no tienen sustitución directa en esta forma, por lo que hay que utilizar otro método como en el anterior.

O de esta otra:

variable = Susana
print(f'Hola me llamo {variable}')

También tenemos esta otra:

variable = "Susana"
print("Hola me llamo {}".format(variable))

En fin, hay muchas formas de hacer sustituciones en los str y en otros tipos de datos que puedes consultar en la documentación oficial.

Iteradores

Un iterador es una especie de puntero que permite devolver valores que le especifiquemos.

lista= ["Hola","esto","es","un","ejemplo","de","iterador"]

# Inicializamos el iterador
mi_iterador = iter(lista)

# Se puede imprimir el valor de esta manera, que devuelve la palabra Hola
print(next(mi_iterador))

# Pasamos al siguiente iterador que contiene la palabra "esto", pero no la imprimimos.
next(mi_iterador)

# Imprimimos la palabra "es"
print(next(mi_iterador))

# Imprimir todos los elementos del iterador:
for item in mi_iterador:
  print(item)

Funciones

Las funciones son un conjunto de código organizado y que contienen una serie de instrucciones que pueden reutilizarse. Por ejemplo, dormir es una función que tenemos, hay múltiples variables como el lugar, la intensidad de la luz, si estamos cómodos... pero que al final el resultado es descansar. Lo mismo sucede con las funciones.

Declaración de ejemplo de una función:

def my_funcion():
  # Bloque de código

return

return permite devolver un valor de la función y darla por terminada más que utilizar un print()

def func(a):
  return a

valor=func(12)
print(valor)

yield

En contra posición de return, yield permite seguir aplicando el código que venga más adelante de la función creando una especie de co-rutina o gestión de resultados o ejecución por turnos, como si fuera un corredor de atletismo que le pasa el testigo a otro y su marca de tiempo es el valor de retorno. Hacemos uso de los iteradores para extraer los datos.

def func(a):
  print("Devolvemos el primer resultado: %i" % (a)) 
  yield a
  c = a - 2
  print("Devolvemos el segundo valor: %i" % (c))
  yield c

abc = func(20)

mi_iter = iter(abc)

for item in mi_iter:
    print(item)

Tipos de funciones en Python

En Python, tenemos 2 tipos de funciones, una que creamos nosotros y otras que vienen integradas. Las que nosotros creamos las definimos en nuestra aplicación, script... mientras que las integradas, vienen con la instalación de Python que ya fueron elaboradas y que puedes utilizar como: len(), max(), min(),type(),range()`...

Veamos un ejemplo:

>>> def hola_mundo():
>>>   print("Hola Mundo")
>>> hola_mundo()
Hola Mundo

Podemos pasar todo tipo de valores, por ejemplo, pasaremos una lista como valor y un número entero:

>>> lugares = [ "Toronto", "Tokio", "Nueva Zelanda" ]

>>> def mostrar_lugares(valores):
>>>   for lugar in valores:
>>>     print(lugar)
>>> mostrar_lugares(lugares)
Toronto
Tokio
Nueva Zelanda

Asignar una función a una variable

Podemos asignar una función a una variable y llamarla como función desde la propia variable:

def mensaje(msg):
    print(msg)

segundo=mensaje

# Imprime "Mundo"
segundo("Mundo")

Asignar valores por defecto a los argumentos

Si no le decimos o especificamos un valor cuando llamamos a la función, podemos hacer que tome parámetros por defecto.

def test(variable="Valor que queremos")
  print(variable)

test()

Esto devolverá "Valor que queremos", si especificamos un valor tal que así:

test("Hola mundo")

Devolverá Hola mundo.

Closures

Los closures es un objeto especial que permite obtener información de otras funciones hijas que forman parte de una función padre, permiten dar más seguridad al código ya que todo lo que tenga que ejecutarse se hará dentro de ese ámbito o scope.

Ejemplo de closure

def func(x):
    def func_a():
        print(x)
    return func_a()

Generadores

Son funciones que crean iteradores, estas funciones realmente son objetos en Python. Si hacemos un print sobre la función, veremos <generator object mensaje at 0x7f31a4957250>, es muy importante saberlo. No solo podemos trabajar con return, también con yield.

def mensaje(msg):
    def lector():
        print(msg, "%s" % ("leido por un lector."))
    def escritor():
        print(msg, "%s" % ("escrito por un escritor."))

    yield lector()
    yield escritor()

ejemplo = mensaje("Alguien escribió este mensaje y ha sido")

for item in ejemplo:
    if item is None:
        pass
    else:
        print(item)

Función Lambda

Esta función no tiene nombre también se le conoce como función anónima, sin embargo, no puede contener más de una expresión:

>>> x = lambda a : a + 10
>>> resultado = x(5)
>>> print(resultado)
15

Si lo pasamos a función esto sería así:

>>> def sumar(a,b):
>>>   return a + b
>>> sumar(5,10)
15

En la próxima entrega veremos cómo un usuario introduce datos y el control de excepciones.