OmniAICreator/Qiita-1.07M huggingface dataset:
大量保有報告書XBRLを活用する

自称XBRL系ダクトテーププログラマ、ぱにです。よろしくお願いします。
[あやぱに](https://ayapani.azurewebsites.net/)というサイトの開発・運営をしています。

[あやぱに](https://ayapani.azurewebsites.net/)は、EDINETから取得した大量保有報告書をデータ化して閲覧・検索できるようにしたサービスです。あやぱにの開発を経験して学んだ（ハマった）こと、考慮したことなどを共有したいと思います。

というか、自分のための備忘録であります。

# 対象読者
大量保有報告書に興味がある人。EDINETと聞いてピンときた人。XBRLの基本的な知識があり、活用方法を知りたい人。

# このページに書かないこと
具体的なプログラムは出しません。[あやぱに](https://ayapani.azurewebsites.net/)は Azure/C# で開発・運営していますが、そっち方面の説明はしません。設計レベルの話ばかりです。

# データ取得(API)編
XBRLをEDINETからとってきますが、これがなぜか単純にはいかないんだなぁ。

## 過去分は5年まで
大量保有報告書は、EDINETで開示から5年間閲覧可能。APIで取得可能な期間も同じです。
それより古いものが欲しければ、、、[有報キャッチャー](https://ufocatch.com/Xir.aspx?m=t)などから取得するしかないかな。

**対応**
* 取得したデータ(XBRL)は**捨てない**。再取得は手間も時間もかかるし、いずれ取得できなくなる。

## APIは403エラーをすぐに返す
EDINETは2023年1月からリニューアルされました。APIも同じ仕様のままアップデートされた模様で、それ以降なぜか「403 Forbidden」エラーが頻発するようになりました。（個人の感想です）

**対応**
* APIは連打しないこと。少なくとも数秒程度間隔をあける。並列処理なんてもってのほか。
* 403エラーは必ず拾って、ちょっと（最低数秒程度）待って、リトライする。最初からやり直ししてたら終わらない。
* 取得したデータを捨てない。（大事なことなので2回目）

## 書類一覧のキーは書類管理番号ではない
これはAPIからデータを集めてデータベース化してから気づいたのですが、APIで取得した書類一覧のユニークキーは「連番」です。**書類管理番号ではありません**。
同じ書類管理番号が日をまたいで出現することもありますし、同日に複数回出現することもあります。

**対応**
* 書類一覧APIは日付をパラメータに渡すので、RDBに１書類１レコードで格納する場合、ユニークキーは「日付」「連番」の組み合わせにする。

## 書類は取り下げられる（一度開示された書類が非開示になる）ケースがある
withdrawalStatus(取り下げ区分)が"1"または"2"の書類は、その時点（書類一覧APIを呼び出した時点）でEDINET閲覧サイトでは開示されていないものです。取り下げデータの扱いをあらかじめ決めておこう。

# 大量保有報告書XBRL解析編
XBRLからほしい情報を取り出します。XBRLを必要以上に難しく考えるのはやめましょう。XBRLインスタンスからほしい要素名を指定して取ってくる、それだけでいいんです。XBRLを処理するためのライブラリなんていらない、シンプルで高速なXMLパーサを使えばいい。名前空間？なにそれ、おいしいの？

## ほしい情報の要素名を探す
[タクソノミ要素リスト](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/download/ESE140114.xlsx)から探せます。
大量保有報告書に関連するのはシート1, シート29-32 です。
大量保有報告書は原則拡張しないので、想定外の要素が出現することはありません。

あやぱにが使用している主な要素は以下の通りです。

| 要素名 | 日本語 |
|:--|:--|
| NameOfIssuer  | 発行者の名称  |
| SecurityCodeOfIssuer  | 発行者の証券コード  |
| StockListing  | 上場金融商品取引所  |
| IndividualOrCorporation  | 個人・法人の別  |
| Name  | 氏名又は名称  |
| PurposeOfHolding  | 保有目的  |
| TotalNumberOfStocksEtcHeld  | 保有株券等の数（総数）  |
| HoldingRatioOfShareCertificatesEtc  | 株券等保有割合  |
| HoldingRatioOfShareCertificatesEtcPerLastReport  | 直前の報告書に記載された株券等保有割合  |
| TotalAmountOfFundingForAcquisition | 取得資金合計 |

## データの取得はXBRLインスタンスからが簡単
大量保有報告書はInlineXBRLという仕様で作成されたHTMLと、そのHTMLから作成されたXBRLインスタンス（拡張子が .xbrl のファイル）が同封されています。
HTMLファイルは複数ファイルに分かれていますが、XBRLインスタンスは1つです。HTMLの余計な情報がそぎ落ちてデータだけの状態になっているので、XBRLインスタンスからデータを取得したほうが簡単です。

XBRLインスタンスから値を取得する場合は、名前空間は気にせず要素名だけで参照して問題ありません。

## コンテキストについて
大量保有報告書では、コンテキストは「FilingDateInstant」と「FilingDateInstant_(ほにゃらら)Holder(数字)Member」というのがあります。
「FilingDateInstant」は書類で１つの値、もしくは共同保有者の合計としての値のコンテキストです。例えば、発行者の名称(NameOfIssuer)なんかはこのコンテキストです。

対して「FilingDateInstant_(ほにゃらら)Holder(数字)Member」は、保有者の個々を示すコンテキストです。複数名の連名で大量保有報告書が出される場合がありますが、各人の保有割合(HoldingRatioOfShareCertificatesEtc)が、各コンテキストの値としてそれぞれ紐づいています。

# むすびにかえて
ここまで読んでくれてありがとう！さあ、大量保有報告書を分析してみましょう。
大量保有報告書は株主からみた保有銘柄の情報ですが、データ化することで、銘柄からみた株主の情報も見ることができるようになります。
新しい発見があるかもしれません！！
Optional class

Optionalはnullかnull以外かのどちらの値も格納できるclass
Optional.ofNullable(xxx)はnullならemptyに読み替えて格納する。
array refer時のArrayIndexOutOfBoundsExceptionやNullpointerExceptionを回避してくれるようなものではないので注意

```java
public class Outer {
    public static void main(String[] args) {
        String strArray[] = {"1a","2a",null};
        System.out.println(get(strArray,3));
        System.out.println(get(strArray,2));
        System.out.println(get(strArray,1));
        System.out.println(get(null,1));        
    }
    static <T> Optional<T> get(T[] array, int index) {
        if(array == null) {
            return Optional.empty();
        } else {
            try {
                return Optional.ofNullable(array[index]);
            } catch (ArrayIndexOutOfBoundsException ex) {
                return Optional.empty();
            }
        }
    }
}
```
```
Optional.empty
Optional.empty
Optional[2a]
Optional.empty
```
emptyからget()すると、NoSuchElementException
```java
        System.out.println(Optional.empty().get());
```
```
Exception in thread "main" java.util.NoSuchElementException: No value present
	at java.base/java.util.Optional.get(Optional.java:148)
	at com.mycompany.mavenproject1.Outer.main(Outer.java:12)
Command execution failed.
```
isPresent/isEmptyで空か空以外かわかる
```java
    public static void main(String[] args) {
        Optional<String> op = Optional.of("xxx");
        System.out.println(op.isPresent());
        System.out.println(op.isEmpty());
        op = Optional.empty();
        System.out.println(op.isPresent());
        System.out.println(op.isEmpty());
        }
```
```
true
false
false
true
```
Azure Cognitive Search あれこれ

# やりたいこと
Azure Cognitive Search を触る機会があり、色々と分からない部分があったので、備忘録も兼ねてこの記事にまとめます。

:::note info
具体的な操作方法やリソースの作成については別記事で投稿する予定です。
:::

# Azure Cognitive Search とは
https://learn.microsoft.com/ja-jp/azure/search/search-what-is-azure-search

公式ドキュメントより
> Azure Cognitive Search (旧称 Azure Search) は、Web、モバイル、エンタープライズ アプリケーションに、プライベートで異種のコンテンツに対するリッチな検索エクスペリエンスを組み込むためのインフラストラクチャ、API、およびツールを開発者に提供するクラウド検索サービスです。

> Azure Cognitive Search は、次のアプリケーション シナリオに適しています。
> * ユーザー定義のプライベートな検索インデックスへの異種コンテンツの統合。
> * インデックス作成とクエリワークロードを専用の検索サービスにオフロードします。
> * 関連性のチューニング、ファセット ナビゲーション、フィルター (地理空間検索)、同意語マッピング、オートコンプリートなど、検索に関連した機能を容易に実装。
> *Azure Blob Storage や Azure Cosmos DB に格納されている未区分の大きなテキスト ファイル、画像ファイル、またはアプリケーション ファイルを検索可能なチャンクに変換。 これは、外部処理を追加するコグニティブ スキルを使ってインデックスを作成するときに行われます。
> * 言語分析またはカスタム テキスト分析を追加。 英語以外のコンテンツがある場合、Azure Cognitive Search では、Lucene アナライザーと Microsoft の自然言語プロセッサの両方がサポートされます。 また、生コンテンツの特殊な処理 (分音記号のフィルター処理や、文字列内のパターンの認識と保持など) を実行するようにアナライザーを構成することもできます。

個人的には、Blob Storage や CosmosDB、 SharePoint の中身を検索できるのが便利そうと思う。

# 構成要素
これも公式ドキュメントより
> 検索サービス自体は、"インデックスの作成" と "クエリの実行" の 2 つが主なワークロードとなります。
> * インデックス作成は、取り込みのプロセスです。コンテンツを検索サービスに読み込んで検索可能にします。 内部では、受信テキストはトークンへと処理され、高速スキャンできるように逆インデックスに格納されます。 JSON ドキュメントをアップロードすることや、インデクサーを使用してデータを JSON にシリアル化することができます。
コグニティブ スキルによる AI エンリッチメントは、インデックス付けの拡張機能です。 インデックスを付ける前に画像や言語の分析がコンテンツに必要な場合、AI エンリッチメントで、アプリケーション ファイルに埋め込まれたテキストの抽出、テキストの翻訳、さらにコンテンツを分析することによるテキスト以外のファイルのテキストと構造の推論もできます。
> * クエリが実行できるようになるのは、検索可能なテキストがインデックスに投入された後です。クライアント アプリが検索サービスにクエリ要求を送信して応答を処理します。 すべてのクエリは、ユーザーが制御する検索インデックスを介して実行されます。

# 検索サービス作成の流れ
Azure Cognitive Search を使って検索サービスを作成する流れは以下のようになる。
1. データソースの準備
1. インデックスの作成
1. (Optional) フィールドマッピングの定義
1. (Optional) スキルセットの登録
1. (Optional) AI エンリッチメント
1. インデクサーの作成

![Azure Cognitive Search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743460/7ce22b00-4857-4d19-2c2f-34afd3390052.png)


以下、具体的に説明していく (ここでは概要のみ述べ、実際の定義や作成方法は別途記事にします)。

## データソース
データソースとは、分析するデータ (文書ファイルなど) が保存されている場所 (ストレージアカウントなど) のこと。
これを定義した上で、インデクサーの作成時に指定してあげることでインデクサーがデータソース内のデータを読みにいく。

## インデックス
インデックスは分析したデータを任意のフィールドに格納するための定義。インデックスに格納されることで検索可能になる。イメージとしては、データベースでいうテーブル定義に相当する。

## [Optional] フィールドマッピング
インデックス作成時に使用される、型や出力名などをデータソースとマッピングするための定義。例えば、BLOB のメタデータからインデックスを作成する場合、[メタデータ名は決まっている](https://learn.microsoft.com/ja-jp/azure/search/search-howto-indexing-azure-blob-storage#indexing-blob-metadata)ため、そのままインデックス定義に用いると分かりにくい。そういった場合に、フィールドマッピングして、分かりやすい名前にする。

## [Optional] スキルセット
AI エンリッチメントを使う場合にインデクサーによって利用されるスキルの集合。スキルには、Microsoft が提供する組み込みスキルとユーザが定義するカスタムスキルがある。事前にスキルセットを定義しておき、そのスキルセット定義をインデクサー定義に記述する。

## [Optional] エンリッチメント
全文検索できないようなコンテンツ (画像など) に対して機械学習モデルを適用すること。上記のスキルを使用することで、様々なエンリッチメントを適用することができる。データソース内のコンテンツが、非構造化テキストや画像などの場合に使用する。

[組み込みスキルの一覧](https://learn.microsoft.com/ja-jp/azure/search/cognitive-search-predefined-skills)

## インデクサー
インデクサーは、データソース内のコンテンツを抽出し事前に定義したインデックスにマッピングするクローラー。また、スキルや AI エンリッチメントもインデクサーによって呼び出される。

インデクサーの作成時に、定義したインデックスが作成され検索可能となる。
ちなみに、インデックスを変更した際には、インデックス定義を更新し、インデクサーの再作成もしくはリセット・再実行を行う必要がある。

以上です。
sklearn.exceptions.NotFittedError: Estimator not fitted, call fit before exploiting the model.

# LGBMNotFittedErrorが出た
## 何が起きて何をしたか
Google Colabで学習させたLightGBMのモデルをpickleし、別の環境でunpickleしてpredictしようとしたところ以下のエラーが出た。
```python
Traceback (most recent call last):
  File "/usr/local/bin/rank_strings", line 8, in <module>
    sys.exit(argmain())
  File "/usr/local/lib/python3.8/site-packages/stringsifter/rank_strings.py", line 140, in argmain
    main(args.input_strings, args.limit, args.min_score,
  File "/usr/local/lib/python3.8/site-packages/stringsifter/rank_strings.py", line 39, in main
    y_pred = model.predict(X_test)
  File "/usr/local/lib/python3.8/site-packages/lightgbm/sklearn.py", line 795, in predict
    raise LGBMNotFittedError("Estimator not fitted, call fit before exploiting the model.")
sklearn.exceptions.NotFittedError: Estimator not fitted, call fit before exploiting the model.
```

原因はGoogle Colabの学習したLightGBMのバージョンと、実行環境のLightGBMのバージョンが異なっていたためだった。Google ColabでLightGBMのバージョンを最新に更新し、改めてモデルを作成しなおしたところ解決。
WPF XAML  NG 解決メモ

xmlns:local="clr-namespace:XXXXX"
XXXXX（名前空間のフルネーム）　コードをコンパイルすると下記エラーが発生する
「CLR 名前空間が定義されていません。'clr-namespace' URI が、アセンブリに含まれていない名前空間 'プロジェクト名' を参照しています。 」
プロジェクト名を右クリック→プロパティ→ビルドのタブで、プラットフォームターゲットをAnyCPUに設定する
Googleプロジェクト管理：プロジェクトマネジメント手法 VUCA

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# アジャイル・マインドセットを採用したいと思うシナリオ

アジャイルは、

- 不確実性
- リスク
- 競争が激しい世界

で価値を提供するものであることを忘れないでください。

新しい情報、新しい市場機会、さらには新しいテクノロジーにできるだけ早く対応できるように、チームをセットアップするのです。

アジャイルは、変化や不確実性の影響を受けやすい業界やプロジェクトで最も効果的に機能します。

ソフトウェア以外で、多くの変化に対応するビジネスや産業にはどのようなものがあるか、思い当たるものはありますか？ 

私が思い浮かべるのは、

- 新しいワクチン
- 治療法
- 技術を持つバイオテクノロジー
- コンテンツを共有するための無限の新しい方法を持つメディア
- 有名シェフや最新のフードブームがある食品業界
- 移り変わるトレンドに対応するために作られたファッション業界

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/48c476d3-fd13-0ec4-4a1d-6d88b07ab62f.png" width="６00">

などです。

逆に

- 農業
- 航空宇宙
- 製造業
- 鉱業

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/79a0bbfa-59d9-bb23-9c83-d9dac55f4be2.png" width="700">

など、かなり安定していると思われる業界でしょう。

しかし、厳格なサプライチェーンと規範を持つこれらの産業でさえ、新しい法律や規制、自然災害、その他の予期せぬ問題によって、変化に対応しなければなりません。

# VUCA

2020年の教訓は、どんな産業も変化と不確実性を免れることはできないということです。私たちは、どのような業界であれ、私たちの世界を形成するこれらの力を分類し、考えるための概念を探求していきます。

この概念は、VUCAと呼ばれ、***<font color="MediumBlue">どのプロジェクトマネジメント手法が最適かを判断する</font>*** のに役立ちます。これは、米軍のウォーカレッジがプロジェクトやビジネスにおいて、変化や不確実性の力を織り込むために考案したものです。

VUCAは

- <font color="MediumVioletRed">**V**olatility（変動性）</font>
- <font color="MediumVioletRed">**U**ncertainty（不確実性）</font>
- <font color="MediumVioletRed">**C**omplexity（複雑性）</font>
- <font color="MediumVioletRed">**A**mbiguity（曖昧性）</font>

の頭文字をとったもの。

それぞれについて、それがプロジェクトやビジネスの現場でどのような意味を持ちうるかを説明します。

### Volatility（変動性）

***<font color="MediumVioletRed">『ビジネスや状況における変化や変化の速さ』</font>***　

変動性の高いプロジェクトでは、業務に対する次の混乱が常にすぐそこにあることを議論することになります。あるいは、物事が通常のリズムに落ち着く暇がないように感じられる。

### Uncertainty（不確実性）

***<font color="MediumVioletRed">『予測不可能なこと、あるいは不意打ちを食らう可能性が高い』</font>***　

不確実性が高いプロジェクトでは、多くの仮定に基づかない将来計画を作成することは困難です。

### Complexity（複雑性）

***<font color="MediumVioletRed">『プロジェクトに影響を及ぼすであろう、相互に関連する力、問題、組織、要因の数が多い』</font>***　

例えば、ある製品が多様でグローバルなサプライヤーに依存している場合、それはプロジェクトの複雑さを増すことになります。

### Ambiguity（曖昧性）

***<font color="MediumVioletRed">『事象や状況の条件や根本的な原因を誤解してしまう可能性のある』</font>***　

曖昧さがあるプロジェクトでは、プロジェクト遅延の原因を特定することが難しく、リスクを低減するための緩和策を設計することが難しくなる。

# なぜVUCAを理解することがプロジェクトマネジメントに関連して重要なのか?

新しいプロジェクトに着手する際、どのようなアプローチを取るべきかを決める前に、***<font color="MediumBlue">そのプロジェクトが存在する環境と状況を調べる</font>*** ことが有効です。

もし、***<font color="MediumVioletRed">『あなたのプロジェクト環境が、変動性、不確実性、複雑性、曖昧性のレベルが高いなら、それは、アジャイルアプローチを検討すべき良い兆候』</font>***　であると言えるでしょう。

アジャイルアプローチは、VUCAを取り除く完璧なソリューションではありませんが、あなたとあなたのチームにVUCAがもたらすリスクを軽減するためのツールとシステムを提供することで、より良い結果を導くことができるのです。

アジャイルの価値と原則を考えれば、アジャイルが、VUCAがプロジェクトにもたらす課題に対する、実績のある、十分に文書化されたソリューションであることは明らかです。


# さいごに

企業は、VUCAの概念を、プロジェクトにどのようにアプローチするのが最善かを判断するツールとして適用することができます。このように、VUCAは非常に多くの情報を含んでいますが、すべて良いことです。これらの概念を理解することは、あらゆる種類のプロジェクトにおける意思決定に役立ちます。

アジャイルアプローチを採用すれば、このような不確実性があっても、成功する可能性が高まります。これらの概念は、プロジェクトだけでなく、広くビジネス界に適用されます。
1. HandsOn - Fundamental 解答アドバイス

※解説では解答を明記することがないように気をつけたいと思います、なので全問は載せません、ご了承ください、、
## Q1.サブカテゴリ「バインダー」は「事務⽤品」内で売上第何位ですか︖順位を数字で明記する必要はなく、⽬視で分かる形になっていればよいです。
A.カテゴリ(事務用品)、サブカテゴリ（品目）ごとに売上を出し。順位を明記をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119165/dac03b6a-b629-dfe7-3794-68313d219dc8.png)
## Q2.割引率が最も⼤きい地域はどこですか︖また、そこでの割引率は何%でしたか︖
A.地域ごとの割引率を出し平均に変更する。並び順を降順にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119165/50ecca8c-a38d-531e-06dc-8c15c2ceaaf5.png)
## Q3.オーダー⽇の2014年を対象とした場合、顧客IDとカテゴリの組み合わせの種類はいくつになりますか︖
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119165/5d36f95a-f2fa-39f9-6e6a-78dbe258cfc3.png)
A.オーダー日(年)をフィルターに入れて、2014年に絞り、顧客IDの個別カウントを行い総計を出す
DDAによる線分描画


DDA（デジタル微分解析器）による線分の描画をします。
整数演算のみで描画ができるので、アセンブラに落とすときなど便利です。
Pythonで書かれています。グラフィックス・キー入力はpygameを使っています。

```line.py
#!/usr/bin/python3
from pygame.locals import *
import pygame
import sys
import os

def waitkey():
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            if event.type == KEYDOWN:  # キーを押したとき
                k=pygame.key.name(event.key)
                return(k)


def draw_line(screen,p1,p2):
  (x1,y1)=p1
  (x2,y2)=p2
  (dx,sx) =(x2-x1,1) if x2>x1 else (x1-x2,-1)
  (dy,sy) =(y2-y1,1) if y2>y1 else (y1-y2,-1)
  if (dx>=dy):
    e = -dx
    for i in range( dx+1 ):
      set( screen,(x1,y1) )
      x1 -= sx
      e += dy+dy
      if ( e>=0 ):
        y1 -= sy
        e -= dx+dx
  else:
    e = -dy
    for i in range( dy+1 ):
      set( screen,(x1,y1) )
      y1 -= sy
      e+= dx+dx
      if ( e>=0 ):
        x1 -=sx
        e -=dy+dy

def set(screen,p):
  screen.set_at(p,(255,255,255))

def main():
    pygame.init()    # Pygameを初期化
    screen = pygame.display.set_mode((200,200))    # 200x200の画面を作成
    pygame.display.set_caption("DDAによる線分描画")    # タイトルを作成
    screen.fill((0,0,0)) # clear screen

    for x in range(0,205,5):
        draw_line(screen,(100,100),(x,0))
        draw_line(screen,(100,100),(x,200))
    for y in range(0,205,5):
        draw_line(screen,(100,100),(0,y),)
        draw_line(screen,(100,100),(200,y))

    pygame.display.update()
    key=waitkey()
    pygame.quit()
    sys.exit()

if __name__=='__main__':
    main()

```
実行計画を理解できるようになる記事まとめ

#### 対象者
 - SQLチューニングをしたことがない
   - SQLのどこがボトルネックになっているかの調査をしたことがない

#### 読んだあとの姿
 - 「ちょっとわかる気がするぞ...?」


#### 記事を読む流れ

1. 実行計画とはなにかを知る
https://tech-blog.rakus.co.jp/entry/20200612/postgreSQL

2. 感覚を掴むために練習環境を用意して色々触ってみる
https://tech-blog.rakus.co.jp/entry/20190315/postgresql/massive-data/function
https://tech-blog.rakus.co.jp/entry/20191025/postgresql
3. 「完全に理解した」
4. 実務のSQLで実行計画出す→「なにもわからない」
5. 読み方のポイントを学ぶ
https://soachr.hatenablog.com/entry/2019/12/11/000000
6. 読み方のケーススタディを読む
https://soachr.hatenablog.com/entry/2022/12/01/063000
7. 4.に戻る

↓

「ちょっとわかる気がするぞ...?」
 ～ TO BE CONTENUE ～

#### チューニングができるようになるために

 - どんなSQLが早くなるのかのテクニックを知る
   - https://tech-blog.rakus.co.jp/entry/20200603/postgreSQL


#### トラブルシューティング

 - 【初心者向け】PostgreSQLでインデックスを使ってくれない理由

https://tech-blog.rakus.co.jp/entry/20190703/postgresql/beginner
Oracle Analytics Cloud： データセットを設定する。データセットの設定で"ライブ"にしたときの動きについてみてみる

はじめに
---
Oracle Analytics Cloud ： データセットでデータアクセスの設定を"ライブ"にしたとき、レポートを実行すると最新のデータを取得しにいきます。
このデータアクセスを"ライブ"にすると、OACはどのような動きをするのでしょうか？についてみてみたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/83f5f736-1341-2be7-22ab-bde2f3a618ce.png)

前提
---
・データセットを作成したことがある
・開発者メニューを設定したことがある

開発者メニューは、右上部の"アカウント"をクリックし、
<img width="400" alt="{5DB2ECAB-E045-4E79-BEA6-90E21F38D16E}.tmp.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/ae625cf1-0916-c45e-c6c6-880cef680b0f.png"/>

"拡張"をクリック、"開発者オプションの有効化"をON(右側にツマミを移動)し、保存します。
<img width="400" alt="{5DB2ECAB-E045-4E79-BEA6-90E21F38D16E}.tmp.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/623a19a8-0a93-8b19-64b5-6a9c47c7fae1.png"/>


"ライブ"のデータセットの用意
---
データセットを作成し、データアクセスを"ライブ"設定にします。
SALES表をデータセットに追加します。"SALES"を右クリックし、右クリックメニューから"定義の編集"をクリックします。
![{5DB2ECAB-E045-4E79-BEA6-90E21F38D16E}.tmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/a2d25346-3326-5fc4-8438-f67311c2c9c3.png)

データ・アクセスが"ライブ"になっていることを確認します。"自動キャッシュ"になっている場合は"ライブ"に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5cfd3792-c4c5-15b8-78dd-5f33cb2221e0.png)

保存します。保存アイコンをクリックし、保存をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5c74dee7-5e12-e9be-3f89-a8d09774a4cf.png)

名前を付けて保存します。SALES_LIVEと入力し、OKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/86db5e50-dbb8-ddc3-b358-c92eb943c412.png)

データアクセスが表示されていないことがあります。その場合は、ウィンドウの右真ん中あたりにマウスカーソルを移動すると、"展開"のツマミがあり、それをクリックすると、表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/425742bd-3642-2a20-4292-4382672c157b.png)


ワークブックを作成する
---
SALES_LIVEのデータセットを使ってワークブックを作成します。
SALES_LIVEデータセットを開き、"ワークブックの作成"をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/e20dd8fc-9e6a-578a-ecb4-2f9dc1c2631e.png)

列を選択します。Ctrlキー＋列で複数列を選択できます。TIME_ID、AMOUNT_SOLDを選択し、右の空白部分"キャンバス"にドロップします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/e1724960-62d9-dff1-c87e-9d9db3cf9d83.png)

ワークブックが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/d9fc4d55-dcfd-5f02-8682-c8210c701427.png)


"動き"をみてみる
---
開発者ウィンドウを開きます。
右上部の「・・・(縦)」メニューをクリックします。"開発者"をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/55b27e67-5ead-1c93-218f-f27a5ebc142c.png)

"リフレッシュ"をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/12599a5e-ca4f-68f8-6f75-a4b177e5ef36.png)

"実行ログ"タブをクリックします。下部までスクロールすると、データベースに発行されたSQLが表示されます。"LIVE"設定の場合は、物理SQLが実行されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/0f0f729b-5d69-5872-b032-eee1caaf4bce.png)

"サマリー"タブをクリックします。
"問合せ時間"で、物理問合せの実行にかかった時間をみることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/208cef3e-69a0-5e1d-fbd3-2d4248a257ef.png)




以上
webp 透過の有る無しによるファイルサイズの違い

webpで透過の有る無しでファイルサイズがどうなるか試してみた。

<img width="45%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13740/76dbbef3-be95-ccbb-4f63-e433627405f3.jpeg">

<img width="45%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13740/feb9048a-2b13-2dc7-66e9-06b111e9d9c6.png">

| 画像の種類 | ファイルサイズ |
|:-|-:|
| 元の写真画像 webp  | 486KB  |
| 丸クリップ写真画像 webp  | 382KB  |
| 元の写真画像 png  | 3898KB  |
| 丸クリップ写真画像 png  | 3913KB  |
| 丸クリップ写真画像 png tiny  | 998KB  |
| 元の写真画像 png tiny  | 998KB  |
| 元の写真画像 jpg 100  | 2357KB  |
| 元の写真画像 jpg 60  | 767KB  |
| 元の写真画像 jpg 30  | 406KB  |

* webpのクオリティはデフォルトの75
* png tiny は https://tinypng.com/
BigQuery: コンソールからSQLを実行するときのロケーション(リージョン)を固定する

BigQuery で一時的なデータを保持するテーブルを作成しようと思い、コンソールから SQL を実行して結果を BigQuery テーブルに保存しようとしたら、ジョブが失敗しました。
どうやら US で実行されたらしく、東京リージョンのデータセットに保存ができなかったようです。

コンソールで実行する場合のリージョンの指定方法は [ここ](https://cloud.google.com/bigquery/docs/locations?hl=ja&_ga=2.168185318.-674800545.1658969619#specify_locations:~:text=Google%20Cloud%20%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AF%E3%80%81%5B%E5%B1%95%E9%96%8B%5D%20%3E%20%5B%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E8%A8%AD%E5%AE%9A%5D%20%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%97%E3%80%81%5B%E5%87%A6%E7%90%86%E3%82%92%E8%A1%8C%E3%81%86%E3%83%AD%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%5D%20%E3%81%A7%20%5B%E8%87%AA%E5%8B%95%E9%81%B8%E6%8A%9E%5D%20%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%97%E3%81%A6%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%AD%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82) にあるのですが、少し迷ったのでスクショを残しておきます。

#### 1.クエリ設定を開く
SQL エディタの上部にある `展開` から `クエリ設定` を選択する
![スクリーンショット 2023-01-24 13.04.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/9f357ea2-5aa6-4241-9f4a-0dcbc438b8e3.png)

#### 2.リージョンを指定する
クエリの設定パネルで `詳細オプション` を開く
`Automatic location selection` のチェックを外す
リージョンをチェックし、リージョンを選択する 
![スクリーンショット 2023-01-24 13.05.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/307fc104-c9b8-17d6-2a60-44ef6aa1675b.png)
文字列関連の関数、コマンド

# はじめに 
UipathでのRPA開発の中で、よく使うけどぱっと出てこないVB.NET系の文字列操作をまとめました。
(1)文字列の位置特定
(2)文字列の抜き出し
(3)文字列分割
(4)文字列から数値だけを抽出
(5)文字列比較/大文字小文字区別なし

## (1)文字列の位置特定
> IndexOf("xxx")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/46deefa8-5b42-9ca3-5e5f-65fd65838183.png)


## (2)文字列の抜き出し
> Substring(位置,文字数)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/e7215c74-4e55-dae6-cc32-7a8e6724adc1.png)


## (3)文字列分割
> Split("文字列","区切り文字")(n) →区切ったn-1個目の要素を取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/a07efbed-081a-4f46-d43e-2916bb9fa955.png)

## (4)文字列から数値だけを抽出
> System.Text.RegularExpressions.Regex.Replace("文字列", "[^0-9]", "")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/a9e6f126-1dfd-6f52-3a1c-4805ccaafda9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/af1fb3fc-de51-7c76-1137-b0ba477373b0.png)



## (5)文字列比較/大文字小文字区別なし
> 文字列①.Equals(文字列②,StringComparison.CurrentCultureIgnoreCase)

#### ↓引数なしだと大文字小文字を区別して判断
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/d8f2d3c4-6fca-5bcd-2dba-2017c4d1938f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/2642879a-5ba3-f7ad-0e28-1ef5ad7a2ff4.png)

#### ↓引数「StringComparison.CurrentCultureIgnoreCase」ありだと大文字小文字を区別しないで判断
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/60f0dfe8-168b-3fe8-88dc-6ebdeae0478c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997221/9491fdc3-0b11-7ec5-e4e6-fae4de7a7f62.png)
pyautoguiで遊ぶ クリックして立ち上げる

# pyautoguiとは
pythonで画面上でのマウスとキーボードの操作を自動化できる

## よく使用する動作
### click
マウス側の操作、左クリックと右クリックの指定、クリック回数の指定ができる。
### locateOnScreen
指定した画像と一致する画面上の画像がある場合にその座標を取得
### sleep
待機時間　プログラム上で保存や更新などの処理が行われるとき、別の処理が挟まれてしまうのを防ぐために使用
### hotkey
同時押し

### 使用例
```
pyautogui.locateOnScreen('./img/kyoyu_up.png')
pyautogui.click(d_click[0],d_click[1],button="left")
pyautogui.sleep(0.2)
pyautogui.hotkey("altleft","printscreen")
```

## zoomをクリックして起動させる
先ほど紹介した使用例をもとに、アイコンをクリックして起動させてみるプログラムを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/67ead876-aed0-d069-c20a-ab4b96c9dfe8.png)
上のアイコンを利用する。
まずは、snippingtoolなどで、アイコンの一部を切り出す。
切り出したものが下図になる。
![zoom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/a2e5894d-bd05-124d-f7c0-4a5e46639e23.png)

locateOnScreenは画面に表示されていないと座標を指定できない。
タスクバーに設定するなどするといいかも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/3f0f07ef-1990-e24c-5207-3d3501c8831f.png)

```
d_click=pyautogui.locateOnScreen('C:/Users/ryous/Desktop/qiita/zoom.png')
pyautogui.click(d_click[0],d_click[1],button="left",clicks=2)
pyautogui.sleep(0.2)
```
d_clickには座標が入る。
成功するとzoomが起動される。
指定した要素で配列化する

```
IEnumerator<Label> GetValues()
{
    yield return 0;
    yield return 1;
    yield return 2;
    yield return 3;
    yield return 4;
    yield return 5;
    yield return 6;
    yield return 7;
}

var it = GetValues();
for (int i = 0; it.MoveNext(); i++)
{
・・・
}
```
Cloudflare Zero Trust に Google Workspace を連携したときに出たエラー

# はじめに

- [Google Workspace · Cloudflare Zero Trust docs](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/gsuite/)

Cloudflare Zero Trust では、さまざまな IdP を連携して、ID 情報やそれに紐づくグループ情報などが含まれた認証通信をプロキシし、その情報を使ったポリシー制御を行うことができます。

Google Workspace も連携先の一つです。

# エラー

```
Failed to fetch group information from the identity provider
{}
```

![image-20230124132437510](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124132437510.png)

場合によっては、以下のエラーとなることもあるようですが、上記のものが再現できています。

```
Failed to exchange code for token
{
  "name": "google-apps",
  "idpType": "google-apps",
  "originalError": {
    "body": {
      "error": "invalid_grant",
      "error_description": "Bad Request"
    }
  }
}
```

![image-20230124133848957](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124133848957.png)

```
Got a non-200 status in oauth code exchange
{
  "body": {
    "error": "invalid_client",
    "error_description": "Unauthorized"
  }
}
```

# 解決法

Save すると出てくる `finish setup` のリンクをクリックしてセットアップを完了しましょう。

![image-20230124132417092](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124132417092.png)

![image-20230124132725774](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124132725774.png)

![image-20230124132746416](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124132746416.png)

# テスト

その後、Test が通って正しく ID・グループ情報を取得できていることがわかります。

![image-20230124132918189](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20230124132918189.png)
Platform App Builder Certification Maintenance (Winter '23)

[Trailhead関係　個別の課題別](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)


# Please make sure the prework is configured in the playground.

やっと解答をみつけたかもしれない。

+ [認定 Platform アプリケーションビルダー資格の更新 (Winter '23)で"Please make sure the prework is configured in the playground."が出たら](https://sfblog.markhammer.net/)

:::note
この画面が出た場合は、一度ユーザ管理設定の「有効期限のある権限セットおよび権限セットグループ」を無効にし、再度有効に変えてからChallenge確認ボタンを押してください。
:::

英語では

:::note
If this screen appears, disable "Permission Sets and Permission Set Groups with Expiration Dates" in User Management Settings, enable them again, and then press the Challenge confirmation button.
:::

+ [未解決】Please make sure the prework is configured in the playground.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JfhRX)

:::note
I managed to complete it by using a combination of the docs, and the instructions for the challenge.  I don't know if you have to put the button and everything, but I did and it worked, just like this doc page shows, except with the property values specified in the challenge.  https://developer.salesforce.com/docs/component-library/bundle/lightning-confirm/documentation
:::

+ [【未解決】I'm trying to complete the Javascript Developer 1 certification maintenance and stuck with the below error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JfALoSAN)
+ [What is the prework that needs to be done for JavaScript Developer 1 maintenance challenge?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000NEUpSSAX)
UIViewRepresentableについて

## はじめに
SwiftUIでUIKitを使用する際に使う「UIViewRepresentable」についてメモします。

## SwiftUIでUIKitを使うには
SwiftUIでUIKitを使うには、**UIViewRepresentableプロトコル**を構造体に準拠させて使用します。
UIViewRepresentableは、UIKitのViewをラップしてSwiftUIで使えるように変換してくれるものです。

## なぜわざわざ変換をする必要があるの？
UIKitのViewを管理するUIViewControllerとSwiftUIのViewは、全く別物のため変換が必要になります。
また、UIkitはSwiftUIが出る前から使用されているフレームワークなので様々な機能やViewが提供されています。ですので、SwiftUIではできないこともUIKitを使用することでアプリ開発の幅が広がります。

## UIViewRepresentableが持つメソッド
### makeUIViewメソッド
makeUIViewメソッドは表示するViewの初期状態のインスタンスを生成するメソッドです。戻り値に使用したいUIKitのViewを返します。
``` swift
    func makeUIView(context: Self.Context) -> Self.UIViewType
```
### updateUIViewメソッド
表示するビューの状態が更新されるたびに呼び出され更新を反映してくれるメソッドです。
``` swift
    func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)
```

## まとめ
今後もおそらく宣言的UIの流れが続くのでSwiftUIのみで全ての機能を実装できるようになるといいなと感じています。
SQLインジェクションとは

SQLインジェクションとは、「外部からSQL文を送信してWebアプリケーションのデータベースを不正に操作して攻撃されてしまう状態のこと（脆弱性）。またはその攻撃」のことです。
主にWebやモバイルアプリケーションのテキストフィールドから不正なSQLを投げられることで成立します。

例えば、WebサイトのID欄に入力値として文字（例として”taro”）が入力され、SQLが実行された時
SELECT * FROM user WHERE id=‘taro’
となり、userという名前のテーブルから、IDがtaroのデータだけが出力されます。

SQLインジェクションを受けた場合の一例は以下のような時です。 ＄IDの部分にtaroに続いて「’ or ‘A’=‘A」を注入（Injection)すると、
SELECT * FROM user WHERE id=‘taro’ or ‘A’=‘A’
となります。WHERE以降の内容としては
①id=‘taro’が成り立つ
”または” (or)
②‘A’=‘A’が成り立つ（’1’=‘1’でも成り立っていれば何でもよい）
→②は必ず成り立つので、①、②トータルとして全て成り立つ →userの全ての情報を出力する
ということになります。
この結果、全てのユーザ情報が漏えいすることになります。
やばいです。userテーブル全てのデータを漏えいさせてしまうことが可能です。

ではどのように対処するかという話ですが、SQLインジェクション対策の一つにプレースホルダーを使うことが挙げられます

あらかじめ同じような質問を何回もDBにするだろうと想定して、SQL文を穴埋めのひな型で作っておきます。穴埋め部は「？」などの特殊文字を仮に入れておきます。
そして「？」などの特殊文字に「user_id」だったりの情報を画面で受け取るようにします。
Xに入力された値をバインド変数といい、ベースのSQL文に仮置きしてある「？」の変動箇所（プレースホルダ）に差し込まれる形でSQL文を生成します。この入力値に悪意ある特殊な記号があっても、単なる値としてデータベースに渡されるため、悪意あるSQL文は作られない、ということです。
SSHでリモートログインした時に、接続元のXサーバーを使うように設定する

# What's？

ふだん、Windows＋Linux（VM）を使っているのですが、SSHでLinux側に入った時にGUIをWindows側に表示したいなということで。

接続元のOSにXサーバーを立てて、LinuxにSSHでログインした際に`DISPLAY`環境変数等を設定するようにしてみます。

# 環境（参考）

- 接続元OS： Windows 10
    - Xサーバー： VcXsrv X Server 1.20.14.0
- 接続先OS： Ubuntu Linux 22.04 LTS

# 設定

`.bashrc`に、以下のように記述しました。

```shell:.bashrc
if [ -n "$SSH_CONNECTION" ] ; then
  export DISPLAY=$(echo $SSH_CONNECTION | awk '{print $1}'):0.0
  export GTK_IM_MODULE=ibus
  export XMODIFIERS='@im=ibus'
  export QT_IM_MODULE=ibus
  export NO_AT_BRIDGE=1
  xset -r 49
  if test $(ps auxw | grep $USER | grep -v grep | grep "ibus-daemon -d -x" 2> /dev/null | wc -l) -eq 0; then
    ibus-daemon -d -x &
  fi
  alias gnome-terminal='dbus-launch gnome-terminal'
fi
```

`SSH_CONNECTION`環境変数が設定されていた場合は、SSHでのログインになるのでこれを利用します。  
また、ログイン元のIPアドレスも`SSH_CONNECTION`環境変数に含まれています。

```shell
  export DISPLAY=$(echo $SSH_CONNECTION | awk '{print $1}'):0.0
```

このあたりは、日本語入力の設定です。

```shell
  export GTK_IM_MODULE=ibus
  export XMODIFIERS='@im=ibus'
  export QT_IM_MODULE=ibus
  export NO_AT_BRIDGE=1
  xset -r 49
  if test $(ps auxw | grep $USER | grep -v grep | grep "ibus-daemon -d -x" 2> /dev/null | wc -l) -eq 0; then
    ibus-daemon -d -x &
  fi
```

この状態にすると、接続元にXサーバーを起動していないとSSHログイン時に応答待ちになってしまうので、その点には注意が必要です。
IT謎解き2 #paiza

## Stage1

### 1

```
U+1F355
```

### 2

```rb
'271176'.tr('781465923', '123456789')
=> "813315"
```

### 3

```py
print('縺薙ｓ縺ｫ縺｡縺ｯ'.encode('shift-jis').decode('utf-8'))
こんにちは
```

```
https://paiza.jp/nazotoki2/Mm5kc3RhZ2U= に移動。
```

## Stage2

### 4

URL

```
606
```

### 5

```
メガネ
```

### 6

HTMLのコメント

```
HELLO NAZOTOKI WORLD
```

### 6.5

リンクが画像の裏に隠されているので開発者ツールからアクセスする

```
https://paiza.jp/nazotoki2/M3Jkc3RhZ2UK
```

## Stage3

### 7

```rb
0x1f355 / 13
=> 9833

cG
```

### 8

応募規約に
プライドを捨ててエントリー
とある

```
ナゾトキ

Fzc
```

画像の「エ」は何の役割があるのか、不明なままである…

### 9

八丈島空港

```
HAC

3dv
```

### 10

辺が奇数本出てるやつ

```
3

cm
```

### 11

```
rm -rf / --no-preserve-root

Rz
```

/の位置を変更すると間違いになってしまうようです…

### 11.5

キーワードをつなげる

```
cGFzc3dvcmRz
```

## Stage4

### 12

モールス

```
パイザ
```

### 13

`convert 'img_riddle13.png' -flip 'img_riddle13_flip.png'`みたくしてからリーダーで読むと https://paiza.jp/nazotoki2/mirror となる。この末尾を反転し https://paiza.jp/nazotoki2/rorrim が正解である。

## Final Stage

### 14

ヒント 14:QRコード、とある。

が、ようわからん。なんか右下をMSBとして読んだら通った。[^1]

```rb
[0b01101100, 0b01100101, 0b01110100, 0b01111010, 0b01110100, 0b01100101].map(&:chr)*''
=> "letzte"
```

[^1]: WikipediaのQRコードを見ると左下がMSBであるように読めるんですよね…
【Python】AWS SAMでLambdaの外部モジュールのバージョンを固定する

# はじめに
外部モジュールを使用するLambdaではモジュールをアップロードする必要があります。
AWS SAMを使うと簡単にソースコードとモジュールを一緒にアップロードする事が可能です。
AWS SAMである関数に久しぶりにdeployを行った時に、モジュールのバージョンを固定する必要がありました。

# やらかし先生
RDSに接続するPythonのLambdaで `pymsql`を使用しています。
RDS接続には関与しない変更を行いデプロイしたところ、RDSへの接続がエラーになりました:scream:

原因としては`pymysql`のバージョンが0.9系から1.0系に変更されていたため、同じ構文では接続が出来なくなっていました。
そのため`pymysql`のバージョンを0.9系に固定する回避策を行いました。

# モジュールのバージョン固定方法
## 結論
**requirements.txt** でバージョンを明記します

```
例 pymysqlを0.9.3のバージョンを指定したい時
pymysql == 0.9.3
```

## 記述方法について
上記の指定方法はAWS SAMに限ったわけではなく、Pythonにおけるrequirements.txtの扱いになります。
指定方法などは以下の記事が参考になりました。

https://note.nkmk.me/python-pip-install-requirements/

# おわりに
更新時の落とし穴になるので、出来る限りバージョンは指定しておきたいなと思いました。
どなたかの助けになれば幸いです。
複数methodをまとめて排他

first,second,thirdをまとめて排他にするときは
別class化(Test)してReentranLockを持たせる。
lockするとunlockするまでlockできない。
Reentrantを共有ため、threadは単一のTestを共有

```java
class Test {
    final ReentrantLock re = new ReentrantLock();
    void lock() {
        this.re.lock();
    }
    void unlock() {
        this.re.unlock();
    }
    void first() {
        System.out.println(Thread.currentThread().getId() + ":1");
    }
    void second() {
        System.out.println(Thread.currentThread().getId() + ":2");
    }
    void third() {
        System.out.println(Thread.currentThread().getId() + ":3");
    }    
    void fourth() {
        System.out.println(Thread.currentThread().getId() + ":4");
    }
}
class Task implements Runnable {
    Test t;
    Task (Test t) {
        this.t = t;
    }
    @Override
    public void run() {
        t.lock();
        t.first();
        t.second();
        t.third();
        t.unlock();
    }
}
class Task2 implements Runnable {
    Test t;
    Task2 (Test t) {
        this.t = t;
    }
    @Override
    public void run() {
        t.lock();
        t.fourth();
        t.unlock();
    }
}

public class Outer {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(3);
        Test t = new Test();
        es.submit(new Task(t));
        es.submit(new Task(t));
        es.submit(new Task2(t));
        es.shutdown();
    }
}
```
```
14:1
14:2
14:3
13:1
13:2
13:3
15:4
```
ArrayListを更新中に参照する

forでlistを読み込み中に、別スレッドでlist addすると
exceptionが発生する
```java
class ReadTask implements Runnable {
    List<String> l;
    ReadTask(List l) {
        this.l = l;
    }
    @Override
    public void run() {
        try {
        for (String str:this.l) {
            System.out.println(str);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
class WriteTask implements Runnable {
    List<String> l;
    WriteTask(List l) {
        this.l = l;
    }
    @Override
    public void run() {
        for (int i=10; i<20; i++) {
            l.add(String.valueOf(i));
            System.out.println("added: " + i);
           try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}
public class Outer {
    public static void main(String[] args) {
        List<String> l = new ArrayList();
        l.add("1");
        l.add("2");
        l.add("3");
        ExecutorService es = Executors.newFixedThreadPool(3);
        es.submit(new WriteTask(l));
        es.submit(new ReadTask(l));
        es.shutdown();
    }
}
```
```
1
added: 10
2
added: 11
java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
	at com.mycompany.mavenproject1.ReadTask.run(Outer.java:21)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
added: 12
added: 13
added: 14
added: 15
added: 16
added: 17
added: 18
added: 19
```
CopyOnWriteArrayListに差し替えると、listのコピーを参照しに行く
結果exceptionが発生しない
コピーをとるタイミングはjvm次第？

```java
List<String> l = new CopyOnWriteArrayList<>();
```
```
1
added: 10
2
added: 11
3
added: 12
10
added: 13
added: 14
added: 15
added: 16
added: 17
added: 18
added: 19
```
Prisma4にアップグレードした際に$queryRawを使用している箇所でTypeError: Cannot mix BigInt and other types, use explicit conversionsが発生する問題

# はじめに
[以前の記事](https://qiita.com/irohafox/items/2d484bbcbf9a023cb524)でPrisma3系から4系にアップグレードする必要があるケースを書いたが、
その際に発生した問題について。

# 環境
- Prisma(before): 3.13.0(<= 3.15.2)
- Prisma(after): 4.8.0(>= 4.0.0)
- Provider：MySQL

# 概要
あるテーブルのレコード件数を`$queryRaw`で取得してレコード件数+1をログに出力する場合、一例ではあるが以下のように書くことができる。
```ts
const result = await this.prisma.$queryRaw<
  { count: number }[]
>`SELECT COUNT(*) AS count FROM users`
const count = result[0].count

console.log('count + 1 =', count + 1)
```
仮にusersテーブルに1,000件のレコード数が存在すれば以下のように何の問題もなく出力される。
```
count + 1 = 1001
```
しかし、Prisma3系(<= 3.15.2)から4系(>= 4.0.0)にアップグレードすると、
上記の実装はTypeErrorが発生してしまう。
```
TypeError: Cannot mix BigInt and other types, use explicit conversions
```
なぜにBigInt？となったがとりあえずcountの値と型を確認してみる。
```typescript
console.log('count:', count)
console.log('typeof count:', typeof count)
```
```log
count: 1000n
typeof count: bigint
```

確かにBigIntになっている。

ということで[Prisma4のアップグレードガイド](https://www.prisma.io/docs/guides/upgrade-guides/upgrading-versions/upgrading-to-prisma-4)を確認してみると、
[queryRawが返却するスカラー値の型に関する仕様変更](https://www.prisma.io/docs/guides/upgrade-guides/upgrading-versions/upgrading-to-prisma-4#raw-query-type-mapping-scalar-values-are-now-deserialized-as-their-correct-javascript-types)が明記されていた。

`$queryRaw`で取得したスカラー値をJSの対応する型にデシリアライズするように変更された模様。
![スクリーンショット 2023-01-24 11.41.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1689782/6e14d8c4-c762-bd10-bf50-93487e5d3c7c.png)
`Int64`の返却型が`Integer`から`BigInt`になっている。

# 対応
queryRawのジェネリクスパラメータを`{ count: bigint }[]`に変更し、
代入時にNumberコンストラクタでNumber型(数値型)に変換する。
```typescript
const result = await this.prisma.$queryRaw<
  { count: bigint }[]
>`SELECT COUNT(*) AS count FROM users`
const count = Number(result[0].count)

console.log('count:', count)
console.log('typeof count:', typeof count)
console.log('count + 1 =', count + 1)
```
```
count: 1000
typeof count: number
count + 1 = 1001
```
無事、Prisma3系を使用していた際に期待していた出力結果と同じ出力結果を確認できた。

ただし、当然のことながら`$queryRaw`で取得したBigInt型(長整数型)のレコード件数が、
Number型(数値型)で扱える範囲を超えてしまっている場合には精度が落ちるので注意を。

# まとめ
Prisma3系(<= 3.15.2)から4系(>= 4.0.0)にアップグレードする際、
`$queryRaw`を使用している箇所には注意しましょう。

本記事では単純な加算処理を例に挙げたが、
実際にこの問題に直面したケースではGraphQLのEntityにマッピングする箇所で発生したので、
アプリケーションのアーキテクチャ全体に関わる問題かと思いひやっとした。

# 参考
https://www.prisma.io/docs/guides/upgrade-guides/upgrading-versions/upgrading-to-prisma-4

# 関連
[Prismaで新規レコード作成時に@default(now())なカラムと@updatedAtなカラムに差異が生じる問題](https://qiita.com/irohafox/items/2d484bbcbf9a023cb524)
[個人用メモ]Three.jsのパフォーマンスのススメ#1

# はじめに
ワールドスケールとレイヤースケールについて考えます。
特定のワールドの広さを任意のグリッドを引き、グリッドごとにレイヤーで描画管理することで、
最適な表示非表示を切り替えます。
カメラの位置をレイヤーから特定のレイヤーまで長さを考える

# 途中作成
```javascript
const l = 3;// 監視グリッドエリア範囲
const g = 8;// グリッド数
const n = 28;// 現在レイヤー
const r = n % g;// 現在レイヤーの列番号
const c = Math.ceil(n/g);// 現在レイヤーの行番号

const layers = [n];// 表示レイヤー

[...Array(l)].map((_, idx) => {
    const i = idx + 1;
    // 中心
    layers.push((c -1 - i)*g + r);
    layers.push((c -1 + i)*g + r);
    layers.push((c -1)*g + (r - i));
    layers.push((c -1)*g + (r + i ));
    
    // 周辺
    [...Array(l - i)].map((_none, _idx) => {
        const _i = _idx + 1;
        layers.push((c-1 - _i)*g + (r - _i ));
        layers.push((c-1 + _i)*g + (r - _i ));
        layers.push((c-1 - _i)*g + (r + _i ));
        layers.push((c-1 + _i)*g + (r + _i ));
    });
    
});

console.log("Length: ", layers.length);
console.log(layers);
```
【Vue3】 transition-groupをtableで使う方法の忘備録

単純にtbodyのattrをこうする。

    <tbody is="vue:transition-group" name="list" tag="tbody">

## is="vue:transition-group" と tag="tbody"
tbodyに一回「transition-group」を認識させて、
またtag="tbody"に戻してる。
tableタグ構成を変にタグを入れると、うまく行かないのでこれでいける。


## name="list"
nameはアクション。
今回はlistにしてるので

【taiwindやと】※@applyつかってるよ

    .list-enter-active,
    .list-leave-active { @apply transition duration-300 ease-out;}
    .list-enter-from,
    .list-leave-to { @apply opacity-0 transform translate-x-20;}


【css/sassやと】

    .list-enter-active,
    .list-leave-active {
        transition: all 0.3s ease;
    }
    .list-enter-from,
    .list-leave-to {
        opacity: 0;
        transform: translate-x-20;
    }


忘れないように忘備録。

これにDraggableとかdrag&dropが使えたら最強なんやけど、
いいのあるよーってかた教えてください。
macOSで特定のアプリの言語設定を変更する方法

# 結論
これだけです。

```
defaults write com.microsoft.Word AppleLanguages '(ja)'
```

`com.microsoft.Word` の部分は任意のアプリのBundle IDを指定します。
Bundle IDの調べ方は以下のとおりです。

```
osascript -e 'id of app "Word"'
```

`Word` の部分は `Excel` とか `iTerm` とか任意のアプリ名を指定します。
ECS Execを使ってコンテナにアクセスする手順

## 前準備

#### 1. session-manager-puginのインストール

[(オプション) AWS CLI 用の Session Manager プラグインをインストールする](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)

#### 2. タスクのIAMロールにSSMエージェント実行用ポリシーをアタッチ

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}
```

#### 3. 下記コマンドを実行

```bash
aws ecs update-service --region ap-northeast-1 --cluster ${ECS_CLUSTER_NAME} --service ${SERVICE_NAME} --enable-execute-command
```

#### 4. タスクを再起動する（現在起動中のタスクには`ecs exec`できない）

```bash
aws ecs update-service --force-new-deployment --cluster ${ECS_CLUSTER_NAME} --service ${SERVICE_NAME}
```

### 注意点

- `aws ecs update-service`後、タスク再起動の必要あり。古いタスクは`ecs exec`できない
- リードオンリーなコンテナにはそもそもアクセスできない

## いざコンテナにアクセス

```bash
aws ecs execute-command --cluster ${ECS_CLUSTER_NAME} --task ${TASK_ID} --interactive --command "bin/sh"
```

## うまくいかないとき

[amazon-ecs-exec-checker](https://github.com/aws-containers/amazon-ecs-exec-checker)を使って原因調査する。うだうだ原因調査するよりこれが一番早い。

```bash
git clone https://github.com/aws-containers/amazon-ecs-exec-checker.git
cd amazon-ecs-exec-checker
./check-ecs-exec.sh <YOUR_ECS_CLUSTER_NAME> <YOUR_ECS_TASK_ID>
```

使用条件：
- jqがインストール済みであること
- aws cliがインストール済みであること
プリザンターにもショートカットキーはあります！

 # はじめに
いちいち保存ボタンや作成ボタンをクリックするのは面倒ではありませんか？業務上、レコードを作成したり更新したりすることが多いのですが、ショートカットキーはないのかなぁと探したらありました！この記事では一覧形式でショートカットキーをご紹介します！

 # ショートカットキー一覧
ショートカットキーはaltキーで操作するんですね！Windowsでは何かとctrlキーを多用するので、慣れていかないといけません！しかし、慣れればさらに楽々作業になりますね！
|操作|キー|新規作成画面|編集画面|一覧画面|サイト設定画面|
|:----|:----|:----|:----|:----|:----|
|上位の画面に戻る|alt + q|-|-|-|-|
|戻るボタン|alt + q|〇|〇|〇|〇|
|作成ボタン|alt + s|〇|-|-|-|
|更新ボタン|alt + s|-|〇|-|〇|
|コピーボタン|alt + c|-|〇|-|〇|
|参照コピーボタン|alt + k|-|〇|-|-|
|移動ボタン|alt + o|-|〇|-|-|
|一括移動ボタン|alt + o|-|-|〇|-|
|メールボタン|alt + m|-|〇|-|〇|
|削除ボタン|alt + r|-|〇|-|-|
|一括削除ボタン|alt + r|-|-|〇|-|
|サイト削除ボタン|alt + r|-|-|-|〇|
|インポートボタン|alt + w|-|-|〇|-|
|エクスポートボタン|alt + x|-|-|〇|-|
|一括更新ボタン|alt + s|-|-|〇|-|
|前ボタン|alt + b|-|〇|-|-|
|次ボタン|alt + n|-|〇|-|-|

 # 参考資料

https://pleasanter.org/manual/shortcut
Edgeブラウザで自動で表示されるマスクアイコンを非表示にする方法

## 目次
1. はじめに
1. 解消方法
1. 最後に


## はじめに
テキストボックスのマスク表示をONにしている場合、
WindowsのMicrosoft Edgeブラウザで表示すると  
デフォルトで以下のようなマスクアイコンが表示されてしまいます。


TextBoxのMask Text設定をONにすると（↓）
![スクリーンショット 0005-01-24 11.22.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/78678a91-50f9-0535-f18a-82d8c696fafe.png)

Microsoft Edgeブラウザでマスクアイコン（目のアイコン）が表示されてしまう（↓）
![image (4)のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/a5ff2075-5f59-e52a-397c-341f0e86589f.png)

Iris側で別途マスクアイコンを設定していると、
Edgeブラウザの場合デフォルトで表示されるアイコンと被ってしまうため、
今回はEdgeでマスクアイコンを非表示にする方法を説明したいと思います。


## 解消方法

早速解消方法を説明します！

下記のコードをカスタムCSSかProject Settingに設定しましょう。

```
::-ms-reveal {
    display: none;
}
```

1つのWidgetに対して適用させたい場合は、Custom CSS、
画面全体に適用させたい場合はProject Settingsで設定を行ってください。


＜補足＞
Custom CSSは、対象のWidgetを選択した状態で、
PROPERTIES->Skin->Custom CSSにチェックを入れることでCSSの設定が可能です。

![スクリーンショット_0005-01-24_11_16_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/305aadae-de9f-8c64-6563-59c74b5443ea.png)


カスタムCSSに関する詳細は以下の記事をご参考ください。

https://qiita.com/Kony_Team/items/70b3230456c3c3433804#4-custom-css%E3%81%AE%E8%A8%AD%E5%AE%9A


今回は画面全体にマスクアイコンが表示されないようにしたいため、
Project Settingsに設定を行います。

![スクリーンショット 0005-01-24 11.02.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/5c497414-4e11-386a-18dd-bd59502089de.png)

設定できたら完了です。

早速動作を見てみましょう！

![ezgif-2-d902424eda.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/5eda8c8a-0c90-1575-9bd4-de16f557aa2a.gif)

テキストボックス内に文字を入力してもマスクアイコンが表示されなくなりましたね！

## 最後に
今回はMicrosoft Edgeでマスクアイコンがデフォルトで表示されてしまう場合の解消方法についてご紹介しました。
参考になれば嬉しいです！

## 参考
https://learn.microsoft.com/en-us/microsoft-edge/web-platform/password-reveal
空白区切りのファイルをcsvに変換 (sed, awk)

空白(複数個)区切りのテキストファイルをcsvに変換したときのメモ。
- 目標 
```text:sample.txt
 -0.02223544   0.36483891 -1.16350713

  1.72316747  -1.4276687   0.91534189

  0.47763427  -0.52007756  0.91546411
```
を
```text:sample.csv
0.36483891,-1.16350713
-1.4276687,0.91534189
-0.52007756,0.91546411
```
に変換する
- コマンド
複数個の空白を`,`に置換した後、先頭の`,`を消し、空行を消し、2列目と3列目を取り出す。

GNU版のsedの場合:
```bash
sed -e 's/ \+/,/g' -e 's/^,//g' -e '/^$/d' sample.txt | awk -F',' -v 'OFS=,' '{print $1,$2}' > sample.csv
```
BSD版のsed: 
```bash
sed -e 's/ \{1,\}/,/g' -e 's/^,//g' -e '/^$/d' sample.txt | awk -F',' -v 'OFS=,' '{print $1,$2}' > sample.csv
```
【MySQL】AWSのRDSでDBを作成したのでMySQL Workbenchで操作する

## MySQL Workbenchとは？？
`MySQL Workbench は、データベースアーキテクト、開発者、DBA のための統合ビジュアルツールです。MySQL Workbench は、データ・モデリング、SQL 開発、およびサーバー設定、ユーザー管理、バックアップなどの包括的な管理ツールを提供します。`
DBをGUI操作できます。
ダウンロードは[こちら](https://www.mysql.com/jp/products/workbench/)から

## 作成している環境
DB→AWS RDS MySQLを選択
踏み台サーバーとしてEC2を作成して、EC2経由でMySQLを操作できるようになっている

## 操作してみる
1\. DBに接続
①Standard TCP/IP over SSH　を選択
②踏み台サーバーとして作成したEC2のパブリックIPを入力
③Usernameはec2-user
④Key FileはRDS作成時に作成したpemファイルなどのキーファイル
⑤RDSのエンドポイント
⑥ログインするためのパスワード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/ae12efc0-0228-8b78-963c-7b24d4067d0c.png)

2\. DBの作成
左側の空白を右クリックし、Create Schema
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/5af4dec0-7a9f-24f3-ec26-fd636b6f0bd4.png)

今回はschema nameをotameshiとして下のApplyをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/266558e4-9193-6c49-891b-077dfdc282da.png)

3\. テーブル作成
今回はテーブルを2つ作成します。
employeeとresionを作成します。

下のCreate tableをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/aab3483a-2ae6-80de-fd9b-d43d2dc6afff.png)

Table Nameにテーブル名を入力して、その下にカラム名を入力していきます。
その際、PKやNNを設定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/5a5d018b-8a18-cafe-47b4-d735b31b82d3.png)

今回作成したテーブル↓
employee
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/2e29decb-d0a9-1c90-656e-0ad804fd1f5a.png)

resion
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/4300a7e2-c1b2-b4e7-f4d8-3cc21403d84c.png)

4\. データの挿入
下の赤丸のところをクリックしてemployeeにデータを入力していきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/be8a1c0e-34fe-0e44-50f9-fe240c71fad7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/bf7b188d-adb2-7359-9f35-d7100ce5f261.png)

resionは以下のような感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/4553ea7b-fe7e-7b7b-9712-08c025cf9272.png)

5\. 外部キーの設定
外部キーを設定していきます。
外部キーは下のタブのForeign Keyで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/777985b2-d8f1-b1b8-be37-20ad785c53ee.png)

Referenced tableに参照先のテーブルReferenced Columnに参照カラムを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/38d20daf-cb69-5671-2e0e-8e016992c881.png)

6\. EC2サーバーで確認
EC2サーバーから確認していきます。

`mysql -h {RDSエンドポイント} -P 3306 -u {設定した管理者の名前} -p`を入力してログイン
`use otameshi`でデータベースに移動
`show create table employee`で中身確認

↓

```
employee | CREATE TABLE `employee` (
  `id` int NOT NULL,
  `name` varchar(45) NOT NULL,
  `resion` int NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_resion_id_idx` (`resion`),
  CONSTRAINT `fk_resion_id` FOREIGN KEY (`resion`) REFERENCES `resion` (`resion_id`)
```
テーブルの中身が確認できました。

MySQL workbenchからRDSにDBのひな型的なものをつくることができました。