OmniAICreator/Qiita-1.07M huggingface dataset:
Ender3のホットエンド冷却ファンを交換する


:::note warn
3年前に記述した記事の供養となります。簡潔な内容ですので参考までに。
:::

## はじめに
昨今の感染症の影響で家にいる機会が多いわけですが、その暇つぶしとして3Dプリンターを購入した結果、見事に3Dプリンター沼にはまってしまいました。
購入したEnder3を色々改造しているわけですが、その過程でホットエンドファンのケーブルを断線してしまったので交換することにしました。しかしWebで調べても英語版しかファン交換の記事を見つけることができなかったので今回はこの記事を作成しました。
少しでもEnder3を触っている人のお役に立てればと思います。

私の環境ではSKR1.4で作業を行っていますが、他のボードでも接続部分が異なる以外は同様の作業で交換できると思います。
## 用意するもの
### 必須
- [Ender3]()
- [DCDCコンバータ]()
- [Noctua NF-A4x20 FLX 40mm]()
- はんだ関連用品
- 電圧測定器
 
  
この交換作業ははんだ付けを行うので、はんだ関連の用具は準備が必要です。(プラスで1万円くらいかかりました...)

Noctuaのファンを選んだ理由として海外のサイトなどで名前が頻繁に出ていた為です。ただ冷却性能は要検証らしい。

日本語のブログで二つくらいあるので、そちらで選んだものでも良いと思います。

Ender3のファンは24Vで動いているので12V用のDCDC降圧コンバータも購入しました。

## 交換
### 0. ファン用の固定具を印刷する
- [Ender 3 Hotend Cap for Noctua NF-A4x20 FLX and blower for stock nozzle fan](https://www.thingiverse.com/thing:3553015)

既存の固定用器具だと固定できないのであらかじめ印刷しておきます。

### 1. 既存のファンを取り外す
まず、既存のファンを取り外します。

### 2. DCDCコンバータの取付
DCDCコンバータのIN部分に極性を間違えないようにはんだごてで接続します。その後既存のファンが接続されていた端子にケーブルを差します。
この時にOut端子の電圧を測定し、金色の－ネジ部分を回して電圧を12vに設定します。

### 3. 固定
印刷した固定具にファンを固定し、配線をDCDCコンバータと接続して終わりです！

## 終わりに
ファンの交換は電圧とかいじらないといけないので最初はどうすればいいか困りましたが、
その点を乗り越えれば後は交換するだけなので簡単です。

最終的に騒音の低減を図ることが出来ました！

PSUのファン等も交換できれば交換していきたいと思います。
【Next.js】Cannot find module XXXXエラー対処法


# はじめに
Next.jsを使用したアプリでテストをしようとしたところ以下のエラーが何度か別々のmoduleで出ました。

# エラー内容

```
Cannot find module /XXXX/XXXX/Desktop/Next/nextjs_blog/.next/server/app/articles/new/page.js
```

page.jsというのが見つからないと言われていますが、
実際にアプリ上には上記のディレクトリにpage.jsファイルは存在している状況でした。


# 解決方法
いくつか方法を調べてみましたが、以下のコマンドでnextファイルを一旦削除して再ビルドしたらうまくいきました。

プロジェクトのルートディレクトリで以下のコマンドを実行します。


```
rm -rf .next
```
.next ディレクトリを完全に削除します。
そうすることで古いビルド情報やキャッシュが原因になっている可能性があり、今回のようにmoduleが読み込まれていないので削除することで情報をリセットできます。
このディレクトリは再ビルドをした後にまた自動で生成されます。

```
npm run build
npm run dev
```
続いて、上記コマンドを実行します。
これでアプリケーションを再ビルド、サーバーの再起動を行います。



# おわりに
上記の対応方法がWeb上で見つけることができなかったので、共有させていただきました！同じ事象が出た方の参考になれば幸いです！
【iOS】CallKitでプロジェクト名とは別のアプリ名を表示させる方法

## はじめに
この記事では、iOS14以降でCallKitのUIに表示させるアプリ名を設定する方法を説明します。

過去の記事では`CXProviderConfiguration.init(localizedName:)`で以下の画像の赤枠の位置に表示されるアプリ名を設定していましたが、この方法はiOS14以降ではDeprecatedになっています。
この記事ではiOS14以降でこの部分の表示を変更する方法を説明します。

![IMG_1251.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768381/4160b281-7a7f-1e30-4162-8ffaa4a56075.png)


今回初投稿になります。至らない点、誤っている点がありましたら、コメントでご指摘いただけると幸いです🙇

## 遭遇した問題
前述したように、localizedNameがiOS14でDeprecatedになりました。

```Swift
let providerConfiguration = CXProviderConfiguration(localizedName: "CallKitサンプル")
// 'init(localizedName:)' was deprecated in iOS 14.0
```
localizedNameをセットしても、iOS14以降のデバイスではプロジェクト名が表示されてしまいます。

### 😱公式ドキュメントにも代替策が書いてない！

そこで公式ドキュメントを読んだのですが、

>No longer supported

と一言書いてあるだけで、代替策は書いてありませんでした。

https://developer.apple.com/documentation/callkit/cxproviderconfiguration/localizedname

## 解決方法
TARGETS > Identityにある"**Display Name**"を設定しましょう。
![スクリーンショット 2024-08-29 19.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768381/b8005c85-592e-e907-f8d4-bfa895e92880.png)

Display Nameに入力すると、「ユーザーに表示されるアプリ名」と「CallKitのアプリ表示名」は同一になります。
localizedNameで設定した頃は別々に設定できたようですが、今は不可能なようです。

これでプロジェクト名とは別のアプリ名を表示させることができました。

![IMG_1254.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768381/a7b72130-7e30-2aeb-67f9-a3bc3f2ca929.png)

## さいごに
CallKitに関する記事は古いものが多く、今回のことを日本語で書いている記事を見つけることができませんでした。
パッと調べて見つかったのは、英語のStackOverflowだけでした。

https://stackoverflow.com/questions/69068324/ios-callkit-cxproviderconfiguration-localizename-is-deprecated

細かい内容でも記事や質問が見つけやすい形で存在していることの重要ですね。アウトプットの大切さの一つを学びました。

今回の内容がどなたかの助けになれば幸いです。
Paiza×Qiitaキャンペーン　「残り物の量（Cランク相当）」をPythonで1行で解く

## ステップ1:問題の意味を理解する
最初に問題文を読んでみましょう。
https://paiza.jp/works/mondai/c_rank_skillcheck_archive/leftover

問題の要旨としては、「最初は生のままで売り、売れ残ったら惣菜にする。それでも売れ残ったら残り物として計算する。」といった感じです。

## ステップ2:計算式を考える。
### 1.生のままの販売
m[kg]の生鮮食品を仕入れ、そのうちp[%]が売れました。よって、売れた量は、m×(p/100)[kg] です。したがって、売れ残った量は、 m-m×(p/100)=m×(1-p/100)[kg]

### 2.惣菜としての販売
次に、売れ残った量（m×(1-p/100)[kg]）をすべて惣菜にします。この惣菜のうちq[%]が売れました。よって、惣菜で売れた量は、m×(1-p/100)×(q/100)[kg] です。したがって、惣菜として売れ残った量は、 m×(1-p/100)-m×(1-p/100)×(q/100)=m×(1-p/100)×(1-q/100)[kg]

### 3.最終的な売れ残り量
1と2より、生鮮食品のうち最終的に売れ残った量は、 m×(1-p/100)×(1-q/100)[kg]

## ステップ3:プログラムを書く
ステップ2で作った計算式をもとにプログラムを書きます。
```py
m,p,q=map(int,input().split())#入力を受け取る
keisan=m*(1-p/100)*(1-q/100)#計算する
print(keisan)#出力する
```
## ステップ4:1行にする
```py
print((lambda m,p,q:m*(1-p/100)*(1-q/100))(*map(int,input().split())))
```

### 解説
1.input().split() でスペース区切りの入力を取得し、map(int, ...) で整数に変換する。
2.lambda m,p,q:m*(1-p/100)*(1-q/100) という無名関数（ラムダ関数）を使い、引数 m,p,q を受け取って計算を行う。
3.1で取得した値が lambda 関数に引数として渡される。
4.結果が出力される。
#### 補足
2の無名関数を普通の関数で書くとこうなります。
```py
#無名関数
(lambda m,p,q:m*(1-p/100)*(1-q/100))
#ふつうのかんす
def keisan(m,p,q):
    return m*(1-p/100)*(1-q/100)
```

:::note warn
注意：プログラムを1行で書くと可読性が著しく低下するので、共同作成プロジェクト等ではやらないようにしましょう
:::
【豆知識】RubyとRuby on railsについて改めて調べてみる

# はじめに
学習が進んでいき、覚えていく内容が無限に増えていっています。そして、過去学んだことに怪しい雲が。
今回は表題にある通り「RubyとRuby on rails」について、改めて自分で調べてみようと思いました。はじめて本などで学習したときはうっすらとしか分かりませんでしたが、改めて色々調べると少しWeb用語の知識も増えたおかげがある程度わかるように。


## **1. Rubyとは？**
- **プログラミング言語**: Rubyは、オブジェクト指向のプログラミング言語になります。シンプルで読みやすい構文が特徴で、開発者にとって使いやすい言語として広く使用されています
- **用途**: 一般的なスクリプト作成から、Webアプリケーション開発、データ処理など、幅広い用途で使われています

<br>

## **2. Ruby on Railsとは？**
- **Webアプリケーションフレームワーク**: Ruby on Rails（通称Rails）は、Rubyで書かれたWebアプリケーションを効率的に開発するためのフレームワークになります
- **特徴**: MVC（Model-View-Controller）アーキテクチャを採用していて、コーディングの手間を減らすための便利なツールと規約が整備されています

<br>

## **お互いの関係性**
- **言語とフレームワークの関係**: Rubyはプログラミング言語であり、RailsはそのRubyを使って作られたフレームワークになります。つまり、Railsを使うためにはRubyの知識が必要だということになります！
- **互換性**: Railsは言語であるRubyの上に構築されているため、RubyのコードをRailsの中で使うことができます。しかし、Rails特有の機能や構文もあるため、Rubyだけの知識ではRailsを使いこなすのは難しいので必ず学習が必要！


<br>

## **コードの例**
### **Rubyのコード例**
```ruby
# Rubyのシンプルなクラス定義
class Greeting
  def hello(name)
    "Hello, #{name}!"
  end
end

greet = Greeting.new
puts greet.hello("World")  # 出力: Hello, World!
```

### **Ruby on Railsのコード例**

```ruby
# Railsでのコントローラーの一部
class GreetingsController < ApplicationController
  def hello
    @message = "Hello, #{params[:name]}!"
  end
end

# Railsのビューでの使用
<%= @message %>  # ユーザーが指定した名前を表示する

```

### **ここまでのまとめ**

- **Ruby**はプログラミング言語で、**Ruby on Rails**はその言語で書かれたWebアプリケーションフレームワークである
- Rubyの知識があればRailsを使うことができるが、Rails特有の構文や規約を学ぶ必要がある
- RubyとRailsは密接に関連していて、RailsはRubyの機能を活かしてWebアプリを素早く構築するためのツール


<br>

## 上記を理解したうえでの疑問と再確認

### **1：Ruby on Railsを単独で使用することはできない？**
**回答**: Ruby on RailsはRubyというプログラミング言語の上に構築されたフレームワークだから、Rubyを使わずにRailsを単独で使用することはできない。Railsを使うためには、Rubyの知識が必要

### **2：Rubyというプログラミング言語を使用している前提でRuby on Railsというフレームワークを使用できる？**
**回答**: Rubyの上にRailsがあるから、Rubyを使うことでRailsも使えるという関係になっている。Rubyを学んでからRailsに進むのが一般的な流れ

### **3：別のフレームワークでもRubyという言語は使用できるのか？**
**回答**: RubyにはRuby on Rails以外にもいくつかのフレームワークがある。例えば、**Sinatra**や**Hanami**などが有名。

<br>

## **どのようなフレームワークが最適とされているのか？**
- **Sinatra**:
    - **特徴**: 軽量でシンプルなWebアプリケーションフレームワーク。小さなアプリやAPIを素早く作るのに向いている
    - **違い**: Railsに比べて、規約が少なく、自由度が高いから、必要な機能だけを選んで使える
- **Hanami**:
    - **特徴**: モダンなフレームワークで、マルチページアプリケーションを作るための機能が整っている。パフォーマンスに優れていて、コンポーネント指向で設計されている。
    - **違い**: Railsよりも軽量で、パフォーマンスが高いが、学習コストが少し高いかもしれない


### **上記フレームワークとRuby on Railsとどのような違いがあるか？**


- **Sinatra**と**Rails**の違い:
    - Sinatraは軽量でシンプル、必要な機能だけを追加するスタイルだが、Railsは「規約より設定」を重視していて、大規模なアプリに向いている
- **Hanami**と**Rails**の違い:
    - Hanamiはパフォーマンスやコンポーネント指向が特徴で、Railsよりも新しい設計哲学を持っている。Railsは成熟していて、豊富なライブラリやコミュニティが強み

### **ここまでのまとめ**
RubyはRuby on Railsだけでなく、SinatraやHanamiなどのフレームワークでも使える。

## さいごに
プログラミング言語を土台としてそれぞれの状況に応じてフレームワークを決めていくという流れを理解することができました。単純にこれとこれのペアは絶対！！というわけではないんですね。
今回の記事が何か参考になれば幸いです。
winget を用いた Microsoft Store アプリのオフライン ダウンロードに必要なPackageIDについて

# 概要

 Windows 11では下記Microsoft公開情報に記載がありますように Store for Business がサポートされておらずオフライン環境でのアプリのインストールは困難でした。


* [ビジネスおよび教育機関向け Microsoft Store の廃止 (2023 年 3 月 31 日) - Microsoft Lifecycle | Microsoft Learn](https://learn.microsoft.com/ja-jp/lifecycle/announcements/microsoft-store-for-business-education-retiring)

先ごろMicrosoftの blogにてその制約を打破できるソリューションが提供されました。 

[winget を用いた Microsoft Store アプリのオフライン ダウンロードについて (正式版が公開となりました) | Microsoft Japan Windows Technology Support Blog](https://jpwinsup.github.io/blog/2024/06/10/UserInterfaceAndApps/winget-store-download/)

本手順での実施にはアプリの PackageID が必要となりますが残念ながら　Blogには記載がございません。

2024 年 8 月 29 日時点で Windows 11 バージョン 23H2 でプレインストールされているアプリについて確認できた PackageID をまとめます。


# 2024 年 8 月 29 日時点で確認できた PackageID 一覧

下記となります。


| アプリ名               | PackageID      | 
| ---------------------- | -------------- | 
| Cortana                | 9NFFX4SZZ23L   | 
| Microsoft 365 (Office) | 9WZDNCRD29V9   | 
| Microsoft Clipchamp    | 9P1J8S7CCWWT   | 
| OneDrive               | 9WZDNCRFJ1P3   | 
| Microsoft Teams        | XP8BT8DW290MPQ | 
| Microsoft To Do        | 9NBLGGH5R558   | 
| Outlook for Windows    | 9NRX63209R7B   | 
| Power Automate         | 9NFTCH6J7FHV   | 
| Snipping Tool          | 9MZ95KL8MR0L   | 
| Windows クロック       | 9WZDNCRFJ3PR   | 
| Xbox                   | 9MV0B5HZVK9Z   | 
| カメラ                 | 9WZDNCRFJBBG   | 
| クイック アシスト      | 9P7BP5VNWKX5   | 
| サウンド レコーダー    | 9WZDNCRFHWKN   | 
| ターミナル             | 9N0DX20HK701   | 
| ニュース               | 9WZDNCRFHVFW   | 
| フィードバック Hub     | 9NBLGGH4R32N   | 
| フォト                 | 9WZDNCRFJBH4   | 
| ペイント               | 9PCFS5B6T72H   | 
| マップ                 | 9WZDNCRDTBVB   | 
| メディア プレーヤー    | 9WZDNCRFJ3PT   | 
| メモ帳                 | 9MSMLRH6LZF3   | 
| 映画 & テレビ          | 9WZDNCRFJ3P2   | 
| 天気                   | 9WZDNCRFJ3Q2   | 
| 電卓                   | 9WZDNCRFHVN5   | 
| 付箋                   | 9NBLGGH4QGHW   | 


# 注意事項

年月をへてアプリのバージョンが変わる可能性はありますのでご注意ください。

その場合にはMicrosoft Store へ接続できる端末で下記を実施し最新のPackageIDを確認してください。

~~~
winget search -s msstore アプリ名
~~~

例

~~~
winget search -s msstore "Snipping Tool"
~~~

もしくは下記ページでダウンロードしたいアプリを検索し、そのurlから判断してください。

[ホーム - Microsoft Apps](https://apps.microsoft.com/home?hl=ja-jp&gl=JP)

![スクリーンショット 2024-08-29 190834.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/9c91aa06-8d7c-485a-1da1-789fad02b8ee.png)

# 補足

正直なところ PackageID を探すよりもMicrosoft 米本社で作成されている記事のように英語のアプリ名でダウンロードしてしまうほうが早い気ように思います。


[Use WinGet 1.8 to download Microsoft Store apps | Windows IT Pro Blog](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/use-winget-1-8-to-download-microsoft-store-apps/ba-p/4204522)

ただ和名と英語名だとかけ離れいるものがあったり、サードパーティの類似アプリがひっかる可能性もありますのでご注意ください。
プログラミング初心者が最難関問題をAIに解いてもらった【村人の友好関係 (paizaランク S 相当)】

# はじめに
プログラミング初心者がpaizaラーニングの最難関問題をAIに解いてもらった結果と、実装されたコードについてのメモをまとめた記事です。
詳しいことはあまり分からないのでコメントなどで私の知識を補ってくださる方はぜひコメントをお願いします。
# 問題内容
以下を参照
[【殿堂入りキャンペーン】村人の友好関係 (paizaランク S 相当)](https://paiza.jp/works/mondai/s_rank_skillcheck_archive/group_popularity)
# 使用したAI
ChatGPT (無料版) GPT-4o
# AIが実装したコード
    import sys
    input = sys.stdin.read
    data = input().splitlines()

    # 入力をパース
    N, M, Q = map(int, data[0].split())
    friendship = [[0] * (N + 1) for _ in range(N + 1)]

    # 友好度情報の格納
    for i in range(1, M + 1):
        a, b, f = map(int, data[i].split())
        friendship[a][b] = f
        friendship[b][a] = f

    # 同好会グループの管理
    club = set()
    results = []

    # クエリの処理
    for i in range(M + 1, M + 1 + Q):
        op, q = data[i].split()
        q = int(q)

        if op == '+':
            # 村人qをグループに追加
            club.add(q)
        elif op == '-':
            # 村人qをグループから削除
            club.remove(q)

        # グループの人気度を計算
        max_friendship = 0
        for member in club:
            for outsider in range(1, N + 1):
                if outsider not in club:
                    max_friendship = max(max_friendship, friendship[member][outsider])

        results.append(max_friendship)

    # 結果を出力
    sys.stdout.write("\n".join(map(str, results)) + "\n")
# 結果
83点(不合格)
どうやらこのコードの場合、関係の数が多すぎるとタイムアウトして失敗になってしまうようです。
ただ、コード自体は単純で現時点の自分の知識でも理解できたためよしとしました。
# コードについてのメモ
    import sys
    input = sys.stdin.read
    data = input().splitlines()
・sysライブラリを読み込み
・sys.stdin.readで入力をまとめてinput変数？に保存(このinputが1行下のinput()とどんな関係があるのかは不明。ただこの行を消すとエラーが出るので何かしら使われてはいる？)
・各行ごとにリストとして分割し、dataに格納

    N, M, Q = map(int, data[0].split())
    friendship = [[0] * (N + 1) for _ in range(N + 1)]
・dataの最初の内容(入力の1行目)をmapでまとめて数値化しながらsplitで3つの変数に分割して保存
・ループを使ってfriendshipに村人リストを作る(N+1にすることでリストのインデックスと村人のナンバリングを一致させている？)

    for i in range(1, M + 1):
        a, b, f = map(int, data[i].split())
        friendship[a][b] = f
        friendship[b][a] = f
・関係性の数と同じ回数のループを設定し、dataの2つ目以降の内容をsplitで3分割
・村人間の関係性とひっくり返したものをそれぞれ異なる変数に保存？

    club = set()
    results = []
・グループに所属する村人を管理するために空集合を用意
・グループ人気度を格納しておくためのリストを用意

    for i in range(M + 1, M + 1 + Q):
        op, q = data[i].split()
        q = int(q)

        if op == '+':
            # 村人qをグループに追加
            club.add(q)
        elif op == '-':
            # 村人qをグループから削除
            club.remove(q)
・入退会のデータをループとsplitで「行ったのは入退会のどちらか」と「誰が入退会したか」に分割
・ifでclubに入退会情報をまとめる。

    max_friendship = 0
    for member in club:
        for outsider in range(1, N + 1):
            if outsider not in club:
                max_friendship = max(max_friendship, friendship[member][outsider])
    results.append(max_friendship)
・max_friendship変数を用意
・ifで所属していない村人を選別しつつ、二重ループで総当たりして最大の有効度をmax_friendshipに保存する
・内側のループが終了するたび、resultsにmax_friendshipを格納する(これによって入退会が発生するタイミングごとの最大値を記録する)
・ところでこのfriendship[member][outsider]、リストの中のリストを呼び出す書き方なのだろうか？

    sys.stdout.write("\n".join(map(str, results)) + "\n")
・最終的にresultsリストを書き出して完了

# 感想
AIの進歩ってすごい。
思いを言葉にする力

## 本の情報
**タイトル**
「うまく言葉にできない」がなくなる言語化大全
**著者**
山口 拓朗

## 本の内容
言語化をする力は、「語彙力」「具体化力」「伝達力」の3点からなる。
「伝達力」ばかりが重要視されがちだが、そのほかの2つも身に着けることで言語化をする力につながる。

* 語彙力
使える言葉がどれだけあるかを示す力。
語彙を増やしてぴったりくる言葉を見つけられるようになると、自分の思いや考えが正確に言葉にできるようになる。
日常生活の中で「出会う(本や経験で新しい語彙を見つける)」→「調べる(正確な意味や類語との差を知る)」→「覚える(実際に使って脳に定着させる)」のサイクルを行うことで、語彙力を伸ばしていく。
トレーニング例：言葉の置き換え・連想・説明

* 具体化力
どのような思いや考えを伝えたいのかを明らかにする力。
伝えたいものが浮かばない、何となく浮かんでいるが整理できていない という状態を解決して伝えたい内容を整理できるようになる。
5W3Hを使って細かい情報を具体的に洗い出す習慣を持つことで、具体化力を身に着ける。
特に、「なぜ？」と「たとえば？」を繰り返すと事実の整理だけでなく、自分の意見の掘り下げなどもしやすくなる。
トレーニング例：「なぜ？」の繰り返し・詳細の描写

* 伝達力
相手が欲しい情報を届ける力。
相手が欲しい要素を踏まえて、具体化した情報から必要なものを相手に渡せるようになる。
相手が理解しやすいか？理解できているか？を考慮しつつ、限りある時間や文字数で伝えることを意識すると必要な要素だけを伝えやすくなる。
トレーニング例：言葉がけ・ネーミング

言語化ができるようになることで、自分がコントロールできるようになることに加え、他者とのコミュニケーションも行いやすくなっていく。

## ためになった点
* 「理解語彙」と「使用語彙」
自分が持つ語彙には、意味を知っていて見聞きしたときに理解できる「理解語彙」と普段から使っていて話したり書いたりするときに使う「使用語彙」がある。このうち、語彙力につながるのは「使用語彙」であり、これを増やすためには実際に使っていくしかない という記載があった。
自身の言動や思考を振り返ると「聞いたことはある」「何となくこういった意味と思っている」と言っていることが多く、まさに「理解語彙」で止まってしまっていることが多いと感じた。
本にあるトレーニングをベースに「使用語彙」を増やし、思いや考えを正確に言語化できるようにしたい。
* 「伝える」ではなく「伝わる」
本に記載されていた言葉だが、これを読んで「伝える」ことに意識が向いてしまっていると気づいた。
=「自分が読んだ時に理解しやすい言葉選びや構成」になっている
相手が何を求めていてそのために必要な情報は何なのか、余分なことに言及していないか といった視点を心がけたい。

## まとめ
具体的なコツやトレーニングに関する記載が多くあり、日常に組み込めそうな本でした。
簡単なことからでも、正確に理解した言葉を使ってアウトプットする ことを行っていきたいと思います。
ありがとうございました。
Git005:Gitの作法 Mergeのconflictの作りと作業方法(Shift-JIS,文字Code対応)

### GitのMergeは正直かなり分かりづらい挙動をします。

```
git merge <Branch名>
```
現在のBranchに対して指定したBranchをMergeし、不整合(conflict)があると変更状態になるのですが、conflictが発生したFileは2つのSourceの結合状態になります。

```
<<<<<<< HEAD
// 現在のブランチの内容
=======
// Mergeするbranchの内容
>>>>>>> Mergeするbranch
```
MergeするFileを置いてくれれば差分見ながらMergeするのに、「結合」しやがるんです。
差分がどこにあるとかいう情報はないです。結合です。

そして、文字CodeがUTF-8ではない場合にこの結合で文字化けが発生する場合があり、この状態になると変更箇所が膨大になり手動での結合なんてものはできません。
(文字Codeの設定についてはGit003を参照)

### GitのMerge機能はSmartとはとても言えない！！力技で解決！
Merge状態になると、Conflict状態のfileを全てStagingか、Merge abortで諦めるしかないです。
```
#Stagingのコマンド(GUIでStagingする方が楽)
git add <File名>

#MergeのAbortコマンド
git merge --abort
```

＜Mergeを進める対応方法＞
- △Merge Editorを使って、conflictを解決してMergeを終了(Staging)。
　→文字化けしている場合は変更箇所が多くてやってられません。

- △Conflictを解決しないままStaging。
　→結合FileがStagingされます。もうひと手間かけてもいいんじゃないでしょうか？
 　明らかに間違っているFileになるので分かりやすい方はこの方法でもOK。

- ○？とりあえず現在か、Merge側か選択してMerge終了(Staging)する。

- ○？ConflictのFileをMergeするFileで上書きしてからStagingする。
または、結合Fileの余計な記号や片方のSourceを全消してからStagingする。
→たまに変換ErrorとかでStagingが進まない場合もこの方法なら進みます。安定性は最強。
 
どの方法でStagingしても、一度Stagingを解除して変更状態にして確認(Stagingは文字Code問題あるからね→Git003)。
必要なら手動でMergeしましょう。
力技でconflictを個々に解決します。

### そもそも、Mergeコマンド使わない選択肢もありますよ？
Mergeコマンドは作りが悪いので、Merge先BranchにCheck outしてFile全部コピーしてから戻ってきてコピーファイル上書きも検討した方がいいんじゃないでしょうか？

[現在Branch] → [Merge先Branch] →全File Copy
  ↓
全File上書きPaste
  ↓
手動Merge

多少面倒ですが、
・間違いやすい手順は無くなり、
・確認せずにMergeされるSourceは無くなり、
　※例えば、2つの挙動の違うブランチA,Bを管理していて、Aの挙動に合わせて作った機能を
　　そのままBにMergeするとAの挙動に合わせた部分はBにはないのでConflict無くMergeされたりする。
  　Conflictが無くても安全とは限らない。
・通常のSoft変更と同じ手順でMergeができます。


この場合のデメリットはGitの扱いではMergeではなくFile変更なので、どこのBranchとMergeした記録が残らず、Git GraphなどでMergeした時の経路がグラフィカルに見えないという点のみです。
matter.jsでオブジェクトに引力を付与する

# はじめに

matter.jsでワールドではなくオブジェクトに引力をつけて惑星みたいな挙動を作りたかった。

だいぶ前にもmatter.jsユーザの中でこの機能を欲する声があったらしいが、公式ライブラリではなく、プラグインで対応することになったらしい。

https://github.com/liabru/matter-js/pull/132

<br />

**が、そのプラグインは7年前で更新が止まっており、最新のmatter.jsだと動かない...**

https://github.com/liabru/matter-attractors/tree/master

幸いなことにコード見てみたら意外と簡単な実装だったので自分で再現してみようと思った。

# 作りたいもの
下記のデモみたいなやつ

https://liabru.github.io/matter-attractors/#basic

## 実装
※基本的なMatter.jsの設定は実装できている前提
<br />

まず下記の`Attractor`を準備する。
```ts
const setAttractor = (bodyA: Matter.Body, bodyB: Matter.Body) => {
  return {
    x: (bodyA.position.x - bodyB.position.x) * 1e-6,
    y: (bodyA.position.y - bodyB.position.y) * 1e-6,
  };
}
```

これは二つの物体間に発生する引力のベクトルを戻り値として返す。

次に`afterUpdate`内で下記のように利用することで引力を付与する仕組みを作ることができる。
```ts
Matter.Events.on(engine, 'afterUpdate', (event) => {
    let bodies = Matter.Composite.allBodies(engine.world)

    for (let i = 0; i < bodies.length; i++) {
      const bodyA = bodies[i]
      
      // 引力を付与したい物体の作成時にblackhallBallsという配列にidを追加している
      if (blackhallBalls.includes(bodyA.id)) {
        for (let j = 0; j < bodies.length; j++) {
          const bodyB = bodies[j]
          const force = setAttractor(bodyA, bodyB)

          // ここで引き寄せられる側の物体に引力を適用する
          Matter.Body.applyForce(bodyB, bodyB.position, Matter.Vector.create(force.x, force.y))
        }
      }
    }
  })
```

## 実際に動かしてみたデモ
![abcde.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303906/1e200474-19c2-168f-a81c-587a0230c823.gif)

それっぽい感じになった！
パワポをコピーしてテキスト保存したら疑問形になった話（ゼロ幅スペースの削除方法）

## 起きた事象
1. パワポに書いてある行すべてコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/6d80c514-ba52-f137-e9a0-51182684035f.png)

2. VS Codeにペースト＆保存（SJIS）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/3f3e12f0-b109-6ad9-703e-4ccd0a2cdd4a.png)

3. VS Codeで同じファイルを開き直す（SJIS）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/3d84776d-ead8-5860-3d00-3ff5aae06e78.png)

パワポで書いていた文章が疑問形になってしまった。

## 原因

同じようにパワポをコピーして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/1243b20c-cf39-97e8-dece-5f103c3c0ca4.png)

sakuraに貼り付けてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/00a22376-91d3-b5fa-5d19-f1dfce2e3922.png)

\u200bが改行の前に入り込んでいる模様
ググってみるとゼロ幅スペースというものらしい

https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E5%B9%85%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9

ちなみにsakuraの場合、ゼロ幅スペースが含まれた状態でSJISで保存しようとすると消える旨のダイアログが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559813/7ad3cf66-632a-284a-6879-ccb8335c6677.png)

## 対策

vscode-bs-ctrlchar-removerなるものをインストールして

https://github.com/satokaz/vscode-bs-ctrlchar-remover/blob/master/README_ja.md

settings.jsonに以下を記載
``` settings.json
    "editor.formatOnSave": true,
    "ctrlchar-remover.pattern": "[\\u200B]",
```
これでVS Codeで保存時に\u200bが削除されるようになった。
◆HTML/CSS　備忘録④ ボックスモデル

今回は、CSSの「ボックスモデル」について書き留めていきたいと思います。
Webページを作成する上でボックスモデルを理解するのは、大変重要です。

# そもそもボックスモデルとは
CSSには「HTMLの要素はすべて四角形の領域を形成する」というボックスと呼ばれる概念があります。
レイアウトを作成したり、アイテム同士を揃えたりするのに必要な考え方です。

また、CSS の定義するボックスモデルは以下の図のように 4つの領域で構成されています。

:::note
- content (内容)
- padding (パディング)
- border (ボーダー)
- margin (マージン)
:::

![イラスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149624/0122e7bb-b756-d772-689b-35452bb211b9.png)

## ボックスモデルの構成について
- **content（内容）**
テキストや画像など、要素そのものの内容が表示される領域です。この領域のサイズは width（幅） と height（高さ）プロパティで指定することができます。
　
- **padding（パディング）**
content と border の間にある余白の領域です。要素の内側の余白を取るために使います。この領域のサイズは padding プロパティで指定することができます。
　
- **border（ボーダー）**
padding の外側にある領域、いわゆる枠線です。この領域のサイズは border-width プロパティで指定することができます。
　
- **margin（マージン）**
ボックスの一番外側の余白の領域です。この領域のサイズは margin プロパティで指定することができます。

## ボックスの種類
使うタグによってできるボックスに種類があります。
特に重要な３種類がありますので、以前紹介したブロックレベル要素とインラインレベル要素のおさらいになりますが、紹介いたします。

※以前の記事は[こちら](https://qiita.com/ume_work0831/items/fb79a980bde0f506bc13)です


:::note
- ブロックボックス
- インラインボックス
- インラインブロックボックス
:::

- **ブロックボックス**
ブロックボックスは、上から下へ配置されます。
前後に改行が入るものと考えてください。
また、横幅と高さを指定することができます。
指定しない場合、ページの横幅いっぱいに広がります。
　
 - **インラインボックス**
インラインボックスは、左から右へ配置され、
横幅いっぱいになると自動で折り返されます。
横幅と高さを指定することはできません。
　
 - **インラインブロックボックス**
インラインブロックボックスは、
上記2つの特徴を併せ持つボックスです。
横幅と高さを指定することができ、左から右に並んで配置されます。


これらの特徴を理解していくと、レイアウト作成やコンテンツの配置がスムーズにできるようになります。
terraform でIAMユーザを作成して簡易的に追加できるようにした


## 開発経緯
チームに新しい人が加わった時に、いちいちAWSのユーザ登録をし、その情報を新規メンバーに送るのが面倒であるため、簡略化したい

## 概要
Teraaform上のコマンドの実行のみでAWS上にIAMユーザを追加できるようにする
作成したIAMユーザの情報をテキストファイルとして格納し、スラックで通知することでログイン情報を自動取得する

## アーキテクチャ図
![スクリーンショット 2024-09-10 23.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817233/9c865700-c40e-c2a2-6b4d-b5341428496e.png)



## ディレクトリ構成
<pre>
├── README.md
├── backend.tf                           # teraformのStateやVersionを管理
├── iam_user.tf                          # 新規ユーザを作成し、ログイン情報をファイル形式へ変換
├── output.tf                            # アウトプット状況に基づいて、ログインに必要なパスワードを生成
├── provider.tf                          # providerを設定
└── s3.tf                                # 新たに作成されたyユーザのログイン情報を{ユーザ名}.txtとして格納
</pre>

## S3にユーザ情報が保存されるまでの思考過程
ユーザを追記したら、そのログイン情報が勝手にS3にアップロードされる必要がある
情報を管理するために、S3に保存するためには、一旦ファイル形式で格納しておくことが必要
- localfileでファイル名とコンテントを記入することで、指定フォルダにファイルが可能になる
- また今回はファイルの形式も指定しているが、他にもCSV形式などで指定することも可能
今回は以下の情報をIAMから撮ってきてlocalfileに格納した
    ```
    resource "local_file" "user_info" {
      for_each = aws_iam_user.test_new_user
      filename = "${pathexpand("./")}/${each.value.name}_user_info.txt"
      content  = <<EOF
        IAM User Name: ${each.value.name}
        Password: ${aws_iam_user_login_profile.test-login-profile[each.key].password}
        Login URL: <https://wevox-login.signin.aws.amazon.com/console>
    EOF
    }
    
    ```
## Lamdaによるアップロードを検知する
- lambdaに関して
    - イベント発生時に、コードを実行し、リソースを自動的に管理するもの
    - なんらかのイベントの発生に伴い、あらかじめ設定した処理が行われるもの
        ```
        file_key = record['s3']['object']['key']
                response = s3.get_object(Bucket=bucket_name, Key=file_key)
                content = response['Body'].read().decode('utf-8')
                message = f"新しいIAMユーザ '{file_key}' が追加されました。\\n\\nログイン情報:\\n{content}"
        ```

## Slackへのログイン情報通知
- Incoming webhoolsの使用に関して
    - 以下の設定に伴って、Slack＝urlを取得することで、スクリプトからの通知が可能になる
    - https://qiita.com/ik-fib/items/b4a502d173a22b3947a0
- PythonのHTTPリクエストに関して
    - 参考　https://techblog.tver.co.jp/entry/h-abe/lambda-slack-tool
    - get,,postリクエストを送信するもの

## 参考文献
以下の記事を参考にさせていただきました。
・　https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_group_membership

・https://qiita.com/hiyanger/items/8f925e21166461a5ddb1
GOのAWS SDKでEC2のインスタンスを作成

# はじめに
GoのAWS SDKを使用してEC2のインスタンスを作成してみました。これまでも、インスタンスの起動、停止用のツールとして使用していましたが、もうちょっと深く学習してみようと思い、EC2インスタンスの作成を行ってみました。

# 環境
* Windows 11
* AWS SDK for Go v2

# 前提
AWSサービスにプログラムからアクセスするため、AWS側でAccess Key IDとSecret Access Keyを事前に作成し、~/.aws/credentialsファイルを準備しました。SDKでもcredentialsファイルからプロファイルを読み込むことができます。

【credentialsファイル】
```
[myregion]
aws_access_key_id = <Access Key ID>
aws_secret_access_key = <Secret Access Key>
```

また、EC2で使用するKeyPaire、Subnet、SecurityGroupも事前にAWSで作成しています。プログラムで作成できますが、力不足のためやってません。

# コード（インスタンス作成部分）
```GO
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		Profile: "myregion", // specify profile
	}))
	svc := ec2.New(sess, aws.NewConfig().WithRegion("ap-northeast-1"))
	result, err := svc.RunInstances(&ec2.RunInstancesInput{
		ImageId:      aws.String("ami-00c79d83cf718a893"),
		InstanceType: aws.String("t2.micro"),
		MinCount:     aws.Int64(1),
		MaxCount:     aws.Int64(1),
		KeyName:      aws.String("testkey"),
		//SecurityGroupIds: []*string{aws.String("sg-05c48f49dbf81efeb")},
		NetworkInterfaces: []*ec2.InstanceNetworkInterfaceSpecification{
			{
				DeviceIndex:              aws.Int64(0), // required
				AssociatePublicIpAddress: aws.Bool(true),
				SubnetId:                 aws.String("subnet-05f2a9a81d40d433d"),
				Groups:                   []*string{aws.String("sg-05c48f49dbf81efeb")},
			},
		},
	})

	if err != nil {
		log.Fatalf("Unable to create instance, %v", err)
	}
	fmt.Println(result)
```
①　~/.aws/credentialsファイルに指定した"myregion" プロファイルを使用してAWSセッションを作成
②　"ap-northeast-1" リージョン用の EC2 サービスクライアントを初期化
③　ec2.RunInstancesで指定されたパラメタにもとづきインスタンスを作成
④　作成するEC2インスタンスの情報がresultにJSON形式で設定される

ec2.InstanceNetworkInterfaceSpecificationで、作成するEC2インスタンスのパラメタを設定していますが、
指定できるパラメタについては、APIのリファレンスを確認しました。
* https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#RunInstancesInput
* https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#InstanceNetworkInterfaceSpecification

パラメタには、次のものを指定しています。Key Pair、subnet、Secrurity Groupは事前にAWS側で作成したものからIDを拾ってきています。また、AssociatePublicIpAddressをtrueにしておくことで、pubic IPが割り振られます。

* AMI: ami-00c79d83cf718a893
* Instance Type: t2.micro
* Key Pair: testkey
* Subnet: subnet-05f2a9a81d40d433d
* Security Group: sg-05c48f49dbf81efeb

ちなみに、AMIに指定するIDは、AWSのコンソールから確認できますが、SDKを使用して次のようなコードで取得することもできます。次の例では、amazonが所有する、AMIのImageID、Imageの名前、作成日を10件分出力さしています。

```Go
	params := &ec2.DescribeImagesInput{
		Owners:     []*string{aws.String("amazon")},
		MaxResults: aws.Int64(10),
	}

	res, err := svc.DescribeImages(params)
	if err != nil {
		fmt.Println(err.Error())
	}
	for _, image := range res.Images {
		fmt.Println(*image.ImageId, *image.Name, *image.CreationDate)
	}
 ```

# おわりに
AWSを操作するのみであれば、CLI、スクリプト言語のほうがお手軽ですが、Goを使用してツールを作った場合、実行ファイルにしてインストールすることなく別の端末に配置して使用できるところが便利だと思いました。
GitHub CLI で、OrganizationのMember一覧を取得する【GitHub】

# やりたいこと
GitHubのOrganizationのメンバー棚卸しをしたい。
GitHub CLI で、OrganizationのMember一覧を取得する。


# やりかた
### とりあえずメンバーのユーザー名一覧だけ取得したい場合
```bash
YOUR_ORGANIZATION_NAME="hoge"
gh api "/orgs/$YOUR_ORGANIZATION_NAME/members?per_page=100" | jq '.[].login'
```
- `per_page`は、何件まで表示させたいかを指定します。指定しないとデフォルトで30件までしか表示されないので注意。
    - [公式ドキュメント - クエリパラメータ](https://docs.github.com/ja/rest/using-the-rest-api/getting-started-with-the-rest-api?apiVersion=2022-11-28#query-parameters)
    - [公式ドキュメント - ページごとのアイテム数の変更](https://docs.github.com/ja/rest/using-the-rest-api/using-pagination-in-the-rest-api?apiVersion=2022-11-28#changing-the-number-of-items-per-page)
    - 上記の例では`100`としてますが、Organizationsのメンバーの数に応じて調整してください。

### メンバーの権限も併せて取得したい場合
ユーザー棚卸しではOrganizationの権限（Member or Owner）を見たいことがあります。


```bash
YOUR_ORGANIZATION_NAME="hoge"

members=($(gh api "orgs/$YOUR_ORGANIZATION_NAME/members?per_page=100" | jq -r '.[].login'))

for member in $members; do
  role=($(gh api orgs/$YOUR_ORGANIZATION_NAME/memberships/$member | jq -r '.role'))
  echo "Username: $member / Role: $role"
done
```
結果
Owner権限を持つユーザーのRoleは「admin」と表示されるようです。
```
Username: yamada-taro / Role: admin
Username: sato-jiro / Role: member
```

# 参考URL
[公式ドキュメント - Organization メンバーの REST API エンドポイント](https://docs.github.com/ja/rest/orgs/members?apiVersion=2022-11-28)
EACCES: permission denied, unlink '/usr/local/bin/code' codeをインストールできない

## 解決方法
codeコマンドをアンインストールし、再度インストールする。

【手順】
1. VSCodeを開き「Shift+command+P」を押下し、コマンドパレットを表示。
2. シェルコマンド：'code'コマンドをPATHからアンインストールを選択する。
3. 再度「Shift+command+P」を押下しコマンドパレットを表示。
4. シェルコマンド：PATH内に'code'コマンドをインストールを選択する。
Github-repository-create-and-clone

# 概要
- Githubに新しいrepositoryを作成し、localにcloneする作業を何度もしているので効率化するツールを作った。
- Githubに新しいrepositoryを作成し、localにcloneするツールの使い方を紹介。
- 私はSourcetreeを使用しているので、それの管理に入れる方法も込み。
- 該当リポジトリは以下

https://github.com/takuma-competition/github-repo-creator

## 主な機能
1. GitHub CLI を使用した新規リポジトリの作成
2. 作成したリポジトリのローカルへのクローン
3. SourceTree への自動追加（SourceTree がインストールされている場合）
4. 対話型モードと非対話型モードの両方をサポート

```mermaid

graph TD
A[開始] --> B[GitHub CLIをインストール]
B --> C[GitHub CLIで認証]
C --> D[新しいリポジトリを作成]
D --> E[指定した場所に移動]
E --> F[リポジトリをクローン]
F --> G[SourceTreeにリポジトリを追加]
G --> H[終了]
```

## 使用方法
1. 以下の手順を実行する前に、`GITHUB_TOKEN` 環境変数に有効な GitHub アクセストークンを設定してください。
    ```bash:
    export GITHUB_TOKEN=your_token
    ```
2. `configs.sample.txt` を `configs.txt` にリネームし、設定を編集します。
    - `INTERACTIVE_MODE`: 対話型モードを使用するかどうかを設定します（`true` または `false`）。
    - 非対話型モード用の設定:
        - `REPO_NAME`: リポジトリ名を設定します。
        - `LOCAL_PATH`: ローカルパスを設定します。
        - `IS_ORG`: 組織アカウントで作成するかどうかを設定します（`true` または `false`）。
        - `ORG_NAME`: 組織名を設定します（`IS_ORG` が `true` の場合）。
        - `IS_PRIVATE`: プライベートリポジトリにするかどうかを設定します（`true` または `false`）。
        - `CREATE_README`: README を作成するかどうかを設定します（`true` または `false`）。
        - `DESCRIPTION`: リポジトリの説明を設定します。
        - `CREATE_GITIGNORE`: .gitignore ファイルを作成するかどうかを設定します（`true` または `false`）。
        - `LICENSE_CHOICE`: ライセンスを選択します（1: MIT, 2: Apache-2.0, 3: GPL-3.0, 4: No license）。
3. `setup_github_repo_tools.sh` を実行して、必要なツールをインストールまたは更新します。

    ```bash
    $ ./setup_github_repo_tools.sh
    ```
4. `create_github_repo.sh` を実行して、GitHub リポジトリを作成します。
    1. 対話型モードの場合は、プロンプトに従って必要な情報を入力します。
    2. 非対話型モードの場合は、`configs.txt` で設定した値が使用されます。
    ```bash
    $ ./create_github_repo.sh
    ```
5. スクリプトが完了すると、指定したローカルパスにリポジトリがクローンされ、[README.md](http://readme.md/) と .gitignore ファイル（設定されている場合）が作成されます。
6. リポジトリが正常に作成されると、SourceTree に自動的に追加されます（SourceTree がインストールされている場合）。

## ファイル構成
- `configs.sample.txt`: 設定ファイルのサンプル
- `create_github_repo.sh`: GitHub リポジトリを作成するメインのシェルスクリプト
- `setup_github_repo_tools.sh`: 必要なツールをインストールまたは更新するシェルスクリプト
- `LICENSE`: MIT ライセンスファイル
- `README.md`: プロジェクトの説明ファイル
- `.gitignore`: 無視するファイルを指定するファイル

## 必要な環境
- macOS
- Homebrew
- GitHub アカウント
- GitHub アクセストークン（`GITHUB_TOKEN` 環境変数に設定）

## 注意事項
- このスクリプトは macOS 環境で動作するように設計されています。
リモートブランチにpushしたけどやっぱりブランチ名変えたい！


### ブランチ名の変更手順

1. **現在のブランチが `対象のブランチ` であることを確認**
   ```bash
   git branch
   ```
   もし他のブランチにいる場合は、対象のブランチに切り替えます。
   ```bash
   git checkout 対象のブランチ名
   ```

2. **ローカルで対象のブランチを新しいブランチ名に変更**
   ```bash
   git branch -m 新しいブランチ名
   ```

3. **リモートリポジトリの古いブランチ名を削除し、新しいブランチ名をプッシュ**
   ```bash
   git push origin --delete 古いブランチ名
   git push origin 新しいブランチ名
   ```

4. **リモートリポジトリでトラッキングを設定**
   ```bash
   git push --set-upstream origin 新しいブランチ名
   ```

EOF
webページが表示されるまでの大まかなな流れ



# HTML,CSS,JavaScriptそれぞれの役割

**HTML:**
ページの構造を定義し、ブラウザはこれを解析してDOMツリーを構築します。

**CSS:** 
ページの見た目を定義し、ブラウザはこれを解析してCSSOMツリーを構築し、スタイルを適用します。

**JavaScript:**
ページの動作を定義し、DOMの操作やユーザーインタラクションに応じた動的な動作を実現します。

**レンダリング:**
これらの要素を統合して、ブラウザはページをレンダリングし、最終的に画面に表示します。

# 表示されるまで行われていること

**HTMLの解析とDOMツリーの構築**
* HTMLの解析:
ブラウザは、最初に受け取ったHTMLファイルの内容を解析(parse)し始めます。解析中にHTMLタグを順次処理し、各要素（タグ）をメモリ上に構築します。

* DOMツリーの構築:
HTML要素が解析されると、それに基づいてDOM（Document Object Model）ツリーが構築されます。DOMツリーは、HTMLドキュメントの階層構造を表現したもので、ブラウザがページのコンテンツを理解するために使用します。

**CSSの解析とスタイルの適用**
* CSSファイルの取得:
HTMLファイル内の`<link>`タグや`<style>`タグによって指定されたCSSファイルが、追加のHTTPリクエストを通じてサーバーからダウンロードされます。

* CSSの解析:
ブラウザはCSSファイルを解析し、各HTML要素にどのスタイルを適用するかを決定します。これにより、CSSOM（CSS Object Model）という別のツリーが構築されます。

* DOMとCSSOMの統合:
DOMツリーとCSSOMツリーが結合され、レンダーツリーが生成されます。レンダーツリーは、ブラウザがどの要素をどのように表示するかを決定するための構造です。

# JavaScriptの実行
* JavaScriptファイルの取得:
HTMLファイル内の`<script>`タグによって指定されたJavaScriptファイルが、必要に応じてサーバーからダウンロードされます。

* JavaScriptの解析と実行:
ブラウザのJavaScriptエンジンが、ダウンロードされたJavaScriptファイルを解析し、コードを実行します。
JavaScriptはDOMやCSSOMにアクセスして変更を加えることができます。

:::note info
もしJavaScriptがHTMLの解析(parse)中に実行されると、HTMLの解析(parse)が**一時停止**され、JavaScriptが完了した後に**再開**されます。

このため、`<script>`タグを適切に配置しないと、ページの表示が遅くなる可能性があります。
:::

`<script>` async / deferの差異
https://qiita.com/phanect/items/82c85ea4b8f9c373d684

# サイトの表示高速化するために気をつけること
以下の記事が参考になります。
https://baigie.me/officialblog/2019/11/26/high-speed-frontend/
写真測量と 3D スキャンを応用して 3D モデルを作成

今日のデジタル時代では、3D モデルの作成がますます重要になっています。映画やテレビの制作、ゲーム開発、あるいは建築や考古学の分野においても、3D モデルは重要な役割を果たします。写真測量と 3D スキャンは、3D モデルの作成に現在使用されている 2 つの主要なテクノロジーですが、それぞれに独自の長所と短所があり、さまざまなシナリオやニーズに適しています。

写真測量

写真測量とは何ですか?
写真測量は、2 次元画像を使用して 3 次元モデルを生成する技術です。オブジェクトの写真を複数の角度から撮影することで、写真測量ソフトウェアはオブジェクトのジオメトリとテクスチャを計算できます。

利点
費用対効果: 1 台のカメラと関連ソフトウェアだけで比較的低コスト。
携帯性: 屋外や、建物や遺跡などのアクセスできない場所での使用に適しています。
高解像度: 細かいテクスチャの詳細を生成できます。

短所
照明条件に対する高い要件: 照明の変化に敏感で、特定の時間に撮影する必要がある場合があります。
長い処理時間: 画像の処理には大量のコンピューティング リソースが必要です。

アプリケーションシナリオ
考古学: 遺跡の記録と分析に使用されます。
建築: 建物の 3 次元モデリングや歴史的建造物の保存に。
![v2-2c2c516dcff60ee98cfae6ba3423dac7_1440w.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/9f61447b-ac3e-a273-fa6b-7f622e08a2b5.png)


3Dスキャン

3Dスキャンとは何ですか?
3D スキャンでは、レーザーや構造化光などの技術を通じて物体の形状を直接測定し、3 次元の点群データを生成します。この点群データは、完全な 3D モデルにさらに処理できます。
![cf6a6aec7b0afdc434745140789fe352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/ba70e4fd-e961-c7a1-b598-6718f6e1cd54.png)

利点
高精度: 微細なディテールや複雑な形状をキャプチャできます。
高速: スキャン プロセスは通常、写真測量よりも高速です。

https://www.revopoint3d.jp/

短所
機器は高価です: プロ仕様の 3D スキャナーはより高価です。
携帯性が低い: 通常、スキャンは固定された場所で実行する必要があります。

アプリケーションシナリオ
工業デザイン: リバースエンジニアリングと品質検査用。
医療分野: 医療機器のカスタマイズや手術計画に使用されます。

適切なテクノロジーを選択する

写真測量と 3D スキャンのどちらを選択するかについては、特定のニーズに基づいてトレードオフがあります。

予算: フォトグラメトリは、予算が限られているプロジェクトに適しています。
精度: 3D スキャンは、高精度が必要な用途に適しています。
環境: 写真測量は屋外に適しており、3D スキャンは屋内の制御された環境に適しています。

写真測量と 3D スキャンには、それぞれ独自の利点と適用可能なシナリオがあります。それらの違いと応用分野を理解することは、さまざまなプロジェクトで最善の選択をし、両方のテクノロジーの可能性を最大限に活用するのに役立ちます。低コストのソリューションを追求している場合でも、高精度のモデルが必要な場合でも、どちらのテクノロジーも 3D モデリングを強力にサポートします。
Julia: Version 1.10.5 (2024-08-27)

 ```Julia             _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.5 (2024-08-27)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |
```
zshでコマンドライン操作を快適に！カスタムキーバインドの設定方法

# はじめに
コマンドライン上で操作する際に、毎回矢印キーで動かすのが面倒だったので、コマンドをカスタムしてみました。その備忘録として残しておきます。

# 設定方法
## zshrcを開く
```zsh
vi ~/.zshrc
```

## カスタムキーバインドの追加
- 単語ごとに移動するカスタムキーバインド
```zsh
bindkey '^W' forward-word
bindkey '^B' backward-word
```

- 単語ごとに削除するカスタムキーバインド
```zsh
bindkey '^D' kill-word
```

Escを押した後、: + wqで保存して閉じます

## 追加した設定を反映
```zsh
source ~/.zshrc
```

## キーバインドを確認
```zsh
bindkey
```
```
"^@" set-mark-command
"^A" beginning-of-line
"^B" backward-word
"^D" kill-word
"^E" end-of-line
"^F" forward-char
"^G" send-break
⋮
```
これでキーバインド一覧を確認することができます。
探すのが面倒であれば、grepを使えば絞り込めます。
【Swift】Swift6移行について

## はじめに
私自身Swift5でSwiftデビューしているのでSwiftのメジャーバージョンのアップデートが正直どのようなものか想像がついていません。なのでまずは4から5にアップデートがあった際は何が起きたのか遡ってみようと思います。

今回は詳細な移行方法や変更点等は調査できていないのでまた別でまとめるとします。

## Swift4 → 5では
2019年当時の記事を漁ってみました。過去の中では破壊的変更も少なく大人しめなアップデートだったようです。移行に関する情報も結構簡素ですね。

https://www.swift.org/migration-guide-swift5/

https://gihyo.jp/dev/serial/01/swift-introduction/0049

## Swift6への移行
結論、Swift5はしばらく使えそうなので現状維持も可能です。ですが生産性、安全性、保守性の観点や開発者・デバイスの体験向上の為にもSwift6へ移行していくのが良いと思います。

> Swift 6は、デベロッパの生産性とコードの明確さの向上を目的とした新しい機能を導入します。マルチコアアーキテクチャによりデバイスがよりパワフルになったように、Swiftは機能を新たに追加し続けることで、並行プログラミングをより簡単にします。Swift 6は、コンパイル時のデータ競合に対する安全策を採用し、デベロッパのプロジェクト全体でコンパイル時のメモリへの並行アクセスを診断します。このような進歩により、エラーを発見し、コードベース全体を最小限の変更で修正することで、将来のコードの安全性と保全性を強化します。

https://www.swift.org/migration/documentation/migrationguide/

Swift5のままSwift6の機能を段階的に有効にすることができます。問題があれば警告としてのみ表示され、ビルドはできるといった状態での移行も可能です。

## 参考
https://developer.apple.com/jp/videos/play/wwdc2024/10169/

https://developer.apple.com/videos/play/wwdc2024/10136/

https://www.apple.com/jp/newsroom/2024/06/apple-empowers-developers-and-fuels-innovation-with-new-tools-and-resources/


## まとめ
今回はSwift6の概要は掴めたので良しとしますが、今回の変更点を理解するにはConcurrencyやデータ競合等の技術や概念をしっかり抑えておく必要があると感じました。まずはそのあたりの理解から深めていく方が結果的に近道となりそうです。


## 最後に
私の働いている会社で経験の有無を問わず採用を行っています。
興味のある方は是非カジュアル面談から応募してみてください！

https://jambo-support.com/recruit_engineer/
Struts6.6.0はTOMCAT10では使えない

(2024年8月記載）
手短にポイントと参考URLを。
ここの記載はstackoverflowにあった質疑を元に書いています。

https://stackoverflow.com/questions/73349418/does-latest-version-6-struts2-support-tomcat-10

## ポイント１：Struts2 6.6.0はJavaEEを使うため
この文章を書いている時点でダウンロードできる最新版であるStruts2 6.6.0もJavaEEを使う。
struts-6.6.0-allを展開し、その中のapps/struts2-rest-showcase-6.6.0.warを展開するのが話は早い。WEB-INF/web.xmlに書かれている呪文はjavaeeのもの。
詳しくはバージョンノートをご確認下さい。

https://cwiki.apache.org/confluence/display/WW/Version+Notes+6.0.0

Struts2 6.6.0はServlet API 3.1が必要となっていて、これがJavaEE7に対応しているようです。
## ポイント２：TOMCAT10はJakartaEEに対応しているため
TOMCAT10からはJakarta EEになりました。classファイル中のネームスペースの差異を解消するためマイグレーションツールを出すくらいなら、もう少しなんとかしてほしかった。

https://tomcat.apache.org/index.html
## 結論：Struts2 6.6.0はTOMCAT9でご使用下さい。
Struts2 7.xはJakartaEEに対応するらしいですが、現時点では有志による確認中？の模様。
現時点では6.x.0はTOMCAT9で動かすしかなさそうです。
Eclipseのプラグインをオフラインインストールする（2024）

Eclipse Tomcat PluginをEclipseにオフラインインストールしたので手順を控えておきます。
マーケットプレイスに直接入れない環境だったのでzipをダウンロードしてから対象環境へコピーしてインストールするという手順で進めました。
## 目次
1.プラグインをダウンロードする
2.インストールする

## １．ダウンロードする
対象のマーケットプレイスのページを開きます。
今回のEclipse Tomcat Pluginだとこのような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682482/7d82f15c-4263-47be-e77c-917f5f5c3fbc.png)
ネコちゃんの左下のホームアイコンをクリックするとGitHubのページへ移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682482/e82dff5f-8638-23f2-c7ce-9a4a98a5f805.png)
「<>CODE」のボタンをクリックして「Download ZIP」を選択
zipファイルが取得できたら該当の環境へ持っていきます。
適当なフォルダでzipを展開しておきます。

## ２．インストールする
Eclipseのメニューバーから、ヘルプ(H) → 「新規ソフトウェアのインストール」を選択します。
作業対象の「追加(A)」を押し、「リポジトリーの追加」ダイアログで「ローカル(O)」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682482/ce715cc2-82fd-1cb0-a752-88aa063d6159.png)
先ほど展開したzipの中の「net.sf.eclipse.tomcat.updatesite」を選択し、「フォルダの選択」ボタンを押します。
（updatesiteフォルダは少し潜ったところにあります）
「リポジトリーの追加」ダイアログへ戻るので「追加(D)」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682482/877b5807-4ebd-20e6-6492-15774ec8ec4d.png)
使用可能なソフトウェアとしてEclipse Tomcat Management Featureが選択できます。
次へをクリックすると要件チェックが開始され、そのまま終了します。
インストール詳細に該当のプラグインが表示されていることを確認して「次へ」をクリックします。
ライセンスに承諾して次へをクリックするとインストールが行われ、再起動要求がきます。
## 最後に
今回入れたpluginはTOMCAT10には使えませんでした。
修行の日々が続きます。
（すべて1冊で身につくJavaScript）ローディング画面を作る

お疲れ様です。

今回もタイトルにあります通り、「すべて1冊で身につくJavaScript入門講座」の内容を勉強し、実践してみたものです。
JavaScriptのanimateプロパティを使ったものですが、指定できるプロパティ1つ1つの意味を理解すれば、こんなこともできるんだなーと感じた次第です:smiley:

転職目指して勉強をしているのですが、最近はアニメーションばかりな気がします…
とはいえ、他の教材を使ってみる前に、この参考書を1冊やり通してから考えようと思います！
qiita内でもたまに探しているのですが、初心者用でおすすめの勉強法がありましたら、お教えいただけますと助かります:sob:
やはりコードを書きまくることが最短でしょうか…

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvLxjJE" data-pen-title="Untitled" data-user="mtzkmy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mtzkmy/pen/wvLxjJE">
  Untitled</a> by mtzkmy (<a href="https://codepen.io/mtzkmy">@mtzkmy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

話が逸れましたが、参考書を元に作ったものが上に表示されているものです。
今回はcssの一括指定プロパティが初見でしたので、**inset, place-items** を調べるところから始まりました:computer:

調べて、使ってみての感想ですが、とても便利ですね！
place-items は今回画像を貼っていないため関係ないのでしょうが、insetはmarginの一括指定というもの魅力的だなと思いましたが、

inset: 0;
position: fixed;

の組み合わせで、画面いっぱいに広げられるという知識も学べました:relaxed:

そして一括指定ではありませんが、object-fit を使えば、画面がどんな大きさであっても表示領域にうまく合わせてくれるプロパティと知り、画像を貼りつける時は必須だなと思いました。

ローディング画面を実装すれば、配色次第でなんだかゲーム画面みたいでかっこいいページができそうです:bulb:
レビューアイで 東横イン 新宿歌舞伎町 のレビュー分析をしてみた


弊社リテジーリンクではレビュー分析AI[レビューアイ](https://reviewai.next-seed.work/)の無料デモを公開中です。
レビューアイ (英語表記 ReviewAI) は、商品・サービスのレビューを分析し、
観点ごとに強みと改善点を明らかにする、レビュー分析AIです。

本記事では、東横イン 新宿歌舞伎町のレビューを例に
レビューアイで明らかになった強みと改善点を1つずつ紹介します。

## 強み

レビューアイでレビュー分析すると、レビューでよく出てくる観点が一覧できます。
強み順に並べると、**部屋** が一番上にきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/e670627b-4053-9cf5-0041-38ba046c6f6d.png)

**部屋** の詳細を確認すると、部屋に関してどのようなレビューがあるのか可視化されます。
こちらを強み順に並べると、**清潔**、**きれい**、**広い** が上位にきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/57c55c29-f118-fd85-fb04-3f25192feff6.png)

**清潔** のレビューを見ると、感情分析した結果で整理してレビューの抜粋文が確認できます。
部屋もお風呂も清潔感があることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/c6d8322b-c675-de9e-5b7e-f6ed94a1f1ea.png)



## 改善点

レビュー分析で見つかる観点を改善順で見ると、**エレベーター** は要改善のようです。
**エレベーター** の改善については[無料デモ](https://reviewai.next-seed.work/)でぜひ詳細をご覧ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/fee9f560-ca97-985a-1f3c-f721e5d67489.png)

今回は **フロント** の詳細を紹介します。
**不足** が一番上にきています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/54aef9c4-7d53-d933-d58b-6caff391d7f8.png)

**フロント**、**不足** に関連するレビューを見ると、フロントのスタッフが不足しており、
手が回ってない様子がうかがえます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/718c333a-790f-683e-374b-713af2dc6730.png)

## まとめ

レビューアイで東横イン 新宿歌舞伎町のレビュー分析をしました。
結果として
- 部屋やお風呂に清潔感がある
- フロントのスタッフが不足している
ということが判明しました。

今回は紹介できていませんが、
- エレベーターにどうような改善要望が届いているのか
- 音に関してどのようなレビューがあるか
などについても貴重な知見があります。

[レビューアイ](https://reviewai.next-seed.work/)の無料デモを公開中です。
ぜひ[こちら](https://reviewai.next-seed.work/)からお申込みください。
ESP32-CAM FaceDetect,FaceRecognation


# 設定
* ArduinoIDE ver 1.8.10(WIN) 
* ボードマネージャー ESP32 ver2.0.4
* ボード AI-THINKER
* ソース(スケッチ例) ESP32>camera>Camerawebserver
  修正箇所　
  #define CAMERA_MODEL_AI_THINKER 及びssid,pass入れること

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/928aba3e-0db5-273a-d3c2-e1701d5c3110.png)

# 結果
URLにArduinoIDEのシリアルモニタに表示されるhttp://192.168.x.x を指定する。
顔認識の黄色枠出た時の画像、赤枠のAlert出た時の画像は撮り忘れた。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/5a289b24-be2a-aaa0-ed57-dfa825ccdea7.gif">

シリアルモニタに　黄色枠の時と赤枠で上部にAlert！と出るときある。
DETECTED -1がAlert！赤枠、つまり下段にて顔登録した顔以外の顔を検出した時である。DETECTED 0が顔検出しただけの黄色枠。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/5d96cbe3-44c4-f573-d560-d046caff373a.png">

## 顔識別テスト(Face Recognation)

1. Face Detection、Face Recognationボタンとも押した状態で顔枠を認識させる。
2. Enrol Faceボタン押すと自動的にFace ID[0]で自動的にそのまま数枚撮られていく。顔はずすと終了。
3. 登録終われば再び顔識別したらFace ID[0]と識別される、ログにも出る。

一旦Resetボタン押せば顔登録はクリアされてしまう。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/2677f136-85f0-ac29-ea49-b1d3da0f0abd.png">

顔認証、顔識別は簡易的には便利だが顔を個別登録して残しておくことは出来ないようだ。よってResetボタン押すと登録した顔が消えてしまうようである。せっかく顔登録しても消えてしまうのでは使えない。
ある表領域内の複数表の断片化をまとめて解消する方法

## はじめに

とある表の断片化を解消する際は、対象の表に対して下記のDDLを実行する必要があります。

alter table テーブル名 enable row movement;
alter table テーブル名 shrink space cascade;
alter table テーブル名 enable row movement;

STATSPACK用表領域TOOLSDAT内の表は、STATSPACKスナップショットを削除した際に
断片化してしまうことがよくある一方で、TOOLSDAT表領域内の表の一つ一つに
上記のコマンドを実行するのは面倒であるという課題がありました。

## 課題への対応策

以下のように、dba_segmentsから対象の表領域内の表名を取得し、
上記３つのalter文を一気に実行するPL/SQLを考えました。

```plsql:defragmentation.sql

whenever sqlerror exit sql.sqlcode

set echo on
set verify off
set serveroutput on
set pages 1000 lines 1000

PROMPT
ACCEPT t_owner CHAR PROMPT 'Schema:';
PROMPT
ACCEPT ts_name CHAR PROMPT 'Tablespace:';
PROMPT

spool D:\basis_scripts\log\defrag.log
DECLARE

  t_name dba_tables.table_name%TYPE;

  -- サイズの降順に上位20件のテーブル情報を取得しています。

  CURSOR objects IS
  SELECT owner, segment_name, segment_type, bytes FROM dba_segments
  WHERE owner = '&&t_owner' and tablespace_name = '&&ts_name' AND segment_type = 'TABLE'
  ORDER BY 4 DESC
  FETCH FIRST 20 ROWS ONLY;

  -- 3つのalter文を格納するための変数

  enable_rowmove varchar2(1000);
  shrink_space varchar2(1000);
  disable_rowmove varchar2(1000);

BEGIN

  FOR obj_tab IN objects LOOP

    enable_rowmove := 'ALTER TABLE ' || obj_tab.owner || '.' || obj_tab.segment_name || ' ENABLE ROW MOVEMENT';
    shrink_space := 'ALTER TABLE ' || obj_tab.owner || '.' || obj_tab.segment_name || ' SHRINK SPACE CASCADE';
    disable_rowmove := 'ALTER TABLE ' || obj_tab.owner || '.' || obj_tab.segment_name || ' DISABLE ROW MOVEMENT';
  
    EXECUTE IMMEDIATE enable_rowmove;
    EXECUTE IMMEDIATE shrink_space;
    EXECUTE IMMEDIATE disable_rowmove;

    -- このdbms_outputはexecute immediateの前に書くと出力されませんでした

    DBMS_OUTPUT.PUT_LINE(enable_rowmove);
    DBMS_OUTPUT.PUT_LINE(shrink_space);
    DBMS_OUTPUT.PUT_LINE(disable_rowmove);

  END LOOP;

END;
/
spool off

```

上記スクリプトではサイズの降順で上位20件の表だけ断片化を解消していますが、
断片化の解消が不十分である場合は何度か繰り返し実行することで
表領域の使用サイズがある値に収束していく様子が確認できます。

## おわりに

上記では実行時にスキーマや表領域名の入力を促していますが、
例えば表領域名をtoolsdatと小文字で入力すると失敗してしまいます。
改善の余地ありです。
New Relic アップデート(2024年7月)

2024年7月分のアップデートではデジタルサービスのエンドユーザー体験を観測する機能アップデートを中心に多くのアップデートが出ています！
Browserでは、ブラウザ上のユーザー操作を記録し、New Relic上で再生することでユーザー体験をより深く把握できるようになりました。


![update202407-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/15685e1f-6e5e-e44f-733b-eaad9fcfc516.png)


他のアップデートもまとめてブログでご確認ください。
↓↓↓↓↓↓

https://newrelic.com/jp/blog/nerdlog/new-relic-update-202407

- Mobile: クラッシュに至るまでのユーザー操作を分岐を含めて可視化
- Mobile: モバイルアプリの詳細ログを収集可能に
- Security: アプリケーションの脆弱性をリアルタイムに検出するIAST
- Dashboards: ダッシュボードで地域別マップを作成
- Alert: インシデントのタイトルをカスタマイズ可能に
- Errors Inbox: 未解決のエラーを把握しやすくなりました
- APM: NVIDIA NIMとのインテグレーションがリリースされました

:::note info
[New Relic株式会社のQiita Organization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::
＃38　【検証】Slackのリマインダーの日時指定はどの程度正確に入力する必要があるのか

## 概要

Slackでは `/remind [誰に(どこのチャンネルに)] [何を] [いつ] ` を入力することで、リマインダーが設定できます。
この、`[いつ]`の部分を指定する際、構文を調べてきっちりと入力していたのですが、
意外とアバウトに入力しても狙い通りに設定できることに気づいたので、どの程度までなら自動で補完してくれるのか検証してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/b7b83c6e-1557-cb19-3131-52eb38b64a20.png)


## 検証

色々な日時指定について、正しい構文を元に、どこまで変えても認識されるか検証しました。
狙い通りにリマインダーが設定されたものに〇をつけています。

### 10分後

構文: `in 10 minutes`

| 指定方法 | 説明 | 結果 |
|--|--|--|
| IN 10 MINUTES | 大文字 | 〇 |
| in 10 minute | 単数形 | 〇 |
| in 10minutes | スペース削り | 〇 |
| in10minutes | スペース削り2 | × |
| in ten minutes | 数字不使用 | 〇 |
| on 10 minutes | 前置詞ミス | × |
| 10 minutes | 前置詞削り | × |
| in 10 minites | スペルミス | × |
| 10 minutes later | 別表現 | × |
| 10分後 | 日本語 | × |

### 7時に

構文: `at 07:00am`

| 指定方法 | 説明 | 結果 |
|--|--|--|
| AT 07:00AM | 大文字 | 〇 |
| at 07:00 | am省略 | 〇 |
| at 7 o'clock | o'clock表記 | 〇 |
| at seven o'clock | 数字不使用 | 〇 |
| at 0700am | コロン削り | 〇 |
| in 07:00am | 前置詞ミス | 〇 |
| on 07:00am | 前置詞ミス2 | 〇 |
| 07:00am | 前置詞削り | 〇 |
| 7時 | 日本語 | × |

### 毎週金曜日

構文: `every Friday`

| 指定方法 | 説明 | 結果 |
|--|--|--|
| every friday | 小文字 | 〇 |
| EVERY FRIDAY | 大文字 | 〇 |
| every Fri | 省略表記 | 〇 |
| in every Friday | 前置詞つき1 | 〇 |
| on every Friday | 前置詞つき2 | 〇 |
| at every Friday | 前置詞つき3 | 〇 |
| every Fryday | スペルミス | 〇 |
| 毎週金曜日 | 日本語 | × |

### 毎月1日

構文: `on the 1st of every month`

| 指定方法 | 説明 | 結果 |
|--|--|--|
| ON THE 1ST OF EVERY MONTH | 大文字 | 〇 |
| on the first of every month | 数字不使用 | 〇 |
| in the 1st of every month | 前置詞ミス | 〇 |
| at the 1st of every month | 前置詞ミス2 | 〇 |
| the 1st of every month | 前置詞削り | 〇 |
| every month 1st | 最小限の単語羅列 | 〇 |
| every 1st | 最小限の単語羅列2 | 〇 |
| 毎月1日 | 日本語 | × |

## 結論

* 表記方法(時間、曜日の書き方等)はこだわらなくてよい
* 前置詞が正確である必要はなく省略も可、ただし〇分後を指定したい場合はinが必要
* スペルミスは補完されない
* 日本語は認識されない

かなり賢く判断してくれるので、おおよそで入力しても大体狙い通りに設定できそうです。
リピートイフダン注文、バックテスト高速化のアイデア

## リピートイフダン注文、バックテスト高速化のアイデア

### 前書き

いちおう m2j問い合わせに「しばらく公知にしないようにしましょうか？」みたいに投げて、回答で待てとも言われなかったので投稿します。なお回答はとても丁寧でした。

### 背景

マネースクエアジャパンのリピートイフダン注文 [^1] を想定しています。FXで有名ですが、最近株価指数等でのCFDも始まりました。
FXは上下がありますが、株価指数は基本的に右肩上がりなので、CFDだと塩漬け状態になりにくそうです。ワクワクしてきます。
いくつかパラメータがあるので、バックテストで試行錯誤したいです。
ナイーブに時系列シミュレーションやってもよいのですが、なんかうまいこと効率化できるんじゃないかと思いました。

[^1]: リピートイフダン注文とは、イフダン注文を自動でリピートしてくれる注文です。
イフダン注文は雑に説明すると、新規指値（この値段になったら買う）と決済（買った後この値段になったら売る）をペアにした注文です。決済はトリガ（ここまで下がったら売る＝損切）と指値（ここまで上がったら売る＝利益確定）の２種類あります。
つまり、リピートイフダン注文を行うと「ある値段になったら買い、そしてある値段になったら売る」というのを延々と繰り返してくれます。
うまいところに仕掛けられたら、頻繁に不労所得が入りますね。

### 本題

あらかじめ分析データを用意しておくことで、時系列でのシミュレーション不要でバックテストが行えます。

#### 分析データを用意する方法

①ある指値を想定します。例えば36000とします。
②tickデータ等にて、指値を下に突き抜けた（36000より大→36000以下となった）タイミングを洗い出します。
③そのタイミング間で、安値/高値を記録します。
→記録データ：指値、タイミング始点、安値、高値、タイミング終点

④その商品の最安値～最高値について、最小単位値幅ずつ指値をずらしながら、①～③を行います。

上記は買いの場合ですが、売りの場合は向きを逆にすればOKです。

#### バックテスト方法

この分析データに対して、バックテスト期間と注文内容でフィルタして、件数を集計すれば結果を得られます。
BIツールを使えば、パタパタ切り替えながら瞬時に分析ができるんじゃないでしょうか。
ロストリガ（損切）は利益確定の決済に優先します[^2]。

[^2]: ②で下に突き抜けたタイミングとしていることから、必ず安値→高値の順になります。

※トレールは対応できません。時系列シミュレーション相当が必要じゃないかと思います。

### 後書き・感想

たいてい数十か月ごとに急騰するので、利益確定値幅を大きくしたほうが利益は大きい傾向がありました。
ただし件数は減るため、定期収入みたいにしたければ ある程度値幅を狭めたほうがよさそうです。
なお公式のヒストリカルデータは日足なので、細かい利益値幅だとバックテストの漏れが多そうです。

長期では結局右肩上がりのトレンドなので、あまり具体的な金額でのバックテストは効果が薄いように思い始めました。
正規化[^3]すればよいかも？

[^3]: 分析データで、指値は長期平均との乖離率、安値/高値は指値との差や比率とするなど。