• Publicidad

Recorrido de cadenas y separación de campos

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Notapor Josmanue » 2006-08-21 05:50 @284

Muchísimas gracias por tu programa, pero ahora tengo algunas dudas, la primera es que pensaba que en Perl no hacía falta predeclarar las variables y en tu programa lo haces con todas.... entonces... ¿es necesario o no?
¿Por qué las declaras todas como locales? ¿debe ser así por convenio? o simplemente te gusta a ti hacerlo así?

No entiendo lo que me dices de la inicialización de P1CosLat. Está inicializada como
Código: Seleccionar todo
$P1CosLat = cos($Latitud_Rad);

Y $Latitud_Rad también toma valor unas lineas antes, así que no debería estar ahi el problema no? De echo en tu programa creo que lo has dejado igual.

En cuanto al campo 'LON' creo que te equivocas, la longitud viene dada como GGGMM,mmmm con GGG: grados, MM: minutos y mmmm: décimas de minutos. La Longitud pueden ser por ejemplo 125º. De hecho fijate como está definido:
Código: Seleccionar todo
 LON.{5},.{4}

Es algo diferente de Latitud:
Código: Seleccionar todo
LAT.{4},.{4}

Por eso yo tenía puestos dos "if" uno para cada campo, porque son diferentes(esta vez lo tenía bien yo ¿no? :D :D )
Hasta aqui mis dudas, ahora me sigue dando un error, o warning:
attemp to separate words with commas at ./programa.pl line 75

¿De que puede ser?
Y por último, al introducir LAT5525,1234 y LON12525,1234 en las pruebas que hago me da como resultado
Easting =-349669.218275869
Northing = 10061918.1812058
así estan en la cadena $sql, pero a la hora de insertar en Easting inserta un '0'.
Si está en la sentencia $sql bien, es que está bien ¿no? ¿Puede ser un problema de la tabla, que no acepte datos negativos?
Lo siento si es muy largo. Gracias.
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Publicidad

Notapor explorer » 2006-08-21 09:58 @457

Josmanue escribiste:Muchísimas gracias por tu programa, pero ahora tengo algunas dudas, la primera es que pensaba que en Perl no hacía falta predeclarar las variables y en tu programa lo haces con todas.... entonces... ¿es necesario o no?
Es necesario si se usa el pragma 'strict'. Algo recomendable para evitar cosas como lo de la variable $P1CosLat.

Josmanue escribiste:¿Por qué las declaras todas como locales? ¿debe ser así por convenio? o simplemente te gusta a ti hacerlo así?
Son locales en el programa en donde están... pero ayuda a evitar confilctos en casos como bucles o subrutinas.

Josmanue escribiste:No entiendo lo que me dices de la inicialización de P1CosLat. Está inicializada como
Código: Seleccionar todo
$P1CosLat = cos($Latitud_Rad);
Y $Latitud_Rad también toma valor unas lineas antes, así que no debería estar ahi el problema no? De echo en tu programa creo que lo has dejado igual.
En el programa que dejaste aquí sólo existía un lugar donde se hacía referencia a $P1CosLat y era en la línea donde se calcula $East_Term1. Viendo el código con calma, se vé que todas las referencias son a la variable $P1_CosLat, como se ven en las líneas que siguen a la que indicas. Fíjate que después de inicializar $P1_CosLat al valor del coseno de $Latitud_Rad, esa variable se usa inmediatamente para el cálculo de las variables $P2_CosLat y $P3_CosLat. Cambié la línea del calculo de $East_Term1 de $P1CosLat a $P1_CosLat y todo fue bien. El aviso me lo dió use strict, que me dijo que esa variable no había sido inicializada. Estas cosas son importantes porque son la base del programa, desde luego.

Josmanue escribiste:En cuanto al campo 'LON' creo que te equivocas, la longitud viene dada como GGGMM,mmmm con GGG: grados, MM: minutos y mmmm: décimas de minutos. La Longitud pueden ser por ejemplo 125º. De hecho fijate como está definido:
Código: Seleccionar todo
 LON.{5},.{4}
Es algo diferente de Latitud:
Código: Seleccionar todo
LAT.{4},.{4}
Por eso yo tenía puestos dos "if" uno para cada campo, porque son diferentes(esta vez lo tenía bien yo ¿no? :D :D )
Sí, lo estabas haciendo bien (salvo el detalle de la variable $mmmm). Pero esas líneas se pueden resumir, ya que los dos if hacen casi lo mismo. Por eso existe un '?' en la expresión regular, para leer dos o tres números. De esa forma el cálculo de LON y LAT se puede meter en las mismas líneas. Esto es lo bueno de las expresiones regulares. Cuando hago
Código: Seleccionar todo
my ($GG,$MM,$mmmm) = $valor =~ /(...?)(..),(....)/;
lo que hago es leer los campos de grados, minutos y segundos y guardarlos en sus variables. En el caso de los grados, con el '.?' indico que puede existir o no un tercer dígito.

Josmanue escribiste:Hasta aqui mis dudas, ahora me sigue dando un error, o warning:
attemp to separate words with commas at ./programa.pl line 75
¿De que puede ser?
Es porque encuentra la coma dentro del qw(). No le hagas ni caso. Cuando el programa funcione, comentas o quitas la línea use warnings y asunto solucionado.

Josmanue escribiste:Y por último, al introducir LAT5525,1234 y LON12525,1234 en las pruebas que hago me da como resultado
Easting =-349669.218275869
Northing = 10061918.1812058
así están en la cadena $sql, pero a la hora de insertar en Easting inserta un '0'.
Si está en la sentencia $sql bien, es que está bien ¿no? ¿Puede ser un problema de la tabla, que no acepte datos negativos?
Eso ya es un tema de la base de datos, según cómo estén definidos esos campos. Podría ser algo tan tonto como la presencia del '.' dentro del número.

Por cierto, con esos valores de muestra a mí me salen estos valores:
Easting = 5088.02311980753
Northing = 9089209.99698948

Para comprobar que estás haciendo bien los cálculos, prueba a ponerle 89º59'59.999 (polo norte), con lo que deberás obtener un valor de Northing muy cercano a los 10 millones (de metros, que son 10 mil kilómetros), que es justo la cuarta parte de la circunferencia de todo el planeta.

En esta página ( http://home.hiwaay.net/~taylorc/toolbox ... eoutm.html ) tienes una calculadora que te servirá para saber si estás haciendo bien o no los cálculos. Con el módulo Geo::Coordinates::UTM y usando el elipsoide WGS84 me salen casi exactos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Josmanue » 2006-08-22 05:36 @275

Todo correcto de momento. He metido la Latitud que me diste 8959,5999 y me da un Northing de: 9998749.42092729, así que supongo que esta todo correcto.
Ahora estoy liado con la ultima parte del programa, decidir en qué servidor se inserta, si servicio=3 va a servidor A y si servicio=5 va a servidor B. Para probar he creado la tabla unidades2:
unidad servicio
moto1 3
moto2 3
moto3 3
cami1 5
cami2 5
buga1 5
buga2 3

Y en el programa he puesto:
Código: Seleccionar todo
my $sql2 = "SELECT servicio FROM unidades2 WHERE unidad='$trama{UID]'";
my $serv = $dbh->do($sql2)
       or die $dbh->errstr;
print "el servicio es: $serv\n";

Pero me devuelve siempre un '1' si hay acierto y '0E0' cuando no hay coincidencia. ¿Por qué no me devuelve el numero del servicio? La sentencia sql2 sí está bien construida ¿no?
unidad esta definido como VARCHAR y servicio como INT.

Y por último, al finalizar el programa, una vez insertados los datos en la tabla, hay que responder al remitente con un acuse de recibo para que de el parte como enviado correctamente. Este acuse de recibo debe ser la cadena: '$INFOK*CrLf' donde CrLf es un retorno de carro y un salto de linea.
¿Cómo puedo hacer esto?
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-08-22 05:52 @286

No debes utilizar do() en los casos de SELECT, porque no devuelve un controlador de acceso a las filas afectadas. Sólo te está devolviendo si lo hizo bien o no.

El acuse de recibo lo envías con un print.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Josmanue » 2006-08-24 02:43 @155

Muchas gracias, ya lo he solucionado, no tenía ni idea de que no se pudiera hacer con el do(). He puesto:
Código: Seleccionar todo
my $sth =$dbh->prepare("SELECT servicio FROM unidades2 WHERE unidad= '$trama{UID}'")
   or die $dbh->errstr;
my $dato = $sth->fetchrow_array();

Y me funciona estupendamente :D :D . Si hago un print de $dato me imprime el servicio correspondiente.
Una cosa, para conectarme al segundo servidor, antes debo desconectarme del primero ¿verdad? Ahora tengo puesto:
Código: Seleccionar todo
if ($dato==5)
{$dbh->disconnect;
my $dsn = "DBI:mysql:database=$database;host=$host;port=$port2";
my $dbh = DBI->connect($dsn,$user,$password)
   or die $DBI::errstr;
}

¿Que te parece?
Ah y una preguntita, te parecera muy tonta pero llevo todo un día buscandolo y no lo encuentro por ninguna parte. En Perl, el salto de linea es '\n' pero ¿y el retorno de carro? :shock: No lo encuentro!!
Gracias.
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-08-24 06:48 @325

Puedes estar conectado a varias bases de datos simultáneamente. Puedes, por ejemplo, conectarte a las bases de datos al principio del programa, y luego, según el caso, hablarle a una o a la otra (o a las dos a la vez, si es necesario). Y al final del programa, cerrar las conexiones.

En Perl, "\n" es un carácter salto de línea si está en un string. PERO a la hora de imprimirlo, sea a pantalla o en un fichero, según en el sistema operativo donde estés, se transformará en "\r\n" si estás en Windows, en "\n" si estás en Unix y en "\r" si estás en Mac.

Si necesitas el carácter retorno de carro, es "\r", PERO normalmente no lo necesitarás para imprimir líneas. Con el "\n" será suficiente.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Josmanue » 2006-08-28 01:56 @122

Ok de acuerdo, lo ideal sería conectar ambas bases de datos al principio, pero si ambas bases de datos poseen la misma estructura y la misma tabla "partes_3" al ejecutar $sql, ¿no lo insertaría en ambas bases de datos? La sentencia sql lo que tiene es "INSERT INTO parte_3....."

En cuanto al acuse de recibo, lo unico que tengo que hacer es enviar la cadena"$INFOK*CrLf" Cr y Lf retorno de carro y salto de linea respectivamente. Supongo que necesitaré tambien el retorno de carro, y como va sobre BSD, he puesto:
Código: Seleccionar todo
print "INFOK*\r\n";

Será así ¿no?
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor explorer » 2006-08-28 08:55 @413

Cuando haces una conexión a una base de datos, esa conexión queda almacenada en una variable que tu llamas $dbh. Bueno, pues entonces es lógico que al comienzo si quieres tener dos conexiones abiertas a la vez, a una la llamas $dbh1 y a la otra $dbh2 (por ejemplo)

En cuanto a lo del retorno de carro, tu mismo puedes hacer las pruebas. Haz un
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
perl -e 'print "INFOK*\r\n"' > test.txt
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

En mi linux sí que pone el retorno de carro:
Código: Seleccionar todo
explorer@casa:~> perl -e 'print "INFOK*\r\n"' > test.txt
explorer@casa:~> hexdump -C test.txt
00000000  49 4e 46 4f 4b 2a 0d 0a                           |INFOK*..|
00000008
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Josmanue » 2006-09-07 04:28 @228

Hola explorer, antes de nada siento no haber escrito en unos dias, pero hasta yo creo que me merezco unas vacaciones.
En cuanto al tema del acuse de recibo, me da exactamente lo mismo que a ti pero no estoy seguro de que haga el retorno de carro, me explico: En primer lugar, si pongo
Código: Seleccionar todo
print "$INFOK*\r\n";

Me da un error de compilacion: Global symbol "$INFOK" requires explicit package.
En cambio, si pongo comillas simples en lugar de dobles:
Código: Seleccionar todo
print '$INFOK*\r\n';
Aqui ya no me da errores, pero al final me devuelve
$INFOK*\r\nConnection closed by foreign host.

Es decir no pilla el retorno de carro ni nada. ¿Como puedo solucionar esto? ¿Y por que no puedo usar las comillas dobles??
El problema puede estar en el simbolo '$' del principio??? Deberia imprimirse también y creo que en mi anterior mensaje no lo puse :oops: .
Gracias.
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

Notapor Josmanue » 2006-09-07 04:44 @239

Vale el problema es el simbolo '$', he probado sin ponerlo y lo hace bien, con retorno de carro y todo y con las comillas dobles. ¿Por que no imprime con el '$'? Piensa quizas que es una variable?
Josmanue
Perlero nuevo
Perlero nuevo
 
Mensajes: 76
Registrado: 2006-06-09 04:33 @231

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 14 invitados