OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoderログ：0086 - パナソニックプログラミングコンテスト2020 B

# 問題

https://atcoder.jp/contests/abc157/tasks/abc157_b

## 問題文
> 縦 $H$ マス、横 $W$ マスの盤面があります。 この盤面の左上隅のマスに角行の駒が置かれています。 駒が $0$ 回以上の好きな回数の移動を繰り返して到達できるマス目は何個あるでしょうか？
> ただし、角行の駒は斜めに動くものとします。 より厳密には、駒が上から 
$r_1$ 番目、左から $c_1$ 番目のマスから上から $r_2$ 番目、左から $c_2$
 番目のマス目に動ける条件は
> ・$r_1+c_1=r_2+c_2$
> ・$r_1−c_1=r_2−c_2$
> のうちちょうど一方が成立することです。

## 制約
> ・$1 \le H,W \le 10^9$
> ・入力は全て整数である。

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #006 

# 回答
## 回答1 (AC)
駒は斜めに移動するので、$H$ または $W$ が偶数ならば駒はマス目のちょうど半分のコマを移動することができ、到達できるマス目の数は $HW/2$ 個となります。また、$H$ も $W$ も奇数ならば、コマは半分より1個多いコマを移動することができるので、到達できるマス目の数は $(HW+1)/2$ 個となります。

これをコードにすれば良いと思いきや、これでは WA になってしまいます (なってしまいました)。これは $W=1$ または $H=1$ になっている場合を見落としていることが原因です。マス目が1行または1列の場合には、コマは全く移動できないことに気づく必要があるのです。この場合、到達できるマス目の数は $1$ 個であり、コードでは別扱いが必要があります (私はこの例外になかなか気づかず、WA を重ねてしまいました)。以上よりコードは次のようになります。

```C++:panasonic2020b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int64_t h, w;
  cin >> h >> w;

  if ( h==1 || w==1 ) {
    cout << 1 << endl;
  } else if ( 'h*w)%2==0 ) {
    cout << h*w/2 << endl;
  } else {
    cout << (h*w+1)/2 << endl;
  }
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2020/03/15/001953)
回答1と同じ方針ですが、出力式は「(h*w+1)/2」にまとめられるとのことでした。

## [AtCoder の解説](https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/panasonic2020/editorial.pdf)
回答1と同じ方針です。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0085 - ABC 049 C](https://qiita.com/RoadLynton/items/41948daf753fd82b878a)
- 次の記事 → [AtCoderログ：0087 - AGC 013 A](https://qiita.com/RoadLynton/items/e0e71defea0554a38874)
Webpack 備忘録

少しわかりにくかったところ。

## cross-env

* `NODE_ENV`を含んだscriptsを打つとwindowsのコマンドプロンプトでうまく動作しない
* scriptsに含むことで**プラットフォームの挙動の差異を無くす**

```
"scripts": {
    "watch": "cross-env NODE_ENV=development webpack-dev-server --color",
    "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.babel.js"
  },
```

[npm cross-env](https://www.npmjs.com/package/cross-env)
[dotenvとcross-envで環境変数を設定して開発環境の処理を切り替える](https://www.tam-tam.co.jp/tipsnote/program/post17589.html)



## contentBase

```webpack.config.babel.js
// webpack-dev-server
  devServer: {
    open: true,
    port: 3000,
    // contentBaseに指定したディレクトリに変更があった場合リロードされる
    watchContentBase: true,
    contentBase: path.join(__dirname, 'public'),
  },
```

* portの3000を明示するために`contentBase`にはビルド後のファイルをカレントディレクトリとして指定する
* 注意すべきは`watch`コマンドを打った場合、実際にはビルドされずメモリに保存されるだけという点（ブラウザには反映される）
* 通常ビルド後のファイルに変更があってもdevserverは応答しないが、`watchContentBase`をtrueにすることでビルド後のファイルにも対応できる

[webpack-dev-server のオプション全部試した](https://zenn.dev/sa2knight/articles/9b19ffd391bca87d7b8c)
[webpack-dev-serverで開発用サーバを立てる](https://numb86-tech.hatenablog.com/entry/2017/05/03/123659)

## .babel拡張子について

* なぜ`webpack.config.babel.js`がES6以降の書き方にも関わらずトランスパイルされているのか
* 結論

> interpret の仕組みはとても簡単で、設定された拡張子に対して動的な前処理を適用するだけです。 interpret の方で、 .babel.js という拡張子に対しては、 babel-register で変換して処理するという風に定義されていますので、 webpack.conf.babel.js でも問題なく処理できるというわけです。

[BabelでES6で書いて、webpackでビルドして、mochaでテスト書いて、power-assertでassertの出力を見やすくして、karmaで複数ブラウザのテストを自動化して、カバレッジを出力するようにした
](https://system.blog.uuum.jp/entry/2016/09/16/110000)
【Material UI】onChangeが反応しない

## 現象
- 下記のようなRatingのコンポーネントを使用していた
- 親コンポーネントでも子コンポーネントでもRatingを使用したかったのでコピペして全く同じコードを使用していた
- 画面上でRatingを変更しても、onChangeに設定したハンドラが呼び出されていなかった（

```react
<Rating
    name="rating"
    value={value}
    onChange={handleChange}
/>
```


## 原因
- 色々調べた結果、[こんな記事](https://stackoverflow.com/questions/62348367/material-ui-rating-component-does-not-update-star-rating-correctly)を見つけた
- 同じ`name`を定義を持つコンポーネントを定義すると起きる現象とのこと
- ただ動作検証したところ、あくまで同ページ内での制約っぽい


## 修正
- 親子で`name`を変えました

```react:親コンポーネント
<Rating
    name="parent-rating"
    value={value}
/>
```

```react:子コンポーネント
<Rating
    name="child-rating"
    value={value}
    onChange={handleChange}
/>
```
3.19(難) ベータ分布

## 方針

ベータ分布と二項分布の関係を示す問題．X~Beta(alpha,beta)の時，確率密度関数は，

```math
f_X(x)=\frac{1}{B(\alpha,\beta)}x^{\alpha-1}(1-x)^{\beta-1}
```

ただしBをベータ関数といい，

```math
B(\alpha,\beta)=\int_0^1t^{\alpha-1}(1-t)^{\beta-1}dt
```

である，ベータ関数は

```math
B(\alpha,\beta)=\frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha+\beta)}
```

という性質を持つ．全確率1を示す．

```math
\begin{align}
\int_0^1\frac{1}{B(\alpha,\beta)}x^{\alpha-1}(1-x)^{\beta-1}dx&= \frac{1}{B(\alpha,\beta)}\int_0^1x^{\alpha-1}(1-x)^{\beta-1}dx\\
&= \frac{B(\alpha,\beta)}{B(\alpha,\beta)}\\
&= 1
\end{align}
```

分布関数は，

```math
\begin{align}
F_X(x)&= \int_0^x\frac{1}{B(\alpha,\beta)}t^{\alpha-1}(1-t)^{\beta-1}dt\\
&= \frac{1}{B(\alpha,\beta)}\int_0^xt^{\alpha-1}(1-t)^{\beta-1}dt
\end{align}
```

期待値と分散は，

```math
\begin{align}
\mathbb{E}_{X\sim Beta(\alpha,\beta)}[X]&= \int_0^1\frac{1}{B(\alpha,\beta)}x^\alpha(1-x)^{\beta-1}dx\\
&= \frac{B(\alpha+1,\beta)}{B(\alpha,\beta)}\int_0^1\frac{1}{B(\alpha+1,\beta)}x^\alpha(1-x)^{\beta-1}dx\\
&= \frac{\Gamma(\alpha+1)\Gamma(\beta)}{\Gamma(\alpha+\beta+1)}\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}\\
&= \frac{\alpha}{\alpha+\beta}\\
\mathbb{E}_{X\sim Beta(\alpha,\beta)}[X^2]&= \int_0^1\frac{1}{B(\alpha,\beta)}x^{\alpha+1}(1-x)^{\beta-1}dx\\
&= \frac{B(\alpha+2,\beta)}{B(\alpha,\beta)}\int_0^1\frac{1}{B(\alpha+2,\beta)}x^{\alpha+1}(1-x)^{\beta-1}dx\\
&= \frac{\Gamma(\alpha+1)\Gamma(\beta)}{\Gamma(\alpha+\beta+2)}\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}\\
&= \frac{\alpha(\alpha+1)}{(\alpha+\beta+1)(\alpha+\beta)}\\
Var(X)&= \frac{\alpha(\alpha+1)}{(\alpha+\beta+1)(\alpha+\beta)}-\frac{\alpha^2}{(\alpha+\beta)^2}\\
&= \frac{\alpha\beta}{(\alpha+\beta+1)(\alpha+\beta)^2}
\end{align}
```

## 答案

X~Bin(n,p)の時，

```math
\begin{align}
P[X\leq x]=\sum_{k=0}^x{}_nC_xp^x(1-p)^{n-x}
\end{align}
```

Y~Beta(n-x,x+1)の時，

```math
\begin{align}
P[Y\leq 1-p]&= \int_0^{1-p}\frac{1}{B(n-x,x+1)}y^{n-x-1}(1-y)^xdy\\
&= \frac{\Gamma(n+1)}{\Gamma(n-x)\Gamma(x+1)}\int_0^{1-p}y^{n-x-1}(1-y)^xdy\\
&= \frac{n!}{(n-x-1)!x!}\int_0^{1-p}\{\frac{1}{n-x}y^{n-x}\}'(1-y)^xdy\\
&= \frac{n!}{(n-x)!x!}\{\left[y^{n-x}(1-y)^x\right]_0^{1-p}+x\int_0^{1-p}y^{n-x}(1-y)^{x-1}dy\}\\
&= {}_nC_xp^x(1-p)^{n-x}+\frac{n!}{(n-x)!(x-1)!}\int_0^{1-p}y^{n-x}(1-y)^{x-1}dy\\
&= {}_nC_xp^x(1-p)^{n-x}+\frac{\Gamma(n+1)}{\Gamma(n-x+1)\Gamma(x)}\int_0^{1-p}y^{n-x}(1-y)^{x-1}dy\\
&= {}_nC_xp^x(1-p)^{n-x}+\int_0^{1-p}\frac{1}{B(n-x+1,x)}y^{n-x}(1-y)^{x-1}dy\tag{1}
\end{align}
```

ここで，

```math
P_x=\int_0^{1-p}\frac{1}{B(n-x,x+1)}y^{n-x-1}(1-y)^xdy
```

と置くと，

```math
\begin{align}
P_0&= \int_0^{1-p}\frac{1}{B(n,1)}y^{n-1}dy\\
&= n\int_0^{1-p}y^{n-1}dy\\
&= n\left[\frac{1}{n}y^n\right]_0^{1-p}\\
&= (1-p)^n\\
&= {}_nC_0p^0(1-p)^n
\end{align}
```

である．(1)より，

```math
\begin{align}
P[Y\leq 1-p]&= P_x\\
&= {}_nC_xp^x(1-p)^{n-x}+P_{x-1}\\
&= {}_nC_xp^x(1-p)^{n-x}+{}_nC_{x-1}p^{x-1}(1-p)^{n-x+1}+P_{x-2}\\
&\vdots\\
&= {}_nC_xp^x(1-p)^{n-x}+{}_nC_{x-1}p^{x-1}(1-p)^{n-x+1}+...+{}_nC_0p^0(1-p)^n\\
&= \sum_{k=0}^x{}_nC_kp^k(1-p)^{n-k}\\
&= P[X\leq x]
\end{align}
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
エクセル複数シートの結合


#1.はじめに & 動作環境
バックオフィスにおいて日常的に発生する業務にエクセルの加工作業がある。
これらの多くの作業は同じ作業の繰り返しであることが多いため、これらをできる限り自動化することで業務の効率化と生産性の向上を目指す。

#2.工程図 for Excel1納期管理表
納期管理表はアイテムごとにシートで分けて管理されている。
そのままだと集計する際に不便なため、一つのシートに全てのアイテムを統合したサマリーシートを作成する。

1.シェアドライブに保管している管理表エクセルの読み込み
2.シートを左から順に読み込んでいく
3.新規シートの作成（サマリーシート）
4.読み込んだシートの情報をサマリーシートに上から順に書き込み
5.ブックのコピーを別名でローカルドライブに保存
![BacklogList.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811258/9d13c01b-17c2-0d38-10e0-5c9f4bc9f8e8.jpeg)


#3.コードの作成 for Excel1納期管理表


```python
import openpyxl

wb = openpyxl.load_workbook(“S:\\xxxDpt\\sales\\001 納期管理表\\n_納期管理表2021Custxyz.xlsm") #Sドライブ上のエクセルの読み込み

is_first_sheet = True #初期値をTrueにしておく
row_list = [] #row_listという空リストを用意し、この中に各シートの行を順次追加する

for ws in wb.worksheets:　#シートを順に読み込んでいく
    if is_first_sheet:
        start_row = 1　#最初のシートは１行目から読み込む
    else:
        start_row = 4　#最初のシート以外は４行目から読み込む
    
    for row in ws.iter_rows(min_row=start_row):
        if row[0].row > 3 and row[0].value is None:　#A列３行目以降が空セルだったら読み込み完了
            break
        value_list = []
        for c in row: ＃読み込んだデータをvalue_listに格納していく
            value_list.append(c.value)
        row_list.append(value_list)
        
    is_first_sheet = False

ws_new = wb.create_sheet(title="SUMsheet") ＃新規シートの作成

row_num = 1  # 書き込み時の行番号

for row in row_list:　#新しいシートに1行ずつデータを書き込む
    ws_new.append(row)
    
    if row_num > 3:
        ws_new.cell(row_num, 1).number_format = "yyyy/m/d"
    row_num = row_num +1

ws_new.delete_rows(idx=1, amount=2)

wb.save(“C:/Users/KY/Documents/n.納期管理表/SUMBook_Custxyz.xlsx") # 別名でブック保存
```

#4.完成 for Excel1納期管理表
二つのシートに分かれて記載してあったItem x1とItem x2を統合して１つのシートにまとめて記載することができた。

model_Aシートの製品X1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811258/d1ccf031-7e47-60bf-5f05-7aa4adaa079d.png)

model_Bシートの製品X2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811258/7b9aca42-135d-8e38-c981-19733311e2dc.png)

新規作成したSUMシートに製品X1 と製品X2の両方が転記された
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811258/f1de49a3-0324-4d25-8b7e-ee316d453bc1.png)


なお、非表示にしているシートも読み込んでしまうが、A列を空欄にしておくことで読み込まないようにさせている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1811258/e98b566d-7249-03ee-4902-35184cb28e1e.png)

今回使用したデータはダミーのため、２シートしかなく、データ自体も少なくしているが、
実際に使用しているブックは10シート以上あり、データ数も膨大である。


以上
Laravel+Vue.jsでコンポーネントを使わずにバインドするには

Laravelのbladeでvueコンポーネントを使わずに直接vueをバインドしたいなぁ。
けど、bladeで`{{ xxxx }}`を書くと、phpの変数参照でエラーになるので、その解決方法です。

## Laravel+Vue.jsでコンポーネントを使わずにバインドするには

### その1

頭に@ つける

`@{{ xxxx }}`

参考サイト
https://blog.capilano-fw.com/?p=8367#BladeVue

### その2
”Mustache” 構文(二重中括弧) `{{ xxxx }}` を変更する

[Vue.jsでマスタッシュ記法で記述するデリミタを変更する方法](https://leben.mobi/blog/vue_delimiter/javascript/)

Vue.js 2系の場合

```js
new Vue({
    el: '#app',
    data: data,
    delimiters: ["<%","%>"]
});
```

### その3

v-text属性でバインドする。
` <span v-text="xxxx"></span> `

参考サイト
https://blog.capilano-fw.com/?p=8367#Vue

## おまけ：非同期の値が再描画されない

[JavaScript - axiosでポストして帰ってきたデータがVueのv-modelに再描画されない｜teratail](https://teratail.com/questions/103176)

### 原因

> 原因としてはthen内でthisが指しているのは Vue instance ではないからです。console.logしてみると確かめられます。
解決策としては、3つぐらいあります。

### 対応

#### arrow function

```js
.then(response => {
  // "this" points to the vue instance
})
```

#### bind

```js
.then(function (response) {
  // "this" points to the vue instance
}.bind(this))
```

#### this の退避

```js
const self = this

// ...
.then(function (response) {
  // "self" points to the vue instance
})
```

## おまけ２：Laravelではaxiosで非同期通信するとCSRFトークンは自動でセットしてくれる

[LaravelのBladeにVueコンポーネントを組み込む - やんばるテック](https://blog.shonansurvivors.com/entry/laravel-blade-vue)
> なお、axiosによる非同期通信のリクエストヘッダのX-XSRF-TOKENには、Laravelのクッキーから取得したCSRFトークンの値が自動でセットされます。


## 参考URL

* [テンプレート構文 — Vue.js](https://jp.vuejs.org/v2/guide/syntax.html)
spctlコマンド

# はじめに
　キーボード自作の際に、QMK Firmwareを入れ直した。

　その際に「"QMK Toolbox.app"が悪質なソフトウェアかどうかをAppleでは確認できないため、このソフトウェアは開けません」というエラーメッセージがでてQMK Toolbox.app（QMK toolbox；QMKファームウェアベースの自作キーボードに搭載されたPro MicroにQMK Firmwareのhexファイルを書き込むためのGUIソフトウェア[[1]]）を開くことができなかった。

　こういった場合には、「システム環境設定」-> 「セキュリティとプライバシー」で設定を変更して対処できることが多いが、今回はうまくいかなかった（勘違いかもしれませんが、、、）。

　googleで検索すると、`spctl`コマンドで許可を与えてQMK toolboxを開けるということがわかり、実際にやってみてうまくいった[[2]]。

　自作キーボード界隈で`spctl`コマンドはあまり話題にならないので記事にすることにした。

# 環境
macOS; version 11.3
zsh; zsh 5.8 (x86_64-apple-darwin20.0)
QMK Toolbox; Version 0.1.1 (0.1.1)

# spctlコマンド

　spctlは`man`によると、'SecAssessment system policy security'の略らしい。

使い方は以下[[3]][[4]][[5]]。

```zsh
#すべてのアプリケーションを許可
sudo spctl --master-disable

#元に戻す
sudo spctl --master-enable

```


\[1\]Helix 自作キーボード製作記 (その3) │ Rephtone, https://rephtone.com/electronics/helix-keyboard-part3/
\[2\]"QMK Toolbox.app”が悪質なソフトウェアかどうかをAppleでは確認できないため、このソフトウェアは開けません。 - :wq, https://scrapbox.io/ima1zumi/%22QMK_Toolbox.app%E2%80%9D%E3%81%8C%E6%82%AA%E8%B3%AA%E3%81%AA%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92Apple%E3%81%A7%E3%81%AF%E7%A2%BA%E8%AA%8D%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%9F%E3%82%81%E3%80%81%E3%81%93%E3%81%AE%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AF%E9%96%8B%E3%81%91%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
\[3\]Gatekeeperの許可リストにアプリを追加するターミナルコマンド | Macの手書き説明書, https://mac-tegaki.com/basic-usage/gatekeeper-command.html
\[4\]macOS Sierraで「すべてのアプリケーションを許可」の設定を復活させる | Macの手書き説明書, https://mac-tegaki.com/basic-usage/sierra-mac-app-store-permission.html
\[5\]Mac - すべてのアプリケーションの実行を許可 | PC設定のカルマ, https://pc-karuma.net/macos-sierra-allow-apps-from-anywhere/


[1]:https://rephtone.com/electronics/helix-keyboard-part3/
[2]:https://scrapbox.io/ima1zumi/%22QMK_Toolbox.app%E2%80%9D%E3%81%8C%E6%82%AA%E8%B3%AA%E3%81%AA%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92Apple%E3%81%A7%E3%81%AF%E7%A2%BA%E8%AA%8D%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%9F%E3%82%81%E3%80%81%E3%81%93%E3%81%AE%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AF%E9%96%8B%E3%81%91%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
[3]:https://mac-tegaki.com/basic-usage/gatekeeper-command.html
[4]:https://mac-tegaki.com/basic-usage/sierra-mac-app-store-permission.html
[5]:https://pc-karuma.net/macos-sierra-allow-apps-from-anywhere/
App Storeレビュー時に審査員のネットワーク環境が原因でリジェクトされた話


## 結論
[審査員のネットワーク環境が原因で接続を確立できない](https://developer.apple.com/forums/thread/133938)のが原因。

対処法としては...
- レビュワーと交渉して別のネットワーク環境での接続を試してもらう
- 動作時の動画を送って問題なく動作することを証明する etc...

---

## 問題の発生
ClubHouse等で使われている[AgoraSDK](https://jp.vcube.com/service/agora)を使ったビデオ通話アプリの申請中、
Apple審査員から「通話機能が使えません」とのことでリジェクトされる。
→ ちなみに他の接続を要する機能は使えてました。

## 調査
### 原因の特定
カメラや音声設定の可能性もあるので、ひとまず該当箇所にログを仕込んで原因箇所を特定。
通話処理部分の各ステップごとに自社サーバー側へログを送信する処理を実装。
SDKで用意している関数内で通話接続の確立に失敗していることが判明。

社内Wifiや4G、LTE等の通信環境、端末やOSのバージョンを変えて試してみるも再現できず...

審査員側の端末内に出力されるAgoraSDKのログを取得してサポートに解析を依頼。
ログを解析してもらったところ、「通話接続の試行時にタイムアウトが発生しており、通話機能で必要なポートが相手方ネットワーク環境で開放されていない可能性がある」とのこと。

### 類似の問題がないか
色々調べているとAppleの開発者フォーラムに類似の質問を発見。
UDPやらTCPやら使う際に稀に発生している問題らしいです。
[Apple reviewer can't connect - Apple Developer Forums](https://developer.apple.com/forums/thread/133938)

## 対処した方法
審査員に「ネットワーク環境が問題とのログが出ています。具体的には〜。ネットワーク環境を変えてお試しください。」と送って再度レビューしてもらうよう依頼。

#### → 通りました！


## 参考リンクまとめ
[Apple reviewer can't connect - Apple Developer Forums](https://developer.apple.com/forums/thread/133938)
[Agora ビデオ通話・ライブ配信SDK - ブイキューブ](https://jp.vcube.com/service/agora)
【Firebase】別アカウント管理のGoogle Playと接続する方法

# TL;DR
Google Playのオーナー or 管理者アカウントユーザーを、Firebaseのプロジェクトに「オーナー」としてメンバー追加して、そのユーザーに接続してもらえばOK

# はじめに
FirebaseのプロジェクトはGoogle Playと接続できます。

[プロジェクト設定] > [統合]の Google Play の箇所
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/c33208b7-d6fd-2fac-bcca-e25295a52abb.png" width=600 />

接続すると、Google Playの収益データがFirebase上から利用できたり、Firebase App DistributionのAndroid App Bundle（aab）配信を使えるようになったりします。:sunglasses:

[【Firebaseヘルプ】Google Play を Firebase にリンクする](https://support.google.com/firebase/answer/6392038?hl=ja)

便利なので、できれば接続しておいたほうがいいと思いますが、接続するには接続したいアプリの**Google Play アカウントのオーナーまたは管理者アカウント**であることが必要となります。

FirebaseとGoogle Playを両方自社で管理していれば問題ありませんが、受託開発などで **Firebaseは開発会社管理・Google Playは別会社管理** という場合には接続することができません。:innocent:

# Firebaseに管理者としてメンバー追加し、接続してもらう
では、別管理の場合 FirebaseとGoogle Playは接続できないのか？ というとそうではなく、**Google Playのオーナー or 管理者アカウントユーザーを、Firebaseのプロジェクトに「オーナー」としてメンバー追加して、そのユーザーに接続してもらえばOK** でした。

Firebaseのプロジェクトで :gear:（設定）から、[ユーザーと権限] を選択し、[役割] を「オーナー」にして招待します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/dddbc714-7a4c-0665-ba77-a72908dd814d.png" width=400 />

※ オーナー以外にした場合、接続の画面に遷移することができません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/3d7f7207-787f-27ec-8454-1138545e136a.png" width=400 />

オーナーとして招待に応じてもらったら、あとはポチポチとしてもらうだけでOKです。

「Google Play に接続する」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/6d37f75e-4a40-f98a-036b-7fdf88af1eff.png" width=600 />

接続が完了するとこんな感じ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/a3821b20-36d8-34d2-2676-50ee32387a38.png" width=600 />

招待さえしてしまえば、あとは簡単に接続することができました！
（まぁ別会社の人に接続するようにお願いするのも、それはそれで大変だったりするわけですが…。）


# メンバーから外したらどうなる？
最後に検証した内容の共有ですが、オーナーとして追加したユーザーをFirebaseのメンバーから外した場合でも、Google Playとの接続は残ったままのようでした。:ok_hand:

なので、Google Playと接続するために一時的にメンバーに追加して、用が済んだらメンバーから外す、という対応も可能であると言えます。
【図解】screenコマンド入門（迷子向け）

screenコマンドを初めて使った時、自分がどこにいるのか全く分からなくなり、正直迷子になりました
原因はウィンドウとセッションの混同だったのですが、この概念の違いを図で説明している記事があまりなかったため、入門記事を書いてみました

この記事が同じ迷子たちの道標となることを祈ります🙏

# screen 概要

screenコマンドはCLI上でのマルチターミナル環境を実現するコマンドです
以下でインストールします

```shell
$ apt install screen
```

screenではセッションという単位で作業スペースを作ることができ
セッション内では更にウィンドウという単位で実行環境を分けられます

![screen command figure (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303575/2abc003c-23ac-fcbf-ee57-65dd84b36816.png)

**図のターミナルウィンドウ全てが独立したシェル環境**です

screen移動操作は、おおまかに上の図の赤色と青色の矢印の2種類があり、
赤矢印はログインシェルとセッション操作、`screen`コマンドを使います
青矢印は同一セッションのウィンドウ操作、`Ctrl-a`キーを使います

実際にコマンド入力を通してセッションとウィンドウを作成してみましょう

## セッション操作

まずはログインシェル（普段つかっているシェル）から`screen`と入力

```shell
$ screen
```

新しいセッションを作成すると同時に`0$ bash`のウィンドウが自動的に作られ、0$に接続します
screenの説明が出てきた場合はエンターキーで閉じます

![screen command figure (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303575/4b280934-238d-811c-aef7-fcadec9f2e4f.png)


#### ウィンドウ操作

ウィンドウ内の操作の基本は`Ctrl-a`です
`Ctrl-a`を押すと表示は変わりませんがコマンド受付状態になります

#### ウィンドウ作成

`Ctrl-a, c`で新しいウィンドウを作って接続します
あるいは`screen`コマンドを打ちます

```shell
$ (Ctrl-a), (c)
$ screen（ウィンドウ内）
```

#### ウィンドウ一覧

`Ctrl-a, w`で現在のセッションのウィンドウ一覧を表示します

```diff_shell
$ (Ctrl-a), (w)
+ 0-$ bash    1*$ bash
```

緑ハイライトの部分が表示されていれば正しくウィンドウ操作ができています
現在のセッションでは`0$`と`1$`のウィンドウが存在しています


![screen command figure (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303575/972ab305-eb4d-43a9-3aae-df2aa97294b7.png)


#### ウィンドウ間の移動

ウィンドウ間を移動する方法は複数あります
状況に合わせて選択すると良いでしょう

```shell
$ (Ctrl-a), (0-9)
{0-9}$のウィンドウに移動

$ (Ctrl-a), (Space)
一つ次のウィンドウに移動

$ (Ctrl-a), (Ctrl-a)
直近のウィンドウに移動
```

#### その他ウィンドウ操作

```shell
$ (Ctrl-a), (k)
$ (Ctrl-d)
$ exit
ウィンドウを削除

$ ctrl+a ?
ヘルプ表示
```

セッション内すべてのウィンドウを削除すると自動的にセッションが削除されログインシェルに戻ります

## ログインシェルへ戻る

#### セッションのデタッチ

ウィンドウ内で`screen -d`と打つとセッションから抜けます(デタッチ)
あるいは`Ctrl-a, Ctrl-d`を打ちます

```shell
$ screen -d
$ (Ctrl-a), (Ctrl-d)
```

![screen command figure (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303575/45a67d19-ba68-6bc5-5b05-fce02b79a6c5.png)


#### セッションの一覧

`screen -ls`でセッションの一覧とセッションのPIDを表示します

```shell
$ screen -ls

There is a screen on:
        (PID).pts-0.mycomputer        (08/19/21 23:36:09)     (Attached)
1 Socket in /run/screen/S-logiteca7.
```

#### セッションのアタッチ

もう一度さっきのセッションに戻るには`screen -r (PID)`か`screen -rx (PID)`(強制アタッチ)

```shell
$ screen -r (PID)
```

#### セッションの削除

お片付けをしましょう

```shell
$ screen kill (PID)
```

これで一連の移動操作が出来ました！

# 参考

screenでは一画面に複数ウィンドウを出したり（リージョン）、コピーペーストをしたり、セッションやウィンドウに名前をつけたりできるんですが、長くなるので割愛しました
他の記事を参照してみてください


### チートシート

※チートシートや用語の説明として素晴らしい記事ですが、若干のtypo注意

https://qiita.com/mgoldchild/items/e336618487eb7d90f6d4

### screenでウィンドウを垂直・水平分割する方法

https://qiita.com/hnishi/items/3190f2901f88e2594a5f

この記事にくどいくらい図が入っているのは、ごめんなさい、draw.io使うのが楽しかった…
Java 11 (OpenJDK: Eclipse Temurin) を Homebrew で macOS にインストールする

## 概要

- AdoptOpenJDK の後継である Eclipse Temurin を Homebrew で macOS にインストールする。

[Good\-bye AdoptOpenJDK\. Hello Adoptium\! \| AdoptOpenJDK Blog](https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/)

> The move from AdoptOpenJDK to Eclipse Adoptium is now complete. The same great community that brought you high quality Java binaries for the last four years at AdoptOpenJDK is now fully productive at Adoptium.

[Adoptium Celebrates First Release \| Adoptium Blog](https://blog.adoptium.net/2021/08/adoptium-celebrates-first-release/)

> This first release of Temurin from the Adoptium community and covers the latest versions of Java SE 8, Java SE 11, and Java SE 16 on each of Linux, Windows, and macOS on Intel 64-bit processors, with more platforms to follow shortly.

## 今回の環境

- macOS Big Sur 11.4

## インストール

インストール方法は Eclipse Temurin の前身である AdoptOpenJDK の公式資料を参考にする。

[GitHub \- AdoptOpenJDK/homebrew\-openjdk: AdoptOpenJDK HomeBrew Tap](https://github.com/AdoptOpenJDK/homebrew-openjdk)

```
$ brew tap homebrew/cask-versions
$ brew install --cask temurin11
```

## java_home コマンドでインストールされたディレクトリの場所を確認

```
$ /usr/libexec/java_home -v 11
/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home
```

## 環境変数 JAVA_HOME と PATH を設定

必要に応じて .zprofile や .zshrc などに記述する。

```
$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home
$ PATH=${JAVA_HOME}/bin:${PATH}
```

## インストールされた Eclipse Temurin を確認

```
$ java -version
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Temurin-11.0.12+7 (build 11.0.12+7)
OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode)

$ javac -version
javac 11.0.12

$ which java
/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home/bin/java

$ which javac
/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home/bin/javac

$ ls /Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home/bin
jaotc		javap		jfr		jmap		jstat		rmiregistry
jar		jcmd		jhsdb		jmod		jstatd		serialver
jarsigner	jconsole	jimage		jps		keytool		unpack200
java		jdb		jinfo		jrunscript	pack200
javac		jdeprscan	jjs		jshell		rmic
javadoc		jdeps		jlink		jstack		rmid
```

## 参考資料

- [Adoptium Celebrates First Release \| Adoptium Blog](https://blog.adoptium.net/2021/08/adoptium-celebrates-first-release/)
- [Good\-bye AdoptOpenJDK\. Hello Adoptium\! \| AdoptOpenJDK Blog](https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/)
- [Adoptium \- Open source, prebuilt OpenJDK binaries](https://adoptium.net/)
- [temurin — Homebrew Formulae](https://formulae.brew.sh/cask/temurin)
- [GitHub \- AdoptOpenJDK/homebrew\-openjdk: AdoptOpenJDK HomeBrew Tap](https://github.com/AdoptOpenJDK/homebrew-openjdk)
ライブラリとフレームワークの違い

#はじめに#
　プログラミングを学習しているとフレームワーク、ライブラリというものが出てくると思いますが、どちらも似たような意味で考えておられる初学者の方は多いと思います。
　かくいう私もその一人で、一体これは何が違うんだ・・・とつまづいてしまいましたので、いろいろ調べて自分なりに解釈してみました。

　誤り等がありましたらご指摘いただきますと幸いです。


#フレームワークとは#
>ソフトウェアフレームワーク（英: software framework）とは、プログラミングにおいて、アプリケーションソフトウェア等の実装に必要となる一般的な機能や定型コードを、ライブラリとしてあらかじめ用意したものである。

↑(Wikipediaより引用）

　いまいちピンとこないし、説明文の中にすでにライブラリが入ってるじゃないか！
これは一旦置いておくとして、私の中では下記のような理解です。

　
　フレームワークとは、英語で枠組み・骨組みといった意味でプログラミングにおいては、アプリケーションを開発する際の土台になります。
　フレームワークというものには、アプリを開発するのに便利な機能がたくさん詰め込まれており、非常に簡単かつ分かりやすくアプリを開発することができます。


　まだよく分からないと思いますので、フレームワークを使うことでどんなメリットがあるか見ていきましょう。


　フレームワークにおいては、変数の名前の付け方やどのファイルにどんなことを書くのか、と言ったいわゆるお作法のようなものがキッチリ決められているので、他の人が見てもコードが読みやすく、メンテナンスや機能拡張がしやすいという大きなメリットがあります。
　ただし反面、書き方に慣れる必要があるので、初めて触る方にとっては少し癖があってとっつきにくいかもしれません。


フレームワークにはいろいろな種類があり、

PHPのフレームワーク：laravel・cakePHP・FuelPHP
Rubyのフレームワーク：Rails・Sinatra・Padrino
JavaScriptのフレームワーク：AngularJS・Vue.js・React

などなど、もはやアプリケーション開発には必須の知識と言えるでしょう。



#ライブラリとは#
>ライブラリ（英: library）は、汎用性の高い複数のプログラムを再利用可能な形でひとまとまりにしたものである。ライブラリと呼ぶときは、それ単体ではプログラムとして動作させることはできない、つまり実行ファイルではない場合がある。ライブラリは他のプログラムに何らかの機能を提供するコードの集まりと言える。

↑(Wikipediaより引用）


案の定、いまいちピンときません。


　こちらも少し噛み砕いていきますと、よく使われる機能をまとめたものになります。こういう機能が作りたい！というものは大抵揃ってます。


　ライブラリを使うことで、開発効率を上げることが出来ます。さまざまな処理を実装するにあたり、先人たちが作り上げてきたプログラムを呼び出すことで簡単に実装することが出来るというのがライブラリの大きなメリットになります。


こちらも色々種類があり、たくさんありすぎるのでここでは紹介しません（笑）


#フレームワークとライブラリの違い#
　さて、本題のテーマであるフレームワークとライブラリの違いについて入っていきます。

　一見、フレームワークにしろライブラリにしろ、便利な機能をまとめたものという意味では同じなので、何が違うの？と思われるかもしれません。
　ざっくり言うと、フレームワークはシステム全体を構築するための土台で、ライブラリはある機能を実現するための部品、のようなイメージです。


　分かりやすいように身近なものの例えで言うと、ライブラリは個々のある機能を実現するための家具（机やらエアコンやら洗濯機やら）で、自分で作るのは大変なのでIKEAやニトリに買いに行き、自分の好きなところで使うことが出来ます。
　フレームワークはモデルハウスです。すでにあるモデルハウスを選択するだけで生活の基盤になるものは揃っています。あとは自分の住みやすいようにカスタムしていくだけです。


#まとめ#
　ライブラリとフレームワークはいずれも便利な機能をまとめたものですが、それぞれ個々の部品に過ぎないのか、全体の土台となるかと言う点で異なっています。


　どちらもアプリ開発においては超重要なところなので、しっかり学習していきましょう！
Swiftでキューを理解する

キュー
--
スタックと逆でFIFOとなる構造体のことを言う。末尾に要素を入れることをエンキュー、先頭からでていくことをデキューと呼ばれる。お店の行列をイメージすればすっと入ってくる。

コード
--

```swift:どうぶつ.swift
//
public struct Queue<T> {
  fileprivate var array = [T]()

//数を返す
  public var count: Int {
    return array.count
  }

//アペンドで末尾に入れる（更新させるからmutating)
  public mutating func enqueue(_ element: T) {
    array.append(element)
  }

//空であればnil,先頭から取り除く　（更新させるからmutating)
  public mutating func dequeue() -> T? {
    if isEmpty {
      return nil
    } else {
      return array.removeFirst()
    }
  }
//先頭の要素を返す
  public var front: T? {
    return array.first
  }
  public var end:T? {
    return array.last
}
}

var queueOfAnimals = Queue(array: ["🐺", "🐵", "🐑", "🐶", "🐍"])
//末尾に入れる
queueOfAnimals.enqueue("🐯")
//先頭を取り除く
queueOfAnimals.dequeue()

```


両端キュー
--
デックとも呼ばれる。キューと違い双方向から追加、削除が可能になる
EnqueueFront - 先頭に要素を挿入する
EnqueueBack - 末尾に要素を挿入する (キューのエンキューと同じ）
DequeueFront - 先頭にある要素を削除して返す　（キューのデキューと同じ）
DequeueBack - 末尾にある要素を削除して返す


```swift:どうぶつ.swift

 //インサートに要素入れる（更新させるからmutating)
  public mutating func enqueueFront(_ element: T) {
    array.insert(element,at:0)
  }
//　最後要素を削除して返す。
public mutating func dequeueBack() -> T? {
    if isEmpty {
      return nil
    } else {
      return array.removeLast()
    }
  }
    
```
開発者のためのドキュメンテーションガイド (Documentation Guide for Developers)

Documentation Guide for Developers という記事のテンプレートが便利そうだったのでそのメモ。

https://hellonehha.hashnode.dev/documentation-guide-for-developers-cksie1jh7050pvps1bnrgf7vh

筆者: https://github.com/Neha/documentation

### テンプレート集
### Feature and approaches / 機能とアプローチ

https://github.com/Neha/documentation/blob/master/developer-story-template.md

解決策: 
> 異なる解決策
> 理由
> 解決策の詳細設計
> 依存関係
> API
> トレードオフ
> LLD (ローレベルデザイン)
> HLD（ハイレベルデザイン)

### Knowledge sharing / 知識共有
https://github.com/Neha/documentation/blob/master/knowledge-sharing-template.md

> あらゆる技術の初期評価
> 学んだこと
> 修正したバグ
> あるべき機能
> 複雑な機能

### Code guidelines / コードガイドライン
https://github.com/Neha/documentation/blob/master/code-guidelines-template.md

### Checklist / チェックリスト
https://github.com/Neha/documentation/blob/master/checklist-template.md

### Dependencies / 依存関係
https://github.com/Neha/documentation/blob/master/dependencies_template.md

### Sprint reviews / スプリントレビュー
https://github.com/Neha/documentation/blob/master/sprint-review.md


というところで、以上参考になればさいわいです。
Activating a new survey version issue with process builder

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)

知らなかったことが議論されています。かなりいい内容です。ちゃんとあとで整理します。とりあえず忘れないように

[Activating a new survey version issue with process builder](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C6cYP)


Error - You can't activate this survey version. Either another version is referenced by one or more objects or you don't have the required permissions

エラー-この調査バージョンをアクティブ化できません。別のバージョンが1つ以上のオブジェクトによって参照されているか、必要な権限がありません。

【説明】
The key fact to remember is that a "survey" is just another flow in Salesforce. You can actually package a survey to move to other orgs by packaging the survey flow. When you incorporate a survey flow, with Send Survey Invitation or some other flow process, it becomes one big flow. So you cannot remove any part of the big flow. 


**覚えておくべき重要な事実は、「調査」はSalesforceの単なる別のフローであるということです。調査フローをパッケージ化することで、実際に調査をパッケージ化して他の組織に移動できます。 Send Survey Invitationまたはその他のフロープロセスを使用して調査フローを組み込むと、1つの大きなフローになります。したがって、大きなフローのどの部分も削除することはできません。**

【回避策】
I have not tried this, but it should work.

1. Clone the original flow as a new flow.
2. Remove the reference to the survey in the cloned flow and save the flow.
3. Delete the original flow.
4. Update the survey to a new version.
5. Link the survey, with its new version to the new cloned flow.

# これに類似する質問と回答

+ [アンケートを有効化ができない件について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FS442SAD)
+ [Either you don't have access to respond to this survey or the default survey invitation hasn't been generated.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000DcAqu)
フローでは機能しないことが言及されている

+ [Cannot view Survey that has attachment option in Experience Cloud](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007aiOzdSAE)

Experience Cloud で認証されたユーザーに対するアンケートを作成しています。添付の質問を含むアンケートを作成してアクティブ化すると、Experience Cloud サイトでは機能しなくなります (添付の質問が存在しない場合は正常に動作します)。次のメッセージが表示されます。

Either you don't have access to respond to this survey or the default survey invitation hasn't been generated

アンケートへの招待状を作成しようとすると、次のメッセージが表示されるため、作成できません。

You can't create a public invitation for this survey because one of the versions contains a question that allows attachment. Remove the question that allows attachment and try again


添付オプションを含むアンケートを機能させる方法を確認するのに苦労しています。誰か助けてくれませんか？


:::note
You can’t create a survey with attachment questions for anonymous users or generate a public invitation for surveys with attachment questions.

https://help.salesforce.com/s/articleView?id=sf.concept_upload_attachments_in_surveys.htm&type=5
:::
楽天ひかりのSMTPサーバにPostfixからメールリレーする

# 目的

自宅サーバなどでPostfixから楽天ひかりのSMTPサーバを使ってメール送信する場合の最短手順です。

# 手順

## 楽天ひかりを開通させる

省略

## 独自ドメインをとる（可能なら）

最近はメール受信元でMXレコードをチェックするものが増えてきているので、お名前.comなどで独自ドメインをとり、MXレコードを設定しておくとよいでしょう。

## 楽天ひかりで無料メールアドレスを取得

SMTP-AUTHを通すために無料メールアドレスを1つ取得しておきます。手順は省略します。

## Postfixのインストール

次のパッケージをインストールします。

```
# dnf install postfix cyrus-sasl-plain
```

## main.cfの変更

```/etc/postfix/main.cf
mydomain = 自分のドメイン名
myorigin = $mydomain
relayhost = [mail.gol.com]:587
smtpd_recipient_restrictions = permit_mynetworks
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp-auth
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
```

## SMTP-AUTHファイルの作成

下記ファイルを作成します。パスワードはデフォルトでメンバーズステーションのパスワードです。

```:/etc/postfix/smtp-auth
[mail.gol.com]:587 無料メールアドレス:パスワード
```

ハッシュ化して、平文ファイルを削除します。

```
# postmap hash:/etc/postfix/smtp-auth
# ls -l /etc/postfix/smtp-auth.db
# rm /etc/postfix/smtp-auth
```

## Postfix起動

```
# systemctl restart postfix
```

以上
デイトラ学習メモ_初級DAY1

#個人的に勉強になったポイント
##・上手な質問の重要性
###1.情報整理ができ問題解決力がつけられる
質問するために情報を書いてると答えが分かることがよくあるらしい。質問力は情報整理の能力と大きく関連しているので、情報をうまく整理出来るようになると問題解決能力が向上する。



###2.エンジニアとして評価される
質問が出来ないとプログラマーとして評価されるのは難しい。
なぜなら質問が下手なプログラマーはチームの生産性を下げてしまうため。質問が下手だと回答者の時間をいたずらに奪ってしまいチームの生産性が悪くなってしまう

>参考にした記事

https://tokyofreelance.jp/question/
【13章】Javaを学ぼう

今回の記事では、他人が作ったクラスを利用する外部ライブラリの利用について詳しく書いていきたいと思います。
私自身のアウトプットの場になりますので、よろしくお願いいたします！

#外部ライブラリ
前章でクラスについて学びましたが、Javaでは、他人が作ったクラスを利用することができます。このようなクラスを**外部ライブラリ**と呼び、自分のプログラムに読み込むことで利用できるようになります。

##import
外部ライブラリを自分のプログラムに使えるようにするには、**import**を用います。
数学的なメソッドを持つMathというクラス（ライブラリ）を読み込むには、class定義より上で「import java.lang.Math」とします。

```java:Main.java
import java.lang.Math;  //外部ライブラリを読み込む
class Main {
 public static void main(String[] args) {
   .
   .
   .
 }
}
```

##Mathクラスのメソッドについて
Mathクラスのmaxメソッドを使ってみます。maxメソッドは、引数に渡した2つの数値の大きい方を返してくれます。

```java:Main.java
import java.lang.Math; 
class Main {
 public static void main(String[] args) {
  int max = Math.max(2, 9);  //外部から読み込んだMathクラス
  System.out.println("最大値は" + max + "です");
 }
}
```

出力結果↓

```java:コンソール
最大値は9です
```

実は、先ほど読み込んだ「java.lang.Math」はよく利用されるため、特別にimportせずに自動で読み込まれるようになっています。Mathクラス以外にも「java.lang.クラス名」となる外部ライブラリはすべて自動で読み込まれます。

#Scannerについて
コンソールに値を「出力」させるのとは逆に、コンソールに値を「入力」し、その値をプログラム内で使うこともできます。
コンソールへの入力を受け取るには**Scanner**というライブラリを用います。Scannerは「import java.util.Scanner」と読み込みます。

```java:コンソール
あなたの名前:John   //Johnと入力すると...

あなたの名前はJohnです  //「あなたの名前はJohnです」が出力される
```

```java:Main.java
import java.util.Scanner; //外部ライブラリ「Scanner」を読み込む
class Main {
 public static void main(String[] args) {
   .
   .
   .  
 }
}
```

もう少し具体的にScannerの使い方を見ていきます。下図を参照してください。
まずScannerを初期化しscannerという変数にいれています。Scannerではこの初期化したものを代入した変数を使ってメソッドを呼び出します。
scanner.next()とすると、コンソールに入力された文字列を受け取ることができます。

```java:Main.java
import java.util.Scanner; 
class Main {
 public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);
                    //Scannerの初期化！
  String name = scanner.next();
                //文字列の入力を受け取る
                //一旦処理を中止し、コンソールに値が入力されたら次の処理に進む
                   ↓
  System.out.println("あなたの名前は" + name + "です");
 }
}
```

scanner.next()が呼ばれると、一旦処理が中断しコンソールに値が入力されるのを待ちます。下図のコンソールに入力された値をscanner.next()が受け取り、変数nameに代入しています。

```java:コンソール
あなたの名前:John   //Johnと入力すると...

あなたの名前はJohnです  //「あなたの名前はJohnです」が出力される
```

補足ですが、Scannerを用いて、整数を受け取るメソッドは**nextIntメソッド**、小数を受け取るメソッドは**nextDoubleメソッド**です。

以上が外部ライブラリの利用についての説明になります。
よろしければ次章もご覧になってください！
最後までご覧いただきまして、ありがとうございました！
Poolingがしたいときのメモ

# 概要
いろいろなPoolingをしたい
→`skimage.measure` の `block_reduce`を使う

# 内容
- DLでよく使われるMax, Average以外のPoolingをしたいものの、端数処理などが面倒。
- いい感じに処理してくれるライブラリはないものか...
- [ありました](https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce)

```python:binning.py
import numpy as np
from skimage import measure

#画像の代わり
img = np.arange(2000*3000*3).reshape(2000, 3000, 3).astype(np.uint32)
print(img.shape, img.dtype, np.average(img))
# (2000, 3000, 3) uint32 8999999.5
```

`skimage.measure.block_reduce(image, block_size, func=<function sum>, cval=0, func_kwargs=None)`

引数として
`image` : 入力画像(N次元)
`block_size` : Poolingに使うブロックの大きさ(これもN次元)
`function sum` : Poolingに使う計算方法、 numpy.sum、numpy.min、numpy.max、numpy.mean、numpy.medianをサポート。
`cval` : paddingする場合の値
`func_kwargs` : 出力のdtypeなどを指定できる。

以下のように、ピクセル当たりの平均が16倍になっていることからsum poolingができていることがわかる。

 ```python:binning_4.py
img_bin = measure.block_reduce(img, (4, 4, 1), np.sum, func_kwargs={'dtype': np.uint32})
print(img_bin.shape, img_bin.dtype, np.average(img_bin))
# (500, 750, 3) uint32 143999992.0
```

Paddingを7などの割り切れない数値にしても計算ができている。

 ```python:binning_7.py
img_bin_7 = measure.block_reduce(img, (7, 7, 1), np.sum, func_kwargs={'dtype': np.uint32})
print(img_bin_7.shape, img_bin_7.dtype, np.average(img_bin_7))
# (286, 429, 3) uint32 440119296.7871289
```
RDSに接続するときに役に立った記事

EC2からRDSに接続するときにお世話になった記事の雑なメモです。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-connect-ec2-bastion-host/

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html

https://dev.classmethod.jp/articles/sales-rds-ec2-session/

## 自分への注意

しっかりAuto-assign Public IPをEnableにしておこう。そうしないとPublic IPが振られなくてアクセスができない。

![Screen Shot 2021-08-20 at 2.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/0337fd29-64a4-d2ce-ae0f-0030fd7bfe4c.png)
PATHを任意のファイルに通す

intellijの実行コマンドが長かったので一発で実行できるようにPATHを通した。
忘れたら嫌なのでやり方を書いておく。

###元々の実行コマンド
```
/opt/idea-IC-212.4746.92/bin/idea.sh
```

いちいちこれを打って実行するのは面倒。


そこで.bash_profileに

```
export PATH=$PATH:/opt/idea-IC-212.4746.92/bin
```
と設定した。これで```/opt/idea-IC-212.4746.92/bin```下のファイルを直に実行できるようになった。

###.bash_profileを作ったら
性質上作った時点では反映されないため、以下のコマンドを実行し反映させる。

```
source ~/.bash_profile 
```


###.bash_profileがない場合
初期状態ではbash_profileがないこともある(自分がそうだった)。その場合はホームディレクトリにviかtouchで作る。

###Ubuntuの場合
.bash_profileが読み込まれないので.bashrcにexport文を書く


---------------------------
追記
デスクトップアイコン作って簡単GUIからアクセスできるようにしました。そのほうが圧倒的に楽でした😨
ただ.bashrcや.bash_profileは起動時に実行されることを覚えておくといろいろ楽です！
ActiveStorageを利用した際のseedデータ作成

初投稿です！宜しくお願いします。

#### やりたいこと
ActiveStorageを使って投稿機能を実装している状態でseedデータを準備したい。
ファイルの添付を必須にするバリデーションをかけている場合のデータを作成したい。

#### seedデータの用意

以下のやり方場合は、
ActiveRecord::RecordInvalid: バリデーションに失敗しました: 写真を追加してください
となってしまった。

失敗例

```db/seeds.rb
10.times do |n|
  post = Post.create!(
    user_id: "1",
    content: "投稿します！",
  )
  post.images.attach(
    io: File.open(Rails.root.join("./app/assets/images/post/test.jpeg")),
    filename: "test.jpeg"
  )
end
```

成功例

```db/seeds.rb
10.times do |n|
  post = Post.new(
    user_id: "1",
    content: "投稿します！",
  )
  post.images.attach(
    io: File.open(Rails.root.join("./app/assets/images/post/test.jpeg")),
    filename: "test.jpeg"
  )
  post.save!
end
```

Post.create!ではバリデーションエラーに引っかかってしまいました。
Post.newからのpost.save!とすることで成功しました！！
RubyでFizzBuzz問題

# アウトプットとしてFizzBuzz問題の記事を書く。

### 要件

- 1～任意の数までの数字を順番に表示する
- ただし、3の倍数のときはFizz、5の倍数のときはBuzz、3と5の公倍数のときはFizzBuzzと表示する。
- 任意の数はプログラム実行時に引数で渡せるようにする

### コードを書く。

```
def fizzbuzz(n)
  if n % 15 == 0
    puts "FizzBuzz" 
  elsif n % 3 == 0
    puts "Fizz"
  elsif n % 5 == 0
    puts "Buzz"
  else
    puts n 
  end
end

num = 15
(1...num).each do |n|
  puts fizzbuzz(n)
end
```

※ここで注意するべきなのが15の倍数の判定コードを先に書くこと。3の判定コードや5の判定コードを先に書くと15の倍数が来たときに一番最初のコードの処理が実行される。つまり15は3の倍数でも5の倍数でもあるのでうまくいきません。わからなければ実際に動かしてみて試すのがおすすめです。
クラウドプラクティショナー合格体験記【AWS】

#・目次
[1. はじめに](#1-はじめに)
[2. 学習前の知識レベル](#2-学習前の知識レベル)
[3. 勉強方法](#3-勉強方法)
[4. 資格を取得すると](#4-資格を取得すると)

#1. はじめに
こんにちは！
AWSの入門的な資格である**クラウドプラクティショナー**に合格したので**勉強方法**について自分なりに紹介していきたいと思います。
ちなみに、**学習期間は1ヶ月**で、**ITについてあまり知らないけど短期間に取得したい**という方に向いています。

クラウドプラクティショナーでは、AWSに関する**広くて浅い知識**が問われるので、個人的には**暗記がメイン**で、
マネジメントコンソールには入ったことがあるよぐらいで十分だと思います。

![325ed20fc9eff11ec5f37192d41b4993.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1910898/554e1b87-f5e1-a0a1-21bd-e83e525e010f.png)
#2. 学習前の知識レベル

**著者のスペック**
・理系学部(数学科)出身の新卒
・就活のために「基本情報技術者試験」を取得
・IT企業に就職

**資格取得の経緯**
入社時、会社がAWS技術者を欲しがっておりセミナーに放り込まれました。
その中でAmazon、Netflixの裏で動いているシステムはAWSだと知って興味が沸き、とりあえず参考書を買って勉強を始めました。


#3. 勉強方法

**主に３つの教材を使用しました。**

**1 - 基本のサービスのインプット（本）**
[(模擬問題付き)改訂新版 徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書[SAA-C02]対応](https://www.amazon.co.jp/%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E4%BB%98%E3%81%8D-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8-SAA-C02/dp/4295010650/ref=sr_1_9?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=AWS&qid=1629383518&sr=8-9)

**2 - 読んでも分からなかったとこを実際に触ってみる（ハンズオン）**
 [AWS ハンズオン資料](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/)

**3- 試験問題の演習**
[Udemy](https://www.udemy.com/)

**- 基本のサービスのインプット -**
一つ目はとりあえずどういったサービスがあるのかを知るために本を読みました。
自分の知識レベルでは`AWS lambda`や`S3`すら、はじめは何をいっているのか分かりませんでした。
最初に読むときは**完全に理解する必要は無い**と思います。

ちなみに、書籍関連でいうとこちらもよくオススメとしてあがっています。
[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=AWS&qid=1629383518&sr=8-6)
![51EuLXpy87L._SX352_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1910898/c9232630-d8d0-1f49-62a0-df88bee9901a.jpeg)


**- 読んでも分からなかったとこを実際に触ってみる -**
2つ目はAWSの提供しているハンズオン資料を使用しました。
ここでは、**YouTubeを見ながら基本的なサービスを組み合わせて構成を組む**ことができます。
例えば、`Amazon EC2 Auto Scaling`基礎編や、試験でもよく出る`AWS lambda`と`Amazon API Gateway`を組み合わせた構成を作成することができます。

何から触っていいか分からないという方は**スケーラブルウェブサイト構築編**がオススメです。

**-試験問題の演習-**
3つ目は最後の仕上げとして過去問演習です。
どういった問題が出るか分からなかったので**Udemy**というサイトであがっている模擬試験問題を購入しました。
最初に解いたときは 58%（合格ライン72%）でした。全然届かないですね。
Udemyはセール時に相当安くなっているのでセールまで待つのがいいと思います。
（自分は約1,000円で購入しました）

#4. 資格を取得すると
クラウドプラクティショナーに合格するといくつかの特典を得ることができます。
特に利用しやすい特典は**次回の受験料半額コード**と**練習問題の無料コード**です。
練習問題というのはAWS認定のサイトから購入して、自身が**次回受験する資格の問題を20問**解くことができます。
次回の受験の前日に確認として使用するのもいいかも知れません。

また、AWS認定のグッズを買うことができるリンクも配布されます。
資格を取得するごとに購入できるものも増えていきますが、欲しいかどうかは判断に委ねます。

現在は**ソリューションアーキテクト-アソシエイト**まで取得することができましたが、これからも取得していく予定ですので今後も自分なりの学習法を共有できたらなと思います！
Android AutoでのYouTube再生アプリ開発メモ

※アウトローどころではなく、googleさんに怒られることをやっている自覚はありますが大目に見てください。
　海外兄貴たちに後れを取らないよう、androidautoも盛り上げていきましょう！

Q. 結局アプリ上で再生はできたんか？
A. こちらを見ていただくのが早いかと思います。
　https://youtu.be/z6Z9rfNOSRw

Q. なんで作ろうと思ったの？
A. OTTOCAST みたいな情弱から搾取するデバイス？が許せねぇ。あとそれを嬉々として紹介するyoutuberの皆様が許せねぇ。6万円とか日本は裕福ですね。

直近で実装したいこと
１．ディスプレイオーディオ側をセカンドディスプレイのように利用する　→　OK
２．下のメニューバーを再度に持ってくる。（画面を大きく使う）→　未調査
３．レイアウトの空白をなくしたい　→　OK

見えているバグ
１．ボリュームつまみを回すと動画再生が止まってしまう！ → 情報あったらください！

以下メモ
１．YoutubeApiでの再生は難しい。通常のactivityなどではなく特殊である。Fragmentも利用できなかった。。。このためwebviewにiframe仕込んでいます。

２．apkからのインストールがクッソ面倒。初心者には無理そう。
【競プロ典型90問】008の解説（python）

## 概要
[競プロ典型90問](https://atcoder.jp/contests/typical90)の解説記事です。
解説の画像を見ても分からない（~~理解力が足りない~~）ことが多々あったので、後で解き直した際に確認できるようまとめました。

※順次、全ての問題の解説記事を挙げていく予定です。
※★５以上の問題は難易度的に後回しにしているため、投稿時期が遅くなる可能性があります。（~~代わりに丁寧に解説してくれる方いたらぜひお願いします~~）

## [問題008-AtCounter](https://atcoder.jp/contests/typical90/tasks/typical90_h)

### 問題概要
文字列Sから任意の文字を順番を変えずに取り出したときに、"atcoder"(以下、文字列Tとします。)となる個数を求める。

### 解き方
まず初めに、単純にSから"atcoder"の文字をそれぞれ検索する方法が考えられますが、
この考えでは、文字列の長さNの検索を7回（Tの長さ分）行うため、$N^7$となりTLEになってしまいます。

そこで今回は、DP（動的計画法）を用います。
dp[i][j]を、Sのi文字目までを用いた時、Tのj文字目までを作る通りの数と定義します。
そうすると、
１. $S[i] = T[j]$の時（Sのi文字目とTのj文字目が等しい時）

$dp[i][j] = dp[i-1][j-1] + dp[i-1][j]$

※Sのi文字目を使ってTのj文字にする時と、Sのi文字を使わずにj文字目まで作った時の和です。

２. $S[i] ≠ T[j]$の時（Sのi文字目とTのj文字目が等しくない時）

$dp[i][j] = dp[i-1][j]$

※Sのi-1文字目までを使ってTのj文字を作る通り数と同じです。

の２つの漸化式が求められます。
また、j=0の時は、文字を取り出さない方法、すなわち１通りとできるので、

$dp[i][0] = 1$

i=0の時（かつj≠0）の時は、Sを１文字も使わず、Tのj文字まで作ることは出来ないため、

$dp[0][j] = 0$

と考えられます。ここまで求められると、i, jを小さい順から計算することで、
全てのi, jに対してdpを求めることができ、dp[N][7]が答えとなります。

![参考画像](https://raw.githubusercontent.com/E869120/kyopro_educational_90/main/editorial/008.jpg "公式解説画像")

引用元：[競プロ典型90問 Github](https://github.com/E869120/kyopro_educational_90)

### 実装

```python:answer.py

# 入力の受け取り

N = int(input())
S = input()

# 今回はatcoderをTとする
T = "atcoder"

# 余りのための変数
mod = 10**9+7

#0文字からN文字まで考えるので、"+1個"配列を定義
dp = [[0]*(len(T)+1) for _ in range(N+1)]

# j=0の時、全て1を代入
for i in range(N+1):
  dp[i][0] = 1

# S[i]がT[j]に等しいかで場合分け
# dpのiとS[i]で示すiが1ズレている点に注意（jも同様）
# 答えをmodで割った余りを格納
for i in range(N):
  for j in range(len(T)):
    if S[i] == T[j]:
      dp[i+1][j+1] = dp[i][j] + dp[i][j+1]
      dp[i+1][j+1] %= mod
    else:
      dp[i+1][j+1] = dp[i][j+1]
      dp[i+1][j+1] %= mod

# N文字まで使って、Tになる時の通り数を出力
print(dp[N][len(T)])

```

## 最後に
問題の解説を読んでも他の人のコードを見てもさっぱり分からないという方の
力に少しでもなれれば幸いです。
コードの改善点やその他、ご意見などあれば、気軽にコメントください。
また、この記事を読んで理解できた方はぜひLGTMを押していただけると嬉しいです。
（~~記事投稿のモチベになります。~~）

ここまでお読みいただきありがとうございました。
イーサリアムテストネットワークを使用する | ブロックチェーン

テストネット上のEtherとトークンは簡単に入手でき、実際の価値はありません。それでも、テストネット上で10,000個のEtherまたは1兆個のトークンを所有するのは楽しい場合があります。本番デプロイ前（またはブロックチェーン自体に変更が加えられる前）に、バージョンがイーサリアムをシミュレートするイーサリアムテストネットワーク（「テストネット」）にデプロイされます。これにより、開発者、コミュニティ、そしてあなたにチャンスが与えられます。

## テストネット
現在使用されているテストネットは3つあり、それぞれが本番ブロックチェーン（実際のEtherとトークンが存在する場所）と同様に動作します。開発者は個人的な好みやお気に入りのテストネットを持っている可能性があり、プロジェクトは通常、そのうちの1つでのみ開発されます。

- Ropsten
   - イーサリアムに最もよく似たプルーフオブワークブロックチェーン。フェイクエーテルを簡単に採掘できます。
   - https://ropsten.etherscan.io/
- Kovan
   - パリティチームによって開始された権限証明ブロックチェーン。エーテルは採掘できません。リクエストする必要があります。
   - https://kovan.etherscan.io/
- Rinkeby
   - Gethチームによって開始された権限証明ブロックチェーン。エーテルは採掘できません。リクエストする必要があります。
   - https://rinkeby.etherscan.io/


## テストネットに接続する
イーサリアムで機能し、各テストネットで機能するイーサリアムアドレスと秘密鍵—イーサリアムメインネット上のイーサリアムまたはトークンをテストネットアドレスに送信しないように細心の注意を払ってください。そうしないと、資産が失われます。

先に進む前に、Compoundはテストネット専用の新しいウォレットを作成することをお勧めします。Etherがない場合、誤ってEtherを送信することはありません。

## MetaMask

https://metamask.io/

MetaMaskを使用してイーサリアムとトークンをテストネットに送信するのは簡単です。MetaMaskの左上で、イーサリアムネットワークを選択できます。
メインイーサリアムネットワークからリンケビー（または他のテストネット）に切り替えると、選択したネットワークを反映するように、残高とトランザクション履歴の更新が表示されます。
これで、MetaMaskを使用してトランザクションを作成すると、選択したネットワークに送信されます。

MyEtherWalletとMyCryptoでも同様に、画面の右上で代替ネットワークを選択できます。これを行うと、すべてのトランザクションと契約の呼び出しは、選択したネットワーク上で実行されます。

## エーテルの取得

新しいアカウントに蛇口イーサリアムをロードする時が来ました。

### Kovan
Kovan蛇口はパリティにあなたのGithubアカウントの資格情報を提供するために、あなたを必要とし、あなたは、24時間ごとに一度Kovanエーテルを要求することができます。

### Rinkeby
Rinkeby蛇口はあなたがソーシャルメディアは、FacebookやTwitterやGoogle Plusのいずれかであなたのアドレスを含む投稿作ることが必要です。そうしたら、その投稿への直接リンクを入力ボックスに入力18.75 Ethers / 3 daysし、右側のドロップダウンから選択します。
GIT HUBで作業するにあたり、エラーが起きた時の対処法

■トピックブランチを作成し忘れ、マスターブランチ上にコードの入力をしてしまっていたケース

気付いた段階でトピックブランチを作成（create brunch)
↓
選択肢が２つポップに表示される
1.Leave my changes on master
元のブランチで書いていたコードを保留にして、新しいブランチで0からコードを書く選択です。
2.Bring my changes to （新しいブランチ名）
元のブランチで書いていたコードを新しいブランチに引き継ぐ選択です。

*１を選択すると、コードが消え最初からやり直しとなる。コードを復旧したい場合はマスターブランチに戻り、画面左下のstash changesをクリックし、restoreをクリックするとコードが復旧される。全部消えることをstashと呼ぶ。

■コンフリクトの場合

コンフリクトとは、日本語では競合という意味で、コード作成上で辻褄の合わないことを指して言う。

１、同一ファイルを複数人が作成し、一方が先にマージし、もう一方がマージできない状況の対策
githubのデスクトップにてResolve conflictsをクリック
↓
２、修正したいファイルが表示される。複数ファイルがある場合は、Mark as resolvedをクリックする必要がある。
↓
３、Mark as resolvedをクリック後、commit margeをクリックし、修正完了となる。

＊コンフリクトの注意点
１、作業を行う前にPullを済ませておく。
最新の状態にしておくことで、修正箇所を最小限にするため。
２、複数人で作業を行うため、打ち合わせを事前に行っておく。

■誤った情報をPushしてしまった場合

前提としてPushした情報のローカルリポジトリは取り消せないものの、リモートリポジトリでは誤った情報を取り消すことができる。

１、revert(リヴァート)
間違ってpushしたcommitを取り消すことができる。commitを削除するのではなく、「指定するcommitを取り消すためのcommit」を追加で行う。
revertはcommitされた変更と逆になる変更を追加することで、commitを取り消す。

１、マスターブランチからHistoryを選択し、修正したいCommit内容を右クリック。最上部にRvert changes in commitをクリックすると、誤って消したコミット内容が修復できる。

■誤った情報をCommitしてしまった

commitが終わると、「Commit to master」の下に、下記図の様に「Undo」というボタンが出てくる。
「Undo」をクリックすると取り消すことができる。
Mac にインストールされているGitをHomebrewを使って最新化する 

Gitを勉強するためMacにインストールされているGitを最新化してみました。

まずはターミナルでGitのバージョンを確認。

```
 % git version     
git version 2.30.1 (Apple Git-130)
```
MacにはGitが標準で入っている様子。
今回はHomebrewから最新版のGitにしてみます。

```
% brew install git
Error: The following directories are not writable by your user:
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
```

早速、エラーが出ました。
内容を見るとユーザーにディレクトリに対する権限がないようなので
 /usr/local/ に権限を付与します。

```
sudo chown -R $(whoami):admin /usr/local
```

再度以下のコマンドでインストールを実行します。

```
% brew install git
Warning: git 2.33.0 is already installed, it's just not linked.
To link this version, run:
  brew link git
```

インストールはできてるけど、リンクがないと言われたのでメッセージ通りリンクを貼ります。
＊以前からGitを使用している場合、古いファイルが残っていることがあるため上書きオプションをつけて実行しました。

```
brew link --overwrite git
```

インストールできたか確認します。

```
% brew info git
git: stable 2.33.0 (bottled), HEAD
Distributed revision control system
```
2.33.0というバージョンがインストールされました！


ターミナルを再起動してバージョンを確認します。

```
 % git version     
git version 2.30.1 (Apple Git-130)
```

...ん？バージョンが変わってない？
HomebrewでインストールしたGitのパスが通っていないためパスを変更します。

まずは使用しているシェルを確認します。

```
% echo $SHELL
/bin/zsh
```

私の場合は、zshを使用していたため下記のコマンドでviを開きます。

```
#zshの場合
% vi ~/.zshrc
```

下記のとおりに入力してviを保存。

```
# HomebrewのGitを使うパス
export PATH=/usr/local/bin/git:$PATH
```

再度ターミナルを再起動してバージョンを確認します。

```
 % git version     
git version 2.33.0
```

HomebrewのGitを使ってGitが最新化されました。


##参考文献
* [Qiita | homebrewとは何者か。仕組みについて調べてみた](https://qiita.com/omega999/items/6f65217b81ad3fffe7e6)
* [システムデザイン研究所 | Homebrewがupdateできないときの対処] (http://fukuzawalab.com/blog/archives/1301)
* [Gworks | Git のインストールメモ 【Homebrew】 ] (http://www.gworks.jp/2014/05/git-homebrew/)
ActiveModel::UnknownAttributeErrorについて

# はじめに
本記事では、
`ActiveModel::UnknownAttributeError in FoodsController#create`
というエラーについて記述します。
本日は、このエラーを解決しました。

# エラーの内容
以下、画像の通りです。

![マイグレーションの名前エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/f212c885-0718-effa-63f6-97428f580815.png)


内容としては、
`Food`に`meal_type_id`なんてものはありませんよ？
と怒っています。

`attribute` = `属性`（Google先生より）

もっと簡単にいうと、
`Foodテーブル`に、`meal_type_id`というカラムは存在しない。ということになります。

# 結論
既に修正してしまったので、修正後のものになりますが、画像を添付します。

![マイグレーションの名前間違いエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/ceb43399-2cf2-2a3e-2776-03a3462ab765.png)

Active Hashを使用してるカラム達に`_id`が抜けておりました。

修正方法は、以下の通り。

```
現状確認
% rails db:migrate:status
```

```
up     20210818093904  Devise create users
up     20210818095054  Create foods
```

今回は、一番下のものを修正したいので、

```
1回だけ
% rails db:rollback
```
これで修正できるようになりました。

```ruby
class CreateFoods < ActiveRecord::Migration[6.0]
  def change
    create_table :foods do |t|
      t.integer     :meal_type_id,           null: false  #_idをつける
.
.
省略
.
.

      t.references  :user,                   null: false, foreign_key: true
      t.timestamps
    end
  end
end
```

オリジナルアプリなので、やや端折っております。申し訳ありません。

その後、

```
% rails db:migrate
```
これで完了です。

# 終わりに
やや簡単なエラー内容かもしれませんが、
エラーにぶつかったら１つ１つ理解、内容把握しアウトプットしたいと考えています。

ここからまだまだ色んなエラーに出会いますが、このスタンスは忘れずに頑張ります！

以下参考サイト
[railsの「ActiveModel::UnknownAttributeError」について](https://teratail.com/questions/299106)

明日も頑張ります！！