2017年8月12日土曜日

Win10でPython

今まではPython使うときは、基本MacかLinuxでした。しかし、大抵の人はWindowsで動くプログラムを希望します。
仕方ないので、Windows10でのPython環境を構築することを考えて、anacondaで試してみました。特に地図表示が欲しいので、basemapパッケージをインストールしたいのですが、これまでwindowsだけは単にinstallコマンドだけではダメでした。しかし、最近やっと一発で行けるようになったようです。以下のコマンドでできました。

> conda install -c conda-forge basemap
> conda install -c conda-forge basemap-data-hires (地図データです)

参考にしたHPでは、basemapのバージョン指定をしていましたが、元のHPを見ると、バージョン番号は省いても最新のものを入れてくれるように今はなっていました。
ただ、このconda-forgeを使うと、conda自体を古いバージョンにしてしまうらしく、再度最新のものにしておかないと、今後の管理に支障をきたす恐れがあります。

> conda update conda

実際、自分が試した時もconda-forgeを使うと一つ古いバージョンに戻されていました。

さて実際に使ってみましたが(Python入門にあったロケットシミュレーションです)、なんかグラフの軸のラベルが文字化けして、□が出てくるだけです。(どうも日本語がダメです)おかしいと思い、半年くらい前に最初に試したMacで動かしてみると、packageのimportでエラーが出ます。どうもいくつか更新したものの相互依存関係が壊れているようなので、全部最新に更新します。それで動かしてみると、あれ?windowsと同じようにグラフの軸のラベルが文字化けしています。最初からこうだったけ?どうも何か問題が起きているようです。(どうも最新のmatplotlibのデフォルトフォントが日本語対応していないようです。plt.rcParams['font.family']='IPAexGothic'とフォントを指定していますが、システムにそれがない模様。)
ただ、windowsでもほぼ同様なpython環境が実現できているようです。

fontについてその後
少し調べてみましたが、以下のコマンドでシステムに登録されているTTFのフォントリストが得られます。
>> import matplotlib.font_manager
>> print([f.name for f in matplotlib.font_manager.fontManager.ttflist])

大量にフォントが出力されてきて、どれが日本語に対応しているのかわかりませんが以下で日本語が出力されました。
・win10
mpl.rcParams['font.family'] = 'HGMaruGothicMPRO'
・Mac
mpl.rcParams['font.family'] = 'AppleGothic'
(一部文字がまだ豆腐でした。Macは少し前にOSがSierraに変わったときにフォントが変わってしまったようです。)

conda-forgeとは
anacondaは元々、continuum社がパッケージをまとめたものですが、github社がその他のグループのリポジトリを集めて公開しているもののようです。そのため、より先進的なパッケージが集まっています。今回試したbasemap(windows版)が、anaconda.orgにはなくても、conda-forgeにはありました。

2017年8月5日土曜日

MacBookのバッテリー交換

2010年より前に購入(つまり10年くらいたってる)したMacBookがあります。当時、Intel搭載の最初のMacBookとして非常に人気が高かったものです。今ではもうOSの更新はとうにできませんが、時々使っています。(さすがにネットサーフィンは怖くて、これではしません)
今日、持ってみたら何か裏面に違和感が… バッテリーが膨らんでいる!?


いや~、見事に膨張していますね。上にのっけたWalkmanが傾いています。これはもう使用は危険です。いつ爆発するかもしれません。(最悪の話ですが)爆発はしなくても、煙くらい吹いてもおかしくありません。これは使用中止かと思いましたが、特定用途でまだ使っているので、試しにバッテリーなしで100Vをつないだ状態で電源を入れてみたら動きます。
それでも、その状態で使い続けるのも危ないので、AMAZONで探してみたら、互換品ですがまだ売ってるんですね交換用バッテリー。早速注文しました。

2017年7月22日土曜日

Windows Visual StudioによるPython環境について

自分はよくPythonでプログラムを作っているんですが、ほとんどMacかLinuxでした。WindowsでPythonやろうと思うと、パッケージを別途インストールしないといけないし、そのメンテンナンスも面倒だし。(Macなんてbrewで更新一発ですよ。最近は、anacondaも試しています。)
ところが、この前Visual StudioでもPython開発環境ができたことを知りました。いや不勉強にも、Visual Studio 2015くらいからあったようです。いや、何だかんだ言っても、仕事でプログラムを作っていると、お客さんはどうしてもWindowsで動くようにして欲しいという要望が多いんです。はっきり言って、システム作る方はWindowsでは作りたくありません。動作環境がM$の都合でコロコロ変わり、動作保証するのが大変なんです。おまけに、余分なプロセスが一杯動いていて、自分の作ったプログラムがどうしても遅くなるし。

ただまあ、お客様の希望は聞かないといけません。ちょっとWindowsでのPython開発環境を試してみました。ただ、その辺は色んなHPに一杯書かれているので省き、一番大事な問題、作ったPythonプログラムをどうやって動かすかです。
どのHPみても(M$のドキュメント見ても)、皆Visual Studioから起動することしか教えてくれません。いやいや、開発中はそれでもいいんですが、開発終わったらアイコン等から直接動かしたいでしょう。ところが肝心の、直接動かす設定に関する情報がどうしても見つかりません。仕方ないので、ちょっと調べてみました。(イリーガルなところがあるかもしれません)

まずそもそもVisual Studio自体が、Python環境としてどこを使っているのかが問題です。(コマンドプロンプトではpythonがどこにあるのかわからない、と言ってきます)実際、anacondaインストールすると、Visual Studioは自動的にその環境を検出してくれて、元々Visual Studioが持っているPython環境とどちらを使うか選択させてくれます。色々ぐぐってみましたが、全然情報が見つからないので、やむなくC:\から「検索」で調べてみました。すると以下の所にPython.exeがありました。

C:\Program Files\Python36\

64bitのPythonインタープリタなのに、何故こちら?とは思うんですが、どうもここです。まあ、PATH設定に追加してしまうのが簡単なんですが、ちょっと場所が気持ち悪いところにあるので何時変わるかもしれません。どうせ単独動作させるときは.batファイルから起動することが多いでしょうから、そこだけPATHを設定してしまいましょう。
Pythonのプログラムを起動する.batファイルを作り、最初に以下を入れておきます。

set PATH=C:\Program Files\Python36;%PATH%

これで、この.batファイルから起動されるプロセスだけにPythonのPATHが通ります。この後、Pythonプログラムの起動プログラムを書いてやればいいだけです。

2017年5月18日木曜日

【雑談】NTTの光モデムがやばい

自分が何時、家のネット回線をADSLから光に変えたか忘れてしまいましたが、昔からずっとNTTです。当時の光は3台装置が必要だったんです。光-電気変換器(正式な名称があるんだろうけど忘れました^^;)、CTU、最後にモデムです。この当時は1portしかEtherがなく、複数台のPCで使いたい場合はその1portをブリッジに繋げるしかありませんでした。(本当はルータにして、そこでproxy噛ませたかったんですが、NTTはDHCPの機能はNTTが持つので、ブリッジしか許してくれませんでした。)

1、2回雷が誘雷したのか壊れて交換しましたが、数年前CTUとモデムを一体型にした新型に交換してくれと電話がきたことがありました。その時は交換が面倒だったので断りましたが、数ヶ月前NTTの携帯と回線の契約をまとめると少し料金がお得になりますという甘言に負けて、契約したらその一体型のモデムに無理やり交換させられてしまいました。開通の設定が少し手間がかかりましたが無事使える様にしました。この新しいモデムですが、無線LANのカードを別売りで追加することはできるは、Etherも4port持ってます。さすがに10年以上前みたいに一家にPCが1台だけだとは思わなくなった様です。
ただLANの配線をし直すのも大変なので、従来のブリッジからの1portとメインのPCをモデムにつなぎました。(ブリッジ経由より、少しは速度が有利なんじゃないかという軽い気持ちでした)

ここからが本題なんですが、家ではNASを使っていて、半年〜1年に1回くらいUSB-HDDにバックアップをとってます。半日くらいかかりますが、まあしかたありません。ところが、今回バックアップをメインのPCにUSB-HDDをつないで行うと、なんかむちゃくちゃ遅い…。しかもよくNASからレスがなくなり、コピーできませんと言ってきます。どうしたのか、色々調べました。NAS周りのLAN回線がどこか接触不良した様子もありませんでした。しかも別の部屋(そこまでWiFiが届かないので、別途回線を通して別のWiFi親機を設置しています)でタブレット等でネットに繋ごうとすると、何時もは何も問題が起きないのに今日に限って全然つながりません。しばらく試していて、どうも別の部屋でタブレットを使うタイミングで、メインPCとNASの接続がおかしくなる様です。

ここまできてやっと推測ができました。メインPCはNTTのモデムに直結しています。4portあるうち、1portの通信量が増えて、他のportからのDHCPの要求に応えれなくなった様です。(能力がこのモデム足りなさすぎ)NASもDHCP機能を使って家庭内LANに接続してますから、時々DHCPアドレスの更新要求を出していますが、その時に別の部屋でタブレットがアクセスしようとすると、両方のDHCP応答が時間内にできない状態になっていたようです。メインPCをNTTのモデムに直結はやめ、NTTのモデムにはブリッジだけつなぎ、あとはブリッジ経由にしました。そうしたところ、NASのバックアップの速度が速くなり、別の部屋でのタブレット使用も問題なくなりました。

しかし、このNTTのモデム一体どんな回路構造になっているのやら。4portつけても、どれかが大量にデータ転送すると(まあ普通の一般家庭では、まずそんなことしないかもしれませんが)、他のportの機能の応答に支障がでるとは。かなりおそまつなCPUを使ってるんだろうな。

2017年4月9日日曜日

Pythonで地図を描く:Basemap

anaconda関係で色々調べていたら、Basemapというパッケージのことを知りました。これは地図を描画してくれるライブラリとのこと。昔から、地図のGUIには苦労していたので、早速試してみました。(ちなみにコードはpython3でかいてます。遂に2.7から3系に移行する決心をつけました)

とりあえず実行例を示します。
環境はmac OSXです。(最近は、Linuxよりmacの方が楽になってきました(^_^;))
これは、matplotlibというグラフ描画パッケージが元にあり、その上で動くようです。しかもGUIまで自分で持ってます。以下にコードを示します。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

# 緯度経度で範囲を指定する
north = 46.
south = 30.
east = 147.
#west = 128.
west = 128.

# 地図の表示('merc"は純粋に緯度経度を直行座標系にplotしている)
m = Basemap( projection='merc', llcrnrlat=south, urcrnrlat=north, llcrnrlon=west, urcrnrlon=east, resolution='l' )

# 陸地を茶色に, 湖を水色に
#m.fillcontinents(color='#8B4513', lake_color='#90FEFF')
m.fillcontinents(color='coral', lake_color='aqua')

# 海を濃い青に
#m.drawlsmask(ocean_color='#00008b')
#m.drawlsmask(ocean_color='blue')
m.drawmapboundary(fill_color='blue')

# NASA 'Blue marble' image
#m.bluemarble()

# 海岸線を引く
m.drawcoastlines(linewidth=0.5, color='black')

# 5度ごとに緯度線を描く
m.drawparallels(np.arange(25, 50, 5), labels = [1, 0, 0, 0], fontsize=10)

# 5度ごとに経度線を描く
m.drawmeridians(np.arange(125, 150, 5), labels = [0, 0, 0, 1], fontsize=10)

# 画面に表示
plt.show()
ちょっと色々試行錯誤したあとがコメントに残ってます。面白いのはNASA 'Blue marble'で、衛星写真ぽいテクスチャを貼り付けてくれます。

さて、実際に使うときは任意の緯度経度にマークをつけたくなります。定番の日本標準時の明石の位置に赤丸を表示してみました。
コードは以下を追加することになります。

# 地図に色をつけると見えなくなる! zorderが配置の意味をつけるらしい
x = 135.
y = 35.
m.scatter(x, y, s=200, c='red', latlon=True, zorder=10)
これはかなり苦労しました。scatterというメソッドを最初は例題を見ていると、matplotlibのpltのメソッドをcallする例が多数でしたが、どうもうまくいきません。大体、なんで表示領域の座標系をpltが理解できるんだ?ということに気づき、継承しているBasemapからcallしてみたらやっとうまくいきました。(latlon=Trueという引数があり、これを呼ばないと全然位置があいません)また更に罠なのが、zorderという引数です。よく考えれば当たり前なんですが、どう見てもこれ大元にOpenGL使ってるよねという感じです。(引数の中にはalphaまでありました)だったら、描画位置の指定をしないと隠れてしまいます。ですから、マークは少しZ軸で手前に置いて描きます。

座標のXYはリストで与えてもいいようなので、簡単にGISデータの描画ができます。

PS
ただ気になったのは、これの海岸前の元データはどこからきたんだろう?ということです。自分が知っている限り、(日本のは)国土地理院しかありません。あそこは基本、利用はプライベートの利用は許可していますが、著作権はどこかに表示してね、というスタンスだったはずです。同様なデータがNatural Earthというサイトにありますが、この海岸線(及び国境線)のデータに関するライセンスの記述がありません。自分が見つけられないだけ?ならいいんですが、少しグレーな気がします。

2017年3月20日月曜日

Pythonのanacondaを導入してみる

pyenv, spyderをmac osxに導入してみる。
SpyderはpythonのIDEで、anacondaパッケージ内に一緒に入っている。
(というか、anaconda内にpython,numpy等全部入ってしまっている模様。逆に事前に入れてあるpythonやライブラリとは独立した生態系になってしまい、混乱することもあり)


とりあえず、macではpyenvのインストールが必須とのこと


$ brew install pyenv


.bash_profileを修正(赤字部分を追加)


export PYENV_ROOT="${HOME}/.pyenv"
export PATH=/opt/lo/bin:/sbin:$PATH:/usr/local/share/python:${PYENV_ROOT}/bin
eval "$(pyenv init -)"


$ pyenv install -lで、インストール可能なバージョン一覧がでるので、確認。


Python3系を使いたい方


$ pyenv install anaconda3-4.0.0
$ pyenv global anaconda3-4.0.0


Python2系を使いたい方


$ pyenv install anaconda-4.0.0
$ pyenv global anaconda-4.0.0


pyenv globalは全体の環境で、anacondaの使うバージョンを指定しています。特定ディレクトリ以下では別のバージョンが使いたい場合、当該ディレクトリでpyenv local (バージョン)としてやります。


condaというバッケージ管理システムがあり、anaconda内のpythonやライブラリはcondaコマンドで管理します。(brewと共存してしまうのがややこしい。気をつけないと何を動かしているのかわからなくなりそう)
それまでbrewでインストールしたpythonはpipコマンドでライブラリのパッケージ管理をします。
(補足:anacondaの環境にはこれまで使っていたchainerが当然入っていません。anaconda内にもpipコマンドがありますので、こいつでanaconda環境内に再度chainerをインストールしてやれば、とりあえずこれまで通りchainerを動かすことはできますが。。。)


またpythonの仮装環境を作るvirtualenvに対する、pyenv-virtualenvというのもあり、condaのpyenv localとsource activateがバッティングしても、こちらが解決してくれるとのこと。

これまでpython2系ばかり使ってきましたが、そろそろpython3系にも手を出したいと考えていました。しかし、このあちこちに異なるバージョンのpythonが入ってしまう状況、頭が混乱しそうで使い方を整理してから始めないと。。。

2017年2月11日土曜日

c++におけるclassの相互参照について

大きなプログラムを長年メンテナンスしていて、改修を繰り返しているとclassの相互参照が必要になってくることがあります。しかも、互いのclassは昔は関係なかったために、別headerで作成していて、相互に#includeしないといけなくなったりします。
ただ、普通にそれをやってしまうとcompilerがやはり「そのclassわからない」というようなエラーを返してきます。

undefined classA
has incomplete classA

とかいってきます。まあ当たり前とは思うんですが、それでもそれを解決しないと先に進みません。色々なキーワードでぐぐってみましたが、やっと理解できたのでメモしておきます。とりあえず、以下にclass Aとclass Bが相互参照しているサンプルを示します。


複数のファイル(classA.h, classA.cpp, classB.h, classB.cpp, main.cpp)で構成されています。この相互参照を可能にするために重要なのが3点あります。

第1点
classA.hの10行目、class B;の参照を宣言しておく。

これはclassA.h内でclass Bを使うために#include "classB.h"をやっているんですが、classA.hをコンパイル時にはまだclass Bのコンパイルは行っていないため、class Bの定義内容がコンパイラにはわかりません。そこで、「とりあえず」class Bというのがあるよ、とプロトタイプ宣言だけしてコンパイラを誤魔化しているようなものです。当然、classB.hでも同じような処置をしておきます。

第2点
class A(class B)の実装は.cppファイルで別に行っておく。

理由はよくわかりませんが、楽しようとしてheaderファイル内にclassの実装もしてしまうとダメなそうです。(大きなプログラムだと大体そうなっているとは思いますが)

第3点
15行目にあるように、相互参照するclassのメンバーはポインタでしか保持できない。

これもコンパイラの問題で、プロトタイプ宣言で当該classがあるよとは誤魔化しましたが、詳細なタイプの定義まではまだこの時点ではわかっていません。そのため、ポインタであれば実体はプログラム実行中に「後で」なんとかできるので、コンパイラはパスします。
あと、重要なのは相互参照しているclassのメンバの実体化は135, 136行目の様にsetUp()関数を使ってやらないといけません。面倒臭がってclass AやBのコンストラクタでnewしてしまうと、実行時に互いをnewしあい、無限loopに入ります。(PCが暴走状態になり、再起動に苦労しました)

大抵こういう時は、調べる情報源にstackoverflow(英語のほうね)が役に立ちますが、今回はぐぐるキーワードでちょっと苦労しました。