Sokkalf™ Skrevet 2. desember 2007 Del Skrevet 2. desember 2007 (endret) 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 3. desember 2007 av Sokkalf^ Lenke til kommentar
cyclo Skrevet 2. desember 2007 Del Skrevet 2. desember 2007 (endret) 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 2. desember 2007 av cyclo Lenke til kommentar
cyclo Skrevet 2. desember 2007 Del Skrevet 2. desember 2007 Skrev et kjappt test script for å illustrere hva jeg mener litt bedre: #!/usr/bin/perl $tall = "1,25"; print "\n".($tall+3); $tall =~ s/,/./; print "\n".($tall+3)."\n"; Gir følgende output: 44.25 Lenke til kommentar
Sokkalf™ Skrevet 2. desember 2007 Forfatter Del Skrevet 2. desember 2007 (endret) 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. 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 3. desember 2007 av Sokkalf^ Lenke til kommentar
cyclo Skrevet 3. desember 2007 Del Skrevet 3. desember 2007 (endret) 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 3. desember 2007 av cyclo Lenke til kommentar
Sokkalf™ Skrevet 3. desember 2007 Forfatter Del Skrevet 3. desember 2007 Herlig! Så den første feilen selv, så string_value() var alt jeg trengte. Tusen takk! Lenke til kommentar
cyclo Skrevet 3. desember 2007 Del Skrevet 3. desember 2007 (endret) 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 3. desember 2007 av cyclo Lenke til kommentar
Sokkalf™ Skrevet 3. desember 2007 Forfatter Del Skrevet 3. desember 2007 Jupp, har drevet litt med C og Java, og litt med shellscripting i Bash. Men til denne oppgaven syntes jeg at jeg trengte en mellomting, og da kastet jeg meg over perl. Kommer nok til å fortsette å leke litt med det. Lenke til kommentar
cyclo Skrevet 3. desember 2007 Del Skrevet 3. desember 2007 (endret) 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 3. desember 2007 av cyclo Lenke til kommentar
cyclo Skrevet 3. desember 2007 Del Skrevet 3. desember 2007 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
Sokkalf™ Skrevet 3. desember 2007 Forfatter Del Skrevet 3. desember 2007 Hehe, tusen takk for alle forslag, setter stor pris på det! Det med regexp har jeg vært minimalt borti i scripts jeg har skrevet i bash, har dog ikke brukt annet enn enkel substitute (s/a/b/ osv). Skal dykke dypere nedi det der. Lenke til kommentar
Torbjørn Skrevet 16. desember 2007 Del Skrevet 16. desember 2007 hm.. det firster litt å ty til grunnleggende matte og bruke 360/16 = 22.5 for å sjekke intervallene se eller nytt for perl 5.10 http://search.cpan.org/~rgarcia/perl-5.10...._Match_operator natifve switch support Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå