OmniAICreator/Qiita-1.07M huggingface dataset:
fluent-bitを使ってログをLog Analyticsに転送する

fluent-bitがデフォルトでAzureのLog Analyticsにログを転送する機能を持っていたので、試してみました。

https://docs.fluentbit.io/manual/pipeline/outputs/azure

# 事前準備

Log Analyticsにログを送信する時に、正直イライラするというか不安になるというか、結構困るのは送信したログがすぐにはクエリできず数分間待たされることです。
初めてやっている時はそもそもログを拾えていないのかどうかとの区別がしにくく、特に不安になるのではないかと思います。
なので、まずは標準出力を出力先にして、ログを出力してみることをお勧めします。

今回は簡単にfluent-bitを立ち上げたかったのでDockerで起動します。出力先は標準出力で、入力はforwardです。

```bash
$ docker run -p 127.0.0.1:24224:24224 fluent/fluent-bit:1.5 /fluent-bit/bin/fluent-bit -i forward -o stdout -p format=json_lines -f 1
Fluent Bit v1.5.7
* Copyright (C) 2019-2020 The Fluent Bit Authors
* Copyright (C) 2015-2018 Treasure Data
* Fluent Bit is a CNCF sub-project under the umbrella of Fluentd
* https://fluentbit.io

[2021/09/24 19:26:42] [ info] [engine] started (pid=1)
[2021/09/24 19:26:42] [ info] [storage] version=1.0.5, initializing...
[2021/09/24 19:26:42] [ info] [storage] in-memory
[2021/09/24 19:26:42] [ info] [storage] normal synchronization mode, checksum disabled, max_chunks_up=128
[2021/09/24 19:26:42] [ info] [input:forward:forward.0] listening on 0.0.0.0:24224
[2021/09/24 19:26:42] [ info] [sp] stream processor started
```

`--log-driver`を指定すると、コンテナのログを簡単に転送できます。

```bash
$ docker run --log-driver=fluentd -t ubuntu echo "Testing a log message"
Testing a log message
```

fluent-bit側のコンテナをみると、ログが送信されていることが分かります。

```json
{"date":1632511701,"source":"stdout","log":"Testing a log message\r","container_id":"c5db93437b82b371454bac959110dc45802b115c134b4520ea3f848343c46002","container_name":"/elastic_pike"}
```

# Log Analyticsにログを転送する

今度は出力先をLog Analyticsにします。まずワークスペースIDとキーを確認しましょう。ポータルだと以下に出ています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16609/1f218696-0fef-23fd-61b0-3132fb82c9d1.png)

fluent-bitのコンテナを作り直します。

```bash
$ docker run -p 127.0.0.1:24224:24224 fluent/fluent-bit:1.5 /fluent-bit/bin/fluent-bit -i forward -o azure -p customer_id=ワークスペースID -p shared_key=キー -m '*' -f 1
[2021/09/24 20:24:54] [ info] [engine] started (pid=1)
[2021/09/24 20:24:54] [ info] [storage] version=1.0.5, initializing...
[2021/09/24 20:24:54] [ info] [storage] in-memory
[2021/09/24 20:24:54] [ info] [storage] normal synchronization mode, checksum disabled, max_chunks_up=128
[2021/09/24 20:24:54] [ info] [input:forward:forward.0] listening on 0.0.0.0:24224
[2021/09/24 20:24:54] [ info] [output:azure:azure.0] customer_id='xxxxxxxxxxxxxxxx' host='xxxxxxxxxxxxxxxxxxxx.ods.opinsights.azure.com:443'
[2021/09/24 20:24:54] [ info] [sp] stream processor started
```

入力は変更していないのでさきほどと同じ方法でログを書き込みます。

```bash
$ docker run --log-driver=fluentd -t ubuntu echo "Testing a log message"
Testing a log message
```

fluent-bit側のコンテナをみて、以下のように出力されていたら問題ないはずなので、しばらく待ちます。10分くらい待ったかも。

```
[2021/09/24 20:25:01] [ info] [output:azure:azure.0] customer_id=xxxxxxxxxxxxxxxxxxxxxx, HTTP status=200
```

どこにも記載がなくて困ったのですが、Log Analyticsのテーブルはカスタムになっていて、fluentbit_CLというところに書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16609/a988398e-7eaf-a35f-dccd-19e23b0569ee.png)
Barrier で Mac 側へキーボードが入力できない場合

Barrier 便利ですよね。
複数の PC を1組のキーボードとマウスでまとめて操作できるので、一度使うと手放せません。

Mac を Barrier クライアントへ変更したところ、キーボードの文字が Mac に反映されず困りました。
キーボードの特殊キー(Ctrlやカーソルキー)は送信されているみたいですが、数字と英字キーは送信されていないように見えます。

解決方法が案外見つからなかったのでメモを残しておきます。
Barrier 側の設定ではなく、Mac 側の設定を一つ加えるだけです。

## 問題発生条件

* Windows 10 を Barrier サーバーに指定している。
* Mac を Barrier クライアントにしている。

Mac を Barrier サーバー、Windows を Barrier クライアントにする場合は問題ありません。
ここで言う Barrier サーバーとは、その PC のキーボードを使って他の PC を操作する親機を指します。

## 解決方法

Barrier の設定ではなく、Mac のキーボード設定を追加します。

1. Mac の**システム環境設定**を開く
1. **キーボード** 設定を開く
1. **入力ソース** タブに切り替える
1. 入力ソース追加 [+] から **Unicode 16進数入力** を追加  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252217/a6dd86e0-836f-53c1-cf25-66a5510b321c.png)  
    (すでに追加しているのでグレーアウトになっていますがこいつです)
1. Mac 側の Barrier を再起動

なお、入力ソースは追加するだけで OK です。
Unicode 16進数入力 に切り替えておく必要はありません。

## おまけ

Windows キーボードから Mac を操作する場合、Command キーと Control キーは入れ替えたほうが使いやすいです。
Mac でも Ctrl+C キーでコピーできたほうが楽ですので。。。

設定変更は、Windows 10 サーバー側の Barrier 設定を下記のように変更してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252217/9dd2449f-5bf2-23af-c54a-d80f3a825f20.png)

## 参考

Barrier は Synergy のフォークなので、Synergy の情報も合わせて探してみましょう。
(Barrier のアイコン、たぶん Synergy のアイコンをばらばらにしてるんじゃ？)

Mac上のSynergyでキーボードが使えない
https://snge.me/blog/2015-02/mac-synergy.html
Chromeやfirefoxでポート番号10080へのアクセスがエラーになる件( This site can't be reached )

# ポート番号: 10080が2021年から使えなくなっていた

詳細は参考記事を見てもらいたいのですが、10080番のポートを使った攻撃手法が見つかったため、chromeとfirefoxでは10080番のポートにアクセスすることができなくなりました。ブラウザ側でブロックされます。

chromeだとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98127/ebbcc039-4c5e-10fd-92ee-b010990bf218.png)


ボート番号の10080は8080や3000と並んでよくlocal環境でWebアプリケーションのサーバーを立ち上げる時に使われていると思います。そのため去年以前に作られたプロジェクトの中には10080のポート番号を指定しているWEBアプリケーションも多いので、久しぶりに立ち上げたLaravelやRailsのアプリケーションがローカルで立ち上がらなくて「あれ、サーバーがうまく立ち上がらないぞ」と勘違いしないように注意したいですね。

なお2021年9月24日現在、 safariでは 10080番にアクセスできました。safariはセキュリティゆるゆる？笑



参考:

https://qiita.com/apple502j/items/2df7773f6f4224f9a219
なんかよさげなモジュール／ライブラリを探すならAwesome

思わぬ発見があるので色々眺めて見るのをおすすめ

# awesome

python

https://github.com/vinta/awesome-python

flask

https://github.com/humiaozuzu/awesome-flask

php

https://github.com/ziadoz/awesome-php

perl

https://github.com/hachiojipm/awesome-perl

jquery

https://github.com/petk/awesome-jquery

git-hooks

https://github.com/compscilauren/awesome-git-hooks

コマンドラインツール
https://github.com/agarrharr/awesome-cli-apps
https://github.com/Kikobeats/awesome-cli


https://github.com/alebcay/awesome-shell

awesomeを集めたもの

https://github.com/fleveque/awesome-awesomes

https://github.com/sindresorhus/awesome

# wtf

https://github.com/satwikkansal/wtfpython


# news

https://news.python.sc/

# 開発者が無料で使えるサービス

https://github.com/ripienaar/free-for-dev

# ci

https://github.com/ligurio/awesome-ci
STM32 チャタリング処理 その2


- 複数ボタンに対応した。ボタン番号にGPIOピンを割り当てるような使い方にした。
- オフトリガー限定。シングルクリックのみ判定。

使い方例

```cpp:main.c
Button_Init(0, GPIOB, GPIO_PIN_0);    // Assign PB0 to button #0.
Button_Init(1, GPIOA, GPIO_PIN_11);   // Assign PA11 to button #1.

while (1) {
	if (Button_Loop(0) == BUTTON_CLICKED) {  // call Button_Loop() function several times. The status will be return.
                // any procedure for clicking PB0.
    		Button_Init(0, GPIOB, GPIO_PIN_0); // to clear button #0 status.
	}
}
```

プロジェクトサンプルはここに置きました。

https://github.com/numeru55/NUCLEO-F303K8_Button
Windows + Alacritty で msys2(MinGW) bash を使うメモ

Alacritty はドキュメントほぼ無いので基本利用はおすすめはしないですが, どうしても Windows で msys2 で Linux gnome-termial のようなレスポンス高いシェル実現し, ag など Linux プログラムも動かして快適にしたいひと向け
(Windows Terminal は `Ctrl+C`, `Ctrl-V` のリマップができないしレスポンス遅い(+ tmux とか使うとレイアウト崩れる),  mintty は悪くはないがレスポンス悪めだったりハングしやすい)

追記: 最近(2023/01)ですと Hyper.js or Termulus のほうがよさそうです!

## 設定(バージョンによってことなる)

`%APPDATA%/alacritty/alacritty.yaml` で手で編集しないといけません.

オフィシャルの設定ファイルのドキュメントは無いです.
`alacritty.yaml` のコメントだけです.

https://github.com/alacritty/alacritty/blob/master/alacritty.yml

を参考に設定必要です.

どうもバージョンによって異なります.

v0.9 の話をします.

v0.9 だと, `cmd.exe /c "...."` みたいなプログラム指定だと Powershell が起動してしまうっぽい.
(検索で出てくるのはこの古い設定方法)


```yaml
working_directory: C:\Users\syoyo

env:
  HOME: C:\Users\syoyo

shell:
  program: C:\mingw64\usr\bin\bash.exe
  args: ["--login", "-i"]

```

program には `"` でエスケープして引数含めて一つに記述はできません(e.g. `"C:\mingw64\usr\bin\bash.exe --login -i"`)

また, `C:\Program Files\Git\bin\bash.exe` のようにスペースがある場合でも quote せずに .exe のパスを記載します. quote するとうまく動きません.


引数は `args:` に記載します.

`Unable to spawn shell...` と出る場合, たぶん program のファイルパスが間違っています.


設定がうまくいけば

![ala2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/c482a70c-2c13-3aa0-f914-6baffb736163.png)

のように起動します! Voila!

## エラー

文法エラーとかあると表示してくれます.

![alacritty-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/b78a5688-bf4e-1dc3-5388-571d21b30d52.png)

設定ファイルは(エラーの場合?)変更あると自動リロードされるるので, Alacritty のウィンドウ出したまま設定ファイルの見直しができます.

キーボードペーストは Linux と同じ(?)ように `ctrl+shift+v` or `shift+INS` でいけます.


## TODO

MSYSTEM の設定をうまくやる(32bit, 64bit, UCRT)

```
envs:
  MSYSTEM: UCRT65
```

はうまくいかずエラーとなりました(process not found エラー)

マウスでコピペなどのバインディングをうまくやる.
[Rails]基本理念について

# はじめに
本記事では、railsの基本理念について、まとめてみました。


# 基本理念

## DRY
railsでコードを書く時には、
同じ情報を繰り返し記述することは、コード的にも、見る人にも良くはありません。

`DRY`とは、`Don't Repeat Yourselfの略`
`同じ情報を繰り返し記述しない`というものです。

`スマブラのドンキーコング`を想像してください。
(ちょっと強引ですので、ご容赦)

`DRYを意識していない`ドンキーコング

```
ジャブ = ドンキーのAボタン
パンチを溜める = ドンキーのBボタン
ジャンプする = ドンキーのYボタン

- 「ドンキー」を修正する場合、３箇所もあるので、工数がかかる
- 一つだけ「ドンキー」のまま未修正に気づかなかった場合のリスク有
```

`DRYを意識した`ドンキーコング

```
fighter = ドンキー
ジャブ = fighter の Aボタン
パンチを溜める = fighter の Bボタン
ジャンプする = fighter の Yボタン

- 変更点が１つだけなので、修正工数が少ない
- 修正点が少ないので、修正漏れも少ない
```

### DRYのメリット
- 可読性の向上
- コード量を減らすことによりアプリケーションの動作が早くなること

## CoC
`Convention Over Configuration`の略
`設定よりも規約を優先する`という考え方です。

例えば、`rails g model`などコマンドを入力すると、
ファイルが自動で作られておりましたが、
このように`railsの決められているルール`を活用し、アプリケーションを作成することが保どんどです。

つまり、自分自身で0から設定するのではなく、
その`ルールに則り作業していたということ`=`設定よりも規約を優先していること`になります。

### CoCのメリット
- 決められているルールを利用することで`開発スピードが上がり、質も担保`できる
- 規約は開発者同士の共通認識であるため、`可読性が向上`することなどが挙げられます。

## railsのディレクトリ階層について
ディレクトリ階層も規約に則って整理されています。
私自身、理解できているか確認したいので改めて記述します。

```
app...MVCに関するファイルなどを格納している、アプリケーションの主要ディレクトリ。

bin...Binary Codeの略。コマンドなどで実行するファイルが格納。

config...アプリケーションの設定関係のファイルが格納。

db...データベースに関するファイルが格納。

lib...libraryの略で、基本的なライブラリが格納。

log...アプリケーションが動いている間の記録などのファイルが格納。

node_modules...nodeのパッケージが格納。

public...デフォルトで表示される画面の情報などが格納。

storage...画像などをアプリケーション自体に保存する際に使用するディレクトリ。

test...アプリケーションのテストを行う際に使用するファイルを格納するディレクトリ。

tmp...アプリケーションが起動している際の一時的な情報を格納するディレクトリ。

vendor...ライブラリ(Gem)などをアプリケーション自体にインストールする際に使用するディレクトリ。

.browserslistrc

.ruby-version

babel.config.js

config.ru

Gemfile

Gemfile.lock

package.json

postcss.config.js

Rakefile

README.md

yarn.lock
```

## オブジェクト指向について
過去に、スマッシュブラザーズのドンキーコング（またかよ）で、
例えている記事がありますので、こちらを参照ください。

https://qiita.com/mkato1013/items/77075ed76aa82aa9a487


以上です。

# 終わりに
プログラミングを始めて2ヶ月程経ち、railsのことをもっと詳しく知りたいと思いました。
rubyやrailsに限らず、今後は、もっと多くの言語を学びたいと考えておりますが、
オブジェクト指向などに関しては、他の言語にも通づるものがありますので、
ここで、今自分が知っている言語を深ぼるのは、良いのではと思っています。

まだまだ学びたいことが多いので、楽しみだなー！
明日も頑張ります！
HoloLens 2 における Unity PlayerPrefs データ保存場所について

# Overview
**[Azure Remote Rendering 公式チュートリアル](https://docs.microsoft.com/ja-jp/azure/remote-rendering/tutorials/unity/view-remote-models/view-remote-models)** を試していたところ、```PlayerPrefs.SetString``` が使用されていて、HoloLens 2 のどこにデータが格納されているか気になったので、調べてみました。

PlayerPrefs を使えば、ユーザー設定等のデータを手軽にローカル端末上で管理することができます。

以下、Azure Remote Rendering 公式チュートリアルに出てくる RemoteRenderingCoordinator.cs の一部抜粋です。Azure Remote Rendering の Session ID を記録し、次回起動時にも同一 Session ID が利用可能であれば、そのセッションに接続を行うという実装で PlayerPrefs が使用されています。


```RemoteRenderingCoorinator.cs
    /// <summary>
    /// Keep the last used SessionID, when launching, connect to this session if its available
    /// 最後に使用した SessionID を保持し、アプリを起動時に、利用可能であれば、そのセッションに接続します。
    /// </summary>
    private string LastUsedSessionID
    {
        get
        {
            if (!string.IsNullOrEmpty(SessionIDOverride))
                return SessionIDOverride;

            if (PlayerPrefs.HasKey("LastUsedSessionID"))
                return PlayerPrefs.GetString("LastUsedSessionID");
            else
                return null;
        }
        set
        {
            PlayerPrefs.SetString("LastUsedSessionID", value);
        }
    }

```

Device Portal を使用して、Playerprefs.dat を探していると、
以下ディレクトリ配下に格納されていました。


**HoloLens 2 における PlayerPrefs データ保存場所** ( PATH )

> User Folders\LocalAppData\PackageName\LocalState\playerprefs.dat

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/b2048a5a-d89b-a786-038a-051b7d3ade4e.png" width="800">


# See Also

- [リモートでレンダリングされたモデルの表示 | Microsoft Dos](https://docs.microsoft.com/ja-jp/azure/remote-rendering/tutorials/unity/view-remote-models/view-remote-models)
- [PlayerPrefs | Unity 2020.3](https://docs.unity3d.com/ScriptReference/PlayerPrefs.html)
インポートできない原因は、データが破損しているから？

テーブル作成でのインポート作業において、自分が躓いたエラーの解決法をまとめようと思う。

#テーブルがあるけどない？
インポートを行いテーブルを作成しようとしたところ、このようなエラーが返ってきた。
「mznというテーブルは存在するのでインポート前にテーブルを削除するように」とのこと。
![スクリーンショット 2021-09-15 22.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1271540/47c62a45-f4cf-efb0-740b-312e17288295.png)
プロンプト上で、「use mzn;」でデータベースmznへ移り、「show tables;」で作成したいテーブルusersを確認したところ空と返ってきた。念の為、「drop table users;」でテーブルを消そうと試したが、当然エラーが返ってくる。
![スクリーンショット 2021-09-11 19.41.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1271540/42d0bb9f-8f8c-ffee-bdd4-dfc435808727.png)
以上のことから、DB上にはテーブルがあるがプロンプト側で見ると存在しないことが分かり、これによりインポートがうまくいかずデータが一部で破損していることが分かる。この破損したデータを削除し、再度create,insert,updateの順でインポートを試すことでテーブルがうまく作成される。





#解決法
infra/mysqlに「Mysql_files」というファイルがある。
![スクリーンショット 2021-09-25 0.30.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1271540/c3e43477-755b-b937-7516-3fc476ca7d5f.png)

これが破損したファイルデータでありこれを削除したのち、下のようにcreate,insert,updateの順でコマンドを実行または同様のことをツール上で行うことで、インポートがなされテーブルが作成される。
```
CREATE TABLE　'テーブル名'
INSERT INTO 'テーブル名'
UPDATE STAFF 'テーブル名'
```
破損箇所はケースによってさまざまなので、今回のような「Mysql_files」というファイルとは限らない可能性があるが、DB関連と考えるとinfra/mysql以下周辺のファイルであることが考えられる。
CSSのみで和柄（七宝？）の背景パターンを作成した

<p>
CSSのみで作成された背景パターンを漁っていたのですが、目当てのパターンがなかったので自分で作りました。
</p>

<h2>「これなんて名前なん…？七宝？検索しても全然出てこない…」となった背景パターン</h2>

```css:style.css
:root {
    --white: #fff;

    /*円の大きさ*/
    --shippo1: calc(var(--shippo2) - 0.6px);
    --shippo2: 40px;
    --shippo3: calc(var(--shippo2) + 0.6px);
}

.box {
    background-color: #9f166a;
    background-image:
        radial-gradient(circle at top left, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at top right, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at bottom left, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at bottom right, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at 50% 150%, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at 50% -50%, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at -50% 50%, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3)),
        radial-gradient(circle at 150% 50%, transparent var(--shippo1), var(--white) var(--shippo2), transparent var(--shippo3));
    background-size: calc(var(--shippo2) * 1.732) var(--shippo2);
}
```

<h3>結果</h3>
![結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2078141/498cb4aa-f03e-7990-da22-33772c260dfd.png)

<h2>参考文献</h2>
<a href="https://developer.mozilla.org/ja/docs/Web/CSS/gradient/radial-gradient()">radial-gradient() - CSS: カスケーディングスタイルシート | MDN</a>
【React】インポートしたコンポーネントの状態を取得

##まず、親コンポーネント(読み込む側)
まず1行目でimportで持ってきて、読み込んだタグを使うとき、「ref=”好きな名前”」って感じで名前をつけて、使うときは以下のようにして、「this.refs.{好きな名前}.{子で定義したメソッド}」

```javascript:anime-suko.js
import { SelectForm } from './select.js';
hoge(e){ //api使ったりするメソッド
    const selectData = this.refs.MySelectForm.getValue();
    console.log("データは、", selectData)
}
    return (
      <div>
     <SelectForm items={['user', 'timeline', 'event'] value=’user’} ref='MySelectForm' />
      </div>
    )


```

##子コンポーネント(読み込まれる側)
getValueメソッドのような、状態を返すメソッドを用意

```javascript:anime-suko.js
import React, { Component } from 'react'
import styles from './styles'
 
export class SelectForm extends Component {
  constructor(props) {
    super(props)
    //propsは、このコンポーネントを使うときに指定されたものを取得する  <SelectForm items={['user', 'timeline', 'event']} value='user' 
    this.state = {
      items: props.items,//selectボックスの、選択肢すべての文字列がある配列
      value: props.value //selectボックスの、選択しているもの
    }
  }
 
  //selectボックスを変更したとき
  doChange(e) {
    this.setState({ value: e.target.value })
  }
 

```

## 感想
業務でフロントをやる機会がほとんど無いので、学生時代にやっていたReactを少しやってみた。
フロントはフロントで見なきゃいけないファイルが多くて大変だなぁって思った。
Amazon SNS 暗号化の有効化の注意点


#暗号化の有効化

以下の設定のこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224973/ed65ca8c-e8a2-0879-2957-a0a3cb27ab18.png)


#発生した事象その1

上記の暗号化を有効にしたまま、`CloudWatch `→`SNS` を実施したが通知されなかった。



#対処方法

以下の `SNS トピックの暗号化が原因で、トリガーアクションが失敗している場合:` にある通り、 `alias/aws/sns` を
使用するのではなく、 `カスタマーマネージドキー` を使用すべきだった。


https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudwatch-receive-sns-for-alarm-trigger/

その際、以下のキーポリシーを設定する。

```shell-session
{
    "Sid": "Allow_CloudWatch_for_CMK",
    "Effect": "Allow",
    "Principal": {
        "Service":[
            "cloudwatch.amazonaws.com"
        ]
    },
    "Action": [
        "kms:Decrypt","kms:GenerateDataKey*"
    ],
    "Resource": "*"
}
```


#発生した事象その2

以下にあるように `GuardDuty`→`EventBridge`→`SNS`と連携させた。

https://dev.classmethod.jp/articles/event-bridge-notify-sns/

しかし、`SNS` で通知されない。

#対処方法

以下の `SNS トピックが暗号化されている場合は、KMS キーポリシーに以下のセクションを含める必要があります。` が必要だった。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-troubleshooting.html#eb-no-messages-published-sns


```shell-session
{
                "Sid": "Allow CWE to use the key",
                "Effect": "Allow",
                "Principal": {
                                "Service": "events.amazonaws.com"
                },
                "Action": [
                                "kms:Decrypt",
                                "kms:GenerateDataKey"
                ],
                "Resource": "*"
}
```
Macで使いたいChromeショートカット

英字キーはわかりやすくするため大文字表記

# タブ移動系
## 次のタブに移動

```
{ctrl} + {tab}
```

## 前のタブに移動

```
{ctrl} + {tab} + {shift}
```

## 新規タブ

```
{cmd} + T
```

## タブ削除

```
{cmd} + W
```

## タブ復元

```
{cmd} + {shift} + T
```

## タブ複製

```
{cmd} + L + {cmd} + {Enter}
```

URL選択状態にする
→別タブでURL閲覧

# ウィンドウ系
## 新規ウィンドウ

```
{cmd} + N
```

## 新規シークレットウィンドウ

```
{cmd} + {shift} + N
```

## ウィンドウ切り替え

```
{cmd} + {shift} + @
```

これは設定変更が必要なので参考記事↓

https://qiita.com/takuyanin/items/54328fe7817f6ee2c17f

# その他
## 検索(URL入力欄に移動)

```
{cmd} + L
```

## ブックマーク登録

```
{cmd} + D
```

## ページ名だけコピー

```
{cmd} + D + {cmd} + C + {esc}
```

ブックマーク登録ポップアップ表示
→この時点でページ名が選択状態
→ページ名をコピーする
→ブクマ登録したくないのでescキーでポップアップを非表示にする
ラズパイでJenkinsを動かしてGitHubのWebhookでPipelineを実行する

# GitHubのWebhookでラズパイ上のJenkinsでPipelineを動かしたい
GitHubのWebhookではJenkinsが動いているサーバーを指定しないといけません。
しかし、自宅で動かしているラズパイを指定するには固定のグローバルアドレスを付与したり、やりたければドメイン名も設定したり面倒です。
特にルーターを設定して外部からの通信を許可しなきゃいけないので、セキュリティ的に自信がありませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/c1af3a73-6679-af12-6341-f489ae991842.png)

そこで何かいい方法がないかと探していたら、GitHubが提供している[smee.io](https://smee.io/)というサービスがあったので、JenkinsがWebhookを受け取るところまでの手順を書いていこうと思います。
Jenkinsのブログ[^2]で紹介されていたので、こちらも参考にしていただければと思います。


# smee.ioとは
公式サイト[^1]に一言で書いてありました。

> Webhook payload delivery service
> Receives payloads then sends them to your locally running application.

Webhookを受け取ってローカルで動いているアプリケーションに送る届けるサービスらしいです。
smee.ioを使うとこんな感じで自宅のラズパイにWebhookのpayloadを送れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/01fb9484-f3de-55fd-065c-0537394a1058.png)

# 導入する
## Jenkinsの設定
### 1.Dash Board > New Item でPipelineを選択する
適当な名前をつけてPipelineを選択してOKを押します。
![new_item.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/95301b56-3dd9-aedc-6117-1141584f0dcf.png)

### 2.Pipelineを設定する
* Build Triggersで「GitHub hook trigger for GITScm polling」を選択
* Pipelineで画像のように選択して、Repository URLにリポジトリのURLを入れる

![jenkins_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/6f07d8cf-9dd3-4dca-565e-fe62781ad2f4.png)

## smee.ioの設定
### 3.smeeサーバーのURLを発行する
https://smee.io/ で「Start a new channel」をクリックするとURLが発行されます。
後にそのURLにGitHubからWebhookを投げることになります。

### 4.smeeクライアントをラズパイにインストールする
```$ npm install --global smee-client```で ラズパイにsmeeクライアントをインストールします

### 5.smeeクライアントを動かすためのユニットファイルを書く
systemdを使っていることを想定しています。これはどっちでもいいですがあると楽なので。

```ini
[Unit]
Description=foo

[Service]
Type=simple
ExecStart=/usr/local/bin/smee --url https://smee.io/<id> --path /github-webhook/ --port 8080
Restart=always

[Install]
WantedBy=multi-user.target
```

## GitHubの設定
### 6.Webhookを送るURLを設定する
リポジトリを選んで、Settings > Webhook で3で生成したsmeeサーバーのURLを入れる。
これで設定は終わりです！

# 動かしてみる
pushしてWebhookが投げられると、3で作ったsmeeサーバーのURLでWebhookの履歴が見れます。
ここでWebhookが動いていることが分かるので便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/4dc64029-4f07-a0ef-f08c-764715be9bb2.png)

また、JenkinsでPipelineが動いていることがわかります。
![jenkins_build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880578/6b3aa102-8faf-efc5-e6c9-de0b72e85327.png)


[^1]: [smee.io](https://smee.io/)
[^2]: [Jenkinsのブログ](https://www.jenkins.io/blog/2019/01/07/webhook-firewalls/) ここにほとんどやり方載ってます
KUSANAGIでファイル改ざん検知のIDS Tripwireを試してみました

KUSANAGIでにファイル検知ができるIDS（侵入検知システム）がアドオンとしてインストールすることができるとのことで試してみました。

![saya2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/4279a075-8cb3-8057-f4f9-50e2dc750fa5.png)

IDSは[tripwire](https://www.tripwire.com/)というオープンソースソフトウェアになります。


## 注意点

tripwireでは設定ファイルの作成、ファイルポリシーDBの更新などにパスフレーズ（パスワード）が必要となります。
ｔripwireの設定にはこの２つのパスフレーズ使うため、忘れてしまうと操作ができなくなるので注意が必要です。

名前 | 用途
----|----
ローカルパスフレーズ (local passphrase) | データベースファイル。レポートファイルの暗号署名に使用する
サイトパスフレーズ (site passphrase) | 設定ファイル、ポリシーファイルの暗号署名に使われる


リセットの方法ですが、tripwireを削除して再インストールする方法が良かったです。

```bash
$ sudo sh -c 'kusanagi addon remove tripwire && rm -rf /etc/tripwire && kusanagi addon install tripwire'
```


## インストールから利用まで

[こちらのサイト](https://column.prime-strategy.co.jp/archives/column_2353)にとても良くまとまっていて、この通りに作業をすれば設定が可能でした。ただいくつかのコマンドでレターケース等の変更が必要でした。

インストールから設定の流れは下記の通りになります。

1. tripwireのインストール
1. 設定ファイルの編集
1. 設定ファイルの暗号化、DB初期化
1. 動作テスト


### tripwireのインストール

インストール時にローカルパスフレーズとサイトパスフレーズの入力を求められます。
ここで最初に入力するものが設定になり、後から入力するものは確認となります。

```bash
$ sudo kusanagi addon install tripwire
```

自分の場合には途中でパスフレーズの入力に失敗してしまい、中途半端に設定ファイルが出来上がってしまいました。

### 設定ファイルの編集

`/etc/tripwire/`にある設定ファイルを編集します。このディレクトリはroot権限で見ることができるので、一般ユーザをrootグループにいれてグループの権限を出しておくと作業しやすいです。（rootになって作業をしないように…）

```bash
$ sudo usermod -aG root $(whoami) && sudo chmod g+rw /etc/tripwire
```

twpol.txt というファイルの166行目付近で、検知の通知先の `emailto` と 対象となるディレクトリを追加しました。

```text:/etc/tripwire/twpol.txt
(
  rulename = "Invariant Directories",
  severity = $(SIG_MED),
  emailto = yousan@gmail.com
)
{
  /                                    -> $(SEC_INVARIANT) (recurse = 0) ;
  /home                                -> $(SEC_INVARIANT) (recurse = 0) ;

  /etc                                 -> $(SEC_INVARIANT) (recurse = 0) ;
  /home/kusanagi -> $(SEC_INVARIANT) (recurse = -1) ;
}
```

参考サイトの記事では簡便のため /home/kusanagi を入れており、今回もその例にならいました。実運用ではuploadsやログの除外等、この設定を細かく制御する必要がありそうです。

この設定ファイルの形式がわかりませんでしたが、`emailto` 辺りは連想配列のようですのでカンマの位置などに注意が必要です。

### 設定ファイルの暗号化、DB初期化

設定ファイルを暗号化して tw.cfg を作成します。パスフレーズが必要です。

```bash
$ sudo twadmin -m P -c /etc/tripwire/tw.cfg -p /etc/tripwire/tw.pol -S /etc/tripwire/site.key /etc/tripwire/twpol.txt
```

ポリシーDBを作成します。（大文字小文字に注意が必要でした）

```bash
$ sudo tripwire --update-policy -Z low /etc/tripwire/twpol.txt
```

### 動作確認

動作確認を行います。

```bash
$ sudo -u kusanagi touch /home/kusanagi/example.com/testfile
```

実際の動作には下記のコマンドで検査を行います。

```bash
$ sudo tripwire -m c -c /etc/tripwire/tw.cfg -M
```

下記のような警告が表示されました。

```bash
Modified:
"/etc/tripwire/tw.pol"

-------------------------------------------------------------------------------
Rule Name: Invariant Directories (/home/kusanagi)
Severity Level: 66
-------------------------------------------------------------------------------

Added:
"/home/kusanagi/example.com/hoge2"
```

## 終わりに

実際の運用には設定ファイルを細かく書く必要がありそうです。またWordPressのコア、プラグインのバージョンアップなどでも応答してしまいそうなため注意が必要そうです。


## 参考情報

https://column.prime-strategy.co.jp/archives/column_2353

https://qiita.com/daijuk/items/8d019f072e4ec8ceaa3b

[Tripwireのインストール](https://www.itmedia.co.jp/help/howto/security/trip/01/02.html)
Redmine のリストア

今までの話:

* Ansible で AWS にワンタッチで Redmine を作る: https://qiita.com/propella/items/7209dfda27f665766867
* Let's Encrypt と Nginx を使った Web アプリの HTTPS 化: https://qiita.com/propella/items/6a4b964fd010585530d2
* Ansible + CloudFormation + docker-compose で作った Redmine のバックアップ: https://qiita.com/propella/items/4d13ef1ccf98abafd94f

実は私は大昔に壊れた redmine を一つ持ってます。Ruby が分からず面倒で放置しておりました。せっかくなのでそのデータを復旧させます。

まず https://redmine.jp/faq/system_management/backup/ に従い旧サーバの files と mysqldump を取得します。

    mysqldump -uxxx -pxxx redmine | gzip > redmine-old.sql.gz
    (cd /path/to/redmine-2.3.4/ && tar czf ~/redmine-old-files.tar.gz files)

これを新しく redmine が動いているホストに置きます。docker で動いている関係上新しい添付ファイルは redmine-files/ に sudo chown -R 999:999 して置く事にします。

files の復旧:

    tar xzvf old/redmine-old-files.tar.gz
    sudo rm -r redmine-files/*
    sudo mv files/* redmine-files
    sudo chown -R 999:999 redmine-files
    rmdir files

mysql の復旧

    zcat old/redmine-old.sql.gz | docker exec -i redmine_db /bin/bash -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD redmine'

移行の実行

    docker exec redmine_app bundle exec rake db:migrate RAILS_ENV=production

ここで大量にエラーが出ます。。。私の場合以下のエラーが順番に出ました。(一個消すと一個出る)

* Mysql2::Error: Table 'queries_roles' already exists
* Mysql2::Error: Table 'custom_fields_roles' already exists
* Mysql2::Error: Table 'email_addresses' already exists
* Mysql2::Error: Table 'roles_managed_roles' already exists
* Mysql2::Error: Table 'imports' already exists
* Mysql2::Error: Table 'import_items' already exists
* Mysql2::Error: Table 'custom_field_enumerations' already exists

仕方が無いので一つずつ手動で消します。

    docker exec redmine_db /bin/bash -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD redmine -e "drop table queries_roles"'
    ...

正しい方法かわかりませんが、面倒で正式な方法を調べるのをサボってしまった。一応動いているので良しとします。これで過去の記録が見事に蘇りました。

## 参考

* Redmine > 3.1→3.4へバージョンアップ: https://qiita.com/sugasaki/items/ebd1d7d3fa2b4752deef
* Redmine データのバックアップ方法: https://redmine.jp/faq/system_management/backup/
* Remine ガイド アップグレード: http://guide.redmine.jp/RedmineUpgrade/
SSGのLinkタグが発火しないときの話

##やりたいこと
- hoverにtransformとkeyframesを割り当てたい


###詰まった問題
>Next.js公式ドキュメントの通りaをLinkで囲うとtransformできない。

###改善の仕方
公式のLinkでaを囲う順序を逆にし,aタグでLinkを囲うようにすることで解決した。




#わかったこと
- モバイルではLinkタグはkeyframesを使うと画面推移されない。
- モバイルレスポンシブ版のCSSではそもそもtransformを使う必要性が少ない。
Flutter開発でAndroid StudioからVSCodeに切り替えた

## なぜAndroid StudioからVSCodeに切り替えたのか
単純に軽い動作環境で開発をしたかった、というところが大きいです。Android Studioはそれなりのマシンパワーを要求されるという面があり、個人としては自分の予算次第ではスペックの良いマシンを使って、不自由なく開発出来ると思います。

しかし参画した案件で、あるいは入社した会社で必ずしも最新のPCがお借り出来るとは限りません。そういう場合でも快適に開発出来るのではと、VSCodeに対して関心が高まりました。

## 実際に切り替えてみて良かったところ

#### やはり動作は軽快、しかし補助機能は充実している
VSCodeはやはり起動も早いところが魅力です。ざっくりですが、Android Studioの時はまずAndroid Studioを開いた時に長い読み込み時間があり、その後ビルドすることになるので、2回待つような感覚がありましたが、VSCodeだと待つのはビルド時のみ、という感覚です。

実際に切り替えてからは、実はコードの補完などもしっかり充実しており、flutterで頻繁に行う、Widgetを別のWidgetで囲ったり、削除する「Wrap this Widget」や「Remove this Widget」などの機能はVSCodeでもしっかり実現されています。それでも切り替えた当初はAndroid　Studioよりはコード補完が弱い気がしたのですが、少し慣れてしまえば特にそういったこともない気がします。

またFlutterのエコシステム的にもFlutterの公式ドキュメントにVSCodeでの環境構築の項目があるのはもちろん、例えばFlutterの状態管理ライブラリのRiverpodの公式ページにもriverpod用のスニペット拡張機能が紹介されていたり、VSCodeはFlutter開発においては、Android Studioと同じく公式推奨であるといえます。

https://marketplace.visualstudio.com/items?itemName=robert-brunhage.flutter-riverpod-snippets

#### Method Channelなどを書く時にエディタの切り替えが不要
Flutterにおいて、やはり様々なパターンでiOS/Androidのコードを呼び出す必要があります。Android Studioで開発をしていたときは、SwiftやKotlinを書く際にAndroid Studioを開き直したり、XCodeを開いたり、切り替えが目まぐるしいと思っていました。

VSCodeに切り替えてからは、SwiftやKotlinの補完も効くので、SwiftやKotlin書く必要があるときも特にエディタを開き直したりすることなく、開発ができるようになりました。

※とはいえ、私はSwiftやKotlinに関しては1から調べつつ、何とか書いているような感じなので、これらの言語に慣れていて、XCodeやAndroid Studioで開発をされてきた人からすると貧弱に感じることや、物足りないところがあるかもしれません。

#### ターミナルを中心にした開発が心地良い

ここは少し余談で、そもそもVSCode自体の話とは少し違うのですが、VSCodeに切り替えてからは自然とターミナルを中心にした開発スタイルになりました。
（Android　Studioの中でもターミナル操作したり出来るのですが、VSVodeの軽快さにさらに後押しされた気がします）

以前、シェルをfishを使うようになった記事を書きました。こういったコマンドの補完が有効なシェル環境は大事です。

[【環境構築】fishの環境設定手順](https://qiita.com/toda-axiaworks/items/7376aee0a47400a35190)

fishに限らずzshでも良いのですが、エディタにコマンドの補完が効く状態にしておくことは大切かな、と思っています。今はプロジェクトファイルを開くのもシェルからVSCodeを起動して、ビルドもシェルから実行していますが、シェルのコマンド入力で補完が有効になっているのと、いないのとでは、VSCodeにスイッチ出来るか出来ないかの分かれ目にもなると思います。（補完無しでのコマンド入力は厳しい）

最近はFlutterの頻繁なバージョンアップ対応の調査のためなど、Flutterバージョン管理ツールのfvmを利用しています。

https://github.com/leoafarias/fvm

fvmでFlutterバージョンアップして試しにビルドしてみる、などといったことが気軽に試せるようになりました。
fvmを導入すると、例えば`fvm flutter clean`、　`fvm flutter run --device-id <デバイスID>`というようにコマンドの最初にfvmをつける必要があります。以前はこれが嫌でfvmは使わないようにしていたのですが、シェルの補完と組み合わすことで気にならなくなりました。

あと結構細かい話だとrunもコマンドで実行すると、プロジェクトなどによっては、設定されているdart-defineをしっかり意識できます。

### まとめ

結論としては、これからもFlutter開発はVSCodeでやっていこうと思います。

私自身、Android Studioもかなりお気に入りのツールで、Gitの操作もほぼ全てAndroid Studioでやるほどだったのですが、fvmでのFlutterバージョン切り替え、FlutterではSwiftやKotlinのコードも確認したり書いたりする必要がある、あたりが決め手になった感じがします。

いきなり完全にスイッチできた訳ではなく、最初は慣れずAndroid Studioに何回か戻ることもありました。一応何となく環境だけ作ってみて、合わなければAndroid Studioに戻るのもアリだと思います。

VSCodeへのスイッチの挫折ポイントはターミナルの操作に慣れないなどもあると思っていて、場合によってはターミナルだとログを見るのもままならない場合もありそうです。とはいえFlutterはbuild runnerコマンドでのコードの生成などが必要だったり、ターミナルと仲良くなっておいて損はない気がします。
【初心者向け】RDBMS（リレーショナルデータベースマネジメントシステム）とは

#はじめに
今回は、RDBMS（リレーショナルデータベースマネジメントシステム）の特徴について簡単に説明します。

#RDBMSとは
データがたくさんある場合、１つのテーブル（表）でそのたくさんのデータを管理するのはとても大変ですし、重複するデータを何度も記述していてはバイト数もどんどん増えてしまいますよね。
そこで、データを複数のテーブルに分けて管理し、テーブル同士を関連付けることによって、たくさんあって複雑なデータも効率よく管理することができるようにしたのが、RDBMSです。

#RDBMSの特徴
RDBMSの特徴としては、「正規化」と「結合」というものがあります。

### ①正規化とは
同じテーブル内でのデータの重複をなくすために、データを分割したり、整理するなどしてデータベースを設計することを「正規化」と言います。
正規化により、データの重複がなくなるので、データに矛盾が生じるのを防ぐことができるというメリットがあります。

### ②結合とは
共通の値を持つカラムをキーとして、２つ以上のテーブルを１つにまとめる操作のことを「結合」と言います。
結合については、外部結合や内部結合などがあるので、それについては別の記事で紹介したいと思います。

#おわりに
まずは、RDBMSがどのような特徴を持っているのかを覚えておきましょう。
ksnctf #20 G00913

#G00913
https://ksnctf.sweetduet.info/problem/20

πの連続する桁で見つかった最初の10桁の素数を求める問題。

標準のmath.piだと15桁しか表示できない。
mpmathは任意精度演算ライブラリでmpmath.dpsで任意の桁数を指定できる。

素数判定の関数は以下を参考
https://qiita.com/hanaata/items/976ff9aa7bd64203a619

1000桁のπを文字列に変換する。左から10桁の値を素数判定しながら右にずらしていく。
素数が見つかったらbreakでfor文を終了する。

```python
from mpmath import *
mpmath.dps = 100

#素数判定
def is_prime(n):
    if n == 1: return False

    for k in range(2, int(mpmath.sqrt(n)) + 1):
        if n % k == 0:
            return False

    return True


str_pi=str(pi)

for i in range(2,mpmath.dps-10):
    if(is_prime(int(str_pi[i:i+10]))):
        print(str_pi[i:i+10])
        break
```

#まとめ
ほしい関数は調べれば大体出てくる
ABC95 C - Half and Half から学んだ

https://atcoder.jp/contests/abc095/tasks/arc096_a

![ABC95_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/de7cfeb1-ac3a-9ebf-7292-f99cfe1ba9d8.png)
![ABC95_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/80d2c7a1-0388-2fce-4ab3-4222507884c7.png)
![ABC95_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/300081f9-19a5-6af4-2811-0c3f0a06d21e.png)

考えても良くわからず、以下のページの冒頭、"AB ピザの全探索" が見えてピンときた。

https://blog.hamayanhamayan.com/entry/2018/04/21/224451

ろくに読まずに、思いついたまま書いたら通った。

```halfandhalf.py
A,B,C,X,Y = map(int,input().split())

#X,Y 多い方 を 2 倍だけ AB ピザを用意できれば、
#worst case を加味して全探索したことがいえる 
N = 2*max(X,Y)
score = 0
ans = float("inf")
for n in range(N+1):
    cur = (n//2)
    if X-cur >= 0 and Y-cur>=0:
        score = n*C+(X-cur)*A+(Y-cur)*B
    elif X-cur < 0 and Y-cur>=0:
        score = n*C+(Y-cur)*B
    elif X-cur >= 0 and Y-cur <0:
        score = n*C+(X-cur)*A
    else:
        score = n*C

    if score < ans:
        ans = score
print(ans)
```

勿論、以下の記述でも通る。

```halfandhalf.py
A,B,C,X,Y = map(int,input().split())

ans = float("inf")
score = 0
#X,Y の最大値はそれぞれ 10**5 。
#その場合 AB ピザは 2 * 10**5 枚、最大で必要となる
#これがイメージ出来れば以下の記述でも対応可能
for i in range(1+2*10**5):
    if i%2 == 0:
        Z = i//2
        if X-Z >= 0 and Y-Z>=0:
            score = A*(X-Z) + B*(y-z) + C*i
        elif X-Z < 0 and Y-Z >= 0:
            score = B*(Y-Z) + C*i
        elif Y-Z < 0 and X-Z >= 0:
            score = A*(X-Z) + C*i
        else:
            score = C*i
    ans = min(ans,score)

print(ans)
```

***

再チャレンジしました。
X , Y が負になる場合に注意して AB ピザの全探索を
すれば大丈夫です。

自力で回答に辿り着けました。
ちょっとは実力が付いたみたいで嬉しいです。

```abc95c.py
A,B,C,X,Y = map(int,input().split())

ab_cnt = 2*max(X,Y)
#print(ab_cnt)
ans = 10**100
for i in range(ab_cnt+1):
    if X-(i//2) < 0 and Y-(i//2) < 0:
        num = C*i
    elif X-(i//2) < 0 and Y-(i//2) >= 0:
        num = C*i+(Y-(i//2))*B
    elif X-(i//2) >= 0 and Y-(i//2) < 0:
        num = C*i+(X-(i//2))*A
    else:
        num = C*i+(X-(i//2))*A + (Y-(i//2))*B
    ans = min(ans,num)

print(ans)
```
【props】classNameを複数追加する方法

# 効率よくpropsを渡す
**ボタンコンポーネント**のようなものを作っていて、それを別のコンポーネントで使い回すとします。

そうすると、**「ここのボタンの色は赤で」****「こっちの文字色は白にして」**などCSSをそれぞれ少しずつ変更させる必要が出てきたりします。

そんなとき、こちらの方法を知っていると**”効率的”**にCSSを変更できるようになります。

# Classnames
[Classnames](https://www.npmjs.com/package/classnames#usage-with-reactjs)を使って、複数のclassNameをpropsで渡してみました。

```Button.tsx
import React from "react";
import styles from "./Button.module.scss";
import classNames from "classnames";

interface PropsTypes {
  backgroundColor?: "primary" | "gray";
  border?: "none";
  fontWeight: "bold";
  textColor?: "white" | "black";
  onClick: React.MouseEventHandler<HTMLParagraphElement> | undefined;
  text: string;
}
const Button = ({
  backgroundColor,
  border,
  fontWeight,
  onClick,
  text,
  textColor,
}: PropsTypes) => {
  return (
    <div
      className={classNames( // ココからclassNames関連
        styles.root,
        { [styles.primary]: backgroundColor === "primary" },
        { [styles.gray]: backgroundColor === "gray" },
        { [styles.borderNone]: border === "none" },
        { [styles.fontWeight]: fontWeight === "bold" },
        { [styles.black]: textColor === "black" },
        { [styles.white]: textColor === "white" }
      )}
    >
      <p onClick={onClick}>{text}</p>
    </div>
  );
};

export default Button;
```

```Button.module.scss
.root {
  border: 1px solid rgb(180, 180, 180);
  border-radius: 5px;
  cursor: pointer;
  color: rgb(121, 121, 121);
  display: flex;
  font-size: 0.6rem;
  padding: 5px;
  p {
    width: 100%;
  }
}
//----- propsCSS -----//
.borderNone {
  border: none;
}
.black {
  color: black;
}
.fontWeight {
  font-weight: bold;
}
.primary {
  background-color: #05c757;
}
.gray {
  background-color: #e5e5e5;
}
.white {
  color: white;
}

```

このように記述することによって、たとえば別のコンポーネントで`<Button>`コンポーネントを呼び出す時に、

```sample.tsx
<Button
  backGroundColor={"primary"}
  fontWeight={"bold"}
  // その他省略
/>
```
このようにpropsで値を渡してあげると、その値に合ったCSSが適用されるようになります。

# まとめ
**Classnames**というライブラリは知らなかったのですが、いろんなclassNameのpropsを渡したい時に重宝しそうです。

また、propsの渡し方がまだまだ無駄があることが多いので、そのあたりもしっかり学びなおして行こうと思います。

### 追記
現在[Coadmap](https://coadmap.com/welcome/driver)というサービスを使って学習しているのですが、そちらの添削サービスにて添削を受けた内容を、今回の記事としてまとめてみました。

実務で実際に使われているコードの書き方だったりを学べるので、とてもいいサービスだと思います。
ぜひ興味のある方は、サイトを覗いてみてください。
discordのInteractionについていろいろまとめてみた

discordのInteractionについてのいろいろまとめ。
# 概要
Interactionを登録・送信してから、それらに対してのリアクション（例えばスラッシュコマンドであればコマンド実行時）があると`Interaction Create`イベント or Webhook経由のどちらかでそれを受け取ることができる。
Webhook経由で受け取りたい場合、`Interactions Endpoint URL`という項目を設定すればOK。

# Interaction
## Application Command
コマンドをあらかじめREST APIで登録しておく。
GuildとGlobalコマンドがあり、
Globalコマンドすべてのギルドで使えるが、登録・更新に最高1時間かかる。
Guildコマンドは特定のギルドでしか使えないが、即座に登録・更新される。

そのため、開発ではGuildコマンドを利用し、本番ではGlobalコマンドを利用する運用が良さそう。


### Slash Command
ご存知スラッシュコマンド
/から始まるメッセージを送ることで実行されるコマンド。

### User Commands
右クリックメニューから使えるコマンド。
### Message Commands
メッセージを選択して右クリックメニューからつかえるコマンド。
これを使った場合、Interactionに指定したMessageの内容が入る。
## Message Components
メッセージの新しいフィールドとして使えるので、メッセージを送信する時やInteractionへのレスポンスの時に利用できる。
### ボタン
押しボタン。
色もいろいろ変えれる。
### プルダウンメニュー
メニューから項目を選択するメニュー。
設定次第で選択数の制限（例えば2個以上5個以下選択しなければならないなど）もできる。
Simulation by Octave GNU

# Octaveでシミュレーションをやってみたい
そもそものモチベーションは植物生理学をもとにしたシミュレーションをやってみたいからだ

## 作業環境のOctaveのバージョン
```:Octave
>> version
ans = 6.3.0
```

## Octaveを使ってシミュレーションした記事はこちらを参考にした
https://qiita.com/rkn/items/ee78f0b6703300f9a63b

**なお、本記事に出てくるOctaveのコードは、上記記事から引用したものである。**

シミュレーションは、入力に対して出力がどうなるか、を計算して結果を得るのが目的なので、まずは伝達関数によるシンプルなシミュレーションを行うことにした。

そのパッケージであるControlを手に入れる。

### OctaveにControlパッケージをインストールする

https://octave.sourceforge.io/control/

```:Octave
>> pkg install -forge control
```

伝達関数は、制御工学において、入出力の関係を表す関数で、その入出力システムの挙動や安定性を評価するもの。
$P(s)$のように表現し、$s$は複素数。どのような入力に対しても、伝達関数を用いれば出力が求まるためには、変数は時間$t$ではなく、複素数によって表現されるs領域$s$を用いる。

つまり、(出力)=(伝達関数)×(入力)の形式である。
出力を制御するためには、伝達関数が肝であることが分かる。


基本関数の特性については、東北大学の張山先生による以下のテキストが参考になる：
基本伝達関数の特性

http://www.ecei.tohoku.ac.jp/hariyama/lecture/control/control-04.pdf



「一次遅れ＋むだ時間」系のモデルの記述式は以下：

```math
P(s)=\frac{K}{1+Ts} e^{-Ls}
```

それぞれの文字の意味は次の通り：

|文字|意味|
|:-|:-|
|$P$ |伝達関数|
|$s$ |s領域|
|$K$ |ゲイン|
|$T$ |時定数（小さいほど入力に対して出力が早くなる）|
|$L$ |むだ時間|

まずはモデリングをする上で、定数を以下の通り設定することにする

|文字|値|
|:-|:-|
|$K$ |0.5|
|$T$ |40.0|
|$L$ |8.0|

```:Octave
% 推定した制御対象のモデル
K = 2.0;
T = 40.0;
L = 8.0;
P = tf(K,[T,1])*tf([-L/2,1],[L/2,1]);  % Octaveの場合（一次で近似）
```

制御器の設計をする

不完全微分付きPIDコントローラを以下の式で表現する
$$C(s)=k_p\left( 1+\frac{1}{{T_i}s}+\frac{T_ds}{1+0.125 {T_d}s} \right)$$

|文字|意味|
|:-|:-|
|$C$ |PID制御伝達関数|
|$s$ |s領域|
|$k_p$ |比例ゲイン（$p:$Proportional）|
|$T_i$ |積分時間（$i:$Integral）|
|$T_d$ |微分時間（$d:$Differential）|

PIDコントローラの設計式の詳細は日本工業新聞の以下の記事を参考にした：

https://www.nikko-pb.co.jp/products/k_data/28P_31P_13.pdf

Octaveコードは以下

```:Octave
kp = 0.6*T/K/L;
Ti = 1.2*T;
Td = 0.5*L;
C = kp*(1+tf(1,[1,0])/Ti+Td*tf([1,0],[0.125*Td,1]));
```

ここで、シミュレーションの結果をグラフに表示すると

```:Octave
>> pkg load control

% 推定した制御対象のモデル

K = 2.0;
T = 40.0;
L = 8.0;
P = tf(K,[T,1])*tf([-L/2,1],[L/2,1]);  % Octaveの場合（一次で近似）

% PIDコントローラの設計

kp = 0.6*T/K/L;
Ti = 1.2*T;
Td = 0.5*L;
C = kp * ( 1+tf(1,[1,0])/Ti + Td * tf([1,0],[0.125*Td,1]))

margin(P*C);
step(P*C/(1+P*C));
step(1/(1+P*C));
```

グラフが表示された。
![スクリーンショット 2021-09-24 23.38.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21771/e6f85fea-b52d-98d5-f4a4-5a10cfb92d41.png)
Google colabの90分切れに対応する

# はじめに
Google Colab、便利でいいですよね。無料でGPUも使えるし機械学習、特にディープラーニングでガシガシ画像処理したい時はお世話になってます。

ただ厄介なのが90分制限。90分何も操作しないと自動的にセッション切れしてしまって学習が止まってしまうやつです。

まぁ学習中に論文見て手法考えたりとかすればいいんですけど、息抜きしたいとか、寝てる間に学習進めたいとかもあると思うので、それに対応しようと思います。

# 環境
chrome
Google colab
あとjupyter 環境もあるといいです

# pyautoguiを使う
要は自動的にマウスなど動かしてあげればいいのでそういうライブラリがないかと調べてみたらありました。

pyautoguiというやつで色々便利なことができそうです。

pipでインストール

```python
pip install pyautogui
```

必要なものをインポート

```python
import time
import pyautogui as pgui
```

以下のコードを学習を実行している環境（今回だとGPUのcolab）以外で実行する
実験的にコードを動かしたりなどは普段jupyter labを使っているのでjupyter labで動かします。
Jupyter環境無ければ、colabはGPUありとGPUなしで同時に2インスタンス立ち上げられるので、GPUなしのcolabタブで実行しましょう

```python:学習を実行している環境以外で実行
for _ in range(72):
    time.sleep(600) # 10分待機
    pgui.click(x=652, y=703, duration=1) # 指定した座標に1秒かけて移動してクリック
    time.sleep(1) # 1秒待機
    pgui.click(x=664, y=638, duration=1)
```

pgui.click()で指定した座標に自動的にマウスカーソルを移動して、クリックします。引数durationの値で何秒かけて移動するか指定できます。

指定した座標がどの位置なのかわかんねーよってなると思うので
`pgui.position()`を実行すると今マウスカーソルがいる位置の座標を表示してくれます。

これを実行することで10分待機した後、移動してクリック、1秒待って、別の場所に移動してクリック
という動きを72回繰り返します。(単純計算で72×10分＝12時間)
72という数字は学習にかかりそうな時間で好きに変えてください。

あとは
①chromeでcolab(学習を実行する場所）とjupyterlab（pyautoguiを実行する場所）を別タブで開く
②jupyterlabのpyautoguiを実行
③colabに表示タブを切り替え、学習スタート

とすれば自動的にcolabの画面上でマウスカーソルが行ったり来たりするので、勝手にセッション切れや、スリープしません。
パソコン自体のスリープ機能もオフにしておくとなお、いいでしょう。

# まとめ
心置きなく睡眠中に学習が進められます。止まってないか神経すり減らさなくて済みそうです。
Azure Synapse Analytics の専用SQLプール（Dedicated SQL Pools）容量制限について（特にシステム動的管理ビューの最大行数）の注意喚起

# はじめに
Azure Synapse Analyticsの専用SQLプール（Dedicated SQL Pools）の諸々の容量制限は、理解しておいた方が良いです。
そして、本記事は特にシステム動的管理ビューの最大行数について言及したい。

# システム動的管理ビューとはなんぞや？
> 動的管理ビューと動的管理関数では、サーバーの状態情報が返されます。返された情報は、サーバー インスタンスのヘルス状態の監視、問題の診断、パフォーマンスのチューニングに使用できます。

[参照先](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/system-dynamic-management-views?view=sql-server-ver15)

要するに、問題を特定したり、パフォーマンスチューニングに使えるビューですね。
クエリが遅かったりとか、原因究明する際に使います。

# システム動的管理ビューの最大行数（注意喚起）
![スクリーンショット 2021-09-24 23.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70138/ea5a9424-6029-db9b-1c22-9b415fc2100c.png)
[参照先](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/system-dynamic-management-views?view=sql-server-ver15)

驚くべきことに、 `sys.dm_pdw_exec_requests（リクエスト・クエリの情報）` の最大行数は `10,000` です。
クエリを大量に投げていたら、この最大行数の `10,000` なんてあっという間です。

さらに、クエリの詳細を追っていきたい場合は `sys.dm_pdw_request_steps（リクエスト・クエリを作成するすべての手順に関する情報）` でクエリのステップごとの情報をを見ていくのですが、なんと、 `sys.dm_pdw_exec_requests` の最新の1,000個の要求に対するステップしか確認できません…

原因究明なんて、とてもじゃないができません…
そして、これは `Azure Synapse Analytics` の仕様です…

# 結論
大量のクエリを投げたら、原因究明できなくなるから、注意が必要です。
みなさま、気をつけましょう。
railsチュートリアル第6章 ユーザーを検証する

##ユーザーを検証する
作成したUserモデルに、アクセス可能なnameとemail属性が与えられました。
しかし、これらの属性は```どんな値でも```取ることができてしまいます。現在は（空文字を含む）```あらゆる文字列が有効```です。
名前とメールアドレスには、もう少し```何らかの制限```があってよいはずです。
例えばnameは空であってはならず、emailはメールアドレスのフォーマットに従う必要があります。
さらに、メールアドレスをユーザーがログインするときの一意のユーザー名として使おうとしているので、メールアドレスが```データベース内で重複することのないようにする```必要もあります。

要するに、nameとemailにあらゆる文字列を許すのは```避ける```べき。
これらの属性値には、何らかの制約を与える必要があります。
Active Record では検証（Validation）という機能を通して、こういった制約を課すことができるようになっています。
ここでは、よく使われるケースのうちのいくつかについて説明します。
それらは存在性（presence）の検証、長さ（length）の検証、フォーマット（format）の検証、一意性（uniqueness）の検証です。
よく使われる最終検証として```確認（confirmation）を追加```します。ユーザーが制約に違反したときに、検証機能によって```自動的に表示される有用なエラーメッセージ```をお見せします。
###有効性を検証する
モデルの```バリデーション機能```は、テスト駆動開発とまさにピッタシの機能と言えます。
バリデーション機能は強力ですが、うまく動いている```自信を持つのが難しい```です。
しかし、（テスト駆動開発のように）```まず失敗する```テストを書き、次にテストを```成功させるよう```に実装すると、期待した通りに動いている自信を持てるようになります。

具体的なテスト方法について、まず```有効なモデルのオブジェクトを作成```し、その属性のうちの1つを```有効でない属性に意図的に変更```します。そして、バリデーションで失敗するかどうかをテストする、といった方針で進めていきます。
念のため、最初に作成時の状態に対してもテストを書いておき、```最初のモデルが有効であるかどうか```も確認しておきます。

コマンドを実行してUser用テストの原型ができているはずなので、まずはその中身から見ていきましょう

####デフォルトのUserテスト（モックのみ）

```rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end
```
有効なオブジェクトに対してテストを書くために、```setup```という特殊なメソッドを使って有効なUserオブジェクト（@user）を作成します（このメソッドは第3章の演習でも少し取り上げました）。
setupメソッド内に書かれた処理は、各テストが走る直前に実行されます。
@userはインスタンス変数ですが、```setup```メソッド内で宣言しておけば、すべてのテスト内でこのインスタンス変数が使えるようになります。
したがって、```valid?```メソッドを使ってUserオブジェクトの有効性をテストすることができます。作成したコードをリスト 6.5に示します。
####有効なUserかどうかをテストする

```rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end
end
```
シンプルなassertメソッドを使ってテストします。@user.valid?がtrueを返すと成功し、falseを返すと失敗します。

```
ubuntu:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 24042

  1/1: [==============================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.03134s
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
```
rails test:modelsというコマンドを実行していますが、これは```モデルに関するテストだけ```を走らせるコマンドです。

###演習
1.コンソールから、新しく生成したuserオブジェクトが有効（valid）であることを確認してみましょう。

```rb
>> user
=> #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil>
>> user.valid?
=> true
```

2.6.1.3で生成したuserオブジェクトも有効であるかどうか、確認してみましょう。

```rb
>> user2 = User.new(name: "Michael Hartl", email: "michael@example.com")   
=> #<User id: nil, name: "Michael Hartl", email: "michael@example.com", created_at: nil, updated_at: nil>
>> user2.valid?
=> true
```
M1 Macでkivyを動かすようにする(Miniforge)

#はじめに
M1のMacに関係なく，kivyは環境構築がややこしいので
備忘録としてまとめてみます．
環境については，以前書いた記事と同様にminiforgeを用います．

https://qiita.com/go_new_innov/items/eb90338c72d8bcfb2046

##仮想環境の作成
作成するpythonのバージョンは3.9と新しいのにしました．
3.8以前のバージョンだと動かなかった記憶があります．（曖昧）

```
conda create -n kivy python=3.9
```

##ライブラリのインストール
次に，kivyとそれに必要なライブラリをインストールしていきます．
以下の順番でインストールして動作しました．
（自動で周辺ライブラリがインストールされる都合で，順番が大切という記事もありました）

ffpyplayerは，kivyを動かす際には，必要ありませんが
kivyを用いて，動画を扱う場合に必要となります．

```
pip install cython
pip install git+https://github.com/kivy/kivy.git
pip install pygame
pip install pillow
pip install ffpyplayer
```

##動作確認

以下のサンプルのスクリプトでkivyのwindowが表示されれば，
環境構築完了です．

```sample.py
import kivy
from kivy.app import App
from kivy.uix.label import Label

class HelloApp(App):
    def build(self):
        return Label(text='Hello World')

if __name__ == '__main__':
    HelloApp().run()
```

#参考

https://www.youtube.com/watch?v=VK8gFXwdY-k
SearchBarにBookMarkを表示

#今回の内容

* SearchBarにBookMarkを表示
* BookMarkが押された時に働くメソッド

#コードと簡単解説

* `.showsBookmarkButton`でBookMarkの表示は出来ます。

* `func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {}`を使用することで、BookMarkが押された時に`{}`の処理が働きます。

```Swift:
import UIKit

class ViewController: UIViewController,UISearchBarDelegate{

 let searchController = UISearchController()  

    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.searchBar.showsBookmarkButton = true
    }

    func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {

        //ブックマークが押された時の処理
    }

}
```

#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
ウイルスバスターはアンインストールできない？

　最近会社のノットパソコンはノートンを使うようになりました。PC購入時インストールされたウイルスバスターを削除したい場合は出来なくなる。
　最初にコントロール パネル\すべてのコントロール パネル項目\プログラムと機能　からアンインストールしようと思った。逆にポップアップメッセージを繰り返し表示して、パソコンを動かないようになりました。凄くストレスに成りました。
　いろいろ調べて一番いい方法はウイルスバスター会社自社製アンインストールツールと思います。

https://helpcenter.trendmicro.com/ja-jp/article/TMKA-17673/
古いバージョンのbashで使ってた変数展開が使えなくなってた話

bash 4.1.x～4.2.xあたりで使ってた以下のようなスクリプトを4.4.xのbashで動かしたときにエラーが出るようになった

```bash:sample.sh
param += ( $@ )
sample_var += ${param[@]:1:((${#param[@]-2}))}
echo ${sample_var}
```

内容としては、引数を配列paramにいれてそっからparamの一部をsample_varに格納するという内容だが
4.2.xまでのbashで実行した場合は特にエラーは発生せず期待通りの出力が得られた。
しかし、4.4.xで実行した場合は以下のエラーとなる。

```error_message
line 2: ((${#param[@]-2})): bad substitution
```

まぁ、そもそも2行目のsyntaxが間違っていて
正しくは以下だ。これなら4.4.x～でも動く。

```
sample_var += ${param[@]:1:((${#param[@]}-2))}
```

古いバージョンのbashだと上手く動いてたのが謎。
詳しいことはよくわからないので有識者の方説明お願いします。
[Windows]'py'と'python'コマンドの違い

## 背景

Pythonで環境構築をしようとすると、主にpipを用いる場面で、Windowsの環境では`py`と`python`の2種類が登場する。
これらの違いは、あまり説明されておらず、知らないとハマる場合があるので備忘録として記事にすることにした。

## 問題

Windowsではコマンドプロンプトからコマンドを打つために、[PATHを通す](https://qiita.com/shuhey/items/7ee0d25f14a997c9e285)必要があるが、PythonをインストールするとPython実行ファイルを管理するPython launcherと呼ばれるものが`C:\Windows\`にインストールされ、pyコマンドを打つことで呼び出される。

そのため、Pythonをインストールするときに環境変数を登録するオプションを有効にしてしまうと

`py`と`python`の2つのコマンドが存在することとなり、これを知らないと非常に混乱することになる。

## 備考

この問題に気がついたきっかけが、PythonからWindows標準のdllを呼び出そうとしたときに、Pythonのバージョンが64bitだったのに対して32bit dllが読み込めないため今回の気づきにつながった。

## 参考

https://stackoverflow.com/questions/50896496/what-is-the-difference-between-py-and-python-in-the-terminal
「1 - 20 / 35件  < >」のような日本語ページネーションの追加[Rails, kaminari]

## はじめに

以下のようなページネーションを作成しました。
実現したコードを記載したいと思います。

![スクリーンショット 2021-09-24 17.34.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779676/e9242459-7e07-52f7-80dc-b8ed9e46e2f9.png)


## コード

```html:app/views/tests.html.erb
<%= page_entries_info @tests %>
<% if @tests.total_count > @tests.limit_value %>
  <%= link_to '<', path_to_prev_page(@tests) %>
  <%= link_to '>', path_to_next_page(@tests) %>
<% end %>
```

```ruby:app/controllers/test_controller.rb
def index
	@tests = Test.all.page(params[:page])
```

```ruby:config/kaminari_config.yml
Kaminari.configure do |config|
  config.default_per_page = 20
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
end

```

```yaml:config/locales/kaminari_ja.yml
ja:
  helpers:
    page_entries_info:
      one_page:
        display_entries:
          zero: ""
          one: "1-1/1件"
          other: "1-%{count}/%{count}件"
      more_pages:
        display_entries: "%{first}-%{last}/%{total}件"
```

## ポイント

次のページと前のページのボタンに関しては、CSSで操作できるよう、リンクだけkaminariに排出してもらうようにしています。

```ruby
path_to_prev_page(@tests) # リンクを吐き出す
```

またどのページでもボタンが表示されてしまう為、条件分岐でボタンは表示と非表示を切り替えています。

## 参考

https://nekorails.hatenablog.com/entry/2018/10/15/005146

最後までお読みいただきありがとうございました！
TsukuCTF 2021 -   train 100 

#問題

https://tsukuctf.sechack365.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d6373340-4b54-2b64-5eb0-29f19460e99a.png)

#解いてみた

画像を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/cc1d9e33-4913-cc41-3b31-8b9f9f9cbfd0.png)

ぱっと目に付くのは

- 山手線が停まる
- 京浜東北線が停まる
- 京浜東北線は昼間は通過する
- 北改札がある

wikipediaにすごく良い画像がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6f1c1b48-4570-3100-cc3e-0251ef086e2a.png)


この図を見る限り


- 山手線が停まる
- 京浜東北線が停まる
- 京浜東北線は昼間は通過する

を満たすのは

- 西日暮里
- 日暮里
- 鶯谷
- 御徒町
- 有楽町
- 新橋


御徒町は土休日のみ停車とかレアさ出してます。
そしてこの問題は5回しか答えられない。
今列挙した候補は6。
これはもう御徒町でしょう。と思って御徒町で答えてみると間違い。

北改札の確認をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/564401d9-ff78-1baa-294e-77972b03920e.png)


北改札口、北口改札、北改札とか言い回しがいろいろあって困るけどとりあえず問題の画像に書いてある通り北改札を示すのは新橋なので、挑戦してみると正解でした。

「駅名は東京近郊路線図内に記載されている駅名の英語表記を使用します。」という問題文を忘れずに。

解き終わってから思ったけど、山手線の方に「東京上野方面」って書いてあるから御徒町はありえないのか！