OmniAICreator/Qiita-1.07M huggingface dataset:
Boyer–Moore majority vote algorithm(過半数判定アルゴリズム)をElixirで書いてみた

下記の記事を見て興味を持ったので，Elixirで実装してみました．

https://qiita.com/tatmius/items/37707bce1ef079616c93

英語のWikipediaでアルゴリズムを確認しました．

https://en.wikipedia.org/wiki/Boyer–Moore_majority_vote_algorithm

原著論文も参照しました．

Robert S. Boyer and J. Strother Moore: MJRTY---A Fast Majority Vote Algorithm, Institute for Computing Science and Computer Applications, Texas University, Austin, Texas, USA, February, 1981. Appear in *Automated Reasoning: Essays in Honor of Woody Bledsoe*, Edited by Robert S. Boyer, Springer Science+Business Media, B.V., 1991.


## 実装例

プログラム本体は次のとおりです．

```elixir:lib/majority.ex
defmodule Majority do
  @moduledoc """
  The Boyer–Moore majority vote algorithm.
  """

  @doc """
  Returns the majority of the given `list`.
  """
  @spec get(list(any())) :: any()
  def get(enum) do
    mid =
      enum
      |> Enum.count()
      |> Bitwise.bsr(1)

    enum
    |> Enum.reduce({nil, 0}, fn
      a, {_, 0} -> {a, 1}
      a, {a, k} -> {a, k + 1}
      _, {m, k} -> {m, k - 1}
    end)
    |> case do
      {c, k} when k > mid ->
        c

      {c, _} ->
        enum
        |> Enum.count(&(&1 == c))
        |> then(&(&1 > mid))
        |> case do
          true -> c
          _ -> nil
        end
    end
  end
end
```

あっさり，[`Enum.reduce/3`](https://hexdocs.pm/elixir/1.16.0/Enum.html#reduce/3)で書けました．

202408004 修正: 原著論文のコードに合わせました．

テストコードは次のとおりです．

```elixir:majority_test.exs
defmodule MajorityTest do
  use ExUnit.Case
  doctest Majority

  describe "Majority.get/1" do
    test "[1, 2, 1, 1]" do
      assert Majority.get([1, 2, 1, 1]) == 1
    end

    test "[1, 2, 2, 1, 1]" do
      assert Majority.get([1, 2, 2, 1, 1]) == 1
    end

    test "[1, 2, 2, 2, 1, 3]" do
      assert Majority.get([1, 2, 2, 2, 1, 3]) == 2
    end

    test "[1, 2, 2, 2, 3, 2, 3]" do
      assert Majority.get([1, 2, 2, 2, 3, 2, 3]) == 2
    end

    test "[1, 2, 3, 2, 1]" do
      assert Majority.get([1, 2, 3, 2, 1]) == nil
    end
  end
end
```

過半数が決まらなかった時には `nil` を返します．(なお，Wikipedia中のコードではランダムな値が返ってくる不完全なコードです．)
ノートパソコンのカバーを閉じても、Suspendしない設定

# Workaround to make Ubuntu not suspend when laptop lid is closed

1. Edit the login.conf
```bash
/etc/systemd/logind.conf
```

2.Inside of the conf

```bash: logind.conf
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
#UserTasksMax=12288

```

Options

```bash:
HandleLidSwitch=lock – lock when lid closed.
HandleLidSwitch=ignore – do nothing, some laptops will disconnect Wi-Fi.
HandleLidSwitch=poweroff – shutdown.
HandleLidSwitch=hibernate – hibernate Ubuntu.
```

Please Change the following three options
```bash
HandleLidSwitch=ignore 
```
DatabricksでMixtral 8x7Bを動かしてみる

こちらのサンプルを動かしてみます。

https://qiita.com/taka_yayoi/items/85525979ef2b56950c5f

Databricksの環境にビルトインされているのですぐに利用できます。

サンプルはこちらです。

```py
import mlflow.deployments

client = mlflow.deployments.get_deploy_client("databricks")
inputs = {
    "messages": [
        {
            "role": "user",
            "content": "List 3 reasons why you should train an AI model on domain specific data sets? No explanations required."
        }
    ],
    "max_tokens": 64,
    "temperature": 0
}

response = client.predict(endpoint="databricks-mixtral-8x7b-instruct", inputs=inputs)
print(response["choices"][0]['message']['content'])
```

ただ、無邪気にこちらを実行すると以下のようなエラーになります。

> MlflowException: No plugin found for managing model deployments to "databricks". In order to deploy models to "databricks", find and install an appropriate plugin from https://mlflow.org/docs/latest/plugins.html#community-plugins using your package manager (pip, conda etc).

と言いますか、いつの間にかに[deployment API](https://mlflow.org/docs/latest/python_api/mlflow.deployments.html#mlflow.deployments)というものが。

解決策はこちらにありました。

[ステップ 2: 外部モデルをサポートする MLflow をインストールする](https://docs.databricks.com/ja/generative-ai/external-models/external-models-tutorial.html#step-2-install-mlflow-with-external-models-support)

> 外部モデルをサポートする MLflow バージョンをインストールするには、以下を使用します。

```py
%pip install mlflow[genai]>=2.9.0
dbutils.library.restartPython() # カーネルの再起動
```

こちらを実行後に再度上のコードを実行します。

```py
import mlflow.deployments

client = mlflow.deployments.get_deploy_client("databricks")
inputs = {
    "messages": [
        {
            "role": "user",
            "content": "List 3 reasons why you should train an AI model on domain specific data sets? No explanations required."
        }
```

```
1. Improved accuracy: Training an AI model on domain-specific data sets can significantly improve its ability to make accurate predictions or classifications related to that specific domain.
2. Better contextual understanding: Using domain-specific data sets allows the AI model to understand the unique context, jargon, and concepts
```

日本語ではどうでしょうか。プロンプトで日本語を返すように指示しています。あと、トークン数も増やしています。


```py
client = mlflow.deployments.get_deploy_client("databricks")
inputs = {
    "messages": [
        {
            "role": "user",
            "content": "ドメイン固有のデータセットでAIモデルをトレーニングすべき理由を日本語で3つ挙げてください。説明は不要です。"
        }
    ],
    "max_tokens": 256,
    "temperature": 0
}

response = client.predict(endpoint="databricks-mixtral-8x7b-instruct", inputs=inputs)
print(response["choices"][0]['message']['content'])
```

```
1. 適合度：ドメイン固有のデータセットを使用すると、特定の分野に特化したAIモデルをトレーニングできるため、適合度が高くなります。
2. 精度：ドメイン固有のデータセットでモデルをトレーニングすることで、より正確な予測や分析が可能になる場合があります。
3. 信頼性：ドメイン固有のデータセットを使用することで、モデルの信頼性が向上し、業界標準や法規遵守に堪能なAIモデルを開発できます。
```

いい感じですね。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
忘れやすいRspecのletとlet!の違い

# はじめに
rspecのletとlet!の違いを忘れてしまうことが多いのでここにメモする

# 問題
letとlet!はRSpecのヘルパーメソッドで、テスト内で使用するデータを定義するために使われます。しかし、それらはいつデータが生成されるかという点で違いがあります。
このような場合はcourseが複数保存されている必要があるのでlet!で定義しないとなにも保存されていない状態になります。
``` ruby
      get "/api/v1/courses"
      expect(JSON.parse(response.body)[0]["authority"]).to eq(course.authority)
      expect(JSON.parse(response.body)[0]["travel_mode"]).to eq(course.travel_mode)
      expect(JSON.parse(response.body)[1]["authority"]).to eq(other_course.authority)
      expect(JSON.parse(response.body)[1]["travel_mode"]).to eq(other_course.travel_mode)

```
# 解決方法
- let: letは遅延評価（lazy evaluation）を行います。つまり、letで定義したデータはそのデータが最初に呼び出されたときに初めて生成されます。同一のスコープ内で複数回呼び出された場合でも、データは一度だけ生成されます。
``` ruby
let(:course) { FactoryBot.create(:course) }
```
- let!: let!は即時評価を行います。つまり、let!で定義したデータは各テストケースが実行される前に必ず生成されます。これは、テストケースが実行される前にデータが存在することを保証する必要がある場合に便利です。
``` ruby
let!(:course) { FactoryBot.create(:course) }
```

# おわりに
よく忘れやすいのでメモしました。

# 参考
VimからNeovimに乗り換えた作業ログ

## この記事は何
ずっとVimを使っていたのですが、最近Neovimに乗り換えました。
乗り換えるにあたって設定周りを色々変更していったので、その作業をログとして残します。

作業前後のファイルは以下のようになっています。

https://github.com/getty104/dotfiles/blob/df3ff84e2a9522ec3c375cf0abc89f56d6d34bea/vimrc

https://github.com/getty104/dotfiles/tree/8d4b259c8d00dda0ef605c4bb39145c7cd84f2cb/nvim

## ステップ1: `~/.vimrc`を`~/.config/nvim/init.vim`にコピー
基本的にNeovimは今までの`.vimrc`を`~/.config/nvim/init.vim`にコピーするだけで使うことができます。

まずはこのコピーの作業を行い、Neovimでも今までのVimと同じように動作するようにしました。

## ステップ2: `~/.config/nvim/init.vim`を`~/.config/nvim/init.lua`に書き換える
Neovimは設定ファイルをVim script （init.vim） か Lua (init.lua) で書くことができます。
プラグインマネージャーをはじめ、NeovimのプラグインはLuaで書かれていることが多く、今後Neovimを使い続けるためには、Luaに書き換え、使用しているプラグインも一新する必要があると考えていました。

書き換え作業は以下のように行いました。


### ChatGPT (GPT-4)を用いて基本的なスクリプトを書き換える。

まずはChatGPTを使って、init.luaのベースとなるスクリプトを作成しました。
作成時のログは以下のとおりです。

https://chat.openai.com/share/1d48be73-dbb1-4d6f-b71a-a80b71d39b50

ただログにもあるとおり、一部ChatGPTだけでは実装できない部分があったり、冗長な実装など、一部修正が必要なところもあるため、そのままでは使用できません。

### ChatGPTで生成したinit.luaを修正していく
この部分は地道な作業になります。
実行して既存のinit.vimと同じ動作になるようにスクリプトの修正を行なっていきます。
修正はNevimのドキュメントを参考に行なっていきました。

https://neovim.io/doc/

## ステップ3: プラグインマネージャーを`dein.vim`から`lazy.nvim`に変える
Vimを利用していたときは[Shougo/dein.vim](https://github.com/Shougo/dein.vim)を使ってプラグインの管理をしていたのですが、`dein.vim`が積極的な開発をストップしているのと、Luaに書き換えたのでせっかくならと思いプラグインマネージャーも他のものへ変更することにしました。
新しく利用するプラグインマネージャーは[folke/lazy.nvim](https://github.com/folke/lazy.nvim)にしました。
`lazy.nvim`を採用した理由は以下のとおりです。

- Neovimのプラグインマネージャーの中でもスター数が多く、メジャーだと判断した
- 現在も積極的な開発がされている
- ピュアなLuaで全ての設定を書くことができる

書き換えはかなり愚直に手作業で行なっていきました。
このタイミングで古いプラグインの入れ替えなども行なっていきました。

`dein.vim`と`lazy.nvim`は以下のように書き換えています。

https://github.com/getty104/dotfiles/tree/df3ff84e2a9522ec3c375cf0abc89f56d6d34bea/toml

https://github.com/getty104/dotfiles/blob/8d4b259c8d00dda0ef605c4bb39145c7cd84f2cb/nvim/lua/lazy-nvim.lua
ボルダリングジムのホールドセグメンテーション

- 2024/1/10 追記 
    - すでにデータセットが存在していた.色分けはホールドだけで人やマットはされていない.
    - ルートを分類するために使用されていることが想定されているかと思われる.
    - 最終的にはまぶしをセグメントできるようにしたい
    - https://universe.roboflow.com/pwals/bouldering-holds-9wavr

# 概要

画像内のピクセルをクラスやカテゴリに分類するセマンティックセグメンテーションは様々な場面で使用されているが, クライミングで適用されている例が見当たらなかったため自分でテストデータを作るところから始めた.
クライミングホールドをセグメンテーションを行う手法は提案されている [[1](https://web.archive.org/web/20220511070209id_/https://repositum.tuwien.at/bitstream/20.500.12708/20091/1/Michenthaler%20Maximilian%20-%202022%20-%20Automated%20scoring%20in%20climbing%20competitions.pdf)].

# やったこと

- データセット作成用のツールを作成と公開
- 学習データを作成
- 室内でクライミングしている画像をセグメンテーションできる?

# やってないこと

- 学習に使用したデータの公開

# ソースコード類

ソースコードが整理されていないが以下のリポジトリに作成したソースコードが含まれている.
- BoulderingSegmentImageGenerator
    - テスト画像を作成するためのツールが含まれているディレクトリ
    - C# を使用
- BoulderingSegment/hold_segment.ipynb
    - 実際に学習に使用してるファイル
    - tensolflow のチュートリアルをベースにU-netで学習させている.
    - U-netは[3]を参考にしている

https://github.com/nagato0614/HoldsSegmentation


# データセットの作成

以下のような画像を元にラベル画像を作成する.
ボリュームとホールドの違いが曖昧だったため今のところ全てホールドという取り扱いをしている.

入力画像
![input_100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141779/98fa73c0-5e0a-fa86-8dd9-4983858560fb.png)

ラベル画像
![segment_100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141779/d943fdfe-6483-25f7-d736-fb1e26e9b192.png)

# 結果

- データの合計数 : 78
- 学習用画像 : 71
- 検証データ : 8
- テストデータ : 2
- 画像サイズ : 128 x 128 [px]

使用PC

- macbook pro
- CPU : Apple M2 Pro
- Memory : 32 GB


Loss
![loss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141779/a865815e-46ac-b3a7-0dab-0658f9b15ac8.png)

acc
![acc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141779/614d2348-3225-cdeb-dd66-7261e05e7290.png)


出力
![predict.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141779/1b3299b1-f94a-836c-a164-a420d3494188.png)

テスト
test_loss: 0.7562419772148132
test_acc: 0.792388916015625


# 今後

U-net以外にも良いモデルが公開されいるのでそれを試してみる.

# 気づき

- macbook で tensorflow を使っていたが案外性能が良かった. データ数が少ないからではあると思う. windowsPC(RTX 2070 Super) で学習を行ったが同じくらいのスピードでtrainを実行できた. 
    - [Get started with tensorflow-metal](https://developer.apple.com/metal/tensorflow-plugin/)

# 参考文献

1. [Michenthaler, Maximilian. Automated scoring in climbing competitions. Diss. Technische Universität Wien, 2022.](https://web.archive.org/web/20220511070209id_/https://repositum.tuwien.at/bitstream/20.500.12708/20091/1/Michenthaler%20Maximilian%20-%202022%20-%20Automated%20scoring%20in%20climbing%20competitions.pdf) 
    - 上記の文献ではYOLOを使ってクライマーやホールドの検出と追跡を実施している.
    - カラーマスクによるセグメンテーションを提案している.
2. [画像セグメンテーション](https://www.tensorflow.org/tutorials/images/segmentation?hl=ja)
    - このチュートリアルを元に実装を開始
3. [Tensorflowでの U-net 実装](https://qiita.com/hiro871_/items/871c76bf65b76ebe1dd0)
    - このサイトの U-net を利用した
Pythonで「辞書の要素の値を変更するまたは新しい要素を追加する」の動作を確認してみた

# 概要

Pythonで「辞書の要素の値を変更するまたは新しい要素を追加する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/dictionary/index3.html

# 実装

以下のファイルを作成しました。
```sample.py
mydict = {1:"Movie", 2:"Foods", 3:"Reading"}
mydict[2] = "Sports"
print(mydict)

mydict = {1:"Movie", 2:"Foods", 3:"Reading"}
mydict[4] = "Sports"
print(mydict)

mydict = {"w":"Water", "o":"Orange", "t":"Tea"}
mydict["t"] = "GreenTea"
print(mydict)
mydict["c"] = "Coffee"
print(mydict)

mydict = {1:"A", 2:"B", 3:"C"}
otherdict = {2:"b", 4:"d"}
mydict.update(otherdict)
print(mydict)

lunchdict = {"a":"curry", "b":"paster", "c":"udon"}
todaydict = {"b":"ramen", "d":"omelette"}
lunchdict.update(todaydict)
print(lunchdict)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
{1: 'Movie', 2: 'Sports', 3: 'Reading'}
{1: 'Movie', 2: 'Foods', 3: 'Reading', 4: 'Sports'}
{'w': 'Water', 'o': 'Orange', 't': 'GreenTea'}
{'w': 'Water', 'o': 'Orange', 't': 'GreenTea', 'c': 'Coffee'}
{1: 'A', 2: 'b', 3: 'C', 4: 'd'}
{'a': 'curry', 'b': 'ramen', 'c': 'udon', 'd': 'omelette'}
```

# まとめ

何かの役に立てばと。
プログラミング学習サイトまとめのまとめ

# はじめに

プログラミング学習サイトまとめのまとめです．
日本，海外問わずにまとめのサイトを掲載しています
同じものを含まないよう少し気を付けていますが混じっているかもしれないです．

https://meister-kentei.jp/magazine/programming/240/

https://tech-camp.in/note/technology/231/

https://products.sint.co.jp/topsic/blog/programing-study-online

https://programmercollege.jp/column/3097/

https://www.sejuku.net/blog/796

https://geek-salon.com/column/programming-practice-site/

https://kredo.jp/media/howtolearn/

https://qiita.com/KNR109/items/af433f1013221c5ed529

https://pikawaka.com/tips/overseas-learning-site-top-10

https://zenn.dev/nameless_sn/articles/awesome_free_programming_site

https://qiita.com/monsoonTropicalBird/items/a5a89cc689a81e6ba71e

https://products.sint.co.jp/topsic/blog/programing-study-online

競プロ
https://w.atwiki.jp/projecthikky/pages/71.html

# 英語

「Programming Learning Site」や「top 10 websites for learning programming languages」で検索しています
あまりとり切れていない感じがするので各自で上記の文で検索することをお勧めします

https://www.codemonkey.com/blog/top-websites-to-learn-to-code/

https://www.hostinger.com/tutorials/learn-coding-online-for-free

https://skillcrush.com/blog/64-online-resources-to-learn-to-code-for-free/

https://www.monster.com/career-advice/article/learn-how-to-code-online

https://devopscube.com/top-websites-to-learn-programming-online/

https://www.shiksha.com/online-courses/articles/free-coding-websites-to-learn-programming/

https://mhzarif.medium.com/top-10-websites-to-learn-programming-e529987b70d5

https://zinduaschool.com/learn-coding-for-free/

https://learntocodewith.me/posts/code-for-free/



# サイトごとまとめ
後ほど追記予定
BigQuery Studio (JupyteNotebook)でPythonの変数を埋め込んでSQLを実行する

## tl;dr

Pythonのdict型で変数を書く。かならず値はint、str、floatにする。

```python
params = {
  "start_time": "2023-12-25T00:00:00+09:00",
  "end_time": "2023-12-26T00:00:00+09:00",
}
```

`%%bigquery results --params $params`を付けて実行する。

```sql
%%bigquery results --project hoge-project --params $params
SELECT
  COUNT(*) count,
  MAX(T.ts) max,
  MIN(T.ts) min,
FROM `hoge-project.hoge_dataset.hoge_table` T
WHERE T.ts BETWEEN @start_time AND @end_time
```

## 仕様の解説

BigQuery Studioは、BigQueryのWebコンソール上でJupyterNotebookを実行する機能。`%%bigquery`と書いたセル作るとクエリを実行できる。

これはJupyter NotebookのCell Magicという機能で実現されている。このCell Magicには引数が与えられ、その場合にPythonの変数を参照するには `$params` と記述する。`%%bigquery`がBigQueryのCell Magicの呼び出しである。

BigQueryのクエリには、query_parametersという仕様（QueryJobConfig参照）があり、クエリ中に`@start_date` などと書くと埋め込むことができる。BigQueryのCell Magicでは`--params $params`でdict型の変数を与えるとこのクエリパラメータに埋め込むことができる。

## 他に便利なノウハウ

`--destination_table hoge_dataset.hoge_table` を付けると、格納先テーブルを指定できる。

クエリ結果をdataframeとしての取得する必要がない場合も、常に全件取得してしまい時間がかかる仕様になっている。その場合、`--max_results 1`とかしておくと、1件しか取得しないので早い。

## 参考資料

BigQueryのQueryJobConfigのドキュメント

https://cloud.google.com/bigquery/docs/parameterized-queries?hl=ja#python

IPython Magic BigQueryのドキュメント

https://github.com/googleapis/python-bigquery/blob/release-v2.12.1/google/cloud/bigquery/magics/magics.py#L15-L145
Xubuntu(Ubuntu)にてSlackがタスクトレイにいない場合の対処法

Slack がタスクトレイに表示されないという Bug Report が上がっていました。

`ayatana-indicator-application` をアンインストールすると解消する可能性があります。

```
sudo apt remove ayatana-indicator-application
```

## 参考

https://bugs.launchpad.net/ubuntu/+source/budgie-indicator-applet/+bug/2023519
golangの公式の構造化ロガー「slog」でシンプルなログを出す

go1.21から公式の構造ロガー「slog」が標準搭載されましたが、シンプルにログを出すことができなかったので、工夫したことをブログにします。

#### やりたいこと

1.ログレベルを指定できる

2.以下のように時間、レベル、メッセージがテキストで印字できる

```
[2024-01-04 18:20:47.234] [ INFO] メッセージ
```

#### slogだけだと何が駄目か？

パッケージにある関数を直接呼び出す `slog.Info("info msg")` という方法だと、レベル指定ができない

TextHandler だと、レベルを指定できが、印字される文字が以下のように`キー=バリュー`という以下のような文字列になり、読みにくい

```
time=2024-01-04T18:20:16.149+09:00 level=INFO msg=メッセージ
```

他の言語にあるFormatterなどを用いた指定もできない。

#### どうしたか

シンプルにログを出せる `SimpleHandler` を作った 

以下、作ったコードです。そのまま動きます。

```golang
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"log/slog"
	"os"
)

type SimpleHandler struct {
	slog.Handler
	logger *log.Logger
}

func NewSimpleHandler(out io.Writer, level slog.Level) *SimpleHandler {
	prefix := ""
	h := &SimpleHandler{
		Handler: slog.NewJSONHandler(out, &slog.HandlerOptions{
			Level: level,
		}),
		logger: log.New(out, prefix, 0),
	}
	return h
}

func (h *SimpleHandler) Handle(_ context.Context, record slog.Record) error {
	ts := record.Time.Format("[2006-01-02 15:04:05.000]")
	level := fmt.Sprintf("[%5s]", record.Level.String())
	h.logger.Println(ts, level, record.Message)
	return nil
}

func main() {
	handler := NewSimpleHandler(os.Stdout, slog.LevelInfo)
	logger := slog.New(handler)
	logger.Debug("debug msg")
	logger.Info("info msg")
	logger.Warn("warning msg")
	logger.Error("error msg")
}
```
実行結果は以下のようにレベルを指定して、時間、レベル、メッセージを出すことができました！

```
[2024-01-04 18:20:47.234] [ INFO] info msg
[2024-01-04 18:20:47.235] [ WARN] warning msg
[2024-01-04 18:20:47.235] [ERROR] error msg
```
~随時更新~ Wetな研究者のための、Pythonを用いた統計検定手法

# はじめに
統計検定をエクセルに頼っている若手学生 （特に学部生） は少なくないのではないだろうか。
確かにエクセルは、
* 容易にソフトを入手できる（大学で配布される）
* データをエクセルにまとめているので、すぐに統計検定を実施できる
* データの可読性に優れる（色付け等が可能）

…等のメリットを有する非常に有用なツールであり、筆者も使用しない日は無いと言っていい。しかしながら一部の統計検定についてはエクセルでは実施不可能、また実施が困難な場合がある。

本稿では、２群間の平均値の比較を中心に、Pythonを用いて統計検定を実施する方法をまとめる。
Pythonも無料（かつ容易？）に入手できるソフトウェアであり、少し発展的な統計検定に手を出そうとしている若手学生の助けになればと思う。
（Pythonの導入については筆者の過去記事を参考にすること https://qiita.com/shyu_manabe/items/682e6c73b368b0fe02ba ）

## 正規性、等分散性の検定
（後ほど更新予定）

## 2群間の平均値の比較
### Student's t-test
* 2群間の平均値を比較
* データ間に対応がない
* 2群とも正規分布に従う（パラメトリック）
* 2群の分散に差がない（等分散性）

```Studentst.py
# 必要なモジュールをインポート
import numpy as np
from scipy import stats

# 使用するデータを定義
A = np.array([5.3, 4.1, 1.4, 9.4, 9.6, 11.5, 11.2, 12.5, 9.0, 6.8])
B = np.array([3.8, 1.1, 4.1, 3.0, 2.0, 2.0, 2.4, 1.7, 5.1, 0.4, 0.6])

# Student's t-testの実施
stats.ttest_ind(A, B)
```
↓結果
```Result.sh
Ttest_indResult(statistic=4.8402379129604505, pvalue=0.00011370228234146141)
```
結果、P<0.05なので（有意水準は各自の設定に依る）、「2群間の平均値に差がない」という帰無仮説が棄却され、対立仮説である「2群間の平均値に差がある」を採択する。
【Java・学習ログ16】コレクションについて～Setの基本～

教本に沿ってやってみたシリーズ、『第16章』その２。
≪使用教材≫スッキリわかるJava入門　第3版　スッキリわかるシリーズ

## set関連のクラスについて
- java.util.HashSetクラス
Setインタフェースを実装するコレクションクラスの中でもっとも一般的なクラス。set関連クラスは複数の情報を重複なく格納する集合(セット)というデータ構造を実現するためのもの。
「重複は許さないが、その順番は問わない」というデータの集まりを利用したい場合にSet関連クラスを用いる。

<b>【Setインタフェースが備えるメソッド】</b>
|操作|戻り値|メソッド|機能|
|-|-|-|-|
|追加|boolean|add(★)|セットに要素を追加|
|取得|なし|なし|なし|
|調査|int|size()|格納されている要素数を返す|
||boolean|isEmpty()|要素数がゼロであるかを判定|
||boolean|contains(★)|指定要素が含まれているかを判定|
|削除|void|clear()|要素をすべて削除する|
|boolean|remove(★)|指定した内容の要素を削除する|
|イテレータ|Iterator<★>|iterator()|要素を順に処理するイテレータを返す|


<b>★★★注意点★★★</b>
1. 重複した値を格納しようとすると無視される
![スクリーンショット 2023-11-09 214325.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/a514f918-640c-fa80-965b-12b6191706b2.png)
【実行結果】
![スクリーンショット 2024-01-04 164030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/ed5c68ec-dab3-6f20-5930-9831162a3241.png)
2. set()やget()は使えない。
リストのように「〇番目」という概念がないため。
3.要素を１つずつ取り出す場合の順序は不明
セット要素には順序がないため、１つずつ取り出す場合、どのような順序で要素が取り出されるかは一切保証がされていない。
![スクリーンショット 2024-01-04 165233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/2acfe9d0-07d9-40e5-74a6-b71f4a56b04c.png)
【実行結果】
![スクリーンショット 2024-01-04 165225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/22516f1f-b3c7-296f-dfb8-c824baccb2ba.png)
### 順序が保証されるSetバリエーション
* LinkedHashSet : 値を格納した順序に整列
* TreeSet : 自然順序付けで整列
<hr>
【Vue.js】配列・連想配列・Mapのループ

## はじめに

Vue.jsのComposition APIでの配列・連想配列・Mapのループについてまとめました。

## 環境

- Vue.js: 3.3.11
- TypeScript: 5.3.0

## 配列

`v-for="value in 配列"` のように指定します。

```Vue
<script setup lang="ts">
import {ref} from "vue";

const userList: string[] = ["樫野有香", "西脇綾香", "大本彩乃"];
</script>

<template>
 <ul>
  <li v-for="name in userList" :key="name">
    ユーザー名は{{ name }}
  </li>
 </ul>
</template>
```

配列に限らずループ文全般にいえることですが、**`key`はコンポーネントで一意**でなければいけません。

`key` に `index` を使用すると入れ替え・更新・削除で順番が変わってしまう可能性があるため、`key` は`name` にしています[^1]。

なお、indexも使用する場合は、`v-for="(value, index) in 配列"` のように指定します。

```Vue
<script setup lang="ts">
import {ref} from "vue";

const userList: string[] = ["樫野有香", "西脇綾香", "大本彩乃"];
</script>

<template>
 <ul>
  <li v-for="(name, index) in userList" :key="name">
    index:{{ index }}のユーザー名は{{ name }}
  </li>
 </ul>
</template>
```

## 連想配列

`v-for="(value, key) in 連想配列"` のように指定します。

```Vue
<script setup lang="ts">
import {ref} from "vue";

const userListInit: {[key: number] : string} = {
  1: "樫野有香",
  2: "西脇綾香",
  3: "大本彩乃"
};
const userList = ref(userListInit);
</script>

<template>
 <ul>
  <li v-for="(name, id) in userList" :key="id">
    id:{{ id }}のユーザー名は{{ name }}
  </li>
 </ul>
</template>
```

なお、indexを使用する場合は `(value, key, index)` の順になります。

## Map

`v-for="[key, value] in Map"` のように指定します。

配列や連想配列と異なり、**[]を使い**、**key, valueの順番が逆**なので気を付けてください。

```Vue
<script setup lang="ts">
import {ref} from "vue";

const userListInit = new Map<number, string>();
userListInit.set(1, "樫野有香");
userListInit.set(2, "西脇綾香");
userListInit.set(3, "大本彩乃");
const userList = ref(userListInit);
</script>

<template>
 <ul>
  <li v-for="[id, name] in userList" :key="id">
    id:{{ id }}のユーザー名は{{ name }}
  </li>
 </ul>
</template>
```

## TypeScriptを使わない場合

以下のように書き換えてください。

```diff
- <script setup lang="ts">
+ <script setup>
```


```diff
// 配列
- const userList: string[] = ["樫野有香", "西脇綾香", "大本彩乃"];
+ const userList = ["樫野有香", "西脇綾香", "大本彩乃"];

// 連想配列
- const userListInit: {[key: number] : string} = {
+ const userListInit = {

// Map
- const userListInit = new Map<number, string>();
+ const userListInit = new Map();
```

## 参考

https://gihyo.jp/book/2022/978-4-297-13072-5

https://jsprimer.net/basic/map-and-set/

[^1]:同姓同名を考慮する必要がある場合は、配列ではなく連想配列にしてidを持たせる等の工夫が必要
Node.jsのバージョン管理ツールを調べてみた

## 動機

[JavaScript Primer](https://jsprimer.net/use-case/setup-local-env/)で公開されているTODOリストを作りたいと思ったから  
そこで、Node.jsのインストールが必要ということがわかった  
少しNode.jsを調べるとバージョンが複数あることが判明  
Pythonをやっていたときにバージョン管理をせずに痛い目にあったことを思い出し、調査を始めた

## 参考にした記事

- [Node.jsのバージョン管理ツールを改めて選定する【2021年】](https://qiita.com/heppokofrontend/items/5c4cc738c5239f4afe02)
  - 河童 エクマさん執筆の記事
  - 技術選定の方法から学べる、最もお世話になった記事
- [WindowsでNode.jsバージョン管理ツールをどれにするか](https://zenn.dev/longbridge/articles/ef1cbd17f2f64c)
  - piyokoさん執筆の記事
- [Mac→Windowsに移行した際にNode.js管理ツールにnvm for windowsを選んだ理由](https://hikoma.jp/tcdigital/works/8365)
  - 株式会社テクノデジタルさん執筆の記事

## 各バージョン管理ツールの比較(2024/01/04)

河童 エクマさんの記事で紹介されていた表がわかりやすかったので   
`Support automatically`の項目以外を調べて、更新してみました。

|Name|Windows|macOS|Support automatically|GitHub Stars|Version/Year|
|--|--|--|--|--|--|
|[nodist](https://github.com/nodists/nodist)|✅|-|.node-version<br/>package.json(engine.node)|1.6k|v0.9.1 / 2023
|[asdf](https://github.com/asdf-vm/asdf)|-|✅|.node-version<br/>.nvmrc|19.4k|v0.13.1 / 2023
|[fnm](https://github.com/Schniz/fnm)|✅|✅|.node-version<br/>.nvmrc|14.2k|v1.35.1 / 2023
|[n](https://github.com/tj/n)|-|✅|.n-node-version<br/>.node-version<br/>.nvmrc<br/>package.json(engine.node)|18.2k|v9.2.0 / 2023
|[nave](https://github.com/isaacs/nave)|✅※1|✅|.naverc|1.6k|v3.5.1 / 2023
|[nodebrew](https://github.com/hokaccha/nodebrew)|-|✅|-|1k|v1.2.0 / 2022
|[nodenv](https://github.com/nodenv/nodenv)|-|✅|.node-version|2.1k|v1.4.1 / 2023
|[nvm](https://github.com/nvm-sh/nvm)|-|✅|.nvmrc|72.7k|v0.39.7 / 2023
|[nvm-windows](https://github.com/coreybutler/nvm-windows)|✅|-|-|32.5k|v1.1.12 / 2023
|[nvs](https://github.com/jasongin/nvs)|✅|✅|.node-version<br/>nvmrc|2.5k|v1.7.1 / 2023
|[volta](https://github.com/volta-cli/volta)|✅|✅|package.json(volta.node)|9.2k|v1.1.1 / 2023

※1:[Windowsに関する記載](https://github.com/isaacs/nave#:~:text=Nave%20requires%20bash.%20It%20will%20probably%20never%20work%20on%20Windows%2C%20or%20other%20systems%20lack%20a%20native%20Bourne%20Again%20Shell.%20Sorry.%20(Patches%20welcome%20if%20you%20can%20get%20it%20to%20work%20properly%20on%20Windows%20that%20do%20have%20bash%2C%20like%20WSL%20and%20Cygwin.))を見るにbashが必要

## nvm-windowsを使ってみる

- 選定の基準
  - 信頼性
  - 生産性
    - 今回は別のツールから移行ではないので、導入のしやすさにのみ注目
  - 情報収集が容易かどうか
    - Nodejsを初めて触るので、参考になる情報が多いほうが良い

上記の選定基準で考え、結果`nvm-windows`にしました。  
デメリットの`クロスプラットフォームではない`と`プロジェクトごとの自動切り替えがない`に関しては  
今はNodejsを試したいだけなので、導入のしやすさと情報量というメリットが上回りました。  

## 所感

調べていると、fnmやvoltaに決めたという記事が多くありました。  
私も最初はそれに従う予定でした。   
ただ、`クロスプラットフォームではない`と`プロジェクトごとの自動切り替えがない`というデメリット
を持っているにもかかわらず、githubのスター数が圧倒的に多いのはなぜだろう。  
今回使ってみて、それが分かればいいなと思います。
ビット操作　Counting Bits

## 問題文
整数 n を指定すると、各 i (0 <= i <= n) について、ans[i] が i のバイナリ表現における 1 の数となる、長さ n + 1 の配列 ans を返します。

## 解答①
引数n+1の長さを持つ配列ansを用意し、ans.length分をループします。
(i/2)+(i%2)で2進数変換を行い、1のカウント数をansに格納する。

### コード
```java
class Solution {
    public int[] countBits(int n) {
        int offset=1;
        int [] ans = new int [n+1];
        for (int i=1;i < ans.length;i++){
            ans[i]=ans[i/2]+(i%2);
        }
        return ans;
    }
}
```
実行時間：2ms
メモリー：46.55MB

## 解答②
n&(n-1)により、nの最下位の1を0に変換および論理積を行い、ans[i]を求めます。

### コード
```java
class Solution {
    public int[] countBits(int n) {
        int [] ans = new int [n+1];
        for (int i=1;i < ans.length;i++){
            ans[i]=ans[i&(i-1)]+1;
        }
        return ans;
    }
}
```
実行時間:2ms
メモリー：46.78MB

参考
https://www.madopro.net/entry/2016/09/23/223037
https://qiita.com/KueharX/items/98dcdb1b82d39c464a92
四捨五入をする関数

## 四捨五入関数

以前に何処かに書いて，コメントももらっていたのが行方不明になっていました。

新たに頂いたコメントに基づいて，本文を追加・訂正します。
さらなるコメント，多言語による実装例等歓迎です。

### Python


```Python
def shishagonyu(x, n=0):
    return (-1 if x < 0 else 1 if x > 0 else 0)*int(abs(x) * 10**n + 0.5) / 10**n
```


```R
(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```




    (5.2, -5.2, 1.0, -1.0)




```R
(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(1.5), shishagonyu(-1.5))
```




    (5.3, -5.3, 2.0, -2.0)



#### @shiracamus(しらかみゅ)


abs を取らなくてもできる。


```Python
def shishagonyu(x, n=0):
    return int(x * 10**n + (-0.5 if x < 0 else 0.5)) / 10**n
```


```Julia
(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```




    (5.2, -5.2, 1.0, -1.0)




```R
(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(1.5), shishagonyu(-1.5))
```




    (5.3, -5.3, 2.0, -2.0)



### Julia


```R
shishagonyu(x, n=0) = sign(x)*Int64(abs(x)*10^n + 0.5)/10^n;
```


```R
(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```




    (5.2, -5.2, 1.0, -1.0)




```R
(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(2.5), shishagonyu(-2.5))
```




    (5.3, -5.3, 3.0, -3.0)


#### @antimon2(Shunsuke GOTOH)


Julia は標準の関数で四捨五入を実現できるものがある。

```R
shishagonyu(x, n=0) = round(x, RoundNearestTiesAway; digits=n);
```


```R
(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```




    (5.2, -5.2, 1.0, -1.0)




```R
(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(2.5), shishagonyu(-2.5))
```




    (5.3, -5.3, 3.0, -3.0)



### R



```R
shishagonyu = function(x, n=0) sign(x)*as.integer(abs(x)*10^n + 0.5)/10^n
```


```R
cat(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```

    5.2 -5.2 1 -1


```R
cat(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(2.5), shishagonyu(-2.5))
```

    5.3 -5.3 3 -3

@shiracamus(しらかみゅ) さんの指摘により修正


```R
shishagonyu = function(x, n=0) as.integer(x * 10^n + ifelse(x < 0, -0.5, 0.5)) / 10^n
```


```R
cat(shishagonyu(5.15, 1), shishagonyu(-5.15, 1), shishagonyu(0.5), shishagonyu(-0.5))
```

    5.2 -5.2 1 -1


```R
cat(shishagonyu(5.25, 1), shishagonyu(-5.25, 1), shishagonyu(2.5), shishagonyu(-2.5))
```

    5.3 -5.3 3 -3
パスワードの使い回しは絶対止めようと痛感した話

とある店舗での買い物中、ちょっとした事件（？）に遭遇しました。

## 何が起きたか
具体的な名前は伏せますが、全国展開しているある専門店で買い物をした際の出来事です。

私はその店舗のポイントサービス（アプリ）に登録していました。
会計の際にポイントアプリの提示を求められたので起動したのですが、久しぶりの利用のためログアウトされており、不覚にアカウント情報を管理ソフトに未登録だったためログインID/パスワードが分からなくなってしまいました。

レジでもたつくのも申し訳ないので今回はポイントの付与は結構です、と断ったのですが店員さんが「ではログイン情報をお調べしますよ」と言い、情報をプリントアウトしたものを渡してくれました。
そこには登録した連絡先などの情報の他にID、**パスワードが平文で記載**されており、これでログインして下さいね、と仰るのでした。

## 思うこと
今回の対応は店員さんが親切心で行ってくれたことで、そこを非難するつもりはありません。

しかしながらポイントサービスにパスワードが平文で保存されていること、販売担当者がその情報にアクセス出来てしまうことは言うまでもなく大変危険なことです。

今回の出来事でたまたまこの店舗のセキュリティの懸念が露見しましたが、これは氷山の一角であるように思います。
大手の店舗であっても正直アプリやサービスの出来に疑問を感じることはあり、そういったサービスのセキュリティがどうなっているかは我々一ユーザーが知ることは難しいのが現状です。

私達にできることとしては
* パスワードは絶対に使い回さない。
* メールアドレスも可能であれば使い捨てのものを検討する。（iCloud+の「メールを非公開」機能など）
* そもそも信頼のおけないサービスに対して個人情報を提供しない。

等、基本的なセキュリティ対策を遵守することです。

## 個人情報を預けるとは
そもそもポイントカードというシステムは、店舗が個人情報を収集しマーケティングに利用、その対価としてポイントを還元する、という側面があります。
（もちろん再来店を期待する効果や、純粋に来店に対するお礼としてなど、それだけではないと思いますが）

今の時代、あらゆるサービスの登録に個人情報の入力を求められるため、個人情報を他者に全く提供せずに生活するのは不可能に近いでしょう。
しかし「便利だから」「お得だから」と安易に情報を登録していくのはそれだけリスクが増すことになります。
サービス運営側のセキュリティ対策の向上を願うのはもちろんですが、ユーザー側もむやみにリスクを増さないようにリテラシーを持つことが大切かもしれません。
C#13でのparamsキーワード

## 参考

https://youtu.be/xMKQ5X1qPZw?si=Cj0_impxJjuv2orj

## paramsキーワード
メソッドの引数が配列の場合、
- 仮引数に`params`を付けることで
- 実引数には値を列挙（カンマで区切る）して渡すことができる
## C#12までのparamsの制限
- `params`が付けられる仮引数の型は、配列のみ
## C#13のparams
- `List<T>`や`IEnumerable<T>`など、仮引数がコレクションなら`params`を付けられる
[TypeScript]ジェネリクスについて簡単にまとめた

# ジェネリクスとは
　ジェネリクスとは、**型引数を受け取る関数を作る機能**のことです。
 ジェネリクスはTypeScriptプログラミングにおいて欠かすことができない機能の一つです。
例えば、以下のように書くことができます。
```sample.ts
type User<N> = {
    age: N;
};
  
const userAge: User<string> = { age: "25" };
const userAge2: User<number> = { age: 25 };
console.log(userAge);
console.log(userAge2);
```
このように、引数の中身(N)を「age」の型定義に適用させることができます。
これが、以下のようにするとコンパイルエラーとなります。
```sample.ts
type User<N> = {
    age: N;
};

// コンパイルエラー↓
const userAge: User<number> = { age: "25" };
// コンパイルエラー↓
const userAge2: User<string> = { age: 25 };
console.log(userAge);
console.log(userAge2);
```

# 関数の型引数とは
以下のコードを参考に説明します。
```sample.ts
function repeat<T>(element: T, length: number): T[]{
    const result: T[] = [];
    for(let i = 0; i < length; i++){
        result.push(element)
    }
    return result
}

// ["a", "a", "a", "a", "a"]が表示される。
console.log(repeat<string>('a', 5));
// [123, 123, 123]が表示される。
console.log(repeat<number>(123, 3));
```
## 解説 
### 1. ジェネリクスの宣言
```sample.ts
function repeat<T>(element: T, length: number): T[]{
    // ...
}
```
Tは型パラメータを宣言しており、この関数が受け取る引数や戻り値の型が任意の型に対応できるようにしています。この場合、T は配列の要素の型を表しています。

### 2. 型パラメータの利用
```sample.ts
const result: T[] = [];
```
T で宣言された型パラメータを使用して、空の配列 result を宣言しています。これにより、result 配列はジェネリクス型に基づいて型付けされます。

### 3. 型の決定
```sample.ts
console.log(repeat<string>('a', 5));
console.log(repeat<number>(123, 3));
```
関数を呼び出す際に、ジェネリクスの型パラメータに具体的な型を指定しています。最初の例では文字列型 (string) を指定し、2番目の例では数値型 (number) を指定しています。これにより、element パラメータと関連する型が string または number に決定されます。

以下のようにするとエラーになります。

```sample.ts
// 型 'number' の引数を型 'string' のパラメーターに割り当てることはできません。
console.log(repeat<string>(100, 5));
```

# 最後に
他にも色々な記事を書いているので、よければ読んでいってください、、、

https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

https://qiita.com/hukuryo/items/2c07c52ff3386d5d75b9

https://qiita.com/hukuryo/items/ebeb26823f944f143b11
【JavaScript】分割代入

### 分割代入とは

分割代入とは、配列/オブジェクトを分解して、要素/プロパティの値を個々の変数に分解するための構文である。

### 分割代入 (配列)
代入先変数全体をブラケット[...]でくくる。

#### 配列要素と変数が同じ
左辺に要素の数だけ変数を列挙する。

```javascript
const data = [1, 2, 3, 4, 5]
const [x0, x1, x2, x3, x4 ] = data
console.log(x0, x1, x2, x3, x4)
```

```javascript:実行結果
1 2 3 4 5
```

#### 配列要素と変数の個数が異なる
左辺変数と右辺の配列要素の個数が等しくなくても構わない。

```javascript
const data = [1, 2, 3, 4, 5]

// 配列サイズよりも代入先の変数の個数が少ない場合は、残りの要素は無視される。
const [x0, x1, x2] = data
console.log(x0, x1, x2)

// 配列サイズよりも代入先の変数の個数が多い場合は、対応する要素がないためundeinedとなる。
const [y0, y1, y2, y3, y4, y5, y6, y7] = data
console.log(y0, y1, y2, y3, y4, y5, y6, y7)

// 要素を無視したい場合は、要素の数だけカンマを列記する。
const [z0, , , z4, z5] = data
console.log(z0, z4, z5)
```

```javascript:実行結果
1 2 3
1 2 3 4 5 undefined undefined undefined
1 4 5
```

#### 「...」演算子で残りの要素を取得
「...」演算子を利用することで、個々の変数に分解しきれなかった要素の残りをまとめて配列として切り出すことが可能。

```javascript
const data = [1 , 2, 3, 4, 5]
// 変数名otherとしているが、名前はなんでも構わない
const [x0, x1, ...other] = data
console.log(x0, x1)
console.log(other)
```

```javascript:実行結果
1 2
[3, 4, 5]
```

#### 変数の入れ替え (スワッピング)
分割代入を利用すれば、変数の値を入れ替える (スワップ) することもできる。

```javascript
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y);
```

```javascript:実行結果
2 1
```

#### 宣言と切り離して分割代入する
変数宣言と分割代入を双方切り離すことできる。

```javascript
let x, y, z;
const data = [1, 2, 3];
[x, y, z] = data;
console.log(x, y, z);
```

```javascript:実行結果
1 2 3
```

### 分割代入 (オブジェクト)
オブジェクトの場合は、プロパティを個々の変数に分解する。よって、変数の並び準はプロパティの定義順と違っていても、分解しないプロパティがあっても構わない。
また、目的のプロパティが存在しない場合に備えて、「変数名 = 既定値」を指定することもできる。
代入先変数全体をブラケット{...}でくくる。

```javascript
const obj = {
  x : 1,
  y : 2,
  z : 3,
}
// xyzのプロパティがobjに存在しないので規定値として4を指定
const { x, y, xyz = 4 } = obj
console.log(x, y, xyz)
```

```javascript:実行結果
1 2 4
```

#### 入れ子となったオブジェクトを分解
入れ子となったオブジェクトを展開するには、オブジェクトの入れ子関係がわかるように代入先の変数も{...}で入れ子構造を表す。

```javascript
const obj = {
  x : 1,
  y : {
    y0: 11,
    y1: 22,
  },
  z : [111, 222]
}
// y: { y0 } にすることでyオブジェクトのy0プロパティの値を取得できる。
// 同様に入れ子の配列を分解する場合は、z: [val0, val1]のようにすることで可能となる。
const { x, y: {　y0　}, z: [val0, val1] } = obj
console.log(x, y0, val0, val1)
```

```javascript:実行結果
1 11 111 222
```

#### 変数の別名を指定
「変数名: 別名」の形式で、プロパティとは異なる名前の変数に値を割り当てることもできる。

```javascript
const obj = {
  x: 1,
  y: 2,
}

const { x: x0, y: y0 } = obj
console.log(x0, y0)
```

```javascript:実行結果
1 2
```
#### 「...」演算子で残りのプロパティを取得
[...]演算子を利用することで、明示的に分解されなかった残りの要素をまとめて取得することができる。

```javascript
const obj = {
  x: 1,
  y: 2,
  z: 3,
}
// 変数名otherとしているが、名前はなんでも構わない
const { x, ...other } = obj
console.log(x)
console.log(other)
```

```javascript:実行結果
1
{ y: 2, z: 3}
```

#### 宣言と切り離して分割代入する
変数宣言と分割代入を双方切り離すことできる。ただし、左辺の{...}はブロックと見なされ、単体で文と見なされないので前後にカッコをつける必要がある。

```javascript
let x, y, z;
const obj = {
  x: 1,
  y: 2,
  z: 3,
};
// {...}はブロックと見なされるのでカッコをつけることで一文と見なす。
({ x, y, z } = obj);
console.log(x, y, z);
```

```javascript:実行結果
1 2 3
```
「複合ジオメトリの作成」の最適解（多分）

# 複合ジオメトリ作成の最適解はFourBarサンプル

公式ヘルプの「複合ジオメトリの作成」よりも、公式のFourBarサンプルの実装が、ベストプラクティスに見えるのですが、解説が無いため初心者には厳しかった。（泣き）
ここにメモを残します。

数日前に作成した記事よりも、本記事の方が効率よく記述できます。

https://qiita.com/t_kumazawa/items/0e4abbff6682c7fd3377

# なぜ「FourBarサンプル」の方がよいのか？

比較表を作ってみました。

||コードを書く場所|初期化タイミング|パラメータを書く場所|
|---|---|---|---|
|「複合ジオメトリの作成」|MATLABコードまたは、MATLABファイル|「ソースから再初期化」ボタン|MATLABコードまたは、MATLABファイルの中|
|「FourBarサンプル」|マスクエディタの「コード」タブ|初期化時に自動実行|マスクエディタの「パラメータとダイアログ」タブ|

+ MATLABコードに直に書く場合、コピペできない
+ MATLABファイルの場合、ファイルを別で用意したり、編集後に「ソースから再初期化」ボタンを押す必要がある
+ MATLABコードの中にパラメータを記述する場合、パラメータの微調整のたびにコードを書き換えることになる
+ パラメータをマスクから引っ張る場合、Mコードとサブシステムとのアクセス関数を記述する必要があり面倒
+ アクセス関数を記述する場合、サブシステムやslxのファイル名が変更されるたびに、Mファイルを編集する必要あり

など、面倒ごとが多かったです。
FourBarサンプルに沿った記述の方が、ジオメトリ情報をきれいな形で記述することができます。

# 複合ジオメトリの編集
## サブシステムの中にExtruded Solidを用意して複合ジオメトリをセットする準備をする

直方体のBrick Solid（レンガソリッド）ではなく、**Extruded Solid**（押出しソリッド）を使ってBodyを作ります。
Extruded Solidを使うことで、Fusion360のスケッチの押出しのようなイメージで、部品を作ることができます。


公式のFourBarサンプルが大変参考になりますが、Initialization()にコールバックで形状データの生成処理を記述する

https://jp.mathworks.com/help/sm/ug/configure-four-bar-model-for-code-generation.html?s_tid=srchtitle_site_search_1_fourbarexample

## マスク編集のコードで複合ジオメトリを記述する

FourBarのCrank Linkの「マスク編集」を開いてみる。
パラメータとしてリンクの長さや幅などを設定している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/da68ba70-988f-824a-1c29-fe5231495415.png)

「コード」タブを選択すると、初期化とコールバックのところにコードが書けます。
パラメータにもアクセスできるので、バラメータを変更すると初期化コードが呼び出されて形状データが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/cb13356c-05ae-0a4a-d766-8a9272850533.png)

コードの中のleft_end_x_section 変数に形状データを入れているので、サブシステムの中の「Cross-section」＝ left_end_x_sectionとしておけば形状が反映されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/5176865f-32b6-72d3-a5e7-b0729d2021f4.png)

## アイコンを変更する

マスクの編集の「アイコン」タブで、アイコンも追加・編集ができます。
実行したときに表示されるリンクのスクリーンショットを貼り付けたpngファイルを作って、適当なディレクトリに保存しました。

プロジェクトの下のslxファイルを置いているディレクトリ : **'05_LinkForm'**
アイコンイメージを保存しているディレクトリ : **'images'**
アイコンファイル : **'link01.png'**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/b9ef1280-d0ae-4954-90f4-6d31c55e8777.png)

# ソルバーの設定
デフォルト設定のままだと、動かしたときにあまりにもガタガタなので、以下の様に調整する。
ode45を選択し、最大ステップサイズと許容誤差を1e-6に調整。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/ca5ae8b7-e916-5404-5d62-46fa2727b2d9.png)


# まとめ

複合ジオメトリを使ってリンク部品を作るとき、以前はMファイルなどを複数作って手動実行して初期化していましたが、この方法を使うとサブシステムのマスク編集の中で完結させることができます。
大変便利なのですが、ヘルプからこのやり方にたどり着くのは初心者には至難の業なので、自分用に記録しました。
どうやら正規表現と思っていたものはワイルドカードだった話

# モチベーション
シェル芸本を読んでいる最中、`.* 任意の文字列を指す`とあった。しかし、任意の文字列とは`*`単体ではなかったか？と思い調べてみた。

# 結論
`*`単体で表される文字列というのはワイルドカードのことであるとわかった。
ワイルドカードとは、`*:任意の文字列`と`?:任意の一文字`でパターンマッチをしてくれる記号で、正規表現とは全くの別物である。
なお、先程`.* 任意の文字列`と書いたが、その実態は`. 任意の一文字`と`* 直前の表現の0回以上の繰り返し`の合せ技によって、任意の文字列、ということになっているようだ。
Bootstrapのカードが横に並んでくれない

## Bootstrapのカードとは？
公式サイトでは、こんな感じでHTMLを記述すると、こんなカッコイイカードが作れるよ！っと説明されていました。
```html
<div class="card" style="width: 18rem;">
  <img src="..." class="card-img-top" alt="...">
  <div class="card-body">
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  </div>
</div>
```
▼できあがるカード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/f94ed648-88f5-1b14-0d76-fa7cb8b4e425.png)

ほぉ・・・カッコよ💛

## カードを横に3つ並べてみよう！

そんなわけで、上記HTML分をコピペして3つつなげたところ、カードが縦に3つ並びました。
ぃゃ💦そうじゃない！！！
私はカードを**横に3つ並べたかった**の！

ぐぬぬっという気持ちを抑えつつ、GTP先生やグーグル先生に色々聞いて、コードをあれやこれやしたけど一向に横に並ばないカードたち。

## 解決方法は公式に書いてあった

1時間ぐらいネットをさまよった結果、Bootstrapの公式にこのようなことが書いてありました。

> .card-deckを廃止し、グリッドを採用しました。カードをカラムクラスでラップし、親となる.row-cols-*コンテナを追加することで、カードデッキを再>現できます（ただし、レスポンシブな配置をより制御できます）。

え・・・グリッド使えばよかったん！？
以下のようにグリッドを設定することでカードが3つ横に並んでくれました＞＜
```
<div class="row">
    <!--カード１-->
    <div class="col">
        <div class="card"">
            <img src="https://placehold.jp/150x100.png" class="card-img-top" alt="...">
            <div class="card-body">
                <h5 class="card-title">🐶わんわん</h5>
                <p class="card-text">ワンコがたくさんいる世界にいきたい</p>
            </div>
        </div>
    </div>
    <!--カード２-->
    <div class="col">
        <div class="card"">
            <img src="https://placehold.jp/150x100.png" class="card-img-top" alt="...">
            <div class="card-body">
                <h5 class="card-title">🐈にゃーん</h5>
                <p class="card-text">ぬこが丸くなって寝てる姿に癒される</p>
            </div>
        </div>
    </div>
    <!--カード３-->
    <div class="col">
        <div class="card"">
            <img src="https://placehold.jp/150x100.png" class="card-img-top" alt="...">
            <div class="card-body">
                <h5 class="card-title">🐤カルガモ</h5>
                <p class="card-text">近所の池にたくさんいる。</p>
            </div>
        </div>
    </div>
</div>
```
▼3つカードが並んだ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/a2e79282-9c4c-7017-3bb1-4e92bfe17edc.png)

いないかもしれないけど、同じようなことで悩んでいる方がいれば・・・
アラームの停止機能


## 実装した機能
アラームが鳴っている間、ポップアップを表示する。
ポップアップのボタンからアラームを停止させる。

## 前提
アラーム音声は10秒毎に繰り返し再生される

## 作業
### ポップアップ表示
モーダルライブラリを使用しました。

``` node.js
npm install react-native-modal
```

``` react
import Modal from 'react-native-modal';
```
    
``` react
{showPopup && (
<Modal isVisible={showPopup} style={styles.modal}>
    <View style={styles.popupContainer}>
        <Text style={styles.popupText}>アラームを停止しますか？</Text>
        <TouchableOpacity
          style={[styles.popupButton, { backgroundColor: '#007AFF' }]}
          onPress={() => handlePopupButtonPress(stopAlarm)}
        >
          <Text style={styles.popupButtonText}>はい</Text>
        </TouchableOpacity>
      </View>
    </Modal>
  )}
```

### アラームの停止

1. 現在なっているアラーム音声の停止をおこなった。

    ``` react
    const stopAlarm = async () => {
        if (sound) {
          clearInterval(alarmIntervalId); // インターバルの停止
          await sound.unloadAsync();
        }
      };
    ```

    :::note info
    unloadAsync()は非同期関数だから、awaitがある？async()で囲っているのはなぜ？
    という疑問が湧いてきました。
    asyncとawaitについては、以下の記事がわかりやすかったです。    
 
https://zenn.dev/tentel/articles/8146043d1101b5ea873d


2. インターバルの停止
    10秒毎に音声を再生させていたため、そのsetInterval関数も停止した。

    ``` react
    import Modal from 'react-native-modal';
    
    const [alarmIntervalId, setAlarmIntervalId] = useState(null)
    
    const checkAlarms = async () => {
        for (const alarm of alarms) {
          const alarmTime = alarm.time;
          const currentTime = new Date();
    
          // アラームの設定された時間（時、分）が現在の時間と一致するかどうかを確認
          if (
            alarm.isActive &&
            alarmTime.getHours() === currentTime.getHours() &&
            alarmTime.getMinutes() === currentTime.getMinutes()
          ) {
            // 10秒ごとに音声を再生
            const intervalId = setInterval(() => {
              playAlarmSound();
            }, 10000);
    
        /// 中略 ///
        
            // stopAlarm() を呼ぶために intervalId を state に保存
            setAlarmIntervalId(intervalId);
          }
        }
      };
    ```
    ``` react
    const stopAlarm = async () => {
    if (sound) {
        clearInterval(alarmIntervalId); // インターバルの停止
        await sound.unloadAsync();
      }
    };
    ```


    :::note info
    intervalIDをわざわざコンポーネント外のステートに保存した理由は？
    ポップアップ画面でのボタン押下時にintervalIDを流し、clearIntervalでインターバルを止めるため。
    useStateに入れるのがbestかは不明。。
ABC056 ARC070 の問題を解いてみました


## A問題
https://atcoder.jp/contests/abc056/tasks/abc056_a

TopCoDeer くんが、 AtCoDeer くんの正体を言い当てているかどうかを判定します。
つまりは、a,b が等しいかどうかを判定します。

~~~C++
#include <bits/stdc++.h>
using namespace std;
//Created by karaju.

int main(void){
  char a, b;
  cin >> a >> b;
  
  if(a == b){ //正体を言い当てているなら
    cout << "H" << endl;
  }
  else{
    cout << "D" << endl;
  }
}
~~~

## B問題
https://atcoder.jp/contests/abc056/tasks/abc056_b

* すでに連結の場合
* 一つ目の長方形の左に二つ目の長方形がある場合
* 一つ目の長方形の右に二つ目の長方形がある場合

という三つの場合について考えます。
一つ目の場合は、0 と出力すれば良いです。
二つ目の場合は、$一つ目の長方形の左端 - 二つ目の長方形の右端$ を出力すれば良いです。
３つ目の場合は、$二つ目の長方形の左端 - 一つ目の長方形の右端$ を出力すれば良いです。

~~~C++
#include <bits/stdc++.h>
using namespace std;
//Created by karaju.

int main(void){
  int w, a, b;
  cin >> w >> a >> b;
  int a_right = a + w, b_right = b + w;
  //a,bの右側の位置を求めておく
  
  if(b_right < a){ // もし、a より b が左にあるなら
    cout << a - b_right << endl;
  }
  else if(a_right < b){ //もし、b より a が左にあるなら
    cout << b - a_right << endl;
  }
  else{ //すでに連結なら
    cout << 0 << endl;
  }
}
~~~

## C問題
https://atcoder.jp/contests/abc056/tasks/arc070_a


時刻$t$ には、 $\displaystyle\sum^{t}_{i = 0}i$ 以下の座標には辿り着くことが可能です。(1 ~ t の総和)
(細かく調整することができる)

なので、$\displaystyle\sum^{t}_{i = 0}i$ が初めて $X$ 以上になるときの t の値を出力すれば良いです。

~~~C++
#include <bits/stdc++.h>
using namespace std;
//Created by karaju.

int main(void){
  int x;
  cin >> x;
  
  int a = 0;
  for(int i = 1; true; i++){
    a += i;
    if(a >= x){
      cout << i << endl;
      return 0;
    }
  }
}
~~~

## D問題
https://atcoder.jp/contests/abc056/tasks/arc070_b
令和6年能登半島地震の募金先まとめ

令和6年能登半島地震の募金できるサイトまとめてみました。
　
Yahooのアカウント持ってないのでYahooは寄付しにくい、という声がSNS上にありましたので、
今回の寄付に関連するwebサービスや
寄附先の口座が書いてある記事をまとめました。
　
　
◇ 令和6年能登半島地震に係る災害義援金の受付について | 石川県
	　　URL: https://www.pref.ishikawa.lg.jp/suitou/gienkinr0601.html
　　・ 石川県の義援金振込先は2024/01/04 12時時点で義援金受付準備中。
　　・ 県への寄付は、寄附金控除及び損金算入できるので、今年の年末ふるさと納税で高い食べ物とか返礼品もらうよりは、こういう寄付も検討するといいかと。
	　
  　		
◇ 令和6年能登半島地震 緊急支援募金（Yahoo!基金） - Yahoo!ネット募金
	　　URL: https://donation.yahoo.co.jp/detail/1630064/
　　・ Tポイントでも寄付できる。
	　
  　	
◇ 楽天クラッチ募金-令和６年能登半島地震被害支援募金 | 楽天グループ株式会社
	　　URL: https://corp.rakuten.co.jp/donation/noto20240101_ja/noto20240101_ja.html
　　・ 楽天ポイントで寄付できるので、ポイント余っている方はこちらから。
	　
  　
◇ メルカリ寄付：令和6年能登半島地震への支援
	　　URL: https://donation.mercari.com/show.html?r=6p9gl1qg&id=01fb3cfz4pa43jd0wzydkjywjc
　　・ メルカリのアカウントや残高ある方はこちらからも寄付できるみたいです。
	　
	　
◇ 日本赤十字社
	　　URL: https://www.jrc.or.jp/
　　・ 2024/01/04 12時時点で義援金受付準備中。
		　
		　
◇ 令和6年能登半島地震について ―災害被災地支援情報 | お知らせ | 一般社団法人 日本経済団体連合会 / Keidanren
	　　URL: https://www.keidanren.or.jp/announce/2024/0104-131.html
　　・ 各支援団体の口座などが載っているので直接振込の方が安心できる方はこちら見て振り込むといいかと。
	　
		　	
◇ 【寄付募集】令和6年能登半島地震の支援金の募集について | 赤い羽根共同募金
	　　URL: https://www.akaihane.or.jp/news/34909/
　　・ ※令和5年石川県能登地震の寄付と間違えないように要注意です。
			　
			　
◇ 【令和６年能登半島地震】被災支援募金（GMO基金・マッチング寄付）の開始について | GMOインターネットグループ株式会社
	　　URL: https://www.gmo.jp/news/article/8766/
　　・ 自分の寄付金額と同じ金額をGMOさんが寄付（つまり倍になる。上限１０００万円）。
　　・ 口座振り込みのみ
		　
    　
◇ 【Makuake公式運営】令和6年能登半島地震災害支援募金｜マクアケ - アタラシイものや体験の応援購入サービス
	　　URL: https://www.makuake.com/project/donation-noto-earthquake/
　　・ クラウドファンディングサービス、makuake事務局が募金実施している
		　
    　
◇ DMM｜『令和6年能登半島地震 緊急支援（DMM.com被災地支援うわのせ募金）』を開設｜プレスリリース｜DMM Group
	　　URL: https://dmm-corp.com/press/corporate/3413/
　　・ 動画のチケット買うと寄付されるみたいな仕様。GMOさん同様、自分の寄付金額と同じ金額をDMMさんが寄付（つまり倍になる。上限１０００万円）。総額を日本赤十字社に寄付するらしい。
			　
			　
	　
　
注意点としては、
※寄付先は、去年の令和５年能登半島地震ではなく令和『6』年能登半島地震なので要注意。
※被災者を装った詐欺が多発しているので要注意。
※URLのドメイン名を確認し、フィッシング詐欺に要注意。
です。
　
　
他にも寄付できるサービスや団体があればコメントなどで教えてください。
　
　
-------
以下、寄付に関して、思うところ。
　
・人と比べて小さな金額だと自分の寄付金額をバカにしなくていいと思います。塵も積もれば山となりますし、「寄付した」という行動自体が大前提として素敵だと思います。
　
　
・やらない善よりやる偽善だし、寄付は偽善ではなく、普通に善だと思います。偽善だとひねくれた見方をしてしまう人の意見はスルーして、シンプルに自分が日々頂いているお金や価値を周りと分け合い感謝したいところ。
　
　
・ひっそり寄付して『シェアしない』のがかっこいいという古い文化がまだあるみたいですが、寄付金増やしたいなら非効率な考え方だと思います。今の時代は、SNSもITも浸透しているので、寄付したことをシェアし、良い影響を与える人をちゃんとリスペクトするような新しい文化になればいいなと。
　
　
そんなことを思いました。
　
　
私自身もっと多くの人の役に立てるように、仕事がんばります！
ステップイン、ステップアウト、ステップオーバーの違い

# ステップイン、ステップアウト、ステップオーバーの違い
エンジニア初心者の時に上司に「デバックして動き確認しといて」と言われ、何もブレークポイントを置かずにただ画面上の動きを確認していました。
※ブレークポイントを置いた行で、強制的に処理を中断することが出来ます。

そこで初めて「ステップイン、ステップアウト、ステップオーバー」を知り、感動したことを覚えています。ただ、最初の頃はよくこの3つの違いが分からず、全部ステップインでデバックしていて、F11をとにかく連打していました。
（※Visual StudioではF11がステップインのキーとなります。）

その様子を見た上司は、「ゲームじゃないんだから、、」と呆れていましたね。
僕と同じ恥ずかしい思いをしてほしくなく、これからデバックを学ぶ人向けに書いていきます。

こちらの記事は当時参考にした以下の記事を元に書いています。
[参考記事](https://penpen-dev.com/blog/steoin-stepout-stepover/)

前提として、以下のようなファイルを想定し、「main → parent → child」という順番で関数が動くような処理を行う状態です。

```js:debug.js
//main関数がまず動く
function main() {
	console.log("main: start");
	//parent関数が動く
	parent();
	console.log("main: end");
}

function parent(){
	console.log("parent: start");
	//child関数が動く
	child(); //ここにブレークポイントを置いた場合
	console.log("parent: end");
}

function child(){
	console.log("child: start");
	console.log("child: end");
}

```

このファイルを元に「ステップイン、ステップアウト、ステップオーバー」の違いを解説していきます。関数parentの中にある関数childの行にブレークポイントを置いた場合、以下のような動きになります。

* ステップイン：関数childの中に入り、関数childの1行目へ移動
* ステップアウト：関数parentを抜け、関数mainの最終行へ移動
* ステップオーバー：関数childの中に入らず、次の行へ移動

1つ1つ解説していきます。

## ステップイン
```js:debug.js
function main() {
	console.log("main: start");
	parent();
	console.log("main: end");
}

function parent(){
	console.log("parent: start");
	child(); //ここにブレークポイントを置いた場合
	console.log("parent: end");
}

function child(){
	console.log("child: start"); //ステップインだとここに移動
	console.log("child: end");
}
```

Step "In"なので、関数childの中に入っていきます。
次にフォーカスが当たるのが関数childの最初の行になります。

デバッガーは、呼び出された関数の最初の行でプログラムの実行を一時停止し、その関数内のコードを調査できるようにします。

## ステップアウト
```js:debug.js
function main() {
	console.log("main: start");
	parent();
	console.log("main: end");//ステップアウトだとここに移動
}

function parent(){
	console.log("parent: start");
	child(); //ここにブレークポイントを置いた場合
	console.log("parent: end");
}

function child(){
	console.log("child: start");
	console.log("child: end");
}
```

Step "Out"なので、今いる関数の外に出ようとします。
次にフォーカスが当たるのが関数mainの最終行になります。

デバッガーは現在の関数を終了するまでプログラムの実行を継続します。

これにより、現在の関数の残りの行をスキップして、呼び出し元に戻ることができます。


## ステップオーバー
```js:debug.js
function main() {
	console.log("main: start");
	parent();
	console.log("main: end");
}

function parent(){
	console.log("parent: start");
	child(); //ここにブレークポイントを置いた場合
	console.log("parent: end");//ステップオーバーだとここに移動
}

function child(){
	console.log("child: start");
	console.log("child: end");
}
```

デバッガーはコードの現在の行を「スキップ」し、次の行で一時停止します。

Step "Over"なので、今いる関数を超えてジャンプするイメージです。

次にフォーカスが当たるのが関数parent内にある関数childの次の行になります。

## まとめ
いかがだったでしょうか。

* ステップイン：関数childの中に入り、関数childの1行目へ移動
* ステップアウト：関数parentを抜け、関数mainの最終行へ移動
* ステップオーバー：関数childの中に入らず、次の行へ移動

デバッグ処理は、プログラム最適化、開発時間の短縮、信頼性向上、メンテナンス容易性の観点から、ソフトウェア開発において重要であり、品質向上と効率化を促進します。

ステップ処理をマスターして、つよつよエンジニアへ近づいていきましょう。