OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoderログ：0088 - ABC 157 B

# 問題

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

## 問題文
> $3 \times 3$ のサイズのビンゴカードがあります。上から $i$ 行目、左から $j$ 列目の数は $A_{i,j}$ です。
> 続けて、 $N$ 個の数 $b_1,b_2,\ldots,b_N$ が選ばれます。選ばれた数がビンゴカードの中にあった場合、ビンゴカードのその数に印を付けます。
> $N$ 個の数字が選ばれた時点でビンゴが達成されているか、則ち、縦・横・斜めのいずれか $1$ 列に並んだ $3$ つの数の組であって、全てに印の付いているものが存在するかどうかを判定してください。

## 制約
> ・入力は全て整数
> ・$1 \le A_{i,j} \le 100$
> ・$A_{i_1,j_1} \ne A_{i_2,j_2}~((i_1,j_1) \ne (i_2,j_2))$
> ・$1 \le N \le 10$
> ・$1 \le b_i \le 100$
> ・$b_i \ne b_j~(i \ne j)$

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

# 回答
## 回答1 (AC)
ビンゴカードがビンゴになっているかを調べる問題です。ビンゴカードの i 行目 j 列目のマス目の値を vector 型変数 a の a.at(i).at(j) に保持し、その値が選ばれていれば 1、選ばれていなければ 0 に置き換えた後、縦・横・斜めに 1 が並んでいるかを調べていけば良いでしょう。コードは以下のようになりました。

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

int main() {
  vector<vector<int>> a(3,vector<int>(3));
  for ( int i=0; i<3; i++ ) {
    for ( int j=0; j<3; j++ ) {
      cin >> a.at(i).at(j);
    }
  }

  int n;
  cin >> n;

  vector<int> b(n);
  for ( int i=0; i<n; i++ ) {
    cin >> b.at(i);
  }

  vector<int> bingo(101,0);
  for ( int i=0; i<n; i++ ) {
    bingo.at(b.at(i)) = 1;
  }

  for ( int i=0; i<3; i++ ) {
    for ( int j=0; j<3; j++ ) {
      a.at(i).at(j) = bingo.at(a.at(i).at(j));
    }
  }

  string answer = "No";
  for ( int i=0; i<3; i++ ) {
    if( a.at(i).at(0) && a.at(i).at(1) && a.at(i).at(2) ) {
      answer = "Yes";
    }
    if( a.at(0).at(i) && a.at(1).at(i) && a.at(2).at(i) ) {
      answer = "Yes";
    }
  }
  if( a.at(0).at(0) && a.at(1).at(1) && a.at(2).at(2) ) {
    answer = "Yes";
  }
  if( a.at(0).at(2) && a.at(1).at(1) && a.at(2).at(0)==1 ) {
    answer = "Yes";
  }
  
  cout << answer << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc157/tasks/abc157_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2020/03/02/000808)
回答1と同じ方針でした。

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

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0087 - ABC 091 B](https://qiita.com/RoadLynton/items/e0e71defea0554a38874)
AtCoderログ：0087 - AGC 013 A

# 問題

https://atcoder.jp/contests/agc013/tasks/agc013_a

## 問題文
> 長さ $N$ の配列 $A$ が与えられます。$A$ を何箇所かで切って、$A$ の連続した部分であるようないくつかの数列に分けます。この時、分けられたあとの数列は全て、単調非減少または単調非増加な列になっている必要があります。最小で何個の数列に分ければ良いかを求めて下さい。

## 制約
> ・$1 \le N \le 10^5$
> ・$1 \le A_i \le 10^9$
> ・$A_i$ は全て整数である

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第09問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-9-%E5%95%8F--abc-049-c---daydream-300-%E7%82%B9))

# 回答
## 回答1 (AC)
まず、単調非減少とは、値が増加することがないと言うことで、同じ値が続くことは許容しています。また、単調非増加とは、値が減少することがないと言うことで、やはり同じ値が続くことは許容しています。

設問では、もとの数列を切って単調非減少または単調非増加な数列を作っていくのですが、切り分ける回数を最小にしたいわけです。そこで、もとの数列を左から順番に見ていき、単調非減少または単調非増加が途切れたところで数列を切っていけばよいでしょう。

もとの数列では同じ値が続くことがあり得ますが、同じ値は数列を切り分ける回数に影響しないので、考えやすいように、コードでは無視して考える(同じ値は連続して書き込まない)ことにします。このとき、数列の最初の2項を見れば、最初の部分が単調増加か単調減少かを判定できるので、その状況が続くまでインデックスを増加させ、続かなくなったところで数列を切れば良いでしょう。コードは以下のようになりました。

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

int main() {
  int n;
  cin >> n;

  int prev = 0, curr;
  vector<int> a;
  for ( int i=0; i<n; i++ ) {
    cin >> curr;
    if ( prev!=curr ) {
      a.push_back(curr);
    }
    prev = curr;
  }

  int cut = 0, index = 0;
  while ( index<(int)a.size()-1 ) {
    int coef = 1;
    if ( a.at(index)>a.at(index+1) ) {
      coef = -1;
    }
    while ( index<(int)a.size()-1 && coef*a.at(index)<coef*a.at(index+1) ) {
      index += 1;
    }
    if ( index<(int)a.size()-1 ) {
      cut += 1;
    }
    index += 1;
  }
  
  cout << cut+1 << endl;
}
```

個人的にはコードが整理し切れていない気がしているのですが、現時点では改良法が思いつかないので、あきらめることにしました。良いアイディアが浮かべば、後日、加筆するかも知れません。

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/agc013/tasks/agc013_a/editorial)  [公式解説](https://img.atcoder.jp/agc013/editorial.pdf)
回答1と同じ方針でした。左から増加列・減少列を最大限に選択していけば良いことの証明が紹介されていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0086 - パナソニックプログラミングコンテスト2020 B](https://qiita.com/RoadLynton/items/b6e3bc9f1803375b0746)
- 次の記事 → [AtCoderログ：0088 - ABC 157 B](https://qiita.com/RoadLynton/items/cf6cf0eacae9ac98adb7)
nuxt.jsでVuetifyを使用する方法

# Vuetifyについて
# 動作環境

* Visual Studio Code 1.43.2
* Windows 10 Pro 20H2

# 実装

1. Nuxt.jsのプロジェクトを作成
  * Package managerはNpmを指定し、それ以外はデフォルトで設定

    ~~~
   $ npx create-nuxt-app use-vuetify
   ? Project name: use-vuetify
   ? Programming language: JavaScript
   ? Package manager: Npm
   ? UI framework: None
   ? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert se
   lection)
   ? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert sele
   ction)
   ? Testing framework: None
   ? Rendering mode: Universal (SSR / SSG)
   ? Deployment target: Server (Node.js hosting)
   ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert 
   selection)
   ? What is your GitHub username? wataru-sakuraba
   ? Version control system: Git
    ~~~

1. 動作確認

    ~~~
    $ cd use-vuetify
    $ npm run dev
    ~~~
    * 上記のコマンドを実行し、localhost:3000にアクセスすると、以下のようなNuxt.jsのページが表示されます![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/957268/2971aeaf-7859-4bd1-db46-6532815642a5.png)

1. プロジェクトにVuetifyをインストール

    ~~~
    $ npm install --save-dev @nuxtjs/vuetify
    ~~~

1. nuxt.config.jsを修正

    ~~~js:nuxt.config.js
    export default {
      ・・・
      // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
      buildModules: [
        '@nuxtjs/vuetify',
      ],
    }
    ~~~

1. Vuetifyを使用したコードを追加

    ~~~vue:index.vue
    <template>
      <v-container>
        <v-row justify="center">
          <v-col cols="6">
            <v-card>
              <v-card-title>Hello, Vuetify!</v-card-title>
            </v-card>
          </v-col>
        </v-row>
      </v-container>
    </template>

    <script>
    export default {}
    </script>

    ~~~

1. ローカルサーバーを再度立ち上げると、以下のような画面が表示されます

    ~~~
    $ npm run dev
    ~~~

    ![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/957268/533de325-b90e-8d2d-40b6-90d6c59b5a8b.png)

# 感想
* Vuetifyは初めて使いましたが、サンプルなども豊富にあり、アイコンなども簡単に使用できるため、WEBページ作成には非常に便利だと思います。


# 参考
https://blog.proglearn.com/2020/04/07/%E3%80%90%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E6%9C%89%E3%80%91nuxt-js-%E3%81%B8%E3%81%AE-vuetify-%E5%B0%8E%E5%85%A5%E6%89%8B%E9%A0%86%E3%82%92%E8%A7%A3%E8%AA%AC%EF%BC%81/
アプリリリースしました　「ツケ台帳」

play storeにて、私が初めて開発したアプリ
[ツケ台帳](https://play.google.com/store/apps/details?id=com.chelak.tsuke_daicho)をリリースしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/c7034df4-e967-3c04-382b-1948335233bf.png" width="160" height="326" class="jop-noMdConv"><a href='https://play.google.com/store/apps/details?id=com.chelak.tsuke_daicho&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Google Play で手に入れよう' src='https://play.google.com/intl/en_us/badges/static/images/badges/ja_badge_web_generic.png'/ width="300"></a>


## 概要
グループでのツケ払いを記録・共有・グラフ化します。機能自体は実際に使っていたもので、もともとはexcelを使って管理していたのですが、勉強を兼ねてアプリ化を試みました。

―複数グループの作成、グループごとのツケの管理
―グループメンバーごとのツケ額、支払ったメンバーの記録
―グループ内のメンバーごとにツケ総額の可視化
―ツケの内容変更時の通知

といった機能があります。
イチからいろいろ勉強しながらだったので開発期間に１か月強かかってしまってます。

## 使い方

①アカウント作成
このアプリを利用するにはアカウントの作成が必要です。
アプリを起動するとログイン画面になるので、アカウント名とメールアドレスを登録してください。
ログインするとメイン画面に移動します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/83da8260-40d8-29d8-50ee-2b8459fa8587.png" width="160" height="326" class="jop-noMdConv">

②グループ作成
ツケの金額はグループごとに管理します。メイン画面右下の「＋」ボタンから新しいグループの作成が可能です。
招待したいメンバーのIDを入力するかQRコードを読み取ることでグループへの招待が可能です。自分のIDおよびQRコードは”情報”タブから確認できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/b04d845c-8fc5-9e9b-7ada-e3d55d67d01e.png" alt="メイン画面.png" width="166" height="297">

③ツケ記録作成
メイン画面に表示されたグループをタップすることでツケ記録画面に移動できます。メイン画面右下の「＋」ボタンから新しいツケ記録の作成が可能です。
グループメンバーのツケ総額は”解析”タブにグラフ化されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/4e125c57-a469-e089-fdca-9e7e8e4aa860.png" alt="ツケリスト.png" width="162" height="288">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/1ef76c7f-2d55-dc07-ceb2-35c7023b6762.png" alt="ツケアナリシス.png" width="165" height="293">

※
自分の所属するグループやツケが作成・編集・削除されると、メイン画面の”通知”タブに通知が送られます。
通知をクリックすることで詳細を確認したり、削除したツケを元に戻したりすることが可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/cbe2dbdf-03a5-6caa-e9f0-926cd519b820.png" alt="通知.png" width="165" height="293">


感想等頂けると嬉しいです。DLはこちらから↓
[ツケ台帳](https://play.google.com/store/apps/details?id=com.chelak.tsuke_daicho)
可読性について(PART1(表面上の改善))

# 概要
- ペーペーエンジニアの覚書
- リーダブルコードのPrat1をまとめる

# リーダブルコードで一貫して伝えていること
第三者が自分のコードを読んで、理解する時間を最短にすること
それが「優れた」コードである

# なぜ可読性が必要なのか？
 動かすのはPCだが、「読むのは人間」であり、
プログラミングのほとんどの時間はコード読む時間であるため 

# 可読性が低いと何が起きるのか？
- 読んで理解するまでに時間がかかる
 - イコール実装までに余計な工数がかかる
- バグが混入しやすい
 - この変数はどんな値が入っているのが正解なのか？
 - この関数はどんな値が返ってくる関数なのか？
- デバッグに時間がかかる
- 改修や変更に時間がかかる

# そもそも読みやすいとは？
- 読みやすさの基本定理
 - 第三者が自分のコードを読んで理解する時間を最短にすること
- 優れたコードとは？
 - 「読みやすい」コードを書くことは、
 - 「理解しやすい」コードを書くことであり、
 - その結果として「優れた」コードに繋がる
- 理解するとは？
 - 変更を加えたり、バグを見つけたりできること

# リーダブルコードで書かれている改善策
- 表面上の改善策
 - 適切な名前
 - 優れたコメント
 - フォーマット
- ループとロジックの単純化
 - 制御フローを読みやすくする
 - ネストを浅く
 - 早期return
- コードの再構成
 - 1度に1つのことを(単一責任の原則)
 - 短いコードを書く(KISSの原則/YAGNIの原則)

# 今回取り上げる改善策 PART1
- 適切な名前
- 目に優しい美しさ
- コメントすべきこと/すべきで「ない」こと

# 適切な名前（命名）
- 明確で正確な単語を選ぶ


```typescript
getSize()    // どこのサイズを指しているか曖昧なためNG
getHeight()  // 明確で正確なためOK
```
- get/fetch/download 状況によって適切で明確なものを選ぶ
- 汎用的な名前は避ける

```typescript
retval      // NG 
sumSquares  // OK

// ただし、情報の一時的な保管で生存期間が短いケースでは汎用的な名前が役に立つこともある(ループイテレータなど)
```

- 抽象的な名前よりも具体的な名前を使う(例：値の単位など)

```typescript
delay    // 何の単位か明確でないためNG
delayMs  // 単位があり明確なためOK
```

- 重要な属性を追加する

```typescript
password              // 重要な属性が抜けているためNG
plaintextPassword     // 属性が明確なためOK

 comment              // 重要な属性が抜けているためNG
 unescapedComment     // 属性が明確なためOK

// 全てに属性を追加するのではなく、「バグ」の元になりそうな所へ追加する
```

# 適切な名前（誤解されない名前）
- filter = 濾過する
- filterは条件にあったものを「選択(select)」なのか「除外(exclude)」なのか不明確
- 限界値はmin/maxを使う
 - 未満(限界値を含まない)なのか以下(限界値を含む)なのか
- booleanはis/has/can/shouldを使う
 - trueとfalseの意味を明確にするため

# 美しさ
- なぜ美しさが必要なのか
 - 優れたコードは目に優しく、見た目が美しいコードの方が使いやすい
 - 美しさと優れた設計は関連しており、リファクタリングがうまくいくようになる
- 3つの原則
 - 読み手が慣れているパターンと一貫性のあるレイアウトを使う
 - -重要度順で並んでいる
 - 似ているコードは似ているように見せる
   - -改行位置やネスト(現在はフォーマッターが主流)
 - 関連するコードをまとめてブロックにする
  - - 似ている考えをグループ分けしてまとめる

# コメント1
- コメントの目的
 - 書き手の意図を読み手に知らせる
 - コードを書いている本人は、頭の中に大切な情報があるが、読み手はその情報が失われてしまう
- コメントすべきで「ない」こと
 - 価値のないコメントは記入しない
- 価値のないコメントとは
 - コードからすぐにわかることはコメントに書かない
 - 例：getHeight() // 高さの取得
 - コード以外の「新しい情報」を提供しているか
 - 背景や経緯
 - コメントのためのコメントはしない
 - コードがおかしい可能性、ひどいコードにはコメントではなく名前を変えるべき
 - コード自体が読みやすいことが大前提

# コメント2
- 自分の考えを記録する
 - 優れたコメントとは「考えを記録する」ためのものである
 - コードは絶えず進化しているので、その過程での欠陥を文章化すべき
 - TODOやFIXMEなどのアノテーションを活用(影響範囲が大きい時など)
 - 基本その場で改善できるところは改善する(ボーイスカウトの原則)
 - 定数には背景となるコメントを残す
 - 定数の定義は、その定数が何をするのか、なぜその値を持っているのかという「背景」が存在する場合が多い
- 読み手の立場になって考える
 - 質問されそうなことを想像する
 - 関数の内部にロジック分けしたブロック毎へ「要約」したコメントをする
- コメントは正確で簡潔に
 - 「これ」「それ」絶対NG
 - 短く単純で直感的な言い回し

# まとめ
- 重要度は命名、美しさ、コメントの順
- そもそもコードが読めないのであればコードが悪い、コメントはあくまで補足
- 可読性が誰に向けてのものなのかで変わるが、ここでは言語が読めて実装できる人へ対してとする(例：JS/TS/Vueの案件では最低限これらを理解していること)
- リーダブルコードで一貫して言われていることは「第三者が自分のコードを読んで、理解する時間を最短にすること。それが「優れた」コードである」
駆け出しプログラマ向け、実務で使える「効率性」ってなに？

# 前置き
こちらの記事は筆者が備忘録的にまとめたものです。
せっかく来てくれた読者の皆様にとっても役に立つように意識して書いてみましたので、
是非最後まで読んでみてください。では、Let us begin!

# 効率性(Efficiency)
こうりつせい とは
## 辞書的な説明
### 日本語だと
> 経済学において、効率性（こうりつせい）とは、資源・財の配分について無駄のないことを意味する。

や効率の説明として

> 機械が有効に働いてなした仕事の量とそれに供給した総エネルギーとの比率。また、仕事の能率。

### 英語だと
> the state or quality of being efficient.

### IT用語的には
> 目的達成の際にリソースを無駄に消費しないことを意味する。この場合のリソースとはメモリ使用量とプロセッサ使用時間である。

## つまり
いかに寄り道や無駄な仕事をせず目的達成ができるか、その状態やクオリティ、みたいなことろでしょうか
IT用語としては、これ↓に尽きそうです。

>目的達成の際にリソースを無駄に消費しないこと

# 効率性をコードに適用した例
ある名前がリストに登録されているかを確認し、登録状態に応じて何かの処理をしてくれる関数、を例にしてみましょう。

## 適用前（効率性 改善前のコード）
```javascript:javascript
const registeredList = ["Haruka", "Toshi", "Yohei"]; // 登録されている名前のリスト

// 引数に渡された名前をもとに何かする関数
function doSomething(searchName) {
  let isFound = false; // 見つかったかどうか。初期値は false。
  for (const name of registeredList) {
    if (name === searchName){
      isFound = true; // 見つかったから true
    }
  }
  if (isFound){ // true のときの処理
    console.log("do something ...")
  }
  else { // false のときの処理
    console.log("do something else ...")
  }
} 

doSomething("Haruka") // 処理の呼び出し
```
### 解説
引数の名前(`searchName`の値)が、`registeredList`に存在するかどうかを確認し、存在する(配列内の文字列と一致する)とき、 
`isFound` を `true` にし、そうでない場合は初期値の `false` のままになっています。

その後、if分岐で isFound の値に応じて何かしらの処理をしてくれています。

### 問題点
上記の例では登録されている名前が3つしかないので、そこまで問題はなさそうです。

しかし、もし登録されている名前が 100,000個 など沢山存在する場合はどうでしょうか？
今のままだと、検索対象の名前が100,000個の名前リストのうち、1つ目の名前と一致したとしても、
残りの99,999個の要素と一致するかどうかの処理を続行してしまいます。

もう見つかっているのにまだ仕事をし続けているなんて、メモリを無駄に使っていますし、
プロセッサも無駄に長い時間働かされて、かわいそうですよね。効率性があるとは言えなそうです。

では効率性を高めてみましょう。

## 適用後（効率性 改善後のコード）
### やること
- 名前が一致した時点で、 break で for文の処理から抜け出す

```javascript:javascript
const registeredList = ["Haruka", "Toshi", "Yohei"];

function doSomething(searchName) {
  let isFound = false;
  for (const name of registeredList) {
    if (name === searchName){
      isFound = true;
      break; // <--- これだけ追加
    }
  }
  if (isFound){
    console.log("do something ...")
  }
  else {
    console.log("do something else ...")
  }
} 

doSomething("Haruka") // 処理の呼び出し
```
いかがでしょうか。（コード自体はもっと改善できそうですが）
一致する名前が見つかって `isFound` が `true` に変わった直後にfor文を抜け出すようになりました。

つまり、"Haruka" という名前が見つかった時点で、残りの名前チェックをする必要がなくなったのです。

今回は簡単な例で、簡単な変更ですが、正直バカにできません。
大規模なデータを扱うようなシステムであればこの `break` 一つで、
ユーザがシステムを使い続けてくれるか、離れてしまうか、なんて話になるかもしれないのです。

# 今回の効率性改善によるメリット
- 必要最低限だけの処理を行うようになりました（効率性UP）
    - 無駄なメモリ消費と、プロセッサの使用時間が改善されました。

# まとめ
- 効率性とは、目的達成の際にリソースを無駄に消費しないこと
- 効率性は、リソースを無駄に消費しないだけでなく、システムを使ってくれるユーザの満足度にも影響してくる。

# 参考
- [wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E5%93%81%E8%B3%AA#%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E5%93%81%E8%B3%AA%E3%81%AE%E8%A6%81%E5%9B%A0)
- [weblio](https://www.weblio.jp/content/%E5%8A%B9%E7%8E%87%E6%80%A7)
- [Microsoft Word - COMP1405_Ch10_CodeEfficiency](http://people.scs.carleton.ca/~lanthier/teaching/JavaNotes/COMP1405_Ch10_CodeEfficiency.pdf)
Markdownのチートシート

## 目次
#### Markdown
* [見出し](#見出し)
* [箇条書き](#箇条書き)
* [箇条書き(番号)](#箇条書き(番号))
* [引用](#引用)
* [pre記法](#pre記法)
* [code記法](#code記法)
* [強調](#強調)
* [水平線](#水平線)
* [リンク](#リンク)

#### GFM
* [URL](#URL)
* [取り消し線](#取り消し線)
* [pre記法](#pre記法-1)
* [表](#表)

# Markdown

## 見出し
#### 書き方

    # サンプル
    ## サンプル
    ### サンプル
    #### サンプル
    ##### サンプル
    ###### サンプル
    #######  サンプル

#### 表示
# サンプル
## サンプル
### サンプル
#### サンプル
##### サンプル
###### サンプル
#######  サンプル (#は6個まで)

## 箇条書き
#### 書き方

    - 1
        - 1-1
            - 1-1-1
            - 1-1-2
        - 1-2
    - 2
    - 3

#### 表示
- 1
    - 1-1
        - 1-1-1
        - 1-1-2
    - 1-2
- 2
- 3

## 箇条書き(番号)
#### 書き方

    1. A
        1. B
        1. C
    1. D
    1. E
####表示
1. A
    1. B
    1. C
1. D
1. E

## 引用
#### 書き方
    > A
    > B
    >> C
    >> D
####表示
> A
> B
>> C
>> D

## pre記法
#### 書き方

    (スペース4個もしくはtab)A
        B
        C

#### 表示

    A
    B
    C

## code記法
#### 書き方

    aaaaaa`aaa`aaa
#### 表示
aaaaaa`aaa`aaa

## 強調
#### 書き方

    *italic*
    _italic_
    **bold**
    __bold__
    ***italic and bold***
    ___italic and bold___
#### 表示
*italic*
_italic_
**bold**
__bold__
***italic and bold***
___italic and bold___

## 水平線
#### 書き方

    ***

    ___

    ---

    *    *    *

#### 表示

***

___

---

*    *    *

## リンク
#### 書き方

    [Google](https://www.google.co.jp/)
あるいは

    [google1][google]
    aaa
    [google2][google]

    [google]: https://www.google.co.jp/
#### 表示
[Google](https://www.google.co.jp/)

[google1][google]
aaa
[google2][google]

[google]: https://www.google.co.jp/

***
# ここからGitHub Flavored Markdown(GFM)
## URL
#### 書き方
~~~
https://www.google.co.jp/
~~~
#### 表示
https://www.google.co.jp/

## 取り消し線
#### 書き方
~~~
~~aaaa~~
~~~
#### 表示
~~aaaa~~

## pre記法
#### 書き方

    ~~~
    aaa
    ~~~
あるいは

    ```
    aaa
    ```
シンタックスハイライト

    ~~~ruby
    class Hoge
      def hoge
        print 'hoge'
      end
    end
    ~~~
#### 表示
~~~
aaa
~~~
あるいは

```
aaa
```

シンタックスハイライト

~~~ruby
class Hoge
  def hoge
    print 'hoge'
  end
end
~~~

## 表
#### 書き方
~~~
|header1|header2|header3|
|:--|--:|:--:|
|align left|align right|align center|
|a|b|c|
~~~

#### 例
|header1|header2|header3|
|:--|--:|:--:|
|align left|align right|align center|
|a|b|c|

[return to 目次](#目次)
【Laravel8】envにAPP_KEYが設定されているのに「No application encryption key has been specified.」のエラーが表示される時の対応方法

# 結論

`bootstrap/cache/config.php` に保持してる暗号化キーの項目にenvの`APP_KEY`の値が反映されていなかった。
(キャッシュが更新されていなかった)

`php artisan config:cache` でキャッシュを更新することでエラーを解消。


# 何が起きたか

社内のLaravelアプリのバージョンを5.7→8系に上げている作業中に事は起きた。
細かい動作確認は後で行うつもりでとりあえずLaravelが8系で動くように更新。
雰囲気で動作しているのを確認した後に、公式謹製のDockerライブラリであるSailをインストールして、動作確認をしていた。
Composer経由で無事にインストールが済んだので `sail up -d` でコンテナを立ち上げ画面を確認してみた。

すると、下記のようなエラーが出てきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/8befa5e9-daff-35fb-aac2-e4ab1615a102.png)

「No application encryption key has been specified.」だと？嘘だろ？
このエラーはenvファイルのAPP_KEYに値が設定されていない時によく見るエラーだ。
そんな初歩的なミスをする理由がないと思い、envファイルを確認してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/4cd3b02d-9f42-7ca1-a653-6061be156244.png)

しっかり値が入っている。
なにかの間違いかと思い、ブラウザのキャッシュを消しもう一度アクセスしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/a497631c-4837-8c68-0eb0-1208c8949985.png)

エラーはまだ表示されている。
なぜだ？ワケがわからないよ。。。
Laravelがenvファイルを読み込めていない可能性を考え、tinkerでAPP_KEYの値を読み込んでみる。
なんならconfigからも値を確認してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/946c7b6c-a104-93d9-3aad-a7f479cef967.png)

envファイルからもconfigからもちゃんと値が取れている。
なのに画面上ではキーが無いと怒られている。
どうしてだ。なぜなんだ。。

腑に落ちない思いをしながらも色んな記事を漁る。
するとLaravelのキャッシュに関する、ある記事を見つけた。

記事内にある下記のコマンドを実行してみる。

```
composer dump-autoload
php artisan clear-compiled
php artisan optimize
php artisan config:cache
```
> [Laravel キャッシュクリア系コマンドなど
](https://qiita.com/Ping/items/10ada8d069e13d729701#%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E8%B8%8F%E3%81%BF%E8%BE%BC%E3%82%93%E3%81%A0%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%82%AF%E3%83%AA%E3%82%A2%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)の「ちょっと踏み込んだキャッシュクリアコマンド」より引用

なんとエラーが解消された！！！
と、同時に今回のエラーの原因がLaravelのキャッシュにあることが分かった。


# 解説してみる

## タイトルの現象が発生していた真の原因とは？
エラーが発生していた時点では、envからAPP_KEYは確かに読み込めていた。
しかし、Laravel上で保持しているキャッシュを参照してしまっていたかつ、キャッシュ上のキーには値が設定されていなかった為エラーが発生していた、という訳だ。

具体的には、`bootstrap/cache/config.php` にLaravelのキャッシュを保持していてその中の `app.key` にブランクが設定されていたのだ。
↓の画像はキャッシュが正しく設定された状態の `bootstrap/cache/config.php`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/34613685-9aa9-2042-514d-3f9d5bb99bc7.png)

キャッシュの理解度が甘かった自分の所為でもあるのだが、これに気づくのが結構難しかった。

## キャッシュの更新方法

ところで、参考にした記事のコマンドを実行して解決には至ったものの、そのコマンドで何が行われていたのかをしっかり抑えて置かなければならない。

> php artisan config:cache

特にこれ。
使ったことはあるけど、イマイチ理解してなかった。
「あーキャッシュしてくれるんでしょ？configを」
といった程度の雑な理解度。

コマンド実行後のファイル(`bootstrap/cache/config.php`) を見てみると全貌が見えてくる。
ただ配列が定義され、それがreturnされているだけのファイルだが、よく見ると、

- app
- auth
- broadcasting
- cache
- database

のように既視感のある名称がキーになっている。
そう、これはconfig配下に配置された各種configファイルを1つにまとめたファイルだったのだ。

こいつら↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/d2059487-c0a4-ef07-c195-e53e37a259da.png)


ここにピンと来れば、配列内部の構造の意味もわかるし、Laravelがconfigファイルをどの様にキャッシュに持たせているのかも理解できる。

つまり `php artisan config:cache` コマンドは、configディレクトリ配下に定義されたconfigファイル達を `bootstrap/cache/config.php` ファイルに1つの配列として定義する処理が行われていたのだ。


# おわりに
今後、envファイル関連のエラーに遭遇した場合は、envファイルだけでなくキャッシュファイルも併せて確認することを肝に銘じた。
Windows10環境でQEMU/Raspberry PiをホストOSと通信できるようにするまで

#やりたいこと
WSL※環境でQEMUとホストOS間でL2レベルの通信を可能にしたい．
※WSL1/WSL2どちらでもよい．

#試行錯誤して実現できたこと

Windows版のQEMUをWSL1上で実行し，ホストOS とゲスト OS 間で ping できた．

https://twitter.com/kanetugu2020/status/1428907968016261127

#環境情報

* ホスト OS
 * Windows10 home
* QEMU
 * Windows 版 QEMU
      * https://qemu.weilnetz.de/w64/
      * 上記のから以下をダウンロードしインストール．
      * qemu-w64-setup-20210810.exe  
      * 補足：WSL1/ubuntuからアクセスしやすくするために，`/mnt/c/qemu` にインストール．
* ネットワークインタフェース
 * Windows 版 TAPインタフェース
      * https://openvpn.net/community-downloads/
      * 上記のから以下をダウンロードしインストール．
      * Windows 64-bit MSI installer
      * インストール後のTAPインタフェース作成手順は以下を参照
      * https://blog.k-san.info/raspios-arm64-on-qemu-on-win#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%BA%96%E5%82%99  
* ゲスト OS
 * Qemu kernel for emulating Rpi on QEMU 
       * https://github.com/dhruvvyas90/qemu-rpi-kernel
       * 上記から以下をダウンロード
       * kernel-qemu-4.19.50-buster
       * versatile-pb.dtb
 * イメージファイル 
       * http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2019-07-12/
       * 上記から以下をダウンロードし，解凍(2019-07-10-raspbian-buster.img)．
       * 2019-07-10-raspbian-buster.zip

# QEMU実行手順

##ダウンロードしたファイルを配置する．

```
$ ls /mnt/c/project/qemu/
2019-07-10-raspbian-buster.img
kernel-qemu-4.19.50-buster
versatile-pb.dtb
```

## qemu を起動する

```
/mnt/c/qemu/qemu-system-arm.exe \
        -M versatilepb  \
        -cpu arm1176 \
        -m 256 \
        -net tap,ifname=tap0 -net nic \
        -hda 2019-07-10-raspbian-buster.img \
        -serial stdio -usb -device usb-kbd \
        -dtb versatile-pb.dtb \
        -kernel kernel-qemu-4.19.50-buster \
        -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw"  \
        -no-reboot
```

以上で，デモ動画にあるような感じでホストOS/ゲストOS間でpingできるようになりました．

起動後，ログイン用のプロンプトが出ますが，以下で入れます．

```
username: pi
password: raspberry
```

なお，ゲストOSのIPアドレス設定は，以下の記事の内容に従って設定しました．

https://blog.k-san.info/raspios-arm64-on-qemu-on-win#IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E6%8C%87%E5%AE%9A-2

#補足
Windows10のセキュリティ設定でICMPの受信を有効化しないと，ゲストOSからホストOSへpingが通りません．この場合の対処方法は以下を参照ください．

https://memo.morelents.com/ping-one-way/


#実現できなかったこと

現時点(2021/08/21)では，WSL/Ubuntu版のQEMUはだめでした．

下記の記事にある通り，WSL2でKVMが利用できれば実現できるはずなのですが，自分の環境では再現できませんでした．．．

https://blog.bobuhiro11.net/2020/11-04-kvm-on-wsl2.html
Next.js メモ

Nextjsプロジェクト作成まで

# 利用技術
- Next.js
- TypeScript

プロジェクト作成

```
$ npx create-next-app <project-name>
```
TypeScript導入

```
$ touch tsconfig.json
$ yarn add --dev typescript @types/react @types/node
$ yarn dev
```

既存ファイルの拡張子を変更

```
$ find pages -name "_app.js" -or -name "index.js" | sed 'p;s/.js$/.tsx/' | xargs -n2 mv & \
  find pages/api -name "*.js" | sed 'p;s/.js$/.ts/' | xargs -n2 mv
```
Vue 3 setupメソッド


#Vue3で追加されたsetupメソッド
vue 3で導入されたComposition APIのsetupメソッドを使った時の備忘録

##Vue 2.5までの書き方
コンポーネントにdata、methods、computed、createdを区別していた。

```Vue.js
<template>
  <div></div>
</template>

<script>
export default {
  data() {

  },
  methods: {

  },
  computed: {

  },
  created() {

  },

}
</script>

<style>

</style>
```


##Vue3の書き方

```vue.js
<template>
  <div>ComositionTest</div>
  <div>
    <p>商品名: {{ item.name }}</p>
    <p>単価: {{ item.price }}</p>
    <p>合計: {{ totalPrice }}</p>
  </div>
  <div>数量</div>
  <button @click="decrement">-</button>
  <button @click="increment">+</button>
</template>
```
setupメソッドではdata、computed、methodsを区別することなく、まとめて書くことができます。

```js
<script>
// import { reactive, computed } from 'vue'
import { reactive } from 'vue'
import useCounter from '@/composables/useCounter'


export default {
  setup() {
    const item = reactive({
      name: '商品名',
      price: '100',
      amount: '0'
    })

    const { increment, decrement, totalPrice} = useCounter(item)
    return {
      item,
      increment,
      decrement,
      totalPrice
    }
  }
}
</script>
```
Yen to Int in python3

* source

```python
def _yenToInt(src):
    print("src:",src)
    ret = 0
    ss = src.split("千")
    if len(ss) > 1:
        ret = ret + int(ss[0])*1000
        src = ss[1]
    ss = src.split("百")
    if len(ss) > 1:
        ret = ret + int(ss[0])*100
        src = ss[1]
    ss = src.split("十")
    if len(ss) > 1:
        ret = ret + int(ss[0])*10
        src = ss[1]
    if src != "":
        ret = ret + int(src)
    return ret

def yenToInt(money):
    print("money:",money)
    money = money.replace(',','')
    money = money.replace('円','')
    ms = money.split("兆")
    if len(ms) > 1:
        sub = int(_yenToInt(ms[0]))*1000000000000
        if ms[1].strip() == "":
            return sub
        else:
            return sub+yenToInt(ms[1])
    ms = money.split("億")
    if len(ms) > 1:
        sub = int(_yenToInt(ms[0]))*100000000
        if ms[1].strip() == "":
            return sub
        else:
            return sub+yenToInt(ms[1])
    ms = money.split("万")
    if len(ms) > 1:
        sub = int(_yenToInt(ms[0]))*10000
        if ms[1].strip() == "":
            return sub
        else:
            return sub+yenToInt(ms[1])
    #print(money,int(money))
    return int(_yenToInt(money))
```

* execution example

```sh
# python3 test.py '2,300万円'
23000000
# python3 test.py '37億5500万円'
3755000000
# python3 test.py '11億7719万円'
1177190000
```
segueを使って前の画面へ遷移する

# はじめに
segueを使って画面遷移をしているときに、画面を戻したい場面があったのですが、
実装するのに時間がかかりました。
今回の記事では、segueを使って画面を前に戻す方法を紹介します。

ソースコードです！
https://github.com/h-taro/WithSegue

# 環境
`Xcode 12.5.1`
`Swift 5.4.2`
`macOS Big Sur 11.5.2`

# 前提条件
動画のように`first`, `second`, `third`というように画面を表示するアプリケーションがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/3150eb07-aa4e-bc14-44a6-2d4f466c625d.gif" width="300" />

今回は`third`画面から`first`画面へ戻りたいです。


# 実装方法
大まかな実装方法は次です！
1. 遷移先の画面に`UIStoryBoardSegue`を引数に持つ関数を定義する
2. 遷移元の画面に`Unwind segue`を定義する
3. 定義した`Unwind segue`に`segue identifier`を定義する
4. 任意のタイミングで`performSegue(withIdentifier: "")`を実行する

## Unwind segueの設定方法
まず、遷移先の画面(今回は`FirstViewController`)に`UIStoryboardSegue`を引数に持つ関数を定義します。

```swift:FirstViewController.swift
@IBAction func showFirst(segue: UIStoryboardSegue) {
}
```


次は遷移元画面(今回は`ThirdViewController`)での作業です。
`Third`画面ボタンから`Exit`へドラッグ&ドロップすることで
`Unwind Segue`を定義しました。
定義した`Unwind Segue`に`showFirst`という`Segue Identifier`を設定しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/17751fc6-db2c-4452-3f77-a75f35184fdb.gif" width="600" />

# ボタンタップ時に画面遷移する
最後にボタンタップ時に`performSegue`を実行します！
`withSegueIdentifer`には前の手順で設定した`Segue Identifier`を使います。

```swift:ThirdViewController.swift
@IBAction func tapCautionButton(_ sender: UIButton) {
    performSegue(withIdentifier: "showCaution", sender: nil)
}
```
findメソッド、filterメソッドの違い

##findメソッド
条件に一致した最初の項目を取得


```js
var users = [
  { id: 1, admin: false },
  { id: 2, admin: false },
  { id: 3, admin: true },
  { id: 4, admin: false },
  { id: 5, admin: true },

];

var admin = users.find((user) => {
    return user.admin === true;
})

admin; // { id: 3, admin: true }

```


##filterメソッド
配列から条件に一致した全ての項目を取得

```js
var users = [
 { id: 1, admin: true },  
 { id: 2, admin: false },
 { id: 3, admin: false },
 { id: 4, admin: false },
 { id: 5, admin: true },
];

var filteredUsers = users.filter((user) => {
    return  user.admin === true;
});


filteredUsers; //[{"id":1,"admin":true},{"id":5,"admin":true}]

```
分割代入 const { } = の使い方

# 分割代入


分割代入`const { } = `を学習したので使い方、注意などを忘れないためにしておくための備忘録。

[MDN 分割代入 ( Destructuring assignment )]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

# ES5で書いた場合

```js
var character = {
  name: 'ミッキー',
  name2: 'ミニー'
}
//個別に使うときに変数に入れる必要がある
var name = character.name;
var name2 = character.name2;
```

参照するときにコードが冗長になってしまう。


# ES6の分割代入で書いた場合

```js
var character = {
  name: 'ミッキー',
  name2: 'ミニー'
}

//characterの中で抽出(分割代入)したい値を中括弧の中に書く
const { name, name2 } = character;

//name; ミッキー
//name2; ミニー 

```
中括弧の変数名は必ずcharacterで書いたキーと同じ名前でないと参照できない。
中括弧に存在しないプロパティ名を書いた時はエラーにならずundefindとして返される。


#参照と分割代入

変数で分割代入

```js
const a = {
  prop: 0
}

let { prop } = a;
prop = 1;

console.log(a, prop);
```

関数fnに分割代入
関数の引数に中括弧と変数名を記述すると、この時点で変数propとして分割代入が行われ、簡略化することができます。

```js

function fn({ prop }) {
  prop = 1;
  console.log(a, prop);
}

fn(a);
```


#オブジェクトに参照を保持している場合
```js
const c = {
  prop1: {
    prop2: 0
  }
}

let { prop1 } = c;

prop1.prop2 = 1;

console.log(c, prop1);
```

分割代入は変数のプロパティをコピーしますが、参照にオブジェクトを保持している場合は元の『　prop1　』まで変更することになり、変数cに影響することになります。
Next.js + Docker + WebStorm での デバッグ

Next.js、Docker、WebStormでデバッグするのに手間取ったのでメモ。

* Next.js 11.0.1
* Docker 20.10.7
* Docker Compose 1.29.2
* WebStorm 2021.2

## Docker設定
Dockerfileは特に特殊なことはしなくても良い。

docker-compose.ymlは以下。

```yml
version: '3'
services:
  app:
    build:
      context: .
      dockerfile: ./servers/app/Dockerfile
    volumes:
      - ./:/usr/src/app
    command: sh -c "NODE_OPTIONS='--inspect=0.0.0.0:9229' ./node_modules/.bin/next dev"
    ports:
      - '80:3000'
      - '9229:9229'
```

ポイントは以下の２点。
* portsにデバッグのポートの9229を開けるようにする。
* commandで`NODE_OPTIONS='--inspect=0.0.0.0:9229'`を指定する。

この状態でコンテナを立ち上げると、Next.jsのアプリとともに、デバッグモードで立ち上がる。  

## WebStorm設定
WebStorm側でポートをアタッチする設定を追加する。

Run/Debug Configurationsで、Attach to Node.js/Chromeを以下の通り設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/599862a4-b2d4-9d13-e69b-56a6547cae7f.png)

この設定をDebugアイコンで起動すると、成功していればデバッグウィンドウにログなどが表示されだす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/b9bd2a63-0544-4b3e-609b-2bd27bb3268f.png)

あとは、ブレークポイントを設定して画面を読み込めばストップしてくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/44a0d506-45ad-26fb-2378-76c1e4285167.png)
JavaScriptで役立つasync/awaitテンプレ（WebDevTips#2）

こんにちは，くるみです
これまでは主にpythonに触れてきましたが，最近Javascriptを勉強し始めたので，Webエンジニアを目指す方々へのtipsとして記事を書いていきたいと思います．

前回の記事はこちら▼

https://qiita.com/cocoa_folio/items/b8d9b435041233637cfa

前回に引き続き，今回はasync/awaitについて説明していきます！

#async/awaitとは

Promiseと一緒に用いられることの多い__async/await__
asyncとawaitって一体なんでしょう？
Googleで「async await」と調べてみると...

#####asyncとは
>非同期関数 — AsyncFunction オブジェクトである関数を定義します。非同期関数はイベントループを介して他のコードとは別に実行され、結果として暗黙の Promise を返します。ただし、非同期関数を使用したコードの構文および構造は、通常の同期関数と似たものになります。

#####awaitとは
>async function によって Promise が返されるのを待機するために使用します。

となっています．

つまり，なんとなく

__asyncを使うと，返り値としてPromiseを返す__
__awaitを使うと待機状態を作ってくれる__

ということが分かります．

#コードの作成
実際のコードを見てみましょう！

##### サンプルコード全体
```js
//こちらはコメントです．
//functionで関数の宣言
//Promiseの機能を持った関数"makeRequest"と"processRequest"を定義
//locationとresponseはそれぞれの関数における引数
//`${}`で文字列の中に変数の値を代入可能

function makeRequest(location){
  return new Promise((resolve, reject)=>{
    console.log(`Making Request to ${location}`)
    if (location === 'Google'){
      resolve('Google says hi')
    }else{
      reject('We can only talk to Google')
    }
  })
}

function processRequest(response){
  return new Promise((resolve,reject)=>{
    console.log('Processing response')
    resolve(`Extra Infromation + ${response}`)
  })
}

//asyncの利用
//try catchを使用

async function doWork(){
  try{
  const response = await makeRequest('Google')
  console.log('Response Received')
  const processedResponse = await processRequest(response)
  console.log(processedResponse)
  } catch(err){
    console.log(err)
  }
}
doWork()
```

こちらのコードをもとにasync/awaitの仕様を説明していきます．
まず，並列処理を行いたい関数__makeRequest__と__processRequest__を用意します．
（関数名はなんでも構いません）

これらのPromiseオブジェクトを処理する際には，__then__を用いて__直列接続（or並列接続）__する必要がありました．
しかし，(start)→関数→then→関数→then→関数→then→...→(goal)と繋いでいくと，__コードの見栄え__が悪くなってしまいます．（ifを何度もつなげてしまうようなイメージ...😭）

そこで，thenの代わりに使用するのが，__async/await__です！
__async/await__を使うことで，複数のPromiseオブジェクトをより簡潔に記載することができます．

##文法
サンプルコードのdoWorkを見ていきましょう．
asyncはfunctionの先頭に記載するだけで，doWork関数を__非同期関数__とすることができます
さらに，async functionの中で

```js
const response = await makeRequest('Google')
```
と定義することで，makeRequest関数に__await（待機状態）__を付与することができます
待機状態が付与されると，makeRequest関数の処理が終了するまで，次に進まないため，__then__のような直列化をたったの１行で施すことができます．

async/awaitを使うときには，エラー処理としてtry catchを使うことが通例なので覚えておきましょう！

#####参考文献
JavaScript Async Await　：　https://www.youtube.com/watch?v=V_Kr9OSfDeU
Arduino: malloc と free の使い方

メモリーの確保と開放のサンプルです。

```text:sketch_aug21a.ino
int count = 0;
void setup()
{
	Serial.begin(19200);
	delay(500);
	Serial.println(F("setup *** end"));
}

void loop()
{
	char *chx = (char *)malloc(256);
	char aa[17] = "0123456789abcdef";

	strcpy(chx,"Good Morning aaaa ");
	for (int it=0; it<6; it++)
		{
		strcat(chx, aa);
		}

	Serial.println(chx);
	Serial.println("strlen(chx) = " +String(strlen(chx)));

	free(chx);

	Serial.println ("Hello " + String(count));
	delay(2000);

	count++;
}
```

実行結果

```text
setup *** end
Good Morning aaaa 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
strlen(chx) = 114
Hello 0
Good Morning aaaa 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
strlen(chx) = 114
Hello 1
Good Morning aaaa 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
strlen(chx) = 114
Hello 2
Good Morning aaaa 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
strlen(chx) = 114
Hello 3
Good Morning aaaa 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
strlen(chx) = 114
Hello 4
```
【PostgreSQL】起動と停止

### 1.背景
Ruby on Railsを主に学習しています。
PostgreSQLはアプリを作成して`-d` でデータベース指定しておく、という認識でした。
（自動で作成してもらえるので仕組みを理解できていなかったです...）

```ruby
cd XX # 作成したいフォルダに移動
rails new sample_app -d postgresql # データベースを指定
rails db:create　 # データベースを作成
```
現在Rubyでアプリ作成をしており、PostgreSQLについて学習しているので備忘録としてまとめます。

### 2.環境
- mac.os バージョン10.15.6
- Ruby 2.7.3
- Rails 6.1.3.1
- psql (PostgreSQL) 12.6

### 3.手順
#### ①導入

```
brew install postgresql
brew services start postgresql
```

#### ②起動と停止
##### その1

```sql
hogehoge@hogenoMacBook-Air ~ % postgres -D /usr/local/var/postgres
2021-08-21 15:03:44.123 JST [2927] LOG:  starting PostgreSQL 12.6 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 12.0.0 (clang-1200.0.32.29), 64-bit
... -- ログが続く
```
上記の方法の場合、実行後にリアルタイムでログが更新されていきターミナルでの入力ができなくなります。`Ctrl+c`で停止できます。

##### その2

```sql
hogehoge@hogenoMacBook-Air ~ % pg_ctl -l /usr/local/var/postgres/server.log start
waiting for server to start.... done
server started
```
上記の方法ではバッグエンドでサーバーを実行することができ、ターミナルの入力が可能です。
`pg_ctl stop`で停止できます。

##### その3(その2の応用)
`pg_ctl -l /usr/local/var/postgres/server.log start`を毎回打つのは手間なので、環境変数を設定します。そうすると、`pg_ctl start`で起動できます。

※方法は、[こちら](https://qiita.com/yorokobi_kannsya/items/f77d074e382a88dae971)の`7.環境変数へPATHを通す(zshの場合)`を参考にしました。

環境の確認(zshかどうか)は下記のコマンドで確認できます。

```sql
hogehoge@hogenoMacBook-Air ~ % echo $SHELL

-- 実行結果が /bin/zsh の場合
echo 'export PGDATA=/usr/local/var/postgres' >> ~/.zshrc
$ source ~/.zshrc

-- 実行結果が /bin/bash の場合
echo 'export PGDATA=/usr/local/var/postgres' >> ~/.bash_profile
source ~/.bash_profile
```

```sql
hogehoge@hogenoMacBook-Air ~ % pg_ctl start                       
waiting for server to start....2021-08-21 15:31:47.286 JST [3240] LOG:  starting PostgreSQL 12.6 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 12.0.0 (clang-1200.0.32.29), 64-bit
2021-08-21 15:31:47.286 JST [3240] LOG:  listening on IPv6 address "::", port 5432
...
 done
server started
```
上記の方法ではその２同様、バッグエンドでサーバーを実行することができ、ターミナルの入力が可能です。
`pg_ctl stop`で停止できます。


### 4.まとめ
とても基本的な内容かと思いますが、改めて復習することで整理できました。

### 5.参考
1.[【PostgreSQL】MacでPostgreSQLデータベースの環境をつくろう！](https://tektektech.com/psql-mac-environment/#postgreSQL-2)
2.[初心者のMac + PostgreSQL インストール](https://qiita.com/yorokobi_kannsya/items/f77d074e382a88dae971)
3.[PostgreSQLの起動・接続・終了・停止コマンドとよく使うpsqlコマンド](https://hirooooo-lab.com/development/postgresql-command-tips/)

### 6.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
コーディング規約の本質について考えてみた

## はじめに
組織・プロジェクトによる多少の差はあれど、
コーディング規約を読んだ経験がある人は多いのではないでしょうか？
斯く言う私もいくつかコーディング規約を読んだ経験があります。

コーディング規約と一言でいっても様々なルールがあり、
・本当に規約を遵守する必要があるのか？
・規約を決めた人の好みじゃないのか？
という疑問を持ったことがある人もいるのではないかと思います。

そこで、「価値の高いコーディング規約とは何か？」という視点でコーディング規約の本質について考えてみたいと思います。

## 価値の高いコーディング規約とは？
まず、コーディング規約を定める目的は何でしょうか？
ソフトウェア開発者がプログラムを記述するルールを統一することでプログラムの品質や保守性の向上を図り、組織・プロジェクトとして一定の水準を担保することだと思います。
なので、__コーディング規約の本質とは、コーディングルールを定めることでプログラムの品質や保守性の向上に寄与すること（≒プロダクトの価値を高めること）__であると考えます。

本当に規約を遵守する必要があるのか？、規約を決めた人の好みじゃないのか？ という疑念を持つ場合、このプログラムの品質や保守性の向上に寄与する（≒プロダクトの価値を高める）ルールとなっていないことが多いと感じます。

if文を例にあげて考えてみたいと思います。

## 例）if文のコーディングスタイル
プロジェクトAのコーディング規約でif文のコーディングスタイルについて、可読性の向上のために以下のルールがあるとします。

#####  ① if文の括弧は、条件式の後に改行せずに書くこと

```C
if a < 1 {
   if b < 1 {
      ***
   }
}
```

if文の括弧の位置は、いくつかコーディングスタイルがあり、
以下のようなスタイルの方が馴染みがある人も多いかと思います。

```C
if a < 1 
{
   if b < 1 
   {
      ***
   }
}
```

①のようなルールがあった場合、
本当に規約を遵守する必要があるのか？、規約を決めた人の好みじゃないのか？ 
という疑念を持つ人もいるのではないでしょうか。
これは、①のルールがプログラムの品質や保守性の向上に対する貢献度が低いからだと考えます。

極端に言うと後者のコーディングスタイルを採用することで、
プログラムの品質や保守性が低下し、プロダクトの価値低下に繋がるでしょうか？
そこまでの影響はないと思われる人が多いのではないでしょうか。

では、次のようなルールの場合は、どうでしょうか。

##### ② if文の括弧の後は改行し、インデントを整えること

```C
if a < 1 {        // 括弧の後は改行する
   if b < 1 {     // インデントを整える
      ***
   }
}
```

もし、②のルールがない場合、
以下のようなプログラムを記述をするソフトウェア開発者がいるかもしれません。

```C
if a < 1 { if b < 1 { *** } }
```
このようなプログラムが散見される場合、どう感じるでしょうか？
プログラムの可読性が低下し、バグを誘発する可能性があると感じるのではないでしょうか。

なので、②のルールはプログラムの品質や保守性の向上に対する貢献度が高く、コーディング規約として必要なルールだと感じます。（もちろん、個人差はあります。）

## ルールの貢献度を意識する
コーディング規約の本質とは、コーディングルールを定めることでプログラムの品質や保守性の向上に寄与すること（≒プロダクトの価値を高めること）です。

なので、コーディング規約のルールは、プログラムの品質や保守性の向上に対して貢献する内容でなければなりません。この貢献度が明確となっているルールこそが価値の高いコーディング規約であると考えます。

コーディング規約とは、コーディングスタイルを統一することが目的ではなく、コーディングスタイルを統一することでプログラムの品質や保守性を向上することが目的なのです。


## さいごに
いろいろなコーディング規約がある中で本当に価値のあるコーディング規約とは何だろう？という疑問があり、個人の視点で考えてみました。
個人の見解となりますので、賛否両論はあると思っています。

組織・プロジェクトのレベルによっては、例としてあげた内容は当たり前であり、
価値のないルールであるということもあるかと思います。

大切なのは、コーディング規約がある理由やルールの貢献度について意識することだと思います。コーディング規約は目的ではなく、目的を達成するための手段であるということを意識していきたいですね。

最後まで読んでいただき、ありがとうございました。
[Python]Seleniumを用いたWebページスクリーンショット取得方法 メモ

* Seleniumを用いたWebページのスクリーンショット取得方法についてメモする。

## プロジェクト構成

```
screenshot --- screenshot.py
			|_ chromedriver.exe
			|_ images
```



## コード

* `screenshot.py`
  * 実行時に指定したURLのWebページのスクリーンショットを取得する。
        * ページ内の特定画像を保存したい場合は、コメントアウト箇所を外し、対象画像のIDを指定する。
  * その他
        * コードと同一階層に`chromedriver`を配置する。`chromedriver`の取得方法は[こちら](https://qiita.com/KWS_0901/items/7191b5f5d129aba6315c)を参照のこと。
        * `images`フォルダに取得結果を配置する。

```python
import sys
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options

# 標準入力から対象ページのURLを取得
args = sys.argv
target_url = args[1]

options = Options()
options.add_argument('--headless')

with webdriver.Chrome("./chromedriver.exe", options=options) as driver:
    # ページ上のすべての要素が読み込まれるまで待機
    wait = WebDriverWait(driver, 15)
    driver.implicitly_wait(10)
    driver.get(target_url)
    wait.until(EC.presence_of_all_elements_located)

    # ウィンドウサイズ調整
    w = driver.execute_script("return document.body.scrollWidth;")
    h = driver.execute_script("return document.body.scrollHeight;")
    driver.set_window_size(w, h)

    # スクリーンショット取得
    # ページ全体を保存したい場合
    driver.save_screenshot("images/all_page_screenshot.png")

    # ページ内の特定画像を保存したい場合
    # png = driver.find_element_by_id('#対象画像のID').screenshot_as_png
    # with open('./images/target_image.png', 'wb') as f:
    #    f.write(png)
    # ブラウザクローズ
    driver.quit()

```



## 実行方法

```shell
python screenshot.py 取得対象ページURL
```

※`images`フォルダにスクリーンショットが保存される。



## 参考情報

* [【Python】Seleniumでスクリーンショットを撮る](https://qiita.com/DisneyAladdin/items/431e9fd0c1cf709347da)
* [PythonでSeleniumを使用してスクリーンショットを撮る](https://laboratory.kazuuu.net/take-a-screenshot-using-selenium-in-python/)
FFFTPのファイル一覧が真っ白になった

# 起こった問題
先日、ホームページの更新をしようと思い、FFFTPを起動してサーバーに接続したところなんと画面が真っ白に。ローカル側にもホスト側にも何も表示されない。`ファイル一覧の取得は正常終了しました`と表示されていたので、接続自体には問題がないはず。
という問題に陥ったので調べてみると、同じような問題にぶち当たった人が多そうだったのでメモ的な感じで残してみる。

# 解決策
**FFFTP画面上部のメニューバー「表示」ボタン → 「形式」→ 「一覧」**をクリック。
これだけ。
どうやらここを「詳細」にすると真っ白になるっぽい。なぜこうなるのかはわからなかった。
`Ctrl`と`+`を同時に押す、みたいな記事もあったが自分の場合はそれをしても何も起こらず、この表示形式を変更することでもとに戻った。
nodenvのパスが通らなかった

# 問題
nodenvのパスが通らなかった。
インストールの方法はnodenvのリポジトリのREADMEに従った。

試したことは

- nodebrewの削除
- bash_profileへのパスを記載

```
export PATH="$HOME/.nodenv/bin:$PATH"
eval "$(nodenv init -)"
```

# 解決
https://github.com/nodenv/nodenv#understanding-shims

ドキュメントにあったパス指定にしたところパスが通った。

```
export PATH="$HOME/.nodenv/shims:/usr/local/bin:/usr/bin:/bin:$PATH"
$ eval "$(nodenv init -)"
```

どうやらShimsというものが関係しているようだった。

> シムは、コマンドをnodenvに渡すだけの軽量の実行可能ファイルです。

ちなみにパスを通した後の確認はこのようになった。

```
$ which node
/Users/{ユーザー名}/.nodenv/shims/node
```

結論、READMEちゃんと読めということだろう。
Gtk３アプリ Dapperのアンダーバーの修正

###Dapperのアンダーバーを使えるようにする修正

DapperでDbのカラム名にアンダーバーがあるとsplitで割って片方を名前を参照する仕様になっている
アンダーバーを使えるようにする。

####Dapperだけを利用する場合

Dapperがカラム名のアンダースコアを無視する設定を追加します。

```cs
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
```

https://qiita.com/hi_zacky/items/64fbc685e3beaac931e6

#####Dapper Extensionを利用する場合

######案1
DapperExtensionのソースを書き換える。
ReflectionHelper.csの中にSplitで割る箇所があるので削除してみる。

```cs
var entityPropertyName = propertyName;//.Split('_').Last();
```


######案2

DapperExtensionのClassMapを使い、大文字小文字とアンダーバーのマッピングを行う

Modelファイル側　キャメルケース　大文字小文字
Db側　　　　　　　スネークケース アンダーバー

ClassMapのサンプルはDapperExtensionの中のテストケースファイルが参考になる

```cs
public class test
{
    public long aId { get; set; }
    public string tes1Tes2 { get; set; }
}

public class testMap : ClassMapper<test>
{
    public testMap()
    {
        Table("test");
        AutoMap();
        Map(f => f.tes1Tes2).Column("tes1_tes2");
    }
}

//mapperを指定する
 DapperExtensions.DapperExtensions.DefaultMapper = typeof (testMap);
//複数
 DapperExtensions.DapperExtensions.SetMappingAssemblies(new[]
 {
     typeof (testMap).Assembly,
     typeof (testMap).Assembly
 });

```

####Dbからモデルを生成する

https://github.com/olsh/datagrip-poco-generator

とりあえず案１で様子を見ることにする

[Gtk3アプリ TreeViewとデータ各種処理](https://qiita.com/iota_11/items/33cc292d1be7278ed5d2)に続く
【docker】コンテナの hosts と resolv.conf を変更する

docker コンテナの hosts と resolv.conf を調査することがあったので、その際に使用したコマンドとオプションをまとめておきます。

## ``/etc/hosts``に追加
``--add-host``オプションを使用する。
https://docs.docker.jp/engine/reference/commandline/run.html#hosts-add-host

コンテナ内の``/etc/hosts``の中身

```terminal
> docker run --rm busybox cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      6fc807297ca7
```

``--add-host``オプションを指定すると、

```terminal
> docker run --rm --add-host=local_dev:123.4.5.6 busybox cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
123.4.5.6       local_dev
172.17.0.2      9b900d1f9346
```

``123.4.5.6       local_dev``が追加された。

## ``/etc/resolv.conf``を変更
``--dns=IPアドレス...``オプションを使用する。
https://docs.docker.jp/engine/userguide/networking/default_network/donfigure-dns.html

コンテナ内の``/etc/resolv.conf``の中身

```terminal
> docker run --rm busybox cat /etc/resolv.conf
# DNS requests are forwarded to the host. DHCP DNS options are ignored.
nameserver 192.168.65.5
```

``--dns``オプションを指定すると、

```terminal
> docker run --rm --dns=8.8.8.8 busybox cat /etc/resolv.conf
nameserver 8.8.8.8
```

コンテナが使用するネームサーバが変わりました。

```terminal
> docker run --rm --dns=8.8.8.8 tutum/dnsutils dig google.com

; <<>> DiG 9.9.5-3ubuntu0.2-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54158
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             299     IN      A       172.217.26.14

;; Query time: 76 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Aug 19 03:45:17 UTC 2021
;; MSG SIZE  rcvd: 55
```

## 参考

``ping``、``curl``、``nslookup``を使用したときに、名前解決されるものとされないものがあるみたいです。
https://qiita.com/tksugimoto/items/804e0051bf1b1ddab168
AWS SNSとSQSをメーリングリストとセンター問い合わせで例えてみる

AWSのSNSとSQSの仕組みについて学んでいて、 
しっくり来る例えを思いついたので、少しまとめてみます。 


## SNSは「メーリングリスト」

まず仕組み自体を少しまとめます。 
SNSはサーバを用意せずに「通知機能の仕組みづくり」を実現できるサービス。
メッセージを送るサービスとも言えます。

以下のようにしてPublisherからSubscriberにメッセージが送られます。 

### 送信者側 Publisher
* `Topic`を作成する
* `Topic`に対してメッセージを送信する
* 複数の購読者(`Subscriber`)に対して、一括でメッセージが送信される(いわゆる`fan out`)

### 受信者側 Subscriber

* `Topic`の`Subscriber`に登録
    * 受信者自ら購読登録はしないが、プロトコルが`メール`の場合は認証が必要
        * Subscriberの登録はAWSコンソールやCLIにて行う

### メーリングリストの仕組みと比べてみる

この仕組みは「メーリングリスト」に似ていると、言えるでしょう。 
SNSと対照させながら、メール送信の流れを書きます。 

* メーリングリストを受け取るメンバーを管理者が設定画面などで登録する。
    * SNSで言うと：Subscriberを登録する
* メッセージを作成し、メーリングリストのメールアドレスに送る
    * SNSで言うと：topicに対してメッセージを送る 
* メーリングリストに登録されている宛先にメールが一括送信される
    * SNSで言うと：Subscriberに対してメッセージがfan outされる 
* メッセージの送信者はメーリングリストに誰が登録されているかを気にしなくてよい。
    * SNSで言うと：メッセージ送信にあたり、 Subscriberに誰が、何が登録されているかを気にしなくてもよい。いわゆる「疎結合」の達成。

### メーリングリストとの違い

SNSはSubscriberのプロトコルの種類が多いことが違いとして挙げられるでしょう。
メールやショートメッセージ(SMS)やプッシュ通知、HTTPリクエストなど。 

## SQSは「センター問い合わせ」

SQSはメッセージをキューとして保存し、取り出す仕組みを提供するサービス。 
先述したSNSとメッセージングの観点では似たサービスですが、少し趣が異なります。

* プロデューサー(送信側)がSQSに対してメッセージを送る
* SQSがメッセージをキューとして蓄える
* コンシューマー(受信側)がSQSに対してメッセージがたまっていないかを確認し、メッセージがあれば受信する

送ったメッセージは即時では相手には届かず、 
受け取り側が自ら取りに行くというという仕組みです。 
(**送信は完了しているけど、相手には届いていない。**)
送った側としては受信側のことは気にせず、「さ、次の処理行こう！」ということができます。 これも「疎結合」

### 「センター問い合わせ」の仕組みと比べてみる

1990年代後半から2000年前半くらいまでのガラケーにあった、
「センター問い合わせ」に対して、少し近いところがあるためまとめます。
(SQSはサーバレス、センター問い合わせはがっつりサーバに関することですが。。

* 相手がメールを送る
    * SQSで言うと：プロデューサーがメッセージを送る
* メールが携帯電話のキャリアのメールサーバに保存される
    * SQSで言うと：メッセージがキューに入る
* 自分が携帯電話のキャリアのメールサーバに対して新着メールがあるかを問い合わせる(これがセンター問い合わせ)
    * SQSで言うと：コンシューマーがキューに対してメッセージの有無を確認。あれば取得。

SQSというよりは、「ポーリング」の仕組みの説明かもしれませんが、
受け取り側が自らサーバやキューに問い合わせるという行為は近しいものがあるかもしれません。 

~~よく「メール来ているかな？」と少し期待しつつでセンター問い合わせを行ったのが懐かしい。~~

https://time-space.kddi.com/au-kddi/20190320/2607


## 参考

https://business.ntt-east.co.jp/content/cloudsolution/column-134.html

https://www.fenet.jp/aws/column/aws-beginner/299/#AWS%E3%81%AE%E3%80%8CAmazon_SQS%EF%BC%88Simple_Queue_Service%EF%BC%89%E3%80%8D%E3%81%A8%E3%81%AF%EF%BC%9F

https://www.slideshare.net/AmazonWebServicesJapan/20190604-aws-black-belt-online-seminar-amazon-simple-notification-service-sns
CML2を使いこなす。（その10：ホストマシンへのSSH接続）

# はじめに
`CML2`のホストマシンにSSH接続を行うと、以下で紹介した通り、各ラボノードに対してコンソール接続するための操作画面にログインできます。

- [CML2を使いこなす。（その４：色々なコンソール接続）](https://qiita.com/sakai00kou/items/bef173fb6383411475f9)

但し、コンソール接続画面からの操作は各ラボノードにコンソール接続するための操作に限られており、`CML2`のホスト側OSを操作することができません。

ホストマシンのコンソール画面や`Cockpit`の「**端末**」画面から`sysadmin`ユーザでログインすればホストマシン側のOS操作を行うことはできますが、レスポンスが悪いため、できればSSH接続して操作したい。

ということで今回は`CML2`のホスト側OSをSSHによるリモート接続経由で操作する方法を紹介します。

- 【前】[CML2を使いこなす。（その９：ストレージの増設）](https://qiita.com/sakai00kou/items/28699d174bdd4ed28b76)
- 【次】[CML2を使いこなす。（その11：Node Definitionsの設定）](https://qiita.com/sakai00kou/items/7f956625990ff0644acb)

# CML2のSSHサービス
`CML2`のホストマシン側の`SSH`サービスは`virl2-sshd.service`というサービスで動作しているため、SSHで接続した際には各ラボノードにコンソール接続する画面が開くようになっています。

但し、一般的な`sshd.service`が存在しないわけでは無く、`sshd.service`のコンフィグ情報も`/etc/ssh`配下に存在します。

そのため、`sshd.service`を起動させることでホストマシンにSSH接続できるようにします。

# sshd.serviceの有効化
`/etc/ssh/sshd_config`のポート設定を確認すると、デフォルトで`Port 1122`となっていることから、`virl2-sshd.service`とはポート番号が被らないようになっており、SSHによるホストマシンへの接続も想定されているようです。

デフォルトでは起動時に起動しないようになっていることから以下のように起動して使えるようにします。

## コンソール画面からのsshd.serviceの有効化
以下コマンドでサービス起動と自動起動の有効化を行います。

```shell:コンソール画面からsshd.serviceの有効化
sudo systemctl enable --now sshd.service
```

## Cockpit画面からのsshd.serviceの有効化
「**サービス**」→「**System Services**」から`sshd`を選択し、以下「**起動と有効化**」を選択するだけでサービスの起動と自動起動設定が行われます。

![capture_21082021_142609.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/3bd71e5b-64a7-6552-d1eb-456c9bf37d73.jpeg)

# ホストマシンへのSSH接続
先ほど起動した`sshd.service`は1122ポートで起動しているため、1122ポートを指定して`sysadmin`ユーザでSSH接続します。

以下`TeraTerm`で接続する場合の例。

![capture_21082021_143148.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/c495c64f-38bb-26fd-ac98-8e0b04564948.jpeg)

# おわりに
ホストマシンのOS側を操作する機会はあまり無いと思いますが、覚えておくとレスポンスが悪いコンソール画面等触らなくても済むため、個人用途で使用するのであれば自動起動の設定にしておくことをお勧めします。