Sunday, March 21, 2010

What is a successful project 何为成功的项目

When a client receives what he's been expecting, on time and for the estimated amount of money.

Project managers define this as: On Time, On scope and On budget.

"A successful project is where everyone involved is happy with the final outcome."

以上讲的是对成功项目的定义,说白了就是客户满意,觉得钱花的值。那有些什么事情会让客户觉得不爽呢? 没有按时,按量,按价把项目做出来,客户自然就不爽了。而速度、质量、价格三者本来就很难都保证,保证俩项,第三项势必就要有折扣,所以在谈项目的时候,应该充分考虑到三个基本要素,来报价。

The promise of a successful project is something we all work harder to achieve, but working harder is not the answer. Software companies need to work smarter before, during, and after development, to ensure that the client gets not only what they want, but what they need.

是不是死磕就能把项目搞好呢? 死磕能加大成功的概率,但是大家都是聪明人,从小比咱们死磕的人多的去了,但大多没咱们屌,一个原因就是用的方法不对。事半功倍这个道理在软件开发中一样通行。 给客户做项目,不是你做的自己觉得多屌就好的,也许技术屌,但客户用不上;或者东西做的复杂,但客户希望简单明了。多和客户沟通,而不是一味闷头干,也许成功概率更大。

讲回正题。没有规矩不能成方圆,开发软件也是一样。那么除了开发上的规矩,还有一些做项目上的规矩,大家又知道多少呢,等我一一道来。

1. Do you understand the value of consistency?

一致性,就是说做事情不要没事就换个花样。咱们如果今天开发用MFC,明天突然就改.Net了,后台就非要再玩玩Java,就过了。 一致性能保证产出,且每次质量不断提高。 从小一点的角度来看,程序里面也需要一致性。今天造个轮子,明天用一个库,都是不好的。不仅要自己的产品一致,公司内部一致,更要和高质量主流产品一致。例子我以后都拿.net说了。Microsoft Application Block,里面的轮子咱们如果常用,就可以提高效率,保持软件质量一致性。

2. Do you know that Rules are made for the guidance of wise men and the obedience of fools?

规矩是给聪明人用的,如果你觉得规矩不对,可以提出更好的改进。

3. Do you manage clients expectations?

客户的期望是需要我们提前打预防针的。 有几点需要注意的

  • 谈价钱的时候不要给区间。 你跟我说20-30w,也许客户的期望就奔着20w去了,30w就变耳边风了。而我们自己是啥意思呢,也许20w压根就没戏。
  • 软件是会有bug的,所以见下一条
  • 不要签固定价格的合同。 固定价格,保证没有bug?没可能嘛。所以得有个事后维护的费用,比如小时收费。开始额外收费钱,得让客户签收已有的成果。
  • 早点开始谈钱。谈完了客户就有预期了。收钱也得勤快。阶段性的收,阶段可以小一点。客户给钱总归都是不爽快的,收的勤快一点,客户还知道你在干活,达到了一个里程碑。不然突然一次收一大笔,让人肉痛。

4. Do you pursue short or long-term relationships with clients?

文中的建议是短期为妙。 对待客户,可以像对待一个长期的合作伙伴一样,但是做生意的时候,还是要步步为营。不要一次跟人说:“这个项目我们100w搞定”, 而是说:“你可以花5k,我们给你安排3个程序员一周时间来调查,给你做一个报告”。给客户以选择,也是给自己更大的机会。

5. Management - Is your client clear on how you manage projects?

这里讲的是和客户沟通项目管理方法。 以敏捷开发为例子,就需要客户的积极参与。这里面,由于管理方法的不同,会导致报价,合同方面的不同。 比如说客户想要一个软件,而我们告诉客户,我们用的是敏捷开发方式,所以你那边会派出人来参与项目,需求也可能会经常改变,我们可以估价一个到某一个阶段的价,然后后面根据进度来调整。 IT开发里面fix price的这种在鬼子这里真的很少见,除非合同额巨大,10M,20M,狮子大开口,不然都必然是会由于项目调整而进度资源调整。如果能尽量减少自身风险,同时让客户得到他们需要的软件,鬼子的这种分阶段报价方式可以值得参考。

Thursday, December 17, 2009

hoyts offer


Friday, December 4, 2009

bbs特色词汇

小钻风
原是西游记里的巡山小妖的名字. 这里是为公共站务ID mitbbs起的外号。此ID刚刚由walklooktalk在sysop版公布时,大家决定叫它总钻风,因为其职能类似于总版主,但小钻风这个名字最后沿用了下来。这个ID由walklooktalk在北京的雇员轮流值班,为提高论坛流量而到各版挑选文章置顶,也经常越过各版版主处理版务,由此引起很多怨言。但由于是雇员,从不像其他站长一样耍态度。

LD
领导,一般指配偶,引申出小LD,指家里的孩子。

LP、LG
老婆、老公的简称。

WSN
Family版经常出现的称呼.可男可女.猥琐男或者猥琐女的简称.特点是心理幼稚但是不阴暗, 行为诡异但是不偏激。

外F女
外嫁女的贬义用法,F估计代表英文Fuck,原指海外华人中对洋人盲目推崇进而随便与其上床的女生,后泛指因为绿卡或金钱等不纯目的而找洋人做男友或老公的中国女子,通常在Dreamer版上出现。这个词应该是源于对一些外嫁女子在网上炫耀自己的涉外爱情和家庭经历,而引起某些人群的不平。


意等同于英文词"TROLL",泛指那些投人所好有争议/夸大其词/或者纯属编造的贴子,来引发网友讨论,这样的贴子常被人称为"坑",发此类贴子的行为被称为"挖坑"。

发包子
凡文章获得版主加精 (M上),发文用户自动获得10元伪币。借此,网友们管发文章让版主加精为发包子行为,一个包子等于10伪币。

毛上、搞上
毛上指的是版主将版面的文章mark以保留该文章,标记符号为m,故取其谐音称为毛上;而搞上是指版主将版面文章加入文摘区,标记符号为g,故取其谐音称为搞上。

饭米粒
特指“我爱我家”版(FAMILY的谐音读法)。


饭米粒版对婚姻问题的标准回复,后来范围扩展至所有问题。很多id上来不看文章,照着原贴就是一个字“离”。后来版主StoryTeller试图令行禁止,成效不大。

八区
泛指"中国新闻"(CHINANEWS),"世界新闻"(WORLDNEWS),以及SALON,HISTORY,MILITARY等等版面,八区的叫法源于这些版面最初在TELNET界面下统属第8版块,该版块因涉及时事新闻较多,持不同见解的人言词激烈,很多时候八区版面火药味浓重,易引发争吵,"八区"在不少网友眼中常常被视为吵架的地方。

BT
源于拼音"变态"。起初用于自认为正常人类对被认为非正常人类的蔑称. 此称谓最初出现于mitbbs dreamer版2000年左右,那个时候dreamer风格转换,忧郁的文青正在被一些被称为新生代变态的新ID为首的新成员所代替。后来这个词逐渐在 MITBBS被泛化,现在已经变成英语里面"dude"一样的称呼。BT 也指 Balance Transfer 多用于Money版。

88一下
即八卦一下。

PENG
源于"肚皮舞运动"(Joke)版面,该用法源于大约1999年左右的一则新闻:英国陆军因为军费缺乏,打靶演习无法用实弹,只好在射击时口中发出射击声音。ID katy时任Joke斑竹,并转载了该新闻,建议今后见到老笑话就用"Peng"表示。"PENG"一词后扩散至整个BBS,涵盖面也扩大到任何性质的贴子,不仅仅只是笑话贴,包括贴子是重复的或者某人说过同样的话,都可以用PENG来表达。后来在 情爱幽幽(Love)版继续演化为 “BENG”。


最初称为裸奔。一般是指网友在版面上帖出自己的照片供大家欣赏取乐,有时也有如交友等特殊目的。常用的口号有:某某奔一个!奔上十大!你小你先! 等等. 2003-2004年度裸本成为mitbbs维护人气的一个重要节目,前著名女光棍,资深ID Janet曾制作并且不定期发布裸奔大全。


指专门show东西物件的,照片里没有人物只有物品。

胖子
Shopping(购物版)的常用词汇,指购物的时候使用的折扣券。因为美国商店的折扣券,英文为“Coupon”和中文“酷胖”或“哭胖”谐音,久而久之网友就改称之为“胖子”,而且显得更加琅琅上口。

死呆婆
美国著名办公用品商Staples的中文谐音,源自Mitbbs人气大版Shopping。该店因良好的客户服务、遍及美国城乡的销售网络、以及诸多的促销活动而深受Shopping版网友的推崇,某些网友的第一桶金即出自Staples。Staples目前已进入中国市场,其中文官方译名为“史泰博”。

RenPinWenTi
人品问题(rpwt)的另类表达。mitbbs南来北往,网友众多,模糊拼音的使用受到广大网友的普遍好评。

医院
ebay, 鉴于购物天堂(Shopping)版版主禁止在版上讨论ebay买卖,所以大家用“医院”这词代替ebay。典故出自前任汽车版主,shopping版资深ID coven在shopping版用隐晦的语言讲述自己在ebay因做托被封杀id及株连马甲的故事。另外由于ebay鱼龙混杂,故又用厕所一称呼代替。

病人
ebay 购物者

JHQ
精华区,多用于提示新手参考精华区,而不是一味问问题。

buffet deal (简称 buffet)
ebiz版 形容一笔交易的利润的量词。。。指获利,够享用一顿buffet...非常形象。

BSO
Bloodly Show off 不管人说啥都可以re:bso!)

Sunday, November 22, 2009

c# create and write to excel file

Following my previous post c# how to read write excel spreedsheet and C# quit excel appliction after using COM objectI wanted to continue the topic with a focus on write to excel spreedsheet.

Using Microsoft.Office.Interop.Excel is the easiest option and with Excel 2007 installed, you can get version 12 of this dll. It allows user to save files as Excel 2007 format, or the old 97-03 format.

Firstly, Let’s look at some sample code.

        private static void NAR( object o )
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject( o );
}
catch( Exception ex )
{
Console.WriteLine( ex.ToString( ) );
}
finally
{
o = null;
}
}

public override void save( FileWriter writer )
{
string filename = writer.FileName;

TimeSeries[] series = checkCompatibleTimeSeries( (Data[])data.ToArray( typeof( Data ) ) );
int count = series[0].itemCount( );
if( count == 0 )
throw new DataFileIOException( this, "Time series to save to " + filename + " are empty" );

// Instantiate Excel and start a new workbook.
Excel.Application objApp;
Excel._Workbook objBook;
Excel.Workbooks objBooks;
Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

objApp = new Excel.Application( );
objBooks = objApp.Workbooks;
objBook = (Excel._Workbook)( objBooks.Add( Missing.Value ) );
objSheets = (Excel.Sheets)objBook.Worksheets;
objSheet = (Excel._Worksheet)( objSheets.get_Item( 1 ) );

if( objSheet == null )
{
throw new Exception( "Worksheet could not be created. Check that your office installation and project references are correct." );
}

try
{
( (Excel.Range) objSheet.Cells[ 1, 1 ] ).set_Value( Missing.Value, "Date" );
( (Excel.Range) objSheet.Cells[ 1, 2 ] ).set_Value( Missing.Value, filename );


for( int rowIndex = 0; rowIndex < count; rowIndex++ )
{
( (Excel.Range) objSheet.Cells[ rowIndex + 2, 1 ] ).set_Value( Missing.Value,
series[ 0 ].timeForItem( rowIndex ) );

for( int columnIndex = 0; columnIndex < data.Count; columnIndex++ )
{
( (Excel.Range) objSheet.Cells[ rowIndex + 2, columnIndex + 2 ] ).set_Value( Missing.Value,
series[ columnIndex
][ rowIndex ] );
}
}
objApp.DisplayAlerts = false;
objApp.AlertBeforeOverwriting = false;
objBook.SaveAs( filename, format , Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlShared, Excel.XlSaveConflictResolution.xlLocalSessionChanges, Missing.Value, Missing.Value, Missing.Value, Missing.Value );

objBooks.Close( );
objApp.Quit( );
}
catch( Exception theException )
{
throw theException;
}
finally
{

if( objBooks != null )
objBooks.Close( );
if( objApp != null )
objApp.Quit( );
NAR( objSheet );
NAR( objSheets );
NAR( objBooks );
NAR( objBook );
NAR( objApp );
}

GC.Collect( );
GC.WaitForPendingFinalizers( );

}



Some tricky part of the code is the SaveAs Method. In order to disable the pop up alert messagebox, you need to do few things. (I believe most people do want to disable it since this must have been handled in the GUI part). Excel.XlSaveAsAccessMode.xlShared is the essential key to solve this problem. If it is not used, then  Excel.XlSaveConflictResolution.xlLocalSessionChanges wouldn’t work. Both “objApp.DisplayAlerts = false;” and “ objApp.AlertBeforeOverwriting = false; ” are used in the Excel dll Version 11 and will be overwrite by the XlSaveConflictResolution.



The code is fairly straight forward, the please refer to my old post on how i clean up the resources before quit.

Monday, November 16, 2009

c# detect excel install location in registry and open file

public void OpenInExcel(string filename)
{
string dir = "";
RegistryKey key = Registry.LocalMachine;
RegistryKey excelKey = key.OpenSubKey(@"SOFTWARE\MicroSoft\Office");
if (excelKey != null)
{
foreach (string valuename in excelKey.GetSubKeyNames())
{
int version = 9;
double currentVersion=0;
if (Double.TryParse(valuename, out currentVersion) && currentVersion >= version)
{
RegistryKey rootdir = excelKey.OpenSubKey(currentVersion + @".0\Excel\InstallRoot");
if (rootdir != null)
{
dir = rootdir.GetValue(rootdir.GetValueNames()[0]).ToString();
break;
}
}
}
}
if (dir != "")
{
ProcessStartInfo startInfo = new ProcessStartInfo();

startInfo.FileName = dir + @"Excel.exe";
startInfo.Arguments = "\"" + fileName + "\"";
startInfo.UseShellExecute = false;

using (Process process = new Process())
{
process.StartInfo = startInfo;
try
{
process.Start();
}
catch (Exception ex)
{
Console.WriteLine("\n\nCould not start Excel process.");
Console.WriteLine(ex);
}
}
}
else
{
MessageBox.Show("Can't Open in excel because excel is not installed.");
}
}

c# revert a LinkedList

void ReverseLinkedList(LinkedList ls)
{
if ( ls == null || ls.Head == null )
return;
ListNode head = ls.Head;
ListNode current = head.Next;
while(current!=null)
{
ListNode tmp = current;
current = current.Next;
tmp.Next = head;
head = tmp;
}
ls.Head.Next = null;
ls.Head = head;
}

c# merge sort algorithm implementation

        private int[] MergeSort(int[] a)
{
if ( a.Length == 1)
return a;
int middle = a.Length / 2;
int[] left = new int[middle];
for (int i = 0 ; i < middle ; i ++)
{
left[ i ] = a[ i ];
}
int[] right = new int[a.Length - middle];
for( int i = 0; i < a.Length - middle; i++ )
{
right[i] = a[i+middle];
}
left = MergeSort( left );
right = MergeSort( right );

int leftptr = 0;
int rightptr = 0;

int[] sorted = new int[a.Length];
for(int k = 0 ; k < a.Length; k++)
{
if ( rightptr == right.Length || ((leftptr < left.Length ) && (left[leftptr] <= right[rightptr])))
{
sorted[ k ] = left[ leftptr ];
leftptr++;
}
else if( leftptr == left.Length || ((rightptr < right.Length ) && (right[rightptr] <= left[leftptr] )))
{
sorted[k] = right[rightptr];
rightptr++;
}
}
return sorted;
}

我要啦免费统计