torstai 15. syyskuuta 2016

Imagine Brains

I needed an image of brains to show the status of the learning memorisation. I found one image which was almost exactly what I was looking for. Shiny brain image which would show words like brighting stars. I share the image here for reference from sciencefacts.com.

Here is what I did to create a similar base image. First blueish gradient bacground for the picture.

Then I added sideview of face [side face from nippo-ent.com].
I removed the ear and inverted the image.
Hue changes.
The background gradient needs some other blue.
And then brains.
Inverted and decreased alpha value.
Finalize with some color and brightness settings.

By the way when I was looking for the image photos I noticed that almost every of them were shiny blue. Does blue brain images make them look more scientific or what is the purpose of use of blue?

maanantai 12. syyskuuta 2016

Implementing login system

In the design there is a login screen with three options: facebook, twitter or email login. The purpose of each is just to get some kind of identifier to keep the users separated. Also I try to prevent misuse of other's account. In Finland there is a law for identity registry. I try to avoid making a one. Well, to be honest it's not really a problem since there needs to be one author for registry and the purpose of the registry needs to available.

Facebook login

Facebook was the easiest to work with. You copy-paste a code snippet from facebook's dev page and call for login. A separate window opens and you authorise the application to see your public profile. There is a callback, which I used localhost:8001/ , and it worked out of the box. With the confidentiality from the small task I got forward with twitter login.

Twitter login

Twitter login was its own beast. It was based on OAuth, well someone said Facebook is also using that but you didn't need to worry about internals. In every place there was a warning note that you should not implement client side authorisation. That's what I was to do in any case. Like it or not. The problem being that I needed to expose the application keys to all in public (javascript file). To fix this I set the application to read only mode. It can read the public profile of twitter, exactly what I need.

The biggest problem with twitter was javascript libraries. There was only few and many of them was designed to work with nodejs. Although, I like javascript I am not yet found love with nodejs. Finally I found Codebird library. The implementation looked nice (read, it had a nice tutorial with examples) and it seemed to do what I was looking for. The problem with twitter application settings was that it was not able to work with localhost. I edited my /etc/hosts to include alias for localhost called www.localhost.com. This worked like a charm but it took quite a lot of time to understand what key was used where. Twitter developer documentation was not really helping. When I finally got it to work it all seemed easy but before that it was horrible way of errors.

function CB() {
  var cb = new Codebird;
  cb.setConsumerKey("KEY", "SECRET");
  return cb;
}

// This will be called when button is clicked.
function twLogin() {

  var cb = CB();

  // gets a request token
  cb.__call(
    "oauth_requestToken",
    // This was the most confusing parameter since OAuth allows Out-of-band authentication too. 
    // In this case user would have to insert a PIN code found from verify page. UX--
    {}, //{oauth_callback: "oob"},   
    function (reply) {
      // stores it
      cb.setToken(reply.oauth_token, reply.oauth_token_secret);
      localStorage.setItem('token', reply.oauth_token);
      localStorage.setItem('token_secret', reply.oauth_token_secret);
      
      // gets the authorize screen URL
      cb.__call(
        "oauth_authorize",
        {},
        function (auth_url) {
          window.open(auth_url);
        }
      );
    }
  );  
}

// The callback function calls this page again with query parameter "oauth_verifier".
// With verifier we can finish the authorization.
(function(){
  var query       = location.search.substr(1).split("&");
  var parameters  = {};
  var parameter;
  
  for (var i = 0; i < query.length; i++) {
    parameter = query[i].split("=");
    if (parameter.length === 1) {
      parameter[1] = "";
    }
    parameters[decodeURIComponent(parameter[0])] = decodeURIComponent(parameter[1]);
  }
  
  // check if oauth_verifier is set by callback function
  if (typeof parameters.oauth_verifier !== "undefined"  && localStorage.getItem('token')) {
    var cb = CB();

    cb.setToken(localStorage.getItem('token'), localStorage.getItem('token_secret'));

    cb.__call(
      "oauth_accessToken",
      {
        oauth_verifier: parameters.oauth_verifier
      },
      function (reply) {
        if (reply.httpstatus == 200) {
          // reply.screen_name is twitter username
        }
      }
    );    
  }
    
})();

Domain name

I started to think if there would be free domain names. Luckily internet offers everything. freenom.com has free domain names for .tk, .ml, .ga and .cf. I guess there are also other name providers but I registered stoningrosetta.cf from freenom. Keep costs low you know. And name just feels really good. I can fully understand why it is very important to remember people names, it feels good when someone recognises you. And now my project can be recognised, yeah.

Email login

2/3 was implemented. Now things got more harder, how to do email login? My idea was following: user sends email to server which would send a special login link to user's email (hash of email + salt). I started to look AWS services how to implement the email sending. Simple Email Service provides API to send messages. The API, however, was not the easiest to understand at all. There was some kind of signature routine but luckily there was a project implementing a library for AWS in erlang already, https://github.com/lookio/eaws. There was small issue, however. Host of the API service was hard coded so I created a fork and fixed the host to be dynamic. That's it.

The erlang code looks something like this. I still don't know if the connect is needed but without it nothing is sent. So there is some kind of erlang internal server or something. I don't yet fully understand erlang concepts.

  eaws_client:connect(),
  eaws_client:send_formatted_email([
    {to_addresses, [binary_to_list(Email)]},
    {from_address, "noreply@stoningrosetta.cf"},
    {subject, "Stoning Rosetta"},
    {text_body, "Here is a login link for your game: " ++ binary_to_list(Uniq) },
    {html_body, ""}
  ]),

As you can see the from address is noreply at stoninrosetta.cf. So how this should work? SES (Simple Email Service) can only send emails from verified users or domains. How to verify the domain for AWS? SES has it's own way to work. First you need to make AWS as your email server with MX record in your domain config. Then you need to add verification code with TXT record. The final configuration can be seen in below. The freenom had issue with normal AWS verification process since the record name cannot have underscore for the needed _amazonses. The other method used amazonses: prefix in value which worked fine.

In couple of hours I got following email from AWS:

   Amazon Web Services 

   Congratulations! The Amazon SES verification process for the domain stoningrosetta.cf in 
   region EU (Ireland) is now complete. You are now able to send email through Amazon SES 
   from any address within this domain. For more information, please refer to the Amazon SES Developer Guide.

   Thank you for using Amazon SES.

And after that I received my first test emails flawlessly.

sunnuntai 11. syyskuuta 2016

Project Stoning Rosetta

If you want to eat an elephant you should do it one spoon at time. I am not elephant eater but it remains me how much work it is to accomplish a project. I try to focus on small project one at time, or, there is no way I will finish anything. By learning with small projects I can re-use my knowledge on bigger projects.

Ta-da-aa!

My next project is Stoning Rosetta. It is a small game to learn languages. It's purpose is to upkeep word dictionary in your memory and learn conversations like how to say hi, what to do in restaurants and so on. It's not intended as a primary study tool but something that goes along with your normal learning routines.

The game name is of course a similar to Rosetta Stone, a rock containing same text in three languages and which was the key to the modern understanding of Egyptian hieroglyphs. Quite cool, ha?

[Rosetta stone by Hans Hillewaert, used with CC BY-SA 4.0]

Design factors

As I have already told the point of the game is to learn languages. Well, kinda it's not a game at all but it's not normal app either. One of the early design influences was Texas Instruments' Little Professor

My dad who was a mathematic teacher in high school bought one of these and I recall to play with it. Image used without permission.

Thus one of the design factors was to have a professor which glorifies your success in the game. And, since the plan is to make money as well the professor shows advertisements if you fail too many times. You will be punished by ads!

The gameplay mode was designed to be so simple that you could play it while waiting in coffee line. Many other language games need the player to input text but this game player needs only clicks. Player selects one from four different variations. In principle while in one task player can guess with 25% success rate, to pass by guessing without failures the probability is low 0.25^n where n is task count. Thus with 5 word game the probability to guess without failures is only 0.000977%.

Second important design factor is word context. It makes no use to learn words that have low connectivity in real life. One session in game should focus on words that form interesting context together. If player is not very interested in to learn, say car parts, she should be able to skip the session (excuse my sexist language).

Third design factor is cognitive. Our ability to recall words and phrases lowers by time. It is important to remind our memory about the words. Thus, the game is designed to be played over days and months. Player will repeat the old material but only when it starts to "rotten" in memory. Thus, it uses cognitive model of forgetting to keep player remembering words.

Last but not least, I have connections to maintain the content to contain different languages: Finish, English, Spanish, Italian. Like in Rosetta Stone, the idea is to write same content in different languages.

Sketch of new user flow

New users need to select the mother language or base language, the language they want to learn and professor. I created some very minimalistic designs for the user flow.

The user needs to login into the system, or actually not, we need something that we can use to identify the player. I like not to even gather the user information since then it cannot be stolen by hacks.

Sketch of game flow

Once the user has logged in to the system the game is ready. There are two screens: brain screen and game screen. When game is ongoing there is time pressure for player but once one level has passed the brain screen mostly waits in shows status of the learning progress. The idea with the brain is that once you learn some context, e.g. colors, the word flows around the brain and shines. Once the time passes the word shines less and less until it drops to selection area to be selected and re-played. Selection area contains four items at time and there can be new or re-remember items. Professor in the view gives you some statistics.

The game screen is really easy. At the top of the screen there is a item to match and you need to match it with the four options flowing from right to left.

Please note!

At the time of writing the game is not yet finished. I will update this text to remove this note when finished!

keskiviikko 7. syyskuuta 2016

Growing up

I have many ideas for different kinds of web services but unfortunately I don't have time to do them all. I try to focus to finish one project at time. It should be the manageable count that man can stand. I have been a professional programmer/designer guy for a decade already and I have been working in couple of companies.

I would like to implement things for two reasons: one is general good and second for money. The current project is for general good but with attitude to learn things. This time I want to learn several new things: AWS Elastic Beanstalk, Docker, Erlang web and AWS Dynamo for back end. Probably also some AWS Lambda / serverless things. In the end the idea is to build a service model that runs in the cloud without me worrying much of it later.

AWS

SC5, a local company here in Jyväskylä, arranged a hackathon with serverless topic. I joined the session and I understood something cool. I don't need any server instance since there are just cpu units in the cloud. Next thing was to start using those items. AWS Lambda (or serverless) was not usable as it is for web page. Amazon provided this elastic beanstalk instead. So, why not? You could use elastic beanstalk more easily with predefined set of languages but in the end I chosen to run Docker image inside the system.

Erlang within Docker

Docker was selected because of it will be used in our company more heavily and I wanted to run and learn Erlang. I don't have currently any comments about Docker. It could be faster but otherwise it is okay. I selected Erlang because it is small and efficient. I run into N2O project some time ago after I was looking for web framework for Erlang. In the front page of N2O it has following image which I like a lot. I am speed-o-holic regarding to software systems. For me a slow system means pretty much same as non-working system. Currenty I work with rails and that is awfully slow in many ways. Legacy is legacy. To tell more about N2O, I have still worked out without N2O technology. The idea within N2O is to serve (almost) whole web page through websocket. Every action you do on the page inits server requests and the page is changed accordingly the business logics in server side. Interesting technology but currently I am looking something else to learn.

Let's see how this goes.