OmniAICreator/Qiita-1.07M huggingface dataset:
クラウド分析ツールとのAPI統合

[Teradata Vantage™ - API Integration Guide for Cloud Machine Learning](https://docs.teradata.com/r/Teradata-VantageTM-API-Integration-Guide-for-Cloud-Machine-Learning/April-2022) [リリース日：2022/8　リリースバージョン：1.1]の内容をもとに作成しています。

> Vantageアナリティクス シリーズのコンテンツです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Lyp9N6nlDG8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

:::note information
各機能の詳細な説明に関しては、段階的にリンクを追加していきますので、リンクから詳細ページを参照してご利用下さい。
:::

# クラウド分析ツールとのAPI統合とは？
1. API_Request 関数により、これにより分析サービスのエンドポイントにアクセスします。
2. 現在は、Amazon SageMaker、Amazon Forcast、Azure Machine Learningに対応しています。
3. SQLからリクエストを行い、SQLの結果としてスコアリングされた値を受け取ることができます。
4. teradatamlを使うことによりpythonからも利用することができます。
5. 結果としてデータベースについなるBIやアプリケーションから分析結果を利用することができます。

<img width="900" alt="クラウド分析ツールとのAPI統合.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740723/1b6881b7-31e2-ff52-4df2-7e6006cb6a59.png">

### 対応しているクラウド分析ツールの一覧
|クラウド分析ツール|説明|
|:-|:-|
|Amazon SageMaker|Teradata は、Amazon SageMaker および Amazon Forecastとの API 統合を導入します。この統合により、顧客は Vantage からこれらの外部サービスにデータを接続し、Python 環境で 1 つの Vantage クエリを使用して分析結果を返すことができます。|
|Amazon Forecast|Teradata は、Amazon Forecastとの API 統合を導入します。この統合により、顧客は Vantage からこれらの外部サービスにデータを接続し、Python 環境で 1 つの Vantage クエリを使用して分析結果を返すことができます   |
|Azure Machine Learing|Azure Machine Learingとの連携により機械学習モデルをトレーニングし、オンラインおよびバッチにてスコアリングするサービスを提供します。この統合により、顧客はオンラインの Azure Machine Learning エンドポイントに接続し、Vantage データを使用してスコアリングすることができます。|


# 実行方法
#### SageMakerの場合

```
SELECT rec_id, output as fraud_risk_score								# 戻り値
FROM  tapidb.API_Request												# API_Request 関数				
(
    ON ( SELECT rec_id, avg_pmt_05_mth,max_utilization_05_mth			# スコアリングの入力データ
               ,times_nsf,credit_util_cur_mth,credit_util_prior_5_mth
               ,credit_util_cur_to_prior_ratio
               ,days_since_lst_pymnt,num_pymnt_lst_7_days,num_pymnt_lst_60_days
               ,num_pur_lst_7_days,num_pur_lst_60_days
               ,tot_pymnt_chnl,last_12m_trans_ct
         FROM NEW_FINANCIAL_TRANS) 
    USING AUTHORIZATION(‘{ “Access_ID”:“XXXXXXXXXXXXX”,					# 認証情報の指定
                                                 "Access_Key":“YYYYYYYYYYYY",
                                                 "Region" : "us-east-2"}')
    API_TYPE(‘aws-sagemaker’) 											# API連携する分析サービス
    ENDPOINT(‘sagemaker-xgboost-2021-10-20-15-43-44-623’) 				# エンドポイントの指定
    CONTENT_TYPE(‘csv’) 												# 入力データの形式指定
    KEY_START_INDEX(‘1’) 												# 入力データの開始カラム位置の指定
) as "DT"
```

## おわりに
:::note warn
警告
この本書はWEB上で公開されております[Teradata Vantageドキュメンテーション](https://docs.teradata.com/)よりトピックに必要な情報を抜粋したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
:::

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
【JavaScript】既存のリストを編集する方法(ToDoList)

## はじめに
JavaScriptでToDoListを作った際に、あまり参考にできる記事が見つからず、難しかったと感じたコードについて記事を書いてみました。良かったら参考にしてみてください！

## 解説
作成した既存のリストの編集ボタンを押すと文字がフォームに変わってその場で編集できるようにしてみます！さらには編集時には既存のボタンを削除し、保存ボタンにして編集内容が保存されるようにします。

#### index.js
```javascript
// 編集ボタンクリック
const editTask = (id) => {
  const currentList = todos.find((todo) => {
    return todo.id === id;
  });

  const listParentNode = document.getElementById(`div-${id}`);
  // ここでのdiv-${id}はのちに作成した親要素のidのvalueです。

  // 子要素取得
  const text = listParentNode.children[1];
  const editBtn = listParentNode.children[2];
  const deleteBtn = listParentNode.children[3];

  const editForm = document.createElement("input");
  // 下記のコードは編集時に既存の文を残すためにあります。
  editForm.value = text.innerText;
  editForm.className = "text"
  listParentNode.replaceChild(editForm, text);

  const addBtn = document.createElement("button");
  addBtn.innerText = "保存";
  addBtn.className = "btn";
  listParentNode.appendChild(addBtn);

  // 下記のコードは既存のボタンを一時的になくすものです。後に出てくるstyle.displayを"block"にすることで元に戻すことができます。
  editBtn.style.display = "none";
  deleteBtn.style.display = "none";

  // 保存ボタンクリック
  addBtn.addEventListener("click", () => {
    if(editForm.value) {
      currentList.value = editForm.value;

      const newText = document.createElement("li");
      newText.innerText = currentList.value;
      newText.className = "text";

      listParentNode.replaceChild(newText, editForm);
      // 保存した後は既存のボタンを元通りに戻します。最後に保存ボタンを削除します。
      editBtn.style.display = "block";
      deleteBtn.style.display = "block";
      listParentNode.removeChild(addBtn);
    };
  });
}
```
sytle.display プロパティとは、要素の表示に関する CSS の display の参照や更新ができるプロパティです。ボタンクリックで対象要素の 表示/非表示 を切り替えたり、JavaScript で要素を組み立てたりする際に使用できます。
使い方は```対象要素.style.display = "block"```で対象要素が表示されます。
反対に```対象要素.style.display = "none"```で対象要素が非表示になります。
とても便利なものですね！

## 参考記事
- https://magazine.techacademy.jp/magazine/33333
【SwiftUI】タグリストを作成できる便利なライブラリ

# はじめに
1から自作でタグリストを作成するとかなりの労力がかかると思います。
KeyboardKitでお世話になっている[danielsaidi](https://github.com/danielsaidi)さんがタグリストを簡単に実装できるライブラリを公開していたので使ってみました。

# ライブラリ
https://github.com/danielsaidi/TagKit

# 完成形
![Simulator Screen Recording - iPhone 14 Pro - 2022-11-14 at 20.21.13.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/488cf181-2a3a-9823-a0e7-440db6b11856.gif)

# データ
今回はマーベルの映画をタグリストに表示します
```swift
let marvels = ["アイアンマン", "インクレディブル・ハルク", "アイアンマン2", "マイティ・ソー", "キャプテン・アメリカ/ザ・ファースト・アベンジャー", "アベンジャーズ", "アイアンマン3", "マイティ・ソー/ダーク・ワールド", "キャプテン・アメリカ/ウィンター・ソルジャー", "ガーディアンズ・オブ・ギャラクシー", "アベンジャーズ/エイジ・オブ・ウルトロン", "アントマン", "シビル・ウォー/キャプテン・アメリカ", "ドクター・ストレンジ", "ガーディアンズ・オブ・ギャラクシー リミックス", "マイティ・ソー/バトルロイヤル", "スパイダーマン", "ホームカミング", "ブラックパンサー", "アベンジャーズ/インフィニティ・ウォー", "アントマン＆ワスプ", "キャプテン・マーベル", "アベンジャーズ/エンドゲーム", "スパイダーマン ファー・フロム・ホーム", "ブラック・ウィドウ", "シャン・チー/テン・リングスの伝説", "エターナルズ", "スパイダーマン ノーウェイ・ホーム", "ドクター・ストレンジ／マルチバース・オブ・マッドネス", "ソー ラブ・アンド・サンダー", "ブラックパンサー ワカンダ・フォーエバー"]
```

# 実装
```swift
struct ContentView: View {
    @State var fontSize: CGFloat = 15
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                tag
            }
            .navigationTitle("マーベル映画")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                Button {
                    fontSize -= 1
                } label: {
                    Image(systemName: "minus")
                }
                Button {
                    fontSize += 1
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
    }

    var tag: some View {
        TagList(tags: marvels) { marvel in
            Text(marvel)
                .foregroundColor(.blue)
                .font(.system(size: fontSize, weight: .medium))
                .padding(.init(top: 5, leading: 8, bottom: 5, trailing: 8))
                .overlay(.blue, in: RoundedRectangle(cornerRadius: 10).stroke(style: .init(lineWidth: 1)))
        }
    }
}
```

# おわり
SNS開発などする場合はタグリストを使うことが多いと思うので[TagKit](https://github.com/danielsaidi/TagKit)を使ってみてください！
no_stdでrust-analyzerのcargo checkがスタックするときの対処

rust-analyzerで保存時に`cargo check`を回すとき、10秒ほどスタックすることがある。

デフォルトだと`--all-targets`オプションが設定されているので、no_stdなクレートをコンパイルしようとするとエラーが起こることが原因っぽかった。

コマンドラインだと以下のようなエラーが出るので分かりやすい。

```ru
error: language item required, but not found: `eh_personality`
  |
  = note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
  = help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
```

rust-analyzerの場合は、checkOnSave時のコマンドを以下のようにオーバーライドすることでクリアできた。

```json
    "rust-analyzer.checkOnSave.overrideCommand": [
        "cargo",
        "clippy",
        "--workspace",
        "--message-format=json",
    ],
```

参照
https://github.com/rust-lang/rust-analyzer/issues/2142
https://github.com/rust-lang/rust-analyzer/issues/4616
Delta Sharingを用いたDatabricks間のデータ共有

[Share data using the Delta Sharing Databricks\-to\-Databricks protocol \| Databricks on AWS](https://docs.databricks.com/data-sharing/share-data-databricks.html) [2022/11/3時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本書では、[Unity Catalog](https://qiita.com/taka_yayoi/items/15aede468bdca58ec6a3)が有効化されているユーザーであれば、アカウントやクラウドホストに関係なく、任意のDatabricksユーザーとデータをセキュアに共有するために、Databricks間でどのようにDelta Sharingを活用するのかを説明します。

:::note
**注意**
Unity Catalogが有効化されたDatabricksワークスペースにアクセスできないユーザーとどの様にデータを共有するのかを知りたいのであれば、[Share data using the Delta Sharing open sharing protocol](https://docs.databricks.com/data-sharing/share-data-open.html)をご覧ください。データ受信者(Databricksのデータが共有されているユーザーあるいはグループ)である場合には、[Delta Sharingを用いて共有データにアクセスする](https://qiita.com/taka_yayoi/items/f45b77984c3ed4b6a0c0)をご覧ください。
:::

Delta Sharingのイントロダクションと、オープンな共有とDatabricks間共有の比較に関しては、[Delta Sharingによるデータ共有](https://qiita.com/taka_yayoi/items/3a53516c4434c0ee76f0)をご覧ください。

# Databricks間におけるDelta Sharingワークフロー

このセクションでは、Databricks間でのワークフローのハイレベルな概要と、それぞれのステップにおける詳細なドキュメントへのリンクを説明します。

Databricks間Delta Sharingモデルにおいては:

1. データの*受信者*はデータ*提供者*に対して、データ提供者が共有しているデータへのアクセスにデータ受信者(ユーザーあるいはグループ)が使うDatabricksワークスペースにアタッチされているDatabricks Unity Catalogのメタストアユニークな*共有ID*を提供します。

    詳細は、[Step 1: Request the recipient’s sharing identifier](https://docs.databricks.com/data-sharing/create-recipient.html#request-uuid)をご覧ください。

1. データ提供者は、提供者側のUnity Catalogメタストアに*共有*を作成します。この名前付きオブジェクトには、メタストアに登録されているテーブルのコレクションが含まれます。

    詳細は、[Create and manage shares for Delta Sharing](https://docs.databricks.com/data-sharing/create-share.html)をご覧ください。

1. データ提供者は提供者側のUnity Catalogメタストアに受信者オブジェクトを作成します。この名前付きオブジェクトには、共有に含まれるデータにアクセ得するユーザーやグループと、ユーザーやグループが共有へのアクセスに使うワークスペースにアタッチされているUnity Catalogメタストアの共有IDが含まれます。共有IDはセキュアな接続を実現する鍵のIDです。

    詳細は、[Step 2: Create the recipient](https://docs.databricks.com/data-sharing/create-recipient.html#create-recipient-db-to-db)をご覧ください。

1. データ提供者は共有に対する受信者のアクセスを許可します。

    詳細は、[Grant and manage access to Delta Sharing data shares](https://docs.databricks.com/data-sharing/grant-access.html)をご覧ください。

1. 受信者のDatabricksワークスペースで共有を利用できる様になり、ユーザーはData Explorer、Databricks CLI、DatabricksノートブックにおけるSQLコマンドや、Databricks SQLクエリーエディタでアクセスできる様になります。

   共有内のテーブルにアクセするには、メタストア管理者あるいは[権限のあるユーザー](https://docs.databricks.com/data-sharing/read-data-databricks.html#access-data)が共有からカタログを作成する必要があります。そして、そのユーザーあるいは適切な権限が許可されたユーザーが、別のユーザーにUnity Catalogに登録されている他のカタログ、スキーマ、テーブルと同じ様に、カタログやカタログ内のオブジェクトへのアクセスを許可することができます。ここでの大きな違いは、Delta Sharingの共有から作成されるカタログのオブジェクトに対しては読み取りアクセスのみを許可できるということです。

    詳細は、[Read data shared using Databricks\-to\-Databricks Delta Sharing](https://docs.databricks.com/data-sharing/read-data-databricks.html)をご覧ください。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Nuxt3のuseFetch()で2回目以降のapiがスルーされる問題　←こういう事象があるらしい・・・

nuxtについて色々調べている時に見つけた情報。
備忘的に参考サイトを残しておく。

＜参考サイト＞

https://blog.cloud-acct.com/posts/nuxt3-usefetch-cashe/

useFetch()を使用して「server/api」以下にリクエストしている場合

2回目以降のクリックアクションでapiリクエストがスルーされる事象が発生

1回目のカートに入れるボタンは正常に動きます。
が、2回目のクリック時はapiリクエストが無視され、いきなりthen()に処理が移っています。

### キャッシュが原因。useAsyncData()を使おう

上記の問題はuseFetch()が内部で行っているキャッシュが原因で、2回目以降の処理をスルーします。
キャッシュを無効にするオプションはuseAsyncData()にしか用意されていません。
そこで、useAsyncData()のキャッシュ無効オプションを付与してuseFetch()を書き換えます。

initialCache ... falseに設定すると、最初のフェッチでペイロードキャッシュをスキップする。(デフォルトはtrue)
参考: Nuxt 3 - useAsyncData
Inertia.js&ReactでcreateRootを使って警告を回避する

最新版のReact18とInertiaを用いてLaravelとReactを共存させた時、consoleに以下のような警告が出ました。

```
Warning: ReactDOM.render is no longer supported in React 18. 
Use createRoot instead. 
Until you switch to the new API, your app will behave as if it's running React 17. 
Learn more: https://reactjs.org/link/switch-to-createroot
```

自分がこの警告に遭遇したとき、Reactコンポーネントの処理がなぜかページの読み込み時に走らないという問題に悩まされていました。警告に従って適切にコードを変更することで、この問題は解決しました。
公式ドキュメントに従って、以下のように記載しているときにこの警告が発生します。必要な部分は適宜読み替えてください。

```react:resources/js/app.jsx
import React from "react";
import { render } from "react-dom";
import { createInertiaApp } from "@inertiajs/inertia-react";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import Layout from "@/js/components/Layout";

createInertiaApp({
    resolve: (name) =>
        resolvePageComponent(
            `./pages/${name}.jsx`,
            import.meta.glob("./pages/**/*.jsx")
        ),
    setup({ el, App, props }) {
        render(
            <Layout>
                <App {...props} />
            </Layout>,
            el
        );
    },
});

```

[警告先のリンク](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis)に従って、app.jsxを以下のように書き換えます。

```react:resources/js/app.jsx
import React from "react";
import { createRoot } from "react-dom/client";
import { createInertiaApp } from "@inertiajs/inertia-react";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import "@/styles/globals.scss";
import Layout from "@/js/components/Layout";

createInertiaApp({
    resolve: (name) =>
        resolvePageComponent(
            `./pages/${name}.jsx`,
            import.meta.glob("./pages/**/*.jsx")
        ),
    setup({ el, App, props }) {
        createRoot(document.getElementById("app")).render(
            <Layout>
                <App {...props} />
            </Layout>
        );
    },
});

```

これで、警告が現れなくなるはずです。
ちなみに、自分はページの初回読み込み時に、[SyntaxHighlighter](https://github.com/react-syntax-highlighter/react-syntax-highlighter)コンポーネントがなぜか動作せず、困っていました(リロードするとうまく動きました)。上記のように最新版に対応させると、うまく動くようになりました。
【UNIX】背後にある9つの設計哲学とは！？【初心者向け】

# 始めに
UNIX哲学について記載する。
尚、解説時には、以下の3つの形式に分けて解説する。

* what??
* why??
* how??

# UNIX哲学

## what??
UNIXを支え続けている哲学のこと。
以下の9つの定理がある。
①小は美なり
②レバレッジ・ソフトウェア
③一つ一つ仕事
④シェルスクリプト活用
⑤速攻プロトタイプ
⑥対話インタフェース回避
⑦効率性より移植性
⑧フィルタ化
⑨データはテキスト

## why??
UNIX哲学は優れていて、かつ普遍的であるため。

## how??
UNIX哲学の背景にある理由を把握し、適切に活用する。

# ①小は美なり
## what??
小さいソフトウェアは、大きいソフトウェアよりも遥かに優れているという考え方。

## why??
小さいソフトウェアには以下の6つのメリットがあるため。
* 理由が容易。
* 保守が容易。
* マシンリソースに負担をかけない。
* 他のソフトウェアと組み合わせやすい。

### 理解が容易
最小限のアルゴリズムしか含まず、全てが目的の作業に直結しているため、理解が容易。

### 保守が容易
コードが読みやすいと保守が容易。

### マシンリソースに負担をかけない。
* 実行イメージがわずかなメモリしか占有しないことで、メモリの割り当てが容易になり・性能も向上する。
* 消費するディスク容量も小さくなる。

### 他のソフトウェアと組み合わせやすい。
要求の多様性や変化に、柔軟に対応するのが容易になる。
大きなソフトウェアには以下の問題がある。
* 複雑でコードの理解が困難。
* 不足の事態に対応できない。

## how??
ソフトウェアを設計するときは、解決する問題を完全に理解し、小さく設計して、一つの仕事に専念するようにする。
機能が足りない場合は、他のソフトウェアと連携する。

# ②一つ一つ仕事
## what??
1つのソフトウェアには、1つのことをうまくやらせるという考え方。

## why??
* 実行速度の向上
* 問題への理解の確認
* 再利用性の向上

## how??
1つのソフトウェアには1つの仕事を担当させる。
解決すべき問題が大きい場合は、小さく分割して対応する。

# ③速攻プロトタイプ

## what??
できるだけ早くプロトタイプ(試作)に着手するという考え方。

## why??
試行錯誤なしで良いものは作れないため。

## how??
できる限り早くプロトタイプを作成する。
プロトタイプの作成には以下の3つのメリットがある。
* 前提の誤りを早期に発見できる。
* 要件不備により手戻りを減らせる。
* 速いうちから誤りを取り除く作業を始められる。

# ④効率性より移植性
## what??
ソフトウェアの設計において、効率性より移植選を優先するという考え方。

## why??
ソフトウェアの価値を持続させるため。
一つのハードウェアの価値が落ちた際、新しいハードウェアへの移植コストが少なく済むため。

## how??
ハードウェアに依存する部分と、依存しない部分を切り離した設計を行う。
依存しない部分に関しては、再利用しやすい単位でモジュール化する。
移植性のために、コードの最適化に時間をかけないようにする。

# ⑤データはテキスト
## what??
データはデータファイルに保存するという考え方。
コードの移植性のみでなく、データの移植性も重要であり、そのための解がテキストファイルである。

## why??
テキストファイルは万能型であるため。
テキストファイルには以下のメリットがある。
* 人間がデータを直ちに確認でき、修正・開発中のデバッグも容易。
* 別の形式への変換を考慮しなくて良い。

## how??
データはテキストファイルに保存する。
ソフトウェアは、各々テキストファイルを入出力するように設計し、ソフトウェア同士の連携を容易にする。
その際、選択する形式は、他のソフトウェアとの接続性のため、標準的なものにする。

# ⑥レバレッジ・ソフトウェア
ソフトウェアを梃子として利用することで、力を増幅させるという考え方。
そのために、ソフトウェア同士で組み合わせる。

## why???
自分の仕事に他人の成果を取り組むことで、先人の努力をうまく利用して、自分のコードの有用性を格段に高めるため。

## how??
それぞれが単機能で炭化地に集中して小さなソフトウェアを作り、グルー言語で繋げて、大きな仕事を達成する。

# ⑦シェルスクリプト活用

## what??
シェルスクリプトで接着することで、梃子の効果と移植性を高めるという考え方。

## why??
* 自分の仕事に他人の成果を取り組むことで、先人の努力をうまく利用して、自分のコードの有用性を格段に高めるため。
* 多くの人に使われることで、梃子の効果を増幅させるため。

## how??
シェルスクリプトをグルー言語として使用する。

# ⑧対話インタフェース

## what??
基本的に対話的インタフェースを避けるという考え方。
使用すると、ユーザーがそのソフトウェアのユーザーインタフェースの内部に拘束されてしまう。

## why??
対話的インタフェースにすることで以下の問題が発生するため。
* ソフトウェアごとの独自の対話方法を覚える必要がある。
* ソフトウェア同士が対話できなくなる。
* 待ち時間が長くなる。
* 入力部分の解析コードが大きく、見にくくなる。
* 「大は美なり」的なアプローチになる。

## how??
基本的に対話インタフェースは避ける。

# ⑨フィルタ化
## what??
全てのソフトウェアをフィルタとして設計するという考え方。

### フィルタ
入力ストリームをデータとして受け取り、何らかの加工を施し、加工したデータを出力ストリームに送り出すこと。

## why??
コンピュータの仕事であるデータの収集とフィルタリングだけに集中させ、うまくやるため。

## how??
標準入出力を使用し、正しく設計する。
Nuxtで画面リロードする

「location.reload()」を使う。

参考サイト
https://shimer-system.com/blog/archives/639

```
<script>
export default {
// 省略
  methods: {
    update(param1) {
      this.$axios.post(
        `/hogehoge`,
        { param1: param1 }
      ).then( res => {
          location.reload();
      })
    }
  }
}
</script>
```
QGISで都道府県白地図を作る方法

# はじめに
<!---->
都道府県の白地図のシェープファイルが必要だったがネットを探してもなかったので、作った時のメモ。

# 行政区域地図のダウンロード
<!---->
国土数値情報のHPから行政区域地図をダウンロードする。
https://nlftp.mlit.go.jp/ksj/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/a50ca795-5cab-65eb-91cc-611ad6f51eda.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/60f2ec16-7608-54a1-f4cb-831c32428220.png)

# ダウンロードしたファイルをQGISに読み込む
<!---->
ダウンロードしたファイルをドラッグアンドドロップでQGISに読み込む。
この段階では全市区町村の区域が出てしまっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/bfa84230-edd8-3628-c447-a9785824f81c.png)


# 都道府県のみ抽出
<!---->
国土数値情報の行政区域情報は都道府県の境界と市区町村の境界が混在しているので、都道府県のもののみ残して他は削除する。

取り込んだファイルを右クリックし「属性テーブルを開く」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/6207d220-a333-f769-757d-2f04ec252936.png)

1.テーブルウィンドウが開いたらまず左上の鉛筆マークをクリックし、編集モードにする。
2.１～４７が都道府県の境界、それ以下が市区町村の境界情報となっているため、48以降のデータをすべて選択する。
3.削除ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/a5ce35da-7089-0a40-93e7-91a47bea575e.png)

これで都道府県のみの白白地図ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/9280dd34-aaea-639c-bd82-c49b778aecc4.png)
Web3.0 FTX破綻に見える正しいブロックチェーンの正しい理解

先日、FTX破綻し大きな話題になってます。

https://coinpost.jp/?p=407206

このニュースで仮想通貨、ブロックチェーン、NFT、Web３．０は危険というイメージが大きく広がってます。

しかし、ここで大事な事は、ブロックチェーンの仕組みとは関係ない所で今回の問題が起きているという事です。

今回の問題は、預かっていた仮想通貨を勝手に別の事に使っていたという事であって、銀行でもある出来事です。預金を勝手に色々な事に使っていた。仮想通貨に限った話ではありません。

そして、銀行の本来の業務は預金を預かって、適切に運用してお金を増やす事です。

問題は、運用が適切に行われなかったという事です。

ここは適切な規制が行われていなかったので、ある意味、仮想通貨マーケットの問題という事になるかもしれません。

・仮想通貨の問題ではなく、銀行でも起こる

・預金の運用が適切でなかった

・仮想通貨交換所の規制をもっと厳しくするべき

という話です。

 

ただ最も問題なのは、何故、自分のウォレットで管理しないで仮想通貨交換所に置いてたのかという事です。

自分のウォレットで管理しとけば、勝手に運用される事は起きません。

 

というのもWeb3.0でDao・中央分散を信用して、仮想通貨やNFT等を購入されている方々が自分で管理せずに結局、取引所に預けっぱなしで、信用してるっていう事です。

 

NFTにしてもDAOにしても分散型なので、自分で自分の資産を管理・コントロールしなければなりません。

自由の裏には、責任がつきまといます。自由ばかり主張して責任を放棄する事は矛盾です。

しかも、この破綻の例は過去に何度も起きてます。想定する事は容易に出来ると思います。

Web3.0に未来を感じて、NFT等に投資されてる方々は是非、自由を得るには責任が伴うという事を理解して欲しいです。
【VR 】雪世界を作成

## Intro
今週、A-FRAMEという新しいツールを知らせました。
`https://aframe.io/examples/showcase/helloworld/`

自分がVRに対してなイメージは、
特別な有料アプリしか使えない技術でしたが、
普通のPCだけでもVRサイトを作れるのを初めて知りました。

## 企画
A-FRAMEを応用して、雪の世界を作りたいです。
最近は友人が、冬の時青森に行ってみたい話がありました。
ターゲトスポットは青森県立美術館であり奈良美智の作品ー犬です。
![b02ea6f6621cb9ddf0747f6fcf68f696c7090be6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/b244f23a-c291-2479-72cc-6a02f5cf9984.jpeg)
雪を降る時に、犬の頭の上はマカロンみたいな雪が積みます。
しかし、実際に雪が降る時は12月末くらいですから、行けないかもしれません。
![DvnZryiUUAAlUAm.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/91042a36-cc36-944d-5f86-22ff3e69f810.jpeg)
雪世界にあ憧れるため、VR雪世界を作成！

## A-FRAMEについての紹介
A-FRAMEはHTMLに基づき、特にダウンロードいらないフレームワークです。
Webサイトで、多くのテンプレートをのっています。
また、Web VR以外、3Dシーンまたは、応答できるゲームも作れられます。

![截圖 2022-11-14 下午6.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/8e2a8116-bc5e-476c-093b-8e1ca3bf5969.png)
↑moonriderというサンプルは、自分が一番好きなのです。
`https://aframe.io/examples/showcase/moonrider/` 

## 成果物（半製品）の紹介
ゲームのテンプレートがカッコイイと思いましたが、
自分のレベルを含めて考え、
最初にはVRの練習プロジェクトから作りたいと思いました。

現時点の成品は以下となります：
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBKjmqG" data-user="3luulm" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/3luulm/pen/qBKjmqG">
  colorful pops</a> by 3luulm (<a href="https://codepen.io/3luulm">@3luulm</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
↑codepen　プロジェクト

真ん中は1つ赤いcursor丸があります。
cursorをそれぞれのコンポーネントの上に移動しますと、色のかわり、挨拶な文字の現す動きがあります。
また、JavaScriptを応用し、コンポーネントの自動色変更ができています。
さらに、mouseenter と mouseleaveによるeventを設定でき、コンポーネントの色は動きによる変わります。

## Netlifyで公開
`https://melodic-sopapillas-d3ef32.netlify.app/`

## 難しいところ
#### 1. VRバックグラウンドの探しは意外と難しいで
普通にbackgroundで検索しましたら、主にこういう感じの写真が見つけられます↓
![360_F_300239640_0N7DxFH5cejBwKBcbdKxQB1xPn8DMn7D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/8bb18031-9f39-5182-fcd8-c4dfeb385ce7.jpeg)
VRではない場合、綺麗に使えます。
しかし、VRであれば、こういうふうになりました↓
`https://codepen.io/3luulm/pen/OJEgxpb`
全然綺麗ではありません。
こういう遠いところから道を延長してきたバックグラウンドを使えば、
より似合うと思いまう↓
`https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg`
#### 2.動画のembedができていない
写真のassetができていましたが、動画でやってみましたら真っ黒になりました。
HTMLのiframe方法とA-FRAMEのA-VIDEO、両方とも失敗しました。
今まではまだこの問題を解決できていません。
###### 方法1
``` <iframe width="560" height="315" src="動画URL" title="video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>  ```
###### ![截圖 2022-11-15 上午2.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/40c392d8-c99f-4cb0-cde6-56c32b6719a1.png)
方法2
``` <a-video src="#videoplayer" width="16" height="9" position="0 0 -20"></a-video>```
error ${url}: Extracting tar content of undefined failed, the file appears to be corrupt: "ENOENT: no such file or directory,open ${directory} のエラーについて原因を調べた

## TL;DR
同時実行できるリクエスト数が多いと、依存関係をインストール中にパス参照に失敗して `No such file or directory` となってインストールに失敗する。そのために `--network-concurrency` を小さくする（ex. 1、2、４）ことで回避できる
https://yarnpkg.com/configuration/yarnrc

shellの場合
```shell
yarn install --network-concurrency 1
```

yarnrcに記載する場合
```
networkConcurrency: 1
```

デフォルトは１５なので、並行で実行しないことで多少実行時間が遅くなってしまうことには注意。

## なぜこの記事を書くのか
表題のエラーに関する記事は大体２０１７年くらいから議論はされているものの、ちゃんと原因まで抑えた日本語のエラー記事が見当たらなかったのでまとめた感じです。できることなら、エラー原因をきっちり抑えて対処したいので。むしろ、この記事が間違っていたり正しい理由を知ってる方がいましたら、ぜひコメントにてご教授いただけると。

## 原因

https://github.com/yarnpkg/yarn/issues/2629#issuecomment-283691556

この辺の議論が近いかなと。

yarnがインストールする多くのファイルと深いフォルダー構造に対して、同時実行で mkdir/copy 操作を行っているときにインストールが失敗しやすいといったところが原因らしい。

表題の `${directory}` の前に着くコマンドは、パス参照が関わるようなコマンドになるので、今回のような `open`に限らず `chmod` とか `mkdir` コマンドとかが類似するエラーとしてヒットするような気がする。

なので、コード自体の間違いというよりも、yarnの持つ仕様って感じで抑えると良さそう。
pycord ValueError: mutable default <class 'discord.utils._MissingSentinel'> for field name is not allowed: use default_factory

# 本題

Python3.11で以下のようなエラー文が出てpycordが使えない場合があります。

```terminal
ValueError: mutable default <class 'discord.utils._MissingSentinel'> for field name is not allowed: use default_factory
```

この場合、以下のコマンドを実行して最新版のpycordをインストールしてください。

```terminal
pip install git+https://github.com/pycord-development/pycord
```

# 参考文献
https://github.com/Pycord-Development/pycord/issues/1752
Annictの記録したアニメ数をGitHubのプロフィールに載せるサービスを作りました


# はじめに
Githubプロフィール用のバッジを生成するサービスがあります。
例えば、
Qiitaのコントリビューション数や記事数をバッジにするサービス。

https://qiita.com/mikkame/items/f2c60d9caf8a8e38ec50

Zennの記事数をバッジにするサービス。

https://github.com/nikaera/zenn-badge


**偉大な先人たちに感謝…！！**
僕のREADMEに使わせていただくと、こんな感じになります。
![スクリーンショット 2022-11-14 181152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/267b3034-69fa-f646-1b25-a18822b626e0.png)
僕も何かバッジ化するサービスを作りたい。

# Annictとは
アニメ視聴を記録し感想を投稿できるサービスです。

https://annict.com

APIも公開されています。

https://developers.annict.com


# 成果物
Annictの見たアニメやフォロワー数をバッジにするサービスを作りました！！

![スクリーンショット 2022-11-14 181702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/d25b4457-41ab-8afc-f2dd-7abf4352090e.png)

(色々なバッジ)
![スクリーンショット 2022-11-14 184700.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/e4307854-d0b8-3dcf-4870-09e91a810168.png)

(先人と並べるとこんな感じ)
![スクリーンショット 2022-11-14 181718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/aea4f5db-e592-116e-398f-ffc4cc1d1af0.png)

# 使い方

## ざっとURLフォーマットを説明
```
https://annict.penguincabinet.com/?user_id=<user_id>&type=<type>&style=<style>
```
user_idにはAnnictのユーザー名(@を除くURLに記述されているもの)を入れてください。
typeに取得するものを入れます(フォロワー数とか見たアニメ数等)。
styleは[shields.io](https://shields.io)のスタイルのことです。取得されるバッジのデザインに影響を及ぼします。お好みでどうぞ。

## あなたのREADMEにAnnictバッジを追加してみよう

user_idをあなたのAnnict IDに書き換えて使って下さい(PenguinCabinetの部分)。

```markdown


# My Annict watched animes(「見た」アニメ数)
[![My Annict watched animes](https://annict.penguincabinet.com/?user_id=PenguinCabinet&type=watched_count)](https://annict.com/@PenguinCabinet)
# My Annict create at(Annictアカウントを作った日付)
[![My Annict create at](https://annict.penguincabinet.com/?user_id=PenguinCabinet&type=created_at)](https://annict.com/@PenguinCabinet)
# My Annict followers(フォロワー数)
[![My Annict followers](https://annict.penguincabinet.com/?user_id=PenguinCabinet&type=followers_count)](https://annict.com/@PenguinCabinet)
```
これをあなたのGithubのREADMEに記述して完了です！

## その他
typeクエリーを変えると他にも色々バッジにできます。
|typeクエリー|バッジの内容|
|---|---|
|followings_count|フォローしている数|
|followers_count|フォロワー数|
|records_count|記録した全アニメ数|
|wanna_watch_count|「見たい」アニメ数|
|watching_count|「見ている」アニメ数|
|watched_count|「見た」アニメ数|
|on_hold_count|「一時中断した」アニメ数|
|stop_watching_count|「視聴中止した」アニメ数|
|created_at|ユーザー作成日|

# 技術的なお話
## 技術スタック
Google Cloud FunctionsとGoogle Cloud Runを使用しています。
言語はPythonです。
独自ドメインにする関係で、Google Cloud FunctionsからGoogle Cloud Runに変換しています。
## 実装方法
受け取ったクエリーをもとにAnnict APIでデータを取得します。
それを[shields.io](https://shields.io)に送り、バッジを取得しているといった感じです。

現在キャッシュは行っていないですが、トラフィックが増えると迷惑かかりそうなので、状況を見て対応します。

## ソースコードについて

ソースコードを整理したら、OSSにするかもしれないです。

# 終わりに
ご活用いただけると幸いです。
コメントや「使ってみたよ」とコメントくれると、非常に嬉しいです。

…バグもありそうなので、何かあれば教えてください。
Laravel: Controllerのstoreメソッドの引数にはRequestをつけよう

# はじめに

Laravel6を用いて、商品のいいね機能を実装していました。
その際、1時間もつまづいたエラーがありました。


|Too few arguments to function App\Http\Controllers\User\Product\RateController::store(), 1 passed in /var/www/ec_Laravel/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 54 and exactly 2 expected|
|-|


こちらは、「引数が足りていないよ」みたいな感じのエラーでした。

# 修正前コード

```web.php
// 中略
Route::resource('user/product/{product_id}/rate', 'User\Product\RateController', ['only' => ['store', 'update', 'destroy']]);
```

```show.blade.php
<form method="POST" action="{{ route('rate.store', $product->product_id)}}">
    @csrf
        <input type="hidden" name="rate_type" value="1">
        <button type="submit">提出</button>
</form>
```

```RateContoroller.php
public function store($product_id, $request)
{
    // ここでエラーが発生


    Rate::create([
        'rate_type' => $request->rate_type,
        'user_id' => Auth::id(),
        'product_id' => $product_id,
    ]);
    
    return redirect()->back();
}
```

普通に`product_id`と`request`をPOSTメソッドで渡しているんだが？？？

これで1時間ぐらい悩まされました。

# 解決方法

```RateContoroller.php
use Illuminate\Http\Request;

public function store($product_id, Request $request)
{
    Rate::create([
        'rate_type' => $request->rate_type,
        'user_id' => Auth::id(),
        'product_id' => $product_id,
    ]);

    return redirect()->back();
}
```

なんとstoreメソッドの`$request`の前に`Request`をつければ解決できました。

公式ドキュメントをちゃんと読みましょう...


# 参考サイト

https://readouble.com/laravel/6.x/ja/requests.html
psコマンドのプロセスステータスコード（STAT）の意味

知りたい情報が日本語で見つからなかったので簡単にまとめておく。

例えば、

```bash
$ ps f -A
```

次のような項目がでる

```
PID TTY      STAT   TIME COMMAND
  2 ?        S      0:00 [kthreadd]
  3 ?        I<     0:00  \_ [rcu_gp]
```

この「STAT」の部分、`I<`、`Ss`、`S+`など色々あってよくわからん(´・ω・｀)

## STAT

DeepL翻訳

| STAT | 内容 |
|---|---|
| D | 中断できないスリープ (通常は IO) |
| I | アイドルカーネルスレッド |
| R | 実行中または実行可能 (実行キュー上) |
| S | 割り込み可能なスリープ（イベントの完了を待っている状態） |
| T | ジョブ制御信号による停止 |
| t | トレース中にデバッガによって停止されている |
| W | ページング (2.6.xx カーネル以降では無効) |
| X | dead（決して見てはならない） |
| Z | 機能していないゾンビプロセス。終了したがリープされていない|

追加文字

| STAT | 内容 |
|---|---|
| < | 高優先 |
| N | 低優先 |
| L | ページがメモリにロックされている (リアルタイムおよびカスタム IO 用) |
| s | セッションリーダー |
| l | マルチスレッド (NPTL pthreads のように CLONE_THREAD を使用) |
| + | フォアグラウンドプロセスグループにある |


## 結果

よくわからん。

`R`実行中なんだな~
`S`はスリープで待機状態にあるんだな〜
`X`は見られたら死ぬんだな〜
`Z`は機能してないからkillするべきなのかもなぁ〜

`<`は優先度高いんだな〜
`s`はリーダーなんだなぁ〜
`+`は今動かしてるやつか〜

`Ss`はリーダーが寝てる
`S+`は自分が寝てる

`Zs`リーダーがゾンビに？！
みたことないけど

調べなければならないことが多そうだったので今はここでやめた(´・ω・｀)
ESP32: Wifi の使い方

Ubuntu 24.04 上の Arduino IDE 2.3.2 を使いました。
ボードは、 ESP32 Dev Module です。

WiFIClientBasic を開きます。
スケッチ例 -> WiFI -> WiFIClientBasic
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/85ded062-1538-16d5-b518-4559a3b37012.png)



SSID と password を修正

```text
WiFiMulti.addAP("ssid***", "password***");
```

LAN内の、192.168.1.6 で http サーバーが動いているとすると、
host を 192.168.1.6
port を 80
にする。

```text
    const uint16_t port = 80;
//    const char * host = "192.168.1.1"; // ip or dns
 //   const uint16_t port = 1337;
    const char * host = "192.168.1.6"; // ip or dns
```

実行結果

```text
$ cu -l /dev/ttyUSB0 -s 115200
Connected.

WiFi connected
IP address: 
192.168.1.8
Connecting to 192.168.1.6
HTTP/1.1 400 Bad Request
Closing connection.
Waiting 5 seconds before restarting...
Connecting to 192.168.1.6
HTTP/1.1 400 Bad Request
Closing connection.
Waiting 5 seconds before restarting...
Connecting to 192.168.1.6
HTTP/1.1 400 Bad Request
Closing connection.
Waiting 5 seconds before restarting...
```

http サーバーから、Bad Request　が返ってきているのを確認。
gitやLinuxコマンドについて

##### 目次
- [gitとgithubの概念](#gitとgithubの概念)
- [git Revert について](#git-revert-について)
- [grepでファイル内容対照](#grepでファイル内容対照)

##### gitとgithubの概念
（個人の抽象てきな理解、正しい概念はオフィシャルドキュメントを参考ください）
- gitはローカル環境中のファイル管理システム、githubはgitの資材をリモート環境（ネット環境）で保存する為のシステム
![スクリーンショット 2023-01-11 16.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/55b9ffe4-41b3-4c19-cdc9-179b5e6c538f.png)
- gitの機能は簡単に言う、平行世界を作って、同じファイル（特にjava、python、html等のコード）に対して、違うバーシュンとして保存する。
  - gitの中、一つの平行世界をブランチ（branch）と呼ぶ、同じファイルは違うブランチの中では、内容も違う。例えは同じ「A.txt」ファイルとして、各ブランチの中では違う内容を保存している。
![スクリーンショット 2023-01-11 16.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/56b4c021-05f8-5ce1-aec7-3d1bbd5d07e8.png)
  - gitでは、フォルダでファイルの管理範囲を決めっている。例えは、フォルダ「A」をgitで中身のファイルを管理と設定した後、フォルダ「A」外のファイル「E」はgitの管理を受けない。

- gitで同じファイルに対して、わざわざ複数のバージョンを保存する理由は、プログラマーがコードを書く時、過去でどの様な機能を想定したのか？ 本来の意図は何か？ 元のロジックは何なのか？ 誰か何時度の部分のコードを弄ったのか？ この様な詳細な「歴史記録」を残す為、gitでソースコードを管理する。
  - その為、gitは先言った、「平行世界」の他、「歴史記録」と言う機能もある。一つのブランチ中のファイルを修正する時、毎回「今回修正の歴史」をgitに記録させる作業が必要。一つの歴史を一つの「commit」と呼。
![スクリーンショット 2023-01-11 17.50.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/826ba4c6-d408-f1aa-bd0f-36c9bd86030b.png)
  - gitは一つのファイルに対して、複数のブランチを分け、そして各ブランチでは、それぞれの歴史を持っている。
![スクリーンショット 2023-01-12 11.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/e5286528-3cb2-4938-f8fc-70ea0ed1fe9e.png)
- gitには、一つのブランチに、他のブランチからの「歴史記録」を受ける機能がある
  - 簡単に言うと、ターゲットブランチ（受ける側）と合併したいブランチ（提供側）を比較し、合併したいブランチの内容と歴史をターゲットブランチに反映させる。このブランチの合併は「merge」と呼ぶ
![スクリーンショット 2023-01-12 11.22.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/030b5585-e87c-5e38-704f-db13b9b4a2b1.png)
  - ここで注意すべきのは、ブランチをmergeの時、根本的には、二つのブランチの歴史記録が比較される、つまり、たとえ二つブランチのファイル内容が同じたとしても、歴史が違う場合、この二つのブランチの間には差が存在する
![スクリーンショット 2023-01-12 11.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/856007fb-2ea0-18da-4126-eb28633e759c.png)
  - もし同じファイルがどちらのブランチでも編集された場合、この時mergeすると、衝突（conflict）が発生する。この時、どちらの歴史を保存すべきなのかを選ぶ必要が有る
![スクリーンショット 2023-01-12 11.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/db505e28-a6fc-10f5-21e9-623aac31cc39.png)



##### git Revert について
一度「init dev03」Revertされた作業ブランチをpc01ブランチへmerge後、他に「init dev03」含めるブランチをpc01へmergeの時、作業ブランチに対するRevert処理が不要。

##### grepでファイル内容対照
`grep -vwf <fileB> <fileA> | wc -l`
行分けfileA内容をfileB内で検索、fileAのみ存在内容をアウトプット；` | wc -l`を付けと行数だけを表示 [参考URL1](https://blog.51cto.com/yunleyigewei/2852574)  [参考URL2](https://www.cnblogs.com/zclinux/p/14268275.html)  [参考URL3](https://blog.csdn.net/zhuying_linux/article/details/7019132)
今は昔M式というものありけり

# 懐かしのM式
かなり古い本である「LISPの構造」JHON ALLEN著を読み直してました。今でも読みごたえがあります。理論と実装の両面で書かれています。そしてそのLispコードはM式なのです。
![IMG_1099.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/ca5d498c-4371-f35c-f725-02136aef74dd.jpeg)


M式はLispの黎明期に使われたものの、その後S式が主流になり、今ではM式でLispを書くなんてことは、まずありません。しかし、現代においてもM式には存在意義があると私は思っています。そんなことをつらつらと綴ってみたいと思います。

# 見かけも大切
私が小学生の頃に「妖怪人間ベム」というアニメがありました。ちょっと怖い雰囲気。人間の見かけとは大きくかけ離れた獣のような見てくれのベムたち。彼らは見た目はともかくそのハートは人間以上に人間なのでした。「早く人間になりたい！」とベムは悲痛に叫ぶのでした。最近では亀梨和也さん主演の実写ドラマでご覧になった方も多いだろうと思います。


さて、彼らは普段は人間の恰好をして人間世界に紛れ込んでいます。しかし、戦闘場面になるとその能力を出し切るためにその本来の姿に戻ります。およそ人間とはかけ離れたその姿は一般人にはモンスターに見えてしまいます。

で、こじつけっぽいのですが、なんかS式のlispとシチュエーションが似てませんか？　昔ならFortran、今ならPython、Rubyとは大きくかけ離れたそのS式の見かけ。これで敬遠されちゃったんじゃLispも可哀そうというものです。妖怪人間ベロは人間風の恰好をするとカワイイのです。男と女の恋愛においても初対面の印象というのは極めて重要です。ここで相手のハートをつかめないとその後の展開はありません。見かけで損をしないためにはM式の仮面をかぶってPython風を装うという戦略もあるとおもうのですね。

# M式でRuby風を装う
というわけで自作のLispインタプリタコンパイラであるEasy-ISLispにmexpというライブラリが用意してります。あの古風なM式を読み込みS式にして実行するというものです。実行例をご覧ください。

```lisp
Easy-ISLisp Ver2.65
> (import "mexp")
T
> (mexp)
Meta expression translator
M> load["example/foo.m"]
T
M> fact[10]
3628800
M> fib[20]
6765
M> 

example/foo.m
;; M-expression samples

foo[x] <= x+1

fact[n] <= 
    [n=0->1;t->n*fact[n-1]]

fib[n] <=
    [n=0->0;
     n=1->1;
     t->fib[n-1]+fib[n-2]]

```

古いLispをご存知の方にとってはあの懐かしいM式です。まったく知らない若い世代の人にとってはRubyに見えるかもしれません。そう見えたなら作戦成功です。とりあえずカワイイベロちゃんなのです。本性は隠しておきます。


# S式とお友達
さて、ファーストインプレッションで合格点を得た後にじわりじわりとその本来のパワーを見せつけることにします。戦闘モードです。
sexp[fn] でS式に変換してファイルに書き出します。

```
M> sexp["example/foo.m"]
T
M>

```

これによりfoo,lspというファイルが生成されます。ここにはM式から変換されたS式が書き込まれています。フォーマッタで整形すればインデントありのS式のできあがりです。

```lisp
(DEFUN FOO (X) (+ X 1))
(DEFUN FACT (N) (COND ((= N 0) 1) (T (* N (FACT (- N 1))))))
(DEFUN FIB (N) (COND ((= N 0) 0) ((= N 1) 1) (T (+ (FIB (- N 1)) (FIB (- N 2))))))

> (import "formatter")
T
> (formatter "example/foo.lsp")
T
> 

(DEFUN FOO (X) (+ X 1))
(DEFUN FACT (N) (COND ((= N 0) 1) (T (* N (FACT (- N 1))))))
(DEFUN FIB
       (N)
       (COND ((= N 0) 0)
             ((= N 1) 1)
             (T (+ (FIB (- N 1)) (FIB (- N 2))))))
```

大文字になってるのはご愛嬌。

へ～、M式ってこんな風にS式になるんだね、と思ってもらえたらシメタものです。あとはマクロをぶちかますとか、戦闘モードならではの実力を見せつけます。さあ、これでLisp遣いの誕生、なんてことにならないかな。

# ソース
Easy-ISLispはOSSです。コードはここにおいてあります。

https://github.com/sasagawa888/eisl
【わたし、気になります！】偶数丸め

## はじめに
今回は、モブで開発中にチームメンバーがポロッと言った

**「Rubyのroundメソッドのデフォルトって偶数丸めじゃなくて四捨五入だよね？」**

という一言をきっかけに偶数丸めについて調べたことを書き留めておこうと思います。

## 目次
1. 偶数丸めについてのざっくり説明
2. 偶数丸めを使ってみた
3. 偶数丸めで行っている処理
4. 偶数丸めはいつ使う？


## 1. 偶数丸めについてのざっくり説明

偶数丸めとは、端数処理の一種で、処理対象がちょうど半分の値の場合、もっとも近い偶数に丸めるという処理のことを指します。
端数処理で一般的な、四捨五入では`1.5`を小数第一位で丸めると`2`になり、`2.5`を小数第一位で丸めると`3`になりますが、偶数丸めでは、`1.5`を小数第一位で丸めると`2`になり、`2.5`を小数第一位で丸めると`2`になります。

例えば、
`1.5 + 2.5 + 1.5 + 2.5 + 1.5 + 2.5 + 1.5 = 13.5`ですが、
各値を四捨五入して足し算を行うと
`2 + 3 + 2 + 3 + 2 + 3 + 2 = 17`になります。
一方、各値を偶数丸めして足し算を行うと
`2 + 2 + 2 + 2 + 2 + 2 + 2 = 14`になります。



このように、**端数処理を行った結果を更に集計する場合、四捨五入よりも偶数丸めを行った方が、より元の数値を集計した値に近づけることが出来ます。**

## 2. 偶数丸めを使ってみた
先程述べた特徴は、数値が多いほど顕著に現れます。
それを示すために、ランダムな数字100万個の合計値を以下の3つの方法で算出し、結果を比較したいと思います。
・端数処理をせずに合計
・小数第一位を四捨五入して合計
・小数第一位を偶数丸めして合計


なお、今回は私が普段使っているRubyのroundメソッドを使います。
Rubyではroundメソッドのオプションを使って簡単に偶数丸めをすることが出来ます。その他のオプションは[こちら](https://docs.ruby-lang.org/ja/latest/method/Float/i/round.html)。
```ruby:round_method.rb
# 四捨五入
2.5.round(1)   # => 3
2.5.round(half: :even) # => 2
```
<br>

ではやってみます！
```ruby:example_1.rb
# 小数第一位までの数字をランダムに100万個作成し配列に詰める
array = []
1000000.times do
    random_number = rand(1.0..10.0).floor(1)
    array.push(random_number) 
end
# そのまま合計する
pp array.sum 

# 小数第一位を四捨五入したものを合計する
round = array.map{|i|i.round(0)}
pp round.sum 

# 小数第一位を偶数丸めしたものを合計する
round_even = array.map{|i|i.round(half: :even)}
pp round_even.sum 
```

実行結果
```ruby:result.rb
# 元の値をそのまま合計
5449937.5

# 四捨五入
# 端数処理をしない場合との差：50,653.5
5500591 

# 偶数丸め
# 端数処理をしない場合との差：5,862.5
5455800 
```

この結果から、偶数丸めをした結果を集計するほうが、四捨五入をした結果を集計するより、誤差が小さいことが分かったと思います。

<br>

しかし、偶数丸めを使用する場合には少し注意点があります。以下を御覧ください。
```ruby:example_2.rb
array = []
1000000.times do
    random_number = rand(1.0..10.0)
 array.push(random_number) 
end
# そのまま合計する
pp array.sum 

# 小数第一位を四捨五入したものを合計する
round = array.map{|i|i.round(0)}
pp round.sum 

# 小数第一位を偶数丸めしたものを合計する
round_even = array.map{|i|i.round(half: :even)}
pp round_even.sum 
```

結果
```ruby:result.rb
# 元の値をそのまま合計
5504232.324396809

# 四捨五入
5504080

# 偶数丸め
5504080
```
...あ....れ？結果同じやん？
そう、偶数丸めはそう単純ではなかったのです。

## 3. 偶数丸めで行っている処理
偶数丸めで小数n桁に丸める場合、処理は以下のルールに沿って行われます。

1. 小数n+1桁が5でない場合　=> 四捨五入と同様に端数処理を行う
2. 小数nが5である場合
2.1 小数n+2桁以下が「0」に相当しない場合 => 繰り上げ処理を行う
2.2 小数n+2桁**以下が「0」に相当する場合または不明の場合**
　2.2.1 小数n+1桁が偶数 => 切り捨て処理を行う
　2.2.2 小数n+1桁が奇数 => 繰り上げ処理を行う

`example_2`では、`rand(1.0..10.0)`によってランダムに生成された小数15桁の数値において、小数代2位以下がピッタリ0になる確率はかなり低かったため、偶数丸めの良さが全く出なかったということです。（`example_1`ではfloorメソッドを使って小数第二位以下を切り捨てています。）

## 4. 偶数丸めはいつ使う？
偶数丸めは、銀行丸めとも呼ばれ、誤差の累積を嫌った銀行員が好んで使っていたそうです。

しかし、最近では、桁数の多い計算も簡単にできるようになってきたため、端数処理は数字を最終的に整形する時にのみ使用するイメージがあります。
このことから偶数丸めが効力を十分発揮する場面は少なくなっていると思います。

一度整形したデータが、更に集計される場合、かつ、その規模がかなり大きい場合は、偶数丸めを用いる方が有効であるため、偶数丸めを使える場面に出くわしたときには使ってみたいです。
Arduino: ESP32 Dev Module の使い方

Ubuntu 24.04 上の Arduino IDE 2.3.2 を使いました。

ボードを ESP32 Dev Module にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/de7ae54a-30fa-3e55-3cbd-fde8144c2f6f.png)



ファイル -> スケッチ例 -> WiFi -> WiFiScan
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ddcb0d52-74d1-d9a2-0e49-4b1a367cac3d.png)


コンパイルして、ボードにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c4f9333c-0d6c-077c-8c35-c03bb0f66cef.png)



ターミナルで接続します。

```bash
cu -l /dev/ttyUSB0 -s 115200
```

結果

```text
$ cu -l /dev/ttyUSB0 -s 115200
Connected.
scan start
scan done
18 networks found
1: Buffalo-G-7008 (-71)*
2: rs500m-e1caa5-1 (-75)*
3: rs500m-e1caa5-2 (-76)*
4: TP-Link_E2EE (-78)*
5: C0B47DD1BB49-2G (-79)*
6: elecom2g-60f1f1 (-80)*
7: Buffalo-G-37E8 (-87)*
8: Buffalo-G-8E70 (-88)*
9: Buffalo-G-37E8-2 (-88)*
10: aterm-74d308-g (-89)*
11: Buffalo-G-8E70-WPA3 (-89)*
12: shimotsuke-wifi (-90)*
13: Extender-G-3D88 (-91)*
14: Buffalo-G-A3F8 (-91)*
15: Buffalo-G-7008 (-93)*
16: Buffalo-G-1370 (-93)*
17: ssw-wep-639639 (-94)*
18: ssw-pc-639639 (-94)*
```
【PHP】処理速度測定方法　ところでin_arrayってほんとに遅いの？

in_arrayを使うなら、連想配列にしてでもissetを使った方が速いという記事を散見します
可読性のよいin_arrayをできれば使いたいので測定してみました

### 目次
処理速度の測り方
issetとin_array 検索に使うならどっちが速いのか？
issetの測定
in_arrayの測定
測定結果
結論

## 処理速度の測り方
とてもシンプル

```php
// 実行環境 PHP v7.1.8

// 現在時刻をマイクロ秒まで取得
$start = microtime(true);

// --- ここに測定したい処理 ---

$end = microtime(true);

// 指数表記回避にsprintf()で桁数を6に指定
var_dump('XXXを検索 : ' . sprintf("%.6f",($end - $start)) . '秒' );
```

## issetとin_array 検索に使うならどっちが速いのか？
検索用配列をつくる

```php
$arr = [];
for( $i = 0; $i < 100; ++$i ){
  $arr[] = 'TEST' . (string)$i;
}
```

## issetの測定
```php
// issetで'TEST99'を検索
$search = false;
$start = microtime(true);

// issetで検索する場合は連想配列にする必要がある
// キーと値を反転させる
$tmpArr = array_flip($arr);

if(isset($tmpArr['TEST99'])) {
 $search = true;    
}

$end = microtime(true);
```
## in_arrayの測定
```php
// in_arrayで'TEST99'を検索
$search = false;
$start = microtime(true);

if(in_array('TEST99' ,$arr)) {
    $search = true;
};

$end = microtime(true);
```

## 測定結果
in_arrayは遅いのでissetを使った方がいい とよく耳にするが、

連想配列に直す必要がある場合はin_arrayの方が速かった

```php
// 配列の要素数が100

// array_flipで連想配列に
string(37) "issetでTEST99を検索 : 0.000006秒"

string(40) "in_arrayでTEST99を検索 : 0.000002秒"
```
foreachで連想配列に直した場合は、更に遅くなる
```php
// 配列の要素数が100

// foreachで連想配列に
string(37) "issetでTEST99を検索 : 0.000011秒"

string(40) "in_arrayでTEST99を検索 : 0.000002秒"
```

ちなみに、配列の要素が多いほど配列生成のコストが大きくなりin_arrayと差がひらく

```php
// 配列の要素数が10000

// array_flipで連想配列に
string(39) "issetでTEST9999を検索 : 0.000296秒"

string(42) "in_arrayでTEST9999を検索 : 0.000051秒"
```
## 結論
検索は、連想配列に直してissetするならin_arrayの方が速い
【Wagtail】RichTextFieldのHTMLから画像のURLリストを取得する

## 結論
DBのRichTextFieldのHTMLから、最小限のクエリ回数で、imgタグのsrc属性を全件取得したかった。

```python:libs.py
from wagtail.core.rich_text.rewriters import FIND_EMBED_TAG, extract_attrs
from wagtail.images.formats import get_image_format
from wagtail.images.models import Rendition

def get_embed_tag_attrs(html: str) -> List[dict]:
    """ wagtail.core.rich_text.rewriters.EmbedRewriter から一部抜粋 """
    match = FIND_EMBED_TAG.findall(html)
    attrs = [extract_attrs(s) for s in match]
    return attrs

def get_image_url_map(image_ids: Optional[List[int]] = None) -> Dict[tuple, str]:
    """DBアクセスを集約する関数

    Notes
    -----
    - Imageレコードからリレーションをたどらずに、直接Rendtionレコードを取得する。
    - Rendtionレコードのfileカラムではなく、インスタンスのurl属性を呼び出すことで、FQDNを取得する。
    """
    renditions = (
        Rendition.objects.all()
        if image_ids is None
        else Rendition.objects.filter(image_id__in=image_ids)
    )
    return {(r.image_id, r.filter_spec): r.url for r in renditions}

def get_image_urls(html: str) -> List[str]:
    """
    Warnings
    --------
    - 各種レコードが存在しない場合に未対処

    Returns
    -------
    Ex. ["https://xxx.com/media/images/foo.jpg"]
    """
    embed_tag_attrs = get_embed_tag_attrs(html=html)

    image_ids = [int(a["id"]) for a in embed_tag_attrs]
    image_url_map = get_image_url_map(image_ids=image_ids)

    image_urls = []
    for attr in embed_tag_attrs:
        image_format = get_image_format(attr["format"])
        rendition_key = (int(attr["id"]), image_format.filter_spec)
        image_urls.append(image_url_map[rendition_key])

    return image_urls
```

## 背景
Wagtailは、DjangoベースのCMSです。

https://github.com/wagtail/wagtail

個人開発でWagtailを使ったWebメディアを運用していて、そのなかで任意の記事に含まれる、全ての画像を閲覧できるViewer機能を作った際に、本機能が必要になりました。

https://tsuchikei.com

## 詳細
:::note info
wagtail = 2.14.2
:::

前提として、RichTextFieldで`img`タグは`embed`タグとして保存されます。
他にもいくつかのタグは、Wagtailによって変換され、内部表現としてDBに保存されます。
```html
<!-- imgタグの場合 -->
<embed alt="foo" embedtype="image" format="fullwidth" id="1"/>
```

これを適切なHTMLに変換するためには、下記の関数を利用できます。
```python
from wagtail.core.rich_text import expand_db_html

expand_db_html(html)
```

しかし`expand_db_html`は、内部で1つの`img`タグに対して、ImageレコードおよびRenditionレコードの取得でクエリを2回発行しています。
これでは記事内の画像数に比例して、パフォーマンスが悪化してしまうので、対処が必要でした。
```python:wagtail.images.rich_text.__init__.py
class ImageEmbedHandler(EmbedHandler):
    identifier = 'image'

    @staticmethod
    def get_model():
        return get_image_model()

    @classmethod
    def expand_db_attributes(cls, attrs):
        """
        Given a dict of attributes from the <embed> tag, return the real HTML
        representation for use on the front-end.
        """
        try:
            image = cls.get_instance(attrs)  # Imageレコードの取得
        except ObjectDoesNotExist:
            return '<img alt="">'

        image_format = get_image_format(attrs['format'])
        return image_format.image_to_html(image, attrs.get('alt', ''))  # Renditionレコードの取得
```

よりよいやり方がありましたら、コメント等お待ちしております！
【合格記】AWS Certified Solutions Architect - Professional（SAP-C01）

AWS Certified Solutions Architect - Professional（SAP-C01）に滑り込みでギリギリ合格できたので、どんな感じで勉強したかを書き連ねていこうと思います。

**2022/11/15以降はSAP-C02という新しいバージョンの試験が開始され、本記事内の学習方法を利用することが難しい可能性があります。教材がSAP-C02に対応していることを確認してから購入することを強くお勧めします。**

## 前提

- 筆者は非情報系の理系大学院生（修士1年）で、基本的に紙とペンを使う研究がメインなので大学で情報系の授業を取ったことはありません。
    - 強いて言えば、C言語を使った数値計算の授業が半年間ありました（簡単な微分方程式を解いて終わりました）。
- 趣味としてのプログラミング歴は5年ほど、AWS歴は3年ほどです。
    - 収入がカツカツでお金がかかるサービスは使えないため、AWS歴3年と言っても基本的にLambda+DynamoDB+S3のような構成でWEBアプリを作るような遊び方がメインでした。
- プロフェッショナル合格の3ヶ月ほど前にアソシエイトの方を取得しており、その勢いのまま受験しました。
    - というよりは、SAP-C02になると問題が難しくなりそうな印象を受けたため、SAP-C01のうちに受験しておこうという気持ちで短めのスパンで受験することにしました。

以上のように、専門的な教育を受けておらず、また実務でAWSを使用した経験がなくとも問題なく合格できたという経験が参考になれば幸いです。

## やったこと

### 1. [AWS認定資格試験テキスト＆問題集　AWS認定ソリューションアーキテクト - プロフェッショナル](https://amzn.asia/d/8uODKnV)

![41jpsyRR9xL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477136/25bb1a0e-eb51-4d34-4a1d-0d7f7da22e29.jpeg)

まずはこの書籍で学習しました。ぶっちゃけ他の本と比較できていないため、これが1番良いと胸を張って言える訳ではありません。「この本でも十分わかりやすく、問題はなかった」という言い方をしておきます。

知識を完全に脳に定着させるのには、2つ目にやったことの方が効率が良いので、まずはどんな本でも良いので広く浅くぼんやりと覚えるくらいの気持ちで読むのが良いと思います。

効率面で言えば、この本の1つ1つのサービスについては深掘りせず、色々なサービスを紹介してくれる方法はかなり良かったと思います。

### 2. [TechStock](https://techstock.jp/)

WEB問題集です。AWS認定試験に関しては色々な問題集がありますが、以下の条件で選定したところこれに辿り着きました。

- PC、スマホで完全に同期しながら進められる
- 学習の進捗の記録が自動で行われ、間違えた問題のみを復習することができる
- 1問答えるごとに解説が表示され、別ページにある解説を探しに行ったり数問分の解説をまとめて読んだりする必要がない

結論として言えばこれは大当たりで、この問題集の問題とほとんど完全に同じ問題が本番の試験でも多数出題されました。体感では半分くらいが同じ問題でしたが、もう少し少なかったかもしれません。ただ、同じではない問題に関しても類推で解けるようなものが多かったため問題はなかったです。例のごとく、他の問題集を試していないためなんとも言えないですが、直感的にはこれ以上同じ問題が出るような問題集はないだろうという印象で、かなりお勧めできます。

ただ、解説は1問ごとに表示されますが、進捗がサーバーに記録されるのは1セット(7問/だいたい15〜25分)ごとなので、本当にスキマ時間で進められるかは怪しくそこだけは注意です。もちろん、ブラウザのタブを開きっぱなしにしておけば1問ずつ進められるのですが、PCで3問進めて、出先でスマホで続きから4問進めるといった使い方ができないため微妙にストレスになることは注意してください。

個人的には、このデメリットと比較してメリットが余りにも大きすぎるため、受験者全員にお勧めしたいと思っています。

やったことはこの2つだけですが、TechStockは問題数がかなり多いため、これだけで1~2ヶ月くらいは消化することになると思います。

## 結論

難易度は聞いていた通り高かったですが、アソシエイトを合格できる人であれば理解ができなくて躓くことはなく、知識の幅が問われる試験だったので時間さえかければ誰でも合格できそうな印象でした。TechStockを利用すればその時間が圧倒的に短縮できると思います（念のために言っておきますがステマではないです）。

SAP-C02にどのタイミングで対応するかは分かりませんが、TechStockがSAP-C02に対応したら是非これを使って学習を進めてみてください。
デイトラ「Web制作コース」　受講内容をアウトプット 6日目


学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース初級編」
②ゼロからサイトを作ってみよう②
③今日得た新しい知識
　・imgタグのaltには画像が映らない際の文字や読み上げ機能がある場合に読む言葉を入れる
　・親クラスを作ってあげる方が後で編集しやすい。（floatしてるときなど）
　　例：pタグを後で編集するとするとしてpタグを直接floatしてる時などで後からpタグを追加したりすると
　　　　おかしくなるが、親要素にfloatあててると問題なくできる。
　・ustify-content: space-betweenを使用するとwidthで指定した残りの％をうまく調整してくれる。
　　ustify-content: space-aroundだと左右の隙間も考慮する。
　・inputタグ内のplaceholder内の文字がinput内に影文字で表示される
　・inputタグにCSSを当てる際は属性まで指定すると良い。それは属性がe-mailでもtextでも見た目は同じだから。
④メインコンテンツ～フッターまで
⑤特になし
⑥特になし
Ubuntu18.04 LTS インストール後のログインループ解消

ずっとUbuntu16.04 を使っていたが
重い腰を上げてOSのバージョンアップを実施
色々ごちゃごちゃしてたのでさっぱりさせる意味でも
Ubuntu18.04 をクリーンインストール実施


ところが実施後の起動で何度ログインしても
ログイン画面に戻る問題発生:disappointed_relieved:

ググってみると、自分の環境に当てはまるのは
どうやらNVIDIAのドライバ問題のようだ

そういやクリーンインストールしたから、
元々入れてたドライバ消し飛ばしてしまった・・・

### 1. ログイン画面 → 仮想コンソールへ
・[Ctrl] + [Alt] + [F**] ※環境によって色々ある模様
　（自分の環境では[F2]だった） 
・コンソールが出てきたらログイン

### 2. ドライバインストール
本来なら必要なドライバを指定して
インストールするべきなのだと思うが
クリーンインストール後で色々入ってなかったので
以下のコマンドにて一括インストール

```
sudo ubuntu-drivers autoinstall
```

### 3. インストール完了後にドライバ情報確認
```
dpkg -l | grep nvidia
```
または
```
nvidia-smi
```
で、
NVIDIAのドライバがインストールされてれば、
何かしら情報が出てくるはず

### 4. ログイン画面に戻る
・[Ctrl] + [Alt] + [Del]
　※Exitで戻れるという記事も見たが自分の環境ではダメだった…

----
ひとまずこれでログインループは解消できたので、
引き続き必要なものを順次入れていく・・・
Leetcode 200. Number of Islands

# 200. Number of Islands

https://leetcode.com/problems/number-of-islands/

## アプローチ
- BFS


```java
class Solution {
    public int numIslands(char[][] grid) {
        int height = grid.length;
        int width = grid[0].length;
        boolean[][] isVisited = new boolean[height][width];
        int[] dx = new int[]{1, 0, -1, 0};
        int[] dy = new int[]{0, 1, 0, -1};


        int result = 0;

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                if (!isVisited[i][j] && grid[i][j] == '1') {
                    result++;
                    Queue<Point200> q = new LinkedList<>();
                    isVisited[i][j] = true;
                    q.add(new Point200(i, j));

                    while (!q.isEmpty()) {
                        Point200 now = q.poll();

                        for (int ne = 0; ne < 4; ne++) {
                            int nextX = now.x + dx[ne];
                            int nextY = now.y + dy[ne];

                            if (nextX < 0 || height <= nextX || nextY < 0 || width <= nextY) {
                                continue;
                            }
                            if(isVisited[nextX][nextY]){
                                continue;
                            }
                            if(grid[nextX][nextY] == '0'){
                                continue;
                            }
                            isVisited[nextX][nextY] = true;
                            q.add(new Point200(nextX,nextY));
                            

                        }
                    }
                }
            }
        }

        return result;
    }
}

class Point200 {
    int x;
    int y;

    Point200(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
```
Javaで何か作ってみる(2022/11/13 Day24)

## 今日やった事
- Mac環境で、VSCodeでJavaプログラムが実行出来るように開発環境を構築した。
## 参考にしたもの
- [Visual Studio CodeでJavaプログラム開発環境構築 - Qiita](https://qiita.com/jsj05543/items/da54e5db258bc9d2538a)
- [Java環境構築(Adoptium(旧:AdoptOpenJDK))](https://zenn.dev/sasakiki/articles/54f68ee1576380)
- [Javaの開発環境(Mac, VS Code) - Qiita](https://qiita.com/aoyaman/items/cd3ed987b8b704778144)
## 所感
- VSCodeの**Extension Pack for Java**の再インストールと、VSCodeの更新をしたら、設定出来た。更新出来てなかっただけだったのか。。。
## 明日の予定
- 明日からは、勉強がてら、Javaでサンプルプログラムを作成していく。