技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Python3 で負荷テストを簡単に

for Python 3.7.x

テスト対象のサーバを起動する

require: Docker version 19.03.+

docker-compose.yml にざっくり記述。

version: "1"

services:
  wordpress:
    image: wordpress:latest
    ports:
      - 9000:80
    links:
      - wordpress-db
    environment:
      WORDPRESS_DB_HOST: wordpress-db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: database_password

  wordpress-db:
    image: mysql:5.7
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: database_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: database_password

今回はテスト対象サーバとして、Wordpress を用意しました。
対象の設定はこのディレクトリにある docker-compose.yml で、次のコマンドで起動します。

$ docker-compose up --detach

http://localhost:9000 にアクセスすると、Wordpress のセットアップが見れるはずです。
適当にセットアップしてしまいましょう。

ID/Password はこのとき控えておいてください。

[f:id:white-azalea:20191002221611p:plain] [f:id:white-azalea:20191002221629p:plain] [f:id:white-azalea:20191002221646p:plain]

ついでにログインできることも確認しましょう。

[f:id:white-azalea:20191002221702p:plain] [f:id:white-azalea:20191002221719p:plain]

LOCUST インストール

Python 用の負荷テストツールをインストールします。
これもライブラリとして配布されてますので、pip からインストールできます。

$ sudo pip install locustio

このツールはインストール時にコマンドも入るので、確認してみます。

$  locust --version
[2019-10-02 21:12:48,992] anyone-macbookpro.local/INFO/stdout: Locust 0.11.0
[2019-10-02 21:12:48,992] anyone-macbookpro.local/INFO/stdout: 
続きを読む

瞬間 HTTP サーバ

for Python 3.7.x

HTTP サーバを単独起動

Python には HTTP サーバがデフォルトで樽座しています。
あらかじめ example/index.html を用意しておきます。

その上で

$ cd example
$ python -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)

後は Chrome でアクセスしてみます。

f:id:white-azalea:20191001215112p:plain

死ぬほど簡単でしょう?

プログラムで実行

プログラムからも指定して起動することもできます。

import http.server
import socketserver

PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("Start server at: ", PORT)
    httpd.serve_forever()

Python 3.x でのシェルとの共存

Python3.7.x で動作確認。
ちまちま記事を追加中。

github.com

シェルとの相互運用周りを行うサンプルです。

Python のシェルライク起動

Pythonpython コマンド引数でなく実行する方法です。
先頭に #!/usr/bin/python を突っ込んで実行権限を与えます。

#!/usr/bin/python
print('fire')

この状態で実行権限を付与して実行します。

$ chmod +x hello.py
$ ./hello.py
fire

パイプから呼び出す処理を作成する

パイプから呼び出される際、その値は標準入力から設定されます。
注意点として、ある程度まとまった結果を標準入力でまとめて受け流という点です。

サンプルとして simple.py を用意しました。

#!/usr/bin/python
import os
import sys

value = sys.stdin.read()  # パイプの入力
value = value.replace('//', '/')  # / が // として入力されるのでリプレース

splitted = value.split("\n")  # 改行で分解し
for line in splitted:
    if os.path.isfile(line):  # それがファイルで
        filename, ext = os.path.splitext(line)
        if '.txt' == ext:  # 拡張子が txt なら中身を表示します
            with open(line, mode='r') as rf:
                print(''.join(rf.readlines()))

そして実行してみる。
1行目はファイル構成。この値が標準入力に入ってきます。

$ find ./sampleTexts/
./sampleTexts/
./sampleTexts//dontcall.md
./sampleTexts//example.txt
$ 
$ chmod +x simple.py
$ find ./sampleTexts/ | ./simple.py 
Hello python: shell command.

Python からシェルコマンドを実行する

一番わかりやすいところで ls コマンドをサブプロセスとして呼んでみます。
shell_command.py というファイル名で作成してます。

#!/usr/local/bin/python3
import subprocess
proc = subprocess.run(["ls"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(proc.stdout.decode("utf8"))

単純にパイプを呼び出す

パイプを実行するもっともシンプルな方法。
simple_pipe.py として保存。

#!/usr/local/bin/python3
import subprocess

res = subprocess.check_output(
    "ls | grep si",
    shell=True,
    stderr=subprocess.STDOUT)

print(res.decode())

Python からパイプを実行してみる

といってもパイプのアウトプットを連結するだけです。
途中に Python 処理を挟みたければ挟めば?って用途ですね。

pipe_basic.py として用意します。

#!/usr/local/bin/python3
import subprocess

p1 = subprocess.Popen(["ls"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "py"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()

result = p2.communicate()[0]
print(result.decode())

第二言語としての Python ススメ

こんなものを記述中。

github.com

この後は、統計/データサイエンス基礎/機械学習 とかそちらに向かう予定です。
ツッコミや、第二言語としてなら「こんな用途書いてくれ」てのあればカモン

Salesforce World Tour Tokyo 2019

ということで行ってきました

www.salesforce.com

このカンファレンスでは、ルーム付きセッションではまず間違いなく同時通訳があるという素敵仕様。
イベントを詰め過ぎて、ブースの類はほぼ回れなかったのだけど…

ちなみにまとめるのも面倒なので、当時のメモを直接公開。

第四次産業革命時代モビリティ市場の創出に向けて

世界経済フォーラムではガバメントが第四次産業革命にアップデートできてない。 ただし何がベストプラクティスはなくて真似ができない。 データガバナンス(データは誰のものか?)に結論をまずだそうといてる。

地方のモビリティの現状。
地方は、アクセスだけでも車がないと殆ど移動ができない。
数少ないバスが生命線。これは自治体から考えてもかなり厳しい。
鉄道も利益率 -80% なんて数値もざらで、経営改善でもどうにもならない。
これは鉄道に限らず、収益性の面で厳しい。タクシーすらドライバー不足なんかが深刻。 だがこれも技術で転換するチャンスが出てきた、自動運転など。

マッキンゼーアンドカンパニー、第四時産業革命センタ共同でここにアサインしてる。

続きを読む

データサイエンスの勉強(データをざっくり眺める)

データサイエンスの育成講座(3) - 技術をかじる猫 この辺の続き

データダウンロードと解凍

ファイルのダウンロードと解凍…って何回やるかは不明だが。

import requests, zipfile
from io import StringIO
import io

target_url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/00356/student.zip'
req = requests.get(target_url, stream=True)

zip_val = zipfile.ZipFile(io.BytesIO(req.content))
zip_val.extractall()

ファイルの読み込み

import numpy as np
import numpy.random as random
import scipy as sp
import pandas as pd
from pandas import Series, DataFrame

student_data_math = pd.read_csv('student-mat.csv')
student_data_math.head()
school;sex;age;address;famsize;Pstatus;Medu;Fedu;Mjob;Fjob;reason;guardian;traveltime;studytime;failures;schoolsup;famsup;paid;activities;nursery;higher;internet;romantic;famrel;freetime;goout;Dalc;Walc;health;absences;G1;G2;G3
0 GP;"F";18;"U";"GT3";"A";4;4;"at_home";"teacher...
1 GP;"F";17;"U";"GT3";"T";1;1;"at_home";"other";...
2 GP;"F";15;"U";"LE3";"T";1;1;"at_home";"other";...
3 GP;"F";15;"U";"GT3";"T";4;2;"health";"services...
4 GP;"F";16;"U";"GT3";"T";3;3;"other";"other";"h...

え!?
まさか…

student_data_math = pd.read_csv('student-mat.csv', sep=';')
student_data_math.head()
school sex age address famsize Pstatus Medu Fedu Mjob Fjob ... famrel freetime goout Dalc Walc health absences G1 G2 G3
0 GP F 18 U GT3 A 4 4 at_home teacher ... 4 3 4 1 1 3 6 5 6 6
1 GP F 17 U GT3 T 1 1 at_home other ... 5 3 3 1 1 3 4 5 5 6
2 GP F 15 U LE3 T 1 1 at_home other ... 4 3 2 2 3 3 10 7 8 10
3 GP F 15 U GT3 T 4 2 health services ... 3 2 2 1 1 5 2 15 14 15
4 GP F 16 U GT3 T 3 3 other other ... 4 3 2 1 2 5 4 6 10 10

5 rows × 33 columns

CSV じゃねーのかよ!?

気を取り直して、情報の状態。
各データ型とどれくらいデータが詰まってるか?(null フィールド検出)

student_data_math.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 395 entries, 0 to 394
Data columns (total 33 columns):
school        395 non-null object
sex           395 non-null object
age           395 non-null int64
address       395 non-null object
famsize       395 non-null object
Pstatus       395 non-null object
Medu          395 non-null int64
Fedu          395 non-null int64
Mjob          395 non-null object
Fjob          395 non-null object
reason        395 non-null object
guardian      395 non-null object
traveltime    395 non-null int64
studytime     395 non-null int64
failures      395 non-null int64
schoolsup     395 non-null object
famsup        395 non-null object
paid          395 non-null object
activities    395 non-null object
nursery       395 non-null object
higher        395 non-null object
internet      395 non-null object
romantic      395 non-null object
famrel        395 non-null int64
freetime      395 non-null int64
goout         395 non-null int64
Dalc          395 non-null int64
Walc          395 non-null int64
health        395 non-null int64
absences      395 non-null int64
G1            395 non-null int64
G2            395 non-null int64
G3            395 non-null int64
dtypes: int64(16), object(17)
memory usage: 102.0+ KB

質的データ

数値化されていない不連続値データ。状態を表す。

# 質的データ:連続的なあたいのデータで、比率に意味がある
student_data_math['sex'].head()
0    F
1    F
2    F
3    F
4    F
Name: sex, dtype: object

量的データ

数値化されたデータ。比率などに意味を持つ。

student_data_math['absences'].head()
0     6
1     4
2    10
3     2
4     4
Name: absences, dtype: int64

軸別に平均値を出す

といってもそのままですね

S¯=1Ni=1N(xix¯)
student_data_math.groupby('sex')['age'].mean()
sex
F    16.730769
M    16.657754
Name: age, dtype: float64
続きを読む