Blog

En tillbakablick på Bokarenan och Symfony

När jag började mitt projekt Bokarenan nu under hösten så hade jag ett mål att göra min kod mer hanterbar. Jag hade kommit till en punkt då jag inte kände att jag hade någon bra överblick över hur min kod hängde samman. Bokarenan var byggd med PHP men utan att använda någon objektorienterad struktur. Varje sida i applikationen var en egen PHP-fil. Min ”om” sida fanns till exempel på bokarenan.se/om.php, och min sökfunktion fanns på bokarenan.se/search.php. Eftersom man kunde logga in så behövde varje sida inkludera mina variables.php- och functions.php-filer. De användes för att dels hitta rätt filer (sökvägarna sparades i variables.php, bland annat sökvägen för functions.php) och dels för att kontrollera om användaren var inloggad och om användaren varit inaktiv för länge. Det var även viktigt att variables.php inkluderades före functions.php för att functions använde variabler i variables.php. Ju fler funktioner jag ville lägga till i applikationen, desto svårare blev det att överblicka att allting kom i rätt ordning. Jag kände att jag behövde göra min kod mer logiskt sammanhängande för att få rätsida på allt ihop. Svaret var Objekt Orienterad Programmering (OOP).

Jag är hyfsat bekant med OOP sedan allt jag gjort i Java har varit att jonglera objekt. Jag har till och med ägnat mig åt designprincipen MVC (Model – View – Controller) när jag prövat att göra en webapplikation i Spring Boot. Detta är ett framework för Java som jag gillade att använda. Men applikationen gjorde jag aldrig färdig för publicering. Kan hända att det projektet dyker upp här. Jag kallade den för Shipstorm och den var till för att dokumentera båtar som jag tyckte såg fina ut.

När jag nu ville göra en uppdaterad version av Bokarenan så ville jag göra OOP och gärna använda ett MVC-framework. Jag visste ju att det skulle hjälpa mig så mycket att få rätt struktur på allt ihop. Jag visste bara inte vart jag skulle hitta ett framework som skulle passa mig och som skulle kunna funka på mitt webbhotell.

Jag läste en del böcker om PHP samt en kurs på Packt Publishing som guidade mig helt okej igenom olika steg för att göra ett eget microframwork, för att sedan ta steget till att börja använda ett färdigt framework. Det blev Symfony till slut. Symfony upplevde jag som väldigt flexibelt. Det var enkelt att välja vilka komponenter av Symfony jag ville ha. Mina favoriter är Twig, Security och Doctrine. Twig gör det enkelt att generera sidor för dynamiskt innehåll. Security hjälper till med inloggning och autentisering. Och Doctrine gör det väldigt enkelt att hämta objekt från en databas.

Medan jag upplevt det som mycket enkelt att utveckla applikationen på min dator; den medföljande virtuella servern gjorde det hur smidigt som helst, så kvarstod utmaningen att få allt att funka på mitt webbhotell. Jag vill inte exponera känslig information så som databasuppgifter, men vill ju att besökare ska kunna nå min hemsida. Via mitt webbhotell så kan man logga in och använda deras filhanteringssystem. Nackdelen är att detta bara erbjuder den allmänna/publika sidan av hemsidan.

Lösningen hette FileZilla, ett FTP-program, som gjorde det möjligt för mig att även komma åt den yta som inte är publik. Jag kunde därmed dela upp min applikation i dess publika och dess privata delar. På den publika arean så la jag ingångsvägen för applikationen – index.php, samt CSS-, JS-, och bildfiler. På den privata arean la jag applikationslogiken; med Controllers, Entities och template-filer. Men bara detta gjorde inte applikationen redo för användning helt. Jag kunde nu ladda första sidan till Bokarenan på bokarenan.se. Men inga länkar funkade, även om applikationen nu kunde kommunicera med databasen. Det visade ju sig att bokarenan.se egentligen laddade bokarenan.se/index.php. Alla länkar gick genom denna fil. Så för att ladda till exempel bokarenan.se/om behövde jag ange bokarenan.se/index.php/om. Detta var inte riktigt snyggt i mitt tycke, så något behövde jag göra. Och in kommer RewriteEngine som jag kan komma åt med hjälp av .htaccess. Det är en fil jag lägger på min area och som instruerar servern till att översätta allting igenom index.php-filen utan att det ska synas i adressfältet.

Det har visserligen tagit mig hela hösten att uppdatera Bokarenan med Symfony och ersätta den spagettikod som utgjorde förra versionen, men jag har haft en rimlig anledning att dra ut på det: bebisar. Nu är allt uppe och funkar. Jag kan definitivt tänka mig att använda Symfony för fler projekt och det utgör en bra grund för att underhålla den nya versionen av Bokarenan.


84% av alla kunder är nöjda med Slajm

Idag skriver jag åter om statistik. Denna gång fokuserar jag på proportioner med fokus på en parameter. Ibland vill man göra en undersökning som fokuserar på hur stor andel av en population som ger lyckosamma utfall. Det kan handla om hur många produkter från en tillverkningsprocess som ej är defekta, eller det kan handla om hur många väljare som kan tänka sig rösta för ett särskilt alternativ. Denna gång återvänder jag till Slajm-farmaren för att undersöka hur stor andel av hans kunder som är nöjda med den slajm som han säljer.

Vi tar ett urval med storlek n=250. Antalet nöjda kunder är X=210. För att räkna ut andel nöjda kunder i vårat urval så har vi :

Vi vill gärna kunna säga något om alla kunder, inte bara kunderna i vårat stickprov. Vi väljer att svara med ett konfidensintervall på en konfidensnivå 95%. För att räkna ut intervallet så har vi vår andel (0,84) plus/minus en marginal:

Marginalen räknas ut med hjälp av det kritiska värdet z* som tas fram för den angivna konfidensnivån 95%. Det ger oss z*=1,96. Det kritiska värdet här är givet vid en särskild konfidensnivå när vi har en t-fördelning. Det liknar antalet standardavvikelser från medelvärdet i en normalfördelning. Det kritiska värdet multipliceras med standardfelet för urvalet. Det ger oss följande uträkning:

Vi har alltså att 84% av kunderna är nöjda med Slajm, med en felmarginal på 5% på en 95%-konfidensnivå. Slajm-farmaren Frans är inte helt nöjd med detta, för det finns en risk att han inte har uppnått en kundnöjdhet över 80%. Frans har lite att tänka över nu. Varför finns det så många kunder som inte är nöjda? Det är ett mysterium som Frans får utreda framöver. Tills dess är vi klara för den här gången.

Nästa gång, på fredag, tänker jag återvända till programmering och skriva ett par rader om det. Hur enkelt var det egentligen att jobba med Symfony och gick det bra att ladda upp applikationen på ett webbhotell? Vi ses då!


Tredje advent, nu är Bokarenan uppe

Måndag och en vecka närmare jul. Vi är i Tredje Advent och snart blir det ett uppehåll över jul och nyår när jag fokuserar på att umgås med familj. Lite nyheter jag har att komma med är att mitt projekt för Bokarenan har kommit till basversionen, eller vad man skulle kunna kalla för Minimal Viable Product. Spana in bokarenan.se och dela med dig av dina läsupplevelser. För närvarande behöver medlemmar lägga till grundinformation för böcker de recenserar, men jag har börjat lära mig lite Python för att kunna stötta upp med detta. Tanken är att skapa en Web Crawler som kan samla in information om böcker, och på så sätt underlätta för medlemmar i deras ifyllande. Jag är mycket nöjd över att ha kommit så här långt.

Men denna vecka går annars åter i statistikens tecken. Denna vecka kommer jag skriva om att bedöma statistiskt underlag när man bara har med en variabel att göra. Exempelvis hur många anser att Slajm är en produkt de skulle vilja köpa? Där jag tidigare har skrivit om medelvärden handlar det här om att göra bedömning utifrån fördelningar. Mer om detta på onsdag. Vi ses då!


Tillbaka igen

Hej igen. Det var en vecka senast jag skrev något, men nu är jag tillbaka. Ibland blir man sjuk! Senast skrev jag att jag skulle återkomma om signifikansnivå. Denna fredag handlar om när vi bortser från vår nollhypotes. Förra gången så hade vi en nollhypotes som sa att produktion av slajm var 100 ml i medel. Vi kunde bortse från denna nollhypotes till förmån för vår alternativa hypotes: att slajmproduktionen var lägre än så. Vi kunde se att sannolikheten för att få det medelvärde vi fick i vårt urval, om medelvärdet på 100 ml i populationen skulle vara rätt, var 1,25%. Det var ganska lågt och vi slöt oss till att det vi hade förutsatt i nollhypotesen inte stämde. Egentligen så hoppade vi över ett steg här, som är ganska viktigt att inkludera tidigt i undersökningen. Anledningen till att vi vill inkludera det tidigt är att vi inte vill låta våra gränsvärden styras av vårt dataunderlag. Därför sätter vi en signifikansnivå innan vi kontrollerar datat. En vanlig nivå är att 5%, eller a=0,05. Om vi sätter vår signifikansnivå vid 0,05 så kan vi säga att vi har fått ett signifikant resultat när vi har ett p-värde lägre än det. Eftersom vårat resultat var 1,25%, eller 0,0125 så ser vi att 0,0125 < 0,05, och vi har därmed ett statistiskt signifikant resultat. Även om vi nu har ett statistiskt signifikant resultat så är det värt att reflektera över om det är av något praktiskt värde. Vi hade 1 ml lägre produktion än väntat. För Frans, slajmfarmaren, så innebar det att han gick miste om cirka 1liter slajm per dag. Men än värre, så indikreade det för honom att hans slajmklumpar inte hade det så roligt som han hade hoppats. För Frans så hade det därför också en praktisk innebörd.

Och nu går vi mot fredag, denna Lucia. Det får bli fika och glögg. Och till kvällen blir det Harry Potter. Denna gång den sjätte filmen, Halvblodsprinsen. Det är filmer som jag tycker håller för att se om igen, ungefär vartannat år. Nästa år får det bli Sagan om ringen istället.

Trevlig helg, allihopa!


Ska jag bry mig om 1 ml hit eller dit?

Äntligen är det dags: hypoteser! Som jag förklarade i måndags så skulle jag återkomma till ämnet idag, om jag så fann tid till det. Och det gjorde jag!

I förra veckan skrev jag om konfidensintervall. Då beskrev jag hur stor andel av populationen (eller sannolikhet kan vi säga) som hade ett visst värde inom ett intervall. Ämnet med hypoteser är besläktat med det. Låt mig förklara.

Det fanns en gång en slajm-tillverkare, farmaren Frans. Slajmen skördade han från sina slajmklumpars saliv. Ju roligare de har desto mer slajm! Målet var att varje slamklump skulle producera 100 ml saliv per dag, men farmaren hade svårt att räkna alla klumpars produktion. Frans tog hjälp av sin granne, den sifferkunnige Samantha. Sam visste att produktionen per klump i snitt avvek med cirka 1 ml, men hon visste inte om produktonen i överlag faktiskt var 100 ml per klump. Sam och Frans valde slumpvist ut 20 klumpar en dag och såg att de producerade 99 ml per klump. De upptäckte då att dessa klumpar producerade 1 ml mindre slajm per dag än de 100 ml som Frans hoppades på. Men det kanske bara var slumpen som spelade in. Kan Frans ignorera att hans slumpvist valda klumpar producerade mindre än han hoppades? Sam tog fram en penna och papper och skrev upp följande:

Sam förklarade att även om det bara handlade om 1 ml, så vart det sannolikt så att alla klumpars produktion var lägre än önskat. Det var nämligen 1,25% chans att produktionen inte var lägre än 100 ml.

Frans tackade Sam så mycket, för nu visste han att han behövde göra dagarna roligare och dräggligare för slajmplumparna. Dagen därpå började Frans bygga vattenrutschkanor och fontäner. Slajmet som producerades veckan därpå översteg 100 ml per klump.

Historien om Frans och Sam handlade om hypoteser. Frans uttryckte att han skulle ha 100 ml saliv per klump (eller mer). Vi kan kalla detta för nollhypotesen. Den alternativa hypotesen är att produktionen är mindre än det. Detta kallas för en ensidig hypotes. Alternativet är en tvåsidig hypotes och det är när den alternativa hypotesen kan anta värden som är såväl mindre som större än nollhypotesen.

Genom att visa att nollhypotesen inte var sann (med 1,25% sannolikhet för att påståendet inte är korrekt), så fastställde Sam att produktionen var för låg mot vad Frans önskade.

Detta var min första stapplande förklaring om hypoteser, nästa gång nämner jag något om signifikansnivå och annat kul. Vi ses då!


En rent hypotetisk vecka

Om det nu skulle vara så att jag har tid över till att skriva om statistik, alltså rent hypotetiskt, så skulle jag skriva om hypoteser. Denna vecka blir det alltså en del om hypotesprövning om medelvärde. Vad är grejen med det? Och det här med nollhypotes, varför då? Är det inte bara bättre att gå rätt på min första hypotes och säga att den är sann? Mer om detta senare i veckan när jag hunnit läsa lite grann.

Jag har gått ur en helg nu där det inte blivit något plugg och heller inte något programmerande. Det har varit hushållsgöra på tapeten, och spel med lillasyster. Vi påbörjade PS4-spelet Bloodborne och blev sålda på hela den idén. Vi turades om att försöka ta oss så långt vi kunde tills vi blev dödade. Vi skapade en ung mjölksopp till äventyrare vid namn ”Hern”. Vid ett tillfälle så hamnade Hern i en gränd tillsammans med vad vi först skulle beskriva som en bjässe. Vi dog vid två slag och kom att undvika den bjässen. Tillslut tänkte vi att vi kanske kunde ge oss på den ändå. Vi hade blivit rätt duktiga trots alla gånger vi dött. Det tog en del timing och sidoskutt för att klara det, men klara det gjorde vi. Bjässen föll till marken. Det var vår första vinst! Så här i efterhand har vi förstått att det där bara var en vanlig motståndare och inte alls någon boss, så som vi hade tänkt oss att bjässen var. Vi får se hur det går när vi tillslut möter någon boss.

Till nästa gång blir det lite hypoteser: Om det finns tid så har Anders skrivit ett inlägg om hypoteser. En konkurrerande hypotes till det är: Om det inte finns tid så har Anders inte skrivit något om hypoteser på onsdag.

Vi ses!


Vi uppskattar avvikelser

I onsdags beskrev jag konfidensintervall. Det vill säga att vi hittar ett intervall där vi har uppnått en viss konfidens, alltså att vi har en metod som med angiven sannolikhet har det riktiga medelvärdet. I onsdags visste vi den riktiga standardavvikelsen, men vad gör vi när vi inte vet det?

Vi anväder t* istället för z. I princip så kommer vi få en normalfördelning när vi tar tillräckligt många stickprov. Men vi kommer få något större spridning, vilket vi kan förstå eftersom vi introducerar mer osäkerhet.

Detta blev jättekort! Men jag skriver detta när vädret äntligen blivit fint, så jag måste ut.

Vi ses igen!

Trevlig helg, allihopa!


Lita på metoden

Du ska kunna lita på metoden, men var lite vaksam på utfallet. Så skulle jag kortfattat vilja beskriva vad konfidensintervall handlar om. Idag är det detta som ligger på bordet.

I måndags skrev jag om centrala gränsvärdessatsen. Den handlade om att fördelningen av medelvärden närmade sig en normalfördelning när man tog tillräckligt stort urval. Det handlar alltså inte specifikt om enskilda värden, utan medelvärdet. I en population med en höger-skev fördelning skulle medelvärdet kunna vara 10. Om vi tar tillräckligt stort urval ur populationen och kontrollerar medelvärdena i den skulle de fördela sig runt 10 på sådant sätt att det är att betrakta som en normalfördelning.

Sedan tidigare kommer vi ihåg sannolikhetsfördelningen runt medelvärdet i en normalkurva som arean under kurvan baserat på standardavvikelse. Det var den kända 68-95-90.7%-regeln som jag skrev om förra gången. Om jag vill säga något om medelvärdet i populationen baserat på mitt urval (det som även kallas statistisk inferens) så säger regeln att jag kan ta medelvärdet och subtrahera och addera standardavvikelse (vilket ger en felmarginal) för att få fram ett intervall. Intervallet ger då en viss felmarginal – som blir större ju större del av befolkningen jag vill täcka. En vanlig andel att vilja täcka är 95%. Detta motsvarar 2 standardavvikelser. Om vi bygger vidare på exemplet ovan så säger vi att vi har en standardavvikelse på 1,5. Vi tar detta värde och multiplicerar med 2 standardavvikelser; detta ger oss en felmarginal på +/-3. Då har vi ett lägre värde på 7 och ett högre värde på 13. Detta är ett intervall som täcker 95% av populationen.

Vi kan nu säga att vi med en konfidensnivå på 95% har ett medelvärde inom 7-13, baserat på vårat urval. Det innebär inte att utfallet med 95% sannolikhet är korrekt; det betyder att metoden i 95% av fallen ger ett medelvärde som faller inom intervallet.

Det om konfidensintervall. På fredag ska jag berätta om vad som händer när vi inte vet standardavvikelsen i populationen utan måste uppskatta den. Det blir ju kul!

Och så vill jag bara säga något om programmering. Igår kväll satt jag och programmerade lite på Bokarenan. Jag höll på att skriva funktioner som motsvarade URI-vägar (typ URL) men det var hela tiden fel funktion som fångade en URI. Jag angav /utforska/bok/ny och en funktion för att skapa en ny bok skulle fånga detta, men istället så var det en funktion för att presentera en enskild bok som fångade anropet. Den funktionen hade till uppgift att fånga /utforska/bok/{id}. Men jag förstod först inte att det var detta som var problemet för det som jag fick till felmeddelande var att applikationen inte kunde hitta något bokobjekt. Jag googlade efter problemet och hittade på stackoverflow att problemet kunde ha att göra med i vilken ordning som funktionerna låg i. Liksom när man har en switch-struktur som avslutar med en generisk defaultcase så ska man tänka på att ha de mer generiska URI:erna längre ned i strukturen. Så jag fixade problemet genom att helt enkelt flytta ena funktionen över den andra!

Vi ses på fredag!


Centrala gränsvärdessatsen

Äntligen en ny vecka! Jag har kommit ut på andra sidan av denna helg där jag mest suttit och slipat på Bokarenan. Jag kände att jag hade den tiden över efter att ha gjort en del plugg under den gångna veckan. Mycket tid har gått åt att slipa på CSS och skapa rimliga views (sidor) för de entiteter jag vill presentera. Jag har upplevt det som enklare att ha koll på vad jag skapar och var jag har det, nu när jag skapar mina views manuellt, istället för att låta Symfony skapa dem åt mig. De views som Symfony skapade var i klass med att sitta med phpMyAdmin, men mer begränsad. Så de färdigbakade sidorna motsvarade inte de syften jag hade med dem. Och jag börjar gilla vart åt det barkar.

För närvarande ser sidan ut som nedan. Jag har avvikit lite från hur jag hade skissat den i Adobe XD och gjort den generellt lite ljusare.

Men nog om programmeringen. Denna vecka fortsätter jag med statistik. Denna gång om centrala gränsvärdessatsen.

I förra veckan beskrev jag normalfördelning och hur bra det var att ha en sådan modell. Kortfattat så innebär det att man enkelt kan uppskatta fördelning av befolkning utifrån hur långt från medelvärdet man kollar baserat på standardavvikelse. Denna vecka säger jag att man kommer få en normalfördelning om man tar tillräckligt stora samplar (urval), i princip oavsett hur den verkliga populationen ser ut. Och det är inte helt negativt! Det man vill göra med att ta stora samplar är att komma så nära det verkliga medelvärdet som möjligt med så liten standardavvikelse som möjligt. Om man lyckas med det så har man fått ett urval som har ett medelvärde som ligger där det riktiga medelvärdet ligger, med liten felmarginal.

I sitt urval kommer man ha en standardavvikelse. Och om man vill säga något om 95% av populationen så fångas de inom 2 standardavvikelser från medelvärdet. Detta har jag skrivit om i förra veckan som 68-95-99.7% regeln. Så om standardavvikelsen är stor så kommer det intervall som beskriver 95% av populationen att vara stor. Förhållandet mellan populationens standardavvikelse och urvalets standardavvikelse är s = σ/(√n), där n är urvalsstorlek. Det innebär att man minskar standardavvikelsen med roten ur sampelstorlekens förändring. Vill man halvera standardavvikelsen så får man fyrdubbla urvalsstorleken.

Nästa gång ska jag skriva något om konfidensintervall. Jag misstänker att vi redan har börjat fila på det, men jag får återkomma när jag läst lite om saken.


Standardiserad fredag

Idag ska jag låta avsluta den ”normala veckan” med standardiserade värden. Vad är ett standardiserat värde? Vad är egentligen poängen med att standardisera värden? Hur standardiserar man värden? Detta kommer jag gå igenom idag.

Ett standardiserat värde är egentligen ett mått på hur långt ifrån ett medelvärde en datapunkt är. Som mått används standardavvikelsen. Det standardiserade värdet representeras av z. Och som jag skrev om förra gången så representeras standardavvikelsen av σ [lilla sigma]. I bilden nedan så har jag ritat in σ och ett standardiserat värde med 1,25.

Vad är då poängen med standardiserade värden? Vad jag vet i skrivande stund så finns det två poänger.

För det första så kan man jämföra olika standardiserade mått med varandra. Som jag har fått förklarat för mig så har man i USA två stora antagningsprov till högre studier: ACT och SAT. De har olika skalor men kan vara angelägna att jämföra mellan. Säg att Emily har fått 650 på SAT-provet, och Michael har fått 28 på ACT. Vem av dem har större anspråk på att komma in på samma kurs om man kan anta att ACT och SAT är likvärdiga test på kunskapsnivå. Genom att standardisera värdena så får jag fram att Emilys z-värde är 1 och Michael är 1,67. Michael har alltså högre poäng om man skulle jämföra dem. Vad det innebär är att en mindre andel av alla som skriver proven har fått så höga poäng som Michael jämfört med Emily. Men det innebär inte att Emily har dåliga poäng. Faktum är att hon har bättre poäng än 84% av alla som tar samma prov. Och då kommer vi till den andra poängen.

För det andra så kan man med hjälp av standardiserade värden av en normalfördelning få fram andelar av en population.

Det är svårt att använda ögonmått för att uppskatta andel av befolkningen som har lägre poäng än Emily. Men med hjälp av z-värde och en tabell över standardiserad normal sannolikhet så kan man få fram andelen. Om man skulle kontrollera hur stor andel av befolkningen som fått poäng som varit mindre än det standardiserade värdet av 0, så kan man se att det delar befolkningen i hälften.

Det om standardiserade värden!

Jag vill också nämna något om Bokarenan. Projektet har löpt på när jag inte orkat läsa kursboken och tid funnits över. Jag har inte gillat hur svårt det varit för mig att navigera mellan relevanta Controllers och views. Jag har heller inte gillat att jag låtit skapa så många views för varje liten entitet. Det kan finnas poänger för det när man vill underhålla vilka entiteter man har. Men jag tycker att det mest har tagit upp massa plats och inte haft någon rimlig logik till sig. Jag har därför tänkt ta bort dem som inte används, och när jag upptäcker att jag behöver dem så skapar jag dem efter mina behov.

Ytterligare så har jag förfinat layouten, men det har jag skrivit lite om tidigare. Men alla dessa åtgärder har inneburit att ganska mycket kod har flyttats runt. Jag tog en liten bild av hur många förändringar det inneburit i Git:

Och till sist vill jag avsluta med lite fredagskänsla: spel! Den gångna veckan har min dotter upptäckt glädjen med att skjuta upp raketer i Kerbal Space Program, och så har också jag. Jag kommer sitta och bygga små dynamitstycken och hoppas att mina små gröna gubbar kan landa säkert någonstans. Jag har lyckats få mina explosioner att smälla i ungefär rätt riktningar, men ännu så har jag inte lyckats flyga ett varv runt planeten. Vi får se vem som först lyckas; jag eller dottern.

Trevlig helg, allihopa!