OmniAICreator/Qiita-1.07M huggingface dataset:
【ポートフォリオ説明】ラーメン記録アプリの概要


# 作成した経緯
- 友人と食べたラーメンを共有したい
- まだ行ったことのないラーメン屋に行きたい
- 行ったお店を把握することにより、全員が行ったことのない店がわかる
- 食べたラーメンを分かりやすく記録したい
- ラーメンが好き

# 使った技術
- 言語　Java
- フレームワーク　Spring Boot
- O/Rマッパー　MyBatis
- DB　MySQL
- フロント　HTML/CSS/BootStrap
- デプロイ　AWS Elastic Beanstalk

# ログイン画面
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/085e4686-c46f-5f3c-6067-677926229679.gif)

- バリデーション  
- パスワードのハッシュ化

# TOPページ
![スクリーンショット 2021-02-08 232858.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/09e69bc5-84b1-6169-ba76-a694a2451e51.png)

- 登録した全件を表示

# 新規登録画面
![Videotogif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/dc4eb839-2096-d5a5-9b13-d7bc4655aaa8.gif)
![スクリーンショット 2021-02-08 213824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/aac8746d-be6a-1553-6314-852f8ec5599c.png)

- バリデーション（画像URLは任意）

# 詳細画面

![スクリーンショット 2021-02-08 214318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/220796ff-a1ad-a76d-1a57-6bb49a67b3b8.png)

- 画像URLを新規登録時に入力しなかった場合、もしくはURL出ないものが入力された場合は自動的にNO IMAGEの画像が入る


# 変更画面
![スクリーンショット 2021-02-08 214550.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/e341c0c6-2446-c0bd-5a32-ed665276eaa6.png)

- 新規登録画面とほぼ同じバリデーション。

# 削除
![Videotogif (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/1cc40224-fae4-c35b-6c70-5a91d3edf921.gif)


# 検索機能
![Videotogif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/32b67dc7-62e8-235f-b08c-7fcaff6bea13.gif)

- カタカナや半角でも検索可能
- 該当する結果が得られない場合は「該当の検索結果がありません！」と表示

# 新規ユーザ登録画面 ※管理者専用
![スクリーンショット 2021-02-08 233306.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/8bc1ad21-0c1a-32bb-fd52-c28c327a20c1.png)

- バリデーション  
同じusernameは登録不可  
パスワードは8文字以上、数字と大文字、小文字のアルファベットを含めることが必須
- ユーザか、管理者か選択

![Videotogif (5).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/2b25bd72-839d-50ac-6a5b-76fd9393f83b.gif)

- ユーザは権限がないので新規ユーザ登録できない

# ログアウト
![スクリーンショット 2021-02-08 235818.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/f2ab3539-34f1-26cc-4501-93ce1f48a7f3.png)

# デプロイ
デプロイについてはこちら
https://qiita.com/sumichan/items/2f651cdf6369ef7ca84c

# 使って頂いて修正した点
- パスワードの強化
- validationの強化  
プルダウン（評価の★）にvalidationがついておらず、★以外もいじれてしまった

# 今後修正したい点
- 画像をURLではなくアップロードにしたい
- DBのテーブルをしっかり分けたい

# 感想
ダメなところもたくさんありますが、このアプリを通して成長できたと感じました。
ひとまず形になったことがうれしいです。
HTAの待機と中断(WScript.Sleep，WScript.Quitが使えない問題)

#前提
　HTAはWSHではなく，IEのエンジンを使って動くので，Wscriptから始まるメソッドが使えません(※別途CreateObjectで生成するWscript.shellなどは使えます)。
　Wscript.Echoなんかは全然困らないんですが，困るのがWScript.QuitとWScript.Sleepとです。
#中断
　まず，うまくいかない例から紹介します。中断事由があればexitMsgに入れて，exitMsgが空ではなければexitMsgを表示して中断するとします。

```vb:
        If exitMsg <> "" Then
            MsgBox exitMsg
            Window.Close
        End If
```
　これでは，HTAの窓が閉じるだけで，後処理が実行されてしまいます。
　なので，安全に中断するためには，基本的に全ての処理をSubプロシージャに入れて，Sub外でCallするようにした上で，windows.Closeの直後にExit Subをして処理を中断します。

```vb:hta
<script language="VBScript">
    '全てSubプロシージャで囲む
    Sub close_exit()
        ････(処理略)････
        If exitMsg <> "" Then
            MsgBox exitMsg
            Window.Close
	    exit sub
        End If
    End Sub
'ここで呼ぶ
Call close_exit()
</script>
```
　もちろん，Callを複数並べるとExit Subをしても次のCallに移行してしまうので，基本的にはメインのSubプロシージャ（変な呼び方ですが・・・）のみCallして，その中で関数や他のSubプロシージャを呼ぶようにすると安全に中断できます。

#待機
　WScript.ShellのRunメソッドでコマンドラインのTimeoutを実行して対応しました。
[Timeout(マイクロソフト公式)](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/timeout)

```vb:hta
<script language="VBScript">
sub sleep1Second()
	Dim wShell
	Set wShell = CreateObject("WScript.Shell")
	wShell.Run "Timeout.exe /t 1", 0, True
	Set wShell = Nothing
end sub
</script>
```
 これを呼び出して使います。

```vb:Run部分
wShell.Run "Timeout.exe /t 1", 0, True
```


　第一引数でコマンドラインの実行をします。１秒待つようにしていますが，待ち時間を変動させたいのであれば，1はダブルクオーテーションから出して引数で指定できるようにしてもよいと思います。
　第二引数はコマンドプロンプトの窓を表示するかの指定です。通常は表示したくないと思いますので，0を指定します。
　第三引数は返値を返すかを指定します。Falseにすると，後処理はコマンドラインの実行を待たず，せっかくのタイムアウトができなくなるのでTrueにします。

#使用例
　これで中断も待機もできるようになりました。
　たとえばIEでページ移動をした後，新しいページを取得するとして，こんな感じで呼び出したりしています。

```vb:hta
<script language="VBScript">
sub sleep1Second()
	Dim wShell
	Set wShell = CreateObject("WScript.Shell")
	wShell.Run "Timeout.exe /t 1", 0, True
	Set wShell = Nothing
end sub
Sub main()
    (///ボタンを押すなどしてページ遷移///)
    '1秒間ごとにページの取得を試みて，5秒間取得できなければループを抜ける
    Dim ie 
    Dim s
        For s = 1 To 5
            'ここで待機
            sleep1Second
            On Error GoTo 0 
            On Error Resume next
            Set ie = FETCH_PAGE("対象ページのlocationName")
                If Err.Number=0 then
                    Exit For
                End If
        Next
        If Err.Number=424 then
            MsgBox "画面に遷移できません"
            'ここで画面を閉じて中断
            Window.Close
            Exit Sub
        End If
    On Error GoTo 0 

    Dim htmlDoc 
    Set htmlDoc = ie.document
End sub
'おまけ：画面で取得する関数
Function FETCH_PAGE(locationName)
    Dim shellApp 
    Set shellApp = CreateObject("Shell.Application")
        Dim win 
        For Each win In shellApp.Windows
            If win.Name = "Internet Explorer" And win.locationName = locationName Then
                Set FETCH_PAGE = win
                Exit For
            End If
        Next
End Function
'ここで呼ぶ
Call main()
</script>
```
　意外と代替手段で対応できることがお分かりいただけると思います。
　HTA，まだまだ現役です。
upm 経由でUnity に  firebase をインストール

ググっても公式情報がなぜか出てこなかったので、やや怪しい情報であるが、こうやると、Registry が追加されて、インストールできる気がする。

![スクリーンショット 2021-02-08 16.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30407/257f60c0-861d-f279-f635-f0f25267dfb2.png)

デスクトップに転がってたメモのスクリーンショットを供養。
Obsidian、Advanced Tablesプラグインが入力しにくかったのが、実はなんとかなった件

### 背景

Obsidianで、Advance Tablesというプラグインがあって、表を書くのに大変べんりなのだけれど、日本語変換との相性が悪いという問題があった。

じつはけっこう困っていて、テーブルを書くときだけ`VS Code`を立ち上げるという、回りくどいことをしていたのだけれど、プラグインの作者のGitHubページを見ていたら、ちゃんと回避策が書いてあった。

Support for non-English language #16
https://github.com/tgrosinger/advanced-tables-obsidian/issues/16


### 対応

要は「日本語の場合、変換のつもりでエンターキーを押すと、テーブルプラグインが「次の行」と勘違いしてしまう」ので、エンターキーの動作を切ればいいという話。

次の行をつくるのには、`shift` + `enter` にすればいいと書いてあったけど、まあそこまで困っていないので、とりあえずエンターを切った。

![SS 2021-02-08 23.49.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/4c57a2c5-4569-e5ae-45b0-424dd4d6ecaf.png)

### 感想

オープンソースはほんとすばらしい。英語でGitHubをのぞく必要はあるけれど……だいたい困ったことは、誰かがなんとかしてくれている。

今回、いろいろとイシューを挙げてくださっているyo-gotoさんは`Obsidian`の日本語化にも尽力してくださっていて、ありがたい。わたしもせっせと日本語化していたけれど、yo-gotoさんが早くてよりよい日本語にしてくださるので、すっかりお任せ……。

### 目次にもどる

[Obsidian｜使いかたの記録（目次） - Qiita](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)

### 環境

- Advanced Tables Plugin v0.9.1
- Obsidian v0.10.11
- macOS BigSur 11.1
- MacBook Pro (13-inch, 2020, Four Thunderbolt 3 Ports)
CloudFormation で署名付きCookieが有効なパスを含む CloudFront Distribution を作る

主に個人的作業メモ。

# 作成する CloudFront の性質

- `/m/*` -> 署名付きCookieがないと閲覧できない、API Gateway (Lambda) が実体を持つコンテンツ
- `/v1/*` -> API Gateway (Lambda) が実体を持つコンテンツ
- `/* (Default)` -> S3 に実体がある静的コンテンツ

# 経緯

2021年2月現在、CloudFront には以下の機能が追加されている。

- Root権限で作成した鍵ではなく、ユーザー権限で公開鍵・KeyGroup を作成して、そのKeyGroup内で署名した Cookie に基づいて特定パス以下のアクセスを制限する機能
  - 例えば、`/private/*` のパスを閲覧する場合、ユーザーの Cookie に事前に適切な値が含まれていない場合 403 エラーとなるような仕組み
- これを実現するためには以下の項目を順次行う必要がある
  - CloudFront に公開鍵を登録する
  - 登録した公開鍵を含む KeyGroup を作成する
  - CloudFront の Behavior (パスごとの挙動) に対して、KeyGroup を指定することで、そのパスに対する署名付きCookie必須のアクセスに制限できる

# CloudFormation 内で実施すべき作業とメモ

- 公開鍵を CloudFormation で登録する
  - EncodedKey には YAML で以下のように登録すればよい
  - `|` は以降の行を改行で結合して複数行を１行に扱うための記号
  - なお、ここで公開している公開鍵は検証用に作ったものなので、自分で登録する場合は別途自分で秘密鍵・公開鍵を作成すること

```yaml
        EncodedKey: |
          -----BEGIN PUBLIC KEY-----
          MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxhzuK6zXYY5w3gwubNYh
          OPPto8+UuvepM/Yna46eqCTQ+6uNC5zjuindBUEAnY4SUBFqeD8uECXpuKYd9Yf/
          JB0tsC1XGeXYzqS4z5OZbGL28p6Kj4tFcTBz1htCGq0Ldhgsag+ZduWRieZUYsFa
          QbfHgFcpJrubqaF4isZLVMTlg0PgT//wkJCDE2KHk/WOBW7hpVo0KDLpztxRKM4s
          kVC4Xt4nqV0q/lfw45PW/d3R5CBt8xdnn26pxMRGRLf2v3DJHpFR7rzDU/TQphFW
          sYRQEudAJcl+eGkUH08LRYnirDnH7f9zI/1lCVsxmSzr/2jZlsqx0BVe6doyXqR4
          sQIDAQAB
          -----END PUBLIC KEY-----
```


# CloudFormation Template

以下の Gist に YAML 形式のものを示す。 
なお、コメントなどは Amplify をもとにしたものなので、それに準じた値が入っている。

https://gist.github.com/t-kigi/f0f104e301b6009a856cee5289cab863
GitHub リベース スタッシュ タグ 

#【GitHub リベース スタッシュ タグ】

山浦清透さん いつもありがとうございます。
[Git：もう怖くないGit！チーム開発で必要なGitを完全マスター](https://www.udemy.com/course/unscared_git/)

##リベース

<strong>リベースは、変更を統合する際に、履歴をきれいに整えること。</strong>
マージのようにただ変更内容を取り込むだけではないところが相違点。

リベースで履歴を整えた形で変更を統合する。
　→　git rebase < ブランチ名 >

　※ブランチの基点となるコミットを別のコミットに移動する。

<strong>注意：GitHubにプッシュしたコミットをリベースするのは絶対NG</strong>
　→　GitHub上の履歴が壊れてしまう恐があるため。

###マージかリベースどちらを使うか。

作業履歴を残したい場合は、マージを使う。
作業履歴を残す必要が無く、履歴をきれいにしたい場合は、リベースを使う。

###プル時にリベースする。

マージコミットを残さずに、GitHubの内容を取得したい時に使う。
GitHubの情報を単純に取得したい時に使う。
　→　git pull --rebase

デフォルトで、プルの挙動をリベース方に設定する。
 →　git config --global pull.rebase true

 ※このコマンドを実行しておくことで、プル時に--rebaseが不要になる。

##スタッシュ

<strong>スタッシュは、作業が途中でコミットしたくないけど、別のブランチで作業しないといけないような時に作業を一時退避する。</strong>

###作業を一時退避

作業を一次退避する。
　→　git stash

　※stashは、隠すと言う意味。変更分をstashに一次退避。

###一時退避した作業を確認

退避した作業の一覧を表示する。
　→　git stash list 

###一時退避した作業を復元

退避した作業を復元する。
　→　git stash apply　（最新の作業を復元）
　→　git stash apply --index　（ステージの状況も復元）
　→　git stash apply [スタッシュ名]　（特定の作業を復元）

　※ apply：適応すると言う意味。

###一時退避した作業を削除

退避した作業を削除する。
　→　git stash drop　（最新の作業を削除）
　→　git stash drop [スタッシュ名]　（特定の作業を復元）
　→　git stash clear　（全作業を削除）

##タグ

<strong>タグは、コミットを参照しやすくするためにわかりやすく名前を付ける。</strong>
リリースポイントによく使う。

###タグの一覧表示

タグの一覧を表示する。
　→　git tag -l （ -lを付けると絞り込みができる。）

###タグの作成

<strong>アノテーション付き（annnotated）とシンプル版（lightweight）の2種類がある。</strong>

アノテーション付きのタグを作成する。
名前やコメント、署名を付けられる。
　→　git tag -a [タグ名] -m "[メッセージ]"

　-aオプション：アノテーションタグを作成
　-mオプション：エディタを立ち上げずにメッセージ入力が可能

シンプル版のタグを作成する。
名前のみを付けられる。
　→　git tag [タグ名]

　※アノテーション付きとの違いは、-aオプションが付いているかいないか。

###タグのデータを表示

タグのデータと関連付けられたコミットを表示する。
　→　git show [タグ名] 

###タグをリモートリポジトリに送信

タグをリモートリポジトリに送信するには、git pushコマンドが必要。
　→　git push [リモート名] [タグ名]

タグを一斉に送信する。
　→　git push [リモート名] --tags

　※--tagsを付けると、ローカルにあってリモートリポジトリに存在しないタグを一斉送信

##おまけ

山浦清透さん ありがとうございました。
Git、GitHubの学習を一通り終えることができました。
今後のチーム開発に活かしていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472549/974834ec-8fd4-c813-d7e8-4b34de8e01fa.png)
Windows powershellにscoop＆oh-my-poshをインストール

Windows powershellにscoop＆oh-my-poshをインストール

# scoop のインストール
```powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
```

# ツールをインストール
```powershell
scoop install aria2
scoop install jq ccat wget sed vim
scoop install 7zip sudo git unzip openssl
```

# PowerLineのインストール
```powershell
Install-Module posh-git -Scope CurrentUser
Install-Module oh-my-posh -Scope CurrentUser
Install-Module -Name PSReadLine -Scope CurrentUser -Force -SkipPublisherCheck
```

# プロファイルを修正
以下のファイルを修正もしくは、作成。

```powershell:\Users\【ユーザー名】\Documents\PowerShell\profile.ps1
# Ctrl + d で Exit
Import-Module PSReadLine
Set-PSReadlineKeyHandler -Key ctrl+d -Function DeleteCharOrExit

# bash風のtab補完
Set-PSReadLineKeyHandler -Key Tab -Function Complete

# PowerShellでPowerLineを適用するための設定
Import-Module posh-git
Import-Module oh-my-posh
Set-PoshPrompt -Theme Paradox
```

Fontは、これで。
プログラミングフォント 白源 (はくげん／HackGen)
https://github.com/yuru7/HackGen

# 参考
https://ascii.jp/elem/000/004/045/4045177/
https://tech-blog.cloud-config.jp/2021-02-19-switch-lover-from-wsl-to-powershell/
Pythonからテスト用コンテナを手軽に作成する方法(testcontainers-python)


# 概要
https://github.com/testcontainers/testcontainers-python

pythonコード内でMySQLやPostgres、Seleniumなどのテストコンテナを作成することができる、testcontainersというライブラリがあるらしいというので試してみた結果です。
最初はDocker環境もいらないとかまさかないよね、と思いつつちょっと期待して試しましたが、予想通り、単にどこかにある既存のDockerホストに対して命令するだけだったのですが、それでも手動で上げ下げするよりは楽だと思われます。

対応範囲も広く、以下に対応しています。
- MySQL
- MariaDB
- PostgreSQL
- ElasticSearch
- Oracle DB
- MongoDB

MongoはなぜかReadmeに記載ないですが、以下のように対応しています。
https://testcontainers-python.readthedocs.io/en/latest/database.html#testcontainers.mongodb.MongoDbContainer

# 前提
自分のPCにDocker Toolboxを使ってコンテナ実行環境を作成しています。WindowsなのでDocker Desktop for Windowsを使いたいところですが、Hyper-Vを有効化できないため、インストールできません。またWindowsのバージョンも縛りがあり、WSL2も不可。
そこで少し古い方法ですが、Docker Toolboxというツールを使用しています。
https://docs.docker.com/toolbox/toolbox_install_windows/

Oracle Virtualboxという仮想化ソフトをHypervisorとして使用し、そのうえでLinuxを動かし、その上でDockerを起動する形になる。そのため、前提としてVirtualBoxをインストールする必要がある。(Toolboxをインストールする際に一緒にインストールすることもできる)

Host: Windows10(1803)
VirtualBox:6.0.12
Docker: 19.03.1

またDocker-Toolbox自体は起動された状態にしておく必要がある。(testcontainersからDocker-Toolboxの起動はできない。たぶん)

ちなみにコンテナ起動環境は、Windowsの場合、DOCKER_HOSTという環境変数を元に探しているとのこと。

```shell-session
echo %DOCKER_HOST%
tcp://192.168.99.100:2376
```

# インストール
必要モジュールのインストールを実施。今回つかう範囲で必要だった上2つは追加で入れています。

```shell-session
pip install PyMySQL
pip install sqlalchemy
pip install testcontainers
```

公式にあるrequirementsファイルをpythonのバージョンに合わせて使用してもよいのですが、分量が多すぎたので個別にいれています。
https://github.com/testcontainers/testcontainers-python/tree/master/requirements

# テスト
公式のテストコードそのままですが、以下のコードを記載したファイルを作成し、実行します。

```py3:app.py
import sqlalchemy
from testcontainers.mysql import MySqlContainer

with MySqlContainer('mysql:5.7.17') as mysql:
    engine = sqlalchemy.create_engine(mysql.get_connection_url())
    version, = engine.execute("select version()").fetchone()
    print(version)  # 5.7.17
```

イメージがない場合はpullしてきて起動してくれます。新規にコンテナを起動した場合は、コード実行後にコンテナも削除するようです。

# テスト(MongoDBバージョン)
前提としてPyMongoをインストールしておきます。

```shell-session
pip install pymongo
```

以下のコードを実行。MySQL同様にバージョンを返しています。

```py3:app.py
from testcontainers.mongodb import MongoDbContainer

with MongoDbContainer("mongo:4.4.4") as mongo:
    db = mongo.get_connection_client()
    version = db.server_info()['version']
    print(version)  # 4.4.4
```

# 感想
今までは開発環境の操作とコーディング、テストは別々に行っていましたが、これをうまく使えば統合できそうだなと。ただまだそこまで至っていないので、まずはテストをしっかり書くところから取組みたいと思います。
Site Kitプラグインで別URLを認識させる方法

Site Kitプラグインで別URL	を認識させる方法


# 内容
WordPressの管理画面のURLとエンドユーザ向けのURLのドメインを変えている場合に、Site Kitにエンドユーザ向けのURLを認識させる方法。
公式の下記案内に沿って試したが上手くいかず、色々試したら理由はわからないが登録する手順を見つけたので、備忘録として残しておく。
>Use Site Kit with a staging environment
>https://sitekit.withgoogle.com/documentation/using-site-kit-on-a-staging-environment/

# 前提
* WordPressの管理画面のURLを https://wp.example.com とする
* 認識させたいURLを https://front.example.com とすし、以下では「フロントのURL」と呼ぶ

# 事前準備
* 管理画面のURLにアクセス制限がある場合は、一時的に解除する
* 「Site Kit by Google」プラグインと「Site Kit by Google Dev Settings」をインストールし、有効にする
* 管理画面のURLのTOP（https://wp.example.com） でHTTPステータス200、かつwp_head、wp_footer関数を実行した結果をレスポンスする（補足後述）
* 下記を満たすGoogleのアカウントを用意する
    * Search Consoleに https://front.example.com が登録されており、閲覧以上の権限を持っている
    * Googleアナリティクスに https://front.example.com が登録されており、閲覧以上の権限を持っている

## 管理画面のURLのTOP(https://wp.example.com) で必要なレスポンスをするためのコード例
```
<?php
wp_head();
print("index");
wp_footer();
?>
```

# 登録手順
## 1. 管理画面「Site Kit Developer Settings」で「OAuth 2.0 クライアント」を作成
「Create your credentials」からGoogle Cloud Platformの「OAuth 2.0 クライアント」を登録する。
「OAuth 2.0 クライアント」の「承認済みのリダイレクト URI」には下記を設定する
https://wp.example.com/wp-admin/index.php?oauth2callback=1

## 2. 管理画面「Site Kit Developer Settings」で設定
「Google OAuth2 Client ID」「Google OAuth2 Client Secret」に登録手順1で用意した「OAuth 2.0 クライアント」のクライアントIDとクライアントシークレットを設定、保存する

## 3. 管理画面「Site Kit Dashborad」で設定
「SIGN IN WITH GOOGLE」ボタンからGooeleのログインページに遷移し、用意していたGoogleアカウントでログイン。
その時求められる認可は全て許可する。

## 4. Site Kitの認証ステップ「Verify URL」で失敗する
下記のエラーメッセージが表示されて失敗する
The necessary verification token could not be found on your site

この時、管理画面のURLに対して下記のようなリクエストが発生している。

```
"GET / HTTP/1.1" 200 3557 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
"GET /?cachebuster=2754430646 HTTP/1.1" 200 3557 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
```

## 4. 再び管理画面「Site Kit Developer Settings」で設定
「Google OAuth2 Client ID」「Google OAuth2 Client Secret」を空にする。
さらに、「Custom Site URL」に https://front.example.com を登録する。

## 5. 管理画面「Site Kit Dashborad」で設定
画面の案内に沿って登録していくと、前回失敗した「Verify URL」も成功する。（理由は不明）

この登録時に管理画面に対して下記のようなリクエストが発生している。（HTMLファイル名は変えています）

```
"GET /googleabcdefg12345.html HTTP/1.1" 200 64 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
"GET /googlezyxwvut98765.html HTTP/1.1" 404 13 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
"GET /googlezyxwvut98765.html HTTP/1.1" 404 13 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
"GET /googleabcdefg12345.html HTTP/1.1" 200 64 "-" "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)"
```

「/googleabcdefg12345.html」が200になっているが、こんなファイルはサーバー上に置いていない。
でも
https://wp.example.com/googleabcdefg12345.html
にアクセスすると、たしかにレスポンスがある。
Site Kitが良しなにしてくれていると予想。（これ以上は調査していない）

## 6. 管理画面「Site Kit Dashborad」で設定
登録手順5でSite KitとSearch Consoleが連携しているはずなので、後は通常の使い方と同様にアナリティクスなど連携したいツールを追加する
Association ; 1対1、1対多、多対多について

## Association
Rails には関連 (Association) という仕組みがある。関連付けを用いて二つのモデルをつなぐことで、コードをシンプル、かつ簡単に書くことができる。
関連付けの関係は大きく分けて以下の三種類に分類される。

* 1 対 1
* 1 対 多
* 多 対 多

### 1 対 1 (has_one, belongs_to)
例えば、Teacher, Class, Student, Subject のモデルで以下の図のような関係性があったとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070052/fda4c427-5edf-6c91-1233-bd196f7fcd53.png)

まずはTeacherとClassの関係性を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070052/485e581d-9385-565d-d503-30d8e00585d5.png)

ここで表されているのは、

* 原田先生 は 2-1 を
* 山川先生 は 2-2 を

担任しているということがわかります。
この場合、Teacherモデルのデータひとつに対し、Classモデルのデータがひとつだけ割り当てられているため、1対1の関係性となっているということになります。
この関係性をコードで表すと以下のようになります。

```
class Teacher < ApplicationRecord
	has_one :Class
end

class Class < ApplicationRecord
	belongs_to :Teacher
end
```

### 1 対 多 (has_many, belongs_to)
次に ClassとStudentの関係性を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070052/8ee5dcdc-0c07-2c51-ab67-cf715871c3e3.png)

ここで表されているのは

* 2-1 には 田中さんと矢島さん
* 2-2 には 中村さんと木下さん

が属しているということがわかります。
この場合、Classモデルのデータひとつに対し、Studentモデルのデータが複数割り当てられているため、1対多の関係性になっているということになります。
この関係性をコードで表すと以下のようになります。

```
class Class < ApplicationRecord
	has_many :Students
end

class Student < ApplicationRecord
	belongs_to :Class
end
```

### 多 対 多 (has_and_belongs_to_many)
最後に、StudentとSubjectの関係性を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070052/96b197ce-2368-a6fa-f04e-5890713deee1.png)

線が多いため、Studentモデルのデータごとに色分けしております。
ここで表されているのは

* 田中さんは 国語、英語、数学 を受講する
* 矢島さんは 国語、英語、数学 を受講する
* 中村さんは 国語、英語、数学 を受講する
* 木下さんは 国語、英語、数学 を受講する

ということがわかります。
ここで、線の色分けをSubjectモデルのデータごとに変えてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1070052/aab1c0a1-54c5-a020-4608-4f175faa9acd.png)

この場合、表されているのは

* 国語を受講するのは 田中さん、矢島さん、中村さん、木下さん
* 英語を受講するのは 田中さん、矢島さん、中村さん、木下さん
* 数学を受講するのは 田中さん、矢島さん、中村さん、木下さん

ということになります。
つまり、Studentモデルのデータひとつに対し、Subjectモデルのデータが複数割り当てられており、またSubjectモデルのデータひとつに対し、Studentモデルのデータが複数割り当てられています。そのため、この関係性は多対多ということになります。
この関係性をコードで表すと以下のようになります。

```
class Student < ApplicationRecord
	has_and_belongs_to_many :Subjects
end

class Subject < ApplicationRecord
	has_and_belongs_to_many :Students
end
```
マウスカーソルを合わせた時に、背景色を変えたい！

#はじめに
Webページでよく目にする、マウスカーソルを合わせた時に、少し色が変わることで、カーソルが合っていることを示す機能を実装しようと思いました。
しかし、私はCSSでどう色を指定すればいいのかわかりません。(`#e1f1e7`←こういうやつ。どこをどれくらいいじれば明るくなるとか、わからない。)そこで、VSCodeで使える、色の指定方法を閃きました。

##流れ
1. 元の背景色を決めて、CSSで指定しておく。
2. 同じクラス(ID)の:hoverセレクタを用意する。
3. 1をコピペする。
4. 色の部分にカーソルを合わせる。
5. 好きな色をクリックする。

##1. 2. 3.

```css
.class {
  background-color: red;
}
.class:hover {
  background-color: red;
}
```

##4.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/fa019754-6fb3-6af9-25ab-8ef1c9b47c0d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/3b4c9835-194a-90c9-67f8-40776f8bcaab.png)

白い枠の部分で、元の色との違いを確認することができます。

##補足
カーソルを合わせた時に、カーソルのポインターを変更すると、よりわかりやすいです。

```css
.class:hover{
  cursor: pointer;
}
気になった事を調べてまとめてみた[コンポーネント？、オブジェクト指向？]

今後、勉強していきたいと思っている単語の意味や理解を深める為に調べた記述を書いていきます。
まだjQueryとかJavaScripct止まりだけど、いつかはreact.jsとか使ってみたいと思う。



##コンポーネント （component）
コンポーネントとは、機械などの構成部分や組み合わせの単位を指す言葉で、IT用語としては何らかの機能を持ったプログラム部品のことをいう。 ... Javaなどのオブジェクト指向言語が普及したことにより、コンポーネントを組み合わせることでソフトウェア開発が進みやすくなっている。
　　

##オブジェクト指向言語
オブジェクト指向とは、プログラミング言語のうち、互いに関連するデータの集合とそれらに対する手続き群をひとまとめにした「オブジェクト」（object）をプログラムの基本的な構成単位として扱うことができるもの。

##Vue.jsのメリット
①SFC(Single File Component) HTML/JavaScript/CSSが区別して管理でき、Web制作上がりの僕のような人にはとっつきやすい。
②Vue CLIが便利 TypeSclipt、ESLint などの plugin の使用などをコマンドラインの指示に従って簡単に導入できる。
③HMR(Hot Module Replacement) ブラウザ画面の再描画(リロード)すること無しにコードの変更をブラウザに適用してくれるので、手間が減って開発が楽になる。
上記3つの点が、僕のような初学者でも簡単に感覚的にコードを書くことができ、かつ多くのことが容易に実現できる。

##React.jsのメリット
①主にクラスベースで実装するため、大規模開発に適している。
②typescriptとの組み合わせが良い
　　

##モジュール
あるまとまりを持った機能部品、または機能単位のこと。 
　ハードウェアとソフトウェアの両方で使われるが、いずれも "交換可能な" 構成単位と位置づけられる。 　つまり、モジュールはシステムの構成要素であり、機能の追加や変更が必要なときに、モジュール単位で結合、交換、削除などができる。
　プログラミングにおいては、モジュールに分割して開発を進め、それぞれのテストを終えてから結合し、システムを完成させる手法が一般的である。 接続部分でやり取りするデータを決めておけば、分担して効率よく開発作業を進めることができる。 その他にも、プログラム構造が分かりやすくなるので保守や再利用がしやすくなる利点が期待できる。
部品のこと、基本的に他のものと組み合わせて使う。
M5StackCore2でWAVもしくはMP3を再生する場合


ESP8266Audioを使ってM5StackでSDカードに入っているWAV(もしくはMP3)を再生させる方法以下のように行うことができます。

```
#include <M5Stack.h>
#include "AudioFileSourceSD.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"

AudioGeneratorWAV *wav;
AudioFileSourceSD *file;
AudioOutputI2S *out;

void setup()
{
  M5.begin();

  file = new AudioFileSourceSD("/sx.wav");      
  wav = new AudioGeneratorWAV();   
  out->SetOutputModeMono(true);
  out->SetGain(1.0);
  wav->begin(file, out);
}

void loop()
{
  if(wav->isRunning()) {
    if (!wav->loop()) wav->stop();
  }
}
```
参考記事
https://qiita.com/ktansai/items/f0096495e2ca7fa38eb7

ですが、Core2の場合にもろもろ仕様が変わっていますので以下のようにAudioOutputI2Sの部分を変更する必要があります。

```
      out = new AudioOutputI2S(0, 1);
      out->SetOutputModeMono(true);
      out->SetGain(1.0);
```
↓

```
      out = new AudioOutputI2S(0, 0);
      out->SetPinout(12, 0, 2);
      out->SetOutputModeMono(true);
      out->SetGain(1.0);
```
Swiftでtableviewを使う(基礎)

#はじめに
Swiftでtableviewを使った開発をします。
簡単な使い方とそれぞれの特有の関数の説明をします。

#TableViewとは
配列などで格納されたデータをリストのようにして出力したい時に使います。
チャット機能や商品の一覧など応用パターンが多いのが特徴になります。
今回は配列に入っているいくつかの要素をリストにして出力してみます。

#特有のメソッド
###numberOfRowsInSection
セルの数を決めるメソッド

```
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return セルの数
}
```
###numberOfSections
セルのセクション数を決めるメソッド

```
func numberOfSections(in tableView: UITableView) -> Int {
        return セクションの数
}
```
###cellForRowAt
セルを構築する際に使うメソッド

```
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return cell
}
```
###heightForRowAt
セルの高さを指定するメソッド

```
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return view.frame.size.height/6
}
```
###didSelectRowAt
セルがタップされた時に呼び出されるメソッド

```
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            
}
```

#簡単な使い方
①プロジェクトを立ち上げる

②main.storyboardでTableViewを配置する
![スクリーンショット 2021-01-09 14.31.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/970027/7deae5d3-38ba-95b7-2fc0-aef2bb272547.png)
![スクリーンショット 2021-01-09 14.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/970027/00416bee-63e6-b540-2b15-3004e4c7ef28.png)
上の画像のようにTableViewのパーツを端に合わせる(AutoLayout使っても可)


③セルとなるxibファイルを作成する
TableView → CocoaTouchClass → 画像のようにSubbClass ofを変更
今回はTableViewCellという名前のファイルを作成しています。
![スクリーンショット 2021-02-28 14.52.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/970027/59881e0f-e334-4fa4-f691-5132f86571ae.png)

④xibファイルを変更する
1.TableViewCell.xibでLabelを配置する。
2.配置したLabelをTableView.swiftに紐付ける。
3.画像右上のidentifierにcellと入力。
![スクリーンショット 2021-02-28 17.11.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/970027/96de4d2d-67c0-677b-99f3-8bb5803cc864.png)

⑤ViewController.swiftを変更する

```swift
import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let array = ["グレープ", "レモン", "アップル", "メロン"] //表示される配列を準備
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        //使うセルを指定する
        tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "cell")　　
        
    }
    
    //TableViewに貼り付ける要素を指定する
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return array.count
        
    }

    //cellを設定する
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

        cell.label.text = array[indexPath.row]
        
        return cell
        
    }

}
```

#最後に
簡単あ使い方のみの説明となりました。
チャット機能のものからもっと高度な使い方までできるので、自分で作りたいものをでリストっぽいものが欲しいなと思ったら使ってみてください。

#参照
https://www.udemy.com/course/ios14-iphone-ios-boot-camp/
[PHP]ディレクトリごとファイルをコピーする

PHPにはファイルのコピーをするためのcopy関数がありますが、ディレクトリとその中に含まれるファイルを丸ごとコピーすることはできません。
そこで、PHPでディレクトリごとファイルをコピーする方法をご紹介します。

```php
/**
 * ディレクトリをコピーする
 *
 * @param  string $dir     コピー元ディレクトリ
 * @param  string $new_dir コピー先ディレクトリ
 * @return void
 */
function copy_dir($dir, $new_dir)
{
    $dir     = rtrim($dir, '/').'/';
    $new_dir = rtrim($new_dir, '/').'/';

    // コピー元ディレクトリが存在すればコピーを行う
    if (is_dir($dir)) {
        // コピー先ディレクトリが存在しなければ作成する
        if (!is_dir($new_dir)) {
            mkdir($new_dir, DIR_WRITE_MODE);
            chmod($new_dir, DIR_WRITE_MODE);
        }

        // ディレクトリを開く
        if ($handle = opendir($dir)) {
            // ディレクトリ内のファイルを取得する
            while (false !== ($file = readdir($handle))) {
                if ($file === '.' || $file === '..') {
                    continue;
                }
                // 下の階層にディレクトリが存在する場合は再帰処理を行う
                if (is_dir($dir.$file)) {
                    copy_dir($dir.$file, $new_dir.$file);
                } else {
                    copy($dir.$file, $new_dir.$file);
                }
            }
            closedir($handle);
        }
    }
}
```
こちらの方法で、対象となるディレクトリを丸ごとコピーできます。
さらに下の階層にディレクトリが存在する場合でも、コピーすることが可能です。
MPCNC作成のためのお話（その４）-電子機器と可動パーツの調達-

##電子機器と可動パーツの調達
コントローラーやフレームに使うスチールパイプ、タイミングベルトやステッピングモーターが必要になります。
ちなみにPCは必須です。多少古くてもWindowsPCで十分ですので、できれば専用に用意しておきたいです。
PCとCNCのコントローラーをUSBで接続することになります。
以下のパーツは必須ですので必ず揃える必要があります。

|パーツ名 |数量|備考|リンク|
|:-:|:-:|:-:|:-:|
|MKS Gen V1.4|1|オフィシャルサイトではMini-RAMBoになっていますがMini-RAMBoだとDualエンドストップというX,Y軸を２つのモーターで動かす形にできないのでモータードライバを５つ載せれるものにしてください。RampsとArduinoでも大丈夫ですがファームウェアを修正する必要があります|[Amazon](https://www.amazon.co.jp/gp/product/B07TD39916/)|
|スイッチング電源（12V 5A以上）|1|あまり安いものだと不安ですがだいたい同じです。|[Amazon](https://www.amazon.co.jp/gp/product/B07KJC5M6N/)|
|GT2 タイミングベルト|4m|鉄線入りはダメです。<br>必要な長さはオフィシャルサイトか前回の「[MPCNCサイズ計算機](https://qiita.com/nyos/items/f4c3d646480c9f0d0b5c#mpcnc%E3%82%B5%E3%82%A4%E3%82%BA%E8%A8%88%E7%AE%97%E6%A9%9F)」で計算してください。|[Amazon](https://www.amazon.co.jp/gp/product/B07SH7ZYTV/)|
|GT2 20歯タイミングプーリー|4|オフィシャルでは16歯になってもますが僕の調節したファームウェアが、20歯でやってるのでこちらに合わせました。完成してから指定値と移動値の比で調整してやれば良いので正直どうでも良いです。AmazonリンクはGT2タイミングベルトとセットのものでベルトのリンクと同じです。|	[Amazon](https://www.amazon.co.jp/gp/product/B07SH7ZYTV/)|
|608 2-RS ベアリング |53 |608-2RZでもOK|[Amazon](https://www.amazon.co.jp/gp/product/B08V8NNYLY/)<br>[Misumi](https://jp.misumi-ec.com/vona2/detail/221005190785/)<br>[Monotaro](https://www.monotaro.com/p/3509/6056/)|
|導管もしくはステンレススチールパイプ|6m以上|僕は2mのステンレスパイプを8本購入し2本余りました。<br>「[MPCNCサイズ計算機](https://qiita.com/nyos/items/f4c3d646480c9f0d0b5c#mpcnc%E3%82%B5%E3%82%A4%E3%82%BA%E8%A8%88%E7%AE%97%E6%A9%9F)」で計算してください|[Monotaro](https://www.monotaro.com/p/3353/2441/)|
|Nema17ステッピングモーター|5|５個セットの安いやつでOKです。Amazonで買うときは納期も気にしましょう。輸入まで考えるならAliexpressやbanggood、Wish等で購入しても同じか安くて同じ納入時期な場合があります。|[Amazon](https://www.amazon.co.jp/gp/product/B08WLGYTT4/)|
|DRV8825モータードライバ|5|他のでも良いですが、ファームウェアの設定を変更する必要があります|[Amazon](https://www.amazon.co.jp/gp/product/B07438MR66/)|
|配線ハーネス|1|4芯以上の通信ケーブルであればOKですが、モーター動力が流れるのでそこそこ芯が太めなものが良いです<br>僕はMonotaroでリンク先のものを購入しましたが、Amazonのリンクの物(最大電圧:300V、最大電流:3.2A 20-80度)で十分だったかもしれません|[Amazon](https://www.amazon.co.jp/gp/product/B07H4KTSRK/)<br>[Monotaro](https://www.monotaro.com/p/5306/1375/)|
|ナイロン結束バンド3.6mm 長さ142mm程度|20以上|タイミングベルトのベルトテンショナーにも使用するので、ちょっと細めが良いです。MPCNC用のベルトテンショナー形状が[thingiverse](https://www.thingiverse.com/thing:1833934)にあるので、こちらを利用するならどんなサイズの結束バンドでもOKです|[Amazon](https://www.amazon.co.jp/gp/product/B00Q4OWTFA)<br>または近所のホームセンター|

今回はAmazonのリンク多めです。
必ずしもリンク先での購入をおすすめするわけではありません。
どのような物が必要なのかと、名称の確認、価格の参考に使用して、できるだけ自分で良さそうと思ったものを購入してください。
ある程度は備考で説明していますが、わからなければご質問ください。

次回は組み立てに入っていきます
【KPI】WITH句【oracle】

WITH句は、特定のSELECT文を、SQL内で何度も使用したい場合に使う。

テーブル「TBL_1」と「TBL_2」がある場合。

・TBL_1

| キー | 値段 |
|----:|----:|
|1|10|
|2|20|
|3|30|
|4|40|

・TBL_2

| キー | 値段 |
|----:|----:|
|1|100|
|2|200|
|3|300|

下記のようなSELECT文を何度も参照する場合

```oracle
SELECT TBL_1.キー, TBL_1.値段, TBL_2.値段 AS 値段2
FROM TBL_1, TBL_2
WHERE TBL_1.キー = TBL_2.キー
```

ちなみに上記結果は下記のようなものとなる。

| キー | 値段 | 値段2 |
|----:|----:|----:|
|1|10|100|
|2|20|200|
|3|30|300|

実際にSQLに盛り込むとこうなる。

```oracle
SELECT B.キー, A.値段, A.値段2, B.値段 AS 値段3 
FROM
(
    SELECT TBL_1.キー, TBL_1.値段, TBL_2.値段 AS 値段2
    FROM TBL_1, TBL_2
    WHERE TBL_1.キー = TBL_2.キー
) A
, (
    SELECT TBL_1.キー, NVL(TBL_3.値段, 0), NVL(TBL_3.値段2, 0) + NVL(TBL_1.値段, 0) AS 値段
    FROM 
    (
        SELECT TBL_1.キー, TBL_1.値段, TBL_2.値段 AS 値段2
        FROM TBL_1, TBL_2
        WHERE TBL_1.キー = TBL_2.キー
    ) TBL_3
    , TBL_1
    WHERE TBL_1.キー = TBL_3.キー(+)
) B
WHERE A.キー(+) = B.キー
```

結果はこう。

| キー | 値段 | 値段2 | 値段3 |
|----:|----:|----:|----:|
|1|10|100|120|
|2|20|200|240|
|3|30|300|360|
|4|||40|

上記のSQLも、WITH句を使えばこうなる。

```oracle
WITH TBL_3 AS
(
    SELECT TBL_1.キー, TBL_1.値段, TBL_2.値段 AS 値段2
    FROM TBL_1, TBL_2
    WHERE TBL_1.キー = TBL_2.キー
)
SELECT B.キー, A.値段, A.値段2, B.値段 AS 値段3 
FROM
  TBL_3 A
, (
    SELECT TBL_1.キー, NVL(TBL_3.値段, 0), NVL(TBL_3.値段2, 0) + NVL(TBL_1.値段, 0) AS 値段
    FROM 
      TBL_3
    , TBL_1
    WHERE TBL_1.キー = TBL_3.キー(+)
) B
WHERE A.キー(+) = B.キー
```

結果は上記と同じ。

---
※実行計画に注意。

下記は複数のWITH句を宣言する場合

```oracle
WITH TBL_3 AS
(
    SELECT TBL_1.キー, TBL_1.値段, TBL_2.値段 AS 値段2
    FROM TBL_1, TBL_2
    WHERE TBL_1.キー = TBL_2.キー
)
, TBL_4 AS
(
    SELECT TBL_1.キー, NVL(TBL_1.値段, 0) * (NVL(TBL_3.値段, 0) + NVL(TBL_3.値段2, 0)) AS 値段
    FROM TBL_1, TBL_3
    WHERE TBL_1.キー = TBL_3.キー
)
```

上記のように複数のWITH句、更にWITH句の中でWITH句を使用すると、実行順がおかしくなる場合がある。
この際、結果が乱れる、乱れた。
可能なら「/*+ MATERIALIZE */」などをWITH句に挿入して、結果が乱れないようにすること。
Effective C++

## 27項 キャストは最小限にしよう
###4つのキャスト
####const_cast<T>
constを取り除く
####dynamic_cast<T>
安全なダウンキャスト
※アップキャスト：基底（親）クラス型の変数に派生（子）クラスのインスタンスを代入する
※ダウンキャスト：派生（子）クラス型の変数に基底（親）クラスのインスタンスを代入する
####reinterpret_cat<T>
低レベルなキャスト
個人的には、その他の3つでできない時のみ
####static_cast<T>
暗黙の型変換を強制する
###Resharperが教えてくれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696559/0fca2870-2d90-6d18-57b2-0c6a0a1020ba.png)
###Base* pb = &d
型変換によってアドレスが違ってしまうこともある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696559/949d21d5-9bce-2af4-9a00-c28d344847ea.png)

C++ objectのメモリ配置
Inside the C++ Object Model　Figure 4.2
https://www.semanticscholar.org/paper/Inside-the-C%2B%2B-Object-Model-Lippman/160489e8b12cd9a44cbff0cd85fb6aa05437d1ac/figure/18
アドレスが違うのでキャストするとダメになる

####菱形継承はビルドエラー
```a.cpp
struct B { virtual ~B() = default; };
struct B1 : B { virtual ~B1() = default; };
struct B2 : B{ virtual ~B2() = default; };
struct D : B1, B2 {};

int main()
{
	D* d = new D;
	B1* b1 = d;
	B2* b2 = d;
	B* b = d;
	
	return 0;
}

```
エラー	C2594	'初期化中': 'D *' から 'B *' への変換はあいまいです。

###dynamic_cast
DSP環境(CCS)ではoptionでデフォルトOFFになっている

##28項 オブジェクト内部のデータへの「ハンドル」を戻さないようにしよう
カプセル化が弱くなるからやらないようにしようという話

Resharper指摘なし
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696559/8e4a40f7-f2ce-53a2-2b10-56622517608c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696559/94e6fc59-2f98-2212-5156-91256375f5a8.png)

##29項 コードを例外安全なものにしよう
コードは例外安全か、例外安全でないかの2つの状態しかない
###例外安全
- リソース漏れを起こさない
- データ構造が無効な状態にならない

リソース漏れはリソース管理オブジェクトで対処
データ構造は次のどれかを保証する
- 基本保証(basic guarantee) 例外が投げられても、データ構造が有効に保たれる
- 強い保証(strong guarantee) 例外が投げられても、プログラムが呼び出し前のものに戻される
- 例外を投げない保証(nothrow guarantee)　例外を投げない

基本は例外を使わないほうが良い

###throw, noexcept
https://docs.microsoft.com/ja-jp/cpp/cpp/exception-specifications-throw-cpp?view=msvc-160
c++14では、noexceptを宣言した関数から例外が投げられたら、std::terminateが呼ばれる
###強い保証を実現する手法としてCopy and Swapがある
https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E3%82%B3%E3%83%94%E3%83%BC%E3%81%97%E3%81%A6_swap(Copy-and-swap)
https://www.geeksforgeeks.org/copy-swap-idiom-c/
C - Modulo Summation, D - Flipping Signs

##[C - Modulo Summation](https://atcoder.jp/contests/abc103/tasks/abc103_c)

O(N)
最小公倍数を計算。
その後、最小公倍数-1の値で余りを取得し加算していきます。

```python:python 
import math
import heapq
import itertools
from functools import reduce
 
def my_lcm_base(x, y):
    return (x * y) // math.gcd(x, y)
 
# main
def main():
    N = int(input())
    A = list(map(int, input().split()))
 
    g = reduce(my_lcm_base, A, 1)
    g = g - 1
    res=0
    for i in range(0, len(A)):
        res += g % A[i]
    
    print(res)
 
# エントリポイント
if __name__ == '__main__':
    main()
```

##[D - Flipping Signs](https://atcoder.jp/contests/abc125/tasks/abc125_d)

O(N)
i, i+1に-1をかけていくのを繰り返す。
最終的に奇数なら−符号が一つ存在、偶数なら全て＋符号になります。

偶数なら全てを正整数に変更して全ての整数の合計を出力。

奇数なら全てを正整数に変更して最小値を取得。
全ての整数-(最小値*2)を計算。
正整数にした際の最小値を負数に変更して、全ての整数の合計を出力。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
def my_lcm_base(x, y):
    return (x * y) // math.gcd(x, y)
 
# main
def main():
    N = int(input())
    A = list(map(int, input().split()))
 
    cnt=0
    for i in range(0, len(A)):
        if A[i]<0:
            cnt+=1
 
    min_v=10000000000
    for i in range(0, len(A)):
        if A[i]<0:
            A[i] = A[i] * -1
        min_v = min(min_v, A[i])
    
    if cnt%2==0:
        print(sum(A))
    else:
        print(sum(A)-(min_v*2))
 
# エントリポイント
if __name__ == '__main__':
    main()
```
railsのgem「pagy」を使ってページネーション

#私がページネーションにpagyを選んだ理由
下記のリンクにて、メモリの負荷がwill-paginateやkaminariより軽いらしいとのことです。

 https://techracho.bpsinc.jp/hachi8833/2018_06_05/57481

記事の中に以下のグラフを見つけました。ページ数と使用メモリ数の関係をグラフ化したものですが、Pagyが圧倒的です。こりゃPagyを選びますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933066/f0cdaedb-4872-1087-6611-6eb512eec6fa.png)

#railsのgem「pagy」を使ってページネーション
以下の記事を参考にしたら初学者の私でも１０分でページネーションできました。


２番目の記事が私的におすすめです。githubにもソースコードが上がっているので。

https://qiita.com/junara/items/eb85559547f87c8cb6b3

https://qiita.com/white0221/items/d5a0386882943131df77


##注意、bootstrapでエラーでます！
ちなみにですが、bootstrapを導入する際は以上の記事を参考にするとエラーがでました。
1年前の記事なので、pagyのbootstrapのソースコードが少し変わった？？ようです。

私の場合ユーザー一覧のページネートを作るべく、記事にしたがって下記のコードを書きました。

```
 <% provide(:title, 'All users') %>
<h1>ユーザー一覧</h1>

<ul class="users">
  <% @users.each do |user| %>
    <li>
      <%= link_to user.name, user %>
    </li>
  <% end %>
  <div class="d-flex justify-content-left mb-2">
    <%== pagy_nav_bootstrap(@pagy) %>
  </div>
```
しかしながら![スクリーンショット 2021-02-28 22.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933066/9d10f9ce-4d90-42f8-4c1a-647ce4835863.png)

NoMethodErrorぁぁぁぁぁエラー発動ぅぅぅぅぅ！！！

pagy のbootstrapのオフィシャルっぽいところの記事を参照し

https://ddnexus.github.io/pagy/extras/bootstrap.html

```
　<%== pagy_nav_bootstrap(@pagy) %>
```
のところを

```
　<%== pagy_bootstrap_nav(@pagy) %>
```
に変えてOK!

![スクリーンショット 2021-02-28 22.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933066/492fc2ab-0c54-5582-0d34-f7d59155d7a2.png)


いい感じにページネーションできました。
グリッドレイアウトで余白、隙間を設定する方法

# はじめに

gridレイアウトでは個別の位置指定をしない限り、grid枠に従ってすきまなく順番に配置されます。
今回はgridレイアウトに余白を設定する方法をまとめてみました。

gridの基本はこちらにまとめてあるので、よかったら参考にしてください。
[gridの使い方](https://qiita.com/startyuki/items/9437333012aff9c20cac)

# gridレイアウトに余白を付ける
余白の付け方は簡単で、
横方向の余白はcolumn-gapプロパティ、縦方向にはrow-gapプロパティを使うだけです。

```css
#{
 display: grid;
 grid-template-columns: repeat(3, 1fr);
 column-gap: 10px;
 row-gap: 30px;
}
```

これでgridのそれぞれの隙間に余白を付けることができます。

また、gap:10px;のようにまとめて付けることもできます。

余白を細かく指定するときは下記の２つを使用します。

# justify-content
justify-contentは、コンテナ内におけるグリッドの横方向（インライン軸）の位置を指定するプロパティです。

使える値は

start　　　　　　　左寄せ
center　　　　　　中央寄せ
end　　　　　　　右寄せ
stretch　　　　　　軸の領域いっぱいにグリッドを広げる
space-between　　均等配置 / 左右の余白無し
space-around　　　均等配置 / 左右の余白ありはアイテム間の半分
space-evenly　　　均等配置 / 左右の余白はアイテム間と同様

などがあります。

# align-content
align-contentは、コンテナ内におけるグリッドの縦方向（ブロック軸）の位置を指定するプロパティです。

使える値は

start　　　　　　　上寄せ
center　　　　　　中央寄せ
end　　　　　　　下寄せ
stretch　　　　　　軸の領域いっぱいにグリッドを広げる
space-between	　　均等配置 / 上下の余白無し
space-around　　　均等配置 / 上下の余白ありはアイテム間の半分
space-evenly　　　均等配置 / 上下の余白はアイテム間と同様

などがあります。

# おわり
gridはflexboxに比べてシンプルに作成できるのでぜひ使ってみてください。
[AtCoder]AtCoder Beginner Contest 193

# はじめに
* AtCoder Beginner Contestの過去問の解法及び提出したソースコードをまとめています。
* 基本的に自分が振り返ることを目的としておりますが、誤りや気になった点、その他質問等もお待ちしておりますので遠慮なくお願いします。

# コンテストページ
https://atcoder.jp/contests/abc193

# A問題
問題文通りなので割愛。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    double a,b;
    cin >> a >> b;
    cout << setprecision(8) << (1-b/a)*100 << endl;
    return 0;
}
```
# B問題
各店舗についてA < Xなら買えるので、買える店舗の中で一番安い店を求めればよいです、

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin >> n;

    int ans = INT32_MAX;
    for(int i = 0; i < n; i++){
        int a,p,x;
        cin >> a >> p >> x;
        if(a < x){
            ans = min(ans, p);
        }
    }

    if(ans == INT32_MAX){
        cout << -1 << endl;
    }
    else{
        cout << ans << endl;
    }

    return 0;
}
```
# C問題
aのb乗で表せるものの個数をカウントし、Nから引いてあげます。
計算を考慮しaは最大でもNの二乗根を超えることがないことから、aをNの二乗根まで全探索します。
カウントの重複を避けるためsetまたはunordered_setを使います。

```c++
#include <bits/stdc++.h>
using namespace std;
#define u64 uint64_t

int main()
{
    u64 n;
    cin >> n;
    set<u64> s;

    for(u64 i = 2; i*i <= n; i++){
        u64 x = i*i;
        while(x <= n){
            s.insert(x);
            x *= i;
        }
    }

    cout << n-s.size() << endl;
    return 0;
}
```
# D問題
山札を構造体で定義し、各人がカードが4枚ずつ引いた状態にします。
最後の1枚の配られ方9*9通りのうち、高橋くんの勝つパターンのみの確率を足していってあげればよいです。
山札からカードを引く関数でカードの減算と戻り値で引く確率を返してあげるとスッキリします。

```c++
#include <bits/stdc++.h>
using namespace std;

struct Deck{
    Deck(int k) : sum(k*9), num(10, k){};
    int sum;
    vector<int> num;
    double draw(int x){
        if(num[x]==0) return 0;
        double ret = (double)num[x]/sum;
        num[x]--;sum--;
        return ret;
    }
};

int main()
{
    int k;
    cin >> k;
    string s,t;
    cin >> s >> t;
    Deck D(k);
    for(int i = 0; i < 4; i++) D.draw(s[i]-'0');
    for(int i = 0; i < 4; i++) D.draw(t[i]-'0');

    double ans = 0;
    for(int i = 1; i < 10; i++){
        s[4] = i+'0';
        for(int j = 1; j < 10; j++){
            t[4] = j+'0';
            int ss = 0;
            int ts = 0;
            for(int k = 1; k < 10; k++){
                ss += k * pow(10, count(s.begin(), s.end(), '0' + k));
                ts += k * pow(10, count(t.begin(), t.end(), '0' + k));
            }
            if(ss > ts){
                Deck d = D;
                ans += d.draw(i) * d.draw(j);
            }
        }
    }

    cout << setprecision(16) << ans << endl;
    return 0;
}
```
# E問題(未AC)
まだ解いておりません。

# F問題(未AC)
まだ解いておりません。
[Ansible]EC2のメタデータを変数に格納する

### pre_tasksでec2のメタデータを収集する。

```yml
pre_tasks:
    - name: gather ec2_metadata
      amazon.aws.ec2_metadata_facts:
```

[収集できるメタデータ(公式サイト)](https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_metadata_facts_module.html)

### 変数に格納
例) "public_ip"にEC2のパブリックIPを格納したい場合、下記のように変数を設定しておく

```
public_ip: "{{ ansible_ec2_public_ipv4 }}"
```

### 使い所
AWXのワークフロー使用時、CloudFormationで新規構築したEC2のIPを後続タスクで使用する変数に格納したい時などに使えます。
【Ruby on Rails】before_actionを使って全てのアクションで同じ処理を行う 

# 同じ処理をbefore_actionで定義する。

あるコントローラー内の全てのアクションで１つの処理を使い回したい時。

```.rb
class Api::V1::Admin::CompanyAdminsController < ApplicationController

  def index
    company_admins = CompanyAdmin.where(company_id: params[:company_id])
    json_response(200, CompanyAdminIndexSerializer.new(company_admins).to_h)
  end

  def show 
    company_admin = CompanyAdmin.find params[:id]
    json_response(:ok, serialize_data(CompanyAdminIndexSerializer, company_admin))
  end

  def destroy
    company_admin = CompanyAdmin.find params[:id]
    company_admin.destroy!
    json_response(204)
  end
  
end
```

このコントローラー内を見てみると、show・destroyアクションで同じ処理が書かれている。

```
company_admin = CompanyAdmin.find params[:id]
```

これをまとめるために、before_actionと記述する。
これによって、全てのアクションで最初に行いたい処理を実行できる。

```ruby
  def load_company_admin
    @company_admin = CompanyAdmin.find params[:id]
  end
end
```
例えば、上のようなメソッドをコントローラー内に記述する。
そして、コントローラー内の一番上にbefore_actionの記述を加える。

## 最終的なコード

```ruby
class Api::V1::Admin::CompanyAdminsController < ApplicationController
  before_action :load_company_admin, only: [:show, :destroy] 
  ##onlyオプションを付け加えることで、showとdestroyアクションのときと指定ができる。

  def index
    company_admins = CompanyAdmin.where(company_id: params[:company_id])
    json_response(200, CompanyAdminIndexSerializer.new(company_admins).to_h)
  end

  def show 
    json_response(:ok, serialize_data(CompanyAdminIndexSerializer, @company_admin))
  end

  def destroy
    @company_admin.destroy!
    json_response(204)
  end

  private
  def load_company_admin　##処理の名前を定義する。
    @company_admin = CompanyAdmin.find params[:id]
  end
  ##ここで同じ処理を記述する。
end
```

少しだけ、このファイルの記述がスッキリした気がする。
何度も同じ記述を書くのはエンジニアとして、あまり優秀ではない気がしているので、できるだけ同じ処理はまとめていきましょう。
Laravel ファイル名が日本語の添付ファイルが送れなかった

# はじめに
あるプロジェクトでファイル名が日本語のPDFをメールで送信する必要がありました。
公式や記事を見ながら実装したところ、何故か日本語部分だけが送信できないという事象が発生しました。

# 前提
```
Centos7系
PHP7系
```

LaravelのMailファサード・Mailableクラスを用いて実装しています。

```php:HogeController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Mail\SampleMailable;
use Mail;

public function sendMail()
{
    Mail::to('hogehoge@hogehoge')->send(new SampleMailable());
}
```

```php:SampleMailable.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class SampleMailable extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */

    public function build()
    {
        return $this->view('emails.test')
                    ->from('XXX@XXXX','Test')
                    ->subject('テストメールです。')
                    ->attach(storage_path('app/pdf/テストfile.pdf'));
    }
}
```

# 事象
送られてきたメールを確認すると、添付されているファイル名が以下のようになっていました。

```
結果
file.pdf

期待値
テストfile.pdf
```

# 調査
以下の順序で調査を行いました。

1. config.phpのlocaleがjaになっているか
2. [参考記事](https://www.messiahworks.com/archives/12345)のようにファイル名を参照する際にbasename()を使用しているかどうか
3. サーバーのlocaleが正しいか
4. php.iniの設定が正しいかどうか


# 調査結果

### php.configの値

```php:config.php
    'locale' => 'ja',
```

### basename()

今回、basenameは未使用。
laravelのソースも確認しましたが、使用されていませんでした。


### サーバーのlocale
正しい値のようでした。

```
LANG=ja_JP.utf8
LC_CTYPE="ja_JP.utf8"
LC_NUMERIC="ja_JP.utf8"
LC_TIME="ja_JP.utf8"
LC_COLLATE="ja_JP.utf8"
LC_MONETARY="ja_JP.utf8"
LC_MESSAGES="ja_JP.utf8"
LC_PAPER="ja_JP.utf8"
LC_NAME="ja_JP.utf8"
LC_ADDRESS="ja_JP.utf8"
LC_TELEPHONE="ja_JP.utf8"
LC_MEASUREMENT="ja_JP.utf8"
LC_IDENTIFICATION="ja_JP.utf8"
LC_ALL=
```

### php.iniの設定値
php.iniでlocale設定がされていなかったです。

# 原因
日本語を扱えるようにするにはphp.ini内で設定が必要ですが、デフォルト値のまま変更がされていませんでした。

# 対処法
### 効果がなかった対処法
https://readouble.com/laravel/6.x/ja/mail.html

こちらに記載されていたMailableのローカライズを参考にしましたが、期待通りに反映されませんでした。

```HogeController.php

public function sendMail()
{
    Mail::to('hogehoge@hogehoge')->locale('ja')->send(new SampleMailable());
}
```

### 今回の対処法
大人の事情でサーバー上にあるphp.iniを編集することは叶いませんでしたので、以下の内容で対応しました。

```php:AppServiceProvoder.php

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        setlocale(LC_ALL, 'ja_JP.UTF-8');
    }
}
```

これでLaravel上の処理は全て日本語対応されるはずです。
ちなみに、LC_ALLは他のLC関連の環境変数よりも優先される環境変数です。

## 別の対処法
php.iniの設定を変更したほうが良いと思います。

```php.ini
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = Off
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
```

これでもうまくいくと思います。（未検証なので、ご存知の方がいらっしゃいましたら教えていただけると幸いです！）
シーダー実行に失敗したためSQLSTATE[42S22]:のエラーが発生

##環境
Laravel6(PHP7.3以上)
MySQL8.0
Laradock(Docker)
Vscode

##エラー発生
seederでテストデータを挿入する際に、下記のエラーが出ました。

```
SQLSTATE[42S22]:
```

```
PDOException::("SQLSTATE[42S22]: Column not found: 1054 Unknown column 'prduct_name' in 'field list'")
```


##エラーの内容
「エラー文の表示からわかるように、フィールド（テーブル）に'prduct_name'というカラムがないですよ。」
と優しく教えてくれています。

テーブルにエラー文で表示されたカラムがあるか確認し、Insert文でそのカラムが正しく書けているかを確認してください。

##解決方法
自分はInsert文で指定したカラムのスペルがテーブルにあるカラムと違っていたためSQLSTATE[42S22]:が発生しました。
`git pull` した際に"reference broken"というエラーが出たときの対処法

## 発生した事象

コードを`git pull`しようとしたところ、

```bash
error: cannot lock ref 'refs/remotes/main': unable to resolve reference 'refs/remotes/main': reference broken
```

という旨のエラーが出て失敗するようになってしまいました。

当該ファイル（`.git/refs/remotes/main`）を覗いてみたところ、40文字ほどのNULL文字が羅列されているだけの内容でした。

発生した環境はWindows 10 (64bit)およびgit version 2.30.1.windows.1です。

## 解決法

Googleで検索を掛けたところ、[こちら](https://stackoverflow.com/questions/2998832/git-pull-fails-unable-to-resolve-reference-unable-to-update-local-ref/50467268#50467268)に

>On my system (Windows 7 64-bit), when a BSOD happens, some of the stored reference files (most likely currently opened/being written into when BSOD happened) are overwritten with NULL characters (ASCII 0).

>As others mentioned, to fix it, it's enough to just delete those invalid reference files and re-fetch or re-pull the repository.

と、自分と同様の事象と解決策の報告がありました。

この報告に従い、当該ファイルを削除して再度 `git pull`したところ、無事にpullすることができました。

## 原因

詳細な発生原因は現状では不明ですが、上記の報告でもブルースクリーンが出た後に発生したという記述があり、自分もPCがフリーズして電源を落とした後に発生しました。
Gitが何らかの作業を行っている最中にシステムがクラッシュしたことが原因の可能性が高そうです。

## 参考資料

- [git pull fails "unable to resolve reference" "unable to update local ref" - Stack Overflow](https://stackoverflow.com/questions/2998832/git-pull-fails-unable-to-resolve-reference-unable-to-update-local-ref/)
【学習メモ】AWS　DynamoDB

#DynamoDbとは
Amazonが提供するNoSQLデータベースサービス。
特徴：信頼性が高い、スケーラビリテ、低レイテンシ

#DynamoDbの基本概念
##DynamoDbの構成
構想部分：テーブル、アイテム、属性。
DynamoDbはテーブル単位から設定する。
テーブル：データのコレクションのこと。
アイテム：各テーブルの中にアイテムを作ってデータを作成する。
属性：各アイテムは1つ以上の属性で構成される。
![dynamoDBのテーブル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/3d36196e-4c9f-ba03-af84-2d04727cd576.png)

##DynamoDbのプライマリーキー
テーブルを作成するとき、テーブル名を指定する以外、プライマリーキーも指定しないといけいない。
プライマリーキーはアイテムを認識するものなので、異なるアイテムは同じプライマリーキーを使っては行けない。

<b>プライマリーキーは2つある。
・パーティションキー（Partition Key)
・パーティションキー & ソートキー　（Partition Key＋Sort Key）⇨複合キーも呼ばれる。
　※第一属性はパーティションキー、第二属性はソートキー。パーティションキーはストレージの場所を決まったので、ソートキーの重複は許さない。
</b>

##DynamoDb　Secondary Index
プライマリーキー以外、セカンダリーインデックスを使って、データの検索も可能。
一つのテーブルは一つor複数のセカンダリーインデックスを作れる。

<b>DynamoDb　Secondary Index
・Global secondary index（GSI）
・Local secondary index（LSI)
</b>

★GSI
テーブルのパーティションキー、ソートキーと異なるインデックス。

★LSI
テーブルのパーティションキーは一緒で、ソートキーは異なるインデックス。

一つのテーブルは最大五つのGSI、五つのLSIを設定できる。

#DynamoDB APIs
®︎Reference:https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.API.html

![dynamo table APIs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/d4a73a7c-358d-15a3-fb43-9ad6114f65e1.png)
![dynamo control plane API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/82eb91d8-14a8-8c50-c5ab-6670b7d0f0b7.png)

#DynamoDB Streams
DynamoDB テーブルに保存された項目の追加・変更・削除の発生時の履歴をキャプチャできる機能。
※過去24時間以内のデータ変更の履歴を保存し、24時間を経過すると消去される。


#DynamoDbの使いところ
IoT：
・デバイスデータの保存。
・DynamoDbをAmazon　Redshiftにデータウェアハウスに接続し、BI分析を実施。

ゲーム：
・ゲームの行動記録。

Advertisement Serving
MacでMySQL, PostgreSQLをインストールしてセットアップする方法

# (1)MySQLについて

## MySQLをインストール
`brew install mysql`
brewが動かない場合はググってインストールしてみてください。

`mysql -u root -p`
でMySQLのrootのパスワードを設定し、MySQLにログインできる。

`データベースの作成`
mysql> create database db #データベースの作成
MySQLにログインした状態で上記コマンドを実行する。この場合はdbという名前のデータベースを作成できる。dbを作成したいデータベース名に変更して実行する。

`データベースの削除`
mysql> drop database db
細かい部分は作成のときと同様

# (2)PostgreSQLについて
## PostgreSQLをインストール
`brew install postgresql`

##PostgreSQLサーバーを起動
`postgres -D /usr/local/var/postgres`

## ユーザーを作成
`createuser -P newuser`
このnewuserを作りたいユーザー名に変更して使えばよい。

## データベースを作成
`createdb db -O postgres`
この場合はdbという名前のデータベースが作成できる。これを好きに変更して実行する。
(備忘録)PHPでデプロイとアプリ公開まで



参考記事

https://qiita.com/0yan/items/cd7eb98e114dd812c498


https://qiita.com/ak25562983/items/c6bd1ec88e06a1f7f954

https://qiita.com/youth_case/items/fb821dcb351c7542030f