OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveRecord::RecordNotFound(Couldn't find Member with 'id'=2)エラーについて


初めての投稿です。
プログラミングスクールの卒業制作のような位置付けでオリジナルアプリを作成していて、エラーが出たので備忘録として投稿します。
読みにくい部分もあるかと思いますがご容赦ください。

## 開発しているアプリ
- 自分の趣味で所属している団体内（約７０名が所属）で使用することを想定した連絡ツールアプリ。
- 今後はメール一斉送信機能、メンバーを指定したチャット機能、データファイル投稿機能などを実装予定。

## 実装環境
- MacOS Ventura13.0
- Ruby 2.6.5
- Rails 6.1.6.1
- MySQL 14.14
- TablePlus 5.1.0(本番環境のデータベースを管理)

## 状況
- deviseを使ってユーザー新規登録とログイン機能を実装済み。
- マイページ・ユーザー情報編集機能を実装。
- さらに、ユーザー情報より詳細な団員情報の登録・編集機能を実装。
- renderを使ってデプロイが完了。

## 関係するDBの構成
- ユーザー情報：usersテーブル
- 団員情報：membersテーブル
- 双方のテーブルは１対１の関係（usersテーブルが親、membersテーブルが子）
　
## 起こったこと
- デプロイ後、本番環境での動作確認を実施。
- 団員情報編集ページへのリンクをクリックしたら、"The page you were looking for doesn't exist."というエラー画面が表示された。
- ログを見てみると、"ActiveRecord::RecordNotFound(Couldn't find Member with 'id'=2)"とある。

## 解決方法
リンクのパスが間違っていた（下記のコードのedit_member_pathの後のidに注目）。

## コード
修正前
```ruby
<%= link_to '団員情報を編集', edit_member_path(@member.user_id), class:"member_info_btn" %><br>
```
##### 修正前の段階で考えていたこと
membersテーブルはuser_idを外部キーとして参照しているから、リンクのパスにもuser_idを指定しないといけない！（思い込み）

##### 試したこと・考えたこと
- 本番環境でのログをよく見てみると、"Couldn't find Member with 'id'=2"とある。
- TablePlusで登録されている情報を見ると、"id =2"は団員情報（member）に紐づいているユーザーのidを示している。
- 当時、member情報は１つしか登録されていなかったため、エラー文にて「member情報でid=2のレコードが見つかりません」と出ていた、とわかった。 
- 外部キーとか考えず、単純にmemberのidをリンクのパスに含めれば良いのでは、と考え、以下のように修正。

修正後
```ruby
<%= link_to '団員情報を編集', edit_member_path(@member.id), class:"member_info_btn" %><br>
```
これでリンク先のページに飛べました！


#### 感想（読み飛ばしていただいて構いません）
解決に至る前からこうやって記事を書いていたら、頭の中で思考が整理されて解決に至ったので、勇気を出して記事を書いて良かったなあ、と思います。
解決後は「こんなしょうもないことで…」と思ってしまい投稿するのも恥ずかしく思えますが、解決の記録がつくことで自分の糧になりそうなので、勇気を出して投稿しました。
これから先の実装も頑張っていきたいと思います。

最後まで読んでいただきありがとうございました。
【python】勉強メモ-その8 辞書


#### ループを利用した辞書の作成
```sample_01.py
# user情報を格納するためのリストを作成
users = []

# 作成したuserのリストに、user情報を辞書型で作成、追加
for user_num in range(10):
    new_user = {"name": "ichiro", "age": 100, "tall": 180}
    persons.append(new_user)

# 5人分だけ出力
for user in users[:5]:
    print(user)

print("")

print(f"作成した人物の人数：{len(users)}")

```

```result.txt
{'name': 'ichiro', 'age': 100, 'tall': 180}
{'name': 'ichiro', 'age': 100, 'tall': 180}
{'name': 'ichiro', 'age': 100, 'tall': 180}
{'name': 'ichiro', 'age': 100, 'tall': 180}
{'name': 'ichiro', 'age': 100, 'tall': 180}

作成したユーザー数：10
```


#### 値をリスト形式で辞書を作成＆値の取得方法
```sample_02.py
menu = {
    "Meat_dish": ["焼肉", "すきやき"],
    "fish_dishes": ["刺身", "寿司"]
}

for order in menu["Meat_dish"]:
    print(order)

print("")

for order in menu["fish_dishes"]:
    print(order)

```

```result.txt
焼肉
すきやき

刺身
寿司
```
#### 辞書の値に辞書を入れる

```sample_03.py

users = {
    "yamada" : {
        "first": "ichiro",
        "last": "yamada",
        "age": 20
    },

    "sato": {
        "first": "jiro",
        "last": "sato",
        "age": 10
    }
}

for user_name, user_info in users.items():
    full_name = f'{user_info["last"]} {user_info["first"]}'
    print(full_name)
    print(user_info['age'])
    print("")

```

```result.txt
yamada ichiro
20

sato jiro
10
```
viteを使っていて、ローカル端末でpwaのエラー

# 事象
PWA対応していないのにPWA関連エラーがブラウザで出る。

# 原因
* 他の開発アプリのポートと同じ
* 他の開発アプリがPWA

# 対応
他の開発アプリとポートを分ける。
```vite.config.ts
server: {
    port: 5175
}
```
ドライブバイダウンロード とは

## 勉強前イメージ

・・・・ドライブからダウンロードしか思い浮かばない、、、

## 調査

### ドライブバイダウンロード とは

DBDとも略され、特定のwebページにアクセスした際に知らない間に
不正なファイルなどをダウンロード・インストールする攻撃手法になります。
大体、不正なファイルからマルウェアに感染することが多いです。

流れとしてはwebページが改ざんされ、
webページにアクセスした際に自動的にダウンロードさせるように変更されてしまいます。
そこで、利用者がアクセスを行いダウンロードされてしまうというようなものになります。
主にアクセスするクライアントのOSやアプリケーションの脆弱性をついた攻撃に分類されます。

## 勉強後イメージ

そもそも攻撃の話だったのか・・・

## 参考

- [ドライブバイダウンロードとは？特徴と適切な対策について解説](https://boxil.jp/mag/a3342/)
- [ドライブバイダウンロードとは？仕組みや被害事例、対策方法について徹底解説](https://cybersecurity-jp.com/security-measures/23408)
C言語には値渡ししかないと考えた方が直交性が高くなる話

C言語において関数に引数を渡す仕組みの所で多くの場合は『C言語には値渡しとポインタ渡しの二種類があります。』と表現される事が多いと思うのだけど、この定義の仕方だと話がややこしくなるだけだと個人的には思っています。

# 新説: C言語には値渡ししかありません。
いいですか? ポインタ渡しという仕組みが値渡しと別にあるのではないのです。
ポインタ渡しと呼ばれているのは『ポインタ型の変数を値渡ししているだけ』なのです。

ポインタ渡しが値渡しとは別の仕組みだと定義してしまうと、型システムの話と引数渡しのシステムの二つの別の話がごちゃ混ぜになり、直交性が低くなります。

これは C++ での参照渡しも同じです。
C++ にも値渡ししかないのです。参照型の変数を値渡ししているだけなのです。

こう定義するだけで、大きな一つの問題を別々の問題に分けて理解する事が出来ます。
直交性が高いという事です。

ソフトウェア設計において、物事のあいだの直交性を見極めるのは極めて重要なスキルです。
プログラミングに従事する人がこの直交性を判別できないとしたら、それはなかなかの素人っぷりだと言えるでしょう。
Nuxt - npm run dev  – RpcIpcMessagePortClosedError: Cannot send the message

# 原因

調べるとwebpackの暗号化方式かなにかのせいらしい。

`NODE_OPTIONS=--openssl-legacy-provider` 環境変数を指定することで強制的に古い暗号化方式を使うことができるようだ。
webpackがバージョンアップして良い感じにしてくれるまで(？)これを付けておくととりあえず動きそう。

# 解決

`package.json`

```diff
{
  "name": "nuxt-project2",
  "version": "1.0.0",
  "private": true,
  "scripts": {
 -   "dev": "nuxt",
+    "dev": "NODE_OPTIONS=--openssl-legacy-provider nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate"
  },
...
```

#  エラー

```
$ npm run dev
```

```
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

RpcIpcMessagePortClosedError: Cannot send the message - the message port has been closed for the process 37967.
    at /Users/yumainaura/projects/YumaInaura/nuxt-project/node_modules/fork-ts-checker-webpack-plugin/lib/rpc/rpc-ipc/RpcIpcMessagePort.js:47:47
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21) {
  code: undefined,
  signal: undefined
}

Node.js v18.12.0
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

RpcIpcMessagePortClosedError: Cannot send the message - the message port has been closed for the process 37966.
    at /Users/yumainaura/projects/YumaInaura/nuxt-project/node_modules/fork-ts-checker-webpack-plugin/lib/rpc/rpc-ipc/RpcIpcMessagePort.js:47:47
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21) {
  code: undefined,
  signal: undefined
}

Node.js v18.12.0
```

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
React を多言語化した時の lang アトリビュートを書き換える

## react-i18next

```i18next``` を使うと、React アプリケーションなどを簡単に多言語化できる。多言語化できるが、html の lang アトリビュートを自動で書き換えてくれたりはしない。

```html:public/index.html
<!DOCTYPE html>
<html lang="en">
...
</html>
```

ここ。```lang``` アトリビュートは、そもそも必要なのか？という話しもあるが、SEO 的には全く無意味らしいが、翻訳などの時に誤認識されることがあるようだし、設定しておいた方が良さそうだ。というわけで、設定する。

## やり方

```typescript:App.tsx
...
import i18next from 'i18next';
...
  i18next.on('languageChanged', (lng) => {
    document.documentElement.setAttribute('lang', lng);
  });

  return (...);
```

おしまい。
プログラマーの為の識別子構成法 親子関係の単語編

『親を殺す前に子供は全員殺しておかなきゃいけないんだよ!! そんな当たり前の事も知らないのか!?』
これはソフトウェアエンジニアにとっては日常で発生し得る会話だが、ソフトウェアエンジニアリングに詳しくない人にはとても恐ろしい話に聞こえるらしい。

というわけでプログラマーの為の識別子構成法、親子関係の単語編である。

# ツリー構造の中のブツは親族呼称で表現する事が多い
ディレクトリ(フォルダ)とファイルのようにツリー構造になっている物は、root, trunk, branch, leaf みたいに樹木で例える事もあるが、親族呼称で表現する事の方が多いと思う。
いや tree 構造なのにツリーの用語じゃなくて親族呼称で言うのはよく考えると違和感あるが、それが伝統であり慣例なのだ。仕方がない。

整理すると以下のような感じになるはずだ。

| singular | plural | adjective | 俺的日本語表現 |
| --- | --- | --- | --- |
| parent | parents | | 親 |
| child | children | | 子 [^1] |
| sibling | siblings | | 兄弟姉妹 |
| ancestor | ancestors | | 祖先 |
| descendant | descendants | descendant (稀に descendent) | 子孫 |
[^1]: 直接の子供を表すために direct children のように表現されるのを見た事がある気がするが、それよりも子孫を表す descendant でなければ直接の子供であると定義した方がすっきりするはず。

自分は正直、sibling というのは DOM 用語で初めて知った。男女の区別をしない兄弟姉妹という単語が英語にはあったのだ。
現代英語は文法性を持たないので、brother か sister かの二択で一意に決めらるルールがないのだと思う。そういう意味では日本語も伝統的な単語としては兄弟と姉妹しかなく、構成要素に女性が含まれている場合でも兄弟に丸められてきたし、現在でも発音上は「きょうだい」が普通だろう。キョウマイとかシテイでは通じまい。後者なんか文脈的にも子弟に間違われるはずだ。

# 親族呼称を使わないケース
ツリー構造のようになる場合でも親族呼称を使わないケースもあるが、どういう時に使わないか一般化は難しいかもしれない。
何かわかったら追加修正するが一旦ケーススタディでお願いしたい。

## オブジェクト指向のクラス継承階層の場合
日本語の、特に口語だと親クラス/子クラスと表現する事が多いと思うが、日本語でも文語の場合や英語の場合は別の用語になる。

| english | 訳語 | 俺的日本語 | 注釈
| --- | --- | --- | ---
| base class | 基底クラス | 親クラス | 普通 base/derived でペア
| super class | スーパークラス | 親クラス | 普通 super/sub でペア
| derived class | 基底クラス | 子クラス | 普通 base/derived でペア
| sub class | サブクラス | 子クラス | 普通 super/sub でペア

同じのが複数セットあると使い分けに困ると思うが、だいたいはプログラミング言語毎にどっちの用語を使う事になっているか決まってるものだと思う。

あと base class の訳語として長く基底クラスが使われてきたが、最近は underlying type という別の概念が出てきていて、これを日本語に訳すと基底型となってしまい、かなりややこしいが全然別の用語なので気をつけないといけない。
もしこの未来がわかってたら base class の訳語は基礎クラスとかにしておくべきだったと思う。

これに関して自分は今まで parent class とか child class という英語表現は見聞きした覚えがないし、継承階層の話は基本的に static な文脈であり、dynamic な文脈とは用語が違うのだと考えると辻褄が合うような気がする(後付けで辻褄を合わせた感はある)。


# 終わりに
まだ他にも表現方法があるような気がするので思いついたら追記するかもしれません。
AtCoder Beginner Contest 106 B - 105を自分的にまとめる（Python）

今回はB - 105をまとめようと思います。

リンクはこちらから

https://atcoder.jp/contests/abc106/tasks/abc106_b

# ①考え方
この問題は、1 ~ Nまで1つずつ約数の個数を調べていき、その中で<font color="Green">**約数の個数が8個**</font>となりそして<font color="Blue">**その数が奇数となる数**</font>の個数を求めるプログラムを書くことでACになります。
<font color="Red">**全探索**</font>を使いましょう。
### 1. 約数の個数を調べる
まず約数の個数を調べるコードを書いていきましょう。
まず配列aを用意します。
その次に、1 <= i <= nまで探索します。
その際に、n%i = 0のiをaに追加していきます。
そして、setをとり重複がないようにしてあげます。
setをとった後のaのサイズが約数の個数と一致します。
以上で約数の個数を求めるプログラムができました。

実装例は以下の通りです
```python:実装例1
def divisor(n):
    a = []
    for i in range(1,n+1):
        if n % i == 0:
            a.append(i)
    a = set(a)
    return len(a)
```
関数定義しなくてもできますが、個人的にこの形が好きなのでこのようにしました。
※約数なのでそれにちなんだ名前にしました。
### 2. 1 <= i <= nまで探索
1 ~ N までそれぞれの数に対して約数の個数を求めていきたいので
1 <= i <= nまで探索してあげます。その際に、
<font color="Green">**約数の個数が8個**</font>かつ<font color="Blue">**その数が奇数となる数**</font>ケースを数えていきます。

実装例は以下の通りです
```python:実装例2
ans = 0
for i in range(1,n+1):
    if divisor(i) == 8 and i % 2 == 1:
        ans += 1
```

# 提出したコード
```python:solution
def divisor(n):
    a = []
    for i in range(1,n+1):
        if n % i == 0:
            a.append(i)
    a = set(a)
    return len(a)

n = int(input())
ans = 0
for i in range(1,n+1):
    if divisor(i) == 8 and i % 2 == 1:
        ans += 1
print(ans)
```

# まとめ
この問題では全探索を使う問題でした。付け加えていうならば、約数とはどんな数なのかをおさえておくことも必要ですかね。最後に、参考文献に問題のリンクと自分がよく閲覧している記事を紹介しておきます。

# 参考文献

https://atcoder.jp/contests/abc106/tasks/abc106_b

https://qiita.com/e869120/items/eb50fdaece12be418faa#%E5%85%A8%E6%8E%A2%E7%B4%A2%E5%85%A8%E5%88%97%E6%8C%99
AtCoder Beginner Contest 141 D - Powerful Discount Ticketsを自分的まとめ（C++・Python）

昨日[@burioden](https://twitter.com/burioden?s=20&t=BW4SFKAnjN0CuuvdNUFWkw)さんが開催しているバチャコンに参加してました。結果からいうと3完だったのですが、Dの問題が解けなくて終わった後に解説ACしました。その復習としてここでまとめようと思います。

リンクはこちらから

https://atcoder.jp/contests/abc141/tasks/abc141_d

# ①考え方
支払う値段をどのくらい小さくできるかっていうのがこの問題の趣旨です。
ではどのようにしてそのようなプログラムを書くのでしょうか？
この問題について考えていくと
以下のようなことがわかると思います。
<font color="Red">**一番高い品物の値段を2で割っていけば良い**</font>
ということです。
入力例1で確認してみましょう
```:入力例1
N = 3
M = 3
A = [2, 13, 8]
```
```
1. 大きい順にします
13 8 2

2. 13を2で割ります
6 8 2
13を2で割ったのでMを1減らします
M = 2

3. 大きい順にします
8 6 2

4. 8を2で割ります
4 6 2
8を2で割ったのでMを1減らします
M = 1

5. 大きい順にします
6 4 2

6. 6を2で割ります
3 4 2
6を2で割ったのでMを1減らします
M = 0

Mが0になったので操作を終了します。
```

という感じの操作をするためのコードを書きたいわけです。
その時に何をすればいいかと言いますと...
<font color="Red">**priority_queue**</font>
を使えばいいのです。
これを使うことで何ができるかと言うと
毎回ソートすることなく最大値にアクセス可能なことです。
（毎回ソートしてると実行時間に間に合わなくなります。）
ではこれを用いて書いていきましょう！

**実装例1**
```cpp:実装例1
#include <bits/stdc++.h>
using namespace std;
 
int main() {

    int N, M;
    priority_queue<int> A;
    for(int i=0; i<N; i++) {
        int x;
        cin >> x;
        A.push(x);
    }
    while(M > 0) {
        int x = A.top();
        x /= 2;
        A.pop();
        A.push(x);
        M--;
    }
 
}
```
priority_queueの使い方に関しては以下のサイトを見ると良いと思います。

https://atcoder.jp/contests/apg4b/tasks/APG4b_aa

そして最後にAが空になるまで足していくという操作をおこないます。
その方法は（ans = 0としておきます）
Aの最大値にアクセスしそれをansに足していき取り出します。

**実装例2**
```cpp:実装例2
#include <bits/stdc++.h>
using namespace std;
 
int main() {

    priority_queue<int> A;
    long long ans = 0;
    while(!A.empty()) {
        ans += A.top();
        A.pop();
    }
    cout << ans << endl;
 
}
```
おそらく大丈夫かもしれませんが、あえてlong long型にしておきました。

# ②提出したコード
```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {

    int N, M;
    cin >> N >> M;
    priority_queue<int> A;
    for(int i=0; i<N; i++) {
        int x;
        cin >> x;
        A.push(x);
    }
    while(M > 0) {
        int x = A.top();
        x /= 2;
        A.pop();
        A.push(x);
        M--;
    }
    long long ans = 0;
    while(!A.empty()) {
        ans += A.top();
        A.pop();
    }
    cout << ans << endl;
    return 0;

}
```
```python
import io
import sys
import statistics
import math
import queue
import heapq

N, M = map(int, input().split())
A = list(map(int, input().split()))
A = list(map(lambda x: x*(-1), A))
heapq.heapify(A)
while M > 0:
    x = heapq.heappop(A) * (-1)
    x = x // 2
    heapq.heappush(A, x * (-1))
    M -= 1
print(sum(A)*(-1))
```

# ③まとめ
この問題ではpriority_queueを使う練習の問題かと個人的に思ってます。①考え方の方にもありますが、これを使うのは毎回ソートすることなく最大値にアクセスして2で割ってあげたいからです。ということで、次は解けるようにしたいですね。参考文献にpriority_queue関連の記事載せておきます。
ここまでお読みいただきありがとうございました！

# ④参考文献
https://qiita.com/ell/items/fe52a9eb9499b7060ed6

https://atcoder.jp/contests/apg4b/tasks/APG4b_aa
Chatworkへのメッセージ送信（Laravel）

## 始めに
Chatworkへのメッセージ送信をLaravelを使って実装しました。
備忘録として記事にします。

流れ
webアプリケーションからChatworkのチャット画面に、設定したメッセージを送信する

## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __Laravel__ | 8.83.19 |
| __PHP__     | 7.3.10  |

## 準備すること
APIトークン、ルームIDを取得する。

__APIトークンの取得__
公式ドキュメント
https://help.chatwork.com/hc/ja/articles/115000172402-API%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E7%99%BA%E8%A1%8C%E3%81%99%E3%82%8B

（Chatwork画面）
上から順に進めていく
![qiita_chatwork_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984846/bba7f4bd-4d47-4725-4bec-98bb80ec73ab.png)
![qiita_chatwork_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984846/9ab07fc2-0aaf-fb8c-d094-1f1ab1786f54.png)
APIトークンが記載されているので、コピーする。
![qiita_chatwork_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984846/1caaa5d7-8947-7074-0978-905d80a2b5af.png)
__ルームIDの取得__
公式ドキュメント
https://help.chatwork.com/hc/ja/articles/360000142942-%E3%83%AB%E3%83%BC%E3%83%A0ID%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B

## 実装方法
```PHP:ChatworkController.php
use GuzzleHttp\Client;

// インスタンス生成
$client = new Client();

// 取得したAPIトークン
$token   = "×××××××××××××××";
// 取得したルームID
$room_id = "×××××××";
// webhookURL
$url     = "https://api.chatwork.com/v2/rooms/{$room_id}/messages";
// 通知内容を設定する
$body    = "通知内容";

$client->post($url, [
    'headers'     => ['X-ChatWorkToken' => $token],
    'form_params' => ['body' => $body]
]);
```

※bodyには、指定されたいくつかのマークダウンのみ使用可能。
　ボタンみたいなものはつけることができないっぽい。。。

__参考URL__
https://go.chatwork.com/ja/column/usage/usage-010.html
https://ishikawa-blog.com/chatwork-short-code-message/

## 最後に
最後まで読んでいただきありがとうございました。
ご指摘、ご意見ありましたらどしどしコメントお願いいたします。

__参考URL__
Laravel8 chatworkに通知する方法
https://halfpower.work/2022/08/30/laravel8-chatwork%E3%81%AB%E9%80%9A%E7%9F%A5%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/
Redwood.jsでテストの立ち上がりを高速化する

```
追記あり
結論だけ知りたい方は一番最後までスクロールしてください
```
## モチベーション
以前こちらの記事に書いた通り、Redwood.jsでは、テストの実行前に毎回Prisma Clientの生成とDBのリセットを行う処理が入ります。

https://qiita.com/mjm2kt/items/0bee58cbfe551e3b1a1b#%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%8C%E3%82%8A%E3%81%8C%E9%81%85%E3%81%84

これにより、私の環境ではテスト開始が毎回7秒程度遅延していました。
テスト駆動開発（TDD）などを行う場合はかなりスピードを遅らせる要因になるため、こちらを解消する方法をご紹介します。

## TR;DR

```shell
SKIP_DB_PUSH=1 yarn rw test # 実行時にSKIP_DB_PUSH=1を設定します

```

## 説明
Redwood.jsのJestの設定はかなり、複雑に入り組んでいるのですが、Prisma Clientの生成とDBのリセットを行う処理についてはこちらに記述されています。

https://github.com/redwoodjs/redwood/blob/99fce77e01198cddd1fcea83453f25562952e280/packages/testing/config/jest/api/globalSetup.js

内容は以下のようになっています。

```globalSetup.js 
...
module.exports = async function () {
  if (process.env.SKIP_DB_PUSH !== '1') {
    const process = require('process')
    // Load dotenvs
    require('dotenv-defaults/config')

    const cacheDirDb = `file:${path.join(__dirname, '.redwood', 'test.db')}`
    process.env.DATABASE_URL = process.env.TEST_DATABASE_URL || cacheDirDb

    const command =
      process.env.TEST_DATABASE_STRATEGY === 'reset'
        ? ['prisma', 'migrate', 'reset', '--force', '--skip-seed']
        : ['prisma', 'db', 'push', '--force-reset', '--accept-data-loss']

    const execa = require('execa')
    execa.sync(`yarn rw`, command, {
      cwd: rwjsPaths.api.base,
      stdio: 'inherit',
      shell: true,
      env: {
        DATABASE_URL: process.env.DATABASE_URL,
      },
    })
  }
}
```

冒頭で
`if (process.env.SKIP_DB_PUSH !== '1') {`
となっているのでこのSKIP_DB_PUSHの値が1になっていればこの関数は全てスキップされるようになっています。

実際にこちらのレポジトリで試してみましたが、
https://github.com/macoto1995/redwood-tdd

一度通常の`yarn rw test`を実行した後`SKIP_DB_PUSH=1 yarn rw test`を実行すると
Prisma Clientの生成とDBのリセットを行う処理を行わず、最初からJestが実行されました。


## 追記
db-pushオプションなるものがあるらしくこちらをfalseに設定するだけで同じことができるようです。
```
yarn rw test db-push false
```

本家のドキュメントにも記載されていました。
https://redwoodjs.com/docs/cli-commands#test

Redwood.jsの実装
https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/commands/testHandler.js#L134
アクティブディフェンス とは

## 勉強前イメージ

積極的な防御・・？

## 調査

### アクティブディフェンス とは

英語でActive Defenseと書き、日本語では積極的防御とも呼ばれます。
積極的なサイバー攻撃に対する防御であり、対策戦略になります。
アクティブディフェンスの目的は攻撃者から攻撃を受ける前に能力を低下させたり失わせたり、
また攻撃が発生しても早期に対応できるようにするためです。

具体的には端末のエンドポイントを動的に変化させたり逆に攻撃者を欺いたり
攻撃者の想定外の状況を作ることで防御側が優位になることができます。

日本では2022年に導入が検討されているもので、明確な定義は現状ではありません。
また、これだけでセキュリティ対策はバッチリ！というわけではもちろんなく
現状のセキュリティ対策に追加して活用することが重要です。

## 勉強後イメージ

## 参考

- [アクティブディフェンスとは？メリットデメリットや今後の展望について徹底解説](https://cybersecurity-jp.com/security-measures/30860)
- [アクティブ・ディフェンスとは【用語集詳細】](https://www.sompocybersecurity.com/column/glossary/active-defense)
リーダブルコードの要約_13章

**13章 短いコードを書く**

コードを簡潔に維持するには、不要なコードは書かないことが大切だ。
そのためには、以下を意識すると良い。

* 最も簡単に問題を解決できるような要求を考える。
* 不必要な機能をプロダクトから削除する。（過剰な機能は持たせない）
* 標準ライブラリに慣れ親しんでおく。

**質問と要求の分割**
あなたは「店舗検索システム」を作っているとする。
要求は以下の通りである。

* 任意のユーザの緯度経度に対して、最も近い店舗を検索する

これを100％正しく実装するには、以下のことも考慮する必要がある。
* 日付変更線をまたいでいるときの処理
* 北極や南極に近いときの処理        など

これらを真面目に実装しようとすると、相当な量のコードを書かなくてはならない。
しかし、このアプリケーションで扱う対象が「テキサス州にある30軒の店舗だけ」だったらどうだろうか？
この小さな範囲で日付変更線や北極のことを考える必要はない。
従って、要求から削除すれば良い。
このように、最も簡単に問題を解決できる要求を考え、無駄な機能を作らないことが大切だ。


**身近なライブラリに親しむ**
余計なコードを書かないためには、新しいコードを書く前に、「標準ライブラリを使って解決できないか？」を考えることが効果的だ。

標準ライブラリとは、
* C++標準テンプレートライブラリ(STL)
* JavaのAPI
* Pythonの組み込みモジュール

などのことである。

ライブラリに備わっている機能を定期的に確認し、「そのライブラリで何ができるのか」をある程度把握しておくことをおすすめする。
そうすれば、新しいコードを書いているときに、その処理がライブラリを使えば簡単に実装できることに気がつけるようになるからだ。
ライブラリを活用することで、書くコードが少なくなり、時間の節約にもなる。
休眠ID とは

## 勉強前イメージ

なんかのサービスのIDとかで退職した人とかでもあるとか？

## 調査

### 休眠ID とは

サービスなどで長期間使われていなかったり、ビジネスサービスだったら退職した人のIDなど
使用されていないIDを指します。
退職した人のIDだったらゴーストIDとも呼ばれます。

基本的には不要なIDは速やかに削除しないといけません。
理由としてはシステム上には残っているため、不正アクセス等で流出されたり情報の改ざんや情報漏洩などの
リスクが発生します。

大手サービスなどでも数年単位でログイン実績がない場合は停止したり
削除したりする対応がされています。

## 勉強後イメージ

確かに管理されていないIDとかだったら簡単にログインできたりするのか・・・
で、会社のとかだったら権限与えられてたりする可能性も。。。

## 参考

- [休眠IDとは？危険性や必要なセキュリティ対策について徹底解説](https://cybersecurity-jp.com/security-measures/35027)
Pythonを改めてちゃんと学ぶメモ #3

# はじめに

ここは、Pythonを改めて学んでいるメモを都度書き出していきます。
※ 筆者のバックグラウンドは#1をご覧ください。

1. https://qiita.com/hideh_hash_845/items/58241f0ce0283e457a87
2. https://qiita.com/hideh_hash_845/items/56c7a2c5594261f380b2
3. ここ
4. https://qiita.com/hideh_hash_845/items/6ebfcbf1682dcc696b76

# 文法の気づき#3
## 関数 def hoge():
- 最後のコロンを忘れがちなので忘れない
- 位置引数はいわゆる引数の指定
- 呼び出す時、返り値がいらなければ `hoge()` だけで良い（ほかの言語と同じ）

### キーワード引数
- いわゆるデフォルト引数
- 引数順を逆にできると聞いて、逆にこれいつ使うんだろと思った
~~~
def sum_2(num_1=0, num_2=1):
    sum = num_1 + num_2
    return sum
# キーワード引数により、順序を逆にして呼び出す
sum_2(num_2=8, num_1=24)
# 32
# 引数を指定しないと、def側で指定したデフォルト引数になる
sum_2(num_2=9)
# 9
~~~

### 可変長引数
- *をつけて宣言するとタプルを引数にできる（Perlだとこれがデフォルトだからイメージしやすい）

~~~
# 可変長引数で渡された引数をすべて掛け算する関数
# numbersは関数中でタプルとして機能する
def multiple(*numbers):
    mul = 1
    for num in numbers:
        mul *= num
    return mul
# すべての位置引数を掛け算する
multiple(1, 2, 3, 4, 5)
~~~
マウススクロールを逆にするだけのスクリプト

# はじめに
Windows と Mac をどちらも使っているとマウスのスクロール方向で混乱することがあります。
私は Mac を使っている時間のほうが長いので Windows の方のスクロールを逆にすることで対処しています。
このスクロールを逆にするというのが少し面倒で、レジストリを書き換える必要があります。
これを簡略化するためのスクリプトです。


# ソースコード
````MouseReverse.py
import winreg

root: str = "SYSTEM\\CurrentControlSet\\Enum\\HID"

def open_rec(key_str: str, depth: int):
    with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_str, 0, winreg.KEY_READ | winreg.KEY_WRITE) as key:
        [sub_key_num, val_num, modified] = winreg.QueryInfoKey(key)
        # 値を列挙する
        updated: bool = False
        for i in range(0, val_num):
            [name, val, type] = winreg.EnumValue(key, i)
            # マウスのスクロール方向を表すキーだけ拾う
            if name == 'FlipFlopWheel' or name == 'FlipFlopHScroll':
                print(f'{key_str}\\{name}({val})')
                try:
                    winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, 1)
                except:
                    import traceback
                    traceback.print_exc()
                updated = True
        if updated:
            winreg.FlushKey(key_str)
        # サブキーを開く
        for i in range(0, sub_key_num):
            sub_key = winreg.EnumKey(key, i)
            try:
                open_rec(f'{key_str}\\{sub_key}', depth + 1)
            except:
                pass

open_rec(root, 0)
````

# 注意点
管理者権限のコマンドプロンプトでないと実行できません。
スクラムガイドを読む

スクラム開発を実践するときに、書籍や研修などの情報源が役に立ちます。
その中で、スクラムガイドを参考にした時の情報をまとめます。

# スクラムガイドとは何か？
スクラムガイドは、Ken SchwaberとJeff Sutherlandによって書かれた公式のスクラム知識体系（Scrum Body of Knowledge）です。
https://scrumguides.org/faq.html

# スクラムガイドはどうやって入手できるか？

スクラムガイドは以下のURLで読むことができます。
https://scrumguides.org/download.html
日本語訳もPDFで入手できます。
https://scrumguides.org/download.html

# スクラムガイドは誰によって書かれているか？
[Ken Schwaber](https://scrumguides.org/ken.html) と [Jeff Sutherland](https://scrumguides.org/jeff.html) の二人がこのスクラムガイドの著者です。

スクラムというフレームワークが始めて発表されたのは、OOPSLA 1995(Object-Oriented Programming Systems, Languages, and Applications)という国際会議でした。
このとき Jeff Sutherland が座長である「[Business object design and implementation workshop](https://dl.acm.org/doi/10.1145/260094.260274)」で、Ken Schwaber が「SCRUM Development Process」という論文を発表しました。


スクラムガイドは2010年に最初のバージョンが発表されました。その後改定が続けられています。

# スクラムガイドにはどのようなことが書かれているか？
日本語版
https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf

スクラムガイドはいくつかの章に分かれています。いかに簡単な内容の要約をまとめています。
正確な内容はスクラムガイド自体を参照することをお勧めします。

- スクラムの定義
    - スクラムがどのようなフレームワークであるかの定義

- スクラムの理論
    - スクラムを基礎づける考え方は、経験主義とリーン思考である。
    - 予測可能性を最適化してリスクを制御するために、イテレーティブ（反復的）でインクリメンタル（漸進的）なアプローチを採用する。

- スクラムの価値基準
    - スクラムを成功させるためには次の５つの価値基準を実践する。
確約（Commitment）、集中（Focus）、公開（Openness）、尊敬（Respect）、勇気（Courage）

- スクラムチーム
    - スクラムチームは、スクラムマスター1 ⼈、プロダクトオーナー1 ⼈、複数⼈の開発者で構成される。
    - スクラムチームは機能横断型で、各スプリントで価値を⽣み出すために必要なすべてのスキルを備えている。・スクラムチームは⾃⼰管理型であり、誰が何を、いつ、どのように⾏うかをスクラムチーム内で決定する。

- スクラムイベント
    - スクラムでは、検査と適応のための４つの正式なイベント（スプリントプランニング、デイリースクラム、スプリントレビュー、スプリントレトロスペクティブ）を組み合わせている。それらを包含するイベントは「スプリント」と呼ばれる。

- スクラムの作成物
    - スクラムにおいて実施する作業や実現するべき価値を表現する物としてスクラムの作成物がある。
    - スクラムの作成物にはプロダクトバックログ、スプリントバックログ、インクリメントがある。
    - それぞれの作成物には確約（コミットメント）が含まれている。つまりプロダクトバッグログのためのプロダクトゴール、スプリントバックログのためのスプリントゴール、インクリメントのための完成の定義である。

# 他のスクラムの書籍と内容にどのような違いがあるか？
スクラムについて書かれた書籍であれば、スクラムガイドの内容は包含されていることが多いと思います。
逆に言うと、スクラムガイドでは、スクラムというフレームワークのエッセンスを読むことができます。

スクラムガイドの記述は決して多くないので、スクラムの開発を実践する場合は、他の情報源も併用することになりそうです。
すでにスクラムを実践している場合は、自分が置かれている状況を整理するために、スクラムガイドが役に立ちます。
WindowsでPCやサーバーに誰かが先にリモートデスクトップしてるかコマンドで確認

# やり方

```bat
qwinsta /server:マシン名もしくはIPアドレス
```

下記のようにrdpがActiveになっていれば **リモートデスクトップしてる** 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8d881796-ed3f-74db-b7fc-3f896131cfe0.png)

下記なら **リモートデスクトップしてない** 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d00c4c45-25eb-959a-026f-ac0b4c31d246.png)

# 蛇足

下記の場合はリモートデスクトップではなく、直接操作している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/57070ca2-bb9a-fed2-3076-b143c08bcffe.png)

rdpのセッションだけ見るのではなく『状態がActiveになっているのが一つも無いか』で確認した方がいいかもね。


# 参考サイトさん

https://nw-engineer.work/qwinsta/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2364

TODO:qwinstaに応答しない奴がたまにいるので、どういう設定なら応答拒否か調べる。
30時間かけてJavaScriptが練習できるアプリを作りました。

# 30時間かけてJavaScriptが練習できるアプリを作りました。

ご存じの通り、JavaScriptが他のプログラミング言語と違うところは、もともと**ブラウザのため**に作られたということです。今では、Node.js等でバックエンドでも使用できるようになりましたがその基本は変わっていません。

私がJavaScriptを習い始めたころはコードを書きながら実際にいちいちconsole.log()を加えながらどういう動きをするのか確かめる作業を繰り返していました。

そこでこの**JSひろば**アプリを作成してみることにしました。
このアプリを通して皆さんにJavaScriptがどう使えるかを、実際の例を使って、自分のコードを書きながら試していただけると嬉しいです。
　　


## [JSひろばを試す](https://js-hiroba.com)
https://js-hiroba.com

![アプリの参考イメージ](https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-1.gif?resize=521%2C651&ssl=1)



もともとの使用するテクノロジーはこのような感じです。

![アプリのスタックイメージ](https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/image-25.png?resize=1024%2C602&ssl=1)


では30時間をどのように過ごしたかそれぞれの記事から詳しい内容をみてください。


* * *



[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JShiroba-day1.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroba-day1/)

### [JSひろばアプリ開発1日目：プロジェクトのセットアップ](https://asameshicode.com/js-hiroba-day1/)
- アイディアを絞る
- UIをFigmaでデザインする
- 使用するテクノロジーを決める
- 課題点をクリアする

[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day2.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroba-day2/)
### [JSひろばアプリ開発2日目：スタイルの設定](https://asameshicode.com/js-hiroba-day2/)
- Figmaのデザインを形にしていく
- ファイル構成を考える
- Vueコンポーネントの作成
- Piniaのインストール


[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day3.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroda-day3/)

### [JSひろばアプリ開発3日目：Vueアプリの全体像](https://asameshicode.com/js-hiroda-day3/)
- ボタンのコンポーネントの作成
- モックのデータを作成
- グローバルで使うデータをPiniaに保管させる
- Emitを使いデータを親コンポーネントに送る
- ライブラリコンポーネントのRefにアクセスする


[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day4.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroba-day4/)

### [JSひろばアプリ開発4日目：Djangoプロジェクトの作成](https://asameshicode.com/js-hiroba-day4/)
- Djangoのプロジェクト作成
- virtualenvの設定
- requirements.txtに書き出し
- DRFのインストール
- DBのテーブルの構成
- モデル、URL、ビューの設定
- PostgreSQLに接続


[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day5.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroba-day5/)

### [JSひろばアプリ開発5日目：Djangoのデプロイ](https://asameshicode.com/js-hiroba-day5/)
- ドメインの取得
- Ubuntuサーバーの設定
- サーバーのユーザー設定
- PostgreSQLのインストール
- リポジトリのクローン
- Djangoのデプロイ
- Nginxの設定
- SSLの取得


[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day6.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroba-day6/)

### [JSひろば開発６日目：Vueアプリのデプロイとデザイン](https://asameshicode.com/js-hiroba-day6/)
- Djangoに実際のデータを入力
- VueアプリにAxiosをインストール
- APIコールのリスポンスをPiniaに保管
- 実行ボタンの作成
- アニメーションの設定
- Highlight.jsを設定


[<img src="https://i0.wp.com/asameshicode.com/wp-content/uploads/2022/12/JS-Hiroba-day7.jpg?resize=1068%2C601&ssl=1">](https://asameshicode.com/js-hiroda-day7/)

### [JSひろば開発7日目：Vueアプリのデプロイとデザイン](https://asameshicode.com/js-hiroda-day7/)
- モジュールインポートエラーの対応
- favアイコンの作成
- 英語版に対応させる
- DBモデルの改修
- Google Analyrticsの追加
- ローディング画面の設定
- Vue-routerの追加


では今日もお疲れ様でした。
エンジニア採用側、何を知りたいか

　転職する側として、採用する側の考えや質問の背景を知りたいと思ったことはないでしょうか？　そういった背景を知り「エンジニア転職活動をハックしたい」という方を応援することが本記事の狙いです。ITエンジニアの採用に関わる方から見聞きした事象や、自身の転職活動経験などから本記事をまとめさせていただきました。

　こちらは、「エンジニア転職活動ハックをシェアしよう！ by キャリアデザインセンター「Direct type」 Advent Calendar 2022」カレンダー2、18日目の記事になります。

https://qiita.com/advent-calendar/2022/directtype


# ITエンジニアをなぜ採用するのか？
　採用側が何故募集要項を打ってITエンジニアを採用したいのか、応募の際に募集要項を見ながら一度考えてみることをおすすめします。背景が分かっていると効果的な準備ができることが期待できます。
　募集の背景としては、以下のようなことが考えられます。

1. 欠員の補充
    - この理由であれば募集要項にピッタリハマりすぐ来てくれる人材が求められるため、自分が欠けたポジションに上手くハマるかをアピールすると良さそうです。
2. 将来の組織維持のための備え
    - 数年後にベテランが退職するため、今のうちから次世代を育成したい、等の理由から採用をかけるケースがあります。この場合、採用側はポテンシャル採用も視野に入れると考えられます。ベテランの業務を引き継ぎ、組織に馴染み活躍できる事をアピールできると良いのではないでしょうか。
3. 新規ビジネス・プロジェクト立ち上げのための増員
    - 新しいことを始めるため、とにかく人を集めたいというパターンの募集です。大筋を外さなければ選考には残れそうです。募集要項等をみて、採用側のやりたい新しいことに関して調べておき、自分は何ができるのか答えられるようにしておく、不明点を面接で質問できるようにしておくと入社後の働き方のイメージをつかみやすいです。



# ITエンジニア採用側の知りたいこと
　主に次のような事を見極めたく、面接で色々と聞くことになるようです。

1. 応募者の本気度
2. 応募者が来て頂いて馴染むか、長く働けるかを見極め
3. 応募者のキャリアの方向性
    - 2と3はセットで確認。長く働きたい意思はあっても、応募者のキャリアの方向性に合う仕事が提供できない場合はお互い不幸になるため。
4. 応募者の「選考書類に出て来ない」転職動機
    - 「現在の職場が遠く近くで働きたい」とあった場合、単純に近くで働きたいのかリモートワーク多めで働きたいのか等掘り下げる等。
5. 応募者の学習継続性
    - 新しい知識が常々必要となるため、自発的かつ継続的に学ぶ方かどうかを確認。
    - 取得資格をいつ取ったか、複数取っていたらその間隔などを見る。
    - ポートフォリオがあれば更新状況を事前に見た上で質問する等。
6. 希望年収が想定レンジと合致するかどうか
    - 合致していない場合はすり合わせを打診して感触を見ます。
7. 今後の採用につながる情報
    - どういうソースから自社を知っていただいていて、足りてない情報が何かを面接の中でそれとなく聞く。
    - 最近の応募者の動向



# ITエンジニア採用側、困ること

## 応募業界・業種への妙な固定観念を持ってこられる
　調べて来ていただけるのはありがたいのですが、「この業界はこうだ」という決めつけや固定観念の主張があると、来ていただいてもなじまないかな…という印象を抱くことがあります。


## 入社希望日が内定受諾後のかなり先
　引き継ぎなどあるため１～３ヶ月後の入社が一般的ですが、半年以上先となると採用側から見て厳しい場合があります。採用側に誰かが抜けた穴をすぐ埋めたいなどの事情がある場合は特に厳しいです。他に内定を出せ、１ヶ月程度で来れる応募者がいる場合はそちらに流れてしまうことがあります。


## 募集要項の給与レンジの上の方
　未経験で「募集要項に400万～900万と書いてあったので900万を希望します」と言われると厳しいようです。給与レンジは応募者のキャリアと経験を見て判断することが一般的ですね。募集側は、未経験の応募者は給与レンジの下の方と想定しているわけです。
　給与レンジが広い場合、その職種の幅広い層（新人～ベテラン）を取りに行く想定の募集要項となり、給与レンジが狭ければ、その職種の中でも狙う層は当たりがついていると推察されます。
[Ruby] 整数を判定する、あるいは"整数ではない"について

何番煎じですかってお題ですが、地味に詰まったので言葉にして残してみます。

# はじめに: 筆者について
Ruby歴2ヶ月ほどで、バックエンドの開発が得意です。Javaのエンジニアからキャリアをスタートし、最近1年半くらいはサーバーサイドKotlinの導入やプロダクション用のビルドやアプリ基盤開発などに従事してきました。個人的な趣味としても、規約よりも設定、型によるモデルの実装といった堅牢だが冗長な実装を好む傾向にあります。

そのような背景がありますので、型やnullの状態がコンパイル時にわかるような気で、 "Java屋的な" 発想でRubyを書いてしまいがちです。

# お題: 小数点付きならエラー
簡単な修正の担当となり、「小数点付きならエラー」を実装しようとしていました。

以下の修正が結論です。変数名などはぼかして書いています。
```ruby
do_on_error unless !@subject&.is_a(Integer)
```

## インスタンスの型もnullabilityも明示的ではない
はじめに気づいたことは、検査対象は数値のインスタンスとは限らないということです。Integerクラスのドキュメントを見ておりましたが、そのような前提があるので `Integer#integer?` は使えないということです。当たり前のことですが... Integer#parseInt をtry-catchで囲いたいなあなんて思っておりました。

最初に考えた方針には、次の2つの落とし穴があります（指摘されるまでもなく自分ですぐに気付けたけど恥ずかしい）
1. 「小数点付きなら」 は、要件としては「整数であること」であること
2. そもそもnilかもしれないことを考慮する必要がある

1については、要件が前提条件にあるのでここでは簡単にだけ触れますが、「小数点付きであること」と「整数であること」は等価ではないです。そして、Rubyにおける数値系データ型の型階層は `Numeric` を中心に整数と小数点付きに分かれております。つまり、 `Integer` と `Float` 同士は is_a にも has_a の関係にもなっていない。

```
Numeric
|_ Integer
|_ Float  
```

[class Numeric](https://docs.ruby-lang.org/ja/latest/class/Numeric.html)

冒頭にも書いたように、そもそも検査対象の型が不明の状態では、 `integer?` をインスタンスメソッドとしてコールすることで `NoMethodError` になる可能性が拭えません。そのため、対象の型を判定します。

```ruby
# nilないしはIntegerのインスタンス以外ではNoMethodErrorになるかも
@subject.integer?
```

また、当初検査対象がnilかもしれないことを考慮しきれていませんでした。実践的には、nilないしは空文字でないことをバリデーションした状態で、ビジネスロジックとして整数判定を入れるかもしれないですが、一般的にnil判定も含めたほうが安全です。

nil判定を型判定と独立してやってもいいですが、safe navigation operator（通称ぼっち演算子）あるじゃんと教えていただき、まとめて判定するようにしました（アドバイスありがとうございました）。

- [2.2.0以降の変更](https://docs.ruby-lang.org/ja/latest/doc/news=2f2_3_0.html)
- [Introduce "safe navigation operator"](https://bugs.ruby-lang.org/issues/11537)

```ruby
# 否定を2回もしていてツライ
!@subject.nil? and !@subject.is_a?(Integer)
```

# おまけ: safe navigation operator付きでは逆にならない
否定 `!` 付きで呼び出していたので運良く（？）要件通り判定できましたが、safe navigation operatorはレシーバがnilの場合メソッドコールせず `nil` を返して終わることにも注意を要します(`Boolean`にならない)。

```ruby
# レシーバがnil
>> subject = nil
>> !subject&.is_a?(Integer)
=> true
# コールされないのでbooleanが返ってこない
>> subject&.is_a?(Integer)
=> nil
```

よく考えたら難しいことではないですが、否定 `!` で裏返せばtrueとfalseが簡単に裏返るわけではないことも明示的ではなかったということです。

# まとめ
Rubyistの皆様からすれば至極単純な実装なはずですが、　型やnullablityがコード上で明確な世界から来ると

- 変数の型が明示的でない -> 安直にインスタンスメソッドをコールできない
- 常にnilないしは空文字かもしれないこと

といった前提条件から逃れられないことは改めて学びになりました。kotlinやtypescriptにもnull safe operatorやoptional chainingなど似たような言語仕様がありますが、そもそもnullにならないよう型宣言するようにしていたのですっかり抜けていたのもあります。
Golangのゼロサプレス



## ゼロサプレスとは

例えば`“000012"`という文字列があったときに、頭についている余計な`”0”`を取り除くこと

```
// ゼロサプレスの例
000012 → 12
001234 → 1234
000101 → 101
000110 → 110
```

### 最初にゼロサプレスをするために考えたこと

文字列を一つ一つ見ていって、0ではないものが出てきた時に別スライスにappendすればいいんじゃないか

```go: before.go
package main

import (
	"fmt"
	"strings"
)

func zeroSuppress(str string) string {
	slice := strings.Split(str, "")
	res := make([]string, 0)
	flag := false

	for _, v := range slice {
		if v != "0" {
			flag = true // 0でないものが現れたら、flagをtrueにしてappendするようにした
		}
		if flag == true {
			res = append(res, v)
		}
	}

	return strings.Join(res, "")
}

func main() {
	str1 := "000012"
	str2 := "001020"

	fmt.Println("str1: ", zeroSuppress(str1))
	fmt.Println("str2: ", zeroSuppress(str2))
}

// > 12
// > 1020
```

<strong> 　ちょっと面倒？ </strong>

### goの標準パッケージにあった
調べるとすでに標準で入っているパッケージの中にちゃんとありました、、、

https://pkg.go.dev/strings#TrimLeft

このメソッドの第二引数に`"0"`を指定すれば、ゼロサプレスできそう

### strings.TrimLeft()を使ってゼロサプレスする
上のプログラムを`strings.TrimLeft()`を用いて書くと
```go: after.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	str1 := "000012"
	str2 := "001020"

	fmt.Println(strings.TrimLeft(str1, "0"))
	fmt.Println(strings.TrimLeft(str2, "0"))
}

// > 12
// > 1020
```
と、すぐできた

### まとめ
標準パッケージ便利、ちゃんと調べよう
脅威ハンティング とは

## 勉強前イメージ

脅威インテリジェンスと似てる？

## 調査

### 脅威ハンティング とは

スレットハンティングとも呼ばれます
従来の方法で検知が難しい脅威に対してすでに侵入されていると仮定して不審なログ等を収集します。
マルウェアはユーザに気づかれないように活動を進めており、実際に被害が出るまでに準備をしています。
またウイルス対策ソフトも最新化していても入ってくる可能性があり、それに対して脅威ハンティングで発見するというものです。

### ペネトレーションテストとの違い

似たような言葉で [ペネトレーションテスト](https://qiita.com/miyuki_samitani/items/61c55869676ba5b6b064) があります。
侵入テストや侵入実験と呼ばれ
ネットワークに接続されているシステムに対して既知のサイバー攻撃を疑似的に行うなど侵入を試みることで脆弱性があるかのテストを行う手法のことを指します。

ペネトレーションテストと脅威ハンティングとの違いは以下になります。

- ペネトレーションテスト : 外部から侵入できる試みる
- 脅威ハンティング : ネットワーク内に脅威があると過程してデータを集める

内部から調査するのか、外部から試してみるのかの違いかなと思います。

## 勉強後イメージ

調査する方法の一つって感じかな。
もう侵入されてるとしてあぶり出す！ってやつ？

## 参考

- [脅威ハンティング(スレット・ハンティング)って何をするの？](https://www.cybereason.co.jp/blog/security/1709/)
- [脅威ハンティング（スレットハンティング）とは？潜伏するマルウェアを発見する最新対策について](https://cybersecurity-jp.com/security-measures/27947)
CloudWatch Logsで複数行をひとまとめにする【Laravel】

# CloudWatch Logsが見づらい！
![qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290902/cccf1ea4-a18c-c953-d99f-dbfa5e5cb216.png)

EC2インスタンスで吐き出されるログをCloudWatchLogsに集約しているのですが、そのログがけっこう見づらくて困っておりました。
具体的には上記画像のように一つのエラーログが人まとまりにならず、複数行にわかれてしまうことです。
一つのエラーがひとまとまりになれば、何件エラーがあったとか、ログの境目が一瞬でわかるのに…と悩んでおりましたがしょうがないと思っておりました。
今回はLaravelで吐き出されるログをまとめたいと思います。

# multi_line_start_patternでまとまりを作ることが可能

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html

こちらにCloudWatchエージェントの設定ファイルの書き方があります

>multi_line_start_pattern – ログメッセージの開始を識別するパターンを指定します。ログメッセージは、パターンに一致する 1 行と、後続パターンに一致しない行で構成されます。
このフィールドを指定しない場合、複数行モードが無効になり、空白文字以外の文字で始まる行は、前のログメッセージを終了して新しいログメッセージを開始します。
このフィールドを含める場合、{timestamp_format} を指定してタイムスタンプ形式と同じ正規表現を使用できます。それ以外の場合、CloudWatch Logs が複数行エントリの最初の行を判断するために使用する別の正規表現を指定できます。

とあるようにmulti_line_start_patternの設定でまとまりを作れることがわかりました。値としては正規表現とtimestamp_formatが使えるようなので

# timestamp_formatで対応する

```
[2022-11-29 09:03:16]
```
Laravelはこのような形式のタイムスタンプで記録されているので、この形式に合わせます。

```json
"timestamp_format": "[%Y-%m-%d %H:%M:%S]"
```

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html

フォーマットの指定の仕方は最初に上げたリンクと同じですが、こちらに記載があります。

なので最終的にはこのようなjsonになります

```json:/opt/aws/amazon-cloudwatch-agent/bin/config.json
{
        "agent": {
                "run_as_user": "root"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/path/to/laravel.log",
                                                "log_group_name": "group_name_laravel.log",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": 30,
                                                "timestamp_format": "[%Y-%m-%d %H:%M:%S]",
                                                "multi_line_start_pattern": "{timestamp_format}"
                                        }
                                ]
                        }
                }
        }
}
```
これで取れるようになったのが以下のような形です（ぐちゃぐちゃですみません…）

![スクリーンショット 2022-12-29 11.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290902/516ac527-5806-3018-c6e6-ea552ad07dff.png)



参考までですがEC2へのCloudWatchエージェントの設定は以下の記事を参照ください

https://qiita.com/YujiHamada3/items/766c30a61aa753f0e238
リーダブルコードの要約_12章

**12章 コードに思いを込める**

読み手が理解しやすいコード書くためには、プログラムの内容を簡単な言葉を使って説明してみると良い。

以下の手順に従うことで、理解しやすい自然なコードを書くことができる。

1.コードの動作を簡単な言葉で同僚にもわかるように説明する
2.その説明の中で使っているキーワードやフレーズに注目する
3.その説明に合わせてコードを書く

**ロジックを明確に説明する**
以下は、あるWebページから取ってきたPHPのコードの一部である。
ユーザにページを閲覧する権限があるかどうかを確認して、権限がなければ、権限がないことをユーザに知らせるページに遷移させる。

```php
<?php
  $is_admin = is_admin_request();
  if ($document) {
    if (!$is_admin && ($document['username'] != $_SESSION['username'])) {
      return not_authorized();
    }
  } else {
    if (!$is_admin) {
      return not_authorized();
    }
  }
  // 引き続きページのレンダリング
?>
```
このコードにはロジックが沢山あり、理解しづらい。
（if文がネストされている、条件式に否定形が使われている、など）

より理解しやすいコードに書き換えるために、まずはこのロジックを簡単な言葉で説明してみる。
```
権限を持つ人は、以下の２通り。
1.管理者
2.文書の所有者（文書がある場合)
そのほかは、権限がない。
```

この説明に合わせてコードを書き直す。
```php
<?php
  if (is_admin_request()) {
    // 管理者 (権限あり)
  } elseif ($document && ($document['username'] == $_SESSION['username'])) {
    // 文書の所有者 (権限あり)
  } else {
    //その他（権限なし）
    return not_authorized();
  }
  // 引き続きページのレンダリング
?>
```
前のコードに比べてロジックが単純になっている。具体的には、
・コードが短くなった（if文のネストも解消できた）
・条件式に否定形が使われなくなった

**まとめ**
プログラムをより簡単な言葉で説明する技法について説明した。
簡単な言葉で説明することで、自然で理解しやすいコードを書くことができる。
統計学実践ワークブック　第1章例題解説

# 第1章 事象と確率
:::note info
著作権の都合により問題文は掲載せず解説のみの記述とします。
:::
## 例1
包除原理より、AまたはBの少なくとも一方を見た生徒は
```math
P(A∪B)=P(A)+P(B)-P(A∩B) \\
=20+15-5 \\
=30
```
いずれも見なかった生徒の数は $50-30=20$名です。

## 例題
### 問1.1
（１）$0.44$
　女子の合格率×女子の比率＋男子の合格率×男子の比率
$=0.5×0.4+0.4×0.6$
$　=0.44$

（２）$5/11$
　ランダムに選んだ1人が女子である事象をW、入試に合格する事象をSとする
　$P(S)=0.44$
　ベイズの定理より
　$P(W|S)=\frac{P(S|W)P(W)}{P(S)}=\frac{0.5×0.4}{0.44}=5/11$

### 問1.2
（１）期待値：2/5　分散：7/12
　$P(X=1)=P(X=2)$であり、1,2,3はそれぞれ少なくとも1つ以上書かれているので
　$P(X=1)=P(X=2)=1/6または1/3$となる。
　期待値は2より大きいとのことなので、$P(X=1)=P(X=2)=1/3$とした場合期待値が2となり当てはまらない。
　よって$P(X=1)=P(X=2)=1/6$かつ$P(X=3)=4/6$
　これにより期待値は$E[X]=1×1/6+2×1/6+3×4/6=15/6=5/2$
　分散は$V[X]=E[X^2]-(E[X])^2=1/6+4/6+36/6-25/4=7/12$

（２）8/9
　確率$P(Y=3)$を求めるには、余事象としてサイコロを2回投げて両方とも2以下になる確率を求めればよい。
　$P(X≦2)=1/3$
　$P(Y=3)=1-(P(X≦2))^2=1-1/9=8/9$

### 問1.3
（１）1/3
　条件付き確率「陽性と診断された時に病気である確率」を求める。
　$X_1$:検査1のとき病気にかかっている
　$Y_1$:検査1で陽性
　という事象として定義すると、問題文より以下の通り確率が求められる。
　$P(X)=0.01、P(X^c)=0.99、P(Y_1|X)=0.99、P(Y_1|X^c)=0.02$
　求める確率は、ベイズの定義より
　$P(X|Y_1)$
　$=\frac{P(Y_1|X)P(X)}{P(Y_1)}$
　$=\frac{P(Y_1|X)P(X)}{P(Y_1|X)P(X)+P(Y_1|X^c)P(X^c)}$
　$=\frac{0.99×0.01}{0.99×0.01+0.02×0.99}$
　$=1/3$

（２）9/11

:::note warn
書籍解説の分かりにくいポイント
前段で説明の無かった同時確率の記述が出てきます。
私は$P(X|Y_1,Y_2)$の「$,$」って何？？？って混乱しました。
$P(X|(Y_1∩Y_2))$と書けばまだ分かりやすいのですが、導出が複雑になるので書籍解説は異なるやり方を紹介することとします。
:::

　$X_2$:検査2のとき病気にかかっている
　$Y_2$:検査2で陽性
　として定義する。
　”検査2は検査1で陽性と診断された者に対して行う”とのことなので、
　$P(X_2)=P(X_1|Y_1)$と置くことができる。
　問題文より以下の通り確率が求められる。
　$P(Y_2|X_2)=0.9、P(Y_2|X_2^c)=0.1、P(X_2)=P(X_1|Y_1)=1/3、P(X_2^c)=1-P(X_2)=2/3$
　求める確率は、ベイズの定理より
　$P(X_2|Y_2)$
　$=\frac{P(Y_2|X_2)P(X_2)}{P(Y_2)}$
　$=\frac{P(Y_2|X_2)P(X_2)}{P(Y_2|X_2)P(X_2)+P(Y_2|X_2^c)P(X_2^c)}$
　$=\frac{0.9×1/3}{0.9×1/3+0.1×2/3}$
　$=9/11$
FDBatchでCSVファイル入出力

これは、他サイトのブログに書いていた Delphi Advent Calendar 2019 の 15 日目の記事を、Qiiter向けに書き直したものです。

# はじめに
FDBatchMoveをつかったCSVファイルの入出力が思いのほかパフォーマンスが良かった(自作ライブラリ比)ので、纏めてみました。

# FDBatchによるCSVファイル入出力
## 仕様
日本郵便のサイトから住所の郵便番号（CSV形式）のデータを、TFDMemTableに、項目を絞って取り込む処理(１)と、取り込んだTFDMemTableのデータを、CSVファイルに出力する処理（２）について纏めました。

## CSV取り込み処理
使うコンポーネントは、下記になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/c1bc6000-4743-0c2b-869f-0d878ec3db3d.png)

FDBatchMoveTextReader1が、読み込みCSVの設定、FDBatchMoveDataSetWriter1が、出力先（この場合、FDMemTable1）の設定となる。
FDBatchMove1が、この２つを繋ぐことになる。
住所の郵便番号（CSV形式）は、１５項目あるがこのうち７項目（郵便番号と、都道府県名、市区町村名、町域名のカタカナと漢字）を抽出することにする。
まず、事前にFDMemTable1に下記のフィールドを定義する。すべて、string型で、とりあえず余裕を持った長さで設定した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/5bdfcbef-52ed-e4af-66f7-560694b6806f.png)

次に、FDBatchMoveTextReader1の定義を行う。
FileNameプロパティに、住所の郵便番号（CSV形式）で落としたファイル(KEN_ALL.CSVを使いました)を指定します。
プロパティのDataDef内のFiledsを選択し、CSVのフィールドを定義する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/a9735d43-4ae0-f69c-63f2-4b93e751a464.png)

住所の郵便番号（CSV形式）は、１５項目あるので、Filedsを１５設定する。
取り込むFiledsのみ、きちんと定義した。取り込むデータのみ、DataTypeは、atStringとし、それ以外は、DataTypeは、atOtherにしておく。また、FieldSize、Percisionは、すべて０にしておく。
（FDBatchMoveを選択し、マウス右ボタンでのポップアップメニュー中の”テキスト形式を推測”で、フィールド定義を生成出来るが、意図しない型やサイズが設定されることがあるので、CSVファイルの場合はあまりお勧めしない）
また、DataDefプロパティのRecordFormatプロパティが、rfCommaDoubleQuote(Default値)になっていることを確認する。

FDBatchMoveDataSetWriter1の設定は、DataSetプロパティに、FDMemTable1を設定する。

FDBatchMove1の設定は、Readerプロパティに、FDBatchMoveTextReader1を、Writerプロパティに、FDBatchMoveDataSetWriter1を設定する。この後、Mappingsを開き、下記のように、Readerのフィールドと、Writerのフィールドを紐づける。
（Readerのフィールドと、Writerのフィールドが同名で紐づけられれば、FDBatchMoveを選択し、マウス右ボタンでのポップアップメニュー中の”すべてのマッピングを追加”で、自動で生成も可能）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/b24ce080-f38e-4e6e-14be-88e2e2c4bb84.png)

## CSV出力処理
使うコンポーネントは、下記になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/582372c5-2186-6b96-94d2-b1e184eaa045.png)

FDMemTable1に、"CSV取り込み処理"で作成したデータを事前に取り込んでいます。
FDBatchMoveDataSetReader1のDataSetに、FDMemTable1を設定。
FDBatchMoveTextWriter1のFileNameに出力先のファイル名を設定。
FDBatchMove1の、ReaderにFDBatchMoveDataSetReader1を、WriterにFDBatchMoveTextWriter1を設定します。
今回は、FDMemTable1の全フィールドを落とすことにするので、Mappingsの定義はなしで行います。
こちらも、ＩＤＥ上で実行可能です。
ソースで行うのであれば、
      FDBatchMove1.Execute;
となります。

# おわりに
今回は、DataSetは、TFDMemTableを使っていますが、TFDTableにすることも可能です。
パフォーマンスも魅力ですが、ＩＤＥ上で実行できるので、データベースのデータをちょっとＣＳＶファイルに落としたい時などに便利だと思います。

＜Delphi 10.3 Update 3で作成しています＞
【VSCode】tsconfig.jsonを環境ごとに準備して、テストのファイルで`Cannot find module...`エラーを出さない方法

# VSCodeで発生していたお悩み

普段開発を行なっているプロジェクトでは、デフォルトの**tsconfig.json**にて、`__tests__`ディレクトリのファイルをコンパイルの対象外に設定しています。

```json
{
    ...
    "include": [
        "src",
    ],
    "exclude": [
        "src/**/*.test.ts",
        "__tests__",
        "__mocks__"
    ]
}
```

そのため、`__tests__`ディレクトリのテストファイルをVSCodeで開くと、次のような赤線がエディター条に表示されてしまいます。

![名称未設定のデザイン (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/1eea52dd-ea8b-668f-c4ee-4bf3f7cd0905.png)

# VSCode用のtsconfig.jsonに修正する

そこで、VSCodeには、テストファイルを開いた時にも`Cannot find module...`エラーを表示させないようにするために`exclude`から`__tests__`を削除するようにします。そして、`include`に、`__tests__`を追加します。

```json
{
    "include": [
        "src",
        "__tests__"
    ],
    "exclude": []
}
```

この結果、テストファイルを開いた状態のVSCodeのエディター画面からエラーの表示が消えました。

![名称未設定のデザイン (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/80a71361-bb0c-ff30-c751-5ea35cda8125.png)

しかし、まだ問題は残っています。

# ビルド用のtsconfig.jsonを作成する

今まで、ビルドもテストもデフォルトの**tsconfig.json**を使って行なってきたため、**package.json**のビルド用のスクリプトは次のようになっています。

```json
{
    "name": "functions",
    "scripts": {
        ...
        "build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
        ...
    }
    ...
}
```

そこで、デフォルトの**tsconfig.json**を拡張して、ビルド用に設定を上書きした**tsconfig.build.json**を作成します。

```json
{
    "extends": "./tsconfig.json",
    "include": [
        "src",
    ],
    "exclude": [
        "src/**/*.test.ts",
        "__tests__",
        "__mocks__"
    ]
}
```

そして、先ほどの`build`スクリプトの内容を修正して、**tsconfig.build.json**を使うように書き換えます。

```json
{
    "name": "functions",
    "scripts": {
        ...
        "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
        ...
    }
    ...
}
```


# テスト用のtsconfig.jsonを作成する

ここまできたら、ついでにテスト時に`ts-jest`で使用される**tsconfig.test.json**も作成することにします。

```json
{
    "extends": "./tsconfig.json",
    "include": [
        "src",
    ],
    "exclude": []
}
```

**jest.config.js**を修正して、`ts-jest`の設定として**tsconfig.test.json**を使用するようにします。

```javascript
module.exports = {
    preset: 'ts-jest',
    testEnvironment: 'node',
    roots: ['<rootDir>/__tests__', '<rootDir>/src'],
    setupFilesAfterEnv: ['<rootDir>/__mocks__/globalMock.js'],
    testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
    testPathIgnorePatterns: ['<rootDir>/../../node_modules/', '<rootDir>/node_modules/'],
    transform: {
        '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/../..//node_modules/ts-jest',
    },
    moduleNameMapper: {
    "^~/(.+)$": "<rootDir>/src/$1",
    "^test/(.+)$": "<rootDir>/test/$1",
    },
    globals: {
        'ts-jest': {
            tsconfig: './tsconfig.test.json',
        },
    },
};
```

# まとめ

これで、すべての設定が完了しました。VSCodeのエディタ画面から煩わしさが減り、**tsconfig.json**を環境ごとに分割したことで、管理のしやすさも副次的に向上したと思います。

年の瀬ということで、年末の大掃除もかねて、既存のプロジェクトに存在する**tsconfig.json**の整理を行ってみることをおススメします！意外と簡単ですよ！

# 参考にした記事

https://stackoverflow.com/questions/57044697/how-to-use-different-tsconfig-file-for-test-files-in-vscode
【TIPS】cloud9でpythonのコマンドを打つとエラーが出たのでバージョンを上げる

# やりたいこと
cloud9でテスト環境を作成した際にpythonのコマンドを確認すると以下のようなエラーが出た。pythonのバージョンが古そうな感じがしているのでアップグレードをして対応したい。

```
hogehoge:~/environment/python $ python -v
import _frozen_importlib # frozen
import _imp # builtin
import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
import '_warnings' # <class '_frozen_importlib.BuiltinImporter'>
import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
# installing zipimport hook

~~~~長いので省略
```

# 手順

```
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ ~/.pyenv/bin/pyenv --version

## ~/.bash_profileに以下を追加し、pyenvのパス設定と設定を行う

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init --path)"
fi

$ source ~/.bash_profile
$ pyenv --version

## 今回は3.8.10をインストールします。

$ pyenv install -l | grep 3.8.
$ pyenv install 3.8.10

$ pyenv versions
$ pyenv global 3.8.10

$ python -m pip install --upgrade pip

$ python -V
$ python -m pip -V

```

とりあえず更新されるのを待つまではこの手順で耐えるしかないか・・・
QuickReportをAlexandriaで

本投稿は、ブログに作成した Delphi Advent Calendar 2021 17日目 の記事をQiita向けに書き直したものです。

# はじめに
UpdateされなくなったQiuckReport(*1)について、パッケージをAlexandriaに対応してみました。

# パッケージ作成
quickreport のProfessional版(ソース付き)を購入していたので、Alexandriaで使えそうか、とりあえずパッケージを作成してみました。Delphiバンドル版でなく、別途購入したものです。
バージョンは最新のVer6でなく、その前のVer5.06になります。Delphiにバンドルされていたのは、こちらのバージョンだと記憶しています。
Delphi10.3 Rioまでは、Delphiの新しいバージョンが出るために対応したパッケージファイル一式ダウンロードできるようになっていたので、それが使えたが、今はできない(*1)ので、Alexandriaでは、自力で試してみます。

1)
Delphi10.3 Rioに、Rio版をインストールし、ソースコード部分をコピー。
2)
上記を、Delphi11 Alexandriaの環境にコピーする。
３）
デザイン用、実行時用パッケージプロジェクトを、それぞれ、QR506DesignDXE11,QR506RunDXE11に変更
４）
R506DesignDXE11.dpkの Requires のQR506RunDXE10_3を、上記に合わせQR506RunDXE11に変更
5)
QR506RunDXE11、QR506DesignDXE11をそれぞれビルド
６）
それぞれの、bplを
C:\Program Files (x86)\Embarcadero\Studio\22.0\bin
にコピー
7)
コンポーネントのインストールからQR506DesignDXE11.bpl をついかすれば、コンポーネントパレットに追加されます

# おわりに

実際にプログラムでの使用はまだ試していません。
Ver5.06は、Berlinでは、実際にDelphiVer7からのマイグレーション作業をしたプログラムで使用していて、特に問題が起きた覚えがないので、Alexandriaでも大丈夫だと期待しています。今のところ実際に使う予定はなさそうですが。


(*1)
サポート開発者の2019年にLutMentz氏が亡くなったため
https://www.quickreport.co.uk/

＃
https://www.componentsource.co.jp/product/quickreport-professional-j
Ver6は、まだ販売しているようだけどほんとに買えるかは不明
PLATEAUのudxフォルダー配下のbldgとかdemとかって何？

PLATEAU のデータをダウンロードすると、 `udx` フォルダーが巨大であることに気づきます。
中身を見ると、以下のように謎のフォルダーがたくさんあり、それぞれが大量の gml ファイルや jpg ファイルを抱えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/14479200-ea8a-74d3-645d-6f12a0d2d270.png)

自分の業務に必要でないものも多く含まれている気がするので、それぞれがどんなデータを格納しているのか調べてみました。

ググっても断片的な情報しか見つけられず、諦めかけていたところ、ダウンロードした zip 内の `specification` フォルダーに仕様書が同梱されていました。（最初に確認すべきでした…）

仕様書を読み解くとこんな感じです！

| フォルダー名 | 格納データ      | 備考                         |
| -------- | ------------ | -------------------------- |
| `bldg`   | 建築物        | おそらく `building` の省略表記 |
| `brid`   | 橋梁          | おそらく `bridge` の省略表記 |
| `dem`    | 地形          | おそらく `digital elevation model` （数値標高モデル）の頭文字 |
| `fld`    | 洪水浸水想定区域 | おそらく `flood` の省略表記 |
| `frn`    | 設置物（都市設備） | 何の略語でしょうか？ご存じの方がいらっしゃったら教えてください！ |
| `lsld`   | 土砂災害警戒区域 | おそらく `landslide` （地滑り）の省略表記 |
| `luse`   | 土地利用       | おそらく `land use` の省略表記 |
| `tnm`    | 津波浸水想定用  | おそらく `tsunami` の省略表記 |
| `tran`   | 道路          | おそらく `transportation` の省略表記 |
| `urf`    | 都市計画区域    | おそらく `urban facilities` の省略表記 |
| `veg`    | 植生          | おそらく `vegetation` の省略表記 |

私の場合、 `bldg` と `dem` さえあれば良いことがわかりました。

# さいごに

本記事作成にあたり、以下のサイトを参考にさせていただきました。
ありがとうございました。

- [3D 都市モデル（Project PLATEAU）東京都 23 区](https://www.geospatial.jp/ckan/dataset/plateau-tokyo23ku)
- [PLATEAU の DEM ファイルに空中写真のテクスチャを貼りたい](https://qiita.com/yoshikawa-hiroyuki/items/6935a9705b3144774fd1)
VSCodeの設定

多分、何度か設定しているが忘れるので自分用備忘録

# インテリセンスの設定

1. 設定を開く
![2022-12-29_09h59_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/e6415434-fb7f-7b70-57a8-1441e7771f71.png)

2. python.autoComplete.extraPathsで検索しsetting.jsonを開く

3. `python.autoComplete.extraPaths`にsite-packagesのパスを入力

絶対パスでも相対パスでもどちらでもOK

![2022-12-29_10h01_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/bb773b77-869e-4eb7-bff0-cd467c9a2825.png)

```
{
    "python.autoComplete.extraPaths": [
        "../../Anaconda3/Lib/site-packages",
        "../../Python/Python38/site-packages",
        "../../Python/Python39/site-packages"
    ]
}
```

これでVSCodeを再起動するとインテリセンスが聞くようになっています。