OmniAICreator/Qiita-1.07M huggingface dataset:
Python の gRPC で Redis のデータを読む (Read)

設定ファイル、サーバープログラム、クライアントプログラムの３つが必要です。

設定ファイル

```text:redis_read.proto

syntax = "proto3";

package redis_read;

service Greeter {
	rpc RedisRead (RedisRequest) returns (RedisReply) {}
}

message RedisRequest {
	string key = 1;
}

message RedisReply {
	string str_json = 1;
}
```

サーバープログラム

```py:redis_read_server.py
#! /usr/bin/python
#
#	redis_read_server.py
#
#					Feb/08/2020
# --------------------------------------------------------------
import sys
import redis
from concurrent import futures
import logging

import grpc

import redis_read_pb2
import redis_read_pb2_grpc

# --------------------------------------------------------------
def read_redis_proc(key_in):
	rr = redis.Redis(host='localhost', port=6379, db=0)
#
	str_json = rr.get(key_in).decode ()
#
	return str_json
# --------------------------------------------------------------
class Greeter(redis_read_pb2_grpc.GreeterServicer):

	def RedisRead(self, request, context):
		sys.stderr.write("*** RedisRead ***\n")
		sys.stderr.write("*** key = %s ***\n" % request.key)
		str_out_aa = read_redis_proc(request.key)
		sys.stderr.write(str_out_aa + "\n")
		return redis_read_pb2.RedisReply(str_json=str_out_aa)

# --------------------------------------------------------------
def serve():
	server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
	redis_read_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
	server.add_insecure_port('[::]:50051')
	server.start()
	server.wait_for_termination()

# --------------------------------------------------------------
if __name__ == '__main__':
	logging.basicConfig()
	serve()
# --------------------------------------------------------------
```

クライアントプログラム

```py:redis_read_client.py
#! /usr/bin/python
#
#	redis_read_client.py
#
#					Feb/08/2020
#
# --------------------------------------------------------------
from __future__ import print_function
import logging
import json
import grpc
import sys

import redis_read_pb2
import redis_read_pb2_grpc

# --------------------------------------------------------------
def display_proc(str_json):
	unit_aa = json.loads(str_json)
	str_out = unit_aa['name']
	str_out += "\t"+ str(unit_aa['population'])
	str_out += "\t"+ unit_aa['date_mod']
	print(str_out)
#
# --------------------------------------------------------------
def run():
	key_in = sys.argv[1]
	with grpc.insecure_channel('localhost:50051') as channel:
		stub = redis_read_pb2_grpc.GreeterStub(channel)
		response = stub.RedisRead(redis_read_pb2.RedisRequest(key=key_in))
#		print("Greeter client received aa: " + response.str_json)
		display_proc(response.str_json)
#
# --------------------------------------------------------------
if __name__ == '__main__':
	logging.basicConfig()
	run()
# --------------------------------------------------------------
```

gRPC のコードを作成します。

```bash
python -m grpc_tools.protoc -I. \
	--python_out=. \
	--grpc_python_out=. \
	./redis_read.proto
```

サーバープログラムの起動

```bash
./redis_read_server.py
```

クライアントプログラムの実行

```text
$ ./redis_read_client.py t1854
大野	89612	2003-9-9
```
【初心者用】Linux(Ubuntu18.04)の基本操作・コマンド説明

<!-- # 【初心者用】Linux(Ubuntu18.04)の基本操作・コマンド説明 -->

# はじめに

Linuxに触るのが初めての人向けに，よく使う操作・コマンドを説明する．
本記事は`Ubuntu 18.04`をベースに記載していく．

# 基本操作

| key | 説明 |
|---|---|
|Ctrl+Alt+ t | 新規terminal立ち上げ|
|Windows key+矢印| 作業中のウィンドウを`←：左半分`，`→：右半分`，`↑：全画面`，`↓：もとの大きさに戻す`|
|Windows key+h| 作業中のウィンドウを最小化|
|Windows key+d| 全てのウィンドウを最小化|
|Ctrl+Alt+矢印| ワーススペースを移動|
|Alt+Tab| 起動中の別のアプリに切り替え|
|Shift+Print Screen| 選択部分のスクリーンショットを取る|

# terminalの操作

| key | 説明 |
|---|---|
|Ctrl+Shift+t| terminalのタブ増設|
|Ctrl+Shift+n| terminalの新規増設|
|Ctrl+d | terminalを閉じる|
|Alt+Page up| 次のタブのterminalに切り替え|
|Alt+Page down| 前のタブのterminalに切り替え|
|Alt+数字| 指定のタブのterminalに切り替え|
|Alt+半角| 別のウィンドウのterminalに切り替え|

# 基本コマンド

| key | 説明 |
|---|---|
|ls | 現在のディレクトリ内のファイル・ディレクトリを表示 |
|ll | lsの詳細表示バージョン(`ls -l`と同じ) |
|cd 移動したい所へのパス | 移動したいディレクトリへ移動 |
|mv ファイルかディレクトリ名 移動したい所へのパス | ファイル・ディレクトリの移動 |
|cp ファイルかディレクトリ名 コピーしたい所へのパス | ファイル・ディレクトリのコピー |
|mkdir 作りたいディレクトリ名 | ディレクトリの作成|
|cat ファイル名| ファイルの中身を表示|
|rm ファイル名 | ファイルの削除|
|rm -rf ディレクトリ名| ディレクトリの削除|
|コマンド &#124; grep キーワード| 「コマンド」で画面表示される文のうち，キーワードを含む行のみを表示|
|history | コマンドの履歴を表示|
|find -name 'キーワード'| 検索|
|chmod 数字 パス | ファイル・ディレクトリへの権限付与．詳しくは[後述](#chmod)|
|ip a | 現在の自分のPCのIPアドレスを確認|
|ping IPアドレス | 他のPCに接続確認|
|ssh IPアドレス | 他のPCにアクセス|
|scp パス パス | 他のPCからファイル・ディレクトリをコピー，もしくは他のPCに自分のファイル・ディレクトリをコピー．詳しくは[後述](#scp)|

## chmod

`ll`で表示すると，例えば以下のように表示される

```terminal
合計 60
drwxr-xr-x 8 user user  4096  1月 26 22:14 ./
drwxr-xr-x 4 user user  4096  1月 26 22:14 ../
-rw-r--r-- 1 user user  1567  1月 26 22:14 CMakeLists.txt
-rw-r--r-- 1 user user 11357  1月 26 22:14 LICENSE
-rw-r--r-- 1 user user    33  1月 26 22:14 README.md
drwxr-xr-x 3 user user  4096  1月 26 22:14 include/
drwxr-xr-x 2 user user  4096  1月 26 22:14 launch/
-rw-r--r-- 1 user user   659  1月 26 22:14 package.xml
drwxr-xr-x 2 user user  4096  1月 26 22:14 parameters/
drwxr-xr-x 2 user user  4096  1月 26 22:14 src/
```

これのはじめの部分が現在付与されている権限である．

最初の1文字目は ファイルの種類 を示し，残りは3文字ずつ，読み込み権限(r)，書き込み権限(w)，実行権限(x)を示す．「-」は権限がないことを示す．3文字3セットになっているが，それぞれ所有者，グループ，他人の順で権限を示している．

`chmod`ではこの権限を変更することができ，例えば上のファイルで

```terminal
chmod 777 README.md
```

とすれば，この時，権限は

```terminal
-rwxrwxrwx 1 user user    33  1月 26 22:14 README.md
```

となる．`777`が表すのは，1文字目の`7`は所有者の権限，2文字目の`7`はグループの権限，3文字目の`7`は他人の権限であり，2進数で表される．例えば`654`ならば`rw-r-xr--`，`321`なら`-wx-w---x`となる．

## scp

ファイルを取ってくるときは

```terminal
scp (相手のユーザー名@)IPアドレス:ファイルの絶対パス 自分のPCで置きたい所のパス
```

ファイルを送るときは

```terminal
scp ファイルのパス (相手のユーザー名@)IPアドレス:置きたい所のパス
```

ディレクトリを取ってくるときは

```terminal
scp -r (相手のユーザー名@)IPアドレス:ディレクトリの絶対パス 自分のPCで置きたい所のパス
```

ディレクトリを送るときは

```terminal
scp -r ディレクトリのパス (相手のユーザー名@)IPアドレス:置きたい所のパス
```

この際，自分のPCと相手のPCのユーザー名が同一の場合はカッコを省略できる．違う場合はカッコ内を書く必要がある．

# 参考

[Ubuntu 18.04で使えるキーボードショートカット一覧](https://sicklylife.hatenablog.com/entry/2017/10/16/231442)

[ブクマ必至！Linuxコマンド一覧表【全33種】](https://www.sejuku.net/blog/5465)

[パーミッションなどを設定する！chmodコマンドの詳細まとめ【Linuxコマンド集】](https://eng-entrance.com/linux-command-chmod)

[ls -l」コマンドの表示からファイルの属性を理解しよう](https://www.atmarkit.co.jp/ait/articles/1605/18/news015.html)
CentOS8 サーバー構築（ネットワーク開通とパッケージ更新）

[CentOS8_1]:https://qiita.com/sigenyan/items/f47e460e154d604b2a33
[CentOS8_2]:https://qiita.com/sigenyan/items/de9d60b86e5fdddf712a

## はじめに

[前回][CentOS8_1]、`CentOS8(1905)` をインストールするところまでやりましたが、今回はネットワークを開通させてパッケージ管理 `dnf` でシステムのアップデートまでを実施したいと思います。

## 開いているポートを閉める

とりあえずネットワークを開通するまえに、`SSH`などデフォルトで空いているポートをしめてしまいます。
ネットワーク開通後はもちろん `SSH` で接続できるようにしますが、ちゃんとセキュリティを確保したうえで接続できるようにしたいので、一旦不要なポートは閉めてしまいます。

早速、`firewall-cmd` コマンドで空いているポートを確認します。

```
[root@localhost ~]# firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```

`firewall-cmd` は名前のとおり、ファイヤーウォールの設定を行うコマンドです。
`firewall-cmd --list-all` で、現在の設定を一覧で確認できます。

```
  services: cockpit dhcpv6-client ssh
```

`cockpit` `dhcpv6-client` `ssh` というサービスで規定されているポートが空いています。

`cockpit` は、ブラウザー上でシステムを管理できるツールのようですが、いらないので永久に閉めます。
`dhcpv6-client` は、Ipv6 を利用するならば必要のようですが、とりあえずいらないので永久に閉めます。
`ssh` は、後ほどちゃんと設定してから開けるので、一時的に閉めます。

というわけで、とりあえずすべて削除してしまいます。

```
[root@localhost ~]# firewall-cmd --permanent --remove-service=cockpit
success
[root@localhost ~]# firewall-cmd --permanent --remove-service=dhcpv6-client
success
[root@localhost ~]# firewall-cmd --permanent --remove-service=ssh
success
[root@localhost ~]# firewall-cmd --reload
success
```

```
[root@localhost ~]# firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```

さっぱりしました。

## ネットワークを開通する

ネットワークの設定は、`nmcli` コマンドで行います。
まずは現状の確認。

```
[root@localhost ~]# nmcli device
DEVICE  TYPE      STATE     CONNECTION
ens3    ethernet  切断済み  --
lo      loopback  管理無し  --
```

`ens3` が NICになりますが、見ての通り切断状態なので接続します。

```
[root@localhost ~]# nmcli connection modify ens3 connection.autoconnect yes
```

状態確認。

```
[root@localhost ~]# nmcli device
DEVICE  TYPE      STATE     CONNECTION
ens3    ethernet  接続済み  ens3
lo      loopback  管理無し  --
```

接続しました。
`connection.autoconnect yes` としているので、以後は自動で接続されます。

## パッケージ管理 `dnf` で更新する

`CentOS7` では `yum` を利用してましたが、`CentOS` からは `dnf` らしいです。一応 `yum` も利用できるようですが、`dnf` をラップしているだけのようなので、素直に `dnf` を利用することにします。

システムにインストール済のパッケージを更新します。

```
[root@localhost ~]# dnf update
...
これでよろしいですか? [y/N]:
```

わらわらとリストが出ていて、インストールの是非を問われるので `y` で Enter します。
ちなみに `y` 押すのも面倒くさいという方は `-y` オプションをつけて実行すれば勝手に `y` したことになります。使い勝手はほぼ `yum` と同じようですね。

```
[root@localhost ~]# dnf update -y
```

システムの状態を最新に保って置くためにたまに `dnf update` しておきましょう。
サーバー管理者の方などは勝手にアップデートされると困ることとかあるかもですが、私の場合はあくまでお勉強のために構築していますので、最新に保っておくにこしたことはないという考えです。。

## 今回はここまで

とりあえず、ネットワークは開通しましたがこのあとはユーザー作成したりSSHも接続できるようにせねばなりません。
このあと私がしたいのは、下記のとおりです。

+ `OpenLDAP` をインストールしてユーザー管理を `LDAP` で行う。
+ `SSH` を開通し、`LDAP` アカウントを公開鍵認証でログインできるようにする。
+ メールサーバーを構築する。

ですので、`SSH` で接続できるのはもう少し先ですね～

## 関連記事
+ [CentOS8 サーバー構築（インストール）][CentOS8_1]
+ CentOS8 サーバー構築（ネットワーク開通とパッケージ更新）　**←今回の記事**
+ CentOS8 サーバー構築（Open LDAP インストール）　**←予定**
yarn self updateの方法

Yarn自体をアップデートする方法についてです。

公式の方法です。
` curl --compressed -o- -L https://yarnpkg.com/install.sh | bash`
Reference：　https://classic.yarnpkg.com/en/docs/cli/self-update/

他にもYarnをアンインストールして再度インストールする方法もあります。
OpenCVでOpenVinoの使い勝手が向上してきている

注意：この記事は古くなっています。
最新の状況は随時、ネットワークで検索してください。

pip で openvinoがインストールできるようになっています。
https://pypi.org/project/openvino/

-----------------
## Ubuntu 18, Ubuntu20 でのaptを使うインストール手順
以下のリンクをたどってください。

https://docs.openvinotoolkit.org/latest/openvino_docs_install_guides_installing_openvino_apt.html

## 概要
OpenCVの初期のリリースはIntelによってなされた。その後長いことIntelとは独立な状況が続いたが、近年またOpenCVにIntelが深く関与するようになった。
最近では、Intelが開発したOpenVinoがOpenCVで使いやすい状況になってきている。

OpenVinoとは、既存のフレームワークで学習済みのモデルを、再学習させることなしに軽量化し、ターゲットデバイスでの動作速度の向上させるものです。
そのOpenVinoで軽量化したモデルをターゲットデバイスで実行させる部分が、OpenCVに取り入れられてきた。
そのことをこの記事では述べる。


## [readNetFromModelOptimizer()](https://docs.opencv.org/3.4/d6/d0f/group__dnn.html#ga4f3b552113d2bff48a54e168791c448e)

OpenVinoのmodel optimizer で最適化済みのモデルをOpenCVで推論できるようになっている。

### Model Optimizer を使う利点：
GPUやCPUで学習されたDNNのモデルは、浮動小数点演算をするモデルの場合が多い。Cの浮動小数点演算がdoubleが基本になっていることもあって、倍精度の浮動小数点演算を使っていることが多い。
しかし、深層学習では、FP32,FP16の浮動小数点演算でも十分なことが多い。演算するデータ型のbit幅が少ないほど計算量を抑えこむことができる。しかも、Model Optimizerでは、学習のやり直しが不要なまま、既存の学習結果から、FP32やFP16などのbit幅の少ない学習モデルに変換する。
このことでIntelは、Intelのターゲットデバイス上で、計算量の少ないモデルの実行を可能にしている。そのModel Optimizerで変換済みの学習結果をOpenCVで利用できるようになってきているようだ。


## [Intel® Inference Engine backend (OpenVINO™):](https://github.com/opencv/opencv/wiki/ChangeLog#version420)をサポートするようになってきている。

[cv::dnn::Target](https://docs.opencv.org/3.4/d6/d0f/group__dnn.html#ga709af7692ba29788182cf573531b0ff5)
には、cv.dnn.DNN_TARGET_MYRIAD、cv.dnn.DNN_TARGET_FPGAが含まれている。


## 執筆時点での状況
cv2.dnn.readNetFromModelOptimizer() を使うには、それようにOpenCVしなければならない。
まず、OpenVinoをインストールする。
インストール後にOpenVinoが利用できる環境にしておく。

```
source /opt/intel/openvino/bin/setupvars.sh
```

opencv, opencv-contrib のビルド時にOpenVinoのinference engine を利用できるようにしておくこと。

cmakeを実行してMakefile を作る際に、以下のオプションを有効にしておく。
  -DWITH_INF_ENGINE=ON 
  -DENABLE_CXX11=ON 

OpenCVのWikiにInference Engine を有効にしてビルドする方法が書いてある。
https://github.com/opencv/opencv/wiki/Intel%27s-Deep-Learning-Inference-Engine-backend

## OpenVino 用の pre-trained model をダウンロードするには

https://docs.openvinotoolkit.org/latest/_tools_downloader_README.html

## OpenVino の各モデルのGFlops の値が書かれている。
https://github.com/openvinotoolkit/open_model_zoo/blob/master/models/public/index.md

## PINTO0309 氏によるモデルの情報
OpenVino上で動くモデルについて詳しい。
https://github.com/PINTO0309/PINTO_model_zoo
https://github.com/PINTO0309/OpenVINO-YoloV3

----
## opencv-python-inference-engine で pipでインストールできるようへの試み
https://github.com/banderlog/opencv-python-inference-engine
### pip でインストールできるようになったようだ。
https://pypi.org/project/opencv-python-inference-engine/


----
追記
参考情報
qiita [Note Book : Build OpenCV v4.5.0 backend Openvino](https://qiita.com/jashika/items/cdc610f38bc94feabb2b)
RaspPi3B+でUSBの差し込み場所でデバイス名を固定する

## USBの差し込み場所をメモ

まず、RaspberryPi3B+の4つあるUSBポートにデバイスを差し込む

```
ls -l /sys/bus/usb-serial/devices
```

>total 0
lrwxrwxrwx 1 root root 0 Feb  8 04:34 ttyUSB0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.2/1-1.1.2:1.0/ttyUSB0

`usb1/1-1/1-1.1/1-1.1.2/1-1.1.2:1.0`の部分をメモ

## ルールの編集

/etc/udev/rules.d/ に移動
```
cd /etc/udev/rules.d/
```

```
sudo vi 90-myusb.rules
```

```
ACTION=="add", DEVPATH=="*/usb1/1-1/1-1.1/1-1.1.2/1-1.1.2:1.0/*", SYMLINK+="ttyUSB_Test"
```

OSを再起動する

## 確認

```
ls -la /dev/ttyUSB*
```

> crw-rw---- 1 root dialout 188, 0 Feb  8 04:39 /dev/ttyUSB0
lrwxrwxrwx 1 root root         7 Feb  8 04:39 /dev/ttyUSB_IM315 -> ttyUSB0
golang でファイルアップロードを受けるREST APIサーバを作る

##  概要
goが提供する標準ライブラリを利用して，ファイルをアップロードするエンドポイントを作成した．下記の理由で標準ライブラリを使用することとなり，私のググり力が少ないのか，Qiita等で同じような記事を見つけられなかった．なので詰まったところ等をまとめておきたいと思う．

標準ライブラリ使用の理由
- githubにアクセスできない環境下であること泣
- メンテナンス性
- 自分の理解向上
環境はgo:1.13
## 学んだところ
詳細は次の節ソースコードを読んでください．
###  RESTAPIのURI設計
最初は，`http://localhost:8080/update`というエンドポイントに対してPOSTでアップロードするように指定していた．しかし，URIに対して動詞を設定するのはアンチパターン．なるべくオブジェクトを一意に指定できるようにし，メソッドで対応するのがベターというアドバイスをいただいた．なので，`http://localhost:8080/file` というエンドポイントを指定するよう変更した．
### bufの処理
メモリが溢れないための，一時的保存領域である`buf`という変数は `buf := make([]byte, 100)` という形で宣言されている．またこれにより自動的に100の領域が確保される．次に，`n, err := file.Read(buf)`という部分で，ファイルからバイナリデータを読み込み，戻り値として読み込んだ数(n)とエラーの有無を返してくる．このままbufをファイルに保存する処理を書くと，保存したファイルにゴミが残ってしまった．そのため，得たn でスライスのサイズをちょうど良い数に変更することでこの問題をクリアした．

## ソースコード
```golang:fileupload.go
package main

import(
       "fmt"
       "net/http"
       "encoding/json"
}

func main() {
  http.HandleFunc("/file", handler) 
  http.ListenAndServe(":8080", nil)
}

func fileHandler(w http.ResponseWriter, r *http.Request) {
    // postのみ対応させる
    if r.Method != "POST" {
        http.Error(w, "405 Method Not Allowed", http.StatusMethodNotAllowed)
        return
    }
 
    file, fileHeader, err := r.FormFile("json")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
 
    uploadedFileName := fileHeader.Filename
    // ファイル名が指定したものじゃないとエラーを吐くように設定
    if uploadedFileName != "file.json" {
        http.Error(w, "Invaild file", http.StatusInternalServerError)
        return
    }
 
    saveJSONFile, err := os.Create("./" + uploadedFileName)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
 
    var len int64 = 0
    for {
        buf := make([]byte, 100) // buf を用意するのはメモリ節約のため．
        n, err := file.Read(buf)
        buf = buf[:n]　　　　　　　// sliceをnで制限しないと，ループ終了時の処理でゴミが残りアップロード
        if err == io.EOF {　　　　// ファイルを後で読み込むことができないエラーが発生する．
            buf = buf[:n]
        }
        if n == 0 {
            break
        }
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        saveJSONFile.WriteAt(buf,len)
        len += int64(n)
    }
    saveJSONFile.Close()
    file.Close()
    fmt.Fprintf(w, "success")
}
```

## おわりに
golang を書き始めて4ヶ月くらい経ちましたが，いいですね〜．特にエンドポイント等が書きやすく使い勝手がいいです．昨今はマイクロサービス化して，RESTAPIでサービスを接続する流れになってきていると思いますので，一度勉強しておくと良いと思います．
Mysql2::Error at /auth/twitter/callback Incorrect string value: 【Rails】

#Mysql2::Error at /auth/twitter/callback Incorrect string value:
MtSQLのエラーで、保存する値に絵文字:cake::cake::cake:が含まれていると起きる。

絵文字を扱うことが出来る文字コードは`utf8mb4`だがデータベースに設定されていた文字コードは`utf8`だった。それが原因。

#MySQLに設定された文字コードを調べる
```
$ show variables like "chara%";
```

#文字コードを変更する
MySQLのファイルはルートディレクトリの/etc/my.cnfにある。

```
$ vim my.cnf
```

以下のように`utf8`を`utf8mb4`に変更と追記。

```
[mysqld]
(省略)
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4
```

DBの再起動

```
$ systemctl restart mysqld.service
```

#RailsAppのdatabase.ymlを編集

```yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: 5
  username: root
  password: <%= ENV['MYSQL2_PASSWORD'] %>
  host: localhost
```

`encoding:`の部分を`utf8mb4`に変更する。

#データベースの作り直し
私は既存のデータベースの文字コードを変更したので、データベースも今一度作り直す必要があった。

```ruby

$ rails db:drop
$ rails db:create
$ rails db:migrate
```

当然ではあるが、格納していたデータはすべて消える。マイグレーションファイルは残っているため`rails db:migrate`すればモデルは直ぐに作り直せる。


#参考

https://babiy3104.hateblo.jp/entry/2014/02/13/000219
pipインストールあれこれ

pipのインストール
Pythonをインストールするとpipもインストールされる場合が多いが
pipがインストールされない場合
C:\Program Files\python-3.7.6などで
下記コマンドを実行
python get-pip.py

パス（Path）の確認
Python と pip の確認のため，端末で，次のコマンドを実行．

where py
where pip

python のバージョンの確認
※ エラーメッセージが出ないことを確認．
py --version

pip の動作確認
※ エラーメッセージが出ないことを確認．
pip list


pipでのインストール
パッケージのインストールは、install コマンドで行います。xxxx パッケージをインストールするときは、次のように実行します。
py -m pip install xxxx


不要なパッケージは、uninstall コマンドで削除できます。
py -m pip uninstall xxxx
…
Proceed (y/n)?
 Successfully uninstalled xxxx-0.0.15


pip そのものをアップデートしたい
py -m pip install --upgrade pip
または
py -m pip install -U pip


.whlファイルのありか
Unofficial Windows Binaries for Python Extension Packages
https://www.lfd.uci.edu/~gohlke/pythonlibs/

win_amd64.whlを選択
Python 3.6の場合、cp36‑cp36m、Python 3.7の場合、cp37‑cp37m を選択


主要なパッケージのインストール
py -m pip install tensorflow-gpu torchvision tensorflow tensorboard tables seaborn scipy scikit-learn PyWavelets pytools pandas opt-einsum opencv-python opencv-contrib-python numexpr matplotlib Keras-Preprocessing Keras-Applications imageio h5py gensim face-recognition cupy chainer keras face-alignment scikit-learn scikit-image matplotlib seaborn pandas pillow jupyter pytest docopt pyyaml cython six chainer sympy facenet alignl pandasl nltkl gensim


packageの更新をしたい場合
pip install --upgrade facenet alignl pandasl nltkl gensim pip


packageをどうしても特定のpackageのversionにしたい場合
pip install --upgrade --force-reinstall "numpy_stl-2.10.1-cp37-cp37m-win_amd64.whl"
pip install --upgrade --force-reinstall tensorflow-gpu==2.1.0


pipでキャッシュを無効にしてライブラリを再インストールする
pip --no-cache-dir install -I protobuf==3.11.2
pip --no-cache-dir install -I tensorflow-gpu torchvision tensorflow tensorboard tables seaborn scipy scikit-learn PyWavelets pytools pandas opt-einsum opencv-python opencv-contrib-python numexpr matplotlib Keras-Preprocessing Keras-Applications imageio h5py gensim face-recognition cupy chainer keras face-alignment


pipでいれたパッケージを一括アップデート
更新状況を知りたかったらオプションを追加する
pip list --o
更新あるというパッケージだけが出力される

パッケージのインストール
pip install hogehoge

アップグレードは-Uオプションを付ける
pip install hogehoge -U

アンインストール
pip uninstall hogehoge

pip install pip-review
pipでpip-reviewを入れてから、pip-reviewを実行。

更新があるパッケージを表示
pip-review
微妙に文言は変わるがpip list -oと同じ結果が得られる。
autoオプションを付けると更新があるパッケージを自動的に更新してくれる。
pip-review --auto

インタラクティブに更新を行う場合は--intaractiveオプションを付けて実行。
これは更新する？しない？と聞いてくるので、お好みで更新ができる。
pip-review --interactive
あとはpip-review自体を忘れないようにしないと
ChEMBL webresource clientのインストール

#はじめに
そろそろChEMBLについて勉強しようと思う。手始めにChEMBL webresource clientというPythonのインターフェースを見つけたのでこれをインストールしてみた。

#ChEMBL webresource clientとは
ChEMBLグループによって開発およびサポートされている唯一の公式Pythonクライアントライブラリ。PythonからChEMBLデータや化学情報学ツールにアクセスするのに役立つ。SQLやRESTを知らなくても使える。

#インストール
python3.6のAnaconda仮想環境上で、以下の通りcondaでいけた。

```
conda install -c conda-forge chembl_webresource_client
Collecting package metadata (current_repodata.json): done
Solving environment: done


==> WARNING: A newer version of conda exists. <==
  current version: 4.7.12
  latest version: 4.8.2

Please update conda by running

    $ conda update -n base -c defaults conda



## Package Plan ##

  environment location: /home/kimisyo/anaconda3/envs/chemlearn

  added / updated specs:
    - chembl_webresource_client


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    chembl_webresource_client-0.10.0|           py36_1          89 KB  conda-forge
    easydict-1.9               |             py_0           9 KB  conda-forge
    gevent-1.4.0               |   py36h516909a_0         2.5 MB  conda-forge
    greenlet-0.4.15            |   py36h516909a_0          22 KB  conda-forge
    grequests-0.4.0            |             py_0           6 KB  conda-forge
    requests_cache-0.4.13      |             py_0          16 KB  conda-forge
    ------------------------------------------------------------
                                           Total:         2.7 MB

The following NEW packages will be INSTALLED:

  chembl_webresourc~ conda-forge/linux-64::chembl_webresource_client-0.10.0-py36_1
  easydict           conda-forge/noarch::easydict-1.9-py_0
  gevent             conda-forge/linux-64::gevent-1.4.0-py36h516909a_0
  greenlet           conda-forge/linux-64::greenlet-0.4.15-py36h516909a_0
  grequests          conda-forge/noarch::grequests-0.4.0-py_0
  requests_cache     conda-forge/noarch::requests_cache-0.4.13-py_0


Proceed ([y]/n)? y


Downloading and Extracting Packages
easydict-1.9         | 9 KB      | ##################################################### | 100%
greenlet-0.4.15      | 22 KB     | ##################################################### | 100%
gevent-1.4.0         | 2.5 MB    | ##################################################### | 100%
chembl_webresource_c | 89 KB     | ##################################################### | 100%
grequests-0.4.0      | 6 KB      | ##################################################### | 100%
requests_cache-0.4.1 | 16 KB     | ##################################################### | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: done

```

使ってみた感想はまた別途。

#参考
- https://github.com/chembl/chembl_webresource_client
【hoge, fuga, ...】【foo, bar, ...】の次

名前に意味がないことを示す名前として、日本では hoge, fuga, piyo が使える。
全世界的に foo, bar, baz, ... が使える。
両方とも使ってしまっで困ったので、何を使うのがよいのか調べた。

# 参考文献
* [Wikipedia - メタ構文変数](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E6%A7%8B%E6%96%87%E5%A4%89%E6%95%B0)
* [Wikipédia - Variable métasyntaxique]( https://fr.wikipedia.org/wiki/Variable_m%C3%A9tasyntaxique )
* [metasyntactic variable]( http://www.catb.org/jargon/html/M/metasyntactic-variable.html )
* [Wikipedia - Leesplankje van Hoogeveen
]( https://nl.wikipedia.org/wiki/Leesplankje_van_Hoogeveen )

# 使いやすそうなのをピックアップ

|由来|変数名|感想|
|:--|:--|:--|
|フランスで使われている|`toto`, `titi`, `tata`, `tutu`, `tete`, `tyty`|覚えやすい。便利。|
|オランダの子供の綴の練習|`aap`, `noot`, `mies`, `wim`, `zus`, `jet`, ...|オランダ語としてはわりと意味があるらしい。|

`aap`, `noot`, ... はオランダ語がわからない人には無意味感が強い綴だけど、オランダ語ではわりと意味があるのでオランダ人と仕事をする場合は要注意か。

## ちなみに

`aap`, `noot`, ... は下表の通り全部で17個ある。
全部意味を調べたけど、意外と意味がわからなかった。

|オランダ語|日本語または英語訳|
|:--|:--|
|aap|猿|
|noot|note|
|mies|❓|
|wim|❓|
|zus|姉妹|
|jet|ジェット|
|teun|援助、助け(aid)|
|vuur|火|
|gijs|❓|
|lam|ラム(lamb)|
|kees|❓|
|bok|オスのヤギ|
|weide|❓|
|does|❓|
|hok|かご(cage)|
|duif|鳩|
|schapen|羊(sheep)|

# というわけで

* `hoge`, `fuga`, ... も `foo`, `bar`, ... も使ってしまってもう一つ系列が欲しい場合は
* 6個以下なら `toto`, `titi`, ... がファーストチョイスかな
* 最初から 14個以上必要だとわかっていたら、`hoge`, ... や `foo`, ... を飛ばして最初から `aap`, `noot`, ... でも悪くない。
Xcode11で、Distribute時のRubyのエラー：ipatool JSON: (null)

# ipatool JSON: (null)

XcodeでアドホックまたはエンタープライズでDistributeをしようとしたら、以下のようなエラーが出てディストリビューションアシスタントがエラーをはいた。

```
...
 2020-02-07 01:53:07 +0000  ipatool JSON: (null)
 2020-02-07 01:55:20 +0000 [MT] Canceled distribution assistant
```

# 解決方法
Rubyのバージョンが問題らしい
システムのRubyを使用するように変更

```
rvm use system
```

↑を実行したら、Xcodeを再起動すると治る。


参考： https://stackoverflow.com/questions/48698874/react-native-ios-signature-export-ipa-file-error-the-data-couldn-t-be-read-beca
#Docker hub から  pull するときのメジャー・マイナー・パッチバージョン指定 

https://hub.docker.com/_/alpine

ゆるい指定をしたときは、最新版を pull するというような運用をしているイメージが多いだろう。

同じイメージなのかどうかを確認するには pull したときの Digest が同じかどうかを見ることで確認できそうだ。

![image](https://user-images.githubusercontent.com/13635059/73994738-f2c45b00-4999-11ea-9f40-fa021edf4b95.png)

```
$ docker pull alpine:latest
Digest: sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
$ docker pull alpine:3     
Digest: sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
$ docker pull alpine:3.11  
Digest: sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
```

```
$ docker pull alpine:3.10
Digest: sha256:7c3773f7bcc969f03f8f653910001d99a9d324b4b9caa008846ad2c3089f5a5f
$ docker pull alpine:3.10.4
Digest: sha256:7c3773f7bcc969f03f8f653910001d99a9d324b4b9caa008846ad2c3089f5a5f
```


ゆるい指定の場合は、pullする時期によって、別のものが取れてしまう

Dockerfileなどに書くときは、なるべくマイナーバージョン、パッチバージョンまで指定しておきたい

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2978








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
rex0220 項目検証プラグイン　テーブルの重複チェック

項目検証プラグインで、テーブル内項目の重複チェックする方法をまとめてみます。


# 環境

- kintone：　いろいろ簡単にできるクラウド型業務アプリ開発プラットフォーム
- [項目検証プラグイン](https://qiita.com/rex0220/items/be20fd879f5e1bc9e035)：　めんどうなチェックを簡単にできるプラグイン



# テーブル内項目の重複チェック１

テーブル内の項目で、同じ値を重複して入力させたくない場合に、項目検証プラグインでエラーにします。

<img width="709" alt="2020-02-08_10h54_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ac5092e9-73e6-4060-cfc4-d6b902abbac6.png">


## アプリのフォーム設定
テーブル内にドロップダウン項目を作成


<img width="1215" alt="2020-02-08_10h59_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d6a95f17-6407-e199-d73d-dccea8acc18d.png">


## 項目検証プラグインの設定

テーブル内のドロップダウン項目に、カスタムバリデーションを設定します。
少しトリッキーなチェックで、重複チェックを行っています。
テーブル内のドロップダウン項目値を',' でつなげて、対象行のドロップダウン値を"" に一つだけ変換したものと、全部変換したものが違っているかどうかで判定しています。


- 条件：
 REPLACEALL(JOIN(TARRAY(ドロップダウン),","),ドロップダウン,"") != <br>REPLACE(JOIN(TARRAY(ドロップダウン),","),ドロップダウン,"")

- メッセージ：
　"重複エラー: " & ドロップダウン

- 関数：　[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)の関数が使えます。
    - REPLACEALL：　文字列変換で対象文字列をすべて変換
    - REPLACE：　文字列変換で対象文字列の先頭のみ変換
    - JOIN：　配列を区切り文字で連結
    - TARRAY：　テーブル内項目の値を配列化

<img width="975" alt="2020-02-08_11h03_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/738e5dc0-3e4f-bed4-332a-961ad134f967.png">


## 問題点
チェックに文字列変換を使っているため、ドロップダウンの選択値に他の選択肢の文字列が含まれている場合に、エラーになってしまいます。
例：ドロップダウン２の選択肢が "ABC","A" で、重複していないのにエラーになるケース。

<img width="422" alt="2020-02-08_11h35_45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ee80a7a0-ff17-c957-388b-e362e37d0b5b.png">


# テーブル内項目の重複チェック２

ドロップダウンの選択値に他の選択肢の文字列が含まれている場合も、対応できるチェックを考えてみます。
例：ドロップダウン2の正常ケースと重複エラー。

<img width="1071" alt="2020-02-08_11h44_00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0171eeb9-eeb6-2a04-94a3-f2f15b8a94af.png">


## 項目検証プラグインの設定２

テーブル内のドロップダウン2項目に、カスタムバリデーションを設定します。
違いは、値をアポストロフィー"'" で囲んで変換する点です。
これで値に部分列があっても、ちゃんとチェックできます。
もし値にアポストロフィーがある場合は、別の記号を使いましょう。

- 条件：
REPLACEALL(JOIN(TARRAY("'"&ドロップダウン2&"'"),","),"'"&ドロップダウン2&"'","") !=
REPLACE(JOIN(TARRAY("'"&ドロップダウン2&"'"),","),"'"&ドロップダウン2&"'","")

- メッセージ：
　"重複エラー: " & ドロップダウン2


<img width="828" alt="2020-02-08_11h50_50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/43d4fccb-9300-6193-33e1-83f9bb902691.png">
【chmod】現在のディレクトリすべてのファイルパーミッションを変更する


```console
$ chmod -R 744 .
```


こうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883/6ba7239d-eafa-d65a-82ba-daa029373705.png)


### 必要になった動機
Ubuntu18.04（WSL2）環境で作成したRailsアプリをcloneして、`bin/rails`をつかおうとしたら実行権限がなかったため。

### 参考
* [Macターミナルコマンド「chmod」の使い方 \| D\-Box](https://do-zan.com/mac-terminal-chmod/)
* [Linuxの権限確認と変更\(chmod\)（超初心者向け） \- Qiita](https://qiita.com/shisama/items/5f4c4fa768642aad9e06#%E6%95%B0%E5%80%A4%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B)
### 
* 「-R」を入力するとフォルダ内のフォルダ、ファイル全てのパーミッションを変更する。
* 744で所有者のみにすべての権限を付与する。777にするとすべてのユーザーに対してになる。

### 数値は2進数で権限を与えたい部分をコントロールする
|読み取り|書きこみ|実行
|:-:|:-:|:-:|
|r|w|x|
|4|2|1|

|数値|所有者|グループ |その他 |
|:-:|:-:|:-:|:-:|
|000|---|---|---|
|700|rwx|---|---|
|744|rwx|r--|r--|
CommonMark の重要な概念、段落の interrupt とは

こんにちは、Markdown ソムリエです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今気づいたけど Qiita って commonmark に準拠してないのかな。fenced code block が段落を interrupt してくれない。</p>&mdash; tk0miya (@tk0miya) <a href="https://twitter.com/tk0miya/status/1225952196199501824?ref_src=twsrc%5Etfw">February 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Qiita でメモを書いているときに、ふとこんなことに気づきました。

## 段落の interrupt とは?

[CommonMark spec](https://spec.commonmark.org/) を一通り読んでいるみなさんなら "〜〜〜 can interrupt a paragraph" という記述を何度も目にしたことがありますよね。この **interrupt** は、あるマークアップが段落に **割り込み**、別の要素を開始できるかどうかを意味しています。

通常、CommonMark では空行を段落の終わりとみなすことになっています。

```
ここは段落1です。
ここは段落1の続きです。
まだ段落1です。

ここは段落2です。空行を入れると段落が終わります。

* 空行を挟んで箇条書きを書きます。

あらたな段落です。
```

テキストの状態でもテキストのかたまりが段落と認識できますし、自然な文法に感じられます。
ちなみにファイルの末尾も段落の終了と認識されます。

これに対し、「段落の interrupt」は **空行を含めずに** 別の要素を書き始めることを許容する文法です。たとえば、次の例は段落と箇条書きの間に空行を入れていませんが、箇条書きの開始に合わせて段落が終了するものと解釈されます。

```
段落1です。
* 空行をはさまずに箇条書きを書いても、ここはリストとして認識されます。
```

そして、ツイートしたように、Qiita Markdown はこの段落の interrupt に対応していないようです。段落と箇条書き、段落とコードブロックといった要素の切り替わりの際は空行を入れる必要があります。他の処理系と同時に使っている人は解釈の差に気をつけてるとよいでしょう (GitHub とかね)。

## ところで、CommonMark ではどう定義されているの?

CommonMark ではそれぞれのブロックレベルの要素ごとに段落に interrupt できるかどうかが定義されています。

|記法|interruptできる?|
|---|---|
|Thematic breaks|できない。Setext headings と解釈される。|
|ATX headings|できる|
|Setext headings|できない。直前のテキストは段落ではなく、見出しと解釈される。|
|Indented code blocks|できない|
|Fenced code blocks|できる|
|HTML blocks|できる要素とできない要素がある (type7 の要素はできない)。|
|Link reference definitions|できない|
|Paragraphs|できない|
|Blank lines|できる|
|Block quotes|できる|
|Bullet lists|できる。ただし、中身が空の箇条書きはできない。|
|Ordered lists|できない。ただし、番号が 1 で、中身がある場合はできる|

おおよそ要素ごとに決まっているので、覚えるのは難しくありません。ルールが多いように見えますが、個人的には実際に書いてみると納得感があるものが多いので違和感はありません。ただ、意識をしないとマークアップをしたつもりが、段落の一部として解釈され、本文として表示されてしまうことがあるのでご注意ください。

ひとつだけ複雑で興味深いのは Ordered lists のルールです。1 からはじまる箇条書きの場合のみ interrupt できます。

```
段落です。
1. 1番から始まるこの箇条書きは割り込みできます。

段落です。
5. 他の番号から始まるこの箇条書きは割り込みできません (段落の続きと解釈されます)
```

とてもヒューリスティックなルールですよね。一貫性とは…と気が遠くなりますが、手に馴染む文法です。

ちなみに実装泣かせです。

## まとめ

* CommonMark ではいくつかの記法が段落を interrupt できる
* ややこしい例外はあるが、書きやすいように調整されている印象 (私には)
* Qiita は段落の interrupt に対応していないため、改行を入れましょう

そのうち暇を見て、逆のパターンである「他の要素の直後に、段落を書いた場合の挙動」について説明しようと思います。
SplunkでJSONを作る

小ネタ
#はじめに
JSONからフィールドに戻して、またJSONにするという、SPLと正規表現の練習
#SPL

```java:JSON.spl
| makeresults
| eval _raw="{\"hensachi\": 60, \"students\": 260, \"name\": \"ichi-koukou\"}"
| spath
| foreach * [ eval json_value=mvappend(json_value,<<FIELD>>), json_header=mvappend(json_header,"<<FIELD>>")]
| eval json_data=mvzip(json_header,json_value,": ")
| stats values(json_data) as json_data delim=","
| nomv json_data
| rex field=json_data mode=sed "s/(\w+):/\"\1\":/g"
| rex field=json_data mode=sed "s/(?:\:) ([^\d,]+?),/: \"\1\",/g"
| eval _raw=replace(json_data,"^(.*)$","{ \1 }")
| spath
```
#解説
`nomv`はデフォルトだと` （空白）`が区切り文字なので`stats()`で区切り文字を指定している。
`foreach`での`<<FIELD>>`と`"<<FIELD>>"`の違いはよく忘れるけど

|\<\<FIELD>>|"\<\<FIELD>>"|'\<\<FIELD>>'|
|:-:|:-:|:-:|
|フィールドの中身|フィールド名|フィールドの中身<br>eval関数の引数の時に使う場合がある。|

`rex mode=sed`も`replace()`も置換側が**正規表現ではない**のはよく間違える。
#まとめ
`spath`が結構便利で、なんでも抽出してくれるので、[むりやりJSON](https://ja.wikipedia.org/wiki/%E5%8E%9A%E5%88%87%E3%82%8A%E3%82%B8%E3%82%A7%E3%82%A4%E3%82%BD%E3%83%B3)してみる時もあります。:sweat_smile:
IPアドレス固定後、Wordpressにログインできない

### 前提・実現したいこと

初心者です。
Raspberry Pi 4 Model BにWebサーバを構築しようとしています。
apache2, WordPressをインストール、まではうまくいきました。

その後、固定IPアドレスの設定を行った後、WordPressにログインできません。


### 発生している問題・エラーメッセージ

http://固定したIPアドレス/wordpress/wp-login.php
でログインすると固定前のIPアドレスにとび
---
このサイトにアクセスできません　固定前のIPアドレス からの応答時間が長すぎます。
次をお試しください

接続を確認する
プロキシとファイアウォールを確認する
ERR_CONNECTION_TIMED_OUT
---
となってしまいます。


### 試したこと
●wp-config.phpに、
define( ‘RELOCATE’, true );
を追加


●wordpress DBのsiteurlを更新する
https://qiita.com/NT1123/items/9b8e11227e88edb73bba


### 補足情報（FW/ツールのバージョンなど）
Hard: Raspberry Pi 4 Model B
OS: Rasbian (NOOBS var.3.3.0)

よろしくお願いします。
明日から現場で使える！便利なHCPチャートのすゝめ

#HCPチャートとは
日本電信電話公社（現NTT）の横須賀電気通信研究所で開発された
プログラムの視覚的記法です。今の現場で使う事が多いのですが、便利なのでアウトプットします。

HCPチャートは、以下のような記号を使って書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240108/26950a52-16fe-34f3-24ad-0ec6376428a4.png)

参照 : https://ja.wikipedia.org/wiki/HCPチャート


#HCPチャートの使いどころ
クラスの概要を説明するときはクラス図を
処理の流れを説明するときはシーケンス図を利用します。

では、関数仕様を説明するときはどうしてますか？
私は、この手法を知る前はフローチャートを書いていました。

フローチャート・・・素晴らしい記法ですよね。
ただ、書くのが非常に~~めんどくさい~~大変です。

#フローチャートとの比較

たとえば、お金を投入した後の自販機の処理をフローチャートで書いた場合、以下のイメージで書きますよね。


※フローチャートのイメージを説明しているだけなので、処理の抜け等は見逃して下さい(_ _)
※商品の最低単価が100円という想定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240108/ebeb2d50-5525-a879-58e5-452e14648ed1.png)
フローチャートを書く専門のツール等もありますが現場レベルでさくっと書く場合
大抵エクセルの図形オブジェクトを駆使して描きます。が・・・図形を並べる作業って結構手間です。

このフローチャートをHCPチャートで書いた場合、以下のように書けます。


```
┬
○ 自販機の処理
┴└┐
  ＠│投入金 > ￥100
  │ └┐
  │  ○ 買える商品のボタンを光らせる
  │  │
  │  ◆│商品購入ボタンが押された
  │  │ └┐(真)
  │  │  │
  │  │  ○ 投入金から商品価格分を引く 
  │  │  │
  │  │  ○ 商品を出す
  │  │  ┴
  │  │
  │  ◆│返金ボタンが押された
  │  │ └┐(真)
  │  │  │
  │  │  ○ 残金を出す  
  │  │  ┴
  │  ┴
  ▼ 終了
  ┴
```

なんと、記号と日本語だけで関数仕様を書く事ができます！

一部、公式の記号とは違う記号(ループが＠でifが◆など)も使っていますが、僕らの現場では
エクセルに張り付ける前提なので、この記号はどういった意味だ。という共通認識をもって作業しています。
正式文章としては、微妙かも知れませんが現場レベルのやり取りでは最適だと思います。

また、上記で使っているHCPチャートはQiitaのコードブロックに直で書いたものですが
実際に使う場合は、VIMや秀丸など罫線を書くためのマクロを持つエディタで記述してから
エクセルに貼っつけるという流れで行うと、大分作業性が良くなります。

フォントはMSゴシックなどの等幅フォントで 9ポイント程で記述するのがオススメです。



#サクラエディタでHCPチャート
私は、サクラエディタユーザーなので、サクラでHCPチャートを書く方法を記載します。
サクラエディタにはスムーズに罫線を書く方法がないので、罫線マクロを準備します。

以下MITライセンスで罫線マクロを作ってくれている方がいます。
https://github.com/pekopeko1/sakura2-keisen

このマクロを登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240108/77c84586-ccb5-49e8-a51b-f1ad6a051c5b.png)

あとは、キー割り当てで登録したマクロを割り振れば
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240108/a5a96e4a-e55e-d3f6-a488-9ffd866a0fc7.png)

Shift + Ctrl + 矢印 で自由に線が引けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240108/01ba2729-7cb4-fcdb-18fa-dba488ef2f3e.png)

最初こそ手間ですが一度マクロを登録してしまえば自由に使えるので、とっても便利です！！
既存のFlutterプロジェクトの導入で躓いたら確認するべきこと

# 前提
DartをインストールしたあとにFlutterをインストールしている場合で発生しているので必ずしもこうなるかどうかはわかりません。

# 事象

既存のFlutterプロジェクトのリポジトリをcloneしてくるときに発生します。

Android Studioからプロジェクトを開くとエディタ上部に*Dart SDK is not configure*という警告が出てきます。

このときOpen Dart Settingをクリックして、設定画面に行きDart SDK path:にDartのSDKのあるpathを指定すればいいはずです。

が、適切に指定しないと

```
Error running 'main.dart': Cannot find runner for main.dart
```

と怒られてしまいます。

このときには任意の[DartのSDK](https://dart.dev/get-dart)のパスではなく、[Flutter](https://flutter.dev/docs/get-started/install)を導入した時に包含されているDartのSDKのパス`{PATH_YOU_INSTALLED}/flutter/bin/cache/dart-sdk/`を指定する必要があります。

もしかしたらこれで解決できるかもしれません。

参考：https://github.com/flutter/flutter/issues/40040
ケモインフォマティクスで学ぶRの条件分岐

# はじめに

[ケモインフォマティクスで学ぶRのデータ構造](https://qiita.com/yukiya285/items/32a8c05f908b68beb14f)に引き続き、リピドミクス（脂質の網羅解析）を題材として「条件分岐」について解説していきます。
ケモインフォマティクスの実践例を中心に説明していきますので、基本を確認したいという人は以下の記事を読んでからこの記事を読んでみてください。

[製薬企業研究者がRの制御文についてまとめてみた](https://qiita.com/yukiya285/items/811d34e9a2e21e4aae5d)


# if文

`if (条件式){処理}`として、条件式が成り立つときの処理を記述します。
`else`を使うことで、`if`に続く条件式が成り立たなかった場合の処理を記述することができます。
さらに細かく条件を分けたい場合は、`else if (条件式){処理}`とすることで、別の条件が成り立つ場合の処理を記述することができます。

```r
Un <- 0

if (Un == 0){
  print("saturated fatty acid")
} else {
  print("unsaturated fatty acid")
}
```

上のプログラムでは、不飽和度（脂肪酸の二重結合の数）を示す変数`Un`が`0`だった場合は、`saturated fatty acid`（飽和脂肪酸）と出力し、`Un`が`0`以外の数値だった場合は、`unsaturated fatty acid`（不飽和脂肪酸）と出力するようにしています。

```r
Cn <- 18
Un <- 0

if (Cn == 16 && Un == 0){
  print("palmitic acid")
} else if (Cn == 18 && Un == 0){
  print("stearic acid")
} else {
  print("other fatty acid")
}
```

ifの後の条件式において、`&&`は「かつ」というような意味になります。
「または」にしたい場合は`||`を用います。


# switch文

指定した変数の値によって処理を分けたいときに使います。
`switch (変数, 値=処理, 値=処理, ・・・)`という風に書きます。

```r
Cn <- "16"

switch (Cn,
        "16" = print("palmitic acid"),
        "18" = print("stearic acid"),
        "20" = print("arachidic acid"),
        print("other fatty acid")
)
```

上の例では変数`Cn`に鎖長（炭素原子数）を格納し、その値によって出力する脂肪酸名を変えています。


# まとめ

ここでは、Rの条件分岐について、ケモインフォマティクスで使える実践的な知識を中心に解説しました。
もう一度要点をおさらいしておきましょう。

- 条件分岐は基本的に`if`を使って記述します。場合分けが必要な場合は、`else`や`else if`を使います。
- `switch`を使うと、`if`よりも短いコードで書ける場合があります。


# 参考資料・リンク

[プログラミング言語Rとは？統計分析に強い？](https://pharma-engineer.com/basic-programming/r-summary/)
docker-compose buildでNOTICE: chromedriver-helper is deprecated after 2019-03-31.と出た時の対処法

    docker-compose build
とgemfileをアップデートをしたときに、エラーにはならなかったが


    NOTICE: chromedriver-helper is deprecated after 2019-03-31.       
                                                                     
    Please update to use the 'webdrivers' gem instead.               
    See https://github.com/flavorjones/chromedriver-helper/issues/83
という注意喚起のメッセージが出た時の対処法について、僕が解決した方法を書いていこうと思います。

#メッセージの意味

    NOTICE: chromedriver-helper is deprecated after 2019-03-31.       
                                                                     
    Please update to use the 'webdrivers' gem instead.               
    See https://github.com/flavorjones/chromedriver-helper/issues/83
まずこの注意喚起の文章の意味を知らないことには話が進まないので、これを日本語訳していこうと思います。

結論、この文章は

chromedriver-helperはサービス終了したのでwebdrivers gemに変更してください。

という意味の文になります。

#対処法
意味が分かれば対処は簡単です。まずはgemfileを開いてください。

gemfileの

group :test doの中のchromedriver-helperを消してwebdriversに書き直します。

そして再び

    docker-compose build
を実行するとこの注意喚起の文は表示されなくなっていると思います。参考になれば幸いです。
React Class内での関数定義(bindしよう)


##はじめに
個人的なメモレベルです。

**[注意]**
現在、Reactでの開発は、**関数コンポーネントが主流**です。
これからReactを学習しようとしてる方は公式ドキュメントに目を通してみてください。

https://ja.reactjs.org/docs/hooks-intro.html

関数コンポーネント前提で学習できる書籍も2021年から充実してきてるので、興味があれば目を通してみると良いかもしれません。

https://www.amazon.co.jp/React%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E7%AC%AC2%E7%89%88-%E2%80%95Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Alex-Banks/dp/4873119383/ref=sr_1_5?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=JIBUVY6973B4&keywords=React&qid=1640322317&sprefix=reac%2Caps%2C345&sr=8-5

オライリーの文体が苦手な人はここら辺は初学者の方には良いかも。

https://www.amazon.co.jp/%E3%83%A2%E3%83%80%E3%83%B3JavaScript%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%82%8B-React%E5%AE%9F%E8%B7%B5%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E6%9C%80%E6%96%B0ReactHooks%E5%AF%BE%E5%BF%9C-Informatics-IDEA/dp/481561072X/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=JIBUVY6973B4&keywords=React&qid=1640322317&sprefix=reac%2Caps%2C345&sr=8-6


##メソッド記法での問題点

Reactで`setState`を利用する際に、JSXで、以下のように書くことが多いかなと思う。

```react:クラスのプロパティとして関数を定義
doPlus = () => {
    this.setState({count: this.state.count + 1});
};

<button onClick={this.doPlus}>ボタンを押したらプラスするよ</button>
```

***しかし、以下のような書き方の場合、初期化時にbindしとかないとエラーになります。***

これクラス内に定義されたメソッドであっても、実行方法によって、`thisの参照先`は変わってしまうJSの仕組み故。この場合、`button`に関数オブジェクトをそのまま渡しているので、`thisの参照先`は`button`になってしまう。

JSの初心者が最初にぶつかる壁は`this`の扱いですよね。。。

```react:ボタンを押下すると、undefindeエラーとなる
doPlus(){
    this.setState({count: this.state.count + 1})
}

<button onClick={this.doPlus}>ボタンを押したらプラスするよ</button>
```

上記のようにメソッド記法で書きたいんだ！！！て場合は、classの初期化時に`thisを必ずbind`しておきましょう。

```react:初期化処理
constructor(props) {
    super(props);
    this.state = {
        count: 0
    }
    this.doPlus = this.doPlus.bind(this);
}

```

これで解決😄
【簡単】renderメソッドの使い方を実際に直面したエラー文と共に解説する※view内のみ



renderメソッドの使い方をメモ。


renderメソッドにまつわるこんなエラーが出ました。
![スクリーンショット 2020-02-08 10.54.4654.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/cc5a70e2-97aa-9f06-3559-0cdcc6d05790.png)

## 原因
renderメソッドで指定しているファイル（shared.erb）がapp/views内に存在しない、とのこと。


そこでapp/views内をみてみたところ、sharedファイルはあったものの、名前が_error_messages_html.rebとなっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/75d96316-e88e-9103-78fc-60b464c859b0.png)





表示したい部分では、'''<%= render 'shared' %>'''だけになっていたので、
```<%= render 'shared/error_messages' %>```に変更する必要がありますね。


```
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared' %>   ←この部分を<%= render 'shared/error_messages' %>に変更する

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>


  </div>
</div>
```

## 【各種条件】renderメソッドの使い方で理解したこと


・app/viewsフォルダの中で、何度も表示したいhtml.erbファイル（つまり<%= =>で指定するファイル）を別に作成しなければいけない。
・railsの慣習として、app/views/sharedファイルの中にrenderメソッドで表示するファイルを置くことになっている。
・慣習として、renderメソッドで指定されるhtml.erbファイルはファイル名の先頭に_をつける。



ググっても難しい言葉でしか書いていないので、簡潔にまとめました。初学者の参考になれば幸いです。
herokuにnode.jsを使用してhtmlファイルを公開する


オンライン上でcvなるものを作成したので、せっかくだからそれをheroku上で公開してみたいと思います。

用意するもの。
- 公開したいhtml、cssファイル
- herokuアカウント
- 気合い
- git, node


#それでははじめ

##場所の指定

コマンドライン　→ CL
ディレクトリ → DIR
atom → ATOM 

## -commandlineでnpm initする（CL）

https://qiita.com/kibinag0/items/8e584677d0a1bfc3759f


### -npm でexpressをインストール（CL）

```
npm git init 
npm install express
```


## -ローカルの画像等を使用できるようにpublicフォルダに画像やcssファイルをぶち込む（DIR）

<img width="411" alt="スクリーンショット 2020-02-08 10.38.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161691/6ead991a-4b2c-bd34-b37a-bdc9800942b5.png">


## -index.jsファイルを作成する（atom）

```js:

//jshint esversion:6

//expressをロードする
const express = require("express");
const app = express();


// public内ファイルを使用できるようにする
app.use(express.static("public"));


//requestがあった時のresponse処理
app.get("/",function(req,res){
  res.sendFile(__dirname+"/index.html");

});

// process.env.PORTはdynamic portとしての機能
app.listen(process.env.PORT || 3000, function(){
  console.log("The server is runnning on port 3000.");
});


```

## -herokuで使用するProcfileを作成

これはあとで必要になるものなのだからあらかじめ作っときます。
（参考） https://devcenter.heroku.com/articles/getting-started-with-nodejs#define-a-procfile

index.htmlとかが入っているdirectoryに "Procfile"という名前のテキストファイルを作成し、『web: node index.js』 と記載します。一語一句同じ名前じゃないとダメみたい。




## -nodemon を使用し、ローカル環境でテスト（CL）

```
nodemon index.js
```

ちなみにnodemonの使用方法はこちら。
https://qiita.com/kibinag0/items/8936476e99ed50279b83#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%9B%B4%E6%96%B0%E8%87%AA%E5%8B%95%E5%8C%96nodemon%E3%81%AE%E3%81%99%E3%81%99%E3%82%81


## -git に保存する

ローカル環境でテストし、OKだったらgitにadd, commitします。

```
git init
git add .
git commit -m "first commit"
```


## -herokuをインストール

次に、herokuのインストールを行います。
（herokuのアカウント持っていない人は先に作成してね）

公式サイト↓
https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up

## -herokuのログイン（CL）

```
heroku login 
```

## -herokuで新しいappを作成（CL）

```
heroku create
```

こんな感じになります。

<img width="527" alt="スクリーンショット 2020-02-08 11.05.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161691/31976d01-d19b-3011-d219-18b8ffae8c48.png">


### -git からherokuにpushする

先ほど git commit したものを今度はhirokuにpushします。

```
git push heroku master
```

これで、完了です。

先ほどcreateしたURLに行ってみると、index.htmlが反映されているはずです。
（反映までに数分かかることもあります。）
大事にしたいこと（Webアプリケーション開発での心構え）

#はじめに
これからWebアプリケーション開発に取り掛かります。
今後、すぐ初心に戻れるように、この記事を書いておきたいと思います。



#Webアプリケーション開発するに当たり重要なこと

###開発セクション
　１　企画
　　　作成するサービスやサービスの主要な機能、どんなユーザーが使用するか考える。
　２　設計
　　　企画したサービスをプログラムするための情報を決める。
　３　開発
　　　HTML/CSS、JS、Railsなどを用いて実際にサービスをプログラミングする。
　４　公開
　　　作成したサービスを外部のサーバーにアップし、Web上から動作できるようにする。

###より良いエンジニアとは
　　１　自分で調べる癖をつける。　
　　　　→　自走できるエンジニアになるために！
　　２　チームメンバーに読みやすいコードを書く。
　　３　サービスを作るときに後から変更しやすいプログラムを書く。

###コミットメッセージ
　　１　後で見て、コードを見なくても何をしたのかをわかるように書く。
　　２　チームメンバーが読むものとして書く。
　　３　長くなりそうなら改行して何行も書いていい。

###コードレビューの目的
　　１　技術的負債となり得るコードがないか確認する。
　　２　担当者の実装レベルの向上
　　３　他人のコードを読むことによる学びや発見


#さいごに
将来、人にとって良いものを作る！という志を持って学習しております。
その志のFirst Stepとして、まずは自分が書くコード、話し方を良いものにしていこうと思います。
WindowsでランチャーのKeypirinha入れたら幸せになりました

## Keypirinhaとは
ランチャーアプリの一種で、Macのspotlightに似ています。
（読み方は、キーピリンハ..でいいのかな..）
![keypirinhaデモ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/91c6b426-3246-5413-b58a-fc1d178ba714.gif)


## 何が嬉しいか
動きが高速なのと、画面の真ん中に出るため視線を移動することもなく、集中が乱されないです。
また、使うたびよく呼び出すアプリは候補も上の方に上がってくるため、より高速に起動できるようになります。

↑ではゆっくりやってますが、↓実際は タタッ! タタタッ! ッターン! な感じでイケます。
![keypirinhaデモ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/3d80212c-26d3-ec00-3f43-4ff8692725fb.gif)

## 各種設定変更について
起動するコマンドやテーマなどの設定も変更できます。
デフォルトでは「Ctrl + Win + K」で起動ですが、自分はMacのspotlight風に「Alt + Space」で起動するようにして、スタートアップ時に起動するのとテーマの変更をしています。
![capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148042/cb8e207b-a9d1-bf42-7d71-38e08416df13.png)

## インストール方法
https://keypirinha.com/
公式からダウンロードしてくるか、Chocolatey（Windows用のパッケージマネジャー）からインストールできます。
公式サイトのトップにある「A fast launcher for keyboard ninjas on Windows」という一文がなんかかっこいいです（keyboard ninjasってなんだ...）

## 追記）注意点
元々Chocolateyで入れてたのを改めてポータブル版をダウンロードして「Program Files」配下に置いて実行したところ異様に遅くなる事態があり、結果的に「管理者で実行」してスタートさせたところ高速に戻りました。
置き場所によっては注意です。
アジャイル開発の手法の一つ、スクラムについてざっくり理解する

　次の現場でアジャイルの導入支援の手伝いをするらしいので、初心者なりに学習した内容を共有したいと思います。何か間違いがあればご指摘くださいませ。
##この記事の要旨
 スクラムについて[スクラムガイド](https://www.scrumguides.org/docs/scrumguide/v2016/2016-Scrum-Guide-Japanese.pdf)を基にして簡単にまとめます。自分なりの解釈やかみ砕いた言い回しを含んだ抽象的な説明をするので、細かな知識に関してはスクラムガイドや参考書を読んでください。また、具体的なスクラムを効率化する手法（ペアプログラミングやタスクボード等）に関しても触れません。あくまで、超入門の記事だと思っていただけると幸いです。
##アジャイル開発とは
　プロダクトを重要なモノから順次作り、完成したらすぐに要件を満たしているかを確認することで、作成速度と質を上げる開発手法です。成果物（プログラムやドキュメント）を少しずつ完成させながら先へ進んでいくので、仕様の変更にも対応しやすいです。
##スクラムとは
　アジャイル開発のフレームワーク（手法・やり方）のうちの一つです。複雑かつ変化があるものに適応しなくてはならないプロジェクトと相性が良いです。要件定義が完全に定まっていない・変更の余地がある場合等に適したフレームワークといえます。
###3つの特徴
　スクラムは下記3つの特徴を持っています。
①軽量（ルール・やるべき事が少ない）
②理解が容易
③習得が困難（スクラムを正しく実施するには経験が必要である）
###経験的プロセス制御（経験主義）
　スクラムはスプリント（後述）を繰り返すことで経験を積み、プロジェクト内の様々な事に対し予測とリスクの管理が出来るようになる事を基本としています。つまり、スプリントを繰り返し経験することでより効果的なスクラムの実施方法を学んでいくのです。これを経験的プロセス制御といいます。経験的プロセス制御は下記3つの概念を重視することによって実現されています。
####・透明性
　見る人全員が共通の理解を持っていることを指します。例えば、用語や進捗・完成の定義（後述）が見える化されていて、それぞれの要素に対し皆が共通認識を持っているということです。この事により、認識の齟齬をなくし円滑な開発を促します。
####・検査
　頻繁に進捗や成果物を確認することで、問題を素早く発見することです。頻繁な検査によって、素早く柔軟な開発を実現しています。
####・適応
　検査で問題が生じた場合、素早く日程の調整・問題の解決をすることです。そうする事で、プロジェクトが本来の趣旨（例えば顧客の要求）から逸脱することを防ぎます。
##プロダクトバックログ
　必要な機能を小分けにして、優先順位をつけてならべたものです。優先度は最初に決めたものを完成形とせず、必要な機能の増減や優先順位の変更があった場合はどんどん書き換えます。
・###スプリントバックログ
　プロダクトバックログの中からスプリント（後述）で達成する項目を抜き出し、達成するための計画を加えたものです。
##完成の定義
　プロダクトバックログやスプリントバックログの項目が達成できているかの基準です。つまり、プログラムやドキュメントのリリースが可能であるか否かの基準の事であるとも言えます。スクラムチーム全員が、完成の定義に対する認識を共有していることで、スクラムが円滑に進みます。
##スプリント
　開発期間を固定の期間（最長1か月まで）に区切った期間を、スプリントと呼びます。スプリントを繰り返す中で改善をしていくことで、スクラムチームの経験を蓄積しスクラムの効果の最大化を図ります。スプリントはスクラムイベントと呼ばれる下記の4つの要素から構成されます。
###スプリントプランニング
　スプリント内でプロダクトバックログ内の何を作るか・どのように作業すべきかを、スクラムチーム全員で決めていく共同作業です。ここで毎回スプリントバックログをつくります。
###デイリースクラム
　毎日行う15分間で必ず終わらせる会議です。スプリントのゴールと現状のズレを把握することを最優先とします。問題を発見した場合は別途会議を開催して、必要なメンバーのみで会議を行うことで、より効率的な時間の使い方をします。
###スプリントレビュー
　実際にできたプログラム（インクリメントと呼びます）がリリース可能なレベルへ到達しているか、関係者（顧客など）を招いて評価します。その他にも、問題点や要件の再確認をしたり、プロダクトの状況について説明します。
###レトロスペクティブ（ふりかえり）
　スクラムチームとしての活動を評価し、次のスプリントの改善方法を考えます。スプリントの中で、上手くいった・いかなかったことを整理し、改善案を出すことでスクラムチームの質を向上させます。
##スプリントの流れ
　スプリントは下記のような流れで進みます。この流れを繰り返す中で検査と適応が何度も実施されることで、達成すべきゴール（顧客の要求）に近づいていきます。
**スプリントプランニング**
↓
**デイリースクラム**（毎日実施）
**成果物の作成**（プログラミング・ドキュメントの作成など）
↓
**スプリントレビュー**
↓
**レトロスペクティブ**
##スクラムチーム
　スクラムで開発する際には下記のメンバーが一箇所に集まって作業することで、より効果的なものになります。
###プロダクトオーナー（1人）
 プロダクトの方針を決めたり、関係者との調整を行います。プロダクトバックログの内容・優先度・可用性に責任を持ちます。
###開発チーム（3~9人）
　リリース可能（つまり完成した）な成果物を作る専門家のチームです。機能横断的であり自己組織化されていることが開発チームの条件です。
####・機能横断
　成果物（プログラムやドキュメント等）を作るのにあたって必要なスキルを、メンバーの誰か（誰でも良い）が持っていて、外部の手助けがいらないことです。
####・自立した組織
　開発チーム内で仕事の進め方が決定され、主体的に作業を進めることです。
###スクラムマスター（1人）
　正しくスクラムの手順・方針・考え方を理解・達成できているかをコントロールする人です。スクラムチームに対しては、スクラムという概念を達成してもらうために働きかけ、外部の人にはスクラムの実現に対して必要/不要な事を理解してもらうことが主な仕事になります。



##参考
https://www.scrumguides.org/docs/scrumguide/v2016/2016-Scrum-Guide-Japanese.pdf
https://www.shoeisha.co.jp/book/detail/9784798129716
http://stay-foolish.com/20180611_agilebook
https://schoo.jp/class/3742
CentOS7+Apacheでphpinfoを表示させたい。

<h1>概要</h1>
筆者「WindowsでLAMP環境を構築してからアプリ開発をしたい！」
⇒でも、ソースを書いてもサーバー上でPHPが読み込まれない…
⇒調査！！！(した結果を自分用にメモとして綴ります)
<h1>環境</h1>
・Vagrant
・VirtualBox
・CentOS7.7
・PHP7.2
・Apache2.4

<h2>①httpd.confに追記</h2>
`$ cd /etc/httpd/conf`
httpd.confがあるディレクトリに移動して、
<br>
`$ vi httpd.conf`
viで編集します。
<br>

```httpd.conf
LoadModule php7_module C:/php/sapi/php7Apache2.dll
AddType application/x-httpd-php .php
```

【viコマンドメモ】
・「i」で編集
・追記したら「:wq」で保存+終了

<h2>②phpinfo.phpをつくる</h2>
`$ cd var/www/html`
今度はドキュメントルートに移動して
<br>
`$ touch phpinfo.php`
phpinfoのファイルを作成
<br>

```phpinfo.php
<?php
  phpinfo(); //phpの詳細を表示する関数
?>
```

これを書いて保存+終了！
サーバーを立ち上げてphpinfo.phpにアクセスすれば無事中身が確認できました。
![phpinfo.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481718/955e809e-fe52-bbae-0e36-abcf3c112298.jpeg)

<h1>まとめ</h1>
XAMPPに慣れてVagrant等の仮想環境から逃避していたので勉強になりました。
vagrant box addとかyumコマンドでインストールさえ済めば万事解決なわけなかった()