Recovering From COVID19

On the first week of March, I got the coronavirus. This is my experience at accelerating my recovery from it. The government was of no help, as usual.

It was just a cold

After going to Paris for EthCC, I got a cold. It was manageable at first, until the day I had to fly back to Berlin, because I thought hey, my flight is so early in the morning, might as well save money by sleeping over at the airport instead of a hostel!

Except that I didn’t even get to the airport in time to sleep, because I was having too much fun dancing zouk. In the end it was 4am, I couldn’t sleep on the bus because I was cold and afraid I might miss the stop at the airport, and when I had finally walked to the boarding gate, there wasn’t enough time to get proper sleep anyway.

There the cold really stopped being a sniffle and I had to blow my nose every now and then.

An aside about the Paris airport: incredibly, you will see homeless people sleeping in the airport. I don’t blame them, but when they piss on a wall indoors, when they could have just walked to a restroom, they really should be kicked out. I have no idea who said Paris was the city of romance.

Once I returned to Berlin, I slept with a hot water bottle. My cold improved immediately, and my mucus became green. So much for the cold.

But a day later, while walking back home, I felt the beginnings of a fever.

Continue reading Recovering From COVID19

Lifesim and Girlsim, answering the big questions of life

A few days ago I discovered cadCAD while researching token engineering, and in a fit of sudden creativity, I coded up two simulations to life’s questions that had been subtly bothering me.

I know I’ll get a lot of flak from people about the dating simulator, even from dating coaches I took advice from, where making a simulation is “thinking too much” to them. But being able to put hard numbers on my expectations is the biggest thing I never knew I was missing.

What is it?

It’s a framework to make testing simulations of complex systems easier.

Or more specifically: you write your actors and strategies and environmental conditions. cadCAD turns this into a pandas.DataFrame and runs the simulation a number of times for you, letting you switch easily between simulation strategies.


Lifesim 2 – a job search situation simulator

Your bank account balance over 3 years, assuming you keep living expenses at 1800EUR and you look for 3 jobs per month between jobs

Suppose the following:
* You’re looking for a job.
* Your monthly expenses are 1800EUR.
* You have a 20% chance of getting a job once you’ve applied for it (IRL this means personal contact, not sending your resume somewhere)
* Most jobs pay around 3000EUR +- 2000EUR.
* Each month, a job has a 10% chance of firing you.
* You can afford to make 2-3 personal connections per month that lead to jobs.
* Your minimum criteria: job must pay at least your monthly living expenses.

What will your bank account look like in 3 years?

To play with the numbers, set up Jupyter notebook and the Python virtual environment with requirements.txt.


To guarantee that your balance will be positive in 3 years, you must look for jobs which pay 2 * monthly living expenses, and you must meet 2-3 people who can provide such jobs per month.


Suppose you’re a 5. How many girls should you ask out per day, and how choosy can you be, to have a satisfactory dating life?

Girlsim – how choosy can you afford to be?

No, there won't be a picture of a hot girl here
If you’re an ‘8’ who only dates ‘7s and up’, here’s your dating history over 30 lifetimes, assuming you’ve asked out 1000 girls (each colour is a different lifetime)

Critical assumptions

  • By definition, most girls are 5 in hotness. Sorry if I burst any princess bubbles.
  • Women of hotness x prefer hotness x+1 (some prefer less actually, but that’s another discussion).
  • Even if you move to a city where you find most girls hot, after a few months you will grow accustomed.
  • You meet an 8 just about as frequently as other people meet their 8s. That is, it doesn’t matter what an 8 actually looks like.
  • Chemistry is modeled by secret Chemistry numbers. If they match up (around 5-10% chance, or 1-2/20), you have chemistry.

Defining Success

Personally, “the feeling of sexual abundance” is important, i.e. you’re not desperate to cling on to her because she’s the only girl who’ll like you back in a long long time.

There are 2 ways of defining this. Pick one.

  1. 1000 girls is 1 year of asking out 3 girls a day. At least 1 girl a month is a reasonable expectation.

  2. The hotness distribution of girls who accepted you must look like a normal distribution, not discrete.


  1. Don’t be choosy. If you’re a 5 who only dates 7s, you’ll spend most of your time being desperate/insecure in a relationship, or lonely.
  2. Even if you do end up becoming a ‘9’ through hard work and upgrading your wardrobe, you’ll still mostly date 5s and 6s. Why? simple, there are more of them around.
  3. Improving your looks really makes a big difference, but it is no guarantee that you will end up with a hot girl. But it’s okay. There are many dimensions to women other than ‘hotness’.

Life Lessons from Dancing

There’s a big gulf between knowing and doing.
I spent a lot of time thinking of how to think so that I could generate moves. That helped to a certain extent, but I just kept thinking fruitlessly instead of just going out there and making mistakes.

Mistakes are great improvisation opportunities – and they make it more fun to dance with beginners (as long as they follow the basics). You can always alter the tension in the embrace/grip, and this changes the character of the dance and makes new things possible.

It’s not good enough to be good.
You need to be socially connected.
Going to a milonga, salsa party or any kind of partner dance social? The good dancers are usually too busy talking and dancing with other people for you to muscle into the situation in a smooth way.

Same with dating and (probably) making money too. Cold approach is not something you should use all the time, but an additional skill in your pocket that you pull out when the time is right (or if you have no other choice).

What do women want? Probably not what you think they want.
It’s easy to think that women want to see your fancy moves, your cars, your riches. No doubt this catches attention – but catching someone’s attention is just getting your foot in the door.

Many women also mistake attention for attraction, the classic example? Women who wear stockings in winter. Have they got our attention? Yes. Are we attracted? Maybe… but she’s obviously got issues. Similarly, if a leader looks great when dancing, but actually isn’t fun to dance with, or leads moves roughly for the follower, she won’t speak well of him afterwards.

Think of your fancy moves, clothing, watches, cars as the candy wrapper. In the end, the chocolate still needs to taste at least as good as the others, if not better.

What’s the chocolate in dance? It’s the feeling of understanding someone at a level where no words are needed. See Cory Henry and Yoran Vroom at 3:53. Telepathic understanding. Emotional sync.

Maybe that’s why women use so many words and emojis with each other, and obsess over how every part of their behaviour comes across. It’s all about establishing emotional harmony (this implies fitting in).

Appearance and reality, just like attention and attraction, are quite disconnected.
Germany is a strange country – a restaurant’s decor correlates directly with its food quality, whereas in Asia, you purposely go to shabby looking stalls by the side of the road to get great chicken rice that’s just as good as fancy restaurants.

For Germans, eating out is a social occasion, and the food is just one part of it. The atmosphere of course contributes to the occasion, and any restaurateur who neglects that is probably similarly sloppy in other aspects.

This is a classic correlation != causation example that only happened because of a particular mindset towards eating.

Apparently, I appear confident and know what I’m doing.
Or rather, women get insecure about their own abilities too and you have to constantly reassure them that yes, I did intend to lead that move.

I heard some women are like that with their looks.

Again, appearance and reality are two very different things. Sometimes they are connected. Beware this mental shortcut.

As you decide for a particular style, you will alienate people.
Dress normal and everybody will think nothing of you.
Dress preppy and some people will think you’re posing.
Dress goth and most people will think you’re “weird”.
Dress outdoorsy and you won’t stand out to the preppy people.

Don’t Think Too Much

There was a time when I never consciously thought about what I was doing. I made no progress and that wasn’t good.

Then I started thinking. I saw results, I made progress and that was good.

So I started thinking even more, because I wanted to succeed faster. I built thought frameworks (general rules to guide my thinking) as I learned about new fields. It took me a long time to realize that my rate of progress hadn’t changed at all, and I was burning more energy for nothing.

Why do I say that?

There were others who hadn’t built a clear framework of how to think. But it didn’t matter. Because of their social position, because they took action, they got the hot girl or were rich. Thinking the right way can lead you to success, but is only one component.

“A change in perspective is worth 80 IQ points” – Alan Kay

What’s the easiest way to get another perspective? Ask someone else. Sure, it is possible to imagine another perspective, but asking is just easier, plus you get to strengthen a social connection.

Sometimes, you don’t know what you don’t know – and this can overturn your thought framework overnight. Exploration is the answer here, and this can be time consuming.

Lastly, after having built many thought frameworks, I noticed most of them resulted in sound common sense. I didn’t have to spend so much energy building them in the first place!
Caveat: some bad life advice masquerades as common sense. It can really help to think through “common sense” advice to see if it really is “common sense” or some misguided line that an unfortunate, misinformed, unfortunately loud individual is spewing on social media.

The value of thinking

Thinking is simply bringing your subconscious thoughts up into the consciousness, where we can think about it faster using reason instead of emotion, overcome biases installed by society, overcome bad habits and misleading values in our subconscious, gain a clear vision of where we want to go etc. Words are the handles by which we grab and manipulate our thoughts from the sea of our subconscious. Word choice is very, very important.

But the consciousness is simply a tool, and one shouldn’t depend on one tool exclusively.

When I think too much

I go through life in a daze, not noticing the beauty in my surroundings, forgetting upcoming chores/appointments which are important but not urgent, and as a result I have to construct routines to get my life back on track, which makes me rigid and (ugh) German.

To improve one’s skills, there is no limit to the conscious complexity one can construct. But actually the most fun way is to improvise, boosting efficiency with honest communication and a very short iteration cycle.

When is a good time to think

When learning a new topic, a framework to guide your thoughts, a chosen set of values to strive towards from the very beginning, will help you achieve your goal quickly. (source: dancing experience)

When you have a gut feeling, but you just can’t put it into words. Not bringing it up to your subconscious could waste months, years of your time. Open a blank document and just start typing whatever comes to your mind, dumping your stream of consciousness into words (very effective, source: The Ultimate Commonplace System).

When building new processes to streamline your life. Within moderation: do not make a whole new routine and force yourself to commit to that. Instead, see what trhythm you naturally fall into and make slight tweaks to that. This is a good balance between enjoying life and improvement. Discipline is a finite resource after all.

Turn your brain off

I used to meditate to turn my brain off. Now I’ve rediscovered a better way from my childhood: video games, anime, tinkering with long lost hobbies. Wall Street Playboys would deride it as a waste of time, but one must waste a bit of anything once in a while.

The trick is to stop playing once you aren’t thinking about the original subject anymore, but your brain isn’t yet totally hooked on the game either. Video games can make your brain noisy and distracted too.

Am I thinking too much?

If you’re asking this question, you most certainly are. Remember a time when you weren’t under pressure to deliver, like your childhood. Then, in this quiet space that you’ve finally allowed yourself, listen to your gut.

You already know what to do.

Why you need a knowledge management system

What’s a knowledge management system? It’s basically your notes, organized. It can be a Google doc, paper, Evernote, or in my case, emacs and org-mode.

It started when I was trading crypto. I’d open a position, and several days later it’d seem like a bad idea, and I couldn’t remember why i had entered that position in the first place. So I started to log my thoughts. This helped me watch my thought process and actually improve.

Plus, it just pisses me off when I have to re-Google something I already learnt a long time ago. This happens a lot when wrestling with Linux for example.

But hopefully, dear reader, I don’t need to convince you why this is a good idea (although I lived without such a system for many years).

What I do want to discuss in this post, though, is using such systems to shape your mindset.


I learn so many things in dance class that I can’t remember all of them. So once I get home, I write them down in a text file.

Actually revising the notes is something I haven’t systematized. It already takes a few weeks to internalize a Zouk movement so even then, many ideas in the notes go to waste because you can’t remember them on the dance floor.


It is so easy to wonder: “how much does (thing I want to buy) cost again?” And waste an hour being distracted on eBay.

Or “how do I do that in Linux again?” And waste time Googling that site you knew you went to ages ago.

My computer notes are just about factual information but it is no understatement to say they have improved my productivity 5x at least by preventing me from being distracted.

The only problem is if I have so many notes in this category that I forget that I already made a note for something.


To remember what a specific book said, I summarize it so that it won’t take me much brain power to understand the important parts in the future.

This might not imprint its insights into my brain that deeply, but it does dig up the associated thoughts I had when reading that passage again, without having to actually spend time re-reading the passage. Repeat this over time and it becomes internalized.

Spaced Repetition with Anki

Using Anki to remember facts is straightforward enough. I can even use it to get me to see things in a new light, using carefully written questions and making sure that I don’t just answer the question correctly, I actually hold that thought in my head for a few minutes before finally answering.

However I haven’t figured out how to use Anki to totally change my mindset. Perhaps that only comes naturally after having seen enough subtopics in a new light.

Repeated visualization of a certain situation, and rehearsing how I should think vs. how I would think in that situation helps a lot more.

A simple guide to Winternitz OTS signatures

WOTS is a way of generating a public/private keypair, and using it for signing messages. In other words, it’s a signature scheme. Importantly, it only depends on having a good hash function, which makes it ‘quantum resistant’ because Shor’s algorithm can make cracking elliptic curves easier on quantum computers (????). XMSS uses a tweaked version called WOTS+, which improves some cryptographical aspects which I don’t quite understand. A lot of what I learnt came from this page at Cryptography Services.

Suppose we have a message ‘1234’. Let’s sign it with WOTS to prove that we created/sent this message.

1. Generate a Secret Key

Since our message is 4 characters long, we need to generate 4 random collections of bits (let’s call them words, because calling them bytes would imply they’re 8 bits long, which doesn’t have to be the case). So let’s say these words should be 6 bits long.

secretkey = ['011001', '010110', '100001', '001000']

2. Calculate the Public Key from the Secret Key

There are many hash functions out there, like SHA-1, SHA-2, SHA-3, Whirlpool, and the one everybody knows from Bittorrent, MD5.

The idea is you hash each word in the secretkey /n/ times, so let’s say /n=8/.

publickey = [sha2(sha2(sha2(sha2...('011001')))), sha2(sha2(sha2(sha2...('010110')))) ... ]

It is now quite impossible to calculate the secret key from the public key. It’s impossible for 1 iteration of SHA2, let alone 8.

3. Signing the message

The signature of '1' is sha2('011001')
The signature of '2' is sha2(sha2('010110'))
The signature of '3' is sha2(sha2(sha2('100001')))
The signature of '4' is sha2(sha2(sha2(sha2('001000'))))

Once you release your public key, everyone can see that if you hash sha2(‘011001′) 7 more times, and sha2(sha2(‘010110′)) 6 more times etc., they will have calculated your public key, and thus you have proved that you were the one who actually signed the message ‘1234′.

Obviously, don’t use this method to sign ‘2345′! Or any other message. It’s called a OTS because it’s a One Time Signature. Generate a new secret key each time you want to sign something.


The secret key now includes a random XOR bitmask for each word.

secretkey = [('011001', '111111'), ('010110', '001001'), ('100001', '000000'), ('001000', '101010')]

When calculating the public key/signature, after calculating the sha2(word), you XOR the result with the word’s secret bitmask. This is supposed to make signature sizes smaller/harder to crack (don’t ask me).

Generating Jules Verne novels with Torch-RNN

Torch-RNN is a rewrite of Andrej Karpathy’s char-rnn. You train it on some text, and then it can generate ‘similar’ text. I loved reading Jules Verne novels, so being able to just crank out some new novels whenever I feel like it sounds like a great idea right?

The hardest part was setting the environment up.

The text preprocessor was written in Python 2, and you’d think “hey it’s just wrangling some text what requirements does it need”. And it pulled in Cython, which numpy requires. Compiling Cython is always a bitch. I hate wading through compile scripts that I didn’t write myself that break.

The NN model itself is written in Lua and needs something called LuaJIT, which sounds like a faster variant of a Lua interpreter. Whatever, not interested in learning the language. Setting that up required a lot of compiling too.

In the end I managed to get everything setup, and realized that I couldn’t run the neural network on my GPU because everybody only writes for CUDA (thanks guys) and I have a Radeon HD 6870 (note: OpenCL won’t work out of the box with the Radeon Crimson 16.x beta drivers, the last ones to be released for Barts. You need Catalyst 15.7.1 WHQL for proper OpenCL 1.2 support).

Anyway. I took From the Earth to the Moon, Eight Hundred Leagues on the Amazon (I wanna read that!), and. The Secret of the Island (I just found out that this was written by someone else, and only translated by Verne!) and put them all in one huge
text file.

Training the neural network took all of my CPU. Since I was running in the Bash shell for Windows 10 there was no way I could’ve gotten it to run on the GPU anyway.

After a day or two of training (and about 20K iterations) the virtual Jules Verne spat this out:

& thon tole, by seemed profufess and metal stations requirements of Judge Ribeiro, which degrees. They have been descended some caber. “Imlet in “the struggled a pressure, we must attracted by Recthman. That is more principants of the amazing, nothing the course were so craw of the same peculiable perpetibilitions of the life of Judge Jarriquez frave to given arrive to violence. On the forests, with the /Tapperto/”_ The companion, and it like a close stretter had the traveler considerable than to the earth where the quality. On thick the Gun Club; what they disarsed of the idea of twenty-keeping them. But to this day as to me, fix _“jussiba!” “Aboats of do. During the darkment is recovertaken a despaited that public Street!” The long poblen the: dembnoit at langual paralle _ther of the Amazon?” “What a compressed to Project Gutenberg-textected to this apparent for hourbascure was no doubt, when he was with in its finished, “there would return with all, or rather journey. The step of the document seen to ask supering and have been liness; it would true. Not the diamobas writable intomarier of great a previous; after less mean them. And which simple with more than the villal work of the projectile would have indeed the topped the moon? Work of the pounds to proceed, at them in at over Joam Dacosta dadled for the refund of Sateltences comply up the certain soon in the right of nigmon. The Sound the projectile, and without retrew of the best conquernts misceldt. He as reply, the loud, the two gran! Unifer-“it is inches that the mass approach it, and we branches-that I cabinged that a comes ank, low. They reprisonation of the metal plantant mashed which his destity proper profession of a large feeting his none-wall of the gas, free cupiness, through frittle for the jokes Donselver, putting scars of carrying an edgars a fear one of the Rodroats as soverlocks at the Chaboy, you, she not have the syriy the coupo
Clearly it seems I should’ve just removed the Project Gutenberg prefaces from the training text.

Anyway it’s doing kinda well for a neural network that doesn’t understand English, and besides, doesn’t even understand the concepts behind the words.

Don’t add Django migrations to version control,, at least.

And here’s the one thing that might be useful, might not: committing your migrations to version control.

Here’s the situation: you’re working on the models for a Django app.

class Dog(models.Model):
    owner = models.ForeignKey(Person, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    age = models.IntegerField()

Hmm, perhaps age should be date-of-birth. After all, you don’t want to have to write some script to be updating the age value for every dog every year. No, perhaps it should be named dob after all.

So you make the change in and add the migrations for the changes as well, they get saved as or something.

Problem is, your colleague has been working on the very same model, and he had added some other fields too:

class Dog(models.Model):
    owner = models.ForeignKey(Person, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    dob = models.DateField()
    fav_foods = models.CharField(max_length=255, blank=True)
    potty_trained = models.BooleanField(default=False)

The migration that changes the first code snippet to the second in PostgreSQL gets saved as, and now your django-migrate fails after a git pull. Because assumes that age is still there and it’s a models.IntegerField, but the database on your machine looks different because you already renamed age to dob. Git can resolve conflicts between your, but not between the Django migrations.

So it’s best to just not add those migrations to the code repository unless you’re really sure that only one guy is working on the models. Because if more than one guy is working on the models, then everybody’s databases are different and the migrations can’t resolve that. You might as well do django-manage makemigrations from scratch.

Unless, of course, you already have data in there.

From Python to Google Go and Life

Now that I’m an adult, I find that doing things on the side these days is nigh unsustainable when one has to spend most of the day making a living. Besides working out almost everyday and reading articles on entrepreneurship like I used to devour articles on dating, there’s no time left but to get a good 8 hours of sleep.

But recently I got a chance to study Golang. As an enthusiastic Python developer, Go shows up as a language that has the same philosophy, but just happens to be compiled, statically typed, and have better support for concurrency.


The documentation is incredible. You can even do the Tour of Go on localhost by simply installing the gotour package.

go get

But I never learned anything from that because the Go Tour is just a museum of code snippets that show you Go’s features.

As usual, the best way to learn is to implement some utility that you want for your own in Go. For this, the go doc command is incredible. For example, this is the output of go doc json, straight from the terminal:

shinichi@ayanami ~/go/src/ $ go doc json
package json // import "encoding/json"

Package json implements encoding and decoding of JSON as defined in RFC
4627. The mapping between JSON and Go values is described in the
documentation for the Marshal and Unmarshal functions.

See "JSON and Go" for an introduction to this package:

func Compact(dst *bytes.Buffer, src []byte) error
func HTMLEscape(dst *bytes.Buffer, src []byte)
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
func Marshal(v interface{}) ([]byte, error)
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
func Unmarshal(data []byte, v interface{}) error
type Decoder struct{ ... }
func NewDecoder(r io.Reader) *Decoder
type Delim rune
type Encoder struct{ ... }
func NewEncoder(w io.Writer) *Encoder
type InvalidUTF8Error struct{ ... }
type InvalidUnmarshalError struct{ ... }
type Marshaler interface{ ... }
type MarshalerError struct{ ... }
type Number string
type RawMessage []byte
type SyntaxError struct{ ... }
type Token interface{}
type UnmarshalFieldError struct{ ... }
type UnmarshalTypeError struct{ ... }
type Unmarshaler interface{ ... }
type UnsupportedTypeError struct{ ... }
type UnsupportedValueError struct{ ... }

And you can go deeper and ask for documentation on the functions and structs too:

shinichi@ayanami ~/go/src/ $ go doc json.Token
package json // import "encoding/json"

type Token interface{}
A Token holds a value of one of these types:

Delim, for the four JSON delimiters [ ] { }
bool, for JSON booleans
float64, for JSON numbers
Number, for JSON numbers
string, for JSON string literals
nil, for JSON null

I only needed the internet to figure out how people usually did things in Go. For the specifics, this go doc command was incredible – never even had to leave my terminal.

The Result

A few hours took me from Hello World to a little utility that mirrors a directory structure with empty files. Why? My photos have important information in their filenames, and I want to write scripts that mess around with said filenames. Not going to do that on my real photo collection.

package main

import (

func mirror(path string, info os.FileInfo, err error) error {
    relpath, _ := filepath.Rel("/Volumes/Toshiba 2TB/pictures/", path)
    if info.IsDir() {
        os.Mkdir(relpath, 0755)
    } else {
        file , err := os.Create(relpath)
        if err != nil {
    return nil

func main(){
    fmt.Println("goutil starting")
    filepath.Walk("/Volumes/Toshiba 2TB/pictures/Photos", mirror)   

Things I noticed

Functions in Go usually return two values, the result and an error object. To receive both into variables you need := instead of =. I ran os.Create(), and some directories would have files in them but others wouldn’t, so I wanted to print the error object that os.Create() returns. However, it also returns a file object, and you can’t ignore that because the go compiler complains. That was seriously frustrating but it turns out that I did need the returned file handle because I was hitting the max open files limit. Good language design I suppose.

I have to say, error checking in returned values clutters up the code. Just look at the if statements above. This would be much more poetic in Python because of exceptions, which are implicit and bubble upwards from code below. Still, it probably doesn’t get much better than this in the compiled language world. Also, this can still be properly mitigated by keeping functions single purpose.

To ignore a return value, use _

Programming Languages and Social Issues

Afterwards I read Rob Pike’s blogpost on why people weren’t moving from C++ to Go as he had originally thought. It wasn’t about “the better tool for the job”, or productivity, or ease of maintenance. Simply put, C++ let you have control over everything, absolutely everything, and people who program in C++ like it that way, while Go has a garbage collector.

I get it, having control over absolutely everything, if only you knew enough about the language, is empowering.

However, I found that I really appreciate it when computers help me accomplish something and then get out of the way, like a tool. That’s why I use a Mac.

The choice of programming languages is now an ideology, a philosophy of life. Which brings us to the next question:

Does the inability of Lisp to gain popularity say something about the people who use it, and their life strategy?

Apparently it does, and I quickly found some articles about it. Rudolf Winestock’s The Lisp Curse is the most plausible and well explained. Mark Tarver’s The Bipolar Lisp Programmer is pithy and poetic, and it shows you what 56 years of living can do for your experience and knowledge.

The Lisp Curse also linked to Stanislav Datskovskiy, whose very writing radiates hatred, “I’m better than you-ness”, and a sense that he really is incredibly brilliant, which does no favours for his ego. I’ve been there, come back to earth, and I have just this one thing to say: he probably doesn’t get to fuck much.

And that was my day spent learning Google Go. In the end I guess I learned more about different walks of people than anything else.