OmniAICreator/Qiita-1.07M huggingface dataset:
スライド作成嫌いエンジニアのMarpとAIを用いたスライド作成

# スライド
今回、Marp, Claude Sonnet3.5を用いてスライド作成する話をスライドとしてMarpの勉強がてらMarpでまとめました。
スライドの最後の方に生成AIを用いてスライドを作成している部分があります。
（この記事の最後には生成AIで生成したMarpのスライドフルバージョン載せてます）
またMarkdownや短いですがプロンプトなどもGitHubに挙げているのでよければ見てください。
[生成の元にした記事はこちら]
- https://qiita.com/i-yuporon/items/aa799b1729f224d8d178

[GitHub]
- https://github.com/Inoue416/learn-marp/blob/main/README.md

[SlideShare]
- https://www.slideshare.net/slideshow/marp-ai-claude-sonnet3-5-d7e4/270577004

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/xBqqxrg3RV0POQ?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

# 目次
1. Marpって何？
1. Marpのできること、できないこと
1. まとめ

# 1. Marpとは？

**Markdown記法を用いてスライドが作れちゃう便利ツール**

- アプリがVSCode**１つで**完結
- うまく利用すれば**メモがそのままスライドに！**
- エンジニアなら**コーディング感覚で**スライドを作成できちゃう！
- CSS・HTMLも利用できるので**カスタマイズ性が高い**
- **統一性**が出る

# Marpでできること・できないこと
### できること
- コーディング感覚で資料作成
- md記法でスライドが作れる
- VSCodeで資料作成できる
- CSSでカスタマイズ

### できないこと
- そもそもGUI使えない...
- 複雑な図形を作れない
- そもそもmd記法が必要
- 細かな調節にHTML・CSS必要
### 便利そうだけど、コーディングするのめんどくね？
**そもそもわい、CSS苦手...**

# 最強の味方AIに書いてもらおう！
### 指示は俺に任せろ！
と、いうことでこれからテキトーにmdでメモをとったファイルを投げて実際に作ってみます。

### 生成AIを使って試しに作ったスライド
フルバージョンになってます。
[生成の元にした記事はこちら]
- https://qiita.com/i-yuporon/items/aa799b1729f224d8d178

[SlideShare]
- https://www.slideshare.net/slideshow/react-suspense-next-js-loadingui/270577039

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/lGOewoCOEQPoyJ?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

# まとめ
- Marpはmdでスライドが作成できるツール
- HTML・CSSを用いれば、高いカスタマイズ性
- VSCodeの拡張機能でプレビューを見ながら作成できる
- AIを組み合わせることにより、爆速でスライドができる

### 僕みたいにスライド作成・CSS嫌いエンジニアには最高の手法だと思ってます
Java Gold SE 11 合格体験記

# **はじめに**
Oracle Certified Java Programmer Gold SE 11に合格したので、私なりの学習方法をまとめました。少しでも参考になれば幸いです。

# **下調べ**
まず、どんな問題が出題されるかを他の方の合格体験記を参考にしながら調べました。以下がその内容です。
・ストリームAPIとラムダ式が絡む問題が、7割出題される。
・黒本の章末問題に似た問題が、5割出題される。

# **学習方法**
使用したものは以下です。
・黒本（徹底攻略Java SE 11 Silver問題集[1Z0-815]対応 ）
・ChatGPT

基本的に黒本の各章を3周ずつ回し、13章の章末問題のみ4周しました。下調べで「ストリームAPIとラムダ式が絡む問題」が重要だと分かっていたので、この二つが絡む問題については、解説を見ても理解できないところがあればChatGPTで質問し、理解を深めていました。試験前日には悪あがきでJavaの公式ドキュメントを確認し、Stream APIの戻り値を頭に叩き込みました。
  
# **実際の試験問題の傾向**
下調べ通り、ストリームAPIとラムダ式が中心となる問題ばかりでした。ただ、黒本の章末問題に似た問題は、私の体感では8割出題されていました。
 　
# **最後に**
私は試験三日前に他の合格体験記を見て、「紫本もやったほうがいい」という記事を見て不安になりました（下調べしたのに）。しかし、実際の試験では黒本に似た問題がほとんどだったので安心しました。また、Java Silverの時より純粋な問題が多く、私はGoldの試験の方が解きやすく感じました。
format string 1のWriteup

# 

問題のソースコードがあるのでDLして表示してみると中身は以下のcコード

```c
#include <stdio.h>

int main() {
  char buf[1024];
  char secret1[64];
  char flag[64];
  char secret2[64];

  // Read in first secret menu item
  FILE *fd = fopen("secret-menu-item-1.txt", "r");
  if (fd == NULL){
    printf("'secret-menu-item-1.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(secret1, 64, fd);
  // Read in the flag
  fd = fopen("flag.txt", "r");
  if (fd == NULL){
    printf("'flag.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(flag, 64, fd);
  // Read in second secret menu item
  fd = fopen("secret-menu-item-2.txt", "r");
  if (fd == NULL){
    printf("'secret-menu-item-2.txt' file not found, aborting.\n");
    return 1;
  }
  fgets(secret2, 64, fd);

  printf("Give me your order and I'll read it back to you:\n");
  fflush(stdout);
  scanf("%1024s", buf);
  printf("Here's your order: ");
  printf(buf);
  printf("\n");
  fflush(stdout);

  printf("Bye!\n");
  fflush(stdout);

  return 0;
}
```

bufに読み込んだ値を書式指定しないでprintfで表示している箇所がある。

```c
  scanf("%1024s", buf);
  printf("Here's your order: ");
  printf(buf);

```

これはformat string bug (fsb)と呼ばれる脆弱性で、printfなど書式指定を扱う関数において攻撃者は書式指定文字列を入力することでプログラム内部のスタック上の値を読み取ったり、任意のアドレスに書き込みを行うことができる。

今回はローカル変数flagの値を知りたいので%pでスタック上の値を読み取ることを試みる


`%14$p` あたりを指定するとフラグらしき文字列（をエンコードした値）があらわあれるので%15$p、%16$p、…と値を読んでデコードするとフラグが得られる

### 参考
- https://www.notion.so/Format-String-Attack-bf9ae57474be42a1b0628b2193b7d2b2?pvs=21
- https://gist.github.com/hhc0null/08c43983b4551f506722
- https://kataware.hatenablog.jp/entry/2017/12/08/233903
抽象クラスとインターフェースの使い分け（血筋とギプスでイメージしてみる話）

## はじめに
https://qiita.com/igayamaguchi/items/e1d35db0a14a84bda452

を見て、たしかにわかりにくいよな～って思って下書きにしていたけどそのままお蔵入りになっていたもの。血筋とギプスにたとえて、すっと読めるような短い記事にしておこう

- 血筋
- ギプス

「血筋」という言い回しは「親のリソースを活用する」というニュアンスがある。「◯◯家に伝わる日本刀は、一子相伝であればこそ扱える」という感じ。
いっぽうで「ギプス」という言い回しは「砕けた骨の回復を待つために固定する」というニュアンスがある。

**別にこんなもの使わなくてもいいのだ**。　:stuck_out_tongue_winking_eye:

ただ、何に便利なのかを知るとやはり使ってしまうのだ。それはなにかというと、「コンパイラを通して意図的にエラーを出せる」ということなのだ。つまり秩序なのだ。
これがチーム開発になるとめちゃくちゃ恩恵をうけることになる。

## 抽象クラス
抽象クラス（＝親クラス）は子クラスの基本的な振る舞いを定義する。これはまさに"血筋"の概念に似ていて、両親(抽象クラス)が子供に特定の特性を引き継ぐ。抽象クラス（＝親クラス）では、一部またはすべてのメソッドが定義されていない可能性があって、それらを子クラスで定義する必要がある。これにより、派生クラス（＝子クラス）は基底クラス（＝親クラス）のプロパティやメソッドを再利用すると同時に、新たな特性を持つことができる。

親が夏休みの自由研究を手伝って子供がよりよい結果を得られる。自由研究はもはや親の戦いでもある、みたいなイメージがいいだろうか（親がフィクサーであり、親のリソースを使うタイプ）

```py
from abc import ABC, abstractmethod


# 抽象クラス (Abstract Base Class)
class AbstractClassExample(ABC):

    @abstractmethod
    def do_something(self):
        print("Some implementation!")


# 基底クラスを継承した具体クラス
class AnotherSubclass(AbstractClassExample):

    def do_something(self):
        super().do_something()
        print("The subclass is doing something")


# インスタンスを作成
x = AnotherSubclass()
x.do_something()
```
```console:console（do_something()を一発実行すると2つの出力が得られる）
Some implementation!
The subclass is doing something
```

親クラスが定義だけをするパターンもある。これは、親が仕組みだけを用意したパターンだ（あの家系に生まれるとかならず首に輪っかをかけている、ような感じ）。子クラスが抽象メソッドを実装しない場合（首に輪っかをかけていない場合）、その子クラスのインスタンスを作成しようとするとPythonはTypeErrorを出す。これが「意図的なエラー」だ。
```py
from abc import ABC, abstractmethod


class AbstractClassExample(ABC):
    @abstractmethod
    def do_something(self):
        pass  # 抽象メソッドは実装を持たない


class AnotherSubclass(AbstractClassExample):
    def do_something(self):
        print("The subclass is implementing the abstract method.")


x = AnotherSubclass()
x.do_something()
```

## インターフェース
インターフェースはあるクラスが特定のメソッドを持っていることを保証するための契約（とよく言われるが、あまりわかってないうちに言われるとますます沼にハマる）。

インターフェース自体は機能を持たず、具体的な実装はそれを実装するクラスに任されている。これはまさに"ギプス"のようなもの。ギプスは壊れた骨が正しく再生すればいいように一定の形式を保持し、それが果たせれば、骨自体は成長の方法を選ぶ自由がある。同様に、インターフェースはプログラムの一部（クラスまたは他のインターフェース）が特定の動作を保証することを強制するが、その動作がどのように達成されるかは全く決めていない。

マックのハッピーセットには、「バーガー」と「飲み物」と「おもちゃ」を必ずつけてね、みたいな感じかな。ルールだよね。

```py
from typing import Protocol


class Quackable(Protocol):
    def quack(self) -> str:
        pass


class Duck:
    def quack(self) -> str:
        return "Quack!"


class Dog:
    def quack(self) -> str:
        return "Woof!"


# ここで animal が Quackable で定義したメソッドを持っているか？をチェックする
def make_it_quack(animal: Quackable) -> None:
    print(animal.quack())


duck = Duck()
dog = Dog()

make_it_quack(duck)  # Output: Quack!
make_it_quack(dog)  # Output: Woof!
```
自己紹介ページのフッターを編集ー2

お疲れ様です。

前回自己紹介ページのフッターに貼っている画像を、アニメーションを使ってじわりと表示するようにし、今日はその画像が順々に表示されるようコードを書きなおそうと思っていたのですが、冷静に考えると

「このページが表示された瞬間に画像たちがじわっと表示されてるから、スクロールしてたどり着くころには全部表示されてるし、これって意味ないんじゃ…？」

ということに気が付きましたので、かなり前に使った監視の observe を使っていきます:sweat_smile:

```diff_javascript
const imgItem = document.querySelectorAll('.item');

// 監視対象が範囲に交差したら実行する
const showItem = (entries) => {
for(let i = 0; i < imgItem.length; i++){
  const keyframes = {
    // 定数keyframesで画像の透明度を指定する
    opacity: [0, 1],
  };

// 再生時間の指定
  const option = {
    duration: 800,
  // fill: 'forwards'はキーフレームの状態を保持するという意味
    fill: 'forwards',
  };
imgItem[i].animate(keyframes, option);
}

entries[0].target.animate(keyframes, option);
};
// 監視の設定
const itemObserver = new IntersectionObserver(showItem);
// 監視するように指示
itemObserver.observer(document.querySelector('.item'));
```

とりあえず、以前のコードが直前にありましたので、見ながらコードを書いてみましたところ、itemObserver～の部分にエラーが出ました…
1つは observer ではなく observe でした　笑

もう1つは、今回.item は複数あるため、それらすべての監視が必要なので、それ用にしなければならないということでしたが、今の私にはそこまでの考えには至らず…

見直したりして定数名間違いなどないか確認した後、やっぱりchatGPT先生に泣きつきました。

```diff_javascript
// .itemの配列要素を個別に取得
const imgItem = document.querySelectorAll('.item');

// 監視対象が範囲に交差したら実行する
const showItem = (entries) => {

entries.forEach(entry => {
  if(entry.isIntersecting) {
 
-// for(let i = 0; i < imgItem.length; i++){
  const keyframes = {
    // 定数keyframesで画像の透明度を指定する
    opacity: [0, 1],
  };

// 再生時間の指定
  const option = {
    duration: 800,
  // fill: 'forwards'はキーフレームの状態を保持するという意味
    fill: 'forwards',
  };
-// imgItem[i].animate(keyframes, option);
-// }

entry.target.animate(keyframes, option);
}
});
};
// 監視の設定
const itemObserver = new IntersectionObserver(showItem);
// 各itemに対して監視するようにする
imgItem.forEach(item => itemObserver.observe(item));

-// // 監視するように指示
-// itemObserver.observe(document.querySelector('.item'));
```

赤い部分は1つ前のコードから削除した部分です。
更新し、ちゃんと交差した時に画像が表示されていることを確認しましたがなるほど…
今回は.item が4つあるので、forEach で各itemを監視するため、繰り返す必要がありますよね…
正解を示されてから改めて考えると、確かにそうです。
GPT先生から修正点をまとめたご説明もありましたので、よくよく読んでおきます。
Windowsで使えるショートカットキー

## はじめに
ショートカットキーは暗記せず、マウス操作で煩わしさを感じたものがあれば使うくらいの気持ちのほうがいいと思いました。

Windowsキーを使ったショートカットの中でこれ便利だなーって思ったやつを残します

## Windowsキーを使ったショートカット
1\. Windowsキー + 矢印キー
ウインドウの画面配置を決められます
設定の システム > マルチタスク にある [ウィンドウのスナップ] に紐づいていて
設定をオフにすると一部機能に制限がかかるようです

2\. Windowsキー + C
Microsoftが公開したAIアシスタント「Copilot」が起動します
タスクバー（画面下部の時計などが表示されている場所）の右下にあるアイコンのものです
何かAIに調べてもらいたかったりした際に使えるなと思っています
※Windowsのバージョンが古すぎたりするとそもそもCopilotが表示されていない可能性があります

3\. Windowsキー + E
エクスプローラーが起動します
他にもエクスプローラーで使えるショートカットがいくつかあるのでまとめます
 
4\. Windowsキー + I
アプリ「設定」を起動
こまめに設定を変えたい人はよく使うかもしれません

5\. Windowsキー + L
画面ロックをします
PCの前から離れる際にセキュリティ面から画面を即時に見られないようにできます

6\. Windowsキー + Shiftキー + S
SnippingToolが起動します
SnippingToolは表示されている画面の切り取り（スクショ）や録画ができます
↓SnippingToolで録画したものです↓
![Qiita用-SnippingTool.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677369/c4f133d8-a70e-e8a0-cef0-89c6cacb1b02.gif)

7\. Windowsキー + V
クリップボードを開きます
今までコピー（Ctrl + C）したものが履歴として見ることができます

## さいごに
はじめにも書いたのですがやっぱり使ってみるのが大事だと思います
もし興味があったらぜひ使ってみてください！
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（78/100）

【78日目】
トピック 8：SAPS/4HANAの製造指図（10/15）

≪問題78≫
計画手配と製造指図の登録時には、以下のどの場所でマスタデータ選択設定がチェックされますか。
（３つ選択）
□作業区
□作業手順
□部品表/配合表（BOM）
□MRP管理者
□製造バージョン

≪解答≫
□作業区
■作業手順
■部品表/配合表（BOM）
□MRP管理者
■製造バージョン

≪解説≫
◆計画手配と製造指図のマスタデータ選択においては、製造バージョン、作業手順、および部品表/配合表（BOM）で設定の確認が行われます。
◆指図のタイプや指図の登録方法によって、確認が不正確な場合の影響は異なりますが、計画手配は確認が正しくなくても登録されることがあります。また、バックグラウンド処理で製造指図が自動登録される場合、通常は確認が正しくないと指図登録が停止されます。
Cloudbuildとgoのginを使用してCloudRunとcloudFunctions(gen2)へデプロイする

## ディレクトリ構造
```
./
├─/cmd
│ └── main.go
├─/handlers
│ └── handlers.go
├── Dockerfile
├── go.mod
├── go.sum
├── cloudbuild.yaml
└── router.go
```
## goのソース
```main.go
package main

import (
	"context"
	"log"

	router "github.com/yourname/gin"

	"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
)
func main() {

	ctx := context.Background()

	gin := router.GinHandler

	// 実行する関数の登録
	if err := funcframework.RegisterHTTPFunctionContext(ctx, "/", gin); err != nil {
		log.Fatalf("funcframework.RegisterHTTPFunctionContext: %v\n", err)
	}

	port := "8080"
	if err := funcframework.Start(port); err != nil {
		log.Fatalf("funcframework.Start: %v\n", err)
	}
}
```
- ginから拝借した
```handlers.go
package handlers

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type album struct {
	ID     string  `json:"id"`
	Title  string  `json:"title"`
	Artist string  `json:"artist"`
	Price  float64 `json:"price"`
}

var albums = []album{
	{ID: "1", Title: "Blue Train", Artist: "John Coltrane", Price: 56.99},
	{ID: "2", Title: "Jeru", Artist: "Gerry Mulligan", Price: 17.99},
	{ID: "3", Title: "Sarah Vaughan", Artist: "Sarah Vaughan", Price: 39.99},
}

func GetAlbums(c *gin.Context) {
	c.JSON(http.StatusOK, albums)
}

func PostAlbums(c *gin.Context) {
	var newAlbum album
	if err := c.BindJSON(&newAlbum); err != nil {
		return
	}
	albums = append(albums, newAlbum)
	c.JSON(http.StatusCreated, newAlbum)
}
```
```router.go
import (
	"net/http"

	"github.com/yourname/gin/handlers"
	"github.com/gin-gonic/gin"
)

func GinHandler(w http.ResponseWriter, r *http.Request) {
	gin.SetMode(gin.ReleaseMode)
	engine := gin.Default()

	engine.GET("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message": "hello world",
		})
	})
	engine.GET("/albums", handlers.GetAlbums)
	engine.ServeHTTP(w, r)
}
```
## Dockefile
```dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main ./cmd/main.go

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]
```
## Cloudbuild.yaml
```yaml
steps:
# Cloud Run用のビルドとデプロイ
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest', '.' ]
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args: ['run', 'deploy', '${CloudRun-name}', '--image', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest', '--region', '${region}', '--platform', 'managed', '--allow-unauthenticated']

# Cloud Functions用のデプロイ
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: gcloud
  args: ['functions', 'deploy', '${CloudFunctions-name}','--gen2', '--runtime', 'go122', '--trigger-http', '--entry-point', 'GinHandler', '--region', 'asia-northeast1','--source','.','--allow-unauthenticated']
```

## CloudFunctionsの注意点
deployしたい関数（今回だとrouter.goのfun）とgo.modの階層が違うとエラーになります
ECS Fargateにログイン

## はじめに
ECS　FargateからMongodb Atlasに接続するアプリケーションを作成したときに、エラーの原因がわからず、結局Fargateにログインして確認した。以下、ログインしたときの手順のメモ。
大まかには、次のような流れでログインした。

1. Session Manager pluginをインストールする
2. タスク実行ロールにSession Manager 機能のアクセス許可を追加
3. ECS Exec機能を有効にする
4. ECSタスクのARNの確認
5. コンテナ名を取得する
6. ECS Fargateにログイン


## 前提
* AWS CLIはインストール済み
* OSはWindows 11

## 手順
### 1. Session Manager pluginをインストールする
Curlコマンドで次のURLからインストーラをダウンロードして実行する。
```bash
curl https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPluginSetup.exe -o SessionManagerPluginSetup.exe
```
ダウンロードしたインストラーを実行する。
```
./SessionManagerPluginSetup.exe
```

### 2.タスク実行ロールにSession Manager 機能のアクセス許可を追加
ECSのタスク実行ロールに設定しているロールに対して、Systems Manager のSession Manager 機能のアクセス許可を追加する。

ECSのタスク実行ロールに設定しているロールに対して、IAMから次のポリシーを設定する。
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}
```

### 3. ECS Exec機能を有効にする
 コマンドプロンプトからAWS CLIを使用して、ECS Execコマンドを機能を有効にする。
 ```
 aws ecs update-service --cluster <クラスター名> --service <サービス名> --enable-execute-command  
 ```
ECS Execコマンド機能が有効になったかどうかは、次のコマンドで確認する。
```
aws ecs describe-services <クラスター名> --service <サービス名> | findstr enableExecuteCommand
```
有効の場合、enableExecuteCommandがtrueにになっている。
```
"enableExecuteCommand": true
```

### 4. ECSタスクのARNの確認
ログイン時に必要となる、ECSタスクのARNを次のコマンドで取得する。
```
aws ecs list-tasks --cluster <クラスター名> --query "taskArns[]" --output text
```

### 5. コンテナ名を取得する
次のコマンドでコンテナ名も取得する。
```
aws ecs  describe-tasks --cluster SQSCluster --tasks <タスクのARN> --query "tasks[].containers[].name" --output text
```

### 6. ECS Fargateにログイン
次のコマンドでFargateにログイン
```
aws ecs execute-command --cluster <クラスタ名> --task <タスクのARN>  --container <コンテナ名> --interactive --command "/bin/bash"
```

## おわりに
Fargateにログインすることで、コマンドラインによる接続確認、ネットワークツールのダウンロード等、直接サーバを調べることができ、不具合調査をすすめることができた。
MIPSで様々なプログラムを書いてみる

# 概要
大学でアセンブリ言語を学んでいるので学んだ知識を共有できたらなということでJavaScriptとC言語で書かれたプログラムを色々[MIPS](https://ja.wikipedia.org/wiki/MIPS%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)アセンブラで書いていきます。今回は再帰関数をやっていきます。

# 1から任意の数nまでの合計 - その壱
数学のように書くとこのようになります。
```math
\sum_{n=1}^{n}k
```
コードを見てもらった方が早いでしょう。
以下にJavaScriptとC言語のコードを載せておきます。

<details><summary>JavaScript</summary>

```javascript:sum.js
function sum(n, res){
    if(n<1) return res;
    else return sum(n-1,res+n);
}
```
</details>

<details><summary>C言語</summary>

```c:sum.c
int sum(int n, int res){
    if(n<1) return res;
    else return sum(n-1,res+n);
}
```
</details>

アセンブリ言語では`for`や`while`の時と同じようにラベルを用いて、ループ処理のような感じで書いていきます。
そのままで解釈したMIPSコードを以下に示します。

```
SUM:
    addi $sp, $sp, -12
    sw   $ra, 0($sp)
    sw   $a0, 4($sp)
    sw   $a1, 8($sp)
    slti $t0, $a0, 1
    beq  $t0, $zero, SUM1
    add  $v0, $a0, $zero
    lw   $a1, 8($sp)
    lw   $a0, 4($sp)
    lw   $ra, 0($sp)
    addi $sp, $sp, 12
    jr   $ra
SUM1:
    add  $a1, $a1, $a0
    addi $a0, $a0, -1
    jal SUM
    lw   $a1, 8($sp)
    lw   $a0, 4($sp)
    lw   $ra, 0($sp)
    addi $sp, $sp, 12
```
少しだけ最適化出来るのでそのコードを以下に示します。

```
SUM:
    bne  $a0, $zero, SUM1
    add  $v0, $a0, $zero
    jr   $ra
SUM1:
    add  $a1, $a1, $a0
    addi $a0, $a0, -1
    jal SUM
```
今回のコードはint型なので`n`の値が0になる瞬間が必ずあります。`$a0`つまり`n=0`の時、初めて`n<1`が`False`になるので`n!=0`の時で`SUM1`にジャンプすればよいのでこうなります。今回の場合`sw`と`lw`で値を保存しなくてもいいので

# 1から任意の数nまでの合計 - その弐
やってることは同じなのですが個人的に引数に計算途中のものを使うのが嫌なので少し変えます。展開されてから計算される感じなので処理速度的にはよろしくないです。

<details><summary>JavaScript</summary>

```javascript:sum.js
function sum(n){
    if(n<1) return 0;
    else return n+sum(--n);
}
```
</details>

<details><summary>C言語</summary>

```c:sum.c
int sum(int n){
    if(n<1) return 0;
    else return n+sum(--n);
}
```
</details>

以下アセンブリのコードです。

```
SUM:
    addi $sp, $sp, -8
    sw   $ra, 0($sp)
    sw   $a0, 4($sp)
    bne  $a0, $zero, SUM1
    addi $v0, $zero, 0
    lw   $a0, 4($sp)
    lw   $ra, 0($sp)
    addi $sp, $sp, 8
    jr   $ra
SUM1:
    addi $a0, $a0, -1
    jal SUM
    lw   $a0, 4($sp)
    add  $v0, $v0, $a0
    lw   $ra, 0($sp)
    addi $sp, $sp, 8
    jr   $ra
```
その壱のプログラムより少し複雑になっていますが、`sw`で値を退避させる意味を私はこれで理解できました。

# 最後に
私も現在アセンブリ言語を学んでいる最中なので稚拙なコードですがご容赦ください。また、コードなどの間違いや誤字脱字等ありましたらコメントお願いします。それ以外の質問等もありましたらコメントください。自分の能力の限りで答えます。

## 参考
- [MIPSプログラムの基本型](http://www.takagi.inf.uec.ac.jp/mips/samples.html)
- [MIPSで書く再帰](https://tchh202.hatenablog.com/entry/2018/06/07/142455)
- MIPSリファレンスデータ(グリーンカード)
Terraformをざっくり把握してみる

## 概要

IaCですよ、などは把握済み。

## コマンドについて

- `terraform init`で初期化する
- `terraform plan`で生成するリソースを確認する
- `terraform apply`で生成する
- `terraform desctoy`で削除する

## プロバイダについて

- main.tfに記載することが多い
- プロバイダ=プラグインという理解でOK
- プロバイダはgemのようなもので、awsやgcpなどをterraform.required_providersブロックに記載する
- initコマンドでインストールでき、Gemfile.lockのようにlockファイルでバージョンが固定される
- init -upgradeオプションで更新も可能

## リソースについて

- main.tfに記載することが多い
- `resource <リソース名> <ローカル名> {}`と記載する

## 変数について

- variables.tfに定義だけ記載する
- 中身は.tfvarsファイルに定義する
- `-var-file=`オプションで指定するか、.auto.tfvarsだと自動で読み込まれる
- 機密情報なのでリポジトリには含めない
- S3でファイルを管理していることもある

## 出力について

- output.tfに記載する
- plan実行後に生成される情報を確認できる
- `terraform output`でも確認可能

## データソースとは

- `data <リソース名> <ローカル名> {}`と記載する
- 既に生成済みのリソースなどをteffaformで参照する場合に利用する

## バックエンドとは

- backend.tfに記載する
- `terraform.backend <名前> {}`で記載する
- apply後の生成状況を管理する.tfstateファイルをどこで管理するかを設定する
- 複数人で作業する前提でS3管理になることが多い

## ワークスペースとは

- 同じプロジェクト構成で複数のリソースを生成する場合に利用する
- `terraform workspace xxx`で利用可能
- 例えば、開発環境をメンバー分生成する場合などに使用しそう
- dev、stg、prdなどは細かい構成が違うことがあるため、使用しなさそうに思う

## プロビジョナとは

- ローカル（local-exec）やリモート（remote-exec）など、コマンド実行が記載できる
- デバッグし辛いのであまり使用しないのが良さそう

## ローカル変数とは

- モジュール内で使える変数
- `locals {}`で定義し、`local.xxx`で参照できる

## モジュールとは

- `module {}`で定義する
- `module.source`で使い回すファイルを指定する。URLも指定できる
- モジュール内で定義した変数を、moduleブロックで設定して使う形になる

##
【AWS】ELBリスナールールで送信元IPとホストヘッダーをAND条件にする

# 概要
ELBのリスナーのルールで、送信元IP(`source-ip`)とホストヘッダー（`host-header`）をAND条件にする方法を紹介します。

## 前提
AWS ELBでは、複数の`Conditions`を指定すると、それらはAND条件として扱われます。
つまり、条件の全てが満たされる場合のみ、適用されます。

今回は、「特定のGIPから、特定のドメインにアクセスがあった場合のみアクションするという条件を設定したい」と仮定しています。

# サンプルテンプレート

以下が、Cloudformationのサンプルテンプレートです。
（ELBやリスナーなどの部分は省略しています）

```yaml

Parameters:
  SampleIP:
    Type: String
    Default: "111.222.333.444/32"

  SampleDomainName:
    Type: String
    Default: "example.com"

Resources:

  ## （省略）ELBやリスナーなどを記載　##

  HttpsListenerRule:
    Type: 'AWS::ElasticLoadBalancingV2::ListenerRule'
    Properties:
      Actions:
        - Type: forward
          ForwardConfig:
            TargetGroups:
              - TargetGroupArn: !Ref TargetGroup
                Weight: 1
      Conditions:
        - Field: source-ip
          SourceIpConfig:
            Values:
              - !Ref SampleIP
        - Field: host-header
          Values:
            - !Ref SampleDomainName
      ListenerArn: !Ref HttpsDefaultListener
      Priority: 1
```

上記により、リスナールールは、`host-header`が`!Ref SampleDomainName`に一致し、かつ送信元IPアドレスが`!Ref SampleIP`に一致するリクエストに対してのみ適用されます。

管理コンソールから確認すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/8ab6b944-6a61-a0cc-eea5-4fb113ba60ec.png)

検証環境とかのもので、自社GIPからしかアクセスできないようにしたい、といった場合に活用できると思います。
Azure Functions 分離ワーカーモデルで BLOB trigger を準備する

最近 Azure Functions の.NET 8 分離ワーカーモデルをよく触っているのですが、何気なく BLOB trigger を追加したところビルドが通らなくなりました。自分メモとして書き残しておきます。

# やりたいこと
- Azure Functions の .NET 8 分離ワーカーモデルで BLOB trigger をビルドする
:::note
あくまでプロジェクト作成時の準備です。
:::

# 環境
- Visual Studio Community 2022 Version 17.10.4
- .NET 8
- Azure Functions 分離ワーカーモデル

# やったこと
## Visual Studio で言われるがままに
1. Azure Functions プロジェクトを追加（.NET 8 Isolated）
1. 初期設定で BLOB trigger を追加（ウィザードに沿って設定）
1. **ビルドできない！**
> BlobTriggerAttribute が見つかりませんでした

:::note warn
自動で追加してくれたと思った NuGet パッケージが足りないようです。
:::

## 手動で NuGet パッケージを追加
1. インストール済のパッケージを最新に更新
1. 関連しそうな `Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs` をインストール
:::note
分離ワーカーモデルでは `Microsoft.Azure.Functions.Worker.Extensions.*` のパッケージが使われるのでだいたいあたりが付きます。
:::

## ビルド成功

上記パッケージをインストールすることでビルドができるようになりました。インストール済みのパッケージをまずアップデートしないと最新版をインストールできいないので注意が必要です。
でもそのうち Visual Studio のアップデートで解決しそうですよね。

# 追記：デバッグ実行のためには…
デバッグ実行するために `local.settings.json` の修正が必要でした。

```diff_json
{
    "IsEncrypted": false,
    "Values": {
-        "AzureWebJobsStorage": "",
+        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
    }
}
```

:::note
プロジェクト作成時、`ランタイムストレージアカウントに Azurite を使用する (AzureWebJobStorage)` にチェックがついてないとここが空になるようです。
:::

---
# 参考

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage-blob?tabs=isolated-process%2Cextensionv5%2Cextensionv3&pivots=programming-language-csharp
Python3: mod7占い (paizaランク S 相当)やってみた


https://paiza.jp/works/mondai/s_rank_skillcheck_sample/mod7

```py:
from itertools import combinations

N = int(input())
DECK = [int(input()) for _ in range(N)]

print(
    sum(1 for cards in combinations(DECK, 3) 
        if sum(cards) % 7 == 0
        )
    )
```

デッキを読み込んで、3枚足すと7の倍数になる組み合わせを計数していく。まんまですな。

これでもタイムアウトせず、ACしてしまったんだけど、解法例を見ると直接modを取るんじゃなくて、早い段階でmod 7を取って、nCrの計算に持ち込む感じらしい。

そっちの方向でやってみた。

```py:
from itertools import combinations_with_replacement, groupby
from math import prod

# n => r => nCr
ncr = (lambda n: lambda r:
       prod(range(n, n - r, -1)) // prod(range(r, 0, -1))
       )

# 0~6のうち、三つ足すと7の倍数になる重複組合せを
# (値, 頻度)のタプルのジェネレーターに
mod7 = ( ((k, len(list(g))) for k, g in groupby(x))
         for x in combinations_with_replacement(range(7), 3)
         if sum(x) % 7 == 0
         )

N = int(input())

a = [0] * 7
for _ in range(N):
    a[int(input()) % 7] += 1

print(
    sum(
        prod( ncr(a[i])(r) for i, r in m)
        for m in mod7
        )
    )
```
うん、確かに速くなった。
私が実践している学習スケジュールの立て方

## はじめに
プログラミング学習を始めたての皆さんはどのようにスケジュールを管理されていますか？
この記事では私が行なっている方法について、特別な方法ではありませんが、紹介したいと思います。

## どこまで計画を立てるのか
目標から逆算して最後まで立て切ってしまうのが良いと思います。
私は当初、1週間程度の計画を毎週立てるスタイルで学習を行なっていましたが、それだと計画からどれくらい遅れて・進んでいるかわからず、学習中に不安を覚えることも良くありました。
そこで、計画がずれた場合は都度修正すれば良いと考え、まずは目標までの計画を立て切ることを優先して行ったところ、今のところは順調に学習を進められています。

## 週・月単位の計画
Notionを用いて管理しています。
基本的にはタイムラインビューで管理し、長期のものはタスクに分けてボードビューも併用しています。
現在は目標までの計画を立て終えているので操作する機会は多くありませんが、毎日の計画を立てる時には必ず確認しています。

![学習計画](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362317/6d7c7496-f035-e804-6037-1c60f50e4487.png "学習計画")

画像では行なっていませんが、Notion公式の[Gantt chart](https://notion.notion.site/Gantt-chart-ca718d79f9d64c509798fc3bed3a290c "Gantt chart")のように、それぞれのデータベースにリレーションを設定するとより進捗状況が見やすくなると思います。

## 毎日の計画
iPadの[Planner](https://apps.apple.com/jp/app/planner-for-ipad/id1246635949 "「Planner for iPad」をApp Storeで - Apple")というアプリで管理しています。
Googleカレンダーを同期させて一日の空き時間がわかるようにしているので、毎朝、空いているところに一日の計画を書き込んでいます。
Notionで一元管理できれば良いのですが、より手軽なこの方法に落ち着いています。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362317/19272f35-4d23-074e-e47b-9cd5d28fa682.png" alt="毎日の計画">

## おわりに
もっと良い方法やサービスは探せばあると思いますが、まずは立てている計画を実行することを優先して進めていきたいと思います。
新しい「誤字俗字・正字一覧表」と「戸籍統一文字に関するワーキンググループ」

『民事月報』2024年6月号(Vol.79, No.6)を見ていたところ、「令和6年5月10日付け法務省民一第1083号法務省民事局長通達」が掲載されていた(pp.209-238)。

> 戸籍法の一部を改正する法律(令和元年法律第17号)が公布されたことに伴い、戸籍事務において社会保障・税番号制度に基づく情報連携が開始されることを契機として、当該情報連携を円滑に実施するため令和元年9月に「戸籍統一文字に関するワーキンググループ」を設置し、令和6年2月までの間、戸籍に記録されている文字について、有識者による漢和辞典等の確認作業を行いました。
> これを踏まえ、平成16年10月14日付け法務省民一第2842号当職通達「氏又は名の記載に用いる文字の取扱いに関する「誤字俗字・正字一覧表」について」を下記のとおり改めますので、これを了知の上、貴管下支局長及び管内市区町村長に周知方取り計らい願います。

あら、出てたのね。だったら「[戸籍統一文字に関するワーキンググループ](https://www.moj.go.jp/MINJI/minji04_00001.html)」で5年も作業した私(安岡孝一)にも、通達の写しを送ってきてくれたっていいのにな、と思いつつ、新しい「誤字俗字・正字一覧表」を見てみた。そうしたところ、p.227に妙な点を見つけた。

![2024-05-10minji.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/3f203fb8-6062-e6cd-d18a-d665757509a5.jpeg)

「𥙿」(文字情報基盤[MJ024002](https://moji.or.jp/mojikibansearch/info?MJ%E6%96%87%E5%AD%97%E5%9B%B3%E5%BD%A2%E5%90%8D=MJ024002))は俗字認定したので、ここに▲が付いてないのはおかしい。北海道での圧倒的な使用例とか、色んなデータちゃんとチェックしたはずなんだけど、どうして▲を付け忘れてるんだろ。うーん、他の字も全部チェックしなおさなきゃダメかな。
Postfixのメール送信が突然停止した

# はじめに
タイトル通り、Postfixで発生したエラーとその解決策について記事です。
実際に発生したのは半年以上前ですし、限定的な問題の可能性もありますが備忘録も兼ねて投稿しておきます。

# 起きたこと
とある朝、監視システムからPostfixで構成しているメールサーバーに関するアラートが届いてきました。
内容を見てみると**特定の時間からのメールのキューが全て溜まっていて未送信**となっている状況でした。なんじゃこりゃ。
うろ覚えですが大体200個くらいは溜まっていたと思います。

とりあえず何とかしなければいけないので、Postfixのログを見てみると何とも見慣れないログがずらりと並んでいました。
```
Feb  1 06:50:31 hogemail postfix/postfix-script[577760]: warning: not owned by postfix: /var/spool/postfix/saved/E8DBA160387
Feb  1 06:50:31 hogemail postfix/postfix-script[577761]: warning: not owned by postfix: /var/spool/postfix/saved/04FC416038A
Feb  1 06:50:31 hogemail postfix/postfix-script[577762]: warning: not owned by postfix: /var/spool/postfix/saved/30C76160396
Feb  1 06:50:31 hogemail postfix/postfix-script[577763]: warning: not owned by postfix: /var/spool/postfix/saved/6CC621603A0
Feb  1 06:50:31 hogemail postfix/postfix-script[577764]: warning: not owned by postfix: /var/spool/postfix/saved/7B55D1603A5
Feb  1 06:50:31 hogemail postfix/postfix-script[577765]: warning: not owned by postfix: /var/spool/postfix/saved/B67121603B2
---- 中略 ----
Feb  1 06:56:08 hogemail postfix/postqueue[610771]: warning: Mail system is down -- accessing queue directly
```

？？？
全く見たことない…`not owned by postfix`とか書いてあるからPostfixのディレクトリとかの権限設定の問題か…？
上記のせいでメール送信が行われず、キューが溜まっている状態なのは分かりました。

とりあえず分からないなりに考えて、`/var/spool/postfix`ディレクトリの権限を変えてみたり、その他色々とコマンドを叩きましたが直らず。
そうこうしている内にキューはどんどん溜まっていくので、焦っていたところ下記のコマンドを発見しました。

```
sudo postfix set-permissions
```

もしやこれか…？と思って実行してみた所、見事に問題が解消しました。
後は溜まっていたキューが順次処理されていき、メールも無事送信されていきました。
良かった…

# なぜこうなったのか？
結論から言うと、下記の<INS>Postfixのバージョンアップ</INS>が原因でした。
3.4.13-0ubuntu1.3 → 3.4.13-0ubuntu1.4

https://launchpad.net/ubuntu/+source/postfix/3.4.13-0ubuntu1.4

確かにセキュリティアップデートは自動で行うようにしていたけど、マイナーバージョンアップだしこんな大問題になるとは…
そもそもこのアップデートでなぜパーミッション周りの問題が起きたのか？までは分からなかったのですが、とにかく気を付けないといけないですね。

# postfix set-permissions とは
下記の公式マニュアルの中に記載があります。

https://www.postfix.org/postfix.1.html

要約すると、「**Postfixに関連するファイルとディレクトリの所有権とパーミッションを設定する**」コマンドとなっています。
今回の問題でも上記アップデートによってPostfixの権限設定がなぜか外れてしまったようで、再度設定を行う必要がある状態だったようです。
当然ながら頻繁に使用するコマンドではないのですが、いざという時のために覚えておいて損はないですね。

# 最後に
今回の問題はかなり限定的な状況ではあったのですが、今後起きた時に同じコマンドを思い出せる自信が無かったので記事にしておきました。
何ならどうやってこのコマンドまでたどり着いたのか、必死にやっていたせいか全く記憶にない…
もし似たような問題に当たった方がいれば参考にしてもらえれば幸いです。
AWS SOA 合格体験記

# はじめに
AWS SOA(C02)試験を受験して一発合格できたので、
忘れないうちに学習方法等メモしていきます。

# 受験前のステータス
・AWS実務経験は1年強、ただし小規模案件ばかりであまり深く触ったことはない（マネージドなWeb3層がメイン）
・AWS SAA、SAP取得済

# 学習の概要
学習時間：10～15時間程度（平日30分～1時間、休日2～3時間）
学習機関：約1週間
学習方法：Web問題集（CloudTech）＋公式サンプル

# 学習に使用したもの
- **Web問題集（[CloudTech](https://kws-cloud-tech.com/)）**
資格会員4980円/90日間です。
AWS SAPを受けるために購入していたものの期間が残っていたため、そのまま利用しました。
問題の質は普通に良いです。解説も悪くはないですが、正答以外の選択肢に対する解説（除外できる理由）がもう少し充実すると嬉しいです。
【良かったところ】Udemyと違って一問一答で解答・解説がみられる。（※出題自体は10問区切り）

- **公式サンプル問題**
公式サイトの試験概要のページに掲載されている[サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sysops-associate/AWS-Certified-SysOps-Administrator-Associate_Sample-Questions.pdf)。
- **公式練習問題**
SkillsBuilder内の「AWS Certified SysOps Administrator – Associate Official Practice Question Set (SOA-C02 - Japanese)」
20問分を無料で受講できます。

# 学習の流れ
### Web問題集で演習を実施
AWS SAProを受けてから3週間での受験予定だったため、基礎知識は十分ついているはず、ということでCloudTechのWeb問題集で演習を開始。
なかなかやる気が出ずに100問程度解いてタイムアップ。

### 公式サンプル問題＋練習問題を解く
公式サンプルは10/10、公式練習問題は14/20で若干の不安を抱えつつ、時間もないので学習完了。

# 受験時の流れ
テストセンターで受験。前回よりは集中して解けました。
やはりProfessional試験よりAssociate試験のほうが試験時間的にも楽ですね。

1周終わった時点で残り時間35分、フラグを付けた問題が20個。
ゆっくり見直して10分前に終了。

結果は2時間半程度でメールが来ました。
割と自信があったのですが、思ったより点数が低くてヒヤッとしました。

# 反省
CloudTechの問題集はせめて1周やり切れるようにすべきだった。
ちょっと力を抜きすぎました。

# 今後に向けて
AWS DVAを申し込みました。
SAP、SOAの感覚を忘れないうちにDVAまで取り切りたいです。
【備忘録】複数テーブルから優先度をつけて優先度の高いテーブルから1レコードのみ取得する方法

# はじめに
Aテーブルからデータが欲しいけど、AテーブルにデータがなければBテーブルから取得したいときの方法を下記に記載します。

## SQL文
```ruby:SQL
SELECT
       別名X.カラム_1,
       別名X.カラム_2
FROM
    (
      SELECT
            "1" AS ソートキー
            A.カラム_1,
            A.カラム_2
      FROM
            テーブル A
      WHERE
            条件_1

      UNION ALL
      
      SELECT
            "2" AS ソートキー
            B.カラム_1,
            B.カラム_2
      FROM
            テーブル B
      WHERE
            条件_1
    ) AS 別名X 
ORDER BY 別名X.ソートキー
LIMIT 1;
```
## おわりに
LIMIT句はすべてのDBで利用できるわけではないので使えないDBの場合は工夫が必要かもしれません。
Python リスト内包表記とappend()の比較について

# はじめに
　リスト内包表記は簡潔に記載できるが、どちらを使った方が良いのか。速度の面で比較しました。
　プログラムは、オイラリー・ジャパンの「入門Python3」を参考にしています。

# timeitを使用した時間の比較
```python:python
from timeit import timeit

def make_list_1():
    result = []
    for value in range(1000):
        result.append(value)
    return result
    
def make_list_2():
    result = [value for value in range(1000)]
    return result
    
print('make_list_1 の所要時間　', timeit(make_list_1, number = 1000),'秒')
print('make_list_2 の所要時間　', timeit(make_list_2, number = 1000),'秒')

# make_list_1 の所要時間　 0.05835742875933647 秒
# make_list_2 の所要時間　 0.03010526718571782 秒

```
# timeitとは
　与えられた文、setup コードおよび timer 関数で Timer インスタンスを作成し、その timeit() メソッドを number 回実行します。


https://docs.python.org/ja/3/library/timeit.html

　詳しい説明は、こちらのサイトが分かりやすいです。

https://note.nkmk.me/python-timeit-measure/

# 結びに
　「入門Python3」では、appendのほうがリスト内包表記の2倍以上時間がかかっているように記載されていますが、今回はそこまで差が出ませんでした。
　実際の環境で確認することも大事ですね。
キー一発でOCR+Linterかけてコマメに日本語をメンテナンスするツール書いた！

# 日本語の乱れはコンテキストの乱れ

日本人だけど日本語力に乏しいと言われ続けて生きてきました・・・

「～の、～の、って二度出てきて読み辛い」
「実装を行う、じゃなくて、実装するで良いんじゃない？」
「アプリなのかい？アプリケーションなのかい？どっちなんだい？」

みなさんも経験があると思うけど、こういう些細なミスは口語だったら言い直しと説明で済む。
でも、資料だけを見て、内容を判断しなきゃならない場合誤読を呼び込んでしまう。
「てにおはを正しく！」って昔、先輩に言われてた事、そういう事だって良いオジサンになってから思い返してる。
読み辛い文はコンテキストを乱し、伝えたいメッセージを弱めてしまう、そういうことだったのサ！

**リンター入れますか?**

# リンター入れられません・・・

Markdownとかテキスト形式ならtextlint使うなりのエコシステムに乗っかれた。
でもそうはいかない状況はしばしば発生する・・・

- Powerpoint
- ブラウザのスプシ
- PDFとかリッチなフォーマット
- そもそも画像フォーマット

元ソースがテキスト文章に寄せてないフォーマットの場合、なんらかの変換ツールでテキストだけ抽出する事になるんだけど
- オンラインの変換ツールは内容抜かれてない？って思うくらいに怪しい・・・
- 良い変換ツールが無い。ていうか変換ツール挟んでLintすると一度に大量の修正点出るので萎える（僕だけ？）

てな問題点あったりしませんか？

# コマメにちゃちゃっと出来ないかな？

コーディング時に当たり前のようにAIがコードをサジェストしてくれる時代に、自然言語でプレゼン資料書くのに当たり前レベルの文章チェックは入ってて欲しいじゃない。
それこそショートカットキーでサクサクっとさ。。。

**てな気持ちでツール書いてみました**

# 置き場所

<a href="https://github.com/yasutakatou/caplint"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/yasutakatou/caplint.png" width="460px"></a>

# 出来る事

OCRとLinterを組み合わせて文字認識にLinterをかけるツールです！
**すまん、手元にWindowsしか無いのでMacでは動かん！！**

① **任意のファイルにOCRをかけてLinterに流せます**
② **クリップボードにある画像にOCRをかけてLinterに流せます**
③ **ショートカットキー打ち込むとクリップボードにある画像にOCRをかけてLinterに流せます**
④ **ショートカットキー打ち込むと現在のアクティブウィンドウをキャプチャしてOCRをかけてLinterに流せます**

# 見ればわかるさ！③のモードが超絶おススメ

~~ていうか、Linterでエラー出ているのだったら、このREADMEも直そうぜ！というツッコミ入れたくなりますよね・・・~~

① 任意のファイルにOCRをかけてLinterに流せます
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/3754c1bb-01c4-5b4a-e97f-7c337714a6ba.png)

② クリップボードにある画像にOCRをかけてLinterに流せます
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/c6cdb2c3-dd35-3caa-38bf-c2d28d08e4f6.png)

③ ショートカットキー打ち込むとクリップボードにある画像にOCRをかけてLinterに流せます
![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/b3043222-5c3a-b666-eff1-3b595bb69aaa.gif)

④ ショートカットキー打ち込むと現在のアクティブウィンドウをキャプチャしてOCRをかけてLinterに流せます
![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/767131eb-f72d-1b82-88f5-de5745bbed32.gif)

# あとがき
OSS勢のはしくれとかXでポストしてるのに、前回のAIプロンプト活用ツールから一年も経っちまった！
いやー仕事忙しかったわけじゃないんですけどね、アイデアが降ってこなかったっていうか。。
もう少しでGitの草が空き地になるとこだったわｗ
次は一年開けずに書こう、相変わらずコーディング力は無いけど、こういうツール書けるのは僕だけな気がするし
（定義ファイルでしっかり中間言語化してて、他に使いまわし効くような作りなのも、らしいよなぁ）
無料かつ爆速のGroq AIでLlama3を試してみた

# 史上最速（！？）と噂のGroq AIを試してみた
最近話題のGroq AIを試してみたので、その体験を共有したいと思います。結論から言うと爆速激ヤバで、API利用は現在無料です。それでは、早速始めましょう。

## Groq AIとは？

Groqは、高速処理と低遅延性能を提供する最先端のAIハードウェアおよびソフトウェアを開発する企業です。

公式サイトはこちら: [Groq](https://groq.com/)
APIについて等のドキュメントはこちら：https://console.groq.com/docs/quickstart
ログイン後、APIキーを発行するURL：https://console.groq.com/keys

## Groqの仕組み

GroqのTensor Streaming Processor（TSP）アーキテクチャにより、データの連続フローが可能となり、処理効率が大幅に向上します。シングルコアモードとマルチコアモードの両方をサポートし、決定論的性能を提供することで、リアルタイム処理が必要なアプリケーションに適しています。とのこと。


## Groq AIの応用分野
この部分は[このページ](https://www.getguru.com/reference/what-is-groq-ai-and-how-to-use-it#:~:text=Groq)を参考にしています。

自然言語処理（NLP）では、カスタマーサービスのチャットボットなどに活用できます。

コンピュータービジョンでは、セキュリティシステムの画像・ビデオ解析などに利用されます。

ハイパフォーマンスコンピューティング（HPC）では、科学研究やデータ解析での計算処理を加速させます。

将来の応用として、自動運転車や高度なロボット工学など、幅広い分野での応用が期待されています。

## Groq AIの使用方法
この部分も[このページ](https://www.getguru.com/reference/what-is-groq-ai-and-how-to-use-it#:~:text=Groq)を参考にしています。

GroqCloudプラットフォームは、GroqのAIツールとハードウェアにアクセスできるクラウドベースのサービスです。

TensorFlowやPyTorchとの統合により、既存ツールを活用しながらGroqの性能を引き出せます。

使いやすいツールとドキュメントにより、すぐにAIモデルの構築や最適化が可能です。

GroqCloudでの実験を通じて、モデルをテストし改良することができます。

## 実際に試してみた！

Groq AIの魅力は、その処理速度にあります。実際に試してみると、驚くほど速く回答が生成されました。文字通り瞬きする間に回答が得られます。
今回使用したモデルは、「Llama3-8b-8192」というものです。このモデルは、非常に高性能で、多くのタスクに対応できることで知られています。

### GPT4oとGroq AIの回答速度を比較

以下のGIFは、同じ質問をGPT4oとGroq AIにした時の回答速度を比較したものです。Groq AIの速さが一目瞭然ですね。一体何が起きているんだとばかりのスピード感です。
GPT4oが使えるようになった時、速さにめっちゃ感謝したんですが、Groq AIが速すぎてGPT4o置き去りにしている・・・！

![Image from Gyazo](https://i.gyazo.com/68a4eb75d91c8ecc07e7d9f33013458f.gif)
![Image from Gyazo](https://i.gyazo.com/6abf507077815b161a72c905ef893562.gif)

即座に回答が表示されます。本当にすごい！

### Groq AIのAPIを使ったチャットボットで速度をみる

さらに、Groq AIのAPIを使ってチャットボットを作ってみました。以下のGIFは、そのチャットボットがどれほど速く応答するかを示しています。Groq AIの速度が際立っていますね。まるで回答をコピペしたかのような速度。。。
しかもAPIは今なら無料です！ヤッター！！！
でもこのボットのコード自体はGPT−4oに書いてもらいました。ちなみに「ユメカワなデザインにして」って言ったらこうなりました。
![Image from Gyazo](https://i.gyazo.com/4c328efcd6dd68911e66b3793650b361.gif)

## 結論

Groq AIは、その圧倒的な速度と使いやすさで、今後のAIツールのスタンダードとなる可能性を秘めていると感じました。しかし、まだ日本語は弱いみたいなので今後に期待したいところです。皆さんも是非、試してみてください。
MediaStore.Images.Media.insertImageは非推奨


# はじめに
端末内の写真などのデータを取得したりする際に
```
MediaStore.Images.Media.insertImage()
```
を扱っていたのですが、調べてみたところどうやら非推奨だったようで・・・
なので上の方法以外でできる方法を調べてみたので、備忘録として記事に残しておきます。

非推奨の理由は分かりませんが、
Android(API 29)からは位置データが保存されなくなっているようです。


# 内容
```
val contentValues = ContentValues().apply {
        put(Images.Media.DATA, metadata.path)
        put(Images.Media.DISPLAY_NAME, metadata.name)
    }
```

詳しくは以下の内容を参考にしていただければと思います。

# 参考

https://stackoverflow.com/questions/57726896/mediastore-images-media-insertimage-deprecated


https://stackoverflow.com/questions/57165523/android-mediastore-images-media-insertimage-vs-contentresolver-insert
kintone 秘密鍵からプラグインID取得

秘密鍵からkintoneプラグインのプラグインIDを生成するツールです。

# 概要

kintone-plugin-packer で、ppk オプションを指定しないと、プラグインID の名称で秘密鍵ファイルが作成されますが、規定で private.ppk の名称を指定しています。
そのため、kintone 環境にプラグインをアップロードするまでプラグインIDがわかりません。
そこで、作成された秘密鍵からプラグインID取得するスクリプトを作成しました。

https://www.npmjs.com/package/@rex0220/kintone-get-pluginid


# インストール

```bash
npm install -g @rex0220/kintone-get-pluginid
```

# 使用方法

- コンソールに表示
```bash
rex0220-get-pluginid -i private.ppk
```

- ファイル出力
```bash
rex0220-get-pluginid -i private.ppk -o pluginId.txt
```

# 使用例

```bash
> rex0220-get-pluginid -i private.ppk
pluginId: fjnoboohpdkgkiajpogkgfhdlipoddop
```

```bash
> rex0220-get-pluginid -h
オプション:
      --version  バージョンを表示                                         [真偽]
  -i, --input    Path to the private key file                    [文字列] [必須]
  -o, --out      Output file path for the pluginId                      [文字列]
  -h, --help     ヘルプを表示                                             [真偽]
  ```

# License
This project is licensed under the MIT License - see the LICENSE file for details.

This project includes code from the following MIT-licensed projects:

kintone/js-sdk (https://github.com/kintone/js-sdk/tree/main/packages/plugin-packer)
Groq tool api

chatgtp tools　というAPIがある。
これと同じことがGroqでも出来る。

## まとめ
モデルは、Llama 3 Groq 70B Tool Use がいい。(英語だけど)
特別仕様(Causal language model fine-tuned for tool use)なだけに、マルチでtoolを呼び出すなどツール処理に優れる。

Llama 3.1 70B も悪くないけど、同時に複数のtoolは呼ばない事が多い。

tool_choice で　最初の質問時には、required と 最後のときはnoneとして、tool呼び出しを管理すると、察しが悪いLLMでもうまくtool処理が出来る。

Llama 3 Groq 8B Tool Use でも、そこそこ処理してくれる。
## 流れ
公式ドキュメント読んで(Handling Tool Resultsは何か違う)
https://console.groq.com/docs/tool-use

公式サンプルを見るとわかりやすい。(受け取ったtool処理をどう返すか)
https://github.com/groq/groq-api-cookbook/blob/main/parallel-tool-use/parallel-tool-use.ipynb

### 1 最初に質問する
System Prompt
```
You are a calculator assistant. Use the calculate function to perform mathematical operations and provide the results.
```
User Prompt 計算問題を出してみる
```
A= 25 * 4 + 10
B= 10 * 3 + 60
which one is bigger?
```

### LLMからの返答
function　使って計算してくださいとmessageでお願いが来る。複数のこともある
```
[
{ "id": "call_6fcw", "type": "function", "function": { "name": "calculate", "arguments": "{\"expression\": \"25 * 4 + 10\"}" } }, 
{ "id": "call_3jqb", "type": "function", "function": { "name": "calculate", "arguments": "{\"expression\": \"10 * 3 + 60\"}" } }
]
```

### ユーザーはfunctionを使った結果を返す。
もちろん普通のチャットの時と同様に、最初のsystem promptとuser prompt、返ってきたLLMからのmessageも先に含めて。複数になるので、こっちの返信は、一つづつ処理して返す
```
{"content":"110","role":"tool","tool_call_id":"call_6fcw"},{"content":"90","role":"tool","tool_call_id":"call_3jqb"}
```
### LLMがこれを受け取った結果から、最初の質問に答えてくれます。
ただ、LLMによっては、一度に複数の質問がうまくできず、ここで再度質問してくることもある。

```
A is bigger than B
```
さくらのCDN（ウェブアクセラレータ）＋オブジェクトストレージでHTTPS配信すると、サイト開いた際にダウンロードになる問題の解決

# 発生事象
さくらのCDN（ウェブアクセラレータ）＋オブジェクトストレージでHTTPS配信すると、サイトを開いた際にダウンロードとなってサイトがブラウザで開けない

# 原因
index.htmlのcontent_typeがoctet-streamで配信されているから。
-> さくらのオブジェクトストレージで2024年7月現在Webからアップロードすると、すべてcontent_typeがoctet-streamで登録される。
-> boto3 使って適切にmime/typeを設定してアップロードする必要がある。


この画面からファイルアップロードしたことが原因だった。
![スクリーンショット 2024-07-28 20.02.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65312/2fe6d38c-522f-3b80-6026-88d28e48ee1d.png)




# 対策 boto3で適切にmime/typeを設定してアップロードする

### まずチェックする

```py
import boto3

# クライアントの設定
client = boto3.client(
    's3',
    endpoint_url="https://s3.isk01.sakurastorage.jp",
    aws_access_key_id='＊＊＊＊＊',
    aws_secret_access_key='＊＊＊＊＊',
    region_name='jp-north-1'  # リージョンに合わせて修正
)

# バケット名とオブジェクトキーを設定
bucket_name = '＊＊＊＊＊'
object_key = 'index.html'

# メタデータの取得
response = client.head_object(Bucket=bucket_name, Key=object_key)

# Content-Typeの表示
print(response)

```


### boto3でMimeType設定してアップロードする

```py
import boto3
import os
import mimetypes

# クライアントの設定
client = boto3.client(
    's3',
    endpoint_url="https://s3.isk01.sakurastorage.jp",
    aws_access_key_id='＊＊＊＊＊',
    aws_secret_access_key='＊＊＊＊＊',
    region_name='jp-north-1'  # リージョンに合わせて修正
)

# バケット名とオブジェクトキーを設定
bucket_name = '＊＊＊＊＊'
directory_path = '../＊＊＊＊＊/'

# ディレクトリ内の全ファイルをリストアップし、アップロード
for subdir, dirs, files in os.walk(directory_path):
    for file in files:
        if file == '.DS_Store':
            continue  # .DS_Store ファイルはスキップする
        full_path = os.path.join(subdir, file)
        with open(full_path, 'rb') as data:
            mime_type, _ = mimetypes.guess_type(full_path)
            if mime_type is None:
                mime_type = 'application/octet-stream'  # デフォルトの MIME タイプ

            client.put_object(
                Bucket=bucket_name,
                Key=os.path.relpath(full_path, directory_path),
                Body=data,
                ContentType=mime_type
            )

            print(f'Uploaded {file} with MIME type {mime_type}')
```
アウトプット習慣をつけるための決意表明

## はじめに
この度、プログラミングコミュニティ「JISOU」に参加する運びとなりました！
このコミュニティを通じてReact学習を通じて技術力を高めよう！ということで、まずはその第一歩目として決意表明をするための記事です。

## 何者？
某地方国立文系大学を卒業後、IT業界で約10年間プログラマー、システムエンジニアとして働いています。
元々はユーザー系のIT企業で働いていましたが、色々あって現在は都内の某SES企業に勤務中です。
今までずっとJavaに触れてきました（Spring、Struts等々…）。
フロントに関してはモダンな技術ではVue.jsを使う現場に1年程度おりましたが、Reactは一切触れたことがありません。

## なぜ「JISOU」に参加したの？
以前Vue.jsに触れたときはUdemyの講座を1、2個やってみたことで現場でついていくには十分だったので、
「新しい技術に触れてなくても現場に入ってから勉強すればいいかな」という考えを持っていましたが、「JISOU」代表の渡邉さんの↓の記事を見たことで感銘を受けて、参加することを決めた次第です。

https://qiita.com/Sicut_study/items/79838a4b8ec36bc3a961

こちらの記事は、主にアウトプットの大切さを謳っている記事なのですが、以下の一節に共感を覚えました。

> インプットは基本的に役に立ちそうことを学んでいるだけで、実践する理由がないため身につけることができません。
> アウトプットを中心に学ぶことは起きた問題に対して必要なことだけを学んですぐに実践できるためしっかりと身につけることができます

良かれと思ってUdemyで様々な講座を購入して視聴するだけで満足することもあった私にとっては胸が痛い一節です；；
しかも今まで自分でアウトプットなんてほとんどしたことないし。。。
と、いうわけで、この記事を書かれた渡邉さんのコミュニティで自分もアウトプットできるエンジニアになろう！ということで入会する運びとなりました！

## 目標
:::note
- 短期(3ヶ月)
カリキュラムを通じてReactの基礎を身につける！
- 中期(半年)
Qiitaを使ったアウトプットを生活の中に取り入れる！
JISOUのカリキュラムを全て完了させる！
- 長期(１年)
Reactを使った現場に入場できるような技術力を身につける！
:::

これからQiitaを通じて様々なアウトプットをしていきたいと考えています！
よろしくお願いいたします！！！

## JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！

https://projisou.jp/
【SOA】試験対策メモ その2

# AWS Systems Manager
## State Manager
cron式などで、グループ化されたマネージドノードに対して一括でRunCommandできるサービス。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-state.html

# CloudFormation
## サービスロール
デフォルトでは実行IAMのポリシーが参照される（危険）。
サービスロールを指定すると、そちらのIAMポリシーが参照される。

## DeletionPolicy 属性

```sample.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myS3Bucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
```

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html

## スタックの出力値のエクスポート
スタック間でリソースなどの情報を共有するために、スタックから情報をエクスポートできる。
エクスポートした変数はリージョン内の別スタックから参照できる。

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

# Client VPN
## 概要
インターネット回線経由でAWS VPCに接続するサービス。気軽
Direct Connect：専用線
Site-to-Site VPN：専用機器でインターネット経由

めっちゃわかりやすい↓

https://qiita.com/Masayuki-Goto/items/6f7f2bc100a2945d1292

## スプリットトンネルオプション
指定した一部トラフィックのみVPN経由にする機能。
AWS宛てトラフィックのみをVPNトンネル経由にできる。

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/split-tunnel-vpn.html

# Amazon QuickSight
## 概要
良い感じのBIサービス。

# CloudFront
## CloudFront Origin Shield
キャッシュ層を追加する機能。
リージョンをまたいでキャッシュを共有する。

https://dev.classmethod.jp/articles/amazon-cloudfront-support-cache-layer-origin-shield/

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html

# IAM Access Analyzer
## 概要
リソースのポリシーなどを確認し、アクセス状況や可否設定を調査できるサービス。
CloudTrail イベントを分析し、 IAM ポリシーを作成することもできる。
ポートの設定などを確認するものではない。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/what-is-access-analyzer.html

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-policy-generation.html#access-analyzer-policy-generation-howitworks

# Amazon Route 53
## Aliasレコード
AWSのリソース（ELB、CloudFront, S3など）のドメインを紐づけることができるレコード。
CNAMEレコード（ドメインを返す）に似ているが、CNAMEと違ってゾーンApexドメインでも使用できる。

# S3 Glacier
## S3 Glacier ボールトロック
ボールトロックポリシーを用いてボールトをロックできる。
ポリシーの適用実施は24時間のテスト期間が設けられる仕組みで、設定適用後、24時間動作確認ができる。
その後、オッケー的な処理をすることで変更が完全に適用される。

https://docs.aws.amazon.com/ja_jp/amazonglacier/latest/dev/vault-lock.html

# EC2
## プレイスメントグループ設定によるハードウェア分離
クラスタープレイスメントグループ：同一ハード上でインスタンスを実行する。インスタンス同士の緻密な連携が必要な場合に使用
パーティションプレイスメントグループ：いくつかのハードに分割され実行される。パフォーマンス気にしつつ、可用性気にする
スプレッドプレイスメントグループ：可用性全振り。全てのインスタンスを個別ハードウェア上に配置する

## Compute Savings Plans
リージョンをまたいでインスタンスを作成できる。
リザーブドインスタンスはリージョンを跨げない。

# KMS
## キーマテリアルをインポートして作成したCMKのローテーション
キーマテリアルがAWS製のものではない場合、キーのローテーションは自動で行えない。
ローテーションする場合は、再度新しいマテリアルをインポートする必要がある。

# Cloud trail
## aws cliを利用したログファイルの妥当性の検証
コマンドでさっくり

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-cli.html

# DynamoDB
## ディザスタリカバリ用防災手順
グローバルテーブルを作成し、DynamoDB Streamsからlambdaか何かでグローバルテーブルに同じ操作を行う。

# AWS Trusted Advisor
## 概要
べスプラの観点で自環境のリソースをコストやセキュリティの観点でチェックしてくれる。

# AWS Artifact
## 概要
AWSのコンプラドキュメントが掲載されているサービス。
Blender 4.2 から Unreal Engine 5.4 へ

## まとめ

* glTF (glb) で書き出すよ
* FBX は使わないよ
* スケール問題も回避できるよ
* 気づき程度の記事だよ（細かな検証はしていない）

## 環境

Blender 4.2.0
UnrealEngine 5.4.3

## 経緯

Blender の新バージョン、UEの新バージョン
久しぶりに触ってどうやってエクスポートすれば良いか迷いました。
（Epic 公式プラグインが新バージョンには対応していない。ちょっと触った感じエラーがでて動かない？？？っぽい）
結果的にglbでうまくいったので共有的に書きます。
各ツール側のアプデの説明とかにも「どれどれでできるよ」など書いてあるかもしれませんが追えずにいたため検証しました。


## 検証準備（Blender）

### メッシュ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/b87a1ad9-7430-9c97-86be-15831abc2fcb.png)

今回のテスト用スタティックメッシュです。
glTFのエクスポーターに上側（+Y Up）の座標軸を設定する項目があったため、上が分かるようにしました。
デフォルトキューブのサイズを X1m × Y1m × Z1m（当環境では100cm表記）で作成し、
上面を面の挿入 → 押出し → 全体にベベル　で作成しています。（Zは130cm）
下面が0（原点）です。

### スケルタルメッシュ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/ba3a45d3-f19f-3baf-3ed4-4bb9939db228.png)

今回のテスト用スケルタルメッシュです。
X1m × Y1m × Z2m
ボーンは下から Root Bone1 Bone2 Bone3 です。全部接続されています。
下面とルートボーンが0（原点）です。

## エクスポート・インポート手順

### Blender 側
File → Export → glTF 2.0 (.glb/.gltf)［日本語設定などの場合は読み替えてください］

デフォルト設定ではオブジェクトを選択していようがしていまいが全てのオブジェクトが書き出されるっぽいです。

### UE 側

おなじみコンテンツドロワーへのドラッグアンドドロップです。


## エクスポートの詳細

### Blender 側

日本語のツールチップが非常にわかりやすいので参考にしましょう。

#### Format

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/ec45d9b9-fdca-5d75-9a89-de969c40039a.png)

バイナリにまとめた 「glb」 か 「gltf + bin + textures」（それぞれ別に書き出す） の二択です。
（個人的にはBlenderで作ったものはテクスチャも別に書き出しているのでここで再び別にする必要は無いように思います。現状は glb が良さそう）

#### Include

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/eb562661-5ebd-d2b4-e7f8-ad2e34b3e578.png)

書き出しに含めるオブジェクトの選択です。画像では上３つにチェックを付けていますが、この設定で

* 選択したオブジェクトのみ
* 可視オブジェクトのみ
* レンダリング可能オブジェクトのみ

と、書き出しするオブジェクトを絞り込んでいます。設定の感じシーンやカメラごと書き出すこともできそうですね。
この設定をするとスケルタルメッシュの書き出しにメッシュとアーマチュアの両方を選択しないといけなくなりました。

#### Transform

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/8b06b8a3-9771-c6b1-da06-d6af7556faf9.png)

チェックを付けないとメッシュの向きが変わります。
位置も下に下がっているような...？

* チェックあり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/fdf01ef0-125e-485a-448b-bbca20b9a8a4.png)


* チェックなし

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/f88a4851-ab69-728d-012a-3fe82a94031f.png)

#### Data・Animation

項目が多くあまり検証できていません。かなり細かく設定ができそうです。
Blenderの新バージョンでプリセットの保存ができるようになりましたし、かなり面白そうですね。


アーマチュアを選択し、「Animation」の項目をアレコレするとアニメーションのみの書き出しができました。
その場合は　UE 側のインポート設定で「Import Only Animations」をチェックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/f08c49b5-60ac-ea56-ab78-3af5b0ca481c.png)

### UE 側

未検証

アニメーションのインポート時にスケルトンを指定するぐらい



## さいごに

ここまで確認いただきありがとうございます。
趣味程度しか触らない人間ですが UE Blender 間の FBX をﾒﾝﾄﾞｸｾｯって思ってたので
今まで気にかけないといけなかったことが気にしなくていいとなると非常に楽です。
記事中の間違いやより良い情報などありましたらコメントをいただけると嬉しいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985004/402b1b10-165b-bcfc-428f-99298d986f7e.png)
グニィ
CSSで脱px指定！remを使って快適なWebサイトを

## サイズ指定はpxよりremがオススメ
一般的に、サイズ指定にはpxのような『絶対単位』が使われます。

一方で%, em, remのような、基準に対して相対的に算出される単位のことを相対単位といいます。

参考↓

https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks/Values_and_units

様々なデバイスでWebサイトを見られるようになった現代においては、画面サイズに合わせて柔軟に表示が変わる『相対単位』の方が何かと都合が良い時が多くなってきました。

特に**rem**は近年のサイズ指定の単位においてベストプラクティスになりつつあります。

## なぜremが人気？
remは、HTMLの文字サイズを基準にするため、サイト全体のフォントサイズを一括で変更できます。
これにより、デバイスの画面サイズに合わせて、サイト全体のフォントサイズを調整することが可能です。

サイト全体のフォントサイズを変更したい場合、html要素の`font-size`を修正するだけで、他の要素のフォントサイズも連動して変更されます。

また、小さい文字が見えづらい高齢者などは、端末設定やブラウザ設定でフォントサイズを大きくしている場合があります。
px指定にしている場合、**絶対**単位なので、いくら端末設定でフォントサイズを大きくしても表示される文字サイズは変わりません。
rem指定の場合、設定に合わせてちゃんと大きくなってくれます。

## remの注意点
remを使うことによる恩恵は、デメリットにもなりえます。

先述したように、サイト全体のフォントサイズを変更したい場合、rem指定であれば簡単に変更できますが、実際はサイト全体のフォントサイズを一気に変更したいなんてケースはまれです。

大体は、特定の箇所のみフォントサイズを調整したいといったケースがほとんどです。
例えばクライアントから、「ここのフォントサイズを14pxにして欲しい」という要望があった場合、14÷16=0.875で`0.875rem`と記述しなくてはいけないので、計算が必要だったり、わかりにくかったりします。
[パーフェクトピクセル](https://chromewebstore.google.com/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=ja)を使って、寸分違わずデザインを再現する必要がある場合、pxを使わざるを得ません。

まあそもそもパーフェクトピクセルは本当に必要なのかという問題はあるのですが...

## まとめ
ある程度自由にサイズ指定ができる案件であれば、今後はremを使用するのが、最適かと個人的に思います。