Przejdź do głównej zawartości

Posty

Wyświetlanie postów z 2013

Code Kata: A simple text-based calendar

In this Kata we want to properly display a simple calendar view of a given month. Let's start with an example. A proper output of our program for the input data of "December, 2013" would be:

Mo Tu We Th Fr Sa Su
                   1
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

Points to consider:
how many times we need to make a call to time-date functions?try to minimize the number of these callstry to separate program logic from presentation as much as you can

Job interview: software developer

We now have two or three generations of software developers who got their first job (or any next job) by correctly answering the question: "what will be the output of this code?". As we possibly did not have a better idea what to ask a candidate about, this might have been a satisfactory question one generation ago. Is it OK, from the point of view of the recruiting entity and the candidate, to ask the same question today? I would gladly replace the conventional list of questions:
what will be the output of this few lines of code?what will be the size of this structure in memory?what is wrong with this code snippet? with questions more relevant to daily developer's tasks, like:
try to refactor this code snippet look at this class; how would you add a unit test to test this function?after running this program, explain why it prints this output While the former questions test something, they are not even close to problems that a developer faces daily. On the contrary, seei…

The return of native applications - but what for?

Before the web applications era we had the following (and not an easy one) situation with software:
some applications had only one target in terms of hardware or operating systemsome applications had different versions so that they could be used on more than one software / hardware combination Around the time when I started my first job (2000) it was apparent that the ultimate interface for everyone and everything would be the browser. Since then we have had web based applications serving as the primary user interface in all possible domains, from email, through project management to modeling and simulation.

But recently, we see more and more applications that are marketed as native. Although often a web version of an application exists, its platform-tied version (iOS, Android or Windows) is marketed as if the nativity alone were such a big advantage.

What can we make out of this? I don't know. But it just seems strange.

Scripting paranoia

Jim is a developer in a team of nine and is better acquainted with Git than any of his colleagues. They rely on him when there is something particularly difficult to do with Git or if they have any kind of questions about Git. They feel comfortable asking him even the most basic questions, because Jim is so friendly and helpful.

Jim wants to make his teams' life easier so much that he creates a whole bunch of scripts. Over the course of time the team has a number of scripts that come in very handy when they want to perform regular, day-to-day versioning tasks:
branching: instead of regular Git commands -> branch.shmerging: instead of regular Git commands -> merge.shtagging: instead of regular Git commands -> mktag.shpushing to remote server: instead of regular Git commands -> pushall.shviewing commit history: instead of regular Git commands -> showcommits.shand so on... Scripts are well suited to what the team does daily. If there's the need to tweak any script a…

Projector effect

When you are in a Scrum planning session or any other kind of Scrum event or at a meeting, look closely how people behave when there is a computer screen projected on the wall.

What happens most of time is this:
nobody looks at others,everybody look at the projected screen (or a monitor, if there is no projector),people stare at the slides even though they have already read them 5 times,and worst of all: people tend to turn off their regular intellectual abilities and day-dream to the subtle noise of projector's fan If you do use computer at the meetings, specifically during Scrum events, try out this advice and stop using it. Even for a couple of meetings. I am sure you will see the difference.

The mere fact that product development is going to be done on computers and that the product will run on a computer doesn't mean that every aspect of our work must be done with a computer.

Real-time shared editing of code in Eclipse

I came across this great video by Mustafa K. Isik.

http://vimeo.com/1195398

This was recorded a couple of years ago and I'm hoping the whole idea had developed since then.

Anyway, I searched for an Eclipse plugin that supports shared editing and I quickly learned about ECF:

http://www.eclipse.org/ecf/

However, despite well documented installation, I found no help there whatsoever to start actually using the plugin. Spending some more time trying to find this information resulted in this excellent how-to article:

http://realsearchgroup.org/SEMaterials/tutorials/docshare/docshare.htm

I really recommend seeing the video in the first link, if you haven't done so yet. And then, actually giving it a try!

Code Kata: A rover

Another game-like exercise. A rover moves over a board with X and Y dimensions. Some places on the board are filled with stones and this is where the rover cannot move onto. Your task is to implement the rover and the board with the following requirements and restrictions:
the rover understands your commands (e.g. from command line) of the form:forward - moves one step forwardleft, right - makes 90 degrees turn left or rightif the rover gets the forward command and there is a stone in front of it, it just ignores it; you can optionally print a message to signal thatthe rover does not have the knowledge of the terrain - it keeps a reference to a board [object] which actually knows where the stones are and tells the rover whether a given move is possible or notthe rover should not be allowed to move outside of the board Although it will probably be fun to test this with command line, you are encouraged to use TDD as you go.

A reflection on the future of programming languages

I started my first job as a programmer in 2000, a year before I got Master's degree in Computer Science. At that time, a recurring question that was asked by students and graduates was:

Which language should I learn in order to be successful on the market?

It seems like this question is universal and has always been asked, in some cases inquiring about a programming language, another time on a library or a framework.

So, will learning Java pay off better than C++? Does it even make sense to learn C these days? Or will mastering the Java Servlet Pages position one better on the market than learning PHP?

The simple and provocative answer is: it does not matter.

The longer answer is really the rest of this post, so if you are interested, read on.

An interesting phenomenon in the history of software is that many great libraries and products have been created by individuals or, at most, tiny groups of people. Consider these examples - if any of the products seems unfamiliar, read about it on…

Bugs on a board - modern concurrency in Clojure

[ Inspired by Rick Hickey's Ant Colony Simulation ] Having said before that Clojure is great, I feel obliged to provide a concrete example of a concurrent Clojure program. We will implement a simulation of N bugs walking randomly on an X x Y board. If two bugs walk onto the same cell, they both vanish. Let's start!

The board has dimensions specified as follows:

(def dimx 50)
(def dimy 50)

A bug performs one step from the current cell by randomly altering its (x,y) coordinates. Each coordinate is incremented or decremented by 1, or it stays the same.

(defn random-step [n]
  (let [step (rand-int 3)]
    (cond (= step 2) (dec n)
      (= step 1) (inc n)
      (= step 0) n)))

Next location for a bug will be randomly generated, unless a bug is at a border. In that case, it immediately jumps in the opposite direction.

(defn next-loc [loc]
(let [x (loc 0) y (loc 1)
      newx (cond (= x (dec dimx)) (dec x)
                 (= x 0) (inc x)
                 :else (random-step x))
    …

Code Kata: shopping list search

We have a list of, let's say, goods we bought at a shop (or you can imagine any other list that you like):

|        Name        |      Quantity      |       Price      |
|        Beer          |           10          |        30            |
|       Pickles        |           1           |        12            |
|     Red beans    |            2           |        22            |
...

The task is to write a piece of code that will search through the list and will display each row that matches search criteria. Too simple? Maybe. But consider these additional hints:
search criteria may not be exact. The string "bean" might match "Red beans"we may even be searching for any of a few items: rows one and three will both match if our search criteria are "any of 'beer', 'bean' ". I recommend that you start this kata with an exact search for one item and then gradually move towards the "like/contains" criteria and to "any of" c…

Do I really have to call super(...).__init__ in Python?

Yes. But, if you prefer a longer answer:

Class B inherits from class A. When implementing B's __init__ function, we may call A's init by writing:

super(B, self).__init__(arguments of A's __init__)

Is it really necessary? After all, in C++ or Java the constructor of base class is called automatically, so shouldn't it be called automatically in Python as well?

The point is that __init__ is not a constructor. Python objects are constructed with __new__. __init__ is used to initialize an object with concrete values, either defaults or passed as __init__'s parameters.

Need more details? Read Python docs at http://docs.python.org/2/reference/datamodel.html#object.__new__


The mythical independency principle

We're having a hypothetical conversation with Joe, a developer in a Scrum team.

- Joe, how is your team doing in terms of unit tests?
- Very good! We have a developer in our team, Jack, who is proficient in writing good unit tests. He works with other developers to understand what they are planning to implement and then writes dozens of unit tests that they can use to validate their work.
- Wait a minute, so he's the only one in the team who writes unit tests?
- Yes. That's his specialization. Because of this, not only is he able to write really good, maintainable tests, but is also so productive that an average of five tests per day is for him a piece of cake.
- But the unit tests aren't a separate development activity, they are integral part of developing the right code!
- This is what I used read on the Internet, but the reality is what we are doing here is in accordance with the independency principle.
- Tell me more about it.
- We are avoiding the Initial Error. I…

Code Kata: text game from 1982

* * * W A R N I N G * * *
This Code Kata can seem very strange for people born in the nineties.

The goal is to implement a text-based game in which the player walks through dungeons in order to accomplish a task. The basic characteristics of an implementation are as follows:
the game generates random dungeons as a group of ROOMS and PATHS that join the ROOMSthe generation does not leave unreachable ROOMSthe user is presented with the information about the ROOM  they are in and the ROOMS reachable directly from the current ROOMthe user can move from the current ROOM to the directly reachable ROOMS by entering a command This may seem very boring at first, but let's add some delighters:
We do all of the implementation using "TDD, as if you meant it", of course Initially, the goal may be simply to get to a given ROOMThen, we may start adding attributes to ROOMS; a possible attribute is something that the user can collect, such as diamonds; N diamonds are placed in the dungeon …

Enjoyment of failed tests

We usually feel bad about failed tests. No surprise, as it simply means that something got wrong or that some tests have been invalidated by the recent change to the code. But can we feel good about a failed test? I think we can and here is why.

If I add a new tests for functionality that does not exist yet, it will either not compile or will fail. Watching it is not entirely upsetting experience, because the bright side of it is that we have evidence that the newly added test get at all executed. And it is good that it got executed, this is what we expected.

Another occasion when we could look at the failing tests with a smile is just after making a "very small change that should not break anything". And after this change we see a dozen of failed tests. Imagine doing this change without unit tests at all and keeping the belief that "it couldn't have really broken anything" for the next few months.

Estimation, estimation... ehh

Steve McConnell gives an excellent overview of estimation methods in his great book "Software Estimation - Demystifying the Black Art". Probably, the most prominent part of the book is the Cone of Uncertainty.

On the other hand, we may spot from time to time the sentence "Estimation is waste". So, where's the Truth? Is it waste or not? And is estimation a fine skill to have? Here is my personal opinion:

Estimation is a Good Thing when we want to answer questions like:
how many months will pass until the project will have been finished? (if the unit is weeks, don't bother estimating)can we do the work that is ahead of us with the staff the we have, or do we need more people / more teams in order to do it? How many do we need?in order to satisfy customer needs, we can implement solution A, B or C; the solutions have different costs and different attributes in terms of scope, risk, maintenance, etc. Estimation of cost helps us with making the right choiceEstimati…

Python profiling for beginners

def bar(i):
    return i*i

def foo():
    for i in range(0,1000000):
        bar(i)

Let's try to use these two silly functions to do a profiling exercise.

First of all, we need to import cProfile. And then call: cProfile.run('foo()')

Output (from my laptop):
         1000004 function calls in 3.564 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    1.926    1.926    3.564    3.564 <pyshell#11>:1(foo)
  1000000    1.638    0.000    1.638    0.000 <pyshell#9>:1(bar)
        1    0.000    0.000    3.564    3.564 <string>:1(<module>)
        1    0.000    0.000    3.564    3.564 {built-in method exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

At the first glance, it may look criptic, but: the total time is the time spent in a function excluding the time spent in callees. The cummulative time is the time spent in a function includin…

Velocity calculations

Let's starts with some facts and numbers. There is five of us in the team. In the last three iterations, we completed the scope worth of 9, 13 and 12 story points. We feel comfortable commiting 10-11 story points in an iteration and we never commit more than 12.

Case #1
If Harry joins our team next iteration, will you comfortably commit 12, on the average?
No. We may be delivering 12 from then on, but the reality is we don't know. It may be 12, but odds are it will be 14 or 8.

Case #2
If Jack leaves your team next iteration, will we comfortably commit about 8?
Not necessarily. We may still be able to deliver functionality worth of 10 story points. But that's not all. We are not sure how you will react to that, but without Jack we may be able to deliver 13 or 14 pretty easily.

Case #3
So you are telling me that arithmetic does not work in Scrum?
No, it's better to put it this way: arithmetic does work in general, but it does not properly describe a complex system, such as a S…

SuperFib - an example of using lexical closure in Python

This story begins with simple implementation of a function that calculates Fibonacci numbers.

def fib(n):
    return 1 if n == 1 or n == 2 else fib(n-1) + fib(n-2)

Assuming that we are using 1-based indices, we can run a couple of tests and see that it works. Of course, fib(35) takes some time to calculate - about 15 seconds on my laptop.

Now, if you don't know what lexical closure is, I recommend reading about it on Wikipedia) before going further. Let's try to cache the results, but also be better than using conventional memoization - not only will we cache the final result of each call, but also intermediate results.

def fib():
_dict = dict()
    def inner(n):
        nonlocal _dict
        if n == 1 or n == 2:
            return 1
        else:
            try:
                return _dict[n]
            except KeyError:
                _dict[n] = inner(n-1) + inner(n-2)
                return _dict[n]
    return inner

f = fib()
f(1000) returns instantly, with:
43466557686937456435688527675…

Unit Testing code with IO file operations (in Python)

We may often come across a piece of code that was written without Unit Tests at all. In addition, the piece of code may be dealing with IO like file writing and reading, which makes it more difficult to Unit Test it when we are trying to refactor and modify. Let's suppose the code in question looks like this:

def writeInitialsToFile(filename, name, surname):
    initials = name[0] + '.' + surname[0] + '.'
    with open(filename, 'w') as file:
        file.write(initials)

def readInitials(filename):
    initials = None
    with open(filename, 'r') as file:
        initials = file.readline()
    return initials

A straightforward and bad idea would be to write a couple of Unit Tests that make use of a real file and simply test the reading and writing. Is therea a better way to test this code?

First of all, we need a way to replace the real file with something else. For both reading and writing we will now have a couple of functions, one that expects a stream fo…

Long if-else statement without if (in Python)

Let's suppose we find ourselves in a situation where we have no other option than to write a lengthy if-else statement (definitely not something that would make cleaner by polimorphism).

def inevitable_long_if (n):
    if n == 0:
        print('Zero')
    elif n == 1:
        print('One')
    elif n == 2:
        print('Two')
    else:
        print('Manu-manu')

Can we re-write it so that we do not use IFs?

import collections
import functools

d = collections.defaultdict(lambda : functools.partial(print, 'Manu-manu'))
d[0] = functools.partial(print, 'Zero')
d[1] = functools.partial(print, 'One')
d[2] = functools.partial(print, 'Two')


Now, let's call some to see how it works:

d[0]()  ==>  Zero
d[1]()  ==>  One
d[2]()  ==>  Two
d[7]()  ==> Manu-manu

The first version is 9 lines long, the second one (without imports) is 4 lines long. To me, the second version is also much more readable, but you decide.

Scrum? Yes, I'll have one, please!

There is one of those soft skills training like "Conflict management" or "Team building". The trainer is a woman with psychological background. After the usual part that is delivered during every soft skills training (and, surprisingly, this part is almost always the same on every training) there is a break. The trainer asks people what they do in their job and it may well be that she is really interested in what people say, or maybe she's just pretending. Regardless, she goes like this:

- Could you tell me more about this Scrum thing you mentioned? How do you do it exactly?

One of the trainees feels he's the one who must speak up:

- Well, we meet every day at 9:00 and we talk briefly what we did yesterday and what we have to do today and whether anyone has any obstacles. This is called "stand-up". Also, the whole project is divided into a number of short periods called iterations and there is the planning at the beginning of each and (...)

The tr…

Pure functions in Object Oriented World

Let's suppose we have a class called Time with method convertToGMT(...). The method has one parameter called time, it converts the parameter to the GMT and returns the result.

For some reason (and please let's don't try to question this reason for the sake of this short exercise) the actual time zone of the caller is an instance variable of the Time object. It may be set when the object is constructed or re-set afterwards.

convertToGMT simply checks the time zone by accessing the instance variable timezone, performs calculation and based on that returns the GMT result.

When writing a couple of unit tests to test how convertToGMT works for different time zones, we would have to repeatedly:
set the time zone by calling the presumed Time.setTimeZone(...) methodcall convertToGMT and check the result We would do that for each time zone - time-to-be-converted pair we want to test. Clearly, this function is not a pure function, since its result depends on the state of the object. …

Clojure is great!

I've been playing with Clojure for a couple of months now and I want to share with you some thoughts why I think it is a great language.

Clojure is a Lisp

Many wise people have written great things on Lisp, so I'm not even trying to present arguments for it; just try out these:
http://www.paulgraham.comhttp://www.gigamonkeys.com/bookClojure integrates easily with Java libs

Everybody knows it. Nothing interesting to add here.

Clojure implements modern concurrency techniques

Clojure implements STM(http://en.wikipedia.org/wiki/Software_transactional_memory). It features Atoms (abstractions for managing state synchronously), Agents (abstractions for managing state asynchronously, by applying function to agent's state), and lock-free handling of scenarios that would have to be handled with mutexes in other programming languages.

Don't be deceived that Clojure is "nice, because it revitalised Lisp or JVM". The key point is that it features modern approach to concurren…

Code Kata: Eating habits and Markov chains

The Wikipedia entry:
http://en.wikipedia.org/wiki/Markov_chain#Introduction
contains nice and clear explanation of the idea of Markov chains. Based on the paragraph about eating habits, we can form an interesting coding exercise:
A person eats lunch every dayWe form a set of rules similar to the one presented in Wikipedia - one part of the exercise is how to represent these rules in a program. What would be the convenient way to represent this internally and how would you translate a possible textual representation (such as one entered from standard input) into the internal format? Would the two format be quite similar or quite different from each other?We run a simulation for a number of days - say, 365 days - and we get statistical distribution of the number of each type of meals that would be eaten Does it seem like a long program to write? My initial solution in Python was 23 lines long and then refined solution took just 14 lines.

Recommended reading: Clean Code

A week ago I started reading Uncle Bob's book "Clean Code". Although I'm still not yet half way through the book, I want to recommend this book to anyone who has not read it yet. One of the many things that impressed me during the reading was this:

In in the book, Robert Martin makes several times the point that the bad code, such as one with long functions, many indentation levels, cryptic names and complicated conditional expressions inside those functions is simply hard to read. This may be an astonishing this to hear from a professional, at a first glance. Indeed, through our education and early professional work we become used to the notion that "real professional" is able to decypher really complicated code without a hitch. We are also often impressed by our colleagues who through years of dedicated work have become fluent in understanding of extremely bad written and uncomprehensible modules.

Martin tells us that this is not the right way to look at …

Code Kata: Recently opened files

Kata #2: Recently opened files

Implement a container that has the well known functionality of "Recently opened files" that you know from various applications you use:
the container must be able to list file paths that it storesif file A is opened and right after that we ask the container to list the file paths it stores, the path to file A will be listed as the first onethe number of stored file paths is limited; when the limit is exceeded the container forgets least recently used file pathin the list of recently open files, each file path can appear once and only once

Code Kata: Vending Machine

Kata #1: Vending Machine

Your task is to implement a piece of software for a vending machine that sells sweets. The machine accepts coins and must be capable of returning change. It is up to you to decide on how inserted coins and change that is given out are represented. Consider the following variations of this exercise:
Simplification: you have an unlimited number of coins of every kindRealistic: the machine is loaded with coins at the beginning and you have a limit on the number of coins of every kindMore realistic: the machine adds the inserted coins to respective coin slots and uses them to serve further transactionsEven more realistic: the machine tries to optimize the way of giving out coins - if there is danger of giving out too many coins of kind A, and there are is surplus of coins of kind B, then more of B coins are used to produce changeFuturistic: the machine asks you to provide it with coins that would help it return the proper change How would your implementatio…

Piotr's Less Obvious Advice on Google Mock: State maintenance

Google Mock provides several ways to maintain state inside mock objects. One way of implementing state maintenance is with SaveArg. Consider the following example.

We have a class Configurator, which allows a caller to set and get values of a parameter:

class Configurator
{
    public:

    virtual ~Configurator() {}

    virtual void setParamX(int n) = 0;
    virtual int getParamX() = 0;
};

And we have a class Client that calls Configurator's methods and it also has a method incParamXBy, that can be used to increase the current value of paramX by a certain value.

class Client
{
    public:

    Client(Configurator & cfg);
    virtual ~Client() {}

    void setParamX(int n);
    void incParamXBy(int n);
    int getParamX();

    private:

    Configurator & _cfg;
};

incParamXBy internally calls setParamX and getParamX on Configurator:

void Client::incParamXBy(int n)
{
    _cfg.setParamX(_cfg.getParamX() + n);
}

Let's assume that the initial value of paramX is A and that we want to increase paramX by…

Piotr's Less Obvious Advice on Google Mock: Returning new objects from a mock

Google Mock provides a way to return newly created objects from a mock method. Suppose we have a  Generator class that is supposed to generate new objects when createNewRecord method is called:

class Generator
{
    public:
    virtual ~Generator() {}
    virtual Record * createNewRecord() = 0;
};

...and suppose we want to mock this class:

class MockGenerator : public Generator
{
    public:
    MOCK_METHOD0(createNewRecord, Record * ());
};

Suppose the caller class Client has run method defined as follows:

void Client::run()
{
    for(int i = 0; i < 3; i++)
    {
        rec_tab[i] = gen.createNewRecord();
    }
}

We want the mock to return a pointer to a new object each time createNewRecord is called. This is how we can express this in the test code:

TEST(ClientTest, CanRun)
{
    MockGenerator gen;
    Client c(gen);

    EXPECT_CALL(gen, createNewRecord())
        .Times(3)
                 //this is equivalent of returning new Record(1,2,3)
        .WillOnce(ReturnNew<Record>(1,2,3))
        .Will…

Piotr's Less Obvious Advice on Google Mock: Mutual method calls

Imagine that object A calls method M of object B and B is a mock object. Let's assume further that if B were real, calling the M method would result in B calling a method on A (M would call an A's method from its body). Suppose we want to simulate the same behavior with a mock object. We have a "master" and "slave" objects called Starter and Startee, respectively.

class Starter
{
 public:
  Starter(Startee & startee, int vol);
  virtual ~Starter() {}

  void start();
  void configure();

 private:
  Startee & startee_;
  int vol_;

  Starter();
};

// implementation of the above Starter methods
Starter::Starter(Startee & startee, int vol) : startee_(startee), vol_(vol)
{
}

// Starter will call run method on startee
void Starter::start()
{
  startee_.run();
}

// this method is supposed to be called by Startee as a result of calling startee_.run()
void Starter::configure()
{
  startee_.setVolume(vol_);
}

And now, Startee:

class Startee
{
 public:

  virtual ~Startee() {}

  virtu…