Tuesday, October 7, 2014

Programmer's Diary: Setting Up a PPTP from CLI on Linux

From time to time I have to set up a PPTP connection to my office, and the KDE GUI fails. So here is a reminder to myself and anyone curious about how to connect to a PPTP VPN.

# pptpsetup --create syneto --server 82.78.203.62 --username csaba --password ******* --encrypt
# pon syneto
# ip route add 192.168.1.0/24 dev ppp0
# ip route add 10.0.0.0/24 dev ppp0

Add the DNS from the VPN network and a search domain.
# mcedit /etc/resolv.conf

# cat /etc/resolv.conf
nameserver 192.168.1.15
nameserver 8.8.8.8
nameserver 95.77.94.88
search dev.syneto.net

Have fun :)

Thursday, October 2, 2014

1st of 3 Books That Changed My Life: @unclebobmartin's Agile Principles, Patterns, and Practices in C#

I was thinking lately that from all the books I've read related to my professional life and career, there are three that stand out. I can not decide which one had a bigger impact because each effected a different part of my life. So there is not one better than the other. I will write three blog posts about each book. They will be presented in the chronological order I read them.

-------------------

I started reading Robert C. Martin's Agile Principles, Patterns, and Practices in C# about one year after I started working for Syneto. At that point, I had more than five years of programming experience and I was quite familiar with many concepts.

However, in almost all my career I worked alone. There was no chance to me to interact with other programmers, to find out about new and cool stuff from others directly. I've heard about Agile and Extreme Programming, but when you work alone you see things differently.

I could not find any satisfying online documentation back then, and there was nobody to recommend me the right books to read.

This lone programmer figure had to go under a major rework after I've got to Syneto. Suddenly I was surrounded by programmers with whom I had to collaborate. Fortunately for me, I worked with people for a long time, so the social side of the integration went well. And with social development came teachings and recommendations and a huge flood of information exchange. One of the books recommended both by colleagues and managers was Robert C. Martin's Agile Principles, Patterns, and Practices in C#.

This was not the first book I've read at Syneto. Not even the second one. It was just "the next book to read" on a long list after a year or so of intense personal and professional development. All the previous books were important and had a great impact, but none of them changed more the way I write code than this one.

Because Robert C. Martin's Agile Principles, Patterns, and Practices in C# had a profound impact on how I write code, I nominate this book one of the three life changers.

Before this book I was thinking about the structure of my code in a naive way. I had my personal experience, I heard about and knew a couple of design patterns, I even knew the basics of code structure and form.

So how this book changed the code that I commit to the version control system every day?

  1. My methods are less than 4 lines long. On average they are 2 lines long. Some methods are still huge and they may have 10-15 lines of code. But they are so rare, that they don't affect the statistics very much.
  2. My architecture is decoupled.
  3. My dependencies are inverted.
  4. My classes have a high cohesion. I once actually managed to create a class, together with +Vadim Comanescu, that we considered a perfect class: 6 public method and 6 private variables. All methods were using all private variables.
  5. I made naming things right one of my top priorities. Rarely can I write a method name that is not changed at least 3 times before the code is committed.
  6. I use design patterns in a much better informed fashion. The book helped me understand them better, and especially to understand possible use cases and scenarios.
  7. ... I could continue with other reasons. But I will stop now. I think these alone are enough. No need to write up another ten or so of them.
That is why I consider this book "The Programmer's Bible". Each software developer, regardless of the programming language or paradigm he or she uses, must read this book. It is quite long, about 600 pages, but it is not a difficult read. Robert C. Martin has a great talent to keep you hooked. I remember that some design patterns were so exciting stories that I just could not stop reading.

So, what are you waiting for, find a copy this extraordinary book and read it.


Sunday, September 28, 2014

Programmer's Diary: Constructing your Tests Line by Line

It is a different thought process for everyone, but when I write the tests that will represent the functionality I am about to implement, I always start with the Exercise or Act part.

A unit test is usually composed of three or four parts, thus the rule of 4As

1. Setup or Arrange
2. Exercise or Act
3. Verify or Assert
4. Tear down or Annihilate (this may be missing, automatic garbage collection, anyone?)

I observed that people who know about these parts have the natural tendency to start writing a test in that exact order. They start by asking themselves "What do I need?" and only then "What do I do?". This frequently leads to dilemmas that can not  be answered, and they just give up writing the test and start writing the production code.

In my opinion this type of thinking has a fundamental flaw. You cannot know what do you need before you first figure out what do you want to do. That is why I always start with 2. Exercise or Act. And my second step is always 3. Verify or Assert. This way I can put down the basis of the test by clearly defining what I want to do and what results I am expecting.

I build the 1. Setup or Arrange part as an iterative process by adding all the required dependencies for the already defined lines. Finally I do 4. Tear down or Annihilate to do the opposite of setup if needed.

1. Write a new test function and name it by the behavior you want to test.

function testItCanAddTwoNumbers() {

}

2. Act! Do the behavior you just defined in the test's name.

function testItCanAddTwoNumbers() {
    $sum = $calculator->add($n1, $n2);
}

3. Assert.

function testItCanAddTwoNumbers() {
    $actualSum = $calculator->add($n1, $n2);
    $this->assertEquals($expectedSum, $actualSum);
}

4. Arrange, or prepare all the missing parts.

function testItCanAddTwoNumbers() {
    $calculator = new Calculator();
    $n1 = 1;
    $n2 = 2;
    $expectedSum = 3;

    $actualSum = $calculator->add($n1, $n2);
    $this->assertEquals($expectedSum, $actualSum);
}

5. Annihilate, or destroy persistent information. Nothing to be done for this part here.

That's it. Have fun writing tests instead of hitting a brick wall with your head!

Saturday, August 30, 2014

Programmer's Diary: Finding Your Ways

I usually tend to give any advice with a pinch of salt. In one of my tutorials about SOLID I wrote the following phrase: "As with any other principle, try not to think about everything from before."

Which led to some dilemmas with a few of my readers, especially because it was in the Interface Segregation Principle article. I answered the questions of the reader, but I think the ideas there merit a blog post. So, here it is. Read on.

Any exaggeration is bad. If you think about everything upfront, it is bad. If you think about nothing upfront, it is also bad. Finding the right balance in what to do and what to postpone or not to do at all is essential for every project. There is no universal theorem or solution. There are however some recommendations that try to keep us on the right track.

In Agile software development, you will mostly meet tow concept. Each of them is pulling back you from one of the two extremes mentioned above.

1) Postpone everything to the last responsible moment. If you apply this, you may ask yourself every time you make an interface: should I create the interface? Will there be more than one implementation? If yes, what and when that implementation will be? Is it more expensive for me to delay the release by 2 hours and implement the interfaces now, or it is more expansive to not write any interface and introduce them on the next release when I know I will need them? How sure I am that I will need the interface on the next release? Can the plan be changed, outside of my control, so that I end up with a code that will never be relevant?

2) Program with change in mind. If not from the first release, then from the second. If you needed to change a specific piece of code, than there is quite a big chance you will need to change it again. On your first change, make it so that your third, forth, and so on, changes will be easy. If you see some code, once written and never modified, and you have no reason to change it, don't.

Basically this is it. Now you may ask yourself how to deal with these problems? You have three possible ways to go on:

1) Take the postpone extreme. Postpone everything, until you feel it starts to heart. Than, gradually try to think a little bit ahead and don't postpone things quite as much. This is how we at Syneto started.

2) Take the plan for everything extreme, and evolve from there. This is actually one of the routes many people take when coming from Waterfall. Gradually try to identify parts that take up a long time in planning but proved to be marginally important. Continue doing so until you feel pleased with your process, and you don't feel that what you do will never be used or useful.

3) Take the middle road. This may sound attractively optimal, but it is not. I don't think any project is right in the middle between the extremes. You can take the middle road, and continually think about both extremes. With time you will find toward which end your project requires more attention.

Sunday, July 20, 2014

Watch, Learn, Do, Decide

I have this concept whenever I need to decide if something new is good or not for me.

First I watch or read about the idea.  Then I study more about it. Then I do it for a relatively long time. Then I decide if it is good or not for me, that I should drop it all or I can adopt parts of it in my life.

This applies exceptionally well to new programming techniques.

At work, at Syneto, we usually do things for about 6 months before we decide.  But those are big things.  They affect a bunch of people.

In my personal life I scale down. Both the discovered things and the time for doing. Still, I always make sure I don't decide too early.

Recently I was invited to a new developers forum in my country. And after just one day,  I am amazed how many people jump over the learn and do part. They only watch and decide.

I believe the only way to decide upon a thing is by past experience. But you need to build that experience yourself. You can't avoid it, at least not for a long time.


Sunday, May 18, 2014

Belgrade CityBreak: An Unexpected Journey

My wife and I had an unplanned opportunity to visit Belgrade for the first time. It went pretty well.

We were asked to drive two of my colleagues to the Belgrade airport from where they took a plane to Paris. This trip allowed us to stop in Belgrade and visit the city. We had no plans, no knowledge about the city. I just set "Belgrade City Center" in the GPS and let it drive us ... somewhere.

First of all, parking your car in Belgrade is extremely difficult. We almost gave up after 30 minutes of randomly choosing streets in the central area and trying to find a spot to stop. Finally, we managed to park, at about 2.5 kms away from the point marked as city center on the GPS. Well, a 20 minutes walk should not be that much. But we were so hungry, and finding a restaurant was a bigger than expected challenge. We did not know the city, but based on the look of the streets and shops, we were somewhere close the center. There were even quite a lot terasses, but only coffe and drinks served. Where are the restaurants?

After trying several alleys that seemed promising, and having no luck at all finding a restaurant, we went on on the main street and finally ended up in the pedestrian area. At least finding a restaurant there was not a challenge any more. We ate at a random restaurant called Opera. They had good food and decent prices. One starter, two main courses, some mineral water and two coffees = 40 Euro.


After we ate, and with our bellies full, we decided that it was a really good time to just walk and admire the city and whatever surprises it may hide. The weather was also a good company, about 25 degrees, mostly sunny. Luckily the restaurant had free WiFi, so we had a chance to look up the surrounding attractions on TripAdvisor. Choosing our next stop was simple. The old City Fortress was just a few minutes away.


What we didn't expect is it to be so well preserved, free to visit, and really impressive. It is bigger than you may think at first sight and spending an hour or so just by walking around the old streets, walls, is not even enough. There is also a great public park surrounding the whole fortress. You can relax on a bench, walk around in a well maintained garden, do some sports, or just stop for a coffee at the Danube's bank.


An expo with first and second world war military equipment was just an amazing plus for this visit. So it's time to wrap up some pros and cons.


PROS:

  • Mixed architecture - there were streets on which you could recognize 4-5 types of different architecture from different eras. From a princesses house, through a peasant's house and a communist office building to victorian architecture. All you could imagine on a single street. There were also places with fluent uniform nice architecture.
  • Food was good - even though we have chosen a restaurant at random and we ordered Serbian specialties we never ate before, we liked the food.
  • People are friendly - we felt the local people friendly, quiet, helpful.


CONS:
  • Difficult to find a restaurant - unless you are in the very city center, on the pedestrian area, even a McDonalds or other fast-food is hard to find. You can get coffee and drinks, but now food.
  • Difficult to find a mini-market - on the whole 2-3 km walk from the car to the city center and back, we found a single mini-market to by some mineral water and cigarettes. Yes, there are kiosks here-and-there, but paying with your credit card is not an option there.
  • Traffic is quite intense - even though it was Sunday, there was quite heavy traffic in the city. Where did all that people had to go by car on Sunday? I can't understand...

That's it. Thanks for reading.





Friday, May 2, 2014

Agile by Instinct

There is a question on my mind for some time now. An idea, a thing that just can't let me alone.

What do you do after you tried all agile practices?

I had the opportunity to work for a company that went through a great deal of change by giving up an old-style waterfall oriented management and adopting agile. But what adopting agile actually means?

As any company and team we started by learning new techniques and practices. We started to plan our work on a board and we did a group-reading marathon of Gerard Maszaros' xUnit Patterns book. This was about 4-5 years ago, and it was enough to rise our interest in all these new things. We went on and adopted TDD and we still use it at a daily bases. We redesigned our architecture so that our business logic is isolated from the rest of the system as Robert C. Martin recommends in his clean architecture concepts.

We implemented a continuous integration and deployment system for our project, we covered most of our code by tests, we even optimized the whole deployment process to an extent that it takes about four and a half minutes to run all the 6000+ assertions in our unit tests, all the MVC framework's controller, helper and model tests (these are just a few, but still), compile and encode everything, crate packages and publish them on an update server. I think we have a process that is quite optimized. Even though there may be small changes to make, there will be no more significant gains.

And our everyday software development process? Well, after doing SCRUM for a while we tried Lean with Kanban. From all of them we devised the parts that can the most help our processes. There is not really any other formalized process we could try and fit in our management structure.

Continuous learning and deliberate discovery are another two things we do frequently. We, as professionals try to make ourselves better, each day, every day. We do courses, we practice at home, we attend conferences, we organize events, and so on.

"It sounds like a success story" as Dan North remarked it when I was talking with him about this topic. But what do we do next? What is the next thing we can try to make our process better, to go faster.

An interesting question Dan North asked me, and I was quite surprised by it, was "What makes you think you can go faster or better? Maybe you reached your maximum speed." (approximate quote). I couldn't answer him then. In retrospective that is because I have no rational reason to sustain my desire to go faster and better. But my instincts tell me we can do better. My professionalism tells me I can learn more and take better decisions. I am asking myself instead "Why should we ever stop getting faster and better?" Of course there is no magic answer. If there would be, it would be a formalized practice or technique, and this blog post would not exist.

For the time being I feel we are far from perfect. In the past year or so we tried to orient our attention more toward our clients. We tried and successfully listened to other departments. Now we are on our path to create a better synergy between dev, sales, operations, and marketing. And this is why Dan North's suggestion surprised me most. He suggested the exact same thing.

So, after you go through all the practices and techniques of agile development and you make them work for you, you must start being truly agile.

Being agile is not about adopting rules and practices. Being agile is not even about learning and devising your best way to work based on those processes.

Being agile is to learn, as a team, as a company, to follow your instinct in order to value individuals and interactions, to create working software, to listen to your customers and to respond to their needs as quickly as possible.

Agile is about us making efforts so that others doesn't have to.


Monday, April 28, 2014

#CraftConf Budapest 2014. A Big Wow!

At the end of April 2014 I went to a conference. CraftConf Budapest. We had no idea how many attendees will there be or how big the event will be, but one thing was sure, there will be a panel I've never seen in Europe at any conference before. There were so many famous people invited to speak that the event became a must-go both for me and for my colleagues.

We will write a more extensive blog post on Syneto's blog, so here I will present only my personal impressions.



First impression: This is a huge event!
I never attended such a big conference. There were more than 900 attendees and the main room had 5 screens, the big one, in the centre on the image above was 10 meters or so in diagonal. They also managed to secure some very wealthy sponsors who kept our bellies full and prevented our mouth to dry out. The other 2 rooms were smaller, but still impressive.



Second impression: There at most 5% of new information in a talk.
For whatever reason I had huge expectations from this conference. However I have to realize that a talk can not contain more than 5% new and useful information. At least not for me and my colleagues. This was a hard thing to realize, but it led to the next one.


Third impression: The value of a conference is in the chance of speaking with famous people.
Yes. You need some guts, but if you want real value for the money you payed for the conference, you must go and talk with those important people. For some I had questions in order to obtain new information, for others just to confirm some of my own ideas and perceptions and for other I actually managed to provide constructive feedback.

All in all I talked with more famous people in 2 days than in my whole life altogether. So I thank you Bruce Eckel, Dan North, Eric Evens, Gerard Meszaros, Theo Schlossnagle, John Hughes, Simon Brown for your time and for every other speaker for their great talks.

Monday, March 24, 2014

I Don't Believe in Genetically Born Leaders

I hear so many times that some are made to lead, while others to follow. And while there may be some truth in that statement I don't believe someone can born to be a leader. I believe in discipline. I believe in hard work. I believe in fulfilling of dreams. I believe any of us can lead or can be led. I believe it is ultimately our choice. But how is that possible? Don't we have different personalities? Don't we have different professional objectives? Don't we have different dreams? Don't we born and live in different societies? Sure, we have, we are, we do. Than how could any of us become a leader or a follower? Well, society, family, and friends have a great impact, but at the end of the day it's up to you what to choose to do. Some choose to follow and be happy. Others choose to lead. Others try to find the balance between the two. I believe when there is someone to follow, you should do so. However, when there are some to lead, you should do so again. There is no way you can't be leaders for some and follow others. This is the only natural situation you can be in. There will always be things to learn from those smarter and wiser than you, and there almost always will be others willing to learn from you. If you only want to be a follower, you will never feel the appreciation and amazement of other young minds discovering your secrets. If you only lead, you will burn out very quickly. Your students and followers, if balanced between the two characters, will simply become smarter and wiser than you and will become leaders instead of you. That's why the most depressive persons I ever seen were followers without will to lead, or fallen leaders without hope to rise again.

Wednesday, February 19, 2014

Programmer's Diary: Transforming PHP Objects to Strings


In my upcoming programming course for +Nettuts+  I will implement a persistence layer for the application developed throughout the course. For the sake of simplicity I decided to make it a file persistence and keep information in plain text. This was a good occasion to use a nice PHP trick to convert simple objects into plain text.

Our objects are books and besides the fact that there is an abstract book class there are a lot of specific implementations for different kind of books, like novels. Each is a little different than the other, so saving all the books in the same text format would have been impossible.

PHP offers a magic method called __toString(). Creating an implementation for this method, on any object, will allow you to use that object in a string context. Let's see a basic example.

class SystemInformation {

 private $cpu;
 private $ram;

 function __construct($cpu, $ram) {
  $this->cpu = $cpu;
  $this->ram = $ram;
 }

 function __toString() {
  return "CPU: " . $this->cpu . "%" .
        "\nMemory: " . $this->ram . "MB";
 }
}

If we create such an object and try to run it in a string context, like in echo(), it will be automatically converted to string, using whatever we return in __toString().

$sysInfo = new SystemInformation(40,1024);
echo $sysInfo;

This will output:

CPU: 40%
Memory: 1024MB

You can also use it in some other contexts also, for example this test will pass just fine:

$this->assertTrue(strpos($sysInfo, 'CPU') !== false);

And when PHP is not smart enough to figure out that you want the object as string, you can always call __toString() on it directly.

$this->assertRegExp('/CPU/', $sysInfo->__toString());

For the complete example with the whole application I mentioned at the beginning, keep an eye on the +Nettuts+ premium courses. Have a nice day of programming.

Wednesday, February 5, 2014

The advantages of working for 2 companies at the same time

Many companies deny their employees to have a second workplace, or work as freelancers in the professional domain as their main job. Other corporations have an approval procedure,  and each employee must declare any other job he or she wants to take. If the company decides that the job may conflict with its interests, it may deny the employee to accept it.
What companies rarely consider are the reciprocal benefits. I had 2 workplaces almost all my career. Right now I work for Syneto and in my free time I write for NetTuts. This is great for everyone. I can write great articles based on my experience at Syneto. Syneto benefits of me becoming a better programmer with each article or course I make. Explaining my ideas greatly improves my knowledge on that specific domain because I need to dive into details about it.
So, I learn more and better, Syneto gets better code and NetTuts better articles.

Everyone wins.

Sunday, February 2, 2014

Programmer's Diary: Writing a Series for @NetTuts


If you are following me on twitter you probably know I am a regular technical writer for +Nettuts+ . I write various tutorials and articles on programming topics. However I never wrote a series with tutorials that are connected in one way or another.

That changed with the series on the SOLID principles. I had to write four articles covering five principles and I found out there are quite a few challenges when writing a series of articles.

Challenge #1 - The first article must be good. Much better than any of my stand-alone articles, because it must convince any reader, new or regular, that the upcoming articles in the series deserve their attention. The first article has the stake of the whole series. If it fails, there is a chance the rest will never be read, doesn't matter how well written it may be.

Challenge #2 - Each article must find a way to refer to, to connect with the previous articles or at least with some of them so that the readers have a feeling of continuity. In each of my SOLID articles I referred to at least one, but preferably two other SOLID principles. Now, this is again tricky. Because the articles are published and read in sequence, from S to D, even though O may relate to I or D, in the article itself I can only refer to S because the reader may not know about the LID principles. If I refer to any of LID I risk one of two things: confusing the reader and loosing him/her, making the reader curious and making him/her read the three LID principles from other sources and not read my upcoming three articles.

Challenge #3 - Each article must be self contained, in a sense that a new reader must be able to comprehend it without reading any of the preceding or upcoming articles in the series.

Challenge #4 - Each article must provide something different so that the readers don't get bored. If one article explained the concepts with mostly text in anecdotal manner, the next one must use a different approach, maybe more schemas or more source code or more quotes of rules and definitions or more funny statements. It doesn't really matter what, but it must be different, it must be unique in a way to disrupt the monotony of the series and still provide the valuable information it proposed as its topic.

Challenge #5 - The last article must contain a conclusion to the whole series. It must be written in a way that not only transfers the last topic in the series, but also connects all the dots and provides a high level view over all the topics presented throughout each tutorial. It also has to put everything in perspective, under a different light, in a different - bigger - universe, where the whole series is just a small piece of the puzzle.


That's why I concluded my series about the SOLID principles with a reference to The Magical Number Seven, Plus or Minus Two and that is why there are 5 challenges in this blog post.

Sunday, January 19, 2014

Programmer's Diary: Mistakes Will Come Bite You in The Butt

Last week I was doing a quick refactoring of our virtualization module at work. We are about to introduce some new concepts in it and a reorganization of the directory structure was due.

However, this being a quite mature project it was started before the dawn of namespaces in PHP and the KVM module was also written in that fashion. As we thrive for perfectness whenever we can, moving the module to namespaces while changing the directory structure was the obvious choice.

Introducing namespacing into a module of about 20 or so classes was not a big deal. Tests covered most of it, find and replace worked like a charm and the PHP analyzer in PHPStorm highlighted a the few spots missed by the former two actions.

In less then a full work day the whole module, at the business logic level, was up and running using namespaces and the new directory structure. Long live TDD and good test coverage, it would have taken several days or maybe weeks to change all that without tests, but that's another story, for another time.

Then my colleague +Vadim Comanescu  offered to help with the update of the web interface. As our business logic is totally separated from our user interface, the changes should have been quite localized. And they were, for the most of it. The change went on smoothly, except one little mistake - or laziness for that matter - we made a few months ago. 

A rogue method in a view helper implemented something like "isCurrentPathForVM($path)" At first sight it was acceptable. It accessed the virtual machine inventory class Kvm_VmInventory, retrieved all the virtual machines with its "findAll()" method and did a quick foreach() on it asking each virtual machine if it belongs or not to the provided path.

Helper -> Inventory -> Virtual Machine. A simple dependency chain involving only 3 classes. Shouldn't be a problem, right?

Then it struck us! Why modifying the public interface of the Inventory class affects a view helper? Why the internal class structure of the KVM module is leaked to the UI? Why a helper attached to a view must know the working details of an class buried deep inside the module? Don't we have a Facade already written for that?

So many question had been risen in an instance. Clearly something was wrong.

A view helper should use only information available to the view and it should only do operations related to presentation. Yes, it should contain logic, but only presentation logic. Was finding out that the current path belongs or not to a virtual machine presentation logic? It turns out it was not.

To start answering our so many questions we decided the helper must not know about the inner classes of the KVM module. However it needs to ask the module for the information it requires: Does the current path belong or not to a virtual machine. If yes, the helper will instruct the view to draw a little computer instead of the folder icon at the left of the path.

To do so the helper need access to the facade. But should it create an instance of the facade? No, it shouldn't. There is already one available created by the Kvm model. But accessing a model from a view helper is again tricky and wrong. The helper needs to take it's parameters from the view.

The view's parameters are defined by the controller. That's great, we have the missing piece in the chain.

Helper -> View -> Controller -> Model -> Facade -> Inventory -> Virtual Machine. Here is our new dependency chain. Much longer, but also way more decoupled and correct. The model provides the facade to the controller and passes it to the view, subsequently letting the helper ask for the question: is the current path for a virtual machine? Which made us realize a distant code duplication was also present. The whole logic of the original method was already implemented in the facade. 

We were pleased to also a remove a code duplication that lingered hidden in the dependency chain.

Finally we moved the logic from the facade to the Inventory. Facade's should have no logic, they should only be a common entry point to the module providing an easy to understand specialized public interface to any client.

All that done, Vadim and I looked at each other, and he said: "There was not one instance when a mistake or laziness did not come and bite us in the butt afterwards!"

We at Syneto always try to make our code better. We are proud of our accomplishments and we are not afraid to acknowledge our mistakes.

Disclaimer: Code descriptions, method names, functionality details are approximate in order to protect our project.