OmniAICreator/Qiita-1.07M huggingface dataset:
【ニコメア】ニコニコ動画の動画情報を取得するAPIの解説(2024年9月版)

## はじめに
この記事にてニコニコ動画に書き込まれたコメントの取得方法を紹介していました

https://qiita.com/vram/items/0b14bc800ce8fd69b70d

しかし2024年8月5日にコメントが新サーバーに移行しました
そしてこれまでコメントを取得を取得していたアプリからは取得出来なくなりました

ここでは2024年9月3日に解析した新コメントサーバーとの通信方法を解説します

## スレッド情報
コメントを取得するにはまずスレッド情報を取得する必要があります
ニコニコ動画では**sm**で始まる動画IDによって普通は管理されていますが
内部では**スレッド**とよばれるIDで管理されていますので
まずは動画IDをスレッドIDに変換する必要があります
その変換過程で動画の情報も取得できます

スレッド取得APIは以前は
```
https://www.nicovideo.jp/api/watch/v3_guest/
```
というAPIがあり、URLの後ろに動画IDを追加 例えばこの技術の紹介動画のスレッドを取得する場合は

```
https://www.nicovideo.jp/api/watch/v3_guest/sm43038967
```

おまじないとしてパラメータを追加
```
https://www.nicovideo.jp/api/watch/v3_guest/sm43038967?_frontendId=70&_frontendVersion=0&actionTrackId=
```

この後ろにランダム生成した英数字9文字と数字12文字を追加すると動画情報が取得出来ていたのですが出来なくなりました。

json形式で返してくるapiが見当たらないので動画視聴ページのHTMLを取得して解析するしか無さそうです。

```
https://www.nicovideo.jp/watch/sm43038967
```

### 取得結果
うまくいくとHTMLが取得出来ます

必要な部分だけ説明すると

```
<link href="https://resource.video.nimg.jp/web/styles/modules/navigation/common_header/common_header.css?1709186126" rel="stylesheet">
```

common_header.css?の後ろに引っ付いている 1709186126 がスレッドIDで

```
<div id="js-initial-watch-data" 
```

というタグの中に様々な情報が入ってます、一部の記号や漢字はHTML用にデコードする必要があります。

```
"threadKey":"eyJ0eXAiOiJKV1QiL・・
```

スレッドのキーとしてここの長い情報を覚えておきます

## コメントを取得する

新しいコメント取得サーバーはこちら
```
https://public.nvcomment.nicovideo.jp/v1/threads
```

アクセスしても何も返しません
実は今回からGETではなくPOSTに変わりました

POSTとしてJSON形式で大量の情報を送って一致させないと返しません
```param.json
{
  "params":{
    "targets":[
      {
        "id":"スレッドID",
        "fork":"owner"
      },
      {
        "id":"スレッドID",
        "fork":"main"
      },
      {
        "id":"スレッドID",
        "fork":"easy"
      }
    ],
    "language":"ja-jp"
  },
  "threadKey":"スレッドキー",
  "additionals":{}
}
  ```
  さきほど取得したスレッドIDとスレッドキーを置き換えたものをPOSTすると

  |  | 説明 |
|:-:|:-:|
| 57a1  |  次のデータ行のバイト数 |
| {"meta":{"status":200},"data":・・・  |  データ |
| ・・  |   |
| 0  |  データの末尾 |

この形式で返ってきます
ステータス200が返っていれば正常です

## おわりに
この説明を見ればわかる人ならすぐにコメントを取得出来るでしょう
わからない人は素直に新サーバーに対応したアプリを使って下さい

https://commons.nicovideo.jp/works/sm41065084

昔は同じようなアプリが複数の開発者によって公開されていましたが
2024/3/1現在、ついに私1人だけになってしまいました。

今使っているAPIもいつまで使えるかわかりませんが解析は続けたいと思います
ピンボールは運ゲーではない


## 最初に

私はWindowsXPに付属していたピンボールで遊んだ経験くらいしかありません。

## 回避不能な死

ピンボールをやったことがある人なら誰もがボールが左右のピョコピョコ動かせるやつにかすりもせずに穴に落ちたという経験をしたことがあると思います。

![無理なんだが.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/136ca4c2-e34e-2c88-a83a-7e8fbe0e9d33.png)

この位置に目掛けれてボールが来た時点でプレイヤーは無慈悲なボールの落下を見届けるしかできません。

そのため、私はピンボールは運ゲーだと思っていました。

## 運ゲーだが試行回数を減らせば…？

時がたち、ふとある考えが生じました。

「回避不能な死」が起こる可能性が低い場合（例えば1%くらい）、それが発生する前にゲームをクリアすればorスコアを稼げばいいのではないか？と。

:::note info
前提としてWindowsXPに付属していたピンボールは、「～にボールを当てろ」みたいなミッションがあり、それを達成するとスコアが増えたり、ストーリーが進んだりする感じのゲームでした。（うろ覚え）
この記事内でピンボールというワードがでたら、WindowsXPに付属していたピンボールのことをベースに話していると思ってください。
:::

ピンボールが下手なプレイヤーは狙った箇所にボールを当てることが出来ず全くミッションが達成できません。

これによりボールを打ち上げ、ボールが落ちるという事象が多く発生します。

つまり「回避不能な死」の抽選回数が増え、「回避不能な死」が発生する可能性が高まります。

それに対し、ピンボールが上手なプレイヤーは少ない試行回数で狙った箇所にボールを当てることができるため、順調にミッションは達成され、ストーリーも進行していきます。（ボールの個数も回復したっけ？）

つまり上手なプレイヤーは「回避不能な死」の抽選回数が少なく、「回避不能な死」が発生しにくい。ということです。

## 要するに

ピンボールは確かに「回避不能な死」がありますが、
それが発生する確率は低いため、少ない試行回数でゲームを進める必要があります。

試行回数を減らすということは、狙った箇所にボールを的確に当てる。という技術が必要であり、
これすなわち、「ピンボールは運ゲーではなく、運ゲーが発生する前にゲームをクリアする実力ゲー」と考えらます。

## ということで

運ゲーを回避するために、試行回数を減らすことに実力がいる。
というゲーム性って面白いよね！という話でした。

## 追記：さらに考えると

下手糞でも運ゲーでクリアできる道すじ（＝回避不能な死が発生しない）があるのか。なかなか興味深い。
ゼロつくDeepLearning_cp8

# はじめに

こちらは「[ゼロつくDeepLearning_cp7](https://qiita.com/ponponnsan/items/e3d4818b6ecc95e8f4d7)」の記事の続きです。

「[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585)」についてのまとめを数回に分けて行いたいと思います。

YOUTUBEでのおすすめチャンネルは以下の通り
- [ヨビノリ](https://www.youtube.com/@yobinori)
- [AIcia Solid Project](https://www.youtube.com/@AIcia_Solid)
- [3Blue1BrownJapan](https://www.youtube.com/@3Blue1BrownJapan)

# 何をまとめるのか
さて、このまとめではpythonのコードを動かしたり、何か実装するということは行いません。

ちなみに、書籍のソースコードは[こちら](https://github.com/oreilly-japan/deep-learning-from-scratch)にまとめられています。

なので1章はとばし、2章からのスタートになります。
そして6章も学習実装時のテクニックなので飛ばします。

今回は**8章**をまとめます。

引き続き個人的に重要だと思うポイントを記載したいと思います。

ついに最終章です！

## 8章 ディープラーニング 

ディープラーニングは、層を深くしたディープなニューラルネットワークです。これまで勉強してきたニューラルネットワークに層を深くしていきます。

メリットもある反面で、デメリットも見えてきています。

### ネットワークをより深く

ニューラルネットワークの層をより深くすることで、ある程度の精度は担保されていると証明されてしまいました。その代表例がGPT3をはじめとするGPTモデル、Whisper、Stable Diffusionなどです。

これらは何十、何百億というパラメータを調整し、自然なテキストや画像、音声を出力することに成功しています。

そして精度の良いモデルを支えているのが、GPUです。

### ディープラーニングの高速化

#### GPU

GPUは元々、グラフィックのための専用ボードとして利用されてきました。
しかし最近では、グラフィック処理だけでなく、並列的な数値計算にも使われています。

ディープラーニングでは、大きな行列の積を行う必要があるので、GPUはうってつけな訳です。

ですが近年はLLMの広がりとともに、GPUの枯渇が叫ばれています。
私の会社もGPUを調達しようとして厳しそうだったり、時間がすごくかかったりしています。

先日さくらインターネットがH100 8基を月額300万で貸し出すニュースがありましたね。
ついに国産クラウドが動き始めました。

またAIを受け入れられる土壌が日本にはあると言われています。すんなりとAIと共存していく道を選んでいるんですね。海外ではAIが敵だと表現されたり、まだ否定的であったりする風潮があるようです。

OpenAIが日本に支社を持つのも楽しみですね！

話がそれました、本題に戻りますね。

#### 演算精度のビット削減

ディープラーニングの高速化においては、計算量に加えてメモリ容量やバス帯域などがボトルネックになります。メモリ容量の点で言うと、大量の重みパラメータや中間データをメモリに収めることを考慮する必要があります。また、バス帯域の点では、GPUやCPUのバスを流れるデータが増加してある制限を超えるとそこがボトルネックになります。

そこで、ネットワークを流れるデータのビット数はできるだけ小さくすることが望ましいです。

コンピューターでは実数を表現するために、主に64ビットや32ビットの浮動小数点が用いられます。

計算する際の誤差は少なくなるものの、そにぶん計算量やメモリ使用量が増大し、バス帯域に負荷をかけてしまいます。

最近では膨大なパラメータを処理するため、量子化という手法でモデルを軽くしています。

量子化とは、重みなどのパラメータをより小さいビットで表現することで、モデルの軽量化を図る仕組みです。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159060/e19cfed7-9371-e46a-9dd3-c80e67e60386.png" width="500">


PyTorchやTensorFlowなどのフレームワークは、32ビット浮動小数点を用いています。
8bitの量子化であれば、1%程度の性能低下であることが報告されています。
【2024年01月版】Open vSwitch でできること 【翻訳】

# はじめに

Open vSwitch とはなんぞや？　からできることを調べます。
理解のために、公式ドキュメントを日本語に翻訳した記事です。

# Open vSwitch

[Open vSwitch](https://www.openvswitch.org/)

Open vSwitchは、オープンソースのApache 2.0ライセンスでライセンスされた、製品品質のマルチレイヤー仮想スイッチです。
標準的な管理インターフェイスとプロトコル（NetFlow、sFlow、IPFIX、RSPAN、CLI、LACP、802.1agなど）をサポートしながら、プログラムによる拡張で大規模なネットワークの自動化を可能にするように設計されています。
さらに、VMwareのvNetwork分散vswitchやCiscoのNexus 1000Vのように、複数の物理サーバーへの分散をサポートするように設計されています。

# Open vSwitch でできること

Open vSwitchは以下の機能をサポートしている。

- NetFlow、sFlow(R)、IPFIX、SPAN、RSPAN、GREトンネルミラーによるVM間通信の可視化
- LACP (IEEE 802.1AX-2008)
- 標準802.1Q VLANモデルとトランキング
- マルチキャスト・スヌーピング
- IETF 自動アタッチ SPBM および初歩的な必須 LLDP サポート
- BFDおよび802.1agリンク監視
- STP (IEEE 802.1D-1998)およびRSTP (IEEE 802.1D-2004)
- きめ細かなQoS制御
- HFSC qdiscのサポート
- VMインターフェイスごとのトラフィックポリシング
- ソース-MACロードバランシング、アクティブバックアップ、L4ハッシングによるNICボンディング
- OpenFlowプロトコルのサポート（仮想化のための多くの拡張を含む）
- IPv6サポート
- 複数のトンネリングプロトコル（GRE、VXLAN、STT、Geneve、IPsec対応）
- CおよびPythonバインディングによるリモート・コンフィギュレーション・プロトコル
- カーネルおよびユーザースペースのフォワーディングエンジンオプション
- フローキャッシングエンジンを備えたマルチテーブル転送パイプライン
- 新しいソフトウェアやハードウェア・プラットフォームへの移植を容易にするフォワーディング・レイヤーの抽象化

# Open vSwitcとは？

## 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/87d0a5df-267f-82db-027a-dd33e53633db.png)

Open vSwitchは、オープンソースApache 2ライセンスの下でライセンスされている多層ソフトウェアスイッチです。
私たちの目標は、標準的な管理インターフェースをサポートし、転送機能をプログラム的な拡張と制御に開放する、生産品質のスイッチプラットフォームを実装することです。

Open vSwitchは、VM環境で仮想スイッチとして機能するのに適しています。
仮想ネットワーキング層に標準の制御および可視性インターフェースを公開するだけでなく、複数の物理サーバー間での分散をサポートするように設計されています。
Open vSwitchは、KVMやVirtualBoxを含む複数のLinuxベースの仮想化技術をサポートしています。

コードの大部分はプラットフォームに依存しないCで書かれており、他の環境に容易に移植できます。
Open vSwitchの現在のリリースは、以下の機能をサポートしています：

- 標準802.1Q VLANモデル、トランクおよびアクセスポート
- 上流スイッチにLACPの有無にかかわらないNICボンディング
- NetFlow、sFlow(R)、ミラーリングによる可視性の向上
- QoS（Quality of Service）設定、およびポリシング
- Geneve、GRE、VXLAN、STT、ERSPAN、GTP-U、SRv6、Bareudp、LISPトンネリング
- 802.1agコネクティビティフォルト管理
- OpenFlow 1.0および多数の拡張機能
- CおよびPythonバインディングを備えたトランザクショナル構成データベース
- Linuxカーネルモジュールを使用した高性能転送

Open vSwitchは、カーネルモジュールの助けを借りずに、完全にユーザースペースで動作することもできます。
このユーザースペース実装は、カーネルベースのスイッチよりも移植が容易であるべきです。
ユーザースペースのOVSは、LinuxまたはDPDKデバイスにアクセスできます。

:::note warn
注：ユーザースペースデータパスと非DPDKデバイスを備えたOpen vSwitchは実験的とされ、パフォーマンスのコストが伴います。
:::

## 何があるのか？

このディストリビューションの主なコンポーネントは以下の通りです：

- ovs-vswitchd、フローベースのスイッチングを行うデーモンと、それに付随するLinuxカーネルモジュール
- ovsdb-server、ovs-vswitchdがその設定を取得するために問い合わせる軽量データベースサーバー
- ovs-dpctl、スイッチのカーネルモジュールを設定するためのツール
- Red Hat Enterprise Linux用のRPMやUbuntu/Debian用のdebパッケージをビルドするためのスクリプトと仕様
- ovs-vsctl、ovs-vswitchdの設定を照会および更新するためのユーティリティ
- ovs-appctl、実行中のOpen vSwitchデーモンにコマンドを送信するユーティリティ

Open vSwitchはいくつかのツールも提供しています：

- ovs-ofctl、OpenFlowスイッチおよびコントローラーを照会および制御するためのユーティリティ
- ovs-pki、OpenFlowスイッチの公開鍵インフラを作成および管理するためのユーティリティ
- ovs-testcontroller、テスト用に便利なシンプルなOpenFlowコントローラー（ただし、本番用ではありません）
- OpenFlowメッセージを解析することを可能にするtcpdumpへのパッチ

# さいごに

次は触りたい

# 関連リンク

[Open vSwitch](https://www.openvswitch.org/)
[Open vSwitch - Getting Started](https://docs.openvswitch.org/en/latest/intro/)
[Wikipedia - Open vSwitch](https://ja.wikipedia.org/wiki/Open_vSwitch)
PlatformIO@ESP32 個人メモ

# platformIO.ini 関連

https://magnolia-tech.jp/platformio_esp-idf_version_set/

https://waregawa-log.hatenablog.com/entry/2021/01/07/141853

https://note.com/masuidrive/n/n1fd9304ca58a

platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
[SwiftUI] 複数のアラートを管理する方法

# はじめに
SwiftUIを使用してアプリを開発していると、1つのViewで複数のアラートを表示するとデータが上書きされ、1つのアラートしか表示されなくなります。この問題を対処する方法はいくつかあるみたいですが、今回はアラートの種類をenumで管理する方法を紹介します。

# 目次
1. [失敗例](#失敗例)
1. [成功例](#成功例)
1. [さいごに](#さいごに)
1. [参考文献](#reference)

<a id="#失敗例"></a>
# 失敗例
この失敗例では、@Stateを使用してアラートの表示状態を管理していますが、複数のアラートが同時に表示されるとデータが上書きされ、期待した動作になりません。
```swift
import SwiftUI

struct SampleView: View {
    // エラーアラートの表示状態を監視
    @State private var showErrorAlert = false
    // 成功アラートの表示状態を監視
    @State private var showSuccessAlert = false

    var body: some View {
        VStack(spacing: 50) {
            Text("失敗例")
            Button("エラーアラートを表示") {
                self.showErrorAlert = true
            }
            Button("成功アラートを表示") {
                self.showSuccessAlert = true
            }
        }
        // このアラートは表示されない(下のアラートに上書きされるため)
        .alert(isPresented: $showErrorAlert) {
            Alert(title: Text("エラー"), message: Text("何か問題が発生しました。"), dismissButton: .default(Text("OK")))
        }
        // このアラートは表示される
        .alert(isPresented: $showSuccessAlert) {
            Alert(title: Text("成功"), message: Text("操作が正常に完了しました。"), dismissButton: .default(Text("OK")))
        }
    }
}
```
![RPReplay_Final1706508354.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530812/76f086e1-d9c8-83b2-6574-2c9514b22281.gif)

<a id="#成功例"></a>
# 成功例
enumを使用してアラートの種類を管理し、それに基づいてアラートを表示しています。これにより、複数のアラートを独立して管理することができ、データの上書きを防ぐことができます。
```swift
import SwiftUI

// アラートの種類を表すenum
enum AlertType: Identifiable {
    case error
    case success
    var id: AlertType { self }
}

struct SampleView: View {
    @State private var currentAlert: AlertType?

    var body: some View {
        VStack(spacing: 50) {
            Text("成功例")
            Button("エラーアラートを表示") {
                self.currentAlert = .error
            }
            Button("成功アラートを表示") {
                self.currentAlert = .success
            }
        }
        // アラートのモディファイアを1つにすることでどちらも表示される
        .alert(item: $currentAlert) { alertType in
            switch alertType {
            case .error:
                return Alert(title: Text("エラー"), message: Text("何か問題が発生しました。"), dismissButton: .default(Text("OK")))
            case .success:
                return Alert(title: Text("成功"), message: Text("操作が正常に完了しました。"), dismissButton: .default(Text("OK")))
            }
        }
    }
}
```
![RPReplay_Final1706508300.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530812/6d895796-ef53-54d9-58af-e1f78d24d0f6.gif)

<a id="#さいごに"></a>
# さいごに
今回は複数のアラートをenumで管理する方法を紹介しました。
このやり方の他にはViewModifierにタイプとそれに応じたアラートの挙動を定義し、ViewからはそのViewModifierを呼び出せば良いようにする方法もあるみたいですね！

<a id="#reference"></a>
# 参考文献
- [[SwiftUI]複数のアラートを表示させる](https://zenn.dev/spyc/articles/993fb47a1d42e8)
Next.jsでのonClickイベントが発火しない問題の解決


# 起きたこと
Next.jsでApp Routerを使用していた際に、カスタムしたbuttonコンポーネントでonClickが発火せず、ターミナルには以下のエラーがはかれていた。
`Uncaught Error: invariant expected app router to be mounted at useRouter`

問題のファイルがこちら↓
```tsx: src/app/layout.tsx (間違えてます)
import type { Metadata } from "next";
import "../assets/styles/reset.scss";
import "../assets/styles/variable.scss";
import { Layout } from "@/components/Templates/Layout";
export const metadata: Metadata = {
  title: "Study Tracker Next",
  description: "Generated by create next app",
};
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <Layout>{children}</Layout>
    </html>
  );
}
```


# 原因

原因はapp/layout.tsxに本来必要なはずのbodyが抜けていたため、正常にhtmlの機能が使えていなかったようだ。

# これで解決した
以下のようにhtmlタグ内にbodyタグを追加すると正常に動作した。
```tsx: diff 
- <Layout>{children}</Layout>
+    <body>
+     <Layout>{children}</Layout>
+    </body>
```

# まとめ
App Routerでプロジェクトをセットアップするとデフォルトでbodyタグ無しのlayout.tsxが作成されるので、bodyタグの追加はすぐにやっておくことをおすすめします。
Next.jsとstripeで決済機能を実装しよう！①環境構築編

# 概要
Next.js(App routor)と決済サービスのstripeを使って簡単な決済機能を実装する流れを数回に分けて書いていきます！

# stripeのアカウントの作成
https://dashboard.stripe.com/register?locale=ja-JP


# Next.jsの環境構築

Next.jsのプロジェクトを作成
```
npx create-next-app@latest
```

npm run devコマンドを実行すると上記で作成したnext.jsのプロジェクトがローカル上で起動します。
```
npm run dev
```

https://nextjs.org/docs/getting-started/installation

# stripe用のライブラリをインストール

```
npm install stripe
```
https://www.npmjs.com/package/stripe


# シークレットキーの設定
stripeの管理画面に記載してあるシークレットキーをenv.localに記載

## シークレットキーの記載場所
stripeの管理画面の右上の「開発者」をクリック
![ホーム_–_hipokuratesu_business_site_–_Stripe__テスト_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551272/f5c6d07b-86b5-9b00-e4b5-8e31928679a1.png)

「APIキー」タブに記載
![開発者_–_hipokuratesu_business_site_–_Stripe__テスト_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551272/dbd3f155-1c66-ca97-a5de-923dbb38900f.png)


```env.local
STRIPE_SECRET_KEY='ここに上記のシークレットキーを記載'
```

※stripeの管理画面ではテスト環境で実施した方が良いかと思います。

次回は実際にコードを書いていきますのでお楽しみに！
Elastic BeanstalkとCloudFormationの違い。

# Elastic BeanstalkとCloudFormationの違いを超簡単に紹介
こんにちは
AWSのSAA資格受験に向け勉強中に、よく出てきていたサービスの1つの
Elastic BeanstalkとCloudFormationの違いについて、今回は記事を書かせていただきます。
僕もサービスの違いをしっかり理解するまでは、間違えまくっていた2つのサービスなので
少しでも皆さんのお力になれれば嬉しいです！

# AWS Elastic Beanstalk: とってもお手軽にアプリケーションデプロイできるよー！ってサービス

**AWS Elastic Beanstalk**は、アプリケーションのデプロイや管理が簡単にできるサービスで、アプリケーションが動作する定番の構成を提供します。
アプリケーションのデプロイやスケーリングなどの面倒な作業を自動化し、開発者がコードの開発に重点を置けるようになります。ブラウザ上で画面をポチポチってするだけで、構成できちゃうお手軽サービス！！

## SAA試験で抑えておくべき特徴:

1. **自動設定:** Elastic Beanstalkによって用意されている定番構成の中からアプリケーションの実行環境に適したものを選んで数クリックするだけで、環境（インフラ）を作成することができます。

2. **プリセット環境:** 複数のプリセット環境が提供され、開発、ステージング、本番環境などを簡単に切り替えられます。

3. **自動スケーリング:** トラフィックの増減に応じて、自動的にインフラをスケーリングできます。関連する各種AWSサービス（ELBやS3、Auto Scalingグループなど）が設定済みのため、構築がとっても簡単。

# AWS CloudFormation: インフラ構成をコード化でき、より複雑な設定もできる！

**AWS CloudFormation**は、インフラストラクチャをコードとして扱うためのサービスです。

## SAA試験で抑えておくべき特徴:

1. **インフラストラクチャのコード:** CloudFormationでは、AWSリソースの構成をテキストで書いたテンプレートとして管理します。JSON・YAMLというデータ定義言語でAWSリソースの設定をコード化し、プロビジョニング（構築）します。

2. **再利用性:** テンプレートを使えば、同じ構成を何度も再利用できます。複数のAWSアカウントもしくは複数のリージョンで構築したい場合には「スタックセット（StackSets）」を利用し、一度の操作で複数の同じ環境を構築できます。

3. **トラックできる変更:** テンプレートの変更はバージョン管理できます。

# まとめ:

**Elastic Beanstalk**は手軽にアプリケーションをデプロイ・管理できるサービス。インフラの知見が無い場合などにもオススメ！
**CloudFormation**はインフラストラクチャをコードとして扱え、より複雑な設定や、同じ環境を再利用したい場合などにオススメ！

色々説明しましたが、ざっくりは上記のようなイメージで理解していただければ、問題ないかと思います！
最後まで読んでいただきありがとうございました！
PythonでOCR（テキスト検出）

# かんたんにテキスト検出

![2a173197-7beb-4840-b095-5e7d7c0e14c6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ba10e89c-c032-fce5-4a33-98f6381ef01d.jpeg)

# 手順 

### インストール

```shell
pip install easyocr
```

### 実行

```python
import easyocr

image_path = 'texts.jpg'

reader = easyocr.Reader(['en']) # this needs to run only once to load the model into memory

results = reader.readtext(image_path)
```

これだけ。

結果は
[xyxy座標, テキスト, 信頼度]

>[([[1242, 3507], [2285, 3507], [2285, 4207], [1242, 4207]],
  '10',
  0.9998860368237108),
 ([[1201, 4275], [2261, 4275], [2261, 4738], [1201, 4738]],
  'kmlh',
  0.9946403503417969)]


使用可能な言語は以下で、二つ以上の言語を同時検出できる。

```
Language	Code Name
Abaza	abq
Adyghe	ady
Afrikaans	af
Angika	ang
Arabic	ar
Assamese	as
Avar	ava
Azerbaijani	az
Belarusian	be
Bulgarian	bg
Bihari	bh
Bhojpuri	bho
Bengali	bn
Bosnian	bs
Simplified Chinese	ch_sim
Traditional Chinese	ch_tra
Chechen	che
Czech	cs
Welsh	cy
Danish	da
Dargwa	dar
German	de
English	en
Spanish	es
Estonian	et
Persian (Farsi)	fa
French	fr
Irish	ga
Goan Konkani	gom
Hindi	hi
Croatian	hr
Hungarian	hu
Indonesian	id
Ingush	inh
Icelandic	is
Italian	it
Japanese	ja
Kabardian	kbd
Kannada	kn
Korean	ko
Kurdish	ku
Latin	la
Lak	lbe
Lezghian	lez
Lithuanian	lt
Latvian	lv
Magahi	mah
Maithili	mai
Maori	mi
Mongolian	mn
Marathi	mr
Malay	ms
Maltese	mt
Nepali	ne
Newari	new
Dutch	nl
Norwegian	no
Occitan	oc
Pali	pi
Polish	pl
Portuguese	pt
Romanian	ro
Russian	ru
Serbian (cyrillic)	rs_cyrillic
Serbian (latin)	rs_latin
Nagpuri	sck
Slovak	sk
Slovenian	sl
Albanian	sq
Swedish	sv
Swahili	sw
Tamil	ta
Tabassaran	tab
Telugu	te
Thai	th
Tajik	tjk
Tagalog	tl
Turkish	tr
Uyghur	ug
Ukranian	uk
Urdu	ur
Uzbek	uz
Vietnamese	vi
```

CPUでも実行できるが、GPUの方が速い。

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[X](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
STM32C011で800KHzを作る(レジ直)(STM32C011J4M7)


目的
WS2812Bを光らせる為に800KHzを作る
カウンターを使い調整する


![o_cop909.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a566034f-42f0-18f7-e7a1-0bcdcabea04c.jpeg)



プログラム


```c++



//800KHzを作る
//GPIO_800KHz_C011_1


//定義
//レジ直PA8の定義
//                        1111110000000000
//                        5432109876543210
int on1  = GPIOA->ODR | 0b0000000100000000;
int off1 = GPIOA->ODR & 0b1111111011111111;


//プロトタイプ宣言
void bit_on1();


//初期化
void setup() {

  //ピンの初期化 PA8
  pinMode(PA8, OUTPUT);

} //setup


//メインループ
void loop() {

  LOOP_1:

  //PA8をオンオフ
  bit_on1();

  goto LOOP_1;

} //loop


// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;

    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;
    GPIOA->ODR = on1;

    GPIOA->ODR = on1;
    GPIOA->ODR = on1;


    GPIOA->ODR = off1;

    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
    GPIOA->ODR = off1;
}//1us



```
Docker 設定 (for Winodws10) 

## Windows 設定
[Windowsの機能の有効化または無効化]の設定で以下をチェック
- Linux 用 Windows サブシステム
- 仮想マシンプラットフォーム
変更を適用してPCを再起動

x64マシン用WSL2 Linuxカーネル更新用プログラムパッケージをインストール
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

`Docker Desktop`を[ココ](https://www.docker.com/products/docker-desktop/)からダウンロード
`Use WSL2 instead of Hyper-V(recommended)`にチェックを入れたままOKでインストール

## サンプルプロジェクトを動かす
[ココ](https://github.com/docker/welcome-to-docker)からサンプルを持ってくる
```
git clone https://github.com/docker/welcome-to-docker.git
```

`Dockerfile`からDockerイメージを作成
```
cd welcome-to-docker
docker build -t welcome-to-docker .
```

コンテナを起動
```
docker run -d -p 8088:3000 --name welcome-to-docker welcome-to-docker
```

## 各種コマンドについて
`docker build`
DockerfileからDockerイメージを作成するために使用

`-t welcome-to-docker`
-t オプションは、作成されるイメージにタグ（名前）を付けるために使用
この場合、「welcome-to-docker」という名前が新しく作成されるイメージに付けられる

`.`
最後の . はビルドコンテキストの場所を指定

ここでは、現在のディレクトリ（.）がビルドコンテキストとして指定される。
ビルドコンテキストとは、DockerfileとともにDockerデーモンに送られるファイルやディレクトリのこと

## Reference
- [Windows Subsystem for Linux に関するドキュメント](https://learn.microsoft.com/ja-jp/windows/wsl/)
- [Docker](https://www.docker.com/)
- [welcome-to-docker](https://github.com/docker/welcome-to-docker)
1ヶ月で基本情報に合格した話【新形式】

## はじめに

今更ながら、先日エンジニアの登竜門である**基本情報技術者試験**を受けて合格したので
学習手順や使用した教材、どういったスケジュール感で試験当日まで望んだか
まとめようと思います。

### 取得したきっかけ

自社でコンピュータの構成と設計（通称パタヘネ本)の輪読会が行われた際に、
非情報系である自分にとって**コンピュータサイエンスの知識が不足している**と気づき危機感を感じました。

そこで基礎知識を網羅的に身につけるために基本情報技術者試験を受験
することにしました。

## 基本情報技術者試験とは?

IT 基礎力を問う試験であり、IT エンジニアの登竜門的な試験です。
ベーシックな IT 知識を幅広く学ぶことができるのがメリットです。

|        | 試験時間 | 出題数 | 解答数 | 出題形式   | 合格基準                  |
| ------ | -------- | ------ | ------ | ---------- | ------------------------- |
| 科目 A | 90 分    | 60 問  | 60 問  | 四肢択一式 | 1000 点満点中、600 点以上 |
| 科目 B | 90 分    | 20 問  | 20 問  | 他肢択一式 | 1000 点満点中、600 点以上 |

https://www.ipa.go.jp/shiken/kubun/fe.html

## 勉強時間

基本的に平日 1 日 1.5 時間で休日は 3 時間ほど勉強しました。
テスト直前は年始だったこともあり、正月期間は 1 日 4-5 時間ほど学習して
合計勉強時間は計 60-70 時間ほどです。

## 学習スケジュールについて

1 週目:科目 A の教材を何でもいいので 1 周する
2 週目:科目 A の過去問を解きつつ、科目 B にも着手
3 週目:科目 B の教材を終わらせて、A・B の過去問両方行う
4 週目:科目 A・B の過去問をとにかく解きまくる

### 1 週目

1週目が自分にとって一番しんどっかたかもしれません。
過去問を解くにしても必要最低限の知識が必要なため、
最初に科目 A の教材を 1 周やりましょう。

こちらは、完璧に理解する必要はなく、分からない箇所は
過去問を解く際に再度読んで理解するという形で大丈夫です。

### 2 週目

2 週目は科目 A の過去問を解きつつ、科目 B にも着手します。
科目 A の過去問については、とにかく量を解くことが重要になります。

参考書で得た何となくの知識を、過去問を解くことで
定着されることができます。

### 3 週目

3 週目は科目 B の教材を終わらせて、A・B の過去問両方行います。
科目 A に関してはとにかく量をこなすことが重要と書きましたが、
科目 B に関しては 1 つ 1 つの問題を理解することが重要になります。

また、科目Bに関してはYouTubeに解説動画があるので、
理解できないものは動画を見て理解していきましょう。

### 4 週目

最後の総仕上げです。
ここまで来たら、あとは過去問を解きまくるだけです。

IPAの公開問題があるので、そちらで力試しをしてみましょう。
初見の公開問題で7割以上取れるようになれば、かなり合格に近づいていると思います。

https://www.ipa.go.jp/shiken/mondai-kaiotu/sg_fe/koukai/2023r05.html

また、過去問の問題の解く量についてですが自分は5年分 ＋ 公開・サンプル問題を解きました

## 教材・学習サイト

科目 A

https://www.sbcr.jp/product/4815624262/

科目 B

https://www.shoeisha.co.jp/book/detail/9784798182520


過去問道場

https://www.fe-siken.com/fekakomon.php

基本情報サンプル問題(公式 科目B)

https://www.ipa.go.jp/shiken/syllabus/henkou/2022/ssf7ph000000h5tb-att/fe_kamoku_b_set_sample_qs.pdf

科目B 解説動画

https://www.youtube.com/watch?v=9fU2HlAXTiM

## 最後に
実務経験の有無や情報系の学部出身かどうかで、必要な勉強時間は変わってくると思いますが、
対策さえしっかりすれば、合格は難しくないと思います。

科目Aについては,とにかく**過去問の量**解く。
科目Bについては、とにかく1問1問理解をして**質を意識して解く**ことが合格の鍵になると思います。

業務内での会話でも、IT基礎力があると話がスムーズに進みますし
学生さんでも日常生活でもITに関する知識があると、よりITに興味を持つことができると思います。

今回の記事が少しでも参考になれば幸いです。
Swift Packageの作り方

# 手順
##### GitHub でリポジトリを作成
![スクリーンショット 2024-01-30 3.40.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/3832c9cd-68c0-5873-59e6-f5b489737ba2.png)
##### ローカルでディレクトリを作成

```shell
mkdir avplayerview
```

##### ディレクトリに移動、パッケージを初期化

```shell
cd avplayerview
swift package init --type library
```

##### Sources にコードを追加

**パッケージの外から使いたい class や func は public にする必要がある**

```swift
public class AVPlayerView: UIView {
    public func play() {
...
```

##### Package.swift にミニマム iOS バージョンを追加

```swift:Package.swift
let package = Package(
    name: "avplayerview",
    platforms: [
        .iOS(.v13) 
    ],
```

##### リソースを追加する場合は Package.swift に記載

```swift:Package.swift
    targets: [
        // Targets are the basic building blocks of a package, defining a module or a test suite.
        // Targets can depend on other targets in this package and products from dependencies.
        .target(
            name: "SwiftAnimeGANv2",
            resources: [
            .process("animeganHayao.mlmodelc")]
    ),
```

##### ディレクトリのリモートに GitHub リポジトリを登録

```shell
git init
git add .
git commit -m "initial commit"
git remote add origin https://github.com/john-rocky/AVPlayerView.git
git push origin main
```

##### ReadMe を書く

これで完成。

# オプション

##### サンプルコードを追加する
Xcodeでプロジェクトを作って、add package dependency で作ったパッケージを追加。

```swift
import avplayerview
```

Swift Package のディレクトリに Xcode Project を含むディレクトリのトップ階層のファイルとフォルダをコピー（こうすることで、Open with xcode ボタンから開ける）。 

![スクリーンショット 2024-01-30 5.27.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f552e661-3edc-d6c3-bb6b-cc6b4351054f.png)


<img src=https://private-user-images.githubusercontent.com/23278992/301338307-0ff05539-bf07-41ba-b428-380c70f0e054.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDY5OTY4NzksIm5iZiI6MTcwNjk5NjU3OSwicGF0aCI6Ii8yMzI3ODk5Mi8zMDEzMzgzMDctMGZmMDU1MzktYmYwNy00MWJhLWI0MjgtMzgwYzcwZjBlMDU0LmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAyMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMjAzVDIxNDI1OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNhNWE0MmYwNWJiOWY2MzAwN2NjYjdiNWU1NjM0ZjQyOTQ5YzlhZWFlYmM5MWZhY2U1OWYyNzA3MDNmN2I3ZTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.Ux_dbT5UuUfyJ6o5oJBhGxzAikYflgPELHThBDRMSnY>


🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[X](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
2024/1/30主にITとかセキュリティの記事

「なりすまし防止」導入拡大　不審メールに対策
花王や資生堂、自動で検知(1/28)
https://www.nikkei.com/article/DGKKZO78023750X20C24A1EA5000/

OWASP API Security Risks Top 10を眺める(BOLA編)(1/28)
https://qiita.com/NaotoCoding/items/0cbb50d05994ac5c4b10

使うのは純正「プレビュー」ソフトだけ！ PDFにパスワードを設定するには【Macの“知っトク”便利技】(1/28)
https://getnavi.jp/digital/938225/

	
神奈川では高校入試の「出願手続き」に影響も...Gmailユーザーが知っておきたい「3つのリスク」(1/27)
https://gunosy.com/articles/eNPsf

Apple、EUのデジタル市場法に準拠するためiOSやApp Storeの変更発表(1/28)
https://www.zaikei.co.jp/article/20240128/755480.html

ランサムウェアの被害が後を絶たない理由(1/28)
https://gunosy.com/articles/eNzNf

ビットコインをクジラが安値で拾う／グレイスケールからさらに15億ドル流出か【Weekly Review：1/20〜1/26】
https://www.coindeskjapan.com/217667/

生成AIの危うい未来──分散型AIを提唱した暗号資産コミュニティ【ダボス会議】(1/28)
https://www.coindeskjapan.com/217215/

バリデーターの8%をダウンさせたバグ──イーサリアム、大規模な障害の懸念と小さな希望(1/28)
https://www.coindeskjapan.com/217064/

「マイナ保険証」に地方から異論　全国１１０議会が意見書可決(1/27)
https://www.sanyonews.jp/article/1508324/

サイバー演習に120組織が参加
現実さながらの緊迫した攻撃シナリオ　現行BCPに限界感じる参加者も(1/29)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800012/011900235/

事例に見る「あなたもこうしてだまされる」
2024年も続くサイバー攻撃者の生成AI悪用(1/29)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800013/011800073/

パスワードの定期的な変更は推奨せず、強度低下や使い回しのリスクが高まる(1/29)
https://xtech.nikkei.com/atcl/nxt/column/18/02676/120500017/
OpenSSL3.2.0のバージョンの不一致でsshできない問題


M1 MacでOSを `version: 14.3` にアップデートしたところ
gitのpullやpushなどが下記エラーでできない状態で詰まった...

## :warning:  エラー内容

```
OpenSSL version mismatch. Built against 30100010, you have 30200000
fatal: Could not read from remote repository.
```

下記のバージョン環境でOpenSSLのバージョンミスマッチが起きてSSHできなくなっているらしい。（現時点の最新）

```
$ openssl --version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

$ git --version
git version 2.43.0
```


## :rocket: 解決

sshコマンドのパスを確認
```
$ which ssh
/opt/homebrew/bin/ssh
```

SSHのパスを移動したら正常にSSHができるようになった。
```
$ sudo mv /opt/homebrew/bin/ssh /usr/local/bin/ssh-apple
```



### 参考になった記事
https://youtu.be/KLtA9IdeEZg?si=kU2poVGTRdgkZbO5
Pythonスクリプトを複数ディレクトリにループで実行する

親ディレクトリの子ディレクトリ全てについて、
```shell
python detect.py --source {子ディレクトリ}
```
を実行する例。


```python
import os
import subprocess

script_name = 'detect.py'

parent_directory = "datasets/"
# ディレクトリを走査
for dirpath, dirnames, _ in os.walk(parent_directory):
    for dirname in dirnames:
        # 完全なディレクトリパス
        full_dir_path = os.path.join(dirpath, dirname)
        
        # スクリプトを引数と共に実行
        result = subprocess.run(['python', 'detect.py', '--source', full_dir_path],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               text=True
                               )
        print(result.stdout)
        print(result.stderr)
    # 1階層のみ走査
    break
```

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[X](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
PHP ぼやき日記 2024-01-30

- [次回](https://qiita.com/sj-i/items/6cce387ebf2c244e8ed6)
- [前回](https://qiita.com/sj-i/items/4218804e1cd7f41fc4b0)

不定期に誰に向けるでもなく PHP に関する雑な殴り書きをしている。気がつけば 1 度も投稿することなく 1 月が終わろうとしていたくらいの雑さ加減。

# phpy がまあまあ熱心に更新されている
- https://github.com/swoole/phpy
- phpy は swoole の人が作った PHP の C 拡張
- CPython の VM をそのまま埋め込み、PHP 側と Python 側で相互にコードを呼び出せるよう橋渡しをしている
- つまり同じプロセス内に PHP と Python 両方の公式 VM を同居させるということ
- [wxPython](https://github.com/swoole/phpy/blob/main/examples/wxPython/hello.php) で GUI アプリも書けるし
- [torch だの transformers だのをインポートして今をときめく LLM を読み込む感じのコード](https://github.com/swoole/phpy/blob/main/examples/chatglm/cli_demo.php)も書ける
- パッと見だとキテレツなキワモノに見えるものの、ありのままの公式処理系 2 つを薄いブリッジで橋渡すような作りに近いので実はかなり堅い作りと思う
- queue とかプロセス間通信の仕組みで下手に PHP 側と Python 側をきっちり分離しながら作ろうとするより、ほとんどの場合にお手軽でかつちゃんと機能しやすい仕組みになるんでなかろうか
- PyDict を Python コードで読み書きするより PHP 側で読み書きする方が速いというのが笑いどころ
- [phpcondo でも喋った](https://fortee.jp/phpcon-hokkaido-2024/proposal/cc682a76-153c-41dc-95af-062b42066b42) のだけど、こっちの日記には書いたつもりでまだ書いてなかった

# NativePHP の 2024 年の抱負
- https://github.com/NativePHP/laravel/discussions/248
- Tauri サポートしてかつ Web サーバ依存をなくそうとしているらしい

# 闇 PHP 勉強会的な何かの気配
- https://github.com/hachiojipm/ya8-2024/discussions/16
- [ya8](https://hachiojipm.connpass.com/event/304403/) で[闇 PHP](https://yamiphp.connpass.com/) っぽい何かが行われるのではないかという気配がある
- 東京だと土日でフラっと子供連れて遊びに行けなくもないので、行きたい気もする

# Psalm でプロセスあたり 5GB とか 8GB とかメモリ使うのを 2.5GB くらいで済むようにした
- https://github.com/vimeo/psalm/issues/10522#issuecomment-1881729504
- [Reli](https://github.com/reliforp/reli-prof) のメモリ解析機能を使ったメモリ問題辻斬り妖怪プレイの 3 つ目
    - [前回は PhpSpreadsheet](https://qiita.com/sj-i/items/4218804e1cd7f41fc4b0#oss-%E3%81%A7-memory_limit-%E8%B6%85%E9%81%8E%E3%81%AE-issue-%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%81%A6%E3%81%AF%E6%80%A5%E3%81%AB%E3%83%A1%E3%83%A2%E3%83%AA%E8%A8%88%E6%B8%AC%E3%82%92%E3%81%A8%E3%81%A3%E3%81%A6%E5%8E%BB%E3%81%A3%E3%81%A6%E3%81%84%E3%81%8F-php-%E7%95%8C%E3%81%AE%E5%A6%96%E6%80%AA%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AE%E6%B4%BB%E5%8B%95%E3%82%82%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E3%81%97%E3%81%9F)
- PHP で特定のキーのセットで複数の値を持つようなものを作る場合、ほぼ常に配列よりオブジェクトの方がメモリ効率が良い
    - 連想配列では最低 8 要素分の bucket 領域（1 つ 32 byte なので 256 byte）とハッシュテーブル用領域（要素数の倍の数の 4byte int 領域なので 64 byte）がアロケーションされ、埋まると 2 倍ずつ領域が伸長されるので領域を余分に確保しがちで、またヘッダ的な領域でも 56 byte を食うため、計 376 byte が必要。要素数が増える際のサイズ増加も激しい。
    - オブジェクトではヘッダ的な領域が 40 バイトあり、その後続領域へ zval の配列が宣言済みプロパティの数だけ続くので、プロパティがなければその 40 バイトだけ、1 つあっても 16 byte 足して 56 byte のみ。
- 連想配列では各インスタンスがキーと値を紐付けるハッシュテーブルを持つ必要があるのに対し、オブジェクトの場合はクラス情報側へプロパティ名とインスタンス領域のオフセットを紐付けるハッシュテーブルを 1 つ持つだけで済むので、このような効率差が出る
- 一方、オブジェクトでも動的プロパティを使おうとするとインスタンスごとに宣言済みプロパティすべてを含むハッシュテーブルが必要になってしまうため、実質的にオブジェクトの領域 + 配列領域のサイズになってメモリ効率が最悪になる
- この動的プロパティテーブルは `\unserialize()` で生成されたオブジェクトには動的プロパティを実際には使ってなくとも必ず付いてきてしまうので、並列処理プロセスとの IPC やキャッシュにシリアライズを使う Psalm でめちゃくちゃ大きな差になっていた
- わりと笑えることに、`__unserialize()` を実装したクラスではこの動的プロパティテーブルの生成が処理系内でバイパスされるので、必要なあたりに `__unserialize()` を付けてまわってデフォルトシリアライズ方式でのメモリ消費量を軽くした
- 本当は igbinary だと interning でデフォルトシリアライズ方式よりメモリ消費を削れる部分もあるのだけど、この動的プロパティテーブルの生成回避ができないのがネック
円形POVできれいに映像を表示するためには

2024/01/30

円形POVを作ったけれども映像が崩れてしまう時のプログラムにおける対処法についてまとめました。

# 目次
[1.結論](#1-結論)
[2.円形POVについて](#2-円形POVについて)
[3.開発環境](#3-開発環境)
[4.結論詳細](#4-結論詳細)
[5.おわりに](#5-おわりに)

# 1. 結論
円形POVできれいに映像を表示するためには、
```
rot time > loop time × Div
```
が成り立つ必要がある。
4.結論詳細で説明する。


# 2. 円形POVについて
POVには円形POVの他にも[振るタイプのPOV](https://www.youtube.com/watch?v=w8qZ3BsHklk)や[3DPOV](https://www.nicovideo.jp/watch/sm28790948)などがあります。
渋谷とかのサイネージとかでよく使われていたりするのは円形タイプですね。
(6分40秒あたり) https://www.youtube.com/watch?v=EZ7iBtdWKkg
撮影にはフレームレートを考慮しないといけないので、普段のように撮影すると肉眼で見た時とは違う風に見えてしまいがち。
3D Phantomのバーサライタによる演出はすさまじいです。完成度えっぐいなと思います。

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

POVについては、"Persistent of Vision", "バーサライター", "versa-writer"等のキーワードで検索すると情報がヒットしやすい気がします。


# 3. 開発環境
ハードウェア、ソフトウェアについては、homemadegarbageさんの[PovRanianのレシピ]( https://shop.homemadegarbage.com/product/povranian_recipe/)やその他の関連記事を見て作ってみました。特に大きな変更点はありません。

### ハードウェア
- マイコン
- LEDテープ
- フォトリフレクタ
- モーター
### ソフトウェア
- Arduino IDE(マイコンで制御)
    - フォトリフレクタで回転の検出(羽が通り過ぎたかどうか)
    - 回転時間(rotTime)を計算
    - pythonで生成した色情報に関する配列をもとに、LEDテープを高速切替点灯
- python
    - pngやjpgなどの画像は4点のどこかを原点(大抵左上か左下)としたxy座標のようにピクセルが並べられている。
    - 画像のピクセル情報(x, y, color)を中心からの距離と角度で指定する座標(極座標)に変換する。
    - 変換した情報を配列にしたものをgraphics.hというファイルで保存
- モーター
    - とりあえず適当な電圧を与えて回転させておけばいい。速度制御とかしなくても動く。


# 4. 結論詳細
円形POVできれいに映像を表示するためには、
```
rot time > loop time × Div
```
が成り立つ必要がある。

- Divとは画像の分割数のこと。pythonプログラム内で指定している変数。ホールケーキを切るように画像を分割していきます。ケーキはせいぜい8分割とかですが、ここでは100分割(Div=100)とかしています。Divが大きいほどより解像度の高い鮮明な映像を表示することができます。
- rot timeとは一回転にかかる時間(μs)。arduinoプログラム内で指定している変数。フォトリフレクタが反応することで計算しています。
- loop timeとはloop関数の最初から最後までにかかる時間(μs)。arduinoプログラム内で指定している変数。ここではフォトリフレクタの処理とLEDテープの処理にかかる時間のことを指します。

一回転の間に、全てのLEDパターンを変えないといけないため、つまり1loopで最低Div回切り替えないといけないため、rot time > loop time × Divが成り立ちます。

なので表示がうまくいかないときは、rot timeとloop timeの値をシリアルモニター等で確認するといいです。
もしrot time 「<」 loop time × Divだったらば、
1. rot timeを大きくする(モーターの回転速度を小さくする)
2. loop timeを小さくする(軽い処理プログラムを探す)
3. Divを小さくする(pythonプログラムの値を変えるだけ)
の3つのアプローチがあります。

しかし、それぞれに課題があります。
1. 回転速度が遅すぎると目の残像効果(Persistent of Vision)が薄れて、映像が見えにくくなる。
2. 見つけるまでの試行錯誤が大変。使うものの選定から再考する必要があるかもしれない。
3. 解像度が小さくなるのでローポリになる。細部を表現することができなくなる。


# 5. おわりに
### プログラム以外で失敗しがちな箇所について

- ハードウェアが原因
    - 今回使用したフォトリフレクタの検出距離が3mmということで離れすぎると検出できず、近すぎると羽とぶつかってしまう距離感がシビアでした。
 
- 電気が原因
    - LEDテープのclkとdataの線にノイズが乗ることがありました。ノイズ対策が必要です。

### 撮影・共有について。
- 原理はよくわからないけどガラスに映したものは撮影しやすい。

https://x.com/2001_ognir/status/1589953870654246912?s=46&t=3ShaupB8CCkBUFgXUMlioQ

- スマホの設定では撮影できていても、共有するプラットフォームに応じては、自動的に映像の表示設定が変更されてしまうことがある。
    - (例)60fpsで撮影したPOVの映像をdiscordで共有したら、30fpsに自動的に下げられ、何が映っているのかさっぱりわからない。

 # 参考
 https://homemadegarbage.com/pov-esp32-03
 https://homemadegarbage.com/povranian-make
「世界一流エンジニアの思考法」読書感想文メモ

# はじめに
本記事は「世界一流エンジニアの思考法」を読んだ感想と、
それに付随するような自分の経験と考えをメモするものです。

Xでの評価がよかったので読んでみましたが、
未来の自分が書いたのかなと思うほど共感できる内容でした。
(バークリー音楽大のトモ藤田を説明に使用するなども共感ポイントが高い)

https://amzn.asia/d/clO16qN

# 3流エンジニアから見た1流エンジニアの生産性が高い理由
全体を通して一流エンジニアと3流エンジニアの基本スペックには大きな差はなく、
生産性の差を生んでいるのは「思考法」と記載されています。
例えば、問題を解決する際には、手あたり次第に調査を行うのではなく、現在の情報から問題個所の推測をしてから、作業に着手するなど具体的な手法が実例を元に説明されていてわかりやすかったです。
自分が新卒のころに読みたいと感じました。

# 生産性の差を生んでいるのは「思考法」
未来の自分が書いたと感じる一番の理由はここでした。
私も筆者と同じようにハンデがあり、仕事がうまくいかない、生産性が低い時期がありました。
よく、複数人の上長に「昔なら殴っていた」「変な癖のある人材なんて首にしたい」など指導されたのは良い思い出です。
同じ人間なのになんでこう違うのだろうかと悩んだ結果、同僚を研究し「思考法」や「仕事術」を学び始め、今ではそれなりに仕事ができるようになったと思います。

## 私の経験
一つだけ筆者と私が異なるのは、私は「1流エンジニア」から何かを学ぶことが下手でした。
いい仕事の仕方を見ても、なんでそうしているのかがよく理解できず、
なんとなく真似をしてしまうため、本当にやるべきことができていませんでした。

かわりに私は「1流エンジニア」ではなく、「3流エンジニア」から仕事を学びました。
1流エンジニアがやらないことを3流エンジニアはやります。
やった高い確率で問題が発生します。私はそれを反面教師にしました。

本でも早く失敗してフィードバックを受け、アジャイル的により良い方法を探していくといった記載がありましたが(ちょっとニュアンス違うかも)、それを同僚を観察して行うイメージです。

1つ報告を例にします。
私に対して報告する際、1流エンジニアは報告は3行くらいで端的にまとめた報告をしました、
しかし、3流エンジニアは長文で煩雑な文章で報告をしました。
それを受けた私は「長文だと受け取るのがつらいなぁ」と実感を伴った仕事術や以前教わった思考法の真意にやっと気づくといった流れです。

「1流エンジニア」は自然と生産性が高い思考法や仕事術に気が付く傾向があると思います。
私はそれを何とか身に着けようと必死です。

今でも上記は継続しており、同僚が書いたNotionや技術記事はいち早くチェックしたり、同僚がどんな仕事をしているか知るようにしています。


# 頭がよくても理解には時間がかかる
タイトルの通りですが、頭が良い人でも複雑なものを理解するには時間がかかります。
しかし、深く理解していることを増やしていくと新しいことを理解する際の効率があがるようです。

生産性が高いというのはなるべく無理をせず、効率的な手法をとるべきということなのかなと思いました。
コードを読む際にコードの中に深く理解していることが含まれていると、読む際の認知負荷が低くなる、結果少ないコストで物事を理解できるといった考えです。

詳細はぜひ書籍で確認してください。

# 健康について
仕事と人生の質を高める生活習慣術にて、運動の大切さについて記載されている。
テストステロンというホルモンを増やすと気力が高い状態を維持できるといった話です。これはおっしゃる通りだと思います。

## 私の経験的な感想
運動をすることで気力が回復するのは実感があります。
私は週5程度の筋トレを習慣にしていますが、以前に比べて肉体的にもメンタル的にもかなり良い状態になりました。

ただ、本に記載のあったテストステロンブースターだけはちょっと実践できないと思いました。偏見だし、詳細は分かりませんがホルモン剤はボディビルでいうドーピングにあたるのではないかなどちょっと怖いです。
バランスの良い食事、運動、睡眠を軸に私は頑張ろうと思います。

# 好きな言葉
以下は本書の中で好きな言葉です。
- 自分がしんどいと思う「努力」は一切やめてしまうこと
- 自分にとって難しすぎると感じると気は、たいてい脳の使い方が間違っているサインだ
- 納期は絶対という神話は捨てよ
- KPIは定時で無理なく楽に達成できる程度のものであるべきだ

# おわり
本書は、3流エンジニアが1流エンジニアになるために必要な思考法について記載された本です。そのため、仕事がうまくいかず色々試行錯誤した人は共感できる箇所が多くあると思います。
記事には記載しませんでしたが、チーム作りの話や小さいドキュメントを作る話なども私は好きです。
本の評価はよくわかりませんが、すくなくとも私は本書を何度も読み返すと思います。
Terraform で AWS SSO で認証できない場合の解消法

# terraform環境
```s
$ terraform -version
Terraform v1.6.1
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v5.34.0

Your version of Terraform is out of date! The latest version
is 1.7.1. You can update by downloading from https://www.terraform.io/downloads.html
```

# terraform applyの結果
```s
$ terraform apply
╷
│ Error: Invalid provider configuration
│ 
│ Provider "registry.terraform.io/hashicorp/aws" requires explicit configuration. Add a provider block to the root module and configure the provider's required arguments as described in the provider
│ documentation.
│ 
╵
╷
│ Error: No valid credential sources found
│ 
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on <empty> line 0:
│   (source code not available)
│ 
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
│ 
│ Error: failed to refresh cached credentials, refresh cached SSO token failed, unable to refresh SSO token, operation error SSO OIDC: CreateToken, https response error StatusCode: 400, RequestID:
│ efb20f89-cfa8-4ac0-a37d-d5960f1201a8, InvalidGrantException: 
```

# 解消方法
```s
$ aws sso login
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.ap-northeast-1.amazonaws.com/

Then enter the code:

KPMK-GKSW
Successfully logged into Start URL: https://d-1234.awsapps.com/start
```
vpcのterraform

# リソース定義
```terraform
resource <RESOURCE_TYPE> <RESOURCE_NAME> {
  ...
}
```
RESOURCE_TYPEは、<font color="orange">aws_vpc </font> になる

```terraform
resource aws_vpc <RESOURCE_NAME> {
  ...
}
```
RESOURCE_NAMEは、<font color="orange">Terraform内で識別するための名称を指定 </font>してあげる

# aws_vpc
|項目|型|説明|
|---|---|---|
|cidr_block *|string|IPv4 CIDR ブロック|
|assign_generated_ipv6_vidr_block|string|IPv6 CIDR ブロック|
|instance_tenancy|enum|テナンシー|
|enable_dns_support|bool|DNS解決|
|enable_dns_hostnames|bool|DNSホスト名|
|tags|object|タグ|
(Quasi-)Monte Carlo法と球面集中現象

# 初めに
「球面集中現象」という言葉を知った．

少しだけ勉強してみる．

文献（備忘録として）：
* [具体例で学ぶ数学: 球面集中現象](https://mathwords.net/kyumensyutyugensho#google_vignette)
* [赤穂2023: 少量のデータに対する機械学習](https://doi.org/10.1587/essfr.16.4_247)

# 球面集中現象
## 2次元空間
まず，2次元空間での単位円を考える（直径$d=1$，半径$r=d/2$）．

単位円の面積$S$は，

```math
\begin{align}
    S 
    &= \pi r^2 \\
\end{align}
```

である．中心から$r_* = 0.9r$以上離れた部分を，円の「表面付近」と呼ぶこととすると，その面積$S_*$は，

```math
\begin{align}
    S_{*}
    &= \pi \left( r^2 - r_{*}^2 \right) \\
    &= \pi \left( r^2 - (0.9r)^2 \right) \\
    &= 0.19 \pi r^2 \\
\end{align}
```

である．円全体の内，19%が「表面付近」である．

## 3次元空間
続いて，3次元空間での単位球を考える．

単位球の体積$V$は，

```math
\begin{align}
    V
    &= \frac{4}{3} \pi r^3 \\
\end{align}
```

である．先ほどと同様に，中心から$r_* = 0.9r$以上離れた部分を，球の「表面付近」と呼ぶこととすると，その体積$V_*$は，

```math
\begin{align}
    V_{*}
    &= \frac{4}{3} \pi \left( r^3 - r_*^3 \right) \\
    &= \frac{4}{3} \pi \left( r^3 - (0.9r)^3 \right) \\
    &= 0.271 \frac{4}{3} \pi r^3 \\
\end{align}
```

である．球全体の内，27%が「表面付近」である．

## d次元空間
より一般化して，$d$次元空間を考える．

ここで，$d$次元空間において，相似な図形の体積比が相似比の$d$乗に比例する性質を利用する．

すなわち，$d$次元超球の体積$V(d)$と，その「表面付近」の体積$V_*(d)$との比は

```math
V(d) : V_*(d) = 1 : 1 - R^d
```

となる．ただし，$R$は相似比である．

実際，

* $d=2$では，$V(d) : V_*(d) = 1 : 1 - 0.9^2 = 1 : 0.19$
* $d=3$では，$V(d) : V_*(d) = 1 : 1 - 0.9^3 = 1 : 0.27$

より，先ほどの計算結果と一致する．

空間次元$d$を大きくしながら$V_*(d)$を計算すると，以下のようになる．

![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529612/9c538dfb-4588-c68f-2d8d-78c7f614721e.png)

高次元になるほど，「表面付近」の割合が大きくなる．

幾つかのサンプリングを試したが，MCだけでなく，QMCでも起きるようである．

![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529612/875c8f87-f2c3-40f2-e653-c1d4ef166fa0.png)

記憶が曖昧だが，何処かでLHSは球面集中現象を回避，或いは緩和できると聞いた気がするが，実験の結果，MCとLHSはそう変わらない気がする．或いは，コードにバグがあるかもしれないが．

# 終わりに
最近は，分からないことだらけである．

# Appendix
```python
import numpy as np
from scipy.stats import qmc
import matplotlib.pyplot as plt

m = 32   # repeat
n = 2**10   # sample size
ds = np.arange(2, 10, 1)   # dimensions

V_star_list = []
for d in ds:
    res_list = []
    for i in range(m):
        X = np.random.uniform(size=(n, d))
        # X = qmc.LatinHypercube(d=d).random(n=n)
        # X = qmc.Sobol(d=d).random(n=n)

        rs = 0.
        for j in range(len(X.T)):
            rs += X[:,j]**2
        rs = np.sqrt(rs)

        count = 0
        count_in = 0
        for r in rs:
            if r < 1.:
                count += 1
            if r < .9:
                count_in += 1

        res = count_in / count
        res_list.append(res)

    print(f"d:{d:d}, V_star: {1. - np.mean(res_list):.2f}")
    V_star_list.append(1. - np.mean(res_list))
```
Terraform デバッグログを有効にする/無効にする

# Terraform デバッグログを有効にする
```s
export TF_LOG=DEBUG
```

# Terraform デバッグログを無効にする
```s
unset TF_LOG  #通常の状態に戻る
```

# 利用可能なログレベル
|ログレベル|説明|
|---|---|
|TRACE|これは最も詳細なログレベルで、システムの動作に関する非常に詳細な情報を提供します。<br>プログラムの流れや変数の値、システムの状態など、デバッグに役立つ広範囲な情報が含まれます。<br>開発者が問題の特定やパフォーマンスチューニングを行う際に有用ですが、通常の運用ではあまりにも情報量が多すぎるため、使用されることは少ないです。|
|DEBUG|このレベルでは、システムの動作に関する重要なデバッグ情報が含まれます。<br>TRACEよりは情報量が少ないですが、システムの動作を理解するのに十分な詳細情報が提供されます。<br>開発者やシステム管理者が問題を診断する際によく使われます。|
|INFO|一般的な情報が提供されます。<br>システムの正常な動作に関するメッセージ、重要なイベントの通知、プロセスの開始や終了などが含まれます。<br>これは一般的な運用において最もよく使われるログレベルで、システムの状態を把握するのに役立ちます。|
|WARN|警告メッセージが含まれます。<br>これらはエラーではありませんが、将来的な問題を引き起こす可能性のある状況を示しています。<br>例えば、リソースの使用量が限界に近づいている場合や、推奨されない操作が行われた場合などが該当します。|
|ERROR|エラーメッセージが含まれます。<br>これはシステムの正常な動作を妨げる重大な問題を指し、直ちに注意が必要な状況を示します。<br>例えば、ファイルの読み込み失敗、ネットワーク通信の障害、プログラムの異常終了などが該当します。|


# Chat-GPTによるアドバイス
通常、ログレベルは環境に応じて選択されます。
開発環境では DEBUG や TRACE レベルが使われることが多いですが、本番環境では INFO や WARN レベルが一般的です。
git の差分比較・マージを WinMerge で行う

## git diff でWinMergeを呼び出す


## 参照URL
https://qiita.com/kobake@github/items/fb317b4fdacad718a4b2

## 追記

上記ブログを参考に、~/.gitconfigを以下のように設定

```
$ cat ~/.gitconfig
[user]
        name = xxx
        email = xxxxxx@gmail.com
[core]
        editor = code --wait
        pager = less -F -X
[alis]
        co = commit
        ci = commit
[alias]
        st = status
        br = branch
        co = checkout
        ci = commit
[pull]
        rebase = true
[diff]
        tool = WinMerge
[difftool "WinMerge"]
        path = C:/Program Files/WinMerge/WinMergeU.exe
[difftool]
        prompt = false
[merge]
        tool = WinMerge
[mergetool "WinMerge"]
        path = C:/Program
[mergetool]
        prompt = false

```



これで「git difftool」コマンドをたたくことで、GUI diffツールのWinMergeで差分が表示される。
Grasshopperのコンポーネント名を上に表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662314/00d57268-9e42-20d1-d7b1-4068f056a234.png)
アイコン表示にしているがコンポーネント名を確認したいときや情報共有の際にすぐに名前を確認したいという状況があったので調べていたところこちらのコンポーネントを見つけたので備忘録的に記事にしておきます。

https://www.food4rhino.com/en/app/bifocals#downloads_list

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662314/0ebade6d-99df-772c-e9cd-c76d0a1fac16.png)

こちらのコンポーネントをキャンバスに配置するだけでコンポーネント名が上部に表示されるようになります。
Google Colab でアップロードされたファイルを指定のファイル名に変える

毎回、思い出すのが面倒なのでメモ

```
def upload_as(new_name: str):
    import os
    from google.colab import files
    
    uploaded_name = [k for k in files.upload().keys()][0]
    os.rename(uploaded_name, new_name)
```
ServiceNowのインスタンスをスクリプトから識別する方法はあるか？

## はじめに
ServiceNowの本番インスタンスを1つ運用するときは、開発用インスタンスやテスト用インスタンスなど、複数の非本番インスタンスを並行して運用することになると思います。

これらのインスタンスでは基本的に同じアプリケーションが動作することになりますが、場合によってはインスタンスを識別して異なる振る舞いをさせたいこともあります。例えばロギングや通知について開発環境専用の運用をしたいとか、テスト環境と本番環境で異なる接続先に接続したいなどということは普通にあると思います。

こういうときに、自インスタンスに関する識別情報をスクリプトから照会して、その結果によって処理を分岐できれば便利ですが、そういうときに使える機能はあるのでしょうか？今回はこの点を調べてみたいと思います。

## いくつかの候補になる機能
自インスタンスを固有のIDで識別する、あるいは自インスタンスが本番か非本番かを識別するときに利用を検討したいOOTB機能はいくつかあります。順に見ていきましょう。

### instance_nameシステムプロパティ
まず、自インスタンスの名称は`instance_name`というプロパティに設定されています。このプロパティの値はURLの`.service-now.com`の前についている文字列です。これは確かにインスタンスを一意に特定することができる文字列なので、利用できるかもしれません。

しかし難点があります。このプロパティの値はユーザーの目に直接ふれるところなので、技術的な要件だけで決定できないということです。言いかえると、**この名称はエンジニアの持ち物ではない**のです。たとえ社内システムだったとしても、社内向けのブランディングの要件で決定あるいは変更されることがあるため、技術的な識別の拠り所にすることができないのです。

変更可能（Now Supportからチケットを起票すれば可能です）で不変のユニークIDというわけではないということも重要です。したがって、永続的な実装でこのプロパティを信じて参照すると、後々変更の影響で悩まなければならなくなります。

### glide.installation.productionシステムプロパティ
別の候補として、`glide.installation.production`というものがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491737/dcbff72c-afe2-6c9d-4127-42b85231b3b2.png)

これの難点はOOTBの設定値が当てにならないということで、非本番でも`true`が入っていたりします。また、本番か否かの情報しか管理できないもの難点です。

それでも情報を修正して利用するという場合は「プライベート」フィールドのチェックを入れて`true`にする必要があります。その意味については後述します。

### glide.db.clone.allow_clone_targetシステムプロパティ
もう少し信頼できそうなプロパティとして`glide.db.clone.allow_clone_target`というものがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491737/c74b5df6-2cdd-a639-b88e-4faa20754bcc.png)

これは、クローニングの際に、ターゲットにすることを許すか否かというプロパティで、初期状態では本番インスタンスにおいて`false`、非本番では`true`が設定されているので、期待通りに動作します。

ただし、あくまでクローニングに関するプロパティであり、非本番でもクローンのターゲットにしたくないインスタンスで`false`を設定することも当然ありうるので、そういう設定変更が将来的に想定される環境では、このプロパティをインスタンスの識別目的には使えません。また本番か非本番かの区別にしか使えないのは先程のものと同じ弱点です。

### 結局は...

結局、どれも帯に短し襷に長しという感じで、決定的な案はありません。したがって、本当にそういうものが必要であれば、自分で用意するしかないというのが現時点での結論です。

## 実装

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491737/ff4c7ad3-64d4-2b00-9d59-e7a5c20a82ec.png)

「プライベート」を`true`に設定したシステムプロパティを新規に追加し、それを管理するというのが結局は一番信頼できます。この新しいプロパティを読み取って評価結果を返すスクリプトインクルードを用意してAPIを提供するのもよいと思います。

なお、システムプロパティを「プライベート」にする意味は、それをインスタンス固有のプロパティ、例えて言うならある種の環境変数として扱うということです。プライベートではないプロパティは更新セットに捕捉され、環境間で移送される対象になります。したがって全ての環境で同じ値を持たせたいものは非プライベートにします。[^1]

https://docs.servicenow.com/csh?topicname=t_AddAPropertyUsingSysPropsList.html&version=latest

## 参考情報
この小文の内容は、この辺りの議論を参考にしながら調べた結果をまとめたものです。

https://www.servicenow.com/community/itsm-forum/what-is-the-glide-installation-production-property-for/m-p/701745

[^1]: そういう意味では、冒頭に挙げた、環境ごとに異なる接続先を、というケースでは、環境をプロパティから読み取って分岐するのではなく、最初から接続先情報をプライベートなプロパティで管理するのがよりスマートなやり方になりますね。
京セラドキュメントソリューションズの長期インターンシップに参加しました。

この記事は京セラドキュメントソリューションズ株式会社から掲載許可を頂いております。

# はじめに
夏頃から継続的に京セラドキュメントソリューションズのインターンシップに参加していました。8月に5DaysのWorkShop、9月～12月にかけて長期のOriginalインターンシップに参加させていただいたので、今回は長期のOriginalインターンについて取り組んだ内容や感想について書いていこうと思います！

# 目次
1. [KDCについて](#Chapter1)
1. [Originalインターンとは](#Chapter2)
1. [取り組んだこと](#Chapter3)
1. [全体を通しての感想](#Chapter3)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# KDCについて
京セラドキュメントソリューションズ株式会社（以降KDC）は大阪府に本社を置く情報機器メーカーで京セラグループの一つです。主に複合機（MFP）の開発を行っており、AI搭載複合機を市場に送り出しているメーカーでもあります。最近では布に印刷を行う捺染プリンターや、言葉を認識してリアルタイムに文字・図解・動画をスクリーンに表示するCotopatなどの開発もしているようです。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654050/f2e0e613-6e0e-56a8-10e3-cba4f6125714.jpeg width=50%>

<a id="#Chapter2"></a>
# Originalインターンとは
主にKDCのソフトウェア開発部門で実施している長期型のインターンシップです。学生の希望に沿って実習内容を企画、実施して頂けるのが魅力に感じてエントリーしました。他に数名学生が参加しているので完全に希望通りというわけではないかもしれませんが、私の場合はほとんど希望通りに実施して頂くことができました。実際に事前の面談ではどのようなことを体験したいのかを聞かれ、研究分野がAIだったこともあり、AI開発課のインターンに参加することになりました！

<a id="#Chapter3"></a>
# 取り組んだこと
内容に関しては掲載できるものが限られているので抜粋して書いていきます。三か月のうち前半はMFPに搭載するAI機能についてのアイディエーション。そして後半は実際にドキュメントに対して画像認識を行うAIモデルの開発を行いました。
### 1. アイディエーション
アイディエーションではMFPに搭載するAI機能を、ペルソナや今ある課題を上げつつグループで考えました。ここではクラウド上で動くAIではなく、MFP内のCPUで動くいわゆるエッジAIを想定しています。最初こそ多く意見が出るのですが、新規性やエッジAIという制約を踏まえると中々いいアイデアが出なくなってくるのが現実です...。ですが最終的にはよいアイデアを発表することができたのではないかと思います。

（実際に発表した資料の一部↓）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654050/fdae427c-f2e6-19c0-dc01-062aec8efd93.png)

### 2. ロゴ認識AIの実装
後半の実装ではドキュメントから企業ロゴを認識して判別するAIモデルを開発しました。まずデータセットの作成から始まり、既存の画像認識モデルに対して作成したデータを転移学習させます。自分は特にデータセットの作成にこだわり、インクが掠れたり潰れてしまっている文書に対してもロゴの識別ができるよう工夫しました。過学習などの問題はありましたが、最終的には高い精度が得られたと思います。なんと！最終日には実際に本社のナレッジプラスという、製品発表などが行われるスペースで成果発表をさせていただきました！なんて貴重な経験...

（ナレッジプラス↓）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654050/f6b7511c-2223-fbee-dea0-52fbcc400ff1.png)


<a id="#Chapter4"></a>
# 全体を通しての感想
全体を通して社員の方のフォローが手厚かったのが印象的でした！これは夏のUI部署のインターンでも感じたことで、社員同士のつながりを大切にしているKDCならではだと思います。また、アイディエーションの時間を長くとって頂けたのもよかったです。新規性のある機能を考える大変さや、グループで意見をまとめる難しさなどを身をもって学ぶことができました。実は2月からベンチャー企業でさらに実務的なインターンに参加させていただく予定なので、今回学んだことを生かしていきたいです！

- [【KDC採用情報】](https://www.kyoceradocumentsolutions.com/ja/careers/)