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:
sábado, 10 de diciembre de 2016
Reemplazando subcadenas dentro de archivos de texto con Python
El siguiente ejemplo muestra cómo se ven mis scripts de Inno Setup, en la realidad incluyen muchos muchos más archivos (tomado de los ejemplos que vienen con el Inno Setup):
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
Compression=lzma2
SolidCompression=yes
OutputDir=D:\Generated Installers\
[Files]
Source: "D:\compiled_2014\MyProg.exe"; DestDir: "{app}"
Source: "D:\compiled_2014\MyProg.chm"; DestDir: "{app}"
Source: "D:\compiled_2014\Readme.txt"; DestDir: "{app}"; Flags: isreadme
[Icons]
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"
Para evitar tener que hacer el cambio de rutas a mano, me creé este script en Python:
import os
import sys
iss = [c for c in os.listdir(sys.path[0]) if ".iss" in c]
for i in iss:
fopen = open(i,'r')
fwrite = []
flines = fopen.readlines()
fopen.close()
for line in flines:
fwrite.append(line.replace("D:\compiled_2014", "F:\compiled_Octubre_2016"))
fopen = open(i,'w')
fopen.writelines(fwrite)
fopen.close()
Lo que hace este script en Python es reemplazar la ruta antigua (en este ejemplo "D:\compiled_2014") por la nueva ruta "F:\compiled_Octubre_2016" de todos los archivos .iss que encuentre en la misma carpeta donde está ubicado.
Finalmente, el script en Inno Setup queda así:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
Compression=lzma2
SolidCompression=yes
OutputDir=D:\Generated Installers\
[Files]
Source: "F:\compiled_Octubre_2016\MyProg.exe"; DestDir: "{app}"
Source: "F:\compiled_Octubre_2016\MyProg.chm"; DestDir: "{app}"
Source: "F:\compiled_Octubre_2016\Readme.txt"; DestDir: "{app}"; Flags: isreadme
[Icons]
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"
lunes, 28 de noviembre de 2016
Imprimir caracteres en consola con Visual C++
#include "stdafx.h"
#include <iostream>
#include
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char* chararr = new unsigned char[256];
// ... asigno valores al array de caracteres...
string str;
str.assign((char*)chararr);
cout << "Look, I'm writting string values";
cout << str << "\n";
cout << "Look, I'm writting hexadecimal values";
for (unsigned long i = 0; i < 256; i++)
printf("%02X ", chararr[i]);
printf("\n");
}
martes, 25 de octubre de 2016
Cómo obtener información de la distro de Linux con Python 2.7
import platform
import subprocess
print platform.architecture()
print platform.linux_distribution()
ret = subprocess.call('java -version', shell = True)
A continuación está lo que me imprimieron algunas distros:
centos 7 x64 por defecto:
('64bit', 'ELF')
('centos', '7.1.1503', 'Core')
java version "1.7.0_91"
OpenJDK Runtime Environment (rhel-2.6.2.1.el7_1-x86_64 u91-b00)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)
Centos 6 x64 con Oracle Java 8:
('64bit', 'ELF')
('centos', '6.5', 'Final')
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
Ubuntu 14 x32 con Oracle Java 8:
('32bit', 'ELF')
('Ubuntu', '14.04', 'trusty')
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Server VM (build 25.65-b01, mixed mode)
Linux Mint 17 x32 por defecto:
('32bit', 'ELF')
('LinuxMint', '17.2', 'rafaela')
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.5) (7u79-2.5.5-0ubuntu0.14.04.2)
OpenJDK Server VM (build 24.79-b02, mixed mode)
Codingground webpage ide:
('64bit', '')
('Fedora', '23', 'Twenty Three')
openjdk version "1.8.0_72"
OpenJDK Runtime Environment (build 1.8.0_72-b15)
OpenJDK 64-Bit Server VM (build 25.72-b15, mixed mode)
Ideone webpage ide:
('32bit', '')
('debian', 'stretch/sid', '')
viernes, 2 de septiembre de 2016
Cómo evitar que C++ decore los nombres de las funciones de una dll
http://stackoverflow.com/q/2804893
http://stackoverflow.com/q/1467144
Mi caso era que estaba compilando una dll en c++ con Visual Studio Express 2013 y encontré que, al intentar invocarla desde otra aplicación, el compilador decoraba los nombres de las funciones.
Para evitarlo, se deben declarar las funciones con extern "C":
En el archivo .h:
extern "C" __declspec (dllexport) long SomeFunction(int param);
Y en el archivo .cpp respectivo:
extern "C"
__declspec (dllexport) long SomeFunction(int param)
{
return _somethingIwantToDo(param);
}
si se está depurando, es mejor dejar la opción de "Generar Información de Depuración" en "Si" o el depurador empezará a protestar:
Al colocar extern "C" el compilador ya no decora los nombres de las funciones aunque la convención de llamada sea stdcall o cdecl:
Eso sí, la convención de llamada de la dll y la aplicación que la invoca debe ser la misma, o el compilador arrojará el error LNK2019 y de paso el LNK1120:
Cómo crear una ventana modal que envíe datos ingresados por el usuario en Java Swing
http://stackoverflow.com/a/28461883
http://stackoverflow.com/a/4089370
En Netbeans, para poder crear una ventana modal para nuestra aplicación de Swing, se debe crear un nuevo JFrame Form, y en la línea donde se declara la clase:
public class JModalFrame extends javax.swing.JFrame
cambiarla por:
public class JModalFrame extends javax.swing.JDialog
y en el constructor se debe poner:
setModal(true);
Luego de añadir un área de texto, un checkbox y un botón a la ventana modal, el código para poder retornar valores desde esta ventana es:
Object[] thoseValues;
public Object[] showDialog()
{
return thoseValues;
}
public JModalFrame()
{
setModal(true);
thoseValues = new Object[2];
initComponents();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
thoseValues[0] = jCheckBox1.isSelected();
thoseValues[1] = jTextArea1.getText();
setModal(false);
this.setVisible(false);
}
Para abrir la ventana modal, se debe añadir el siguiente código en la ventana principal (en mi caso, es la ventana que está declarada como la clase main en las propiedades del proyecto en Netbeans):
JModalFrame jMod = new JModalFrame();
jMod.setVisible(true);
Object[] thosevalues = jMod.showDialog();
jMod.dispose();
Se pueden recibir cualquier tipo de valores, yo he elegido un array de objetos.
Si se desea que la ventana modal aparezca en la barra de tareas se debe añadir el siugiente código en su constructor:
// http://stackoverflow.com/a/14261194
super(null, java.awt.Dialog.ModalityType.TOOLKIT_MODAL);
lunes, 29 de agosto de 2016
Cómo hacer un Select en un Datatable con campos tipo DateTime
Tengo un DataTable con dos campos "BirthDay" y "HireDay" del tipo DateTime, y quiero filtrar las filas que correspondan a dos fechas determinadas.
Siguiendo las instrucciones de este enlace armé mi query de la siguiente manera:
DateTime hday = new DateTime(2016, 8, 10);
String query =
String.Concat("BirthDay=#", Convert.ToString(bday.Date), "# or HireDay=#", Convert.ToString(bday.Date), "#");
DataRow[] encontrados = miDatatable.Select(query);
Al ejecutar mi aplicación me lanza esta excepción:
Excepción no controlada del tipo 'System.FormatException' en mscorlib.dll
Información adicional: La cadena no se reconoce como DateTime válido. Hay una palabra desconocida al inicio del índice 24.
En cambio, si cambio manualmente el valor de la variable
query
a:"BirthDay=#09/08/2016# or HireDay=#10/08/2016#"
no me tira excepción, pero ya no me devuelve ninguna fila, a pesar de
que sí tengo fechas en los campos "BirthDay" y "HireDay" iguales al 9
de agosto del 2016.La solución me la dio Leandro Tuttini, el formato de fecha debe ser en-US, independientemente de la configuración regional del sistema operativo. La variable query debe armarse de la siguiente forma:
DateTime bday = new DateTime(2016, 8, 9);
DateTime hday = new DateTime(2016, 8, 10);
string query = string.Format("BirthDay=#{0:MM/dd/yyyy}# or HireDay=#{1:MM/dd/yyyy}#", bday, hday);
DataRow[] encontrados = miDatatable.Select(query);
viernes, 22 de julio de 2016
Cambiando la codificación de un archivo de Python en Python Tools for Visual Studio 2013 Express
1. En la primera línea le ponemos la codificación deseada, en este caso es "# coding=utf-8". La codificación debe ir con el símbolo de numeral para que el intérprete la reconozca:
2. Vamor a Archivo->Guardar como...
3. Elegimos "Guardar con codificación..."
4. Elegimos la codificación "Unicode UTF-8":
De esta forma el intérprete no tirará error al poner comentarios con caracteres internacionales.
martes, 7 de junio de 2016
Detectar si un puerto está abierto en un host específico.
from socket import *
import sys
# http://serverfault.com/a/311580
if __name__ == "__main__":
fTimeOutSec = 1
sNetworkAddress = sys.argv[1].split(":")[0]
aiPort = sys.argv[1].split(":")[1]
setdefaulttimeout(fTimeOutSec)
print ("Starting Scan...")
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((sNetworkAddress, int(aiPort)))
if (result == 0):
print ("OPEN: " + sNetworkAddress + ":" + aiPort)
elif (10035 == result):
print ("Timeout or inexistent host")
pass
else:
print ("closed: " + sNetworkAddress + ":" + aiPort)
s.close()
print ("Scan Completed.")
He puesto el script en un archivo llamado "scan_port.py", y los argumentos que se le pasan son la ip y el puerto separados por dos punto, es decir, de la siguiente manera: "ip:puerto":
Aquí estoy probando con localhost, pero también funciona para ips remotas.
sábado, 21 de mayo de 2016
Error en Visual Studio 2013, no se encontraron exportaciones que coincidieran con la restricción: ContractName
"Error en Visual Studio 2013, no se encontraron exportaciones que coincidieran con la restricción: ContractName".
La solución se encuentra
sábado, 23 de abril de 2016
Gráfica del Movimiento Browniano unidimensional en Python
El código para generar la gráfica del Movimiento Browniano fue traducido del Matlab al Python a partir del código del capítulo 2 del libro "Stochastic Diferential Equations: Models and Numerics" de Jesper Carlsson, Kyoung-Sook Moon, Anders Szepessy, Raúl Tempone y Georgios Zouraris. Además, como ejercicio, quise implementar mi propia función de suma acumulada "cumsum". El código resultante es el siguiente:
import numpy as np
import math
import matplotlib.pyplot as plt
def cumsum(lista):
lista2 = [lista[0]]
for i in range(1, len(lista)):
lista2.append(lista[i] + lista2[-1])
return lista2
N = 1E6
np.random.seed(1337)
A = np.random.normal(0, 1, N-1)
T = 1
dt = 1/(N-1)
t = [c/(N-1) for c in range(0, int(N-1))]
dW = [c*math.sqrt(dt) for c in A]
W = cumsum(dW)
# Aqui se requiere Numpy y Mathplotlib
plt.plot(W)
plt.ylabel('Brownian Motion')
plt.show()
'''
N = 1E6; % number of timesteps
randn('state',0); % initialize random number generator
T = 1; % final time
dt = T/(N-1); % time step
t = 0:dt:T;
dW = sqrt(dt)*randn(1,N-1); % Wiener increments
W = [0 cumsum(dW)]; % Brownian path
LHS = sum(t(1:N-1).*dW);
RHS = T*W(N) - sum(W(1:N-1))*dt;
'''
Para instalar Numpy y Matplotlib se debe bajar el archivo get-pip.py de este enlace. Y se debe ejecutar en la terminal (para Linux) o en el CMD (para Windows) la siguiente instrucción:
python get-pip.py
Si es Linux es mejor poner:
sudo python get-pip.py
La terminal o el CMD deben apuntar a la carpeta donde está el archivo get-pip.py.
Luego se debe instalar numpy y matplotlib. En Linux se ingresa los comandos:
pip install matplotlib
pip install numpy
Si no recuerdo mal, Matplotlib también instala Numpy.
En Windows, como soy muy floja, me descargué el pip-Win e ingresé los respectivos comandos en la caja de texto donde pide el comando:
Éste es el resultado. Estoy usando Python Tools for Visual Studio:
jueves, 17 de marzo de 2016
Calculando el MCD de dos números con el algoritmo de Euclides en Prolog
Blatant Copy/Paste:
La lógica de Prolog es la siguiente: devuelve el valor de retorno en la variable del extremo derecho. La coma es el AND lógico, y el punto y coma el OR lógico. Cada declaración de la función "mcd" equivale a un if.
End of Blatant Copy/Paste
Si el valor en la variable B es 0 ó 1, el algoritmo ignora el valor de A y retorna 0 ó 1 según corresponda. Si no es así, evalúa si A es menor a B, si es así intercambia los valores de A y B, y luego realiza las restas sucesivas como indica el algoritmo. En el algoritmo de Euclides se suele usar un bucle, pero en Prolog se debe utilizar recursividad.
He aquí el código:
mcd(_, 0, 0).
mcd(_, 1, 1).
mcd(A, B, X):- A < B, mcd(B,A,X).
mcd(A, B, X):- N is A - B, N =:= 0, X is B.
mcd(A, B, X):- N is A - B, N =:= B, X is B.
mcd(A, B, X):- N is A-B, N < B, mcd(B, N, X).
mcd(A, B, X):- N is A-B, N > B, mcd(A, N, X).
Estoy usando SWI Prolog 7.2.
miércoles, 10 de febrero de 2016
Visualizar imágenes en Sql Server Management Studio con SSMSBoost
Rebuscando en internet hallé un add-on que sí lo permite: el SSMSBoost, el cual tiene una versión Community gratuita que se puede usar para todo, sólo hay que reinstalarla cada tres meses.
Luego de instalarlo, y para poder ver las imágenes, se deben seguir los siguientes pasos:
1. Escoger la tabla con las imágenes y elegir la opción "Visualizar los primeros 1000 registros" haciendo clc derecho (en realidad se debe hacer un select).
2. Hacer click derecho al registro con la imagen que queremos ver, escoger la opción "Visualize as->Settings"
3. En la opción "Picture (any format)", el formato de imagen se coloca png, pues si se deja el valor por defecto (dat) el mspaint no lo va a reconocer:
Esto hace que mspant pueda abrir imágenes png, gif y jpg (no he probado con otros formatos, pero debe funcionar).
4. Luego de presionar el botón "Apply" o "Apply & Close", se escoge la opción "Visualize as->Picture (any format)".
Éste es el resultado:
domingo, 17 de enero de 2016
Implementación del Chatbot Eliza en Prolog
El algoritmo, que permite que Eliza genere una respuesta acorde a las consultas del usuario, se basa en comparar término a término la data ingresada versus una lista de templates con las respuestas predefinidas. Las ideas iniciales para desarrollar este algoritmo fueron obtenidas de [2] y de [3], a partir de estas fuentes se realizó una implementación propia.
El formato de cada template es el siguiente:
template([lista con las palabras del estímulo], [lista con las palabras de la respuesta de Eliza], [lista con las posiciones de las palabras clave en el estímulo empezando de cero]).
Un template de ejemplo tendrá la forma:
Las palabras clave le permiten a Eliza generar una
coincidencia para diferentes listas de palabras, tales como “i am sad.” o “i am
angry.”. Las palabras claves se reemplazarán en la respuesta en las posiciones
donde hay números y no palabras.
La función que realiza la comparación es la función “match”.
En el estímulo, las palabras clave están marcadas por predicados, mientras que
el resto de los términos son atómicos. Cuando la función match detecta un dato
no atómico, usando la función de SWI-Prolog “atom”, lo ignora y continúa con la
comparación término a término entre la data ingresada y el estímulo. Si se
encuentra un template que coincida, devolverá la respuesta correspondiente y la
lista de índices. Los índices deben coincidir con las posiciones de los datos no
atómicos en el estímulo del template.
La función “replace0” se encarga de reemplazar las palabras claves de la data ingresada en las posiciones donde la respuesta del template tiene números. Las palabras clave pueden ser una o más. Para saber qué palabra clave corresponde a qué posición en la respuesta, los números se van incrementando de uno en uno. Si no hay palabras para reemplazar, la lista de índices será una lista vacía.
Esta función llama a las siguientes funciones ya implementadas en SWI-Porlog:
nth0: devuelve el elemento de una lista en una posición dada.
select: reemplaza el valor de un elemento de una lista por otro en función a sus valores.
append: concatena dos listas. En este caso va concatenando
las palabras de la respuesta, junto con la palabra reemplazada en la posición
donde hay un número, palabra por palabra.
La función “replace0” también genera las respuestas a
preguntas y consultas del tipo “do you like ...?”, “you are ...” y “do you (verb)
...?”. Los templates correspondientes tienen el siguiente formato:
Si la función “replace0” detecta una de las banderas (flags) configuradas, buscará la respuesta correspondiente en las funciones elizaDoes, elizaIs y ElizaLikes, las cuales evalúan los hechos que determinan si Eliza hace, es o le gusta algo.
El código donde se declaran estos hechos es el siguiente:
El código que le permite al usuario ingresar sus consultas es el siguiente:
La función “readln” convierte las consultas del usuario en
una lista. Luego el programa escogerá el primer template de la base del
conocimiento, a continuación el estímulo de ese template, y la consulta del
usuario (Input), son ingresados a la función “match”. Si el estímulo no coincide
con la consulta, Prolog empezará el backtracking, escogiendo el siguiente
template y repitiendo la operación. El último template de la base de
conocimiento hace que la función “match” retorne verdadero si ninguno de los
otros estímulos de los otros templates coincide con la consulta del usuario.
Esto evita que se rompa el bucle de Eliza y finalice el programa de forma
abrupta. A continuación se llama a la función “replace0”, para luego imprimir la
respuesta en la pantalla. Eliza seguirá esperando las consultas del usuario
mientras éste no ingrese “bye” o “bye.”.
II
Conversando con Eliza
Para interactuar con el programa Eliza, se debe ejecutar el intérprete SWI-Prolog,
abrir el archvo eliza_complete.pl y compilarlo. En la consola de SWI-Prolog se
deberá ingresar “eliza.” Eliza mostrará un mensaje de bienvenida y esperará por
más consultas del usuario. Éstas deben estar en minúsculas y tener un punto al
final.
Una conversación de ejemplo es la siguiente:
Eliza da las respuestas en forma de listas de palabras, separadas por comas y entre corchetes. Se mantuvo este formato porque en una aplicación Eliza real, es muy probable que las respuesta halladas requieran un procesamiento posterior.
La aplicación ha sido probada en SWI-Prolog versión 7.2.1. No se ha probado en versiones anteriores. No funcionará en versiones de SWI-Prolog que no tengan implementadas las funciones length, nth0, atom y select.
Esta implementación de Eliza no tiene memoria, es decir, no recuerda las
consultas ingresadas y sus respuestas, por lo que la coherencia de la
conversación depende del usuario. Por ejemplo, para Eliza es válido ingresar
primero la consulta “because you are creepy.” Y luego “i hate you.”.
Para ampliar las respuestas de Eliza a más estímulos basta crear más templates con los formatos ya mencionados.
En este programa, la aparente inteligencia de Eliza está en función a la
amplitud de su base de conocimientos. Como la coincidencia de las consultas del
usuario y los estímulos se realiza término a término, la base de conocimiento de
Eliza debe ser bastante grande para producir una conversación coherente, y poder
respetar género, número, tiempos verbales, etc. Un programa más completo
consideraría toda una lista de palabras clave en lugar de sólo una.
El código completo es (Escrito en Prolog y probado en Swi Prolog v7.2.):
% by: Y3l1nna_Broken_Window: % la función match permite crear un output para varios inputs. eliza:- writeln('Hi, I am Eliza your chatbot, please enter your query, use only lowercases and a dot at the end:'), readln(Input), eliza(Input),!. eliza(Input):- Input == ['bye'], writeln('Goodbye. I hope I have helped you.'), !. eliza(Input):- Input == ['bye', '.'], writeln('Goodbye. I hope I have helped you.'), !. eliza(Input) :- template(Stim, Resp, IndStim), match(Stim, Input), % si he llegado aquí es que he % hallado el template correcto: replace0(IndStim, Input, 0, Resp, R), writeln(R), readln(Input1), eliza(Input1), !. % algunos saludos % debido al backtracking, los templates más específicos deben ir antes % de los más genéricos. Eso se nota acá: template([hi, my, name, is, s(_), '.'], ['Hi', 0, 'How', are, you, '?'], [4]). template([hello, my, name, is, s(_), '.'], ['Hello', 'How', are, you, 0, '?'], [4]). template([hi, ',', my, name, is, s(_), '.'], ['Hi', 0, 'How', are, you, '?'], [5]). template([hello, ',', my, name, is, s(_), '.'], ['Hello', 'How', are, you, 0, '?'], [5]). template([hi, _], ['Hi', 'How', are, you, '?'], []). template([hello, _], ['Hello', 'How', are, you, '?'], []). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% template([i, s(_), i, am, s(_),'.'], [why, do, you, 0, you, are, 1, '?'], [1, 4]). template([i, s(_), you, '.'], [why, do, you, 0, me ,'?'], [1]). template([i, am, s(_),'.'], [why, are, you, 0, '?'], [2]). % pregunta algo que le gusta a eliza template([do, you, like, s(_), _], [flagLike], [3]). % pregunta algo que hace eliza template([do, you, s(_), _], [flagDo], [2]). % pregunta algo que es eliza template([you, are, s(_)], [flagIs], [2]). template([are, you, s(_), '?'], [flagIs], [2]). template([how, are, you, '?'], [i, am, fine, ',', thanks, for, asking, '.'], []). template([i, think, _], [well, that, is, just, your, opinion], []). template([because, _], [that, is, not, a, good, reason, '.'], []). template([i, have, s(_), with, s(_), '.'], ['You', have, to, deal, with, your, 0, and, your, 1, in, a, mature, way, '.'], [2, 4]). template([i, s(_), _], [i, can, recommend, you, a, book, about, that, issue], []). template([please, s(_), _], ['No', i, can, not, help, ',', i, am, just, a, machine], []). % didn't passed the Turing Test template([tell, me, a, s(_), _], ['No', i, can, not, ',', i, am, bad, at, that], []). % classic AI problem: una máquina aún no puede contar una historia coherente. template(_, ['Please', explain, a, little, more, '.'], []). % cuando se ingresa algo que Eliza no tiene en sus templates, esto debe ir al final o eliza responderá a todo con esto. % Lo que le gusta a eliza : flagLike elizaLikes(X, R):- likes(X), R = ['Yeah', i, like, X]. elizaLikes(X, R):- \+likes(X), R = ['Nope', i, do, not, like, X]. likes(apples). likes(ponies). likes(zombies). %%%%%%%%%%%%%%%%%%%%%% % lo que hace eliza: flagDo elizaDoes(X, R):- does(X), R = ['Yes', i, X, and, i, love, it]. elizaDoes(X, R):- \+does(X), R = ['No', i, do, not, X ,'.', it, is, too, hard, for, me]. does(study). does(cook). does(work). %%%%%%%%%%%%%%%%% % lo que es eliza: flagIs elizaIs(X, R):- is0(X), R = ['Yes', i, am, X]. elizaIs(X, R):- \+is0(X), R = ['No', i, am, not, X]. is0(dumb). is0(weird). is0(nice). is0(fine). is0(happy). is0(redundant). % http://stackoverflow.com/questions/12939425/prolog-access-specific-member-of-list % magic happens here :D % lo que hace match es comparar el input y el estímulo término a % término, ignorando los s(X) en cada template. Si match falla en el % loop de la función eliza, empezará el backtracking que permite % recorrer los templates ingresados. match devolverá verdadero si haya % un estímulo (primer término del template) que coincide con el Input, y % devolverá la respuesta. match([],[]). match([], _):- true. match([S|Stim],[I|Input]) :- atom(S), % si I es un s(X) devuelve falso S == I, match(Stim, Input),!. match([S|Stim],[_|Input]) :- % I es un s(X), lo ignoro y continúo con el resto de la lista \+atom(S), match(Stim, Input),!. % esta función es para que se muestre bien en pantalla las respuestas de % eliza. Además responde a lo que le gusta Eliza y a lo que hace, la % función select reemplaza el número en la respuesta por la palabra % clave hallada: replace0([], _, _, Resp, R):- append(Resp, [], R),!. % Eliza likes: replace0([I|_], Input, _, Resp, R):- nth0(I, Input, Atom), nth0(0, Resp, X), X == flagLike, elizaLikes(Atom, R). % Eliza does: replace0([I|_], Input, _, Resp, R):- nth0(I, Input, Atom), nth0(0, Resp, X), X == flagDo, elizaDoes(Atom, R). % Eliza is: replace0([I|_], Input, _, Resp, R):- nth0(I, Input, Atom), nth0(0, Resp, X), X == flagIs, elizaIs(Atom, R). replace0([I|Index], Input, N, Resp, R):- length(Index, M), M =:= 0, nth0(I, Input, Atom), select(N, Resp, Atom, R1), append(R1, [], R),!. replace0([I|Index], Input, N, Resp, R):- nth0(I, Input, Atom), length(Index, M), M > 0, select(N, Resp, Atom, R1), N1 is N + 1, replace0(Index, Input, N1, R1, R),!.
sábado, 9 de enero de 2016
Listar los archivos en una carpeta y sus subcarpetas de forma recursiva v2
import os
import sys
from os import listdir
from os.path import isfile, isdir, join
def listdir_recurd(files_list, root, folder, checked_folders):
if (folder != root):
checked_folders.append(folder)
for f in listdir(folder):
d = join(folder, f)
if isdir(d) and d not in checked_folders:
listdir_recurd(files_list, root, d, checked_folders)
else:
if isfile(d): # si no hago esto, inserta en la lista el nombre de las carpetas ignoradas
files_list.append(join(folder, f))
return files_list
Esta vez, la función devuelve las rutas completas de solamente los archivos que va encontrando, ignorando las carpetas y subcarpetas. Yo necesité esta función para borrar archivos de prueba que generaba otra aplicación, dejando sólo las carpetas vacías:
if __name__ == "__main__":
# filez = listdir_recurd([], 'D:\test0', 'D:\test0', []) # esto lista todos los archivos
# filez = listdir_recurd([], 'D:\test', 'D:\test', ['D:\\test\\t1', 'D:\\test\\t2']) # esto omite las carpetas 'D:\\test\\t1' y 'D:\\test\\t2'
# filez = listdir_recurd([], 'D:\test', 'D:\test', ['D:\\test\\t1']) # esto omite la carpeta 'D:\\test\\t1'
filez = []
for f in sys.argv[1:]:
if os.path.exists(f):
filez += listdir_recurd([], f, f, [])
# la línea siguiente es la que hay que temer, borrará todo lo que se haya encontrado
# si por error se ingresa un directorio raíz... lo borrará todo, dejando las carpetas vacías!!
[os.remove(c) for c in filez if os.path.exists(c)]
print 'Files Deleted!!'
Como estoy usando Python Tools For Visual Studio, el script se debe setear como Startup File haciéndole click derecho en el explorador de soluciones. Las carpetas cuyos archivos se desean eliminar se ingresan como:
Hay que tener cuidado al borrar archivos con este método ya que no van a la papelera de reciclaje.