OmniAICreator/Qiita-1.07M huggingface dataset:
GASで受信・送信済みメールを取得し、スプレッドシートに出力する

## これはなに
GAS を利用して Gmail から各種メールを取得する方法をまとめたものです。

## 受信メールを取得する

GAS を利用して Gmail からメールを取得する際、メールは「スレッド」というものにまとめられた状態で取得されます。
「スレッド」とは、一連のメールのやり取りをまとめたものです。
送信したメールの件名を変更せずに返信されたメール、または受信したメールの件名を変更せずに返信したメールがスレッドにまとめられます。

### 取得メソッド

##### getInboxThreads(start, max)
すべての受信トレイのスレッドを取得します。

##### getStarredThreads(start, max)
すべてのスター付きスレッドを取得します。

##### getPriorityInboxThreads(start, max)
すべての優先トレイスレッドを取得します。

##### getSpamThreads(start, max)
すべてのスパムスレッドを取得します。

##### getTrashThreads(start, max)
すべてのゴミ箱スレッドを取得します。

##### search(query, start, max)
検索クエリを使用してスレッドを取得します。
検索クエリは、実際に Gmail の検索ボックスで使用できるクエリと同じものが使用できます。 
詳しくは以下のリンク先をご覧ください。

https://support.google.com/mail/answer/7190?hl=ja

これらのメソッドの start と max は省略することもできますが、
メールの取得件数が多くなりすぎると処理しきれずエラーになる場合があるようなので、
指定しておいたほうが無難そうです。

## 送信済みメールを取得する

調べてみたところ、送信済みメールを取得する専用のメソッドは存在しないようです。
ではどうすればいいのかというと、先に挙げた
search メソッドを利用すると取得できそうでした。

以下のクエリを指定することで送信済みのメールスレッドを取得できます。
`in:sent`

## 使用例

以下はスター付きのメールを取得し、スプレッドシートにメールタイトルを出力するコードです。

```js
function checkGmail() {
  const messages = fetchGmail()

  if(messages.length > 0){
    writeSheet(messages);
  }
}

function fetchGmail() {
  const threads = GmailApp.getStarredThreads();
  const messages = GmailApp.getMessagesForThreads(threads);

  return messages;
}

function writeSheet(messages) {
  const id = "{スプレッドシートのID}"
  const spreadSheet = SpreadsheetApp.openById(id)
  const sheet = spreadSheet.getSheetByName("{出力先のシートの名前}")

  messages.forEach(function(message){
    const mail = message[0]
    const subject = mail.getSubject();
    const maxRow = sheet.getMaxRows()
    const lastRow = sheet.getRange(maxRow, 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow()

    sheet.getRange(lastRow+1, 1).setValue(subject)
  });
}

```
DockerでMySQLコンテナを起動してクライアントから接続する方法

# 結論

```bash:MySQLコンテナ起動
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d -p 3306:3306 mysql:latest
```
```bash:クライアントから接続
mysql -h 127.0.0.1 -P 3306 -u root -proot
```
```bash:DockerのゲストOSから接続(おまけ)
# コンテナにアタッチしてMySQL接続
docker exec -it sample-app-db bash
mysql -u root -proot
```
※ MySQLで-pオプションに直接パスワードを打つと現場によってはめっちゃ怒られます。遊びでのみ利用しましょう。
# 説明
## MySQLコンテナ起動
ここで大切なことは-pオプションでクライアント側のポート3306がゲストOS側の3306ポートにつながるように設定してやることだけです。
これを指定してやらないと外部からコンテナにアクセスすることはできません。
他は、MySQLの公式dockerhubのサンプルをほとんどそのまま利用しました。
## クライアントから接続
ここで大切なことはホストに`127.0.0.1`を指定することです。
なぜ`127.0.0.1`にしないといけないのかは、よくわかりませんでした。
以下のリンクを参考に指定しました。
https://qiita.com/saken649/items/00e752d89f2a6c5a82f6#sql%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%8B%E3%82%89%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9
また、MySQLはポートを指定しない場合はデフォルトで3306が指定されるため今回のケースでは指定しなくても問題ありません。

# 読まなくてもいいこと
以降は私のグチを交えて、どうやってこの結論に至ったのかをタラタラ書きます。
暇すぎてどうしようもない時に読んでください。
## 結論に至るまで
### 1. dockerhubでMySQLコンテナの起動コマンドを確認
以下の公式ページからとりあえず起動コマンドを確認し自分好みにパラメータを書き換えました。
https://hub.docker.com/_/mysql
```bash:起動コマンド
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
```
### 2. クライアントから接続を試みるが失敗
```bash
$ mysql -h sample-app-db -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2005 (HY000): Unknown MySQL server host 'sample-app-db' (8)
```
直感的にホスト名ってコンテナ名じゃね？ってな感じで実行すると`sample-app-db`なんてホストは無いとエラーが出ました。
コンテナにアタッチしてMySQL接続はできるのですが、クライアントから接続ができませんでした。
### 3. 神記事との出会い
え？じゃホストって何指定したらええねん？って思い`docker mysql ホスト名指定`でググってみると、以下の記事がヒットしました。ホスト名を指定してコンテナを立ち上げる方法を調べるための検索単語でしたが、クライアント側でどんなホスト名を指定したらいいかが記述されていました。
https://qiita.com/saken649/items/00e752d89f2a6c5a82f6
この記事の内容を一部引用させていただくとMySQLコマンドのパラメータは以下のように設定するとのこと。
- Host: 127.0.0.1
- User: root
- Password: your_password
- Port: 3306

上記により改めてコマンドを組み直し実行してみました。
```bash
$ mysql -h 127.0.0.1 -P 3306 -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```
はい、予想通りうまく動きませんね。
### 4. エラーメッセージをAccess denied for user 'root'@'localhost' (using password: YES)をググる
エラーメッセージ的にアクセスが拒否されているっぽい。ググってみたけれどよくわからなかった。パスワードもあってそうだし、ホストを`localhost`にしてもダメ。ハマりそうだったので、一旦コンテナ起動コマンドについて考え直してみることにしました。
### 5. いろんなサイトで「3306:3306」って記述をよく見るぞ
調べている中で出回っている情報の多くが`docker-compose`を利用した内容でした。
なので`docker-compose.yml`ファイルを良く目にしたのですが、その中で以下の記述をよくみました。
```yml:docker-compose.yml(一部)
  xxx-db:
    ports:
    - 3306:3306
```
これってコンテナ起動時に指定してやらないといけないんじゃね?って思い早速コンテナ起動コマンドを以下のようにポートを指定するように修正。
```bash
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d -p 3306:3306 mysql:latest
```
以上で思った通りの動作をさせることができました。
## 番外編：新たな問題
以下のコマンドでもクライアントからDBに接続することができます。
```bash
mysql -h localhost -P 3306 --protocol=tcp -u root -proot
```
しかしこのコマンドを実行してから従来のコマンドを実行しても接続できなくなりました。
```bash
$ mysql -h 127.0.0.1 -P 3306 -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```
なぜコンテナは拗ねてしまったのでしょうか?誰か助けてほしいです。
定期的にGASのアクセス承認が要求されWebhookが止まってしまう件の対処例

# 概要
GASでWebサービスをホストしていて、たまに権限を承認しないといけない問題。
利用がないタイミングでそれが訪れても気付けるように、エラー通知はメールが即時に飛ぶようにして、トリガーで定期的にアクセスして検出できるようにしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/de28bbe0-b602-600b-400d-c06b010cea02.png)

# 課題
LINE BotのバックエンドにSpreadsheetのGASでWebhookを作成し運用している。

Webサービスをデプロイする際、Webアプリから誰でもアクセスできるようにするため、アクセスを承認する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/bba7d604-7666-60b7-1908-1d44ba574412.png)
そしてこれがデプロイのタイミングだけかというとそうでもなく、しばらくするとアクセスができなくなり、Webサービスとして機能しなくなってしまう。

そうなってしまったらどうするか。。　いまのところ叩き起こすしかない。

が、気付けないことが問題で、利用者から「止まってるみたい」と通報があって初めて回復措置に動くことになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/abe90917-c00d-f43f-8ac4-beb0c0148e70.png)

# 解決方法

根本解決として、明示的に永続的な権限を承認ないし付与することができれば良いのだが、ときどきネットを探すも良い情報に行き当たらず。

次善の策として、定期的にサービスにアクセスし、エラーを起こさせてその通知を受け取るというアプローチをとることにした。

GASではトリガーでスケジュール実行ができる。（ほかに、スプレッドシートやカレンダーがイベントソースとして利用できる）
WebhookはPOSTだが、定期的に死活監視のためのGETリクエストを送ってエラー時はトリガの設定にある通知を利用してメールを受信することにした。

こうすることで、利用者がアクセスし初めてエラーが起きるのではなく、エラーが起きる状態になったら速やかに（トリガの実行インターバルで）通知を受け取り回復措置に動けるようになる。

もちろん自動で回復できればよいのだが、アクセスの承認は人がポチッとやる以外の方法がなさそうなのだ。

# 実装
簡単なdoGet関数を書き、トリガを作成して一定間隔で実行されるようにします。

```js:code.gs

// HealthCheck用ダミーGETメソッド
function doGet() {
  return ContentService.createTextOutput(JSON.stringify({"success":true})).setMimeType(ContentService.MimeType.JSON);
}

// HealthCheck invoke by scheduled trigger
function checkSelf() {
  var url = HEALTH_CHECK_URL;
  var response;
  try {
    response = UrlFetchApp.fetch(url, {
      "muteHttpExceptions" : true,
      "validateHttpsCertificates" : false,
      "followRedirects" : true
    });
    Logger.log('checkSelf() : ' + response.getResponseCode());
    if (response.getResponseCode() != 200) {
      // お知らせ
      // sendLine(ADMIN_LINE_ID, '寝たかも。 status:' + response.getResponseCode());
    }
    return 'OK';
  } catch(e) {
    // 例外エラー処理
    Logger.log('Error:')
    Logger.log(e)
    return null;
  }
}
```

トリガは以下のように設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/ab916f3c-c999-4d65-03a8-b432da9c7e52.png)
checkSelf（)の中で自分自身をリクエストし、エラーが起きた場合は「今すぐ通知を受け取る」設定によりメールを受信します。

# 近況
概ね七日おきに起きている感じである。Gmailで受け取っているので、新着に気づいた時に対処していますが対処するまで繰り返し届くので気付きやすくなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3381/7f06bd68-0e83-aff9-c6c7-bdf0679442e6.png)
スレッド毎の通数は、気づくまでの15分おきの継続回数。。

# 今後に向けて
簡単な実験的実装はよしとして、やはり本格的に運用するにはAWS LambdaやGCPのCloud Functionなどを検討すべきだなというところで、来年はその辺もみていきたいと思います。
Dockerで環境構築したmicro-ROSでカスタムメッセージを利用する方法

micro-ROSで配列データを扱うには, MultiArray系のメッセージを利用します.
しかし, このMultiArray系のメッセージはセットアップが少し面倒で, かつmallocによる動的メモリ確保を行う必要があります.

以上の２点が理由で「ロボコンにおいてはカスタムメッセージ作った方が楽では？」という考えに至りました.

---

マイコン向けにカスタムメッセージをビルドする方法を調べたところ, 公式サイトにそれらしいものを見つけました.

https://micro.ros.org/docs/tutorials/advanced/create_new_type/

ところが, Dockerでmicro-ROSの環境を構築していたこともあってかこのページの通りに実行しても上手くいかず...

諦めきれずにさらに調査を進めたところ, 以下のページの方法にてビルドすることができました.

https://github.com/kajMork/Brick_Feeder/wiki/How-to-create-custom-micro-ros-message-service-for-use-in-arduino-framework

大筋はこのページの通りに実行すれば上手くいくのですが, いくつか違うポイントもあったので本記事で紹介します.

# 環境

Dockerでmicro-ROSの環境構築をしていることを前提とします.
PlatformIOで開発を行っている想定で話を進めますが, ArduinoIDEとかでも可能です.

私が動作を確認した環境は以下の通りです.

|項目|バージョン|
|:---:|:---:|
|OS|Ubuntu22.04|
|ROS2|humble|
|マイコン|STM32F746ZG|

# カスタムメッセージをビルドする

始めに `micro_ros_arduino` ライブラリの中にある `extra_packages` ディレクトリまで移動します.
私の環境では以下の場所でした(参考ページと若干違います). <>の部分は適宜読み替えてください.

```
/home/<USER_NAME>/Documents/PlatformIO/Projects/<PROJECT_NAME>/.pio/libdeps/<ENV_NAME>/micro_ros_arduino/extras/library_generation/extra_packages
```

次に `extra_packages` ディレクトリ内にカスタムメッセージのファイルを作成します.
手順はmicro-ROS公式サイトの通りです(msgファイル記述・CMakeLists.txtとpackage.xml書き換えまで).

https://micro.ros.org/docs/tutorials/advanced/create_new_type/

今回はサイト通りに `my_custom_message/msg/myCustomMessage` というファイルを作成した想定で話を進めます.

続いて `micro_ros_arduino`ライブラリのルートディレクトリに移動します. 
私の環境では以下の場所です.

```
/home/<USER_NAME>/Documents/PlatformIO/Projects/<PROJECT_NAME>/.pio/libdeps/<ENV_NAME>/micro_ros_arduino
```

いよいよビルドを行います.
今回はターゲットとなるマイコンのMCUがCortex-M7なので, `cortex_m4` オプションを付けています.
~~本来はCortex-M4用のオプションですが互換性があるので気にしないことにします.~~

```
docker pull microros/micro_ros_static_library_builder:humble
docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=extras microros/micro_ros_static_library_builder:humble -p cortex_m4
```

使えるオプションの代表例は以下の通りです.
`extra_packages` ディレクトリと同じ階層にある `library_generation.sh` に書かれています.
オプションを指定しないとすべてのターゲットに対してビルドを行うのか, かなり時間がかかりますのでご注意ください.

|ターゲット|オプション|
|:---:|:---:|
|OpenCR|opencr1|
|STM32F4|cortex_m4|
|Teensy 4.0(4.1?)|teensy4|
|ESP32|esp32|

これでビルドは完了です.
上手くいっていれば以下の場所に作成したメッセージがビルドされたものが格納されています.
逆に失敗していると空のディレクトリになっているかと思います.

```
/home/<USER_NAME>/Documents/PlatformIO/Projects/<PROJECT_NAME>/.pio/libdeps/<ENV_NAME>/micro_ros_arduino/src/my_custom_message
```

実際のプログラムでは次のようにしてカスタムメッセージを利用します.
```
#include <my_custom_message/msg/my_custom_message.h>

my_custom_message__msg__MyCustomMessage msg;

msg.bool_test = True;
msg.uint16_test = 223;
```

# まとめ

micro-ROSカスタムメッセージをビルドして使えるようにする手順を, 参考ページを基に紹介しました.
たまにメッセージの内容によっては通信ができない現象が発生することがあったので, それについて調査を進めていきたいと考えています.
何かお気づきの点がありましたらコメントいただけますと幸いです.
SSD1306のアドレスについて(Arduinoの答えは、3Cまたは3D)



目的
OLEDのテスト
I2Cアドレスについて、わかっていない人がいるので


　1. I2Cアドレスは、アドレス7ビット、読み込み書き込み1ビットの計8ビットである

　2. アドレスは、十六進で表現されている。

0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7

1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F


　3. SSD1306は、2個アドレスを持っていてデップスイッチ等で切り替え出来る


0x78 0111-1000

0x7A 0111-1010


　4. 0x78 を　Arduinoのアドレスに変換する

1ビット右にシフトは、0011-1100 3C

　5. 0x7A を　Arduinoのアドレスに変換する

1ビット右にシフトは、0011-1101 3D

　6. よつて、Arduino使用時のアドレスは、3Cまたは、3D


サーチもあるよ


https://qiita.com/caa45040/items/a92670598d49e6e547aa
Ruby on Railsでプルダウン検索機能を実装する（gem不使用）

---
こんにちは。GeekSalonのプログラミング駆け出しメンターです。
今日はgem（ransack）を使用せずに実装できるプルダウン検索機能についての記事を書こうと思います。
初めて記事を書くので、温かい目で見てくださると嬉しいです。

# 目次
①前提
②開発概要
③実際のコード


## 前提
○開発環境
    Ruby 3.0.4
    Rails 6.1.6

○前提
   ・ ListでのCRUD機能実装済み
   ・ 新規投稿ページでプルダウン機能を実装

## 開発概要
①投稿時にプルダウンで選択した情報を、変数を使って検索をプルダウン式でかける。
②検索用のparamsをコントローラーで作成
    ・検索したいカラムの選択項目を検索バーにも作成する
③コントローラーで検索した結果だけを表示する変数を作る
    ・ビューに表示

実装イメージはこちら

ー投稿一覧ページー
![スクリーンショット 2022-12-27 15.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822642/e50b7cdd-86f2-26b9-4e60-d3d4f4a5ed4f.png)

左上がプルダウン検索バーになっています。

![スクリーンショット 2022-12-27 15.20.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822642/920f640f-3457-640b-0696-f234a96227ed.png)

![スクリーンショット 2022-12-27 15.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822642/772acd0e-6f6a-af99-4202-f42ee1f6988a.png)

選択して検索をかけると、検索条件に当てはまる投稿一覧を表示します。
検索結果も表示可能です。


ー新規投稿ページー

![スクリーンショット 2022-12-27 15.48.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822642/bda277b2-67f9-03b6-9321-4ecbf85d2df2.png)

このように新規投稿ページでもプルダウン選択で指定しておきます。

## 機能実装コード
コントローラー作成とモデル作成は省きます。

新規投稿(newページ)を作成する際、簡単なプルダウン選択を実装しておいてください。




```ruby:new.html.erb
<%= form_for @list do |f| %>
      <div class="new_2_field">
        <%= f.label :price %>
        <br>
        <%= f.select :price, [["〜1000円", "〜1000円"], ["〜2000円", "〜2000円"], ["〜3000円", "〜3000円"], ["〜4000円", "〜4000円"]], include_blank: "選択して下さい" %>
        <br>
      <%= f.submit "投稿する" %>
<% end %>
```
selectタグを使ってこのようにプルダウン機能を実装します。


### 投稿一覧ページの実装

続いて実際に一覧ページで検索して表示するところを実装します。

まず検索して情報の受け渡しを行えるようにparamsを使って変数を定義します。
```ruby:lists_controller.rb
def index
        @lists = List.all
        @searchprice = params[:search]
end

```

コントローラーで定義したら、実際に検索バーを作ります。


```ruby:index.html.erb
<%= form_tag({controller:"lists",action:"index"}, method: :get) do %>
    <%= select_tag :search, options_for_select([["〜1000円","〜1000円"],["〜2000円","〜2000円"],["〜3000円","〜3000円"],["〜4000円","〜4000円"]]) %> 
    <%= submit_tag "絞り込み" %>
<% end %>
```

select_tagで先ほど指定したparamsを指定して、options_for_selectで検索する内容を指定します。その中身を検索する選択項目に自由に変えて実装してください。
※新規投稿ページで先ほど指定した内容と全く同じでないと検索かからないので注意してください。

次に実際に検索した条件での投稿表示のコードを実装していきます。

```ruby:lists_controller.rb
 def index
        @lists = List.all
        @searchprice = params[:search]
        @search = @lists.where(price: @searchprice) #追加
end

```

投稿表示を行う変数を@searchで定義します。whereで条件を指定して、検索したいカラムを指定（price）して情報の受け渡しをするために先ほど定義した@searchpriceを定義しておきます。

そして最後にeachメソッドで投稿表示するだけ！

```ruby:index.html.erb
<% @search.each do |s| %>
    <p><%= s.price %></p>  
　　#表示したいものを中に書いてね！
<% end %>
```

whereで条件分岐した変数@searchをeachメソッドに入れて検索条件にあった投稿を表示します。


### 検索結果表示

最後に検索する際に選択したものを表示するために記述を加えます。


```ruby:index.html.erb
検索結果：<%= params[:search] %>
```

情報の受け渡しをおこなっているparamsを表示することで選択した項目を表示することができます。


# 最後に
ransackを使ったとき、他のgemとの兼ね合いでエラーが出てつまづくことが多かった私からすると、こっちの方が実装早いなと思い今回記事を書きました。

初心者の方には実装しやすい機能だと思います。
またもっといい方法があれば教えていただけると初心者からするととても嬉しいです。
自分でももっといい方法があるのか試行錯誤していこうと思います。
【ルール説明】empty-string-compare

こちらの記事は [Ansible lint Advent Calendar 2022 カレンダー2](https://qiita.com/advent-calendar/2022/ansible-lint) 22日目の記事になります。

今回はルール [empty-string-compare](https://ansible-lint.readthedocs.io/rules/empty-string-compare/) について説明します。

### empty-string-compare

[empty-string-compare](https://ansible-lint.readthedocs.io/rules/empty-string-compare/) は Ansible playbook 等で条件を指定する際に空の文字列が利用されていないかチェックします。空の文字列の比較は [jinja2](https://jinja.palletsprojects.com/en/3.1.x/) フィルターの形式 にします。

* `when: var != ""`ではなく`when: var | length > 0`と記述する
* `when: var == ""`ではなく`when: var | length == 0`と記述する

[jinja2](https://jinja.palletsprojects.com/en/3.1.x/) フィルターは`var | length`で`var`が何文字かをカウントします。その文字数のカウントの結果と`0`を比較します。プログラミング的に言えば副作用を避けるために`文字列と数値の比較`ではなく`数値と数値の比較`にすると言う処理になります。

[empty-string-compare](https://ansible-lint.readthedocs.io/rules/empty-string-compare/) は`opt-in`のため初期設定では無効になっています。[empty-string-compare](https://ansible-lint.readthedocs.io/rules/empty-string-compare/) を有効にするには [Ansible lint](https://ansible-lint.readthedocs.io) の設定ファイルを変更します。

```yaml:.ansible-lint
enable_list:
  - empty-string-compare
```

#### 問題のあるコード

Ansible がターゲットの OS 情報を取得できない場合`/sbin/shutdown -t now`を実行する処理です。

```yaml
--
- name: Example playbook
  hosts: all
  tasks:
    - name: Shut down
      ansible.builtin.command: /sbin/shutdown -t now
      when: ansible_os_family == "" # <- 空の文字列で比較している
```

#### 修正されたコード

```yaml
---
- name: Example playbook
  hosts: all
  tasks:
    - name: Shut down
      ansible.builtin.shell: |
        /sbin/shutdown -t now
        echo $var ==
      when: ansible_os_family | length == 0 # <- jinja2 テンプレートの形式で記述する
```

### 参考サイト

* [empty-string-compare — Ansible Lint Documentation](https://ansible-lint.readthedocs.io/rules/empty-string-compare/)
企業の部活動としてkaggle部を運営するメリットについて

# はじめに

kaggleなどのデータサイエンスコンペの認知度が上がった昨今では、企業内にkaggle部を設置する例を多く見かけるようになったかと思います。

弊社にもデータ分析コンペ参加を目的とする部（通称ARISE kaggle部）がありますが、部として運営していく上での効果や課題感などを共有したいと思います。

# kaggleとは

kaggleとは、データサイエンティストに特化した競技会サイトを運営しており、世界中のデータサイエンティストが予測精度を競い合うコンテストを主催するプラットフォーマーです。

コンペの期間は約2~3ヵ月であり、与えられたデータに対して意図を読み解き、前処理を行い、分析モデルを構築して、プログラム実装を期間内に繰り返しながら、予測精度を競うスピード開発が求められるため、分析スキルを短期間で向上させることが期待できます。

# どういった活動をしているか

slackにkaggle部の専用チャンネルを用意しており、チャンネルには40-50人程度が参加してもらっており、目ぼしいコンペが開催されるたびに、チャネルで周知してコンペ参加希望を募り、チームを組んで参加してもらうのが主な活動内容となっております。

チーム参加での負担や細かい分担は組んだメンバーでの意向が色濃く反映されますが、ディスカッションなどのコンペ情報をチームで共有しつつ、週一でミーティングするのが基本になっています。

# なぜチームコンペを推奨するのか

チームでのコンペ参加を主な活動内容としていますが、以下の効果を期待してます。

## ①情報がスムーズに取得できること
一人で参加するより、チームで公開されている解法を共有しあう体制をとることができるので情報取得の効率がかなり良くなり知識量が圧倒的に向上します。

## ②初心者参加のハードルを下げるため

チーム内に初心者だけにならないよう、チーム編成時に気を払っており、参加経験なくても、コンペ経験者の中で磨かれることを期待しています。

## ③モチベーションが維持できること

割と大事なのですが、日々の業務と並走しつつ、1-2か月モチベーションを維持するのが大変なので、チームによってモチベーションの維持を狙っています。


逆にチーム制による課題もあり
- チームメンバー同士での稼働調整が大変でメンバー1人に負荷が行ってしまう恐れがある。
- コード管理が複雑になる。特に最近多い、参加者が Kaggle の Code 環境上でソースコードを実行する「code competitions」形式だと管理の難易度が上がる。

ここら辺はチーム内での工夫ポイントだったりするかもしれないですが、コンペ内容やメンバーの気質によって左右されるので難しいところです。

# アウトプットの機会提供

LT会での発表でも良いのでアウトプットすることで理解度がかなり異なってきます。

たとえ入賞できなくても上位解法をまとめただけでも、理解力が向上するので積極的に社内勉強会やブログでの発信を推奨しています。勉強会などは、個人でやるより会社の勉強会などを活用できるので、企業内kaggle部とするメリットの一つかと思います。

# まとめ

チーム制で目標に向かってスキル向上を目指してしてもらうのはスキルアップ面ではとても良いことであり、効果も見えております。
また企業側からしても成長の機会提供や採用活動への大きなメリットとして考えられます。

もし、皆さんの会社にkaggle活動している団体があれば参加したり、なければ有志で設立してみてはいかがでしょうか。
【Ruby】4つの等値演算子

# equal?メソッド

以下の例を見てみます。

```ruby
p "foo".equal?("foo") # => false
```
これは一見して、同じ値に見えますが、falseが出力されます。
`equal？メソッド`では、内容や値で2つのオブジェクトを比較するのではなく、オブジェクトIDで2つの値比較します。

そしてこれから紹介する他の等値演算子と使い方に注意しなければいけないことは、**equal?メソッドをオーバーライドしてはいけない**ということです。
比較しているオブジェクトの両方が、メモリ内の同じオブジェクトを指していない限りtrueを返してはいけないように動作すべきと考えられています。

# "=="演算子
数値の比較でよくみる演算子です。
数値だけでなく、文字列の比較にも使用できます。

```ruby
"foo" == "foo" # => ture
1.0 == 1       # => true
```
~~Fixnumと~~Floatの比較でも数値が同等であればtrueを返します。
⇨@scivolaよりご指摘あり。Ruby 3.2で廃止。

# eql?メソッド
基本的には`==演算子`を同じ動きをしますが、特にHashキーを比較するのに使用されます。

# "==="演算子
case式で使用されます。
暗黙的に使用されているため、caseが使われている式では見かけないことが多いかもしれません。
例を見てみます。

```ruby
a = "foo"

case a
when "bar"
  p "bar"
when "baz"
  p "baz"
else
  p "Erorr"
end

# => "Erorr"
```

これを書き換えます。

```ruby
a = "foo"

if "bar" === a
  p "bar"
elsif "baz" === a
  p "baz"
else
  p "Erorr"
end

# => "Erorr"
```

これだけだと、 "=="演算子との違いがあまりわからないと思います。
"==="演算子はクラスで実装しているものに所属しているかを比較してくれます。

わかりやすい例で、数値を色々なクラスで比較してみます

```ruby
a = 0.01

if Fixnum === a
  p "I'm Fixnum!"
elsif Float === a
  p "I'm Float!"
else
  p "I'm Error!"
end
```

これは同値性をみていますが、クラスごとの性質を加味して比較しています。
実は"==="演算子はメソッドであり、`.===` という形でも使用できます。
ですので、左辺はメッセージのレシーバとなり、右辺はメソッド呼び出しに使用される引数となります。(.===()という形をとる)
左辺のオブジェクトによって動きが決まるということを覚えておきましょう。
組織成立の3つの要素 

組織運営において、重要な3本の柱がある。
---

アメリカの経営学者のチェスター・バーナードが提唱した組織が成立するための３つの条件というものをご紹介したい。
今年、最後のブログとなります。改めて、皆様の今年一年の振り返り、来年に活かして頂けましたら、幸いです。

具体的には「コミュニケーション」、「協働の意欲」、「共通の目標」の3つを挙げており、
それらのどれもが組織には一定水準必要とされている。

__「コミュニケーション」__
コミュニケーションは、ある程度の関係性がないと、本音など言えない。
コミュニケーションは、報告、連絡、相談、評価とは、異なる。
仕事となると、報告、連絡、相談、評価は、出来る人が多いと思いますが、
コミュニケーションを取れている人が多いかと言うと、少ないかもしれませんね。。
つまり、集団の統率と組織の運営は、異なるという事です。

自分が持っている情報だけを基準とせず、相手のもっている情報とすり合わせが出来ているのか？
コミュニケーションを取る相手と、ある程度の関係性をつくり、本音や言いたいことをヒアリングできているのか？
考えてみて下さい。

コミュニケーションとは、双方向のもので、相手を理解しようという気持ちがないと、相手の事を理解する事が出来ません。

__「協働の意欲」__
何人かの人が集まって、持っている力を合わせてお互いに補いあえば、目的を果たすことができる。
これがないと、内部のリソースを奪い合う集団となる可能性があります。
仲間外れにされたような意識をメンバーに持たせてしまうと、組織は、活力を失うでしょう。

__「共通の目標」__
あなたは、何のために、仲間と仕事をしていますか？
目的は、一人では成し遂げられない事を成し遂げるために、仲間と仕事をしているはずです。
これがないと、農作物を荒らすイナゴの群れのように、問題のある集団となってしまう可能性があります。

組織存続に必要な2条件
---
組織成立の次に重要課題となるのは、組織を長く存続させることです。 どんなに良い組織が成立しても、その先も上手く機能し続けることが出来なければ、やがて衰退し崩壊してしまうでしょう。 バーナードは、組織成立の三要素に加えて、組織が存続するために必要な2つの条件についても言及しています。そこで、ここでは組織存続に必要な2条件をご紹介します。

__企業は、__
__一回限りのタスクをこなすことを主業務としていません。__
__ゴーイングコンサーン(継続企業)である必要があります。__

そこで、会社が
__将来にわたって継続していく__
前提について、考察してみたいと思います。

将来にわたって継続していくためには、バランスが必要です。

__組織内部__
「貢献」と「誘因」のバランスを、上手く保つためには、メンバー間のコミュニケーションが必要です。
__組織外部__
お客様と良い関係を保つためには、コミュニケーションが大切です。

下記のサイトに次のような記載がありました。
https://schoo.jp/biz/column/1271

__内部均衡__
組織存続のための1つ目の条件は、内部均衡です。 内部均衡とは、組織内部の貢献度のバランスを表し、メンバーが自分の貢献以上のリターンを受け取っていると考えている状態を言います。バーナードは、組織が存続していくためには、組織メンバーの貢献意欲を継続的に引き出すことが重要であり、メンバーの貢献意欲を引き出すためには、メンバーを満足させるための誘因（対価）が必要であると考えました。誘因の具体例として、雇用の安定、貢献度に見合った給料・ボーナスの支払いなどが挙げられます。 組織内部において、このような「貢献」と「誘因」のバランスを常に上手く保つことがメンバーの存続、そして組織存続の条件となるのです。

__外部均衡__
2つ目の存続条件は、外部均衡です。 外部均衡とは、社会（外部環境）における組織の存在意義や有効性のことを言います。 時代とともに変化し続ける「社会」や「市場」において、常に貢献し続けることが存続にとって重要となります。そのためには、外部環境の変化に応じて柔軟に対応し変化していく必要があります。 このことから、社会に貢献し必要とされる組織であり続けることが、組織存続の条件といえるでしょう。

__世間では、オンライン忘年会を終えた時期なのではないでしょうか。__
コロナ前は、実際に会って毎日のように飲んでいました。
私のコミュニケーションツールでした。
しかし、コロナになって、仲間と飲む機会がなくなったので、お酒をやめました。
コミュニケーションは、ほぼ、なくなりましたね。。

__最近、会社のオンライン忘年会に参加しました。__
実際に会って飲み会をすると、自分の話しかけたい相手と話すというように偏りが出てしまうのですが、
オンライン忘年会は、Zoomで行い、ブレークアウトルームにランダムで参加する事となり、
初めてお話する人と交流を深める事が出来ました。
会社が何も工夫しないと、このブレークアウトルームでのコミュニケーションも、
会話の内容に偏りが出てしまったかもしれませんが、
クイズを取り入れてくれたり、コミュニケーション活性化の工夫をしてくれていたので、
初めてお話する方々とのコミュニケーションが取りやすかったです。
__オンライン忘年会というのに参加してみて、__
__改めて、私の会社は、コミュニケーションを大切にする良い会社だなと思いました。__

__ただ、参加してみて、思ったのは、業務上、これが出来ていないなという反省です。__
__業務でもコミュニケーションを意識して、来年は、取り組んでいきたいと思います。__
Aerospikeを使ってみる：Windows11環境のDockerを使って起動

# はじめに
Aerospikeを使ってみたいと思ったとき、通常はLinuxサーバかEC2のインスタンスなどのLinuxの環境が必要になります。
でももっと簡単に使ってみたい時は、WindowsやMacでAerospikeを動作させることができます。
今回は、WindowsでEnterprise EditionとCommunity Editionを動作させる方法を説明します。

# 環境構築
### WSL 2 (Ubuntu)のインストール
今回はDockerでAerospikeを動作させます。
Docker環境はWindowsにDocker Desktopをインストールすることもできますが、ここではWindows上にLinux環境を作成するWSLを使用します。

以下を参考に手順を記載します。
https://learn.microsoft.com/ja-jp/windows/wsl/install

1. 管理者モードでPowerShellを開きます。
1. 以下のコマンドを実行します。
    ```
    wsl --install
    ```

1. Windowsを再起動します。Ubuntuの画面が表示され、ユーザ名とパスワードの入力を求められるので入力します。

### Ubuntu環境の設定

以下を参考に手順を記載します。
https://docs.docker.com/engine/install/ubuntu/

1. Ubuntuを起動し、パッケージのアップデートと必要なパッケージのインストールを行います。
    ```
    sudo apt-get update
    sudo apt-get install ca-certificates curl gnupg sb-release
    ```

1. GPGキーの追加と設定を実施します。

    ```
    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    ```

### dockerのインストール

1. パッケージの更新とDockerのパッケージのインストールを行います。
    ```
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    ```

1. Dockerサービスの開始と動作確認を行います。

    ```
    sudo service docker start
    sudo docker run hello-world
    ```

1. Docker Composerをインストールします。（今回は不要ですが、今後のためにインストールしておきます。）

    ```
    sudo apt install docker-compose
    ```

以上で、準備は完了です。

# Aerospikeの実行

次にAerospikeを上記のインストールしたDockerで実行します。
実行は、Community Edition、Enterprise Editionについて記載します。
また、Aerospike社と契約しFeatures Keyをお持ちの場合についても記載します。

### Docker Hubの確認

Aerospikeのイメージを、以下のDocker Hubで確認してください。
https://hub.docker.com/_/aerospike
2022年12月27日の時点の最新版は、両Editionとも6.1.0.3ですので、以下は6.1.0.3として記載します。

### Aerospikeの起動
- Community Editionを起動する場合は、以下の通りです。(nameは適宜変更してください。)
    ```
    sudo docker run -d --name aerospike_ce -p 3000-3002:3000-3002 aerospike:ce-6.1.0.3
    ```
- Enterprise Editionを起動する場合は、以下の通りです。 (nameは適宜変更してください。)
    ```
    sudo docker run -d --name aerospike_ee -p 3000-3002:3000-3002 aerospike:ee-6.1.0.3
    ```
    上記の場合、試用ライセンスのためノード数が1つに制限されますが、すべての機能がご利用いただけます。

- お持ちのFeature-Keyを指定してEnterprise Editionを起動する場合は、以下の通りです。 (nameは適宜変更してください。)
    ```
    sudo docker run -d -v [DIR]:/opt/aerospike/etc/ -e "FEATURE_KEY_FILE=/opt/aerospike/etc/features.conf" --name aerospike_ee -p 3000-3002:3000-3002 aerospike:ee-6.1.0.3
    ```
    [DIR]にはローカルのUbuntuのディレクトリを指定し、そのディレクトリに事前に保有のfeatures.confを保存してください。

    必要に応じて以下を実行し、上記のコンテナにログインしてください。
    ```
    sudo docker exec -it [コンテナ名] /bin/bash
    ```

### 補足
Community EditionおよびFeature Keyをお持ちの場合は、複数ノードでご利用いただけます。
Dockerでの複数ノード構成は、ご利用方法によって最適な方法が違ってきますので、いくつかのパターンについて、今後、投稿します。

# 最後に
上記では、Windows11上のWSLでの実行を説明しましたが、Windows11上のDocker DesktopやMacのDockerでも同様にAerospikeを実行することができます。
まずは、お気軽にAerospikeを使ってみてください。

[次の記事](https://qiita.com/aerospike_nakadai/items/7d8ecfa376b1206cbe5a "Aerospikeを使ってみる：Dockerを使ってCRUDのテストと管理")では、CRUDの操作や管理の方法を説明します。
OSについて調べてみた

# 参考文献

https://eng-entrance.com/programming-os

# OSとは

オペレーティングシステムのこと。
ユーザとハードウェアの橋渡しをするための基盤ソフトウェア。

# OSの主なもの

- Windows
- macOS
- Unix
- Linux
- BSD
- iOS
- Android

# Windows

Microsoft社が作成した

# macOS

Apple社が作成した
BSDを基としたApple開発のUnix系OS

現在はMacintosh上でWindowsとのデュアルブートも可能

# Unix

ベル研修所が発表
macOSなど、色々とUnixを元にしたOSはある
黒画面でコマンド操作する

# Linux

オープンソースのOS
Linuxは企業のサーバとして使われることが多い
Linuxはたくさん種類がある
黒画面でコマンド操作する
主要ディストリビューション

-「RedHat系」→有償、CentOSやFedora
-「Debian系」　→ボランティア、UbuntuやLinux mint
-「Slackware系」→一つの完成形、安定性が高い、セキュリティ、速い

# BSD

Unix系統のOS
配布ライセンスはBSDで最も自由度の高いライセンス

# iOS

Apple社開発のiPhone用のOD

# Android

Google社開発のOS
Linuxカーネルとその他オープンソースソフトウェアを元に開発された
スマホだけでなく、カーナビやクルマそのものなどメガネなどのも搭載されてきている
BibLaTeXの設定メモ

LaTeXは文章を書くのには良いのだが、レイアウトとかスタイルを設定しようとすると色々と面倒だと改めて感じたので、自分のためにメモを残す。今回は主にBibtexでの文献管理関連のことをメモする。

# LaTeXの環境について
最近は文献の管理にPaperpileというのを使っている。
https://paperpile.com/?welcome
Chromeのブラウザ拡張を使うと、気になる文献があったらボタン一つで登録できるのでとても重宝している。

最近はローカルにLaTeXの環境を作るのが面倒になったのと、共著者と一緒に文章を書くときに共有するのが楽なのでOverleafを使うようにしている。
https://www.overleaf.com/
Overleafを日本語で使うためにはひと手間必要だけど、そもそも日本語で何か文章を書くときはなるべくLaTeXを使わないようにしている。

# BibLaTeXを使う

で、bibtexをつかった文献の引用方法について。以前からなんとなく誤魔化しながら使っていたが、引用した文献のリストのスタイルをなんとかしようとすると、bstファイルを直接変更する必要があってとても面倒。いい加減なにかいい方法がないかと思って調べたところ、最近はBibLaTeXというのを使うのが良いみたい、というのを知った。

まずPaperpileの文献リストをOverleafに取り込む。
https://ja.overleaf.com/blog/how-to-create-a-bibliography-using-overleaf-and-paperpile-a-step-by-step
これで文章を書いている途中に新しい文献を追加しても、自動でアップデートされるようになる。とても便利。

あとは必要な設定を書くだけ。今書いている文章の設定を書く。

```tex:main.tex
\documentclass{article}

\usepackage[backend=biber,style=phys,%
articletitle=false,biblabel=brackets,%
chaptertitle=false,pageranges=false,%
eprint=true,%
maxnames=3]{biblatex}
\addbibresource{paperpile.bib}
\renewcommand*{\bibfont}{\small}
\setlength\bibitemsep{0.1\baselineskip}

\begin{document}

...

\printbibliography

\end{document}
```

オプションは色々あるけど、自分が簡単な文章を書くときは上の設定でだいたい満足できる出力を得ることができた。

# 上の設定に辿り着くまでに調べたこと

基本的にここにまとまっていた。
https://paper3510mm.github.io/latex/bibtex3.html
引用すると
> 文献リストで文献がどのように表示されるかは、使っている文献スタイルファイル（bstファイル）に依存する。しかし、既存のbstファイルによる文献表示に満足できなかったり、サポートされていないフィールドを出力したいと思ったりするかもしれない。このように文献リストの調整やカスタマイズをすることは、あまり容易ではない。方法としては以下のようなものが挙げられる：
> 1. 直接bstファイルを編集する。
> 2. BibLaTeXを用いる。
> 3. amsrefsパッケージを利用する。
> 4. Bibulousを用いる。
> 5. 自動でのカスタマイズは諦めて、bblファイルを手動で調整する。

という選択肢がある。2のBibLaTeXを使う、というのが自分なりの結論。

1の直接bstファイルを編集するというのは、原理的にはやりたいことがなんでもできること自体は知っていたが、bstの文法は自分には見てすぐに理解できるものではなかったので、なかなか手をつけられずにいた。
https://qiita.com/HexagramNM/items/7c59f307e55010caf693

自分の目的に合ったbstファイルが存在していれば良いのだが、意外と細かいところが思い通りでなくて困っていた。
https://mathlandscape.com/latex-bibstyles/
ここから目的に近いものを探して、細かいところは自分で修正する、というのが良いのかとは思っていたが、それでもなかなか難しい。

日本語で使うならば、jecon.bstを使うのが良さそうな気がする。少なくともbstの中身を見て、自分でもある程度カスタマイズできそうな気がした。しかし、私は基本的に日本語ではLaTeXを使わない方針にしている。
https://github.com/ShiroTakeda/jecon-bst

amsrefsやBibulousというのはよくわからないのでパス。そもそもOverleaf上で使えるのか不明。

bblを手動で調整するのは少々手間はかかるけど確実な方法。引用文献が少なければなんとかなるかもしれないけど、Overleaf上でPaperpileを使う、という私の環境だと、bblをダウンロードして、編集して、アップロードする、という手間がかかるのでかなり面倒なので最終手段としては良いがあまりやりたくない。

適当なbstファイルがなくて、いまいち文献引用のスタイルがカスタマイズできずに困っている人も多いかと思い、メモを残しておく。
JQuery

# JQueryとは
開発の現場で全てを自分で0からコードを書くことも可能だが、よく使われる機能を実装しやすいようにひとかたまりのコードにしてくれているのがライブラリ。
JQueryはJavaScriptのライブラリの一つ。

主な機能として
・DOM操作
・イベント
・CSS操作
・エフェクトとアニメーション
・AJax

などがある。

最近の開発の現場ではあまり使われない。
Webブラウザ間での揺らぎがJQueryを使わなくても大きく無くなったため。
https://www.webstaff.jp/guide/trend/jquery/

https://releases.jquery.com/

# DOMの取得

### 要素の取得
```javascript
const main = $('#main');
console.log(main);
```
```javascript
$('.article')
$('p')
$('[show="on"]')
$('#main > p:first-child')

```

### テキストの変更
```javascript
$('#main > p:first-child').text('変更されました');
```

### HTML要素の書き換え
```javascript
$('#main > p:first-child').html('<ul><li>リスト1</li><li>リスト2</li></ul>')
```
HTMLを書き換えるのはセキュリティ的に微妙なところもありそう。あくまで例示しているだけなので良いやり方は調べてください。

### 要素の削除

```javascript
$(#main > p:first-child').remove()
```

### CSSクラスの追加

```javascript
$('#main > p:first-child').addClass('red');
```

### CSSクラスの切り替え
そのクラス名があれば外してなければつける
```javascript
$(''#main > p:first-child).addClass('red');
```

### CSSスタイルの追加,変更

```javascript
$('#main > p:first-child').css((
    color: 'red',
    fontSize: '30px',
    backgrondColor: 'black'
});
```

### 属性の追加・変更
第一引数=属性名
第二引数=その値
```javascript
$('$main > p:first-child').attr('show', 'on');
```

### DOMの生成
```javascript
const $el1 = $('<p>').text('追加されたテキスト1');
const $el2 = $('<p>').text('追加されたテキスト2');

$('#main').prepend($el1);
$('#main').append($el2);
```

### イベント処理
```javascript
const $target = $('#main > p:first-child');

$target.on('click', function(){
    $(this).css({
        color: 'red',
        fontWeight: 'bold'
    });
});
```
ZeroNetを使う

# きっかけ
こういうの興味あったから

# 環境
- Ubuntu22.04 LTS
- Python3.9.7

# やってく
早速公式サイトからd……って言いたいところですが、**実はZeroNetの公式Githubの更新は一年以上されていません**

さらに、**TorのOnion v3に対応していません**

~~終いにはissueで「開発者どこいったん？」と聞かれる始末~~

ちなみに実際に使ってみましたが、**結構遅いです**

NO PEERS FOUNDがずっと表示される

以上の理由から公式のやつは使いません

# 代替品
[zeronet-conservancy](https://github.com/zeronet-conservancy/zeronet-conservancy)を使います

理由は[ZeroNetをforkしたリポジトリを人気順に並べた](https://gitpop2.vercel.app/HelloZeroNet/ZeroNet)ときに、上位にあったからです

次に人気のある[ZeroNetX](https://github.com/ZeroNetX/ZeroNet)を使ってもいいと思います

もちろん、どちらも開発は現在進行系ですし、更新日も比較的最近です

**--追記--**
ZeroNetX使ってみましたがまず最初の画面でずっとロードしてて使い物になりませんでした
多分[zeronet-conservancy](https://github.com/zeronet-conservancy/zeronet-conservancy)がいいと思います

# 今度こそやってく
まず依存関係をインストールしましょう
と言ってもPython3系を入れるだけなので簡単です(適当に調べたら出てきます)

次は本体をダウンロードしてきます

下記のコマンドでダウンロード
```bash
$ git clone https://github.com/zeronet-conservancy/zeronet-conservancy
```

もしgitコマンドが無かったら、githubのページから圧縮ファイル拾ってきて展開してください

**--追記--**
Pythonライブラリ依存関係のインストール忘れてました
すみません
```bash
$ cd zeronet-conservancy
$ pip install -r requirements.txt
```

**--------**

実行は以下のコマンド
```bash
$ cd zeronet-conservancy
$ python3 zeronet.py
```

注意点として、**zeronet.pyは必ずzeronet-conservancyをカレントディレクトリにして実行してください**

これは、**プログラムのファイル参照の方法が相対パスだからです**(~~何してんねん~~)

あとはお好きなブラウザで`http://127.0.0.1:43110`にアクセスするだけです

公式と比べたらめっちゃ早くページがロードされます

# おまけ
## torとの併用
公式の方はtorの起動も自動でやってくれたんですが、今回紹介したやつはやってくれません

なので手動で起動、という形になります

tor本体はなんかTor Browserを入れたら勝手に入ってました(そりゃそう)
```bash
$ sudo service tor start
# or
$ tor # 個人的にはこっちのほうがアクセスログ表示されるし好きです
```

別端末から以下のコマンドで起動確認
torrcを弄ってなければ9050ポートが開くはずです
```bash
# serviceコマンドで起動した場合
$ sudo service tor status

# torコマンドで起動した場合
$ lsof -i:9050
```

ログを見る限り、今回紹介した[zeronet-conservancy](https://github.com/zeronet-conservancy/zeronet-conservancy)は、tor接続だとポートは開かない仕様っぽいです(つまり自分は見る専になるということ)

**Tor Browserとの併用方法はよくわかりません**(ドキュメント通りにやったのに……(´・ω・`))

# ZeroIDについて
過去の紹介記事を見ると、「ZeroIDを取得しましょう」みたいなことを書いてる記事が多いです

しかし現在、**なぜかZeroIDを取得しようとするとエラーが発生します**
具体的には「Error while during request: Forbidden」などと表示されます

対処法は知りませんし、公式の方のissueを見たところ「推奨すべきでない」みたいなこと議論されてて🤔ってなりました

ZeroTalkとかは別のIDが使えるっぽいのでそっち使いましょう

**--追記--**
久しぶりに見たらなんか取得できました
エラーにめげずにめっちゃポチポチしてたら多分できます

# 終わりに
今ZeroNetの掲示板クソ過疎なので、変なニュースサイト見たり英語の掲示板で情報収集くらいしかやることありません

~~MangaとかAnimeみたいないかにも割れを配信してそうなサイトは怖くて行けません~~

それでも、いるとこには数百人くらいいるっぽいです

というわけで、よいZeroNet生活を！！
Pythonでjsonlを読み書きする

## [jsonl](https://jsonlines.org/)とは
改行区切りの１レコードがjsonになっているデータのことです。
こんなデータ↓

```json
{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
```


## pandas使わない方法
### ファイル読み込み
```python
import json
with open('hoge.jsonl') as f:
    jsonl_data = [json.loads(l) for l in f.readlines()]
```

### ファイル出力
```python
with open('fuga.jsonl', 'w') as f:
    f.writelines([json.dumps(l) for l in jsonl_data])
```

## pandas使う方法
### ファイル読み込み
```python
import pandas as pd
df = pd.read_json('piyo.jsonl', orient='records', lines=True)
```

### ファイル出力
```python
df.to_json('piyopiyo.jsonl', orient='records', force_ascii=False, lines=True)
```

## 感想
- 備忘録です。
- pandasで読んだり、readlines()で読んだりしてるなぁと思ったので書いておきました。
3日で取得する統計検定2級

こんにちは。
この度、統計検定2級に合格しましたので、それまでの３日間で行ったことを書いておきます。

対象読者は私と同じ条件ということで、

:::note info
- 文系の大学生
- 数IAの統計の分野は学んだが、数IIBの統計分野は学んでいない
（中央値、平均値、分散、標準偏差、四分位数辺りは知っている）
- 1日5, 6時間程度は確保できる
:::

という方を対象にしています。1日3時間なら、1週間程度かかるかもしれませんし、合格だけなら1日でも可能かもしれません。

# １日目
**ヨビノリ様の[確率統計の動画](https://www.youtube.com/watch?v=Bj8fkq533Dc&list=PLDJfzGjtVLHmx7qMP410-9gx0weC9d90X)を、機械学習のものを除いて一通り見る。**

勉強時間が少ないので、**いきなりチートシートのようなものを見てしまいがちですが、最初に見ても混乱するだけ**です。
したがって、最初は**新しい概念がゆっくり１つ１つ出てくる**講義形式をおすすめします。

ヨビノリ様の講義は、難しすぎず、ざっくりすぎない解説をなさっているので、２級の受験生にうってつけの内容となっています。これらを視聴することで、推定・検定に用いる公式やその使い方をスムーズにインプットすることができます。

そして、**自分でもチートシートのようなものを作りながら受講する**と、頭の中も整理できますし、後々便利です！

# ２日目
昨日の内容を復習しましょう。どんな状況でどういった推定・検定を行うのかをざっくり説明できればOKです。

それが済んだら、ネットで公開されているチートシート（[こちらの記事](https://qiita.com/moriokumura/items/ed246efe11fc5d3fc760)や[こちらの記事](https://toketarou.com/cheatsheet/)）を見て、**試験範囲内だが自分に足りていない知識を確認**していきましょう。
おそらく、半分くらいは知っている公式で、知らない公式の方も比較的シンプルだったり名前通りの公式だと思うので、混乱してパニックになるほどではないと思います。

**この時点で知らない公式の量は結構多い**と思いますが、１つ１つの公式について、ググったりしながらイメージを固めていってください。

# ３日目
１，２日目の復習を行います。
チートシートで、どんな時にどんな公式を使うかを答えられるようにしましょう。
[過去問](https://www.toukei-kentei.jp/prepare/kakomon/)も１回分は無料で見られますし、数年分は書籍として売っているので、解いてみるのが良いと思います。**合格の目安は6割程度です。**
復習がすんだら、しっかりと睡眠を取りましょう。

# 当日
朝に改めてチートシートを確認しておくと安心です。

# まとめ
だらだら勉強しがちな資格試験ですが、「３日後に受験する！」と決めて**申し込んでしまえば、これ以上ない強制力となりますし、集中して勉強するので無駄な時間を過ごすことも減ります**。

もっとも、資格自体が無駄であることもあるので注意する必要があります。私の場合は統計に興味はあったものの、学ぶ明確な目標がなく他の短期的な誘惑に屈していたので、わかりやすい仮の目標として資格試験を設定したことで、３日とは思えない充実が得られました。

特に学生の方は、5000円という**高すぎない ~~が充分に高い~~ 値段**でいつでも受験できますので、統計を学んでみたいがやる気が出ない方は、即座に申し込んで勉強せざるを得ない状況を作ることをおすすめします。
【SwiftUI】タイピング風テキストアニメーションを作ってみた

# はじめに
ChatGPTはAIからの返答がタイピング風のアニメーションで返ってきます。
これをSwiftUIで再現できないかなと思い試してみました。

![画面収録_2022-12-27_21_24_15_AdobeExpress](https://user-images.githubusercontent.com/84154073/209666946-f0f3dfb6-0459-40d9-a56e-3102bbf5fd1c.gif)

# サンプルアプリ
ChatGPTの返答をそのまま表示してます
![Simulator Screen Recording - iPhone 14 Pro - 2022-12-27 at 21 35 11](https://user-images.githubusercontent.com/84154073/209667552-b15dfd1c-821d-4279-afb9-558920d3c279.gif)

# 実装
```swift:ContentView
import SwiftUI

struct ContentView: View {
    @State var isStart: Bool = false
    private let input: String = """
            SwiftUIは、Appleが開発したiOS、macOS、watchOS、tvOSを対象とするUIフレームワークです。

            SwiftUIは、より簡単でスマートな方法でUIを構築することを目的としています。SwiftUIでは、UIを宣言的に記述し、プレビューでリアルタイムに表示されるため、デザインと実装を効率的に行うことができます。

            SwiftUIでは、画面を構成するUI要素（テキスト、画像、ボタンなど）を宣言するだけで、自動的にレイアウトが生成されます。また、SwiftUIでは、アプリケーションの自動更新機能を使用することで、データの変更が自動的にUIに反映されるようになります。

            SwiftUIでは、多数のプラットフォームをサポートするため、同じコードを使用して、iOS、macOS、watchOS、tvOSのアプリケーションを構築することができます。

            また、SwiftUIでは、Accessibility、Dark Mode、Localizationなどの機能も簡単に実装することができます。

            SwiftUIを使用することで、より効率的でスマートな方法でUIを構築することができるため、現在では非常に人気のあるUIフレームワークとなっています。
            """
    var body: some View {
        VStack {
            Button {
                isStart = true
            } label: {
                Text("スタート")
            }

            TypeWriterTextView(
                input,
                speed: 0.1,
                isStart: $isStart
            )
        }
        .padding()
    }
}
```

```swift:TypeWriterTextView
import SwiftUI

struct TypeWriterTextView: View {
    private let text: String

    private let speed: TimeInterval

    @Binding var isStart: Bool

    @State private var textArray: String = ""

    init(_ text: String, speed: TimeInterval = 0.1, isStart: Binding<Bool>) {
        self.text = text
        self.speed = speed
        self._isStart = isStart
    }

    var body: some View {
        Text(textArray)
            .onChange(of: isStart) { _ in
                startAnimation()
            }
    }

    private func startAnimation() {
        DispatchQueue.global().async {
            let _ = text.map {
                Thread.sleep(forTimeInterval: speed)
                textArray += $0.description
            }
        }
    }
}
```

# おわり
ちゃんと使えるようになったらライブラリにでもしようかと思ってます
[C#]  メモtip:UDPマルチキャストを受信する(送受信同一ホスト対応)

# はじめに
とあるソフトがマルチキャストで送信する信号を同一のホストで受信解析する仕組みが欲しく、
UDPClientの使い方を調べるもどうにもローカルホストを考慮したサンプルが見つからず、
ようやく見つけたのでメモ。

# 結論
以下のように書けばよい。

```c#

public static void Main(string[] args)
        {
           
            UdpClient client = new UdpClient();
            client.ExclusiveAddressUse = false;
            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 5568);
            client.Client.Bind(localEp);
            client.JoinMulticastGroup(IPAddress.Parse("239.255.0.1"), IPAddress.Any);
            client.JoinMulticastGroup(IPAddress.Parse("239.255.0.2"), IPAddress.Any);
            
            while (true)
            {
                try
                {
                    byte[] data = client.Receive(ref localEp);
                    string text = Encoding.ASCII.GetString(data);
                    Console.WriteLine(localEp.Address);
                }
                catch (Exception e)
                {
                    
                }
            }
        }

```

## プチ解説

ローカルで回すことなんて考慮されてないのかMSのドキュメント(Multicast)にはぱっと見存在しない以下の2行が大事
```c#
client.ExclusiveAddressUse = false;
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
```

### ExclusiveAddressUse
以下ドキュメント引用
> Socket で 1 つのプロセスだけにポートのバインドを許可するかどうかを指定する Boolean 値を取得または設定します。

https://learn.microsoft.com/ja-jp/dotnet/api/system.net.sockets.socket.exclusiveaddressuse?view=net-7.0  

### SocketOptionName.ReuseAddress
以下ドキュメント引用
> SocketOptionName.ReuseAddress 既に使用されているアドレスにソケットをバインドすることを許可します。

https://learn.microsoft.com/ja-jp/dotnet/api/system.net.sockets.socketoptionname?view=net-7.0
個人開発、サークル開発における構築パターン案

# はじめに

もうすぐ年末年始のお休みですね。まとまった休みになるので、個人開発を始めてみようといった人もいるかと思います。
個人開発をするときにどんな開発パターンがあるか、少しまとめてみたいと思います。
また、個人開発に関わらず、仕事ではない複数人のチーム開発という意味でサークル開発というのも同じくスコープに入れます。

# 方向性決めについて

個人開発をするときに、以下のどちらかのパターンになると思います。

## 技術から入るパターン

こんな技術を見聞きしたけど、それの実践編として動くアプリを作ってみたいというケースです。
目的としては、その技術の習熟度を上げる、学ぶということが主軸になります。


## ニーズから入るパターン

機能ベースで、こんなものをざっくり作ってみたいとか、こんな困り事があるのでアプリ作って課題解決したいといったケースです。
ニーズの出元としては、自分自身が使いたいというものもあるかもしれませんし、家族や知り合いが困っていたというケースもあります。
また、未知なるニーズに応えるという意味では、新規ビジネスになりそうなサービス開発のようなものもここから始まるのだとは思います。

有名な例としては、FaceBookは、大学内での名簿も兼ねたソーシャルサービス、ゲームとして作り出されたものというものもあります。

https://ja.wikipedia.org/wiki/Facebook

# アプリ種類ごとのアーキテクチャパターン

今回は上記どちらのパターンから入ってもよいように、カタログ的にあげ出していきたいと思います。

## スタンドアロンアプリ

アプリから外に通信をせずに、端末内でクローズした形で動くアプリケーションです。例としては、電卓、BMI計算、バックアップ機能がないカメラアプリ、通信機能のないゲーム全般などがあります。
扱う技術については、動作環境により異なります。PC上でのデスクトップアプリであれば、Javaを扱いたければJavaFX、Windows系でC#、Pythonでもデスクトップライブラリがあります。
一方、スマホアプリでは、iOSであればSwift、Androidであれば今はKotlinで開発していく形になるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/98c1c02b-396c-2ac3-0dca-6f622e260840.png)

GUIではなく、CLIアプリであれば、Shellだけでも実現できますが、これはアプリというよりツールかなと思いましたので詳細の説明は割愛します。

## Webサイト

これは、静的なコンテンツとしてサイトを作るというものです。静的とはいいつつ綺麗なUIを実現することができます。
具体的な例としては企業や個人のホームページなどがあります。
扱う技術としては、フロントエンド関連の技術となります。利用者からはブラウザ経由でアクセスするためです。一方、ブラウザといえどもPCであったり、スマホのプラウザだったり、iPadのようなタブレットであっても表示崩れなく表現するようにしていくには技術が必要となります。SPA（Single Page Application)の技術や、JavaScript、HTML、CSSといったフロントエンド技術の進化は数年激しいものになってきていますので、技術として飽きはこないでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/e3d803af-8930-573c-ea07-7121e07389c6.png)


## Webアプリケーション（サーバー単体）

仕事で扱うパターンとして最も多いものかと思います。
利用者のアクセス端末としては先ほどのWebサイトと同じで、PCやスマホやタブレットになります。ただし、利用者の想定によってタブレットやスマホは対象外にしたりすることもありえます。個人やサークル開発ではなおさらスモールスタートになると思うので、まずどこを対象にするのかかが考えることになります。

具体的な例としては、ブラウザ経由で動かすシステム全般になると思います。掲示板のような利用者から送信したデータを他の利用者にも見せたりするといったものまでかなり広い範囲で機能実現することできます。１つ目のパターンの例で示した電卓アプリやゲームなどを端末へのアプリインストールなしにブラウザだけで機能提供することも出来ます。

扱う技術としては、サーバー側のロジックも必要になりますが、実現手段は様々です。Java、Python、PHP、JavaScript（Node.js)、C#などからどれかをチョイスすれば良いと思います。データの永続化先（保管先）として、DBも用意することが多いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/9530135d-f601-720c-e43f-d0e829155517.png)

優れたUIを実現するために、ブラウザ経由ではなく、ネィティブアプリケーションで動かして、データだけをサーバーから取得することもあります。その際には先ほど記載したように、SwiftかKotlinを使うこともあります。

## Webアプリケーション（他サービスと連携）

先ほどのWebアプリケーション（サーバー単体）はそこで閉じる形でしたが、最近ではWebAPIの発展により、サービス単体で動くものではなく複数サービスを連携させて利用者に提供するものがほとんどです。
具体的な例としては、SNSとの連携機能付きのサービスとして、Qiitaなどもサービス連携と利用者許諾をすることで記事を書いたら自動でTwitterに記事を書きましたという内容の投稿がされたり、Connpassといった勉強会情報共有のプラットフォームがありますがそこから参加登録したらGoogleカレンダーに連携されて自分の予定が登録される、などの実例があります。

https://help.qiita.com/ja/articles/qiita-release-account-coop

https://help.connpass.com/basic/setting_calendar.html


郵便番号から住所を取得するなど、データ取得パターンとしての繋ぎ方もあります。そういった世の中のサービスやデータも活用しつつTotalで利用しやすいサービスを実現していきます。
AWSを始めとしたクラウドサービスの中のマネージドサービスを使うケースについても、このパターンに含まれるとも表現できるかなと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/d6dbe3cf-10d1-e09f-99d0-7505c4f2f95a.png)

# おわりに

何か開発したいといった際に、何をどうやって作ろうかと考える際の材料としてまとめてみました。
この後については、技術選定をしつつ、ソースコード管理、タスク管理などどうしようかなどを考えていく形になるかと思います。
【Linux】乱数を生成する方法

## 生成方法

`RANDOM`変数を使用することで乱数を生成できます。  
`RANDOM`変数は`0`から`32767`の間の数値を返却します。  

```terminal
$ echo $RANDOM
18739
```

数値の範囲を`0`から`9`までにしたい場合には以下のように実行します。  

```terminal
$ echo $(($RANDOM % 10))
4
$ echo $(($RANDOM % 10))
6
$ echo $(($RANDOM % 10))
0
$ echo $(($RANDOM % 10))
5
$ echo $(($RANDOM % 10))
7
$ echo $(($RANDOM % 10))
8
```

数値の範囲を`1`から`10`までにしたい場合には以下のように実行します。  

```terminal
$ echo $(($RANDOM % 10 + 1))
2
$ echo $(($RANDOM % 10 + 1))
4
$ echo $(($RANDOM % 10 + 1))
10
$ echo $(($RANDOM % 10 + 1))
9
$ echo $(($RANDOM % 10 + 1))
7
```

数値の範囲を`101`から`200`にしたい場合には以下のように実行します。  

```terminal
$ echo $(($RANDOM % 100 + 101))
195
$ echo $(($RANDOM % 100 + 101))
139
$ echo $(($RANDOM % 100 + 101))
101
$ echo $(($RANDOM % 100 + 101))
148
$ echo $(($RANDOM % 100 + 101))
142
```
競馬データEDA　その1

過去2年の中央競馬の6823レースを分析したものになります。
前提として、今回は複勝馬券内(3位以内)に入れば勝ち、それ以外を負けという扱いにし、分析します。
また、筆者のデータ分析の経験はタイタニックくらいですので参考にしてはいけません。

まず、勝ちと負けの馬の割合です。
![スクリーンショット 2022-12-20 13.27.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/37fff07b-dc5f-9784-c9da-80809380dc73.png)

## 性別による勝ち負けの差
male,female,gelding(センバ)の勝率の違いを見ています。

![スクリーンショット 2022-12-20 13.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/1fff68f9-8d5d-ba88-3e3d-5de6e77b5d61.png)
maleの勝率が5%前後高いことがわかります。また、出走数がmaleが一番多く、センバはかなり少ないというのが見えます。
![graph (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/52c005b1-20a0-e0d7-04ce-2c9dcc6fd75b.png)
```
下のracecourseのラベルの中身[0:'Hanshin', 1:'Tokyo', 2:'Nakayama', 3:'Chukyo', 4:'Niigata', 5:'Kokura', 6:'Kyoto', 7:'Fukushima', 8:'Sapporo', 9:'Hakodate']
```
8,9,6,4など、センバの勝率が高い馬場と低い馬場がはっきり分かれていることがわかります。また、maleの勝率はどこも2.3前後にいます。一方でmaleは8,9が高く、センバと連動してそうなグラフであると感じました。
また、8:'Sapporo', 9:'Hakodate',6:'Kyoto',4:'Niigata'など、緯度が高いほどmale以外が勝つ確率も上がっているように思えます(fukushimaだけ別ですが)
具体的な数は以下のようになっています。
![スクリーンショット 2022-12-20 13.33.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/cb34e7c6-7ec0-01e8-e7b0-8954163a45fc.png)

## オッズ,人気による勝ち負けの差
![スクリーンショット 2022-12-20 13.57.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/67576d2d-27c9-75f8-a5c9-8d1bff3c6ea0.png)
右がオッズごとの勝率で、左がオッズごとの勝ちと負けの数の合計のグラフになっています。
項目が細かすぎて黒塗りされてますが、オッズが高い(左に偏る)ほど勝率が高いことがわかります。

![スクリーンショット 2022-12-20 14.01.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/22cec0ce-9546-e172-11a5-8b5d2ae6841d.png)
また、一番人気の勝率が60%くらいで順調に右に下がっていることがわかります。人気順にしっかり勝ち負けが出ていることがわかります。
![graph (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/aefe7666-2ae8-fb5c-b074-167792fc47f5.png)

とりあえずデータを見て人間の馬を見る目はある程度正しくて、そこから競馬場ごとの性別の成績差などの差という付加価値を見つけていくことが必要だなと感じました。

まだまだ見ていきます。
paizaラーニング『フィボナッチ数』

https://paiza.jp/works/mondai/array_primer/array_primer__fibo

解らなかったです。。。

#### 解答例
```Python3
N = int(input())

fibo = [0] * N
fibo[0] = 0
fibo[1] = 1

for i in range(2, N):
    fibo[i] = fibo[i - 2] + fibo[i - 1]

for ele in fibo:
    print(ele)
```
４０代おっさんDockerメモ①

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## Dockerfile

DockerfileはUMLダイアグラムみたいなもの
Dockerイメージを作る設計書

- FROMでイメージを指定
  - `FROM イメージ名前：タグ(主にバージョンを表記するために利用されることが多い)`
- COPYでホストからファイルをイメージにコピー
  - ローカルファイルをコンテナの中にコピーする
  - `COPY コピー元 コピー先` 
- RUNでシェルコマンドを実行
  -  `RUN 実行コマンド`
- WORKDIRでコンテナが起動するときのディレクトリの絶対パス（推奨）を指定します
  - `WORKDIR 絶対パス`
- ENVで環境変数の設定ができます
  -  `ENV 環境変数名=値`
- CMDでコンテナ起動時に実行するコマンドとオプションを変更できます。 原則は末尾に記載です。
  - `CMD ["実行コマンド", "オプション1", "オプション2"...]`
paizaラーニング「二点間の距離 2 Python3編」

https://paiza.jp/works/mondai/array_primer/array_primer__array_distance_step2
#### 私の解答
```Python3
N, A, B = map(int,input().split())

X = [0] * N
Y = [0] * N
for i in range(N):
    values = input().split()
    X[i] = int(values[0])
    Y[i] = int(values[1])


print(abs(X[A-1] - X[B-1]) + abs(Y[A-1] - Y[B-1]))
```
#### 解答例
```Python3
values = input().split()
N = int(values[0])
A = int(values[1])
B = int(values[2])

X = [0] * N
Y = [0] * N
for i in range(N):
    values = input().split()
    X[i] = int(values[0])
    Y[i] = int(values[1])

print(abs(X[B - 1] - X[A - 1]) + abs(Y[B - 1] - Y[A - 1]))
```
paizaラーニング「二点間の距離 1 Python3編」

https://paiza.jp/works/mondai/array_primer/array_primer__array_distance_step1
#### 私の解答
```Python3
n = int(input())
for i in range(n):
    values = input().split()
    ans = abs(int(values[0]) - 2) + abs(int(values[1]) - 3)
    print(ans)
```
#### 解答例
```Python3
N = int(input())

X = [0] * N
Y = [0] * N
for i in range(N):
    values = input().split()
    X[i] = int(values[0])
    Y[i] = int(values[1])

for i in range(N):
    print(abs(X[i] - 2) + abs(Y[i] - 3))
```
Rigidbody2D.IsTouching(Collider2D)による接地判定時にlocalScaleで左右反転すると判定がブレる事がある

# はじめに
本記事はUnityで2Dアクションゲームを作っている時に躓いた点を備忘録として記録しております。
こうすると判定がブレないよ！という実装方法がありましたらコメントで教えて頂けると幸いです(;'∀')

# 参考記事
キャラクターの接地判定を行うにあたって、以下の記事を参考にさせて頂きました。
ColliderやRayを使った接地判定より使いやすいので、毎度使わせて頂いております！感謝！

https://tsubakit1.hateblo.jp/entry/2018/04/07/234028

# 今回問題になった事
で、今回何が問題になったのかですが…

2Dアクションゲームでキャラクターが左右に移動する際、キャラクター反転の方法として
「transform.localScaleのx値をマイナス値にする」事で再現している記事は多いかと思います。

僕もこの方法で実装していたのですが、
参考記事に記載した「Rigidbody2D.IsTouching(Collider2D)」による接地判定と組み合わせて使っていると、
左右を振り向いた際に接地判定がfalseを返すタイミングがありました。

**▼接地してる時はTrue**
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56177/1e788cf0-ace3-1d40-880e-85b6e74d0c72.png)

**左右に動かすとFalseが返るタイミングがある！**
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56177/afc5ef3f-8049-3c39-e498-630f91736c98.png)

# 解決策
結局、左右反転については「SpriteRenderer.FlipX」を使う事で解決しました。
SpineAnimationを使っている場合は「SkeletonAnimation.skeleton.ScaleX」となります。

# 問題が起きたコード
こちらになります。本番コードからの切り抜きなので説明不足な部分もありますがご了承下さい。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestController : MonoBehaviour
{
    [SerializeField] private ContactFilter2D filter2d;
    float movespeed = 1.5f;
    bool isTouched;
    Vector3 move_control;
    protected PlayerInput playerinput;
    Rigidbody2D rb;

    protected void Awake()
    {
        playerinput = new PlayerInput();
        playerinput.Enable();
        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        isTouched = GetComponent<Rigidbody2D>().IsTouching(filter2d);

        Vector2 newvec = Vector2.zero;
        move_control = playerinput.Player.Move.ReadValue<Vector2>();

        if (move_control.x != 0.0f)
        {
            Vector3 ls = transform.localScale;

            if (move_control.x > 0.0f)
            {
                newvec.x = movespeed;
                ls.x = -Mathf.Abs(ls.x);
            }
            else if (move_control.x < 0.0f)
            {
                newvec.x = -movespeed;
                ls.x = Mathf.Abs(ls.x);
            }
            transform.localScale = ls;
        }
        //移動速度を適用する。
        rb.velocity = newvec;

        print("?:" + isTouched);
    }
}

```
thiserror の feature(provide_any) で出る E0554

# エラーの詳細
Rust に [thiserror](https://github.com/dtolnay/thiserror) という、広く使われているライブラリがありますが、このライブラリに（間接的にでも）依存しているクレートをビルドするときに以下のようなエラーが出ることがあります。

```
error[E0554]: `#![feature]` may not be used on the stable release channel
   --> C:\Users\user\.cargo\registry\src\github.com-1ecc6299db9ec823\thiserror-1.0.38\src\lib.rs:238:34
    |
238 | #![cfg_attr(provide_any, feature(provide_any))]
    |                                  ^^^^^^^^^^^

For more information about this error, try `rustc --explain E0554`.
```

# 解決法
```
$ cargo clean -p thiserror
```

# 原因
よくわかりません。この問題の[issue](https://github.com/dtolnay/thiserror/issues/192)が出ていますが、ライブラリの開発者は古いバージョンのrust-analyzerかIntelliJを使っているのが原因だと言っています。

私の環境は以下の通りです。
|ソフトウェア|バージョン|
|:-:|:-:|
|thiserror|1.0.38|
|Windows|11|
|cargo|1.65.0 (4bc8f24d3 2022-10-20)|
|rustc|1.65.0 (897e37553 2022-11-02)|
|toolchain|stable-x86_64-pc-windows-msvc|
|CLion|2022.3.1|
|CLion Rust プラグイン|0.4.185.5086-223|