Python 3.5.1 + Selenium + Chrome on Windows
GUIで操作するSeleniumを利用したことがあるような記憶はありましたが、
プログラムからも操作できるそうなので
Windows7上でPython3からSeleniumを利用してChromeを開くまでを行ってみました。
pipでseleniumをインストール
- Python3がまだの場合は https://www.python.org/downloads/ で入手後Python3をインストールします。
pip
でselenium
を指定するとインストールできました。
python -m pip install selenium
- この時点では
selenium-3.0.2
がインストールされました。
Collecting selenium Downloading selenium-3.0.2-py2.py3-none-any.whl (915kB) 100% |################################| 921kB 856kB/s Installing collected packages: selenium Successfully installed selenium-3.0.2
ChromeDriverをインストール
https://sites.google.com/a/chromium.org/chromedriver/downloads
- この時点では
ChromeDriver 2.27
が最新でした。
PythonでChromeを起動
executable_path
にダウンロード後に展開した ChromeDriver のパスを指定します。
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.keys import Keys browser = webdriver.Chrome(executable_path='[C:\\設置したパス\\chromedriver.exe]') browser.get('https://www.google.co.jp/') browser.find_element_by_name("q").send_keys("Python3 Selenium Windows Chrome") browser.find_element_by_name("q").send_keys(Keys.ENTER)
- Chromeを指定。
https://www.google.co.jp/
を開く。- 検索ワードに
Python3 Selenium Windows Chrome
を入力。 - Enterキーを押す。
参考
Vagrant + Python3.5 を用いて Japronto を動かすメモ
Windows で Vagrant + Python3.5 を用いて Japronto をとりあえず動かすまで。
※VirtualBox/Vagrantはインストール済み
- Japronto
- VagrantにCnetOS環境構築
- Python3 と Japronto インストール
- ホストOSで ./public/index.py を用意
- ゲストOSで index.py を起動
- 起動後はホストOSのブラウザで http://192.168.33.15:8080/ にアクセス
Japronto
- レスポンスが高速らしいとのことで興味を持ちました。
VagrantにCnetOS環境構築
- Vagrant, Python3 のセットアップは一部こちらを参考にしました。
$ vagrant box add py3_centos67 https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box $ vagrant init
- Vagrantfileを編集
Vagrant.configure("2") do |config| config.vm.box = "py3_centos67" config.vm.network "private_network", ip: "192.168.33.15" config.vm.synced_folder "./public", "/home/vagrant/public" end
- Guest Additionsをインストール後、Vagrantを起動してゲストOSに接続
※次回起動時に共有フォルダが共有されない問題が起きたときにGuest Additionsをインストールして解消しました。
$ vagrant plugin install vagrant-vbguest $ vagrant vbguest $ vagrant up $ vagrant ssh
Python3 と Japronto インストール
$ sudo su - $ yum install https://centos6.iuscommunity.org/ius-release.rpm $ yum search python3 $ yum install -y python35u python35u-pip python35u-devel $ pip3.5 install --upgrade pip $ pip3.5 install japronto $ exit
ホストOSで ./public/index.py
を用意
- 共有フォルダ(
config.vm.synced_folder
)を設定しているのでホストOS側で用意できます。 - ゲストOSで操作する際は
vi
などで。 ./public/index.py
※日本時間で今日の日時を表示
#!/usr/bin/python3.5 # -*- coding: utf-8 -*- from japronto import Application import codecs import datetime DEFAULT_ENCODING = 'UTF-8' JST = datetime.timezone(datetime.timedelta(hours = 9), 'JST') def header(title): with codecs.open('header.txt', 'r', DEFAULT_ENCODING) as f: return f.read().format(title) def footer(): with codecs.open('footer.txt', 'r', DEFAULT_ENCODING) as f: return f.read() def index(request): now = datetime.datetime.now(JST) text = '' text += header('index') text += '<div class="center">' text += now.strftime('<span class="l b">%Y</span><span class="s">年</span><br>') text += now.strftime('<span class="l b">%m</span><span class="s">月</span>') text += now.strftime('<span class="l b">%d</span><span class="s">日</span>') text += '<span class="s">(</span><span class="l b">{}</span><span class="s">)</span><br>'.format( ['日', '月', '火', '水', '木', '金', '土'][int(now.strftime('%w'))] ) text += now.strftime('<span class="l">%H</span><span class="s">:</span><span class="l">%M</span><span class="s">:</span><span class="l">%S</span>') text += '</div>' text += footer() return request.Response(mime_type='text/html', text=text, encoding=DEFAULT_ENCODING) app = Application() app.router.add_route('/', index) app.run()
./public/header.txt
※ファイルが長くなるので分けました。
<!DOCTYPE html> <html> <meta http-equiv="refresh" content="1;URL=/"> <head> <title>{}</title> </head> <style type="text/css"> .center {{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; width: 200px; height: 80px; text-align:center; }} .b {{ font-weight: bold; }} .l {{ font-size: larger; }} .s {{ font-size: smaller; </style> <body>
./public/footer.txt
※ファイルが長くなるので分けました。
</body> </html>
ゲストOSで index.py
を起動
$ ./index.py Accepting connections on http://0.0.0.0:8080
起動後はホストOSのブラウザで http://192.168.33.15:8080/ にアクセス
Python 3.5.1でプレミアムフライデーを求めてみた
偶然目にしたPHPでプレミアムフライデー(月末の金曜日)を求めるが興味深かったのでPythonでプレミアムフライデーを求めてみました。
# -*- coding: utf-8 -*- import calendar cal = calendar.Calendar(firstweekday=calendar.FRIDAY) y = 2017 for m in range(1, 13): for row in reversed(cal.monthdayscalendar(y, m)): d = row[0] if d > 0: print('{}-{:0>2}-{:0>2}'.format(y, m, d)) break
結果
2017-01-27 2017-02-24 2017-03-31 2017-04-28 2017-05-26 2017-06-30 2017-07-28 2017-08-25 2017-09-29 2017-10-27 2017-11-24 2017-12-29
Python 3.5.1 で文字コード指定してテキストファイルを読み込んだ際のメモ
codecs
を使うと良い様子
# -*- conding: utf-8 -*- import codecs import os file = '.{}UTF8.txt'.format(os.path.sep) f = codecs.open(file, 'r', 'utf-8') for lineno, line in enumerate(f, start=1): print(lineno, ':', line.rstrip()) f.close()
または
# -*- conding: utf-8 -*- import codecs import os file = '.{}UTF8.txt'.format(os.path.sep) with codecs.open(file, 'r', 'utf-8') as f: for lineno, line in enumerate(f, start=1): print(lineno, ':', line.rstrip())
など
codecs.open()
の第三引数に'utf-8'
を指定してみたところ- 他、
lineno
で行番号を出力 - 他、
''.rstrip()
で行末の改行を除去
出力例:
1 : これは1行目 2 : 2行目 3 : 3行目の文章 4 : 4行目
場合によっては、
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
などで標準出力の文字コードも変える。
以前試した別記事:
行番号 lineno
についてはこちらを参考にしました:
Laravel 5.4.12 でカスタムコマンドを試す
- artisan でカスタムコマンド HelloCommand を作る
- ファイルを編集: app/Console/Commands/HelloCommand.php
- ファイルを編集: app/Console/Kernel.php
- 引数無しで実行してみる
- 引数に Hoge と指定して実行してみる
- 登録したカスタムコマンドを確認してみる
- 参考
artisan
でカスタムコマンド HelloCommand
を作る
make:command
でカスタムコマンドHelloCommand
を作成。--command=
オプションで$signature
を指定して作成できる模様。
$ php artisan make:command HelloCommand --command="command:hello {message=Hello}" Console command created successfully.
ファイルを編集: app/Console/Commands/HelloCommand.php
- 新規に作成された
app/Console/Commands/HelloCommand.php
を編集。 $signature
に、コマンドの名称と引数を設定。--command=
オプションで指定済みの値が入っている。handle()
に処理を書く。
<?php namespace App\Console\Commands; use Illuminate\Console\Command; class HelloCommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'command:hello {message=Hello}'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $funcs = ['line', 'info', 'comment', 'question', 'error']; foreach ($funcs as $func) { $this->$func($this->argument('message')); } } }
ファイルを編集: app/Console/Kernel.php
- 元からある
app/Console/Kernel.php
を編集して、HelloCommand
を登録。
<?php /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ Commands\HelloCommand::class ];
引数無しで実行してみる
php artisan command:hello
$ php artisan command:hello Hello Hello Hello Hello Hello
※Windows7のcmdで実行した場合、出力される文字に色は付かない。
引数に Hoge
と指定して実行してみる
php artisan command:hello Hoge
$ php artisan command:hello Hoge Hoge Hoge Hoge Hoge Hoge
登録したカスタムコマンドを確認してみる
php artisan list [<namespace>]
$ php artisan list command Laravel Framework 5.4.12 : : Available commands for the "command" namespace: command:hello Command description
参考
Three.js r76 で星空を作ってみた
リアルな感じではなくGIFアニメっぽい感じです。
完成系はこちらです。
Three.jsはまだ触れ始めたばかりですので手順として誤りなどが含まれているかもしれません。
目次
- 目次
- 星を斜めに移動させたいのでカメラを回転させました
- テクスチャ画像はjsにBase64エンコードして埋め込んでいます
- SphereGeometryの頂点座標を活用しPlaneGeometryの星を配置しました
- 親の球体に子の星を追加しています
- 球体はあくまでも軸としているだけなのでMaterialは不要と思っていましたが。
- Raycasterでマウスに反応するようにしてみました
- フレームレートは 30 fps にしています
星を斜めに移動させたいのでカメラを回転させました
SphereGeometryを利用して挑んでいます。
カメラを引いてみると次のようになります。
この球体を利用すると地球に例えるなら北極と南極に当たる部分には頂点が密集しています。
この頂点が密集してる部分を利用すると等間隔っぽい並びにならなくなるためカメラに映りこまないようにしたいと考えました。
球体のY軸だけ回せばこの頂点が密集してる部分はカメラに映りこまないので、
斜めに移動しているように見せるためカメラそのもののZ軸を回すことにしました。
テクスチャ画像はjsにBase64エンコードして埋め込んでいます
やり方が悪かったのかデスクトップ上でテクスチャが読まれないので、テクスチャ画像をjsに埋め込みました。
// http://icooon-mono.com/14622-%E6%98%9F%E3%81%AE%E7%84%A1%E6%96%99%E7%B4%A0%E6%9D%907/ var starImg = new Image(); starImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABPElEQVQ4T5WTwU3DQBBF/48FV0IFpANikdyhAtwBOWCLG6GDdADcUMwhdGAqgDtGTirAdJBcg+xBu4sdrxU7ZCQfrJl5uzP/L9ESEgeeSnMwjZrK2JSQ5KaHLP/SeWd9THe23FbbDPgMxhDc6ybijmfTh/0AsZ8CPNFNInMOQ/ffAEn8PjImVoMjLt1wXodQL4o4NSehD0gXYA+A+qqRAqJutQRhQIKFAqjlHLWp0ZJbUT6uz8GOkmlfyAqSe1qFP8kUxIyyOxZwOh7dp7SUUZJRF9mhkupqR/8LnPW48IXlg63br9NqatiAqnmavWuZygbEfgTwsn0EeeUg1G/EmLQSEgey+ZVviIxMFWelK83jKvs2SzRyvhmAPML5mRSLMgs+mAC8Nen8gsPnd+sGZZFIVCTroxjP0KvCfwGZVYAhUmIo4gAAAABJRU5ErkJggg=='; var starTexture = new THREE.Texture(); starTexture.needsUpdate = true; starTexture.image = starImg;
なお、テクスチャとして画像はこちらのものを利用させていただいています。
画像をjsに埋め込む際Base64エンコードをするため、「画像
base64エンコード
」のキーワードでヒットしたサイトを利用しました。
SphereGeometryの頂点座標を活用しPlaneGeometryの星を配置しました
以前作ったThreejs r76で球体&パーティクルの頂点部分が星になれば良いかと考えて、SphereGeometryを利用しています。当初はPointsの個々に貼り付けたテクスチャを回転させることが出来ればと考えましたが、テクスチャを回転させるような手段は用意されていないようで、個々の星はPlaneGeometryを用いてSphereGeometryの頂点部分に貼り付ける形としています。
親の球体に子の星を追加しています
言い回しがあっているかわかりませんが、シーンに直接加えるとグローバル空間上の中心を軸とするようです。
この中心を軸に星々を回転させることは可能でしたが、星々をその場で回転させることは容易でないようです。
そこで、球体を親とし星を子として加えることで子の星はZ軸を回転させるだけでその場で回転させることが行えました。
なお、親を回転させれば子も追随してグローバル空間上を回転するので、やりたいことを達成しました。
- 球体の頂点が密集している北極と南極に当たる部分はカメラに映りこまないのでその部分は除外するようにしています
if (this.starSphere[this.starSphere.length - 1].geometry.vertices[i].y > 130 || this.starSphere[this.starSphere.length - 1].geometry.vertices[i].y < -130) { continue; }
- 星になるPlaneGeometryを用意し
var plane = new THREE.Mesh( new THREE.PlaneGeometry(starSize, starSize), material.clone() );
- 親となる球体
this.starSphere[this.starSphere.length - 1]
の頂点座標を活用して
plane.position.set( this.starSphere[this.starSphere.length - 1].geometry.vertices[i].x + ((variability * Math.random()) - (variability / 2)), this.starSphere[this.starSphere.length - 1].geometry.vertices[i].y + ((variability * Math.random()) - (variability / 2)), this.starSphere[this.starSphere.length - 1].geometry.vertices[i].z );
- addしています
this.starSphere[this.starSphere.length - 1].add(plane);
- 子を親に加えた後は親のオブジェクトをシーンに加えます
this.scene.add(this.starSphere[this.starSphere.length - 1]);
球体はあくまでも軸としているだけなのでMaterialは不要と思っていましたが。
やり方の問題かもしれませんが、子の星を追加していない状態ならば何もレンダリングされないようなのですが、Material未指定のPointsを利用したところ球体の頂点が青白い点でレンダリングされてしまいました。
this.starSphere.push(new THREE.Points( new THREE.SphereGeometry(200, particleSize, particleSize) ));
透明のMaterialを利用することで回避しました。
this.starSphere.push(new THREE.Points( new THREE.SphereGeometry(200, particleSize, particleSize), new THREE.PointsMaterial({transparent: true, opacity: 0}) ));
Raycasterでマウスに反応するようにしてみました
マウスに流れ星以外の星が重なると色が変わり回転が速くなります。
- マウスが動いたら位置を記録
this.renderer.domElement.addEventListener('mousemove',function(e){ this.mouseVector2.x = (e.clientX / this.renderer.domElement.width) * 2 - 1; this.mouseVector2.y = -(e.clientY / this.renderer.domElement.height) * 2 + 1; }.bind(this), false);
- マウスに重なった星
intersects
を取り出して処理
※この際、個々の星の色を変えるためにmaterialをclone()しています。同じマテリアルだと同じマテリアルを利用している星全ての色が変わってしまいます。
var checkMouseMove = (this.mouseVector2.x >= -1 && this.mouseVector2.x <= 1 && this.mouseVector2.y >= -1 && this.mouseVector2.y <= 1); if (checkMouseMove) { this.raycaster.setFromCamera(this.mouseVector2, this.camera); } for (var i = this.starSphere.length - 1; i >= 0; --i) { : if (checkMouseMove) { var intersects = this.raycaster.intersectObjects(this.starSphere[i].children); if (intersects.length > 0){ for (var j = intersects.length - 1; j >= 0; --j) { var add = this.localAddZ[intersects[j].object.geometry.id]; intersects[j].object.rotation.z += add > 0 ? 0.15 : -0.15; intersects[j].object.material.color = this.starMaterialMouseenterColor; intersects[j].object.scale.set(1.5, 1.5, 1); } } } }
Raycasterの使い方についてはドキュメントにあるExampleを参考にしています。
https://threejs.org/docs/api/core/Raycaster.html
フレームレートは 30 fps にしています
Firefox 50.0.2 だと次のような警告が出力されます。
Error: WebGL: texImage2D: Incurred CPU-side conversion, which is very slow. Error: WebGL: texImage2D: Incurred CPU pixel conversion, which is very slow. Error: WebGL: texImage2D: Chosen format/type incurred an expensive reformat: 0x1908/0x1401
Firefoxの問題のようです。
https://bugzilla.mozilla.org/show_bug.cgi?id=1246410
requestAnimationFrame()
を利用すると 60 fps になるそうですが、処理の負荷軽減になるかと思い 30 fps になるようにしました。
- レンダリングされる頻度を1/2にする
if (this.frame++ % 2 === 0) { this.render(); }
こちらのサイトを参考にしました。
CakePHP2系で指定Exceptionのログ出力を抑制する
環境は PHP 5.6.24, CakePHP 2.7.11
コード
- 例えば
MissingControllerException
の出力を抑制するなら、app/Config/core.php
に、'skipLog' => ['MissingControllerException']
を加える。
Configure::write('Exception', [ 'handler' => 'ErrorHandler::handleException', 'renderer' => 'ExceptionRenderer', 'log' => true, 'skipLog' => ['MissingControllerException'] ]);
参考サイト
- 初めにたどり着いたサイトはCakePHP3系用だったので書き方が少々異なりました。
- 更に調べたところCakePHP2系のものにたどり着きました。