OmniAICreator/Qiita-1.07M huggingface dataset:
幅優先の二分木を深さ優先探索 (Ruby 3.0のEnumerator再帰について)


## 概要

階層が浅い順に左から1,(2,3),(4,5,6,7),...と詰められた2分木がある。これを先行順巡回し指定番目のノードを答えよ。

## 解答の出自

この問題の回答に行き着くまでの経緯は以下の通りである。

### CodeIQ 結城先生のTriany問題

Triany Low Level Interface(TLLI)およびDICT Interface(DICTI)を実装する問題。
「ウチに来ない？」(企業が管理者ページから評価を閲覧できる)問題であり、コードのインターフェース部を含めて評価されるものであった。
DICTIは実際にはどういうデータ構造でもよく、線形リストでも良かったのだが、2分木で解くことにした。
多分初めての木構造の実装だと思う。

https://github.com/cielavenir/codeiq_solutions/blob/master/yuki_hiroshi/tyama_codeiq238.rb


### AOJの2分木問題(ALDS1 8A/8B)

TrianyのDICTI(Dict-Interface)を派生させて解いた。DICTではなくSETでよかったのでTrianyの範疇でもそこそこくどくなく書けたらしい。

https://github.com/cielavenir/procon/commit/a240bf8153d43dffd44c1736df5446345d4bdce3

### AOJの2分木問題(巡回のみ)(ALDS1 7C)

BioRuby(Bio::Tree)を用いて解いた。[Rosalind](http://rosalind.info/)でBioRubyを多用していた[^1]ためその流れ。

https://github.com/cielavenir/procon/commit/e9118df1fc054f3e80f6a1b56ede532fdae6c882

### ALDS1 7Cを標準機能のみで

C++で解くと同時にRubyでも標準機能だけで解いた。[^2]
https://github.com/cielavenir/procon/commit/d3b38f9115e924a2b531013026a3902b7b2be734

### 表題、yieldに変形

https://github.com/cielavenir/codeiq_solutions/blob/master/thisweek_masuipeo2/tyama_codeiq3197.rb


## リストを返す再帰関数

なぜここまで長々と経緯を書いたかというと、この答案の原型は巡回結果を出力するのみであり、値を返すものではなかったということを述べるためである。

さてリストを返す関数の再帰は思ったよりも面倒である。C++で値を返すためには返値用の配列を持って回るのが一般的であるが。Ruby(やPython)には別の手段がある。 **yield** である。Pythonでは、(Python3であれば) **yield from** を使えば良い。しかし、Rubyにはyield fromは存在しない。

しかし擬似的にyield fromを実現することは可能である。具体的には、以下の3要素で構成される(はずだった。後述)。

- **block_given?** を確認し、偽ならEnumerator化する
- 返す要素を **yield** する
- 再帰時に **&proc** を渡し、再帰先でのyieldにより親のブロックが実行されるようにする。再帰においては最も肝要な要素である。

## &proc

**残念ながら&procの表記法はRuby 3.0で使えなくなった。** ブロックを渡したいなら明示的にブロックを引数として受けよということである。であれば、yieldとはなんなのだろうか。

まず、Pythonにおいて、yield fromは本来必要ではない。以下の2つは同じものである[^3]。

```py
yield from rec()
for e in rec(): yield e
```

また、Rubyにおいてyieldは必要ではない。以下の4つは同じものである(f1はRuby 3.0では動作しないが)。

```rb
def f1(n)
  return to_enum(:f1, n) if !block_given?
  return if n<=0
  yield n
  f1(n-1,&proc)
end

def f2(n, &blk)
  return to_enum(:f2, n) if !block_given?
  return if n<=0
  blk.call(n)
  f2(n-1, &blk)
end

def f2x(n, &blk)
  blk or return to_enum(:f2x, n)
  return if n<=0
  blk.(n)
  f2x(n-1, &blk)
end

def f3(n)
  return to_enum(:f3, n) if !block_given?
  return if n<=0
  yield n
  f3(n-1){|e|yield e}
end
```

blk.callの糖衣構文としてyieldが用意されたのであるという理解でいる。
ならば、Sub-Enumeratorへの移譲を(blk変数無しで)行えるようにすべきであると信じる。(f2xで)blkのnil判定に取って代わられた[^4]block_given?は不遇。


[^1]: 手元で実行して答えを返す形式なので外部ライブラリは問題ない。CodeJam(やIndeed Coding Duel)もこの形式。
[^2]: 日(略)
[^3]: コロンのあとに改行しないのを禁ずるとするのは[宗教](https://qiita.com/cielavenir/items/19e3b180cfe940d3d9b5)だよなー
[^4]: 更にいうとこのor+statementってPerl由来(のはず)(||は不可)
macbook pro 2020(intel)にgraphvizを入れようとしたらエラー吐いたので解決してみた

#経緯
vscodeでplantUMLを使おうと思い、拡張機能を入れて遊んでいた際、クラス図でクラスを2個以上作るとエラーを吐いたので解決策としてgraphvizを入れることにしました。

```
% brew install graphviz
```
を実行。するとエラーが；；

```
Updating Homebrew...
fatal: Could not resolve HEAD to a revision
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
==> New Casks
brooklite                                simtoolkitpro
==> Updated Casks
Updated 19 casks.

==> Searching for similarly named formulae...
Error: No similarly named formulae found.
Error: No available formula or cask with the name "graphviz".
It was migrated from homebrew/cask to homebrew/core.
```

==> 似たような名前の式を検索すると...
エラーが発生しました。類似した名前の式は見つかりませんでした。
エラーです。graphviz "という名前の利用可能な数式またはカスクがありません。
homebrew/caskからhomebrew/coreに移行されました。

とのこと
このあと色々やって解決しやした

#解決手順
まず以下を実行してみました。

```
% brew doctor
```
すると

```
Warning: Some taps are not on the default git origin branch and may not receive
updates. If this is a surprise to you, check out the default branch with:
  git -C $(brew --repo homebrew/core) checkout master
```
だからできんかったのかぁ
早速上の

```
 % git -C $(brew --repo homebrew/core) checkout master
```
を実行
すると

```
Updating files: 100% (5827/5827), done.
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
```
なんかできたっぽいですね
これでまた

```
% brew install graphviz
```
を実行したら無事にインストールできました！

PlantUMLも無事にうごきました！
![スクリーンショット 2021-03-24 2.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1008454/04c00d8f-d308-6748-c8ea-2ee1e268c398.png)
express-sessionをMongodbで。

#初めに
今回の記事は対して裏取りをしておりませんので憶測で物をいうことが多いと思います。気になりすぎて夜も眠れネェヨクソが！という方は"フッザケンじゃねぇよ!"を接頭辞にコメントを寄せてもらえればと思います。

#connect-mongo
バージョンがアップしたのかどうなのかこちらのモジュールを日本語の記事を参考に使おうと思えば使えませんでした。というわけで、[公式のページ](https://www.npmjs.com/package/connect-mongo#usage)を参考にちょこっとだけ覚書していきます。解説はしません。というかできません。（まだべんきょうちゅー）

```node.js
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);

⇓⇓⇓

var session = require('express-session');
var MongoStore = require('connect-mongo');
```
上のようにしてrequireしてみようとすれば、

```
TypeError: Class constructor MongoStore cannot be invoked without 'new' at Object.<anonymous>
```
というエラーが出てきて、よくわからなかったので公式のページを見てみれば下の様に完結of完結に書いてありました。・・・よくわかんないけど、まぁ、いっか！バージョン違いとか多分そんなんでしょ。


```node.js
var options = {
  db:'example',
  host:'localhost',
  port:27017,

  ...
  etc
  ...

  clear_interval: 60 * 60
}

⇓⇓⇓

var options = {
  mongoUrl: 'mongodb://username:password@localhost:27017/database',
  autoRemove: 'native'
};
```
optionsと分けるか分けないかは個人の自由ですけれど、自分は分けたい派の人間ですので分けました。
このoptionsもhostとかdbとかportとかあった・・・のかな？あったみたいですが、mongoUrlと簡潔になりましたね。mongodbモジュールでアクセスするときと全く同じURLでいけるようです。

```node.js
app.use(session({
  secret:'foo',

  store: new MongoStore(options)
}));

⇓⇓⇓

app.use(session({
  secret: 'foo',

  store:MongoStore.create(options)
}));

```
sessionの中身です。new MongoStore(options)で出来たようですが、自分がやってみれば出来なかったですので、公式のページをみたところ、MongoStore.create(options)でできるようです。ほんといろいろと変わったんですね。できることなら変えないでほしかったんですけど。（楽々参考にできるドキュメントがなくなるから）

#最後
というわけで、ほんとに最低限ですけど、この設定でエラーは起きませんでした。その代わり警告は出ますけどね。しかし優秀なプログラマーのあなた方であれば、警告の一つや二つは解決することなんて簡単でしょう！
というわけで終わりです。
困った人の助けに少しでもなればよかったのですが。
画像(image)の登録と編集の仕方 (途中)

###やりたいこと
ユーザーに紐づいた画像の登録、表示、編集をしたい
画像はフォルダーを作って、フォルダーの中に登録し、画像の名前はDBに登録する
なので
登録する時はファイル名はDBに登録して、画像はフォルダーに登録
表示する時はDBから画像名を取得し、フォルダーから画像を持ってきて表示させる

####登録
#####html.erb

#####controller.rb


####登録
#####html.erb

#####controller.rb
Variadic Tuple Typesでジェネリック型の要素を持つタプルを、別のジェネリック型の要素を持つタプルに変換する

# やりたかったこと
タイトルの通りですが、もともとのモチベーションは「あるジェネリック型の要素を持つ配列」を、「別のジェネリック型の要素を持つ配列」に変換（このとき型引数は引き継ぐ）したいというものでした。色々試行錯誤した結果、対象を配列ではなくタプル型で定義し、Variadic Tuple Typesを使うと目的の型定義ができることがわかりました。

```typescript
// イメージ
const beforeList = [Before<number>, Before<string>, Before<number>]
const afterList = convert(beforeList)
// afterListの型は [After<number>, After<string>, After<number>] になる
```

上の通り、`Before<T>` 型の要素を持つ配列があり、これを `convert` という関数に渡すと、各要素の型引数 `T` を引き継いだまま、`After<T>` の配列が帰ってくるというイメージです。この `convert` に型付けしたいというのがモチベーションです。
※ 前述の通り、最終的にはタプル型で定義しています。

# 実装
いきなり結論ですが、以下で定義できました。

```typescript
// サンプルとして Before<T> 型と After<T> 型を定義
type Before<T> = {
    type: 'before',
    value: T,
}

type After<T> = {
    type: 'after',
    value: T,
}

// convert の型定義 (関数本体の実装は省略しています。)
function convert<T extends ReadonlyArray<Before<unknown>>>(beforeList: [...T]): [
    ...{ [K in keyof T]: T[K] extends Before<infer U> ? After<U> : never }
]

// テスト
const before1: Before<number> = {
    type: 'before',
    value: 1,
}

const before2: Before<string> = {
    type: 'before',
    value: 'string',
}

const afterList = convert([before1, before2]); // [After<number>, After<string>] 型になっている
```

上では `convert` の引数の中で `[before1, before2]` と書いているので、これがタプル型と判断されています。ポイントは Variadic Tuple Types によって要素数が不定のタプルの中身を `...T` で受けられていることです。受けた後は `T` の各要素にインデックスアクセスすることができ、例のように Map してそれぞれの要素から型変数を取り出すことができています。

もし上の例で before のタプルを関数の外で定義する場合は、

```typescript
// before のリストを外で定義する場合
const beforeList: [Before<number>, Before<string>] = [before1, before2];
const afterList = convert(beforeList);
```

のように、明示的にタプル型で定義することが必要です。


昨年いくつかVariadic Tuple Typesの紹介記事を目にしたときには、自分が TypeScript に不慣れだったこともありいつ使うものなんだろうと思っていましたが、今回必要に迫られて利用してみるととても便利な型であることがわかりました。

[本記事の内容の TypeScript Playground へのリンク](https://www.typescriptlang.org/play?#code/C4TwDgpgBAQhBmB7AThAPAFQHxQLxQG8AoKUqUSALigHIAjBFCGgGhLIDcBDAGwFcI1DGwC+RIhWgBBeMAjJMOfMTLlwg2l1nzW7Ut34bhRMUXh8AdgGNgAS0QWoVhx3nBMUCAA85FgCYAzlAAShBcfg48IFLIyFwgaHBIqGiWANYWiADuFlh5ABQMyRAAMrYBwNQA2gB0dRgAugCU1XpQdTUEUFUA0lC2jmkQIIjwUI1CvQ2ePhD+QUlMaAPw8lAAqjgA-FAycgqbUNQWEK7IUGIN4s4WFVBFTACM1IspFnwAtgzISoRtktR6IxULpVAYBNRHqJrg47g9UAAmF7A9AVZADADmvxUZABtHhzDYYN4ENoaMxulMNzuWn2ZTu+BuZ2A+SqBKh9xRCOaAG4YbdgJzivTKt1Xuh3l95FgWLAUWhyRYsdN8GyURyCdy+dTBbT5CKEXgnC43IUUSKmnygA)
IBM Cloud Cloud Foundryのアプリケーションの削除などのメモ


CLIからの制御メモです。

[Cloud Foundry アプリケーションの管理](https://cloud.ibm.com/docs/cli?topic=cli-ibmcloud_commands_apps)にまとまってます。[Cloud Foundry サービスの作成](https://cloud.ibm.com/docs/cli?topic=cli-ibmcloud_commands_services)とは別物なので注意

[IBM CloudのCloud Foundryデプロイの無料枠のメモリ制限](https://qiita.com/n0bisuke/items/6f23897fbf405ef91b7b)でいくつか作ったアプリを削除してきます。

## アプリの一覧表示 (ibmcloud app list)

```bash
$ ibmcloud app list   
 
'cf apps' を起動しています...

nobisuke@protoout.onmicrosoft.com として組織 n0bisuke / スペース dev 内のアプリを取得しています...
OK

名前                要求された状態   インスタンス   メモリー   ディスク   URL
n0bisuke-testapp5   stopped          0/1            64M        1G         n0bisuke-testapp5-persistent-bear-jh.mybluemix.net
n0bisuke-testapp3   started          1/1            64M        1G         n0bisuke-testapp3-nice-lynx-sg.mybluemix.net
n0bisuke-testapp2   started          1/1            64M        1G         n0bisuke-testapp2-intelligent-gazelle-ig.mybluemix.net
n0bisuke-testapp    started          1/1            64M        1G         n0bisuke-testapp.us-south.cf.appdomain.cloud
```

これで一覧が表示されました。

## 削除 (ibmcloud app delete APP_NAME)

アプリ名を指定して削除します。n0bisuke-testapp5を消す場合は以下

```bash
$ ibmcloud app delete n0bisuke-testapp5

'cf delete n0bisuke-testapp5' を起動しています...


アプリ n0bisuke-testapp5 を削除しますか?> y
nobisuke@protoout.onmicrosoft.com として組織 n0bisuke / スペース dev 内のアプリ n0bisuke-testapp5 を削除しています...
OK
```
GitHubDesktop上でリポジトリを削除できなくなった。

#備忘録

環境：Windows10

Windows環境でGitHubDesktopを操作した際、
リポジトリの削除が行えず苦戦したことを、備忘録としてアップします。

GitHubDesktop上でリポジトリを作成。
動作テスト完了後、削除を行うとした際、エラーMSGが表示され削除ができない現象が発生。

##試したこと
1. Webからリポジトリを削除、GitHubDesktop上から削除。
2. webからリポジトリを作成、GitHubDesktopから先に削除。
3. 隠しファイル.gitを削除。<br>
→結果的には隠しファイルの.gitを削除にて解決。

エラーメッセージ

```
Failed moving repository directory to Recycle Bin.
A common reason for this is if a file or directory is open in another program.
```

![github_desktop_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459220/793a1c0d-add9-f89f-c592-60d9a3ed7e9d.png)

直訳すると・・・

```
リポジトリディレクトリをごみ箱に移動できませんでした。
これの一般的な理由は、ファイルまたはディレクトリが別のプログラムで開かれている場合です。
```

１．Webからリポジトリを削除、GitHubDesktop上から削除。
Repository>setting>Delete this repository
現象変わらず。
厄介なことに同じディレクトリ配下に新たなリポジトリを作成しようとすると、
似たようなエラーMSGが表示されリポジトリが作成できなくなる問題も発生。

２．webからリポジトリを作成、GitHubDesktopから先に削除。
現象変わらず。
エラーMSGやRecycle Bin.というキーワードを調べた結果、Windowsの隠しファイルにて
.gitを削除すると今回の現象が解決されるのでは？と糸口を掴む。

３．隠しファイル.gitを削除。
Windowsで.gitの隠しファイルを表示させるために以下を設定。
表示タブ＞隠しファイルにチェック
.gitファイルが表示。

![隠しファイル2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459220/d491ec60-29db-08f8-8087-1028abec7d2d.png)

この隠しファイルを削除することにより、事象が解決。

macOSであれば、対象ディレクトリまで入り、rm -rf .gitと
コマンド実行すれば簡単に削除ができるのですが、
Windows環境だとgitをインストールしたりなど少し手間がかかりそうです。
もしかしたら、vscodeにてターミナルからコマンド入力ができるかもしれない。

当分はWindows環境でガリガリする予定もないので、備忘録程度に上げておきます。

以上、初投稿でした。
Javaの拡張ForループでMapをループするときの書き方


JavaでMapの拡張For文の書き方を忘れてしまったのでメモ的に記載。

```java:SampleController.java
for(Map.Entry<Integer, Entity> entity : map.entrySet()) {
    System.out.println(entity.getKey());
    System.out.println(entity.getValue());
}
```
[JS] オブジェクト

定義方法
---

{　}　＝　オブジェクトリテラル

初期化を行なってからプロパティを格納する

```
const person = {　};
person.name = 'shun';
```

初期化を行なうタイミングでプロパティを格納する

```
const person = {
  name: 'shun'
};
```

---

オブジェクトの中にオブジェクトを格納したり、配列を格納することもできます。

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  }
};

```

ドット記法
---
person.color;のような記法を「ドット記法」と言い、値を取得できる

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  }
};

console.log(person.color);
```

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

---
値を変更する

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  }
};

person.age = 12
console.log(person.age);
```

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

ブラケット記法
---
[　]で書く記法

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  }
};

person['age'] = 12
console.log(person.age);
```


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

---
ブラケット記法は、変数を使いたい場合に使用します

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  }
};

const agekey = 'age'
person[agekey] = 12
console.log(person.age);
```


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

キー情報が動的な場合に、意図して[　]を使うことがあります

メソッドの格納
---
オブジェクトはメソッドも格納することができます

```
const person = {
  name: 'shun',
  age: 20,
  gender: 'male',
  color: ['white', 'black'],
  interests: {
    sports: 'soccer',
    music: 'King Gnu'
  },
  getFullColor: function() {
    console.log(this.color[0] + this.color[1])
  }
};

const agekey = 'age'
person[agekey] = 12
console.log(person.age);
person.getFullColor();
```

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

thisオブジェクトは、宣言されたオブジェクトのこと（今回だったらperson）
【保存版】Form用正規表現

今回はForm用の正規表現を書いていこうかなと思います。

１つ１つ説明していると長くなるので、分からないところは自分なりに調べてみてください。

それでは早速やっていきます。

#空白が無いか#

入力フォームでまず確認すべきことは空欄が無いか

これだけは関数として書きます。

```js
    validateRequiredInput(...args) {
      // 入力フォームで空欄が無いかの確認
      let isBlank = false
      for (let i = 0; i < args.length; i = (i + 1) | 0) {
        if (!args[i] || args[i] === '') {
          isBlank = true
        }
      }
      return isBlank
    },
```

``...args``で引数を何個でも受け取れるようにしています。

#メールアドレス#

```js
const regex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
regex.test(email)
```

#住所#

##都道府県##

```js

const regex = /^[一-龥]+$/
return regex.test(prefecture)
```

漢字で制御

##市区町村##

```js

const regex = /^[ぁ-んァ-ン一-龥]+$/
return regex.test(city)
```

ひらがな、カタカナ、漢字で制御

日本にはカタカナの市があるらしい。

興味深かったので一応載せておきます（笑）。

・山梨県南アルプス市

軽く調べたぐらいなので、もっとあるかも。

##番地##

```js

const regex = /[0-9]+(-|ー)[0-9]+(-|ー)[0-9]/
return regex.test(number)
```

ちなみに最大桁数は「静岡県浜松市西区篠原町」の``27409``だそうです。

##郵便番号##

```js

// ハイフンなし
const regex = /[0-9]{7}/
// ハイフンあり
const regex = /[0-9]{3}(-|ー)[0-9]{4}/
return regex.test(code)
```

#電話番号#

```js

// ハイフンなし
const regex = /^0[789]0[0-9]{4}[0-9]{4}$/
// ハイフンあり
const regex = /^0[789]0-[0-9]{4}-[0-9]{4}$/
return regex.test(number)
```

#クレジットカード#

##番号##

やり方は電話番号とほぼ一緒

```js

// ハイフンなし
const regex = /[0-9]{4}[0-9]{4}[0-9]{4}[0-9]{4}$/
// ハイフンあり
const regex = /[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$/
return regex.test(number)
```

セキュリティコードも同じようにやってあげればいいので割愛します。

##名義##

```js

const regex = /^[A-Z]+\s[A-Z]+$/
return regex.test(name)
```

大文字のみを適用

``\s``は半角スペースを表している

とりあえず今回はこんなところで終わりにします。

変更があれば随時更新していきます。
Flutterの名前付きコールバック ValueChanged

## 動機
しばらく書かないと、すぐ忘れてしまうので。

以前、以下のVoidCallbackの記事を書いたところ、忘れづらくなった感覚があったり、

https://qiita.com/toda-axiaworks/items/1ef00343ce3c032c6400

Web上にあると、どこからでも参照出来るので便利であると感じています。

## 使用例

Flutter 2.0.1 で動作確認しました。

```dart

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ValueChanged Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

/// ページ
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'ValueChanged',
          style: TextStyle(
            fontSize: 16,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
      ),
      // body: _List(),
      body: _Body(),
    );
  }
}

/// body
class _Body extends StatefulWidget {
  @override
  __BodyState createState() => __BodyState();
}

class __BodyState extends State<_Body> {
  /// フードリスト
  final foods = [
    '寿司',
    'ラーメン',
    'カレー',
    '焼肉',
    'ハンバーグ',
  ];

  var selectedFood = '食べ物を選択して下さい';

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: ListView.builder(
            itemCount: foods.length,
            itemBuilder: (
              BuildContext context,
              int index,
            ) =>
                FoodListItem(
              title: foods[index],
              onTap: (title) => setState(
                () => selectedFood = title,
              ),
            ),
          ),
        ),
        SizedBox(height: 30),
        Text(selectedFood),
        SizedBox(height: 80),
      ],
    );
  }
}

// 食べ物のリストアイテム
class FoodListItem extends StatelessWidget {
  const FoodListItem({
    this.title,
    this.onTap,
  });

  final String title;
  final ValueChanged onTap;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: InkWell(
        // タップされた食べ物の名前を返す
        onTap: () => onTap(title),
        child: Container(
          height: 65,
          alignment: Alignment.centerLeft,
          padding: EdgeInsets.only(left: 15),
          child: Text(
            title,
          ),
        ),
      ),
    );
  }
}

```

タップした食べ物が、画面下部のラベルに表示されます。

![スクリーンショット 2021-03-24 0.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/eaf02136-c549-60fb-9e00-1d62c5346cc7.png)

## メモ

定義を確認すると、同じ意味になるのですが、

```dart
final ValueChanged<String> onTap;
```
の部分を、以下のように書いてあることも多いです。むしろValueChangedは、ほとんど見ないくらいな気もします。（これでよく混乱しています。）

```dart
final void Function(String) onTap;
```
【Swift】QiitaAPIアプリで学んだこと

#はじめに
自作アプリ、QiitaAPIで学んだことをまとめます。（自分用メモ）

#GitHubリンク
https://github.com/0429oonishi/QiitaAPI

#学んだこと
###API通信をしている処理とViewControllerの分離
悪い例

```swift:QiitaViewController
func fetchQiitaAPI() {
    guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=10") else {
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let error = error {
            print(error)
            return
        }
        guard let data = data else {
            return
        }
        do {
            let qiitas = try JSONDecoder().decode([Qiita].self, from: data)
            self.qiitas = qiitas
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}
```

良い例

```swift:QiitaViewController
private func fetchQiitaAPI() {
    //メイン処理
    QiitaAPI.shared.fetchQiitaAPI(page: pageCount) { result in
        switch result {
        case .success(let qiitas):
            self.qiitas = qiitas
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        case .failure(let error):
            print(error)
        }
    }

}
```

```swift:QiitaAPI
typealias ResultHandler<T> = (Result<T, APIError>) -> Void

class QiitaAPI {
    //シングルトンで
    static let shared = QiitaAPI()
    private init() { }
    
    func fetchQiitaAPI(page: Int, handler: @escaping ResultHandler<[Qiita]>) {
        //メイン処理
        guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=\(page)") else {
            handler(.failure(NetworkError.invalidURL))
            return
        }
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let error = error {
                handler(.failure(error))
            }
            guard let data = data else {
                handler(.failure(NetworkError.unknown))
                return
            }
            do {
                let qiitas = try JSONDecoder().decode([Qiita].self, from: data)
                handler(.success(qiitas))
            } catch {
                handler(.failure(NetworkError.invalidResponse))
            }
        }
        task.resume()
    }
    
}
```
`typealias ResultHandler<T> = (Result<T, Error>) -> Void`とおくのもポイント

###JSONがスネークケースの時の対応

```swift:Model
enum CodingKeys: String, CodingKey {
    case title = "title"
    case createdAt = "created_at"
    case user = "user"
}
```
`CodingKeys`を設定する

二つ目の方法として、このようにしてあげれば自動でスネークケースに変換してくれます。

```swift
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
```


#おわりに
おわりです。
【ミライトデザイン社内勉強会#20】「IDDD本から理解するドメイン駆動設計」輪読会~第11章「ファクトリ」~

### 前回の記事
[【ミライトデザイン社内勉強会#19】「IDDD本から理解するドメイン駆動設計」輪読会~第10章「モジュール」~ - Qiita](https://qiita.com/tkek321/items/248a4203c40b96fcfa84)

## [実践DDD本 第11章「ファクトリ」～複雑な生成をユビキタス言語でシンプルに～ (1/3)：CodeZine（コードジン）](https://codezine.jp/article/detail/10903)

### 集約の取得や生成はリポジトリが行うイメージだったけど、集約から他の集約を生成する時にDBに保存しているデータが欲しくなった場合はどうするの？

[p2](https://codezine.jp/article/detail/10903?p=2)

- Applicationサービスとかで、あらかじめ必要なデータをRepositoryやQueryServiceで取得して置いて、メソッドに渡すのでは？
- リポジトリはデータの永続化や再構築は行うが、集約の生成自体は行わない
    - 再構築と生成は別
        - 生成は不変条件が必要、再構築はチェック済のデータを取得するだけなので、不変条件のチェックはいらない。
        - 再構築する場合は、リポジトリからnewしてくればいい
- 使い方はコンストラクタでnew する時と同じ
    - Factoryを使う側はコンストラクタで生成する場合と同じようにFactoryからインスタンスを取得する
        - コンストラクタでインスタンスを生成する場合とはちがって、生成する時の条件を指定できる

- Repository = 倉庫
    - 倉庫なので、生成はしない
    - 再構築
    - データの取得
- Factory = 工場
    - 生成する
    - Factoryで生成したものをRepositoryに保存する
- Factoryを置く場所
    - コンストラクタ
    - 集約上のFactory
    - サービス上のFactory
- ファクトリでは集約の生成を同じ手続きで行うようにする

### ファクトリで不変条件を満たすとあるが、オブジェクト側でその条件を保証するんじゃないの？

[p2](https://codezine.jp/article/detail/10903?p=2)

> 不変条件を満たすファクトリ

- 他のエンティティの不変条件なので、生成前にオブジェクト自身では保証できない

### `優れたファクトリは「生成される具象クラスではなく、要求される型に応じて抽象化されないといけない」`ってどういう意味

[p3](https://codezine.jp/article/detail/10903?p=3)

- 返り値の方を具象クラスでなく、インターフェースで定義しろみたいな話かな？
    - ちょっと日本語難しくてわからん。

[ファクトリが不要な条件](https://blog.j5ik2o.me/entry/20101229/1293634287) 

>ここまでファクトリの必要性を説いていますが、ファクトリが不要な場合もあります。
>DDD Quickly日本語版では、以下の条件が示されています。

> - オブジェクトの作成処理が複雑でない。
>- オブジェクトの作成処理内で他のオブジェクトを作成しない。必要な属性はすべてコンストラクタで設定する。
>- クライアントはオブジェクトの実装に興味がある。例えば、ストラテジパターンを使って処理を選択したい。
>- クラスは具体的な型であり、その型から派生しているクラスはない。したがって具体的な実装を選ばなくていい。

## 次回
[【ミライトデザイン社内勉強会#21】「IDDD本から理解するドメイン駆動設計」輪読会~第12章「リポジトリ」~ - Qiita](https://qiita.com/tkek321/items/7f58a3aa26b325331345)
Gitでコミットログを汚さずにやりかけの状態を他の人に共有する

## 背景
ペアプロやモブプロをやっていると、変更が中途半端でそのままコミットしたくないようなタイミングでもドライバーを変更することがあります。リモートペアプロなどソースを編集する環境が別環境の場合だと変更を共有するためには一度リポジトリを経由する必要がありますが、中途半端な変更をコミットしてしまうとコミットログが汚れてしまいます。`git stash`の退避内容を共有できたらいいのですが、stashにそんな機能は無いですし。

というわけで、コミットログを汚さずにやりかけの状態を他人へ渡すための、私なりに考えた方法を書きます。
※もっといいやり方がありましたらコメントで教えてください！

## 手順
AさんのやりかけをBさんに渡す場合、以下の手順で渡します。

### Aさん(やりかけを渡す人)の手順
``` bash
# (1) 変更内容を退避する
$ git stash save

# (2) 捨てブランチを作成し、ブランチを切り替える
$ git checkout -b tmp-yarikake

# (3) 退避した変更を、捨てブランチにcommit＆pushする
$ git stash pop
$ git add -A .
$ git commit -m "中途半端なコミット"
$ git push origin tmp-yarikake
```

### Bさん(やりかけを受け取る人)の手順
``` bash
# (4) リモートリポジトリをfetchする
$ git fetch

# (5) (3)のコミット内容を取り込む
$ git cherry-pick 8169d7c

# (6) (5)のコミットをresetする
$ git reset --mixed HEAD^

# (7) 不要になった捨てブランチを削除する
$ git push --delete origin tmp-yarikake
```
手順が多いように見えますが、1つ1つは簡単です。

## 各手順の解説

### (1) 変更内容を退避する
捨てブランチを作成するために、一度修正内容を退避します。

``` bash
$ git stash save
```

### (2) 捨てブランチを作成し、ブランチを切り替える
リモートリポジトリにプッシュするための捨てブランチを作成します。このブランチは最終的には削除しますので、`tmp`など一時的なブランチであることが分かる名前にすると良いでしょう。

```
$ git checkout -b tmp-yarikake
```

### (3) 退避した変更を、捨てブランチにcommit＆pushする
修正内容をコミットします。このコミットは最終的なコミットログとしては残りません。コミットメッセージには一時的なコミットであることがわかる内容を記載しておくと良いでしょう。

``` bash
$ git stash pop
$ git add -A .
$ git commit -m "中途半端なコミット"
$ git push origin tmp-yarikake
```

### (4) リモートリポジトリをfetchする
ここからはBさんの操作になります。まずは(3)のpush内容を購読するためにfetchします。

``` bash
$ git fetch
```

### (5) (3)のコミット内容を取り込む
※Aさんの最初の作業ブランチ
特定のコミットを取り込めるcherry-pickを使って(3)の変更をマージします。`8169d7c`の部分には(3)のコミット時のコミットIDを指定しましょう。

``` bash
$ git cherry-pick 8169d7c
```

### (6) (5)のコミットをresetする
cherry-pickを使うと変更分は自動でコミットされてしまうので、コミットの取り消しを行います。
これで、BさんのローカルにAさんのやりかけの状態を復元することができました。

``` bash
$ git reset --mixed HEAD^
```

### (7) 不要になった捨てブランチを削除する
不要になった捨てブランチを削除します。
(6)で目的は達成されたのでこの作業は必須ではないですが、一時的なブランチを残しておくのは微妙なので可能なら消しておきましょう。
また、ブランチから参照されなくなったコミットはいずれ消える[^1]ため、(3)のコミットも無かったことにすることができます。

[^1]: https://git-scm.com/book/ja/v2/Gitの内側-メンテナンスとデータリカバリ

``` bash
$ git push --delete origin tmp-yarikake
```

以上です。同じような悩みを持つ方いらっしゃいましたら使ってみてください。
Heroku に react アプリケーションをデプロイして遊ぶ

## Heroku に登録
https://jp.heroku.com/

## Heroku CLI のインストール

```sh
sudo snap install --classic heroku
```

https://devcenter.heroku.com/articles/heroku-cli#download-and-install

インストールできたけど、updateしてねって言われた。が、無視しちゃう。

```sh
$ heroku -v
 ›   Warning: heroku update available from 7.49.0 to 7.51.0.
heroku/7.49.0 linux-x64 node-v12.16.2
```

## react app 作成 & Heroku にデプロイ
以下の記事をそのとおりやる。
https://blog.heroku.com/deploying-react-with-zero-configuration

## できた
かんたん。
react から叩くAPIも Heroku で用意したい。また明日。
Dockerを使ったRuby on Rails6の環境構築

Dockerとdocker-composeを使ってRuby on Rails6の環境を構築しました。


### 前提
Docker & docker-composeをインストール済み

### 動作環境
- macOS Catalina 10.15.7
- Docker 20.10.2
- docker-compose 1.27.4

<br>

ディレクトリを作成します。

```
mkdir rails_api_docker
cd rails_api_docker
```

<br>

`Gemfile` `Dockerfile` `docker-compose.yml`を作成します。

```ruby:Gemfile
source 'https://rubygems.org'

gem 'rails', '6.0.3'
```

```dockerfile:Dockerfile
FROM ruby:2.7.1-alpine3.11

ENV BUNDLER_VERSION=2.1.4

WORKDIR /usr/src/app

COPY Gemfile .
COPY Gemfile.lock .

RUN apk update && \
    apk add --no-cache \
    shared-mime-info \
    yarn \
    nodejs \
    linux-headers \
    libxml2-dev \
    curl-dev \
    make \
    gcc \
    libc-dev \
    g++ \
    sqlite-dev \
    tzdata && \
    gem install bundler && \
    bundle install

COPY . .

EXPOSE 3000
```

```yml:docker-compose.yml
version: '3'
services: 
  web:
    build: .
    ports: 
      - '3000:3000'
    volumes: 
      - .:/usr/src/app
    tty: true
    command: ["rails", "server", "-b", "0.0.0.0"]
```

<br>

docker-composeを使ってRailsアプリケーションを作成します。

```
docker-compose run web rails new . --force
```

<br>

もう一度Dockerイメージをビルドします。

```
docker-compose build
```

<br>

docker-composeを起動します。

```
docker-compose up
```

<br>

`localhost:3000`にアクセスし、以下が表示されれば成功です。
![スクリーンショット 2021-03-24 0.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1016415/ad3becf3-b59d-6db4-d044-c03e82c3fdee.png)

<br>

読んでいただきありがとうございました！ご指摘やご意見などありましたらコメントしていただけると嬉しいです🐳
機械学習が学べるサイトまとめ

自分が機械学の勉強をしたり、情報収集をする際に参考にしているサイトのまとめ
随時追加予定

###学習教材
[PyTorchチュートリアル（日本語翻訳版）]
(https://yutaroogawa.github.io/pytorch_tutorials_jp/)
公式チュートリアルの日本語版。Gooogle Colaboratoryファイルもあるのですぐ始められてありがたい。

[chainerチュートリアル]
(https://tutorials.chainer.org/ja/tutorial.html)
開発が終了してしまったchainerだが、基本的な内容のため参考になる。

[東京大学松尾研究室　演習コンテンツ]
(https://weblab.t.u-tokyo.ac.jp/%e6%bc%94%e7%bf%92%e3%82%b3%e3%83%b3%e3%83%86%e3%83%b3%e3%83%84%e5%85%ac%e9%96%8b%e3%83%9a%e3%83%bc%e3%82%b8/)
東京大学の松尾研究室が監修した学習講座を無料で公開してくれてる。環境構築不要でgoogle colaboratoryですぐ始められる


[Udemy]
(https://www.udemy.com/ja/)
有料の動画講座で講座の質に多少ばらつきがある。
pythonや機械学習関係の講座が豊富で初心者向きの内容が多く、学習の敷居が低め。ただし1講座当たりの値段は高い(数千円～2万円程度)。

[Corusera]
(https://ja.coursera.org/)
動画講座大学や企業から講義が提供されているため、全体的に質が高め。一部機能に制限があるが無料でも受けられる。
スタンフォード大学などの有名大学の講座を無料で受けられるのは魅力的。
ただ、日本語は字幕版がほとんど。


[SIGNATE]
(https://signate.jp/)
国内のコンペティションプラットフォームで、機械学習の講座も受講できる（月額2000円）。
テキストベースの講座だが、現実社会での実際の課題をベースとした演習を受けられるためかなり実践的。


###技術解説・ニュース等
[AI-SCHOLAR]( https://ai-scholar.tech/)
AI関係中心のニュースサイトで、最新論文の情報などかなり技術よりな内容が多い。

[AINOW](https://ainow.ai/)
AI全般のニュースを取り扱っているニュースサイトで、カジュアルな内容からモデル解説までと内容の幅が広い。

###コード・モデル
[pytorch-image-models](https://github.com/rwightman/pytorch-image-models)
timmと呼ばれるパッケージ。様々なCNNモデルを簡単に使用できる。
割と最近のEfficientNetやその派生形もあり種類が豊富

[lightgbmドキュメント]
(https://lightgbm.readthedocs.io/en/latest/index.html#)
テーブル系コンペで方式に迷ったらコレ、というくらい強力な機械学習モデル

[Papers With Code: The latest in Machine Learning](https://paperswithcode.com/sota/image-classification-on-imagenet)
最新のSoTAモデルを探せるサイト、主に画像認識用のモデルが精度ごとに確認できる。

[SuperGLUE]
(https://gluebenchmark.com/leaderboard)
最新のSoTAモデルを探せるサイト、こちらは自然言語処理系のモデルが確認できる。

###ドキュメント類
機械学習を行う上で必ずと言っていいほど使用されるモジュール群。kaggleで他人のコードを見ていて困ったときに確認する。

[Pytorchドキュメント]
(https://pytorch.org/docs/stable/index.html)
[numpyドキュメント]
(https://numpy.org/doc/stable/reference/)
[pandasドキュメント]
(https://pandas.pydata.org/docs/)
[matplotlibドキュメント]
(https://matplotlib.org/3.3.3/contents.html)
ソースコード内でのTeensyの判別

同じソースをTeensyと他の一般的なOS用とで共用する時に、Teensyだけで定義したい何かとかその逆があると思うんだけど、その時にはこれを使えば良いっぽい。

```hoge.cpp
#if defined(TEENSYDUINO)
(略)
#endif
```

ボクは何か変数をFLASHに置きたい時にこんな風にしてる。PROGMEMはTeensy(というかArduino)で変数をFLASHに置く指定。

```hoge.cpp
#if defined(TEENSYDUINO)
#include <avr/pgmspace.h>
#else
#define PROGMEM const
#endif

PROGMEM unsigned int const_var_temp = 100;
```

なぜかTeensyでビルドする時にPROGMEMとconstを同時に使うとエラーになるので、上記のようにしている。
Visual Studio CodeでGoogle Cloud Shellを開く

VSCode の Remote Development を使って、Google の Cloud Shell に ssh で接続して開発を行う方法です。

macOS および Windows10 でそれぞれ手順が少し異なります。また、Windows10 では Cloud Shell への接続に WSL(Windows Subsystem for Linux) を使用します。[^1]

[^1]: Windows版 Google Cloud SDK には ssh用ツールとして`putty.exe`が同梱されており、手順4.で設定する`-W`オプションが使用できないため

## 手順
### 1. `gcloud`コマンドを準備する
Google Cloud SDK をインストールします。

macOS は通常の手順で、Window 10 は Ubuntu の手順などに従って WSL 内でインストールを行います。その後、`gcloud`コマンドが使えることを確認します。

https://cloud.google.com/sdk/docs/install

### 2. Cloud Shell に ssh接続できることを確認する
```console
$ gcloud cloud-shell ssh
```

#### 2-1. (Windows 10のみ)`~/.ssh/google_compute_engine`を移動する
Cloud Shell に ssh したあと、`~/.ssh/google_compute_engine`に生成されている秘密鍵をWSLからWindows側の適当な場所に移動させておきます。

### 3. VSCode に拡張機能 「Remote - SSH」 をインストールする
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh

### 4. `~/.ssh/config` を編集する
下記のように設定を追加します。`User`と`IdentityFile`など、適宜内容を書き換えること。

#### Mac
```ssh
Host cloudshell
    ProxyCommand gcloud cloud-shell ssh --ssh-flag='-W localhost:22'
    User CloudShellのユーザー名
    IdentityFile ~/.ssh/google_compute_engine
    StrictHostKeyChecking no
```

#### Windows 10
```ssh
Host cloudshell
    ProxyCommand C:\Windows\system32\wsl.exe gcloud cloud-shell ssh --ssh-flag='-W localhost:22'
    User CloudShellのユーザー名
    IdentityFile 手順2-1.で移動させたフォルダ\google_compute_engine
    StrictHostKeyChecking no
```


### 5. VSCode から Cloud Shell を開く
VSCodeの左下の青いボタンか、F1キーを押して「Remote-SSH: Connect to Host...」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268782/6b714c0c-85d0-de58-de96-839874069065.png)

その後、「cloudshell」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268782/122985b0-5d2f-5e18-b8fb-ae98181139a7.png)

## 参考
https://www.youtube.com/watch?v=d1yb-ee7jX0

動画でも使用されている`StrictHostKeyChecking`、`UserKnownHostsFile`は警告メッセージを非表示にするための設定のようです。

https://qiita.com/liubin/items/654ea5ace65a8c3cc56b

また、動画では`User`を記述していませんが、ローカルのユーザー名とCloud Shellのユーザー名が異なる場合に必要です。
PowerShellでHexハッシュ生成

特筆すべきこと🍐

```powershell
[array]	$HexChar		=	(-Join ([char[]]((48..57) + (97..102)))).ToCharArray()
[string]$RandomizedHex	=	-Join (Get-Random -Count 8 -input ${HexChar})
```

>ワンラインだと見づらいので分けています。
AWS NorthStarってなんだ？

おもしろそうなプロダクトを発見しました。
第一印象としては、**AWSのマネジメントコンソールみたいなUIを簡単に作れるフレームワーク**だと思います。

その名も**NorthStar**。

![northstar.aws-prototyping.cloud_(Laptop with MDPI screen).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/e8ba6dcd-090e-be72-2f9a-168af4fb96ba.png)

GitHubリポジトリ
https://github.com/aws/aws-northstar

ドキュメント
https://northstar.aws-prototyping.cloud/


[About NorthStar](https://northstar.aws-prototyping.cloud/#/About%20NorthStar)のページを一部日本語訳してみました。

> **NorthStarを使用すると、直感的で意味のあるアクセス可能なユーザーエクスペリエンスを大規模に迅速にプロトタイプ化できます。**

> NorthStarは、直感的で意味のある、アクセスしやすいユーザーエクスペリエンスを迅速にプロトタイピングするための標準となることを目指しています。 それはあなたの仕事を簡素化し、あなたの顧客のために大規模で一貫した、予測可能な経験を確実にします。 NorthStarを使用すると、イノベーションに集中し、少ない労力でより多くのことを実行できます。

---



いくつかドキュメントのキャプチャを。

*Layouts*としていくつか用意されていて、こちらは`AppLayout`。
Examplesのキャプチャを見ると一目瞭然、これは**マネジメントコンソール**ですね。

![northstar.aws-prototyping.cloud_(Laptop with MDPI screen) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/660934a7-0142-a2ba-5964-579b8fee4c92.png)

お次は*Components*の`Alert`。

![northstar.aws-prototyping.cloud_(Laptop with MDPI screen) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/8e40724f-ea09-b55e-ba67-e6979552a690.png)

`KeyValuePair`

![northstar.aws-prototyping.cloud_(Laptop with MDPI screen) (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/a25e3b77-c3d9-9ce3-29b0-8f3cc45acc15.png)

なんと、*Charts*もあります。

![northstar.aws-prototyping.cloud_(Laptop with MDPI screen) (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/52534f1d-7388-5012-8bbe-4e2cd952540d.png)


なにか作ってみたくなりますね。
[JS] 配列


JSの配列は、数値・文字・booleanなど、複数のデータ型を一つの配列に併せ持つことができる

```
const arry = [1,2,3,4,5,6, 'banana', false];
console.log(arry);
```

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

push
---
pushプロパティで配列に要素を追加できる

```
const arry = [1,2,3,4,5,6, 'banana', false];
arry.push('new item')
console.log(arry);
```

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

unshift
---

unshiftプロパティで、配列の最後に要素を追加できる

```
const arry = [1,2,3,4,5,6, 'banana', false];
arry.unshift('new item')
console.log(arry);
```

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

pop
---
popプロパティは配列の最後の要素を削除できる

```
const arry = [1,2,3,4,5,6, 'banana', false];
arry.unshift('new item')
arry.pop(　);
console.log(arry);
```

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

---
popで削除した要素は、定数に代入して出力することもできる

```
const arry = [1,2,3,4,5,6, 'banana', false];
arry.unshift('new item')
const val = arry.pop(　);
console.log(val);
```

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

shift
---
shiftプロパティで配列の最初の要素を削除できる

```
const arry = [1,2,3,4,5,6, 'banana', false];
arry.unshift('new item')
const val = arry.shift(　);
console.log(val);
```

[![Image from Gyazo](https://i.gyazo.com/c08af738e375aae14d33c348f52a3877.png)](https://gyazo.com/c08af738e375aae14d33c348f52a3877)
ポートフォリオ制作時の落とし穴

前書き
  ・自分が見直せるようにメモ書きになります。
  ・私がプログラミング未経験からプログラミングを制作していく上で詰まった場所が多かったので記事して残します。
・プログラミングを勉強し始めてから1カ月でポートフォリオ制作を始めました。

ポートフォリオ制作時に詰まった部分とは
　1.if文などの書き方もよくわからない状態でポートフォリオ制作をしてしまったこと
　2.参考書などを購入して勉強すべきだったこと
　3．見積もりが甘かったこと

詰まった部分の改善策
　1.Progateの基礎、応用コースなどで学習した後にポートフォリオを制作しました。それだけではポートフォリオで必要となるif文の書き方などは「Progateの説明を見れば書ける」この程度でした。ポートフォリオを制作していてもProgateのイラストを見返さないといけない状態でした。これではコードの丸写しのようなものです。あまり意味がありません。Progateの学習段階で自分で調べる癖をつけて実践で詰まっても調べれば解決できる力が必要になります。

　2．私はProgateで学習したのだから基礎は学習済みと思っていました。しかしポートフォリオを制作していく段階で調べてもわからない事がたくさん出てきます。明らかに基礎学習不足でした。Progateでは一度学習をしていましたが実際にコードに書く時にはコードは書けませんでした。参考書や本などを購入して学習することで必要な時に必要な部分の知識のインプットが出来たと実感しています。調べてもわからないことは基礎がなっていないのです。私は3H以上調べることは日常でした。時間の無駄です！基礎勉強してください。

　3．ポートフォリオを制作していくうちにTrelloを使用して時間を管理するようになりました。3hで実装完了できる項目に7h以上費やしてしまうことは日常茶飯事でした。この問題の解決策としては、実装していく段階で詰まった時は基礎学習をし直すことです。基礎学習を選択肢に入れることにより遅延がなくなると考えています。

最後に
　これからエンジニアになる自分へ
　エンジニア人生の小さな一歩にすぎません。これからたくさん学習して立派なエンジニアになるように！健康一番できっとできるぞ。
Windows 版 IntelliJ IDEA で WSL 上のプロジェクトを開いた後に出る警告 (Filesystem Case-Sensitivity Mismatch)

どうやら Windows 版 IntelliJ IDEA は NTFS か FAT を前提として大文字小文字を区別しない設定らしいのだが,
\\\\wsl$\ 以下のプロジェクトを開くとちゃんと警告で『区別するー？』と聞いてきてくれる。

聞いてきてはくれるのだが、どこで設定できるのかは教えてくれない。

## 設定場所
メニューバー から Help > Edit Custom Properties... を選択する

ファイルが存在しない場合

"File '%APPDATA%\JetBrains\IntelliJIdea2020.3\idea.properties' does not exist. Create?"

のように問うダイアログがでるので Create ボタン押下で作成する。

※ %APPDATA% の部分は実際には C:\Users\your_name\AppData\Roaming のような値のはず

```idea.properties
# custom IntelliJ IDEA properties

idea.case.sensitive.fs=true
```

こんな感じで collation を厳密に設定する。
ローカル環境（Truffle＋Ganache）でブロックチェーンアプリ開発入門①【イントロダクション】

# はじめに
　ブロックチェーン技術を利用したデジタル資産の一つであるであるNFT（非代替性トークン）が今年(２０２１年)に入って人気が爆発し、アートや音楽における分野で目覚ましい発展を遂げています。
　先日、イーロンマスク氏が手がけたNFT作品に１億円以上の価値がつけられたというニュースもそれを物語っています。
　そこで今回はこれらに利用されるブロックチェーン技術を利用した初歩的なアプリケーションを作成し、ブロックチェーンでアプリケーションを開発するとはどういうものなのかを実際に開発し体験していくこととします。

# 対象者
　ブロックチェーン、Botcoin、Ethereumなどの入門書を一通り読み、アプリケーションを作成してみたい方。または、ブロックチェーンの技術をなんとなくは理解できているが実際にどのようにしたらアプリケーションが作成できるか分からないという方。
　本記事ではブロックチェーンの入門書で頻繁に使用されるような語句の解説などは行わないので、もし単語や語句の意味が分からなければ入門書に都度戻ってもらって確認してみてください。
　また、作成するアプリケーションにはWEBアプリとスマホアプリを想定していますので、Vue.jsやFlutterの基本的な知識を持っていることが前提になります。

# 学べること
- ローカル環境にEthereumのprivate環境を構築する方法
- スマートコントラクトの作成とデプロイの仕方
- ブロックチェーンに接続、コントラクの実行を行えるWEBアプリ・スマホアプリの作成方法

# 作成するもの
Truffleでは、TruffleBoxというアプリケーションのテンプレートが利用できます。
今回はTruffleBoxで用意されている「METACOIN」というテンプレートを使用して、独自トークンをユーザ同士で交換できるアプリを作成していきます。 

* [ローカル環境（Truffle＋Ganache）でブロックチェーンアプリ開発入門②【チェーン構築・コントラクトデプロイ】](https://qiita.com/marimomasuo/items/9552dfc5138fd9121615)
* ローカル環境（Truffle＋Ganache）でブロックチェーンアプリ開発入門③【WEBアプリ編】
* ローカル環境（Truffle＋Ganache）でブロックチェーンアプリ開発入門④【スマホアプリ編】
【paiza】【Java編】Cランクレベルアップメニュー　標準入出力　 STEP: 2 複数行にわたる出力　解いてみた！

Aybeeです！

Javaのスキルアップのために、「paizaラーニング」さんの問題を解き始めました。
記録用ですが、お役に立てれば幸いです:innocent:

他の問題についても記事をアップしております。
興味がございましたら、マイページへどうぞ！

#はじめに
この記事では、「paizaラーニング」さんの以下の問題について記載しています。
より良くするためのアドバイス、お待ちしております！


プログラミング練習問題「複数行にわたる出力」

https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_std_in_out_step2



※当問題は、以下のように作成したコードを公開することが推奨されています。
![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424017/9f51b8e5-9aab-019c-e19f-09d71eb92ea5.png)


#問題
整数 n が与えられるので、 n 回、改行区切りで paiza と出力してください。

##入力される値
入力は以下のフォーマットで与えられます。

n

整数 n が 1 行で与えられます。

入力値最終行の末尾に改行が１つ入ります。
文字列は標準入力から渡されます。 標準入力からの値取得方法はこちらをご確認ください

##期待する出力
n 回 paiza と改行区切りで出力してください。

paiza
...
paiza

末尾に改行を入れ、余計な文字、空行を含んではいけません。

#作成したコード

```java

import java.util.*;


public class Main {
    public static void main(String[] args) {
        // 自分の得意な言語で
        // Let's チャレンジ！！
		Scanner sc = new Scanner(System.in);
		int data = sc.nextInt(); // ⓵Scannerで入力された値を変数「data」に入れる

		/*
		 * ⓶変数「data」の値分、繰り返し「paiza」と出力する
		*/
		for (int i = 0; i < data; i++) {
			System.out.println("paiza");
		}
		sc.close();
	}
}
```

#解説
「Scanner」クラスを通じて入力された値を、
⓵「nextInt()」メソッドでint型で変数に設定し、
⓶その変数の値分、for文で繰り返し処理を行いました！

今回こだわったポイントは、**「nextInt()」**メソッドを使用したことです！
前回の[単純な入出力] (https://qiita.com/Aybee/items/6b27bc1afca11097fad8)では、String 型を変数に設定したかったので、「nextLine()」メソッドを使用したのですが、今回はInt型で変数に設定したかったので、調べました。
他にも、「next()」メソッドなど、便利そうなメソッドがあったので、これから勉強したいです！

おわり:smile:
"SendMessage cannot be called during Awake"を出さずにインスペクターの値を反映させる


グラフィカルなボタンをデザインして、その表示内容をスクリプトで切り替えたい場合があります。
![DuaringAwake00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/f73627a1-e984-aa36-4e26-4dad67157eea.png)

```C#:ButtonTextSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ButtonTextSelector : MonoBehaviour
{
    public Sprite[] Jp;
    public Sprite[] En;

    public enum TxtList
    {
        Tutorial, Option, GameStart, OK, Tweet, Title, Skip, Close
    }

    public bool isJp = true;

    [SerializeField]
    private TxtList _Txt = TxtList.OK;
    public TxtList Txt
    {
        set
        {
            _Txt = value;
                int idx = (int)Txt;
                if (isJp)
                {
                    GetComponent<SpriteRenderer>().sprite = Jp[idx];
                }
                else
                {
                    GetComponent<SpriteRenderer>().sprite = En[idx];
                }
        }
        get { return _Txt; }
    }
}
```

ですが、このままでは実行するまで表示内容がかわらないため、インスペクターで設定した値で表示内容を確認したい場合、

```C#:
    void OnValidate()
    {
        Txt = Txt;
    }

```
のようにOnValidate()をつけてインスペクターの値が変更されたときの処理を書くことが多いと思いますが、このOnValidate()を使ってインスペクターの値を変更すると、
![DuaringAwake01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/b8a50ca1-47af-e0c7-abb9-2ca124681738.png)
と一応は反映されますが、"SendMessage cannot be called during Awake, CheckConsistency, or OnValidate UnityEngine.StackTraceUtility:ExtractStackTrace ()"という警告が出ます。
![DuaringAwake02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/4dfdb724-9937-783a-0bb2-de34ee966d3d.png)
しかも#pragma warning disable XXX で表示を消すことが出来ず、非常にうざったらしいです。

なのでこの警告を出さずにインスペクターの値を反映させるためには、クラスの頭に[ExecuteAlways]アトリビュートをつけて、Update()で更新させるようにします。

```C#:ButtonTextSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways]
public class ButtonTextSelector : MonoBehaviour
{
    public Sprite[] Jp;
    public Sprite[] En;

    public enum TxtList
    {
        Tutorial, Option, GameStart, OK, Tweet, Title, Skip, Close
    }

    public bool isJp = true;

    [SerializeField]
    private TxtList _Txt = TxtList.OK;
    public TxtList Txt
    {
        set
        {
            _Txt = value;
                int idx = (int)Txt;
                if (isJp)
                {
                    GetComponent<SpriteRenderer>().sprite = Jp[idx];
                }
                else
                {
                    GetComponent<SpriteRenderer>().sprite = En[idx];
                }
        }
        get { return _Txt; }
    }

    void Update()
    {
        if (!Application.isPlaying)
        {
            Txt = Txt;
        }
    }
}
```

[ExecuteAlways]をつけるとエディター上でも実行中と同じ処理を行うようになるため、Update()が実際に実行されインスペクターの値が反映されるという仕組みです。
![DuaringAwake03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1146955/a8bd542d-95dc-7727-9de2-609670b19420.png)
"SendMessage cannot be called during Awake"の警告が出なくなりました。
Active Storageの概要

# Active Storageについて
ファイルアップロード機能を簡単に実装できる機能（Gem）。Railsに統合されているため、指定のコマンドを実行することで簡単に導入できる。
Amazon S3, Google Cloud Storage, Microsoft Azure Storageなどのクラウドストレージサービスに対するファイルのアップロードを簡単に行うことができる。クラウドストレージの他に、ローカルディスクにファイルを保存することもできる。

# Active Storage 使い方

### 1. Active Storageをインストール
Active Storageをアプリケーション内で使用するための準備として、以下コマンドを実行する。

```:ターミナル
rails active_storage:install
```

上記コマンドを実行すると、Active Storageに関連したマイグレーションが作成されるのでマイグレートし、

* active_storage_attachments
* active_storage_blobs

上記テーブルが、データベースに追加されていれば成功:v:

### 2. Active Record モデルの用意
ファイルアップロード機能を使いたいモデルを用意する。(ここではtweetモデルにしておきます)
画像用のカラムを用意する必要がない点もActive Storageの特徴の一つ:eyes:

### 3.ファイルの添付
##### 3-1) 1つの添付ファイルの場合
Tweetモデルに1つの画像を添付するには、has_one_attachedを使う。

```:tweet.rb
class Tweet < ApplicationRecord
  has_one_attached :image
end
```

```:tweets_controller.rb
class TweetsController < ApplicationController

  (省略)

  def create
    @tweet = Tweet.new(tweet_params)
    if @tweet.save
      redirect_to root_path
    else
      render 'new'
    end
  end

  （省略）

  private

  def tweet_params
    params.require(:tweet).permit(:image, :text).merge(user_id: current_user.id)
  end

end
```

#### 3-1) 複数の添付ファイルの場合
Tweetモデルに1つの画像を添付するには、has_many_attachedを使う。
フォームのfile_fieldにmultiple: trueを追記して、複数ファイルの選択を許可する。

```:tweet.rb
class Tweet < ApplicationRecord
  has_many_attached :images
end
```

```:tweets_controller.rb
class TweetsController < ApplicationController

  (省略)

  def create
    @tweet = Tweet.new(tweet_params)
    if @tweet.save
      redirect_to root_path
    else
      render 'new'
    end
  end

  （省略）

  private

  def tweet_params
    params.require(:tweet).permit(:images, :text).merge(user_id: current_user.id)
  end

end

```

```:new.html.erb
<%= form_with model: @tweet, local: true  do |f| %>
  <%= f.file_field :images, multiple: true %>
  <%= f.text_area :text %>
  <%= f.submit %>
<% end %>
```

### 4. ファイルの保存先
ファイルの保存先は、各環境の設定ファイルに記載する。
初期状態では、開発環境(development)、本番環境(production)ともに保存先は :local に設定されている。この local とは、 config/storage.yml で定義された保存先の名前。（保存先の変更については別の記事で記載したいと思います:zzz:）

# 参考
https://railsguides.jp/active_storage_overview.html
https://qiita.com/hmmrjn/items/7cc5e5348755c517458a
DockerでRails環境構築


##①　Docker関連のファイルを用意
###Dockerfile


```:Dockerfile
# ベースイメージの指定
FROM ruby:2.7

# 必要なライブラリのインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn 
#   作業ディレクトリの指定
WORKDIR /app
# ソース以下のファイルをコピー
COPY ./src /app
# rubyに必要なgemのインストール
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install
```
###docker-compose.yml

```:docker-compose.yml
version: '3'
# 管理するコンテナの記述
services:
  # データベース
  db:
    image: mysql:8.0
    # Mysqlの認証設定
    command: --default-authentication-plugin=mysql_native_password
    volumes:
    # ローカルのデータ：dockerのデータ　同期するための記述
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  # rails
  web:
    # ディレクトリ直下のDockerfileを参照
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
    # ローカルのデータ：dockerのデータ　同期するための記述
      - ./src:/app
    ports:
    # ローカルのポート：dockerのポート
      - "3000:3000"
    depends_on:
    # Myaqlに接続するための記述
      - db
```

###Gemfile
```:Gemfile
# railsのgemをインストールするための雛形
source 'https://rubygems.org'

gem 'rails','~> 6.1.0'
```     

##②Railsをインストール
```:terminal
rails_docker % docker-compose run web rails new . --force --database=mysql  // dbをmysqlに指定しrailsのインストール　--force(強制的に実行オプション)
.
.
.
Webpacker successfully installed 🎉 🍰
```

##③イメージをビルド
```:terminal
rails_docker % docker-compose build 
```

##④新しく作成されたdatabase.ymlを編集
```:database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password  //記述
  host: db　　//記述
```

##⑤データベースを作成
```:terminal
rails_docker % docker-compose run web rails db:create 
```

##⑥起動
```:terminal
rails_docker % docker-compose up
```
![スクリーンショット 2021-03-23 23.30.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961525/efe21aae-53b9-adf1-de83-bcab84324ca2.png)

##参考サイト
きよとのプログラミング大学
なんてステキな split コマンド

Google Search Console で読み込むことができる sitemap.xml は 1ファイル 50,000URL が上限となっています。 See: [サイトマップの作成と送信](https://developers.google.com/search/docs/advanced/sitemaps/build-sitemap?hl=ja)
sitemap.xml を作るための、元の URL のリストファイルがウン十万行とあったので、これを 5万行ごとに分割してから、 sitemap.xml を作ることにしました。

そんな巨大なテキストファイルを分割するときに、大活躍なのが split コマンドです。

split コマンドは MacOS に入ってます。 (BigSurで確認)
Amazon Linux の場合は 1 にも 2 にも入ってます。

ウン十万行の url_list.txt ファイルを
5万行ずつの
url_list00.txt
url_list01.txt
url_list02.txt
url_list03.txt
....
に分割したいときは、以下のようにします。

```
split -l 50000 -d --additional-suffix=.txt url_list.txt url_list
```
-l オプションは分割した1ファイルの行数です。
-d オプションは接尾辞を数字の連番で付与します。
--additional-suffix=SUFFIX は上記末尾の後に付与する文字列です。拡張子を付けたい場合はこのオプションで。
そのあとに分割するファイル名、
そのあとにファイル分割後の接頭辞(省略可)です。


```
split -l 行数 [-d] [--additional-suffix=SUFFIX] ファイル [分割後ファイルの接頭辞]
```

かなりの行数でも split コマンドなら爆速で処理終了です。

AWS EC2 t3.small(gp3) で、125万行近いファイルを 25個のファイルに分割したときの time の結果がこちら。

```
real    0m0.038s
user    0m0.012s
sys     0m0.004s
```
なんて速いんだ！