すなぶろ

フリーランスのWebエンジニアがPythonを中心にプログラミング情報を紹介していきます。Rubyも書きますが、今はPython勉強中。一緒にPythonista目指しましょう!

Hy の macroexpand が S 式じゃない→直した

Python へ直接コンパイルできる Lisp 方言 Hy が楽しいです。 しかし Lisp 族のつもりでいると思わぬ落とし穴があったり( let, cons がないなど)するので、 とりあえず macroexpand の結果を S 式にしてみます。

例えば let をマクロで定義してみましょう。 let の正体は lambda というか関数なので、 無名関数を使って実装します。

(defmacro let [values &rest body]
  (setv var-names (list (map first  values))
        var-vals  (list (map second values)))
  `((fn [~@var-names] ~@body) ~@var-vals))

デフォルトの macroexpand-1 の挙動はこんな感じ。

=> (macroexpand-1 '(let ((var 1)) (print var)))
HyExpression([
  HyExpression([
    HySymbol('fn'),
    HyList([
      HySymbol('var')]),
    HyExpression([
      HySymbol('print'),
      HySymbol('var')])]),
  HyInteger(1)])

待って読めない。

もうちょっと Lisper 向けの表現(= S-expression)に近づけてほしいので、 hy コマンドを起動するときに引数をつけてあげます。

  • hy --repl-output-fn=hy.contrib.hy-repr.hy-repr

これで macroexpand してみると、今度はこんな感じに。

=> (macroexpand-1 '(let ((var 1)) (print var)))
'((fn [var] (print var)) 1)

なぜか一行で表示されましたが、それでもこちらのほうが何倍も読みやすいです。

私は Emacs 使いなので hy-mode 経由で hy シェルを起動しているんですが、その場合は hy-shell-interpreter-args (デフォルト "--spy" )を変更すればよい感じです。

(add-hook 'hy-mode-hook
          (lambda ()
            (setq hy-shell-interpreter-args
                  (concat "--repl-output-fn=hy.contrib.hy-repr.hy-repr "
                          hy-shell-interpreter-args))))

Hy がもっと繁栄しますように。

Spacemacs + Python で快適コーディング環境を整える

最近spacemacsにハマってます。「Spacemacs とはなんぞや」についてはいろんな方々が 解説してくださっているので、その魅力についてはぜひそちらをご参照ください。 かくいう私もそういった記事を読んで手を出し、そのまま戻れなくなった身です。

今回は Python のコーディング環境を整えてみます。条件は以下。

  • Python 3.6.6
  • Spacemacs (develop branch)
  • virtualenvwrapper を使用している
  • pyenv を使用している (optional)

Spacemacs + Python + LiveCoding + IPython

Spacemacs では .py という拡張子のファイルを開くだけで Python コーディング用の様々なパッケージが自動インストールされる1のですが、 pip で特定のパッケージをインストールするとさらにパワフルになります。 しかも自動で。

サポートされている機能はこんな感じです。参考: spacemacs/Python layer

  • コードの自動補完
  • ドキュメント検索
  • テスト実行
  • virtualenv のサポート
  • PEP8 互換のコードチェック・自動整形
  • 不要な import 文のハイライト
  • import 文をアルファベット順で自動ソート
  • ライブコーディング
  • REPL
  • Python で書かれた Lisp 方言 hy との互換性
続きを読む

Pythonでバイナリファイルをnバイトずつ取り出したかった

  • やりたかったこと
    • 4バイトずつ取り出す
    • トルエンディアンでunsigned intに変換する
    • リストにぶちこむ

read(), struct.unpack()などでできそうな気はしたんですが、Pythonっぽいやり方ないのかなと探した結果をメモしておきます。オーバーヘッドなどを考えると最適解ではないと思うので、ビッグデータには向いていないはずです。

続きを読む

IPythonにモジュールを自動リロードしてほしいとき

  1. IPython上でモジュールをimportする。
  2. コードスニペットを書いてテストしてみる。
  3. エディタでモジュールを書き直す。
  4. 反映させるにはIPythonごと再起動する必要がある。
  5. 「なんで?」ってなる。

では、自動化を始めましょう。

続きを読む

ディープラーニングするPython製の将棋AIを見つけたら2 years ago

AlphaGoってどのくらいの強さなんでしょう。とりあえずべらぼうに強いとは聞いたんですが、囲碁にまったく明るくない私にとっては、ドラゴンボールにおける「宇宙一強い」くらい現実味のないふわふわした印象です。

そんな私にもわかることはあって、なんでも『ディープラーニング』という言葉を世界的に有名にしたらしいですね。『深層学習』って言うと、むしろ漢字なのに意味が遠い気がします。

どこの国でもそうですが、あまりにも文化や常識からかけ離れたものであればあるほど、名前をそのまま取り込む傾向にあるように思います。例えば日本発祥のmai waifuとかwapaneseとか。

私は将棋が好きなので「マシンでディープなラーニングをするショーギ・インテリジェンスがあればプレイできるのに」などと今風なことを考えていたらありました。それもPython製の、まだ開発版のAIが。

続きを読む

AIが人類を超える日は来るの?→もう来てるよ

f:id:sandmark:20171020155324j:plain

先日買い物に行きました。ごま油が欲しかったのですが、目の前にあったのは

  • 298円のごま油(250g、セール中)
  • 378円のごま油(340g、通常価格)

の2つ。私は安ければ何でも良いのですが、オトクなのはどちらだ?と考えたとき、暗算が苦手なのですぐに答えが出ません。そこでGoogleアシスタントさんにご登場願いました。

  • 「250グラム298円のごま油と340グラム378円のごま油、安いのはどっち?」
  • 「お調べしました」
  • 「えっ」
続きを読む

unmoをsetup.pyを使ってパッケージにしてみた

Pythonのパッケージと言えばsetup.pyです。依存関係も解決してくれるし、必要ならwheelを使ったプリビルトパッケージも含めることができます。

でも書くのが面倒くさいと思ってずっと放置していたんですが、先日知人にUnmoを試してもらおうと思ったら思いの外手間がかかりました。知人がコマンドプロンプトに明るくないのも手伝って、

  • pip install dillして」
  • 「ぷっぷ……なに?」
  • 「ぴっぷ いんすとーる でぃる」
  • 「ぴっぷい……?」

などという珍妙な会話に。二度あの会話をするくらいならsetup.pyを書いたほうがずっと楽だと気づきました。

続きを読む