OmniAICreator/Qiita-1.07M huggingface dataset:
正規表現で特定文字列を含まない、否定の検索・記述

# 正規表現で特定文字列を含まない検索をしたい！
よく大量のcsvだったり、tsvデータの中から、特定の文字列を含む行だけを取り出したい！！
なんてことがありませんか？

そんなときにサクラエディタと正規表現で不要物を取り除く。
ということをやる人はやるかと思うので、その方法を備忘録として記載しております。

## 利用する記述としては以下
### ～を含まない
```
^(?!.*abc).*$
```

### 〜または〜を含まない
```
^(?!.*(abc|efg)).*$
```

### 〜で始まらない
```
^(?!abc).*$
```

### 〜で終わらない
```
^(?!.*abc$).*$
```

### 〜を含むが、〜を含まない
```
^(?=.*abc)(?!.*def).*$
```

## 参考リンク
https://uxmilk.jp/50674
CKAに合格したので感想を書く

先日Certified Kubernetes Administrator (CKA) の試験を受けて合格したので感想を書きます。

## 著者のバックグラウンド
- Linuxサーバ管理は3年弱ほど経験あり
- Kubernetesは1年弱ほど

## CKAを受けようと思ったきっかけ
- 対外的にKubernetesわかります！と言いたかったので
- 業務で触れないKubernetesの機能を使ってみたかったので

## 勉強法
[Udemyの定番コース](https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/)を試験2週間ぐらい前からやり始めました。
ハンズオンラボ環境がついてきます。


## 感想
### 良かったこと
- Kubernetesの基礎的なアーキテクチャに関する知識が深まった
    - control planeの各コンポーネントの動作や起動方法は今まで`kubeadm`任せだった
- セキュリティ・認証認可まわりのアーキテクチャや、設定に関するベストプラクティスを知れた
- 部屋が片付いた

### よくなかったこと
- 正直知っている内容が多かった
    - 業務でオンプレミスのKubernetesクラスタを管理しているため
    - 合格することを目標にしてしまうと、対して勉強しなくても合格できてしまうという印象はあった
        - しかし、知らないことを知るのは難しく、一度体系的に広く浅く学ぶことで弱かった領域を確認できたことは良かった
- クラスタ管理に必須だが、Kubernetesに備わっていない機能については学習できない
    - [カリキュラム](https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/)にも記載があるが、外部プラグインに関する動作や設定方法は試験範囲外である
    - 対象外の例：
        - 各CNIプラグインの動作
        - Obserbability関連(Prometheus, Fluentd, Grafana, Elastic stack等)
        - サービスメッシュ
        - 外部ロードバランサの設定
        - ストレージドライバの動作　(`hostPath`以外はほとんど使いませんでした)
        - helm, Kustomize, GitOpsなどのマニフェスト管理
            - CKADのカリキュラム内かもしれない

## 試験について

CKA-JPを受けましたが、試験官・サポートセンターとのやりとりは全て英語でした。問題文は自然な日本語でした。

試験はPSIセキュアブラウザという仮想環境的なものをコンピュータにインストールして行います。Webカメラで部屋に怪しいメモや本などがないことを確認させられるので、事前に部屋を片付けておく必要があります。
Kubernetesの公式ドキュメントを参照することができますが、PSIセキュアブラウザ内の非常に小さい画面(画面サイズの1/4ぐらい)から確認していたので非常に見づらかったです。
先人たちはChromeで見てブックマークも使っていたと書いていたので、Chromeを使えるのかと思っていました。試験官にChromeを使っていいかを聞いたら試験要項を確認してくださいと言われ、試験要項をChromeを使わずにどうやって確認するのかわからなかったので、結局PSIセキュアブラウザ内からドキュメントを閲覧することにしました。

今後CKADやCKSを受ける可能性があるので、Chromeを使えるのかどうか調べておこうと思います…

### 試験でのやらかし
- Linux Foundationに英語で名前を登録していたが、英語の身分証明書を持っていなかったので、結局日本語名に名前を変えることになった。
- 初めWindowsデスクトップで受けようとしたが、Webカメラがザコすぎて身分証にピントが合わず、身分証を確認できないと言われて、海の向こうのサポートセンターまで電話することになった。
    - 拙い英語でやりとりした結果リモートデスクトップで遠隔操作させられそうになったが、それで解決すると思えなかったので、別のデバイスで入り直していいですか？と聞いて、そうすることになった。
    - 結局Macbook Proで入り直したら何の問題もなく試験できた。
    - 先人の言う通り試験はノートPCで受けることを推奨します。

## まとめ
自分はKubernetesの実務経験がある程度ある状態で試験を受けましたが、むしろ全く未経験でこれからKubernetes始めます、の時に受けておきたかった試験でした。
と言うのも、体系的な理解のもとで実務に取り組んだ方が、実務上の問題の理解も早く、よりよい判断ができただろうと思うからです。

また、CKAの合格でKubernetesの基本的なアーキテクチャの理解とトラブルシューティング能力を証明することはできますが、実務でクラスタ管理するための全ての知識が備わっているという証明にはならなさそうだな、という印象を受けました。これは、OSSでも商用でも、実際にクラスタ管理するにはサードパーティツールの活用が必須となっていると考えるからです。
試験合格は目的ではなく、それに至るまでの勉強、あるいはその勉強内容を足がかりにした実践が大事というよく言われていることを再び思った試験でした。
Azure App Serviceへの継続的デプロイを試す

### はじめに

前回、[Azure App Serviceを使ってWebアプリを動かしました](https://qiita.com/k-kimino/items/6fa61f407ffe61fc8b56)。継続的デプロイを使ってGitHubにPushしたら変更が自動で環境に適用されるようにします。

### Githubにレポジトリを作成

公開したいファイルをレポジトリに登録します。とりあえずindex.htmlを適当に作成してPushしました。
```
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>My website</title>
    </head>
    <body>
        <p>Hello World</p>
    </body>
</html>
```

### App Serviceを作成

今回はAzure PortalからApp ServiceおよびApp Service Planを作成していきます。後からでも設定できますが、ここでGitHubのレポジトリと紐づけることができます。これを設定しておくことで、継続的デプロイが実行できます。
![Createkeisfirstweb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/75b3251d-d6bf-ed11-b98b-e002955219f3.png)

### アプリの実行を確認する

すでに継続的デプロイのセットアップが完了しているので実行結果を見てみます。寂しい感じですがHello Worldが表示されているのを確認できました。
![deploymentcenterlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/cfa1904b-af36-43fe-ee1e-08fc0730cb24.png)
![webaccess1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/43610cea-8864-1830-da4a-7f51c26a7a6f.png)

### 変更をコミットする

あまり面白くないですが、表示する文字をHello Keisukeに変えてコミットします。GitHub上で連携したブランチの中身の変更をコミットするだけで即座にApp Serviceにも変更が適用されました。
![CommitChange.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/5e585130-057a-577c-8032-d00894f79911.png)
![webaccess2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/75823691-865e-13d4-dbed-3395c21a6a5c.png)

### まとめ

Azure App Serviceへの継続的デプロイを設定してみました。GitHubを更新するだけなのでいい感じに効率化されましたと思います。

### 参考

- [GitHubとAzure AppServiceで自動デプロイ](https://qiita.com/t-sakurai816/items/dcbbc8dbe988873412cc)
- [Azure App Service への継続的デプロイ](https://learn.microsoft.com/ja-jp/azure/app-service/deploy-continuous-deployment?tabs=github)
Tasks: TOP => db:migrate:status => db:load_config => environment (See full trace by running task with --trace)のエラーの解決方法

<h3>経緯</h3>
マイグレーションのあと勝手にコマンドが入って実行中のタスクをctrl+Cをして強制終了したあとデバイスの導入を継続していたが、下記エラーが発生してdbのマイグレーションを実行しようとしたら実行で
きなくなった

```ruby:ターミナル
Tasks: TOP => db:migrate:status => db:load_config => environment
(See full trace by running task with --trace)
```


<h3>解決までの道のり</h3>

1. routes.rbにあるdevise_for :usersというコードを削除する（これでrailsコマンドが使えるようになります！）
2. rake db:rollbackでマイグレーションファイルをロールバックする。（これをすることによって先ほど作ったuserテーブルのマイグレーションファイルをなかったことにしましょう。）
3. userテーブルを作ったときのマイグレーションファイルを削除する。
4. rails d model userを行いuserモデルを削除する。

上記の2の工程で同じエラーが出た。

`
 bundle exec rake db:migrate:status`

を実行すると、

```ruby:ターミナル
database: ファイル名_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     000             ********** NO FILE **********
  down    20230505232327  Devise create users

```

マイグレーションファイルがupの状態で消されたためエラーになっている様子。

マイグレーションファイルをコマンドで削除してみる

<b>1.まず名前を付けてあげる</b>

`touch db/migrate/000_hoge.rb`

再度` bundle exec rake db:migrate:status`実行すると以下の結果に

```ruby:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     000             Hoge
  down    20230505232327  Devise create users

```
無事に名前が付きました

その後

`bundle exec rake db:migrate:down VERSION=000_Hoge.rb`
を実行

```ruby:ターミナル
rake aborted!
Invalid format of target version: `VERSION=000_Hoge.rb`
/home/user/.rbenv/versions/2.6.5/bin/bundle:23:in `load'
/home/user/.rbenv/versions/2.6.5/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate:down
(See full trace by running task with --trace)
```
まだエラー
コマンドの記述間違えたのか？と思いコマンドの記述を下記に変更して実行
`rails db:migrate:down VERSION=000`　

down成功！

この後消していく
`rm db/migrate/000_hoge.rb`

```
$:~/ディレクトリ名/ファイル名 rm db/migrate/20230505232327_devise_create_users.rb
$:~/projects/protospace-38955$ bundle exec rake db:migrate:status

database: ファイル名_development

 Status   Migration ID    Migration Name
--------------------------------------------------

```
大成功！！

これでdeviseの導入から再スタートできそう
deviseによるユーザー管理機能の実装手順

<h3>手順1：Gemの導入</h3>

 gemfileの最終行に追加
```Ruby:gemfile
gem 'devise'
```
 `bundle install`を実行
 `rails g devise:install`を実行

<h3>手順2：モデルの作成</h3>

`rails g devise モデル名`でモデルを作成
今回はuserモデルを作成するので`rails g devise user`とする。
その後`rails db:migrate`でマイグレーションを実行する。

<h3>手順3：テーブルの作成</h3>
マイグレーションファイルにはデフォルトでemailやパスワードが入っているのでそのほかの項目を追加していく。

`rails g migration Addカラム名To追加先テーブル名　追加するカラム型:型`

でテーブルにカラムを追加することができる。
今回は、[profile:text型]、[occupation:text型]、[position:text型]　の3つのカラムを追加する。
```ruby:ターミナル
rails g migration AddProfileToUsers profile:text
rails g migration AddOccupationToUsers occupation:text
rails g migration AddPositionToUsers position:text
```

マイグレーション前であれば、直接マイグレーションファイルに記述を追記してマイグレーションを実行することでカラムを追加することもできる。

```ruby:***********_devise_create_users.rb
      # 省略
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.string :name,               null: false
      t.text   :profile,            null: false
      t.text   :occupation,         null: false
      t.text   :position,           null: false
```
記述完了後`rails db:migrate`でマイグレーションを実行する。


<h3>手順4：viewファイルの作成</h3>

`rails g devise:views`でdevise用のビューファイルを作成する。

<h3>手順5：バリデーションの設定</h3>

```ruby:userモデル
  validates :profile,    presence: true
  validates :profile,    presence: true
  validates :occupation, presence: true
  validates :position,   presence: true
```

<h3>手順6：パラメーターが受け取れるように記述</h3>

```ruby:ApplicationController
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :profile, :occupation, :position])
  end
end
```

デバイスの導入完了
ChatGPTを使っているのは、ほんの一部の人だけ！？ChatGPTの利用状況について1000人に聞いてみた

最近話題の「ChatGPT」ですが、果たしてどれくらい使われているのでしょうか？

私自身、毎日ChatGPTを活用しており、職場（IT係）でも周りのほとんどの人が使ったことがあるため、かなり普及していると感じていました。しかし、プライベートの友人たち（IT系はいない）の中では、使っている人がほとんどいません。

そこで、「もしかしてChatGPTは、実はほんの一部の人たちだけで使われているのかも？」 と疑問に思い、1000人にアンケートを実施しました。

この調査では、ChatGPTの普及状況や今後の広がり、そしてChatGPT Plusについても触れています。驚くべき結果が明らかになりましたので、ぜひ最後までお楽しみください！

# アンケート回答者について
-  **調査概要**：ChatGPTの利用についてのアンケート
-  **調査期間**：2023年5月5日〜2023年5月8日
-  **調査人数**：1,000人
-  **調査対象**：全国の10代～70代男女
-  **調査方法**：インターネットでのアンケート

![スクリーンショット 2023-05-09 17.32.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356814/5cb57ea2-eb48-4ee8-5d0d-c171929f2546.png)
アンケート回答者の男女比は半々で、年代は30代~40代で半分以上を占めています。

回答者の職業や勤務先の業界は以下の通りです。
「その他」がかなり多くなってしまったので、選択肢の作り方をちょっとミスった感はありますね...
![スクリーンショット 2023-05-09 17.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356814/f85bf3fd-8549-d240-6959-9d7dce713bc2.png)
# ChatGPTの認知率は86.4%!!
![スクリーンショット 2023-05-09 17.59.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356814/bb084615-9e38-f5c4-f3eb-59ba07fba681.png)
まず、「ChatGPT」自体を知っているかどうかを尋ねたところ、なんと86.4%もの人が「知っている」と回答しました。

正直、まだ一部の人しか知らないと思っていたので、こんなに高い数字には驚きました！

インターネットのアンケートなので、普段からネットを使っている人が多いというバイアスはありますが、それでも驚くべき結果です。

以下のアンケートはそれぞれ2023年の2月と3月に行われたもので、その時点では「ChatGPTを知っている」という人は30%程度でした。

今回のアンケートと比べると認知率が半分以下という結果ですが、この2~3ヶ月で何が起きたのでしょうか？

https://prtimes.jp/main/html/rd/p/000000007.000068054.html

https://productzine.jp/article/detail/1677

![スクリーンショット 2023-05-09 18.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356814/8a3a590b-6d0f-cb94-18b2-2eadd5748346.png)

Googleトレンドによると、2023年の4月ごろから検索数が急上昇しています。

2023年3月末ごろに国会でChatGPTの話題が取り上げられたり、少しずつ世間に認知されてきた可能性が高いです。

特に、4月10日に首相がOpenAI社（ChatGPTの運営会社）のCEOと会ったことで、ニュースでも大きく報道され、検索数が急激に増えました。

その後、各都道府県の知事がChatGPTの利用について言及するなど、ニュースや新聞でChatGPTという言葉を目にする機会が増えました。

だからこそ、2023年2月と3月のアンケート結果と比較して、認知度が大幅に上がったのでは予想されます。

もうChatGPTは国民の多くが認知しているツールになっているのですね。

# ChatGPTの利用率

それでは利用率はどうでしょうか？

![スクリーンショット 2023-05-09 18.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356814/1525a507-d010-22d6-6e3b-fffd944024ba.png)


次に、「ChatGPT」を利用したことがあるかどうかを尋ねたところ、無料版を使ったことがある人は29.7%でした。

認知率が86%ある中で、実際に利用したことがある人が30%程度と、知っているけど使ったことがない人が多いことがわかりますね。

ただ、国民の3割が少なくとも一度はChatGPTを使ったことがあるというのは驚きですね。

一方で、ChatGPT Plus（有料版）を利用したことがある人はわずか1%でした。

無料で使えるChatGPTでも日常使いには十分ですし、月額2000円以上もかかる上に利用制限があることから、有料版は興味が強いユーザーだけが使っているようです。

性別、年代別、業界別のChatGPT利用率については、以下のページで詳しく解説しています。興味がある方はぜひご覧ください。

https://generativeinfo365.com/?p=205

# ChatGPTを使いこなすだけで使っていない人と大きく差が出るのは確実
アンケート結果から明らかになったことは、ChatGPTの認知率がなんと86.4%にも達し、無料版の利用率は29.7%で、国民の3割が少なくとも一度は試したことがあるということです。

しかしながら、有料版のChatGPT Plusは利用率が1%と、興味津々なユーザーが中心だという結果が得られました。

このデータから言えることは、今後ChatGPTの利用率はさらに拡大することは間違いないので、今後の時代を見据えた場合、ChatGPTの活用がビジネスや日常生活において大きな差を生むと予測されます。

結局のところ、今後の成功において、ChatGPTの使いこなし方が重要な要素となることは間違いないので、早いうちから使い方に慣れ、時代の変化に適応していくことが求められることでしょう。

今回のアンケートは全体の認知率や利用率以外にも、性別、年代別、業界別の利用率や、ChatGPTを利用している人の普段の利用方法や今後についてのアンケートも行なっています。

そちらの結果は以下のページでまとめているので、興味がある人はこちらも参考にしてみてください！

https://generativeinfo365.com/?p=205
リモートリポジトリとローカルリポジトリの状態が不一致したとき

こんにちわ。ZaQです。:smiley:

会社内でおいてGithubを用いてプロジェクト管理を行い、メンバー内でのコードレビューを実施しています。

メンバー内でブランチをpushする際には一定のルールを設定した上で行っているものの、ふと自分のローカルリポジトリを見ると、、

 **ローカルリポジトリ内がレビューしたリポジトリがたくさん〜〜**
 **リモートリポジトリ内で無くなっているリポジトリもたくさん〜〜**

これはデータの整理が必要ですね。

## 弊社内のリポジトリバージョン管理のルール

弊社内では、

:::note info
<dt>ルール</dt>
1.リモートリポジトリのブランチは基本的にmainのみとする <br>
2.レビューが終了後はリモートリポジトリのブランチを削除する <br>
3.リモートリポジトリにpushする場合は、 <strong>name/branch_name</strong> とする
:::

といった形でリポジトリ管理を行っております。プロジェクトを進めていく上では最低限のルール策定は必要ですね。

ではローカルリポジトリのデータ整理を実施しましょう。

## 整理は簡単！一つのコードのみ！

下記のコードを実施しましょう。

```
git fetch --prune
```

このコードを実施すると

:::note info
<dt>ポイント</dt>
リモートリポジトリから最新の変更を取得し、リモートリポジトリから削除されたブランチやタグをローカルのリポジトリからも削除
:::

してくれます。そのため、下記のような出力を得ることができます。

#### ■削除の例
リモートリポジトリから削除されたブランチやタグをローカルのリポジトリから削除

```
 - [deleted]         (none)     -> origin/ZaQ/sample1
 - [deleted]         (none)     -> origin/ZaQ/sample2
```

#### ■追加の例
ローカルのリポジトリをリモートリポジトリと同期

```
* [new branch]      develop             -> origin/develop
* [new branch]      testsample          -> origin/testsample
```

これにより、不要なブランチが残ることなく、リポジトリが整理することができます。

それではまた。

弊社サイト：https://www.winescan.co.jp/
私たちの働きでひとり一人の自分らしさをupdateし続けることができる社会を目指します
新しいことを学ぶ環境の作り方

## 結論
自分で何を行うか決めること

## 内容
何かを勉強したい。何かを勉強しないといけない状況はあると思いますが、実際に何かを勉強し始めることはそう多くないと思います。もともと普段行っていることで、１週間のスケジュールは埋まっていると思います。そこで、追加で何かを勉強するには、時間が追加されたりしない限り、物理的に実行できないと思います。
時間を追加することは難しいと思います。(というか私はできません。)
時間を追加することはできない中で、どうやって他の人は勉強することができているのでしょうか。
答えは「決めること」です。
実は皆さんは、１日にかなりの多くの決めることを行っています。今日起きた後にスマホの電源を入れるかどうか。今日は外に出る時に何の服を着るべきか。何時に仕事や学校に向かうか。こういった決めることをたくさん行っているのですが、毎日同じことをしているので、決めるという感覚が皆さんには無いと思います。
朝起きて、スマホの電源をつけづに洗面台に向かう。外に出る時に、パジャマのままで出ていく。仕事や学校に向かう時間を３０分早める。決定すればできることはたくさんできます。(パジャマが良いかどうかは置いておいて)
その中で、英語を１８時を過ぎたら勉強するであったり、機械学習の勉強を朝５時に起きて行うであったり、決めてしまえばいくらでも勉強を開始することができます。
もともとあったスケジュールは勉強することよりも大切なものかを一度考えると良いと思います。（トイレとか、人間にとって最低限のことは優先しましょう）
パソコンやタブレット端末からスマホへSMS、電話番号にショートメッセージを送る方法

こんにちは！ChatGPTです！
またまたクソくだらない記事の要約を頼まれてしまったので、下記の通り要約をしていくぜ！

筆者が3年前に作った「もじアドレス」というサービスについて、宣伝記事を書いた過去があったが、サービスの使い方の紹介記事がないことに気付き、改めてデモ的操作の記事を作成することにした。

サービスは、文字情報からテキスト送信フォームを形成し、登録されたテキストを使って文字だけで連絡を取り合うことができる。

筆者は、例えばエアコンの掃除業者からの電話がテキストメッセージになると良いと感じ、このサービスが役立つと考えている。記事では、具体的な手順を示しながら<a href="https://figreen.org/it/%e3%83%91%e3%82%bd%e3%82%b3%e3%83%b3%e3%82%84%e3%82%bf%e3%83%96%e3%83%ac%e3%83%83%e3%83%88%e7%ab%af%e6%9c%ab%e3%81%8b%e3%82%89%e3%82%b9%e3%83%9e%e3%83%9b%e3%81%b8sms%e3%80%81%e3%82%b7%e3%83%a7/" target="_blank">→続きはこちら</a>
C++コンパイラがgccかclangかそれ以外かをコード側から判別して条件分岐


共通ライブラリを提供したいのに、GCCコンパイラだけの仕様とか、Clangコンパイラにバグがあるとか、色々な理由でコンパイラごとにコードを分けたい場合がありました。その場合の対策です。

```c++
#ifdef __clang__
  // Clang compiled code
#elif defined __GNUC__
  // GCC compiled code
#elif defined _MSC_VER
  // Microsoft Visual C++ compiled code
#else
  // Others
#endif
```

ところで、GCCとそれ以外でコードを分けたい場合は、__GNUC__の判別だけではだめなので（Clangでも__GNUC__は定義されている）、次のようにすると出来ます。

```c++
#if !defined(__clang__) && defined(__GNUC__)
// GCC compiled code
#else
// Others
#endif
```


参考記事：
https://gist.github.com/treastrain/483a2d233560dc99fda8e59b6fd03361
https://qiita.com/D-3/items/b98b63c2629496856654
https://secret-garden.hatenablog.com/entry/2015/07/17/000000
https://qiita.com/naohikowatanabe/items/a4e1a3f8080210257a42
競技プログラミングの鉄則 A10 - Resort Hotel

# 記事概要
競技プログラミングの鉄則 演習問題集のA10のとりあえず動くコードと説明．

# 注意
アルゴリズム初心者が書いてます．時間内の動作は確認してますが、必ずしも最適解ではないです．

# とりあえずコード
~~~c++:A10_main.cpp
//////////////////////
// A10-Resort Hotel //
//////////////////////

#include <iostream>
#include <vector>
#include <algorithm>

using std::vector;

int main(void)
{
	//============================== 入力 ==============================//
	
	// 部屋数の入力
	int N;
	std::cin >> N;

	// 部屋ごとの収容人数の入力
	vector<int> room_capacity(N + 1);   
	room_capacity[0] = 0;
	room_capacity[0] = 0;				// 使わない部分は0で初期化
	for (int i = 1; i <= N; ++i) {
		std::cin >> room_capacity[i];
	}

	// 期間の入力
	int D;								// 期間
	std::cin >> D;

	// 工事範囲の入力(L：範囲の先頭 R：範囲の後尾)
	vector<int> L(D + 1), R(D + 1);
	for (int i = 1; i <= D; ++i) {
		std::cin >> L[i] >> R[i];
	}

	//=============================== 計算 ==============================//
	vector<int> P(N + 1), Q(N + 1);
	
	// Pを計算
	// Pの説明
	// P[i]は、部屋の収容人数の配列で、先頭から位置iまでの内の最大値をP[i]に格納する．
	P[1] = room_capacity[1];
	for (int i = 1; i <= N; ++i) {
		P[i] = std::max(room_capacity[i], P[i - 1]);
	}

	// Qの計算
	// Qの説明．
	// Pと同様だが、こっちはQ[i]に収容人数の配列の最後尾から位置iまでの内の最大値を格納する．
	Q[N] = room_capacity[N];
	for (int i = N - 1; i >= 1; --i) {
		Q[i] = std::max(room_capacity[i], Q[i + 1]);
	}

	// 答えの計算
	// 計算方法の説明
	// 使用可能な部屋を○、工事中の部屋を●で表すと、ある日Dのとき、
	// ○○○●●○○○○
	// のような配列の内、○の範囲内の最大値を調べたい．というのがA10の問題の趣旨である．
	// ここでPとQはそれぞれ位置iに左から、右から見ていった時の最大値を格納している．
	// つまり、○と●の境界の○の位置のPとQを調べ、比較した内の大きい方がある日Dの使用できる部屋の収容人数の最大値になる．
	vector<int> ans(D + 1);
	for (int i = 1; i <= D; ++i) {
		ans[i] = std::max(P[L[i] - 1], Q[R[i] + 1]);
	}

	//============================== 出力 ==============================//
	for (int i = 1; i <= D; ++i) {
		std::cout << ans[i] << std::endl;
	}
}
~~~

# コード説明
コメントにほとんど書いていますが、説明．
配列Pは、部屋の収容人数room_capacityを先頭から見ていったとき、位置iまでに現れる最大値をP[i]に格納します．(なのでPの計算でP[i-1]とroom_capacity[i]の内大きい方をP[i]に格納いている)
同じく配列Qには、room_capacityを最後尾から見ていったとき、位置iまでに現れる最大値をQ[i]に格納する．
![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305871/f0b27e4c-52b3-e52b-cc04-0f8e7878e639.png)


この問題は、下の図で白丸を使用可能な部屋、黒丸を工事中の部屋としたとき、白丸である2つの範囲内の最大値を調べたいというものである．ちょっと言い方を変えると、「先頭からL-1番目まで」と「最後尾からR-1番目まで」の範囲の内の最大値が欲しいということである．
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305871/42a77e27-2a7f-ec35-bc2b-5b0b24e90475.png)


ここでさっきのPとQを使う．P[L-1]には「先頭からL-1番目まで」の内の最大値が格納されており、Q[R-1]には「最後尾からR-1番目まで」のうちの最大値が格納されている．
つまり、P[L-1]とQ[R-1]のうち大きい方が、ある日Dの使用可能な部屋の最大の収容人数となる．

# 終わりに
最初の方は結構力ずくでどうにかなってましたがA10になってくときついですね．
あと、この手法になんか名前があったら教えてください．
事業企画での気づき＜ジーズ1ヶ月経過＞


本記事は私が感じた3つのことを備忘録として書きます。
新規事業の企画で悩まれている方、今後ジーズに入学を考えている方にとって参考になると嬉しいです。

<h2>①WHO（サービスの想定対象者）が身近にいる場合は、とにかく聞きに行く。

よく語られていることだが、自分のことになると全くできていなかった。
ジーズのチューターの方に、やりたいサービスの方角について話したときに
「デプスやってみたら？」って言われて、やってみた。

なにか見つかば！って思って、早速その週に実行をしてみた。
結果は発見がたくさんあった。
むしろ自分はWHOのことを理解していると思ってしまっていたので、大反省。

WHOに聞いた結果、様々な発見があった。
今回の自分の場合は、むしろ「自分がWHOの課題を作ってしまっていたんじゃないか」って思うような内容だった。
思いが強ければ強いほど、「自分は気持ちをわかっている」という罠にハマりやすいので特に自分は注意する。

またチューターの方に「デプスはしっかり録音して、何回も聞くんだよ」というアドバイスも頂いていたので、実践してみた。
自分は風呂の中でジップロックに携帯を入れて聞くことにした。

繰り返し聞いていくうちにWHOの感情がよりイメージできるようになった。
現場で聞くだけでは、言葉ばかりに考えが及んでしまうが、録音でくり返し聞くと感情に考えが及ぶようになる。

「WHOの感情をトレースするくらい理解する」

新規事業のプロが言っていた気がする。
まだまだ自分は理解できていないことばかりだけど、一つ進めた気がする。

<h2>②全員を救おうとしない。

これも自分が陥った罠の一つだ。
デプスインタビューのおかげで、その1人の感情はかなり理解できた。

しかしその結果、これってむしろ自分が悪いことをしちゃっているのかもと思った。
これまで自分が熱を捧げてきたことが馬鹿みたいで、喜劇みたいで虚しくなった。
何のために自分は走ってきたんだ？
そんな感情が立ち込め、プログラミングにも身が入らなくなった。

そうして時間を過ごしているうちに、焦りが出てきた。
Twitterで嘆いていると、ジーズの仲間からありがたい言葉をもらった。
（本当にみんなありがとう…！！）

それが「全員を救おうとしなくて良いんじゃない？」って言葉だった。
すべてを救えるサービスなんで存在しなくて、究極同じ人だったとしても
状況やタイミングによって、その人にとってのサービスの価値は変わる。

「少しでも自分の手によって救われる人がいるなら、それで大成功だよね。」
そんなありがたい言葉ももらった。

この言葉のおかげでもう一歩足を踏み出せそうな気がする。
ジーズの仲間には本当に感謝しかない。


<h2>③自分のエゴを過信する。

これも同じ仲間からもらった言葉だ。
ジーズの児玉先生もおっしゃっていた。

「結局、自分たちが作ろうとしているサービスなんて求められているわけではない。
どうしようもなくしてあげたいくらいの、社会に対してのおせっかいが事業である。」

そんな言葉だった。

自分のエゴを通して、世界を変える。
そうするためにこの6ヶ月取り組もうと思う。

<h2>最後に

ジーズに入学して1ヶ月経過したわけだが、正直早かったと感じる。
だが自分の現状には満足をしていない。

挫けそうなタイミングも何度もあったが、仲間に支えられた。

明日からはそんな仲間に自分も返していけたらと思う。
まずは自分が持っている情熱から。

明日も一歩踏み出していく。
【Tableau】DATASaber:HandsOn - Fundamental(Ord1) Q1 解説

tableau datasaberになるための技術力に関する問題を解いていきたいと思います。
こちらの問題はtableauを始める方にぴったりだと思いますので、ぜひチャレンジしてみてください！
使用するデータは、「サンプル - スーパーストア.xls」を使用する。:arrow_down:
https://drive.google.com/drive/u/0/folders/1kXSb3fqPTt3VcPjGUSgOmrztlRfvvpMH

:white_check_mark:ord1-Q1
・サブカテゴリ「バインダー」は事務用品内で売り上げ何位ですか？

①まず売上は何位ですかと聞かれているので、売り上げを行に入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/84c19df1-f76f-d212-b85b-af0d645f3a32.png)

②サブカテゴリ「バインダー」は事務用品内で売り上げ何位ですか？という問いなので、
　事務用品というカテゴリの中のバインダーというサブカテゴリの売り上げを知る必要があるので、
　列に、カテゴリとサブカテゴリを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/30a349af-0a24-df72-7e6f-66703c9cff29.png)

③最後に売上第何位かを求めるために、降順にしていきたいと思います。
　売上軸の隣にある階段のマークを押下、もしくは、ツールバーから並び替えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/d75d1a39-0e30-d5ef-5612-c76463928d53.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/19728468-ccd8-23b4-4216-0aef53569ef6.png)

よって、バインダーが事務用品内で売り上げ何位かがわかるかと思います。
【GAS無し】Googleスプレッドシートで毎日の担当者を自動で割り当てるシートを作成する

# やること
「$n$人のメンバー表から順番に今日の当番を割り当てる（ただし休日はスキップする）」ようなシートを作成します。

サンプルは以下にアップロードしてあります。
ローカルにコピーし、メンバー部分を編集することで、そのまま利用できます。
ただし、このサンプルでは祝日を考慮していません（祝日を考慮する方法は最後に解説します）。

https://docs.google.com/spreadsheets/d/1UkXQhF6hKfLV3BO6uZ0GW5lcDOc0UMqhcwfwTDGeIYE

# 解説
サンプルシートは以下の要素で成り立っています。

1. 基準日からの経過営業日数計算
1. 1をメンバーに割り当てる変換

以下、それぞれ解説していきます。

## 1. 基準日からの経過営業日数計算
この値はサンプルシートのA, B列で計算しています。
基準日は、シートの運用開始日時より過去であれば何日が入っていても大丈夫です。

| |A|B|
|:----|:----|:----|
|**1**|基準日|基準日からの経過営業日数|
|**2**|2023/4/1|`=NETWORKDAYS(A2, today())`|

ここで肝となるのが`NETWORKDAYS`関数です。
この関数は、開始日から終了日までの土日を除いた日数を返してくれます。

https://support.google.com/docs/answer/3092979?hl=ja

祝日を考慮する場合については最後に解説しています。

## 2. 1をメンバーに割り当てる変換
この変換を行なっているのがG列です。

| |...|G|
|:----|:----|:----|
|1|...|今日の担当者|
|2|...|`=INDIRECT("D" & (mod(B2, E2) + 2))`|

ここで肝となるのが`MOD`関数です。
サンプルシートの`mod(B2, E2)`の部分では、「基準日からの経過営業日数をメンバー数で割った余り」を計算しています。
今回はメンバー数が3なので、この値は0, 1, 2のいずれかになります。

`+ 2`の部分は、メンバー列が2行目から始まることに合わせるためのオフセットです。

# おまけ: 祝日を考慮する方法について
`NETWORKDAYS`関数の第3引数には、祝日（祝日としてみなす）期間を入力することができます。
サンプルを祝日考慮版にするためには、以下の作業が必要です。

1. 基準日を`=year(today()) & "/01/01"`（今年の1月1日）に変更する
1. 祝日シートを作成し、`=NETWORKDAYS(A2, today(), 作成した祝日の範囲)`と変更する

基準日を変更しているのは、過去分の祝日全てを保持しなくてもいいようにするためです。
ただし、これを行うと年末年始で当番がズレる点に注意が必要です。

祝日シートの作成方法は以下を想定しています。

https://qiita.com/wrongwrong/items/1c235ea33e254580ff45
UnityでAndroid向けにビルドする時、ワイヤレスデバッグしたら便利だった

# 環境
- M1 Mac 12.6.2
- Unity 2021.3.22f1
- Pixel4a(5G) Android13

# 困った
Unityもアプリ開発もはじめて3時間の初心者です。
Unityで開発したアプリをAndroid実機向けにビルドして実行する時、たまたま手元にPDケーブルしかなくてMacと接続できなくて困った。

# 解決策
Androidのワイヤレスデバッグを使った。
Wi-Fi経由で無線で無事ビルドと実行ができてハッピーだったのでメモする。

### 手順
#### Androidの操作
1. 設定→デバイス情報→ビルド番号を連打して開発者になる
1. 設定→システム→開発者向けオプション→ワイヤレスデバッグをON
1. ワイヤレスデバッグ→ペア設定コードによるデバイスのペア設定で[6桁のコード]と[IPアドレスとポート]を確認

#### Macの操作
1. Androidと同じWi-Fiに繋ぐ
1. ターミナルで`adb pair [IPアドレスとポート]`と打つ
1. `Enter pairing code:`と言われるので、`[6桁のコード]`を入力
1. `Successfully paired to 192.168.x.x:x`とか出たら成功

#### Unityの操作
1. `Build And Run`する
1. 無線で実行できる！

#### その他
adb入れるの面倒だったので、Unityのやつを使った
パスは以下
`/Applications/Unity/Hub/Editor/<Unityのバージョン>/PlaybackEngines/AndroidPlayer/SDK/platform-tools/adb`
【Docker】WindowsでDockerDesktopを使わずにdockerを利用する方法

開発環境の構築でdockerが必要なんだけど、DockerDesktopを商用利用する場合は有償となってしまったため代替手段が必要になったのでその時のメモ

TL;DR
WSL2経由でDockerCEを使えば解決すると思う。
[WSL を使用して Windows に Linux をインストールする](https://learn.microsoft.com/ja-jp/windows/wsl/install)

Hyper-Vを有効化してWindowsを再起動をする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89244/284588c6-9611-59ad-35e0-fecca30b5994.png)

再起動後、管理者権限でPowerShellを開き下記コマンドを実行する。

```
PS C:\Users\masas> wsl --install -d ubuntu
```

Ubuntuの画面になったらUnixユーザとパスワードを設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89244/e6bd352f-f084-99b4-3e33-0661b963bddf.png)

Ubuntu用のインストール手順を参照しdocker-ceをインストールする。

```
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

amd64のバージョンの手順でリポジトリを登録する。

```
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89244/b18779e1-0ea3-34e5-2108-d735c4a26428.png)

apt パッケージ・インデックスを更新する。

```
$ sudo apt-get update && sudo apt-get install docker-ce
```

ここまででDockerの設定はOK

WSL2のUbuntuでdocker-ceを起動しようとすると、Iptablesでブロックされるみたいなのでlegacy版に変更をする。


```
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
```

Dockerをserviceコマンドで起動する。

```
$ sudo service docker start
 * Starting Docker: docker                                                                           [ OK ]
$ sudo service docker status
 * Docker is running
```

Dockerデーモンがちゃんと起動しているかを確認するため、hello-worldのコンテナを起動する。

```
$ sudo docker run hello-world
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89244/a5074ea2-d214-d5b8-a8bd-d1b98ff83582.png)


参考リンク

https://learn.microsoft.com/ja-jp/windows/wsl/install

https://docs.docker.jp/engine/installation/linux/docker-ce/ubuntu.html#docker-ce

https://github.com/WhitewaterFoundry/Pengwin/issues/485#issuecomment-518028465

https://zenn.dev/taiga533/articles/11f1b21ef4a5ff
音楽再生システムを作ってみた 音楽再生機能 設計編

# 1. 今回のやりたいこと
音楽再生システムを作ります。
これを実現するためには、下記4つの機能が必要になります。
* 表示機能
* ダウンロード機能
* 音楽受信機能
* 音楽再生機能

詳細については下記リンクを参照ください。
[音楽再生システムを作ってみた (前編)](https://qiita.com/hcuymitoh/items/914df0504a8a5bbb0685)

本記事では、音楽受信機能と音楽再生機能の設計編に関する内容を記載します。

# 2. 音楽受信/再生機能

音声データのフォーマットはWAVファイルとし、BlueTooth経由で受信します。BlueToothデバイスには、HC-06を使用します。（HC-06の詳細については[KOZOS上で超音波センサのデータを周期的にPCへ送信してみた (設計編)](https://qiita.com/hcuymitoh/items/5bea7f9bed80ff842ea2)を参照ください）

音楽受信/再生機能のソフトウェア構成図を以下に示します。
下記図の左半分が音楽受信機能、右半分が音楽再生機能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/6df5abd4-346c-8ede-aef2-c03a78ab75f3.png)

次章から、各ソフトウェアの説明をします。

### 2.1 音楽受信/再生アプリケーション

改めての説明にはなりますが、音楽データはBlueTooth経由で受信します。BlueToothデバイスとして使用するHC-06の通信インタフェースはUARTであり、その最大通信速度は115200bpsとなっています。音声の仕様としては、1サンプル16bit、モノラル、サンプリング周波数16kHzとなっています。
1サンプルは16bitのため、1サンプルをBlueTooth経由で受信するのに約0.13ms（(1/115200)×16）かかります。1s分の音声を再生するには16000サンプル必要になるため、1s分の音声データを受信するのに約2s(16000×0.13)かかってしまいます。

ある程度連続で音声を再生させたいため、アプリにて音声データをためる必要があります。
音楽データをためるためのバッファ構造を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/efd1bcc7-789a-eaf0-4f06-9a731fcc6063.png)
バッファは2次元配列で定義し、1つ1つのデータが1サンプルに相当します。x方向は160サンプル(10ms分の音声データ)とし、これを1フレームと定義します。今回は、最大3秒分の音声データを格納するようにするため、y方向は300フレームとします。

### 2.2 WAVファイル解析マネージャ
WAVファイルにはヘッダとデータがあります。ヘッダを解析し、WAVファイルと認識した場合は、データを音楽受信/再生アプリケーションへ通知します。

### 2.2 BlueToothデバイスドライバ
BlueToothデバイスを制御するためのソフトウェアになります。
BlueToothデバイスドライバ下記2つのタスクから構成されています。

* __データ受信タスク__
BlueToothからのデータを受信するタスクになります。
データを受信するとWAVファイル解析マネージャへ通知します。

* __データ送信/接続チェックタスク__
BlueToothデバイスと接続状態を管理し、接続されている場合はデータをBlueToothデバイスへ送信します。（ただし、今回はデータ送信は行いません。デバッグ用にATコマンドを送信するときにのみ使用します。）
デバイスとの接続方法については結構調べたため、詳しく説明したいと思います。[KOZOS上で超音波センサのデータを周期的にPCへ送信してみた (設計編)](KOZOS上で超音波センサのデータを周期的にPCへ送信してみた (設計編))でも接続方法について記載しているのですが、今回はより詳細に調査いたしました。
今回、HC-06と使用しているマイコンとは以下のように接続しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/29fa4ac9-6632-f538-0d42-8844ef0830ba.png)
HC-06には、STATE、RXD、TXD、GND、VCC、WAKE UPピンがあります。いろいろ調査したところSTATEピンがデバイスとの接続チェックに使えることがわかりました。
以下に何かしらと接続されているときと接続されていないときのSTATEピンの波形を載せます。
・接続されているときの波形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/74e208c1-98cb-2b7a-6470-2170903ce005.png)
・接続されていないときの波形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782242/8c628d47-96ca-b3a9-a794-6b304df76c05.png)
上記の通り、何かしらと接続されているときは常に3.3V、接続されていないときは約200ms周期でhighとlowを繰り返しています。10ms周期でSTATEピンを確認し、16回連続同じ値であれば”接続された”、そうでない場合は"接続されていない"と判断することとしました。

### 2.3 USARTドライバ
USART通信を行うためのソフトウェアになります。
BlueToothデバイスとはUARTで通信するため、USARTドライバが必要になります。

### 2.4 GPIOドライバ
GPIOの制御を行うためのドライバになります。
2.1のデバイス接続チェックタスクで述べたように、STATEピンで接続状態を確認する必要があるため、GPIOドライバが必要になります。

# 3. 最後に
今回作成したソースコードを下記githubに置きました。
[Nucleo-L4R5ZI_System](https://github.com/Yas-Mi/Nucleo-L4R5ZI_System)
簡単な動作確認しかできていませんので、使用される場合は自己責任でお願いいたします。

次回は、音楽再生機能についての記事を作成する予定です。
Java 条件分岐式

## Javaで主に使用される条件分岐式

### if文
条件分岐を行う処理が出来る。
特徴
・条件式のところには「a == b」、「a != b」のような式を入れる。
・処理文には上の条件式で「true」だった場合に行いたい処理を書く。
　例）System.out.println("AとBは正しいです。")など。
```
if(条件式;){
処理文;
}
```
### if-else文
特徴
・先程のif文に追記として、「else」を書く。
・「else」を書くことで、条件式で「false」だった場合の返しを処理文②に書いて出力することができる。
```
if(条件式){
処理文①;
} else {
処理文②;
}
```
---

### for文
処理を決まった回数繰り返すことができる。
特徴
・変数の初期化のところには「i = 0」のような式を入れる。
・終了条件には「i <= 5」のような式を入れる。
・増減式には「i ++」、「i --」のような式を入れる。
・処理文には繰り返したい処理を書く。
例）System.out.println("表示"+ i +"回目")など。
```
for (変数の初期化; 終了条件; 増減式) {
     処理文;
}
```
### 拡張for文
配列の要素を1つずつ取り出すループを簡単に書くための特殊なfor文
ループ変数や配列の添え字を記述する必要が無いためコードがスッキリする。
特徴
・任意の変数名を設定することができる。
・要素数だけ繰り返したい場合に使用できる。
・for文より簡潔で見やすい。
```
for (要素の型  任意の変数名 : 配列変数名) {
　　　   処理文;
}
```
---
### while文
while文もif文と同様に、処理を決まった回数繰り返すことができる。
特徴
・書き方は基本if文と同じ。

```
while (条件式) {
      処理文;
}
```
### do-while文
while文との違いは、処理を先に行った後で処理するか否かを条件式によって判断する。
特徴
・処理を行った後に処理するかの判断を条件式で行うので、仮に処理文で
例）System.out.println("表示"+ i +"回目")
　のような出力させるコードを書いた場合、条件式でNGが出ても処理を行っているので
　条件式にはカウントされている。（NGの場合、while文より１カウント多い状態）
```
do {
処理文;
} while (条件式);
```
---
### continue文
今の周回の処理を中断して、同じ繰り返しの次の周回に進む。
```
処理文;
continue;
```
### break文
for文やwhile文のループ処理中にbreak文が読み込まれると、処理を中断させる。continue文のように次の周回には進めない。
```
処理文;
break;
```
---
### switch文
式の値が値1のときに処理1、値2のときに処理2、値3のときに処理3がピンポイントで実行される。どれにも該当しない場合は、処理４（default）が実行される。
特徴
・変数のところに代入された値が下の処理で該当するところに行く。
・case 値１の後ろは:(コロン)を書く。
・defaultにはcaseは不要。
・個人的には変数のところには好きな数字を入れたいので、
int 変数名 = new java.util.Scanner(System.in).nextInt();
（好きな数値を入力できるコード）
と併用したい。
```
switch (変数) {
case 値1:
    処理1;
    break;
case 値2:
    処理2;
    break;
case 値3:
    処理3;
    break;
default:
    処理4;
}
```
nvim - windows - C#: スクロールバーを非表示にするコマンドの作成

# windows上でnvimやvimを触っているときに出てくるスクロールバーを消したい

ウィンドウサイズをいじったりするとWindowsのスクロールバーがひょっこりと顔を出す。

特に水平方向のスクロールバーはコマンドが見えなくなるのでやっかいです。

ということで、スクロールバーを削除するコマンドをC#で作成してnvimから呼び出そうという作戦です。

## 環境
OS: windows 10
コンパイラ: Microsoft (R) Visual C# Compiler version 4.8.4084.0
nvim: v0.8.2

今回C#を選択した理由は、ほとんどのwindows環境に標準でインストールされているため、環境構築の必要がないからです。
同様の理由で、Visual Studioを使用せずに手動コンパイル?します。

## 実装

#### 1.書く
忘れたとき用にヘルプも書いときました。
``` C#:hidesb.cs
using System;
using System.Runtime.InteropServices;

class HideSB
{
    // Windows API
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    static extern int ShowScrollBar(IntPtr hWnd, int wBar, int bShow);

    //定数定義
    const int SB_HORZ = 0;
    const int SB_VERT = 1;
    const int SB_BOTH = 3;
    const int SW_HIDE = 0;

    static void Main(string[] args)
    {
        //コマンドライン引数が1つのときだけ続行
        if (args.Length != 1)
        {
            Console.WriteLine("\r\nError: Argument count mismatch.");
            ShowHelp();
            return;
        }

        //コマンドライン引数の値によって処理を分岐
        string option = args[0];
        int target;

        if (option == "-h")
        {
            //水平スクロールバー
            target = SB_HORZ;
        }
        else if (option == "-v")
        {
            //垂直スクロールバー
            target = SB_VERT;
        }
        else if (option == "-b")
        {
            //水平、垂直スクロールバー
            target = SB_BOTH;
        }
        else if (option == "--help")
        {
            //helpを表示して終了
            ShowHelp();
            return;
        }
        else
        {
            //予期しない引数の場合は中断
            Console.WriteLine("\r\nError: invalid argument.");
            ShowHelp();
            return;
        }

        //現在のウィンドウのハンドラを取得
        IntPtr hWnd = GetForegroundWindow();

        //対象のスクロールバーを非表示にする
        ShowScrollBar(hWnd, target, SW_HIDE);
    }

    static void ShowHelp()
    {
        Console.WriteLine("\r\n================= help =================");
        Console.WriteLine("Usage");
        Console.WriteLine("  hidesb [option]");
        Console.WriteLine("Available auguments");
        Console.WriteLine("  -h      hide Horizontal Scroll Bar.");
        Console.WriteLine("  -v      hide Vertical Scroll Bar.");
        Console.WriteLine("  -b      hide Both Scroll Bar.");
        Console.WriteLine("  --help  this help.");
        Console.WriteLine("========================================");
    }
}
```

#### 2.コンパイル
今回はVisual Studioを使わないので、コマンドを叩いてコンパイルすることにします。
バッチを作っておくと楽です。

```:cmd
> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe hidesb.csまでのパス
```

csc.exeが上のパスになかったら、このコマンドで探してみてください。
```:cmd
> dir C:\ /b /s | findstr csc.exe$
```


#### 3.パスを通す
完成した実行ファイルのパスを通して、雑に実行できるようにします。
vimで呼び出すだけであれば、手順4のコマンドを絶対パスで書いても大丈夫です。

#### 4.init.vimにコマンド追加
自分は基本nvimなのでinit.vimです。一応wls上のvimでも動作確認済みです。
お好みでコマンド以外の方法で呼び出しても大丈夫です。

```init.vim
command! HIDESB  :call system("hidesb -b")
command! HIDEHSB :call system("hidesb -h")
command! HIDESVB :call system("hidesb -v")
```

## おわり

見ていただきありがとうございました。
自分はこの方法でスクロールバーを消しましたが、もっと良い方法があったら教えていただけると幸いです。
【Bash】インクリメントする方法

## `expr`

```sh:expr
count=0
while [ $count -lt 10 ]; do
	echo $count
	count=`expr $count + 1`
done
```

```bash
$ bash sample.sh
0
1
2
3
4
5
6
7
8
9
```

## `let`
```sh:let
count=0
while [ $count -lt 10 ]; do
	echo $count
	let count=$count+1
done
```
```bash
$ bash sample.sh
0
1
2
3
4
5
6
7
8
9
```



## `((...))`

```sh:((...))
count=0
while [ $count -lt 10 ]; do
	echo $count
    ((count++))
done
```
```bash
$ bash sample.sh
0
1
2
3
4
5
6
7
8
9
```
AWS

## AWS（Amazon Web Services）

Amazonが提供するクラウドコンピューティングプラットフォーム
AWSを利用することで、ネットワーク、ストレージ、データベース、アプリケーションサービスなどのインフラストラクチャーをクラウド上で提供し、スケーラブルなシステムを構築することができる

## AWSのサービス

- EC2（Elastic Compute Cloud）：仮想マシンを提供するサービス
- S3（Simple Storage Service）：オブジェクトストレージサービス
- RDS（Relational Database Service）：リレーショナルデータベースの提供サービス
- Lambda：サーバーレスアーキテクチャを実現するためのサービス
- API Gateway：APIの管理・公開を行うサービス
- CloudFront：CDN（Content Delivery Network）サービス
【ShellScript】$*と$@の違い

## `$*`と`$@`の違い

クォートしない場合には`$*`と`$@`は同じ挙動になります。  

```test.sh
outputarg() {
  echo "引数の数は $# 個です。"
  echo "第一引数は $1 です。"
  echo "第二引数は ${2:-なし} です。"
}

echo 'クォートなし'
echo '$@'
outputarg $@
echo '--------------------------'
echo '$*'
outputarg $*

```

```terminal
$ bash test.sh 'arg1 arg2' 'arg3 arg4'
$@
引数の数は 4 個です。
第一引数は arg1 です。
第二引数は arg2 です。
--------------------------
$*
引数の数は 4 個です。
第一引数は arg1 です。
第二引数は arg2 です。
```

## `"$*"`と`"$@"`の違い

クォートした場合には`"$*"`は引数が結合され、`"$@"`は引数が渡したとおりに分割されます。

```test.sh
outputarg() {
  echo "引数の数は $# 個です。"
  echo "第一引数は $1 です。"
  echo "第二引数は ${2:-なし} です。"
}

echo '"$@"'
outputarg "$@"
echo '--------------------------'
echo '"$*"'
outputarg "$*"

```

```terminal
$ bash test.sh 'arg1 arg2' 'arg3 arg4'
"$@"
引数の数は 2 個です。
第一引数は arg1 arg2 です。
第二引数は arg3 arg4 です。
--------------------------
"$*"
引数の数は 1 個です。
第一引数は arg1 arg2 arg3 arg4 です。
第二引数は なし です。

```
OpenSearchのTokenizerとフレーズ検索の挙動について

# はじめに
本記事はOpenSearchのTokenizerによるトークン分割とフレーズ検索の挙動について、直感的に分かるよう例を多く使って説明しています。

# Tokenizerによるトークン分割
OpenSearchは文章を保存する際に、Tokenizerによってトークンに分割されてインデックスに保存されます。
Tokenizerは主に「形態素解析」と「N-Gram」の2種類があります。

# 1. 形態素解析(kuromoji)
形態素解析とは、文章やフレーズを最小の意味単位である形態素に分割することです。
下記の文章をkuromojiという形態素解析器によって単語ごとにトークン分割した場合、4つのトークンに分割されます。

**日本一の企業のインターンシップに参加**
- 日本一
- 企業
- インターンシップ
- 参加

※ kuromoji_part_of_speechというToken Filterを使って助詞を排除しています。

# 2. N-Gram
N-Gramとは、文章をN文字ごとに分割することです。
同じく下記の文章をN=2,N=3でトークン分割した場合について示します。

**日本一の企業のインターンシップに参加**

- N=2の場合
日本、本一、一の、の企、企業、業の、のイ、イン、ンタ、ター、ーン、ンシ、シッ、ップ、プに、に参、参加
- N=3の場合
日本一、本一の、一の企、の企業、企業の、業のイ、のイン、インタ、ンター、ターン、ーンシ、ンシッ、シップ、ップに、プに参、に参加

このように、N-Gramによるトークン分割は無駄が多く保存するデータの容量も増えますが後に説明するように利点もあります。

# フレーズ検索
今回はTokenizerに形態素解析を用いて、フレーズ検索の挙動を見てます。
下記の文章に対して、検索を行った場合を考えます。

**日本一の企業のインターンシップに参加**

先の説明でもあったように、これは下記のトークンに分割されて保存されます。
- 日本一
- 企業
- インターンシップ
- 参加

これに対して、様々なワードで検索をしたときの動作を示します。
OpenSearchでは検索するワードに対してもTokenizerによってトークン分割され、トークンで検索がされます。
検索ワード(検索ワードが分割されたトークン)の形式で一覧にします。
#### 例の文章がヒットする検索ワード
- 日本一(日本一)
- 日本一の企業(日本一、企業)
- 企業のインターンシップに参加(企業、インターンシップ、参加)
- 企業にインターンシップで参加(企業、インターンシップ、参加) 

#### 例の文章がヒットしない検索ワード
- 日本(日本)
- インターン(インターン)
- 企業のインターン(企業、インターン)
- 企業の日本一(企業、日本一)
- 日本一のインターンシップ(日本一、インターンシップ)

上記の例のように、フレーズ検索では検索語と同じトークンの順番になっている文章がヒットします。
つまり、「日本一、企業、インターンシップ、参加」の順番に検索語のトークンが並んでいたらヒットします。



「企業にインターンシップで参加(企業、インターンシップ、参加) 」のように、トークンの順番が例の文章と同じなら助詞が異なっていてもヒットします。

逆に、「企業の日本一(企業、日本一)」や「日本一のインターンシップ(日本一、インターンシップ)」のようにトークンの順番が例の文章と異なる場合はトークンが同じでもヒットしません。

また、「日本」や「インターン」で検索しても、「日本一」や「インターンシップ」というトークンとは異なるのでヒットしません。
こういう形態素解析ではうまくいかない場合に、N=2のN-Gramを使っていると「日本」というトークンが作られているので「日本」で検索してもヒットします。

# カスタム辞書とシノニム
N-Gramを使うと容量の増加や検索ノイズの増加などデメリットがあるため、「日本」で検索してヒットさせたい場合は代わりにカスタム辞書やシノニムを使って解決した方が良いと思います。

カスタム辞書とシノニムについてはまた別の記事にしたいと思います。
wixローカルで開発できるらしい(Velo by wix)

# はじめに

多分wix界隈のエンジニアに当たり前なんでしょうけど、ちょっと感動したのでメモとして書きます。
実はwixには開発者向けに「velo by wix」っていう機能が用意されています。
これは簡単に言うとjsを使ってwixの機能だけじゃできない機能をつける開発者向けの機能です。

見栄えだけじゃなくて独自のテーブルを定義して、そのデータを呼び出してブログみたいな機能を独自でつけるようにもできます。
(バックエンドもnodejsでかけるらしい？)

以前触った際、可能性は感じていたんですけど、結局wixだから見栄えの調整がしづらいし、開発する際もローカルで好きなエディターを使って開発できないから、開発者にはあまり流行らないかなーと思って使うのをやめてしまいました。
(見栄えの調整がしづらいっていうのは、スマホにしたときに見出しと説明文の文字が変に被ったりとか)

そんなこんなでwixをしばらく忘れていたのですがcss niteでwixに新しいプロ向けの「editor x」という新エディターが追加されたと見て触ってみました。

## ローカルで開発の流れ

すごく難しい設定があるのかと思ったら簡単にローカル開発ができます。

![test01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/f1992701-d7af-ebdc-d318-164d1ce819e7.jpeg)

↑githubと連携する画面

「editorx」のサイドバーにgithubのアイコンがあって押すと、githubのアカウントと紐付けられてプライベートリポジトリーが作成されます。

リポジトリーが作成されると、wix上にコマンドが表示されるので手順に従って、リポジトリーの内容をcloneします。

うまく行っていれば、「wix dev」コマンドを入力します。
これで自動的にwix上で表示されるjsと紐付けられるようです。

### 参考
https://ja.editorx.com/

https://support.wix.com/en/article/velo-about-git-integration-wix-cli



## 感想
ローカルで開発できるとは思っていなくて「editorx」を開いた時にサイドバーにgithubのロゴがあってもしかしてローカル開発できる？ってなって実際にできて感動しました。

その他にnpmからパッケージもインストールもできるみたいなので、かなり可能性を感じます。
この辺を押すと開発者にも刺さるかも？とか思いました。

![test02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/b5e99dba-6d49-6722-c0dc-e4a6361aa848.jpeg)
ファイルの情報を取得し、自動送信する

## はじめに

`Power Automate` は今までほとんど学習していなかったのですが、
「自動化したい仕事」がありまして、腰を据えて勉強することにしました。
まずは簡単そうなフローから徐々にレベルアップしながら学習していこうと思います。

### 注意

個人のMicrosoft アカウントで作成しているので、コネクタは個人アカウントで使用できるものを使っています。


## やりたいこと

以下のようなイメージのフローを作成したい。
![step1_フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/85be85cf-f33c-4a88-995f-fd6bdae1e2cc.png)

## フロー作成

### トリガー

日時指定のスケジュールをトリガーとする。

### ファイルからキーを取得

テキストファイルにキーを格納。
![参照用テキストファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/c2cef28d-9c04-bbf4-d023-5ec12870d70a.png)

### ファイル（テーブル構造）からキーに紐づく値を取得

Excelブック(xlsx)に、以下のようなテーブルを格納。
![Excelブック_テーブル1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/ba3d72b0-4335-a297-203e-8d158c65e486.png)
※シート2については今回未使用（後述する）

#### ここまでのフロー

トリガー（スケジュール）
-> [ファイルのコンテンツを取得](https://learn.microsoft.com/en-us/connectors/onedrive/#get-file-content)
-> [行の取得](https://learn.microsoft.com/en-us/connectors/excelonline/#get-a-row) 
　　`キー値` にひとつ前の処理から取得したファイルコンテンツを指定する。
![外部ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/7e9e36c8-145f-825c-81b0-a73ce7002eee.png)

### 取得した値を盛り込んだ文章をTeamsなりメールなりで自動送信

個人アカウントだと`Teams` にサインアップできなかった。
![Teamsサインアップエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/d5e7844a-b266-ff1e-6379-2a187fd192a2.png)
> テスト接続に失敗しました。詳細: Failed to get onbehalfof access token: connectionId=teams, message={"error":"invalid_grant","error_description":"AADSTS500200: User account '{EmailHidden}' is a personal Microsoft account. Personal Microsoft accounts are not supported for this application unless explicitly invited to an organization. Try signing out and signing back in with an organizational account. Trace ID: 8d08425b-885c-4178-98b6-355a7f96bb00 Correlation ID: c9ce4664-91a4-43d4-b96a-ff636d024a55 Timestamp: 2023-05-29 14:01:41Z","error_codes":[500200],"timestamp":"2023-05-29 14:01:41Z","trace_id":"8d08425b-885c-4178-98b6-355a7f96bb00","correlation_id":"c9ce4664-91a4-43d4-b96a-ff636d024a55"}

なのでメールを用いる。
-> [メールを送信(V2)](https://learn.microsoft.com/en-us/connectors/outlook/#send-an-email-(v2))

![メール送信.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/3a09136e-72cc-509b-34c7-8253ef989ec2.png)

## 実行結果

実行できた。
![実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/08f2ebb9-54e3-3415-b32c-9feccfe58205.png)


## 断念したこと

Excelブックのシート2からキーを取得しようとしたが、ワークシートの扱いが直感的でなかったので今回は断念してテキストファイルを読み込むことにした。
![Excelブック_シート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/3b78a291-ac71-5eee-ac7f-8129340fecd3.png)

## 今後やりたいこと

* Excelブックのシート2からキーを読み込む
* 自動送信後、キーを +1 する

などなど…

## おわりに

難しいことはせず、シンプルなフローで実現してみました。
次回は変数なども使っていき、徐々にフローを進化させていきたいと思います。
【Python】PAY.JPの導入案と使い方を簡単にまとめたよ

## PAY.JPについて
この前のプロジェクトでPAY.JPを使ったから導入案と使い方について簡単にまとめたぜ
公式ドキュメントが最強だから困ったら↓を確認してくれ
https://pay.jp/docs/payjs

## PAY.JPの導入例
**クレジットカードの入力以外の処理は基本的にバックエンド側のAPIが行う感じが簡単**
こんな感じ↓
1. ユーザー作成(フロント、バックエンドどっちでもよし)
2. フロントでクレジットカードのトークンを作成後、バックエンドのAPIがトークンを受け取りユーザーとクレカの紐付け行う(**カード登録をしなくても決済でトークンを直接使うこともできるよ**)
3. ユーザーが購入ボタンを押した後、APIがユーザー情報と決済金額をPAY.JPに送信

シーケンス的なものはこちら
```plantuml

participant user #FC9A88
participant Web #FDF1E1
participant API #BDE7E6
participant PAYJP #7DC6C8

== ユーザー作成 ==
user -> Web ++ : 登録情報入力
    alt APIを経由する場合
        Web -> API ++ : ユーザー作成
            API -> PAYJP ++ : ユーザー作成
            PAYJP -> API -- : OK
        API -> Web -- : OK
    else API経由しない場合
        Web -> PAYJP ++ : ユーザー作成
        PAYJP -> Web -- : OK
    end
Web -> user -- : 登録完了

== クレジットカード登録 ==
user -> Web ++ : クレジットカード情報入力
    Web -> PAYJP ++ : カードのトークン化
    PAYJP --> Web -- : トークン返却
    Web -> API ++ : カード登録
    rnote over Web,API #97EECC: ユーザー情報とトークンを送信
        API -> PAYJP ++ : カード登録
            PAYJP -> PAYJP ++-- : ユーザーとカードの紐付け
        PAYJP --> API -- : OK
    API --> Web -- : OK
Web --> user -- : カード登録完了

== 決済 ==
user -> Web ++ : 商品購入
    Web -> API ++ : 商品購入
    rnote over Web,API #97EECC: ユーザーID、金額を送信
        API -> PAYJP ++ : 決済
        PAYJP -> API -- : OK
    API -> Web -- : OK
Web -> user -- : 購入完了
```

## PAY.JPの導入
pythonの場合はpipで入れるだけです
```
$ pip install payjp
```

## 使い方
詳しいことは↓
https://pay.jp/docs/api/
**クレジットカードのトークンは一度使用すると使えなくなるから注意**
```python
import payjp

# APIキーのセット
payjp.api_key = "API_KEY"

# ユーザー作成
# idには100桁までの一意な文字列を指定可能。
# 未指定時はcus_で始まる32桁までの一意な文字列が自動生成される
payjp.Customer.create(
    id = "適当なユーザーID",
    email = "test@example.com"
)

# カード紐づけ
customer = payjp.Customer.retrieve("ユーザーID")
customer.cards.create(
    card='フロントで作成したカードトークンを入れる'
)

# カード情報取得
customer = payjp.Customer.retrieve('ユーザーID')
card = customer.cards.retrieve('カードID')

# 決済
charge = payjp.Charge.create(
    amount = "金額",
    customer = "ユーザーID",
    card = "カードID or カードのトークン",
    currency = "jpy",
)
```

## 感想
ドキュメント分かりやすいし簡単だしめちゃええ
Spring BootにおいてのWebのアーキテクチャについて

# 初めに

去年の現場で１年間、初めてJavaのSpring Bootを体験。

その際に、ただDB取得や業務処理を作成するだけではなく、これから紹介するWebのアーキテクチャの各役割を意識して、作成する必要があるということを学びました。

現場で作成をする中で学んだため、復習の意味も込めて、
今回、基本的な概念だけですが、共有いたします。

# Webのアーキテクチャ ３層のイメージ図

![スクリーンショット 2023-05-29 23.12.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583781/7cf0ebd6-af9a-dd14-826d-a1c14ceeaa86.png)

# 各層の役割について

## ①Application Layer（アプリケーションレイヤー）

【Controller】の役割
・主にクライアントとサービスを繋ぐ処理を行う！
・クライアント側からまず呼ばれる層。
・クライアントからのリクエスト値を受け取り、【Service】に値を橋渡し、
　最終的には【Service】から返ってきたレスポンス値をクライアント側に返す。
・バリデーションチェックなども行う。

## ②Domain Layer（サービスレイヤー）

【Service】の役割
・主に業務処理を行う！
・【Controller】側から渡された値に対して業務処理を行う役割。
・業務処理を実行した値を【Repository】に橋渡し、最終的に
　【Repository】から返ってきたレスポンスを【Controller】側に返す。
・値の加工や計算処理や変換形などは、すべてここで業務処理として行う。

## ③ Infrastructure Layer（インフラストラクチャレイヤー)

【Repository】の役割
・主にDBに対してCRUD処理を行う！
・【Service】より受け取った値を元に、SQLにバインドさせ、DB処理を実施。
・MyBatisなどを用いて、CRUD後に結果として取得した返したいテーブルデータを、
　テーブルモデルに設定して、【Service】側に返す。

# まとめ

・これら３層に分けることにより、各層での適切な役割を行い、Webのアーキテクチャを保つことができます。

・これまでやってきている２案件ではJavaのSpring Bootではこれら３層のアーキテクチャに準じていたので、わりかしJava現場では覚えることは必須かと思われます。

・Spring Boot以外でもアーキテクチャとして考え方は、紹介されているサイトを見たことあるので使用されると思われます。

# おわりに

これらのアーキテクチャごとの受け渡しやDB接続を行う際には、
以下の自動生成機能を用いることで、
【Repository】内でのデータモデル、SQLの自動生成、リクエストボディ、レスポンスの定義を作成可能です。（実際に現場でも使いました。）

・OpenAPI generator
　（OpenAPIを用いて、リクエストとレスポンスやController内の呼び出し用のメソッドの自動生成）

・Mybatis Generator
（Repository内で使用するDBからのデータモデルや基本的なCRUDのSQLを定義したXMLの自動生成）

上記は現在学習中のため、６月中に実例とともに記事をあげます。
PHPコマンドが使えない...

## エラー

```bash
% php -v
dyld[12345]: Library not loaded: /opt/homebrew/opt/icu4c/lib/libicuio.69.dylib
  Referenced from: <12345678-1234-1234-1234-123456789012> /opt/homebrew/Cellar/php@7.4/7.4.27/bin/php
  Reason: tried: '/opt/homebrew/opt/icu4c/lib/libicuio.69.dylib' (no such file),
```

## 解決手順

:::note warn
この記事では、icu4cのバージョン69が必要となっているので、それをインストールします。
また、`yourname`としている部分は、好きに変更して問題ありません。
また、ディレクトリ構成も環境により多少変わる場合があります。
:::

### 1. タップを作成

タップとは、Homebrew経由で外部のパッケージを参照するための機能

:::note info
ざっくり言えば、brewコマンドでinstallなどができないもの(前のバージョンのパッケージなど)をできるようにするためのもの
:::

https://docs.brew.sh/Taps

```bash
brew tap-new yourname/taps
```

### 2. タップに展開

```bash
brew extract icu4c yourname/taps --version 69
```

### 3. タップを使いインストール

```bash
brew install yourname/taps/icu4c@69
```

### 4. シンボリックリンクを貼る

自分の解釈としては、インストールしたファイルに紐づけられたファイルを置くみたいな感じ。
(`icu4c@69`の直下にあるファイルを`icu4c`の直下にあるようにする)

```bash
# ディレクトリ移動
cd /opt/homebrew/opt/icu4c/lib
# バージョン確認
ls ../../../icu4c@69
  # ↓↓↓ こんな感じに出力されるはず ↓↓↓
  # 69.1
# シンボリックリンクを貼る(先ほどの69.1を使う)
ln -s ../../../icu4c@69/69.1/lib/libicuio.69.1.dylib libicuio.69.dylib
ln -s ../../../icu4c@69/69.1/lib/libicui18n.69.1.dylib libicui18n.69.dylib
ln -s ../../../icu4c@69/69.1/lib/libicuuc.69.1.dylib libicuuc.69.dylib
ln -s ../../../icu4c@69/69.1/lib/libicudata.69.1.dylib libicudata.69.dylib
ln -s ../../../icu4c@69/69.1/lib/libicutest.69.1.dylib libicutest.69.dylib
ln -s ../../../icu4c@69/69.1/lib/libicutu.69.1.dylib libicutu.69.dylib
# シンボリックリンクが貼れたかの確認
ls -l . | grep 69.dy
  # ↓↓↓ こんな感じに出力されるはず ↓↓↓
  # abcde-xy-x  1 yourname  admin     48  5 29 12:00 libicudata.69.dylib -> ../../../icu4c@69/69.1/lib/libicudata.69.1.dylib
  # abcde-xy-x  1 yourname  admin     48  5 29 12:00 libicui18n.69.dylib -> ../../../icu4c@69/69.1/lib/libicui18n.69.1.dylib
  # abcde-xy-x  1 yourname  admin     46  5 29 12:00 libicuio.69.dylib -> ../../../icu4c@69/69.1/lib/libicuio.69.1.dylib
  # abcde-xy-x  1 yourname  admin     48  5 29 12:00 libicutest.69.dylib -> ../../../icu4c@69/69.1/lib/libicutest.69.1.dylib
  # abcde-xy-x  1 yourname  admin     46  5 29 12:00 libicutu.69.dylib -> ../../../icu4c@69/69.1/lib/libicutu.69.1.dylib
  # abcde-xy-x  1 yourname  admin     46  5 29 12:00 libicuuc.69.dylib -> ../../../icu4c@69/69.1/lib/libicuuc.69.1.dylib
```

### 5. 動作確認

```bash
% php -v
```
【雑論①】ViT(Vision Transformer[ICL2021, Google Reserch])

# 序論
Motoです。メーカー研究職勤務。
継続学習のモチベーション維持法の１つとしてQiitaにoutputしていくことにしました。
目標は年間100投稿。つまり月7-8投稿、週2投稿を目安として頑張っていきたいです。
質ももちろん大事ですが、気にしだすと結局やらない。。というのが私の特性なので
雑でもいいからとにかくやる！という意識で雑に論文を読んでいく【雑論】というハードルを下げたタイトルにしてみました。未来の自分に祈る！！怠惰な自分頑張れ！

# [本日の論文Title]：An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
URL：https://arxiv.org/abs/2010.11929
論文読み時間：1H
←論文難易度の指標にならないかを個人的にメモしてます


## １．どんなもの？
・NLP（自然言語処理タスク）のデファクトスタンダードともなってきてTransformerを画像認識に応用した研究
・事前学習を利用すると、最新のCNNに匹敵する性能

## ２．先行研究と比べてどこがすごい？
・これまでTransformerを画像に適用すると精度がでなかったりしたが、
  一般的なTransformerをできる限りそのままの形で画像に適用することを提案し高い精度を達成した点

## ３．技術や手法のキモはどこ？
・**画像をgrid上に分割し、それぞれの画像パッチをTransformerでいう単語のように見なして入力とした点**
・TransformerのEncorder＋Headといったアーキテクチャで実現
・大規模データセットで学習させた事前学習モデルを小規模データセットを用いたタスクにてfine tuneingすると精度が出る点
・ ViTが大きなモデルであるほど大きなデータセットでの事前学習の効果が強く表れる
   →**事前学習とfine tuningが高精度のキモ**

↓ViTのアーキテクチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742915/f9380221-caa9-3928-1c8d-2cf46782003d.png)

## ４．その他、工夫や得られた知見（細かいところ）
　　・ 画像パッチは1次元化された後、Position Embedding（位置エンコーディング）されて入力とされる
　　・同じ行・列の位置エンコーディングの類似度は似るように学習されている
　　・位置情報に加えて分類タスクの場合、先頭に[class]をEmbeddingする
　　  →パッチ埋め込みと呼ばれる
　　・オリジナルのTransformerとの差分は、Normの位置と活性化関数GELUを採用した部分
　　・CNNは下位層で局所的、上位層で大域的な特量表現を得ることが知られているが、
　　　ViTでは下位層で局所的＋大域的な特量表現、上位層で大域的な特量表現を得ている
　　　→逆に言えば、ViTは層を重ねても異なる表現を獲得しにくいとも捉えられる
　　・局所的な表現は特に重要で、これが行われていないと性能の劣化が顕著に起こる
　　　→CNNのパフォーマンスは下位層でしっかりと局所的な特量表現を得ることができているから実現するという解釈になる
　　・ハイブリット・アーキテクチャとして画像パッチをCNNで畳み込んで得られた特徴マップに変換したのちに入力するアイディアもアリだとされている
　　・ViTのモデルサイズが小さい場合にCNNとのハイブリット型の効果が大きく出るが、モデルサイズが大きい場合は効果は小さくなる　　
　　・ViTにおけるスキップコネクションは重要であることも示されている
　　・ViTの空間情報はある領域に集中しているが、CNNは幅広い領域に拡散していて情報がぼやける傾向にあることがわかる
　　・ViTはメモリ効率がCNNよりも優れている　　
　　・事前学習よりもfine tuningの際の解像度を大きくするとよい
　　・パッチのサイズは事前学習とfine tuningで一定
　　・fine tuning時に足りない位置エンコーディングは内挿で補完

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742915/2d76c72d-6268-c91b-e801-49611c3e5a95.png)


## ５. 議論はある？
・事前学習について、ViTのfew-shot特性をさらに分析すると有望（本論文では十分に言及されていないから）
・ViTで最適化されていない部分は、パッチ抽出と解像度調整（事前学習の解像度とギャップができる場合に行うべき）であるとされている
・メモリ効率が良いが、Attentionの計算複雑度O(N^2)がボトルネック
　　
## ６．感想
・メモリ効率は良いとのことだけど実際エッジに乗せると速度はどうなるんだろうと思いました。
　（組み込んでみて同じくらいの規模のCNNと比較してみたい）
・事前学習の影響が高いということで、自己教師系の事前学習手法は要チェックだなと思いました。
・結果の示し方が面白くて参考になるなと思いました。（Size of attended area by head and network depthの表とか）
jupyter notebook上にあるフォルダをローカルにダウンロードする

1. 以下を実行する。
```
!zip -r ローカルでのファイル名 jupyter上にあるフォルダ名
```

2\. zipファイルが生成されているのでダウンロードする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659845/ed80f6cf-2e94-68f0-f705-e31edb33dfba.png)

参考：https://yshr10ic.hatenablog.com/entry/2019/03/10/190103