OmniAICreator/Qiita-1.07M huggingface dataset:
Workload Identity連携で、AWS Cloud9からPythonでGCP操作

# はじめに
AWSからGCPの操作がセキュアにできるWorkload Identity連携を、Cloud9上からPythonで試してみたので記事にしました。

# まとめ
- 認証ファイルのパスを、環境変数`GOOGLE_APPLICATION_CREDENTIALS`にセットする
    - 対象プロジェクトを指定するために、別途環境変数`GCLOUD_PROJECT`にセット
- Cloud9から行う場合は、使用しているEC2にIAMロールを付与して使う
- Pythonライブラリをインストールする際、ローカルにインストールする`pip install -t .`だとうまくいかない

# 参考
GCP側の手順やCloud9の設定は以下のページが詳しいです。

https://tech.nri-net.com/entry/2021/07/01/111020

# やったこと
## GCP側
前回の記事をそのままやっています。

https://qiita.com/a_b_/items/f30b85be4f44ed1f620c#gcp%E5%81%B4

こちらで作られたファイルをそのまま使います。

## AWS側
### Cloud9設定
参考で紹介したページにやり方があります。

画面のスクショで補足しますと、Cloud9でtemporary credentialを無効にする場合は以下の順序になります。
1. 右上の歯車マークをクリック
1. 左ペインから"AWS Settings"を選択
1. CredentialsをOFF

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/ecc2fde5-8076-6b50-e67a-c9d29612d80d.png)

インスタンスにIAMロールをつける場合は、EC2のコンソールから[アクション]-[セキュリティ]-[IAMロールを変更]と操作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/5ec60d23-2f31-dbc5-f8b6-6b2950bdd50e.png)


Cloud9に戻って、左メニューのAWSアイコンからAWS:Explorerのアイコンで、[Choose AWS Profile...]で設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1e8fa64f-d253-2f70-6316-4252e5966d1b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/ed9846d8-9e23-825a-1244-e3e50431eed8.png)


### 仮想環境作成
今回は仮想環境を作り、その上で実行しました。
Cloud9に直で構築しても問題ないですが、後片付けがしやすいように仮想環境を使いました。
```
$ mkdir aws-to-gcp
$ cd aws-to-gcp

# virtualenv上で環境構築
$ virtualenv a2genv
$ source a2genv/bin/activate
```

### ライブラリインストール
今回はGCSを操作するので、必要なライブラリをインストール。
ただ`pip install -t .`だとうまくいきませんでした。
```
# google-cloud-storageをインストール
# pip install -t . だと　うまくインストールされないようで、protobufが使えない
(a2genv) $ pip install google-cloud-storage
```

### 環境変数設定
GCP側で作ったファイルをアップロードします。
アップロードしたファイルまでのパスを、環境変数`GOOGLE_APPLICATION_CREDENTIALS`にセットします。
環境変数を使う話は公式より

https://cloud.google.com/docs/authentication/production?hl=ja#auth-cloud-implicit-python

操作するGCPプロジェクトのIDを、環境変数`GCLOUD_PROJECT`にセットします。
```
# 環境変数設定
(a2genv) $ export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/clientLibraryConfig-awstogcp.json

# 対象のGCP上のプロジェクトを指定
(a2genv) $ export GCLOUD_PROJECT=hogehoge-pj

# 環境変数確認
(a2genv) $ printenv GOOGLE_APPLICATION_CREDENTIALS
(a2genv) $ printenv GCLOUD_PROJECT
```

これで準備は完了です。

### Python実行
後はPythonから操作するだけです。
以下のコマンドで、GCSのバケット一覧が取得できます。
```python
(a2genv) $ python
>>> from google.cloud import storage
>>> storage_client = storage.Client()
>>> list(storage_client.list_buckets())
```

# 片づけ
仮想環境下で行ったので、ディレクトリごと削除すれば片付け完了です。
```
(a2genv) $ deactivate
$ cd ..
$ rm -rf aws-to-gcp/
```

# おわりに
今回はWorkload Identity連携の成功事例を記事にしました。
使い方が簡単でセキュアなので、連携する際はこの方法を積極利用していきたいと思います。
ローカルにてLambda関数を組む二つ方法まとめ(VSCode,Pycharmなど)

方法としては下記の２種類です。

# １、Dockerを利用してローカルで実行
手順は[この記事](https://qiita.com/zukakosan/items/9c01aba5ff537382c856)の通りですが、実際設定・実行する時は二つ問題が発見しました。
①VSCodeにの`app.py`ファイルには`Run Locally | Debug Locally | Configure`が表示せず、代わりに`AWS: Add Debug Configuration | AWS: Edit Debug Configuration`が表示しました。記事の[ここに書いている内容](https://qiita.com/zukakosan/items/9c01aba5ff537382c856#vscodeでlambdaをローカルテスト)と違います。なんか仕様変更らしいです。
`Add Debug Configuration`或いは`Edit Debug Configuration`をクリックしたら、`launch.json`デバッグ設定を追加しまして、`Edit SAM Debug Configuration`ファイルも表示しました。でも`Invoke`をクリックすると②のエラーが表示しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/a8472473-0b5d-4f77-2cb7-d20bbba7c43e.png)

②`Running AWS SAM projects locally requires Docker. Is it installed and running?`エラー
Dockerを再インストールし、DockerとVSCodeを再起動すると解決できました。

# ２、コードをAWSにアップロードしてリモートで実行

Dockerでローカルで実行する設定はややこしくてそんな頻繁にデバッグではない場合、簡単にAWSでテストしたらいいでしょう。

VSCodeのAWSプラグインでLambda下に組みたい関数に`Download...`をクリックして、ソースコード保存フォルダーを選択するとソースコードはVSCodeで編集できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/8f18458b-1db2-f68e-297f-9ad5fe75e90d.png)

編集後、`Upload Lambda...`→`Directory`→`No(AWS Toolkit will upload a ZIP of the directory.)`→関数フォルダーを選択すると新しいソースコードをLambdaリモートにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/7895baed-c2ce-043e-c3c4-384eb4e20770.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/d7638b94-f285-818c-ab21-611db8fad170.png)

最後は関数上`Invode on AWS`をクリックして、`Invoke Lambda`画面を開きます。`Invoke`をクリックすると関数をリモートLambdaにて実行し、結果はローカルコンソールに表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236892/540bebe2-7c42-cf90-e5fe-e66bdf30b1d0.png)
python学習 - 1日目

# はじめに
python初心者がこっそり学習する。
まずはなるべく毎日30分でも触ることが目標。

# pythonの環境構築
こちらは別記事で実施する予定。
環境構築で挫折したくないので。。
今回は構築しなくても、ブラウザでpython実行できる[Google Colaboratory](https://colab.research.google.com/)を利用する。
[使い方](https://www.python.jp/train/experience/colab.html)の記事を参考にしました。

# pythonのバージョン
python3を使用する。
ちなみにpython2系は2020にサポート終了済み。
私のようにこれから始める方は、python3系を選ぶのが良いと思います！

# Pythonのコーディングルール
[PEP8](https://pep8-ja.readthedocs.io/ja/latest/)をまずは参考にするのが良さそう。

# コメント
コメントは、コードが実行される時に無視されるもの。
メモやコードの説明に使う。
コードの全行にコメントつけるのは逆に見づらくなるが、
重要なところは(なぜこの処理を入れたかとか)、メモとして入れておくと良い。
業務でpythonコードを書くとなると、複数人で作成することが多いので、
他人が読みやすいように、コメントを書く習慣をつけたい。

 ```
# コメントなのでこの行は実行されない

print("Hello, Python") 

# コメントなのでこの行は実行されない
 ```

上記を自分で実行してみると、コメントした行は表示されない。

今日はここまで！
【JavaScript関数ドリル】初級編のzipObject関数の実装アウトプット

## zipObject関数の課題内容

_.zipObject関数を自分で実装する内容です。
https://lodash.com/docs/4.17.15#zipObject

「課題内容」/「解説動画」/「解答例」を確認したい場合は、以下リンク先のページを参照。

https://js-drills.com/blog/zipobject/

## 課題に取り組む前の状態

- １ヶ月以上前に課題の動画を１度見た
- オブジェクトの操作についてあまり覚えていない状態
- オブジェクトの操作についてリファレンスを調べる必要がある


## 課題に取り組んだ後の状態

- 答えを見なくてもだいたい実装できたが、代入方法について思い出せず、リファレンスを調べる必要があった
https://www.w3schools.com/js/js_objects.asp
- 解答例の引数が、propsだけではなく、props = [] のようになっている

## zipObject関数の実装コード（答えを見る前）

```javascript
function zioObject(props,values) {
    const newObj = { };
    props.forEach((prop, index) => {
        newObj[prop] = values[index];
    });
    return newObj;
}

console.log(zioObject(['a','b'],[1,2]));
```

## zipObject関数の実装コード（解答例）

```javascript

function zipObject(props = [], values = []) {
    const zippedObject = {};
    for(let i = 0; i < props.length; i++) {
      const prop = props[i];
      const value = values[i];
      zippedObject[prop] = value;
    }
  
    return zippedObject;
  }
  
  console.log( zipObject(['a', 'b'], [1, 2]) );
```
Django+Reactで学ぶプログラミング基礎(3): 開発環境構築(React)

##### [前回] [Django+Reactで学ぶプログラミング基礎(2): 開発環境構築(Django/VS Code)](https://qiita.com/mingchun_zhao/items/36adb0243ea27c637053)

## はじめに

前回に続き、開発環境を整えます。
今回は、React開発環境です。

## 開発環境情報(Windows)

- 前回までインストール済み
    - Python 3.10
    - VS Code(Visual Studio Code) 1.67
    - Django 4.0
- 今回は、React開発に必要なもの
    - Node.js(ノード・ジェイエス)
        - サーバーサイドJavaScript環境で、イベント化された入出力を操作
        - Webサーバーなどスケーラブルなネットワークプログラムの記述を可能に
        - V8 JavaScriptエンジン上に構築されたJavaScript実行環境の1つ
            - V8は、Googleが開発するオープンソースのJIT(Just In Time) Virtual Machine型のJavaScriptエンジン
    - npm(Node Package Manager)
        - Node.jsに同梱される
        - Node.jsのパッケージ管理システムで、V8 JavaScriptエンジンで動作
        - Node.jsのツールやパッケージ(モジュール)をインストール/管理
        - パッケージを扱うためのインターフェイスを備える
        - リポジトリ機能
            - パッケージ(モジュール)を、検索/ダウンロード/インストール/アップデート/公開
    - npx
        - npmに同梱される
        - npmパッケージを簡単に実行できるコマンド
            - 一回だけ実行したいパッケージを、グローバルインストールせず実行可能
            - パッケージを自動的に探しインストール/実行/削除してくれる、放置せず環境をきれいに
        - 対して、npmを使ってスクリプトを実行するには
            - プロジェクトを作成
                - `npm init <project-name>`
                - npmを使ってプロジェクト管理するための`package.json`が生成される
            - `package.json`のscriptsへ予めスクリプトを定義
    - `Create React App`ジェネレータ(generator)
        - Reactで新しいSPA(シングルページアプリケーション)を自動生成
        - Reactを学習するための快適な環境

## React開発環境構築
### Node.js(npm同梱)をインストール

- `https://nodejs.org/ja/download/`からLTS版(64-bit)をインストール
- VS Codeを起動し、ターミナルで、Node.jsとnpmのバージョン確認
```
>node --version
v16.15.1

>npm --version
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` 
instead.
8.4.1
```
※ `npm WARN ...`警告は無視
### Reactアプリを作成(テスト用)
```
>npx create-react-app my-app
... ...
Success! Created my-app at C:\kanban\my-app
... ...
```
- Webサーバーを起動
```
>cd my-app
>npm start
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/fed4475c-68e9-26c1-d0f7-33fa0eaf8df4.png)
- ブラウザが開かれる、Reactアプリを確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/48ba3a23-bbeb-81fe-2968-cc375adf7351.png)

### VS CodeでReactアプリを開く
- もう一つターミナルを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/b6835e76-af15-8dd3-5ae1-b08688fde705.png)
```
>C:\kanban>cd my-app
>C:\kanban\my-app>code .
```
新しいVS Code画面が開かれ、Reactアプリが表示される。
上述`package.json`も生成されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/c931af39-8114-4cb2-c3e6-ad6f673b4a3b.png)

## おわりに

Windows環境にReact開発に必要なものをインストールしました。
次回も続きます。お楽しみに。

##### [次回] [Django+Reactで学ぶプログラミング基礎(4): 開発環境構築(Redux)](https://qiita.com/mingchun_zhao/items/095a7d7ee5ac58cc0f51)
Railsコンソールで出力したデータを見やすくする

mac OS バージョン11.6
Rails 6.0.4
# pry(REPL環境)へHirbを導入する
railsでは標準の**irb**よりも、高度なpryがコンソールツールとしてよく使われています。

**Hirb**はRailsコンソールでテーブルデータを見やすく表示してくれるGemです。
pryまたはirbでモデル表示「**[モデル名].all**など」をおこなうと表示があまり見やすくありません。そこで、Hirbでは表形式で表示してくれます。

こんな感じに。
![11f4b500a0f6cb379bff792a39ee27e7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962714/9f90fa5a-f350-72f4-8c72-b588aadaacab.png)
コンソールを見やすくするために、これからpryとHirbを導入していきます。

# 手順
①まず、Gemfileにgemをインストールします。


```.Gemfile
　　　　gem 'pry-rails'

  gem 'hirb' 
  gem 'hirb-unicode' 
```

※```hirb-unicode```
hirb-unicodeは日本語などマルチバイト文字が入る場合に、出力が乱れないようにするために必要です。



```
% bundle install
```

② **.pryrc**ファイルの追加
.pryrcファイルをプロジェクト直下に以下の内容で作成します。

```
% touch .pryrc
```

```.pryrc
begin
  require 'hirb'
rescue LoadError
  # Missing goodies, bummer
end
 
if defined? Hirb
  # Slightly dirty hack to fully support in-session Hirb.disable/enable toggling
  Hirb::View.instance_eval do
    def enable_output_method
      @output_method = true
      @old_print = Pry.config.print
      Pry.config.print = proc do |*args|
        Hirb::View.view_or_page_output(args[1]) || @old_print.call(*args)
      end
    end
 
    def disable_output_method
      Pry.config.print = @old_print
      @output_method = nil
    end
  end
 
  Hirb.enable
end
```

そのままコピペで大丈夫です。

ただ内容はバージョンにより更新される場合があるので、最新版は以下のサイトより確認ください。
https://github.com/pry/pry/wiki/FAQ#hirb

# 動作確認
```
% rails c
```
pryコンソールモードでモデルの情報を表示します。(例：Userモデル)
```
pry(main)> User.all
```

実行結果として表形式で表示されるようになっていればOKです。

参考：http://to-developer.com/blog/?p=1919
Ubuntu 20.04.3のタイムゾーン変更方法

### 目次
- 実行環境
- やりたいこと
- 現在のタイムゾーン確認
- タイムゾーンの変更
- 反映状況確認

#### 実行環境
OS：Ubuntu-20.04.3

#### やりたいこと
UbuntuのタイムゾーンをUTCからJSTへ変更する

#### 現在のタイムゾーン確認
```
[コマンド]
date 

[結果]
Sun 05 Jun 2022 12:17:10 AM UTC
```

※下記コマンドでも確認できるみたい
```
[コマンド]
timedatectl

[結果]
               Local time: Sun 2022-06-05 00:18:42:UTC
           Universal time: Sun 2022-06-05 00:18:42:UTC
                 RTC time: Sun 2022-06-05 00:18:42
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```

#### タイムゾーンの変更
```
[コマンド]
sudo timedatectl set-timezone Asia/Tokyo
```
即時反映されます。

#### 反映状況確認
```
[コマンド]
date 

[結果]
Sun 05 Jun 2022 09:19:42 AM JST
```
Rebootしても問題なし。
Phoenix のクライアントエラーの処理一覧、随時更新

ホストしている Phoenix を Sentry で監視する中でみつけた、クライアントエラーとなった（不正アクセスへの）処理を以下にまとめます。


# Plug.Static.InvalidPathError 

Sentry の MESSAGE

```
(Plug.Static.InvalidPathError invalid path for static asset)
```

どのパスへのリクエストで発生したかが分からないメッセージですが、 https://github.com/elixir-plug/plug/pull/1098/files で改良されるようです。

## 起きる要因

パスに無効な文字列を含むリクエスト等で発生します。

## 再現方法

`GET http://localhost:4000/assets/:`

※`assets` は `Plug.Static` で公開しているディレクトリ

## レスポンスステータス: 400

https://github.com/elixir-plug/plug/blob/e75d542b3028b5c1f348ac9d128306c46a6b6e70/lib/plug/static.ex#L142-L144


# Phoenix.NotAcceptableError

Sentry の MESSAGE

```
(Phoenix.NotAcceptableError no supported media type in accept header.

Expected one of ["html"] but got the following formats:

  * 

To accept custom formats, register them under the :mime library
in your config/config.exs file:

    config :mime, :types, %{
      "application/xml" => ["xml"]
    }

And then run `mix deps.clean --build mime` to force it to be recompiled.
)
```

## 起きる要因

サポートしない `Accept` ヘッダー でのリクエストにより発生します。今回のケースは `Accept` ヘッダーの 値が `*`

## 再現方法

サポートしない `Accept` ヘッダーを付与して

`GET http://localhost:4000`

## レスポンスステータス: 406

https://github.com/phoenixframework/phoenix/blob/385bdebdcc879dfb06f02faa5bef7d5e0b97761c/lib/phoenix/exceptions.ex#L1-L16
VSCode起動時にワークスペースを選んでpecoるbat

## はじめに

`VSCode`のワークスペースが増えてお困りではありませんか？

バッチファイル(`bat`)を介して`VSCode`を起動することにより、起動時にワークスペースを選択できる`bat`を紹介します。ワークスペースが増えてきたとき、いつでもワークスペースを切り替えられると便利です。

## batの構成図

```mermaid
%%{init:{'themeVariables':{'lineColor':'#b6c0b6'}}}%%
flowchart LR
    A[(フォルダ\nAAA.code-workspace\nBBB.code-workspace\nCCC.code-workspace\n...)] -.->|peco| B[[ファイル\nAAA.code-workspace]]
    B -.-> |VSCode| C((ワークスペース\nAAA))
    style C fill:#ffe6f6
```

ワークスペースの保存ファイルを一箇所のフォルダにまとめておきます。一覧をもとに入力キーでフィルターしながら選択する機能が[peco](https://github.com/peco/peco)にあります。さいごに、選んだワークスペースを`VSCode`の起動コマンドに渡します。

## batの現物

```bat
@echo off
setlocal
set WORKSPACE_FOLDER=C:\VSCodeWorkspaces

for /f "usebackq delims=" %%A in (`dir /b/o-d %WORKSPACE_FOLDER%\*.code-workspace ^| peco`) do set WORKSPACE_FILE=%%A

@echo WORKSPACE_FILE is "%WORKSPACE_FILE%"

if "%WORKSPACE_FILE%"=="" (
	code
) else (
	code "%WORKSPACE_FOLDER%\%WORKSPACE_FILE%"
)
```

## batの解説

`setlocal`は環境変数のローカライズを開始します。呼び出し元に環境変数が反映されてしまうので`setlocal`を付けたほうがいいです。

`WORKSPACE_FOLDER` は変数です。

:::note info
変数`WORKSPACE_FOLDER`にワークスペースの保存ファイルをまとめて置いてあるフォルダを指定してください。
:::

`for %%A in (...) do set` はコマンドの実行結果を変数に格納します。

`dir` の引数は次の通りです。

- `/B`	ファイル名のみを表示します。
- `/O`	ファイル名を並べ替えて表示します。`D`は日時を古いほうからにし、`-`は順番を逆にします。

`peco`の選択画面でエスケープや`Control-C`を押下したとき`"%WORKSPACE_FILE%"`が`""`にな って引数なしで前回の状態で起動し、コマンドウィンドウを閉じたときは起動しません。

実は`peco`は複数選択が可能になっていまして、複数選択した場合は最も下の選択が起動します。`--select-1`を使えば１つのみ選択にできるかと思いましたが、入力行数が１つのみのときに選択をスキップする機能でした。

`code` は`VSCode`を起動します。

## 拡張機能「Project Manager」と比較

こちらは評価の高い拡張機能ですが、起動時にワークスペースを選択できる`bat`のほうが気に入っています。:relaxed:

`Project Manager`にはワークスペースをタグ付けする機能がありますが、ワークスペースの名前をつけて`peco`で選ぶことで代替できます。

## （参考）バックアップを取るbat

`bat`で連想したのですが、ファイルのバックアップを取る`bat`が[この記事のコメント](https://qiita.com/hachan/items/abd3a8579ff0a9a0d939#comments)で紹介されていて、最初のコメントの`bat`（現在の日時を取得するほう）が便利で使っています。:blush:

右クリックの「送る」(`SendTo`)で使っています。

## （宣伝）ファイルのフォルダをワークスペースに1クリックで追加する拡張機能

`VSCode`の拡張機能[Add This Folder To Workspace](https://marketplace.visualstudio.com/items?itemName=querykuma.add-this-folder-to-workspace)を以前に作りました[^1]。

ファイルの右クリックから`VSCode`で開いた後、ファイルのあるフォルダをワークスペースに追加するときに、ダイアログ画面をスキップさせたいと思って作りました。クリック1回で追加できます。:alarm_clock:

## さいごに

起動時にワークスペースを選んで`VSCode`を起動するバッチファイルを紹介しました。

`bat`が誰かの役に立てれば幸いです。:hugging:

[^1]: 更新してませんが :sleepy:。
ABC065 B問題 解法

6月からAtCoderのC++入門に取り組みはじめたにくうさぎちゃんです。
社会人、数学とか久しぶりすぎて頭が固くなってて、びっくりしています。
数学はできなくなくてもいいと思うけど、頭は柔らかいに越したことはないですよね。😅

今日はこれについて。

https://atcoder.jp/contests/abc065/tasks/abc065_b


[C++入門 AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/apg4b/tasks/APG4b_n)で紹介されていたので取り組んだところ、TLEや、WAが出て、何度かトライしていたので復習。

1回目はタイムアウトしていた。
```
// 1回目のコード TLE
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  vector<int> arrA(n);
  
  for (int i=0; i<n; i++) {
    cin >> arrA.at(i);
  }
  
  int i = 0;
  int y = 0;
  
  while (true) {
    int x = arrA.at(y);
    i++;
    if (x == 2) {
      cout << i << endl;
      break;
    } else if (x == 1) {
      cout << -1 << endl;
      break;
    } else {
      y = x-1;
    }
  }
}
```
ケース01.txt, 02.txt, 03.txt　でTLEが出ていた。

ボタン2が押されないパターンについて、
入力例2, 出力例2 に記載されている
「押すボタンがループしているパターン」だけを考えていた。

しかし、この時にケースの考慮漏れに気づいていればよかったが気づいておらず、
タイムアウトしちゃった〜ぐらいの感覚だったので、
「押すボタンがループしているパターン」がタイムアウトしないように下記になった。
```
// 2回目のコード WA
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  vector<int> arr(n);
  
  for (int i=0; i<n; i++) {
    cin >> arr.at(i);
  }
  
  int b = 1;
  int count = 1;
  
  for (int i=0; i<n; i++) {
    b = arr.at(b-1);
    if (b == 1) {
      cout << -1 << endl;
      break;
    } else if (b == 2) {
      cout << count << endl;
      break;
    } else {
      count++;
    }
  }
}
```
全てのボタンを押すのに必要な回数はボタンがある回数なので、
脳死で`while(true)`としていたものを、for文に変えて、i<[ボタンの個数]にした感じ。

で、ここでもやっぱりケース01.txt, 02.txt, 03.txtが通らないわけです。今度はWAとなって。
そこで、やっと考慮漏れしているな…と気づいて、下記に書き換えた。

```
// 3回目のコード AC
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  vector<int> arr(n);
  
  for (int i=0; i<n; i++) {
    cin >> arr.at(i);
  }
  
  int b = 1;
  int count = 1;
  bool f = false;
  
  for (int i=0; i<n; i++) {
    b = arr.at(b-1);
    if (b == 1) {
      cout << -1 << endl;
      f = true;
      break;
    } else if (b == 2) {
      cout << count << endl;
      f = true;
      break;
    } else {
      count++;
    }
  }
  
  if (!f) {
    cout << -1 << endl;
  }
}
```

ボタン2が押されないパターンについて、「押すボタンがループしているパターン」だけを考えていたけど、

```
ボタン1 -> ボタン3 ->　ボタン4 -> ボタン3 -> ボタン4 .....
```

「途中からループされるパターン」というのも考慮が必要だったわね。
不覚だったわ。
あーこういうこともあるわねと思ったので、あらかじめ考慮できてないケースを拾える方法をとっておくとスムーズそうね。

3回目のコードは、とりあえず考慮漏れを拾うという意気込みだけだったけど、
for文内は、`b==1`の場合を考えなくていいので、こうした方が短くできるわね。

```
if (b == 2){
  cout << count << endl;
  f = true;
  break;
} else {
  continue;
}
```
スクレイピングに必要な知識

スクレイピングの副業に興味があるので簡単にまとめてみました。

# スクレイピングに必要な知識

## Python
基本的なことができれば良い。入門書一冊やれば十分とのこと。

以下のライブラリの知識が必要。ライブラリはターミナルで
```python
pip3 install ライブラリ名
```
と入力。

### Requests
HTTP通信用のライブラリ。ウェブスクレイピングやHTMLやXMLファイルからデータを取得するのに使う。

### BeautifulSoup
requesteで取得したデータの中から必要な情報を抽出する。

### Selenium
データの取得、抽出の両方を行うが、ブラウザを操作してデータを取得するので動作が遅い。


## HTML
beautifulsoupではHTMLのツリー状のオブジェクトを取得するのでHTMLの構造を理解する必要がある。body、titleなどタグの構造を理解する必要がある。


## CSS
HTMLで記述されたウェブページをどのように装飾するか定義する言語。CSSの中でもCSSセレクタを理解する必要がある。CSSセレクタとは、CSSで定義したデザインをどのHTML要素に適応させるかを指定するもの。


## JavaScript
ブラウザ上でWebページをダイナミックに動かすためのもの。情報を取得、抽出する際に理解しておく必要がある。jQuery、Vue.jsなどのフレームワークがありそれらの知識も必要。


# デベロッパーツール
chromeのデベロッパーツールではそのサイトのHTML、CSS、JavaScriptのコードを無料で見ることができる。macbookでは情報を得たいサイトで　option + command + i　を押す。windowsは ctrl + shift + i　を押す。

# 法律
Webページは著作権の保護をうける。収集してデータの譲渡は違法。
規約にスクレイピング禁止と記載されている場合も違法。ただし、利用規約がユーザーとの間で有効となるのは利用規約をユーザーに示し同意をクリックした場合に限るので、会員登録の必要がなく誰でもみられるコンテンツに関しては規約違反とならない。

スクレイピングはサーバーに負担をかけるため、高頻度のスクレイピングをすると当該サイトの業務を妨害したとして偽計業務妨害になることも。sleepメソッドを使って頻度を調節する必要がある。
[Kotlin]JetpackComposeでステータスバー、ナビゲーションバーの色を手軽に変える方法

# 概要
Androidアプリのステータスバーとナビゲーションバーの色を変更する手順です。

themes.xmlで変更する方法もありますが、今回の方法を使えばiOSぽい見た目（背景色白色でナビゲーションバーのボタン部分が黒色の組み合わせ）も手軽に実現できます。
# 前置き
![スクリーンショット 2022-06-05 8.14.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/04740666-a7ab-b617-e7c2-8943b4911543.png)

Empty Compose Activityでプロジェクトを作った直後の実行画面はこんな感じです。
![スクリーンショット 2022-06-05 8.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/d10df964-09a2-b8ce-e434-909be261c651.png)

# 本文
build.gradle(:app)にaccompanistライブラリを指定します(Sync Nowを押し忘れないでください:robot:)
```kotlin
dependencies {


    // UI Controller
    implementation 'com.google.accompanist:accompanist-systemuicontroller:0.20.3'
}
```

setContentの中に以下のコードを追加するだけです。

```kotlin
            val systemUiController = rememberSystemUiController()
            SideEffect {
                systemUiController.setSystemBarsColor( color = Color.Blue)
            }
```

全体のコードはこんな感じになりました
```kotlin
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val systemUiController = rememberSystemUiController()
            SideEffect {
                systemUiController.setSystemBarsColor( color = Color.Blue)
            }

            QiitaTestTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}
```
![スクリーンショット 2022-06-05 8.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/6d504534-6c32-8f78-71a5-dfb095644088.png)

# 補足
白色を指定すると、ボタンや文字等が自動で黒色になってくれます
![スクリーンショット 2022-06-05 8.27.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a2b8d8ff-8436-8ee1-03fc-0a31abc5d455.png)
tkinter キャンバス内にフレームを配置するときの注意点

# 注意点
ウィジェットの設定をするときはpropagate=Falseと明示的に書かないと設定が反映されない。（tk.Tkの設定で上書きされてしまう)

```python3
import tkinter as tk

if __name__ == '__main__':
    root = tk.Tk()
    root.configure(background='black')
    root.geometry('1000x1000')

    canvas = tk.Canvas(root, width=800, height=800, background='white')
    canvas.propagate(False)
    canvas.pack()

    frame = tk.Frame(canvas, width=500, height=500, background='blue')
    frame.propagate(False)
    frame.pack()

    root.mainloop()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/6a7f10fa-7fc9-ec11-0264-b07f20e68d66.png)
access2000の作法 その25

# 概要
access2000の作法、調べてみた。
sqlから、リレーショナルなテーブルを作ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ccefe1a7-7a29-c644-f70d-5871e6d42dc2.png)

# sqlを発行する手順
- リボンの「作成」→「クエリデザイン」を選択します。
- 「テーブルの表示」が表示されますが、ここでは追加せずにそのまま閉じます。
- 画面左上の「SQL 表示」をクリックします。
- SQL を記述します。

```

CREATE TABLE T_取引先(取引先番号 AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY,取引先名 CHAR(50));


CREATE TABLE T_果物(果物番号 AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY,果物名 CHAR(10),取引先番号 LONG CONSTRAINT FK_PrimaryKey1 REFERENCES T_取引先(取引先番号));


CREATE TABLE T_顧客(顧客番号 AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY,顧客名 CHAR(50));


CREATE TABLE T_受注(受注番号 AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY,顧客番号 LONG NOT NULL CONSTRAINT FK_PrimaryKey2 REFERENCES T_顧客 (顧客番号),果物番号 INTEGER CONSTRAINT FK_PrimaryKey3 REFERENCES T_果物 (果物番号),受注数 LONG );

```
- 画面左上の「実行」をクリックします。

以上。
access2000の作法 その24

# 概要
access2000の作法、調べてみた。
sqlを実行してみた。

# 「SQL ビュー」で、sqlを発行する手順
- リボンの「作成」→「クエリデザイン」を選択します。
- 「テーブルの表示」が表示されますが、ここでは追加せずにそのまま閉じます。
- 画面左上の「SQL 表示」をクリックします。
- SQL を記述します。
- 画面左上の「実行」をクリックします。

以上。
ファイアウォールの設定を変更してWebブラウザからindex.htmlを表示する

# ファイアーウォールの設定を確認する
ファイアーウォールの設定を確認します。
以下のコマンドを実行してください。
```
# firewall-cmd --list-all
```

「dhcpv6-client」と「ssh」のポートの通信が許可されています。
![スクリーンショット 2022-06-04 7.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/33d6858e-9510-bbe7-61e5-e9bbc95a4d27.png)

# ゾーンの設定を変更する
publicゾーンにWebで使う「http」と「https」の通信を許可するように変更します。
以下のコマンドを実行してください。
```
# firewall-cmd --zone=public --add-service=http --permanent
# firewall-cmd --zone=public --add-service=https --permanent
# firewall-cmd --reload
```

# 変更した設定を確認する
以下のコマンドを実行してください。
「http」と「https」が追加されています。
```
# firewall-cmd --list-all
```
![スクリーンショット 2022-06-04 7.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/1dedaf91-c25a-83dc-72b1-4c52c9921bcd.png)

# ポートフォワーディングを設定する
VirtualBoxのネットワークで、ポートフォワーディングを設定します。
ホストポートに「8888」、ゲストポートに「80」を設定してください。
![スクリーンショット 2022-06-04 7.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/5af466d8-1be6-dea2-0a59-a12fa91fbeae.png)


あとは、Webブラウザで、「http]//ホスト名、またはIPアドレス:8888/index.html」のURLを表示するとindex.htmlが表示されます。
Vagrantを使ってUbuntu20.04LTSの仮想マシンをインストールする

# Ubuntu20.04LTSの仮想マシンイメージを探す
[Vagrantのサイト](https://app.vagrantup.com/boxes/search)でUbuntu20.04LTSの仮想マシンのイメージを探します。
Ubuntu、20.04LTSなどのキーワードを入力し、検索します。
![スクリーンショット 2022-06-05 7.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/491d09f6-2d02-3ae6-4d51-001e5a04b3d3.png)

# 仮想マシンをインストールする
以下のコマンドを実行してください。
```
% vagrant box add ubuntu/focal64
```

Vagrantの仮想マシンを確認します。
```
% vagrant box list
```

# 仮想マシンの作業用ディレクトリを作成する
作業用のディレクトリを作成します。
```
% mkdir ubuntu2004
```

# 仮想マシンの設定ファイルを作成する
設定ファイルを作成します。
以下のコマンドを実行してください。
```
% cd ubuntu2004
% vagrant init ubuntu/focal64
```

# 仮想マシンを起動する
仮想マシンを起動します。
以下のコマンドを実行してください。
```
% vagrant up
% vagrant status
```

# 仮想マシンを停止する
仮想マシンを停止するときは、以下のコマンドを実行してください。
```
% vagrant halt
% vagrant status
```

以上で、作業は終わりです。
【Ruby on Rails】migrationファイル change・up/downの使い分けについて

## はじめに
カラムの追加や削除をしたり、テーブル内の情報を変更する際にmigrationファイルを追加して対応することがある。

その時に、基本的な記述として、、、
```ruby
def change

end
```
``` ruby
def up

end

def down

end
```
という2つのパターンがある。

厳密には、ファイル名の付け方(クラス名の付け方？)、``rails g migration <クラス名>``で入力されるクラス名によって、上のどちらのパターンのメソッドでファイルが生成されるらしい。
ただ、このメソッド changeとup/downの違いがいまいちわからなかったのでまとめておく。

間違いがありましたら、コメントいただけますと幸いです。喜んで修正します。

## changeとup/downの違い
違いとしては、``メソッドの中で　使用できる処理``に違いがあるらしい。
Rails公式ドキュメントには以下の処理がchangeメソッドでは使用できるらしい。

現時点では、changeでサポートされているマイグレーション定義は以下のものだけです。

> add_column
add_foreign_key
add_index
add_reference
add_timestamps
change_column_default (:fromと:toの指定は省略できない)
change_column_null
create_join_table
create_table
disable_extension
drop_join_table
drop_table （ブロックを渡さなければならない）
enable_extension
remove_column（型を指定しなければならない）
remove_foreign_key（2番目のテーブルを指定しなければならない）
remove_index
remove_reference
remove_timestamps
rename_column
rename_index
rename_table
>
> (Rails公式ドキュメントより引用しております。　https://railsguides.jp/active_record_migrations.html)

上記に記載の処理以外を使用する時には、up/downメソッドを明示的に記載することが必要らしい。
MacにVagrantをインストールする

# Vagrantをダウンロードする
Vagrantの[ダウンロードサイト](https://www.vagrantup.com/downloads)からインストーラをダウンロードしてください。

# Vagrantをインストールする
ダウンロードしたインストーラをダブルクリックしてください。

インストール画面が表示されます。
「vagrant.pkgアイコン」をダブルクリックしてください。
![スクリーンショット 2022-06-05 7.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/58e9591e-1c6e-e956-1746-1c020e6faea3.png)

「続ける」をクリックしてください。
![スクリーンショット 2022-06-05 7.18.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/8ae1ae94-716c-2bc3-dbb9-2e17f7ba4afb.png)

「インストール」をクリックしてください。
![スクリーンショット 2022-06-05 7.19.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/f89dab4f-5e3f-ef9e-3a6d-58c7bc7bf0b8.png)

インストールが完了しましたと表示されます。
「閉じる」をクリックしてください。
![スクリーンショット 2022-06-05 7.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/5f4828ff-260b-21e0-3510-bc863d485d70.png)

# 正常にインストールできたか確認する
ターミナルから、以下のコマンドを実行します。
```
% vagrant version
```
![スクリーンショット 2022-06-05 7.26.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/264c7277-c918-15d9-f902-d4f60c6037cc.png)

# Homebrewでインストールする
Homebrewを使う場合は、以下のコマンドを実行してください。
```
% brew install hashicorp/tap/hashicorp-vagrant
```


以上で、インストールは終わりです。
PostgreSQL: タグ別の自己記事目次 [automated]

# 概要
タグ別での自己記事の目次です。
Power Automate にて定期更新をしています。

# [Postgres: Power BI で利用しやすくする為の Pivot SQL](https://qiita.com/baku2san/items/6494ab619315c92f5961)
投稿日: 2022/7/3 
SQL, PostgreSQL, Pivot, PowerBI, 行列変換

# [Postgres: Psql Meta-Commands で複数のSQL Files を実行する](https://qiita.com/baku2san/items/3f9d9855db7c74bb5faf)
投稿日: 2022/6/2 
PostgreSQL, psql, pgadmin4, Meta-Commands

# [Postgres: View 上での連番追加方法](https://qiita.com/baku2san/items/0750c61d4e7b00904e72)
投稿日: 2022/3/29 
PostgreSQL, view

# [Postgres: Power BI で利用しやすくする為の Unpivot SQL](https://qiita.com/baku2san/items/7606a46e85d2c8ea9bf6)
投稿日: 2022/3/27 
SQL, PostgreSQL, PowerBI, unpivot, 行列変換

# [pgAdmin: Table や View をGUI で作った場合の、Create SQL の取得方法](https://qiita.com/baku2san/items/3c80a9ff9ca70a172665)
投稿日: 2022/3/17 
SQL, PostgreSQL, 初心者, pgadmin4

# [Postgre: Windows 版でクエリーログの分析をしたい](https://qiita.com/baku2san/items/1c579e36b766ebf4adb4)
投稿日: 2022/2/25 
PostgreSQL, log, Windows10, PowerBI

# [PostgreSQL を Power BI のデータソースとした際の備忘録](https://qiita.com/baku2san/items/281d643137add0826997)
投稿日: 2021/10/8 
PostgreSQL, LINQPad, PowerBI

# [LinqPad: PostgreSQL のデータ操作を EF Driver で](https://qiita.com/baku2san/items/6a98e24bcfc55e2f5122)
投稿日: 2021/9/16 (更新日: 2022/2/25)
PostgreSQL, LINQPad, EntityFramework_Core, VisualStudio2019, .NET5.0
Flaskで作ったアプリをherokuにデプロイするときにつまづいたこと

# Herokuって無料らしいじゃん？

じゃあWebアプリ作るしかないべ。

想定していたのはオンラインゲームでP2P通信をするためのIPアドレスを交換するためのWebアプリです。

おおよその実装は以下で公開しています。真似しない方が良い部分もあるので注意してください。

https://github.com/AtomicHeadd/GameLobbyServer

# PostgreSQLとSQLAlchemy

Flask + Herokuで検索すると**PostgreSQL**と**SQLAlchemy**の話ばかり出てくると思います。
**PostgreSQL**は割とメジャー(就活の利用経験の欄に出てくるレベル)なので使ってみていいと思います。
**SQLAlchemy**はデータベースの違いを吸収してくれるライブラリです。多分MySQL使ってもSQLite使ってもPostegre使っても全部似たような書き方になるではないでしょうか。**Postgreしか使ったことないから知らんけど**。

**PostgreSQL**はherokuのAdd-onから追加しましょう。Resources→PostgreSQL→Setting→Database CredentialsからURIを取得します。そのURIをSQLAlchemyのデータベース用のURLとして使用します。

SQLAlchemyの書き方自体はシンプルです。
簡単に書くと
```python:そーすこーど♡

DB_URI = "*"
engine = create_engine(DB_URI)

@app.route("/some_func/", methods=['POST'])
def some_func():
    SessionClass = sessionmaker(engine) # おまじない
    session = SessionClass() # おまじない

    # 何らかの変更

    session.commit() # 変更の反映
    session.close()
```
詳しいクエリの書き方は除きますがおおよそこんな感じです。
エンジンはアプリにつき一つ、セッションはリクエストごと一つって感じ、**らしい**

webアプリはまずはローカル環境で実行してPythonのHTTPクライアントを作って一つ一つテストしてみるのが良いと思います。

# Heroku CLI

**heroku CLI**はデプロイするためのツールです。**git**も同時に必要になります。そこらへんに転がってるものをインストールしましょう。

herokuへのデプロイは簡単で、herokuのDeployの欄に実行するコマンドが全て書いてあります。
**ただし、そのままデプロイすると何もしないWebアプリの完成です。**

```heroku open```してもなんか「Congrats!」的なメッセージが出るだけです。

それは、
「どの言語のWebアプリか」の情報**Buildpack**と、
「どのモジュールを入れるか」の情報**requirements.txt**と、
「サーバーが何をすれば良いか」の情報**Procfile**が不足しているからです。。

# Buildpack

**Buildpack**はheroku管理ページのSettingにあるので使ってる言語のBuildpackを入れましょう。わーい！

もちろんFlaskを使っている場合はPythonです。
次にプロジェクトのディレクトリに```requiremenets.txt```を作成します(**必須**)
Buildpackはこの```requirements.txt```をつかってモジュールのインストールをしてくれます。

中身はこんな感じ！ウキキ！
使っているモジュールのリストなので人によって増減します。

```requirements.txt
Flask==1.1.1
gunicorn==20.0.4
SQLAlchemy==1.3.5
psycopg2 == 2.9.3
```

ちなみにherokuはgunicornを使うのでgunicornを入れる、**らしい**。

あとはこんな感じの```Procfile```(**必須**)を作ってかんせ～～～い。ワア！

```:Procfile
web: gunicorn --bind 0.0.0.0:$PORT app:app
```

あとはDeployに書いてあるとおりにコマンドを実行していけば無事公開されると思います。

# 動かない時は...

```heroku logs```を実行するとだいたい書いてあります。requirements.txtのモジュール漏れが大半じゃないでしょうか。

```code=H10 desc="App crashed"```や```error: failed to push some refs to```もだいたい```heroku logs```かheroku管理画面のOverview右上の```view build log```を参照することで解決できます。
(前者はモジュール漏れ、後者は必要なファイルが足りてない)

# 以上！

いやぁコマンド一つでアプリを無料デプロイできるのってすごい良いですよね。

エラーが出た時にとりあえず検索 → 試すを繰り返していたため紹介しきれなかった設定があるかもしれないですがご容赦いただきたい。多分必須知識は書いたかなと思います。
SQLite3でよく使うコマンドのメモ書き

SQLite3を使う時に、よく使うコマンドのメモ書きです。
SQLite3自体を時間を空けて使おうとすると忘れてしまうので、、

### SQLite3のバージョン確認

```
$ sqlite3 --version
SQLite version 3.27.0 〜
Enter ".help" for usage hints.
sqlite>
```

### SQLite3のDBファイルにアクセスする

これで、sqlite3のプロンプトに入る事ができ、指定したSQLiteのDB（データベース）にSQLを実行できるようになる。

```
$ sqlite3 testdb.sqlite3
SQLite version 3.27.0 〜
Enter ".help" for usage hints.
sqlite>

```

### SQLite3プロンプトの終了

.exitだけでなく、ショートカット「Ctrl + D」でもできる。

```
sqlite> .exit
```

### DBにあるテーブル一覧を確認する

```
sqlite> .table
```

### テーブルのスキーマを確認する

```
sqlite> .schema hogetable
CREATE TABLE hogetable(
  id integer primary key autoincrement,
  name text not null,
  content text not null,
  created_at text not null default (datetime('now', 'localtime'))
);
```

### 設定を確認する

ヘッダーやモードの設定を確認できる。

```
sqlite> .show
        echo: off
         eqp: off
     explain: auto
     headers: off
        mode: list
   nullvalue: ""
      output: stdout
colseparator: "|"
rowseparator: "\n"
       stats: off
       width: 
    filename: testdb.sqlite3
```

### ヘッダーを表示する

select SQL実行時に、結果のヘッダーに列名（カラム）を表示するようになる。

```
sqlite> .header on
```

### モード設定をlineに変更する

デフォルトのモードのlistだと、select SQL実行時の結果表示が非常に見にくいので、モードをlineに変更する。
(モードは他にもcolumn、htmlなどがある。)

```
sqlite> .mode line
```

### ヘルプでSQLite3のコマンド一覧を確認する。

```
sqlite> .help
```

### DBのSQLダンプを取る

DBのバックアップを取得したい場合で、SQLダンプを取得したい時についてです。

まず、hogetableテーブルのSQLダンプを取得する。

```
sqlite> .dump hogetable
〜
```

次に、DB全体のSQLダンプを取得する。

```
sqlite> .dump
〜
```

次に、SQLダンプをファイル保存したい場合です。
hogetableテーブルのSQLダンプをdump.sqlファイルに保存します。

```
sqlite> .output dump.sql
sqlite> .dump hogetable
```

### 外部のSQLファイルを読み込んで実行する

取得したSQLのダンプファイルなどを読み込んで実行したい場合についてです。
duml.sqlというファイル（中身はSQL）を読み込んで実行する。

```
sqlite> .read dump.sql
```
【Dokcer】gitを使用する【Remote-Containers】

## はじめに
Remote-Containersでgitを使用する方法について記載します。
設定を行わないと以下のようなエラーが発生します。
```:ターミナル
$ git clone git@github.com:sample/example.git .
Cloning into '.'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
OSによって手順が異なりますのでMacの設定方法について記載します。

## gitを使用する方法
秘密鍵を作成してGitHubに公開鍵を設定します。
次に以下のコマンドをローカルで実行し、ssh-agentにローカルSSHキーを追加します。
```:ターミナル
$ ssh-add ~/.ssh/id_rsa
Identity added: /Users/user_name/.ssh/id_rsa (user_name@MacBook-Pro.local)
```
上記のファイル名については異なる可能性があります。
追加されたか以下のコマンドで確認します。
```:ターミナル
$ ssh-add -l
```

以上でRemote-Containersでもgitを使用できるようになります。
PCを再起動した場合には上記の手順を再度ローカルSSHキーを追加する必要があります。

また、`.gitconfig`も自動的にコピーされます。
以下のようなエラーが発生した場合には`.gitconfig`にエディタの設定を追加してください。
```
error: unable to start editor 'editor'
```
vscodeに設定する場合には以下のコマンドで設定することができます。
```:ターミナル
$ git config --global core.editor "code --wait"
```
研修で行ったグループ開発(9日)

## 初めに
新卒として入った会社にて、受けさせて頂いた二か月のJava研修のラスト9日で行った、グループ開発についてまとめた記事です。

### 成果物
`家庭教師と学生のマッチングを行うシステム`を作成しました。
![スクリーンショット 2022-06-05 003400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695130/74c48c15-0307-3dbf-c9c1-d8c730e573c7.png)


### グループについて
6人のグループでした、簡単に私の主観を交えて役割(グループリーダー、サブリーダー、テクニカルリーダー[フロント]、テクニカルリーダー[バック]、DB管理、品質管理)と共に紹介します。

Wさん(グループリーダー)
・研修中、プログラムの演習で後述する神に次いで優秀な成績を残していた方、コーディングはもちろん、リーダー適性もとてもあったため、グループ最初のミーティングで満場一致でリーダーに。

Kさん(サブリーダー)
・自頭と顔が良い、言語化が上手いためメンバー間の認識を合わせるために、全体の方針、意見の統一をしてくださいました。

神(テクニカルリーダー[フロント])
・研修中、全てにおいてトップの成績を残していた神。
・今回のグループ開発において、この方が居てくださったおかげで成果物が二回りほど良い物となりました。

私(テクニカルリーダー[バック])
・コードを書くのが好きなため立候補。
・後述しますが、2日目でgitを壊す無能。

Sさん(DB管理)
・自信家、DB管理の仕事を後述の品質管理の方がついでに終わらせてしまい、ほぼコーディングをしていた方。

Tさん(品質管理)
・自頭と顔が良い、言語化が上手くミーティングで率先して話をしてくれるため、とてもありがたかった方。
・面倒な内容の仕事も、率先してくださったり、既に終わらせてしまっていた方。

## 開発の流れ
主要言語: Java
フロント: JSP、Bootstrap
RDBMS: MySQL
APPサーバー: Tomcat
開発環境: Eclipse
### 要件定義(1日目)
・最初、`マッチングアプリ`を作ってみたいとなったのですが、仮にも企業に成果物として提出するものが`マッチングアプリ`はまずいのでは、となり少しずらした`家庭教師と学生のマッチングを行うシステム`となりました。

・機能の洗い出し、画面遷移、スケジュールの作成等を行いました。

### 基本設計、DB設計、実装準備(2日目)
・基本設計からDBの設計、DBマスターデータの作成を行ったのですが、私がER図を作成するタイミングでミスを犯してしまいました、これが原因でDBレビューと言う物を一度で通過することが出来ませんでした。

・また、3日目の実装準備の際gitのマージをミスしてしまい、masterが壊れる事態になりました。

・以上、2日目は主に私の第一印象を最低にする事にしか成功しませんでした。
### 一次開発実装、テスト(3~6日目)
・基本設計時に決めたシステムに最低限必要を一次開発として実装しました。
・私は下の画像の赤い四角で囲んである、家庭教師と学生で共通の新規登録、ログイン機能を担当しました。
・実装に関しては特に問題が起こることは無く、神のおかげもあり、かなりスムーズに終わらせる事が出来ました。
![スクリーンショット 2022-06-05 015817.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695130/52283fa1-01c1-959a-caa5-279550af1f69.png)

### 二次開発実装(6~8日目)
・一次開発実装の完了の見通しがついたため、二次開発に取り組む事が出来ました。
・私は下の画像の赤い四角で囲んである、家庭教師と学生の間で連絡するためのチャットの実装をしました。
・一人でチャット機能を作り切ったことで、2日目で私の落ち切っていた印象を改善できたと思います(とても嬉しかった)。
・二次開発では家庭教師評価機能でフロントとバックでの連携で若干手間取ってしまいましたが、最終的には問題なく実装する事が出来ました。
![スクリーンショット 2022-06-05 022411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695130/353cf848-685f-97f4-877e-ddecbd41d5b7.png)
### 単体、結合テスト(9日目)
・一次開発分はほぼ単体、結合テスト共に終わっていたのですが、それに加えて二次開発分のテストを行いました。
・テストに割く日数が少なくなってしまい若干不安が残りましたが、問題なくシステムを作り上げることが出来ました。

## 感想
具体例や理由なしに、否定は行わない。
ポジティブな意見(すごいと思った事、感謝を伝える等)は積極的に言葉にし、相手に伝える。
など、意見を交わしやすい環境を作る事で、状況の共有や正確な意見の交換をすることが出来ると感じました。
また、それらはグループで開発をする上でとても重要だと感じたので、今後は行動に移していきます。
【書評】『推薦システム実践入門』 まとめと感想

## どんな本？
最近出た**日本語のレコメンド本**。
界隈で話題になっていたので読んでみた。
この記事では本の内容に触れつつ感想を書いていく。

https://www.oreilly.co.jp/books/9784873119663/

GitHub: https://github.com/oreilly-japan/RecommenderSystems

## どのへんが良い本なのか
まず、日本語で書かれたレコメンドの本には初学者にちょうどいい本がなかった。
（難しすぎたり、やや内容が古かったり。。）
この本はレコメンドに関連する技術や活用方法が網羅的に説明されているのがとても良い。
実際自分は**新卒の時にこの本があれば良かったなぁ**と思う。

一言で言えば「**近年のレコメンド界隈の全体像を把握するにはちょうどいい本**」

逆に細かい部分の詳細には立ち入っていないので、各分野について詳しく知りたければ他の本やドキュメントを漁る必要がありそう。

## 構成
この本はざっくり以下の3パートに分割できる。

- **1~4章　レコメンドの導入、活用方法**
    - サクッと読める
- **5章　レコメンドで使われる手法の紹介**
    - ボリュームがでかい
    - GitHubにコードが置いてある 
- **6~8章 実サービスでの運用**
    - オンライン/オフラインでの検証方法など
    - 7章は評価指標（メトリクス）について

それぞれ感想を書いていく。

## 1~4章　レコメンドの導入、活用方法

「**レコメンドとはなんぞや？ なぜ重要なのか？**」
の部分。
数式がほとんど出てこないので、ビジネスに興味はあるけど数式が苦手な人でもサクッと読めると思う。

僕はエンジニアなので、レコメンドシステムと聞くとどうしても具体的な手法にばかり興味がいってしまう。
一方で1-4章では多角的な視点からレコメンドの役割について考えていて、勉強になった。

例えば

- 検索システムとの比較、役割の違い
- UIの重要性
- どのような課題を解決できるのか

などなど。

「**トンカチを持つと全てが釘に見える**」

とはよく言われるけど、それはレコメンドについても同様だと思う。
何か課題があって、その課題を解決するための手段としてレコメンドが存在するんだということを僕たちは肝に銘じておかなければならない。

とまぁ俯瞰的な内容が1-3章。
4章はもう少し技術的な部分に立ち入ってて、レコメンドにおいて重要な
- **コンテンツベースの手法**
- **協調フィルタリング**

が説明される。

## 5章　レコメンドで使われる手法の紹介

この5章では雰囲気がガラリと変わる。
Pythonのコードを添えて具体的な実装方法の説明に入る。
検証に使われるデータはこの分野ではおなじみの　"**Movie Lens**"。

コードは本にも載っているがこれだけ見ていてもわかりづらいので、必要に応じてGitHubに置いてあるnotebookを動かしてみると理解が深まると思う。

自分は**Google Colab**でいくつか回してみた。

ちなみにAmazonのレビューで「コードが読みにくい」という意見があったが、GitHubのコードを見に行けば済む話なので自分はそんなに気にならなかった。
紹介されている手法は以下

- **ランダム推薦**
    - ランダムに推薦した場合
    - 他の手法と比べる時のbaselineとしての意味しか持たない
- **統計情報などのルールベースの推薦**
    - 売り上げ順に推薦したり、ユーザーの年齢などのデモグラ情報使ったり
- **アソシエーションルール**
    - 同時に買われる商品の共起を数え上げたりするやつ
    - 「おむつとビールが同時に購入される」みたいな逸話
- **ユーザー間型メモリベース協調フィルタリング**
    - バッチではなくリアルタイムに類似度を計算する
- **行列分解**
    - ユーザー✖️商品のmatrixがスパースな場合にどうやって分解するか
    - **MF** (Matrix Factorization)
    - **BPR** (Bayesian Personalized Ranking)
    - **FM** (Factorization Machine) 
    - etc.
- **自然言語処理手法の推薦システム応用**
    - 自然言語処理の手法をどうやって推薦処理に活かすか
    - word2vecとかその辺の話
    - ユーザーの購入遷移を時系列データとして扱う
- **深層学習 (Deep Learning)**
    - 深層学習を用いたレコメンド
    - 特徴量生成に使う or モデリングに使う
- **バンディットアルゴリズム**
    - 強化学習の文脈
    - A/Bテストに比べて利益最大化しやすいが、知見を得づらい


見てわかる通り、多岐に渡っているので辞書的に読むのでもいいかもしれない。
全体をざっと読んで気になる手法があればコードを動かしてみるといいと思う。

## **6~8章 実サービスでの運用**

実際にどういう仕組みで運用するのかについての話。
例えば近年多くの企業では
- candidateとなる商品をざっくり選ぶ（recall重視）
- GBDTなどでrerankする

などの複数のステージにまたがってシステムを構成することが多い。
他にもオンライン/オフラインでそれぞれ

- **オンライン**
    - どのようにログを落とすか
    - どのようにA/Bテストを行うか

- **オフライン**
    - どのようなメトリクスを採用すべきか
    - MRR, MAP, nDCG, etc.
    - メトリクスごとの違い

などについて説明されている。

## 感想

A/Bテストの他にインターリービングの話も載ってたり、深層学習や強化学習にも触れられていたり、とにかく幅広いなーと思った。

参考文献も比較的最近のものが多く、良かった。
例えばDeep Learningの章ではRecSys 2019のベストペーパーで提言された
「**近年提案された深層学習の推薦システムのほとんどがちゃんとチューニングしたk近傍システムよりも精度が悪かった**」
という身も蓋もない話が載ってたりとか。

コードが全部GitHubに載ってるのも嬉しいところ。

## まとめ

- 初学者がレコメンドについて網羅的に理解するには最適
- 各トピックの詳細については他の資料をあたる必要がありそう
LINE Bot作成時のLINE Developers設定の備忘録

プログラム初心者が、覚えた事を備忘録として記事にしています。
本記事は`LINE BOt`作成時の`LINE Developers設定`の備忘録。

## 新規登録から設定までの流れ

https://developers.line.biz/ja/

### [LINE Developers](https://developers.line.biz/ja/)でプロバイダー作成
※初めてご利用される方はLINEアカウントでログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/13b8ffa2-b55d-6cdd-6e22-be4f77e26dd0.png)
### `今すぐはじめよう`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/b918145f-09fe-f308-b4ba-102551681e0c.png)
### `チャネルの種類`　`プロバイダー`は初期設定のまま
`プロバイダー名`は任意の文字を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/a73b9aa9-ea67-dede-a991-88df8c0ffbc8.png)
### `チャネル説明`は自身が分かりやすい内容を入力。
`大業種``小業種`はご自由に選択下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/fd02f1ae-1b54-1d16-fc6f-2f0398f9e875.png)
### `同意欄`２か所にチェックし`作成`ボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/b217c1cd-9bfd-1b41-0acb-dc504b0abb62.png)
### 新しいプロバイダが作成されました！赤枠内は今後の各種設定で必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/c6ec581d-9337-e34f-3e55-4a72949b0054.png)
### まずは作成したLINE Botと友達になりましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/ba943898-7871-3767-ce29-69a0e34549df.png)
### 次に応答設定を以下の通り変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/ada9b3f4-714c-7e3b-0a0b-5ff7bcd3eb23.png)

### MAKE(旧Integromat)やNode-REDなどと連携する場合は、以下の情報が必要となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667370/a7b491d6-c7d7-d3b2-0c38-167dfd0d37a9.png)


以上で基本的な設定は終了です。
コマンドでサクッと動画からgifを作成

## 準備
ターミナルで以下のコマンドを実行していきます

適当なフォルダを作成して、その中に動画を入れます。
```
|フォルダ1
    |_ 動画
```

## 動画を画像に変換
```
ffmpeg -i ファイル名.拡張子 -an -r 10 %04d.png
```
この際大量に画像が作成されるため、フォルダを作成してからその中で実行した方がいいです。

## 画像サイズ変更
40%のところをいじって、リサイズしてみてください
```
convert *.png -resize 40% output_%04d.png
```
## gifを作成
```
convert output_*.png ファイル名.gif
```

以上
Laravelのバリデーションエラー時にoldや$errorsが消える

# 概要
LaravelのFormRequestでバリデーションを入れた。
バリデーションに引っ掛かると前のページに戻されるがフラッシュセッションがバグってoldも$errorsも空になる。

# 検証結果

バリデーションエラーを検知すると以下が発動。

laravel_project/vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php

```
    protected function failedValidation(Validator $validator)
    {
        throw (new ValidationException($validator))
                    ->errorBag($this->errorBag)
                    ->redirectTo($this->getRedirectUrl());
    }
```


xdebugで追いかけていると、ここで一回セットされていた。
が、なぜかもう１周走って
1週目は　sessionの　_new が _old になり。
2週目で _old がクリアされていた。

laravel_project/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php

```
    protected function handleStatefulRequest(Request $request, $session, Closure $next)
    {
        // If a session driver has been configured, we will need to start the session here
        // so that the data is ready for an application. Note that the Laravel sessions
        // do not make use of PHP "native" sessions in any way since they are crappy.
        $request->setLaravelSession(
            $this->startSession($request, $session)
        );

        $this->collectGarbage($session);

        $response = $next($request);

        $this->storeCurrentUrl($request, $session);

        $this->addCookieToResponse($response, $session);

        // Again, if the session has been configured we will need to close out the session
        // so that the attributes may be persisted to some storage medium. We will also
        // add the session identifier cookie to the application response headers now.
        $this->saveSession($request);

        return $response;
    }
```


#原因

laravel_project/app/Http/Kernel.php
で

```
 \Illuminate\Session\Middleware\StartSession::class
```

を２回コールしていた。

たぶんデフォルトは以下の場所にしかなかったのではと思うが、

```
    protected $middlewareGroups = [
        'web' => [
          ..... 
        ],
```

過去のタスクで
以下の中にも書く修正を入れていた。

```
protected $middleware = [
   ...
]
```

結果としてweb.phpに入っているルートでは全部フラッシュセッションを２回処理していたらしい。

普通、この状態で長期間放置されることはありえないのですが、今回はweb.phpとadmin.phpにルートファイルが分かれていて、今までにフラッシュセッションを使っているのが管理画面だけだったため、気づくことがなかった。


# 他のパターン
## Kernel.phpに以下の記述がない場合も表示されない。

```
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
```

## .envのセッションドライバー

セッションドライバーがクッキーだと動かないのでファイルにするようにとのこと。
データベースでも問題ないと思う。たぶん。
mac vscode switch tabs


```js
[{
    "key": "cmd+0",
    "command": "workbench.action.openLastEditorInGroup"
  },
  {
    "key": "cmd+1",
    "command": "workbench.action.openEditorAtIndex1"
  },
  {
    "key": "cmd+2",
    "command": "workbench.action.openEditorAtIndex2"
  },
  {
    "key": "cmd+3",
    "command": "workbench.action.openEditorAtIndex3"
  },
  {
    "key": "cmd+4",
    "command": "workbench.action.openEditorAtIndex4"
  },
  {
    "key": "cmd+5",
    "command": "workbench.action.openEditorAtIndex5"
  },
  {
    "key": "cmd+6",
    "command": "workbench.action.openEditorAtIndex6"
  },
  {
    "key": "cmd+7",
    "command": "workbench.action.openEditorAtIndex7"
  },
  {
    "key": "cmd+8",
    "command": "workbench.action.openEditorAtIndex8"
  },
  {
    "key": "cmd+9",
    "command": "workbench.action.openEditorAtIndex9"
  },
  {
    "key": "ctrl+1",
    "command": "workbench.action.focusFirstEditorGroup"
  },
  {
    "key": "ctrl+2",
    "command": "workbench.action.focusSecondEditorGroup"
  },
  {
    "key": "ctrl+3",
    "command": "workbench.action.focusThirdEditorGroup"
  }
]
```


---

Ref:

https://stackoverflow.com/a/46087295
【2022年版】Cisco ルータ コマンド メモ

# Cisco ルータ コマンド メモ

- Cisco Packet Tracer上におけるコマンド利用のメモ
- [Cisco Packet Tracer のダウンロード](https://www.netacad.com/courses/packet-tracer)

## 設定モードへ

```
>enable
```

## 共通設定

- ドメイン名を引かせない（コマンドをミスタイプすると名前解決しようとする不便を解決）
```
(config)#no ip domain-lookup
```

## 設定保存
### 現在の設定を起動時設定に保存

```
#copy running-config startup-config
```

## パスワード設定

```
(config)#enable password {password}
```

## ユーザ設定/作成

```
(config)#username {username} password {password}
```

## ホスト名・ドメイン名・NTP・DNS設定

```
(config)#hostname {hostname}
(config)#ip domain-name {domain-name}
(config)#ntp server {ntp ip address}
(config)#ip name-server {dns ip address}
```

## web(http/https)サーバ無効化

```
(config)#no ip http server
(config)#no ip http secure-server
```

## IPアドレス設定

```
(config)#interface {interface}
(config-if)#ip address {ip address} {subnetmask}
```

## ssh設定

```
(config)#ip access-list standard permit-ssh
(config-std-nacl)#permit {ip address}
(config-std-nacl)#exit
(config)#line vty 0 15
(config-line)#login local
(config-line)#access-class permit-ssh in
(config-line)#transport input ssh
(config-line)#transport output none
(config-line)#exit
(config)#crypto key generate rsa
How many bits in the modulus [512]: 2048
% Generating 2048 bit RSA keys, keys will be non-exportable...[OK]
(config)#ip ssh version 2
```

* password は secret を使うことを推奨
* route のsshクライアント機能を利用する場合は、```transport output ssh``` に変更する

## ルーティングテーブル確認

```
>show ip route
```

## ルーティングテーブル設定

```
(config)#ip route {ip} {subnet} {interface}
```

## デフォルトゲートウェイの設定

```
(config)#ip route 0.0.0.0 0.0.0.0 {gateway ip address}
```

## アクセスリストの設定

- 利用できる標準アクセスリスト番号
  1〜99
  1300〜1999

- 利用できる拡張アクセスリスト番号
  100〜199
  2000〜2699

- アクセスリストの確認

```
#show ip access-list
```

```
#show ip interface {interface}
```

## バナー設定

```
(config)#banner motd #
```

## pat/napt/IPマスカレードの設定

- 内側のインターフェイスの設定

```
(config)#interface {interface}
(config-if)#ip nat inside
```

- 外側のインターフェイスの設定

```
(config)#interface {interface}
(config-if)#ip nat outside
```

- アドレスプールの設定（patなので１つ）

```
(config)#ip nat pool patpool {outside interface ip} {outside interface ip} netmask 255.255.255.0
```

- アクセスリストの設定

```
(config)#access-list {1 - 99} permit {access allow ip} {access allow length}
```
  
-  アクセスリストの番号 10 を 192.168.0.0/24 を範囲とする場合

```
(config)#access-list 10 permit 192.168.0.0 0.0.0.255
```

- アクセスリストをプールにマッピング

```
(config)#ip nat inside source list {access list number} pool patpool overload
```

- NATテーブルの確認

```
#show ip nat translations
```

## コマンド編集機能

|コマンド|結果|
|--------|-------------------|
|ctrl a|カーソルを行頭へ|
|ctrl e|カーソルを行末へ|
|ctrl f|カーソルを１文字すすむ|
|ctrl b|カーソルを１文字もどる|
|esc f|カーソルを１単語すすむ|
|esc b|カーソルを１単語もどる|
|ctrl d|カーソルの右側の１文字を削除(DELETE)|
|ctrl x|カーソルから右側を全て削除|
|ctrl k|カーソルから左側を全て削除|
|ctrl w|カーソルの左側の１単語を削除|
|ctrl u|行の削除|
|ctrl r|行の再表示|
|ctrl p|ひとつ前のコマンドを表示|
|↑|ひとつ前のコマンドを表示|
|ctrl n|ひとつ先のコマンドを表示|
|↓|ひとつ先のコマンドを表示|


## macからルータへの接続

- consoleへ物理的に接続する
- インターフェイスの確認、usbserialのインターフェイスがルータへの接続

```
% ls -l /dev/tty.usbserial*
```

- インターフェイスへの接続

```
% screen /dev/tty.usbserial-{確認した値}
```

## Cisco IOSのダウンロード

- [Cisco Software Download](https://software.cisco.com/download/home)