Buscando tutoriales, llegué a esta web:
http://elclubdelautodidacta.es/wp/2014/12/python-una-tortuga-de-brocha-fina/
Yo no sabía que Python tenía una tortuga al mismo estilo Logo. Luego de experimentar un poco con el código, llegué a esto:
import turtle
turtle.showturtle()
turtle.shape("turtle")
for i in range (0, 36):
turtle.penup()
turtle.left(10)
turtle.forward(80)
turtle.pendown()
turtle.circle(50)
turtle.penup()
turtle.forward(-80)
turtle.mainloop()
turtle.done()
turtle.exitonclick()
El resultado es:
Haciendo unos pequeños cambios:
import turtle
turtle.showturtle()
turtle.shape("turtle")
for i in range (0, 36):
turtle.penup()
turtle.left(10)
turtle.forward(25)
turtle.pendown()
turtle.circle(90)
turtle.penup()
turtle.forward(-25)
turtle.hideturtle()
turtle.mainloop()
turtle.done()
turtle.exitonclick()
Se obtiene:
Más info se puede hallar en la documentación oficial (en inglés).
Códigos de ejemplo para aprender distintas tecnologías, o lo que sucede cuando a una cuarentona se la deja sola con una computadora
Acerca de:
Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)
sábado, 27 de octubre de 2018
martes, 18 de septiembre de 2018
El colador o la criba de Eratóstenes con Linq y recursivo
Ya antes había jugado con el colador de Eratóstenes, pero ahora toca hacerlo más pretencioso, menos legible y más recursivo :D
En total son tres intentos nada prácticos pero muy instructivos, pues voy a jugar un poco con funciones lambda recursivas:
// primer intento
Func<int, int> colador = null;
int[] nums = Enumerable.Range(2, 48).ToArray();
colador = n =>
{
if (n == 8)
return 0;
else
{
nums = nums.Where(c => c == n || c % n != 0).ToArray();
return colador(n + 1);
}
};
colador(2);
nums.ToList().ForEach(c => Console.Write(c.ToString() + " "));
// el primer intento es una shit, modifica un array que está fuera de la función lambda.
// Acá viene el segundo intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador2 = null;
IEnumerable<int> nums2 = Enumerable.Range(2, 48);
colador2 = (n, x) =>
{
if (n == 8)
return x;
else
{
x = x.Where(c => c == n || c % n != 0);
return colador2(n + 1, x);
}
};
nums2 = colador2(2, nums2);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));
// el segundo intento aún es demasiado legible.
// Acá va el tercer intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador3 = null;
IEnumerable<int> nums3 = Enumerable.Range(2, 48);
colador3 = (n, x) =>
{
x = x.Where(c => c == n || c % n != 0);
return (n < 8) ? colador3(n + 1, x) : x;
};
nums3 = colador3(2, nums3);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));
Console.ReadLine();
El resultado es:
En total son tres intentos nada prácticos pero muy instructivos, pues voy a jugar un poco con funciones lambda recursivas:
// primer intento
Func<int, int> colador = null;
int[] nums = Enumerable.Range(2, 48).ToArray();
colador = n =>
{
if (n == 8)
return 0;
else
{
nums = nums.Where(c => c == n || c % n != 0).ToArray();
return colador(n + 1);
}
};
colador(2);
nums.ToList().ForEach(c => Console.Write(c.ToString() + " "));
// el primer intento es una shit, modifica un array que está fuera de la función lambda.
// Acá viene el segundo intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador2 = null;
IEnumerable<int> nums2 = Enumerable.Range(2, 48);
colador2 = (n, x) =>
{
if (n == 8)
return x;
else
{
x = x.Where(c => c == n || c % n != 0);
return colador2(n + 1, x);
}
};
nums2 = colador2(2, nums2);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));
// el segundo intento aún es demasiado legible.
// Acá va el tercer intento:
Func<int, IEnumerable<int>, IEnumerable<int>> colador3 = null;
IEnumerable<int> nums3 = Enumerable.Range(2, 48);
colador3 = (n, x) =>
{
x = x.Where(c => c == n || c % n != 0);
return (n < 8) ? colador3(n + 1, x) : x;
};
nums3 = colador3(2, nums3);
Console.WriteLine();
nums2.ToList().ForEach(c => Console.Write(c.ToString() + " "));
Console.ReadLine();
El resultado es:
viernes, 6 de julio de 2018
Cómo obtener información de la Distro de Linux
>cat /etc/lsb-release
Me da el nombre y la versión de la distro.
>uname -a
Me dice si es de 32 o 64 bits.
A continuación muestro la información que dan estos comandos en distintos Ubuntus gracias a la magia de VirtualBox :D
Si dice "x86_64" es de 64 bits. Este Ubuntu vino con Unity.
Otra de 64 bits. Éste es Ubuntu Mate.
Este es un Ubuntu de 32 bits con xfce. Si es de 32 bits, uname sólo mostrará "i686".
Este es un Xubuntu 14 de 32 bits.
Debo añadir que estos comandos no dan información acerca del entorno de escritorio que se está usando.
viernes, 25 de mayo de 2018
Beamer: Error "Missign $ insert" al dejar líneas en blanco dentro de las etiquetas para ecuaciones
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beamer Presentation
% LaTeX Template
% Version 1.0 (10/11/12)
%
% This template has been downloaded from:
% http://www.LaTeXTemplates.com
%
% License:
% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{beamer}
\mode
\usetheme{Madrid}
}
\usepackage[utf8]{inputenc}
\usepackage{graphicx} % Allows including images
\usepackage{booktabs} % Allows the use of \toprule, \midrule and \bottomrule in tables
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{geometry}
\title[Sample1]{This is a sample Title}
\author{Y0} % Your name
\institute[LOL] % Your institution as it will appear on the bottom of every slide, may be shorthand to save space
{
LOL University \\ % Your institution for the title page
\medskip
\textit{mail@mail.com} % Your email address
}
\date{\today} % Date, can be changed to a custom date
\begin{document}
\begin{frame}
\frametitle{A Title}
Texto texto texto
\[
\frac{\partial u}{\partial t} + \frac{\partial^{2}u}{\partial x^{2}}
\]
\begin{equation}
f_{i} + \sum\limits_{k=k_{min}}^{k=k_{max}} a_k f_{i+k}
\end{equation}
\begin{align}
f_{i} + \sum\limits_{k=k_{min}}^{k=k_{max}} a_k f_{i+k}
\end{align}
\end{frame}
\end{document}
Y, mientras lo editaba, de pronto el compilador de latex empezó a protestar con el error "Missign $ insert". Aparentemente el documento no tenían errores. Me tomó buen rato encontrar que se generaba con las líneas en blanco que había dejaado donde latex no las admite.
Para generar el error "Missign $ insert" se deben dejar líneas en blanco en las siguientes secciones (las que contienen ecuaciones):
He aquí el error:
Esto es discutido en los foros de Latex desde hace tiempo, y hasta ahora no parece haber solución más que eliminar todas las líneas en blanco entre las etiquedas que usen modo matemático.
viernes, 20 de abril de 2018
Cómo darle privilegios de sudo a un usuario en Centos 7
Esto es un resumen de 5 páginas web que explicaban cómo darle privilegios de sudo a un usuario con la terminal, a qué grupo añadirlo (no hay grupo "sudo" o "sudoers" en Centos) y cómo trabajar con el visudo, el editor que nos permitirá modificar los privilegios sin que haya condiciones de carrera con otros usuarios logueados.
En Centos, el grupo equivalente al "sudoers" es "wheel". Tengo un usuario llamado "pc" el cual quiero que pueda ejecutar comandos de "sudo", pero en mi instalación de Centos por defecto "pc" no tiene privilegios, y tampoco los tiene el grupo "wheels".
Para empezar a dar privilegios, primero hay que loguearse en la terminal como root con el comando su root, y luego ejecutar visudo:
Una vez dentro del visudo, con las teclas del cursos buscamos la línea donde dice "allows people in group wheel to run all commands", la siguiente línea es la que le da privilegios al grupo "wheel". Si empieza con el caracter #, está comentada y debemos borrarlo:
Yo prefiero ir hasta el final del archivo para guardar y salir, esto se hace con el comando :wq
Luego se ejecuta el comando usermod -aG wheel pc el cual añadirá el usuario "pc" al grupo wheel:
Y eso es todo! Si el usuario sigue sin poder ejecutar comandos de sudo se debe reiniciar el sistema.
Lo he probado en Centos 7, pero también debería funcionar en Centos 6.
En Centos, el grupo equivalente al "sudoers" es "wheel". Tengo un usuario llamado "pc" el cual quiero que pueda ejecutar comandos de "sudo", pero en mi instalación de Centos por defecto "pc" no tiene privilegios, y tampoco los tiene el grupo "wheels".
Para empezar a dar privilegios, primero hay que loguearse en la terminal como root con el comando su root, y luego ejecutar visudo:
Una vez dentro del visudo, con las teclas del cursos buscamos la línea donde dice "allows people in group wheel to run all commands", la siguiente línea es la que le da privilegios al grupo "wheel". Si empieza con el caracter #, está comentada y debemos borrarlo:
Yo prefiero ir hasta el final del archivo para guardar y salir, esto se hace con el comando :wq
Luego se ejecuta el comando usermod -aG wheel pc el cual añadirá el usuario "pc" al grupo wheel:
Y eso es todo! Si el usuario sigue sin poder ejecutar comandos de sudo se debe reiniciar el sistema.
Lo he probado en Centos 7, pero también debería funcionar en Centos 6.
sábado, 31 de marzo de 2018
Generar archivos .pyc en Python para Windows
La pregunta original la hice aquí.
En python 2.7 genero mis archivos .pyc con esta línea:
y hasta me hice un script para compilar todos los archivos .py en una carpeta determinada:
import sys;
import subprocess;
from os import listdir
from os.path import isfile, join
[subprocess.call('python -m compileall ' + p, shell=True) for p in listdir('D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]
Esto no funciona en Python 2.6. En python 2.6 los genero con:
El script para compilar todos los archivos .py en una carpeta determinada sería:
import sys;
import subprocess;
from os import listdir
from os.path import isfile, join
[subprocess.call('C:\Python26\python -m py_compile ' + p, shell=True) for p in listdir('D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]
En este enlace, explican qué significa Shell=True y en la documentación advierten sobre su uso.
En python 2.7 genero mis archivos .pyc con esta línea:
python -m compileall C:\una_ruta\myscript.py
y hasta me hice un script para compilar todos los archivos .py en una carpeta determinada:
import sys;
import subprocess;
from os import listdir
from os.path import isfile, join
[subprocess.call('python -m compileall ' + p, shell=True) for p in listdir('D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]
Esto no funciona en Python 2.6. En python 2.6 los genero con:
C:\Python26\python -m py_compile C:\una_ruta\myscript.py
El script para compilar todos los archivos .py en una carpeta determinada sería:
import sys;
import subprocess;
from os import listdir
from os.path import isfile, join
[subprocess.call('C:\Python26\python -m py_compile ' + p, shell=True) for p in listdir('D:\una_ruta') if isfile(join('D:\una_ruta', p)) and p.endswith('.py')]
En este enlace, explican qué significa Shell=True y en la documentación advierten sobre su uso.
domingo, 28 de enero de 2018
Abrir y pasarle parámetros a una ventana secundaria desde Java swing en Netbeans
Lo que se necesita en esta ocasión es que al presionar un botón de una ventana en Java Swing, se abra una ventana secundaria una sola vez sin importar cuántas veces se presione el botón, que al cerrar sólo la ventana secundaria la ventana pricipal continúe ejecutandose, y que ambas ventanas se cierren y el programa finalice al cerrar la ventana principal. Además tengo que pasarle parámetros desde la ventana principal a la ventana secundaria al abrirse ésta:
Hacerlo es bastante fácil, se deben crear dos ventanas, la principal frmMain y la secundaria frmOther, ambas del tipo JFrame:
En la ventana principal se declara a nivel de clase:
frmOther formOther;
Y en el listener del botón que abre la ventana secundaria se ingresa el siguiente código:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
if (formOther == null || !formOther.isVisible())
{
formOther = new frmOther("Nuevo ", "Título");
formOther.setVisible(true);
}
else
formOther.setExtendedState(JFrame.NORMAL);
}
En este caso la ventana secundaria recibe dos parámetros tipo String, pero se puede hacer que reciba cualquier cantidad y tipo de parámetros, para esto basta sobrecargar el constructor en la clase de la ventana secundaria (en este caso sólo voy a cambiar el título):
public frmOther(String param1, String param2)
{
initComponents();
this.setTitle(param1 + param2);
}
Por último, en la propiedad DefaultCloseOperation de la ventana secundaria se escoge DISPOSE.
Y eso es todo!
El proyecto en Netbeans 8.0.2 se puede descargar de aquí.
Hacerlo es bastante fácil, se deben crear dos ventanas, la principal frmMain y la secundaria frmOther, ambas del tipo JFrame:
En la ventana principal se declara a nivel de clase:
frmOther formOther;
Y en el listener del botón que abre la ventana secundaria se ingresa el siguiente código:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
if (formOther == null || !formOther.isVisible())
{
formOther = new frmOther("Nuevo ", "Título");
formOther.setVisible(true);
}
else
formOther.setExtendedState(JFrame.NORMAL);
}
En este caso la ventana secundaria recibe dos parámetros tipo String, pero se puede hacer que reciba cualquier cantidad y tipo de parámetros, para esto basta sobrecargar el constructor en la clase de la ventana secundaria (en este caso sólo voy a cambiar el título):
public frmOther(String param1, String param2)
{
initComponents();
this.setTitle(param1 + param2);
}
Por último, en la propiedad DefaultCloseOperation de la ventana secundaria se escoge DISPOSE.
Y eso es todo!
El proyecto en Netbeans 8.0.2 se puede descargar de aquí.
Suscribirse a:
Entradas (Atom)