OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFormationのテンプレートファイルでLambdaコードベタ書きから脱却したい

## はじめに
CloudFomationでLambdaリソースを作るにはやり方が2つ。
- S3へ事前に固めたZipファイルを指定してLambdaリソースを作る
- テンプレートファイルそのものにインラインでベタ書きで書いてしまう

後者のベタ書きだと色々不都合があって、

- Nodejs.18ランタイムだと、CommonJS形式の強制的にindex.jsになる（マネコンからデフォルトで作成するとES形式のindex.mjsなのに）
- テンプレートとコードが分離できないので、IDEのlinterが通せない
- インラインだとテンプレートファイルがそもそも見にくい

テンプレートへのインラインベタ書きをやめるには、CodeセクションでLambdaコードにS3へアップロードしたZipファイルを指定すればよく、AWS CLIだと`aws cloudformation package`が使えるが、自前でpackage化して面倒くささを体感してみる。


参考：packageコマンド

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-cli-package.html


## つくるもの

`sam package`の動作を参考にする。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-package.html

`package`コマンドでは、
1. 材料となるテンプレートファイルの中でLambdaコードのローカルのファイルパスを指定して
1. テンポラリなzipファイルを作成してS3へアップロードすると
1. Code部分をS3パスに置き替えた新しいテンプレートファイルを作成してくれる

これをbashとCloudFormationのテンプレートで工夫して実装する。


### bash側
zip操作とS3へのアップロード操作。zip時には`-j`オプション(junk-paths)が無いとlambdaランタイムがindexファイルを参照できなくなって困る。また、アップロードするS3バケットは一時的にしか使わないので、ライフサイクルルールでファイルが削除されるような設定にしておくと良いかも。

```bash:depoly_withMaunalPackage.bash
#!/bin/bash
VAR=$(uuidgen);
ARR=(${VAR//-/ });
VAR=${ARR[0]};

TMP_BACKET=bd8z-temporary;
PACKEGE_ZIP="file-${VAR}.zip";
zip -r -j $PACKEGE_ZIP src;
aws s3api put-object --bucket "${TMP_BACKET}" --key "${PACKEGE_ZIP}" --body $PACKEGE_ZIP;
aws cloudformation create-stack --stack-name "stack-${VAR}" --capabilities CAPABILITY_NAMED_IAM --template-body file://templateV2.yaml --parameters ParameterKey=UUID,ParameterValue=${VAR} ParameterKey=LambdaCodeKey,ParameterValue=${PACKEGE_ZIP} ParameterKey=LambdaCodeBucket,ParameterValue=${TMP_BACKET};
```

### CFnのテンプレート側
ParameterセクションでLambda関数のS3の場所を指定できるようにする。
```yaml:templateV2.yaml
Parameters:
  LambdaCodeKey:
    Type: String
  LambdaCodeBucket:
    Type: String
<--------中略------->
Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "App-Lambda-${UUID}"
      Handler: index.handler
      Role: !GetAtt LambdaServiceRole.Arn
      Runtime: nodejs18.x
      Timeout: 300
      Environment:
        Variables:
          APIPATH: !Sub prod/${APIPath}
          APIURL: !Sub https://${RestAPI}.execute-api.${AWS::Region}.amazonaws.com/
          BUCKETNAME01: images-for-serverless-page
          DYNAMODB_TALBENAME: !Ref MyTable
          IMAGE_KEY01: background.png
          PARTITION_KEY: !Ref PartitionKey
      Code:
        S3Bucket: !Ref LambdaCodeBucket
        S3Key: !Ref LambdaCodeKey
```

## おわりに
packagingコマンドを使う場合だと、linterで警告が出るので何となく気持ち悪い。自分でS3へアップロードするメリットはこの警告が解消できるぐらいかな。

package コマンドを使う場合にcfn-lintが吐く警告
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54100/c23fed92-01ff-d12c-deaf-8c308c556f25.png)



#### 成果物
packgingコマンドで実行する版も載せた。

https://github.com/bd8z/serverless-frontend
Power Automate: Azure DevOps のWiki更新を、Teamsに通知する

# 背景

wiki の更新通知を用意したかったが、DevOps のActionにはなかった。

しかしながら、Azure DevOps Wiki は、Git で管理されていて、Azure Repos を Repository にすることも可能

ということで、Git の更新を検知して飛ばす方向で。

# 結果例

こんな感じで、編集すると、通知が飛んでくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a5c77113-00b9-d3b1-ad0c-50972630aa93.png)


# 前提

- Wiki を作るときに Publish code as wiki を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d0ef31c1-44de-1f97-d1bc-27a4351e0c6a.png)

詳しくは以下で

https://learn.microsoft.com/ja-jp/azure/devops/project/wiki/publish-repo-to-wiki?view=azure-devops&tabs=browser

# Power Automate

実装例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/6364c08c-1d2c-9bae-1ad1-d295691ed043.png)

1. Wiki の元とした Git で、プッシュをトリガー
1. トリガーから、以下 ID を取得
   - repositoryID
   - newObjectId
       - commitID
1. コミットIDから、変更(changes) を取得
1. あとは、Teamsへ投稿する

## トリガーについて

- Wiki をフォルダー扱いとしている場合は、フォルダーを Trigger Condition に突っ込めないので、内容から判断する必要がありそう

## トリガーからのID取得

- newObjectId は以下で取得
    - Wiki の編集で、同時に複数コミットがあるとは思えないので、first() を利用

```json: newObjectID as newCommitID
@{first(triggerOutputs()?['body/refUpdates'])?['newObjectId']}
```

## changes の取得

以下、REST API を使用。
これの為に、事前に ID を取得している

https://learn.microsoft.com/ja-jp/rest/api/azure/devops/git/commits/get-commits?view=azure-devops-rest-7.1&tabs=HTTP

https://learn.microsoft.com/ja-jp/rest/api/azure/devops/git/pushes/get?view=azure-devops-rest-7.1&tabs=HTTP

## Teams への投稿

- Git として管理しているだけで、wiki を認識はしてなさそうなので、通知として使う場合は、Wiki 自体へのリンクは最初から貼っておく必要がある。（指定のパスに飛ばしたい場合は、相対パスで合成すれば行ける筈）

- changes にある item URL は、最新ファイル取得してくるので、まぁ、結果を見るには便利
- 元の CommitID から、旧ファイル取得して差分をとかも出来るかもしれないが面倒なんでパス

# あとがき

Wiki の編集をちょこちょこやってしまうと、通知がわんさか飛んでくる・・
でもって、差分が分からないのはちょっとうざい・・

Commit 差分なら簡単なんだが・・まぁ、とりあえずは放置・・

https://learn.microsoft.com/ja-jp/rest/api/azure/devops/git/diffs?view=azure-devops-rest-7.1
SharePointに毎月ひな形Excelを月の名前をつけてコピーする

Qiitaの質問で見つけたテーマです。割とよく使いそうな自動化なのでさっそく試してみます。
SharePointのドキュメントライブラリに、適当なひな形を用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/49d8b0bd-fb9a-727c-b74d-26c91fbf35a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/e4d7b5bd-66af-8bcb-cee3-021d8b8e44cf.png)
# スケジュールをトリガーにする
毎月1日にこのひな形ファイルを同じフォルダに、月の名前がわかるような名前を付けてコピーしたいと思います。したがって使うのは「スケジュール済みクラウドフロー」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/cae3bbef-b55f-3d72-2a7a-d09dd5db111f.png)
トリガーの詳細オプションを開き、タイムゾーンを設定しておきます。
月初の朝９時に動かそうと思うので、初回は11/1の日本時間９時にします。お尻にZがついているのはUTC時間です。UTC時間は日本時間より９時間前なので、ちょうど０時にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/39002657-cd20-0889-7f27-0b9a328cfe32.png)
# ひな形のコピーは「ファイルのコピー」は使わない
あとはひな形に名前を付けてコピーすればよいので、「ファイルのコピー」を使いたくなるところですが、ここが落とし穴。このアクションは名前を付けて保存ができないので、使った場合には後でファイル名変更が必要。ただこれが結構ハードルが高いので別の方法を使います。

そこで利用するのが、「ファイル コンテンツの取得」です。この時点では情報を持ってきているだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/f9207a9a-bc49-e375-e02c-96a47558b1b8.png)
取得ができたら、今度はSharePoint上に「ファイルの作成」をしてやります。ひとまずファイル名は適当に。ファイルコンテンツには、前のステップで取得したファイルコンテンツを動的なコンテンツから選択してやればＯＫです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/dcc35ab1-15e4-6b09-69e0-cc0e50e32bba.png)

ここまで出来たら、一度テスト実行をしてみましょう。PowerAutomateで付けた名前でひな形のコピーが作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5efe1181-7432-ef0c-723c-3c0bd7b79e41.png)

# 日付のファイル名を付ける
ファイル名には日付を使います。今回は使い勝手がよいようにaddDays関数を使っています。UTC時間に1日(24時間)を加えて、2023-11　のような文字列を作っています。
`addDays(utcNow(),1,'yyyy-MM')
`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/a877b693-c4c2-98a8-8a53-00141d422320.png)
UTC時間の扱いについては、こちらのブログでいろいろ試していますので参考にしていただけると嬉しいです。

https://mocabrown.com/blog/archives/6273

うまく日付をファイル名に用いたコピーができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/4e01122d-bf3d-a3f3-1cae-d332a4722be2.png)
【SwiftUI】ToggleStyleを使用してCheckBoxを作成する

# はじめに
SwiftUIにはチェックボックスがありません。
めっちゃ使う場面ありそうなのに。。。

ToggleStyleを使って自作してみます。

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-11-04 at 21.26.51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3f888990-4d4e-81d5-bbfc-88af647d1401.gif)

# 実装
```swift
import SwiftUI

public struct CheckBoxStyle: ToggleStyle {
    public func makeBody(configuration: Configuration) -> some View {
        HStack {
            Button {
                configuration.isOn.toggle()
            } label: {
                Image(systemName: configuration.isOn ? "checkmark.square" : "square")
            }
            .foregroundStyle(configuration.isOn ? Color.accentColor : Color.primary)

            configuration.label
        }
    }
}

extension ToggleStyle where Self == CheckBoxStyle {
    public static var checkBox: CheckBoxStyle {
        .init()
    }
}
```

# 使い方
```swift
import SwiftUI

struct ContentView: View {
    @State private var isChecked = false
    var body: some View {
        Toggle(isOn: $isChecked) {
            Text("利用規約に同意しました")
        }
        .toggleStyle(.checkBox)
    }
}
```

# おわり
今回はSFSymbolsを使ってチェックボックスを作ってますが、カスタムのViewを作ってオリジナリティを出すのも良さそうです
【Rails】form_withメソッドでURL指定が必要な場合

# Railsの`form_with`ヘルパーメソッドとURLの指定

Railsのフォーム作成において、`form_with`ヘルパーメソッドは非常に便利ですが、URLの指定が必要な場合とそうでない場合があります。以下に、`form_with`ヘルパーメソッドでURLの指定が必要なケースを説明します。

## 基本の使い方

基本的に、`form_with`ヘルパーメソッドはURLの指定が必要ありません。以下は典型的な使用例です。

```erb
<%= form_with model: @article, local: true do |form| %>
  <!-- フォームの内容を定義 -->
<% end %>
```

この場合、フォームは`@article`というモデルと関連付けられ、自動的に適切なURLが生成されます。ただし、いくつかの特別なケースではURLの指定が必要になります。

## ModelとControllerの名称が異なる場合

モデルとコントローラーの名前が異なる場合、`form_with`は自動的にURLを推測できません。この場合、URLを明示的に指定する必要があります。

```erb
<%= form_with model: @plan, url: calendars_path, class: 'form' do |f| %>
  <!-- フォームの内容を定義 -->
<% end %>
```

この例では、`@plan`モデルを使用しているが、コントローラーの名前が`calendarsController`であるため、`url`パラメータで正確なURLを指定しています。

## `application_record`とモデルの紐づきがない場合

Railsのモデルは通常`ApplicationRecord`を継承しています。しかし、モデルがこの標準的な紐づきを持っていない場合、URLの指定が必要です。
確認を行う際はビューファイルでなくモデルファイルの1行目を確認しましょう。

## まとめ

`form_with`ヘルパーメソッドは通常、モデルを使用してURLを自動的に生成しますが、モデルとコントローラーの名前が異なる場合や、モデルが`ApplicationRecord`と紐づいていない場合にはURLの指定が必要です。URLを指定することで、正確なフォームのアクションを設定できます。
ストアドファンクション(テーブル値関数)を作成する方法

売上年月を受け取り、その年月に売上のあった商品コードのテーブル返す
[GetSoldItems]というテーブル値関数を作成します:smiley:
以下は売上テーブルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3247892/8a5961b5-f22f-1a90-87f4-90256fb4cade.png)

## 実行するスクリプト
``` SQL
CREATE FUNCTION [GetSoldItems]
(	
	@FROM datetime,
	@TO datetime
)
RETURNS @SoldItems TABLE (
	商品ID NCHAR(10) NOT NULL
)
AS
BEGIN 
	INSERT INTO @SoldItems ( 商品ID )
	SELECT DISTINCT 商品ID FROM 売上 WHERE 売上日 BETWEEN @FROM AND @TO
	RETURN;
END
```
上記スクリプトを実行すると、以下のようにテーブル値関数が作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3247892/736823e1-b29b-75fe-b664-6b2de03e8e54.png)

## 実行結果
``` SQL
SELECT * FROM 商品マスタ	
INNER JOIN dbo.GetSoldItems('2023-11-01 00:00:00', '2023-11-30 00:00:00') 売上済商品
ON 商品マスタ.商品ID = 売上済商品.商品ID
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3247892/5c9487a7-771b-451e-059a-d9b74bec56c3.png)
引数で指定した年月に売上のあった商品コードを取得することができました。

## ポイント
:pencil2:テーブル値関数について
 - テーブル値関数の最後のステートメントはRETURNです。
 - テーブルの値を更新・挿入・削除するようなステートメントは記載できません。
 - テーブル値関数を作成する構文は以下の通りです。
 
 ``` SQL
 CREATE FUNCTION [ ファンクション名 ] (
    [ @入力パラメーター名1 ] [ 入力パラメーター名1のデータ型 ],
    [ @入力パラメーター名2 ] [ 入力パラメーター名2のデータ型 ],
    [ @入力パラメーター名3 ] [ 入力パラメーター名3のデータ型 ]
)  
RETURNS [ @戻り値のテーブル名 ] TABLE (
    [カラム名1] [カラム名1のデータ型] [NULL or NOT NULLなどのテーブル定義],
    [カラム名2] [カラム名2のデータ型] [NULL or NOT NULLなどのテーブル定義],
    [カラム名3] [カラム名3のデータ型] [NULL or NOT NULLなどのテーブル定義]
)
AS
BEGIN
    [ ファンクションで処理したい一連のT-SQLステートメント
      @戻り値のテーブルに値をインサートする ]

    RETURN;
END;
``` 

:pencil2: DISTINCTについて
 - 重複したレコードを一行にまとめることができます。

``` SQL 
SELECT DISTINCT 商品ID FROM 売上
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3247892/8a5961b5-f22f-1a90-87f4-90256fb4cade.png)
　↓　重複した商品IDは一行にまとめられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3247892/02c26e87-6f7c-ffd5-73cd-96156856d805.png)
C++17のモダンなループ

# C++17のモダンなループ
`C++17`ではモダンなループを書くことができます。例えば
```c++
for(int i=0; i<as.size(); i++) {
    std::cout << as[i] << std::endl;
}
```
というループは
```c++
for(auto a: as) {
    std::cout << a << std::endl;
}
```
と書くことがきます。`auto`は動的型付けしてくれます

さらに構造化束縛を使えばさらにモダンな見た目になります。
```c++
/*
Point (x, y)
*/
for(auto [xx, yy] : points) {
    処理...
}
```
小マイコンのSPIの速度を測って遊ぶ2(SPIあたらしい初期化)(STM32G071)


目的
SPIの初期化の値による速度を
カウンターを使って計って遊ぶ

参考

![o_cop746.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ce21a459-e00e-ef6b-e019-c436b7d555cb.jpeg)

http://www.musashinodenpa.com/arduino/ref/index.php?f=1&pos=539

●プログラム仕様

=SPI実験速度の項目
 STM32G071は、クロック32MHzで動いています。
 (1) 32MHz
 (2) 16MHz
 (3) 8MHz
 (4) 4MHz
 (5) 2MHz
 (6) 1MHz
 SPIの速度は、(4)から(6)まで実施


```c++

//SPI.beginTransaction( SPISettings( 4000000, MSBFIRST, SPI_MODE0) );
//SPI.beginTransaction( SPISettings( 2000000, MSBFIRST, SPI_MODE0) );
SPI.beginTransaction( SPISettings( 1000000, MSBFIRST, SPI_MODE0) );


```

●結果

1MHz

![o_cop751.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/313b81d4-c2a1-4660-cf44-e5c08920815f.jpeg)


2MHz

![o_cop752.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/98f09c84-9009-aed4-449f-e824be2389ac.jpeg)



4MHz

![o_cop753.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3b8a37a2-1411-6578-6332-e9ac05d63a2f.jpeg)





●プログラム

```c++


//SPI_spped_ck_071_2

//ヘッダーファイル
#include <SPI.h>

//定義
#define DW    digitalWrite

//初期化
void setup() {

  // SPIの初期化
  SPI.beginTransaction( SPISettings( 4000000, MSBFIRST, SPI_MODE0) );
  //SPI.beginTransaction( SPISettings( 2000000, MSBFIRST, SPI_MODE0) );
  //SPI.beginTransaction( SPISettings( 1000000, MSBFIRST, SPI_MODE0) );
  SPI.begin(); // 11 12 13
  pinMode(SS, OUTPUT); // 10
  DW(SS, LOW); // 10


loop1_a:
  SPI.transfer(0b11110000); //1
  SPI.transfer(0b11110000); //2
  SPI.transfer(0b11110000); //3
  SPI.transfer(0b11110000); //4
  SPI.transfer(0b11110000); //5

  SPI.transfer(0b11110000); //6
  SPI.transfer(0b11110000); //7
  SPI.transfer(0b11110000); //8
  SPI.transfer(0b11110000); //9
  SPI.transfer(0b11110000); //10

  SPI.transfer(0b11110000); //11
  SPI.transfer(0b11110000); //12
  SPI.transfer(0b11110000); //13
  SPI.transfer(0b11110000); //14
  SPI.transfer(0b11110000); //15

  SPI.transfer(0b11110000); //16
  SPI.transfer(0b11110000); //17
  SPI.transfer(0b11110000); //18
  SPI.transfer(0b11110000); //19
  SPI.transfer(0b11110000); //20
goto loop1_a;

} //setup

//無限ループ
void loop() {
} //loop

```
Big Objectについて

データが 2,000 万行から数十億行に至る場合は Big Object を推奨します。
Big Object は非リレーショナルデータベースを使用してデータを格納します。
Big Objectの設定はカスタムオブジェクトとほとんど同じ。

次に該当する場合は、Big Object を使用します。
1. 数百万行から数十億行のデータを処理する必要がある。	
　・カスタムオブジェクトに比べるとストレージは低価格	
2. フルデータセットのデータと集計の多数のセットを (非同期 SOQL を使用して) バッチ処理する必要がある。	
3. 業務レポートまたは Tableau CRM を使用してビッグデータを分析する必要がある。

いくつかの制限があります。
　・標準で提供されるユーザインタフェース（画面）がない
　・共有ルールが使えない
　・トランザクション処理には向かない
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669836/b315b9d6-01e7-da29-99f5-a0ebe1937ae8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669836/0ab63dab-c287-18a4-a326-fae7bede9bf7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669836/4f7e1409-7cd6-91d7-e44e-f690d7609419.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669836/3a96edd3-9047-969f-52f3-23634b5af67a.png)
非同期 SOQL とカスタムオブジェクトを使用して、小さなデータセットと集計を作成します。一度にデータセット全体を分析する必要がある場合は、Tableau CRM を使用します。データセットの一部に対して Salesforce の自動化を利用する場合は、Tableau CRM のほか、非同期 SOQL とカスタムオブジェクトも併用します。
OpenSSLサーバ証明書発行チートシート

# ■環境
**CentOS** : `CentOS Linux release 7.6.1810 (Core)` `openssl-1.0.2k-16.el7.x86_64`
**Ubuntu** : `Ubuntu 20.04.6 LTS` `openssl 1.1.1f-1ubuntu2.20 amd64`

# ■CentOS
コンフィグファイル：`/etc/pki/tls/openssl.cnf `
シリアル番号ファイル：`/etc/pki/CA/serial`
インデックスファイル：`/etc/pki/CA/index.txt`
ルート証明書：`/etc/pki/CA/certs/ca.crt`
ルート秘密鍵：`/etc/pki/CA/private/ca.key`
サーバＣＳＲ：`/etc/pki/CA/certs/server.csr`
サーバ秘密鍵：`/etc/pki/CA/private/server.key`
サーバ証明書：`/etc/pki/CA/newcerts/01.pem`

```text:setup
■関連ファイル作成
# touch /etc/pki/CA/index.txt
# touch /etc/pki/CA/serial
# echo 01 > /etc/pki/CA/serial
# cat /etc/pki/CA/serial


■openssl.cnf修正
# ll /etc/pki/tls/openssl.cnf 
# cp -p  /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf.org
# cat /etc/pki/tls/openssl.cnf

# vi /etc/pki/tls/openssl.cnf
-----------------------------------------
certificate     = $dir/certs/ca.crt
private_key     = $dir/private/ca.key
-----------------------------------------
# cat /etc/pki/tls/openssl.cnf
# diff  /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf.org


■ルート秘密鍵およびルート証明書の発行
# openssl req -new -x509 -extensions v3_ca -keyout /etc/pki/CA/private/ca.key -out /etc/pki/CA/certs/ca.crt -days 3652


■サーバ秘密鍵の発行
# openssl genrsa -aes256 -out /etc/pki/CA/private/server.key 2048


■サーバ秘密鍵パスフレーズ除去
# openssl rsa -in /etc/pki/CA/private/server.key -out /etc/pki/CA/private/server.key


■サーバＣＳＲの発行
# openssl req -new -days 1826 -key /etc/pki/CA/private/server.key -out /etc/pki/CA/certs/server.csr


■サーバ証明書発行
# openssl ca -in /etc/pki/CA/certs/server.csr -config /etc/pki/tls/openssl.cnf


■サーバ証明書確認
# ll /etc/pki/CA/newcerts/01.pem
```

# ■Ubuntu
コンフィグファイル：`/etc/ssl/openssl.cnf `
シリアル番号ファイル：`/etc/ssl/CA/serial`
インデックスファイル：`/etc/ssl/CA/index.txt`
ルート証明書：`/etc/ssl/certs/ca.crt`
ルート秘密鍵：`/etc/ssl/private/ca.key`
サーバＣＳＲ：`/etc/pki/CA/certs/server.csr`
サーバ秘密鍵：`/etc/ssl/certs/server.csr`
サーバ証明書：`/etc/ssl/newcerts/01.pem`

```text:setup
■関連ファイル/ディレクトリ作成
# ll /etc/ssl/
# mkdir /etc/ssl/CA
# mkdir /etc/ssl/newcerts

# touch /etc/ssl/CA/index.txt
# touch /etc/ssl/CA/serial
# echo 01 > /etc/ssl/CA/serial
# cat /etc/ssl/CA/serial


■openssl.cnf修正
# ll /etc/ssl/openssl.cnf
# cp -p  /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.org
# cat /etc/ssl/openssl.cnf
# vi /etc/ssl/openssl.cnf
-----------------------------------------
dir = /etc/ssl
database	= $dir/CA/index.txt
certificate	= $dir/certs/ca.crt
serial		= $dir/CA/serial
private_key	= $dir/private/ca.key
-----------------------------------------
# cat /etc/ssl/openssl.cnf
# diff  /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.org


■ルート秘密鍵およびルート証明書の発行
# openssl req -new -x509 -extensions v3_ca -keyout /etc/ssl/private/ca.key -out /etc/ssl/certs/ca.crt -days 3652


■サーバ秘密鍵の発行
# openssl genrsa -aes256 -out /etc/ssl/private/server.key 2048


■サーバ秘密鍵パスフレーズ除去
# openssl rsa -in /etc/ssl/private/server.key -out /etc/ssl/private/server.key


■サーバＣＳＲの発行
# openssl req -new -days 1826 -key /etc/ssl/private/server.key -out /etc/ssl/certs/server.csr


■サーバ証明書発行
# openssl ca -in /etc/ssl/certs/server1.csr -config /etc/ssl/openssl.cnf


■サーバ証明書確認
# ll /etc/ssl/newcerts/01.pem
```
Fscalendarでreloaddata()時に画面が点滅するバグ

このバグの改修に丸二日ほど費やしたので備忘録として記事にします。
まず最初に環境としては、SwiftUIとFscalendarを使ってアプリの開発をしていました。

### バグの詳細
バグの内容はFscalendarで日付の選択をしたときに、選択した日付以外の日付がフラッシュするといった内容のものです。
![スクリーンショット 2023-11-04 20.01.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3087376/3b0cdbd3-8469-bcfd-2d24-d22bd16c06ff.png)

### 解決策
原因はupdateUIView()の中でreloadData()が複数回実行されていることでした。
これだけだとソースコードによって状況が違うと思いますので、私のパターンのソースコードの概要を以下に示します。
```ruby:qiita.swift
struct CalendarDispView : UIViewRepresentable {
    
    func makeUIView(context: Context) -> FSCalendar {
        typealias UIViewType = FSCalendar
        let fsCalendar = FSCalendar()
        
        fsCalendar.delegate = context.coordinator
        fsCalendar.dataSource = context.coordinator
        
        return fsCalendar
    }
    
    func updateUIView(_ uiView: FSCalendar, context: Context) {
        context.coordinator.updateCalendar(uiView as FSCalendar, with: selectedDate)
        
        // 該当箇所　ここが原因でフラッシュが発生していた
        uiView.reloadData()
    }
    
    func makeCoordinator() -> Coordinator{
        return Coordinator(self)
    }
    
    class Coordinator: NSObject, FSCalendarDelegate, FSCalendarDataSource {
        var parent:CalendarDispView
        
        init(_ parent:CalendarDispView){
            self.parent = parent
        }
        
        func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
            parent.selectedDate = date
        }
    }
}
```

SwiftUIを使用して、Fscalendarを使用すると大体このようなコードになると思うのですが、私の場合は該当箇所でreloadData()を使っていました。

解決策は、reloadData()を必要な時のみ行うことです。

```ruby:qiita.swift   
    func updateUIView(_ uiView: FSCalendar, context: Context) {
        context.coordinator.updateCalendar(uiView as FSCalendar, with: selectedDate)
        // フラグがtrueであれば、reloadData()が実行されない
        if updateCheck.updateFlag { return }
        uiView.reloadData()
    }
```

reloadData()が複数回実行されることがなくなり、画面のフラッシュが発生しなくなります。
余談ですが、updateUIView()は構造体のプロパティが更新されるたびに呼び出されるため、reloadData()はFscalendarのイベントマークを更新するために使用していました。

わかりにくい文章ですが、ここまでお読みいただきありがとうございました。
LangchainによるLLMの進化：意思決定を可能にする"Agent"モデル

最近githubでlangchainについて色々勉強しました。特にlangchainにおいて最も重要な"Agent"の内容について中身を理解しましたので、それを共有したいと思います。
まずlangchainは、LLＭのために開発されたフレームワークです。（イメージとしては、ディープラーニングためのPyTorchやTensorFlowといった関係に近いです。）
langchainには主に以下の6つのモジュールがあり、"Agent"はこれらの中で最もコアな機能です。

![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/f09d2010-6dd5-0ca0-fa27-e4e084cdceb7.png)

## ①Agentとは
"Agent"はモデルに意思決定の機能を与えるものです。具体的に言うと、モデルが状況によって、適切なAPIやツールを活用して問題を解決する能力を提供します。
Agentを活用すればLLMが持っている多くの弱みを克服できます。
例えば、LLMは学習データに含まれていない情報に対しては適切に回答することができず、誤った情報を提供する（幻覚問題とも呼ばれる）傾向がありますが、Agentなら解決できます。
APIを使って、自分でインターネットに接続し、必要な情報を検索すれば、学習されたことない情報に関する問題にも対処できるようになりますね。
さらに、どのような状況でローカルのデータセットを利用して検索するか、どのような状況でインターネットを使うべきかまでも全部「Agent」が考えて作業します。

## ②ReActについて
langchainにはいくつかのAgentが用意されてます。（Agentより「モデルの考え方」に近いです。）
最もシンプルなAgentはReActです。
ReActはReasoning+Actingの略語で、もう少し具体的に分けると「思考＋行動＋観察」の三段階になります。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/ed159556-b96d-37fe-4ebe-614332c4f147.png)


## ③ReActの例
下の例を見るとわかりやすく理解できると思います。
例えば、「現在アメリカのバラの平均価格に15％を上乗せして販売したいならいくらにするべきか？」という質問をAgentに投げたら、Agentは以下のような流れで処理しました。（verboseというパラメーターをTrueにすれば、LLMがどのように問題を処理しているかの流れが表示されます。）
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/dde46043-44a3-6e48-6c85-353de335f332.png)


まず「思考」段階で、「現在アメリカのバラの平均価格はいくらなのか」を先に考えます、それに対してLLMは学習データにその情報がないため、調査が必要だと判断します。
次に、「行動」としてインターネットでの検索を行います（ネットにつなげるchain （serpapi.com）を呼び出して探しに行きます）。
その後、「観察」段階でインターネット検索の結果を確認します。そして再度「思考」に戻り、平均価格が判明したので、次の「行動」として「平均価格に15％を上乗せする」という計算が必要であると理解します。
この計算を行うために計算用の「chain」（計算機能を提供するAPI）を呼び出して計算します。（80.16*1.15）
最終的な計算結果を「観察」した後、「思考」を経て「最終的な答えを得た」という結果に至ります。そして、「求めていた結果を得られたので、ここで作業を終了する」として処理を終了します。

このようにLLMが意思決定できるのは、「AgentExecutor」と呼ばれるプロンプトの集まりのような関数を通じて実現されています。
AgentExecutorの詳細についてさらに理解を深めたい場合は、langchainの「agent.py」における「AgentExecutor」関数の中身をデバッグすればわかります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/478d27c2-1b40-38e3-e1e5-95ecb386f29f.png)

## ④他のAgent
ReAct以外にも他のAgentがあります。
例えば、Structured Tool Chat（複数の外部ツールAPIを組み合わせて使う）、Self-Ask with Search（自分の回答に対して質問をして、それに再び答えるというプロセスを繰り返す）、Plan and execute（マルチAgent）などがあります。
"Plan and execute"は今一番注目されてるマルチエージェントです。普通のAgentとの違いは"思考"（Plan）と"行動"（execute）をそれぞれ違うLLMに任せることです。（処理時間は長くなりますが、より複雑な問題も回答できます）

ReActについて：

https://arxiv.org/abs/2210.03629

マルチエージェント（Plan and execute）を最初に提出した論文：

https://arxiv.org/abs/2305.04091

END
【UE,C++メモ -4- 】 レベル内の要素を取得

## C++で取得
~~~C++
// アウトライナーからAActorをすべて取得
TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), Actors);
	for (AActor* Actor : Actors)
	{
		if (AHoge* Hoge = Cast<AHoge>(Actor))
        {
            HogeArray.Add(Hoge);
        }
    }
~~~
これで特定のアクタを取得できるが効率が悪い気がする。
エディタ上でも取得できるのでそれで良いだろう。
## UPROPERTY()のこと
`UPROPERTY(EditAnywhere)`　エディタ上で編集可能
`UPROPERTY(VisibleAnywhere)`　エディタ上で閲覧可能
大体これしか使わなかった。
細かく説明するとすると以下の表のように結構ある。
[参考サイト様](https://logicalbeat.jp/blog/8212/)
| 引数 | 説明 |
|:-:|:-:|
| EditAnywhere | レベルエディターおよびブループリントエディター上での閲覧・編集が可能 |
| EditDefaultsOnly  |  ブループリントエディター上での閲覧・編集が可能 |
| EditInstanceOnly  | レベルエディター上での閲覧・編集が可能  |
| VisibleAnywhere  | レベルエディターおよびブループリントエディター上での閲覧のみが可能  |
| VisibleDefaultsOnly  | ブループリントエディター上での閲覧のみが可能  |
|  VisibleInstanceOnly |  レベルエディター上での閲覧のみが可能 |
| BlueprintReadOnly  |  ブループリントエディター上でGetのみ公開 |
|  BlueprintReadWrite |  ブループリントエディター上でGet・Setの両方を公開 |
| Category = “TopCategory｜SubCategory｜…”  | ブループリントエディター上で表示される際のプロパティのカテゴリを設定  |

Categoryは結構使ったと思う。
このように、編集可能にしておき、ワールドに配置後、同ワールド内の要素を設定するのもありだし正直そのほうが楽な場合もある。
UPROPERTY()はUFUNCTION()、UCLASS()、UENUM()、USTRUCT()と数種あるがタイトルとかけ離れてくるため説明はしない。
Stable Diffusionでイラスト絵を出力するまで（2023/11/04現在）

## 目的
参考サイトを基にStable Diffusion Web UIをローカルでセットアップしようとしたら躓いたので記録に残します

webUI入れただけじゃ全然いい絵がでないことすら知らなかった…

## 参考サイト
各作業はこちらのサイト様を参照
* インストール作業

https://soroban.highreso.jp/article/article-036

* モデル導入

https://itdtm.com/sdweb-modelin/

* ネガティブプロンプト自動追加機能「EasyNegative」の導入

https://nagi.blog/generativeai-easynegative-v2/

## 作例
上記サイトを参考に適当に出力したものです。
ちょっと手は怪しいですが、試行錯誤10分でこの絵が作れるのは驚異的です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3604151/510f0f9c-4fc1-51f7-2f5e-d6cac042facb.png)

<details><summary>入力条件</summary>

cute girl, single, alone, white hair, nice smile, short cut, cat ear, wafuku, japanese traditonal cloths, blue eyes, white clothes, point color of clothes is light blue, wear white beret
Negative prompt: EasyNegativeV2
Steps: 32, Sampler: DPM++ SDE Karras, CFG scale: 7, Seed: 1025811022, Size: 512x512, Model hash: 54ef3e3610, Model: meinamix_meinaV11, TI hashes: "EasyNegativeV2: 339cc9210f70", Version: v1.6.0
</details>

## ハードウェア構成
* AMD Ryzen 7 5700G with Radeon Graphics
* メモリ 16.0 GB
* NVIDIA GeForce RTX 3060 Ti
* Windows 11 Home  22H2 64bit

## 躓きポイント
### インストール作業
#### 1. No module named "Torch".
症状：webui.batを実行するとPyTorchが見つからないというエラーで止まる
原因：PyTorchが最新バージョン（Python 3.12.0）に対応していなかった
対策
* Pythonをアンインストールして3.11.6をインストールし直す
* stable-diffusion-webuiフォルダを削除して作業やり直し

### 2. no module 'xformers'. Processing without...
症状：webui.batを実行するとxformersが見つからないというエラーで止まる
原因：xformersというモジュールを有効化できていないらしい
対策
* webui-user.batを以下のように修正
* 今後はwebui-user.batから起動
```shell:webui-user.bat
@echo off

set PYTHON=
set GIT=
set VENV_DIR=
set COMMANDLINE_ARGS=--xformers

call webui.bat
```
参考サイト

https://wikiwiki.jp/sd_toshiaki/%E3%80%8Cwebui-user.bat%E3%80%8D%E3%82%92%E7%B7%A8%E9%9B%86%E3%81%99%E3%82%8B

### ネガティブプロンプト自動追加機能「EasyNegative」の導入
#### 1. EasyNagetiveの導入確認場所の変更
症状：解説サイトで言及されている「花札」アイコンの消失
原因：バージョンアップによるレイアウト変更
対策：
* txt2imgタブ内のTextual Inversion (Generationの右隣)を選択
* 正常にインストールできていればEaxyNegative or EaxyNegative2のボックスが確認できる

## 最後に
日々情報が更新されている世界なので、この情報もいずれ古くなるかと思いますが、何かの参考になれば幸いです。
Stable Diffusionで期待以上の絵が出てくるとやっぱり楽しいですね。
【UE,C++メモ -3- 】コンテンツドロワー内の要素を取得

## コンストラクタで取得
```C++
#include "Kismet/GameplayStatics.h"

// マテリアルインスタンスを取得
static ConstructorHelpers::FObjectFinder<UMaterialInstance> MaterialInsance(TEXT("/Game/Materials/ExampleMaterial.ExampleMaterial"));
if (MaterialInsance.Succeeded())
{
    MyMesh->SetMaterial(0, MaterialInstance.Object);
}

// スタティックメッシュを取得
MyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMesh(TEXT("/Game/StaticMesh/SM_hoge.SM_hoge"));
if (StaticMesh.Succeeded())
{
	MyMesh->SetStaticMesh(StaticMesh.Object);
}
```
**この記述は必ずコンストラクタで実装しよう！！**
*自信は無いが..*
staticで生成することで、クラスに紐づかなくなるので、消えることがないデータとして保持することができているはず。
BPに変換して、エディタ上で変換した方がやりやすいと思う。
replace複数回とregどっちがいいんだろ

# 前説
文字列に対して、いらない文字を複数消したい時何を使えばいいんだろ
`replace`構文か正規表現か
ということで、調べてみたので備忘録として

# 結論

replaceが圧倒的に早かったです
１文字の探索ならということか
ただ納得はいってない...
有識者がいれば教えてください

# スクリプト

## 文字列生成

```python
import string
import random

def generate_text(length = 200):
  ch_text = ['"',' ','@']
  # 安全なランダム文字列を生成
  weighted_chars = {
    **{value:1 for value in string.ascii_letters + string.digits},
    **{value:10 for value in ch_text}
  }
  random_string = ''.join(random.choices(list(weighted_chars.keys()), weights=weighted_chars.values(), k=length))

  print(",".join([f"{t}: {random_string.count(t)}" for t in ch_text]))
  return random_string
generate_text()
```
調べたい文字に重み付けしてランダムに生成という感じです。その他文字は適当に英数字としました。

## 時間計測のプログラム

```python
text = generate_text(10000)
%time re_text=text.replace(" ", "").replace('"', "").replace('@', "")
%time sub_text = re.sub('[ "@]',"",text)

print(re_text==sub_text)
```

一応最後に検索結果が同じか出力してます
同じに決まってるけど



# 結果
```
": 1080, : 1106,@: 1101
CPU times: user 235 µs, sys: 1 µs, total: 236 µs
Wall time: 262 µs
CPU times: user 1.79 ms, sys: 0 ns, total: 1.79 ms
Wall time: 5.44 ms
True
```
これが結果
1000字の文字列に対して、各文字が1000くらい
これの検索結果が、replaceだと`262 µs`,正規表現で`5.44 ms`
実に、20倍くらい
逆だと思ってたのでとても驚きでした
文字数増えたらどっかで逆転するのかな？

# 余談
文字列置き換えってAIに使うよね
きっと
【注意】ポップアップ JS ライブラリ「Lightbox 2」での XSS 対策について

今回は、画像のポップアップ表示で有名な [JavaScript ライブラリ「Lightbox 2」](https://lokeshdhakar.com/projects/lightbox2/)を使用する際に自分がハマった点を紹介します。といっても、たいしたことは書けませんが、笑

## 概要
キャプションとして `` data-title ``で設定した内容がデフォルトでサニタライズされない。HTML 出力時にはエスケープされていたとしても。
``` html:xss-sample.html
<!-- 開くと、javascript が実行されます -->
<a href="https://image.example.com/path/to/image.jpeg"
    data-lightbox="group1"
    data-title="&lt;script&gt;alert('xss');&lt;/script&gt;">
Open Image
</a>
```

## 対策
### 方法１． オプションを設定する（おすすめ）
```sanitizeTitle```オプションを```true```に設定しましょう。
```js:example.js
lightbox.option({
    'sanitizeTitle': true
})
```
### 方法２． 二重にエスケープする
```php:example.php
$user_devil_text = "<script>alert('xss');</script>";
print htmlspecialchars( htmlspecialchars($user_devil_text, ENT_QUOTES) , ENT_QUOTES);
```

## 理由
```lightbox.js``` 本体を見てみると、```sanitizeTitle```オプションを設定しないとhtmlとして出力されてしまうようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669617/64f61ada-fb30-af4a-5185-8ae5a1388156.png)
*※ 上の画像は、[GitHub でのソースコード](https://github.com/lokesh/lightbox2/blob/686670d3b3088792e582df489ef50e6d0221b50d/src/js/lightbox.js#L489-L493)のスクリーンショットにマーカーしたものです*



[公式サイトのオプション一覧](https://lokeshdhakar.com/projects/lightbox2/#options)には載ってませんが、実はライブラリを見ると、コメントアウトされた注意書きがあります。
> If the caption data is trusted, for example you are hardcoding it in, then leave this to false.
> This will free you to add html tags, such as links, in the caption.
> 
> If the caption data is user submitted or from some other untrusted source, then set this to true to prevent xss and other injection attacks.

だいたいこんなことが書いてあります：
・キャプションを信頼できるものであれば false のままにしておいてください。html タグを自由に使えます。
・ユーザーや他の信頼できないソースから送信されたものである場合は、true　に設定してください。


# おわり
意外と気付かず、そのまま使ってしまいがちだと思うので、お気を付けください。
~~なに？ jQuery なんて古いって、、？~~

## 参考資料
この記事を書くにあたって、参考にした資料です。（順不同）
- 『PHP: htmlspecialchars - Manual』https://www.php.net/manual/ja/function.htmlspecialchars.php （2023年11月4日参照）
- 『Lightbox2』https://lokeshdhakar.com/projects/lightbox2/ （2023年11月4日参照）
- 『GitHub - lokesh/lightbox2: THE original Lightbox script (v2).』https://github.com/lokesh/lightbox2 （2023年11月4日参照）
micro:bitからOctoStudioへ記号を送信

# OctoStudio のスマホ間メッセージ

2023年10月24日に [OctoStudio](https://octostudio.org/ja/) がリリースされました。

https://www.media.mit.edu/projects/octostudio/press-kit/

この OctoStudio は、子ども向けで世界で最も人気のあるプログラミング言語であるScratchを作成した MITメディアラボ Lifelong Kindergarten グループ によって開発されました。

スマホのカメラやセンサーを使ったアプリを開発できますし、 **スマホ間のメッセージ機能を使えば、アプリ同士を連動させることもできます。**

**そうなると、 micro:bit をコントローラーとして使いたくなります。**

**プログラミング例**
![IMG_1021.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/9db98e9b-81cc-4c42-197d-ae8ceb782964.png)

# micro:bitをOctoStudioのコントローラーにする方法

OctoStudio のスマホ間メッセージ機能は、BLEのアドバタイジングで実現しているようです。
それをmicro:bitで実現可能とするのが、MakeCodeのユーザー拡張機能である **BLADV([pxt-ubit-bladv](https://github.com/jp-rad/pxt-ubit-bladv))** に含まれる `send` ブロックです。

**▼ サンプル プロジェクト m2o**

https://makecode.microbit.org/_X7AY0aDLrViF

## インストール：MakeCodeのユーザー拡張機能 - BLADV

この **BLADV([pxt-ubit-bladv](https://github.com/jp-rad/pxt-ubit-bladv))** は、MakeCode for micro:bitに対応したユーザー定義の拡張機能として、GitHubで公開されています。

https://jp-rad.github.io/pxt-ubit-bladv/

**インストール手順**

1. [**MakeCodeのページ**](https://makecode.microbit.org/)を開きます
https://makecode.microbit.org/
1. **「新しいプロジェクト」** を作成します
1. **プロジェクトの設定** （右上の歯車アイコン）で
**`No Pairing Required: Anyone can connect via Bluetooth`**
を **オン** にします
1. ブロックの **拡張機能** をクリックし、「拡張機能」画面を開きます
1. **検索欄** (`検索または、プロジェクトのURLを入力・・・`)に
**`https://github.com/jp-rad/pxt-ubit-bladv`**
と入力し、 **Enter** キーを押下します
1. **ubit-bladv** パネルが表示されますので、それを **クリック** して拡張機能をインポートします
1. **プロジェクトの設定** （右上の歯車アイコン）で、
`JustWorks pairing (default): Pairing is automatic once the pairing is initiated.`
と
`Passkey pairing: Pairing requires 6 digit key to pair.`
を **オフ** にし、**これら以外を** 全て **オン** にします

**プロジェクトの設定**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/4285acb4-fdf8-9078-b03a-14f8893413ac.png)

## メッセージ送信： sendブロック

`BLADV` の中から、 `reset` ブロックと `send` ブロックとを使ってプログラミングします。

`最初だけ` で、`reset` ブロックを実行し、メッセージを送信したいタイミングで、 `send` ブロックを実行するようにプログラミングします。`send` ブロックでは、5種類の記号を送ることができます。

**プログラミング例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/a2f9f754-ca66-cbd6-b086-48281b3ce739.png)


## メッセージ受信： OctoStudio でのプログラミング

OctoStudio でプロジェクトを作成し、メッセージ受信を待って、何らかの処理を実行するようにプログラミングします。
現行バージョン(2023/11/03現在)では、メッセージ受信のイベントブロックがありません。その為、繰り返し処理の中で、5種類の内の１つの記号を指定して、その受信を待つようにプログラミングします。

**ずっとで繰り返し待つ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/d9efae4c-7569-a208-b7bd-89b96ed987ea.png)


# 最後に

次のような場合にmicro:bitをコントローラーとして活用できそうです。

- スマホを振り回したりするのが、少し危険と感じる場合
- 外部のスイッチやセンサーを接続したい場合
- micro:bitを隠し持って、友だちを驚かしたい場合
【UE,C++メモ -2- 】GameModeについて

## 各クラスを設定する方法
#### C++で記述する場合
```C++
AMyGameModeBase::AMyGameModeBase()
{
    GameStateClass = AMyGameState::StaticClass();
    PlayerControllerClass = AMyPlayerGameState::StaticClass();
    DefaultPawnClass = AMyDefaultPawn::StaticClass();
}
```
この記述で設定が行える。
GameModeの設定はプロジェクト設定から行おう。
#### BPで行う場合
![GameModeの編集画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3277190/c823d1dc-a4ca-9327-114b-5b37dc0903c4.png "GameMode編集画面")
BPの編集ウィンドウを開き青枠内を編集すれば良い。
GameModeやGameStateはBPだとわかりやすい面が多々あるので、C++を元にBPを作成して調整することをお勧めする。
## GameModeBaseの役割
:::note warn
ゲームの設計の知識が浅いため、間違った知識を公開している可能性が高いです。指摘事項あればいただきたく存じます。
:::
* ゲームのルール、勝利条件等を設定する。
* ポーズを要求された場合、一時停止の処理内容を設定する。
* プレイヤー数やスペクテイター数の設定
* レベル間の遷移やゲーム全体のシーケンス遷移、制御。
* ワールド内にどのような要素があるのか。

これらの内容はサーバー上にのみ存在し、通常はプレイ中に変更されるデータはあまりあってはならず、クライアントが知る必要のある一時的なデータは絶対にあってはいけません。
※UnrealEngine 4.27 Documentationを参照し、一部抜粋しております。
時系列データの並列フィルタリングの最適化

**下記は、ChatGPTと散々やり取りをした後「このチャットでの一連のやりとりを整理してまとめてください。Qiitaの記事として公開できるよう、markdown形式で出力してください。」とお願いした結果の出力です。**

---

# 時系列データの並列フィルタリングの最適化

時系列データの分析において、ノイズを取り除くことは非常に重要です。特に、地球科学の分野では、観測データにフィルタを適用することによって、有用なシグナルを抽出する必要があります。Pythonの`numpy`や`scipy.signal`を用いたフィルタリング処理を効率的に行うための方法を、並列処理を交えながら紹介します。

## はじめに

データセットには様々な次元数があり、例えば3次元や4次元の配列を扱う場合があります。ここでは、3次元データには単一のフィルタリング処理を、4次元データには次元ごとに並列フィルタリング処理を適用する方法について考えます。

## フィルタリング関数の定義

### FFTフィルタリング関数

```python
def fft_filter(time_series, b):
    N = len(time_series)
    F = fft(time_series, n=2*N)  # 2*N でのゼロパディング
    H = fft(b, n=2*N)
    return np.real(ifft(F * H)[:N])
```

### ランツォスフィルタ

```python
def lanczos_filter(time_series, delta_t, f_cut, numtaps):
    b = signal.firwin(numtaps, f_cut, window='lanczos', fs=1/delta_t, pass_zero=True)
    return fft_filter(time_series, b)
```

### バターワースフィルタ

```python
def butterworth_filter(time_series, delta_t, f_cut, order):
    b, a = signal.butter(order, f_cut, btype='low', fs=1/delta_t)
    return signal.filtfilt(b, a, time_series)
```

## 並列処理を用いたフィルタリング

### FFTフィルタリング関数

```python
from numpy.fft import fft, ifft

def fft_filter(time_series, b):
    N = len(time_series)
    pad_to = max(len(b), N)
    F = fft(time_series, n=pad_to)  # FFTのサイズを調整
    H = fft(b, n=pad_to)
    result = ifft(F * H)
    return np.real(result[:N])  # 元のサイズにトリミング
```

### 並列処理を用いたフィルタリング関数の最適化

```python
from concurrent.futures import ThreadPoolExecutor
import numpy as np

def batch_filter(start, end, value, filter_func, *args, **kwargs):
    output_array = np.zeros_like(value[start:end], dtype=np.float32)
    for i in range(end - start):
        output_array[i] = filter_func(value[start+i], *args, **kwargs)
    return output_array

def filtering(timeseries_array, filter_func, *args, batch_size=100, **kwargs):
    # バッチ処理を用いてフィルタリングを並列実行
    with ThreadPoolExecutor() as executor:
        futures = []
        for start in range(0, len(timeseries_array), batch_size):
            end = start + batch_size
            if end > len(timeseries_array):
                end = len(timeseries_array)
            futures.append(executor.submit(batch_filter, start, end, timeseries_array, filter_func, *args, **kwargs))
        result = np.concatenate([future.result() for future in futures])
    return result
```

## まとめ

この記事で紹介した最適化された関数は、地球科学の研究者が時系列データを効率的に処理し、ノイズを除去するためのツールとして有効です。高次元のデータセットに対するフィルタリング処理を、並列処理を利用して高速化することが可能になります。

---
Lanczosフィルターを用いた気候データの解析

**下記は、ChatGPTと散々やり取りをした後「このチャットでの一連のやりとりを整理してまとめてください。Qiitaの記事として公開できるよう、markdown形式で出力してください。」とお願いした結果の出力ソノママです。**

---

気候データの長期トレンドと短期変動を分析するためにLanczosフィルターを適用する方法についての一連のステップを説明します。

## データセット

データセットは、時間（10950ポイント）、緯度（66ポイント）、経度（129ポイント）の3次元配列です。1日に4回のデータセットを持っており、30年分のデータを含んでいます。

## Lanczosフィルターとは

Lanczosフィルターは、特定のカットオフ周波数以上または以下の信号成分を抽出するために使用される窓関数を伴うFIR（有限インパルス応答）フィルタです。

### 実装のステップ

#### 1. フィルターの設定

```python
def lanczos_coef(window_size, cutoff_frequency):
    """Compute Lanczos coefficients."""
    sinc = lambda x: np.sin(np.pi * x) / (np.pi * x) if x != 0 else 1.0
    return np.array([sinc(2 * cutoff_frequency * n) * sinc(n / window_size)
                     for n in range(-window_size//2, window_size//2 + 1)])
```

この関数はLanczos窓関数の係数を計算します。

#### 2. フィルターの適用

```python
def lanczos_filter(data, window_size=121, cutoff_period=10):
    cutoff_frequency = 1.0 / cutoff_period
    nyq = 0.5 * 4  # 4 times daily data
    coeffs = lanczos_coef(window_size, cutoff_frequency)

    lf_anomalies = np.apply_along_axis(lambda x: np.convolve(x, coeffs, mode='same'), axis=0, arr=data)
    synoptic_anomalies = data - lf_anomalies

    return lf_anomalies, synoptic_anomalies
```

この関数はデータに対してLanczosフィルタを適用し、長期成分と短期成分を分離します。

#### 3. エラーの修正

適用中に生じたエラーを修正するための詳細なトラブルシューティングが行われました。

#### 4. データの可視化

最後に、得られたフィルター処理後のデータを可視化するための関数が構築されました。

```python
def plot_polar_stereo(fourier_data):
    # 処理内容
```

この関数は、フーリエ変換後のデータを南極ステレオ投影で可視化します。

## 結論

Lanczosフィルタを用いて気候データから長期成分と短期成分を抽出し、さらなる分析や視覚化のための基礎を提供する手法を説明しました。エラーのトラブルシューティングを通じて正確な結果を得ることができました。

---

記事をQiitaに公開する際には、追加で適切なタグ付けを行い、読者が内容を理解しやすいように適宜セクションを追加することが重要です。また、コードを実行するために必要なライブラリのインストール方法や、前提条件となるデータ形式についての説明も入れることをお勧めします。
Bootstrap臭の消し方10選

# Bootstrap臭の消し方10選

BootstrapはWebデザインにおいて非常に便利なツールであり、多くのWeb開発者にとって重要な要素となっています。しかし、Bootstrapを使いすぎると、サイトやアプリケーションに特有の「Bootstrap臭」が漂うことがあります。Bootstrap臭とは、Bootstrapのデフォルトのデザインやコンポーネントが強く反映され、独自性が失われてしまう現象です。このブログでは、Bootstrap臭を消すための10の方法をご紹介します。

## 1. カスタムCSSを利用する

Bootstrapのデフォルトのスタイリングをオーバーライドし、独自のデザインを適用するために、カスタムCSSを使用しましょう。自分のプロジェクトに合ったスタイルを適用することで、Bootstrapのデフォルトの見た目から脱却できます。

```css
/* カスタムCSSの例 */
.btn-primary {
  background-color: #FF5733;
  border-color: #FF5733;
  color: #ffffff;
}
```

## 2. カスタムクラスを作成する

Bootstrapのクラス名に独自のクラス名を追加し、それを用いてスタイリングを調整することができます。これにより、Bootstrapのデフォルトスタイルと独自のスタイルを組み合わせることができます。

```html
<button class="btn btn-primary my-custom-button">カスタムボタン</button>
```

```css
/* カスタムクラスのスタイリング */
.my-custom-button {
  background-color: #FF5733;
  border-color: #FF5733;
  color: #ffffff;
}
```

## 3. カスタムテーマを使用する

Bootstrapにはカスタムテーマを適用できる機能があります。これにより、Bootstrapの見た目を完全に変えることができます。公式のBootstrapテーマギャラリーから好みのテーマを選び、プロジェクトに適用しましょう。

## 4. レスポンシブデザインをカスタマイズする

Bootstrapはレスポンシブデザインのフレームワークでもありますが、それをカスタマイズして独自のブレークポイントやグリッドシステムを設定できます。これにより、サイトのレイアウトを完全にコントロールできます。

```html
<!-- カスタムなブレークポイントの設定 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
```

## 5. カスタムフォントを使用する

Bootstrapのデフォルトフォントを変更し、プロジェクトに合ったフォントを選びましょう。Google Fontsなどのフォントライブラリを活用することで、個性的なデザインを実現できます。

```html
<!-- カスタムフォントの追加 -->
<link href="https://fonts.googleapis.com/css?family=Your+Custom+Font" rel="stylesheet">
```

```css
/* カスタムフォントの適用 */
body {
  font-family: 'Your Custom Font', sans-serif;
}
```

## 6. カスタムアイコンを使用する

Bootstrapにはアイコンライブラリが含まれていますが、独自のアイコンセットを使用することで、デザインに独自性を持たせることができます。Font AwesomeやMaterial Iconsなどが便利です。

```html
<!-- カスタムアイコンの追加 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
```

## 7. カスタムコンポーネントを作成する

Bootstrapのコンポーネントをベースにして、独自のコンポーネントを作成しましょう。これにより、Bootstrap臭を排除し、ユニークなデザインを実現できます。

```html
<!-- カスタムコンポーネントの例 -->
<div class="custom-card">
  <img src="custom-image.jpg" alt="Custom Image">
  <h3>カスタムタイトル</h3>
  <p>カスタムコンテンツ</p>
</div>
```

## 8. 不要なコンポーネントを削除する

Bootstrapにはさまざまなコンポーネントが含まれていますが、プロジェクトに必要のないものは削除しましょう。これにより、サイトの軽量化とスッキリしたデザインが実現できます。

## 9. カスタムJavaScriptを活用する

BootstrapのJavaScriptコンポーネントをカスタマイズして、独自の動作を実現しましょう。イベントハンドラやアニメーションなど、カスタムJavaScriptを追加することで、Bootstrap臭を排除できます。

```javascript
// カスタムJavaScriptの例
document.querySelector('.custom-button').addEventListener('click', function() {
  // カスタムアクションの追加
});
```

## 10. テストとフィードバックを受ける

最後に、プロジェクトを実際にテストし、ユーザ

ーからのフィードバックを受けましょう。ユーザーの要望に合わせてデザインを調整し、Bootstrap臭をさらに軽減できます。

## まとめ
Bootstrap臭を消すためには、カスタマイズと独自性が鍵です。これらの方法を組み合わせて、Bootstrapをベースにしつつも独自のデザインを実現しましょう。プロジェクトに適した方法を選んで、Bootstrap臭から脱却しましょう。
IntelliJ: Retrofit で HTTP リクエスト

次のサンプルの
「Retrofit を使用して Kotlin で HTTP リクエストを作成する」
と同じことを行いました。
[Kotlin で HTTP リクエストを作成する](https://www.delftstack.com/ja/howto/kotlin/kotlin-http-request/)

サーバーは、こちらと同じ設定とします。
[IntelliJ: Java 標準ライブラリーで HTTP リクエスト](https://qiita.com/ekzemplaro/items/aba4ba29fbe869d09d76)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/cb16d8c3-1e79-ee6b-02d2-a5a54e6a0219.png)

## 環境

```build.gradele.kts
（省略）
dependencies {
    implementation ("com.squareup.retrofit2:retrofit:2.9.0")
    implementation ("com.squareup.retrofit2:converter-gson:2.9.0")


    testImplementation(kotlin("test"))
（省略）
}
```

## プログラム
ツリー構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/93c328cd-281b-b8de-8853-6f18f884a8ba.png)

```Main.kt
import model.Country
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import service.CountryService
import service.CountryServiceImpl

fun getAllCountriesUsingRetrofit(){
    val countryService: CountryService =
        CountryServiceImpl().getCountryServiceFactory()

    val call: Call<List<Country>> = countryService.getAllCountries()

    call.enqueue(object : Callback<List<Country>> {
        override fun onResponse(call: Call<List<Country>>,
                                response: Response<List<Country>>
        ) {
            response.body()?.forEach(::println)
        }

        override fun onFailure(call: Call<List<Country>>, t: Throwable) {
            t.printStackTrace()



        }

    })
}

fun main(){
    getAllCountriesUsingRetrofit()
}
```

```model/Country.kt

package model

data class Country(var id: Number,
              var countryName: String)
```

```service/CountryService.kt
package service

import model.Country
import retrofit2.Call
import retrofit2.http.GET

interface CountryService {
    @GET("/tmp/country_all.json")
    fun getAllCountries(): Call<List<Country>>
}
```

```service/CountryServiceImpl.kt

package service

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class CountryServiceImpl {
    fun getCountryServiceFactory(): CountryService{
        val retrofit = Retrofit.Builder()
            .baseUrl("https://ekzemplaro.org")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

        return retrofit.create(CountryService::class.java)
    }
}
```

## 実行結果

```text
Country(id=18, countryName=Kenya)
Country(id=20, countryName=Tanzania)
Country(id=21, countryName=Ethiopia)
Country(id=22, countryName=Malawi)
Country(id=23, countryName=Country)
Country(id=24, countryName=Country)
Country(id=25, countryName=Kenya)
Country(id=26, countryName=Country)
Country(id=27, countryName=USA)
Country(id=28, countryName=USA)
Country(id=29, countryName=Kenya)
Country(id=30, countryName=Kenya)
```
【Vue.js】入力値をリアルタイムで画面に反映する

# はじめに
イベントオブジェクトを取得することで、inputタグのvalue値を即時に画面表示する方法を記録。

# イベントオブジェクト取得
inputイベント（要素のvalueの値が変化するたびに発生）でsetNameメソッドを発火させる。この時、イベントオブジェクトを取得するためにsetNameメソッドの引数にeventを設定。

```ruby:HTML
  <body>
    <section id="events" v-cloak>
        <h2>Enter Your Name!</h2>
        <input type="text" @input="setName">
        <p>Your Name:{{ name }}</p>
    </section>
  </body>
```

```ruby:Javascript
const app = Vue.createApp({
  data() {
    return {
      name:''
    };
  },
  methods:{
    setName(event){
      console.log(event)
    },
  }
}).mount('#events');

```
eventオブジェクトの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/a71ac497-58a3-ac60-e3b3-d26a6ee6783f.png)

targetのタブをさらに開くとValueの項目があり、入力値が表示されている。
この値を使用することで、画面に入力値を表示できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/aceb6c8c-79b5-c5e1-c17d-8ae8aff06745.png)


# 入力値をそのまま表示Ver
```ruby:HTML
  <body>
    <section id="events" v-cloak>
        <h2>Enter Your Name!</h2>
        <input type="text" @input="setName">
        <p>Your Name:{{ name }}</p>
    </section>
  </body>
```

```ruby:Javascript
const app = Vue.createApp({
  data() {
    return {
      name:''
    };
  },
  methods:{
    setName(event){
      this.name = event.target.value;
    },
  }
}).mount('#events');

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/b1aa11d8-1c3e-608e-5636-bcb681377942.png)



# 入力値を整形して表示Ver
setNameの引数に$eventを設定。

```HTML
  <body>
    <section id="events" v-cloak>
        <h2>Enter Your Name!</h2>
        <input type="text" @input="setName($event,'山田')">
        <p>Your Name:{{ name }}</p>
    </section>
  </body>
  ```

  ```javascript
const app = Vue.createApp({
  data() {
    return {
      name:''
    };
  },
  methods:{
    setName(event,lastName){
      this.name = event.target.value + ' ' +  lastName;
    },
  }
}).mount('#events');
  ```

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521217/c88a4879-df69-ec9c-7e04-f74faa92ecdb.png)

# 終わりに
入力値をリアルタイムで反映できるのは、結構使い勝手が良いと感じた。
他のアプリケーション作成にも活用していきたい。

# 参考
Vueの勉強で活用中⇒https://www.udemy.com/course/vuejs-2-the-complete-guide/
stable-diffusion-webui-dockerの初回起動時エラーを解決する

以前StableDiffusionのWebUIをDockerにて環境構築したのですが、久しぶりにアップデートして使用してみようと思ったらエラーが出て立ち上がらなくなっていたのでとりあえずの解決法を共有します。

# 前提

- 使用環境：[AbdBarho / stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker) ([6a34739](https://github.com/AbdBarho/stable-diffusion-webui-docker/commit/6a34739135eb112667f00943c1fac98ab294716a))
- エラー：`TypeError: AsyncConnectionPool.__init__() got an unexpected keyword argument ‘socket_options’`

## 原因

WebUIが使用しているhttpxのバージョンの不整合が原因となります。

- 参考：[としあきdiffusion Wiki](https://wikiwiki.jp/sd_toshiaki/%E6%9C%80%E8%BF%91%E3%81%AE%E4%B8%BB%E3%81%AA%E5%87%BA%E6%9D%A5%E4%BA%8B#o9bfb139)
- 参考：[TypeError: AsyncConnectionPool.__init__(), new install bug, httpx==0.24.1 #13840](https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13840)

## 対策

httpxのバージョンを2.5.1からダウングレードすることが必要です。

下記を追記することで解消可能です。

```docker:./services/AUTOMATIC1111/Dockerfile
RUN --mount=type=cache,target=/root/.cache/pip \
   pip install httpx==0.24.1
```

今回、挿入位置は`requirements.txt`の直後としました。

```diff_docker
RUN --mount=type=cache,target=/root/.cache/pip \
  pip install -r ${ROOT}/repositories/CodeFormer/requirements.txt

+ RUN --mount=type=cache,target=/root/.cache/pip \
+   pip install httpx==0.24.1
```

※[WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui)では修正方法が既に掲示されているので、遠からずこの記事で書いた対処法を行わなくともDockerでも問題なく起動が出来るようになると思います。待てる人はアップデート、待てない人にはこの記事が助けになれば幸いです。
新卒エンジニアでもアウトプットを頑張っている理由

![スクリーンショット 2023-11-04 17.32.13（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/62f97695-5cd4-30c6-09e7-cfa50ea592bd.png)


この記事は、「アウトプットの心構え Advent Calendar 2023」のアドベントカレンダーの投稿となっております。

https://qiita.com/advent-calendar/2023/output


リモートワークの中で、色々な方に「アウトプットの量がすごいですね」と褒めていただけることが増えました。とても嬉しいですね。今回は、新卒エンジニアでもアウトプットを頑張っている理由について記載していこうと思います。


# アウトプットの量の違いを確認してみた

まずは、以前よりもどのぐらい量が増えているのかを確認してみようと思いました。
Qiita APIを使用して、ゆめみで内定者アルバイトを始めた時期である<b>2020年の11月以降の投稿</b>とそれ以前の投稿数を比べてみました。

![スクリーンショット 2023-11-04 17.24.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/b156609b-0879-d101-365b-5c922265b4b3.png)

:::note info
感想
今までで100件を超えていることを知らなかったです💦
実際に数を見てみるとたくさんアウトプットしたんだなと驚きました。

:::



# 新卒エンジニアでもアウトプットを頑張っている理由

これはとてもシンプルです。アウトプットすることが自分にとって定着につながると信じているからです。
自分は物事を理解するのが他の人よりも遅いと自負しています。だから記事にすることでアウトプットをしています。

また、書いた記事をポートフォリオにできるというメリットがあると考えています。まだまだ転職は考えていませんが、いつか転職をしたりしたときに、実力の証明になります。そのため、頑張っています🔥

そして、記事にいいねしてくれることにより、喜びを感じることができることも理由の一つになります。承認欲求を高めることができると記事を書いて良かったと嬉しい気持ちになります😍


# 最後に

個人的には、すごい人が記事を書くのだけでなく、初学者の方もどんどん記事を書いてもいいと思います。間違っていたりしても、きっと強いエンジニアの方が修正してくれます。個人的には一部のエンジニアを除き、とても親切な方が多い印象があります。

だからこそ、僕は書き続けていこうと思います。自分のために。
　　
 　　
 　　
 　　
 　　
  　　
 　

　
　
   　
 　
# 最後の最後

おまけで自慢をさせてください(笑)

Findyを調べてみたときに、「スキル偏差値」と「想定年収」が高かったので共有したい！！

![スクリーンショット 2023-11-03 15.33.12（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/68205a0d-715e-ad07-bae0-d6a97bddf3c8.png)

中学や高校でもとったことのない偏差値！！！鬼嬉しいですね😂
想定年収も高くてニコニコできますね笑


これも個人的には、モチベーションを高めることができる要因でもあると思うので、来年は８０以上を目指したいです🔥

# ちょっとした宣伝

株式会社ゆめみの23卒のメンバーでアドベントカレンダーを作成しています。
新卒のフレッシュな記事がたくさん投稿予定なので、少しでも興味があれば購読いただけると幸いです！！

https://qiita.com/advent-calendar/2023/yumemi-23-graduation