Skip to content →

Tag: Software Engineering

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

i386-jos-elf toolchain on OS X Lion

Yesterday friend and I decided to follow the MIT Operating System Engineering course together in order to get a deep understanding of OS’s. And today I started setting up the cross compling environment for the labs. At first I wanted to get the toolchain from macports, but unluckily it didn’t successfully build binutils on my Mac. As a result, I started building the toolchain from the source code, following the instructions at http://pdos.csail.mit.edu/6.828/2011/tools.html.

The programs you need for the toolchain include binutils, gcc, and gdb. For compiling gcc you also need GMP, MPFR, and MPC. The source codes are available at:

wget http://ftpmirror.gnu.org/binutils/binutils-2.21.1.tar.bz2
wget ftp://ftp.gmplib.org/pub/gmp-5.0.4/gmp-5.0.4.tar.bz2
wget http://www.mpfr.org/mpfr-current/mpfr-3.1.0.tar.bz2
wget http://www.multiprecision.org/mpc/download/mpc-0.8.2.tar.gz
wget http://ftpmirror.gnu.org/gcc/gcc-4.5.1/gcc-core-4.5.1.tar.bz2
wget http://ftpmirror.gnu.org/gdb/gdb-6.8a.tar.gz

Unzip them in a directory and build binutils, gcc, and gdb one by one.

$ tar jxvf binutils-2.21.1.tar.bz2
$ cd binutils-2.21.1
$ ./configure --target=i386-jos-elf --disable-nls && make && sudo make install

In order to build gcc, GMP, MPFR and MPC needs to be built first.

$ mkdir -p libs/install
$ mv gmp-5.0.4.tar.bz2 mpfr-3.1.0.tar.bz2 mpc-0.8.2.tar.gz libs/
$ tar jxvf gmp-5.0.4.tar.bz2
$ mkdir gmp-build; cd gmp-build
$ ../gmp-5.0.4/configure --prefix=$(cd ../install && pwd)
$ make && sudo make install
$ cd ..
$ tar jxvf mpfr-3.1.0.tar.bz2
$ mkdir mpfr-build; cd mpfr-build
$ ../mpfr-3.1.0/configure --prefix=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/ --with-gmp=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/
$ make && sudo make install
$ cd ..
$ tar zxvf mpc-0.8.2.tar.gz
$ mkdir mpc-build; cd mpc-build
$ ./configure --prefix=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/ --with-gmp=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/ --with-mpfr=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/
$ make ; sudo make install
$ cd ..
$ tar jxvf gcc-core-4.5.1.tar.bz2
$ mkdir gcc-build; cd gcc-build
$ ../gcc-4.5.1/configure --target=i386-jos-elf --disable-nls --without-headers --with-newlib --disable-threads --disable-shared --disable-libmudflap --disable-libssp --with-gmp=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/ --with-mpfr=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/ --with-mpc=/Users/daoyuanli/Downloads/i386-elf-gcc/libs/install/
$ make ; sudo make install

Note that it’s essential to build gcc in a directory different from the source code directory to avoid compiling errors.

Then make gdb:

$ tar zxvf gdb-6.8a.tar.gz
$ mkdir gdb-build; cd gdb-build
$ ../gdb-6.8/./configure --target=i386-jos-elf --program-prefix=i386-jos-elf- --disable-werror
$ make && sudo make install

QEMU is available in macports:

$ sudo port install qemu
15 Comments

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

Session Establishment and Tearing Down

Each session has a ‘status’, it can be ‘new’, ‘establishing’, ‘cancelling’, ‘established’, ‘tearingdown’ and ‘destroyed’.

When a new session is created, its status is ‘new’.

When an ‘INVITE’ is received, it sends out an ‘OK’ message and change its status to ‘establishing’.

After receiving an ‘ACK’ message the status will be changed to ‘established’.

Then begins the transferring of voice data using RTP.

When the sending finishes the status will become ‘tearingdown’.

A ‘BYE’ message is also sent to the client.

The status becomes ‘destroyed’ after getting ‘OK’ from the client.

When a ‘CANCEL’ message is received, the status becomes ‘cancelling’.

Then it sends back ‘OK’ and ‘Request Terminated’ messages.

After received an ‘ACK’, the status becomes ‘destroyed’.

The thread is as follows:


@Override
public void run() {

    while (true) {
        if (requests.size() == 0) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            final DatagramPacket packet = requests.get(0);
            final String request = new String(packet.getData());
            System.err.println(request);
            sipRequest = new SIPRequest(request);
            if (request.toUpperCase().startsWith("INVITE")) {
                System.out.println("Got INVITE");
                if (!status.equals("new")) {
                    requests.remove(0);
                    continue;
                }

                String requestLine = request.substring(6).trim();
                String uri = requestLine.substring(0, requestLine.indexOf(' '));
                //System.out.println(uri);
                String usr = "";
                if (uri.toUpperCase().startsWith("SIP:")) {
                    usr = uri.substring(4, uri.indexOf('@'));
                } else {
                    usr = uri.substring(0, uri.indexOf('@'));
                }
                if (!usr.equalsIgnoreCase(user)) {
                    sendUserNotFound(sipRequest);
                    status = "tearingdown";
                    System.out.println("Status: " + status);
                    continue;
                }

                sendTrying(sipRequest);
                sendRinging(sipRequest);
                final String rtpport = request.substring(request.indexOf("m=audio") + 8, request.indexOf("m=audio") + 13);
                final String sdp = getSDP(request);
                new Thread() {

                    @Override
                    public void run() {
                        File file = new File("wav/" + voiceFile);
                        if (file.exists()) {
                            locator = new MediaLocator("file:/" + file.getAbsolutePath());
                        } else {
                            System.out.println("Using default voice file!");
                            locator = new MediaLocator("file:/" + file.getAbsolutePath());
                        }
                        transmitter = new Transmitter(locator, packet.getAddress().toString().substring(1), rtpport);
                        transmitter.prepare();
                    }
                }.start();

                new Thread() {

                    @Override
                    public void run() {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        if (status.equals("establishing")) {
                            sendOK(sipRequest, sdp, rtpport);
                        } else {
                            try {
                                transmitter.stop();
                            } catch (NullPointerException ex) {
                                Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
                                System.out.println("Transmitter already stopped!");
                            }
                        }
                    }
                }.start();
                requests.remove(0);
                status = "establishing";
                System.out.println("Status: " + status);
            } else if (request.toUpperCase().startsWith("ACK")) {
                System.out.println("Got ACK");
                //sendOK(sipRequest);
                requests.remove(0);
                if (status.equals("establishing")) {
                    status = "established";
                    System.out.println("Status: " + status);
                    new Thread() {

                        @Override
                        public void run() {
                            transmitter.start();

                            long duration = new VoiceInfo(locator).getDuration();
                            try {
                                Thread.sleep(duration);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
                            }

                            try {
                                transmitter.stop();
                            } catch (NullPointerException ex) {
                                Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
                                System.out.println("Transmitter already stopped!");
                            }
                            if (!status.equals("tearingdown") && !status.equals("destroyed")) {
                                sendBye(sipRequest);
                                status = "tearingdown";
                                System.out.println("Status: " + status);
                            }
                        }
                    }.start();
                } else if (status.equals("tearingdown")) {
                    status = "destroyed";
                    System.out.println("Status: " + status);
                    break;
                } else if (status.equals("cancelling")) {
                    status = "destroyed";
                    System.out.println("Status: " + status);
                    break;
                }
            } else if (request.toUpperCase().startsWith("BYE")) {
                System.out.println("Got BYE");
                sendOKWithoutSDP(sipRequest);
                requests.remove(0);
                try {
                    transmitter.stop();
                } catch (NullPointerException ex) {
                    Logger.getLogger(Session.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.println("Transmitter already stopped!");
                }
                status = "destroyed";
                System.out.println("Status: " + status);
                break;
            } else if (request.toUpperCase().startsWith("SIP/2.0 200")) {
                requests.remove(0);
                System.out.println("Got OK");
                if (status.equals("tearingdown")) {
                    status = "destroyed";
                    System.out.println("Status: " + status);
                    break;
                }
            } else if (request.toUpperCase().startsWith("CANCEL")) {
                requests.remove(0);
                System.out.println("Got CANCEL");
                status = "cancelling";
                System.out.println("Status: " + status);
                sendOKWithoutSDP(sipRequest);
                sendTerminated(sipRequest);
            } else {
                requests.remove(0);
            }
        }
    }
}
Leave a Comment

Test plan

1.Introduction

In this project we implemented an Olympic medal tracking system; its basic requirements are included in Functional Requirements and Project Plan. For more details, please refer to the two documentations mentioned above.

Testing for this system is relatively easy for the following reasons:

  1. The functions required by the customer are simple and basic.
  2. The customer does not place scalability at an important position.

However, testing is still important because we can not guarantee the system to function well according to the requirements. Furthermore, even if the customer does not place performance of the system at first place, it is still essential that our system will respond within the time one user could bare.

2. Testing Staff

Staff Responsibilities
Song Shaoyi Make test plan, Functional test
Mei Xiaowei User interface test
Li Boqiang Performance test

3. Test Cases

Case #

Module

Pre-condition

Action

Expected result

1

Login

On login page. User is not logged in.

Type in an invalid username/password and press “Login”

An error message of “Invalid username or password” is displayed in red on login page.

2

Login

On login page. User is not logged in.

Type in an correct username/password and press “Login”

Display admin functions on the top of the page, including login out link.

3

Login

On login page. User is logged in.

Whether require user login again

No further requirement for relogin.

4

Log off

On any page. User is logged in.

Click on link “logoff”.

Admin functions on top of the page disappear and display “login” function link.

5

Search

On search main page. User logged in.

Click on link “Search by date(s)”.

Go to search by date page.

6

Search

On search main page. User not logged in.

Click on link “Search by date(s)”.

Go to search by date page.

7

Search

On search main page.

Click on link “Search by event(s)”.

Go to search by event
page.

8

Search

On search main page.

Click on link “Search by
country(s)”.

Go to search by country page.

9

Search

On search main
page.

Click on link “Search by athlete(s)”.

Go to search by athlete page.

10

Search

On index page.

Click on link “Search by date(s)”.

Go to search by date page.

11

Search

On index page.

Click on link “Search by event(s)”.

Go to search by event page.

12

Search

On index page.

Click on link “Search by country(s)”.

Go to search by country page.

13

Search

On index page.

Click on link “Search by athlete(s)”.

Go to search by athlete
page.

14

Search

On index page.

Click on link “country name”.

Go to search results of medals the country won.

15

Search

On index page.

Click on link “athlete name”.

Go to search results of medals the athlete won.

16

Search

On index page.

Enter a valid country name in “country field”, Click on link “search”.

Go to search results of medals the country won.

17

Search

On index page.

Enter an invalid country name in “country field”, Click on link “search”.

Show no such country error message.

18

Search

On index page.

Enter a valid country name in “athlete field”, and enter athlete name in “athlete field”, Click on link “search”.

Go to search results of medals the country won.

19

Search

On index page.

Enter an invalid country name in “athlete field”, and enter athlete name in “athlete field”, Click on link “search”.

Show no such country error message.

20

Search

On index page.

Enter a valid country name in “athlete field”, and enter athlete name in “athlete field”, Click on link “search”.

Go to search results of medals the country won.

21

Search

On index page.

Enter a valid athlete name in “athlete field”, Click on link “search”.

Go to search results of medals the athlete won.

22

Search

On index page.

Enter an invalid athlete name in “athlete field”, Click on link “search”.

Show no such athlete error message.

23

Search

On search result page.

Click on link “athlete name”.

Go to search results of medals the athlete won.

24

Search

On search result page.

Click on link “country name”.

Go to search results of medals the country won.

25

Search

On search result page.

Click on link “rank by date”.

Rank search results by
date.

26

Search

On search result page.

Click on link “rank by
event”.

Rank search results by event.

27

Ranking

On index
page.

Click on link “gold”

Rank countries by number of gold medals.

28

Ranking

On index page.

Click on link “total”

Rank countries by number of total medals.

29

Ranking

On search result page.

Click on link “Search by date(s)”.

Rank the results by date.

30

Ranking

On search result page.

Click on link “Search by event(s)”.

Rank the results by event.

31

Admin

On management page. User is logged in.

Click on link “add”

Jump to add medal page.

32

Admin

On management page. User is logged in.

Click on link “correct”

Jump to correct medal confirm page.

33

Admin

On correct medal confirm page. User is logged
in.

Click on link “confirm”

Jump to delete medal information page.

34

Admin

On correct medal confirm page. User is logged in.

Click on link “cancel”

Jump to admin default page.

35

Admin

On management page. User is logged in.

Click on link “delete”

Jump to delete medal confirm page.

36

Admin

On delete medal confirm page. User is logged in.

Click on link “confirm”

Jump to delete medal information page.

37

Admin

On delete medal confirm page. User is logged in.

Click on link “cancel”

Jump to admin default page.

4. Performance and UI tes

It is essential that our system will respond within the time one user could bare, and the user interface should be nice as well. So testing of performance should be measured by the testers’ comparison between our system and existing systems.

Leave a Comment

Functional requirements

1. Features

1) For general users

a) Simulation of a simple Olympic medal tracking system.
b) The system should allow general users to access the medal tracker pages without requiring them to login. They should be able to see the number of medals (broken down to gold, silver, bronze, and total) won by each country in a sorted list. Users should be able to sort by gold medals and total medals.
c) The system should also enable general users to go to any particular country and check the number of medals the country has collected in each event.
d) Finally a user can go to any athlete and find out the number of medal(s) won by this athlete, broken down by events.
2) For the administrator

a) The system should have admin login functionality for the administrator to input and correct the data.
b) Once an administrator logs into the admin account, the system should provide the capabilities of assigning and removing a medal from any country for any event by any athlete.
c) The system needs to give admin user an option to logoff.
d) Without requiring them to login, the system should also allow general users to access the medal tracker pages. They should be able to see the number of medals (broken down to gold, silver, bronze, and total) won by each country in a sorted list. Users should be able to sort by gold medals and total medals.
e) The system should also enable general users to go to any particular country and check the number of medals the country has collected in each event.
f) Finally a user can go to any athlete and find out the number of medal(s) won by this athlete, broken down by events.
2. Performance

1. The default page for general users should be a rank by gold medals.
2. Web pages should display well in IE version 6.0 or above.
3. Login link for the administrator should be obvious on page.
4. Languages displayed on pages can be decided by the team, English and Chinese are both OK.
5. Scalability is not an important issue.
6. Search function should be obvious and user-friendly.
7. The web page should be free of advertisements.
3. Speed

There are no speed requirements; but the system should respond within the time a regular user could stand.

4. Use cases

 

Leave a Comment

使用Oracle Job实现定时向管理员发送信息

1.构造实现功能(发送消息)的存储过程:

CREATE OR REPLACE PROCEDURE "ADMIN"."SEND_EMP_BIRTHDAY_MSG" is
 cursor emp_cursoris
 select eid, ename
 from admin.employee
 where to_char(sysdate, 'mm-dd') = to_char(birthdate, 'mm-dd');
eid number(5);
 ename varchar2(20);
 msgdesc varchar2(3000);
begin
 msgdesc := '';
 for rname in emp_cursor loop
 msgdesc := msgdesc || '\n员工编号: ' || rname.eid
|| ' 员工姓名: ' || rname.ename;
 end loop;
 if length(msgdesc) > 0
 then
 msgdesc := '今天是以下员工的生日:\n' || msgdesc;
insert into admin.messagevalues(admin.msgid_sequence.nextval,
sysdate, '系统提示', 'admin', msgdesc, 1, 1, 0);
dbms_output.put_line(msgdesc);
end if;
dbms_output.put_line(msgdesc);
end;

2.创建JOB

variable job1 number;
begin
dbms_job.submit(:job1,'send_emp_birthday_msg;',sysdate,'sysdate+1');
--每天运行send_emp_birthday_msg过程一次
end;

3. 运行JOB

begin
dbms_job.run(:job1);
end;
Leave a Comment

CrazyBus Overview

CrazyBus public transport management system is a system used to help public transport companies manage their daily affairs. The system contains several modules including employee management, department management, bus management, line and bus stop management and lookup, business achievement management, accident management, user management, ticket management, IC card management, and so on.

It contains a Client/Server (C/S) system written in Java, and a Browser/Server (B/S) system written in JSP. The C/S module handles all the management tasks, while the B/S system handles users’ lookup requests and feedbacks and so on. The system uses Oracle 9i as database management system.

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		

Experience of Geany — A lightweighted IDE

Geany’s homepage: http://geany.uvena.de/Main/HomePage

Well, since it’s lightweighted, it’s small and, above all, FAST. For personal user, I think it’s much faster than eclipse, and much easier to use than emacs.

It’s basic features:

syntax highlighting
code folding
code completion
auto completion of often used constructs like if, for and while
auto completion of XML and HTML tags
call tips
many supported filetypes like C, Java, PHP, HTML, Python, Perl, Pascal
symbol lists

It’s code completion function is of great help, and will help us a lot!

But there are problems. I’ve used this IDE for only a day, but the auto
indentation function can’t work correctly. For example:

for(i=0;i<10;i++) [press enter here]
[it should be indented like this]
[but not this]

or maybe it’s my problem.

If anyone works this problem out, please email me! Thanks.

 

Leave a Comment