Linke

Linke

My brother asked me to come up with some pictures to show her girlfriend the many beautiful places of this world.

Being the dedicated overachiever I am, in return I handed over a website.

Where should Linke go? is a 3D ‘slideshow’ built on Hakim El’s reveal library. Of course it’s optimized to mobile and desktop, and of course I created a unique SoundCloud playlist to complement the experience.

Linke Cover
Linke Cover
Linke - Malta
Linke – Malta
Linke - Thailand
Linke – Thailand
Linke - Colorado
Linke – Colorado

Feast your eyes on more beautiful pictures from all over the world on Where should Linke go? and let me know if there is another country you’d like to see in there.

When you realize

That more people attended the Argentina – Bosnia game (74, 738) than the opening Brazil – Croatia game (62, 103) at the 2014 World Cup in Brazil

 Conclusion: Argentina is gooooooooooooood.

The Good, the Bad and the Ugly – part 2

A little while ago I did a roundup on two LMS out there – Opigno (‘The Good’) featured the article on their site as well.

Since that post we’ve been continuously testing Opigno, and I still couldn’t manage to install Moodle (‘The Bad’). However, I haven’t said a word on ‘The Ugly.’ Therefore, ladies and gentlemen, this is the time that I finish the article, and speak up about edX.

For those who are not familiar with edX – another platform in the arena, ‘cept for that this one actually puts the platform in good use as well. You can go to edx.org and start participating in free online classes. I do, too, this is what my dash looked like in June, 2014:

edx_dash

 

EdX was founded by MIT and Harvard, and was open sourced in June, 2013. The code can be found on GitHub, forks come from all over the world, including Stanford and Google. You, too, can download the code, but I’m warning you – you’re in for a difficult time.

For the purpose of getting the production stack first I tried with a Virtual Machine (edX feels most comfortable on Ubuntu), but the box was killing my memory and eventually I just snatched up an idle laptop, and put a fresh copy of Ubuntu 12.04 on it. There are decent instructions on GitHub to setup the environment and install the software, and yet it took me two weeks to get this thing to work.

I wish I could explain you what happened in that two weeks. Install ruby, install this, install that, start the edX installation process, run into an error, try again, fail better. I have never seen such a complicated installation before. Constant errors, luckily google was my friend every time, and someone had a solution to any of the errors I encountered.

Also, here is one more thing I didn’t realize, and it’s kind of silly. Hopefully you’ll read this article and not make the same mistake.

Once the installation process ended without errors, with other words: it was done, I somehow didn’t realize that we were done. I thought I have to rehash, or rake something, or run some additional commands. Wrong. Once the production stack’s playbook ran, and you get the green light, you can hit http://localhost:80 immediately and check out your new edX site. No additional steps required. EdX does come out of the box, it just takes a lot of patience to unbox it. A LOT of patience. Don’t give up.

So there you go.

Conclusion: You, too, can install edX, but the process will most likely do magic to your blood pressure.

The Good, the Bad and the Ugly

We’re looking into Learning Management Systems (LMS) and having some experience on the matter (see my co-founding venture, GradFly) I happily volunteered for the task.

Based on what I’ve seen so far, here are the best candidates:

  • Opigno. Opigno is a Drupal-based open source solution. Their business model is the usual, you can have the open source platform and go on your merry way, or you can have it hosted and tended to for some charges. So far I could not seen any small print within that business model, truly, if you download the open source version, that is yours. The code is released under GPLv2, which means you can make as much money selling it as you want. Basically, the question is – do you want it to be hosted as a service, or do you want to do the heavy lifting yourself?Opigno UI
    Opigno’s UI looks absolutely sweet. Their website is Foundation for sure, indicating that the people developing Opigno have a strong sense of beauty. Opigno, by deafult, does not ship with Foundation, but fear not: there is a Drupal Foundation module for that. The Opigno distribution contains the Drupal core, so it’s enough to download and setup Opigno, no need to get the separate Drupal core beforehand. The installation will take 2 minutes if you have XAMPP, 30 minutes if you need to install XAMPP as well, and 2 hours if you need to install Opigno, XAMPP, and have to assign new ports for the bundle. Really, aside from my personal port-struggles (Pentaho runs on Tomcat as well, so now there are two tomcat instances on my sandbox) the installation process was a delight. Opigno is a beauty.
  • Moodle. Oh my God, I don’t want to talk about it. Actually the reason I decided to write up this article was Moodle. I’ve been struggling with the installation for 2 hours now, and I needed to take a break.
    Moodle is a well-known player in the arena, my alma mater uses it, too. It is also based on XAMPP, so it shouldn’t be a problem to install, right? I don’t know, my friend. This Moodle is a bad, bad news. I exploded the package in the right directory, created a database, assigned the permissions and modified the config.php file. Two clicks into installation and Moodle throws the first error:

    DDL SQL EXECUTION ERROR
    Debug info: Can’t sync file ‘.\moodle\mdl_user_private_key.frm’ to disk (Errcode: 22 – Invalid argument)
    CREATE TABLE mdl_user_private_key (
    id BIGINT(10) NOT NULL auto_increment,
    script VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ”,
    value VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ”,
    userid BIGINT(10) NOT NULL,
    instance BIGINT(10),
    iprestriction VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    validuntil BIGINT(10),
    timecreated BIGINT(10),
    CONSTRAINT PRIMARY KEY (id)
    ) ENGINE = InnoDB DEFAULT CHARACTER SET utf8 DEFAULT COLLATE = utf8_unicode_ci
    Error code: ddlexecuteerror
    Stack trace:

    • line 449 of \lib\dml\moodle_database.php: ddl_change_structure_exception thrown
    • line 833 of \lib\dml\mysqli_native_moodle_database.php: call to moodle_database->query_end()
    • line 88 of \lib\ddl\database_manager.php: call to mysqli_native_moodle_database->change_database_structure()
    • line 77 of \lib\ddl\database_manager.php: call to database_manager->execute_sql()
    • line 417 of \lib\ddl\database_manager.php: call to database_manager->execute_sql_arr()
    • line 369 of \lib\ddl\database_manager.php: call to database_manager->install_from_xmldb_structure()
    • line 1486 of \lib\upgradelib.php: call to database_manager->install_from_xmldb_file()
    • line 237 of \admin\index.php: call to install_core()

    Disgusting. I check the database – there are 109 new tables sitting there. So it’s not a permissions issue. I drop and recreate the database, restart the install: another SQL error comes up.  Quick google, turns out the error happens quite a few times on Windows boxes. Congratulations. This is an entirely different experience, conmpared to yesterday’s Opigno.

I gotta go now, and finish this Moodle install. I’ll let you know if I find a solution to the DDL execution error.

UPDATE: I will be posting every attempt’s error message for your entertainment.

Debug info: MySQL server has gone away

I don’t know what this little prick is trying to do, but we’ve now reached the points where MySQL just quits. I do not wish to express my opinion on the matter.

16:34: Debug info: The table ‘mdl_course’ is full

I haven’t even created the course table yet.

16:38: Debug info: MySQL server has gone away

16:39: Debug info: Debug info: Table ‘mdl_config’ already exists

Haaaa, tricked you! Didn’t drop the database before this round.

16:44: Debug info: Can’t sync file ‘.\moodle\#sql-1230_bd.frm’ to disk (Errcode: 22 – Invalid argument)

That’s new…

16:49: Debug info: Can’t sync file ‘.\moodle\#sql-1230_bd.frm’ to disk (Errcode: 22 – Invalid argument)

17:00: Debug info: Debug info: The table ‘mood_course_log’ is full

17:02: Debug info: Debug info: The table ‘mood_course_completion_criteria’ is full

17:11: Debug info: Debug info: The table ‘mood_course_completion_criteria’ is full

See how consistent the error messages are? In the meantime all I do is change table prefixes, drop databases, and change permission parameters (switching back and forth between ‘everyone can execute here’ to ‘only I can execute here’).

17:18: Debug info: The table ‘mdl_course’ is full

17:25: Debug info: MySQL server has gone away

MySQL gave up. Excellent idea, I call it a day myself.

Conclusion: Drupal – sí, sí, Moodle – no, no. Drupal – sí, sí, Moodle – no, no.

UPDATE: Here is the second part of the story, where I describe ‘The Ugly’ of the trio.

Sounds like Ukraine needs some freedom

The Washington Post published an interesting visualization. They asked people two questions:

  1. Where is Ukraine on the map?
  2. What should the US do with this Ukraine-issue?

The answers to the first question are summarized in the following map.

16% of the respondents correctly placed Ukraine on the map, the median response was within 1800 mile radius.

In general, younger Americans tended to provide more accurate responses than their older counterparts: 27 percent of 18-24 year olds correctly identified Ukraine, compared with 14 percent of 65+ year-olds. Men tended to do better than women, with 20 percent of men correctly identifying Ukraine and 13 percent  of women. Interestingly, members of military households were no more likely to correctly locate Ukraine (16.1 percent  correct) than members of non-military households (16 percent  correct), but self-identified independents (29 percent  correct) outperformed both Democrats (14 percent  correct) and Republicans (15 percent  correct).

Here comes the fun part: the correlation between the first and the second question.

However, the further our respondents thought that Ukraine was from its actual location, the more they wanted the U.S. to intervene militarily.

I would like to ask: what are those 5 dots doing on US soil, 20 dots if you include Alaska as well? Same applies to Australia – I mean, come on, it’s kind of hard to miss where Australia is, so clearly that can’t be Ukraine. What about those dots in the ocean?

What about the million dots in Russia? If Ukraine were part of Russia, we wouldn’t be talking about this conflict right now.

Conclusion: Before you voice your opinion, make sure you have a good understanding of the circumstances, geographical locations included.

Change two axes in D3 Scatterplot

The original scatterplot that I used for my own purposes projected values on one axis. The ‘What makes us happy?’ visualization shows correlation between well-being and various socioeconomic aspects, but the y-axis (well-being) always remains the same.

However, when I wanted to show how BI vendors fared in Gartner’s 2013 and 2014 reports, I had to change the values on both scales. Much to my surprise there wasn’t a solution out there, so I thought I share my own version of changing both axes individually or simultaneously on the same chart.

1. Changing each dimension separately:

Obviously, you will create the appropriate placeholders and formatting:

<div id="menu"> <!-- the comments are D3 placeholders -->
   <!--<h2>&uarr; Y axis</h2>--> <ul id="y-axis-menu"></ul>
   <!--<h2>&rarr; X axis</h2>--> <ul id="x-axis-menu"></ul>
</div>

And define the axes separately in D3:

var xAxis = 'GDP', yAxis = 'Well-being';
var xAxisOptions = ["Well-being" , "GDP", "Equality", "Food consumption", "Alcohol consumption", "Energy consumption", "Family", "Working hours", "Work income", "Health spending", "Military spending"]
var yAxisOptions = ["Well-being", "Equality"];

On click, the axes will change separately, so you’ll have to click twice:

d3.select('#x-axis-menu')
    .selectAll('li')
    .data(xAxisOptions)
    .enter()
    .append('li')
    .text(function(d) {return d;})
    .classed('selected', function(d) {
      return d === xAxis;
    })
    .on('click', function(d) {
      xAxis = d;
      updateChart();
      updateMenus();
    });

Then just do the same for the y-axis.

d3.select('#y-axis-menu')
    .selectAll('li')
    .data(yAxisOptions)
    .enter()
    .append('li')
    .text(function(d) {return d;})
    .classed('selected', function(d) {
      return d === yAxis;
    })
    .on('click', function(d) {
      yAxis = d;
      updateChart();
      updateMenus();
    });

The axes labels are changed with each click, too:

  // Axis labels
  d3.select('svg g.chart')
    .append('text')
    .attr({'id': 'xLabel', 'x': 400, 'y': 670, 'text-anchor': 'middle'})
    .text(descriptions[xAxis]);

  d3.select('svg g.chart')
    .append('text')
    .attr('transform', 'translate(-60, 330)rotate(-90)')
    .attr({'id': 'yLabel', 'text-anchor': 'middle'})
    .text(descriptions[xAxis]);

The data for this exercise should look like this:

Country,  Well-being,  GDP,         Equality, ... etc. 
Austria,     5.37,     26171.6909,  70.85, ... etc. 
Belgium,     5.04,     24512.4131,  67.03, ... etc. 
Bulgaria,    4.59,     2332.3631,   69.416666, ... etc.

With other words, both axes are in the header row, and the values are below. Here is my working example.

2. Change both axes at the same time.
The DOM (and CSS) doens’t change, you can copy that from above.
The axes’ definition is somewhat different, since I’m plotting the Gartner report, not country data:

  var xAxis = '2013x', yAxis = '2013y';
  var xAxisOptions = ["2013" , "2014"]
  var descriptions = {
    "2013x" : "Vision in 2013",
    "2013y" : "Execution in 2013",
    "2014x" : "Vision in 2014",
    "2014y" : "Execution in 2014"
  };

The menu build has to be merged into one segment, since the same mouse click will change both axes:

  // Build menus
  d3.select('#x-axis-menu')
    .selectAll('li')
    .data(xAxisOptions)
    .enter()
    .append('li')
    .text(function(d) {return d;})
    .classed('selected', function(d) {
      return d === xAxis;
      return d === yAxis;
    })
    .on('click', function(d) {
      xAxis = d + "x";
      yAxis = d + "y";
      updateChart();
      updateMenus();
    });

To make sure this solution works, you have to label your data appropriately:

Company,    2013x,  2013y,   2014x,   2014y
Microsoft,   68,     81,      64,      69
Tableau,     52,     79,      63,      78
QlikTech,    58,     76,      63,      70

See? Because D3 is a little crippled on the matter of changing two axes simultaneously, you have to meet it half-way, and do half the work yourself with the labels. Here is the working example.

Conclusion: You can change axes in D3 all day long. Above are two examples for you.

How to remove login in standalone Saiku

Note: Standalone, as in not integrated in other platforms, solutions, apps, whatnot. If you integrate two apps, you will want to integrate their security as well, mmmkay?

The setting: Saiku is an awesome-looking, relatively fast OLAP analyzer. It’s shipped within Pentaho, but you can get it by itself, too. The logic is the same: set the Java path, fire up the server, and ahoi slices and dices!

The problem: In our internal CRM, the security is already taken care of, we no need additional Spring security. So I want the security be gone. Here is how.

1. The first step is well-explained on Saiku’s support page, it’s just kind of hidden in the middle of the comment flood.

This method works for me
step 1. change applicationContext-saiku-webapp.xml:

    <security:intercept-url pattern="/rest/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <security:intercept-url pattern="/json/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />

step 2. add property allowAnonymous in saiku-beans.xml

    <bean id="sessionService">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="allowAnonymous" value="true" />
    </bean>

2. The second step, to remove the window itself, is also in one of the threads, also rather straightforward:

just comment the last if in settings.js like this

//if (window.location.hostname && (window.location.hostname == “dev.analytical-labs.com” || window.location.hostname == “demo.analytical-labs.com” )) { Settings.USERNAME = “admin”; Settings.PASSWORD = “admin”; //}

Ta-dah! No more authorization issue. Then in two weeks you will discover the magic of user schemas and multi-tenant reporting and want to undo the whole process.

Conclusion: Now you know how to remove Saiku security.

Dilemma

I’m taking a Machine Learning course on Coursera. Turns out, it’s a rather old course, more than two years old.

First week, and we had to submit our Octave programming assignments. I basically had two choices: spend hours to come up with the solution myself, or google the solution in less, than 5 minutes.

If you get the job done, get the job done. Never in my career Google failed me before.

Conclusion: The answer for any of your questions is most likely written somewhere on the internet. Don’t waste more time than you need to get the job done.