关于kawa.net的汉字转罗马字工具使用不了的问题

今天想把HimeHina的新歌『ヒバリ』转换成罗马音,以便我学着唱,于是就在http://kawa.net/works/ajax/romanize/japanese.html网站使用上面的工具。

结果,用不了。一直是Now loading的状态。于是我打开Chrome的控制台,就发现了是跨域请求的问题,如图:

知道是什么问题就好办了,马上安装了一个解除跨域请求限制的插件: Moesif Orign & CORS Changer ,启动解除CORS的限制,就解决了这个问题。

附:关于跨域请求:https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/#

「水」用两只手表示1000多个数字

今天吃完饭看群友聊天,他们在聊做菜的话题,在讨论会做什么菜。

阿花表示「自己做的菜用两只手就能数得过来」

这时数字怪回了一句「五进制?」

这突然间引发了我思考,以前基本上只用手表示0至9这10个数字,因为这些最常用到。如果要表示超过10的数,通常需要两只手来表示。一只手作为十位,一只手作为个位,这样通过两只手组合就可以表示0~99的100个数字。

但这就是极限了吗?

当然不是,一只手能表示10个数字是因为我们只规定了0~9的手势,我们只用规定更多的手势当然就可以表示更多的数了。

然而这大大增加了记忆的负担,并且还要花心思如何去设计更多的手势。

数字怪说的「五进制」启发了我,如果在手上用五进制来进行数数的话,一只手当做低位,另一只手当做高位,低位的手数满了5以后,向高位的手进一位。这样一共能表示5^2=25个数字。

虽然25个数字没有上面100个数字多,但是启发了我,可以通过变换进制来数更多的数字。

实际上,我们很容易联想到,手指的伸出与否表示两个状态,如果使用二进制来表示,刚好可以让手指伸出表示1,收起来表示0。这样,我们一般有10个手指,就可以通过二进制表示2^10=1024个数字。这样就能充分的利用每个手指所提供的表示能力了。

更进一步:我们甚至可以可以使用三进制,一根手指可以表示三个状态,如:伸直,弯曲,收起,分别表示2、1、0,这样十个手指一共可以组合成3^10=59049个状态,也就是说可以表示近6万个数字!!是不是有点厉害呢?

然而没人会这么无聊用三进制手势来表示数字的吧:)

「杂」记一次网站搬家

今天又进行了一年一度的网站搬家。

为什么要网站搬家呢?

还不是因为要贪点小便宜,每年去找优惠价格的服务器,而这些服务器虽然价格便宜但是要续费就会比原来购买的价格贵上几倍甚至几十倍。

于是快要到期的时候,我通常都会重新去找优惠的服务器,然后把整个网站都搬过去。

最初这个网站是部署在阿里云ECS上的,由于学生优惠还算比较便宜,配置也很好:2G的内存,独立ip,独占的1M宽带。

一年后发现,百度云(不是网盘那个百度云)上面的虚拟主机太便宜了,当时是512m的内存,2M宽带,价格19.9一年。于是我毫不犹豫地将网站搬到了百度云上来。

又过了一年,也就是到今天,服务器快到期了,我发现如果要续费,那就要付20倍的价格,也就是399,这比我在阿里云上租服务器还要贵,果断放弃。再找其他优惠,发现重新去买活动的服务器会便宜很多,还是百度云的内存128m,2m宽带,20块钱一年。

配置稍微有点低,我以为是够用的,就买来试试,毕竟也不贵。买完部署完以后,发现128m的内存有点够呛,运行WordPress,如果只是浏览网页还好,要用什么附加的插件呀,或者甚至只是想更新一下WordPress的版本都会爆内存。

这也算是贪小便宜的后果吧,于是现在我把多余的插件什么的都关闭了,统计服务、缓存之类的功能都没有开,这才勉强能跑的起来。

现在又在考虑要不要把网站搬回阿里云ECS算了,学生优惠还有一年的时间,不过先用用看吧orz

 

ps:这次搬家完以后顺便启用了https,百度云上的免费https申请非常方便(不是广告啦)

「心」炒股的感悟

太久没有写博客了,今天趁G20中美和谈之后,美股大涨之际谈下最近所思所想。

先交代一下背景吧,最近股市波动,每个夜晚都让我心惊胆颤,心神不宁,无法集中注意力,这段时间里,我经过了多次的失误操作以后,总资产一度跌破了30%,在这迷茫之际,我决定将我的感悟写下。

这篇文章不是想谈我是怎么炒股亏钱的,而是想谈一个有关的感悟。

随着时代的进步,物质生活的丰富,人类可以做出的选择也是越来越多样化了,在这有多样选择的世界里,大家是感觉更幸福了呢,还是更焦虑了呢。

就我而言:多样的选择使人更焦虑。

为什么这么说呢?

这是我从亲身体会里总结出来的,先说个例子吧:

上小学中学的时候,必须要穿校服,没得选择,觉得穿校服是件很自然的事情,每天轻松愉快的很快就换好了衣服去上学了。

到大学以后,没有校服,要自己买衣服了,就多了选择。

牌子、颜色、尺寸、价格、质量都可以选,选来选去,费时费钱又费精力。

选择多了,人,也就变焦虑了。

这还只是买衣服罢,你还得选择每天要穿什么衣服,还要选择如何搭配,考虑出行的场合,与谁会面,考虑我是不是这周穿过了这套衣服,考虑会不会和别人撞衫,考虑太多太多。。。

多样的选择给生活增添了一份负担。

再举个股票的例子:

先要说句很有争议的话:相比炒美股,炒A股是幸福的。

你可能在第一时间就会反驳我说的这句话,心想你肯定是美股亏太多钱,觉得A股有涨跌幅限制就会亏少一点,却忘记美股是牛市,A股是熊市的事实。

我呢,当然是知道这一点的,但我想说的幸福并不是在哪好赚钱,在哪不好赚钱的问题,我比较的依据是对人的折磨程度。

在A股,一般的散户是只能做多的(这里说的是一般的散户啦,别计较什么融资什么的),并且只能T+1交易,也就是说你当天买入要次日后才能卖出。

炒A股时我是这样的:我看好一支股票,我唯一的选择就是要在什么价位上买多少股呢,我当天买进去以后,这天的交易就结束了,因为我无法再支配我买进去的这部分资金了,它是涨还是跌我都只能看着。

但在美股,一切就不一样了。

美股里可以做空和做多,可以轻易的融资上杠杆,最重要的是它可以T+0交易,也就是说你可以在当天买入当天卖出,反悔无数次(有代价的)。

炒美股时我是这样的:我看好一支股票,先选择在什么价位买多少股,买进去以后就一直盯着盘,因为我还有机会反悔啊。我买进去以后就看着,它一跌我就在想我是不是该提前抛掉止损。它一涨我又在想,它是不是已经涨到顶点了该抛掉止盈。每一次方向的变动都会在我的心里掀起不小的波澜,不断拍打我的意志,折磨我的内心。

在A股里,你一天的选择是有限的,你进行完当天的交易以后你就只能看着。而在美股里,你一天的选择是无限的,你可以不断地买进卖出买进卖出。美股给你更多的选择,同时给你带来了更多的焦虑与压力。

我不是想说哪个市场好哪个市场坏,我只是想表明焦虑的来源是选择的多样性造成的,越多的选择带来越大的焦虑。

人类的一大共同点就是害怕损失,害怕自己的利益没有最大化,这就能解释为什么选择使人焦虑,人需要做出选择,通常都是在几个对自己利益程度不同的选项中选择,而且一般都没有完美的选项(e.g., 这衣服超好看超舒服,但好贵啊。 这工作超轻松超适合我,但工资好低啊。诸如此类)。为了让自己的利益最大化,我们会不断的比较不同的选项,从不同选项中找到最优解,这个过程是很耗费精力的,选择的越久,耗费的精力越大,人也就会越来越焦虑,越来越烦躁。

焦虑影响人们做出理性的决定。

一旦被选择折磨久了,注定变得焦虑,在焦躁不安的情况下,人们的理性思维能力会下降,容易冲动,做出欠思考的决定(e.g., 你可能之前研究一个股票了很久决定要在这个股票跌到13刀再买入,但当你看到这股票势如破竹的涨到16刀的时候,冲动地放弃自己这么久的研究的成果,直接买入,结果追高了)。因此在有更多选择的美股市场里,你更容易变得焦虑,并更容易做出错误的操作。

所以说,当你要做出重大决定的时候,冷静下来思考一下:这个决定是不是一时冲动造成的,是非理性的呢?

在这越来越自由、物质种类越来越繁多的时代里,选择自然而然也就会变得很多,要如何在这个时代里做到不再焦虑,似乎是一件比较困难的事呢。

雨田子雨廷

于2018/12/4凌晨

「心」熬夜有感

嗯。。现在是凌晨五点,我还没睡着。

十一点上床,十二点睡觉。

睡前看了会儿手机,有点兴奋,睡不着。

努力睡着,挣扎着睡着,睡不着。

想着熬夜对身体不好,更拼命地睡着,更睡不着。

数绵羊?998、999、1000。好,两点了,睡不着。

想到以前背单词,背着背着就困了,于是开始背单词,背完单词,莫名地更加精神,三点了,睡不着。

越熬越害怕,怕今晚休息不够,明天没精力学习,心跳加速,睡不着。

四点钟,听到宿舍外清洁工阿姨已经开始工作了,我意识到这晚上已接近尾声。我渐渐开始不再焦虑了,睡不着的话,继续背单词也不错吧。今天没睡够,明天补上就好。

又打开扇贝单词直到现在。

五点钟,站在阳台,看见对面宿舍全部关着灯,听见树丛中虫子在鸣叫,我的内心感受着深夜的宁静。回想当初挣扎入睡,不由地觉得可笑。故觉得有必要记录一下,便打开博客记下此感。

嘛,其实很多事情都是这样的。

从一开始的 无知担心 到 痛苦焦虑 到最后 懂得了放下,才能得到解脱。

写完这篇以后已经五点四十七分了,决定去睡觉了。

 

[R.M.C] 用python实现微信控制电脑端虾米音乐(3)

接上篇 用python实现微信控制电脑端虾米音乐(2)

上篇里介绍了如何接受用户发送到微信的消息,做了个简单的echo程序,这次我们来讲SAE中完整的代码写完。

一、指令的处理以及储存

也就是图上画红圈的部分:

我们给weixinInterface.py里的POST方法中加上处理指令的代码(weixinInterface.py改后完整的代码见文章末尾):

# 检测是否为命令(是否为"cmd "开头)
if content.startswith("cmd "):
    command = content[4:] # 截取指令的内容
    mc = pylibmc.Client() # 获取Memcache实例
    old = mc.get(fromUser + "_cmd") # 获取该用户缓存的指令
    if not old: # 如果没有缓存的指令,设置成空列表
        old = []
    
    # 将之前缓存的指令与新的指令形成的列表
    # 存放在"用户名_cmd"的键下
    mc.set(fromUser + "_cmd", old + [command])
    content = "命令[{}]已接收".format(command) # 修改回复的内容
Memcache在这里的作用:

先说明一下Memcache在这里的作用,SAE是我们的我们的网络应用,每次我们访问一次我们网络应用的URL就会运行一遍我们的代码,所以如果我们只是单纯的创建一个变量将我们的数据储存在内存中,下一次访问的时候,这些数据都会重置,不能储存下来,所以我们需要Memcache这个缓存服务来讲我们需要储存的数据储存下来,以便之后使用。还有我们创建的这个网络应用时选的是共享环境,所以每次运行我们代码的服务器可能都不一样,所以需要Memcache来缓存我们的数据。Memcache是以键值对的形式来管理数据的,就像Python中的字典一样。

在Memcache中储存命令的形式:

将用户的所有命令已字符串的形式存在列表中,并将该列表储存在Memcache中以”用户名_cmd”的键下

处理命令的具体步骤如下:
  1. 判断用户发送的消息是否为”cmd空格”开头
  2. 截取指令部分即cmd空格之后的内容
  3. 获取pylibmc实例(pylibmc库是一个让Python管理Memcache的库)
  4. 从Memcache中获取用户的旧指令
  5. 将新指令连接到旧指令列表中,储存进Memcache

二、客户端指令的接收

思路

这里让客户端使用GET方法来获取用户储存在SAE的指令。指令以json的形式传递,接收到的将是json形式的列表,列表内以字符串的形式存放着所有未获得的指令。这里为了简单起见,定义:如果使用GET方法访问我们SAE的URL时,有usercmd这个参数表明要获取以这个参数为名称的用户所存放的所有指令。当然这里存在一点安全隐患,因为任何人都可以随意的访问我们这个URL来读取用户的指令列表,可以采取一些简单的加密来提高安全性,这里简单起见就不做这些处理了。

SAE端的设置

首先在weixinInterface.py的GET方法中添加(weixinInterface.py改后完整的代码见文章末尾):

try: # 来自电脑客户端的请求
    user = params.usercmd # 获取usercmd参数
    mc = pylibmc.Client() # 获取Memcache实例
    cmdlist = mc.get(user + "_cmd") # 获取用户对应的所有指令
    if not cmdlist:
        cmdlist = []
    mc.set(user + "_cmd", []) # 将用户对应的指令列表清空
    return json.dumps(cmdlist) # 将指令列表以json的格式作为响应返回

except: # 错误请求
    pass

 

客户端的设置

再在电脑本地创建一个client.py文件,作为我们的客户端程序,之后将使用它来访问我们的SAE来获取指令,我们先写个简单的测试程序:

import requests
import json
import time


if __name__ == "__main__":
    while True:
        user = "LeiZiTing" # 这里填入你企业微信中用户的名称,可以在企业微信的成员管理中找到
        # 访问SAE,并添加参数usercmd
        r = requests.get("http://timpcfanwx01.applinzi.com/weixin?usercmd=" + user)
        cmdlist = json.loads(r.text) # 读取获得的json数据,得到指令列表
        for command in cmdlist: # 处理指令列表中每一条指令
            print(time.strftime("%D %H:%M:%S ") + command)
        time.sleep(1) # 休息一秒钟~

运行我们的测试程序,然后在微信上发以”cmd空格”开头的指令试试看~

效果图:

我们成功将微信上发的内容传递到电脑上了,接下来我们就可以做任何我们想做的事了。

随时随地使用微信给自己的电脑发送指令,通过python完成一些简单的任务,是不是很棒棒xD

以下附上修改后完整的weixinInterface.py:(修改的部分使用注释标明)

# -*- coding: utf-8 -*-
import hashlib
import web
import lxml
import time
import os
import urllib2, json, urllib
from lxml import etree
from WXBizMsgCrypt import WXBizMsgCrypt
import pylibmc # 需要在SAE中申请创建Memcached
import json # 处理json

sCorpID = 'YOUR_CORPID' # 企业微信的CorpID
AGENTID_RMC = 'YOUR_AGENTID' # 应用的AgentId
SECRET_RMC = 'YOUR_SECRET' # 应用的Secret
sToken = 'Token00000'
sEncodingAESKey = 'EncodingAESKey00000000000000000000000000000'


class WeixinInterface:
    def __init__(self):
        self.app_root = os.path.dirname(__file__)
        self.templates_root = os.path.join(self.app_root, 'templates')
        self.render = web.template.render(self.templates_root)
        self.wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)

    def GET(self):
        # 获取URL参数
        params = web.input()

        try: # 来自微信的请求
            signature = params.msg_signature
            timestamp = params.timestamp
            nonce = params.nonce
            echostr = params.echostr
            ret, echostr = self.wxcpt.VerifyURL(signature, timestamp, nonce, echostr)
            if ret == 0:
                return echostr
           	
        except:
            try: # 来自电脑客户端的请求
                user = str(params.usercmd) # 获取usercmd参数,并转化为str类型(原本是unicode类型)
                mc = pylibmc.Client() # 获取Memcache实例
                cmdlist = mc.get(user + "_cmd") # 获取用户对应的所有指令
                if not cmdlist:
                    cmdlist = []
                mc.set(user + "_cmd", []) # 将用户对应的指令列表清空
                print cmdlist
                return json.dumps(cmdlist) # 将指令列表以json的格式作为响应返回
            
            except: # 错误请求
                pass
                
        
    def POST(self):
        # 获取URL参数
        params = web.input()

        # 获取POST的数据
        data = web.data()

        signature = params.msg_signature
        timestamp = params.timestamp
        nonce = params.nonce

        # 解密消息
        ret, msg = self.wxcpt.DecryptMsg(data, signature, timestamp, nonce)
        if ret != 0:
            print "ERR: DecryptMsg ret: " + str(ret)
            return ''

        xml = etree.fromstring(msg)
        content = xml.find("Content").text
        msgType = xml.find("MsgType").text
        fromUser = xml.find("FromUserName").text
        toUser = xml.find("ToUserName").text
        msgid = xml.find("MsgId").text
        
        # 检测是否为命令(是否为"cmd "开头)
        if content.startswith("cmd "):
            command = content[4:] # 截取指令的内容
            mc = pylibmc.Client() # 获取Memcache实例
            old = mc.get(fromUser + "_cmd") # 获取该用户缓存的指令
            if not old: # 如果没有缓存的指令,设置成空列表
                old = []
            # 将之前缓存的指令与新的指令形成的列表
            # 存放在"用户名_cmd"的键下
            mc.set(fromUser + "_cmd", old + [command])
            content = "命令[{}]已接收".format(command) # 修改回复的内容

        msg_xml = self.render.reply_text(fromUser, toUser, timestamp, content, msgid, AGENTID_RMC)
        # 将产生的数据加密
        ret, encryptmsg = self.wxcpt.EncryptMsg(str(msg_xml), nonce, timestamp)
        if ret != 0:
            print "ERR: EncryptMsg ret: " + str(ret)
            return ''
        # 将加密的数据返回给用户
        return encryptmsg

 

待续未完~

 

[R.M.C] 用python实现微信控制电脑端虾米音乐(2)

接上篇 用python实现微信控制电脑端虾米音乐(1)

上一篇介绍了准备工作,以及企业微信的连接。这次我们来试试让SAE接收微信用户发送的信息,做一个简单的echo程序,即回复用户发送的内容。

先简单说一下流程,当企业微信收到用户发送的消息以后,会将消息本身进行AES加密再POST到我们设置好的SAE应用的URL上。

我们首先在SAE应用的根目录下创建一个templates的文件夹,并在里面创建一个reply_text.xml

$def with (toUser,fromUser,createTime,content,msgid)
<xml>
   <ToUserName><![CDATA[$toUser]]></ToUserName>
   <FromUserName><![CDATA[$fromUser]]></FromUserName> 
   <CreateTime>$createTime</CreateTime>
   <MsgType><![CDATA[text]]></MsgType>
   <Content>$content</Content>
   <MsgId>$msgid</MsgId>
   <AgentID>1000005</AgentID>
</xml>

注意,把最后的AgentID改成你的AgentID。这个文件是回复信息时的模板。

我们来继续编辑SAE上我们之前创建的weixinInterface.py这个文件。上一次,我们只给它写了个GET方法,这个方法是当我们对SAE应用URL使用GET方法访问时会自动调用的方法。这次由于消息接收是使用POST方法传递的,所以我们这里定义一个POST方法。

def POST(self):
    # 获取URL参数
    params = web.input()

    # 获取POST的数据
    data = web.data()


    signature = params.msg_signature
    timestamp = params.timestamp
    nonce = params.nonce

    # 解密消息
    ret, msg = self.wxcpt.DecryptMsg(data, signature, timestamp, nonce)
    if ret != 0:
        print "ERR: DecryptMsg ret: " + str(ret)
        return ''
    # 这里使用print可以用来当做记录日志,也能用来Debug
    # 在SAE的日志中心的错误日志中可以看到print的内容

    xml = etree.fromstring(msg)  # 进行XML解析
    content = xml.find("Content").text  # 获得用户所输入的内容
    msgType = xml.find("MsgType").text
    fromUser = xml.find("FromUserName").text
    toUser = xml.find("ToUserName").text
    msgid = xml.find("MsgId").text

    # 使用模版产生response的内容,我们这里将toUser和fromUser反过来填写,将消息回复给发送的用户
    msg_xml = self.render.reply_text(fromUser, toUser, timestamp, content, msgid, AGENTID_RMC)
    # 将产生的数据加密
    ret, encryptmsg = self.wxcpt.EncryptMsg(str(msg_xml), nonce, timestamp)
    if ret != 0:
        print "ERR: EncryptMsg ret: " + str(ret)
        return ''
    # 将加密的数据返回给用户
    return encryptmsg

在微信上给应用发送一个消息来测试一下吧~

PS:再说一下调试的技巧,如果发送消息过去,并没有消息回复回来不要着急,很可能是代码哪里错了。我们可以在SAE的日志中心里查看错误日志,我们每发一次消息,代码就会运行一次,如果有错误产生,可以在错误日志中看到,所以每改一次代码,保存后,在微信上发送一条消息,然后刷新一下错误日志,可以帮助我们debug喔,是不是很棒棒(๑•̀ㅂ•́)و✧

错误日志如下:

用python实现微信控制电脑端虾米音乐(3)