OmniAICreator/Qiita-1.07M huggingface dataset:
wpのインポートにpower automateを使う

#自動化したサンプル
![login.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/6b1bf7ad-e89b-eece-d2bc-0497983b5e47.gif)



#作ろうとした背景
他のシステムからcsvをダウンロードしてきて、wordpressに記事データをインポートすることってよくあると思うのですがカスタムフィールドのデータもインポートしようとすると結構大変で、意外と時間がかかったりします。




##大変な点
・wpの形式にcsvを合わせなければいけない

・標準だとカスタム投稿をインポートできない

・カスタムフィールドはインポートできない

↑この時間がかかる箇所をpower automateを使って自動化できないかなと考えました。

#具体的な処理
###メインの処理
まずはメインの処理から見ていきます。
![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/2b038223-dc5a-785d-1886-95862582a99c.jpeg)

キャプチャーを見ると分かりますが処理が3行しか書いていません
これはサブフローという関数みたいなもので処理をまとめてあるからメインの処理が少ないです。

**注意する点としてlogin関数の後に遅延処理を1秒入れています。
これは何故かというとloginをしたあとのページロードが遅くて次の関数が実行できないときがあったため1秒入れています。**



###ログイン処理
webオートメーションから動作の処理を選んでもらうだけなのでログイン処理に関しては説明する所は無いかと思います。
![test02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/cdff2ebc-c4e8-4e68-27b3-282268440c1b.jpeg)


##入力部分
まず読み取りcsvを用意します。
今回のサンプルcsv

```csv:test.csv
タイトル,詳細,カスタムフィールド01,カスタムフィールド02
テストタイトル01,記事の説明,テストカスタムフィールド,96
テストタイトル02,記事の説明,テストカスタムフィールド,96
テストタイトル03,記事の説明,テストカスタムフィールド,96
テストタイトル04,記事の説明,テストカスタムフィールド,96
テストタイトル05,記事の説明,テストカスタムフィールド,96
テストタイトル06,記事の説明,テストカスタムフィールド,96
テストタイトル07,記事の説明,テストカスタムフィールド,96
テストタイトル08,記事の説明,テストカスタムフィールド,96
テストタイトル09,記事の説明,テストカスタムフィールド,96
テストタイトル10,記事の説明,テストカスタムフィールド,96
```

↑このcsvを読み込んでforeachで回していきます。


![test03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/5a78c82e-fdc6-1add-a3e3-ab3b3cd86303.jpeg)


こちらもwebオートメーションから動作の処理を選んでもらうだけです。

**1点悩んだのが画像の選択処理です。
赤枠を囲んである箇所は画像の選択処理なのですがwpの画像選択をボタンのクリックの自動化を組み合わせて選択させるのは難しそうだったのでjsを使いinput hiddenに直接wpの画像idを仕込むことで実現しています。**

```javascript:test.js
function ExecuteScript() {
    document.getElementsByName("acf[field_61173df3d99c7]")[0].value = %CurrentItem[3]%;
//%CurrentItem[3]%はforeachの値
}
```

##感想
まだまだ日本語の情報が少なく使い方が良く分からないツールの一つなのかと使い始める前は思っていたのですが、ツール自体は日本語化されていますし触っていれば使い方が分かるツールだなと感じました。
また多少プログラミング的な要素もありますが、vbsやgasでやるより大分ハードルが下がっているので自動化ツールに興味のある方に是非オススメしたいです。
WindowsServer2012でforeach-object -parallel をやりたい

それらしいものを

```powershell
function Start-ThrottlingJob {
    Param(
        [int]$StartupInterval = 2,
        [int]$IntervalSecond = 5,
        [int]$Parallel = 5,
        [string]$Name,
        [Parameter(ValueFromPipeline=$True)][object[]]$ArgumentList,
        [Parameter(Mandatory=$True)][scriptblock]$ScriptBlock
    )
    begin {
        $q = New-Object System.Collections.Queue
    }
    process {
        foreach($o in $ArgumentList){
            $q.Enqueue($o) | Out-Null
        }
    }
    end {
        while($q.Count -ne 0)
        {
            if ((get-job -state Running).Count -ge $Parallel) { break }
            $task = $q.dequeue()
            $n = if ($Name -ne $null) { $task.$name } elseif ($task -is [string]) { $task }
            Start-Job $ScriptBlock -Name $n -ArgumentList $task -Verbose
            Start-Sleep $StartupInterval
        }
        while($q.Count -ne 0)
        {
            Start-Sleep $IntervalSecond
            if ((get-job -state Running).Count -ge $Parallel) { continue }
            $task = $q.dequeue()
            $n = if ($Name -ne $null) { $task.$name } elseif ($task -is [string]) { $task }
            Start-Job $ScriptBlock -Name $n -ArgumentList $task
        }
    }
}
```

テスト

```powershell
$sb = { param($a) sleep (get-random -min 1 -max 60); echo $a.FullName }
ls | Start-ThrottlingJob -StartupInterval 1 -Parallel 10 -name name -ScriptBlock $sb
```

ゴテゴテしてしまったけど、それらしく動いたので良いことにする
アクセス修飾子 コンストラクタ 継承 PHP

#■アクセス修飾子
プロパティやメソッドのアクセス権を指定するものクラスを定義する際には必ず明治する。

####▼praivate
自分のクラス内でのみアクセス可能

####▼protected
自クラスか継承クラスからのみアクセス可能

####▼public
どこからでもアクセス可能
プロパティやメソッドにアクセス修飾子をつけてない場合は自動でpublicとして設定されている。

#■staticキーワード
●静的なプロパティやメソッドを定義する。
●インスタンス化しなくてもアクセスできる。
共通で使うプロパティやメソッドに使う。

``` php
//書き方例
public static function メソッド名() {}

//クラス内での呼び出し方
Self::メソッド名()

//外で使う場合
クラス名::メソッド名()
```

#■コンストラクタとは
クラスがインスタンス化された時に、最初に実行される特別なメソッド
汎用的なプロパティを使いたい時などに使う。
テーブル名が複数使う時など
construct()
インスタンス化する時の引数に入れた値がconstructで定義したメソッドの引数に入って実行される。

``` php
//書き方 例
Class Aaa{
//結果的にこのプロパティにインスタンス時に入れた引数が入る。
protected $table_name;

//$table_nameと言う引数にインスタンス時の引数が入る。
 function_construct($table_name) {
  $this->table_name = $table_name
 }
}

//別ファイルでクラスのインスタンス化 引数を渡している。
$aaa = newAaa('blog');
```
#■継承とは
クラスを引き継ぐ
別クラス(親クラス)のプロパティやメソッドを引き継ぐ事ができる。
protectedは親クラスとこの継承した子クラスで使える。

``` php
requirce_once('dbc.php');

Class 子クラス名 extends 親クラス名{}
```
PCに接続したWEB CAMERAを使って、Google-Colaboratory上でPythonスクリプトを走らせBarcodeを読む方法

PCに接続したWEB CAMERAを使って、Google-Colaboratory上でPythonスクリプトを走らせBarcodeを読む方法

<font color='red'>【重要：言い訳】</font>

* コードを読んでいただいたほうが早いと思いましたので解説は後回しにします。
* 実用というより、こういう事ができるのだなと、機能を実感できるコードです。

<font color='red'>必要なもの：</font>

* WEB CAMERAの動作が確認できているPC
* Google-Colaboratoryを使用するためのGoogleのアカウント

<font color='red'>使用しているライブラリ：</font>

* pyzbar
* OpenCV
* 他、

<font color='red'>実装している機能：(というほどのものではありません)</font>
* バーコードを読むことができ、読んだバーコードは左上に表示されます。
* 連続して同じバーコードを読むと、「OK! Bring next barcode」と表示されます。
* 不連続で同じバーコードを読むと、「Duplicate. Read already」と表示されます。
* 読んだバーコードは、「Barcode reader result.csv」というファイルが、Colabが用意したSample_dataフォルダと同じ並びに作成されます。
* １フーレムを処理するのに必要とした時間が「秒」単位で表示されます
* 画面を左クリックでQuitします。


<font color='red'>実行方法：</font>
次の手順を行えばまずは動作を確認できます。

* 次のURLをクリックする  
   https://github.com/JunkeyMonkeyBaby/Barcode-Reader-on-Google-Colaboratory-WebCAM

* 次のリンクをクリックする
	「Barcode_Reader_on_Go…」をクリックする。

	参考：リンク先はここ
https://github.com/JunkeyMonkeyBaby/Barcode-Reader-on-Google-Colaboratory-WebCAM/blob/main/Barcode_Reader_on_Google_Colaboratory.ipynb

* 中央にある「Open in Colab」をクリックする。Google Colabに遷移します。
<font color='red'>注意：</font>Googleへのログインを要求されます

* 一番上のセルから順番に最後まで実行する。 
  実行は、SHIFTキーを押しながら、Enterキーを押します。

<font color='red'>　注意：</font>「警告：このノートブックはGoogleが作成したものではありません」と言われます。自己責任、自己判断で進めてください。

* WEBカメラから取得した画像が最後のセルの下に表示されるはずです。
* バーコードを画角内に写します。
* 読み取りが成功すれば表示されます！
* 画面を左クリックで終了します。

<font color='red'>参考画面</font>

![Barcode_Reader_on_Google_Colaboratory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/ccb4506c-369c-92fd-8eac-a09d23564405.png)

<font color='red'>参考：</font>
* How to Use Webcam In Google Colab for Images and Video (FACE DETECTION)  
  https://www.youtube.com/watch?v=YjWh7QvVH60

* How to Detect QRCode and BarCode using OpenCV in Python + Project  
  https://www.youtube.com/watch?v=SrZuwM705yE

Enjoy!
[Linux_01]コマンド一覧

#コマンド

#演算子
##&&
1つ目のコマンドが正常終了した場合に2つ目のコマンドを実行する。
以下の例では、`pwd`の出力結果の後に`ls -la`の結果を出力している。

```
$ pwd && ls -la
/home/ec2-user
total 20
drwx------ 4 ec2-user ec2-user  117 Aug  6 09:46 .
drwxr-xr-x 3 root     root       22 Aug  6 08:56 ..
-rw------- 1 ec2-user ec2-user    5 Aug  6 09:46 .bash_history
-rw-r--r-- 1 ec2-user ec2-user   18 Jul 15  2020 .bash_logout
-rw-r--r-- 1 ec2-user ec2-user  193 Jul 15  2020 .bash_profile
-rw-r--r-- 1 ec2-user ec2-user  231 Jul 15  2020 .bashrc
drwx------ 2 ec2-user ec2-user   29 Aug  6 08:56 .ssh
drwxrwxr-x 5 ec2-user ec2-user 4096 Aug 14 06:28 .vscode-server
```

##\
bashに長いコマンドを入力する際に改行して見やすくする。
以下の例では、`ls \`を入力するとプロンプトが出て、`-la`のオプションを入れることでそれらのコマンドを結合してくれている。

```
$ ls \
> -la
total 20
drwx------ 4 ec2-user ec2-user  117 Aug  6 09:46 .
drwxr-xr-x 3 root     root       22 Aug  6 08:56 ..
-rw------- 1 ec2-user ec2-user    5 Aug  6 09:46 .bash_history
-rw-r--r-- 1 ec2-user ec2-user   18 Jul 15  2020 .bash_logout
-rw-r--r-- 1 ec2-user ec2-user  193 Jul 15  2020 .bash_profile
-rw-r--r-- 1 ec2-user ec2-user  231 Jul 15  2020 .bashrc
drwx------ 2 ec2-user ec2-user   29 Aug  6 08:56 .ssh
drwxrwxr-x 5 ec2-user ec2-user 4096 Aug 14 06:28 .vscode-server
```

#引数
【Laravel】DBファサードで取得した日付にformatメソッドを使うとエラーになる(Call to a member function format() on string)

#はじめに
DBファサードを用いて、timestamp型の`created_at`の値をview側で`format('Y年m月d日 H時i分')`をかけて表示しようとしたところ、
***「Call to a member function format() on string」*** 
というエラーが発生しました。

#対処法
DBファサードを利用することで、timestamp型がstring型になっていることが分かったので、
phpの`strtotime()`を使ってフォーマットをかけると上手くいきました！

```html:viewファイル
<p>
   作成日：{{ date('Y年m月d日 H時i分' ,strtotime($properties->created_at)) }}
</p>
```

```php:コントローラー
<?php
namespace App\Http\Controllers\admin;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class PropertyController extends Controller
{
    public function index()
    {
            return view('admin.index', [
                'properties' => DB::table('properties')->paginate(10)
            ]);
    }
}
```

#終わりに
以上、自分用備忘録でした。
AmplifyでLambda Layerを環境非依存にできなかった話とその対策

# 概要
AmplifyのLambda layerを環境*非依存にするために試行錯誤したのでメモ。（Lambda layerとはLambda関数で使用するライブラリ群で、例えばJSの場合`node_modules`ディレクトリをLambda関数から利用できるようにアップロードしておくものだ。）

環境：`amplify env`で切り替えられるenvironmentのこと。

# 結論
2021/08/14現在、AmplifyでLambda layerの環境に依存する設定をAmplifyの設定ファイルから切り離すことができなかった。
対策としては、Lambda layerをAmplifyの外(Lambdaコンソール等)で直に作成し、ARNをAmplifyのLambda関数で指定して使用することとした。

Amplifyの進化は激しいので、しばらくしたら改善されることを祈る。

# 詳細
## 問題
Amplifyで`amplify add function`コマンドから、Lambda layerを作成しAmplifyプロジェクトでLambda関数と一緒に管理することが可能なのだが、layerに関してはCloudFormationのテンプレートから環境毎に違う設定を切り出すことができない。

Lambda関数やAPIに関しては、環境依存の設定はパラメータ化して`amplify/team-provider-info.json`に環境毎の設定として切り出すことができるのだが、layerに関してはできない。

具体的には `amplify/backend/function/mylayer/mylayer-cloudformation-template.json` のようなファイルがlayerのCloudFormationテンプレートになるが、このファイルにlayerの各バージョンがリソースとして記載されてしまう。そして、そのバージョンは環境毎のlayerによって異なるリソースとなるため、環境を切り替える度にこのファイルが書き換えられてしまう。

なんとかこれをパラメータを利用するようにしても、Layerのバージョンが上がるとこのファイルがAmplify CLIによってまるまる上書きされてしまい環境依存の内容に戻ってしまう。

今のところ、これにより大きな障害があったわけではないが、異なる開発者がpull requestを出す度にここが変わっているので、それをマージして良いものか迷うし、本来の設定が何だったのかわからなくなる。

[Amplify CLIのリポジトリでも2021/05/27に問題提起](https://github.com/aws-amplify/amplify-cli/issues/5479#issuecomment-849600546)されているが有効な解決策が提示されないまま、2021/06/10にメンテナーによってクローズされている。なので、近いうちに改善されるとは思えない。

## 対策
ワークアラウンドとしてLambda layerをAmpliyの管理下から外した。
Lambdaコンソールで直に作成して、そのARNをAmplify管理下のLambda関数の設定で指定するようにした。
指定する場所はLambda関数のCloudFormationテンプレート `amplify/backend/function/myfunction/myfunction-cloudformation-template.json` のようなファイルの、`Resources.LambdaFunction.Properties.Layers`になる。

```js
"Resources": {
  "LambdaFunction": {
    ...
    "Properties": {
      ...
      "Layers": [
        "arn:aws:lambda:ap-northeast-1:00000000000000:layer:mylayer:1"
      ]
    }
  },
  ...
},
```

### おまけ: このANRはパラメータ化できる
このLambda関数のCloudFormationテンプレートでは`amplify/team-provider-info.json`に切り出したパラメータを使用することができるので、このlayerのARNをパラメータ化してしまえば、環境毎に切り替えることが可能だ。
また、パラメータのデフォルト値に通常利用するARNを設定しておき、必要なときだけ`amplify/team-provider-info.json`に任意のARNを設定することで、異なるLambda layerやそのバージョンを一時的に使用することができる。
やり方は[こちら](https://qiita.com/fossamagna/items/16f4eb427b7401808f3a)でまとめてくれている。
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.

# git clone、git push しようとしたらエラーがでた。
```
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
・・・ 省略 ・・・
: The requested URL returned error: 403
```
```
【日本語翻訳】
リモート：パスワード認証のサポートは2021年8月13日に削除されました。代わりに個人アクセストークンを使用してください。
```
GitHubのパスワード認証を2021年8月13日に廃止するとのことでした。。。

# 個人アクセストークン取得手順
１｜[https://github.com/settings/tokens](https://github.com/settings/tokens)にアクセスする
２｜「Generate new token」をクリック
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595315/12128de8-ce9e-ec9e-1826-d53ec9763cb6.png)
３｜「Note」にトーク名を設定、「Generate token」をクリック
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595315/35b7adaf-6c47-f31f-f929-bc1905ed63e3.png)

４｜生成されたトークンをコピー
※ ページを離れると再度コピーできなくなるので注意

# 試しに「git clone・・・」してみたが、、、
```
Cloning into 'リポジトリ名'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
```
【日本語訳】
'リポジトリ名'へのクローン作成...
git@github.com：アクセスが拒否されました（公開キー）。
致命的：リモートリポジトリから読み取ることができませんでした。

正しいアクセス権があることを確認してください
リポジトリが存在します。
```
何故なんだ、、、
本来であれば下記のようにパスワードを求められるはずなのに、、、、

```
$ git clone https://github.com/username/repo.git
Username: your_username
Password: your_token
```

# Macのキーチェーンで保存されているパスワードを変更
キーチェーンで保存されているgithubのパスワードを変更することで解決することがわかりました。
１｜「command + スペース」で「spotlight」を出し「Keychain Access.app」を検索
２｜右上の検索から「github」で検索
３｜「インターネットパスワード」の青いgitthubをクリック
４｜パスワードを表示させてコピーしたトークン（ghp_・・・）をここにペーストして保存

# 最後に
最後に「git clone」してみると...

```
Cloning into 'リポジトリ名'...
remote: Enumerating objects: 198, done.
remote: Counting objects: 100% (198/198), done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 198 (delta 37), reused 187 (delta 26), pack-reused 0
Receiving objects: 100% (198/198), 58.39 KiB | 398.00 KiB/s, done.
Resolving deltas: 100% (37/37), done.
```
無事にクローンすることができました。

# 参考サイト
・[公式ドキュメント](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)
・[ほげさん](https://zenn.dev/suzuki_hoge/articles/2021-08-github-access-f732e5b9868137)
【1行野郎】ldd で表示されるライブラリの合計サイズを算出する


## 処理内容

下記の場合だと libgtk3-nocsd.so.0、libexpect.so.5.45、、、といった
ファイルのサイズの合計値を求める

```
$ ldd /usr/bin/expect
	linux-vdso.so.1 (0x00007ffc27fc5000)
	libgtk3-nocsd.so.0 => /usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 (0x00007f10722bb000)
	libexpect.so.5.45 => /usr/lib/x86_64-linux-gnu/libexpect.so.5.45 (0x00007f107208b000)
	libtcl8.6.so => /usr/lib/x86_64-linux-gnu/libtcl8.6.so (0x00007f1071cda000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f10718e9000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f10716e5000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f10714c6000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f10712c3000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1070f25000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f1070d08000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f10726c5000)
```

## コード

```bash
$ LANG=C ldd /usr/bin/expect |
  sed -r -n 's/(.*) => (.*) \((.*)\)/\2/p' |
  xargs -I@ realpath @ |
  xargs -I@ ls -ltr @ |
  awk '{i += $5 } END { print i }'
```

## 実行結果

```bash
$ LANG=C ldd /usr/bin/expect | sed -r -n 's/(.*) => (.*) \((.*)\)/\2/p' | xargs -I@ realpath @ | xargs -I@ ls -ltr @ | awk '{i+=$5 } END { print i }'
5998352
```
aws_セキュリティグループとネットワークACLの違い

#まえがき
SAA-S02の試験対策となります。

#前提知識
掲題の機能が提供される目的としては以下の内容となるようです。
``「ネットワークレベル(IP, TCP/UDP レベル) で通信を許可 / 拒否し、トラフィックを制御するファイアウォールとして機能する。」``
いずれもファイアウォール（パケットフィルタリング）機能にあたり、上記だけを見ると同じもののように見えますね。

#では何が異なるのか
対象や設定評価の方式が微妙に異なるようです。

| | セキュリティグループ | ネットワークACL |
| ---- | ---- | ---- |
| 紐付け対象 | インスタンス | サブネット |
| ルール設定 | 許可ルールのみ | 許可 / 拒否ルール |
| ステート | ステートフル<br />戻りの設定は不要| ステートレス <br /> 両方向の設定が必要|
| デフォルト | インバウンド通信は拒否 | 双方向に許可 |

例えば、インスタンス間（A→B）のhttp通信が行われる場合、以下のルートを通るようです。

|  | 通信方向 | 適用 |
| ---- | ---- | ---- |
| インスタンスA | アウトバウンド | ネットワークACL |
| サブネットA | アウトバウンド | セキュリティグループ |
| サブネットB | インバウンド | セキュリティグループ |
| インスタンスB | インバウンド | ネットワークACL |


#Tips
・同一サブネット内の通信
　→セキュリティグループが適用される。

・サブネット間の通信
　→ネットワークACLが通信の往復に適用される。
　
・両者に重複するルールが存在する場合はいずれも許可されていないと通信できない。
LibreOffice Base を使うテスト

キッズに SQL でデータ処理をさせようかな？ と思い、 LibreOffice Base が使えるかどうかチャレンジ。

# 条件

- Ubuntu Linux デスクトップで完結
 - 我が家のキッズ環境/ワークショップ環境として Ubuntu Linux デスクトップ環境を使用しているため
- CSV ファイルをデータソースとする
- パスワード無しで扱う
- テーブル名やフィールド名は日本語を用いる
- インストール簡単
- 

# 環境

- Ubuntu 20.04 LTS デスクトップ
- LibreOffice バージョン: 6.4.7.2 ( Ubuntu ディストリビューション付属)


# Base のインストール

Ubuntu Desktop だと Libreofficeはインストールされているが、Baseは入っていない。

以下のようにしてインストール

```

$ apt install libreoffice-base
```

メニューから Base が呼び出せるようになった。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5f485cf0-c87a-f458-138b-a7e99803e706.png)

しかしアイコンを押しても起動した様子が無い。

おかしーなーと思ってたら、ずっと LibreOffice をひらっきぱなしだったので一旦全部消したら Base 
が起動するようになった。


# CSVデータの取り込み

「新規データベースの作成(E)」で、



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5295dbcb-473b-d4b8-e399-b090410f44e0.png)
以下を経由して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1199bf30-0711-4df5-b603-71368629f0dd.png)
名前を付けて保存します。

そのうえで、「ファイル」-「開く」で、CSVファイルを選択します。直接Baseで取り込みではなく、LibreOffice Calc で取り込まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d4324158-8273-39a1-cc62-50dde8a183ed.png)

これを Ctrl+A + Ctrl+C で全てコピーし、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/eab7b93f-3851-c75e-7fa3-ef80efc6141a.png)



Base で「テーブル」を選択した状態で「編集」→「貼り付け」とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3e0aeba4-d6c5-70ae-b371-dc632b746af8.png)

「次へ」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/98a755bd-2ff0-7343-7f62-d1d6df36df42.png)

「≫」 を押して全てを適用し、


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c2fdd509-ff99-1a6d-23d3-5e1f51754b24.png)


「プライマリキーを作成しますか？」で「はい」を選ぶと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0fbfcd45-de84-1113-54d7-1b5b0a34205d.png)

CSV テーブルが取り込みできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0f1cb01f-31e8-28f5-e4dd-b752801da8b3.png)

# SELECT 文を実行する

「クエリー」の「SQL表示でクエリーを作成...」で、以下のようにしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4be58a66-4e41-fcce-1ef0-c266b8bfbe1f.png)

結果が以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/92e6a21a-9419-1993-bb9a-b1ef64d71ddd.png)

なお、結果をソートするために 

```

SELECT 年代,count(ID) FROM "テーブル1" GROUP BY 年代 ORDER BY 年代
```


としています。


# SQL 実行のエラー


ここまではうまくいきましたが、問題がありました。例えば 


ここまでしましたが、例えば

SELECT 性別,count(ID) FROM "テーブル1" GROUP BY 性別

とすると、以下のエラーが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d085a847-d216-af2d-5b97-c34b74922140.png)


# その他の問題

クエリーではなく、「ツール」→「SQL」で、以下のようにすれば同じSQLが正常に実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5b5cc599-b550-797f-466b-b822d5d9460a.png)


しかしながらIMEがONにならず、日本語がタイプインできませんでした。
SQLをコピー&ペーストだと使えますが、日常的に使うのには難しそうです。

# 使用を断念

ここまで試しましたが、日本語環境でわかりやすい操作ができる環境にはなりそうにないので、ここでテストを諦めました。
M5Camera単体でWifi設定できるようにしてみた

以下のページを参考に試してみた
https://tech-blog.cerevo.com/archives/4952/
https://firtel.blogspot.com/2019/06/esp32-cam-wifi-manager.html


```
cd ${arduino_core_directory}/libraries
git clone https://github.com/me-no-dev/AsyncTCP
git clone https://github.com/me-no-dev/ESPAsyncWebServer
git clone https://github.com/alanswx/ESPAsyncWiFiManager
```


```cpp
#include "esp_camera.h"
#include <WiFi.h>
#include <ESPmDNS.h>//追加
#include <ESPAsyncWebServer.h>//追加
#include <ESPAsyncWiFiManager.h>//追加
AsyncWebServer server(80);//追加
DNSServer dns;//追加

//
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
//            Ensure ESP32 Wrover Module or other board with PSRAM is selected
//            Partial images will be transmitted if image exceeds buffer size
//

// Select camera model
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM  //コメントアウト
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM // コメント外す
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM

#include "camera_pins.h"

//const char* ssid = "*********";　//コメントアウト
//const char* password = "*********";　//コメントアウト

void startCameraServer();

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  AsyncWiFiManager wifiManager(&server,&dns);//追加
  wifiManager.autoConnect("ESP32-CAM");//追加
```

```cpp
  //WiFi.begin(ssid, password);//コメントアウト
  WiFi.begin();//追加
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  MDNS.begin("cam");//追加
```

リセットしたい時に

```cpp
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(true,true);
```

を`void setup() {`の直後におく

※ただし、これはあくまで書き込みリセット用。この部分をコメントアウトして再度書き込まないといけないっぽい
もしコメントアウトして再書き込みしなかった場合、写真が撮れず、シリアルモニタに以下のエラーが出る

```
E (56332) httpd: httpd_server_init: error in bind (112)
```

コメントアウトして再書き込みする以外に楽な方法あったら教えてください

スマホ等でESP32-CAMに接続するとログイン画面が出てくる（出てこなかったら http://192.168.4.1 にアクセス）。
設定後に
http://cam.local/
にアクセスすると以下のような見覚えのある画面が出てくる

![スクリーンショット 2021-08-14 15.20.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263016/61aaef5f-a8e3-36b8-253e-d013a1de98d4.png)

URLが固定されるんで結構嬉しい。

あとは煮るなり焼くなり。
参考になりそう：https://www.hiroto.tech/moin.cgi/Embedded/M5Stack/M5Camera

あ
画像サイズ設定：http://cam.local/control?var=framesize&val=10
画像取得：http://cam.local/capture
C++: base64 ライブラリの使い方

こちらから、インクルードファイルをダウンロードします。
[CLX C++ Libraries](https://ja.osdn.net/projects/clxcpp/releases/51423)

解凍

```bash
tar xvfj clx_0.18.2.tar.bz2
```

プログラム

```cpp:ex01.cpp
// -----------------------------------------------------------------------
/*
	ex01.cpp

						Aug/14/2021
*/
// -----------------------------------------------------------------------
#include <iostream>
#include <string>
#include <clx/base64.h>

// -----------------------------------------------------------------------
int main()
{
	std::cerr << "*** 開始 ***\n";

	std::string src = "ABCDEFG";

	std::string code = clx::base64::encode(src);

	std::cout << code << std::endl;

	std::cout << clx::base64::decode(code) << std::endl;

	std::cerr << "*** 終了 ***\n";

	return 0;
}

// -----------------------------------------------------------------------
```

```text:Makefile
ex01: ex01.cpp
	clang++ -o ex01 ex01.cpp -I./
clean:
	rm -f ex01
```

コンパイル

```bash
make
```

実行結果

```text
$ ./ex01 
*** 開始 ***
QUJDREVGRw==
ABCDEFG
*** 終了 ***
```

結果の検証

エンコード

>```text
$ echo 'ABCDEF' | base64
QUJDREVGCg==
```

デコード

>```text
$ echo 'QUJDREVGCg==' | base64 -d
ABCDEF
```

参考ページ
[Base64 変換](https://qiita.com/ekzemplaro/items/b0db9965480e05d4c5e6)
Luaでrefのようなものを作る

# Luaでrefのようなものを作る

Luaで参照のようなものを作ります。テーブルに対する「参照値」ではなくプリミティブにも使える参照のような動作をするものです。

## 実装の方針

メタメソッドの `__index` および `__newIndex` によってテーブルへのアクセスを制御することができることを利用します。参照名と参照先 (テーブルとキーのペア) の対応を保持しローバルのrefオブジェクトへのアクセスにより参照先を操作します。

## 実装

### refオブジェクト

refオブジェクトに次のメンバを持たせます。

| キー   | 型         | 値                     |
| - | - | - |
| table  | "table"    | 参照名と参照先のリスト |
| put    | "function" | 参照を追加するメソッド |
| delete | "function" | 参照を削除するメソッド |

今回は簡単のためrefはグローバルオブジェクトとしますがインスタンスとする場合はメタテーブルから `put` メソッドと `delete` メソッドを呼べるようにすればよいです。

### インデックスへのアクセス

refオブジェクトの `__index` を設定します。フィールドにアクセスされるとこの関数が呼ばれるため、 `ref.table` 内を参照して返します。ただし `put` メソッドや `delete` メソッドへのアクセスは特別に直接 `ref` オブジェクト内のメソッドを呼び出します。呼び出しが循環しないために `rawget` メソッドを使い `ref` 内のフィールドを直接参照します。なお、コード内ではメタテーブルに設定するためのオブジェクトを `meta` と表しています。

```lua
meta.__index = function(ref, key)
  if type(ref) ~= "table" then
    return nil
  end

  -- putフィールドとdeleteフィールドはref内を直接参照
  if key == "put" or key == "delete" then
    return rawget(ref, key);
  end

  -- ref.table内のフィールドを参照
  local obj = rawget(ref, "table")[key]
  if obj ~= nil then
    return (obj.table)[obj.key]
  end

  return nil
end
```

代入も同様にして行えます。

```lua
meta.__newindex = function(ref, key, value)
  if type(ref) ~= "table" then
    return nil
  end

  -- ref.table内のフィールドを参照
  local obj = rawget(ref, "table")[key]
  if obj ~= nil then
    (obj.table)[obj.key] = value
  end
end
```

`put` メソッドと `delete` メソッドは単純に `ref.table` 内を書き換えるだけです。メタテーブルの設定前に書くと `rawget` を使わずに済みます。

```lua
ref.put = function(name, table, key)
  rawget(ref, "table")[name] = {
    table = table,
    key = key
  }
end

ref.delete = function(name)
  rawget(ref, "table")[name] = nil
end
```

## 振る舞い

次のように参照のような使い方をできます。ただしテーブルへの参照はテーブルを参照する値への参照になります。

```lua
local table = {
  a = 0
}

ref.put("a", table, "a")
ref.put("a2", table, "a")

print(table.a .. ", " .. ref.a .. ", " .. ref.a2)    -- 0, 0, 0
table.a = 10
print(table.a .. ", " .. ref.a .. ", " .. ref.a2)    -- 10, 10, 10

ref.a = 20
print(table.a .. ", " .. ref.a .. ", " .. ref.a2)    -- 20, 20, 20

ref.a2 = 30
print(table.a .. ", " .. ref.a .. ", " .. ref.a2)    -- 30, 30, 30
```

また、次のように参照に対して参照を設定することもできます。この場合も結果は同様です。

```lua
ref.put("a2", ref, "a")
```
md2googleslides の使い方メモ

微妙にハマりどころがあるけど直ってないぽいのでメモ。

## インストール
### Linux
Nodeが新しいと動かないので、Node 12をnvmなどを使っていれる https://github.com/nvm-sh/nvm 。

```sh 
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.zshrc
nvm install 12

npm install -g md2gslides
```

`npm install googleworkspace/md2googleslides` で mainブランチを直接インストールすると後でcredentialをいじったりNode.js 12を使うのを避けることができる。`-g` は動かず、インストール先はnode_modulesになる。

### macOS
```sh
# node-gypのビルドに必要
brew install vips

npm install -g md2gslides
```

## developer projectの準備
https://github.com/googleworkspace/md2googleslides#installation-and-usage の箇条書きに従ってdeveloper projectを作る。個人利用でも、プロジェクトは一般公開しないと使えない (OAuth consent screenのメニューからPublishする)。適当にYouTubeのリンクも足してレビューに出さないといけないが、approveされなくても即座に使える。レビューに出すとVerify Domainのリクエストが来るので、それを無視すればそこから何も起きなそう。

permission scope は `https://www.googleapis.com/auth/presentations`, `https://www.googleapis.com/auth/drive` に絞る。

## ~/.md2googleslides/client_id.json の用意

Credentialsを作った時にダウンロードできるやつをここに置く。 `~/.md2googleslides` はディレクトリであって、JSONのパスそのものではないことに注意。

これは [Credentials page](https://console.cloud.google.com/apis/credentials) で下矢印ボタンを押すことで後からダウンロードすることもできる。

## OAuth client id/secret の変更
`which md2gslides` をして、そのファイルを編集する。

https://github.com/googleworkspace/md2googleslides/issues/95#issuecomment-858729913 に書いてある通り、 `clientId` と `clientSecret` を自分で用意したものに差し替える。

これも先ほどの [Credentials page](https://console.cloud.google.com/apis/credentials) の DOWNLOAD JSON と同じ場所で見れる。

前述の方法でmainブランチからインストールした場合は不要。

## 使い方
スライドを作る時は

```bash
md2gslides slides.md --title "Talk Title"
```

で一旦適当につくる。その後は、

```bash
md2gslides slides.md --append [slide_id] --erase -n
```

を使うのが良い。
slide_id は `https://docs.google.com/presentation/d/[slide_id]/edit` から取る。
【5章】Javaを学ぼう

#論理演算子について
前章では真偽値・比較演算子について学びました！
今回は論理演算子についてアウトプットしていきたいと思います！
論理演算子は「かつ」「または」「~でない」を表現する記号になります。

##論理演算子 「かつ」 
まずは「かつ」について解説していきます。
「かつ」は&&で表現し、「条件1 && 条件2」は「条件1がtrueかつ条件2もtrue」であれば結果もtrueになり、どちらか一方でもfalseであれば結果はfalseになります。

```java:論理演算子&&
 aが10の時     a > 15 && a < 35    .......  false
              //false   //true

 aが25の時     a > 15 && a < 35    .......  true
              //true    //true

 aが40の時     a > 15 && a < 35    .......  false
              //true   //false
```

##論理演算子 「または」
次は「または」について解説していきます。
「または」は||で表現し、「条件1 || 条件2」は、「条件1または条件2のどちらか一方でもtrue」であれば結果はtrueになります。

```java:論理演算子||
 aが10の時     a < 15 || a > 35    .......  true
              //true   //false

 aが25の時     a < 15 || a > 35    .......  false
              //false  //false

 aが40の時     a < 15 || a > 35    .......  true
              //false   //true
```

##論理演算子 「〜でない」
最後に「〜でない」について解説します。
!を用いると、「〜でない」を表現できます。例えば、!(a >= 25)は「xが25以上でない（25より小さい）」ときtrueになり、「xが25以上」のときfalseになります。

```java:論理演算子!
 aが10の時     a >= 20    .......  false
              //false

 aが10の時     !(a >= 20)   .......  true
              //true

```

##まとめ
重複してしまいますが、&&は、どちらもtrueでなければ全体の結果はtrueになりませんが、||は、どちらか一方でもtrueであれば全体の結果もtrueになります。しっかりと覚えておきましょう！

```java:Main.java
System.out.println(true && false);   // 「かつ」
System.out.println(true || false);  // 「または」
```

出力結果↓

```java:コンソール
false
true
```

以上が論理演算子の説明になります。
次章はif文について記事を書いていきたいと思います。よろしければご覧になってください！
最後までご覧いただきまして、ありがとうございました！
CentOSにPython3.8をインストール（docker利用）

まあ、実際にはdockerfileやdocker-composeでまとめるのだが、
勉強がてら一度サクッとやってみるのはよさそう。
手順を間違えると`print('テスト')`するだけでエラーが出るので注意。（エラー時はGCCのバージョンに注目）

# CentOS 7

コンテナ起動

```
docker run -it -d --name centos7 centos:centos7
```

コンテナに入る

```
docker exec -it centos7 /bin/bash
```

Python3.8をインストール

```
yum update yum -y
yum install -y centos-release-scl
yum install -y rh-python38 which
scl enable rh-python38 bash
```

Pythonの動作確認

```
[root@2c1d51bcffb9 /]# python3
Python 3.8.6 (default, Oct 27 2020, 09:13:12)
[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('テスト')
テスト
>>> exit()
```

コンテナを停止して削除

```
docker stop centos7
docker rm centos7
```
# CentOS 8

コンテナ起動

```
docker run -it -d --name centos8 centos:centos8
```

コンテナに入る

```
docker exec -it centos8 /bin/bash
```

Python3.8インストール

```
yum update yum -y
yum install python38 -y
```

Pythonの動作確認

```
[root@166a5a5ffebc /]# python3
Python 3.8.6 (default, Jan 29 2021, 17:38:16)
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('テスト')
テスト
>>> exit()
```

コンテナを停止して削除

```
docker stop centos8
docker rm centos8
```
【Python】print出力で文字列の差異を色で表現する

## この記事の目的
正解文字列と任意の文字列を１文字単位で比較し、消えた文字を赤文字で、増えた文字を黄色の背景色でprint出力する。

![diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/2e99ca52-d44b-cb7b-7821-117710ec9720.png)

ページの最後に[コード一覧](#コード一覧)があります。

## 実行環境
+ python 3.9

## 解説
使用するのは標準モジュール difflib の Differ オブジェクトの compare メソッドです。


https://docs.python.org/ja/3/library/difflib.html

compare(a, b)
>文字列からなる2つのシーケンスを比較し、差分（を表す文字列からなるシーケンス）を生成します。
各シーケンスの要素は、改行で終わる独立した単一行からなる文字列でなければなりません。そのようなシーケンスは、ファイル風オブジェクトの readlines() メソッドによって得ることができます。（得られる）差分は改行文字で終了する文字列のシーケンスとして得られ、ファイル風オブジェクトの writelines() メソッドによって出力できる形になっています。

返り値はgenerator。

```example.py
import difflib
d = difflib.Differ()

a = "abcde"
b = "a ydef"

diffs = d.compare(a, b)
for diff in diffs:
    print(diff)
```

実行結果はコードと文字からなります。

```py
  a
- b
- c
+  
+ y
  d
  e
+ f
```

|  コード  |  意味  |
| ---- | ---- |
|`'-'`|  この文字は文字列aにのみ存在する  |
|`'+'`|  この文字は文字列bにのみ存在する  |
|`' '`| この文字は共通|

一方で、文字に色をつけるにはエスケープシーケンスを使って、「色を付けるコード」＋文章＋「色付け終了コード」をprint文で出力します。

https://qiita.com/yuto16/items/5618e4147b749177bd15

https://www.nomuramath.com/kv8wr0mp/

例えば、赤字で出力すると以下のような感じにします。

```py
color_dic = {
        'red':'\033[31m',
        'yellow':'\033[43m',  
        'end':'\033[0m'
    }
print(color_dic['red'] + 'サンプルです' + color_dic['end'])
```

![サンプル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577794/e524f496-979f-e6ca-2a34-8eb46059950d.png)

色つけ終了コードをつけ忘れると、最後の文字まで指定コードの色に染まるのでお気をつけください。

表題の内容を実現するには、compareメソッドの返り値を差分コードに応じて色分けします。
今回は、正解文字列と対照文字列を比較したときに、消えた文字は赤文字で、増えた文字は黄背景で、変化のない文字はそのままprintすることにします。

## コード一覧
```py
import difflib

def print_diff_hl(ground_truth, target):
    """
    文字列の差異をハイライト表示する
    """
    color_dic = {
        'red':'\033[31m',
        'yellow':'\033[43m',  
        'end':'\033[0m'
    }
    
    d = difflib.Differ()
    diffs = d.compare(ground_truth, target)
    
    result = ''
    for diff in diffs:
        status, _, character = list(diff)
        if status == '-':
            character = color_dic['red'] + character + color_dic['end']
        elif status == '+':
            character = color_dic['yellow'] + character + color_dic['end']
        else:
            pass
        result += character
    
    print(f"ground truth : {ground_truth}")
    print(f"target string: {target}")
    print(f"diff result  : {result}")


ground_truth = "abcde"
target = "a ydef"
print_diff_hl(ground_truth, target)
```

## 終わりに
長い文字列の比較には適しませんが、tipsの一つとなれば幸いです。
【SQL】ACID特性　〜データベースの安全機構〜


こちらの本で学んだことの備忘録第2段。

https://sukkiri.jp/books/sukkiri_sql2

実務で頻繁に使うのは、おそらく四大命令などデータの出し入れ等の操作をする命令なんだろう。

だけどDBMSにおいて、前提となる最重要事項は**安全で確実なデータ操作・管理**であり、**トランザクション**や安全性を保つ為の仕組みを理解していないと大変なことになりかねないんだろうなと思ったので、備忘録を書いておく。

##ACID特性とは
「データを正確かつ安全に取り扱うために、システムが備えるべき4つの特性」として、ACID特性というものがある。ACIDというのは、以下4つの頭文字。

・Atomicity 原子性　（処理が中断しても中途半端な状態にならない）
・Consistency 一貫性　（データの内容が矛盾した状態にならない）
・Isolation 分離性　（複数の処理を同時実行しても副作用がない）
・Durability 永続性　（記録した情報は消滅せず保持され続ける）

ここから、これらACID特性を保つためにDBMSに用意されている、様々な安全機構を紹介していく。

##トランザクションとは
データベースの安全機構に不可欠なものとして、**トランザクション**という仕組みがある。

DBMSに対して複数のSQL文を送る際、1つ以上のSQL文をひとかたまりとして扱うように指示をすることができるが、このかたまりのことをトランザクションという。

DBMSではトランザクションを次のように扱う。
・トランザクションの途中で、処理が中断されないようにする。
・トランザクションの途中に、他の人の処理が割り込めないようにする。

DBMSがこのようにひとかたまりのSQL文を扱うことを**トランザクション制御**という。



##コミットとロールバック
####DBMSによるトランザクション制御①
DBMSは、トランザクションに含まれるすべてのSQL文について、必ず「すべての実行が完了している」もしくは「1つも実行されていない」のどちらかの状態になるように制御する。

この制御を実現するために、**コミット**と**ロールバック**という仕組みが使用される。
ACID特性のひとつ、「原子性」を守っている。

・**コミット**
トランザクション中のSQL文によってテーブルのデータが書き換えられると、それらは仮のものとして管理される。そしてトランザクションが終了するときに、仮の書き換えを全て確定させる。このように確定させることをコミットという。

・**ロールバック**
トランザクション中に何らかの異常が発生して中断した場合、DBMSはそれまで行った仮の書き換えをキャンセルして、無かったことにする。この無かったことにする動作をロールバックという。

##分離レベル・ロック
####DBMSによるトランザクション制御②
DBMSは、あるトランザクションを実行する際、ほかのトランザクションから影響を受けないように分離して実行する。

この制御を行うために、**ロック**と呼ばれる仕組みが使用される。
ACID特性のひとつ、「分離性」を守っている。

・**ロック**
あるトランザクションが現在読み書きしている行に鍵をかけ、他の人のトランザクションからは読み書きできないようにする。

・**トランザクション分離レベル**
自分が読み書きしたい行を他人がロックしている間は、その相手のトランザクションが完了するまで自分は待たされるので、ロックが大量に発生するとデータベースの動作速度低下につながってしまう。この副作用を克服するため、多くのDBMSではトランザクション分離レベルを指定することができる。

##データ型・制約
ここまで挙げたトランザクションを使った仕組みは、システム的なデータ異常を防いでくれるものの、人為的なミスに対しては効力を持たない。
そこでデータベースが意図しない値を格納できないように、あらかじめ**データ型**に制限をかけたり**制約**を使用する。これにより、ACID特性のひとつ、「一貫性」を守っている。

####制約の種類
・**NOT NULL 制約**
NOT NULL制約が設定された列にはNULLの格納が許可されない。また多くの場合NOT NULL制約は、DEFAULT指定と組み合わせて使用される。

・**UNIQUE制約**
ある列の内容が重複してはならない場合は、UNIQUE制約を付ける。なおUNIQUE制約がかけられていても、「NULLはNULLとも等しくない」ため、NULLが格納された行が複数存在することは許される。

・**CHECK制約**
ある列に格納される値が妥当であるかを細かく判定する場合は、CHECK制約を使用する。CHECKの後ろのカッコ内に記述した条件式が真となる値だけが格納を許される。

・**主キー制約**
主キーの役割を担う列には、主キー制約（PRIMARY KEY制約）をつけることで、「NULLも重複も許されない列」であることに加えて主キーの役割を担うという意味を持つ。

・**外部キー制約**
参照整合性（外部キーが指し示す先に、きちんと行が存在して関係性が成立していること）が崩れるようなデータ操作をしようとした場合にエラーを発生させ、処理を中断させる制約として外部キー制約（FOREIGN KEY制約）を使用する。この制約は、参照元のテーブルの外部キー列に設定する。

##バックアップ
ACID特性の4つ目、記録した情報を保持し続ける「永続性」を守るため、多くのDBMSではバックアップの仕組みを備えている。

バックアップには、以下2つの方式がある。

・**オフラインバックアップ**（DBMSを停止して行うバックアップ）
　整合性を保ちつつ、最も簡単に行う方法。
・**オンラインバックアップ**（DBMSを稼働させながら行うバックアップ）
　オフラインバックアップ中は一切データ処理が行えなくなるため、多くの場合は、稼働しながらも整合性のあるバックアップデータを取得できるオンラインバックアップを行う。

・**ログファイルのバックアップ**
通常のバックアップは1日ごとなど低頻度で行われるが、この間を補完するため、データベースが出力するログファイルを高頻度でバックアップする。なお障害発生時に、ログに記録されているSQL文を際実行して障害が発生する直前の状態までデータを更新する処理のことを**ロールフォワード**という。

<br>
<br>

####引用・参考文献

https://sukkiri.jp/books/sukkiri_sql2
AWSのCLIを設定してみる

[zenn](https://zenn.dev/mo_ri_regen/articles/aws-cli-setting)にも同様の記事を書いています。更新頻度はzennのほうが多めです👋

## この記事の目的

aws configure を使ってCLIの設定方法を学ぶ📚

## はじめに

AWSではコンソール画面からクリックすることでいろいろ設定ができます。
しかし、画面が定期的にアップデートされるため参考にしていた画面が今の画面と異なることがよくあります。

AWSのCLIを使えばAWSの画面のアップデートに左右されずに、ターミナル上で設定を行うことができます。

## 実行環境

Macbook Air(M1)
ターミナル:fish ver 3.2.2

※WindowsでもCLIはインストールできますが、動作確認はしていません

## 準備

AWSでIAMユーザを作成してください。(過去にIAMユーザを作成した[記事]([過去](https://zenn.dev/mo_ri_regen/articles/aws-iam-with-administrator-rights))もあるのでよければ参考にしてください。)

## インストール

CLIは[こちら](https://aws.amazon.com/jp/cli/)からダウンロードできます。

下記コマンドを入力してインストールされているか確認しましょう👀

```bash
aws --version
```

## 設定

下記コマンドを入力すると対話的に設定ができます。

```bash
aws configure
```

![aws configureで設定](https://gyazo.com/310680a4708a9f58fa7205fa99877e44.png)

- Access Key
IAMの左ペイン アクセス管理→ユーザをクリック。確認したいユーザを選択→認証情報
のところでAccessKeyを確認できます。(ない場合は作成してください)
(文章だけだとわかりづらいかもしれないので、~~気が向いたら~~記事にします✍️)

- Secret Access Key
キーを作成するときにのみSecret Access Keyを確認できます。
わからない場合はAccessKeyをもう一度作成してください。

- Default region name
デフォルトでリクエストを送信するサーバのAWSリージョンを設定します。東京(ap-north-east-1)に設定しました。

- Default output format
出力結果の形式を選択します。デフォルトは"json"です。
json,yaml,yaml-stream,text,tableの中から選びます。(yamlはCLIのバージョン2で使用可能)

間違えて入力した場合でも、もう一度"aws configure"と打てば再設定できます。

<details>
<summary>リージョン名("ap-north-east-1"の部分)の確認方法</summary>
[公式ページ](https://docs.aws.amazon.com/general/latest/gr/rande.html)でも確認できますが、簡単な方法としてコンソール画面の右上の地域のところを確認すれば一覧が出てきます。
![リージョン名確認](https://gyazo.com/df3cbd105d227923d9d666c73d9230e0.png)
東京の場合は"ap-northeast-1"となっていますね😊
</details>

## プロファイル

設定のコレクションをプロファイルと呼びます。
下記コマンドを入力することでプロファイルに名前をつけることができます。

```bash
# 設定例
aws configure --profile produser

# あとは最初にconfigureと打ったときと同様に設定する
AWS Access Key ID [None]: AKIAI44QH8DHBEXAMPLE
AWS Secret Access Key [None]: je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: text
```

```bash
# プロファイル使用方法
aws s3 ls --profile produser
```

## 参考

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html

https://aws.amazon.com/jp/cli/
create-react-appでエラーが出る

## 環境

macbook pro 2015
macOs Bigsur

node v16.6.2
npm 7.20.3

##エラー内容

`npx create-react-app my-app`

したところ、ターミナルに以下のエラー。

```
error jest-diff@27.0.6: The engine "node" is incompatible with this module. Expected vers│
ion "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0". Got "14.4.0"                         │
error Found incompatible module.                                                         │
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.     │
`yarnpkg add @testing-library/jest-dom@^5.11.4 @testing-library/react@^11.1.0 @testing-li│
brary/user-event@^12.1.10 web-vitals@^1.0.1` failed
```

プロジェクトはできていたので、
`npm run start`
で起動したが、以下のエラーが出た。

```
Failed to compile
./src/reportWebVitals.js
Module not found: Can't resolve 'web-vitals' in '/Users/st/Documents/react_test/src'
This error occurred during the build time and cannot be dismissed.
```

## 解決方法

以下のように、--use-npmをつけるとうまくできた。

`npx create-react-app my-app --use-npm`

参考：
https://create-react-app.dev/docs/getting-started#selecting-a-package-manager

## 原因（予想）

create-react-appでの依存関係の解決がyarnで行われていた。

最近yarnを入れたからだと思うが、
npmで解決されてた依存関係をなぜかyarnで解決するように勝手に変更されてしまっていた。

ということだと思う。
Linux ubuntu SSH公開鍵設定時の操作 メモ

## 秘密鍵と公開鍵
|項目|説明|備考|
|----|----|----|
|公開鍵|サーバーに設置する|データを暗号化するための鍵。|
|秘密鍵|自分の端末で持っておく|公開鍵で暗号化されたデータを復号化するための鍵|

## RLoginで秘密鍵と公開鍵の作成
RLogin：Windows用のターミナルソフト
ターミナルソフト：ネットワークを通じて他のコンピュータに接続し、コマンドライン方式で遠隔操作するためのソフトウェア。

→Macは不要（ターミナルからログイン可能）

https://knowledge.sakura.ad.jp/3543/
https://soji256.hatenablog.jp/entry/2021/03/04/070000

### sshとsshdの違い
https://qiita.com/pocket8137/items/e504fa2481d5b9f0c064
　
### ユーザーの追加
```
adduser user_name
```

### sudo グループに追加
```
gpasswd -a user_name sudo
```
参考
https://qiita.com/white_aspara25/items/c1b9d02310b4731bfbaa
　

### rootユーザーへ昇格 / 元のユーザーに戻る【Ubuntu】

rootユーザーへ昇格

```
sudo su -
#  password
```

元のユーザーに戻る

```
exit
```
## vim
https://qiita.com/YuichiTanaka007/items/60899ed3d3369a70cca2


## 鍵ディレクトリの作成と権限変更
一般ユーザーのIDでログインしたあと、ホームディレクトリ(ログイン直後のディレクトリ)で以下のコマンドを実行

```
mkdir .ssh
chmod 700 .ssh
cd .ssh
```
### コマンドのオプション
|引数|内容|例|
|----|----|----|
|-v|コマンド実行結果を表示|chmod -vR 700 .ssh|
|-c|変更があった場合のみ、実行結果を表示|
|-R|再帰的に変更|chmod -R 700 .ssh|

```:コピーした公開鍵を張り付ける
vim authorized_keys
chmod 600 .ssh/authorized_keys
```
https://knowledge.sakura.ad.jp/3543/

#### 鍵の権限変更(change mode)
**パーミッション の変更**
chmod 700 .ssh
chmod 600 .ssh/authorized_keys

#### 権限の区分
|例|自分の権限|グループユーザーの権限|その他ユーザーの権限|対象|
|----|----|----|----|----|
|# chmod 700 .ssh|(7) rwx|(0) ---|(0) ---|.ssh|
|# chmod 600 .ssh/authorized_keys|(6) rw-|(0) ---|(0) ---|.ssh/authorized_keys|

#### 権限の種類
|r|w|x|-|
|----|----|----|----|
|読み込み(read)|書き込み(write)|実行(execute)|無し|

|0|1|2|3|4|5|6|7|
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|---|--x|-w-|-wx|r--|r-x|rw-|rwx|

#### 権限確認
```
ll  もしくは  ls -l
```
パーミッション

参考
https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95

## 一般ユーザーのアクセスを制限する
### ファイルのバックアップ / 書き換え

#### sshd_config ファイルのバックアップ

```
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.old
```
#### sshd_config ファイルの書き換え

```
sudo vi /etc/ssh/sshd_config

```

* 変更箇所
【注意】"# "はコメントなので、外す。
 * PermitRootLogin no
 * PubkeyAuthentication yes
 * PermitEmptyPasswords no
 * AllowUsers 



#### PermitRootLogin （rootユーザーのログイン許可・拒否）

|値|説明|
|----|----|
|yes|rootユーザのログインを許可|
|no|rootユーザのログインを拒否|
|prohibit-password|初期値 ≒　without-password|
|without-password|パスワードを使用したrootユーザのログインを拒否|
|forced-commands-only|rootユーザの直接ログインを拒否するが、root権限を使うコマンドのアクセスは許可|

|その他 パラメータ|説明|値|
|----|----|----|
|PubkeyAuthentication|公開鍵認証の許可・拒否|yes/no|
|PasswordAuthentication|パスワード認証の許可・拒否|yes/no|
|PermitEmptyPasswords |パスワードの空文字許可・拒否|yes/no|
|AllowUsers|ログイン可能ユーザー設定|yes/no|

```
#  AllowUsers user ユーザー名@192.168.1.10
```


#### ログファイル確認（参考までに）
```
sudo vi /var/log/auth.log

```
参考
https://www.server-memo.net/server-setting/ssh/allow-users.html

参考
https://qiita.com/ine1127/items/b50b9a8f831736cf14ea

## 設定の反映
```
sudo systemctl restart sshd

```

## Ubuntuの再起動

```
sudo reboot
```

## 注意点
SSH公開鍵をきちんと間違えずに設定しても、さくらVPSのVNCコンソールからパスワードでログインできてしまうが、これは問題ない。
→SSH設定とコンソールからのログインは無関係。

参考
https://qiita.com/YuichiTanaka007/questions/32e3f70f4210f4c69b4e
https://teratail.com/questions/183493
ユーザー定義のコスト配分タグ

##タグによってコスト管理する

###手順

①管理したいリソースにタグを付与する
②Billingコンソールにてタグをアクティブ化する
③Cost Explorerでタグごとにコスト管理できる

＊アクティブ化してからCost Explorerに反映されるまで最大２４時間かかる


###参照
https://aws.amazon.com/jp/blogs/news/cost-allocation-tag/
pyenvのパスが通らない

# pyenvのパスが通らない
手順通りにインストールして .zshrc(.bashrc)に

```shell
eval "$(pyenv init -)"
```
を書いても

```
$ which python
usr/bin/python
```

となってしまう

# 正解
```shell
eval "$(pyenv init --path)"
```

大半の記事は```eval"$(pyenv init -)"```と書いてあるがこっちが正しいらしい．
連想配列に関数を保存して呼び出す

キーボードショートカットを実装していて、関数を連想配列に保存して管理したくなった。

#ダメな例
連想配列にそのまま関数を保存すると、読み込み時に実行されてしまう。

```javascript:dame.js
const sc = {
	s:save(),
	l:load()
};
sc['s']; //save()を呼び出したいけど失敗
```
#成功例

```javascript:ok.js
const sc = {
	s:function(){save()},
	l:function(){load()}
};
sc['s'](); //save()が実行される
```

#ショートカット実装時のtips

```javascript:shortcut.js
$(function(){
	const sc = {
		s:function(){save()},
		l:function(){load()}
	};
	$(document).on('keydown',function(e){
		if(e.ctrlKey){		//コントロールキー押下判断
			var key= e.key;
			shortcut(e,key);
		};
	});
	function shortcut(e,key){
		if($.isFunction(sc[key])){	//ショートカットが登録されていれば
			sc[key]();		//ショートカットを実行して
			e.preventDefault();	//ブラウザ標準のショートカットをキャンセル
		};
	};
});
```

#ショートカット実装のための参考リンク

https://qiita.com/pochman/items/f4657f948aebcfc411f6
[AppleScript] Chrome Full Screen Mode


```
on run argv	
	set theapp to "Google Chrome"

	if application theapp is running then
		return
	end if
	
	if item 2 of argv is "false" then
		set toggleOnFull to true
	else
		set toggleOnFull to false
	end if
	
	tell application theapp
		activate
		delay 2
		(* 
      Initially from http://stackoverflow.com/questions/8215501/applescript-use-lion-fullscreen
    *)
		set isFullScreen to false
		tell application "System Events" to tell process theapp
			set isFullScreen to value of attribute "AXFullScreen" of window 1
		end tell
		--display dialog "var " & isfullscreen
		
		if isFullScreen is toggleOnFull then
			tell application "System Events" to keystroke "f" using {command down, control down}
			delay 2
		end if
	end tell
end run

```
Angular11 で Firebase Authを動作確認するため行った最小限の事メモ

FirebaseのAuth機能を簡単に実装しようとしてインターネットで検索したところ、ほとんどの資料のバージョンが古く、期待通りに動かなかったので、いろんな資料を参考しながら自分でまとめてみました。

この資料が書かれた時期：
2021年8月14日（土曜日）

インターネットの資料を参考した時うまくいかなかったところ：
Firebaseの関数が結構更新されていて、インターネットで検索したサンプルではエラーになってしまった。

自分みたいにうまく行かなくて悩んいる方には少しでもヒントになればと思います。

FirebaseのWeb上での設定は割愛します。

## ライブラリーのインストール

```
npm install firebase @angular/fire --save
```

そして開発環境でのFirebaseの初期化

```
firebase init
```
詳細は省略させていただきます。

## アクセス用の環境設定及びモジュールに初期化追加

environment.tsにfirebaseアクセス用情報を追加

```js
export const environment = {
  production: false, 
  firebase: {
    apiKey: "略",
    authDomain: "略",
    databaseURL: "略",
    projectId: "略",
    storageBucket: "略",
    messagingSenderId: "略",
    appId: "略",
    measurementId: "略"
  }
};
```

そしてモジュールに追加

```js
...
import { AngularFireModule } from '@angular/fire';
import { AngularFirestore } from '@angular/fire/firestore';
import { environment } from '../environments/environment';
...

imports: [
    ... 
    AngularFireModule.initializeApp(environment.firebase),
  ],
providers: [
    ...
    AngularFirestore
]

```


## サービースを追加

```
ng g c shared/services/auth
```

追加したサービースの中に追加した内容：

```js
import { AngularFireAuth } from '@angular/fire/auth'; //追加
import { Router } from '@angular/router'; //追加
...

  constructor(
    public afAuth: AngularFireAuth,
    public router: Router
  ) { }

  //ログイン
  LogIn(email:string, password:string){
    this.afAuth.signInWithEmailAndPassword(email, password)
    .then(value=>{
      console.log("Successfully logged in");
      this.router.navigate(['/member']);
    })
    .catch(error=>{
      console.log("Something wrong:", error.message);
    });
  }

  //ログアウト
  LogOut(){
    this.afAuth.signOut()
    .then(() => {
      console.log("Logged out");
      this.router.navigate(['/login']);
    }).catch((error) => {
      console.log("something wrong:", error.message);
    });
  }

```

## コンポーネント側

TSファイル

```js
import { AuthService } from 'src/app/shared/services/auth.service';

...

  constructor(
    public authService: AuthService
  ) { }

```

HTML のコード（Bootstrap5を使っています）

```html
<input
  type="text"
  placeholder="user id"
  #userName
  required>
<input
  type="password"
  placeholder="password"
  #userPassword
  required>
<button
  type="button"
  class="btn btn-primary"
  (click)="authService.LogIn(userName.value, userPassword.value)">
Login
</button>
```

一応これでログイン確認ができました。

もし不明なところありましたらコメントいただくと詳細内容を追加していく予定です。
php wordpress 対応バージョンに関するエラー

## はじめに

AWSの下記教材の演習で、EC2にwordpressを公開する際にエラーが発生した。

`・ゼロからわかる Amazon Web Services超入門`

解決できたので、対応方法を簡単にまとめる。



## 事象

同誌の１８１ページに従い
`http://パブリックIP/wp-admin/install.php`をブラウザに入力するも
`httpステータス：500のエラー`が返される。

ここに至るまで
`・EC2インスタンス作成`
`・ssh接続でリモート(Webサーバ)に繋ぐ`
`・apache, mariaDB, phpをインストール`
を完了している。



## 原因

何となく、教材に写っているデモ画面のURLを
ブラウザに入力してみると、エラー文が出てきた。
そこでインストールしているphpのバージョンが原因だと判明する。

・打ち込んだURL
`http://自分のパブリックIPアドレス/wp-admin/setup-config.php`

・エラー文
`Your server is running PHP version 5.4.16 but WordPress 5.8 requires at least 5.6.20.`
→ このwordpressには`php5.6.20以降のバージョン`を必要とする　らしい…



## 対処

PHPのリリース情報を調べると、私がインストールしていたphp5系は
2019年1月にサポートが終了しているよう。

https://www.php.net/releases/

■サポート終了する文言を抜粋
`Support for PHP 5 has been discontinued since 10 Jan 2019.Please consider upgrading to 8.`

という理由から、現行の安定版（7.4系）でphpをインストールし直すことに。

phpインストールのコマンドは、別書籍（AmazonWebServices基礎からのネットワーク&サーバー構築）の８−３章を参考にした。

一連のコードは以下の通り。

```:ターミナル

まず、インストール済みのものを確認
% yum list installed | grep php

さきほど、返答されたものを削除する
% sudo yum erase php php-cli php-common php-gd php-mbstring php-mysqlnd php-pd

7.4系でphpをインストール
% sudo amazon-linux-extras install php7.4

インストールされたか確認
% yum list installed | grep php

```

念のため、関係があるかもしれないので
インストール済みだったapache,mariaDBを再起動しておく。

```言語:ターミナル

% systemctl restart httpd

% systemctl restart mariadb

```



## 再度ブラウザで表示できるかトライする

ブラウザに`http://パブリックIP/wp-admin/install.php`を入力してみる！

するとwordpressの言語選択の画面が表示された！

ということで、成功している様子。



## その他参考記事

https://qiita.com/aiiro_engineer/items/821c54d9b986b04ace00

https://techacademy.jp/magazine/19321


##終わりに

アプリはバックエンドにrailsを使っているが、
今回のphpの件で、バージョンの相性があることを理解した。

他アプリを一部利用する場合など、複雑なアプリ構成になれば
こういったバージョンが合わない問題が多く出てきそうなので注意しよう。

最後までお読み頂き、ありがとうございました。
Java から PostgreSQL JDBC Driver を使って PostgreSQL に接続してみる

Java から PostgreSQL JDBC Driver を使って PostgreSQL に接続するプログラムの作成方法について説明します。

環境は CentOS 7 または 8、PostgreSQL 9.6 以降を対象とし、PostgreSQL に接続できる状態になっていることを前提とします。PostgreSQL のインストールや設定がまだであれば、インストール方法は [こちらの記事](https://qiita.com/tom-sato/items/e1903cb974fb6c6d5664)、ローカルホスト以外からの接続受けつけに必要な設定方法は [こちらの記事](https://qiita.com/tom-sato/items/d5f722fd02ed76db5440) を参照してください。

1. Java、PostgreSQL JDBC Driver をインストールします。

    ```shell-session
    $ sudo yum -y install java-1.8.0-openjdk-devel postgresql-jdbc
    (省略)
    Complete!
    ```

1. プログラムを作成します。

    プログラムの内容はデータベースの一覧を出力するというものです。エラー処理は行っていません。

    ```java:TestJDBC.java
    import java.sql.*;
    
    class TestJDBC {
    
        public static void main(String[] args) throws Exception {
            Class.forName("org.postgresql.Driver");
            String url = "jdbc:postgresql://localhost:5432/postgres";
            String username = "postgres";
            String password = "password";
            Connection conn = DriverManager.getConnection(url, username, password);
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT datname FROM pg_database");
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
            rs.close();
            st.close();
            conn.close();
        }
    }
    ```

    変数の `url` には `jdbc:postgresql://ホスト:ポート/データベース` 形式で接続先、`username` にはユーザ名、`password` にはパスワードを指定します。ご自身の環境に合わせて書き替えてください。

1. プログラムをビルドします。

    ```shell-session
    $ javac TestJDBC.java
    ```

    エラーメッセージが出力されず、クラスファイル `TestJDBC.class` が生成されれば、プログラムのビルドは成功です。

1. プログラムを実行します。

    ```shell-session
    $ java -cp .:/usr/share/java/postgresql-jdbc.jar TestJDBC
    postgres
    template1
    template0
    ```

    `-cp` オプションにはコロン `:` 区切りでクラスファイル格納先のパスを指定します。ここではカレントディレクトリと PostgreSQL JDBC Driver の jar ファイルを指定しています。

    エラーメッセージが出力されず、データベースの一覧が出力されれば、プログラムの実行は成功です。

以上でプログラムの作成は完了です。