Tag Archives: workspace

Cleaner Code With Functional Programming

I’m a Technical Team Leader at Université catholique de Louvain and one of my responsibilities is to analyse pull requests sent by my team mates and all other contributors of OSIS project. Each pull request is analysed according to some acceptance criteria, which determine if the pull request is accepted right away, accepted after completing requests for changes or refused. This process was taking too long because of excessive requests for changes, revealing too many problems to be fixed before the merges.

To gain some time on pull requests, I’ve decided to invest part of my time training the team to improve the general sense of maintainability, stability and reusability of the code. We’ve started with some pressure to change the established culture by following Robert C. Martin’s Clean Code video series. Uncle Bob, as he’s well known, seems to have radical ideas, but he is quite good at convincing us that he is not that radical at all. This initiative has been very valuable and the quality of recent pull requests has increased substantially.

Training sessions are now a weekly commitment. Nowadays, I’m reinforcing what we have learned during the clean code training, but more focused on the technologies we use. Recently, I’ve brought an interesting problem to be solved in Python using Test-Driven Development (TDD):

Given a list of programmers and the maximum number of team members, let’s write an algorithm to randomly distribute programmers into teams. The maximum number of members is greater than 1. The minimum number of members is implicitly equal to 2. The list of programmers should contain at least two elements. A programmer can be member of only one team or no team at all but never member of 2 or more teams. The return should be a list of lists where the lists represent the teams.

We started writing a failing test and then just enough code to pass it. In this loop we ended up writing 7 tests to check the algorithm. Here is what we’ve got:

import random
import unittest

class TeamBuildingTest(unittest.TestCase):
  def test_list_contains_programmers(self):
    programmers = []
    teams = build_teams(programmers, 2)
    self.assertFalse(teams)

  def test_list_with_a_single_programmer(self):
    programmers = ['John']
    teams = build_teams(programmers, 2)
    self.assertFalse(teams)

  def test_minimal_team_size(self):
    programmers = ['John', 'Mary']
    teams = build_teams(programmers, 1)
    self.assertEqual(len(teams), 1)
    teams = build_teams(programmers, 0)
    self.assertEqual(len(teams), 1)

  def test_multiple_teams(self):
    programmers = ['John', 'Mary', 'Carl', 'Smith']
    teams = build_teams(programmers, 2)
    self.assertEqual(len(teams), 2)

  def test_odd_size_of_programmers_teams(self):
    programmers = ['John', 'Mary', 'Carl', 'Smith', 'Luc', 
                   'Paul', 'Ringo']
    teams = build_teams(programmers, 3)
    self.assertEqual(len(teams), 2)

  def test_minimal_and_maximal_team_size(self):
    programmers = ['John', 'Mary', 'Carl', 'Smith', 'Luc', 
                   'Paul', 'Ringo', 'Adam']
    teams = build_teams(programmers, 3)
    self.assertEqual(len(teams), 3)
    self.assertEqual(len(teams[0]), 3)
    self.assertEqual(len(teams[1]), 3)
    self.assertEqual(len(teams[2]), 2)

  def test_random_teams(self):
    programmers = ['John', 'Mary', 'Carl', 'Smith', 'Luc', 
                   'Paul']
    first_round = build_teams(programmers, 2)
    second_round = build_teams(programmers, 2)
    self.assertNotEqual(first_round, second_round)

We arrived together to the following solution:

def build_teams(programmers, size):
  if not programmers or len(programmers) < 2:
    return []
  else:
    return partition_teams(shuffle_programmers(programmers),
                           size if size > 1 else 2)

def shuffle_programmers(programmers):
  shuffled_programmers = list(programmers)
  random.shuffle(shuffled_programmers)
  return shuffled_programmers

def partition_teams(programmers, size=2):
  teams = []
  team = []

  for i, programmer in enumerate(programmers):
    if i == 0 or i % size != 0:
      team.append(programmer)
    else:
      teams.append(team)
      team = []
      team.append(programmer)
  if len(team) > 1:
    teams.append(team)
  return teams

To run all of it yourself, just put all the code in a file named “team_building.py” and run the tests using the following command in the same folder of the file:

$ python3 -m unittest -f 'team_building.py'

When we were done with the code we realised we didn’t do a good job in the function partition_teams(). It was written in the imperative style, with more variables and less meaningful controls. It’s difficult to extract another function from it without breaking other programming rules. However, with a 100% test coverage, we could rethink the problem and refactor the code without breaking the algorithm. Look at what we’ve got:

def partition_teams(progs, s):
  return [progs[x:y] for x in range(0, len(progs), s)
                     for y in range(s, len(progs) + s, s)
                     if x < y and y - x == s and 
                        len(progs[x:y]) > 1]

The new partition_teams() function uses list comprehension, a functional programming concept implemented in Python and many other languages nowadays. We’ve initially thought about nesting maps, filters and reduces, but it seemed to be heading towards complexity. List comprehension was proposed to address exactly the nested cases of higher order list operations, making the code more expressive.

The point about this list comprehension is to manipulate list slicing intervals to get what we want from the list of programmers. Given a list of 9 programmers from which we expect to extract pair programming teams, the first for produces the sequence 0, 2, 4, 6, and 8 and the second for produces the sequence 2, 4, 6, 8, and 10. When they execute we have a y for each x, producing the combinations (0, 2), (0, 4), (0, 6), (0, 8) … (4, 2), (4, 4), (4, 6) … (8, 6), (8, 8), (8, 10). Considering the rules of slicing, combinations like (4, 2) and (8, 8) won’t help us to solve the problem. So we exclude them with the conditions (x < y) and (y - x == s). It partitions the programmers properly, but it isn't immune to teams of 1 person. Since this kind of team doesn't exist, we include the condition (len(progs[x:y]) > 1) to take them out.

Notice that it has more semantics than the imperative solution because we get a dataset and we keep working with datasets in mind, while the imperative solution is more value-oriented and requires more control. Functional programming fascinates me and I'm glad to work with such a powerful language.

Installing Intellij IDEA on Mac and Ubuntu

It has been a year since I moved my professional and community development projects from Netbeans to IntelliJ IDEA. Netbeans is still a great IDE and I recommend it over any other open source alternative, but the productivity brought by IntelliJ is so great that the time I’ve saved using this IDE already paid off.

I have IntelliJ installed at home and at the office. It’s the same license but the deal is: you can install it in several computers but use one installation at a time. I use Mac and Ubuntu at home and my experience installing IntelliJ in those platforms was the following:

Installing on Mac

I’m not really going into step by step here. IntelliJ is pretty easy to install on Mac, but I had a problem with the JDK and I’m going to focus on that now. IntelliJ uses the JDK distributed by Apple by default, which is a JDK 6 implementation. Well, this is not a big deal, since we can install the most recent JDK and configure our projects in the IDE to use it instead. But, for some unexplained reason, I couldn’t configure the IDE to start the application server in a JDK different from the one used by IntelliJ (JDK 6). In the image below, you can see I’ve configured JDK 8 to run WildFly, which requires JDK 7 or superior, but it didn’t work.

wildfly-configuration

So, I had to change the JDK used by the IDE. For that, I:

  1. closed IntelliJ;
  2. went to the folder where all applications are installed (/Applications) and selected the file “IntelliJ IDEA ##.app”;
  3. accessed the context menu (mouse click with two fingers) and selected “Show Package Contents”;
  4. opened the file “/Contents/Info.plist” and
  5. located the JVMVersion to change its correspondent value to 1.8*.

After this configuration, I could finally make IntelliJ run Wildfly.

Installing on Ubuntu

The installation on Linux is traditionally more complicated. I wonder why people complain about the low number of Linux desktop users. 🙂 The IntelliJ IDEA download page mentions only two steps:

  1. unpack the “ideaIU-XX.Y.Z.tar.gz” file using the command “tar xfz ideaIU-XX.Y.Z.tar.gz” and
  2. run “idea.sh” from the bin subdirectory.

However, this instructions don’t deliver IntelliJ as delivered in other platforms. People don’t go to the installation folder and execute the file idea.sh. They either create a desktop icon or add the bin directory to the path, but these steps are missing. So, in my understanding, the installation is not completed. To launch IntelliJ from anywhere in the command prompt:

Become the root user:

sudo -i

Move the unpacked folder to “/opt/idea”:

mv ideaIC-XX.Y.Z /opt/idea

Edit the file .bashrc:

gedit ~/.bashrc

Add the following line to the end of the file:

export PATH=/opt/idea/bin:$PATH

Log out and log in to the change take effect.

To add the launcher icon on the desktop, there is a soft and a hard way.

The Soft Way

Fortunately, IntelliJ can help you once you run it for the first time. In the welcome window, select “Configure”:

intellij-configure

And then select “Create Desktop Entry”.

intellij-configure-desktop-entry

That’s it!

The Hard Way

As a good Linux user, you may prefer doing it the hard way, as follows:

Create a desktop file:

cd /opt/idea
gedit idea.desktop    

Copy the content bellow to the file:

      [Desktop Entry]
      Name=IntelliJ IDEA 
      Type=Application
      Exec=idea.sh
      Terminal=false
      Icon=idea
      Comment=Integrated Development Environment
      NoDisplay=false
      Categories=Development;IDE;
      Name[en]=IntelliJ IDEA

Install the desktop file:

desktop-file-install idea.desktop

Create a symlink:

cd /usr/local/bin
ln -s /opt/idea/bin/idea.sh /usr/local/bin/idea.sh

Finally, display the idea icon in dash:

cp /opt/idea/bin/idea.png /usr/share/pixmaps/idea.png

At this point, you will finally feel IntelliJ as an application, integrated with the desktop and always ready to be executed.

Development Environment to Work with WebLogic

I have to confess that, despite not evolving as fast as the Java EE specification, Oracle WebLogic is a f*** good application server. Its stability is impressive and works smoothly with popular IDEs, such as Eclipse and Netbeans. Of course its qualities come with a cost, which is expensive for poor developers like us, but it’s worthwhile for companies.

The official name of WebLogic is “Oracle WebLogic Server 11g Standard Edition”. It is part of a broader range of products called “Oracle Fusion Middleware”, which offers a complete support for enterprise service-oriented applications (SOA). I’m currently working with WebLogic 10.3.4, which is the first version that supports JSF 2.0, my favority web framework. WebLogic is available for download on Oracle’s website. Go to the download page to get your copy. To install it:

  1. Unzip the file in your development folder. For example /home/you/java/weblogic.
  2. Create the environment variable JAVA_HOME, pointing to your JDK installation.
  3. Create the environment variable MW_HOME pointing to /home/you/java/weblogic.
  4. Go to the command line and run the installation configuration script $MW_HOME/configure.[sh/cmd].
  5. Create the domain to start working with WebLogic, running the command MW_HOME/wlserver/common/bin/config.[sh/cmd] and following the instructions on the screen.
  6. Start a web browser and open the url http://localhost:7001/console to access the administration console.

Now, we have to configure the IDE to start, debug, and stop WebLogic, as well as deploy Java EE applications. Because most developers actually use Eclipse as a working IDE, let’s configure it, installing the necessary plugin. I’m using Oracle Enterprise Pack for Eclipse (OEPE), a plugin that empowers Eclipse to develop Enterprise Java Application for Oracle Products. To install it:

  1. Open Eclipse and go to the menu Help – Install New Software…
  2. Add a new repository by clicking on Add…
  3. Inform the name Oracle Enterprise Pack for Eclipse and the URL http://download.oracle.com/otn_software/oepe/indigo if you are using Eclipse Indigo, or http://download.oracle.com/otn_software/oepe/helios if you are still using Eclipse Helios.
  4. Follow the instructions and restart Eclipse to finalize.

 Finally, configure the plugin to integrate the IDE with Eclipse:

  1. Go to the menu Windows – Show View and select Servers.
  2. Click with the right button of the mouse on the working area of the view and select New – Server.
  3. In the list of server types, go to the category Oracle and select Oracle WebLogic Server 11gR1 (10.3.4), or the version of WebLogic that you have installed. It’s important to select the right version, otherwise an error will continously occur.
  4. Make sure that the field Server’s host name contains the value localhost and press Next.
  5. In the field WebLogic home inform the path /home/you/java/weblogic/wlserver.
  6. In the field Java home inform the path to your JDK installation.
  7. You can optionally install some server extensions. I recommend to install all available extensions, clicking on Install, besides each item. Press Next to continue.
  8. Leave the option Local selected in the Server type field and inform the location of the domain. The domain was created in the first part of this tutorial, when we executed the configuration assistent. 
  9. Press Finish to conclude.

That’s it! Make sure to select this server when creating a new Java EE application. Don’t hesitate to share your experience while following this tutorial.

Creative Solution to Keep Business Running Under Special Circumstances

Rue du Luxembourg, Brussels, around 7:20 in the morning, going to work. A drugstore was under complete renovation. It wouldn’t be open for customers… unless they put the drugstore in a special container and place it on the sidewalk just in front of it 🙂

If you are planning to renew your business, take some time to think about a creative solution to keep it running.

My Last Day in The Lab

In November 15th this year, Matt Welsh, a young and successful tenured professor at Harvard, decided to leave his prestigious academic position to work full time for the industry. He is now a Google employee and he claims that he has more freedom and computational power than ever to make real and substantial contributions for the computer world.

I fully understand Matt, besides not having his prestigious position neither his brilliant mind. We both love our respective universities, keeping a profound admiration for what they represent for the society. However, we both also agree that sometimes our way of thinking and acting don’t fit the way the traditional research world is moved. We love freedom of thinking with a minimal influence of external factors, but we also get upset when things happen too slow because we have a lot of formalities to deal with before having our work appropriately recognized.

Normal working day at the lab registered by Koen Cobbaert

After all, my experience of doing PhD at UCL was amazing and I do recommend it for those who ask me for an advice about the academic world. In this world I’ve learned how to solve really tough problems and to practice my favorite sports: writing and coding. It was a journey of 4 years extracting the maximum of creativity, patience and emotional control. When I finished, I had a feeling that everything else is easier and I lost the fear of facing new challenges. In summary, life gets more exciting.

After this remarkable academic period, I feel the need of changing in my heart. As my adviser said once:

“we are fundamentally educators and in order to spread knowledge people should come and go elsewhere to make useful things with their privileged knowledge”.

I do agree with his statement and that’s one of the reasons I’m leaving the lab today. Because I believe it’s time to leave my sit available for another brave student who is looking for this wonderful life experience. And I should follow my path, doing what I love to do, which is work as a Java Architect in the corporate world.