Skip to content

Blogs

Crisp DNA is now open source!

Henrik Kniberg's blog - Fri, 01/23/2015 - 13:01
Crisp DNA screenshot

Crisp DNA screenshot

We get a lot of questions about how Crisp works and why, especially from other consultants looking to create something similar. After many years of experimenting we’ve converged on a model that works well, basically the sweet spot between being an independent consultant and being an employee. So we decided to open source it.

In January 2015, at Crisp Hack Summit 10, Mats Henricsson, Henrik Kniberg and Max Wenzin huddled up and created the first version of the open-sourced Crisp DNA. It is published at http://dna.crisp.se/

The Crisp DNA is version controlled using Git and both Crisp DNA repository and Crisp DNA web site is hosted at GitHub using GitHub Pages. The web site is a bunch of static web pages and images that is generated from Markdown and Textile files using Jekyll. This is the same setup that GitHub themselves use.

By using open, version-control friendly formats such as Markdown and Textile, we hope to benefit from the open source community which can fork our model, make changes and perhaps suggest improvements. This can actually change how Crisp works!

Categories: Blogs

Big Agile, the Route Less Travelled

Leading Answers - Mike Griffiths - Fri, 01/23/2015 - 04:40
Scaling Collaboration not Process is the Key to Enterprise Agility. Agile methods have been found to be extremely effective when used correctly. A reasonable reaction to witnessing any great performance in an organization is to demand more of it. So... Mike Griffiths
Categories: Blogs

LeadingAnswers in 2015

Leading Answers - Mike Griffiths - Fri, 01/23/2015 - 04:35
I am well overdue for posting to this site, but it is not through lack of interest or ideas. There is an inverse relationship between postings and with how busy I have been. When I have time to post here... Mike Griffiths
Categories: Blogs

Multi-Tasking

Scrum Log Jeff Sutherland - Thu, 01/22/2015 - 23:53

Multitasking is a form of wasted motion. Taiichi Ohno, in his keystone book: The Toyota Production System outlined a total of 13 forms of waste. Multitasking is a classic form of Muda, or wasted effort. It happens when people, systems or machines switch between contexts. Context switching has been heavily researched and pretty much every study shows that it creates large amounts of waste (see slide.)

A scientist named Harold Pashler demonstrated this in the early 1990’s. He called it “Dual Task Interference.” Pashler theorized that there was some sort of processing bottleneck happening in a person’s brain when multi-tasking. That people can really only think about one thing at a time, that a certain amount of effort was involved in packing up one process, reaching into your memory and pulling out another, and then running that job. And each time you switch tasks, that process takes time. Numerous other studies show the same thing.

Scrum Inc. Multi-Tasking Weinberg - Context Switching Slide121 Slide121

The lessons a Scrum Master should take from this is to make sure individual Team members are protected from distractions and other Impediments that would cause them to switch from one Backlog Item to another. Other research has shown that people typically work best in 90-minute bursts followed by some recuperation time. Scrum Masters should make sure to give their Team members ample opportunity to work in blocks of uninterrupted time but also make sure they have opportunities to take care day-to-day assignments that are just a part of having a job like filling out paper work and other management overhead.

Product Owners need to demonstrate to management that their Teams can do better quality work, faster if they can work on one project at a time. The business case for this is strong. Teams can get multiple projects done is less time when they can focus on just one project at a time. The quality of their work also increases. Just like switching from writing, to reading e-mail, to a phone-call interrupts, slows down and wastes an individual Team member’s time, switching from one development project to another wastes Team time (see slide.)

Multitasking is an embedded part of our culture in the digital age. Job descriptions demand it, bosses expect and we brag about our abilities to perform it. It seems like as a society, as multi-tasking has been pushed more and more upon us, we have embraced it. Unfortunately, multi-tasking is wasteful. Don’t do it.

Back to All Topics

The post Multi-Tasking appeared first on Scrum Inc..

Categories: Blogs

Scrum Inc. Heads Back to the Valley

Scrum Log Jeff Sutherland - Thu, 01/22/2015 - 19:37

This past fall I visited some of the biggest tech players in Silicon Valley (PayPal, Twitter, Salesforce, Wallmart.com etc.) There were two take-a-ways from those visits. First, people, mostly leadership, wanted to know how to scale their Scrum implementations; and second, teams weren’t getting testing done inside the Sprint.

I’m heading back to the Valley in mid February to teach both a public CSM and CSPO course as well as a one day Scaling workshop and I plan to address these two issues head on.

Scaling: More scaling frameworks come-online everyday. Most I find overly prescriptive and limited in their efficacy. However, frameworks like SAFe are a good starting place for companies with very new implementations.

It’s important to remember that Scrum was designed to scale. The first time I scaled Scrum teams at IDX in the mid 90’s it became really clear. Scrum is based on modular or object oriented architecture. It allows multiple teams to swarm on all modules simultaneously without ripple effect. This is called all-at-once-Scrum and it was the team model Nonaka and Tachieuchi highlighted in their HBR paper that inspired Scrum. A truly effective Enterprise Scrum should be modular in design. The Scrum Inc. team has developed a scaled framework that allows companies to plug-and-pull the modules they need based on their specific context.

What is your context? Are you in a large mature industry like a government contractor? Or, are you a successful software company feeling innovation nipping at your heels? Depending on your vision, needs and industry, you will probably want to prioritize certain scaling aspects before others.

Test Inside the Sprint: Quite possibly the most important aspect of Scrum is the feedback loop. The team demonstrates working software to all the stakeholders at the end of the Sprint. The stakeholders try it out and then give the team feedback on possible improvements. Continuous improvement is really the end game here so without working software, the Scrum process breaks down.

It has to work to get feedback. You won’t know it works until you test it.

If you aren’t testing inside the Sprint, you don’t get feedback from your customers and stakeholders at Sprint Review. Feedback you need to assess what they like, what they don’t, and make changes early.

Testing is tough and a lot of teams don’t feel like they have the skill set or the opportunity to test within the Sprint. Bring you testers onto the team. Use out-of-the-box tools and develop a testing regime incrementally. With clear goals and a motivated and focused team, testing can get done before review.

-- Jeff Sutherland

The post Scrum Inc. Heads Back to the Valley appeared first on Scrum Inc..

Categories: Blogs

Coaching a Team to Get Started

Agilecraft - Petri Heiramo - Thu, 01/22/2015 - 14:06

In those times when I have had more time to work with a team to get them started, I have used the following general outline and found it working. By working I mean, it has struck a good balance between effort invested and value delivered. Investing more time could make things even faster, but not proportionally. Investing less time would reduce value and impact disproportionately. You know.

The Plan for Team’s First Sprints * Pre-game *

1) Kick-off meeting on first day, to get started (this is more
facilitation than training), including

  • What are the things we don’t know? How critical are they to know before we start Sprint 1?
  • How do we learn together?

2) High level conversations – concept, requirements, UX, design, architecture, technologies, …

3) Initial release planning workshop

  • Vision clarification
  • Writing out user stories
  • Analyzing the stories for consequences, value, risk, possibly also dependencies
  • Building initial release plan

4) Add detail to high priority stories, doing research on unknown stuff (from step 1)

  • Coaching for collaborative design
* First Sprint *

5) Sprint planning for Sprint 1, including coaching on good conversations to have

6) Run the first Sprint

  • Including a couple of refinement meetings to clarify backlog

7) Review and retrospective for Sprint 1

* Second Sprint *

8) Sprint planning for Sprint 2

9) Run the second Sprint

  • Including story estimation workshop and first version of the release burn-up
  • Including more refinement meetings

10) Review and retrospective for Sprint 2

* Third Spring and onwards *

11) Sprint planning for next Sprint

12) Run the next Sprint

  • Including more refinement meetings

13) Review and retrospective for next Sprint

The Coaching Plan Itself

The coaching plan below assumes:

  • There is one team to coach
  • More frequent participation is not possible due to e.g. budget or travel
  • Two week pre-game, two-week sprints
  • Days counted as 5 days per week
  • The project has a SM who can carry the duties while coach is away
  • The team can learn (or already know) the technical practices on their own
Week 1 – days 1 & 2

Facilitate a 1) Kick-Off Meeting to get people to know each other and aligned on shared goal.

Run 2) High-Level Conversations (possibly at least partly on same day, depending on project size), and help teams have good conversations and get started effectively.

Week 2 – day 6

Facilitate 3) Initial Release Planning Workshop with PO, Team, and key stakeholders. Instruct how to refine stories during the other days of the week ( 4) Add Detail to High-Level Stories ).

Week 3 – day 11

Facilitate 5) Sprint Planning for First Sprint.

Train for 6) Run the First Sprint.

Week 5 – Day 21 (possibly extending to day 22)

Facilitate 7) Review and Retrospective for Sprint 1, 8) Sprint Planning for Sprint 2 and 9) Run the Second Sprint.

Coaching on topics the team feels they like help.

Week 7 – Day 31

Facilitate 10) Review and Retrospective for Sprint 2 and 11) Sprint Planning for Next Sprint.

Ensure the team, SM & PO are ready for a two-sprint stretch on their own ( 12) Run the Next Sprint). Prepare them appropriately.

Week 11 – Day 51

Facilitate 13) Review and Retrospective for Next Sprint and 11) Sprint Planning for Next Sprint.

Discuss with team how they plan to go from here on their own (with remote support, as needed).

Further visits are agreed if the team wishes more support (like every 1-3 months or so).

Conversations with, coaching and training management people has to be considered separately.

Conclusion of the above:
  • 7-8 coaching days, 6 visits
  • Expectation is that PO, Team and SM can operate as a well-functioning Scrum team independently after the coaching period, with proper practices and a jelled team.
  • If there is a lot of legacy, the process probably takes a bit longer.
Possible cost-cutting opportunities (with reduced impact / outcome):

Skip the visit on week 2, and do 3) Initial Release Planning Workshop on the same visit as 1) Kick-Off Meeting & 2) High-Level Conversations.

  • Negative impact: the team hasn’t had enough time to familiarize with project information, can be mitigated with up-front study before kick-off.

On week 5, have everything in one day, even if it takes longer.

  • Negative impact: people get tired and the planning quality suffers. No real mitigation strategy (coffee doesn’t count :) ).
Longer term goals

Teach someone (like the SM from the first project) to be able to coach new teams (instead of external coach). Then start building a community of SM’s who know the process and can run the process for their teams.

Interested team members start helping other teams in adopting good engineering practices and team behaviors.

Management learns how to support these Agile teams, and barriers for effective operation are removed as they are found.


Categories: Blogs

Agile Quick Links #29

Notes from a Tool User - Mark Levison - Thu, 01/22/2015 - 09:25

miscellaneous links of interest to the Agile / Scrum community

Some interesting reading for the Agile community:
Categories: Blogs

Der alles entscheidende Unterschied im Commitment

Scrum 4 You - Thu, 01/22/2015 - 08:51

Was ist besser für ein Team? Wenn es 9 von 11 Stories oder 9 von 7 Stories schafft?

Richtig gelesen: Ich rede über die gleiche Anzahl abgearbeiteter Stories. Der einzige Unterschied ist, dass ein Team einmal 2 Stories mehr absolviert als es committet hat, während es im gegensätzlichen Fall 2 Stories weniger geschafft als committet hat. Angenommen, dass die Storypoints dieselben sind, wäre das Ergebnis doch eigentlich das Gleiche, oder? Nur ist das leider nicht so. Warum, ist recht einfach erklärt.

Übercommitment und seine Folgen

Haben Sie schon einmal ein Team erlebt, das beim Review vor versammelter Mannschaft sagen musste: “Hey Leute, es tut uns leid, aber wir konnten unser Commitment nicht erfüllen.” Für mich war es bisher meistens ein deprimierender Anblick. Hebt dann noch ein Manager mit Inbrunst die fehlerhafte Leistung hervor, fällt das Team geradewegs in das Motivationsloch des Jahres. Dann schnappen Sie sich am besten die Angeprangerten und gehen mit ihnen irgendwo hin, wo sie ihren Frust rauslassen und alles vergessen können – damit vielleicht, so halbwegs und eventuell wieder ein Start möglich wird. So oder so: der Schaden ist passiert, die Scherben können so gut wie möglich aufgesammelt werden, aber im Großen und Ganzen wars das für die nächsten Tage mit der maximal möglichen Leistungsfähigkeit.

Untercommitment und seine Folgen

Ganz im Gegensatz dazu steht das Team, das mit stolzgeblähter Brust verkünden kann: “Hey Leute, wir haben nicht nur unser Commitment erfüllt, wir haben Euch sogar noch mehr geliefert. Es war uns ein Volksfest.” Abgang von der Bühne unter donnerndem Applaus. Wie geht wohl dieses Team in den nächsten Sprint? Es ist stolz auf das, was es geschafft hat. Die Teammitglieder haben ihr Baby (das Produkt) weitergebracht und durften dem Management zeigen, was sie können. Wenn ich von etwas überzeugt bin, dann davon, dass dieses Team sein Bestes geben wird, um im nächsten Sprint noch besser zu sein und mehr zu können.

Der Grund dafür ist relativ einfach: Bekannterweise funktioniert positive Motivation wesentlich besser als Bestrafung. Falls Sie das für ein Gerücht halten, rufen Sie beim nächsten Casino an und fragen Sie nach, warum so viele Menschen weiterspielen, obwohl sie selten gewinnen, aber ganz oft verlieren. Die positive Motivation durch einen Gewinn – egal wie klein er ausfallen mag – hebt den Bestrafungseffekt des Verlierens (ebenfalls egal, wie viel Geld man schon verspielt hat) wieder auf. Dieses Prinzip funktioniert so gut, dass Casinos hervorragend davon leben können. Höchste Zeit also, diesen Effekt dafür zu nutzen, um etwas Positives für unsere Unternehmen und die Menschen darin zu tun. Denn es kann doch jeder nur gewinnen, wenn ein Team motiviert ist, gerne zur Arbeit kommt und das Management mehr bekommt, als es erwartet hat, oder?

Was bedeutet das praktisch? Versuchen Sie also nicht, Ihr Team dazu zu bewegen mehr zu committen, wenn Sie den Eindruck haben, dass es untercommittet hat. Lassen Sie dem Team stattdessen die Freude, mehr Arbeit dazunehmen zu können, sein Commitment damit zu übertreffen und das auch kommunizieren zu können. Das Team wird sich mit mehr Leistung bedanken, denn es will zeigen, was es kann – und das nützt auf Dauer der Organisation als Ganzes.

Categories: Blogs

Python/pdfquery: Scraping the FIFA World Player of the Year votes PDF into shape

Mark Needham - Thu, 01/22/2015 - 02:25

Last week the FIFA Ballon d’Or 2014 was announced and along with the announcement of the winner the individual votes were also made available.

Unfortunately they weren’t made open in a way that Ben Wellington (of IQuantNY fame) would approve of – the choice of format for the data is a PDF file!

I wanted to extract this data to play around with it but I wanted to automate the extraction as I’d done when working with Google Trends data.

I had a quick look for PDF scraping libraries in Python and R and eventually settled on Python’s pdfquery, mainly because there was lots of documentation which made it easy to get started.

One way you scrape data from a PDF is by locating an element on the page and then grabbing everything within a bounded box relative to that element.

In my case I had 17 pages all of which had a heading for each of six columns.

2015 01 22 00 08 18

I wanted to grab the data in each of those columns but initially struggled working out what elements I should be looking for until I came across the following function which allows you to dump an XML version of the PDF to disk:

import pdfquery
pdf = pdfquery.PDFQuery("fboaward_menplayer2014_neutral.pdf")
pdf.load()
pdf.tree.write("/tmp/yadda", pretty_print=True)

The output looks like this:

$ head -n 10 /tmp/yadda
<pdfxml ModDate="D:20150110224554+01'00'" CreationDate="D:20150110224539+01'00'" Producer="Microsoft&#174; Excel&#174; 2010" Creator="Microsoft&#174; Excel&#174; 2010">
  <LTPage bbox="[0, 0, 841.8, 595.2]" height="595.2" pageid="1" rotate="0" width="841.8" x0="0" x1="841.8" y0="0" y1="595.2" page_index="0" page_label="">
    <LTAnon> </LTAnon>
    <LTTextLineHorizontal bbox="[31.08, 546.15, 122.524, 556.59]" height="10.44" width="91.444" word_margin="0.1" x0="31.08" x1="122.524" y0="546.15" y1="556.59"><LTTextBoxHorizontal bbox="[31.08, 546.15, 122.524, 556.59]" height="10.44" index="0" width="91.444" x0="31.08" x1="122.524" y0="546.15" y1="556.59">FIFA Ballon d'Or 2014 </LTTextBoxHorizontal></LTTextLineHorizontal>
    <LTAnon> </LTAnon>
    <LTAnon> </LTAnon>
    <LTAnon> </LTAnon>
    <LTAnon> </LTAnon>
    <LTAnon> </LTAnon>
    <LTAnon> </LTAnon>

Having scanned through the file I realised that what I needed to do was locate the ‘LTTextLineHorizontal’ element for each heading and then grab all the ‘LTTextLineHorizontal’ elements that appeared in that column.

I started out by trying to grab the ‘Name’ column on the first page:

>>> name_element = pdf.pq('LTPage[pageid=\'1\'] LTTextLineHorizontal:contains("Name")')[0]
>>> name_element.text
'Name '

Next I needed to get the other elements in that column. With a bit of trial and error I ended up with the following code:

x = float(name_element.get('x0'))
y = float(name_element.get('y0'))
cells = pdf.extract( [
         ('with_parent','LTPage[pageid=\'1\']'),
         ('cells', 'LTTextLineHorizontal:in_bbox("%s,%s,%s,%s")' % (x, y-500, x+150, y))
    ])
 
>>> [cell.text.encode('utf-8').strip() for cell in cells['cells']]
['Amiri Islam', 'Cana Lorik', 'Bougherra Madjid', 'Luvu Rafe Talalelei', 'Sonejee Masand Oscar', 'Amaral Felisberto', 'Liddie Ryan', 'Griffith Quinton', 'Messi Lionel', 'Berezovskiy Roman', 'Breinburg Reinhard', 'Jedinak Mile', 'Fuchs Christian', 'Sadigov Rashad', 'Gavin Christie', 'Hasan Mohamed', 'Mamun Md Mamnul Islam', 'Burgess Romelle', 'Kalachou Tsimafei', 'Komany Vincent', 'Eiley Dalton', 'Nusum John', 'Tshering Passang', 'Raldes Ronald', 'D\xc5\xbeeko Edin', 'Da Silva Santos Junior Neymar', 'Ceasar Troy', 'Popov Ivelin', 'Kabore Charles', 'Ntibazonkiza Saidi', 'Kouch Sokumpheak']

I cleaned that up and generified it to work for any page and for columns of different widths. This is what the function looks like:

def extract_cells(page, header, cell_width):
    name_element = pdf.pq('LTPage[pageid=\'%s\'] LTTextLineHorizontal:contains("%s")' % (page, header))[0]
    x = float(name_element.get('x0'))
    y = float(name_element.get('y0'))
    cells = pdf.extract( [
         ('with_parent','LTPage[pageid=\'%s\']' %(page)),
         ('cells', 'LTTextLineHorizontal:in_bbox("%s,%s,%s,%s")' % (x, y-500, x+cell_width, y))
    ])
    return [cell.text.encode('utf-8').strip() for cell in cells['cells']]

We can then call that for each column on the page and zip together the resulting arrays to get a tuple for each row:

roles = extract_cells(1, "Vote", 50)
countries = extract_cells(1, "Country", 150)
voters = extract_cells(1, "Name", 170)
first = extract_cells(1, "First (5 points)", 150)
second = extract_cells(1, "Second (3 points)", 150)
third = extract_cells(1, "Third (1 point)", 130)
 
>>> for vote in zip(roles, countries, voters, first, second, third)[:5]:
       print vote
 
('Captain', 'Afghanistan', 'Amiri Islam', 'Messi Lionel', 'Cristiano Ronaldo', 'Ibrahimovic Zlatan')
('Captain', 'Albania', 'Cana Lorik', 'Cristiano Ronaldo', 'Robben Arjen', 'Mueller Thomas')
('Captain', 'Algeria', 'Bougherra Madjid', 'Cristiano Ronaldo', 'Robben Arjen', 'Benzema Karim')
('Captain', 'American Samoa', 'Luvu Rafe Talalelei', 'Neymar', 'Robben Arjen', 'Cristiano Ronaldo')
('Captain', 'Andorra', 'Sonejee Masand Oscar', 'Cristiano Ronaldo', 'Mueller Thomas', 'Kroos Toni')

The next step was to write out each of those rows to a CSV file so we can use it from another program. The full script looks like this:

import pdfquery
import csv
 
def extract_cells(page, header, cell_width):
    name_element = pdf.pq('LTPage[pageid=\'%s\'] LTTextLineHorizontal:contains("%s")' % (page, header))[0]
    x = float(name_element.get('x0'))
    y = float(name_element.get('y0'))
    cells = pdf.extract( [
         ('with_parent','LTPage[pageid=\'%s\']' %(page)),
         ('cells', 'LTTextLineHorizontal:in_bbox("%s,%s,%s,%s")' % (x, y-500, x+cell_width, y))
    ])
    return [cell.text.encode('utf-8').strip() for cell in cells['cells']]
 
if __name__ == "__main__":
    pdf = pdfquery.PDFQuery("fboaward_menplayer2014_neutral.pdf")
    pdf.load()
    pdf.tree.write("/tmp/yadda", pretty_print=True)
 
    pages_in_pdf = len(pdf.pq('LTPage'))
 
    with open('votes.csv', 'w') as votesfile:
        writer = csv.writer(votesfile, delimiter=",")
        writer.writerow(["Role", "Country", "Voter", "FirstPlace", "SecondPlace", "ThirdPlace"])
        for page in range(1, pages_in_pdf + 1):
            print page
            roles = extract_cells(page, "Vote", 50)
            countries = extract_cells(page, "Country", 150)
            voters = extract_cells(page, "Name", 170)
            first = extract_cells(page, "First (5 points)", 150)
            second = extract_cells(page, "Second (3 points)", 150)
            third = extract_cells(page, "Third (1 point)", 130)
            votes = zip(roles, countries, voters, first, second, third)
            print votes
            for vote in votes:
                writer.writerow(list(vote))

The code is on github if you want to play around with it or if you just want to grab the votes data that’s there too.

Categories: Blogs

Hiding Recursion With Nested Functions In JavaScript

Derick Bailey - new ThoughtStream - Wed, 01/21/2015 - 22:01

I can’t even count the number of times that I’ve written recursion in my code – directories, tree nodes, object graphs… whatever the case was. It’s a fairly important part of dealing with things in software, it seems.

recursion

But in all these times I’ve done this in the past, I’ve usually had some sort of ugly group of functions or separate class / object with an ugly group of functions to handle this for me.

Hide The Ugly Parts

I found myself needing to do recursion again, today. And I was about to complain about how ugly it was to have all these extra functions on my object just for recursion, when it hit me that I don’t need to do that. I can hide the ugly inside of a single function, using nested functions in JavaScript.

The end result is pretty nice:

Now I don’t ever have to see the “extra” function for recursion on my object’s API. It’s hidden inside of the actual API call that I care about.

This may not be anything new or revolutionary (nothing I do ever is!), but it was a fun little “aha!” moment for me, today.

 

 

P.S. In case your wondering, the code above if MongooseJS code. Need to learn more about Mongoose and MongoDB? Check out my WatchMeCode screencast series on MongooseJS Fundamentals.

Categories: Blogs

Implementing Scrum in a Non-Engineering Team

TV Agile - Wed, 01/21/2015 - 18:57
This session tells the story of how a team comprising of marketing, customer support and agency relations experts used Scrum to improve its communication and alignment. It will look at what went well, what we could have improved, what failed utterly and what we learned in the process! In October 2013, the Growth team at […]
Categories: Blogs

We Need Planning; Do We Need Estimation?

Johanna Rothman - Wed, 01/21/2015 - 15:37

As I write the program management book, I am struck by how difficult it is to estimate large chunks of work.

In Essays on Estimation and Manage It!, I recommend several approaches to estimation, each of which include showing that there is no one absolute date for a project or a program.

What can you do? Here are some options:

  1. Plan to replan. Decide how much to invest in the project or program for now. See (as in demo) the project/program progress. Decide how much longer you want to invest in the project or program.
  2. Work to a target date. A target date works best if you work iteratively and incrementally. If you have internal releases often, you can see project/program progress and replan. (If you use a waterfall approach, you are not likely to meet the target with all the features you want and defects you don’t want. If you work iteratively and incrementally, you refine the plan as you approach the target. Notice I said refine the plan, not the estimate.
  3. Provide a 3-point estimate: possible, likely, and worst case. This is PERT estimation.
  4. Provide a percentage confidence with your estimate. You think you can release near a certain date. What is your percentage confidence in that date? This works best with replanning, so you can update your percentage confidence.

Each of these shows your estimation audience you have uncertainty. The larger the project or program, the more you want to show uncertainty.

If you are agile, you may not need to estimate at all. I have managed many projects and programs over the years. No one asked me for a cost or schedule estimate. I received targets. Sometimes, those targets were so optimistic, I had to do a gross estimate to explain why we could not meet that date.

However, I am not convinced anything more than a gross estimate is useful. I am convinced an agile roadmap, building incrementally, seeing progress, and deciding what to do next are good ideas.

Agile Roadmap When you see this roadmap, you can see how we have planned for an internal release each month.

With internal releases, everyone can see the project or program progress.

In addition, we have a quarterly external release. Now, your project or program might not be able to release to your customers every quarter. But, that should be a business decision, not a decision you make because you can’t release. If you are not agile, you might not be able to meet a quarterly release. But, I’m assuming you are agile.

Agile Roadmap, One Quarter at a time In the one-quarter view, you can see the Minimum Viable Products.

You might need to replace MVPs with MIFS, Minimum Indispensable Feature Sets, especially at the beginning.

If you always make stories so small that you can count them, instead of estimate them, you will be close. You won’t spend time estimating instead of developing product, especially at the beginning.

You know the least about the risks and gotchas at the beginning of a project or program. You might not even know much about your MIFS or MVPs. However, if you can release something for customer consumption, you can get the feedback you need.

Feedback is what will tell you:

  • Are these stories too big to count? If so, any estimate you create will be wrong.
  • Are we delivering useful work? If so, the organization will continue to invest.
  • Are we working on the most valuable work, right now? What is valuable will change during the project/program. Sometimes, you realize this feature (set) is less useful than another. Sometimes you realize you’re done.
  • Are we ready to stop? If we met the release criteria early, that’s great. If we are not ready to release, what more do we have to do?

Here’s my experience with estimation. If you provide an estimate, managers won’t believe you. They pressure you to “do more with less,” or some such nonsense. They say things such as, “If we cut out testing, you can go faster, right?” (The answer to that question is, “NO. The less technical debt we have or create, the faster we can go.”)

However, you do need the planning of roadmaps and backlogs. If you don’t have a roadmap that shows people something like what they can expect when, they think you’re faking. You need to replan the roadmap, because what the teams deliver won’t be everything the product owner wanted. That’s okay. Getting feedback about what the teams can do early is great.

There are two questions you want to ask people who ask for estimates:

  1. How much would you like to invest in this project/program before we stop?
  2. How valuable is this project/program to you?

If you work on the most valuable project/program, why are you estimating it? You need to understand how much the organization wants to invest before you stop. If you’re not working on the most valuable project/program, you still want to know how much the organization wants to invest. Or, you need a target date. With a target date, you can release parts iteratively and incrementally until you meet the target.

This is risk management for estimation and replanning. Yes, I am a fan of #noestimates, because the smaller we make the chunks, the easier it is to see what to plan and replan.

We need planning and replanning. I am not convinced we need detailed estimation if we use iterative and incremental approaches.

Categories: Blogs

Looking back on 2014

AvailAgility - Karl Scotland - Wed, 01/21/2015 - 13:24

This is a little later than I would have liked, but 2015 seems to have had a busy start! As I look back on last year, the main thing that stands out for me was my decision to go solo. As a result, the second half of the year was an interesting learning curve for me, and as I look forward to 2015, I’m please with the way events have unfolded, and excited by future possibilities. In particular, I’ve been able to focus more time on Kanban Thinking, including put together the downloadable Kanban Canvas, and writing more about how I use it.

On the topic of writing, you can read the blog’s 2014 annual report for the full statistics. The highlights for me were the fact that I had my busiest day, and I managed 23 posts – a significant increase from 2013. I hope I can maintain, and even continue to improve that number. Also interesting is that the top 3 posts remain the same; Kanban, Flow and Cadence“,What is Cadence? and Fidelity – The Lost Dimension of the Iron Triangle. Its nice to see Running the Ball Flow Game come in at number 4 – I love playing that game in workshops and it always seems to generate good discussion and learning. Finally, Making an Impact with Kanban Thinking is at number 5, and given that this is a recent post, I hope this bodes well for the future of Kanban Thinking in general.

The other big passion of mine in 2014 was taking up running, which I mentioned a when I posted on Estimates as Sensors. According to MapMyRun, I did a total of 177 runs, with an average run of 5.11 miles (giving a total of 904.5 miles), and a longest run of 17 miles. My average pace was 9:06 min/mile and my fastest pace was 4:31 min/mile.

For posterity, here’s my PB’s for the 2014

I’m currently training for the Brighton Marathon (watch this space for a call for sponsorship) so I’m also expecting those number to go up (or down for pace!). As part of my running addiction, I’ve become involve in my local parkrun community – something I gave a lightning talk about at LKUK14.

Thanks you for reading this blog, and for the continued support. I look forward to more of the same in 2015, and hope I get to meet many of you in person. Please let me know if you’d like me to work with you, or just say “Hi” if you see me at a conference or event.

Categories: Blogs

fighting temptation and building good habits

Derick Bailey - new ThoughtStream - Wed, 01/21/2015 - 13:00

A reader recently asked me a question about habits, and building good ones:

What is the best way to form good habits? You see all these books: Miracle Morning, Getting Things Done, Superhuman by Habit, Pomodoro Technique, etc. They all provide ways to better manage your time, so you have time for side projects, etc. But most of them don’t really say what to do when you are tired, feel like hitting the snooze button rather than getting up, or feel like checking twitter rather than banging out the 20 unit tests on your plate. What do you do to stay focused and form good habits?

As I was thinking about the questions and thoughts about what I wanted to say were running through my head, I realized that most of what I wanted to say were things that my friend John Sonmez had been talking about recently. John’s a fountain of knowledge, when it comes to getting things done, building habits and generally making yourself a better person, not just a better developer. So, rather than me trying to re-hash the things that John says so well, I asked him to respond to the questions directly. Fortunately for me, and you, he did!

Here, as a guest post to my newsletter and archive, is John Sonmez, answering the question of how to build good habits.

I don’t know if you know it or not, but you’ve basically just asked the question “what is the secret to success?” because habits—and more specifically executing on them when you don’t feel like it—is exactly that.

If I could take success and put it in a bottle and drink it, it would taste like consistency and sweat. (In case you are wondering “consistency” tastes a bit like slightly soured milk, and sweat… well, it’s salty.)

Every single successful person I know has figured out some way to bottle this substance and to drink healthy servings of it, just about every day.

But, of course this is a lot easier said than done—otherwise we’d all be super successful.

So, how do you actually become consistent?

How do you actually develop habits?

Especially when the passion has died down and you just aren’t feeling motivated?

Unfortunately, there is no easy answer to these questions.

I can’t handle you that bottle of sour milk and sweat for you to drink. It’s up to all of us to brew up our own batch.

potion

Brewing up a batch of “success” juice

It all starts with the proper mindset.

As lazy human beings, we tend to be pretty short-sighted.

My wife handed me two Cadbury Creme Eggs that she picked up when she went to the store and they are sitting there on my desk, staring at me, trying to prevent my mind from thinking about anything else.

I have to actively fight and resist the urge to eat them, because I know that eating chocolate eggs, when I am supposed to be working and when they aren’t on my planned diet, is going to be counter-productive to my long term goals.

But, I am resisting them. I am sitting here typing this email, because I’ve figured out—at least in some way—to shift my thinking from the short-term to the long-term.

If you want to get out of bed instead of hitting the snooze button, you have to think about more than just today. You have to think about how making that decision 100 or 1,000 times will affect your life. That is what thinking in the long-term is about.

If you want to write those unit tests and get some real work done. You’ve got to think about how choosing to work instead of goofing off is going to play out over the course of the next 5 years.

It’s not easy to think this way, so most people don’t even try.

Most people just make the short-term decision that feels good.

They plop down in front of the TV, instead of working on their side-project.

They stuff their face full of junk, instead of carefully planning their meals and losing the 10—or 50—pounds they’ve been trying to lose for the last 5 years.

laz

They are the same kind of people who always start out with good intentions.

We’ve all been that kind of person at some time in our lives—perhaps you are now. (I know I still am from time-to-time.)

But, we have to fight it.

We have to see something bigger on the horizon.

We have to realize that when we give up a battle with temptation, laziness or procrastination, we aren’t just making a single decision, we are setting a course. A course that will eventually run our ship aground.

Only by changing your mindset to realize these things—to thing big; long term—can you ever hope to build and execute on good habits.

Most people know exactly what they need to do to achieve their goals in life.

Fat people know they need to stop eating so much and exercise more.

Broke people know they need to stop spending so much.

Lazy people know they need to stop procrastinating all the time.

But, do they do it?

No.

Will you do it?

It’s up to you.

The drink isn’t very tasty and it has a hell of a bite, but if you mix up a batch and start chugging it, you’ll do what 99% people are incapable of.

And when you do, productivity tricks aside, you are going to see results.

That’s all I have time for to include in this email, but I have a whole section devoted to productivity in my book “Soft Skills: The Software Developer’s Life Manual.”

You can also find a chapter that deals specifically with how to be get things done when you don’t feel motivated called “Burnout? I’ve got the cure.

– John Sonmez

Categories: Blogs

Scrum in der Hardware – eine Zwischenbilanz

Scrum 4 You - Wed, 01/21/2015 - 08:46

Als Takeuchi und Nonaka 1986 den Artikel “The New New Product Development Game” veröffentlichten, fiel das Wort “Scrum” zum ersten Mal im Kontext der Produktentwicklung. Dort ging es nicht um Softwareapplikationen, sondern um Kopierer, Fotokameras und PCs. Dennoch stand die Blütezeit von Scrum ganz im Zeichen der Softwareentwicklung: Das Rahmenwerk, das wir heute kennen, entstand in den 1990er und frühen 2000er-Jahren.

Allmählich wird Scrum für die Hardwareentwicklung wieder entdeckt. Das ist kein Zufall: Die Entwickler von Hardwareprodukten stehen heute vor ähnlichen Herausforderungen wie die Softwareentwicklung Anfang der 1990er Jahre. Unternehmen in der Medizin- oder Messtechnik, die vor einem Jahrzehnt mit einer handvoll innovativer Produkte die Marktführerschaft erobert haben, müssen wieder einmal vorangehen. Doch dieses Mal sind die Vorzeichen andere: Ihre Produkte verkaufen sich mittlerweile in der ganzen Welt und die Konkurrenz ist in der Lage, die Produkte aus dem Katalog in kurzer Zeit nachzubauen und preislich zu unterbieten. Um die Marktführerschaft zu erhalten, müssen Unternehmen am Ball bleiben.

Am Ball zu bleiben wird umso schwieriger, je erfolgreicher das Unternehmen ist. Denn Wachstum bedeutet häufig auch, dass selbständig agierende, kleine Teams einer übegreifenden Abteilungs- und Projektstruktur weichen müssen. Wie können innovative und zuverlässige Produkte entstehen, wenn ganze Entwicklungsabteilungen vor sich hin arbeiten, die dann auch noch mit QA, Fertigung, Einkauf, Produktmanagement und Vertrieb in Einklang zu bringen sind?

Scrum bietet mit seinem Augenmerk auf selbstorganisierte Einheiten, in denen das Wissen der Abteilungen im Mikrokosmos eines Teams gebunden ist, eine erfrischende Alternative zu herkömmlichen Produktentstehungsprozessen. Wie aber sehen die bisherigen Erfahrungen mit Scrum in der Hardwareentwicklung aus? Es ist Zeit, eine Zwischenbilanz zu ziehen.

Eine Mannschaft aufstellen, die alle Positionen beherrscht

Für die erfolgreiche Lieferung eines Hardwareprodukts braucht es nicht nur Spezialisten für Software, Hardware und Konstruktion. Zulieferer, Fertigung und QA können entscheidende Beiträge leisten, wenn es um die richtige Auswahl von Bauteilen oder um geeignete Produktionsverfahren geht. In Scrum haben wir den Vorteil, dass wir jeden dieser Spezialisten völlig unbürokratisch in jene Sprints mit einbinden können, in denen ihr Wissen gefragt ist. Diese sind dann z.B. Teil des 15-minütigen Daily Scrums und können darin selber Aufgaben übernehmen. Je früher sie eingebunden werden, desto überflüssiger werden die üblichen zeit- und kostenintensiven “Nachbesserungsrunden” vor (und häufig sogar nach) dem Produkt-Launch.

Was bringt die Software ohne das Gehäuse?

Gerade in der Hardwareentwicklung können leicht “Paralleluniversen” entstehen. Der Konstrukteur baut sein Gehäuse, der Hardware-Entwickler seine Platine. Erst spät fällt auf, dass beides nicht so richtig zusammenpasst, weil z.B. die Bohrungen für die Befestigungen den Bestückungsraum für die Platine einschränken. Oder weil die vorgesehene Lichtleiterkonstruktion Dichtigkeitsprobleme beim Ausschäumen hervorrufen könnte. Wenn das Wissen um diese Abhängigkeiten im Team vorhanden ist, können die Inkremente auf Komponenten-Ebene (Gehäuse, Platine) zu einem Inkrement auf Produkt-Ebene zusammengeführt werden. Das Team stellt dann im Sprint Review einen Stand des Produkts vor, der bereits aus verschiedenen Perspektiven (Konstrukteur, HW-Entwickler, Fertiger) verifiziert worden ist.

Die richtige Lösung für das richtige Problem

Wenige Unternehmen sind es gewohnt, Kunden und User zu ihren Sprint Reviews einzuladen. Am Ende entstehen so Produkte, die ein Problem lösen, das der Kunde so gar nicht hat. Dabei kann gerade in der Hardwareentwicklung mit einfach Mitteln (3D-Drucker, virtuelle Modellierung) ein sehr konkretes Bild des künftigen Produktes vermittelt werden. Dafür braucht es einen Product Owner, der direkte Anbindung an den Markt hat (und nicht nur auf die Anforderungen des Vetriebs angewiesen ist), den Kunden mit einer eigenen Vision führen kann (anstatt ihn zu fragen, was er denn haben möchte) und in die Stärken seines Entwicklungsteams vertrauen kann. So können die Reviews genutzt werden, um das Produkt durch Kunde und User validieren zu lassen und so möglichst früh Weichenstellungen in der Entwicklung durchzuführen.

Über den Sprint hinausschauen

In der Softwareentwicklung messen wir den Durchsatz an entwickelten Funktionalitäten pro Sprint, um die Geschwindigkeit des Teams zu bestimmen. In der Hardwareentwicklung müssen wir anders vorgehen, da die Laufzeiten bis zur Fertigstellung einer Funktionalität länger sind. So sind mehrere Entwicklungsschritte (z.B. Platzstudie, Stromlaufplan, Layout, PCB) erforderlich, bis eine Funktionalität (z.B. das Auslesen von RFID-Tags) fertig ist. Deshalb bauen wir das Product Backlog auf zwei Ebenen auf:

  1. Auf der Feature-Ebene sind die Funktionen des Produkts aus Benutzersicht mit ihren Rahmenbedingungen beschrieben (z.B. das Auslesen und Beschreiben von Datenträgern mit einer bestimmten Geschwindigkeit und Leseabstand).
  2. Auf der System-Ebene sind die Entwicklungsschritte innerhalb der verschiedenen Disziplinen (Konstruktion, Hardware, Software) beschrieben, die zum Erreichen der gewünschten Funktionalität erforderlich sind. Wir ermitteln die Geschwindigkeit auf dieser zweiten Ebenen (wie viele Entwicklungsschritte schafft das Team pro Sprint), um die Dauer bis zum Erreichen der ersten Ebene (fertig gestellte Funktionalitäten) zu ermitteln. Hierbei ist die Berücksichtigung von harten Abhängigkeiten (wann läuft die Entwicklung leer, weil sie z.B. auf Lieferungen der Software angewiesen ist?) wichtig, um eine rechtzeitige Einplanung in die Sprints zu ermöglichen.

Scrum ist seinerzeit angetreten, um Unternehmen, die sich in Entwicklungsphasen und Abteilungsdenken verzettelt hatten, wieder lieferfähig zu machen. Mit Scrum haben wir ein vergleichweise leichtes Regelwerk, das durch kurze Iterationen und interdisziplinäre Teams den Augenmerk auf eine zuverlässige Integration des Produkts bei einer klaren Ausrichtung am Markt legt. Nirgendwo ist dieser Bedarf dafür aktuell größer als in der Hardwareentwicklung.

Whitepaper Scrum in der Hardwareentwicklung

Tipp: Am 10.2.2015 diskutieren wir von 16 bis 17 Uhr in einem Webinar über Scrum in der Hardwareentwicklung. Unsere Gäste sind Claus Höhn, Entwicklungsleiter der Business Unit Identification bei Balluff GmbH und Christoph Wehe, Product Owner bei Thermo Fisher Scientific Inc. Alle Infos dazu gibt es hier

Categories: Blogs

Integrating MediatR with Web API

Jimmy Bogard - Tue, 01/20/2015 - 19:25

One of the design goals I had in mind with MediatR was to limit the 3rd party dependencies (and work) needed to integrate MediatR. To do so, I only take a dependency on CommonServiceLocator. In MediatR, I need to resolve instances of request/notification handlers. Rather than build my own factory class that others would need to implement, I lean on CSL to define this interface:

public interface IServiceLocator : IServiceProvider
{
    object GetInstance(Type serviceType);
    object GetInstance(Type serviceType, string key);
    IEnumerable<object> GetAllInstances(Type serviceType);
    TService GetInstance<TService>();
    TService GetInstance<TService>(string key);
    IEnumerable<TService> GetAllInstances<TService>();
}

But that wasn’t quite enough. I also wanted to support child/nested containers, which meant I didn’t want a single instance of the IServiceLocator. Typically, when you want a component’s lifetime decided by a consumer, you depend on Func<Foo>. It turns out though that CSL already defines a delegate to provide a service locator, aptly named ServiceLocatorProvider:

public delegate IServiceLocator ServiceLocatorProvider();

In resolving handlers, I execute the delegate to get an instance of an IServiceLocatorProvider and off we go. I much prefer this approach than defining my own yet-another-factory-interface for people to implement. Just not worth it. As a consumer, you will need to supply this delegate to the mediator.

I’ll show an example using StructureMap. The first thing I do is add a NuGet dependency to the Web API IoC shim for StructureMap:

Install-Package StructureMap.WebApi2

This will also bring in the CommonServiceLocator dependency and some files to shim with Web API:

image

I have the basic building blocks for what I need in order to have a Web API project using StructureMap. The next piece is to configure the DefaultRegistry to include handlers in scanning:

public DefaultRegistry() {
    Scan(
        scan => {
            scan.TheCallingAssembly();
            scan.AssemblyContainingType<PingHandler>();
            scan.WithDefaultConventions();
			scan.With(new ControllerConvention());
            scan.AddAllTypesOf(typeof(IRequestHandler<,>));
            scan.AddAllTypesOf(typeof(IAsyncRequestHandler<,>));
            scan.AddAllTypesOf(typeof(INotificationHandler<>));
            scan.AddAllTypesOf(typeof(IAsyncNotificationHandler<>));
        });
    For<IMediator>().Use<Mediator>();
}

This is pretty much the same code you’d find in any of the samples in the MediatR project. The final piece is to hook up the dependency resolver delegate, ServiceLocatorProvider. Since most/all containers have implementations of the IServiceLocator, it’s really about finding the place where the underlying code creates one of these IServiceLocator implementations and supplies it to the infrastructure. In my case, there’s the Web API IDependencyResolver implementation:

public IDependencyScope BeginScope()
{
    IContainer child = this.Container.GetNestedContainer();
    return new StructureMapWebApiDependencyResolver(child);
}

I modify this to use the current nested container and attach the resolver to this:

public IDependencyScope BeginScope()
{
    var resolver = new StructureMapWebApiDependencyResolver(CurrentNestedContainer);

    ServiceLocatorProvider provider = () => resolver;

    CurrentNestedContainer.Configure(cfg => cfg.For<ServiceLocatorProvider>().Use(provider));
    
    return resolver;
}

This is also the location where I’ll attach per-request dependencies (NHibernate, EF etc.). Finally, I can use a mediator in a controller:

public class ValuesController : ApiController
{
    private readonly IMediator _mediator;

    public ValuesController(IMediator mediator)
    {
        _mediator = mediator;
    }

    // GET api/values
    public IEnumerable<string> Get()
    {
        var result = _mediator.Send(new Ping());

        return new string[] { result.Message };
    }

That’s pretty much it. How you need to configure the mediator in your application might be different, but the gist of the means is to configure the ServiceLocatorProvider delegate dependency to return the “thing that the framework uses for IServiceLocator”. What that is depends on your context, and unfortunately changes based on every framework out there.

In my example above, I’m preferring to configure the IServiceLocator instance to be the same instance as the IDependencyScope instance, so that any handler instantiated is from the same composition root/nested container as whatever instantiated my controller.

See, containers are easy, right?

(crickets)

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Categories: Blogs

News update 2015/01 – Scrum Coaching Retreat Cape Town

ScrumSense.com - Peter Hundermark - Tue, 01/20/2015 - 15:29

Scrum Coaching Retreat Cape TownYou may be considering attending the upcoming Scrum Coaching Retreat (SCR) to be held in Franschhoek, near Cape Town on 09-11 February 2015. And you may be wondering what the value will be to you. You may also need to find a convincing argument for your boss to sign off on the registration fee and, perhaps, travel costs from Jhb or elsewhere.

Well in this month’s blog post, Peter Hundermark shares his personal experiences of past Scrum Coaching Retreats in Colorado and London. Discover what he learnt and what to expect from South Africa’s inaugural event! Read more HERE.

CLICK FOR EVENT DETAILS Upcoming Courses Certified Scrum Master (CPT)
26-27 Jan 2015
Steenberg Hotel, Cape Town

 

Certified Scrum Master (JHB)
03-04 Feb 2015
FNB Conference & Learning Centre, Sandton

 

Certified Scrum Product Owner (CPT)
23-24 Feb 2015
Steenberg Hotel, Cape Town

 

Certified Scrum Master (JHB)
10-11 Mar 2015
FNB Conference & Learning Centre, Sandton

 

Course schedule and Book Online

The post News update 2015/01 – Scrum Coaching Retreat Cape Town appeared first on ScrumSense.

Categories: Blogs

Viktor Frankl’s Meaning Triangle for Organizations

Agile For All - Bob Hartman - Tue, 01/20/2015 - 15:15

Viktor_Frankl2Viktor Frankl was an incredible human being, having survived the Holocaust and establishing logotherapy, a type of psychotherapy. His book, Man’s Search for Meaning, details his development of his theory around meaning and suffering.

And he was a student of suffering as he and his fellow prisoners walked through horrifying conditions. What he discovered, though, was how some of his colleagues were able to not only survive but grow in the process.

His conclusion – that the most basic human motivation is the will to meaning, and as Nietzsche put it,

He who has a why to live for can bear almost any how.

Frankl outlines further what he calls the “Meaning Triangle” as a way of processing the growth that some would face in seemingly hopeless circumstance:

  1. Creativity – Giving something to the world through self-expression and using our talents in various ways.
  2. Experiencing – Receiving from the world through nature, culture, relationships, and interactions with others and with our environment.
  3. Change of Attitude – Even if we can’t change a situation or circumstance we can still choose our attitude toward a condition. This is often a self-transcending way of finding meaning through suffering.

viktor-frankl-meaning-triangleI have been personally inspired by Viktor Frankl’s story and his work as he has created some incredible points of connection for me as I have walked through difficult times.

His work in logotherapy has also provided many talking points for the variety of teams, organizations, and cultures that we engage with – as all teams and businesses are challenged with being responsible for their human capital (creativity) and managing it well, creating the right environment for their staff and teams to operate (experiencing), and finally providing the right tools and culture to assist in developing a positive attitude (or change of attitude) to do their best work.

How have you experienced the Meaning Triangle in your context and in your organization? What are the tools or the systems within your culture that help your team achieve greater results, individually and collectively?

Now, we wouldn’t always say (at least explicitly) that we’re “suffering” in our work daily, and obviously not to the extent of which Frankl has experienced, but we all know what it’s like to work in environments where it seems “meaning” and “purpose” are often dismissed for the tasks at hand or stepped over for the sake of surviving the “daily grind.”

What I love doing is to help organizations move back to their original purpose(s) and what made them such an exciting organization to work for and with – and help capture the reasons why they exist in the first place. This reminds the individuals and teams that there’s meaning behind the “suffering” and even greater opportunities to thrive.

The post Viktor Frankl’s Meaning Triangle for Organizations appeared first on Agile For All.

Categories: Blogs

Discovering Your Leadership Posted

Johanna Rothman - Mon, 01/19/2015 - 20:01

I published a new Pragmatic Manager this past weekend. It’s called Discovering Your Leadership.

It has a pointer to the Influential Agile Leader event that Gil Broza and I are leading in San Francisco and then in London. You can still get early bird pricing, until Feb 15. Don’t miss this opportunity—we’re only leading it twice this year.

Categories: Blogs