Kebmans blogg

Arma 3: Fyll bensin på ditt helikopter

Posted in Data, Programmering, Scripting, Spill by kebman on 28/09/2013

En enkel oppskrift på hvordan kode fylling av drivstoff på ditt helikopter i Arma 3.

Forhåndskunnskaper: Du må minimum kunne plassere objekter ved hjelp av editoren i spillet. Hvis du ikke kan det enda, se her: http://www.youtube.com/watch?v=oN8s58xEi0k
Ellers er prosessen forklart veldig nøye. Teskje-metoden here we come! 😀

Oppskrift

Åpne opp kartet du har lyst å jobbe med og plasser enten en player eller et helikopter som du gjør til player.
Gi helikopteret navnet myHeli. Lagre kartet med Mission Name «Trigger» og som User Mission.

Plasser så en trigger (finnes under flagg-ikonet).
Sett størrelsen slik at det passer med landingsplassen din.
Pass også på at den er satt til Repeatedly og at enten din gruppe, eller alle, kan trigge den.
Repeatedly betyr ganske enkelt at du kan bruke triggeren til å fylle bensin så mange ganger du måtte ønske.

I boksen Condition, skriv følgende kode:

({getPosATL _x select 2 < 0.1} count thisList) > 0 && fuel myHeli < 0.9;

Forklaring av koden

Den første delen av koden gjør at triggeren kun fyrer av om helikopteret er under 0,1 meter over bakken (Merk: i USA bruker de punktum for å skille mellom desimaler, mens vi bruker komma her i Norge).
Den andre delen av koden (etter &&) gjør at triggeren kun fyrer av om helikoptere har under 90 prosent drivstoff i tanken.

getPosATL finner plassering og høyde over land. Det kommer som en array _x bestående av posisjonskoordinatene 0=X, 1=Y og 2=Z.
Vi er selvsagt bare interessert i høydevektoren Z, derfor står select 2 der.
For at det ikke skal fylles drivstoff før helikopteret står på bakken, vil ikke «listen» bli telt som 1 før høyden er under 0,1 meter over land.

I tillegg vil ikke triggeren skyte av før helikopteret har under 90 prosent drivstoff.
&& står simpelten for en logisk «og», som betyr at begge delene av kondisjonalen må være sann før triggeren fyrer av. Det holder ikke at bare én av dem er det.

I boksen On Act (On Activation), skriv følgende kode:

nul = [] execVM "fuel.sqf";

Forklaring til koden

Dette lager en null-array, fordi det av en eller annen grunn kun kan kjøres fra en sånn… Og execVM kjører ganske enkelt filen fuel.sqf.

Denne filen finnes naturlig nok ikke enda, derfor er det på tide at du starter opp din beste tekst-editor (Notepad++, f.eks., men vanlig Notisblokk funker også).

I tekst-editoren, skriv inn følgende skript:

heliFuel = fuel myHeli;
addFuel = 0.1;
while {heliFuel < 1.0} do {
     myHeli setfuel heliFuel + addFuel;
     addFuel = addFuel + 0.1;
     sleep 0.2;
};

Lagre skriptet som fuel.sqf i mission-folderen. Denne ligger vanligvis på C:\Users\DittBrukernavn\Documents\Arma 3\missions\Trigger.Map . I alle fall gjelder det Windows 7
For alt jeg vet har du den på D-disken. Bytt i så fall C: ut med D:. DittBrukernavn bytter du selvfølgelig med ditt brukernavn.
.Map er det kartet du har valgte, enten Stratis, Altis eller et annet kart.

Forklaring av skriptet

heliFuel = fuel myHeli lagrer simpelten hvor mye drivstoff helikopteret har igjen i tanken i variabelen heliFuel.
addFuel lagrer hvor mye som skal fylles hver gang skriptet slår en ny løkke. Det definerer altså hvor fort tanken fylles opp. Jo høyere tall, jo fortere går det, men det er ingen grunn til å sette tallet over 1, siden 1 er normalisert til å bety «full tank».
while-løkken kjører så lenge det er plass til mer drivstoff i tanken (så lenge heliFuel er under 1), men ikke noe mer enn det.
Inni while-løkken, legger setfuel ganske enkelt den eksisterende mengden drivstoff (heliFuel) sammen med ny mengde drivstoff (addFuel).
sleep pauser ganske enkelt løkken så mange sekunder det er angitt (0,2 sekunder i dette tilfellet).

Som du ser er det et ganske lite skript. Kanskje tenker du da at det kunne vært i kondisjonal-feltet i triggeren. Grunnen til at det ikke kan være der, er fordi triggeren ikke godtar pauser. Det er kun mulig i eksterne skript, derfor trenger det å være i sin egen fil.

Valgfritt

Om du vil at det skal se ekstra bra ut, plasser også ut et helipad-objekt under triggeren fra Empty > Objects (Signs).
Det er nemlig litt lettere å finne igjen trigger-området i spillet om du også har en synlig landingsplass assosisert med den. 😉

Advertisements

SMPTE-synkronisering på GitHub

Posted in Data, Filmredigering, Internett, Programmering, Programvare, Scripting, Teknologi, Video by kebman on 13/05/2013

Endelig har jeg oppdaget GitHub og lagt ut mitt første prosjekt der. Driver på med et videoprosjekt nå, men jeg fikk noen problemer med SMPTE-koder (tidskoder for video) som ikke stemte med hverandre da jeg logget. Først sjekket jeg ut noen programmer, men de dugde ikke, så da bare satte jeg i gang å lage min egen kode.

Sjekk det ut her: https://github.com/kebman/Simple-SMPTE-class-in-PHP

Hvordan traversere JSON med PHP

Posted in Programmering, Scripting, Teknologi, Webdesign by kebman on 10/04/2013

Nå og da trenger man å traversere JSON-data med PHP. Da kan det være greit å vite hvordan man gjør det. Her er et lite eksempel.

La oss si du har fått en fil, folk.json. Her er den:

{
 "folk": [
 { "fornavn": "Ola", "etternavn": "Nordmann" },
 { "fornavn": "Kari", "etternavn": "Nordmann" },
 { "fornavn": "Lars", "etternavn": "Medelsvensson" },
 ]
}

Det du har her er for alle praktiske formål en flerdimensjonell array. Ofte kan slike by på litt hodebry, men egentlig er det ganske enkelt når man holder på med JSON. Alt du trenger å gjøre er å gjøre om innholdet i filen til et PHP-objekt, slik:

<?php
$json_object = json_decode(file_get_contents('folk.json'));
?>

Her er det som skjer i koden: For det første opprettes en variabel til å hodle objektet på plass, $json_object. Deretter må folk.json leses inn til PHP med funksjonen file_get_contents(). Og til slutt må innholdet som er lest inn gjøres om til et objekt med funksjonen json_decode() – om koden den blir servert er korrekt JSON, vel å merke.

Så OK, vi har nå et JSON objekt lagret i PHP. Hva nå? Vel, siden det er et objekt, er det veldig lett å få tak i delene det består av med foreach. Vanligvis brukes foreach til å traversere flerdimensjonelle arrays, men faktisk kan det også brukes til å traversere objekter. Bare se her:

<ul><?php
foreach ($json_object->folk as $key=>$value) {
 echo "<li>" . $value->fornavn ." ". $value->etternavn . "</li>";
}?></ul>

De vi ber foreach-løkken om å gjøre her, er å skippe direkte til objektet folk, og å dele innholdet i objektet opp i nøkler og verdier. Når det er gjort, har vi – siden det er et objekt – direkte tilgang til underobjektene. Hvert av navneparene er her underobjekter av objektet folk, og vi kan nå hver del av dem ganske enkelt med å peke til riktig underobjekt.

Resultatet er en liste, slik:

  • Ola Nordmann
  • Kari Nordmann
  • Lars Medelsvensson

Vil du nå enda dypere, må du nøste flere foreach-løkker inn i hverandre, men dette er altså den grunnleggende idéen.

Gi nye filetternavn til flere filer samtidig

Posted in Programmering, Scripting, Teknologi by kebman on 23/12/2012

Sannsynligvis har du vært borti at du trenger å gi nytt filetternavn til flere filer av samme type. Det er noe skikkelig herk, så derfor skrev jeg et lite Perl-script for å gjøre jobben raskere.
Her er det:

#!/usr/bin/perl
# ChSuff v1.0 by Kebman
# Change the suffixes of all files of a given type in a dir
use strict;
use warnings;
use File::Copy;

if ($#ARGV +1 == "2") {
	if ($ARGV[0] eq $ARGV[1]) {
		print "Sorry arguments cannot be equal.\n";
	} else {

		# -- Main Code -- #
		my $old_suffix = "." . "$ARGV[0]";
		my $new_suffix = "." . "$ARGV[1]";

		my @old_filenames = grep (-f, <*$old_suffix>); # store only files with old suffix

		if (scalar(@old_filenames) == 0) { # If there are 0 occurences of given file
			print "Sorry, there are no files with the suffix $old_suffix\n";
		} else {
			my $old_length = length($old_suffix); # Check length of input
			my $old_name;
			my $new_name;
			my $without_suffix;

			foreach $old_name (@old_filenames) { # trip trough the array of filenames
				# remove old suffix with subrstr()
				$without_suffix = substr($old_name, 0, -$old_length);
				# rename the suffix of each file
				$new_name = "$without_suffix" . "$new_suffix";
				move($old_name, $new_name);
			}
		}
		# ---- #
	}
} else {
	print "\033[2J"; # These two incantation clears the screen
	print "\033[0;0H"; # ... and resets the cursor
	print "chsuff v1.0 by Kebman\nRename the suffixes of all files of a certain type in a dir\n";
	print "---\nUSAGE: chsuff [old suffix] [new suffix]\n---\n";
	print "Example: chsuff txt html\n";
	print "Will change the old suffixes all .txt-files to .html in the directory you're in\n";
}

Så langt fungerer det på Mac OS X og dermed sikkert også på Linux-maskiner, men det er usikkert om det vil fungere på en Windows PC grunnet bruken av glob. Føl deg i så fall fri til å skrive om på kildekoden bare du husker å gi meg litt cred. 🙂

For ordens skyld, glem nå det lille programmet som på de fleste systemer kalles «rename». 😉

Norske tegn med HTML

Posted in Design, Hobby, Internett, Scripting, Teknologi, Typografi, Webdesign by kebman on 02/07/2012

Mange har problemer med å få norske tegn og bokstaver første gangen de koder HTML. Med HTML5 er løsningen enklere enn noen gang.

Basiskoden for å få gyldig HTML5 ser slik ut:

<!DOCTYPE html>
<html>
<head>
	<title>Min tittel</title>
</head>
<body>
	<p>Min første hjemmeside.</p>
</body>
</html>

Kodetabell

Men fortsatt ser de norske bokstavene skikkelig rare ut når du åpner HTML-filen i en nettleser. Det kommer av et eldgammelt problem med datamaskinene; at de var laget kun for det engelske alfabetet. For å korrigere problemet, laget produsentene ekstra kodetabeller som også inneholdt europeiske tegn – deriblant vår egen æ, ø og å – men nettleserne tar bare høyde for disse om du fysisk angir riktig kodetabell med HTML-kode.

Du angir riktig kodetabell ved å legge inn følgende HTML-kode i hodet av HTML-dokumentet ditt:
<meta charset="utf-8" />

Hele HTML-koden vil da se slik ut:

<!DOCTYPE html>
<html>
<head>
	<title>Min tittel</title>
	<meta charset="utf-8" />
</head>
<body>
	<p>Min første hjemmeside.</p>
</body>
</html>

Her er kodetabellen UTF-8 fra Unicode brukt. Dette er den kodetabellen som har har de vanligste europeiske tegnene i seg, og derfor også den kodetabellen som er mest utbredt.

Feilsøking

Om norske tegn fortsatt vises feil er det stort sett en av to grunner til det:

  1. Det er ikke angitt noen kodetabell i HTML-koden, eller feil tabell er angitt.
  2. Filen er lagret med en annen kodetabell enn den du har satt i HTML-koden i tekstredigeringsprogrammet du har brukt.

Selv om du angir riktig kodetabell i HTML-koden, hjelper det ikke om du har lagret selve datafilen med feil kodetabell i redigeringsprogrammet. Noen redigeringsprogram har en fast kodetabell de bruker, men i de fleste programmene kan du angi hvilken kodetabell selve datafilen din skal lagres med. Pass på at det da at du har valgt UTF-8, eller Unicode (UTF-8) som tegnformat før du lagrer filen. Hvor du endrer det, er forskjellig fra hvilket program du bruker, men som regel finnes det i innstillingene.

I redigeringsprogrammet jeg bruker, TextWrangler, er det angitt på barren under tekstredigeringsvinduet, og det er bare å klikke på teksten, så kommer det en liste med alle kodetabellene jeg måtte ønske.

Tegnkoding i xHTML

Med xHTML er det litt mer plunder å få norske tegn.

For det første, trenges XML-versjon sammen med kodetabell helt øverst i dokumentet, før !DOCTYPE, slik:
<?xml version="1.0" encoding="UTF-8"?>

Og endelig må det velges riktig kodetabell for HTML-koden i hodet, slik:
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />

Hvordan gjøre ordsøk i MySQL

Posted in Programmering, Programvare, Scripting, Teknologi by kebman on 25/02/2012

Så du trenger å søke etter ord i databasen din? Her er noen kjappe eksempler på hvordan du kan gjøre det.

Fulltext-søking er kanskje den greieste måten å søke etter ord i SQL-databaser. Det er veldig kjapt og fungerer bra så lenge ordet er lenger enn tre bokstaver. Grunnen til dette er at det krever ekstra kapasitet å indeksere kortere ord, spesielt om de opptrer ofte. Slik bruker du fulltext-søk:

SELECT * FROM tabell
WHERE MATCH(felt)
AGAINST('søkeord' IN BOOLEAN MODE);

Men hva om du ønsker å søke etter ord med færre enn fire bokstaver? Vel, her er noen alternativer.

Ved å bruke LIKE kan du søke etter felter som inneholder ditt søkeord, enten det er del av større ord eller ikke. Du får som regel ganske mange treff med denne, og det er ikke like kjapt som Fulltext-søk.

SELECT * FROM tabell
WHERE felt
LIKE '%søkeord%';

Eksperimenter med å fjerne prosenttegn foran eller bak. Prosenttegnet fungerer som et «wildcard» eller en joker, og betyr «hvilken som helst tegn».

Men kanskje du bare vil ha hele ord som står alene? Prøv i så fall regular expressions.

SELECT * FROM tabell
WHERE felt
REGEXP '[[:<:]]søkeord[[:>:]]';

Merk at denne vil også gi treff på ord som har bindestrek foran eller bak. En annen hake er at regular expressions kan være litt tregt fordi det krever en del ekstra prosesseringskraft. Det er ikke alltid det er så viktig, men skal du lage noe som er stort og blir hyppig brukt av svært mange brukere, risikerer du fort at forsinkelsene blir merkbare.

Vil du kun ha helt enslige ord, må du søke etter ord som har mellomrom foran og bak. Prøv i så fall denne:

SELECT * FROM tabell
WHERE Locate('søkeord ', felt) > 0
AND Locate(' søkeord', felt) > 0;

Legende:

  • tabell: Databasetabellen du ønsker å søke i
  • felt: Feltet i tabellen som du ønsker å søke i
  • søkeord: Søkeordet du ønsker å bruke

PHP kobler ikke til MySQL via localhost

Posted in Internett, Programmering, Scripting, Teknologi, Webdesign by kebman on 24/02/2012

Fikk plutselig feil da jeg prøvde å koble til MySQL-databasen via PHP i dag. Vips så ble det en aldri så liten detektivhistorie.

Koden jeg bruker for å koble til MySQL med PHP er veldig enkel, godt testet, og har fungert mange ganger før. Ikke det mest avanserte og ikke objektorientert, men den egner seg godt for testing. Her er den:

$host = 'localhost';
$user = 'root';
$pass = 'password';
$link = mysql_connect($host, $user, $pass);
if (!$link) {
   die('MySQL error '. mysql_errno() . ': ' . mysql_error());
}

Kort forklart, hvis $link klarer å koble opp til databasen går alt som det skal, mens om variablen inneholder feil, blir koblingen brutt og det blir istedenfor sendt tilbake noen feilmeldinger. Og her er den jeg fikk:

MySQL error 2002: No such file or directory

Så jeg prøvde å bytte ute passord, bruker, og byttet fra localhost og til 127.0.0.1, og heureka! Da funket det. Men likevel var jeg jo like langt i forhold til localhost. Jeg blunket litt med de våte øynene mine, og et slags mørke la seg over hjernen min. Feilmeldingen sa meg ikke en dritt, og jeg skjønte ikke hvorfor det bare funket med den lokale IP-adressen. Her var det bare å sette i gang og google.

En av tingene jeg testet var om MySQL i det hele tatt reagerte, men det visste jeg jo at den gjorde, fordi jeg kunne koble til via terminalen og via Sequel Pro. Likevel prøvde jeg å pinge den over telnet i terminale, slik:

telnet localhost 3306

Her tittet MySQL frem og sa hei som normalt, så dette var i orden, og fortsatt var jeg like lite klok.

Heldigvis kom jeg ganske snart over denne fine siden: C.5.2.2. Can’t connect to [local] MySQL server

Der sto det utrolig mye unødvendig og irrelevant, men jeg bet meg i alle fall merke i de tingene som faktisk stemte – blant annet en serie tester man kan gjøre i terminalen, disse her:

  1. mysqladmin version
  2. mysqladmin variables
  3. mysqladmin -h `hostname` version variables
  4. mysqladmin -h `hostname` --port=3306 version
  5. mysqladmin -h host_ip version
  6. mysqladmin --protocol=SOCKET --socket=/tmp/mysql.sock version

Da jeg kom til nummer tre på listen, skjønte jeg at noe var galt. Det gikk helt fint om jeg byttet ut `hostname` med localhost, men da jeg brukte den riktige koden, `hostname`, fikk jeg en feilmelding:

mysqladmin: connect to server at 'kebman.local' failed
error: 'Host '10.0.0.7' is not allowed to connect to this MySQL server'

Dette skjønte jeg ikke noe særlig mer utav heller, men det ante meg at det kunne være at en eller annen trodde at kebman.local var localhost, men det er jo slett ikke tilfelle. Dessuten er jo ikke 10.0.0.7 adressen til localhost heller (127.0.0.1 er adressen til localhost).

Lenger nede i dokumentet sto det noe om å finne navnet på socket-filen som brukes for å koble via localhost:

netstat -ln | grep mysql

Svaret jeg fikk, var dette:

/tmp/mysql.sock

«Hm», tenkte jeg nå. «Kan dette ha noe med denne kebman.local-greia å gjøre, tro? Feilen må jo ligge i php.ini et sted (filen man bruker til å konfigrere PHP med), men hvor?» Hadde også lest noe om det på erværdige stackoverflow.com. Jeg søkte igjennom alt som hadde med MySQL i php.ini, og endelig fant jeg det. I php.ini var det en annen adresse til mysql.sock. Jeg endret det til adressen jeg fikk opp med netstat-koden, og voila, endelig funket det å koble til MySQL via localhost med PHP igjen.

For å redigere php.ini på Mac må du først ha rot-passordet til maskinen din. Deretter er det letteste å bruke TextWrangler (gratis) til å åpne opp /etc/php.ini for redigering. Du kan også åpne filen med pico eller et annet UNIX-program for tekstredigering gjennom sudo-kommandoen (sudo gir ordre som rot-bruker).

Perl-hack for å hacke terminalene i Fallout 3

Posted in Perl, Scripting, Spill by kebman on 16/07/2011

Det er ikke bare vanskelig å hacke terminalene i spillet Fallout 3 – det er også tidkrevende. Selv om du leser en kjempebra tutorial – for eksempel denne FALLOUT 3: Hacking FAQ v1.2 av Dave Bosley – så kan det ta lang tid å hacke passordet til en terminal.

Men frykt ikke. Siden det er ferie har jeg programmert to Perl-scripts som du kan bruke til å korte ned tiden det tar å hacke en terminal betraktelig.

For å bruke scriptene må du for det ha Perl installert. Har du PC må du kanskje laste det ned, mens er du så heldig å ha Mac så er det allerede forhåndsinstallert. Deretter må du kopiere koden inn i hver sin tekstfil. Kall f.eks filene for bestcandidate.pl og shortenlist.pl.

Det første skriptet brukes til å finne det beste ordet å teste først. Dette gjøres ved å finne ut hvilket ord som har mest til felles med de andre. For å bruke skriptet må du skrive ned alle ordene som kommer på terminalskjermen i spillet. Så må du kopiere dem inn på riktig plass i scriptet. Deretter må du kjøre scriptet fra kommandolinjen din, ved å skrive inn perl bestcandidate.pl.

Her er det første scriptet:

#!/usr/bin/perl
use strict;
use warnings; 

# here's the list of candidate words
my @list = qw(
PARTNERSHIPS
REPRIMANDING
CIVILIZATION
APPRECIATION
CONVERSATION
CIRCUMSTANCE
PURIFICATION
SECLUSIONIST
CONSTRUCTION
DISAPPEARING
TRANSMISSION
APPREHENSIVE
ENCOUNTERING
); # end of the list of words it should be checked against    
# populate two dimensional array with the list,
# so we can compare each letter with the other 
# letters on the same row more easily 
my $list_length = @list;
my @words;

for (my $i = 0; $i < $list_length; $i++) {
    my @letters = split(//, $list[$i]);
    my $letters_length = @letters;
    for (my $j = 0; $j < $letters_length; $j++) {
        $words[$i][$j] = $letters[$j];
    }
}
# this gives a two-dimensional array like this: 
# @words = (    ["B", "A", "K", "E", "R"], 
#               ["S", "A", "L", "E", "R"], 
#               ["B", "A", "L", "E", "R"], 
#               ["C", "A", "R", "E", "R"], 
#               ["R", "U", "F", "F", "R"], 
# ); 
# now, on to find the word with most letters in 
# common with the other on the same row

# add up the score for each letter in each word
my $word_length = @words;
my @letter_score;
for my $i (0 .. $#words) {
    for my $j (0 .. $#{$words[$i]}) {
        for (my $k = 0; $k < $word_length; $k++) {
            if ($words[$i][$j] eq $words[$k][$j]) {
                $letter_score[$i][$j] += 1;    
            }
        }
        $letter_score[$i][$j] -= 1;
    }
}

# sum each score up
my @scores;
for my $i (0 .. $#letter_score ) {
    for my $j (0 .. $#{$letter_score[$i]}) {
        $scores[$i] += $letter_score[$i][$j];
    }
}

# find the highest score
my $max = $scores[0];
foreach my $i (@scores[1 .. $#scores]) {
    if ($i > $max) {
        $max = $i;
    }
}

# and print it all out :D
for my $i (0 .. $#letter_score ) {
    print "$list[$i]: $scores[$i]";
    if ($scores[$i] == $max) {
        print " <- best";
    }     
    print "\n";
}

Creative Commons License

Tester du det første scriptet uten å endre på innholdet, vil du få ut samme ord som i tutorialen til Bosley, nemlig APPRECIATION. I tutorialen kan du se at dette ordet har fire (4) av tolv mulige matches med det virkelige passordet (vist som 4/12 i spillet). Dette er viktig, fordi dette er ting vi må bruke for å korte ned listen av passordkandidater i det andre scriptet.

Det andre scriptet bruker du til å korte ned listen av mulige passordkandidater. Skriv inn ordet du testet på riktig plass, og pass på å få inn matchtallet på riktig plass. Kjør så scriptet fra kommandolinen, slik: perl shortenlist.pl

#!/usr/bin/perl
use strict;
use warnings; 

my $checkword = "APPRECIATION"; # the word to be checked
my $match = 4; # equal to the match you got from testing your checkword
my @checkletters = split(//, $checkword);

# the list of words:
my @wordlist = qw(
PARTNERSHIPS
REPRIMANDING
CIVILIZATION
APPRECIATION
CONVERSATION
CIRCUMSTANCE
PURIFICATION
SECLUSIONIST
CONSTRUCTION
DISAPPEARING
TRANSMISSION
APPREHENSIVE
ENCOUNTERING
); # end of the list of words it should be checked against 
print "$checkword has $match letters in common with:\n";

# split the word into single characters into an array with regexp //
foreach my $word (@wordlist) {
    next if $word eq $checkword;
    my @letters = split(//, $word);
    my $length = @letters; # determine how many letters to check

    my $eq_letters = 0;
    for (my $i = 0; $i < $length; $i++) {
        if ($letters[$i] eq $checkletters[$i]) {
            $eq_letters++;
        }
    }
    if ($eq_letters == $match) {
        print "$word\n";
    }
}

Creative Commons License

Må også rette en stor takk til folkene på Stackoverflow.com som har gitt mye uvurderlig hjelp til prosjektet.

Function og array i PHP

Posted in Økonomi, Programmering, Scripting, Webdesign by kebman on 10/11/2010

#Ruter, selskapet med ansvar for kollektivtransporten i Oslo og Akershus, har for mange billettyper å velge imellom, of derfor kan det være svært vanskelig å vite hva slags billett som er den beste å ha til en hver tid. Som ledd i et personlig korstog for å lage en kalkulator som regner ut den beste billettypen for deg – fordi Ruter sannsynligvis ikke har noen planer om det –  har jeg lekt meg litt med funksjoner og listevariabler i PHP.

<?php
// Pris på enkelbilletter for voksne i Akershus
// Nøkkel: sone => pris
$enkelBillA_v = array(1=>30,2=>40,3=>50,4=>60,5=>70,6=>80,7=>90,8=>100,9=>110,10=>120);

// Funksjon som lager barnebilletter av voksenbilletter
// Opprett funksjonen og send prisene for voksenbilletter til den
function enkelBarneBillA($voksenbilletter) {

// Gjør barnebillettene lik voksenbilettene
$barnebilletter = $voksenbilletter;
// Men gå igjennom alle prisene til barnebilettene...
foreach ($barnebilletter as &$value) {

// ...og del dem i to - HEEE-YAHH!
$value = $value / 2;

}

// Returner svaret ut av funksjonen
return $barnebilletter;
}

// Enkelbiletter for barn i Akershus
$enkelBillA_b = enkelBarneBillA($enkelBillA_v);
// Arrayen er lik outputen av funksjonen enkelBarneBillA(),
// og til denne funksjonen sender vi prisene på alle voksenbillettene
?>

Og en stort vanskeligere måte å dele et tall i to på, skal du vel egentlig lete lenge etter… Men nå har du altså et lite eksempel på hvordan funksjoner kan brukes sammen med listevariabler. Du kan teste den nye variabelen ved å ta med følgende kode:

<?php print_r($enkelBillA_b); ?>

Heldigvis finnes det en litt enklere måte å gjøre det på:

<?php
// Funksjon som halverer det den får inn:
function halver(&$value) { $value = $value / 2; }
// Kopierer priser for voksenbilletter til $barnebill:
$barnebill = $enkelBillA_v;
// Spaserer igjennom $barnebill og halverer alle prisene:
array_walk(&$barnebill, 'halver');
// Helt sant, bare sjekk:
print_r($barnebill);
?>