Pythonの型の扱いに困惑している

ただのメモ。

最近pythonを触ることになったのでいろいろ試してみているのだが、型がこれまで使ってきた言語と違うため、とても困惑している*1pythonそのものというよりライブラリのせいかもしれない。

例えばProblem 8 - Project Eulerをやってみると、以下のようにぱっと見よさそうなのに想定した結果にならない場合がある。

NGなコード

i = 0
j = 13
max_product = 0
while j < len(num) :
    tmp_str = num[i:j]
    tmp_product = np.prod([int(x) for x in list(tmp_str)])
    if (tmp_product > max_product):
        max_product = tmp_product
        max_str = tmp_str
    i = i + 1
    j = j + 1

print(max_str)
print(max_product)
    

OKなコード

i = 0
j = 13
max_product = 0
while j < len(num) :
    tmp_str = num[i:j]
    tmp_product = np.prod([int(x) for x in list(tmp_str)], dtype=np.int64)
    if (tmp_product > max_product):
        max_product = tmp_product
        max_str = tmp_str
    i = i + 1
    j = j + 1

print(max_str)
print(max_product)
    

NGなコードだと、np.prod()が暗黙的にnp.int32を仮定して値を返す*2ので、np.int32の上限値()までしか値が計算されず、正確な値を計算できない。

それ自体はしょうがないのだが、メソッドの引数で戻り値の型を指定するのは違和感が... 変数の宣言時に型を明示的に指定できるようにしてほしい(そして実行時でよいのでエラーを出力してほしい)。もしくは動的型付けなら、数値の桁ぐらいよろしく変換して適切な型で返してほしい。

とはいえ毎度、自前のコードに型判定を書くというものつらい。 正直、Pythonで型をどう扱えばいいものかわかりかねている。

参考

*1:扱える型が多い割りに動的型付けで

*2:OS依存かもしれない

pandas.DataFrameの列の順序を入れ替える

概要

  • pandasでデータフレームの列の順序を入れ替えたい

  • 日本語でググると出てくるのはpandas.DataFrame.ixを使ったものだが、ixはpandas 0.20.0 以降では非推奨*1

  • 素直に[]locilocなりを使って指定しましょう。

本論

やりたいこと

pandasで列の順序を入れ替えたい。逆順にしたり、追加した列の場所を移動したりしたい。

日本語でググると...

日本語でググると以下のようなpandas.DataFrame.ixを使ったページがヒットする。

行はスライスで全指定して、列をカラム名で指定してる。 しかし、そもそもixはpandas 0.20.0 以降では非推奨になっているので、基本的にこれから各コードで記載すべきではない。

まともなやり方

列を操作したいだけなら[]で列名を指定すればよい。

# pandasのドキュメントを参考にデータフレームの初期化
dates = pd.date_range('1/1/2000', periods=8)
df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])

#      A       B       C       D
#2000-01-01    0.333113    -0.385784   0.848445    -0.172187
#2000-01-02    0.091376    0.699982    -2.448879   0.012055
#2000-01-03    0.273267    -0.203492   0.477200    -0.170348
#2000-01-04    0.747750    0.253019    -0.025682   -0.343925
#2000-01-05    -0.155484   0.644080    0.437013    0.623010
#2000-01-06    -0.070695   -0.868981   0.289951    2.202987
#2000-01-07    -1.301506   0.301445    0.956880    1.197488
#2000-01-08    2.112945    -1.066225   -0.075310   0.586197

# 逆順にしたい場合は列名をスライスで逆順に取得すればいい
df[df.columns[::-1]]

#      D       C       B       A
#2000-01-01    -0.172187   0.848445    -0.385784   0.333113
#2000-01-02    0.012055    -2.448879   0.699982    0.091376
#2000-01-03    -0.170348   0.477200    -0.203492   -0.273267
#2000-01-04    -0.343925   -0.025682   0.253019    0.747750
#2000-01-05    0.623010    0.437013    0.644080    -0.155484
#2000-01-06    2.202987    0.289951    -0.868981   -0.070695
#2000-01-07    1.197488    0.956880    0.301445    -1.301506
#2000-01-08    0.586197    -0.075310   -1.066225   2.112945

# 列名をリストで指定すれば自由な順番で取得できる
df[['D','C','B','A']]

# データフレームの内容は上記と同じなので省略

行も指定したいときはlocilocをつかう。 特定の列を列名なり列番号で指定すればよいだけ。 ※以下の例では、行をスライスで全指定している。

df.loc[:,['D','C','B','A']]
df.loc[:,df.columns[::-1]]
df.iloc[:,[3,2,1,0]]

# 上記はすべて、[]で逆順にする場合と同じ結果になる。

なお、ご多分に漏れず、上記は新しいDataFrameを返すだけ。 そのため元のDataFrameを変更したいときは元のDataFrameを指定して代入すること。

参考

スライスについて

ixの非推奨(deprecated)について

pandasのデータフレーム操作について

全然関係ないけど

Indexing and Selecting Data — pandas 0.23.4 documentation によると列の値を入れ替えたい場合は、生の値を操作しないといけないそうな。しかし、こういう場合はpandas.DataFrame.rename()で列名を変更してしまえばよいのではないだろうか。

*1:本記事時点の最新リリースは0.23.4

技術書典5へ行った

2018-10-08、池袋のサンシャインシティ2F展示ホールDで開催された技術書典5へ行った。その際の個人的なメモ。 一般参加で、そもそも技術書典にいくのも初めてであった。

なぜ行こうと思ったのか

  • 普段の仕事とは違う刺激が欲しい
  • 正直、SIでない世界を見てみたかった。

会場の様子とか感想とか

  • 11時過ぎに会場へついたものの、すでに結構な列ができていた
  • 企業が無料で同人誌を配っていた。おそらく採用活動のためで、下手にエージェントにお金を払うよりは賢いお金の使い方だ。
  • 12時ごろには完売している本もあった。多くの本はダウンロード販売もあるが、どうしても紙でほしい本があるのなら、午前中に来ておくべき。
  • 文化祭っぽいイメージ

購入した本

技術季報 Vol.4

技術書典の公式ファンブック。 サークルの自動配置に関しては、他のイベント等でも利用できるのではないか。

Webフロントエンドの歴史本

ざっくりとJavaScriptの発展の歴史を書いた本。 読み物としては面白くJavaScriptがどういった経緯で今の形になり、今後はなにを目指しているかを理解するのに役立ちそうだ*1

可視化法学 Vol.1 Vol.2

分かりにくい法律をITを用いて可視化することを試みた本。 総務省の提供している法令データを元にして、法令間の参照関係を可視化している。 これだけで何かできるかというと、正直そうではないと思われるが、興味深くはある。 関連する法律を整理できるので、複雑度の類推みたいなものには使える可能性はある*2

若干脱線すると、法律とITという点でちょっと気になって調べてみると、どうやらそういった分野はあるようで。 法情報学(参考→情報教育 法情報学)であったり、法令工学*3といった分野があるようだ。 また、法律とAIも20年以上前から研究されている分野らしい(人工知能と法 - Wikipedia)。 日本語で検索した限りでも条文自体を自然言語処理するといった試みもなされている模様。

参考

技術と法律

可視化法学よりは実務よりで、技術者と法律家が技術と法律が交錯するテーマについて論考した本。正直なところ、まだ流し読みしかできていないが、あまり法律の前提知識を持っていない私はちょっと理解するのが難しいと感じている。 が、テーマとしては非常に興味深いので時間をかけて読んでいきたい。

余談だが、最先端を走る技術というものは、どちらかといえば法の抜け穴をつくことでビジネスとして成長している感もある。正直なところその手の技術者でこういった分野に興味を持つ人は少数派かもしれない。

参考

PythonによるKaagleのチュートリアル

Python を使って Kaagle に公開された簡単な問題を解いてみるという趣旨の本。 書いてあることはネットで探せば出てくるような話ではあるのだが、本として一連の流れがまとまっていることに価値がある。

マイナンバーカードの電子証明書

各種ライブラリを使ってマイナンバーカードに入っている電子署名を活用するための本。 マイナンバーカードと記載があるが、どちらかといえばスマートカードを利用するためのライブラリ群の簡単な紹介に近いような気がする。面白かったが。

国がマイナンバーカードの仕様を公開していないのは不思議。

誰もちゃんと教えてくれなかった USB 充電モバイルバッテリー

モバイルバッテリーの歴史と構造、どういった動きをするかについて書いてある本。 正直なところ、100%理解できている気はしないが、普段使っているものの動きが多少なりともわかる本で、興味深かった。

トララボ vol.1

無料で配っていたとらのあなさんの技術書。とらのあならでどういったことをしているかの簡単な説明が書いてある。

HOT ENGINEER

リクルートライフスタイルさんが配っていた本。 技術書というよりは中途採用向けのパンフレットのような冊子だった。

完全SIer脱出マニュアル

PDF版を購入(紙は売り切れだった) なので、まだ読めていない。 目次を眺めて見た感じだと、SEとしてはだいぶ読むのがつらいのような気がしている。

また比較的若手の人はこの本を読んで、飛び出せばいいような気もするのだが、年齢が上がってきたアラサー以降はまた別の生存戦略が必要になるのだろう。

*1:私はJavascriptには詳しくないが

*2:似たような形で科学論文における引用関係の可視化ができると割と面白いかも

*3:英語ではlegal engineeringのことか

PandocでTemplateを使うときのためのメモ

Pandocの--Templateオプションを利用して、Markdownから完全なHTMLを出力するときにTemplateを使うためのメモ。

Pandoc User’s GuidePandoc ユーザーズガイド 日本語版を基に記載。 環境はWindows 10 (64bit)。 随時更新。

正確な一次ソースとしてはPandoc User’s GuideのTemplatesがあります。

デフォルトテンプレートを確認する

単に-s/--standaloneオプションを利用した際に使われるデフォルトのテンプレートはpandoc -D *FORMAT*で確認できる。 FORMATは出力フォーマットを指定する。

PS D:\SandBox> pandoc -D markdown
$if(titleblock)$
$titleblock$

$endif$
$for(header-includes)$

# *sinp*

PS D:\SandBox> pandoc -D html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
<head>

# *snip*

Templateを使って変換する

一番簡単なのはtemplateファイルを--templateオプションで指定すること。 (--templateを指定すると、自動的に-s/--standaloneオプションも有効になる)

PS D:\SandBox> pandoc --template=template.html D:\Sandbox\PandocでTemplateを使うためのメモ.md

テンプレートファイルの優先順位

テンプレートファイルの利用優先順位は以下の通り。

どの優先順位でテンプレートやユーザデータディレクトリが使われるかは、(よく読めば)Pandocのユーザーズガイドに書かれています。

*snip*

  1. カレントディレクトリを見る
    • 指定されている文字通りのファイル名を探す
    • 拡張子が無い場合は、出力フォーマットに対応する拡張子を勝手に補う
  2. --data-dir で指定されるユーザデータディレクトリの中にある「templates」ディレクトリを探す
  3. デフォルトユーザデータディレクトリの中にある「templates」を探す
    1. Pandoc既定のデータディレクトリの中にある「templates」を探す

メモ: Pandocのテンプレートとデータディレクトリの優先順位

自作テンプレートを作る

  • テンプレートファイルに記載された$body$部がPandocにより生成したHTMLに置き換わる。
  • 自分で定義した変数も$var$のように利用できる(--variable=*KEY*:*VAL*なり、--metadata=*KEY*:*VAL*で指定する)。
  • ifやforといった制御構造も利用できる
  • 各種組み込みの変数もある。メタデータ向けの変数はファイルで読める(--metadata-file=*FILE*))

その他

以下のような拡張機能も便利そう。

Extension: pandoc_title_block

  • 入力ファイル冒頭の%で始まる行を、title,author,dataという変数として読み込んでくれる。
  • デフォルトで有効だが、明示的に指定したい場合は--from *FORMAT*+pandoc_title_blockする。
  • Lintツール(markdownlintなど)によっては警告が出力されるので、Lintツール側で無効化する必要あり。

WindowsでPandocをいれてみる

  • Markdownを手軽にHTMLに変換したい
  • かつて、DISCOUNTを使ったりしてみたのだが、結局Windowsマシンでも動かないと面倒なので、メジャーなPandocをいれてみる。

Pandocについて

環境

PS D:\>  "$((get-wmiobject win32_operatingsystem).caption) ($((get-wmiobject win32_operatingsystem).version))"
Microsoft Windows 10 Pro (10.0.17134)

PS D:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      17134  228

実際にやること

ようはPandoc で Windows に作るmarkdown to html, docx 環境において書かれていることをやるだけ。

  • github pandoc から最新版の Pandoc-x.yy.z-windows.msi をダウンロード。
  • Pandoc-x.yy.z-windows.msi をインストール。
  • システム環境変数 Path に 「C:\Users\UserName\AppData\Local\Pandoc」を通す。(※UserName は現在のログインユーザ名)

インストールされたことはpandoc --versionを実行して確認できる。

Markdown to HTML

細かいところはユーザガイドを読めばよいのでひとまず動かしてみる (ヘルプを表示するpandoc --helpWindowsでは説明のないオプションの一覧だけなので)

# 完全なHTMLを作る(head,body,htmlタグあり))
pandoc ./test.md -f markdown -t html -o test.html -s

# 部分的なHTMLをつくる(パーツとしてのHTMLへの変換)
pandoc ./test.md -f markdown -t html -o test.html

# githubのmarkdownにしたい
pandoc ./test.md -f markdown_github -t html -o test.html

先送り事項

pandoc は UTF8 を前提にしているのだが、日本語環境のPowershell文字コードは932(Shift-JIS)。 このため標準出力に結果を出力すると文字化けする。

chcp 65001文字コードUTF-8にし、かつ日本語フォントを指定すれば良いかと思ったが、その場合は日本語を含むファイル名がつぶれる。

ひとまず、ファイルへの書き出しに問題はないので先送りとした。

PosgtreSQLをpg_restore -c でリストアするとスキーマの権限が正しくリストアされない話

ただの備忘録。別にPostgreSQLに詳しいわけではない。

やったこと

pg_dump -d <hoge> -FtPostgreSQLのバックアップを取得 pg_restore -c -F t -d <hoge>PostgreSQLをリストアしようとした。

起こったこと

postgresのスキーマ(PUBLIC)に権限(privilages)がリストアされない。 -cもとい--cleanオプションを付けてprivilagesを削除しているので、リストアされたスキーマはprivilagesがない形になる。

スキーマのprivilegesがバックアップ前後で以下のように変わる*1

バックアップ前

全ロールにUSAGEとCREATEが付与されていた。

  name  |  owner   |  access privileges   |      description
--------+----------+----------------------+------------------------
 public | postgres | postgres=uc/postgres+| standard public schema
        |          | =uc/postgres         |

バックアップ後

一切の権限が付与されていない。

   Name  |  Owner   | Access privileges |      Description
 --------+----------+-------------------+------------------------
  public | postgres |                   | standard public schema

このためpostgresユーザ以外はスキーマへのアクセスができなくなる。 実際にはテーブル一覧を表示できなくなったり、スキーマ名を省略できなくなる。

オブジェクトへの権限がついていれば、明示的にスキーマを指定すればオブジェクトへアクセスはできるよう。 (schema.tablenameのように指定する)

なお、PUBLIC以外のスキーマで起こるかは未確認。

原因

詳細は不明なのだが、おそらくPostgreSQLバグ。

PostgreSQL: Re: BUG #14788: `pg_restore -c` won't restore schema access privileges.を参照すると同じような事象が報告されている。

上記では9.6.4だが、まだfixされているわけではないのだろう。

暫定対処

schemaに手動でGRANTする。PUBLICスキーマなら以下。

GRANT ALL ON SCHEMA public TO PUBLIC

その他

\dn+のアクセス権限の読み方が分からなかった。コマンド名で調べても情報がないが、ちゃんと大本のGRANTのドキュメントには記載があった。 困ったときはググるまえに公式ドキュメントをちゃんと読んだ方がよい。

*1:後述するメーリングリストからの引用

神崎洋治(2017)人工知能解体新書

人工知能がどういったもので、何ができるのか勉強する前ふりとして読んだ。

本としては悪くないと思うのだが、求めていた内容ではなかった。

本書はその内容の大半が実例だ。人工知能そのものの説明は2割あるかないかで、しかも体系だってはいない。

ビジネス向けの本、といったところで、いちおう科学向けの新書レーベルに期待していたものでば下さいはなかった。 (単に著者が想定した読者像と私にもがアンマッチだっただけなのだが)