Skip to content →

Author: Daoyuan Li

NumPy’s ndarray indexing

In NumPy a new kind of array is provided: n-dimensional array or ndarray. It’s usually fixed-sized and accepts items of the same type and size. For example, to define a 2×3 matrix:

import numpy as np
a = np.array([[1,2,3,], [4,5,6]], np.int32)

When indexing ndarray, it supports “array indexing” other than single element indexing.  (See http://docs.scipy.org/doc/numpy/user/basics.indexing.html)

It is possible to index arrays with other arrays for the purposes of selecting lists of values out of arrays into new arrays. There are two different ways of accomplishing this. One uses one or more arrays of index values. The other involves giving a boolean array of the proper shape to indicate the values to be selected. Index arrays are a very powerful tool that allow one to avoid looping over individual elements in arrays and thus greatly improve performance.

So you basically can do the following:

a = np.array([1, 2, 3], np.int32)
a[np.array([0, 2])) # Fetch the first the third elements, returns np.array([1, 3])
a[np.array([True, False, True])] # Same as the line above

Besides, when you do equals operation on ndarrays, another ndarray is returned by comparing each element:

a = np.array([1, 2, 3], np.int32)
a == 2 # Returns array([False,  True, False], dtype=bool)
a != 2 # Returns array([ True, False,  True], dtype=bool)
a[a != 2] # Returns a sub array that excludes elements with a value 2, in this case array([1, 3], dtype=int32)
Leave a Comment

Statistics of insurance sold on Taobao.com on Valentine’s Day

On Feb. 14th Taobao launched a campaign to sell insurance products, which promises 7% yearly interest rate. The sales data is public, so I wrote a script to crawl them down and did a brief study on this data. Here’re the results.

On that day (actually sold out in less than two hours in total) more than 40,000 people participated, resulting a total sales of almost one billion CNY (the exact number: 980,270,000 CNY). Two companies participated in this sales campaign: Zhujiang and Tian’an. The sales statistics are:

ZhujiangTian’anTotal
# of Customers138312909242923
Sales mean (k CNY)24.92205921.84700322.837872
Sales min (k CNY)111
Sales 25% (k CNY)122
Sales 50% (k CNY)101010
Sales 75% (k CNY)202522
Sales max (k CNY)10009001000
Sales total (k CNY)344697635573980270

The histograms of how many people pay for each amount.

le100kgt100kle100k

Zhujiang was extremely popular: in 2 minutes and 56 seconds it reached a sales of 200,212,000 CNY, that’s more than 1 million CNY sales PER SECOND! Indeed Chinese are crazy about online shopping. 😀

Leave a Comment

MapReduce in MongoDB

http://docs.mongodb.org/manual/core/map-reduce/

http://docs.mongodb.org/manual/reference/command/mapReduce/

> db.lattern_money_record.mapReduce( function() { emit(this.quantity, 1) }, function(key, values) { return Array.sum(values) }, {   query: {'quantity': {$gt: 500}}, out: {inline: 1} } )
{
	"results" : [
		{
			"_id" : 550,
			"value" : 3
		},
		{
			"_id" : 570,
			"value" : 1
		},
		{
			"_id" : 580,
			"value" : 1
		},
		{
			"_id" : 583,
			"value" : 1
		},
		{
			"_id" : 587,
			"value" : 1
		},
		{
			"_id" : 600,
			"value" : 2
		},
		{
			"_id" : 660,
			"value" : 1
		},
		{
			"_id" : 700,
			"value" : 2
		},
		{
			"_id" : 800,
			"value" : 5
		},
		{
			"_id" : 900,
			"value" : 2
		},
		{
			"_id" : 924,
			"value" : 1
		},
		{
			"_id" : 949,
			"value" : 1
		},
		{
			"_id" : 980,
			"value" : 1
		},
		{
			"_id" : 990,
			"value" : 1
		},
		{
			"_id" : 1000,
			"value" : 12
		}
	],
	"timeMillis" : 36,
	"counts" : {
		"input" : 35,
		"emit" : 35,
		"reduce" : 6,
		"output" : 15
	},
	"ok" : 1,
}

The MapReduce code I used to analyze the 20 million hotel reservation records:

def get_aggregation(collection):
    '''
    1. Get unique set of people
    2. Get most frequent users
    3. Get aggregation by location of birth, age, month and day of birth
    '''
    # Emit multiple times in mapper function:
    # http://docs.mongodb.org/manual/reference/command/mapReduce/
    mapper = Code('''
                  function() {
                    function validate_rid(id) {
                        // From: https://gist.github.com/foxwoods/1817822
                        // 18位身份证号
                        // 国家标准《GB 11643-1999》
                        function rid18(id) {
                            if(! /\d{17}[\dxX]/.test(id)) {
                                return false;
                            }
                            var modcmpl = function(m, i, n) { return (i + n - m % i) % i; },
                                f = function(v, i) { return v * (Math.pow(2, i-1) % 11); },
                                s = 0;
                            for(var i=0; i<17; i++) {
                                s += f(+id.charAt(i), 18-i);
                            }
                            var c0 = id.charAt(17),
                                c1 = modcmpl(s, 11, 1);
                            return c0-c1===0 || (c0.toLowerCase()==='x' && c1===10);
                        }

                        // 15位身份证号
                        // 2013年1月1日起将停止使用
                        // http://www.gov.cn/flfg/2011-10/29/content_1981408.htm
                        function rid15(id) {
                            var pattern = /[1-9]\d{5}(\d{2})(\d{2})(\d{2})\d{3}/,
                                matches, y, m, d, date;
                            matches = id.match(pattern);
                            y = +('19' + matches[1]);
                            m = +matches[2];
                            d = +matches[3];
                            date = new Date(y, m-1, d);
                            return (date.getFullYear()===y && date.getMonth()===m-1 && date.getDate()===d);
                        }

                        // return rid18(id) || rid15(id);
                        try {
                            ret = rid18(id) || rid15(id);
                            return ret;
                        } catch (err) {
                            return false;
                        }
                    }

                    function validateEmail(email) {
                        // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
                        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
                        return re.test(email);
                    }

                    var str = this.CtfId;
                    if (str && validate_rid(str)) {
                        var prov = parseInt(str.slice(0, 2));
                        var year, month, day, sex;
                        if (str.length == 15) {
                            year = parseInt('19' + str.slice(6, 8));
                            month = parseInt(str.slice(8, 10));
                            day = parseInt(str.slice(10, 12));
                            sex = parseInt(str.slice(14, 15)) % 2 ? 'M' : 'F';
                        } else {
                            year = parseInt(str.slice(6, 10));
                            month = parseInt(str.slice(10, 12));
                            day = parseInt(str.slice(12, 14));
                            sex = parseInt(str.slice(16, 17)) % 2 ? 'M' : 'F';
                        }
                        var age = 2013 - year;
                        var valid_provs = [11, 12, 13, 14, 15,
                            21, 22, 23, 31, 32, 33, 34, 35, 36, 37,
                            41, 42, 43, 44, 45, 46,
                            50, 51, 52, 53, 54,
                            61, 62, 63, 64, 65,
                            71, 81, 82, 91];
                        if (age <= 0 || age > 100 ||
                            month <=0 || month > 12 ||
                            day <= 0 || day > 31 ||
                            valid_provs.indexOf(prov) == -1) {
                            emit('Corrupted', 1);
                        } else {
                            // emit('Province ' + prov, 1);
                            // emit('Age ' + age, 1);
                            // emit('Month ' + month, 1);
                            // emit('Day ' + day, 1);
                            // emit('Sex ' + sex, 1);
                            // emit('Prov ' + prov + ' Sex ' + sex, 1);
                            // if (this.Address && this.Address.length > 3) {
                            //     var cur_prov = this.Address.slice(0, 3);
                            //     emit('From ' + prov + ' to ' + cur_prov, 1);
                            // }

                            // var email = this.EMail;
                            // if (email && validateEmail(email)) {
                            //     var idx = email.lastIndexOf('@');
                            //     var domain = email.slice(idx + 1);
                            //     emit(domain.toLowerCase(), 1);
                            // }

                            if (prov == 32 && sex == 'M') {
                                emit(str, 1);
                            }
                            // if (prov == 32 && sex == 'F') {
                            //     emit(str, 1);
                            // }
                        }
                    } else {
                        emit('Corrupted', 1);
                    }
                  }''')
    reducer = Code('''
                   function(key, values) {
                    return Array.sum(values);
                   }''')
    result = collection.map_reduce(
        mapper, reducer, 'aggregation', query={'CtfTp': 'ID'}
    )
    return result

 

Leave a Comment

Debugging Apache configuration files on Mac OS X

Sometimes I make some modification to my site’s apache config and apache stops functioning, but I cannot get enough information from /var/log/apache2/error.log. Here’s a command that will tell you where the problem is:

sudo /usr/sbin/httpd -k start -e Debug -E /dev/stdout

It starts apache for debugging and prints out the messages on screen, so that hopefully you can find something useful.

Leave a Comment

mod_wsgi and mod_xsendfile on OS X 10.9 Mavericks

Updated on Nov 4, 2013: The following tricks may still work, however I have found a much easier solution. Simply install Xcode command line developer tools and you should be able to compile source code without issues:

$ xcode-select --install

After upgrading my Mac from 10.8 to 10.9 Mavericks my apache stopped working, so I have to reinstall mod_wsgi and mod_xsendfile. However, tricks are needed to compile and install these mods successfully.

Upgrade Xcode

Upgrade Xcode in App Store. As mentioned by Valerie:

I had to manually upgrade Xcode (after Mavericks upgrade) from the App Store & agree to its license because ./configure hung forever until I did that.

mod_wsgi

For mod_wsgi installation, create a soft link to OSX10.9.xctoolchain:

cd /Applications/Xcode.app/Contents/Developer/Toolchains/
sudo ln -s XcodeDefault.xctoolchain OSX10.9.xctoolchain

Then run configure under mod_wsgi source code directory:

mod_wsgi-3.4$ ./configure

It will generate a Makefile similar as follows:

#  Copyright 2007 GRAHAM DUMPLETON                                               
#                                                                                
#  Licensed under the Apache License, Version 2.0 (the "License");               
#  you may not use this file except in compliance with the License.              
#  You may obtain a copy of the License at                                       
#                                                                                
#      http://www.apache.org/licenses/LICENSE-2.0                                
#                                                                                
#  Unless required by applicable law or agreed to in writing, software           
#  distributed under the License is distributed on an "AS IS" BASIS,             
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      
#  See the License for the specific language governing permissions and           
#  limitations under the License.                                                

APXS = /usr/sbin/apxs                                                            
PYTHON = /usr/local/bin/python                                                   

DESTDIR =                                                                        
LIBEXECDIR = /usr/libexec/apache2                                                

CPPFLAGS =  -I/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/include/python2.7 -DNDEBUG 
CFLAGS =   -Wc,'-arch x86_64'                                                    
LDFLAGS =  -Wl,-F/usr/local/Cellar/python/2.7.5/Frameworks -framework Python -u _PyMac_Error   -arch x86_64
LDLIBS =  -ldl  -framework CoreFoundation                                        

all : mod_wsgi.la                                                                

mod_wsgi.la : mod_wsgi.c                                                         
    $(APXS) -c $(CPPFLAGS) $(CFLAGS) mod_wsgi.c $(LDFLAGS) $(LDLIBS)             

$(DESTDIR)$(LIBEXECDIR) :                                                        
    mkdir -p $@                                                                  

install : all $(DESTDIR)$(LIBEXECDIR)                                            
    $(APXS) -i -S LIBEXECDIR=$(DESTDIR)$(LIBEXECDIR) -n 'mod_wsgi' mod_wsgi.la 

clean :                                                                          
    -rm -rf .libs                                                                
    -rm -f mod_wsgi.o mod_wsgi.la mod_wsgi.lo mod_wsgi.slo mod_wsgi.loT          
    -rm -f config.log config.status                                              
    -rm -rf autom4te.cache                                                       

distclean : clean                                                                
    -rm -f Makefile Makefile.in                                                  

realclean : distclean                                                            
    -rm -f configure

However, this Makefile is not correct and running ‘make’ the compiler will complain something like:

mod_wsgi.c:34:10: fatal error: 'httpd.h' file not found

Prepend the following line to CPPFLAGS value:

-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apr-1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apache2

Save the Makefile and it will look something like:

#  Copyright 2007 GRAHAM DUMPLETON                                               
#                                                                                
#  Licensed under the Apache License, Version 2.0 (the "License");               
#  you may not use this file except in compliance with the License.              
#  You may obtain a copy of the License at                                       
#                                                                                
#      http://www.apache.org/licenses/LICENSE-2.0                                
#                                                                                
#  Unless required by applicable law or agreed to in writing, software           
#  distributed under the License is distributed on an "AS IS" BASIS,             
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      
#  See the License for the specific language governing permissions and           
#  limitations under the License.                                                

APXS = /usr/sbin/apxs                                                            
PYTHON = /usr/local/bin/python                                                   

DESTDIR =                                                                        
LIBEXECDIR = /usr/libexec/apache2                                                

CPPFLAGS =  -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apr-1 -I/Applications/Xcode. app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apache2 -I/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/include/python2.7 -DNDEBUG
CFLAGS =   -Wc,'-arch x86_64'                                                             
LDFLAGS =  -Wl,-F/usr/local/Cellar/python/2.7.5/Frameworks -framework Python -u _PyMac_Error   -arch x86_64
LDLIBS =  -ldl  -framework CoreFoundation                                        

all : mod_wsgi.la                                                                

mod_wsgi.la : mod_wsgi.c                                                         
    $(APXS) -c $(CPPFLAGS) $(CFLAGS) mod_wsgi.c $(LDFLAGS) $(LDLIBS)             

$(DESTDIR)$(LIBEXECDIR) :                                                        
    mkdir -p $@                                                                  

install : all $(DESTDIR)$(LIBEXECDIR)                                            
    $(APXS) -i -S LIBEXECDIR=$(DESTDIR)$(LIBEXECDIR) -n 'mod_wsgi' mod_wsgi.la 

clean :                                                                          
    -rm -rf .libs                                                                
    -rm -f mod_wsgi.o mod_wsgi.la mod_wsgi.lo mod_wsgi.slo mod_wsgi.loT          
    -rm -f config.log config.status                                              
    -rm -rf autom4te.cache                                                       

distclean : clean                                                                
    -rm -f Makefile Makefile.in                                                  

realclean : distclean                                                            
    -rm -f configure

Then make && install:

mod_wsgi-3.4$ make
mod_wsgi-3.4$ sudo make install

Modify /etc/apache2/httpd.conf to enable mod_wsgi:

LoadModule wsgi_module libexec/apache2/mod_wsgi.so

mod_xsendfile

Use the following command to compile and install mod_xsendfile:

sudo apxs -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apr-1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/apache2 -cia mod_xsendfile.c

Enabling HTTPS/SSL

After upgrading OS X the apache configuration was reset, but your original config is save to /etc/apache2/httpd.conf.pre-update. I need to enable SSL in httpd.conf again by uncommenting the following line:

# Include /private/etc/apache2/extra/httpd-ssl.conf

Restart Apache and everything should work fine

sudo apachectl restart
3 Comments

Solution: dd too slow on Mac OS X

When I was cloning SD cards on Mac OS X using `dd’, it takes ages to get things done. I was using the following command:

diskutil unmountDisk /dev/disk2
sudo dd bs=1m if=~/Downloads/2013-10-09.alice.img of=/dev/disk2

It takes much less time when using /dev/rdisk2 instead of /dev/disk2:

diskutil unmountDisk /dev/disk2
sudo dd bs=1m if=~/Downloads/2013-10-09.alice.img of=/dev/rdisk2

The reason is that rdisks are “raw” thus resulting in a higher R/W speed, according to `man hdiutil` [1]:

/dev/rdisk nodes are character-special devices, but are “raw” in the BSD sense and force block-aligned I/O. They are closer to the physical disk than the buffer cache. /dev/disk nodes, on the other hand, are buffered block-special devices and are used primarily by the kernel’s filesystem code.

[1] http://superuser.com/questions/631592/mac-osx-why-is-dev-rdisk-20-times-faster-than-dev-disk

58 Comments

The power of thinking without thinking

Blink: the power of thinking without thinking is another book by Malcolm Gladwell, the author of Outliers: the story of success I just read a few days ago. He is a good writer: he knows how to explains theories with examples and stories that creates resonance to audience. And he knows how to write bestsellers: books should be easy to follow and not too lengthy. This book Blink is a fine example: it’s a less-than-300-page small book.

Compared with Subliminal, this book does not contain too much diving into how human brains work. Instead, it’s all about plain but intriguing stories. It starts by talking about spotting a bogus statue at first sight; then it discusses about how to predict divorces by analyzing how couples talk to each other; then it comes to why we fall for people’s appearances, how newbie police fails to read people’s minds, etc.

This book brings up a theory called “thin-slicing”: getting the big picture without actually going through the whole picture, but through taking a small part of descriptive samples and inferring the correct result using these samples. Thin-slicing is an ability that only through years of practice can it be possessed. It is a state that spontaneous and correct judgement occurs to you even though your consciousness has yet participated in the process. This ability becomes an integrated part of yourself, just like the instinct to avoid coming cars. It doesn’t necessarily deal with reasoning: your success of getting the correct answer does not guarantee that you know exactly why. If you are forced to give reasons, you may not come up with correct ones and they may hazard your first-sight judgement. To reason means to use your conscious mind; but thin-slicing is from deeper than the consciousness — it comes from the unconsciousness of your brain.

However, thin-slicing may not always give us correct results. We usually trust those who are good looking, while this sometimes leads to unpleasant endings, such as choosing the handsome Warren Harding as the president of the US and who make the worst president in US history; Most white people and including some black people, think under their consciousness that the white is a superior; Many treat women as inferior. These are the unconsciousness that we need to prevent, otherwise we are not able to focus on the aspects that really matters.

In summary, use the unconsciousness, but use it properly. Train the mind, so that the pattern recognition engine in our brains gets recognizing what is important and what is not, so that in a blink of time, we can make the best decision without thinking (using our conscious mind).

3 Comments

A “normal” sed on Mac

The `sed` program on Mac is not a standard (GNU) one. To get the normal one, use brew:

brew install gnu-sed

After this, alter PATH. For example, add the following line to your `~/.bash_profile`:

PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"

And now you have a normal sed!

 

2 Comments

What sets outliers apart

There is a famous quote from Einstein that goes “genius is 1% talent and 99% hard work”, and the book Outliers: the story of success proves it correct. As many knows that Einstein has an IQ of around 150, however, IQ is not the definite factor towards success, but rather, IQ is not important at all once it reaches a threshold — as long as you have an adequate intelligence, it’s other aspects that really matters. Those aspects include hard work, social savvy, upbringing and the culture one comes from.

This book tells a story of a man named Chris Langan with an IQ of 195, but he ended as as a bouncer at a bar for the most of his life. He is smart, so smart that he understands Principia Mathematica at the age of 16. But he never knows how to deal with people. He lost his scholarship because his mother forgot to fill a form for him and after he confronted his dean he concluded that the professors do not care about the students. And so he quitted. By contrast, the father of atomic bombs, Oppenheimer is not as smart, but he processes a great practical knowledge. He knows how to get away with punishment after trying to poison his tutor at  Cambridge. He also persuaded General Groves to let him participate in the Manhattan Project, despite his poisoning record and affiliations with Communists. It’s obvious that both Langan and Oppenheimer are smart, but in a way they could not be more different in aspects other than intelligence.

The author also elaborates how important diligence is. It’s known that for one to become good at something, he/she has to spend at least 10,000 hours on it. Bill Gates had more than 10,000 hours of experience with computers before he dropped out; the Beatles had more than 10,000 hours of practice before they made a real hit; the same with Steve Jobs, Bill Joy (cofounder of Sun Microsystems), Eric Schemidt, etc. As the book puts it, “no one who can rise before dawn 360 days a year fails to make his family rich”.

However, as important as diligence is, it’s equivalently important to have the ability of seizing opportunities. The computer gurus are typically born in mid 1950s (Bill Gates 1955, Paul Allen 1953, Steve Ballmer 1956, Steve Jobs 1955, Eric Schemidt 1955, Bill Joy 1954);If you look at Chinese Internet gurus, same intersting facts: year in which the founder is born: Baidu 1968, Alibaba 1964, Tecent 1971, Netease 1971, Sina 1969, Sohu 1964, why? Because they all had their 10,000 hours of practice when the personal computer revolution began in 1975 (or internet starts to become popular in China in mid 1990s). It did not happen only in computer industry, but also in other industries such as law, manufacturing, and so on.

The culture you are from and the upbringing shape your thinking and behaviours and in the end how successful you are. It takes three generations for Jews to transform from tailors and garment industry workers to doctors and lawyers. Success is not magic; it’s the hard work passed along generations to generations. Asians are better at mathematics because our ancestors have to calculate carefully when growing rice; and asians are more diligent because our ancestors have to put the hours in hard work so as to survive.

Next time when someone asks how could Chinese economy grow so fast, show him how Chinese work.

Leave a Comment

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

乌合之众

所谓经典,经久不衰之宝典也。这本来自1895年的法国的书,在100多年之后读起来仍然让人觉得津津有味。作者对社会的剖析入木三分,深刻揭示了社会群体的特性。

群体顾名思义,由一群个体组成。而这群个体走到一起形成一个群体之后,其中的每个个体的特性便不再重要,作为群体中的一员,这个个体可能会完全迷失在群体中间。群体抹去每个个体心智的的差距,使他们的行为趋向一致;每个个体不断相互影响和暗示,相互传染极端思想,使这个群体做出任何单个个体都不会做出的出格事情。书中有个很形象的故事:在一个马戏团里,一匹马将粪便拉在了一位坐着观看表演的女士的腿上。而周围的一群绅士却丝毫没有绅士的表现,一齐大笑起来。试想,如果只有一个绅士在场,会发生这样的情况吗?

群体是不使用理性,不用逻辑思考问题的。在群体之中一个个体的智力会泯灭,群体只能接受感性的,形象的思维。作者认为群体中个人智力的泯灭存在着四个阶段:自我意识模糊,独立思考能力下降,判断力和逻辑在暗示与传染的作用下趋同一致,最后残存的智力被测底反噬。历史上很多不可思议的事件中都能找到这种情形:不管平时多么聪明,在群体中却完全迷失了自我。比如高级知识分子失去独立思考的能力,去做一些违背原则的事情(想想我国几十年前发生的事情)。群体只接受简单的概念和形象,不接受正常逻辑。群体迷恋偶像,创造偶像,并沉浸其中不可自拔。

一个群体需要有领袖,这个领袖往往是这个群体里最极端的个体。只有极端的人才能成为领袖,因为极端的个体可以更好的感染群体,而群体的奴性成就一个领袖,个体成为领袖之后又使得群体和领袖变得更为极端。为了释放这些极端的情绪,这个群体便以残暴可怖的手段去处理异见持有者。

文末作者以悲观的情绪分析了人类历史发展的规律:个体走到一起,团结起来抵御外部入侵;摆脱野蛮,发展个体,形成文明;文明强盛,逐渐复杂,止步不前;走向衰落;群体分崩离析;回归原始。“人们在追求理想的过程中,从野蛮状态发展到文明状态,然后,当这个理想失去优点时,便走向衰落和死亡,这就是一个民族的生命循环过程。”

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

全世界人民都知道

读了这本书,发现李承鹏的杂文水平确实不怎么样,杂文能记成流水账也算是一种境界。文字无端卖弄,莫名其妙的拼凑同音词显得无比做作。在我的印象中杂文应该针砭时弊,把人骂的狗血淋头,把事说得无比通透,把政府批得体无完肤才是。可这本书给人的感觉是完全没有高潮,读罢全文像是听隔壁村大婶絮叨了半天一般,那种想听人骂街而不得的挫败感让人生闷气。

读到书末几篇散文倒是有点感觉,不过大哥,下次能不能一件事情说完就行了,别絮絮叨叨的说上个三五遍好不好?

Leave a Comment