“你画我猜”(draw something)单词猜测工具 – 升级版

前几天写的“你画我猜”(draw something)单词猜测工具,最后提到了有道已经做了相关工具。既然有大树了,俺们就可以直接乘凉了~

使用有道网页版的改进版本来了:直接发送查询请求然后对返回结果格式化就搞定了,非常easy:)(需要用到lxml模块)

 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina Weibo @SeganW
"""
from __future__ import unicode_literals
import urllib
import lxml.html as lh
import sys

def query(char_str,num=None):
    if not None:
        num=len(char_str)
    con=None
    resp=None
    try:
        con=urllib.urlopen('http://dict.youdao.com/drawsth?letters={}&length={}'.format(char_str,num))
        resp=con.read()
    except Exception as e:
        if con:
            con.close()
        raise SystemExit('[error] guess request failed: {}'.format(e))
    doc=lh.document_fromstring(resp)
    words=[i.text_content().lower() for i in doc.xpath("//span[@class='word']")]
    translates=[i.text_content() for i in doc.xpath("//div[@class='trans']")]
    return zip(words,translates)

if __name__ == '__main__':
    args=sys.argv
    if len(args)==2:
        charstr= args[1]
        num=None
    elif len(args)==3:
        charstr= args[1]
        num=int(args[2])
    else:
        raise SystemExit('usage: drawsomthing.py charstr [num]')
    results=query(charstr,num)
    if results:
        for sub_result in results:
            print '{}:\t{}'.format(*sub_result)
    else:
        print "No results found:("

使用方法不变:

运行的命令行就是

drawsomething_updated.py char_str [num]

char_str为程序显示的乱序字符串,把让你拆的所有字符串起来做一个字符串
num是程序让你猜的单词包含的字符个数;可不填,这样就变成python版词典了:)

选择最快的appstore ip地址之Python版

今天才用上正统的Appstore软件下载方法:从iTunes端下载,然后PC端与iOS设备同步。然后俺就发现,下载速度那个慢啊。。。
从网上得到如下消息:

苹果为 App Store 准备了 a1.phobos.apple.com 到 a2000.phobos.apple.com 这么一群服务器,美国、欧洲、日韩、港澳……就是没有中国。。。

不管真假,让咱们用Python挨个ping出哪个地址最快,然后加到hosts里面吧:)
以下代码为Windows中文版,如果其它版,请把speed_ptn行的字符串改成对应的:

Nov/4/2014更新:
multiprocessing.dummy处理I/O负荷的并发,multiprocessing处理CPU负荷的并发。多少个url都无所谓啦~
注意:只写了Mac OS X版本的

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
Only works in Mac OS X, I tested in Yosemite
"""
from __future__ import unicode_literals
from subprocess import check_output, CalledProcessError
from re import compile as re_compile
from sys import getfilesystemencoding
from os import devnull
from multiprocessing.dummy import Pool 

URLS = ['a{}.phobos.apple.com'.format(i) for i in range(1,2001)]
IP_PTN = re_compile('\d+\.\d+\.\d+\.\d+')
AVG_PTN = re_compile('min/avg/max/stddev = \d+\.\d+/(\d+\.\d+)/')

def ping_test(url):
    try:
        with open(devnull, 'w') as null:
            output = check_output(['ping','-c','3', url], stderr=null).decode(getfilesystemencoding())
            ip = IP_PTN.search(output).group()
            avg = float(AVG_PTN.search(output).group(1))
    except CalledProcessError:
        ip = ""
        avg = ""
    print 'Server {}\t||\t Average Speed: {}ms'.format(url,avg)
    return {ip: avg}

if __name__ == '__main__':
    pool = Pool(25) #25 is process count, try increase or decrease it to find the best performance
    results = pool.map(ping_test, URLS)
    pool.close()
    pool.join()
    best = min(results,key=lambda x: x.values()[0])
    best_svr = results.index(best)
    print '***** Best server is a{}.phobos.apple.com, ip={}, avg speed={}ms *****'.format(best_svr, best.keys()[0],best.values()[0])

Aug/20/2012更新:写了使用多线程并加入了对timeout情况的处理,发现虽然速度快了,但是结果却是每次都是最大那个数的服务器ping值最快。不知道为啥。另外并发数不能太大,URLS里面直接用2000会提示打开文件太多。改成500没发现问题。

新版代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
"""
from __future__ import unicode_literals
import subprocess
import re
import sys
import threading

URLS=map(lambda x: 'a{}.phobos.apple.com'.format(x), range(1,501))
NUM=0
BEST=[2**16,'',''] # a big number normally larger than average
IP_PTN=re.compile('\[(.*)\]')
SPEED_PTN=re.compile('平均 = (\d+)ms')

class Ping(threading.Thread):
    def __init__(self, url, lock):
        threading.Thread.__init__(self)
        self.url=url
        self.lock=lock

    def run(self):
        try:
            output=subprocess.check_output(['ping',self.url]).decode(sys.getfilesystemencoding())
        except subprocess.CalledProcessError as cpe:
            print cpe.output
            output=cpe.output.decode(sys.getfilesystemencoding())
            avg='timed out'
        else:
            avg="{}ms".format((SPEED_PTN.search(output).group(1)))
        ip= IP_PTN.search(output).group(1)
        self.lock.acquire()
        print 'Server {}\t||\t Average Speed: {}'.format(self.url,avg)
        if avg =='timed out':
            pass
        elif BEST[0] > int(avg[:-2]):
            BEST[0] = int(avg[:-2])
            BEST[1] = ip
            BEST[2] = url
        global NUM
        NUM+=1
        if NUM==len(URLS):
            print 'Fastest server: {2} ( {1} ) fastest average speed: {0}ms'.format(*BEST)
        self.lock.release()

if __name__ == '__main__':
    lock=threading.Lock()
    try:
        for url in URLS:
            ping_thread=Ping(url,lock)
            ping_thread.start()
    except KeyboardInterrupt:
        pass

原版:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
"""
from __future__ import unicode_literals
import subprocess
import re
import sys

urls=map(lambda x: 'a{}.phobos.apple.com'.format(x), range(1,2001))
best=[2**16,'',''] # a big number normally larger than average
ip_ptn=re.compile(r'\[(.*)\]')
speed_ptn=re.compile(r'平均 = (\d+)ms')
try:
    for url in urls:
        output=subprocess.check_output('ping {}'.format(url),shell=True).decode(sys.getfilesystemencoding())
        output=[i for i in output.split('\r\n') if i]
        ip= ip_ptn.search(output[0]).group(1)
        avg=int(speed_ptn.search(output[-1]).group(1))
        print 'Server {}\t||\t Average Speed: {}ms'.format(url,avg)
        if best[0] > avg:
            best[0] = avg
            best[1] = ip
            best[2] = url
except KeyboardInterrupt:
    print '\n'
print 'Fastest ip address:\n{1} {2}\nfastest speed: {0}ms'.format(*best)

找到最快的以后就可以改hosts文件了,这个不懂的自己google吧。

OpenCV 2.3.1 Python Bindings installation on Windows 7

Today I searched several post about how to install OpenCV Python bindings on Windows 7. And I found many of them made it too complicated.

Here is my simple solution. Many thanks to Christoph Gohlke, Laboratory for Fluorescence Dynamics, University of California, Irvine, his work makes many Python modules be easy to be installed on Windows.

Simple steps:

  1. Install numpy for python, as OpenCV 2.3.1 needs this. normally choose the MKL version and the relevant python version and OS architecture( x86 or amd64)
  2. Install OpenCV , choose the relevant python version and OS architecture( x86 or amd64) as numpy
  3. The tricky part: as opencv 2.3.1 has been evolved to cv2, the old cv functions has been moved to cv2.cv. The workaround is create a cv.py file with
    from cv2.cv import *
    
  4. Copy this cv.py file under directory %PYTHON_HOME%\Lib\site-packages
  5. Now you can import cv to wrote OpenCV code. Have fun:)

“你画我猜”(draw something)单词猜测工具

Apr.6 更新:修正一处elif写成if的bug;增加ctrl-c强制停止的支持;增加对不填字符个数的用处的说明

最近“Draw Something”很火,我也玩了几次。碰到过靠谱的搭档,也碰到过很不靠谱的搭档。当然我自己也属于不靠谱一类,哈哈。

碰到的不靠谱的人多了,猜个词就费劲了。试词语让人很不爽。

所以就想写个Python脚本干这事。

首先想到了我这边对备选的字符进行排列,然后找个网络词典的接口来进行查验。

网上能搜到的在线词典的接口比较少,有dict.cn, iciba.cn和dict.qq.com的。其实我本人想用iciba的来着,不过貌似现在不能用了。最后选择了qq的词典。json返回值,我很喜欢。

刚才找了下google translate的接口,确实有。不过1M字符=20刀的价格真是伤不起。

接口搞定,就差对所有字符排列组合了。最后俺选用了itertools.permutations方法。这个方法比较傻,对所有字符进行穷举排列;如果哪位同学有更好的算法,欢迎不吝赐教:)

好了,不多说了,上代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: weibo @SeganW
"""
from __future__ import unicode_literals
import urllib
import json
import itertools
import sys

def query(word):
    con=None
    try:
        #由于google translate接口收费,而且非常的贵;
        #词霸的接口现在好像用不了了,不知道谁知道新地址
        #网上能找到能使用的就剩qq词典;词典结果不是很理想;
        #比如有些单词不在本地词典中,而网络释义的结果有非常的不可信,只能退而求其次,把所有网络释义都标记上了,大家自行鉴别
        con=urllib.urlopen('http://dict.qq.com/dict?q={}'.format(word))
        resp=con.read()
    except Exception as e:
        print '[error] get {!r} definition failed: {}'.format(word,e)
        if con:
            con.close()
        return None
    resp_json=json.loads(resp)
    if resp_json.get('err'):
        return None
    elif resp_json.get('lang') != 'eng':
        return None
    else:
        descs=[]
        if resp_json.get('local'):
            try:
                loc_desc=resp_json['local'][0]['des']
            except KeyError:
                return None
            for des in loc_desc:
                try:
                    p_type=des['p']
                except KeyError as ke:
                    return None
                if p_type == 'n.':
                    descs.append(des['d'])
        elif resp_json.get('netdes'):
            for net_desc in resp_json.get('netdes'):
                net_word=net_desc.get('word')
                if net_word and net_word.lower()==word.lower():
                    try:
                        descs.append('网络释义:{}'.format(net_desc['des'][0]['d']))
                    except KeyError:
                        continue
                else:
                    return None
        else:
            return None
        if descs:
            result= '{} : {}'.format(word,';'.join(descs)).encode(sys.getfilesystemencoding())
            print result
        else:
            result=None
	return result

def guess(char_str,num=None):
    if not num:
        num=len(char_str)
    assert isinstance(char_str,str), 'not a string'
    #非常傻的穷举方法,有好的算法的同学请不吝赐教~
    pmt=itertools.permutations(char_str,r=num)
    result=[]
    for i in pmt:
        word=''.join(i)
        #print 'Guessing word {!r}'.format(word)
        guess_result=query(word)
        if guess_result:
            result.append(guess_result)
    return result

if __name__ == '__main__':
    args=sys.argv
    if len(args)==2:
        charstr= args[1]
        num=None
    elif len(args)==3:
        charstr= args[1]
        num=int(args[2])
    else:
        raise SystemExit('usage: drawsomthing.py charstr [num]')
    print """友情提醒:由于QQ词典网络释义和部分解释不准确,请自行辨别\n开始查询..."""
    try:
        guess(charstr,num)
    except KeyboardInterrupt:
        print '已强制退出'
    else:
        print "查询结束"

运行的命令行就是

drawsomething.py char_str num

char_str为程序显示的乱序字符串,把让你拆的所有字符串起来做一个字符串
num是程序让你猜的单词包含的字符个数;可不填,这样就变成python版词典了:)

刚才写这篇文章的时候发现有道词典已经做好了更先进的工具(毕竟人家有完善的词库,俺这只是个小python脚本~),大家如果真的要用的话,就去用它的吧,地址在这里

Manipulate your wireless router using Python

Here below I just give a thread about how to manipulate your wireless router by refresh/read/delete logs. I think you could do more things than this. As the theory is the same.
This scipt can be used for monitoring who else is using the network doing what now if you find your WoW is lagged so much 🙂

There is a wireless router I connected is a NetGear WGR614v7. After accessing the adminstation page, we can find that it is a very simple web page. so we could use the common webpage crawling way to deal with it.

Actually the script I pasted below is a guide for how to deal with the Basic Authentication of HTTP and some use of lxml and re:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @author: Sean Wang, fclef.wordpress.com/about
# target router type: NetGear, WGR614v7
from __future__ import unicode_literals
import urllib2
import re
import lxml.html as lh

rooturl='http://192.168.1.1' # admin url of the router
username = 'admin'
password = 'password'

# create a urllib2 opener for basic authentication
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, rooturl, username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

#get self ip
devhandle= urllib2.urlopen(rooturl+'/DEV_device.htm')
devcontent=devhandle.read()
devdoc= lh.document_fromstring(devcontent)
devhandle.close()
devs=[i.text_content() for i in devdoc.xpath("//span")]
devs=zip(*[devs[i::4] for i in xrange(1,4)])
myips=[]
othernames={}
for i in devs[1:]:
    if 'fclef' in i[1].lower(): # fclef is my computer name
        myips.append(i[0])
    else:
        othernames[i[0]]=i[1]

#refresh log, a post method
urllib2.urlopen(rooturl+'/fwLog.cgi','log_detail=&action_Refresh=%CB%A2%D0%C2&email_on=0&log_refresh=1&log_send=0&log_clear=0')

#get log
pagehandle = urllib2.urlopen(rooturl+'/fwLog.cgi')
content=pagehandle.read()
pagehandle.close()
doc=lh.document_fromstring(content)
logs=doc.xpath("//textarea")[0].text_content()
ptn=re.compile('^\[(.+): (.+)\] Source: ([0-9\.]{11,15})')
for i in [i for i in logs.split('\r\n') if i]:
    loginfo=re.search(ptn,i).groups()
    if loginfo[2] not in myips:
        print '{0[2]}({1}) {0[0]} {0[1]}'.format(loginfo,othernames.get(loginfo[2]))

#clear log
urllib2.urlopen(rooturl+'/fwLog.cgi','log_detail=&action_Clear=%C7%E5%BF%D5%C8%D5%D6%BE&email_on=0&log_refresh=0&log_send=0&log_clear=1')

Remove CarrierIQ from rooted Android device

First of all, Thanks TrevE , the author of  Logging Test App. All I done in this article is just following what he did in his app.

These days, Carrier IQ brought an big earthquake in almost all popular mobile platforms including Android, iOS, Blackberry

How to check if your device is CIQed or not:

Update: just got in mind that no need to use PC side tools, just install and launchTerminal Emulator and run below commands one by one and check command output like adb method:

am start -n com.htc.android.iqagent/.test.MainActivity
am start -n com.carrieriq.iqagent.service/.ui.DebugSettings

( not requiring root, but android adb tool needed)

1. Make sure you have installed adb driver of your device; make sure you have got adb on your PC (download Android SDK and find it in platform-tools)
2. Execute following two commands:

</del>
<del>adb shell am start -n com.htc.android.iqagent/.test.MainActivity</del>
<del>adb shell am start -n com.carrieriq.iqagent.service/.ui.DebugSettings</del>
<del>


If both commands give you output like:

Error: Activity class {…} does not exist.

Congrats, your device has not been infected.

If no error output displayed, then you are infected. See below guides to remove

How to remove CarrierIQ:
( need root privilege in your device, root your device firstly and then install superuser app )

Caution: Do below at your own risk. I will not be responsible for any damage

1. If you are not familiar with shell commands, just use RootExplorer to do it instead:

  • click “Mount R/W” to remount a directory as read and write
  • Long press on an entry and select ‘Delete’ from the popup list to delete

2. commands below ( explanation starts with ‘#’)

#enter adb shell
adb shell
# got root privilege. make sure you have rooted your device and install Superuser.
#If you did not see a change from '$' to '#' after the command without any error, you do not root your device
su
#remount your /system with read&write privilege. every device got different arguments.
#Below is a Nexus S example, just an example, Nexus S does not include CIQ
#To get the correct argument, you could firstly use command 'mount' in the shell, then find the line contains '/system'

# e.g. I found "/dev/block/platform/s3c-sdhci.0/by-name/system /system ext4 ro,relatime,barrier=1,data=ordered 0 0"
#split them by white spaces. then see the command below, you will know how to remount your system

mount -o rw,remount -t ext4 /dev/block/platform/s3c-sdhci.0/by-name/system /system
# remove below files and folders
rm /system/bin/htcipcd
rm -r /app-cache/ciq/*
rm -r /app-cache/iqserver/*
rm -r /data/misc/agent_htc/*
rm -r /data/data/com.htc.android.iqagent/*
rm -r /data/data/com.htc.android.iqrd/*
#remount /system as Read Only again.
mount -o ro,remount -t ext4 /dev/block/platform/s3c-sdhci.0/by-name/system /system
#exit root
exit

That’s what I get from the application. Do not know if it works.
So plz tell me the check result after your did the remove part to see if the remove part works.

Using Android monkeyrunner from Eclipse, both in Windows and Linux!

This time I want to use English to make this article useful for all others in the world:)

As you know, Android MonkeyRunner is a good testing tool, but we could only develop monkeyrunner under a text editor like Vim, emacs, etc.

Diego Torres Milano wrote a blog to make Monkeyrunner running on Eclipse, he had done that on Linux. But according to his article, he mislead guys thinking that his solution also works on Windows. But after serveral tries by myself and others’ comments, it does not work in Windows at all.

Here I found a solution which also works on Windows(I have tried it by myself). And I believe that it also works on Linux, as the solution does not include any platform independent mechanism. Here we go 🙂

      1. Install/Update latest PyDev (2.2.4 at present, I think it does not relate to the PyDev version) by Eclipse Marketplace or direct install link, see guide here
      2. Extract Lib folder in ANDROID_SDK\tools\lib\jython.jar using 7-Zip/WinRAR  to ANDROID_SDK\tools\lib folder, which would be like ANDROID_SDK\tools\lib\Lib
      3. Add a Jython Interpreter under Window>Preferences>PyDev>Interpreter – Jython. Using the jython.jar from Android SDK\tools\lib folder.
      4. Please notice that adding Android SDK\tools\lib and monkeyrunner.jar in Libraries. See snapshot below: Monkeyrunner in Eclipse
      5. Click “Apply” and wait it finish. Press “OK”
      6. Now you can use this new MonkeyRunner Interpreter to set up a PyDev project. But please make sure to choose “Jython” and using Grammar version “2.5” as Jython itself is not catching up with Python. The latest Jython is 2.5.2, but Android SDK uses 2.5.0. It’s OK to replace the old one with the latest one. That’s another story. Snapshot of project setup:

Now you could write MonkeyRunner script with convenient features like auto-completion, grammmer error notice etc. Have fun:)

Notice: you cannot click the Run button to execute monkeyrunner script, it will not use monkeyrunner.bat to execute.