OmniAICreator/Qiita-1.07M huggingface dataset:
学習記録（１日目）

# 今日からプログラミングの学習内容を記録していきます
学習内容を記録しようと思った理由は以下の３つです。  
    1. アウトプットを意識することによって日々のプログラミング学習を効率よくするため
    2. 過去に学習した内容を自分で見返せるようにするため
    3. 日毎に記録することによって学習を継続的に行うため

# 学習内容
* Qittaの記事の書き方
* Pythonの基礎
* Pythonによる簡単なスクレイピング

## Qittaの記事の書き方
GitHubである程度経験のあるMarkdown記法だったので復習程度に記法を確認しました。
今回は最初の記事なので、できるだけ多くの記法を活用して記述しました。

## Pythonの基礎
Pythonの初心者でありながら、いきなりスクレイピングを始めるのはどうかと思いました。が、大学で二年間プログラミングを学んでいて変数がどうの、関数がどうの、分岐が・・・などと一から勉強すると煩わしくて続かなかったので、スクレイピングと機械学習をおかずにPythonの文法も同時に学習していくことにしました。以下、非常に基礎的な内容ですが今日学習したことをまとめます。

### コメントアウト  
経験のあるC,Java、Swiftとは異なるコメントアウトの記述法でした。

* 一行のコメントアウト  
`#`から始まる一行はコメントアウトされる。（`#`の後はスペースを一つ空けてからコメントを記述する）

##### 記述例
~~~python
# 一行のコメントアウト
~~~

* 複数行のコメントアウト  
`"""`（ダブルクォーテーション3つ）または`'''`（シングルクォーテーション3つ）で囲まれた部分は全てコメントアウトされる。

##### 記述例
~~~python
"""
    ダブルクォーテーションによる
    複数行のコメントアウト
"""

'''
    シングルクォーテーションによる
    複数行のコメントアウト
'''
~~~
  

### ループ処理
Javaの拡張for文と似た記述法
##### 記述例
~~~python
    num = [0, 1, 2, 3]

    # ループ文
    for a in num:
        print(a)
~~~
実行結果
>0
>1
>2
>3
>
>

### lambda式
Pythonにおいて、関数名は変数名と同様に扱われることを利用している。小さな関数を定義する際に便利。
##### 記述例
~~~python
bai_print = lambda x: print(x*2)

bai(2)
bai(10)
~~~
実行結果
>4
>20

### 

## Pythonによるスクレイピング
`urllib`を用いたスクレイピングを学習しました。
本日学んだurllibライブラリーにある関数とその使用例を以下にまとめました。

~~~python
import urllib.request as req
import urllib.parse as par

url = "https://uta.pw/shodou/img/28/214.png"
savename = "test.png"

# urlretrive(ファイルのURL,保存先のファイル名)
# Web上のファイルをダウンロードする関数
# https://uta.pw/shodou/img/28/214.pngにあるpngファイルがtest.pngという名前で保存される
req.urlretrive(url, savename)


# urlopen(ファイルのURL)
# URLリソースを開く関数、read()によってデータを読み込む
# Web上のファイルがPythonメモリ上に保存される
mem = req.urlopen(url).read()


# urlencode(URLへと変換するパラメータ)
# パラメータからクエリを作成してリクエスト用のURLを作成する
# https://api.aoikujira.com/zip/xml/get.php?fmt=xml&zn=1500042というURLが生成される
API = "https://api.aoikujira.com/zip/xml/get.php"

values = {
    'fmt' = 'xml'
    'zn' = '1500042'
}
params = par.urlencode(values)

url = API + "?" + params
~~~

## まとめ
今回は初めて記事を書くということで様々な記法を活用して記述したが、そこそこ時間がかかってしまい時間がもったいないので明日以降は学習記録にとどまる範囲で簡潔に書いていこうと思う。
Rustで整数リテラルを使うときは、できるだけ型を指定した方が良さそう

競技プログラミングを想定して書いていますが、他でもハマる可能性はあるかもしれません。

# Rustのデフォルト整数型

Rustのデフォルトの整数型は`i32`になっているようです。

https://doc.rust-lang.org/book/ch03-02-data-types.html
> integer types default to i32

以下のコードで試してみることもできます。
（`print_typename`については https://qiita.com/garkimasera/items/729dbf11dd5738c70e11 を参考にしました）

```rust
fn main() {
    let m = 0usize;
    print_typename(m);

    let n = 0;
    print_typename(n);
}

fn print_typename<T>(_: T) {
    println!("{}", std::any::type_name::<T>());
}

```

出力：

```
usize
i32
```

# 競プロの場合

32ビットの上限は、符号なしの場合で4 * 10^9程度なので、競プロで扱う数の大きさだと容易にあふれます。

さらに`cargo run`デバッグビルドしている場合はオーバーフローをチェックしてくれますが、リリースビルドではチェックしてくれません。
そのため以下のコードは`cargo run --release`で実行すると`-2147483648`を出力し、終了ステータスも0（正常終了）となります。

```
fn main() {
    let l = std::i32::MAX;
    println!("{}", l + 1);
}
```

AtCoder上の表示もREではなくWAとなります。気をつけましょう。

# 結論

できるだけ、変数に型アノテーションをつけるか`0usize`などとしましょう。
【Ruby on Rails && SQL】アソシエーションで子要素を持つ親要素だけ取得したい場合

子要素を持つ親要素だけ取得したい場合、SQLによる抽出が必要となる。
Railsでは何気なくuser.productsなど取得しているが、これはRailsがSQLの記述を省略しているにすぎない。複雑になれば、SQLは必要となる。

## 本題
子要素を持つ親要素のみ取得したい場合どうすればいいでしょうか？？
何気にわからないと思います。

親要素：User
子要素：Product

productを持つUserだけ取得したい場合、下記になります。

```ruby:子要素を持つ親要素だけ取得１
User.joins(:products).preload(:products)
```
この処理だとSQLとしては下の処理がされます。

```sql:
User Load (3.2ms)  SELECT `users`.* FROM `users` INNER JOIN `products` ON `products`.`user_id` = `users`.`id`
```
`products`.`user_id` = `users`.`id`で成立するレコードだけを残します。
つまり、productを持たないuserは除外されます。


## class_nameでカラムを定義している場合
class_nameでカラム名をuser_id定義しておらず、buyer_idと定義している場合は下記になります。


```ruby:子要素を持つ親要素だけ取得する
User.joins('LEFT JOIN Products ON users.id = products.buyer_id').where('products.id IS NOT NULL').uniq
```


[【INNER JOIN, LEFT JOIN , RIGHT JOIN】テーブル結合の挙動をまとめてみた【SQL】](https://qiita.com/ngron/items/db4947fb0551f21321c0)
[Rails における内部結合、外部結合まとめ](https://qiita.com/yuyasat/items/c2ad37b5a24a58ee3d30#1-1-joinsselect%E3%81%AA%E3%81%97%E3%82%92%E4%BD%BF%E3%81%86)
[ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い](https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58)
[参考ページ]
(https://q.hatena.ne.jp/1418825151)
[一番参考になるページ](https://qiita.com/tomomomo1217/items/1ccd21bfb97730763255#%E5%AD%90%E3%83%A2%E3%83%87%E3%83%AB%E5%AD%AB%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E7%B5%90%E5%90%88%E3%81%A8%E7%B5%9E%E8%BE%BC%E3%82%92%E3%81%86%E3%81%BE%E3%81%84%E3%81%93%E3%81%A8%E3%82%84%E3%82%8B)
Codeforces Round #626 Div1. A. Unusual Competitions : 括弧

https://codeforces.com/contest/1322/problem/A

# 題意
- ()で構成される文字列を正しく直せ(直せないなら-1を述べよ)
- 直し方はある位置iから位置jの文字列を入れ替えることが出来る。この場合、コストj-iがかかる。
- 最小のコストの合計を述べよ

# 考えたこと
$()$の問題を考えるときには、$)$に対して$($が不足しているかをカウントすることが多い。今回もそのアプローチで考える。(で+1, )で-1するカウントを考えると、
$))((())( -> [-1, -2, -1, 0, 1, 0, -1, 0] $
となる。思うに、)が不足する場合、最も近い(をその)の前に持ってくるのが最適となる。こう考えると、

```
))((())(
^^^^  ^^
```

この区間で文字列を並び替えられれば良い。その文字を読み込んだ瞬間にカウンタが負であれば、並び替えが必要な区間として処理する。実装としては各マスに1をたて、最後にsumをする。

# コード
```Python
n = int(input())
s = input()
c1 = s.count("(")
c2 = s.count(")")
if c1 != c2:
    print(-1)
else:
    need = [0] * n # 並び替えが必要な区間カウンタ
    cnt = 0
    for i in range(n):
        if cnt < 0:
            need[i] = 1
        if s[i] == "(":
            cnt += 1
        elif s[i] == ")":
            cnt -= 1
        else:
            print("error")
        if cnt < 0:
            need[i] = 1
    print(sum(need))

```
https://codeforces.com/contest/1323/submission/72648743
konfig + kubectx でk8sのconfigを管理する

複数のクラスタがあると、pyenvやanacondaみたいな環境切り替え機能が欲しい。

# 概要

まず、複数のconfigを下記のように配置します：

```
~/.kube/
 ├── cache
 │   └── ...
 ├── config
 └── custom-contexts
     └── clusterA
         └── config
     └── clusterB
         └── config
```

すると、konfigというプラグインで新configを簡単に追加します。

```
kubectl konfig import -s ~/.kube/custom-contexts/clusterA/config
```

環境の確認：

```
$ ~ kubectx
default
clusterA
clusterB
```

環境の切り替え：

```
$ ~ kubectx clusterA
```

一つ前の環境に戻る：

```
$ ~ kubectx -
```

# インストール手順

## krewをインストール

https://krew.sigs.k8s.io/docs/user-guide/setup/install/

krewは kubectl のプラグインマネージャーです。

krewの解説：

[地球上の Kubernetes ユーザーは絶対使うべきツールたちを紹介するよ](https://qiita.com/kamina_zzz/items/b5eedfe4a34c8d01d5f6)
[kubectl のプラグイン機能 kubectl plugin を使おう！](https://qiita.com/superbrothers/items/b4a0aab0575ca6d65739)


## kubectxをインストール


https://github.com/ahmetb/kubectx

krewを使わずという点で要注意。
psql(Redshift)チート集

psqlに関するチート集。
よく忘れるものを備忘録として記録。適宜追加予定。
psqlと言いつつ、基本的にredshiftでしか動作確認していないので悪しからず。

#メモ
###基本
1. 大文字と小文字は区別されない
2. 数値からはじまるテーブル名は許容されない
3. 整数同士での除算で小数点以下の精度が欲しいならば、castするのを忘れない

###クエリ評価順序
1. from
2. on
3. join
4. where
5. group by
6. having
7. select
8. distinct
9. order by
10. top(limit)


#型変換
```
-- 好みによるのかもしれないが、コロンで書く方が楽だし見やすい
cast(column as type)
column::type
```
#日時関連
###現在時刻取得
```
-- 日本標準時で時刻取得
convert_timezone('JST',getdate())
```
###週数

```
-- 1. ISO準拠(月曜始まり)での週数付与
to_char(datetime , 'IYYYIW')
-- 2. 週始まりの曜日は以下のようにずらす(e.g.木曜始まり週に変換する場合)
to_char(dateadd(day, -3, datetime)), 'IYYYIW')
```
#数値計算
### 縦持ちを横持ちに集計
```
sum(case when column='A' then num else 0 end) sum_A
sum(case when column='B' then num else 0 end) sum_B
sum(case when column='C' then num else 0 end) sum_C
```

### 累積計算
```
-- partion指定の列内で計算対象を区分、order by によって並び替えられた順に上から累積和を取る
sum(num) over(partition by [partition_columns] 
order by [order_coloumns] {asc|desc} rows UNBOUNDED PRECEDING)
```

#DDL
###基本
```
-- 1.テーブル削除
---- 基本（依存オブジェクトがあると削除されない）
drop table if exists table_name;
---- テーブルに依存するオブジェクトを自動的に削除
drop table if exists table_name cascade;

-- 2.テーブル作成
---- 正統派
---- 列に対して物理名と型と圧縮エンコードを指定
create table table_name
(
    id INTEGER ENCODE lzo
  , name VARCHAR(8) ENCODE lzo
  , PRIMARY KEY(id)
  , create_date timestamp default getdate()
)
{COMPOUND|INTERLEAVED} sort key([sort_columns])
DISTSTYLE{EVEN|ALL|KEY}
;
---- クエリから作成
create table table_name as ([query]);

```
###S3からデータ読み込み
```
-- 1. 基本
---- オブジェクト名は前方一致で読み込める、複数一致する場合は複数ファイルが読み込まれる
---- TRIMBLANKSオプションはVARCHAR文字列から末尾の空白文字削除
---- DATE/TIME FORMATオプションはデフォルト値を無駄に記載しているだけだが、
---- 書いて置くと忘れなくて済むので書いてる
COPY table_name
FROM 's3://bucket_name/prefix/object_name'
ACCESS_KEY_ID [acces key]
SECRET_ACCESS_KEY [secret access key]
REGION AS [region]
ENCODING AS UTF8
DATEFORMAT AS 'YYYY-MM-DD'
TIMEFORMAT AS 'YYYY-MM-DD HH:MM:SS'
TRIMBLANKS
EMPTYASNULL
DELIMITER ','
IGNOREHEADER 1
CSV GZIP
;

-- 2. テーブルの列数とロードするファイルの列数が異なる場合
---- テーブル作成日時など、default指定での列名がある場合、
---- 1.列名指定で回避
COPY table_name (id, name, )
from ...
;
---- 2. テーブル複製により回避
create table table_tmp ( LIKE table_name);
alter table table_tmp drop column ([drop column]);
COPY table_tmp
from ...
;
INSERT INTO table_name SELECT * FROM table_tmp;
DROP TABLE table_tmp;

---- 3. 読み込むデータの前処理
---- bomなしのutf-8でないと読み込めないので、そうでなければ以下で変換
---- 3-1. linux(bash)
nkf -w data > data_utf8
---- 3-2. windows(Powershell)
$file = Get-Content $file_path 
$file | Set-Content -Encoding UTF8 $file_path
```
omniauthを使った認証時にsessionが消える時の対処法

# 事象
auth0とomniauthを利用して認証処理を作成した。
omniauthの以下のフローがあるが、2の時点では保持しているsessionが、3になるとnilとなってしまい、ログインできないという事象が発生した。
1. プロバイダー側で認証後、railsアプリケーションのcallback関数呼び出し
2. callback関数で諸々処理し、画面にredirect
3. 画面に対応するcontrollerで処理後、画面表示

さらに、ログインできたアカウントが一つ、ログインできなかったアカウントが3つという状態もあり、原因特定に時間がかかった。

# 環境
- Ruby 2.7.0
- Rails 6.0.2.1
- omniauth 1.9.0
- omniauth-auth0 2.2.0
- omniauth-rails_csrf_protection 0.1.2

# 原因
結論から言うと、`3. 画面に対応するcontrollerで処理後、画面表示`の段階で、cookieに保存していたsessionが4KBを超えてしまい、sessionが削除されてしまったのが原因。

[チュートリアル](https://auth0.com/docs/quickstart/webapp/rails)にある以下のcallback関数で、sessionにrequest.env['omniauth.auth']を保存していたが、これだとサイズがわずかに大きかった。4人中3人が4KBをオーバーし、1人がオーバーしていなかった。

```auth0_controller.rb
  def callback
    # This stores all the user information that came from Auth0
    # and the IdP
    session[:userinfo] = request.env['omniauth.auth']

    # Redirect to the URL you want after successful auth
    redirect_to '/dashboard'
  end
```

#対応
`request.env['omniauth.auth']`の`info`だけをsessionに保持させるように修正した。

```auth0_controller.rb
  def callback
    # This stores all the user information that came from Auth0
    # and the IdP
    session[:userinfo] = request.env['omniauth.auth']['info']

    # Redirect to the URL you want after successful auth
    redirect_to '/dashboard'
  end
```

# 参考
https://stackoverflow.com/questions/18422182/rails-sessions-not-saving/18576525#18576525
AWS CLI

- [AWS CLI](https://docs.aws.amazon.com/cli/latest/index.html)
 - [コンフィグ](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/configure/index.html)

```
# aws configure
AWS Access Key ID [None]: アクセスキー  
AWS Secret Access Key [None]: シークレットアクセスキー  
Default region name [None]: ap-northeast-1 <- (東京)  
Default output format [None]: json
```  

- EC2
 - 起動
 - [開始](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/start-instances.html)  
`aws ec2 start-instances --instance-ids "インスタンスID"` 

 - [インスタンス開始待ち](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/wait/instance-running.html)  
`aws ec2 wait instance-running --instance-ids "インスタンスID"`  
上記コマンドでは初期化中に返ってくるので以下のコマンドであれば初期化完了状態になるまで待つ(当然、時間はかかる)  
`aws ec2 wait instance-status-ok --instance-ids "インスタンスID"`  
["aws EC2 wait" による処理待ちステータスの一覧](https://awsjp.com/AWS/Faq/c/aws-EC2-wait-status-list-6B50.html)
 - [停止](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/stop-instances.html)  
`aws ec2 stop-instances --instance-ids "インスタンスID"`
 - [停止待ち](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/wait/instance-stopped.html)  
`aws ec2 wait instance-stopped --instance-ids "インスタンスID"`  
 - [状態確認](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/describe-instance-status.html)  
`aws ec2 describe-instance-status --instance-ids "インスタンスID"`
 - [インスタンスリスト](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ec2/describe-instances.html)  
`aws ec2 describe-instances`

- key pair
 - linuxからの接続  
Linux コンピュータからインスタンスに接続の場合は、使用してプライベートキーファイルのアクセス許可を設定する  
`$ chmod 400 MyKeyPair.pem`
活動記録(2020.3.8)

#今週やった事
・平日は繁忙期の残業続きによりあまり進まず…
移動中や休み時間はDocker周りの資料に目を通す等していた。
・Udemy『もう怖くないGit！チーム開発で必要なGitを完全マスター』をサクッと終える。Git、GitHub周りの不安感がかなり払拭された。
Qiitaにまとめながら講座を進めたのでそれなりに定着したと思う。
・ポートフォリオ案を思い付く。
→稟議書承認機能を持たせた社内SNS。Slack等に通知を飛ばせるよう連携予定

#課題・不明点
・ルート、ポート、DNS等ネットワーク周りの知識が弱い→基本情報技術者テキスト
・Docker→入門（入門、Qiita記事、日本語ガイド）を繰り返し読みつつひとまずポートフォリオ開発に着手する
・GemはBootstrapでOK？
・SQL周りの知識
・AWS→公式チュートリアル読む
・Golangも勉強したいけどまずRubyでのポートフォリオを一旦完成させないといけないし課題が山積み…
（後回し：CircleCI、Terraform）
VirtualBox に各種OSをインストールする

# virtualboxに各種OSの仮想マシンを作成する
- [virtualbox](https://www.virtualbox.org/)をダウンロードする
![virtualbox_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/fbf872c9-83a5-ecc7-f4a2-977dfc7a6e2c.png)
- virtualboxをローカルにインストールする
![virtualbox_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/723f04d8-9bf0-22be-8d84-c81f11947d35.png)
- virtualboxを起動して仮想マシンを作成する
![virtualbox_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/c77a5d04-508f-10da-4caa-7e25249025da.png)
- 各OSのイメージ（isoファイル）をダウンロードする
![virtualbox_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/8dc70d7a-06fd-11b6-9d69-eebe782d8a6b.png)
- 光学ドライブにマウントして各種OSをインストールする
![virtualbox_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/11138fcd-3a7e-c045-1983-5b54545b759a.png)

- macOsのみ特殊です。
下記のコマンドはCMD端末に実行必要。
```
cd "C:\Program Files\Oracle\VirtualBox\" 
VBoxManage.exe modifyvm "mac1013" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff
VBoxManage setextradata "mac1013" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac11,3"
VBoxManage setextradata "mac1013" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0"
VBoxManage setextradata "mac1013" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple"
VBoxManage setextradata "mac1013" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
VBoxManage setextradata "mac1013" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1
```
pipがSSL関係で止まったらpython自体を入れ直すのが良い

#brewが原因ではない

pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

これを見てぐぐるとBrew を入れ直せば良いという記事が出てきますが、僕の環境では治りませんでした。
さいわいpyenvを使っていたので別のバージョンのpythonを使ったところ無事にpipが動く様になりました。

よくわからんけどまあ。。
バーチャルパッドアセット『Joystick Pack』で初回タッチ時のみ描画がズレてしまう

バーチャルパッドを簡単に導入できるアセット、[『Joystick Pack』](https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631)。

Fixed Joystick、Floating Joystick、Dynamic Joystick の3つのタイプのバーチャルパッドを導入できます。 が、**Floating Joystick** を **CanvasのRenderModeがScreenSpaceCamera** の時に使用すると、初回のタッチ時にパッドの描画位置がズレます。（Joystick Pack Version2.1）

パッドの描画位置算出時に使用する、カメラの参照がnullであるために起こるようなので、OnDrag内でカメラオブジェクトを取得している部分を、Start内に移動させることで対応できました。

```csharp:Joystick.cs
    protected virtual void Start()
    {
        HandleRange = handleRange;
        DeadZone = deadZone;
        baseRect = GetComponent<RectTransform>();
        canvas = GetComponentInParent<Canvas>();
        if (canvas == null)
            Debug.LogError("The Joystick is not placed inside a canvas");

        Vector2 center = new Vector2(0.5f, 0.5f);
        background.pivot = center;
        handle.anchorMin = center;
        handle.anchorMax = center;
        handle.pivot = center;
        handle.anchoredPosition = Vector2.zero;

+        cam = null;
+        if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
+            cam = canvas.worldCamera;
    }

    public void OnDrag(PointerEventData eventData)
    {
-        cam = null;
-        if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
-            cam = canvas.worldCamera;

        Vector2 position = RectTransformUtility.WorldToScreenPoint(cam, background.position);
        Vector2 radius = background.sizeDelta / 2;
        input = (eventData.position - position) / (radius * canvas.scaleFactor);
        FormatInput();
        HandleInput(input.magnitude, input.normalized, radius, cam);
        handle.anchoredPosition = input * radius * handleRange;
    }
```
あたまのなかの整理メモ(Java - インスタンス編)

## My Java環境

* java11

## static

* `static`なフィールドは、インスタンスを生成しなくても使用できる
* `クラス名.フィールド名`または、インスタンス生成後に`インスタンス名.フィールド名`で使用する
* `static`なメソッドから`static`ではないフィールドやメソッドにはアクセスできない(`static`なメソッドからは`static`なフィールドやメソッドにしかアクセスできない)
* `static`ではないメソッドから`static`なフィールドやメソッドにはアクセスできる


## メソッドの戻り値

* メソッドの戻り値は`戻り値と同じ型`または`互換性のある型`である必要がある。

## 可変長引数

* 引数の数を自由に変更できる引数のこと。JVMによって配列に置き換えられる。
* 引数の型の直後にピリオド3つ`...`をつけて宣言する。

```java

public static void main(String... args) {
    // 処理
}
```

* 可変長引数を最後の引数にする必要がある。

```java

public void method(String value, String... args) {  } // OK
public void method(String... args, String value) {  } // NG
```

## メソッドのオーバーロード

* メソッドの名前が同じ、引数が異なる(引数の数・型・並び順)

## コンストラクタ

* メソッド名をクラス名と同じにすること
* 戻り値は記述できない
* `new`したときにしか呼ばれない、呼べない
* アクセス修飾子はなんでもOK

## コンストラクタと初期化子`{}`

初期化子`{}`は、クラスブロック直下に記述する。コンストラクタが実行される前に実行される。

```java

public class Test {
    {
        // 初期化処理
    }
}
```

`static`初期化子もある。クラスがロードされたときに実行される。

```java

public class Test {
    static {
        // 初期化処理
    }
}
```

* デフォルトコンストラクタはコンストラクタを1つも定義しない場合に追加される。
* コンストラクタからオーバーロードされた別のコンストラクタを呼ぶときは`this(...)`を使用するが、使用する際は処理の1番最初に記述する必要がある。

## 修飾子

* public : すべてのクラスからアクセス可能
* protected : 同じパッケージと、継承しているサブクラスからアクセス可能
* (なし) : 同じパッケージのクラスからアクセス可能
* private : クラス内からのみアクセス可能

## メソッドの引数

* プリミティブ型をメソッドの引数に指定した場合は、メソッドにはコピーが渡される(メソッド内で値が変更されても、呼び出し元の値には影響しない。) 
* オブジェクト型をメソッドの引数に指定した場合は、メソッドにはインスタンスの参照(リンク)が渡される。(メソッド内で値が変更されたら、呼び出し元の値も変わる。)
Ansibleがメチャクチャ便利だった

## 初めて触るAnsible

複数のAWS EC2にOS初期設定を行う。お約束のことなので、できるだけ自動化したい。
AWSマネジメントコンソールにて複数のサーバを用意する必要があったので
構成管理ツールのAnsibleを使った。

## 手順

1. EC2セットアップ
2. pythonをインストール
3. awscliをインストール
4. ansibleをインストール
5. 初期設定ファイルを取得
6. 再起動

## EC2セットアップ

AWSマネジメントコンソールにてEC2をセットアップする。用意する際にAMIを指定するようにする。
バージョン等がずれると再度インストールしなおしになるためAMIで確認することをお勧めします。

今回はRHELをインストールしたかったので下記の方法でAMIを取得した
http://blog.serverworks.co.jp/tech/2019/06/18/post-71160/

## sshで接続できることを確認

EC2を構築する際にキーペアが発行される、
もしくは既存のキーペアを使ってssh接続できることを確認します。

## pythonをインストール

EPELリポジトリからpython3をyumでインストール
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-enable-epel/

```
$ sudo su -
$ yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ yum -y install python3
$ yum -y install python3-pip
$ pip3 install --upgrade pip
```

## awscliをインストール

https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html

```
$ sudo su -
$ pip3 install --upgrade awscli
```
## ansibleをインストール

```
$ pip3 install --upgrade ansible
$ mkdir -p /opt/ansible
```

## playbookを作成して実行

一から作るのは勉強になりますが、
今回は以下のリポジトリを参考にさせていただきました。
https://github.com/kouji-kojima/sample-ansible-el7-init

1. ホスト名
2. 時刻同期
3. タイムゾーン
4. 文字コード
などなど

```
$ ansible-playbook -i localhost site.yml --private-key=/path/key.pem -vvv
```

## 後処理

```
# epel無効化
$ sed -i 's/enabled=1/enabled=0/g' /etc/yum.repos.d/epel* 
$ systemctl restart sshd
# error確認
$ egrep -i "error|warning|fatal|fail" /var/log/messages
```

問題なければ、このイメージをコピーして配布する。
同一の設定のOSを複数セットアップする際にはめっちゃくちゃ便利です。

## 余談

EC2にはユーザーデータを利用することもできる。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html
AtCoder 日立製作所 社会システム事業部 プログラミングコンテスト2020 参戦記

# AtCoder 日立製作所 社会システム事業部 プログラミングコンテスト2020 参戦記

## [hitachi2020A - Hitachi String](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_a)

3分で突破. どう書くのが楽か戸惑ったけど、長さが10までなので、ありえる解答総当りが一番速いかとこうなった.

```python
S = input()

for i in range(1, 6):
    if S == 'hi' * i:
        print('Yes')
        exit()
print('No')
```

## [hitachi2020B - Nice Shopping](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_b)

8分で突破. B問題だから総当たりでいいかと思ったら、制限を見るに無理. ちょっと考えたけど、割引券が無ければ最小金額は min(a) + min(b) に決まってるので、後は割引券だけ総当りすればいいやとこうなった.

```python
A, B, M = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

result = min(a) + min(b)
for _ in range(M):
    x, y, c = map(int, input().split())
    t = a[x - 1] + b[y - 1] - c
    if t < result:
        result = t
print(result)
```

## [hitachi2020C - ThREE](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_c)

敗退. 書くだけは書いたけど、7割型 TLE な上に WA も食らったので残り1時間くらい残して心が折れました(笑).
jsonnetを使ったCloudFormationのパラメータ管理

CloudFormationは、awscliでのデプロイ時にパラメータを指定することができます。
以下のような感じです。

```bash
aws cloudformation deploy \
  --template-file template.yaml \
  --stack-name hoge \
  --parameter-overrides \
    Param1=hoge \
    Param2=fuga
```

普段は、環境変数で上書きできるようにした上で stagingやproductionとうの環境によってパラメータを設定していたのですが、パラメータが増えてきて、deployようのシェルが肥大化してきて管理が辛くなってきました。
そこで、パラメータをjsonで管理するようにしてみました。
ただ、単純なjsonとすると、環境によって似たような値だったり、共通するものが散らばってしまうので、これを機に [jsonnet](https://jsonnet.org/)で管理するようにしてみました。

# ディレクトリ構成

```
<root>
├── bin
│   └── deploy.sh
├── template
│   └── pipeline.yaml
└── params
    ├── pipeline.jsonnet
    ├── production
    │   └── pipeline.jsonnet
    └── staging
        └── pipeline.jsonnet
```

```jsonnet:params/pipeline.jsonnet
local github_token = std.extVar('GITHUB_TOKEN');
{
  GitHubOwner: 'imishinist',
  GitHubRepo: 'hogehoge',
  GitHubToken: github_token,
  VPCStackName: '%s-vpc' % [self.Stage],
}
```

```jsonnet:params/production/pipeline.jsonnet
{
  Stage: 'production',
  GitHubBranch: 'develop',
} + import '../resource.jsonnet'
```

このようにパラメータ用のjsonnetファイルを用意しておけば、以下のコマンドでjsonを出力することができます

```bash
$ jsonnet -V GITHUB_TOKEN=hogehoge params/production/pipeline.jsonnet
{
   "GitHubBranch": "develop",
   "GitHubOwner": "imishinist",
   "GitHubRepo": "hogehoge",
   "GitHubToken": "hogehoge",
   "Stage": "production",
   "VPCStackName": "production-vpc"
}
```

# デプロイ
あとは、jqを使って適当に加工します

```bash:bin/deploy.sh
#!/bin/bash

export GITHUB_TOKEN

params=$(jsonnet -V GITHUB_TOKEN=$GITHUB_TOKEN params/production/pipeline.jsonnet \
  | jq -r 'to_entries | map(.key + "=" + (.value | tostring) | @sh) | join(" ")')

aws cloudformation deploy \
  --template-file template.yaml \
  --stack-name hoge \
  --parameter-overrides "$params"
```

パラメータの中に改行が含まれるときのために、 `@sh` を使って、escapeしています。


# 小話
調べてなかったので知りませんでしたが、 cloudformationでは、deployじゃなく、create-change-setを使えば、`--parameters`オプションでjsonを直接渡せるようです。
そのフォーマットが以下のような形のようです。
以下の形に合わせてパラメータファイルを管理するか、上記の形で管理した上で、jqで加工して使うと良さそうです。

```json
[
  { "ParameterKey" : "GitHubToken", "ParameterValue" : "hogehoge" }
]
```

```bash:例
$ jsonnet -V GITHUB_TOKEN=hogehoge params/production/pipeline.jsonnet | jq -r 'to_entries | map({ ParameterKey: .key, ParameterValue: .value })'
[
  {
    "ParameterKey": "GitHubBranch",
    "ParameterValue": "develop"
  },
  {
    "ParameterKey": "GitHubOwner",
    "ParameterValue": "imishinist"
  },
  {
    "ParameterKey": "GitHubRepo",
    "ParameterValue": "hogehoge"
  },
  {
    "ParameterKey": "GitHubToken",
    "ParameterValue": "hogehoge"
  },
  {
    "ParameterKey": "Stage",
    "ParameterValue": "production"
  },
  {
    "ParameterKey": "VPCStackName",
    "ParameterValue": "production-vpc"
  }
]
```
Pythonで日立製作所 社会システム事業部 プログラミングコンテスト2020を解きたかった

### はじめに
こんばんは、tax_freeです。前回のABC(ABC157,158)は忘れていて参加できませんでした。もったいない。
今回は、ARC相当のコンテストでした。私は、A,Bの二つしか解けませんでした。とても悔しい。

###A問題
[問題](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_a)

**考えたこと**
最初は問題文を読み間違えていて3WAも出してしまいました。今回の敗因はここ。
問題文の**'hii'はhitachi文字列ではありません**を完全に読み落していました。
最初は、'hi'が含まれていればよいと思ったので

```
'hi' in [文字列]
```
でif文にかけていました。
それだけでは、'hii'に対応できないので改善しました。

```python
s = str(input())

checker = True
if 'hi' not in s:
    checker =False

while 'hi' in s:
    s = s.replace('hi','XX')

for i in range(1,len(s)-1):
    if s[i] =='X':
        if s[i-1] == 'i' or s[i-1] == 'h'or s[i+1] == 'i' or s[i+1] == 'h':
            checker = False
            break

if checker:
    print('Yes')
else:
    print('No')
````
前後の文字まで判別してACが出ました。
A問題だからと油断していました。

###B問題
[問題](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_b)

**考えたこと**
今までの最小金額と今の最小金額を比べて更新していけばいいじゃんという指針で解きました。

```python
a, b, m = map(int,input().split())
a_l = list(map(int,input().split()))
b_l = list(map(int,input().split()))
m_l = []
for i in range(m):
    m_l.append(list((map(int,input().split()))))

m_l.sort(key=lambda x: x[2])
a_l_s = sorted(a_l)
b_l_s = sorted(b_l)
ans = a_l_s[0] + b_l_s[0]

for j in range(m):
    price = a_l[m_l[j][0]-1] + b_l[m_l[j][1]-1] - m_l[j][2]
    if price < ans:
        ans = price

print(ans)
```
多次元配列のsortの仕方を毎回忘れてしまうので、覚える。

###解けなかったD問題
[問題](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_d)

**考えたこと**
与えられている時間$t$内であればいいので、whileで回せばいいのではと思い書いた。TLEだけでなくWAも出てきたので、指針が間違えている。~~最後はやけくそになって3回くらいsubmitしてた~~

###まとめ
少しでも競プロから離れていると、すぐに解けなくなることを実感した。学校が休みになったので競プロの勉強もします。
おやすみなさい
【MySQL】うるう年を判定するストアドファンクション

# はじめに

以前は業務でMySQLを使うことが多かったですが、最近はご無沙汰しているので、ちょっとしたリハビリにMySQLのストアドファンクションを作ってみました。

専用のテーブルを用意するのはちょっと面倒だったので、今回はテーブルが不要で作れる「うるう年の判定処理」を題材にしてみました。

# 作成したSQL

* 引数には、うるう年であるかを判定したい西暦年（4桁）を指定します。
* 戻り値は、引数の西暦年がうるう年であれば1、うるう年でない場合は0を返します。

```sql:うるう年を求めるストアドファンクション
DELIMITER //
​
/*
 うるう年であるかを判定する関数。
 year：4桁の西暦年
 return：うるう年であれば1、それ以外の年は0を返す。
 */
CREATE FUNCTION is_leap_year(year INT) RETURNS BOOLEAN DETERMINISTIC
BEGIN
  DECLARE result TINYINT;
  set result = 0;
  
  IF MOD(year, 4)=0 AND MOD(year, 100)<>0 THEN
    SET result=1;
  ELSEIF MOD(year, 400)=0 THEN
    SET result=1;
  END IF;
  
  RETURN(result);
END;
//
​
DELIMITER ;
```

# 実行結果

```sql:実行結果
mysql> select is_leap_year(2019);
+--------------------+
| is_leap_year(2019) |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)

mysql> select is_leap_year(2020);
+--------------------+
| is_leap_year(2020) |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.01 sec)

mysql> select is_leap_year(2021);
+--------------------+
| is_leap_year(2021) |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)
```

# 参考URL

* [【MySQL】ストアドプロシージャー①](https://qiita.com/chihiro/items/5d438549b5869900abdd)
* [初心者からのMySQLストアドプロシージャ＆ファンクション入門](https://proengineer.internous.co.jp/content/columnfeature/7078)
* [SQL if文のサンプルコード集 NULL判定や、Switch文のような分岐をする方法](https://style.potepan.com/articles/15273.html)
* [MySQL 5.6 リファレンスマニュアル - CREATE PROCEDURE および CREATE FUNCTION 構文](https://dev.mysql.com/doc/refman/5.6/ja/create-procedure.html)
送信ドメイン認証技術についておさらい

令和元年度　秋期
情報処理安全確保支援士　午後1　問1より

業務上絡むことの少なかったメールに関する問題
まとめて勉強するにはちょうどいい問題だったのでおさらい。

電子メールのセキュリティの送信ドメイン認証技術に関しての整理。

###### SPF（Envelope-FROMのドメインを認証）

- 効能：なりすまし

- 送信側の成立条件：送信元のメールドメインを管理するDNSにSPFレコードが設定されていること

- 受信側の成立条件：受信側のメールサーバがSPF対応していること

- 処理の流れ
  - 送信メールサーバから受信メールサーバにメールが到達
  - 受信メールサーバはドメインのDNSにSPFレコード問い合わせ
  - SPFレコードと送信メールサーバのIPアドレスが一致していることを確認【認証完了】

[送信ドメインを認証するためのSPFレコードに詳しくなろう](https://sendgrid.kke.co.jp/blog/?p=3509)

###### DKIM（Header-FROMのドメインを認証）

- 効能：メールヘッダ・メール本文の改ざん防止、なりすまし

- 送信側の成立条件：送信元のメールドメインを管理するDNSに公開鍵が設定されていること

- 受信側の成立条件：受信側のメールサーバがDKIMを対応していること

- 処理の流れ
  - 送信メールサーバでは電文を秘密鍵で暗号化
  - 送信メールサーバで暗号化したメールが受信メールサーバに到達
  - 受信メールサーバはドメインのDNSに公開鍵の取得要求
  - 受信メールサーバは取得した公開鍵で送信メールを検証【認証完了】

参考：[DKIMとは？](https://sendgrid.kke.co.jp/blog/?p=2044)

###### DMARC

- 効能：送信側(DMARCレコードを設定する側)が認証失敗時の受信可否をコントロールできる

- 送信側の成立条件：送信元のメールドメインを管理するDNSにDMARCの設定されていること

- 受信側の成立条件：受信側のメールサーバがDMARCに対応していること

- 処理の流れ
  - メールの認証の仕組みは上記SPFやDKIM参照
  - ～認証失敗から～
  - 受信メールサーバはドメインのDNSにDMARCレコード問い合わせ（認証失敗したメールの取り扱いを確認（規定しない、受信しない、隔離））
  - DMARCレコードの指示に従いメールを処理
  - DMARKレポートを送信側の管理者に送信

参考：[DMARC関連技術の紹介](https://sendgrid.kke.co.jp/blog/?p=10342)

###### 用語

- エンベロープの送信者メールアドレス（Envelope-FROM）
- メールデータ内のメールヘッダで指定される送信者メールアドレス（Header-FROM）

- SPF（Sender Policy Framework）

- DKIM（DomainKeys Identified Mail）

- DMARC（Domain-based Message Authentication, Reporting, and Conformance）
ETロボコンシミュレータ 超音波センサー機能拡張

## はじめに
[ETロボコンシミュレータ](https://qiita.com/kanetugu2018/items/0e521f4779cd680dab18)の超音波センサーに機能拡張を行いました。

## 動作の前提事項
- ETロボコンシミュレータの環境構築すること
- ARM版マイコンシミュレータで動作させること

環境の構築方法については、以下を参照してください。

1. [TOPPERS/箱庭デモ ETロボコンシミュレータ](https://qiita.com/kanetugu2018/items/0e521f4779cd680dab18)
1. [ARM版マイコンシミュレータを Mac/Linux/Windows 環境で自作した話](https://qiita.com/kanetugu2018/items/14b42fbfcc690ca36580)

## 超音波センサの実装
```C#:UltrasonicSensor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UltrasonicSensor : MonoBehaviour
{
    private float contact_distance;
    public float distanceValue;
    // Start is called before the first frame update
    void Start()
    {
        contact_distance = 255;
    }

    // Update is called once per frame
    void Update()
    {
        //nothing to do
    }

    public void UpdateUltrasonicSensor()
    {
        this.distanceValue = contact_distance;
    }

    private void OnTriggerStay(Collider other)
    {

        GameObject FrontSensor = GameObject.Find("UltrasonicSensor");

        Vector3 Apoint = FrontSensor.transform.position;
        Vector3 Bpoint = other.gameObject.transform.position;

        // Distance between Sensor and Object
        contact_distance = Vector3.Distance(Apoint,Bpoint);
    }
}
```
Colliderがオブジェクトに接触するとオブジェクトと，超音波センサとの距離を取得します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250916/4e22e72f-13a0-2038-1f82-474360947ee4.png)


athrill側で、ev3_ultrasonic_sensor_get_distance (sensor_port_t port)を呼び出すことで、
unity上の超音波のセンサ値を取得することができます。

# 動作確認
unityをシミュレーションモードにして、
WSL上で、以下のコマンドを実行してください。

```bash
$ cd athrill-sample/ev3rt/ev3rt-beta7-release/asp_arm/sdk/OBJ1.1
$ make clean
$ make
$ athrill2 -c1 -m memory.txt -d device_config.txt -t -1 asp
```
![xg5ye-sh6d6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250916/bf56fcc2-0b9e-2ce8-b679-a9504323de2f.gif)
GitHubのプッシュをSlackに通知


## Slackの設定

●Slack ヘルプセンター
https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8

「Incoming Webhook の設定」の手順で、Incoming Webhook URLを発行します。

## Google Cloud Platform （Cloud Function）の設定
Google Cloud Platformの登録をしていない場合は、登録を。

### 手順
- 「Cloud Function」に移動します。
- 「関数を作成」で関数を作ります。設定は下記

名前：任意
割り当てられるメモリ：任意
トリガー：HTTP
認証：未認証の呼び出しを許可する
ソースコード：インライン エディタ
ランタイム：Python3.7
実行する関数：ソースに記述した関数名（sampleではslack_notice）


### ソースコード

```sample.py
import requests
import json

def slack_notice(request):

    webhook_url = "https://hooks.slack.com/<Incoming Webhook URL>"
    request_json = request.get_json()

    if 'commits' in request_json:
        name = request_json['commits'][0]['author']['name']
        text = name+"がプッシュしました。"
        requests.post(webhook_url, data = json.dumps({
            "text": text
        }))
```

## GitHubの設定
「Setteing」→「Webhooks」→「Add webhook」に移動し、下記のように設定

Payload URL：Google Cloud Platformのトリガーに書かれているURL
Content type：application/json
SSL verification：Enable SSL verification
Which events would you like to trigger this webhook?：Just the push event.
Active：チェック

## あとは試しにプッシュ！
でけた
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287209/d40fc8ea-a678-5904-29cc-012ec540be6e.png)
CentOS 8 で Kubernetes + Calico を動かす

# CentOS 8 で Kubernetes を動かすときの問題点

CentOS 8 / RHEL 8 で Kubernetes を動かす場合、以下の2つの問題があります。

1. CRI コンテナランタイムがない
2. iptables legacy モードがない

CentOS 8 / RHEL 8 からは Docker が含まれなくなり、podman + runC という構成になったため、CRI 対応した container runtime がありません。なので、docker-ce などを別途インストールする必要があります。

もう１つの問題として、nftables が標準となり iptables legacy モードが無いという問題があります。
[v1.17.0 以降の kube-proxy は nftables でも動く](https://github.com/kubernetes/kubernetes/pull/82966)ので問題ないのですが、デフォルトでは calico は iptables legacy モードでないと動かないのでオプションをつけてあげる必要があります。

# calico のオプション

calico v3.8.1 以降で [FELIX_IPTABLESBACKEND](https://docs.projectcalico.org/reference/felix/configuration) というオプションが追加されています。
デフォルトでは `Legacy` になっていますが、これだと iptables legacy モードでしか動作しません。
nftables で動かすには `Auto` または `NFT` に設定する必要があります。

https://docs.projectcalico.org/v3.8/manifests/calico.yaml
から YAML ファイルをダウンロードして、以下のように `FELIX_IPTABLESBACKEND` を指定してから `kubectl apply -f` すれば OK。

```yaml:calico.yaml      
      containers:
        # Runs calico-node container on each Kubernetes node.  This
        # container programs network policy and routes on each
        # host.
        - name: calico-node
          image: calico/node:v3.8.6
          env:
            - name: FELIX_IPTABLESBACKEND
              value: NFT
            ...
```

# サンプル

https://github.com/tmurakam/kubernetes-vagrant-env
に Vagrant + kubeadm を使って Kubernetes クラスタを構築するためのスクリプトなどを入れてあります。

# 参考リンク

* [Kubernetes 1.16 のクラスタを CentOS 8 と containerd で構築する](https://www.kaitoy.xyz/2019/12/05/k8s-on-centos8-with-containerd/)
復習

ER図
Entity-Relationship Diagramの略でテーブル同士の関係を視覚的にわかりやすく表した図

バリデーション
空のツイート投稿ができないようにバリデーションの設定

rails routesコマンドを実行
Prefix	「Prefix」はルーティングの名前を表しています。「Prefix」は設定を行わなくても、自動的に割り当てられますが、自ら設定することもできます。
Verb	「Verb」はHTTPメソッドを表しています。右側に表示されているパスにどのHTTPメソッドでアクセスするかを示しています。
URI Pattern	「URI Pattern」はルーティングのパスを表しています。このパスにアクセスされた際に、指定のコントローラーとアクションで処理が行われます。
Controller#Action	「Controller#Action」は指定したパスにアクセスした際に処理が行われるコントローラーとアクションを表しています。#以前がコントローラー名、#以後がアクション名を示しています。

HTTPリクエストのメソッド

| GET | サーバーからブラウザに情報を返す。単にウェブサイトを閲覧する際にはこのメソッドが利用されている。 |
|:--|:--|
| POST | ブラウザからサーバーに情報を送信し、サーバーに情報を保存する。情報の登録などの際に、サーバーに情報を送信するために利用される。 |
| DELETE | ブラウザからサーバーに情報を送信し、サーバーの情報を削除する。アカウントの削除などの際に、サーバー内のデータを削除するために利用される。 |
| PATCH | ブラウザからサーバーに情報を送信し、サーバー内の情報を置き換える。登録情報の更新などの際に、サーバー内のデータを更新するために利用される。 |


| Railsのリソースの7つのアクション | 役割 |
|:--|:--|
| index | リソースの一覧を表示する。 |
| new | リソースを追加する。 |
| create | リソースを追加し、作成する。 |
| edit | リソースを更新するためのフォームを表示する。 |
| update | リソースを更新する。 |
| destroy | リソースを削除する。 |
| show | リソースの内容を表示する。 |


before_action
あるコントローラのすべてのアクションで実行の前に共通の処理を行いたいときに、before_actionを使用すると全てのアクションが実行される前に指定したメソッドを呼び出すことができるようになります
before_actionを利用して、edit、showの2つのアクションに対して、set_tweetというメソッド名をつけて定義

ヘルパーメソッド
主にviewでHTMLタグを出現させたりテキストを加工するために予めメソッドが用意されてる。これらをまとめて、ヘルパーメソッド。HTMLやRubyの記述がセットになった、ビューファイルで使用できるメソッド
1. 複雑なアプリケーションにおいては、ヘルパーメソッドを使用するとコードがシンプルになる
2. 特にフォームにおいては、ヘルパーメソッドを使用しないとセキュリティ上の問題が発生する

ストロングパラメーター
指定したキーを持つパラメーターのみを受け取るようにするもの
プライベートメソッド
クラス外から呼び出すことのできないメソッド
ストロングパラメーターを記述したメソッドは、private以下に記載して、プライベートメソッドとして扱う

N+1 問題
SQLがたくさん発行されて動作が重くなること
モデルを利用してデータベースにアクセスをする際にSQLが発行されます。
アソシエーションの利用して、子モデルのインスタンスを複数取得する際には、N+1問題があることを考慮しましょう。
includesメソッドなど使用することでN+1問題を解消することができます。

アソシエーション
モデル間を紐付けること
has_many メソッド
モデルとの間に「1対多」のつながりがあることを示す
belongs_to メソッド
モデルとの間に「1対1」のつながりがあることを示す
Batch Normalizationとは？？　〜機械学習の用語まとめ〜

#アクティベーションの偏りの解消

アクティベーション(活性化関数を通した後の出力データ)に偏りがあると、勾配消失が起こり学習が停滞してしまったり、表現力が低下してしまうことがある。
この解決策として、[重みの初期値](https://qiita.com/Becon147/items/a9971041bca5c10483bc)を調節することで、アクティベーション(活性化関数を通した後の出力データ）がある程度広がりのある分布となる。

他にも、アクティベーションの偏りを解消させる手法がある。強制的にアクティベーションに広がりを持たせる**Batch Normalization**である。

#Batch Normalizationの仕組み
Batch Normalizationは2015年、Ioffe、Szegedy氏によって提案された手法である。([論文](https://arxiv.org/abs/1502.03167))
Batch Normalizationは、その名の通り、BatchごとにNormalization(**正規化**)する手法である。
正規化とは、入力されたデータの平均を0に、分散を1にすることである。

Batch Normalizationを式で表す。入力データを$x_i = (i = 1 〜 n)$とすると、
$$
\mu_{B} \leftarrow \frac{1}{m}\sum_{k=1}^{n}x_i  \\\
\sigma_B \leftarrow \frac{1}{m}\sum_{k=1}^{n}(x_i - \mu_{B})^{2}  \\\
\hat{x_i} \leftarrow \frac{x_i - \mu_{B}}{\sqrt{\sigma_B^{2} + \epsilon}}
$$
このようにして計算された$\hat{x_i}$は、平均0、分散1と正規化されている。
さらに,$y_i = \gamma \hat{x_i} + \beta$とスケール変換されたものが最終的な出力となる。
なお、$\gamma = 1,\beta = 0$からスタートして、学習と同時に変化していく。

これが、Batch Normalizationの流れである。
Batch Normalizationをどこで行うかには様々な議論がある。活性化関数の直前で行う、または活性化関数の直後で行うのが主流である。

#Batch Normalizationの利点
Batch Normalizationはkaggleなどの多くの機械学習コンペで使用されているのが見受けられる。これはBatch Normalizationに様々な利点があるからである。
①学習がはやくなる。
これまでは、学習係数を大きくしすぎると勾配消失や勾配爆発が起こってしまうことがあるため、小さくせざるを得なかった。Batch Noramlizationを使うと、パラメータのスケールを気にしなくて良いので、学習係数を大きくすることができる。つまり、学習スピードが上がるのである。

②過学習が抑制される。
過学習とは、訓練データに特化したモデルになってしまい、新たなデータに対応する汎化性能がなくなってしまうことである。Batch Noramlizationを使うことで、過学習が抑制され、DropOutなども用いる必要性がなくなる。

③初期値の影響が小さくなる。
これまで[重みの初期値]()も重要視されてきたが、Batch Noramlizationを利用することで、それが不必要となってくる。

特に学習速度、過学習は、機械学習において頻繁に問題となる点である。
これらを同時に解消できるBatch Normalizationの需要が高い理由も納得できる。

#まとめ
Batch Normalizationとは、強制的にアクティベーションに広がりを与える手法であり、勾配消失、表現力の低下を防ぐことができる。
他にも、学習スピードの向上、過学習の抑制、初期値依存の抑制など様々な効果を発揮する非常有用な手法である。
Batch Normalizationは入力を正規化し、スケール変換したものを出力する。基本的には、活性化関数の前後で利用される。


###参考
[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585)
RICOH THETAの全天球動画を正距円筒図法へFFmpegで変換する

RICOH THETAの全天球動画を正距円筒図法動画にffmpegを用いて変換する方法を共有します。

## 結論

FFmpegのmasterブランチのビルド( Windows&Mac:[[1]](https://www.ffmpeg.org/download.html), Linux:[[2]](https://www.johnvansickle.com/ffmpeg/) )を入手した上で、下記コマンドを実行することで2つの魚眼動画を正距円筒図法動画へ変換できます。

```bash
ffmpeg -i INPUT.MP4 -y -vf crop=1920:960:0:0,v360=dfisheye:in_pad=0.112:roll=-90:e:pitch=90,crop=1920:840:0:0,pad=1920:1080:0:0 -c:a copy OUTPUT.mp4
```

## 解説

FFmpegに全方位カメラ向けのライブラリ[v360](https://ffmpeg.org/ffmpeg-filters.html#v360)が昨年の9月辺りにmasterブランチに入りました。
ただし、2020/03/08時点の最新版である4.2.2には含まれていないため、masterブランチのビルド( Windows&Mac:[[1]](https://www.ffmpeg.org/download.html), Linux:[[2]](https://www.johnvansickle.com/ffmpeg/) )を用いて作業をする必要があります。

ビデオフィルタオプション `-vf` のそれぞれの意味は下記のとおりです。

- `crop=1920:960:0:0`
    - 入力画像は1920x1080であるが、実際に魚眼画像がある1920x960の範囲のみに限定する必要がある
- `v360=dfisheye:in_pad=0.112:roll=-90:e:pitch=90`
    - `dfisheye` : Dual Fisheye Movie として入力画像を解釈する
    - `in_pad=0.112` : 魚眼動画のマージンを無視する
    - `roll=-90` : roll角度調整(お好みで調整)
    - `e` : 正距円筒図法に投影して出力する
    - `pitch=90` : pitch角度調整(お好みで調整)
    - この他にも必要に応じて[オプション](https://ffmpeg.org/ffmpeg-filters.html#v360)を追加
     - `interp` : `gaussian`, `lanc` など高次な補完処理を用いても良いかもしれません(標準は `linear` )。

- `crop=1920:840:0:0,pad=1920:1080:0:0`
    - 取っ手部分がノイジーなので黒く塗りつぶす
    - 不要な場合はフィルタオプション `,crop=1920:840:0:0,pad=1920:1080:0:0` をまるごと削除すればよい


## 変換結果例

![dual-fisheye.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60150/868ff063-6187-a4f9-b980-f506040056b7.png)

![equirectangular.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60150/1f598c9f-3963-3753-70f8-dc9173f39b73.png)


## 課題

つなぎ目が不自然なのでSLAMとかにかけるときに副作用がありそうです。
`in_pad` を少なめにとった上で、それらの境界を自然にブレンドをしたいのですが、該当する実装を探せていません。

## 背景

RICOH THETAシリーズは、未だにライバルが少ない全天球撮影を簡単に行える優秀なデバイスですが、動画撮影の場合に正距円筒図法に投影されない動画データが吐き出されます。魚眼カメラ2つの映像を生でエンコードしたもの(Dual Fisheye
 Movie)となっています。
一般的に多くのサービスや動画処理で使われているのは正距円筒図法(Equirectangular)に投影したものを入力としているので、そのままでは扱えません。

この問題を解決するために、[RICOHの本家のツール](https://support.theta360.com/ja/download/)が存在します。変換自体の機能は充足しますが、GUIでの操作が前提となっており、大量変換・自動変換に不向きであるという問題があります。また、Linuxに対応していない点もSLAM実装に投げるなどの環境実装上、大いにマイナスです。

そこで、メジャーなOSSでの実装、かつ持続可能な調達が見込める方法を調査した結果が本記事になります。
ほとんどまとまった言及がなかったのですが、[唯一具体的なQ&AがStack overflowに1件](https://stackoverflow.com/questions/37796911/is-there-a-fisheye-or-dual-fisheye-to-equirectangular-filter-for-ffmpeg/58336312#58336312)ありました。ただ、この記述どおりではうまく行かなかったため、試行錯誤をした結果が上記のコマンドになります。

## 参考文献
 1. [Download FFmpeg](https://www.ffmpeg.org/download.html)
 2. [FFmpeg Static Builds](https://www.johnvansickle.com/ffmpeg/)
 3. [FFmpeg Filters Documentation # v360](https://ffmpeg.org/ffmpeg-filters.html#v360)
 4. [RICOH THETA ダウンロード](https://support.theta360.com/ja/download/)
 5. [Is there a fisheye or dual fisheye to equirectangular filter for ffmpeg? - Stack overflow](https://stackoverflow.com/questions/37796911/is-there-a-fisheye-or-dual-fisheye-to-equirectangular-filter-for-ffmpeg/58336312#58336312)
php.ini 内で環境変数を参照した設定ができる

docker-composeで開発環境を構築していて、
.env に各コンテナ名の情報を定義しておき
docker-compose.yaml の env_fileに読み込ませ
各コンテナ間の疎通に環境変数に定義したコンテナ名を利用したりしていた。

```docker:.env
#docker-composeプロジェクト名定義
COMPOSE_PROJECT_NAME=projecta
#php(web)コンテナ名
WEBCONTAINER=projecta_web_1
#mysqlコンテナ名
DBCONTAINER=projecta_mysql_1
```

```docker:docker-compose.yaml
  env_file:
   .env
```

こうしておくと、phpのスクリプト内で環境変数を使ってDBコンテナを指定できる

```php:php
// DB接続先定義
define('DB_HOST', getenv("DBCONTAINER"));
```



phpのセッション保存用にmemcachedのコンテナも立ち上げていて
こちらはcompose内で定義しているサービス名をphp.iniにベタ書きしていたけど、
php.ini内でも環境変数が使える様子

■変更前

```docker:docker-compose.yaml
 //memcached のサービス定義
 memcached:
```

```php:php.ini
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = memcached
session.save_path = memcached:11211
```

↓↓↓

■変更後

```docker:.env
#memcachedコンテナ名
MEMCACHEDCONTAINER=projecta_memcached_1
```
${変数名}で参照ができる

```php:php.ini
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = memcached
session.save_path = ${MEMCACHEDCONTAINER}:11211
```

[https://www.php.net/manual/ja/configuration.file.php](https://www.php.net/manual/ja/configuration.file.php)

php.iniで環境変数を使うことは今までなかったけど、
dockerでコンテナ間通信で利用するコンテナ名はできるだけ外から
注入する形で統一したかったので勉強になった。
データを整形するときに困ったこと備忘録

この記事はスクレイピングしてきたデータ型がいろいろ変だったりしたときに行った処理の備忘録です。

#データの型を確認する
~~~python
df['column名'].dtype #DataFrame
np.dtype() #numpy配列
~~~

#データ型の変更
~~~python
df['column名'].astype(int) #intに変換
df['column名'].dtype(float) #floatに変換
df['column名'].dtype(str) #文字列に変換
~~~
#欠損値の確認
~~~python
df.isnull()
~~~

#欠損値を削除する
~~~python
df.dropna()
~~~

#pandasの行削除
~~~python
df.drop(行数)
~~~

#pandasに列追加
~~~python
df['新しい列の名前']=[a,b,c,d,...]
~~~
AngularでStorybookを導入する

# はじめに
storybookが良いと聞く今日このごろ。
Angularでも使えることを知ったので、今回はそれを試してみる。

# TL;DR.
[ソースコード](https://github.com/Tetsuya-Minase/ui-components/tree/master/ng-component)

# Angularプロジェクト作成
CLIでサクッと作成する。

``` bash
$ ng new ng-component
```

# Storybook導入

[公式サイト](https://storybook.js.org/docs/guides/guide-angular/)に手順があるので、それを参考に進める。
これだけでセットアップが完了する。

``` bash
$ npx -p @storybook/cli sb init --type angular
```

サンプルプログラムも作ってくれるが、
パッケージがなくうまく動かなかったりしたのでstoryを作っていく。

# Storyを作成する
`src/stories`配下に`button.component.stories.ts(任意)`を作成する。
※`ButtonComponent`の中身は後述

``` typescript
import { ButtonComponent } from '../app/component/button/button.component';

export default {
  title: 'button component',
};

export const ButtonDefault = () => ({
  component: ButtonComponent,
  props: {
    text: 'default'
  }
});
```

## 作成したcomponent
### button.component.ts

``` typescript
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-button',
  templateUrl: './button.component.html',
  styleUrls: ['./button.component.scss']
})
export class ButtonComponent implements OnInit {
  @Input() text: string;

  buttonClasses: string[] = ['button'];

  ngOnInit() {
  }

}
```

### button.component.scss
``` scss
.button {
  width: 150px;
  height: 50px;
  background-color: #fff;
  border: 1px solid #000;
  color: #333;
  font-size: 16px; 
}
```

### button.component.html
``` html
<button [ngClass]="buttonClasses">{{text}}</button>
```

# 実行してみる
自動で追加された`npm script`があるので、それを実行すればOK。

``` bash
$ npm run storybook
> ブラウザが勝手に立ち上がり表示される
```

<img width="1680" alt="スクリーンショット 2020-03-08 18.47.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176571/ec2e997c-5d57-8d3f-deac-fe7eb6321466.png">
画像の様に出てくれば完了。

# まとめ
今回は前々からやろうと思ってたstorybookの導入をやった。
component単位で見れるものがあるのは、やっぱり楽だと思うので今後は作っていきたいところ。
＋github pagesで見れると楽なのでいつか対応したい。

# 参考リンク
- [Storybook for Angular](https://storybook.js.org/docs/guides/guide-angular/)
【Python】Python版lodashのpydashを試してみる

# Python版lodashのpydashを試してみる
## TL;DR
会社ではフロントサイドをReact、バックエンドでDjangoで開発してるんですね。
フロントサイドでは`lodash`というライブラリーをよく利用するんですが、めちゃくちゃく便利で、そのあとPythonを書くときに、`lodash`がないため、もどかしさを感じることがあります。
そんなもどかしさに苛まれているある日`pydash`というPython版`lodash`とも言えるlibraryを見つけたので紹介します。

## インストール
利用できるPtyhonのバージョンは2.6以上、または3.3以上とのことなので、適当にPython 3.7.6で試すことにします。

```shell
$ pip install pydash
```

## 軽く触ってみる

```python
>>> import pydash
>>> from pydash import flatten

# Arrays
>>> flatten([1, 2, [3, [4, 5, [6, 7]]]])
[1, 2, 3, [4, 5, [6, 7]]]

>>> pydash.flatten_deep([1, 2, [3, [4, 5, [6, 7]]]])
[1, 2, 3, 4, 5, 6, 7]
>>> pydash.remove([{'name': 'moe', 'age': 40}, {'name': 'larry', 'age': 50}], lambda x: x['age'] < 50)
[{'name': 'moe', 'age': 40}]

# Collections
>>> pydash.map_([{'name': 'moe', 'age': 40}, {'name': 'larry', 'age': 50}], 'name')
['moe', 'larry']
>>> pydash.filter_([{'name': 'moe', 'age': 40}, {'name': 'larry', 'age': 50}], {'age': 40})
[{'name': 'moe', 'age': 40}]

# Functions
>>> curried = pydash.curry(lambda a, b, c: a + b + c)
>>> curried(1, 2)(3)
6

# Objects
>>> pydash.omit({'name': 'moe', 'age': 40}, 'age')
{'name': 'moe'}

# Utilities
>>> pydash.times(3, lambda index: index)
[0, 1, 2]

# Chaining
>>> pydash.chain([1, 2, 3, 4]).without(2, 3).reject(lambda x: x > 1).value()
[1]
```
すばらしいですね。
lodashと比べても遜色ないですね。

## lodashとの違い
上記にもありますが、`pydash.map_`や`pydash.filter_`など関数名に微妙に違いがあります。

## 最後に
かなり便利だと思います。
lodashのドキュメントはかなり読みやすいのでそちらを参考にしつつ開発が捗りそうです。

## 参考
https://pydash.readthedocs.io/en/latest/
https://lodash.com/
object-fitとは

# object-fitとは
img要素やvideo要素などの中身を、コンテナーにどのように表示するかを設定するプロパティです。
よく「画像をトリミングする方法」などとして紹介されています。

# 対応状況
https://caniuse.com/#feat=object-fit
IEでは使用できませんが、さすがにIEは無視して良いかと思います。


#いつ使う？
個人的に一番よく使用するのが、サムネイルの形状を一致させるデザインの時です。
後はスライダーなどで、画面サイズによってスライダー自身のサイズを変えている場合などです。

# 実装
## プロパティ
###contain
コンテンツのアスペクト比（長辺と短辺の比率）を維持したまま、**要素のコンテンツボックスに収まるように拡大縮小** されます。
要素のアスペクト比とコンテンツボックスのアスペクト比が合わない場合は、**レターボックス表示**(上下左右に余白ありの表示)になります。

###cover
コンテンツのアスペクト比を維持したまま、**コンテンツボックス全体を埋めるように拡大縮小**します。
コンテンツのアスペクト比とコンテンツボックスのアスペクト比と合わない場合は、拡大されます.
トリミングで紹介される場合、この`cover`の例になっています。

###fill
初期値です。
コンテンツはコンテンツボックス全体を埋めるように拡大縮小します。

###none
コンテンツの拡大縮小をしません。

###scale-down
コンテンツは、noneやcontainを指定したようにサイズが設定され、コンテンツの実際のサイズが小さい方が採用されます。

## 実装例
<p class="codepen" data-height="468" data-theme-id="light" data-default-tab="html,result" data-user="H_Naito" data-slug-hash="JjdOwwB" style="height: 468px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="object-fit Sample">
  <span>See the Pen <a href="https://codepen.io/H_Naito/pen/JjdOwwB">
  object-fit Sample</a> by H.N (<a href="https://codepen.io/H_Naito">@H_Naito</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考

https://developer.mozilla.org/ja/docs/Web/CSS/object-fit
https://liginc.co.jp/463976
https://www.webcreatorbox.com/tech/object-fit
JSforceとレコードの型

　初投稿です。[JSforce 2.0](https://jsforce.github.io/blog/posts/20191216-jsforce20-alpha-preview-with-schema-type-feature.html)でのレコードの型が気になりました。いずれドキュメントなどで公開されるのだと思いますが私は今知りたかったので……。
 
環境は次の通りです。
 
 - JSforce 2.0.0-alpha.11
 - TypeScript 3.8.3
 
　あるオブジェクトのレコードの型は `SObjectRecord` とスキーマとオブジェクト名で表せるようです。

```typescript
type Account = SObjectRecord<StandardSchema, "Account">;

const accounts: Account[] = await conn
  .sobject("Account")
  .find();

const id: string = accounts[0].Id;
```

項目を絞るときはそのパターンを追加します。

```typescript
type Account = SObjectRecord<StandardSchema, "Account", "Id" | "Name">;

const accounts: Account[] = await conn
  .sobject("Account")
  .find(null, ["Id", "Name"]);

const name: string = accounts[0].Name;
```

親のレコードを含むときも同様です。

```typescript
type Account = SObjectRecord<StandardSchema, "Account", "Id" | "Name" | { Owner: "Id" | "Name" }>;

const accounts: Account[] = await conn
  .sobject("Account")
  .find(null, ["Id", "Name", "Owner.Id", "Owner.Name"]);

const ownerId: string = accounts[0].Owner.Id;
```

子のレコードを含むときは `SObjectChildRelationshipProp` で拡張します。

```typescript
type Contact = SObjectRecord<StandardSchema, "Contact", "Id" | "Name">;
type Account = SObjectRecord<StandardSchema, "Account", "Id" | "Name"> &
  SObjectChildRelationshipProp<"Contacts", Contact>;

const accounts: Account[] = await conn
  .sobject("Account")
  .find(null, ["Id", "Name"])
  .include("Contacts", null, ["Id", "Name"])
  .end();

const contactIds: string[] = accounts[0].Contacts?.records.map(contact => contact.Id) ?? [];
```

これで大体のレコードに型を付けられそうです。やっていきましょう。

- [jsforce/jsforce at 2.0 - GitHub](https://github.com/jsforce/jsforce/tree/2.0)
Tool紹介ビデオ通話ツール「Whereby」　

今日は、オススメのビデオ通話ツールのご紹介です。

最近、コロナの影響を受けてGoogleがG suiteの全てのエディションにてビデオ会議機能などを無料提供などを無料で提供したようですね。
>Google、新型コロナ対策として250人ビデオ会議機能などを無料提供
>https://www.itmedia.co.jp/news/articles/2003/04/news066.html

最近まで、ビデオ通話なんてと思っていましたが、結構便利だと感じています。



# Whereby とは？
ブラウザで使用できる、ビデオ会議ツールです。無料でも様々な機能がしよう出来ますし、登録も簡単なのですぐに始められます。
[Whereby](https://whereby.com/user/login)

## オススメポイント

- 登録が簡単
まずは、始めようと思ってからが、すごく早いです。余計な登録はありません。Googleのアカウントがあればそのまま登録出来ます。

- ビデオ通話の開始が簡単
登録したら、無料プランですとroom(ビデオ通話スペース)が一つ作成出来ます。
![スクリーンショット 2020-03-08 22.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406727/0908846a-18c6-8005-18bc-14331447c557.png)
あとは、roomのリンクを共有するだけです！
相手が登録してなくても使用できます！（・・・確か）
フリープランだと最大で４人までです。

- 機能が豊富
    - マイクのon　off
    - カメラのon　off
    - 画面の共有も可能です。
    - チャット機能もあります。
    - あとは、youtubeやtrelloとの連携もできるようです。
  

気軽に使えるので、ぜひ試してみてください！