OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP備忘録】ログインの流れ

<p>ログインの大まかな流れ。

<h2>前提
<p>・join/index.php（登録画面）
・join/checked.php（登録確認画面）
・login.php（ログイン画面）
・index.php（ログインされた画面）

formのactionは空にしておく


あと各フォルダの最初にこれを忘れない

```PHP:
session_start();
require('../dbconnect.php');
```
これで、つながる

```
$_SESSION['join'] = $_POST;
```
後これがPOSTにある値をセッションにさせたやつ


<h2>HTMLにて変数で代入する
<p>例　この場合だと打たれた名前が表示されるようになる

```PHP:check.php
		<dd>
		<?php print (htmlspecialchars($_SESSION['join']['name'],ENT_QUOTES));?>
        </dd>

```
これを各それぞれの値にやる
あとこれめちゃくちゃやる、もうほぼこれ。

<h2>DB接続->登録情報をINSERT
<p>ここでドキドキのDB接続

```PHP:check.php
if(!empty($_POST)) {
	$statement= $db->prepare('INSERT INTO members SET name=?, email=?, password=?, picture=?, created=NOW()');
$statement -> execute(array(
$_SESSION['join']['name'],
$_SESSION['join']['email'],
// 「sha1」というのは記号化してくれるもの（不可逆）
sha1($_SESSION['join']['password']),
$_SESSION['join']['image'],
));

```

終わったらデータが残らないように削除して完了。

```PHP:check.php
unset ($_SESSION['join']);
header('Location: thanks.php');
exit();

```

これでDBにINSERTされた。
<h2>ログイン画面で呼び出し
<p>さて…



```PHP:login.php
  if($_POST['email']  !='' && $_POST['password']  !== '' ) {
    $login = $db ->prepare('SELECT * FROM members WHERE email=? AND password=?');
    $login ->execute(array(
      $_POST['email'],
      sha1 ($_POST['password'])
    ));

    $member = $login->fetch();


    if($member) {
      $_SESSION['id'] = $member['id'];
$_SESSION['time'] = time();
  header('Location: index.php');
      exit();
```
最初の段落から
<strong>POSTのEメール・パスワードがともに埋まってる時
→DB接続（memberのテーブルでEメール・パスワードの値が？をさがして！）
→POSTにあるこれさがして！</strong>
↓
<strong>取得して$memberにわかりやすくして！</strong>
↓
<strong>SESSIONとmemberのID一緒だったらindex.phpにいっていいよ！</strong>
<p>って感じ？

<h2>違うIDの人が入らないように
<p>

```PHP:index.php
if (isset($_SESSION['id'])  && $_SESSION['time'] +3600 > time() ) {
$_SESSION['time'] = time();

$members = $db->prepare('SELECT * FROM members WHERE id=?');
$members ->execute(array($_SESSION['id']));
$member= $members -> fetch();
} else {
  header('Location: login.php');
  exit();}
```

<p>ん～、多分IDとパスワードの値が入ってたらそのログインした時間を現在の時間に上書きする。
そして、ログインしたユーザーの情報を持ってくることができた。


一通りは以上！

ps.用語意識して覚えてないから説明するの抽象的になってしまうなぁ
Amazon RDS for SQL Server の "Always on"

#内容#
Amazon RDS for SQL Server で Standard Edition で Always On Availability Group が利用可能に
[[Feb 23, 2021]Amazon RDS for SQL Server now supports Always On Availability Groups for Standard Edition](https://aws.amazon.com/jp/about-aws/whats-new/2021/02/amazon-rds-for-sql-server-now-supports-always-on-availability-groups-for-standard-edition/)

普段、AWS RDS を利用する際は、MySQLを利用することが多いのですが、エンジンのタイプが異なると、マルチAZの選択がどうなるのかと気になり、多少やって見た系の記事です。


#やって見た系#
最新アップデート情報の内容の通り、
エンジンタイプには「Microsoft SQL Server」
エディションには「SQL Server Standard Edition」
を選択する。
![スクリーンショット 2021-02-25 18.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/b92aa2c6-4d8f-ce46-0dee-1a5ca0033963.png)

マルチAZ配置では「あり」もしくは「なし」しか選べないようになっている。
では、"Always on"か"Mirroring"どちらが指定されるのか？
※[こちら] (https://go-journey.club/archives/11649#RDS_%E3%82%92%E3%83%9E%E3%83%AB%E3%83%81_AZ_%E9%85%8D%E7%BD%AE%E3%81%AB%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)の説明にあるとおり、"Always On" とは SQL Server の「高可用性」を実現する機能であり、"Mirroring"に変わる機能。
"Mirroring"は非推奨のようであり、"Always On" に対応した[Microsoft SQL Server のマルチ AZ 配置](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_SQLServerMultiAZ.html)を確認すべき。
![スクリーンショット 2021-02-25 18.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/6bd9d781-f328-b396-7c75-108e96895557.png)

設定は自動的に行われ、RDS はデプロイする SQL Server のバージョンに基づいて、"Always on"か"Mirroring"かが選択され、マネージコンソールから確認することが可能なようです。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2c61bc54-1007-79e3-e6ab-a2b00a166f6f.png)

フェイルオーバーで再起動をしてみると、40秒程度でフェイルオーバーしているようです。

```
二月 25, 2021, 12:34:33 午後 UTC
Multi-AZ instance failover started.
二月 25, 2021, 12:34:58 午後 UTC
Multi-AZ instance failover completed
二月 25, 2021, 12:35:13 午後 UTC
Multi-AZ failover to standby complete - DNS propagation may take a few minutes
```

なお、現在"Mirroring"から"Always on"に自動では変更されません。
"Mirroring"から"Always on"に変更したい場合は、シングル構成に変更して、再度マルチAZ構成変更する必要があるようです。


#リンク#
[Amazon RDS](https://qiita.com/leomaro7/items/9ac81ae543689a15b322)
多次元配列を時間順に並び替える

#概要
データベースの結果を多次元の配列に代入して時間順に並び替えたのでその方法をメモします。


#結論
    array_multisort( array_map( "strtotime", array_column( $data, "created_at" ) ), SORT_DESC, $array ) ;

一つずつ見ていきます。

#実装
こんな感じの配列

```.php
$data=[
            {
                "post_id": 76,
                "user_id": 3,
                "description": "hogehoge",
                "created_at": "2021-02-08T09:59:52.000000Z",
            },
            {
                "post_id": 77,
                "user_id": 2,
                "description": "hogehoge",
                "created_at": "2021-02-11T12:08:44.000000Z",
            }
            {
                "post_id": 78,
                "user_id": 2,
                "description": "hogehoge",
                "created_at": "2021-01-26T21:50:47.000000Z",
            }
];
```
時間順に並べたいので`created_at`から参照して並び替えます。

>array_multisort( ソートしたい配列 , ソート順 ,ソート方法（省略可） , 追加の配列 )

今回ソートしたい配列は$dataですが`created_at`が英文日付なので、UNIXタイムスタンプ形式にする必要があります。
ですのでarray_map()関数を使います。

>array_map(コールバック関数, $配列)

ですので、

    array_map("strtotime",array_column( $data, "created_at" ) )

で日付を比較できるように変換します。


    array_multisort( array_map( "strtotime", array_column( $data, "created_at" ) ), SORT_DESC, $array ) ;


結果

```.php
$data=[
            {
                "post_id": 78,
                "user_id": 2,
                "description": "hogehoge",
                "created_at": "2021-01-26T21:50:47.000000Z",
            },
            {
                "post_id": 76,
                "user_id": 3,
                "description": "hogehoge",
                "created_at": "2021-02-08T09:59:52.000000Z",
            },
            {
                "post_id": 77,
                "user_id": 2,
                "description": "hogehoge",
                "created_at": "2021-02-11T12:08:44.000000Z",
            }

];
```


無事時間順に並び替えることができました。
composerコンテナでrequireのコマンドを実行したら、"require: not found"のエラー

## 環境

- Ubuntu 18.04 LTS
- Docker Composer Container

## 発生した問題

composerコンテナで`composer require`の処理を実行しようとすると、エラーが出た。

```
docker-compose run composer require phpunit/phpunit
```

エラー内容

```
/docker-entrypoint.sh: exec: line 24: require: not found
```

## 解決方法

中身が空の`composer.json`を削除する。

```
$ rm ./composer.json 
```

再実行したところ、成功した。


```
docker-compose run composer require phpunit/phpunit
```

## 詳細

`--help` オプションをつけて実行しようとすると、例外の出力が出た。

```
$ docker-compose run composer --help

                                                                          
  [Seld\JsonLint\ParsingException]                                        
  "./composer.json" does not contain valid JSON                           
  Parse error on line 1:                                                  
                                                                          
  ^                                                                       
  Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['  
                                                                         
```

`./composer.json`が悪そうだなと思って確認すると空ファイルだった。これを削除したところ解決した。

```
$ cat ./composer.json
$
```
ECサイトでのFastly活用チェックポイント

#この文書で表現したいこと
いまや高速で使いやすいECサイトを作成するのにCDNの使いこなしは不可欠になりました。

ここで__「CDNを使いこなして高速化する」にはどのように考えたらよいのかをFastly、VCLを題材に論点を整理__します。
この整理を元に実際の設定を吟味、作り込みして、皆さんのECサイトのパフォーマンスを向上させてください。

#何をキャッシュさせるか、させないか
ECでは金銭情報、在庫などの情報、個人情報を扱うため他のサービスに対してさせないべきかの決定がパフォーマンス上、ビジネス上、法令遵守上、信用上いずれとても重要なポイントになります。
逆にキャッシュした方が良い情報や、中間的な「ほどよい時間キャッシュした方が良いもの」もあるため、私の経験よりその性質で以下の5種類に分類します。

1. 在庫などリアルタイムで変わる情報
1. 個人情報などパーソナライズされた情報
1. 時刻で変化する情報など定期的に変更される情報
1. あまり変化しないがオリジンが変化した場合に数分で反映されて欲しい情報
1. あまり変化しない情報

1や2はCDNやブラウザにキャッシュさせずに都度オリジンから配信することが基本です。（=キャッシュ禁止コンテンツ）

3は長めのTTLと短めのブラウザキャッシュでCDNにキャッシュさせておき、
オリジンで情報が更新させてたタイミングでキャッシュパージをすることが望ましいです。（定期パージコンテンツ）

4は商品詳細、商品リストページのhtmlなどを想定します。これは短めのTTLで短期間CDNにキャッシュさせる様にします。（準安定コンテンツ）

5はjsやcssなど一般によくCDNのキャッシュ対象になるコンテンツです。（安定コンテンツ）

#サイトの構造
非キャッシュコンテンツ、定期パージコンテンツ、準安定コンテンツ、安定コンテンツの4種類のミックスを適切に行うことで効果的になキャッシュを狙います。


| 種類 | 分類 |
|:-:|:-:|
| css,js,画像等  | 安定コンテンツ  |
|  多くのお客様に共通して見せたいページのhtml |  準安定コンテンツ、または定期パージコンテンツ |
|  パーソナライズされたコンテンツ | キャッシュ禁止コンテンツ  |

とするのが基本だということです。

つまり、ページを読み込みパースする際のクリティカルパスになるhtmlを準安定コンテンツまたは定期パージコンテンツとしてCDNキャッシュし、
そこから呼び出されるcss、js、画像は安定コンテンツとして確実にCDNキャッシュにヒットさせ、
これらキャッシュコンテンツから分離してキャッシュ禁止コンテンツを扱うようにします。
__キャッシュ禁止コンテンツはAPIで提供するようにしてDOM上で表示を作る__ことが好ましいでしょう。

#各コンテンツのヘッダ、キャッシュポリシ
##キャッシュ禁止コンテンツ
Cache-control: privateとすることを強くお勧めします。
vclでpassすることでキャッシュしないことは可能ですが、ECにおいて非キャッシュコンテンツはCDN、ブラウザいずれでも確実にキャッシュしないことを確認できるようにする必要があります。
万が一間違ってキャッシュした場合即、個人情報事故になることがありますから、
__明示的にキャッシュされないことを保証するため__にpassは使わずCache-control: privateを使うことしましょう。

##定期パージコンテンツ
普段はCDNにキャッシュさせておき、オリジンコンテンツが変更されたときに確実に更新する必要があります。
商品毎に情報が更新される場合には共通してパージする必要があるURLに同じSurrogate Keysを指定しておき、オリジンシステム側からPurge APIを叩くことでキャッシュパージする方法が最も効率がよいでしょう。

##準安定コンテンツ
定期パージコンテンツと違って不定期ではあるがオリジンの情報が更新され1～2分程度であれば古い情報が表示されても許容できる場合です。
前の項の通りできるだけユーザ共通部分はこの分類になるようにし、キャッシュ禁止コンテンツはAPIとしてフロントで合成することで大きな高速化が期待できます。
この場合は1～2分程度のTTLを指定して短い時間でもキャッシュするようにします。
例え短いTTLであってもその間オリジンにまで到達するリクエストは高々1つになるため高速化とサーバ負荷の低減に十分な威力を発揮します。

##安定コンテンツ
長いTTLや長いブラウザキャッシュを指定することでオリジンにほとんどリクエストが来ないように設定すると良いでしょう。
長いブラウザキャッシュでの事故が不安な場合はクエリパラメータ付きURL、長いTTLが不安な場合はSurrogate Keysを活用して任意のタイミングでキャッシュを無効化できるように備えておけば安心して運用できます。

#期待される効果
ECサイト一般ではhtmlの読み込みが起点になり、そこから各画像の読み込みやCSS、jsのロード、APIの実行のように繋がっていきます。
つまりhtmlの読み込みの高速化は全体のロード時間、First Contentful Paintいずれにもオールマイティに効く要素なわけですが、これは経験上かなり高速化した__ECパッケージやCMSからさらに約600msの高速化__はできるという感触を得ています。
パーソナライズ情報等キャッシュ禁止コンテンツのAPI化をすすめ、そこにhttp/2を採用することでコンテンツの__フェッチ処理が並列で進むようになるため数百から1000ms程度の高速化__が期待できます。

実際にはこれらの施策の積み重ねでロード時間、First Contentful Paintとも半分程度になることがほとんどでした。


#まとめ
- 動的、静的、プライバシーなどに注目してコンテンツを分類しました
- キャッシュ効果を最大化するサイトの構成を考えました
- サイトを構成する際にそれぞれのコンテンツの振る舞いに何をどう期待するかを定義しました
- 各コンテンツの期待される振る舞いからキャッシュポリシーを設定するべきかの指針を決めました

CDNは通信量（バイト数、リクエスト数）で課金されることがほとんどなので、使いこなして性能を引き出しても、使いこなくてもほとんど料金は変わりません。
使いこなし次第で、性能が向上して料金が安くなることがありますからぜひこちらを参考に最適化を図ってみてください。
第31回 Tokyo Jazug Night (Online) で学んだこと

# はじめに

第31回 Tokyo Jazug Night(Japan Azure User Groupの勉強会)で学んだことを書きます。
https://jazug.connpass.com/event/202626/

# Azure WAF を活用しよう 〜WAF の解説から他サービスとの連携まで〜
発表者：サイバーセキュリティクラウド WAF 自動運用サービス部部長 市川さん
[発表資料はこちら](https://www.slideshare.net/YutoIchikawa1/jazug202102cscichikawa)

Azure WAF = Azure Web アプリケーション ファイアウォール。公式サイトは以下。
https://azure.microsoft.com/ja-jp/services/web-application-firewall/

近年、サイバー攻撃は、年々増加している。

Azure WAFは、様々なインジェクションの攻撃を防ぐことができる。

リスト型攻撃や平文による通信で中間者攻撃をWAFで防ぐのは難しい。

セキュリティ対策しているというアピールをすることがWAFの重要な効果。
（攻撃者から狙われにくくなる）

WAF Policy に、WAFのルールや設定を入れる。
Application Gateway(App GW), Frontdoor用の2種類の WAF Policy がある。

App GW：かんたんに設定できる
Frontdoor：細かく設定できる

WAFログの保存は、3つの方法でできる

- Strage Account：安い
- Azure Monitor Log Analytics：時系列でログがたまる。コストバランス良い
- Event Hubs：リアルタイム性が一番高い。必ずしも時系列順でない

Azure DDoS Protection
Azureのリソースは、特に設定しなくても、Azure DDoS Protectionで守られている。

# How to Azure環境のセキュリティコンサルティング
発表者：NRIセキュアテクノロジーズ株式会社 サイバーセキュリティコンサルティング部 吉江 瞬さん
[発表資料はこちら](https://speakerdeck.com/syoshie/how-to-azurehuan-jing-falsesekiyuriteikonsaruteingu)

Azureのセキュリティをどうやって対策するか？
ひと昔前は、Azure Security XXX で検索していた。

現在は「Azureのセキュリティ設計原則」というものが公開されている。
（ゼロトラストを前提とするなど）

Azure Security Center を利用することがおすすめ。
統合されたセキュリティ管理と高度な脅威保護を実現するサービス。
無償でできるセキュリティ対策もあるので、まず有効化した方がいい。

CIS Benchmark を用いてチェックすることがおすすめ。

# 初心者スクラムマスターがAzure DevOpsを使ってスクラムチームを立ち上げた話
発表者：PHC株式会社メディコム事業部 市川さん

Azure DevOpsを用いてスクラムチームを立ち上げた。

Azure Boardsの活用
タスクをAzure Boardsで作成してカンバンのように管理。
アイテムの管理はMSの方法に準拠。

Azure Reposの活用
Policiesで、mainブランチへのプッシュを禁止したりなど、ポリシーを設定。

Slackでプルリクエストの状況見える化(Azure Repos app for Slack)。

ダッシュボードで全体進捗見える化した(バーンダウン、ベロシティ、残りタスクなど表示)。

# まとめ
Azure の知らない機能を色々学ぶことができました。

ちなみに私は、普段はエンジニアリングマネージャーとして、チームの皆で楽しく開発する施策を色々実施しています。詳しくは以下を参照ください。
[1年以上かけて生産性倍増＋成長し続けるチームになった施策を全部公開](https://qiita.com/kojimadev/items/4b28f801863cf4e8f0da)

Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)
空白を含むShell変数の展開時の挙動

## 環境

- bash

## 疑問

以下のように変数を定義したとき、空白やタブはどのように処理されるのか知りたい。

```
packages='
    httpd
    postgresql
    redis
'

yum install ${packages}
```

## 結論

`yum httpd postgresql redis`と展開されるので、処理は正常に完了する。

## 詳細

`echo`コマンドで挙動を確認する。

```
#!/bin/bash
# your code goes here

packages='
    httpd
    postgresql
    redis
'

echo ${packages}
echo '${packages}'
echo "${packages}"
```

**output**

```
httpd postgresql redis
${packages}

    httpd
    postgresql
    redis
```

https://ideone.com/XfbkBI

`""`で囲んだ場合はスペース区切りになるのではなく、タブなどの情報が保持されたまま出力されるようだ。
Conoha VPS （Ubuntu）にPython3をインストールする

# apt をアップデート、アップグレード

```sh
apt update
apt upgrade
```
なお、「apt upgrade」は結構時間がかかる。

#make gcc make build-essential する。
```sh
apt install -y make gcc
apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils
```

#git clone
```sh
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
```


#profile をvimで編集
```sh
vi ~/.profile
```
#profile に以下を追記
```sh
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
```
#再読み込みする
```sh
source ~/.profile
```

#libffi-devをインストール
```sh
sudo apt install libffi-dev
```

#python3 をインストール
```sh
pyenv install 3.7.3 
pyenv global 3.7.3
```

#参考にした記事
conohaでVPS借りたのでとりあえずubuntuでpython3系起動するまで
http://auau.hatenablog.com/entry/2019/06/07/130927
pyenvで3.7系のインストールに失敗したときのメモ
https://qiita.com/hitochan777/items/941d4422c53978b275f8
【TypeScript】TypeScriptの修飾子・ショートカット構文

#TypeScriptの修飾子
* private / public / readonly 修飾子
* 修飾子を使ったプロパティ初期化時のショートカット構文


について、まとめました📝

#private / public
* TypeScriptでは、クラスのプロパティにprivate/publicを設定可能です
* private : このクラスの内部からのみアクセスできる非公開のプロパティ
* public : 外からプロパティにアクセス可能

```ts

class Department {
  name: string;
  private employees: string[] = []; //このクラスの内部からのみアクセスできる

  constructor(n: string) {
    this.name = n;
  }

  describe(this: Department) {
    console.log('Department: ' + this.name);
  }

  addEmployee(employee: string) {
    this.employees.push(employee);
  }

  printEmployeeInformation() {
    console.log(this.employees.length);
    console.log(this.employees);
  }
}

// クラスを作成
const accounting = new Department('Accounting');

//従業員を追加
accounting.addEmployee('NEKO');
accounting.addEmployee('INU'); 

// もしemployeesプロパティをpublicにしていたら、外から追加できてしまう → private にして、非公開にする
// accounting.employees[2] = 'Anna'; 

// nameは、publicなので値を設定できる
accounting.name = 'NEW NEKO';


```

#readonly

* readonly修飾子は、一度初期値を設定すると、変更できない、読み取り専用のプロパティであることを宣言できます
* ※JSにはないけど、TSに存在する修飾子です

```ts
class Department {

  private employees: string[] = [];

constructor(private readonly id: string, public name: string) {
    this.id = id;  
    this.name = n; 
  }


  describe(this: Department) {
    console.log(`Department (${this.id}): ${this.name}`);
  }

  addEmployee(employee: string) {
    //this.id = 'id2'; // readonlyなのでerrになります
    this.employees.push(employee);
  }
}

```


# プロパティ初期化時のショートカット構文
* 毎回、プロパティの定義と、コンストラクタでの初期化をするのは面倒です。。
* コンストラクタでアクセス修飾子、引数、型を書くと、<br>アクセス修飾子がある全引数について、クラス生成時に引数を取得し、同名でクラスのプロパティの宣言も行ってくれます！(^o^)

```ts

class Department {
  // private id: string; //不要！
  // name: string; //不要！
  private employees: string[] = [];

constructor(private id: string, public name: string) {
    // this.id = id; //不要！
    // this.name = n; //不要！
  }

```
【Vue.js】axiosを使ってrailsで作成したAPIを呼び出す

``` javascript
  async mounted() { 
    const res = await this.$axios.$get(`/api/v1/companies/${this.$route.params.id}`) 
    this.form.admin_email = res.data.email
    this.form.admin_first_name = res.data.first_name
    this.form.admin_last_name = res.data.last_name
    this.form.admin_kind = res.data.role
  },
```

一部抜粋ではあるが、axiosでapiのデータを表示させたい時の記述。


``${this.$route.params.id}``これが、nuxt.jsに関係する記述。
これによって、idの値を受け取り、それに応じたapiを良いｂ出すことができる。
Aレコードってなに


| DNSレコード | 意味  | 例  |
| :----:   | :--: | :-: |
| A | ドメイン名をIPV4とマップ | webserver.local => 192.168.1.10 |
| AAAA | ドメイン名をIPV6とマップ | webserver.local => 2001:0db8:85a3:0000:0000:8a2e:0370:7334 |
| CNAME | ドメイン名を別のドメイン名とマップ | webserver.local => web.server |



# FQDNってなに
*FQDN = Fully Qualified Domain Name*

- コンピュータの名前（フルネーム）
- 「ホスト名」と「ドメイン名」で構成されている

例えば*mail.dakc.com*の場合は、
dakc.com = ドメイン名
mail = ホスト名

※「.com」は、<font color="red">top-level domain(TLD)</font>と言います。
paiza D「一番小さい値」でのミス例(python)

〈ミス１〉

```python
input_line = list(map(int,input().split()))
print(min(input_line))
```
出力　10
エラー　なし


〈ミス２〉

```python
try:
    N = int(input())
    a = []

except EOFError:
    pass

for i in range(N):
    a.append(int(input()))
print(a)
```
出力　なし
エラー　Runtime error
Traceback (most recent call last):
  File "Main.py", line 12, in <module>
    a.append(int(input()))
EOFError: EOF when reading a line
DockerでNode.jsアプリを起動する

## 概要
先日作ったSlackBotを定期実行したいため、Dockerでnodejsの環境を構築します。

## 前提条件
[Dockerインストール済み](https://docs.docker.com/get-docker/)

```
$ docker --version
Docker version 20.10.2, build 2291f61
```

ジョブフローを平日18:00に実行する設定済み

```js:job.js
const schedule = require("node-schedule");
schedule.scheduleJob("00 18 * * 1-5", run);
```

## Dockerイメージを作成する
1、プロジェクトフォルダー直下に``Dockerfile``を作成して、以下のコードを貼り付ける

```Dockerfile
FROM node:12.20.1
WORKDIR /app
COPY . .
RUN npm install
ENV TZ Asia/Tokyo
EXPOSE 8888
CMD ["node" , "job.js" ]
```

2、``.dockerignore``ファイルを設置してnode_modulesなどを転送対象から除外する

```
node_modules/
.gitignore
Dockerfile
package-lock.json
```

3、Dockerイメージのビルド

実行コマンド（``magical-yuanxiao``はイメージ名）

```
$ docker build -t magical-yuanxiao .
```

ログ

```
Successfully built aebb1184bf44
Successfully tagged magical-yuanxiao:latest
```

## コンテナを起動状態で作成する
実行コマンド（``magical-yuanxiao``は先作ったイメージ）

```
$ docker run -p 8888:8888 magical-yuanxiao
```

最後に、``docker ps -a``コマンドでコンテナの稼働状況を確認します。

## 自動的に実行される
午後6時に自動投稿を行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/91c159e1-f28d-fadd-637b-89e1ce4e9440.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109922/70b0c780-dfe9-e1b5-bf46-9bff2433bd71.png)

## 参照サイト
https://www.npmjs.com/package/node-schedule

https://qiita.com/kooohei/items/0e788a2ce8c30f9dba53

https://matsuand.github.io/docs.docker.jp.onthefly/engine/reference/builder/
Bootstrapのhtml見本をhtml.erbで使うときの書き方変換いろいろ【超初心者】

よく忘れるので書き方
ボタンとフォームの書き方

```erb:ボタン
#html
<button type="button" class="btn btn-primary">投稿ボタン</button>

#html.erb form_withを使ってるとき
<%= f.submit '投稿ボタン', class: "btn btn-primary" %>
```

```erb:フォーム
#html
<div class="mb-3">
  <label for="content" class="form-label">投稿内容</label>
  <textarea class="form-control" id="content" rows="3" placeholder="薄くフォームに表示されるやつ"></textarea>
</div>

#html.erb form_withのフォーム
<div class="mb-3">
  <%= f.label :content, "投稿内容" %>
  <%= f.text_area :content, class: "form-control m-3", rows: 3, placeholder: "薄くフォームに表示されるやつ" %>
</div>
```
f.text_fieldだとフォームの大きさを変えられないので注意

順次忘れやすいやつを入力していきます
Laravel 8.x Seeder生成で怒られる

Seederでダミーデータを作成する際、グローバルヘルパや関数を使用する際の落とし穴があります。

`php artisan make:seed UsersTableSeeder`で作成すると以下のSeederが生成されます。

```php:UsersTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
      //
    }
}
```

ダミーデータを`run`メソッド内に記述しSeederを実行するとヘルパや関数を使用している場合は怒られます。

```php:UsersTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name'           => 'hoge',
            'password'       => Hash::make('hoge'),
            'remember_token' => Str::random(30),
        ]);
    }
}
```
#対処法
ファザードやヘルパを使用する際は宣言してあげる必要があるらしいです。

```php:UsersTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;       //最初からある
use Illuminate\Support\Facades\DB;    //DBファザード使用の為追加
use Illuminate\Support\Facades\Hash;  //Hashファザード使用の為追加
use Illuminate\Support\Str;           //strメソッド使用の為追加

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name'           => 'hoge',
            'password'       => Hash::make('hoge'),
            'remember_token' => Str::random(30),
        ]);
    }
}
```
##参考
https://readouble.com/laravel/8.x/ja/helpers.html
初学者でもよく使うGitのコマンド集

# 前提

- 私自身は学習歴約半年ほどの初学者です。
- 最近はGitコマンド操作に慣れるために、様々なツールでGit/GitHubについて学習しているので、アウトプットしてみようと思い執筆しました。


# Gitよく使うコマンド集

```
# ローカルリポジトリを作成するコマンド
% git init
```

```
# リモートリポジトリからローカルリポジトリにコピーしてくるコマンド
% git clone [リポジトリの名前]
```

```
# ファイルの変更を確認するコマンド
% git status
```

```
# ファイルやディレクトリの変更をステージに追加するコマンド
% git add [ファイルの名前]or[ディレクトリの名前]

# すべての変更をステージに追加するコマンド
% git add .
```

```
# コミットするコマンド(コマンド入力後、ターミナルやエディターでメッセージを入力する必要がある)
% git commit

# コミットするコマンド
% git commit -m "[メッセージ]"
```

```
# ファイルを削除するコマンド
% git rm [ファイルの名前]

# ディレクトリを削除するコマンド
% git rm -r [ディレクトリの名前]
```

```
# リモートリポジトリのurlをoriginに割り当てるコマンド(git push origin masterが使える)
% git remote add origin https://github.com/ユーザー名/リポジトリ名.git
```

```
# リモートリポジトリのmasterブランチにpushするコマンド
% git push origin master

# 本来のpushするコマンド
% git push [リモートの名前] [ブランチの名前]
```
```
# リモートから変更情報を取ってくるコマンド
% git fetch [リモートの名前]
```

```
# 変更をマージ(統合)するコマンド
% git merge [リモートの名前/ブランチの名前]
% git merge [ブランチの名前]
```

```
# fetchとmergeを一緒に行うコマンド
% git pull [リモートの名前] [ブランチの名前]
```

```
# ブランチを新しく作成するコマンド
% git branch [作成したいブランチの名前]
```

```
# ブランチを切り替えるコマンド
% git checkout [ブランチの名前]
```

```
# ブランチの一覧を表示するコマンド
% git branch
```

```
# ブランチを削除するコマンド
% git branch -d [削除したいブランチの名前]
```

```
# 差分を確認するコマンド(後ろにファイル名等を指定できる)
% git diff

# ステージ追加後の差分を確認するコマンド
% git diff --staged
```

```
# ログを確認するコマンド
% git log

# 数字の分だけコミットを表示するコマンド
% git log -n [数字]
```

```
# ファイルやディレクトリの変更を取り消すコマンド
% git checkout -- [ファイルの名前]or[ディレクトリの名前]

# すべての変更を取り消すコマンド
% git checkout -- .
```

```
# git addでステージに追加したファイルやディレクトリの変更を取り消すコマンド
% git reset HEAD [ファイルの名前]or[ディレクトリの名前]

# git addでステージに追加したすべての変更を取り消すコマンド
% git reset HEAD .
```

```
# 直前のコミットをやり直すコマンド
% git commit --amend
```

まだまだいろんなコマンドがあるとは思いますが、個人的によく使うと感じたもの(実務未経験者という立場ではありますが）を列挙してみました。

以上です。ご覧いただきありがとうございました。
「NxでMNISTの手書き数字画像分類を試す」kentaro/jnnnx プロジェクトへのプルリクがマージしてもらえた話 (Elixir)

# はじめに
- [Elixir](https://elixir-lang.org/)楽しんでいますか:bangbang::bangbang::bangbang:
- 2021/02/25(木)に開催された[NervesJP #15 Nxを触ってみる回](https://nerves-jp.connpass.com/event/205125/)に参加してみました
    - @takasehideki 先生ありがとうございます！
- [Nx](https://github.com/elixir-nx/nx)です:bangbang::bangbang::bangbang:
- [Nx](https://github.com/elixir-nx/nx)です:bangbang::bangbang::bangbang:
- [Nx](https://github.com/elixir-nx/nx)です:bangbang::bangbang::bangbang:

# 会の中で @kentaro さんが「NxでMNISTの手書き数字画像分類を試す」という話をしてくださいました
- [NxでMNISTの手書き数字画像分類を試す](https://twitter.com/kentaro/status/1364894054832504834)
- [Introducing Nx - José Valim | Lambda Days 2021](https://www.youtube.com/watch?v=fPKMmJpAGWc) :video_camera: からみるとよいらしいです
- この動画 :video_camera: のライブコーディングを写経して再現されたそうです :thumbsup::thumbsup_tone1::thumbsup_tone2::thumbsup_tone3::thumbsup_tone4::thumbsup_tone5:   

# [kentaro/jnnnx](https://github.com/kentaro/jnnnx) :tada::tada::tada: 
- ライブコーディングの再現！
- READMEのサンプルの通りそのままやってみましょう
- けっこう時間がかかるみたい

# 私の[プルリク](https://github.com/kentaro/jnnnx/pull/1)が採用されました :tada::tada::tada: 
- https://github.com/kentaro/jnnnx/pull/1
- データダウンロード用の`tmp`フォルダがあることを期待しているようで、[File.mkdir_p/1](https://hexdocs.pm/elixir/File.html#mkdir_p/1)で作ることにしました
    - 元から`tmp`があってもよいように[File.mkdir_p/1](https://hexdocs.pm/elixir/File.html#mkdir_p/1)を使いました
- [Nx](https://github.com/elixir-nx/nx)の
- <font color="purple">$\huge{本筋ではありません}$</font>

# Wrapping Up :lgtm::lgtm::lgtm::lgtm::lgtm:
- 会の途中でプルリクだして、マージしてもらって、[Qiita](https://qiita.com/)の記事も書きました
- [Elixir](https://elixir-lang.org/)でやったことはなんでも[Qiita](https://qiita.com/)に書いていくスタイル
- Enjoy [Elixir](https://elixir-lang.org/) :rocket::rocket::rocket:
【Rails6】同じユーザーが1投稿に対して、無限にレビューを出来てしまう不具合を解消

#概要
同じユーザーが、１つの投稿に対してのレビュー（評価）を永遠出来続けてしまう不具合を解消した方法について、紹介します。
→1投稿に対して1レビューしか出来ない状態にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/0defa42e-9e2f-e553-bff6-e628606b3dac.png)

#結論
reviewモデルに以下のような、uniquness_ofのバリデーションを追加することで解決します。


```app/models/review.rb

class Review < ApplicationRecord
  belongs_to :user
  belongs_to :definition

  validates :score, presence: true
  validates_uniqueness_of :definition_id, scope: :user_id #　←追加

end

```

![レビュー無限解消.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/7bc115b9-2550-ace3-b33e-fd46befa0032.gif)

#バージョン
rubyのバージョン　ruby-2.6.5
Railsのバージョン Rails:6.0.0


#補足
validates_uniqueness_of :definition_id, scope: :user_id

validates_uniqueness_ofは唯一性を定めるためのバリデーションです。
scopeは範囲を定めます。

なので今回は、definition_idとuser_idの組み合わせが１通りしかないということになります。

この記述があるかぎり一意性が担保されるということです。

#記事紹介
似たようなエラーを、いいね機能でも起こし、その解消例を以下に載せています。
よろしければご参考ください。
https://qiita.com/narimiya/items/c4480b17c07f7e1bbc61
nginx・gunicorn・djangoの環境におけるTips

webアプリケーションを開発したものの、インフラ周りが弱いため、Tipsとしてまとめていくつもりです。
適宜、更新はしていくつもりです。間違いだった場合は指摘いただければ幸いです。

クラウドには、[digital ocean](https://www.digitalocean.com/)を使用しています。
基本的には、[現場で使える Django の教科書《実践編》](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%AE%9F%E8%B7%B5%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81-ebook/dp/B07L3DRGBT)を模倣しています。
アーキテクチャは[こちらから](https://qiita.com/tamitarai/items/89835f6f63775155bc7c)

# 技術スタック
- python(3.8.5)
- Django(3.0.8)
- nginx(1.18.0)
- gunicorn(20.0.4)
- ubuntu(20.04)

#　ファイル構成
/home/webapp/mysite/[django-project]

 
# 変更を反映させたい時
nginx、gunicorn、djangoなど色々いじると思います。
開発環境とは異なり、いじったら``restart``しないといけないです。

## gunicorn周りを変更した時
反映させるファイルは、``/etc/systemd/system/mysite.service``と``/etc/systemd/system/mysite.socket``です。特に、``daemon-reload``も必要らしい。

ということで、

``sudo systemctl daemon-reload ``
(↑sudoをつけないと怒られた)

``sudo systemctl restart mysite.service``
``sudo systemcctl restart mysite.socket``

毎回、↑を書くのが面倒だったので、.bashrcに``alias``を設定しました。

```bash
fuction all-reset(){
    sudo systemctl restart mysite.service
    sudo systemcctl restart mysite.socket
}
alias allreset = all-reset
```

## djangoの中身（models.pyとかviews.pyとか）を変更したとき

なぜかわかりませんが、ここら辺の変更を適用するためには
``sudo systemctl restart mysite.service``
が必要でした。

もちろん、models.py周りを変更した際は``python manage.py makemigrations``や``python manage.py migrate``も忘れずに。

また、開発環境では、``sqlite3``、本番環境では、``postgresql``や``mysql``と使い分けがある場合があるかと思います。
（というより、開発時にちゃんとアーキテクチャを設計せず、ノリでデフォルトの``sqlite3``を利用した）
そんなときは、``manage.py``を二つ定義しました。こうして中のbase.pyを別々にしてあげれば、OK.

## nginx周りを変更させたとき

``restart``をしましよう。

``sudo systemctl restart nginx``

# 状態を知りたいとき

基本的には、``sudo systemctl status``でOKでした。

ex.
``sudo systemctl status nginx``
``sudo systemctl status mysite.service``
``sudo systemctl status mysite.socket``

後は、``error_log``ですね。
``/var/log/nginx/error_log``です。



# 最終更新日
- 2020.02.25
- 2021.05.27
GCPロギングを使いPython（Flask）のログを管理

# GCPロギングを使いPython（Flask）のログを管理

[google-cloud-logging](https://github.com/googleapis/python-logging) をインストール

```
$ pip install google-cloud-logging
```

## ロギング設定

```Python
from google.cloud import logging


client = logging.Client()
logger = client.logger("pronichi")
```

ログ用の関数
severityはログレベル（INFO,NOTICE,ERROR etc...）
ログは環境変数、URI、任意メッセージを保存することにした
`ensure_ascii=False` を設定しないとコンソール表示が文字化け

```Python
def log_write(severity: str, uri: str, message: str):
    tmp = {"env": APP_ENV, "uri": uri, "message": message}
    tmp_json = json.dumps(tmp, ensure_ascii=False)
    logger.log_text(tmp_json, severity=severity)
```

スクリプトにログ追加

```Python
log_write("NOTICE", "/", "テスト")
```

## ログ確認

GCPコンソールよりログ出力されたか確認
![screencapture-console-cloud-google-logs-query-query-logName-projects-weekend-hackathon-logs-pronichi-2021-02-25-01_18_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/1cecfd10-d68d-c220-1f0a-8569846be9ea.png)

```
{
textPayload: "{"env": "prod", "uri": "/", "message": "テスト"}"
insertId: "1io3pqvgej50y6v"
resource: {2}
timestamp: "2021-02-24T16:15:50.363645648Z"
severity: "NOTICE"
logName: "projects/weekend-hackathon/logs/pronichi"
receiveTimestamp: "2021-02-24T16:15:50.363645648Z"
}
```

---

ログが出力できるようになりました
いいね！と思ったら LGTM お願いします :clap::clap::clap:

【PR】プログラミング新聞リリースしました！ → https://pronichi.com

【PR】週末ハッカソンというイベントやってます！ → https://weekend-hackathon.toyscreation.jp/about/
Raspberry Pi PicoでCO2濃度を測定する

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Raspberry Pi PicoでCO2濃度を測定する<br>CO2センサー(MH-Z19C)は秋月で買いました。<a href="https://twitter.com/hashtag/RaspberryPiPico?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPiPico</a> <a href="https://t.co/7r8mSMarU9">pic.twitter.com/7r8mSMarU9</a></p>&mdash; Sam Akada@HomeKit (@sam_akada) <a href="https://twitter.com/sam_akada/status/1364716699996446721?ref_src=twsrc%5Etfw">February 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
## CO2センサーモジュール
[ＣＯ２センサーモジュール　ＭＨ－Ｚ１９Ｃ](https://akizukidenshi.com/catalog/g/gM-16142/)を秋月で買いました。

## 接続図
![CO2A.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452335/8c133ad5-fb2d-5f3a-7284-9ad2a25e7983.jpeg)


## ソースコード
```python
import machine
import utime

mhz19c=machine.UART(1,baudrate=9600)

while True:
    data=bytearray([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
    mhz19c.write(data)
    mhz19c.readinto(data,len(data))
    co2=data[2]*256+data[3]
    print(str(co2)+' ppm')
    utime.sleep(1)
```

## 参考
- [M1 Macで Raspberry Pi PicoのLチカ](https://qiita.com/SamAkada/items/13cf63b6fc8a8198c160)
AWSを勉強しての備忘録

AWS Cloud Tech を通して学習した内容を備忘録として記述します。
#AWSとは
Amazon.comにより提供されているクラウドコンピューティングサービス。
AWSとは、Amazon Web Servicesの略で、Amazonが提供している100以上のクラウドコンピューティングサービスの総称。
従来の「オンプレミス」とは違い、初期費用なし、メンテナンスなし、料金は使った分だけで今すぐ使用することができる便利なサービス。
#主要サービス
+ VPC
仮想プライベートクラウドを提供する商用クラウドコンピューティングサービス。AWSクラウド空間上に自分だけのクラウド空間を作れる。広いAWSさんの土地に自分だけの土地を確保するみたいなこと。

+ EC2
安全でサイズ変更可能なコンピューティング性能をクラウド内で提供するウェブサービス。AWS上に自分がほしいスペックのサーバー自由に構築できる。VPCで確保した土地に自分の好みの家をつくるみたいなこと。

+ IAM
AWS リソースへのアクセスを安全に管理するためのウェブサービス。VPCやEC2にアクセスできるユーザーを管理するもの。AWS上に確保した土地や作った家に入れる人を管理する機能みたいなこと。

+ RDS
AWSのフルマネージドなリレーショナルデータベースのサービス。AWS上に確保した土地や作った家の中で必要な家具や家電を管理する機能みたいなこと。(←あまりいい例えじゃない気がする。)

#基本的なAWS構成図
クロカワさんのレクチャー・資料を参考に「cacoo」で作ってみました。
![AWS Design (updated) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552264/bd2a414e-6caf-613c-b240-e8f3ccfcf662.png)


主要サービス以外の解説

+ Availability　Zone
リージョンごとにアベイラビリティーゾーンと呼ばれる複数の独立した場所、つまりサーバーが置かれた建物がある。

+ インターネットゲートウェイ
VPCのコンポーネント(部品)の1つ。VPC内部とインターネットを通信をする機能。

+ subnet
大きいネットワーク（VPC）を小さく分割したネットワーク。
Public subnetとPrivate subnetで分けてVPC外部とやり取りするものとVPC内部でのみやり取りするネットワークという感じで分けて使う場合もある。　

+ Security group
VPCインスタンスの仮想ファイアウォールとして機能している。

+ レプリケーション
複製（レプリカ）の作成を意味する。2セット（稼働系と待機系）用意された環境において リアルタイムにデータ複製する技術のこと。
障害とか何かあれば瞬時に切り替わる仕組み。

#まとめ
AWSについて全くの素人がここまで学べました。
残りの教材も頑張っていきたいです。

この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
機械学習を学んでいてよく出てきた単語まとめ①

# はじめに
機械学習初心者で知らない単語だったり、聞いたことはあるけど具体的な意味を知らない単語、意味はわかるけど機械学習の観点で説明するとなった時にわからない単語などを集めてまとめてみました。
今回はscikit learn中心にまとめました。

# 単語まとめ
- **SVM (サポートベクターマシン)とは、データを分類して境界線を引くためのアルゴリズムです。**「教師あり学習」**と呼ばれる手法を用い、正解データを「教師からの助言」として学習し、学習結果を元に境界線を定めた「分類器」を作成する。 
- **clf = class ficationの略語。**翻訳すると**分類**。predictで予測させたいデータを指定して結果を出力するという流れになっている。
- **LabelEncoderr** : 文字を数値に変換　**OneHotEncoder** : 数値をダミー変数に変換
- **カテゴリカル変数** : 計数データをカテゴリカルデータと呼び、**性別**や**カテゴリー**を**カテゴリカル変数(categorical variable)**と呼ぶ。(例 性別(男、女)、血液型(A,B,O,AB)やアンケート調査票の中の質問における選択肢などを集計したデータは、いずれも計数データと呼ぶ。)
- **ダミー変数** : 「あるかなしか」、「ある状態をとるか取らないか」と言ったような、2つに1つとなる状況を、数値化して「1」か「0」かで表すこと。元々数字でないデータを数字に変換できるということ。
- **train_test_split**では、 **x_train(トレーニングデータ:特徴), x_test(テストデータ:ラベル), y_train(トレーニングデータ:特徴), y_test(テストデータ:ラベル)**のように書いて**xに訓練用・トレーニングデータ、yに学習用・テスト用データ**が入る
- **random_state**を利用する場合はシード値によってランダム値が決められており、シード値を同じ数字にすると毎回同じ疑似乱数が生成されるもの。
- **特徴データ** : 特徴が数値化されたもの。(例 身長や体重、年齢、性別)
- **ラベルデータ** : 各データがグラフで何を表しているのかを示すための情報。グラフに表示される値や割合などを示す数値のこと。
- **シード値** : **コンピュータで乱数を生成**する場合、ある数値をシード値(seed)として用い、その値を基にして特定の演算により乱数を生成していく。このため同じシード値を使用した場合、発生する乱数は全く同じものとなる。
- **疑似乱数** : **乱数の代わりに用いられる数字の列。**疑似数。コンピュータでは、サイコロを振って出る目のような無秩序(予測不可能)な数列は生成できないため、**計算によってそれに似た数列を作り、乱数の代用**とする。電子データの暗号化などに用いられる。
- **トレーニングデータ・テストデータ** : 教師あり学習によるモデルを作成するには、準備した**データセット**を**トレーニングデータ(訓練用データ、学習用データとも呼ばれる)**と**テストデータ(検証用データ、評価用データとも呼ばれる)**の2つに分割して予測モデルの作成、評価を行うことが一般的。このように**一定の割合でトレーニングデータとテストデータに分割することをホールドアウト(hpld-out)**と呼ぶ。
- **交差検証** : 汎化性能を評価する統計的な手法で、分類でも回帰でも用いることができる。**機械学習を行うとき、学習を行うための学習データと未知のデータに適用した時のモデルを評価するためのテストデータがある。トレーニングデータでの性能がとてもいいのにも関わらず、テストデータでの性能が悪くなってしまうことを過学習と言う。**
- **評価性能が必要な理由**：**既存のデータ(学習データ)の説明変数(特徴量)を使って目的変数を予測する予測式(モデル)を作り、結果が未知のデータを予測するから。**
- **k-分割交差検証(クロスバリデーション)** : 用意したトレーニングデータセットをk分割し、そのうちの1つのテストデータ、残りのk-1個を学習データとして使用する。そして、**学習と評価を繰り返して得られるk個のモデルと性能評価から平均性能を算出するという手法。

# 最後に
今回は以上です。
2つ目も投稿しようと思っているので、まとめましたら投稿します。
ありがとうございました。
EloquentORMとクエリビルダについてメモ

Laravel初学者です。
勉強のためメモを取っています。

ほぼ参考サイトを同じことが書いてるので、投稿する意味はないのですが、自分なりに書き方を変えながらメモったり、まとめたりすることで知識の定着率が上がらないかなぁと思い投稿しております。

Laravel Framework 7.30.4
PHP 7.4.9

# まとめ

個人でポートフォリオ作ったり、小規模なサービスであればEloquentで良さそう。

大規模なサービスで、サブクエリが大量に発行されて重くなる場合は、クエリビルダを使うとよいのかもしれない。

## Eloquent

Laravel7.x Eloquent
https://readouble.com/laravel/7.x/ja/eloquent.html

書き方

```
$posts = Post::where('category_id',$catId->id)->get();
```

### メリット

SQLを書かずにDBを操作したり、テーブル同士の関係性を定義できる。

### デメリット

 - ぱっと見でどういうクエリを発行しているのかわからない。
 - SQL文とは違う書き方をするので、専用の書き方を覚えないといけない。  


## クエリビルダ

Laravel 7.x データベース：クエリビルダ
https://readouble.com/laravel/7.x/ja/queries.html

書き方

```
$users = DB::table('users')->get();
```

### メリット

 - Eloquentより処理が早くなる。

 - サブクエリを使う使わない限らず、処理が早いと主張している人もいる。
参考：https://www.youtube.com/watch?v=3TJfR1Ta4GU
 - SQL文と書き方がほぼ同じなので、どんなクエリが発行されているかわかりやすい。

### デメリット

 - テーブル同士の結合を自分で行う必要がある。

リレーションを正しく把握しないといけない。
SQL文の理解が必要。




## 今まで認識していたLaravel→DBのやりとりについて

今までは↓のように認識していた

Laravel
↓↑
クエリビルダ
↓↑
Eloquent
↓↑
DB

でも違うらしい。

実際は、以下のようだ。

Laravel
↓↑
Eloquent or クエリビルダ
↓↑
DB

## EloquentORMとは

公式ドキュメント
https://readouble.com/laravel/7.x/ja/eloquent.html

Laravelが提供するO／Rマッパ

ActiveRecordライクにデータの取得ができる
↑これRailsの機能らしい。あ、だからActiveRecord”ライク”なのか。。。

RailsのO/Rマッパ = ActiveRecord
LaravelのO/Rマッパ = Eloquent

ってことっぽい。

参考：weblio辞書
https://www.weblio.jp/content/%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89

### メリット

O/Rマッパのメリットを享受できる。

 - LaravelでSQLを書く必要がない。
 - テーブル同士の関係性を定義できる。(Modelに書くリレーションのことかな？hasmanyとか)
 - 再利用性や拡張性が高い  
(例えばPostControllerからUserのModelにアクセスできたりするのが再利用性かな？)

拡張性は、独自メソッドを実装したり、特定のイベントをフックにした処理の実行(Observer)ができるということらしい。
カテゴリidからカテゴリ名を取得するメソッドを作ったことあるけど、これのことかな？

Eloquentだと以下の書き方になる。

```
$posts = Post::where('category_id',$catId->id)->get();
```
また、Eloquentモデルは、クエリビルダとしても動作するので、以下のようにクエリに制約を加えることもできる。

```
$posts = Post::where('category_id',$catId->id)
　　　　　　->orderBy('id', 'desc')
　　　　　　->get();
```

疑問点
クエリビルダとしても動作するなら、もうEroquentだけ使えばいい気がするけどなあ。

### デメリット

O/Rマッパのデメリットを享受する

 - SQLが書けなくてもデータ取得ができる。

 - ぱっと見て、どういうクエリを発行しているのかわからない

hasやwherehasを使うと、サブクエリを実行するが、
サブクエリを実行するとクエリの時間が長くなる。
なかには、join句を使えばサブクエリにしなくてもいい内容までサブクエリで実行してしまう。

 - Eloquent O/R マッパは、ActiveRecordパターンで実装されているので、ActiveRecord パターンを覚える必要がある

たとえば、テーブル名をPostsにしたら、モデル名はPostにするとか。
外部キーはなにも指定しなければ、idが自動で選ばれるとか、そういうのをパターンというのかな？

## クエリビルダとは

 - 複雑な条件や大量のデータを扱うため、クエリの回数を減らしてパフォーマンスを上げたい。

 - 複雑な条件のクエリを発行したい

場合に使う。

### Active-Recordとは

>Active-Recordパターンは、Enterprise Application Patternsの一種で、一つのデータベースのテーブルと一つのクラスを対応付ける。
またそのクラスのインスタンスを(クラスに対応する)テーブルの一つのレコードに紐付ける、というパターンです。
よくRuby on RailsやLaravelなどのWebフレームワークで用いられます。

引用元：
https://qiita.com/CostlierRain464/items/5be3c1860bb5137db3d1

## 参考サイト

Eloquent ORM vs Query Builder (+ DB Facade )
https://cocoeyes02.hatenadiary.jp/entry/2018/12/08/231033
Java 小テスト① 〜if 編〜

これは友達向けのJavaの小テストです。
Java初心者の文法腕試しでお使いくださいー！！

今日はif文の小テストを作りたいと思います！


第１問：ミスを探し, 動く状態を作りなさい。

```java
    public static void main(String[] args) {
        int grade = 90;

        if grade >= 90 {
            System.out.println("秀");
        } else if grade >= 80 & grade < 90 {
            System.out.println("優");
        } else if grade >= 70 & grade < 80 {
            System.out.println("良");
        } else if grade >= 60 & grade < 70 {
            System.out.println("可");
        } else {
            System.out.println("不可");
        }
    }
```

第２問：出力結果を答えなさい。

```java
    public static void main(String[] args) {
        Random random = new Random();
        int randomValue = random.nextInt(8);
        int grade = 60 + randomValue;

        if (grade >= 90) {
            System.out.println("秀");
        } else if (grade >= 80 && grade < 90) {
            System.out.println("優");
        } else if (grade >= 70 && grade < 80) {
            System.out.println("良");
        } else if (grade >= 60 && grade < 70) {
            System.out.println("可");
        } else {
            System.out.println("不可");
        }
    }
```


第3問：次の問題に答えよ。

> if文における"&"と"&&"の違いは何か？


第4問：下記を全て満たすプログラムをJavaで書きなさい。

- 変数(int型)numberを準備する
- numberは1 ~ 10の値をランダムに取る
- numberが7のとき, 「大当たり」を出力
- numberが1か2か３か５の場合「当たり」を出力
- それ以外は「ハズレ」を出力


次は「for」の予定！！
Macのデスクトップに動画ファイルが追加されたら、自動的にGifを生成してみる

## はじめに
普段アプリ開発をしているときに動作確認した結果をGifでPRに載せたりするのですが、
`.mov`や`.MP4`の動画ファイルからFFmpegでGifを生成するのを自動化できないかなーと思い、やってみました！

## 準備
動画ファイルからGifを生成するのに[FFmpeg](https://ffmpeg.org/)を使用するので、ダウンロードしておきます。

Homebrewからでもインストールできます。

```
$ brew install ffmpeg
```

## AutomatorでWorkflowを作成する
Macの作業を自動化するということで、今回は標準で用意されている`Automator`を使用します！

まずは、Automatorを起動して、フォルダアクションを新規作成します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/2cdad5db-c3c7-4ad9-04a7-10a363282fa5.png)

フォルダはDesktopを指定します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/3c6799c2-6d40-74e2-d793-f21852a8f54b.png)

左上の検索欄に「シェルスクリプト」と入力してアクションを検索をして、「シェルスクリプトを実行」のアクションを右側にドラッグします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/3d85e7a0-3c48-c269-a0f7-dcff06fbac5c.png)

「入力の引き渡し方法」を「引数として」に変更して、以下のスクリプトを書きます。
fpsやscaleなど、ffmpegの設定値の部分は、お好みで調整してください(\*・ω・\*)

```shell
# 1
originalFilePath=$1

# 2
if [[ $originalFilePath == **".mov" ]] || [[ $originalFilePath == **".MP4" ]] || [[ $originalFilePath == **".mp4" ]]; then
  uuid=$(uuidgen)
  uuidFilePath=$originalFilePath-$uuid

  # 3
  /usr/local/Cellar/ffmpeg/4.3.1_9/bin/ffmpeg -i $originalFilePath -filter_complex "[0:v] fps=20,scale=320:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" $uuidFilePath.gif
fi
```

`# 1`の行で、引数で受け取った動画ファイルのPATHを変数に格納しています。

`# 2`のif文で、動画ファイルの拡張子を`.mov` `.MP4` `.mp4` の3つに限定しています。
Gifファイルがデスクトップに追加された場合もWorkflowが動くので、条件を指定しないと、自動生成されたGifファイルから新しいGifファイルを作り出そうとして、無限にGifを作り続けてしまいます(´；ω；`)

`# 3`でffmpegを実行していますが、`/usr/local/Cellar/ffmpeg/4.3.1_9/bin/ffmpeg` の部分は、ffmpegが格納されているPATHを指定する必要があるので、適宜変更してください。
`/Applications/ffmpeg` とかの場合もあるかもしれません。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/324c791f-e2ec-2129-7318-de875da3b2cb.png)


「command + S」で、適当な名前を付けて保存します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/a7e0952b-1f0a-f2aa-e830-5aacc55a4676.png)

これで、保存して終了です！
デスクトップに`.mov`や`.MP4`または`mp4` のファイルが追加されると、gifを生成してくれるようになります。

## さいごに
デスクトップに動画を追加したら、Gifを作ってくれるようになりました:clap:
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/17f283fc-7746-61d3-cbc1-ac8e6945a923.gif)

↑のGifでは別のディレクトリからドラッグしてデスクトップに動画を追加していますが、
QuickTime Playerとかで画面収録をしたら、Desktopに動画保存されるので
そこから勝手にGif作ってくれるといった感じです\\(。・o・。)/

ちなみに、iOSのアプリ開発であれば、
以下のようなxcrunコマンドでiPhone Simulatorの動画を撮ることもできるので、
その時にもデスクトップに動画ファイルを保存すれば勝手にGif作ってくれます！
`xcrun simctl io booted recordVideo output.mov`
rails + docker環境内で時間を日本時間に合わせる

docker-compose.yml

```
web: &web
    build: .
    # command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
      - gem_data:/usr/local/bundle
    ports:
      - "3000:3000"
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
      WEBPACKER_DEV_SERVER_PUBLIC: 0.0.0.0:3035
      TZ: Asia/Tokyo　←　こいつを記載
```
application.rb

```
module App
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0
    # config.active_record.default_timezone = :local
    config.i18n.default_locale = :ja # デフォルトのlocaleを日本語(:ja)にする


    config.time_zone = 'Asia/Tokyo'　←　追加
    config.active_record.default_timezone = :local ←　追加


    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

    initializer(:remove_action_mailbox_and_activestorage_routes, after: :add_routing_paths) { |app|
      app.routes_reloader.paths.delete_if {|path| path =~ /activestorage/}
      app.routes_reloader.paths.delete_if {|path| path =~ /actionmailbox/ }
    }
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    config.paths.add 'lib', eager_load: true
  end
end
```

これだけで日本時間に変更可能。
＃dockerfileは書き換えたら docker-compose down、docker-compose upの手順踏まないと反映されません。
閾値判定のためのスレッショルドを作ってみた



農業用IoTシステムで自分が指定した値になったときにラインの送信をするために閾値判定のためのスレッショルドを作ってみました。

スレッショルドとは敷居、閾のことです。
具体的には温度がx℃となったときにアラートを発信するとしたときのxという値だと考えてください。

スレッショルドに付随してヒステリシスという考え方があります。
ヒステリシスとは物質の状態が現在の状態だけではなく、過去の経路の影響を受けることです。
少しわかりにくいかもしれませんが、スレッショルドを判断するときの幅（余裕）だと考えてください。

具体的にはx℃という閾値をとるときに判断する幅を2yにするとしたら、
判断するときの上限値はx+y、下限値はx-yとなります。

つまりx+yを上回ったときに上限を超えたという判断を
x-yを下回ったときに下限値を下回ったという判断をするようにします。

実際にc言語で実装してみました
スレッショルドよりも温度が上がったときと、温度が下がったときにアラートを発信するプログラムです。
そのままプログラムを書いてしまうと、
同じ状態で何度もアラートを発信してしまうので、
プログラムに状態を持たせます。

閾値よりも低温の状態の時に閾値を超えたときと、
閾値よりも高温の状態の時に閾値を下回ったときにアラートを送信するようにしています。
また。閾値の付近で頻繁にアラートを送信しないようにするためにスレッショルドを指定するようにしています。

```
/*アラートを送信するためのスレッショルドの作成テスト
スレッショルドとヒステリシスは最初に設定する*/

#include<stdio.h>

//statusを定義する
enum status {
	high,
	low
};



int main(void) {

	int		value_th;			//スレッショルドの値
	float	hys;				//ヒステリシス
	float	th_higher;			//ヒステリシスの上限値
	float	th_lower;			//ヒステリシスの下限値

	//入力された値を判断する
	float value;

	//テストで使用するときは値を手入力する
	//value_thを入力する
	printf("input threshold: ");
	(void)scanf_s("%d", &value_th);
	//hysを入力する
	printf("input hysteris: ");
	(void)scanf_s("%f", &hys);

	th_higher = value_th + hys;
	th_lower = value_th - hys;

	//確認用の表示
	printf("th_higher is %F\n", th_higher);
	printf("th_lower is %F\n", th_lower);

	
	//閾値よりも低い状態からスタートすると仮定する
	int status = low;
	

	//ヒステリシスを含めた値と同じになった場合はlowerのほうに含めることにする
	//テストのために10回好きな値を入力できるようにする
	for (int i = 0; i < 10; i++) {

		printf("input value: ");
		(void)scanf_s("%f", &value);

		//statusがlowの時に閾値を超えた場合
		if (status == low && th_higher < value) {

			//alertを出す
			printf("this is High\n");
			//statusをhighにする
			status = high;
		}

		//siatusがhighの時に閾値を超えた場合
		else if (status == high && th_higher < value) {

			//特に何もしない


		}

		//statusがhighの時に閾値を下回る
		//statusがlowの時に閾値を下回る場合
		if (status == low && th_lower >= value) {

			//特に何もしない
			
		}

		//statusがhighの時に閾値を下回る
		 else if (status == high && th_lower >= value) {

			//alertを発火する
			printf("this is law\n");
			//statusをlowにする
			status = low;

		}
	}	

	return 0;

}


```

テストをしてみて想定通りに結果が出たので、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/f97455e6-8bb6-2eb8-5b2d-e602f7b6feca.png)

ちょっとだけ改造して、農業用IoTシステムのアラート発信判断部分に実装しました。

今のところいい感じで使えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/d9853987-83fb-0ee0-500c-f10c63d2ca87.png)
コマンドラインから(awscliで）CloudFrontのキャッシュ無効化する

## 手順

3つのコマンドを実行して達成可能。

1. CloudFront の disutribution id を入手
2. パスを無効化する
3. 無効化の進捗状況を確認する

## 例の内訳

<dl>
  <dt>{profile}</dt>
  <dd>認証情報のプロファイル</dd>
  <dt>{hostname}</dt>
  <dd>ドメイン割り当て済みならFQDN</dd>
  <dt>{path}</dt>
  <dd>無効化するパス。例えば<code>/aaa/bbb.json</code></dd
</dl>

## 例

```cli
$ aws cloudfront list-distributions --profile {profile} | jq '.DistributionList.Items[] | .Id + " " + .Aliases.Items[0]' -r
E************ {hostname}
...

$ aws cloudfront create-invalidation --distribution-id E************ --paths "{path}" --profile {profile}
{
    "Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/E************/invalidation/I17***********",
    "Invalidation": {
        "Id": "I17***********",
        "Status": "InProgress",
        "CreateTime": "2021-02-22T12:47:09.866Z",
        "InvalidationBatch": {
            "Paths": {
                "Quantity": 1,
                "Items": [
                    "{path}"
                ]
            },
            "CallerReference": "cli-0000000000-000000"
        }
    }
}

$ aws cloudfront get-invalidation --id I17*********** --distribution-id E************ --profile {profile} | jq -r '.Invalidation | .CreateTime + " " + .Status'
2021-02-22T12:47:09.866Z Completed

$ aws cloudfront get-invalidation --id I17*********** --distribution-id E************ --profile {profile}
{
    "Invalidation": {
        "Id": "I17***********",
        "Status": "Completed",
        "CreateTime": "2021-02-22T12:47:09.866Z",
        "InvalidationBatch": {
            "Paths": {
                "Quantity": 1,
                "Items": [
                    "{path}"
                ]
            },
            "CallerReference": "cli-0000000000-000000"
        }
    }
}
```
【Swift】ViewControllerのライフサイクル

#はじめに
この記事では、ViewControllerのライフサイクルについて簡単にまとめました。
⚠️当方初学のため認識違いがある可能性大です
誤りを見つけた際はコメントにて指摘していただけると幸いです🙇‍♀️🙇‍♂️


#ライフサイクルの発火の流れ
①loadView(View読み込み前)
②viewDidLoad（View読み込み後）
③viewWillAppear（View表示前）
④viewWillLayoutSubviews（SubViewレイアウト前）
⑤viewDidLayoutSubviews（SubViewレイアウト後）
⑥viewDidAppear（View表示後）
⑦viewWillDisappear（View除去前）
⑧viewDidDisappear（View除去後）


#目次
1. loadView
2. viewDidLoad
3. viewWillAppear
4. viewWillLayoutSubviews
5. viewDidLayoutSubviews
6. viewDidAppear
7. viewWillDisappear
8. viewDidDisappear


#1. loadView
 - タイミング・・・viewがnilの状態でviewを呼び出そうとした時
 - 活用例　　・・・Viewの追加や制約の追加など、StoryBoardで行う操作のコードでの実装


#2. viewDidLoad
 - タイミング・・・viewをメモリにロードした後
 - 活用例　　・・・クラス内で利用するオブジェクトの初期化


#3. viewWillAppear
 - タイミング・・・viewをview階層に追加する直前、もしくはviewを表示するためにアニメーションが設定される前
 - 活用例　　・・・表示されるたびにviewを更新したい処理


#4. viewWillLayoutSubviews
 - タイミング・・・viewがSubviewをレイアウトする前
 - 活用例　　・・・特になし


#5. viewDidLayoutSubviews
 - タイミング・・・viewがSubviewをレイアウトした後
 - 活用例　　・・・特になし


#6. viewDidAppear
 - タイミング・・・viewがview階層に追加された後
 - 活用例　　・・・ログの送信、操作のブロック


#7. viewWillDisappear
 - タイミング・・・viewがview階層から削除される前
 - 活用例　　・・・特になし


#8. viewDidDisappear
 - タイミング・・・viewがview階層から削除された後
 - 活用例　　・・・特になし