OmniAICreator/Qiita-1.07M huggingface dataset:
Rubyの大クラス主義について解説してみた

Rubyを勉強していったら、「Rubyには大クラス主義というものがあるんだよ」というのを聞いて、自分はよくわからなかったので調べてみてわかったことを記事にしようとおもいます。

## 大クラス主義
例えば、配列を表すクラスにArrayクラスというものがRubyにあります。そしてArrayクラスにはpopメソッドやunshiftメソッドがあります。
ここから分かることはArrayクラスにはキューやスタックとしても使えるんです。
自分はJava等の言語を触ったことはないのですが、JavaではQueueクラスやStackクラスとそれぞれ分かれているみたいです。
他にもeachメソッドがありますが、JavaではIteratorクラスが用意されていて、それぞれが処理するみたいです。

このようにRubyのArrayクラスでは、Arrayクラスでは担う役割が大きいんですね。そのことを**大クラス主義**といいます。

※キューやスタックについてよく分からない方は以下の記事を参照にしてみてください

https://qiita.com/jnchito/items/62b9bab0455ed0f47d19

「Javaのようにそれぞれ役割がクラスごとに分かれていたほうが、バグが起こりにくいんじゃない？Rubyってもしかして微妙？」とおもわれるかもしれませんが、そこにはダックタイピングというものが深くかかわっています。

## ダックタイピング
ダックタイピングとは、
>"If it walks like a duck and quacks like a duck, it must be a duck"
>（もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである）

このように説明されています。文章でいわれてもよく分からないとおもいますので、実際にコードをみていきましょう。
```
class Human
  def say; p "おはよう!"; end
end

class Dog
  def say; p "ワン！"; end
end

def greeting(animal)
  puts animal.say
end

greeting(Human.new)
greeting(Dog.new)
```
上記のコードで注目すべきなのは、```greetingメソッド```の引数であるanimalが```sayメソッド```を参照できることを期待しているんですね。そしてsayメソッドが参照できるのなら、レシーバであるオブジェクトは何でも良い、ということなんです。
これが「もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである」という言葉の意味なんです。

## ダックタイピングが使えそうな例
ある清掃会社があって、清掃員は床をぴかぴかにし、マネージャーはキレイになっているかをチェックする仕事をしています。
その際にこのように書くことで、スッキリ書くことができます。
```
class Staff
  def kiai
    p 'きれいにするよ！'
  end
end

class Manager
  def kiai
    p 'チェックするよ！'
  end
end

def work(person)
  p person.kiai
end

work(Staff.new)
work(Manager.new)
```

以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

https://pbgreen.hatenadiary.org/entry/20111016/1318782503

https://qiita.com/shimgo/items/9d9fbab1e3a7c4343f7b

https://madogiwa0124.hatenablog.com/entry/2018/01/31/222612
Laravel用語まとめ

## ライフサイクル
Laravelアプリケーションにおける、HTTPリクエストからHTTPレスポンス返却までの流れ
![lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278263/0d4a85c7-5abe-7e84-e91b-0927989f7169.png)


### エントリポイント
エントリポイントは、Laravelアプリケーションの起点となります。
### HTTPカーネル
HTTPカーネルでは、アプリケーションのセットアップやミドルウェアの設定を行い、ルータを実行します。
### ルータ
ルータでは、定義されたルートの中からRequestにマッチするルートを探して、ルートに定義されたコントローラやアクションクラス、クロージャといったアプリケーションコードを実行します。
### ミドルウェア
ミドルウェアでは、ルートで指定された処理を実行する前後に任意の処理を実行可能です。
### コントローラ
コントローラではHTTPリクエストに対応する処理を実行します。

---

## サービスコンテナ
サービスコンテナはLaravelフレームワーク内におけるインスタンス管理の役割を担っている。
### バインド
サービスコンテナに対してインスタンスの生成方法を登録する処理。
### 解決
指定されたインスタンスをサービスコンテナが生成し返すこと。
### ファサード
ファサードは、クラスメソッド形式でフレームワークの機能を簡単に利用できるもの。

---

## サービスプロバイダ
サービスプロバイダは、サービスコンテナっへのバインド処理で利用する機能

サービスプロバイダの役割
1. サービスコンテナへのバインド
1. イベントリスナーやミドルウェア、ルーティングの登録
1. 外部コンポーネントを組み込む

---

## コントラクト
コントラクトとは、Laravelのコアコンポーネントで利用されている関数をインターフェースとして定義したもの。
逆引きdockerメモ


Dockerで調べたことをすぐ忘れてしまうので調べたリンクなどをまとめておく
コマンド例などはバージョンアップで変更・廃止になるので最新はリンクで確認すること

## docker-composeでOS再起動してもコンテナを動かしたい時

docker-compose.yamlで”restert”のポリシーを設定する。

https://docs.docker.jp/config/container/start-containers-automatically.html
[GAS] スプレッドシートの特定の列における、「値のある一番下の行数」を取得する関数

# やりたいこと

下記の状態のシートが存在しているときに、「A列で、値のあるセルの最終行数」(つまり `7` )を取得したい。

## パターンA
こういうときはうまくいくのだけれど、
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/16e52722-f6ae-eefb-be79-b4bdff86e9cb.png)

## パターンB

↓ こういうとき(存在する一番の下のセルに値がある場合) に`10` がほしいのに、うまく取れないことがあったので自分メモ。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/eb499bad-a1f8-019d-931d-99f315090879.png)



# ダメな例

パターンA
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/16e52722-f6ae-eefb-be79-b4bdff86e9cb.png)

のときに、`sheet.getLastRow()` だと、そのシート内で値のある最終行数が取得されるので、B8の`8`になります。

```js
function myFunction() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("sheet");
  const lastRow = sheet.getLastRow();

  console.log(lastRow); // -> 8
}
```

# maxRow から上に上がるやり方を知る

やっていることは、「そのシートの、特定の列の一番下(値の有無に関わらず、存在するセルの一番下)から、上に上がってきて(**ctrl+↑ と同じ挙動**) 最初に見つかったセルの行数を取得する」

`sheet.getRange()` の第2引数の `1` がA列のこと。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/16e52722-f6ae-eefb-be79-b4bdff86e9cb.png)

の状態で

```js
function myFunction2() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("sheet");
  const lastRow =sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();

  console.log(lastRow); // -> 7 (A列の最終行。期待通り！)
}
```

を実行すると、A列で値のある一番下の行数である `7` が取れます。

詳しくは [【GAS】1行で書ける！特定列の最終行・特定行の最終列を取得する方法｜もりさんのプログラミング手帳](https://moripro.net/gas-get-specified-lastcol-lastrow/) を参照。

やったね！これで解決だ！！！


...って思ってたよね。しばらくはこれでうまく行っていたよね。


# 問題発生。うまくいかないことがある。

ここで パターンB が出てきます。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/eb499bad-a1f8-019d-931d-99f315090879.png)

この状態で上記の `myFunction2()` を実行すると `7` になります。

なぜならば

>「そのシートの、特定の列の一番下(値の有無に関わらず、存在するセルの一番下)から、上に上がってきて(**ctrl+↑ と同じ挙動**) 最初に見つかったセルの行数を取得する」

からです。つまり、A10を選択して、**ctrl+↑** をすると、A7 に移動するので `7` が取得できます。

でもほしいのは `10` なんです！！！

ってことで、「そのスプレッドシートの最終行に値がある場合、この方法が使えない」ことになります。。。


# ということでこういう関数を作ってみたよ。

sheetと列名を渡すと、その列において値のある最終行数を返してくれる関数を作ってみました。


```js
/**
 * 指定した列で、値の存在する最終行数を返す
 * @param {sheet} sheet 対象のsheetオブジェクト
 * @param {string} col 列を表すアルファベット
 */
function getLastRow(sheet, col) {
  // そのシート内で値のある最終行
  const lastRow = sheet.getLastRow()

  // そのシートの最終行のcol列に値があれば、それが「col列に値がある最終行」
  if (sheet.getRange(`${col}${lastRow}`).getValue()) return lastRow

  // ↑コレじゃない場合は、col列の最終行は「空欄」なので、そこからCtrl↑で取得したのが、「col列に値がある最終行」
  return sheet.getRange(`${col}${sheet.getMaxRows()}`).getNextDataCell(SpreadsheetApp.Direction.UP).getRow()
}

function myFunction3() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("sheet");
  console.log(getLastRow(sheet, "A"));
  console.log(getLastRow(sheet, "B"));
}
```

`myFunction3()` を実行すると、パターンBの時でもAの最終行として`10`、Bの最終行として`8` が出力されます。


やったね！！
Zipkinを用いてSpringBootアプリケーションをトレーシング

# 概要

Zipkinを触ってみたので導入方法をメモしておきます

トレーシング対象のアプリケーションはSpringBootです。

# 導入方法

最小構成で、とりあえず動くところを目指します

## Zipkinサーバ構築

Zipkinサーバを起動します。

```sh
docker run -d -p 9411:9411 openzipkin/zipkin
```

http://localhost:9411/ にアクセスして以下のような画面が表示されればOK！

![スクリーンショット 2022-03-12 14.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/2ee3ee5d-9f5c-5c84-7906-414828ff9f9f.png)

## アプリケーションの実装

依存に`spring-cloud-sleuth-zipkin`と`spring-cloud-starter-sleuth`を含めるようにします

```groovy:guild.gradle
dependencies {
    compileOnly('org.projectlombok:lombok')
    annotationProcessor('org.projectlombok:lombok')

    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-sleuth-zipkin'
    implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
}
```

HTTP通信でRestTemplateを使用します。

Jipkinへ連携するためにはRestTemplateを必ずBean登録する必要があります

```java
@Configuration
public class ApplicationConfiguration {
    @Bean
    public RestTemplate myRestTemplate() {
        return new RestTemplateBuilder()
                .rootUri("http://localhost:8080")
                .build();
    }
}
```

アプリケーション本体は以下の通り。

`/proxy/hello`で受け付けたリクエストを`/hello`にproxyさせるだけのAPIです。

```java
@RestController
@RequiredArgsConstructor
public class SampleController {
    private final RestTemplate restTemplate;

    @GetMapping("/proxy/hello")
    public String proxyToHello() {
        return restTemplate.getForObject("/hello", String.class);
    }

    @GetMapping("/hello")
    public String hello() {
        return "Hello zipkin.";
    }
}
```

最後にpropertyです

```yaml:application.yml
spring:
  zipkin:
    # zipkinサーバのURLを指定
    base-url: "http://localhost:9411/"
    # Zipkinを有効化（デフォルトでも有効）
    enabled: true
    sender:
      # 情報の送信方法を指定
      type: web
  application:
    # アプリケーション名を指定
    name: zipkin-sample
  sleuth:
    sampler:
      # 秒間の送信数
      rate: 10
```

bootRunでアプリケーションを起動して終わり

## 動作確認

それではアプリケーションにリクエストを送信してみます

```sh
$ curl localhost:8080/proxy/hello
Hello zipkin.
```

JipkinのUIで見てみると...

![スクリーンショット 2022-03-12 14.34.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/64727efb-cac1-2e41-356b-9430482bfcdb.png)

🎉🎉🎉🎉

# あとがき

実運用する場合はJipkinでデータの永続化ができるようにとか意識しなければならないことはまだありますが、
とりあえずどんな感じか触ってみるところまでできました。

時間があったらこんなこともしてみたい

- 処理時間が遅いものだけ送信
- 任意の処理をトレーシングしてみる
【Python】JavaScriptレンダリングページからhtmlのtableをスクレイピングする（Playwright→BeautifulSoup4→pandas）

## 目次
[1. はじめに](#1-はじめに)
[2. 環境](#2-環境)
[3. インストールするライブラリ](#3-インストールするライブラリ)
[4. サンプルコード](#4-サンプルコード)
[5. 補足](#5-補足)
[6. 参考にしたサイト](#6-参考にしたサイト)

## 1. はじめに
Pythonのpandasで`read_html()`だけを使いWebスクレピングしてると、必ず邪魔をしてくるJavaScriptレンダリングページ。
そんな時、データ処理はpandasにまかせて、htmlのtableデータ取得はPlaywright、BeautifulSoup4を必要最低限だけ利用してスクレイピングする方法です。

## 2. 環境
- Windows10 Pro：21H2
- Python：3.10.5

## 3. インストールするライブラリ
- playwright：ブラウザ操作（Selenium→puppeteer→Playwrightときて、これが一番安定）
- beautifulsoup4：htmlパーサー
- lxml：htmlパーサー(beautifulsoup4で利用)
- pandas：データ解析ライブラリ
```PowerShell
pip install pandas 
pip install beautifulsoup4
pip install lxml
pip install playwright
playwright install
```

## 4. サンプルコード
- [GitHub](https://github.com/takanori-azegami-jp/python-webscraping-jsrendering)

```python:get_html.py
import pandas as pd
from bs4 import BeautifulSoup
from playwright.sync_api import sync_playwright

# playwright→BeautifulSoup4→pandasでHTMLのtableを読み込む
def get_html(playwright):
 try:
  # playwright
  browser = playwright.chromium.launch()
  context  = browser.new_context()
  page = context.new_page()
  page.goto("https://スクレイピングしたいWebサイトのURL")
  html = page.content()
  # BeautifulSoup4
  soup = BeautifulSoup(html, "lxml")
  tables = soup.find_all("table")
  # pandas
  dfs = pd.read_html(str(tables))

 except:
  #エラー処理を書く（HTTPエラー、tableタグなし等）
  print("Error")

 else:
  # pandasのデータフレーム処理を書く
  print(dfs)

 finally:
  page.close()
  context.close()
  browser.close()

# get_html関数呼び出し
with sync_playwright() as playwright:
  get_html(playwright)
```

## 5. 補足
PuppeteerからPlaywrightに変更し非同期処理をやめたら下記エラーは発生しなくなった

:::note warn
警告
ConnectionResetError: [WinError 10054] 既存の接続はリモート ホストに強制的に切断されました。
:::

## 6. 参考にしたサイト
- [Selenium、BeautifulSoup、およびPandasを使用してJavaScriptWebページからテーブルをスクレイピングする](https://ichi.pro/selenium-beautifulsoup-oyobi-pandas-o-shiyoshite-javascriptweb-pe-ji-kara-te-buru-o-sukureipingu-suru-224107195692542)

- [Python と Playwright でブラウザを自動操作させるコードを自動生成したよ](https://qiita.com/mainy/items/3a9de19f440991f67f34)
Kotlin KoansでKotlin入門　第８回：Lambdas

# はじめに
公式の問題集[「Kotlin Koans」](https://play.kotlinlang.org/koans/overview)を解きながらKotlinを学習します。

過去記事はこちら
- [第０回：Kotlin Koansについて](https://qiita.com/kosuke1/items/41d192af63485bfc8cb8)
- [第１回：Simple Functions](https://qiita.com/kosuke1/items/5862a3ece96082a62e67)
- [第２回：Named arguments](https://qiita.com/kosuke1/items/2af11262852ee41b5da7)
- [第３回：Default arguments](https://qiita.com/kosuke1/items/16cb8ac780df58dc8054)
- [第４回：Triple-quoted strings](https://qiita.com/kosuke1/items/52cfeed2c49b0252d40e)
- [第５回：String templates](https://qiita.com/kosuke1/items/0221bbbc5bc70847be6f)
- [第６回：Nullable types](https://qiita.com/kosuke1/items/aa96e422c5313b6961bc)
- [第７回：Nothing type](https://qiita.com/kosuke1/items/1ca0e48820d58c9dfe16)

# 問題
[Lambdas](https://play.kotlinlang.org/koans/Introduction/Lambdas/Task.kt)

コレクションに偶数が含まれているかどうかをチェックするために、[any関数](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html)にラムダを渡します。any関数は少なくとも1つの要素が指定した条件を満たした場合にtrueを返します。


修正前のコード
```Kotlin
fun containsEven(collection: Collection<Int>): Boolean =
        collection.any { TODO() }
```


# 問題のポイント
Kotlinは関数型プログラミングをサポートしています。Kotlinの[ラムダ](https://kotlinlang.org/docs/lambdas.html?&_ga=2.223798035.986859629.1647058027-406738180.1646311119#lambda-expressions-and-anonymous-functions)について学びます。

ラムダ式の概要
- ラムダ式は、常に中括弧で囲まれています
- パラメータがもしあれば -> の前で宣言されます（パラメータの型を省略してもかまいません）
- 本体が -> に続きます（存在する場合）
- パラメータを1つだけ持つ場合、その宣言を（ -> と一緒に）省略できます。その場合の変数名は、 it になります。


# 解答例
ラムダ式を省略しない形式で解答してみます。
ラムダ式は常に中括弧で囲まれ、完全な構文形式のパラメータ宣言はカッコ内にあり、型注釈を持つことができ、本体（今回だとBooleanを返す処理）は -> 記号の後に置かれます。
```Kotlin
fun containsEven(collection: Collection<Int>): Boolean = 
    collection.any { i: Int -> i % 2 == 0 }
```

次は省略できるところはする形式で解答してみます。パラメータを1つだけ持つ場合、その宣言を（ -> と一緒に）省略できます。その場合の変数名は、 it になります。
```Kotlin
fun containsEven(collection: Collection<Int>): Boolean =
        collection.any { it % 2 == 0 }
```
プロジェクト憲章の必要性を言語化してみる

## モチベーション

最近自身が参加しているPJにおいて、プロジェクト憲章の重要性と必要性を再確認する出来事がありました。
良い機会なので、自分への戒めとして言語化してみました。

## いきなりですが、伝えたいこと

+ プロジェクト憲章は絶対に必要
    + PJ立ち上げ時には必須(プロジェクトを発足させない)、少なくともフェーズから計画フェーズ以降へ進むための必要条件する
        + 以下のプロセスを経て、完了とみなす
            + PJメンバー以外の有識者によるレビュー
            + PJメンバー全員による合意形成

これらを組織のルールに組み込むべき

## 前提

+ ｢事業価値の創造やビジネス戦略を実現し、何かしらのベネフィットを組織にもたらす｣ためのPJを主な対象にする
+ プロジェクト憲章は、PJMやPLによって作成される

## プロジェクト憲章ってなに??

+ PJにおける以下の項目について明文化、視覚化したもの
    + 背景
    + 目的
    + 目標と成功基準(SMARTであること)
        + プロジェクトの終了条件
    + スコープと主要成果物
    + 前提条件(制約やリスク)
        + 人･物･カネ
    + PJメンバーとその役割
        + 権限の範囲
    + マイルストーン(大日程レベルのスケジュール)

## プロジェクト憲章を作成するために必要なインプットは??

+ 事業計画と実現可能性の根拠
    + 売上･利益
    + 費用
    + ビジネスモデル
    + 戦略
        + 母体組織の状況
            + 資産(人･物･カネ･情報(経験やナレッジ))
            + 市場状況や、上位組織の状況

## プロジェクト憲章がない(もしくは、不十分な)状況とは??

+ 情報が不足している
    + 事業計画が曖昧で十分に検討されてない

or

+ PM/PLが情報を把握できてない、もしくは、正しく認識できていない
    + 能力不足(プロジェクト憲章の必要性を認識できていない)
    + 情報アクセスへの権限不足
    + 時間が十分にとれてない

## プロジェクト憲章がない(もしくは、不十分な状況)でプロジェクトを進めた場合

+ 以下が起こりえる可能性が高くなる
    + 目的の誤認
    + 不確実性の増大

## 目的の誤認と不確実性が増大した結果

**望まない未来が実現する可能性が高くなる**

+ 例:
    + 目的の未達成
        + プロジェクトは終わったが、期待したベネフィットが得られない
    + 目標の未達成
        + 計画フェーズ以降での大幅な変更(成果物の変更や追加)や手戻りが発生する
            + PJ中断や大幅な遅延

## じゃあどうするの??

1. プロジェクト憲章は必ず作成する
1. PJメンバー外の有識者によるレビューしてもらう
1. キックオフ
1. PJメンバー全員による合意形成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444225/03583c7d-6ece-5d3d-0a8b-b5c62ea46a1e.png)

## PJメンバー外の有識者によるレビューの必要性

+ ｢早く進めないといけない｣という思いから、内容が不十分でも走り出してしまう可能性がある
    + 悪い誘惑負ける
        + ｢走りながら決めればいいか･･･｣
        + ｢期日優先だし･･･｣
        + ｢周りから進んでないって見られないかな･･･｣
+ そもそも、PM/PLはメンバーの中で一番の有識者であるはずなのでメンバー内でレビューしたところで効果的ではない

## 最後に

冒頭で`｢組織のルールとして組み込むべき｣`と描きましたが意図としては、みんなで`｢プロジェクト憲章は必ず作成する必要だよね｣`って意識と文化を作ることです。 プロジェクトの規模や状況によっては、必ずしも必要無いかもしれません。ただ基本的にはあったほうがいいし、PJオーナー(意思決定者や組織長)にはプロジェクト憲章の必要性と、ない場合に起こりえることについては理解してほしいと思います。
【Minecraft統合版】コマンド解説 〜中級者向けその２〜

統合版Minecraftコマンド解説
今回は中級者向けその２の解説をしていきます。

手打ちしているのでタイプミスや構文ミス、スペルミスがあるかもしれません。その場合はご指摘願えるとありがたいです。

## バージョン情報
・統合版（Windows10版・Switch・PS4）
・ Ver. 1.17.30

## はじめに
コマンドに多く触れてもらうために作成しています。今回は中級者向けの解説をしていきます。あくまで自分の基準で初心者・中級者などを決めています。ご了承ください。初心者向け・中級者向けその１の記事もぜひご覧ください。

[初心者向けコマンド解説](https://qiita.com/soutaisitai/items/6c340e91d5330b138d70　 "初心者向け")
[中級者向けコマンド解説その１](https://qiita.com/soutaisitai/items/c0275d9cef2d569f9774　 "初心者向け")
## 目次
- executeコマンド
- abilityコマンド
- functionコマンド

## executeコマンド
executeとは簡単にいうと「実行する」という意味です。executeコマンドは指定したのエンティティでコマンドを実行することができます。
Java版では多くのことをexecuteコマンドですることができますが、統合版ではできることが限られるコマンドです。

例えば、牛をスポーンさせ、以下のコマンド打つと、牛から牛がスポーンします。
```
execute @e[type=cow] ~ ~ ~ summon cow
```
```execute```はコマンド名、```@e```はターゲットです。詳しくは[こちら](https://qiita.com/soutaisitai/items/6c340e91d5330b138d70 "初心者向けコマンド解説")。 
```~ ~ ~```は相対座標で、指定した（今回の場合は牛）の位置を指しています。 ```~ ~-1 ~```とすると牛の1マス下が指定されます。この際、~と-1の間を開けないようにしてください。
```summon```はエンティティをスポーンさせるコマンドです。
※一応付け加えると「cow」は牛のことです。

これを使うと、いわゆるドラえもんのバイバイン状態にすることができます。
コマンドブロックを使用して、先程のコマンドを入れ、反復・無条件・常にアクティブにし、遅延を50にすると牛から牛が生まれ続け、あっという間にワールドが崩壊します。

誰かに雷を落としたい時も座標をわざわざ特定する必要なく、先程のコマンドの最後、```summon cow```を```summon lightning_bolt```に変えると指定したものに対して雷を落とすことができます。

## abilityコマンド
abilityコマンドはプレイヤーの能力を設定します。
【mayfly】
mayflyはプレイヤーに飛行を許可するかどうかです。これをtrueにするとゲームモード関係なく空を飛ぶことができます。観戦モードなどで使えそうです。falseにすると飛行ができなくなります。trueの状態でも落下ダメージは喰らうので注意が必要です。また、true、falseを指定せずにコマンドを実行すると、現在のabilityが表示されます。
```
ability @a mayfly true
```

【mute】
その名の通り、プレイヤーをチャットで発言できなくできます。使い方はmayflyと同じです。trueにすると発言できなくなり、falseにすると発言できるようになります。
```
ability @a mayfly true
```
## functionコマンド
functionコマンドとは、数多くのコマンドを一度に実行できるコマンドです。
このfunctionコマンドはMinecraft外での作業が多くなります。
構文は簡単で
```
function ファイル名
```
です。つまり、ファイルを作ってそれを呼び出す関数っていうことです。そのファイルは
```.mcfunction```という拡張子で保存します。そのファイルの中に書くのは普段打っているコマンドだけなのでとても簡単です。しかし、このファイルを格納する場所が少し複雑なので、テンプレートを用意しました。
ダウンロードリンク↓
https://www.mediafire.com/file/1b48gx46t0yzbgn/qiita.zip/file
このファイルを解凍し、ウィンドウユーザの方は検索窓に```com.mojang```と入力し、フォルダを検索してください。
開いたらその中に```behavior_packs```というフォルダがあると思うのでそこに解凍したフォルダを入れてください。
入れることができたらマインクラフトを起動し、任意のワールドの設定からビヘイビアパックを選択し、soutaihaというものを有効にしてください。※トップ画面の設定ではなく、ワールドの設定です。
できたらワールドに入り、
```
function qiita
```
と打ってください。
タイトルとチャット欄に文字が表示されれば成功です。

導入ができれば先程のフォルダの中の```functions```を開くと```qiita.mcfunction```というファイルがあると思います。この```qiita```の部分がコマンド名になります。
コードエディタで開くと普段見るコマンドが並んでいると思います。
このようにコマンドを一つにファイルにまとめ、それを実行できるのがfunctionコマンドです。
ミニゲームを作るときは必須なコマンドです。

コマンドブロックを連結させる必要もなく、コマンドブロックの中にfunctionコマンドを書けばそれで多くのコマンドを発動させられるのです。

ファイルを増やしたいときは```qiita.mcfunciton```を複製し、中身を書き換えればokです。

注意したいのはfunctionファイル内で遅延をかけられない点です。

## 最後に
またまた長くなってしまいました。
記事を読んで良いと思ったらLGTMのボタンを押してくれると続編を書く気が起きます。
次回は上級編を書く予定ですが、何を書けばいいのかよくわかっていないので、知りたい情報や既に解決済みだけどなかなか分からなかったことなどをコメントで教えていただけると嬉しいです。
Actix-webとDieselを使ったWEBアプリケーションのAPIサーバ設計のフローをメモる

# 前提
## 開発領域
* WEBアプリケーションのバックエンド（APIサーバーとして）
## 技術
### 言語：Rust
### フレームワーク:Actix-web
### ORM:Diesel

# 本題
## アプリケーションのディレクトリ構成
* main.rs
* models.rs
* handlers.rs
* schema.rs
## APIサーバ製造にあたっての概観
```
テーブル設計
↓
モデル定義
↓
ハンドラー定義
↓
ハンドラー内のビジネスロジック定義
↓
URIとハンドラー関数のマッピング
```

# 最後に
趣味開発ではカチッとした設計をせずに動かしながら改善しているので、手戻りが物凄いです。
手数だけ増えて全然前に進んでいる感じがしないので、メンタル的に全然ヘルシーではないのですが、その分リアルタイムに実行と改善を回せている感覚があってそれはそれで楽しいです。

何度も修正を繰り返していく中で、この経験を抽象化して、どうゆうフローで自分は開発というオペレーションを実行しているのか、と考えたときに、本題にあるようなフローが思い浮かんだので言語化してみました。

基本的に開発フローはどの技術を使っていたとしてもそんなに差異がないものだと思います（あくまで技術は手段なので本質的な構造は普遍的だと思ってます）。

わざわざ書くまでもない分かりきったことですが、忘れっぽいのでメモっときます。
docker secretでdjangoのSECRET_KEYを入れて./manage.py collectstaticする。

お久しぶりでございます。
今回はdjangoのSECRET_KEYをいかにdockerコンテナ内に公開せずにビルドするか四苦八苦して、どうにか環境変数を載せない方法見つけたので紹介したい。
ただshellのところとか個人的に未熟部分なので、ベストプラクティスあれば教えてちょ。

### 導入部分
dockerのコンテナ内でENVって使う機会多いと思いますが、
ただこのENV、セキュア的に公開できる情報のみしかdockerfileには保存できないと思うんですね。

```dockerfile:Dockerfile
#alpine使うことが多い
FROM alpine:3.15 
ENV hogehoge=fuga

/ # env
hogehoge=fuga

#貴様みているな！

```

そのまんま書き込むやつはいねーよとツッコミきそうですが・・・。まぁ、待てや。

### ではどうするか

最初思いついたのは、k8sのようにsecretとかないのかなと思ったら、dockerコマンドのsecretが使えるということを[ここ](https://developer.feedforce.jp/entry/2021/03/15/102530){:target="_blank"}で詳しく書いていただけていたので、参考にさせていただきました。

準備するのは、dockerfileと.envとshellファイル、できればdocker engineは最新のものにしておいてね？

以下のディレクトリに置いておきました。

+ /directory
    + .env
    + Dockerfile
    + build.sh

##### .env

```.env
DJANGO_SECRET_KEY=hogehoge

```

##### build.sh

build用のシェル

```bash:build.sh
#!/usr/bin/env bash

cd "$(dirname $0)" || exit

image_name=test/test-django
image_tag=1.0
container_name=test-django

# ここでenvファイルを一時的な環境変数にしている。source .envで動きそうだが、試したらダメだった。
export $(cat .env || grep -v ^# | xargs)

# --secretというのが今回の重要なポイント
docker build . --progress=plain --secret id=django_env,env=DJANGO_SECRET_KEY --ssh default -t ${image_name}:${image_tag} -f directory/Dockerfile
docker tag ${image_name}:${image_tag} ${image_name}:latest

```

##### Dockerfile


```docker:Dockerfile

FROM alpine:3.15

#　省略　django入れて

#　このRUNの間DJANGO_SECRET_KEYは使える
RUN --mount=type=secret,id=django_env export DJANGO_SECRET_KEY=$(cat /run/secrets/django_env) \
    && python3 ./manage.py collectstatic --noinput --settings=test-django.settings

```

一応、このコードでできる、はず。（若干コードを省略しているので、うまくやっていただければ！）

Dockerfileとdockerコマンドでid=django_env　が使うところのキーとなっている、そしてrunディレクトリのsecretsの中にdjango_envという一時ファイルが一時的にできるようだ。
（一応、コンテナ内で確認した。）

Dockerfileもそうだが、build.shとかわざわざexportして渡している点お気づきかもしれないが、

### もうすこしスマートな書き方あるんじゃない？

安心してください。
### 私もTOTEMO思っている。


個人的には、```export DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY```ぐらいで終わりたかった。

なかなか思った通りにならず何度かやりつつ、今の完成形（私の中での）ができる。


#### 終わりに
ここ一年ISMS、PMS関連でセキュアなことに関わってきたが、こんなにも漏洩リスクや漏洩予防する技術があるんだなとOJTを通して勉強できる現職には感謝している。
ベンチャーでもISMSにちかいシステムを構築しておいてもいいかもね？と日々思います。
個人的にとってもきらいなExcelシート

こういうシート。
きらいなExcelのお手本みたいなものを見つけたのでメモ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2593011/6846ad67-a6c8-a8e5-2a01-92ef6c1799cf.png)
https://cio.go.jp/sites/default/files/uploads/documents/digital/20211026_news_local_governments_01.pdf

・1セル1データじゃない
・データ統計時に無視されるフォントの色付け
・評価した点に情報詰め込みすぎ、ぱっと見てわからん

というわけで個人的にすきなシートはこうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2593011/9f6e1519-2ed5-d7e7-2367-18bbbd2f01b6.png)

・データとしてはみ出す情報は備考に書く
・評価した点をデータ列化する（今回はもちろんてきとうです）
・テーブル化してスライサー

こうすると、「評価した点」列をウーンとにらめっこしなくても、スライサーでぽいぽい統計して判断できるというわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2593011/7789a3fd-e326-9e8a-1866-1b86d3d37a98.png)
団体規模列でフィルタ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2593011/4e7164f6-764b-10a1-dd72-642f3f741e96.png)
システム列でフィルタ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2593011/d1b30268-f258-e6db-5c3e-924743acaff1.png)
コスト列でフィルタ

この方法を覚えると、データが何百行となったときに地味に時短になります。

今回のExcelファイルはこちらからダウンロードできます。
https://www.mediafire.com/file/g13qmsjp66qay2o/Book1.xlsx/file
Node.jsとは【個人的なお勉強アウトプット】

# Node.jsとは
javascriptの実行環境。
javascriptは元々実行環境がブラウザ（クライアント）だった。
パソコン（OS等の中枢）にはアクセスできない。
なぜなら、ユーザーがブラウザからパソコンにアクセスできると、良くないことが多いから。
(GoogleのWeb会議ツールmeet等、ブラウザからカメラやマイクを使う時はダイアログを表示してOSへのアクセスをユーザーに選択させているから安心。)
そんなブラウザ上でしか動かなかったjavascriptをパソコン上で動かせるようにしてくれるのがNode.js。

# なぜみんなNode.jsをつかっているのか
## Babelを動かす実行環境として
javascriptは人口も多く若い層も多く進化がめざましい。
ES2015やTypeScriptなど新しい書き方もでてきてる。
ただ、javascriptの進化にブラウザがついていけず、ブラウザでは動かないことがある。
そのためBabelというコンパイルツールをつかってES2015やTypeScriptを旧法にコンパイルしてブラウザで動くようにしてくれる。
Babelの実行環境に必要なのがnode.js。

## 効率の良いWebサーバーとして
また、Node.jsは大量の同時接続をさばけるようなネットワークアプリケーションを構築することを目的として設計されたらしい。
なのでWebサーバーとしてWebアプリケーションの処理を担当するのにも効率が良い。
ただし、足りないところもあるので、Apachやnginxと組み合わせる構成も多い。

## 効率の良い開発環境作成のため
webpackやSasのcss変換等など、開発環境をより効率化できるツールがたくさんある。

# 補足：npmとは
node.jsで使えるライブラリやフレームワークの管理ツール。
コマンドだけで設定したものをまとめてインストールできる。

# 参考、引用記事
https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb
ドットインストールでCSS レスポンシブウェブデザイン編をやってみた

# ドットインストールCSS レスポンシブウェブデザイン編です
要点だけまとめてみたので、後で振り返り用としておきます

### レスポンシブウェブデザインとは
ブラウザ幅に合わせてレイアウトを変えていくためのテクニック

- viewport
日本語に訳すと「表示領域」という言葉が分かりやすい
メタタグのviewportを対応させたいブラウザに変更させる

- Media Queries
表示された画面環境に応じて適用するスタイルを切り替える機能
viewportの幅ごとにスタイルを指定いく

- ブレイクポイント
スタイルが切り替わるときの、viewportの幅をブレイクポイントと呼ぶ 

:::note
全てのブレイクポイントにメディアクエリの記述を入れると大変なので
一番最初に切り替わる前を共通とし、途中のブレイクポイントの記述は入れ、
最後のブレイクポイント以降をまた共通と考える
（自分の解釈なので分かりづらかったらすみません）
:::
【ラビットチャレンジ】応用数学

## 線形代数

#### スカラーとベクトル
- スカラー
    - いわゆる普通の数
    - 四則演算ができる
    - ベクトルに対する係数になれる
- ベクトル
    - 大きさと向きを持つ
    - 矢印で図示される
    - スカラーとセットで表示される

#### 行列
- 行列の基本
    - スカラーを表にしたもの
    - ベクトルを並べたもの
    - ベクトルの変換ができる

```math
{\begin{pmatrix}
1 & 2 & 3 \\
3 & 2 & 1
\end{pmatrix}
}
```

- 行列とベクトルの積

```math
{\begin{pmatrix}
6 & 4 \\
3 & 5
\end{pmatrix}
\begin{pmatrix}
1 \\ 2
\end{pmatrix}
=
\begin{pmatrix}
(6×1)+(4×2) \\
(3×1)+(5×2)
\end{pmatrix}
=
\begin{pmatrix}
14 \\ 13
\end{pmatrix}
}
```

- 行列と行列の積

```math
{\begin{pmatrix}
2 & 1 \\
4 & 1
\end{pmatrix}
\begin{pmatrix}
1 & 3 \\
3 & 1
\end{pmatrix}
=
\begin{pmatrix}
(2×1)+(1×3) & (2×3)+(1×1)\\
(4×1)+(1×3) & (4×3)+(1×1)
\end{pmatrix}
=
\begin{pmatrix}
5 & 5 \\
7 & 13
\end{pmatrix}
}
```

- 単位行列

対角成分が1
それ以外が0の行列

```math
{\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{pmatrix}
}
```

#### 固有値と固有ベクトル
ある行列Aに対して、以下の式を考える。

```math
A\vec{x} = λ\vec{x}
```

行列Aとベクトル$\vec{x}$の積は、スカラーλとベクトル$\vec{x}$との積と同じ値になる。
ベクトル$\vec{x}$を行列Aに対する固有ベクトル、
係数λを行列Aに対する固有値という。

固有値固有ベクトルの例

```math
{\begin{pmatrix}
1 & 4 \\
2 & 3
\end{pmatrix}
\begin{pmatrix}
1 \\ 1
\end{pmatrix}
=
\begin{pmatrix}
5 \\ 5
\end{pmatrix}
=5
\begin{pmatrix}
1\\ 1
\end{pmatrix}
}
```
このとき、

```math
A=
{\begin{pmatrix}
1 & 4 \\
2 & 3
\end{pmatrix},
}
```
```math
𝜆=5,
```
```math
\vec{x}=
{\begin{pmatrix}
1 \\
1
\end{pmatrix}
}
```
となる。
行列Aについて固有値𝜆=5、固有ベクトル$\vec{x}={\begin{pmatrix} 1 \\ 1\end{pmatrix}}$である。

#### 固有値分解

ある実数を正方形にならべて作られた行列A（Aは正方行列）が固有値と固有ベクトルを持つとする。この固有値を対角線上に並べた行列Λ（Λは対角行列：対角線上以外の成分は0）

```math
{Λ = 
\begin{pmatrix}
λ_1 & \\
& λ_2 \\
& & \ddots
\end{pmatrix}
}
```
と、それに対応する固有ベクトルを並べた行列V（Vは正則行列：掛け合わせると単位行列になる）

```math
{V = 
\begin{pmatrix}
\vec{v_1} & \vec{v_1} & \cdots
\end{pmatrix}
}
```
を用意した時、それらは

```math
AV = VΛ
```
と関係付けられる。したがって

```math
A = VΛV^{-1}
```

と変形できる。このように正方形の行列を3つの行列の積に変換することを固有値分解という。この変換によって行列の累乗の計算が容易になる等の利点がある。


## 確率

- 条件付き確率

事象Aが起こっているという条件で事象Bが起きる確率は下記の式のようになる。

```math
P(B|A)=P(B∩A)P(A)
A = VΛV^{-1}
```

- 期待値

変数Xの取りうる値$x_1$,$x_2$,...,$x_n$に対してそれぞれ確率$p_1$,$p_2$,...,$p_n$が定まっているとき、変数$X$を確率変数という。
また、下記のような式を、期待値という。

```math
\sum_{n=1}^{k}x_ip_i
```

- 分散
```math
V(X)=E(X^2)−(E(X))^2
```

- 標準偏差
```math
σ=\sqrt{V(X)}$$
```

- ベルヌーイ分布
```math
P(x|μ)=p^x(1−p)^{(1−x)}
```

- 二項分布
```math
P(x|λ,n)=\frac{n!}{x!(n−x)!}λ^x(1−λ)^{(n−x)}
```

- 正規分布
```math
N(x;μ,σ2)=\frac{1}{\sqrt{2πσ^2}}exp{(-\frac{(x-μ)^2}{2σ^2})}
```

## 情報理論

- 自己情報量

自己情報量$I(x)$に対する確率分布を$P(x)$としたとき

```math
I(x)= -log\bigl(P(x)\bigr)
```


- 平均情報量（シャノンエントロピー）

自己情報量$H(x)$の期待値$E(x)$としたとき

```math
H(x)=E\bigl(I(x)\bigr)= -E\bigl(log\bigl(P (x)\bigr)
\bigr)= -\sum\bigl(P(x)log\bigl(P (x)\bigr)
\bigr)
```

- カルバック・ライブラー ダイバージェンス
同じ事象・確率変数における異なる確率分布P,Qの違いを表す。

```math
D_{KL}(P||Q) = 
E_{X\sim P}\begin{bmatrix}
log\frac{P(x)}{Q(x)}
\end{bmatrix}
=
E_{X\sim P}
\begin{bmatrix}
logP(x)-logQ(x)
\end{bmatrix}
```

- 交差エントロピー
PのエントロピーにPのQに対するKL情報量を足したもの

```math
H(P,Q) = H(P) + D_{KL}(P||Q) \\
H(P,Q) = -E_{X\sim P}  log(Q(x)
AWSロードマップ(S3)

#目次
[1.はじめに](#1-はじめに)
[2.用語](#2-用語)
[3.ドローンでクラウドを利用](#3-ドローンでクラウドを利用)

# 1.はじめに
ドローン✖︎クラウドの記事をよく見るけど、どうゆう仕組みで連携してるのか分からなかったので
[AWSロードマップ](https://qiita.com/KurokawaKouhei/items/4e9aa3b526f3f233bf85 "Qiita Home")で勉強をしたいと思います！
(まずはざっくり覚えて徐々に深堀していく、仕事でAWS少し触ったぐらい)

#### S3とは(クラウド型のオブジェクトストレージ)
- 空き容量を気にしなくていい(使えるのあと何GBとか気にせんでいい)
- データが安全な確率(99.999999999%)
- 使用料は使った分だけで安い
- オブジェクトストレージは、データをファイル単位でなくオブジェクトという単位で扱う
    - オブジェクト -> ID(URI)、メタデータ(データの種類、保存期間など多くの情報を付与できる)

# 2. 用語
![スクリーンショット 2022-03-12 9.47.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2181084/b1081066-0b4e-bb92-bde6-f665912c2da6.png)


#### ストレージクラス
- S3 Standard -> アクセス頻度が高いデータを保存
- S3 Standard-IA -> アクセス頻度が低いデータかつ必要に応じてすぐに取り出せるデータを保存
- S3 Intelligent-Tiring -> アクセスパターンに基づいてコスト効率の高いストレージ階層を自動で選択
- S3 ONEZone-IA -> 一つのAZにデータを保存、存在期間が長くアクセス頻度が低い、重要度の低いデータを保存
- S3 Glacier -> 長期のデータアーカイブ用、データの一部を数分で取り出せる必要がある場合に使用
- S3 Deep Glacier -> 長期のアーカイブ用、ほとんどアクセスする必要がない場合に使用

#### Glacier
- データのアーカイブと長期のバックアップ用の安全・耐久性が高い・抵抗コストのストレージクラス

#### ライフサイクル管理
- オフジェクトをコスト効率の高い方法で保存する為に設定
- バケット内の一定期間が経過したオブジェクトを他のS3バケットに移動、削除できたりする
    - バケット -> オブジェクトを入れておく入れ物

#### バージョニング機能
- オブジェクトの複数のバージョンを管理(AとA + 削除したって印) 
    - 最新オブジェクトバージョン(A) -> オブジェクト削除 -> (A + 削除したって印)
- 削除してしまっても復元可能
    - A+削除したって印 -> 削除したって印を消す -> Aが復活

#### マルチパートアップロード
- 大きいファイルをS3へアップする際の推奨方法
- 細かく分けて送信 -> 全部揃ったら合体
    - パーツを並行して送信でき、失敗しても部分的にやり直せばいい

#### バケットポリシー
- バケット毎にアクセスを制御できる

#### Transfer Acceleration
- クライアントとS3バケット間で長距離転送を安全、高速、簡単に行えるバケットレベルの機能
    - 大陸間で定期的にギガバイトからテラバイト単位のデータを転送する

#### Snowball
- 大量のデータをS3に送る場合、インターネットより早い方法
    - AWSが大容量、高性能なPCを貸してくる -> データをそのPCに入れる -> そのPCをAWSに渡すとS3にデータをあげてくれる

#### 静的ウェブサイトホスティング
- 静的ファイルを公開できる
    - サーバーに、”静的ウェブ”と書かれたhtmlを置いておく
    - だれが上記のサーバーにアクセスしても"静的ウェブ"と見える

#### パブリックアクセス設定
- 誤ってデータを公開してしまうことを防ぐ設定をAWSアカウント全体・バケット毎にできる

#### パブリックブロックアクセス
- バケットやオブジェクトが公に公開されることを防ぐ機能

# 3. ドローンでクラウドを利用
#### S3を絡めると
いつかできるんやろなーって思ってた事([ドローンが自動で飛行し、ソーラーパネル点検、結果をクラウドでAI解析](https://drone-journal.impress.co.jp/docs/special/1184091.html ""))がもうできてた！
ソーラーパネル点検などの場合、
[太陽光発電を導入してから1年経ったら最初の保守点検、最初の保守点検が終わったら、少なくとも4年に1回のペースで点検](https://www.liberal-solution.co.jp/column/?id=1615697597-310851#index_5 "")
らしいのでアクセス低頻度のストレージクラスを選んで、

警備監視の場合、不定期(侵入者の来る頻度)やからIntelligent-Tiringみたいな選び方になるんかな！
マイクラ札幌市データをSwitchで遊ぶときの構築メモ

Plateauデータを利用した、札幌市のworldデータが公開されました。
このデータをつかうことで、リアルな札幌市の街のデータをつかって、Minecraftを遊ぶことができます。

* [札幌市Minecraftワールドデータ](https://ckan.pf-sapporo.jp/dataset/minecraft)

ライセンスはCC-BY4.0の、れっきとしたオープンデータです。

配布はJava版のデータとして公開されているのですが、統合版に変換し、Switchからも遊べるようにしました。

手順とリファレンスを備忘として残します。
Minecraftのバージョンは `1.18.12.01` です。


![Screenshot_20220312-161627.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9928/b39ff7b3-9ef3-21ee-a696-f70a4c3109a8.png)
_子供がSwitchを返してくれないので、仕方なく、僕のスマホから撮影_

## 手順概要
1. データをダウンロードする
1. ja2beで、統合版のデータに変換する
1. ConohaでMinecraft統合版のサーバをたてる
1. ConohaのMinecraftサーバにアップロードする
1. ディレクトリにデータを配置する
1. ownerを変更
1. プロセスの再起動
1. Switchの設定変更と接続

### リファレンス
#### 1: データをダウンロードする
[札幌市Minecraftワールドデータ](https://ckan.pf-sapporo.jp/dataset/minecraft)からデータをダウンロード。

#### 2: ja2beで、統合版のデータに変換する
https://muralnotes.com/mc-world-je-to-be/

TBD: せっかくのオープンデータなので、あとで時間できたら、変換したデータをGithubかどこかにアップロード。

#### 3: ConohaでMinecraft統合版のサーバをたてる
https://www.conoha.jp/vps/function/minecraft/

#### 4: ConohaのMinecraftサーバにアップロードする
CyberduckでもFFFTPでも、好きなものを使えばよろしい。
いきなりroot権限でつながるので注意。`/root`がhome。
https://miya-system-works.com/blog/detail/minecraft-worlddata-transfer/

#### 5: ディレクトリにデータを配置する
↑のURLの手順は、たぶんバージョンが古く、少し間違っている。
ja2beで変換したデータは `/opt/minecraft_be_server_worlds/worlds/Bedrock level`
 に配置する。
treeはこんなかんじ。コンソール経由なのでスクリーンショット。

![スクリーンショット 2022-03-12 11.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9928/c8e0c2b6-934f-1cc6-f26d-e9c2af34571e.png)

#### 6: ownerを変更
ownerがrootになっているはずなので、chown。
```
chown -R minecraft:minecraft /opt/minecraft_be_server_worlds/worlds/Bedrock level
```

#### 7: プロセスの再起動
ConohaのMinecraftコンソールから、Minecraftサーバの停止→起動、を実施。プロセス再起動する。

![スクリーンショット 2022-03-12 11.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9928/dbf43445-6783-a9ce-1250-d25e029b5f36.png)

#### 8: Switchの設定変更と接続
https://kotoyasyou.work/archives/4873

設定変更が終わったら、↑の記事の通り、Switchでマイクラ起動し、Conohaのサーバに接続。

## Note: operator権限の設定
まだやってないけど、たぶんここの手順でできる。

https://shitamachi634.com/minecraft-settings/

## 他の都市は？
この札幌市のデータは、国交省がすすめている[Plateauプロジェクト](https://www.mlit.go.jp/plateau/)のCityGMLデータを、[株式会社MIERUNE](https://www.mierune.co.jp/)がMinecraftの形式に変換したものです。

もし自分が住んでいる地元のデータが欲しかったら、市役所のオープンデータ担当係に要望をだしてみると、もしかしたら配布が始まるかもしれません。
Plateauのデータとしては、東京や横浜、大阪、名古屋なども存在しています。

Plateau対象都市の一覧はこちら: https://www.geospatial.jp/ckan/dataset/plateau
reTerminalで電力測定ボード(ADJTSB01)を動かす

# はじめに

reTerminalで電力測定ボードを使用してみました。

![IMG_0056.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8aae543a-f871-fc28-771d-28efd266fdf7.jpeg)

https://bit-trade-one.co.jp/adjtsb01/

https://shell-mag.com/vol-69/

# reTerminalの初期設定

公式ページのとおりに初期設定を行います。

# 電力測定ボードを動かす

基本的に書籍の内容とおりで動作しました。
出力内容や手順が異なる点を中心に記載します。

## I2Cの動作確認

reTerminalは最初からI2Cが有効化されています。
出力内容が書籍の内容と異なりますが、reTerminalでI2Cが使用されているため、3cと40が出力されれば問題ありません。

```bash
pi@raspberrypi:~ $ sudo i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- UU -- -- -- 3c -- -- -- 
40: 40 -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
```

![出力1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5e611959-7b83-7134-ff2e-a12c13181da0.jpeg)

## gitコマンドのインストール

gitコマンドがインストールされていないため、サンプルプログラムの入手でエラーになります。
gitコマンドをインストールします。

```bash
pi@raspberrypi:~ $ sudo apt install git
```

## 電力測定値をグラフで表示する

![出力2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ac720717-2af6-91d8-034b-980c08541bbb.jpeg)

## 単色有機ELディスプレイの動作を確認する

![出力3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5d837adf-6378-5af8-07b7-226484b92cf3.jpeg)

## 単色有機ELディスプレイに電力測定値を表示する

![出力4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d8f89383-2308-061b-f594-e5cf719faac2.jpeg)

![出力5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1575c3a2-758c-4680-174b-b6a1940815cc.jpeg)

![出力6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/4180e665-3621-fb3f-54a0-dbda15cca150.jpeg)
環境変数をファイルで扱う env-cmd をローカルインストールで利用してみる（-f オプションでの利用）

環境変数を扱うようなパッケージで、[dotenv](https://www.npmjs.com/package/dotenv) などがありますが、自分は使ったことのない「env-cmd」というのを見かけて、それを試してみました。

●env-cmd - npm
　https://www.npmjs.com/package/env-cmd

●toddbluhm/env-cmd: Setting environment variables from a file
　https://github.com/toddbluhm/env-cmd

## サクッと試す
まずは、 `$ npm i env-cmd` というコマンドで env-cmd をローカルインストールします。

そして、ここで Node.js で環境変数を出力する以下のプログラムを動かしてみて、env-cmd を使わなかった場合にデフォルトで読み込める環境変数を確認してみます。以下を nodeコマンドで実行してみると、ご自身の環境の環境変数が出力されると思います。

```javascript
console.log(process.env);
```

それでは、ここから env-cmd を使っていきます。

### env-cmd の -f オプション
[公式の GitHubリポジトリの「Using custom env file path」という項目の部分](https://github.com/toddbluhm/env-cmd#using-custom-env-file-path)に以下の記載があります。
![env-cmd の -f オプション利用](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/0a9383d1-1370-4d85-1ecb-455b9d38228d.png)

今回は、このやり方で試してみます。そのために、以下のようなプログラムを用意してみました。

```javascript:index.js
console.log(process.env.ENV_CMD_TEST1);
console.log(process.env.ENV_CMD_TEST2);
```

今時点だと、nodeコマンドで普通に実行すると「undefined」が出力されます。

ここから、env-cmd を活用していきます。
まずは、環境変数を記載したファイルを準備します。ファイル名は `.env` にして、JavaScript のファイルと同じ階層に置きました。

```bash
# 環境変数2つ
ENV_CMD_TEST1=aaaaaa
ENV_CMD_TEST2=bbbbbb
```

あとは、env-cmdコマンドを使って上記の内容を読み込みつつ、JavaScript のプログラムを実行します。
実行時のコマンドについて、元の記載だと `./node_modules/.bin/env-cmd` となっていた部分は、 `npx env-cmd` にしました。実行するコマンドは、以下となります。

```bash
$ npx env-cmd -f .env node index.js
```

上記を実行すると、先ほどとは異なり以下の出力結果を得ることができました。
![env-cmd のお試し](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9ff88bba-b438-b07d-eae5-02620a0f0615.png)

無事に、.envファイルに記載していた内容を出力できました。

### 公式の「Basic Usage」
公式の「Basic Usage」と書かれた部分があり、基本的な使い方は以下となるようですが、今回はその下にある -fオプションのほうを試してみたくてやってみました。

![公式の「Basic Usage」](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b5ae0665-266b-84e4-1148-e6280a816f7c.png)
現在地の標高を取得する(JavaScript)

# ブラウザ上で現在地の標高を知りたい。
![FE3847C3-1DB9-4FD8-8E07-72576F8091B5_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/8c79bc6f-cfc6-1433-9079-8de669817f4b.jpeg)

すでに標高を知ることができるアプリなどもありますが、オリジナルアプリ作成で
標高データ取得が必要なので調べました。

# GeolocationAPIで現在地の取得
GeolocationAPIはJavaScriptのAPIです。
位置情報、IPアドレス、WiFiなどの情報から現在地を取得します。

```javascript:
function test() {
    navigator.geolocation.getCurrentPosition(test2);
}
```

getCurrentPosition()でデータの取得に成功すると引数のtest2()が実行されます。

```javascript:
function test2(position) {
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
}
```

test2()で緯度軽度の入れ物を用意し、test()で取得したデータを入れます。
緯度軽度の取得だけならここで終了です。


# 国土地理院APIの使用
国土地理院のAPIに緯度軽度を渡すと標高が返ってきます。
返ってくる値はJSONです。

```html:国土地理院API(標高取得)のURL
    http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon={軽度}&lat={緯度}&outtype=JSON
```

### 緯度：36.103543　軽度：140.08531　の例
http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=140.08531&lat=36.103543&outtype=JSON

### 返ってくる値

```javascript:返ってきたJSONデータ
    {"elevation":25.3,"hsrc":"5m\uff08\u30ec\u30fc\u30b6\uff09"}
```



# 取得したJSONデータをパースする

```javascript:
    var jsonAltitude = JSON.parse(text);
    console.log(jsonAltitude.elevation);
```

# パースしたデータをポップアップで表示

```javascript:
//ポップアップ表示
      alert("現在地の標高は" + jsonAltitude.elevation + "mです。" +  "(" + "緯度：" + stringLat + "、経度：" + stringLon + ")")
```


# ブラウザでの実行結果
適当にhtmlを形成します。
![4B86539B-EF2B-4F84-B2BB-C1E0522603E8_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/f4b03ea8-9341-1ffd-8c80-b1a55dffb77f.jpeg)

「標高を取得」ボタンをクリックします。
![5570D4D7-915C-49EC-AC95-0E6F17405C8C_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/9d4da466-9a55-3f3a-9fff-8413fff5a3f4.jpeg)
できました。

# 全てのコード

```javascript:fetchAltitude.js
//GeolocationAPが利用できるか確認
if (navigator.geolocation) {
  test()
} else {
  alert("現在地を取得できませんでした。")
}


function test() {
    navigator.geolocation.getCurrentPosition(test2);
}

function test2(position) {

    //まず現在地の緯度経度を取得する
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;

    //国土地理院API用に有効桁数を合わせる。
    var adjustiveLat = lat + "00";
    var adjustiveLon = lon + "0";

    //文字列に変換
    var stringLat = String(adjustiveLat);
    var stringLon = String(adjustiveLon);

    //国土地理院APIに現在地の緯度経度を渡して、標高を取得する
    const url = 'http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=' + stringLon + '&lat=' + stringLat + '&outtype=JSON';

    console.log(url);

    fetch(url).then(function(response) {
      return response.text();
    }).then(function(text) {
      console.log(text);
      
      //取得したjsonをパース
      var jsonAltitude = JSON.parse(text);
      console.log("標高：" + jsonAltitude.elevation + "m");

      //ポップアップ表示
      alert("現在地の標高は" + jsonAltitude.elevation + "mです。" +  "(" + "緯度：" + stringLat + "、経度：" + stringLon + ")")

    });

}
```
Ubuntu Server 20.04.3 LTS 構築#21 Docker構築（MYSQLのコンテナ作成～データベース作成）

実施日:2022/03/06～

【今回の内容】
MySQLのコンテナ作成

## MySQLのコンテナ作成
1.MySQLコンテナ作成
```
docker run --name mysql-numbers -e MYSQL_ROOT_PASSWORD=rootのPW -e MYSQL_DATABASE=データべーし領域名 -e MYSQL_USER=ユーザー名 -e MYSQL_PASSWORD=ユーザーのPW mysql  --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password
```
2.コンテナの動作確認
```
docker ps -a
```

## MYSQL操作
1.Dockerログイン
```
docker exec -it コンテナ名 bash
```

2.MYSQLへログイン
```
mysql -u root -p
Enter password: 
```

3.データベースの作成
```
CREATE DATABASES データベース名;
```

4.データベースの一覧確認
```
SHOW DATABASES;
```
## 関連項目
[インストール～基本操作迄](https://qiita.com/art22/items/3ba46d56fa7aac70c409)
## 参考サイト様
[･@pugiemonn様](https://qiita.com/pug)
Ubuntu Server 20.04.3 LTS 構築#20 Docker構築（インストール～基本操作迄）

実施日:2022/03/06～09

【今回の内容】
Dockerの導入～基本操作

## Dockerの導入
1.パッケージリストの更新
```
sudo apt-get update
```
2.必要なソフトウェアのインストール
```
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
実行結果として、既に最新バージョンでした。
```

3.Docker公式GPG鍵を追加する
```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

4.Docker本体のインストール
```
sudo apt-get install docker-ce docker-ce-cli containerd.io
```
詳しいインストール方法はGoogle検索や市販の指南書等でご確認ください。

## コンテナの立ち上げ～削除
1.コンテナの立ち上げ
```
docker run --name コンテナ名 -dit ～
-ditは各オプションが合体したもの
-dはバックエンド処理
-iはコンテナにキーボードをつなぐ 
-tは特殊キーを使用可能にする
```

2.コンテナの稼働確認
```
docker ps
実行すると、下記の項目が表示されます。
CONTAINERID IMAGE COMMAND CREATED STATUS PORTS NAMES
STATUSの箇所がUpになっていたら稼働しています。
```
3.コンテナの起動停止
```
docker stop コンテナ名
```

4.コンテナの起動開始
```
docker start コンテナ名
```

5.コンテナの削除
```
docker rm コンテナ名　
※削除前にコンテナが停止していることが条件
```

## イメージ
1.イメージ一覧の表示
```
docker image ls
```

2.イメージの削除
```
docker image rm IMAGE名
又は
docker image rm IMAGE ID 
```

関連項目
[MYSQLのコンテナ作成～データベース作成](https://qiita.com/art22/items/bd007969c58869ba3561)
【TypeScript入門 #8】型宣言ファイルと外部パッケージの型利用

# 概要

オンラインサロン IT_KINGDOM で、typescript について学んだことを備忘録としてメモしていきます。

---

### 学習内容

- 外部で定義された型とは
- d.ts とは

---

### 外部で定義された型とは

- コード開発する際には、通常、自分で定義した型だけでなく、外部で定義された型も用いる。
- 外部パッケージの型を見に行くためには、F12 ボタンでコードジャンプできる。

```typescript: NextPage.tsx
// Next.jsで使われるNextPageは外部で定義された型
const Home: NextPage = () => {
  return (
      <div></div>
  )
}

// NextPageの型では、undefinedは設定されていないため、下記はエラーになる。
const Home: NextPage = () => {
  return undefined;
}
```

```typescript: index.d.ts
/**
 * `Page` type, use it as a guide to create `pages`.
 */
export type NextPage<P = {}, IP = P> = NextComponentType<NextPageContext, IP, P>

```

### .d.ts とは

- 型定義ファイルのこと
- 型定義 NextPage は nodemodules/next/types/index.d.ts ファイルで指定している

# 参考サイト

[IT Kingdom](https://it-kingdom.com/)
グラブルルーレット選択問題（8th Anniversaryキャンペーン）その２

前回、フェス期間内におけるガチャピンモード突入確率を最大化する方法を紹介しました。

・グラブルルーレット選択問題（8th Anniversaryキャンペーン）
https://qiita.com/toqoo/items/f633ea1c0087cecaf130

今回はこの方法を用いて、ゲージ量やフェスまでの日数が様々な状況を想定し、突入確率最大の選択に関する一般的な傾向を調べます。当日の選択肢は以下の３通りが考えられます。

１：ガチャピンルーレット(チャレンジ)
２：ムックルーレット(堅実)
３：ルーレットを選択しない

これらのうち、
戦略A．選択肢が１，２のみの場合
戦略B．選択肢が１，２，３全ての場合

の２パターンで検証を行います。

運営より、次回グラフェスの日程が告知されています。
・3/19~22	新キャラPUのグランデフェス
・3/22~24	PU無しのグランデフェス
※23日は無料100連確定！

今日が3/12であるとし、3/19~22の新キャラPUのグランデフェス期間内にガチャピンモードに突入することを狙います。今日を含めたフェスまでの日数は７日間、新キャラPUフェスの日数は４日間で、合計１１日間あり、以下のように日付をラベル付けします。
3/12 → ラベル0，3/13 → ラベル1，…，3/22 → ラベル11
ラベル0~6はフェス外、ラベル7~10はフェスとなります。

例えば、3/15にゲージ50%の場合は、
・ゲージ50%
・ラベル3
の条件で突入確率を最大化すればよいわけです。

# 戦略A．選択肢が１，２のみの場合
以上を踏まえて、
・ゲージ：0%, 0.5%, …, 99.5%
・ラベル：0, 1, …, 11
の全パターンに対して突入確率の最大化を行います。

### 当日にガチャピンルーレットの場合
横軸がラベル、縦軸がゲージで最大の突入確率をヒートマップで図示すると、以下のようになります。（以下同様）

例）3/15にゲージ50%でガチャピンルーレットを選んだ場合、3/19~22にガチャピンモードに入れる最大確率は、図のgauge50%、day3から0.6（60%）程度であることが分かります。
![Max_Prob_2choices_first_challenge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/f8ed9621-03d1-7cde-5054-827fb933dba2.png)

### 当日にムックルーレットの場合
初日がガチャピンルーレットの場合とかなり似ていますが、よく見ると少し異なります。
![Max_Prob_2choices_first_steady.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/06923e9d-3824-c3a9-9966-12070a600679.png)

### 戦略Aの最大確率
上記の２つのヒートマップから、ゲージ量とラベルの各パターンで高い方を選んで図示すると以下のようになります。
![Max_Prob_2choices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/11ca6e9d-6802-42f8-585d-35d9cd86e8fa.png)

### 戦略Aの最適選択
初日の選択がガチャピンルーレット、ムックルーレットのうち、最大確率の高い方をパターン毎に図示すると以下のようになります。

例）3/15にゲージ50%の場合、ムックモードを選んだ方がフェス中突入確率が高くなります。
![Best_Select_2choices_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/2a1265ca-ac36-cecc-d1bb-f1530fb5d589.png)


# 戦略B．選択肢が１，２，３全ての場合
続いて、ルーレットを選ばない選択肢を加えた場合についても同様に検証します。
### 当日にガチャピンルーレットの場合
![Max_Prob_3choices_first_challenge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/eea7a54e-b4b3-ad29-7ca1-495999a2a84b.png)

### 当日にムックルーレットの場合
![Max_Prob_3choices_first_steady.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/5f0e5a43-386b-c9c0-70fe-7f09213faa14.png)

### 当日にルーレット未選択の場合
フェス期間中の最大確率が全て0%になっています。
フェス期間中はルーレットを選ばないメリットが無いため最大確率の計算を省略しているからです。（無視して大丈夫です）
![Max_Prob_3choices_first_no_choice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/d618ccb6-75b8-25f9-6f15-2216e77e1c80.png)

### 戦略Bの最大確率
ルーレット未選択が可能な分、ゲージ量100%付近の突入確率がほとんど1となっていることが分かります。
![Max_Prob_3choices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/f31fdfe4-2231-766d-ce52-1ab1087ea519.png)

### 戦略Bの場合の最適選択
ゲージ量が60%を超えると、フェス外でルーレット未選択を続けることで突入確率最大になります。
またこの方法が可能なため、例えばゲージ50%のday0では戦略Aと戦略Bの最適選択が異なります。
![Best_Select_3choices_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2590424/42a2c750-c28c-6142-2d4f-fefcdb09628a.png)

# まとめ
本記事では各ゲージ量とラベル（日付）毎の最適選択を検証しました。実際にはフェス外でガチャを回せるメリットもあるため一概には言えないですが、フェス中のガチャピンモードを最優先したい場合には適宜活用できると思います。
Coil 1.x から Coil 2.x へ移行時に変更したこと

Coil 2.x　が rc-01 から kotlin 1.6.10 に対応しました :tada: 
https://coil-kt.github.io/coil/changelog/#200-rc01-march-2-2022

これを気に Coil を 1.x から 2.x に Update してみたわけですが、多少変更が必要な箇所があったので備忘録を兼ねて記載します

## 関数名の変更

以下の関数名の変更がなされています。必要に応じて変えましょう。

- `loadAny` -> `load`
- `clear` -> `dispose`

## OkHttpのDiskCacheは非推奨に

Coil に DiskCache が実装されたのでこれを使いましょう。
ちなみに以下で指定しているCacheサイズは [1.x のサイズ](https://github.com/coil-kt/coil/blob/1.x/coil-base/src/main/java/coil/util/Utils.kt#L43)を参考にしています。

```kotlin

    ImageLoader.Builder(context)
        .diskCache(
            DiskCache.Builder()
                .directory(context.cacheDir)
                .maxSizePercent(0.02)
                .minimumMaxSizeBytes(250L * 1024 * 1024)
                .minimumMaxSizeBytes(10L * 1024 * 1024)
                .build()
        )
        .build()
```

## Transformation の interface が変更

key が cacheKey に変更され、 transform 関数の引数が変更されました。
BitmapPool が引数からなくなっているので、素直にBitmapを作って書き換えると良いようです。

```kotlin:変更前
    override suspend fun transform(
        pool: coil.bitmap.BitmapPool,
        input: Bitmap,
        size: Size
    ): Bitmap {
        val output = pool.get(input.width, input.height, input.config)

        // change bitmap

        return output
    }
```
```kotlin:変更後
    override suspend fun transform(input: Bitmap, size: Size): Bitmap {
        val output = createBitmap(
            input.width,
            input.height,
            input.config ?: Bitmap.Config.ARGB_8888
        )

        // change bitmap

        return output
    }
```

これに伴ってか、 BlurTransformation と GrayscaleTransformation が削除されたようです。

> BlurTransformation and GrayscaleTransformation are removed from the library. If you use them, you can copy their code into your project.

1.x の BlurTransformation を Migrate すると以下のようになると思います。

https://gist.github.com/satohu20xx/416b1127ebb96eba6d35a95af80a96d4
NCMBのFramework7用UIコンポーネントを使ってスマホアプリを作る（その3：地図画面と情報一覧画面）

NCMBはmBaaS（mobile Backend as a Serivce）であり、UIは各フレームワークやプログラミング言語で開発する必要があります。しかし、イチからUIを作るのは大変なことです。

そこで最近、色々なUIコンポーネントを作っています。これらは個々に独立しているので、簡単にアプリ内に導入が可能です。今はFramework7向けに作っていますが、以下のようなUIコンポーネントがあります。

- [地図コンポーネント](https://qiita.com/goofmint/items/20d73a3aad5313f2ecd8)
- [お知らせコンポーネント](https://qiita.com/goofmint/items/ede45debc91df4439da5)
- [ギャラリーコンポーネント](https://qiita.com/goofmint/items/07a5bf7d747b99c16589)
- [認証コンポーネント](https://qiita.com/goofmint/items/6dc28141da611426abc4)
- [リスト・詳細コンポーネント](https://qiita.com/goofmint/items/9df40e8d4117716fe073)
- [フォームコンポーネント](https://qiita.com/goofmint/items/df11f566c35f55fce826)
- [スワイパーコンポーネント](https://qiita.com/goofmint/items/d5bfc38a30c4112dc14a)
- [設定画面コンポーネント](https://qiita.com/goofmint/items/053707151e8a3ada5da4)
- [プロフィール画面コンポーネント](https://qiita.com/goofmint/items/f2a01782bc9149f82ffa)
- [情報リスト画面コンポーネント](https://qiita.com/goofmint/items/286c934cd8445915ae31)

今回は実際にこれらのコンポーネントを使ってアプリを開発する方法を紹介します。前回は[認証コンポーネントとリスト・詳細コンポーネントを利用する流れを解説しました](https://qiita.com/goofmint/items/4159ba7e3e5e1069947a)ので、今回は地図画面と情報一覧画面を解説します。

![demo-app (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f94b192e-e53d-f9d0-9964-d3dcafff3bf4.gif)


## 地図画面

![screenshot-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/e0fa4b47-3529-4d3b-2882-05ab9d5fc472.jpeg)


### データのインポート

今回は[store.json](https://raw.githubusercontent.com/NCMBMania/UIComponentApp/main/stores.json)を読み込んで利用します。NCMBの管理画面にて `Store` クラスとしてインポートしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f408964f-331a-7317-66ea-1e021e9bba6f.png)


このデータフォーマットは次のようになっています。

| フィールド名 | 型 |
|------------|------------|
| name | 文字列 |
| geo | 位置情報
| address | 文字列 |
| tel | 文字列 |

後は地図タブを表示するだけで、このデータを表示できます。

## 情報画面

![FireShot Capture 153 - 20220307133148 Information - localhost.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/de7b8163-17ad-5a30-38c8-f6e6da4d6c00.jpeg)

### データの作成

NCMBの管理画面にて `Information` クラスを作成します。そしてフィールドを作成します。

| フィールド名 | 意味 |
|------------|------------|
| label | 一覧に出す名前 |
| color | アイコンの色 |
| icon | Framework7のアイコン名 |
| path | URLまたはFramework7のルーティングパス |

iconはFramework7の他、line/hatebu/feedlyが利用できます。

これもデータを作成するだけで表示できます。

## まとめ

UIコンポーネントを使えば、Framework7とNCMBを使ったリッチなアプリが素早く組み立てられます。個々のHTMLに機能は閉じていますので、カスタマイズする場合も簡単です。ぜひお試しください。

NCMBでは他の言語向けにもUIコンポーネントを提供予定です。皆さんのアプリ開発に役立ててください。

[NCMBMania/UIComponentApp: Framework7向けUIコンポーネントを使ったデモアプリです。](https://github.com/NCMBMania/UIComponentApp)
Riverpod V1~ HookConsumerWidgetに

いつの間にか、`HookConsumerWidget`が目立つようになったと思ったら、`Riverpod v1.0.0
`から`useProvider`が無くなったからなんですね。`Riverpod`は状態管理を行うためのパッケージなので、さらっと変更点を修正。そこまで大規模な実装でなければ、手動でマイグレーションでもいいですが`riverpod_cli`でサクッとマイグレートしましょう。
```
dart pub global activate riverpod_cli
```
プロジェクト内にコンパイルエラーがないか確認後に
```
riverpod migrate
```
実行して下さい。
## 変更前
```main.dart
class App extends HookWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
```
## 変更後
```main.dart
class App extends HookConsumerWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
```
## 変更前
```main.dart
Widget build(BuildContext context) {
    final id = useProvider(selectedFormId);

    return useProvider(form(id)).when(
```
## 変更後
```main.dart
 Widget build(BuildContext context, WidgetRef ref) {
    final id = ref.watch(selectedFormId);

    return ref.watch(form(id)).when(
```

## 変更前
```main.dart
return HookBuilder(
              builder: (context) {
                final form = useProvider(
```
## 変更後
```main.dart
 return HookConsumer(
                  builder: (context, ref, child) {
                    final form = ref.watch(

```