martedì 31 gennaio 2012

Vim color scheme samples

I have a lot of Vim colorschemes, and I like to change them very often, reflecting my mood. I needed a way to showcase them all and quickly pick one.

The original Vim Color Scheme Test script by maverick.woo is written in Perl and the build works on Windows systems. I wanted to add some new features, and to test it with my own colorschemes, but as I'm not very confident with Perl, I preferred to start over with a new Ruby version instead of forking his project. Here's my version (and here's the github page):





The script loads all your colorschemes from your default vim directory (~/.vim/colors), and writes into the output dir an HTML file for each colorscheme, with a render of a Ruby file using this colorscheme. It also writes a different copy for each language present in the samples/ directory. It also builds an index page for each language, with a showcase of how the colorschemes render the sample code, a download link for each colorscheme and a nice lightbox to preview it.

To make it run, you'll need:
  • ruby
  • macvim
  • tilt rubygem (to render the index template)

What still needs to be done:
  • Separate light and dark colorschemes
  • Make this work with versions of vim different from MacVim
  • Add the current language name to index pages
  • Add more languages (currently only Ruby and Python are supported)

ATM, the script uses a vim server named VIMCOLORS and sends it remote commands. This was made to make it faster, because opening a single macvim instance for each script required too much time. However, the --remote-send command of vim doesn't wait for previous remote-sends to be completed, so I had to add a "sleep 1" command in the script to prevent it from messing up the execution flow. Any hint to solve this is greatly appreciated.

venerdì 28 ottobre 2011

Using virtual attributes for multi-parameter form helpers in Rails

In a Rails application I am working on, I needed to setup a form with a field with a non-standard behaviour. The field represents a date object, so the FormHelper date_select helper looked great; however, the date to display was not the actual date to be set on the database, but the day before. Changing all the data on the DB was a bit risky, so I had to stick with this requirement.
I decided to use a virtual attribute to do this, as it seemed the most elegant solution, so I wrote this in my model:



And this in my controller:



However, trying to send this data to the controller resulted in a "1 error(s) on assignment of multiparameter attributes" error.

The solution I found after some search was this one:



Reference:
http://gabeodess.heroku.com/posts/14

mercoledì 20 luglio 2011

OSX Lion: "This disk cannot be used to start up your computer"

Today I downloaded the installer for OSX Lion from the App Store. I ran it, and when it came to choose the disk to install to, it told me that "this disk cannot be used to start up your computer". I had a setup with 4 partitions: the hidden EFI system partition, the Macintosh HD partition, and two linux partitions (an ext3 one + a swap one).

So, the solution was to resize the Macintosh HD partition. I booted my Mac from the Lion install DVD (you can burn it from the installer package, just search google to know how to do it), went into disk utility, checked all partitions for errors (this was necessary because I wasn't able to resize them otherwise) then I resized only the Macintosh HD partition shrinking it by some GBs.

After this, I ran the installer again and installation started smoothly.

HTH!

domenica 19 giugno 2011

Machinist vs Factory Girl: Machinist win!

Today I decided to verify if Machinist could be a good replacement for Factory Girl. In our project, we have a big problem with Factory Girl: even if you tell her not to hit the database, using the Factory.build method, if an object has associations, these are saved on the DB. And this causes a huge slowdown in specs using factories. We've been using Factory Girl for nearly two years, and if we could find a way to stop him hitting the DB, we could really have a huge improvent in our test suite running time.



To verify if Machinist could perform better, I set up a basic rails app. Look at this example:





If you do a tail -f log/test.log and you run this spec, you'll see something like this:





The Factory.build method has to save dependencies on the DB to set the foreign keys on the objects and validate them.



Let's try with machinist:





This time, running tail on the test.log file and running the spec, doesn't shown any DB hit, and of yeah, we have a green test.



I verified this also by putting a debugger line after the validation and inspecting the DB from within the debugger after the validation has run - with FactoryGirl, it revealed an Address object saved on the DB, while with Mechanist it didn't.



I still haven't looked inside machinist to show how it handles this, but I'll do it soon, so keep in touch!

giovedì 10 marzo 2011

Howto: Run a rake task in sandbox mode

If you have a Rails rake task that somehow changes your DB data, but you want to be sure that the DB will be rolled back to its previous state after the rake task has completed, you can simply include this snippet right after your task definition:



If you wonder where is this code coming from, it's directly from the rails console code.

venerdì 28 gennaio 2011

Rails 3 scopes with HABTM (has and belongs to many) relations

There are already many posts about this, but maybe this simple example will help you understand this subject even better.

martedì 18 gennaio 2011

invalid option: --with-pg-dir=/opt/PostgreSQL/9.0

I'd bet a lot of ruby devs actually found themselves stuck in this problem. You checkout a github repo, you run a bundle install and = duh = a gem cannot install because of a missing library.
You're sure you've already installed the library or dependency or whatever, but in a different path from the standard one (in this example I'm talking about PostgreSQL installed via the graphical installer instead of the ubuntu apt repo); so you issue the command

gem install pg -v0.9.0 --with-pg-dir=/opt/PostgreSQL/9.0

And you get this error message: invalid option: --with-pg-dir=/opt/PostgreSQL/9.0

What's the problem? You need to separate options with another pair of dashes:

gem install pg -v0.9.0 -- --with-pg-dir=/opt/PostgreSQL/9.0

And everything will work.

giovedì 30 settembre 2010

Format the results of a MySQL query like MySQL! In Rails!

It may happen that you need to display the results of a MySQL query on a page. E.g., your customer asks you to add a report on a page, and you don't want to build a custom template, but just write the query and see the results.

We can do this easily thanks to the terminal-table gem (see http://github.com/visionmedia/terminal-table). This gem allows printing an ASCII table, just like the one you see when you use MySQL from the terminal. Look at its page on GitHub to see how easy it is.

To integrate it with MySQL and Rails, we can use ActiveRecord::Base.connection.execute("some_sql_query"). This method extracts the result of our query to a Mysql::Result object, which consists of a set of hashes with the results of the query. We can navigate through this hashes iterating over the all_hashes method, and throw these results into a table. Here's the code:



So all we need to do is include our module and call the method print_results_of_query. Look at this example in script/console:



All you have to do if you want to put this in a page is wrap it into <% and %> markers in your .html.erb template. Have fun!

venerdì 2 luglio 2010

SCREENCAST REVIEW - Vim for Rails Developers, by Ben Orenstein

(link: www.codeulatescreencasts.com)

In the last months I've been working on a Rails project in an Agile team. I worked mostly on TextMate, and its speed is really amazing. It has a full set of features, with snippets, bundles, syntaxes and so on. It has many shortcuts, and apparently there's no need to switch away from TextMate.

But, it has its drawbacks: it's a Mac only application, so I can't use it on my Linux box. Also, it's a commercial application, and even if its cost is not too high, I don't like to pay for software. Finally, it's a GUI application, and it cannot be used over SSH to work on a production machine.

VIM always looked like the perfect answer to these needs - but yet, getting the productivity I reached after one full year of TextMate requires some time. Every time I tried using VIM for some serious work, I ended up discouraged, because even the most basic stuff like file navigation and launching tests took ages, compared to the snap of fingers of TextMate.

I always like to challenge me though, so when I saw this screencast by Ben Orenstein I immediately decided to give it a try. And yes, it was a good decision!

The screencast begins with some general hints about typing speed, keyboard layouts and Dvorak keyboards. Even if it may not look strictly related to the main subject of the screencast, I appreciated this part, and I think many people will find it useful.

Then the video moves on to the vim-rails plugin by Tim Pope and highlights its main functionalities. Here you'll see clearly how this screencast is mostly intended to tell "stuff that matters" instead of just giving a plain list of features that you'll never use in ages.

In this section, the screencast shows how to launch tests, navigate between files, and execute Rake commands directly from your VIM session. I think this plugin has really a lot of features, too many to be covered in this screencast; Ben managed to make a good choice, selecting the fundamentals you'll use everyday.

Another amazing plugin is Snipmate: it allows to insert snippets of code by just inserting a few characters and hitting TAB. Ben quickly overviews it and shows its use - another must-have for TextMate aficionados like me ;)

After this follows a section about ctags and their integration with Rails and VIM. This is also really useful, and combined with rails-vim it provides a quick way to navigate between project files.

Finally, there's an overview of ACK - a grep replacement, focused on ease of use and speed - and its simple VIM integration. I'm also using Ack.mate, so I already knew it, and it's one of those tools you feel the lack of when you don't find it installed.

Before ending the screencast, Ben also shows an overviews of single commands and configurations that he finds particularly useful. Again, they're being selected with usefulness in mind, so you'll end up with that "Wow, I need to try these now!" wonderful sensation.

What else can I say? The screencast is well done, has a nice music, a simple and clean layout and it's spoken in a clear English ;) This should be obvious but I've found a lot of screencasts with crazily fast voices, so it's not so obvious :)

To improve this screencast, I have nothing to say about its content: it's really great! I would only add some OSD with keys when key combinations are being explained, so that it could be even simpler to memorize them.

I would definitely recommend this to any Rails developer wanting to try VIM, or to any VIM user who is starting to code Rails and wants to boost his productivity. It has a good amount of tricks and hints that can be useful both for the VIM neophyte and the VIM master starting a Rails project.

venerdì 14 maggio 2010

TextMate Syntax Highlighting Howto: A simple todo list

Today I wanted to add a syntax highlight for my todo list favourite format to TextMate.




Here's how to do it. In TextMate, go to Bundles, then Bundles Editor, then Edit Languages...



Click on the plus button in the lower left corner and choose "New Language". Paste the following code in place of the example code provided.





This defines three patterns for each condition. They should be self-explanatory, I used only simple regexps here. Save your language definition, and it should appear in the languages combo of your Textmate.



To complete syntax highlighting, you also have to add the colors to your current textmate theme. In the application menu, go to Textmate, then Preferences, then Fonts & Colors. For each pattern name, click the plus button and create a new element. It must have the pattern name as scope selector. Choose colors as you like.






References:

Textmate help
Mac Dev Center

venerdì 23 aprile 2010

Ruby Mixin and monkey patching examples

Let's explore a couple of solutions to dynamically add a split_by_half behaviour to an array object. The first technique is the mixin: it allows to add the method to a single array instance. The second one is called monkey patching, and adds the method directly to the Array class, adding this behaviour to every array instance.


lunedì 12 aprile 2010

Script to download the latest Chromium build for OSX

lunedì 22 febbraio 2010

The way we plan

In our Agile team, we have iterations lasting one week, and we plan our work every Monday morning. Our customer comes to our office, we gather around a table, and we watch the project backlog to choose the new stories to be worked in the current week.
For the majority of the User Stories, we already have an estimate made at the beginning of the project. This estimate has been made in Story Points, and sometimes it's really inaccurate, because when we started our project some features looked really different to our eyes; so, we have to re-estimate these stories. For this we use another measuring unit, the Pomodoro (look here if you don't know what I'm talking about).
After these estimates, we decide with our customer which user stories are to be worked in the current iteration, trying to balance the business value and the stories costs. We plan stories to fit our work capacity for the iteration (e.g., 3 developer pairs work each 10 pomodori per day, so in a week we can plan 150 pomodori/pair).
Of course, when we discuss features with the customers, some new stories may be introduced, some could get splitted, and some others delayed for future releases.

There's something wrong with this. First of all, estimating in Pomodori needs a lot of deep analysis to be made to get to an accurate estimate. This slows the estimating process a lot, because we end up talking about implementation details. Of course our customer gets bored soon, as he's not a technical customer. We introduced this way of estimating after the first iterations of the project, because we were estimating using Story Points, and we were having a very low accuracy; later, we never tried to switch back to Story Points, even if now our accuracy could have improved. Just to mess things up, we also use a "fake" Story Point measuring, obtained just multiplying pomodori by 10. So we estimate 10 pomodori, and we write 1 story point. Using the Real Story Points could speed up our planning work a lot, because we could step up by an order of magnitude, and estimate user stories comparing them with the ones already worked.

Another problem we are having is that we're splitting stories too much. We're following a rule of thumb, like "no stories bigger than 2 points". Such a rule had been voted in a retrospective, after a couple of weekly fails. We had some big stories (like 4 points stories) not being accepted by our customer because of minor issues; so we decided to split them up, to minimize the impact of a rejected user story on the iteration score. The wrong thing with this approach is that we're just changing the way of measuring our system to obtain better measures. Think about it: an iteration ends, and you discover a bug during the demo. Of course you'll have to fix it in the following iteration, and of course this will cost you some additional work. If the iteration scores are 2-10 or 5-7, nothing changes in the system; you still would need to do some additional work. The only thing changing is a couple of numbers written on a spreadsheet. Also, different iteration scores would impact only on the short term velocity, and would instead have no effect on the long term velocity. The short term measure gives no confidence and is much less important than the long term one, so there's no need of getting better short term results. This "hack" on measuring, in our case, is also introducing new problems. We spend time thinking about ways to correctly split stories, we introduce unneeded dependencies and we get to stories which are really difficult to demonstrate to the customer.

giovedì 3 settembre 2009

Some ActiveRecord fun

Many of you have already used has_many and belongs_to Active Record relationships. This is really easy to do when you have a single attribute to map; like, in example, an Article with many Comments. You’d write something like


class Article < ActiveRecord::Base
has_many :comments
...
end



class Comment < ActiveRecord::Base
belongs_to :article
...
end

Combining these declarations with a article_id column in your comments table would allow you to:



  • access all the comments of an article with article.comments

  • access the article a comment belongs to with comment.article


There are situations, however, when things get a little more tricky. Think about this example: you have a Movement object, which identifies a cash flow between two Accounts. You also have an accounts table; so, in your movements table, you would add columns like from_account_id and to_account_id.


How can this be mapped with ActiveRecord? We need to write two belongs_to declaration, this way:


class Movement < ActiveRecord::Base
belongs_to :from_account, :class_name => "Account", :foreign_key => "from_account_id"
belongs_to :to_account, :class_name => "Account", :foreign_key => "to_account_id"
...
end

This tells ActiveRecord that the movement class must reference two Account objects. One is accessed with movement.from_account and the other with movement.to_account.


You can do the same thing for your Account class:


class Account < ActiveRecord::Base
has_many :movements_out, :class_name => "Movement", :foreign_key => "from_account_id"
has_many :movements_in, :class_name => "Movement", :foreign_key => "to_account_id"
...
end

This way, with account.movements_in, you can get all the cash flows to the account, and with account.movements_out all the cash flows going out of the account.


Plain and simple! :)

sabato 15 agosto 2009

Autospec for Rails + libnotify on ubuntu howto


Hallo! After a couple of hours of work I finally managed to get autospec popup notifications on my ubuntu machine. Now I can start autotest in the background, and whenever I save a file into my project folder, after a few seconds I receive a notification message on my desktop about the tests.
Here are the steps to get the same result:

  1. install the required gems (ZenTest, and obviously rspec and rspec-rails);
  2. sudo aptitude install libnotify-bin;
  3. edit the file .autotest in your home folder (I said home, not the root of your project!) with the content from this link: https://gist.github.com/840314
  4. save the two pictures rails_ok.png and rail_fail.png from http://blog.internautdesign.com/2006/11/12/autotest-growl-goodness and put them into your ~/Pictures/rails folder.
At this point you are supposed to only run autospec in your project root folder, save a file and see a notification like the one at the top of this article! Happy BDD!

domenica 9 agosto 2009

Building a pronounceable password generator in Ruby

Heya guys! Today I tried to build a pronounceable password generator. To keep it simple, I started from a simple concatenation of words - in my case, italian words. This is really easy, but you'll see that results will be very good.

I took a list of italian words from this site: Italian dictionary and affix file for ispell. It's a good choice because ispell dictionaries are prepared to be declined; concatenating two words without suffixes will give good results for pronounceability.

Before proceeding, however, I needed to narrow the words list:

I removed the ispell affix definitions, to get words like "abaco" instead of "abaco/G":
cat italian.words | sed 's/\/[A-Z]*//g' > parole.txt
I removed all words containing capital letters, like "Yamaha", "Windows", and "Acicastello":
cat parole.txt | sed '/[a-z]*[A-Z][a-z]*/d' > paroleNoCapital.txt
Finally, I sedded out some cuss words - not writing them here, for the sake of decency! :)

I was then ready to write the following ruby script:

def genera_pass_da(parole, n = 2)
how_many_words = parole.size
word = ''
1.upto(n) do
word += parole[rand(how_many_words)].chomp
end
word
end

file = File.open("parole.txt")
parole = file.lines.to_a.select { |word| word.size < 7 }
1.upto(10) do
puts genera_pass_da parole
end
Even if it's far from being polished and optimized, launching this gives a good set of pronounceable passwords. They're all lowercase and without numbers - so probably not the best choice for your remote banking account - but still ok for other uses. Here's a shot:

metalelf0@eagleone$ ruby rapg.rb
uditovoi
vammimidi
gechitua
dareisisma
ecoivi
ancabatto
unotacca
fangopupe
apesella
bemasire
Someday I'll improve it by adding numbers, some capital letters, customizing choices and so on - but many friends are yelling me that it's sunday and I need to go out, so... see ya soon!

domenica 28 giugno 2009

Shared pomodoro part II


Last month I posted an article about the Shared Pomodoro, a shared timer for all the members of an Agile team. By sharing a common timer, all the team members can have pauses at the same time; so, there's nobody hanging around speaking or joking when someone else is working.

We are trying to apply this in our Agile team, without much success. The main area of debate is focused on pauses: a lot of times the developers keep working for 1-2 minutes after the ring of the timer, and then they want to take a 5 minutes break like their team partners. But in a shared timer environment, this is not possible. Shared pomodoro should also mean shared pauses.

Also, when somebody is on a difficult task at the end of a pomodoro, and wants to finish it before having a pause, it's common that he needs more focus and concentration. This is really difficult if the other developers are pausing, and talking loudly in the same room.

Another problem we had with pauses was that they sometimes extended after 5 minutes.
In our latest retrospective, a week ago, we decided to ban the usage of personal laptops during the 5-minutes break, to remove on of the most common sources of oversized pauses. However, some of the pauses lasted more anyway, because somebody was going out of the room to get a snack, smoke a cigarette, go to the toilet and so on.

Personally, I don't think that forcing all the team members to finish exactly at the same time and start over exactly at the same time could be more productive than leaving each couple free to take its own rhythm. If a couple works 28 minutes and then takes a 5 minutes pause, they're not working less than a couple doing 25-5. But I think that the couple working 28 minutes still needs a 5 minutes pause, and it wouldn't be correct to force them to a 2 minutes pause just to keep the shared pomodoro rhythm alive. I know that the strict application of the Pomodoro Technique would prohibit any work after 25 minutes, but in my experience I think this doesn't compromise the technique effectiveness too much. After all, the technique leaves space for flexibility in the pauses duration (both short and long pauses), so even applying it strictly could lead to not synchronized couples.

I've read on the Pomodoro Technique official mailing list (http://tinyurl.com/l55un2) that some other teams tried using a shared pomodoro without much success. At this point, I think the best solution is having a pomodoro for each couple. It has its downsides too, but IMHO they can be overcome much more easily.

giovedì 21 maggio 2009

Don't leave juniors on the bench


Recently I've read many articles about how to choose the best junior developers, and how to train them. This is an hot topic for project managers, as they need to have good and cheap developers: usually, this also means "young" developers.

I still haven't found any article, though, approaching this subject from a psychological point of view. Typically, these writings are about technical training, or maybe about how to productively insert a junior resource into a team: but not about how to make the junior motivated to give everything for the project.

I think it's a really different situation from inserting an already expert developer into a team. A young developer still needs to understand almost everything about team work, daily planning, and so on. Sometimes universities don't give them any hint about the situation they'll find in a real work place, so it's time for them to find out. I suggest, let them find out the hard way.

A young developer needs to be involved in all the team activities. He really should be able to write a lot of code, discuss planning, design and so on, since the start of his work in the project. In an agile team, this means that he should write code at least as often as he drives his pair; he should be able to speak while the team writes down user stories, and participate actively to retrospectives.

Don't care too much about the impact this could have on both the developer and your team: in the worst case, you'll have a small loss of productivity, but we'll discuss this in detail later in this article.

I think a good analogy can be done with football. Yeah, I wrote football - after all, it's a team game, where the cohesion between all the team members is important to achieve success.

In a football team, as players get old, young players come in, and they need to be inserted into the first team. This process can be really difficult, no matter how good the young players are: for a coach, leaving the 33 years old world-class striker on the bench and throwing the 17 years old promise on the field, could result in both a success or a failure covered with critics.



However, if you ask any football coach what's the best way for young players to improve, they will answer the same: experience. They need to *play*. A young player, if left on the bench, can not grow, even if he has the chance to train with the best footballers in the world. He needs to feel the adrenaline of important matches, receive the ball and face the toughest opponents.

Going back to our junior developer, it's exactly the same situation. If you want him to improve, you must not leave him on the bench, thinking that time will help him.

Such a cautious and mild approach could result in a demotivated young resource, compromising both his morale and his productivity. Also, you'll need a lot of time to evaluate his real skills.

You should let him code, even if he's half as fast as your other developers, and hear his opinion about the practices of your team. Involve him in all the team activities, and try to teach him what he needs to start working with your team.
Obviously, this can be done only if he has at least some basic skills, but choosing the best young resources is another topic - I won't dwelve into this right now.

Maybe you'll realize he's such a good developer that after some weeks he'll be perfectly inserted in the team, contributing interesting ideas and giving a productivity boost, but even if this takes more time, it's the right thing to do.

Such a steep approach is obviously not productive in the first weeks, but as time goes on, you'll be able to evaluate better not only the technical skills of your junior, but also his resistance to pressure and work load. These characteristics are as important as the technical skills, maybe even more, so finding them out is definitely useful.

lunedì 11 maggio 2009

Shared pomodoro - to share or not to share?

Last week a very interesting discussion emerged in our Agile Team. We are 10 developers, and we all work in the same room. We use the popular "Pomodoro Technique", conceived by Francesco Cirillo, to organize our daily work. If you have never heard about it, visit www.pomodorotechnique.com; shortly, its main characteristic is that it divides the daily work into very small iterations called pomodori, all of 25 minutes, separated by regular pauses of 5 minutes.

The technique works really well; we had some discussions about the nature of timers - somebody loved the kitchen mechanical ones, somebody else was irritated by their ringing sound and preferred software timers. But apart from this, there were no problems.

A month ago, we added two couples of developers to our team. The new guys came from another popular Agile team, and they proposed the idea of a "shared pomodoro": an unique timer being shared by the whole team. The Pomodoro Technique defines clearly how to setup work iterations and pauses, and it's also really strict about the need of stopping work exactly after 25 minutes; so, there's no reason for not synchronizing all the developers.

Before this fact, we didn't follow the technique too strictly; somebody prefered to work for 50 minutes and take a longer pause thereafter; others used pomodori just to track their work, without caring too much about pauses duration.

As you can imagine, the shared pomodoro is quite difficult to apply in such an environment.

Let's try to summarize briefly the advantages of a shared pomodoro:

- pauses are shared too, so the whole team can have a pause together;
- when you're working, everybody else is working too; so, you don't have distractions from other people having a pause;
- there's more discipline: all the developers have to keep the same rhythm, even if they're tired;
- the team actually behaves like a team, and this common practices may increase the cohesion between the team members.

The disadvantages of the shared pomodoro are almost symmetric:

- if you *really* need to take a pause, for any reason, you break the team rhythm;
- if you want to work for more than 25 minutes without a pause, you can't;
- every time there's a pause, the whole team has to wait for all the team members coming back to the open space (but hey, this is called discipline!);
- the team behavior looks more chaotic, and it's more difficult to organize common activities.

So it's mostly a choice between discipline and relaxed rules. It's not easy to choose which solution is the best for you, or which one will give you more productivity. The author of the pomodoro technique, Francesco Cirillo, reports that studies have been made to find the maximum time a human brain can keep concentrated on a single subject, and the average value found out is 25 minutes. So, if his theory is right, following the technique strictly is the best way to keep concentrated, work better and consequentially improve productivity.

Enough said? Not exactly. In the previous statement, there's an important word: "average". This means that the "25 minutes" value is not the same for everyone, or for any situation. Sometimes it may happen that you work on a really hard subject, and after a pomodoro of work you need a slightly longer pause, because you're tired; some other times, you're feeling a good rhythm, with many tests passing, and you want to take a shorter pause. This kind of behaviour is definitely not compatible with a shared pomodoro.

If you want to decide whether a shared pomodoro is right for your team, try to ask your team members how confident they are with the rhythm described by Francesco Cirillo. If they're already using the technique strictly and they feel confident with it, you can try out the shared pomodoro for a month or so, and then decide whether yo keep it or not. Otherwise, you can try to tend to it, if you feel that your team is too chaotic.

The only approach I find not correct is imposing a shared pomodoro from above, without asking any opinion to the team members. This may lead to unhappy team members, cause they could feel their freedom and creativity is constrained by a timer. If all of your team members feel like this, maybe you should put the shared pomodoro apart - or find other team members! :)

giovedì 25 settembre 2008