• Reading
  • Language

The 54 characters short stories challenge

It’s been a while I was looking for material to improve my Japanese, getting to know more kanji, knowing words and expressions. I’ve been trying to read the short news on the NHK easy website, but I wasn’t really into it. Since the content is changing almost every day, you don’t see any form of progress or rewards.

But these days I’ve been in Paris for work and decided to stop by the Japanese bookshop there, it was literally 15 minutes away from the workplace. It’s quite a big place, with two floors, comparing to what you can find in Lyon… nothing. So I just went there straight after work to take a look and stumbled across the easy-to-read and recommended book section. And there was this book, called the 「54字の物語」, literally “Stories in 54 characters”. The lady told me the required kanji level for this was similar to what primary school students knows in Japan and on each page, you get a simple explanation of the previous page’s short text. So I decided to give it a shot.

Cover of 54字の物語 © @ujiqn

To spice things up, and since there is 90 stories, I thought it could be cool to challenge myself to read one per day. But, to be sure everything was understood and to keep on doing it, I had to write the translation down somewhere. You know how it is easy to just let something go and forget about it. I had no intention in ruining the book by writing on it. I didn’t think it would either fit a blog post, so I went with Instagram stories instead. It seemed like a good place: picture, to show the original story, text, to write the translation on it and also a pin functionality on the profile, to keep them in one place, separated from the other random stuff I can share. Nice!

So here you go, I currently read and “translated” half of the book you can now watch here:

🎉 The stories in 54 characters challenge on Instagram. 🎉

Along the way, I noticed a few things that made this book even more interesting. A lot of stories are made according to a pattern: a normal situation is described followed by a pun or a weird element that completely change the understanding of the situation. For example, in the first pages, there’s a funny story that made me laugh:

海外旅行の大事な場面で、パパがくれた辞書に何度も助けられたよ。でもトイレに紙がない国にはもう行きたくないな。 “During important moments of my trip abroad, the dictionary my father gave me saved me many times ! But, I don’t want to go in countries without toilet paper in the restroom anymore.” If you didn’t understand the joke, the guy probably had to use his dictionary to wipe himself, just saying.

In an even more creative way, I found a story that is sort of an Easter egg. In Japan, unlike France, a lot of books have a dust cover and, sometimes, even a promotional belly-band, called obi coming from the Japanese kanji 帯. These are usually better crafted than the underlying cover. The paper is often soft or shiny and colorful, unlike the simple and monochrome cover it protects. And a lot of manga I’ve been reading often hide small drawings there, like funny cartoons related or not to the story you can find inside. K-ON!, for example, had these silly 4-cases short stories, Fullmetal Alchemist had one black cartoon per pure white cover… This has also inspired foreign drawers to make their own, French manga-like Lastman for example. It has this sex scene (nothing graphical) under the dust cover with the main character saying “what are you looking at?”. It makes the undercover a private place where things shouldn’t be seen but you’d still want to peek in. It can also be kind of a tool to hide what wouldn’t have been accepted in a library or simply random thoughts and sketches not matching the content.

When I removed the dust cover to see what’s inside — note that I’ve been so used to these, it’s almost a mechanical thing to do when I buy a book with a dust cover now — I found a short story, how surprising… But I didn’t immediately notice it was a different story from the one on the dust cover, the latter being just a retake from the book. So when I read it, I’d wanted to clap the author for such a clever note.

Belly-band and dust cover next to the gray cover showing a short story: こんなところまで読んでくれてありがとう。嬉しいよ。だけど、少し肌寒いからそのカバーはかけておいてくれないか? Undercover story: Thanks for reading this far. I’m happy! But, as it is a bit cold, could you put back the cover?

This simple short story reflects the humor the entire book is made of and this comparison with the cover of the book being wore to stay warm is brilliant I think. Congrats! 👏

I encountered another story type as well in a way they use the language itself to play with it. I remember one story where a thief stole a plate, plate whose writing was also included in the steal character, but as it was stolen, it changed the meaning of the story. I don’t remember if this was the first case of “writing play” I had seen but it sure is very clever. Either be meaning, writing or pronunciation tricks, this book has a lot to offer.


At the end of the book, the author explains a few things to make your own stories as well and share them on social networks. I might want to try writing my own stories later on, we’ll see if I feel like it.

I also thought about it since the beginning, but I’m following and supporting Dogen’s awesome lessons on Patreon about Japanese pitch-accent patterns and phonetics, and it could be nice to try recording myself pronouncing these short sentences as a way to practice.

If you understand Japanese, I encourage you to see the author’s other works, it is really interesting and I love his website: thinking.co.jp

While writing this article, I came across the announcement of the second volume, chills special, now available. Take a look at it! I’ll definitely buy it some day and might do this challenge myself one more time.

See you!

  • Development

Making a Twitter emoji map with Yahoo Weather API

A few days ago, a friend sent me a tweet showing a map of France made of emojis representing the weather in each part of the country. I found the idea to be nice and followed the account. Here’s what it looks like:

Emoji Weather Map France

Following this, several community managers took the opportunity to joke on the idea for the brands they were representing. It quickly became a meme Yahoo UK even reported it.

Another friend of mine sent me a roughly made version of Brittany, the France’s region I am from, that he wanted to make aswell. This got me the idea to look online for a Japan version of it with the corresponding words, tenki 天気 for weather, emoji 絵文字 which is originally a japanese word. But I didn’t find anything, so it was a little project that I could build for fun.

The same way I made the Twitter bot for my flying potato, I decided to go with simple free services not asking for so much maintenance. Hook.io was one of the solution I had known that stores scripts online and executes them through a URL, as simple as I needed. A thing I didn’t know before but that is very nice, is the ability to have your script directly on Github Gists and having it pulled automatically by hook.io, making it really easy to update your code unlike AWS Lambda for example.

With that settled, I started coding the script with the twitter package on NPM. I don’t know how it will go for the future but Twitter is actually updating its developer platform as I write these lines. So, for now, I used the former apps, gaving me the customer key / secret and the access token / secret I needed to tweet on behalf of an account. The code then, is rather simple:

import Twitter from 'twitter';

export default function postTweet(hook) {
  const client = new Twitter({
    consumer_key: hook.env.TWITTER_CONSUMER_KEY,
    consumer_secret: hook.env.TWITTER_CONSUMER_SECRET,
    access_token_key: hook.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: hook.env.TWITTER_ACCESS_TOKEN_SECRET
  });

  const status = 'Hello word!';

  client.post('statuses/update', {status}, (err, data) => {
    if (err) console.log(err);
    
    hook.res.end('Tweet', status, 'has been sent!');
  });
};

And now onto the real problem, drawing the map and finding the weather. For the first one, I just went to my Twitter and played around with spaces and the Sun emoji on the input text… I quickly ran out of characters since Japan is a wide country but thanksfully, japanese full-width space is wide and only takes 2 characters like emojis. So here’s my Japan emoji map:

Emoji Weather Map Japan Sunny

If you think you can do better, don’t hesitate to send me your result, I would glady update my script.

To get the weather information, I used Yahoo Weather API through a SQL-like language they made, YQL. All the information I needed on the data it gives me was the climate code under the condition key. Yahoo also uses a thing called woeid to represents places. So I made a list of places I thought the best and send it in only one request.

select item.condition from weather.forecast where woeid in (1, 2, 3...)

Now I only had to map the results to emojis. Here’s the list from what I thought was the best:

code emoji name
0 🌪️ tornado
1 🌀 tropical storm
2 🌀 hurricane
3 severe thunderstorms
4 thunderstorms
5 🌧️ mixed rain and snow
6 🌧️ mixed rain and sleet
7 🌨️ mixed snow and sleet
8 🌧️ freezing drizzle
9 🌧️ drizzle
10 🌧️ freezing rain
11 💦 showers
12 💦 showers
13 snow flurries
14 🌨️ light snow showers
15 blowing snow
16 snow
17 🌨️ hail
18 🌨️ sleet
19 🤔 dust (I don t know for this one yet)
20 🌁 foggy
21 🌫️ haze
22 🌫️ smoky
23 💨 blustery
24 🍃 windy
25 🥶 cold
26 cloudy
27 mostly cloudy (night)
28 🌥️ mostly cloudy (day)
29 partly cloudy (night)
30 🌤️ partly cloudy (day)
31 🌑 clear (night)
32 sunny
33 🌑 fair (night)
34 fair (day)
35 🌧 mixed rain and hail
36 🥵 hot
37 ⚡️ isolated thunderstorms
38 🌩️ scattered thunderstorms
39 🌩️ scattered thunderstorms
40 🌧 scattered showers
41 heavy snow
42 🌨 scattered snow showers
43 heavy snow
44 🌤 partly cloudy
45 ⛈️ thundershowers
46 snow showers
47 ⛈️ isolated thundershowers
3200 not available

Last step, making it into the tweet! Nothing more simple: dumping every variables into a template string, and sending it to Twitter. Important thing to keep in mind: Twitter trims the tweet, so you have to put something at the beginning that isn’t a space.

And voilà!

Emoji Weather Map Japan

With that being done, the script works but you have to activate it yourself. To create a regular call, I thought about using hook.io cron jobs, but they didn’t seem to work at the moment I was doing this. So I went to a little service called IFTTT working on the principle: if this occurs, then do that, the bold part being chosen through services they offer. So I picked Dates and Webhooks and made it into an applet: if each day at 12pm, then calls this URL.

The service is now fully working by itself on @emoji_tenki if you want to follow it and get the weather every 6 hours. :D

I also thought about trying to make a special version with Japanese kanji representing the weather (雨、晴、雷、雪…), I might give it a shot later.

See you next time!

  • Workshop

Parametric font workshop in Darmstadt

Hey everyone! A few months ago, on behalf of the company I work for, Prototypo, one of our designers, Pedro, and I headed to Germany! We held a 2-day workshop for the design faculty of Darmstadt.

Presenting the app and the technology

We introduced eager students to our parametric technology and typefaces, while sharing our history of how parametric typefaces and Prototypo came to life. The next generation of designers sure asked us a bunch of interesting questions! We covered licenses, the app’s freedom of creation and how you can achieve the best outcome in a limited time.

The idea for the workshop was to first create a typeface in Prototypo that would be reused with the parametric font technology in the context of an animation. This would be then integrated using HTML and the animation feature of CSS3 inside a web page.

We prepared a few sketches and examples to inspire the students and give them a few ideas to start with: simple animations using squares, rectangles, circles… in combination with some flashy color backgrounds.

Pedro's sketches

The workshop started on the Friday morning and, as expected, the students managed to master Prototypo quite easily. They started to refine their typeface on the very first day using different features like the manual editing.

Student using the app

The afternoon was a little more tricky, as we dived into coding. Applying an idea or a sketch into concrete logic is not an easy task, and as not everyone is familiar with coding, getting started was the real challenge. We started simple things using codepen.io, a really simple website that abstracts the hard part and gives you results very quickly.

The second day, we continued to refine the different compositions and integrated them in a pre-made ready-to-use project powered by Prototypo’s parametric font technology. With their pro account, students could directly import their font projects (created on Prototypo) into their animation. The only thing left to do was to explore the possibilities of the different inputs we could use (keyboard, sound…) and the different parameters we wanted to change according to these followings.

Student using the technology

All in all, this workshop was a great experience! We’re happy to have had the opportunity to teach both type design and code. And we even had the chance to get back with cool posters made by the students!!

Workshop posters made with Prototypo

We hope everyone had a great time! If you’re interested in a workshop, don’t hesitate to send us an email at contact[at]prototypo.io!

  • Development

Migrating 40k users from Hoodie / CouchDB to Graphcool

At Prototypo, we had an old backend system, that wasn’t flexible, or should I say too much flexible? So when I joined the team, I had the charge to rewrite the payment system with externals AWS Lamda. I didn’t talk that much about it but I dropped some thoughts on the article about Lambda and API Gateway.

But as we were adding features and all, we felt the need to refactor the rest. I guess Hoodie is a great tech when it comes to offline-first capabilities, simple storage like Firebase does and real-time data but we didn’t need all of this. It was used in a weird way that I immediately wanted to fix. Everything was loaded at the first page load and it kept sending data everytime there was a change without anything coming down from the server. We also experienced lots of problems where people had their fonts completely reset to a previous state due to multiple active sessions at the same time.

So our needs were:

  • Link more data to start working on collaborating features
  • Real-time data coming down from the server (again, collaborating features)
  • BaaS (Backend as a Service) to avoid the maintenance pain
  • Extensibility (like webhooks) to support the different

And I was using GraphQL for another project, that seemed to me the thing to use (no hype driven development, it’s just easier to fetch the data we need). It appears that, between all solutions that exists, graph.cool was the way to go. They have done a lot for the community, they open-source pretty much everything, they’re nice and their solution has a lot to offer!

  • Link more data: it’s a GraphQL API (compatible with both Relay and custom solutions like Apollo)
  • Real-time: They support GraphQL Subscriptions
  • “Functions” are a way to transform or react to changes
  • Their project plan is free for open-source (we are \o/)
  • They also have a way to extend GraphQL mutations with functions

And now, let’s dig that migration!

The database was, if I may, very poorly designed. Users are registered under a _users database that contains the basic info like the email, the password and a link to the billing account. Every user is linked to a unique — or so I thought… — database to store its preferences and projects.

Transfering user accounts first

I first decided to transfer every users we had in the database and that was the easiest since CouchDB has a REST endpoint that can dump everything. Just with /_users/_all_docs?include_docs=true. That being set, I had to push them onto GraphCool without bloating the network with 40k requests, that’s when GraphQL comes to be handy, you can batch mutations to avoid sending multiple requests and sending them all at once. I split my users into groups of 100 and send them while checking no errors were found.

To avoid duplicates, I first used the same batch ability to query every users and see which one were missing. So I could use that script multiple times to push the last users that were registered before we push the new code.

  1. Fetching all users

    {
      user1: User(email: "user@something.com") {
        id
      }
    
      user2: User(email: "notyetregistered@something.com") {
        id
      }
    
      ...
    }
    
  2. Filtering the response:

    {
      "data": {
        "user1": { "id": "some_id_returned_by_graphcool" },
        "user2": null,
        ...
      }
    }
    
  3. Sending the new ones:

    mutation {
    
      user2: signUpEmail(
        email: "notyetregistered@something.com",
        password: "password"
        oldSignedUpAt: "${signedUpAt}"
        oldCreatedAt: "${createdAt}"
      ) {
        id
      }
    
      ...
    }
    

And that’s pretty much everything to get everyone transfered.

Users’ fonts, profile and preferences

The biggest challenge was to sync users’ fonts because of the one-database-per-user thing. So if you take a user that have these projects:

  • My First Font
    • Regular
    • Bold
    • Custom variant
  • My Second Font
    • Regular

His database looked like this:

newappvalues/default
newaccountvalues/default

newfontvalues/myfirstfontregular
newfontvalues/myfirstfontbold
newfontvalues/myfirstfontcustomvariant
newfontvalues/mysecondfontregular

The first two documents contains the preferences and the profile values, but we’ll get to this later.

Each variant has its own document stored under family_name + variant_name somewhat sanitized. Now, that makes a terrible problem that I encountered when transferring accounts. What if I’m Japanese and I want to name my font 青空 — because Blue Sky is such a great name — you end up with newfontvalues/regular and worse, if you name your variant the same way newfontvalues/. You end up with an empty document name, that’s pretty bad… So I hope that our non-latin community could forgive us for this and that it should be totally fine from now on!

Font families are stored directly on the user preferences. Every font is just a plain object that has its own variants list pointing to their databases, roughly like this:

{
  "library": [
    {
      "name": "My First Font",
      "template": "venus.ptf",
      "variants": [
        { "name": "Regular", "db": "myfirstfontregular" },
        { "name": "Bold", "db": "myfirstfontbold" },
      ]
    },
    {
      "name": "My Second Font",
      "template": "elzevir.ptf",
      "variants": [
        { "name": "Regular", "db": "mysecondfontregular" }
      ]
    }
  ],
  ...
}

But, as far as I know, we only get users’ databases by querying them one by one… GET /__user_database__/_all_docs?include_all=true.

This time, the script went a bit further: I needed to fetch all users, remove the non-existing common documents from both ends (GraphCool and CouchDB) and query all the data. I made up a small cache system to avoid redownloading the all thing in case of failure. That being done, I could fetch a hundred users’ databases and send in one row the mutations I needed.

I used glouton, a small utility I made before for another use case. It allows you to retry failing requests and define a concurrency limit if you don’t want to send to many requests at the same time. For this migration, the configuration was pretty straightforward:

import fetch from 'node-fetch';
import glouton from 'glouton';

const fetchWithRetry = glouton(fetch, {
  concurrency: 1,

  validateResponse: r => {

    // We continue (see below why)
    if (r.status === 404) {
      return true;
    }

    // if request has failed, we'll try again later
    // you can also return a time (ms)
    // pretty useful for API limits
    if (!r.ok) {
      return 0;
    }

    // everything is ok, we shall proceed
    return true;
  },
});

...

fetchWithRetry(...)
  .then(r => {
    // When the resource is not found,
    // we can return a default value or something else
    // to avoid breaking everything
    if (r.status === 404) {
      return { rows: [] };
    }

    return r.json();
  })
  .then(data => {
    // do what you need
  })

Having everything I needed, I just had to start creating my mutations. The rough part was knowing which variant belong to which font — assuming people could and would rename them — when they were already transfered. Basically, I only saved user_database-document_name into an oldId field that could allowed me to gather them into a family array.

  1. Gather me every variant with their family infos.
  2. Look for the ones that were already migrated
  3. Prepare the variants attributes
    const variantProperties = font.map(variant => `
      name: "${variant.name}",
      oldId: "${user.databaseName}-${variant.documentName}",
      values: "${JSON.stringify(variant.values)}",
    `)
    
  4. Update families and create the missing variants
    gql`
      updateFamily(id: "${familyId}", name: "${familyName}", template: "${familyTemplate}") {
        id
      }
      
      createVariant(
        ${variantProperties}
        familyId: "${familyId}"
      ) {
        id
      }
    `
    
  5. Create the missing families with their variants using nested mutations
    gql`
      createFamily(
        name: "${familyName}",
        template: "${familyTemplate}",
        ownerId: "${user.id}"
        variants: [
          ${
            variantProperties
              .map(properties => `{ ${properties} }`)
              .join(',')
          }
        ]
      ) {
        id
      }
    `
    
  6. Update families and variants if they have been modified

When everything is done, you concatenate all the mutations and send them in one row to the server and keep going through the users. I won’t mention how I did transfer the profile infos and preferences as it is pretty much the same thing but easier.

And that, kids, is how I transfered 40 000 users from one place to another!

  • Anime
  • Non-TV program

Nichijō - 日常

Nichijo Cover

Hey, it’s been a while! Today, I want to talk about anime again. Besides the fact that I finally watched Attack on Titans (and you should), I heard about Nichijō. It appeared to me like a reference or something, so I jumped into it. And what a weird encountering it had been.

The plot… I guess there is no plot. You just take a bunch of people, mainly high school girls and somewhat connected to each other, and watch them live. The episodes are composed with many short scenes that are independents but sometimes references are made to the past. And that’s pretty much anything I can say about it.

If you happen to love absurd scenes like I do, I advise you to watch it right now, you won’t be disappointed. And just for you, here’s a glimpse at my favorite scenes (don’t worry, you can’t really be spoiled).

Note
I think 通 (tooru) means transparent, that’s why she overreacted when hearing the word. But I have no clue for the small/short dilemma.

As a bonus, she gets back there to trick her friend a few episodes later.

And a last very funny one:

If you want more, you could check out the mosquitoes scene, or simply watch everything. ;)

  • Music

5 French Pop / Punk bands you might wanna know about

I don’t really know how is seen the French music scene abroad and some people might want to discover some interesting local bands. As I am (really really) into punk related music, this is the only thing that I’ll share with you now but there’s plenty things to discover everywhere!

Guerilla Poubelle

Punk from Paris. Started in 2003.
That band likes to criticize the living society, that’s why I considered them pure punk (that and the loud guitar and rough voice). They sing mostly in French but it happened they released songs in English. I think this is one of the best French punk reference (they toured all around the world).
They’re part of the Guerilla Asso, which gathers lots of punk artists (even from abroad).

Les 3 Fromages

Funny pop punk from Quiberon, Brittany. Started in 2006.
Originated from Brittany where I come from too, these guys are cool! Litterally “The 3 cheese” (referencing a pizza name in case you didn’t understand :P), they do funny (and sometimes dirty) pop punk rock inspired by Green Day, Offspring and Blink-182. Their most known song is a pray for a cheese-based French dish called “Tartiflette”.

Maladroit

Punk from Paris.
This band is one of the many projects Guerilla Poubelle’s member can have (you can easily recognize one of the singer’s voice). Completely pop punk, their lyrics are funny and the songs catchy. I like them for that and the crazy movie clips!

Sons Of O’Flaherty

Celtic punk from Vannes.
With one of Les 3 Fromages’s member (yeah I know, they all play in each other’s band), this band makes interesting music as they use traditional instruments like tin whistle or even bagpipes. Inspired by bands like Dropkick Murphys or The Pogues, they mix Breton music, folk songs and irish classics.

Poésie Zéro

Punk from outer space.
I wanted to put this band because they have a really funny weird way to do their communication. They’re always pissed off about everything and shout at the public that they’re idiots. Sometimes you think they’re trying to educate you about society, but sometimes they’re just yelling at you. This still makes me laugh.

And you might want to check out also:

Setting up a React Native & Web project

REST API made easy with Apex, AWS Lambda and AWS API Gateway

The Renewal

Inserting React components inside your Jekyll markdown posts

Thoughts about relationship deletion in Redux with Normalizr

Forms without refs in React stateless components

Echofon for Firefox : The renewal

Pretty printing all JSON output in Silex PHP

Symfony2 : Protéger ses entités avec les voters

Global Game Jam 2015 - Que ferait MacGyver ?

SuperTurkey - Thanksgiving

Ménage de prin... automne

Informations ISEN CIR3 - L'alternance en Cycle Informatique & Réseaux

Angel Beats! - エンジェルビーツ!

The Internet's Own Boy : The Story of Aaron Swartz

Glass Camp Bank à Brest

Brezeliad - Première séquence gameplay

Le Trailer de Brezeliad ou Le Parcours du Combattant

Une patate volante sur Twitter

Stunfest J-27 - L'aventure continue

L'offre légale chez EA

Stunfest - J-100

Marty - Back To The Future

Steins;Gate - シュタインズ ゲート

Enfin un nom de domaine !

OnHack Reborn !

Une deuxième année bien chargée

Raspberry Pi - Un ordinateur low-cost au goût de framboise

Echofon for Firefox (Twitterfox) is not dead (et espérons qu'elle le restera)

Groar ou l'art de ne jamais finir ses projets

Extensions Gnome-Shell - Requêtes HTTP avec libsoup

Gérer les changements de maps avec MelonJS

Les Mystères de Rennes

Global Game Jam 2013 - Retour d'expérience

Les Enfants Loups, Ame et Yuki - おおかみこどもの雨と雪

Puella Magi Madoka Magica - 魔法少女まどか☆マギカ

Accel World - アクセル・ワールド

Saleté de système de traduction !

Et encore un blog !