Opportunity
Knocked, you weren’t in.
Ruby Wizardry translation to Ukrainian
The Ruby Wizardry book translation into Ukrainian is published!
I got involved with this book quite unexpectedly: a friend of mine who is a core member of local Ruby community #pivorak decided to translate this book into Ukrainian. As she was working through the book, we discussed and brainstormed a lot about how to best express many different puns, made-up words, exclamations in Ukrainian, how to translate character names and preserve their flair, how to pick the right name for various contraptions which might not be familiar to Ukrainian kids. All of this turned out to be very difficult; some sentences we worked on for days. Irina enlisted the help of the Ruby community as well, for example to come up with Ukrainian replacements to a plethora of humorous and witty exclamations the characters used.
An interesting challenge was about preserving or changing the genders of some characters to make the story sound more natural in Ukrainian language. There is an outstanding explanation about this difficulty on stackexchange, which I’d copy here:
Russian has a long standing tradition of narrating fables (stories featuring anthropomorphic animals).
In this tradition, the grammatical gender of name of the species (not necessarily the proper name of the animal) should be the same as the biological sex of the animal.
Some have mentioned Jungle Book’s Bagheera (who had been made a female in Russian adaptation), but this has little to do with his name.
The translator did not see any problem with Akela or Rama or other characters with declension I names, as long as she could put a masculine species name on them: волк, буйвол etc. Raksha is a female wolf, волчица, so she gets to stay a female as well.
However, this is a issue with пантера. The translator was faced with a problem: pick another species (she could have used леопард), make the readers accept that пантера is a boy in this story, or change Bagheera’s gender.
I don’t know why didn’t the translator choose the option 1, but the option 2 (leaving everything as is) was so bad that going through the pain of changing Bagheera’s sex through the story and having to cope with arousing difficulties was a better option.
Different authors choose different strategies for dealing with that, but in most cases, either the species or the sex gets changed, and only in rare cases the species name gender and the biological gender are left different:
- When translating “The Ant and the Grasshopper”, Krylov picked another species instead of grasshopper, a dragonfly (стрекоза), apparently to give the fable a better rhythm. Of course she was made a female. He left the word попрыгунья (“a jumper”) though, even though dragonflies don’t jump.
- In “Winnie-the-Pooh” adaptations, the Owl (Сова) was made a female character, though a Russian word филин does exist. In “Rikki-Tikki-Tavi”, Chuchundra (a rat, крыса) and Karait were made females. Even though the Russian word крайт exists and is masculine, it was deemed too unfamiliar to the Russian reader, so Karait was made just a snake, змея, and hence female.
- In “Alice’s Adventures in Wonderland”, the Dormouse (Соня) is female. The Caterpillar in different translations is either female (Гусеница) or changes the species (Червяк, “The Worm”).
- As you mentioned, changing the species name from masculine to feminine is almost always an option in Russian, so I can’t think of a reverse situation off the top of my head (changing the biological sex from female to male in the story), but would not be surprised if it was ever the case.
So the answer to your question would be that:
You just don’t write a traditional story about a male zebra in Russian. That’s not how Russian story telling works.
The Russian word for zebra is feminine, so a zebra character should be female. If he should be male, he should not be a zebra.
The book can be ordered here: https://starylev.com.ua/ruby-dlya-ditey
I am very happy with the print quality of the book, it actually surpassed my expectations. Very pleasant to see and read!
Correct English
Even if you do learn to speak correct English, whom are you going to speak it to?
Producing histograms in terminal
Quite often I end up with the need to quickly visualize information in a terminal as a histogram or a chart of some sort. Here are three methods I use most often.
Gnuplot
The first thing that comes to mind when it comes to charts is gnuplot
– a versatile tool to produce all kinds of charts and graphs. The cool feature of it is the support for dumb terminals so you can easily have charts like this:
ping google.com
55 +---------------------------------------------------------------------------+
| + + + + + + + + |
| |
50 |-+ * +-|
| * |
| * * * |
| * * * * |
45 |-+ * * * * +-|
| * * * * |
| * * * * |
40 |-+ * * * * +-|
| * * * * |
ms | * * * * |
35 |-+ * * * * +-|
| * * * * |
| * * * * |
30 |-+ ***** * *** * *-|
| **** ** * * * * |
|********** ** * ** * *|
| * * ** * *|
25 |-+ ********** * +-|
| * |
| + + + + + + + + |
20 +---------------------------------------------------------------------------+
0 1 2 3 4 5 6 7 8 9
count
I’ve generated this graph with the following command:
$ ping -c 10 google.com -i 0.2 | awk '/time=/{ print $(NF-1) }' | cut -d= -f2 | \
gnuplot -e \
"set terminal dumb size 90, 30; set autoscale; set title 'ping google.com';
set ylabel 'ms'; set xlabel 'count'; plot '-' with lines notitle";
A little bit more useful example:
$ sar | awk '/^(09|10)/{print substr($1,1,5), $4}' | \
gnuplot -e \
"set terminal dumb size 90, 30; set title '% CPU User'; set autoscale;
plot '-' using 2:xtic(1) with lines notitle";
% CPU User
18 +------------------------------------------------------------------------------+
| + + + + + + *******+ + + |
| * *** |
16 |-+ * * +-|
| * ** |
14 |-+ * ** +-|
| * |
| * *** |
12 |-+ * * +-|
| * * |
| * ** |
10 |-+ ** +-|
| ** *******|
8 |-+ ** +-|
| *** |
| **** |
6 |-+ ** +-|
| * |
| * |
4 |-+ * +-|
| * |
2 |-+ * +-|
| * |
|*********************+* + + + + + + + |
0 +------------------------------------------------------------------------------+
09:00 09:10 09:20 09:30 09:40 09:50 10:00 10:10 10:20 10:30 10:40 10:50
Important difference here is that we’re using xtic for x
tic labels. Let’s look at the input data sample:
$ sar | awk '/^(09|10)/{print substr($1,1,5), $4}'
09:00 0.44
09:10 0.44
09:20 0.41
09:30 0.37
09:40 6.37
09:50 7.35
10:00 9.58
10:10 17.54
10:20 16.42
10:30 12.82
10:40 9.33
10:50 8.85
Essentially, we have x tic labels in column one and the actual data in column two. We’re letting gnuplot
know about this with using 2:xtic(1)
instruction.
The key is to remember (or write down) this skeleton command:
gnuplot -e "set term dumb 120, 30; set autoscale; plot '-' with lines notitle"
It’s enough to draw a simple chart with a single data series. To account for xtic labels you just add using 2:xtic(1)
to plot
instruction.
Finally, for histogram data use set boxwidth 0.2; plot ... with boxes
.
perl one-liner
gnuplot
is an incredibly powerful tool, but often I find myself looking for a quick and dirty histogram-like representation for data. I don’t want go about fetching data from remote system to process it with gnuplot
on my laptop, nor am I willing to install gnuplot
on the remote system. In such situations I refer to a very old perl
-based approach, thanks to the fact that perl
is installed almost everywhere.
Let’s return to the above example with CPU usage information from sar
utility. Taking in the same input, we can do this:
$ sar | awk '/^(09|10)/{print substr($1,1,5), $4}' | \
perl -lane 'print $F[0], "\t", "=" x $F[1]'
09:00
09:10
09:20
09:30
09:40 ======
09:50 =======
10:00 =========
10:10 =================
10:20 ================
10:30 ============
10:40 =========
10:50 ========
It’s amazing how simple this command is for the results it produces! When the raw data numbers are to big for the terminal width, it’s easy to add scaling with ($F[1]/<scale_factor>)
, for example:
perl -lane 'print $F[0], "\t", "=" x ($F[1]/5)'
Sparklines
The third method for generating histograms and charts in terminal that I wanted to mention is sparklines. I first discovered it when I learnt about spark tool. It’s a simple bash script that you can use to generate Tufte’s sparklines.
Here’s an example (earthquakes and their magnitudes in the last 24 hours):
$ curl -s https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.csv | \
sed '1d' | \
cut -d, -f5 | \
spark
▃█▅▅█▅▃▃▅█▃▃▁▅▅▃▃▅▁▁▃▃▃▃▃▅▃█▅▁▃▅▃█▃▁
Setting up autossh autostart with systemd
Just a quick note on setting up autossh
on system’s startup. I use it to proxy-forward traffic from the internet exposed host to a firewalled host inside a private network. This way all the data and apps stay on-prem but are available to external users if needed.
autossh
advantage is that it restart ssh
in case connection breaks for some reason. It’s important to configure it in a way so that it can detect such breakdowns. For non-critical services, I specify the following options:
-o "ExitOnForwardFailure=yes" -o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3"
That makes autossh
detect issues within 2 minutes – enough for my purposes. The rest of parameters I provide are disabling autossh
monitoring mechanism (-M 0
because it’s not very reliable), sending it to the background (-f
, if running from command line) and the standard ones to set up ssh
tunnel. Here’s an example:
autossh -M 0 -f -o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-NR 8088:127.0.0.1:80 -i <ssh_key> user@host
To get this command execute on system’s boot, we need to create a simple systemd
service file /etc/systemd/system/autossh-<host>-<service/port>.service
:
[Unit]
Description=Keeps a tunnel to <host> for <service/port> open
After=network.target
[Service]
User=<user>
ExecStart=/usr/bin/autossh -M 0 -o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-NR 8088:127.0.0.1:80 \
-i <ssh-key>
user@host
[Install]
WantedBy=multi-user.target
and activate it: systemctl enable autossh-<host>-<service/port>
.