martes, 17 de diciembre de 2013

Derreferenciamiento en Perl

Interpretación provisoria. No está basada en la teoría, sino en el caso empírico dado.
perl -w o bien use strict deberían quejarse de la mayoría de estos casos.


Código:
@ARY = ( [ qw(vilma palma vampiro) ], [ qw(zapallo zanahoria zapallito) ] );
print "@ARY\n";   # 1) Testigo
print ARY[1];   # 2) La expresión de derreferenciamiento requiere un caracter de tipo bien al principio. El subscript [] no es suficiente para que Perl sepa que nos estamos refiriendo al array ARY.
print "\n";
print "@{ARY[1]}\n";   # 3) Adentro de {}: no rige la regla del caso (2). Afuera de {}: derreferenciamento impropio de un escalar con @.
print "@ARY[1]\n"; # 4) El caracter de tipo tiene mayor precedencia que el subscript de matrices [] (perldsc sobre Perl 5.12.5, "Caveat on precedence"), excepto que la regla (2) tiene mayor prioridad. Mismo mecanismo que el caso (3).
print "@{@ARY[1]}\n"; # 5) Adentro de {}: Si hay un @ bien al principio, entonces la expresión se trata como en el caso (4), si no, es exactamente el caso (3). Afuera de {}: correcto derreferenciamiento de un array con @.
print "@{@{ARY[1]}}\n"; # 6) Expresión explícita del caso (5). Es exactamente el mismo caso.

Output:
1) ARRAY(0x989c818) ARRAY(0x98b7110)
2)
3) ARRAY(0x98b7110)
4) ARRAY(0x98b7110)
5) zapallo zanahoria zapallito
6) zapallo zanahoria zapallito


Código:
@ARY = (58, 90);
print ARY[1];   # 1) ARY: descriptor de archivo (en general nulo => el output no va a ningún lado). [1]: Arrayref anónimo con el elemento 1. Comparar por ejemplo con: print STDOUT"8";
print "\n";
print @{ARY[1]};   # 2) El contexto @{} aplicado a un escalar x, significa el array con el único elemento x.
print "\n";
print @ARY[1]; # El caracter de tipo tiene mayor precedencia que el subscript de matrices [] (perldsc sobre Perl 5.12.5, "Caveat on precedence").
print "\n";

print ( (\@ARY[1]) eq (\$ARY[1]) );   # 4
print "\n";
print ( (\@{ARY[1]}) eq (\@ARY[1]) );   # 5
print "\n";
print ( (\@{ARY[1]}) eq (\$ARY[1]) );   # 6
print "\n";


Output:
1)
2) 90
3) 90

4) 1
5) 1
6) 1



lunes, 16 de diciembre de 2013

Pruebas manejo de punteros y matrices en C

Código 1:
Compilador: gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), y a parte Visual C++ (ver nota a continuación)
Compilation flags -Wall -g


// matrix operations
#include <stdio.h>

void myPrint(int **table, int x, int y);

int main(int argc, char **argv) {

  int matrix[3][3];

  matrix[0][0] = 2;
  matrix[0][1] = 3;
  matrix[0][2] = 5;

  matrix[1][0] = 1;
  matrix[1][1] = 4;
  matrix[1][2] = 16;

  matrix[2][0] = 9;
  matrix[2][1] = 28;
  matrix[2][2] = 14;

  myPrint(matrix, 2, 1);
  return 0;
}

void myPrint(int **table, int x, int y) {

  printf("%d\n", table[x][y]);
}


Compilación:
warning: passing argument 1 of ‘myPrint’ from incompatible pointer type
note: expected ‘int **’ but argument is of type ‘int (*)[3]’

Ejecución:
Fallo de segmentación





Nota: en Visual C++ la validación de tipos es más estricta y hay que agregar
- myPrint((int **)matrix, 2, 1);   // conciliación de tipos entre parámetros formales y reales
Porque si no da error de compilación, que viene a ser justamente lo mismo que en gcc es warning. 

Código 2:
Compilador Visual C++

// matrix operations
#include <stdio.h>

void myPrint(int (*table)[3], int x, int y);

int main(int argc, char **argv) {

  int matrix[3][3];

  matrix[0][0] = 2;
  matrix[0][1] = 3;
  matrix[0][2] = 5;

  matrix[1][0] = 1;
  matrix[1][1] = 4;
  matrix[1][2] = 16;

  matrix[2][0] = 9;
  matrix[2][1] = 28;
  matrix[2][2] = 14;
  myPrint(matrix, 2, 1);
  return 0;
}

void myPrint(int (*table)[3], int x, int y) {

  printf("%d\n", table[x][y]);
}

Compilación: sin warnings
Ejecución:
28

Código 3:
Compilador: Por separado gcc y Visual C++ (ver nota abajo)
// matrix operations
#include
<stdio.h>
#include <stdlib.h>

void myPrint(int **table, int x, int y);

int main(int argc, char **argv) {

  int *matrix[3];

  matrix[0] = malloc(3*sizeof(int));
  matrix[0][0] = 2;
  matrix[0][1] = 3;
  matrix[0][2] = 5;

  matrix[1] = malloc(3*sizeof(int));
  matrix[1][0] = 1;
  matrix[1][1] = 4;
  matrix[1][2] = 16;

  matrix[2] = malloc(3*sizeof(int));
  matrix[2][0] = 9;
  matrix[2][1] = 28;
  matrix[2][2] = 14;

  myPrint(&matrix, 2, 1);
  return 0;
}


void myPrint(int **table, int x, int y) {

  printf("%d\n", table[x][y]);
}


Compilación: warning: passing argument 1 of ‘myPrint’ from incompatible pointer type
note: expected ‘int **’ but argument is of type ‘int * (*)[3]’

Ejecución:
28



Nota: en Visual C++ para Windows la validación de tipos es más estricta y hace falta las siguientes adaptaciones:

- (int*)malloc(3*sizeof(int)); // explícitamente decir el tipo de puntero con el que se va a usar lo que devuelva malloc.

- myPrint((int **)&matrix, 2, 1); // conciliar tipos entre parámetros formales y actuales Porque si no da error de compilación, que viene a ser justamente lo mismo que en gcc es warning. 

SQL - selección en base a rangos de fechas

Patrón:
- La relación tiene atributos de fecha inicio y fin (fecha_inicio_relación y fecha_fin_relación).
- La selección se quiere hacer según un rango fecha inicio y fin (fecha_inicio_selección y fecha_fin_selección), seleccionando todas en las que los segmentos se toquen o se superpongan (ver imagen):




fecha_inicio_relación                         fecha_fin_relación
|——————————————|
fecha_inicio_selección                       fecha_fin_selección
|——————————————|


Query:

select * from relación where (fecha_inicio_relación <= fecha_inicio_selección and fecha_fin_relación >= fecha_inicio_selección or fecha_inicio_relación <= fecha_fin_selección and fecha_fin_relación >= fecha_fin_selección or fecha_inicio_relación >= fecha_inicio_selección and fecha_fin_relación <= fecha_fin_selección or fecha_inicio_relación <= fecha_inicio_selección and fecha_fin_relación >= fecha_fin_selección)
-- validaciones de consistencia
and fecha_inicio_relación <= fecha_fin_relación and fecha_inicio_selección <= fecha_fin_selección