OmniAICreator/Qiita-1.07M huggingface dataset:
iPad ssh clientからfish shellの環境にアクセスできない

iPadのsshクライアントでfish shellをログインシェルにしている環境にログインできなかったという小ネタです。

# 起きたこと

## 環境
fish: 3.1.2
theme-bobthefish
iTerminal: Free 8.80 build 1

## 事象
[iTerminal](https://apps.apple.com/jp/app/iterminal-ssh-telnet-client/id581455211)というssh clientを使って、ログインシェルがfishの環境にアクセスしたところ、以下のようなエラーが出て接続を確立できませんでした。

~~~bash
Assertion failed: (!find_prompt_layout(input) &&  
 "Should not have a prompt layout for this input"),  
 function add_prompt_layout
~~~

# 対処

fishのバージョンを上げることで対処できました。
参考:[Should not have a prompt layout for this input #7528](https://github.com/fish-shell/fish-shell/issues/7528)

Canonicalの配布パッケージが今現在3.1.2のため、ppa:fish-shell/release-3を追加してupgradeすればOKです。2022年2月時点で3.3.1–1がインストールされました。
(試してませんがtheme-bobthefish使わず地味なプロンプトにしとけばログインできたはずです)

# その他

iTerminalはフォントを変更できないので、fishのバージョンを上げるとログインはできるようになったものの結局綺麗にプロンプト表示できませんでした。
フォント変更できないiPadのクライアントは同様に全滅だと思われます。

iPadへのpowerline系フォントインストール自体は[adobe creative cloud](https://termius.com/)を使って可能でした。
[Font Families](https://github.com/powerline/fonts#font-families)
Noto Mono・Space Monoあたりは含まれているっぽいです。フォント入れるだけなのになんでこんな大掛かりなことやらなきゃならんのだと思ってしまいますが・・・

尚、[Termius](https://termius.com/)はpowerline系フォントを含んだパッケージ構成になってます。有料です。
PHP【クラス入門】フレームワーク学ぶ前に見ると良い動画集

# フレームワークを学ぶ前に見ると良い動画として用意

:::note info
PHPのクラス「クラス・アクセス修飾子・継承・静的」の導入部分を収録しております。
 「 全て理解 」ではなく「 フレームワークに登場する知らない書き方に慣れる 」がポイントです。
:::

### 自己紹介
ジーズアカデミー学校長（デジタルハリウッドでも教鞭をとる）山崎と申します。
[ジーズアカデミー](https://gsacademy.jp/mentor/)は開校6年目のデジタルハリウッドが運営する「起業家エンジニア養成スクール（卒業生が6年で69社起業し総資金調達額80億5,620万円と卒業生が頑張っている学校）」です。
**なぜ動画を公開したのか？**
今回、私の授業（初級者向け）をYoutube配信したものをまとめました。
画質は「コロナ」が始まった当初に自宅で初めて動画撮影するようになったので、あまり画質等は最高とはいえませんが、初学者には入りやすい内容なのではと思います（自分でいうのもあれですが・・・）。
全国のプログラミング初学者・初級者の皆さんの底上げになればと思い公開させていただきます。



### 動画の内容レベル
**内容は「基礎を学んだ」レベルに合わせています。
PHPの「基礎」のところはプロゲートやドットインストールで学んだけどClassがわからないって人用です。**
また「 デジタルハリウッド / ジーズアカデミー / 大学 / 大学院 」で私の講義動画を見たことがある人はその追加講義として見ていただければと思います。
※他の学校、提携校の皆さんもご活用ください！




 
-----

## ◆PHP入門「Class基礎」

1~3の動画を見たら5の演習をやるとClassの理解につながりやすいようです。

| タイトル | 動画🔗 | 
| ---- | ---- | 
| クラス基礎01(class, アクセス修飾子, コンストラクタ) | https://youtu.be/wi0BAL2Pazg |
| クラス基礎02(アクセス修飾子, 継承って？) | https://youtu.be/tA5IOC2ZIkw |
| クラス基礎03 static(静的メソッド・静的プロパティって？) | https://youtu.be/l8JAJ9UH2Jk |
| クラス基礎04 namespace(名前空間とは？) | https://youtu.be/HNTvPbU9Gek |
| クラス基礎05 DBクラスを考えて作ってみよう(演習) | https://youtu.be/21j1l0dWvYk |

-----

## ◆サーバー・データベース基礎知識


| タイトル | 動画🔗 | 
| ---- | ---- | 
| データベース 「 基本から解説」 | https://youtu.be/Er4JbQXyTxM |
| クラウドとレンタルサーバー何がちがうの？「！AWS？Azure？GCP」12分で解る | https://youtu.be/GFr6eeY8V7M |
| Linuxコマンド超入門 | https://youtu.be/-7ZDeEYgrh8 |
| **New** VSCodeからMySQLを操作「 MySQL Shell （拡張機能）」 | https://youtu.be/3EE60OTb2Xw |

-----

## ◆PHP開発環境準備＋Valitron


| タイトル | 動画🔗 | 
| ---- | ---- | 
| PHP初めての開発環境（ PHP8/Windows編 ) | https://youtu.be/yTz2GIvLwdo |
| HTML/CSS/JS/PHP..」なぜこの順番で学ぶ？ | https://youtu.be/aEDEl9ecdmM |
| 【入力チェックは必須！】調べながら覚えるValitron| https://youtu.be/7z9WVPnw6MM | 

-----

## ◆Laravel開発環境準備


| タイトル | 動画🔗 | 
| ---- | ---- | 
| Laravel/PHP「PaizaCloud」初学者でも挫折しない開発環境 | https://youtu.be/WHXa4llB488 | 
| AWS Cloud9＋Amazon Linux2で「 Laravel 9.x 」開発環境構築| https://youtu.be/Fhh5ornkeJg | 
| AWS Cloud9＋Amazon Linux2で「 Laravel 6.x 」開発環境構築 | https://youtu.be/XGDS6TRWDLU | 

-----


## ◆Laravel便利「LaravelDB.com」
こちらのツールは私が開発し、運用しております。
使いたい人は無料ですので、使ってみてください。

| タイトル | 動画🔗 | 
| ---- | ---- | 
| LaravelDB.com 基本操作-DEMO | https://youtu.be/sHt5v4XOWbc | 

-----


## ◆JavaScript【 応用力が身につく！実践トレーニング 】 動画集
別で、JavaScriptのまとめ動画もQiitaにアップしてますので、そちらもおススメしております。
こちらはかなり数があるので、是非JavaScriptで応用できるようになりたい人は見てください。
きっと役にたつはずです。
[JavaScript【 応用力が身につく！実践トレーニング 】 動画集](https://qiita.com/daisu_yamazaki/items/69c84b4990b02784efe9)


##【遅咲きエンジニア👉山崎先生【 プログラミングTips! 】
役立ちましたか？
- SNSでの拡散
- 学校で「使わせてもらってます」
- 応援メッセージ
など、お願いできればと思います!!
※必須ではありませんが今後のやる気につながります(#^^#)

学校等での講義依頼も受けてますので気軽にお声がけください
また、基礎から私たちから学びたいと言う人がいれば、ぜひ学校へ来てください。

**今後も講義動画増えたら、こちらを更新していきます。
ブックマークしていただければ幸いです。**


以上
AWS Secrets Manager ってなに？

## 勉強前イメージ

パスワードを持ってくれるサービス？
雰囲気知ってるけどちゃんと知らんかも

## 調査

### AWS Secrets Manager とは

様々なAWSのサービス、環境、アプリケーションに接続するためのパスワードなどの機密情報を管理するためのマネージドサービスです。
AWS CLIやAPI、SDKを使ってアクセスが可能です。

どういうときに使われるかと言うと、
DBへアクセスしデータを取ってくるあプリケーションを作る際、アプリケーションにDBへの接続するための情報(パスワード)などを記載する必要があります。
このアプリケーションをバージョン管理ツールなどで管理している場合
パスワード情報が見れる状態になってしまい、セキュリティ的にも良い状態ではないです。
また、機密情報のローテーションが難しいため漏洩した際のセキュリティリスクが増えてしまいます。

### AWS Secrets Manager の特徴

- アプリケーションで接続の際に機密情報を取得

アプリケーションで機密情報を持つのではなく、都度取得します。
履歴を保つ場合もあり、複数保持することもできます。

- 格納できる機密情報が多彩

機密情報は以下のような情報がJSONで格納でき、最大4096バイトのテキストを格納できます。

・ サーバ名
・ IPアドレス
・ ポート名
・ DB接続情報

- ローテーションが可能

スケジュールに基づいて機密情報のローテーションを行うことができます。
lambdaファンクションによって定義されます。
AuroraやRDSは機密情報のローテーションとDBの接続情報のローテーションは統合されています。

## 勉強後イメージ

IPアドレスまで格納できるんだ・・・パスワードだけじゃないのね。。。

## 参考

- [機密情報を一元管理できる「AWS Secrets Manager」とは？概要と主要機能、動作原理、各種リソースまとめ](https://dev.classmethod.jp/articles/about-secrets-manager/)
- [AWS Secrets Managerによる機密情報の管理](https://business.ntt-east.co.jp/content/cloudsolution/column-84.html)
SPSS Modeler ノードリファレンス 7-3 データベースエクスポート

# 7-3 データベースノード[エクスポートタブ]
<img width="200" alt="107_89データベースExport.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/72bfc2a5-5961-1b85-e40b-0affc9e0747e.png">

## 1.ノードの目的
データをデータベーステーブルとしてエクスポートします。新規テーブルの生成や既存テーブルへの挿入・結合が可能です。外部ローダーを利用して高速に書き込むことができます。

## 2.解説動画（60秒）

<iframe width="560" height="315" src="https://www.youtube.com/embed/DMo_m9k3Rdk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 3.クイックスタート

DBのテーブルを読み込むために、ODBCの設定をあらかじめ行います。
![スクリーンショット 2022-02-18 18.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/61587faa-cd25-6d07-d246-e3098059c91d.png)
![スクリーンショット 2022-02-18 18.11.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/24910cd8-dadc-8443-def4-83f584698d9b.png)

[可変長ファイル]入力ノードに[データ型]、[データベース]の順で接続します。
＊サンプルデータ（CSV）は[5.参考情報]をして参照ください。
![スクリーンショット 2022-02-19 11.01.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a869edbe-c241-2b17-883b-3de05e47903e.png)

[データ型]を編集します。[値の読み込み]ボタンを押して値を確定します。
![スクリーンショット 2022-02-19 11.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a7b6efdb-1724-c972-aa61-b8652ded52f3.png)

[データベース]ノードを編集します。ODBCで登録済みのデータソースを選択して新規生成するテーブル名を記述します。
![スクリーンショット 2022-02-19 11.10.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f70263fb-98c0-924a-250e-e5fecfeb0808.png)

[データベース]を実行します。テーブルを生成するためのSQLが自動で生成されているため紫色にノードが発光します。
![スクリーンショット 2022-02-19 11.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/697296cd-cde0-98b1-aa89-ebe4c52f83f9.png)

データベース内に新規テーブルが作られ、[データベース]入力ノードが自動生成されます。
![スクリーンショット 2022-02-19 11.18.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/44ba1535-13c9-6c9d-4f05-9973907964a1.png)


### データベースノードのヒント
データベース入力ノードの記事にODBC接続に関する情報やSQLプッシュバックについて関連情報を掲載しています。

https://qiita.com/416nishimaki/items/ee13873b9d78268d648a


## 4.Tips

#### DBキャッシュ

https://qiita.com/kawada2017/items/ea4f0e1b068c9bb152e5



## 5.参考情報

#### 利用データ

SPSS Modeler インストール時にDemosに同梱されているbank_customer_data.txt
以下の赤枠ボタンでDemosフォルダへ直接参照します。
![スクリーンショット 2022-02-19 10.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2bee559a-a6e4-721a-a4b4-30a312283b68.png)


#### ノードのヘルプ

https://www.ibm.com/docs/ja/spss-modeler/18.3.0?topic=nodes-database-export-node

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/items/4bf813e6cba84b2a1008

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee
Mac Appでサーバーからのデータ取得がエラーになるときの対処法

#MacAppでURLSessionをするときには、設定が必要です

#A server with the specified hostname could not be found
何も設定せずにURLSessionでサーバーのデータを取得しようとすると、上記のエラーが出ます。

#設定
AppのTargetのSigning&Capabilitiesで、App SandboxのOutgoing Connectionsにチェックを入れます。
![スクリーンショット 2022-02-19 11.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/05abd62b-010e-4efe-90bf-c1108b7e5180.png)

これで、サーバーからデータを取得することができるようになります。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[Golang] Cloud Runで構造化ログを出力できるように実装してみた


## やったこと

* goの標準log出力をGCPの構造化ログのフォーマットで出力するようにしてみた。
* Cloud Runにデプロイして確認してみたところ無事ログが各ログレベルで出力されるようになった。
* 標準logライブラリのファイル名表示などされなくなったが、ログの出力をgrepすれば調査はできるので一旦よしとします。

## 課題

* サービス運用では同時に複数のアクセスが考えられるため、traceId等でログを追跡できるようにする必要があります。アクセスがたまにしかないようなフェーズではいいかもしれないけど、`X-Cloud-Trace-Context`を使用してリクエストとログを一意にできるようにすることは必須だと思うので今後やる。
* Cloud loggingなどの仕組みをつかってERRORのログをSlackに通知する仕組みとか作ってみようと思います。


## 内容ははてなブログに掲載してます

https://moritomo7315.hatenablog.com/entry/golang-gcp-log-output
pandasで値を得る時の備忘録

pandasでcsvやtsvを読み込みして、
中の値を取り出そうとした時
数字っぽい文字列を扱う時にはまったので備忘録

# pandasでtsvを読み込む

``` .py
import pandas as pd
df = pd.read_csv(filepath_or_buffer=cvd.check_voice_path, encoding="utf-8", sep="\t")
```
文字コードと区切り文字指定して読み込む
df(データフレーム)という形式で得られる

# pandasで、行をみつけて読みこむ場合
特定の列の項目と一致するものを探して
その行の要素にアクセスする

| text_id | text_jp | text_en |
|:-:|:-:|:-:|
| 1000  | こんにちわ  | hello  |


``` .py
def get_row(df, text_id):
    if df.empty:
        return None
    if df[df['text_id'] == int(text_id)].empty:
        return None
    return df[df['text_id'] == int(text_id)].iloc[0]

row = get_row(df, "1000")
print(row["text_jp"])

```
この例では、データーフレームを渡して一致したデータ行を得て
見つけたらその行の列の項目にアクセスしている。

一致するかどうかをチェックするとき、
セルの内容に応じて　型が勝手に決まるので、
この場合intにキャストして、一致しているか調べている。
もしtext_idのところに文字を入れてある場合は、
文字でも一致しているかチェックする必要もあるかも。

# セル入力のヒューマンエラー
セルを入力する人が、数字か文字か曖昧だったりすると素直に比較が通らないなんてことがあったりするかもしれない

例えば、text_idにバリエーションがついて
1000_a 1000_b といった文字列になってしまっているとか起こりうる。

他にも
- 間違えて全角文字が入っている
- 指示やコメントみたいな想定フォーマットと異なる文字が入っている
- 空欄

こういうのが起こりそうな場合は、いったん整形する処理を入れてしまうのも手だったりする。
フォーマットチェックで、異なる書き方している行はスキップするなど。

なるべく綺麗なデータで処理するのが効率が良くなる。
Jetson NanoでOpenCV 4.5.xをmakeするとSegmentation faultになる件について

* Jetson Nano 4GB
* JetPack 4.6

参考：https://www.koikikukan.com/archives/2017/05/26-000300.php

## はじめに
Prob：OpenCV 4.5.xのmake中に「c++: internal compiler error: Segmentation fault (program cc1plus)」が生じてしまいます。
Solve：スタックサイズを無制限に設定することで回避できました。

## パッケージの更新とスワップ領域の設定など
sudo apt update
sudo apt upgrade
（Automatically restart Docker daemon? -> No）

sudo apt install nano

sudo apt install dphys-swapfile

sudo nano /sbin/dphys-swapfile

```:/sbin/dphys-swapfile
CONF_MAXSWAP=4096
```
sudo nano /etc/dphys-swapfile

```:/etc/dphys-swafile
CONF_SWAPSIZE=4096
```

sudo sh -c 'echo 128 > /sys/devices/pwm-fan/target_pwm'

reboot

### スタックサイズの確認と設定
ulimit -a

```
stack size (kbytes, -s) 1024
```

sudo nano /etc/security/limits.conf

「ubuntu」ユーザーのスタックサイズを無制限に設定します。

```/etc/security/limits.conf
# End of file
nvidia hard stack 1024
nvidia soft stack 1024
ubuntu hard stack unlimited
ubuntu soft stack unlimited
root hard stack 1024
root soft stack 1024
```

###OpenCVのインストール
wget https://github.com/Qengineering/Install-OpenCV-Jetson-Nano/raw/main/OpenCV-4-5-5.sh
sudo chmod 755 ./OpenCV-4-5-5.sh
./OpenCV-4-5-5.sh
Python 機械学習 入門 vol.1 - データ分析精度に関する注意

# 機械学習入門
こんにちは！Kazuyaです。

クラウドベンダーのカスタマーサクセスにいながら、
広範囲の知識を得るために、
経験の浅い機械学習のコンテンツを学習中！

覚書をこのタイトルのシリーズでやっていこうと思います。

# データクレンジングにおける注意の学び  

Pythonを使いながら機械学習をしていると、
データクレンジング、データビイングなどなどをする必要があり。

その中で、分析したいデータセット・データフレームに、
欠落値があった場合、その値を以下のいずれかで処理。

- 欠落値があるデータ行をDropnaで削除してしまう。
- replaceで欠落値を平均値や、より一般的な値で置き換えてしまう。
- そのまま処理する

このいずれにするのかというのによって、
得られる結果が変わってきます。

「そのまま処理する」となると、NAだらけになり統計が取れなくなる可能性がある反面、
代替の値を入れてしまったことによる不確実性を避けられる別の案を検討することができます。

平均値を使うと、それは欠損していないデータをもとに、平均を出しているため、
例えばデータの４０％が欠損していないデータだった場合、
標本全体の半数を超えるデータは、半数以下のデータの平均値を使うこととなり、
そのデータを用いた分析は果たして統計として正しいのか、精度に疑問が出てきます。

いかようにして、機械学習の精度を高いものにするかは、
やはり「データ」が資産であることを理解の上で、
DataFabricが今のCognitiveなFeatureを追い求める時代には、
必要不可欠。

たかがログ、されどログということを改めて理解したシステム設計が必要ですね。

と、導入はこんなところで、今後は実践編を。

See you next time!
PHP、データベースにうまく接続できなかった事例

今回はPHPのソースコードからデータベースに接続するときに簡単なミスで生じる内容を報告します。

入力してもエラー表示がされずに、データベースに反映しないという内容です。

PHP　version 7.4
10.4.22-MariaDB(phpmyAdimin)を使用。


（ケース)データベースに接続文字列

```
$dsn = "mysql:dbname = php_work;host = localhost;charset = utf8";
// エラー表示はされないが、接続はされない
```
【原因】イコール（＝）の間にスペースが入っている。
この部分を見やすくしたいがために、改行やスペースを入れてしまうと結果的に、接続が出来なくなる

正しくは、
__mysql:dbname=test;host=localhost;charset=utf8mb4(スペースを入れない）__

```
$dsn ="mysql:dbname=test;host=localhost;charset=utf8mb4";
// すべてを隙間を入れずに入力すること。
```

簡単なところだが、意外にエラー表示されずに、うまくいかないときは歯がゆくなります。
まぁおそらく、ほとんどの人が、コピペで対応するからトラブることはないかもしれませんが、
トラブった代表として、ここに報告いたしますね。
[GitHub]マージしたブランチを自動で削除する方法

マージした後、ブランチを削除するのを忘れることがあるので、調べてみたらGitHbuで設定できることを知ったのでメモ。

##やり方
###1.開発中のリポジトリでSettingsにアクセス
###2.Pull Requestsの項目にある[Automatically delete head branches] にチェックを入れる
![effc25b55efeba5bd2530de65233a027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1374322/67955da4-72bd-7faa-7e66-6caba549459f.png)

これで設定完了です！
【備忘録】BEM、SMACSS、FLOCSSについてまとめてみた

# はじめに
こんにちは、まさやんです。

■運営サービス一部
https://smart-wordpress.com
業界特化、スマートなWordPressテーマ販売サイト『SMART WP』

今回は、学習の備忘録としてCSS設計の手法である**BEM**、**SMACSS**、**FLOCSS**についてまとめてみたいと思います。

# BEM
#### BEMってなに？
「**Block Element Modifier**」の略です。
Block：大元の要素
Element：Blockの中の要素
Modifier：変化の状態を表す要素（active、大きさ、色など）
という感じです。

#### ルール
「**Block__Element--modifer**」のように__（アンスコ2つ）と--（ハイフン2つ）で繋ぎ合わせて、クラス名をつけます。
このように、クラス名を見れば、**どの**要素で**どんな状態**の要素なのかがわかるようになります。

#### サンプルコード
```html:HTML
<ul class="menu">
  <li class="menu__item--large">Large Item</li>
  <li class="menu__item--active">Active Item</li>
</ul>
```
```sass:SASS
.menu {
  list-style-type: none;
}
.menu__item {
  width: 80px;
  margin-bottom: 12px;
  text-align: center;
  &--large {
    width: 100px;
  }
  &--active {
  color: #545454;
  background: #fff;
  }
} 
```
#### メリット
前述したとおり、クラス名を見ただけでどんな要素かが分かります。最初は、長くてごちゃごちゃしてると思いますが、コードの**可読性**が上がり、後々の**保守性**、にも繋がります。

# SMACSS
### SMACSSってなに？
「**Scalable and Modular Architecture for CSS**」の略です。
CSSを**５つに分類**して、書きましょうというCSS設計の手法になります。

#### ルール
Base：サイト全体に影響するもの（リセットCSSや変数の定義など）
Layout：ページのレイアウト（ヘッダー、フッターなど）
Module：再利用可能なパーツのこと（繰り返し使うボタンなど）
State：状態によって見た目が変化するもの（色の変化など）
Theme：テーマごとのスタイルのこと（サイトをダークモードにガラッと変えるなど）
このような**５つのディレクトリ**を作成し、各ディレクトリにファイルを保存していきます。

命名規則は、「**１ページに１度しか登場しないレイアウト**」についてはIDセレクタが容認されています。例えば、ヘッダーやフッター、サイドバーなんかがこれに当たります。
また、LayoutカテゴリやStateカテゴリにあたるクラスには、**接頭辞**をつけることが推奨されています（.l-header、.is-panel-activeなど）。
※.is-activeなどと命名してしまうと、active状態にしたい要素が他にもあったときにどれがどれだかわからなくなってしまうので、どの要素のことなのかをしっかり記述する

#### メリット
共通で使えるものは共通化できるので**再利用性**が高く、効率的な開発が行えます。
また、ディレクトリごとに分けてるので見やすく、管理しやすいです。
さらに、優先順位がはっきりしているのでCSSがこんがらがりにくくなっています。

# FLOCSS
#### FLOCSSってなに？
BEMやSMACSSなど色んなCSS設計の手法を取り入れたハイブリッドなものです。
比較的新しく、日本人の方が考案したもので、ドキュメントも日本語でありがたいです。こちらの[「柴犬でもわかるFLOCSS」](https://mamehiko.booth.pm/items/1033385)は、僕も読ませていただいたのですが、非常に分かりやすくておすすめです。

#### ルール
Foundation：デフォルトのスタイル（リセットCSSや変数の定義など）
Layout：ページのレイアウト（ヘッダー、フッターなど）
Object：繰り返し使われるもの
Component：再利用できるモジュール
Project：プロジェクトごとのスタイル
Utility：装飾に関するもの

```
SCSS
  ├─Foundation
  | ├─_base.scss
  | └─_reset.scss
  ├─Layout
  | ├─_header.scss
  | └─_main.scss
  └─Object
    ├──Component
    |  └─_btn.scss
    ├──Project
    |  └─_articles.scss
    └──Utility
       └─_margin.scss
```
ディレクトリ構成はこんな感じで、まず、「Foundation」、「Layout」、「Object」の３レイヤーに分かれ、さらにObjectレイヤーの子レイヤーとして、「Component」、「Project」、「Utility」の３つに分類されます。
命名規則は、**BEM**が採用されています。また、SMACSSと同様にそれぞれのカテゴリにあたるクラスには、**接頭辞**をつけてあげます。（.l-headerや.c-btnみたいな感じ）

#### メリット
ディレクトリ構成をきっちり決めてあげることで、どのディレクトリに編集したいファイルがあるのかを**予測しやすく**、**メンテナンス性が上がる**ので、複数人で開発するときに、FLOCSSの恩恵をより感じられるのではないかと思います。

# おわりに
最後まで、お読みいただきありがとうございます！
個人開発では、FLOCSSを採用しているのですが、慣れるまではglobでファイルをまとめるのに戸惑ったり、クラス名をどう命名するかにいちいち悩んだりととても大変でした。（今でも悩みますが。。。）
実際、CSS設計に明確な正解はなく、現場によってルールが決まっているということなので、基本的なことは頭に入れて、柔軟に対応したいと思います。

これからも学んだことをどんどんアウトプットしていきたいと思います。
それでは！
PHP上から順に実行されることを意識する。

rand()関数を使ってスコアに応じてメッセージを変更するプログラムを書こうとしたが、以下のようにrand()関数をwhile分の外（上）に出していたため、while文で10回繰り返す処理に全て同じスコアが入ってしまい意図しない結果となった。

```PHP
<?php
$try = 1;
$score = rand(0,100);
while ($try <=10){
    echo $try.'回目'.' ';
    echo $score.'点'.' ';
    if($score > 60){
        echo '合格！';
    }else{
        echo '不合格。';
    }
    echo "<br>";
    $try++;
}
?>
```


while文の処理1回ごとに異なるスコアを出せるようにrand()関数をwhile文の中にセット。

```PHP
<?
while ($try <=10){
    $score = rand(0,100);
    echo $try.'回目'.' ';
    echo $score.'点'.' ';
    if($score > 60){
        echo 'やったね！合格！';
    }else{
        echo 'ざんねん、不合格。';
    }
    echo "<br>";
    $try++;
}
?>
Google ColaboratoryでPython + OpenCVを試してみる

#はじめに
以前の記事でOpenCVの速さに驚愕し、手持ちのデバイスで試していたのですが、Google ColabotoryでOpenCVが出来る、しかもGPUアクセラレーションつきで、ということでやってみました。

以前の記事 

https://qiita.com/tnar-f/items/719cc3b018a7f1c761b0

#環境構築
環境構築は@croquette0212さんの記事を参考にしました。

https://qiita.com/croquette0212/items/36cadce5bf0fb703ed19

このあと、ランタイムメニューのランタイムのタイプを変更からハードウェアアクセラレータをGPUに変更しておきます。

実験に必要なビットマップをカレントディレクトリにコピーします。
1920 x 1200グレースケール、約230万画素のビットマップファイルです。

自分のマシンからColaboratoryにファイルをコピーする方法は@5at00001040さんの記事を参考にしました。

https://qiita.com/5at00001040/items/d7867974d2fd1d21dbbf

#実行

以前の記事で使ったコードをコピペして実行します。

以前の記事

https://qiita.com/tnar-f/items/b5d5ae1a2acc31d63ce8

3x3近傍の平滑化処理(Blur)を20回連続して行い、かかった時間の平均を表示します。

![スクリーンショット 2022-02-19 8.50.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517091/1817a336-95cd-9170-f48c-9005e3b1b2a4.png)

#1.4ミリ秒!
じゅうぶん速いですが、うーん、どうなんでしょう？ 
(´^｀).｡oஇ

以前WindowsでCore-i5@2.6GHzのマシンを使って試した時の2倍以上高速なのですが、M1 MacやiPhoneで試した時よりは遅かったです。

#結論
GPUを使っているといっても、負荷のかかっていない状態で、GPUの能力を100％引き出せているのか、というのが気になります。

あと、GPUへの画像の転送時間と結果画像を戻す時間を検討しないと、GPUにやらせる仕事によってはかえって遅くなる、ということもあるでしょう。

ともあれ、これだけの環境をブラウザ上で、苦労もなく得られるのは素晴らしいことです。手元に非力なマシンしかなくても、ネットの向こうにあるマシンにやらせて、結果をいただくというのは、これからひとつの方向になるのでしょうね。
Databricks JobsからDelta Live Tablesパイプラインを呼び出す

[Delta Live Tables(DLT)](https://qiita.com/taka_yayoi/items/7fe8ed2c2f95fd53cc3d)を用いることで、複雑なデータパイプラインであっても簡単かつ、信頼性高く構築、運用が行えるようになります。

DLT単体でもパイプラインを実行できますが、これと[Databricks Jobs](https://qiita.com/taka_yayoi/items/b3275a1983c51a8bbe1a)とを組み合わせると、さらに複雑な処理を自動化することができます。

本書では、Databricks JobsからどのようにDLTを呼び出すのか、また、その際の注意点を説明します。

# Delta Live Tablesでパイプラインを定義する

> **プレビュー**
この機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。アクセスする際にはDatabricks担当者にお問い合わせください。

JSONを読み込むシンプルなパイプラインを定義します。

```py:Python
import dlt
from pyspark.sql.functions import *
from pyspark.sql.types import *

json_path = "/databricks-datasets/wikipedia-datasets/data-001/clickstream/raw-uncompressed-json/2015_2_clickstream.json"

@dlt.table(
  comment="Jobsテスト用DLT"
)
def bronze():
  return (spark.read.json(json_path))
```

サイドバーから**Jobs > Delta Live Tables**にアクセスし、**Create Pipeline**をクリックします。上記パイプラインを定義したノートブックを選択し、パイプラインの名前をつけて**Create**をクリックしてパイプラインを作成します。
![Screen Shot 2022-02-19 at 9.49.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9d17dd39-bff8-57c5-52ad-41749d8a30b1.png)

パイプラインの詳細画面が表示されます。ジョブから呼び出すので、ここでパイプラインの実行はしません。ただ、一点注意が必要です。画面右上にある**Development/Production**でパイプラインの[モード](https://qiita.com/taka_yayoi/items/6726ad1edfa92d5cd0e9#%E9%96%8B%E7%99%BA%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%A2%E3%83%BC%E3%83%89)を指定できるのですが、ジョブから実行する際には**Production**モードにすることを忘れないでください。ジョブからDLTパイプラインを呼び出した際、このモードによってDLTクラスターの挙動が変わります。

- **Development**モード: ジョブ終了後、2時間クラスターが稼働し続けます。
- **Production**モード: ジョブ終了後、即座に(約5分後)クラスターが終了します。

**Development**モードは名前の通り、パイプライン開発時に選択するモードで試行錯誤、デバッグを行うため、パイプラインの処理が終了しても即座にDLTクラスターは停止しません。
![Screen Shot 2022-02-19 at 9.56.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b15f75a8-bc51-b951-078e-ee8418f6cc01.png)

# ジョブからパイプラインを実行する

1. サイドバーから**Jobs**にアクセスします。
1. **Create Job**をクリックします。
1. ジョブは複数のタスクから構成することができます。ここでは1つのみのタスクを作成します。タスクの**Type**ではDelta Live Tables pipelineを選択し、**Pipeline**では上で作成したDLTパイプラインを選択します。
![Screen Shot 2022-02-19 at 9.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5b3ff0d3-fcff-c4ce-7186-1ae410161c92.png)
1. これでDLTパイプラインを呼び出すジョブを定義することができました。
![Screen Shot 2022-02-19 at 9.57.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5e659af5-b4ea-58f8-f1a1-e54efeacf603.png)
1. 右上の**Run now**で即時実行することもできますし、右側の**Schedule**を指定してスケジュール実行することもできます。

なお、ジョブの実行中にDLTのパイプラインにアクセスすると、処理状況をリアルタイムで確認できます。
![Screen Shot 2022-02-19 at 10.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/69ed8428-fe7d-25f9-28bb-024321eeeaf3.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
【SQL Server】「ゔ」が「ヴ」になってしまった話


データベースに「ゔぃんせんと」と登録しようとしたら「ヴぃんせんと」にされてしまいました。

#現象

SQL Serverでvarchar型のカラムに「ゔ」をinsertしようとすると「ヴ」と登録されます。
▼varcharのカラムに
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1641177/1f3c5d76-961d-14ba-51fb-a0e1bcf5f497.png)
▼「ゔ」をinsert
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1641177/3413aa89-6338-fccc-5abc-796b096ddf07.png)
▲「ヴ」になっている！

#原因

SQL Serverのvarchar型はデフォルトの文字コードがShift_JISだそうです。「ゔ」はShift_JISに存在しない為、文字の意味的に近い「ヴ」としてinsertされるようです（推測）

#対処

**nvarchar型**でinsertしましょう。
nvarchar型は文字コードがUnicodeなので「ゔ」をinsertすることができます。
insertする際にUnicodeを意味する**Nプレフィックス**を指定します。

▼nvarcharのカラムに
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1641177/ea7eb4e9-227f-860c-5c0a-ce148ff5c745.png)
▼Nプレフィックスを指定してinsertします
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1641177/1a11c654-cbd4-a8a8-aef8-e2d7329d1e99.png)
▲「ゔ」が正しくinsertされました！

#まとめ

「ゔ」以外にもShift_JISで扱えない文字が存在するようなので、SQL Serverで日本語の文字列をinsertするときは、**nvarchar型**で**Nプレフィックス**を指定してinsertしましょう。
基本　Aタグページジャンプ機能作成

今回は、ホームページの絶対必要ページジャンプ機能を、作成しましょう😊😊😊

```ruby

<a href="自分のページのURL">表示する文字</a>

```

完成
たったの一行で完成します
プログラム初心者には、必要です覚えてみてください
Mangumを用いたFastAPI製APIのSAM Local実行方法 メモ

* Fast APIで作成したAPIをSAM Localで実行する方法についてメモする。

# Mangum

* ASGI(Asynchronous Server Gateway Interface)アプリをAWS Lambdaで動作させるためのアダプター
* FastAPIなどで実装したASGIアプリを、Lambda + API Gateway構成でサーバレスにWebアプリケーションとして動かす事が可能
* FastAPI利用者であれば、Lambda特有の文法を覚えずLambda利用をスモールスタートできる



## 手順

### 1.サンプルSAMプロジェクトを作成

```shell
sam init
```

※ランタイムはPython3.8を選択

* ``template.yml`

  * Hello World Exampleを利用する。
  * 特に内容は変更しない。

* `requirements.txt`

  ```
  requests
  mangum
  uvicorn
  fastapi
  ```

  ※Mangum,FastAPIを利用するためのライブラリを追加

### 2.サンプルFastAPIアプリ用意

* `asgi_app.py`
  * `{project_dir}/hello_world`ディレクトリに配置

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
def root():
    return {"message": "Hello World"}
```

### 3.Lambdaハンドラ修正

* `app.py`

```python
from mangum import Mangum
from asgi_app import app

lambda_handler = Mangum(app)
```

## 動作確認

1.ビルド

```shell
sam build --use-container
```

2.起動

```shell
sam local start-api
```

3.リクエスト

```http
GET /hello HTTP/1.1
Host: 127.0.0.1:3000
```

4.レスポンス

```http
Status: 200 OK
{
    "message": "Hello World"
}
```



## 参考情報

* [FastAPIのアプリをAWS Lambdaで動かすためにMangumでラップする](https://qiita.com/araki-yzrh/items/985015b9e08978e95b16)
* [[python,AWS]FastAPIで作るサーバーレスAPI(Mangum)](https://zenn.dev/mini_hiori/articles/mangum-serverless)
* [Mangum](https://mangum.io/)
【Twitterで規制がかかった】「このリクエストは、コンピュータによる自動的なものと判断されました。・・・

# Twitterで規制

Twitterを操作していると、ある日突然以下のようなエラーが表示されました。

【エラー内容】
「このリクエストは、コンピュータによる自動的なものと判断されました。アカウントをスパムやその他の迷惑行為から保護するために、現在この操作は実行できません。しばらくしてからやりなおしてください。」
![IMG_2231.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/fe70ab5d-cff5-0e1c-7de7-b4515260ccdc.jpeg)


他のアカウントから見たらこのように見えます。
![image-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/c2522be1-279e-4b91-42bc-faea1a62d383.png)


# エラーの原因

Twitter運営者から以下のような行為がスパムと判断されたのでしょう。
・ 同じURLをツイートまたはDMで送る
・ 短時間に多量のいいね

# エラーの対応

・ 一旦ログアウトしてみる
・ パスワードを変えてみる
・ 問い合わせをしてみる
・ 1〜3日ほど放置してみる
[Oracle Cloud] Identity Domainsを使ってみる② (接続元IPの制限)

# はじめに

Identity Domainsが使えるアカウントを触る機会があったので、いろいろと試しています。
今回は、コンソールにアクセス可能なIPアドレスを制限してみました。

従来どおりのアクセス制限方法には、2種類あります。IDCS側で制限する方法と、OCI側で制限する方法です。

IDCS側で制限する場合は、ネットワーク・ペリメータでアクセス許可するIPを指定して、Sign-On Policiesに設定していました。ネットワーク・ペリメータは、IDCS側で以下のような画面から設定します。(詳細は割愛します)

[ネットワーク・ペリメータのマニュアル](https://docs.oracle.com/cd/E83857_01/paas/identity-cloud/uaids/manage-oracle-identity-cloud-service-network-permieters.html)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/7e4e45c9-abee-9a0f-6cb0-c0c1f8b41325.png)

OCI側で制限する場合は、ネットワーク・ソースでアクセス許可するIPを指定して、認証設定に設定していました。以下のような画面で作成したネットワーク・ソースを指定します。(詳細は割愛します。)

[認証設定のマニュアル](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingpasswordrules.htm)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/e6bc4828-1032-7d9d-5f2d-36d4f11a6949.png)

この接続元制限、Identity Domainsになるとどうやって設定するのでしょう。

# 結果
先に結果から。
従来のIDCSと同様に、ネットワーク・ペリメータとサイン・イン・ポリシーを設定することで設定できました。
(従来OCI側で設定するときに使用していた「認証設定」の画面は、探した限り見つかりませんでした。)

<b>ドメインごとにアクセス制限の設定をしないといけなかったことが、注意点です。</b> Defaultドメインでネットワーク・ペリメータの設定をしても、追加したドメインでは有効になっておらず、個別に設定する必要がありました。

逆に言えば、ドメインごとにアクセス制御を設定できるので、設定は面倒ですが柔軟に設定することができそうです。

# やってみる

デフォルトドメインにログインして、Defaultドメインの設定画面に遷移し、「セキュリティ」リンクを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/8dad89f2-291d-3581-6461-0fff81ba1015.png)

ネットワーク・ペリメータのリンクを選択後、「ネットワーク・ペリメータの作成」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/fddd147d-6f5d-57aa-b080-58c5c92ebe49.png)

アクセスを許可するIP/ネットワークアドレスをCIDR形式で入力します。複数のCIDRを指定する場合は、カンマ(,)つなぎで列挙します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/54c83e6d-23b0-21ef-ff43-f67faad25cfb.png)

続いて、サインインポリシーを設定します。デフォルトで存在するDefault Sign-On Policyを設定変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/fe2c4176-39aa-2644-b09c-26777afc189e.png)

Default Sign-On Policyを編集します。
※Default Sign-On Ruleでは、既定ですべてのIPのアクセスが許可されていました。そのため、Default Sign-On Rule側でアクセス制限をしないと、アクセス制限のルールを追加しても、Default Sign-On Ruleによって許可されてしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/9dc3bdfe-4e4d-29f3-05d2-535384a9ecff.png)


作成したネットワーク・ペリメータをルールに追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/54c89141-f126-7a20-73a3-0a9eae64d827.png)

1度ログアウトして、アクセス許可していないIPアドレスからコンソールにログインしてみます。アクセスが拒否されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/d6f962b0-6382-750f-d688-c9eb85d08342.png)

アクセスが許可されているIPからログインして、ログインできることを確認します。ログインできたら成功です。


追加ドメインが存在し、同じようにアクセス制限をしたい場合は、追加ドメインに対しても同様にアクセス制限の設定を行います。
Excel 表記の変換  R1C1 から A1 へ / A1 から R1C1 へ

Excel 表記の変換方法です。
R1C1表記 から A1表記 へ、 そして A1表記 から R1C1表記 への変換ができます。

Codeforge の 1B がこれに似た問題です。 最近は Excel での作業もそこそこあり、 たまに使いたくなることがあります。

## 関数・定数定義

```ruby
RC_PATTERN = /\AR(\d+)C(\d+)/
ABC_PATTERN = /\A([A-Z]+)(\d+)\z/

def cv_rc(value)
    v = 0
    for c in value.split('')
        v *= 26
        v += (c.ord - 'A'.ord + 1)
    end
    v
end

def cv_a(value)
    ('A'.ord + value - 1).chr
end

def cv_ab(value)
    return '' if value == 0

    cv_ab((value - 1) / 26) + cv_a((value - 1) % 26 + 1)
end

def cv(pattern)
    if pattern =~ RC_PATTERN
        m = RC_PATTERN.match(pattern)

        puts cv_ab(m[2].to_i) + m[1]
    else
        m = ABC_PATTERN.match(pattern)

        puts 'R' + m[2] + 'C' +  cv_rc(m[1]).to_s
    end
end
```

A1表記のアルファベット部分は、 27進数のように思うかもしれませんが、 ちょっと違います。
27進数では、 
`A` を 0 とすると `AA` = `A` になりますし、
`A` を 1 とすると 26 (`Z`) の次が 28 (`AA`) になります。

## 実行

```ruby
cv('AS1')   # R1C45
cv('R1C45') # AS1
```

## 参考

マイクロソフトがやり方を公開しています。
<a href="https://docs.microsoft.com/ja-JP/office/troubleshoot/excel/convert-excel-column-numbers">Excel の列番号をアルファベット順に変換する方法</a>
ヒュベニの公式(Hybeny's Distance Formula)を使って緯度経度間の距離を算出する


緯度経度間の直線距離は、地球が楕円型の所為でそれほど平面上の座標の距離ほど簡単に算出できない。
そのため、緯度軽度間の距離を計算するにはいくつかの方法があるらしいが、
最初に見つけた以下のJavaのサンプルコードが私の用途に削ぐわない結果が出たので、
別の方法を調べた。

https://qiita.com/niwasawa/items/5128101ef93a56e8a6af#java

それがヒュベニの公式(Hybeny's Distance Formula)を使った方法である。
こちらの実装例を紹介するページは多かったが、Javaはぱっと見つからなかったので、
書いてみた。
尚、ヒュベニの公式を使った距離の精度は近い位置だとそれらしい結果だったが、
距離が離れていると誤差が大きそうだった。
とはいえ、私の用途だと大きな問題なさそうだ。

```java
double distance(final double latitude1,
                final double longitude1,
                final double latitude2,
                final double longitude2) {
    // このあたりはstatic化できる
    final double POLE_RADIUS = 6356752.314245; // 極半径(短半径)                                                                                                                                            
    final double EQUATORIAL_RADIUS = 6378137.0; // 赤道半径(長半径)                                                                                                                                         
    final double ECCENTRICITY2 =
        (Math.pow(EQUATORIAL_RADIUS, 2) - Math.pow(POLE_RADIUS, 2))
        / Math.pow(EQUATORIAL_RADIUS, 2); // 離心率の２乗                                                                                                                                                   

    // ラジアンへ変換                                                                                                                                                                                       
    final double rlat1 = Math.toRadians(latitude1);
    final double rlng1 = Math.toRadians(longitude1);
    final double rlat2 = Math.toRadians(latitude2);
    final double rlng2 = Math.toRadians(longitude2);

    final double latDiff = rlat1 - rlat2; // 緯度差                                                                                                                                                         
    final double lngDiff = rlng1 - rlng2; // 経度差                                                                                                                                                         
    final double latAvg = (rlat1 + rlat2) / 2; // 緯度経度平均                                                                                                                                              

    final double w = Math.sqrt(1 - ECCENTRICITY2 * Math.pow(Math.sin(latAvg), 2));
    final double m = EQUATORIAL_RADIUS * (1 - ECCENTRICITY2) / Math.pow(w, 3); // 子午線曲率半径                                                                                                            
    final double n = EQUATORIAL_RADIUS / w; // 卯酉線曲率半径                                                                                                                                               

    return Math.sqrt(Math.pow(m * latDiff, 2)
                     + Math.pow(n * lngDiff * Math.cos(latAvg), 2));
}
```

# 参考

 - https://butter-tiger.hatenablog.com/entry/2020/08/20/222650
 - https://komoriss.com/calculate-distance-between-two-points-from-latitude-and-longitude/
 - https://keisan.casio.jp/exec/system/1257670779
［AWS］CloudTrail攻略問題

# 問題
問1. CloudTrailはデフォルトで各種操作を記録している。その上で証跡を作成するメリットを以下から選択せよ。
a.90日以上データを保存できる
b.データイベントやInsightsイベントを設定できる
c.Cloudtrailから直接ログ情報をDLできる
d.S3に保存できる

問2. ログインイベントはどのリージョンの証跡に残されるか答えよ。

問3. ログインイベントなど特定のイベントに対してCloudWatchを使用せずに通知を鳴らす場合、必要となるサービスを2つ答えよ。

問4. S3上のデータ操作をイベントとして残したい場合に、証跡作成時にどのような設定が必要か答えよ。

問5. EventBridgeで各種イベントに対してアラートを発報したい場合、CloudTrail側で操作しなければいけないことを答えよ。

# 解答
問1. a.b.d
問2. バージニア北部(IAMなどのグローバルサービスに関するイベントはバージニア北部に記録される模様)
問3. EventBridge、SNS
問4. データイベントの有効化
問5. 証跡の作成(証跡無しではなぜか通知が鳴らない、理由が分かり次第追記予定)
Geohashについて(Javaの変換サンプル付き)

# Geohash とは

Geohash は、Gustavo Niemeyer が geohash.org というWebサービスを作成中に発明した、
ジオコーディング方法の一つ。
Geohash を使うと地球を矩形単位で分割して、それをBase32のハッシュで表すことができる。

## geohash は何が便利？

* 矩形のサイズは桁数に比例して変わり、10桁になると0.59m × 0.97mなので、実質的に位置として扱える。
* 矩形単位で位置情報を管理できる。
  * 一定範囲ごとのグループ化などがし易い。例えば上位5桁なら4872.66m × 3955.08mの、上位4桁なら19490.62m × 31640.62mの範囲でグループ化できる。
* 上位の桁が同じ場所は近い位置にある。
  * 前方一致検索ができる。
  * 曖昧な検索ができる。

# Geohashの仕組み

緯度軽度はそれぞれ-90〜+90、-180〜+180の範囲がある。
geohashでは、それを交互に分割していく。
例えば緯度経度が `35.68, 139.70` の場合

1. `139.70` は-180と+180の中央(0)よりは+180側【大きい】
1. `35.68` は-90と+90の中央(0)よりは+90側【大きい】
1. `139.70` は0と+180の中央(90)よりは+180側【大きい】
1. `35.68` は0と+90の中央(+45)よりは+0側【小さい】
1. `139.70` は90と+180の中央(135)よりは+180側【大きい】

このような処理を繰り返す。
そして、これを5回ごとに分割し、大きい側の場合は1、小さい側の場合は0とすると、
11101(2進数)=29(10進数)になる。
この値をBase32に変換すると、xになる。
(値が0はじまりなので、30番目の文字)

```
Base32の文字列： 0123456789bcdefghjkmnpqrstuvwxyz
```

geohashから緯度経度を調べたい場合はこの逆の処理を行い、
Base32(x)から番号(29)に変換し、前述のような判定をしていくのだが、
当然だが座標から座標を含む範囲を求めることは可能だが、
範囲から特定の座標を求めることはできない。
そのため、結果としては矩形の東西南北の緯度経度を求めることになる。
ただし、geohashの桁数が高い場合はほとんど元の位置がわかる
例えば `xn774cneps` から変換した結果は以下。

|位置|値|
|:-----------|------------:|
| 緯度(大)       | 35.68962872028351 |
| 緯度(小)       | 35.68962335586548 |
| 経度(大)       | 139.7004210948944 |
| 経度(小)       | 139.70041036605835 |


# サンプルコード(Java)

## 緯度軽度からgeohashへの変換

```java
String encode(final double latitude,
              final double longitude,
              final int precision) {
    final char[] chars = new char[precision];
    final double[] latLng = { latitude, longitude };
    final double[][] points = {{ 90.0, -90.0 }, { 180.0, -180.0 }};
    int latLngIdx = 1;
    for (int i = 0; i < precision; i++){
        int ch = 0;
        for(int j = 0; j < 5; j++){
            final double mid = (points[latLngIdx][0] + points[latLngIdx][1]) / 2;
            final int b = latLng[latLngIdx] > mid ? 1 : 0;
            points[latLngIdx][b] = mid;
            ch <<= 1;
            ch |= b;
            latLngIdx ^= 1;
        }
        chars[i] = "0123456789bcdefghjkmnpqrstuvwxyz".charAt(ch);
    }
    return new String(chars);
}
```

ググって出てきたRubyやPythonのサンプルだと文字列を使う例が多かったが、
上記の例では効率化のためにビット演算を使用している。

## geohashから緯度経度へ変換

```java
double[][] decode(final String geohash) {
    final double[][] latLng = { { 90.0, -90.0 }, { 180.0, -180.0 } };
    int isLng = 1;
    final String v = geohash.toLowerCase(); // Base32は大文字小文字区別しない
    for (int i = 0; i < v.length(); i++) {
        final int ch = v.charAt(i);
        final int chIdx = "0123456789bcdefghjkmnpqrstuvwxyz".indexOf(ch);
        for (int j = 5; j > 0; j--) {
            final int idx = (chIdx >> (j - 1)) & 1;
            latLng[isLng][idx] = (latLng[isLng][0] + latLng[isLng][1]) / 2;
            isLng ^= 1;
        }
    }
    return latLng;
}
```

# 参考

- https://qiita.com/yabooun/items/da59e47d61ddff141f0c
- https://github.com/masuidrive/pr_geohash
Pugでextendsするときに変数を使う方法

結論から言うと `extends` するページの先頭で変数用のブロックを用意して、 `extends` 先でそこに変数定義する。

例えばこんな感じのhtmlを出力したいとする。

```html:page.html
<!DOCTYPE html>
<html>
  <head>
    <title>タイトル</title>
  </head>
  <body>
    hogehoge
  </body>
</html>
```

pugを使って共通部分を `extends` として読み込むときに、 `extends` はページの先頭に記述する必要がある。
なので、以下のように `extends` より前に変数を定義する書き方だとエラーになってしまう。

```pug:_layout.pug
doctype html
html
    head
        title #title
    body
        block content
```

```pug:page.pug
- var title = "タイトル"
@extends _layout
block content
    | hogehoge
```

しかし、変数は先に定義しないと `extends` 元のpugファイルで使えない。
なので `extends` 元のpugファイルの先頭に変数定義用のブロックを追加して、そこに変数を記述することにする。

```pug:_layout.pug
block vars
doctype html
html
    head
        title #title
```

```pug:_layout.pug
block vars
    - var title = "タイトル"
block content
    | hogehoge
```

これでうまくコンパイルできた。
Gmailで大量のメールを一括操作で一斉削除する (15GB制限対策)

# ふざけんなよGmail…


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/bacd101d-6ee7-559c-5de7-9cb7fd87f2e9.png)


# 削除の手順

1. 適当にラベルを選んだり、キーワード検索して削除したいメールを絞り込む
1. 「メール全てを選択する」チェックボックスにチェックを入れる 
1. 「この検索条件に一致するすべてのスレッドを選択」のリンクが出現するので、それを選ぶ
1. 削除アイコンを押して削除する
1. メールの通常削除が済んだら「ゴミ箱をすぐ空にする」で削除済みメールを消去して容量を確保する



ただし5万件とかあまりに件数が多くなると内部的なエラーで削除できず止まる模様
この場合はキーワードや期間を工夫するなどして1万件ほどの

# 例

## キーワード検索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/85830ff3-6061-cd30-4856-2a4ecc720977.png)


## メール全てを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/fb104910-9dac-e2c0-27fc-f84e6e1e3be1.png)

## 全てのスレッドを選択するリンクが出現

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/45d00239-14fe-6802-dc41-1be0f229717d.png)

## 削除の確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/c209405a-cfc9-87cd-c4f9-babb53097589.png)

## 完全削除

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/bfe32635-dfe9-2fb5-ff95-1bd8bae8195b.png)













<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
pppoe-serverの設定がデフォルトの場所(/etc/ppp/options)だと読み込まれない

地味にハマったので備忘録

Debian系ディストリビューションでpppoeパッケージを入れると、デフォルトで `/etc/ppp/options` に設定ファイルが設置されるが、これだとpppoe-serverコマンドでサーバーを起動しても設定が読み込まれない。(その他ディストロに関しては試してないので知らない)
しれっと置いてあるので、そのまま読み込まれそうだが本当に読み込まれない。

ログを見ると `pppd: Can't open options file /etc/ppp/pppoe-server-options: No such file or directory` と書いてあるので、`/etc/ppp/pppoe-server-options` に置かないといけないらしい

`$ sudo cp /etc/ppp/options /etc/ppp/pppoe-server-options`でコピーしたら動いた。
`$ sudo pppoe -I eth1 -O /etc/ppp/options`でも良さそう


manページを読むと `from the default /etc/ppp/pppoe-server-options` って書いてあるのになぜ `/etc/ppp/options` 設置されているのだろうか...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96621/5c8efc69-c0a4-c054-32e5-f3a08399f780.png)
2022/2/19主にITとかセキュリティの記事

「Adobe Commerce」「Magento」に今月2度目の緊急パッチ
https://www.security-next.com/134234

広島県にDDoS攻撃 - 県や市町のウェブ閲覧や防災メール配信に影響
https://www.security-next.com/134283

Cisco製メールセキュリティ製品にDoS攻撃を受けるおそれ
https://www.security-next.com/134253

「Emotet」感染で従業員装うメール出回る - クラシエ
https://www.security-next.com/134260

「Drupal」に2件の脆弱性 - アップデートが公開
https://www.security-next.com/134247

「Yahoo! JAPAN ID」を制限とだますフィッシング攻撃に注意
https://www.security-next.com/134275

個人情報保護法改正や越境問題をテーマにセミナー開催 - DBSC(3/2開催)
https://www.security-next.com/134265

デジタル庁でさえ囲い込み脱せず、公取委がベンダーロックインに独禁法の警鐘(2/18)
https://xtech.nikkei.com/atcl/nxt/column/18/00989/021700075/

JR東がSuica統計データ外販　炎上から9年、安全策講じ再挑戦(2/17)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020800017/020900675/

2021年に開示された脆弱性の数は過去最大の2万8695件(2/16)
https://news.mynavi.jp/techplus/article/20220216-2272972/

米ＦＢＩ、ロシア関与のサイバー攻撃警告　防衛企業は対策を(2/17)
https://jp.reuters.com/article/ukraine-crisis-usa-cyber-idJPKBN2KL22O

Androidスマホ　セキュリティー設定変更で鉄壁の備え(2/17)
https://style.nikkei.com/article/DGXZQOUC07223007012022000000

ランサムウェアVPN機器からの侵入が54％(2/16)
https://www.risktaisaku.com/articles/-/65110

「プライバシー サンドボックス」がAndroidにも導入 ～Googleが提案する新しいWeb広告の仕組み(2/17)
https://forest.watch.impress.co.jp/docs/news/1389025.html

「もらったEXEなんて開かねえよｗ」なんて人も絶対に騙される偽装ファイル名に思わず戦慄(2/17)
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1388917.html

個人情報漏えい等事案の公表　鹿児島県(2/16)
http://www.city.kagoshima.lg.jp/soumu/soumu/soumu/roueikouhyou.html

栃木県のビッグデータ活用実験　見えた想定外客(2/16)
https://www.nikkei.com/article/DGXZQOCC150MY0V10C22A2000000/

ウクライナの国防省・銀行・軍施設にDoS攻撃発生、ロシアは関与を否定(2/17)
https://jp.techcrunch.com/2022/02/17/cyberattacks-on-ukraine-on-the-rise-as-russian-invasion-looms/

テストでバグ発見！（8）状態遷移モデルで扇風機シミュレーターのバグを摘出せよ【解答編】(2/17)
https://monoist.itmedia.co.jp/mn/spv/2202/17/news031.html

21年のランサムウェア被害、医療、福祉分野は7件
感染経路の半数以上がVPN機器から　(2/16)
https://www.cbnews.jp/news/entry/20220216165125

サイバー攻撃で診療継続３割　病院調査、対策に遅れ(2/16)
https://www.chibanippo.co.jp/newspack/20220216/906274

ハッカーが米国を拠点とするFintechスタートアップから3600万ドルを奪う(2/17)
https://nextmoney.jp/?p=48233

グーグル、アプリ追跡制限へ　プライバシー保護を強化(2/17)
https://jp.wsj.com/articles/google-plans-to-curtail-cross-app-tracking-on-android-phones-11645049420

中国　IT企業の海外上場に関する新規制を施行　米への情報流出を警戒(2/16)
https://www.khb-tv.co.jp/news/14550563

グーグルもアップルと同様のプライバシー保護を導入へ…フェイスブックにさらなる打撃(2/17)
https://www.businessinsider.jp/post-250692

米国の防衛企業にサイバー攻撃、ロシア政府が支援--CISAが警告
https://japan.cnet.com/article/35183654/

複雑なパスワードがセキュリティのリスクを高める？　Impervaが指摘(2/17)
https://www.itmedia.co.jp/enterprise/spv/2202/17/news043.html

プルーフポイント「内部脅威による損失グローバルレポート2022」を発表　内部脅威による組織の損失は2020年から34％増加し、年間1,540万ドルと判明インシデントの56%は内部関係者の過失によるもので、認証情報の窃取による内部脅威は倍増、修復コストは1件あたり平均80万ドル以上(2/17)
https://prtimes.jp/main/html/rd/p/000000002.000073972.html

相次ぐランサムウェアによる医療機関へのサイバーテロ、どう対応するべきなのか（藤谷 昌敏）(2/17)
https://agora-web.jp/archives/2055145.html

JPモルガン、メタバースに情報拠点　金融サービスも視野(2/17)
https://www.nikkei.com/article/DGXZQOGN1700U0X10C22A2000000/
Ignoring racc-1.5.2 because its extensions are not built. Try: gem pristine racc --version 1.5.2が出た時の対処法

## はじめに
こちら自分用のメモであるためとても雑な記事です。
ただ、同じようなエラーが出た人の助けに少しでもなれば幸いです。
## エラーログ
railsコマンドをターミナルで実行すると無限に以下のメッセージが吐き出される

![スクリーンショット 2022-02-19 2.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081227/5842c8d9-4536-f834-133e-3927a7a3c897.png)


```.zsh
...
Ignoring racc-1.5.2 because its extensions are not built. Try: gem pristine racc --version 1.5.2
Ignoring racc-1.5.2 because its extensions are not built. Try: gem pristine racc --version 1.5.2
Ignoring racc-1.5.2 because its extensions are not built. Try: gem pristine racc --version 1.5.2
Ignoring racc-1.5.2 because its extensions are not built. Try: gem pristine racc --version 1.5.2
...
```



##解決策

以下のコマンドを実行する


```.zsh
$ gem pristine --all
```
Objectのコピーについて(Javascript)

javascrptのオブジェクトは単純な代入だと参照が渡されてしまいプロパティに対する編集が共有されてしまう。


```Javascript
const hoge = { name: 'hoge'};
let hogehoge = hoge;

hogehoge.name = 'hogehoge';

console.log(hoge)//{name: 'hogehoge'}が表示される
```

1階層のオブジェクトであれば新規の配列を作成するmapを使い、参照を共有しないオブジェクトを取得できる。

```Javascript
const hoge = { name: 'hoge'};
let hogehoge = [hoge].map( val => ({...val}))[0];

hogehoge.name = 'hogehoge';

console.log(hoge, hogehoge)//{name: 'hoge'} {name: 'hogehoge'}が表示される

```

しかしオブジェクトがプロパティとしてオブジェクトを持っている場合、ネストされたオブジェクトの参照はやはり共有されてしまう。

```Javascript
const hoge = { id: 1 , data: { name: "hoge" } };
let hogehoge = [hoge].map( val => ({...val}))[0];

hogehoge.id = 999;
hogehoge.data.name = 'hogehoge';

console.log(hoge, hogehoge);
/*
{id: 1, data:{name: 'hogehoge'} } 
{id: 999, data:{name: 'hogehoge'} }が表示される。
idはそれぞれ独自の値を保持しているがdata.nameの値は共有されている
*/
```

プロパティとして配列を持っている場合も同じ挙動をとる。

```Javascript
const hoge = { id: 1 , arr: ['hoge'] };
let hogehoge = [hoge].map( val => ({...val}))[0];

hogehoge.id = 999;
hogehoge.arr[0] = 'hogehoge';

console.log(hoge, hogehoge)
/*
{id: 1, arr:['hogehoge'] } 
{id: 999, arr:['hogehoge'] }が表示される。
idはそれぞれ独自の値を保持しているがdata.arの値は共有されている
*/
```
区間が重なるためのある条件式と `Range#overlaps?` の定義は同じなのか

Rails で定義されている [`Range#overlaps?`](https://api.rubyonrails.org/classes/Range.html#method-i-overlaps-3F) の[定義](https://github.com/rails/rails/blob/2459c20afb508c987347f52148210d874a9af4fa/activesupport/lib/active_support/core_ext/range/overlaps.rb#L8)は

```rb
def overlaps?(other)
  cover?(other.first) || other.cover?(first)
end
```

となっている。`other` と対比しやすいよう `self` を補うと

```rb
self.cover?(other.first) || other.cover?(self.first)
```

となる。

ところで、区間が重なっているか調べるには

```rb
self.first <= other.end && other.first <= self.end
```

という別式も知られている。これは、区間どうしが重ならない条件

```rb
self.end < other.first || other.end < self.first
```

の否定として得られる。

Rails の `Range#overlaps?` の定義が、この別式と等しいかどうか見てみよう。区間は両端を含み、`first <= end` となっているとする。

さっき `self` を補った式

```rb
self.cover?(other.first) || other.cover?(self.first)
```

からスタートする。`cover?` の定義を展開する。

```rb
(self.first <= other.first && other.first <= self.end) || 
  (other.first <= self.first && self.first <= other.end)
```

`&&` を `||` した形になった。ここで

```rb
   (A && B) || (C && D)
== (A || (C && D)) && (B || (C && D))
== (A || C) && (A || D) && (B || C) && (B || D)
```

だから、当てはめて

```rb
(self.first <= other.first || other.first <= self.end) &&
  (self.first <= other.first || self.first <= other.end) &&
  (other.first <= self.first || other.first <= self.end) &&
  (other.first <= self.first || self.first <= other.end)
```

を得る。第二項と第三項は冗長、たとえば第二項で `self.first <= other.first` のときは常に `self.first <= other.end` を満たすので、まとめて

```rb
(self.first <= other.first || other.first <= self.end) &&
  (self.first <= other.end) &&
  (other.first <= self.end) &&
  (other.first <= self.first || self.first <= other.end)
```

となる。ここで第一項の

```rb
(self.first <= other.first || other.first <= self.end)
```

に注目しよう。実は簡単な条件じゃないかという匂いがするので二重否定をつけて

```rb
!!(self.first <= other.first || other.first <= self.end)
```

まずド・モルガンと不等号を反転して

```rb
!(self.first > other.first && other.first > self.end)
```

だが、`self.first <= self.end` なので `!(...)` の中身は常に成り立たない。つまり

```rb
!false
```

なので、第一項は `true` だった。同様に第四項も `true` になって

```rb
true &&
  (self.first <= other.end) &&
  (other.first <= self.end) &&
  true
```

であり、`true &&` を縮約して別式と同じ

```rb
self.first <= other.end && other.first <= self.end
```

が得られた。
【rbenv】`rbenv install 3.1.0`実行時の`BUILD FAILED`を解消した方法【Ruby】【Rails】

##`rbenv install 3.1.0`実行時の`BUILD FAILED`を解消した方法

### 状況
M1 macで以前にRuby 2.7.5をインストールしていました。
OSを11.6.4(Big Sur)から12.2.1(Monterey)にバージョンアップした後にRubyをバージョンアップするために、`rbenv install 3.1.0`を実行した際に、以下のエラーが出てインストールができませんでした。

```:ターミナル
$ rbenv install 3.1.0
Downloading openssl-1.1.1l.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1
Installing openssl-1.1.1l...

BUILD FAILED (macOS 12.2.1 using ruby-build 20211227)

Inspect or clean up the working tree at /var/folders/8z/why2366147x1h2j9jtf0000gn/T/ruby-build.2022180259.98949.4ygKJM
Results logged to /var/folders/8z/why2366147x1h2jzhrw0000gn/T/ruby-build.2022090259.949.log

Last 10 log lines:
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL file first)         ***
***                                                                ***
**********************************************************************
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

```


### 解決した方法

以下の通り対応することでエラーが解消し、インストールすることができました。

```:ターミナル
$ brew upgrade rbenv ruby-build
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 1 formula.

Error: No developer tools installed.
Install the Command Line Tools:
  xcode-select --install

$ xcode-select --install
xcode-select: note: install requested for command line developer tools

$ xcode-select --install
xcode-select: error: command line tools are already installed, use "Software Update" to install updates

$ brew upgrade rbenv ruby-build

$ rbenv install 3.1.0
     
$ rbenv global 3.1.0           
$ ruby -v
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [arm64-darwin21]

```
[Mac]DBeaverでJava heap spaceが出た時の対処法

# 背景
MacでDBeaverでJava heap spaceが出ていて、困ったので対処法を共有です。
SQLファイルが50MBくらいあるクエリをSQLファイルに貼り付けた際にこのエラーが出ました。

# 環境
* OS macOS Catalina 10.15
* プロセッサ 2.4GHz クアッドコアintel Core i5
* メモリ 16GB
* DBeaver version21.3.2

# 解決策
DBeaverの設定ファイルから最大ヒープメモリを変更します。

まず、下記をターミナルで実行します。

```shell
cd /Applications/DBeaver.app/Contents/Eclipse/
vi dbeaver.ini
```

次に、dbeaver.iniの中身を編集します。
`-Xmx4096m`の部分が小さいためにエラーが出ているため最大値を増やします。
確かデフォルトは1024mだったのですが、2048mにあげ、さらに4096mにあげとエラーが出るたびに繰り返し、現在4096mに落ち着いています。

```text
-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.300.v20210813-1054.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.2.300.v20210828-0802
-vm
../Eclipse/jre/Contents/Home/bin/java
-vmargs
-XX:+IgnoreUnrecognizedVMOptions
--add-modules=ALL-SYSTEM
-Dosgi.requiredJavaVersion=11
-Xms128m
-Xmx4096m
-XstartOnFirstThread
```

# まとめ
 * DBeaverでヒープサイズを上げるにはdbeaver.iniを編集する。
 * dbeaver.iniはMacの場合は/Applications/DBeaver.app/Contents/Eclipse/以下にある。 
 * 最大ヒープメモリXmxの値を変更する。
EC-CUBE4.1公式のローカル環境(docker-compose)でphpMyAdminを使う。

やっぱりDBのテーブルをサクッと見れるphpMyAdminは便利。

EC-CUBE公式のdocker-compose.ymlにphpMyAdminが使えるように記述を追加した。

※mysqlを使用してます。デフォルトではSQLiteなので注意。

```
 ### phpMyAdmin ##################################
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - 8888:80
    environment:
      PMA_HOST: mysql
      PMA_USER: dbuser
      PMA_PASSWORD: secret
    networks:
      - backend
```

http://localhost:8888

にアクセスすればphpMyAdminが使える。