Mostrando entradas con la etiqueta programación. Mostrar todas las entradas
Mostrando entradas con la etiqueta programación. Mostrar todas las entradas

miércoles, 7 de julio de 2010

javascript:grayInfo();

Para terminar la semana y colorearte la vida (?), acá va una función javascript:

function grayInfo() {
var table = ui.getTable("contentTable");
var codFam = table.getKeyVal("codeFamille");
var grpSil = table.getKeyVal("groupeSilhouette");
var codSil = table.getKeyVal("codeSilhouette");
var cells = document.getElementById("contentTable").getElementsByTagName("td");

for (var i=0; i<cells.length; i++) {
if (cells[i].style.color == "gray") {
cells[i].removeAttribute("style");
cells[++i].removeAttribute("style");
cells[++i].removeAttribute("style");
}
if (cells[i].innerHTML==codFam && cells[i+1].innerHTML==grpSil &&
cells[i+2].innerHTML==codSil) {
cells[i].style.color = "gray";
cells[++i].style.color = "gray";
cells[++i].style.color = "gray";
}
}
}


Algún día editaré y explicaré que hace exactamente esta verga. Pero capaz mientras te sirve (?)

Update: la función tenía un bug (!) y ya fue arreglado

viernes, 25 de junio de 2010

BD Oracle: constraints, sequence, For en PL/SQL

Constraints
Como vemos las constraints de una tabla en una base de datos Oracle? Así:
SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'nombre_tabla'

También hay otras queries utiles por si esa no te sirve:
select * from user_cons_columns
select * from all_cons_columns
select * from all_constraints

Sequence value
Para obtener el valor de una secuencia se ejecuta lo siguiente:
SELECT nombre_de_la_secuencia.CURRVAL FROM dual

Puede que ese comando te tire un error 08002 que indica que la secuencia no está definida en la sesión. Esto se soluciona facilmente llamando al siguiente valor de la secuencia:
SELECT nombre_de_la_secuencia.NEXTVAL FROM dual

Y bueno, en un insert con id secuenciado se usa: nombre_de_la_sequencia.NEXTVAL

Bloque FOR en PL/SQL
BEGIN
-- use a FOR loop to process a series of numbers
  DBMS_OUTPUT.enable;
  FOR i in 2476..2486 LOOP
    update nloqt_veh_atr_fam_d set lib_grp_fam = (SELECT to_char(b.ID_ATR_FAM) from nloqt_veh_atr_fam_d b where b.id_atr_fam = to_char(i))  where id_atr_fam = to_char(i);
    DBMS_OUTPUT.PUT_LINE('Updatee el id: ' || TO_CHAR(i) || ', wiii (?)');
  END LOOP;
END;

miércoles, 30 de septiembre de 2009

Aprendiendo JavaScript a lo bestia

JavaScript es un lenguaje de programación interpretado, es decir, que no requiere compilación, utilizado principalmente en páginas web, con una sintaxis semejante a la del lenguaje Java y el lenguaje C.

Gracias Wikipedia, ahora andate.

Lo que va a ir acá y en sucesivos post con el mismo título, serán funciones, sentencias y pedacitos de código javascript que me han sido utiles en el pasado, así cuando me tenga que enfrentar con un problema similar, evito buscar en google otra vez lo mismo.

Para empezar con nuestra primera leccion (?), tenemos 3 maneras de meter codigo javascript en una pagina: en la cabeza, en el cuerpo o afuera.

1) En la cabeza (HEAD)
Los scripts que metamos aqui solo seran ejecutados cuando sean llamados por algun evento o alguna otra funcion (que esten dentro de esta misma pagina).
Entre los tags <head> y </head> colocamos lo siguiente:

<script type="text/javascript">
function mensaje() {
alert("holaaaaaaaaaaaaaa");
}
</script>

Si queremos que esa funcion se ejecute cuando clickeamos un boton en un pagina, hacemos lo siguiente:

<input type="button" value="boton loco" onclick="mensaje();"/>

El html final quedaria asi (prueba.html):

<html>
<head>
<title>prueba</title>
<script type="text/javascript">
function mensaje() {
alert("holaaaaaaaaaaaaaa");
}
</script>
</head>
<body>
Clickea en este boton y te sorprenderas (?)
<input type="button" value="boton loco" onclick="mensaje();"/>
</body>
</html>



2) En el cuerpo (BODY)
Los script que metamos aca (entre los tags y , que es donde esta el contenido de la página) se ejecutan cuando carga la página y el navegador pasa por esa línea. La verdad que no lo recomiendo, pero alguna vez lo usé y quizás a alguno le sirve.
Ejemplo:

<html>
<head></head>
<body>
<script type="text/javascript">
document.write("Esta linea se escribio mediante javascript. Uy que piola que soy (?)");
</script>
</body>
</html>



3) Afuera de la página
Esta solución es la mejorcita porque separa el html del javascript, pero que se yo (?). Es muy util cuando una o varias funciones son usadas por más de una página (por ejemplo, para validar una entrada de datos).
Entonces las funciones javascript se ponen en un archivo de texto plano directamente, sin los tags <script>

Y en la parte HEAD de la página se hace una referencia al archivo conteniendo las funciones.

<script type="text/javascript" src="funciones.js"></script>


Asi que finalmente tendremos los archivos asi:

funciones.js

function mensaje() {
alert("holaaaaaaaaaaaaaa");
}

function otroMensaje (texto) {
alert(texto);
}


prueba2.html

<html>
<head>
<title>prueba2</title>
<script type="text/javascript" src="funciones.js"></script>
</head>
<body>
Clickea en este boton y te sorprenderas (?)
<input type="button" value="boton loco" onclick="mensaje();"/><br/>
Clickea en este boton y te sorprenderas aun mas (?)
<input type="button" value="otro boton loco" onclick="otroMensaje('hola2');"/>
</body>
</html>


Hasta acá llega nuestra primera lección. Pruebenlo en sus casas y después me cuentan (?)

martes, 5 de mayo de 2009

Subir un archivo en Struts

Este tutorial (?) es para aprender (?) a subir archivos correctamente (puro trial and error hasta que me salió) usando el framework Struts 1, asi que si no sabes Struts no sigas leyendo, gracias.

El JSP
Aquí es donde va estar el campo para subir el archivo. Supongamos que ya tenemos el esqueleto del jsp bien configurado y lo que nos falta es lo que vemos en la foto.


En el jsp vamos a tener que poner una cosa asi (en negrita lo importante):

<table align="center">
<tr>
<td align="left">
Fichier a charger <font color="#FF0000">&nbsp;*</font>
</td>
<td valign="top">
<html:file name="massGroupReplacementFileForm" property="replacementFile" style="width:80%;"/>
</td>
</tr>
</table>


Esta tabla va a estar adentro de un form obviamente (el formato es <html:form><table>blabla</table></html:form>) y para que el form tome bien el archivo que subimos tiene que quedar asi:

<html:form enctype="multipart/form-data" action="/admin/massGroupReplacement/fileSave.do">


Ese enctype=blabla es lo que me tuvo a maltraer un buen rato.


El struts-config.xml
Pongo el codigo nomás, it's pretty straightforward (!)

<action path="/admin/massGroupReplacement/fileSave"
name="massGroupReplacementFileForm"
validate="false"
scope="request"
type="com.blabla.admin.struts.MassGroupReplacementFileSaveAction">
<forward name="OK" path="/admin/menu.do" />
<forward name="ERROR" path=
"/jsp/administration/massGroupReplacementFileUpload.jsp" />
</action>


El ActionForm
Pongo el codigo directamente porque también es simple, no hay mucho para decir, solo que el tipo de dato correspondiente al campo del archivo es un FormFile, no un File comun y corriente.

import org.apache.struts.upload.FormFile;

public class MassGroupReplacementFileForm {

private FormFile replacementFile;

public FormFile getReplacementFile() {
return replacementFile;
}

public void setReplacementFile(FormFile replacementFile) {
this.replacementFile = replacementFile;
}
}


El Action
Obviamente uno con ese archivo subido puede hacer lo que carajo quiera, pero que se yo, lo recomendable es copiarlo a una carpeta del servidor para luego hacerle algo.
Entonces obtenemos el FormFile subido y lo metemos en nuestro File, de la siguiente manera:

MassGroupReplacementFileForm rf = (MassGroupReplacementFileForm) form;
FormFile replacementFile = rf.getReplacementFile();
File f = new File("c:\\directorio\\subdirectorio\\pepito.dat");
OutputStream out = new FileOutputStream(f);
out.write(replacementFile.getFileData());
out.flush();
out.close();


En un futuro próximo veremos como carambas se hace esto en Struts 2. Chau.

martes, 24 de febrero de 2009

Validame essssta... fecha

A lo largo de nuestras vidas como programadores (ay el, jose_programador) siempre nos cruzamos con el problema de validar fechas ingresadas por el usuario.
Sabemos que el usuario es un pelotudo capaz de ponerte 30 de febrero como fecha de nacimiento y uno tiene que evitar eso, tiene que estar un paso adelante de ese tarado, porque este tipo de detalles pueden hacer que una aplicación re grosa deje una mala impresión.

Afortunadamente, lenguajes como Java traen clases que hacen hacen esto automáticamente.
A mi me cabe (?) la clase SimpleDateFormat y mi manera de usarla es la siguiente.

Creo un objeto de esta clase usando el constructor que recibe por parámetro el formato de la fecha (lo que se llama "pattern").
El pattern lo defino yo y más adelante comentaré sobre el mismo.

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");


Este objeto sdf va a ser usado para convertir el String recibido (el que ingresó el usuario a traves de un formulario o un campo en una ventana) en un objeto Date.

Antes de llamar al metodo que hace la conversión, hay que setear el lenient de este objeto (sdf) en falso, esto es para que a la hora de comprobar el pattern sea estricto.
sdf.setLenient(false);


Aca se hace la conversión de String a Date
// cadenaFecha es el String ingresado por el usuario
Date fecha = sdf.parse(cadenaFecha);

Si al hacer esa conversion, salta una exception, significa que la fecha estuvo mal ingresada, ya sea porque el usuario no respetó el formato definido por nosotros o porque metió una fecha inexistente.
Por eso es que se tiene que meter en un bloque try-catch, para hacer algo en
que caso que la fecha no funque, así no se rompe todo


try {
// cadenaFecha es el String ingresado por el usuario
Date fecha = sdf.parse(cadenaFecha);
} catch (ParseException e) {
throw e;
/* Podria haber puesto cualquiera de las siguientes:
e.printStackTrace();
o
actionErrors.add("date", new ActionMessage("errors.date"));
return actionErrors;
o
lo q se me cante hacer con esta exception
*/
}


O sea, para poder validar el ingreso del 1 de enero de 2009, el usuario tiene que haberla ingresado como "01/01/2009".
Pero lo bueno es que ese "pattern" (formato) que puse al principio es no restrictivo y se puede cambiar a conveniencia.
Si quisiera que pase ingresando 1/1/09 hubiera elegido como pattern "d/M/yy"
Si quisiera que pase con 1-1-09 hubiera elegido "d-M-yy"
Si quisiera que pase con 01012009 hubiera elegido "ddMMyyyy"

Aquí hay un cuadro indicando los caracteres que se pueden usar y lo que cada uno representa a la hora de definir nuestro pattern.

Entonces, basicamente para pasar una fecha de String a Date y en el medio validar, tengo que hacer:


SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
// cadenaFecha es el String ingresado por el usuario
Date fecha = sdf.parse(cadenaFecha);
} catch (ParseException e) {
e.printStackTrace();
throw e;
}

La magia (?) de la clase SimpleDateFormat no termina aquí. Oh no, no no! (?)
También sirve para hacer la inversa, pasar un fecha que tengamos (de tipo Date) a un String en el formato que queramos.
Esto se hace con el metodo format y una manera simplisima de probar esto es asi:

Date miDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy - HH:mm:ss");
String cad = sdf.format(miDate);
System.out.println(cad);

Este código nos va a imprimir la fecha y hora actual en pantalla.
Ej: 24 02 2009 - 14:48:33


Bárbaro, pero y si no tenés la suerte de contar con una ayuda así?
Bueno, pues aquí tenemos un código en C adaptable a cualquier lenguaje que hace tooooodo lo que dije al principio.

Fue robado de aquí y adaptado al castellano (menos los comments) por un servidor.

int es_anio_bisiesto (int);

int fecha_valida(int dia, int mes, int anio)
{
int valida=1;
int mes_long[13] ={ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

if (es_anio_bisiesto(anio))
mes_long[2] = 29;

if ( mes < 1 mes > 12 )
valida = 0;
else if ( dia < 1 dia > mes_long[mes] )
valida = 0;

return valida;
}

int es_anio_bisiesto(int anio)
{

int result;

if ( (anio%4) != 0 ) // or: if ( year%4 )
result = 0; // means: if year is not divisible by 4
else
if ( (anio%400) == 0 ) // or: if ( !(year%400) )
result = 1; // means: if year is divisible by 400
else
if ( (anio%100) == 0 ) // or: if ( !(year%100) )
result = 0; // means: if year is divisible by 100
else // (but not by 400, since that case
result = 1; // considered already)

return result;

}

sábado, 1 de marzo de 2008

C: strings, punteros, structs, archivos

Hoy, 9 AM en punto, tengo final de "Lenguaje de programación 2" y no tengo sueño. No deberia haber siesteado 2 horas y media (!).

Es así que para aprovechar el tiempo (?), publico aquí algunas funciones, definiciones, etc, a modo de resumen y repaso.

Strings - Funciones copadas (?)

strcpy(cadena1, cadena2)
Mete el contenido de cadena2 en la cadena1
strcat(cadena1, cadena2)
Lo mismo que hacer cadena1=cadena1+cadena2 en Java
int x=strlen(cadena)
En la variable de tipo entero x guarda la longitud de cadena
strupr(cadena)
Convierte cadena a CADENA. A veces no funca (!) asi que hay recorrer toda la cadena haciendo toupper(char) a cada caracter.
int x=strcmp(cad1,cad2)
Si cad1 y cad2 son iguales, devuelve 0.
Diferencia entre gets(cadena) y scanf("%s",&cadena)
scanf detecta espacio como fin de la cadena
gets guarda toda la cadena, con espacios y todo

Uso de punteros - Ejemplos
int * ptr; // puntero a entero
int x=*ptr; // a x le asigno el entero al que el puntero apunta

int * buscar(int * vec, int num, int tam);
Una funcion que busca el numero num en el vector de enteros vec. tam es el tamaño del vector. La función devuelve un puntero a entero.
Adentro de ella, vec es la direccion de memoria al primer elemento del vector. Si quiero ir al segundo elemento, tengo que hacer vec+1. Para ir al tercero vec+2 y así.
Por eso la implementacion de esa funcion seria:
for(i=0; i<tam;i++)
   if (*(vec+i)==num)
     return (vec+i);
return NULL;
// *(vec+i) es el contenido de la posicion i del vector

Structs
typedef struct alumno {
   int codigo;
   char nya[20];
   float nota;
} alu;

Defino el tipo de dato struct alumno o alu que es una variable compuesta (digamos) por 3 variables adentro. Como el viejo y querido record de Pascal.

Para utilizarlo con funciones, en el main:
struct alumno registro; // poner "alu registro;" es lo mismo
cargar(&registro); // le paso la direccion de memoria
La función cargar sería:
void cargar(struct alumno * reg){
   scanf("%d", &(reg->legajo));
   gets(reg->nya);
   scanf("%f", &(reg->nota));
}

Memoria dinámica
(Incluir la libreria stdlib.h)

int * vec; // defino un puntero a entero llamado vec

vec=(int *) malloc(cantidad*sizeof(int));
Para el puntero vec estoy reservando cantidad*sizeof(int) bytes de memoria. La función calloc es similar, pero los parametros son distintos.

vec=(int *) realloc(vec,cantidadTotal*sizeof(int));
Si quiero redimensionar el espacio que reservé porque me di cuenta que necesitaba mas lugares o porque sì.

free (vec)
Libero la memoria.

Para trabajar con structs, donde es más útil esto de la memoria dinámica y aparte porque seguro me lo toman :P, en el main:
struct alumno * vec;
ingresa(vec,cant);
La función ingresa:
void ingresa(struct alumno * vec, int cant){
   for (int i=0; i<cant; i**){
     scanf("%d",&((vec+i)->legajo));
     gets((vec+i)->nya);
     scanf("%f",&((vec+i)->nota));
   }

Archivos
FILE *arch; // puntero a archivo
arch=fopen("C:\\cpp\\arch.dat","wb+"); //abro el archivo
El parámetro "wb+" crea el archivo. Si el archivo ya existe, lo pisa.
El otro atributo posible (de los usados, digamos) es "rb+", que lo abre para lectura/escritura.

Si me piden "cree el archivo bla y guarde blabla", uso "wb+".
Si me piden "abra el archivo bla y modifque tal registro", uso "rb+".

while (!feof(arch)) recorre el archivo mientras no llegue al fin del mismo.

Para posicionarse en el archivo:
fseek(arch,0,SEEK_SET); //se posiciona al principio
fseek(arch,0,SEEK_END); //se posiciona al final
fseek(arch,x,SEEK_CUR); //para desplazarse x bytes desde la posicion actual

Si necesito saber cuantos registros hay en el archivo.
int cant=ftell(arch)/sizeof(struct alumno); //solo puedo utilizarlo despues de ir a la ultima posicion del archivo.

Para guardar en el archivo:
fwrite(alu,sizeof(struct alumno),1,arch);
 alu es el puntero que apunta (valga la redundancia) a lo que voy a escribir en arch.
 sizeof(struct alumno) es el tamaño de lo que voy a escribir.
 1 es la cantidad bloques (elementos) que voy a guardar.

Hay un par de variantes utiles. Si quiero recorrer mi vector con un for y grabar registro por registro:
fwrite((alu+i),sizeof(struct alumno),1,arch);
O puedo grabar todo mi vector de una:
fwrite(alu,cant*sizeof(struct alumno),1,arch);

fread (para cargar desde el archivo) es más o menos similar. Si quiero leer todo un archivo y meterlo en memoria, luego de reservar ese espacio:
fread(alu,cant*sizeof(struct alumno),1, arch);

Importante: Cada vez que se hace un fwrite o un fread el puntero al archivo avanza una posición.


Archivos de texto
(esto es copypaste, ni bola le di)

FILE *arch=fopen("c:\\cpp\\texto.txt","w"); // (o "r", no se usa b porque no es binario)

fget(aux,80,arch);
Saca del archivo arch 80 caracteres y los mete en la cadena aux

fputs("cadena",arch); //se sobreentiende

fprintf(arch,"%d",alu->nota); //mete el valor de alu->nota en el archivo


Por el momento, nada más. Suerte (?)

((escuchando)) LETHAL - V.A.M.

miércoles, 30 de enero de 2008

boolToInt

private String boolToInt(boolean valor) {
   if (valor==true)
     return new Integer(1).toString();
   else
     return new Integer(0).toString();
}


¿Anda?
Obvio, como todos los métodos que desarrollo (H)

¿Es truchísimo?
Obvio, pero repito: ANDA

Así inauguro la sección (?) de programación, donde me verán tirar fruta (!) o tratar de explicar cosas simples onda "programming for dummies". Cuando te cuesta entender algo (debido a mi poca capacidad de concentracion al leer libros) explicarlas te puede ayudar a que se te graben en el cerebro (y de paso capaz le sirve a alguien).