OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】関数の引数として空のタプルを渡す

この記法について

```swift
hoge(())
```



# 何をしているのか
空のタプルを引数として取る関数に空のタプルを渡している。

```swift
func hoge(a: ()) {
    ...
}

hoge(())
```
[Voidは空のタプルのtypealias](https://developer.apple.com/documentation/swift/void)なのでこうも書ける

```swift
func hoge(a: Void) {
    ...
}

hoge(())
hoge(Void())
```

# なぜこんな関数が生まれるのか
通常意味がないので空のタプルを引数として取る関数を作ることはない。
が、`空のタプルを取り得る型パラメーターTを引数として取る関数`を定義した場合に空のタプルを引数として取る関数が生まれてしまう。

```swift
class Fuga<T> {
 func piyo(_ a: T) {
   // Tは空のタプルになり得る
 }
}

let fuga = Fuga<()>() // もちろん Fuga<Void>() でも良い
fuga.piyo(())
```

# Swift4以降では空のタプルは省略できない
空のタプルを引数として取る関数には脳死で空のタプルを渡せば良い。

#### Appendix
[[Swift] 関数における引数/戻り値とタプルの関係](https://dev.classmethod.jp/smartphone/swift-function-tuple/)
https://stackoverflow.com/questions/45183961/compile-error-in-swift-4-on-parameter-passing
[Swift: () -> () vs () -> Void](https://ericasadun.com/2015/05/11/swift-vs-void/)
F9Pで基地局

#u-centerをインストールしてUSBで繋ぐ
https://www.u-blox.com/ja/evaluation-software-and-tools

###基本的な使い方
![スクリーンショット 2019-06-17 23.57.16-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/e212c9ca-7c60-1e64-a759-7a83ceb5a50c.png)
##Connect-モジュールへ接続する
出てこない場合、Windows-デバイスマネージャー-センサーの中に入ってます。
センサー内にあるu-bloxを右クリック-プロバティ-ドライバー-ドライバーの更新-コンピュータを参照して(ry-コンピュータ上の利用可能な(ry-USBシリアルデバイス-次へ-閉じる
とやって、COM2とか（数字は変動する）に変更する。
###Configure-設定画面を表示
###Send-設定をu-bloxモジュールへ送る

#基地局用の設定
・UBX-CFG-MSG
F5-05 RTCM3.3 1005
USB ON 1
F5-4D RTCM3.3 1077
USB ON 1
RTCM 3.3 1087
USB ON 1
F5-61 RTCM3.3 1097
USB ON 1
F5-7F RTCM3.3 1127
USB ON 1

・UBX-CFG-TMODE
Survery-in 300s,3.000で設定

・UBX-CFG-PRT
Target:USB
in:none
out:RTCM3

・UBX-CFG
Save current configuration
コレ重要。
これやらないでUSB抜くと、設定が全部もとに戻ります。

##補足
・UBX-CFG
Revert to default configration
初期設定に戻す

#ソフトウェアの選定
#u-center
Receiver-NTRIP client

##NTRIP server for Arduino
https://github.com/GLAY-AK2/NTRIP-server-for-Arduino

##RTKLIB
http://www.rtklib.com/

###STRSVR
Inputは先ほど設定したCOMポート。
Outputはこんな感じ。
<img width="411" alt="スクリーンショット 2019-06-18 0.41.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/4924e50a-02ea-85f9-7c70-fb191449f4c1.png">

```strsvr.txt

[Mountpoint-Name];RTCM3;1005(1),1077(1),1087(1),1127(1),1197(1),1230(10);1;GPS+GAL+BDS;SNIP;JPN;[Lat];[Lon];0;0;sNTRIP;None;N;N;;

```
・[]記号は不要。
・[eniwa-333]の部分は適宜変更すること。
・[Lat][Lon]はu-centerとかで適宜変更すること。
小数点以下２位までしか拾わない仕様ぽい。
<img width="201" alt="スクリーンショット 2019-06-18 0.39.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/f534ef6b-c5d5-bab5-d0ce-81a9d7b4b87a.png">

・ケース作ってみました。
https://make.dmm.com/item/1073389/

・仕様書
https://software.rtcm-ntrip.org/wiki/STR
・参考資料
http://www.geosense.co.jp/html/gijo_f9p_setting.html
RESTfulAPIは複合アーキテクチャスタイルである


# RESTとは
RESTはWebのアーキテクチャスタイル。実際のアーキテクチャを設計するときの指針だったり、作法だったりするもの。
RESTは複数のアーキテクチャスタイルを組み合わせて構築した複合アーキテクチャスタイル。
基本はクライアント/サーバーで、そこに制約を課していくことでRESTを構成していく。

## クライアント/サーバー
そもそもWebはクライアント/サーバーのアーキテクチャスタイルを採用しているので、クライアント/サーバーが基本になる。
クライアントとサーバーに分離することでマルチプラットフォームにすることができる。
これをもとに以下の制約を課していく。

## ステートレスサーバー
クライアントの状態をサーバーで保持しない。
クライアントの状態を保持しないことで実装を簡単にすることができる。

## キャッシュ
一度取得したリソースをクライアント側で保存し使いまわす。
クライアント/サーバー間での通信を減らすことができる。

## 統一インターフェース
URIで指し示したリソースに対する操作を統一した限定的なインターフェースで行う。

ここがちょっと分かりにくいですね。

まず統一の部分ですが、GETといえばリソースの取得で、POSTといえばリソースの更新ですよね？
このように操作を統一することで、リソースの提供者はRESTに従えば正しくリソースを提供でき、クライアントもRESTに従って要求すれば正しくリソースが取得できるわけです。

つぎに限定的な部分ですが、HTTP1.1ではGETやPOSTなど8個のメソッドが定義されています。
このようにメソッドを限定することでアーキテクチャをシンプルに保ちます。

全てのサーバーが同じインターフェースを採用することで(RESTに則ることで)、正しくリソースのやりとりができるね！ってかんじです。

## 階層化システム
階層化システムは統一インターフェースの利点でもあります。
クライアント側からしてみれば、直接通信するところのインターフェースが統一されていれば通信できるわけです。
それより先のことは特に気にする必要はないので、プロキシやロードバランサを挟んだりして階層化することができます。

## コードオンデマンド
プログラムをクライアント側で実行すること。JavaScriptとか。
(RESTの提唱者であるFieldingの博士論文ではオプション扱いだった。)

## REST = ULCODC$SS
- クライアント/サーバー
- ステートレスサーバー
- キャッシュ
- 統一インターフェース
- 階層化システム
- コードオンデマンド

上記すべてのアーキテクチャスタイルを追加したものが**ULCODC$SS**(Uniform Layered Code on Demand Client Cache Stateless Server)です。

これだけみるとRESTAPIってハードル高いなあと思います。
ただRESTはあくまでアーキテクチャスタイルなので、実際にシステムを設計するときにはいくつか除外してもOKなのです。ほとんどを除外してしまう場合はRESTではないアーキテクチャスタイルを採用するべきでしょう。


[Webを支える技術 HTTP,URI,HTML,そしてREST](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042/ref=sr_1_1?adgrpid=52846719243&gclid=Cj0KCQjw9JzoBRDjARIsAGcdIDVXq0-jeLOZQy5iSimbrn76n-bH4dC76iOlLXn4XOXkenzWeB--r7saAj0IEALw_wcB&hvadid=338558549746&hvdev=c&hvlocphy=1009300&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=10098567977622848698&hvtargid=kwd-333749887651&hydadcr=16039_11170864&jp-ad-ap=0&keywords=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1560829886&s=gateway&sr=8-1)
IIS関連情報整理


# IIS 設定ファイル関連

```bat:iisConfigOperation.bat
REM バックアップ
REM   ※下記にバックアップが作成される
REM     %systemroot%\system32\inetsrv\backup
%systemroot%\system32\inetsrv\appcmd add backup IIS_CONF
REM リストア
%systemroot%\system32\inetsrv\appcmd restore backup IIS_CONF
```
◆IISのapplicationHOST.config の保存場所
　https://iroiro-memo.hatenablog.com/entry/20151116/1448103652
◆IIS config
　https://techinfoofmicrosofttech.osscons.jp/index.php?IIS%20config
◆[Windows]IISの設定のバックアップ・リストア作業
　http://ht-jp.net/blog/pc/windows/windowsiis-bkup

# ログ関連
今は下記３つを見ている
　・イベントビューア
　・アクセスログ：u_ex%y%m%d.log
　　C:\inetpub\logs\LogFiles\W3SVCx　※x⇒番号
　・エラーログ：httperrxx.log ※xx⇒連番
　　C:\Windows\System32\LogFiles\HTTPERR
　※サービスにもログあるかも...!?要確認
◆IISのログ
　https://techinfoofmicrosofttech.osscons.jp/index.php?IIS%E3%81%AE%E3%83%AD%E3%82%B0
◆IIS の調査に必要な基本的なログ情報について
　https://jpdsi.github.io/blog/web-apps/LogCollection1/
◆IIS の調査に必要な通信系のログ情報について
　https://jpdsi.github.io/blog/web-apps/LogCollection2/



# LogParser
◆Log Parserでログを統合的に扱い運用保守に役立てる（実践編）
　https://codezine.jp/article/detail/541
　　※印刷用を表示で一気に見る
◆LogParser でIIS解析
　http://100mds.blogspot.com/2013/05/logparseriis.html

# 参考サイト
◆IISのアーキテクチャ基礎（前編）
　https://qiita.com/matarillo/items/2d713603f23b0ac165f3
◆IISのアーキテクチャ基礎（後編）
　https://qiita.com/matarillo/items/c7ec64ae8e3b9a65f5ea

# その他
◆Visual Studio 2015 の IIS Express にIP経由で接続する方法 | asp.net
　https://itblogdsi.blog.fc2.com/blog-entry-136.html
　　※URL ACL
◆Visual Studio 2015のIIS Expressにlocalhost以外からアクセスできるようにする方法
　https://qiita.com/k_saito/items/790884389e0c0611b258
◆IIS Express を外部公開する
　https://qiita.com/ledsun/items/ca77c60aad424438cdd7
◆WindowsのIISでURLのリダイレクト（転送）を設定する（基本編）
　https://www.atmarkit.co.jp/ait/articles/0908/07/news108.html
UTが書きにくいと感じた時に思い返したいメモ

# はじめに

ユニットテストを作っていると、テストコードを書きやすいクラス、書きにくいクラスがありますよね。
ユニットテストを書きにくいクラスのテストコードを頑張って作っても、プログラムに改修が入ると地獄のようなテスト直しが待っており、挙げ句の果てにテストされなくなる、そんな苦い思いをしました。

そもそもなぜユニットテストが書きにくいのか、どうすればいいのか、未来の自分に向けて残します。

# そもそもユニットテストの存在意義について考える

ユニットテスト書きたくないですよね、私は嫌いです。
ではなぜ書くのかを考えてみた。

- 良い動機
    - 実装したコードの動作確認
    - CI/CDでバグ改修がさらなるバグを生んでいないか確認するため
- 悪い動機
    - なんとなく
    - カバレッジが測定できれば品質を保てるという誤解

ユニットテストを作成して一番助かったのは、目視では気付けなかったバグの発見でした。
Input/Outputの検証をしていると、稀に期待通り動かない時があり、よく見るとロジックがおかしかったり。。。と

他にも、バグを修正したと思いきや他のクラスのテストが失敗。。。原因を調べると他にも修正するべきところがあったことに気づく、なんてこともあります。

個人的に一番ダメな例は、カバレッジ網羅のためにユニットテストを作成することですね。
カバレッジを網羅するためにソースを読み、ソースの分岐を通るためのテストを作る。
出来レースの様なテストコードは意味がない。

# ユニットテストを作成する上で意識したいこと

ユニットテストを作成するときは、以下を自問自答するよう心がけるといいだろう。
テストコードは軌道に乗ってしまえば流れ作業のようになってしまうからこそ、
作成の意義や大切にしたい思いを振り返ることが大切。

- ソースコードの中身を細かく見ないで、様々なInput/Outputパターンを試す
    - コード作成時には気づかなかったバグを発見できる
    - コード作成時には気づかなかった使い方を閃く
- ユニットテストは、ソースコード作成から少し日を開けて作る
    - ソースコードの中身を把握していると、どうしても分岐を通るためのテストになりがち。。。
- テストの実装が難しいと感じたら一旦立ち止まる
    - おそらくソースコードが難解
    - テストが実装できないようなソースコード、果たして数ヶ月後に見返して実装意図が思い出せるだろうか
    - 頑張って実装したテスト、ソース改修が発生するたびに直せる？

# ユニットテストの作成を妨げる要因

ここにきてやっと本題だが、ユニットテストの作成を妨げる要因はなんだろうか。
様々なブログ、本でユニットテストのあるべき姿が紹介されているが、
あるべき姿とかけ離れた成果物ができてしまうのは何故なのか、
ということを真面目に考えてみた。

要因は、大きく分けて２つあると思う。

- 考え方
- モチベーション

それぞれの要因について、細かく話を進めていく。

## 考え方

ユニットテストの考え方自体に問題があるのではないだろうか、という観点を掘り下げていく。
ユニットテスト自体が悪いわけではなく、ユニットテストの捉え方の問題である。

テストは、元のソースコードを試験するものである、これは当たり前。
バグが発見されたから治す、これも当たり前。
では、テストコードを作成するには少々難解であったり長いロジックであったが、頑張ってテストを実装した、これはどうだろうか。
私としては、NGである。

何が言いたいかというと、ユニットテストをリファクタリングのきっかけにしてもいいのではないだろうか。
俗に神クラスと呼ばれる超膨大なクラス、メソッドをテストする意味があるのだろうか、ないと思う。
やるべきことは、ユニットテストの実装に手こずるようなクラスやメソッドを、リファクタリングすることなのではないだろうか。

テストをしやすいように元のソースコードに手を加えることに対して抵抗感を感じるかもしれない。
しかし見方を変えれば **単純明快にする** 、 **結合度を下げる** 等と捉えることができるのではないだろうか。

## モチベーション

ユニットテスト作成に最も大切なこと、それはモチベーション管理である。
ソースコードを作成している時のワクワク感に比べ、ユニットテストのつまらなさといったら。。。（私の私見です

しかし、ユニットテストはコード作成者の使命だと思っています（だって、ユニットテストだけお願いするのはちょっと。。。

じゃぁモチベーションを維持するためにはどうしたらいいか、
ソースコード製造の４、５倍の期間を確保したい。

ユニットテストは、パターン出しと実装の繰り返しだと考えている。
１日に何度も何度もテストを作っていると、昼食後や夕方のタイミングで思考力が低下し、
パターンのだし漏れや、単純作業によるパターンの実装漏れが発生しかねない。
（最悪の場合、気力が湧かずにカバレッジだけ網羅して終わりなんてことも。。。

１日のうちで精度の高いユニットテストを作れる時間帯は決まっていると思うので、
せいぜい１日半分程度の稼動でテストを作り終えるくらいの期間を設けることがベストなのではないだろうか。

# 最後に

ユニットテストは品質の向上に有効である反面、ただの時間の無駄遣いにもなりかねない。
いっそのことテストをしない勢力も見かけるが、人の出入りが激しいIT業界で作成者に依存してしまうような作り方は、私は好まない。

泥臭いやり方ではあるが、少しでも存在意義のあるユニットテストを作成していけるよう、
今後も模索していきたい。
mysqlが起動しない

業務ではdockerを用いててたけど、プライベートで開発しようとした時にmysqlでえらい詰まったのでメモ

悩まされていたエラー

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
```

```
ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxxxx.ftth.ucom.ne.jp.pid).
```

他の記事で原因としてよく挙げられていたのが以下であった
・ mysql.serverを起動していなかった
・ 必要なファイルの権限が正しくなかった

確認したこと
・/tmp/mysql.sockがあるかどうか → ある
・/tmp/mysql.sockの権限 → _mysql（mysqlの実行ユーザーなので正しい）
・export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" がbash_profileに記述されているか => パスは通っていて呼びだせる
mysqld_safeを起動できるか -> できない

結論
- 1. mysqlをアンインストール

```
brew uninstall mysql@5.7
```
- 2. アンインストール後も /usr/local/var/mysql 以下の関連のファイルが削除されていなかったため削除

```
sudo rm -rf /usr/local/var/mysq
```

- 3.再インストール

```
$ brew install mysql@5.7
```

- 4. sockを再作成、権限を変更

```
$ touch /tmp/mysql.sock
$ chown _mysql /tmp/mysql.sock
```

- 5. 新しく作成された関連ファイルの権限が自分になっていたので_mysqlに変更

```
$ sudo chown -R _mysql:_mysql /usr/local/var/mysql 
```

これで動いた


参考
https://qiita.com/_natsu_no_yuki_/items/ae4c94187093e4ab3cdc
【swift】 時間経過で背景色のグラデーション変化 (自分専用アプリ開発その２)

毎日少しでもさわって新しい機能をつけていこう、というコトで。

### 画面イメージ
<img width="294" alt="スクリーンショット 2019-06-18 0.11.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/2c2ca9f0-1ed5-5855-5335-832b1b5f90c2.png">
<img width="298" alt="スクリーンショット 2019-06-18 0.11.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/8a3f563d-507f-406b-7020-79668b5830e9.png">
<img width="294" alt="スクリーンショット 2019-06-18 0.12.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/b491430e-217f-5084-bdbc-327b9932367a.png">


### ソース

サンプルとして上げるには
余計なロジックが多すぎるので、肝心な部分だけ。

```swift:ViewController.swift

    func timerFiring() {
        let timer = Timer(timeInterval: 0.2,
                          target: self,
                          selector: #selector(updateColor),
                          userInfo: nil,
                          repeats: true)
        RunLoop.main.add(timer, forMode: .default)
    }

    func updateColor() {

        //グラデーションの開始色（上下）
        //タイマー処理でRGB値を少しずつ変化させてセット
        let topColor = UIColor(red: tBgRed, green: tBgGreen, blue: tBgBlue, alpha: 1)
        let bottomColor = UIColor(red: bBgRed, green: bBgGreen, blue: bBgBlue, alpha: 1)
        
        //グラデーションの色を配列で管理
        let gradientColors: [CGColor] = [topColor.cgColor, bottomColor.cgColor]
           
        //グラデーションレイヤーを作成
        gradientLayer?.removeFromSuperlayer()
        gradientLayer = CAGradientLayer()
        //グラデーションの色をレイヤーに割り当てる
        gradientLayer!.colors = gradientColors
        //グラデーションレイヤーをスクリーンサイズにする
        gradientLayer!.frame = self.view.bounds      
        //グラデーションレイヤーをビューの一番下に配置
        self.view.layer.insertSublayer(gradientLayer!, at: 0)
    }
```

### ポイント

ポイントとしては、`gradientLayer?.removeFromSuperlayer()`を入れたこと。これを入れないと、updateColor()をtimerで繰り返し呼出し実行をしても最初にセットされた配色から更新されなかったです。
ちなみに配色に関しては、自分は上下のRGB値をそれぞれランダムなペースで０〜255の間を往復させるような処理として書いてます。
（現状そこは雑なロジックなので、キレイにまとめたら別の記事として投稿したい）

### 感想
机の上の充電スタンドに立てかけてたら、席の近くに来た人が「あれ、さっきと色違う・・・」みたいなアイキャッチになればいいかな、と。
変換/無変換キーをUS配列キーボードでも使いたい

JIS配列のキーボードにはあまり使わないキーがいっぱいあって、その代表格が変換キーと無変換キーです。
でも、スペースの両隣という最高の位置に普段使わないキーがあるのはとても便利で、
たとえばIMEのオンを変換キー、オフを無変換キーに割り当てるとプログラミングがとってもはかどります。

そんな背景で、僕はいつもJIS配列のキーボードをUS配列として認識させて使っています。
でも、わけあってUS配列キーボードを使わざるを得ない時、あの洗練されたキーボードには変換/無変換キーがありません。
そこで、無理やり変換/無変換キーを実現できるようにするのが本記事の目的です。

## xdotool の導入

Linux にはキー入力やマウス操作をコマンドラインでシミュレートしてくれる xdotool コマンドがあります。
Windows とか Mac は知りません。なんか適当に同じようなやつを探してください。

xdotool で、無変換キーの押下をシミュレートするには

```bash
$ xdotool key 0xff22
```

変換キーの押下をシミュレートするには

```bash
$ xdotool key 0xff23
```

とします。

## キーボードショートカットに登録

Ubuntu だったらキーボードショートカットを簡単に登録できます。
ここでは、US配列でもあまり使われないキーである「メニューキー」（右Altの隣りにあるやつ）を

```bash
$ xdotool key 0xff23
```

のショートカットとして登録すれば、メニューキーを押した時に無変換キーを押すことと同様の効果が得られるはずです。

しかし、これには落とし穴があって、「メニューキー」を押した瞬間に無変換キーの押下がシミュレートされてしまうので、実際には「メニューキーと無変換キーを同時に押した」と判断されてしまいます。
これを防ぐためにちょっとHackyですが

```bash
$ bash -c "sleep 0.5 && xdotool key 0xff23"
```

のように、スリープを挟んで「メニューキー」の押下が終わった頃に無変換キーの押下がシミュレートされるようにしましょう。

同じようにたとえば Shift + メニューキー というキーボードショートカットに

```bash
$ bash -c "sleep 0.5 && xdotool key 0xff22"
```

を割り当てておけば、変換キーの押下をシミュレートすることができます。
【秀丸マクロ】#ifdef等のカラー表示

##userhilight.mac

```cpp
call Initialize;
call Main;
endmacro;

Initialize:
	$FILE_NAME = "userhilight";
	$PATH = settingdir + "\\" + $FILE_NAME + ".hilight";
	return;

Main:
	call Hilight;
	return;

Hilight:
	question "はい：LOAD　いいえ：OPEN";
    if( result == yes ) {
		loadhilight $PATH, 1, 0x00000010;
    }
    else
    {
        openfile $PATH;
    }
    return;
```

##userhilight.hilight (settingフォルダに入れる)
```cpp
/<Defines>
/////////////////////////////////////
//---#ifdefで有効にする#define値---//
/////////////////////////////////////

/<DefinesInvalid>
/////////////////////////////////////
//---#ifdefで無効にする#define値---//
/////////////////////////////////////


/<Ifvalue>
/////////////////////////////////////
//---#ifで有効にする式の内容-------//
/////////////////////////////////////


/<IfvalueInvalid>
/////////////////////////////////////
//---#ifで無効にする式の内容-------//
/////////////////////////////////////
```
スケジュールに乗せるバッファはどれぐらいが適切か？ - 二乗和平方根法（SRSS法）

多くのプロジェクトでは、個々の作業を洗い出してそれぞれの作業時間を見積もり、スケジュールを引く。
この時、見積りに対してある程度バッファを乗せるケースは多いだろう。
<img width="458" alt="スクリーンショット 2019-06-17 15.25.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28691/960ca253-ce78-a7c7-e2bb-a4a12e170d3f.png">
スケジュールに乗せるバッファはどれぐらいが適切なのだろうか。

あるシステム開発会社では、見積もった合計日数の50%をバッファとして加えるよう、社内のプロジェクトに推奨している。
別の会社では、個々の作業の作業時間見積りに20%を上乗せしている。
バッファの大きさを感覚値で決めている方もいるだろう。

この記事では、SRSS法という数式を用いたバッファの算出法を紹介する。
# そもそもなぜスケジュールにバッファを乗せるのか？
スケジュールにバッファを乗せる理由は、プロジェクトを不確実性から守るためだ。

不確実性が0のプロジェクト、すなわち未来は全て見えていると断言できるプロジェクトであれば（そんなプロジェクトはないと思うが）バッファは必要ないだろう。
また、不確実性をいくらか含んだプロジェクトであっても、遅れた時の損害がないのであれば、こちらもバッファは不要ではないだろうか。

一方、プロジェクトが不確実性を含んでいて、かつ遅れた時に損害を伴う場合は、バッファを乗せることは立派なリスクマネジメントとなる。
そして、この不確実性が小さければバッファもそれほど必要ないが、不確実性が大きければ、それを吸収できるだけの十分なバッファが必要になるだろう。
# 見積りは幅をもった値である
バッファの算出法を紹介する前に、前提として、見積りが幅をもった値であることを述べておく必要がある。

「ログイン機能には3日かかります」という見積りを出す時、あたかも見積りが3日というただ1つの解として導き出せるかのように振舞っている。
しかし、見積りは実際には「順調にいけば3日、遅くとも5日ぐらいと見込んでいます」というようにある程度の幅をもった値になるのではないだろうか。
なぜなら、見積りは現時点で見えているだけの不完全な情報から完了日を予測する行為だからだ。予定完了日を変動させる要因はいくつもあるだろう。
# 見積りの幅からバッファを算出する例 - 二乗和平方根法
前述した見積りは、「50%の確度で3日、90%の確度で5日と見込んでいます」という言い方もできる。

そして、この2点の見積りが散らばっているほど、不確実性の大きい作業と言えるだろう。つまり、3日〜5日の機能よりも、3日〜8日の機能のほうが、見えていない部分が大きく、遅れるリスクが高い機能ということだ。
したがって、バッファを不確実性の大きさに応じて確保するものと考えれば、この2点の見積りが散らばっているほどバッファも大きくするべきということになる。

さて、散らばり具合を表す数値として標準偏差という値がある。
二乗和平方根法は、この2点の見積りの標準偏差をバッファとする算出法だ。

以下の式で算出することができる。
<img width="360" alt="スクリーンショット 2019-06-17 15.46.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28691/9073bd3d-bb3b-11dd-78fa-ea7d3ab430e4.png">

例えば、3日〜5日のログイン機能、5日〜10日の記事一覧機能、4日〜6日の記事詳細機能から成る開発スケジュールであれば、次のようになる。
<img width="315" alt="スクリーンショット 2019-08-09 13.56.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28691/09dc40c1-de79-5bb4-5a54-27afd35fcb21.png">
<img width="458" alt="スクリーンショット 2019-08-09 13.53.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28691/87704dae-9eb3-67b3-35ee-f46ac783755f.png">
このように、2点見積りの標準偏差からバッファを求めることで、不確実性の大きさに応じたバッファを、一つの計算結果として求めることができる。

ちなみに、最初から全ての作業に90%見積りを適用すれば良いのではと思われた方もいるかもしれない。確かにそのほうがより安心できる。
しかし、何もかもが最悪のケースになる可能性はほとんどないだろう。であれば、必要以上に時間とお金を使う選択は避けるべきだ。
また、パーキンソンの法則（仕事の量は、完成のために与えられた時間をすべて満たすまで膨張する）を防ぐ効果もある。バッファのつもりで個々の作業に90%の見積りをあてても、その90%を満たすまで作業が膨張すれば、結局はバッファがないことと同じになってしまう。
# バッファは水増しではなく、スケジュールの信頼性を上げるための工夫
バッファを乗せたスケジュールを顧客に見せづらいと感じるプロジェクトマネージャーもいるかもしれない。
しかし、バッファを乗せることに後ろめたさを感じる必要はない。
バッファは水増しではなく、不確実性の中にあってもスケジュールの信頼性を上げるための工夫だからだ。

良いスケジュールとは、無理に早めたスケジュールではなく、プロジェクトを取り巻く関係者たちが信頼できるスケジュールである。
なぜなら、そのスケジュールを元に様々な意思決定が下されるからだ。

もちろん、見積りが将来の予測である以上、このやり方で算出したバッファを積めば100%スケジュール通りにいくと断言できるものではない。
しかし、バッファがスケジュールの信頼性を上げていることは間違いないだろう。
そして、顧客から「なぜそれだけのバッファを確保したのか？」と問われても、説得力をもって答えられるはずだ。
# 参考
[Project Management Institute, Inc. - Critical chain buffer sizing](
https://www.pmi.org/learning/library/critical-chain-project-management-theory-7118)
[アジャイルな見積りと計画づくり](https://www.amazon.co.jp/dp/B00IR1HYGW)
私なりの「これからプログラミングを学ぶ人へ」

*お前誰や.*

はい，誰もが思う質問だと思います．

私は情報系の学部に在籍しているPaSeRiと申します．学部4年(B4)です．高校までは普通科に通っていて，プログラミングを学んだ期間は，大学に入ってからの3年と少しです．

気がつけばB4，進学するか就活するかを決める時がきまして，私は就活の道を選びました．そんな私が，就職活動をする中で振り返ったこの3年間を踏まえて，**私なりの「これからプログラミングを学ぶ人に向けて」**を書いてみたいと思います．

たった3つの考え方になります．誰でも思いつきそうなものですが，そこはご了承ください．誰かの参考になれば幸いです．



# 「これからプログラミングを学ぶ人へ」

## 1. 初心忘れるべからず

*「あなたがプログラミングを学ぼうと思ったきっかけはなんですか？」*

これ，よく就職活動で聞かれる質問の1つなんです．採用担当者がどのような意図で聞いているのかは知りませんが，私は就活関係なく，この質問に対する答えを常に頭の片隅に置いておくことが重要だと思います．

なぜなら，これが**あなたを動かした最初の原動力だから**です．

私のきっかけは「中学生の時，同級生がVBSを教えてくれたから」です．普通の学生だと聴き慣れない言語ですよね．RPA(Robotic Process Automation)に携わっている方であれば聞いたことあるかもしれません．Windowsで動くスクリプト言語です．

そのきっかけがあったので，自分の考えた通りに，パソコンで動くものが作れる感動を覚えました．そこから**自分の案をプログラミングで実現したい！**と理由が生まれ，進路が決まりました．

もし，これからプログラミングを学ぼうとしているなら，学ぼうと思った最初の理由やきっかけは忘れないでください．新しい言語や技術を学ぶ上で，支えになると思います．



## 2. 目的こそ学習意欲

目的は学習に直結すると考えています．

「<u>iPhoneアプリ</u>作りたいなぁ，<u>Swift</u>やってみようかな．」

「<u>人工知能</u>に興味があるし<u>Python</u>使って画像解析してみようかな」

といった漠然としたもので構いません，何か興味を持ち，それを作ろう，習得しようという目的を持ってみてください．特に**何かを作りたい**という気持ちの効果は大きいです．

授業と同じように教科書を読んで，例題解いて，次の章へ進む．これほど独学で何かを学ぶのに非効率的な方法はないと思います．だって，**作りたいもの**さえあれば，それを作る間に必然的に<u>調べ</u>，<u>覚え</u>，<u>使う</u>じゃないですか．もし，漠然としすぎてて，最終的に完成はできなくとも，そこまでで得た知識は，使いながら覚えた分，**定着率も高い**はずです．

実際私も，「Pythonを使って，Macの常駐アプリケーション作ってやる」と思いながら学習していました．なんで常駐アプリにPython？と思ったそこのあなた，いい質問ですね．

技術的に可能ならば，**目的に対して最適解を持ってくる必要はない**ということです．Pythonだって，ライブラリを使えば，割と簡単に常駐アプリを作れます．Pythonを覚えたい時期と，常駐アプリでこんな機能欲しいなぁと思っていた時期が重なったので，結果こうなっただけです．むしろ，**欲しいアプリがあるという目的**が固まっているからこそ，Pythonをしっかり学べました．

いますぐ見つける必要はありません．何か作ってみたい！そう思った時に，新たな知識をついでに取得してみませんか？



## 3. あればいいのに，で終わらせない

普段何気なく過ごしていて，**「あれば便利なのになぁ」**と思うことはありませんか？誰もが便利と思うようなものである必要はありません．ちょっとした作業の自動化など，その程度のものを思い浮かべてください．

私が大学生活を過ごす中で，あれば便利だなぁと思ったことの例を以下に挙げてみます．

- 大学のシャトルバスの時刻表，PDFじゃなくてウィジェットでみれたらなぁ
- 研究で使うログのテキストデータ，中身見て仕分けるの面倒臭いなぁ，自動化できないかなぁ
- 空き教室有効活用したいなぁ，簡単に調べられたらなぁ
- 複数のプログラムを走らせる時に，その数だけターミナル(コマンドプロンプト)を実行するのは面倒臭いなぁ

こんな感じです．

もちろん，自分しかいらないだろってものが多いです．それはつまり，<u>この要求を満たすプログラムはダウンロードしてこれない</u>ということです．そこで諦めてはもったいない．せっかく自分で書ける環境を持っているのですから，作ってみましょう．それこそ，2. で話した「**目的**」です．

ちなみに上に挙げた例，全て自分で解決しました．でも，実用性はないものが多いです．空き教室検索するプログラムなんて，GUIはもたせましたが，PC用なので気軽に検索できないし．しかし，作る間に得た知識は今でも活かせます．

つまり，伝えたいことは1つ．せっかくの機会，見逃してませんか？ということです．あればいいのになぁで終わらせず，無いなら作ってやるという思考に切り替えてみましょう．



# 最後に

成長するには，もっと重要なことはあるかもしれません．私が挙げたのはあくまで，気持ちの問題に近いところです．

プログラミング，楽しんでください，何事も楽しくないと続きません．

良きプログラミングライフを！！
npm で提供されている JavaScriptのライブラリを Webブラウザからライブラリとして呼び出したい

## やりたいこと

長いけど、タイトルに書いてある通り。scriptタグで読み込みました。ハイ、動きましたー!ではなくて、

```javascript
<script src="/path/to/myLibrary.js" type="text/javascript" ></script>
<script>
const mymodule= new MyLibrary.MyModule({"param1": "value1"});
</script>
```
みたいな事をしたい。

## tl; dr 

webpack で babel を利用して、トランスパイルするときに　`library` を指定する。

## webpack と npmを利用するライブラリ

```json:webpack.config.js
module.exports = {
～ 省略 ～
	entry : {
		"MyLibrary" : './src/my-library.js',
	},
	output : {
		library: 'MyLibrary',
		libraryTarget: "umd",
		filename : '[name].bundle.js',
		path : path.resolve(__dirname, './dist')
	},
	module : {
～ 省略 ～
        }
}
```

```javascript:./src/my-library.js
class Auth {
	constructor(config) {
		console.log(JSON.stringify(config));
	}

	auth( userName, password ) {
		// npm のモジュールを利用した認証処理を実装;
	}
}

export { Auth }
```

## ブラウザ
```html:index.html
<!-- webpack が出力したファイルを読み込む -->
<script src="'/path/to/MyLibrary.bundle.js" type="text/javascript" ></script>

<script type="text/javascript" >

// webpack.config.js の output.library に指定した名前で グローバルなオブジェクトがある。
// 中身は { "Auth": Authクラス , __esModule: true } 
console.log(MyLibrary);
// クラス Authを利用する
const auth = new MyLibrary.Auth({"pool_id": "my_pool_id"});
auth.auth("user-name", "password");
```

グローバルなオブジェクトを作ってしまうのは気になるけど、無事に呼び出せた。`import` で利用で利用するための方法は課題として先送り。

## 参考資料

### 公式
* https://webpack.js.org/guides/author-libraries/
* https://webpack.js.org/configuration/output/#outputlibrary

### 公式へたどり着くまでに、参考にさせていただいた
* https://stackoverflow.com/questions/33148787/how-expose-a-exported-function-into-global-scope-with-babel-and-webpack
* https://qiita.com/jkr_2255/items/283bc12dd07bc237179e
【PHP】ストリームってなに？


## PHPのストリーム
https://www.php.net/manual/ja/intro.stream.php

>ストリームは、 ファイル、ネットワーク、データ圧縮などに関する、 共通した一連の関数群と利用法を持つ操作の一般化の手法です。

正直よくわからないので[YYPHP](https://qiita.com/tags/yyphp)で質問させていただきました。

## PHPのストリームと一般的なストリームは若干異なる

PHPにはストリームという機能がある。
ストリームのアルゴリズムとは少し違う話。

## 共通していること

データの総量が確定していないものを扱う処理を[ストリーム](http://e-words.jp/w/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0.html)(ストリーム処理)と言われることが多い。

大量のデータを水が小川を流れるように少しずつ処理をする。

## PHPのストリーム
入出力を扱う機能。
CSVを1行ずつ読み込んで、DBに保存したりするイメージ

・ストリーム関数
例：[fread](https://www.php.net/manual/ja/function.fread.php), [stream_get_contents](https://www.php.net/manual/ja/function.stream-get-contents.php)
〇〇バイトずつ読み込む、というような処理。

・ストリーム処理じゃない関数
例：[file_get_contents](https://www.php.net/manual/ja/function.file-get-contents.php)
全データを取得してくる
何十メガバイトもあるような大きいファイルを読み込むとPHPのメモリが足りなくなってエラーが起きたりする。

### ストリームフィルタ
https://www.php.net/manual/ja/stream.filters.php
>フィルタ は、ストリームから読み込まれたり、 あるいは、ストリームから書き込まれたするデータに対して何らかの操作を行う、 最終段階にあるコードです。 PHP スクリプトの内部で、 stream_filter_register() を使って、 あるいは拡張モジュールの内部で ストリームの作成 に示された関連する API を使って、カスタムフィルタを作成することができます。 現在登録されているフィルタの一覧を取得するには、 stream_get_filters() をお使いください。

ストリームで入出力するデータに対して操作ができるっぽい。
フィルターっていうくらいなので、流れてくるデータに対してフィルター（コーヒーのフィルターみたいな）をかけるイメージで良さそう。

[利用できるフィルタのリスト](https://php.net/manual/ja/filters.php)
[PHPのストリームフィルタでCSV読み込み](https://qiita.com/rana_kualu/items/dc99be34b9e2f721b70f)

### ストリームコンテキスト
https://www.php.net/manual/ja/stream.contexts.php
>コンテキスト は、ストリームの挙動を変えたり、 拡張したりすることのできる パラメータ と ラッパー固有の オプション の集合です。 

ストリームフィルターの振る舞いを変える設定などを渡せるようになる。
https://www.php.net/manual/ja/context.php

例：file_get_contensの第３引数
file_get_contensの内部の振る舞いを変える。

※file_get_contensはPHPの関数としてはストリーム処理ではないが、file_get_contensの内部（C言語レベル）ではストリーム処理を行なっている（多分）。
その振る舞いの設定を変えるもの。

### ラッパー
https://www.php.net/manual/ja/wrappers.php
>PHP には多くの組み込みラッパーが用意されています。さまざまな URL 風のプロトコルによって、 fopen() や copy()、 file_exists() そして filesize() といったファイルシステム関数で使用することができます。 これらのラッパーだけでなく、 stream_wrapper_register() 関数でラッパーを自作することもできます。

php:// 
://の前の部分、自作することも可能
[ストリームラッパーとして登録するクラスの例](https://www.php.net/manual/ja/stream.streamwrapper.example-1.php)

# 参考
[YYPHP#87「PhpStorm有効活用術」「自社サービス開発と受託開発の違いとは？」「ポートフォリオにどんな内容が必要？」](https://qiita.com/suin/items/93dd258fccfe926bbba3)

[YYPHP #88「どんなバリデーションをどこでやる？」「エンジニアの転職活動ってどんなの？」「もっと快適な開発環境」「php-javaをどうして作っているか？」](https://qiita.com/suin/items/4b86b45f22a24c46756c)
RxSwiftのHot/Coldを理解する

# はじめに
RxSwiftを理解するにあたり、Hot/Coldは一つの関門だと思います。そこで各特徴だけをまとめてみました。

# Hotの特徴

* HotなObservableはsubscribeされなくても動作する
* HotはObservableは前のColdを動作させる
* HotなObservableは分岐できる
    * HotなObservableはObserverを複数持てる
* HotなObservableのイベントは各Observerで共有される
    * 各Observerに対して同じイベントが送出される。つまりそこまでのColdは何度も呼ばれない(分岐の性質)
    * すでに流れたイベント(Next)は送出されない。つまり途中からsubcribeすると途中からしか受け取れない。

# Coldの特徴
* ColdなObservableはsubscribeするまで動作しない
* ColdなObservableは分岐できない
    * ColdなObservableはObserverを１つしか持てない

# SubjectはHot

* Publish Subject
* Behavior Subject
* Relay Subject

# ほとんどのオペレータはCold。Hotに関連するオペレータは少数
## Hotに関連するオペレータ

* ConnectObservableを返すオペレータ
    * multicast()
        * Subjectを指定して一旦イベントを受けるようにする
    * publish()
        * PublishSubjectに、multicastする
    * replay()/replayAll()
        * ReplaySubjectに、multicastする

### ConnectObservableとは
* connect（）メソッドを呼ぶことで、Hot変換が完了する。
* 複数のObserverがHot変換されたストリームを最初から受け取りたいときに使用する。connect()を呼ぶまで動作しないので、その間にすべてのObserverをsubcribeさせておくことができる。

## 上記以外のオペレータ

* share()
    * 内部的には、publish().refCount()
* refCount()
    * Hotだがsubcribeするまで動作しない。内部的には、最初にsubcribeされた時点でconnectを呼ぶ。
* shareReplay()
    * 内部的には、publish().refCount().replay（）
    * 「Hotだがsubcribeするまで動作しない」を守りつつ、指定された個数だけ値をreplayする。RxSwiftのExampleでもよく使用されている。
    * 変数的に扱いつつ、再計算させないようにするときに、shareReplay(1)をつけると良い。
* shareRelayLatestWithConnected()
    * Driverはデフォルトで同じ動作をする。connect中でないと最後の値が取れない。一度.completedが流れたら、そのあとにはreplayされず.completdしか流れてこない。


## さいごに
Hot/Coldの特徴、Hot変換についてまとめたので、それぞれの違いについて分かりやすくなったかと思います。

# 参考
[今日こそ理解するHot/Cold](https://www.slideshare.net/yukitakahashi3139241/hot-cold)
[今日こそ理解するHot変換](https://www.slideshare.net/yukitakahashi3139241/hot-64131190)
Dockerコンテナ上のTomcatに外部のブラウザからアクセスする方法

- 環境
    - 外部:Windows10 64bit
       - Dockerコンテナへはリモートデスクトップで接続している
    - Dockerホスト:
        - CentOS Linux release 7.6.1810 (Core)
        - Docker version 18.09.6, build 481bc77156
        - docker-compose version 1.24.0, build 0aa59064
    - Dockerコンテナ
        - CentOS Linux release 7.6.1810 (Core)
        - Tomcat v6.0

# やりたいことのイメージ
![2019-06-14 17.33.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/2a8935c4-442d-425d-39cb-08e9431c6747.jpeg)

# 1. `docker-compose.yml`にTomcat用のポートを設定する

```yml:docker-compose.yml
# 省略
    build:
      context: .
      dockerfile: doubutu/Dockerfile
      args:
        USER: ponsuke
        PORT: 8080
    ports:
      - "8082:8080" # リモートデスクトップ用のポート
      - "{Tomcat用ホストのポート}:{コンテナでのTomcatのポート}"
# 省略
```

# 2. コンテナを作る
[自分のコンテナだけ作り直す方法](https://qiita.com/ponsuke0531/items/960b1da7e1656c5d6ce3)

```bash
$ docker-compose up -d --build {コンテナ名}
Building {コンテナ名}
Step 1/56 : FROM centos:7.6.1810
 ---> f1cb7c7d58b7
# 省略
Recreating {コンテナ名} ... done
```

# 確認する

```bash
$ docker ps
CONTAINER ID    IMAGE             COMMAND          CREATED             STATUS              PORTS                                                                              NAMES
{コンテナID}    {イメージ名}      "/usr/sbin/init"  About an hour ago   Up About an hour    0.0.0.0:8082->8080/tcp, 0.0.0.0:{Tomcat用ホストのポート}->{コンテナでのTomcatのポート}/tcp  {コンテナ名}

$ docker port {コンテナID}
8080/tcp -> 0.0.0.0:8082
{コンテナでのTomcatのポート}/tcp -> 0.0.0.0:{Tomcat用ホストのポート}
```

# 3. Tomcatを起動して外部のブラウザから接続する
1. Tomcatを起動する
1. 外部のブラウザで`http://{ホストのID}:{Tomcat用ホストのポート}`を表示する

# 参考
- [Docker Compose - CLI リファレンス - Qiita](https://qiita.com/zembutsu/items/eca797efaed39ec7b906)
- [Linuxで開いているポートを確認する方法 | mzgkworks.com](http://mzgkworks.com/post/linux-port-confirm/)
What’s New with Chrome and the Web (Google I/O ’19)

[動画本編] (https://www.youtube.com/watch?v=rUUazNIZW7I)

#What’s New with Chrome and the Web (Google I/O ’19)　TL;DR
話していた内容をとりあえず順番に書き出しました。

##冒頭挨拶
・昨年9月にchromeが出て10年、UIのメジャーアップデートをした。そしてgoogleができて20年、webができて今年で30年

###webプラットフォーム向上の３つのゴール
1. instant-どこにいてもすぐwebが見れる(人々が新しいコンテンツを見つけ続けることができる)
2. powerfull-ウェブの力をより広げる（世界中の情報やサービスを見つけられる）
3. safe-使用者は安全であり続けるべき

webはまだまだinstantでない。課題たくさん。

##Lazy loading
画像を表示に必要なタイミングでロードする新しい機能。
ユーザーがスクロールした時に画像読み込みを自動管理。
タグに追記するだけ。

``` 
<img src="countdown.jpg" loading="lazy" alt~~>
```

ユーザーの接続速度から読み込みタイミングを自動判断し、プレースホルダーのサイズ決めのため画像の最初2kBだけを取得する。
iframeでも使用できる。

##Lighthouse
Dev toolsに組み込まれている。
「パフォーマンスを改善する様々な最新の機能」の使い方を提示するためにサイトを解析するもの。
jsonファイルを取得してリソース予算（制限）などを設定。
パフォーマンス予算（performance budget）を決めて実行するとパフォーマンスもよくなるしユーザーからも愛されるものになる。

##Search ConsoleにSpeed Report追加
URLレベルでのインサイトと、どのように改善できるかの情報を提示。
firebaseチームはFirebase Performance Monitoringを発表した。

##paint holding
ページ読み込み時に画面が一瞬白くなる現象を防ぎ、シームレスな表示を可能にする。
canaryで利用可能。

##portals
(11:45からデモ）
複数サイト間を流動的に移動できる。（デモ見た方がわかりやいかもです）
マルチページサイトをSPAっぽくもできる。
APIはcanaryで公開。

##web packing
開発者が署名付きページを作成し、どこからでも（ピア機器からでも）ロードできる。
パッケージ取得のためのデータがオリジンサーバーに戻らないからプライバシーが安全なプリロードモデルとなる(?)

##perseption-toolkit
(18:54~デモ）
カメラでバーコードや画像（デモではロゴ画像)をスキャンして読み込み、ページ遷移を行う。

##Desktop PWA
デスクトップPWAとして2019年版マインスウィーパーつくった　-> [proxx.app](https://proxx.app/)
フィーチャーフォンでもうごく。
デスクトップPWAはいろんなサイトで使われてる。

##Duplex on the Web
アシスタントの翻訳機能。動画ではヒンディー語使用者に対し英語のECサイトをヒンディー語に翻訳。
robot.txtで制御できる（？）

##Cookieについて
今後はCookieはファーストパーティのcontextに限定。
Cookieを第三者が見えるようにするにはsamesite noneという新しい設定をcookieに追加する。
サードパーティのcookieはHTTPS接続でのみ提供。

##WebAuthn
これからはweb上でパスワードではなく生体認証を使いましょう。（新しいweb標準)
サインインまでの時間も大幅改善されます
（yahoo Japanはこれにより時間を37.5%削減）
WEBサーバのインストール

# 概要
- PHPを先にインストールしただけだったが、httpd2.4がすでに入っていた。
- nginxを使いたいので、nginxをインストールし、httpd を無効化する。

# やったこと
- [nginx.repo] を追加
- nginx のインストール
- 起動・自動起動
- 簡単なリバースプロキシの設定

# リポジトリの追加
- [/etc/yum.repos.d/nginx.repo] ファイルを作成

```
$ sudo vi /etc/yum.repos.d/nginx.repo
```
- 中身を以下に書き加える

```
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```

# nginx のインストール
```
$ yum install nginx
```

#起動・自動起動
```
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
```
起動してみたら、サーバのIPアドレスへ接続。

するとこんな画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387311/12bee396-b1a4-57f6-5813-935b81b9e1c9.png)

```
# index.html デフォルトのパス
/usr/share/nginx/html/index.html
# nginx の設定ファイルのパス
/etc/nginx/conf.d/*.conf
```

#簡単なリバースプロキシの設定
[こちら](https://qiita.com/MuuKojima/items/afc0ad8309ba9c5ed5ee)を参考に設定しました。

[/etc/nginx/conf.d/] 直下に[*.conf]という命名でファイルの作成

```
$ vi /etc/nginx/conf.d/server.conf
```
server.confを新たに作成

```
server {
     listen 80;
     # アクセス可能なIPアドレス、もしくはドメイン
     server_name hoge.com;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     proxy_max_temp_file_size 0;
     # ローカル側のポートの設定
     location / {
        proxy_pass http://localhost:8000;
     }
}
```

このファイルを作成し、再起動

```
$ sudo systemctl restart nginx
```

#### リバースプロキシとは？
- ユーザからの応答を、一時的に受けて指示を出す人。
- フィルタリング機能や、リクエストをどこへ渡すのか、などを行う。
- また、キャッシュすることでキャッシュデータから応答することが出来るため、動作向上も見込める。

★ネットワーク関連わからない場合は、[こちら](https://qiita.com/growsic/items/fead30272a5fa374ac7b)を見るとお勉強になります。

# おわり
とりあえず、簡単なwebサーバの設定は終わりです。
次回は、Wordpress のインストール&設定！！
設定のときに、DNS当ててしまおうーっと。
リモートサーバのDocker上で起動したJupyter Notebookに他端末からアクセス

# はじめに
研究室のマシン上のDockerでJupyter Notebookを使う際に自分のmacからアクセスできるようにしたときの話です。
他の方の記事を見ながら作業する上でつまずいた点を中心に書きます。


# 概要
リモートサーバのDocker上で起動したJupyter Notebookに他端末からアクセスする。


# ポイント
1. Dockerの起動時にポートを指定
- Jupyter Notebook起動時にIPとパスワードを指定
- SSH Port Forwardingを使って、他端末のローカルホストにリモートサーバをマッピング

# 作業
## 1. Dockerの起動時にポートを指定
Jupyter Notebookはデフォルトでポート番号が`8888`になるのでローカルのポートを割り当てます。

```
$ docker run -p 8888:888 その他オプション
```

## 2. Jupyter Notebook起動時にIPとパスワードを指定
### 2.1 パスワードの設定
`ipython`を利用します。Docker上で`ipython`を実行して、以下のように入力します。

```
from notebook.auth import passwd
passwd()
```
パスワード(決める)を入力すると、暗号化された文字列が発行されます。これはJupyter Notebook起動時に必要になるので、メモしておきましょう。
メモできたら、ipythonは`exit`して問題はないです。

## 2.2 パスワードとIPの指定
`IP`の指定と先ほど作成した`パスワード`の指定を行なってください。
先ほど入力したパスワードをローカルPCからJupyter Notebookにアクセスするときに使うことになります。

```
$ jupyter notebook --ip=0.0.0.0 --NotebookApp.password='sha1:パスワードを設定したときの文字列'
```
Jupyter Notebook起動時に表示される`token`を利用する方法もあるようですが、`token`の入力ではログインページがリロードされるだけでファイルにアクセスすることはできませんでした。(原因解明中ごめんなさい)


## 3. 他端末のローカルホストにリモートサーバをマッピング
Jupyter Notebookを起動するためにsshしたターミナルとは別のターミナルを開いて、SSHログインする。このとき以下のようにマッピングを行う。

```
$ ssh -L 8888:localhost:8888 <username>@<remotehost>
```

この後、ローカルの端末から`http://localhost:8888`にアクセスすると、パスワードの入力画面が現れます。2.1で設定したパスワードを入力すると、無事にJupyter Notebookを開くことができます。


# おわり
前も1度この作業を行なっていたはずでしたが、作業メモがなくて困ったので未来の自分のためにも残しておくことにしました。
エラー内容や細かい作業はついつい必死になってしまうとメモをするのを忘れてしまいますが、ちゃんと残していきたいですね。
下記のページをとても参考にさせていただきました。ありがとうございます。

参考:
[サーバーのDockerで起動したJupyter Notebookを他のパソコンからアクセスできるようにした話](https://qiita.com/yamasakih/items/d23ac0bf773e9b1b4d9d)
[リモートサーバの Jupyter Notebook を SSH Port Forwarding 経由で使う](https://blog.amedama.jp/entry/jupyter-nb-ssh-port-forwarding)
UserAgentをChromeブラウザで変更する方法

## UserAgentをChromeブラウザで変更する方法
UserAgentをサーバーで見てコンテンツを出し分けるパターンも増えてきました。
そこで役に立つのがこのChrome拡張です。
https://chrome.google.com/webstore/detail/user-agent-switcher-for-c/djflhoibgkdhkhhcedjiklpkjnoahfmg

シンプルにUserAgentを変えることができるChrome拡張です。ぜひお試しください。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
CakePHP3　ORマッパーでexists()を使用してデータの存在有無を確認

# サンプルコード
```php
<?php
namespace App\Controller;

use App\Controller\AppController;

/**
 * Sample Controller
 *
 *
 * @method \App\Model\Entity\Sample[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class SampleController extends AppController
{
    public function index()
    {
        // usersテーブルを読み込む
        $this->loadModel('Users');

        // idカラムが[1]の値のデータが存在するか確認
        $result = $this->Users
            ->find()
            ->exists(['id' => 1]);

        /*
         * 【返り値】
         * 存在する場合  => true
         * 存在しない場合 => false
         */
    }
}
```

※ORマッパーについては割愛する。

## 複数条件指定したい場合
- exists()内の連想配列を「,」カンマ区切りで、繋げる。

```php
<?php
namespace App\Controller;

use App\Controller\AppController;

/**
 * Sample Controller
 *
 *
 * @method \App\Model\Entity\Sample[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class SampleController extends AppController
{
    public function index()
    {
        // usersテーブルを読み込む
        $this->loadModel('Users');

        // idカラムが[1]でかつ、nameカラムが['hoge']のデータが存在するか確認
        $result = $this->Users
            ->find()
            ->exists([
                'id' => 1,
                'name' => 'hoge'
            ]);

        /*
         * 【返り値】
         * 存在する場合  => true
         * 存在しない場合 => false
         */
    }
}
```

- **exists()**と逆の動きをする**notExists()**も存在する。
- 【返り値】
    - 存在しない場合 => true
    - 存在する場合 => false

## 参考
- https://book.cakephp.org/3.0/ja/orm/query-builder.html


## SQLの場合

```sql
SELECT *
FROM table1
WHERE EXISTS
    ( SELECT id
     FROM table2
     WHERE table1.id = table2.hoge_id);
```

## 参考
- http://www.sql-reference.com/select/subquery_exists.html
[JS] spliceメソッドの戻り値が、削除された値のみを返すという謎仕様だった件

# spliceメソッドとは
古い要素を取り除きつつ、新しい要素を追加することで、配列内容を変更するメソッドだそうな。
引用：[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
# とりあえずサンプルコード
実行結果は、コメントアウトの「=>」の先に書いてあるものです。

```javascript:とりあえずサンプルコード
let months = ['1月', '3月', '4月', '6月'];
months.splice(1, 0, '2月'); // 配列1番目に「2月」を追加、削除する要素は0個
console.log(months); // => ["1月", "2月", "3月", "4月", "6月"]

months.splice(4, 1, '5月'); // 配列4番目に「5月」を追加、削除する要素は1個
console.log(months); // => ["1月", "2月", "3月", "4月", "5月"]
```
# 構文
```javascript:構文
配列.splice(数字①,数字②,値①);
```
配列：このメソッドを適応させる（対象の）配列
数字①：配列の開始位置をインデックスで指定する。
数字②：配列から削除する要素の数を指定する。

# 本題：戻り値にクセがある
### これ、実は破壊的メソッド
このメソッドは、破壊的メソッドと呼ばれるものです。例として、以下のコードを見てください。

```javascript:破壊的メソッドの例
let array = ['hoge', 'fuga']
array.splice(2, 0, 'poon');
console.log(array) // => ["hoge", "fuga", "poon"] （元のarray配列は無くなり、hogeが追加された後の新しい配列が表示される）
```
このコードでは、`「array」という配列の2番目に「poon」を追加。削除する要素は0個`という意味になっている。
この場合、spliceが破壊的メソッドなので、元の「array」配列は文字通り**破壊**されていて、「hoge」が追加された後の形に変形されています。
### じゃあ、戻り値は？
お察しの通り、元の配列が直接変形されるので、それと同じ配列を返すわけではありません。
具体的にどうなるか、見てみましょう。

```javascript:戻り値の例
const array2 = array.splice(3, 0, 'hoge');

console.log(array);  // => (「hoge」が追加された後の配列)
console.log(array2); // => [] (まさかの空配列が出力されます…) 
```
元のarray配列は、整形後の「hoge」が入った配列が出力されますが、戻り値が代入されたarray2メソッドは、空配列が入ってます。
### 戻り値は、削除された値が配列化したものが返る
以下に、戻り値に着目したサンプルコードをあげるので、確認してみて下さい。

```javascript:戻り値に着目したサンプルコード
let months = ['1月', '2月', '3月', '4月', '6月'];

let afterMonths = months.splice(4, 1, '5月'); // 配列4番目に「5月」を追加、削除する要素は1個
console.log(months); // => ["1月", "2月", "3月", "4月", "5月"]
console.log(afterMonths); // => ["6月"]

afterMonths = months.splice(5, 0, '6月'); // 配列5番目に「6月」を追加、削除する要素は0個
console.log(months); // => ["1月", "2月", "3月", "4月", "5月", "6月"]
console.log(afterMonths); // => []

afterMonths = months.splice(0, 3, 'ほげ月'); // 配列0番目に「ほげ月」を追加、削除する要素はそこから3個
console.log(months); // => ["ほげ月", "4月", "5月", "6月"]
console.log(afterMonths); // => ["1月", "2月", "3月"]
```

謎仕様ですが、戻り値が真逆用途に使えそうなので、これはこれで便利かも。

以上です。
最後までありがとうございました。
requests を GAE python2.7 で使うと IncompleteRead でこける話

## 謎の ChunkedEngcodingError

Google App Engine Standard Environment (Python 2.7) で line_bot_sdk を使って LINE Bot を動かしていると、ときどき以下のような例外を吐きます。

```
ChunkedEncodingError: ('Connection broken: IncompleteRead(2 bytes read)', IncompleteRead(2 bytes read))
```

返答を投げ終わった後のレスポンスのパースで落ちているため、メッセージ送信自体は正常に完了しているので、無視しても良いのですが、どうにも気持ち悪いので、原因を調査してみました。

## 原因

* GAE では httplib が urlfetch で再実装されている。
* line_bot_sdk が使っている requests が使っている urllib3 には、下位層が httplib のインスタンスだったときだけ http の chunked encoding を自前で解決するコードが含まれている。
* しかし、urlfetch で再実装された GAE の httplib は chunked encoding を自前でデコードしてしまう。
* urllib3 で chunked encoding を二重にデコードしようとして例外が発生する。

### エラーの中身
IncompleteRead(2 bytes read) と出ている中身をデバッグ出力してみたところ、 '{}' でした。
LINE Messaging API のサーバは、普段は chunked encoding を使わないのですが、まれに chunked encoding で返信を返してくるようで、その時だけエラーが発生していたようです。
複数端末から同時アクセス発生時にのみ起こる気がしますので、複数リクエストが被ってコネクションをkeepaliveで使いまわした時だけとか、そういう話な気がしてますが、そこまでは追っていません。

## 解決方法
類似した内容をディスカッションしている [urllib3 の issue](https://github.com/urllib3/urllib3/issues/618) では、以下のパッチが提案されています。

https://github.com/agfor/requests/commit/6f7af88464504d6c9a4f84ce9c9535d2eb941b39

urllib3 の問題なのに requests のレイヤで対応しているのが微妙に気持ち悪いですが、とりあえず同じパッチを当てれば、chunked encoding の問題は発生しなくなります。

（本質的には、urllib3/response.py で self.raw の httplib の中身が GAE 版だと判別できたら self.chunked を True にしないというのが正しい対処のはずです）
ZenbookにUbuntuを入れたら音が出なかったときの解決法

ググってもビシッと答えが出てこなくて3日くらいかけて解決したので記事にしておきます。

Core i7クワッドコアでメモリ16GBくらいのSSD搭載ウルトラブックがほしいなと思って、amazon.**com** で[UX333FA-AB77](https://amzn.to/2N2Y8IO)という13.3インチのZenbookを見つけました。
日本の amazon.**jp** とか[ASUSの公式ページ](https://www.asus.com/jp/Laptops/ASUS-ZenBook-13-UX333FA/)でUX33FAを探すとCore i3/i5でメモリ8GBのマシンがこれよりも高く売ってて「マジかよ」ってなります。
ちなみに、僕が購入したときの為替では送料含めて 120,918円でした。
クレジットカードで買うときには現地通貨払いを選ぶとお得です。

## 音が出ない

さて、さっそくデュアルブートでUbuntu（厳密にはUbuntu Mate）を入れたんですが、スピーカーやイヤホンから音が出ません。
いろいろ調べて試してもうまく行かず、[ukuu](https://teejeetech.in/ukuu/)でカーネルをアップデートしてみても音が出ない上にUbuntuが立ち上がらなくなってインストールし直すのを3,4回繰り返しました。

結論としてはBIOSのバージョンアップをすることでUbuntuが立ち上がらない問題もスピーカーやイヤホンから音がでない問題も解決しました。
(もしかしたらBIOSバージョンアップに加えて、Linuxカーネルのバージョンをukuuで4.20にあげる必要があるかもしれません)

## BIOSバージョンアップの方法

BIOSバージョンアップの方法も少しクセがありました。
ASUS公式にある[Easy Flash を使用してノートPCの BIOS のバージョンを更新する方法](https://www.asus.com/jp/support/FAQ/1008859)を使います。

> １、以下を参考にお使いのモデルに対応する最新の BIOS をダウンロードしてください。

にしたがって [ASUS UX333FAサポートページ](https://www.asus.com/jp/Laptops/ASUS-ZenBook-13-UX333FA/HelpDesk_Download/)の "Driver & Tools" で最新のBIOSを探しますが、この時に公式ページ通りに「OSを選択してください」を "Windows 10 64bit" にするとすでにインストールされているバージョン302しかでてきません。
"その他" を選択するとバージョン306が表示されるので、これをダウンロードして zip を解凍したものをフラッシュメモリに保存して、あとは Esc キーを押しながら電源を入れると立ち上がるBIOSページで公式ページにしたがってBIOSをバージョンアップするだけです。
AWS SUMMIT TOKYO で得られた知見




2019年６月１２日〜１４日で「AWS SUMMITTOKYO」へ参加してきました。
そこで得られた知見を共有します。
<img width="821" alt="AWS_Summit_Tokyo_2019___2019_年_6_月_12__水__〜14__金__幕張メッセで開催.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234640/5a7ad61f-2c11-b1c1-4742-402c924cc9c7.png">

##マルチアカウント 

企業におけるAWSアカウントは増える傾向にある。 
理由 

・ EC2の上限数がある 
・環境の分離(本番・開発など) 
・コスト管理(請求を分けたいなど) 
・複数チームによる利用 

アカウントを分ける例 
　◯管理者アカウント 
　　・AWSアカウントの作成 
　　・AWSアカウントのアクセス管理 
　　・共通設定 
　◯ログアカウント 
　　・ログの管理(CloudTrailで各アカウントのログ一つのS3に集約管理) 
　◯セキュリティアカウント 
　　・脅威検知(AWS guard dutyを使用して不正アクセス等を検知できる) 
　◯サービスアカウント 
　　・本番環境 
　　・開発環境 

マルチアカウントの管理ができるサービス 
「AWS Organizations」 

##ネットワーク 

重要サービス 
・VPC Peering 
　異なるVPCを接続 
　アカウントやリージョンが違っていても可能 
   ※同一のIPアドレス帯では不可(例えばどちらのVPCでも10.1.0.0/16の場合等) 

・VPC Sharing(新機能) 
　異なるアカウント間でのサブネットの共有が可能 
　※同一のIPアドレス帯であっても可 

・Transit Gateway(新機能) 
　VPCとオンプレミスネットワークを単一のゲートウェイに接続できるようにするサービス 

#サーバ/DB移行 

◯オンプレミスSQLserverのRDS移行 
　選択肢 
　①エンジンは変更せずにプラットフォームだけ変更(オンプレDBをRDS 
　　にそのまま移行するパターン）　 
　②エンジンもプラットフォームも変更（エンジンをAmazon Auroraに変えるとか) 
　③プラットフォーム移行後しばらくしてエンジンも変更 

　①の場合の移行手順フローチャート 
　十分な停止時間を取れる場合 
　　→「.bak」ファイルによる移行 
　十分な停止時間を取れない場合 
　　→レプリケーションによる移行 

◯WindowsシステムのAWS移行 

　最新動向 
　・AWSでのWindowsサポートは10周年 
　・493%伸びている(2014年~2019年) 

　メリット 
　・コスト最適化(ライセンス持ち込みやインスタンスタイプの選択等) 
　・俊敏性(各サービスを使うか使わないか選択するだけ、RDSのバージョンアップは 
　　　　　４クリックでできる等) 
　・スケール可能(高い可用性) 

　サービスの有効活用 
　・FSx for Windows File Server 
　・AWS Directory Service for Active Directory 

　管理自動化 
　・SSMパッチマネージャー（パッチの自動適用が可能） 

##テクニカルサポートブース 
業務上、本番環境の複製が必要だった為、 
サポートデスクでベストプラクティスを伺った。 

「EC2」 
方法1 AMIによる複製 
方法2 EBSスナップショットによる複製 
※AMI(amazonマシンイメージ)とスナップショットの違い 
　AMI・・・EBSボリュームのデータ(スナップショット)とインスタンスを構成する 管理情報を含む起動テンプレート
　スナップショット・・・EBSボリュームの中のデータを特定のタイミングで取得し、 S3に保存したもの 

「RDS」 
スナップショットによる複製 
　・RDSメンテナンス開始 
　・スナップショット取得 or 自動スナップショットもある 
　・スナップショットからインスタンスの復元 
　※RDSを稼働させたままスナップショットを作成すると、 
　取得開始時点でコミットされていたトランザクションが対象になるので 
　タイミングなどの注意が必要。 

参考) 
「CloudFormation」 
テンプレートからAWSリソース(EC2,RDS,VPC)等を自動構築するサービス 
テンプレート作成することで、同じインフラ構成をすぐに再現できる。 
※あくまで環境なので中身のファイルなどはコピーされない。 

##感想
今回「AWS SUMMIT」に参加してまず感じたのは、参加者がとても多いこと。 
成長率は41%にものぼるとのことで、今後もさらに利用者は増えると思われる。 
AWSはサービス数が非常に多く、毎月のように新機能が発表されている。 
どんなサービスがあり、どのような場合に使えるかということを把握することがシステムを作る上で非常に重要になってくる。

以上です。
シンボリックリンクをGitHubに置いてみた

# はじめに

シンボリックリンクをGitHubに置いて試してみました。

# 本題

こちらが今回のリポジトリです。

https://github.com/matoruru/symbolic-links-in-git

普通に動きました。

# まとめ

新規性がない
【備忘録】docker pushしたら拒否された

<h2>docker loginしてもdenyされる</h2>
新卒3ヶ月目が独学でDocker入門してみたら、案の定つまづいたのでここに備忘録として書き残しておきます。

イメージpullしてきて、コンテナ作って、ってところまではできたけど

```bash:
$ docker push イメージ（ユーザー名/任意の名前）
# => denied: requested access to the resource is denied
```
「アクセスが拒否されたよー！」と怒られた。いやだ。

色々調べてみても、どこのサイトにも```docker login```すればpushできるよ、としか書いていない。
いやイメージpullしてくる前にloginしたはずなんだけど何かしらのやーつでセッション切れたのか、、？いやまさかそんなことないよな〜と思いつつも渋々やってみるが、やはり結果は変わらず。

てかそもそもイメージ名って<b>ユーザー名/任意の名前</b>だから、push先であるDockerHubのユーザー名と一致してないとダメなのかもと思い、イメージのユーザー名部分をDockerHubのユーザー名と一致させてみることに。

<h2>やはりユーザー名が問題だった！</h2>
手順としては、間違った名前のイメージから任意のコンテナを作成し、そのコンテナから新しいイメージを作るという二段戦法。

1.まず間違った名前のイメージから、tmpコンテナを作成。

```bash
$ docker run -d --name tmp false-username/任意の名前
```

2.次にcommitして新しくpush対象のイメージを作成。

```bash
$ docker commit tmp true-username/任意の名前
```

3.push!!!

```bash
$ docker push true-username/任意の名前
```
↓
`Pushed`と表示され、なんとかpushに成功。
なんだこんな簡単なことか、、、今日も一つ勉強になりましたとさ。
<hr>

<h3>参考</h3>
[Docker のインストールからレポジトリへのpush までやってみた【CentOS 7】](https://qiita.com/umi/items/d4b5a68263ad0444693b)
[Dockerイメージの名前を変更する](https://qiita.com/hirocueki/items/4f077795ac8d94c6ad8f)
秘密鍵・公開鍵のチェック観点

#秘密鍵・公開鍵のチェック観点

#####ハッシュファイル（X.sha256）のハッシュ値と各ファイルのハッシュ値が一致していること
```
    openssl sha256 XXXXXXXXXXX-client.crt
    openssl sha256 XXXXXXXXXXX-client.key
    openssl sha256 XXXXXXXXXXX-server.crt
    openssl sha256 XXXXXXXXXXX-server.key
```

#####クライアント証明書・秘密鍵のペア、サーバー証明書・秘密鍵のペアが一致していること

```
    openssl x509 -noout -modulus -in XXXXXXXXXXX-client.crt | openssl md5
    openssl rsa -noout -modulus -in XXXXXXXXXXX-client.key | openssl md5
    openssl x509 -noout -modulus -in XXXXXXXXXXX-server.crt | openssl md5
    openssl rsa -noout -modulus -in XXXXXXXXXXX-server.key | openssl md5
```
画像ファイルのバリデーション

ECサイト作成の過程で商品の画像を登録する必要があり、その際のバリデーションに時間がかかってしまったので、備忘録として残します。
## 作りたいもの
ユーザー登録と同様に商品の情報をする際にバリデーションを行います。具体的には以下のようになります。

  - product_register.phpで商品名、商品画像、紹介文、価格を入力する。
  - 入力情報にバリデーションをかけて、エラーメッセージがなければproduct_confirm.phpに遷移し、そうでなければエラーメッセージを表示してリダイレクトする。
  - バリデーションは、全て入力必須、画像は画像ファイルであること、価格は半角数字とした

## 画像ファイルのバリデーション
以下のような画像ファイルかどうかを判定する関数を`validation.php`に作成しました。(前回の記事で作成したファイルに追加しました。)

```php
<?
function isImage($fileName,$tmpImage,$filetype){
     if (is_uploaded_file($tmpImage)) {
         if(explode("/",$filetype)[0] != "image"){
           //画像判定
           $message= "画像ファイルをアップロードしてください。";
           return $message;
         }

        	if (move_uploaded_file ($tmpImage, "images/" .date("Ymd-His") . $fileName)) {
          	chmod("images/" . date("Ymd-His") . $fileName, 0644);
          	echo  $fileName."がアップロードされました。";

          } else {
          	$message = "ファイルをアップロードできません。";
            return $message;
          }

      } else {
      	$message = "ファイルが選択されていません。";
        return $message;
      }
?>
```
引数には`$filename`にはファイル名,`$tmpImage`には一時保存ファイル名,`filetype`にはファイルのMIMEタイプを渡します。
この関数を使う際には以下のように記述します。

```php
<?

        require_once 'validation.php';
        $val = new Validation();
        $result = $val->validate($input_control,$_POST);
        $isImage= $val->isImage($_FILES['productImage']['name'],$_FILES['productImage']['tmp_name'],$_FILES['productImage']['type']);
        if(!is_null($is_image)){
          $result['productImage']=$isImage;
        }

      if(!(empty($result))){
        //エラーがある場合の処理

        foreach($result as $error){
          echo $error;
          echo '<br>';
        }


      }else{
        //エラーがない場合の処理
        $_SESSION = $_POST;
        header('Location:product_confirm.php');//確認ページに遷移
        exit;
      }
```

isImage関数では適切なファイルであればreturnがされないのでNULLが返ってきます。なので返り値がNULLではないときにエラーメッセージを代入します。
※ `$result['productImage']=isImage();`とすればよさそうに見えますが、そうするとバリデーション通過時に`$result['productImage']`にNULLが入ってしまい、$result自体は空ではなくなってしまうのでエラーメッセージが入ってしまうので注意しましょう。
超初心者が書く！初心者のためのPython解説！

#自己紹介
##初めに
さらっとでいいので読んでやってください...

私はデータサイエンティストを目指す学生です。
学校のITプロジェクトの一環として**[ProjectEuler](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%BB%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC)**を解くことになりました。
はじめに宣言をしておきますが**過去にプログラミング経験がない**超初心者です！

そんな人が**ProjectEulerを解きながら、Pythonを学ぶ**ページになります。

ほかにも同じようにQiitaに書いている人がいるのでそちらもよろしくお願いします!

**[ここから見れます！](https://qiita.com/projecteuler)**

##目的

 *  同じプロジェクトを進めている仲間との情報共有

 * pythonの書き方の整理

 * それから ... **単位のためです！！** (こればっかりは仕方がないね...)

そしてほかの何よりも大切なのは ...

 * **社会貢献活動** です！

「**高校生だけど**(高校生に限らず)**これからプログラミングをやってみたい**」
「**独学でProjectEulerを解いてるけど関数の使い方がよくわからない**」

そのような方々に見ていってほしいです。

##環境について
ProjectEulerを解くにあたって私は、
プログラミング言語は**Python3.7.3**([Pythonのダウンロードはここから](https://www.python.org/downloads/))、
ソースコードエディタは**VisualStudioCode**([VisualStudioCodeのダウンロードはここから](https://code.visualstudio.com/))
をつかって書いていきます。


~~使用PCはノートパソコンで~~
~~Windows 10 pro 64 ビット~~
~~CPU ... intel Core i3-5005U 2.00GHz　です。~~

新しいPCを買ったのでスペックを書き直しておきます。
Windows10 Home 64bit
CPU ... Ryzen7 2700X
GPU ... GeForce RTX2060


#問題の解き方と解説の書き方
##問題の解き方について
あくまでも予定なので私の気分によってその都度変わると思います。
###10問目ぐらいまでは...
 1. 1~10問目まで順に問題を見る
       内容によっては別の問題から解きます。

 2. 解き方を考える
       たとえプログラムが組めなさそうだとしても、効率が悪くても、
       自分で**どのようにして解くのかの方針を立てます**。

 3. ネットで解答を見る
       はじめのうちは何をしていいのかわからないし
       どんな関数があるのかもわかっていないので、解答を見ながら
       **書き方を解析及び理解します**。

 4. 自分でもプログラムを組んでみる
       効率が悪くてもおｋ！

といった流れになる予定です

###それ以降は...
 1. 好きな問題を選ぶ
 **興味のある**問題から解きます。

 2. 解き方を考える
 **方針立て**は変わらないです。

 3. 自分んでプログラムを組み、答え合わせ
 解答があっていればそれでよしとします。

 4. より効率的なプログラムを目指す
 **効率化**と**汎用化**(ホントにちょっとした工夫)を目指します！

こんな感じで書いていこうと思っています。

##解説の書き方について
**関数の使い方**やコードがどのように動いているのかを、**細かく**書いていこうと思っています。
（ここは後でもう少し書き込みます...）

問題の解き方解説の書き方はあくまで予定です。
こちらの都合で多少書き方に変更があったりしますがご了承ください。
#最後に
なんかQiitaに書き込んでいくの楽しいので、学校卒業するまで不定期に更新し続けようかなといます。
今後の予定としては、Javaの学習も始めようと思うのでそちらも更新しようかなと思ったり、アルゴリズムにも興味があるのでそのあたりも記事にできたらなと思っているのでよろしくお願いします。(しばらくはPython一筋です)
至らぬ点が多々あると思いますが、今後も**よろしくお願いいたします！**

 - [超初心者が書く！ Project Euler を Python で解いてみた！ Problem1](https://qiita.com/darknessdragon0128/items/a9787dc49dadd1bbadfd)
 - [超初心者が書く！ Project Euler を Python で解いてみた！ Problem2](https://qiita.com/darknessdragon0128/items/9f3d73f31e0c787fbeae)
ICカードで施錠

マイポータル https://qiita.com/carpenders/items/adb743f0a308f6786c73
setup https://qiita.com/carpenders/items/8dbcaab2b053b277e1f6
nfcpy https://qiita.com/carpenders/items/14f15807a9dca15f5fde
pigpio https://qiita.com/carpenders/items/84857bb2a75311b700fb
readonly https://qiita.com/carpenders/items/a588b9ca704b17d616c7
code https://qiita.com/carpenders/items/c93799f039ca848a4d62
メモ https://qiita.com/carpenders/items/2a540e4dc31f38d7e7e7