Cercare un valore e scrivere tutta la riga txt che lo contiene

12 Lug 2014
9
0
0
Buongiorno a tutto il forum.
Sto scrivendo una piccola script per trovare un valore massimo ottenuto con la funzione MAX e poi riscriverlo.
Cerco di spiegare brevemente su cosa non mi trovo.

I miei dati sorgenti sono dei file di testo contenenti dei valori su righe usa sotto l'altra. Ho un file txt chiamato parameterlist.txt per ogni dato da comparare: ecco un esempio di una riga: stationPressure=928.1

Con la funzione explode, ho separato i valori dopo il simbolo "=" e li ho messi in una array, dopodichè ho scritto tutto su un file di testo che mi funge da mini archivio/database

Il file di testo che ho ottenuto contiene un qualcosa come:

stazione1=23.7
stazione2=36.0

in cui "stazione" è una parola costante che scrivo, ed i numeri sono gli array.

Utilizzando la funziona MAX, ottengo con successo il valore massimo in una variabile e posso anche scriverla.
Il mio problema è che vorrei che scrivesse tutto il rigo che la contiene, quindi in questo caso stazione2=36.0

vi lascio lo script che ho realizzato, se potete aiutarmi ve ne sarei grato. Non fate caso alla sintassi ed all'architettura perchè sono davvero alle primissime armi. :dipser:

grazie a tutti

PHP:
<?php
// lettura massima stazione1
$fit = array();
$fit = file(".../stazione1/parameterlist.txt");
for($i=0; $i<=count($fit); $i++) { list($a, $d[$i]) = explode("=", $fit[$i]); $d[$i]=str_replace("\n","",$d[$i]);}

$riga = "stazione1" ."=" ."$d[186]\n";

$file = "paragone.txt";
$fr = fopen($file, 'a');
fwrite($fr, $riga);


$array = array();


// lettura massima stazione2
$fit = array();
$fit = file("...stazione2/parameterlist.txt");
for($i=0; $i<=count($fit); $i++) { list($a, $d[$i]) = explode("=", $fit[$i]); $d[$i]=str_replace("\n","",$d[$i]);}

$riga = "stazione2" ."=" ."$d[186]\n";

$file = "paragone.txt";
$fr = fopen($file, 'a');
fwrite($fr, $riga);
fclose($fr);

$array = array();


$fit = array();
$fit = file("paragone.txt");
for($i=0; $i<=count($fit); $i++) { list($a, $d[$i]) = explode("=", $fit[$i]); $d[$i]=str_replace("\n","",$d[$i]);}



$max = (max($d[1], $d[2]));


echo "$max";



// file_put_contents("paragone.txt", '');

?>
 
Ciao, io farei cosi
PHP:
<?php

$file = "paragone.txt";
// apro il file in lettura
$fr = fopen($file, 'r');
// valorizzo la variabile max
$max = 0;
// ciclo il contenuto
while (!feof($fr)) {
    // estraggo la riga
    $riga = fgets($fr);
    // separo la riga
    $split = explode("=", $riga);
    // ricavo il valore
    $val = $split[1];
    // verifico che il valore sia più alto di max
    if ($val > $max) {
        // assegno il nuovo valore
        $max = $val;
        // creo l'output
        $output = $riga;
    }
}
// chiudo
fclose($fr);
// stampo l'output
echo $output;
?>
in questo modo nel file possono essere presenti anche più di 2 valori, verrà stampata sempre la riga del più alto
 
Ciao Criric, ti ringrazio infinitamente per il disturbo che hai affrontato per me.
ho provato velocemente copiando ed incollando il pezzo di codice nel mio file e funziona tutto perfettamente.
Avevo intuito che il problema andava affrontato diversamente da come lo stavo pensando ma non avevo la minima idea di come risolverlo.
Ora però mi tocca ragionare un po sulla tua soluzione "ciclica" e cercare di imparare da tutto questo

grazie di nuovo, gentilissimo. :D:D
 
Grazie Criric, si ho letto le regole sui post.

Proprio usando la script ho comparato con successo 14 righe diverse !
D'istinto mi è venuto di individuare anche il valore minore e sono intervenuto sul ciclo, invertendo l'operatore di confronto nell'if e sistemando un po di cose per esigenze di ordine, ovviamente poteva mai funzionare ? ehe, NO! questo è quello che ho fatto... si accettano bacchettate sulle mani ;)

grazie.

PHP:
$file = "min.txt";
// apro il file in lettura
$fr = fopen($file, 'r');
// valorizzo la variabile min
$min = 0;
// ciclo il contenuto
while (!feof($fr)) {
    // estraggo la riga
    $riga = fgets($fr);
    // separo la riga
    $split = explode("=", $riga);
    // ricavo il valore
    $val = $split[1];
    // verifico che il valore sia più basso di min
    if ($val < $min) {
        // assegno il nuovo valore
        $min = $val;
        // creo l'output
        $output = $riga;
    }
}
// chiudo
fclose($fr);
// stampo l'output
echo $output;
 
Nessun numero positivo potrà mai essere minore di 0.
quello che puoi fare è assegnare a $min il valore della prima iterazione del ciclo
PHP:
if($min == 0) {
   $min = $val;
}
poi ti affidi alll'operatore < come hai fatto.
 
Grazie ancora :)

tuttavia sono una capra ;) modificando la condizione come mi hai suggerito, credo che il ciclo si fermi alla prima riga. Brancolo nel buio su come collocare il confronto "<" . C'entra qualcosa il fatto che potrei avere numeri negativi da comparare ??
 
Ti riposto lo script modificato
PHP:
<?php

$file = "paragone.txt";
// apro il file in lettura
$fr = fopen($file, 'r');
// valorizzo la variabile min
$min = 0;
// ciclo il contenuto
while (!feof($fr)) {
    // estraggo la riga
    $riga = fgets($fr);
    // separo la riga
    $split = explode("=", $riga);
    // ricavo il valore
    $val = $split[1];
    // imposto il primo valore
    if ($min == 0) {
        $min = (float) $val;
        echo "prima iterazione <br/>";
    }
    // verifico che il valore sia più basso di min
    if ($val < $min) {
        echo "val $val &egrave; minore di min $min<br/>";
        // assegno il nuovo valore
        $min = (float) $val;
        // creo l'output
        $output = $riga;
    } else {
        echo "val $val non &egrave; minore di min $min<br/>";
    }
    echo "valore minore : $min<br/>";
}
// chiudo
fclose($fr);
// stampo l'output
echo "riga estratta " . $output;
?>
ho aggiunto (float) per forzare la variabile ad essere un decimale
ho aggiunto degli echo per farti capire il lavoro che fa
quando hai capito puoi togliere tutti gli echo
 
Grazie davvero Criric, non ci sarei mai arrivato da solo. Ho provato e funziona. Qualche passetto in avanti ho fatto vedendo cosa fa materialemente il ciclo. Solo una piccola precisazione che sono riuscito ad intuire: il file TXT contenente i dati da analizzare terminava con un "a capo" \n per intenderci, inducendo il ciclo ad analizzarlo e restituendo un valore non coerente.
Ho risolto trasformando la generazione della riga dell'ultima stazione in elenco

$riga = "Stazione14" ."=" ."$d[188]\n";

in

$riga = "Stazione14" ."=" ."$d[188]";

in questo modo l'ultimo rigo del file txt è salvo ed il ciclo termina correttamente il lavoro.
avrebbe dovuto succedere anche nel primissimo caso MAX ma ha funzionato correttamente, comunque bon, se capita almeno so dove rimediare.

grazie di tutto.
 
rileggendo lo script ho notato che potrebbe andare in errore se il primo valore è anche il più basso, perchè in questo caso la variabile $output non verrebbe valorizzata. E' sufficiente, per risolvere, valorizzarla anche nella prma iterazione
PHP:
if ($min == 0) {
        $min = (float) $val;
        $output = $riga;
    }
non ho capito invece cosa intendi con
$riga = "Stazione14" ."=" ."$d[188]\n";
 
Grazie, ho fixato con il tuo consiglio.

in merito a $riga = "Stazione14" ."=" ."$d[188]\n"; forse sono stato poco chiaro, faccio un passo indietro.

Ricordi all'inizio, quando parlaro del come ho generato il file TXT come archivio da analizzare successivamente

PHP:
// lettura massima stazione1
$fit = array();
$fit = file(".../stazione1/parameterlist.txt");
for($i=0; $i<=count($fit); $i++) { list($a, $d[$i]) = explode("=", $fit[$i]); $d[$i]=str_replace("\n","",$d[$i]);}

$riga = "stazione1" ."=" ."$d[186]\n";

$file = "paragone.txt";
$fr = fopen($file, 'a');
fwrite($fr, $riga);


$array = array();

ebbene, aggiungendo i vari parameterlist.txt (ho aggiunto la stessa routine per ogni stazione cambiando l'indirizzo assoluto del parameterlist.txt) ottengo nel file TXT un elenco dele righe poi esplose successivamente.

Ecco, l'ultima riga del TXT non è chiusa, l'ho verificato perchè l'output mi dava questo

PHP:
prima iterazione
val 14.0 non è minore di min 14
valore minore : 14
val 20.1 non è minore di min 14
valore minore : 14
val 13.1 è minore di min 14
valore minore : 13.1
val 15.6 non è minore di min 13.1
valore minore : 13.1
val 13.0 è minore di min 13.1
valore minore : 13
val 12.9 è minore di min 13
valore minore : 12.9
val 10.8 è minore di min 12.9
valore minore : 10.8
val 16.1 non è minore di min 10.8
valore minore : 10.8
val 11.1 non è minore di min 10.8
valore minore : 10.8
val 13.4 non è minore di min 10.8
valore minore : 10.8
val 13.4 non è minore di min 10.8
valore minore : 10.8
val 13.5 non è minore di min 10.8
valore minore : 10.8
val 13.3 non è minore di min 10.8
valore minore : 10.8
val 12.0 non è minore di min 10.8
valore minore : 10.8
val è minore di min 10.8
valore minore : 0
riga estratta

come vedi l'ultima azione del ciclo mi dava 0 perchè analizzava un rigo praticamente vuoto. Questo succedeva perchè i valori erano scritti con

PHP:
$riga = "stazione1" ."=" ."$d[186]\n";

e alla fine di ogni scrittura, veniva generato un "a capo" per il rigo successivo.

Alla luce dello 0 che vedevo nell'output, ho ricontato le azioni del ciclo e ce ne era una in più, quindi per fortuna ho intuito che veniva ciclato anche il rigo vuoto ma con "l'accapo". Per ovviare ciò ho tolto all'ultima routine l'opzione \n in modo che, una volta generato l'ultimo record del TXT, non viene generato "l'accapo".

Spero di essermi spiegato meglio, purtroppo non riesco ad esprimermi in termini molto tecnici.
 
Capito :fonzie:
se vuoi essere più sicuro puoi mettere un ulteriore controllo sulla riga
PHP:
// se la riga non è vuota
if(!empty($riga)) {
  // eseguo il codice
}
 
Buonasera Criric, eccomi nuovamente dopo un buon periodo di testing della scritp :rolleyes:
Tutto funziona correttamente. Visto che il programmino va a scrivere un file txt, forse è da capire cosa accadrà quando la stessa script sarà eseguita molte volte di seguito ogni volta che comparirà sulla pagina. Forse un piccolo DB potrebbe risolvere questo potenziale problema, ma forse ho una soluzione in tasca meno sofisticata: si potrebbe attivare un cron ogni minuto per tenere sempre il txt aggiornato e poi limitarsi alla lettura del txt stesso, in modo da rendere più stabile la cosa "alla lunga". Non so se ho detto corbellerie.

Ah, nel caso in cui avessimo più valori di input uguali (accade più spesso di quello che pensavo) sarebbe difficile fargli stampare le righe con i valori massimi (o minimi) uguali?

grazie !
 
..forse è da capire cosa accadrà quando la stessa script sarà eseguita molte volte di seguito ogni volta che comparirà sulla pagina.
Semplicemente se capitano nello stesso istante un accesso in lettura ed uno in scrittura sul file quest'ultimo si corromperà e questo sicuramente comporterà degli errori anche nel tuo script php.

Forse un piccolo DB potrebbe risolvere questo potenziale problema, ma forse ho una soluzione in tasca meno sofisticata: si potrebbe attivare un cron ogni minuto per tenere sempre il txt aggiornato e poi limitarsi alla lettura del txt stesso, in modo da rendere più stabile la cosa "alla lunga". Non so se ho detto corbellerie.
Il database è una buona pensata ma anche quella del job pianificato non è male per ridurre al minimo le operazioni di scrittura, tuttavia anche così rischi la corrosione del file.
Per evitarlo puoi richiedere un lock tramite la funzione flock(), in questo modo mentre lo stai scrivendo non sarà possibile effettuare operazioni di lettura e questo dovrebbe essere sufficiente a salvaguardare in modo appropriato il tuo file.
 

Discussioni simili