OmniAICreator/Qiita-1.07M huggingface dataset:
JPEG の解像度 DPI 値うんちく


JPEG 画像ファイルはメタデータとして解像度(Resolution もしくは Density)値を DPI単位もしくはcm単位で保持できます。そのうんちくです。

# JPEG 解像度について

スキャナで映像を取り込んだ時やスクリーンショットで JPEG 保存した時など、
対象の物理的大きさを元に算出した DPI 値を JPEG ファイルに含める事が多いです。
スキャナだと 200 や 300、スクリーンショットは 72 や 144 が代表的な値です。
ベクター画像から JPEG に変換する場合だと 37 をよく見かけます。

とりあえず JPEG のメタデータを見るツールを作ってみました。JPEGファイルをドロップしてお試し下さい。

- https://yoya.github.io/image.js/jpegmeta.html

JavaScript でローカルに動くので、サーバにアップロードしません。

# JFIF 規格

JPEG の歴史的に解像度はまず JFIF marker に実装されました。
JPEG チャンクでいう APP0 です。

-  https://www.w3.org/Graphics/JPEG/jfif3.pdf

|  |  |  |
|---|---|---|
|units|  (1 byte) | Units for the X and Y densities.   <br />  units = 0: no units, X and Y specify the pixel aspect ratio  <br />  <br /> units = 1: X and Y are dots per inch  <br /> units = 2: X and Y are dots per cm  |
| Xdensity | (2 bytes) | Horizontal pixel density |
| Ydensity | (2 bytes) | Vertical pixel density |

見ての通り、横方向の解像度と縦方向の解像度を別で表現します。

units によって Xdensity, Ydensity の意味合いや単位が変わります。

## units: 0 (aspect ratio)

units:0 の場合は、ピクセル(またはドット)の縦横比 aspect ratio を表す値になります。
つまり解像度(Resolution/Density)ではありません。無単位です。
具体的にはピクセルの物理的サイズが正方形の時は 1:1 が入ります。

```
The JFIF APP0 marker provides information which is missing from
the JPEG stream: version number, X and Y pixel density
(dots per inch or dots per cm), pixel aspect ratio
(derived from X and Y pixel density), thumbnail.
```

PCモニタは正方形ですが、昔のご家庭テレビや映画フィルム等は少し長方形で、これらに対応する規格のようです。

## units: 1 (dots per inch, DPI) 

units: 1 だと 72:72 や 200:200 といったおなじみの DPI 値を入れる事ができます。

## units: 2 (dots per cm)

こちらは cm 単位です。おなじみ国際単位系 (SI) ですね。
ヤードポンド系死すべしって時に使います。

## units の実情

実際には units:0 のまま DPI を入れる処理系もあったりで混乱させられます。
DPI の値は x:y の比率でもあるので一応仕様通りで、約分が面倒でそのまま入れてるのかもしれません。
具体的にいうと macOS スクリーンショットですが、これは Exif にも DPI 値を残してるので。そちらを見れば良いです。

# Exif 規格

上記のように JFIF に DPI 解像度を入れない事があり。DPI が大事な時は JPEG に Exif をつけて解像度を含める事が多いです。

JPEG チャンクの APP1 です。

- https://www.cipa.jp/std/documents/j/DC-008-2012_J.pdf

|タグ名称 | Field Name | タグ番号Dec | Hex | タイプ | カウント |
|---|---|---|---|---|---|
| 画像の幅の解像度 | XResolution | 282 | 11A | RATIONAL | 1 |
| 画像の高さの解像度 | YResolution | 283 | 11B | RATIONAL | 1 |

ただ、Exif は JPEG ファイルサイズ削減で消される筆頭なので、

- JFIF に aspect ratio でなく DPI で入れる
- Exif の全部を消さず resolution だけ残す
- Exif を strip する時に JFIF に反映してくれる神プログラムを探す。☜ ImageMagickとか！!
- DPI を諦める、(Web 表示用なら DPI あまり関係ないですし)

といった判断に迫られるでしょう。

## 72 DPI

Exif の規格書には以下のように書かれています。

```text:
ImageWidth 方向の 1 ResolutionUnit あたりの画素数。画像の解像度が不明のときには
72[dpi] を記録しなければならない。 
```

```text:
画像の幅と高さの解像度の単位
ResolutionUnit XResolution と YResolution の単位系。
XResolution、YResolution と一緒に用いる。
画像の解像度が不明のときには 2(インチ)を記録しなければならない。
```
つまりインチ単位で 72 が入っている時は文字通りの 72DPI とは限らないようです。
特殊な値として覚えておくと良いかもしれません。

# そもそも論

そもそも JPEG の resolution DPI値は実用上、あまり意味がないので気にしない。というのも手です。

JPEG ファイルを PDF に包まず単体でプリンタに送ってしまうとか、macOS 標準プレビューで開く時に、DPI によって表示サイズが違う。みたいな影響はありますが、それらにこだわる状況はあまりないでしょう。

でもって、こだわる時は処理フロー全体で真面目に拘りましょう。頑張って。٩( 'ω' )و
Arduinoを使ってみた記事

# この記事について
部内講習用の記事です。
ロボットを開発する上で欠かせない「マイコン」の勉強になればと思い
Arduino(アルディーノ)について自分なりに解説してみました。（自分も未熟なので間違ってたらごめんなさい。）

# 環境構築
|OS|Windows10|
|:-:|:-:|
|使用|Arduino IDE 2.0.4|

まずは、環境構築。
プログラミングを書く上ではエディターは欠かせませんよね。
てことで[こちら](https://www.arduino.cc/en/software)からArduinoIDEをダウンロードします。

サイトに飛んだら**Windows10 and newer, 64 bits**をクリック
すると「Arduinoを支援してね」みたいなページが出るので
**JUST DOWNLOAD**をクリック

なにやら～～.exeみたいなのをダウンロードすることができたと思います。

これはEXEファイルと呼ばれるものでダブルクリックで実行できる
ソフトウェアをインストールするプログラム？のようなものです。（説明下手でごめんなさい）

実行したら色々聞かれると思うので、何もさわらずに「次へ」「インストール」
をクリックしましょう。
![スクリーンショット (98).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119891/a308c7a9-c334-5157-c7bb-00849b0c8f9f.png)
このような画面が出るはず。
これで環境構築は完了です

# 使ってみる
### はじめに
使うマイコンはArduino Nano Every。
さっそくArduinoIDEを開いて見るとすでになにかが書かれています。
```python:sketch.ino
void setup(){
}
```
まずsetupのあとの｛｝の中にはプログラムの実行時にのみ処理させたいことを書きます。
```python:sketch.ino
void loop(){
}
```
次にloopのあとの｛｝の中には実行後繰り返される処理が書かれます。

### Lチカしたい
今回は「Lチカ」するプログラムを書きたいと思います。
つまりはArduino本体についたLEDをチカチカさせます。

必要な処理は
光らしたいLEDの宣言
点灯
消灯
といった感じでしょうか。
#### 光らしたいLEDの宣言
まずどのLEDなのかを教える必要がありますよね。
Arduinoではこのように書きます。
```c:led_test.ino
//pinMode(つかいたいpin, オプション)
pinMode(LED_BUILTIN, OUTPUT);
```
ArduinoではpinModeというのを使って指定することができます。
今回はLED_BUILTIN（Arduino本体のLED）にたいしてOutPut（出力）します。
この処理は実行時にのみ実行されればよいのでsetupのなかに入れます。

#### 点灯　消灯
```c:led_test.ino
 digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
```
なにやらふたつ新しい関数が出てきてますね。
それぞれ
>digitalwrite(pinの名前, HIGH or LOW)
出力する関数です。
５V出力するHIGHと０VにするLOWの処理が行えます。

>delay(ms)
ディレイと聞いたらゲームで聞いたことがある人もいるのではないのでしょうか
待ち時間を用意します。かっこの中に何秒待つかを入れます。（単位は1/1000秒）

こちらは繰り返したいのでloopに入れましょう。

### 完成
全体はこのようになりました。
```c:led_test.ino
void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}
```
このコードで
1秒点灯→1秒消灯
を繰り返すことができます。

# 最後に
今回はArduinoの基本にふれてみました。
プログラミングは基本tryとerrorの繰り返しなので私も
勉強を続けたいと思います。
java初心者が行く～クラスとインスタンス_1～

# はじめに
初心者が備忘録的な感じで書いています．
間違ったことを書いてしまっていたらごめんね！
# クラスとインスタンス
クラスとは簡単に言えばインスタンスを生み出す物のこと．
~~クラス＝金型，インスタンス＝金型の形に作った金属的なイメージ．~~
以下コメント引用
イメージとしては，クラス＝たいやきの金型，インスタンス＝焼き上がったたいやきそのもの．
他の例えだとクラスは概念でインスタンスは実物．
国語辞書に載っている猫という言葉が定義クラスで実物の猫がインスタンス．
（instanceという英語からきているらしい）
初心者の理解としてはこんな感じでしょうかね（~~合っている保証はしないがな！~~）

# クラスの定義
クラスにはクラスの属性を書ける！！！
クラスの定義はざっとこんな感じ
(クラスの最初の文字は大文字にしよう！暗黙の了解らしい)
```java
public class Hogehoge{
    //sampleの属性を書ける
}
```

もう少しイメージしやすくすると，今回はSelfIntroductionというクラス名なので，
適当に年齢と名前の属性でも付けておきましょう．
```java
public class SelfIntroduction{
    //sampleの属性を書ける
    int age;
    String name;
}
```
こんな感じ．
更にクラスには動作の宣言も書ける．
~~c言語で言うと関数みたいな感じかな？~~

```java
public class SelfIntroduction{
    //sampleの属性を書ける
    int age;
    String name;
    public void hello(){
        this.age = 24;
        this.name = hogehoge;
        System.out.println(this.name + "です." + age +"歳です");
    }
}
```
動作の宣言は何個でもかける．
また，関数みたいに引数を受け取ることもできる.

```java
public class SelfIntroduction{
    //sampleの属性を書ける
    int age;
    String name;
    public void Introduction(){
        this.age = 24;
        this.name = hogehoge;
        System.out.println(this.name + "です." + age +"歳です");
    }
    public void hello (String your_name){
        System.out.println(your_name + "さんこんにちは");
    }
}
```
クラスの定義はこんな感じ．
次はMainからクラスを呼び出してインスタンス化しよう！
ってところで良い時間なので続きはまた後日，，
早く寝て明日に備えよう，，，
AWSについて簡単に解説してみた②(学習まとめ)

今回は「AWS Lambda」を中心としたwEBアプリ(＝Webシステム＆Webサーヴィス)の構成について解説していきたいと思います。

初めに、「Amazon API Gateway」は、ユーザーから送られるHTTPリクエストを受け付けて、これを「AWS Lambda」に引き渡します。

ここで、AWSでは、データは「バケット」と呼ばれる単位で取り扱います。さらに、これを大きくした単位に「データレイク」と呼ばれるものがあります。たとえば、「AWS Lambda」においては、入力されたデータを一旦バケットに入れて、バケットの中身を関数が取り出して、これを処理します。そして、これを最終的にデータレイクに移します。
※この際に扱われるデータの形式は、(どうやら)Jsonが一般的なよう。

また「Amazon EventBridgh」を用いることで「Lambda」の関数を定期実行させることができるので、目的の時刻にWebサーヴィスを起動したり、目的の時刻にサーヴィスを停止させるといったことが可能です。

そして「DWH,Data-Ware=House」は、比較的、事前処理(＝整理・分類)されたものを蓄積・保管する場所として用いられますが、先に出したデータレイクは事前処理のなされていないデータを蓄積・保管する場所として用いられます。

ちなみに、オンプレミスからAWSへとクラウド移行をする際には、通常、システムを二重化して構成(＝サブネット化)します。たとえば、Webサーヴァー(＝EC2)とDBサーヴァー(＝RDS)を２台ずつ用意するようにです。

また、サーヴァー負荷を分散させるためにはロードバランサーである「ELB,Elastic-load-Balancer」を用います。

最後に、AWSでは、通常、全てのサーヴァーインスタンスをプライヴェイト―ネットワークでつなぎますが、「ENI」(＝Praivate-Link)」を介することで外部のパブリック―ネットワークとの接続もできます。この際に用いられるのが「Amazon Kinesis」です。

いかがでしたしょうか。
何せAWSは、Webアプリの技術要素をテンコ盛りしたものなので、中々一本の記事にはまとめられず、少々、筆者としては心苦しいのですが、皆さんのお役に立てるような記事を書きたいと思うので、今後ともお付き合いくださると嬉しいです。
それではまた～。
【Angular Material】Dialogからのイベントを親コンポーネントで検知

# 問題

[Angular MaterialのDialog](https://material.angular.io/components/dialog/overview)には `close` メソッドが存在し、これが叩かれたとき呼び出し元コンポーネント(親コンポーネント)ではafterClosedでダイアログからの値を取得することができます。

```ts
/** --- 親コンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleParentComponent implements OnDestroy {
  subscription = new Subscription();
  constructor(public dialog: MatDialog) {}

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  onClickOpenDialogButton(): void {
    const dialogRef = this.dialog.open(ExampleDialogComponent, {
      data: {...},
    });

    this.subscription.add(
      dialogRef.afterClosed().subscribe(result => {
        /** closeに渡された値を取得可能 */
      });
    );
  }
}

/** --- ダイアログコンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleDialogComponent {
  constructor(
    public dialogRef: MatDialogRef<ExampleDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData,
  ) {}

  onClickCloseButton(): void {
    this.dialogRef.close(/** params */);
  }
}
```

ではダイアログを閉じずに値を親コンポーネントに渡すにはどうしたらいいのでしょうか？

# 解決法

[EventEmitter](https://angular.jp/api/core/EventEmitter)を用います。

```ts
/** --- 親コンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleParentComponent implements OnDestroy {
  subscription = new Subscription();
  constructor(public dialog: MatDialog) {}

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }

  onClickOpenDialogButton(): void {
    const dialogRef = this.dialog.open(ExampleDialogComponent, {
      data: {...},
    });

    this.subscription.add(
      dialogRef.componentInstance.emitter.subscribe(result => {
        /** emitが走ったときの処理 */
      })
    );

    this.subscription.add(
      dialogRef.afterClosed().subscribe(result => {
        /** closeに渡された値を取得可能 */
      });
    );
  }
}

/** --- ダイアログコンポーネント --- */
@Component({
  selector: '...',
  templateUrl: '...',
})
export class ExampleDialogComponent {
  @Output() emitter = new EventEmitter<T>();

  constructor(
    public dialogRef: MatDialogRef<ExampleDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData,
  ) {}

  onClickEmitButton(): void {
    this.emitter.emit(/** params */);
  }

  onClickCloseButton(): void {
    this.dialogRef.close(/** params */);
  }
}
```

MatDialogRefには[componentInstance](https://material.angular.io/components/dialog/api#MatDialogRef)プロパティが存在し、これを用いることでダイアログコンポーネントにアクセスできます。
また、[EventEmitter](https://angular.jp/api/core/EventEmitter)にはsubscribeが生えており、emitされたときに配信されます。
この二つを組み合わせることで、ダイアログ上からcloseすることなく親コンポーネントに値やイベントを送ることができるというわけです。

# 参考

- [angular/components#3593](https://github.com/angular/components/issues/3593)
生成AIを使うときに知っておきたいこと――日本ディープラーニング協会（JDLA）が発表したガイドラインのポイント

# 生成AIの利用ガイドライン

日本ディープラーニング協会（JDLA）が公開した『生成AIの利用ガイドライン』についてポイントをまとめます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31402/d770c4b3-2dd3-0473-cf63-5b3efaa505f4.png)

https://www.jdla.org/document/#ai-guideline

生成AIとは、人工知能（AI）が自動的に文章や画像などのコンテンツを生成する技術のことで、対話型AIや画像生成AIなどがあります。

生成AIの利用ガイドラインは、生成AIを活用する組織がスムーズに導入できるように、注意すべき事項や参考事例をまとめたものです。

利用ガイドラインは、以下の2つのパートで構成されています。 

## データ入力に際して注意すべき事項

データ入力に際して注意すべき事項として、次の6つの項目が挙げられています。  

- **第三者の著作権を有するデータ**
- **登録商標・意匠**
- **著名人の顔写真や氏名**
- **個人情報**
- **他社から秘密保持義務を課されて開示された秘密情報**
- **自組織の機密情報**

これらのデータを生成AIに入力すると、法的な問題や信頼性の低下などのリスクが生じる可能性があります。  

## 生成物を利用するに際して注意すべき事項

生成物を利用するに際して注意すべき事項として、次の5つの項目が挙げられています。  

- **生成物の内容に虚偽が含まれている可能性がある**
- **生成物を利用する行為が誰かの既存の権利を侵害する可能性がある**
- **生成物について著作権が発生しない可能性がある**
- **生成物を商用利用できない可能性がある**
- **生成AIのポリシー上の制限に注意する**

これらの事項に留意しないと、法的な問題や信頼性の低下などのリスクが生じる可能性があります。  

利用ガイドラインは、JDLAの公式ホームページから無料で[ダウンロード](https://www.jdla.org/document/#ai-guideline "jdla")できます。

また、利用ガイドラインは技術や業界動向に合わせて柔軟にアップデートされる予定のようですので、定期的にチェックしましょう。
【Rails】ToDoコメントを残しておいて一覧形式で表示する方法

ソースコードを書いている時、または、既存のソースコードを読んでいる時、こんな風に思うことがあります。  
- ここバグってる。ToDoとして残しておいて後で対応しよう
- 冗長だな…。後で最適化しよう

こんな時に、ソースコード内にコメントを入れておいて、後で一覧形式で表示しようというのが今回の内容です。  

> Visual Studio Codeなど横断検索できるエディタを使っていれば、エディタの検索機能の方が楽かもしれません。  
> チーム開発で共通的な取り決めとして、またはRailsの小ネタとして、書きたいと思います。  

## バージョンと試行した環境
- Ubuntu 22.04.2 LTS
- Rails 7.0.4.2

## Railsのソースコードにコメントを残す
コメントは、標準で以下の3つが用意されています。
```ruby
# TODO:
# FIXME:
# OPTIMIZE:
```

`TODO`はその名の通り、後で対応したい箇所に対して残します。  
`FIXME`は例えば優先順位が高い箇所に対して残します。  
`OPTIMIZE`は動作を維持したまま最適化したい箇所に対して残します。  

コメント例としては、自分はこんなイメージで残しています。
```ruby
# TODO: このチェックは必要？設計を確認
# FIXME: 次の○○対応時に合わせて対応が必要
# OPTIMIZE: 余計な繰り返しをしているので要最適化
```

## 残しておいたコメントを一覧形式で表示する
railsコマンドを使って一覧表示できます。  
```terminal
$ bin/rails notes

app/models/user.rb:
  * [182] [TODO] このチェックは必要？設計を確認
  * [236] [OPTIMIZE] 余計な繰り返しをしているので要最適化

app/controllers/users_controller.rb:
  * [ 98] [FIXME] 次の○○対応時に合わせて対応が必要
```

## 検索対象とディレクトリ
`bin/rails notes`コマンドによって検索されるディレクトリは`app、config、lib、bin、test`  
検索対象となるファイル拡張子は`.builder、.rb、.rake、.yml、.yaml、.ruby、.css、.js、.erb`です。
CKA試験、Trouble Shooting

# Trouble Shooting

## 確認方向
1. Dockerが動いているのか確認する
1. Kubeletが動いているのか確認する
1. Cniが動いているのか確認する



```sh
systemctl status docker
systemctl enable --now docker
```

```sh
systemctl status kubelet
systemctl enable --now kubelet
```

# 今から、永久的に動くように
```sh
systemctl enable --now ~~~
```
docker, docker composeコマンドの整理

## はじめに

これまでに使ったことのあるdockerコマンドの整理をします

## キーワード

docker, docker compose, makefile


## dockderコマンド

- build
    - イメージを作成する
- run
    - イメージを元に、コンテナを作成し、起動する
        - 以下のコマンドの合成である
        - 作成: docker create
        - 起動: docker start
- exec
    - 既に起動しているコンテナでコマンドを打てるコマンド
- ps
    - 起動中のコンテナの情報をえる
        - IDとか名前とかポート番号とか
- volume ls
    - volumeを一覧する
    - ここで注意すべきは設定ファイルできちんとvolumeの名前を指定しておかないとデフォルトではハッシュ値になる
- image ls
    - imageを一覧する

## docker composeコマンド

- build
    - docker buildを複数コンテナに
- up
    - 起動
- down
    - 落とす
- ps
    - docker psと実質変わらないが、docker-compose.ymlファイルで設定した内容が見れる
- logs
    - logがたくさん見れる

以上
Google Colaboratoryで上書きしたノートブックを以前のものに復元したい

# 結論
変更履歴を使用することで復元可能です。

# 前提
2023年5月9日時点のGoogle Colaboratoryの操作となります。

# 手順
1. 復元したいノートブックを開きます。
![変更履歴01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/fbb869a2-db85-b1cd-fb1b-85617b6f8f6a.png)
1. メニュー上部にある「ファイル」をクリックします。
![変更履歴02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/9072e99d-51a5-47f7-1a6b-4e72359ed8a4.png)
1. メニューに表示された「変更履歴」をクリックします。
![変更履歴03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/edb66046-ece8-631a-2c97-b63af5574e5e.png)
1. ダイアログ左部に過去に変更された履歴が時系列に表示されます。
 ラジオボタンで選択したものが左右それぞれダイアログ右部に表示されるため、復元したい履歴を探します。
![変更履歴04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/d64244bf-0283-c9dd-e15d-fe491d51f5de.png)
1. 復元したい履歴を見つけたら、その履歴の3つの点をクリックし、そこから「以前の版を復元」をクリックします。
![変更履歴05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/75ea8f17-4b88-7e79-80e5-f3b68c98e638.png)
1. 復元できていることを確認します。
Laravel9でテキスト画像を動的に作る

HTMLでのテキストの余白が邪魔だったり、親要素の横幅の何パーセントで文字を配置したい時など、時々画像として文字を表示したいケースがあります。

 

Laravel9でテキストをパラメータで受け取り、png形式の余白無しの画像を返すメゾッドを作っていきます。

 

# 手順
### 作るもの

指定のURLにパラメータを指定してアクセスしたら画像を返す

例

```https://mashmy.net/image?text=TEST```

 ![TEST.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363696/2ba1ce72-904f-e5b1-1d3a-c15eb0f62648.png)



### 手順① ライブラリをインストール
```composer require intervention/image```
 

### 手順② フォントファイルをpublicディレクトリに配置
私はpublic/fontsに配置しました

 

### 手順③ ルーティング、コントローラーにメゾッドを作成
routes/web.php
```
Route::get('/', [App\Http\Controllers\ImageController::class, 'text'])->name('front.image.text');
app/Http/Controllers/ImageController
```
app/Http/Controllers/ImageController
```
use Intervention\Image\Facades\Image;

// ...

public function image(Request $request)
{
    $canvas = Image::canvas(100, 100, '#0072c6');

    return $canvas->encode('png')->response();
}
 
```
こればかりはプレビュー見ながら作業しないとどうにもならないのでとりあえず見えるようにします。

 

何も問題なければ青い四角形が表示されると思います。

 

### 手順④ テキスト生成の処理を書く
```
public function detail(Request $request)
{
    $canvas = Image::canvas(600, 300, [0, 0, 0, 0]);
    $canvas->text($request->text, 300, 150, function ($font) {
        $font->file(public_path('fonts/KiwiMaru-Light.ttf'));
        $font->size(50);
        $font->align('center');
    });
    // キャンバスの余白をトリミングする
    $canvas = $canvas->trim('top-left', ['top', 'bottom', 'left', 'right'], 0, 0);
    return $canvas->encode('png')->response();
}
 ```

下の箇所で生成する画像のサイズを指定するのですが(後でトリミングするけど)

```
$canvas = Image::canvas(横幅, 縦幅, [0, 0, 0, 0]);
$canvas->text($request->text, 横幅, 縦幅, function ($font) {
    $font->file(public_path('fonts/KiwiMaru-Light.ttf'));
    $font->size(50);
    $font->align('center');
});
 ```

ここのサイズが充分でないと生成した画像の余白が残ってたりテキストがカットされたりします。

----

[Laravel9でテキスト画像を動的に作る](https://mashmy.net/blog/Laravel9%E3%81%A7%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E7%94%BB%E5%83%8F%E3%82%92%E5%8B%95%E7%9A%84%E3%81%AB%E4%BD%9C%E3%82%8B)
HTML/CSS  Javascriptでボタンを作ってみた

# 初めに　

ボタンを作るきっかけは、Googleの「I’m feeling」が、きっかけでした。
「I`m feeling」にカーソルを合わせると、ボタンの中身がスロットのように
回転してランダムに文字が出てくるのが、とても面白いと思いました。
今回制作したボタンは、スロットのように回転しませんが、マウスカーソルを合わせると、
ランダムに文字が出てくる仕組みです。

# ボタン作成

## 1 ボタンの中身がランダムに変化する

ボタンの中身の文字を変化させるために、あらかじめjavascriptで文字列のリストを記述
します。そしてlist[Math.floor(Math.random()*list.length)]を変数aに代入して、
ランダムに文字が出てくるようにします。

```button.js
const list = ["eat double cheese burger", "driving a car", "go and see messi", "crush my car"];

let a = list[Math.floor(Math.random()*list.length)];

```

## 2 カーソルを合わせた時の動き

ここでは、マウスのカーソルを合わせた時の動作をmouseoverとmouseleaveを記述して、
合わせた時、話した時の別々の処理を書きます。

```button.js
const target = document.getElementById('button');


    

    target.addEventListener("mouseover", () => {  //マウスのカーソルを合わせた時
        document.getElementById("button").textContent = a;//先述のリストの中の文字列をランダムに表示
        

    }, false);
    
    target.addEventListener("mouseleave", () => {// マウスカーソルを離した時
        document.getElementById("button").textContent = "I wanna....";//元の文字列「I wanna ....」を表示
        

    }, false);

}

```

# 最後に

次回はgoogleの「I'm feeling」に近づけるよう、スロットのような効果の作成に挑戦してみたいです。


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

## なぜこの記事を書こうと思ったか
業務で画像を随所に散りばめた、position:absoluteを多用するWebサイトを実装することがあり、その際に画像と重なった要素のhoverが効かなくなることがあり、自身では原因がわからなかったため。

## pointer-eventsについて
- pointer-eventsには、以下の10個の値が指定できる（キーワード値の場合）
    - auto
    - none
    - visiblePainted
    - visibleFill
    - visibleStroke
    - visible
    - painted
    - fill
    - stroke
    - all

## 解説
- auto
    - 初期値。pointer-eventsプロパティを指定していない場合と同じ振る舞いをする。
- none
    - 要素はポインターイベントの対象にならない。ただし、子孫要素が別のpointer-eventsプロパティの指定をしている場合には、子孫要素はポインターイベントの対象になり得る。
- 他の値はsvgのみに指定可能な値である。これらは別の機会にこの記事を編集してまとめる。

## 参考
MDN : https://developer.mozilla.org/ja/docs/Web/CSS/pointer-events
AWS Certified Machine Learning – Specialty＿勉強メモ（２日目）

# はじめに
標記資格取得に向けた勉強メモ（２日目）です。

# 勉強メモ
・主成分分析 (PCA)：
&emsp;可能な限り多くの情報を保持しながら、データセット内の次元 (特徴の数) を削減しようとする教師なし機械学習アルゴリズム。

・k-means アルゴリズム
&emsp;グループのメンバーが互いに可能な限り類似し、他のグループのメンバーとは可能な限り異なる、データ内の離散グループを見つけようとするアルゴリズム。

・Factorization Machine アルゴリズム
&emsp;回帰および分類タスクの解決に使用される教師ありアルゴリズム。

・潜在的ディリクレ配分 (LDA)
&emsp;教師なしアルゴリズム。主にテキスト コーパス内のドキュメントで共有される、ユーザーが指定した数のトピックを検出するために使用される。例えば、各単語の出現を判断することによって、ドキュメントから新しいトピック/カテゴリを明らかにすることができる。

・正則化
&emsp;極端な重み値にペナルティを課すことで、線形モデルがトレーニングデータの例に過剰適合するのを防ぐのに役立つ。

・モデルが過剰適合している場合に各メンバーが電子メール通知で警告されるソリューションを実装するには？
&emsp;CloudWatch APIオペレーションを使用して、トレーニング メトリクスを CloudWatch に送信し、それらのメトリクスのダッシュボードを作成する。最後に、Simple Notification Service (Amazon SNS) を使用して、モデルが過剰適合しているときに通知を送信する。

・Amazon Rekognition Content Moderationとは？
&emsp;機械学習を使用して、画像およびビデオのモデレーション ワークフローを合理化または自動化できる。フル マネージドの画像およびビデオ モデレーション API を使用して、ヌード、暗示、暴力などのカテゴリを含む、不適切、不要、または攻撃的なコンテンツをプロアクティブに検出可能。

・コンテンツベースのフィルタリングアルゴリズムとは？
&emsp;過去の行動や好みに基づいて、ユーザーのコンテンツをパーソナライズする。例えば、過去7日間、コメディ映画や SF映画をよく見ていたとすると、コンテンツベースのフィルタリングレコメンダーは、以前に視聴したのと同じジャンルの映画をレコメンデーションする可能性が高くなる。

・Amazon Lexとは？
&emsp;会話型インターフェースまたはチャットボットの構築に使用できるサービス。

・Amazon Pollyとは？
&emsp;テキスト読み上げサービス。

・セレンディピティとは？
&emsp;成功または関連する推奨事項がどれほど驚くべきものであるかの尺度

・データストリームに対して SQLクエリを実行して、リアルタイムの洞察を得たい時
&emsp;AWS Lambdaで設定された Kinesis Data Analytics アプリケーションを使用してデータを変換する。
※ S3 バケットに保存し、Amazon Athena を使用してクエリを実行する場合だと、リアルタイムで行うことができない。

・Amazon Comprehendとは？
&emsp;機械学習を使用して、非構造化データの洞察と関係を明らかにするサービス。このサービスは、テキストの言語を識別し、キー フレーズ、場所、人、ブランド、またはイベントを抽出する。テキストがどの程度肯定的か否定的かを識別したり、トークン化と品詞を使用してテキストを分析し、トピックごとにテキスト ファイルのコレクションを自動的に整理する。Amazon Comprehend の AutoML 機能を使用することで、組織のニーズに合わせて独自に調整されたエンティティまたはテキスト分類モデルのカスタムセットを構築することも可能。

・Amazon Rekognitionとは？
&emsp;機械学習による画像と動画の分析に使用されるサービス。

・Amazon Transcribeとは？
&emsp;音声をテキストに迅速かつ正確に変換することができるサービス。

・AWS Glue DataBrewとは？
&emsp;レシピアクションを使用して、さまざまな観点からデータを集計および要約したり、高度な変換を実行したりできるサービス。

# 参考
https://www.udemy.com/course/aws-certified-machine-learning-specialty-practice-exams-amazon
JavaScript のビット演算がカスだった話

# 前書き

TypeScript のお勉強を始めたのですが, 言語になれるために AtCoder の簡単な問題を解いていました

[ABC293E - Geometric Progression](https://atcoder.jp/contests/abc293/tasks/abc293_e) を解いていてシフト演算子を使ったら謎のバグでハマったときの話です

# 本文

こんなコードを書いていました

```ts
// judge
const lineit = (function* () { for (const line of require("fs").readFileSync("/dev/stdin", "utf8").split('\n')) yield line; })();
// local
// const lineit = (function* () { for (const line of require("fs").readFileSync("./dev/stdin", "utf8").split('\r\n')) yield line; })();
const wordit = (function* () { while (true) { let line = lineit.next(); if (line.done) break; for (const word of String(line.value).split(' ')) yield word; } })();
const charit = (function* () { while (true) { let word = wordit.next(); if (word.done) break; for (const char of String(word.value).split('')) yield char; } })();
const readline = () => String((lineit.next()).value);
const read = () => String((wordit.next()).value);
const readchar = () => String((charit.next()).value);


function main() : void {
  const a : bigint = BigInt(read());
  const x : number = Number(read());
  const m : bigint = BigInt(read());
  /*
  [a, 1] ^ x
  [0, 1]
  */

  const b = pow([a, 1n, 0n, 1n], x - 1, m);
  
  console.log(((b[0] + b[1]) % m).toString());
}

function mul(a:bigint[], b:bigint[], m:bigint) {
  const c:bigint[] = [0n, 0n, 0n, 0n];
  for(let i = 0; i < 2; ++i){
    for(let j = 0; j < 2; ++j){
      for(let k = 0; k < 2; ++k){
        c[i * 2 + j] += a[i * 2 + k] * b[k * 2 + j];
        c[i * 2 + j] %= m;
      }
    }
  }
  return c;
}

function pow(a:bigint[], n:number, m:bigint) {
  let res = [1n, 0n, 0n, 1n];
  while(n > 0){
    if(n % 2 == 1) res = mul(res, a, m);
    a = mul(a, a, m);
    n >>= 1;
  }
  return res;
}

main();

function range(s : number, t : number) : number[] {
  return (s < t) ? Array.from(Array(t - s), (val, idx) => s + idx) : [];
}
```

なんかよくわからんことしてると思いますが, 今回注目したいのはこの部分です

```ts
function pow(a:bigint[], n:number, m:bigint) {
  let res = [1n, 0n, 0n, 1n];
  while(n > 0){
    if(n % 2 == 1) res = mul(res, a, m);
    a = mul(a, a, m);
    n >>= 1;
  }
  return res;
}
```

所謂繰り返し二乗法というやつを書いていたのですが, `n` を半分にしていきたいということで `n >>= 1` としています

すると, サンプル 1, 2 は会いましたが サンプル 3 が全然合いません

方針が間違ってるのかと思っていろいろと試してみたのですが全くうまくいかず, まさかと思ってこのように修正してみると答えが合いました

```ts
function pow(a:bigint[], n:number, m:bigint) {
  let res = [1n, 0n, 0n, 1n];
  while(n > 0){
    if(n % 2 == 1) res = mul(res, a, m);
    a = mul(a, a, m);
    n = Math.floor(n/2);
  }
  return res;
}
```

[提出結果](https://atcoder.jp/contests/abc293/submissions/41261520)

なんでや右シフト一回したら同じことやろ！！！！！！！！！！！！

と思って調べてみたのですが, 冷静になって考えてみると JS/TS の number は整数型じゃありません 64bit浮動小数点数です

じゃあどうやってビット演算なんてやってるんだ と思ったところ, なんと 32bit 整数に変換してから行っているようです (符号の有無は `>>` か `>>>` かで変わる)


ということで, 今回の制約では 32bit 整数だと余裕でオーバーフローする値が突っ込まれるので死亡していた ということでした

そもそもデフォルトが固定小数点数じゃない時点でだいぶ違和感がありましたが, この仕様にはかなり驚きました

もし似たようなハマり方をした人がいたら (いるか？) 参考にしてください

# 参考文献

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators
【Unity】ローグライクの部屋生成を作った話

はじめまして　今回初めて記事を書かせていただくkomugikoShimizu というものです。
今回関わった作品でローグライクの部屋生成を担当した話を記述していこうと思います。
初めてなので拙い文章になっていたら申し訳ございませんが、良ければご覧いただけますと幸いです。

# 目次
* 今回の実装要件
* 実装内容
* 終わりに

## 今回の実装要件
今回制作に携わった作品は **「アンドロイドメイドメガフィスト」** という作品です。
賞をいただいた作品なのでご存じの方もいるかもしれません。(良ければ調べてみてね)

このゲームは「2Dローグライクアクションゲーム」で、私は部屋生成も担当することになりました。
そこでプランナーから実装要件を聞いたところ
「部屋には道があったりなかったりしてほしい」といった要件がありました。

今回はこれをどのように実装したのかを話していこうと思います。

![220.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3236298/43a7e424-96b0-f0d9-ca49-0eaa29686130.png)


## 実装内容

細かいことはいったん置いておいて、まずは実装した方法を

```C#
private byte direction;
```
byte型変数1つです。
**なぜbyte??** って思った方も少なくないでしょう。
なぜこのような実装にしたのかを解説していきます。

## byte型である理由
byte型である理由は **「2進数として扱いたかったから」** です。
4ビットの2進数　が 1111 となるのは分かるかと思います。
2進数は 0 と 1 しかないためbool型のように扱うことができます。
これを4ビット分用意することで4つの道を表現することが可能になります。

```C#
// 1 1 1 1 
// ↓ 10進数に直すと...
// 8 4 2 1 
// ↓ これを各道に番号として割り振る
// 上 下 右 左
```

## なぜbool型の配列ではないのか
ここまでの解説を聞いたところで **「でもbool型の配列でも同じことできない?」** と思った方もいると思います。
ではなぜバイト型を用いたのか　それは **「乱数値の生成を1回するだけでいい」** というのが理由になります。
今回の道があるかないかという情報はランダムに決定されます。
これをbool型配列で実装しようとする場合、乱数値を4回生成する必要があります。
ですが、この実装方法を用いることで 「0から15までの乱数値」を1回生成するだけで良くなるのです。

```C#
byte direction = (byte)Random.Range(0,15); // これで15までの乱数を生成できる
```

## 不都合な点はないのか
正直ほぼなかったです。
道を足さなければいけない場合も、byte型変数に数値を足すだけで実装できますし
道があるかを確認する場合も、AND論理演算を行うだけで取得できます。
強いてあげるなら **「数値にバグがある場合、生成される道がおかしくなる」** という点です。
先ほど述べた通り、道の足し引きはbyte型変数に足し引きをすることで実装できます。
しかし、この演算に何かしらの間違いがあった場合「なぜか道があるorない」が発生する可能性があります。
実際にこれが発生した際、まず道の仕組みを疑ったため見つけるのに時間を要してしまいました。

## 終わりに
ここまでご覧いただき、ありがとうございました。
今回の制作を通し、うまく実装できたかと思ったため記事にした次第です。
読んでいただき「これがしたかったんだ！」という方が一人でもいれば記事にした甲斐があります。
ぜひ1例として参考にしていただければと思います。
できる限りonTapGestureよりButtonを使おう(SwiftUI)

## はじめに

表題の通りです。
できる限り `onTapGesture { ... }` より `Button` を使いましょう。

```swift
// 🔺: `onTapGesture` を `Button` として使っている
FooView(foo: foo)
  .onTapGesture {
    print("FooView tapped.")
  }
  .accessibilityAddTraits(.isButton)

// ✅: `Button` を使っている
Button {
  print("FooView tapped.")
} label: {
  FooView(foo: foo)
}
```

`Button` の `label` には `View` を渡せるので、リファクタリングも簡単です。

## 環境

- OS：macOS Ventura 13.3.1
- Xcode：14.3 (14E222b)
- Swift：5.8

## 理由

できる限り `onTapGesture { ... }` より `Button` を使う理由を紹介します。

### 公式ドキュメントに記載されている

[onTapGestureの公式ドキュメント](https://developer.apple.com/documentation/swiftui/view/ontapgesture(count:perform:)) に以下の記載があります。

> Note
> 
> If you create a control that’s functionally equivalent to a Button, use ButtonStyle to create a customized button instead.
> （ボタンと同等の機能を持つコントロールを作成する場合は、 ButtonStyleを使用して、代わりにカスタマイズされたボタンを作成します。）

`Button` と同等のコントロールなら `Button` を使いましょう、と明記されています。

最初の例では `label` に `FooView` をそのまま渡しましたが、 部品化するなら `ButtonStyle` を実装するのがいいと思います。

[`PrimitiveButtonStyle`](https://developer.apple.com/documentation/swiftui/primitivebuttonstyle) を使うのがいいとのことです。

https://twitter.com/noppefoxwolf/status/1655990280305393665

https://twitter.com/noppefoxwolf/status/1656152888203444224

### タップ時にハイライトが付く

個人的には `Button` を使う一番の理由です。
`onTapGesture` だとタップ時にハイライトが付かないので、タップしたかどうかがわかりづらいです。
`Button` はデフォルトでハイライトが付きます。

ただ `ButtonStyle` を自作する場合、ハイライト処理を自前で実装する必要があります。

```diff_swift:FloatingActionButtonStyle.swift
struct FloatingActionButtonStyle: ButtonStyle {
    let backgroundColor: Color
    let foregroundColor: Color

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .frame(width: 56, height: 56)
            .foregroundColor(foregroundColor)
            .background(backgroundColor)
            .cornerRadius(16)
+           .opacity(configuration.isPressed ? 0.5 : 1)
    }
}
```

といっても1行のみの実装で済みます。
Swift Playgroundsでスニペットを使って `ButtonStyle` を作ると、最初から書かれている処理です。

## おわりに

タップ時の処理に `onTapGesture` を使っていたら、ぜひ `Button` に置き換えてハイライトが付くライフを送りましょう :relaxed:

## 参考リンク

- [Highlight on FAB by uhooi · Pull Request #146 · uhooi/Loki](https://github.com/uhooi/Loki/pull/146)
Deno KVで保存する前に圧縮する【Deno Deploy】

# TypeError: value too large (max 65536 bytes)

圧縮することでデータが10分の1ほどになります。保存できないときにお試しください

```typescript
import { serve } from "https://deno.land/std@0.177.0/http/server.ts";
import { deflate, inflate } from "https://deno.land/x/compress@v0.4.4/mod.ts";

const kv = await Deno.openKv();
kv.getText = (...args) => kv.get(...args).then(e => ({...e, value: new TextDecoder().decode(inflate(e.value))}))
kv.setText = (key, value) => kv.set(key, deflate(new TextEncoder().encode(value)))
kv.listText = async (...args) => {
    const entries = []
    for await (const e of kv.list(...args)) entries.push({...e, value: new TextDecoder().decode(inflate(e.value))})
    return entries
}

serve(async (req: Request) => {
    const html = await fetch("https://example.com/").then(r => r.text())
    await kv.setText(["mykey"], html)
    console.log(await kv.getText(["mykey"]))
    console.log(await kv.listText({prefix: []}))
    return new Response("Hello World")
});
```

https://dash.deno.com/playground/ess



### deflateではなく、gzipを使う場合

gzipは、deflateより12バイト多くなります

```typescript
import { serve } from "https://deno.land/std@0.177.0/http/server.ts";
import { gzip, gunzip } from "https://deno.land/x/compress@v0.4.4/mod.ts";

const kv = await Deno.openKv();
kv.getText = (...args) => kv.get(...args).then(e => ({...e, value: new TextDecoder().decode(gunzip(e.value))}))
kv.setText = (key, value) => kv.set(key, gzip(new TextEncoder().encode(value)))
kv.listText = async (...args) => {
    const entries = []
    for await (const e of kv.list(...args)) entries.push({...e, value: new TextDecoder().decode(gunzip(e.value))})
    return entries
}

serve(async (req: Request) => {
    const html = await fetch("https://example.com/").then(r => r.text())
    await kv.setText(["mykey"], html)
    console.log(await kv.getText(["mykey"]))
    console.log(await kv.listText({prefix: []}))
    return new Response("Hello World")
});
```
laravel Featureテストで特定のミドルウェアを無効にする方法

# 概要

- laravelのFeatureテストにて特定のミドルウェアを無効にする方法を簡単にまとめる。

# 方法

- テストメソッド内で`$this->withoutMiddleware(無効にしたいミドルウェアクラス);`を記載することで特定のミドルウェアを無効にする事ができる。
- 例

    ```FooTest.php
    public function test_Foo()
    {
        $this->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);

        $this->assertTrue(true);
    }
    ```

- 上記のように記載することでVerifyCsrfTokenのミドルウエアのみを無効にする事ができる。
    - ただし、laravelのテストコード実行時にはweb.phpだろうがapi.phpだろうがすべてのルートでcsrfは無効になるはずなので本来VerifyCsrfTokenのミドルウエアを無効にすることは無いはず。あくまで例として受け取っていただきたい。

# 参考文献

https://readouble.com/laravel/10.x/ja/middleware.html#excluding-middleware

https://readouble.com/laravel/10.x/ja/csrf.html#csrf-excluding-uris
Ansibleでuserのカスタムモジュールメモ

# Ansibleで、ユーザパスワード期限ポリシーを変えたい！！
## 対応状況整理

|項目|chageオプション|Ansible(userモジュール)|
|--|--|--|
|min days|-m|password_expire_min|
|max days|-M|password_expire_max|
|warn days|-W|非対応|
|Inactive days|-I|非対応|

対応してないので、
shellモジュール or カスタムモジュールしかない。

参考：
https://www.ansiblepilot.com/articles/user-password-expiration-ansible-module-user/
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html

## カスタムモジュール作成

```update_password_policy.py
#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule
import os

def get_current_policy(module, user):
    with open("/etc/shadow", "r") as shadow_file:
        shadow_data = shadow_file.readlines()

    user_data = None
    for line in shadow_data:
        if line.startswith(user + ":"):
            user_data = line
            break

    if not user_data:
        module.fail_json(msg="User not found in /etc/shadow")

    _, _, mindays, maxdays, warndays, inactive, _, _, = user_data.split(":")[1:9]

    current_policy = {
        "maxdays": int(maxdays) if maxdays != '' else -1,
        "mindays": int(mindays) if mindays != '' else -1,
        "warndays": int(warndays) if warndays != '' else -1,
        "inactive": int(inactive) if inactive != '' else -1
    }

    return current_policy

def main():
    module_args = dict(
        user=dict(type='str', required=True),
        maxdays=dict(type='int', required=True),
        mindays=dict(type='int', required=True),
        warndays=dict(type='int', required=True),
        inactive=dict(type='int', required=True)
    )

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    # Get current password policy
    current_policy = get_current_policy(module, module.params['user'])

    chage_command = [
        "chage",
        "-M", str(module.params['maxdays']),
        "-m", str(module.params['mindays']),
        "-W", str(module.params['warndays']),
        "-I", str(module.params['inactive']),
        module.params['user']
    ]

    # Check if policy needs to be updated
    update_required = False
    for param in ['maxdays', 'mindays', 'warndays', 'inactive']:
        if module.params[param] != current_policy[param]:
            update_required = True
            break

    # If update is not required, exit with no changes
    if not update_required:
        module.exit_json(changed=False, msg="Password policy is already up-to-date")

    if module.check_mode:
        module.exit_json(changed=True)

    rc = os.system(" ".join(chage_command))
    if rc == 0:
        result = {"changed": True, "user": module.params["user"]}
    else:
        result = {"failed": True, "msg": "chage command failed with return code {}".format(rc)}

    module.exit_json(**result)

if __name__ == '__main__':
    main()
```

## デバッグ

```module_args.json
{
    "ANSIBLE_MODULE_ARGS": {
        "user": "hogehoge",
        "mindays": "-1",
        "maxdays": "-1",
        "warndays": "-1",
        "inactive": "-1"
    }
}
```

```bash
$ python3 update_password_policy.py < module_args.json
```

カスタムモジュールの配置場所とか、Ansible実行方法は流石は割愛

余談。
-I（アイ）
-l（エル）
見辛すぎだろ。
string型のdecimalをint型に変換する

## 経緯

Web APIの戻り値を整形してDBに保存する処理を実装中。
戻り値に金額（円）が含まれるが、小数点第一位までの値ため、string型になる。
単位が円なことからも、DB保存するときはint型に変換して保存する仕様に決まった。
しかし、以下のように書いたらExceptionが発生してしまった。

```csharp:c#
string str = "1234.5";
int num = int.Parse(str);
```

## 環境

.NET Framework 4.8を使用

## 原因

公式ドキュメントを確認してみた。

https://learn.microsoft.com/ja-jp/dotnet/api/system.int32.parse?view=net-7.0#system-int32-parse(system-string)

どうやら、小数点を含む数値なので<code>FormatException</code>が発生するっぽい。

## 解決策①：decimalに変換→Convert.ToInt32()する

以下の記事を参考に。

https://stackoverflow.com/questions/4975613/convert-string-decimal-to-int

```csharp:解決策①
string str = "1234.5";
int num = Convert.ToInt32(decimal.Parse(str));
Console.WriteLine(num); // 1234
```

なお、Convert.ToInt32(Decimal)について、公式ドキュメントには以下の記載がある。

>最も近い 32 ビット符号付き整数に丸められた value。 value が 2 つの整数のちょうど中間にある場合は、偶数が返されます。つまり、4.5 は 4 に変換され、5.5 は 6 に変換されます。

つまり、偶数丸めという丸め方をするそう。切り捨て/四捨五入/切り上げしたい場合は注意。

## 解決策②：「.」以降の文字列を切り捨ててint.Parse()する

```csharp:解決策②
string str = "1234.5";
int indexOfDot = str.IndexOf(".");
string integerStr = str.Substring(0, indexOfDot);
int num = int.Parse(integerStr);
Console.WriteLine(num); // 1234
```

## 感想

string型の数値を変換する方法が<code>int.Parse()</code>だけじゃなくて、<code>Convert.ToInt32()</code>もあると気づけたのは良かったです。
解決策①は、明示的にMath.Round()などを書いたほうがいいのか、まだその辺りの判断に迷いますね、、

## 参考

https://learn.microsoft.com/ja-jp/dotnet/api/system.int32.parse?view=net-7.0#system-int32-parse(system-string)


https://learn.microsoft.com/ja-jp/dotnet/api/system.convert.toint32?view=net-8.0#system-convert-toint32(system-decimal)

https://stackoverflow.com/questions/4975613/convert-string-decimal-to-int
[AWS Q&A 365][Step Function]AWSのよくある問題の毎日5選 #52

# 1. AWS Step Functionsの価格設定モデルは何ですか？
回答：AWS Step Functionsの価格は、状態遷移の数とその遷移の時間（秒単位）に基づいています。最低料金や前払いのコミットメントはありません。

# 2. AWS Step Functionsには無料利用枠がありますか？
回答：はい、AWS Step Functionsには、月間4,000回の状態遷移と月間1,000回の無料ステートマシン実行を含む無料利用枠があります。

# 3. AWS Step Functionsの1回の状態遷移あたりの費用はいくらですか？
回答：1回の状態遷移あたりの費用は、地域と使用されるワークフローの種類によって異なります。米国東部（バージニア北部）地域では、標準ワークフローに対して1,000回の状態遷移あたり0.025ドル、エクスプレスワークフローに対して1,000回の状態遷移あたり0.0125ドルの費用がかかります。

# 4. AWS Step Functionsの1秒あたりの遷移時間あたりの費用はいくらですか？
回答：1秒あたりの遷移時間あたりの費用も、地域とワークフローの種類によって異なります。米国東部（バージニア北部）地域では、標準ワークフローに対して0.000025ドル/秒、エクスプレスワークフローに対して0.0000125ドル/秒の費用がかかります。

# 5. AWS Step Functionsを使用する場合、追加料金がありますか？
回答：Lambda関数やDynamoDBテーブルなど、他のAWSサービスをStep Functionsと組み合わせて使用する場合、追加料金が発生する場合があります。ワークフローで使用される各個別のサービスの価格を確認して、正確な総費用を計算することが重要です。
[AWS Q&A 365][Step Function]Daily Five Common Questions #52

# 1. What is the pricing model for AWS Step Functions? 
Answer: AWS Step Functions pricing is based on the number of state transitions and the duration of those transitions, measured in seconds. There is no minimum fee or upfront commitment. 

# 2. Is there a free tier for AWS Step Functions? 
Answer: Yes, AWS Step Functions offers a free tier that includes 4,000 state transitions per month and 1,000 free state machine runs per month. 

# 3. How much does AWS Step Functions cost per state transition? 
Answer: The cost per state transition depends on the region and the type of workflow used. In the US East (N. Virginia) region, the cost is $0.025 per 1,000 state transitions for standard workflows and $0.0125 per 1,000 state transitions for express workflows. 

# 4. How much does AWS Step Functions cost per second of transition time? 
Answer: The cost per second of transition time also varies by region and workflow type. In the US East (N. Virginia) region, the cost is $0.000025 per second for standard workflows and $0.0000125 per second for express workflows. 

# 5. Are there any additional fees for using AWS Step Functions? 
Answer: There may be additional fees for using other AWS services in conjunction with Step Functions, such as Lambda functions or DynamoDB tables. It is important to check the pricing for each individual service used in a workflow to accurately calculate the total cost.
【Swift】if文でcaseを分岐する

# はじめに
caseを分岐する際によく使うのはswitch文だと思います
しかし、一つのcaseだけ処理を行いたいときにswitch文を使うと見た目がよろしくない気がするのでif文を使おうと思います。

# やりかた
```swift
enum Sample {
    case sample1
    case sample2
    case sample3
}

let sample: Sample = .sample1

if case .sample1 = sample {
    // .sample1の場合にのみ処理を行う
}
```

# おわり
割と最近まで知りませんでした
[AWS Q&A 365][Step Function]AWSのよくある問題の毎日5選 #51

# 1. AWS Step Functionsとは何ですか？
回答：AWS Step Functionsは、ビジュアルワークフローを使用して、分散型アプリケーションやマイクロサービスを調整することができるサーバーレスのワークフローサービスです。

# 2. AWS Step Functionsのユースケースは何ですか？
回答：AWS Step Functionsは、関数オーケストレーション、分岐、エラーハンドリング、ヒューマンインザループ、並列処理、および動的並列処理に使用することができます。

# 3. AWS Step Functionsを使用するための前提条件は何ですか？
回答：AWS Step Functionsを使用するための前提条件は、AWSアカウントの作成、管理者ユーザーの作成、およびプログラム的なアクセスの許可です。

# 4. AWS Step Functionsの主要なコンセプトは何ですか？
回答：AWS Step Functionsの主要なコンセプトは、状態、遷移、ステートマシンデータ、データ処理、機械学習、マイクロサービスオーケストレーション、ITおよびセキュリティの自動化です。

# 5. AWS Step Functionsのエラーをデバッグする方法は何ですか？
回答：AWS Step Functionsのエラーをデバッグするには、コンソールを使用したり、Map Runを調べたりすることができます。また、RetryおよびCatchを使用してエラーを処理することもできます。
表領域のサイズ拡張

実業務でローカルの表領域不足が原因でデータインポート時にエラーが発生
その際に表領域のサイズを拡張

[構文]
ALTER TABLESPACE 表領域名 
ADD DATAFILE データファイル名（ファイルパス）
SIZE データファイルサイズ;

[例文]
ALTER TABLESPACE AAA ADD DATEFILE 'C:\BBB\CCC\DATEFILE1.dbf' SIZE 1024M;
[AWS Q&A 365][Step Function]Daily Five Common Questions #51

# 1. What is AWS Step Functions? 
Answer: AWS Step Functions is a serverless workflow service that allows you to coordinate distributed applications and microservices using visual workflows. 

# 2. What are the use cases of AWS Step Functions? 
Answer: AWS Step Functions can be used for function orchestration, branching, error handling, human in the loop, parallel processing, and dynamic parallelism. 

# 3. What are the prerequisites for using AWS Step Functions? 
Answer: The prerequisites for using AWS Step Functions are creating an AWS account, creating an administrative user, and granting programmatic access. 

# 4. What are the key concepts of AWS Step Functions? 
Answer: The key concepts of AWS Step Functions are states, transitions, state machine data, data processing, machine learning, microservice orchestration, and IT and security automation. 

# 5. How can you debug errors in AWS Step Functions? 
Answer: You can debug errors in AWS Step Functions using the console and by examining Map Run. You can also use Retry and Catch to handle errors.
No wkhtmltopdf executable found: "b''" エラー対応

## wkhtmltopdfのエラー
コマンドラインでは実行できるのに cronで実行できない場合など

```
localhost CROND[1691593]: (root) CMDOUT (No wkhtmltopdf executable found: "b''")
localhost CROND[1691593]: (root) CMDOUT (If this file exists please check that this process can read it or you can pass path to it manually in method call, check README. Otherwise please install wkhtmltopdf - https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf)
```

## 原因
wkhtmltopdfのパスが見つからないため

Pythonのコードのでwkhtmltopdfのパスを認識できるようにする

```
import os

# wkhtmltopdfのパスを環境変数に設定
os.environ['PATH'] += ':/usr/local/bin/'
```
Treasure data CDP/データ取得方法

![CDP.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180499/6c24cd3b-2f77-b356-06c0-59bf301d7d50.jpeg)



# 概要

Treasure Data CDPでは他ツールからデータを取得する方法が様々ございます。
今回は、データコネクターとWorkflowを使ってデータ取得する方法を紹介します。

# インポートの種類

![インポートの種類.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180499/54da184b-24b3-5265-4fa2-e8092431682b.png)


### Data Connectorによるインポート処理の強み

### 「WEB UI」
Sourceであれば簡易的な設定で取り込みがスムーズですが
Workflowを利用することで簡単に依存関係を設けることができます。
pipelineのようなイメージですね。

※余談：「ワークフロー」は実際に現場で行われる作業フローのことで、その中でデザイナーの画力が発揮されます。 「パイプライン」はワークフローの様々な箇所で利用されるツールなどをまとめたもの

### 設定方法

手順

大まかな流れ！

① ワークフロー実行dig & yamlファイルを作成
② テーブルを作成
③ ワークフローを実施

詳細

① yamlファイルを作成

```digdag
# 「in」は取り込み元のデータソースを指定します
in:
​
 # 取り込み元は「s3」
  type: s3
​
 # 「s3(AWS)」のアクセスID
  access_key_id: XXX
​
 # 「s3(AWS)」のアクセスキー
  secret_access_key: XXX
​
 # 「s3(AWS)」のバケット
  bucket: XXX
​
 # 「s3(AWS)」のパス
  path_prefix: XXX
​
 # 新規登録として指定
  mode: insert
​
 # 取り込み対象ファイルのパースを設定
  parser:
​
 # 文字コード
    charset: UTF-8
​
 # CSVの改行コード
    newline: LF
​
 # ファイル・タイプ
    type: csv
​
 # CSVの区切り文字
    delimiter: ','
​
 # CSVの文字列区切り文字
    quote: '"'
​
 # CSVのエスケープ文字
    escape: '"'
​
 # ‘’をnullに変換
    null_string: '' 
​
 # クォートされていないと文字列前後の空白を削除、初期値false
    trim_if_not_quoted: false
​
 # CSVの1行目を取り込まない
    skip_header_lines: 1
​
 # 「true」の場合は過多なカラムを取り込まない
    allow_extra_columns: false
​
 # 「true」の場合、足りていないカラムを無視
    allow_optional_columns: false
​
 # 「true」の場合でパースエラーが発生した場合停止させる
    stop_on_invalid_record: true
​
 # デフォルトのタイムゾーン
    default_timezone: 'Asia/Tokyo' 
​
    # カラムを定義
    columns:
    - {name: id, type: string}
    - {name: text, type: string}
​
filters:
- type: add_time
  to_column:
    name: time
    type: timestamp
  from_value:
    value: ${session_unixtime}
```

ワークフロー実行
digファイル

（余談；Digdagのワークフロー定義について)
Digdagのワークフローは拡張子*.digを持つファイルとして作成

```digdag
# リージョンとスケジュール設定
timezone: Asia/Tokyo
schedule:
  daily>: 00:00:00

_export:

# S3取り込み先データベース
  to_database: xxxx
# ↑!includeを使用して子ファイルの呼び出しも可能です。

# S3取り込み先テーブル
  to_table: xxxx

+import:
  call>: digファイル

# 上記のS3取り込み設定ファイルを指定
  td_load>: s3.yml
  database: データベース名
  table: テーブル名
```


② テーブルを作成
先にテーブルを作成する
データをインポートするための箱を先に作るので
yamlファイルに記載した型に合わせたテーブルを先に作成

```
create table データセット名.テーブル名 as

select

'' as column_1 --文字列

1 as column_1 --数値型

from

データセット.テーブル -- 仮テーブル/なんでもよし

limit 1 -- 1行のみ
```
③ ワークフローを実施
成功を確認！

参照資料

[Treasure Data CDPを理解する- Import編 –](https://user-engagement.treasuredata.co.jp/)
[Workflowでデータコネクターを利用する方法](https://cloud.google.com/workflows/docs/samples/workflows-connector-bigquerydatatransfer?hl=ja)
【Python】スパイラルマトリックスの実装

# はじめに
与えられた行列を螺旋状のリスト形式で返すアルゴリズムです。
### 参考図
<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/c7f1f24c-d144-8193-00e0-0fcfaec3d9cd.png")>
# 実装
```python:spiral_matrix.py
from typing import List
class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        # 出力配列を初期化
        result = []
        rows, columns = len(matrix), len(matrix[0])
        # 上、右、下、左の境界をup、right、down、leftとして初期化
        up = left = 0
        right = columns - 1
        down = rows - 1
        # 要素をらせん状にトラバースし、各要素をresultに追加
        while len(result) < rows * columns:
            for col in range(left, right + 1):
                result.append(matrix[up][col])
            for row in range(up + 1, down + 1):
                result.append(matrix[row][right])
            
            if up != down:
                for col in range(right - 1, left - 1, -1):
                    result.append(matrix[down][col])
            if left != right:
                for row in range(down - 1, up, -1):
                    result.append(matrix[row][left])
            left += 1
            right -= 1
            up += 1
            down -= 1
        
        return result
# テスト
if __name__ == "__main__":
    matrix = [[1,2,3],[4,5,6],[7,8,9]]
    print(Solution().spiralOrder(matrix))
```
# 参考
https://leetcode.com/problems/spiral-matrix/editorial/
Githubへpushエラー

# Githubへpushしようとしたら突然エラーになってpushできなくなった

1回目は通常通りpushできたのですが、突然エラーが出てpushできなくなりました。
色々調べて解決できたので、備忘録として載せておきます。

```php
ec2-user:~/environment/book (main) $ git push origin main
.
.
.
remote: fatal error in commit_refs
To github.com:〇〇〇/book.git
 ! [remote rejected] main -> main (failure)
error: failed to push some refs to 'github.com:〇〇〇/book.git'
```

と謎のエラーが出来てしまいpushできずにいました。

```php
remote: fatal error in commit_refs
```
ここの部分を抜き取ってネットで検索してみるとGithub自体に問題があると、このエラーが出てくるようです。
なので、一度ログアウトして再ログインしてpushしてみたら出来ました！
Deno KVでlocalStorageを実装する【Deno Deploy】

シンプルなインタフェースでKVS使いたいときに活用ください

```typescript
import { serve } from "https://deno.land/std@0.177.0/http/server.ts";

const kv = await Deno.openKv()
class localStorage {
    static async getItem(key) {
        const { value } = await kv.get([key])
        return value
    }
    static async setItem(key, value) {
        await kv.set([key], value)
    }
    static async removeItem(key) {
        await kv.delete([key])
    }
    static async clear() {
        for await (const { key } of kv.list({ prefix: [] })) await kv.delete(key)
    }
}

serve(async (req: Request) => {
    await localStorage.setItem('abc', 'xyz')
    console.log(await localStorage.getItem('abc'))
    await localStorage.removeItem('abc')
    console.log(await localStorage.getItem('abc'))
    await localStorage.setItem('abc', 'opq')
    console.log(await localStorage.getItem('abc'))
    await localStorage.clear()
    console.log(await localStorage.getItem('abc'))
    return new Response("Hello World")
});
```

https://dash.deno.com/playground/lst
Chat GPTに音声文字起こしのやり方を聞いてみた

# はじめに
　会話内容が自動的に要約されて送られてきたら便利だなあと思い、まずは音声文字起こしのコードを作成するころにしました。面倒なのでChat GPT君に丸投げして作成してもらいました。動作させるまで5分でできました。戦々恐々としています、、、、
# コード
Google Colabで動作します。実行後にmp3ファイルをアップロードし、アップロードしたファイルの音声を文字起こししてテキストファイルに出力してくれます。
すべてChat GPTに生成してもらいました。(優秀すぎ、、)
Colabにそのまま貼り付けると動作しますので、mp3ファイルをご用意の上お試しください。

```python:main.ipynb
!pip install pydub
!pip install SpeechRecognition

from google.colab import files
from pydub import AudioSegment
import speech_recognition as sr

def convert_audio_to_wav(input_file, output_file):
    audio = AudioSegment.from_mp3(input_file)
    audio.export(output_file, format="wav")

def transcribe_audio(input_file, output_file):
    r = sr.Recognizer()
    with sr.AudioFile(input_file) as source:
        audio = r.record(source)
        text = r.recognize_google(audio, language="ja-JP")
        with open(output_file, "w", encoding="utf-8") as f:
            f.write(text)

# mp3ファイルのアップロード
uploaded = files.upload()

# アップロードされたファイルのパスを取得
input_file = list(uploaded.keys())[0]
output_file = "/content/output.txt"

# mp3をwavに変換
converted_file = "/content/converted.wav"
convert_audio_to_wav(input_file, converted_file)

# 音声を文字起こししてテキストファイルに保存
transcribe_audio(converted_file, output_file)

# 出力ファイルをダウンロード
files.download(output_file)

# 一時ファイルを削除
os.remove(converted_file)
output_file = "/content/output.txt"

# テキストファイルを読み込んで表示
with open(output_file, "r", encoding="utf-8") as f:
    text = f.read()
    print(text)
```

# 結果
　テキストとなって出てきました。ところどころ漢字変換ミスがありますが、これをコピペでChat GPT君に漢字変換してもらうと正しい漢字になりました。テキストを、要約してってお願いしたら要約してくれました。もう優秀すぎですね。
Docker：CentOS環境でlessコマンドが使えなかった際の対応メモ

○問題
Linux標準教科書を用いて学習を行っている際、
less /etc/hosts(ページャを使った表示)コマンドを実行すると
”bash: less: command not found” と表示されコマンドが実行できなかった。

○対応方法
yum install lessコマンドを実行するとlessコマンドが使えるようになった。
(追記)
whichコマンドも同様に
yum install whichを実行すると使えるようになった