OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby　文字列と数値について

Rubyの基本文法である、文字列と数値について記事を書きたいと思う。

### 文字列について
■文字列
文字列は、プログラミングの中で文字を扱うための値。
文字列を生成するには、以下のように文字をダブルクォーテーション「"」またはシングルクォーテーション「'」で囲む。

```
"これは文字列です。"
'これは文字列です'
```
ちなみに、「値」とは

■値
数や文字をはじめ、プログラムで扱うデータを「値」と言いう。
プログラミングでは値の種類を明確に分けて扱う。
種類によってそれぞれ書き方が異なり、実行できる命令も異なる。

文字列同士は連結できる。
今回は、ターミナルより、irbを起動させ連結させたいと思う。

■irb
irbコマンドは、ターミナルから直接Rubyのプログラムを動かすことができる機能を起動する。
irbは「Interactive Ruby」の略。

[![Image from Gyazo](https://i.gyazo.com/615627df99fbff3fd23f73da70ed23b4.png)](https://gyazo.com/615627df99fbff3fd23f73da70ed23b4)

このように、「""」で囲んだ文字列を「+」で連結させることができる。

ちなみに、数値を足した場合と文字列を足した場合の違いをみてみたいと思う。
まずは、数値を足した場合。
[![Image from Gyazo](https://i.gyazo.com/b03e75436827d4425d6a48df4d0a997b.png)](https://gyazo.com/b03e75436827d4425d6a48df4d0a997b)

次に文字列。
[![Image from Gyazo](https://i.gyazo.com/50961fae22c6f6bbae78ae016d5228fd.png)](https://gyazo.com/50961fae22c6f6bbae78ae016d5228fd)
このように数値と文字列というのは全くの別物ということがわかる。

### メソッドについて
■メソッド
メソッドとは、プログラミングにおける何らかの処理をまとめたもの。
メソッド名をプログラム中に記述することで、そのメソッドの処理を実行できる。
何か実装したい時、実装に関係するコードを全部書いていたら進まなくなる。
Rubyではよく使われる機能をひとまとめにして呼び出すだけで簡単に使えるようにする。
実際にメソッドを使ってみたいと思う。

■lengthメソッド
文字列が持つメソッド。length（レングス）メソッドは文字列の文字数を数えてくれる。
メソッドの使用は、値に対してメソッド名「length」をドット.で繋ぎ実行する。
[![Image from Gyazo](https://i.gyazo.com/a0aa7d98dbdf0ede22eaabea7faed212.png)](https://gyazo.com/a0aa7d98dbdf0ede22eaabea7faed212)

### 数値について
数値
数値は、数を表現する値。文字列とは異なり、計算などを行うことができる。
数値は文字列とは違って、ダブルクォーテーション"やシングルクォーテーション'も必要ない。

数値を使った数の表し方の例

```
# 整数
5

# 負の値
-5

# 小数
3.14
```
### 数値の計算
■演算子
プログラミングにおける値の計算や比較などに使用する記号のこと。
計算における代表的な演算子は「+」や「-」、比較における代表的な演算子は「>」や「<」がある。
この簡単な記号である演算子を用いることで、計算や比較処理を瞬時に行ってくれる。

■代数演算子

|代数演算子|説明|
|--------|----|
|+       |足し算|
|-       |引き算|
|*	 |かけ算|
|/	 |割り算|
|%	 |剰余(割ったあまり)|

使い方は、普通の算数の計算と同じ。

```
irb(main):001:0> 2000 + 2000
=> 4000

# 引き算
irb(main):002:0> 2000 - 1000
=> 1000

# 掛け算
irb(main):003:0> 50 * 50
=> 2500

# 割り算
irb(main):004:0> 800 / 10
=> 80

# 剰余演算（5 ÷ 2をした余り）
irb(main):005:0> 5 % 2
=> 1
```

### 異なる値同士の連結
文字列"i am ",　数値20,　文字列" years old."
この3つの値を連結して出力する場合。
[![Image from Gyazo](https://i.gyazo.com/93a3786096e2a936b60efb66cc5d9ae6.png)](https://gyazo.com/93a3786096e2a936b60efb66cc5d9ae6)
このようにエラーが現れる。
これは、文字列と数値は別の種類の値なので、連結することができないため。
そこで、数値を文字列に変換するto_sメソッドを使って、数値の20を文字列の"20"に変換する。

■to_sメソッド
数値が持つメソッド。数値を文字列に変換してくれる。to_sのsの意味は「string(文字列)」。
[![Image from Gyazo](https://i.gyazo.com/ba0407363df58545ae04763242a67939.png)](https://gyazo.com/ba0407363df58545ae04763242a67939)

反対に文字列を数値に変換するメソッドもある。それがto_iメソッド。これは文字列がもつメソッド。

■to_iメソッド
文字列が持つメソッドです。文字列を数値に変換してくれる。
to_iのiの意味は「integer(整数)」
[![Image from Gyazo](https://i.gyazo.com/9e5d2f38d46aab7902fb449877b93508.png)](https://gyazo.com/9e5d2f38d46aab7902fb449877b93508)
このように数値に直すことで足し算ができる。

### 文字列の中に文字列以外を含める
この場合は式展開を行う。
■式展開
式展開は、文字列の中に式を入れることができる機能。
式展開の書き方は文字列中で#{式}とする。
式展開をする場合は、文字列を作るときにダブルクォーテーション"で囲む必要がある。
シングルクォーテーション'で囲んだ場合は式展開が行われない。

■式
Rubyにおける「式」とは文字列や数値の他に、メソッドの呼び出し、
変数や演算子式などが含まれる。
Rubyは記述をすべて式と捉える。

[![Image from Gyazo](https://i.gyazo.com/f64461d13398d7860a661d8f7f853c01.png)](https://gyazo.com/f64461d13398d7860a661d8f7f853c01)
このように式展開を使い文字列の中に、数値を入れることができた。
【CSS】flexboxで定義リスト(dl、dt、dd）を横並びにする方法

　今回は、HTMLタグのdl、dt、ddタグを使って定義リストを作成していきます。定義リストタグを横並びにする際、一昔前はfloatを使用していましたが、今回はflexboxを使って横並びにする方法を解説します。
　まず定義リストタグというのは、定義する用語とその用語の説明を対にしたリストを作成するためのタグになります。
それぞれのタグの意味は以下の通りです。

dlタグ：「description list」の略で、定義リスト全体を表すタグ
dtタグ：「description term」の略で、定義する用語（名称やタイトル）を表すタグ
ddタグ：「description description」の略で、dtで定義した用語の説明を記述するタグ

##HTMLで骨子を作る

```index.html
 <div class="company_info">
   <dl>
     <dt>会社名</dt>
       <dd>株式会社〇〇</dd>
       <dt>所在地</dt>
       <dd>〒000-0000 東京都渋谷区</dd>
       <dt>電話番号</dt>
       <dd>03-1122-3456</dd>
       <dt>代表者</dt>
       <dd>名前 太郎</dd>
       <dt>E-Mail</dt>
       <dd>xxx@xxxx.com</dd>
       <dt>お問い合わせ受付時間</dt>
       <dd>平日：10：00～19：00（土・日・祝 定休）</dd>
   </dl>
 </div>

```
今回は例として新着情報の一覧をHTMLで作成しました。上記の場合、通常は下記の様に表示されます。
![定義リスト2 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/00158b1c-4cdd-46f9-d218-660fcbe1134e.png)

これに以下のCSSを追加して、dtとddを横並びにしていきましょう。

##dtとddを横並びにする
　dtタグとddタグを横並びにするため、その親要素であるdlタグにdisplay: flex;を適用し、横並びを実現しています。また、複数行の表示に対応するために、flex-wrap: wrap;を指定します。

```style.css
dl {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}

```
##dtとddの横幅を指定
　dtとddの合計の幅がdlと同じ幅になるように指定します。例えばdlの幅が100%の場合は、dt30%、dd70%の様に、dlと同じ幅に収めないとレイアウトが崩れてしまいます。これはdlでflex-wrap: wrap;を指定しているためです。

```style.css
dt {
  width: 30%;
  padding-bottom: 20px;
  margin-bottom: 10px;
  background-color: #DADADA;
}

dd {
  width: 70%;
  padding-bottom: 20px;
  background-color: #F3F3F3;
  margin-bottom: 10px;
}
```


#まとめ
・dl、dt、ddタグを使うと定義リストを作れる
・定義リストとは”用語（名称やタイトル）”と”用語の説明”が1つのセットとなったリストのこと
・flexbox（display: flex;、flex-wrap: wrap;）を使ってリストを横並びにできる

![定義リスト3 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/3b992be7-c7d0-1560-5afe-7f85e11f2929.png)
バッチファイルにドロップして、ファイル名に現在日時を付加する

Y子です。
土日ってすぐに終わっちゃいますね。

今日は、過去2回の合わせ技で、ファイル名を簡単に変更するバッチファイルを作ってみました。

* [バッチファイルに日付・時間の文字列を作ってもらう](https://qiita.com/koiwaiwaiko/items/b7e969a00020025c4d7e)
* [バッチファイルにドロップしたファイルの情報を得る](https://qiita.com/koiwaiwaiko/items/31a7c9c0638d2b8a5e56)

つまり、なにかファイルをドロップすると、ファイル名に現在日時を付加するようリネームしてくれるバッチファイルです。

たとえば、「```test.txt```」が「```test_20210402_094617.txt```」になります。

```bat:filedrop_ren_curdate.bat
@echo off

rem 引数がない場合は終了する
if "%~1"=="" (
  echo 引数がありません
  pause
  exit /b
)

rem 日付「20210402」形式
set str_date=%date:~0,4%%date:~5,2%%date:~8%

rem 時刻「094617」形式
set str_time=%time: =0%
set str_time=%str_time:~0,2%%str_time:~3,2%%str_time:~6,2%

rem 変更前のファイル名(フルパス)「C:\work dir\test.txt」
set str_oldfile=%~1

rem ファイル名分割…拡張子なし「test」と拡張子のみ「.txt」
set str_new_fn=%~n1
set str_new_ex=%~x1

rem 変更後のファイル名(ファイル名のみ)「test_20210402_094617.txt」
set str_newfile=%str_new_fn%_%str_date%_%str_time%%str_new_ex%

ren "%str_oldfile%" "%str_newfile%"
echo ファイル名を「%str_newfile%」に変更しました。

pause
```

リネームコマンドの```ren```や```rename```は、第2引数にフォルダ名を含んではだめなんですね。
なので、```str_new_fn```には「```%~dpn1```」ではなく「```%~n1```」を代入しています。

リネームの成否の判定をしていないので、「変更しました」と出力しているのはちょっとウソですね(^-^;
まあいっか！

明日は月曜だー。わー。

【2021/04/05 09:00 追記】
```set str_oldfile=%1``` だったところにチルダを入れました。そうしないと、ファイル名にスペースがある場合にエラーになってました。
お祭りの日付

とある王国では 4 で割って余りが 1 になる年に開催される祭があります。
とある王国では暦が独特であり、以下のような暦になっています。

・1 年には 1 月から 13 月までの 13 ヶ月がある。
・偶数月の日数は 15 日である。
・奇数月の日数は 13 日である。

とある王国の国民たちはこの祭が大好きでいつも、次に開催される日を楽しみにしています。
あなたも、祭を楽しみにしているので、次の開催日まであと何日あるのか早く知りたいです。

そこで、あなたには、現在の日付と次の祭の開催日が与えられるので、次の祭までの日数を計算するプログラムを作ってもらいます。
ただし、今年の祭は開催されないことはわかっており、今日の日付はカウントされません。

入力例 1 の場合、以下のようになります。

![スクリーンショット 2021-04-04 22.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/918117/ba5b1af0-2b32-1113-d28c-728d614442ea.png)


2000 年から見て、一番近い開催年は 2001 年です。2000 年 12 月 10 日から、 2001 年 1 月 10 日までの日数は 5 + 13 + 10 = 28 で 28 日となります。

コード例

```
#変数への格納と余りが１の年（開催年 == opening_y）を炙り出すための材料となる「starting_y」を作成する
starting_y_origin,starting_m,starting_d = gets.chomp.split(" ").map(&:to_i)
opening_m,opening_d = gets.chomp.split(" ").map(&:to_i)
starting_y = starting_y_origin

#この時にはまだ謎に包まれているopening_yを炙り出す
#二つの分岐を作るが、最終的に格納される変数は同じ
if starting_y_origin % 4 == 0
   opening_y = starting_y_origin + 1
else
  loop do
    starting_y += 1
  break if starting_y % 4 == 1
    opening_y = starting_y + 1
  end
end

if starting_m.odd?
 rest_days_sm = (13 - starting_d)
 this_year_days = ((starting_m..13).to_a.count{|m| m.odd? == true} -1)*13 + ((starting_m..13).to_a.count{|m| m.even? == true})*15 + rest_days_sm
else
 rest_days_sm = (15- starting_d)
 this_year_days = ((starting_m..13).to_a.count{|m| m.odd? == true})*13 + ((starting_m..13).to_a.count{|m| m.even? == true}-1)*15 + rest_days_sm
end

if opening_m.odd?
 op_year_days =  ((1..opening_m).to_a.count{|m| m.odd? == true} -1)*13 +((1..opening_m).to_a.count{|m| m.even? == true})*15 + opening_d
else
 op_year_days =  ((1..opening_m).to_a.count{|m| m.odd? == true})*13 + ((1..opening_m).to_a.count{|m| m.even? == true} -1)*15 + opening_d
end

if (opening_y - (starting_y_origin)) == 1
 puts this_year_days + op_year_days
else
 puts (15*6 + 13*7)*((opening_y - starting_y_origin) - 1) + this_year_days + op_year_days
end
```
YAMLファイルについて勉強した

現在お仕事でAPI連携設計を先輩と一緒に考えています。
エンジニアとして初めてのお仕事です。

そこでYAMLファイルを作成しているのですが、YAMLについて正しい認識であるか不安だったので勉強してみました！
勉強する前の私の認識としては`何らかの設定を決めたファイル`というような認識です。

まとめます。

## YAML

簡単にいうと

#### 「ファイルの書き方のルールの一つ」

他にも`XML`とかがよく聞いたことありますが意味としては同じでルールが違うだけ。
日本語と英語と同じ意味でも「こんにちは」と言うか「Hello」と言うかが違うのと同じです。

Wikipediaでは
`構造化データやオブジェクトを文字列にシリアライズ（直列化）するためのデータ形式の一種`と説明されていました。

拡張子は`.yml`もしくは`.yaml`です。

うん。
何となく私の元々の認識とずれてはいないですね。

## 例

```PHP:docker-compose.yml

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
        build:
            context: ./docker/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
            - redis
            - selenium
    mysql:
        image: 'mysql:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
        volumes:
            - 'sailmysql:/var/lib/mysql'
        networks:
            - sail
        healthcheck:
          test: ["CMD", "mysqladmin", "ping"]

# 省略
```

上記はLaravel8の公式のやり方で新規アプリケーションを立ち上げた時に作成されるdocker-compose.ymlです。

「mysqlはこういう風に使いますよー」「ポートはここ使いますよ」って書いてあるんですね。


## 書き方

#### コメント

YAMLはコメントが書けます。

```yaml
#コメントです
```

#### 配列

配列は-(ハイフン)とスペースで表します。

```yaml
- AAA
- aaa
- BBB
- bbb
```

上記は`['AAA','aaa','BBB','bbb']`という配列の意味です。

以下のようにネストもできます。`['AAA',['aaa','bbb']]`の配列です。

```yaml
- AAA
- - aaa
  - bbb
```

#### ハッシュ

ハッシュ(連想配列)は:(コロン)とスペースで表します。

```yaml
ABC: abc
```

上記は`{'ABC': 'abc'}`のハッシュの意味です。

こちらもネストできます。半角2つを前に入れます。

```yaml
ABC: abc
  DEF: def
```

なるほど。
YAMLファイルって少しでもインデントがずれるダメな理由が分かりました:thinking:

以上です。
UpdateView　による　他のユーザーが変更できないようにする!

#他のユーザーは、投稿を編集できないようにする。
deletのclassもget_querysetでアクセス不可にする。

```views.py
class Edit(LoginRequiredMixin, generic.UpdateView):
    model = Content
    template_name = 'content/edit.html'
    form_class = ContentEdit
    success_url ='/content/index/'

    # ログインしているユーザが作ったもでなければアクセス不可
    def get_queryset(self):
        # このビューで生成されるベースとなるクエリセットを取得
        base_qs = super(Edit, self).get_queryset()
        # さらにユーザIDで絞った結果を返す。(存在しないので404が返る)
        # 条件分岐してエラーページを出しても可
        return base_qs.filter(owner=self.request.user)

    def form_valid(self, form):
        messages.success(self.request, '編集できました！')
        return super().form_valid(form)
[Laravel8] Eloquent日付関連where句まとめ

#概要

Eloquent ORMで日付関連のwhere句検索をメモします。

#方法

###日付(whereDate)

```.php
$posts = DB::table('posts')
                ->whereDate('created_at', '2021-04-04')
                ->get();
```

###月　(whereMonth)

```.php
$posts = DB::table('posts')
                ->whereMonth('created_at', '04')
                ->get();
```

###日(whereDay)

```.php
$posts = DB::table('posts')
                ->whereDay('created_at', '04')
                ->get();
```

###年(whereYear)

```.php
$posts = DB::table('posts')
                ->whereYear('created_at', '2021')
                ->get();
```

###時間(whereTime)

```.php
$posts = DB::table('posts')
                ->whereTime('created_at', '22:00:00')
                ->get();
```


#文献
https://readouble.com/laravel/8.x/ja/queries.html
MVCモデルでTableViewCellを表示させる（xib使用）

xibを使用してTableViewCellにただ表示させるコード
CellModelに追加する想定で、仮のダミーを用意してCellに表示する。

##Controller

```ruby:TableViewController.swift
import UIKit

final class TableViewController: UIViewController {
    
    private let CELL_NIB_NAME = "TableViewCell"
    private let CELL_ID = "TableViewCell"
    
    var dummyModel:[CellModel]{
        [
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
            CellModel.init(number: "1", menu: "hoge"),
        ]
    }
    
    @IBOutlet private weak var tableView: UITableView! {
        didSet {
            let cellNIB = UINib(nibName: CELL_NIB_NAME, bundle: nil)
            tableView.register(cellNIB, forCellReuseIdentifier: CELL_ID)
            
            tableView.delegate = self
            tableView.dataSource = self
            
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
}

extension TableViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dummyModel.count
        
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: CELL_ID, for: indexPath) as? TableViewCell else {
            return UITableViewCell()
        }
        let user = dummyModel[indexPath.row]
        cell.configure(contents: user)
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 200
    }
    
}
extension TableViewController: UITableViewDelegate {
    
}
```

##View

```ruby:TableViewCell.swift
import UIKit

class TableViewCell: UITableViewCell {
    
    @IBOutlet private weak var pctureImage: UIImageView!
    @IBOutlet private weak var numberName: UILabel!
    @IBOutlet private weak var menuName: UILabel!
    
    
    override func prepareForReuse() {
        super.prepareForReuse()
        pctureImage.image = nil
        numberName.text = nil
        menuName.text = nil
    }
    
    
    func configure(contents: CellModel) {
        menuName.text = contents.menu
        numberName.text = contents.number
        
    }
    
    
}
```

##Model

```ruby:CellModel.swift
import Foundation

struct CellModel {
    var number: String
    var menu: String 

}
```
ねんがんの 枠線付き角丸三角 をてにいれる with mixin

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248832/f85d2058-bacd-51ab-bd82-f64ac9e564cb.png)
「 [Creating rounded triangles in CSS with clip-path | CodyHouse](https://codyhouse.co/blog/post/css-rounded-triangles-with-clip-path) 」という記事で `clip-path` を使うと三角に枠線どころか角丸も適用できることを知りました。すごい！え、二年前から知ってる？あ、そう…でも専用の Mixin を作ったし、吹き出しも作ってみたので、とりあえず載っけておきますね…。

## 枠線付き角丸三角で吹き出しを作る
HTML はこんなんです。

```html
<div class="baloon">うんち</div>
```

Sass の Mixin がこちら。必要最低限です。

```sass
@mixin triangle ($direction) {
  clip-path: polygon(0 0, 100% 100%, 0 100%);
  @if $direction == up {
    transform: rotate(135deg);
  }
  @else if $direction == down {
    transform: rotate(-45deg);
  }
  @else if $direction == left {
    transform: rotate(45deg);
  }
  @else if $direction == right {
    transform: rotate(-135deg);
  }
}
```

ちょっと長くなってしまいましたが、 Sass がこちら。吹き出し用の Mixin を別途用意しても良いかもしれません。

```sass
.baloon {
  background-color: #ffffff;
  border: 8px solid #000000;
  border-radius: 1rem;
  box-sizing: border-box;
  margin: 4rem;
  position: relative;
  width: 32rem;
  height: 16rem;

  &::after {
    @include triangle(down);
    background-color: inherit;
    border: inherit;
    border-radius: 0 0 0 1rem;
    box-sizing: border-box;
    content: "";
    display: block;
    margin-left: -2rem;
    position: absolute;
    left: 50%;
    bottom: -2rem;
    width: 4rem;
    height: 4rem;
  }
}
```

これで扉画像のような吹き出しができるはずです。
ただし、 `&::after` の `width` と `height` には同じ値を設定する必要がある…と思います。詳しい説明は [こちらの記事](https://qiita.com/yuta-38/items/e0df334755d4f4a42d2d) へどうぞ（丸投げ）。
あと `px` 以外の単位だと、描画に若干のズレが生じるかもしれません。それな。

## 普通の三角 Mixin

```sass
@mixin triangle ($direction) {
  @if $direction == up {
    clip-path: polygon(0 100%, 100% 100%, 50% 0);
  }
  @else if $direction == down {
    clip-path: polygon(0 0, 100% 0, 50% 100%);
  }
  @else if $direction == left {
    clip-path: polygon(100% 0, 100% 100%, 0 50%);
  }
  @else if $direction == right {
    clip-path: polygon(0 0, 0 100%, 100% 50%);
  }
}
```

この方法だと枠線も角丸も適用できませんが、 `width` と `height` に別々の値を設定できます。適材適所。
【RSpec】【Capybara】非表示にしている要素の取得の仕方

# 解決したいこと
![3ea158441107e30634a3f2e5724b9a11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182947/ce8797be-9b87-feb9-50bb-a5dce3036c5c.gif)
結合テストコードを作成している際に、
上のようにメニューボタンを押した時だけ現れるテキストを確認するために、

```users_spec.rb
expect{
  find('input[class="menu-btn"]').click
}.to have_content('新規登録')
```
このように記述したらエラーが出ました。
調べると、非表示になっている要素は書き方を変えないと検出されないとのことでした。
# 今回の解決方法

```users_spec.rb
expect(find('.menu-content', visible: false).text(:all)).to include '新規登録'
```
上のような書き方で無事テストを通せるようになりました。
visible: false のオプションで非表示になっている要素も含めて検出できるようになります。

参考
https://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders
https://chaika.hatenablog.com/entry/2019/10/08/083000
テキスト編集したい時

# テキストの編集あれこれ

このページはviやshellの使い方をマスターするといった内容でなく、テキスト編集時の際はこんな方法を使えば早く仕上げることができる、といったことを解説したページになります。普段テキスト編集したい時、その時のやりたい内容に応じてvi使ったり、shellの様々なコマンドやらと組み合わせて実現するのでそれの備忘録。

# ファイルの文字列を置換


### ケース１：複数ファイルの同じ文字列を置換する場合


同じような置換をしたいファイルが複数ある場合、ひとつづつファイルを開いて変更すると時間がかかる場合に一括変換する方法。
sedの`-i`オプションで上書き置換となるのでこれを利用。また`-i.bak`とやると.bakという拡張子でコピーが作成されるので、バックアップとして使える。ただし置換されないファイルを含め、全てのファイルに対してバックアップを作る。

例えば`txt`の拡張子を持つ複数のファイルがあって、ファイル中の`hoge`で終わる文字列を`HOGE`に変換する場合は以下の通り。

```shell
$ sed -i.bak 's/hoge$/HOGE/g' *.txt
```

### ケース2：複数のサーバに置換したいファイルが複数ある場合

複数のサーバにファイルがある場合はansibleを使って置換が加納。web01,web02の２つのサーバにあるファイルを置換する場合は以下。

playbookのインベントリファイルの定義。

```inventory/inventory.ini
[web:children]
web01
web02
###
[web01]
10.10.10.10
[web02]
10.10.10.11
```
置換したいファイルを絶対パスで指定。/tmpフォルダにあるtxtの拡張子

```shell
$ ansible -i inventory/inventory.ini web -m shell -a 'sed -i.bak s/hoge$/HOGE/g /tmp/*.txt'
```
### ケース３：マッチした文字列の行の上／下に文字列を追加する
マッチした文字列の上／下に任意の文字列を追加する。
複数ファイルが対象の場合はケース１と同じ。

```test.txt
aaa
bbb
# comment
ccc
```
`# comment`行の上に文字列を追加する場合

```shell
$ sed -i '/^# comment/i ----上に行追加' test.txt 

$ cat test.txt
aaa
bbb
----上に行加行
# comment
ccc

# 下に行を追加する場合
$ sed -i '/^# comment/a ----下に行を追加' test.txt 
```


## テキストの各行に文字や数値を入れたい

下記のようなテキストの各行の先頭に文字や数値を入れたい場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/d70b45bd-6f43-f822-81be-aa5af982b165.png" width=30%>

色々やり方はあるかと思いますが、私はviで以下のようにして編集する。
CSV風に`0,`を入れる場合はこんな感じ。

```vim
# viのノーマルモードで以下を実施
gg # ファイルの先頭行に移動
V  # 行指定のVisualモード（範囲指定の<C-g>でもオッケー）
G  # ファイルの最終行まで範囲指定
:normal I0,<RTN> # ノーマルモードからのI(行先頭インサート)での「0,」を入れる！
```
viで実行した結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/e87bdc3b-d267-4dd6-046e-5bd44a2194ce.png" width=30%>

ちなみにviのキー操作の最後`:normal I0,<RTN>`を`:normal A,0<RTN>`にすると各行の最終行に`,0`が挿入される。

## 挿入した各行の数値を変更する
テキストに連番を振りたい場合やテキスト内の数値を変更したい場合もviを使って実施する

### 連番を振る場合

```vim
# viのノーマルモードで以下を実施
gg # ファイルの先頭行に移動
<C-v> # Ctrl+vでVisualモード
G  # ファイルの最終行まで数値を指定
g<C-a> # g押下後にCtrl+aで数値をインクリメント
```

`G`で最終行まで数値を指定した場合
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/dd293dcc-419b-4770-9cb5-30b1b6710878.png" width=30%>

`g<C-a>`で指定した範囲に連番をふった結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/c29fabab-7e11-009e-ae3f-7a69f6a58377.png" width=30%>

`g`がないと各行同じ分だけ数値が増加する。例えば`11<C-a>`だと下記のようになる。逆に減らす場合は`<C-x>`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/370698af-e2da-6851-dce9-cf935c5c5f5e.png" width=30%>

###　"0x"の数値に連番を振る場合

set nf=""
レガシーコードの不具合にテストを書いて立ち向かう #1 基本的な手順

# はじめに

[レガシーコード改善ガイド](https://www.shoeisha.co.jp/book/detail/9784798146355)によると、レガシーコードとは(自動)テストのないコードです。本記事では、そんなレガシーコードの不具合を修正するときに必要な手法について説明します。

和田卓人さんによる下記のエッセイをベースに、レガシーコードの世界におけるアレンジを加えています。まずは下記のエッセイを読んでから、改めてこの記事を読んでみてください。

https://ja.wikisource.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%8C%E7%9F%A5%E3%82%8B%E3%81%B9%E3%81%8D97%E3%81%AE%E3%81%93%E3%81%A8/%E4%B8%8D%E5%85%B7%E5%90%88%E3%81%AB%E3%83%86%E3%82%B9%E3%83%88%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E7%AB%8B%E3%81%A1%E5%90%91%E3%81%8B%E3%81%86

# レガシーコードに対する不具合修正の手順

上記のエッセイにあった「不具合修正時のテストの手順」を、２点アレンジしています。
この流れに沿った修正が、レガシーコードの不具合に立ち向かうための道筋です。

1. E2Eテスト(打鍵テスト)で不具合を再現させる
1. 再現時と同じログ(スタックトレース)が出力されるテストコードを書く
1. 2で書いたテストコードを実行し、落ちることを確認する(Red)
1. 不具合を修正する
1. 2で書いたテストコードが通ることを確認する(Green)
1. テストコードが通っている状態を保ったまま、コードをリファクタリングする(Refactor)
1. E2Eテストを再度実施し、不具合が修正されていることを確認する

以下、アレンジした箇所について説明します。

## アレンジ1: テスト駆動開発のサイクルを追加

テスト駆動開発の基本的なサイクルは、Red→Green→Refactorです。
しかし、テストコードを書いていないときの習慣が残っていると、このRefactorを忘れがちです。
このため、手順に明記するようにしました。

テストコードを書いていないときは、修正の結果確認はE2Eテストに頼っていました。しかし、E2Eテストには手間や時間がかかるので、リファクタリングした後にそれを再実行するのは面倒です。このため、リファクタリングはおろそかになりがちでした。

しかし、上記の不具合修正の手順で書いたテストコードは、すぐに何度でも実行が可能です。このため、ストレスなく快適にリファクタリングができるはずです。

テストコードが通ったことを確認したら、そのコードをリファクタリングする必要性を思い出してください。

### リファクタリング時の注意点

上記のリファクタリングですが、1つ注意点があります。

テストコードによるカバレッジが不十分な場合(100%ではない場合)は、今回修正したコードの範囲に留めてください。周辺のコードをリファクタリングしたくなった場合は、その部分のテストコードを書いてから実施するようにしましょう。

## アレンジ2: E2Eテスト(打鍵テスト)を追加

「E2Eテスト」を手順に明記しました。

E2Eテストが必要な理由は「不具合の原因となるコードは、1箇所だけではないかもしれないから」です。仮に原因となるコードが2箇所以上だった場合は、ほかの箇所が修正されていないと、不具合は直りきっていないことになります。

しかし、そうなると、結局、E2Eテストが必要なことには変わりがないじゃないか。むしろテストコードを書く手間が増えている、という指摘があるかもしれません。

数日レベルの短期的なことを考えれば、その通りです。

### それでもテストコードを書いたほうがいい理由

しかし、改めてテストコードを書かないケースと比較してみてください。不具合の修正を確認するために、アプリケーション全体の起動が必要な回数は減ったのではないでしょうか。

また、テストコードを書くコストを回収できるタイミングは、思ったより早くやってきます。下記の記事の「内部品質や保守性への投資はいつ実るのか？」を読んでみてください。

https://www.publickey1.jp/blog/20/_2020_1.html

# おわりに

上記の手順を踏むことで、テストのないレガシーコードに対して、テストを生み出すことができます。このやり方を繰り返せば、「レガシーコードをこれ以上増やさないようにする」力を身につけることができるでしょう。

しかし、実際にやってみると、思うようにはいかないケースがあるかもしれません。その一つは、テストコードを書くときに既存のコードの内容が理解できないというケースです。

そのようなときの助けとなる手法として、次回の記事では「仕様化テスト」について説明しようと思います。
技術に5万時間費やしたエンジニアが、次に1万時間費やす技術


![IMG_4692 - コピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131196/b9450e19-7f09-793c-56d4-8bfd2afb0e4d.jpeg)

[短答パーフェクト2022版 全７科目８冊セット（2022年対策）](https://tatsumi.co.jp/web-store/tanto_perfect22_2/)

![tatsumi_perfect1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131196/fd105089-7150-3d98-03fe-6a5301bb8359.jpeg)

![tatsumi_perfect2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131196/665c624e-e8b1-5206-00e7-ab64f5b24dd3.jpeg)
[JavaScript] 配列オブジェクトをオブジェクトに変換する4つの実装方法

# はじめに

配列オブジェクト（オブジェクトを要素に持つ配列）を
オブジェクトに変換する実装方法を4つ紹介します！

# 問題

```js
// この配列を
const sampleArray = [
  {id: '1', name: 'React'},
  {id: '2', name: 'Angular'},
  {id: '3', name: 'Vue.js'},
];

// こうしたい
{
 '1': { id: '1', name: 'React' },
 '2': { id: '2', name: 'Angular' },
 '3': { id: '3', name: 'Vue.js' },
}

// どうやって実装する？
```

# 解法1

for...of...構文を使って実装する

```js
let sampleObj = {}

for(const element of sampleArray) {
    obj1[element.id] = element;
}

console.log(sampleObj);

// 出力結果
{
 '1': { id: '1', name: 'React' },
 '2': { id: '2', name: 'Angular' },
 '3': { id: '3', name: 'Vue.js' },
}
```

# 解法2

forEach関数を使って実装する方法

```js
let sampleObj = {}

sampleArray.forEach((cur) =>
  sampleObj[cur.id] = cur;
}

console.log(sampleObj);

// 出力結果
{
 '1': { id: '1', name: 'React' },
 '2': { id: '2', name: 'Angular' },
 '3': { id: '3', name: 'Vue.js' },
}
```

# 解法3

reduce関数を用いて実装する

```js
const result = sampleArray.reduce((acc, cur) => {
    acc[cur.id] = cur;
    return acc;
},{})

console.log(result);

// 出力結果
{
 '1': { id: '1', name: 'React' },
 '2': { id: '2', name: 'Angular' },
 '3': { id: '3', name: 'Vue.js' },
}
```

reduce関数の第二引数に「空オブジェクト」を渡すことで
配列をオブジェクトに変換することができます

# 解法4

reduce関数と[Computed Property Names（MDN）](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names)を用いて実装する

```js
const result = sampleArray.reduce((acc, cur) => ({...acc, [cur.id]: cur}), {});

console.log(result);

// 出力結果
{
 '1': { id: '1', name: 'React' },
 '2': { id: '2', name: 'Angular' },
 '3': { id: '3', name: 'Vue.js' },
}
```

[Computed Property Names（MDN）](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names)を用いると
処理が1行で書けるのでコードが簡潔になって便利です！

# 参考文献

[for...of... | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of)
[forEach | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
[reduce | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
【VSCode】Prettierの使い方 備忘録

# Prettierとは
[Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)とはソースコードを
一貫したスタイルに自動整形してくれるツールである。

## 利用シーン
* 自分のコードを楽にに綺麗に整形したい
* 複数人で開発しており、書き方に統一性を持たせたい
* コードが読みづらいので可読性を上げたいなど


## 利点
* 開発者間で統一した共通のスタイルにすることが可能
* 開発者はコードスタイルを意識することなくコーディングに集中できる。
* 可読性の高いコードを作成できる。



# インストール手順
①. VScodeの拡張機能からインストール
②. 設定
③. 使用


## インストール
VSCodeにPrettierプラグインをインストールします。

![Prettire1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914798/0da599b1-61d0-2b83-cef6-ac9f9076d239.png)

![Prettire2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914798/4ac6ae1e-9a2d-531f-8dfc-0d6567d50879.png)

以上でインストール完了。


## 設定
![Prettier3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914798/321a2af9-85c9-a611-2454-640dd2b4f86a.png)

![Prettire5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914798/46951edc-debf-667d-5307-d24db41e449b.png)

以上で設定完了。

## 使用

コードを保存するとコードをフォーマットしてくれる。
以上
【Swift】UISwitchの色を変更する

# どういうことか

コレ

![スクリーンショット 2014-09-14 14.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/a7f9b412-98e0-1468-7a83-d936cc5c1b97.png)

――の、 ◯ の部分とかの色を変えたい。

## やる

```swift
@IBOutlet weak var toggleSwitch: UISwitch!

// 中略

// ◯の部分
toggleSwitch.thumbTintColor = UIColor.black
// ◯じゃない部分
toggleSwitch.onTintColor = UIColor.orange
```

たとえばスイッチオンのときだけ色を変えたい場合はif文を使えばよい。

```swift
// メンバ変数
var toggleSwitchCheck = false

// 中略

if toggleSwitchCheck {
    toggleSwitch.setOn(false, animated:true)
    toggleSwitchCheck = false
    toggleSwitch.thumbTintColor = UIColor.white
} else {
    toggleSwitch.setOn(true, animated:true)
    toggleSwitchCheck = true
    toggleSwitch.thumbTintColor = UIColor.orange
}
```

完(´・ω・｀)
JaCoCoをeBuilderから起動したresinで使うときのメモ（チラシの裏レベル）


JaCoCoはシャットダウンフックで結果をファイルに書き出す操作となっていますが、  
eBuilderからresinを起動、停止してもファイルが出力されないので、どうやらシャットダウンフックが動作していないみたいです。（2019頃の記憶）
結果ファイルを出力するには下記手順が必要みたいです。

≪手順≫  
① eBuilderのサーバー起動構成のVM引数に jmx=true を追加  
＜サンプル＞  

    -javaagent:D:/tools/jacoco/jacoco-0.7.5.201505241946/lib/jacocoagent.jar=jmx=true,destfile=D:/tools/jacoco/jacoco-0.7.5.201505241946/lib/jacoco.exec,includes=jp.co.intra_mart.*

※ jacocoのjarと実行ファイルのパスは環境に合わせてください

② eBuilderからサーバー(Resin)を起動  
③ 画面操作を行う  
④ JMXでorg.jacoco:type=Runtimeのdumpメソッドを実行  
　　1. 【JAVA_HOME】\bin\jconsole.exe を起動し、実行中のresinに接続  
　　2. [MBean]タブのツリーから以下の画面を開く  
　　　　org.jacoco - Runtime - 操作   
　　3. 右ペインの[dump]ボタンを押下  

で出力されると思います
Notionの使い方メモ

**Notionの使い方**

・任意の場所をクリックして入力を開始する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/2171d43d-919f-6b99-97fd-b98887c5807c.png)
・左のプラスボタンをクリックするとヘッダー、ビデオ、サブページなどの追加されるすべてのコンテンツが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/27c3527e-cc14-0c7b-de22-433ea350ee11.png)
クリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/bec8bd04-5a36-d193-0af5-12b117077423.png)
・Notionではページ内にページを無限に入れ子にすることができる。もうごちゃごちゃしたフォルダは必要ない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/c753ab1a-c15a-c3d5-7022-480b7dc20479.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/e6f2849b-5e34-cf3e-7774-1ef6b6a93117.png)
・任意のテキストを選択した状態で表示されるメニューで文章を自由にアレンジすることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/5bd5f70a-8ad8-1993-2e1e-449fc62b7730.png)
・左の::マークをドラッグすることで上下に移動させることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/9117786b-e06e-0559-7f98-fae086e04a97.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/0d702c63-ba31-c502-45cd-a395770a8d6c.png)
・左のサイドバーに表示されている+Add a pageをクリックすると新しいページが追加される。（クリックするとUntitledページが作成された）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/a8073632-af2e-1d56-da5a-0c024353b3c1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/38203523-e272-c715-c57a-8b4f6f35ac17.png)
・左のサイドバーのTemplatesをクリックすると予め作成されたページが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593111/18ab13cb-c452-6748-735c-1a3ef3cac589.png)
・トグル

休憩中
React RouterのBrowserRouterを使うと404が返ってくる

React RouterのBrowserRouterを使っている場合、ブラウザバックしたり下層ページのURLを直打ちしてアクセスすると404が返ってくる。
これはリクエストしているリソースへのアクセスをサーバが拒否しているからだが、ワイルドカードでルーティングをしてやれば解決する。

例えばRuby on Railsなら以下のようにルーティングを書いておく。

`config/routes.rb`

```ruby
Rails.application.routes.draw do
  match '*path', to: 'react#index', via: :get
end
```

`app/controllers/react_controller.rb`

```ruby
class ReactController < ApplicationController
  def index
  end
end
```

このとき `app/views/react/index.erb` 等のviewファイルは必要ない。



## 参考

- [Single Page ReactJS Applications and Server Side Rendering Using Ruby on Rails](https://medium.com/@jefawks3/single-page-reactjs-applications-and-server-side-rendering-using-ruby-on-rails-5ff46986c23e)
【Swift】なぜViewModelの型はModelTypeであるべきなのか


MVVMで設計するうえで、

```Swift
viewModel: ViewModelType
```
のようにviewModelの型をModelTypeとして宣言すると思う。
もしくは、この記事で説明したいことがわかっていないところでは

```Swift
viewModel: ViewModel
```
のようにViewModelクラスをそのまま型としていると思う。
なぜviewModelの型をModelTypeとすべきなのかを説明していく。

##インターフェースによる疎結合
理由はこの見出しが全てで、インターフェースによる疎結合が
最大のメリットだと自分は考える。
(インターフェースがわからない人は、調べて欲しい)
(SOLIDの原則に遵守するうえで、インターフェースはとても有効である。)

どういうことかというと、ModelTypeを型にすることで、
viewModelにはインターフェースのinputかoutputにしかアクセスできなくなる。

つまり、**インターフェースを介すことを強制する**のである。
インターフェースを介すことで疎結合が保証され、テスタビリティが保証される。


##終わりに
ModelTypeで宣言する意味がわかったことで、割と大きな意味があったことが理解できたと思う。
それでもModelTypeとするかはここの考えや技量にもよると思うのでこれが絶対！とは言わないが、
個人的には規約としたいレベルである。
Windows Admin Center を Azure CLI でインストールしてみた

## 背景と目的

Azure ポータル上で Windows Admin Center がプレビューで使えるようになったのですが、Azure CLI でのインストール方法が不明だったので実際にやってみました。

 [Announcing public preview of Windows Admin Center in the Azure portal](https://cloudblogs.microsoft.com/windowsserver/2021/03/02/announcing-public-preview-of-window-admin-center-in-the-azure-portal/)

## 前提条件

Azure CLI のバージョンを確認します。

```zsh:zsh
az version                            

{
  "azure-cli": "2.21.0",
  "azure-cli-core": "2.21.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}
```

## 実施内容

```zsh:zsh
# パラメーターを設定
azRG=myResourceGroup
azRegion=japaneast
azVMName=myVM
azUserName=azureuser
azPassword=$(openssl rand -base64 16)
echo $azPassword

# リソースグループを作成
az group create \
  --name $azRG \
  --location $azRegion

# VM を作成（ NSG は後ほど設定）
az vm create \
  --resource-group $azRG \
  --name $azVMName \
  --image Win2019Datacenter \
  --admin-username $azUserName \
  --admin-password $azPassword \
  --size Standard_DS1_v2 \
  --nsg-rule NONE \
  --storage-sku Standard_LRS

# VM エージェントが動作しているか確認
az vm run-command invoke \
  --command-id IPConfig \
  --resource-group $azRG \
  --name $azVMName

# AdminCenter をインストール
az vm extension set \
  --resource-group $azRG \
  --vm-name $azVMName \
  --name AdminCenter \
  --publisher Microsoft.AdminCenter \
  --settings '{"port":"6516", "cspFrameAncestors":["https://portal.azure.com","https://*.hosting.portal.azure.net","https://localhost:1340"], "corsOrigins":["https://portal.azure.com","https://waconazure.com"]}'

# 自分自身の IP アドレスを変数にセット
myIP=$(curl -s inet-ip.info)

# NSG 名を変数にセット
azNSG=$(az network nsg list \
  --resource-group $azRG \
  --query "[].name" \
  --out tsv)

# NSG に自分自身の IP アドレスからポート 6516 への接続を許可するルールを追加
az network nsg rule create \
    --resource-group $azRG \
    --name WAC \
    --nsg-name $azNSG \
    --priority 1000 \
    --source-address-prefixes $myIP/32 \
    --destination-port-ranges 6516 \
    --access Allow \
    --protocol Tcp
```

## 実施結果

無事 Azure ポータルから Windows Admin Center を使うことが出来ました。

こちらのスクリーンショットは、リモートデスクトップの画面です。

![admin-center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/2b1f0018-000c-419d-a3f3-76425702a5f4.png)

## 参考

標準ポートは 6516 ですが、443 でインストールしても Windows Admin Center を使うことが出来ました。
Linuxコマンドを使いたい

機械に使われることのなよう、機械を使いこなす為にコマンドを覚えたいと思います。
頑張ろう。
##Linuxの使い所
エンジニアはLAMP（L:Linux、A：apache、M:MySQL、P:PHP）環境で開発を行っていくことが多い。そのためLinuxコマンドは仕事をしていく上で必須の技術。
ちなみにLinuxコマンドは一つのプログラミング言語らしい。

LAMP環境を調べていくと2021年現在ではLAMP環境は少しづつ古い技術になってきているとのこと。
面白い話が下記記事にありました。

[LAMP環境はオワコン？ 今後のインフラ技術と何を勉強するか](https://www.threenext.com/lamp/)


結局のところ、これからの技術ではLAMP環境の応用をしていくことになるとのことだったので、まずはLAMP環境を身に着けてこれからに対応できるようにしたいです。



##基本のコマンド
###ｃｄ
ディレクトリの移動。

```
cd Documents
```

###ｌｓ
フォルダの内容を一覧表示。
ｃｄで移動後にｌｓコマンドを叩くと移動したフォルダの中身を一覧で表示することができる。

```
ls -a　//隠しファイルの表示

ls -l  //テキストファイルの表示
```

###ｍｖ
ファイルの移動

```
ｍｖ A B　//　ファイルAをBディレクトリに移動
```

###ｃｐ
ファイルのコピー。

```
ｃｐ A B　//AファイルをBディレクトリにコピー
```

###claer
ターミナル上を綺麗な状態にしてくれる。

###mkdir
フォルダの作成

```
mkdir A　//Aフォルダの作成
```
###touch
ファイルの作成

```
touch A　//Aファイルの作成
```

###dir
フォルダやファイルの削除

```　
dir A  //Aフォルダ（Aファイル）の削除
```

###ｐｗｄ
いまいるディレクトリの表示

###find
ファイルの検索

###cat
ファイルの中身を表示

###vim
ファイルの中身を見る。（catと似ている）

```
insert  //ファイルの中身を編集する
ｑ！　//編集したファイルを保存しないで終了する
wp　//編集したファイルを保存する
```
###diff
ファイルとファイルの内容の違いを表示。

```
diff A B  //AファイルとBファイルの違いを見る
```

##最後に
自分が使ったことのあるコマンドをまとめました。未使用のコマンドを記載したところで記憶には残らないので記載しません。

新しいコマンドの使用経験がある度に随時更新します。
TypeScriptでstyled-components内のmediaQueryを管理する。

# 背景
`styled-components`を利用することが多いのですが、プロジェクト全体で`MediaQuery`の指定がバラバラだったり、`max-width`と`min-width`が混合していてキモチ悪かった😥のでヘルパーを用意することでmediaQueryを管理しました。


# コード
`TypeScript`で書きました！！！よかったら参考にしてください。

```js:mediaHelper.ts
type ScreenType = "desktop" | "tablet" | "phone";

const sizes: { [key in ScreenType]: number } = {
  desktop: 1024,
  tablet: 768,
  phone: 560,
};

export const media = (Object.keys(sizes) as Array<keyof typeof sizes>).reduce(
  (acc, key) => {
    acc[key] = (style: String) => {
      return `@media (max-width: ${sizes[key]}px) { ${style} }`;
    };
    return acc;
  },
  {} as { [key in ScreenType]: Function }
);

```
[Java]文字列に含まれる特定の文字の個数を数えたい

# はじめに

文字列`"hogetext"`は`t`を いくつ含んでいるのか？という問題を例として、
文字列に含まれる文字の個数を数えてみました。

# 方法
次のような手順で算出しました。

1. 文字列を1文字ずつ、配列に格納する
2. 調べたい文字と配列の中身を次々と比較し、一致するかを調べる

# ソースコード


```Java
        int count = 0;  // 数え上げた結果を格納する
        String str = "hogetext";

        // 文字列を1文字ずつ配列に格納する
        String[] ary = str.split("");
        
        for(int i=0; i<ary.length; i++){
            System.out.print(ary[i] + " ");
        }
        // "h o g e t e x t "が出力される
        
        // 指定した文字の個数を数える、ここではtの個数を数えたい
        for(int i = 0; i<ary.length; i++){
            if ("t".equals(ary[i])){
                count++;
            }
        }
        System.out.println(count);
        // 2が出力される
```

# 参考
- [【Java】文字列を1文字ずつ取り出す](https://chibicat.hatenablog.jp/entry/2018/06/19/230333)
- [Javaで文字列を1文字ずつ配列に格納する方法](https://yuu.1000quu.com/java_string_to_array)
PMがPTA広報の部長になった訳だが(2)

# 啓蟄
年度切り替え前の3月初旬の事です。
簡単に言うと妻の勤務先はリモートワークがしずらく、対して私の会社はコロナ前からリモートワーク可能だった為、在宅している私がPTA活動を妻から引き継ぎました。
正直に言うと今まで妻にPTA活動を押し付けており、PTA活動が何もわかっていません。

新年度に向けた役職決め会議があるのでとりあえず参加した所、まぁ誰も立候補せずこのままだとくじ引きで役職決めするという雰囲気に耐えらなくなりました。
開始10分でこりゃ問題ありな組織だと気づき、組織運営を健全化したい欲求が頭をもたげてしまったので部長に立候補します。

私が立候補した事でじゃあ私もと副部長、書記、会計に立候補してくれた方がいたので最悪のPJ体制は回避されたと思います。少なくとも自分の意志で引き受けてくれた人で役職が構成されたので。

##LINEの悲劇
ここでPTA広報部LINEがある事を知らされ、広報部、広報部役職、広報部と本部連絡用の３つのLINEグループに私自身を登録します。

正直LINEは使わないで済むなら使いたくなく派です。
友人関係でLINEしか使えない人が居る為仕方なく導入してますが、PTAではLINEがデファクトスタンダードです。discord提案しても導入障壁が高すぎて現時点ではLINEを許容せざるを得ませんでした。

部長になったので率先して部員の方達とQRコード交換して友達登録して広報部LINEグループへ誘導...を始めると私を友達登録できないとの報告があり、そういえば友達検索禁止してたなと設定変更た時に、時間がなく急いで操作したのでミスオペを起こします。**アドレス帳とLINEの同期…**
気が付いたのは時間が経ってからで何故かLINEアカウントを持ってる企業の番号、会社支給携帯が配備される前に仕方なく登録した同僚の番号、関係の切れた人、連絡とりたくもないしがらみのある人、**昔付き合ってた彼女…**
男性はアーカイブ、女性は上書き保存の法則通り私もアドレス帳に残ったままでした。
速攻LINEの友達登録を削除します。削除操作が1件毎なので時間かかるったらありゃしない。
LINEは悪い文明、LINE滅ぶべし、慈悲はない。

##甘い認識
過去資料が残ってるだろうし、それみて同じように1年間PJをドライブすればいいや程度の軽い認識でした。
早速前部長と引き継ぎを始めますが

* 昨年は何も活動なかったので何も分かりません
* 資料は2年前のが残ってる**　筈！　**なのでそれ見てください
* 新一年生への次回部会開催連絡と本日欠席者への**紙の手紙**は前役職が最後の仕事としてやっておきます

PJから逃げたい人の引継ぎ発言BEST!って感じです。
短時間で過去資料を査読する事も出来ず、後でLINEグループで確認すればよいかと解散します。

LINEグループに新部長ですよろしくお願いします、の投稿しても返信がなく既読だけはついていきます。
あれ、PJ内のチャットの感覚で使ったんだけど、私空気読めてませんでした？

返信も何もない事に気が抜けてしまい、この後部長である認識も薄くなりのほほんと過ごしてしまいました。
Raspberry Pi 4B にWindows10ARMを入れて SSDからブート その後２


そろそろ 21H1 シリーズのインストールに挑戦ということで 19043.906をSSDにインストールして
Raspberry Pi 4Bで起動、セットアップをやってみました

ISOファイルはuup dumpから　21H1 のボタンを押して
Feature update to Windows 10, version 21H1 (19043.906) arm64 
を使ってISOファイルを作成しました

WORで玄人志向GW2.5CR-U3のSSDに書き込みました

ここまでは通常の手順です

ここからひと工夫します

1.SSDをラズパイに接続してスイッチオン 
2.ラズパイブート画面が表示されたら ESC を押す
3.Device Managerを選択
4.Raspberry Pi Configuration を選択
5.Display Configuration を選択
6.解像度の設定を Virtual 720p を選択
7.Native resolution のチェックをクリア
8.F10　を押して　y を押す
9.ESCを押して画面を戻していき　Continue を選択

Windowsがブートしてデバイス設定、準備、リブート、セットアップとなります
インストールが無事成功しましたら解像度の設定をもとに戻してください

Windows updateとかでブートに失敗したら解像度を720pに設定して見てください

firmware は３月１８日のものを使用しました
Logitec LMD-SPA240U3　でもインストールできました


参考情報
https://www.youtube.com/watch?v=2EAgc7MLbNE

この続きは　https://qiita.com/jibri/items/2bf9663206bf468aa61c
julia を googlecolab で使えるようにしたい。

このテンプレートの実行をポチっとする。

https://colab.research.google.com/github/ageron/julia_notebooks/blob/master/Julia_Colab_Notebook_Template.ipynb#scrollTo=tQ1r1bbb0yBv

```julia
versioninfo()

Julia Version 1.6.0
Commit f9720dc2eb (2021-03-24 12:55 UTC)
Platform Info:  OS: Linux (x86_64-pc-linux-gnu)
  CPU: AMD EPYC 7B12
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, znver2)
Environment:  JULIA_NUM_THREADS = 2
```

Rf.
https://stackoverflow.com/questions/58270424/julia-in-google-colab
【エラー備忘録】LaravelでNamespace declaration statement has to be the very first statement or after any declare call in the script のエラー

##状況

Laravelでアプリケーションを作成中、localhostを立ち上げると次のようなエラーが出た。

「　Namespace declaration statement has to be the very first statement or after any declare call in the script　」


##原因
・namespaceの上に何も書いてはいけない
・<?php の上に何も書いてはいけない
ということのようだ。


エラーが指していたのは、Articleモデルである app/Article.php のファイル。


##解決策
app/Article.php の <?php の上に、コメント化したメモを書いていた。
それを <?php の下に移動させてみると、正常に画面表示された。
Jetpack Composeでリストの最後を検知する

Jetpack Composeでリスト表示を作るとき、今までのRecyclerViewのようにリスト表示を作るとき、 `LazyColumn`というComposableメソッドを使うと思います。

この `LazyColumn`の引数には、 `LazyListState`型の `state`を渡すことができ、これによって今リストのどのへんをスクロールしてるかなどの状態を参照したり、操作したりできるようになります。

そして本題のリストが最後のItemまでスクロールされたかどうかを検知する方法ですが、自分は今の所下記の方法で実装しています。

```kotlin
val listState = rememberLazyListState()
        LazyColumn(
            contentPadding = LocalWindowInsets.current.systemBars
                .toPaddingValues(top = false, start = false, end = false),
            state = listState
        ) {
                if (listState.firstVisibleItemIndex + listState.layoutInfo
                .visibleItemsInfo.size == listState.layoutInfo.totalItemsCount) {
                      // なにかする
                }
            }
        }
```

`listState` がリストの状態を持っている変数です。

`listState.firstVisibleItemIndex`が今画面に表示されている一番上のItemのindexを持っています。そして、`listState.layoutInfo.visibleItemsInfo.size`が今画面に表示されているItemの数を持っています。これを足した値が、 `listState.layoutInfo.totalItemsCount`である全体のリストの長さと同じになったときリストが一番最後までスクロールされた状態であることがわかります。

自分はこの方法でやっているのですが、もっとスマートなやり方がありそうなので詳しい方教えてくださると嬉しいです。

そのうち、デフォルトでリスナーみたいなのが `LazyListState`から生えるといいな。。。。

ちなみに、 `LazyListState`には `listState.animateScrollToItem()`っていうのがいてよくある、リストを一番上まで一気にスクロールさせるようなものも簡単に実装できそうです。
IEEE 802.11無線LAN規格の備忘録

IEEE 802.11無線LAN規格の備忘録です。

# IEEE 802.11 規格文書の関係図

IEEE 802.11規格文書の関係図です。
表記してあるのは、文書のタイトルと、文書のURLです。
赤色背景は、現在（2021年3月）有効な規格文書です。
「Supersed」は置き換えを意味します。例えば、802.11-1999は、802.11-1997を置き換えます。
「Amendment」は修正・追補を意味します。例えば、802.11ac-2013は、802.11-2007の修正・追補です。

![IEEE80211DocumentHierarchy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/b692da03-bf8d-748b-4ff0-1a88d513d2b5.png)

どういうふうに進化してきたか、なんとなくわかるかなー？

# 規格はいろいろあったけれど

これから使う場合には、Wi-Fi 4/5/6だけ知っていれば大丈夫そうです。

# Wi-Fi 6 (802.11ax)

現在(2021年3月)策定中です。
1GHz〜7.125GHzを使う規格ですが、実際の製品は2.4/5GHzになるそうです。
大多数のユーザが同時接続できることを目指しています。

# Wi-Fi 5 (802.11ac)

5GHz帯を使います。

# Wi-Fi 4 (802.11n)

2.4/5GHz帯を使います。
【Java】Doubleとdoubleの違いは何か？

# 結論
Double：オブジェクト型
double：プリミティブ型
「Doubleはdoubleをラップしたオブジェクトである」ということです。

(・ω・´。)ん？つまりどういうこと？

こゆこと。
　↓
Double：オブジェクト型　→　フィールド（単一のdouble値）、メソッドを持つ
double：プリミティブ型　→　単一のdouble値を持つのみ
※Integer（オブジェクト型）とint（プリミティブ型）の関係と同じなので、そっちの方が理解しやすいかもしれませんね。

# ソースコード
``` Double.java
// オブジェクト型
Double d_obj = new Double(1.0D);			// Java8まで
Double d_obj_9over = Double.valueOf(1.0D);	// Java9以降

// プリミティブ型
double d_prm = 1.0D;

System.out.println("d_obj : " + d_obj);
System.out.println("d_obj_methodCall : " + d_obj.doubleValue());
System.out.println("d_obj_9over : " + d_obj_9over);
System.out.println("d_prm : " + d_prm);

// 出力結果
d_obj : 1.0
d_obj_methodCall : 1.0
d_obj_9over : 1.0
d_prm : 1.0
```

## 補足
Java9以降において、Doubleを含むいくつかのオブジェクト型はコンストラクタ呼び出し時に値を設定する方法が非推奨になりました。
そのため、上記のようにJava8までとJava9以降で初期値の設定方法を変えています。

（引用元）クラスDouble
<a href="https://docs.oracle.com/javase/jp/9/docs/api/java/lang/Double.html#constructor" rel="noopener" target="_blank">https://docs.oracle.com/javase/jp/9/docs/api/java/lang/Double.html#constructor</a>

# 使い分け
DoubleはtoStringやintValueなどのメソッド使う必要である場合に使い、
doubleはただのdouble値を保持するだけという場合に使用すればよいでしょう。

# まとめ
<ul>
<li>Doubleはオブジェクト型、doubleはプリミティブ型という違いがある。</li>
<li>Java8までとJava9以降で初期化の推奨方法が異なる。</li>
<li>メソッドを使用して何らかの処理をしたい場合は、Doubleを使用すればよい。</li>
</ul>
トークスクリプトを参考にしてみた

どの仕事にもコミュニケーションはかかさないと思いますが、保守運用業務の障害対応の時、各部署の方々や、上長の方々と、連携したりして対応し、いち早くシステムを復旧させるといった業務において、コミュニケーションというのは欠かせないものだと思います。
でも意外とコミュニケーションって難しいなと思う場面が多く、知識レベルの違いや、認識の違いですれ違いが起こる事が意外と多く、障害対応業務に慣れていない最初の頃はいろいろと大変でした。
ここ最近もコミュニケーションの話題があり、認識齟齬を起こさないためには？という事で営業やサービス業でよく使われる？トークスクリプトというものを参考にコミュニケーションの流れを明確化してみました。その一部を紹介したいと思います。

#そもそもトークスクリプトとは？
トークスクリプトとは営業などで顧客に対して話をする際の内容や話の流れを記した台本の様なもの。話の展開などをフローチャートにまとめたりして、初めて営業の仕事をする人にとっては心強いマニュアルになるみたいです。

#トークスクリプトを参考に障害対応時の流れを作ってみた

今回の目的としては認識齟齬の発生(コミュニケーションのミス)を抑えるためには、、という観点で作ってみました。

_認識齟齬を抑えるためのポイント_
＊確実に伝えなくてはならない内容のピックアップ
＊相手もしくは自分の認識の確認
＊専門用語や独自の用語が伝わるか

3つめについては普段自分が使ってる言葉や言い回し
例えば、システムごとのサーバーをシステム名で言うか、ノード名で言うか、、などが伝わるかどうかなどです。

_ざっくりこんな感じ、実際はもっと細かく作ってます_↓
![スクリーンショット 2021-04-04 19.58.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394397/c6276f73-9c6f-2581-20b0-a404461cf64f.png)
こういった形でこちらから確認観点の内容を自ら発言することで確認担うといったような感じです。
システム名とサーバ名を両方いう事によりどんなサービスを提供しているかが認識しやすく障害自体の温度感などが伝わりやすくなります。自分たちは普段サーバーに接続したりでノード名のほうが親しみがありますが普段そういうことをしていない方に取ってはシステム名の方が伝わりやすい、といったこともあり得るので両方伝えるといった形にしてあります。

こうして会話の流れなどを可視化して見てみると普段の自分は伝えたい内容を明確に伝えられているか、また相手の立場を考えた言い回しができているか、などの確認や、予習にもなってなかなか便利だなと感じました。
実際障害対応となるとイレギュラーな事とかもあると思うのでフロー通り行くとは限りませんし、早急にサービスを復旧させなくてはならないので、焦ってしまったりすることもあると思いますが、フローとして普段から段階的に見ていると、要所要所で確認するきっかけ(冷静になって落ち着ける時間)づくりにもなるかと思います。←個人的にはものすごく大事な事だと思います。


#実際に作ってみて
コミュニケーションとか目に見えないものを可視化すると普段の自分の行動とか言動とかがより鮮明になっていろいろ見直すきっかけにもなると思いますので個人的にはなかなか面白いなと思いました。普段自分が使っている言い回しなどは他部署共通認識なのか？などの対話相手の環境などを気にするいい機会にもなるのでより連携や環境の理解につながるかと思いました。
python3で複数のインスタンスを１つの配列で管理したい

python3で複数のインスタンスを１つの配列で管理したい。以下のようにすればできました。便利です。

```python:test.py
class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age
 
  def getAge(self):
    print(self.age)
 
  def getName(self):
    print(self.name)
 
# set value
members = [
    Person("Test1", 11), 
    Person("Test2", 22), 
    Person("Test3", 33)
]

# search member
for member in members:
  member.getName()
  member.getAge()
```

```
$ python3 test.py
Test1
11
Test2
22
Test3
33
```

# 参考
[Pythonの配列はオブジェクトも格納できる（ジェネリックスになる）](http://pineplanter.moo.jp/non-it-salaryman/2018/01/07/python-generics/)
HTMLのインライン要素、ブロック要素の違いについて

こんばんは！taroです！

今回はHTMLのブロック要素とインライン要素の違いについて説明します！

HTMLの要素には、改行される要素と改行されない要素があります。
改行が入り、親要素の幅一杯に広がる要素のことをブロック要素
div、h1などがいい例です。

そして、改行されない要素をインライン要素といいます。
これはaやspanなどが例になります。

インライン要素にはwidthやheightが指定できない、つまり、高さや幅を調整できない
ということです。

今回は以上になります！
お疲れ様でした！
JavaScriptの何がややこしいのか

#UPDATE

JavaScriptに関して、昨日学んだことを振り返ってみる。

* ForEachがメソッドだということを知らなかった。

昔の言語では、予約語とか言っていたものが、もう時代が違うんですね。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

自分がソースを見ても、わからなかったことが、
ちゃんとドキュメントに書いてあるじゃ、あーりませんか！
（私、電化製品とかソフトのマニュアルを読まない主義だったので、
今ごろになって、猛反省いたしました）

```
解説
forEach() は、与えられた関数 callback を配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。インデックスプロパティが削除されていたり、初期化されていなかったりした場合は呼び出されません。(疎らな配列については、下記の例を参照。)

callback は次の 3 つの引数で呼び出されます。

要素の値
要素のインデックス
走査されている配列
forEach() に thisArg 引数が与えられると、callback の呼び出し時にそのオブジェクトが thisArg として使用されます。callback によって究極に管理される this の値は、関数から見える this を特定する一般規則に従います。
```



#前回の疑問

先ずは、プログラムにおける繰り返し処理
ここが、つまづきの原因・・・

一応自分のために整理する。

参考資料　https://github.com/reshinto/programming_language_syntax_comparison#loops


#Python

これですね、要するにenumerateを知っているかどうかが肝
今となったら、indexがイテレーション可能なオブジェクトに共通する変数というのが理解できたけど・・・

```Python
# Looping and getting index and value
for index, value in enumerate(list_name):
    print(index, value)  # output index, value
```

#JavaScript
ここからが本題・・・

```JavaScript
// forEach loop
// Looping through a list while calling a function
list_name.forEach(function(value, index, list){  // do not need to include all 3 parameters, but must be in order
    console.log(index, value, list);  // outputs index value list
});
```

そもそも、なんじゃこれは？
って、最初は身体が180度ぐらい仰け反りそうになった。

つまり、
その・・・
あの・・・
って

こうやって、理路整然と説明しようとしても、一向に説明できん・・・

コールバック関数というのやら、なんで引数が３つもあるんやって
もう、訳わかめです。

#結論

習うより慣れろ

#さらに
ここに、アロー関数なんて入ってくると、もう意味不明

```JavaScript
const func = function(argument) {
 alert( 'これまでの関数' );
}

const func = (argument) => {
 alert( '新しいアロー関数' );
}
```
Zennで10万文字の本を書いてわかった、QiitaとZenn(Web)とZen(Local)の使い分け

# Zennとは
ZennはQiitaのように、技術的なノウハウを記事や本にまとめて共有できるサイトです

* https://zenn.dev/about

# 実際にZennで書いた本
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* flutterに関する本で、Qiitaで書いていた20近くの記事を統合して書き直した結果10万字近くになりました。。。


# Qiita VS Zenn
## Qiitaの良いところ
* 知名度はQiitaのほうが高い
    * ユーザ数や検索はQiitaのほうがよい
* 記法が多く、htmlによる細かい修正ができる
    * 赤文字にするとか地味だけど細かい事ができる
* コードとプレビューが同じ画面で行える
    * Zennで書いてみて、プレビューがすぐに出ないのが思ったより辛い

## Zennの良いところ
* 本という仕組みがZennにしか無い
    * 知識を体系的にまとめることができる
        * 体系化すると隙間の知識が足りていないことに気づける
        * チャプターをまたいだ作業のしづらいが、、、
* 有料化できる
    * ただし、よほど有益なコンテンツでないと収益にならないのでは？？とも


## 個人的な結論
* 断片的な記事を書くならQiita、本にまとめるならZenn
    * 自分はFlutter系の記事が20本ぐらいあったのでZennで本にしてみました。
    * 体系化すると隙間や過去記事のメンテナンスをすることになり、非常に有益でした


# Zenn(Web) VS Zenn(Local)
Zennにはウェブで直接書く以外にも、ローカルでmdファイルを書いてgithubにpushする方法もあります。

* [Zenn CLIで記事・本を管理する方法](https://zenn.dev/zenn/articles/zenn-cli-guide)
* [GitHubリポジトリでZennのコンテンツを管理する](https://zenn.dev/zenn/articles/connect-to-github)

## Zenn(Web)の良いところ
* すぐに書ける
* プレビューで実施に利用者が見るのと同じ条件で見れる
    * localでも内容は見れますが、目次など一部が完全に同じと言えない状況です

## Zenn(Local)の良いところ
* Githubと連携して構成管理と自動デプロイができる
* 別ブランチで作業できる(即時反映でない)
    * ローカルで動作確認できる
* シンプルでわかりやすい
    * 本の設定をyamlで記述して、チャプターごとにmdファイルで書きます
* まだβ版
    * 裏を返すとこれから改良をいろいろしてくれるようです

## 個人的な結論
* 初めて作るときはWebで十分
* 改定などをするときに、一旦ローカルで確認したい時はローカルのほうがいい
* 複数のmdファイルをIDEで横断検索したり、水平展開するのにはローカルが良い
    * ブラウザで比較するのは辛い。。。



どういったものか、しばらく両立で使い続けてみる予定です :smile:

## 追記
* 最初にzenn-sampleという名前でリポジトリを作ってしまったので、リネームしたら連携されなくなり、一旦解除して再連携したら問題なく連携できるようになりました。
    * もともとの情報やlikesなども変わらずそのまま継承できました。