Actionary

A man is valued by his works, not his words!

How to Successfully Host and Facilitate Coderetreat

Alt text

1. What’s coderetreat

Coderetreat is a day-long, intensive practice event, focusing on the fundamentals of software development and design. By providing developers the opportunity to take part in focused practice away from the pressures of ‘getting things done’, the coderetreat format has proven itself to be a highly effective means of skill improvement. You can visit coderetreat.org for details.

2. What consists of the coderetreat day?

The day-long activity including: beginning, coding sessions and ending. Consider the time arrangement, there will be at least 5 sessions during that day. Beginning is reserved to introduce the coderetreat activity, sponsor, and the rules etc. The coding sessions are the major part of coderetreat day, the details will be described below. And ending part is used to retrospective of day-long whole coderetreat activity.

3. What’s consists of the session?

In each session, there basically including below steps:

Step 1. Delete the source code what is written in previous sessions

I often was asked why we programmer shall delete the source code what is written in previous session by them, they treated the source code as asset, programmer always makes the increase the source code size, but has less opportunity to delete source code. And remove the source code permanently helps programmers enter in new session with brand new status, new session with new constraint will make programmer has new idea.

Step 2. Add new constraint in constraints-list

The most interested part in coderetreat is coding under constraints. Image that, if your hands are tied, you will consider use other parts of your body. Before prepare coderetreat, facilitator shall prepare enough coding constraints carefully. Add one constraint in one session, current session shall be follow previous all constraints and new added in current session. For example, in the first session, the constraint is “TDD is required”, and in the second session, there is new constraint called “No local/global variable used”, it means in the second session, programmers shall follow two constraints.

Add constraints can help programmer programming in different solution, one constraint would help programmer to realize his/her potential well.

Some constraint examples:

  • TDD is required
  • The LoC of each function shall be less than 6
  • No conditional statement used, for example, “if, if else, ?: etc” shall be forbidden, of cause, it does not allow use for or while loop to instead of conditional statement
  • Follow “Tell, don’t ask” principle**
  • No loop
  • Keyboard only, no mouse, no touchpad
  • Silent: all of the programmer shall be silent, no talking, it helps programmers use the source code and unit test case to make communication, test case and source code shall be readable

Step 3. Coding to solve the problem

Actually, in coderetreat, we suggest every two programmers pair programming together, and in different sessions, the pair partner shall be rotated. Alice pair programming with Denial in session 1, but Alice shall pair programming with someone else. It helps programmers get new idea, and help them how to work with new partner. During coding, as facilitator shall walk through all of pair, to get to know what’s the situation, is there any problem, if someone stuck there, facilitator can give a clue to help them keep going forward.

Step 4. Debrief and share each other

In each session, shall reserve at least 5~10 minutes to collect the feedback from participants. As facilitator, you can ask “What’s your feeling in this session?”, “Is there any problem you encounter, and how do you resolve it?”, ask programmers write down the answers on the post-it, and paste them on the wall. and share each other. To facilitator, frequency quick feedback can help to adjust coming session’s plan. To participants, it’s a easy way to learn other’s idea well.

Alt text Alt text

4. As a host, what’s shall be prepared before the day?

As a host, you shall provide a comfortable workplace for programmers, so some logistics including:

  • A good place
  • Nice table and chair
  • Food, snack and drinking

Since in the activity, there are a lot of sharing to make, so below shall be prepare as well:

  • Projector
  • Whiteboard
  • White paper
  • Marker pen
  • Post-it (more color)

If you consider interact with other coderetreat place:

  • Camera for live recorder
  • Audio device for live broadcast play

Enroll you coderetreat on coderetreat website , if you’re going to organize a GDCR (Global Day of Coderetreat), please don’t forget register it on gdcr website, and create you owned registration, and publish it for participants enroll. Of cause, if you registered your activity in the gdcr website, you will get support from administrator. Post your activity on twitter with tag “#gdcr”, “#gdcr15” or “#coderetreat” etc. for great promotion.

5. As a facilitator, what’s shall be focused on the sessions?

Remember that: YOU ARE FACILITATOR. This is important role during the activity, your passion can inspire people enjoy the activity well.

  • First of all, you shall understand the whole process of coderetreat,
  • Then understand the constraints well, you can explain every constraint,
  • Know the problem well, and solve the problem under the constraint before the activity start.
  • Before session, you shall clear delivery the requirements to participants, and inspire people
  • In in the session, you shall walk through the pair, and getting to know the status, and facilitate the programmers in the right way
  • In the end of the session, you shall use right tools to get enough feedback, and help participants share the idea each other.
  • In the coderetreat ending part (the last activity of whole day), you shall make whole day retrospective.

Alt text

How to make whole day retrospective?

Actually, there are three questions facilitator shall ask:

  1. What’s your feeling today?
  2. What’s you learned today?
  3. What are you going to do related coderetreat?

You can split the participants in different groups, each group has 10 persons, give everyone three green color post-it, and write down the first question’s answer, write down 3 feelings, and paste them on the white paper external circle, and then give each member 30 seconds to share his/her feeling one by one in the group.

Then give everyone two yellow post-it, and write down the second question’s answer, write down 3 learning, and paste them on the white paper middle circle, share his/her learning one by one in the group.

In the end, give each person one red post-it, and write down the third question’s answer, write down the action plan, and paste it on the white paper inner circle, share the action plan one by one in the group.

Alt text

-EOF-

How Does TeXstudio Support Chinese Words Edit in LaTeX Under Mac

These days, I’m trying to edit some Chinese text documents edit in LaTeX language. It’s not a problem in Windows since Chinese font support, and Windows OS is popular used in Chinese forum. For English supporting is not a problem in LaTeX, but Chinese edit problem I encounter under Mac OS. I’m trying to make the notes to remember the steps here in case of somebody needs it as well.

Step 1. Choose good editor and compiler package

As friend recommend, I used TeXstudio for my LaTeX document editing, this tool was quite good when I used under Windows, I suppose it will do great job under Mac OS as well. And Install the MacTeX the LaTeX compiling supporting.

Step 2. Change the PDFLaTeX command to XeLaTeX

The first problem I encounter is when I finish a sample document editing, and tried to compile it, TeXstudio will use the default command PDFLaTeX to compile it. It works under PC, but failed under Mac system. So the first thing you need to set the default command to XeLaTeX. In TeXstudio, you can change the option via “Preferences” -> “Build” -> “Default compiler”, select the value as XeLaTeX. Now if you compile this document, it works fine:

1
2
3
4
5
6
7
8
\documentclass{article}
\title{Hello World}
\author{Mac}
\date{2015, July 4}
\begin{document}
  \maketitle
  This is my first sound.
\end{document}

and the result is like this:

Alt text

Step 3. Support Chinese words editing

But if we change the English content to Chinese, it doesn’t work well, such like this:

1
2
3
4
5
6
7
8
\documentclass{article}
\title{你好,世界}
\author{Mac}
\date{2015, July 4}
\begin{document}
  \maketitle
  这是我呐喊出来的第一句话。
\end{document}

Except the English words can be displayed well, everything is mass, unreadable. So we need use ctex package to support it. so add the \usepackage{ctex} after \documentclass{article}, the result is still bad. So I realize the problem might be caused by the fonts supporting. And then I inserted these lines before \begin{document}, the document like this:

1
2
3
4
5
6
7
8
9
10
11
12
\documentclass{article}
\usepackage{ctex}
\title{你好,世界}
\author{Mac}
\setCJKmainfont{Kaiti TC Regular}
\setCJKsansfont{Songti TC Regular}
\setCJKmonofont{Heiti TC Regular}
\date{2015, July 4}
\begin{document}
  \maketitle
  这是我呐喊出来的第一句话。
\end{document}

and change the encoding to UTF-8

Alt text

then the final result likes this:

Alt text

Step 4. How do I know the font’s name

As you see, I insert these line about the font supporting, but you may ask why I know the Chinese font name. Yes, it’s tricky, :p Firstly, I installed Microsoft Office, and I open the Microsoft Word, you can find the font name from the font dropbox, after you selected a font, the font text box will show its name. See, that’s why I know the font name exactly.

Alt text

In the eend

Here I give an example of the Chinese words editing, hope it’s useful for your reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
\documentclass{ctexart}
%\usepackage{ctex}
\usepackage{xeCJK}
\setCJKmainfont{Kaiti TC Regular}
\setCJKsansfont{Songti TC Regular}
\setCJKmonofont{Heiti TC Regular}

\begin{document}

\tableofcontents

\begin{abstract}
这是在文件的开头的介绍文字.本文的主要话题的简短说明.
\end{abstract}

\section{ 前言 }
在该第一部分中的一些额外的元素可以被添加。巴贝尔包将采取的翻译服务.

\section{关于数学部分}
在本节中的一些数学会使用数学模型含中文字符显示。

這是一個傳統的中國文字

\end{document}

-EOF-

The Ways to Break the Dependency During Unit Testing in C/C++ Programming

We encourage people writes unit testing shall follow F.I.R.S.T principle, but dependency gets in the way. Especially you make unit testing under legacy code, that’s mess. That’s the excuse we plan to ignore unit testing during coding.

For example, there is SUT code is game.c:

1
2
3
4
5
6
7
bool is_win() {
  printf("is_win is invoked!\n");
  if (dice_points() > 3) {
      return true;
  }
  return false;
}

function is_win() relies on the return value of function dice_points() which is defined in another file called dice.c:

1
2
3
4
int dice_points() {
  printf("dice_points is invoked!\n");
  return rand() % 6 + 1;
}

If we would like to test is_win(), see the test case like this:

1
2
3
TEST(VerifyGame, test_the_game_is_win) {
    CHECK(is_win());
}

The problem is you don’t know the case will be pass or not, since the dependent function dice_points() return value is volatile, this test case is unrepeatable. So we need define a test double called stub_dice_points() to replace real implementation of dice_points(), and return a value which is configurable, like this:

1
2
3
4
5
6
7
8
9
static int m_points = 0;

void set_stub_dice_points(int point){
  m_points = point;
}

int stub_dice_points() {
  return m_points;
}

And during you execute is_win() function, use stub_dice_points() instead of dice_points(), when you implement the unit testing like this:

1
2
3
4
 TEST (VerifyGame, test_bigger_than_three_points_shall_be_win) {
   set_stub_dice_points(3 + 2);
   CHECK(is_win());
}

But problem is how to replace the dice_points() with stub_dice_points()? There are some ways here:

1. Pre-compile macro

Macro #ifdef, #else and #endif can be used during pre-compile phase, to select which source code statement can be compiled. So the SUT source code game.c can be modified like this:

1
2
3
4
5
6
7
8
9
10
11
bool is_win() {
  printf("is_win is invoked!\n");
#ifndef UNIT_TEST
  if (dice_points() > 3) {
#else
  if (stub_dice_points() > 3) {
#endif
      return true;
  }
  return false;
}

And during compile the source code for unit testing purpose, give the -DUNIT_TEST compilation option, to enable the replacement. But this way requires you modify productive source code, and there will be a lot of macro like this, too ugly, and the source code readability will be getting worse.

2. Function pointer replacement

Another way is define a function pointer, in production code, the pointer is points a real depended function, and during unit testing, the function pointer will point the stub function, but it requires programmer change the production code like this, for example, the dice.h change like this:

1
external int (*dice_pionts)();

and the dice.c change to this:

1
2
3
4
5
6
int dice_points_imp() {
  printf("dice_points is invoked!\n");
  return rand() % 6 + 1;
}

int (*dice_pionts)() = dice_points_imp;

After that, in the test case, you can use the function pointer re-assignment like below (in cpputest framework):

1
2
3
4
5
TEST(VerifyGame, test_the_dice_points_is_bigger_than_3_points_shall_be_win) {
  UT_PTR_SET(dice_points, stub_dice_points);
  set_stub_dice_points(3 + 2)
    CHECK(is_win());
}

The obvious disadvantage is production code changing is needed. You can image that, every function dependency shall be replaced by function pointer way, too ugly.

3. Linker links replaced object

Above two ways require to change the production code, is there any can avoid the production code change to complete the function replacement. We assume the game.c includes dice.h, and dice.c is to implement the function dice_ponits() implementation. If we define another stub.c to implement the function dice_points() implementation in stub way. During compile the unit testing binary, don’t compile the dice.c, just compile game.c and stub.c, and link them together to build a executable binary file.

But there will be another problem occurs: How many *.c files under testing, there will be how many unit testing executable binary files. But, if the function is_win() and dice_points() in the same file, how to replace it? It will be difficult.

4. Dynamically replace

Is there any way to replace the dependency without do any production code change? The answer is yes, here we would like to introduce a tricky way to replace the dependency: During the function invoking, we let the invoking jump to our defined stub function. For example, during isWin() invoke dice_points(), we change the memory stack information, leads the invoking to jump to stub_dice_points(). The principle is first make the code page where dice_points() located writable using mprotect() in Linux or VirtualProect() in Win32. Then overwrite a JMP instructor which jump to stub_dice_poinots() at the begin of dice_points() binary code.

For example, there is a assistant source code assistant.c which includes set_stup() and reset_stub() implementation. The two are used to the dependency replacement:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//assistant.h
#ifndef __ASSISTANT_H__
#define __ASSISTANT_H__

#ifdef __cplusplus
extern "C" {
#endif

#define JUMP_CODE_MAX   0x05
#define JUMP_CODE_CMD   0xE9
#define JUMP_CODE_RET   0xC3

typedef struct stubInfo {
  void *funcAddr;
  unsigned char byteCode[5];
} stubInfo;

extern void set_stub(void *funcAddr, void *stubAddr, stubInfo *si);
extern void reset_stub(stubInfo *si);
#ifdef __cplusplus
}
#endif
#endif /* __ASSISTANT_H__ */

And the assistant.c is here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <sys/mman.h>
#include <unistd.h>
#include "assistant.h"

static void set_jump_code(void *codeAddr, char jumpCode[JUMP_CODE_MAX]) {
  int pagesize = sysconf(_SC_PAGE_SIZE);
  if (mprotect((void*) ((unsigned long) codeAddr & (~(pagesize - 1))), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
    return;
  }
  memcpy(codeAddr, jumpCode, JUMP_CODE_MAX);
}

void set_stub(void *funcAddr, void *stubAddr, stubInfo *si) {
    char jumpCode[JUMP_CODE_MAX] = {JUMP_CODE_CMD};
    int  dist = stubAddr - funcAddr - 5;

    memcpy((void *)&jumpCode[1], (void *)&dist, sizeof(void *));
    si->funcAddr = funcAddr;
    memcpy((void *)&si->byteCode[0], (void *)funcAddr, JUMP_CODE_MAX);

    set_jump_code(funcAddr, jumpCode);
}

void reset_stub(stubInfo *si)
{
    char   jumpCode[JUMP_CODE_MAX];
    memcpy((void *)&jumpCode, (void *)&si->byteCode[0], JUMP_CODE_MAX);
    set_jump_code(si->funcAddr, jumpCode);
}

And then in the unit test file, you can use the assistant function for the dependency replacement:

1
2
3
4
5
6
7
TEST(VerifyGame, test_the_dice_points_is_bigger_than_3_points_shall_be_win) {
    stubInfo si;
    set_stup(dice_points, stub_dice_points, &si);
    set_stub_dice_points(3 + 2);
    CHECK(is_win());
    reset_stub(&si);
}

5. Inherit from abstract class, replaced in dependency injection way

As we know, in OOP, there is interface concept, in C++, there is abstract class which used for interface purpose. If above the functions are defined as class way, there will be like this:

1
2
3
4
5
6
7
8
9
10
11
//game.h
class Game {
public:
    bool isWin() {
        Dice dice;
        if (dice.points() > 3) {
            return true;
        }
        return false;
    }
};

and the dice class is like this:

1
2
3
4
5
6
class Dice{
public:
    int points(){
        return rand() % 6 + 1;
    }
};

If we would like to make the replacement, we have to define an abstract class called Player like this:

1
2
3
4
class Player{
public:
    int points() = 0;
};

And the class Dice inherits from Player like this:

1
2
3
4
5
6
class Dice: public Player {
public:
    int points() {
      return rand() % 6 + 1;
  }
};

And the Game class shall make some change as well:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Game {
private:
  Player m_opponent;
public:
    Game(Player player) {
      m_opponent = player;
  }
  
  bool isWin(){
      if (m_opponent.points() > 3){
          return true;
      }    
      return false;
    }
};

The constructor function is used to dependency injection. In test purpose, we will inherit a new class called StubDice from abstract class Player, and use the StubDice replace the real Dice in test case:

1
2
3
4
5
6
7
8
9
10
11
12
//stub_dice.h
class StubDice: public Player {
private:
  int m_points = 0;
public:
    void set_points(int points) {
      m_points = points;
  }
  int points() {
      return m_points;
  }
}

In the test case, the implementation as below:

1
2
3
4
5
6
TEST(VerifyGame, test_the_dice_points_less_3_points_shall_be_lose) {
  StubDice stub;
  Game *game = new Game(stub);
  stub.set_points( 3 - 1);
  CHECK(!game->isWin());
}

Summary

We list the 5 ways of dependency breaking, it doesn’t mean that we suggest you use the ways in unit testing. During unit testing, if we find that it’s hard to make unit testing, we have to look back, check why it’s too hard to implement unit testing. Is it the design problem? Is it too many dependency, why? Is there any other way to implement same requirements? Refactor your source code often, make it better.

Treat the unit testing as design tool, helps you make better design; treat unit testing as safety tools, facilitates you make source code change.

-EOF-