Gå til innhold

[LØST] Konvertering av string til float


Anbefalte innlegg

Har laget et script her som leser inn noen verdier fra en xml-fil. En av verdiene er et flyttal, men det ser ut som den blir lest inn som string, så når jeg skal behandle tallet videre, funker det ikke med pluss og minus, osv.

 

Er det noen enkel måte å få konvertert en string til float?

Endret av Sokkalf^
Lenke til kommentar
Videoannonse
Annonse

Perl skal vell i teorien ta seg av dette selv. Variabler har ikke type, man kan behandle dem som streng i det ene øyeblikket, tall i det neste, og perl tar seg av alt sammen selv.

 

Jeg tipper problemet ditt er at flyttallet er lagret etter "norsk" standard. Altså problematikken med , og .

 

Prøv å bruk en regexp for å bytte ut , med .

 

$tall = "1,2";

$tall =~ s/,/./;

print ($tall +3);

 

burde da gi 4.2 som svar.

Endret av cyclo
Lenke til kommentar

Skjønner hva du mener, men tallet jeg har er lagret med punktum, så det er ikke det som er problemet.

 

Feilmeldingen jeg får :

Operation "==": no method found,

left argument in overloaded package XML::XPath::NodeSet,

right argument has no overloaded magic at /home/sokkalf/scripts/getweather.pl line 9.

 

 

Hele scriptet :

Klikk for å se/fjerne innholdet nedenfor

#!/usr/bin/perl -w

use XML::XPath;
use LWP::Simple;

sub getDirection {
my $deg = $_[0];

if (($deg == 360 || $deg == 0 ) || ($deg < 22.5)) {
	return "N";
}
elsif ($deg >= 22.5 && $deg < 45) {
	return "NNE";
}
elsif ($deg >= 45 && $deg < 67.5) {
	return "NE";
}
elsif ($deg >= 67.5 && $deg < 90) {
	return "ENE";
}
elsif ($deg >= 90 && $deg < 112.5) {
	return "E";
}
elsif ($deg >= 112.5 && $deg < 135) {
	return "ESE";
}
elsif ($deg >= 135 && $deg < 157.5) {
	return "SE";
}
elsif ($deg >= 157.5 && $deg < 180) {
	return "SSE";
}
elsif ($deg >= 180 && $deg < 202.5) {
	return "S";
}
elsif ($deg >= 202.5 && $deg < 225) {
	return "SSW";
}
elsif ($deg >= 225 && $deg < 247.5) {
	return "SW";
}
elsif ($deg >= 247.5 && $deg < 270) {
	return "WSW";
}
elsif ($deg >= 270 && $deg < 292.5) {
	return "W";
}
elsif ($deg >= 292.5 && $deg < 315) {
	return "WNW";
}
elsif ($deg >= 315 && $deg < 337.5) {
	return "NW";
}
elsif ($deg >= 337.5 && $deg < 360) {
	return "NNW";
}
else {
	return "?";
}
}

my $data_url = 
"http://www.yr.no/place/Norway/Akershus/Asker/Vollen/varsel.xml";

# get data and drop it in a file
my $xml_data = get ($data_url);
my $xp = XML::XPath->new(xml => $xml_data);
my $weatherdata = $xp->find('/weatherdata/forecast/tabular/time')->get_node(1);

my $temperatur = $weatherdata->find('temperature')->get_node(1);
my $vindhastighet = $weatherdata->find('windSpeed')->get_node(1);
my $vindretning = $weatherdata->find('windDirection')->get_node(1);
my $nedboer = $weatherdata->find('symbol')->get_node(1);
my $degree = $weatherdata->find('@deg');

print "Temp: ".$temperatur->find('@value')."°C | Vindhastighet: ".$vindhastighet->find('@mps')."m/s | Vindretning: ".$degree."° (".getDirection($degree).")| ".$nedboer->find('@name');

 

Hvis jeg bare skriver "print $degree", så får jeg f.eks 43.5 som output, men det går ikke an å regne på eller teste verdien med en if-setning.

 

Dette er forøvrig mitt første perl-script ever, så mulig koden er helteit. :p

 

Edit: Har også sjekket at getDirection-funksjonen fungerer fint ved å kalle den som f.eks "getDirection(50.3)".

 

Edit 2: Fant en liten feil i scriptet, den oppsto under renskriving av scriptet, dog, og feilen skjer fortsatt. :(

 

my $degree = $weatherdata->find('@deg'); skal være my $degree = $vindretning->find('@deg');

Endret av Sokkalf^
Lenke til kommentar

Det er to feil i scriptet ditt:

 

Først og fremst må du endre linjen:

my $degree = $weatherdata->find('@deg');

til

my $degree = $vindretning->find('@deg');

 

$degree var nemlig ikke en verdi i det hele tatt :)

 

For det andre, find returnerer en XML::XPath::NodeSet. Derfor må du endre getDirection($degree) til

getDirection($degree->string_value())

 

Jeg fikset scriptet ditt. Laster opp fungerende versjon likesågreit:

 

#!/usr/bin/perl -w

use XML::XPath;
use LWP::Simple;

sub getDirection {
my $deg = $_[0];


if (($deg == 360 || $deg == 0 ) || ($deg < 22.5)) {
	return "N";
}
elsif ($deg >= 22.5 && $deg < 45) {
	return "NNE";
}
elsif ($deg >= 45 && $deg < 67.5) {
	return "NE";
}
elsif ($deg >= 67.5 && $deg < 90) {
	return "ENE";
}
elsif ($deg >= 90 && $deg < 112.5) {
	return "E";
}
elsif ($deg >= 112.5 && $deg < 135) {
	return "ESE";
}
elsif ($deg >= 135 && $deg < 157.5) {
	return "SE";
}
elsif ($deg >= 157.5 && $deg < 180) {
	return "SSE";
}
elsif ($deg >= 180 && $deg < 202.5) {
	return "S";
}
elsif ($deg >= 202.5 && $deg < 225) {
	return "SSW";
}
elsif ($deg >= 225 && $deg < 247.5) {
	return "SW";
}
elsif ($deg >= 247.5 && $deg < 270) {
	return "WSW";
}
elsif ($deg >= 270 && $deg < 292.5) {
	return "W";
}
elsif ($deg >= 292.5 && $deg < 315) {
	return "WNW";
}
elsif ($deg >= 315 && $deg < 337.5) {
	return "NW";
}
elsif ($deg >= 337.5 && $deg < 360) {
	return "NNW";
}
else {
	return "?";
}
}

my $data_url =
"http://www.yr.no/place/Norway/Akershus/Asker/Vollen/varsel.xml";

# get data and drop it in a file
my $xml_data = get ($data_url);
my $xp = XML::XPath->new(xml => $xml_data);
my $weatherdata = $xp->find('/weatherdata/forecast/tabular/time')->get_node(1);

my $temperatur = $weatherdata->find('temperature')->get_node(1);
my $vindhastighet = $weatherdata->find('windSpeed')->get_node(1);
my $vindretning = $weatherdata->find('windDirection')->get_node(1);
my $nedboer = $weatherdata->find('symbol')->get_node(1);
my $degree = $vindretning->find('@deg');


print "Temp: ".$temperatur->find('@value')."°C | Vindhastighet: ".$vindhastighet->find('@mps')."m/s | Vindretning: ".$degree."° (".getDirection($degree->string_value()).")| ".$nedboer->find('@name');

Endret av cyclo
Lenke til kommentar

Ikke noe problem :)

 

Hehe. Jeg gjorde motsatt. Jeg så string_value() feilen med en gang, den andre feilen derimot brukte jeg en stund på å finne.

 

Lykke til med videre perl. Perl er helt sinnsykt genialt når man først har lært seg å bruke det orntlig.

Endret av cyclo
Lenke til kommentar

Jeg så perl for første gang i 1997, og det var "love at first sight". Jeg bruker perl til absolutt alt av scriptoppgaver. Til større oppgaver blir det java eller c#. Lærte også c++ i 1997, men klarte aldri helt å like det, så dermed har det gått mer eller mindre i glemmeboka.

 

Forøvrig om du er interesert i perl, så bør du sette deg ned og lære regexp først som sist. Når du virkelig kan regexp, så blir perl noe av det kraftigste du kommer til å komme borti. Regexp er rett og slett helt genialt :)

 

PS! For å gjøre funksjonen din litt mer oversiktelig kunne du gjort noe slik som:

 

return "N" if (($deg == 360 || $deg == 0 ) || ($deg < 22.5));
return "NNE" if ($deg >= 22.5 && $deg < 45);
return "NE" if ($deg >= 45 && $deg < 67.5);
.
.
etc.

Endret av cyclo
Lenke til kommentar

Og enda et forslag (Obs, jeg har ikke fyllt ut hele arrayet, det gadd jeg ikke):

 

#!/usr/bin/perl -w

use XML::XPath;
use LWP::Simple;

@dirs = ([22.5,45,"NNE"],[45,67.5,"NE"],[57.5,90,"ENE"]);
$d = @dirs;

sub getDirection {
	my $deg = $_[0];
return "N" if (($deg == 360 || $deg == 0 ) || ($deg < 22.5));
	foreach (0..$d-1) {
	return $dirs[$_][2] if ($deg>=$dirs[$_][0] && $deg<$dirs[$_][1]);
}
return "?";
}

my $data_url =
"http://www.yr.no/place/Norway/Akershus/Asker/Vollen/varsel.xml";

# get data and drop it in a file
my $xml_data = get ($data_url);
my $xp = XML::XPath->new(xml => $xml_data);
my $weatherdata = $xp->find('/weatherdata/forecast/tabular/time')->get_node(1);

my $temperatur = $weatherdata->find('temperature')->get_node(1);
my $vindhastighet = $weatherdata->find('windSpeed')->get_node(1);
my $vindretning = $weatherdata->find('windDirection')->get_node(1);
my $nedboer = $weatherdata->find('symbol')->get_node(1);
my $degree = $vindretning->find('@deg');


print "Temp: ".$temperatur->find('@value')."°C | Vindhastighet: ".$vindhastighet->find('@mps')."m/s | Vindretning: ".$degree."° (".getDirection($degree->string_value()).")| ".$nedboer->find('@name');

 

Æsj. Du ser hvor hekta jeg er på perl, klarer bare ikke holde meg unna. Håper i hvertfall du fikk noen ideer ut av det jeg skrev.

Lenke til kommentar
  • 2 uker senere...

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...