OmniAICreator/Qiita-1.07M huggingface dataset:
[Swift] 遷移先で変更した配列を遷移元に反映させ、Label等に表示させる方法

#はじめに
今回はNavigationControllerを用いて、画面遷移を行っています。そのため、遷移先から遷移元に戻る時に呼ばれるnavigationControllerのwillShowを使っています。また、collectionViewのCell内にLabelを置き、そこに配列（String)の値を表示させています。
#開発環境
```
macOS 11.0.1
Xcode version 12.2
Swift version 5.3.1
```
#コード
親画面にはString型で変数aを与え、初期値として5個の何の値も入っていない値を与えておきます。これを、collectionViewを用いて、Cell内に設置したLabelに先程の値を与えています。遷移先で変更された配列を遷移元に渡した時にプロパティ・オブザーバを設定してあげることで変更が起こった時の処理を書くことができるようになります。オブザーバは、プロパティ変更前に呼ばれる willSet と、変更後に呼ばれる didSet があります。今回は、変更後に呼ばれる**didset**を使います。

```swift:FirstViewContoroller
import UIKit

class ViewController:
                  //collectionViewを用いるため、下の2つを書いておく
UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
   //上と同じ理由で書いておく
    @IBOutlet weak var collectionView: UICollectionView!

    var a = ["","","","",""] {didSet{

       //didset内に書くことで、変数aに変更が起こった場合にreloadDataし、label内の表示         　　される値も変更することができる
        collectionView.reloadData()

        }
    
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()        
        
    } 
 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        return a.count
        
    }     
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for:indexPath)
        cell.backgroundColor = .lightGray
          
        //タグつけしたlabelに変数aの値を順に表示
        var aLabel = cell.contentView.viewWithTag(1) as! UILabel
        aLabel.text = a[indexPath.row]
              
        return cell
    }
    
//ほかには、何かしらの方法で遷移するコード書く

}

```
```swift:NextViewController
import UIKit


class NextViewController: UIViewController,UINavigationControllerDelegate {

    @IBOutlet weak var textFiled: UITextField! 
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    //ナビゲーションバーの戻るボタンを押した時に呼ばれる処理。下記を書くことで遷移先で遷移元の値　　　をいじることができる
     func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {

                                              //親画面のファイル名を記入
        if let controller = viewController as? FirstViewContoroller{

       //今回は変数aの1番目の値を変更する
       //遷移先画面のテキストフィールドに打たれた文字が遷移元の変数aの1番目の値を変更する
            controller.a[0] = textfiled.text!
        }
```
#まとめ
今回のコードで重要なことは、プロパティ・オブザーバの一つである**didset**です。この中で**collectionView.reloadData()**を書くことで、変数である配列に変更が起きた場合に、
**collectionView.reloadData()**が呼ばれ、cell内のlabelに表示される値を変更毎に更新することができます。
書評：｢Elmer｣ではじめる連成解析

##Elmerとは？
オープンソースのマルチフィジックス用シミュレーションソフトです。主な開発元はフィンランドの非営利の国営企業であるCSC ( IT Center for Science Ltd. ) です。詳しいことは本に丁寧に書いてあります。

##購入した理由

構造流体連成解析に興味がありました。これまで自分は、CAEにはSalomeMeca(Salome & Code_Aster)、CFDにはOpenFOAMを使ってきました。これまでの調査結果からSalomeMecaかOpenFOAMのどちらかを起点にして構造流体連成解析をするのが良いだろうと思っていました。詳しい感想を下に記載します。

1.
SalomeMecaにはCode_Saturneという単相流のCFDのモジュールが同梱されていて、どうやらSalomeMecaだけで構造流体連成解析ができそうです。しかし、情報が少なく特に日本語の情報が皆無のようです。

2.
OpenFOAMのフォーク版であるextend版には構造流体連成解析の機能があり、日本でもやっている人が少数ながらいらっしゃいます。しかし、extend版の設定ファイルの文法は本家版と異なり、自分はかなりの躊躇を感じました。OpenFOAMを殆ど独学で習得したのを再び繰り返すような予感がしたためです。

3.
DAKOTAという複数のソフトを連携させるオープンソースの最適化ソフトがあり、日本での使用例もあります。しかし、連携させるにはDAKOTA本体の設定方法だけでなく、連携相手のソフトを外部からコマンド制御する方法も覚えないとDAKOTA用のスクリプトが書けないため、自分はかなりの躊躇を感じました、というか、断念しました。数年前のオープンＣＡＥ学会主催による夏合宿の内容がDAKOTAのハンズオン講習会だったので参加したのですが、そのときの感想です。

4.
Elmerというマルチフィジックスのオープンソースのシミュレーションソフトがあり、CAEとして使っている人は日本にもいる。構造流体連成解析も簡単にできるらしいですが、情報が乏しい。



このような状況のときに、 <b>｢Elmer｣ではじめる連成解析</b>　という本が発売されました。
すぐに買って、今年の冬休み期間中に本の例題の計算をしました。

##本の感想
<b>この本に記載されている例題の順番の通りに作業をしていけば、構造流体連成解析ができてしまいました。<font color="Red">自分にとっては非常に有益な本です。</b></font>一通り操作してソフトのGUIが分かりやすいと思ったので、これからは頑張って膨大なページ数の英文マニュアルを読んでいきます。英文マニュアルのライセンスはCC-BY-NDですから和訳を勝手に公開してはいけません。(ライセンスがCC-BY-NCのマニュアルも一部にあります。)

この本の内容は、CAEだけの定常計算と非定計算ののち、CFDだけの定常計算と非定常計算、そのあとに構造流体連成解析の定常計算と非定常計算です。構造解析の固有値計算と熱流体解析の非定常計算の例題も含まれています。

#### 唯一の難点
CFDの非定常計算の例題は円柱カルマン渦のシミュレーションです。応用練習で主流速度を変えたり粘性係数を変えるのですが、実際の現象ではカルマン渦が発生するのにも関わらず、この本では「カルマン渦は発生しなくなる」と記載されています。これはタイムステップが不適切なのが原因です。流体力学を知っていればカルマン渦が発生しないことに違和感を持ち、CFDの経験があるとタイムステップの設定が不適切だと気が付くだろうと思います。しかし、もしかすると、この本の読者の中に全くの初心者がいらっしゃるかもしれないという可能性を危惧し、注意喚起のために敢えて記載させていただきました。この本を批判する意図は全くありません、上記のように自分にとっては非常に有益な本です。

タイムステップを適切な値にしてカルマン渦の再現ができている計算結果を以下に記載します。

#####Re=500 (本の通りの設定での計算結果)![Movie_Re500.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888272/6de4e0d8-1aa6-f2fc-0626-5f229c901560.gif)

#####Re=500（適切な設定での計算結果）![Movie_Re500_TimeStepPlus.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888272/b5ffad37-3848-ac54-708f-4a9777720154.gif)
ストローハル数が概ね一定なので、カルマン渦の発生周期は主流の速度に反比例します。
応用練習では主流速度を５倍にするので、カルマン渦の発生を捉えるためにタイムステップを5分の1にして計算した結果です。
<br>
数値粘性ではないか？という御指摘がありましたので、以下を2021/01/06 に追記しました。

この本の応用練習には、さらに粘性係数を5倍にしてRe数を100に戻した計算もあります。

#####Re=100 (本の通りの設定での計算結果)![Movie_Ex35_U5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888272/9bbbdf1e-824f-81e4-55c5-78f075b2495a.gif)

以下の場合だけはアニメーションGifファイルの容量が大きくなってアップロードが出来なかったため、静止画です。タイプ条件と比べて主流速度が５倍になっているので、カルマン渦の発生を捉えるためにタイムステップを5分の1にして計算した結果です。
#####Re=500（適切な設定での計算結果）![000009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888272/228001af-954f-b136-7dbb-1f7f28b7d706.jpeg)

したがって、御指摘のように数値粘性による“なまり”ではなく、カルマン渦のような非定常な現象を捉えるにはその周期よりもタイムステップを短くする必要があることを示していると考えます。この本での非定常計算の時間スキームの指定は2次のBDF(後退微分法)です。陰解法はタイムステップを大きくしても数値計算の安定性が保たれる便利なスキームですが、このような “落とし穴” があります。

<br>
不適切なタイムステップの件は、2021年1月4日に、いくつか見つけた誤植とともに出版元に連絡しておきました。
統計検定準1級(2019年6月試験) 問7〔1〕の解き方 

# 統計検定準1級(2019/6) 問7の解き方（俺メモ）

　残念ながら、ご法度なので問題文の掲載はしません。編集してもダメという厳しいお達しなので、お達しに触れないように気を付けながら書いてみます。
https://www.toukei-kentei.jp/faq/#4400
　禁止理由は、もっとらしいことは書いていますが、実態は公式解説本を売らんがための利権がらみなのでしょうねぇ…。いや、公式解説本がわかりやすければ全然いいと思うんですが、ものすごくわかりにくいんです、公式解説本。

## [1]
 問題文に$\mu_0=0,\sigma_0=1,\sigma=0$という条件が示されています。この条件を、回答選択肢の数式$\tilde{\mu}$と$\tilde{\sigma}^2$に代入して計算してみます。
 
| 選択肢 | $\tilde{\mu}$ | $\tilde{\sigma}^2$ |
|:-----------:|:------------:|:------------:|
| ① | $\frac{2^2\cdot2+1^2\cdot0}{2^2+1^2} =\frac{8}{5} $|$2\cdot1=2$|
| ② | $\frac{2^2\cdot2+1^2\cdot0}{2^2+1^2} =\frac{8}{5} $|$\frac{2^2+1^2}{2}=\frac{5}{2}$|
| ③ | $\frac{2^2\cdot2+1^2\cdot0}{2^2+1^2} =\frac{8}{5} $|$(\frac{1}{2^2}+\frac{1}{1^2})^{-1}=\frac{4}{5}$|
| ④ | $\frac{1^2\cdot2+2^2\cdot0}{2^2+1^2} =\frac{2}{5} $|$\frac{2^2+1^2}{2}=\frac{5}{2}$|
| ⑤ |$\frac{1^2\cdot2+2^2\cdot0}{2^2+1^2} =\frac{2}{5} $|$(\frac{1}{2^2}+\frac{1}{1^2})^{-1}=\frac{4}{5}$|

　で、計算した$\tilde{\mu}$と$\tilde{\sigma}^2$を図1の実線グラフ（事後分布）と比較してみます。
　まず平均の推定値$\tilde{\mu}$について。実線グラフの頂点部分（平均値）に着目します。横軸で値を読むとおおよそ0.4ぐらいです。なので、$\tilde{\mu}=\frac{2}{5}$である④か⑤が候補になります。
　次は分散の推定値$\tilde{\sigma}^2$です。実線グラフは破線グラフより幅が狭く、かつ頂点が高いので、破線のグラフより分散が小さいことがわかります。破線グラフの分散は$\sigma_0^2=1^2$なので、$\tilde{\sigma}^2<1$の③と⑤が候補になります。
　2つの条件を満たす回答の選択肢は⑤ですので、⑤が正答です。

　この問題の心ですが、$\mu$の分布を「だいたいこれぐらいかなぁ～？」と仮定（事前確率）しておいて、実際に標本を取り出してみます。その標本を元に「だいたいこれくらいかなぁ～？」の精度を高くする（事後確率）ということでした。
　実際、図1のグラフでも破線グラフよりも実線グラフのほうが頂点が高く幅が狭い、つまり分散が小さい（平均値の付近にある確率が高い）ということが読み取れます。
Google App ScriptからSlack通知 with 例外処理

Google App ScriptからSlackへ通知するコードを過去に書いていたが，例外処理をサボったせいで失敗に気づかなかった．そこで，例外が発生したときにメールで通知を受け取れるように修正をした．

```javascript
const POST_URL = 'https://hooks.slack.com/services/XXXXXXXX/YYYYYYY/ZZZZZZZZZZZZZZZZZZZ';
const PAYLOADS = JSON.stringify({
    "attachments": [
        {
            "blocks": [
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": "*YOUR_MESSAGE*"
                    }
                }
            ]
        }
    ]
});
const POST_OPTIONS = {
    "method": "post",
    "contentType": "application/json",
    "payload": PAYLOADS,
};

try {
    Logger.log("Call Salck API");
    UrlFetchApp.fetch(POST_URL, POST_OPTIONS);
} catch (e) {
    Logger.log("Exception: " + e);
    const mailDest = "admin@example.com";
    const mailBody = "お疲れさまです．\n次のエラーが発生しました．\n" + e;
    GmailApp.sendEmail(mailDest, "Slack通知に失敗しました．", mailBody);
}
```

参考URL

- [sendEmail(recipient, subject, body) - Class GmailApp | Apps Script | Google Developers](https://developers.google.com/apps-script/reference/gmail/gmail-app#sendemailrecipient,-subject,-body)
- [UrlFetchApp.fetchの応答3種 タイムアウトがつらい - Qiita](https://qiita.com/khsk/items/7d90513c88559e3d703f#%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E7%95%B0%E5%B8%B8)
CentOSインストールに使用した参考記事や本

#参考にしたもの
###本：Linuxの教科書
この本に基本的な方法が記述されているものの不足している部分がある。
そこをURLで補填した

###URL：
https://www.rem-system.com/centos-linux8-install/
https://qiita.com/tamago3keran/items/260899458959d3214dcf
[WinIoT/ラズパイ] VS2019で作ったUWPのslnをラズパイ3+WinIoTCoreでリモートデバッグができないときの対処

# やりたいこと

2021年1月時点で、ラズパイ3にWindowsIoTCoreを入れて、VisualStudio2019でUWPアプリを新規作成してデバッグしようとしたところ、うまくデバッグできなかった。

具体的には、「リモートデバッガに接続できない」旨のエラーが出て、リモートデバッグできなかった。(※画面キャプチャしなかったので文言を忘れてしまったが、そういう感じのエラーだった)

そういうときに、下記をすると(なぜか)動くようになった。

Microsoftの公式のやり方でもなんでもないので毎回この方法でうまくいくかどうかはわからないが、趣味やら実験でやる分にはとにかく動けば十分なので、一応メモっておく。

# やったこと概要

- 新規でUWPプロジェクト作成
- それを[こちら](https://qiita.com/tera1707/items/51027e2896f708959eaf)のやり方でリモートデバッグできるように準備する
- [サンプルコードを動かす](https://qiita.com/tera1707/items/51027e2896f708959eaf#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%8B%95%E3%81%8B%E3%81%99)ところで、リモートデバッグに失敗する
- 下記のやり方で(なぜか)うまく動くようになった

というときのメモ。

# やったこと詳細

とりあえず、UWPでなにか作成する。

そいつのアプリパッケージの作成をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/93af06e5-ba5f-7471-a934-2fdd31515051.png)

サイドローディングで作成してやる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/522c3f82-64e0-e342-6bc5-251629ae5aca.png)

証明書はスキップ(たぶん)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/630f31b4-07b9-4e69-d7a7-5e2ab8c93fd7.png)

ARMのみで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/86c8e6cb-8e6b-1d60-d0a4-855b09a430a3.png)

パッケージの作成完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/b9601eb3-6d97-578d-55ac-d9e4dd7b4301.png)

.msixbundleができてるのを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/20c800bc-6320-b2c6-3687-15c93bc008a9.png)

できあがったmsixは一旦おいておいて、IoTダッシュボードを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/038c5079-7a5d-2edf-8a36-7c5f84fd06c0.png)

デバイスポータルを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/31190b91-9ff0-221d-bb26-4bf14b92ae49.png)

AppManagerを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/639aa190-5378-2e02-a128-dbcb2a62bed5.png)

ここの「ファイルを選択」から、さっき作成したパッケージを上げるのだが、まず「.msixbundle」を上げると「依存するファイルがない」というエラーがでるので、まず下記の中にできている依存関係のファイルを上げる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/8e9fd9a3-4398-0a7a-46f2-11054d01b178.png)
＞`Dependencies\arm`の中にあるファイル。今回は下記だった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/69bda9f9-175c-bb9c-a5f6-fa297a665137.png)

上記を全部uploadしてから`.msixbundle`をあげると、うまくアップロードできる。


ここまでやってから、VS2019からリモートデバッグをすると、なぜかデバッグ実行することができるようになった。
(リモートデバッグ開始時に依存ファイルがなくて落ちるのが「リモートデバッガに接続できなかった」というエラーになって表れていた、ということか？？)

なぜ動くようになるのかはよくわからないが、とにかく今回は上記手順でリモートデバッグできるようになった。
(別の新規のUWPアプリを作ったあともリモートデバッグできていた。一度不足物をあげてやれば、以降はできる状態が続く？？)

# IoT Core用のプロジェクトテンプレートがある？？

下記が、VS2017と2019に使えるIoT Core用のテンプレートらしい。
まだ試してないのでわからないが、これを元にUWPのプロジェクトを作成すれば、最初からリモートデバッグできるのかも？

Windows IoT Core Project Templates for VS 2017+
https://marketplace.visualstudio.com/items?itemName=MicrosoftIoT.WindowsIoTCoreProjectTemplatesforVS15

# 参考

VS2019では、リモートデバッグできない？？
https://www.codeproject.com/Articles/1945985/App-Development-on-Windows-IoT-using-VS-2019
Vagrantで複数台同時起動する設定


Vagrantで複数台同時起動するマルチマシン設定
自分PCの中で複数のサーバー動作実験をするときに使用する。

- VirtualBox  6.1.16 r140961 (Qt5.6.2)
- Vagrant 2.2.9
- ホストOS：Windows10
- ゲストOS：CentOS Linux release 8.3.2011

```ruby:Vagranfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
  config.vm.define "server111" do |server|
    server.vm.box = "bento/centos-8"
    server.vm.hostname = "server111"
    server.vm.network "private_network", ip: "192.168.56.111"
    server.vm.synced_folder ".", "/vagrant", disabled: true
    server.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.memory = "512"
    end
  end
  config.vm.define "server112" do |server|
    server.vm.box = "bento/centos-8"
    server.vm.hostname = "server112"
    server.vm.network "private_network", ip: "192.168.56.112"
    server.vm.synced_folder ".", "/vagrant", disabled: true
    server.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.memory = "512"
    end
  end
end
```

```dosbatch


```
XCOPYとタスクスケジューラで自動バックアップ

#背景
業務の中で、フォルダをバックアップすることがあり、

「面倒くさいなぁ・・・」「自動化できないかなぁ・・・」

と、思ったのがきっかけ。
色々調べた結果、「**コマンドプロンプト（XCOPY）**」とWindowsの「**タスクスケジューラ**」を組み合わせれば、フォルダのバックアップを自動化することができることがわかったので、忘備録として投稿。

##必要なファイル
・ファイルをコピーするためのバッチファイル（XCOPY）
※自分用に、日付の変数を入れたりとしています。
任意で削除したりしてください。

※/E/I等の、「XCOPY」の仕様については、別記事にて投稿します。

```backup.bat
rem 現在日付(YYYYMMDD)の取得
set date_str=%date:~,4%%date:~5,2%%date:~8,2%

XCOPY コピー元 コピー先%date_str%バックアップフォルダ名% /E/I/Q/S/Y
```



・タスクスケジューラ起動時、コマンドプロンプトを非表示にするためのvbsファイル

```backup.vbs
Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c batch実行ファイルのパス", vbhide
```

###タスクスケジューラ登録方法


①タスクスケジューラを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/6571e6b4-df9c-1dab-b5a3-bdba315bcd58.png)

②「基本タスクの作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/0a775187-fe09-5a98-37cc-3be0ee6fb2f5.png)

③この後は、手順に沿って登録すれば大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/52f1bfc4-453f-d3d3-e63e-61f38bc5a6b8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/272135eb-91e4-c191-447e-e8323aa0ce01.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/da22379c-5523-5680-484a-b66b11328e32.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/80bfe64a-cfa0-cde0-17a9-827be27fd27c.png)

※VBSファイルを選択しないと、batch実行時、コマンドプロンプトの画面が表示されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/bf8833d8-0a98-f514-8784-097e0ae41ba4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998004/1153d5fc-76ce-4639-8f1f-d34fb1db85ad.png)

以上です！

何かご質問がございましたらご連絡お願いします！
次回は、XCOPYについての記事をあげれたらな～と思います。

最後までお読みいただき、ありがとうございました！
PythonでHEICファイルをPNGファイルに変換

iPhoneのライブフォトで撮影した写真はHEICファイルで保存される．
このファイルはJPEGやPNGに比べて対応しているソフトウェアが少なく扱いにくい．
そこでHEICファイルをPNGファイルに変換する方法をメモしておく．

Google Colaboratoryを使えばブラウザから実行できる．

# 環境

- Ubuntu 20.04.1 LTS on WSL2
- Python 3.8.5

# ソースコード

変換したいファイルと同一の階層にconv.pyを配置して実行する．

```python:conv.py
from PIL import Image
import pyheif

def conv(image_path):
    new_name = image_path.replace('heic', 'png')
    heif_file = pyheif.read(image_path)
    data = Image.frombytes(
        heif_file.mode,
        heif_file.size,
        heif_file.data,
        "raw",
        heif_file.mode,
        heif_file.stride,
        )
    data.save(new_name, "PNG")

import glob
lst = glob.glob("*.heic")
for l in lst:
    conv(l)
```

# 利用パッケージ

- pyheif
- PIL

PILは以下のコマンドでインストールする．

```
pip install Pillow pyheif
```

pyheifはOSごとに適したコマンドでインストールする．

macOSの場合，以下でインストールする．

```
brew install libffi libheif
pip install git+https://github.com/david-poirier-csn/pyheif.git
```

Debian系のLinuxディストリビューションの場合，以下でインストールする．

```
apt install libffi libheif-dev libde265-dev
pip install git+https://github.com/david-poirier-csn/pyheif.git
```

RedHat系のLinuxディストリビューションの場合，以下でインストールする．

```
yum install libffi libheif-devel libde265-devel
pip install git+https://github.com/david-poirier-csn/pyheif.git
```

# 実行結果

```bash
$ python conv.py
$ ls
IMG_3488.heic*  IMG_3494.heic*  IMG_3497.heic*  IMG_3499.heic*  IMG_3503.heic*  IMG_3510.heic*  IMG_3514.heic*  a.py*  
IMG_3488.mov*   IMG_3494.mov*   IMG_3497.mov*   IMG_3499.mov*   IMG_3503.mov*   IMG_3510.mov*   IMG_3514.mov*   env/
```

# 参考URL

[Pythonで指定ディレクトリのHEICファイルをJPEGへ変換する - Qiita](https://qiita.com/Tak3315/items/c0dc8b4d81ed2a582f22)
【Excel】カウント

#頭3桁シート作成
A列→記入
B列→記入
C列→　=COUNTIF(頭5桁分類!\$D\$3:\$D\$100,頭3桁分類!A2)
D列→　=COUNTIF(全体シート!\$B\$2:\$B\$229,頭3桁分類!A2)
E列→　=AVERAGEIF(全体シート!\$B\$2:\$B\$229,頭3桁分類!A2,全体シート!\$CF\$2:\$CF\$229)

#頭5桁シート
B列→記入
C列→記入
D列→　=LEFT(B3,3)
E列→　=VLOOKUP(LEFT(B3,3),頭3桁分類!\$A\$2:\$B\$100,2)
F列→　=COUNTIF(全体シート!\$D\$2:\$D\$229,B3)
G列→　=AVERAGEIF(全体シート!\$D\$2:\$D\$229,頭5桁分類!B3,全体シート!\$CF\$2:\$CF\$229)
H列→　=COUNTIFS(全体シート!\$D\$2:\$D\$229,頭5桁分類!\$B3,需要表!\$E\$2:\$E\$229,頭5桁分類!H\$2)
I列→　=IFERROR(AVERAGEIFS(全体シート!\$CF\$2:\$CF\$229,全体シート!\$D\$2:\$D\$229,頭5桁分類!\$B3,全体シート!\$E\$2:\$E\$229,頭5桁分類!H\$2),0)
J~U列→ コピー

#全体シート

B列→ =LEFT(G2,3)
C列→ =VLOOKUP(B2,頭3桁分類!\$A\$1:\$B\$26,2,FALSE)
D列→ =LEFT(G2,5)
E列→ =MID(G2,6,3)
F列→ =MID(G2,9,5)
EC2インスタンスをWebサーバとして起動し、Hello, worldを出力する

# はじめに
- [Amazon EC2を起動し、MacのターミナルからSSH接続してみる](https://qiita.com/TaishiOikawa/items/2af53935e5f741f05bbb)の続きです
- 今回はEC2インスタンスにApacheを入れてブラウザでHello,worldを表示してみます

# 構造図
- [Amazon EC2を起動し、MacのターミナルからSSH接続してみる](https://qiita.com/TaishiOikawa/items/2af53935e5f741f05bbb)の構成のまま

![ssh接続.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779593/e4e6ed73-1d69-9a18-fe66-3941a2a256da.png)

- 例によってPrivate subnetは不要でもよい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779593/c83864ce-879a-ae74-3bcf-fe69da8761ae.png)


# 手順
## 1. Apacheをインストールする
- ターミナルを開く

- ec2インスタンスにsshアクセスする
    - `ssh -i ~/.ssh/develop.pem ec2-user@[パブリックIPv4アドレス]`
- 管理者権限に移動
    - `sudo su`
- インストールされているソフトウェアを最新のものに更新
    - `yum update -y`
- apacheサーバをインストール
    - `yum install httpd -y`

## 2. index.htmlを作成する
- `/var/www/html`に移動
    - `cd /var/www/html`
- htmlファイルを作る
- `vi index.html`
    - 下記をコピー&ペースト
        - `<html><h1>Hello, world!</h1></html>`
    - 上書き保存
        - `esc` → `:wq` 
- apacheを起動
    - `systemctl start httpd`
- インスタンスの起動時にapacheが起動するように設定
    - `systemctl enable httpd`

## 3. ネットワークACL、セキュリティグループに設定を追加する
- htmlを読み込むためにHTTP,HTTPSの設定を追加する

- ネットワークACL
    - インバウンドルール（アウトバウンドルールも同様）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779593/94952d94-7290-a923-a451-c95aa136916f.png)

- セキュリティグループ
    - インバウンドルール（アウトバウンドルールは設定不要）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779593/d8efcd4d-6388-d1df-21ce-53b35ec43140.png)

## 4.ブラウザでインスタンスにアクセスする
- EC2インスタンスのパブリックIPアドレスをコピー
- 任意のブラウザでアドレスをペースト
- `Hello, world!`が出力されれば成功

![スクリーンショット 2021-01-05 22.31.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779593/19f1f588-87c8-7cd8-4099-405350886d61.png)

## 完了

# 終わりに
- EC2インスタンスは無料枠には時間制限があるので、使用しない場合は停止しておきましょう
- 次回はStreamlitというPythonのAPIを使って、コロナウイルス感染者の人数を可視化するWebアプリケーションを作ってみます
- 間違いや改善点等ございましたらコメントをいただければ幸いです

---

### 作図ツール
- draw.io(https://www.draw.io/?splash=0&libs=aws4)
CentOS上でマウス操作を切り替える方法

#CentOS上でマウスポインターを自分のパソコンと仮想環境画面のポインターで切り替える方法

![スクリーンショット 2021-01-05 22.30.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/241a7e5c-0081-3da4-0d45-ca91eb46a8f2.png)

**左側の⌘キー**を押せば押すたびにメインPC⇄centOSの画面で切り替わる
ログイン時に何かを出力するようにしていると scp が失敗する問題の対処法

# TL;DR
[Fix scp command failure · noraworld/dotfiles@4d7cf4f](https://github.com/noraworld/dotfiles/commit/4d7cf4ff1e8dbdeb09b0e5973a2edf96e7f86c4b)

# はじめに
たとえば `~/.bashrc` などで、`echo` コマンドなどを使って何かを出力するようにしていると `scp` コマンドが失敗します。

```bash:~/.bashrc
# リモートホスト側
echo "something"
```

```shell
# クライアント側
$ scp username@example.com:~/test .
something
```

ファイルがカレントディレクトリにダウンロードされるはずがダウンロードされず、"something" と表示されただけで終わってしまいます。

ログイン時に標準出力に何かを表示するようにしていると `scp` コマンドが失敗するらしいので、`scp` コマンド実行時のみ `~/.bashrc` などで何も出力しないようにします。

# やり方
`scp` でのログインかどうかを判定する `is_not_scp()` 関数を作ります。`is_not_scp()` 関数は `scp` からのログインでなければ `true` を返し、`scp` からのログインだったら `false` を返します。

そして、`scp` だったら、ログイン時に何かを出力するようにしている部分を出力しないようにします。

```bash:~/.bashrc
is_not_scp() {
  if [ ! -f /proc/$PPID/cmdline ]; then
    echo true
  elif [ -f /proc/$PPID/cmdline ] && [[ "$(cat /proc/$PPID/cmdline | sed 's/\x0//g')" =~ sshd:([[:blank:]]+.*)@notty ]]; then
    echo false
  else
    echo true
  fi
}

if "$(is_not_scp)"; then
  echo "something"
fi
```

## 解説
macOS では `/proc/$PPID/cmdline` は存在しないのでスキップします。

Linux では `/proc/$PPID/cmdline` に現在ログイン中の端末の情報が表示されます。たとえば SSH ログイン中に実行すると以下のように表示されます。

```shell
$ cat /proc/$PPID/cmdline
sshd: ubuntu@pts/0
```

これが `scp` コマンドだと以下のようになります。

```shell
sshd: ubuntu@notty
```

`notty` は端末が割り当てられていないということなのですが、`scp` コマンドだと `notty` と表示されるので、そうなっていれば `scp` コマンドからだと判断します[^1]。

[^1]: それ以外で `sshd: ubuntu@notty` のように表示されるケースもありますが実用上はおそらく問題ないと思いますので割愛します。

`sed` コマンドを使っているのは、`cat /proc/$PPID/cmdline` の出力にヌルバイトが混ざっているからです。`sed` でヌルバイトを除去しています。

ログイン時に何かを出力している箇所を `if "$(is_not_scp)"; then` と `fi` で囲めば `scp` 時にはその部分は出力されなくなるので、`scp` がうまく機能するようになります。

`~/.bashrc` じゃなくて `~/.bash_profile` に何かを出力していたり、Zsh を使っていて `~/.zshrc` とかに何かを出力していた場合も同様です。適宜、ファイル名は読み替えてください。

# 参考サイト
- [scpできなくて私もハマった](https://engineer-log.net/index.php/2017/05/26/post-2490/)
- [「root@notty」って何者？](https://meteoricstream.com/tips_detail/88.html)
業界未経験の私がポートフォリオを作って転職をしたい件

## 自分で作ったポートフォリオサイト・作品集（作成途中）
[こちら](https://github.com/yapiro/)に今まで作ったアプリが入っているので、ぜひご覧ください。

### TOPページ

![スクリーンショット 2021-01-05 21.12.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942636/395d540d-aaba-4aec-9ee3-b6a66ed68d6d.png)

TOPページは、誰もが操作しやすく簡単に理解できる見た目にしてみました。構成は４つ。
1. 自分のプロフィール
2. スキル/制作実績
3. 学習の積み上げ報告（twitter）
4. Qiita
この４つを意識することが転職活動を成功に導くと仮定して選びました。

### 作品集（サイトを見ればもう一つあります）」
![スクリーンショット 2021-01-05 21.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942636/1ab0fad4-6612-fff8-11ac-b69d13f17548.png)
作品集はスキル/制作実績ページにあります。

画像向かって左側には自分の趣味であるウイスキーや旅、筋トレをいろんな人が主体的に投稿して楽しめたらいいなという思いで作りました（未完成）。


## 作ってみたきっかけ

きっかけは単刀直入にエンジニアになることでした。
東日本大震災で被災した友人から当時の話を聞いたことをきっかけに、人のために働きたいという想いが根底にあり、今一番感動させられるのはIT技術だと思ったからです。今やスマホがないと生きていけない人がほとんどな世の中で、自分自身がサービス開発に携わり、サービス利用者を満足させたいと思いました。

## 使用言語

フロントエンド言語であるjavascriptを選びました。
その中でもSPA（シングルページアプリケーション）を実装したかったので、reactとvueで作ってました。
前述したポートフォリオサイトはreactを使用しました。


## サイト概要
https://yapiro.github.io/pf-site/

* このサイトは主に自分を知ってもらうために作成
* 自己紹介をはじめ、作品、学習記録をアピールすることが目的

## アプリ概要
https://yapiro.github.io/portfolio/
reactで作りました。

* ブログ簡易掲示板
* 投稿機能
* 写真投稿機能

### 使い方

上半分はブログのため、見たい記事があればクリック
下半分は３つの項目（ウイスキー・旅・筋トレ）をみんなと共有したいときにクリック

### ローカル環境へのインストール方法

```shell
git clone https://yapiro.github.io/portfolio/
npm install
npm start
```

## 現在
現在もアプリは作成途中です。
作成した際はhttps://github.com/yapiro に順次掲載していきます。

[twitter](https://twitter.com/1m8pseqcODr2idm)でもリンクを貼っています。
Pythonで正規表現

# 使い方

## モジュールのimport

```
import re
```

## 正規表現オブジェクトの生成・マッチング

正規表現オブジェクトを生成してから、マッチングする方法

```
# 生成
cmpObj = re.compile(r'a.c')
# マッチング
ret = cmpObj.match('abc')
```

正規表現オブジェクトを生成しなくても、マッチングできる。
しかし、プログラム中で何度も同じ正規表現パターンを使用する場合は、正規表現オブジェクトを生成して使用するほうが効率的に処理できる。

```
# マッチング
ret = re.match(r'a.c', 'abc')
```

正規表現パターンに文字列がマッチしている場合には、`match()`の戻り値として、マッチオブジェクトを返却する。
マッチしなかった場合は、Noneが返却される。

`match()`は文字列の先頭がマッチするかを見ているため、以下のような場合はマッチしない

```
# これはマッチしない
ret = re.match(r'a.c', 'babc') 
```

文字列の先頭だけでなく、途中でもマッチしているかを確認する場合は、`search()`を使用する。

```
# これはマッチする
ret = re.search(r'a.c', 'babc')
# 正規表現オブジェクトを使用する場合
ret = cmpObj.search('babc')
```

## マッチしたか確認する

```
if ret : 
    print(ret) # マッチした場合
else :
    print('not match') # マッチしなかった場合
```

## 注意点

* パターンと検索する文字列は`str`または`bytes`を使用するが、`str`と`bytes`の混在はできない。
* 正規表現パターンの文字列を指定するときには、raw文字列記法を使用する。（`\`を特殊文字として扱いたくないため）
[ JavaScript 入門 ] 演算を行うメソッドをクロージャーを用いて作成してみる！

#演算を行うメソッドをクロージャーを用いて作成してみる！ 
```js
// 演算を行うメソッドを持ったオブジェクトを
// クロージャーを用いて作成してみる。 

const calc = calcFactory(10); // 初期値を10として設定
calc.plus(5);      // 出力結果 "10 + 5 = 15"

```

まずcalcFactory実行して初期値を設定できるようにする:point_up:
そして、オブジェクトを返す為、returnを記述。

```js
function calcFactory(val){
  return {
  }
}
```
その中にメソッドとして***plus***を格納する必要がある:raised_hand:

```js
function calcFactory(val){
 return {
 plus: function(target) {
            const newVal = val + target;
            console.log(`${val} + ${target} = ${newVal}`);  
        },      
    };
}
```
plus(5); このメソッド自体引数を持っているので、function(target)としてあげる！
const newVal = val + target;　のところで渡ってきた***val***と***target***を足してあげる必要があるのでこの記述。:v:　　　

このようすることで、出力したい出力結果 "10 + 5 = 15"というのは、 plus:のメソッド内では全て参照可能になるので、valには10がわたり、targetにはplus(5)の5が渡る:runner_tone2:　　　

この出力結果に合うようにコンソールに出力する:point_up_2:

```js
function calcFactory(val){
 return {
 plus: function(target) {
            const newVal = val + target;
            console.log(`${val} + ${target} = ${newVal}`);  
        },      
    };
}
const calc = calcFactory(10);
calc.plus(5); 
```
***このようにすることによって、コンソールに10 + 5 = 15と出力することができる***
1か月の試験勉強でAWS 認定 デベロッパー – アソシエイト (DVA) に合格した話 

AWS SAA(ソリューションアーキテクトアソシエイト)を取得できたエンジニアが
1か月の試験対策でAWS DVA(デベロッパーアソシエイト)に合格できた話です。
AWS DVAについては、他の方が説明されていたり、AWS HPに記載されているので、
ここでは省略させて頂きます。

SAA取得時の話は下記となります。
[AWS SAA取得時の話](https://qiita.com/pkopko-b8/items/3bfd8ccdbbc9baadbffe)
※SAA取得から1年以上、受験をしておらずコンスタントに取り組めば、
 もっと良かったと、思ったりしました。(今年は、ステップアップしたいと思います。)

個人的な経験ですが備忘録として投稿いたします。
ちょっとは、役に立てばうれしいです。
年末年始の休み中、比較的勉強ができたこともあるため、1ヶ月の試験とはいえ、
比較的、取り組み時間が長く取れたかと思います。
下記、試験結果です。

![スクリーンショット 2021-01-05 21.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513502/2fe6753c-de44-dec7-7430-f5638d44b985.png)

# 背景
## 経歴
　組込系（ARMアーキテクチャ）エンジニアとして働いています。
　IoT機器のアプリケーション開発、ネットワーク環境構築がメインの業務としてます。
　また、AWSを使用した、IoT機器の保守システム開発などをしてきました。

## 受験きっかけ
　前回、SAAを取得できて、少し満足したところがあり、他の資格取得は目指しておりませんでした。しかし、今年は[AWS re:Invent](https://aws.amazon.com/jp/about-aws/events/2020/reinvent/)がオンライン配信ということもあり、気軽に新しいサービスを知るきっかけができました。こういったこともあって、秋以降、AWSへの興味が再熱してきました。そこで、他の資格も取得してみようと思ったのがきっかけです。

# 取り組んだこと

##（１）本による"試験対象サービスの知識習得"
　デベロッパーアソシエイト取得後、
　SysOpsアドミニストレーターも取得したい思いがあったため、
　下記を試験対策本としました。この本の中で、DVAが対象としている章(サービス)を
　一通り確認し理解できるよう読み込みました。
　[AWS認定アソシエイト3資格対策～ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター](https://www.amazon.co.jp/dp/B07TT1N73K/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

　本という形のため、以後に記載するもの(Udemy,BlackBelt)よりも、情報量は少ないですが、
　体系的に説明されているため初めに試験勉強として取り組むものとしては良いと思います。
　
##（２）Udemyによるオンライン学習
　セールをやっていたので、下記購入しました。
　[AWS 認定デベロッパー アソシエイト模擬試験問題集（5回分325問）](https://www.udemy.com/course/aws-31955/)
　⇒正直なところ、実際の試験よりもやや難しいと感じるところもあります。
　 また、若干ですが、試験には出てこない範囲も含まれます。
　 しかし、この問題集は解説も細かく記載されているため、これらを合格点がとれるまで
　 繰り返すと、とても自信がつきました。

##（３）BlackBelt Online Seminarをみる
　[Amazon Web Services Japan 公式](https://www.youtube.com/channel/UCnjKWUK2t5QJYfeqqilhJhQ)
　たくさんの動画がupされているため、全部を見るのは難しいかと思います。
　問題集ばかりをやっていると、飽きてくるのもあったため、
　DVAの試験対象のサービスに関して、動画をチェックいたしました。
　(Lambda,API Gateway,CodePipelineあたり）
　本やUdemy講座などで各サービスの概要を知った上でBlackBeltを
　観ると理解が深まると思いました。

##（4）実際にAWSサービスに触れる
　やはり、これが一番だと思います。文字を追うだけよりも実際に触ってみたら、理解が
　早いです。手軽にサービスに触れるところがクラウドの良いところだなと改めて思いました。

## スケジュール

  *　1週目 
　本を中心に全体像を理解
　勉強時間：平日-通勤時間の30分ぐらい
　　　　　　　 土日-なし
  *　2週目
　Udemyのオンライン講座で理解
　※勉強時間：平日-通勤時間の30分ぐらい
　　　　　　　　土日-2時間/日ぐらい
　
  *　3週目
　本とUdemyの問題集を繰り返し実施し、3周程度いたしました。
　この時、年明け最初に受験するよう、申込をいたしました。
　
  *　4週目(年末年始)
　BlackBeltを観始めました。
　Udemyの問題集で間違えたサービスについて、BlackBeltを観て、不明点を補う作業
　飽きてきたら、本/Udemy/BlackBeltの教材をチェンジしながら勉強してました。
　また、AWSサービスに触れ、理解を進めました。
　※勉強時間：1日3時間程度

#　試験当日
　運転免許証とクレジットカードをもって、テストセンターへ
　コロナ禍のため、マスクしたままでした。席も間が空いており、人はまばらでした。
　ホワイトボードを渡され、試験を開始しました。
　
　■1周目
　約５0分かけて、まずは全問題を解きました。
　あやふやなところ含めて、確信できない問題にチェックをいれていきました。
　■2周目
　見直しフェーズ。
　約30分かけて、見直ししました。
　落ち着いて見直しを行い、1問ずつ、大丈夫かなと思えるようになってきました。
　⇒時間が長い試験ですが、2周問題をチェックするとあっという間でした。
　　アンケートを答えたら、"合格"となっていたので、うれしかったです。
　　3時間後程度に試験結果のリンクのメールがきておりました。

# その他
　[ホワイトペーパー](https://aws.amazon.com/jp/whitepapers/)や[ベストプラクティス](https://aws.amazon.com/jp/premiumsupport/trustedadvisor/best-practices/)など、いろいろありましたが、ボリュームに圧倒されて、題材に使うのは諦めました。。

# 感想
　やはり、受験料も安くないので、1発で合格出来てよかったです。
　今年は、この流れで他の資格も取れていければなと思います。
　新しいサービスがどんどん出てきて、興味が沸く一方、
　キャッチアップも大変なところもあるなと感じました。
　でもできることが増えるのはやはり楽しいです。

以上です。
PowerAutomateにてデータベース挿入時、自動採番を補う

DB上のフィールド定義にて自動採番にしてあっても、PowerAutomate側から入力する際、
何かしらの値の入力が必要らしい。

自動採番というくらいなので、キー、Null禁止になっているでしょうから困ったものです。

そこで自力で対策を考えたのでよりよい方法をご存知でしたらご教授ください

1. 対象のテーブルをIDを逆ソートし、1行だけ読み込む
1. 読み込んだIDを変数に入れ、＋１追加する
1. 対象のテーブルの書き込みと共に、先の変数を書き込む

以上desu

<hr>

1.IDを逆ソートし、1行だけ読み込む、のところ
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/91052fd8-d9de-3d48-a173-807ccf929270.png)

2.読み込んだIDを変数に入れ、＋１追加する、のところ
実際は初期化の際、初期値を1に設定し、先のIDのMAX値を足している
![スクリーンショット 2021-01-05 215758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/9c3cd0a2-ca8a-775e-ef11-4a280b0a2254.png)

3.テーブルの自動採番の項目に、先の変数を書き込む
![名称未設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/61454c18-9db6-a291-7855-490477cbdd8e.png)
【Java】Mapの使い方

#プログラミング勉強日記
2021年1月5日
JavaでのMapの扱い方を簡単にまとめる。

#Mapとは
　Mapはキーと値の2つの要素からなる複数のデータを格納できるものである。キーは値に名前を付けるようなもので、値の1つ1つにキーが存在する。このキーと値がペアになっているのがMapの特徴である。そのため、Mapから値を探すときにキーを目印に探すことができる。

#HashMapで初期化する方法
　Mapはインターフェースなので、インスタンスを生成するにはそれを実装したクラスを使用しないといけない。Mapのインスタンスを生成するのによく使われているのが、HashMapクラスである。

```java:HashMapクラスを使って宣言する方法
Map<キーの型名, 値の型名> オブジェクト名 = new HashMap<>();
```
　宣言するときにはキーと値のデータ型を指定する必要がある。

```java:サンプルコード
import java.util.HashMap;
import java.util.Map;

public class Sample {
    public static void main(String[] args) throws Exception {
        // キーをInteger、値をStringにする場合
        Map<Integer, String> map = new HashMap<>();
    }
}
```

#Mapでよく使用するメソッド

##putメソッド
　Mapにデータを追加できるメソッドで、第1引数にキー、第2引数に値を指定する。

```java:サンプルコード
import java.util.HashMap;
import java.util.Map;

public class Sample {
           public static void main(String[] args) throws Exception {
                      Map<Integer, String> map = new HashMap<>();
                      map.put(1, "田中");
                      map.put(3, "鈴木");
                      map.put(5, "山田");
           }
}
```

##getメソッド
　Mapに格納したデータを取得することができるメソッドで、引数にキーを指定することでそのキーの値を取得できる。

```java:サンプルコード
import java.util.HashMap;
import java.util.Map;

public class Sample {
           public static void main(String[] args) throws Exception {
                      Map<Integer, String> map = new HashMap<>();
                      map.put(1, "田中");
                      map.put(3, "鈴木");
                      map.put(5, "山田");

                      System.out.println(map.get(1));
                      System.out.println(map.get(3));
                      System.out.println(map.get(5));
           }
}
```

```:実行結果
田中
鈴木
山田
```

##keySetメソッド
　Mapに含まれるキーの値を返すメソッド。今回はkeySetメソッドを使ってMapのすべてのキーを出力する方法を紹介する。

```java:サンプルコード
import java.util.HashMap;
import java.util.Map;

public class Sample {
           public static void main(String[] args) throws Exception {
                      Map<Integer, String> map = new HashMap<>();
                      map.put(1, "田中");
                      map.put(3, "鈴木");
                      map.put(5, "山田");

                      for(Integer key:map.keySet()) {
                                 System.out.println(key);
                      }
           }
}
```

```:実行結果
1
3
5
```


#valuesメソッド
　valuesメソッドは、定義したMapや列挙子をまとめて受け取ることができる。Mapの値を全て取得する場合はvaluesメソッドを使う。

```java:サンプルコード
```java:サンプルコード
import java.util.HashMap;
import java.util.Map;

public class Sample {
           public static void main(String[] args) throws Exception {
                      Map<Integer, String> map = new HashMap<>();
                      map.put(1, "田中");
                      map.put(3, "鈴木");
                      map.put(5, "山田");

                      for(String values: map.values()) {
                                 System.out.println(values);
                      }
           }
}
```

```:実行結果
田中
鈴木
山田
```

#参考文献
[【初心者向け】Javaのmapの使い方を解説！サンプルコードも紹介！](https://www.tech-teacher.jp/blog/java-map/)
[【Java入門】Mapの使い方総まとめ(HashMapで初期化、値のソート)](8https://www.sejuku.net/blog/19796)
PAM 認証エラーの回数制限 

+ 検証環境
  - CentOS Linux release 7.8 

sshdはデフォルトでPAM認証を利用する。`UsePAM`のパラメータが`yes`になっている。

/etc/ssh/sshd_config

```
UsePAM yes
```

`/etc/pam.d/password-auth` を編集する。

/etc/pam.d/password-auth

[変更前]

``` 
auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so
```

[変更後]

```
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
# Add setting
auth        required      pam_faillock.so preauth silent audit deny=3 unlock_time=3600
auth        sufficient    pam_unix.so try_first_pass nullok
# Add setting
auth        [default=die] pam_faillock.so authfail audit deny=3 unlock_time=3600
auth        required      pam_deny.so

account     required      pam_unix.so
# Add setting
account     required      pam_faillock.so
```

記載順によって評価が変化するため注意する。

`auth` ユーザ認証を行う。

`account` ユーザ認証が可能か確認する。

`required` モジュールの実行に失敗してもすぐに拒否せず、同じタイプのモジュールの実行が全て失敗した時点で認証を拒否する。
`sufficient` モジュールの実行に成功した場合、より上位のrequired行が全て成功であれば、その時点で認証を成功とする。失敗した場合は引き続き評価する。

`faillock`コマンドで認証失敗情報を表示する。3回認証失敗した場合は、以下のように表示される。

```
[root@c ~]# faillock
u1:
When                Type  Source                                           Valid
2021-01-05 21:22:07 RHOST m014011003224.v4.enabler.ne.jp                       V
2021-01-05 21:22:10 RHOST m014011003224.v4.enabler.ne.jp                       V
2021-01-05 21:22:13 RHOST m014011003224.v4.enabler.ne.jp                       V
```

アカウントロックされると、アンロック時間を超えるまで正しいパスワードを入力してもログインできなくなる。

```
> ssh u1@c.example.com
u1@c.example.com's password:
u1@c.example.com's password:
u1@c.example.com's password:
Permission denied (publickey,password).
```

手動でリセットすることもできる。

```
[root@c ~]# faillock --user u1 --reset
```

PAMの詳しい使用方法が知りたければ、[The Linux-PAM System Administrators' Guide](http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_SAG.html) を見てみる。

`The Linux-PAM System Administrators' Guide`
http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_SAG.html
Laravelはじめました

#Larave（ディレクトリ構成）

本日からLaravelを触り出したので自分の勉強記録として投稿していこうと思う。

簡単にディレクトリ構成から勉強。
（フレームワークを余り触ったことがないので混乱）


 ディレクトリ構成
- 
| 1 | 2 |
|:-:|:-:|
| app  | アプリのメインとなるところ  |
|  bootstrap |  初期処理やキャッシュ |
|  config |  アプリの設定 |
|  database | データベース(マイグレーション)  |
|  public |  画像,JS,CSS |
|  resources |  blade(HTML的な) |
|   routes|  アプリのURL設定など |
|  storage | セッションやログ  |
|  tests | テスト用  |
|  vendor | Composerの依存内容  | （）


# 設定ファイル(隠しフォルダにあり)
 - codeフォルダの歯車マーク押して、show hidden filesをクリック
 - .envフォルダを開く
 
```言語:php
DB_CONNECTION=mysql
DB_HOST=localhost         // 編集
DB_PORT=3306
DB_DATABASE=laravel_todo  // 編集
DB_USERNAME=root
DB_PASSWORD=root          // 編集 環境によって異なる　現在はAWS


```


# dbマイグレーションとは

- SQLを直接使わなくても、データベースを管理できるLaravelの仕組み。

- テーブル作成の流れ
1.マイグレーションファイルを生成
2.ファイルにテーブル定義を書く
3.マイグレーションを実行し、DBに反映

※まず、１テーブル１ファイルと覚えよう

# マイグレーションの生成

- ファイルの場所とファイル名のルール
 database/migrations

2020_12_20_00000_todos_table.php
　　生成時間　　　　　アクション名　テーブル名

- ファイル生成コマンド
- 
 ```言語:tarminal
php artisan make:migration todos_table

```
カラム名:add_カラム名_to_users_table

 ```言語:tarminal
php artisan migrate

```
全ファイルが実行される

# マイグレーションの中身

- upとdawnメソッドがある
upが実行(作成)で、downが元に戻す(削除)

- Schemaファザードを使っている
例)Schema::create テーブルを作成

- カラムの作成はBlueprintオブジェクトのtableメソッドを使う
例)$table->string('name')名前カラムを作成!


# 実際にファイルを見てみる

```言語:php database/migrations/2020_12~

 /**
  ここでマイグレーションファイルを読み込む
 */
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
       /*
        Schemaファザードを使っている 
        if tableがなかったら作る
        */
        if(!Schema::hasTables('todos')){
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('todo');
            $table->date('deadline');
            $table->text('comment')->nullable();
            /*　100文字制限の時は('comment',100) */
            $table->timestamps();
        });
      }
    }
  }

```

マイグレーションを実行する

 ```言語:tarminal
php artisan migrate

```
結果

 ```言語:tarminal
Migration table created successfully.
Migrating: 2014_10_12_000000_todos_table
Migrated:  2014_10_12_000000_todos_table (31.23ms)
```

error
 ```言語:tarminal
  $ composer dump-autoload
```
からの再起動




とりあえずここまで。
次回に進む。
Arduino Due互換機でST-Link V2を使用してブレークポイントデバッグをする

ArduinoDue互換機でブレークポイントデバッグができることが判ったので手順をまとめました。投稿者が使用した互換機はDUE COREですが、正規のArduinoDueや他のご互換機でも同じだと思います。

【前提】
・VSCode + PlatformIOのセットアップが済んでおり、Dueにプログラム書き込みができている(書き込みケーブル用のデバイスドライバもインストール済み)。
・ST-Link V2(パチモンでもOK)を持っていて、このデバイスのドライバもインストール済みである。
![dd.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/919305/a1198130-e751-577b-5c9f-ba069967f91a.png)

【手順】
1. platformio.iniを下記を参考に書き換えます。upload_portを固定で指定しているのは投稿者の環境で同じデバイス(書き込みケーブル)が複数ありオートで識別しなかったためです。オート(ポート無指定)でもうまくいく環境もあると思います。

```ini:platromio.ini
[env:due]
platform = atmelsam
board = due
framework = arduino
debug_tool = stlink
upload_protocol = sam-ba
upload_port = COM3 ;デバイスマネージャで確認して正しいポートを指定
```


2. デバッグしたいソースをVSCodeで開き、ブレークポイントを適当に貼ります(F9押下)。
![bp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/919305/64371962-33d3-dbc8-da99-efd093cec256.png)

3. 書き込みケーブル(投稿者の環境では下の画像のようなもの)、ST-Link V2をDue基板に接続します。
　　　Due　　　　　　　　ST-LinkV2
  PB28/TCK/SWCLK --- SWCLK
  PB31/TMS/SWDIO --- SWDIO
![DSC_1175.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/919305/560cda4c-f86d-dd45-ee98-0406ff164b20.jpeg)

4. Due基板のERASEボタンを押下してflashをクリアします(デバッグ用のプログラムをアップロードするため)。
5.  VSCodeの"Run"メニューからStart "Debugging"を選びます。
6.  プログラムのアップロードとデバッガの接続が終わるとブレークポイントでプログラムが停止します。このとき何か所かブレークを貼っていなくても止まってしまう箇所(OSの中)がありますが、それはF5でスキップしてください。
7.  希望の位置でブレークしたら成功です。F10でステップ実行、F11で関数の中に入る、F5で次のブレークポイントまで一気に実行、変数の書き換えなどいろいろ試してみてください。
![running.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/919305/b9e6f6d2-cf05-c388-8572-5b13770f1959.png)
元旦からはじめるビットコイン鉱夫

# まとめ
電気代とPCがロックされることを無視すれば、今のBTC価格ならGPUマシンが二台あれば月1万円以上は稼げそう

# きっかけ
時はちょうど2021年元旦、やねうら王さんの以下のツイートを偶然見つけてしまいました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">コロナで金融危機への不安が広がったためか、Bitcoinが高騰してしまい、現在1 Bitcoinが300万円を突破している。この相場だとGeForce RTX 3080で1ヶ月マイニングをすると18,500円ぐらいになる。そのせいか10万円前後の3080は、どこも即日完売。おかげで私は、将棋ソフト開発のための3080が買えねぇ。</p>&mdash; やねうら王 (@yaneuraou) <a href="https://twitter.com/yaneuraou/status/1344830416755150849?ref_src=twsrc%5Etfw">January 1, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

そんなに流れが来ているならせっかく買ったけど寝かせていた3080(Pytorchがまだうまく動かない)を使ってちょっくらビットコインを掘ってみようと思いました。鉱夫としての下積みはモンハンでそれなりにあります。

※そこまで細かく調べられていない＆まだ5日目なので、認識ずれがそこそこありそうなのはご容赦を。
※電気代については来月になったら考えるのでいったん無視して書いてます。赤字になる可能性もあります

# わからなかったことと回答
以下あまりにもわからなさすぎたので当時の頭の中をメモ的に起こしたもの

### マイニングってそもそも何？
- ビットコイン運営のために計算資源を提供して報酬としてビットコインをもらう行為
    - 確実にもらえるわけではなく、提供した計算資源に比例した確率に応じて付与される
    - ASIC(採掘専用機材) or PCを使って行う
        - PCの場合はGPUで計算を行うことが主流
- 自分で行うマイニングは大別すると2つがあるらしい
    - ソロマイニング
        - 元々の定義通りのマイニングをそのまま行う
        - イメージ：一人でマグロ釣り。釣れたらでかいけど、釣れなかったら収益はなし
    - プールマイニング
        - プラットフォームに自分の計算資源を提供し、それに応じた支払いを受ける
        - イメージ：誰かの漁船に乗って釣りに行く。労働力の提供に対して収益を得られる

### どちらにするか？
- マイニングファームとかの存在を考えると個人用PCはおそらくミジンコのようなものだと思われる
- やってみたけど収益0でしたの可能性があるとつまらない
- プールマイニングの方を選択
    - 運営が利益を出すために期待値はソロの方が上のはずだが、お遊びなのでサポートしてくれる誰かがいたほうがいい


### 具体的にどこでどうやってやるか？
- プールマイニングの性質上、運営者がサービスっぽい感じで提供していると考えTwitterを眺めてみたらNicehashというやつがよさそうと判断
    - Nicehashは仮想通貨採掘用の計算資源の売買プラットフォームらしい
- Nicehashでどのようにやるか？
    - アカウント作成し、彼らの提供しているソフトを使って計算資源の提供を行う

### Nicehashのソフトの選択肢
- Nicehash OS
    - https://www.nicehash.com/nhos-mining
    - LinuxベースのOS
    - イメージをUSBに焼き、自分のBTCアドレス（Nicehashが発行したもの）、PC名を設定してOSを起動するだけで勝手にやってくれる
- Nicehash Miner
    - https://www.nicehash.com/cpu-gpu-mining
    - Windowsにインストールするソフト
    - こちらも開始ボタンをおしとけばあとは勝手にやってくれる
    - CPUマイニングもやってくれる



# 実際にやってみた編
2台準備してちょくちょく動かしてみています

### マシンごとに積んでいるGPU
- 1号機
    - RTX 2060 Super(Cudaコア: 2176 消費電力: 160W)
    - RTX 2080ti(Cudaコア: 4352　消費電力: 260W)
- 2号機
    - RTX 3080(Cudaコア: 8704 消費電力: 320W)

### マシンごと収益
他の用途で使っているので、かなり途中で止ているため実際にこの金額が入ってきているわけではないのですが、1日つけっぱなしにした時の金額です。1BTC=300万円で計算しています


- 1号機
    - 546円/日ペース
- 2号機
    - 720円/日ペース

自分の↑の数値は公式が出している金額より10〜20%くらい低いですが、レート計算が適当、GPUの細かいスペックとか設定によるものでだいたい差を説明できそうです。
https://www.nicehash.com/profitability-calculator/nvidia-rtx-3080/nvidia-rtx-2080-ti


### マシンごとの温度
そもそものコア数もそうなんですが、30系の熱まわりの性能がすごいなという感想しかありません

- 1号機
    - Nicehash OSで動かして以下の温度
        - 2060 Super: 80℃
        - 2080ti: 88℃
            - 熱すぎ
            - 半年前に買ったばっかりなので30系の登場もあわせてこれの涙が止まりません。。
- 2号機
    - NicehashOSで動かして65℃
    - AfterBurnerで多少OCしてからNicehash Miningで動かして71℃


## やってみて原因特定まで至っていないもの
- 同じマシンでやっているはずが時間あたりの収益量が結構ばらつく
    - 最大と最小でだいたい3〜4倍くらい違う
    - 売買プラットフォームだから入札単価、採掘対象通貨が異なることによるものな気がする
- 夜のほうが収益量が多い
    - 寒いから？


## 今後
- もともとの買った用途のDNN系の学習にも使いたいのでもうちょいやったらたぶん引退します
    - 学習マシンの一種のベンチマークとして非常におもしろかった
- 2号機の熱が全然出ていないので内排気モデルの軽めのGPUを刺しても元の3080のパフォーマンスが落ちなさそうな気もする
    - そこは要実験
JavaScript (ES6) 基礎編　switch文とは？

こちらではJavaScript学習の備忘録となります。
プログラミング初心者や他の言語にも興味、関心をお持ちの方の参考になれば幸いです。
* * *
###switch文とは？

if文以外の条件分岐の方法。
ある値によって処理を分岐する場合に、switch文を用いる。


###switch文の書き方とは？

『 **switch ( 変数や定数などの条件の値 ) { 処理 }** 』

また、switch文の中に「 **case** 」を追加することで処理を分けることができる。

```javascript:script.js
// switch{}の中にcaseを追加して処理を分ける
switch (条件の値) {
  case 値1:
    // 「条件の値」 が 「値1」 と等しいときの処理
    break;
}
```
switch文では、分岐の数だけcaseを追加していく。

```javascript:script.js
// 分岐の数だけcaseを追加する
switch (条件の値) {
  case 値1:
    // 「条件の値」 が 「値1」 と等しいときの処理
    break;
  case 値2:
    // 「条件の値」 が 「値2」 と等しいときの処理
    break;
  case 値3:
    // 「条件の値」 が 「値3」 と等しいときの処理
    break;
}
```

**上記「break」について**

switch文では、breakが非常に重要。
breakとは、switch文を終了する命令である。
breakがないと、合致したcaseの処理を行った後、その次のcaseの処理も実行してしまう。
そのため、switch文を使うときはbreakを忘れないように気をつける。

###defaultとは？
switchの条件の値がcaseの値と一致したとき、その部分の処理が実行されるが、caseのどれにも一致しなかったとき、**default**の処理が実行される。
defaultは、if文のelseに似たようなものである。

```javascript:script.js
switch (条件の値) {
  case 値1:
    処理
    break;
  case 値2:
    処理
    break;
  case 値3:
    処理
    break;
  default:
    処理 // 「条件の値」が値1、値2、値3のどれとも一致しなかった場合に実行
    break;
}
```
* * * 
####おわりに
値の後ろのコロン「 : 」をセミコロン「 ; 」で記述しないように気をつける。
はじめてのswitch文だったので備忘録として記事にしました。
何かありましたらご指摘願います。
宜しくお願いいたします！！
KubernetesのJobとCronjobについて必死で調べた

- インフラ屋じゃないが、業務で必要になったため最低限調べてまとめた。
- 個人的なメモです。ミスがあったら教えてください。

- 21/07/24 kubernetesをガチ目に学んだので、追加でメモる。



## Cronjobとは


- Cronjobが定期的にJobを作成し、Jobがコンテナを作ってその中で処理を指定された実行する
- Jobは、指定時間になったらpodをその中のコンテナで指定された処理を行う。
    - ~~多分コンテナは毎回指定時間になるたびに作り直すけど、podは作り直すわけではないんだと思う~~
    - たまに超複する2つのJobが作られたり、Jobが作られなかったりすることもある → Jobはidempotentであるべき。




## Jobの詳細


- 先述した処理の「実行時間」「処理内容」「並列数や完了数」、、、などを保持しており、それに応じた処理を行う
- Jobのためにpodが作成される。そのJobが完了してもpodは消されない(terminated)になる。そのJobをdeleteしたらpodも消される。


<details>
<summary>non-parallel job と parallel jobがある</summary><div>

    - non-parallel jobは、completionの回数だけ逐次的にjobが繰り返し実行される
    - parallel jobは、
        - without worker は、completionとparallelismを指定する。
            - 今存在するpodが全て成功したらcompletionに達するなら、もうpodは作られなくなる。
            - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/61f60dfa-12eb-7296-77a4-91e31bca28f4.png)

        - with worker queue は、completionを指定しない。(1とみなされる)
            - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/b99ee56c-60fd-4d62-24a5-b9b4024c879a.png)

</div></details>





      



## CronJobを使ってJobを作る方法

- https://kubernetes.io/ja/docs/concepts/workloads/controllers/cron-jobs/ から引用している。
まとめると、

### (1) yamlファイルを書く。

```application/job/cronjob.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
```


### (2) このファイルを指定して`$kubectl create -f <ファイル名>`コマンドでCronJobリソースを作成する

(そもそも`$kubectrl create`コマンドとは、Create a resource from a file or from stdinするためのもの。このファイルのkind次第で、cronjobに限らず、podなりjobなりconfigmapなりを作成することもできる)


## その他メモ

- `kubectl get cronjob`でjobの一覧取得
- `kubectl get cronjobs/<cronjob名>`でcronjobの一覧のうち、cronjob名と一致するcronjobのみ表示
- `kubectl delete cronjob <cronjob名>`cronjobの削除


- `kubectl get job` でjobの一覧取得
    - (By default Kubernetes sets the Job history limits so that only the last three successful and last failed job are retained.)
- `kubectl get jobs/<job名>`でjobの一覧のうち、job名と一致するjobのみ表示
- `kubectl describe jobs <job名>`で指定されたjobの実行履歴を表示





## 参考

- [kubernetes公式ドキュメントJobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/#single-job-starts-controller-pod)
AzureSQLに書き込む

AutomateでMSN天気情報をExcel Onlineに取り込んでいたが、データ利用方法の変更に伴い、AzureSQLに取り込もうとしたら案外、よくわからなかったので備忘録として。
（わかれば何も問題ない ＆ 誰か記事にしていないのか私がたどり着けないだけか？）


コネクタ：SQLServer_行を挿入する(V2)

初期設定はコネクタウィンドウの右上の・・・をクリック
マイコネクションから新しい接続の追加
サーバー接続情報を入力
![スクリーンショット 2021-01-05 153617.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/d98b35d8-8347-4bc6-979f-3e39c0ea30c3.png)


オマケ
入力とDBのデータ型がマッチしないと、接続テストは成功するが
Bad Gateway で弾かれる
Basic認証で強制ログアウトさせて、再認証プロンプトを表示させる

# はじめに

Basic認証で強制的にログアウトさせ、別アカウントで再認証させる仕組みを作るのにすごく手間取ったのでメモを残しておきます。

# 結論

Ajaxで存在しないアカウントを指定し呼んで、その後location.hrefで遷移させればOK。

# ソースコード

jQueryの使用を想定。
axios等を使う場合は、脳内で置き換えてください。

```javascript
function logout() {
  $.get('https://logout@example.com').always(function() {  // https://example.com下がBasic認証必要と想定
    location.href = 'https://example.com';
  });
}
```

のような関数を作って、aタグのclickイベントとして呼び出せばOK

# 解説

まず前提として、Basic認証で認証情報の破棄は想定した作りになっていません。
そのため、ログアウト扱いにして再度認証のプロンプトを強制表示させるためには、ユーザーにブラウザを閉じて開き直してもらう以外には、前述のように別ユーザーとしてログインを試行すればOKです。

URLに
`https://user_name:password@example.com`
と入れることで、`https://example.com`に、ID`user_name`、パスワード`password`で認証した際と同じ挙動になります。

ここではlogoutという存在しないアカウントで試行をしたことにより、401レスポンスが返ってきて認証が破棄されます。
その後のlocation.hrefでページ遷移をすると認証情報が破棄されているので、再度プロンプトが表示されるというわけです。

Ajaxでsuccessやdoneではなくalwaysを指定しているのは、レスポンスコードが401のためsuccessを通らずfailedになるため、手抜きでalwaysを指定しています。

# 失敗談

当初はバックエンドのredirect処理で頑張っていましたがうまく転送されず断念。
フロントエンドだけで実装してみました。
Rails 初心者から抜け出すべく意識すること (※随時追加予定)

コードが動けばいいやの時期はそろそろ終わりたい
と思い、調べてメモする

また業務でおこなっていて指摘されることも書きます

##Ruby編

###メソッド
**1つのメソッドに複数のロジックを書かずに**別のメソッドに抽象化させる
ロジックや操作ごとにメソッドを作って、それを呼び出す形にする

例) if文で条件により操作を分岐させているときに、
2つ以上の操作をその**メソッド内に直接書く**のではなく、
操作ごとにメソッドを作って、それを呼び出す形にする

##定数
ロジックで用いる具体的な数字は**定数に格納**する

ロジックを作るときに、生の数字を書いてしまうと初見の人には伝わらない
**名前をつけた定数に格納**することで、その**数字が何を意味するのか分かる**

例) 税 **TAX = 10**
基本ストレージ **DEFAULT_STORAGE = 5** など

##Rails

###Routing
ルーティングの書く順番だけではなく**ネストできるところはする::

独自URLを設定しているルーティングは
resourcesにネストして書いた方が分かりやすくなる

```rb:config/routes.rb
Rails.application.routes.draw do
  resources :posts do
    resource :likes
  end
end
```
###Controller
ルーティングのresourcesにonlyやexpectオプションを付けることで、
どのリソースを使っているかを可視化する

クラスを継承してsuperメソッドを使う

publicメソッドはアクションのみに

処理の移動先は基本**Model**
Modelへの移動とリファクタリングを同時にするのが厳しそうな場合は、
アクションの中身を一旦全てModelに映してから
必要に応じてControllerに戻す、という手順を取るのも良い

###Model
ビジネスロジックはmodelに書く
concerns/に置くのはあくまで**複数のmodel間で共通する処理**、
**クラスをまたぐ処理**はconcernに

同ファイル内で**module化**する
複数のクラスで使いたい処理のまとまりはconcern化して、取り込むクラスにmix-inする

**複数のmodel**にまたがる処理は**service層**に書く

modelからデータを取り出す方法として**scope**を使う
その場合、where句を多用して条件を毎回書かなくても、**scopeに定義すればメソッド**のように使える


###View
共通パーツ化(**部分テンプレート、partial**)するのと、
viewにロジックを書かない(**ヘルパー、helper**)

**Helperメソッド**に定義する
viewにはなるべくロジックを書かない、見た目に関するメソッドはヘルパーに記載する

ページごとの**jsファイル**に分離する
erbファイルにスクリプトタグを仕込みかかない

viewに直接styleを記述しない

js専用のclassはjs-プレフィックスをつけて区別する

###その他
繰り返し使う文字列を**locale**に定義する
時刻のフォーマット等もlocaleを使い、strftimeは基本使わない
金額や距離、日付等も指定できる

なるべく短い書き方、リファクタ
→後置if、三項演算子、ぼっち演算子、nilガード、%記法など


##参考記事
https://qiita.com/TOSHIMITSU_MIYACHI/items/fec069bcdf23b6be7623
https://qiita.com/d0ne1s/items/fabbc0df7c273cf04fc3
https://qiita.com/shunsuke227ono/items/60de21690238aa25e9d4