szmmctag

  • Things you should do to sabotage your Scrum implementation

    Yesterday's Agile Tour in Luxembourg included a short open space session. One of the topics was about anti-patterns that increase risk of failure when implementing Scrum, so the question was: "If you wanted to kill the Scrum implementation in your team or enterprise, what should you do?".

    The main idea behind doing a brainstorming on things to make something worse came from a retrospective in which the facilitator did not ask "what could we have done better" but "what went wrong and what could we have done to make it even worse" in order to extract patterns from anti-patterns. Sometimes, people may get more creative by imagining the worst case than the best case.

    Although it turned out in our session that most attendees where more in a positive mood than in a negative one, we came up with a list of things you should avoid to do. In this post I summarize the list of anti-patterns without major edits or comments. As our session was short, the list isn't necessarily complete or even based on a consensus.

    • Implement Scrum without having a sponsor
    • Wait with implementing Scrum methods until you have a formal approval
    • Save costs on consulting and coaching
    • Ignore impact of Scrum and its roles on existing roles in your teams
    • Exclude your HR department from the transition process
    • Do not adopt the personal bonus model of team members and don't confuse them with team goals
    • Do not train your entire staff
    • Assume that change will happen without change management support
    • Wait with implementing Scrum methods until you can be sure that you start with 100% perfect Scrum
    • Do not change your initial Scrum implementation
    • Blame others for mistakes, blame individuals
    • Hide your metrics from management or others (or have no metrics at all)
    • Isolate expert knowledge in your R&D
  • iPhone Programming Tutorial: Manually Creating a Simple Application Step By Step

    I recently started to develop for the iPhone platform. Coming from Java, I've encountered some things that puzzled me when I started to develop on the iPhone, thus I started to take some "howto" notes -- more in order to reflect what I've learned than to teach others how to develop apps for the iPhone. However, maybe the resulting mini tutorials may give a kick start to those of you who are Java developers who are new to the iPhone platform. This "Hello World" tutorial concludes with a brief checklist of things that need to be done to get the basic tasks done. Feel free to download a zipped copy of the project including all sources.

    Step 1: get started

    Get the Xcode SDK and install it. Then, start Xcode. If you cannot find it under your applications menu, it has been most likely installed directly under your root folder of your local drive. Coming from Eclipse, using Xcode and the Interface Builder tool feels like programming with Gimp. You will be challanged to manage many open windows at the same time, so be prepared.

    We start writing our first app by creating a new project in the File menu. Xcode offers you a set of predefined project templates, but in order to understand what's going on I found that manually creating the application is more feasible. At latest when you want to combine tab bars and nav bars, you need to understand how those things work without using the templates anyway.

    Thus, just choose the plain project type "Window-based Application".

    Bildschirmfoto 2010-10-14 um 16.10.59

    Complete the step by giving a name to your project, e.g. "Tutorial1". The wizard creates a bunch of files and opens the main IDE. The file "MainWindow.xib" is the main visual container (view) for every application you are going to create. Related to this view, the wizard created a class file "Tutorial1AppDelegate" consisting of the public interface (".h" extension) and the implementation (".m" extension). If you are coming from Java, this separation into files sounds boring, but be sure there will be also a bunch of other things you will miss so that this separation will be quite normal for you after a while. If you are coming from C, you will feel home most likely.

    Step 2: Create the UI

    If you double click on "MainWindow.xib" (actually, people will refer to these kinds of files as "NIB" files for historic reasons), the visual designer "Interface Builder" will open. Each NIB has a "document window", which shows the components of the view either as icons or as hierarchical view.

    Bildschirmfoto 2010-10-14 um 16.22.40Bildschirmfoto 2010-10-14 um 16.22.44

    Currently, it contains just an empty, white window. This window can be populated by individual views. Each view represents a visual container that will contain your text fields, buttons and other visual elements and comes along with a controller object that takes care of processing user interaction and pushing data to the view.

    To add our first view to the application, open the library in Interface Builder, select a "ViewController" and simply drag it into the document window of your MainWindow.xib. It will appear on the bottom of the list:

    Bildschirmfoto 2010-10-14 um 16.27.22 Bildschirmfoto 2010-10-14 um 16.29.33

    If you select the newly added ViewController, you see the empty view in a separate window. Use this window to place your visual elements, for example by dragging a label on it. Enter "Hello World" as label text and play around with the label's properties in order to change the font size or color of the text and save your edits. You will see, that all elements will be added as subelements to your ViewController in the document window. The initial view (left image) may look like this (right image) afterwards:

    Bildschirmfoto 2010-10-14 um 16.36.06Bildschirmfoto 2010-10-14 um 16.39.50

    If you would run the application now, the screen still shows the white window instead of your carefully designed "Hello World" view. Why? While we already added it to the main window NIB, we did not tell your app that it should be displayed. So let's have a look at the AppDelegate class.

    Step 3: write the code

    Open the .h file of your AppDelegate. As you will see, there is only one element known to your app, which is the window. As we added a ViewController to the MainWindow.xib, we need to do two things in this class: first, to declare that there is a ViewController object; second, to show this object by adding it to the window.

    So, first, make your .h file look like this:

    @interface Tutorial1AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow
    *window;

    UIViewController
    *rootController;

    }

    @property (nonatomic, retain) IBOutlet UIWindow *window;
    @property
    (nonatomic, retain) IBOutlet UIViewController *rootController;

    @end

    In the interface, we declare a UIViewController object and we call it "rootController". Also, we declare it as IBOutlet property (properties can be read and set through a dot operator later on). IBOutlets are elements that are visible to the Interface Builder later.

    Then, as second step, add the missing lines as shown next to the implementation of the AppDelegate .m file:

    @synthesize window;
    @synthesize
    rootController;

    - (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
    /* Override point for customization after application launch.
    */
    [
    window addSubview: rootController.view];
    /* in Java, the line before would look like window.addSubview( rootController.getView() ); */
    [
    window makeKeyAndVisible];

    return YES;
    }

    - (void)dealloc {
    [
    rootController release];
    [
    window release];
    [
    super dealloc];

    }

     

    The @synthesize command is the counterpart to the property directive in the interface file. The important line is the one added to the "didFinishLaunchingWithOptions" method. There, we add the view of the rootController to the window in order to display it.

    The syntax is slightly different than Java, but you should get used to it quickly. Method or function calls are enclosed in squared brackets; methods that use parameters are postfixed with a colon. You can access properties of a class by using the dot operator and this is how we read the view from our controller in order to add it as subview to the window. Another thing you should consider is to release allocated memory, as you don't have a garbage collector.

    Step 4: wire everything

    Run your app now. It still shows a white screen. Damn! Let's recap what we did so far:

    1. We added a view (controller) to the main MainWindow.xib. In this view, we created a label.
    2. We declared a controller in the AppDelegate class and we added the controller's view to the main window.

    However, what is missing, is the link between the controller declared in the AppDelegate and the one defined in the MainWindow.xib. This "wiring" is done in the Interface Builder.

    Link

    Right-click on the AppDelegate entry in the document window of your MainWindow.xib. Here, you will find all Outlets (remember, you declared the rootController as IBOutlet property before) declared in the interface section. Click on the circle on the right side next to the rootController entry, hold the mouse pressed and drag a link to the View Controller.

    Now, you can run your application and see the Hello World label on the virtual iPhone device.

    Bildschirmfoto 2010-10-14 um 17.02.47Bildschirmfoto 2010-10-14 um 17.25.50

    Step 5: customize the controller of your view

    Although a "Hello World" example traditionally isn't very interactive, it would be cool if the label would always display correct, even if we turn the device. It is pretty easy to implement it, but the functionality is not included in the default ViewController which is used by our example. To implement additional functionality, especially to interact with data entry components later on, each view should have its own, custom controller. Let's create one and replace the default controller by the new one!

    In Xcode, right-click on "classes" and create a new file. Select a "UIViewController subclass" type and call it "Tutorial1HelloWorldViewController".

    Bildschirmfoto 2010-10-14 um 17.29.12

    A new class consisting of a .h and a .m file is added to your project. This controller class inherits the UIViewController class and can thus be used to replace the default controller in our application. Open the .m file and search for the method "shouldAutorotateToInterfaceOrientation" which is one of the many predefined methods. Uncomment the method and change it as follows:

    - (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
    return YES
    ;

    }

     

    Now the controller tells the view in the event that the device is rotated to also rotate the contents. All we need to do now is to replace the default view controller in the MainWindow.xib by our new class. For this, in the Interface Builder, select the "View Controller" in the document window, open the "identity inspector" and change the class identity to your newly created controller class.

    Controller

    Once you completed this step, the view should rotate when rotating the iPhone. If you have trouble in getting the label centered, play around with the settings of "Label Size" of your label. There, you can define which dimensions are fixed, which are dynamic, etc.

    Bildschirmfoto 2010-10-14 um 17.40.43

    You may also want to update the rootController IBOutlet in your AppDelegate file by replacing the UIViewController definition by your new class in the interface and property. You may need to do so if you want to call methods in your new controller from the AppDelegate class. Make sure to add @class directives or imports in order to get it compiled.

    Conclusion

    To add a simple, plain root controller view to your application, make sure you have:

    • Created a window based application
    • Added a ViewController to the Document Window in your MainWindow.xib (and some visual components to that view of course)
    • Defined the ViewController as rootController IBOutlet in your AppDelegate interface and added it as subview in the AppDelegate implementation
    • Wired the rootController outlet in the MainWindow.xib to the ViewController in the MainWindow.xib

    To make it more interactive, you may need to replace the default ViewController by your own. For this, make sure you

    • Create a new, dedicated controller class for your view that inherits UIViewController
    • Set this controller class as class identity of the ViewController in your MainWindow.xib

    Literally for each kind of Controller you are going to use in an iPhone app, both in the main window or within other controllers (such as tab bars or navigation bars) you will need to replace the standard implementation in the identity inspector to your specific, customized controller class.

  • GWT + GAE + Twitter in 20 Minutes

    Yesterday, I played around with authenticating a user with my Google Webtoolkit application hosted on Google App Engine against Twitter. I have no idea what I am going to do with it, but as most Twitter authentication HOWTOs on the web either deal with GWT or with GAE, I summerized the steps here. I will provide the source code of the project once this blog post is online.

    Create your GWT/GAE project

    I assume that you are going to use Eclipse and the Google plugin. Create a new GWT/GAE project with your favorite settings and clean up the pre-generated classes.

    Bildschirmfoto 2010-08-20 um 19.11.56

    Just delete the GreetingService*-classes and the FieldVerifier, we don't need them.

    Bildschirmfoto 2010-08-20 um 19.12.59

    Also, delete the servlet from the web.xml file and clean up the generated main class.

    Bildschirmfoto 2010-08-20 um 19.14.18

    Download twitter4j

    First, download the twitter4j library. There are alternatives, but for me this library worked well. I used twitter4j-2.1.4-SNAPSHOT.zip but you may want to check if there are newer versions. Unzip the archive and copy the file twitter4j-core-2.1.4-SNAPSHOT.jar to your /war/WEB-INF/lib folder. Add the jar to your project's classpath.

    Create your application on Google App Engine

    We need to register your domain to the Twitter API in a quite early stage, so you should create your Google App Engine application right now. You need a Google account to do so. Login to https://appengine.google.com and select "Create an Application".

    Bildschirmfoto 2010-08-20 um 19.20.20

    Now enter the Application ID that you have chosen into your project's properties in Eclipse:

    Bildschirmfoto 2010-08-20 um 19.21.59

    From now on, you can deploy your GAE application. The default URL is composed by your Application ID and Google's host appspot.com. In my example, this is http://gwtgaeauthtwitter.appspot.com

    Register your application at Twitter

    Open http://dev.twitter.com/apps/new and login to Twitter, if you are not already logged in. Fill out the form:

    Bildschirmfoto 2010-08-20 um 19.27.24

    Most settings should be self-explainatory. The most important one for the authentification step is the call-back URL. Many servlet based tutorials enter here the mapped URL of a specific servlet, but as we are going to create a ass kicking Ajax GWT application, just enter your host here. We will take care about delegating to the server in the entry point of our GWT application later. [Update: you have to enter the URL pointing to your host/domain when you go online with your service; during development, simply enter your complete http://127.0.0.1:8888/... URL into the callback field; then, Twitter automatically redirects to your local server where you can debug your application.]

    Complete the form and make sure you remember two codes you will receive on the confirmation screen: the Consumer Key and the Consumer Secret. We will need them in the next steps.

    Create the main authentication servlet

    The idea behind the authentication of the GWT is to check on first load of the application in the browser by a server call if the user is currently logged in by the current session. If logged in, we return some information that can be used by the client application to continue. If not logged in, we return a login link. Actually, this is the identical principle as logging in (or checking the login) using Google's GAE login services.

    The authentication servlet looks like this:

    package ggat.server;

    import java.util.logging.Logger;
    import ggat.client.GCredentials;
    import ggat.shared.ITwitterServlet;
    import javax.servlet.http.HttpSession;
    import twitter4j.Twitter;
    import twitter4j.TwitterException;
    import twitter4j.TwitterFactory;
    import twitter4j.User;
    import twitter4j.http.AccessToken;
    import twitter4j.http.RequestToken;
    import com.google.gwt.user.server.rpc.RemoteServiceServlet;

    public class TwitterServlet extends RemoteServiceServlet implements ITwitterServlet {

    private static final long serialVersionUID = 3681517323829124979L;
    private static final String CONSUMER_KEY = <your consumer key as string>;
    private static final String CONSUMER_SECRET =
    <your consumer secret key as string>;

    @Override
    public GCredentials login() {
    Twitter twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);

    HttpSession session = super.getThreadLocalRequest().getSession();

    User user = getUserLogin( twitter, session );

    if (user != null) {
    GCredentials result = new GCredentials();
    result.setUser( user.getName() );
    return result;
    } else {
    return requestToken( twitter, session );
    }
    }

    @SuppressWarnings("deprecation")
    protected User getUserLogin( Twitter twitter, HttpSession session ) {
    // try to get credentials
    User user = null;
    if ((session.getAttribute("token") != null) && (session.getAttribute("tokenSecret") != null)) {

    try {
    AccessToken accessToken = twitter.getOAuthAccessToken(
    (String) session.getAttribute("token"),
    (String) session.getAttribute("tokenSecret"));
    twitter.setOAuthAccessToken(accessToken);

    user = twitter.verifyCredentials();
    } catch (TwitterException e) {
    if (e.getStatusCode() == 401) {
    Logger.getLogger( GCredentials.class.getName() ).info( e.getMessage() );   
    } else {
    Logger.getLogger( GCredentials.class.getName() ).severe( e.getMessage() );
    }
    }
    }
    return user;
    }

    private GCredentials requestToken( Twitter twitter, HttpSession session ) {   
    RequestToken requestToken;
    try {
    session.setAttribute("token", null);
    session.setAttribute("tokenSecret", null);
    requestToken = twitter.getOAuthRequestToken();
    } catch (TwitterException e) {
    Logger.getLogger( GCredentials.class.getName() ).severe( e.getMessage() );
    return null;
    }

    String token = requestToken.getToken();
    String tokenSecret = requestToken.getTokenSecret();

    session.setAttribute("token", token);
    session.setAttribute("tokenSecret", tokenSecret);

    GCredentials result = new GCredentials();
    result.setLoginURL( requestToken.getAuthorizationURL() );
    return result;
    }
    }

    The servlet provides one public method which is also defined in the client/server interface classes and which is later called from the client during onLoad(). This method login() returns a plain POJO to the client that contains either a user name as String as indication that the user is logged in or an URL as String which is to be used to login through Twitter if the user is not logged in.

    This method first calls an internal, protected method getUserLogin() that tries to verify the current session credentials (and currently makes use of depricated methods which, however, currently work). If this fails, it returns null. This method can be later as starting point for an authentication methods used by other servlets to check if the user is logged in in the current session or to retrieve the Twitter client object. This pattern is similar to using Google's GAE authentication methods as starting point for servlet call authentications for methods that expect a valid login. [Edit: make sure that you do not evoke this function more than once per session, as it counts on the rate limit of  Twitter API calls. Best is to check the valid login at the beginning of the session and then to use the OAuth token for subsequent calls without checking the validity. If they are expired for some reasons, you will get corresponding error codes anyway.]

    The third, private method requestToken() is used only to retrieve a login URL in the case that the user is not logged in. Make sure you remove the token and tokenSecret attribute before requesting getOAuthRequestToken() as you may get a 401:Authentication credentials were missing or incorrect. Failed to validate oauth signature and token else.

    To make the servlet usable, create the interfaces:

    package ggat.shared;
    import ggat.client.GCredentials;
    import com.google.gwt.user.client.rpc.RemoteService;
    /*
    *             gmodel                                 ~        controller
    *                                                    ~
    *  +----------------------+     +----------------+   ~    +----------------------+
    *  |  ServiceDefTarget    |     | RemoteService  |   ~    | RemoteServiceServlet |
    *  +----------------------+     +----------------+   ~    +----------------------+
    *                                     ^           ~               ^
    *  +----------------------+     +----------------+   ~    +-----------------------+
    *  | ITwitterServletAsync |     |ITwitterServlet |<--~----|      TwitterServlet   |
    *  +----------------------+     +----------------+   ~    +-----------------------+
    *
    */

    /
    * The client side stub for the RPC service.
    */

    public interface ITwitterServlet extends RemoteService {
    /
    read user information or login URL from server */

    public GCredentials login();
    }

    And the corresponding client interface:

    package ggat.shared;
    import ggat.client.GCredentials;
    import com.google.gwt.user.client.rpc.AsyncCallback;
    /
    * The async counterpart of <code>GreetingService</code>.
    */

    public interface ITwitterServletAsync {
    /
    read user information or login URL from server */

    void login(AsyncCallback<GCredentials> callback);
    }

    Don't forget to update your web.xml file:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app
    PUBLIC "-Sun Microsystems, Inc.DTD Web Application 2.3EN"
    "http:
    java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
    <!-- Servlets -->
    <servlet>
    <servlet-name>twitterServlet</servlet-name>
    <servlet-class>ggat.server.TwitterServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>twitterServlet</servlet-name>
    <url-pattern>/gwtgaeauthtwitter/twitter</url-pattern>
    </servlet-mapping>

    <!-- Default page to serve -->
    <welcome-file-list>
    <welcome-file>Gwtgaeauthtwitter.html</welcome-file>
    </welcome-file-list>
    </web-app>

    Also update your appengine-web.xml file and add session support:

    <sessions-enabled>true</sessions-enabled>

    Create the client application

    For starting, I've added just a link and a label to the client application. I've simply replaced the generated headline and table by this:

    <h1>GWT GAE Authentication with Twitter</h1>
    <center>
    <div id="buttonLogin"></div>
    <div id="labelResult"></div>
    </center>

    The client class consist of some UI code and the server call to check the login state or to retrieve the login URL:

    Bildschirmfoto 2010-08-21 um 12.44.45

    The entry method onModuleLoad() simply adds a label and an anchor (a hyperlink) to the main page. The idea of the startup procedure is the following:

    1. Add a status label and an anchor
    2. Hide the anchor and ask the user to wait for authentication
    3. If we get a user name back, swith to "login mode" (here: by welcoming the user)
    4. If we get a login URL back, set the URL as target for the anchor and show the anchor

    That's it. Deploy your application to the GAE and open your favorite
    browser.

    Result

    Unlike implementations which make use of different servlets and client URLs for retrieving the login or calling back the application, we just use the plain URL of our app. When the user evokes the application the first time, the page shows the login link to Twitter.

    Bildschirmfoto 2010-08-21 um 13.01.23

    By clicking on the Twitter link, the well known "allow access screen" shows up. The following screenshot is taken from a browser where I already logged in to Twitter before (else, a login promt will appear):

    Bildschirmfoto 2010-08-21 um 13.01.54

    By selecting "Allow", Twitter calls back our application. Remember, you entered a call back URL before while creating your Twitter Application Account. This URL now evokes our application a second time; also, the onModuleLoad() is executed a second time (as the page is loaded from scratch).

    Bildschirmfoto 2010-08-21 um 13.02.23

    Next steps

    Voilá. This now could be your starting point to retrieve more information and to interact with the user's Twitter account. You basically don't need to pass any additional login information as payload of your calls (as long as you don't want to implement further security measures), just evoke the getUserLoginU() method within your additional servlets and functions. [Edit: as mentioned before, authenticating is rate limited, so be sure to reduce this call to a minimum per session.]

    I provide you as starting point the zipped project here. Also, I will investigate how to get rid of the deprecated methods. If anybody out there already knows, please leave me hints or a link. Whoever has an idea how I can publish formatted code with blog.de please also leave me a hint. Thanks!

    Pages that helped me:

  • Screencast on perfectiongame.org extensions

    Yesterday, I wrote about two ideas I've implemented to www.perfectiongame.org that extend the scope of the traditional rules of a perfection game. Based on this, I got some feedback on Twitter and in real life and I've spend some thoughts on these discussions and proposals.

    Today, I've adopted @scrumnl's idea of turning "comments" into "enhancements" in order to save the spirit of a perfection game and renamed the "comment" link as "improve". To explain what's the idea behind the "like" and "improve" functionality and why I still believe that it fit's into the perfection game idea, I recorded a screen cast:

    As always, I would appreciate to receive any feedback, either here, on Twitter, or directly on perfectiongame.org.

  • Extensions to a Perfection Game web site for increased interaction

    The Perfection Game is a method to receive positive, constructive feedback on anything you want. The rules are simple to understand and already topic of some blog entries and articles on the web (i.e. the original description as part of the Core Protocols by Jim and Michele McCarthy, in the book Software for Your Head by Jim and Michelle, in a blog post by Alex Champandard and also in a blog post and an great article by Yves Hanoulle).

    For playing asynchronous, distributed Perfection Games online, I've created the website www.perfectiongame.org that supports the basic steps of a perfection game: The initiator of a perfection game describes his "object for perfection" and invites one or more participants to give him feedback. Every participant describes what he or she likes about the object for perfection, gives proposals for improvements and scores the object for perfection on a scale from 1 to 10. The lower the score is, the higher the participant value his or her proposals for improvements. The rules follow principles of giving constructive feedback in a positive atmosphere which are very close the the principles of feedback rules.

    When playing the game in my professional life, I noticed that while the idea of the game is simple, it may contain some traps:

    Improvements
    The proposed improvements are supposed to focus on positive added value only. Or, as Alex describes more explicit, "only make positive suggestions; no mention of 'I don’t like this.'". If your participants did not get a good introduction about the perfection game, they may have tendencies to phrase improvements by describing what they do not like. It also happened to me; it is always easier to shout out what's wrong -- the real challenge is to step back and help to improve by contributing ideas. Yves elaborated about this also in his article.

    The Score from 1 to 10
    Participants who are not well prepared may interpret the score as a rating of the value of the object instead of indicating the value of their own proposals. Participants may hesitate to give low values as they may be afraid to offend the initiator of the perfection game. Instead, make sure that the participants understand that the lower the score is, the higher the potential value of their feedback may be.

    On the other side, as organizer of a perfection game, be aware that each score has only meaning in the specific context of the respective feedback. Thus, doing calculations -- such as calculating an average score -- on the set of scores makes no sense. Also, be prepared to receive feedback with different scores from the same participant; this makes absolutely sense if he or she is able to add new improvement ideas that make different value to him or her.

    Receiving feedback
    As receiver of feedback, just listen to what the participants say. Do not argue, do not defend yourself. It is up to you whether you accept and consider the ideas or not. As feedback giver, don't be frustrated if your ideas are not taken up.

    I believe this works well for feedback of individual objects of which the initiator of the Perfection Game is solely responsible of. He is able to receive honest feedback without ending up in discussions or even defending himself. In cases where the object is shared among a team these rules may be too strict as there is not one individual who has to process the feedback but a group of individuals who need to share this task.

    To support this process, I've added two more interactions to my implementations:

    Like improvements
    Participants can mark individual improvements proposed by other participants if they like it. I noticed that after contributing to a perfection game reading other's proposals brought me to new ideas. Or others thought about improvements I did not think about. By having the opportunity to "like" them, I can emphasize that these contributions of others have high value to me. This extension fits pretty much into the constructive principle of a perfection game.

    Comment improvements
    Participants can comment on other's proposals for improvement. This makes the result of a perfection game more interactive and less static, especially when the group who owns the object for perfection is the same or overlaps with the group of feedback givers. For example, when improving the team's "definition of done", such a functionality can be valuable to ask questions if an improvement is unclear or to propose an improvement to the improvement. However, introducing such a channel may also increase the risk to add negative or offensive statements to the game that may force either the initiator or the individual feedback giver into a defensive position. On the other side, if the participants are aware of the basic rules for a perfection game I would not rate this risk too high.

    I believe that both methods can add value to the principle of a perfection game without spoiling the idea by default, provided that the participants are well trained and have self discipline. Another method to encourage an interactive use of the perfection game results may be to bring all individual improvement proposals into one list, to group similar proposals and to do a dot voting on the list in order to identify the improvements that have the highest value to all.

  • Two simple patterns for encouraging a constructive meeting culture

    Some while ago, I had the pleasure to attend a series of workshops at the European Commission. During this time, I took part to discussions with several other participants facilitated by Stefano Bertolo from the European Commission. Stefano made a great job in facilitating us: in particular, as we had a competitive agenda and thus a very strict schedule, Stefano encouraged us to be as efficient as we could. Unfortunately, our discussions showed two particular tendencies: it seemed to be much easier for all participants to criticise other's proposals than to highlight the positive things and secondly it seemed to be much easier to express concerns and disagreement instead of coming up with alternative proposals.

    Stefano described the purpose of our meeting in a simplified way by "Our job is to fill an empty text buffer with a meaningful sequence of characters" to emphasize that, while he valued our contribution in discussions, the value would be even higher if we come up with our reports at the end of the meeting. Thus, during the course of the meeting, he introduced two meeting rules, which turned out to increase efficiency of our meeting without limiting each individual's freedom to express his or her positions.

    When rating an other's proposal, start with positives before coming up with disagreement.

    The first rule helped in reducing negative attitudes by letting everybody to think about what they actually appreciate. This approach is very similar to an advice I received from my academic mentor, Prof. Adlassnig from University of Vienna Medical School, who suggested me how to behave at conferences: "Whenever you question something that has been presented at a talk, first start with thanking the presenter for his talk. Try to outline some highlights you appreciate. Then, ask your question or express disagreement in particular aspects. By this, you create a positive atmosphere and give the presenter room to address your concerns without feeling attacked."

    Do not just express your disagreement to a proposal. Instead, propose specific edits.

    The second rule can be easily applied to all meetings in which you work on a document shared in the room or on screens. Ask your participants not just to express disagreement or concerns, but let them propose alternative phrases; edit the document at the same time, visible to all. Ask others not to interrupt or to comment during these few seconds. Then, ask if the edit can stay as proposed based on consensus. If no consensus can be found, ask for edits.

    This rule increases accountability of each individual; simply saying "no" is not good enough anymore. It may still happen that somebody disagrees without being able to phrase an alternative, but even in these cases the individual at least spends time on reflecting it before contributing.

    Conclusion

    For some reasons, I did not really implement these specific rules in my daily work so far. However, these patterns ecountered me in some exercises and best practises that have been introduced to us by our agile coaches in the last year.

    Both patterns manifest in the "Perfection Game" taught me by two agile coaches and co-workers from Belgium, Yves Hanoulle and Jürgen De Smet. The Perfection Game is one of the Core Protocols, a set of best practices to communicate and collaborate within great teams, which are also topic of a great article recently published by Yves. The Perfection Game also includes these two behavioural patterns "phrase what you like before describing what needs to be improved" and "propose improvements instead of just expressing what you don't like".

    These patterns also are elementary part of the feedback rules: When giving feedback, it is worth to begin with positive aspects to show appreciation of the other's contributions. Then, start with expressing your disagreement by suggesting improvements. Closely related to this aspect is also the "'yes, and...' vs. 'yes, but...'" exercise.

    After all, the principles of appreciation and accountability will help you to have better, collaborative meetings through facilitation.

  • Generating unique identifiers on Google App Engine

    Web applications that let you sign up for a service or let you opt-in to newsletters often have to validate your e-mail address. A simple way to implement such a validation is to ask the user to enter his or her e-mail address and then to send an e-mail which contains a unique validation link to this address. When the user clicks the link, your service can be confident that the e-mail address belongs to the user who just entered it. Technically, the implementation is easy; all you need is an unique identifier (token, code, ...) which is persisted along with the e-mail address object.

    Although the creation of such an unique identifier sounds pretty trivial, it is worth to spend some thoughts on it. In my use case, I wanted to create short, unique identifiers which are not only clickable but can be also entered manually without bigger efforts. Therefore, endless sequences of arbitrary characters didn't qualify. Also, the creation of such identifiers should run on the Google App Engine (GAE) which makes the uniqueness, similar to applications running in an JEE container, slightly more complicated compared to a local "Hello World" Java application as multiple instances of the application may create such identifiers at the same point in time.

    I tested some approaches to come up with good results. All methods discussed next generated twenty unique identifiers in a plain while loop:

    public static List<String> tokensBy....() {
    ...       
    List<String> tokens = new ArrayList<String>();
    while (tokens.size()<MAX) {
    String nextToken = ...; // creation of the token as discussed next

    if (tokens.contains( nextToken )) {
    System.err.println("generated redundant token");
    } else {
    tokens.add( nextToken );
    }
    }
    return tokens;
    }

    First approach: Unique identifiers based on System.currentTimeMillis()
    Each token is simply generated by converting the current time in milliseconds to a String representation:

    private static synchronized String tokenBySystemTime() {
    return "" + System.currentTimeMillis();
    }

    If you want to produce a series of identifiers quickly, you will get very similar results:

    1280316308710
    1280316308711
    1280316308712
    1280316308713
    1280316308714
    1280316308715
    ...

    As this leaves too much room to validate somebody else's address by guessing, I did not use this trivial approach.

    Second approach: Using the session id to generate unique identifiers
    This approach uses the session id of the current user which is retrieved from the HttpServiceRequest object:

    public static List<String> tokensBySession(HttpServletRequest _request) {
    ...
    String nextToken = "" + _request.getSession().getId() + random.nextInt();
    ...
    }

    The service request object can be retrieved from the servlet by calling super.getThreadLocalRequest(). As I also want to create more than one identifier in one step, I simply concatenate a random integer to the end of the session id. The results look less regular compared in the first approach:

    viwh7h4qfdi85697
    viwh7h4qfdi83178
    viwh7h4qfdi82979
    viwh7h4qfdi88871
    viwh7h4qfdi87837
    viwh7h4qfdi87903
    ...

    Looks better and less predictable because of the random integer at the end. But wait, why shouldn't I simply use integers?

    Third approach: Unique identifiers based on Random
    This approach is trivial:

    int r = random.nextInt();
    if (r<0) {
    r = r * (-1);
    }
    String nextToken = "" + r;

    The result is a list of short identifiers:

    1193959466
    1139614796
    837415749
    1220615319
    1429538713
    118249332
    ...

    But this looks pretty technical. All these numbers. Let's convert it to something alphabetical.

    Fourth approach: Unique alphabetical identifiers based on random integers
    This approach also uses random integer values, but converts them to a character string which doesn't look like anything mathematical at all anymore.

    private static String encodeBase10ToChar26( int _l ) {

    String chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    String result="";

    while(_l>0) {
    result = chars.charAt(_l%26) + result;
    _l /= 26;
    }

    while (result.length()<7) {
    result = "A" + result;
    }

    return result;
    }

    The algorithm has been adopted from this site. The result looks nice. I prefer these tokens as they don't look "computed" such as random numbers but still don't follow any clear pattern:

    DWMTGFY
    DRXVGSI
    CSMNKSB
    DYTBVZB
    EQIGSGF
    AJYTXBG
    ...

    To tweak this approach, you may want to use another algorithm to generate your (pseudo) random numbers. To understand the issue with randomness on a deterministic system such as a computer, good starting points are articles in wikipedia or discussions such as this one. I played around with a Marsenne Twister implementation by David Beaumont but returned to java.util.Random as I don't have the expertise to rate those approaches and the standard one seems to work well for me.

    Fifth approach: generating unique identifiers by using database entity keys
    When hosting a service on GAE or on a JEE application server, such as a jBoss, the expected behaviour of a client application doesn't apply anymore. In the worst case, you don't know on which machine your application is running and, even worse, if there are other instances running in other Java virtual machines. Thus, you cannot rely on public static synchronized methods or singleton patterns to compute unique identifiers with any of the methods mentioned before. Instead, you may simply create the tokens on the database and use the key of the object which is, by definition, unique even if multiple threads create such objects on the database in parallel.

    UniqueToken token = new UniqueToken();
    _persistanceManager.makePersistent( token );
    _persistanceManager.close();
    String nextToken = "" + token.getKey().getId();

    Now we can be sure that the identifiers are unique even in a distributed scenario, but the key IDs seem to be pretty predictable:

    1
    2
    3
    4
    5
    6
    ...

    Although the numbering scheme on the GAE differs slightly from the one used in the development mode, this approach is too plain. If you evoke KeyFactory.keyToString( token.getKey() ) at least the result looks more confusing and less predictable at a first glance:

    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBUM
    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBYM
    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBcM
    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBgM
    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBkM
    aglub19hcHBfaWRyEQsSC1VuaXF1ZVRva2VuGBoM
    ...

    However, compared to the approach that made use of the session id, this approach doesn't promise any added value.

    Conclusion
    Every algorithm to compute unique values works well as long as your application runs in one virtual machine. Creating random integer numbers and converting them to something alphabetic results in nice, short identifiers; however, generating them in a distributed environment, such as GAE, brings the tiny risk to generate the same identifier at the same moment in time twice. Two of the discussed approaches also work in such a distributed setting:

    1. Using the session id (and postfix it with a random value, if needed); however, the session id does not change during one session
    2. Using a entity in the data base taking its primary key as value; as long as the key is generated through the database and not by you, it is unique by definition; however, the result looks pretty predictable

    In the end, I chose a mixed approach: I persist an object with a regular numeric key to the database. Then, I take the numeric key and convert it to an alphabetic identifier as described before. This short identifier is then additionally postfixed with a random integer, also converted to an alphabetic representation.

    1. Numeric key of persisted object ensures uniqueness in distributed environment:
      8001
      := LVT
    2. Random integer value converted to alphabetic representation makes the code less guessable:
      FHWPDHQ
    3. The two concatenated values are used as unique identifier, e.g. for validating an e-mail address:
      LVTFHWPDHQ

    This approach should generate unique IDs in a thread-save way. Alternatively, you could simply persist your generated identifier and then check if only one object is retrieved when querying on that identifier. If more than one result comes back, you may delete the object and start over. This method is proposed in some discussions of Google's Java GAE groups. I also experimented with using String keys, hoping that storing a new object with exisiting key would throw an Exception; however, in such a case the existing object is silently overwritten.

    If you know any alternatives to my proposed procedure, for example based on transactions, I would appreciate if you could leave a comment.

    PS: I have to apologize for the lousy format of the code. Blog.de still does not support leading blanks.

  • Brute force. Brute patience. Brute success. Brute disappointment.

    Some weeks ago, I received a parcel from Portugal. Part of that parcel has been a puzzle made out of eighteen wood sticks which are supposed, if assembled in the right way, to form a cube.

    Puzzle_Kaputt

    While sitting on the couch, watching TV and chatting with a friend, we tried to solve the puzzle. Two things puzzled me: first, in contrast to myself my fried solved it almost at first try; then, we where not able to reproduce it or to identify patterns which may have helped us to solve it a second time. We always ended up with one or two tiles in our hands.

    So, I asked myself: what would a software engineer do in this case? Right: if my own intellectual power won't fix it, my computer will do so. And as I am used to think in an object oriented way, I modeled what I saw in front of me: The puzzle consists out of six different kinds of tiles with some notches on each side; each type exists three times, which makes a total of eighteen tiles. So I created a class that represents the upper and lower part of a specific tile and which has a method that is able to check if it fits into a specific row of notches and bolts in the one or other way.

    Another class represents the set of available tiles during a game. It provides a methods to draw one tile and to clone a tile set which is used later during recursions. Finally, another class represents one layer of tiles placed during the game which in sum makes the cube.

    As I had no idea about a good strategy, I implemented a recursive, plain brute force approach:

    I made the assumption that the lower and upper part of the cube does not contain any notches. So, the first layer (the ground) has been initialized with nine notches to make sure that the lower part of the cube will be made of bolts only.

    TileSet initialTileSet = new TileSet();
    TileSet tileSetOfNextRecursion = initialTileSet.drawNextStick();
    while (tileSetOfNextRecursion != null) {
    GameThread aThread = new GameThread( new Layer(), tileSetOfNextRecursion.getCurrentStick(), tileSetOfNextRecursion );
    aThread.start();
    tileSetOfNextRecursion = initialTileSet.drawNextStick();
    }

    The main idea is that in each state of the game, I sequentially try to continue to place each available stick in my current tile set on the current layer. If I have six sticks left A, B, C, D, E, F then the algorithm tries to place each of it on the current layer. If A fits, the algorithm will continue with stick A placed on a clone of the current layer and the tile set B, C, D, E, F. In parallel, it will check on the initial layer if B fits; in that case it will analogously continue with the remaining tile set A, C, D, E, F.

    Cloning the layers (which is, the current state of the game) and the tile set allows me to run the game multi threaded; also, there was no need for a backtracking algorithm, as in case of a dead end, I do not need to undo the last steps.

    The core of each thread are two methods. The first one starts recursions from the current layer for each stick in the current tile set:

    private void continue( Layer _currentLayer, TileSet _tiles) {
    if (_currentLayer.isFull()) {
    _currentLayer = _currentLayer.createNextLayer();
    }
    if (_tiles.size() == 0) {
    Game.solved( _currentLayer.layersAsXML(), _currentLayer.layersAsBitCode() );
    return;
    }
    boolean deadEnd = true;
    TileSet tileSetOfNextRecursion = _tiles.drawNextStick();
    while (tileSetOfNextRecursion != null) {
    deadEnd = _currentLayer.place( tileSetOfNextRecursion.getCurrentStick(), tileSetOfNextRecursion ) && deadEnd;
    tileSetOfNextRecursion = _tiles.drawNextStick();
    }
    if (deadEnd) {
    Game.deadEnd( _currentLayer.getDepth(), _tiles.size() );
    }
    }

    The second one places the stick selected by this method on the current layer in all possible variations and continues the recursion by calling the first method:

    public boolean place(Tile _tile, TileSet _tiles) {
    if (getPosition_1().isEmpty()) {
    List<PlacedTile> variants = _
    tile.fitsIn( getPosition_1() );
    for (
    PlacedTile aVariant : variants) {
    Layer updatedLayer = new Layer( this );
    updatedLayer.setPosition_1(aVariant);
    continue(
    updatedLayer, _tiles );
    }
    }

    // repeat placing the selected tile for positions 2 and 3 on current (not updated!) layer

    }

    As result, the algorithm computed and computed and computed. Brute force turned out to require brute patience as the brute force approach led to an combinatoric explosion of variants. Reducing the tile set led to fast computation of results, but with each additional tile in the tile set the required time grew and grew. For the last run with all 18 tiles, my core i7 iMac was busy for several days.

    Two things let the brute force approach explode: first, some tiles are symmetric, so placing them twice in the opposite direction made no difference but increased complexity. Second, the first approach simply started a new recursion for each tile in the tile set; as every type of stick exists three times, for each stick two redundant recursions have been started. The complexity grew exponentially.

    By replacing these stupid parts of the alorithm by something slightly less stupid, the computation time reduced from several days to eight seconds: what a brute success. As result, the algorithm computed 219 solutions for the puzzle (although I did not clean up symmetric duplicates); 4.249.021 combinations lead to a dead end.

    Buying this puzzle and starting randomly to solve it, will let you end up in 1.133.361 cases with exactly one tile in your hand. There are 2.809.350 ways to end up with four completed layers but three remaining tiles in your hand, but only 24 variants to end up on the first layer with more than 15 sticks remaining in your hand. So at least the start is easy.

    Puzzle_Ganz

    By this, although I was not able to solve the puzzle, I managed to get to a solution. But, after all, what a brute disappointment. While my machine was calculating days and nights, I thought I would compute a tremendously complex problem; for some days, it felt like computing in the same league like CERN or Seti@Home. But then, it simply turned out that brute force without taking care about obvious optimization opportunities can make a mountain out of a molehill.

  • Communication in Scrum: Open Discussion Culture vs. Time-Boxed Meetings

    Most likely, everybody involved in Software Engineering knows this comic:

    tree_swing

    One idea of agile methods is to work out as soon as possible what the customer really wants. In many cases the customer's real needs become clear while implementing the first ideas, using them and learning more about possibilities and limitations of the selected conceptual approach and technical platform. To support quick success and learning, Scrum and agile methodologies put an emphasis on the role of communication between all stakeholders. By sharing leadership between all actors, the collective creativity of the entire team can lead to faster and better results compared to traditional approaches where decisions are taken by one leadership role only. Thus, all Team members are encouraged to participate in the product design process during development. In an self-organized team, everyone has the right to express his individual opinion in order to achieve the best team outcome.

    While I really like this idea of shared leadership, there is also a risk of ending up in endless discussions or even in situations where developers explain to the product owner how he thinks the product should look like, undermining the product owner's role. When I started with scrum I was quite afraid of this pattern which I experienced in earlier teams. However, my biggest fear turned out to be without any reason: A good Scrum team with an open communication culture is founded on respect of each other's opinions, but also on each other's roles. Getting to this state of respect and to clear role definitions and responsibilities is a prerequisite for a functional state of shared leadership.

    We have a clear agreement that everybody is allowed to express his or her opinion to make the product better. Certainly, the team restrospective is one of the dedicated meetings to talk about what we have done, but of course communication happens also outside this meeting. However, in one particular case, we encountered a situation where an open discussion culture even started to hurt us, as we had an important, time-critical job to do which virtually attracted extensive debates: the estimation of user stories. Instead of just exploring the stories in order to understand them, we tried to extend, debate or fix them. Even if the result often looked good for a particular feature, overall we did not manage to finish our estimations. While I believe in general that such discussions are of high value, I think they should not happen during the estimation meeting.

    So we came up with two rules specifically for the estimation meeting:

    During an estimation meeting, while we value the items on the right, we value the items on the left more:

    • Getting a story estimated over questioning the sense of the particular features.
    • Getting estimation work done over fixing the backlog.

    To make efficient use of the time during an estimation meeting, the team can ask as many questions to the product owner as they want in order to understand the feature. On the other side, they are asked not to question the value of the feature itself. Also, when a feature is not ready to be estimated it should be pushed back instead of spending time on fixing, extending or rewriting it during the meeting. If team members have any ideas or concerns regarding the stories, they take a note and are encouraged to discuss everything with the product owner and others outside of this particular meeting.

    These rules helped to make our estimation meetings more efficient without giving anybody the impression of not having a voice.

  • Validating syntax and host of an e-mail address on Google App Engine

    Free services on the web often make use of sending activation links to a user's email address in order to validate their e-mail identity. The most common method to prevent errors in this process is to prevent mistyped email addresses by letting the user enter his or her address twice. However, while working on dotvoting.org, I wondered if it was additionally possible to validate an e-mail address for syntactic and semantic correctness. A simple check could for example consist of two simple steps:

    1. Check the syntax
    2. Check if the host can be resolved

    The main assumption is that a syntactical correct address and a resolvable host increases the chance that an email can be delivered, although it cannot guarantee if the host receives emails at all or whether the specific address is valid.

    I realized both functionalities as server call, although the syntactical check could also be realized on the client side using the Google Web Toolkit (GWT) and JavaScript. Checking the host turned out to be tricky as the obvious way, using INetAddress to resolve a host to an IP address, is blocked as this class is restricted and not available on Google App Engine (GAE).

    Starting from a hint given by BarryBHunter during a discussion I implemented the host check by calling a service that resolves a host passed as GET request to an IP address.

    public enum ResultCodes {CHECK_EMAIL_BAD_SYNTAX, CHECK_EMAIL_BAD_HOST, CHECK_EMAIL_CHECKED};

    public ResultCodes checkEMailAddress(String _email) {
    String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$";
    Pattern pattern = Pattern.compile(EMAIL_PATTERN);
    Matcher matcher = pattern.matcher( _email );

    if (!matcher.matches()) {
    return ResultCodes.CHECK_EMAIL_BAD_SYNTAX;
    }


    StringTokenizer emailTokens = new StringTokenizer( _email, "@", false );
    String beforeAt = emailTokens.nextToken();
    String afterAt = emailTokens.nextToken();

    try {
    URL url = new URL("http://www.nearby.org.uk/api/dig.php?l=" + afterAt);
    BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
    String line;

    while ((line = reader.readLine()) != null) {
    if (line.equals( afterAt )) {
    return ResultCodes.CHECK_EMAIL_BAD_HOST;
    }
    }
    reader.close();

    } catch (MalformedURLException e) {
    /* failure of calling this external service should not block app */
    } catch (IOException e) {
    /* failure of calling this external service should not block app */
    }

    return ResultCodes.CHECK_EMAIL_CHECKED;
    }

    The regular expression used in the example to validate the syntax can be easily found out there in the web. The limitations of this approach are so far:

    • The service of nearby.org.uk only resolves A records. CNAME records are not resolved.
    • If the user enters an email address, such as foo@localhost or bar@127.0.0.1 the syntactic check fails.
    • Resolving a host doesn't mean that the email will be deliverable.

    Because of the limitations the check has been implemented in a defensive way. In my particular use case, the user is informed about the result of the validation but is still able to continue setting up a new dot voting even if the check failed. Also, as the availability of the external service that resolves a host is not guaranteed, exceptions thrown while evoking it are logged but do not impact the validation result in order not to block the user.

    If anybody has a good idea how to resolve host names to IP addresses in order to check their validity on GAE, please leave a comment.

Footer:

The content of this website belongs to a private person, blog.de is not responsible for the content of this website.