OmniAICreator/Qiita-1.07M huggingface dataset:
Python学習日記　～文字列型に関連するメソッドについて～

ということで、python学習開始２日目です。
学んだことは自分で文字に起こして忘れないよう、
知識定着できるよう適宜まとめていきたいと思います。

まず、pythonでは、

#オブジェクト.メソッド（）　

として、関数を示すことがわかりました。いままでやってきたPHPの時とはちがうなあ！
JSと近いイメージだなと思いました。（素人感想すみません、、）



以下は本日学習した、文字列に関連する関数とユースケースです。



#文字列の複製
fruit_10 = 'fruit' * 10
print(fruit_10)
→fruitfruitfruitfruitfruitfruitfruitfruitfruitfruitfruitfruit


#文字列の連結
new_fruit = 'apple' + 'banana'
print(new_fruit)
→applebanana


#特定のインデックスの文字のみ抽出
fruit = 'fruit'
print(fruit[2])
→u
※f(0) r(1) u(2) i(3) t(4)


#count　指定の文字列が何個あるか
msg = 'ABCDEABC'
print(msg.count('ABC'))
msg内に’ABC’は２個あるから、２を返す


#startswith　指定の文字列から始まっているかいないか
msg = 'ABCDEABC'
print(msg.startswith('ABCD'))
msgは’ABCD’で始まっているので、Trueを返す
違う場合は、Falseを返す


#endtswith　指定の文字列で終わっているかいないか
msg = 'ABCDEABC'
print(msg.endswith('ABC'))
msgは’ABC’で終わっているので、Trueを返す
違う場合は、Falseを返す


#strip(両端)　rstrip(右端)　lstrip(左端)
msg = 'ABCDEABC'
print(msg.strip('CBA'))
両端から、’CBA’それぞれと一致した文字列を削除する
上記の場合は、両端にA/B/Cがあるので、DEを返す。

例えば
msg = 'ABCDEABC'
print(msg.strip('CA'))
とすると、左端の場合は、まずAを削除。
次のBはstripで指定していないのでそこで削除終了。
右はCを削除。次のBはないので削除終了。BCDEABを返す。

rstripは右端のみ。lstripは左端のみを返す。


#upper lower swapcase　大文字・小文字を変換する
msg = 'abcABC'
msg_u = msg.upper() #大文字
msg_l = msg.lower() #小文字
msg_s = msg.swapcase() #大文字と小文字を変換する

・upper：すべての文字列を大文字にする（msg_u = ABCABC）
・lower：すべての文字列を小文字にする (msg_l = abcabc)
・swapcase：すべての文字列の大文字と小文字を入れ替える (ABCabc)


#replace 文字列の置換
msg = 'ABCDEABC'
msg_r = msg.replace('ABC', 'FFF') 
第１引数の文字列を第２引数の文字列に置換する（msg_r = FFFDEFFF）

第３引数があるとき
msg = 'ABCDEABC'
msg_r = msg.replace('ABC', 'FFF', 1) #変換 第三引数は左からその順番のものだけ変換
第３引数には数値を入れる。左から順に見てn番目の文字列のみ置換する
上記の場合は、msg_r = FFFDEABC


#capitalize 一文字目のみ大文字に変換
msg = 'hello World'
print(msg.capitalize())
上記の場合は、Hello worldを返す。
※大文字だったＷは一文字目ではないので小文字に変換


#文字列の一部取り出し
msg = 'hello my name is Taro'
print(msg[:7])
print(msg[7:])
print(msg[1:7])
print(msg[1:7:2])
上から順に、
hello m（indexで数えて７番目まで）
y name is Taro（indexで数えて７番目よりあと）
ello m（indexで数えて１番目から７番目まで）
el（indexで数えて１番目から７番目までを２文字飛ばしで’e’’l’’ ’）
※第３引数はn文字飛ばしで取り出しを行う。


#islower と isupper 大文字小文字の判別

・islower すべて小文字ならTrue　一文字でも小文字でないならFalse
・isupper すべて大文字ならTrue　一文字でも大文字でないならFalse
msg = 'apple'
print(msg.islower()) #すべて小文字なのでTrue
print(msg.isupper()) #すべて大文字ではないのでFalse


#find rfind index rindex 文字列のある場所を返す
msg = 'ABCDEABC'
print(msg.find('ABC')) 
print(msg.rfind('ABC'))
print(msg.index('ABC')) 
print(msg.rindex('ABC')) 

上から順に、
0（indexで０番目にあるため）
5（indexで５番目にあるため）
0（indexで０番目にあるため）
5（indexで５番目にあるため）

※findとindexの違いは、指定の文字列が見つからなかったとき
find：見つからなかったら、-1を返す
index：見つからなかったら、エラーとなる


#所感

今までPHPを少し学んでいたこともあって、そんなに抵抗なくメソッドの知識が入ってきている実感があります。さっさと知識身に着けてアプリ作ってみて10月の入社まで引き続き頑張ります。
つたない文章でしたが、お読みいただいてありがとうございました。

※encodeとformatは落ち着いたら別の機会にまとめようと思います。
radare2で計算する

追記1：XORの見える化を追加しました。
追記2：おすすめのLinux版radare2インストール方法を追加しました。

## radare2を使って計算する

```powershell
PS C:\Users> r2 -
 -- Use headphones for best experience.
[0x00000000]> ? 0x20
int32   32
uint32  32
hex     0x20
octal   040
unit    32
segment 0000:0020
string  " "
fvalue: 32.0
float:  0.000000f
double: 0.000000
binary  0b00100000
ternary 0t1012
[0x00000000]> ? 00100011
int32   32777
uint32  32777
hex     0x8009
octal   0100011
unit    32.0K
segment 0000:0009
string  "\t\x80"
fvalue: 32777.0
float:  0.000000f
double: 0.000000
binary  0b1000000000001001
ternary 0t1122221222
[0x00000000]> ? 10
int32   10
uint32  10
hex     0xa
octal   012
unit    10
segment 0000:000a
string  "\n"
fvalue: 10.0
float:  0.000000f
double: 0.000000
binary  0b00001010
ternary 0t101
[0x00000000]>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277081/1168a0a6-c548-1acf-bfff-d98e910f939e.png)

## XORの見える化
```
└─$ r2 -
#~でgrepして文字だけ表示する
[0x00000000]> ? 0xb0 ^ 0xFF ~string
string  "O"
[0x00000000]> ? 0x8f ^ 0xFF ~string
string  "p"
[0x00000000]> ? 0x9a ^ 0xFF ~string
string  "e"
[0x00000000]> ? 0x91 ^ 0xFF ~string
string  "n"
[0x00000000]> ? 0xa0 ^ 0xFF ~string
```

:::note info
おすすめのLinux版radare2インストール方法
```bash
└─$ git clone https://github.com/radareorg/radare2
└─$ radare2/sys/install.sh
└─$ r2 -V
```
参考：[Radare2: Libre Reversing Framework for Unix Geeks](https://github.com/radareorg/radare2#installation)
:::
PHP タイプヒンティング（型宣言）を記載して引数、戻り値のデータ型を指定する

# 目的

- タイプヒンティングを用いて引数と戻り値のデータ型を指定する方法をまとめる

# 情報

- 下記のサービスを用いて動作確認を行った。
    - [https://paiza.io/ja](https://paiza.io/ja)

# 方法

- 下記のように記載することで引数の型を指定する事ができる。

    ```php
    function 関数名(型名 変数名) {
        関数内部の処理
    }
    ```

- 下記のように記載することで戻り値の型を指定する事ができる。

    ```php
    function 関数名(): 型名 {
        関数内部の処理
    }
    ```

### 利用できる型（PHPのバージョンにより異なる。下記はPHP7）

| 型名 | 概要 |
| --- | --- |
| bool | 真偽値 |
| float | 浮動小数点 |
| int | 整数 |
| string | 文字列 |
| array | 配列 |
| callble | コールバック関数 |
| クラス名/インターフェイス名 |  |
| self | 現在のクラス |

### 引数と戻り値の型を指定する例

- 数字を受け取って帰すだけの関数を定義する。
- 引数はint型を想定する。戻り値はint型を返すことを想定する。

    ```php
    function getNum(int $num): int
    {
        return $num;
    }

    echo getNum(1);
    // 1が出力される
    ```

- 引数はint型を想定して関数を定義しているが、文字列を与えてみる。

    ```php
    function getNum(int $num): int
    {
        return $num;
    }

    echo getNum('strです');
    ```

- 下記のエラーが出力される。（関数の引数の型をint型で固定しているので文字列を渡すとエラーになる）

    ```php
    PHP Fatal error:  Uncaught TypeError: getNum(): Argument #1 ($num) must be of type int, string given, called in /workspace/Main.php on line 10 and defined in /workspace/Main.php:5
    ```

- 次に定義した関数の中で文字列を返してみる。

    ```php
    function getNum(int $num): int
    {
        return 'strです';
    }

    echo getNum(1);
    ```

- 下記のエラーが出力される。（関数の戻り値の型をint型で固定しているので文字列を返すようにするとエラーになる）

#### まとめ

- ケース・バイ・ケースではあるが、タイプヒンティング（型宣言）は使ったほうが良いと思った。
- 己のソースの記載ミスを早期に発見できてバグを減らすことができると思った。


#### 参考文献

- 独習PHP
Ubuntu 20.04@ Windows-WSL2で pyenv + venv環境でjupyterを動かす。

すぐ忘れるので、自分用のメモです。 

## pyenvのインストール

### 必要なコマンドを入れる
```bash
sudo apt update
sudo apt upgrade

sudo apt install git wget curl
```

### Python が依存するライブラリのインストール

Ubuntu 20.04 では、/etc/apt/sources.list を編集する。

```bash
sudo vim /etc/apt/sources.list
```
して　以下を最後の行に追加する。

```bash

deb-src http://archive.ubuntu.com/ubuntu/ focal-updates main
```

して、　以下のコマンドを実行

```bash
sudo apt update
sudo apt build-dep python3.8
```

### pyenv のダウンロード

```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

cd ~/.pyenv
git checkout v1.2.21
```


### bash_profileの編集
```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

最後にbash_profileの保存を行う。

```bash
source ~/.bash_profile
```

### 環境変数の追加
.bashrcに以下を追加

```bash
# sudo vim ~/.bashrc
PYENV_ROOT="${HOME}/.pyenv"
PATH="${PYENV_ROOT}/bin:${PATH}"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi
```

### Pythonのインストール
ターミナルを再起動して

```bash
pyenv install 3.7.9
```
ソールからビルドするので、時間かかります。


### (備考）pyenvのチートシート

| **Command**               | **Description**                                              |
| ------------------------- | ------------------------------------------------------------ |
| pyenv install --list      | pyenv でインストール可能な Pythonのバージョンを一覧表示 |
| pyenv install [version]   | 指定したバージョンの Pythonをインストール |
| pyenv versions            | pyenv でインストールした Python を一覧表示 |
| pyenv shell [version]     | 現在のシェルで使用する Python のバージョンを設定 |
| pyenv local [version]     | カレントディレクトリ以下で使用する Python のバージョンを設定 |
| pyenv global [version]    | すべてのシェルで使用する Pythonのバージョンを設定 |
| pyenv version             | 現在設定されている Python のバージョンを表示 |
| pyenv uninstall [version] | 指定したバージョンの Pythonをアンインストール |


### pythonを3.7.9に設定する。
確認→設定　そして確認

```bash
# 確認
pyenv versions
# 設定
pyenv local 3.7.9
# 確認
pyenv versions
```


## venvの設定
pyenv は Python 自体のバージョンを管理するものですが、これと合わせて Python 標準ライブラリの venv を利用することで、設定した Python のバージョンでパッケージを管理する仮想環境を作成することができる。

```bash
# Python のバージョンを設定
pyenv shell 3.7.9

# カレントディレクトリに仮想環境を作成
python -m venv --upgrade-deps my-env379

# 仮想環境を有効化
source venv/bin/activate


# 必要に応じて
pip install -r requirements.txt
```

以上
Kotlin GroupByをまとめてみた

# Kotlin GroupByまとめ

Kotlinコレクションを操作してをGroupByしてまとめたい。ということでコード補完を・・・・・

## って似たようなメソッドが5つもあるやないかい！！！:punch::angry::punch:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923880/884d12ee-c8d5-168e-f443-b4db70e49397.png)


ということでこれらを全部調べてみました。

 
##1． `groupBy(keySelector: (T) -> K): kotlin.collections.Map<K, kotlin.collections.List<T>>`

どうやら要素からキーを生成してまとめるらしい。returnはMapでkeyが生成したキーでValueが要素と・・・・
はい。求めていたものはこれです。これで明日も安泰です。これで今夜もぐっすり眠れます。ということでサンプルコードを載せておきます。

```kotlin
// お友達の名簿をGroupBy
val friends: Map<Int, List<Friend>> = listOf(
    Friend("takashi", 19),
    Friend("satoshi", 20),
    Friend("takao", 21),
    Friend("sadap", 20),
    Friend("hideki", 20),
    Friend("rikio", 21),
).groupBy { it.age }

println("型：${friends.javaClass.kotlin}")
println("-------------------------------")
println("結果:${friends}")
```
```
型：class java.util.LinkedHashMap
-------------------------------
結果:{19=[Friend(name=takashi, age=19)], 20=[Friend(name=satoshi, age=20), Friend(name=sadap, age=20), Friend(name=hideki, age=20)], 21=[Friend(name=takao, age=21), Friend(name=rikio, age=21)]}
```


##2．`groupBy(keySelector: (T) -> K, valueTransform: (T) -> V): kotlin.collections.Map<K, kotlin.collections.List<V>> `
こちらは第一引数に要素からキーを生成する処理を渡し、第二引数にはValueを変化させる処理を渡せるようですね。

```kotlin
// お友達の名簿をGroupBy
val friends: Map<Int, List<String>> = listOf(
       Friend("takashi", 19),
       Friend("satoshi", 20),
       Friend("takao", 21),
       Friend("sadap", 20),
       Friend("hideki", 20),
       Friend("rikio", 21),
).groupBy(
       { it.age },
       { "Mr." + it.name } // ValueをFriend型からString型に変化
)

println("型：${friends.javaClass.kotlin}")
println("-------------------------------")
println("結果:${friends}")

```


```
型：class java.util.LinkedHashMap
-------------------------------
結果:{19=[Mr.takashi], 20=[Mr.satoshi, Mr.sadao, Mr.hideki], 21=[Mr.takao, Mr.rikio]}

```



疲れたのでまた今度追記します。見てくれてありがとうございました。
【CSS】ブロックボックスとインラインボックス ~divとspanの違い~

# はじめに
* divとspanの使い分けがあやふやだったのでまとめました。

## ブロックボックスとインラインボックスについて
* ```<div>```: ブロックボックス
* ```<span>```: インラインボックス
* [MDN ドキュメントブロック要素](https://developer.mozilla.org/ja/docs/Web/HTML/Block-level_elements)
* [MDN インライン要素](https://developer.mozilla.org/ja/docs/Web/HTML/Inline_elements#elements)

### それぞれの違いは？
* 改行されるかどうか
    * ブロックボックスは改行される
    * インラインボックスは改行されない
* width、heightプロパティの挙動
    * ブロックボックスは適用される
    * インラインボックスは適用されない
* padding、margin、borderの挙動
    * ブロックボックスは適用される
    * インラインボックスはpadding、margin、borderがきたとき他の要素は無視される
    
```html:html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body style="margin: 0">

    <div>私はブロックです</div><div>私はブロックです</div><div>私はブロックです</div>
    <hr />
    <span>私はインラインです</span><span>私はインラインです</span><span>私はインラインです</span>

  </body>
</html>

```

|![FireShot Capture 076 - Document - .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95954/f2757285-27e8-4759-3ae3-14398077acdc.png)|
|:-:|


## ```display```: 無理やりインラインボックスとブロックボックスを変更する

* ```display```を使うことでインラインボックスとブロックボックスを変更する事ができる


### ブロックボックスをインラインボックスへ変更する

```css:css
div {
  display: inline;
}
```

### インラインボックスをブロックボックスへ変更する

```css:css
span {
  display: block;
}
```

## ```inline-block```: インラインボックスとブロックボックス両方の性質を持つ
* ```display: inline-block;```を使うことで両方の性質をもたせることができる

```html:html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body style="margin: 0">

    <div>ブロック内の<span>インライン</span>です。インラインの場合は、margin,padding,borderがきたときに他の要素のことを考えません。</div>

  </body>
</html>

```

```css:css
span{
  background-color: yellow;
  margin: 20px;
  border: 1px solid black;
  padding: 20px;
  display: inline-block;
}
```

* 下の画像のようにインラインで表示されているが、padding、margin、borderが効いているのがわかる。

|![スクリーンショット 2021-09-04 21.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95954/ccf6a9b0-2933-a6f9-eea3-c1bac9ae1513.png)|
|:-:|
Reactをexpressにホストする


やり方を聞かれて調べたのでメモ。
react-router-domでルーティングされているページをbuildしてexpressにホストしたい。

## Reactでの作業

とりあえず何でもいいのですが、react-router-domで最低限のルーティングを設定します。

### 簡易仕様

* / → Home.js
* /about → About.js
* それ以外だと、Page not found.を表示。


### プロジェクトの作成

とりあえずcreate-react-appでプロジェクトを作成。

```bash
npx create-react-app react-test
cd react-test
```

最低限のルーティングを設定したいのでreact-router-domのインストール。

```bash
npm install react-router-dom
```

Home.jsとAbout.jsを生成。

```bash
touch src/Home.s src/About.js
```

### Home.js

Home.jsの実装。Homeと表示し、About.jsへのリンクがあるだけ。

```js:Home.js
import { Link } from "react-router-dom";

const Home = () => {
    return (
        <div>
            Home<br/>
            <Link to="/about">Aboutへ</Link>
        </div>
    );
}

export default Home;
```

### About.js

Aboutと表示しHome.jsへのリンクがあるだけ。

```js:About.js
import { Link } from "react-router-dom";

const About = () => {
    return (
        <div>
            About<br/>
            <Link to="/">Homeへ</Link>
        </div>
    );
}

export default About;
```

### App.js

ルーティングの設定。/でも/aboutでもなければPage not foundを表示。

```js:App.js
import { BrowserRouter, Switch, Route } from "react-router-dom";

import Home from "./Home";
import About from "./About";

const App = () => {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/about" exact component={About} />
        <Route render={()=><p>Page not found.</p>}/>
      </Switch>
    </BrowserRouter>
  );
}

export default App;
```

### 動作確認

npm startで動作確認。 http://localhost:3000。

```bash
npm start
```

### build（本番用ファイル生成）

今回の肝はbuildしたファイルがexpressで動くかなのでbuild。

```bash
npm run build
```

buildファイルが作成され、中にbuild結果が出力される。index.htmlを始めとする各種ファイルが生成される。

## Express側での作業

上記で生成されたファイル群をexpressの静的ファイルホスティングで正常に動作させるのがゴール。

### expressのインストールと作業場の作成

expressをインストールし、reactのプロジェクトフォルダ中にnodeフォルダを作る（わけてもいい。めんどいのでそうしているだけ）。そして、index.jsを生成。

```bash
npm install express
mkdir node
touch node/index.js
cd node
```

### 実装

index.jsを実装していく。

```js:index.js
const path = require("path");
const express = require("express");
const app = express();

//ミドルウエアでstaticパスを追加（ただ、これだけだと直アクセスや無いpathだと動かない）
app.use(express.static(path.join(__dirname, "..", "build")));

//これを追加（全てをindex.htmlにリダイレクト。いわゆるrewrite設定）
app.use((req, res, next) => {
    res.sendFile(path.join(__dirname, "..", "build", "index.html"));
});

app.listen(3001, () => {
    console.log("server started on port 3001");
});
```

### ポイント

動作のポイントは２つ。

#### 静的ファイルの場所

まず、静的フォルダを設定する。
これだけで実は http://localhsot:3001にアクセスすると動きます。が、これだけでは不十分。

```js
app.use(express.static(path.join(__dirname, "..", "build")));
```

/を経由せず、ダイレクトに/aboutや/xxxとかにアクセスするとエラーとなる（表示されない or Not foundとならない）。

#### 全てのリクエストをbuild/index.htmlへ

これらを処理するには全てのリクエストをindex.htmlに処理させる必要がある。
一般的なWebサーバではRewirte処理などを行うがExpressでは以下のようにする。

```js
app.use((req, res, next) => {
    res.sendFile(path.join(__dirname, "..", "build", "index.html"));
});
```

### 実行

では動作確認してみる。

```bash
node index.js
```

### 確認

http://localhost:3001/
CREATE TABLEを利用せずに一時テーブルを作成したい

SQLServerには一時テーブルという機能があるのですが、既存のテーブルをもとにして一時テーブルを作成したい場合、INTOを利用します。

たとえば以下はテーブルXから一時テーブルYを作成するサンプルです。

```SQL
SELECT * INTO #Y FROM X;
```

INTOを利用すると、何もないところからCREATE TABLEを利用せずに一時テーブルを作成することも可能です。

以下のSQLでは初期データを持った一時テーブルPを作成することができます。

```SQL
SELECT *
INTO #P
FROM (VALUES
  (1, 'A'),
  (2, 'B'),
  (3, 'C')
) AS T (col1, col2);
```

**環境情報**

```
Microsoft SQL Server 2019 (RTM-CU9) (KB5000642) - 15.0.4102.2 (X64) 
    Jan 25 2021 20:16:12 
    Copyright (C) 2019 Microsoft Corporation
    Developer Edition (64-bit) on Linux (Ubuntu 18.04.5 LTS) <X64>
```
[Ruby]Integer#downto

##はじめに
最近コメントいただいた中で新しいメソッドを教えて頂いたので忘れないうちに記事にしておきます。

##Integer#downto

integer型の数字に使えます。
使用した数字から1ずつ減らした数を一つずつブロック変数に入れて繰り返し処理をします。

引数にどこまで減らすか、最小の数字を渡すことで、最小値を指定できます。

```ruby
6.downto(0) do |i|
  print i
end
=> 6543210


6.downto(1) do |i|
  print i
end
=>654321


6.downto(3) do |i|
  print i
end
=>6543
```

参考記事では下記のような使い方もしていました。
そのまま引用します↓

```ruby
5.downto(1) {|i| print i, " " } # => 5 4 3 2 1
```

参考: https://docs.ruby-lang.org/ja/latest/method/Integer/i/downto.html
【C#】小数点の四捨五入

##今回学んだこと

小数点の四捨五入
小数点以下の一部をゼロで埋める方法
##コード
```C#:小数点の四捨五入
//四捨五入したい数と、小数点第何位までの桁数を表示させたいかを入力する。
//桁数が足りない場合は0が入る。
  decimal[] N = Console.ReadLine().Split().Select(decimal.Parse).ToArray();

                decimal num = Math.Round(N[0], (int)N[1], MidpointRounding.AwayFromZero);

                Console.WriteLine(num.ToString().PadRight((int)N[1] + 2, '0'));
```
`Math.Round()`だけたど、最近接偶数というものが発生する。
端数が真ん中0.5だと、値に一番近い偶数になってしまうというもの。
（例えば、2.5を四捨五入して3になるだろうと思ったら、実際は2になる）

そのため、`Math.Round()`の引数で
`MidpointRounding.AwayFromZero`を追加して四捨五入ができるようにします。
<br>
ちなみに配列Nは、
N[0]　四捨五入したい数
N[1]　四捨五入したい数を小数点第何位まで表示するかを指定
を表しています。
<br>

そして`num.ToString()`で文字列に変換。
`PadRight((int)N[1] + 2, '0')`で右から0をN[1]個詰めていきます。
+2と書いてあるのは、PadRightがコンマも計算に入れるからです。
というよりも、他の良い方法が思いつかなかっただけ…。
【Windows】バッチファイルで現在の日付・時刻を取得するdate・timeコマンドの使い方

  Windowsでbatファイルを作る際、ファイル名に日付や時刻を入れたい時があると思います。
そのため、今回はDOSコマンドで日付や時刻を取得する方法を解説していきたいと思います。

#日付と時刻を取得する（環境変数「date」と「time」）
　日付を取得するには「date」、時刻を取得するには「time」を使用します。「date」と「time」はWindowsの環境変数であり、既に現在の日付と時刻が格納されています。
これをバッチ内に記載すれば日付と時刻を取得してくれます。

```sample.bat
@echo off

rem 現在日付
echo %date%
rem 現在時刻
echo %time%
```
コマンドプロンプト上での実行結果は下記の通りです。

```
c:\>sample.bat
2021/09/06
19:20:14.73
```

#日付のフォーマットをyyyymmdd形式に変更する
　ハイフンを削除するなど、日付のフォーマットを変更したい場合は、取得した日付文字を置換することで実現します。

```sample2.bat
@echo off

rem 「date」から切り出した数字をそれぞれ変数に代入
set year=%date:~0,4%
set month=%date:~5,2%
set day=%date:~8,2%
 
set date2=%year%%month%%day%

echo %date2%
```

 4行目から6行目で、変数「date」から必要な部分だけを切り取り、それぞれ年「YYYY」、月「MM」、日「DD」に代入しています。文字列の切り取りの基本は以下のような形式で書きます。

```
%[変数]:~[飛ばす文字数],[切り取る文字数]%
```
例えば、4行目の「YYYY」であれば、0文字飛ばし（つまり何も飛ばさず初めの文字から）、1文字目から4文字分を切り取るという指示になっています。

実行結果は下記の通りです。

```
c:\>sample2.bat
20210906
```
#時刻のフォーマットをHHMMSS 形式に変更する。
　同じように、時間は「19:20:14.73」という形式なので、これを秒未満は切り捨てて時刻のフォーマットをHHMMSS 形式に変更することが出来ます。

```sample3.bat
@echo off

set time2=%time: =0%

rem 「time」から切り出した数字をそれぞれ変数に代入
set hour=%time2:~0,2%
set minute=%time2:~3,2%
set second=%time2:~6,2%
 
set time3=%hour%%minute%%second%

echo %time3%
```

実行結果は下記の通りです。

```
c:\>sample3.bat
192014
```

#ファイル名に日付の文字列を追加して出力する
　最後に、バッチファイル内で日付と時刻の文字列を利用してログファイルを作ってみましょう。ファイル名はYYYYMMDD.logになるようにします。

```sample4.bat
@echo off

set time2=%time: =0%

set year=%date:~0,4%
set month=%date:~5,2%
set day=%date:~8,2%
set hour=%time2:~0,2%
set minute=%time2:~3,2%
set second=%time2:~6,2%

set filename=%year%-%month%%date%-%hour%%minute%%second%
 
echo test >> %logname%.log
```
#まとめ
 バッチファイル内で環境変数「date」と「time」を使うことで、日付と時刻が含まれたファイル名を作成することが出来ます。バックアップのログファイルなどを作成する際は、本記事を参考にして頂ければ幸いです。
display:none;を指定した要素にもアニメーションする

## はじめに
メニューをホバーしたら、サブメニューが表示させるヘッダーを制作していたときの話。
メニューをホバーしたらdisplay: none;で指定していたサブメニューをdisplay: block;に変更させるとき、transitionが効かなかった。（フワッと表示されない）

なので解決策をまとめてみました。

## 解決法
**keyframes**とjQueryを使う。
任意のタイミング（例ではhoverイベント時）にクラスを付与する（例の場合、show）

```index.html
<ul class="header_menu">
  <li>About</li>
  <li>News</li>
  <li>
    <p class="main_menu">Category</p>
    <ul class="sub_menu">
      <li>Head</li>
      <li>Body</li>
      <li>Hand</li>
    </ul>
  </li>
  <li>Contact</li>
</ul>
```

```style.css
.sub_menu {
  display: none;
  transition: 0.5s;
}
.sub_menu.show {
  display: block;
  animation: show 1s linear 0s;
}
@keyframes show {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
```

```index.js
$('.main_menu').hover(
    function() {
      //マウスカーソルが重なった時の処理
      $('this').next('.sub_menu').addClass('show');
    },
    function() {
      $('this').next('.sub_menu').removeClass('show');
    }
);

```

## おわりに
display: none;を指定している要素をフワッと表示させるにはkeyframsとjQueryの処理が必要。
HTMLとCSSで完結させたい場合は、opacityプロパティとvisibilityプロパティで実現させるもいい。
Java Tips

# Java Tips

## Objectをjsonに変換
Gsonを使う。
https://github.com/google/gson

```gradle
dependencies {
  implementation 'com.google.code.gson:gson:2.8.7'
}
```

```java
SampleModel results = SampleModel.findAll();

Gson gson = new Gson();
System.out.println(gson.toJson(results));

// 出力結果
// [{"id":1,"name":"Sample001"}, {"id":2,"name":"Sample002"}, {"id":3,"name":"Sample003"}]
```

## StreamAPIのmap
PHPでいうarray_map、rubyでいうmap
[Java Stream APIをいまさら入門](https://qiita.com/takumi-n/items/369dd3fcb9ccb8fcfa44)

```java
/*
 * 以下のような値を持つModel
 * [{"id":1,"name":"Sample001"}, {"id":2,"name":"Sample002"}, {"id":3,"name":"Sample003"}]
 */
SampleModel model = SampleModel.findAll();

/*
 * map処理
 * SampleModelに@Getterが付与されている前提
 */
List results = model.stream()
    .map(elem -> elem.getName())
    .collect(Collectors.toList())

// 出力結果：["Sample001", "Sample002", "Sample003"]
System.out.println(results);
```

## `@Test`でprivateメソッドのExceptionが発生するかをテストする方法
https://qiita.com/Esfahan/items/d3dcf75192e41b28aca7

## [JAVA] JPAで1対Nで中間テーブルのあるDBをModelに落とし込む
https://qiita.com/Esfahan/items/157d4d4170a3f92f5997

## JPAのNo default constructor for entityエラーについて
https://qiita.com/Esfahan/items/959f07826b57129f6a2f

## JPAでlimit

```java
// select * from samples order by id desc limit 3;
public List<SampleModel> findTop3ByOrderByIdDesc();
```

## JPAでwhere != (not equal)
`UserIdNot` のようにカラム名の末尾にNotを付ける

```java
/*
select
    *
from
    samples
where
    user_id != "xxxx"
and group_id = "xxxx"
order by
    id desc
limit 3;
*/
public List<SampleModel> findTop3ByUserIdNotAndGroupIdOrderByIdDesc(
    String userId,
    String groupId
);
```
[Rails] ネストについて

##初めに
####記事の対象者
・routes.rbで詰まってしまうとき

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

##ネストってなんだ？(通販サイトで考えてみよう)
####自分のイメージは
・resources君とresourcesさんが手を繋いでいると情報の共有ができるけどしていないとできない
・共有方法は。paramとして共有される
・繋ぐ方法は、do~endの間に他のresourcesを配置
・手をつないでも、上下関係が生まれる。（入れ子構造）

####通販サイトのDB(itemとpayment)

![nestsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/565d0b57-58a8-d863-7fc6-6a38153868b1.png)

####ネストをしない状態(items=商品、payments＝送り先、users＝ユーザ)

```
resources :items
resources :payments, only:[:create]
resources :users
```

上記のように設定すると、itemsとpaymentsは別々のものであり、結びついていない状態となる
＊これだと、どの商品をどこに送ればいいかわからない

####ネストしている状態(items=商品、payments＝送り先、users＝ユーザ)

```
resources :items do
  resources :payments
end
resources : users
````
上記のように,do~endを使ってresources同士を紐付けさせた状態となる
＊どの商品をどこに送ればいいかわかるようになる。
####items_controllerのアクション時にparams:idにpaymentのレコードが一緒についてくるようになる!


##最後に
・paramsってなんだろう？についてのリンクはこちらに（製作中）
・ここまで書いて、もっとうまく説明する勉強しなきゃなってつくづく思う（汗）
・ここまで、読んでくれましてありがとうございます！
Apple Watch コンテンツサイズ測定結果

![Screen Shot 2021-09-15 at 12.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1380/6977e076-177b-9354-5593-7f099c01d879.png)

※ シミュレータで計測しています

# WKInterfaceDevice

## screenBounds
デバイスの画面範囲。コンテンツの内容に関わらず、デバイスごとに固定の数値。
```WKInterfaceDevice.current().screenBounds```

| | x | y | width | height |
|---|---|---|---|---|
| 38mm | 0 | 0 | 136 | 170 |
| 42mm | 0 | 0 | 156 | 195 |
| 40mm | 0 | 0 | 162 | 197 |
| 44mm | 0 | 0 | 184 | 224 |
| 41mm | 0 | 0 | 176 | 215 |
| 45mm | 0 | 0 | 198 | 242 |

# SwiftUI GeometryReader

SwiftUIでサイズを取得するためのGeometryReader。
```GeometryReader { geometry in } ```

### size
コンテンツを表示できる範囲。
40mm, 44mm, 45mmは画面の丸みがあるため、SafeArea Bottom部分も除かれている。

| | width | height |
|---|---|---|
| 38mm | 136 | 151 |
| 42mm | 156 | 174 |
| 40mm | 161 | 141 |
| 44mm | 183 | 162 |
| 41mm | 174 | 147 |
| 45mm | 196 | 172 |

### safeAreaInsets
| | top | left | bottom | right |
|---|---|---|---|---|
| 38mm | 19 | 0 | 0 | 0 |
| 42mm | 21 | 0 | 0 | 0 |
| 40mm | 28 | 0.5 | 28 | 0.5 |
| 44mm | 31 | 0.5 | 31 | 0.5 |
| 41mm | 34 | 1 | 34 | 1 |
| 45mm | 35 | 1 | 35 | 1 |

## TabView内の画面 (PageNavigation有り)
38mm, 42mm, 41mmは、+7ptのSafeArea Bottomになる。 45mmは +8pt、 40mm, 44mmは変わらない。

### size
| | width | height |
|---|---|---|---|
| 38mm | 136 | 144 |
| 42mm | 156 | 167 | 
| 40mm | 161 | 141 |
| 44mm | 183 | 162 |
| 41mm | 174 | 140 |
| 45mm | 196 | 164 |

### safeAreaInsets
| | top | left | bottom | right |
|---|---|---|---|---|
| 38mm | 19 | 0 | 7 | 0 |
| 42mm | 21 | 0 | 7 | 0 |
| 40mm | 28 | 0.5 | 28 | 0.5 |
| 44mm | 31 | 0.5 | 31 | 0.5 |
| 41mm | 34 | 1 | 41 | 1 |
| 45mm | 35 | 1 | 43 | 1 |

# WKInterfaceController
SwiftUIを使わない場合、WKInterfaceControllerのメソッドからサイズを取得できる。
contentFrameは、SafeArea Left,Bottom,Rightも含んだ値になっているっぽい。

### contentFrame

| | x | y | width | height |
|---|---|---|---|---|
| 38mm | 0 | 19 | 136 | 151 |
| 42mm | 0 | 21 | 156 | 174 |
| 40mm | 0 | 28 | 162 | 169 |
| 44mm | 0 | 31 | 184 | 193 |
| 41mm | 0 | 34 | 176 | 181 |
| 45mm | 0 | 35 | 198 | 207 |

### contentSafeAreaInsets

| | top | left | bottom | right |
|---|---|---|---|---|
| 38mm | 19 | 0 | 0 | 0 |
| 42mm | 21 | 0 | 0 | 0 |
| 40mm | 28 | 0.5 | 28 | 0.5 |
| 44mm | 31 | 0.5 | 31 | 0.5 |
| 41mm | 34 | 1 | 34 | 1 |
| 45mm | 35 | 1 | 35 | 1 |
magento、管理画面メニューの表示

# はじめに
magento、管理画面メニューの表示をしている箇所を忘れないように、メモ。

# このように表示されます

![F3221CFD-C182-4936-AC12-A44592320026.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/befeef1d-6c7c-b932-24d2-e923e18ed5d2.jpeg)

# 該当

```xml
<menu>
<add id="Dev_Grid::home" title="テストよ(　･ิω･ิ)" module="Dev_Grid" sortOrder="1000" parent="Magento_Catalog::catalog_categories" resource="Magento_Catalog::categories" action="dev_grid/index/index"/>
</menu>
```

例として、カタログのメニューに表示しています。
このようにタイトルに記載します。
新たなJLCPCBの紫のプリント基板

紫のプリント基板今日からロールアウト！
いつでも発注できる
新たな色は君たちに刺激を与え創造力を与える。
pcbの変革は今から始まる:grinning:

https://jlcpcb.com/JPA

![IMG_4165.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1873014/5ea25e0d-e414-fc56-c170-92700c6a154d.jpeg)
![IMG_4166.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1873014/72b215fb-efb1-e7bd-1605-7d0bacff5e49.jpeg)
![IMG_4167.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1873014/fa5019e7-a2fe-682f-4bd7-06346508d9d2.jpeg)
![IMG_4168.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1873014/dca2f6d6-5738-fd84-74cb-d2a0868affdf.jpeg)
python 好きな文字で囲む（記録）

### 文字列を枠で囲む装飾をするプログラム

#### 例
```
=======
<qiita>
=======
```
↑のようになるプログラム

```

input_text = input()

str_len = len(input_text)

print("="*(str_len +2))
print("<"+input_text+">")
print("="*(str_len +2))

# 結果
# =======
# <qiita>
# =======
```
Target class [〇〇〇TableSeeder] does not exist. って出てきたときにやったこと。

## 事象
Seederファイルに目的のデータを追加して、
DatabaseSeeder.phpにも追加。
`php artisan migrate:refresh --seed`　を実行。

```
 Illuminate\Contracts\Container\BindingResolutionException  : Target class [XxxxxTableSeeder] does not exist.
```
なぜかエラーに。
typoを疑い、探してみるも見つけられず。

## 原因
composerのリロードが必要だったようです。

```bash
composer dump-autoload
# リロードした後に再作成。
php artisan migrate:refresh --seed
```
今度は問題なく再作成することができました。
〜〜　does not exist　のようなエラーは、変にググるよりキャッシュを疑った方が効率的ですね！

```bash
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
composer dump-autoload
```
【Laravel】Bladeで共通で参照できるグローバルな変数を定義する。

自分用のメモとして残します。

各コントローラでわざわざviewに渡す変数を定義するのは面倒。
AppServiceProviderのbootメソッドで、全てのviewで参照できる変数をに定義する方法をメモ。
#やり方

```app\Providers\AppServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Auth;


class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // view()->composer内でやっているのは、Authの情報を取るためなので、なくてもOK
        view()->composer('*', function ($view)
        {
            $globalArg_hoge = null;
            if (Auth::guard('user')->check()) {
                $globalArg_hoge = 'HOGE';
            }


            // ポイント：view()->shareで変数を定義してあげることで、冗長にならなくなる。
            view()->share([
                'globalArg_hoge'=> $globalArg_hoge,
            ]);

        });

    }
}
```

以上です。
AWS EC2インスタンス作成後にセキュリティグループを変更する方法

セキュリティグループの設定を間違えてEC2インスタンスを作成してしまった場合の変更方法です。
再度EC2インスタンスを作成し直す必要はありません。起動中のまま簡単に変更できます。

# 1. EC2インスタンス一覧画面を開く

色々と方法はあると思いますが、サービス検索窓に`ec2`と入力し`EC2`をクリックすると表示させることができます。
![1-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/50238637-e59b-6c50-20fd-ef384b9fae4e.png)



# 2. 対象のインスタンスのチェックボックスをクリックする

以下のキャプチャのように、対象のインスタンスのチェックボックスをクリックしてください。

![1-1-a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/42a31ab5-a65d-b62a-c4a3-9cba6557a4f0.png)


起動中のまま変更できます。停止する必要はありません。

一度に複数のインスタンスの設定を同時に変更することはできないようです。対象のインスタンスのチェックボックスを一つだけ選んでクリックしてください。

# 3. 「アクション」をクリックする

画面右上にある「アクション」をクリックします。

![1-1-b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/db59ee47-7cee-e0b9-67dd-f1d3ef86dbbc.png)

# 4. 「セキュリティ」をクリックする

次は「セキュリティ」をクリックしましょう。

![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/e2581909-6ecf-42ec-c4bd-51b20bc80793.png)

# 5. 「セキュリティグループの変更」をクリックする

次は「セキュリティグループの変更」をクリックしましょう。

![1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/206037e7-3019-11e9-dcf1-ece48e2e5f66.png)


# 6. セキュリティグループの設定を変更し、「保存」をクリックする

以下のような設定画面が表示されていると思います。

![1-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/44f1d589-4ef0-943a-c3f0-475998ef7ab9.png)

この画面でセキュリティグループの変更ができます。

「削除」をクリックするとセキュリティグループを削除できます。
また、検索窓にセキュリティグループ名を入れて既存のセキュリティグループを選択し、「セキュリティグループを追加」をクリックすると追加できます。

最後にオレンジ色の「保存」をクリックしましょう。 **<--これしないと変更されません！**

「せキュリティーグループが正常に変更されました」というメッセージが出力されます。
これで設定変更できたはずです。ちなみに変更は即反映されます。

![1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1884434/9e3927f3-73d5-e338-1d11-57ce1f3e5cc6.png)
Pythonのdatetimeモジュールで日時を取得するサンプル

# Pythonのdatetimeモジュールで日時を取得するサンプル

## はじめに

コードを書いていて日時を使用する場面が出てくるかと思います｡
そのときに私がほしいと思う､フォーマットと表示のサンプルを書きました｡
解説はしていなくて､フォーマットと表示の羅列のみです｡

## 環境

- windows 10
- Python 3.9.1
- datetime

## コード

```python
import datetime

NOW = datetime.datetime.now()

print(NOW)
print(type(NOW))
# 2021-09-06 18:19:37.079126
# <class 'datetime.datetime'>

print(NOW.year)
print(type(NOW).year)
# 2021
# <attribute 'year' of 'datetime.date' objects>

print(NOW.month)
print(type(NOW.month))
# 9
# <class 'int'>

print(NOW.day)
print(type(NOW.day))
# 6
# <class 'int'>

# 曜日
# 0:月, 1:火, 2:水, 3:木, 4:金, 5:土, 6:日
print(NOW.weekday())
print(type(NOW.weekday()))
# 0
# <class 'int'>

# UTC
print(NOW.utcnow())
print(type(NOW.utcnow()))
# 2021-09-06 09:19:37.079126
# <class 'datetime.datetime'>

print(NOW.strftime("%Y_%m_%d"))
print(type(NOW.strftime("%Y_%m_%d")))
# 2021_09_06
# <class 'str'>

print(NOW.strftime("%Y/%m/%d %H:%M"))
print(type(NOW.strftime("%Y/%m/%d %H:%M")))
# 2021/09/06 18:19
# <class 'str'>

# 一週間前
print(NOW + datetime.timedelta(weeks=-1))
print(type(NOW + datetime.timedelta(weeks=-1)))
# 2021-08-30 18:19:37.079126
# <class 'datetime.datetime'>

# 30日前
print(NOW + datetime.timedelta(days=-30))
# 2021-08-07 18:19:37.079126

# 一時間前
print(NOW + datetime.timedelta(hours=-1))
# 2021-09-06 17:19:37.079126

# 1日と12時間を秒に変換
dt = datetime.timedelta(days=1, hours=12)
print(dt.total_seconds())
print(type(dt.total_seconds()))
# 129600.0
# <class 'float'>

# 3600秒を日時に変換
print(datetime.timedelta(seconds=3600))
print(type(datetime.timedelta(seconds=3600)))
# 1:00:00
# <class 'datetime.timedelta'>

```

## 参考

[datetime --- 基本的な日付型および時間型 — Python 3.9.4 ドキュメント](https://docs.python.org/ja/3/library/datetime.html)
Firebase JS SDK v9 でログイン認証(Authentication)をする時の変更点

またFirebaseのv9.0.0以降の変更点です。
プログラミング初心者なので誤りがあるかもしれません。
その際はご指摘お願いいたします。

## Firebase Authenticationをこれから使用する人向け

Firebase v9はつい先日(2021/08/25)アップデートが行われ、正式にv9.0.0になりました。
```npm install --save firebase```
ってバージョンを明示せずにインストールするとv9になってるってことですね。
大きな変更点としては、Option API方式からComposition API方式になった事です。
といっても私もよくわかんないのでコードで説明すると、

```v8_10_0.js
import firebase from "firebase/app"
import "firebase/auth"

const config = {
  //...
}

firebase.initializeApp(config);
const auth = firebase.auth();
```

```v9_0_0.js
import { initializeApp } from "firebase/app"
import { getAuth } from "firebase/auth"

const config = {
  //...
}

initializeApp(config);
const auth = new getAuth();
```

のように、特定の関数をimportで明示的に呼び出す形のことをComposition APIと呼ぶようで、Vue3でも同様にComposition APIを使用するように変更が行われています。
これはページのロード高速化のためで、そりゃ毎回ライブラリ全部をimportするより明示的に一部分をimportした方が速いよねってことだと理解してます。

これからFirebaseやVue.jsで何かを作る場合は、Composition APIでコードを書くようにした方がいいみたいですね。

## だいたいの引数にgetAuth()を入れる

色々なFirebase v8以前のサンプルコードを見ながら、どうv9に対応させればよいのか悩みましたが結局```getAuth()```を使えばほとんど解決する事に気づきました。
当然と言われれば当然なんですが…。

例えばセッションの永続性を設定する```setPersistence()```だと、

```v8_10_0.js
import firebase from "firebase/app"
import "firebase/auth"

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(() => {
  //...
}
```

```v9_0_0.js
import { getAuth, setPersistence, browserSessionPersistence } from "firebase/auth"

setPersistence(getAuth(), browserSessionPersistence).then(() => {
  //...
}
```

と書きます。
ここでの違いは、Composition APIだと関数の引数に```Auth```インスタンスを含むようになっていて、ここに```getAuth()```を入れると解決します。
```getAuth()```は既存のAuthインスタンスを呼ぶか、既存のAuthインスタンスが無ければ新規でAuthインスタンスを生成します。
なので、```firebase.js```等のファイルで最初に初期化をし、```setPersistence()```でセッションの永続性を設定しておけばあとはFirebase Authenticationを使いたいところで```getAuth()```を引数に入れておけばよいみたいです。

FirebaseのCodelabにあるサンプルコード（Friendly-chat）でも、最初に初期化した後は全部```getAuth()```してるので多分合ってます。

## 私がしてた勘違い
私が色んなサイトを見て混乱してたのは、例えば```firebase.js```でAuthインスタンスの初期化をした時に

```js
import { getAuth } from "firebase/auth"
const auth = new getAuth();

export { auth }
```
として、それを他のAuthenticationを使いたい場所で

```js
import auth from "@/firebase.js"
import { signOut } from "firebase/auth"

signOut(auth).then(() => {
  //...
}
```
と書く必要があるのかと思って混乱していました。
実際にはこんな事をせずに、

```js
import { signOut, getAuth } from "firebase/auth"

signOut(getAuth()).then(() => {
  //...
}
```

同じ勘違いをされる方がいらっしゃるかはわかりませんが、そう解説してあるサイトもあったので一応…。（そのコードではそう書く必要があったのかもしれません。）

# Firebase Authentication の初期化 

```onAuthStateChanged()``` の使い方で3~4日悩んだんですが、こうすればいいってわかったのでまた別投稿で書きます。
kintoneのフィールド値変更時イベントで計算フィールドとJavaScriptカスタマイズの計算を一緒にしちゃだめ！という話

今回は、「フィールド値変更イベント」で計算フィールドとJavaScriptカスタマイズの計算を一緒にしないようにしましょう！というお話です。

ためしに、アプリを作ってみましょう。

# アプリの準備

数値フィールドのA,Bに値を入力したら、
計算フィールドCと数値フィールドDに自動的に計算値が入る。という仕組みにします。

| フィールド種類| フィールドコード | 計算式 |
|:-:|:-:|:-:|
| 数値  | A  |   |
| 数値  | B  |   |
| 計算  | C  | A + 10  |
| 数値  | D  | JavaScriptで B+C を計算する   |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/f858ef3a-48c8-70f9-c839-0a694166c1cd.png)

# JavaScriptの準備

計算フィールドはフィールド値変更時イベントで指定できないので、
数値フィールドのA,Bの値変更時に計算をすることにします。

```js
kintone.events.on(
  [
    "app.record.create.change.A",
    "app.record.create.change.B",
    "app.record.edit.change.A",
    "app.record.edit.change.B",
  ],
  (event) => {
    // D = B + C
    event.record.D.value =
      Number(event.record.B.value) + Number(event.record.C.value);
    return event;
  }
);
```

# 動かしてみましょう👀

動かしてみると、こんな感じになると思います。
数値フィールドAの値を更新しても、
最終的な計算結果の数値フィールドDの値が更新されません。

<iframe width="480" height="360" src="https://www.youtube.com/embed/hwmugwlw8y0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 何故！？

先程のJavaScriptのコードの
`// D = B + C`の上辺りに、

```js
console.log(event);
```
を忍ばせてから、Aの値を10から15に変更してみましょう。

すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/6dae0e30-e087-09cf-7b24-d36971feae17.png)

計算フィールドの計算よりも先に「フィールド値変更時イベント」が動いている！？
と思って、JavaScript計算の方を先に動かす作戦でやってみても

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/386b8bbc-2d61-b856-2323-e5eec6cf2398.png)

のような変な計算結果になって・・・・だめでした。
計算フィールドの方が先とか後とかではなくて、「フィールド値変更時イベント」とは非同期に動いています。
どちらが先とかはわからないですね。

というわけで、JavaScriptで「フィールド値変更時イベント」を使って計算する場合は「計算フィールド」が絡む計算をしないようにしましょう。

※ボタンクリックで発火するようなイベントのときは計算フィールド使って計算しても大丈夫です✨
データ分析メモ

##はじめに
以下のUdemy講座の学習メモです。
[やさしい実用統計 Pythonによるデータ分析入門](https://www.udemy.com/share/103DSBAEASdltXRH0F/)

##統計の分野
大きく4つあります。企業で一般的に利用される統計は記述統計です。

- 記述統計（ほかの統計分野の基礎でもある）
データの情報収集

- 推測統計（統計の中心的な理論）
部分から全体を推定

- ベイズ統計
データに基づく確率的推移

- 多変量解析
多変量データのモデリング

##記述統計
データの情報収集。データを集約して情報を抽出する方法の総称。
主な方法は次の通り。

- データの分布を確認する
- 代表値を調べる
- 散布度を調べる
- 変量を標準化する

##データ分析の目的
データ分析は必ずおおもとの課題につながるものでなければならない。
データ分析の結果から施策が立案・実行されることが大切。施策が実行されて初めてデータ分析が成功したか否かがわかる。
##データ分析の種類
2種類に分類できます。

- 求解：求める結果が明確に定義されている
- 探索：データの中から何かを発見する調査

##データ分析プロジェクトの作業と作業量

1. 計画（5%）
2. データ収集（5%）
3. データクレンジング（60%）
4. 本格的なデータ分析（20%）
5. 結果解釈～活用への提言（10%）

##必要なスキルと知識

- 本来業務の知識
- 統計の知識
- プログラミングスキル
- データ分析ツールの知識
- プロジェクト管理

##データプロファイリング
いつどこでだれが何のためにどのようにして集めたのかを調べてデータの前提を明確にすることが大切

####データの発生目的

- 今回のデータ分析のために集められたデータ
- 別の目的のために集められたデータの流用

####母集団と標本

- 母集団：分析対象全体
- 標本（サンプル）：分析対象の一部

####紙データと電子データのギャップ
####データ発生システムの特徴

##変数名の規則
- 英字で始まる半角英数字を使用する
- 特殊文字や全角文字は使用しない
- 英語で意味の通じる名称にする
- 複数の単語をつなげる場合はcamelCaseにする

##データ加工の原則
データの修正・加工のプロセスにおいて、加工ミスの防止と再現性の保証のためルールを守ります。

- オリジナルデータの保管
- プログラムによる加工（再現性のない手作業は行わない）
- 履歴管理

##Pythonの重要なライブラリー

- NumPy（import numpy as np)
    - 用途：高速の配列計算。
    - 通常の配列ではできない計算を行うためのメソッドがたくさん用意されています。計算精度と計算速度に配慮されているため科学技術計算での利用に適しています。

- pandas（import pandas as pd）
    - 用途：データフレーム
    - 表形式のデータ構造で、データ分析に必要な様々な機能を備えています。

- matplotlib（import matplotlib.pyplot as plt）
    - 用途：グラフ描画

##用語

- 代表値
データの特徴を一つの値で表したモノです。
主な代表値として、平均値、中央値、最頻値、その他の代表値として最大値、最小値、トリム平均、分位数があります。

- 散布度
データのばらつき度合いをあらわす指標で、代表値を補足する情報。

- 変量の標準化
異なる変量を比較するためにデータの標準化を行います。
変量の標準化には、標準化変量、偏差値、正規化があります。

- 変量
異なる値をとり得る量

- 平均値
算術平均、幾何平均、調和平均があります。

- 階級化
数値データの範囲をいくつかの区間に区切ることを階級。各階級の中心の値を階級値。
データの値を所属する区間の階級値で表すことを階級化と言います。

- 度数分布表
階級化したデータを各階級で集計した結果をまとめた表を度数分布表と言います。
項目としては、階級値、度数、相対度数、累積度数、相対累積度数があります。

- 散布度
データのばらつき度合いを示す統計量

- ヒストグラム
度数分布表の内容を横軸に数値データの範囲、縦軸に度数あるいは相対度数の値をとったグラフ。

- 中央値
数値データを昇順にソートして並び順の真ん中にくる値

- 分位数
数値データを昇順にソートして、同じ個数のK個のグループに分けた時の区切り地をK分位数と言います。主な分位数として、中央値（二分位数）、四分位数、パーセンタイル（百分位数）があります。

- 最頻値
度数分布表において、頻度が最大となる階級値のこと。

- トリム平均
データの最大値側と最初内側から数個を除外したデータの平均をとったモノ

- 平均偏差
各変量の値と平均値の差の絶対値の平均

- 中央値絶対偏差
各データと中央値の差の絶対値をとり、その値を照準に並べた時の中央値

- 外れ値
その値が他の値に比較して極端に大きくは離れている値。統計手法により何を外れ値とするかは異なる。

- 有限事象
何かの事象が発生する可能性があるとして、可能な事象のパターンが有限個である場合
nvmを利用して、Node.jsをセットアップする方法のチートシート

# 前提条件

- Node.jsが入っていること

プロジェクトフォルダがある階層で`node -v`してみた時、きちんとバージョンが表示されればOK
表示されない時は,Node.jsを入れよう。

- macOS Mojave

多分macならコマンドは基本的に同じだと思う。でも私はbashを使っているので、zshの人は少し違うこともあるみたいですが、手持ちの環境で動作確認ができないので[公式Readme](https://github.com/nvm-sh/nvm#install--update-script)を呼んでください。とっても丁寧に書いてあるのでChrome ＋ Google翻訳ツールバーを 使えば楽々読めるはずです。


# nvmってなんだ
nvmはすーぐ新しいバージョンが出てしまうNode.jsのバージョン管理をしてくれるもの。
バージョンの切り替えなんかを簡単にしてくれます。
[公式Readme](https://github.com/nvm-sh/nvm#install--update-script)によると、ユーザごとにインストールされて、シェルごとに呼び出される様に設計されているとのこと。

sh、dash、ksh、zsh、bash、特にUNIX、macOS、WindowsWSLで動作するそうです。
※Windowsの方は、そのままだと使えません。Windows上でLinuxを動かせるWindowsWSL上で作業しましょう。

# nvmが入っているか確認したい

私のように、過去に自らやったにもかかわらず、入っているか入っていないのか忘れちゃったという人は以下のコマンドで確認ができます。

```
nvm --version
```

# Gitからnvmをインストール
インストールスクリプトを使用する方法もある様ですが、注意書きが長くて面倒そうだと思ったので、今回はGithubからインストールする方法で行きます。

[公式Readme](https://github.com/nvm-sh/nvm#install--update-script)によれば、どこの階層にいても実行できるとのことなので、ターミナルを開いたらすぐに以下のコマンドを入力。

```terminal
$ git clone https://github.com/creationix/nvm.git ~/.nvm
```

もしも、すでにnvmが入っていたら`fatal: destination path '所在のパス' already exists and is not an empty directory.`と出力されて、どこに入っているのか教えてくれます。(親切)

先のような出力が出て、nvmが入っているはずなのに、`nvm --version`をすると`command not find`が出力されてnvmのコマンドが使えない場合は、パスが通っていないのでnvmを召喚できない状況です。(インストールした後に以下のパスを通す作業が未完です)
インストール直後にやる作業なので、一時的に使えるようにするのではなく、ターミナルを開いたらいつでも使える状態に整備しましょう。
以下のコマンドを打って、ターミナル立ち上げ時に召喚するリストに登録(一般的にパスを通すという)をします。

ただ、人によってどのファイルに書き込むのかが異なってきます。おそらく私と同じbashを使っている人は.bash_profileなのではないかと思いますが、何を言われているのかワケが分からないよという人は、[過去にパスを通すとは何か？をまとめた記事がありますので、こちら](https://qiita.com/usayamadausako/items/a4d71e7738db31451cb5)を参考にしてみてください。

若干話が長くなりましたが、各々パスを通すファイル(私の場合は.bash_profile)をvimなどで開いて、以下の記述を追加してください。
`#`以降はコメントなのであってもなくてもいいです。

```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
```

かけたらターミナルのウインドウを一度閉じて開き直すか、面倒な場合は以下のコマンドで適用しましょう。

```
$ source .bash_profile
```

# 特定のバージョンのNode.jsを入れたい
Node.jsの公式ページで確認するなり、以下のコマンドを実行するなりして、入れたいバージョンを確認します。

```terminal
$ nvm ls-remote
```

確認できたら、以下のコマンドでインストールしましょう。

```terminal
$ nvm install 入れたいバージョン番号
```

以下の様なメッセージが出れば完了です。

```terminal
Now using node 入れたいバージョン番号 (npm ほにゃらら)
Creating default alias: default -> 入れたいバージョン番号
```

# ターミナルを開いたらデフォで使えるバージョンを変更したい
`nvm use バージョン番号`で一時的に使用するバージョン指定をする方法もありますが、いつターミナルを開いても同じバージョンを適用させたいときは以下のコマンドでできます。

```
$ nvm alias default バージョン番号
```

# 一時的に使うバージョンを切り替えたい

```
$ nvm use バージョン番号
```
ActiveRecord の `after_save` と `after_commit on: :save`

比較する。



### `x ---after_save ---> y`

xとyは同一のtransaction内に入る。「xとyが同時に行われないとデータ不整合が生じまずい」際に使用する。
レコードへの差分は、#saved_changes_to_attributeにより取得できる。

なお、after_save内にタスクのエンキューを含めるのは悪手である。
- y内でエンキューより後で処理が転んだ時に、作成されたレコードはロールバックされるがジョブは残ることになる。
- ジョブの中に別トランザクションを張って同一のテーブルを見る処理があったとする。エンキューされたジョブの中でafter_saveのコミット前にDBを参照すると、x内での処理が反映されていない。


(このような場合は、after_commitを用いる)。


### `x --- after_commit ---> y`

xはtransactionがはられ,yはその中に入らない。つまり、「yが失敗してxだけが実行されても問題ない」。(Error Reporting Serviceを見てyの失敗通知に気づいてyだけ実行するので問題ない）つまり、「yの成否にかかわらず、xを実行したい」

レコードへの差分は以下で取得できる。(on: :destroyの場合は、普通にselfのattributeを見れば良い)

- 差分があったか `attr_previously_changed?`
- 差分 `attr_previously_change`
- 差分前 `attr_previously_was`



## Ref


- https://makandracards.com/makandra/34789-how-to-capture-changes-in-after_commit
- https://www.bigbinary.com/blog/rails-6-1-adds-_previously_was-attribute-methods
K8s:コンテナにログイン

kubectl exec readiness-httpget-pod -it -- /bin/sh
kubectl exec readiness-httpget-pod -c ContainerName -it -- /bin/sh

-itオプション意思是代表交互和打开一个tty.
-c 是如果一个pod里面有多个container，加上-c指定容器名称。
--是一个固定格式，后面接要运行的命令。
GASで開発するLineBotでログを出力する

# はじめに
GASでLine Botを開発している際にログがでないと不便だなーと思い、ログをスプレッドシートに出力できるようなコードを書きました。（書きましたというには大袈裟ですが…）

# コード

```javascript:logger.gs
const sheetId = '[スプレッドシートのID]';
const sheetName = '[スプレッドシート のシート名]';
const sh = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);

function logger(log) {
  let lastRow = sh.getLastRow() + 1;
  sh.getRange(lastRow,1).setValue(new Date());
  sh.getRange(lastRow,2).setValue(log);
}
```

上記のコードを新しいスクリプトにでも貼り付けたら使えると思います。

* スプレッドシートのIDはスプレッドシートを開いた際のURLに書かれています。<br/>
https://docs.google.com/spreadsheets/d/[スプレッドシートID]/
* シート名は各自出力したいシート名を記入してください。

# 使い方
同一プロジェクト内の出力したいところから呼び出すだけです。

```javascript:test.gs
function test() {
  logger("test");
}
```

![スクリーンショット 2021-09-06 18.06.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547651/cfc415bb-c202-8b98-ede3-93b6f395ea3f.png)

時刻とログがスプレッドシートに順に表示されます。
AndroidStudio 4.2でGradleからsigningReport、SHA-1を確認する

GCPのAPIを使うためにAndroidStudioでSHA-1を発給しようとしたところ、あれGradleウィンドウのTasksから確認できない？？　ってなりました。
よく見たらできました。
AndroidStudio 4.2から変わったのかな？

***

AndroidStudioの画面右側には`Gradle`というボタンがあるのでこれをクリックするとGradleのウィンドウが開きます。
昔はここから`app→Tasks→android`と辿っていくと`signingReport`が確認できたのですが、あれ、無くなってる？
<img width="700" alt="AndroidStudio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/b07bcd7f-087d-399d-f807-58af982030e9.png">

てわけで象さんのアイコンをクリックしましょう。カーソルを合わせると`Execute Gradle Task`と表示されます。
<img width="600" alt="SelectExecuteGradleTask.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/d4dee170-31bb-e732-7590-7681b7902f36.png">

ターミナルが開くので以下を`gradle signingReport`と入力し、実行します。
<img width="600" alt="Terminal.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/e6658231-3500-96fc-8546-4651a4f1a0f4.png">

Runウィンドウにアレコレ情報が出力されますがその中にSHA-1も含まれています。
<img width="700" alt="SHA-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073313/9eb58bb7-0227-08ac-b123-51d496cc6c7d.png">

はい。
コマンドを打つよりも楽ですね。
【React】React ことはじめ (ただの学習ログ) Part2

## きっかけ
- 前回の以下記事の続き

https://qiita.com/kei1-dev/items/33b630f477a4aaed050e

##学習の進め方
- 前回の本で触れられていなかったAPI呼び出しやルーティングの内容が触れられている[Reactハンズオンラーニング第2版](https://www.oreilly.co.jp/books/9784873119380/)で学習したいところだけメモしています。
- 前回と同じく、記事の記載に間違いがある場合、マサカリをお願いします…

## 学習内容
### ステート管理
- アプリケーション全体のステート管理
  - 複数コンポーネントがステートを持つと複雑になるため、1箇所でステートを管理したい→最上位のルートコンポーネントで管理、参照は親から子コンポーネントへプロパティとして渡す、変更は子から親コンポーネントへ伝えステートを更新する

-  コンテキスト
  - 巨大アプリケーションでのステート伝達の際に、中間コンポーネントが伝達のためだけにプロパティ設定が必要となり、複雑なアプリケーションとなってしまう。→コンテキストを使用することで解決。コンテキストプロバイダへデータを渡し、コンテキストコンシューマから読み出す

### データ
- API呼び出し
  - fetch APIでHTTPリクエストを送信可能。GET, POST, PUTの場合はfetch APIのオプションとしてmethod内で指定。(axiosで実現する方法は別途確認)

- WebStorageへの保存
  - saveJSONでlocalStorageへの保存、loadJSONでlocalStorageからの読み出す。

### ルーティング
- React Routerでルーティングを設定

### 遭遇したエラーとその対処

- Module not found: You attempted to import XXX which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
  - srcより上階層の資源を読み込もうとしたら発生。src配下に資源を移動、importのパスを修正 

- Syntax error: Unterminated JSX contents
  - returnで書いていたJSXのタグの閉じ忘れが原因。

- Manifest: Line: 1, column: 1, Syntax error Manifest.json
  - create-react-app後にpublicの内容をindex.jsを除き、削除していたことが原因。manifest.jsonを復活。

- ESLintで’jsx-a11y/href-no-hash’ was not found
  - .eslintrc.json内でhref-no-hashをoffにする設定を追加。
二桁以上の整数を入力すると、十の位と一の位の数字の足し算、十の位と一の位の数字の掛け算をそれぞれ行い、最後に2つの結果を足し合わせて出力するプログラムの作成

初投稿。

とある日に遭遇したRuby問題。
ポイントは整数の十の位・一の位を個別の整数として出力するメソッドを理解すること。特に十の位！
模範解答だけではイマイチしっくり来なかったため、解答コードを元に解説を備忘録として。

〜今回はヒントがありました。〜
「入力された2桁以上の整数を10で割った計算結果の余りが1の位、整数を10で割ったものを更に10で割った計算結果の余りが10の位となります。」
現代文の問題かのようなヒントが記載されていましたが、要は'%'を使いなさいということですね。

```rb
def addition(a, b)
  a + b
end

def multiplication(a,b)
  a * b
end

def slice_num(num)
  # 10の位
  tens_place = (num / 10) % 10
  # 1の位
  ones_place = num % 10
  return tens_place, ones_place
end

puts "二桁の整数を入力してください"
input = gets.to_i
X, Y = slice_num(input)
add_result = addition(X, Y)
multiple_result = multiplication(X, Y)
puts "足し算結果と掛け算結果の合計値は#{add_result + multiple_result}です"
```
解いていく前に忘れてはいけない大前提のおさらい！
「Rubyの性質上、整数同士（integer型）の計算だと返り値は整数になるので、小数点以下は切り捨てられる。」
この前提で今回のアプトプットの8割完了です。

では実際に2桁の整数を入力して考えてみます。

```ruby:qiita.rb
input = 55 の場合
ｓｌｉｃｅ_numメソッドに代入され、
tens_place = (55 / 10) % 10
ones_place = 55 % 10
```

ここで文系の私は壁にぶつかるわけです。
ones_plase = 55 % 10　すると余りは5。なるほどどんな整数が入力されても一の位は求められるわこれで。
では十の位tens_place = (55 / 10) % 10 するとそもそも5(小数点以下切り捨て）をさらに10で割って余りってなんぞ？！と。

原因は'%'の理解不足でした。
割り算では5を10で割ると0.5ですが、'%'←で割って余りを求める際の考え方は「5（10未満の数字）を10で割ると、割れない。なので5がそのまま余る」という解釈なのです。

ターミナルで実行結果を確認すると、下記の通り55でも75でも十の位が個別の整数として返ってきます。

```
irb(main):001:0> num = (55 / 10) % 10
=> 5
irb(main):002:0> num = (75 / 10) % 10
=> 7
irb(main):003:0> 
```
2桁の整数では（num / 10）の段階で十の位を求められそうな雰囲気もありますが、ここでの　'/　10'の役割はnumの十の位を1桁目に持ってくることです。その上でnum十の位より上の数字を'%　10'で排除します。
(num / 10)では3桁以上の整数が入力された場合に対応できません。ターミナルで実行結果を確認すると、

```
irb(main):001:0> num = (1525 / 10)
=> 152
irb(main):002:0> num = (1525 / 10) % 10
=> 2
irb(main):003:0>
```
となり、'% 10'を記述することで何桁の整数でも十の位を個別の整数として求めることができます。

以上。
[Rails]resources、アクションについて

##はじめに
####記事の対象者
・Railsのroutesで混乱しているヒト

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
１）routesとは？
２）resourcesとは？
３）基本アクション
４）全アクション指定
##routesとは？
自分なりにroutesについての説明は下記のリンクにあるよ↓
https://qiita.com/janani/items/1bb869260ce252f18a73
##resourcesとは?
上記のリンク先のように説明すると。。。resources=記憶となる。

```
resources :コントローラ名
```
routes.rbに記入することによってプラウザから受け取ったアクション（地図）をroutes.rbさんがresources（記憶）にあるcontrollerさんへ案内してくれる。

##基本アクションとは

![actionsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/7f059cb2-5aba-0655-a4a6-6b4afb7d3fe3.png)
####indexアクション
・基本的にアプリケーションのユーザが一番最初に見るページ
・他のページへ遷移するためにリンク先を集中して配置
・通販サイトで例えると、ログインや新規登録、サイトについて、買い物リストなどいろいろなボタンがあるページ
####newアクション
・resources:controller名内に、ユーザ側からなにか新しいデータを追加させたいときに使う
・例えば、ユーザの識別のためのログイン/新規登録ページ
####createアクション
・newアクションでユーザが記入したデータを保存するために使う
→例えば、新規登録をしたときのデータを保存してログイン時に再利用するとき
######＊newとcreateは基本的にセット＊
####showアクション
・保存されたデータを個別に詳細ページとして表示するときに使う
→通販サイトで例えると、商品一覧ページにある商品の詳細ページ
####editアクション
・保存されたデータを編集するために使う
→例えば、ログインするときにパスワードを忘れてしまい変えたいとき
####updateアクション
・editで編集したデータを保存するために使う
→例えば、パスワード変更時のデータを保存してログイン時に再利用するとき
######＊editとupdateは基本的にセット＊
####destroyアクション
・データをまるごと消すときに使う
→例えば、ログアウトをしたいときに使う

##アクションの指定方法
下記のようにresourcesの後ろに、使うアクション名をonly:[:]記入する。

```
resources :controller名,  only: [:アクション名, :アクション名]
```

######＊全アクションを使うなら下記のように設定すると上記の表の全アクション込みとなる＊

```
resources :controller名
```
######＊アクションは自分で作れる！＊
例えば、トップページ→　ログイン/新規登録(new)→indexの順にページの遷移をしたい場合。
トップページのページへ遷移するためのアクション名をtopとする。

```
(routes.rb)
resources :controller名, only: [:top, :index, :new]

(controller.rb)
def top
end

def index
end

def new
end
```

##最後に
ここまで読んでくださいましてありがとうございます！