oneshotlife-pythonのブログ

Pythonを好んで使っているプログラマです。Pythonこそが最強のプログラミング言語だと思っています。Pythonは使いやすいです。Pythonは書きやすいです。Pythonは読みやすいです。Pythonはパワフルです。Pythonは一貫性があります。Pythonが好きです。

Windows10でPythonとIDLEを使って開発する #Python

IDLEについて

IDELとはPythonに同梱している統合開発環境のこと。学習用らしいのだが、私のようにちょっとしたスクリプトを書いたり、スクレイピングをする程度の用途だったら充分使える。

IDLEの特徴

OSを選ばない

WindowsでもLinuxでも同じ動きをする。Linuxのviやらemacsの操作に慣れていない人も、Windowsの感覚で使える。

インタラクティブシェル

IPythonなどと似たようなことが出来る。もちろん、IPythonより機能的には劣るのだが、これで充分な場合も多い。

専用のGUI

WindowsでIPythonを起動した場合、コピペが面倒だったりする。右クリックして範囲選択しENTERを押すという一連の流れが非常に面倒。その点IDLEは、普通のテキストエディタのようにCTRL+Cでコピーが出来る。貼り付けもCTRL+Vで出来る。要するに、Windowsの一般的なテキストエディタと似たような操作で使いこなせる。これは便利。

また、Pythonらしく、フォントとかもお洒落に設定出来たりする。
試しに、Calibriっていうフォントにしてみた。
f:id:oneshotlife_tom:20161105183408p:plain

オヤジギャグじゃないけど、フォントは本当に重要!
フォントが違うだけで、テンションとかモチベーションががらっと変わってくる。

シェルと連動したエディタ

私の好きな使い方は、インタラクティブシェルでガチャガチャ動かしながら、動作を確認しつつ、動作に問題が無い場合、エディタに転記して清書する。先ほども言ったように、コピペが非常に楽なので、この辺の作業はサクサク進む。特に、スクレイピングをやっている人は、XPathやら正規表現やらを何度も書いたり書き直したりするので、こういった使い方が出来るというのは便利だろう。

デバッカーも付いている

実は、IDLEのデバッカーってあまり使ったことないんだけど。。。インタラクティブシェルを使いながら開発しているとデバッカーのお世話になるケースは少なくなる。でも、ソースコードの規模がある程度大きくなったら、デバッカーも必要になるでしょう。デバッカーも同梱というのはありがたい。

軽量で軽快

私は、重いIDEって大嫌いなんで。。。基本的にちょっとしたスクリプトを書くことが多いので、起動に時間がかかるのはNGです。起動の速さは非常に重要。

どうしてIDLE使っている人少ないんだろう。

こんなに便利なのに。。。
こんなにPythonっぽいのに。。。

Windows10でpipのバージョンアップ

pipを使っていると古いバージョンを使っているとのワーニングが出ていることに気付いた。

pip : You are using pip version 7.1.0, however version 9.0.0 is available.

いちいち言われるのは面倒臭いからpipをバージョンアップしようと思った。

pipのインストールは以下のコマンドで実行出来る。
ところが、アクセスが拒否されるとのメッセージが!!!

C:\Users\oneshot>python -m pip install --upgrade pip
You are using pip version 7.1.0, however version 9.0.0 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
Collecting pip
  Using cached pip-9.0.0-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 7.1.0
    Uninstalling pip-7.1.0:
Exception:
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\pip\basecommand.py", line 223, in main
    status = self.run(options, args)
  File "C:\Python27\lib\site-packages\pip\commands\install.py", line 299, in run
    root=options.root_path,
  File "C:\Python27\lib\site-packages\pip\req\req_set.py", line 640, in install
    requirement.uninstall(auto_confirm=True)
  File "C:\Python27\lib\site-packages\pip\req\req_install.py", line 726, in uninstall
    paths_to_remove.remove(auto_confirm)
  File "C:\Python27\lib\site-packages\pip\req\req_uninstall.py", line 125, in remove
    renames(path, new_path)
  File "C:\Python27\lib\site-packages\pip\utils\__init__.py", line 314, in renames
    shutil.move(old, new)
  File "C:\Python27\lib\shutil.py", line 303, in move
    os.unlink(src)
WindowsError: [Error 5] アクセスが拒否されました。: 'c:\\python27\\lib\\site-packages\\pip-7.1.0.dist-info\\description.rst'

どうやらWindows10で普通にコマンドプロンプトを立ち上げると、管理者権限が付いていないようだ。Linuxで言うところのsudoとか付ければいいんだろうけど、Windows10にそのようなコマンドがあるかはわからない。コマンドプロンプトを管理者権限で開いて実行してみたところ上手く行った。

C:\WINDOWS\system32>python -m pip install --upgrade pip
You are using pip version 7.1.0, however version 9.0.0 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
Collecting pip
  Using cached pip-9.0.0-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 7.1.0
    Uninstalling pip-7.1.0:
      Successfully uninstalled pip-7.1.0
Successfully installed pip-9.0.0

面倒臭くなったものだ。

ImportError: No module named win32api

Scrapy shellを起動しようとしたら以下のエラーが出た。

ImportError: No module named win32api

試しに、win32apiをインストールしてみた。

PS>pip install win32api
pip : You are using pip version 7.1.0, however version 9.0.0 is available.
発生場所 行:1 文字:1
+ pip install win32api
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (You are using p...0 is available.:String) [], RemoteE 
   xception
    + FullyQualifiedErrorId : NativeCommandError
 
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
Collecting win32api
  Could not find a version that satisfies the requirement win32api (from versions: )
No matching distribution found for win32api

そんなの無いって!!!

stackoverflowで解決方法を見つけた。pypiwin32というモジュール名らしい。

PS>pip install pypiwin32
pip : You are using pip version 7.1.0, however version 9.0.0 is available.
発生場所 行:1 文字:1
+ pip install pypiwin32
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (You are using p...0 is available.:String) [], RemoteE 
   xception
    + FullyQualifiedErrorId : NativeCommandError
 
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
Collecting pypiwin32
  Downloading pypiwin32-219-cp27-none-win32.whl (6.7MB)
Installing collected packages: pypiwin32
Successfully installed pypiwin32-219

IPythonの起動時にモジュールをインポート #IPython

IPythonの起動時にモジュールをインポートしたい

毎回おまじないのように、モジュールをインポートするのは面倒臭い。起動時に自動的に読み込んでくれればいいのに。と思ったときには、プロファイルを編集してあげれば実現可能。
私の場合、oneshotlife_tomというプロファイルを作成したので、プロファイルパスは以下となる。

C:\Users\oneshot\.ipython\profile_oneshotlife_tom

そこにある"ipython_config.py"を編集してあげれば良い。

変更点

変更前

#c.InteractiveShellApp.exec_lines = []

変更後

c.InteractiveShellApp.exec_lines = [
    'import sys',
    'import os'    
]

動作確認結果

C:\Users\oneshot\Desktop>ipython --profile='oneshotlife_tom'
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 4.1.2 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

IPython profile: oneshotlife_tom

>>>sys.
sys.api_version           sys.float_repr_style      sys.platform
sys.argv                  sys.getcheckinterval      sys.prefix
sys.builtin_module_names  sys.getdefaultencoding    sys.ps1
sys.byteorder             sys.getfilesystemencoding sys.ps2
sys.call_tracing          sys.getprofile            sys.ps3
sys.callstats             sys.getrecursionlimit     sys.py3kwarning
sys.copyright             sys.getrefcount           sys.setcheckinterval
sys.displayhook           sys.getsizeof             sys.setprofile
sys.dllhandle             sys.gettrace              sys.setrecursionlimit
sys.dont_write_bytecode   sys.getwindowsversion     sys.settrace
sys.exc_clear             sys.hexversion            sys.stderr
sys.exc_info              sys.long_info             sys.stdin
sys.exc_type              sys.maxint                sys.stdout
sys.excepthook            sys.maxsize               sys.subversion
sys.exec_prefix           sys.maxunicode            sys.version
sys.executable            sys.meta_path             sys.version_info
sys.exit                  sys.modules               sys.warnoptions
sys.exitfunc              sys.path                  sys.winver
sys.flags                 sys.path_hooks
sys.float_info            sys.path_importer_cache

読み込まれている!

IPython プロファイルを作成/削除/変更 #IPython

IPythonのインストールについて

http://oneshotlife-python.hatenablog.com/entry/install_IPython
上記を参照下さい。

プロファイルについて

基本的に、プログラムは全ユーザーに適用させる。特定のユーザーにだけ設定を適用させたい場合はプロファイルを作成すると便利。

プロファイルの作成方法

C:\Users\oneshot>ipython profile create oneshotlife_tom
[ProfileCreate] Generating default config file: u'C:\\Users\\oneshot\\.ipython\\profile_oneshotlife_tom\\ipython_config.py'
[ProfileCreate] Generating default config file: u'C:\\Users\\oneshot\\.ipython\\profile_oneshotlife_tom\\ipython_kernel_config.py'

プロファイルの削除方法

コマンドは特に用意されていない様子。
フォルダを削除するしか無いっぽい。

プロファイルのカスタマイズ

ipython_config.pyを開いてみると、設定項目がいろいろと列挙されており、デフォルトではコメントアウトされている。マニュアルや書籍などは無いようなので、コメントアウトされたスクリプトを元にいろいろといじってみると良さそうだ。

参考までに、プロンプトの表示をいじってみた。デフォルトだと"In [1]:"のように表示がされるが、私は数字が入るのを好まない。ブログなどに引用するときに、中途半端な数字だと嫌なので。。。

# Input prompt. '\#' will be transformed to the prompt number
c.PromptManager.in_template = 'In =>'

# Output prompt. '\#' will be transformed to the prompt number
c.PromptManager.out_template = 'Out =>'

こんな感じにしてみた。

プロファイルを指定して実行

C:\Users\oneshot>ipython --profile='oneshotlife_tom'
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 4.1.2 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

IPython profile: oneshotlife_tom

In =>print "Hello,World!"
Hello,World!

ランチャーなんて作ってみたり

Windowsの人限定だが、batファイルなんかを作ると起動が便利だと思う。
ipython_oneshotlife_tom.cmd

ipython --profile='oneshotlife_tom'

IPythonについてもっと知りたい方は

Learning IPython for Interactive Computing and Data Visualization - Second Edition
洋書しかないけど。。。

PythonとbottlenoseでAmazon Product Advertising APIを使う。

概要

Product Advertising APIについては、Product Advertising APIから。
基本的に上記の通りのルールでプログラムを書けばいいのだが、面倒臭い。

APIのラッパー的なものが既に作られているのであればそちらを使ったほうが早い。

プログラムもPerl,Python,Ruby,PHPなどいろいろあるが、好きなものを選べば良いと思う。

Pythonのライブラリではbottlenoseが使い易そうだったので使ってみた。

ちなみに、AWSAccessKeyId、AWSSecretKey、AssosiateIdなどの取得の方法は、省略する。。。
他に詳しく説明されている方がいるので各自でお調べを。

bottlenoseについて

インストール方法

pip install bottlenose

ItemLookupで商品情報をxml形式で取得する

ASINコードを元に検索する場合にこちらを使う。
ASINとはAmazonで使っているコードのこと。
書籍の場合はISBNとほぼ一緒。
参考に、ASIN:4873117569の情報を取得してみた。

サンプルコード
# -*- coding: cp932 -*-
import bottlenose
from bs4 import BeautifulSoup

AWSAccessKeyId="自分のIDを入れてね"
AWSSecretKey="自分のIDを入れてね"
AssosiateId = "自分のIDを入れてね"
amazon = bottlenose.Amazon(AWSAccessKeyId,
                           AWSSecretKey,
                           AssosiateId ,
                           Region='JP')

res = amazon.ItemLookup(ItemId="4873117569")
soup = BeautifulSoup(res,"lxml")

print soup.prettify()
実行結果(item要素のみ抜粋)
<?xml version="1.0" ?>
<html>
 <body>  
    <item>
     <asin>
      4873117569
     </asin>
     <detailpageurl>
      http://www.amazon.co.jp/Effective-Python-%E2%80%95Python%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%94%B9%E8%89%AF%E3%81%99%E3%82%8B59%E9%A0%85%E7%9B%AE-Brett-Slatkin/dp/4873117569%3FSubscriptionId%3DAKIAJGREZ6P3ZM45HYGQ%26tag%3Doneshotlifetom-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4873117569
     </detailpageurl>
     <itemlinks>
      <itemlink>
       <description>
        Add To Wishlist
       </description>
       <url>
        http://www.amazon.co.jp/gp/registry/wishlist/add-item.html%3Fasin.0%3D4873117569%26SubscriptionId%3DAKIAJGREZ6P3ZM45HYGQ%26tag%3Doneshotlifetom-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4873117569
       </url>
      </itemlink>
      <itemlink>
       <description>
        Tell A Friend
       </description>
       <url>
        http://www.amazon.co.jp/gp/pdp/taf/4873117569%3FSubscriptionId%3DAKIAJGREZ6P3ZM45HYGQ%26tag%3Doneshotlifetom-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4873117569
       </url>
      </itemlink>
      <itemlink>
       <description>
        All Customer Reviews
       </description>
       <url>
        http://www.amazon.co.jp/review/product/4873117569%3FSubscriptionId%3DAKIAJGREZ6P3ZM45HYGQ%26tag%3Doneshotlifetom-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4873117569
       </url>
      </itemlink>
      <itemlink>
       <description>
        All Offers
       </description>
       <url>
        http://www.amazon.co.jp/gp/offer-listing/4873117569%3FSubscriptionId%3DAKIAJGREZ6P3ZM45HYGQ%26tag%3Doneshotlifetom-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D5143%26creativeASIN%3D4873117569
       </url>
      </itemlink>
     </itemlinks>
     <itemattributes>
      <author>
       Brett Slatkin
      </author>
      <creator role="監修">
       石本 敦夫
      </creator>
      <creator role="翻訳">
       黒川 利明
      </creator>
      <manufacturer>
       オライリージャパン
      </manufacturer>
      <productgroup>
       Book
      </productgroup>
      <title>
       Effective Python ―Pythonプログラムを改良する59項目
      </title>
     </itemattributes>
    </item>
   </items>
  </itemlookupresponse>
 </body>
</html>

xmlをパースする

beautifulsoupを使えば余裕で解析が出来る。

サンプルコード
soup = BeautifulSoup(res,"lxml")

dic = {}
dic["asin"] = soup.findAll("asin")[0].text
dic["detailpageurl"] = soup.findAll("detailpageurl")[0].text
dic["author"] = soup.findAll("author")[0].text
dic["title"] = soup.findAll("title")[0].text
dic["manufacturer"] = soup.findAll("manufacturer")[0].text
dic["productgroup"] = soup.findAll("productgroup")[0].text

for key,val in dic.iteritems():
    print "|",key,"|",val,"|"

最後に

WebAPIを使って情報を取得するのは楽しい。たいていの場合xmljsonで情報が取得出来るので、xmlとjosonのparseの仕方が分かれば余裕で情報が取得出来る。こういった構造化された情報を提供する人たちは、綺麗にデータを並べてくれているのが大半なので、HTMLをギコギコ解析するよりずっと簡単!

Pythonでデザインパターンを勉強するならこのサイトを見るといいよ。

esu-ko.hatenablog.com
先日、教えてもらったのだが、もっと調べてみると、ウェブサイト上で公開している方がいましたね。

github.com
簡単に引用すると、以下のようなデザインパターンが、なんとPythonのサンプルコード付きで掲載されています。
が、全部英語ですので悪しからず。。。

英語も勉強せんとねー

Creational Patterns

Pattern Description
abstract_factory use a generic function with specific factories
borg a singleton with shared-state among instances
builder instead of using multiple constructors, builder object receives parameters and returns constructed objects
factory_method delegate a specialized function/method to create instances
lazy_evaluation lazily-evaluated property pattern in Python
pool preinstantiate and maintain a group of instances of the same type
prototype use a factory and clones of a prototype for new instances (if instantiation is expensive)

Structural Patterns

Pattern Description
3-tier data<->business logic<->presentation separation (strict relationships)
adapter adapt one interface to another using a white-list
bridge a client-provider middleman to soften interface changes
composite encapsulate and provide access to a number of different objects
decorator wrap functionality with other functionality in order to affect outputs
facade use one class as an API to a number of others
flyweight transparently reuse existing instances of objects with similar/identical state
front_controller single handler requests coming to the application
mvc model<->view<->controller (non-strict relationships)
proxy an object funnels operations to something else

Behavioral Patterns

Pattern Description
chain apply a chain of successive handlers to try and process the data
catalog general methods will call different specialized methods based on construction parameter
chaining_method continue callback next object method
command bundle a command and arguments to call later
mediator an object that knows how to connect other objects and act as a proxy
memento generate an opaque token that can be used to go back to a previous state
observer provide a callback for notification of events/changes to data
publish_subscribe a source syndicates events/data to 0+ registered listeners
registry keep track of all subclasses of a given class
specification business rules can be recombined by chaining the business rules together using boolean logic
state logic is organized into a discrete number of potential states and the next state that can be transitioned to
strategy selectable operations over the same data
template an object imposes a structure but takes pluggable components
visitor invoke a callback for all items of a collection

Others

Pattern Description
graph_search (graphing algorithms, not design patterns)

実践 Python 3

実践 Python 3