存档

2011年5月 的存档

I am back

2011年5月29日 3 条评论

小小终于恢复了。开始知道自己吃东西了。伤口也基本上长好了。悬了十几天的心终于可以放一下了。I’m gonna go back to work now.

两件事情要尽快做

  1. HOJ在下周三之前上线(不含论坛功能)
  2. 工大内部网站评估报告在下周日之前出个草稿

张志桐和李海,需要批评。备忘。

今天复习《把时间当作朋友》,看自己的上一篇流水帐时,发现已经是12天前的了。反省。

分类: 流水账 标签:

偷懒

2011年5月17日 2 条评论

今天偷懒,在睡觉、上网冲浪、洗澡、吃零食中度过了。

反省。

分类: 流水账 标签:

用dompdf和pChart生成PDF报表

2011年5月16日 2 条评论

今天搞定了Proposal Tool v2.0的PDF报表生成模块。简单总结一下我所使用的解决方案。

需求

需求是要根据用户选择的历史数据,动态的生成一系列的折线图、饼图、柱状图,然后将这些图表整合到一个PDF文件中。PDF中的文本也是动态的和可修改的。

工具

开发语言使用PHP;图表生成工具使用了强大的pChart库;生成PDF的库选择了dompdf。

pChart将直接生成图片文件,很方便的就可以作多种用途。(pChart和jqPlot的比较,可参考我之前的文章:《图表生成工具pChart和jqPlot》)

dompdf简单易用,可直接将HTML转换成PDF。API十分简洁。不过dompdf有一些限制,它不支持position:relative/absolute, 不支持嵌套表格,不支持float等等(其他限制参考dompdf官方网站)。所以布局比较复杂的页面用它来处理会比较吃力。

解决思路

分3步解决

  1. 使用pChart将数据转换成图表,并存储为图片文件,保存在临时存储区中
  2. 使用PHP的模板引擎定制HTML,并在其中引用上一步中生成的图片文件
  3. 使用dompdf将上一步中的HTML转换为PDF文件,删除临时存储区中的图片文件

效果图

PDF Report Generated by pChart and dompdf

PDF Report Generated by pChart and dompdf

开始新项目

2011年5月15日 没有评论

曰:贵有恒,何必三更眠五更起;最无益,莫过一日曝十日寒

要做的两件事情现在都开始做了。CMS决定放弃重新发明轮子的冲动,使用PMWiki作为解决方案。工大网站的评估今天正式开始了,由小雨、大龙、张雄、张志桐、陈云飞、李海六位同学来负责。希望他们能够完满的完成这个项目,给出一份牛逼的报告。

今天检查了一下功课,又是老毛病,没能持之以恒,中间时有间断。上一次的钢笔字还停留在5月10日。三天打鱼两天晒网,从小到大就是这个毛病。反省。

分类: 流水账 标签:

科学需要严谨,科普需要耐心

2011年5月13日 2 条评论

这两天方舟子在其微博上发布了关于哈工大机器人涉嫌造假的消息。这让很多哈工大的校友十分不满。我昨天刚刚看到这个消息的时候,也是满心的不高兴。我想有必要对这件事情做一个全面的反思。

今天在人人网上看到两篇文章:有关方舟子关注哈工大机器人事件的个人看法关于工大机器人和方舟子我要说几句。让我对这个事情有了新的看法。

对于专业的计算机从业人员来说,机器人需要编程驱动是很浅显的道理,但是,对于普通人来说,机器人就是一个机器,至于它具体是如何工作的,大多数人恐怕并不清楚。因此,洪教授的那句话让大家以为“机器人是哈工大自己制造的”不仅是情有可原的,甚至几乎是必然的。方舟子尽管是一名科技工作者,但他是生物化学博士,不了解计算机科学也属正常。大家通过理性的讨论,把疑问和误会解开就可以了。

不过看起来有些哈工大的校友们有点不够淡定,从上面两篇文章及评论中能看得出来,显得有点着急和忙乱。实际上大可不必,方舟子尽管成功的打了不少假,可是那并不意味着他发布的所有消息就都是确凿的,都是定案。况且方舟子在这个问题上不是科普工作者,而是一个需要接受科普知识的受众,如果他果真搞错了,耐心的解释解释,误会是能够搞清楚的。如果把这种纯粹的学术上的争辩变成了对方舟子个人的攻击,那不仅无法有效的化解误会,更让我们哈工大人的斯文扫地。

况且,洪教授的话的确太过夸张,“我们自己研发的仿人型机器人,不输于任何世界各个国家”,即便考虑到上下文,也是言过其实的。这话不应出自一个严谨的科研工作者之口。

我想,在这个问题上,工大方面可以给出一个回应,澄清一下,达人秀那边也应该把洪炳镕教授说过的话的完整视频放出来。

造成这种误会,有多种原因,首先就是达人秀方面把节目进行了剪辑,使得洪教授的对话失去了上下文,让人造成误解;另外方舟子单凭几个机器人的图片就断定“没有做任何修改”,太过武断,这无疑是与科学精神相违背的;更重要的是,洪教授的话的确不够严谨,难免让人误解。

新浪的这篇报道很不错,综合了多方的看法,而且没有简单的给出结论。

Update

跟墨总吵吵了一阵子,我承认科学家的思路比较诡异,他认为在这件事情上,最应该反省的是那些搞机器人制造的。

Update

今天下午跟kinslover同学进行了一番争论,最后基本上达成了谅解。我的观点总结如下:

我认为,对于监督者,要求不应太高。因为监督者的作用是提醒性的。如果一定要每一个监督者都以“论述有力、证据确凿、毫不偏颇”为标准进行监督的话,那毫无疑问的,能够达到标准的凤毛麟角。我想,监督应该就是我觉得这事可疑,我就提出我的质疑,然后你来解释。可以类比近代民主制度中的一些基本原则,发对派的质疑可以尖刻或偏颇。因为只有降低监督的门槛,才能形成有效的监督。

因此,即便方舟子的质疑是尖刻和偏颇的,我认为这种质疑也是有价值的,因为它构成了对学术造假的有效监督。

kinslover同学的观点我不好总结,请参考他的原文

Update

sunner依然是那么视角独到:《面子重要,还是真相重要?》。最后一段实在很“狡黠”。

记录要做的两件事情

2011年5月11日 1 条评论

曰:万事蹉跎因懒惰,穷困潦倒缘贪心

便捷灵巧的CMS

最近做好多事情都发现需要一个便捷灵巧的CMS,Wordpress现在也显得太过臃肿了。我又令人羞耻的想要重新发明轮子了。暂时的想法是使用Textile和Geshi库,在现在的Crude Framework上开发一个CMS。

在Textile的官方站上看到他们有一个CMS,不过下载试用之后发现太丑陋了,完全不是我喜欢的型。

一直很喜欢Textile风格的Markup,在考虑OJ的后台的内容编辑也基于它来做。

工大各院系处所网站评估

这是大烈交代的一件事情,要对工大各院系处所的网站做一个全面的评估,给出评估报告。原本我对这件事情兴趣不大,不过这几天仔细的思考了一下,发现这个事情还是很有意义也很有意思的。列一下思路,以防忘记。欢迎补充。

从以下几点进行评估

  • 外观
    • 界面美观程度
    • 各浏览器下的兼容性
    • 图片、Flash等的使用情况
    • 特效使用情况
  • 内容
    • 信息量
    • 主要内容分类
    • 时效性
    • 纯文本、多媒体内容的比例
  • 功能
    • 展示功能模块
    • 交互功能模块
    • 其他功能
  • 体验
    • 浏览体验
    • 信息获取的便捷程度
    • 交互功能体验
  • 使用情况
    • 使用频率
    • 交互频率

针对以上各点给出评级,对于存在问题的,给出改进建议。针对每一点,评出一个最优一个最差。再对所有网站做一整体的评级。

尽管我不喜欢长篇大论的报告,但是这两天合计了一下,这个报告肯定短不了。

分类: 流水账 标签:

图表生成工具pChart和jqPlot

2011年5月10日 6 条评论

之前开发喜乐喜乐网的后台统计功能的时候,一直在用jqPlot,效果很不错,我挺喜欢的。最近手头的一个项目要求将生成的图表嵌入到PDF中,jqPlot就无能为力了。于是我不得不转而寻找其他的解决方案,这才发现了pChart。感觉只有一个,那就是相见恨晚啊。

下面简单对比一下这两个图表生成工具。

成像风格

先上两个图看看效果

pChart Showcase

pChart Showcase

jqPlot Showcase

jqPlot Showcase

在图像风格上,pChart更加倾向于秀气,线条比较纤细;而jqPlot则显得比较大气,线条结实稳重。pChart内置了边缘防锯齿的功能,阴影、透明等feature一应俱全,成像风格很漂亮,我个人比较偏爱之。

适用场景

当然,图像的风格只是外在的表象,这二者最重要的区别在于,一个是在服务器端渲染图像,另外一个则是在浏览器端。

因此,pChart要占用服务器的CPU资源,当然,也要占用硬盘空间,如果你要把图表通过web页面展示的话,还要占用带宽资源。因此,pChart并不适合于用在仅需通过web页面显示图表的情境下,在这方面,jqPlot要更有优势一些,因为它是完全通过Javascript在浏览器端作图像渲染,不需要占用服务器端的CPU和硬盘,带宽的消耗也偏小,因为仅需传输文本数据而不是图片。

反过来,当你的图片不仅仅是要在浏览器上显示,还要作其他用处,比如我现在面临的情境,需要把图表嵌入到PDF文件中,那么pChart就将是不二之选了。pChart还内置了缓存机制pCache,用以节约CPU资源。一定程度上减少了CPU的消耗。

API易用程度

由于图表中需要控制的元素特别的多,因此API不可避免的会比较复杂一点,总体上来看,由于jqPlot中可以使用json,API上相对会比较简洁一些。而pChart则略逊一筹。

pChart

  1. /* Create and populate the pData object */
  2.  $MyData = new pData()
  3.  $MyData->addPoints(array(-4,VOID,VOID,12,8,3),"Probe 1");
  4.  $MyData->addPoints(array(3,12,15,8,5,-5),"Probe 2");
  5.  $MyData->addPoints(array(2,7,5,18,19,22),"Probe 3");
  6.  $MyData->setSerieTicks("Probe 2",4);
  7.  $MyData->setSerieWeight("Probe 3",2);
  8.  $MyData->setAxisName(0,"Temperatures");
  9.  $MyData->addPoints(array("Jan","Feb","Mar","Apr","May","Jun"),"Labels");
  10.  $MyData->setSerieDescription("Labels","Months");
  11.  $MyData->setAbscissa("Labels");
  12.  
  13.  /* Create the pChart object */
  14.  $myPicture = new pImage(700,230,$MyData);
  15.  
  16.  /* Turn of Antialiasing */
  17.  $myPicture->Antialias = FALSE;
  18.  
  19.  /* Add a border to the picture */
  20.  $myPicture->drawRectangle(0,0,699,229,array("R"=>0,"G"=>0,"B"=>0));
  21.  
  22.  /* Write the chart title */ 
  23.  $myPicture->setFontProperties(array("FontName"=>"../fonts/Forgotte.ttf","FontSize"=>11));
  24.  $myPicture->drawText(150,35,"Average temperature",array("FontSize"=>20,"Align"=>TEXT_ALIGN_BOTTOMMIDDLE));
  25.  
  26.  /* Set the default font */
  27.  $myPicture->setFontProperties(array("FontName"=>"../fonts/pf_arma_five.ttf","FontSize"=>6));
  28.  
  29.  /* Define the chart area */
  30.  $myPicture->setGraphArea(60,40,650,200);
  31.  
  32.  /* Draw the scale */
  33.  $scaleSettings = array("XMargin"=>10,"YMargin"=>10,"Floating"=>TRUE,"GridR"=>200,"GridG"=>200,"GridB"=>200,"DrawSubTicks"=>TRUE,"CycleBackground"=>TRUE);
  34.  $myPicture->drawScale($scaleSettings);
  35.  
  36.  /* Turn on Antialiasing */
  37.  $myPicture->Antialias = TRUE;
  38.  
  39.  /* Draw the line chart */
  40.  $myPicture->drawLineChart();
  41.  
  42.  /* Write the chart legend */
  43.  $myPicture->drawLegend(540,20,array("Style"=>LEGEND_NOBORDER,"Mode"=>LEGEND_HORIZONTAL));
  44.  
  45.  /* Render the picture (choose the best way) */
  46.  $myPicture->autoOutput("pictures/example.drawLineChart.simple.png");

jqPlot

  1. plot1 = $.jqplot('plot-area-daily'[s3, s1, s2],
  2. {
  3.         title : '总订单数、付款订单数按日统计 - 2011-04-10 ~ 2011-05-10',
  4.         legend:{show:true, renderer:$.jqplot.EnhancedLegendRenderer, location:'nw'},
  5.         series : [ 
  6.                 { label : '总订单数' },
  7.                 { label : '付款订单数' },
  8.                 { label : '未付款订单数' } 
  9.         ]
  10.         axes : { 
  11.                 xaxis : { 
  12.                         renderer : $.jqplot.DateAxisRenderer,
  13.                         tickOptions : { formatString: '%Y-%m-%d %a' }
  14.                         }
  15.                 yaxis : { min : 0, tickOptions : { formatString: '%d' } } 
  16.         }
  17.         cursor:{zoom:true, showTooltop:false}
  18. });

总结

pChartjqPlot
成像风格秀气,鲜亮大气,稍显暗淡
技术特点服务器端,基于PHP浏览器端,基于Javascript
优势生成图片文件,可用于多种用途在浏览器端渲染,节约服务器资源
适用场合图表有多种用途时图表仅需在浏览器中显示时

PureWeber On The Go

2011年5月9日 3 条评论

曰:路遥知马力

OJ要开始联合调试了,今天开始搭建一个测试环境,让OJ跑起来。折腾了一阵子,尚未搞定,判出来的题都是 -992, Server not ready。 估计要好好阅读一下Judge的代码才能找到问题的根源。

这两天在考虑开新项目,让小雨同学牵个头,充分利用一下学生们的空闲时间,力争不让他们空转。

现在参与项目的学生还是稍显少了点。不过兵在精不在多。还是克制住招更多人的欲望吧,把这些学生好好带出来。有了几个能独当一面的人,再招不迟。

OJ开发中遇到了不少问题,今天测Submit功能的时候,就发现张雄的代码有多处问题。为防止遗忘,记录之

  • 测试用的echo语句没有删除干净
  • 从老界面切换到新界面时,没有进行测试,直接提交了代码,导致原本应该post的表单变成了get,而且有一个输入框的name没有定义

OJ有很多页面都涉及到分页,原本打算写一个通用的分页功能,不过后来放弃了这个打算,改成让每个人都自己做一个分页。回头把它们各自的实现放在一起对比一下,然后再总结一下分页这个问题。恩,这需要组织一次分享会。

陈云飞的主题算是合格吧,不过评论的样式太过简陋,得安排他好好细化一下。

分类: 流水账 标签:

Run Faster

2011年5月8日 2 条评论

曰:刘郎已恨蓬山远,更隔蓬山一万重

昨天跟张志桐探讨了一下OJ某页面的SQL优化的问题。为防遗忘,特此记录。

测试的SQL

Query #1

  1. SELECT
  2.         Problems.Proid,Title,ACproblem.Totalsubmit
  3. FROM
  4.         Problems,
  5.         (SELECT Proid , count(*) AS Totalsubmit FROM Status
  6.                 WHERE Contestid = 0 AND Author = "patrick1234"
  7.                 GROUP BY Proid
  8.                 HAVING Proid in
  9.                         (SELECT Proid FROM Status WHERE Contestid = 0 AND Author = "patrick1234" AND JudgeStatus = -1002)
  10.         )
  11.         AS ACproblem
  12. WHERE Problems.Proid = ACproblem.Proid;

Query #2

  1. SELECT
  2.         Status.Proid,Title,count(*) as Totalsubmit
  3. FROM
  4.         `Status` , `Problems`
  5. WHERE Problems.Contestid = 0 AND Status.Proid = Problems.Proid AND `Author` = "patrick1234"
  6. GROUP BY Status.Proid
  7. HAVING Proid in
  8.         (SELECT Proid FROM Status WHERE Contestid = 0 AND `Author` = "patrick1234" AND JudgeStatus = -1002)
  9. ORDER BY Status.Proid;

Query #3

  1. SELECT p.Proid, Title, ac.ac, ac.total FROM
  2. (SELECT Proid, COUNT(CASE WHEN JudgeStatus = -1002 THEN 1 ELSE NULL END) AS ac, COUNT(*) AS total
  3.         FROM Status WHERE Author = "patrick1234" and Contestid = 0 GROUP BY Proid) AS ac
  4. LEFT JOIN Problems AS p ON p.Proid = ac.Proid
  5. WHERE ac.ac > 0

执行时间比较

QueryTime(seconds)
#10.12727000
#20.08309100
#30.03952900

Profile 信息

Query #1

Status Duration
starting0.000031
checking query cache for query0.000165
Opening tables0.000049
System lock0.000007
Table lock0.000141
optimizing0.000025
statistics0.000177
preparing0.000026
Creating tmp table0.000030
executing0.000005
Copying to tmp table0.048290
Sorting result0.000038
optimizing0.000024
statistics0.000133
preparing0.075577
Sending data0.000100
removing tmp table0.000009
Sending data0.000029
init0.000026
optimizing0.000010
statistics0.000026
preparing0.000013
executing0.000002
Sending data0.002261
end0.000008
query end0.000003
freeing items0.000042
storing result in query cache0.000003
removing tmp table0.000008
closing tables0.000006
logging slow query0.000002
cleaning up0.000004

Query #2

Status Duration
starting0.000030
checking query cache for query0.000168
Opening tables0.000025
System lock0.000007
Table lock0.000061
init0.000097
optimizing0.000029
statistics0.003208
preparing0.000060
Creating tmp table0.000058
executing0.000025
Copying to tmp table0.015100
Sorting result0.000056
optimizing0.000030
statistics0.000764
preparing0.063109
Sending data0.000185
end0.000003
removing tmp table0.000010
end0.000006
query end0.000003
freeing items0.000042
storing result in query cache0.000008
logging slow query0.000002
cleaning up0.000005

Query #3

Status Duration
starting0.000030
checking query cache for query0.000173
Opening tables0.000025
System lock0.000006
Table lock0.000115
optimizing0.000023
statistics0.000178
preparing0.000025
Creating tmp table0.000030
executing0.000005
Copying to tmp table0.037741
Sorting result0.000069
Sending data0.000101
removing tmp table0.000008
Sending data0.000023
init0.000032
optimizing0.000012
statistics0.000024
preparing0.000015
executing0.000002
Sending data0.000834
end0.000004
query end0.000003
freeing items0.000032
storing result in query cache0.000003
removing tmp table0.000005
closing tables0.000005
logging slow query0.000002
cleaning up0.000004

程序设计与实践2结课

2011年5月7日 2 条评论

曰:悠悠长路暂别过,漫漫征途再启程

程序设计与实践2顺利结课了。今天下午跟学生们唠叨了一下项目开发的一些琐事,估计学生们也是云里雾里的。以后这种不伦不类的说教得完全抛弃了,原本以为自己能真正的言之有物的,结果发现离开了代码和项目的土壤,扯这些闲淡实在是不给力。

总体上来讲这学期的课程效果还算是可以,几个参与项目的学生都还是令人满意的。而且还有王芳同学,这个所有作业全部完成的女生。应该说课程的基本目标是达到了。但是还是有很多的遗憾,在此罗列一下,下学期要有针对性的改进。

一、作业还不够精

我非常赞同sunner的“淡讲课,精作业”的理念,在这学期得课程里也在尝试去模仿,不过看起来现在还是有点蹒跚学步,不够老道。一共布置了3次作业,一个HTML+CSS的作业,一个算命程序,一个Mini WOW。前两次作业的提交情况还是让人满意的,效果也不错,不过最后一次的作业效果不好。

作业的几个问题:量小、难度低、没有体系。这些都要好好的加强一下。如果作业不够有挑战性,就无法显著的提升教学效果。本学期的作业还是侧重于让学生能够完成,免得太难吓跑了大家。下个学期应该适当的调整。目前在跟老杨讨论建立习题库的想法。

二、课堂讲授内容不够充实

有几节课的内容太过干瘪,言之无物。没有能够传达尽量多的信息量。课堂也显得枯燥无味,与我最开始“有意思”的定位相去甚远。在这一点上,可能还要多下一点功夫。课堂上的内容应该既有趣,又有代表性。下学期会考虑把本学期的学生遇到的问题整理汇总一下,作为素材用到下学期的讲授中。结合实例进行剖析,不能再这样光靠唾沫星子作战了。

三、知识缺乏系统性和条理性

原本计划本学期的课程要把Web开发的入门步骤整理一个有条理的系统出来,但是由于种种原因这件事情到现在还没有完成。尽管我自己已经在脑海中反复的构思过这个东西,但一直没能落实成文字和一个可执行的规划出来。这件事情一定得在下学期开学前搞出来。否则这个硬伤肯定会影响到下学期的教学效果。

Page optimized by WP Minify WordPress Plugin