クッキーもぐもぐ

PC関係とか映画とかゲームとかの

サイボウズの研修資料が素晴らしい件について

 

先日、サイボウズがエンジニア関係の研修資料を公開した。

webの基礎知識からサーバーまで入門にはとても幅広く、そしてある程度詳しく書いている。こういうまとまった知識が手軽に見れるのは非常にありがたい。

 

blog.cybozu.io

 

とくにwebアプリケーション、HTTPSのスライドが参考になったので、ここに載せておきます。(他のどれも素晴らしい)

speakerdeck.com

 

speakerdeck.com

web関係に関する知識を再復習してみる(スライドリンクあり)

 

 概要

先日親友がweb関係のスライドリンクを教えてくれたので(感謝しかない・・・!)、復習をかねて勉強

 

ぶっちゃけスライドを見るのが一番わかりやすいのだけど、自分なりに抑えておきたい所をメモ&まとめてみた

 

 

speakerdeck.com

 

アプリ、ソフトウェアって何? 違いは?

→ハードウェアのような物理ではなく、その中で動くプログラム
 
各アプリの総括、ハードウェアを大きくマネジメントするのがOS
それ以外は用途によってアプリだったり、ソフトだったり、要は用途によって名前が変わるだけで大まかな意味合いは同じ
(ソフトもアプリも明確な境界線はない)
EX ブラウザ上で動くソフトはwebアプリ
 
 

ライブラリとフレームワークって何? 違いは?

→テンプレ部品、フレームワークはライブラリの一種

f:id:christmas-cookies:20180820154652p:plain

 
 
 

クライアントについて

サーバーに対するクライアントは、ブラウザのイメージがあるものの
要はサーバーにリクエストを送るやつなので、lineなどのアプリも含まれる
 
 
 
 

サーバについて

いろいろサーバがあるけど、その違いはどんなリクエスト(要求)をうけ、どんな返事(レスポンス)をするか、という所
 
webサーバー
静的(予め作っておいたもの、ページ、画像)を応えるサーバー
コンビニであの商品くれ~っていわれて、はいよ~って渡す感じ
nginx
 
appサーバー
動的(注文をうけてから作成、注文内容によって変わるページ)を応えるサーバー
料理人にこれ作って~って言われて、はいよ~って渡す感じ
 
DBサーバー
在庫+それを出し入れするサーバー
 
検索サーバー
在庫に何があるか、索引を作っておいて管理する所
Elasticsearch
solr
 
関係図

f:id:christmas-cookies:20180820154644p:plain

 
 
簡単な商品の注文だったらWebサーバが、
変化のあるオーダーメイドの注文ならwebサーバがappサーバに頼み、
appサーバーは索引で使ったり、それで在庫から取り出したりして作成して出来たものをwebサーバーに返す
 

ブラウザとアプリの違い

最初の話を挙げるとブラウザもアプリの一種になるので、正確には
ブラウザと、それ以外のアプリの違い
 
ブラウザはレスポンスとしてHTML,CSS、JSなどを全部受けっって表示する
 
アプリはレスポンスとしてJSON(データ)を受け取り、それ以外の表示方法はアプリに任せる
 
ブラウザはレシピも渡されこれ作ってね~
アプリは素材だけ渡してあとは任せるわ~
かな?
 
 

通信と暗号

SSLTLSHTTPSの違いがよくわかってなかったのでメモ
TLS(=昔はSSL)で、TSL+HTTP=HTTPS
 

公開鍵と秘密鍵

ってどっちがどっちで、送信側と受信側がどっちを送るんだっけ・・・ と毎回混乱するやつ。公開鍵というから混乱するねん。

公開鍵=南京錠として、送信側に南京錠をばらまいて、

受け取った自分だけ鍵(秘密鍵)を使って見れるって覚えれば楽になった

 

公開鍵=南京錠、これを配る
秘密鍵=鍵

 

MFA/2FA

認証にパスワード意外にユーザ固有のものを使用する方式(スマホなど
よくスマホに6文字のコード送ったらか、それを確認して入れてね!ってやつ 
 
 
*暗号関係はこのサイトがわかりやすかった
 

 

簡単な線形回帰を実装してみる

前置き

機械学習挫折中です(涙

先日、本を買ってすこし勉強+実装してみました。

今回は回帰の実装。

2次元のサンプルデータを元に、関数を予測するもの

大まかな流れ

  1. 学習データ取得

  2. データの標準化

  3. 予測関数と目的関数を設定

  4. 予測関数はa+bxのパラメータ2つ(パラメータは事前に初期化しておく)

  5. 目的関数は今回は最小二乗法を仕様

6.目的関数を微分した式を元に、パラメータ更新の式を作成(a,bそれぞれに関して)

7.パラメータの更新前後で目的関数を比べ、差が一定以下になるまでひたすら更新していく

8.最終的なパラメータを元に、予測関数を決定、グラフに表示 (今回は評価はしない)

書いたコード

import numpy as np
import matplotlib.pyplot as plt

#パラメータ初期化
theta0 = np.random.rand()
theta1 = np.random.rand()

#予想関数
def predict_f(x,theta0,theta1):
    return theta0+theta1*x

#目的関数
def E(x,y,theta0,theta1):
    return 0.5*(np.sum(y-predict_f(x,theta0,theta1))**2)

#標準化
def zscore(x):
    mu = x.mean()
    sigma = x.std()
    return (x - mu)/sigma

def predict_theta(train_z,train_y,theta0,theta1):
    
    #誤差の計算
    error = E(train_z,train_y,theta0,theta1)

    #パラメータ設定
    ETA = 1e-3 #学習率
    diff = 1 #誤差の差分の初期値
    count = 0 #更新回数初期化
    while diff > 1e-3:
        #更新パラメータを求める     
        tmp0 = theta0 - ETA*(np.sum(predict_f(train_z,theta0,theta1)-train_y))
        tmp1 = theta1 - ETA*(np.sum((predict_f(train_z,theta0,theta1)-train_y)*train_z))

        #パラメータの更新
        theta0 = tmp0
        theta1 = tmp1

        #更新後の誤差を求める
        current_error = E(train_z,train_y,theta0,theta1)

        #誤差がどれだけ変わったか
        diff = error - current_error
        error = current_error
        count += 1

    
    return theta0, theta1


#学習データ読み込み
train = np.loadtxt("click.csv",delimiter=',',skiprows=1)#delimiter区切り文字指定,skiprows n行目まで飛ばす
train_x = train[:,0]
train_y = train[:,1]

#データの正規化
train_z = zscore(train_x)

theta0,theta1 = predict_theta(train_z,train_y,theta0,theta1)

print (theta0)
print (theta1)
x = np.linspace(-3,3,100)
print (predict_f(x,theta0,theta1))
#plot

# plt.plot(train_x,train_y,'o')
plt.plot(train_z,train_y,'o')
plt.plot(x,predict_f(x,theta0,theta1),'o')
plt.show()

まとめ

結果はこんな感じでちゃんと予測できている f:id:christmas-cookies:20180819223942p:plain

更新回数(diff)よりも学習率ETAが大きく結果に影響していると、触ってみてわかった。

今後は重回帰のようもやっていきたい

GCE: Flask + uWSGI + nginx でhello world表示

前置き

先日作ったGoogle Cloud Engine(GCE)にFlaskを使って"Hello world"を表示させた

その手順、メモ、学んだことをここに書く

独学なので結構間違えてることも、あるかも・・・?

環境

参考

以下のサイトを主として参考にさせて頂いた

Flask + uWSGI + Nginx でハローワールドするまで @ さくらのVPS (CentOS 6.6)

【Pythonで多分人気2位のWebアプリケーションフレームワーク】Flaskの基本をわかりやすくまとめる

Ubuntu 16.04 で Flask アプリケーションを動かすまでにやることまとめ

大まかな手順

  • 各機能の役割についてメモ
  • flaskのインストール、疎通確認
  • nginxのインストール 、疎通確認
  • uWSGIのインストール
  • 各種設定、疎通確認

各機能の役割について

サーバーは、OSという脳みそとフレームワークという雑務処理みたいなのがいれば、最低限機能する

イメージ

Framework <-> Client(ユーザ)

ユーザからhttp(https)で、リクエスト(これくれ~)がきたとき、応じて適切なものを上げる。
ユーザはそれを受け取ってブラウザで表示する。
だけどFramework(とくにFlaskのような小規模むけのもの)だけだと同時多数のアクセスには対応できない。
一度に大量の受付を処理できずパンクしちゃう。

f:id:christmas-cookies:20180813190821p:plain

そこでユーザとフレームワークの間に入って受付担当してくれる仲介人を入れておけば、同時アクセスにも対応できるようになる。
それがwebサーバー。nginxやapacheとか。
フレームワークとwebサーバーもいろいろ種類があるので、その相性をよくするため、さらに間に入って仲介してくれるものをいる。
それがWSGI(uWSGIとの違いがよくわからなかった・・・すいません)
これで大量の同時アクセスにも対応できるようになる。

f:id:christmas-cookies:20180813190901p:plain

Framework <-> uWSGI <-> Web Server <-> Client(ユーザ)

nginx, uwsgiについての参考サイト

【Django入門】Nginxを使ってWebサーバーを動かそう | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト

WSGI(Web Server Gateway Interface)の役割

なので始めはフレームワークをインストール+表示(疎通)確認。

次にnginxをインストール+疎通確認

uwsgiをインストール

最後に各設定ファイルを作成し、flask<->uwsgi<->nginxで疎通確認を行う。

ちなみにGCEの場合、VMインスタンスで「ブラウザウィンドを開く」を選択し、そこにコマンドを打っていけばOK。

f:id:christmas-cookies:20180813191345p:plain

flaskのインストール、表示テスト

OSにFlaskを入れる。
Flaskは言語がpythonなので、まずpython,pipを入れる。

ubuntuではインストールにaptコマンドを使う。
aptとはubuntuのパッケージ管理。

[Ubuntu] apt-get まとめ

まずは既に入っているパッケージのアプデと内容確認

apt update #パッケージリストの更新
apt upgrade #インストールされてるパッケージの更新
dpkg -l #インストールされてるパッケージの一覧

確認したあと、pythonとpipを入れる。
pythonはver3。
pipとは、pythonのパッケージの管理システム。
なのでubuntu全体に関するものはaptで、python関係はpipでインストールしていく。

ちなみにGCEでubuntuだとpythonははじめから入っている。
入っていなければ以下で入れる。

apt install python3 #python3のインストール
apt install python3-pip #pipのインストール
pip3 install flask #flaskのインストール

これでフレームワークのインストールは終わり。
とてもシンプル。

試しに簡単な表示を行う。

今回はhomeフォルダの下にgacha_yosoというフォルダを作成し、その下にapp.pyを作った。 (プロジェクトフォルダの場所、名前、app.pyの名前は自由)。

cd /home #ホームへ移動
sudo mkdir gacha_yoso #フォルダ作成
cd gacha_yoso #フォルダ移動
sudo touch app.py #ファイル作成
sudo vi app.py #vimでファイル編集

app.pyには以下の内容を入れる。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "hello world"

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=80)

ここでちょっとvim関係のメモ

iでインサートモード
vimでペーストする場合、windowsからだとshift+insertでペーストできる
:wq で保存、終了

sudo vi でvimにしておかないと権限でうまくいかない
単純なvi でやった場合、:w,:qに以下を追加することで強制的に書き込みできる
:w !sudo tee % :q!

viコマンド基本

【touch】Linuxで新規ファイル作成をするコマンド | UX MILK

クリップボードを経由する貼り付け方法 < 全般 < 初級編 | viエディタ入門

権限

書き込み権限のないユーザでファイルを編集してしまったとき Can't open file for writing - MEMOcho-

ポイントなのが

 app.run(host="0.0.0.0",port=80)

のところ。
ローカルで確認ならば、app.run()でOKなのだがflaskはデフォルトで外部サイトに公開していない設定+portが5000なので
host="0.0.0.0"で外部にも公開ですよ~
port=80でポート80で公開ですよ~ 
と指定しやる(GCEはpoort80が開放されている

この設定により、flaskだけで簡易的なサーバーが完了する

ちゃんと設定がうまくいているか確認する

sudo python3 app.py

これで起動
この状態で

http://xxxxx:80 (xxxはGCEで設定したIPアドレス

にアクセスし、

hello world

と表示されればOK。(スマホからも表示されるのはちょっと感動^^

終了に関するメモ
ちなみにctrl+cでpythonを終了できるが、うまく終了できない場合があった。
そういうときは

ps -fA | grep python

でむだなpythonプロセスが動いてないか確認。

app.py~ のように表示されてて、まだ動いているようであれば、プロセスIDを控え
sudo kill -9 プロセスID

で強制的に終了させられる

Nginxインストール

apt install nginx

これだけ

試しに
http://xxxxx(xxxはGCEで設定したIPアドレス にアクセスし、welcome to nginx 的な表示がされればちゃんとwebサーバーが入っているはず。

uWSGIインストール

uWSGIをインストールする。
参考にしたサイトではaptではなくpip経由が多かった。

pip3 install uwsgi

これでOK

各疎通テスト

flaskでの疎通確認をした
nginxでの疎通確認もした

つまり

flask<->cliant
nginx<->cliant

がOK

ここでnginx、uwsgiの設定ファイルを作成することで
flask<->uwsgi<->nginx<->cliantを実現させる

まずnginxの設定
簡単にいうと/etc/nginx/下に設定を作成する
実は設定ファイルを置く場所が複数あってややこしい(別記事で詳しく書く予定)
centosだとconf.d下に設定ファイルを置く
ubuntuだとsites-available下にファイルをおき、sites-enabledにそのショートカットを作っておく

参考 nginxでsites-availableとsites-enabledを用いたバーチャルホストの設定 - YoshinoriN's Memento

├── conf.d
│   └── default.conf←centosはここに設定ファイル
├── nginx.conf
├── sites-available←ubuntuはここに設定ファイル*
│   └── default
└── sites-enablede←*ここにそのショートカット
    └── default
cd /etc/nginx/sites-available #移動
sudo touch uwsgi #名前はなんでもよい
sudo vi usgi

ファイルの中身は以下のようにすればOK

server {
    listen       80;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
}

簡単に説明すると、nginxにきたアクセスはuwsgiに任せるで~という指示が書いてある
(つまり、nginxに情報がきたら(httpによるアクセス)、uwsgiに担当させるで~

sites-enabledeフォルダに今作ったファイルのショートカット(正確にはシンボリックリンク)を作る

ls -s リンク元ファイル ショートカット先

今回だと

ls -s /etc/nginx/sites-available/uwsgi /etc/nginx/sites-enablede/uwsgi 

sites-enabledeのdefaultは削除しておく

cd  /etc/nginx/sites-enablede
rm default

これにより、元はsites-enabledeのdefaultショートカット=sites-availableのdefaultを参照だったのが、
sites-enabledeのuwsgiショートカット=sites-availableのuwsgiを参照するようになった

ちなみに、そのファイガシンボリックリンクかどうかは

ls -l

で確認できる

あとはnginxを再起動して設定ファイル

systemctl restart nginx.service #nginx再起動
sudo nginx -t #nginx自体に問題ないか確認

これでsuccessfulみたいな言葉がでればOK

ちなみに

systemctl enable nginx #自動的に起動
sudo service nginx stop #停止

次にuwsgiの設定 uwsgi自体は

uwsgi  (いろんなパラメータ設定の引数)

で起動できる。
けど毎回、パラメータを書いて起動するのはめんどくさい。
そこでパラメータをまとめてかいた設定ファイルをしておき、

uwsgi (設定ファイル読み込み)

として起動させるようにする。
設定ファイルはflaskのプロジェクトフォルダに作る

cd home/gacha_yoso #移動
sudo touch myapp.ini #ファイルの名前はなんでもよい
sudo vi myapp.ini

ファイルの内容

[uwsgi]
module = app
callable = app
master = true
processes = 1
socket = /tmp/uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true

moduleはモジュール、つまりflaskで作ったapp.pyのファイル名
socket はnginxで書いたソケット
これでuwsgi<->nginxがつながる

これで

uwsgi --ini myapp.ini

によって、uwsgiを起動(+設定ファイル読み込み)できる

この状態で http://xxxxx にアクセスすると、python3 app.pyと指定なくてもhello worldと表示されるはず。

ここでwelcom to nginxと表示された場合
nginx<->uwsgi間の設定がうまくいっていない可能性がる。

ちなみに、これでうまく言っている場合、app.pyの app.run(host="0.0.0.0",port=80)はrun()にしてOK。

まとめ

ubuntu+flask+uwsgi+nginxの環境構築を行い、hello worldを表示させた

やったこと自体はfalsk,uwsgi,nginxの各インストール、設定ファイルの作成

インストールはどれも1行で終わる

設定ファイルはnginxだけ気をつける(OSによって変わる)

実行内容じたいはとてもシンプルだが、結構ハマりやすい要素が多く、各項目において確認する作業が大事だと痛感

今後

sshの設定とかgit cloneでファイルをごそっと持ってきたりしたい

Google Cloud Platformで仮想サーバを立ててみる

概要

  • Google Cloud Platform(GCP)を利用した、 Google Compute Engine(GCE:仮想サーバー)を立ててみる

  • しかも利用条件をみたせば無料でずっと使える

  • ようは無料でずっとサーバーをレンタルできるよ

方法

以下のサイトが詳しく丁寧に説明してくれてる。

スペックによっては無料じゃなくなってしまうので、間違わないように選択すること

ちなみに今回OSはubuntu18を選択した

いつでも無料!Google Compute Engine 常時無料枠の使い方 | あぱーブログ

GCEで事前準備(SSHでサーバー接続するまで編) - ゼロからWeb開発

注意すべきこと

スペック意外にもIPアドレスに注意

固定IPアドレスはひとつなら無料。ただしインスタンス削除後にその固定IPアドレスがどこにも割り当てられず、宙ぶらりんになると課金。 インスタンス削除後は必ず静的IPアドレスを削除!

つまり固定のIPアドレスを取得しておきながら、サーバー自体を削除して使ってない状態を作ると課金される

なのでサーバーを削除したあとは、しっかり固定IPも削除(開放)すること。

しっかり注意したい

Flask: pythonの変数をhtml(javascriptにも)わたす方法

目的

前回はpost通信によりhtmlからpython側に変数をわたした

今回はpythonで指定した変数を、htmlないしjavascriptにわたす方法をメモ

流れ python->htmlの場合

python側は以下にしてhtmlへ変数を渡す

return render_template(○○.html,変数名=渡したい中身)

html側は以下にしてpythonから受け取り、表示できる

<p>{{変数名}}</p>

シンプル

@app.route("/")
def hello():
    tmp = 1+2
    return render_template('test.html', result = tmp)
<p>結果は{{result}}です</p>

→「結果は3です」と表示される

流れ python->javascriptの場合

python側は同じ

return render_template(○○.html,変数名=渡したい中身)

html側はjavacript内で以下にして取り出す

var jsでの変数名 = {{ 変数名|tojson }};

ポイントは|tojsonを追加することでjson形式でpython<->jsのデータのやり取りを可能にしてるらしい

参考

javascript - pythonの変数をjavascriptで受け取るには? - スタック・オーバーフロー

例(Chart.js

実際にpythonで作った変数(リスト)をchart.jsの結果として流用した

chart.jsでdata : [x,x,x,x,・・・]と記述するところを

var result = {{ result|tojson }};
//略
data: result,

でリスト(配列?)のままデータ指定できた

 

まとめ

hmtl->pythonに引き続き、

python->html,js の渡す方法をメモ

今は

hmtl->python 計算->html,jsへ

としているけど、これが複雑な計算とか情報として蓄積したい場合は

hmtl->python ->DBへ格納、計算->DBから取り出す->html,js

みたいな感じになるんだろうね

Flaskでjavasript導入(chart.js)方法

大まかなまとめ

  • URL参照からjsを呼ぶ方法

  • ローカルフォルダからjsを呼ぶ方法

URL参照の場合

呼び出しはhtmlのの中に

<script src="呼び出したいjavasripctの該当url"></script>

を入れるだけ

ローカルフォルダから呼び出す場合

templatesと同じ階層に「statics」という名前のフォルダ作成→そこにサイトからDLしたjsやcssを入れていく

呼び出しはhtmlの内で

<script src="{{url_for('static', filename='使いたいファイル名.js')}}"></script>

参考

[Python] Flask 入門 - ゾンビでもわかるPythonプログラミング

 

Chart.js導入時にここがハマったよ

グラフ表示の王道js, Char.jsを導入しようとしたけど中々うまく表示できなかった

問題点

  1. そもそも表示されない

  2. 表示されてもグラフがバカでかい

解決

1→chart.jsにはv1とv2がある。いろんなサイトを参考にすると1,2の記述が混在して、エラーにより表示されなくなる

→2を使うように意識

2→デフォでレスポンスシブがonになってたので、サイズを指定しても画面いっぱいに表示された

→そこでoffにし、サイズ指定で解決

  <canvas id="ChartDemo" width="400" height="400"></canvas>

    options: {
      responsive: false,
    }

参考

Chart.jsを使ってグラフを描画する方法