Skip to content →

Category: Software Engineering

Tastypie error handling with Unauthorized Exception

In Tastypie v0.9.15 unauthorized exception messages are not included in the response. The cause lies in the following code: (tastypie/resources.py, Line 601-602 in v0.9.15)

    def unauthorized_result(self, exception):
        raise ImmediateHttpResponse(response=http.HttpUnauthorized())

In the above snippet an empty response is returned, without including messages in `exception`.

In order to fix this, you can override this method in your model resources, for example:

    def unauthorized_result(self, exception):
        """Override tastypie method to return a reasonable error response."""
        raise ImmediateHttpResponse(
            response=HttpUnauthorized(
                json.dumps({'error': exception.message})
            )
        )

Hi, the company I’m working for (yabroad.com) is hiring Website Backend and Frontend Developers to our platform team. We are building an open platform for youngsters to travel beyond boarders and we offer youngsters internship, language study, travel and volunteer opportunities. Please contact me if you are interested.

Leave a Comment

Upgrading Tastypie from v0.9.11 to v0.9.12 and above

Here are my notes on how to upgrade Tastypie from version 0.9.11 to 0.9.12, as there’re no release notes for v0.9.12. Release notes for 0.9.13 and above are available here: http://django-tastypie.readthedocs.org/en/latest/release_notes/index.html.

1. override_urls() becomes prepend_urls(), the new name makes more sense since what the function does is to insert customized urls instead of replacing the default urls with your customized urls.

2. obj_* methods accepts different parameters. Before:

def obj_get(self, request=None, **kwargs):
    pass

Now obj_get, obj_create, etc. accepts bundle as the parameter apart from keyword arguments. You can get request object from the bundle:

def obj_get(self, bundle, **kwargs):
    request = bundle.request
    pass

3. apply_authorization_limits is no longer in use and it’s replace with a finer grained authorization mechanism. For example:

from tastypie.authorization import Authorization
from tastypie.exceptions import Unauthorized

class ProgramAuthorization(Authorization):
    def read_list(self, object_list, bundle):
        user = bundle.request.user
        if user.is_authenticated() and user.is_staff:
            return object_list
        else:
            return object_list.filter(is_published=True)

    def read_detail(self, object_list, bundle):
        if bundle.request.user.is_staff or bundle.obj.is_published:
            return True
        raise Unauthorized()

    def create_list(self, object_list, bundle):
        raise Unauthorized()

    def create_detail(self, object_list, bundle):
        if bundle.request.user.is_staff:
            return True
        raise Unauthorized()

    def update_list(self, object_list, bundle):
        raise Unauthorized()

    def update_detail(self, object_list, bundle):
        if bundle.request.user.is_staff:
            return True
        raise Unauthorized()

    def delete_list(self, object_list, bundle):
        raise Unauthorized()

    def delete_detail(self, object_list, bundle):
        raise Unauthorized()

Please note that *_list methods should return a list or raise exceptions; whereas *_detail methods should return boolean values or raise exceptions. For more information, see: http://django-tastypie.readthedocs.org/en/v0.9.12/authorization.html

Hi, the company I’m working for (yabroad.com) is hiring Website Backend and Frontend Developers to our platform team. We are building an open platform for youngsters to travel beyond boarders and we offer youngsters internship, language study, travel and volunteer opportunities. Please contact me if you are interested.

Leave a Comment

码农

最近看系统编程准备面试,顺便找点儿小算法练练手。在面试书上看到写冒泡排序的面试题,心血来潮也来练练手。闭着眼睛敲完代码,编译竟然没有错误,运行了一下结果也竟然是对的。

于是重新打开代码,怀着无比复杂的心情来审视自己的代码,郁闷的是看不懂自己5秒钟之前写的代码。我一边很囧的看着书上给出的代码,一边对着自己的代码检查。迷迷糊糊五分钟过去之后还是看不出来自己的代码是不是冒泡排序……

无奈之下拿出笔在草稿上画图一步一步推,终于验证了自己代码的正确性……30秒写完代码,300+秒来读自己写了什么,确实够囧的,
不知道是大一的时候代码背的太熟了的缘故……

估计以后当了码农会经常出现这种状况吧:噼里啪啦的一顿敲代码,敲完之后对着显示器一顿发愣,TMD刚才都敲了些啥?就像真正的农民种田一样,种久了之后做事情完全不过脑,偶尔思考一下的时候就会感慨:我靠,我这块地为啥要撒这么多种子,用这么多化肥啊。第二天睡觉前恍然大悟:就应该放这么多才对!之前折腾个什么劲儿阿!

Leave a Comment

Qt画图

Qt提供了一个QPainter来画图,可以用来绘制矢量图,也可以用来装载图片。今天实现的是一个给照片加边框的功能,为了练习,将PicFrame构造成一个继承自QWidget的自定义Widget。这时QPainter不能直接在自己定义的Widget中使用,而需要在paintEvent(QPaintEvent *event)中实现,否则会有类似于“QPainter::begin: Paint
device returned engine == 0, type: 1”的错误消息出现。

void PicFrame::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QRect rect(0, 0, image.width()*(1+frameSize), image.height()*(1+frameSize));
    painter.fillRect(rect,color);
    QPoint point(frameSize*image.width()/2, frameSize*image.height()/2);
    painter.drawImage(point, image);
}

=============================心情分割线=============================

今天NordSec2010开始,又见到了很多老朋友。再聚首总是有很多要交流的,大家都在为毕设发愁,都在为前途迷茫。从来没有像现在这样反感学术,当初不去美国的决定似乎是对的。

Leave a Comment

一步一脚印

咱虽然笨,一步一步慢慢来还不行么。

用正则表达式改进了昨天的计算器,用来限制用户输入。

regExp.setPattern("^\\d*.?\\d+[\\+\\-\\*\\/]\\d*.?\\d+$");
lineEdit->setValidator(new QRegExpValidator(regExp,this));

因为这个匹配模式是字符串,而字符串中”是转义字符,所以’d’放到字符串中就应该写成’\d’。类似的,如果要匹配一个”,则应该写成’\\’。

另外今天还写了个记事本,实现了最基本的打开,修改,保存和修改字体功能。Qt
Designer用的不太熟,于是手工添加控件,那叫一个麻烦。基本控件大致了解了,对文件的操作还不熟。中间由于把保存文件的对话框写成了打开文件的对话框而导致一直不能保存文件,原来这两个还不一样,虽然长得很像,汗。

QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), ".", tr("Text files (*.txt)"));
QString filename = QFileDialog::getSaveFileName(this, tr("Save text file"), ".", tr("Text files(*.txt)"));

对Signal-Slot机制的了解基本到了可以用的程度,但是对于中间的参数传递过程还一无所知。明天继续。

=============================心情分割线=============================

最近一直比较抑郁,算来差不多郁闷了将近二十年了。当然中间也会有间歇性的亢奋,但总体来说太微不足道了。以前总是对过去恋恋不舍,对未来不知所措,对当下却不能把握。总是过于重视别人的看法,过多的考虑别人的感受。从来不知道自己需要什么,现在回首看看,自己竟然不认识自己。

于是我打算跟自己一刀两断,我从今天开始就是我而且只是我,不再在乎他人的评价,不去关心我不愿关心的人和事,只做自己想做的事情。锲而不舍,勇往直前,纵然头破血流也在所不惜。不是做回自己,因为以前的我没有自己。

这几天一直听李宗盛,把他的四首歌翻来覆去的听。他那沙哑的声音切割者我的心,想哭却无法从干枯的眼睛中挤出半滴泪水。真爱难寻,我会继续等待,孤傲的常驻于此。直到你出现在我面前,I’ll love as if I’ve never been in love before.

思维之混乱,阅者了然。

Leave a Comment

千里之行

用Qt写计算器,花了我一个晚上终于写出来一个能用的了,能赶上大二学Java时写计算器的速度了。

用Qt Designer设计界面比较方便,用熟之后效率会更高。把界面设计好之后可以通过继承的方式给自己的类添加逻辑。如果设计的界面保存为mycaculator.ui的话,uic将会自动将这个XML文件转换成ui_mycaculator.h,其中的namespace为Ui。

#include"ui_mycaculator.h"
class Caculator : public QMainWindow, public Ui::MyCaculator

另外,Qt对字符串的处理简直跟Java一样了:

QString s1 = expStr.split(QRegExp("[+-*/]"))[0]; 
QString s2 = expStr.split(QRegExp("[+-*/]"))[1];
double d1 = s1.toDouble();
double d2 =s2.toDouble();
resStr = QVariant(d1+d2).toString();
expStr.append(resStr);

总算是迈出了第一步,再接再厉。

更新:上面的正则表达式不对,因为’+’, ‘-‘和’*’在正则表达式中有特殊意义。应该为如下:

QString s1 = expStr.split(QRegExp("[\\+\\-\\*/]"))[0];
QString s2 =expStr.split(QRegExp("[\\+\\-\\*/]"))[1];
double d1 = s1.toDouble();
double d2 = s2.toDouble();
resStr = QVariant(d1+d2).toString();
expStr.append(resStr);
Leave a Comment

Qt学习:简介和信号与槽机制

以前以为Qt比较麻烦,今天看了一下,发现它其实不比Java难。

首先Qt有非常详细的文档。这个对于开发者来说是十分重要的,纵览现在的流行开发平台,不管是Java,还是微软的平台,都有为开发人员提供详实的文档和指南。如果没有文档支持,开发过程会相当痛苦。这一点我深有体会,前段时间用libpcap写点儿小程序,这个库的所有文档就是一页man page,我甚至不知道某个函数的参数到底是什么类型。

其次,Qt的跨平台性能不输Java。Qt现在支持大多数桌面平台,Windows,Linux和Unix,Mac,手机平台上面的应用也已经成熟。开发者不用更改一行代码,就可以使自己的应用程序运行在每一个操作系统中。

还有,Qt被Nokia收购之后推出了配套的IDE,Qt Creator。这个IDE强大且美观,包含方便的图形界面设计工具,图形化调试工具,手机界面模拟器以及多样化的版本控制工具支持。

总体来说,Qt的易用性是不错的,易于上手,易于开发;但是至于性能,包括速度和安全性,我目前还没有一个清晰地认识。但我相信Nokia里面的那帮人会不断想方设法的提升Qt性能的,毕竟Nokia现在手里的王牌也只有这个了。

Qt之中提供了方便的消息传递机制:信号和槽机制(Signals and Slots),这也是Qt的核心机制,用于对象之间的通信。他的格式如下:

connect(Object1, SIGNAL(signal), Object2, SLOT(slot));

当Object1的信号被触发时,Object2的相应槽就会给以相应。当然,上面只是信号与槽的一种连接方式,其他方式还可能是:
一个信号与另外一个信号相连,即一个信号触发另外一个信号:

connect(Object1, SIGNAL(signal1), Object2,
SIGNAL(signal2));

一个信号与多个槽相连:

connect(Object1, SIGNAL(signal), Object2, SLOT(slot1));
connect(Object1, SIGNAL(signal), Object3, SLOT(slot2));

同样的,一个槽也可以响应多个信号:

connect(Object1, SIGNAL(signal1), Object2, SLOT(slot));
connect(Object3, SIGNAL(signal3), Object2, SLOT(slot));

简单的例子:

#include
#include

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPushButton b("Quit");
    b.show();
    QObject::connect(&b, SIGNAL(clicked()), &app, SLOT(quit()));
    return app.exec();
}
Leave a Comment

UML Review

Input and output of different stages in software development:

Stage Inputs Outputs
Requirement Analysis Stackeholders, goals, existing bussiness processes Business models, use case models, prototypes
Systems
Analysis
 Business models, use case models, prototypes  Use case definitions, object model, prototypes
Design  Use case definitions, object model, prototypes  Object model, data model, component model, architectural view, interface specifications
Implementation  Object model, data model, component model, architectural view, interface
specifications
Source code, complied code, database, interfaces, deployment plan
Testing  Business models, use case models, use case definitions Fault report, acceptance

Activity diagrams are used to describe flows in a variety of situations, they are flow diagrams and can be used in business modelling, requirements modelling, systems analysis and design.

Use case diagrams are used to show the presentation of functionality of a system and its interaction with the outside world. The diagrams show the boundaries of software systems but do not specify functionalities. They can be used in business modelling and requirements modelling.

Class diagrams show the static structure of a system, with classes and relationships between classes. They are used in business modelling, requirements modelling, systems analysis and design.

Statechart diagrams are used for modelling the internal state changes of and object and are a variant of activity diagrams with largely the same notation. They are used in business modelling, requirements modelling, systems analysis and design.

Sequence diagrams provide a time-ordered mapping of steps in the execution of a scenario into interactions between objects. They are one of the primary tools ofr elaborating use cases in analysis and design. They are used in systems analysis and design.

Collaboration diagrams provide a mapping of steps in the execution of a scenario into interactions between objects, drawn in two dimension in a similar way to class diagrams. They are used for similar purposes to sequence diagrams, but present the information in a different way.

Component diagrams show the implementation structure of the application and are used by the designer to indicate where the objects are implemented and how the components interact.

Reference: Ken Lunn, Software Development with UML, Palgrave Macmillan, New York, 2003, pp362-376

Leave a Comment

项目总结

从8月份小学期开始到现在,已经过去了近四个月,我们的项目也随着时间的慢慢流逝,一点一点的从不成熟的想法变成了有那么一点意思的产品(虽然幼稚了一点,但是基本功能大部分还是实现了,对比一下需求分析,我们做得还是挺不错的!),下面是我们项目实现的大致日程:

8.15~9.27:

做基本的知识准备,听课(似乎也没有认真听),做需求分析,其中第一版在9月2号讨论得出,后来又经过修修补补,于9月4日最终定稿;

9.28~10.31:

继续储备知识,复习Java程序设计,复习数据库原理,了解Oracle的基本操作,画E-R图,设计数据库结构框架;

11.1~11.4:

验证表结构,建立数据库,建立表空间,表,约束,视图;

11.5~11.30:

实际编码,写文档,模块测试;

12.1~

整体测试,优化系统,写帮助文档;

截至现在(12.2),我们的C/S模块的客户端代码已经达到了22,000+ 行(当然,其中不乏质量低劣的代码,整个系统的集成度也还不够,我想这是两个导致代码量大的原因,另外一个重要原因是:我们选定的题目不够好,后面我将会提到),C/S模块主要由周滔,王靖,李道远三人完成,其中:

周滔主要负责乘车卡管理,安全事故管理模块,以及系统的美工,代码量 1,500+;

王靖主要负责人事管理,部门管理,业绩考核模块,以及数据库的建立和日常维护,代码量8,500+;

李道远主要负责车辆管理,线路站点管理,客户反馈模块,以及管理员登录界面,主界面,系统集成和数据库权限管理,代码量12,000+;

我们的B/S模块部分主要由林栋完成:

林栋主要负责客户查询线路、站点信息,查询乘车卡消费记录、余额,提交建议、投诉。

上面提到,我们选定的题目不够好,作为小组组长,我应该首先做自我检讨:

一方面,做公交公司运营管理系统是我提出来的,其实她可以算是一个企业级别的管理应用程序,但我不自量力,觉得我们可以把这个系统做好,实际上虽然实现了基本功能,但离真正的企业级应用还有很大距离。在没有动手之前,我们认为,“只要完成了需求分析里的功能,就可以拿出去卖了”,结果现在呢?我们确实完成了需求分析里的功能,但“就算给自己用,自己都不放心”。所谓“蚍蜉撼大树,可笑不自量”,也许说得就是我吧!

另一方面,我在最开始时并不十分了解这个系统究竟应该实现什么功能,只是简单的在网上找了一些介绍性的资料,而且我没有控制好需求分析,我们并没有到实地进行考察,而是通过自己的主观想象臆造出来的,有很多细节当时并没有想清楚,只是一味的好高骛远,以为功能是越多越好。

当然,做这个项目毕竟不是我们的最终目的,我们现在也根本没有能力和精力来做好这个项目,但是我觉得我们的确从中学到了很多东西,拿我自己为例:

第一,我知道了写代码并不是一件简单的事情。虽然以前也在学校ACM网站上做过一些题目,但真正应用到实际中,却又是另外一回事,ACM要求的更多的是算法与数据结构方面的知识,而实际应用中考虑的更多的是整体架构以及模块之间的契合,至于细节,我想考虑的最多的应该是异常处理吧,虽然我们的系统并没有过多的涉及;不仅是异常处理,整天坐在电脑前面敲代码也并不是一件很愉快的事情,项目做到一半的时候我的颈椎就开始疼,现在还在疼呢!难道这就是我们以后要过的生活?唉,这也太让人沮丧了吧!

第二,软件工程太重要了。我们的需求分析做得不够好,直接导致后来的实现上的诸多困难,也许现在我们还没有“软件工程里句句话都是血”这样刻骨铭心的经历,但是,这个项目的确给我敲响了警钟。以前看周爱民的《大道至简》,觉得他说的太玄了,做完项目后我又大致浏览了前面几节,似乎现在有那么一点“共鸣”的感觉了,呵呵,不知道到时候学习软件工程能不能深入理解。

第三,做一个管理者好难。前几天和另外一个组的组长聊天,他说:“没办法,我们不能扣他们的工资!”可能说得极端了一点,但有时候我也感到非常无奈,经常在组员面前觉得无所适从,究竟怎样才能让组员做事、做实事,怎样才能调动组员的积极性一直困扰着我。有一个网友在我们的Blog上留下了这样的话:“软件中价值的创造不仅取决于开发人员所知道的和所做的,也取决于他们之间的关系以及他们共同完成的事情。沟通、简单、反馈、勇气、尊重。”在完成这个项目的过程中,虽然没有出现什么大的问题,但我们之间的默契肯定没有达到,不是每个组员都是把这个项目当成自己的任务来完成的,不是每个组员都为这个项目贡献了自己的全部力量(或者很大部分力量)。一个优秀的团队需要相互信任,但我并没有充分信任组员,这是我的错误。我曾一度感到心力交瘁,也许真的,做任何事情都不简单,想要做好则更甚。

第四,做什么事情都不能及于求成。在没有正式开始写代码之前,一个组员估计一个星期之内就可以完成自己的模块,然而实际上他写了三个多星期,中间的过程似乎也是异常痛苦的。正因为我们都急于求成,所以需求分析没做好,看来做什么事情,脚踏实地,一步一个脚印才是正道。

第五,关于解决问题之道。曾经在网上看到一篇关于如何成为一个黑客的文章,文章建议拿到一个东西应该首先对它有一个大致的了解,然后遇到问题时可以高效的解决它。现在觉得,知识不是最重要的,重要的是思维、是能力,这也许是现在我们所缺少的。我一直在尝试培养自己的解决问题的能力,发现这种方法确实是挺高效的。以前从来没有接触过NetBeans,装上后先看看它的FAQ和帮助文档是相当必要的,所谓“磨刀不误砍柴功”,正是这个意思。

第六,独立自主与协同作战。以前还看过一篇文章,其中提到:绝大多数(或者全部)的黑客都是自学成才的,而且他们对待问题的态度都是自己一定可以解决掉问题,他们遇到问题时并不急于去问别人,而是自己认真分析,自己找资料,依靠自己的能力来解决问题。也许黑客有其自身的特殊性,但我认为独立自主解决问题无疑是提高自己的最快、最好的途径。至于协同作战,其重要性主要体现在大的项目中,但协同作战并不意味着抛弃独立自主。就像在大的战役中,士兵间的相互配合是很重要的,但如果抛弃了每个士兵的自主性不谈,恐怕相互配合是很难做到的。我想说的是,相互配合最终是要落实到每个个体上的,协同说到底还是体现到了个体的能力与素质之上。

第七,关于经验。以前看见什么招聘公告上都注明“有某某经验者优先”,开始觉得没什么,现在才稍微有一点感触。有很多东西是平时在课本上所学不到的,而要靠平时积累。自己慢慢在实践中摸索出来的东西才是最重要的。

第八,专业素质。听一个老师说保送研究生面试时不一定看你得了什么奖,老师们会跟你谈话,很容易就可以知道你是什么水平,也许这就是专业素质吧。我自己觉得通过做这个项目学到了很多,知识和能力方面都有所进步。至于专业素质,不是一朝一夕可以提高的,还有待进一步努力提高。

唉,越说越多,越扯越远,就此打住,总之,这样的实践机会并不多,感谢学院,康老师为我们提供这样一次难得的机会,也希望大家以后能珍惜这样的机会,珍惜短暂的大学生活,珍惜青春!

 

Leave a Comment

自虐是怎样炼成的

项目写代码连续写了近一个月了,我的自虐倾向与越来越严重了。现在看着代码就想吐,还有砸电脑的冲动,再严重一点可能就一拳挥到墙上去了,哇,流血、疼痛是否是一件很有快感的事情呢?(现在又发现自己不但有自虐倾向,而且还有变态的潜质啊!)

下面把我的修炼过程记录下来,供大家学习借鉴参考,欢迎拍砖:

1.从早上七点起床到晚上十一点半断电,一直看书,找资料,写代码,其间留下约半小时的时间补充一天所需的淀粉,脂肪,蛋白质和维他命;

2.在电脑屏幕前一坐就是三四个小时,有时候死盯着屏幕十几分钟发呆,醒过来时眼睛看不见任何不发光的东西,腰酸背痛,颈椎僵硬;

3.干吃奶粉,麦片,咖啡;

4.全身心投入到项目中,一个多星期不洗澡,当然,大家也可以不“刷脸洗牙”──引用王靖语;

5.忘掉除了项目以外的所有东西,头脑中除了项目还是项目,反应迟钝,丢三落四,记忆力下降,忘记“眼睛”的“眼”字怎么写;

6.语无伦次,逻辑混乱,自己都不知道自己在说什么;

7.经常说
The F Word ;

8.下定决心明天要去上课,第二天起床后的第一件事情就是开电脑,条件反射般的启动NetBeans,Oracle,然后开始新一天的战斗;

逃了近一个月的课,想想后天还有口语考试,My God! 唉,不写了,捶桌子摔椅子去了。

 

Leave a Comment

CrazyBus 项目需求分析最终版

一.人事管理

1. 能够记录每个在职员工的ID号,职务,姓名,照片,出生日期,加入公司的时间,工龄,职位变更,联系电话,家庭住址,政治面貌;

2. 记录出勤,奖惩,客户投诉;

3. 能提供已离职和退休员工其在职期间各种资料和档案。

二.车队管理

1.
记录车队队长,司机及其他相关工作人员;

2. 记录车队车辆数目,车牌号,车辆线路;

3. 车队长能管理该车队员工出勤,安排司机出车时间,临时调整车辆路线;

三.车辆管理

1. 管理公交公司的所有车辆,记录每辆车的车牌号,车型号,当前线路,维修记录,购车日期,各证件审核信息等;

2.
能查询车辆状况(服役年龄,维修记录等);能提醒相应工作人员定期对汽车作维护,证件审核等工作;

3. 已报废或退役车辆的相关记录和去向,可在车辆退役和报废时吊销相关的车牌,证件

四.线路和站点管理

1. 客户,管理员能通过线路号查询此线路的起点、终点,首末班车时间,每两趟公交车的发车间隔时间,票价;

2. 客户,管理员可以通过站点名查询经过此站点的线路号,此站点附近有名的地点;

3.
管理员可以通过线路号查询线路的效益(如按时间查询卖出的票数等);

4. 管理员可以查询运行在特定线路上的汽车车牌号及汽车数量;

5. 管理员可以调整线路经过的站点(增删站点),可以调整首末班车时间(按季节调整),发车间隔,票价等;

6. 管理员可以调整特定线路上的汽车(比如将一辆车换跑另一条线路等);

7. 管理员可以查询用户对特定线路或站点的建议及意见;

8.
管理员可以按时间查询特定线路的收入情况;

五.业绩考核

1. 管理员可以按时间查询员工的工作记录(比如出勤情况,司机的出车记录等);

2. 管理员能按时间查询司机的出车收入情况;

六.安全管理

1. 管理员可以按时间,按线路,按车队,按车牌号,按司机查询安全记录;

2. 管理员可以按事故原因中的关键字查询安全记录;

七.客户反馈管理

1. 客户可以给线路,车队,车辆,司机提意见和建议;

2.
管理员可以通过线路号,车队号,车牌号,司机ID,时间,关键字查询用户反馈记录;

八.客户查询管理

1. 输入起点和终点或者含有多个中途经过的站点,可以给出相应的换乘路线以及所经过的站点、站点数、各线路号、换乘次数、总里程数等信息。

2. 可以用街道名称或者标志建筑物来表示站点。

3. 线路查询,即查询该车次经由的所有站点。

4.
站点查询,即经过该站点的所有线路。

九.票务管理

1. 记录每趟车的收入。

2. 查询办卡的各项事宜。

3. 办里,挂失,退款各种类型的卡。

4. 查询办卡客户的消费记录,余额,办卡日期等,更改密码。

 

Leave a Comment

开发日记之三:小结一下

经过两个多月的酝酿和半个多月的逃课写代码的过程,终于于今天晚上8:00基本完成了我们项目的C/S部分的基本功能,下一步将进入模块测试和系统优化阶段,以及实现B/S部分的功能。

逃课两个多星期,写代码写的腰酸背痛,就技术方面来讲,解决了一下问题:

1.了解了NetBeans使用的GroupLayout,感谢豆芽的指点,看NetBeans生成的代码,然后拷贝,稍加修改,就可以向GroupLayout的面板中添加自己的模块,方法虽然流氓了一点,但也不失为一种好方法;

2.知道了数据库序列的使用,就是NEXTVAL,
CURRVAL;

3.知道了数据库触发器的使用,触发器是用来监听数据库表中数据的变化的,要定时完成某个任务,还得用job;

4.知道了数据库函数和过程,自己也还写了几个,并能配合job定时完成特定任务;

5.数据库游标,写存储过程和函数的时候学会的;

6.数据库约束和视图的使用;

7.数据库中的chr(10), chr(13), ||;

8.数据库的to_char(), to_date(),
length()等函数;

9.jdbc连接数据库;

10.java中的Date,Calenda,SimpleDateFormat等类以及自己定义类和接口;

11.JavaBean的基本使用;

12.JTable, JComboBox,JList以及DefaultTableModel, DefaultComboBoxModel, DefaultListModel;

13.Swing线程:invokeLater(), invokeAndWait();

14.BoxLayout,GroupLayout,BorderLayout,CardLayout

15.java事件监听;

写了这些,怎么觉得自己很傻?这些不都是以前都应该会的吗?

唉,傻就傻吧,以后加油。

 

Leave a Comment

开发日记之二:体会颇多

“嘴”上谈来终觉浅,绝知此事要躬行。

我们在讨论的时候觉得好像没有太大的问题,每次讨论也是嘻嘻哈哈,每个人都一副成竹在胸的样子;而具体画E-R图的时候,却感觉不是那么愉快了:一方面是因为我们前期的讨论不到位,基本上没有达到讨论应有的效果,在基本所有问题上都没有达成共识,所以画图的时候每个人还是固执己见,都认为自己的观点更好,导致大家吵架吵了一遍又一遍;令一方面是需求分析做得不够,在项目初期对项目的分析不全面、不透彻,也没有到公司去做需求,需求上的东西有一些是我们自己捏造出来的,有一些不完全符合实际,导致画图的时候模棱两可。

还有一个很大的问题:对数据库的理解不够透彻。虽然大家上学期都学了数据库这门课程,但我们不得不承认自己认识的浅陋,抛开我们对知识点的遗忘不说,我们对E-R模型以及范式的理解深度不够是肯定的。几乎每个人都画了E-R图,但每个人的质量都不高,而且画出来的图也不全面,不是关系没有理清楚,就是实关系的基数没标好,总之没有达到应有的水平。

更要命的是,大家都觉得自己的东西没有问题,自己做的就是对的,不容易接受他人的想法和观点。架是吵了很多,有时候争得脸红脖子粗的,但似乎也于事无补,却导致进程陷入僵局。

最后迫于交文档的期限,大家才又重新开始画图。但即使在这个时候,大家的努力配合仍然不够,四个人的精力始终不能放到一件事情上去。我作为组长,肯定有我自己的问题,没能使大家的力量往一处使。希望以后在这方面可以加强。

E-R图画了好几遍,又经过缝缝补补,终于开始有了一点轮廓,开始还想用范式来验证一下,结果发现根本无法入手──这便又是需求没做好的缘故了。最后抱着以后再好好想想约束的想法,把E-R图确定了下来。又根据E-R图,初步确定了数据库的表结构。尽管有些模块的具体实现还没有敲定,但数据库的基本轮廓算是确定下来了。

这个项目的前期工作基本上就已经确定下来了,即使前期做得不够,也只能靠后期好好实现了。需求分析要尽可能的保持原状,对于数据库,其基本的表结构也已经确定。剩下的工作就是具体实现了,希望大家在后期的工作中团结一致,心往一起想,劲往一处使,以最高的热情与斗志,迎接挑战,做好每一个细节,充分完成、完善我们的项目!

现在才发现需求分析的重要性,也许我们的每一步,都会牵扯到项目后面的实现,所以,我们应该做好每一件我们应该做得事情。前面的错误过失也许无法再补救,但现在我们做的,以及以后我们需要做的,却不能再马马虎虎、嘻嘻哈哈了!

 

Leave a Comment

开发日记之一:前期感受

组好队,取完队名,经过讨论终于确定了项目。又通过讨论,基本上确定了需求的大致框架,但是这一步却走得比较困难。

最初看起来非常简单的事情,仔细分析起来却并不简单。虽然说做需求的时候不要想如何去实现,但实际做起来却总想往实现上靠。简单的模型越想越复杂,但还好最终把框架定了下来。

细想一下,要实现这个系统并不简单,单是用户查询这一模块,要想做得好就要费劲脑汁,如何将查询做到快、省、准,如何实现图像的整合,都是我们面临的较大的挑战;还有数据的获取,暂时也没有想到好的解决方案;还有,怎样做才能更贴近实际,而又避免把系统做得臃肿……

现在我们还有很多不足的地方,比如对项目不够重视,缺乏激情,动手能力亟待提高,理论分析做得不太到位,更糟糕的是,对有些模块的认识还是模模糊糊;这些不足,克服了我们就会有很大的进步,然而如果克服不了,这个项目估计就完成不了。现在以我们的能力,要将这一系统做好恐怕还要每个人不懈努力。在今后的两个月里,要重新拾起JAVA,把数据库理论再弄通弄懂,熟悉JDBC,数据库编程,加强数据结构与算法方面的修养,学习XML……

任务虽然艰巨,但是我们不是懦夫,我们不能退却。我们要合理的安排自己的学习活动,相信自己,相信队友,相信我们Crazy_Bus!在未来的一段时间里,我们是室友,是队友,也是战友!想信通过大家的努力拼搏和奋斗,我们一定可以优雅的谢幕!

 

Leave a Comment

C++ STL Notes: String Replacement

Macro

You are asked to do some replacements on a string. Can you work it out?

Input and Output

 

Each test case will begin with a string in a single line, and followed by an integer N which means the number of replacements. The next N lines will give you two strings s1, s2, you should replace all the s1 into s2. For more details, see the
sample below.

Sample Input

 

abc
3
a b
bb a
c d
aaabaaaa
1
aa a

Sample Output

 

ad
aabaa

Note:
For the first sample:
After the first replacement, the string will be bbc.
After the second replacement, the string will be ac.
At last, the string will be ad.

My Code:

#include 
#include 
#include 

using namespace std;

void myreplace(string & strBig, const string & strsrc, const string &strdst)
{
string::size_type pos=0;
string::size_type srclen=strsrc.size();
string::size_type dstlen=strdst.size();
while( (pos=strBig.find(strsrc, pos)) != string::npos)
{
strBig.replace(pos, srclen, strdst);
pos += dstlen;
}
}

int main(int argc, char** argv)
{
string s;
while(cin>>s)
{
int n;
string s1,s2;
cin>>n;
while(n–)
{
cin>>s1>>s2;
myreplace(s,s1,s2);
}
cout<
			
	
	Leave a Comment