OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on Rails　MVCモデル

#【Ruby on Rails　MVCモデル】

独学でRuby on Railsでアプリ作成に取り組んでいるのでその備忘録です。

##Ruby on Rails

WEB開発に用いられるフレームワーク
MVCと呼ばれるソフトウェアのデザインバターンを採用している。

##MVCモデル
GUIアプリケーションのための模範的構造
例）お手本、ガイドライン

###・Model(モデル)
データベースに対してデータの登録取得 更新·削除などを行う。

例）実務係
アプリケーションの主たる処理(計算処理など)やデータ格納などを行う。

###・View(ビュー)
ブラウザに表示される画面の作成を行う。
一般的にはHTMLファイルではなく、html.erbファイルにRubyのコードを埋め込んでデータを表示する。

例）表示係
ユーザーに対して、画面の表示を行う。

###・Controller(コントローラー)
ユーザーからの要求に対して、ModelからのデータをViewに渡すなどの処理を行う。

例）受付兼指示係
ユーザーから要求を受け取り、処理実行をモデルに依頼し、その結果の表示をビューに依頼する。
kotlin.UninitializedPropertyAccessException: lateinit property auth has not been initialized

イニシャライズできていないことが原因。

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

auth = FirebaseAuth.getInstance()
}
```
変数をインスタンス化する。

https://qiita.com/minme31/items/c4f665b22fcbd97111f6
Ectoで生SQLを実行して結果を構造体で受け取る

```elixir
    result =
      """
      SELECT * FROM user
      """
      |> Repo.query!()

   users =
      Enum.map(result.rows, &Repo.load(User, {result.columns, &1}))
```

`Ecto.Repo.load/2` を使うことで任意の構造体に入れることが可能

https://hexdocs.pm/ecto/Ecto.Repo.html#c:load/2
サーバーの新規導入について

サーバーがいくら安定稼働しているとしても、**数年に一度は新しいサーバーを導入し、機能を新サーバーに移行しなければならない。**

古くなって耐用年数が過ぎた(減価償却期間が満了した)サーバーは陳腐化しており、メーカー保守も打ち切りが近づいてきていることになる。`メーカー保守が打ち切りになったサーバーは保守契約が結べなくなる為、故障したとしてもサポートを受けることができず、部品交換も困難になってしまう`。


#サーバーを新しく入れ替えるには

- 最初に判断することは、`「自分でやるか」`、`「外部の専門業者を頼むか」`という方針の決定である。

- 判断の基準は、「どれくらいのコストをかけられるのか」になる

###外部の専門業者の場合

- メリット
 - 知識・経験が豊富なので、自分では解決できない技術的な問題も解決してくれる
 
- デメリット
 - コストがかさむ


###自分でやる場合

自分でやる場合でも、`「部分的に外部の専門業者に任せる」`というやり方もある。つまり、自分でできる基本的な部分は自分で行い、自分には難しい領域の作業だけを専門業者の力を借りるという方法である。

- メリット
 - コストを抑えられる

- デメリット
 - 責任分界点や作業の分類を行う必要が出てくる


#入れ替え作業

前提として、サーバーが稼働するには次の３つのステップが必要になる。

① 構築して使えるようにする(構築作業)
② 構築を完了し、使えるようにする(テストからサービスイン)
③ 使っている中で必要な作業を行う(運用作業)

`サーバーを新たに作り直す場合には、①と②の作業を行う`ことになる。

※ 実際の移行作業は、稼働しているサーバーの数だけ存在し、環境に依存する部分がとても多い。
ActiveHashを解説してみた

##ActiveHash
職業選択などの変更されないデータをモデルファイル内に直接記述することで、データベースへ保存せずにデータを取り扱うことができる。つまり、Active_Hashを用いることで、モデルファイルに直接記述した変更されないデータに対して、ActiveRecordのメソッドを用いることができる。
##導入方法
######Gemfile
```ruby:qiita.rb
gem 'active_hash'
```
記述したらbundle installを実行する。
##モデル作成時に押さえておくべきこと
結論、--skip-migrationを使用すること。
理由は、データベースを作らない。すなわちマイグレーションファイルは不要となるからだ。ここでrails g modelコマンドを使用してしまうと、マイグレーションファイルも同時に作成されてしまうので注意が必要。

```
% rails g model モデル名 --skip-migration
```
##ActiveHash::Base
ActiveRecordと同様のメソッドが使用できる。
つまり、ActiveHash::Baseを継承することで、モデルに定義したオブジェクトに対してActiveRecordのメソッドが使用できるようになる。

```ruby:qiita.rb
class ShippingFee < ActiveHash::Base
  self.data = [
    { id: 0, name: '---' },
    { id: 1, name: '着払い(購入者負担)' }, { id: 2, name: '送料込み(出品者負担)' }
  ]
end
```
self.dataでテーブルを作成しているイメージ。データは配列にハッシュ形式で格納されている。

######belongs_to_active_hash
通常であればbelongs_to :モデル名となるが、ActiveHashを使って作成したモデルに対してアソシエーションを設定する場合は、belongs_to_active_hashメソッドを使用する。

######collection_select
データをプルダウン形式で表示することができるメソッド

| 記述順 | 詳細 | 具体例 |
| :----------:|:------------:|:------------:|
| 第一引数 | メソッド名 | カラム名 |
| 第二引数 | オブジェクト | 配列データの指定 |
| 第三引数 | id | 参照DBのカラム名 |
| 第四引数 | name | 実際のカラム名 |
| 第五引数 | prompt | プルダウンで一番上に表示したい内容
| オプション | クラス名 | -- |

```ruby:qiita.rb
<%= f.collection_select(:shipping_fee_id, Shipping_fee.all, :id, :name, {}, {class:"select-box", id:"item-shipping-fee-status"}) %>
```

##実装例
代表的なものをいくつかあげてみた
・都道府県
・職業選択
・クローズドクエスチョン(yes or noで答えられるようなもの)
・アンケート
・カテゴリー
・商品のステータス

個人的にはこれがあることで利用者側のストレスを大幅に減らすことができ、かつ効率的に情報収集をすることができると感じた。
相手に意見を求めたいときなどに使うといいかもしれない。

##最後に
ここまで記事を読んでいただき、ありがとうございました。

普段何気なく使っているものにもActiveHashが取り入れられているのですね。
実装も簡単なので、積極的に使っていきたいと感じました。

今後も学習を進めていく中で、役立つ情報をどんどん発信していきたいと思うので、よろしくお願いします。

ここまで記事を読んでいただき、本当にありがとうございました‼
見ているページのURLとタイトルをすぐにPukiWikiスタイルの書式に変換するブックマークレットを作った。

表題どおり。pukiwikiのために毎回URLやタイトルをコピペしてコリコリするっていうのがおっくうになったのでブックマークレットを作りました。

![e128219b8e2f9242ba053cb240f32f89[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712840/75c9ae59-ac7a-8442-624b-0bf002ddb07a.png)

URLをすぐHTMLリンク形式にする～みたいなやつをサクッと改造したやつです。

```
javascript: (function () { var ele = document.createElement('textarea'); ele.style.width = '100%'; ele.value = '[[' + document.title +'>'+ location.href + ']]'; document.body.insertBefore(ele, document.body.firstChild); ele.focus(); ele.select(); ele.ondblclick = function () { ele.parentNode.removeChild(ele); }; ele.oncopy = function () { setTimeout(function () { ele.parentNode.removeChild(ele); }, 1); return true; }})()
```

これをコピペしてお気に入り登録のURLのところに打ち込めば使えます。ブックマークバーに置いておくとすぐに使えると思います。

ソースコードは下。自分で改造したい場合はどうぞ。

```javascript
javascript: (function () {
    var ele = document.createElement('textarea');
    ele.style.width = '100%';
    ele.value = '[[' + document.title + ">" + location.href + ']]';
    document.body.insertBefore(ele, document.body.firstChild);
    ele.focus();
    ele.select();
    ele.ondblclick = function () {
        ele.parentNode.removeChild(ele);
    };
    ele.oncopy = function () {
        setTimeout(function () {
            ele.parentNode.removeChild(ele);
        }, 1);
        return true;
    }
})()
```
echoでより高速なJSONを返す

# はじめに
goのwebフレームワークである[Echo](https://github.com/labstack/echo)にてデフォルトのJSONよりも高速なJSONを返したいことがあると思います。その例として[easyjson](https://github.com/labstack/echo)で作ったJSONを返そうとしたときに少し詰まりどころがあったので書き留めておきたいと思います。

# まずはデフォルトから
```golang:main.go
package main

import (
	"github.com/masibw/echo_json/model"
	"net/http"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

func main() {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Routes
	e.GET("/", getUser)

	// Start server
	e.Logger.Fatal(e.Start(":1323"))
}

// Handler
func getUser(c echo.Context) error {
	user := model.User{Name:"John",Age:18}
	return c.JSON(http.StatusOK, user)
}
```

という感じで

```golang
return c.JSON(http.StatusOK, user)
```
と返せば良いです。
# [easyjson](https://github.com/mailru/easyjson)で作ったJSONを返す
詳しいパフォーマンス測定は行っていませんが [こちら](https://www.sambaiz.net/article/193/)の記事によるとencoding/jsonよりも2倍くらいは速そうです。

echoにて既にencoding済みのJSONを返すには

```golang
func(c echo.Context) error {
  encodedJSON := []byte{} // Encoded JSON from external source
  return c.JSONBlob(http.StatusOK, encodedJSON)
}
```
という感じで渡してあげれば良いです。ということでencodedJSONのところにeasyjsonで作ったJSONを渡しましょう。

ディレクトリ構成はこんな感じで作業します。

```
.
├── go.mod
├── go.sum
├── main.go
└── model
    └── model.go
```


```golang:model.go
package model

type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

```

## easyjsonのインストール

```
go get -u github.com/mailru/easyjson/...
```
した後にmodelが記載されているディレクトリに移動して

```
easyjson -all <file>.go
```
する必要があります。
すると

```
<file>_easyjson.go
```
というファイルが作成されるはずです。
あとはプログラム内で

```golang
encodedJSON, err := easyjson.Marshal(user)
```
のようにJSONへencodeすることができます。
これをechoで返す様にすれば良いです。全体像がこちら

```golang:main.go
package main

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/mailru/easyjson"
	"github.com/masibw/echo_json/model"
	"log"
	"net/http"
)

func main() {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Routes
	e.GET("/", getUser)

	// Start server
	e.Logger.Fatal(e.Start(":1323"))
}

// Handler
func getUser(c echo.Context) error {

	user := model.User{Name: "John", Age: 18}
	encodedJSON, err := easyjson.Marshal(user)

	if err != nil {
		log.Fatal("json marshal error")
	}
	return c.JSONBlob(http.StatusOK, encodedJSON)
}

```


# つまりどころ
## mainパッケージに対してコマンドが実行できない
```
easyjson -all <file>.go
```

[該当Issue?](https://github.com/mailru/easyjson/issues/236)
なのでmodelパッケージのように別パッケージを用意してあげましょう。
それに加えて厳密な条件は調べていませんが構造体定義以外が対象ファイルに記載されているとエラーが返ってきてしまうことがあるようです。
その場合は一旦構造体のみ別パッケージに移すなりしてeasyjsonのコマンドを実行し,自動生成されたファイルをコピーして同じパッケージにすれば動きます(構造体定義が変わるたびに実行する必要があるのでめんどくさいですが)
Linux よく使うコマンド

#【Linux よく使うコマンド】

業務内でよく使用する Linuxコマンドのメモです。

##基本コマンド

cdコマンド
ディレクトリを移動

Isコマンド
ディレクトリの内容を表示

Is -a コマンド
隠しファイルを含めたディレクトリの全内容を表示

mkdirコマンド
ディレクトリを新規作成

rmコマンド
ファイルを削除

cpコマンド
ファイルをコピー

mvコマンド
ファイルの移動とファイル名の変更
【本当は怖いFirestore】ガバガバセキュリティルールのFirestoreからデータを簡単に抜き取る方法

# はじめに
Firestoreはバックエンドのコードを書くことなく、簡単にDBを扱えます。
バックエンド開発になれていない初心者だけでなく、プロトタイプを素早く作成したい人にもマッチする技術です。
しかし、クライアントから直接DBをいじることができる都合上、**ユーザーが悪意のあるクエリを叩くことができてしまう**ということを知っておく必要があります。

# 対象者
- Firestoreを使っているが、セキュリティルールがいまいちわかっていない人
- 以下のセキュリティルールを見ても、危険性がわからない人
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297745/051efded-9fd0-7780-0aec-b315fa62de4c.png)

この記事では上記のセキュリティルールが設定されているWebアプリから簡単にデータを抜き取れることを説明することで、セキュリティルールを書くことの大切さを伝えることが目的です。

# 手順
必要なのはブラウザだけです。この記事ではChromeを使うことを想定しています。

## ログインする
セキュリティルールを見るとわかるように、ログインしないとすべてのクエリが弾かれるようになっています。とりあえず。サービスにログインしましょう

## SDKを読み込む
devツールを開きましょう。`Console`で以下のコマンドをうち、firebaseSDKを読み込みます。

```js
> const script = document.createElement('script')
> script.src="https://www.gstatic.com/firebasejs/8.2.1/firebase.js"
> document.head.append(script)
```
バージョンの部分(`8.2.1`)は適宜変更してください。現時点(2021/01/06)の最新バージョンは`8.2.1`です。


## firebaseConfigを抜き取る
devツールの`Sources`タブから、mainファイルっぽいjsを選択し、`apiKey`で検索をかけると、firebaseConfigが抜き取れます。`{"apiKey": "***", "authDomain": "***", ...}`となっている部分がfirebaseConfigです。


## SDKの初期化
次に、抜き取ったfirebaseConfigを使ってfirebase sdkを初期化しましょう。devツールの`Console`タブで以下のコマンドを打ちます

```js
firebase.initializeApp(/** 抜き取ったfirebaseConfig */)
```

## さあ、準備は整いました。
自由にクエリを叩くことができます。

```js
> const snap = await firebase.firestore().collection('users').get()
> snap.docs.map(doc => doc.data())
```
これで、usersコレクションのすべてのデータを見ることができてしまいます。DBの全データを閲覧・書き換え・削除することも可能です。

# 対策方法
firebase configを非公開にすることは現状無理です。つまり、firestoreのセキュリティルールをきちんと書くしかないです。
もしくは、firestoreのセキュリティルールをフロントからはアクセスできないようにして、functionsからのみアクセスできるようにするというのも考えられます(ただし、その場合はコールドスタートというパフォーマンス問題が発生し、対策が必要になります)。

# 結論
セキュリティルールはちゃんと書きましょう。
この記事を読んで冷や汗をかいた人は、まず公式ドキュメントを読みましょう。おすすめのドキュメントは以下です。
- [Cloud Firestore セキュリティ ルールの条件の記述](https://firebase.google.com/docs/firestore/security/rules-conditions?hl=ja)
fishのPATH登録/確認/削除

fishのPATH登録はbashやzshと異なるので注意

# PATHの登録
ターミナルにて以下のコマンドを一回打てばOK

```sh
$ set -Ux fish_user_paths （登録したいPATH スペース区切りで複数登録可能） $fish_user_paths
```

もし`~/.config/fish/config.fish`
に記述している場合、fishシェルを起動するたびにPATH登録がされてしまう。
そのままにするとPATHが長すぎて起動時にエラーが発生するようになるので以下の対応を行う。

# PATHの確認
以下のコマンドを打つとindex付きで出力される

```sh

$ echo $fish_user_paths | tr " " "\n" | nl
#     1	/user/local/.anyenv/bin
#     2	/user/local/bin
#     3 /user/local/bin
```

# PATHの削除
先ほど確認した登録PATHのindexを指定して、以下のコマンドを打つ
`消したいPATHのindex`については`2..20`のように範囲指定も可能

```sh
$ set --erase --universal fish_user_paths[（消したいPATHのindex）]
```

# エイリアス
上記操作用のエイリアスです。
`~/.config/fish/config.fish`に下記を追記すればコマンドで使えます。

```sh
function set_path
  set -Ux fish_user_paths $argv $fish_user_paths
end

alias path_list='echo $fish_user_paths | tr " " "\n" | nl'
 
function remove_path
  set --erase --universal fish_user_paths[$argv]
end
 
# 使用例
# $ set_path /user/local/bin
# $ path_list
# $ remove_path 1
```

# 参考
https://qiita.com/mochizukikotaro/items/0beae50b2a20f93e496d
【Python】Openpyxlで書き込んだ値が指数表示(E)にされた

#発生した問題
Pythonのライブラリopenpyxlで書き込んだ値がEを用いた指数表示の表示形式にされた

```python:sample_code.py
import openpyxl

wb = openpyxl.open('./Book1.xlsx')
sh = wb['Sheet1']

sh.cell(row=1, column=1).value = 308985489249593041

wb.save('./result.xlsx')
```
**結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705535/d2e008ea-57f4-5023-8024-c7fb3fe5a624.png)
指数関数を取り除いた表示にしても末尾がいくつか0に置き換えられてて困る

#原因
openpyxlでなくExcelの仕様上の問題
>Excel のセルに15桁を超える数字を入力すると、15桁を超える数字はすべて0に変更されます。 

[Excel のセルに長い数値を入力すると、最後の数字が0に変更される](https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/last-digits-changed-to-zeros)より

数値計算ならこんくらいの桁数なら少しくらい精度が落とされても問題ではなさそうですが，
なんかのidだとかクレカの番号だとか1ケタでも違うと困るのを書き込んでる場合は困りますね

#解決策
文字列として数値を書き込んであげればよい

```python:sample_code.py
import openpyxl

wb = openpyxl.open('./Book1.xlsx')
sh = wb['Sheet1']

#ここで書き込む数値をstr型にしてあげる
sh.cell(row=1, column=1).value = str(308985489249593041)

wb.save('./result.xlsx')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705535/58e450dd-36d3-b79e-5a54-7a893a8de7d9.png)
これ文字列かアポストロフィで始まってる数値だよって怒られるけど書き込めた
ちなみにExcel内での計算はこのエラー出てても正常に行える

###openpyxlでは文字列として書き込んだ値はどんな感じで取得できるか
```python:sample_code.py
import openpyxl

wb = openpyxl.open('./result.xlsx')
sh = wb['Sheet1']

A1_value = sh.cell(row=1, column=1).value
print(A1_value)
print(type(A1_value))

'''
> 308985489249593041
> <class 'str'>
```
文字列として取得されるみたいですね
intでまた置き換えてあげないといけないですね

###追記：フォーマットを指定してあげる
コメントで以下の記事を紹介して頂きました．
[openpyxlで数値の表示フォーマットを指定する](https://qiita.com/github-nakasho/items/7db0c3bfaad6637a0f40)

ってことで
`sh.cell(row= , colum=).number_format = `に何個かフォーマットを渡してみました．
書き込む数値は上と同じ308985489249593041
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705535/dac08675-6cee-3c6c-e1ce-6c1c23a87337.png)
A列が与えたフォーマットで，B列が結果
おー，すごい．ちゃんとフォーマットが変わってますね．
けど残念なことにやっぱり末尾の方は0に変えられちゃいますね…．
B2とか文字列フォーマットなんだけど書き込む時点でint型だと多分無理っぽいですね…．

#あとがき
もっとかしこい回避策あるんですかね
Excelのプラグインで上限解放できるとかｗ
知っている方いたら教えてください
シェル

#【シェル】

業務内でシェルを使用するのでその備忘録です。

##シェル
OSと対話するためのインターフェースであり、コマンド制御の環境
→インタプリンタ。

上から順番に実行し、コンパイルが無いために即実行結果が分かる。

##シェルスクリプト（シェルが解釈できる台本）
複数のコマンドと条件分岐やループ処理等で使用し、一連の処理を実現させるプログラム

※書くのに苦労するような複雑なものは、基本的にシェルスクリプトで書かない方が良い。

###bash (シェルスクリプト)
bashとは、Unix OS上で動作する言語で、OSコマンドの自動実行やサーバー管理に使用される。
習得すると、OSに搭載されたコマンドを効率よく運用する上で役立つ。
Unix OSが搭載されたサーバーを扱う時に使用する。


##bashの基本
###・書き始め
 #!/bin/bash (# hash、! bang → #! shebang　シバン)

###・コメント
 # 以下にコメントを書くことが出来る。

###・入力、出力
readで入力、echoで出力する。
（bashで、-eフラグで特殊テキストをエスケープできる）

###・変数
変数に値を与える時、 = は前後空白なしで書く。文字列は、""。
変数をアクセスする時、変数名の前に＄を入れる。または、＄入れて{}で囲む
変数の上書きされないように、readonlyを使う
変数を削除するには、unsetを使う

###・特別な変数
変数
機能

＄0
スクリプト名

＄1～＄9
引数、1番目の引数を＄1、2番目の引数を$2でアクセスする

＄#
スクリプトに与えた引数の数

＄＊
全部の引数をまとめて1つとして処理＠全部の引数を個別として処理

＄?
直前実行したコマンドの終了値（0は成功、1は失敗）

＄＄
このシェルスクリプトのプロセスID

＄!
最後に実行したバックグラウンドプロセスID
Svelteとsvelte-material-uiで割り算ツールを作ってみたらほぼ学習コスト0で作れた

こんにちは！
フロントエンドの技術進歩は目まぐるしく変化していますね。
JSフレームワークの一つ「Svelte」は一年前くらいから人気が高まっているようです。

[こちら](https://2019.stateofjs.com/front-end-frameworks/)の海外サイトによると、2019年のReact, Vue.jsなど主要フレームワークの中で、
**最も認知度が低く、最も関心度が高いJSフレームワークだそうです。**

本記事用にJSフレームワーク「Svelte」で割り算ツールを作ってみました。
・Svelteがとっても簡単に書ける
・`svelte-material-ui`はいい感じ♪
これらのことがお伝えできればいいなと思います。

### 環境構築

#### Svelteプロジェクト作成
```terminal
npx degit sveltejs/template svelte-sample
cd svelte-sample
npm install
npm run dev
```
#### svelte-material-uiの導入
こちら手順は必須ではありません。
CSSを書くのが面倒くさかったので、導入しました。笑

手順については、@hisayukiさんの記事を参考にしていただければと思います。
https://qiita.com/hisayuki/items/11e625c647cc421cbe86
@hisayukiさんありがとうございます。

### 割り算ツールの作成

`App.svelte`を開き、以下のように記述します。

```javascript
<script>
        // svelte-material-uiのコンポーネントをimport
	import Button, {Labeln} from '@smui/button';
	import Textfield, {Input} from '@smui/textfield';
	import Card from '@smui/card';
	import HelperText from '@smui/textfield/helper-text/index';

        // 割られる数
	let dividend = '';
        // 割る数
	let divisor = '';
        // 結果
	let result = '';
        // CALUCULLATEボタンを押したときの処理
	function handleClick() {
		if (dividend && divisor) {
			if (!isNaN(Number(dividend)) && !isNaN(Number(divisor))) { {
				if (divisor != 0) {
					result = dividend / divisor;
				} else {
					alert('0で割ってはいけません。');
				}
			} else {
				alert('数字を入力してください。');
			}
		} else {
			alert('入力値が空白です。');
		}
	}
</script>

<main>
	<h1>割り算</h1>
	<div style="display:flex; flex-wrap: wrap;">
		<div>
			<Textfield variant="outlined" dense bind:value={dividend} label="割られる数" input$aria-controls="helper-text-dense-c" input$aria-describedby="helper-text-dense-c" />
			<HelperText id="helper-text-dense-c">例：1, 222, -33, 4321</HelperText>
		</div>
		<div style="padding: 15px;">
			÷
		</div>
		<div style="display: inline-block">
			<Textfield variant="outlined" dense bind:value={divisor} label="割る数" input$aria-controls="helper-text-dense-c" input$aria-describedby="helper-text-dense-c" />
		<HelperText id="helper-text-dense-c">例：1, 222, -33, 4321</HelperText>
		</div>
	</div>
	<Button on:click={() => {handleClick()}} variant="outlined"><Label>Caluculate</Label></Button><br/>
	<h2>Result</h2>
	<div class="card-number">
		<Card style="width: 210px;" padded>{result}</Card>
	</div>
</main>

```

完成したものがこちら
![svelte使ってみた.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/54586386-2458-a5c2-010f-4d8b488ca46a.gif)

svelte-material-uiはいい感じです！
詳しくは[▶︎こちら](https://sveltematerialui.com/demo/card/)


### 所感
今回はほとんどJSとReact, HTML, CSSの知識で作れてしまいました。
ReactのStateのようなSvelte特有の機能は使用しませんでした。

Reactを少し触ったことある方であれば、チュートリアルをやらずとも作れてしまうと思います。
（本当はチュートリアルはやった方がいいと思いますが、、）

### 参考URL
https://note.com/kawa1228/n/n3a45fab21f99#fWe6h
https://qiita.com/hisayuki/items/11e625c647cc421cbe86
【AzureAD】リソースグループの配下に作成したものに自動でタグが付くよう設定してみた


##タグの設定

AzureADのタグにリソースをつけてみました。
Azureのタグって自分の事業部のリソースはこれだって明示的にわかりやすくするものだけど
リソース作る毎にタグつくるのめんどくさいので、自動でつくように設定してみました

AzureAD→すべてのサービスから「ポリシー」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/a30b5cd7-aae0-46dc-7c58-e60cc38e50c0.png)

ポリシー画面にて「定義」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/c42184f8-c5c4-9abe-5779-832ec5aa86f0.png)

ポリシー｜定義画面にて「タグとその値をリソースに追加する」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/24527af5-0ab1-3c2c-a519-eeb99dc29795.png)

タグとその値をリソースに追加する画面にて　「割り当て」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/34a9d97e-5c28-1fd4-ee23-93fde45c29e6.png)

スコープ「…」をクリックし、サブスクリプションを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/40c629c5-28c9-124c-255d-ee6717b3924e.png)

「除外」は他のチームが使っているリソースグループとか　外したいものがある場合は
指定します。
「割り当て名」は任意です。今回はPolicyTestとしました。
ポリシーの適用を「有効」にします。
「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/74dcd9c7-3930-8eb4-d047-2d95f181c7c4.png)

パラメータに移動します。
タグ名とタグの値を決めます。事業部とかで分けている場合は、ここで事業部名とか
書いておくとわかりやすいと思います。
「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/4046cb2d-2d76-82af-60ff-a05e43dadf41.png)

修復に移動します。
ここは何も記載せずに「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/264b39a2-8da9-b700-e060-59d3a11ada82.png)

「作成」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/272473c3-35ca-f15b-4bcb-1dbbf03b8978.png)



##検証
実際タグが自動的につくか確認してみます。
試しにネットワークセキュリティグループを追加してみます

全てのサービス→ネットワーク→「ネットワークセキュリティグループ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/edeec0ac-29d3-eaef-532d-54fb0f7dc117.png)

「追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/9f7c1d9e-a078-1022-4da0-dce79ccf635e.png)

サブスクリプションは自分の利用しているサブスクを選択
リソースグループは今回NetworkWatcherRGを選択してみました。
名前と地域は以下のように設定しました。
「次：タグ」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/64b82a41-def2-fc88-23da-bede99853f4e.png)

タグはここでは記載をせずに「確認および作成」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/d71c8822-79d4-f926-4fda-4eca76ccad72.png)
ネットワークセキュリティグループが出来ることを待ちます。
「リソースに移動」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/eb52f814-33b9-eac4-7a64-31c2c52195aa.png)
無事タグが付与されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480057/cbedb0ed-562b-d616-fa5e-1555c9135fdc.png)

タグは色々利用できそうですね。
以上です（＾＾）
A Tour of Go メモ【2】１日目

[A Tour of Go](https://go-tour-jp.appspot.com/flowcontrol/1　#)
時折、コードを変更したり、関連記事を調べたりしながら、学習しました。

# for

```
func main() {
    sum := 0
    for i :=0; i < 10; i++ {
        sum += i
        fmt.Println(i)
        fmt.Println(sum)
    }
}

#省略可能
for ; sum < 100; {
    sum += sum
}

#さらに省略可能
for sum < 100 {
    sum += 100
}

# 無限ループ
for {

}
```

# if

```
func judge(x int) string {
    if x > 0 {
        return "マイナス"
    }
    return　fmt.Println("プラス")
}
func main() {
    fmt.Println(judge(−100))
}
>> "マイナス"

#注意 returnどちらか一つ
if文内の returnに到達したら、
if文外の　return の戻り値は返ってこない
```

# 条件の前に変数を定義できる

条件の前に定義した変数はifのスコープ内のみ使用可能
もちろん、elseブロッック内でも使用可能

```
func pow(x, n, lim float64) float64 {
    if v := math.pow(x, n); v < lim {
        return v
    } else {
        return v+10
    }
    return lim
}

func main() {
    fmt.Println(
        pow(3, 2, 10)
        pow(3, 3, 20)
    )
}
>> 9
>> 127


#スコープ外で使うとエラー

if v := 10: v < 100 {
  return "１００以下"
}
fmt.Println(v)
>> undefined: v
```
#Switch

breakはいらない
caseの条件が一致すれば、自動的にbreakする

runtime.GOOSで実行しているOSを判定できる

```
func main() {
    fmt.Printl("Go runs on")
    switch os := runtime.GOOS; os {
    case "darwin":
        fmt.Println("OS x.")
    case "linux":
        fmt.Println("Linux.")
    default:
       fmt.Printf("%s.\n", os)
    }
}

switch {
    t := time.now()
    case t.Hour() < 12:
        fmt.Println("Good morning")
    case t.Hour() < 17:
        fmt.Println("Good afternoon")
    default:
        fmt.Println("Good evening")
}
```


#Defer
呼び出し元の関数が終わるまで、deferに渡した関数の実行を遅らせる
deferに渡した関数の引数はすぐに評価される
[Go言語のdeferを正しく理解する | How defer in Golang works](https://qiita.com/Ishidall/items/8dd663de5755a15e84f2 #)

```
func main() {
        world := "world"
        defer fmt.Println(world)
        world = "new world"
        fmt.Println("hello")
}

> hello
# deferにより、main()関数が終わった後に実行される
#　しかし、worldはすぐに評価されるので、deferの後に"new world" と変更しても、反映されない
> world
```
AnacondaにOpenCVのインストールができなかったときの対処法

# はじめに
Anacondaでちょっとゴニョゴニョやろうとした時に、python3.7を使いたかったんですが、何故かNavigatorでバージョンの選択が出来ませんでした（下図のプルダウンが選択できない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19695/39eb2a74-c2ac-42e5-153e-48044a513016.png)

まあ、ちょっとした実験程度なので、そこまで強いこだわりも無かったので、そのままにしてたのですがOpenCVのインストール時にこけました。

# 環境
Mac OS 10.15.6
AnacondaNAVIGATOR 1.9.12

# OpenCVのインストール失敗

```OpenCVのインストール時にエラー
Collecting package metadata (current_repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: | 
Found conflicts! Looking for incompatible packages.
This can take several minutes.  Press CTRL-C to abort.
failed                                                                                                               

UnsatisfiableError: The following specifications were found
to be incompatible with the existing python installation in your environment:

Specifications:

  - opencv -> python[version='>=2.7,<2.8.0a0|>=3.5,<3.6.0a0|>=3.6,<3.7.0a0|>=3.7,<3.8.0a0']

Your python: python=3.8

If python is on the left-most side of the chain, that's the version you've asked for.
When python appears to the right, that indicates that the thing on the left is somehow
not available for the python version you are constrained to. Note that conda will not
change your python version to a different minor version unless you explicitly specify
that.
```

要するにマイナーバージョン（対応してるバージョンも明記してくれてます）を入れろ、ということで3.7を入れました。

```
$ conda install python=3.7
```

その上で再度

```
$ conda install opencv
```

で一件落着。
A Tour of Go メモ【1】１日目

# goのチュートリアル
[A Tour of GO](https://go-tour-jp.appspot.com/basics/1 #)
時折、コードをいじって、どんなエラーが出るかなどを試しながら、学習しました。



#出力
```packages.go
package main

# パッケージをインポート
import (
  # 出力のためのパッケージ
	"fmt"
)

func main() {
    # 出力
	fmt.Println("Hello World"))
}
```

#パッケージのインポート

```packages.go
package main

#複数行で書くこともできる
import "fmt"
import "math"

#こっちの方がスマート
import (
 "fmt"
 "math"
)
```

#関数と引数

```function.go
package main

import "fmt"

#変数の後ろに型名を指定する必要がある
func add(x int, y int) int {
    return x + y
}

func main() {
    fmt.Pringln(add(20, 30))
}

// 50


#関数の引数が同じ型なら、省略可能

func add(x, y int) int {
  return x + y

}
```

#複数の戻り値

```
func swap(x, y string) (string, string) {
    return y, x
}

func main() {
  a, b := swap("hello", "world")
  fmt.Println(a,b)
}

// "world" "hello"




#　Namec return values

* 以下は戻り値の変数が定義されないので、エラーになる
func split(sum int) (int, int) {
    a = sum / 2
    b = sum / 3
    return a, b
}


* 戻り値の変数に名前をつける必要がある
func split2(sum　int) (a, b int) {
    a = sum / 2
    b = sum / 3
    return a, b
}
```

# 変数

```
var n int
var c


func main () {
  fmt.Println(n)
  fmt.Println(c)
}

# int を指定し、何も値を指定しないと初期値は０
// 0
# 型を指定しなかった c　はエラーになる
// syntax error: unexpected newline, expecting type
```

#　変数の初期値

```
var i, j int = 1, 2
# 初期値を同時に指定すると、型を宣言しなくて良い
var a, b = 10, 11
var c, python, java = true, false, "no"

func main() {
    fmt.Println(i, j)
    fmt.Println(a, b)
    fmt.Println(c, python, java)
}

// 1 2
// 10 11
// true false no
```

#変数の定義と代入

```
func main() {
    a := "hello"
    k := 3
    fmt.Println(a)
    fmt.Println(k)
}

// hello
// 3



# func main()の外で := を使って、代入するとエラー

# ok
var a strint = "hello"
# ng
b := "hello"

func main() {
    fmt.Println(a)
    fmt.Println(b)
}
# a は OK
// hello
# b はエラーになる
// syntax error: non-declaration statement outside function body
```

#各変数の初期値

```
func main() {
    var i int
    // 0
    var f float64
    // 0
    var b bool
    // false
    var s string
    // ""
    ...
}
```

# 型の変換

```
var i int = 32
var f float64 = float64(i)
var u uint = uint(f)

i := 32
f := float64(i)
u := uint(f)
```

#型の確認

```

func main() {
    v := 100
    fmt.Printf("%T\n", v)
    s := "hello"
    fmt.Printf("%T\n", s)
}
// v
> int
// s
> string
```

#定数の宣言

```
func main() {
    const Say = "hello"
    fmt.Println(Say)

   #再代入できない
    Say = "Hey"
    // cannot assign to Say
}
> "hello"
```
konashi探究：konashi 3.0でココロキットをうごかしてみる

# はじめに
[konashi 3.0](https://store.ux-xu.com/products/konashi)はユカイ工学が開発・販売しているフィジカル・コンピューティングツールキットです。スマートフォンからデバイスを制御する開発環境あり、ものづくりに詳しくなくても扱えるものとなっています。また、一部機能をブロックプログラミングが行えるScratchからも扱えます。

またユカイ工学発売されている[「ユカイな生きものロボットキット」](https://kurikit.ux-xu.com/robotkit/)の拡張キットである[ココロキット](https://kurikit.ux-xu.com/cocorokit/)、こちらはScrachやJavascriptでBLEを通して簡単にDCモータを制御できるマイコンにです。

どうやら、こちらの二つを組み合わせ、Konashi 3.0の入力からココロキットを簡単に操作できると聞いたので試してみました。
Konashi 3.0には入出力ピンやUART、PWM、I2Cなどに対応しているので、拡張性があります。


# うごかしてみる
結果、動かしてみると下記のような感じです。
Konashi 3.0(黒い基板)はボタン電池での駆動も可能で、基板上のボタンを押すことで、ココロキットにつながったモーターをBLEで簡単に制御することができました。

こうやってみると配線がなくて、とてもスマートな印象です。

![kokorokit.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/83eb1917-173f-67bd-5a8c-6c400d460a6b.gif)

# うごかしかた
Scratchでプログラムを組み立てました。
ココロキットをScratchでつかう方法は、[こちらの説明](https://kurikit.ux-xu.com/scratch/)を参考にしました。
下記にURLにアクセスすれば、Scratchの画面がでてきます。
https://kurikit.ux-xu.com/scratch/

1. Scratchの画面を開きます
2. ココロキットとkonashiの拡張機能を追加します
3. プログラムをくみます。モーターの左右はココロキットへの接続次第です。
4. konashiとココロキットをそれぞれ「接続する」でWeb bluetoothで繋ぎます。
5. あとは、konashiの基板上にあるボタンを押すとモーターが回転し、話すと回転がとまります。 
![プログラム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/6505cb31-8fb0-15c7-f074-4ca48d00f022.png)

PIO 0が基板上のスイッチにデフォルトでつながっているようです。

# おわりに
簡単にBLEをつかってkonashi 3.0からココロキットにつながったモーターを制御することができました。
他の入出力ピンにも何かしらのセンサを入出力して、konashi 3.0で遊んでみたいと思います。

# 参考
- konashiの使い方　https://konashi.ux-xu.com/
- ココロキットについて　https://note.com/kurikit
[メモ]組み込みのコンパイルができなくて数時間溶かした話～展開ソフトに気をつけろ!!～

## 環境

Win10にWSL(1)、arm-none-eabi-gccのwin版バイナリをbashのmakeで呼んでコンパイル。

## ことの発端

* WindowsアップデートでOS再起動
* なぜかコンパイルができなくなる
    * arm-none-eabi-gccがファイルを見つけられないらしい
    * WSL周りの仕様変更?
* WSLからWindowsバイナリを呼ぶとだめっぽい
* linux版のGCCを入れてコンパイル
    * オブジェクトファイルの作成までは動くようになった
    * しかしリンクができない
* コンパイラの実行ファイルを確認してみると、いくつかの実行ファイル(-ldや-asや-objcopy等)のサイズが0バイトになっていた
    * いくつかのバージョンをダウンロードしてみたが、バージョンごとにどの実行ファイルかは異なるが、少なくとも数個の実行ファイルは0バイトになっている
    * Linuxをつかったことがない僕「Linuxって実行ファイル0バイトでも動くんだ、不思議な物だなぁ」
* ほんの気まぐれで、普段使っている展開ソフトではなく、WSLのtarコマンドでtar.bz2を展開
    * すべてのファイルがちゃんと容量有る!!!
* make→コンパイル成功

6時間位溶かした。

## 教訓

普段使い慣れたツールでも過信してはいけない。
普段はtar.bz2とか使わないし、zip等は問題なく展開できていたはずなので、ツールを疑うという考えはなかった。
macOS Catalina で MacOS X Snow Leopard のインストールUSBメモリを作成し、古いMacを初期化する

古いMacは工場出荷時にインストールされていたのと同じバージョンのOSがないと初期化できません。
手元に元々Snow LeopardがインストールされていたMac miniがありますが、付属していたOSインストールディスクを紛失したため、以下の方法で初期化しました。
なお、Snow Leopard のインストールDVDを別途入手したのですが、Mac miniのDVDドライブがこのDVDを認識してくれなかったため、ブータブルなUSBメモリを作成し、初期化に使用しました。

#環境
インストールUSBメモリを作成するために使った環境です。

* MacBook Pro（macOS 10.15.6）
* 外付けDVDドライブ
* 16GBのUSBメモリ
* Mac OS X Snow Leopard のインストールDVD

#1. Snow Leopard のインストールDVDからディスクイメージを作成する

ディスクユーティリティを使用してディスクイメージを作成しようとすると失敗します。
このバグはEl Captainのときに発生していたようで、Catalinaでも同じバグが発生しています。
そのため、ターミナルでhdiutilを実行し作成します。
ターミナルで次を打つとディスクイメージを作成できます。

```
$ hdiutil convert -format UDTO -o <出力ファイル名> <ドライブ名>
```

<出力ファイル名>は ~/cdrom などとすると、cdrom.cdr が作成されます。
<ドライブ名>は、Snow Leopardのディスクが入ったDVDドライブのドライブ名で、/dev/disk3 などとします。
ディスクドライブ名は diskutil list と打って調べます。
-formatのUDTOは、DVD/CDマスターのことです。
hdiutil convert -help と打つと他のフォーマットを調べることができます。
作成されたファイルの拡張子を「.cdr」から「.iso」に変更します。

#2. .dmg ファイルの生成

次のコマンドを実行して先ほどの cdrom.iso から SnowLeopard.img.dmg を生成します。

```
hdiutil convert -format UDRW -o ~/SnowLeopard.img ~/cdrom.iso
```

#3. USBメモリをアンマウントする

次のコマンドを実行してUSBメモリをアンマウントしておきます。

```
diskutil unmount <ドライブ名>
```
これをしないとこの後のUSBメモリへの書き込み時に「Resource busy」と表示され実行に失敗します。
<ドライブ名>は先と同様に diskutil list と打ってUSBメモリのドライブ名を調べます。
もし上記でコマンドを実行して次のメッセージが表示されたら、

```
<ドライブ名> was already unmounted or it has a partitioning scheme so use "diskutil unmountDisk" instead
```

次を実行してアンマウントします。

```
diskutil unmountDisk <ドライブ名> 
```

#4. ブータブルなUSBメモリを作成する

先ほど「3.」で生成した SnowLeopard.img.dmg をUSBメモリに書き込みます。

```
sudo dd if=~/SnowLeopard.img.dmg of=<ドライブ名> bs=1m
```
<ドライブ名>はUSBメモリのドライブ名を指定します。

#5. MacをUSBメモリから起動し、初期化する。

インストール先のMacにUSBメモリを挿し、Option キーを押しながら電源を投入します。
しばらくして表示される起動ドライブを選択する画面でUSBメモリを選択して起動。
後は画面に従えば初期化できます。
なお、USBメモリで起動後にディスクユーティリティで初期化対象のハードディスクを一旦消去してフォーマットしておかないと初期化できない場合があるかもしれません。

#参考
https://beiznotes.org/failed-to-make-a-cdrom-disk-image-on-macos-catalina/
https://qiita.com/kikuchy/items/4073c3bad9fe39101a25
https://www.taikun-room.com/2019/12/how-to-make-bootable-usb-installer.html
DockerのブリッジでIPアドレスが干渉した

# はじめに

物理ネットワークで `172.17.xxx.xxx` のアドレス帯を使用したときに起きた話。

Ubuntu 18.04.3 LTS
Docker version 19.03.5

# 本題

Dockerが自動生成するブリッジインタフェースが `172.17.0.xxx/16` を使用しており、
**物理ネットワークのアドレス帯と干渉した**。

`/etc/docker/daemon.json` で自動生成される際のIPアドレスを指定できるらしい。

```jdon:/etc/docker/daemon.json
{
    "bip": "192.168.0.1/24",
    "default-address-pools":[
        {
            "base":"192.168.0.0/16",
            "size":24
        }
    ]
}
```

ポイントとしては

- `bip` は `docker0` 向け
- `default-address-pools` は `br-xxxxxxxxxxxx` 向け
- `bip` は無くても `default-address-pools` から自動生成されるので省略して構わない

でした。
TrelloAPIをpythonで使う

TrelloAPIをpythonで使う機会があったので、まとめておきます。

## 準備
```.py
from trello import TrelloClient
import requests

key = '***********'
token = '***********'
trello = TrelloClient(key, token)
```
##ボード（名前、ID、URL）を取得

```.py
boards=trello.list_boards()
for board in boards:
    print(board.name)
    print(board.id)
    print(board.url)
    print("---------------")
```

## 特定のボードの情報を取得
```.py
#知りたいボードのIDを以下に代入
BOARD_ID="***********"

board=trello.get_board(BOARD_ID)
#リスト一覧取得
lists = board.all_lists()
#リスト名、リストID
for list_ in lists:
    print(list_.name)
    print(list_.id)

#カード一覧取得
cards=board.get_cards()
#カード名、説明、ID、URL
for card in cards:
    print(card.name)
    print(card.desc)
    print(card.id)
    print(card.url)
    print("------------------")
```

## カードを特定のリストに追加
```.py
BOARD_ID="***********"
LIST_ID="***********"

board = client.get_board(BOARD_ID)
target_list = board.get_list(LIST_ID)
#カード追加（カード名,説明）
created_card = target_list.add_card("card_name","card_desc")
```

## 説明、コメントを追加
```.py
CARD_ID="***********"
#カードを選択
card=trello.get_card(CARD_ID)
#説明を追加
card.set_description("~~~~~~~~")
#コメントを追加
card.comment("~~~~~~~~")
```

## カードにファイルを添付
```.py
CARD_ID="***********"
#カードを選択
card=trello.get_card(CARD_ID)
file_path= "***********"
file =  open(file_path, 'rb')
card.attach(name="~~~~~~~~",file=file)
```


参考
-
[py-trello](https://py-trello-dev.readthedocs.io/en/latest/_modules/index.html)

[Simple python script to upload a file to Trello.](https://gist.github.com/hugorodgerbrown/5058032)

[Python + py-trelloで、Trello APIを使ってみた](https://thinkami.hatenablog.com/entry/2016/03/01/003050)

[【Python】特定のハッシュタグが付いたツイートを自動的にTrelloのカードに追加](https://qiita.com/momopanda_jp/items/aaa67874fb4e9df8f126)

[PythonでTrelloのタスクを取得する](https://miyabikno-jobs.com/python-api-trello/)
『More Effective Agile』の感想

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236681/338516cb-5d4f-e3e4-cc03-3675768dcd74.png)

# 概要

https://www.nikkeibp.co.jp/atclpubmkt/book/20/P86580/


良いアジャイルチームに関する方法論、考え方がよくまとまっていると感じた。

昨今の開発現場ではDevOpsやアジャイルの議論は避けて通れない。
チームの技術的リーダーを自任する方は、ぜひ実際に読むことをお勧めしたい。

この中からいくつか、個人的に覚えておきたいと思った箇所を紹介する。

## 第３章：複雑さと不確実さという課題に対処する

複雑系や一般システム論の視点から、ソフトウェアおよびその開発の複雑さを説明している。
複雑さに対する基本的理解がなければ、なぜアジャイルでなければならないかを理解することは難しいだろうと思っている。

もしこの章に興味があれば、複雑系に関する本を読んで欲しい。

* [複雑系入門](https://www.kinokuniya.co.jp/f/dsg-01-9784871885607)

* [一般システム論 その基礎・発展・応用](https://www.msz.co.jp/book/detail/02522.html)

## 第５～７章：チーム構造、チーム文化、分散チーム

### 【チームのブラックボックス化とマイクロマネジメントの否定】

チームの自律性を育てるために、ブラックボックス化することについて説明している。
ブラックボックス化とは、チームの外部からマイクロマネジメントしないということ。

> **マイクロマネジメント**
> あれやれ、これやれ、こうやれ、と細かく指図すること。

アジャイルは、メンバー一人一人の成長と、自律性を重視している。
マイクロマネジメントは自分で考えて行動すること（自律性）を阻害する。
マネージャーは、メンバーの目的意識と自主性を育てるために細かく指示しないという事が、これまでの管理至上主義なプロジェクトマネジメントの考え方と異なると思っている。

### 【コンウェイの法則】

システムの大構造と人間組織の構造は一致すべきという事。
システムをDesign by Contract（責任による設計）によって設計するとすると、そのモジュールの責任は一つのチームに割り当てられているべき。

### 【人ではなく仕組みを修正する】

チームの中で何か問題が発覚したとき、人を問題の根源と考えるのではなく、システム（仕組み）を問題の根源と考える。
限界はあると思うが、仕組みを変えることによって行動の変革を促すことが「自律性を尊重する」という事だと思う。

## 第９章：プロジェクト

### 【プロジェクトを小さく保つ、スプリントを小さく保つ】

これがなかなか実際は難しい。プロジェクトはすぐ大きくなりがちだし、スプリントもすぐ長くなりがち。それを小さく保つには、常に意識する必要がある。

そうしないと加速度的にチームがカオスになるというのはとても感じる。
チームレベルでも個人レベルでも、常に心の中に置いておくべき価値観だと思う。

> 個人：Pull Requestはなるべく小さく保ち、短い時間でcloseする。

## 第１０章：大規模なプロジェクト

この章はとても面白かった。大規模なプロジェクトはウォーターフォールでやるしかないのではないか、というのがこれまで一般的に語られてきた文脈だと思う。ここでは大規模プロジェクトでアジャイルをするための考え方がまとめられている。
是非読んで欲しい。

### 【アーキテクチャを通じて大規模なアジャイルプロジェクトをサポートする】

基本的には、大規模プロジェクトは複数の小さなプロジェクトに分割する。

* 疎結合、モジュール化
* モノシリックなデータベースを回避する
* キューを使用する
* 契約による設計(Design by Contract)を使用する

いわゆるマイクロサービスアーキテクチャの話。
一般的な議論だがとても重要。

### 【スクラムオブスクラム（SoS）】

この言葉を初めて知った。複数のスクラムチームにより、大きなスクラムチームを構成する事。
スクラムチームにおけるメンバーが人間からチームに変わっただけとも言える。そしてSoSにおける考え方はスクラムチームと同じ。

```
スクラムチーム 1---* メンバー
スクラムチーム 1---1 スクラムマスター
SoS 1---* スクラムチーム
SoS 1---1 SoSマスター
```

プロダクトオーナーは全てのスクラムチームに配置すべきだろうか？SoSに一人だろうか？
全体に一人でいいように思うが・・・そこは分からなかった。

# 第１１章：より効果的なアジャイル：品質

### 【Definition of Done(DoD)】

完成の定義。何をもってタスクの完了とみなすか、文書化しろと。
レビューポイント、レビューの方法の定義などなど、あいまいだとタスクがいつ終わったのか分からなりがち。

## 第１７章：組織文化

* 間違いを許す
* 心理的安全性

DevOpsによく出てくるテーマだ。

## 第１８章：計測

計測の重要性は常に意識すべきだと思う。
ただし、計測しすぎないことも重要。過学習になる。

問題が発生したら、想像で修正に動くのではなく、ログを調べて原因を突き止めてから動くよう心がけよう。性能上問題が発覚した場合、いきなりコードを修正するのではなく、どこがボトルネックか計測してから修正しよう。

# 最後に

個人的には、大規模プロジェクトでもアジャイルできる希望を持った。
この内容が「当然だよね」と言える開発チームが日本国内に増える事を願っている。

---

## 付録： [[翻訳] スクラムがアジア圏でうまくいかない4つの理由 - Scrum does not work here in Asia](https://qiita.com/wataradio/items/6b79130b8ea53aa698aa)

日本でなぜアジャイルがうまくいかないのか？とても考えさせられる。
上に書いてあるような事を実際に実行しようとしたとき、おそらく多くの反発があるに違いない。

多くの開発現場で、ここに書かれているような罠に陥っているだろうという事は想像に難くない。
【メモ】空白文字、改行、タブ文字の正規表現

## スペース
``\s`` ･･･ 空白文字
``[\s]+`` ･･･ すべての空白文字

## 改行
``\r`` ``\n`` ``\r\n``･･･ 改行
``[\r|\n|\r\n]+`` ･･･ すべての改行

## タブ文字
``\t`` ･･･ タブ文字
``[\t]+`` ･･･ すべての空白文字


## おわりに
「すべてを置換」の時に使ってください😉
strlen関数とmb_stlen関数について

今日からPHP学び始めたので初歩的な内容ですがまとめたいと思います。
<br>

## strlen関数とは

これはrubyでいうところのstring#lengthメソッドと同じです。

構文はこうです。
<br>

```
strlen ( string $string ) : int

```

<br>

引数の`( string $string )`には文字列が入り`: int`は返り値となってます。

例えばこうです。

```
strlen('abc') => 3
```

ただ日本語の場合は違う返り値になります。
例えば、、、

```
$text = 'あいうえお'

strlen($text) => 15
```

なぜ。。。
<br>

原因としては日本語のマルチバイトはsjis, utf-8だからです。（現在はほとんどがutf-8みたいです。）

###マルチバイトとは

1バイトで表現できない（2バイト以上で表現する）データのことみたいです。。。
<br>
バイトってなんだ。。

###バイトとは

調べたところ、バイトとは、情報量の単位で、8ビットと等しい情報量のことを指すようです。

ビットってなんだ...

###ビットとは

　パソコンの内部でデータを扱う最小単位。
文字や数字などのデータは2進数で扱おり2進数の1桁をビットと呼び、これがデータを扱うときの最小単位になります。
2進数とは0か１で数を表すことを指しますね。
<br>

これらをまとめると１バイト（８ビット）は8ビットでは00000000から11111111までの256通りの数を扱えることを指します。

つまり日本語の文字はパターンが漢字もあるし256通りで表現できないということになり、1バイト以上になることがわかります。

そんな1バイトで表現できない（＝2バイト以上で表現する）文字を「マルチバイト文字」と呼んだりします。

<br>


話がだいぶ逸れましたが

```
$text = 'あいうえお'

strlen($text) => 15
```

こうなったのはひらがなの文字列は3バイトだからということでしょう。

もし日本語の文字列の正確な数を取得したい場合はマルチバイトに対応しているマルチバイト文字列関数を使いましょう。

```
$text = 'あいうえお'

mb_strlen($text) => 5


```
2020年9月にclusterで何かを作って楽しむ方法

# この記事でできること
- 9月にclusterを楽しむアレコレを書きました。
- 今月はclusterで何かを作りたいな−という方の参考になれば幸いです。


---

## 9月のお題企画は、「ひきこもりの秋」
- [ひきこもりの秋](https://note.com/cluster_official/n/n003faaa18d6d)
- clusterのワールド内に配置して、アバターが使用できるアイテムです。

> 2つのハッシュタグ「#cluster用アイテム #ひきこもりの秋」と
> 「アイテムがダウンロード可能なURL」を一緒にツイート！

- たとえば、公式noteにも紹介されていますが、[ねおソフトさんのハトソード](https://noir-neo.booth.pm/items/2162556)。

- Blenderやマジカボクセル、tinkercadでモデリングしたり、
Freeのアセットストアからの素材を改造するなどして、
Package化してBOOTH出店するのが近道かと。(あるいはgitHub)

- なお、「つかめるアイテムの作り方」は、[コチラ公式で紹介](https://creator.cluster.mu/2020/03/30/howto-item-create/)されています。

---


## clusterのサンプルプロジェクトを組み合わせる
- たとえば、うのっちの名作「[AddBalance](https://unityroom.com/games/addbalance)」は、バランスゲームなので、clusterで対戦するにはもってこい。

これ↓
![AddBalanceAniGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/62366bb0-898c-f78b-1e22-892973e97889.gif)

### 準備編
#### サンプルプロジェクトのダウンロード
- 「[的あてゲーム](https://creator.cluster.mu/2020/06/11/howto_shootinggame/)」のサンプルプロジェクトをダウンロードしよう。
- 的あてゲームのサンプル万能説。

#### クリエイターキットの更新
- 最新版は常に[コチラ](https://github.com/ClusterVR/ClusterCreatorKit/releases)で確認しておこう。
- zipファイルを解凍して、Packageマネージャーで、jsonファイルを選択する。
- クリエイターキットのアップデート方法は[コチラ](https://clustervr.gitbook.io/creatorkit/installation/update-creatorkit)から。

#### 目標のイメージ像
![AddBalanceForCluster2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/5fbf690c-b210-8f19-b6bf-fa722c572915.png)
![AddBalanceForCLusterAnim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/954a6652-293e-92f5-139c-947597352454.gif)
Scene画面↓
![スクリーンショット 2020-09-12 23.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/6c232e8f-dcfb-fb58-0c82-ee7562c4001b.png)

clusterでのワールドは[コチラ](https://cluster.mu/w/ef49e840-f2a4-4eca-817d-9ef4b54060a1)から。
まずはプレイしてみて、どんな改造を施しているか、考えてみましょう。

#### アセットで時短
- [POLYGON – Starter Pack](https://assetstore.unity.com/packages/3d/props/polygon-starter-pack-156819)
- すでに過去のプロジェクトで使用している場合は、Packageマネージャーからダウンロードすることができる。
【WordPress】functions.phpの内容が読み込まれない件

## 概要
タイトルの通り。
WordPressを最近初めて、`functions.php`の内容を修正して生成ページをリロードした時に
「css追加されないやん！」ってなり、
30分以上もの貴重な時間を無駄にしてしまった戒めのために記す。

## 結論
`functions.php`の"s"が抜けていた。:anguished:
(`function.php`になっていた）

## さいごに
エラーを吐いても、いいんじゃないかな...
xserverにpythonをインストールしてpipを使えるようにする

# 目的
Xserverは管理者権限がないので

- Python2.7.x   /usr/bin/python
- Python3.4.x   /usr/bin/python3.4
- Python3.6.x	/usr/bin/python3.6

が入っているが、パッケージ管理のpipがない＆インストールできない

# やったこと
Linuxbrewをインストールしてbrewでpythonを入れる

## Linuxbrewをインストール
適当なディレクトリで

```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
```

<b>以降 XXXXX　は Xserverでの自アカウントと置き換えてください<b/>

```
...
==> Select the Homebrew installation directory
- Enter your password to install to /home/linuxbrew/.linuxbrew (recommended)
- Press Control-D to install to /home/XXXXX/.linuxbrew
- Press Control-C to cancel installation
[sudo] XXXXX のパスワード:
```
と聞かれるので、 `Control-D` でアカウント配下のディレクトリにインストールする

しばらくダウンロード、インストールが動く...

インストールが完了すると以下のように `Next steps` とアドバイスされるのでそのとおり実行していく

```
==> Next steps:
- Run `brew help` to get started
- Further documentation: 
    https://docs.brew.sh
- Install the Homebrew dependencies if you have sudo access:
    sudo yum groupinstall 'Development Tools'
    See https://docs.brew.sh/linux for more information
- Add Homebrew to your PATH in /home/XXXXX/.bash_profile:
    echo 'eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)' >> /home/XXXXX/.bash_profile
    eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
- We recommend that you install GCC:
    brew install gcc
```

以下コマンドを実行。
gccはlinuxbrew入れるときに入っているがrecommendしてくれてるので念の為。

```
echo 'eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)' >> /home/XXXXX/.bash_profile
eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
brew install gcc
```

Python3系を入れる（マイナーバージョンは今回指定しなかった）

```
brew install python3
```

インストールしたら3.8.5が入りました。

```
$ python3 --version
Python 3.8.5

$ pip3 --version
pip 20.1.1 from /home/XXXXX/.linuxbrew/opt/python@3.8/lib/python3.8/site-packages/pip (python 3.8)
```

↑`python --version`　では /usr/bin/pythonのパスに通されるので2.7.x系が表示されます

### 注意点
.bash_profileを確認すると

```
PATH=$PATH:$HOME/bin

export PATHeval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
```
と PATHとevalに改行がなく次回ログイン時にPATHが効かない状態になる
改行いれてなおしておく
↓

```
PATH=$PATH:$HOME/bin

export PATH
eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
```
Amazon Pinpointが東京リージョンにやってきた！

# ようやく東京リージョンに！
[Amazon Pinpoint](https://aws.amazon.com/jp/pinpoint/)が東京リージョンに対応しました！
ようやく、[AWSブログ](https://aws.amazon.com/jp/blogs/news/amazon-pinpoint-tokyo/)でも正式発表！
[こちらのページ](https://aws.amazon.com/jp/about-aws/whats-new/2020/09/amazon-pinpoint-available-3-additional-regions/)で先に発表されてますね。東京と一緒にロンドンとカナダも。

9/7からマネジメントコンソールからリージョン選択で、東京リージョンが選べるようになってたので、[AWS Summit Online](https://aws.amazon.com/jp/summits/2020/)で発表されるかと思ったけど、現在開催中の[JAWS SONIC 2020 & MIDNIGHT JAWS](https://jawssonic2020.jaws-ug.jp/)中にひっそりと。笑

![スクリーンショット 2020-09-07 14.59.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447180/b603340d-c055-4d8f-18b6-53dbabe757f9.png)

ちょうどぼくたちのチームでも、Pinpointを使い始めていて、東京リージョンがなくて「米国西部（オレゴン）」にしてたので、早速移行してみようと思ってます。

![スクリーンショット 2020-09-07 15.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447180/e27c0413-0147-b975-f6cb-c5810a5e7c05.png)

**ap-northeast-1**でtestプロジェクトを作ることができました！
SonarQubeで静的解析（Java, Go, TypeScript）

## 目標

- Java, Go, TypeScript を利用するプロジェクトで SonarQube を利用して静的解析を行う

## 概要

- macOS 上に docker-machine, docker-compose で sonarqube のサーバーを立てる
- docker-machine の driver には VirtualBox を利用する
- テストカバレッジを SonarQube に与える設定は行わない
- SonarQube のサーバーを macOS 上に立てて、各プロジェクトに scanner を設定して実行する。scanner の設定方法が言語によって違う

## SonarQube サーバーを立てる

開発元が作っている docker-compose.yml をコピーしておく。
   https://github.com/SonarSource/docker-sonarqube/blob/master/example-compose-files/sq-with-postgres/docker-compose.yml

以下の手順で実行する

```bash
# docker-machine作成
docker-machine create default
# docker-machine起動
docker-machine start default
# sonarqubeが利用するElasticsearchを実行するためにパラメーターを変更
docker-machine ssh default "sudo sysctl -w vm.max_map_count=262144"
# 環境変数設定
eval $(docker-machine env default)
# IPアドレスを確認する(以下の例では192.168.99.100だとして例示する)
docker-machine ip
# sonarqube起動
docker-compose up -d
# ブラウザで開く(admin/admin でログイン可能)
open http://`(docker-machine ip)`:9000/
# 停止するときはCtrl+C
docker-compose rm
docker-machine stop
```

## Java の場合の実行方法

事前に `~/.m2/settings.xml` に設定をしておく。`<sonar.host.url>`の部分は`docker-machine ip`の IP を指定する

```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
  https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <offline/>
  <servers/>
  <mirrors/>
  <proxies/>
  <activeProfiles/>
  <pluginGroups>
    <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
  </pluginGroups>
  <profiles>
    <profile>
      <id>sonar</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <sonar.host.url>
        http://192.168.99.100:9000
        </sonar.host.url>
      </properties>
    </profile>
  </profiles>
</settings>
```

実行する

```bash
mvn clean verify sonar:sonar -Dmaven.test.skip=true
```

## Go の場合の実行方法

sonar-scanner を導入する

```bash
brew install sonar-scanner
```

`sonar-project.properties` を作成する

```properties
sonar.projectKey=com.company.projectkey1
sonar.projectName=My Project Name

sonar.sources=.
sonar.exclusions=**/*_test.go,**/vendor/**
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.test.exclusions=**/vendor/**
```

実行する

```bash
# sonar-scannerの導入
brew install sonar-scanner
# 実行する
sonar-scanner -Dsonar.host.url=http://192.168.99.100:9000
```

## TypeScript の場合

sonar-scanner を実行するためのパッケージを導入する

```bash
npm install -D sonarqube-scanner
```

sonar-scanner を実行するためのスクリプトを作成する. `sonar-project.js`という名前で作成する

```javascript
const sonarqubeScanner = require("sonarqube-scanner");
sonarqubeScanner(
  {
    serverUrl: "http://192.168.99.100:9000",
    options: {
      "sonar.sources": "./src",
    },
  },
  () => {}
);
```

package.json の`scripts`に以下を追加する

```javascript
"sonar": "node sonar-project.js"
```

実行する

```bash
npm run sonar
```
mailcatcherが起動しない場合にやること


<h2>はじめに</h2>
現在、「現場で使えるRuby on Rails5 速習実践ガイド」いわゆる、現場Railsをざっと通して学習しています。途中でmailcatcherを使うシーンが出てくるのですが、そこで詰まったのでメモとして置いておきます。

<h2>そもそもmailcatcherって</h2>
https://mailcatcher.me/

（訳）公式サイトの訳です
mailcatcherは、ウェブインターフェースから送信されるあらゆるメッセージをキャッチしてくれるシンプルなsmtpサーバです。mailcatcherを起動し、検証したいアプリの送信先をsmtp://127.0.0.1:1025に設定することで、mailcatcherで用意したブラウザでメールを確認することができます。

言ってしまえば、シンプルなメール検証gemです。

<h2>インストールと設定</h2>
インストールはgem installを公式が推奨しています。

```
$gem install mailcatcher
```

インストール後以下の設定を行います。（公式のrails欄を引用）


```environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { :address => '127.0.0.1', :port => 1025 }
config.action_mailer.raise_delivery_errors = false #ここはすでに記載がある箇所
```

<h2>起動方法とトラブルシューティング</h2>

この設定を行えば`mailcatcher`で起動できると公式にも書いてあるのですが、

```
$ mailcatcher
-bash: mailcatcher: command not found
```

コマンドが見つかりませんになってしまいました。

（１）rbenv rehash

```
$ rbenv rehash
rbenv: cannot rehash: /Users/local/.rbenv/shims/.rbenv-shim exists
```

ファイルが存在してるためrehashできないと言われる。

（２）rails sを止める
これは完全に凡ミスでした。sを止めないとそもそもrbenvができない。

（３）ファイルの削除
rehashができない原因のファイルの削除を行う

```
$rm /Users/local/.rbenv/shims/.rbenv-shim
```

改めてrehashすると、通ったようなので、改めて

```
$ mailcatcher
Starting MailCatcher
==> smtp://127.0.0.1:1025
```

無事に通りました！

<h2>参考サイト様</h2>
以下を参考にさせていただきました。
ありがとうございます。
https://k-koh.hatenablog.com/entry/2020/02/20/095445
https://qiita.com/ironsand/items/2f9f20e6e77ab1877160
SwiftUIでCoreDataを使おう！

SwiftUIでCoreDataの使い方を学んだので、忘れないためにメモします。少しでもCoreDataの使い方で苦労している人の助けになればいいと思います。
# Fetch処理
```
// 1
@Environment(\.managedObjectContext) var managedObjectContext
// 2
@FetchRequest(
// 3
  entity: Sample.entity(),
  // 4
  sortDescriptors: [
    NSSortDescriptor(keyPath: \Sample.inPutNum, ascending: true)
  ]
  /*
    特定の情報を取得したい時だけ、述語を追加する

    ,predicate: NSPredicate(format: "genre contains 'Action'")

    これを追加すれば結果を制限することができる
  */
  // 5
) var samples: FetchedResults<Sample>
```

1. managedObjectContext(管理オブジェクトが登録されているコンテキスト)にアクセスする宣言
2. プロパティラッパーを使用してプロパティを宣言。これにより、結果を直接使用することができる
3. CoreDataがfetchするEntityを指定。
4. `keyPath`でEntityの属性でソートします。ここでデータを読み込み、成形しているため必須
5. FetchedResults（フェッチ要求の実行結果）を継承する"samples"を宣言

# データの追加
```
// 1
let newSample = Sample(context: self.managedObjectContext)
// 2
newSample.inPutNum = self.keyPut
// 3                    
let appDelegate:AppDelegate  = UIApplication.shared.delegate as! AppDelegate
// 4
appDelegate.saveContext()
```

1. 新しいオブジェクトコンテキストを作成
2. パラメーターとして渡されるプロパティの設定
3. AppDelegateを継承する
4. 管理オブジェクトコンテキストを保存する

# 勝手にAppDelegate.swiftに追加されるメソッド達
プロジェクト作成時、CoreDataの項目を選択すると自動で２つのメソッドが追加されています。

## CoreDataStackを設定するために必要なこと
```php:AppDelegate.swift
// 1
lazy var persistentContainer: NSPersistentCloudKitContainer = {
  // 2
  let container = NSPersistentCloudKitContainer(name: "DemoCoreData")
  // 3
  container.loadPersistentStores(completionHandler: { (storeDescription, error) in
    if let error = error as NSError? {
      // 4
      fatalError("Unresolved error \(error), \(error.userInfo)")
    }
    })
  return container
}
```
1. persistentContainerを呼び出すとNSPersistentContainerを継承したプロパティが作成
2. コンテナを呼び出す
3. containerに永続ストアをロード。これにより、CoreDataStackがセットアップされる
4. エラーチェック

## ディスクにデータを保存する方法
CoreDataは自動的に保存しないため、ディスクに保存する処理が必要です。

```php:AppDelegate.swift
func saveContext () {
  // 1
  let context = persistentContainer.viewContext
  // 2
  if context.hasChanges {
    do {
      // 3
      try context.save()
    } catch {
      // 4
      let nserror = error as NSError
      fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
    }
  }
}
```
1. viewContext(永続コンテナの管理対象オブジェクトのコンテキスト)を取得
2. hasChanges(コンテキストに変更があるかをboolで返す)でデータに変更があった場合のみ保存
3. 保存する
4. エラー処理

# ソースコード
コードをGitHubで公開しているので、参考にしてください。  
https://github.com/r0227n/SwiftUI/tree/master/DemoCoreData

# 参考サイト
https://www.raywenderlich.com/9335365-core-data-with-swiftui-tutorial-getting-started