Kategori Projektuppdatering

Fler projekt för lärande

Som jag inledde denna vecka så har jag fullt upp med att göra web-design projekt på freeCodeCamp. I måndags gjorde jag klart min Tribute-sida till Horizon Zero Dawn. När jag gjorde den så såg jag det som en övning i att jobba med grid-areas och animationer.

Bild

Igår gjorde jag klart det andra projektet som var ett undersökningsformulär. Utmaningen med det tyckte jag var att få till en fungerande och okej design. Den går att hitta på femtearenan.se/survey.

Bild

Jag jobbade en del med att få till cirklarna för att bryta upp enformigheten av formuläret. Jag använde mig av position:absolute på dem. Utmaningen var att få cirklarna att stanna kvar på samma ställen när man ändrar storleken på fönstret. Jag fick till det. Jag har däremot upptäckt att den teknik jag har tillämpat har dock visat sig fungerar mindre bra på mobiler. Och detta för mig över till det tredje projektet som jag jobbar med idag.

Idag har jag jobbat med designen på en produktsida för valfri produkt. Jag kommer under kvällen jobba med att implementera designen med HTML och CSS. Med erfarenheten från förra projektet så har jag valt att först få till sidan så att den ska fungera på mobiler (mobile first).

Nu får vi se hur det går att implementera det hela! Det och ett par andra projekt skriver jag om på fredag. Vi ses då!


Uppdaterade nyheter

Hej kära vänner och läsare! Det är fredag och helg. Många av oss sätter oss i soffan ikväll med chips och tittar på något underhållande. De senaste veckorna har jag och min sambo kunnat njuta av den dumma (men roliga!) tv-serien Medical Police på Netflix. Tyvärr var det bara 10 avsnitt så nu får vi ägna oss åt något annat. Men eftersom det är fredag så skriver jag veckans sista inlägg så här på eftermiddagen. Den här veckan har fokus varit på programmering och att lägga till en blogg-funktion till Bokarenan. I onsdags skrev jag om hur Symfony och Doctrine har underlättat skapandet av en ny entitet (BlogPost) och uppdateringen av databasen. Denna gång ska jag skriva om den avslutande delen: hur allt ska kunna presenteras till användaren.

Det finns två komponenter att beakta när det kommer till hur nyheterna presenteras till användarna: template och Controller. Jag tänkte börja med Controller.

Min tanke är att den som är administratör ska kunna skriva ett blogginlägg (nyhet). Jag löste detta genom att använda AdminController och lägga till två funktioner till denna Controller som jag alltså har haft sedan tidigare. Den första funktionen innebär att administratören kan lägga till ett nytt inlägg. Något som jag vill lyfta fram som några detaljer är att administratören kan välja publiceringsdatum. Det innebär att inläggen inte dyker upp under Nyheter om inte publiceringsdatumet har nåtts. Den andra detaljen jag vill lyfta fram är ”slugs”. Det innebär att varje inlägg har en unik länk i stil med 2020-01-31-Det_här_är_en_nyhet. Detta kommer till användning när man vill titta på endast en nyhet, eller för sökmotorers möjligheter att länka direkt till ett inlägg.

Den andra Controllern som behövde uppdateras var NewsController. Denna kontroller har tilluppgift att presentera nyheter till användare. I kontrollern så skapade jag en ny funktion som hämtar de senaste inläggen och skickar dem till template-engine. Det tillkommer lite fler detaljer som innebär att jag kan paginera allt ihop och bara hämta de inlägg som ska vara på den aktuella sidan som användaren är på. Oftast är detta första sidan, men länkar till övriga sidor dyker upp längst ned.

Vad är då template-engine? Det är i princip en funktion som renderar html (eller php-filer med html-element) med dynamiskt innehåll. Som template-engine använder jag Twig. Från NewsController skickar jag de aktuella inläggen till Twig som löser det hela med att placera innehåll på rätt ställen och presenterar det med html-element och innehåll till användaren.

I NewsController så kan det se ut så här:

    /**
     * @Route("/{page}", name="nyheter_index", methods={"GET"})
     */
    public function index(BlogPostRepository $blogRepository, $page=1): Response
    {
        if (!\is_numeric($page)) {
            $page=1;
        }

        
        $count = $blogRepository->getCount();
        $limit = 1;
        $pages = $count/$limit;
        $pages = \ceil($pages);
        if ($page > $pages) {
            $page = $pages;
        }
        $posts = $blogRepository->getLatest($page, $limit);
        return $this->render("nyheter/index.html.twig", [
            "count" => $count,
            "page" => $page,
            "pages" => $pages,
            "posts" => $posts
        ]);
    }

Man kan se att det finns en template fil under filmappen nyheter som heter index.html.twig. Den filen ser ut så här:

{% extends "content.html.twig" %}
{% block navNyheter %}active{% endblock %}
{% block content %}
    {% for post in posts %}
        <article>
            <div class="article-header">
                <h1><a href="{{ path("nyheter_view", {'slug': post.slug}) }}">{{ post.title }}</a></h1>
            </div>
            <div class="article-content">
                <p class="time">{{ post.publish|date("d/m/Y") }} av {{ post.user }}</p>
                <p>{{ post.text|striptags('<em><strong><i><mark><cite><dfn>')|raw|nl2br }}</p>
                {% if app.user == post.user %}
                    <p><a href=""></a></p>
                {% endif %}
                
            </div>
        </article>
    {% endfor %}
    <div class="flex-center">
        {% for i in 1.. pages %}
            {% if i == page %}
                <a class="page-number active" href="/nyheter/{{i}}">{{ i }}</a>
            {% else %}
                <a class="page-number" href="/nyheter/{{i}}">{{ i }}</a>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

Som man kan se i ovanstående kod så kan jag komma åt variabeln $posts genom instruktionen {{ post }}. Och när jag använder det på rätt sätt så kan jag få ett resultat som liknar det nedan.

Så det var allt för denna gången. Jag har skrivit ett blogginlägg om att göra en bloggfunktion för att göra blogginlägg. Blogg. Nu har jag skrivit det så mycket att jag börjar läsa det hela som grogg. Och apropå det: spel! Jag har visserligen en viss varm känsla för Secret of Monkey Island, men något som jag ser fram emot nu är att börja spela Skyrim igen. Senast jag gjorde det var 2013. Nu har jag den uppdaterade versionen på PS4. Jag får se om det fortfarande kan hålla mig underhållen. Men det är lugnt. Jag har några partyspel som nog funkar gott ändå!

Trevlig helg, allihopa!


Att göra en nyhetsblogg

Denna onsdag skriver jag om Bokarenan och möjligheten att bygga på den med fler funktioner. Det som står på dagordningen denna gång är en nyhetsblogg. För att få till detta så är det tre saker som ska komma på plats:

  • Ny entitet
  • Uppdaterad databas
  • Uppdaterad presentation/view

Det enklaste är att skapa en ny entitet med hjälp av MakerBundle i Symfony. Det innebär att jag via ett CLI (kommandotolken) kan instruera Symfony att göra den nya entiteten åt mig. På vägen får jag hjälp av Symfony för vad jag ska göra härnäst. För att starta det hela så utgår jag från projektets root-mapp och kör följande kommando:
php .\bin\console make:entity

Detta ger följande interaktion:

Jag döper min nya entitet till BlogPost, och ger den följande fält:
– title [string]
– text [text]
– entered [datetime]
– modified [datetime]
– publish [datetime]
– user [ManyToOne]

Exempel på hur fältet user i BlogPost relaterar till en annan entitet. User är det objekt som alltså refereras av BlogPost. ManyToOne innebär att respektive BlogPost bara kan referera till en användare, men en användare kan skapa flera BlogPost.

Genom hela denna process så har Symfony skapat och uppdaterat klassen BlogPost. Om vi tar en översikt över kursen så har den följande metoder och fält:

Då var steg ett avklarat. Nästa steg är att uppdatera databasen. Återigen är Symfony behjälplig… eller rättare sagt så är det faktiskt Doctrine. I CLI:t så kör jag följande kommandon:
php .\bin\console make:migration
Detta är en instruktion från Symfony till Doctrine hur databasen ska uppdateras efter att en till entitet har lagts till. Då återstår att låta Doctrine uppdatera databasen:
php .\bin\console doctrine:migrations:migrate
Databasen är nu uppdaterad och har rätta relationerna mellan BloggPost-tabellen och User-tabellen.

Då var två av tre steg avklarade. Det som återstår nu är att uppdatera presentationen för denna nya entitet. Detta steg består faktiskt av flera detaljer. Det innebär att en kontroller (eller två) ska uppdateras, en template för att skapa bloggposter ska skapas, en template för att presentera bloggposter ska uppdateras. Detta steg återkommer jag till på fredag. Vi ses då!


Statistik ”avklarad” och frågan om Oauth2

Det var onsdag den 30 oktober 2019 när jag började skriva något om statistik på den här bloggen. Det har blivit 20 inlägg i den kategorin och nu är jag klar med den kurs jag gått under senhösten/vintern. Jag har behandlat ämnen så som sannolikhet, standardavvikelser, standardiserade värden, normalfördelning, hypoteser, centrala gränsvärdessatsen, konfidensintervall, proportioner, chi2 och linjär regression. Jag har gått från deskriptiv statistik till prediktiv analys med en förklaringsvariabel. Emellanåt har det varit utmanande att finna tid till att skriva om statistiken och plugga, samtidigt som jag tagit hand om bebisar, tränat och programmerat. Men jag tycker att jag lärt mig mycket om statistik och jag har nu några idéer om hur jag skulle kunna tillämpa några av de kunskaper jag fått. Så här är några idéer:

  • Undersök korrelation mellan löptid och förlorad vätska. Min hypotes är att det finns ett positivt förhållande mellan hur länge jag springer och hur mycket vätska jag blir av med.
  • Undersök om jag har preferens för en särskild kategori böcker jämfört med andra. Jag behöver dock ett större läsunderlag klart innan jag kan påbörja detta. Jag tror att chi2-analys kan vara på sin plats då.
  • Sammanställ en beskrivning hur länge det tar att lägga upp en ny recension på Bokarenan innan en användare lägger upp en ny. Hur ser sambandet mellan detta och längden på den bok som recenseras.

Så även om jag är klar med statistikkursen så är jag inte klar med statistiken. Vi får se var det smyger sig in framöver. Men nu kommer jag flytta fokus tillbaka till programmering ett tag.

Förra måndagen skrev jag att jag skulle kolla på möjligheten att logga in med oauth (eller rättare sagt oauth2) till Bokarenan. Då skrev jag att jag eventuellt skulle titta på inloggning med Google-konto. Nu har jag kollat möjligheter och provat implementeringar och kan rapportera tillbaka.

Jag kom att prova med Facebook istället för Google och provade följande behjälpliga paket: knpuniversity/oauth2-client-bundle tillsammans med league/oauth2-facebook. Det jag fick göra var att skapa en controller för Facebook-inloggning och registrering samt en autentiserare för det också. Jag upplevde instruktionerna från knpuniversity/oauth2-client-bundle var enkla att följa och redigera för egna behov. Det krävdes att jag fick lägga till ytterligare autentiserare i min konfigurering (security.yaml) och att jag skrev vilken av dem som i första hand skulle användas:

        guard:
            authenticators:
                - App\Security\FacebookAuthenticator
                - App\Security\LoginFormAuthenticator
            entry_point: App\Security\LoginFormAuthenticator

Jag fick en till konfigureringsfil (knpu_oauth2_client.yaml) med instruktioner för autentisering:

knpu_oauth2_client:
    clients:
       
        facebook_main:

            type: facebook
            client_id: '%env(OAUTH_FACEBOOK_ID)%'
            client_secret: '%env(OAUTH_FACEBOOK_SECRET)%'

            redirect_route: connect_facebook_check
            redirect_params: {}
            graph_api_version: v2.12

Det denna konfigureringsfil innehåller är alltså vilken ”användare” och vilket ”lösenord” som ska användas gentemot Facebook för att få en ingång till oauth2 (så användare kan logga in med sina Facebook-användare). Informationen för det sparas i .env-filen. Sedan finns information om vilken funktion i controllern som kommer fånga upp inloggningen.

Det som jag tyckte var det svåraste var om en Facebook-användare behövde registreras som ny användare. Det jag gjorde då var att logga in användaren och sedan dirigera denna till avregistrering om denne inte vill gå med på användarvillkoren. Jag fick ta och registrera i sessionen (via autentiseraren) att användaren var ny och sedan kontrollera detta:

if ($this->session->get('fb-new')) {
    $targetUrl = $this->router->generate('connect_facebook_register');
    return new RedirectResponse($targetUrl);
}

Jag gillade slutresultatet. Det var jätteenkelt att logga in! Men jag har beslutat att för närvarande inte inkludera funktionen i produktion. Anledningen: jag är inte ett företag. Med det vill jag säga att det finns juridiska åtaganden att ta hänsyn till när det kommer till oauth2 och jag vill inte ta ansvar för Facebooks data om användare på min hobby-sida. Det kan vara så att jag överreagerar vad gäller detta och om så vore fallet så återinför jag funktionen.

Det som jag ska göra härnäst på Bokarenan är att införa en nyhetsblogg. Vi får se hur det går. Vi ses på onsdag!


Uppehåll över, nytt år är igång

Det har nu gått en hel månad sedan jag senast skrev ett inlägg. Då var datumet 20:e december 2019. Det är nu den 20:e januari 2020. I stort sett har jag under hösten skrivit tre inlägg i veckan och jag planerar att fortsätta så den närmaste tiden. Det uppehåll som jag hade var välbehövt. När det kommer till familj så är det något som kommer först. Över nyår och de första veckorna därefter så ägnade jag mycket tid till att hälsa på familj och släkt tillsammans med bebisar som fortsätter att utveckla sig. Till detta har kommit att slutföra den kurs jag har ägnat övrig tid åt: grundläggande statistik. Men ni läsare som har följt mina inlägg ett tag nu vet att jag antagligen lyckats hitta tid över till programmering trots allt detta. Ni har rätt!

Den gångna månaden har jag ägnat strötiden åt att göra en lättare data scaper. Den har till uppdrag att hitta bokinformation så att användare inte ska behöva fylla i femtioelva fält på egen hand. Istället ska användare kunna ägna sig åt att skriva om sin senaste läsning. Jag laddade upp denna funktion vid lunch idag. Så om du vill se om det funkar så kan du bli medlem idag på bokarenan.se/registrera.

Nästa steg i Bokarenan är några mindre justeringar i layouten och jag ska kolla på möjligheten att införa OAuth; eller möjligheten att logga in med ditt Google-konto. Uppdateringar om det kommer längre fram.

Denna vecka på Femte Arenan så kommer jag fortsätta i statistikens tecken. På onsdag kommer jag beskriva hur man kan analysera om det finns statistiskt signifikanta skillnader mellan röda slajmar och gröna slajmar vad avser deras preferens för att äta maskrosor. På fredag kommer jag försöka förutse hur mycket slajm en slajmklump kan producera baserat på hur mycket maskrosor den har ätit under dagen. Vi kommer alltså beröra chi2-analys och linjär regressionsanalys denna vecka. Det är ju toppen, och superintressant för en slajmproducent! Vi ses på onsdag!


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.


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å!


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!