OmniAICreator/Qiita-1.07M huggingface dataset:
Running resistances, ボッシュ自動車handbook 11版(31) p.464

Vehicle motion  , ボッシュ自動車handbook 11版(30)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

# Running resistances
p.464

## Total running resistance
Table 1: QUantities and units
## Individual running resistances
### Rolling resistance

### Aerodynamic drag

### Climbing resistances and downgrade force

Table 5 Gradient angle and climbing resistance

Table 6: Climbing resistance and climbing power


# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
# 文書履歴(document history)
ver. 0.01 初稿 　20221021
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Vehicle motion , ボッシュ自動車handbook 11版(30) p.462

Vehicle motion  , ボッシュ自動車handbook 11版(30)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

# Vehicle motion
p.462

## Coordinate system

Figure 1 Translational and rotational degrees of freedom of the vehicle body

## Degree of freedom of vehicle system

### Translational motion
Table 1 QUantities and Units

#### Float angle

#### Centripetal accelaration and tamgemtoa; acce;aratopm

### Rotational motions

### Moments

# Reference

[1] DIN ISO 8865 :2013
Road vehicles - Vehicle dynamics and road-holding ability - Vocabulary (ISO 8855:2011)
(Earlier standard: DIN 70000)

DIN 70000 Strassenfahrzeuge; Fahrzeugdynamik und Fahrverhalten; Begriffe (ISO 8855:1991, modifiziert)


ISO 8855:2011
Road vehicles — Vehicle dynamics and road-holding ability — Vocabulary

https://www.iso.org/standard/51180.html

Bibliography

[1]	ISO 21308-2:2006, Road vehicles — Product data exchange between chassis and bodywork manufacturers (BEP) — Part 2: Dimensional bodywork exchange parameters
[2]	SAE J670, Vehicle Dynamics Terminology


# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20221021
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
【Swift】端末の傾きを取得する

# はじめに
https://apps.apple.com/jp/app/%E6%B0%B4%E6%BA%96%E5%99%A8/id1621303604

以前、水準器を作成した際に使用した`CoreMotion`を使ってサンプルアプリを作ってみます。
簡単に端末の傾きが取得できるので是非試してみてください！

# 実装
```swift
import SwiftUI
import CoreMotion

struct ContentView: View {
    private let motionManager = CMMotionManager()
    @State private var x: Double = 0.0
    @State private var y: Double = 0.0
    @State private var z: Double = 0.0
    var body: some View {
        VStack(spacing: 50) {
            Text("x: \(x)")
            Text("y: \(y)")
            Text("z: \(z)")
        }
        .onAppear() {
            start()
        }
        .onDisappear() {
            stop()
        }
    }
    func start() {
        if motionManager.isAccelerometerAvailable {
            motionManager.accelerometerUpdateInterval = 0.5
            motionManager.startAccelerometerUpdates(to: .main) { data, error in
                guard let data else { return }
                x = data.acceleration.x
                y = data.acceleration.y
                z = data.acceleration.z
            }
        }
    }
    func stop() {
        if motionManager.isAccelerometerActive {
            motionManager.stopAccelerometerUpdates()
        }
    }
}
```

:::note warn
注意
サンプルアプリは実機でのみ動きます
:::

# 解説
`CoreMotion`をインポートします。
```swift
import CoreMotion
```
`CMMotionManager()`をインスタンス化します
```swift
private let motionManager = CMMotionManager()
```
傾きの格納先を作ります
```swift
@State private var x: Double = 0.0
@State private var y: Double = 0.0
@State private var z: Double = 0.0
```
`isAccelerometerAvailable`でモーションセンサーが使用できるか判定します
```swift
if motionManager.isAccelerometerAvailable {

}
```
`accelerometerUpdateInterval`で更新の頻度を決めます
```swift
motionManager.accelerometerUpdateInterval = 0.5
```
`startAccelerometerUpdates`で傾きの監視を開始します。
```swift
motionManager.startAccelerometerUpdates(to: .main) { data, error in
    guard let data else { return }
    x = data.acceleration.x
    y = data.acceleration.y
    z = data.acceleration.z
}
```
Viewが表示された時に監視をスタートさせます。
```swift
.onAppear() {
    start()
}
```
Viewが非表示された時に監視をストップさせます。
```swift
.onDisappear() {
    stop()
}
```

# おわり
めっちゃ簡単でした！！
CoreMotionは他にもいろいろな値が取得できるっぽいので今後使ってみようと思います！
【Markdown】バッククォートをエスケープする方法

## インラインコード

インラインコードの場合には以下の方法でバッククォートをエスケープできます。

```markdown
`` `code` ``
```

以下のように表示されます。
`` `code` ``

## コードブロック

コードブロックの場合には以下の方法でバッククォートをエスケープできます。

`````markdown
````markdown
```sample.txt
sample text
```
````
`````

以下のように表示されます。

````markdown
```sample.txt
sample text
```
````

`~~~`を使用することでもエスケープできます。

~~~~markdown
~~~markdown
```sample.txt
sample text
```
~~~
~~~~

以下のように表示されます。

~~~markdown
```sample.txt
sample text
```
~~~
【Java】toString()だと『ぬるぽ』になる話

# 経緯
DBから主キーをもとに特定のレコードを参照したあとに、カラム名と値をセットにMapに詰めてから値を取得しようとした時の話

Mapの値はObject型なので欲しい値をString型に変換しようと
```java:
    //map:レコードの情報が入ったMap<String, Object>　→ <カラム名、値>
    String value = map.get("カラム名").tostring();
```
こんな感じで書きました。
カラム名に該当する値を取ってきてObject型からString型に変換する時にtoString()を使って変数に詰めていました。

すると現場の上長からレビュー時にこんなご指摘が。。。

上長「toString()だと『ぬるぽ』しちゃうかもしれないので別のやり方で変換してください。」

私「承知です！」
（ほほう、、、なるほど、、、。
確かにカラムの値がnullの可能性もあるか、、。というかぬるぽとか気にしてなかった、、、。ってかぬるぽになるんや😇）

正直、String型に変換する時にそこまで考えていなかった私は事前に『ぬるぽ』を回避すべく、対策を見つける旅に出ました。スキルアップのチャンスです！
まあしかし、その旅は歩いて１０歩ほど進んだところで終わりを迎えましたが、せっかくインプットしたものなのでアウトプットしていきます。

# 『ぬるぽ』ってなんぞやねん
ぬるぽぬるぽってなんぞやねん。っとツッコミが聞こえてきた気がするので

NullPointerExceptionを『ぬるぽ』って呼ぶ人たちが多いです。
っていうかNullPointerExceptionのことです。

海外ではNPE等と略されてるらしいです。

参照型で参照する値が無い時（nullの時）に怒られるパターンです。
プログラミング初心者が出くわすエラーNo.1とも言われているとかいないとか。。。


# String型に変換するときに『ぬるぽ』を回避する方法
前置きが長くなりましたが、結論から言うとvalueOf()とキャストです。

valueOf()を使ってあげると変換元がnullでもnullで返してくれます。
キャストも同様です。

これらを使えば変換元がnullであってもぬるぽで落ちずに処理が通ります。

DBの値がnullを許容されていなければ回避する必要もないかもしれませんが
今回はシステムの都合上、たとえDBの値がnullでもとにかく返して欲しいのです！

### valueOf()
上のコードでぬるぽを回避するなら
```Java:
    String value = map.get("カラム名").valueOf();
```
こんな感じですね。簡単です。
これだと"カラム名"に該当する値がnullでも`value`にはnullが入ります。
nullでもいいからとりあえず値を返して！って時にはこっちですね。


### キャスト
同じくキャストでぬるぽを回避するなら
```Java:
    String value = (String)map.get("カラム名");
```
キャストもvalueOfと同様で該当する値がnullの場合は`value`にはnullが入ります。


# まとめ
toString()を使うと『ぬるぽ』で落ちちゃうよって話でした。
ぬるぽだと都合が悪くなる場合は

・valueOf()でStringに変換
・キャストでStringに変換

この2つでぬるぽは回避できます。

開発ビギナーが出くわすエラー1位の『ぬるぽ』もこれで怖くないですね。
統計検定準1級に1ヶ月で合格した話

# はじめに
**統計検定準1級に運良く合格できてしまったのでその記録です。**
![準1級合格.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883466/84d5246b-46cc-df24-af58-b2b6f789349f.png)

# 筆者のスペック
- 偏差値50くらいの大学4年生
- 数学はあまり得意ではない
- 1ヶ月前に統計検定2級に合格([記事](https://qiita.com/astrfo/items/62f708da379927dbb69e))

# やったこと
1. [統計学実践ワークブック](https://www.gakujutsu.co.jp/product/978-4-7806-0852-6/)を軽く1周読む(読むだけで問題は解かない)
1. もう1周、今度は章末問題を一部解きながら深く読む
1. [過去問](https://www.amazon.co.jp/dp/4788925575)を1周
1. 統計学実践ワークブックを最後に1周

**勉強時間は1日3~5時間程度だったので、恐らく100時間以上はかかりました。**

# 使った書籍
**使った本はこの2冊だけです。**
- [統計検定準1級対応　統計学実践ワークブック](https://www.gakujutsu.co.jp/product/978-4-7806-0852-6/)
![workbook.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883466/a454acfa-3ed0-4c07-d3a5-eb58093633de.jpeg)

- [統計検定 準1級 公式問題集](https://www.amazon.co.jp/dp/4788925575)
![kakomon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883466/49d32c59-26e0-d17a-8b32-b186ac9a0552.jpeg)


# 詳しい勉強方法について

### 1. [統計学実践ワークブック](https://www.gakujutsu.co.jp/product/978-4-7806-0852-6/)を軽く1周読む(読むだけで問題は解かない)
色々な合格体験記を読んでいると、みんなこれが重要と書いてあったのでとりあえず読むことにしました。しかし、思いのほか難しかったので、まずは軽く読んでみることにしました。ここでは、どういう単元があるのか・どんな内容なのかに注力して読みました。

### 2. もう1周、今度は章末問題を一部解きながら深く読む
軽く1周読んだだけでは正直何も分からなかったので、今度は単語の意味だったり公式を覚えたりして一部章末問題を解きました。

**[反省点] 単語の意味や公式を覚えただけでは過去問は解けません。ここで、全ての章末問題を解いておくべきでした。章末問題はかなり難しいですが、時間をかけてでもやるべきだったと思います。**


### 3. [過去問](https://www.amazon.co.jp/dp/4788925575)を1周
ここで受験日を決めて、本格的に過去問に取り掛かります。過去問の点数は以下のとおりです。(2021年は難しいという噂があったので最後に回しました)

- 2019年：47% (16/34)　論述なし
- 2018年：56% (19/34)　論述なし
- 2017年：63% (24/38)　論述あり
- 2016年：67% (22/33)　論述なし
- 2015年：63% (22/35)　論述なし
- 2021年：31% (11/35)　論述なし

ワークブックの章末問題を解かなかったツケが来ました。2級でやった区間推定や仮説検定に関しては難なく解けるんですが、それ以外はほとんど取れなかったです。2018, 2017年で点数は上がっていくのですが、ここで取れたのはグラフの読み取りのような簡単な部類で、計算問題はほとんど解けなかったです。
2021年の過去問はテスト2日前に解いたので控えめに言って絶望しました。

### 4. 統計学実践ワークブックを最後に1周
2021年の過去問を解いた直後は絶望してましたが、一応合格点を超えた年もあったので諦めずにワークブックをもう1周しました。**ここでようやく解いてなかった問題に取り掛かります。** とは言っても、1日しかなかったので出そうな単元だけピックアップして解きました。なので、3~4割くらいは捨てたかなと思います。正直、これおかげでギリギリ合格できたなと思います。

# PBTとCBT
PBTと違ってCBTはどうなの？という疑問があると思いますが、実際難易度的には以下のようになると思います。
**2021 >>>> CBT ≧ 2015~2019**
CBTは日によって問題も難易度も違うので一概には言えませんが、こんな感じになると思います。ちなみに私は**CBT = 2015~2019**の問題を引けたのかなと思います。

# まとめ
これからも統計学の勉強は続けていきたいなと思います。
お世話になった記事を以下に載せておきますので参考にしていただけると幸いです。

### 参考

- [統計検定準1級　リンク集](https://qiita.com/Ken1234/items/0ac51e21b10568587c95)
- [これから学ぶ人向け「統計検定準１級チートシート」](https://qiita.com/DeepTama/items/9a07129626f82e9add5e)
- [統計検定準1級に受かるための勉強法・参考サイト](https://zenn.dev/dlbsabu/articles/5300da50921070)
- [【資格】統計初心者が統計検定２級・準１級を合計２か月で合格した話](https://zenn.dev/yanagikk/articles/a32a575a9163e2)
- [統計検定準1級 解説　〜過去問解答例・解説 ＆ 公式ワークブックの解答例・解説〜](https://www.hello-statisticians.com/toukeikentei-semi1)
- [【失敗しない】統計検定準1級向けのおすすめ参考書](https://mimikousi.com/statistical-certificate-pre1-book/)
- [統計検定準1級に合格した話](https://i5882353i.hatenablog.com/entry/2022/04/14/193914)
MPIプログラムをgdbとtmuxでデバッグ（マルチノード対応）

## はじめに

MPIプログラムをgdbでデバッグするためのまともな方法が見つからず、あまりにしんどかったので`mpitx`というツールを作った、というお話です。

https://github.com/s417-lama/mpitx

デモ動画を見てもらえると分かりやすいかもしれないですが、各MPIプロセス毎に端末が割り当てられてtmuxで制御できます。

![](https://raw.githubusercontent.com/s417-lama/mpitx/images/mpitx_gdb.gif)

tmuxの機能としてキーボード入力を全ての端末に複製して送ることができるので、gdbによるデバッグ等に便利です。

さらに、複数ノードにも対応させたので、スパコンやクラスタ等の環境でも動作します。
これは某スパコンで実際に実行したときのキャプチャですが、

![](https://raw.githubusercontent.com/s417-lama/mpitx/images/mpitx_remote.gif)

`hostname`の結果から別のノードでの実行をインタラクティブに制御できているのが分かると思います。

## 必要になった背景

MPIプログラムをgdbでデバッグするには、下の記事でも言及されているようにあんなことやこんなことをしてやる必要がありました。

https://qiita.com/kaityo256/items/01dcd47eb4179b0d1f55

いちいちデバッグのためにコンパイルし直すのもなんだかなあという気がして、もっと簡単にgdbを起動できる何かが欲しいなあと思っていたところ、`tmpi`なるスクリプトを見つけました。

https://github.com/Azrael3000/tmpi

これが`mpitx`の原型で、大体の機能は既にあってありがたく使わせていただいていました。
しかし、しばらく使っているうちにいくつか不満が出てきたので作り直したという次第です。

`mpitx` と `tmpi` の比較:
- `mpitx`はマルチノード対応、`tmpi`はマルチノード不可
- `mpitx`はMPI実装固有のオプションをそのまま`mpiexec`に渡せる、`tmpi`ではそれが面倒
- `mpitx`はpython3スクリプト、`tmpi`はbashスクリプト
    - 細かい話: `tmpi`では`reptyr`コマンドがなければMPIの子プロセスに環境変数を引き継ぐことができないが、`mpitx`ではpython3のいい感じに上手いことやっているので`reptyr`への依存なしで環境を引き継げる

色々あるんですが、大きかったのは`tmpi`がマルチノードに対応していなかったことでした。
複数ノードでしか再現しないバグがたまーに出現するので、この機能はぜひとも欲しいところ。

## 使い方

だいたいはGitHubの方に書いたので、そちらを参照してもらえればと思います。

https://github.com/s417-lama/mpitx

単なるpython3スクリプトなので、python3とtmuxがあればうごくはず、です。

簡単に試したければこれでインストール:
```sh
pip3 install git+https://github.com/s417-lama/mpitx.git
```

使い方は
```
mpitx [OPTIONS]... -- [COMMANDS]...
```

こんな感じで、`[OPTIONS]...`の部分が`mpiexec`のオプションとしてそのまま渡されます。
コマンドとの区切りの`--`は必須になっていて、`--`のあとの`[COMMANDS]...`がtmuxの各端末上で実行され（ているように見え）ます。

`--`が必須なのはオプション解析をサボるためで、MPI実装固有のオプションが渡されてもそれをそのまま`mpiexec`に投げられるようにするためです。
一方`tmpi`では独自のオプション体系を持っていたので、`mpiexec`にそのまま渡したいパラメタがあると大変です（`--hostfile`とか諸々）。

例えば4プロセスでbashを起動したければ
```sh
mpitx -n 4 -- bash
```

gdbでデバッグしたければ
```sh
mpitx -- gdb --args ./a.out arg1 arg2 ...
```

こんな感じで簡単にできます。

## 実装について

細かい話ですが簡単にメモしておきます。
単に使う上では知らなくても困らないと思うので適宜読み飛ばしてください。

`mpitx`コマンドで立ち上げられた大元のプロセスを`P`としましょう。
まず渡されたオプションは`mpiexec`にそのまま渡し、コマンドは`mpitx`のラッパを挟んで`mpiexec`に渡しておきます。
そして`mpiexec`によって立ち上げられたMPIの子プロセスを`C_i`（`i`はMPIランク）とします。

次に、tmuxの各端末に標準入出力をプロキシするプロセスを立ち上げておきます。
MPIプロセスの数だけ端末を用意するので、これらのプロセスを同様に`T_i`と表記します。

ここで、`P`と`T_i`は同一のノードで実行されていますが、これらと`C_i`が同一のノードで実行されている保証はありません。
これらのプロセス間での情報のやり取りにはTCPソケットを用いています。

まず最初に`P <---> C_i`間の接続を確立し、次に`P <---> T_i`間の接続を確立します。
`T_i`では[リバースシェル](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md)と同様の原理で、標準入出力を`C_i`へフォワードするために`C_i`からの接続を待ち受けます。
`T_i`のホスト名およびポート番号は`P`を介して`C_i`に伝えられ、`C_i`から`T_i`への接続が完了します。

この時点で`C_i`が`mpitx`に渡されたコマンドを実行し、`T_i`の端末から`C_i`のセッションをインタラクティブに操作することが可能になります。

TCPソケットを用いた実装である以上、マルチノードで`mpitx`を使うにはノード間がイーサネットで接続されていてソケット通信が通ることが条件になります。
接続できるポートが制限されていたりすると動かないかもしれないです。

## 最後に

gdbやtmuxなど、使い慣れたツールを気軽に使えた方がデバッグへの心理的障壁が下がるのでおすすめです。
MPI向けにはTotalViewのようなリッチなデバッガもあるようですが、オープンソースではないし使えるシステムも限られてくるので...。

主にデバッグ用途で紹介していましたが、マルチノードで各計算機の状態を確認する用途でもこれは結構便利です。

https://github.com/s417-lama/mpitx
４０代おっさんPythonを勉強する（数学関連や時間表現のモジュール）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

### random

- 疑似乱数を生成する

```python
import random

print(random.choice([1, 2, 3, 4, 5,])) # リストから無造作で1つを返す
print(random.randint(15, 50)) # 15から50までに整数を１つ返す
print(random.random()) # 0.0から1.0までの間に浮動小数点数を1つ返す
print(random.sample(range(1000), k=20)) # 1000の中に整数に20個の整数リストを返す
n = [1, 2, 3, 4, 5]
print(random.shuffle(n)) # リストnをシャッフルする
print(n)
```

### math

- 数学関数

```python
import math

#  入力引数はxとする
print(math.ceil(2.7)) # x以上の最小の整数を返す
print(math.floor(2.7)) # x以上の最大の整数を返す
print(math.fabs(-25)) # xの絶対値を返す
print(math.factorial(5)) # xの階乗を返す
print(math.fsum([0.1, 0.1, 0.1])) # iterbleの中の値の浮動小数点数の正確な和を返す
print(math.gcd(126, 366)) # 整数aとbの最大公約数を返す
print(math.pow(2, 3)) # xのy乗を返す
print(math.sqrt(25)) # xの平方根を返す
print(math.pi) # 数学定数 π = 3.141592......(円周率)
print(math.e) # 数学定数 e = 2718281.....(自然対数の底)

# 組み込み関数
print(round(2.546721, 2)) # 小数点以下2桁で四捨五入
print(abs(-2.55)) # 絶対値
print(sum([0.1, 0.1, 0.1])) # 総和
```

### decimal

- decimalモジュールは正確に丸められた十進浮動小数点数

```python
import decimal as d

d.getcontext().prec = 6 # 計算精度を変更
print(d.Decimal(1) / d.Decimal(7)) # 結果 0.142857
d.getcontext().prec = 28 # 計算精度を変更
print(d.Decimal(1) / d.Decimal(7)) # 結果 0.1428571428571428571428571429

#  普通の数値と同じ演算子が使える
a, b, c = d.Decimal('1.34'), d.Decimal('1.87'), d.Decimal('3.45')
print(sum([a, b, c]))
print(str(a))
print(float(a))
print(round(a, 1))
print(int(a))
print(a * 5)
print(a * b)
print(c % a)

# いくつかの数学的な関数も用意されている
print(c.sqrt()) # 平方根
print(c.exp()) # (自然)指数関数
print(c.ln()) # 自然対数（底eの対数)
print(c.log10()) # 底10の対数
```

### datetime

- 基本的な日付型および時間型

```python
from datetime import date, datetime
today = date.today()
print(today)
print(today.strftime("%m-%d-%y. %d %b %Y. Today is %A")) # 書式化コード
```

- 書式化コード
  <https://docs.python.org/ja/3/library/datetime.html#strftime-strptime-behavior>

```python
#  dateオブジェクトは演算できる
#  自分の誕生日を入れてみよう
birthday = date(1980, 11, 15)
age = today - birthday
print(f'あなたは生後 {age.days} 日です')
y, d = divmod(age.days, 365) # 閏年がないと仮定
print(f'あなたは約 {y} と {d} 日です')

years_old = today.year - birthday.year - \
    ((today.month, today.day) < (birthday.month, birthday.day)) # 誕生日過ぎているか判定
print(f'あなたは {years_old} 41歳です')
```

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
リスト編① 〜 参照渡し・addAllの理解 〜


# 目次
　[1.参照型とは](#1-参照型とは)
　[2.参照渡しの理解](#2-参照渡しの理解)
　[3.addAllの理解](#3-addallの理解)

# 1. 参照型とは
　参照型の変数には「アドレス」が格納されている。
　その「アドレス」のメモリ上（一時的にデータを保管しておく場所）に、値が格納されている。
　このように「アドレス」を参照し、値にアクセスする型の総称を「参照型」という。
　オブジェクト（変数）の生成はnew演算子を使っておこなう。
　nullは参照先がない状態のこと。
# 2. 参照渡しの理解


```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.List;

public class Qiita {
	public static void main (String args[]) {

        // ①さかなリスト作成
        List<String> fishList = new ArrayList<String>();
        fishList.add("まぐろ");
        fishList.add("あじ");

        // ②リスト更新メソッド呼び出し
        updateList(fishList);
    }
    
    // ③リスト更新メソッド
    private static void updateList(List<String> fishList) {
		fishList.add("しゃけ");
		fishList.add("さんま");
		
		// ④出力
		System.out.println(fishList.toString());
	}
}

```
　↑
①fishListの参照先の値には "まぐろ" と "あじ" が格納されている。
②fishListの参照を引数に、updateListメソッド呼び出し。
③fishListの参照先の値に "しゃけ" と "さんま" が追加される。
④さかなリストの出力結果は [まぐろ, あじ, しゃけ, さんま] となる。
※参照先の値を直接編集しているため、③でListをreturnする必要がない。

```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.List;

public class Qiita {
	public static void main (String args[]) {

        // ①さかなリスト作成
        List<String> fishList = new ArrayList<String>();
        fishList.add("まぐろ");
        fishList.add("あじ");

        // ②リスト更新メソッド呼び出し
        updateList(fishList);
    }
    
    // ③リスト更新メソッド
    private static void updateList(List<String> fishList) {
    	// ④鳥リスト作成
		List<String> birdList = new ArrayList<String>();
		birdList.add("すずめ");
		birdList.add("カラス");
		
        // ⑤引数で渡ってきたfishList = このメソッドで作成したbirdList
		fishList = birdList;
		
		// ⑥出力
		System.out.println(fishList.toString());
	}
}
```
　↑
ひとつ前のソースと異なるのは④⑤。
⑤では、fishListのアドレス自体を、birdListのアドレスで上書きしているため、
さかなリストの出力結果は [すずめ, カラス] となる。

# 3. addAllの理解

```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.List;

public class Qiita {
	public static void main (String args[]) {

        // ①さかなリスト作成
        List<String> fishList = new ArrayList<String>();
        fishList.add("まぐろ");
        fishList.add("あじ");

        // ②リスト更新メソッド呼び出し
        updateList(fishList);
    }
    
    // ③リスト更新メソッド
    private static void updateList(List<String> fishList) {
    	// ④鳥リスト作成
		List<String> birdList = new ArrayList<String>();
		birdList.add("すずめ");
		birdList.add("カラス");

		// ⑤AddAll
		fishList.addAll(birdList);

		// ⑥出力
		System.out.println(fishList.toString());
	}
}
```
　↑
ひとつ前のソースと異なるのは⑤。
AddAllの場合は、ふたつのリストがマージされるので、
さかなリストの出力結果は [まぐろ, あじ, すずめ, カラス] となる。


```java
    // ③リスト更新メソッド
    private static void updateList(List<String> fishList) {
    	// ④鳥リスト作成
		List<String> birdList = new ArrayList<String>();
		birdList.add("すずめ");
		birdList.add("カラス");
        
        ///// 追加 /////
        fishList.clear();
		// ⑤AddAll
		fishList.addAll(birdList);

		// ⑥出力
		System.out.println(fishList.toString());
	}

```
　↑
ひとつ前のソースの⑤AddAllの直前に、fishList.clear();をすると、
fishListの値が削除されるため、出力結果は [すずめ, カラス] となる。
【初心者向け】非同期処理とは何？

## 非同期処理とは同期処理と異なる処理

### 同期処理とは
同期処理の場合、基本的にプログラムはコードを
記述した順に上から順に実行されるため
例えばWEBページで新しい情報が欲しい場合
一度ページを丸ごと更新する必要があります。

### 非同期処理とは
他のプログラムとは異なり、ページを丸ごと更新せず
単体で動かせる処理を指します。

## 非同期処理は具体的にどんなもの？

例えばGoogleマップの場合、地図をスクロールする場合
ページを丸ごと更新せずとも
マウス操作で上や下、左右自在に動かせますが
同期処理で作られている場合、スクロールするにも
いちいちページを更新しなくてはなりません
RDS MySQL Workbench による import/export

# はじめに

実際には、RDS のバックアップと復元機能を使うが、RDS MySQL Workbench による import/exportは参考までに残す。

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

# RDS の設定変更

RDS の　DBパラメーターグループ の `log_bin_trust_function_creators` を`1`に設定し再起動。

# Import

Data Import/Restore > Import from Disk > Import from Self-Contained File でインポートするファイルを選択　> Default Target Schema で　DB を選択もしくは新しく DB を作成 > Start Import を選択。

![スクリーンショット 2022-10-21 19.26.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/708ca169-01a6-de63-5f74-9db12a853a2c.png)

# Export

Data Export > Tables to Export でエクスポートしたい DB と　テーブルを指定 > Export to Self-Contained File でエクスポート先を指定 > Start Export を選択。

![スクリーンショット 2022-10-21 19.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4f813f28-c666-9f81-389c-de0cbee0a3df.png)

MySQLWorkbench.app/ 8.0.12 ですが、ダンプする MySQL サーバーのバージョンは 5.7.39。
mysqldump のバージョンはサーバーと同じではないため、一部の機能は正しくバックアップされない場合があります。
と警告が出るが、 Contine Anyway をクリック。

![スクリーンショット 2022-10-21 19.41.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/cfc39d77-94e2-9abc-d538-c8a1d2270f2b.png)
AWS EC2 Route53 Apacheで静的テストページアップロードまでまとめ2022 (How To Host a Static Website in EC2 instance)

###     おそらくすぐに内容変わりますが(2022年10月時点)。
###     意外と重要：Login AWS, Confirm region.

###     ①Route53:Get original domain(ほかのドメインサーバーでも多分可)

###     ②EC2:Start-up Instance(出来たら起動の都度キーペア作成する方がよさげ)

###     ③When status is display "pass" while Instance running, you can go next.

###     ④EC2:Click Elastic IP from menu. Do "Assign" and then "Associate".

###     ⑤Route53: Making A record in Hostzone.

(ここでNuxt.jsなど動的サイト運用時はレコードタイプをCNAMEにする？) 

###     ⑦Login into cloud server using TeraTerm. Install "Apache" on your amazon Linux2.

簡易ページ作ってipアドレスでスマホからアクセステスト。

###     ⑧KeyManamgementSeivice(KSK作成：Route53からの有料の「カスタマ管理CMKの作成」が安全)

###     ⑨Route53>ドメイン>登録済みドメイン(DNSsecのステータス:キーの管理>パブリックキー登録)

# 完了
######     ここで静的サイトは独自ドメインから表示OK(ただし警告出ている）
###### なのでほぼほぼEC2と Route53だけで静的サイトは表示できます。
######  自分はここからどうやってNuxt.jsを表示させるのか...。

### (①～⑨でドメインでのアクセスは可能だが警告出るので今後SSLを)
     例「このサイトへの接続は安全ではありません」「このサイトには証明書がありません」
###   SSL対応にするときはおそらく以下を行うと思われる。
#######     Certificate Managerでの証明書リクエスト。その他設定。
Git bash開いた瞬間にssh接続された状態にしてみる


## 今回やりたいこと
いつもssh接続するとき、linuxコマンド使えるGit Bashやvscodeの拡張機能を使ってssh接続してていたが、
GitBashに関してはsshコマンド入力しなきゃいけないし、vscodeに関しては左下にある拡張機能のボタンから何回かボタン押さなきゃいけない。

これが面倒なので、Gitbash開いた瞬間にssh接続された状態にしてみたかった

※仕事ではこれはやらない。個人の趣味で使ってるパソコンで行いましょう。


## まず、設定ファイルをいじる
Gitのインストール先は、自分は「C:\Program Files\Git\etc」だったので、ここを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/a7e5c39b-2130-f06b-979d-3eb3868f05c8.png)


●次に、この中の「bash.bashrc」を管理者権限で開くと、63行目ぐらいまでいろいろ書かれている。
Gitbashを開いた際に呼ばれるコマンド一覧なのだろう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/bf70d242-47c9-f0cf-4073-85f2a6cfcd0d.png)

●上記の「bash.bashrc」の最後に、sshコマンドの追記する。

●これで、GitBashを開くと、いきなりssh接続された状態で開くことができた。
PHP laravel 任意のルーティングパラメーターを設定する

# 概要

- laravelで任意のルーティングパラメーターを設定する方法をまとめる。

# 方法

- 絞り込みなどでURLに任意のパラメーターを含めたいとき下記ようにルーティングを記載する（yearとmonthは合ってもなくても当該のページが表示できる。）

    ```web.php
    // シングルアクションコントローラーのコントローラー指定方法なので通常とは異なる
    Route::get('/Foo/Bar/{year?}/{month?}', HogeHogeController::class)
    ```

- 上記のようにしておけば`/Foo/Ber`にアクセスしても`/Foo/Bar/2022/10`にアクセスしても同じページが開く。
rex0220 計算式プラグイン テーブル項目の値を集計・取得

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、テーブルの集計や特定行の値を取得を行ってみます。
SUMIF, FIRSTIF 関数で簡単に集計できます。

※集計結果をテーブルに設定する場合は、[rex0220 計算式プラグイン テーブル集計](https://qiita.com/rex0220/items/25507c54f893d5ba74c5)

# 概要
テーブルのドロップダウン毎に集計

![2022-10-21_18h57_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3b61be0a-4329-8651-2cab-11730d7a6d41.png)

# 計算式プラグインの設定

SUMIF, FIRSTIF 等の集計関数で計算できます。

- 合計
    - SUM(数値T)
- 合計SAMPLE1
    - SUMIF(ドロップダウン="sample1",数値T)
- 合計SAMPLE2
    - SUMIF(ドロップダウン="sample2",数値T)
- 最初の有効な値
    - FIRST(数値T)
- 最初のSAMPL1
    - FIRSTIF(ドロップダウン="sample1",数値T)
- 最初のSAMPL2
    - FIRSTIF(ドロップダウン="sample2",数値T)
- 最後の有効な値
    - LAST(数値T)
- 最後のSAMPL1
    - LASTIF(ドロップダウン="sample1",数値T)
- 最後のSAMPL2
    - LASTIF(ドロップダウン="sample2",数値T)

![2022-10-21_19h01_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3277d796-0b59-41a0-29ca-58db294affe8.png)
「Apach POI」を使ってJavaでExcelファイルを操作してみた

##
JavaからExcelファイルを操作できるようにするライブラリ「Apach POI」を使ってみました。
プログラミングを初めるときにどの言語でも最初に行う「Hello World」みたいに、
動きましたー！すごいー！、、、のような内容です。

ちなみに、Excelが無い環境でも動きます。ちょっと感動しました。
（Excelが入っていないプライベートPCでもxlsxファイルを出力できました）

## 開発環境
- Eclipse：202209
- Java：SE11
- Apach POI：5.2.3

## 環境構築
まずは、主役となる「Apach POI」を以下からダウンロード
https://poi.apache.org/
ダウンロード→「Binary Distribution」→「poi-bin-5.2.3-20220909.zip」→「HTTP」

Eclipse上の操作
- 新規「Javaプロジェクト」
- Java11
- 「ライブラリ」→「クラスパス」→「外部JARの追加」
- 解凍したフォルダの中のjarファイルをすべて追加する

今回はシンプルに何も考えず環境構築をしました。

## 実践

以下ソースです。

```Java
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class Main{
    public static void main(String[] args){
        try{
            //まっさらなworkbookを作る
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            XSSFRow row = sheet.createRow(0);
            XSSFCell cell = row.createCell(0);
            cell.setCellValue("セルに値を書き込めるよ");
            String path = "C:/Users/XXX/Desktop/";
            String fileName = "complete.xlsx";
            FileOutputStream output = new FileOutputStream(path + fileName);
            workbook.write(output);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}
```

ファイルを開いた結果が以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779836/96a9115e-989c-f390-5bb8-700ee09a6008.png)

指定したパス、指定したファイル名で出力されていることを確認出来ました。
下記のコードを追加すれば、上の画像のようにシート名を設定できます。
そして、getSheetで対象のシートを操作出来ます。
```Java
workbook.setSheetName(0, "sample");
sheet = workbook.getSheet("sample");
```

## 終わりに

JavaからExcelファイルを出力できるだけでちょっと感動しました。
読み込むことも可能なので、簡易的なDBのように使うことも出来そうです。
次回以降試してみようと思います。
[Chart.js]折れ線グラフの縦軸を反対にする方法

# はじめに
今回ポートフォリを制作するにあたってChart.jsを使用し折れ線グラフを表示させました。
その中で折れ線グラフの縦軸を反対にしました。
あまり需要がないのか、実際に記事にされているものが無かったため公式を調べ実装を行いました。
この知識が誰かの役に立てば幸いと思い記事を書かせてもらいます。

# 今回記述するグラフについて
### 修正前
```js:line_graph.html.erb
document.addEventListener('turbolinks:load', function() {
  var ctx = document.getElementById('line_graph');
  var myChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: ['1回前', '2回前', '3回前', '4回前', '5回前', '6回前', '7回前', '8回前', '9回前', '10回前'],
        datasets: [{
          label: '順位',
          data: <%= user.limit(10).pluck(:rank) %>,
          borderColor: 'rgba(0, 128, 0, 1)',
          lineTension: 0,
          fill: false,
          borderWidth: 3
        }]
      },
      options: {
        // animation: false// アニメーションOFF
        scales: {
          yAxes: {
              ticks: {
                  stepSize: 1,
              }
          }
        }
      }
  });
});
```
少しグラフについて説明させてください。
直近１０回でのゲームでの順位を表示するグラフです。
なので１０回戦まで表示出来るようにしてあります。
options内のanimationをコメントアウトしてあります。ここのコメントを外すことで、アニメーションをカットしてロードを少し早く出来ます。
このコードで記述されるグラフがこちらです。
![スクリーンショット 2022-10-21 18.35.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920144/d6041326-cb77-2336-9514-45ba8b961dc5.png)
Y軸に順位が表示されるのですが、4位が上になってるのが気持ち悪いな〜っといった感じです。

### 修正
optionsのscales内にreverse: trueを記述してあげます。
```js:line_graph.html.erb
document.addEventListener('turbolinks:load', function() {
  var ctx = document.getElementById('line_graph');
  var myChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: ['1回前', '2回前', '3回前', '4回前', '5回前', '6回前', '7回前', '8回前', '9回前', '10回前'],
        datasets: [{
          label: '順位',
          data: <%= user.limit(10).pluck(:rank) %>,
          borderColor: 'rgba(0, 128, 0, 1)',
          lineTension: 0,
          fill: false,
          borderWidth: 3
        }]
      },
      options: {
        // animation: false// アニメーションOFF
        scales: {
          yAxes: {
              ticks: {
                  stepSize: 1,
              }
              reverse: true
          }
        }
      }
  });
});
```
このコードで表示されるグラフがこちらです。
![スクリーンショット 2022-10-21 18.35.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920144/5f9ad5a6-99db-6c0f-7028-197fcb88a5d0.png)
Y軸が反対で表示されるようになりました。
以上です。
もしこの記事が誰かの役に立てたなら幸いです。
Phoenix 1.7のverified_routeを使ってみた

# はじめに
本記事は [Qiita AdventCalendar2022 Elixir](https://qiita.com/advent-calendar/2022/elixir) vol7 3日目の記事です
Phoenix1.7で導入されるverified_routeを紹介します
# セットアップ
Phoenixのバージョンを1.7にあげていきます

実行時のバージョンは以下で行いました
erlang 25.0.4
elixir 1.14.1-otp-25

こちらに沿って行います
https://github.com/phoenixframework/phoenix/tree/master/installer

```
git clone https://github.com/phoenixframework/phoenix.git
cd phoenix/installer
mix archive.uninstall phx_new
MIX_ENV=prod mix do archive.build, archive.install
```

これで　phx_newが　1.7になったのでプロジェクトを作成していきます
```
mix phx.new blog
```
これで準備が整いました


※ 10/21日現在 phoenixの masterブランチは絶賛開発中のためちょくちょくライブラリの依存関係が壊れるのでご注意ください　

# verified_routeの概要
verified_routeですがパスを記述する際には

```elixir
Routes.blog_index_path(BlogWeb.Endpoint, :index)
```

と長々と書かないといけなかったものを

```elixir
~p"/blogs"
```
と新しく導入された`~p`を使うことでとてもスマートにパスを書くことができます

# 使い方
いくつか使い方を紹介します

routerに以下のパスが定義されているとして
```elixir
live "/posts", PostLive.Index, :index
live "/posts/new", PostLive.Index, :new
live "/posts/:id/edit", PostLive.Index, :edit

live "/posts/:id", PostLive.Show, :show
live "/posts/:id/show/edit", PostLive.Show, :edit
```
それぞれ以下のように書きます
```elixir
~p"/posts"
~p"/posts/new"
~p"/posts/#{@post}/edit"

~p"/posts/#{@post}"
~p"/posts/#{@post}/show/edit"
```

ネストした場合もシンプルにかけます
```elixir
live "posts/:id/comments/:comment_id", CommentShowLive,:show
-> ~p"/posts/#{@post}/comments/#{comment}"
```

長くなりがちな静的パスも以下のようにかけます

```elixir
# before
Routes.static_path(BlogWeb.Endpoit, "phoenix.png")
# after
~p"/images/phoenix.png"
```

今まで冗長的だったパスの記述がとても楽になりました！

# 仕組み
コードをしっかりと読み込んでいないのでざっくりとですが

blog_web.exのverified_routeの設定で以下のようなコードがあります

```blog_web.ex
  def verified_routes do
    quote do
      use Phoenix.VerifiedRoutes,
        endpoint: BlogWeb.Endpoint,
        router: BlogWeb.Router,
        statics: BlogWeb.static_paths()
    end
  end
```

https://github.com/phoenixframework/phoenix/blob/0cec3cd6cb554f82cebba5794300a54c7e850daa/lib/phoenix/verified_routes.ex#L196-L233
ここらへんに

```elixir
 defp inject_path(
         {%__MODULE__{} = route, static?, _endpoint_ctx, _route_ast, path_ast, static_ast},
         env
       ) do
    if static? do
      static_ast
    else
      Module.put_attribute(env.module, :phoenix_verified_routes, route)
      path_ast
    end
  end
```

staticのパスにふくまれているのならstatic、そうでないならRoutesで探すぽいみたいな処理がかかれています

なので、static_pathとRouteのすべてを精査してマッチするものがあればそのパスに変換する処理を行うのが sigil_pのようですね

# 最後に
Phoenix1.7ですがverified_routeの他に
phx.gen.authがLiveViewになったり
デフォルトcssがtailwindになり、デザインが一新され
Phoenix.ComponentがReact + Typescriptのようにインターフェース情報や型情報をつけれるようになったり
.form以外のデフォルトコンポーネントが多く入っていたり
と大きな変更がいくつか入っているようです

追従や変更は大変ですが素晴らしい機能が目白押しで正式リリースが待ち遠しいです
本記事は以上になりますありがとうございました

# 参考サイト
https://www.erlang-solutions.com/blog/what-you-need-to-know-phoenix-framework-1-7/
https://www.youtube.com/watch?v=9-rqBLjr5Eo
https://github.com/phoenixframework/phoenix/blob/master/CHANGELOG.md
【Git】ブランチ運用についてのテンプレメモ


vagran環境で構築
ブランチ運用のテンプレメモです。

| 環境名(日本語名) | 環境名(英語名) | 対応するブランチ |
|:-----------|------------:|:------------:|
| 本番環境   | production | master |
| 開発環境   | staging    | develo |

## 1．複数の改修内容(新機能)をまとめて開発環境にデプロイしたい場合のブランチ運用方法(releaseブランチを作成する)

###### 1-1．developブランチからreleaseブランチを作成する

```
1. developブランチに切り替えを行う
 git checkout develop

2. developブランチを最新にする
 git remote update
 git pull

3. developブランチからreleaseブランチを作成する
 git checkout -b release/yyyymm
  (例:2022年2月にリリースを行う場合、ブランチ名はrelease/202202とする)

4. 3で作成したブランチをリモートに登録
 git push -u origin (3)で作成したブランチ名

5. 4で作成したブランチがリモートに登録されたか確認する
 Github画面上で確認
```

###### 1-2．releaseブランチからfeatureブランチを作成する
```
1. releaseブランチに切り替えを行う
 git checkout release

2. releaseブランチを最新にする
 git remote update
 git pull

3. releaseブランチからfeatureブランチを作成する
 git checkout -b feature/[issue番号]_実装内容(英語)
```

###### 1-3．ローカル環境にて1-2の(3)で作成したfeatureブランチで実装を行う

###### 1-4．実装完了後、featureブランチをreleaseブランチにマージするプルリクエストの作成を行う

```
1. 実装内容をプッシュする
 git add .
 git commit -m "コミット内容"
 git push origin 1-2の(3)で作成したfeatureブランチ

2. プッシュ後、コマンドラインにプルリクエスト作成用のURLが表示されるので、アクセスしてプルリクエストの作成を行う
2. 
3. マージ先がreleaseブランチになっているか確認を行う
```
###### 1-5．ソースレビュー完了後、マージを行う

###### 1-6．releaseブランチをdevelopブランチにマージするプルリクエストの作成を行う
1. プルリクエストのページで「New pull request」ボタンを押下してプルリクエスト新規作成画面に遷移する

###### 1-7．1-6で作成したプルリクエストの画面で「Merge pull request」ボタンを押下する

###### 1-8．「Confirm merge」ボタンを押下してマージを行う

###### 1-9．CodePipelineによって自動的に開発環境へのデプロイが開始される
　　

## 2．軽微な修正を随時開発環境にデプロイしたい場合のブランチ運用方法(releaseブランチを作成しない)

###### 2-1．developブランチからfeatureブランチを作成する

```
1. developブランチに切り替えを行う
 git checkout develop

2. developブランチを最新にする
 git remote update
 git pull

3. releaseブランチからfeatureブランチを作成する
 git checkout -b feature/[issue番号]_実装内容(英語)
```

###### 2-2．ローカル環境にて2-1の3で作成したfeatureブランチで実装を行う

###### 2-3．実装完了後、featureブランチをdevelopブランチにマージするプルリクエストの作成を行う

```
1. 実装内容をプッシュする
 git add .
 git commit -m "コミット内容"
 git push origin 1-2の(3)で作成したfeatureブランチ

2. プッシュ後、コマンドラインにプルリクエスト作成用のURLが表示されるので、アクセスしてプルリクエストの作成を行う

3. マージ先がdevelopブランチになっているか確認を行う
```

###### 2-4．ソースレビュー完了後、マージを行う

###### 2-5．CodePipelineによって自動的に開発環境へのデプロイが開始される


## 3．本番環境へのデプロイを行う場合のブランチ運用方法

###### 3-1．developブランチをmasterブランチにマージするプルリクエストの作成を行う
1. プルリクエストのページで「New pull request」ボタンを押下してプルリクエスト新規作成画面に遷移する

###### 3-2．3-1で作成したプルリクエストの画面で「Merge pull request」ボタンを押下する

###### 3-3．「Confirm merge」ボタンを押下してマージを行う

###### 3-4．CodePipelineによって自動的に本番環境へのデプロイが開始される
Pythonで複数のサブネットをスーパーネット化して集約する

# はじめに
　ルータやファイアウォールの設定の際に複数のサブネットを集約して、最小限のネットワークアドレスで表現したいことがあります。そんな時に必要となるスーパーネット化とかCIDR結合などと呼ばれる操作をPythonで簡単に行う方法があるので紹介します。

# スーパーネット化


　[ネットワークスペシャリスト試験](https://www.ipa.go.jp/shiken/kubun/nw.html)に出題された以下の問を題材にPythonを使ってスーパーネット化してみる。

>問14　サブネットマスクが 255.255.255.0 である四つのネットワーク 192.168.32.0，192.168.33.0，192.168.34.0，192.168.35.0を，CIDRを使ってスーパーネット化したとき，ネットワーク番号とサブネットマスクの適切な組合せはどれか。
>
>||ネットワーク番号|サブネットマスク|
>|:-: |:----------:|:-----------:|
>|ア|192.168.32.0|255.255.248.0|
>|イ|192.168.32.0|255.255.252.0|
>|ウ|192.168.35.0|255.255.248.0|
>|エ|192.168.35.0|255.255.252.0|

出典:[平成27年度 ネットワークスペシャリスト試験 午前Ⅱ 問14](https://www.ipa.go.jp/shiken/mondai-kaiotu/gmcbt8000000gxj0-att/2015h27a_nw_am2_qs.pdf#page=7)




・準備

　必要なライブラリのインストール。
```
pip install netaddr
```

・スーパネット化
```python:merge.py
#便利なライブラリのnetaddrを読み込む
from netaddr import IPNetwork, cidr_merge

'''
問に記載されているネットワークアドレスをIPnetworkクラスに渡してsubnetsリストに格納。
(サブネット255.255.255.0はCIDR表記では/24。オクテット形式でも渡せる)
'''
subnets = [IPNetwork('192.168.32.0/24'), 
           IPNetwork('192.168.33.0/24'), 
           IPNetwork('192.168.34.0/24'), 
           IPNetwork('192.168.35.0/24')]

#たったこの１行だけでスーパーネット化できる!
merged_subnets = netaddr.cidr_merge(subnets)
print(merged_subnets)
```

・結果
　この様にサブネットが<code>192.168.32.0/22</code>に集約されてうまくスーパーネット化ができたことがわかる。

```:結果
[IPNetwork('192.168.32.0/22')]
```

　なお問14の解答群のサブネットマスクはオクテット表記となっているので、以下の様にCIDR表記のサブネットを求めると、

```python
print(merged_subnets[0].netmask)
```

```:結果
255.255.252.0
```
となるため、答えはイ(<code>192.168.32.0/255.255.252.0</code>)であることがわかる。

2022/10/21追記:
@shiracamusさんのコメントにある通り、[ipaddress](https://docs.python.org/ja/3/library/ipaddress.html)ライブラリでも同じことが出来ました。このライブラリは[標準ライブラリ](https://docs.python.org/ja/3/library/index.html)に含まれていて、インストール不要なのでこちら方が使いやすいですね。

```python:merge2.py
#@shiracamusさんのコメントから引用
from ipaddress import IPv4Network, collapse_addresses

subnets = [IPv4Network('192.168.32.0/24'),
           IPv4Network('192.168.33.0/24'),
           IPv4Network('192.168.34.0/24'),
           IPv4Network('192.168.35.0/24')]

merged_subnets = [*collapse_addresses(subnets)]
print(merged_subnets)
```

```:結果
[IPv4Network('192.168.32.0/22')]
```

# さいごに
　この[netaddr](https://netaddr.readthedocs.io/en/latest/index.html)というライブラリはIPアドレスやネットワークアドレスに対する操作をするのにすごく便利なライブラリで、スーパーネット化だけでなく、さまざまな操作ができます。これまでにいくつか記事を書きましたので、そちらもご参照ください。

https://qiita.com/aikamanami11/items/d88183c7ced2df071ea0

https://qiita.com/aikamanami11/items/4e8348d7369d9dadb1c4

以上

参考サイト:

https://netaddr.readthedocs.io/en/latest/index.html
[VSCode]Preview Mermaidで、仕様を可視化して伝える

# 概要
最近自分が、他人に伝える際に心がけていることの一つで、仕様を可視化して伝える、というものがあります。
今やっている案件で、今回の拡張機能「Preview Mermaid」を活用できたので、ご紹介させていただきます

---

# [拡張機能]Preview Mermaid

Command + Shift + P --> "Preview Mermaid" --> mermaid記法で
書いている箇所をクリックでプレビュー表示する、という拡張機能です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587970/7abd60a5-7aa5-ee2d-34f0-25510f6f7567.png)

---

# Preview Mermaidって？

その名の通り「Mermaid記法に則って記載されたものをPreviewしてくれる」もの。
Mermaid記法とは、Merkdowonっぽい、PlantUMLっぽい書き方で、UMLが記述することのできる記法のことです

[参考]https://mermaid-js.github.io/mermaid/#/

---

# 例
[シナリオ]
共通部品を作って、一緒に案件参加されている方に、使い方(仕様)を伝える

---

# 例えば、、、（極端な例）

「A」っていうクラス作りました。
呼び出し元でnewしてもらったら、XXXと、YYYYと、ZZZZを引数にしてもらって、
AAA()メソッド呼んだら、「B」のBBB（）メソッドが呼ばれるので、
そのレスポンスデータの”CCC”というキーでを使ってデータとって、
呼び出し元画面に、「A」クラスのZZZ()メソッドで値埋め込みできます
で、そこから、、、、、、、。

詳しくは、ソーストレースしてください、じゃお願いします！

---

# ...？

---

# 1mmもわからんわ、、、

---

# VSCode"Preview Mermaid"を使うと。。。？(Mermaid記法例)

以下は、シーケンス図をmermaid記法で書いた記載例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587970/462c84d5-7a4a-378d-22fa-183ea3f22447.png)


---

# VSCode"Preview Mermaid"を使うと。。。？(プレビュー)

プレビューすると、こんな感じ
※　Qiitaもプレビューできるんですね（この記事書いてて気づいた）
※　そもそもシーケンス図の書き方なってないわ〜はご容赦。。。
```mermaid
sequenceDiagram
    participant 0125 as XXXX_XXX/index.pug
    participant 0125js as XXXX_XXX/index.js
    participant widget as ホーム画面ウィジェット群
    participant homeWidget as HomeWidget.js
    participant dataEmbedder as dataEmbedder.js

    0125-->>0125js: window.HOGEHOGE.init()
    0125js-->>widget: draw(画面.APIパラメータの情報)
    widget-->>homeWidget: render(callback処理（！）)
    homeWidget-->>homeWidget: APIリクエスト
    homeWidget-->>homeWidget: 共通エラーチェック処理
    homeWidget-->>homeWidget: （！）個別ウィジェットのエラー表示処理
    homeWidget-->>dataEmbedder: （！）callback処理
    dataEmbedder-->>dataEmbedder: （！）DOM埋め込み
    dataEmbedder-->>dataEmbedder: （！）エラー表示処理
    dataEmbedder-->>homeWidget: 
    homeWidget-->>widget: ホーム画面描画: (あるいは、エラー表示)
    widget-->>0125js: _
    0125js-->>0125:_
```

---

# いかがでしょうか

極端例、や、ソース見るだけ、より
シーケンス図が理解の一助にはなっているのかな、と思います

---

#  まとめ

この手のツールってたくさんありますよね。
Mermaid記法より、PlantUMLの方が有名（だと思ってる）

ただ前職で、GitLab使ってて、GitLabはMermaid記法のプレビューに対応しているけど、PlantUMLはプラグイン入れないとダメだったので、
Mermaid記法でいいか、で採用した経緯があります

学習コストも特に高くないので、トライアンドエラーしながらで、１０分、15分で大体書けるようになるのでよかったらぜひ！

---

# Thank you!
OAOO原則 - Good Concepts in Programming -

# 概要
プログラミングの良い概念を理解するとプログラマーレベルが上がると考えています。
良い概念は特定のプログラミング言語に縛られないので、様々なプログラミング言語で役に立ちます。
今回紹介する良い概念は「OAOO原則」です。

# OAOO原則とは
OAOOは「Once And Only Once」の略で、要約すると「同じコードを何度も書くな」となります。
同じようなコードを2か所以上（重複したコード）で見られたら、1か所にまとめることを考えると良いプログラミングになります。
OAOO原則に従うとコードに変更が必要になった場合、1か所だけの変更で済みます。
「重複したコード」はプログラミングにおいて最も起こりやすい（コードのコピペなど）ですが、最もやっていはいけないことでもあります。

DRY原則（Don't Repeat Yourself）がありますが、DRY原則はシステム全体として使われることが多いです。
本記事はプログラミングにスコープを当てているのでOAOO原則として紹介します。

# サンプルコード
重複したコードと発生例とその除去方法をサンプルコードで見ていきます。

## 1.マジックナンバーを定数定義する
マジックナンバーとはコード上に書かれた「何らかの意味を持つ具体的な数値」です。
マジックナンバーは以下の問題点があります。
・数値の意味がわかりにくい（同じ数値で別の意味を持つ場合、判断が難しい）
・コードに変更が必要になった場合、複数箇所の変更が必要

マジックナンバーを使用したコートは以下になります。
```ampm_not_oaoo.js
// 1:午前, 2:午後
if (ampm === 1) {
    // 午前の処理
} else if (ampm === 2) {
    // 午後の処理
} else {
    // その他の処理
}

// ...
if (ampm === 1) {
    // 午前だけの特別な処理
}

// 午前とは違う意味の「1」です
count += 1;
```
マジックナンバーを定数定義したコードは以下になります。
```ampm_oaoo.js
// 1:午前
const AM = 1;
// 2:午後
const PM = 2;
// 1:増加数
const Increment = 1;

if (ampm === AM) {
    // 午前の処理
} else if (ampm === PM) {
    // 午後の処理
} else {
    // その他の処理
}

// ...
if (ampm === AM) {
    // 午前だけの特別な処理
}

// 午前と違うことを判断できる
count += Increment;
```
マジックナンバーを定数定義することで数値の意味を判断できるようになりました。

## 2.同じ処理を関数定義する
同じ処理をしているコード群がある場合、そのコード群を関数として定義します。
関数定義をしたことのないプログラマーはいないと思いますが、その利点についてあらためて確認してみましょう。

関数定義されていないコードは以下になります。
```function_not_oaoo.js
// pre => main => postの順番で実行（1回目）
preProcessing();
mainProcessing();
postProcessing();

// ...

// pre => main => postの順番で実行（2回目）
preProcessing();
mainProcessing();
postProcessing();
```

関数定義したコードは以下になります。
```function_oaoo.js
// pre => main => postの順番で実行
function doProcessing() {
    preProcessing();
    mainProcessing();
    postProcessing();
}

// 処理実行（1回目）
doProcessing();

// ...

// 処理実行（2回目）
doProcessing();
```

同じ処理を関数定義することで以下の利点があります。
・関数定義した関数を使用することで何度も同じ処理を実行できる
・コードに変更が必要になった場合、関数内の処理を変更すればよい

# まとめ
今回はOAOO原則を紹介しました。
OAOO原則に従い「重複したコード」がなくなると以下の利点があります。
・コードに変更が必要になった場合、変更箇所が1か所になる
・コードの可読性が良くなる

プログラミングにおける様々な概念やテクニックは
「OAOO原則を達成するために存在する」と言っても過言ではないくらい重要な概念と考えています。
OAOO原則を理解してプログラマーレベルが上がったと感じていただければ幸いです。

最後まで読んでいただきありがとうございます。
[Jetpack Compose] xmlでtextSizeがdp指定されている部分をComposeで書き直す [Android]

## 内容
- xmlでtextSizeがdp指定になっているところをCompose化する時にどうやって書くか。
- Composeで、システムのフォントサイズに関係なく（依存せずに）、テキストサイズが一貫するように「.dp」を使用する方法

## xmlの場合

```
<TextView
    ...
    android:textSize="16dp"
    tools:ignore="SpUsage" />
```

## Compose化する場合
```
...
Text(
     ...
     fontSize = dpToSp(dp = 16.dp)
     )

@Composable
fun dpToSp(dp: Dp) = with(LocalDensity.current) { dp.toSp() }
 ```

## 見たサイト
- https://y-anz-m.blogspot.com/2021/06/jetpack-compose-text-dp.html
- https://stackoverflow.com/questions/67918698/why-is-there-only-sp-in-fontsize-of-text-composable-and-not-dp-in-jetp
cloudflaredでトンネルを作る手順

cloudflaredでプライベートなサーバーをWeb公開することができます。

テンポラリのURLを生成する用途で紹介されることも多いですが、固定のドメインも作ることができます。

以下手順

```
cloudflared tunnel login
```
- これで~./cloudflared/cert.pemが作られる
- ログインする際にどのドメインでURLをつくるかを選ぶ

```
cloudflared tunnel create [トンネル名]
```
このタイミングで~./.cloudflared/[uuid].json が作られる
トンネルを作り直す時には.jsonを削除するのではなく、後述のトンネル削除のコマンドを使う。

```
cloudflared tunnel route dns [トンネル名] [サブドメイン]
```
このコマンドで、サブドメインが新規に作られ、トンネルに接続される

```
cloudflared tunnel run --url localhost:8080 [トンネル名]
```

このコマンドで、ローカルの8080ポートが外部に公開される

## ここからが番外編

- やりなおしたい時がちょっと大変
- トンネルができたかどうかが不安なときには、.jsonファイルが作られていることと、`cloudflared tunnel list` でトンネルが確かに作られてることを確認
- その上で`cloudflared tunnel delete [トンネル名]` で削除してからcreateをもう一回やりなおす必要がある
- さらにトンネルを作り直すと、サブドメインとの関連付けも再度必要になるため`cloudflared tunnel route dns` もやり直す必要があるが、残念ながらtunnel route dnsの削除や更新をするコマンドがないため、Webコンソールからサブドメインを一度削除する必要がある
Watson DiscoveryでのBoxクロール - CP4D版とIBM Cloud版との違い

Watson Discoveryを使用する場合、IBM Cloud Pak for Data上で稼働するサービスとしてインストールする方法(以下、CP4D版)と、IBM Cloud上のSaaSとして利用する方法(以下、IBM Cloud版)があります。

普段、**CP4D版**でBoxクロールを使用していますが、**IBM Cloud版**を使用したところ、意外と違いがあることに気づきましたので、記録しておくことにします。2022年10月現在の情報です。

## 主な違い

構成関連：
- Boxアプリの作成方法
    - **IBM Cloud版**では、パスフレーズなしの秘密鍵は使用できないので要注意です。
- WD collectionの設定方法

挙動：
- スケジュール・クロール(更新のクロール)の設定、動き
- サポートされる機能
    - `文書レベルのセキュリティー`は**CP4D版**だけでサポートされます。



## Boxクロールの構成方法

**CP4D版**
[CP4D版 Watson DiscoveryのBoxクロール方法](https://qiita.com/mizutan/items/ffaa2f5cad97a590c7f4)
＊下のIBM Cloud版の記事を参考に書きました

**IBM Cloud版**
[Watson DiscoveryのBOXクロール方法](https://qiita.com/nsatoh/items/d3d3cc29b4621ba26642)


## スケジュール・クロール

コレクションを作成すると、最初のクロールが即時に開始します。クロール・スケジュールに選択する頻度によって、次のクロールがいつ開始されるかを指定できます。

### スケジュール・クロールでのクロール・タイプの指定

**CP4D版**では、`More scheduling setting`から、スケジュール・クロールで実行されるクロールのタイプを指定できます。次の３つから選択できます。


- `Full crawling`: 外部データ・ソースを再クロールして、コレクション内の文書を更新します。
- `Crawling updates (look for new, modified, and deleted content)`: 更新のクロール (新規、変更、および削除されたコンテンツの検索)。最後のクロール以降に外部データ・ソースのデータが追加、変更、または削除された場合にのみ、コレクションを更新します。
- `Crawling new and modified content`: 新規コンテンツおよび変更されたコンテンツのクロール。最後のクロール以降に追加または変更された外部データ・ソース内のデータの場合にのみ、コレクションを更新します。

これに対して、**IBM Cloud版**では、スケジュール・クロールのクロールタイプを選択することはできません。一律で、次の挙動となります。

- 新規コンテンツおよび変更されたコンテンツのクロール
- データ・ソースで削除された文書はコレクションから削除されません


また、**IBM Cloud版**では、`アプリアクセスレベル`が`アプリ+ Enterpriseアクセス`となっているBoxアプリを使用している場合についてのみ、スケジュールされたクロールで文書の更新がサポートされます。（`アプリアクセス`のBoxアプリの場合は、スケジュールされたクロールで文書の更新がサポートされません。）

### スケジュール・クロールの頻度の指定について

**CP4D版**、**IBM Cloud版**とも次の頻度を選択できます。

- Hourly
- Daily
- Weekly
- Monthly

これに加えて、**CP4D版**では、`Custom intervals`という選択肢があり、Minutes/Hours/Daysを組み合わせた、より柔軟な頻度を指定できます。
![custom_intervals.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/e1dfadb5-9e65-c073-86ec-548318aec824.png)

また、**CP4D版**のBoxクロール（Webクロール以外のクローラー）に関しては、次のように特定の日時からスケジュール・クロールを実行するように指定することができます。
![enable_schedule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/fc08cc62-48ce-378a-6197-a23a06de302a.png)


### スケジュール・クロール その他の違い

少し選択の幅が狭い**IBM Cloud版**のスケジュール・クロールですが、**CP4D版**にはない機能があります。ToolingUIに、スケジュール・クロールの次回実行予定日時が表示されるのです。
![ToolingUI_SaaS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2164968/dcb11e94-3995-7871-92f8-6368e32d519f.png)

## 公式ドキュメント

構成について：

- IBM Cloud: [IBM Cloud データ・ソースの構成 > Box](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-connector-box-cloud)

- CP4D: [IBM Cloud Pak for Data データ・ソースの構成 > Box](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-connector-box-cp4d)


スケジュール・クロール(更新のクロール)について：

- [クロール・スケジュールのオプション](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-collections#crawlschedule)

- [クロールされる文書 - IBM Cloud版](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-connector-box-cloud#connector-box-cloud-objects)
Mr.モブの奮闘記 Twilio編（第１話）

## はじめに

みなさん始めまして。

Mr.モブと申します。

INNOOV株式会社という会社で、サポートエンジニアをやらせてもろてます。

以前は、不動産やったり光通信Groupで「ゾスッ」て挨拶したり営業やったりしてました。

現在は、Atlassian製品のテクニカルサポートをしたり、Twilioなどの他製品連携やアドオン開発等を含めた技術調査を行っています。

今後、Qiitaでは実際に顧客に導入した製品の紹介と、簡単なセットアップ手順について発信していきたいと思います。

## 新コールセンターシステム稼働開始まであと1か月⁉ Twilioとの出会い

ある日、顧客から新コールセンターの構築について相談がありました。

コールセンターを Jira Service Managementと接続したいとのこと。稼働開始は…１か月後⁉
（ちょw マジかよw　半端ねーなw）


ヒアリングを行うと以下のような要件が欲しいとのことでした。

通話記録をJiraチケットとして残したい

CRMとの連携（登録・参照）

オペレーターの稼働状況をグラフで可視化したい



かなりざっくりですが…

顧客のヒアリングを終えて情報整理後、Mr.モブは特に突出した技術もないのでまず頭によぎったのは



「無理だろ…間に合わねーよ…」



そこで、Mr.モブはチームリーダーに言いました。



Mr.モブ『リーダー。これ流石に1ヶ月じゃ無理っすよね？』

リーダー『一回行けるとこまでやってみて。Twilioっていうサービスを使うから！！』

Mr.モブ『おまw 』

リーダー『Just do it』



これがTwilioとの出会いです。



ひとまず上記の要件を基に何の製品がFitするのかリーダーと検討しました。

結論は以下の通りです。

通話記録をJiraチケットとして残したい ⇨ Twilio Flex + Jira Service Management

CRMとの連携（登録・参照） ⇨ Twilio Flex + HubSpot

オペレーターの稼働状況をグラフで可視化したい ⇨ Twilio Flex



Mr.モブ『3製品（Atlassian, Twilio, HubSpot）の連携。。終わった。。』

幸いにもリーダーはAtlassianエキスパート（認定資格を5個以上保有）していたため、Mr.モブがJira構成を１から考える必要はなく2人でデイスカッションして構成を決めることができたのが唯一の救い。





## Twilioって何？

Twilioとは音声、メッセージング・SMS、Video、emailなどの顧客との接点となるチャネルを包括的にAPIで提供する、顧客エンゲージメントプラットフォームです。



Mr.モブ『よくわからんなー。ひとまずどんな製品があるか見てみるか…』
![スクリーンショット 2022-07-28 16.46.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748892/5c5dc0d1-f4a7-c985-73ed-f19374eda6f4.png)







Mr.モブ『めちゃくちゃあるやん…何使えばええねん…』





## TwilioFlexって何？

クラウド型のコンタクトセンターソリューションです。Twilioは、テキストメッセージから電子メール、電話からビデオ、あるいはインテリジェントなチャットボットを介して、企業が顧客と対話することを、単一の強力なプラットフォームの中で可能にします。

柔軟にUIカスタマイズできるプラットフォームであり、自社のやり方に合わせて
コンタクトセンターを構築することができます。

様々な他の製品と連携させることも可能です。





Mr.モブ『今回の顧客の要望は「なるべく早くコールセンターを一新したい」だったからきっとTwilioFlexやな』
![スクリーンショット 2022-07-28 16.50.21 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2748892/eb632278-0cdd-492f-af04-a638a2e26d65.png)



https://www.twilio.com/ja/flex 



Mr.モブ『まさにこれやん。これで進めよ。早速アカウント登録や』



## Twilioアカウントの作成

Mr.モブはこちらから作成しました。

https://www.twilio.com/blog/how-to-create-twilio-account-jp 



次回以降はTwilioFlexに機能を追加していく記事を投稿しますのでTwilioアカウントの作成は済ませていただると次回がスムーズになるかなと思います。
さくらのVPSでメール送信できるようにする

さくらのVPSにはCentOS7を入れています。
送信メールサーバにはPostfixを使うといいらしいです。
あらかじめVPSのポートは開けておく。

----------------

CentOS7は、最初からPostfixがインストールされていらしいので確認して、
アップデートします。

```
yum list installed | grep postfix
yum -y update postfix
```

設定ファイルをコピーしてバックアップをとり、編集します。

```
cd /etc/postfix
cp -p main.cf main.cf_backup
vim main.cf
```

以下を適切な箇所を変更します。

```
省略
myhostname = mail.hogehoge.com 
省略
mydomain = hogehoge.com
省略
myorigin = $mydomain
省略
#inet_interfaces = 127.0.0.1 　//コメントアウト
inet_interfaces = all
省略
#mydestination = $myhostname, localhost.$mydomain, localhost 　//コメントアウト
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
省略
home_mailbox = Maildir/
省略
smtpd_banner = $myhostname ESMTP unknown
省略
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination
message_size_limit = 10485760
```


もう一つ設定ファイルをコピーしてバックアップをとり、編集します。

```
cp -p master.cf master.cf_backup
vim master.cf
```

適切な箇所を変更します。
```
省略
submission inet n       -       n       -       -       smtpd
省略
-o smtpd_sasl_auth_enable=yes
省略
```

cyrus-saslをインストールして、ユーザー名、パスワードを使用するSMTP認証ができるようにします。

```
yum -y install cyrus-sasl
```
自動起動設定
```
systemctl start saslauthd
systemctl enable saslauthd
```
さらに設定ファイルを変更します。
```
vim /etc/sasl2/smtpd.conf
```

```
pwcheck_method: auxprop
mech_list: cram-md5 plain login
```

再起動
```
systemctl restart postfix
```

テストメール送信
```
smtp-source -v -f "" -t "hoge@test.com" 127.0.0.1:25
```

メールが届いたらOK！



----

参考

https://qiita.com/hot_study_man/items/1af7ead2d84cf1a14812



https://www.sakura-vps.net/centos7-setting-list/postfix-settings-for-sakura-vps-centos7/



https://www.koikikukan.com/archives/2020/08/11-235555.php


https://qiita.com/SI-K_Maeda/items/f814add3208cc5327373