Comparing the Corona outbreak in Scandinavia and South, South-East Asia

I have read the WHO's sitreps on CoViD-19 daily since the end of January 2020, where I was visiting Viet Nam. I now live in Denmark (a Scandinavian country) where the Corona virus has shut down society and many people have tested positive. When I compare the numbers for Scandinavia (Denmark, Norway, Sweden) with a large group of low-incidence Asian countries (Philippines, Singapore, Viet Nam, Cambodia, Mongolia, Laos, Thailand, Indonesia, India, Sri Lanka, Bangladesh), then the facts are that:

  • The number of reported infected and dead people in the Asian Countries and Scandinavia is roughly the same, with 4,565/7,839 infected and 152/121 dead in the two groups. (source: WHO).
  • The population of the Asian countries is 100 times larger than the Scandinavian countries, with 2 billion and 20 million people respectively (source: Wikipedia)

How can this be? Either the numbers are directionally wrong or they are directionally right?

I deliberately didn't include Korea and Japan. I have focused on the Asian countries, where 1/4 of all humans live today and where the WHO says that people haven't caught the Corona virus (yet).

If the numbers are wrong

Then the numbers might be systematically under-reported in all of the low-incidence Asian countries. They could also be over-reported in Scandinavia or something else. One of these might be true, but I will assume that the numbers are right.

If the numbers are right

According to some theories of epidemics (and many assumptions on population density etc.), either:
1) The number of number of susceptible people must have been much, much lower in the Asian countries compared to Scandinavia at end of February 2020. In other words, people from the listed Asian countries simply can't catch the virus.
2) And/or, the infection rate must have been much, much lower in the Asian countries compared to Scandinavia. In other words, the virus simply doesn't spread effectively in the listed Asian countries.

Possible explanations

Again, assuming that the numbers are right. I can think of a few explanations.

For case 1 ("fewer susceptible people in Asian countries"), I have one hypothesis (which you can try to argue against):

  • a: The Asian population already had partial immunity to SARS-CoV-2, due to historical outbreaks e.g. of SARS.

For case 2 ("lower infection rate in Asian countries"), I have a handful of hypotheses (which you can try to argue against):

  • a: The climate is different in the Asian countries (from Mongolia to Indonesia) and Scandinavia in a way that affects the Corona virus.
  • b: The measures against the spread of the virus, such as social distancing, are fundamentally more effective in the low-incidence Asian countries than in Scandinavia. I was in Viet Nam in February 2020 and the level of caution was very high back then compared to Denmark (e.g. face masks everywhere).

Can you refute any of the hypotheses that assume that the numbers are right?

Sagawind 20

Through hulls on Sagawind 20

This year I bought an old sail boat from 1979 - a Sagawind 20. My first order of concern is to check the location and state of the through hulls, which are perhaps the most critical part of a sail boat. There is literally a hole through the hull!

Special valves - called sea cocks - keep water from flowing in and the state of these is important as the boat will sink if they leak.

Through hull locations

The boat was in the water when I bought it, but the previous owner has sent me some pictures from when it was on land. I've tried to spot the through hulls and numbered them below.

It looks like 1 and 2 are below the water line, while 3, 4 and 5 are above the water line. I believe that (?) is just some gritty stuff and not an actual through hull, but I will see when I get it on land.


I've found three seacocks inside the boat, two for the toilet (probably drain to holes 1 and 2) and one seacock for the sink. The wierd thing is that I don't see a through hull where the sink's seacock is located. If the sink drains to 3, then why is there a sea cock when it's above the water line? This leads me to suspect that there might be one more below-water-line through hull, that I have not found in the pictures. I will see when the boat is on land the next time.

Here are some images of the seacocks. I've been told that the previous-previous owner changed them, but I'm a bit uncertain about the material used. I will try to diagnose the next time I'm on the boat. My fear is that he chose brass seacocks, which will corrode very quickly. We will see. If that is the case, I'll probably spend the money to exchange them to bronze or plastic (Marelon) seacocks.

Here is a very nice description of different types of seacocks:

How to compute and plot Bollinger Bands® in Python

The aim is to produce a plot like this. The orange line is your data, the green line is the upper "bollinger" band, the blue line is the lower "bollinger" band. The red dots indicate where your data is either above or below the bands.

Copy-paste this code:

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

N = 100
XMAX = 5
WINMA = 10

def get_bollinger(data, winma=10, alpha=2):
    ser = pd.Series(data)
    ma = ser.rolling(winma).mean()
    std = ser.rolling(winma).std()
    lower = pd.Series(ma - alpha*std).fillna(method='bfill').values
    upper = pd.Series(ma + alpha*std).fillna(method='bfill').values
    return lower, upper

def get_alerts(data, lower, upper):
    low = np.argwhere(data < lower)
    high = np.argwhere(data > upper)
    return low, high

if __name__=='__main__':

    X = np.linspace(0.0, XMAX, num=N)
    data = np.sin(X) + np.random.random(N)
    lower, upper = get_bollinger(data, winma=WINMA, alpha=ALPHA)
    low, high = get_alerts(data, lower, upper)
    for i in low:
        plt.plot(X[i], data[i], 'ro')
    for i in high:
        plt.plot(X[i], data[i], 'ro')
    plt.plot(X, lower)
    plt.plot(X, data)
    plt.plot(X, upper)

See who is hosting a website

To see who is hosting a website (e.g., you will need the IP address of the website and the WHOIS record for that IP address. You can obtain both from the command-line.

Obtain the IP address for

# Ping the website
# Alternatively, use traceroute and note the last IP address

For me, the command returned the IP address Now, look up the WHOIS record for the IP address to see who owns it:

# Look up the WHOIS record

Here is the record I got from WHOIS for netflix:

OrgName:        Amazon Technologies Inc.
OrgId:          AT-88-Z
Address:        410 Terry Ave N.
City:           Seattle
StateProv:      WA
PostalCode:     98109
Country:        US

So, at the time of writing, it seems that was hosted by Amazon.

How to chat between computers using netcat on Mac and Linux

In our home we have a mix of Mac and Linux computers. My children have a Raspberry Pi in their room and I have a Mac at my desk. Today we chatted with each other through the Terminal running on both computers.

Hi children!
Am I talking to a bird?

(It was a very interesting conversation as you can see)

How to chat using netcat

You can chat between two Unix computers (e.g. Linux or Mac) only using the Terminal and netcat command (i.e. the command nc). The netcat command is slightly different on the two OS'es, but I'll write the variation in comments.

First, you open a terminal window on both computers:

On a Mac, open e.g. the Terminal application

Now, choose one computer to listen (computer #1) and the other to connect to the first (computer #2). We chose that my Mac would listen and the childrens Raspberry Pi would connect.

Set up the listening computer

On the first computer, start netcat listening for incoming messages on port 23456 (or whatever port you prefer). You'll see that the command is slightly different on Mac and Linux.

# On Mac: nc -l <PORT>
nc -l 23456
# On Linux: nc -l -p <PORT>
nc -l -p 23456

Check the IP address of the listening computer:


Look for an entry called "inet", which looks something like this:

inet netmask 0xffffff00 broadcast

Shout the IP address you found into the house for all to hear!

Hey, I'm listening on port 23456 and my IP address is !!!

Remember to shout the IP address you found, not the one I wrote above, since yours will probably be different... Now this computer is ready to chat!

Set up the connecting computer

On the second computer, use netcat to connect to the "listening" computer, using the IP address and port that the other person shouted to you.

# Mac/Linux: nc <IP ADDR> <PORT>
nc 23456

Again, rememember that the IP address above is just an example. Most likely, the person shouted different numbers to you.

Now the fun part: chat!

Now either computer you can type messages and hit enter. The thing you typed will appear on the other computer. Remember to finish your message by hitting the enter key.

hi, how are you? <enter>

After you hit enter, the message will appear on the other computer, where the person might reply:

hi, how are you?
I am fine thank you. How are you doing? <enter>


After you have exchanged a few pleasant greetings, you can start hacking. For example:

  • What happens if you receive a message while you are typing?
  • Does the output always look the same on both computers?
  • What happens if you send special characters (e.g. apple character on a Mac)?
    • You can generally type special characters by using modifier keys, such as alt/option. E.g. to type an Apple icon on a Mac (Danish keyboard) you'll hit option + $/§.

When you are done chatting you can exit netcat with ctrl + c. It doesn't matter who does this first, the other side will exit as well.

How to discover devices on your network (Mac/Linux)

There are several ways to check what devices are currently logged on to your network (e.g. WiFi at home).

The first option is to use arp, which I have found works the best. There will be some cases where it does not work.

In the following example, I'll assume that your IP address is

Using arp and nmap

First, scan your sub-network:

# see you IP address using ifconfig, here it's assumed to be

Second, list devices in your ARP cache:

arp -a

If the output doesn’t look up to date, or if it’s missing an IP you believe should be there, ping the broadcast IP (typically the last result of arp -a ending with “.255”).

# Assuming was the last address in the output from arp -a

Now, run arp -a again.

ARP spoofing

Notice that a malicious user can use arp spoofing to mix up the association between MAC addresses and IP addresses. This can be used for man-in-the-middle attacks.

Other ways

You could also use WireShark or even a third or fourth method, but I will not cover those here.

Frk. Slimas Fornemmelse for Snot

Af Kostas Kefaloukos

Danmark er et lille halvkoldt land, halvlangt mod nord. Det er ikke så koldt at der er særligt meget sne. Til gengæld blæser det meget og regner hele tiden. Disse vejrforhold gør at danskerne ofte bliver forkølede og udvikler store mængder af snot i næse og svælg. På samme måder som grønlænderne har mange ord for sne, har danskerne mange ord for snot. "Grønhakker", "Bussemand", "Løbesnot" osv. Snot forekommer i mange variationer og danskerne kender indgående fornemmelsen af hver eneste form for snot. I denne artikel vil jeg omhyggeligt gennemgå de mest gængse former for snot og relaterede emner.

  • Almindelig snot
  • bussemænd
  • sjældne snotformer.

Almindelig snot

  • Løbesnot. Meget tyndtflydende og oftest klar snot, som typisk forekommer ved allergi og høfeber. Utroligt irriterende og nærmest umulig at slippe af med. Man pudser næse hver 30. sekund og lige lidt hjælper det. Har man ikke et stykke papir, må man snøfte konstant for at holde trit med snotten. Dette er helt utroligt irriterende. Forekommer dette mens man sover, må man på et tidspunkt give op, og acceptere at der kommer snot overalt.
  • Kompakt snot. Typisk ved slem forkølelse. Der dannes et ekstremt overtryk i hovedet når man prøver at blæse den ud og man kan lige så godt give op. Man har det lidt som Arnold Schwarzenegger i Total Recall; scenen hvor hans øjne popper ud og hovedet sprænger i luften. Kompakt snot kommer ikke ud foreløbigt. Man fristes til at prøve igen og igen da fornemmelsen af at kraniet er blevet udstoppet af en satanisk taksidermiker er tæt på uudholdelig. På et tidspunkt kan man fristes til at holde hovedet over en dampende gryde i et desperat forsøg på at opløse snotten, men man kan lige så godt lade være. Det er omsonst.
  • Gul snot. Når forkølelsen er på sit højeste forkommer denne særligt klamme form for snot. Store mængder. Mellem-flydende. Minder lidt om østers. På dette tidspunkt kan området under næsen godt være en smule medtaget, og det svier at tørre snotten væk. Når man pudser næsen i et stykke køkkenrulle eller serviet, kan man betaget stå og se på de enorme mængder der havnede i papiret. Det er lige før man kan spå i det. Det dejlige ved denne form for snot er, at man rent faktisk bliver lidt stolt når man har produceret en ordentlig klump i lommetørklædet.
  • Grønhakker. Som gul snot, bare grønt. Denne form for snot kan næsten gå selv. Meget tilfredsstillende at spytte ud på en fortorvsflise, men samtidigt ekstremt klamt at se på. Ret fascinerende den måde som grønhakkeren lander f.eks. på en fortorvsflise. Fra det sted hvor den lander, bliver den typisk strukket et par centimeter indtil den indre sammenhængskraft og friktion standser processen. Resultatet er ofte en lang grøn streg på flisen. Hvis man er en meget barsk fyr eller pige gøres dette helt åbenlyst og til stor gru for omkringstående personer, som i smug er lidt bange for at komme til at træde i grønhakkeren. Man går selv i en meget stor bue udenom mesterværket.
  • Hvid Gummisnot. Meget viskos snot, der kommer ud i små gelé-agtige klumper. Det burde være forbudt og det er ikke særligt tilfredsstillende at have med at gøre. Snottens svar på Sysifosarbejde.
  • Gul gummisnot. Kan eventuelt hostes op fra lungerne. Dejligt at spytte ud i håndvasken og skylle væk med koldt vand! I forhold til hvor betændt denne snot ser ud, er mængderne som regel ret beherskede. Man tænker måske bekymret på om man udviser tegn på forstadier til slem "gulag" lungebetændelse.
  • Grøn kæmpe-gummisnot. En klar indikator på "gulag" lungebetændelse. Døden er nær, men indtræffer til stor lettelse sjældent. Hostes op fra lungerne i en kompakt klump. Utroligt tilfredsstillende at spytte ud i håndvasken. Man føler at kroppen er blevet renset. Det dummeste man kan gøre er at tygge på det, og genoptage klumpen i systemet. Den vender tilbage!!


  • Knastør bussemand. Indgår ofte i fusion med næsehår og kan derfor være smertelig at pille ud, da næsehårene typisk rives med ud. Man skulle tro at næsen spontant havde produceret superlim. Denne bussemand er typisk ret flad og grålig i farven. Den er ikke særligt god at trille, da den højst kan foldes lidt sammen og danner ikke en fin kugleform. Følelsen er lidt anti-klimatisk og af denne grund smides bussemanden ofte hvor den pilles. En ret kedelig bussemand.
  • Almindelig bussemand. Dette er en dejlig bussemand. Kan trilles til en perfekt kugle. Farven kan være grønlig til grålig. En almindelig adspredelse er, at trille disse bussemænd mens man sidder i en bilkø eller i sofaen og ser fjernsyn. Selve trilningen må foregå i smug, da det sociale stigma ved åbenlyst at trille bussemænd for de fleste er for stort. Når man er færdig med at trille bussemanden, skal man skille sig af med den. Dette foregår for de flestes vedkommende også i smug. Den kan f.eks. elegant sendes afsted med pegefingeren fra en skjult position. Ved kørsel kan man rulle vinduet ned og måske lade som om armen bare skal dingle lidt. Med en diskret bevægelse smides bussemanden ned på vejen uden at nogen ser det. En lignende manøvre kan foretages i sofaen, hvor hånden der holder bussemanden diskret lægges på ryglænet. Efter en passende pause lader man bussemanden falde. Denne form for bussemand spises ofte af børn, enten rå eller trillet. Det er ikke farligt, men dog ret klamt.
  • Gummi bussemand. Ofte lille og nærmest dej-agtig (våd dej) at røre ved. Lad dig ikke narre af størrelsen. Dette er den mest irriterende form for bussemand. Den er umulig at få pillet ud i ét stykke med fingeren. Man piller og piller og piller og ender med at tvære bussemanden ud på fingeren uden at få det hele med. Resultatet kan i slemme tilfælde være lange bussemandstråde mellem finger og næse. Forsøger man at trille den til en kugle, som en almindelig bussemand, vil man fejle. Man kan med nogen success skrabe denne slemme bussemandstype ud med et lommetørklæde.

Sjældne snotformer

  • Orange snot. snot i sin pureste form. Mellem-flydende. Meget sjælden.

How to scrape images from the web

I'm interested in object detection and other computer vision tasks. For example, I'm working on a teddy-bear detector with my son.

So, how do you quickly download images for a certain category? You can use this approach that I learned from a course on Udemy.

# pip install icrawler
from icrawler.builtin import GoogleImageCrawler

keywords = ['cat', 'dog']
for keyword in keywords:
    google_crawler = GoogleImageCrawler(
        storage={'root_dir': 'images/{}'.format(keyword)}
        keyword=keyword, max_num=10, min_size=(200, 200))

In the above example, the crawler will find images in two categories -- cats and dogs, as if you search for 'cat' and 'dog' on Google images and downloaded what you found.

Let's walk through the parameters used in the code. First, there is the constructor, which is called with three arguments in the example. The most important parameter is storage, which specifies where the images will be stored. Second, we have the call to the crawl function. Here, the max_num parameter is used to specify that at most 10 images per category should be downloaded. The min_size argument specifies that the images must be at least 200 x 200 pixels.

That's it. Happy downloading.

How to fill missing dates in Pandas

Create a pandas dataframe with a date column:

import pandas as pd
import datetime
ONE_WEEK = datetime.timedelta(days=7)
ONE_DAY = datetime.timedelta(days=1)
df = pd.DataFrame({'dt': [TODAY-ONE_WEEK, TODAY-3*ONE_DAY, TODAY], 'x': [42, 45,127]})

The dates have gaps:

           dt    x
0  2018-11-19   42
1  2018-11-23   45
2  2018-11-26  127

Now, fill in the missing dates:

r = pd.date_range(start=df.dt.min(), end=df.dt.max())

Voila! The dataframe no longer has gaps:

          dt      x
0 2018-11-19   42.0
1 2018-11-20    NaN
2 2018-11-21    NaN
3 2018-11-22    NaN
4 2018-11-23   45.0
5 2018-11-24    NaN
6 2018-11-25    NaN
7 2018-11-26  127.0