一个python的组合题目

帮同学做了道题,附上自己的解答。

他的题目是:

有a,b两序列,大小相同,序列中元素均为正整数,无序。

要求实现:通过交换a,b中的元素,使得 [序列a所有元素的和] 与 [序列b所有元素的和] 之间的差值最小。

这是一个组合问题,我们需要从一个列表里取出一半的元素,然后让这些元素的和最接近原始和的一半。

对于排列组合,python提供了高效迭代器,位于itertools模块。 可以直接暴力枚举。

#coding:utf-8
import itertools

def swap_item(a, b):
    lst = a + b    # 合并两个列表
    min_diff = sum(lst)
    half_sum = min_diff / 2    # 原始和的一半

    for item in itertools.permutations(lst, len(lst)/2):
        diff = abs(half_sum - sum(item))
        if diff < min_diff:
            min_diff = diff
            result = list(item)
            if diff == 0: break    # 如果正好是原始和的一半,即最佳方案
    in_lst = []
    out_lst = []
    for item in set(a + result):
        a_num = a.count(item)
        result_num = result.count(item)
        if a_num < result_num:    # 列表A添加该元素
            in_lst.append(item * (result_num - a_num))
        elif a_num > result_num:    # 列表A移除该元素
            out_lst.append(item * (a_num - result_num))
            
    print 'A ----->'.ljust(10), '<----- B'.rjust(9)
    for x,y in zip(out_lst, in_lst):
        print str(x).ljust(10), str(y).rjust(9)
    print '\nFinal result is', result

a = [19, 90, 1, 2, 3, 52, 11]
b = [6, 66, 21, 45, 32, 17, 43]
swap_item(a, b)

输出结果:
swap-list-items

Android客户端HTTP抓包分析的一般步骤

抓包分析Andorid APP可以做许多事情,跟PC上的应用相比,移动应用一般逻辑简单安全性不高。比如说,某些APP上的摇0元商品、刷抽奖、刷红包,都是非常容易编码实现的。

一种不好的思路,可以是自己安装Android SDK,创建虚拟设备来抓包。

另一种不理想的思路,还可以是通过在PC创建共享WIFI,然后在PC上抓包。

总之,相同点是,抓包在PC上进行,而不是直接在手机上。

本文余下部分介绍利用fiddler代理抓包,以及在chrome上修改User-Agent、模拟触屏事件(淘宝刮刮卡?)等。

要求: 手机必须能够访问PC,最好能连接到同一个无线路由器。

1. 安装fiddler

首先是下载安装fiddler:  http://fiddler2.com/get-fiddler

运行fiddler,修改设置:  Tools => Fiddler Options,在 HTTPS选项卡中,勾选Capture和Decrypt  HTTPS。如下图:

fiddler-https

在Connections选项卡中,可以看到fiddler的代理端口为8888,勾选上允许远程访问,如下图:

fiddler-proxy

2. 关闭windows防火墙

在控制面板中,临时关闭windows防火墙。允许连接入代理。

3.  在手机上设置代理

在PC上通过ipconfig获取IP地址。

我的IP地址是192.168.1.4。 那么,在手机上需要将代理设置为192.168.1.4: 8888,如下图:

wifi-proxy-settings

完成以上设置,打开某个APP,fiddler就可以抓到HTTP traffic了。

4. Chrome修改User-Agent和模拟触屏事件

某些页面检测到User-Agent不是指定值,会自动转到APP下载页面。 比如淘宝双12的刮刮卡页面:

http://h5.m.taobao.com/1212/scratchcard/home.html

根据抓包信息,修改User-Agent为: null WindVane/2.6.0 TBANDROID/600000@taobao_android_3.9.5

方法是在Chrome浏览器Ctrl + Shift + J打开控制台,点击右下角的齿轮进行设置。

在settings =>  override选项卡中,勾选Enable,修改User-Agent。

勾选Emulate touch events,模拟触屏事件。

chrome-useragent

西工大的猫 v1.3

“西工大的猫” 是在xiaoxia的 sogou代理脚本 基础上加了个壳子,

方便用户一键设置浏览器HTTP代理, 现在每天有几千人使用。

教育网的同学可以用它来免费上网、浏览器提速,国外的同学可以用它浏览内地视频网站等。

 

昨天用python、Tkinter、winIco简单实现了这个工具,

ballon tip是自己用Toplevel实现的,3.5秒内会自动淡出直至消失。  popup menu和ballon的位置只是粗略计算,最终显示效果不是特别理想。

 

源代码      Windows可执行文件

为什么我不关心比特币

前几天,朋友反复跟我提比特币(bitcioin),还想让我研究一下比特币的算法,希望可以搞出自己的虚拟货币。下面是我给他的Email:

昨儿有点忙,也不好给{{人名}}详说。
比特币、莱特币之类的东西,我是不感兴趣的。
它们身上赌博的味道太重,我自己非常不喜欢这一点。
赌博和冒险并不一样。

要论我们”曾经错过”的赚钱机会,真是一大把一大把的。
我一点不眼红别人赚了钱,更不会觉得自己损失了什么。”错过”是必然的,抓住了才是偶然。

对这个东西不感兴趣,有几点:

1) 美元是真正的世界货币,其实通过paypal、用信用卡付款,在任何一个国家支付美元、全球购物都是非常方便的。 只要比特币没有跟美元直接挂钩,形成官方汇率,形成良性监督,这个东西风险都非常高。比如法律风险、比特币自身的安全漏洞。

2) 比特币被用来做非法地下交易、洗钱,这一点你应该是了解的。

3) 考虑一下比特币有没有实际改善人们的生活。 大家投入很多人力、物力、财力,买挖矿机、买服务器、写程序。 没有衣服穿、没有饭吃,不行。但没有比特币,普通老百姓的生活没有多大影响。

4) 炒得太厉害。当大家都觉得这里机会多的时候,可能它就不怎么适合我们去做了。 比特币主要分布在哪些人手上,他们手上有多少? 大多数人进去之后,可能只是个垫背的,最后死得很惨。

5) 搞自己的虚拟货币,想创造什么价值,解决什么实际问题。 人民币不能买东西吗? 用信用卡不能在国外买东西了吗?

6) 最好在自己的领域沉下心来,做自己懂的东西。 不懂的东西,风险太高太高。 就拿邓亚萍来做即刻搜索来说,烧完20亿,做出牛逼的产品了吗?

如果后面的事实发展证明我是错的,那还是遵循上面的话,别人赚了多少钱,我不关心。
我关心的是,自己想做什么、自己能做什么、自己能做好什么。

在VPS上给自己的人人网账号刷”人品”

人人网新出了一个增加用户粘性的类似积分制度,叫”人品”。

每半个小时刷新一下人人网,就可以得到1RP,而得到的RP,可以兑换一些小礼品。

这类似于挂机, 如果你已经有VPS,写一段python脚本跑起来就可以全天刷了。

#encoding:utf-8
import httplib
import time
import datetime

headers = {
    'Cookie': '你的Cookie',
    'Referer': '自行修改Referer',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \
    Chrome/31.0.1650.48 Safari/537.36'
}

while True:
    conn = httplib.HTTPConnection('www.renren.com')
    conn.request(method='GET', url='/你的人人网ID', headers=headers)
    html_doc = conn.getresponse().read().decode('utf-8')
    
    with open('renpin.log', 'a') as outFile:
        if html_doc.find(u'class="logout">退出') > 0:
            outFile.write('OK ' + str(datetime.datetime.now()) + '\n' )
        else:
            outFile.write('Fail ' +  str(datetime.datetime.now()) + '\n' )
    conn.close()
    time.sleep(600)

获取人人网的cookie,可以直接在Chrome浏览器Ctrl + Shift + J打开控制台,刷新当前页面,在Network选项卡查看对应的URL条目即可。

把这段代码保存到renpin.py,放到VPS上某个文件夹,然后执行

python renpin.py &

就可以全天24小时,每隔10分钟自动刷新人人了。 程序还会在当前路径下写入日志到renpin.log。

Python使用winIco编写一个托盘图标不停闪烁的小程序

昨天测试了使用Tkinter来编写简单的托盘程序,总体说来是非常方便的,代码在Windows和Linux下都能很好地工作。

Windows下,Tkinter可以使用封装好的winIco API: tktable/winico
下载最新的0.6即可。 (05年发布,有人提到64位系统下无法正常工作,我没有测试)
另外,还可以参考这个TCL项目: http://cran.r-project.org/web/packages/tcltk2/

里面有个package ico1.0,是在winIco的基础上修改的,但是它的接口已经改变,如果你对TCL脚本熟悉,建议使用。

1. 解压dll到tcl文件夹

下载winIco0.6之后,直接解压到tcl文件夹下,类似: D:\Python27\tcl\winico0.6。
测试python下是否可用:

>>> from Tkinter import Tk
>>> root = Tk()
>>> root.tk.call('package', 'require', 'Winico')
'0.6'

2. 合成不同的图标到一个ico文件

程序在托盘不停闪烁图标,利用了在一个ico文件中,可以集成多个不同大小、颜色的图标资源。
我使用了Greenfish Icon Editor Pro来合并图标文件:
join-icons
第一个图标对应的是#0,第二个图标对应的是#1。还可以继续添加其他需要使用到的图标。

3. python调用winIco

winIco提供的接口非常简单:https://www.lijiejie.com/python/winico/winico.html

  1. 使用createfrom可以直接从ico文件创建图标资源。
  2. load命令可以从exe或dll中加载图标资源
  3. info命令则是获取某个句柄对应的若干图标资源的信息:  包括编号、大小、颜色深度
  4. taskbar命令用于添加、修改、删除托盘图标,重要的参数包括了-callback(回调函数)、-pos(图标资源序列号)、-text(托盘图标的提示文本),在回调函数中,可以通过%m参数来传递窗口消息。

在添加托盘图标时,可以用-callback参数指定回调函数,比如右键点击弹出菜单。

我写了一个简单的示例程序:
flash-trayicon-sample
这个地球图标会不停闪烁(0.5秒切换一次),右键单击,可弹出一个菜单。 源代码在这里