OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby・Rails】ダックタイピング

# ダックタイピングとは？

ダックタイピングはRubyのような動的型付け言語でよく使われるプログラミングの概念です。この概念は、「もしオブジェクトがカモのように歩き、カモのように鳴くなら、そのオブジェクトはカモである」という考え方に基づいています。つまり、オブジェクトの型よりも、そのオブジェクトがどのようなメソッドを持っているか（どのように「振る舞う」か）が重要とされます。

```ruby:ダックタイピングを使った例
# オブジェクトの型よりも、そのオブジェクトがどのようなメソッドを持っているか
# Duck, Lion, Sheep, Zekromはそれぞれquackというメソッド・振る舞いを持っている状態
class Duck
  def quack
    "クワ！"
  end
end

class Lion
  def quack
    "ガオー"
  end
end

class Sheep
  def quack
    "メェメェ"
  end
end

class Zekrom
  def quack
    "ババリバリッシュ!!"
  end
end

duck = Duck.new
lion = Lion.new
sheep = Sheep.new
zekrom = Zekrom.new

animals = [duck, lion, sheep, zekrom]

animals.each do |animal|
  puts animal.quack
end
# => "クワ！"
# => "ガオー"
# => "メェメェ"
# => "ババリバリッシュ!!"
```

```ruby:ダックタイピングを使わないとどうなる？
class Duck
  def quack
    "クワ!"
  end
end

class Lion
  def roar
    "ガオー"
  end
end

class Sheep
  def bleat
    "メェメェ"
  end
end

class Zekrom
  def scream
    "ババリバリッシュ!!"
  end
end

# ダックタイピングが存在しない場合、新しい動物クラスを追加するたびに、make_animal_soundメソッドに対する変更が必要になるというデメリットが発生
def make_animal_sound(animal)
  if animal.is_a?(Duck)
    puts animal.quack
  elsif animal.is_a?(Lion)
    puts animal.roar
  elsif animal.is_a?(Sheep)
    puts animal.bleat
  elsif animal.is_a?(Zekrom)
    puts animal.scream
  else
    puts "未知の動物です"
  end
end

# それぞれのクラスのインスタンスを作成
duck = Duck.new
lion = Lion.new
sheep = Sheep.new
zekrom = Zekrom.new

# 関数を呼び出す
make_animal_sound(duck)
make_animal_sound(lion)
make_animal_sound(sheep)
make_animal_sound(zekrom)
```

:::note info
### なぜ、新しい動物クラスを追加するたびにmake_animal_soundメソッドを変更する必要があることがデメリットになるのか？

**保守性の低下**
プログラムに新しい機能を追加するたびに、既存の関数やメソッドを変更する必要があると、そのコードは保守しにくくなる。特に大きなプロジェクトや多くの開発者が関わるプロジェクトでは、一箇所の変更が他の部分に予期せぬ影響を与える可能性があるため。

**スケーラビリティの問題**
システムが成長し、新しいタイプの動物が頻繁に追加される場合、そのたびに中央のmake_animal_soundメソッドを更新する必要がある。これはソースコードが複雑になり、ソフトウェアの拡張性に問題が出る(Aを変更したら、BやCを変更しなければならないが、そんなの覚えてないので、改修漏れが起きる)

**オープン/クローズド原則の違反**
「拡張に対して開かれているべきであり、変更に対しては閉じているべき」だが、case文の追加をする必要があるため、既存のコードの変更に対しては閉じているべき(=変更せずにいられるべき)に反する。
参考
https://qiita.com/zizynonno/items/4aed159690b74c84d058

**エラー発生の可能性**
既存のメソッドを頻繁に変更すると、新しいバグの導入や既存の機能の破壊のリスクが高まる。テストカバレッジが不十分な場合、これらのエラーは発見されにくい。
:::

ダックタイピングを使用すると、これらの問題を大幅に軽減できる。各クラスは独立して同じインターフェース（この例ではquackメソッド）を実装するため、新しい動物クラスを追加しても中央のメソッドを変更する必要がない。これにより、システムの拡張性が向上し、保守性が高まる。
Requirements of Vehicle Update and Configuration Management

Requirements of Vehicle Update and Configuration Management

https://www.autosar.org/fileadmin/standards/R23-11/AP/AUTOSAR_AP_RS_VehicleUpdateAndConfigurationManagement.pdf

<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words in order.

# Release Overviews
Classic Platform Release Overview, AUTOSAR No.0 ,R23-11, CP
https://qiita.com/kaizen_nagoya/items/8468435185e109189ead

Foundation Release Overview, AUTOSAR 781, R23-11, FO
https://qiita.com/kaizen_nagoya/items/f249bdb8c313d8bff883

Adaptive Platform Release Overview, AUTOSAR 782, R23-11, AP
https://qiita.com/kaizen_nagoya/items/13a104606a34fe24fcf7
# Terms

|terms(Acronyms and abbreviations)| Description|
|:--|:--|
|UCM| Update and Configuration Management
|V-UCM| V-UCM is distributing packages and coordinating an update campaign in a vehicle
|Backend| Backend is a server hosting Software Packages


# Reference
[1] Standardization Template AUTOSAR_FO_TPS_StandardizationTemplate

[2] Glossary AUTOSAR_FO_TR_Glossary
https://www.autosar.org/fileadmin/standards/R23-11/FO/AUTOSAR_FO_TR_Glossary.p
df

[3] Main Requirements AUTOSAR_FO_RS_Main


# 補足資料（Additions）

2023 Countdown Calendar 主催・参加一覧
https://qiita.com/kaizen_nagoya/items/c4c2f08ac97f38d08543

CountDownCalendar月間　いいねをいただいた記事群　views　順
https://qiita.com/kaizen_nagoya/items/583c5cbc225dac23398a

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)
ver. 0.01 初稿 　20231231
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Bubbleを転職先で使うので、特徴をざっくりとだけまとめてみた

## はじめに

はじめまして！
私は24年1月からBubbleを使った受託開発の企業で就業します:boy:

そこで、今回は数あるノーコードツールの中でBubbleとはどういう特徴があるか概要程度にまとめてみました！

さらに知りたい方は参考にした情報元を載せたので、そちらをご覧になってください:ok_hand:

## 目次

1. [Bubbleとは](#bubbleとは)
2. [Bubbleが得意な開発はWebアプリ](#bubbleが得意な開発はwebアプリ)
3. [学習者目線でのメリットとデメリット](#学習者目線でのメリットとデメリット)
4. [経営目線でのメリットとデメリット](#経営目線でのメリットとデメリット)

## Bubbleとは

Bubbleとは「ドラッグ&ドロップで高度なWebアプリを開発できるツール」です:point_up:

私も実務の開発はまだ経験していませんが、
本当にドラッグ＆ドロップで操作という感じでした！

データベースを組む際にも厳密に正規化をする必要がなかったりすることが多く、プログラミング言語を用いた開発と比べて、かなりお手軽です。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/b9e08360-6cb9-be28-2ecf-5fdaf5dbb3b0.gif">!

利用ユーザー数も300万人を超え、世界的に最も人気のあるノーコード開発ツールの1つとなっているそうです:family_mmbb:　

## Bubbleが得意な開発は「Webアプリ」

Bubbleが得意な開発領域はWebアプリだそうです。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/7050e453-f9cd-5efb-215e-818ee10d04f1.png">

そして、ここ最近では
Bubbleが本格的にネイティブアプリ対応することを発表しました。

ですので、ネイティブアプリにも強くなることが考えられます。

ちなみにSEOには弱いため、Webサイトで運用する際にはその辺りの対策が必要とされるそうです。

## 学習者目線でのメリットとデメリット

続いて学習者目線ではBubbleはどういうものなのか？
優れているところ、難しいところは以下となります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/2869f7c2-5ee5-c9da-247d-51b06c70978f.png">

私自身もBubbleを学習している中で、操作画面が全て英語であることもあってツールに慣れるまでには確かに少々時間がかかりました:sweat_smile:

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/b0c3887b-baa0-873a-a7f7-066dede5f048.png">

出典：[【プロが解説】ノーコードツールBubble(バブル)とは？デメリットからよくある質問まで完全解説](https://walker-s.co.jp/media/what-is-bubble/)

しかしながら、需要も伸びてきているらしいのでBubbleの技術を身につけてみるメリットはあると思います:point_up:

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/455551ab-ffce-f242-524d-22bb0c8a36dc.png">

出典：[アイ・ティ・アール(ITR)](https://www.itr.co.jp/topics/pr-20220217-1)

## 経営目線でのメリットとデメリット

では、経営目線でのBubbleはどういうものか？
優れているところ、難しいところは以下のようになります。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/c77ec5ef-2700-b92b-1eb1-9f1863d5ac84.png">

一番の大きな特徴としては、
開発コストがかなり低いながら、
大規模なものや複雑なアプリの開発は難しい点です。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113349/96a3aab0-96c1-2099-c9da-3fa205f8acfc.png">

出典：[【プロが解説】ノーコードツールBubble(バブル)とは？デメリットからよくある質問まで完全解説](https://walker-s.co.jp/media/what-is-bubble/)

逆にいうと小～中規模の開発はBubbleの真骨頂とも言えれるかもしれません:clap:

## Bubbleの開発事例一覧

Bubbleの開発事例です！
詳細を知りたい方はアクセスしてみてください

https://remote-hq.com/

https://prompt-laboratory.com/

https://lp.the-chekk.com/

https://syu1syain.com/

https://gururepo.studio.site/

簡潔に知りたい方はこちらの動画がオススメです:relaxed:

https://www.youtube.com/watch?v=5AuudTevgvI

## さいごに

いかかだったでしょうか？？
私はRailsで個人開発の経験はありながら実務での開発経験は無かったですが、それでも「ノーコードでここまで出来るのか!?:flushed:」となりました。

ノーコード開発に興味がある方はぜひ触ってみてください！

## 参考にした内容
https://walker-s.co.jp/media/what-is-bubble/

https://epic-s.co.jp/bubble-recommendation/

https://www.youtube.com/watch?v=B0YcMmhLkF4

https://www.youtube.com/watch?v=5AuudTevgvI
再帰を使用したDFSについて

## 問題 Leetcode 104. Maximum Depth of Binary Tree
バイナリ ツリーのルートを指定すると、その最大の深さを返します。

バイナリ ツリーの最大の深さは、ルート ノードから最も遠いリーフ ノードまでの最長パスに沿ったノードの数です。
Input: root = [3,9,20,null,null,15,7]
Output: 3

## 再帰
### コード
```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        int left=0, right = 0; 
        if(root == null) return 0;

        left = 1 + maxDepth(root.left);       
        right = 1 + maxDepth(root.right);

        return Math.max(left, right);
    }
}
```
実行時間：0ms
メモリー：43.00MB

### 挙動
①現在地：3
maxDepth(root.left)により、次のrootに移動
②現在地:9
maxDepth(root.left)により、次のrootに移動。

③現在地：null
移動先がnullのため、0を返す。

④現在地：9
0が返されたため、1+0になり、変数leftに1を格納する。

次にmaxDepth(root.right)が動き、次のrootに移動。

⑤現在地：null
このrootもnullなので、0を返す。

⑥現在地：9
0が返されたため、1+0になり、変数rightに1を格納する。

leftとrightどちらも1のため、Math.maxでは1になり、1を返す。

⑦現在地：3
maxDepth(root.left)の戻り値は1になり、1+1で変数leftに2を格納する

次にmaxDepth(root.right)が動き、次のrootに移動する。

⑧現在地：20
maxDepth(root.left)により、次のrootに移動する

⑨現在地：15
maxDepth(root.left)により、次のrootに移動する。

⑩現在地：null
rootがnullのため、0を返す。

⑪現在地：15
0で返されたため、1+0になり、変数leftに1を格納する
maxDepth(root.right)により、次のrootに移動する。

⑫現在地：null
rootがnullのため、0を返す。

⑬現在地：15
0で返されたため、1+0になり、変数rightに1を格納する
leftとrightは共に1のため、1を返す。

⑭現在地：20
1で返されたため、1+1により変数leftに1を格納する
次にmaxDepth(root.right)を動かし、次のrootに移動する

⑮現在地：7
maxDepth(root.left)により、次のrootに移動する。

⑯現在地：null
rootがnullのため、0を返す。

⑰現在地：7
0で返されたため、1+0になり、変数leftに1を格納する
maxDepth(root.right)により、次のrootに移動する。

⑯現在地：null
rootがnullのため、0を返す。

⑰現在地：7
0で返されたため、1+0により変数rightに1を格納する
leftとrightは共に1のため、1を返す。

⑱現在地：20
1を返されたため、1+1により、変数rightに2を格納する
leftとrightは共に2のため、2を返す。

⑲現在地:3
maxDepth(root.right)の戻り値は2のため、1+2になり、変数rightに3を格納する。

変数leftは2、変数rightは3のため、3を返す。
画像認識の処理の手順

画像認識は、コンピュータが画像や動画内の物体、パターン、特徴を、識別する事を言います。本記事では、画像認識の処理の手順に関して取り扱っていきます。

## 1: 画像の取得
目的: 画像の取得。
方法: WEBカメラ、デプスカメラ、画像、動画を取得して入力として使用。

## 2: 画像の前処理
目的: 画像を分析しやすくするために、ノイズを減らし、画像を標準化する。
手法: グレースケール変換、ヒストグラム均一化、ノイズリダクション、エッジ検出、リサイズ。

## 3: 特徴抽出
目的: 画像から識別可能な特徴を抽出する。
手法: エッジ検出、テクスチャ分析、形状抽出、カラー分析、SIFT（Scale-Invariant Feature Transform）、HOG（Histogram of Oriented Gradients）など。

## 4: 特徴選択/削減
目的: 分析のために最も有用な特徴を選択し、次元の呪いを避ける。
手法: 主成分分析（PCA）、線形判別分析（LDA）、オートエンコーダなど。

## 5: 分類/認識
目的: 抽出された特徴を使用して、画像内のオブジェクトやシーンを識別する。
手法: k-最近傍法、サポートベクターマシン（SVM）、ディープラーニング（CNN）、ランダムフォレストなど。

## 6: 結果の解釈と評価
目的: 認識結果を解釈し、性能を評価する。
手法: 混同行列、精度、リコール、F1スコア、ROC曲線。

## 7: フィードバックと改善
目的: システムの性能を改善し、より正確な認識を実現する。
手法: 追加データの取得、アルゴリズムの調整、新しい特徴の統合。

## 追加の処理
セグメンテーション: 画像を複数のセグメントに分割して、特定のオブジェクトや領域に焦点を当てます。（ROI）
データ拡張: トレーニングデータセットのバリエーションを増やして、モデルの一般化能力を向上させます。
オブジェクト追跡: ビデオ内でオブジェクトが時間と共にどのように動くかを追跡します。
podmanでdocker-composeの仕方

podmanでdocker-composeを動かす方法をご紹介します。

まず、`podman-compose`ライブラリを以下のコマンドでインストールします。
```
npm install podman-compose
```

その後、docker-compose.ymlファイルがあるディレクトリで以下のコマンドを実行すると、podmanの環境でdocker-composeを実行できます。
```
podman-compose up -d
```

以上です。ご視聴いただきありがとうございました！
Python3エンジニア認定基礎試験 勉強してみた2

# 「Python3エンジニア認定 ［基礎試験］」 合格を目指します。

使用教材：
・Pythonチュートリアル第4版 --オライリー・ジャパン--
・徹底攻略Python3エンジニア認定基礎試験 問題集 --impress--

前回の記事：
・[Python3エンジニア認定基礎試験 勉強してみた1](https://qiita.com/SHIRYU_0515/private/80be254354edc001258b)

こんにちは！
徹底攻略Python3エンジニア認定基礎試験 問題集を解きました。

第3章 **リストの操作**
**9問中6問正解！**
第4章 **判定と繰り返し**
**10問中5問正解**

間違えた所を確認していきます。

## 見直し
###### 【リストのスライス操作】
リストのスライス範囲は、「開始位置：終了位置」のように記述します。
開始位置を省略すると先頭からになり、終了位置を省略すると末尾までになります。
```
data = [|1,|2,|3,|4 |]
        0  1  2  3  4
```

###### 【append()メソッド】
リストの末尾に要素を追加するには、append()メソッドを使います。

リストに要素を追加する①
**リスト名.append(値)**

リストに要素を追加する②
**リスト名 +=  [値]**

###### 【短絡演算子】
不要な評価を省略して短絡する（一足飛びに結論を出す）演算子を、短絡演算子といいます。
例えば、A and Bは、次のように計算して結果を返します。

・Aを評価しその評価結果の真偽を判定する
・判定が偽であれば、Bを評価せずにAの評価結果を返す
・判定が真であれは、Bを評価しその評価結果を返す

**・andがずっと続く場合**
左から評価していき、「最初に偽」になった評価結果が最終結果になります。
すべて真の場合は、最後の評価結果が最終結果になります。
```ruby:例：andが続く場合
def num(value):
    return value

value1 = num(0) and num(1) and num(2)
```
```ruby:回答
value1 = 0
```
**・orがずっと続く場合**
左から評価していき、「最初に真」になった評価結果が最終結果になります。
すべて偽の場合は、最後の評価結果が最終結果になります。

```ruby:例：orが続く場合
def num(value):
    return value

value2 = num(0) or num(1) or num(2)
```
```ruby:回答
value2 = 1
```
###### 【Noneとの比較】
<table>
<caption>【コードと判定結果】</caption>
  <thead>
    <tr>
      <th>コード</th> <th>valueがNoneのとき</th> <th>valueがNoneでないとき</th>
    </tr>
  </thead>
  <tr>
    <td> if value: </td> <td>偽</td> <td>不定</td>
  </tr>
  <tr>
    <td> if not value: </td> <td>真</td> <td>不定</td>
  </tr>
  <tr>
    <td> if value is None: </td> <td>真</td> <td>偽</td>
  </tr>
  <tr>
    <td> if value == None: </td> <td>真</td> <td>偽</td>
  </tr>
</table>

###### 【range()関数】
range()関数は、整数を繰り返すオブジェクトを返す関数です。
```ruby:range()関数による数列の作成
range(stop)
range(start, stop)
range(start, stop, step)
```
```ruby:range()関数による数列の作成
r = range(3, 10, 3)
print(list(r))
```
```ruby:実行結果
[3, 6, 9]
```

###### 【enumerate()関数】
enumerate()関数は、for文と組み合わせることで、リストと文字列などの反復可能体からインデックスと要素を同時に取得できます。
**反復可能体**とは、for文による繰り返しが可能なもの
（リスト、タプル、ディクショナリ、文字列などのデータ型）を指します。

```ruby:書式：インデックスと要素を取得する
for i, elem in enumerate(iterable):
    print(i, elem)
```
```ruby:指定したインデックスの要素を取得する
for i, c in enumerate("WORD"):
    if i == 2:
        print(c)
```
```ruby:実行結果
R
```
###### 【sorted()関数】
反復可能体から昇順にソートしたリストを取得できます。
```ruby:書式：昇順のリストを取得する
sorted(iterable)
```
```ruby:昇順のリストを取得する
print(sorted("EAT"))
```
```ruby:実行結果
['A','E','T']
```
###### 【reversed()関数】
リストや文字列などから逆順したオブジェクトを取得できます。
```ruby:書式：逆順にしたオブジェクトを取得する
reversed(sequence)
```
```ruby:逆順のリストを出力する
print(list(reversed(sorted("EAT"))))
```
```ruby:実行結果
['T','E','A']
```
###### 【zip()関数】
複数の反復可能体から並列で要素を取得できます。
```ruby:2つのリストから要素を出力する
for n, c in zip([1, 2, 3],["1", "2", "3"]):
    print(c * n)
```
```ruby:実行結果
1
22
333
```

次の記事
[Python3エンジニア認定基礎試験 勉強してみた3](https://qiita.com/SHIRYU_0515/private/a267f9143b7dc1c92c21)
🐸PowerShellのビープ音で「カエルの歌」を奏でる🐸

# 概要

PowerShellのBeep音で音階を指定することができます。
それを利用し「カエルの歌」をBeep音で奏でるプログラムを作成します。

（本当に2023年最後の記事がネタ記事で良いのだろうか...

# 環境


- Windows: 10
- Powershellバージョン
```powershell
$ PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.3803
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.3803
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
```

# プログラム

下記プログラムが「カエルの歌」となります

```powershell:kaerunouta.ps1
$Rhythm = 1000

[Console]::Beep(262, $Rhythm/4) #ド
[Console]::Beep(294, $Rhythm/4) #レ
[Console]::Beep(330, $Rhythm/4) #ミ
[Console]::Beep(349, $Rhythm/4) #ファ
[Console]::Beep(330, $Rhythm/4) #ミ
[Console]::Beep(294, $Rhythm/4) #レ
[Console]::Beep(262, $Rhythm/4) #ド

Start-Sleep -Milliseconds ($Rhythm/4)

[Console]::Beep(330, $Rhythm/4) #ミ
[Console]::Beep(349, $Rhythm/4) #ファ
[Console]::Beep(392, $Rhythm/4) #ソ
[Console]::Beep(440, $Rhythm/4) #ラ
[Console]::Beep(392, $Rhythm/4) #ソ
[Console]::Beep(349, $Rhythm/4) #ファ
[Console]::Beep(330, $Rhythm/4) #ミ
Start-Sleep -Milliseconds ($Rhythm/4)

[Console]::Beep(262, $Rhythm/4) #ド
Start-Sleep -Milliseconds ($Rhythm/4)
[Console]::Beep(262, $Rhythm/4) #ド
Start-Sleep -Milliseconds ($Rhythm/4)
[Console]::Beep(262, $Rhythm/4) #ド
Start-Sleep -Milliseconds ($Rhythm/4)
[Console]::Beep(262, $Rhythm/4) #ド

Start-Sleep -Milliseconds ($Rhythm/4)

[Console]::Beep(262, $Rhythm/8) #ド
[Console]::Beep(262, $Rhythm/8) #ド
[Console]::Beep(294, $Rhythm/8) #レ
[Console]::Beep(294, $Rhythm/8) #レ
[Console]::Beep(330, $Rhythm/8) #ミ
[Console]::Beep(330, $Rhythm/8) #ミ
[Console]::Beep(349, $Rhythm/8) #ファ
[Console]::Beep(349, $Rhythm/8) #ファ
[Console]::Beep(330, $Rhythm/4) #ミ
[Console]::Beep(294, $Rhythm/4) #レ
[Console]::Beep(262, $Rhythm/4) #ド
Start-Sleep -Milliseconds ($Rhythm/4)
```

# プログラム説明

音楽はあんまり詳しくないので、表現や説明が間違っていたらご指摘ください。

### テンポ

`$Rhythm`を値を変更すると、音楽のスピードを変更することができます。

```powershell
$Rhythm = 1000
```

### 音符

`Beep()`でBeep音を鳴らすことができます。
第1引数は、音階です。＃や♭も数値を調整すればできます。
第2引数は、音の長さです。`$Rhythm/4`は4分音符を表しています。`$Rhythm/8`は8分音符になります。


```powershell
[Console]::Beep(262, $Rhythm/4) #ド
```


### 休符

`Start-Sleep`を使って音のなっていない時間を表現しています。
`$Rhythm/4`は四分休符です。

```powershell
Start-Sleep -Milliseconds ($Rhythm/4)
```


# 実行方法

### 其壱） ファイルを作成し、右クリックから、「PowerShellで実行」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/65b975a1-e5b4-4114-924e-40b539d9deb3.png)

### 其弐） 実行ポリシーの変更が出たら**Y**または**A**を入力しEnter


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/73479486-aa48-b909-4675-98dad8f8a35b.png)


これでカエルの歌が聞こえてきます。（2回目以降は、其弐の手順が不要となります）


# おわりに

年を跨ぐときにカエルのようにジャンプはしませんが、今年は頑張ったので、おいしい料理を食べたいと思います。

**2024年もよろしくお願いいたします！**

**ここまで読んでいただきありがとうございました！**
特定の人のIPアドレスをアクセス拒否にしたい【Wordpress】




# 問題
特定の人のIPアドレスをアクセス拒否にしたい

# 原因

お問い合わせなどで同じIPの人からスパムメールが来るなど


# 対処法

### １　利用サーバー上ではずすコードを追加する(.htaccess)


ただし、.htaccess ファイルを編集する際にエラーが発生するとサイトにアクセスできなくなる可能性があるため、慎重に作業することが重要らしい。

apacheというプログラミング言語を使えばいいらしいです。

具体的な編集方法については下記にあったので参考まで

https://www.wpx.ne.jp/old_server/manual/wordpress_setting_htaccess.php

https://www.xserver.ne.jp/manual/man_server_htaccess.php

それぞれ自分の使っているレンタルサーバーのページが多分あるのでそこから編集方法を学びましょう。

####  .htaccess ファイルをバックアップしてから編集
失敗したら取り戻せないので、バックアップはとっておきましょう。

#### 下記のようなコードを追加
（XX.XX.XX.XX の部分をブロックしたいIPアドレスに置き換える）。

~~~
<RequireAll>
    Require all granted
    Require not ip XX.XX.XX.XX
</RequireAll>
~~~

これで完了。
２つ以上ある場合は

~~~
<RequireAll>
    Require all granted
    Require not ip XX.XX.XX.XX
    Require not ip YY.YY.YY.YY
    Require not ip ZZ.ZZ.ZZ.ZZ
</RequireAll>
~~~

のように行を追加していく。

### ２　プラグインを使って国ごとBan

Wordpress上でどうしてもやりたいなら思った以上に広範囲ですが
でも、国際的にいろいろな世界の人から自分のウェブページを見てほしいならあまりお勧めできないかもしれない。

色々ありますが、下記とかが著名だと思います。

IP2Location Redirection
https://wordpress.org/plugins/ip2location-redirection/



# Memo/Comment
Wordpress上のHtmlコードを修正しても意味がないようです。
それ以外にもっと簡単にスパムを防ぐルールを見出すのがいいかもしれない。（例えば、問い合わせ系なら何行以下はスパム扱いするなど

でもこれは
ChatGPT的には

>>ただし、この方法は完全なセキュリティ対策とはなりません。ユーザー側の制御であり、ブラウザやJavaScriptの機能を利用しているため、ユーザーがブラウザのデベロッパーツールなどを使って簡単にバイパスすることができます。真のセキュリティを求めるのであれば、サーバーサイドでのバリデーションが必要です。
>ブラウザのJavaScriptでユーザーが２行以上の文章を入力しないように制限するには、フォームの送信をトリガーする前に入力されたテキストの行数をチェックすることが必要です。以下は、簡単な例です。

html
~~~
<form id="myForm">
  <textarea id="message" rows="4"></textarea>
  <input type="submit" value="送信">
</form>

<script>
document.getElementById('myForm').addEventListener('submit', function(event) {
  var message = document.getElementById('message').value;
  var lineCount = (message.match(/\n/g) || []).length + 1; // 改行の数 + 1 で行数を取得

  if (lineCount < 2) {
    alert('２行以上の文章を入力してください');
    event.preventDefault(); // 送信を中止
  }
});
</script>

~~~

>このコードでは、フォームの送信が行われる前に、テキストエリア内のテキストの行数をカウントしています。改行の数を基に行数を計算し、もし２行未満の場合は送信を中止し、アラートを表示しています。

ほかにも迷惑メール系ならRecapchaを導入すればよさそう。

https://contactform7.com/ja/recaptcha/

https://lpeg.info/wordpress/recaptcha.html
第1回　StreamlitとLangChainとLM studioを使って自分専用LLMウェブアプリを作りたい！

# やりたいこと

LLMで自分専用のwebアプリを作成したい！

こんにちは。今日は備忘録もかねて2023年、年末年始に勉強することをまとめさせて頂きます。
また、これは私の取り組みを記載するので、これを読んだからといって直ぐに表題の内容が作成出来るようになるわけではありません。私が途中で飽きないための、報告になります。
１週間ごとに進捗報告も兼ねて記事にして行きます。

皆さんはChatGPTは利用されていますか？私自身ChatGPTProにしたり、APIに課金して遊んでいます。
しかし、やはり値段が気になる...
できれば、自分のメールやカレンダー、Obsidianのメモ内容をもとに返答をして欲しい..
そこでMemGPTなどを使って個人に最適化された秘書GPTを作成したい、と考えています。
そちらも頑張りますが、やはり自分専用の秘書を作成したい。
楽をしたい...
そこでLocal LLMを使った秘書を作成します！（きっと）
このあと、私の作成したいものは「秘書GPT」と呼称します。

# 具体的には？
今現在私が行いたいことは以下の3点です。
1,日本語対応したLLMをローカルサーバーで動かす
2,１の成果によってスマホからもパソコンからも秘書GPTにアクセスできるようにする。
3,秘書GPTに雑務を丸投げできるようにする。（情報収集や予定の管理など）

# そのために必要なこと
1,自分だけがアクセス出来るLLMローカルサーバーの構築（無知！）
2,カレンダーやメール、Obsidainの内容を秘書GPTに教える方法（どうやって情報にアクセスさせるのか？APIやそれ以外の方法）
3,情報収集ツールとしての利用（RSSやウェブスプリングを使って、私専用の情報収集もして欲しい）


# 次のアクション
https://blog.streamlit.io/
1,streamlitにLangChainを使ったwebアプリについての紹介記事があるので、触ってみます。
2,自分でも簡単なstreamlit上で動くwebアプリのデモを作成します。出来次第GitHubに公開予定です。
【Docker Rails】HerokuのclearDBのIgniteプランが終了するそうなので、renderに移行した話

## 前提
最近、こんなメールが届きました。

>Dear Valued ClearDB Customer,
We are improving and modernizing our ClearDB platform. As result, the Ignite Plan that you are currently subscribed to will be retired on January 15th, 2024. If you would like to continue using ClearDB MySQL databases, you will need to upgrade to the Punch Plan which is $9.99 per month. 

翻訳
>ClearDBをご愛顧いただいている皆様へ、
弊社は ClearDB プラットフォームの改善と近代化を進めております。そのため、現在ご契約いただいている Ignite プランは 2024 年 1 月 15 日に終了いたします。引き続きClearDB MySQLデータベースをご利用になりたい場合は、月額$9.99のPunchプランにアップグレードする必要があります。

ほとんど無料で運用していたアプリにお金がかかってしまうため、何らかの対応をする必要がありました。
以前、renderを使用したことがあったので、移行した際のことをまとめます。

:::note warn
注意
:::

- DBにはほとんどデータがなかったので、中身に関してはまっさらにしました
- 移行の際は慎重に注意して自己責任で行ってください
- 若干日が空いて書いているので、間違っている箇所などあればご指摘お願いします

## 元の環境
HerokuにDockerコンテナをデプロイして、DBはMySQLでclearDBのアドオンを使用していました。

```yml
build:
  docker:
    web: backend/Dockerfile
run:
  web: mkdir -p tmp/pids && mkdir -p tmp/sockets && bundle exec puma -C config/puma.rb
```

こんな感じでHeroku用の`heroku.yml`をアプリケーションのルートに配置することでスムーズにデプロイできました。

詳しいことは次の記事で書いています。

https://qiita.com/yuki82511988/items/9c06f844b19f768126c1

## 次の環境
Renderのドキュメントを読んでみると、Dockerに対応していそうでした。
https://docs.render.com/docker

ので、やってみる。

### Gemfileの設定

```Gemfile
gem 'pg'
```

ポスグレが確か無料だったと思います。これを機にローカルもMySQLのコンテナを無くしてポスグレにしました。
https://docs.render.com/databases

### bin/render-build.sh を作る

```sh
#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
bundle exec rake db:migrate
```

https://docs.render.com/deploy-rails#create-a-build-script

### secret_key_baseの設定
`credential.yml.enc`を作成して、secret_key_baseをrenderの`SECRET_KEY_BASE`に設定しました。

もともと自分は知っていたのでコマンドをピッと実行しましたが、詳しくは次の記事をご覧ください。
DockerでRails動かしている場合は、vimとか使いたい際にインストールしておくのが必要だったと思います。

参考にさせていただきました🙏
https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39

### config/database.yml をいじる

```yml
production:
  <<: *default
  adapter: postgresql
  encoding: unicode
  url: <%= ENV["BACKEND_DATABASE_URL"] %>
```

DBもrenderで作成したので、passwordとかuserがまとまっているURL1つで設定が完了しました。
もともと user passwordとかを分けて書いていたはず。

### 環境変数
DBのURLとSECRET_KEY_BASEに加えて、`RAILS_ENV`をproductionにしました。

## デプロイ
こんな感じで設定できたら、renderでDBを作成し、アプリケーションをリリースすることで問題なく動きました 🎉

雑な記事でしたが、どなたかのためになれば幸いです🙏
DevRelチーム振り返りとスカウトでの知見共有

# 自己紹介
初めまして、株式会社LabBase Developer Relations（以下、DevRel）チームの平塚です。
この記事は[『技術広報 Advent Calendar 2023』](https://qiita.com/advent-calendar/2023/tech_pr)の17日目の記事として書きました。

弊社のDevRelチームはLabBaseのエバンジェリストとして、Tech PR活動と採用を推進するチームで、その中でリーダをしております。
発足間もないチームですが、その振り返りとして、スカウト活動で得た知見をお伝えできればと思っています。

いきなりですが、本題に入る前に、DevRelチームとして私が大事にしていることをお伝えさせてください。
それは、**自らの会社について 「情報をただ伝えるだけでなく、自分の言葉で解像度高く熱量を持って語れるようになること」** です。
スピード感を持って少数精鋭のチームで最大効果を上げていくために、母集団形成やスカウト、面談やその後のフォローまで全ての接点で、全員が純度高くこれを実行できることが大事だと日頃感じています。
自らが語れる採用広報を目指している私たちのチームですが、チーム発足から3ヶ月の取り組みを振り返りながら、良かった結果をシェアしたいと思います。
この記事は採用広報に携わる方だけでなく、広くエンジニア採用に携わる方の気づきや議論のきっかけになれば幸いです


# 本題
本日のテーマは「スカウト返信率を改善するための施策」に関してです。
弊社は、現場エンジニアを中心にスカウトを行っていますが、その中で以下の課題がありました：

* 目指す反応率に対してスカウト量の適性が不明確
* スカウト返信率が10%程度と低い

そこに対して考えた仮説は以下の通りです：

* スカウト本数が足りない（目標反応率に対して、スカウトの本数が足りないのではないか？
* スカウト文（候補者に魅力的な文章になっていないのではないか？）
* 条件（他社と比較して条件がマッチしていないのではないか？）
* タイミング（スカウト送付している候補者さんが返信したいタイミングではない？）

これらに対して、それぞれアクションを起こしていきました。
スカウト文や条件をブラッシュアップしてく中で、返信率の改善は見られたものの期待するほどのものではありませんでした。
そのため、「私たちがスカウトしたい候補者は多くスカウトを受け取っており、他の返信で手一杯になっている」と仮定し、候補者さんが登録や更新したタイミングで最速でアプローチすることを目指して、スカウト方法やチームの動き方を変えていきました。
また、タイミングに関して言及している投稿が少なかったのも今回投稿のきっかけになりました。

皆さんも転職メディア上で候補者さんが転職意欲を書き換えたタイミングで通知が来るな設定していると思いますが、どのくらいで行動に移しているでしょうか？
弊社はこれまでは、送付可否から文章を考えアプローチという流れを経て数時間もしくは翌日にアクションという手法でしたが、候補者さん転職意欲書き換え後の**5分以内にアプローチ** を目標としました。
この5分を実現するためにはワークフローや体制構築が必要になりますが、大事なのは候補者さんに一番最初に声をかけた会社になることだと考えています。
文章を5分で作成することが難しいと思われるかもしれませんが、判断完了後にまずは声をかけ、具体的な内容は後追いでも問題ありません。

このような試行錯誤の結果、以下の成果を得ることができました：

* 返信率の上昇（三ヶ月間で返信率が10% 〜 20%の上昇）
* 採用の加速（通年の採用目標に関して、半期で達成できる速度）
負担がかかる運用でしたが、スカウト返信率を上げるために一緒に頑張ってくれたDevRelチームのみんなにお礼を伝えたいとともに、より型化してサステナブルな運用をしていくことも今後の課題です



# 最後に
これまでは短期採用目標達成に向けて即効性のある改善策を打ってきました。
来年はさらに社内外に向けて発信を行い、自社の採用に対する中長期的な投資をしていきたいと思っています。
採用広報の真髄である広報活動を強化し、会社の魅力を伝え、働きたい！と思ってもらえる仲間を増やしていく。
その結果、自主応募をたくさんしていただけるような情報発信の取り組みをたくさんトライしていく年にします。
そのためには私たちのチームも、もう一段レベルアップをしたいと思っています。
例えば、採用に対する評価制度のアップデート、強いチームに向かうためのカルチャーの浸透、自社のプロダクトに閉じないITリテラシーの強化など、まだまだ私たちは強くなれると考えています。
宣伝になってしまうのですが、チーム発足からこの短期間でトライを重ねてきた魅力的なチームの進化はこれからです。
どうか、力を貸してやってもいいぞ！という採用広報のみなさん、ぜひカジュアルに意見交換できると嬉しいです。
一緒にエンジニア採用を盛り上げていきましょう。
最後までお読みいただきありがとうございました。
VSCodeの拡張機能でアウトラインに関数の一覧を表示する

# はじめに
VSCodeの拡張機能を紹介する記事は多いのですが、そのような記事ではほとんど紹介されていなかった、私が欲しくて便利だと思った拡張機能を紹介します。

#### 欲しかった機能
関数の一覧を表示させて、自由にジャンプできるようにしたかった。
標準のアウトラインにも同様の機能はあるが、アウトラインの一覧に変数も表示されて鬱陶しかったので、純粋に関数だけの一覧を表示させたかった。


# Outline Map

https://marketplace.visualstudio.com/items?itemName=Gerrnperl.outline-map

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/2f4d2536-eea1-b63b-c118-4c1733245ca0.png)


# おすすめの設定

#### WORKSPACE をメインに使う

並び順の見出しをWORKSPACEのタブをドラッグしてWORKSPACEをOUTLINEの上に表示させる
＞WORKSPACE
＞OUTLINE

WORKSPACEだと一度表示させれば、編集タブでファイルを閉じても、すぐにジャンプできる
OUTLINEだと開いているファイルのシンボルしか一覧に表示されない

<br>
設定項目の Workspace: Include Symbols で
Function 
を追加 
必要に応じで
Method 
Event
等も追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/d604eabe-593c-9884-8bdb-c06f4f46cdd6.png)
SOP8変換

SOP8のFlashをDIPに変換して使うことがあります。以前はこんな風にしていました。

![写真（2023-12-31 9.09）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c5672223-0f2a-4039-e29b-81da471b489e.jpeg)

![写真（2023-12-31 9.09） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/fc87095b-52d6-79a3-4105-a8b8b9b182ff.jpeg)

秋月電子で販売されている基板用リードフレームを使うとちょっと小さくなります。

![写真（2023-12-31 9.10）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d3f5d044-43a0-5d4b-bb54-9fdcc600d864.jpeg)

今朝思いついたのですが、抵抗などのきったリード使ってみました。

![写真（2023-12-31 9.10） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c8d21934-ccac-f3d8-1b47-d318f5f24d9b.jpeg)

いったんDIPの丸ピンソケットにリードを立てて、変換基板を乗せてハンダ付けします。費用もかからずいいです。

一番上の基板はおそらくAitendoで購入したもので、下の二つは秋月電子のものです。秋月電子の変換基板は8MのFlashをつけるとちょっと足が窮屈です。

忘れていましたが、こんなのも作っていました。

![写真（2022-07-01 6.21）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/59d96d57-f820-cfeb-2f3f-7d51bcd53117.jpeg)

こんなのもありました。

https://qiita.com/yamori813/items/65667a14a939b7a877d3
Apex Class パブリック、プライベート、グローバルの使い分け


+ [when to use public,private,global](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T4QxSSAV)
+ [What is difference between public and global class in Salesforce Apex ?](https://www.forcetalks.com/salesforce-topic/what-is-difference-between-public-and-global-class-in-salesforce-apex/)


**パブリック**
これは、このアプリケーションまたは名前空間内のすべての Apex でメソッドまたは変数を使用できることを意味します。

**プライベート**
このキーワードは、内部のユーザーから見えるメソッド/変数を定義します。
定義する Apex クラスのクラス。

**グローバル**
これは、同じアプリケーション内の Apex コードだけでなく、クラスにアクセスできるすべての Apex コードでメソッドまたは変数を使用できることを意味します。このアクセス修飾子は、SOAP API または他の Apex コードのいずれかで、アプリケーションの外部で参照する必要があるメソッドに使用する必要があります。メソッドまたは変数をグローバルとして宣言する場合は、それを含むクラスもグローバルとして宣言する必要があります。

 

グローバルの使用例は Batch Apex です。Apex ジョブの実行へのアクセスを管理できます。同様に、ジョブを実行する管理者は、任意のアプリケーションのコンテキスト内でジョブを実行できます。


+ [エクスペリエンスクラウド上でAuraからApexを読み込む場合はApexクラスとメソッドをglobalにする？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Vhfz9)

:::note
第 2 世代管理パッケージの説明の中に、関連しそうな記述があります。

グローバル宣言されていると制約がないみたいですね。

 The @NamespaceAccessible makes public Apex in a package available to other packages that use the same namespace. Without this annotation, Apex classes, methods, interfaces, and properties defined in a second-generation managed package aren’t accessible to the other packages with which they share a namespace. Apex that is declared global is always available across all namespaces, and needs no annotation. 

https://developer.salesforce.com/docs/atlas.en-us.pkg2_dev.meta/pkg2_dev/sfdx_dev_dev2gp_namespace_visibility.htm
:::


:::note
Experience Cloudから呼び出するApexはPublicで動きます。

というのが前提となります。以下のURLのソースでExCloudからPublicで呼び出すことが可能であることを確認することができました。

https://developer.salesforce.com/docs/atlas.ja-jp.communities_dev.meta/communities_dev/communities_dev_sample_code_without_sharing__let_guest_users_create_and_read_records_in_the_same_transaction.htm?q=aura

悩んでSFさんに聞いてみたら上記のURLのサンプルソースみて動くの確認できたので、Publicでもいけるんです！そこでまったく新規で同じ処理書いて、Publicにしたら動きました。なんじゃこれ？って感じですが、、、新規作成したら解決しましたです！

同じ事象が発生したら、ぜひ新規で作ってみてください。
:::

+ [該当のコンポーネントを読み込むことができませんでした。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Vhg7j)

:::note
★新規作成したら解決しました★！
つまり原因不明なんですね～。 

同じ事象が発生したら、ぜひ新規で作ってみてください。
:::
CourseraなどMOOC講座の履歴書への書き方が知りたい。結論：資格欄に書ける！

Coursera、edxなどの修了証は資格欄に書けるのでしょうか？以下の記事で認定資格と書かれています。Googleが公式で認定証が認定資格であることを明記していますね。

https://grow.google/intl/ALL_jp/certificates/?tab=google-career-certificates

dodaの転職サイトでGoogleデータアナリティクス認定資格と公式で書かれていたので調べてみました。すると以下の記事がトップに出てきます。読んでみた限りcourseraの修了証は資格とみて間違いないようです。



<p><a href="https://jp.indeed.com/career-advice/career-development/is-google-data-analyst-certification-worth-it">Googleデータアナリティクス認定資格とは？取得すべきかどうか内容を解説！</a></p>

リクルートもGoogle UX Design Certificateを公式で認定していますね。

資格欄に記載する際は、以下の点に注意しましょう。

・資格名を明確に記載する
・取得年月を記載する
・講座名を記載する（任意）
具体的には、以下のようになります。

2023年12月　Googleデータアナリティクス認定資格取得

また、修了証を提出できる場合は、合わせて提出しましょう。


6ヶ月程度かかる講座であれば、普通に出回っている簡単な資格より修了するのは大変です。そのため、資格欄に記載することで、自分のスキルや意欲をアピールすることができます。今回は求人サイトの公式の認定資格を資格の例としてGoogleの一部講座が挙げられていたのでGoogleの講座を上げましたが、IBM、Microsoft、Amazon、Metaのコースも企業に入るうえで役立つでしょう。なぜなら企業が出しているコースは実務に即したコースになっているかもしれないからです。大学のコースもスタンフォードなどの有名大学が監修している講座であれば採用担当様の目に留まるかもしれません。いずれにせよMOOC講座を選ぶ際はどのようなキャリアを歩みたいかで決めるとよいです。

ここで資格欄にかけるcourseraの修了の講座は何でしょうか。以下サイトで調べました。

https://www.coursera.org/browse

書かれているプロフェッショナル認定証の説明を書きます。
新しいキャリアを始めようとしている方も、現在のキャリアを変更しようとする方も、Courseraのプロフェッショナル認定は、仕事の準備をするのに役立ちます。トップレベルの企業や大学から自分のペースで学び、新しいスキルを潜在的雇用者に自分の専門知識を示す実践プロジェクトに適用し、新しいキャリアを始めるためのキャリア資格を獲得します。

資格と書かれていますね！Professional certificate(プロフェッショナル認定証)が資格欄にかけると考えてよさそうです。

ただし、資格欄に記載する際は、講座の内容や難易度を踏まえて、自分のスキルや経験に合ったものを選ぶようにしましょう。それに関しては国家資格も応募する仕事に合ったものを記載する場合もあるので同じですね。他の資格と合わせて記載することで、より説得力のあるアピールになります。なお、Coursera、edXなどのオンライン講座の修了証は、必ずしも資格として認知されているわけではありません。そのため、転職活動の際には、企業に事前に確認しておくとよいでしょう。coursera, edx Udacity, Sophia, Great learningの修了証を資格欄に書いてアピールしましょう！
UbuntuでFTPサーバを用意してみる（Pure-ftpd, docker）

記載日 : 2023/12/31

備忘録として、FTPサーバを用意する手順を記載します。
なお、FTPサーバは　stilliard/docker-pure-ftpd　のdocker imageを使って起動します。

## 環境
OS : Ubuntu 22.04
dockerインストール済
docker-composeインストール済
VSCodeインストール済（拡張機能からGit Graphをインストール済）

## ファイル構成
project
　|
　|- docker-compose.yml
　|
　|- sample.txt


## 作業 (計8分)
### 0.FTPサーバへアップロードするファイルを作成する (2分)
sampple.txtをあらかじめ用意する。
~~~
test1
test2
~~~

FTPサーバの動作確認をするために、lftp（FTPクライアントツール）をインストールする。
~~~
sudo apt update
sudo apt install lftp
~~~


### 1.FTP用のdocker composeファイルを作成する (2分)
FTPサーバを用意するにあたり、stilliard/pure-ftpdのdocker imageを使ったdocker-compose.ymlファイルを作る。ファイルの記述は以下の通り。
なお、30000～30009のポートは、このDockerイメージのデフォルト・パッシブ・ポートがアサインされているために必要らしい。

~~~docker compose
version: '3'
services:
  ftp_server:
    image: stilliard/pure-ftpd
    container_name: ftp-server
    ports:
      - "21:21"
      - "30000-30009:30000-30009"

    environment:
      - PUBLICHOST=127.0.0.1
      - FTP_USER_NAME=uname
      - FTP_USER_PASS=uP@ssw0rd
      - FTP_USER_HOME=/home/ubuntu　 # "/"だけだとFTPサーバへログインできない

    restart: always
~~~

docker-compose.ymlファイルが容易で来たら、以下コマンドでFTPサーバを起動する。
~~~
docker compose up -d
~~~


### 2.FTPサーバへのファイルアップロード （2分)
lftpを使ってFTPサーバへログインし、任意のディレクトリにsample.txtファイルをアップロードする。
~~~
lftp  # lftpのターミナルが開く
lftp:~>  open -u uname,uP@ssw0rd ftp://localhost/  # ログイン
lftp:~>  mkdir files  # FTPサーバにディレクトリ作成
lftp:~>  cd files  # 移動
lftp/files:~>  PUT ./sample.txt  # sample.txtをFTPサーバへアップロード
lftp/files:~>  exit
~~~


### 3.動作確（ファイルダウンロード）（2分)
それでは、FTPサーバのsample.txtをダウンロードしてみようと思う。
curl -u [username]:[password] -o [/path/to/download] [ftp://url/to/uploadedfile]　のコマンドでファイルをダウンロードする。
~~~
curl -u uname:uP@ssw0rd -o ./sam.txt ftp://localhost/files/sample.txt
~~~
あるいは、lftpでダウンロードすることもできる。
~~~
mkdir download
cd download

lftp
lftp:~>  open -u uname,uP@ssw0rd ftp://localhost/
lftp:~>  get ./files/sample.txt
lftp:~>  exit

ls  # sample.txtが表示され、ダウンロードできているのを確認できる。
~~~


## 参考にさせて頂いたサイト
・Pure-ftpdとは
https://wiki.archlinux.jp/index.php/Pure-FTPd

・Pure-ftpd Serverのdocker image
https://github.com/stilliard/docker-pure-ftpd

・dockerインストール後に、docker composeコマンドでpermission denyエラーが出るのを解決する
https://qiita.com/Nw3965/items/8e75da0012cb7a451cc2
p5.js の createGraphics()（オフスクリーンキャンバス）で translate() などを適用した場合の注意点： reset() によるリセットが必要

Qiita で以下の記事を書いた時などに、記事内で書いている話を、独立した記事に書きます。

●p5.js で createGraphics() の描画領域を見えるようにして利用してみる（＋ 特定の処理に関して明示的なリセットが必要な話）【小ネタ】 #JavaScript - Qiita
　https://qiita.com/youtoy/items/5c853cfd5dfe9e94702d

たまに、「p5.js の createGraphics() で translate() などを使った時、draw() の冒頭でリセットがかからない場合の対処って、どうやるんだっけ？」と思うことがあるので、見つけやすいように独立させた記事にしました。

## リセットを行うという話
冒頭で紹介した記事の以下で書いているのが、今回の記事のトピックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b8c85616-641d-d086-3c90-efa4af0a6aab.png)

例えば、以下のような処理を行った場合に、意図しない動作になります。

```javascript
function setup() {
  ...
  pg = createGraphics(400, 400);
  ...
}

function draw() {
  ...
  pg.translate(width / 2, height / 2)
  ...
}
```

自分が上記の書き方をする場合、 `pg.translate(width / 2, height / 2)` で意図した処理は、draw() が実行される時に毎回、オフスクリーンキャンバスの中心へ原点を移動させる、というものです。
しかし上記を実行すると、draw() が実行されるたびに原点が、右下へと移動していってしまいます。

その対処法は、以下のように reset()　を行う事です。

```javascript
function setup() {
  ...
  pg = createGraphics(400, 400);
  ...
}

function draw() {
  ...
  pg.reset()
  pg.translate(width / 2, height / 2)
  ...
}
```

p5.js公式のリファレンスでの、reset()　の説明は以下です。

●reference | reset()
　https://p5js.org/reference/#/p5.Graphics/reset

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/268492af-ffb9-4c21-1eed-42367c89af7e.png)

「Transform」と「Lights」のカテゴリの処理を、意図的にリセットする処理になります。

## 余談： 別の reset()
以下は余談です。

今回の記事を書いていて、p5.js の reset() に関して、上記と別の reset() が出てきました。

●reference | reset()
　https://p5js.org/reference/#/p5.Image/reset

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f27a1e0d-d0cb-34e4-045c-1b7f564deda3.png)

本記事のトピックで扱った reset() は、p5.Graphics に関するものですが、上記のものは p5.Image に関するものでした。上記のほうは、GIF のアニメーションを最初のフレームに戻す、というものになるようです。
プログラミングテクニック　最大倍数の求め方

### 整数Nを超えないMの倍数の求め方
N=7,M=3で考える。
0から７の間に３を何回加算できるか考えると

7　/　3　= 2

2回なので

3 × 2　= 6

と求めることができる。

Nが負の場合で同じ式に当てはめると

N=-7,M=3で考える。

-7 / 3 = -2

3 × -2 = -6

と求まる。

この値は-7を超えた値となる。
欲しい値は-9であった。
つまりNが負の数では成立しない。

N以下の倍数Mの値との距離は以下の式で求めることができる。

(N % M + M) % M　 ・・・・・・・・・・①

①を用いると

-7 - (-7 % 3 + 3) % 3 = -9

と想定通りの値を得られる。
Nが正の場合でも成立する。
引継ぎで実施しておきたいことまとめ


先日、プロジェクト参画3ヶ月めにして、協力会社さんの契約終了が決まり、諸々引継ぎを受ける必要が出てきました。
その時に実施した内容について、それ以前の経験も踏まえ、覚え書きを兼ねて記事にしておきます。

# 概要

引継ぎについて、

1. 引き継ぎをする側の作業
2. 引き継ぎを受ける側の作業

に分けて書いています。

今回、自分は引き継ぎを受ける側でした（ので、そのような書きっぷりになっている点、ご了承ください。）


# 実際の作業

## 1. 引き継ぎをする側の作業

まずは、引き継ぎをする側の作業について
今回、前任者や協力会社さんに依頼して実施いただいた作業になります。

### (1) プロジェクト概要の説明を受ける

今回はプロジェクトに参画してそこそこ期間がたっていたため対象外でしたが、参画して間もないプロジェクトを引き継ぐ場合は、必ず前任者からプロジェクト概要について整理してもらい、説明を受けるようにします。

そんなの当たり前でしょ? と思われるかもですが、時間がない時や参画して間もなく右も左も分からない時など、どさくさに紛れて実施されずに終わってしまった、なんてこともあるもの。

意識しておくとよいでしょう。

### (2) ドキュメントの最新化、ブラッシュアップ

引継ぎを受けるに当たって、いちばん重要なのでは? と思うパートがコチラ。
ドキュメントを現状に合わせて最新化、更に、内容をよりわかりやすくブラッシュアップされていれば、言うことナシ。

ザッと以下のようなものが対象でしょうか。

#### ①WikiやREADMEの最新化、ブラッシュアップ

重要なのに、意外と放置されがちなのが、WikiやREADMEの最新化。
プロジェクトの在籍期間がそこそこ長くなってくると、あまり見なくなってしまうからか・・?

何はともあれ、<b>初めて見た人が理解できるか?</b>という視点から、手直しをお願いしましょう。

#### ②各種設計書、仕様書の最新化

追加開発などがあった場合、更新を忘れがち。
<b>最新の内容に沿っているか?</b> 確認してもらい、合っていない場合は修正してもらいます。

#### ③ソースコードへのドキュメンテーションコメントの追記（ない場合）

ソースコードにドキュメンテーションコメントの記載がない場合は書いてもらうとよいです。
<b>ソースコードの内容を把握でき、また、設計書化もできるようになる</b>ので、一石二鳥！
ただし、<b>コメントの書きすぎはかえってコードが見づらくなってしまう</b>ので、粒度についてはよい感じに調整してください。

#### ④システム構成図の最新化

コチラも意外と放置されがち。
後々も手軽に修正できるよう、[draw.io](https://app.diagrams.net/)など、編集しやすいツールを使って更新してもらうようにしましょう。

#### ⑤虎の巻の作成
引継ぎを受ける側が知見の薄い分野について、チュートリアル的なものを作ってもらうとよいでしょう。
普通のチュートリアルなら、公式サイトを見れば? というお話になるかと思いますので、<b>プロジェクト特有の内容も盛り込んでもらう</b>のがベター。

### (3) 優先度の高いタスクの消化

引継ぎではないですが、引き継ぎ作業を実施してもらいながら、優先度の高いタスクの消化も忘れずに。
特に終盤は、工数との兼ね合いで、やる/やらないを決めるようにします。

### (4) システム監査対策

プロジェクトの進度にもよりますが、システム監査対策がなされているかもヒアリングしておきましょう。

具体的には、

- テスト仕様書と証跡の保管場所/方法
- リリース手順とリリース後確認の方法/記載場所
- ログの取得方法、保管先と保管期間

あたりでしょうか。

## 2. 引き継ぎを受ける側の作業

引き継ぎを受ける側、今回は、自分側の作業です。

### (1)ドキュメントレビュー

1-(2)で最新化してもらったドキュメントをレビューします。
体裁に関する指摘だけでなく、レビューの中で、疑問点が出てくれば質問するようにすると◎。

### (2) 実際に開発、リリースしてみる

実際に開発をして、引き継ぎする側にレビューをしてもらうようにします。
レビュワーがどういう観点でレビューをしているか、にも注目しましょう。

リリース作業まで実施して、手順を確認しておくのが吉。

### (3) 適宜不明点を質問する


Google Sheetsなどで質問票（一問一答形式でもOK）を作り、適宜記入してもらうとよいかと。
必要に応じて突撃インタビュー（直接聞く）のもアリ。

### (4) 新体制に向けての準備

新規メンバー参画が控えている場合は、準備も怠らないように。
ザッと以下のような内容でしょうか。

#### ①各種アカウントの開設等

手続き系は、承認フローとの兼ね合いから、思った以上に時間がかかることがあります。
余裕をもって実施するようにしましょう。

#### ②技術スタックの共有

事前に、プロジェクトの技術スタックを共有しておきます。
可能であれば事前に少しかじっておいてもらうと、参画後、スムーズに開発に着手してもらえるハズ。
ただし、他の業務との兼ね合いもあるはずなので、強制はしないこと。


#### ③説明資料の準備と実施



- 事前説明
可能であればプロジェクト参画前に少し（最大30分程度)時間をもらって軽くプロジェクトについて説明をするとよいでしょう。

    - プロジェクト概要: どういったモノを作るか（コトをするか?）
    - プロジェクトの沿革: 今どういったフェーズなのか、体制の変遷など
    - 技術スタック: ②の内容と被りますが、口頭でも伝えるようにするとよいです。
<br/>

- 参画後の説明準備
事前説明よりも詳細な説明を準備します。

    - システム構成、フロー
    - 各種ドキュメントのありか
    - 開発のお作法

    などなど、開発を進めるにあたって必要な知見を説明します。

# 終わりに

今回、引き継ぎに使えた時間は1ヶ月。
比較的余裕はあった方かと思いますが、、引き継いでもらう内容がパッとは思い浮かばず、実は、一部の作業で、やり残しが出てしまいました・・・。

自戒の意味も込めて、本記事を執筆。
今後、同じ二の轍を踏まないようにしたい・・・！

また、後々、この点足りなかったな、という内容が出てきたら随時追記したいと思います。
強化学習入門を果たした際の備忘録

## 概要
そこそこ長くデータサイエンティストとして働いてきたけど避けてきた（触れる機会がなかった？）強化学習にようやっと入門したので自分の取ったスタディパスと概要を残しておく。これから強化学習に入門する人の参考になるかも？

## お前誰？
ブラジルでデータサイエンティスト/機械学習エンジニアとして働いています。

## 強化学習
教師あり、教師なしと並んでデータサイエンスの一大分野。色々なところで名前は聞くけれど、個人的には『ゲームくらいでしか使わなくね？』と思っていてキャリアの構築によっては正直ノータッチでも行けると思ってる。勉強コストの割に使う頻度が著しく少なそうなのでこれまでは完全にノータッチだった。

## どこまで行った？
数式を追って、自分で書いておおよそ理解したつもりになってるのは以下のもの
* DP
* MC
* TD
* on/off policy
* SARSA
* DQN
* REINFORCE
* Actor-Critic
* etc..

## 所感
入門してみての感想は『数学で押せる』だった。そんなに多くない数の式とその周辺の式を理解してコードに落とし込むだけで、とりあえず入門はできる。

## スタディパス
勉強開始したのがおおよそ二週間前。最初に手にっ取った本は『Pythonで学ぶ強化学習』(KS情報科学専門書)。とても良い本で一つ一つのステップを追っていくのはそんなに難しくはなかったけれど、どうにも強化学習の全体像と俯瞰したときの一つ一つの役割について迷子になってしまった。丁寧に読み返して整理すれば多分どうにかなったとは思うけれど、せっかくの新しい分野なので他の本に切り替えてみた。（どうせ有名所は後々全部読むことになるので。。）
それで手にしたのが『ゼロから作る　Deep Learning』の四巻(O'Reily)。これがすごくわかりやすく一気に読了。数式関係は一通り自分でもノートで追ってみて、アルゴリズムも自分で書いて実験。
本のコードはPythonだったけれど、なんとなくGoで書きたい気分だったのでGoで一通り書いてみた。(https://github.com/marubontan/reinforcement-learning-playground)
ちょいちょい怪しい部分もあるけど、入門段階で気にしすぎると詰まってしまうのでザクッと書いてみた感じ。
TDくらいまではGoで書いていたけれど、ニューラルネットが絡んできたあたりからPythonにシフト。この辺は、ディープラーニング部分はGoではなくPythonを使いたかったから。

## 今後
自分的には『入門しました！』と言えるための部分は一通り攫ったとは思うので、ここからは論文の実装や他の本に手を出しながら学習を進めていきたい。仕事で使う機会は来るのか？？
SQLをちょっと使うなら、Cloud9がおすすめ

# はじめに
すこしSQLを試してみたかったり、SQLを勉強したかったりする際、データベースの環境を用意するのは面倒です。
今回はSQLをお試しする環境として、Cloud9が使えることを紹介します。

# 概要
SQLを軽く確認・勉強するならCloud9が使えます。以下のようなメリットがあります。

- Cloud9にはデフォルトでSQLiteが入っています
    - インストールに手間取ることはありません
- Cloud9は簡単に作成、削除ができます
    - うまく動かなくなったらインスタンスごと削除して、再作成してやり直せます
- クラウド上の個人環境です
    - テストデータに機微な情報を使える
        - Web上にSQLを使えるサービスもありますが、機微なデータは使いづらい
- 料金も安い
    - Cloud9は使わないと自動で停止する機能があります
    - AWSクーポンがあれば、コスト0で利用できます

SQLiteについては以下の記事で紹介されています。

https://qiita.com/ko1nksm/items/87d27a287e1b6005d11c



# やってみる

環境はCloud9(t2.micro,Amazon Linux 2023)です。
※Amazon Linux 2でも可能です。

まずは実行して終了する方法です。
```bash
# SQLite実行
sqlite3

# 詳細はヘルプに
sqlite > .help

# 終了
sqlite > .exit
```

## 操作
データベースファイルを作って起動する方法です。
```bash
# sample.sqliteをデータベースファイルにして起動
sqlite3 sample.sqlite
```

テーブルを作って、データを操作してみます。
```sql
CREATE TABLE users( name TEXT, email TEXT);

INSERT INTO users VALUES ( 'hoge taro','aaa@example.com');
UPDATE users SET email='bbb@example.com' WHERE name='hoge taro';
-- ヘッダを表示する
.header ON
SELECT * FROM users;
DELETE FROM users;
SELECT COUNT(*) FROM users;
```


### SQLファイルを実行する
長いSQLをプロンプトで実行するのは面倒です。
以下はSQLファイルを作って、それを実行する例になります。

```bash
touch insert_users.sql
```

```sql:insert_users.sql
INSERT INTO users (name, email) VALUES
 ('taro','taro@example.com')
,('jiro','jiro@example.com')
,('kuro','kuro@example.com')
;
```

作ったSQLファイルは`.read`で実行できます。
```
.read insert_users.sql
```


# おわりに

新しいことを勉強する際、環境を作るのが面倒で挫折してしまうことも多いのではないでしょうか。Cloud9であれば、起動しただけでSQLが実行できる環境が整っているので、簡単に始められます。
SQLの勉強を考えている方は、ぜひ参考にしてください。

この記事がどなたかのお役に立てれば幸いです。
Pythonで「文字列、リスト、rangeなどからタプルを作成する」の動作を確認してみた

# 概要

Pythonで「文字列、リスト、rangeなどからタプルを作成する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/tuple/index6.html

# 実装

以下のファイルを作成しました。
```sample.py
mytuple = ("A", "B", "C")
newtuple = tuple(mytuple);
print(newtuple)

mytuple = tuple("Hello Python")
print(mytuple)

mytuple = tuple(["A", "B", "C"])
print(mytuple)

mytuple = tuple(range(10))
print(mytuple)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
('A', 'B', 'C')
('H', 'e', 'l', 'l', 'o', ' ', 'P', 'y', 't', 'h', 'o', 'n')
('A', 'B', 'C')
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
```

# まとめ

何かの役に立てばと。
VSCodeのExplorerパネルを大きな文字で読みたい

## はじめに
視力が0.1未満にもかかわらず裸眼で生活をしているため、VSCおでのExplorerパネルの文字が小さすぎてつらいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/53cff308-5871-eeb1-b16e-589a53769cb2.png)

## 環境
Mac OS
日本語キーボード

## 手順

簡単です。VScodeを"Ctrl+Shif+'-'"でズームインすればOKです。または、以下を設定に加えてもOKです。
```
"window.zoomLevel": 1
```
ちなみにズームアウトは"Ctrl+'-'"でいけます。

これだとエディターのフォントが大きくなりすぎると感じる場合は、エディターのフォントサイズだけど制御できる設定項目をいじりましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/b89fd990-a8b4-e74f-80ff-3de63f47bcb3.png)

```
"editor.fontSize": 16,
```

## まとめ

VScodeのExplorerの文字を大きくする方法を紹介しました。レッツエンジョイ裸眼ライフ！
VSCodeのExplorer要素を右に表示する方法

## はじめに
Copilotが快適なので、VSCodeでMarkdownを書くことが増えてきました。

Markdownを書いている時、アウトラインが常に右側に表示されていると便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/01fd5c6c-ed07-3010-b0d1-c3b76688bbd1.png)


## 環境
MacOS 13.6.1
VSCode 1.85.1

## 手順
簡単ですがトリッキーです。

#### 1. VSCodeの画面下部のパネルを開く

Problem, Output, Terminalなどが表示されているパネルです。
Ctrl+Shift+Pで`Toggle Panel Visibility`を実行すると開きます。私の環境だとCtrl+Jでも開きます。

![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/b1284488-44c0-e35d-f488-cb3df9abd202.png)


#### 2. 右側に移動したいExplorer要素を画面下部に移動する

Explorerの要素は画面下部のパネルに移すことができます。
ためしにOUTLINEをドラッグして移動してみます。

OUTLINEのヘッダをマウスで掴んで・・・
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/e7f54f7a-6cde-e0b2-ce02-0caedf1d379a.png)


画面下部のパネルにドロップ。

![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445203/95f283d0-0d5a-b43d-1a41-e9374c59e999.png)



#### 3. 画面下部に移動した要素を右側に移動する

画面下部に移動した要素を右側に移動します。普通にドラッグアンドドロップでいけます。

## まとめ

VSCodeの画面下部のパネルにExplorer要素を移動して、右側に表示することができました。
個人的な学習メモ3

## ノート
1. Rustの勉強を始めた。
1. CやC++などと同じようにメモリを意識したコーディングが必要。
1. これまで自身はPHPやPython、RubyなどGCを搭載している言語を主流としていたので新しい感覚。
1. Goも少しかじっていて、ポインタとか参照の概念が曖昧だったので、Rustで学び直している。
1. デスクトップアプリやOSも作れるらしい。
1. 処理が高速らしい。
1. Stackに参照するアドレスやメモリの情報を保持する。
1. Heapにデータの実体を保持する。
1. Box pointerというものでメモリ容量が確定しないデータをHeap領域に移動し、Stackでは参照先のアドレスだけ保持するようにする。（エラー回避）

## キュー
人気な言語らしいしちょっと勉強したい。

## サマリー
Rustを通してメモリに関する概念、知識を学び直す。
Google Apps Scriptを活用したスプレッドシート自動化の概要

### Google Apps Scriptを活用したスプレッドシート自動化の概要

Google Apps Script（GAS）は、Google スプレッドシートや他のGoogle Workspaceアプリケーションを自動化し、拡張できる。以下では、GASを使用してスプレッドシートに特定の機能を実装する際の主要なメソッドと工夫点を概説します。

#### 主要メソッド

1. **データ取得と処理**:
   - `SpreadsheetApp.getActiveSpreadsheet()`: アクティブなスプレッドシートを取得。
   - `getSheetByName()` または `getActiveSheet()`: 特定のシートを取得。
   - `getDataRange().getValues()`: シートの全データを二次元配列として取得。

2. **データ書き込み**:
   - `getRange(row, column)`: 特定のセルを指定。
   - `setValue(value)`: 指定したセルに値を設定。

3. **グラフの作成**:
   - `newChart()`: 新しいグラフを作成。
   - `setChartType(Charts.ChartType.PIE)`: グラフの種類を設定。
   - `addRange(chartRange)`: グラフのデータ範囲を設定。
   - `setPosition(row, column, offsetX, offsetY)`: グラフの位置を設定。

4. **カレンダーからのデータ取得**:
   - `CalendarApp.getDefaultCalendar()`: デフォルトのカレンダーを取得。
   - `getEvents(start, end)`: 指定された期間内のイベントを取得。

#### 活用手段

1. **データ整理と分析**:
   - 複数のイベントやデータポイントを効率的に処理するために、ループ（`for`や`forEach`）を使用することができる。
   - 条件に基づいてデータをフィルタリングまたは変換（例: イベントの時間計算）。

2. **ユーザーインターフェイスの向上**:
   - データを視覚的にわかりやすく表示するためにグラフを使用することができる。
   - スプレッドシートのセルに色を設定して、情報を直感的に理解しやすくするなど。

3. **自動化の効率化**:
   - スクリプトの各段階で中間データを変数に保存し、再利用することで処理効率を高められる。
   - 計算やデータ処理のためのヘルパー関数を定義して、コードの再利用性と可読性を向上させられる。

#### まとめ

Google Apps Scriptを使用することで、スプレッドシートのデータを効率的に処理し、自動化することが可能になる。
データ取得、分析、グラフ作成などの機能を組み合わせることで、なんとなく楽しいデータ分析も行える
【ゼロから始める】TitanicコンペからKaggleに入るダイジェスト

**記事作成に至った経緯**
私自身、プログラミング初心者でKaggleもこれから参加していく様なアマチュアです。
私が躓いた部分を記事として共有する事で、同じ様な状況の方の役にたてればと思い記事にしていく予定です。

**この記事の対象者**
・Kaggleをやってみたいが何から始めたらいいか分からない方
・自分が探したい記事を探すのが面倒な方

**記事ダイジェスト**
※今後、ここに記事のリンクを貼っていく予定です。
【JavaScript】マリオRPGのトライアスロン問題を解くプログラム

## 問題

A,B,C,Dがトライアスロン（※）をしました。
それぞれの証言から順位を推理し、1位から順にA,B,C,Dを並べ替えてください。

※：水泳→自転車→マラソンの順で争う競技。マラソンの順位が最終的な順位

【証言】
A「水泳も自転車も順位は同じだったけど、マラソンで二人に抜かれちゃった。」
B「自転車でDを抜いて、そのあとはゴールまで Dには抜かれてないよ。」
C「水泳で3位だったけど、ゴールするまで3位より上になったことはなかったよ。ちぇ。」
D「自転車で調子が悪くて 4位に落ちちゃったけど、結局水泳と同じ順位でゴールできた。」

## プログラム

```js
const 順位 = {
    A: { 水泳: 0, 自転車: 0, マラソン: 0 },
    B: { 水泳: 0, 自転車: 0, マラソン: 0 },
    C: { 水泳: 0, 自転車: 0, マラソン: 0 },
    D: { 水泳: 0, 自転車: 0, マラソン: 0 },
};

const 満たすべき条件たち = [
    // A「水泳も自転車も順位は同じだったけど、マラソンで二人に抜かれちゃった。」
    () => 順位.A.水泳 === 順位.A.自転車,
    () => 順位.A.マラソン === 順位.A.自転車 + 2,
    // B「自転車でDを抜いて、そのあとはゴールまで Dには抜かれてないよ。」
    () => 順位.B.自転車 < 順位.D.自転車,
    () => 順位.B.マラソン < 順位.D.マラソン,
    // C「水泳で3位だったけど、ゴールするまで3位より上になったことはなかったよ。ちぇ。」
    () => 順位.C.水泳 === 3,
    () => 順位.C.自転車 >= 3 && 順位.C.マラソン >= 3,
    // D「自転車で調子が悪くて 4位に落ちちゃったけど、結局水泳と同じ順位でゴールできた。」
    () => 順位.D.自転車 === 4,
    () => 順位.D.水泳 === 順位.D.マラソン,
];

function permute(nums) {
    const result = [];
    function backtrack(current, remaining) {
        if (remaining.length === 0) {
            result.push(current);
            return;
        }
        for (let i = 0; i < remaining.length; i++) {
            const newCurrent = current.concat([remaining[i]]);
            const newRemaining = remaining.slice(0, i).concat(remaining.slice(i + 1));
            backtrack(newCurrent, newRemaining);
        }
    }
    backtrack([], nums);
    return result;
}

const 順位組み合わせ一覧 = permute([1, 2, 3, 4]);

loop:
for (const 水泳順位 of 順位組み合わせ一覧) {
    順位.A.水泳 = 水泳順位[0];
    順位.B.水泳 = 水泳順位[1];
    順位.C.水泳 = 水泳順位[2];
    順位.D.水泳 = 水泳順位[3];
    for (const 自転車順位 of 順位組み合わせ一覧) {
        順位.A.自転車 = 自転車順位[0];
        順位.B.自転車 = 自転車順位[1];
        順位.C.自転車 = 自転車順位[2];
        順位.D.自転車 = 自転車順位[3];
        for (const マラソン順位 of 順位組み合わせ一覧) {
            順位.A.マラソン = マラソン順位[0];
            順位.B.マラソン = マラソン順位[1];
            順位.C.マラソン = マラソン順位[2];
            順位.D.マラソン = マラソン順位[3];
            let 条件が満たされているか = true;
            for (const 満たすべき条件 of 満たすべき条件たち) {
                if (!満たすべき条件()) {
                    条件が満たされているか = false;
                    break;
                }
            }
            if (条件が満たされているか) {
                break loop;
            }
        }
    }
}

console.log(
    [
        { 名前: "A", 順位: 順位.A.マラソン },
        { 名前: "B", 順位: 順位.B.マラソン },
        { 名前: "C", 順位: 順位.C.マラソン },
        { 名前: "D", 順位: 順位.D.マラソン },
    ]
    .sort((a, b) => a.順位 - b.順位)
    .map(e => e.名前)
    .join("")
);
```

## 結果

```
BDAC
```

## その他

論理的な解き方が知りたい方は以下のサイトを見てください。

https://game8.jp/mario-rpg/547218

## Prolog版

https://qiita.com/mogamoga1337/items/6b9226111ccccc8bb341
俺的GitHubレポジトリライセンス選択ガイド（MITライセンス以外の選択肢）

## 独断と偏見の選択フローチャート
[ライセンスの王、ライセンスキング](https://qiita.com/uts1_6/items/11e348ead4bae71571b8)になりたいですよね。

まずは結論から
```plantuml
!pragma useVerticalIf on
start

if (わざわざ著作権を表示するまでもない) then (著作権を放棄する)
    if (面白いライセンス名が欲しいか？) is (欲しい) then
        :WTFPL;
        kill
    else (綺麗な名前がいい)
        :The Unlicense;
        kill
    endif
(表示しろ) elseif (パクられたくない) then (パクるな)
    :そもそもライセンスを付けない;
    kill
(著作権表示付きならパクってもいい) elseif (コンパイル後の成果物に著作権表示は要らない) then (ソースコードの著作権表示だけでいい)
    :Boost Software License 1.0;
    kill
(要る) elseif (変更点を明記してほしい) then (明記しろ)
    :Apache Software License 2.0;
    kill
(明記しなくていい) elseif (宣伝・保証に自分の名前を使ってもいい) then (使ってもいいよ)
    :MIT License;
    kill
else (使うな)
    :BSD 3;
    kill
endif
```

## 何も考えずMITライセンスで大丈夫?
ライセンスに無頓着の場合、「迷ったら`MITライセンス`なら困らない」というイメージがあるかもしれません。
少なくとも僕はそうでした。

### コンパイル後のライセンス表示
しかし、こちらのツイートを見て、ハッとしました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これはゲーセンにあった桃鉄のメダルゲームなんですが、UniRxとかUniTask使ってて、アーケードにもUnityの息吹を感じる <a href="https://t.co/keHWOmkkAl">pic.twitter.com/keHWOmkkAl</a></p>&mdash; 若旦那 (@wakapippi) <a href="https://twitter.com/wakapippi/status/1664454640803647488?ref_src=twsrc%5Etfw">June 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

要するに、アーケードゲーム「桃太郎電鉄メダルゲーム」の実機から、`UniTask`の`MITライセンス`の明記が確認できる、という内容です。

人によっては色んな考えがあるかもしれませんが、僕は「自分が作った **ちょっとした** コードをわざわざ **コンパイル後まで** ライセンス表示するぐらい手間をかけさせたくない」と思うわけです。

しかし、自分の愛着のあるソースコードを手放したくないので、基本的に **ソースコードの著作権表示のみ** の`Boost Software License 1.0`を使っています。

独自性が全くなく、愛着もわかないソースコードは`WTFPLライセンス`あるいは`The Unlicense`を使っています。

### ソースコード公開している作品にライセンスをつけるとパクられるわよ
しっかり完成したゲームを、世のためにコードを公開するべく`public`レポジトリにすることがあると思います。
しませんか？僕はやっています。

そもそもこれらのライセンスは **オープンソース** にするためのものですからね。 何も考えず `MITライセンス` を付けていると、そのままパクられて商用利用される可能性が十分にあります。

**ライセンスを逆に付けない場合、通常の著作権と同じ扱いになるので、パクられなくなります**