Automatisera slumpmässiga stickprov.

Permalänk
Medlem

Automatisera slumpmässiga stickprov.

Hej!

Jag skulle vilja få förslag på hur jag kan förenkla mitt jobb!

Jag har idag ett ark i Excel på 10.000+ rader och 4 kolumner:

A: Provider
B: Brand
C: Product
D: URL

Mitt jobb är att varje dag slumpmässigt gå igenom varje Provider och klicka på URL för en slumpmässigt vald Product för respektive Brand.

Det vore kanon om jag i ett Excelmakro (eller om man ska importera excelfilen in i en databas och köra PHP?) så att det kan reducera mina 10.000 rader till:

7 Providers * 40 Brands = 280 rader där bara en klickbar URL visas.

Det är viktigt att det blir någorlunda slumpmässigt urval varje gång.

Någon som ser direkt vilken lösning jag ska fixa detta med?

Permalänk
Medlem

Hur får du till slumpmässigheten idag? Vad är det som ska undersökas via URLen? Att den fungerar?

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Borde vara skapligt enkelt!
1: sluta använda Excel-ark (använd istället CSV eller liknande)
2: välj ett språk som är enkelt att scripta i (t ex Powershell eller Python)
3: Skriv en enkel randomizer som plockar ur index baserat på hur många som finns
4: gör det du vill göra med URL:en osv

Du kan säkert skriva det i VBA också och dumpa in i Excel för att köras på det dokumentet som du får till dig.

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem
Skrivet av GreyWilk:

Borde vara skapligt enkelt!
1: sluta använda Excel-ark (använd istället CSV eller liknande)

Enkelt är det knappast för någon som frågar om hur man gör.

Om det är en bra ide eller inte att byta lagringsformat beror på hur datan underhålls. Om det enkelt går att få datan i ett bättre format så är ju nästan vad som helst bättre än Excel. Men om datan underhålls manuellt i Excel så kommer användaren som underhåller förr eller senare ställa till med kvalitetsproblem och då är antagligen Excel det enklaste sättet att rätta till problemet också.

Alla .NET-språken har möjlighet att läsa Excel utan större problem, numera även på datorer där Office inte är installerat. Även Powershell tycks ha stöd, men det har jag aldrig prövat. VBA gör ju lösningen extremt beroende av datakällan.

När man väl automatiserat detta försvinner ju behovet av slumpmässighet, man kan helt enkelt köra igenom allt och få ut en fullständig rapport över vad som inte fungerar, till exempel som Excel-fil. Kollen som görs är antagligen inte svårare än att se att produkten existerar?

Permalänk
Medlem

@zencity

Skrivet av KAD:

Enkelt är det knappast för någon som frågar om hur man gör.

Jag ska omformulera mig.

Det är enkelt att göra såhär:

1: Spara om Excel-filen till CSV
2: kör följande powershellkod genom att starta t ex powershell_ise.exe

$csvdata = Import-Csv -Path C:\temp\scb_valresultat_historiskt.csv -Delimiter ';' $randomMax = $csvdata.count $getRandomIndex = Get-Random -Minimum 0 -Maximum $randomMax $csvdata[$getRandomIndex] $csvdata[$getRandomIndex].URL #för att få fram kolumnen som heter URL. Kanske heter något annat hos dig

EDIT: parametern "-delimiter" kanske inte ska använda semikolon som avgränsare utan det som finns i faktiskta csv-filen. Förmodat är det ett vanligt komma men kan vara semikolon...
(justera lite efter behov, t ex ändra sökvägen till DIN csv-fil - och just nu saknas all form av automatisk kontroll så att saker inte går snett )
3: Gör något med URL

Jag brukar försöka undvika att använda mig av filtyper som xlsx mfl för att de ofta kräver att man specifikt skapar automation som bygger på att man läser just den typen oftast. Istället kan man använda gamla solida format som csv men även xml och json.
Det är en hel grej bara det.

Skrivet av KAD:

Om det är en bra ide eller inte att byta lagringsformat beror på hur datan underhålls.

Jao. Sant i vissa fall. Jag bara utgår från att det inte är någon "master-excel-databas-där-även-lönerna-finns-på-någon-flik" och att det istället är en export från något system och man valt Excel för läsbarhet.
Det återstår att se dock.

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem

Tack för svaren! Ska kolla på powershell idag och se om jag kan få till något. Idag sker slumpmässigheten att jag bara scrollar random

Det jag ska kolla är att URL inte är bruten, om sidan laddas eller ej. Inte superspännande

Permalänk
Medlem

Tack för exemplet med powershellkoden.

Som jag förstår det spottar ditt exempel ut random URL´s utan att ta hänsyn till Provider/Brand.

Jag behöver få 1 random URL för varje Provider, Brand och en utvald Product (som har URL).

Exempelvis från en sådan här lista:

ICA, KELLOGS, CORNFLAKES, ica.com/cornflakes
ICA, KELLOGS, BRANFLAKES, ica.com/branflakes
ICA, KELLOGS, CORNFLAKES2, ica.com/cornflakes2
ICA, KELLOGS, BRANFLAKES2, ica.com/branflakes2
KONSUM, KELLOGS, CORNFLAKES, konsum.com/cornflakes
KONSUM, KELLOGS, BRANFLAKES, konsum.com/branflakes
KONSUM, KELLOGS, CORNFLAKES2, konsum.com/cornflakes2
KONSUM, KELLOGS, BRANFLAKES2, konsum.com/branflakes2

Av ovan vill jag få ut en slumpmässig url baserat på de två första kolumnerna och max visa ett resultat för denna kombination.

Slutresultatet av ovan lista ska visa enbart två URL´s efter körning.

Exempel:
ica.com/branflakes
konsum.com/cornflakes2

Så målet är att få ner mina 10.000 rader till 280 URL´s men det är nästlat och beroende på Provider/Brand och limiterat till max 1 utfall av denna kombo.

Hoppas jag förklarar mig OK, ber om ursäkt om det är lite snurrigt

EDIT: Jag provade powershellkoden och den funkar fint. Jag får ut en slumpmässig rad. Så detta är något att bygga vidare på!

Skrivet av GreyWilk:

@zencity
Jag ska omformulera mig.

Det är enkelt att göra såhär:

1: Spara om Excel-filen till CSV
2: kör följande powershellkod genom att starta t ex powershell_ise.exe

$csvdata = Import-Csv -Path C:\temp\scb_valresultat_historiskt.csv -Delimiter ';' $randomMax = $csvdata.count $getRandomIndex = Get-Random -Minimum 0 -Maximum $randomMax $csvdata[$getRandomIndex] $csvdata[$getRandomIndex].URL #för att få fram kolumnen som heter URL. Kanske heter något annat hos dig

EDIT: parametern "-delimiter" kanske inte ska använda semikolon som avgränsare utan det som finns i faktiskta csv-filen. Förmodat är det ett vanligt komma men kan vara semikolon...
(justera lite efter behov, t ex ändra sökvägen till DIN csv-fil - och just nu saknas all form av automatisk kontroll så att saker inte går snett )
3: Gör något med URL

Jag brukar försöka undvika att använda mig av filtyper som xlsx mfl för att de ofta kräver att man specifikt skapar automation som bygger på att man läser just den typen oftast. Istället kan man använda gamla solida format som csv men även xml och json.
Det är en hel grej bara det.

Jao. Sant i vissa fall. Jag bara utgår från att det inte är någon "master-excel-databas-där-även-lönerna-finns-på-någon-flik" och att det istället är en export från något system och man valt Excel för läsbarhet.
Det återstår att se dock.

Permalänk
Medlem
Skrivet av zencity:

Tack för exemplet med powershellkoden.

Som jag förstår det spottar ditt exempel ut random URL´s utan att ta hänsyn till Provider/Brand.

Jag behöver få 1 random URL för varje Provider, Brand och en utvald Product (som har URL).

Exempelvis från en sådan här lista:

ICA, KELLOGS, CORNFLAKES, ica.com/cornflakes
ICA, KELLOGS, BRANFLAKES, ica.com/branflakes
ICA, KELLOGS, CORNFLAKES2, ica.com/cornflakes2
ICA, KELLOGS, BRANFLAKES2, ica.com/branflakes2
KONSUM, KELLOGS, CORNFLAKES, konsum.com/cornflakes
KONSUM, KELLOGS, BRANFLAKES, konsum.com/branflakes
KONSUM, KELLOGS, CORNFLAKES2, konsum.com/cornflakes2
KONSUM, KELLOGS, BRANFLAKES2, konsum.com/branflakes2

Av ovan vill jag få ut en slumpmässig url baserat på de två första kolumnerna och max visa ett resultat för denna kombination.

Slutresultatet av ovan lista ska visa enbart två URL´s efter körning.

Exempel:
ica.com/branflakes
konsum.com/cornflakes2

Så målet är att få ner mina 10.000 rader till 280 URL´s men det är nästlat och beroende på Provider/Brand och limiterat till max 1 utfall av denna kombo.

Hoppas jag förklarar mig OK, ber om ursäkt om det är lite snurrigt

EDIT: Jag provade powershellkoden och den funkar fint. Jag får ut en slumpmässig rad. Så detta är något att bygga vidare på!

Inga problem!
se om detta fungerar för ditta ändamål

EDIT: Kom på att jag la headers på din CSV data: company, category, type, url
Så det måste stå högst upp i CSV:n.

$tempArray = @() $csvdata = Import-Csv -Path C:\temp\zencity_testdata.csv -Delimiter ',' $groupedCSVdata = $csvdata | Group-Object -Property company,category $groupedCSVdata | ForEach-Object { $randomMax = $PSItem.Group.Count $getRandomIndex = Get-Random -Minimum 0 -Maximum ($randomMax-1) $tempArray += -join( $PSItem.group.company[$getRandomIndex] + ',' + $PSItem.group.category[$getRandomIndex] + ',' + $PSItem.group.type[$getRandomIndex] + ',' + $PSItem.group.url[$getRandomIndex] ) } $tempArray

EDIT:
Du kan också lägga till att den testar sidan med hjälp av nedan kod
Dock kan detta nedan behöva justeras en del baserat på dina behov. Och vissa sidor kanske levererar en 200-kod även om sidan inte finns för att det är någon redirekt eller annat. Jag är inte bäst på webb-lösningar...

$tempArray | ForEach-Object { $wgetResult = Invoke-WebRequest -Uri $PSItem if( $wgetResult.StatusCode -eq 200 ) { Write-Host "$($PSItem.split(',')[-1]) responded with $($wgetResult.StatusCode)" -ForegroundColor Green } else { Write-Host "$($PSItem.split(',')[-1]) responded with $($wgetResult.StatusCode)" -ForegroundColor Red } }

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem
Skrivet av GreyWilk:

Inga problem!
se om detta fungerar för ditta ändamål

EDIT: Kom på att jag la headers på din CSV data: company, category, type, url
Så det måste stå högst upp i CSV:n.

$tempArray = @() $csvdata = Import-Csv -Path C:\temp\zencity_testdata.csv -Delimiter ',' $groupedCSVdata = $csvdata | Group-Object -Property company,category $groupedCSVdata | ForEach-Object { $randomMax = $PSItem.Group.Count $getRandomIndex = Get-Random -Minimum 0 -Maximum ($randomMax-1) $tempArray += -join( $PSItem.group.company[$getRandomIndex] + ',' + $PSItem.group.category[$getRandomIndex] + ',' + $PSItem.group.type[$getRandomIndex] + ',' + $PSItem.group.url[$getRandomIndex] ) } $tempArray

EDIT:
Du kan också lägga till att den testar sidan med hjälp av nedan kod
Dock kan detta nedan behöva justeras en del baserat på dina behov. Och vissa sidor kanske levererar en 200-kod även om sidan inte finns för att det är någon redirekt eller annat. Jag är inte bäst på webb-lösningar...

$tempArray | ForEach-Object { $wgetResult = Invoke-WebRequest -Uri $PSItem if( $wgetResult.StatusCode -eq 200 ) { Write-Host "$($PSItem.split(',')[-1]) responded with $($wgetResult.StatusCode)" -ForegroundColor Green } else { Write-Host "$($PSItem.split(',')[-1]) responded with $($wgetResult.StatusCode)" -ForegroundColor Red } }

Jäklar så snyggt!!! Funkade fint att få ut en random lista.

Angående tillägget för att testa url så får jag dock detta på alla rader:

https://www.domainname.com/en/test/test/test/test responded with
Invoke-WebRequest : Ogiltig URI. Den gick inte att parsa värdnamnet.
At line:18 char:19
+ $wgetResult = Invoke-WebRequest -Uri $PSItem
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], UriFormatException
+ FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Något du känner till lösning på? Oavsett är jag mer än nöjd med att få ut listan så jag manuellt kan kopiera in i excel och klicka på länkarna!

Permalänk
Medlem

Går det att med något echo (vet egentligen inte vad jag pratar om) spotta ut resultatet i en ny CSV?

Permalänk
Medlem
Skrivet av zencity:

Går det att med något echo (vet egentligen inte vad jag pratar om) spotta ut resultatet i en ny CSV?

Sista raden är $tempArray
Skriv $tempArray > minfil.csv
Så blir det en fil istället för att det går till konsolen.

Hade varit snyggt om du snabbt kunde öppna 10st som flikar i webbläsaren med ett klick för att stänga en och en. Så slipper man vänta på sidladdningen. En snabbare dator kan öppna ännu fler samtidigt

Permalänk
Medlem
Skrivet av zencity:

Jäklar så snyggt!!! Funkade fint att få ut en random lista.

Nice! Inga problem!

Skrivet av zencity:

Angående tillägget för att testa url så får jag dock detta på alla rader

Skrivet av zencity:

Går det att med något echo (vet egentligen inte vad jag pratar om) spotta ut resultatet i en ny CSV?

Japp. En liten miss i koden. Lätt hänt ^^
Klistrar in _hela_ koden som den ska vara... hoppas jag xD
Nya koden skriver ut i console och i loggfil. Justera sökvägar efter behov

$tempArray = @() $csvdata = Import-Csv -Path C:\temp\zencity_testdata.csv -Delimiter ',' $groupedCSVdata = $csvdata | Group-Object -Property company,category $groupedCSVdata | ForEach-Object { $randomMax = $PSItem.Group.Count $getRandomIndex = Get-Random -Minimum 0 -Maximum ($randomMax-1) $tempArray += -join( $PSItem.group.company[$getRandomIndex] + ',' + $PSItem.group.category[$getRandomIndex] + ',' + $PSItem.group.type[$getRandomIndex] + ',' + $PSItem.group.url[$getRandomIndex] ) } $logFilePath = "c:\temp" $logFileOKName = "$(Get-Date -Format 'yyyyMMdd-HHmmss')_LogOK.txt" $logFileOK = "$logFilePath\$logFileOKName" $logFileNOTOKName = "$(Get-Date -Format 'yyyyMMdd-HHmmss')_LogNOTOK.txt" $logFileNOTOK = "$logFilePath\$logFileNOTOKName" if( -not $($logFileOK | Test-Path) ) { New-Item -Path $logFilePath -Name $logFileOKName -ItemType File } if( -not $($logFileNOTOK | Test-Path) ) { New-Item -Path $logFilePath -Name $logFileNOTOKName -ItemType File } $tempArray | ForEach-Object { try{ $currentURL = $($PSItem.split(',')[-1]) $wgetResult = $null $wgetResult = Invoke-WebRequest -Uri $currentURL -ErrorAction Stop if( $wgetResult.StatusCode -eq 200 ) { Write-Host "$currentURL responded with $($wgetResult.StatusCode)" -ForegroundColor Green Add-Content -Path $logFileOK -Value "[PROC] $currentURL responded with $($wgetResult.StatusCode)" } else { Write-Host "$currentURL responded with $($wgetResult.StatusCode)" -ForegroundColor Red Add-Content -Path $logFileNOTOK -Value -Value "[WRNG] $$currentURL responded with $($wgetResult.StatusCode)" } } catch { Write-Host "$currentURL responded with no status code." -ForegroundColor Red Add-Content -Path $logFileNOTOK -Value "[ERR] $currentURL responded with no status code." } }

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem
Skrivet av jocke92:

Hade varit snyggt om du snabbt kunde öppna 10st som flikar i webbläsaren med ett klick för att stänga en och en. Så slipper man vänta på sidladdningen. En snabbare dator kan öppna ännu fler samtidigt

Kan köra

Start-Process www.google.com

Efter det kan man köra att var X sekund så stängs processen. Dock är det lite mer kod än vad jag orkar skriva just nu

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem
Skrivet av GreyWilk:

Nice! Inga problem!
Japp. En liten miss i koden. Lätt hänt ^^
Klistrar in _hela_ koden som den ska vara... hoppas jag xD
Nya koden skriver ut i console och i loggfil. Justera sökvägar efter behov

$tempArray = @() $csvdata = Import-Csv -Path C:\temp\zencity_testdata.csv -Delimiter ',' $groupedCSVdata = $csvdata | Group-Object -Property company,category $groupedCSVdata | ForEach-Object { $randomMax = $PSItem.Group.Count $getRandomIndex = Get-Random -Minimum 0 -Maximum ($randomMax-1) $tempArray += -join( $PSItem.group.company[$getRandomIndex] + ',' + $PSItem.group.category[$getRandomIndex] + ',' + $PSItem.group.type[$getRandomIndex] + ',' + $PSItem.group.url[$getRandomIndex] ) } $logFilePath = "c:\temp" $logFileOKName = "$(Get-Date -Format 'yyyyMMdd-HHmmss')_LogOK.txt" $logFileOK = "$logFilePath\$logFileOKName" $logFileNOTOKName = "$(Get-Date -Format 'yyyyMMdd-HHmmss')_LogNOTOK.txt" $logFileNOTOK = "$logFilePath\$logFileNOTOKName" if( -not $($logFileOK | Test-Path) ) { New-Item -Path $logFilePath -Name $logFileOKName -ItemType File } if( -not $($logFileNOTOK | Test-Path) ) { New-Item -Path $logFilePath -Name $logFileNOTOKName -ItemType File } $tempArray | ForEach-Object { try{ $currentURL = $($PSItem.split(',')[-1]) $wgetResult = $null $wgetResult = Invoke-WebRequest -Uri $currentURL -ErrorAction Stop if( $wgetResult.StatusCode -eq 200 ) { Write-Host "$currentURL responded with $($wgetResult.StatusCode)" -ForegroundColor Green Add-Content -Path $logFileOK -Value "[PROC] $currentURL responded with $($wgetResult.StatusCode)" } else { Write-Host "$currentURL responded with $($wgetResult.StatusCode)" -ForegroundColor Red Add-Content -Path $logFileNOTOK -Value -Value "[WRNG] $$currentURL responded with $($wgetResult.StatusCode)" } } catch { Write-Host "$currentURL responded with no status code." -ForegroundColor Red Add-Content -Path $logFileNOTOK -Value "[ERR] $currentURL responded with no status code." } }

Provade koden men den spottar ut två tomma filer, har ändrat source och logfile location men gissar att det är något annat som spökar!

Bifogar bild på error men som sagt, tidigare när jag får i consol och kan kopiera in själv funkar så spendera inte för mycket tid på mig

Permalänk
Medlem

Du får tänka på att sajtens innehåll kan ha ändrats eller försvunnit medans länken fortfarande fungerar men det kanske inte spelar någon roll för just det du gör.

Permalänk
Medlem
Skrivet av zencity:

Provade koden men den spottar ut två tomma filer, har ändrat source och logfile location men gissar att det är något annat som spökar!

Bifogar bild på error men som sagt, tidigare när jag får i consol och kan kopiera in själv funkar så spendera inte för mycket tid på mig

https://i.postimg.cc/Y9XXWZX0/errorz.png

Ja, den skapar loggfilerna innan den skriver till dem. Därför kan de, om det går fel, bli två tomma filer.

Det du får är egen text som jag lagt in. Det den säger är att den inte har någon URL identifierad och att något gick fel när den försökte nå URL:en.

Jag kan absolut hjälpa till mer Gör sånt här både på arbetstid och fritid
Men ska vi göra det bättre och snyggare så kanske jag behöver lite mer info - som du kanske inte vill lämna här i en tråd.
Vill du dra det vidare så kan du köra via PM eller annat - och då kan du säga hur via PM

Cheers!

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Medlem

Tack som tusan, sicket geni du är. Jag ska sitta en del med det här i helgen och kanske slänger iväg ett PM på önskelista och om möjligt kontraktera dig. Det vore smutt att koka ner mina tråkiga arbetsuppgifter till ett minimum

Permalänk

Jag förstår inte riktigt vad själva syftet är?

Varför inte bara göra en ping till alla sidor och spotta ut dem med problem?

Permalänk
Medlem
Skrivet av andreasekman:

Jag förstår inte riktigt vad själva syftet är?

Varför inte bara göra en ping till alla sidor och spotta ut dem med problem?

Detta var scope enligt TL:
"varje dag slumpmässigt gå igenom varje Provider och klicka på URL för en slumpmässigt vald Product för respektive Brand"

Visa signatur

🟢 Main: Ryzen7 5800X | Strix x470-I | 32GB | RTX2070S | Samsung C49RG9
🔵 unRaid: Ryzen5 2700X | B450M DS3H | 32GB
🟠 Tfn: Google Pixel 7 Lime Green

-:| @ eller citera för svar |:-

Permalänk
Skrivet av GreyWilk:

Detta var scope enligt TL:
"varje dag slumpmässigt gå igenom varje Provider och klicka på URL för en slumpmässigt vald Product för respektive Brand"

Jo det läste jag, men jag förstår inte vad man försöker åstadkomma. Lite lättare att hjälpa till om jag förstår

Permalänk
Medlem

Du kunde löst det med Excel också

COUNTA för antalet rader
RAND som genererar slumpat tal mellan 0 och 1
Multiplicera med COUNTA och avrunda till heltal med ROUND
INDEX("hela listan";slumpade radnumret;kolumnen du söker).

RAND är volatil så den vill räknas om varje gång du ändrar något i arket om du inte stänger av automatisk kalkylering

Gjorde en snabb mockup

Visa signatur

Solen i africa! Hjälp snabbt. Tävling i klassen!
Det var High noon.
Om solen i Africa en truckförare kommer från East till Weast på huvudvägen. och exact vid eqvatorn vid Africa. Landskapet är totalt slät. På en tidpunkt var solen så ett par telestolpar gjorde så att det blev skugga.
3 gissar jag på, men kan inte förklara?