OmniAICreator/Qiita-1.07M huggingface dataset:
Chainlink から価格の履歴を取得し DeFi の税計算に利用するメモ(途中)

## 背景

DeFi 取引の税計算で, トークンの交換時点でのそれぞれの法定通貨での価格を知る必要がある.

DeFi の多くは Chainlink の Oracle を使っているので, chainlink のデータを辿って価格を取得したい(Eth にオンチェーンで価格の記録が書き込まれているはずだが..)

Chainlink price history とかで検索すると, `$LINK`(Chainlink のトークン)の価格履歴ばかりヒットしてつらい 
:cry:

チェーンのデータをパースできればいいので, コントラクトを実行する必要はない.

## 情報

https://docs.chain.link/docs/historical-price-data

## セットアップ

python web3 を使います.
とりあえず上記リンクように, infra を使います. infra のアカウントを取得しておきます.
(自前で geth を建てている場合は geth でよさそうです)

コントラクトは call(staticcall)で読み取りのみで chain の state を変更しないため, gas を使わずに実行できます(Metamask などとの連携は不要).

Kovan で実行すると 5 個データがでてきます.

```
[18446744073709562301, 36359000000, 1599826936, 1599826936, 18446744073709562301]
```

https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol


にあるように, roundId, answer, startedAt, updatedAt, answeredInRound になります.

https://docs.chain.link/docs/price-feeds-api-reference#return-values

とりあえずは `answer` が価格であることがわかります. startedAt, updatedAt は unix timestamp になります.


### roundId

クエリをするには, 対応する timestamp と紐付いた roundId(block id みたいなものかな?)が必要になります. roundId は基本 monotonically increasing ですが, 連続しているとはかぎりません.

この roundId をどう取得するか...? たとえば Uniswap で交換したときに roundId の記録も残っているのかしらん?

T.B.W.
【Ruby】10の位と1の位を取得する方法

## 概要

二桁の整数から10の位と1の位を取得して、計算結果を出力するまでを書いていきます。

## 目次

- 実践
    - 問題
    - 解答(解説)
    - 別解（digitsメソッド）
    - 別解(divmodメソッド)

- まとめ

- 参考文献

## 実践

#### 問題

>二桁の整数から**１０の位と1の位**の数字の**足し算と掛け算の結果**を足し合わせて出力するプログラムを書いてください

#### 解答（解説）

```ruby:解答
def addition(a, b)
  a + b
end

# 10の位と1の位の掛け算
def multiplication(a, b)
  a * b
end

def check_num(num)
  tens_place = (num / 10) % 10   # 10の位を10で割ることで1桁にしてから余りを計算している
  ones_place = num % 10          # 10で割ったときの余りが1の位になる

  addition_result       = addition(tens_place, ones_place)        # additionメソッドで足し算
  multiplication_result = multiplication(tens_place, ones_place)  # multiplicationメソッドで掛け算

  p "足し算の結果と掛け算の結果の合計は#{ addition_result +  multiplication_result }です。"
end

# ターミナルで入力する
p '二桁の整数を入力してください'
num = gets.to_i

# メソッド呼び出し
check_num(num)
```

#### 別解（digitsメソッド）

書き換えた箇所は**10の位と1の位を計算**しているところです。 `digits.take` の引数に `2` を指定しているのは1の位と10の位の2つの値を取得しているからです。注意点としては `digits.take` で取得する際 `1の位` から順番に取得する点です。

```ruby:digits
def addition(a, b)
  a + b
end

def multiplication(a, b)
  a * b
end

def check_num(num)
  ones_place, tens_place = num.digits.take(2) # 1の位と10の位を取得

  addition_result       = addition(tens_place, ones_place)       
  multiplication_result = multiplication(tens_place, ones_place) 

  p "足し算の結果と掛け算の結果の合計は#{ addition_result +  multiplication_result }です。"
end

p '二桁の整数を入力してください'
num = gets.to_i

check_num(num)
```

#### 別解(divmodメソッド)

書き換えた箇所は**１０の位と1の位を計算**しているところです。 `divmod` の引数（今回の場合は`10`）に数値を指定することで割ったときの商と余り取得することができます。

```ruby:divmod
def addition(a, b)
  a + b
end

def multiplication(a, b)
  a * b
end

def check_num(num)
  tens_place, ones_place = num.divmod(10) # 1の位と10の位を取得

  addition_result       = addition(tens_place, ones_place)        
  multiplication_result = multiplication(tens_place, ones_place) 

  p "足し算の結果と掛け算の結果の合計は#{ addition_result +  multiplication_result }です。"
end

p '二桁の整数を入力してください'
num = gets.to_i

check_num(num)
```

## まとめ

- 10の位は二桁の整数を10で割り、さらに10で割った余り
- 1の位は二桁の整数を10で割った余り
- digitsメソッドを使用することで1の位から順番に数値を取得することができる

## 参考文献

- [Ruby 2.7.0 リファレンスマニュアル(digits)](https://docs.ruby-lang.org/ja/2.7.0/method/Integer/i/digits.html)
- [Ruby 2.7.0 リファレンスマニュアル(divmod)](https://docs.ruby-lang.org/ja/2.7.0/method/Integer/i/divmod.html)
- [2桁から十の位と一の位を取得する](https://qiita.com/eve1224/items/cc0bcabea60e9ac7ab1d)
- [割り算の商と余りを一度に求める](http://www.openspc2.org/reibun/Ruby/calc/008/index.html)
devise機能

デバイズ機能を使うとユーザー管理がしやすくなる！

rails g devise user の命令をターミナル上で出すと、ログイン画面とサインアップ画面が生成される。
しかしビューファイルとして生成はしない！
これは、deviseのGem内に存在するビューファイルを読み込んでいるから！

そこで、deviseのビューファイルをコピーし、devise用のビューファイルを用意する。
命令としては　rails g devise:views

すると、

app/views/devise/registrations/new.html.erb

app/views/devise/sessions/new.html.erb

2つビューファイルが出来上がるが、サインアップ画面が上、ログイン画面が下に対応する！
ファイル名が同じでもpathが違う




すでに作成されたテーブルの内容を変更する場合は rails g migration　コマンドを行う
rails g migration Addカラム名To追加先テーブル名　追加するカラム:型




＜サインアップ画面の編集＞
・maxlengthオプション
→inputタグを生成するヘルパーメソッド



ストロングパラメーターの扱い
→deviseに関しても受け取れるパラメーターをコントローラーで制限する！
しかし、deviseの処理を行うコントローラーはGem内に記述されているので編集できない！
そこで、

①deviseのコントローラーにストロングパラメーターを反映する方法
②devise特有のパラメーターを取得する方法

が必要になる。

②devise特有のパラメーターを取得する方法
→devise__parameter_sanitizerメソッドを使う

private
def configure_permitted_parameters  # メソッド名は慣習
  # deviseのUserモデルにパラメーターを許可
  devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可するキー])
end

→引数の部分が今までと違う
deviseの処理には、  :sign_in   :sign_up   :account_update などがある

ストロングパラメーターを追加するコードはapplication_controller.rb に記載する

（例）
private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end

これは、sign_up(新規登録の処理)をする時、nicknameというキーのパラメーターを許可するもの！


このままだと、devise機能を使わない時も実行されてしまう（？）ので、ifというオプションを使う。

before_action :configure_permitted_parameters, if: :devise_controller?
デバイズに関するコントローラーの処理の時だけconfigure_permitted_parametersを実行する！











tweetsテーブルにカラムを追加する方法(すでにテーブルができている時)
→　rails g migration AddUserIdToTweets user_id:integer

→　rails db:migrate
じぶんpython環境メモ

```python
katayamashunyuunoMacBook-Pro:~ katayamashunsuke$ which python
/Users/katayamashunsuke/.pyenv/shims/python
#pyenvのpythonを使っている

katayamashunyuunoMacBook-Pro:~ katayamashunsuke$ which pip
/Users/katayamashunsuke/.pyenv/shims/pip
#pipもpyenv由来

katayamashunyuunoMacBook-Pro:~ katayamashunsuke$ which conda
katayamashunyuunoMacBook-Pro:~ katayamashunsuke$ which anaconda
#conda anacondaは入ってない

katayamashunyuunoMacBook-Pro:~ katayamashunsuke$ pyenv versions
  system
  3.6.5
* 3.7.4 (set by /Users/katayamashunsuke/.pyenv/version)
  3.7.7
  3.8.2
  anaconda3-5.3.1
#anacondaでjupyter notebookを使いたい時はpyenvからlocalで使う
#使い方
#適用ディレクトリに移動して
pyenv local anaconda3-5.2.0
jupyter-notebook
```

pipとcondaをconflictさせずにどっちも使うことができる。
#pipenvについて
ここを見ろ
https://rinatz.github.io/python-book/ch04-05-pipenv/
# cvxpy周りの環境について
作成したconda環境内でしっかりjupyterしましょうという話
ここではcondaで仮想環境を作っている

```terminal　
環境の作り方
$ x64..x86_64環境への切り替え
$ conda create --name cvxpy
$ echo ". /Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/etc/profile.d/conda.sh" >> ~/.zshrc
$ conda activate cvxpy
$ conda install -c conda-forge cvxpy
$ conda install jupyter
$ jupyter notebook
```
これは今はやらなくてもなんか上手く行ってる。上手く行かない時はみてみる

```terminal
cvxpy環境への入り方
$ x64
$ conda activate cvxpy
$ jupyter-notebook
```

# M1周りの設定について
```python
#アーキテクチャをx86_64に変更
x64
#アーキテクチャをarm64に変更
a64
#アーキテクチャ確認
uname -m
```

下記はモジュールのimport元について。anaconda環境においてはpipからのインストールは行われていない。

```python
#anaconda3-5.3.1
>>> sys.path
['', 
'/Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/lib/python37.zip', 
'/Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/lib/python3.7', 
'/Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/lib-dynload', 
'/Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages', 
'/Users/katayamashunsuke/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/aeosa']

#3.9.2
>>> sys.path
['', 
'/Users/katayamashunsuke/.pyenv/versions/3.9.2/lib/python39.zip', 
'/Users/katayamashunsuke/.pyenv/versions/3.9.2/lib/python3.9', 
'/Users/katayamashunsuke/.pyenv/versions/3.9.2/lib/python3.9/lib-dynload', 
'/Users/katayamashunsuke/.pyenv/versions/3.9.2/lib/python3.9/site-packages']

#importしたモジュールのverison確認
>>> import matplotlib
>>> print(matplotlib.__version__)
3.4.2
```

#pyenvで何故かglobalが反映されない時に見る場所
下のページの主にpathの部分
https://github.com/pyenv/pyenv#basic-github-checkout

#pythonでモジュールのimport元を確認する
```
import pandas as pd
print(pd.__version__)
```

#pythonでimport環境を確認する
```
mport sys
import pprint
pprint.pprint(sys.path)
```
Emmetの記法について

<h1>説明</h1>
Emmetは、HTMLやCSSを効率的に記述するためのプラグインです。初めのうちはプログラミングの学習に集中し、このような記法があることに気が付きませんでした。以下に使用例を記載します。tabキーを押すことで展開されます。

<h2>●HTMLの場合</h2>
<p>!</p>
>
```html
<!DOCTYPE html>
<html lang=“ja”>
<head>
  <meta charset=“UTF-8”>
  <meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
  <title>Document</title>
</head>
<body>
</body>
</html>
```

<p>div</p>
>
```html
<div></div>
```

<p> a </p>
>
```html
<a href=“”></a>
```

<p>div#top</p>
>
```html
<div id=“top”></div>
```

<p> div.container </p>
>
```html
<div class=“container”></div>
```


<p> div#section.btn.twitter </p>
>
```html
<div id=“section” class=“btn twitter”></div>
```

<p>p{hello} </p>
>
```html
<p>hello</p>
```

<p> p*3 </p>
>
```html
<p></p>
<p></p>
<p></p>
```

<p> div.item*4 </p>
>
```html
<div class=“item”></div>
<div class=“item”></div>
<div class=“item”></div>
<div class=“item”></div>
```

ダミー文章を入力する事もできます。

<p>&lt;p&gt;lorem&lt;/p&gt;</p>
>
```html
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum illum reprehenderit vel rem mollitia, consequatur facilis sapiente earum, voluptatem veritatis officia iusto debitis expedita ducimus excepturi omnis quas voluptas nostrum?</p>
```

<h2>●CSSの場合</h2>

<p>m</p>
>
```CSS
margin: ;
```

<p>p</p>
>
```CSS
padding: ;
```

ピクセルを指定することでもできます。

<p>m10</p>
>
```CSS
margin: 10px;
```


<p>m10-20-30</p>
>
```CSS
margin: 10px 20px 30px;
```

他にも以下のように、省略して記述することも出来ます。

<p>bgc</p>
>
```CSS
background-color: #fff;
```

<p>fsz</p>
>
```CSS
font-size: ;
```

<p>pos</p>
>
```CSS
position: relative;
```

このようにEmmetを使用すればコーディングが捗ります。
Next.js × FastAPIでメディア共有サイトを作る #2 (フロントの構成編)

# はじめに
[こちら](https://qiita.com/kihara-takahiro/items/b1cd5b10bef8aa0ebe75)の記事の続きになります。
本日はフロントの構成をどのように行うかという点について記載していこうと思います。
ソースコードは[こちら](https://github.com/KiharaTakahiro/share-media)


# ディレクトリ構成
srcディレクトリ以下を記載します。

```
.src
|--- common           共通的に使用するロジックの格納
|--- componets        コンポーネントを格納する
|--- |--- parts       部品として使用するべきコンポーネント群
|--- |--- group       partsをグループ化したコンポーネント群
|--- |--- template    画面の表示に関わるコンポーネント群
|--- pages            表示用のロジック
|--- service          APIのコール等のサービスを格納
```

# 悩んだポイント
上記のディレクトリ構成のうちcomponentsの部分をどのように分割するかという点では悩みました。
当初はアトミックデザインを採用しようとしていましたが、以下の点で悩み採用を見送りました。
・ AtomsとMoleculesをどうやって分ければよいかで悩む
・ Atomsの必要性が分からない(自分しか書かないことが起因していると思いますが・・・)

このことからtemplateとpages(これはnext.jsに依存するので選択肢は一択ですが)は残すもののgroupとpartsという分け方にしました。
方針としてそれぞれのインプット等はpartsで作成し、partsの集合をgroupとしてtemplateからはgroupとpartsを使用して画面のレイアウトを決めるという方針にしました。(要はMoleculesをAtomとOrganismsに統合するイメージ)

# 終わりに
他にも良い構成はあるかもしれませんが、いったんはこの方針で行ってみようと考えています。
また、serviceとcommonは統合する方が良いような気もしているので折をみてcommonにしてしまうかもしれないです
Serverless FrameworkでIAMロールを使ってデプロイする方法

Serverless FrameworkでIAMロールを使ってデプロイしようとしてハマったときのメモ。
結論としては、.aws/configだけではなく、.aws/credentialsにもrole_arnとsource_profileの設定をすればOK。

# 環境
## Serverless Framework 
```{bash}
$ serverless --version
Framework Core: 1.69.0
Plugin: 3.6.9
SDK: 2.3.0
Components: 2.30.5
```

## AWSのconfigとcredentials
assume roleしてadmin権限でcli実行するprofileを下記のように設定。

```
$ cat ~/.aws/config 
[default]
region = ap-northeast-2
output = json

[profile admin]
region = ap-northeast-2
role_arn = arn:aws:iam::NNNNNNNNNNNN:role/xxxxxxxx-yyyyyyyy
source_profile = default
```

credentialsファイルはdefaultのみ、下記のように設定。

```
$ cat ~/.aws/credentials 
[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
```

Terminalからaws cliコマンドを直接実行する分には、この設定で問題ない。

# 現象
serverless frameworkを使って、AWS Lambdaのデプロイを試みると、profileが見つからないエラーが表示されて、処理が中断する。参照して欲しいprofileは--aws-profileで設定しているはずなのに...。

```
 serverless deploy --aws-profile admin
 
  Error --------------------------------------------------
 
  Error: Profile admin does not exist
      at Object.addProfileCredentials (/Users/shizuku/.nodebrew/node/v12.16.2/lib/node_modules/serverless/lib/plugins/aws/provider/awsProvider.js:102:15)
      at AwsProvider.getCredentials (/Users/shizuku/.nodebrew/node/v12.16.2/lib/node_modules/serverless/lib/plugins/aws/provider/awsProvider.js:3
...
```

# 対策
awsのcredentialsファイルの方にも、configファイルと同様のプロファイル名のエントリを追記して、role_arnとsource_profileを記載する。

```
$ cat ~/.aws/credentials 
[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
[admin]
region = ap-northeast-2
role_arn = arn:aws:iam::NNNNNNNNNNNN:role/xxxxxxxx-yyyyyyyy
source_profile = default
```
NFSサーバーの構築ついて纏めてみる

# NFSを実現するサービス

|サービス名|サーバー|クライアント|説明|
|---|---|---|---|
|portmap|○|○|RPCプログラム番号をTCP/IPポート番号に変換|
|nfsd|○||ファイルシステムのエクスポートとクライアント要求の処理|
|mountd|○||リモートファイルシステムのマウントおよびアンマウント|

## rpc

```:/etc/rpc
portmapper	100000	portmap sunrpc rpcbind
rstatd		100001	rstat rup perfmeter rstat_svc
rusersd		100002	rusers
nfs		100003	nfsprog
ypserv		100004	ypprog
mountd		100005	mount showmount
```

- TCP/UDPポート番号は動的に割りあてられます
- つまり、RPCクライアントが利用するには、まずポート番号を知ることが必要です
- portmapはRPCクライアントから問い合わせがあると、対応するサービスのポート番号を返します
- RPCを利用してサービスを提供するプログラムは、起動時に自分の情報をportmapに登録します
- RPCサービスの接続状況は、**rpcinfo** で確認できます

```
rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
```

# NFSサーバーの設定

サービスを開始するには次の通りです。

```
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
```

NFSサーバー側で特定のディレクトリを公開することを、**エクスポート**と言います。
エクスポートするディレクトリは、**/etc/exports** に記述します。

```:/etc/exports
/share 192.168.1.0/255.2255.255.0(rw)
/pub   *.example.com(ro)
```

|/etc/exportsのオプション|説明|
|---|---|
|ro|読み取り専用|
|rw|読み書き|
|no_root_squash|rootでのアクセス時にroot権限で実行|
|root_squash|rootでのアクセス時に匿名アカウント権限で実行|
|all_squash|全てのアクセスを匿名アカウント権限で実行|
|fsid|「0」で疑似ルートにする|
|nohide|クライアント側で非表示にしないようにする|

エクスポート状況を表示したり、/etc/exports の変更を反映させるには、**exports** を使います。

|exportsのオプション|説明|
|---|---|
|-a|全てのディレクトリをエクスポート/アンエクスポート|
|-r|全てのディレクトリを再エクスポート|
|-u|アンエクスポート|
|-v|詳細表示|

エクスポートしているディレクトリを調べるには、**showmount** を使う。

|showmountのオプション|説明|
|---|---|
|-a|クライアントのホスト名とマウントしているディレクトリを表示|
|-e|指定したホストでエクスポートしているディレクトリを表示|

NFSの統計情報を調べるには、**nfsstat** を使う。

|nfsstatのオプション|説明|
|---|---|
|-s|NFSサーバー側の統計のみ表示|
|-c|NFSクライアント側の統計のみ表示|
|-n|NFSの統計のみ表示|
|-r|RFCの統計のみ表示|
|-o net|ネットワーク層の統計を表示|

# NFSクライアントの設定

- NFSを使って、リモートファイルシステムをマウントするには、**mount** を使う
- ファイルタイプシステムには、nfs を指定します
- ローカルファイルシステムには、マウントポイントとなるディレクトリを用意しておきます

```
mount -t nfs linux:/pib /mnt/nfs
```

|NFS特有のマウントオプション|説明|
|---|---|
|bg|マウントに失敗してもバックグラウンドで試行|
|fg|フォアグラウンドで実行|
|soft|ソフトマウント|
|hard|ハードマウント|
|intr|ハートマウント時の割り込みを許可|
|retrans|ソフトマウントの場合の再試行回数|
|nolock|ファイルのロックを行わない|
|rsize=|読み取りのブロックサイズ|
|wsize=|書き込みのブロックサイズ|

※[ハードマウントとソフトマウントの違い](http://www.linuxbeginner.com/linux_kihon146.html)

/etc/fstab に記述しておくと、システムの起動時に、リモートファイルシステムを自動的にマウントできます。

```
linux:/pib /mnt/nfs nfs defaults 0 0 
```

# リンク

AWSには、EFSがあるので不要かと思われるが、↓の記事が上手く纏められていた。
[EC2上にNFSサーバ/クライアント構築する](https://qiita.com/shungok/items/462c9abe2c6dd7a3fc69)
✳️NFSv4以降の手順なので、portmap、rpcbind、nfslockは不要
Squid について纏めてみる

# squid.conf

|squid.conf|説明|
|---|---|
|http_port|ポート番号|
|visible_hostname|ホスト名|
|hierarchy_stoplist|キャッシュを利用しない文字列|
|maximum_object_size|キャッシュ可能な最大サイズ|
|minimum_object_size|キャッシュ可能な最小サイズ|
|maximum_object_size_in_memory|メモリ上の最大ファイルサイズ|
|ipcache_size|キャッシュするIPアドレス数|
|cache_dir|キャッシュを格納するディレクトリと容量などのパラメータ|
|cache_mem|メモリ上のキャッシュサイズ|
|cache_access_log|クライアントのアクセスログ|
|cache_log|キャッシュのログ|
|ftp_user|anonymousでFTPアクセスする際のパスワード|
|ftp_passive|FTPのパッシブモード|
|reference_age|キャッシュの保存期間|
|request_header_max_size|HTTPリクエストヘッダの最大サイズ|
|request_body_max_size|HTTPリクエストボディの最大サイズ|
|reply_body_max_size|レスポンスの最大サイズ|
|acl|アクセスコントロールリストの設定|
|http_access|アクセスコントロールリストの制御|


# アクセス制御

## acl

ホストやプロトコルの集合にアクセスコントロールリストを行う。

書式 : `acl ACL名 ACLタイプ 文字列もしくはファイル名`

|ACLタイプ|説明|
|---|---|
|src|クライアント側のIP|
|dst|代理アクセス先サーバーのIP|
|srcdomain|クライアントのドメイン名|
|dstdomain|代理アクセス先サーバーのドメイン名|
|port|代理アクセスサーバーのポート番号|
|myport|クライアントのポート番号|
|arp|MACアドレス|
|proto|プロトコル|
|method|HTTPのメソッド|
|time|有効な時間|
|proxy_auth|ユーザ認証|

## http_access

アクセスコントロールリストに対しての制御を、http_access で行う。

書式 : `http_access allow|deny ACL名`

## アクセス制御の設定例

次の例では、192.168.0.0/24からのアクセスを禁止しています。

```:squid.conf
acl test src 192.168.0.0/255.255.255.0
http_access deny test
```

# やってみる系(Amazon Linux2)

AWSでは、まあ、NAT ゲートウェイを使えばいいでしょうが。

## 準備

クライアントからプロキシを経由して、yumなどを実行できるようにする。

- サブネット
 - piblic-subnet（プロキシサーバー）
 - private-subnet（クライアント）

- セキュリティグループ
 - public-sg：22,3128
 - private-sg:22（public-sgからの接続を許可する。）

## プロキシサーバー設定

### 1

Squidの設定ファイルに直接対象のIPアドレスまたはサブネットのCIDRを記述する。

```squid.conf
acl private-subnet src <プライベートサブネットのCIDR>
http_access allow private-subnet
```

### 2

`/etc/squid/acl/whitelist.txt`にプロキシを経由したいサーバーのプライベートIPアドレスまたは、サブネットのCIDRを記述する。

```squid.conf
acl Whitelist dstdomain "/etc/squid/acl/Whitelist.txt"
http_access allow Whitelist
http_access deny all
```

## クライアント側設定

```/etc/yum.conf
proxy=http://<proxyのプライベートIP>:3128
```

```/etc/wgetrc.
http_proxy=http://<proxyのプライベートIP>:3128
https_proxy=http://<proxyのプライベートIP>:3128
```

```~/.curlrc
proxy=http://<proxyのプライベートIP>:3128
```

# HTTPサーバーとプロキシサーバのリンク
[Apache について纏めてみる](https://qiita.com/leomaro7/items/ef6db835bd44864f7957)
[Nginx について纏めてみる](https://qiita.com/leomaro7/items/98d6af85a4e155449aed)
モデル単体テスト内で、Fakerを使ってランダムな値を生成できるように上書きをする方法

#はじめに
　FakerはFactoryBotでのみ使えるものだと勝手に思っていたけど、RSpecでモデルの単体テストコードを記述するファイルでも使うことができることに気づき、新たに学んだことを記録しておきます。

##Faker

　数字をランダムに生成する記述。

基本的な使い方としては、

```ruby
Faker::Number.between(from: 5, to: 11) #5以上11以下をランダム生成
```

条件を減らすこともできます。

```ruby
Faker::Number.between(from: 11) #11以上をランダム生成
```
`between`ってあるけど、`to:`を付けなければ、最高値を設けずに値を生成できる。
逆に、

```ruby
Faker::Number.between(to: 11) #11以下をランダム生成
```
`from:`を`to:`にすれば、最高値のみを設けて値を生成できる。


###具体的な使い方

####目的
学年を入力する欄で8以上が入力出来ないようになっているかを確認するコードです。

####テストコード

```ruby
before do
  @class_room = FactoryBot.build(:class_room)
end
it '学年が8以上では登録できないこと' do
  @class_room.grade = Faker::Number.between(from: 8) #確かめたい部分を上書き
  @class_room.valid?
  expect(@class_room.errors.full_messages).to include("学年は一覧にありません")
end
```

##最後に
　Railsが便利にRubyを使えるようにしてくれているから、「なぜそうなるのか」ブラックボックスになっていることがたくさんあることに日々気づかされるばかりです。今回でいうと、FakerはFactoryBot内だけだと、思い込んでしました。
git commit の -a オプションで git add を省略する

```console
git commit -am "commit message"
```

-aオプションは変更分を自動検出する。

簡単に言うと`git add`を省略し`git commit`できる。

ただし過去に`git add`したことがあるファイルに限る。
(= git管理の対象になっているファイルに限る。)
Kali Linux ver2020.4でのJISキーボード対応

# 概要
Kali Linux2020.4のデフォルトのキーボードレイアウトをUSからでJISに変更する方法です。

## 方法
1. DesktopのApplicationの検索窓にKeyboardと入力し、Keyboardアプリを開く
![desktop-search.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656421/553c7502-46cc-ce6a-bfbf-9febe75c1284.jpeg)
この検索窓に**Keyboard**と入力してください。

2. AddからJapaneseを追加する
**Keyboard**を開いて上のタブから**Layout**を開くとこのような画面になっていると思います。
![keyboard-layout-tab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656421/67b2ca7a-f556-b904-dab2-360e15bb041d.png)
この画面の**Add**をクリックし、**Japanese**を追加します。
すると先ほどの**English(US)**の下に**Japanese**が追加されたと思います。

3. EnglishをRemoveする
そのままですが、**English(US)**を選択した状態でRemoveをクリックしてください。（Removeした後に、いくらでも再追加することは可能です）
そして**Close**をクリックするとJISのレイアウトが適用され、JISのキーボードを使用しているユーザーでも正しく入力を行えると思います。
Reactでいい感じの拡大サブウィンドウを実装する まとめ記事

Reactでいい感じの拡大サブウィンドウを実装するのまとめ記事です。
随時追加していきます。

# 基礎編
- [Reactでいい感じの拡大サブウィンドウを実装する ① 入門編](https://qiita.com/aokisinn1192/items/dd5f2598aef88d5a824f)
- [Reactでいい感じのサブウィンドウを実装する ② 全画面編](https://qiita.com/aokisinn1192/items/56f577098a4b3b7846ca)
- [Reactでいい感じのサブウィンドウを実装する  ③ リサイズ機能をON/OFF切り替える](https://qiita.com/aokisinn1192/items/64dfe28e93b0ec6f0a0a)
- [Reactでいい感じのサブウィンドウを実装する  ④ ウィンドウ動かす機能をON/OFF切り替える](https://qiita.com/aokisinn1192/items/5ad597acee6a7ac28493)
- [Reactでいい感じのサブウィンドウを実装する  ⑤  初期表示の設定方法](https://qiita.com/aokisinn1192/items/d8acbb36543dd37097c3)

最後まで読んでよかったらLGTMお願いします！
Elasticsearch スロークエリの有効化

**Elasticsearch**は検索の動きが怪しくても、デフォルトではログを追うことができません。この問題が該当する**スロークエリ**の出力方法を記述します。

**環境：macOS/Elasticserch7.4.2**

###確認コマンド

```
curl -XGET ‘localhost:9200/[インデックス名]/_settings?pretty’
```

###設定変更コマンド
クエリやthreshold(0ms)のところは適宜変更、デフォルト値は「-1」（無効）のようです。
クエリは他にも種類があるかも。

```
curl -XPUT ‘localhost:9200/[インデックス名]/_settings’ -H ‘Content-Type: application/json’ -d ‘{
“index.search.slowlog.threshold.query.warn”: “0ms”,
“index.search.slowlog.threshold.query.info”: “0ms”,
“index.search.slowlog.threshold.query.debug”: “0ms”,
“index.search.slowlog.threshold.query.trace”: “0ms”,
“index.search.slowlog.threshold.fetch.warn”: “0ms”,
“index.search.slowlog.threshold.fetch.info”: “0ms”,
“index.search.slowlog.threshold.fetch.debug”: “0ms”,
“index.search.slowlog.threshold.fetch.trace”: “0ms”
}’
```

**参考**
https://qiita.com/hunter9x/items/321a97ebb5a6258d83f2
Reactでいい感じのサブウィンドウを実装する  ② 全画面編

前回の[記事](https://qiita.com/aokisinn1192/items/dd5f2598aef88d5a824f)の続きです。

前回は、いい感じのサブウィンドウを配置するとこで終わったので、今回はこれに全画面表示する機能を付けていきます。

追加するとこんな感じです。
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606623/fbee7626-8f4f-b514-acc3-387db954371f.gif)


# やり方
前回のソースコードに、全画面の状態を持つフックを追加し、
全画面の状態の時に、sizeを指定してあげれば終わりです！


``` javascript
import "./App.css";
import React, { useState } from "react";
import { Rnd } from "react-rnd";

function App() {
  const [isOpen, setIsOpen] = useState(false);
  // 今回ここに全画面表示を管理する状態(ステートフック)を追加
  const [isFull, setisFull] = useState(false);

  return (
    <div className="App">
      <header className="App-header">
        <button onClick={() => setIsOpen(true)}>サブウィンドウを開く</button>
        <br />

        {/* 全画面表示するボタンも追加します */}
        <button
          onClick={() => {
            setIsOpen(true);
            setisFull(true);
          }}
        >
          ウィンドウを全画面で開く
        </button>

        {isOpen ? (
          <Rnd
            style={{
              background: "#fff"
            }}
            default={{
              x: 0,
              y: 0,
              width: 320,
              height: 200
            }}
            // 全画面表示の時は、幅,高さ共に100%表示へ
            size={
              isFull
                ? {
                    width: "100%",
                    height: "100%"
                  }
                : undefined
            }
          >
            <button
              onClick={() => {
                {
                  /* 閉じるときに全画面表示の状態もfalseにします */
                }
                setisFull(false);
                setIsOpen(false);
              }}
            >
              サブウィンドウを閉じる
            </button>
          </Rnd>
        ) : (
          <></>
        )}
      </header>
    </div>
  );
}

export default App;
```

# 最後に
状態を一つ持たせるだけで全画面表示の切り替えができるようになりましたね

次は、リサイズやウィンドウ動かす機能のオンオフのやり方について紹介していきます。

最後まで読んでよかったらLGTMお願いします！

[まとめ記事](https://qiita.com/aokisinn1192/items/32ade691b0fc60dedef0) もあるのでよければこちらもみてください
cloud9でインスタンスを作成し直したい場合

初めて記事を書きます。
これは自分用のメモです


cloud9の設定をミスってしまった。
勢い余ってEC2のストレージ容量を無料枠以上にアゲてしまった。
その他よくわからなくなってまた最初から始めたい。
そのようばあい




githubにpushしていることが前提です。
そのpushをcloud9にcloneします。


loud9に新しいインスタンスを作成します。
作成時の設定はrails チュートリアルに従いました。


gitが入っているかを確認（私の環境では既に入っていました）します。

次に新しく作成したインスタンスに自分のgithubの情報を教えてあげます。

git config --global user.name USER_NAME

git config --global user.email EMAIL_ADDRESS

USER_NAME,EMAIL_ADDRESSには自分のユーザーネームとemailアドレスを代入します。私の場合は、

git config --global user.name irojiroserika

となります。


特にレスポンスがあるわけではありませんが、大丈夫です。もしここでユーザーネーム等間違えてしまった場合はもう一度入力しなおせば良いです。


次にcloneしたいcommitのURLを見つけます。
画像参照（緑色のところをクリックすると出てきます。）

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764848/f4b77c3b-16c2-e650-753c-b4f579d76116.png)

最後に
git clone そのURL

で、clone自体は終了です。
ファイルを確認してください。


しかし、ここから開発を始めようと思ってもrails serverが立ち上がりませんので、bundle installを実行します。

ここで注意点
私はrailsチュートリアルに乗っ取りGemfileを書き換えているため、開発用と本番用で使用するdbが異なります。この場合

bundle install --without production

も実行しなければbundle install時に本番環境のgemがインストールできないというエラーが発生し、結果的にrails serverが立ち上がりません。

ので
bundle install
と
bundle install --without production
も実行します。

あ、そうそう

yarnが入っていない場合もrails serverが立ち上がりませんので、yarnをインストールしてください。
このとき
========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================
というメッセージが返ってくると思いますが、そもそもyarnが入っていない場合は
yarn install --check-files
をそもそも実行できませんので、

source <(curl -sL https://cdn.learnenough.com/yarn_install)
（cloud9環境）

を実行してくださいね。

これでrails serverが立ち上がります。

これで本当に最後です。



rails db:migrateを実行すれば、cloneしてきたアプリがエラーなく見れるようになります。


自分用ですが、為になれば嬉しいです。
Spring Boot + Java + PostgreSQL でDBに画像ファイルをアップロード＆画面表示

#はじめに
ユーザや商品等のテーブルに画像の一緒に保存したくなったので、データベース上に保存できないかどうか色々と調べた結果何とかその方法がわかったので備忘録としての残しておきます。誰かの参考になればと思います。

#完成イメージ
1. 以下のような、画面ファイルのアップロードボタンがあり、画像を選択する
![スクリーンショット 2021-01-01 19.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/a7215dde-8ac1-95b9-7c91-4c90f993697e.png)

2. アップロードボタンをクリックするとアップロードしたファイルが画面に表示されます。
![スクリーンショット 2021-01-01 19.02.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/9997ec2f-00d0-3548-1b9a-8e6e6af79629.png)

#以下必要となるソースコードです
これの応用でウェブアプリケーションに画像の実装ができました:)

```SQL
CREATE TABLE files (
  id SERIAL PRIMARY KEY,
  name VARCHAR,
  type VARCHAR,
  data BYTEA -- ポイント1: 保存したい写真のデータ型をBYTEA(byte array)にする
);
```

```java
@Entity
@Table(name = "files")
@Getter @Setter @NoArgsConstructor
public class FileDB {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private String id;
  private String name;
  private String type;
  　
  @Lob // ポイント2: @Lobと@Typeを以下のようにつける(@Lobはサイズが大きいデータのカラムにつけるみたい。@Typeがないと「bigintのデータが出力されてますよ」的なエラーが出る
  @Type(type = "org.hibernate.type.BinaryType")
  @Column(name = "data")
  private byte[] data;

  public FileDB(String name, String type, byte[] data) {
    this.name = name;
    this.type = type;
    this.data = data;
  }

}
```

```html

<body><!-- ポイント3: formタグに「enctype="multipart/form-data"」追記 -->
  <form th:action="@{/portfolio/file/upload}" method="POST" enctype="multipart/form-data">
    <input type="file" name="file" id="file">
    <button type="submit">UPLOAD</button>
  </form>
  <div>
    <p th:text="${message}"></p>
    <img th:src="${'data:image/png;base64,'+image}" alt="">
  </div>
</body>
```

```java
@Controller
@RequestMapping("/portfolio/file")
public class FileController {
  @Autowired  private FileStorageService storageService;

  @GetMapping(value="/index")
  public String index(Model m) {
    String path = "";
    m.addAttribute("path", path);
    return "file_upload";
  }

  @PostMapping("/upload")
  public String uploadFile(@RequestParam("file") MultipartFile file, Model m) {
    String message = "";
    try {
      FileDB savedFile = storageService.store(file);
      byte[] bytes = savedFile.getData();
      // ポイント4: Base64.getEncoder().encodeToString(bytes)でbyteをStringにして、Viewに渡す
      String image =  Base64.getEncoder().encodeToString(bytes);
      message = "Uploaded the file successfully: " + file.getOriginalFilename();
      m.addAttribute("message", message);
      m.addAttribute("image", image);
      return "file_upload";
    } catch (Exception e) {
      message = "Could not upload the file: " + file.getOriginalFilename() + "!";
      m.addAttribute("message", message);
      return "file_upload";
    }
  }
}
```

```java
@Service
public class FileStorageService {

  @Autowired
  private FileDBRepository fileDBRepository;

  public FileDB store(MultipartFile file) throws IOException {
    String fileName = StringUtils.cleanPath(file.getOriginalFilename());
    FileDB FileDB = new FileDB(fileName, file.getContentType(), file.getBytes());

    return fileDBRepository.save(FileDB);
  }

}
```
気になる関数の実装はドキュメントの</>を押してソースコードをみてみましょう (Elixir)

# はじめに
- [Elixir](https://elixir-lang.org/) 楽しんでいますか :bangbang::bangbang::bangbang:
- <font color="purple">$\huge{今年もよろしくお願いします！！！}$</font>
- 今日は気になった関数のソースコードを見に行く方法をご紹介します
    - この関数、どんな実装になっているのだろう？　って気になることありませんか
- [Elixir](https://elixir-lang.org/)は公式ドキュメントを読むのが一番よいです

## 新年のごあいさつ
```elixir
[12354, 12369, 12414, 12375, 12390, 12362, 12417, 12391, 12392, 12358, 12372, 12374, 12356, 12414, 12377, 127885]
```
:point_down::point_down_tone1::point_down_tone2::point_down_tone3::point_down_tone4::point_down_tone5: 

```elixir
$ iex

iex> (
[12354, 12369, 12414, 12375, 12390, 12362, 12417, 12391, 12392, 12358, 12372, 12374, 12356, 12414, 12377, 127885]
|> List.to_string()
)
"?????"
```

**[Elixir](https://elixir-lang.org/)をインストールして、`IEx(Elixir's interactive shell)`を起動してお確かめください。**
**[Elixir](https://elixir-lang.org/)のインストールは、手前味噌ですが、[インストール](https://qiita.com/torifukukaiou/items/d04d0273749c41eb50af#0-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)などをご参照ください。**


# [List.foldl/3](https://hexdocs.pm/elixir/List.html#foldl/3)

[Elixir](https://elixir-lang.org/)の公式ドキュメントをながめる旅[^1]をしておりましたところ、[List.foldl/3](https://hexdocs.pm/elixir/List.html#foldl/3)なる関数に行き当たりました。

[^1]: 旅と言う名の記事を書くためのネタ探しジャーニーです。

![スクリーンショット 2021-01-01 18.56.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/d2090268-c6aa-86f1-b24c-614bcf09bed6.png)

## [Examples](https://hexdocs.pm/elixir/List.html#foldl/3-examples) だけ書き起こします

```elixir
iex> List.foldl([5, 5], 10, fn x, acc -> x + acc end)
20

iex> List.foldl([1, 2, 3, 4], 0, fn x, acc -> x - acc end)
2
```

- [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)となにが違うのだろう？　という疑問を持ちました
- [Elixir](https://elixir-lang.org/)の実装がどうなっているかを見に行きましょう :rocket::rocket::rocket: 
- 関数の右のほうにある[</>](https://github.com/elixir-lang/elixir/blob/v1.11.2/lib/elixir/lib/list.ex#L238) がリンクになっておりまして押せますですよ！
- **ありがとナイス:flag_cn:**

## https://github.com/elixir-lang/elixir/blob/v1.11.2/lib/elixir/lib/list.ex#L237-L240

```elixir
defmodule List do
  ...

  @spec foldl([elem], acc, (elem, acc -> acc)) :: acc when elem: var, acc: var
  def foldl(list, acc, fun) when is_list(list) and is_function(fun) do
    :lists.foldl(fun, acc, list)
  end
```

## https://github.com/elixir-lang/elixir/blob/v1.11.2/lib/elixir/lib/enum.ex#L2179-L2182

```elixir
defmodule Enum do
  ...

  @spec reduce(t, any, (element, acc -> acc)) :: acc
  def reduce(enumerable, acc, fun) when is_list(enumerable) do
    :lists.foldl(fun, acc, enumerable)
  end
``` 

[List.foldl/3](https://hexdocs.pm/elixir/List.html#foldl/3)、[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)ともにErlangの[lists:foldl](https://erlang.org/doc/man/lists.html#foldl-3)を呼び出しています。 
これにより実行結果は同じになることがわかりました :rocket::rocket::rocket:

# Wrapping Up :moyai::moyai::moyai::moyai::moyai:
- 気になる関数の実装は、ドキュメントの[</>](https://github.com/elixir-lang/elixir/blob/v1.11.2/lib/elixir/lib/list.ex#L238)を押してみましょう :bangbang::bangbang::bangbang: 
- <font color="purple">$\huge{今年もよろしくお願いします！！！}$</font>
- Enjoy [Elixir](https://elixir-lang.org/) :rocket::rocket::rocket:
税金模型の基礎知識

税金関係のシステムを設計する場合に、
税金に関連する貨幣価値と貨幣価値のある対象物の流れを模擬する体系を作るとよい。

貨幣価値の流れの模型は、古くはサミュエルソンの電気回路の数式を利用したものから、計量経済学でさまざま提案があがってきている。

#言語
計算機は模擬試験に用いてきており、
Simulaという言語をはじめ、模擬試験用の言語はさまざま設計されてきている。

R言語, S言語なども統計が得意で、R言語とpythonは相性がよいらしい。

##統計システム
統計処理のシステムも、SAS, SPSS, STATAなどがある。

SPSS
https://www.samuraiz.co.jp/spss/index.html?gclid=CjwKCAiArbv_BRA8EiwAYGs23LXlFSUAZI6FxJCHUG8aHBICKvalEqZAOM5i8R4oBD6ohlWX_x3qJRoC8pUQAvD_BwE





#参考資料
Penn Wharton Budget Model’s Tax Policy Simulator
https://budgetmodel.wharton.upenn.edu/issues/2017/10/16/penn-wharton-budget-models-tax-policy-simulator

Microscopic simulation model of personal income tax system reform based on the perspective of resident income fair distribution
https://www.tandfonline.com/doi/abs/10.1080/09720502.2017.1311047

Use of Simulation Models for the Tax Reform in Slovenia
https://www.researchgate.net/publication/5129483_Use_of_Simulation_Models_for_the_Tax_Reform_in_Slovenia

LEM: A General Program for the Analysis of Categorical Data, January 1997, Jeroen K. VermuntJeroen K. Vermunt
https://www.researchgate.net/publication/228391002_LEM_A_General_Program_for_the_Analysis_of_Categorical_Data
Ruby/Racc: パースに失敗した位置（行、桁）を得る

パースに失敗したとき、失敗した位置をたとえば次のように表示したいですよね？

```
parse error: line 2, col 5
foo bar
    ^
```

----

短いのでとりあえず全部貼ります。

```ruby
# parser.y

class Parser

rule
  program: "a" "b" "c" "d" ";"
  {
    puts "program found"
    result = val
  }
end

---- header

TokenValue = Struct.new(:value, :pos)

---- inner

def initialize(src, tokens)
  @src = src
  @tokens = tokens
end

def next_token
  @tokens.shift
end

def parse
  do_parse
end

def get_lineno_and_range(pos)
  lineno = 1
  line_start = 0
  range = nil

  @src.each_line do |line|
    next_line_start = line_start + line.size
    range = line_start .. (next_line_start - 1)
    break if range.include?(pos)

    line_start = next_line_start
    lineno += 1
  end

  [lineno, range]
end

def on_error(token_id, val, vstack)
  lineno, range = get_lineno_and_range(val.pos)
  colno = val.pos - range.begin + 1
  line = @src[range]

  puts "parse error: line #{lineno}, col #{colno}"

  puts line
  print " " * (colno - 1), "^\n"
end

---- footer

def tokenize(src)
  tokens = []

  pos = 0
  while pos < src.size
    c = src[pos]
    case c
    when /\s/
      pos += 1
    else
      tokens << [c, TokenValue.new(c, pos)]
      pos += 1
    end
  end

  tokens
end

src = File.read(ARGV[0])
tokens = tokenize(src)
parser = Parser.new(src, tokens)
result = parser.parse()
puts "result: " + result.inspect
```

`a` `b` `c` `d` `;` というトークン列だけを受理するパーサです。
入力となるソースコードではトークン同士をスペースや改行で区切ります。

パースに成功する例:

```
a
b

c d
;
```

たとえば `d` を `X` に置き換えた次のソースコードを与えるとパースに失敗します。

```
a
b

c X
;
```

失敗する場合の実行例:

```
$ racc parser.y -o parser.rb

$ ruby parser.rb sample_ng.txt
parse error: line 4, col 3
c X
  ^
result: nil
```

----

短いので上に貼ったコードを読んだ方が早いと思いますが、一応簡単にメモ。

- トークンの開始位置（元のソースコードで何文字目か）をトークン値に持たせておく
- 元のソースコードを `Parser#src` として保持しておく
- パースに失敗したら `Parser#src` と失敗したトークンの開始位置を使って
  元のソースコード上の行と桁を割り出す



# メモ

> 終端／非終端にかかわらず、すべての記号はそれに対応する値（かっこよく言うと semantic value）を持っていて、これを使って情報をやりとりすることができる。
> （略）
> 値としては好きなRubyのオブジェクト1個が使えるので、これはつまり *なんでも送れる* と同義だ。

『[Rubyを256倍使うための本 無道編](https://i.loveruby.net/ja/support/ruby256mudo.html) （[Amazon](https://www.amazon.co.jp/gp/product/4756137091)）』 p46

とのことなので、上記ではトークンの値として `TokenValue` クラスのインスタンスを使っています。


<!--
 # バージョン

 ```
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

$ racc --version
racc version 1.5.0
 ```
-->

# 関連

- [Ruby/Racc: パース時のスタックの動きをFlameGraphっぽくビジュアライズする](https://memo88.hatenablog.com/entry/2021/01/04/103749)

以下は Racc 関連ではありませんが、Ruby + パーサ関連で書いたものということで。

- [Rubyで素朴な自作言語のコンパイラを作った](https://memo88.hatenablog.com/entry/2020/05/04/155425)
- [四則演算と剰余のみのexprコマンドをRubyで作ってみた](https://memo88.hatenablog.com/entry/2020/07/05/111103)
- [正規表現エンジン（ロブ・パイクのバックトラック実装）をRubyで写経した](https://memo88.hatenablog.com/entry/2020/07/23/090115)

# 他に Ruby 関連で書いたもの

https://memo88.hatenablog.com/archive/category/Ruby
【Java】for文についてまとめ

#はじめに

現在Java Silver受験に向けて勉強中です。
勉強の中で、for文について間違えて覚えていたり混乱することが多かったので、自分の言葉で基本からまとめていこうと思います。

#基本
for (初期化文; 条件文; 更新文)　{
　　/// 繰り返し処理
}

```
for(int i = 0; i < 10; i++) {
   System.out.println(i);
}
```

①初期化文
②条件文
③繰り返し処理
④更新文
⑤終了
※②～④を繰り返す

#拡張for文
for (型 変数名 : 集合)　{
　　/// 繰り返し処理
}
※ ;（セミコロン）ではなく:（コロン）であることに注意

```
int[] array = {1, 2, 3}

for(int num : array) {
   System.out.println(num);
}
```

集合の中身を最初から最後まで一つずつ取り出すイメージ。

#繰り返し処理の中断
##break
例：
for (初期化文; 条件文; 更新文)　{
　　if (条件文) {
　　　　break
　　}
　　/// 繰り返し処理
}

```
for(int i = 0; i < 10; i++) {
   if (i = 5) {
      break;
   }
   System.out.println(i);
}
```
breakした時点で繰り返し処理を抜ける（終了する）。
この場合はi=5以降のSystem.out.println(i);が実行されない。

##continue
例：
for (初期化文; 条件文; 更新文)　{
　　if (条件文) {
　　　　continue
　　}
　　/// 繰り返し処理
}

```
for(int i = 0; i < 10; i++) {
   if (i = 5) {
      break;
   }
   System.out.println(i);
}
```
continueした一回分の繰り返し処理をスキップする。
この場合はi=5の時のSystem.out.println(i);のみ実行されず、それ以外はすべて実行される。

#まとめ
for文の中で特に業務でよく使うものをまとめました。
個人的に、学生時代C言語の初歩の初歩を勉強していたのもあり、拡張for文の感覚が掴みづらい部分がありましたのでしっかりと把握しておこうと思います。


参考資料：志賀 澄人『徹底攻略Java SE 8 Silver問題集［1Z0-808］対応 徹底攻略シリーズ』,株式会社ソキウス・ジャパン,2016
「部分和問題」　競プロ例題　#1

### 部分和問題
整数 a_1, a_2,・・・, a_n が与えられる。その中からいくつか選び、その和を丁度kにすることができるかを判定する。

##### 例1
* 入力

```
n=4
a={1,2,4,7}
k=13
```

* 出力

```
Yes
```

##### 例2
* 入力

```
n=4
a={1,2,4,7}
k=15
```

* 出力

```
No
```

### アルゴリズム
a_1 から順に加えるかどうかを決め、n個全てについて決め終わったらその和がkに等しいかを判定する。

### 回答例

```c++

static int n = 4;
static int a[] = {1, 2, 4, 7};
static int k = 15;

//iまででsumを作って、残りi以降を調べる
static bool dfs(int i, int sum) {
    //n個決め終わったら、今までの和sumがkと等しいかを返す
    if ( i == n ) return sum == k;
    
    //a[i]を使わない場合
    if (dfs(i + 1, sum)) return true;
    
    //a[i]を使う場合
    if (dfs(i + 1, sum + a[i])) return true;
    
    //a[i]を使わないに関わらずkが作れないのでfalseを返す
    return false;
}

static void solve_partial_sum() {
    if (dfs(0 ,0)) printf("Yes\n");
    else printf("No\n");
}
```

main関数でsolve_partial_sum()関数を実行する。
[Python] 動的計画法　TDPC D

#[TDPC D](https://atcoder.jp/contests/tdpc/tasks/tdpc_dice)

高校数学の確率問題（場合の数）として解くのは、6=2*3の処理が難しいので、情報数学の手法が適している。
部分構造最適性と部分問題重複性を有するので、動的計画法を検討する。

問題内のデータをそのまま実装するのは難しいので、単純化する必要がある。

積について考えるので、サイコロの目に存在する素因数 2,3,5 の指数のみを考えれば良い。

$10^{18}<2^{60}$ なので、指数として考える値はそれぞれ 60 以下でよいです。

動的計画法の設計は次の通り。

$dp[n][c_2][c_3][c_5]$の定義：
$n$ 回振ったときに、出た目の積に含まれる素因数 2,3,5 の個数がそれぞれ$c_2,c_3,c_5$となる確率

dpの漸化式：

```math
dp[n][nc_2][nc_3][nc_5]=\sum_{i=0}^{n-1}\sum_{c_2\ge nc_2, c_3 \ge nc_3, c_5 \ge nc_5}dp[i][c_2][c_3][c_5]
```

dp初期条件：
$dp[0][0][0][0]=1$（0 回振ったとき、目の積を 1 とするので、素因数にいかなる素数も含まれない）
$dp[0][*][*][]=0$

求めるもの：

$D=2^a 3^b 5^c$のとき

```math
\sum_{p_2\ge a, p_3 \ge b, p_5 \ge c}dp[N][p_2][p_3][p_5]
```

実装は、ボトムアップ方式の配るDPで行う。

```python:サンプルコード
n, d = map(int, input().split())

# サイコロの目を素因数分解すると、2, 3, 5しか現れない
count2 = 0
count3 = 0
count5 = 0
while d % 2 == 0:
    d //= 2
    count2 += 1
while d % 3 == 0:
    d //= 3
    count3 += 1
while d % 5 == 0:
    d //= 5
    count5 += 1

# 2, 3, 5以外があったらだめ
if d != 1:
    print(0)
    exit()

# dp初期化
dp = [[[[0] * (count5 + 1) for i in range(count3 + 1)] for j in range(count2 + 1)] for k in range(n + 1)]
dp[0][0][0][0] = 1

# サイコロの目1~6を素因数分解
d2 = [0, 1, 0, 2, 0, 1]
d3 = [0, 0, 1, 0, 0, 1]
d5 = [0, 0, 0, 0, 1, 0]

# dp[i][c2][c3][c5] := サイコロを i 回振って、2^c2 * 3^c3 * 5^c5 になる確率
for i in range(n):
    # c2,c3,c5および6つの目についてi+1のdpを更新
    for c2 in range(count2 + 1):
        for c3 in range(count3 + 1):
            for c5 in range(count5 + 1):
                for j in range(6):
                    nc2 = min(count2, c2 + d2[j])
                    nc3 = min(count3, c3 + d3[j])
                    nc5 = min(count5, c5 + d5[j])
                    dp[i + 1][nc2][nc3][nc5] += dp[i][c2][c3][c5] / 6

print(dp[n][count2][count3][count5])
```
Next.js × FastAPIの構成でCORSではまる

# 経緯
[こちら](https://qiita.com/kihara-takahiro/items/b1cd5b10bef8aa0ebe75)で紹介させていただいておりますが、Next.jsとFastAPIでNext.jsからAPIをコールするとCORSの設定ではまったので記載させていただきます。

# CORSとは
Cross-Origin Resource Shareringの略で日本語訳すると「オリジン間リソース共有」と呼びます。
そもそも**オリジン**が何かといえば、ページの**スキーム(プロトコル)**、**ホスト(ドメイン)**、**ポート**によって定義されるもので、これらがすべて一致するものが**同一オリジン**であると言えます。
セキュリティ上の理由からブラウザーはスクリプトによって開始されるオリジン間HTTPリクエストを制限しています。
このことからNext.jsとFastAPIでそれぞれ起動している場合はportは異なるのでこの制限を受けてしまいます。

# 発生するエラー
Next.jsを``` http://127.0.0.1:3000 ```で起動しており、fastAPIの``` http://localhost:8000/users/create ```のAPIをコールしたら下記のようなエラーが発生しました。  
![エラー画像.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524088/e017f53a-e659-d759-92f5-009578cd57e6.png)

- **エラーメッセージ**  
```
Access to XMLHttpRequest at 'http://localhost:8000/users/create' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

# 対応方法
FastAPI側からオリジン間共有を認めるように設定する必要があります。
生成したFastAPIのインスタンスに対して下記のように設定することで対応しました。

```python

from starlette.middleware.cors import CORSMiddleware
    app.add_middleware(
      CORSMiddleware,
      allow_origins=["*"],
      allow_credentials=True,
      allow_methods=["*"],
      allow_headers=["*"])
```

# 終わりに
もっと良い対応方法があるかもしれませんが、いったんは上記で対応しました。
すべてを認めてしまってよいのか等は今後考えていきたいなと考えています。
DockerでRails + MySQLの環境構築

## 概要

https://docs.docker.com/compose/rails/ をMySQL用に作り替える。

### 手順:

1. 構成ファイルの準備
    1. Dockerfile作成
    2. Gemfile作成
    3. entrypoint.sh作成
    4. docker-compose.yaml作成
2. ビルド
    1. railsプロジェクトの初期化
    2. imageの更新
3. DBと接続
4. 表示確認

## 構成ファイルの準備

### Dockerfile作成

```Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs build-essential libpq-dev
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```

### Gemfile作成

プロジェクトルートにGemfileを作っておく

```Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5'
```

`Gemfile.lock` を作っておく

```
touch Gemfile.lock
```

### entrypoint.sh作成

```
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

### docker-compose.yaml作成

`db_data` としてvolumeを作って、DBデータを永続化

```yaml
version: "3"
services:
  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
    ports: 
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: root
      MYSQL_USER: admin
      MYSQL_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  db_data:
```

## ビルド

Railプロジェクトつくる。

### railsプロジェクトの初期化

webで rails new を実行して、railsを初期化。
Gemfileが自動的に更新される。

```bash
docker-compose run --no-deps web rails new . --force --database=mysql
```

### imageの更新

Gemfileが更新されたので、イメージを再度ビルド。

```bash
docker-compose build
```

## DBと接続

`config/database.yml` にDB設定を書き込む

```yaml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: root
  host: db

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test

production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
```

## 表示確認

### コンテナ立ち上げ

```bash
docker-compose up -d
```

### DB作成

```bash
docker-compose run web rake db:create
```

http://localhost:3000 に接続して動作確認。
React Routerについて

## 始めに
本筆者はズブズブの素人であリます。学習用の記録であります。

##まずはインストール
```
npm install react-router-dom
```

インストール後はreact-dom-domをimportする。
BrowserRouter, Switch,Route,Link使用できる様にする。

```
//index.js
mport {
  BrowserRouter,
  Switch,
  Route,
  Link
} from "react-router-dom";
```
## BrowserRouter
BrowserRouterのタグ内部でrouter機能が使用できる様になる。
BrowserRouterは1プロジェクトにつき1回しか使えません。
react-router関連のコンポーネントが全て入るように、かなり上の階層で使うことになる。

```
//index.js

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <>
         {/* ここにreact-router関連のコンポーネントを全て書く */}
      </>
    </BrowserRouter>
  </React.StrictMode>,
  rootElement
);

```

## Route
- ルーティング先のURLと、そのURLで表示したいコンポーネントを指定します。
- pathで遷移先のURLしする。
- componentで表示したいコンポーネントを指定します
- exactでURL完全しないと画面遷移されない様にする。react-routerは実はURLが前方一致したコンポーネントを全て表示します。それを予防します。

```
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <>
         <Route path="/" component={APP}/>
      </>
    </BrowserRouter>
  </React.StrictMode>,
  rootElement
);
```
## Link
- LinkはHTMLのaタグと同じような役割。
- toでリンク先を指定することでそこへ遷移できる。
- レンダリングされるとaタグに変換する。<Link>の中にaタグは含めることができない。

----
## fileの分割
上記の内容でroutingの設定を進めると冗長となり、可読性が悪くなる。その為、routing用のファイルを作成し、分割していく。

```
src/router/Public.js

import React from "react";
import { Route, Switch } from "react-router-dom";
import Auth from "../components/auth_componets/Auth";
import Main from "../components/layouts/Main";

const Public: React.FC = () => {
  return (
    <>
      <Switch>
        <Route exact path="/login" component={Auth} />
        <Route exact path="/" component={Main} />
      </Switch>
    </>
  );
};

export default Public;
```

分割したファイルをimportしてやる

```
import Public './router/Public';

const App: React.FC = () => {
  return (
    <BrowserRouter>
      <>
        <Header />
        <Container fixed>
          <Public />
        </Container>
        <Footer />
      </>
    </BrowserRouter>
  );
};
```

## 終わりに
react routerを学習していきました。routerのバリエーションや実践的な内容が増えればアップしていきます。
小ネタ：日付と時刻の表を生成する

以前、[カレンダーを作る関数の記事](https://qiita.com/tanuki_phoenix/items/7c2e3a60fbfcc43022c6)を書きました。
今日たまたま時刻を足したものを作ったので、整理して投稿しておきます。

##実行した様子
Excelシートから呼ぶ時はこんな具合です。当然ながら半角で入力しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/13f87773-428c-f5fb-1eb4-9e0d2a02fc0e.png)
出来上がり品はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/05c383e4-ebe5-b964-fcfd-490d4b84bb14.png)


##コード
日にちは1日ごと、時刻は1時間間隔で固定してます。
変えたい場合は引数追加するか、コード書き換えてください。
（日にち間隔は`#duration(1,0,0,0)`のところ、時間間隔は`#duration(0,1,0,0)`のところ）

```
(開始日 as date,終了日 as date,時刻始 as time,時刻終 as time) as table=>
let
    日にちリスト   = List.Dates(開始日,Duration.TotalDays(終了日-開始日)+1,#duration(1,0,0,0) ),
    日にちだけ     = Table.FromColumns( {日にちリスト},type table[日にち=date] ),
    時刻リスト     = List.Times(時刻始,Duration.TotalHours(時刻終-時刻始)+1,#duration(0,1,0,0) ),
    時刻リスト入れ = Table.AddColumn(日にちだけ, "時刻", each 時刻リスト ,type {time} ),
    時刻列の展開   = Table.ExpandListColumn(時刻リスト入れ, "時刻")
in
    時刻列の展開
```


##注意点など
テスト環境：Excel365（バージョン2011、64bit）
Power Query：2.87.846.0
##リンク
durationの書き方
https://docs.microsoft.com/en-us/powerquery-m/sharpduration
List.Datesの仕様
https://docs.microsoft.com/en-us/powerquery-m/list-dates
List.Timesの仕様
https://docs.microsoft.com/en-us/powerquery-m/list-times
Git基本コマンド(リモートレポジトリ編)

**リモートリポジトリの確認**

```
git remote     //登録されているリモートリポジトリのショートカット名
git remote -v  //URL
```

**リモートレポジトリの追加**
複数追加できる

```
git remote add 'リモート名' 'リモートURL'
git remote add project https://github.com/user/project.git
```

*****
**リモートから取得する（フェッチ）**

```
git fetch 'リモート名'
git fetch origin
```
リモートレポジトリからローカルレポジトリに取ってくる。
保存場所は　remote/リモート名/ブランチ名
ワークツリーには反映されていない！

ワークツリーに反映させるには

```
git merge
```

自分が管理しているgitを確認するには

```
git branch -a
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/709175/27404f9e-5241-f3e1-ed03-1b6092a44320.png)
緑が今自分のいるgit(ローカルリポジトリ)
赤は自分か管理している他のgit

今自分がいるgitを切り替えるには、例えば

```
git checkout remotes/origin/master
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/709175/21eb06b2-7564-cc72-5655-1995a10f7334.png)
※が今いるレポジトリ（リモートレポジトリ）
ローカルレポジトリは白になった。
リモートリポジトリは赤になった。

最後にワークツリーに反映させるには

```
git merge origin/master  //オリジンレポジトリのマスターブランチの情報を自分のワークツリーにマージ（統合）することになる
```
*****

**リモートから取得する（プル）**
リモートからマージまで一気に行いたいとき

```
git pull 'リモート名' 'ブランチ名'
git pull origin master
```

ここでoriginとmasterについて
・originはリモートレポジトリーのショートカット名
・masterはメインのブランチ名
なので、git pull origin master
はリモートレポジトリーからローカルレポジトリにコピーしてマージすることになる。
この一行で

```
git fetch origin master
git marge origin/master
```

を行うことになる。
プルは簡単だが基本はフェッチを使う。
自分が今いるブランチと違うリモートレポジトリからプルしてしますとえらいことになる。（消えてしまう）

*****
**リモートの詳細情報の表示**

```
git remote show 'リモート名'
git remote show origin
```
FetchのURL
PushのUTL
リモートブランチ
git pullの挙動
git pushの挙動
がわかる

*****
**リモート名の変更・削除**

```
git remote rename '旧リモート名'　'新リモート名'
git remote rename aproject bproject

git remote rm 'リモート名'
git remote rm bproject
```