OmniAICreator/Qiita-1.07M huggingface dataset:
ABC208 C - Fair Candy Distribution を解いてみた

https://atcoder.jp/contests/abc208/tasks/abc208_c

![abc208_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/e065d600-360c-43ec-9cb1-497ec7c0daa7.png)
![abc208_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/02f3425e-2c14-586f-0b43-732a0b3a556e.png)
![abc208_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/74a02752-53c2-263e-d245-db7c8e366f68.png)

辞書を使うと簡単かも。

```abc208c.py
def solv():
    N,K = map(int,input().split())
    A = list(map(int,input().split()))
    dic = {}
    for i in range(N):
        dic[A[i]] = K//N

    A.sort()
    for j in range(K%N):
        dic[A[j]] += 1

    for key in dic.keys():
        print(dic[key])

solv()#302ms
```

配列を使った場合の記述もできた方がいいかも

```abc208c.py
def solv():
    N,K = map(int,input().split())
    A = list(map(int,input().split()))
    lis = []
    for i,a in enumerate(A,1):
        lis.append([i,a,K//N])
    lis = sorted(lis,key=lambda t:t[1])

    for j in range(K%N):
        lis[j][2] += 1
    lis = sorted(lis,key=lambda t:t[0])

    for a,b,c in lis:
        print(c)

solv()#492ms
```
[Rails] 退会機能(論理削除)

ポートフォリオに実装した退会機能のメモです。

# 実装
### Userモデルにカラムを追加
Userが退会済みかどうかを判断するためのbooleanカラムを追加していきます。
ちなみにUserモデルは`devise`で追加したことを想定しています。

```terminal:ターミナル 
rails g migration AddIsValidToUsers is_valid:boolean
```

```ruby:db/migrate/20210617022549_add_is_valid_to_users.rb
class AddIsValidToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :is_valid, :boolean, default: true, null: false
  end
end
```
```terminal:ターミナル 
rails db:migrate
```

### 退会処理
退会画面と退会処理を作っていきます。

```ruby:config/routes.rb
get '/accounts/:id/unsubscribe' => 'accounts#unsubscribe', as: 'unsubscribe'
patch '/accounts/:id/withdrawal' => 'accounts#withdrawal', as: 'withdrawal'
```
退会画面を表示する画面用のgetリクエストの`unsubscribe`と先程作成したUserカラムのbooleanを更新するpatchリクエストの`withdrawal`のルーティングを作ります。

続いてController

```ruby:app/controllers/accounts_controller.rb
def unsubscribe
  @user = User.find(params[:id])
end

def withdrawal
  @user = User.find(params[:id])
  @user.update(is_valid: false)
  reset_session
  flash[:notice] = "退会処理を実行いたしました"
  redirect_to root_path
end
```
`unsubscribe`では`user_id`を取得
`withdrawal`では退会のためのbooleanを更新して退会したらroot_pathに飛ばしているだけです。

次にviewです。

```haml:app/views/accounts/unsbscribe.html.haml
.container 
  %h2 退会お手続き
  %p
    退会手続きをされますと、全てのサービスがご利用いただけなくなります。
    %br
    再度ご利用をいただく場合には、新規登録のお手続きが必要になります。
    %br
    本当に退会してよろしいですか？
  = link_to "退会する", withdrawal_path, method: :patch, data: { confilm: "本当に退会しますか？" }
  = link_to "退会しない", root_path
```
退会するを押したらlink_toで先程のControllerの`withdrawal`アクションに飛んでbooleanを更新する流れです。

### 退会ユーザーはログインできなくする
退会したらログインできなくしていきます。

```ruby:app/models/user.rb
def active_for_authentication?
  super && (is_valid == true)
end
```
モデルに制約を設定します。

```ruby:app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
   protected

  def reject_user
    @user = User.find(params[:id])
      if @user 
        if @user.valid_password?(params[:user][:password]) &&  (@user.active_for_authentication? == true)
        redirect_to new_user_registration
      end
    end
  end
end
```
Controllerで退会済みUserはログインできなくしていきます。
`valid_password?`でパスワードが正しいかどうか、
`active_for_authentication? == true`で先程設定したモデルの制約がtrueの場合はログインせずログインページにリダイレクトされるようにしています。

これで完成です。

# 参考

https://blog.edwardkenfox.com/post/90435229476
ABC200 C - Ringo's Favorite Numbers 2 を解いた

https://atcoder.jp/contests/abc200/tasks/abc200_c

![abc200_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/8fd1b3c4-234b-1c14-c371-18712e0d054c.png)
![abc200_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/462dbf64-89d1-5d90-004f-54c16a397a5e.png)
![abc200_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/488e9812-55fd-810e-2e96-20b46ed8bbfe.png)

まともに全探索するとO(N^2)となるので無理。

確か、倍数を問う問題は、
**その倍数で割った余りの集合から共通項の組み合わせで求められる気がする。**

書いてみた。

```abc200c.py
N = int(input())
A = list(map(int,input().split()))
A_ = list(map(lambda x:x%200,A))

#print(A)
#print(A_)

from collections import Counter
KEYs = list(set(A_))
lis = Counter(A_)

score = 0
for key in KEYs:
    if lis[key] > 1:
        score += ( lis[key]*(lis[key]-1) )//2

print(score)
```

counter じゃなくても 辞書でも同じアプローチが出来る。
【NestJS】「git add .」実行時に「error: 'nest-retrospective/' does not have a commit checked out fatal: adding files failed」というエラーが発生した時の対処法

# エラー発生時の状況
* モノレポ方式でGit管理
* ディレクトリの階層構造
    * nestjs_example
        * nest-retrospective 
* `nestjs_example`ディレクトリにいる状態で、`nest new`で`nest-retrospective`ディレクトリを作成後、`git.add`した時エラー発生

# エラーメッセージ
```
error: 'nest-retrospective/' does not have a commit checked out
fatal: adding files failed
```

# ファイルの詳細を確認 （隠しファイルを含む）
```bash
$ cd nest-retrospective/
$ ls -la
total 1280
drwxr-xr-x   15 maiamea  staff     480 10 12 07:40 ./
drwxr-xr-x    6 maiamea  staff     192 10 12 07:37 ../
-rw-r--r--    1 maiamea  staff     631 10 12 07:37 .eslintrc.js
drwxr-xr-x    9 maiamea  staff     288 10 12 07:40 .git/
-rw-r--r--    1 maiamea  staff     391 10 12 07:40 .gitignore
-rw-r--r--    1 maiamea  staff      51 10 12 07:37 .prettierrc
-rw-r--r--    1 maiamea  staff    3339 10 12 07:37 README.md
-rw-r--r--    1 maiamea  staff      64 10 12 07:37 nest-cli.json
drwxr-xr-x  490 maiamea  staff   15680 10 12 07:40 node_modules/
-rw-r--r--    1 maiamea  staff  618935 10 12 07:40 package-lock.json
-rw-r--r--    1 maiamea  staff    1974 10 12 07:37 package.json
drwxr-xr-x    7 maiamea  staff     224 10 12 07:37 src/
drwxr-xr-x    4 maiamea  staff     128 10 12 07:37 test/
-rw-r--r--    1 maiamea  staff      97 10 12 07:37 tsconfig.build.json
-rw-r--r--    1 maiamea  staff     546 10 12 07:37 tsconfig.json
```

# 原因
* `nest-retrospective`に`.git`ディレクトリがあったことで、別のGitリポジトリとして認識されエラーになった（`nestjs_example`のGitリポジトリの管理対象外とみなされた）

# 対処法1
* `.git`ディレクトリを削除する。

```bash
# -r:再帰的に削除 (ディレクトリを削除)
# -f:確認メッセージを表示せずに削除
rm -rf .git
```

# 対処法2

* `nest new`する時に`--skip-git`をつけると、`.git`ディレクトリは生成されない。

```bash
nest new --skip-git プロジェクト名
```

# 参考サイト
* [【Linux】lsコマンド](https://qiita.com/chihiro/items/6e1404c41e1236a9efe1)
Herokuデプロイ時に起きたエラーと対処法

# 概要
HerokuにDjangoアプリをデプロイ(`$ git push heroku master`)する際エラーが立て続けに起きたので、その時のエラーと原因・対処法をまとめました。

# エラー集
### エラー①：App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/python.tgz

実際のエラー文

```terminal
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 12 threads
Compressing objects: 100% (17/17), done.
Writing objects: 100% (18/18), 4.27 KiB | 546.00 KiB/s, done.
Total 18 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/python
remote: -----> App not compatible with buildpack: https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/python.tgz
remote:        More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
remote:
remote:  !     Push failed
remote:  !
remote:  ! ## Warning - The same version of this code has already been built: e2af378ab78b4f9d724ccfbab21e79cba1bec8d6
remote:  !
remote:  ! We have detected that you have triggered a build from source code with version e2af378ab78b4f9d724ccfbab21e79cba1bec8d6
remote:  ! at least twice. One common cause of this behavior is attempting to deploy code from a different branch.
remote:  !
remote:  ! If you are developing on a branch and deploying via git you must run:
remote:  !
remote:  !     git push heroku <branchname>:main          #これを試してみる
remote:  !
remote:  ! This article goes into details on the behavior:
remote:  !   https://devcenter.heroku.com/articles/duplicate-build-version
remote:
remote: Verifying deploy...
remote:
remote: !       Push rejected to xxxxblog.
remote:
To https://git.heroku.com/xxxxblog.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/xxxxblog.git'
```
**【解決方法】**

`$ git push heroku <branchname>:main`


### エラー②： FileNotFoundError: [Errno 2] No such file or directory

実際のエラー文

```terminal
 FileNotFoundError: [Errno 2] No such file or directory: '/tmp/build_15243909/static'
remote:
remote:  !     Error while running '$ python manage.py collectstatic --noinput'.
remote:        See traceback above for details.
```
**【解決方法】**
原因は、.gitignoreファイルに`/static`の記述があり、静的ファイルがデプロイ時に見つけられない状態になっていたことでした。この記述を削除し、`$ git commit`すると解決されました。
■アプリに静的ファイルが無い場合：`$heroku config:set DISABLE_COLLECTSTATIC=1`を実行し、再度`$bgit push heroku <branchname>:main`をする。

### エラー③：Push failed: cannot parse Procfile.
```terminal
Push failed: cannot parse Procfile.
remote:  !     Please try pushing again.
remote:  !     If the problem persists, see https://help.heroku.com/ and provide Request ID 1ec2da4d-fdbf-eae6-0236-721305c905ce.
```
調べたところ、ProcfileをUTF-8にする必要があることがわかった（[参考サイト](https://help.heroku.com/CH22EKEK/why-am-i-seeing-push-failed-can-not-parse-procfile-when-deploying-my-app)）ので、UTF-8に変更し再度```git push heroku <branchname>:main```をすると、無事にpushできました:sunny:
【JavaScript】変数と参照の振り返り⑤　AND条件とOR条件の応用


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/5c339408ebc9059bf654

#目的

* 変数についての理解を深める


#本題
###1.AND条件とOR条件の応用

####例

````javascript
function hello(name){
  console.log("Hello" + name);
}
// Hello Bobと表示される
hello("Bob")
// 引数がない場合、Hello undefinedと表示される
hello()
````

これを避けるためにif文を使って、該当しなかった場合の処理を追記する。

```javascript
function hello(name){
  // nameがundifine = falseな値である場合にTomと出力されればいいので
  // NOT演算子を条件式に加える
  if(!name){
    name = "Tom"
  }
  console.log("Hello" + name);
}
// 結果、ここでは「Hello Tom」と出力される
hello()
`````

この書き方を更に簡略化するためにAND条件、OR条件で書き換える。

```javascript
function hello(name){
  // OR条件の場合、trueな値が見つかった時点で出力する
  name = name || "Tom";
  console.log("Hello" + name);
}
// nameはundefined(空欄)なのでfalse,結果Tomが出力される
hello()
// ここではnameに”Bob”が入っているので上記のnameがtrueになった時点で出力されている
hello("Bob")
```
```javascript
// ES6からはデフォルト引数が設けられるため以下でも同じ意味になる
function hello(name = "Tom"){
  // name = name || "Tom";
  console.log("Hello" + name);
}
// nameがTomじゃないからBobが出力される
hello("Bob")
````

####OR条件を使う際の注意点
falseな場合に初期値を返すが、”数値”である場合は注意が必要

````javascript
function hello(name){
  name = name || "Tom";
  console.log("Hello" + name);
}
// この場合、「Hello 0」と出力したいが0はfalseな値なのでTomと出力される
hello(0)
`````

####応用例

````javascript
function hello(name){
  name = name || "Tom";
  console.log("Hello" + name);
}
hello()

let name = "Bob"
if(name){
  hello(name);
}
// nameがtrueである場合、Bobを呼ぶようにしたい
````

if文でも書くことができるが、AND条件を用いて簡略化すると、以下の通りになる。

```javascript
function hello(name){
  name = name || "Tom";
  console.log("Hello" + name);
}
hello()
let name = "Bob"
// 下記のように記述すると最初のnameがfalseの場合、次のhello(name)は実行されない
name && hello(name)
```
````javascript
function hello(name){
  name = name || "Tom";
  console.log("Hello" + name);
}
hello()
// 試しに下記のように、"Bob"を消してみると
let name 
// nameはfalseになるので、上記のhello()のみになる
name && hello(name)
```

今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
【線形代数】行列の乗法(積) in Python


機械学習では線形代数がよく使われています。
その中で、自分が間違えたことある行列の乗法について話したいと思います。

### 1. アダマール積 (Hadamard product)
また要素ごとの積 (element-wise product)と呼ばれています。
同じサイズの行列$A$と行列$B$のアダマール積は$A\odot B$と書きます。

```math
A=\begin{bmatrix}
  3&4\\ 
  5&6
\end{bmatrix},  
B=\begin{bmatrix}
  1&2 \\ 
  3&4
\end{bmatrix}
```

```math
A\odot B=
\begin{bmatrix}
  3*1&4*2 \\ 
  5*3&6*4
\end{bmatrix}=
\begin{bmatrix}
  3&8 \\ 
  15&24
\end{bmatrix}
```

#### numpy
```python
import numpy as np

A = np.array([[3, 4], [5, 6]])
B = np.array([[1, 2], [3, 4]])

print(A * B)
"""
[[ 3  8]
 [15 24]]
"""
```
#### pytorch
```python
import torch

A_pt = torch.tensor([[3, 4], [5, 6]])
B_pt = torch.tensor([[1, 2], [3, 4]])

print((A_pt * B_pt))
"""
tensor([[ 3,  8],
        [15, 24]])
"""
```

### 2. 通常の行列の積 (dot product)
 サイズ$n×m$の行列$A$とサイズ$m×k$の行列$B$を計算する時に
1. $A\cdot B$
2. $\lt A,  B\gt$
3. $\sum_{i=1}^{n} a_ib_i$ 

などの書き方があります。

```math
A=\begin{bmatrix}
  3&4 \\ 
  5&6
\end{bmatrix},  
B=\begin{bmatrix}
  1&2 \\ 
  3&4
\end{bmatrix}
```

```math
A\cdot B=
\begin{bmatrix}
  3*1+4*3&3*2+4*4 \\ 
  5*1+6*3&5*2+6*4
\end{bmatrix}=
\begin{bmatrix}
  15&22 \\ 
  23&34
\end{bmatrix}
```

#### numpy
```python
import numpy as np

A = np.array([[3, 4], [5, 6]])
B = np.array([[1, 2], [3, 4]])

print(np.dot(A, B))
"""
[[15 22]
 [23 34]]
"""
```

#### pytorch
```python
import torch

A_pt = torch.tensor([[3, 4], [5, 6]])
B_pt = torch.tensor([[1, 2], [3, 4]])

# print(torch.mm(A_pt, B_pt))も一緒です
print(torch.matmul(A_pt, B_pt))
"""
tensor([[15, 22],
        [23, 34]])
"""
```

以上、簡単にメモしました。
RubyでArrayを使う方法

RubyでArrayを使う方法です。

```Ruby
#数字を入力します
m = gets.to_i
#Array配列を定義します
c = Array.new(m)
m.times { |i| c[i] = gets.chomp }
#数字を入力します
n = gets.to_i
#文字列を入力します
s = Array.new(n)
n.times { |i| s[i] = gets.chomp }

c.each do |d|
  s.each do |t|
　　#文字列が含まれているかチェックします
    if t.include? d
      puts 'YES'
    else
      puts 'NO'
    end
  end
end
```
Unityのインスペクター上で列挙型リストを動的に表示する


Dictionaryに追加されたKeyや要素をインスペクター上に"列挙型"として表示するためのスクリプトです。DictionaryはSeiralizeできないので、インスペクター上で内容を確認することはできません。

ただ内容を表示するだけならDebug.logで構わないのですが、要素にdelegate型等を指定して「keyに応じたなにかしらの動作のチェックを行いたい」場合、インスペクターにGUILayout.Buttonで全てのkeyを書くのは非常に大変です。
そこでDictionaryの内容を列挙型で取得できたら非常に便利なんじゃないかと組んでみました。

```c#:InspectorEnumPopup.cs 

using System.Collections;
using System.Collections.Generic;
using System.Linq;

using UnityEngine;
using UnityEditor;

public class InspectorEnumPopup : MonoBehaviour
{
    public Dictionary<string, string> Dic = new Dictionary<string, string>();

    void Start()
    {
        Dic.Add("Hello", "こんにちわ");
        Dic.Add("Bye", "さようなら");
    }
}
#if UNITY_EDITOR
//CustomEditor
[CustomEditor(typeof(InspectorEnumPopup))]
public class InspectorEnumPopupCustom : Editor
{
    private string[] EnumList = new string[] { "None" };
    private int Idx = 0;

    private InspectorEnumPopup Content;

    public void EnumUpdate()
    {
        EnumList = Content.Dic.Keys.ToArray();
    }
    public override void OnInspectorGUI()
    {
        Content = target as InspectorEnumPopup;
        base.OnInspectorGUI();

        Idx = EditorGUILayout.Popup("List", Idx, EnumList);
        if (GUILayout.Button("Enum.Update"))
        {
            if (Application.isPlaying)
            {
                EnumUpdate();
            }
        }
        if (GUILayout.Button("Check Dictionary"))
        {
            if (Application.isPlaying)
            {
                Debug.Log("Key:" + EnumList[Idx] + " Element:" + Content.Dic[EnumList[Idx]]);
            }
        }
    }
}

#endif

```

![qiita01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/4ff660a6-20f7-15ee-e169-09be481df78c.png)

![qiita02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/16128c92-3cce-98ce-ea43-34737f090faa.png)

ここではDictionaryの内容を表示しているだけですが、本来の目的はエディターでの動作確認を簡単にする為のスクリプトです。
SQLで計算

普段SQL書くときって「SELECT カラム名 FROM テーブル名 ...」って構文で書くことがほとんどじゃないですか。
実はSQLってSELECT句だけあれば動きます。なので私は、データベースにログイン中にちょっとした計算がしたくなった時はSQLで計算しています。
(※コメント欄でrana_kualuさんからご指摘いただきましたが、OracleだとFROM句が必須だそうです)

```sql:MariaDB
> SELECT 1 + 3;
+-------+
| 1 + 3 |
+-------+
|     4 |
+-------+
1 row in set (0.000 sec)
>
```

もちろん、関数も使えます。(各ベンターによって実装されている関数に違いはあります)

```sql:MariaDB
> SELECT SQRT(2);
+--------------------+
| SQRT(2)            |
+--------------------+
| 1.4142135623730951 |
+--------------------+
1 row in set (0.000 sec)

> SELECT CURRENT_DATE(), DATEDIFF('2022-01-01', CURRENT_DATE());
+----------------+----------------------------------------+
| CURRENT_DATE() | DATEDIFF('2022-01-01', CURRENT_DATE()) |
+----------------+----------------------------------------+
| 2021-10-12     |                                     81 |
+----------------+----------------------------------------+
1 row in set (0.000 sec)

>
```

あと81日寝るとお正月ですね。
Git よく利用するコマンド

## はじめに
gitコマンドを覚えてもちょっと時間があくとすぐに忘れるので、よく使うコマンドや、自分が現場で利用するgitの使い方をまとめてみようかと思います

## 基本操作
**リポジトリのクーロン**

```
git clone <リポジトリのURL>
```

**ブランチの作成**

```
git branch <ブランチ名>
```

**ブランチの切り替え**

```
git checkout <ブランチ名>
```

**修正したファイルをステージングにあげる**

```
git add <修正したファイルのパス>
```

**コミット**

```
git commit -m <コミットメッセージ>
```

**リモートリポジトリにプッシュ**

```
git push origin <ブランチ名>
```

## よく使うコマンド

**ブランチを作成してそのまま作成したブランチに移動する**

```
git checkout -b <ブランチ名>
```

**現在存在するブランチを確認**

```
# ローカルブランチの確認
git branch
# リモートブランチも含めた確認
git branch -a
```

**ブランチの削除**

```
# マージ済みのローカルブランチを削除する
git branch -d <ブランチ名>

# マージしてないブランチを削除する
git branch -D <ブランチ名>

```

**変更した内容スタッシュする**

```
# スタッシュする
git stash save "変更内容を記載"

# 現在のスタッシュしているリストを確認
git stash list

# スタッシュした内容を復元する
git stash apply stash@{スタッシュ番号}

# スタッシュを削除
git stash drop stash@{スタッシュ番号}

```

**コミットログを確認**

```
git log
```

**直下の変更があったファイルを全てステージングにあげる**

```
git add .
```

**指定のコミットに強制的に戻る**

```
git reset --hard <commit ID>
```

## rebase時のコンフリクト解決方法

```
# 作業してるブランチでrebase対象を取り込む
git rebase <取り込みたいブランチ名>

# 手動でコンフリクトを解決した後、ステージングにあげる
git add <修正したファイル>

# rebase続行
git rebase --continue

# リモートブランチに強制的にpushする
git push origin <ブランチ名> --force
```



## その他

**随時更新予定**
ReactのuseContext()

## useContextとは？
propsを直接渡したい子孫コンポーネントに値を渡すことができるフックです。

孫コンポーネントに値を受け渡す場合、親コンポーネントから子コンポーネントに受け渡した値をさらに孫コンポーネントに渡す。
ということが必要でしたが`useContext`を利用することで直接を渡すことができます。

|オブジェクト / コンポーネント|説明|
| ---- | ---- |
|Contextオブジェクト|React.createContext()の戻り値|
|Providerコンポーネント|Contextオブジェクトが保持しているコンポーネント|
|Consumerコンポーネント|useContext()を利用することで、Contextオブジェクトから値を取得できる|

### Contextオブジェクト

```js
const ContextObj = React.createContext();
```
または、

```js
import React, { createContext } from 'react';

const ContextObj = createContext();
```

### Providerコンポーネント
`.Provider`でラップするとラップされたコンポーネントのツリー内でvalueの値を参照できるようになります。

```js
<ContextObj.Provider
 value={ツリー内で共有可能なコンテキストオブジェクトの値}
>
 <Consumer />
</ContextObj.Provider>
```

import時に`useContext`を読み込みます。

```js
import React, { useContext } from 'react';

const コンテキストオブジェクトの値 = useContext(コンテキストオブジェクト);
```

## useContextの利用
```js
import React, { createContext, useContext } from 'react';

const ContextObj = createContext();

const Consumer = () => {
  const message = useContext(ContextObj);
  console.log(message);

  return <p>{message}</p>;
};

const message = 'React useContext';

export default function App() {
  return (
    <>
      <ContextObj.Provider value={message}>
        <Consumer />
      </ContextObj.Provider>
    </>
  );
};
```

`useContext`でContextオブジェクトから値を取得し、変数`message`に格納します。

```js
const message = useContext(ContextObj);
```

`message`には`Provider`コンポーネントにて`value`に指定された値を受け取ります。

```js
const message = 'React useContext';

export default function App() {
  return (
    <>
      <ContextObj.Provider value={message}>
        <Consumer />
      </ContextObj.Provider>
    </>
  );
};
```
すると画面に「React useContext」が表示されると思います。

次はファイルを分割した場合を試してみたいと思います。
Lambdaで取得した画像をKinesis及びLambda経由でS3にアップロードする

[Lambdaで取得した画像をKinesis及びFirehose経由でS3にアップロードする](https://qiita.com/nkmk1215/items/24d481001f94901853be)にて
流した画像がFirehoseを経由うすると複数の画像がまとめられて出力されたので
KinesisからLambda経由でS3にアップロードしたときの個人メモ

[（参考）S3 — Boto3 Docs 1.18.57 documentation - Amazon AWS](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.put_object)
[（参考）Amazon Kinesis で AWS Lambda を使用する](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-kinesis.html)

---

# Kinesis
- [Lambdaで取得した画像をKinesis及びFirehose経由でS3にアップロードする](https://qiita.com/nkmk1215/items/24d481001f94901853be)にて  
  作成したものを流用

# Lambda
- Python3.9にて作成

![024.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/ea3f66f3-ea7c-1f4b-3f37-80a0c46050a9.jpeg)

- 自動生成されたロールを選択

![003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/a8382b73-b9b6-7f86-ffe7-e20a1a7026e5.jpeg)

- ロールにアタッチされているポリシーを以下のように修正
    - S3へのPutObjectを付与
    - logsはデフォルトのまま
- ロールに既存ポリシー「AWSLambdaKinesisExecutionRole」をアタッチ

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:（リージョン名）:（AWSアカウント）:*",
                "arn:aws:s3:::（バケット名）/*"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:（リージョン名）:（AWSアカウント）:log-group:/aws/lambda/uploadToS3FromKinesis:*"
        }
    ]
}
```

![011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/1f70d0f2-b6db-23f2-d343-a28425344d8b.jpeg)

- ソース修正

```lambda_function.py
import os
import logging
import boto3
import base64

# ログ設定
logger = logging.getLogger(__name__)
logger.setLevel(os.environ['LOG_LEVEL'])

# 環境変数から取得
BACKET_NAME = os.environ['BACKET_NAME']
FILE_PATH = os.environ['FILE_PATH']


# 画像をS3にアップロードする
# img:画像のバイナリデータ
# return:プットした結果
def put_img_to_s3(img):
    logger.debug('start put_img_to_s3()')

    s3 = boto3.client('s3')
    response = s3.put_object(Bucket=BACKET_NAME, Key=FILE_PATH, Body=img)

    logger.debug('end put_img_to_s3()')

    return response


def lambda_handler(event, context):
    logger.debug('start lambda_handler()')

    logger.debug('event:' + str(event))
    img = base64.b64decode(event['Records'][0]['kinesis']['data'])

    result = put_img_to_s3(img)

    logger.debug('end lambda_handler()')

    return result
```

- 環境変数設定

![010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/335dc905-8eaa-7875-0399-dd283d9f6118.jpeg)

# 動作確認
- [Lambdaで取得した画像をKinesis及びFirehose経由でS3にアップロードする](https://qiita.com/nkmk1215/items/24d481001f94901853be)と同様

![012.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/f58e7bb2-2e83-65da-5994-bfe2d463a002.jpeg)

# 感想
- Firehose経由と異なり、連続で画像を流してもまとめてアップロードされなかった
- アップロード時のファイル名は環境変数で指定した固定値なので  
  動的に設定できるようにしたい
unity basic unitask async await with Process and Stream

## unity と外部プログラムを連携したときの基本的な非同期のやり方



unity

```
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using System.Diagnostics;
using System.IO;
using Cysharp.Threading.Tasks;
using Debug = UnityEngine.Debug;


public class TestUniTask : MonoBehaviour
{
    // Start is called before the first frame update
    private string pyExePath = @"C:\meganebu\venv\Scripts\python.exe";
    private ProcessStartInfo processStartInfo;
    private Process process;
    private StreamReader streamReader;
    private string processResult;
    
    
    // Basic async await with Process(ex python)    
    async void Start()
    {

        Debug.Log("Start1");
        var result = await TestFunc();
        Debug.Log(result);
        Debug.Log("Start4");

    }

    private UniTask<string> TestFunc()
    {
        Debug.Log("Start2");
        return UniTask.Run(() =>
        {
            processStartInfo = new ProcessStartInfo()
            {
                FileName = pyExePath,
                UseShellExecute = false,
                CreateNoWindow = true,  
                RedirectStandardOutput = true,
                Arguments = @"C:\meganebu\test.py"
            };
            process = Process.Start(processStartInfo);
            streamReader = process.StandardOutput;
            processResult = streamReader.ReadLine();
            process.WaitForExit();
            process.Close();
            Debug.Log(processResult);
            Debug.Log("Start3");
            return processResult;
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
```


大事な箇所だけ、説明
```private string pyExePath = @"C:\meganebu\venv\Scripts\python.exe";
```
ここで、あらかじめインストールしておいたpythonを指定


```Arguments = @"C:\meganebu\test.py"
```
次に、ここで、実際に実行したいpythonを指定。


```var result = await TestFunc();
```
実際には、ここで実行。すると、TestFunc内が実行され、pythonが実行され、pythonからの戻り、print(1)の１を受け取って、resultに入る。

ので場合よっては、python側で、処理分岐し、０、１で成否、その戻りをunityで受けてUI上に表示するとか、が良いかも。


python

```
import sys
import time

time.sleep(5)
print(1)
```


```time.sleep(5)
```
ここは、確認用にわかりやすく入れているsleep処理。unityから呼び出した後、ちゃんと５秒待って、戻りが戻ってくる。
ラビットチャレンジ　レポート

#応用数学
##第1章：線形代数
###要点のまとめ(100字以上)
* 行列は「ベクトルの変換」と「連立方程式を解く」ために使う
* 単位行列は主対角線上の要素が全て1でそれ以外の要素が全て0の正方行列のこと
* 逆行列を求める際に、「掃き出し法」を用いる
* 行列式の計算のおいて、行と列を入れ替えると符号が変わる
* 行列式の性質として以下の3つがある

1. 同じベクトルが含まれていると行列式は0になる
1. 1つのベクトルがk倍されると行列式がk倍される
1. 他の成分が全て同じでi番目のベクトルだけが違う場合、行列式の足し合わせになる

* ある行列Aに対して、特殊なベクトル$\vec{x}$と係数$\lambda$がある
$$A\boldsymbol{x} = \lambda\vec{x} $$
($\boldsymbol{x}$：固有ベクトル、$\lambda$：固有値)
* 固有値分解によって行列を分解できる
* 正方行列以外の行列に関しては特異値分解によって固有値分解と似たような分解ができる

###メモ・例題
![S__45531138.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/de6575e9-f304-a78f-ce47-493c841776b0.jpeg)
![S__45531140.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/caf4d26c-1c0b-9c9b-9535-2a55f7dc14cf.jpeg)
![S__45531141.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/238b60af-8678-78d7-ec73-d387444e6ef0.jpeg)
![S__45531142.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/87fc2937-23df-18fb-6220-ed7e042af501.jpeg)
![S__45531143.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/90a4ee9b-e279-994a-5bcc-80381ff181be.jpeg)


##第2章：確率・統計
###要点のまとめ(100字以上)
* 大量のデータから特徴を見つけ出し分析するのが「統計学」
* 確率・統計に登場する「事象」は「集合」として扱うことができる
* 全体$U$の中の集合$A$に対して、$A$以外の部分を「絶対補」といい、$U$ \ $A$ (=$\bar{A}$)であらわす
* 集合$B$のうち集合$A$と共通する部分を除いたものを「相対補」といい、$B$ \ $A$であらわす
* 確率には頻度確率(発生する頻度)とベイズ確率(信念の度合い)の2種類がある
* 様々ある確率分布の中には、

1. ベルヌーイ分布(0 or 1の試行)
1. 二項分布(ベルヌーイ分布の多試行版)
1. ガウス分布(釣り鐘型の連続分布)

　等がある

* 点推定：平均値等を1つの値に推定すること
* 区間推定：平均値などが存在する範囲(区間)を推定すること
* 標本分散：標本から計算した分散
* 不偏分散：標本分散が母分散に等しくなるように補正したもの

###メモ・例題
![S__45531144.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/40c164a4-acd4-57a4-3eb2-80f1ae8caa99.jpeg)
![S__45531145.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/9fffc3f5-bcf9-b42d-8f5d-fd743d1062ea.jpeg)

##第3章：情報理論
###要点のまとめ(100字以上)
* 自己情報量：対数の底が2のとき単位はbit(ビット)、底が*e*のとき単位はnat
* シャノンエントロピ：微分エントロピともいうが微分しているわけではない、自己情報量の期待値である
* カルバック・ライブラー　ダイバージェンス(KLダイバージェンス)：同じ事象・確率変数における異なる確率分布*P*と*Q*の違いをあらわす、最初に与えられた情報のめずらしさ*Q*からあとでわかった情報のめずらしさ*P*を引き算する、古い情報の分布を新たに分かった情報の分布と比較したときにどれくらい違うかの程度を示す
* 交差エントロピ：KLダイバージェンスの一部分を取り出したもの、*Q*についての自己情報量を*P*の分布で平均している

###メモ・例題
![S__45531145.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/79d083cb-ef10-dad6-f501-eb1a8585f636.jpeg)
![S__45531146.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/71ce7175-9c81-733f-86c8-afa549063497.jpeg)


##演習問題
![S__45531147.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/40d427a3-3e86-1e06-2da9-ae76df337c94.jpeg)
![S__45531148.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1300365/d7b22a9b-de18-a42b-3b9b-fe7ba58ace9c.jpeg)
論文まとめ：Visual Identification of Individual Holstein-Friesian Cattle via Deep Metric Learning

# はじめに
Computers and Electronics in Agricultureから以下の論文
[1] W. Andrew, et. al. "Visual Identification of Individual Holstein-Friesian Cattle via Deep Metric Learning" Computers and Electronics in Agriculture 185, 106133
のまとめ

arXiv:
https://arxiv.org/abs/2006.09205

Github:
https://github.com/CWOA/MetricLearningIdentification
 -> pytorch

この分野の第１人者であるAndrew氏の直近の論文。

# 概要
- ホルスタインの体の白黒模様から個体識別をするしくみ
- メトリクス学習し、未知（open-set）のホルスタインに対してはlatentベースでマッチングする

これまでのAndrew氏の手法は、学習したIDに対して推定するものであったが、今回は未知のIDに対しても使えるようになった。

# モデルの全体像

以下がモデルの全体像。

![CWOA_img00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/c6f0d3c9-3354-b6ca-d142-d923af3dae69.png)

（１）左下ホルスタインが映った画像に対し、その上、yolo-v3等で牛の領域をdetectする。

（２）切り取った矩形領域に対し、ResNet等でembedする。学習時はこれに対しメトリクス学習を行う。

（３）推論時は推定した複数のlatentに対し、k近傍法でそれらのIDが一致するか否かを判断する。

# 新たに作成したdataset OpenCows2020に関して
まず、このdatasetはこちら
https://research-information.bris.ac.uk/en/datasets/opencows2020
からフリーで入手できる。

以下、概要
- 牛舎内、及び野外の２つのシーンがあり、いずれも上部から撮影されている
- 3,707枚の画像において6,917頭のホルスタインがアノテーションされている
- detection用に矩形がアノテーションされているが、頭部と尻尾は矩形領域から外している
- 牛のIDもアノテーションされている
- 全体を8:1:1に分け、training, validation, testとしている
- 20枚以上写っている牛のみIDとして採用している
- 46の個体があり、１個体あたり平均103枚程度写っている

以下が画像全体のサンプル。

![W_Andrew2020_img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/766052bf-8038-fa2f-d7c6-71fba2d19683.png)

以下が矩形領域のサンプル。

![W_Andrew2020_img04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/c0f09a4b-e3aa-6380-83a8-8b06effdfaeb.png)

# ID識別部分の学習
## ネットワーク構造
上述したように、ネットワークのアーキテクチャはResNet-50。

## loss
triplet loss。

$x\_a$ ：アンカーのデータ
$x\_p$ ；aと同じID（positive）の別のinstanceのデータ
$x\_n$ ：aと異なるID（negative）のデータ
として、まずベースはこれ。

```math
\mathbb{L}_{TL} = \max (0, d(x_a, x_p) - d(x_a, x_n) + \alpha) \tag{1}
```

ただし、これは以下の図の右部分

![W_Andrew2020_img10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/2d86a5d3-46fa-3902-6341-832a095bb260.png)

のようないわゆる margin problem を引き起こす。この図ではpositiveとnegativeはちゃんと $\alpha$ のマージンが取られているが（つまり（１）式を満たすが）、anchorとpositiveとは近くならない。

そこで以下のような改良版も提案されている。

```math
\mathbb{L}_{RTL} = d(x_a, x_p) +\frac{1}{d(x_a, x_n)} \tag{2}
```

これだとanchorとpositiveを近くすると同時にanchorとnegativeを遠くできる。

これに softmax loss を加えると精度がよくなることが知られている。よって本手法でのlossは（２）式に softmax loss を加え、


```math
\mathbb{L}_{softmax + RTL} = \mathbb{L}_{softmax} + \lambda \cdot \mathbb{L}_{RTL} \tag{3}
```

とする。

#実験と結果
## 定量的評価
OpenCows2020を用いた先行研究がないため、Lossを比較した。

![W_Andrew2020_img12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/d091f3f9-9b55-4cb3-c223-eb4110bdaf6c.png)

グラフの横軸はvalidation data、もしくはtest dataの割合。

赤点線がtriplet lossのみ、黄緑点線が式（２）、緑点線はsoftmax＋triplet loss、青点線は本論文提案のsoftmax + 式（２）。

提案手法が右側test dataに対して最も精度がよい。

## embeddingをt-sneで可視化。
こちらもlossごとに可視化。

![W_Andrew2020_img17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/d7aa666e-0f21-be9a-50bd-b0df54ef77bb.png)

微妙だが、右下の提案手法lossが最も分けられてる感じか？
LispのFizzBuzzを解説してみる


# はじめに
https://twitter.com/mattn_jp/status/1447190673485013000

について解説します。
おそらく出典は
https://gist.github.com/youz/8e2296ce36087a6cc859f174315d187c
だと思います。
# 元コード

```common-lisp
(dotimes'101(format t"~&~[~;~A~v^~;~;Fi~;~;Bu~:;~v^FizzBu~]zz"(gcd .'15).'0))
```

とりあえずmacroexpandしてみます。

```common-lisp
* (macroexpand '(dotimes'101(format t"~&~[~;~A~v^~;~;Fi~;~;Bu~:;~v^FizzBu~]zz"(gcd .'15).'0)))
(BLOCK NIL
  (LET ((QUOTE 0))
    (DECLARE (TYPE UNSIGNED-BYTE QUOTE))
    (TAGBODY
      (GO #:G446)
     #:G445
      (TAGBODY
        (FORMAT T "~&~[~;~A~v^~;~;Fi~;~;Bu~:;~v^FizzBu~]zz" (GCD QUOTE 15)
                QUOTE 0))
      (PSETQ QUOTE (1+ QUOTE))
     #:G446
      (UNLESS (>= QUOTE 101) (GO #:G445))
      (RETURN-FROM NIL (PROGN NIL)))))
```

Lisperならなんとなくの構造はつかめるのではないでしょうか。

## 外側から見てみる
### (dotimes '101 X)
まずdotimesは他の言語でのforなどに相当するループのマクロです。
本来の記法は

```common-lisp
(dotimes (x 101) (print x))
```

のように用います。この場合0~100までの数値がprintされます。
'はlispのスペシャルフォームであり、'101は(quote 101)に展開されます。なので、

```common-lisp
(dotimes (quote 101) X)
```

に展開されます(よく思いつくなこれ...)。今後quoteにバインドされる数値をQと表記します(quoteでは混同するため)。

### (format X)
次にformatです。
最初から見てみましょう。
#### 第一引数 t 標準出力に出力
nilの場合返り値になります。今回は標準出力なのでt。
#### 第二引数 "" control-string
formatでは、第二引数に出力コントロール用の記号(formatディレクティブ)を含む文字列をとってそのコントロール通りに出力します。第三引数以降はformatディレクティブが用いる引数です。
例えば
(format t "~5Aa" 1)
は~5Aがformatディレクティブです。~はformatディレクティブの開始位置を示します。終端位置はAなどの指定されたディレクティブ指定文字です。開始位置でも終端位置でもない部分はパラメータでありformatディレクティブの振る舞いを制御します。Aのディレクティブ指定文字は引数をひとつとって出力するので引数の1が出力されます。このとき、パラメータの5は後ろに文字をパディングするため1とaの間に空白文字を5つ入れます。

##### ~& 行頭でなければ改行
Q=0の時は行頭ではないので改行されません。
##### ~[~;~;~] 引数を1つとって;で区切られた部分を出力する
(format t "~[0~;1~;2~;3~]" 1)
0スタートかつ最後の一つ前の;が:;だった場合当てはまらないそれ以上の数になるので

| 第三引数 | 出力される部分 |
|:-:|:-:|
|  0 |   |
|  1 |  ~A~v^ |
|  2 |   |
|  3 |  Fi |
|  4 |   |
|  5 |  Bu |
|  6以上 |  ~v^FizzBu   |

が出力されます。ここに渡される引数は(GCD QUOTE 15)に展開されるので、Qと15の共通因数が渡されます。なので共通因数がない(互いに素)場合1に、3で割り切れる(Qに3の因数がある)場合3に...となります。
##### ~A なんでも出力
おなじみなんでも出力です(ここはAである必要はなくDやSでも動きます)。第四引数に対応します。
##### ~v^ 処理打ち切り
まず^は条件を満たした時にformatの処理を打ち切ります。
これがあるためQが3でも5でも割り切れない場合後続のzzも出力されなくなります。
vは特殊な文字で、パラメータに存在する場合formatの引数をとってパラメータにします。^は第一パラメータが指定されている場合、第一パラメータ=0が条件になり第三引数は0なので必ず処理が打ち切られます。
##### Fi Bu (文字出力)
そのままFiとBuが出力されます(処理が継続するのでzzが後に出力されます)。
##### ~v^FizzBu (処理打ち切り+文字出力)
~v^は前述の通り引数をひとつとって引数=0のとき処理を打ち切ります。これは(gcd Q 15)が6以上の場合に出力されるのですが、commonlispはどちらかが0の場合最大の因数を返すので、Q=0のとき15を返します。FizzBuzzは1始まりなのでQ=0の時に何も表示しないようにこの部分があります。Q/=0の場合はFizzbuを出力します(処理が継続するのでzzが後に出力されます)。
#### 第三引数 (gcd .' 15)
まず、これは(gcd quote 15)に展開されます(なぜ.'がquoteに展開されるかはわかりません...わかる人情報ください...)。
前述の通り~[~;~;~]にQと15の共通因数が渡されます。なので共通因数がない(互いに素)場合1に、3で割り切れる(Qに3の因数がある)場合3に...となります。
#### 第四引数 .'
前述の通りquoteに展開されます。3でも5でも割れない場合の数値の出力と0の場合の処理打ち切りに利用されます。
#### 第五引数 0
3でも5でも割れない場合の処理打ち切りに利用されます。

# 終わりに
formatを用いたcodegolfについて解説しました。自分でも知らない仕様があったので勉強にもなりました。特にdotimesとquoteの組み合わせはかなり衝撃的でした。今後使う機会があるかはわかりませんが...
## 参考文献
http://ais.sys.i.kyoto-u.ac.jp/~task/format-func.html
http://www.lispworks.com/documentation/HyperSpec/Body/s_quote.htm#quote
[AtCoder][ABC194D] コンプガチャをコンプリートするのに必要な回数の期待値

N種類の景品を全て手に入れるには何回ガチャをまわす必要があるのかを考える。
ここで景品が出る確率は全て等しいとする。

下記はこの問題に帰着できる。
AtCoder Beginner Contest 194

https://atcoder.jp/contests/abc194/tasks/abc194_d


## STEP1. 期待値の分解

0からN種類まで手に入れるまでのガチャ回数を下記の考え方で分解する。
> 0種類持っている状態から新しい1種類を手に入れるまでの回数
1種類持っている状態から新しい1種類を手に入れるまでの回数
2種類持っている状態から新しい1種類を手に入れるまでの回数
・・・
N-1種類持っている状態から新しい1種類を手に入れるまでの回数

これらの回数の合計が答えとなる。

言い換えると、
k種類持っている状態から新しい景品が出るまでに必要な回数をX(k)とする
するとN種類手に入れるまでの回数の期待値は下記となる
```X(0)+X(1)+...+X(N-1)```


## STEP2. 期待値の求め方

確率Pで発生する事象が実際に発生するまでに必要な回数の期待値は確率の逆数となる
```1/P```

直観的には、1/2で発生する事象は2回試せば1回は発生する。とイメージするとわかりやすい
数学的証明は複雑なので省略

X(k)を考えると、k種類持っている状態で残りのN-kから新しい1つを手に入れる確率は
```P(k) = (N-k)/N```
よって
```X(k) = 1/P(k) = N/(N-k)```

STEP1と組み合わせることで最終的な答えは下記の式で表すことができる。
```N/(N-1) + N/(N-2) + ... + N/(N-(N-1))```

## 参考

https://manabitimes.jp/math/1053
AWS (CodePipeline CodeCommit CodeBuild CodeDeploy) をざっくり理解

#概要
CodePipeline CodeCommit CodeBuild CodeDeploy を用いたデプロイの流れをざっくり解説しました。
細かい設定や、ファイルへの記述は最後に書いていないです。

#参考にさせていただいた講座および引用させていただいた画像

[Techpit 「Laravel × CircleCI × AWSで学ぶCI/CD」  　shonansurvivors様 著](https://www.techpit.jp/courses/78)

#基盤となる図

![スクリーンショット 2021-10-12 0.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/3d8bdbe3-bdb3-252f-713b-4f0f8a03d50c.png)

1~7まではローカルからCircleCIを通して、featureブランチでテストをパスした後masterにマージ。そしてテストを行っている。
その後からCode〇〇を用いたデプロイの開始である。

#Code〇〇のそれぞれの役割

##CodePipeline
デプロイをするためのパイプラインを文字通り作っている。以下の図のようにCodeCommit CodeBuild CodeDeploy　をこのパイプラインに当てはめる。
これがデプロイするためのパイプライン（CodePipeline）である。

下記の図で上からCodeCommit CodeBuild CodeDeploy　の順に並ぶ。

CodePipeline　を作成する際にCodeCommit CodeBuild CodeDeploy　という３つのパーツを当てはめる。

また、CodePipelineを作成するときにCodePipeline用のS3バケットが自動で作成される。

![27981f7d-8b5b-4f56-936e-f92b0e32d187.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/619d13ff-5ded-8641-822b-56f21fdc561a.png)


#Codecommit

CodeCommitとは、AWS上に存在するGitリポジトリのサービス(AWS版のGitHubのようなもの)。

CodeCommitに最新のmasterブランチがプッシュされると、そのコードがS3にコピーされ(図の9)、これをCodeBuildが取得します(図の10)。

下記のようにリポジトリが作成される。
![スクリーンショット 2021-10-12 1.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/f5c9fff1-41e8-bd9f-3ccd-1514a8daeb12.png)

#Codebuild

CodebuildはS3から先程コピーされたソースコードを取得。
テスト、パッケージのインストールを実行して、すぐにデプロイできるアーティファクトを生成する役割(図の10,11,12)。

例としては、yarn install yarn test rake assets:precompile等を実行してデプロイできる準備を行う。

テストをここで行うこともできるので、CircleCIでのテストを省略可能。

行いたいコマンドをbuildspec.yml に記述しアプリケーションのトップディレクトリに配置する。(詳しくは後)

#CodeDeploy

デプロイを指示する役割（図の１３）。S3からビルド後のファイル群を取り出し、EC2にデプロイします(図の14)。
また、EC2からRDSのDBに対してマイグレーションを実行します(図の15)

appspec.yml というファイルをアプリケーションのトップディレクトリに配置することによってデプロイする際のコマンド（rails db:migrate　など）を指定することができる（後に詳しく）

#全体の流れ

全体の流れとしては

① CircleCIでのテストをパスしたソースコードをCodeCommitにpush
② そのソースコードをCodeCommitからS３にコピー
③ CodebuildがS3からソースコードを取得し、デプロイの準備のためのコマンドを実行
④ CodeDeployがデプロイを指示。その際に、データベースのマイグレーションなど行いたいコマンドを実行。
Oracle Cloud Infrastructure (OCI)でのタスクスケジューリング (CRON 編)

#はじめに
Cloud サービス利用しているとき、スケジューリングタスクの実行が必要な場合があります。例えば：インスタンスの自動起動・停止をスケジュールする
記事を作成時点、オラクルは、クラウドネイティブ機能としてスケジューリングを提供していません。その機能リリースされる可能性がありますが、それまでは、これは実行可能な代替手段としての方法を検討しました。

#方法
OCIコンピューティングインスタンスでのCRONジョブを設定、OCI CLIを利用してOCIを操作

#環境
OS: Oracle-Linux-7.9

#手順
##STEP1: OCI CLI  インストール
下記の記事を参照

[Oracle Cloud : コマンド・ライン・インタフェース(CLI) をインストールしてみた](https://qiita.com/shirok/items/e63be9a22158fef10ba9)

##STEP2: 必要タスクのシェル作成
例1：　Computeインスタンス起動停止
ファイル：/home/opc/ocicli/ocicompute.sh

```
#!/bin/bash

oci compute instance action --instance-id $1 --action $2

if [ $? -eq 0 ]
then
  echo "Success"
  exit 0
else
  echo "Failure" 
  exit 1
fi
```
`$1` - instance-id （例：ocid1.instance.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa）
`$2` - action (例：start , softstop , stop )
※通知やエラー処理などを省略させてください。

インスタンス起動使用例：

```
/home/opc/ocicli/ocicompute.sh ocid1.instance.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa start
```

例２：DBインスタンスシェイプ変更
ファイル：/home/opc/ocicli/changedbshape.sh

```
#!/bin/bash

oci db system update --db-system-id $1 --shape $2

if [ $? -eq 0 ]
the
  echo "Success"
  exit 0
else
  echo "Failure" 
  exit 1
fi

```
`$1` - db-system-id （例：ocid1.dbsystem.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa）
`$2` - shape (例：VM.Standard2.1 ,VM.Standard2.2 )
※通知やエラー処理などを省略させてください。


シェイプをVM.Standard2.2に変更使用例：

```
/home/opc/ocicli/changedbshape.sh ocid1.dbsystem.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa VM.Standard2.2
```

##STEP3: 実行権限追加
例：

```
chmod u+x /home/opc/ocicli/ocicompute.sh
chmod u+x /home/opc/ocicli/changedbshape.sh
 
```
##STEP3: CRON 設定
例１：毎日９時インスタンス起動、２０時インスタンスを停止

```
0 9 * * * /home/opc/ocicli/ocicompute.sh ocid1.instance.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimuwb2eciaq3kqzvegzp7os3ub6obyrxa start
0 20 * * * /home/opc/ocicli/ocicompute.sh ocid1.instance.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimuwb2eciaq3kqzvegzp7os3ub6obyrxa softstop
```

例2：毎月1日DBインスタンスのシェイプをVM.Standard2.2に変更
毎月25日DBインスタンスのシェイプをVM.Standard2.4に変更

```
0 0 1 * * /home/opc/ocicli/changedbshape.sh ocid1.dbsystem.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa VM.Standard2.2
0 0 25 * * /home/opc/ocicli/changedbshape.sh ocid1.dbsystem.oc1.ap-tokyo-1.anxhiljr5tza4ciczisonvcjybtimu4b2eciaq3kqzvegzp7os3ub6odvzxa VM.Standard2.4
```


#参考資料：
https://mytechretreat.com/5-ways-to-schedule-serverless-functions-on-oracle-cloud-infrastructure/
railsでkaminariを使ってpaginationを作りそのテストをRspecで書こうとしてハマりました

# 概要
勉強とポートフォリオ作成を兼ねてrails tutorialをなぞりながらtestをminitestではなくRspecで書いて見ようと試みていたところ、
第10章のPaginationの箇所でハマったので（他にも色々ハマっていますが）投稿記事として無難かなという思いと個人的な備忘録としても書いとこうと思います。

## 環境
rails tutorial ６版とはGemのverが一部異なります。
kaminariとrspec-railsを入れてます

```Gemfiles.rb
# 抜粋です

ruby '2.7.4'

gem 'bootstrap',                  '~> 4.6.0'
gem 'kaminari'
gem 'rails',                      '6.0.3'
gem 'rails-i18n'

group :test do
  gem 'capybara',                 '3.28.0'
  gem 'factory_bot_rails'
  gem 'rails-controller-testing', '1.0.4'
  gem 'rspec-rails'
  gem 'selenium-webdriver',       '3.142.4'
  gem 'webdrivers',               '4.1.2'
end
```

## ハマったところ
tutorial リスト 10.48のテストについて
やっていることを下記します
1. ログインする
2. ユーザ一覧ページへ移動
3. `assert_template`
4. paginationがあるか
5. 1page目に表示されているすべてのuserのリンクが正しいことの確認
rspecに書く際、3.はtitleを確認することでお茶を濁しています。
ハマったのは５.です。
## 結論
1ページのレコード数（今回はユーザー数）はperメソッドで変更してもrspecでのtestはデフォルトの25で検査を強行されるので、
`kaminari_config.rb`を作ってデフォルトを変更するべし
## 状況

```user_controller.rb
# 抜粋
  def index
    # pageとperがkaminariで定義されたメソッド perメソッドの引数にどれだけのレコード
    # (この場合はユーザー)が表示されたらページを増やすかを指定する
    @users = User.page(params[:page]).per(10)
  end
```

RspecはSystem_specでやってます

```spec/systems/users_index_spec.rb
require 'rails_helper'

RSpec.describe 'user_index', type: :system do
  describe 'ユーザ一覧を開いたとき' do
    let!(:first_user) { FactoryBot.create(:user) }

    it 'ページネーションが存在しページ遷移ができること' do
      # create_listでFactoryBotから模擬ユーザを量産
      create_list(:user, 25)
      # login_asヘルパーメソッドはsupport/test_helper内で定義
      login_as(first_user)
      visit users_path
      expect(page.title).to eq full_title('ユーザ一覧')
      # ページネーションが上下で２つあることを確認する
      expect(page).to have_selector '.pagination', count: 2
      # 最初のページ２へのリンクをクリックする
      click_on '2', match: :first
      # ユーザーフレンドリー＋ページキャッシュのために下記で通るようにroutes.rbで細工してる
      expect(current_path).to eq '/users/page/2'
      click_on '1', match: :first
      User.page(1).each do |user|
        expect(page).to have_link href: "/users/#{user.id}" # この部分でエラーが起こる
      end
    end
  end
end
```

ご参考にroutes.rbの細工箇所です

```routes.rb
#下記でpagination 2page目のPathが/users/page/2 とできる
  resources :users do
    get 'page/:page', action: :index, on: :collection
  end
```

## 解決策
結論で書きましたが、`kaminari_config.rb`を作ります。

```
$ rails g kaminari:config
    create  config/initializers/kaminari_config.rb
```

作ったファイルでデフォルトのper_pageを変更します。

```config/initializers/kaminari_config.rb
# frozen_string_literal: true

Kaminari.configure do |config|
  config.default_per_page = 10 # ここの部分のコメントを外し２５　⇨　１０にしました
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  config.left = 2
  config.right = 1
  # config.page_method_name = :page
  # config.param_name = :page
  # config.max_pages = nil
  # config.params_on_first_page = false
end
```

`user_controller`内の`per(10)`は不要なので消しときます。
これでtest通るようになりました。
ありがとうございました。
BlenderのPythonスクリプトでプロポーショナル編集したい時

　需要があるのがないのかわからない Blender Python スクリプト講座。日本語の情報がなかったので。あと検索範囲が足りないのかもしれないけど、英語でも古い情報しかなかったような......。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/7b3faedd-13c4-6e1e-a60c-e7e7d41b1e08.png)

　こういうグリッドを、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/cc925843-5112-4920-4bed-4644bb9406de.png)

　こうしたいと考えます。ランダムに 10 個頂点を選択して、上に持ち上げて波打った地面のようにするという作業です。

# 頂点の編集（基本）

　基本的には、`bpy.data`から頂点を編集するのが王道です。以下のようなスクリプトを考えてみます。

```python
import bpy
import random

obj = bpy.context.object
msh_name = obj.to_mesh().name
msh = bpy.data.meshes[msh_name]
vts = msh.vertices
size = len(vts)
for i in range(10):
    idx = random.randint(0,size-1)
    vts[idx].co.z += 1
```

　これは、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/38664d1a-5188-0db8-cb83-b5feddcceeaa.png)

　このような絵面が生み出されます。プロポーショナル編集にしていないから当たり前です。

# プロポーショナル in オブジェクトモード

　次に、オブジェクトモードでプロポーショナル編集を有効にしてみます。

```python
obj = bpy.context.object
msh_name = obj.to_mesh().name
msh = bpy.data.meshes[msh_name]
vts = msh.vertices
vts_size = len(vts)
bpy.context.tool_settings.use_proportional_edit_objects = True #追加
for i in range(10):
    idx = random.randint(0,vts_size-1)
    vts[idx].co.z += 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/acb2c756-de44-ae8d-0344-fb17936f6159.png)

　プロポーショナル編集マークはアクティブになりますが変化なしです。実はこれは、オブジェクトの拡大とか回転とかをプロポーショナルに伝播させるための機能で、頂点編集とは関係ないのでした。

# 編集モード

　やはり編集モードで頂点を編集する必要があります。以下のようなコードに修正します。

```python
import bpy
import bmesh
import random

bpy.ops.object.mode_set(mode='EDIT', toggle=False)
obj = bpy.context.object
meshdata = bmesh.from_edit_mesh(obj.data)
verts = meshdata.verts
size = len(verts)
bpy.context.tool_settings.use_proportional_edit = True
for i in range(10):
    idx = random.randint(0,vts_size-1)
    verts[idx].select_set(True)
    bpy.ops.transform.translate(value=(0,0,.5))  
    verts[idx].select_set(False)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/d5a4b5de-9346-96a5-6fab-f6522925759b.png)

　！？

　それでもプロポーショナル編集は反映されません。マークは有効になっているのに。

# 結論

　`tool_settings`の設定は**全く関係なく**、`translate`の引数の中にプロポーショナル編集を使うことを明示する必要があります。公式ドキュメントは[こちら](https://docs.blender.org/api/current/bpy.ops.transform.html?#bpy.ops.transform.translate)。

```python
import bpy
import random
import bmesh

bpy.ops.object.mode_set(mode='EDIT', toggle=False)
obj = bpy.context.object
meshdata = bmesh.from_edit_mesh(obj.data)
verts = meshdata.verts
size = len(verts)
# bpy.context.tool_settings.use_proportional_edit = True #全くの無意味
for i in range(10):
    idx = random.randint(0,vts_size-1)
    verts[idx].select_set(True)
    bpy.ops.transform.translate(value=(0,0,.5),use_proportional_edit=True,proportional_size=0.5)  
    verts[idx].select_set(False)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/96ecfae0-bf07-4103-3e2d-0338f60c1b45.png)

　これでやっとスクリプトによるプロポーショナル編集ができました。
AWS EC2にVSCodeでRemote-SSH接続(Windows)

AWS EC2インスタンスにTera Termではなく、VScodeで接続
とても簡単で、これするだけでGUIで感覚的な操作ができます。

EC2 OSはAmazon Linux 2の場合ユーザ名は「ec2-user」です。
（そのほかのOSのEC2の場合はAWSのリファレンスを確認）


#手順
* VScodeで拡張機能「Remote-SSH」インストール
* VScodeウィンドウの左に「リモートエクスプローラー」のアイコンが現れるのでクリック
* プルダウンで「SSH Targets」を選択
* 歯車アイコンをクリック
* 「C:\Users\[ユーザ名]\.ssh\config」　を選択
* 以下を入力して保存

 ```
Host (任意)
HostName [EC2パブリックアドレス]
Port 22
IdentityFile [pemキーのパス]
User ec2-user
```


* VSCodeウィンドウ左下の緑色の"><"ボタンを押す
* 表示されたメニューから「Connecto to Host...」を選択
* configに入力したHost名を選択「ec2」
* Select the platform of the remote host "ホスト名"と聞かれたら「Linux」を選択
* 初回接続で「Continue」と「Cancel」が聞かれたら、「Continue」を選択
* 「フォルダ開く」を選択してEC2上の好きなフォルダを選択
* これだけでGUIの操作ができます
【成果物】旅日記

初投稿です。
html、css、Bootstrapを使用したLP形式での広島の紹介ページを作成しました。
Web制作について独学で勉強し始め、初めての成果物です。
いわゆるポートフォリオとは異なりますが、何か感想等いただけたら嬉しいです。

▼リンク
http://www.tamari-web.site/
コードリーディングを視覚的に助けるVimの機能やプラグイン

この変数ってなんだっけ。この関数はどこから呼ばれているんだっけ。

脳のスタックには限度がありますし、そう簡単に鍛えられるものでもありません。

この記事では、普段のコードリーディングを少しでも楽にするために利用している、コードリーディングを視覚的に助けるVimの機能やプラグインを紹介します。

まずはVimの標準機能でできることから。

## シンタックスハイライト

それはそう。それはそうなんですが、シンタックスハイライトは普通に大事です。

お気に入りのカラースキームを使えば良いと思います。個人的にはIcebergが好きです。

https://github.com/cocopon/iceberg.vim

## folding

折りたたみ機能ですね。

必要な情報を強調するのも大事ですが、余計な情報は見ないというのも大事です。

コードの概要を俯瞰したいとき、たとえば同階層のテストケースを一覧で見たいときなどでも重宝します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694808/eff01152-31a6-9511-ca77-de6ff58f17ab.png)

`zm`で折りたたみ。`zr`で開きます。

次はプラグインの紹介。

## vim-quickhl

単語に色を付けることができるプラグインです。

変数がどこで定義されたか、どこで使われたかが文字通りひと目で分かります。

色の情報は脳にダイレクトに届きますし、コードがどんどんカラフルになっていくのも楽しい。手放せないプラグインです。

https://github.com/t9md/vim-quickhl

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694808/322b2108-3468-d7a7-9612-9c4185286236.png)

`Space h` でノーマルモードではカーソル下の単語を、ビジュアルモードでは選んでいる箇所を色付けできるように設定しています。

```toml:dein.toml
[[plugins]]
repo = 't9md/vim-quickhl'
hook_add = '''
  nmap <Space>h <Plug>(quickhl-manual-this)
  xmap <Space>h <Plug>(quickhl-manual-this)
  nmap <Space>H <Plug>(quickhl-manual-reset)
'''
```

## vim-brightest

カーソル下の単語と同じ単語に下線を引いてくれるプラグインです。

「カーソル位置から離れた場所で見た目の変化が起こる」というのは案外目立つもので、このプラグインを入れておくだけで変数の流れがだいぶ追いやすくなります。

https://github.com/osyo-manga/vim-brightest

日本語の箇所では動作してほしくないのでちょっとだけ設定。

```toml:dein.toml
[[plugins]]
repo = 'osyo-manga/vim-brightest'
hook_add = '''
  let g:brightest#highlight = { "group" : "BrightestUnderline" }
  let g:brightest#pattern = '\k\+'
'''
```

## vim-signature

Vimにはコードの行に印を付けておくマーク機能が標準で備わってるのですが、このプラグインはそれを使いやすくしてくれます。

付けたマークが左に表示されるようになり、付けるマークを自動でABC順にすることもできます。

関数呼び出しの場所や順番のメモとして使っています。

https://github.com/kshenoy/vim-signature

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694808/76966429-17ad-362f-ae78-58cc865bed30.png)

`Space m`でABC順にマークの付け外しができるようにして使っています。

```toml:dein.toml
[[plugins]]
repo = 'kshenoy/vim-signature'
hook_add = '''
  let g:SignatureMap = { 'Leader' : "m", 'PlaceNextMark' : "", 'ToggleMarkAtLine' : "<Space>m", 'PurgeMarksAtLine' : "", 'DeleteMark' : "", 'PurgeMarks' : "", 'PurgeMarkers' : "", 'GotoNextLineAlpha' : "", 'GotoPrevLineAlpha' : "", 'GotoNextSpotAlpha' : "", 'GotoPrevSpotAlpha' : "", 'GotoNextLineByPos' : "", 'GotoPrevLineByPos' : "", 'GotoNextSpotByPos' : "", 'GotoPrevSpotByPos' : "", 'GotoNextMarker' : "", 'GotoPrevMarker' : "", 'GotoNextMarkerAny' : "", 'GotoPrevMarkerAny' : "", 'ListBufferMarks' : "", 'ListBufferMarkers' : "" }
  let g:SignatureIncludeMarks = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
'''

```

## おわりに

脳に優しいコードリーディングを!

オススメの機能やプラグインがあったらコメントにて教えてもらえると滅茶苦茶助かります。