Hola! ¿Que tal?
Ya que pasas por aquí, quiero que sepas que este blog ya no tiene mantenimiento. El nuevo blog ahora está en Github http://ropherpanama.github.io/
Nos leemos allá.
Saludos!
Programando como un Xobi
Blog sobre programación Java, Android, Python y Ruby/Rails. Apuntes de Oracle, MySQL, PostgreSQL, SQLite y algo más ...
martes, 29 de septiembre de 2015
martes, 2 de junio de 2015
Linux, comandos que me facilitan la vida!
Este post es simplemente para tener a mano comandos o secuencias de comandos que son muy útiles.
- Promedio del peso de los archivos en una carpeta, el peso se muestra en KB: ls -l | gawk '{sum += $5; n++;} END {print sum/n/1024 " KB"}
- Listar archivos con su peso en KB: ls -lh
- Mostrar el total de archivos de una carpeta: ls | wc -l
- Ejecutar un comando y ver la salida por terminal y a la vez guardarla en un archivo: {comando} | tee salida.log
- Buscar archivo a partir de un directorio en sus subdirectorios: find . -name FILE.ext
martes, 11 de noviembre de 2014
Apuntes - Tuning Glassfish (Optimización para producción)
Ajuste de JVM
Ya que
Glassfish está hecho sobre Java, muchas de las optimizaciones pueden hacerse a través
de la Java Virtual Machine
- En el fichero domain.xml ubicado en %GLASSFISH_HOME%/glassfish/domains/<DOMAIN_NAME/config se deben editar los parametro Xms y Xmx, esto para reservar más memoria para el GF. Ubica los siguientes parámetros y modificalos según la necesidad y capacidad del server:<jvm-options>-Xmx1024m</jvm-options> y <jvm-options>-Xms1024m</jvm-options>
- En este caso se está asignando 1GB de RAM, ambos parámetros se colocan igual para asignar la memoria en el arranque del servicio, de esta forma no se pierde tiempo haciéndolo después.
- Modificar la opción -client por -server de la siguiente manera, si el servidor que ejecuta el GF es 64bits entonces por default tomará la opción correcta, pero nada se pierde con “asegurarnos":<jvm-options>-server</jvm-options>
- También incluir estas configuraciones -Xss128k -XX:+DisableExplicitGC-XX:ParallelGCThreads=N (en donde N es el número de CPU's del servidor si la cantidad es menor a 8, en caso contrario N es igual #CPU's/2)
-XX:+UseParallelOldGC
Si la aplicación está haciendo una gran cantidad de operaciones de E/S
como escritura, también se le puede decir a Grizzly que utilice una estrategia asíncrona:
-Dcom.sun.grizzly.http.asyncwrite.enabled=true
Una alternativa que podría considerarse también si se está notando que algunas
operaciones de escritura parecen toma más tiempo de lo esperado. Se puede aumentar el número de procesadores
de escritura al aumentar el número Selectors NIO:
-Dcom.sun.grizzly.maxSelectors=XXX
Si la aplicación será utilizada por dispostivos
móviles o a traves de redes lentas puede configurar:
-Dcom.sun.grizzly.readTimeout
o
network-config>network-listeners>network-listener>transport#read-timeout para las operaciones read
y
com.sun.grizzly.writeTimeout o network-config>network-listeners>network-listener>transport#write-timeout para las operaciones write. Para que un hilo no bloquee otros posibles procesos de I/O durante mucho tiempo puede configurar la opción:
o
network-config>network-listeners>network-listener>transport#read-timeout para las operaciones read
y
com.sun.grizzly.writeTimeout o network-config>network-listeners>network-listener>transport#write-timeout para las operaciones write. Para que un hilo no bloquee otros posibles procesos de I/O durante mucho tiempo puede configurar la opción:
-Dcom.sun.grizzly.useKeepAliveAlgorithm=true
Esto le dará oportunidad de ejecución a otras peticiones.
GlassFish
Tuning
Algunas
configuraciones en el servidor de aplicaciones en sí pueden ser las siguientes:
En el
mismo fichero domain.xml modificar las siguientes opciones como se muestra a
continuación:
1.
<das-config
autodeploy-enabled="false"
dynamic-reload-enabled="false"></das-config>
2. Aceptor Threads: Si se tiene por
ejemplo un servidor con 2 CPU's de 4 nucleos cada uno, el valor de este
parametro debe ser 8. Para configurarlo ve a la consola de administración y
busca la siguiente direccion Configuration -> Network Config -> Transports
-> tcp -> Acceptor threads
3. Cacheo de recursos estáticos:
Configuration -> Network Config -> Protocols -> http-listener-1 ->
File Cache -> Enabled. De
tener conexiones HTTPS habilitarlo tambien para el listener seguro.
4. Si el servidor solo posee un
Network Interface Card (NIC) reemplaza todos los valores 0.0.0.0 de los
http listeners con el IP del servidor, como se muestra
Configuration -> Network
Config -> Network Listeners -> <listener_name> -> Address
5. Modificar el fichero default-web.xml ubicado en %GLASSFISH_HOME%/glassfish/domains/<DOMAIN_NAME>/ config como se muestra:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>development</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>genStrAsCharArray</param-name>
<param-value>true</param-value>
</init-param>
...
</servlet>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>development</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>genStrAsCharArray</param-name>
<param-value>true</param-value>
</init-param>
...
</servlet>
Optimizaciones para JDBC
Para drivers JDBC de Oracle pueden configurarse las siguientes opciones:
- ImplicitCachingEnabled=true
- MaxStatements=200
- MaxStatements=200
Configurar
los valores del Pool de conexiones steady-pool-size y max-pool-size con el
mismo valor. Una regla general es configurar estos valores con el mismo número
que se ha configurado en los HTTP request processing threads
Etiquetas:
gc,
j2ee,
JAVA,
java web development,
jsf,
jsp,
jvm,
tuning glassfish
viernes, 7 de noviembre de 2014
Threads en JAVA, iniciarlos, detenerlos y reanudarlos (Básico)
Bien primero que nada explicar de que vá el asunto.
La idea es controlar la ejecución de un Thread; es decir, poder detenerlo y reanudarlo. De plano que para iniciarlo lo iniciamos en el main y que tambien podemos detener del todo el proceso (para no poder levantarlo más).
Explico un poco el enfoque de la solución, implementé un Proceso principal, este es el trabajo que debe hacer el Thread; simplemente consiste en imprimir un numero cada cierto tiempo random no mayor a 5 segundos.
Decir que esto se ejecutará infinitamente.
Clase Proceso.java
import java.util.Random;
/**
* @author ropherpanama@gmail.com
* Esta clase representa el proceso de trabajo; imprimir un entero cada cierto tiempo
* se sobrescriben los metodos suspend y resume
*/
public class Proceso implements Runnable {
private int currentCont;
private Thread t;
private final int sleepTime;
boolean suspended = false;
private String threadName;
private boolean working = true;
private final static Random generator = new Random();
public Proceso(String threadName) {
this.threadName = threadName;
sleepTime = generator.nextInt(5000);
currentCont = 0;
}
@Override
public void run() {
System.out.println("Running " + threadName);
try {
while (isWorking()) {
System.out.println(threadName + " doing : " + currentCont);
currentCont++;
Thread.sleep(sleepTime);
synchronized (this) {
while (suspended) {
wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
void suspend() {
System.out.println("Suspending " + threadName);
suspended = true;
}
synchronized void resume() {
System.out.println("Resuming " + threadName);
suspended = false;
notify();
}
public boolean isWorking() {
return working;
}
public void setWorking(boolean working) {
this.working = working;
}
}
Notar que el propio hilo se sincroniza y si se cumple que el hilo entra en estado suspend se llama al método wait(), esto provocará que el hilo se mantenga pausado hasta que alguien llame al método notify(); que precisamente se llama en el método resume() y se niega que el estado del hilo es suspend (suspend = false). Otro punto importante es que al tener un proceso que podría ejecutarse hasta el final de los tiempos, podriamos querer algún día detenerlo, para eso usamos el while con la variable working, que en primera instancia tendra un valor true.
Interactuar por consola con tu Thread
Lo divertido del caso era que se pudiera; mediante el teclado decirle al Thread lo que tenía que hacer, no simplemente escribirlo y no poder interactuar con el programa. Para eso, pensé en un "monitor" de entrada de teclado (Thread también por cierto) que en base a lo que escribas en el teclado defina el estado del Thread que está realizando el proceso principal. Entonces puedo escribir S (suspender), D (detener), R (reanudar) y B (salir) y con esto podré controlar los estados de mi hilo Proceso. Para este ejemplo simple solo estoy vigilando un solo Thread pero pueden ser cuantos se requieran.
Clase Entrada.java
import java.util.Scanner;
/**
* @author ropherpanama@gmail.com
* Esta clase esta pendiente de la entrada del usuario, la misma actua
* como monitor de entrada por teclado y dependiendo de ello ajustara el estado
* del Hilo al cual controla
*
*/
public class Entrada implements Runnable {
private Scanner sc = new Scanner(System.in);
private String command = "";
private Proceso p1;
public Entrada(Proceso p1) {
this.p1 = p1;
}
@Override
public void run() {
while (true) {
System.out.println("Waiting input:");
command = sc.nextLine();
if (this.getCommand().toUpperCase().equals("S")) {
p1.suspend();
} else if (this.getCommand().toUpperCase().equals("R")) {
p1.resume();
} else if (this.getCommand().toUpperCase().equals("D")) {
p1.setWorking(false);
System.out.println("Fin de trabajo");
} else if (this.getCommand().toUpperCase().equals("B")) {
System.out.println("Saliendo");
System.exit(0);
} else
System.out.println("No input");
}
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}
Vemos que esta clase, al igual que Proceso implementa la Runnable, por ende tambien es un Thread. Este hilo va a estar pendiente de lo que escribas en el teclado y según ello actuará sobre el Thread que este monitorizando.
Ahora vamos a probar esto, creamos la clase Test.java que contiene el main y lo ponemos todo a interactuar.
Clase Test.java
public class Test {
public static void main(String[] args) {
Proceso p1 = new Proceso("Juana");
p1.start();
Entrada e = new Entrada(p1);
Thread input = new Thread(e);
input.start();
}
}
Bien, he llamado a mi proceso principal "Juana" (no sé porqué) y le he dicho que inicie (p1.start()), luego; he creado una instancia de mi Thread monitor de entrada, para que vigile lo que escribo y opere sobre "Juana". Notar que le paso a "Juana" (p1) como argumento de su constructor. Entrada e = new Entrada(p1);
La salida del programa es la siguiente:
Starting Juana
Running Juana
Juana doing : 0
Waiting input:
Juana doing : 1
Juana doing : 2
Juana doing : 3
Juana doing : 4
Juana doing : 5
Juana doing : 6
Juana doing : 7
Juana doing : 8
S
Juana doing : 9
Suspending Juana
Waiting input:
R
Resuming Juana
Waiting input:
Juana doing : 10
Juana doing : 11
Juana doing : 12
Juana doing : 13
Juana doing : 14
Juana doing : 15
Juana doing : 16
B
Juana doing : 17
Saliendo
Juana inicio y se ejecutó, e inició a tirar sus números. Luego le dije Juana descanza un rato (S) y descanzó hasta que le dije continúa (R), siguió hasta el número 17 y le dije sal del programa totalmente (B)
Si te quedan dudas te invito a ver la video demostración en Youtube, pronto pongo el link.
Saludos!
La idea es controlar la ejecución de un Thread; es decir, poder detenerlo y reanudarlo. De plano que para iniciarlo lo iniciamos en el main y que tambien podemos detener del todo el proceso (para no poder levantarlo más).
Explico un poco el enfoque de la solución, implementé un Proceso principal, este es el trabajo que debe hacer el Thread; simplemente consiste en imprimir un numero cada cierto tiempo random no mayor a 5 segundos.
Decir que esto se ejecutará infinitamente.
Clase Proceso.java
import java.util.Random;
/**
* @author ropherpanama@gmail.com
* Esta clase representa el proceso de trabajo; imprimir un entero cada cierto tiempo
* se sobrescriben los metodos suspend y resume
*/
public class Proceso implements Runnable {
private int currentCont;
private Thread t;
private final int sleepTime;
boolean suspended = false;
private String threadName;
private boolean working = true;
private final static Random generator = new Random();
public Proceso(String threadName) {
this.threadName = threadName;
sleepTime = generator.nextInt(5000);
currentCont = 0;
}
@Override
public void run() {
System.out.println("Running " + threadName);
try {
while (isWorking()) {
System.out.println(threadName + " doing : " + currentCont);
currentCont++;
Thread.sleep(sleepTime);
synchronized (this) {
while (suspended) {
wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
void suspend() {
System.out.println("Suspending " + threadName);
suspended = true;
}
synchronized void resume() {
System.out.println("Resuming " + threadName);
suspended = false;
notify();
}
public boolean isWorking() {
return working;
}
public void setWorking(boolean working) {
this.working = working;
}
}
Notar que el propio hilo se sincroniza y si se cumple que el hilo entra en estado suspend se llama al método wait(), esto provocará que el hilo se mantenga pausado hasta que alguien llame al método notify(); que precisamente se llama en el método resume() y se niega que el estado del hilo es suspend (suspend = false). Otro punto importante es que al tener un proceso que podría ejecutarse hasta el final de los tiempos, podriamos querer algún día detenerlo, para eso usamos el while con la variable working, que en primera instancia tendra un valor true.
Interactuar por consola con tu Thread
Lo divertido del caso era que se pudiera; mediante el teclado decirle al Thread lo que tenía que hacer, no simplemente escribirlo y no poder interactuar con el programa. Para eso, pensé en un "monitor" de entrada de teclado (Thread también por cierto) que en base a lo que escribas en el teclado defina el estado del Thread que está realizando el proceso principal. Entonces puedo escribir S (suspender), D (detener), R (reanudar) y B (salir) y con esto podré controlar los estados de mi hilo Proceso. Para este ejemplo simple solo estoy vigilando un solo Thread pero pueden ser cuantos se requieran.
Clase Entrada.java
import java.util.Scanner;
/**
* @author ropherpanama@gmail.com
* Esta clase esta pendiente de la entrada del usuario, la misma actua
* como monitor de entrada por teclado y dependiendo de ello ajustara el estado
* del Hilo al cual controla
*
*/
public class Entrada implements Runnable {
private Scanner sc = new Scanner(System.in);
private String command = "";
private Proceso p1;
public Entrada(Proceso p1) {
this.p1 = p1;
}
@Override
public void run() {
while (true) {
System.out.println("Waiting input:");
command = sc.nextLine();
if (this.getCommand().toUpperCase().equals("S")) {
p1.suspend();
} else if (this.getCommand().toUpperCase().equals("R")) {
p1.resume();
} else if (this.getCommand().toUpperCase().equals("D")) {
p1.setWorking(false);
System.out.println("Fin de trabajo");
} else if (this.getCommand().toUpperCase().equals("B")) {
System.out.println("Saliendo");
System.exit(0);
} else
System.out.println("No input");
}
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}
Vemos que esta clase, al igual que Proceso implementa la Runnable, por ende tambien es un Thread. Este hilo va a estar pendiente de lo que escribas en el teclado y según ello actuará sobre el Thread que este monitorizando.
Ahora vamos a probar esto, creamos la clase Test.java que contiene el main y lo ponemos todo a interactuar.
Clase Test.java
public class Test {
public static void main(String[] args) {
Proceso p1 = new Proceso("Juana");
p1.start();
Entrada e = new Entrada(p1);
Thread input = new Thread(e);
input.start();
}
}
Bien, he llamado a mi proceso principal "Juana" (no sé porqué) y le he dicho que inicie (p1.start()), luego; he creado una instancia de mi Thread monitor de entrada, para que vigile lo que escribo y opere sobre "Juana". Notar que le paso a "Juana" (p1) como argumento de su constructor. Entrada e = new Entrada(p1);
La salida del programa es la siguiente:
Starting Juana
Running Juana
Juana doing : 0
Waiting input:
Juana doing : 1
Juana doing : 2
Juana doing : 3
Juana doing : 4
Juana doing : 5
Juana doing : 6
Juana doing : 7
Juana doing : 8
S
Juana doing : 9
Suspending Juana
Waiting input:
R
Resuming Juana
Waiting input:
Juana doing : 10
Juana doing : 11
Juana doing : 12
Juana doing : 13
Juana doing : 14
Juana doing : 15
Juana doing : 16
B
Juana doing : 17
Saliendo
Juana inicio y se ejecutó, e inició a tirar sus números. Luego le dije Juana descanza un rato (S) y descanzó hasta que le dije continúa (R), siguió hasta el número 17 y le dije sal del programa totalmente (B)
Si te quedan dudas te invito a ver la video demostración en Youtube, pronto pongo el link.
Saludos!
miércoles, 4 de junio de 2014
Sexto programa de Python Conexiones a Base de Datos
Una parte importante y lo mas real en casi todo entorno de trabajo automatizado, es la interacción con base de datos. Para este fin Python nos ofrece una manera
sencilla de trabajar con bases de datos.
Debemos tomar en cuenta la versión de Python que estemos usando para instalar la libreria específica para la base de datos que estemos usando.
Vamos a ver un programa que realiza una tarea muy comun:
1. Conectarse a una base de datos
2. Consultar una tabla
3. Exportar los resultados a un archivo de texto
Increíble que esto lo podamos hacer con tan pocas líneas, en este ejemplo usé Oracle. Y en esta ocasión colocaré imágenes en vez de texto (adiós copy/paste) hahaha,
veamos que tal.
Espero que les ayude, ya saben que bienvenidas son las preguntas!
Un saludo!
sencilla de trabajar con bases de datos.
Debemos tomar en cuenta la versión de Python que estemos usando para instalar la libreria específica para la base de datos que estemos usando.
Vamos a ver un programa que realiza una tarea muy comun:
1. Conectarse a una base de datos
2. Consultar una tabla
3. Exportar los resultados a un archivo de texto
Increíble que esto lo podamos hacer con tan pocas líneas, en este ejemplo usé Oracle. Y en esta ocasión colocaré imágenes en vez de texto (adiós copy/paste) hahaha,
veamos que tal.
Vemos que en las primeras líneas estamos haciendo un import de componentes externos, en este caso tenemos que instalas el modulo cx_Oracle que nos permite trabajar con bases de datos Oracle, para casos en que uses PostgreSQL, MySQL, SQLite deberás buscar el módulo adecuado y seguir los pasos de su instalación, tomar en cuenta que los módulos de base de datos van de acuerdo a la version de Python que estés usando.
Otro punto importante es notar que podemos especificar un name a nuestro gusto (cx_Oracle as ora) eso ayuda cuando el nombre del módulo que importamos tiene un nombre muy largo.
Con makedsn construimos una cadena de conexión para el metodo connect, vemos que el primer parámetro es el IP del servidor de la BDD, segundo el puerto, y tercero el nombre de la base de datos (SID por ejemplo).
Una vez teniendo el dsn nos conectamos con el user/password de la base de datos.
Estando conectados podemos ejecutar DML y extraer datos, en este caso volcamos los resultados a un archivo de texto llamado "tablares.txt"
Al ejecutar el programa deberas ver lo siguiente:
En donde 11.2.0.1.0 es la version de mi base de datos y seguido el tiempo que tomo el proceso en crear el archivo de texto con todos los registros.
Luego podremos ver que se ha creado el archivo de texto "tableres.txt"
Un saludo!
Quinto programa con Python (Clases)
Para este programa vamos a ver que tal se maneja el concepto de Clase con Python, revisemos línea a línea el siguiente programa para ver a que corresponde cada una.
Como siempre te invito a copiar (a mano) las lineas que no tienen # por delante, ya que como sabemos son comentarios que el compilador ignora.
Este programa escribirá todo lo que el usario le envie por consola en un archivo de texto, terminará cuando el usuario escriba Adios.
#Una clase se define mediante la palabra clase class
class Archivo:
#Viniendo de Java lo primero que intente ubicar fue un constructor, en el caso de python, este se define como __init__, y algo muy importante es nunca olvidar
#el parametro self, de olvidarlo veras algo como "TypeError: function() takes 0 positional arguments but 1 was given".
#self viene a ser algo asi como el this de java, es decir los atributos de instancia que persisten a traves de la vida del objeto.
def __init__(self, name, content):
self.name = name
self.content = content
print("Archivo llamado ", name)
#En java tenemos la palabra private para indicar que un atributo o metodo es privado, en python esto lo podemos hacer para los metodos con un doble subrayado,
#veremos que la forma de utilizar (llamar) estas funciones es un tanto diferente, no olvidar el parametro self
def __escribir(self):
t = input("Escriba > ")
self.content += "\n" + t
#Este metodo es normal, tal como lo habiamos visto en el programa 4
def leer(self):
#Validamos el contenido del archivo antes de leerlo
if len(self.content) == 0:
print("Archivo no tiene contenido, escriba algo")
else:
print("cat " + self.name + "\n",self.content)
#Uso de la clase
#Vamos a instanciar un objeto de nuestra clase
#Recordar que arriba colocamos el metodo de inicializacion con los parametros de nombre del archivo y algo de contenido, notar que el self no debe ser cargado por
#nosotros
a = Archivo("CV.doc", "")
#Ofrecemos las instrucciones, notar que con triple doble comilla podemos imprimir lineas tal cual como las escribimos en el fichero de fuente.
print("""Escriba:
e para escribir
l para leer
bye para salir""")
#Entramos a un blucle infinito, que se encargara de interactual con el usuario
while True:
r = input("> ")
if r == "bye":
print("Adios")#Si el usuario escribe Adios salimos del programa
break
elif r == "e":
#Observar el llamado a la funcion que definimos privada, a es el identificador de la instancia, seguido de un underline y el nombre de nuestra clase (Archivo) doble
#subrayado y el nombre de nuestra funcion.
a._Archivo__escribir()#Llamado a una funcion privada
elif r == "l":
a.leer()
else:
print("Opcion no valida")
Bueno, eso ha sido todo por hoy. Ya podemos definir clases, sabemos como instanciarlas y construir inicializadores segun las necesidades de nuestro objeto.
Podemos acceder a funciones privadas y publicas de una clase.
Un saludo, bienvenidas son las preguntas!
Como siempre te invito a copiar (a mano) las lineas que no tienen # por delante, ya que como sabemos son comentarios que el compilador ignora.
Este programa escribirá todo lo que el usario le envie por consola en un archivo de texto, terminará cuando el usuario escriba Adios.
#Una clase se define mediante la palabra clase class
class Archivo:
#Viniendo de Java lo primero que intente ubicar fue un constructor, en el caso de python, este se define como __init__, y algo muy importante es nunca olvidar
#el parametro self, de olvidarlo veras algo como "TypeError: function() takes 0 positional arguments but 1 was given".
#self viene a ser algo asi como el this de java, es decir los atributos de instancia que persisten a traves de la vida del objeto.
def __init__(self, name, content):
self.name = name
self.content = content
print("Archivo llamado ", name)
#En java tenemos la palabra private para indicar que un atributo o metodo es privado, en python esto lo podemos hacer para los metodos con un doble subrayado,
#veremos que la forma de utilizar (llamar) estas funciones es un tanto diferente, no olvidar el parametro self
def __escribir(self):
t = input("Escriba > ")
self.content += "\n" + t
#Este metodo es normal, tal como lo habiamos visto en el programa 4
def leer(self):
#Validamos el contenido del archivo antes de leerlo
if len(self.content) == 0:
print("Archivo no tiene contenido, escriba algo")
else:
print("cat " + self.name + "\n",self.content)
#Uso de la clase
#Vamos a instanciar un objeto de nuestra clase
#Recordar que arriba colocamos el metodo de inicializacion con los parametros de nombre del archivo y algo de contenido, notar que el self no debe ser cargado por
#nosotros
a = Archivo("CV.doc", "")
#Ofrecemos las instrucciones, notar que con triple doble comilla podemos imprimir lineas tal cual como las escribimos en el fichero de fuente.
print("""Escriba:
e para escribir
l para leer
bye para salir""")
#Entramos a un blucle infinito, que se encargara de interactual con el usuario
while True:
r = input("> ")
if r == "bye":
print("Adios")#Si el usuario escribe Adios salimos del programa
break
elif r == "e":
#Observar el llamado a la funcion que definimos privada, a es el identificador de la instancia, seguido de un underline y el nombre de nuestra clase (Archivo) doble
#subrayado y el nombre de nuestra funcion.
a._Archivo__escribir()#Llamado a una funcion privada
elif r == "l":
a.leer()
else:
print("Opcion no valida")
Bueno, eso ha sido todo por hoy. Ya podemos definir clases, sabemos como instanciarlas y construir inicializadores segun las necesidades de nuestro objeto.
Podemos acceder a funciones privadas y publicas de una clase.
Un saludo, bienvenidas son las preguntas!
martes, 13 de mayo de 2014
Cuarto programa de Python (Funciones)
Para el cuarto programa vamos a ponernos interactivos, vamos a crear un programa que nos diga nuestra edad, muy sencillo, pero nos servirá para entender mejor la captura de datos por teclado y lo más importante, definir y utilizar funciones (métodos)
Voy a #comentar todo entre líneas para que se entienda mejor.
Como de costumbre puedes escribir (sí escribir, no copy/paste) este código en tu IDLE de Python y ejecutarlo con F5
#Mi cuarto programa Python
#Si se abre con IDLE, ejecutar con la tecla F5
#Funciones
#Vamos a definir una fincion, su nombre es calcularEdad (a python no le gustan las mayusculas, pero es que vengo de Java entiéndanme)
#Esta función o metodo va a recibir un argumento, fijense que no estamos especificando el tipo del argumento, simplemente va porque vá, queda de nosotros
#manipular este dato en nuestro código, en este ejemplo; como lo vamos a recibir de input() por seguridad lo pasamos a string con str()
#la función no retorna cosa alguna, solo nos imprime nuestra edad
def calcularEdad (anio_nacimiento):
print("Tu edad es " + str(2014 - anio_nacimiento) + " años")
#la variable entrada tendra valor capturado por teclado, esto se logra con la función input()
entrada = input("Ingrese su año de nacimiento ")
#Vamos a llamar a nuestra función creada anteriormente con el valor que tomamos de entrada
calcularEdad(int(entrada))
#Bien, ahora que vimos funciones sin retorno (tipo void) vamos a ver funciones que retornen algo
#nuevamente fue muy extraño para mi no tener la necesidad de definir qué es lo que debo retornar en mi función, simplemente con colocar la palabra return
#estamos indicando que la función retorna algo, en nuestro ejemplo retorna un entero (nuestra edad)
def calcularEdad2 (anio):
return 2014 - anio
#Nuevamente vamos a tomar entrada desde el teclado para ejecutar nuestra función
entrada2 = input("Ingrese su año de nacimiento ")
#Vemos que para este caso, como la funcion retorna, podemos almacenar su valor retornado en una variable (answer)
answer = calcularEdad2(int(entrada2))
#Imprimimos la variable answer que es la que posee el valor que retorno la funcion
print("Tu edad es " + str(answer) + " años")
#Numero variable de parametros en una funcion
#Tal como lo indica la documentacion https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions
#una funcion puede definirse para que tome una cantidad de argumentos variable, si bien es cierto en este ejemplo obligatoriamente estamos definiendo que
#se le deben enviar 2 argumentos (por arg1 y arg2), el tercer parametro puede ser una tupla o un diccionario, esto lo sabemos por el argumento *arg3.
#Si la tupla no contiene valor alguno no se imprimirá nada que inicie con Item: o en el print de abajo, prueba colocarle algo a ver que pasa :)
def variable(arg1, arg2, *arg3):
for s in arg3:
print("Item: " + str(s))
print(arg1, arg2, arg3)
a = input("Ingrese un numero ")
b = input("otro ...")
#array = [23,22,21,20] #lista extra #descomenta esta linea para enviarle una lista a la funcion
#variable(int(a), int(b), array) # esta tambien si le pasas la lista
variable(int(a), int(b))
En resumen
Voy a #comentar todo entre líneas para que se entienda mejor.
Como de costumbre puedes escribir (sí escribir, no copy/paste) este código en tu IDLE de Python y ejecutarlo con F5
#Mi cuarto programa Python
#Si se abre con IDLE, ejecutar con la tecla F5
#Funciones
#Vamos a definir una fincion, su nombre es calcularEdad (a python no le gustan las mayusculas, pero es que vengo de Java entiéndanme)
#Esta función o metodo va a recibir un argumento, fijense que no estamos especificando el tipo del argumento, simplemente va porque vá, queda de nosotros
#manipular este dato en nuestro código, en este ejemplo; como lo vamos a recibir de input() por seguridad lo pasamos a string con str()
#la función no retorna cosa alguna, solo nos imprime nuestra edad
def calcularEdad (anio_nacimiento):
print("Tu edad es " + str(2014 - anio_nacimiento) + " años")
#la variable entrada tendra valor capturado por teclado, esto se logra con la función input()
entrada = input("Ingrese su año de nacimiento ")
#Vamos a llamar a nuestra función creada anteriormente con el valor que tomamos de entrada
calcularEdad(int(entrada))
#Bien, ahora que vimos funciones sin retorno (tipo void) vamos a ver funciones que retornen algo
#nuevamente fue muy extraño para mi no tener la necesidad de definir qué es lo que debo retornar en mi función, simplemente con colocar la palabra return
#estamos indicando que la función retorna algo, en nuestro ejemplo retorna un entero (nuestra edad)
def calcularEdad2 (anio):
return 2014 - anio
#Nuevamente vamos a tomar entrada desde el teclado para ejecutar nuestra función
entrada2 = input("Ingrese su año de nacimiento ")
#Vemos que para este caso, como la funcion retorna, podemos almacenar su valor retornado en una variable (answer)
answer = calcularEdad2(int(entrada2))
#Imprimimos la variable answer que es la que posee el valor que retorno la funcion
print("Tu edad es " + str(answer) + " años")
#Numero variable de parametros en una funcion
#Tal como lo indica la documentacion https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions
#una funcion puede definirse para que tome una cantidad de argumentos variable, si bien es cierto en este ejemplo obligatoriamente estamos definiendo que
#se le deben enviar 2 argumentos (por arg1 y arg2), el tercer parametro puede ser una tupla o un diccionario, esto lo sabemos por el argumento *arg3.
#Si la tupla no contiene valor alguno no se imprimirá nada que inicie con Item: o en el print de abajo, prueba colocarle algo a ver que pasa :)
def variable(arg1, arg2, *arg3):
for s in arg3:
print("Item: " + str(s))
print(arg1, arg2, arg3)
a = input("Ingrese un numero ")
b = input("otro ...")
#array = [23,22,21,20] #lista extra #descomenta esta linea para enviarle una lista a la funcion
#variable(int(a), int(b), array) # esta tambien si le pasas la lista
variable(int(a), int(b))
En resumen
- Muy importante y si eres observador, habrás notado que las funciones se definen con la palabra def
- Lo demás está explicado no?, las preguntas son bienvenidas!
Recuerden ir a descubrir mucho mas en la Documentación
Suscribirse a:
Entradas (Atom)