Mie Ago 29, 2007 10:14 pm
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
| Crear un bucle dentro de otro |
|
|
¡Hola a todos de nuevo!
Veréis quería crear un bucle dentro de otro con la función for que es la que controlo por ahora.. Siguiendo con mi programilla para generar archivos que algunos conoceréis ya (gracias de nuevo explorer) del tema cambiar un archivo, me encuentro con un problema al definir un loop dentro de otro.. Quiero cambiar unas variables de manera que la primera la defino en el primer bucle y quiero que quede fija en un valor mientras con el segundo bucle recorro todo el rango de la segunda variable generando así una serie de archivos tal que siendo la primera variable A y la segunda B queden así A1B1, A1B2, A1B3 y volviendo de nuevo al primer bucle A2B1, A2B2.. y así sucesivamente.. El problema que me encuentro es que me genera solamente archivos tal que A1B3 tantas veces como debería generar los sucesivos archivos. No se si me explico muy bien... así que os dejo aquí mi pequeño programa a ver si me podéis orientar un poco. ¡Gracias por adelantado y un saludo!
| Perl: | # Programa genera sucesivos archivos de entrada para FAST.
# ______________________________________________________________________
# Cambiamos la altura de la torre en el archivo_parámetros.
for $i (72.. 74) {
for $j (- 3.. 0) {
# Lugar donde almacenaremos el fichero leido y modificado
my @params;
# Abrimos el fichero en lectura
open (PARAMS, "<PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";
# Para todas las lineas del fichero hacemos el cambio
for $line (<PARAMS>) {
if ($line =~ /^B/ ) {
$line =~ s/=.*\d+/= $j/ or die "No se pudo cambiar el pitch:$!";
} else {
("$line =~ s/TOWER_HT =.*\d+/TOWER_HT= $i/") == 0 or die "No se cambió la altura de la torre: $!";
}
push @params, $line;
}
close PARAMS;
# Grabamos el resultado
open (OVERWRITE, ">PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";
print OVERWRITE @params or die "No se pudo sobreescribir PARAMS.in: $!";
close OVERWRITE;
# Corre el programa prepro y genera una entrada para FAST.
system ("c:\\perl\\bin\\perl prepro.pl PARAMS.in FAST.template H$i($j).in") == 0 or die "No se generó el input para FAST: $!";
}
} |
|
|
|
|

Jue Ago 30, 2007 4:47 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
Yo veo que el system es llamado con todas las combinaciones de $i y $j...
| Código: |
H72(-3).in
H72(-2).in
H72(-1).in
H72(0).in
H73(-3).in
H73(-2).in
... |
|
|
Jue Ago 30, 2007 7:35 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
Sí que crea los archivos que tu dices pero no sé por qué cuando entro dentro de todos y cada uno de los archivos creados H es 72 en todos y P es 0 en todos... he ahí el problema.
¡No sé que está mal en el bucle para que no me corra el resto de Hs y corra todos las Ps dejando sólo la última!
Siento no explicarme mejor.. |
|
Jue Ago 30, 2007 8:19 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
| Ya veo el error... tienes puesta la segunda expresión regular como una cadena de caracteres, entrecomillada. Quita las '"'. |
|
Jue Ago 30, 2007 8:30 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
| He hecho como me has dicho pero ahora no sé qué pasa, no cambia ninguna variable, sólo genera los archivos con los nombres correspondientes pero son todos iguales al original ni siquiera ha cambiado el pitch ni la altura de la torre... |
|

Jue Ago 30, 2007 9:06 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
Lo estoy viendo... el problema son las expresiones regulares... como siempre he dicho, hay que tener mucho cuidado con los glotones (.*)
La siguiente solución sí que me funciona:
| Perl: | for $i (72.. 74) {
for $j (- 3.. 0) {
# Lugar donde almacenaremos el fichero leido y modificado
my @params;
# Abrimos el fichero en lectura
open (PARAMS, "<PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";
# Para todas las lineas del fichero hacemos el cambio
for $line (<PARAMS>) {
$line =~ s/ (\ {B.+=.*? )[\d.- ]+/$ 1$j/;
$line =~ s/ (\ {TOWER_HT.*=.*? )[\d.- ]+/$ 1$i/;
push @params, $line;
}
close PARAMS;
# Grabamos el resultado
open (OVERWRITE, ">PARAMS.in") or die "No se pudo abrir PARAMS.in: $!";
print OVERWRITE @params or die "No se pudo sobreescribir PARAMS.in: $!";
close OVERWRITE;
# Corre el programa prepro y genera una entrada para FAST.
system ("c:\\perl\\bin\\perl prepro.pl PARAMS.in FAST.template H$i($j).in") == 0 or die "No se genero el input para FAST: $!";
}
} | Los cambios son en las expresión regulares, que, además, las sacamos de los if porque tienen los suficientes controles como para discriminar las líneas.
En cada expresión regular hacemos lo mismo: ponemos un control para verificar que es la línea correcta la que vamos a cambiar. Usamos, de cada línea, las partes que no cambian. En concreto, sabemos que empiezan por '{' y le sigue el nombre del parámetro. Eso lo usaremos como marca de cada sustitución.
En la expresión regular, por ejemplo, /(\{B.+=.*?)[\d.-]+/, lo que hacemos es que la sustitución se hará si coincide con el patrón: la línea comienza por una '{B' , seguida de algo, un '=', seguido de cero o más caracteres que no son dígitos, o '-' o '.'. Todo esto lo capturamos con los paréntesis. Y seguido, de un número.
Aquí, cambiamos de usar un operador glotón (.*) por uno inmediato (.*?). El operador hace lo mismo (captura todo lo posible), PERO queremos que se pare justo antes de lo que le decimos que viene a continuación: un número, no que se trague todos los dígitos y sólo nos devuelva el último.
Si la línea coincide con este patrón, lo sustituimos por $1$j, que quiere decir lo capturado por los paréntesis más el contenido de la variable $j. Digamos que los paréntesis nos capturan toda la línea hasta llegar a la cifra que vamos a sustituir.
La segunda expresión regular es casi igual, solo que buscamos '{TOWER_HT'.
Como ves, hacemos lo siguiente:
* Quitamos los if porque el control de a qué línea debo hacer el cambio lo hace el propio s///;
* En cada s/// ponemos esos controles para identificar cada línea de forma única. Si la línea coincide con lo esperado, hacemos su cambio.
Ultima edición por explorer el Jue Ago 30, 2007 6:24 pm, editado 2 veces |
|

Jue Ago 30, 2007 5:05 pm
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
Pues sigue sin cambiar nada... no sé que más cambiar ya del programa para probarlo... te pongo el archivo PARAMS.in para que veas las líneas a ver si el problema viene de ahí aunque ya me extrañaría con los cambios que me has puesto... perdona por empreñar tanto... ¡¡y muchísimas gracias por la ayuda!!
| Código: |
{BL_PITCH1 = 5}
{BL_PITCH2 = 5}
{BL_PITCH3 = 5}
{B1_PITCHF1 = 0}
{B1_PITCHF2 = 0}
{B1_PITCHF3 = 0}
{ROT_SPEED = 18.0}
{TIP_RAD = 40.000}
{HUB_RAD = 1.250}
{TOWER_HT =60.000}
{AD_FILE = 1.ipt} |
|
|

Jue Ago 30, 2007 6:22 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
¡Anda! Pero si ninguna línea empieza por 'B', sino que empieza por '{'.
He modificado mi programa anterior, con unas nuevas expresiones regulares, y una explicación más resumida de lo que hacen. Lo he probado y funciona.
Lo que no dices es si quieres cambiar todos los parámetros que empiezan por 'B' (que son 6) o sólo uno. Tal como está el programa, cambiará todos. Si solo quieres cambiar uno deberás cambiar la expresión regular por una como la del parámetro 'TOWER_HT'. |
|

Vie Ago 31, 2007 3:51 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
¡Ains, que despiste! Pues es verdad, ¡ahí debe estar el error! Si es que llevo dándole tantas vueltas que cuando se me ocurrió la feliz idea de poner que empezaba por 'B' ya no estaba yo... y no me di cuenta que el otro programa que sí funciona no llevaba que empezase por 'B'...
Sí que quiero cambiar todas las líneas que empiezan por 'B'. Probaré a quitar el metacarácter de principio de string y si ya no funciona.. ¡¡Muchísimas gracias por todo!! |
|
Vie Ago 31, 2007 5:15 am
|
 |
Merisue
Perlero Nuevo

|
Registrado: 24 Ago 2007
Mensajes: 19
|
|
|
|
|
¡Ay, pero que desastrosa soy! ¡Me acabo de dar cuenta de que habías editado el mensaje!! ¡¡ajaja y funciona con tus modificaciones, va perfecto!! Muchísimas gracias por todo!!  |
|
Powered by phpBB © 2001, 2005 phpBB Group
|