Skip to content

Feed aggregator

Manage Agile, Berlin, Germany, October 27-30 2014

Scrum Expert - Mon, 10/13/2014 - 17:32
Manage Agile is a four day conference focused on Agile management topics – no pure technologic aspects. The Manage Agile conference is a networking platform where specialists and managers discuss agile topics not only in software engineering but also in the whole company up to the management. The conference is divided into two workshop days and two conference days. Most of the presentations are in German, but you will also find English content. In the agenda of Manage Agile you can find topics like “The roots of Agile and Lean in ...
Categories: Communities

Xebia KnowledgeCast Episode 5: Madhur Kathuria and Scrum Day Europe 2014

Xebia Blog - Mon, 10/13/2014 - 11:48

xebia_xkc_podcast
The Xebia KnowledgeCast is a bi-weekly podcast about software architecture, software development, lean/agile, continuous delivery, and big data. Also, we'll have some fun with stickies!

In this 5th episode, we share key insights of Madhur Kathuria, Xebia India’s Director of Agile Consulting and Transformation, as well as some impressions of our Knowledge Exchange and Scrum Day Europe 2014. And of course, Serge Beaumont will have Fun With Stickies!

First, Madhur Kathuria shares his vision on Agile and we interview Guido Schoonheim at Scrum Day Europe 2014.

In this episode's Fun With Stickies Serge Beaumont talks about wide versus deep retrospectives.

Then, we interview Martin Olesen and Patricia Kong at Scrum Day Europe 2014.

Want to subscribe to the Xebia KnowledgeCast? Subscribe via iTunes, or use our direct rss feed.

Your feedback is appreciated. Please leave your comments in the shownotes. Better yet, send in a voice message so we can put you ON the show!

Credits

Categories: Companies

Design Thinking für Product Owner – Teil 5: Wie entstehen eigentlich gute Ideen?

Scrum 4 You - Mon, 10/13/2014 - 07:30

Unser Gehirn vermag Erstaunliches. Wie wäre es, wenn wir mehr von diesem Potential zur Problemlösung nutzen würden? Sicher haben auch Sie schon den Spruch gehört: “Kreative arbeiten am stärksten, wenn es aussieht, als ob sie gar nichts täten.” Und tatsächlich ist da etwas dran!

Im Business-Alltag herrscht die analytische Denkform. Wenn es aber darum geht neue Lösungen zu finden, ist es ratsam, auch in andere Denkformen vorzustoßen. In unseren Design-Thinking-Trainings für Product Owner und ScrumMaster wird beispielsweise die Ideenfindung vom Mittagessen unterbrochen: Die Teilnehmer haben sich 30 Minuten intensivem Brainstorming hingegeben, ihr analytisches Denken hat die meisten Ideen und Lösungsmöglichkeiten bereits hervorgebracht, diese warten auf bunten Haftnotizen an der Wand. Der Strom der Ideen versiegt langsam. – Pause -

Wir schalten die analytische Denkform absichtlich ab, aber Sie können sicher sein, dass die Gedanken im “Hinterkopf” weiter kreisen. Gemeinsam oder auch einzeln gehen wir essen und die Bedingung ist, dass jeder einen Block Haftnotizen und einen Stift in der Tasche hat. Und nun passiert Erstaunliches: Die Teilnehmer haben die Gelegenheit, ihre Aufmerksamkeit in die Bereiche der Reflexion, der Inspiration oder auch des Loslassens gleiten zu lassen. Nach der Mittagspause beginnen wir mit einem Team-Resync, d.h. wir nehmen uns 15 Minuten Zeit, um neue Ideen und Einsichten zusammenzutragen. Erfahrungsgemäß bringt hier mindestens die Hälfte der Teilnehmer noch einmal sehr wertvolle Impulse in ihr Team: “Ich habe da draußen etwas gesehen, da habe ich mich erinnert, dass…” oder “als ich noch einmal in Ruhe darüber nachgedacht habe, habe ich gemerkt, wie wichtig mir dieser Aspekt ist” oder “ich habe gar nicht daran gedacht, aber plötzlich hatte ich die Idee …”.

Analyse, Inspiration, Reflexion & Loslassen

Werfen wir nun noch einen genaueren Blick auf diese vier Denkformen und betrachten wir das Two-by-Two Diagramm für die Aufmerksamkeit. Die horizontale Achse reicht von eng (links) bis weit (rechts), die vertikale Achse reicht von innen (unten) bis außen (oben). Damit ergeben sich vier Bereiche.

Design Thinking & Change Management Flipcharts

Aufmerksamkeit eng und nach außen gerichtet: Die Analyse

Hier bewegen wir uns i.d.R. im Business-Umfeld. Diese Denkweise ist anstrengend und wir halten das maximal 1,5 Stunden aus, danach sinkt unsere Leistungsfähigkeit rapide ab. Die Analyse ist geeignet, um sich initial mit einer Fragestellung zu befassen und ein Grundverständnis zu schaffen. Sucht man jedoch auf diese Art nach einer Lösung, wird man nur selten eine Innovation finden.

Aufmerksamkeit eng und nach innen gerichtet: Die Reflexion

In diesem Bereich bewegen wir uns, wenn wir über unsere Prioritäten und persönlichen Ziele nachdenken, wir zapfe unser Wissen und unsere Erfahrung an. Dieser Bereich ist wertvoll, um beispielsweise allein einen Stapel generierter Ideen zu bewerten und diese Ergebnisse später mit anderen zu teilen.

Aufmerksamkeit weit und nach außen gerichtet: Die Inspiration

Hier bewegen wir uns seltener, denn nun kommen unsere Vorstellungskraft und die Erlebniswelten anderer Menschen ins Spiel. Die Business-Welt hat Angst vor diesem Bereich, weil er nicht berechenbar und planbar ist. Viele Kreativtechniken probieren hier in den Raum des Denkbaren vorzustoßen. Gelegentlich müssen diese Vorstöße ganz sanft passieren, weil sich viele Menschen auf für sie unsicheres Terrain begeben. Ein Besuch beim User führt beispielsweise Software-Entwickler oder Ingenieure in den Bereich der Inspiration: “Nur mal ganz kurz … wir kehren gleich zurück … nur mal ganz kurz raus, da hin wo der User ist … nur mal ganz kurz nicht an die Machbarkeit denken … und dann hopp, hopp, schnell zurück.” Es ist immer wieder erstaunlich, wie viele Einsichten und Ideen von solchen Ausflügen mitgebracht werden.
Eine andere, noch komfortablere Methode, um in den Raum des Denkbaren zu gelangen, ist die Verlagerung der Frage an andere Orte oder Zeiten: “Wie würde Supermann das lösen? Wie würde das auf der Enterprise oder im Mittelalter aussehen?”

Aufmerksamkeit weit und nach innen gerichtet: Das Loslassen

Dies ist ein defokussierter Zustand, hier werden Metaphern und Witze verstanden. Es ist ein Bereich, der meist komplett ignoriert wird. Wer ihn allerdings entdeckt, kann beobachten, wie sich Lösungen ganz von selbst im Kopf materialisieren – meistens dann, wenn man es eigentlich gar nicht erwartet. Mancher Mensch kann diesen Zustand nach jahrelangen Meditationsübungen schnell herbeiführen. Mir gelingt es manchmal nach dem Sport unter der Dusche, wenn der Körper ermattet dasteht, Wasser über meinen Kopf fließt und meine Gedanken mit dem Wasser treiben. Gelegentlich “erwache” ich aus diesem Zustand und habe das dringende Gefühl, eine Art “Eingebung” aufschreiben zu müssen.

Integration ins Unternehmen

In Unternehmen ist es i.d.R. nicht einfach, den analytischen Bereich zu verlassen. Andere Denkweisen zu erkunden braucht Zeit und Raum! Außerdem vereinheitlicht die Unternehmenskultur die Denkweise von Mitarbeitern. Tradition und Gewohnheit verhindern den Blick über den Tellerrand. Und genau deshalb sind “Kreative” auch oft gerade dann produktiv, wenn man es ihnen nicht ansieht. Denn Sie haben Wege gefunden, sich mit Ruhe den anderen Denkweisen hinzugeben.

In der Innovationsarbeit gilt also:
Raus aus der Routine -> Sondersituation schaffen -> Rückführung in den Alltag

Dieser Prozess braucht eine professionelle Begleitung. Eine schnelle und günstige Lösung sind daher Coaches von außen, zumal Innovation auch immer eine Schleuse von außen nach innen benötigt. Aber auch die Schnittstellen in dieser Kette sind kritisch. Die Überführung von Wissen benötigt eine interne Konstante. Diese Konstante ist im besten Fall der Product Owner.

Tipp: Mit den unterschiedlichen Arten der Aufmerksamkeit können Sie in unserem Training “Produktfindung mit Design Thinking” experimentieren. Alle Informationen und Termine gibt es hier.

Design Thinking für Product Owner – Teil 1: Was ist eigentlich Design Thinking?
Design Thinking für Product Owner – Teil 2: Das Design-Thinking-Team
Design Thinking für Product Owner – Teil 3: Des Design-Thinking-Raum
Design Thinking für Product Owner – Teil 4: Der Design-Thinking-Prozess

Related posts:

  1. Produktfindung mit Design Thinking
  2. Design Thinking für Product Owner – Teil 1: Was ist eigentlich Design Thinking?
  3. Design Thinking für Product Owner – Teil 2: Das Design-Thinking-Team

Categories: Blogs

Hungarian Notation for Teams

Agile Tools - Mon, 10/13/2014 - 07:04

SONY DSC

Back in the day when I was writing windows programs there was this thing called hungarian notation. It was a form of shorthand that allowed you to add the type of a variable to the name of the variable. It led to variable names like “lpszUserName” that stood for “long pointer to a zero terminated string named UserName.” It made for some pretty awkward variable names, but the idea was that you could always tell the type of the variable, even if you couldn’t see the declaration. It was kind of handy, at least until somebody changed the variable type and forgot to change the name. In hindsight, it really was always doomed to fail for almost any kind of legacy code. Name the variable wrong and you introduce subtle bugs that will haunt you for years.

So there we are looking at a list of teams the other day. They had a lot of interesting things in common. They all have some specialization in a given domain. Often they had different geographic location. We were wondering if perhaps they should have some sort of naming convention applied to their names. That’s when I perked up and said, “Hungarian notation for teams!” If the team is located in Bellevue, then we will use ‘bv’. If the team is in the mobile domain, we’ll use ‘mb’. So for a team named “Viper” located in Bellevue doing mobile development we would have “bvmbViper!” Maybe you have a team that is located in San Francisco ‘sf’ that works on web apps ‘wa’ called “Cheetah” we would have “sfwaCheetah.” Now you can simply look at the name of your team and know instantly where they work, and what they work on.

Genius! Maybe we should do this for people too? I’m an Agile manager ‘am’ who writes a blog ‘bl’. You can call me “amblTomPerry”


Filed under: Agile, Humor Tagged: hungarian notiation, name, notation, Teams
Categories: Blogs

Building the Agile Culture you want

When some organizations think of going Agile, they tend to gravitate toward applying a set of Agile practices.  While this provides insight into the mechanical elements of agile, these types of implementations tend to overlook the cultural elements.  A move to Agile implies that you make the cultural transformation to embrace the Agile values and principles and put them into action. 
Adapting an organization's culture is effectively an effort in change management.  And changing a culture is hard. People underestimate the difficulties of a culture change within their organization because it involves the cooperation of everyone. This is why some organizations avoid this.  But the business benefits can be tremendous. I have seen Agile efforts get started with poorly stated objectives and motivations, a lack of employee ownership or engagement, and a lack of thinking through the effort. Also, Agile journeys significantly benefit from education in both change management and agile techniques to achieve a meaningful cultural change. I have seen companies assign a member of senior management as the change agent, yet they have neither education nor experience in change management. A better approach may be to hire an Agile Coach with change management and Agile experience.
Creating or adapting a culture is not done by accident. It must be considered a change initiative and thought through. As part of readiness of deploying Agile, start the process of adapting to an Agile mindset and the culture you are looking for. What are some activities that will help you move to an agile culture?  Some include:
  • Recognizing that moving to Agile is a cultural change (it’s a journey)
  • Sharing and embracing the Agile values and principles (seriously folks!)
  • Moving to an end-to-end view of delivering value (don’t stop at just the build portion)
  • Adapting your governance to focus on value (enough with the cost, schedule, and scope!)
  • Evaluating employee willingness (employees are your brainpower!)
  • Gaining continuous feedback from customers (adapt toward customer value)
  • Adapting the reward system to align with the new culture (toward team and value)
  • Assessing executive support (build engagement along the way)

What other activities would benefit you in getting to an Agile culture?  Ultimately you want to start living the values and principles that help you develop the culture you are looking for.  As you have approached Agile in the past, how much of it was focused on the mechanics and how much was focused on adapting to an Agile culture? 

PS - to read more about really making the shift toward an Agile culture, consider reading the Agile book entitled Being Agile.  
Categories: Blogs

correction: Agile HARDWARE ....

Agile Scotland - Sun, 10/12/2014 - 20:08
I forgot the word HARDWARE in the last email.  I'm losing it ...

Great news! Agile Engineering expert, Nancy Van Schooenderwoert is over in Scotland again and is giving a seminar on the evening of the 30th of October on Agile Engineering. It's at Glasgow Caledonian University.
http://www.eventbrite.co.uk/e/agilescotland-agile-hardware-development-tickets-13660303335?utm_campaign=new_eventv2&utm_medium=email&utm_source=eb_email&utm_term=eventname_text

Clarke
Categories: Communities

[AgileScotland] Agile Engineering seminar - Glasgow Caledonian University - 30th October, start 7pm

Agile Scotland - Sun, 10/12/2014 - 20:00
Great news! Agile Engineering expert, Nancy Van Schooenderwoert is over in Scotland again and is giving a seminar on the evening of the 30th of October on Agile Engineering. It's at Glasgow Caledonian University.
http://www.eventbrite.co.uk/e/agilescotland-agile-hardware-development-tickets-13660303335?utm_campaign=new_eventv2&utm_medium=email&utm_source=eb_email&utm_term=eventname_text

Clarke
Categories: Communities

Building Glass Houses: Creating the Transparent Organization

Agile Tools - Sun, 10/12/2014 - 07:54

blur-city-drops-of-water-871-733x550

Visual management occurs at many levels. There is personal transparency: the ability for people to see what you are working on within the team. Then there is team transparency: the ability for stakeholders and other teams to see what the team is working on. Finally, there is organizational transparency: the ability for people within and outside the organization to see what the organization is working on. Ideally, we have all three levels of transparency fully developed in an Agile organization.

Individual transparency consists of the ways in which we communicate the state of our work to the team. We can use both active and passive mechanisms to achieve this. Active mechanisms are things like using one-way broadcast like yammer, or just shouting out when you need help, achieve victory, or otherwise want to share with the team. Then there is two-way broadcast like the status in the daily standup, one-on-one communication, working meetings like the planning and demo. Passive mechanisms include updating things like task boards, wiki pages, and status reports. All of this information is primarily directed at the team.

At the team level there are active and passive mechanisms for communication. There are burn down charts, task boards, calendars, which are all passive. Then there is the active communication that takes place at the scrum of scrums and other larger forums where multiple teams and stakeholders meet. I’ve often seen teams struggle to get information out at this level. They tend to do really well at the individual level, but at the team level it is not uncommon to find that teams aren’t getting enough information out beyond their own boundaries.

Finally at the organizational level there are active and passive mechanisms for communication as well. There are passive communication mechanisms like annual reports, company web pages, intranets, and billboards in the coffee room. There is also active communication at company meetings, and…often not much else. This is an area where as Agilists we need the most improvement. It seems as though the communication demands get more challenging the higher up the organization that you go.


Filed under: Agile, Coaching, Lean, Process Tagged: information radiators, transparency
Categories: Blogs

Selling Agile Contracts Slides from Agile Philly 1/2 Day Event 10/6/2014

Agile Philly - Sun, 10/12/2014 - 04:30

Hi All.

Noticed that the Dropbox link to my preso in the mail John circulated was broken so...

I renamed the preso to remove spaces, posted the thing on slide share, and create a tiny URL so you can get to it easy!

Enjoy: http://tinyurl.com/agile-contracts

I really enjoyed sharing this with the group. Please do not hesitate to contact me if you have questions or just want to discuss. I am definitely…

Categories: Communities

BDD Using Cucumber JVM and Groovy (video)

TestDriven.com - Sat, 10/11/2014 - 21:47
BDD Using Cucumber JVM and Groovy
Categories: Communities

Uh Oh... We Discovered More Stories!

Practical Agility - Dave Rooney - Sat, 10/11/2014 - 18:00
As I've said before, I'm a huge fan of Jeff Patton's Story Mapping technique. While Story Mapping goes a long way towards identifying the work that needs to be completed to deliver a viable system, you will inevitably miss some stories. This is a natural outcome of the discovery process that is inherent to software development. When you discover that some functionality is missing or
Categories: Blogs

Codea Calculator II

xProgramming.com - Sat, 10/11/2014 - 15:39

Ignatz and Jmv38 on the Codea forums commented on the previous article. I had hoped to do more anyway so here’s the next one.

Note that this article is different from what it might have been, because I’ve had conversations with other programmers looking at (working with) the code. This isn’t bad, it’s good. It’s like pair programming without all the travel. Be aware, though, that many of the “discoveries” in this article have already been discovered. There’s a long note on the forum replying to their comments. This article will follow that note’s line of reasoning, but I plan to rewrite it rather than copy and edit.

Because that’s what I do.

GUI

Ignatz and Jmv38 talked about why I hadn’t built the GUI and whether I should. I plan to do so, but this isn’t that article.

It’s worth mentioning here that I find GUIs hard to test, so I like to write really solid “model” objects, test the heck out of them, and then write thin GUIs where “nothing can go wrong”. Or at least very little.

Even so, some testing is probably needed, and I think we’ll discover that in the GUI article when I get to it.

Duplication

There is significant duplication in the calculator as it stands. Take a look:

    function Calculator:press(key)
        if key == "*" then
            self:doPending(function(d,t) return d*t end)
        elseif key == "/" then
            self:doPending(function(d,t) return t/d end)
        elseif key == "-" then
            self:doPending(function(d,t) return t-d end)
        elseif key == "+" then
            self:doPending(function(d,t) return t+d end)
        elseif key == "=" then
            self:doPending(nil)
        else
            if self.first then
                self.temp = self.display
                self.display = ""
                self.first = false
            end
            self.display = self.display..key
        end
    end

There are four or five if statements, checking a key and then doing a do-Pending. And inside each doPending there is a function definition that looks exactly the same except for the operation done inside. (I note that they all are in t then d order except the first one. That’s because I did a non-commutative operator second and t has to be first. I should change the first one to match, and I will. (I just did, and the tests all run.))

We’d like to remove this duplication. Perhaps I should stop and say why.

Why we remove duplication

I’ve mentioned some of the concerns already. If there is duplication in the code, that tells us that there is some idea, either in our mind or emerging in the code, that is not well-represented in the code. Here, the idea is “hey, all these operators are alike”.

If there is duplication and changes are needed, we have to make the changes in many places. This is tedious and error-prone.

Here’s a thing I haven’t mentioned in this series yet. Long ago, Kent Beck (creator of Extreme Programming) listed the elements of “simple code”. His list has taken a few forms but the one I prefer is this one:

Simple code:

  1. Runs all the tests.
  2. Contains no duplication.
  3. Expresses all the programmer’s ideas.
  4. Minimizes the number of programming entities: lines, classes, files, etc.

These items are in priority order.

Now if you think about these, you might think “But wait, expressing ideas might require duplication. Numbers 2 and 3 should be reversed.” Well, you might be right. If there were ever a conflict. But I prefer them in this order, because more often than not, duplication to “express an idea” really means that the code contains an idea that I have not as yet recognized. So I like to feel the conflict.

The list does come in the other order and in other forms. Find one you like and use it. I like this one.

Anyway, we’ve got this code: what shall we do about it?

Issues

I see two issues with those ifs. First of all, they are clearly very redundant. The duplication should be removed. But they are also a bit unclear: those embedded functions inside the doPending inside the then make the code tricky to read, especially since we don’t expect to see functions written in line like that. At least I don’t.

Both the following ideas come from Jmv38. We could break the functions out like this:

function Calculator.mult(d,t) return t*d end
function Calculator.divide(d,t) return t/d end
function Calculator.minus(d,t) return t-d end
function Calculator.add(d,t) return d+t end

Then we’d say, for example:

if key == "*" then
    self:doPending(self.mult)

and so on. That might be a bit more clear but still leaves us with duplication.

Maybe we would look at this and realize that there is a one-to-one relationship between the character pressed and the function to be executed. (And the function has that character in the middle of it, but I can’t figure a way in Codea to just do that. Unless I compile on the fly. No. Just no.)

So Jmv38 suggests that we build a local table, indexed by the key pressed:

local operations = {}
operations["*"] = function(d,t) return t*d end
operations["+"] = function(d,t) return t+d end
operations["/"] = function(d,t) return t/d end
operations["-"] = function(d,t) return t-d end 

Now as it happens, I didn’t realize that one could define a local table that way. It’s “obvious” when you think about how Codea works but it wasn’t obvious to me. This is why pair programming is so powerful. The other person knows stuff you don’t know and thinks of stuff you don’t think of.

We’re left with the question of how to access the table. I think I prefer this:

function Calculator:press(key)
    if key=="*" or key=="+" or key=="/" or key=="-" then
        self:doPending(operations[key])
    elseif key == "=" then
        self:doPending(nil)
    else
        if self.first then
            self.temp = self.display
            self.display = ""
            self.first = false
        end
        self.display = self.display..key
    end
end

Are you starting to wish these things were in order plus minus times divide? I am. Something in my brain wants them to be that way. I’ll fix that because what good is having a touch of OCD if you don’t give in to it once in a while?

Done, and the tests still run. I feel better now.

Now Jmv38 suggests going a step further with

local f = operations[key]
if f then
    doPending(f)
elseif key == "="
    ...

Nothing wrong with that, probably. But it does require us to look back and say “When could f be nil? Oh, if key isn’t one of those operators. Hmm …”

I don’t like things that make me go “Hmmm”. So I prefer the or. However, there are a lot of binary operators in the world, and that if could get pretty long. Jmv38’s approach extends to new operators smoothly. So it could be better. I prefer it more explicit. YMMV.

Summing up …

First of all many props to Ignatz and Jmv38 for their ideas and questions. We wouldn’t be here without them.

I’ll show the relevant code one more time below. First, the discussion. We saw more duplication, and we thought of ways to remove it. We also saw some code that didn’t express itself well. We considered ways of fixing it but (with help) we saw an approach that seemed to promise help on both dimensions. We tried it, we liked it.

But those tests!! Without those tests, I’d have been scared as hell about making a major change like a table of functions and removing all my if statements. It would be too easy to screw it up.

The tests give us confidence that when we screw up, we’ll find out before anyone else does. That’s a very good thing.

Next time, the GUI. Might be soon, might not. I’ve got a gig next week.

Current Code
--# Calculator
Calculator = class()

function Calculator:init()
    self.display = ""
    self.op = nil
    self.first = false
end

local operations = {}
operations["+"] = function(d,t) return t+d end
operations["-"] = function(d,t) return t-d end
operations["*"] = function(d,t) return t*d end
operations["/"] = function(d,t) return t/d end

function Calculator:press(key)
    if key=="+" or key=="-" or key=="*" or key=="/" then
        self:doPending(operations[key])
    elseif key == "=" then
        self:doPending(nil)
    else
        if self.first then
            self.temp = self.display
            self.display = ""
            self.first = false
        end
        self.display = self.display..key
    end
end

function Calculator:check(key, result)
    self:press(key)
    self:displayIs(result)
end

function Calculator:doPending(func)
    if self.op ~= nil then
        self.display = "" .. (self.op(self.display, self.temp))
    end
    self.first = true
    self.op = func
end

function Calculator:displayIs(string)
    if self.display ~= string then
        local diag = "expected /"..string.."/ but got /"..self.display.."/!"
        print(diag)
    end
end

function Calculator:draw()
end

function Calculator:touched(touch)
end

--# Main
-- Article Calc

-- Use this function to perform your initial setup
function setup()
    print("tests begin")
    local c = Calculator()
    c:check("1","1")
    c:check("2","12")
    c:check("*","12")
    c:check("3","3")
    c:check("=","36")

    c = Calculator()
    c:check("4","4")
    c:check("5","45")
    c:check("0","450")
    c:check("/","450")
    c:check("1","1")
    c:check("5","15")
    c:check("-","30")
    c:check("1","1")
    c:check("9","19")
    c:check("=","11")
    c:check("+","11")
    c:check("5","5")
    c:check("=","16")
    print("tests end")
end

-- This function gets called once every frame
function draw()
    background(40, 40, 50)
end
Categories: Blogs

VersionOne Announces SAFe 3.0 Alignment

Agile Product Owner - Sat, 10/11/2014 - 14:11

VersionOne just announced their latest update in support of SAFe 3.0. See here for details.

Categories: Blogs

Lessons from running Neo4j based ‘hackathons’

Mark Needham - Sat, 10/11/2014 - 12:52

Over the last 6 months my colleagues and I have been running hands on Neo4j based sessions every few weeks and I was recently asked if I could write up the lessons we’ve learned.

So in no particular order here are some of the things that we’ve learnt:

Have a plan but don’t stick to it rigidly

Something we learnt early on is that it’s helpful to have a rough plan of how you’re going to spend the session otherwise it can feel quite chaotic for attendees.

We show people that plan at the beginning of the session so that they know what to expect and can plan their time accordingly if the second part doesn’t interest them as much.

Having said that, we’ve often gone off on a tangent and since people have been very interested in that we’ve just gone with it.

This sometimes means that you don’t cover everything you had in mind but the main thing is that people enjoy themselves so it’s nothing to worry about.

Prepare for people to be unprepared

We try to set expectations in advanced of the sessions with respect to what people should prepare or have installed on their machines but despite that you’ll have people in varying levels of readiness.

Having noticed this trend over a few months we now allot time in the schedule for getting people up and running and if we’re really struggling then we’ll ask people to pair with each other.

There will also be experience level differences so we always factor in some time to go over the basics for those who are new. We also encourage experienced people to help the others out – after all you only really know if you know something when you try to teach someone else!

Don’t try to do too much

Our first ‘hackathon’-esque event involved an attempt to build a Java application based on a British Library dataset.

I thought we’d be able to model the data set, import it and then wire up some queries to an application in a few hours.

This proved to be ever so slightly ambitious!

It took much longer than anticipated to do those first two steps and we didn’t get to build any of the application – teaching people how to model in a graph is probably a session in its own right.

Show the end state

Feedback we got from attendees to the first few versions was that they’d like to see what the end state should have looked like if they’d completed everything.

In our Clojure Hackathon Rohit got the furthest so we shared his code with everyone afterwards.

An even better approach is to have the final solution ready in advance and have it checked in on a different branch that you can point people at afterwards.

Show the intermediate states

Another thing we noticed was that if people got behind in the first part of the session then they’d never be able to catch up.

Nigel therefore came up with the idea of snapshotting intermediate states so that people could reset themselves after each part of the session. This is something that the Polymer tutorial does as well.

We worked out that we have two solid one hour slots before people start getting distracted by their journey home so we came up with two distinct types of tasks for people to do and then created a branch with the solution at the end of those tasks.

No doubt there will be more lessons to come as we run more sessions but this is where we are at the moment. If you fancy joining in our next session is Java based in a couple of weeks time.

Finally, if you want to see a really slick hands on meetup then you’ll want to head over to the London Clojure DojoBruce Durling has even written up some tips on how you run one yourself.

Categories: Blogs

Ripping the Planning Out of Agile

Agile Tools - Sat, 10/11/2014 - 08:22

needle-31827_640

Recently I was following some twitter feed about #NoEstimates. I’m no expert, but it seems to be a conversation about the fundamental value, or lack of value, that planning provides to teams. What they seem to be arguing is that planning represents a lot of wasted effort that would be better spent elsewhere.

Fundamentally I would have to agree. I’ve wasted a tremendous amount of time arguing about story points, burning down hours, and calculating person days – all for what seems like very little benefit.

What I would rather do is spend more time talking about the problem we are trying to solve. I really value a deep understanding of the system and the changes that we intend to make to it. If I have that much, then I’m well situated to deliver fast enough that nobody’s going to give me much grief about not having estimates. That’s my theory anyway. The sooner you can deliver working software, the sooner people will shut up about estimates.

But often we never do talk about the problem at anything other than a very superficial level. We spend most of our time trying to size the effort according to some artificial schema that has nothing to do with the work or any real empirical evidence at all.

So what if there were no plan? What if we took Scrum and did everything but the planning? You show up Monday morning and you have no idea what you are going to work on. The team sits down with the customer and talks about their most pressing need. They work out what they need to build, make important design decisions, and coordinate among themselves. At no point are there any hours, or points, or days. What would happen to the cadence of the sprint if we removed the planning? Basically, we would have our daily standup, and then we would review our accomplishments at the end of the sprint and look for ways to improve.

That sounds pretty good actually. Like anything else, I’m sure it has pros and cons:

Pros: Save time and energy otherwise wasted on estimation, and use that time instead for important problem solving work.

Cons: Stakeholders really like estimates. It’s like crack. They start to shake and twitch if you take their estimates away. Not many will even let you talk about it.

It might be worth a try sometime. It would certainly make an interesting experiment for a sprint or two. What if the sprint were focused entirely on the improvement cycle instead?


Filed under: Agile, Scrum Tagged: #noestimates, Agile, estimates, Planning, sizing
Categories: Blogs

I am an ironing board

Business Craftsmanship - Tobias Mayer - Fri, 10/10/2014 - 17:46

Session Notes for Open Space session at Agile Open, California, Thursday 9th October 2014. Around 25-30 people in attendance.

image

Session title: Metaphor—Why?

Introduction: (System) metaphor is one of the original XP principles, but has been neglected over time in favor of other, more actionable principles such as test-driven development and continuous integration. A system metaphor creates a shared understanding, and its absence often creates misunderstanding and misalignment. In this session I’m interested in exploring metaphor, not specifically for code, but for human systems,and also individuals. Metaphor can create new understanding, new ways of looking at familiar situations. What might it mean, for example, to say to someone, “you are an ironing board”.

Part #1

For want of a plan of any kind, I started the session with this question, and asked participants to pair up and explore what it meant to them. Some pairs explored it from a personal perspective, and some from the perspective of their work role, e.g. developer or Agile coach. In sharing we focused on “I” statements, and paraphrasing…

"When I am folded away in a closet I see the world differently to when I am out in the open, being of service."

"I seek something hot and steamy to be pressed against me."

"I am the body of workers that supports the change agent (the iron) in removing the wrinkles in my organization (the clothing). Without me there is no foundation for improvement"

A nice corollary for this last one, from the iron’s perspective, was “If I stay too long I will burn a hole, and ruin what I am trying to improve.”

The neat thing about facilitating an open space session, is the sense of release. The session goes where it goes, and all I needed to do was embrace the ideas that emerged, turn them into offers, and suggest some containment for the dialog.

Part #2

The “I am” statement led a participant to be reminded of an improv exercise called Invocation, where an object is identified of spoken of in four different ways, each one taking the speaker from objectivity to subjectivity: “It is…”, “You are…”, “Thou art…” and “I am…” We practiced this framework in the second part, people finding a new partner and offering an object of their own choice, e.g. bird, flipchart marker, redwood tree, highway… The use of this framework led people to greater empathy. Was that what we were seeking with metaphor? Perhaps. The following discussion looked at the difference between the incremental understanding and the immediate jump to “I am”. The latter is more of an analogy: I am like this thing because… opening up new ways of seeing self, while the former takes the speaker deeper into a place of understanding of the other (thing). 

Note: when my partner struggled with the “Thou art” part, I asked him to recite a love sonnet to the flipchart marker he was holding. “Thou art an extension of my imagination…”, he began. I don’t recall the rest but it was very eloquent, and oddly moving. When he tried to do the same in front of the group he wasn’t able to, and afterwards commented how wrong it felt to express intimacy in front of a large group.

Part #3

We discussed the idea of using another person as the “object”. A traffic cop. 1) It is an authority figure, uniformed, unwelcome. 2) You are a man with a job to do. You need to earn a living like the rest of us. 3) Thou art a keeper of the law, a man with a mission. Thou art possibly a family man, seeking to improve the life of your family in the best way you can. Thou enforces the law because thou believeth in justice.” 4) I am a man with a mission, a believer in truth and justice. I care for my community and want to help others do the same. This had now moved beyond metaphor into a pure empathy exercise. Time for a retrospective. Are we getting what we want from this session? Where do we want to go now?

Retrospective

I asked for the five most vocal people to form small teams. Their job was to facilitate a dialog and not speak themselves. One of them asked, what, not speak at all? I had rather meant that they did not offer input but made sure all voices were heard, but this was an idea worth exploring. Yes, facilitate in complete silence. Feedback from the facilitators was interesting. In general it improved the ability to listen. The retrospective gave us three topics to explore further, so we created an short open-space-within-open-space. 

Part #4

  1. The use of metaphor in retrospectives—how would it help to ask participants to come up with a metaphor for the last sprint? What new avenues of exploration/understanding might it encourage?
  2. Exploring common metaphors, e.g. herding cats, war room, firefighting. Many of our metaphors are negative, or derogatory, creating a (perhaps) undesirable mindset. We looked for new metaphors, and the one that shone for me was a new way at looking at “cat herder” (a typical description of a project manager). I am a builder of playgrounds. This idea completely changes how one might approach their job: don’t try to manage the chaos, embrace it and support it with fresh imagination.
  3. Empathy via Invocation. Some wanted to explore this further. I have no notes for this short session.

Time expired, so the small groups dissolved. I asked those remaining at the end to practice with each other during the event, by simply offering a “you are an [object]” challenge to one another at random moments, and see what happened. As I left the eception at the end of the day, I offered a colleague “You are a stuffed mushroom”. I look forward to hearing what he had to say to the others in the group when we next meet.

Categories: Blogs

New daily stand up questions

Xebia Blog - Fri, 10/10/2014 - 16:51

This post provides some alternate standup questions to let your standup be: aimed forward, goal focused, team focused.

The questions are:

  1. What have I achieved since our last SUM?
  2. What is my goal for today?
  3. What things keep me from reaching my goal?
  4. What is our team goal for the end of our sprint day?

The daily stand up runs on a few standard questions. The traditional questions are:

  • What did I accomplish yesterday?
  • What will I be doing today?
  • What obstacles are impeding my progress?

A couple of effects I see when using the above list are:

  • A lot of emphasis is placed on past activities rather than getting the most out of the day at hand.
  • Team members tell what they will be busy with, but not what they aim to complete.
  • Impediments are not related to daily goals.
  • There is no summary for the team relating to the sprint goal.

If you are experiencing the same issues you could try the alternate questions. They worked for me, but any feedback is appreciated of course. Are you using other questions? Let me know your experience. You could use the PDF below to print out the questions for your scrum board.

STAND_EN

STAND_EN

 

Categories: Companies

Codea Calculator

xProgramming.com - Fri, 10/10/2014 - 16:30
Codea Calculator Warning

This is long. Bring food and water, or read it in parts.

Be aware of this, please: with all these words, all this explanation, the project itself goes very smoothly. My suggestion is that it wasn’t all these words, but it was the attention to testing, simple code, incremental development, and keeping the code clean.

See what you think!

Initial Thinking

Codea is a lovely Lua development system that runs on the iPad. I enjoy building things with it. Recently, on the forums at codea.io, “dave1707″ posted an example of a little calculator, as an example to some new member. I thought I might put together a description of how I might do a similar thing.

I expect to find a lot of differences between Dave’s calculator and mine, so I’ll keep my functionality the same as his. Predicting what will come out, I expect that Dave’s version will be many fewer lines of code. It will probably be more “efficient”, though it’s not clear just what efficiency means in a program that spends its time waiting for someone to press a button. Anyway, we’ll see what happens, and in the end, everyone gets to do it the way they see fit.

I did read Dave’s version and sort of figured out what it did. That might influence what I do now, but we’re always building on everything we know. It may also have confused me, especially since I didn’t type it in and run it. We’ll see if we see his influence on this version, or not. I’m happy either way.

There will be a lot of words here, because I’ll try to put down all my thinking. My experience is that it takes more than twice as long to write an article like this as it does to write the program. That’s because we all think a lot faster than we type. At least I hope so …

Calculator Operation

I started by drawing a little sketch of how this kind of calculator works.

calc

My “theory of calculator operation” is that you have buttons, a display, and a temp register. The buttons come in digits, standard binary infix operators (+ – * / ^) and sin/cos, which are a different kind of operator, as we’ll see. These are unary operators if you’re into terminology.

When you press a digit key, that digit appends to the digits already in the display.

When you press an infix operator, the operation implied is performed between the display register and the temp register. The result goes to temp, and the display is cleared. When you press a unary key, the operation is immediately applied to the display and the result left in the display.

Now I’m pretty sure this is how calculators are supposed to work. It’s possible, though, that I just don’t get it. So I’d like to find out ASAP whether this design will work.

Program Design

Well, there will be buttons. I plan to rip off Dave’s design for the buttons, although I expect I’ll generate them a bit differently. We’ll see what we need.

And I plan to build a calculator object, in a class. Dave put his functionality right in the buttons, which certainly works fine. My training and experience lead me to put separate function into separate modules, in this case, objects. If I were just whacking out a calculator, I might do it differently. I might even build something along Dave’s lines and then refactor it to a design that I like better. (Of course I might just leave it alone, if it was working fine, especially if it was just something I did for fun.) But for today, I’m going to break out the calculator as a separate class. My plan is to test it as I go.

First Implementation Begin with a test

As usual, I start with a test. I’m putting it in setup, and the initial cut looks like this:

c = Calculator()
c.press("1")
c.press("3")
c.press("*")
c.press("3")
c.press("=")

So I’m assuming I’ll have a Calculator class, and that it understands a press method. I’ve not checked any results yet but I expect to see display containing, in order, 1, 13, nothing, 3, 36, while temp will contain 0 (or nothing), 0, 13 …

WOW, wait! My design is wrong! I’m thinking that when you type the ‘*’ it will apply the operator multiply to temp and put the result into temp. But the temp at this point will be zero, so that won’t do. It would zero the result.

I am tempted at this moment to read Dave’s version and see what it does. But we won’t always have Dave to rely on so I’m going back to the drawing board to figure out how these things work.

… thinking and sketching ensues …

OK, I have a new theory of operation. The calculator has to remember the operator you type, and when you type a new operator, then it applies the old one. And then it remembers the new one.

I’m still thinking I can work with just one temp register but I’m uncertain.

There are a number of things one can do when uncertain. One of them is to think more. The other is to have the computer help you, by programming something to see what the program really wants to be. In the past, I used to design for a long time. My more modern practice is to do my design thinking, as much as possible, with the program there in front of me. So I’m going to extend my test to examine some results and then I’m going to code a Calculator.

Revised test
c = Calculator()
c.press("1")
c:displayIs("1")
c.press("3")
c:displayIs("12")
c.press("*")
c:displayIs("12")
c.press("3")
c:displayIs("3")
c.press("=")
c:displayIs("36")

Now, of course, I could just print the display after each step. And if I weren’t trying to demonstrate a sort of “test-driven” approach, I might. After all, it’s just a calculator. What I’m doing here, though, is different from testing by printing in a couple of ways.

First of all, I’m saying right in the code what I expect to happen. So I have designed and specified the behavior of the calculator, right here in plain sight.

Second, I’m setting up a test that I can repeat without looking at the printout and checking it by eye. In this case, it may not be worth it. Even here, it might be. In a larger program, that grows and changes for a longer time, this kind of test can be quite valuable in assuring me that I haven’t broken anything. Because I surely will break something.

Now to write a calculator that can do this. I’m not sure what the displayIs function will do just yet but I’m thinking it’ll print the display and say whether it’s happy. It might do nothing unless it’s not happy. We’ll see what we like.

First Version — just shows errors

Here’s what I did:

Calculator = class()

function Calculator:init()
   self.display = ""
end

function Calculator:press(key)

end

function Calculator:displayIs(string)
   if self.display ~= string then
       print("expected", string, "but got", self.display, "!")
   end
end

I decided that I don’t want the displayIs whining at me all the time, so it’ll just print the exceptions. Of course right now, it gets everything wrong so all the displayIs calls print an error. I hope to fix that soon.

Next Version — eliminate an error or two

So, OK. Next step is when a digit is pressed, append it to the display string. At least that’s my plan. Here goes:

function Calculator:press(key)
    self.display = self.display..key
end

Now you may find this interesting. All I’m doing is appending every keypressed to the display. This is clearly wrong! Why would I do such a stupid thing? Well, my story is that it’s simple, not stupid, and I’m sticking to it. This “implementation” makes my first two tests run, and the rest still fail. So it is progress. I prefer to write as little code as possible between a test failing and success.

A concern people often raise about working this way is that I’ll have to change a lot of code. We’ll see. What usually happens is that I add code, but don’t often have to replace or change much.

Mind you, I don’t always take such tiny bites. It’s easy to get on a roll and slam in a lot of code. Then, inevitably, I have to debug it. I don’t like that: I’d rather have a program that works a bit, then a bit more, then a bit more. Your mileage may vary. I’m showing a particular way of working here. Take what you wish from it, ignore the rest.

Make it clear on star

Now I need to make another test run, the one where you type * and I expect the display to go from 12 to blank. Tell you what: I’ll just code this much: “When the star is pressed, clear the display.” That will give an interesting outcome I think.

function Calculator:press(key)
   if key == "*" then
       self.display = ""
   else
       self.display = self.display..key
   end
end

The tests fail! Look at these lines:

c.press("3")
c:displayIs("12")
c.press("*")
c:displayIs("12")
c.press("3")
c:displayIs("3")

OK, well, that was just dumb. My calculator is supposed to do nothing on star, and then when you type another digit, it should clear.

Did you see that that was going to fail? Are you thinking “how dumb”? Well, I took a break for lunch between the last test and this one, and I forgot what the test was. I just coded what I thought it was. I should have looked but I started typing before I got my iPad out of the bag.

Oddly, this doesn’t bother me, because my tests immediately tell me “how dumb”. That’s why I like having them: they remind me of what I was doing when I come back from lunch. What people who work this way will often do, before they leave for the day, is write one new test that fails. The failing test reminds them what to do when they come back.

If this all seems odd to you, I’m not surprised. It was odd to me when I started working this way, oh, 15 years ago. And I’ve shown a lot of other people how to do it, and it was odd to them at the start too. After a few days trying it, they get the idea and begin to use this approach — in their own style — when they think it’s useful. Right now, you’re probably thinking how dumb I am for not realizing that the display wasn’t supposed to clear yet. I’m thinking how smart I was for having that test to catch me out. It’s all in the point of view.

One other thing on this: no matter how smart you are — and I will say right here that I am hella smart — you will make programming mistakes, and most of them will be dumb. It’s important not to take your dumb moments personally, but to learn from them. Just now I learned that I’m happy to have tests, and that I need to remember to look at them.

Back up – stop clearing on star

OK back to the drawing board. Obviously the star isn’t supposed to do anything. So I can remove the code inside that part of the if. No, really, that’s what I’m going to do:

function Calculator:press(key)
   if key == "*" then

   else
       self.display = self.display..key
   end
end

Guess what! My test runs. Now these last two are failing, like this:

c.press("*")
c:displayIs("12") -- OK
c.press("3")
c:displayIs("3")  -- Displays 123
c.press("=")
c:displayIs("36") -- Displays 123=

So, what to do here? We have to make pressing 3 after star clear out the display and put three into it. (We know this will apply to all of 0 – 9, so I won’t insult us all by just making it work for 3.) So somehow we have to know that a star happened, so that we’ll clear the display before we append to it like always.

I wasn’t sure what the calculator should do, so I ran Dave’s. I noticed that if you type 3*6+2 into it, you get 8. The display, meanwhile, displays “3*6+2″ Well, he said it was still buggy: his point was to show how to do certain things, not to build a real calculator. I kind of like it displaying the whole calculation but if it were to do that I’d like it to work, and that way lies trouble, because when we type 2+3*6 we mean that to be 2 + 18, not 5*6, because operator precedence. We don’t want to go there. No, really, we don’t. That’s a whole different kind of calculator.

Make it clear on next digit after star

So I have to make mine work. I think I’ll save the operator and if a digit comes in when an operator is saved, clear the display and start the append over again. (Yes, I know I’m supposed to do a calculation too but that’s in a future test.)

I had to initialize my new variable, “op” in setup, so now I have this:

function Calculator:init()
   self.display = ""
   self.op = ""
end

function Calculator:press(key)
   if key == "*" then
       self.op = key
   else
       if self.op ~= "" then
           self.display = ""
       end
       self.display = self.display..key
   end
end

Now the only test that’s failing is the =. It displays = and it should display 36. To make this work, when the equal comes up, I need to multiply what was on the screen (the 12) by what is on the screen (the 3). This means I’d better tuck the 12 away, at the same time as I save the star.

Do the math. Finally!

And I’d better handle the = separately too, using it to trigger the arithmetic. So I write this:

function Calculator:press(key)
   if key == "*" then
       self.op = key
       self.temp = self.display
   elseif key == "=" then
       self.display = self.display * self.temp
   else
       if self.op ~= "" then
           self.display = ""
       end
       self.display = self.display..key
   end
end

This gives the surprising result in my test of expected 36 but got 36 !. My guess is that when I do multiply of “12” and “3”, I’m getting a blank in the result. To find out, I’ll improve the test to show some delimiters:

function Calculator:displayIs(string)
   if self.display ~= string then
       local diag = "expected /"..string.."/ but got /"..self.display.."/!"
       print(diag)
   end
end

Much to my momentary surprise, it says “expected /36/ but got /36/!”. So what’s going on? Ah! What’s going on is that the multiply operator returned the number 36 instead of the string “36”, so the test failed. I’m not sure what to do. One simple thing would be to convert my numeric results back to strings. I wonder what would happen, though, if I just ignored the problem. Trouble with that is that I would have to fiddle the tests to deal with “36” versus 36.

I think I’ll just convert back to string. What’s a good way to do that? How about ""..(self.display*self.temp)? That might work … basically appending the number to an empty string in hopes that Codea will convert it for me. Failing that I’m going to have to look something up. Ha! That works. Kind of a hack but I’m happy for now.

By the way, did you notice that "12" * "3" results in 36? Codea converts the strings to numbers before doing the arithmetic. How polite!

Anyway, my first test now runs. Let’s review the whole thing:

First test runs!
-- Article Calc

-- Use this function to perform your initial setup
function setup()
   c = Calculator()
   c:press("1")
   c:displayIs("1")
   c:press("2")
   c:displayIs("12")
   c:press("*")
   c:displayIs("12")
   c:press("3")
   c:displayIs("3")
   c:press("=")
   c:displayIs("36")
end

-- This function gets called once every frame
function draw()
   background(40, 40, 50)
end

Calculator = class()

function Calculator:init()
   self.display = ""
   self.op = ""
end

function Calculator:press(key)
   if key == "*" then
       self.op = key
       self.temp = self.display
   elseif key == "=" then
       self.display = "" .. (self.display * self.temp)
   else
       if self.op ~= "" then
           self.display = ""
       end
       self.display = self.display..key
   end
end

function Calculator:displayIs(string)
   if self.display ~= string then
       local diag = "expected /"..string.."/ but got /"..self.display.."/!"
       print(diag)
   end
end
Story complete. Pause and reflect.

Time to reflect a bit on what just happened. I wrote a short series of tests of the calculator and made them run one by one. I haven’t added any code that wasn’t needed to make those tests work — at least I don’t think so.

That is part of the test-driven development style (TDD) that I use and teach. We never write a line of code that isn’t required by a failing test. So even though I know that there are other ops to worry about, plus minus and so on, I didn’t put them into the if statement. I didn’t cater to anything that wasn’t implied by that test, to the best of my ability.

For this tiny app, it’s not important. When building something larger, this discipline is a nice way to keep from gold-plating things, adding “generality” that isn’t needed. I love to write general code. I have an advanced degree in this stuff and there’s great joy in writing that sort of thing. These days, I take greater joy in letting the program seem to emerge from the fog.

YMMV. I’m not suggesting you should work this way. You might not even want to know this way. But if you want to be a professional programmer these days, it’s valuable to be aware of these approaches. For the folks here, I just hope you find it interesting.

Now what? Well, we need another test. We could do a simple one with + or – or / and we’d learn a bit. But I am inclined to write a harder test, including one of those operators, and to learn from that.

Temptation – operations as anonymous functions

Looking forward, I can see there’s going to be a lot of checking for star and plus and all those. One time to save them in self.op and then probably later to apply them (where I just have a multiply now). I am really tempted to do something nicer than a bunch of if statements. And we are here to learn Codea/Lua, not just to be all up tight and supposedly professional. What if, when we see the star, we stored a function in self.op and when we need to execute that star (or plus or whatever it’ll be) we just executed that function? That might be better.

Now when I’m operating at full discipline, I would build it with if statements and the look at it and find it ugly and improve it. This would be safe and easy, because my tests would support me. It’s a bit against my best principles to put in this idea right now before it has shown to be fully required.

But hey, if you wanted a saint, you should have called someone else. I’m going to try it and see if I like it:

function Calculator:press(key)
   if key == "*" then
       self.op = function(a,b) return a*b end
       self.temp = self.display
   elseif key == "=" then
       self.display = "" .. (self.op(self.display, self.temp))
   else
       if self.op ~= "" then
           self.display = ""
       end
       self.display = self.display..key
   end
end

Note the

self.op = function(a,b) return a*b end

and the corresponding

self.display = "" .. (self.op(self.display, self.temp))

In self.op, I stored an anonymous function returning a*b, and then just called that function when the equal came up. I plan to store similar functions for plus, minus and so on. Will I love this? We’ll see.

Right now, it’s time for a break. Next time, I’ll write a new test that’s a little longer and has another operator or two. We’ll see what happens.

The Next Test

I decided to do a bigger test, basically 450 / 15 – 19, which if my calculations are correct comes to 11. I noticed in writing it that I had not made the calculator instance local in my test. So I’ll provide the full text of the setup() function here.

function setup()
   print("tests begin")
   local c = Calculator()
   c:press("1")
   c:displayIs("1")
   c:press("2")
   c:displayIs("12")
   c:press("*")
   c:displayIs("12")
   c:press("3")
   c:displayIs("3")
   c:press("=")
   c:displayIs("36")

   c = Calculator()
   c:press("4")
   c:displayIs("4")
   c:press("5")
   c:displayIs("45")
   c:press("0")
   c:displayIs("450")
   c:press("/")
   c:displayIs("450")
   c:press("1")
   c:displayIs("1")
   c:press("5")
   c:displayIs("15")
   c:press("-")
   c:displayIs("30")
   c:press("1")
   c:displayIs("1")
   c:press("9")
   c:displayIs("19")
   c:press("=")
   c:displayIs("11")
   print("tests end")
end

It’s getting a bit tedious to write these tests. Often, in this kind of situation, it is. I expect tests for a real calculator object to last for a long time but even so, if it’s a pain I won’t do it. One way to make it easier might be a helper method pressDisplaying(input, output) that would do the press and then check the result. That would save a lot of typing. With a little regex action I could do that here but Codea isn’t as much help on that as some editors.

Anyway, this test calls for implementation of divide and subtract, plus it deals with chaining operations. We’ll see how that goes. I haven’t run the test yet. Stand back, this thing may explode.

First error is “expected /450/ but got /450//!”. And I notice that I can’t tell just which one of my expected 450s this is, but I’m pretty sure it’s the one after the slash, since we know we don’t cater to it and so it’ll be treated as a digit. Makes me think the tests need a number or something. I’ll keep it in mind.

Side Note

Are you amazed or shocked at how little pre-planning or up front design I do, or how I seem to tolerate things being a bit crufty for a while? That’s on purpose. I am confident that my approach will bring all the issues into view, and that I’ll work on the ones that are actually troublesome. And I’ll skip the ones that turn out not to be a burr in my fundament.

This is rather different from the approach described in most of the older software development books, such as Code Complete. There’s great material in those books but we in the Agile movement have observed that with today’s tools and techniques, we can do more and more of our design as we go, not just up front.

I’ve been programming for over half a century (arrgh) and working in this style for 15 years, so I’m pretty comfortable with it. Not that it’s just easy and automatic. I think programming will never be easy, because as my friend Ward Cunningham once said to me, everyone winds up working at the limits of their ability, because people keep piling harder problems on us as we get better. But we can work to keep things simple, if not easy.

Back to the code

I went ahead and put in slash in the same style as times. That caused me to see that order matters for divide and subtract (and power, if I do that). So I renamed the parameters for my anonymous functions to d and t, for display and temp, both in the new divide and back in multiply. It doesn’t change the function, but makes the code more clear and consistent.

function Calculator:press(key)
    if key == "*" then
        self.op = function(d,t) return d*t end
        self.temp = self.display
    elseif key == "/" then
        self.op = function(d,t) return t/d end
    elseif key == "=" then
        self.display = "" .. (self.op(self.display, self.temp))
    else
        if self.op ~= "" then
            self.display = ""
        end
        self.display = self.display..key
    end
end

The tests now run up to “expected /15/ but got /5/!”. This surprises me. In the first test we got two numbers in. But! It was in the first argument, not the second. OK, look at where the digits go in. We’re checking op against “”, and if it isn’t, we’re clearing the screen. That will happen on every press, because the op is still hanging. In addition, we shouldn’t use an empty string test anyway, since op is now a function, not a string.

The behavior we want is that the first digit after an op should clear and then go in, but not the following ones. Also, I noticed that in setting up for divide, I forgot to copy display to temp. So I put it in there. But now I’m wondering if we can combine the clearing and the copying until the first digit after an op. I’ll try it. I plan to add a flag, named first, and do the copy and clear based on that. Here goes.

function Calculator:press(key)
  if key == "*" then
      self.op = function(d,t) return d*t end
      self.first = true
  elseif key == "/" then
      self.op = function(d,t) return t/d end
      self.first = true
  elseif key == "=" then
      self.display = "" .. (self.op(self.display, self.temp))
  else
      if self.first then
          self.temp = self.displat -- typo discovered below!
          self.display = ""
          self.first = false
      end
      self.display = self.display..key
  end
end

With this in place, the tests run with no comment until an error, on line 11, attempt to perform arithmetic on local t. This leads me to the typo above, referring to self.displat. Oops.

function Calculator:press(key)
  if key == "*" then
      self.op = function(d,t) return d*t end
      self.first = true
  elseif key == "/" then
      self.op = function(d,t) return t/d end
      self.first = true
  elseif key == "=" then
      self.display = "" .. (self.op(self.display, self.temp))
  else
      if self.first then
          self.temp = self.display
          self.display = ""
          self.first = false
      end
      self.display = self.display..key
  end
end

Fixing that gives me “expected /30/ but got /15-/!”, which is, of course, the minus failing to be known as an operator.

So we code minus:

elseif key == "-" then
    self.op = function(d,t) return t-d end
    self.first = true

Now we get “expected /30/ but got /15/”. Hmm. I think we clobbered the divide op before doing it! Hey, look, we only actually ever perform an operation on equals! We need to do any pending op before ever putting the next one in.

I also notice a lot of duplicated lines here. Duplication is the code’s way of telling us that there is an idea in our head that is not reflected directly in the code. We’ll want to clean that up soon. But I don’t like to do much code improvement while the code isn’t working. It’s too easy to introduce new errors and not notice them. So I’ll press forward, noting the duplication but living with it until these tests run, if I can. If it gets too hairy, that will be a sign that I’ve bitten off too much. Let’s hope not.

The tests run

And the tests run to completion! I added a doPending() function and used it as needed. Nothing else that I recall:

Calculator = class()

function Calculator:init()
   self.display = ""
   self.op = nil
   self.first = false
end

    function Calculator:press(key)
       if key == "*" then
           self:doPending()
           self.op = function(d,t) return d*t end
           self.first = true
       elseif key == "/" then
           self:doPending()
           self.op = function(d,t) return t/d end
           self.first = true
       elseif key == "-" then
       elseif key == "=" then
           self:doPending()
       else
           if self.first then
               self.temp = self.display
               self.display = ""
               self.first = false
           end
           self.display = self.display..key
       end
    end

    function Calculator:doPending()
       if self.op == nil then return end
       self.display = "" .. (self.op(self.display, self.temp))
       self.op = nil
    end

    function Calculator:displayIs(string)
       if self.display ~= string then
           local diag = "expected /"..string.."/ but got /"..self.display.."/!"
           print(diag)
       end
    end

    function Calculator:draw()
    end

    function Calculator:touched(touch)
    end

Note the new doPending() function. If there’s an op present, it executes it and clears the op. It’s called right before installing an op. Let me mention explicitly the if at the beginning of that function. I could have said if self.op ~= nil then and then done the statements. Same effect. The way I’ve done it there is called “Guard Clause” (see Kent Beck’s books on coding patterns). The idea is that you check any special cases at the top and then exit. If the code got at all complex there, I’d do it with the more usual if/elseif/else, of course. Guard Clause is a pattern I use commonly. If the team’s coding standard uses it, then the team will be used to it. If not, then really no one on the team should be using it. I’m my own team right here, so we do it my way.

Refactoring – duplication means the design needs improvement

As I predicted, we see duplication now. Each of the operators follows the same pattern. Each does any pending op, then puts its own special function into self.op, and then sets the first flag.

As I mentioned, duplication tells us that the code has an idea in it (or our head does) that is not as explicit in the code as it could be. Duplication is the enemy of clear code and the enemy of easy maintenance. If we have this copy-pasted patch of code all over, then when we have to change it — and surely we will — we have to change it everywhere. And we’ll likely miss one. Or worse yet, we might have code that is nearly duplicated, looks the same, but with subtle differences. If we extract the duplicated part, we can see the differences more readily. That gets us to working, clean, maintainable code sooner.

Now that my tests are working, I can clean up the code. In test-driven development (TDD), we call this “Red / Green / Refactor”. When the tests are Red (not running) we do not refactor if we can possibly avoid it. We make the tests go Green. When they run, then we look at the code and see how to improve it. It’s time to do that now. We could wait until we put in plus, and power, or we could do it now. If we wait, there will be more duplication. Right now we have three cases, and that’s usually a good basis for making the improvement. What shall we do? The three offending lines look like this:

       self:doPending()
       self.op = function(d,t) return t-d end
       self.first = true

Each occurrence has a different function in the middle and the other two lines alike. I can think of a number of ways to improve it. Let’s look at doPending() as well, since it’s used in the dups:

function Calculator:doPending()
   if self.op == nil then return end
   self.display = "" .. (self.op(self.display, self.temp))
   self.op = nil
end

What if we change doPending() to accept the function as a parameter. Then it can update the display, set the first flag, and store the new op all at once. Sounds tempting.

However, the equals operator calls doPendng() but doesn’t do the other things. Perhaps it should. It could certainly take nil as the function to set up next, and it seems likely that setting first will be a good idea, since if after displaying the result, the next digit typed does in fact want to clear the display.

The bad news is, there goes my Guard Clause. That didn’t last long this time, but it’s still a good bet because — by my standards of code reading — it’s more clear when it does apply. YMMV of course, as with all of this.

Anyway, doPending(). We’ll pass in a function to be saved away in self.op. We’ll always set the first flag. If there’s an existing op waiting, we’ll execute it, otherwise not. This can be coded in a couple of ways. I could probably save my Guard Clause, but it would have to occur in the middle. That’s not kosher for Guard Clause. So I extend doPending():

function Calculator:doPending(func)
   if self.op ~= nil then
       self.display = "" .. (self.op(self.display, self.temp))
   end
   self.first = true
   self.op = func
end

And then use it:

function Calculator:press(key)
   if key == "*" then
       self:doPending(function(d,t) return d*t end)
   elseif key == "/" then
       self:doPending(function(d,t) return t/d end)
   elseif key == "-" then
       self:doPending(function(d,t) return t-d end)
   elseif key == "=" then
       self:doPending(nil)
   else
       if self.first then
           self.temp = self.display
           self.display = ""
           self.first = false
       end
       self.display = self.display..key
   end
end
It’s alive!

And the tests still run! This gives me great confidence that I haven’t broken anything. The code is pretty clean so far, I’d say. We need to implement the + and ^ operators, and sin and cos if we’re going to copy Dave, but it’s bedtime here at the ranch. I’ll decide tomorrow whether to publish this as one, article, or three. It’s over 5000 words now, so I think three, or even four, might be a good idea. I’ll decide when next I get back to this. For now, everything is solid and rather clean, and I can rest easy.

A Note

Before I go, a note to myself. The else clause in the press() function accepts digits but also any unimplemented operators. We have seen that happen, with the slashes showing up at the end of the display. (Dave’s calc actually does that. I think he intended it, as it shows what’s going to happen in the future. I do not intend it.) Anyway, we should probably limit the else to the digits and put in an else clause that gives us some kind of error if we get an unexpected character. But that’s for tomorrow.

In fact, it was for Friday

Hello, Friday morning here. I’ve been doing other things that I was supposed to be doing. Now let’s see if we can finish up this article, at least to a point where it makes sense to publish it. (Sense by my standards. YMMV.)

I’ve pretty much decided that I’m going to stop with the four operations plus minus times divide, without sin/cos, but I might do them just to show that I can. Or maybe +/-, the unary sign-changing operation, which is commonly present on “four-function” calculators.

What to do

When I return to a project after a day or a month, I look around to see what needs to be done. Sometimes there is an intentionally broken test waiting, to remind me where to go. I did not do that way back Wednesday, because I knew I was leaving for a day or two and I don’t like a system left on a red bar for very long. And anyway I knew that minus was the only operator left untested and unimplemented. No, wait, it’s plus. Wait … two days and I don’t know quite where I left off.

The only way to know is to look at my notes … or the code … or the tests. I’ll pick the tests. Time to review them anyway. They look like this:

-- Article Calc

-- Use this function to perform your initial setup
function setup()
    print("tests begin")
    local c = Calculator()
    c:press("1")
    c:displayIs("1")
    c:press("2")
    c:displayIs("12")
    c:press("*")
    c:displayIs("12")
    c:press("3")
    c:displayIs("3")
    c:press("=")
    c:displayIs("36")

    c = Calculator()
    c:press("4")
    c:displayIs("4")
    c:press("5")
    c:displayIs("45")
    c:press("0")
    c:displayIs("450")
    c:press("/")
    c:displayIs("450")
    c:press("1")
    c:displayIs("1")
    c:press("5")
    c:displayIs("15")
    c:press("-")
    c:displayIs("30")
    c:press("1")
    c:displayIs("1")
    c:press("9")
    c:displayIs("19")
    c:press("=")
    c:displayIs("11")
    print("tests end")
end

With a bit of inspection, I see that there is no test of plus. I also see that the tests are harder to read than I might like. And they were a pain to write. I think I’d prefer something like this:

c:check("4","4")
c:check("5","45")

where check presses the first parameter and checks the display for containing the second. This would readily be implemented by calling the other two functions, of course.

We might also wish to build that function into our testing, rather than into the Calculator. It’s considered to be a bit off to have functions in production code that are only intended for testing. And it would be easy enough to do it in setup.

There are other “nice” things we might do with the tests. We could have a checkBegin and checkEnd function, for example, that might print something like “….X.X.” if tests 1-4, 6, and 8 passed, but 5 and 7 did not. The fact that the tests print nothing when everything is OK is a bit scary.

Why do you bring this up?

Good question. I bring this up because, today, the top “Agile” teams actually think about this stuff and do something about it. With modern refactoring tools it’s easy to make changes like this, and if we were going to be looking at this code for months, making it easier to understand is worth the effort

So I mention it because part of my purpose in life is to let people know how things are being done. I’m not saying you need to do them. I’m just explaining what I do, what other “Agilists” do, and why we do them. Then you get to see the code and the results and decide for yourself what, if anything, is worth trying. I hope you’ll try a lot of these ideas, but I don’t get paid any more — or any less — if you don’t.

Anyway, plus …

I’m feeling pressure to get this article out. And that pressure, self-imposed though it is, is telling me not to clean up the tests but to Build That Feature. And that’s what I’m going to do. But I’m aware that even a tiny bit of self-imposed pressure is enough to cause me to slack a bit on the things that I know darn well make my code more able to be changed in the future.

You have to make trade-offs. I’m making this one. But even now, there’s a bit of me whispering that I’m doing the wrong thing. Hell, I could have fixed the tests up by now.

Oh, OK, stop nagging. First I’ll fix the tests. Hold on.

That was grueling …

I decided to do the change at 9:40. It’s 9:44. I took the code into Sublime, did a find/replace with a regular expression, and now it looks like this:

-- Article Calc

-- Use this function to perform your initial setup
function setup()
    print("tests begin")
    local c = Calculator()
    c:check("1","1")
    c:check("2","12")
    c:check("*","12")
    c:check("3","3")
    c:check("=","36")

    c = Calculator()
    c:check("4","4")
    c:check("5","45")
    c:check("0","450")
    c:check("/","450")
    c:check("1","1")
    c:check("5","15")
    c:check("-","30")
    c:check("1","1")
    c:check("9","19")
    c:check("=","11")
    print("tests end")
end

I’ll paste that back to Codea. It will fail for lack of check, which I’ll implement:

function Calculator:check(key, result)
    self:press(key)
    self:displayIs(result)
end

And Bob’s your uncle, whatever that means. Anyway it was totally easy and took just a few minutes to do. And I feel better now. Lesson learned? Probably not, I am perpetually lazy. The moment you guys look away I’m gonna do something lazy. Trust me.

CloudClip

By the way, got a neat free tool called CloudClip Manager, for the iPad and the Mac. It shares the clipboard across iCloud. So I can copy something on my Mac (where I’m writing this) and paste it into Codea. Or vice versa.

Because the iPad doesn’t multi-task at all well, you have to flip into CloudClip to get it to refresh through iCloud but it is still ten times easier than mailing the code to yourself or whatever I used to be doing. Recommended product. I have nothing to do with it and do not get a percentage of the (free) price. Or 100 percent of it. I forget.

Plus. We were going to do plus.

I think I’ll just add a plus operation to an existing test. That should be good enough to get plus working. Then maybe I’ll add another test. So, looking at the last test above, we end up with 11. I could add a +5 before the = and get 16. Or, might be interesting to add the +5 after the = just to see what it does. I’ve not specified that.

I’m going to try it but when it fails, I’m going back to before the = and get that working first, because otherwise I’d be building two features at once, plus and input after equal. That would be bad. Here goes …

Well, the first thing that happens is “Expected 11 but got +”. We know that’s because plus doesn’t work at all yet. So I’ll put in the obvious lines for plus.

And the tests run! Woot! Here’s all the code:

--# Calculator
Calculator = class()

function Calculator:init()
    self.display = ""
    self.op = nil
    self.first = false
end

function Calculator:press(key)
    if key == "*" then
        self:doPending(function(d,t) return d*t end)
    elseif key == "/" then
        self:doPending(function(d,t) return t/d end)
    elseif key == "-" then
        self:doPending(function(d,t) return t-d end)
    elseif key == "+" then
        self:doPending(function(d,t) return t+d end)
    elseif key == "=" then
        self:doPending(nil)
    else
        if self.first then
            self.temp = self.display
            self.display = ""
            self.first = false
        end
        self.display = self.display..key
    end
end

function Calculator:check(key, result)
    self:press(key)
    self:displayIs(result)
end

function Calculator:doPending(func)
    if self.op ~= nil then
        self.display = "" .. (self.op(self.display, self.temp))
    end
    self.first = true
    self.op = func
end

function Calculator:displayIs(string)
    if self.display ~= string then
        local diag = "expected /"..string.."/ but got /"..self.display.."/!"
        print(diag)
    end
end

function Calculator:draw()
end

function Calculator:touched(touch)
end

--# Main
-- Article Calc

-- Use this function to perform your initial setup
function setup()
    print("tests begin")
    local c = Calculator()
    c:check("1","1")
    c:check("2","12")
    c:check("*","12")
    c:check("3","3")
    c:check("=","36")

    c = Calculator()
    c:check("4","4")
    c:check("5","45")
    c:check("0","450")
    c:check("/","450")
    c:check("1","1")
    c:check("5","15")
    c:check("-","30")
    c:check("1","1")
    c:check("9","19")
    c:check("=","11")
    c:check("+","11")
    c:check("5","5")
    c:check("=","16")
    print("tests end")
end

Notice the check for + 5, there at the end.

Summing Up

Are we done? Well, we’re probably all more than done reading this article, but if we were building a production calculator, we can think of more things to do. There certainly could be more functions, change sign, sine, cosine, arc-cotangent, and so on. Two- and three-dimensional plotting. I don’t know: the people who want products think of a lot of stuff. That’s up to whoever is deciding what the product needs to do.

Right now, that’s me, and I’ve decided the product has done its job, which is to serve as a platform for talking about how I might implement something in Codea.

But there are things we might yet do if this were a real business project. First, we might want more tests. These were the bare minimum. We might want to deal with errors like dividing by zero, or errors like typing one operator after another. And so on. We should test all those and make them do whatever we decide is right.

That can get bloody tedious. That’s why programmers in real life get paid, I suppose. But frankly, I’d rather do this than ship a product that has bugs in it, and I’d rather code this way than leave code lying around for the unsuspecting future me to look at and go WTF????

Practices — and do you really do this??

Let’s look at some of the key aspects of what I’ve done in this exercise.

Quick Design

First, I started with a little bit of design. I drew a picture of how I thought a calculator works. Remember that I got it wrong. The more we design without feedback, the more we get bits wrong. We’re tempted to say “we should have designed more”, but I believe the truth is “we should have gotten concrete feedback sooner”.

Begin with tests

Then, I did move quickly to an implementation. I started with tests. Automated tests cause me to think a bit more carefully about what I’m doing, and they can be run again and again to be sure I don’t break anything. And once in a while, when a test “fails”, I look at it and realize that my expectation as expressed in the test is wrong: my understanding of what I’m doing is wrong.

When a test fails, I always learn something. Usually I learn that I’ve not yet built a feature. Sometimes I learn that I’ve broken an old feature. Sometimes I learn that I don’t know what I want. Sometimes I learn that I fumble-fingered in the test or in the code. It’s all good. When the tests work, I have growing confidence in the program, and when they fail, it alerts me to an incoming learning.

Build from a simple (nearly stupid) design

Remember that I started by just appending every key press to the displayed answer. Some would call that stupid: we in the Agile programming universe call it simple. (Sometimes we return a constant for a variable answer. If it’s the correct constant for our current test, we call that pattern “Fake it til you make it”. I don’t think I did that here.)

Appending the key press isn’t wrong … it’s just wrong sometimes. So I do it, and some tests pass. When one fails, I’ve discovered when “sometimes” is.

Just make the test pass

Now, trust me, I am fairly good at programming, so I really did know that times was going to show up in the display, and that that was bad. But I didn’t code for that. I coded to make the next test pass.

What I do is make the test pass with the simplest code I can write. Not bad code, but simple. I make the code “more nearly” do the right thing. Inch by inch, step by step (slowly he turned), I make the program work, guided by my tests. I try never to write a line of code that isn’t required by the test I’m working on.

Refactor to make the code clean

I’m always watching for code that is not clean. It might be in my tests, and it will certainly be in the production code.

When my tests are green — all running — I look for ways to improve it. I changed the code to use an anonymous function at one of those points, and it worked out well.

Avoid the esoteric

Anonymous functions are pretty popular these days, in some circles, but to some programmers they are quite odd because they may have never used a language where they are possible.

I don’t use them often myself so I wanted to try it. Against doing that was my own lack of practice, and the fact that I’m kind of writing to beginners with Codea. In favor of doing it was that it’s an important thing to be good at in Lua, and that I had my tests to guide me.

Is the anonymous function too esoteric for you? Then don’t do it. And if you do decide to try something cool, make sure it’s surrounded by tests. Some teams have a rule that if anyone every writes something “cool”, it has to be deleted. Cool code is the code that bites you at 2 AM when you are called in to get the system back up.

So, use judgment.

Bottom line — nearly

All these words aside, if you’ll think about what we did here, it went incredibly smoothly. We wrote some tests, made them work one after another, worked very simply, cleaned up the code as we went. We had no long debugging or “what the heck is going on” sessions.

Click click click. That’s how it goes when I work this way. Might it work for you? I think it might.

Enough already

OK, this is more than enough for a single article. But I’ve decided not to split it apart. I’ll warn readers at the top to consider small bites. If you made it all the way down here, congratulations and thanks for reading.

You can offer feedback on the codea.io forums if you’re a member, or drop me an email. If there are interesting questions, I’ll update this or write a follow-up. For now, thanks for tuning in.

Categories: Blogs

The Agile Reader – Weekend Edition: 10/10/2014

Scrumology.com - Kane Mar - Fri, 10/10/2014 - 10:20

You can get the Weekend Edition delivered directly to you via email by signing up http://eepurl.com/0ifWn.

The Weekend Edition is a list of some interesting links found on the web to catch up with over the weekend. It is generated automatically, so I can’t vouch for any particular link but I’ve found the results are generally interesting and useful.

  • Cynical Agile and Scrum Dictionary – Yuriy Zubarev #LOL #Fun
  • RT @velkan12: great video about agile work flow #uzility #agile #kanban #scrum @UzilitySoftware
  • #Accenture is hiring! Agile Methods (Scrum/FDD/XP/Crystal/DSDM) in #Kolkata, apply now! #job http://t.co/APOkPL5c4E
  • New #job opening at #Accenture in #Kolkata! Agile Methods (Scrum/FDD/XP/Crystal/DSDM) http://t.co/HNDrDB5jYS
  • Agile Methods (Scrum/FDD/XP/Crystal/DSDM) needed in #Kolkata, apply now at #Accenture! #job http://t.co/J8EA4sSMW2
  • Agile Methods (Scrum/FDD/XP/Crystal/DSDM) needed in #Kolkata, apply now at #Accenture! #job http://t.co/cq0jRBBEqV
  • Agile Methods (Scrum/FDD/XP/Crystal/DSDM) (#job) wanted in #Kolkata. #Accenture http://t.co/nxNrcH441O
  • Apply now to work for #Accenture as Agile Methods (Scrum/FDD/XP/Crystal/DSDM)! (#Kolkata) #job http://t.co/p7YkCMXHO2
  • How to Plan an Agile Sprint Meeting? – http://t.co/RDht7k2Quw
  • Check out this #job: Agile Methods (Scrum/FDD/XP/Crystal/DSDM) at #Accenture (#Kolkata) http://t.co/gvDp7Ebrwp
  • Apply now to work for #Accenture as Agile Methods (Scrum/FDD/XP/Crystal/DSDM)! (#Kolkata) #job http://t.co/sfvfCKO7nP
  • Apply now to work for #Accenture as Agile Methods (Scrum/FDD/XP/Crystal/DSDM)! (#Kolkata) #job http://t.co/nbresrR6fT
  • #Accenture is hiring an Agile Methods (Scrum/FDD/XP/Crystal/DSDM), apply now! (#Kolkata) #job http://t.co/9YuKpxFYgf
  • @rkasper But wait- there’s more #agile #scrum #lean #management #innovation #leadership #triballeadership
  • How to be a Product Owner in 3 Steps — — #agile #scrum http://t.co/jUrGElkP3r
  • Try TargetProcess3 — fascinating agile project management software #targetprocess #kanban #scrum
  • New #job opening at #Accenture in #Kolkata! Agile Methods (Scrum/FDD/XP/Crystal/DSDM) http://t.co/kZJHjnRiTB
  • Apply now to work for #Accenture as Agile Methods (Scrum/FDD/XP/Crystal/DSDM)! (#Kolkata) #job http://t.co/oweptJLVwW
  • Agile by McKnight, Scrum by Day is out! Stories via @spencerhurst @SaraHitchcock
  • 5 Myths About #DevOps… And One Hard Truth via @Champagnie #Agile #PM #Scrum
  • RT @AstrolabeMe: Cynical Agile and Scrum Dictionary – Yuriy Zubarev #LOL #Fun
  • RT @mscurah: 5 Myths About #DevOps… And One Hard Truth via @Champagnie #Agile #PM #Scrum
  • Medical Mutual: Web Business Analyst – Agile Scrum Master 14-267 (#Strongsville, OH) #IT #Job #Jobs
  • RT @mscurah: 5 Myths About #DevOps… And One Hard Truth via @Champagnie #Agile #PM #Scrum
  • RT @mscurah: 5 Myths About #DevOps… And One Hard Truth via @Champagnie #Agile #PM #Scrum
  • I liked a @YouTube video Best Online Agile Scrum Project Management Methodology Certification
  • #Accenture is hiring an Agile Scrum #Master in #SanFrancisco, apply now! #job http://t.co/paRu7PGY3H
  • RT @MasterScrum: The Lorax Would Be a Great Product Owner!
    Lessons in #scrum from a Dr Seuss classic. #agile
    http://…
  • RT @yochum: Spotify engineering culture (part 2) #agile #scrum #startup http://t.co/yo5LFi6ffc
  • RT @yochum: Spotify engineering culture (part 2) #agile #scrum #startup http://t.co/yo5LFi6ffc
  • RT @yochum: Spotify engineering culture (part 1) #agile #scrum #startup http://t.co/vLrxNsGCxq
  • Keep it Simple: What is Agile SCRUM: #scrum #agile
  • RT @AstrolabeMe: Cynical Agile and Scrum Dictionary – Yuriy Zubarev #LOL #Fun
  • RT @FreeScrumEbook: Keep it Simple: What is Agile SCRUM: #scrum #agile
  • Your stuff is too big make it smaller! #agile #scrum #thatsIntelligence
  • RT @christianlmiles: Your stuff is too big make it smaller! #agile #scrum #thatsIntelligence
  • Managing in Agile – Introducing Scope Changes
    via @AgilePJ
    #PMI-ACP#Agile#Scrum
  • #Scrum vs. #Kanban – an interesting discussion… #ScrumvsKanban #Agile
  • RT @terealvarezv: “@ShirlyRonenRL: AgiloPedia: #Stattys – Write & Slide #scrum #agile” ~~ #worthwatching
  • Agile Canada » Project Manager & Scrum Master – Colligo Networks – Vancouver, BC: Evange… #Canada #Agile #Jobs
  • #DevOps team? DevOps toolchains! #agile #scrum http://t.co/F1NlEriG1s
  • RT @Neomobile_Group: #DevOps team? DevOps toolchains! #agile #scrum http://t.co/F1NlEriG1s
  • RT @CriticalMfg: Yes, we’re #lego fans RT @CriticalMfg: Scrum training @ Critical Manufacturing #scrum #agile http:/…
  • Plus d’infos sur TV du stand @sii_ouest #atrennes #managementVisuel #calottes cc @msieur_tim http://t.co/kegUvh7Zwa
  • New #job: Business Analyst – Ecommerce / Agile / Scrum / Web Applications,Chester .. #jobs
  • RT @yochum: 10 Things You Could Do When You’re Done Writing Code #agile #scrum
  • Categories: Blogs

    Empower Teams to Increase Quality

    Ben Linders - Fri, 10/10/2014 - 09:29
    When an organization is experiencing quality problems with their products, agile software development often isn't the first solution that comes up in people's minds. Often I see people trying to address them using classical waterfall based approaches, only to find out that it will make problems even worse. I recommend agile, not only to deliver working software faster but also with the right quality. This posts shows how empowering the team helps to increase the quality of product. Continue reading →
    Categories: Blogs

    Knowledge Sharing


    SpiraTeam is a agile application lifecycle management (ALM) system designed specifically for methodologies such as scrum, XP and Kanban.