分类:'原创精选' 的所有文章

邮局,快递,还有修车的

最近有些感触,讲两个故事。

故事一:邮局和快递

如果你在网上下了一个订单,这个订单对你比较重要,你会用邮局吗?

邮局绝对不是我的首选。

有段时间,邮局是这样工作的:货物发出以后,直到货物到达你手上,中途不会有任何消息,直到有一天货物到了,让你去签收。或者某一天你突然发现东西怎么还~~~没到,打电话过去查询,告诉你,没事,还在路上;有时候你会变得神经质,怀疑电话号码写错了,怀疑邮编写错了,怀疑地址写错了,怀疑收件人写错了;几个电话以后,你很沮丧,什么都没错,但是就是没到,到哪儿了?什么时候到?我也不知道,等吧。

虽然最后可能邮包到了,你对邮局开始有看法了。
然后是第二次。
然后是第三次第四次第n次。。。
然后你就对对邮局彻底失去信心了。

快递呢?
货物发出以后,给你发个邮件,告诉你收件人发件人联系信息等等等等,还有个链接,可以查结果

然后你就可以看到不断的结果更新:
到xx集散地了,
到xx机场了,
到北京了,
到回龙观了,
到某某分发处了,
到某个快递员了。。。

直到到达你的手中,你都会很踏实。

————————————————————-

好吧,这个故事很平淡,好像没啥意思。但是工作中,“邮局”的事情每天都在发生。

某天,工头老张给员工小李安排了一个工作,小李说,好,我去做。

从此杳无音信。
一个星期过去了。
没有email,没有电话。
连小李是不是还在干这个都不知道。
这时候老张怎么想?

如果你是小李,你该怎么做?你是邮局还是快递?

——————————————————————————————–

故事二:修车的故事

有天周末,下午两点,你去修车,打算修完以后晚上拉着女朋友去看演唱会。

先把车开到“卜靠谱汽车专修”,说,车有点儿问题,能给修修吗?

店老板说,好。然后他拿出了钳子扳手千斤顶,开始拆卸了。

这时候你会怎么想?

!!他到底知不知道我要干嘛~~~~!!

你实在憋不住了,问他,你知道哪儿坏了吗?

他说,哦,对不起,我忘了问了,哪儿坏了?

你压着火,跟他说:车开着开着就没气了,开着还总回跑偏。。。blablabla,总算搞清楚问题

然后店老板再次上阵,千斤顶、钳子、扳手。

你等了半小时,总算明白过来,他是要给你换轮胎,而且还要换后车轴,估计要5个小时才能搞定了,一堆的¥¥¥在眼前飘过

这时候你又会怎么想?

天哪,你为什么不早说!!!
能不能不换轮胎?!
能不能不换后车轴?!

你提出问题来了,老板说,可以,补胎,后车轴其实调调也能用,换了更好。

是不是很崩溃呢?下次你想修车,还会不会再光顾呢?

然后这天你知道了一家“薪胖子放心店”,听说不错。

开去修车。

老板问清楚了状况,说需要几分钟检查一下。
十分钟以后,查清楚了原因。
然后给你两种解决方案,一种临时的一种长久的,价位都给出来了。推荐一个长久的(更换轮胎啊,¥¥¥)。
问你看怎么办?
你犹豫了一下,说先来临时的吧,晚上还要用呢。
那需要半小时。
没问题,我先切会儿水果。
店老板嘁哩喀喳,搞定收工。
然后你从fruit ninjia回落到现实世界,交钱开车走人。

多么和谐啊。

好了,现在你被分配了一个任务,你打算怎么办?卜靠谱还是薪胖子?

  • Share/Bookmark

Python HTTP - Post a Binary File using urllib2

I was trying to post a png file to our internal webserver for some quick and dirty task, but Python keep throwing ascii encoding exception.

Then I search “post http binary urllib2″ and did found several options, like multipart/form-data and pycurl, but they need the webserver’s help to accomplish a simple file posting.

In the end I decide to dig into Python’s httplib and urllib2 to find out what’s going on, if that doesn’t work I will fallback to raw TCP socket solution.

Luckily I got the following solution that works like a charm:
1. set Content-Length header(of the file) before doing post
2. pass a opened file when doing post

Sample code:

Python语言: Python Post a Binary File using urllib2
import urllib2, os

image_path = "png\\01.png"
url = 'http://xx.oo.com/webserviceapi/postfile/'
length = os.path.getsize(image_path)
png_data = open(image_path, "rb")
request = urllib2.Request(url, data=png_data)
request.add_header('Cache-Control', 'no-cache')
request.add_header('Content-Length', '%d' % length)
request.add_header('Content-Type', 'image/png')
res = urllib2.urlopen(request).read().strip()
return res

  • Share/Bookmark

Python urllib2的使用点滴: cookie, https, put, 500/403的处理

Update @ 2011-03-06, 13:46:08
刚刚发现了一个比urllib2更好用的库httplib2,可以比较简单的解决本文遇到的一些问题
http://code.google.com/p/httplib2/

————————————————————

最近用urllib2写了一个公司内部用的脚本

这个脚本要访问一个webservice,访问之前先要用https登陆拿到cookie再到另一个地方获取一个临时用的id

https登陆,获取cookie

首先是https登陆,这段很好写,以前写过校内网发帖机,轻车熟路,用cookielib的CookieJar加上HTTPCookieProcessor搞定,代码如下(其中那个超简单的lambda hack简直绝了:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
        ('password', '密码'),
        ('action', 'login'),)

print 'login to get cookies'
opener.open(url_login, urllib.urlencode(body))

处理HTTP 403/500 Exception

但是后面用cookie去拿id的时候,就老是告诉我403错误,然后opener就抛异常,想问题想到头大,后来发现这个服务访问成功不是返回200,而是403,所以看到403的时候不要管他,直接看body内容就行了,日,不知道为什么这么设计。

怎么办呢?查了一下urllib2的文档,发现可以继承一下HTTPCookieProcessor,自己做了一个NoExceptionCookieProcesser,后来的过程中发现webservice有时候返回400和500的时候body中包含有用的信息,一并处理了:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import urllib, urllib2, sys, cookielib, re, os, json
#suppress the 403/400/500 exception and return the body
class NoExceptionCookieProcesser(urllib2.HTTPCookieProcessor):
  def http_error_403(self, req, fp, code, msg, hdrs):
    return fp
  def http_error_400(self, req, fp, code, msg, hdrs):
    return fp
  def http_error_500(self, req, fp, code, msg, hdrs):
    return fp
 
cj = cookielib.CookieJar()
opener = urllib2.build_opener(NoExceptionCookieProcesser(cj))
url_login = 'https://xxx.yahoo.com/login/'
body = (('username', '半瓶墨水'),
        ('password', '密码'),
        ('action', 'login'),)

print 'login to get cookies'
opener.open(url_login, urllib.urlencode(body))

urllib2中用PUT进行请求

然后又发现一个问题,webservice在提交的时候要求用PUT方式,并且只接受json,urllib2默认只支持GET和POST,Google了一下,发现可以创建Request对象,然后更改它的请求方法(get_method)以及header,搞定:

request = urllib2.Request(url_ws, data="blablabla")
request.add_header('Content-Type', 'application/json')
request.add_header('Accept', 'application/json')
request.get_method = lambda: 'PUT'
result = opener.open(request).read().strip()

参考:http://stackoverflow.com/questions/111945/is-there-any-way-to-do-http-put-in-python

  • Share/Bookmark

把Picasa加星标的图片一次性导出

年前买了个千万级的照相机,再加上不加节制的使用,200G的硬盘开始不够用了,为了节省空间,决定把多数照片放在一个不是很常用的地方+刻盘,只把选择出来的照片留下

为了达到这个目标,现在安装的Faststone Image Viewer就不是很好用,安装的光影看看更是管理图片的废材。最后Google了一下,发现最好用的还是Picasa

下载了最新版,又花了过年的三四天的精选了照片,最后想把照片导出的时候遇到问题了,一共四五十个文件夹,Picasa并没有提供一次性导出的功能,只能一个文件夹一个文件夹的导出。最后还是决定写个脚本来搞定,研究了一下,发现每个目录下都有个.picasa.ini文件,格式十分简单,比如这个:

[IMG_0152.JPG]
faces=rect64(78f63255a1427ae3),155499df12e3d390
backuphash=4191
star=yes

其中的star=yes代表该照片已加星标。这就简单了,半小时写,十分钟导出,搞定!

脚本如下,注意脚本运行完以后生成了一个叫做copystar_go.bat的批处理文件,执行它才是真正的导出,这本来是调试用的,后来发现可以手工控制删掉一些不需要的导出操作(用Vim很快的),就没改回来,不多说,上代码:

Python语言: Export all stared photos in Picasa once
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
#Purpose: export all picasa stared photos under a folder and it's subfolders
#         because Picasa doesn't support - it only can export one folder once
#
#  Reach me via: realfun AT gmail DOT com
#
#  http://2maomao.com/blog/py-script-export-all-stared-photos-in-picasa/
#  http://www.google.com/profiles/realfun
#  2011-02-22, 22:26:28

from os import walk
from os.path import join

#damn python encoding hack
import sys
reload(sys)
sys.setdefaultencoding("gb2312")

PICASA = '.picasa.ini'
PICASA_OLD = 'Picasa.ini'
TARGET = 'G:\\ipad\\sync\\temp\\'

def get_stars(dir, picasa):
    stars = []
    last = None
    for line in open(join(dir, picasa)).readlines():
        line = line.rstrip("\n")
        if line.startswith("[") and line.endswith("]"):
            last = line[1:-1].decode("utf-8")
        elif line.startswith("star=yes"):
            stars.append(last)
    return stars

out = open("copystar_go.bat", "wb")
for root, dirs, files in walk("."):
    picasa = None
    if PICASA in files:
        picasa = PICASA
    elif PICASA_OLD in files:
        picasa = PICASA_OLD
    if picasa:
        stars = get_stars(root, picasa)
        for star in stars:
            line = 'robocopy "%s" "%s" "%s"\r' % (root, join(TARGET, root), star)
            print >>out, line

  • Share/Bookmark

关于25马问题的思考

题酷发芽网上的一个题目 “25匹赛马血拼Top5”:

有25匹马,共5个跑道,不用任何工具,请问

  1. 用几场比赛可分出前3名?
  2. 几场比赛可以分出前5名?
  3. 几场比赛可以给所有赛马排名?

Solrex Yang同学写了一篇文章比较全面的分析了这个问题,虽然后面有人指出其推理过程中的问题,但是可以看出主要的思想还是正确的,那就是尽量利用已经存在的信息。

今天无意间翻信翻到这个问题,突然想到,这其实是个可以编程求解的问题,而且跟我已经搞定的猜数字游戏求解过程很像

几点零星的想法,等到有时间再来细化:

1. 几次赛马以后,实际上生成了一个逻辑排序的图,每一次赛马,都要尽可能的把这个图变成一条**线**
2. 贪心的标准可以是:消除尽量多的分支
3. 每一步采用贪心算法,不一定能做到全盘最优 - 我求解猜数字游戏的时候就遇到过,贪心总是会有3、4个需要8步的,而全局最优却可以做到都在7步以内
4. 如果只是前三名,或许贪心算法得到的结果跟全局最优是一致的
5. 全局最优的算法,粗略一想,需要25!的计算量。要尽量减少计算的话,就要考虑做一些cache,滤掉重复性的计算,或许需要用到动态规划
6. 如果只是要求前三名,全盘最优应该很容易做到

先写这么多,等有时间再来写程序验证。。。

  • Share/Bookmark

下一页 »