Google
 

Monday, September 17, 2007

Earned value management (EVM)

Earned Value Management (EVM) is a project management technique that measures forward progress objectively. EVM has the unique ability to combine measurements of technical performance (i.e., accomplishment of planned work), schedule performance (i.e., behind/ahead of schedule), and cost performance (i.e., under/over budget) within a single integrated methodology. EVM provides an early warning of performance problems while there is time for corrective action. In addition, EVM improves the definition of project scope, prevents scope creep, communicates objective progress to stakeholders, and keeps the project team focused on achieving progress.

EVM emerged as a financial analysis specialty in United States Government programs in the 1960s, but it has since become a significant branch of project management. Project management research investigating the contribution of EVM to project success suggests a moderately strong positive relationship [1]. Implementations of EVM can be scaled to fit projects of all sizes and complexity

Essential features of any EVM implementation include (1) a project plan that identifies work to be accomplished, (2) a valuation of planned work, called planned value (PV), and (3) pre-defined “earning rules” (also called metrics) to quantify the accomplishment of work, called Earned Value (EV). EVM implementations for large or complex projects include many more features, such as indicators and forecasts of cost performance (over/under budget) and schedule performance (behind/ahead of schedule). The most basic requirement of an EVM system, however, is that it quantifies progress using PV and EV.

More detail see Wikipedia: http://en.wikipedia.org/wiki/Earned_value_management

Some ideas on project management

Here are some ideas from our real life practice on project management, monitoring and tracking:

I. Estimation and scheduling projects tasks
1. Get experienced member to do the estimate
2. Assign suitable tasks to suitable members. Understand and manage people is the most difficult task of TL/PM.
3. Provide good estimated time and add more 10%-20% buffer. Discuss with members to finalize

II. Tracking and monitoring project tasks
Go get your member to find the answer for below questions:
1. What questions:
a. What is the plan for today?
b. What has been done today?
c. What are your problems? à Can be resolved by you
- Have the problems been fixed yet?
- How much time you need to fix them?
- Do you need any help from others?
d. What are your issues? à Out of your scope
- Have you escalated them to higher level management?
- Is there any time limit to resolve the issues?
2. When to track:
a. Daily: tasks at function level
b. Weekly: tasks at module level
c. Monthly: tasks at application level

III. Getting the real status of the tasks
Should work closely with team members to get real result number (percentage done) and map with schedule
TIP: Trust but Verify (like security concept)

How to verify the result of member?
1. Function level:
a. Review detail design to see if he/she implements follow the design
b. Review code: cross review between experienced members
c. Debug the implemented functions
2. Module level:
a. Review high level design
b. Module test and integration test with input/output between related modules
3. Application level:
a. Review SRS to see all the requirements implemented correctly
b. System test the whole application

Any ideas please contribute.

How Do I: Use Visual C++ to Start, Stop and Configure Windows Services?

This is a good video tutorial on how to use Visual C++ to start/stop/configure a Windows service
Download the video from Microsoft here http://download.microsoft.com/download/e/3/d/e3d8152f-4e56-4e1d-8e0e-6a5505bd6a01/winvideo-nativecoding-startinservice.wmv

(Will DePalo, Microsoft)

Netting C++ : Mapping Templates to Generics

Under .NET, the static nature of C++ templates instantiation makes them less than first-class citizens of C++/CLI. In language design, we speak of the primary language entities as exhibiting first-class status. Think of an int: the movement in the 1970s to model abstract data types was an attempt to provide a mechanism so that user-defined types could approach the first-class status of primitive language types such as integer. So it is always legitimate to compare the first- and second class-citizens of a language. And if we do that with a generic and a template object under the .NET Framework, we could say that generics fly first class, and templates unfortunately are not only back in coach, but they're in the last row so they can't even recline.

The problem is that a template is local to the assembly within which it is built. This is because an assembly type is identified not simply by its name, but by its location. Thus, two objects of myTemplate passed between assemblies in a method would be flagged as a type error. So templates cannot be part of the public interface of a type. In addition, they are not language-interoperable.

Generics are tightly integrated into .NET because the underlying intermediate language was extended to explicitly support them. In addition, the runtime automatically manages the instantiation of generics on demand as they are needed. That problem was never solved in C++ due to the nature of the native compilation model in which files are compiled separately and linked together only at run time.

More generally, .NET solves three programming-in-the-large problems that proved intractable in C++ due to the native compilation model: the initialization order of complex global objects (that is, the assurance that an object is constructed before its first use when the use and initialization are in separate files), the management of dynamic heap-allocated memory, and the on-demand instantiation of a parameterized type. These problems, each of which represents a language layer of complexity independent of the actual domain solution, disappear under .NET.

The issue of templates versus generics moves front and center in this column because TQL relies heavily on templates-in particular, on the STL. There are three primary problems to address, and they are all aggravating since this is work we would all prefer not to have to do.

First, my implementation uses the STL vector class. While the STL is not currently available under C++/CLI, the .NET Framework does provide an equivalent generic collection type: List. Declaration-wise, then, I simply have to swap it in. However, I'll have to manually change the usage of each object since the two sets of operations are different. (Alternatively, I could think about writing my own one-to-one mapping of the vector class. I'll consider that later for the STL set associative container.) For example, here are a number of vector declarations:

typedef pair location;
typedef vector loc;
typedef vector text;
typedef pair text_loc;

To replace vector by List, simply open up the namespace, change the type name, and add the tracking handle (^), since List is a reference class:

using namespace System::Collections::Generic;

typedef pair location;
typedef List^ loc;
typedef List^ text;
typedef pair text_loc;

Second, as you can see from the previous code sample, this implementation also uses the C++ Standard Library pair<> utility. It is not available with C++/CLI, so I'll have to do something there. It's a pretty simple implementation, so I'll just see if I can clone it. The thing is, nothing maps quite one-to-one between the native and managed platform. Again, that's not surprising, since you need to think of the managed platform as the best thinking on how to make the native platform more successful. (I think the only thing missing right now is equivalent performance.)

Finally, my implementation also uses the STL set class. Unfortunately, there is no equivalent generic collection type, so I'll have to do something. My first thought is to implement a one-to-one mapping of its interface-except I cannot hijack heap allocation under the .NET Framework. But, as you'll see, that turns out to be a less than good idea. Here's an example of the TQL use of set:

class Query {
public:
// ...

private:

set* vec2set( const vector* );
vector loc;
set *solution;
};

So let's see how to solve the issue with the C++ Standard Library pair<> utility. The pair<> utility is exceedingly trivial. Its value is not so much in the elegance of its design as the fact that it is standardized as part of the C++ Standard Library. However, it does exhibit some template magic that only partially migrates to the .NET Framework and generics. Figure 1 depicts what the ISO-C++ Standard shows us of pair<>'s implementation.

I'll maintain the unencapsulated public nature of pair<> by keeping it a struct. In addition, I'll define it as a value class since I want to minimize its overhead. And, as I indicated at the start of the column, I'll implement it as a generic. The skeleton declaration looks as follows:

generic
value struct pair { ... };

This supports the previous use of pair<> , such as:

typedef List^ text;
typedef pair text_loc;

It also supports the sorts of uses illustrated in Figure 2.

So, let's look at the implementation, the easiest part of which is the data:

generic
value struct pair
{
typedef T1 first_type;
typedef T2 second_type;

T1 first;
T2 second;

I was holding my breath to see whether the trait pattern carries over into generics. The typedef-ing of the type parameter to a type-transparent name is one of the more elegant template patterns. (I would suspect that you cannot do this in C#. If you can't, that is one neat advantage C++/CLI has over C#.) In this case, first_type and second_type can be used transparently, as I did in Figure 2:

pair< int, String^ >::first_type ft = psi.first;
pair< int, String^ >::second_type st = psi.second;

The next set of pair elements we need to deal with are the three constructors, and generics provides mixed results in this case.

According to the standard, the default constructor for pair zeroes out the pair of objects, T1 and T2. Value types cannot support a default constructor because the compiler cannot guarantee that it can always intervene to generate the appropriate invocation. In this case, however, that is more than fine since each value type is guaranteed to be zeroed out by the runtime prior to being handed over to you. So, for this one, the .NET Framework is the winner, so to speak. Removing code, in general, is always an improvement.

The two-argument constructor takes a T1 and a T2. This is largely the same within C++/CLI, except for two issues in the following declaration:

pair(const T1& t1, const T2& t2 );

The first issue is const, which the .NET Framework does not recognize. On the C++/CLI design team, one school of thought is if the framework doesn't recognize const and a function with a const argument is passed to the framework, then we can't guarantee const-ness and therefore mustn't support it. The counter argument, which initially prevailed, was that C++ programmers use const as an interface design toggle and we can guarantee this surface-that is, compile-time-behavior. And, it was claimed, this is very important to them.

The problem with the initial design choice is that it was justified by a supposition. It claimed to know what is most important to the hearts and minds of C++ programmers. That's a difficult conversation to navigate. After all, most of us can make plausible assertions about what C++ programmers want-naturally we won't agree but we all believe that we know what is right. Unfortunately, beliefs are what we get passionate about, and they typically gain importance over technical issues. In a sense, our implementation of templates was more a supposition than a technical decision.

The immutability of a value (that is, its const-ness) is not something we tend to argue about, however passionate our nature. As much as C++ programmers want their const, they want their const to remain const even more. That was just something the compiler cannot guarantee given the absence of const within the System namespace-except perhaps by disallowing all calls into that namespace that want to pass a const parameter. This was felt to be unsupportable. So we reversed ourselves and removed support for const.

The second issue in the two-constructor signature is the declaration of the parameterized type name as a reference:

const T2& t2

You have to do this in native programming because of the performance penalty of passing a large user-defined type by value to the function being invoked. Under the .NET Framework, this is not an issue. A value type should not be more than 16 bytes; reference types are all passed by reference. So the revised C++/CLI two-constructor signature looks like this:

pair( T1 t1, T2 t2 ): first( t1 ), second( t2 ){}.

I would characterize this two-argument constructor as a wash when viewed as moving from one platform to the other.

The third constructor is a template copy constructor (at least in the case where T1 equals U and T2 equals V):

template pair(const pair &p);

This is not supported under C++/CLI generics. Member function generics, in general, are supported, such as this:

generic
value struct pair {
generic void foo( U, V ); // ok
// ...
};

But my attempts to have a generic constructor member function result in a rather inscrutable error message, which left me unsure whether the message was a compiler error or an aspect of the common language runtime (CLR) specification:

error C2061: syntax error : identifier 'pair'
error C2238: unexpected token(s) preceding ';'

The following shows the two additional syntaxes I tried:

generic
value struct pair
{
// neither compile ...
generic pair( int );
generic pair( pair% );

// ok: but not quite equivalent
// note: not considered a copy constructor
pair( pair% );

// ...
};

As it turns out, the CLR implementation does not support a generic constructor. (Unfortunately, a clearer error message probably won't make it into the next Visual Studio® release.) Therefore, in scoring this, I would give the point to templates. The entire pair implementation is shown in Figure 3.
[ Editor's Update - 3/14/2007: The code in Figure 3 will compile under Visual C++ 2005. However, due to the nature of generics, it shouldn't have, and a fix to the compiler was implemented as part of Visual C++ 2005 SP1 that will prevent this from compiling (SP1 is available for download). For a pair struct like the one implemented in Figure 3, there are several solutions. One is to use templates instead of generics (simply changing "generic" to "template" ). Another is to constrain the generic parameters to implement IComparable methods on IComparable can then be used within the struct definition to compare instances of the generic parameters.]

Finally, I have to deal with the set class abstraction provided by the STL. In the .NET Framework 2.0, there is not a set representation within the Generic collection namespace. I don't see any alternative except to cook up something of my own-which is unfortunate since presumably we'll all end up cooking our own slightly different implementation, and that makes for an awfully big set. Figure 4 shows the ISO-C++ specification of the public interface for set. On one level, I imagine people expect I would implement the full STL specification. That was what I first assumed until I looked at it closely.

Why, for example, would anyone want a reverse iterator for a set, let alone both a const and non-const instance of that? The functional abstraction of a set has little connection with, I would guess, 80 percent of its STL interface. That is, about 80 percent of the members of set are a requirement of the STL, not of the set abstraction. So that's pure STL overhead; there is nothing I really need in that. So I'm going to (virtually) toss it out. My set looks like this:

generic
public ref class set : IEnumerable {
public:
set();

void add( element );
bool find( element );
void remove( element );

int count();
bool empty();
void clear();

virtual IEnumerator^ GetEnumerator()
};

And then, of course, I need to swap this set interface in place of the STL set of calls. This is the same problem as moving from vector to List. Space doesn't permit me to walk through any of the implementation details, but you can view that and the entire TQL .NET port in the download from the MSDN®Magazine Web site.

Download http://download.microsoft.com/download/f/2...gC++2007_04.exe
Online code: http://msdn.microsoft.com/msdnmag/code/?ur.../07/04/NettingC

(Stanley Lippman, Microsoft)

Service interacts with WinLogon desktop on Vista?

Found some interesting articles from Microsoft:

Interactive Services

Typically, services are console applications that are designed to run unattended without a graphical user interface (GUI). However, some services may require occasional interaction with a user. This page discusses the best ways to interact with the user from a service.

Important Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.

Interacting with a User from a Service Indirectly

You can use the following techniques to interact with the user from a service on all supported versions of Windows:

* Display a dialog box in the user's session using the WTSSendMessage function.
* Create a separate hidden GUI application and use the CreateProcessAsUser function to run the application within the context of the interactive user. Design the GUI application to communicate with the service through some method of interprocess communication (IPC), for example, named pipes. The service communicates with the GUI application to tell it when to display the GUI. The application communicates the results of the user interaction back to the service so that the service can take the appropriate action. Note that IPC can expose your service interfaces over the network unless you use an appropriate access control list (ACL).

If this service runs on a multiuser system, add the application to the following key so that it is run in each session: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. If the application uses named pipes for IPC, the server can distinguish between multiple user processes by giving each pipe a unique name based on the session ID.

The following technique is also available for Windows Server 2003, Windows XP, and Windows 2000:

* Display a message box by calling the MessageBox function with MB_SERVICE_NOTIFICATION. This is recommended for displaying simple status messages. Do not call MessageBox during service initialization or from the HandlerEx routine, unless you call it from a separate thread, so that you return to the SCM in a timely manner.

Using an Interactive Service

By default, services use a noninteractive window station and cannot interact with the user. However, an interactive service can display a user interface and receive user input.

Caution Services running in an elevated security context, such as the LocalSystem account, should not create a window on the interactive desktop because any other application that is running on the interactive desktop can interact with this window. This exposes the service to any application that a logged-on user executes. Also, services that are running as LocalSystem should not access the interactive desktop by calling the OpenWindowStation or GetThreadDesktop function.

To create an interactive service, do the following when calling the CreateService function:

1. Specify NULL for the lpServiceStartName parameter to run the service in the context of the LocalSystem account.
2. Specify the SERVICE_INTERACTIVE_PROCESS flag.

To determine whether a service is running as an interactive service, call the GetProcessWindowStation function to retrieve a handle to the window station, and the GetUserObjectInformation function to test whether the window station has the WSF_VISIBLE attribute.

However, note that the following registry key contains a value, NoInteractiveServices, that controls the effect of SERVICE_INTERACTIVE_PROCESS:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows

The NoInteractiveServices value defaults to 0, which means that services with SERVICE_INTERACTIVE_PROCESS are allowed to run interactively. When NoInteractiveServices is set to a nonzero value, no service started thereafter is allowed to run interactively, regardless of whether it has SERVICE_INTERACTIVE_PROCESS.

Important All services run in Terminal Services session 0. Therefore, if an interactive service displays a user interface, it is visible only to the user who connected to session 0. Because there is no way to guarantee that the interactive user is connected to session 0, do not configure a service to run as an interactive service under Terminal Services or on a system that supports fast user switching (fast user switching is implemented using Terminal Services).