Techracho

PythonでGoogle Language APIを使うときに、'がデコードされなくて困った

このエントリーをはてなブックマーク Share
2010.07.19    Python, 馬場   タグ: , , , , —    baba   

Google Language APIは素晴らしくて、AjaxのAPIがしっかり用意されているほか、RESTfulなAPIとして以下のようなものも使えます。

http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q={文字列}&langpair={変換前言語}|{変換後言語}

さらに、珍しく日本語ガイドがあるのも良いですね。
http://code.google.com/intl/ja/apis/ajaxlanguage/documentation/

さて、このRESTfulAPIで取得する結果はJSONになっているのですが、シングルコーテーション(アポストロフィ)は' に文字参照されて帰ってきます。

Pythonは特に関係ないんですが、文字参照されたままだと色々困ります。
標準モジュールで簡単にデコードするものが見つからなかったので、http://d.hatena.ne.jp/MOOK/20100407/1270601539を使わせて頂くことにしました。

トータルでは、以下のようなコードになります。

import urllib
import json

#参照URLの実体参照解除コードを、entity_referenceモジュールにした
import entity_reference 

text = urllib.quote("私はピーターです")
url = 'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=ja|en' % text
result = json.loads(urllib.urlopen(url).read())

print entity_reference.encode(result['responseData']['translatedText'])
#I'm peter

Twitter APIなども、実体参照で返ってきたはずなので、注意が必要ですね。

PythonのSQLiteで検索しようとしたらIncorrect number of bindings supplied. The current statement uses 1, 10 supplied.とか言われた

このエントリーをはてなブックマーク Share
2010.07.16    Python, 馬場   タグ: , , , , —    baba   

最近の言語はSQLite3のライブラリが入っていることが多いですね。

Python 2.6でも簡単で、

import sqlite3
db = sqlite3.connect('data.db')
db.execute('create table users (id integer primary key, name text, age integer)')
db.execute('insert into users (name, age) values (?, ?)', ('yamada', 21))

のように簡単に扱えます。

ところが、使い方を間違えると

Incorrect number of bindings supplied. The current statement uses 1, 10 supplied.

のようなエラーが出てしまうことがあります。

原因は単純。
executeの第2引数はタプルにしないといけません。

項目が1個のとき、()で囲んだだけだとダメですね・・・

#ダメな例
db.execute('select * from users where name = ?', ('yamada'))  

#良い例
db.execute('select * from users where name = ?', ('yamada',))

基本的ですが、普段別の言語を書いていると気づくのが遅れます。

Twitter OAuthのrequest_tokenするところで、CallbackURLを指定したときだけ401 Unauthorizedになる場合

このエントリーをはてなブックマーク Share
2010.07.15    Python, 馬場   タグ: , , , , , , , —    baba   

Twitter APIで認証ページに遷移させるときは、http://twitter.com/oauth/request_token にリクエストトークンを発行依頼します。
しかし、設定を間違えるとここで401 Unauthorizedが発生してしまうことがあります。

Tweepyの場合、以下のようなコードになると思います。

consumer_token = "xxxxxxxxxx"
consumer_secret = "xxxxxxxxxxx"
callback = "http://www.bpsinc.jp/"
auth = tweepy.OAuthHandler(consumer_token, consumer_secret, callback)
redirect_url = auth.get_authorization_url()

今回は、auth.get_authorization_url()のところで、401 Unauthorizedが発生しました。

OAuthHandlerの第3引数、callbackを無しにすると、うまく動きます。

なぜかと思ったら・・・

ここが空だった

ここが空だった

Twitterのページでアプリを登録する際に、「ブラウザアプリケーション」を選んで、Callback URLを入力し忘れると、自動的にクライアントアプリケーションになります

クライアントアプリケーションでCallbackは使えないため、401エラーが返っていたようです(400 Bad Requestを返して欲しかったな・・・)。

また、登録したアプリがBANされた場合にも、同じ現象が発生するようなのでご注意下さい。

true/false一覧君

このエントリーをはてなブックマーク Share
2010.06.12    C#, C++, PHP, Python, Ruby, java, javascript, プログラミング言語, 馬場   タグ: —    baba   

当然ながら、言語ごとに真偽判定(true/false)の基準が違います。

特にスクリプト系の言語では、明示的に型を指定しないことが多いので、たまに問題になります。

たまたま手元にあった環境で、どんな値が真に判定されるのか、というのをまとめてみました。
新しい言語に突撃するときのメモ代わりにでもして頂ければ幸いです。

検証コードイメージ

a = 0
if a
  print 'true'
else
  print 'false'
end

truefalse

凡例:
× は、コンパイルエラー
ー は、言語仕様にその値が存在しない

備考:
*”" というのは、ナル文字の値を指す(\0なので、実体はゼロという整数値)
array[] というのは、各言語での空の配列を指す
※1 C言語にfalseは存在しない
※2 配列のアドレスを指すため、真と評価される
※3 noticeが発生するが、設定や@で抑制可能

こうしてみると、やはりPHPは変態です。’0′ をfalseと判定する言語はあまりないですね。Webに特化しているのがよくわかります。$_GETなどは文字列で渡ってくるので、確かに手抜きに便利仕様です。

空配列をfalseと判定するのが、PythonとPHPというなんだかおもしろい組み合わせになりました。
良く忘れるけど、rubyはゼロという数字をtrueに判定するので注意が必要ですね。

結局、ミスのしようが無い Java / C# は安全で好きです。
また、ゼロは false、ほかは true と割り切ったC言語も、シンプルで好きです。

Pythonの便利なロガー君

このエントリーをはてなブックマーク Share
2010.05.11    Python, 馬場      baba   

pythonには便利なloggerが最初から入っているので、最初からprintじゃなくてこっちを使っておけば良いですね。
小規模なプログラムでも役立ちます。

main.py

import logging
import logging.config

logging.config.fileConfig('./logging.conf')
mylog = logging.getLogger('mylog1')
mylog.debug('hello')
mylog.error('oh no!')

logging.conf

[loggers]
keys=root,mylog1,mylog2

[handlers]
keys=default,file1,file2

[formatters]
keys=basic

[logger_root]
level=NOTSET
handlers=default

[logger_mylog1]
lebel=NOTSET
handlers=file1
qualname=mylog1

[logger_mylog2]
lebel=NOTSET
handlers=file2
qualname=mylog2

[handler_default]
class=StreamHandler
level=NOTSET
formatter=basic
args=(sys.stdout,)

[handler_file1]
class=FileHandler
level=NOTSET
formatter=basic
args=(”log1.log”,’a')

[handler_file2]
class=FileHandler
level=NOTSET
formatter=basic
args=(”log2.log”,’a')

[formatter_basic]
format=%(name)s: %(asctime)s %(levelname)s %(message)s
datefmt=%Y/%m/%d %H:%M:%S
class=logging.Formatter

confファイルに複数のlogger、handlerを指定することで、複数のファイルに書き込んだり、標準出力とファイルの両方に書き込んだり、エラーレベルでフィルタリングしたりできます。formatterを指定することで、日付を表示したりといった加工が簡単にできます。

便利ですね。

Pythonで最後の文字を削除しよう

このエントリーをはてなブックマーク Share
2010.04.21    Python, 馬場   タグ: —    baba   

SQLやCSVなどをごりごりと構築する際、項目区切りにカンマを付けて、最後のカンマを取り除く処理をよくやりますね。

PHPに慣れると、mb_substr() などとやるのが何となく億劫になりますが、pythonだとコードの見た目がスマート。
さすがです。

datas = ('hoge', 'piyo', 'foo', 'baa')
text = ''
for data in datas:
    text += data + ','
text = text[:-1]

ただ、なんとなく、表情が硬いので、text :- ) とか書けるとさらに可愛かったのですが・・・

COPYRIGHT [C] 2009 BEYOND PERSPECTIVE SOLUTIONS LTD. ALL RIGHTS RESERVED.