「sudo: pip: コマンドが見つかりません」というエラー
現象
このエラーは、pipコマンド自体をアップデートしていなかったら現れるようです。
#pip単体でのインストールはエラーは出ないが pip install library #sudoを組み合わせると、エラーが発生 sudo pip install library sudo: pip: コマンドが見つかりません
原因
sudoの参照先にpipコマンドがないためため、コマンドが見つからないというエラーメッセージ通りです。
以下のコマンドで異なるパスを参照しようとしていることがわかります。
私はanacondaでpythonを入れているため、このような現象が起きます。
which pip #/home/username/anaconda3/bin/pip which sudo #/usr/bin/sudo
/usr/bin/の中にpipコマンドがあれば、このようなエラーは起きませんが、pipはanacondaのbinにあります。
対処法1
単純明快、pipコマンドをアップグレードする。
この下のどれでもアップグレードできるので、自分の環境に合わせたコマンドを選択する。
pip install -U pip easy_install pip conda install pip
pipのインストーラーを直接、サイトからダウンロードしてきても可。
Installation — pip 9.0.1 documentation
ダウンロードしてきたら、ファイルを実行する。
python get-pip.py
ちなみに、自分はこれらのどれでもなく、ubuntuのapt-getで入れたpipを使っているので以下のコマンド。
sudo apt-get install python-pip
対処法2
対処法1で対処できなかった場合です。
sudoの後にanacondaのpipの参照先を指定します。
which pip #/home/username/anaconda3/bin/pip sudo /home/username/anaconda3/bin/pip install libname
ちょとナガイ。
環境変数を変えるなり、aliasに登録なりすると便利!
これらのどれかで解決できるはず
問題は、どの入れ方でpipをインストールしたかです。
pipとコマンドをうったときに、参照してる先のpipを指定しないとこのエラーは直りません。
以上、終わり!
pythonでシェルスクリプト実行(カレントディレクトリ取得したり、cdしたり)
pythonでシェルスクリプト実行をしたい
import os
os依存のコマンドをこのライブラリで実行することが出来ます。
端末(ubuntu)やターミナル(mac)の上でうつコマンドをpythonのプログラムで書けるなかなか汎用性の高いライブラリです。
例えば...
ディレクトリを移動したい!時のcdコマンドなどが、
pythonプログラムを通して、実行できるわけです。
os.systemは、コーテーション内にシェルスクリプトを書くことで実行が可能です。
コマンドが実行できた場合は、0が返り値となります。
他にも。
>|python
#ファイル作成
os.system('touch test')
|
Pythonで画像処理 〜2枚の画像を重ねてみる〜
pythonのライブラリ、pillowを使って、2つの画像を重ねてみたいと思います。
重ねる画像はこの2つ。
アナログテレビ時代のザザーッって感じのやつ。
微妙にこの2つの画像、違います。
これを重ねてみます。
以下が重ねるコードです。
画像のピクセルを配列に入れる関数と画像を重ねる関数の2つを使って、画像を重ねています。
コードと一緒に、コードの動きをコメントで書いています。
#pillowとnumpyをインストール from PIL import Image import numpy as np #画像のピクセルを配列に入れる関数 def pixelGetter(img): #画像を開く img = Image.open(img) #画像のサイズ(縦×横)を入れる #今回使用する画像は640×480 size = img.size #print(size[0]) #print(size[1]) #配列を入れる変数を定義 img_pixels = [] for x in range(size[0]): for y in range(size[1]): #画像の左上から順番にピクセルの情報を取得 #1ピクセルの情報は(r, g, b, 透過度) #この情報をappendで配列に入れている img_pixels.append(img.getpixel((x,y))) #ピクセル情報が入っている配列をリターン return img_pixels #画像を重ねる関数 def pileUp(pic1, pic2): #2枚の画像を開く img = Image.open("pic1.png") img2 = Image.open("pic2.png") #2枚の画像のサイズを入れる size = img.size size2 = img2.size #2枚の画像を重ねるための変数を定義 #重ねるといっても、実際は2枚の画像から新しい3枚目の画像を作成している #そのため、3枚目の画像を入れる変数をここで定義する必要がある #サイズは2枚の画像と一緒であるため、640×480を入れる new_img = Image.new("RGBA", size) #重ねる処理を行う #画像を重ねるというのは、中の処理は1つ1つのピクセル同士を足し合わせるということ #赤い透明の下敷きを2枚重ねると、濃い赤になる原理と同じ #そのため、2枚の同じ位置同士のピクセルの(r, g, b)を足し合わせている i = 0 for x in range(size[0]): for y in range(size[1]): r = pic1[i][0] + pic2[i][0] g = pic1[i][1] + pic2[i][1] b = pic1[i][2] + pic2[i][2] #ピクセル情報の入った配列では、画像を表示する形式に合わない #そのため、putpixelで画像表示の形式に変換 new_img.putpixel((x, y), (r, g, b, 255)) i += 1 #リターンで重ねた画像を表示 return new_img.show() pic1 = pixelGetter("pic1.png") pic2 = pixelGetter("pic2.png") pileUp(pic1, pic2)
結果的に、重ねると...
重ねるとちょっとした文字がでてきましたね。(出てきた文字に特に意味はありません)
ROT13をPythonで実装してみる
ROT13って何?
ROT13 または ROT-13、rot13 は単換字式暗号(シーザー暗号)の一つである。アルファベットを一文字毎に13文字後のアルファベットに置き換える。Aは Nに、 B は O に置き換えられ、以下同様である。英語の "Rotate by 13 places" の略。ネットワーク上のやりとり(電子掲示板、ネットニューズ、フォーラム等)で冗談の落ち、パズルの解法、ネタばれ情報、不快表現等を隠すのに用いられるアルゴリズムである。実際には暗号というほどのものではないが、ちょっと見に読んでしまうという事態は避けられる。雑誌などでクイズの正解を上下逆さまに印刷するが、それと似たようなものである。
実装手順
この文字はROT13で暗号化された文字です。
pboby vf sbffvy.
文字にそのまま13は足せないので、一度この文字列をASCIIの数値に変換します。
以下、ASCIIコードの数値と文字の対応表のURL。
112 98 111 98 121 32 118 102 32 115 98 102 102 118 121 46
ASCIIの数値に変換するとこうなります。
文字コードに変換してから、13を足すか引くかの条件を分岐するので、ASCIIの文字コードに変換した時
- 65〜77であれば、プラス13
- 78〜90であれば、マイナス13
- 97〜109であれば、プラス13
- 110〜123であれば、マイナス13
これで、A〜Z、a〜zの対応付けすることができます。
以下、簡単な対応表です。
A - M | 65 - 77 |
N - Z | 78 - 90 |
a - m | 97 - 109 |
n - z | 110 - 123 |
実装してみる
contents = "pboby vf sbffvy." process = "" for script in contents: num = ord(script) #space or period if num == 32 or num == 46: ascii_script = chr(num) #A - M elif num >= 65 and num <= 77: ascii_script = chr(num + 13) #N - Z elif num >= 78 and num <= 90: ascii_script = chr(num - 13) #a - m elif num >= 97 and num <= 109: ascii_script = chr(num + 13) #n - z elif num >= 110 and num <= 123: ascii_script = chr(num - 13) process += ascii_script print(process)
このプログラムをじっこうした結果
cobol is fossil.
こうなります。
seleniumで自動売買 〜SBI証券から自動で株を買ってみる〜
自動売買ってどうやってやるの?
アルゴリズムトレードが昨今流行りではありますが。
残念ながら日本の証券会社は一般向けに株式売買のAPIは公開されていません。
そのため、APIを通してのアルゴリズムによる株の自動売買は現状できません。
FXやビットコインはAPIが公開されているので、アルゴリズムで自動売買を行っている人が多いようですが、株式で自動売買をやっている人があまりいないのはここらへんの理由かと思います。
(高頻度取引は東京証券取引所に登録すれば可能なようですが、調べてもあまり情報がでてきません、個人では行えず法人のみっぽいです)
最近、銀行の取引をAPI化して業務提携をする動きが盛んになってきていますが、証券会社が売買等のシステムをAPI化する話はあまり聞きません。
こういった話は国主導で進めるので、明日急にAPI公開なんてことにはならないので、株式売買のAPI公開はいったん諦めましょう。
では、どうやるか。
どうやらseleniumというウェブのUI自動テストツールが使えそうです。
seleniumはクリックや文字入力をプログラムを通して、自動で行えることができるライブラリです。
もともとはシステムのテストを自動化する目的で発展してきたようですが、これを使ってウェブを操作することもできます。
seleniumの簡単な使い方の記事
前にyoutubeで「yui」と検索するコードをseleniumで書きました。
これをちょっと変えるだけで、SBI証券にログインして株を売買するってのはできそうです。
SBI証券にログインして株を買ってみる
import unittest from selenium import webdriver from selenium.webdriver.common.keys import Keys class PythonOrgSearch(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome("/home/ubuntu/robo/chromedriver") def test_serch_in_python_org(self, signal=1): driver = self.driver #SBI証券のHP driver.get("https://www.sbisec.co.jp/ETGate") #SBI証券のログインID driver.find_element_by_name("user_id").send_keys("login_id") #SBI証券のログインパスワード driver.find_element_by_name("user_password").send_keys("login_password") driver.find_element_by_name("ACT_login").click() driver.find_element_by_xpath('//div[@id="link02M"]/ul/li[2]').click() if signal == 1: PythonOrgSearch.buy(self) elif signal == 0: PythonOrgSearch.sell(self) def tearDown(self): self.driver.close() def buy(self): print("buy") driver = self.driver #現物買にチェック driver.find_element_by_name("trade_kbn").click() #銘柄コードを入力 driver.find_element_by_name("stock_sec_code").send_keys(1305) #売買株数を入力 driver.find_element_by_name("input_quantity").send_keys(100) #価格指定 driver.find_element_by_xpath('//td[@id="gsn1"]/input').click() #預かり区分を指定 driver.find_element_by_name("hitokutei_trade_kbn").click() #取引パスワードを入力 driver.find_element_by_name("trade_pwd").send_keys("trade_password") #注文確認画面をクリック driver.find_element_by_name("ACT_estimate").click() #注文発注 driver.find_element_by_name("ACT_place").click() def sell(self): print("sell") if __name__ == "__main__": unittest.main()
HTMLの構造上、find_element_by_nameで要素を取得できない部分はxpathを使いました。
成行か指値か、を選択するところがまさにそれで、仕方がなくxpathを使っています。
SBI証券はHPにJaveScriptを使用していないので、selenium単体で全ての操作を完結させることができました。
selenium自体の使い方はシンプルなので、コードを書くと言ってもHTMLの構造を読むのがメインでした。
seleniumの環境構築と簡単な使い方
- 今は日曜日の夜2時
- 環境構築
- Youtubeで「YUI」と検索する操作をseleniumを使ってやってみる
- クリックもできるselenium
- id要素以外の見つけ方
- けっこう簡単だったselenium
今は日曜日の夜2時
早く寝ないと!!
明日は仕事なんです。
急いで書くのでぶっきらぼうな今日は文章になるかもです。
何とかブログだけ書いてさっさと寝ます。
環境構築
pipでインストール可能です。
pip install selenium
seleniumはAPIを通じてブラウザを使用するため、seleniumとは別にブラウザ用のドライバーをインストールする必要があります。
Safari、Firefox、Chrome、Edge、どれでも好きなブラウザのドライバーの圧縮ファイルをHPからダウンロードでき、私はChromeを選択しました。
ダウンロードした圧縮ファイルを解凍するとChromedriverというファイルが現れます。
これをseleniumを使用するファイルと同じフォルダに入れておきます。
公式HPにはPATHを通すと書いてあったが、そこは本人の自由。
私は面倒だったので、そのままコードの中にChromedriverの位置を書きました。
ここらへんの環境構築にちょっと苦労しました。
Youtubeで「YUI」と検索する操作をseleniumを使ってやってみる
#unittestは単体テスト用のライブラリ。 #動作の開始から終了までの時間を計測してくれるので、なんとなく使用。 import unittest from selenium import webdriver from selenium.webdriver.common.keys import Keys class PythonOrgSearch(unittest.TestCase): def setUp(self): #pwdでカレントディレクトリを確認。 #カレントディレクトリの場所をそのまま記述。 #seleniumを実行するファイルとChromedriverを同じ場所に格納が楽。 self.driver = webdriver.Chrome("/home/ubuntu/serv/robo/chromedriver") def test_serch_in_python_org(self): driver = self.driver #youtubeのURL #driverの中にはサイトの構造がHTMLとして格納されている。 driver.get("https://www.youtube.com/") #youtubeの検索バーはid="masthead-search-term" #find_element_by_idで検索バーのidを取得してくる elem = driver.find_element_by_id("masthead-search-term") #yuiと検索 elem.send_keys("yui", Keys.RETURN) def tearDown(self): self.driver.close() if __name__ == "__main__": unittest.main()
ちなみに、youtubeのサイト構造の画像。
id="masthead-search-term"が検索バーであることがわかります。
クリックもできるselenium
クリックを自動で行いときは.click()で可能。
方法はだいたいさっきと同じで、HTMLからクリックしたい要素のidを探して.click()をつけたします。
driver.find_element_by_id("about").click()
公式サイトを見るとドラッグ・アンド・ドロップもできるみたいだが、どの場面でドラッグ・アンド・ドロップを使うのかは私には思いつかない...
herokuでのスケジュール管理にAPSchedulerを使ってみる
目次
- herokuで定期的にファイルを実行したいとき何を使っていますか?
- cron...?
- heroku scheduler...?
- cronよりもheroku schedulerよりAPSchedulerが良い
- heroku上でAPSchedulerを使ってみる
- 用意するもの
- まとめ
- 参考
herokuで定期的にファイルを実行したいとき何を使っていますか?
cron?
heroku scheduler?
APScheduler?
cron...?
DBの更新、データの取得、バックアップの保存などのスケジュールの管理はモダンなWebアプリには必須機能です。
ubuntuのデフォルトでインストールされているcronはあらゆるスケジューリングが可能で、上記のほとんどのことはcronによって達成することが出来ます。
ですが、cronはサーバー上で動作することもあり、Webアプリのテストをローカル環境で行うことを考えると、もっと高いレイヤーのアプリケーションのインスタンスで動作するほうが勝手がいいです。
heroku scheduler...?
herokuにはスケジュール管理のためのファンタスティックなアドオンが用意されています。
このheroku schedulerはシンプルなタスクを10分、1時間、一日、複数の間隔での実行が可能です。
しかし、5分や37分など中途半端な時間での実行は難しいです。
cronよりもheroku schedulerよりAPSchedulerが良い
アプリケーションのインスタンスで動作し、かつ、中途半端な時間でも簡単にスケジュールの管理が可能なのが、APSchedulerです。
これはPython製のライブラリなので、私のようにwebアプリを全てpythonで完結させたい人たちにはもってこいです。
heroku上でAPSchedulerを使ってみる
ということで、1分おきに現在時刻をDBにインサートするプログラムを書いてみます。
最終的な出力はこうなります。
herokuのログを見ると、1分おきにDBを更新していることがわかります。
用意するもの
herokuでアプリを運用するために必要なファイルは以下です。
#適当に用意してください runtime.txt requirements.txt #以下は今から作成します Procfile gettime.py time.db timeclock.py
スタート。
#screamtimeという名前のアプリを作ります heroku create screamtime
次に、gettime.pyを作成します。
import sqlite3 import pandas as pd import datetime #現在時刻を取得する now = datetime.datetime.today() hour = now.hour minute = now.minute #DataFrame形式にぶち込む #普通はSQL文書いてインサートすると思いますが、 #私がDataFrame形式に慣れているので、こちらを使用していますが、各自なれた方法でお願いします time_df = pd.DataFrame({"Hour" : [hour], "Minute" : [minute]}) #db作成 dbname = "time.db" #dbコネクト conn = sqlite3.connect(dbname) c = conn.cursor() #dbのnameをtime_dfとし、読み込んだcsvファイルをsqlに書き込む #if_existsでもしすでにtime_dfが存在していても、置き換えるように指示 time_df.to_sql("times", conn, if_exists="replace") #作成したdbを見てみる select_sql = 'select * from times' for row in c.execute(select_sql): print(row) conn.close()
これをgettime.pyという名前で保存します。
次は、今作成したgettime.pyをAPSchedulerで定期的に実行させるコードを書きます。
from apscheduler.schedulers.blocking import BlockingScheduler import os sched = BlockingScheduler() #間隔は1分ごとにしています #minutesではなくてhourに変更したら、時間での指定も可能です @sched.scheduled_job('interval', minutes=1) def timed_job(): print("Let's start") os.system("python gettime.py") sched.start()
これをtimeclock.pyという名前で保存します。
最後にProcfileを作成します。
clock: python timeclock.py
これで、herokuにclockのファイルであるということを宣言します。
ファイルが全て揃ったので、あとはherokuに上げるだけです。
念の為、herokuに上げるまでのgitでの手順を載せておきます。
git init git add . git commit -m "first commit" git push heroku master
エラーなく行けば、これでherokuには「1分おきに現在時刻をDBにインサートするプログラム」がアップロードされました。
以下でherokuにclockをスケールします。
heroku ps:scale clock=1
上手くスケールされたことを確認して。
heroku ps |< 数分待ってからherokuのログを見てみます。 >|| heroku logs
以上で「1分おきに現在時刻をDBにインサートするプログラム」が完成しました。
まとめ
APSchedulerはとても簡単にスケジュールの管理が行うことができます。
コードもpythonで書くことができるので、使い勝手がとても良いです。
cronよりもheroku schedulerよりもAPSchedulerが良いんじゃあないでしょうか!?