You have to be carefully taught

Ieri sera mi sono accorto che stavo tenendo uno strano comportamento: da un lato ero in procinto di prendere l'aereo, e il maltempo su Dublino rischiava di impedirmi di partire; dall'altro lato, invece che tenere d'occhio le notizie sul maltempo, passavo il tempo a consultare le pagine politiche di un tot di giornali italiani (senza particolari preferenze: Corriere, Repubblica, la Stampa, il Fatto Quotidiano, il Giornale).

Mi sono allora chiesto il perché di questa asimmetria tra quello di cui avevo bisogno e quello che stavo facendo.

Alcune risposte possibili:

  • ho ancora amici e conoscenti in Italia, quindi me ne interesso;
  • quello che succede in Italia potrebbe avere influenza sulla mia vita qui all'estero (e.g. pensate se l'Italia facesse una corbelleria modello la Brexit);
  • sono abituato a leggere certe notizie quindi continuo a farlo;

Anche se in tutte queste c'è qualche cosa di vero, ho l'impressione che ci sia dell'altro.

A cosa sono abituato? A leggere notizie dell'Italia?

No, sono abituato a leggere notizie che hanno scarso impatto sulla mia vita quotidiana.

Quando era diventata da poco sindaco di Roma Virginia Raggi, i giornali erano pieni di tutto quello che faceva, e di quello che andava male a Roma; la cosa si era ripetuta uguale con Marino e con Alemanno.

Ora, questo avrebbe senso se la maggior parte degli italiani vivesse a Roma; ma la maggior parte degli italiani non vive a Roma, non ci è mai andato, e non ci andrà mai. Perciò, sapere che a Roma ci sono le buche o non ci sono non ha grande influenza nella loro vita.

Eppure siamo stati abituati a pensare che sia normale riempire i giornali per giorni e giorni di notizie di cui davvero non ci interessa nulla.

E che sia normale per noi leggerle.


ADnD, Low Pass Filter and Extract Method

As I am very fond of old style Role Playing Games, I am working on a toy project about Advanced Dungeons and Dragons, 1st edition.

Now, this game is full of strange rules. For example, when the characters encounter a group of monsters, both parties have to roll a d6 (standard six faced die); if one of the parties rolls 1 or 2, that party is surprised. Also, in this case, the value of the die (1 or 2) indicates the number of "segments" (6 seconds period) for which that party is surprised.

In my first Python implementation, this lead me to write a method in the Party class, which was something like this:

def surprise_segments(self):
roll = random.randint(1, 6)
return roll if roll <= 2 else 0
Pretty simple, right?

This simple piece of code didn't satisfy me very much. The roll variable wasn't very useful here: it was just a temp variable to keep the roll value so that it could be used in the following expression.

So, I decided to extract that part and see if I could come with something better:

def _upper_bound(self, roll):
return roll if roll <= 2 else 0
def surprise_segments(self):
return _upper_bound(random.randint(1, 6))
This was much better, as now I just invoked the randint function without holding the result somewhere.

What was not satisfactory now was the name of the auxiliary function; it wasn't saying very much about the actual behavior of the code. Moreover, if I read "upper bound", I expect something which will cap at a specific value.

From the experiences of some previous (working) life, I remembered that I was implementing some sort of filter, a low pass filter ( https://en.wikipedia.org/wiki/Low-pass_filter ). In my case, this is an "Ideal low pass filter", but this was enough for me. So, now I could rename the function:

def _low_pass_filter(self, value, cutoff):
return value if value <= cutoff else 0
def surprise_segments(self):
return self._low_pass_filter(random.randint(1, 6), 2)
While I wasn't able (yet) to find other parts of my code which needed a low_pass_filter, I found similar patterns like:

def a_method(self, ...)
x = something
y = something_else

So, this kind of pattern can be easily refactored:

def _do_something(self, x, y):
def a_method(self, ...)
self._do_something(something, something_else)
There are some advantages in doing this:
  • a_method becomes shorter, which could make it easier to read 
  • do_something can get a better name which really explains what you are trying to do_something 
  • do_something is a behavior which can be re-used 
  • do_something is a behavior which can be stubbed/mocked in a test 

There are a couple of refactorings which are relevant here:


You've got to be taught to hate and fear

You've got to be taught to hate and fear
You've got to be taught from year to year
It's got to be drummed in your dear little ear
You've got to be carefully taught

You've got to be taught to be afraid
Of people whose eyes are oddly made
And people whose skin is of diff'rent shade
You've got to be carefully taught

You've got to be taught before it's too late
Before you'r six or seven or eight
To hate all the people youre relatives hate
You've got to be carefully taught


Adding initiative table

A new version of the Calc spreadsheet to handle the combats.

I added on the right side the initiative order; also, the current attacker is highlighter both on the initiative order table (right side) and on the couplings table (middle).

I also restructured a lot the table on the left. My idea was to make it a little more "storytelling" and a little less "data entry". The labels will change according to what is the next expected action (by me or by the players) and thus I should avoid to be confused during the combat resolution.

I plan to create a new sheet to resolve social and academic actions, so that they can have the required depth as well.


Game session of Sunday

Yesterday was Sunday, and as usual, we had our (short) session playing Decipher's Lord of the Rings RPG.

In this game, I am the Narrator (or Dungeon Master if you prefer); my wife plays Carawen, an Elven female warrior from Mirkwood, and my daughter plays Luna, a (very young) wizard, pupil of Radagast, from the land of Rohan.

They are in year 2700 from Third Era. At the moment, they are traveling in the Iron Hills directed to Cape East, the most eastern of the Dwarven settlements in the Iron Hills. They are following the tracks of another Dwarf, Nar son of Dar, who was hunting a Dragon years before.

In the last short session, while they were camping on the road they met Morwen, a mysterious woman who was traveling alone coming from Cape East. During the night, they were attacked by a group of six orcs, but they were able to overcome them, also thanks to the prowess of Morwen with her sword. While they were warned about the possibility of attacks of Orcs on this road, they have not discovered yet if there was something more behind this.

Aside from the story (very little happened), I had the possibility to play-test the new version of my spreadsheet.

What went well:
  • spreadsheet is very good at keeping track of effects, like Staggered, Wounded, Broken Leg, etc.
  • since I can track them, I will actually use them

What went wrong
  • I didn't have the stats for a creature in the spreadsheet, hence I had to add them on-the-fly (lack of preparation);
  • having a single creature to make a test is fine, having 6 of them is cumbersome (need automation here);
  • some skills like Elusion (?) where I need to roll 3d6 and drop the lowest one are hard (create a generic dice roller to use);
  • while the system keeps track of who is doing who, I have to ensure that this is actually what is happening (interface is sometimes confusing);
  • Staggered tests are very common, better to have a dedicated button for it (add staggered button);
  • also, sometimes I am not sure of what is happening: maybe I need to add a little more log;

Actions (still to be cleared)
  • ensure that you have the proper stats loaded;- devise testing for a group, both for players and for other creatures;
  • create a generic dice roller (how many dice, how many to drops, etc);
  • have the system explain what it is doing;
  • add a button to check for Staggering;