OmniAICreator/Qiita-1.07M huggingface dataset:
Xcodeをバージョン16.0へアップデートしたのちに、ビルドした際にエラー"Undefined symbol: __mh_execute_header"が出力される。

# 環境
* Xcode Version 16.0
# 事象
* 担当エンジニアが、XcodeをVersion 16.0へアップデートしました。
* アップデート完了後に、UaaL(Unity as a Library)アプリをビルドしたところ下記のエラーが出力されました。
    ```
    Undefined symbol: __mh_execute_header
    
    Linker command failed with exit code 1 (use -v to see invocation)
    ```

# 解決策
* UnityFrameworkをセットアップする箇所のうち、`_mh_execute_header`を使用している箇所を、`_mh_dylib_header `へ修正する。
```Swift
        let bundlePath: String = Bundle.main.bundlePath + "/Frameworks/UnityFramework.framework"
        let bundle = Bundle(path: bundlePath)!
        if !bundle.isLoaded == false {
           bundle.load()
        }

        let frameworkClass = bundle.principalClass as! UnityFramework.Type
        let framework = frameworkClass.getInstance()!
        if framework.appController() == nil {
           let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
           // 変更前
           // machineHeader.pointee = _mh_execute_header
           // 変更後
           machineHeader.pointee = _mh_dylib_header 
           framework.setExecuteHeader(machineHeader)
       }

```

* エンジニアの環境では上記で解決しましたが、内容に誤りがあったり、他に情報がございましたらコメント頂けますと幸いです。

# 参考元
https://forums.developer.apple.com/forums/thread/760227

> _mh_execute_header is a synthetic symbols inserted by the linker to mark the beginning of a Mach-O executable. There are a suite of these, one for each Mach-O image type, all defined in <mach-o/ldsyms.h>. That header has doc comments that explain their usage.
> The most common cause of problems like this is with folks using the wrong symbol. _mh_execute_header is only relevant if you’re building an executable. If, for example, you’re building a dynamic library or framework, you must use _mh_dylib_header instead.

* Apple様の回答によりますと、UaaL(Unity as a Library)含め、Frameworkをビルドする際にはシンボル`_mh_dylib_header`を使用しなければならないようです。

https://stackoverflow.com/questions/54368717/undefined-symbols-for-mh-execute-header

* `__mh_execute_header`については、上記ページで解説しています。
OpenApiでdouble型の整数部と小数部の桁数チェックはできない

## 結論
OpenAPI自体には直接整数部や小数部の桁数を制御する機能はありません。ただし、OpenAPIのバリデーション機能を使って制約を追加する場合、`multipleOf`や`minimum`、`maximum`の属性を組み合わせて間接的に制御することができます。


## 例：整数部3桁、小数部2桁の`double`型をチェックする場合

### OpenAPI定義

```yaml
components:
  schemas:
    Price:
      type: number
      format: double
      description: 整数部3桁以下、小数点以下2桁までの値
      minimum: 0
      maximum: 999.99
      multipleOf: 0.01
```

### 各要素の説明

- **`type: number`**: 数値型であることを指定します。
- **`format: double`**: 浮動小数点数（倍精度）であることを指定します。`float`も使用可能ですが、精度が異なります。
- **`minimum: 0`**: 最小値を設定します。整数部3桁の制限に従い、0以上に設定しています。
- **`maximum: 999.99`**: 最大値を設定します。整数部3桁、小数点以下2桁を表す最大の数値は999.99です。
- **`multipleOf: 0.01`**: 小数点以下2桁を制約するために、0.01の倍数であることを指定します。これにより、値が0.01の倍数であることが保証され、小数点以下2桁に制限されます。

### 注意点

- `multipleOf`は小数点以下の桁数を制限するために役立ちますが、これは直接整数部や小数部を区別してバリデーションしているわけではなく、実際にどのようにバリデーションされるかはAPI実装に依存します。
- OpenAPIはあくまでスキーマを定義する仕様であり、実際のバリデーションロジックや細かいチェック（例えば、整数部と小数部のチェック）を実装するのはバックエンド（サーバーサイド）で行う必要があります。
egui 0.29を使う

# egui

とにかく破壊的変更が多いcrateです。すでに以前の情報が使えなくなっている部分もあるのでとりあえず動かしたり日本語化したりしながら何となく問題なく使えるところまでやってみましょう。

以前とは違い正攻法でやっていますので学びなおしにもどうぞ。

*※この記事は追記という形で更新してゆきます。*


## eframe_tamplate

まずはテンプレートプロジェクトをクローン。

```sh
git clone https://github.com/emilk/eframe_template.git
```

- Cargo.tomlの **[package]** 内の **name**、**authors**を変更する。
- src/app.rs の **eframe_template** を 適当なものに変更する（例: myapp、packageのnameと同じにする)
- ```cargo run --release``` ですぐ動作する。



## 日本語を使えるようにする。

フォントファイル(ttf)を用意し、以下のようなコードでデフォルトのフォントに指定することで表示・入力が可能になる。
**include_bytes!** は **src/** からの相対パスになるので適当なパスを指定する。


```rust
let mut fonts = egui::FontDefinitions::default();
fonts.font_data.insert("myrica".to_owned(), egui::FontData::from_static(include_bytes!("myrica.ttf")));
fonts.families.entry(egui::FontFamily::Proportional).or_default().insert(0, "myrica".to_owned());
fonts.families.entry(egui::FontFamily::Monospace).or_default().insert(0, "myrica".to_owned());
cc.egui_ctx.set_fonts(fonts);

```

eframe_templateのもともとのコードに対してこのように修正。
これで日本語の表示・入力が可能になる。

```rust
impl TemplateApp {
    pub fn new(cc: &eframe::CreationContext<'_>) -> Self {

        //日本語対応
        let mut fonts = egui::FontDefinitions::default();
        fonts.font_data.insert("myrica".to_owned(), egui::FontData::from_static(include_bytes!("myrica.ttf")));
        fonts.families.entry(egui::FontFamily::Proportional).or_default().insert(0, "myrica".to_owned());
        fonts.families.entry(egui::FontFamily::Monospace).or_default().insert(0, "myrica".to_owned());
        cc.egui_ctx.set_fonts(fonts);
        // ここまで

        if let Some(storage) = cc.storage {
            return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
        }

        Default::default()
    }
}
```

### text_edit_singlelineの日本語入力がおかしい

エンターキーまわりの処理の関係で日本語変換の確定動作のエンターでフォーカスを移す処理が入ってしまうためエンターキーを押すたびに入力が中断されてしまう。

```rust
ui.text_edit_singleline(&mut self.label);
```

eframe_templateのapp.rsでこのように書いてある部分がシングルラインの入力ボックス、これを以下のように書き直すと変換確定のエンターでフォーカスを失うことは無くなる。

逆にエンターでテキストエディットの入力確定動作が出来なくなるので利用目的をよく考えながら注意して都合の良い方を使う。

> ちなみにマルチラインの場合、同じようにこの変更をすると改行が出来なくなる。
とてもまともに使えないのでマルチラインで日本語入力が必要なら現在のeguiは候補にしない方が良いかも。

```rust
ui.add(egui::TextEdit::singleline(&mut self.label).return_key(None));
```

ここまで 2024.10.23
【エラー】Mysql2::Error: Duplicate entry '' for key 'items.index_items_on_email'

なぜか保存できません。

## エラー
``
ActiveRecord::RecordNotUnique in ItemsController#create
Mysql2::Error: Duplicate entry '' for key 'items.index_items_on_email'
``

コントローラーのクリエイトアクションが問題？
バリデーションの問題？
明日考えよう！！
【SpringBoot】EntityからDtoに詰め替える方法

## 方法1: 手動でのマッピング

#### エンティティ例: `User`

```java
@Entity
public class User {
    private Integer id;
    private String name;
    private Integer age;

    // コンストラクタ、ゲッター、セッターなど
}
```

#### DTO例: `UserDto`

```java
public class UserDto {
    private Integer id;
    private String name;

    // コンストラクタ、ゲッター、セッターなど
}
```

#### サービス層での手動変換

```java
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<UserDto> getAllUsers() {
        List<User> users = userRepository.findAll();
        return users.stream().map(this::convertToDto).collect(Collectors.toList());
    }

    private UserDto convertToDto(User user) {
        UserDto dto = new UserDto();
        dto.setId(user.getId());
        dto.setName(user.getName());
        return dto;
    }
}
```

- **メリット**: コードがシンプルで理解しやすい。
- **デメリット**: エンティティとDTOのフィールドが多い場合、手動での変換が煩雑になる。

## 方法2: ModelMapperを使用した自動マッピング

`ModelMapper`は、Javaオブジェクト間のマッピングを自動的に行うためのライブラリです。エンティティとDTOのフィールド名が一致している場合、非常に簡単に変換ができます。

#### 依存関係（Maven）

```xml
<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.1.0</version> <!-- バージョンは最新のものに合わせてください -->
</dependency>
```

#### ModelMapperの設定

`ModelMapper`をSpringのコンポーネントとして設定します。

```java
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ModelMapperConfig {
    
    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
}
```

#### サービス層での使用例

```java
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ModelMapper modelMapper;

    public List<UserDto> getAllUsers() {
        List<User> users = userRepository.findAll();
        return users.stream()
            .map(user -> modelMapper.map(user, UserDto.class))
            .collect(Collectors.toList());
    }
}
```

- **メリット**: コード量を大幅に削減でき、フィールド名が一致している限り、手動でのマッピングが不要です。
- **デメリット**: 複雑なマッピングやカスタムロジックが必要な場合には、調整が必要です。


### まとめ

エンティティをDTOに変換する最適な方法は、プロジェクトの要件によって異なります。以下にそれぞれの特徴をまとめます。

1. **手動マッピング**: シンプルなプロジェクトでは有効ですが、大規模プロジェクトでは煩雑。
2. **ModelMapper**: フィールド名が一致する場合には便利。動的な変換が少ない場合に推奨。
MCTへの道：トレイン・ザ・トレーナー1日目

趣味でマイクロソフト認定トレーナー（通称MCT）を目指しています。（趣味ってなんだよっていう話はいったん置いておく）

https://learn.microsoft.com/ja-jp/credentials/certifications/mct-certification

MCTの資格要件として、指導スキル証明書プロバイダー (ISCP) プログラムを受講完了する必要があり、今回はプログラムとして選定されているトレノケート株式会社の「トレイン・ザ・トレーナー」を受講中です。「トレーナーを育成するための研修」という名前の研修ですが、講師やトレーナーだけが対象というわけではなく、部下や後輩を育成・指導する人や講座を作る人、研修を運営する人向けの研修でもあります。

少々お高い気もしますが、少人数でがっつり４日間みっちり研修のため納得のお値段。オンサイトで受けていますが、どうやら１０名が定員のようです。

## 受講層
MCT目指して受講しているのは私だけのようですが、ほかの方々は企業向けにIT系のトレーナーをされている方や、社内で講師や教育系の部署にいらっしゃる方々がいました。皆さん教える領域は様々。講師歴も１年未満の方から、独学で長年やっていたが教える型を知りたい！と申し込まれたベテラン風の方までバラエティ豊かです。途中で一人２分の自己紹介タイムがあるのですが、結構人となりが見えておもしろい。そしてみなさん人前で話すことに慣れている感ありでさすがです。

https://www.trainocate.co.jp/reference/course_details.aspx?code=ON258

## １日目のカリキュラム
1．学習を始める前に
  - 自己紹介
  - 個人目標の設定

2. 成人学習
  - 成人の学習と子供の学習の違い（ディスカッション演習あり）
  - 学習の法則を研修に取り入れるには（プレゼンテーション演習あり）
  - 受講者に役立つフィードバックをするためのポイント

※カリキュラムは、上記研修案内ページに掲載があります。
１日目は第２章までいきました。

## １日目の振り返り
有償研修なので、詳細までは触れませんが、演習中心の講義です。教育学の理論に沿った学術的な内容なのでかなり勉強になっています。というかほとんどの時間、何かワークをしてるんじゃないか？ってくらい常に何かしています。経験→観察→考察→応用→経験…の学習のサイクルまわしまくり。そして初日からプレゼンの演習タイムもあり、なかなかの緊張感があります。

これまでの人生の様々な研修の中で自分が当たってきた「いい講師」「悪い講師」を思い浮かべながら、「あー教え方・話し方うまい人はこういう原則や法則を使っていたのかー」、「すごく当たりまえだけど子供に教えるのと大人に教えるのでそもそも前提や手法も確かに違うわねー（＝成人学習）」「うーむ、このやり方は改めてみよう」と考えさせられる部分が多々あります。自分はいい講師であらねば…という自覚と焦燥感も身につく。

なかなか体系的に、講師のふるまいや講座の進め方等勉強してこなかったので、学びが多いです！明日も楽しみ。
Next.js LinkとMaterial-UIのMenuItemの型定義互換性問題でハマった話

# Next.js LinkとMaterial-UIのMenuItemの型定義互換性問題でハマった話

## 想定読者
- Next.jsでの開発を始めたばかりの方
- Material-UIを使い始めた方
- Webアプリケーション開発初学者

## 結論から
Next.jsとMaterial-UIの型定義の互換性問題によるエラーが発生する。
UrlObjectを用いた型定義を適切に用いる・NextLinkでMenuItemをラップすることで解決可能である。

## 開発環境
- Next.js: 14.2.11
- Material UI: 6.1.0
- TypeScript: 5.0

## 問題のあるコード
最初に、以下のように`MenuItem`と`NextLink`を直接組み合わせようとすると型エラーが発生する：

```typescript
interface MobileMenuProps {
    menuItems: Array<{
        href: string;
        label: string;
    }>;
}

export function MobileMenu({ menuItems }: MobileMenuProps) {
    return (
        <>
            {menuItems.map((item) => (
                <MenuItem 
                    key={item.href} 
                    component={NextLink} 
                    href={item.href} 
                    onClick={handleClose}
                >
                    {item.label}
                </MenuItem>
            ))}
        </>
    );
}
```

### 発生するエラー
```typescript
No overload matches this call.
Type '{ children: string; key: string; component: <RouteType>(props: LinkProps<RouteType>) => Element; href: string; onClick: () => void; }' 
is not assignable to type 'IntrinsicAttributes & { href: string; } & MenuItemOwnProps & Omit<ButtonBaseOwnProps, "classes"> & CommonProps & Omit<...>'.
Property 'component' does not exist on type 'IntrinsicAttributes & { href: string; } & MenuItemOwnProps...'
```

## 解決方法
問題を解決するために以下の2つを行なった：

1. `href`の型を`string`から`UrlObject`に変更
2. コンポーネントの構造を変更し、`NextLink`で`MenuItem`をラップする

```typescript
import { MenuItem } from "@mui/material";
import NextLink from "next/link";
import { UrlObject } from "url";

interface MobileMenuProps {
    menuItems: {
        href: UrlObject;
        label: string;
    }[];
}

export function MobileMenu({ menuItems }: MobileMenuProps) {
    return (
        <>
            {menuItems.map((item) => (
                <NextLink 
                    passHref 
                    href={item.href} 
                    key={item.label} 
                    style={{ textDecoration: "none", color: "inherit" }}
                >
                    <MenuItem onClick={handleClose}>
                        {item.label}
                    </MenuItem>
                </NextLink>
            ))}
        </>
    );
}
```

### 変更点について
1. **型定義の変更**
   - `href`の型を`string`から`UrlObject`に変更することで、Next.jsの型システムとより適切に連携
   - `UrlObject`は Next.js の `Link` コンポーネントが期待する型定義であるためNext.js側の問題を解決

2. **コンポーネント構造の変更**
   - `MenuItem`を`component={NextLink}`として使用する代わりに、`NextLink`で`MenuItem`をラップ
   - `passHref`プロパティを追加して、適切なリンク機能を確保
   - スタイリングを追加して、デフォルトのリンクスタイルを適切に上書き (optional)

## まとめ
Next.jsとMaterial-UIの型定義の互換性問題によるエラーが発生した。
UrlObjectを用いた型定義を適切に用いる・NextLinkでMenuItemをラップすることで問題を解決した。

## 参考文献
- [Stack Overflow: ReactJS and TypeScript: refers to a value, but is being used as a type here (TS2749)](https://stackoverflow.com/questions/62059408/reactjs-and-typescript-refers-to-a-value-but-is-being-used-as-a-type-here-ts)
あの日見た""の理由を僕はまだ知らない

:::note
こちらの記事ですが、コメントにて有識者による解説を頂けましたので、究極的な原因を知りたい方はそちらを参照してください。
:::

## 始まりは自己紹介から
初めまして　あおげばにゃんこです。
最近JSにこなれ感を出しつつコード書いていた矢先に悲劇が起きましたので、ご報告です。

## data属性に「""」がついてくる

普段はrailsで開発を行っているのですが、HTMLのdata属性にデータを入れておいて取り出そうとした際にある問題が生じました。

発生した問題は以下のとおりです。
```
<input type="checkbox" name="type" id="birthday" data-status=""2024-10-03"">
```

お気づきになりましたか？

謎の「""」がついてますよね？　
こいつはいったい何者なんだと
そう思うのが自然の摂理です。

今回はこちらの直接的な原因について記事を書きます。
※究極的な原因であるhtmlやrails,jsのことについては詳しく述べません

## 原因はなんぞや

まずは我々が望む美しい理想形を確認してみましょう。

```
<input type="checkbox" name="type" id="birthday" data-status="2024-10-03">
```

いかがですか？
実に綺麗でしょう。

それでは再度自身の構造を確認してみましょう。

```
<input type="checkbox" name="type" id="birthday" data-status=""2024-10-03"">
```

汚いですね〜
1週間お風呂入ってないのかな？ってくらい汚いですよね？

さて、それではこちらの構造の元になったコードを見てみましょう。

### ""がついてる方
```
 = check_box_tag 'type', 'birthday', false, id: "birthday", data: { status: birthday }
```

### ""がついていない方
```
= check_box_tag 'type', 'happy', false, id: "happy", data: { status: "#{(@user.birthday )}" }
```

お気づきになりましたか？

そうです。上は剥き出しの変数のまま、下は式展開を使った文字列なのです。

つまり、data属性にはちゃんと文字列を渡してあげないとhtml側？がエスケープ処理を行い正しく認識されないのです！！！
(たぶん文字列)

# 今回のまとめ

つまりdata属性にrailsからデータを渡す場合はちゃんと文字列にしてあげることが重要なのです！

今回の記事が誰かの役に立てば幸いです。

## 余談

この記事を書く前に色々調べてみたのですが、jQueryだとdata属性からデータを取得する際に勝手に型を変換してくれるそうです。
ソースについてはご自身で調べていただければと思います。
投稿 114 PostgreSQL 2024/10/22

本日の勉強時間　4H

Laravelには、「ガード」と「プロバイダ」から構成されるモジュールがあります。ガードは各リクエストのユーザー認証を定義し、プロバイダは永続ストレージ（MySQLデータベースなど）からのユーザーの取得方法を定義します。
投稿 113 PostgreSQL 2024/10/21

本日の勉強時間　3H

PostgreSQLの欠点部分データベースエンジンへの新しい接続を開始するのに非常にコストがかかることです。 接続を大量に行うアプリケーションでは、PostgreSQLが接続を生成する方法がボトルネックになる可能性があります。
【Next.js】サーバーコンポーネントでreferrerの値を取得する方法

以下のように`headers`を使用してサーバーコンポーネントにおいてreferrerの値が取得できます。

```tsx:page.tsx
import { headers } from 'next/headers'
 
export default function Page() {
  const headersList = headers()
  const referer = headersList.get('referer')
 
  return <div>Referer: {referer}</div>
}
```
トレイリングクロージャ

# クロージャ（無名関数）とは
・クロージャは引数として渡すことができるオブジェクト。
・クロージャは、引数として使用できる処理の塊です。
・クロージャ自体は引数ではなく、関数やメソッドに引数として渡すことができます。
・関数の引数に関数を用いたい場合に、クロージャが活躍します。
以下は、関数内でクロージャを呼び出す際の例です。引数名と関数呼び出し名は同じ名前を使う必要があります。
```swift
func numArrAndClosure(numArr: [Int], closure: (Int) -> Void) {
    for num in numArr {
        closure(num)
    }
}

numArrAndClosure(numArr: [1, 2, 3, 4, 5], closure: { x in print(x + 1) })
```
# トレイリングクロージャとは何か
メソッドや関数の最後の引数がクロージャの場合、クロージャを括弧 () の外に書くことができる記法が「トレイリングクロージャ」です。
# 基本的な構文の説明
Swiftでは、クロージャを関数の最後の引数として渡す場合、トレイリングクロージャ構文を使うことでコードを簡潔に記述できます。
・通常のクロージャ:
```swift
numArrAndClosure(numArr: [1, 2, 3, 4, 5], closure: { x in primeJudge(x) })

```
・トレイリングクロージャ:
```swift
numArrAndClosure(numArr: [1, 2, 3, 4, 5]) {
    x in primeJudge(x)
}
```
・通常の渡し方では、引数ラベルを明示的に指定する必要があります。
・トレイリングクロージャを使用することで、クロージャを関数呼び出しの外に書くことができ、可読性を向上させることができます。

# トレイリングクロージャの利点:
・トレイリングクロージャは、関数の最後の引数としてクロージャを使う場合に、括弧を省略できるため、コードがすっきりします。
・これにより、クロージャの内容が際立ち、全体の可読性が向上します。
PowerShellでSQL DeveloperをWindowsに自動インストール

このシリーズの他の記事は、[オラクル・クラウドの個人ブログ一覧 ](https://qiita.com/letian/items/10152a4fec813c1b7d98)からご覧いただけます。

__初めに__
このブログでは、PowerShellスクリプトを活用して、<strong>SQL Developer</strong>のの自動インストール を実現する方法について解説します。特に、クラウド環境での効率的なセットアップを目指す方や、Computeインスタンス作成時に開発ツールを自動で導入したい方にとって、一助となれば幸いです。

<strong>cloud-init</strong>スクリプトに組み込むことで、インスタンスの初期設定時に SQL Developer を自動インストールできるようになり、手動インストールの手間を省くことができます。これにより、環境構築のスピードを大幅に向上させることが可能です。

__環境情報__
Windows Server 2019 Standard Edition (OCI VM)
SQL Devloper 24.3 (Windows 64-bit with JDK 17 included)


__ステップ__
- インストーラのダウンロード ([リンク](https://www.oracle.com/database/sqldeveloper/technologies/download/))
- インストーラの解凍
- インストーラの削除（オプション）

```powershell
#ps1_sysnative

# Define the URL of the SQL Developer installer
$InstallerFile = "sqldeveloper-24.3.1.347.1826-x64.zip"
$InstallerUrl =  "https://download.oracle.com/otn_software/java/sqldeveloper/" + $InstallerFile

# Define the path where you want to save the installer
$InstallerPath = Join-Path $env:TEMP $InstallerFile

# Download the installer
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $InstallerUrl -OutFile $InstallerPath

# Unzip the installer
Expand-Archive -Path $InstallerPath -DestinationPath "C:\"

# Clean up the installer after installation
Remove-Item $InstallerPath
```

:::note
OCI cloud-initスクリプトで使用する場合は、スクリプトの先頭に`#ps1_sysnative`を追加する必要があります。
:::



----
__関連記事__
[SQL Developerで様々なDBに接続する方法](https://qiita.com/letian/items/08f2e2f6d90c08549cbf)
[Oracle LinuxでSQL Developerを利用する方法](https://qiita.com/liu-wei/items/46eb16dbd4f2d665c67f)
[OCI Cloud-initスクリプト](https://qiita.com/letian/items/10152a4fec813c1b7d98#11-cloud-init%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)
JetsonNanoとArduino間でUSB経由のシリアル通信

## JetsonNanoとArduino間でUSB経由のシリアル通信

JetsonNanoのサブボードとして、ArduinoにPWM変換を一任してもらう。


### Arduino側準備
#### プログラム
　Arduino側は以下のプログラム
　「A」を受信するとPPM1500（計測値は1477）
　「B」を受信するとPPM1800（計測値は1770）になる


```C 
#include <Wire.h>                 
#include <Adafruit_PWMServoDriver.h>
  
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); //　PCA9685のI2Cアドレスを指定
  
#define SERVOMIN 1500    // 最小パルス幅(μs)
#define SERVOMAX 1800    // 最大パルス幅(μs)
  
int Servo_pin = 0; // サーボ接続ピンを0番に
  
void setup() {
  Serial.begin(9600);   // シリアル通信を9600bpsで開始
  pwm.begin();          // 初期設定
  pwm.setPWMFreq(50);   // PWM周期を50Hzに設定
  delay(1000);
}
  
void loop() {
  if (Serial.available() > 0) 
    char command = Serial.read();  // シリアルデータを読み取る
  
    if (command == 'A') {
      pwm.writeMicroseconds(Servo_pin, SERVOMIN);  // 「A」が送信されたらパルス幅を1500μsに設定
      Serial.println("Pulse width set to 1500μs");
    }
    else if (command == 'B') {
      pwm.writeMicroseconds(Servo_pin, SERVOMAX);  // 「B」が送信されたらパルス幅を1800μsに設定
      Serial.println("Pulse width set to 1800μs");
    }
  }
```

#### 接続
　![Pasted image 20241022155355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840203/60e2b032-4e30-7c97-dc9c-051e6951f702.png)


---

### JetsonNano側の準備

C言語でシリアル通信を制御する。
`termios` `fcntl`のライブラリを使ってシリアル通信を実現

C言語でのシリアル通信コードを作成した例。
このコードは、指定したデバイス（`/dev/ttyACM0`）に対して9600baudの速度で接続し、データ`'A'`を送信する。

```C: serial_write.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main() {
    int fd;
    struct termios options;

    // シリアルポートを開く
    fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
        perror("Unable to open serial port");
        return 1;
    }

    // シリアルポートの設定
    tcgetattr(fd, &options);
    cfsetispeed(&options, B9600); // ボーレートを9600に設定
    cfsetospeed(&options, B9600);
    options.c_cflag |= (CLOCAL | CREAD); // ローカル接続、読み込み有効
    options.c_cflag &= ~PARENB; // パリティビット無効
    options.c_cflag &= ~CSTOPB; // ストップビット1
    options.c_cflag &= ~CSIZE; // データビットサイズをクリア
    options.c_cflag |= CS8; // データビットサイズを8ビットに設定
    tcsetattr(fd, TCSANOW, &options); // 設定を適用

    // データを交互に送信
    while (1) {
        char dataA = 'A';
        char dataB = 'B';

        // 'A'を送信
        write(fd, &dataA, 1);
        printf("Sent: %c\n", dataA);
        sleep(2); // 2秒待機

        // 'B'を送信
        write(fd, &dataB, 1);
        printf("Sent: %c\n", dataB);
        sleep(2); // 2秒待機
    }

    // シリアルポートを閉じる
    close(fd);
    return 0;
}
```

#### 説明

- **`open()`**: シリアルポートを開く。エラーが発生した場合は、エラーメッセージを表示する
- **`tcgetattr()` / `tcsetattr()`**: シリアルポートの設定を取得し、設定を適用する
- **`write()`**: 指定したデータをシリアルポートに書き込む
- **`close()`**: シリアルポートを閉じる

#### コンパイルと実行

このコードをファイル（例: `serial_write.c`）に保存し、以下のコマンドでコンパイルする。

```bash
gcc -o serial_write serial_write.c
```

実行するには、次のコマンドを使用。

```bash
sudo ./serial_write
```

シリアルポートへのアクセスには、適切な権限が必要な場合もあるので、`sudo`を使用する。

## 完成
![IMG_1726.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840203/50f3328c-9ecb-b81b-cfda-ef692f61e226.jpeg)
SQL ServerでIDENTITYがロールバックされない

# はじめに
SQL ServerでIDENTITYを設定したテーブルをロールバックした時に連番が戻らなかったので調べてみました。


# Microsoftのサイトによると
https://learn.microsoft.com/ja-jp/sql/t-sql/functions/identity-transact-sql?view=sql-server-ver16

>失敗したステートメントとトランザクションによって、テーブルに対する現在の ID が変更され、ID 列値に差異が生じる可能性があります。 ID 値がロールバックされることはありません。これは、テーブルに値を挿入するトランザクションがコミットされない場合でも同じです。 たとえば、INSERT ステートメントが IGNORE_DUP_KEY 違反のために失敗しても、テーブルの現在の ID 値は増分されます。

「ロールバックされない」と書かれているので、そういうものなのかと思いましたが、考えてみると当たり前のことでした。

---
以下のようなテーブルがあり、AさんとBさんがデータを登録します。
```sql
CREATE TABLE [m_vegetable] (
    [id] INT IDENTITY(1,1),
    [name] NVARCHAR(20)
)
```
| id | name |
|:-:|:-:|
| 1 | 大根 |
| 2 | 人参 |

１．Aさんがトランザクションを開始する
２．Aさんがデータを登録する
| id | name |
|:-:|:-:|
| 3 | ごぼう |

３．Bさんがデータを登録する
| id | name |
|:-:|:-:|
| ? | ジャガイモ |

:::note
Aさんのトランザクションはコミットされていません。
この時、Bさんの登録したデータのidは何番が採番されるでしょうか。
:::

「3」が入った場合、Aさんのトランザクションをコミットすると「3」が重複してしまいます。
つまり、idには「4」が入ります。
| id | name |
|:-:|:-:|
| 1 | 大根 |
| 2 | 人参 |
| 4 | ジャガイモ |

ここで、AさんがロールバックしてもBさんが登録したデータのidは「4」のままです。
ですので、IDENTITYをロールバックするわけにはいかなくなります。

# 連番に関するSQL
```sql
--自動採番を一時解除
SET IDENTITY_INSERT [m_vegetable] ON
--idを指定して登録
INSERT INTO [m_vegetable] ([id], [name]) VALUES (3, 'ごぼう')
--自動採番に戻す
SET IDENTITY_INSERT [m_vegetable] OFF
```
| id | name |
|:-:|:-:|
| 1 | 大根 |
| 2 | 人参 |
| 3 | ごぼう |
| 4 | ジャガイモ |

```sql
-- 最大値をチェック
DBCC CHECKIDENT ([m_vegetable], NORESEED)
--⇒ ID 情報を調べています。現在の ID 値 '4'、現在の列値 '4'。

-- 最大値をセット
DBCC CHECKIDENT ([m_vegetable], RESEED, 100)
--⇒ ID 情報を調べています。現在の ID 値 '100'。

DBCC CHECKIDENT ([m_vegetable], NORESEED)
--⇒ ID 情報を調べています。現在の ID 値 '100'、現在の列値 '4'。

INSERT INTO [m_vegetable] ([name]) VALUES ('白菜')
```
| id | name |
|:-:|:-:|
| 1 | 大根 |
| 2 | 人参 |
| 3 | ごぼう |
| 4 | ジャガイモ |
| 101 | 白菜 |
"小説の一節"でQRコードを描くという試み - テキストQRコードアートをつくってみた【python】

# QRコードアートというジャンル
従来の白黒でシンプルに構成されたものではなく、デザインに凝ったクリエイティブなデザインのQRコードのことを「QRコードアート」と呼ぶ。

最近は[QAコートAIアートジェネレーター](https://qrcode-ai.com/ja)が話題になった。誰でも簡単に独自なデザインのQRコードを生成できるというものである。

https://prtimes.jp/main/html/rd/p/000000001.000132013.html


実は話題になる前から、QRコードアートというジャンルは存在した。2016年のこちらの記事では「世界のQRコードを使った広告戦略がとても面白い！」というテーマで、さまざまなデザインのQRコードが紹介されている。


https://k-art-factory.jp/blog-contents/okumura-%EF%BD%91%EF%BD%92/

ディズニーキャラクターの顔の形をしたデザインや、一見するとQRコードには見えないような工夫が施されていたり、その種類は多岐にわたる。

ここでは紹介しないが、「これ本当に読み取れるの！？」みたいなデザインが施されていて非常に興味深い。

私も気づいたらスマホのカメラアプリを開いて、QRコードを読み取ろうとしてしまっていた。してやられたり、という感じである。

# 今回の挑戦
AIによって簡単にデザインが作れるようになったけれど、**文字で構成されたQRコードは見たことがないな**と私は考えた。例えば「吾輩は猫である。名前はまだない...」のような文字が大量に敷き詰められた黒色の塊をうまく配置すれば、QRコードとして成立するのではないかと考えたのだ。

（👇こんな感じのブロックを敷き詰めればいけそう）


`吾輩は猫で`　　`吾輩は猫で`
`ある。名前`　　`ある。名前`
`はまだない`　　`はまだない`




`吾輩は猫で`　　`吾輩は猫で`
`ある。名前`　　`ある。名前`
`はまだない`　　`はまだない`


特に実用性のあるデザインではないと思うが、気になってしまったのでとりあえず作ってみようと思った。今回はその経緯を簡単にまとめたいと思う。

# QRコードはなぜデザインが崩れても読み取れるのか
そもそもなぜQRコードアートが、不都合なく読み取れるのだろうか。


QRコードが多様なデザインを受け入れられる理由は、その設計に組み込まれた「エラー訂正機能」にある。この機能は、QRコードの一部が損傷や変更されても、元のデータを復元できるようにする優れた技術である。

これによって、障害物に一部が遮られていても読み取ることができるし、以下のようなQRコードが成立するのである。

![スクリーンショット 2024-10-22 22.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/78ba8ba8-0ee2-1beb-0be3-7c2e5d0e973c.png)


### エラー訂正レベル
QRコードには4段階のエラー訂正レベルが用意されている。

レベルL：約7%のデータを復元可能
レベルM：約15%のデータを復元可能
レベルQ：約25%のデータを復元可能
レベルH：約30%のデータを復元可能

ちなみに今回の文字QRコードでは最高レベルの「H」を使用している。これにより、QRコードの約30%が変更されても（文字で置き換えられても）、正常に読み取ることが可能だ。

ただし、3つの角にある正方形の切り出しシンボル（四角くて大きく目立つ部分）が汚れている場合は、ビットパターンの位置がわからず読み取れなくなるらしい。汚れ・破損が許されるのは、ここ以外に限られている。






# 使用技術
最初は「適当なQRコードを作って、手動で同じ形になるように文字を貼り付けていこうか」などと**狂気じみたアイディア**が浮かんだが、それは絶対後悔することになるので却下した。時間がかかるし、その結果読み取れない謎のデザインが完成したら悲しくなってしまう。

次に思い浮かんだのは、無難にpythonでコードを書いてしまうというもの。最近はAIに聞けば簡単に作り方を教えてくれるし、pythonは経験がそれなりにあるのでこの案を採用した。

PythonのQRコード画像生成ライブラリ「qrcode」を使用し、実装は案外サクッと完了した。今のAIの精度は本当に感動レベルで、初期の実装はほんの5分程度で完了した。

- python
- VSCode
- qrcode
- Claude

# 完成したQRコード
結論、この試みは成功し、実際にQRコードを読み取れた。私の運営アプリのURLをQRコード化してみたので、ぜひ確認してみて欲しい。

（かなり細かい粒度で画像出力されているので、よーーーーーく目を凝らしてみないとよくわからない。というかスマホなどではほとんどよくわからないかもしれないが、確かに超拡大するとそれぞれが文字になっている）

![水色　白　金　エレガント　夏　お知らせ　チラシ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/b795aa08-5c42-0cc2-8b93-8a8dcb9700cd.png)


冒頭にもお伝えした通り、全然実用的ではない。文字間の空白が生じるのでどうしても読み取りづらくなってしまうし、そもそも言われなければこれが文字で構成されていることに気がつけないだろう。

しかし個人的にはとても面白い試みだと思っているし、無事成功して感動している。身近なQRコードの技術が素晴らしいものであることを再認識させられる良い機会になった。

もし気になる人がいれば、コメントをもらえればもしかしたらソースコードも公開するかもしれないので、ぜひ感想などもらえるとありがたい。
OPTiM × every Golang Developer Night (240702)に参加してきました

2024/07/02 OPTIMさんのオフィスで開催されたGo言語のイベントにリアル参加してきましたので、お聞きしたLT内容など、メモを元にご紹介します。

※ **3ヶ月寝かせていた記事です、もう加筆できる気がしないのでこのまま公開してしまいます。**
※ 間違い/解釈違いが含まれる可能性もあるのでご注意ください。もしお気づきの点あればそっとコメントで教えて頂けると嬉しいです。

## イベント概要
様々な産業DXを実現する自社サービスを展開する[株式会社オプティム](https://www.optim.co.jp/)さんと、食、子育て、地方創生の課題に向き合うプラットフォームを展開する[株式会社エブリー](https://corp.every.tv/)さんの2社で共同開催された、2~30人規模のGo言語系のLTイベントでした。

### Connpass 
https://optim.connpass.com/event/321331/

## LT・セッション

### Go x LLMで新たなコード生成の可能性を探る (今枝さん)
Goで一般的なコード自動生成ツールと、LLMを使い生成するツールを組み合わせて開発の効率化を図るアプローチの紹介でした。今回紹介頂いたのは、OpenAPIドキュメントを元にコードを生成するツールでした。

(すみません失念しました、恐らくAiderか、下記一覧にありそうです)
https://github.com/jamesmurdza/awesome-ai-devtools?tab=readme-ov-file#agents

#### 感想
自動生成されたエンドポイントに対してTODOコメントをたくさん書いて、そこをAIツールに補完させるというアプローチは、確かに上手くいきそうだなと興味深く聞かせてもらいました。一方で処理する流れのイメージは固まっていないとできないので、要件がゆるふわな状況やマイグレーション等、実装の縛りがあるパターンだと、上手くいかなさそうだなぁと思いました。

### Go言語で行うメール解析 (every きょー。さん)

#### 感想
Goの標準ライブラリでメールをパースして分析できるというのは聞き覚えがなく新鮮でした。(と言いつつ実はお仕事のバックエンドで使ってたかもしれませんが。)こういうのを使って広告メールの山で埋もれている自分のGmailを、いい感じに分類や、必要なものだけ通知とかできたらいいなぁと思いました。

### プロダクトでどれぐらいMELTしてますか？ (OPTiM 坂井さん)

#### 感想
MELTという単語に聞き覚えがなく、タイトルだけだとだと正直よくわかりませんでした💦 聞いてみると、既に趣味開発でも採用しているオブザーバビリティの話で、なるほどーと思いました。

### slices/map pkgを活用してオレオレ実装を撲滅したい (every yoshidaさん)

#### 感想
趣味開発の方で、ちょうど撲滅される側のオレオレ実装をしていたので、そろそろ置き換えないとなぁという危機感を持ちました。質疑応答では、"sort.Sortよりslices.Sortの方がシンプルに書ける上に速い"という情報を聞けたので、今後ソートしたくなったらslices.Sortが良さそうです。

## 完走した感想
Goの言語のイベントという割には、幅広いLTがあって面白かったです。また、懇親会もGoのエンジニアさんしか居ないだろうなーと思いながら参加しましたが、意外にもフロントエンドエンジニアさんやJavaエンジニアさん等様々な方と話せて良かったです。

なお、今回も会場スポンサーのOPTIMさんに、(ドローン等技術を活用して作られた)スマート米を振る舞ってもらいました。美味しかったです。

Amazonで販売されているそうなので良ければどうぞ。

https://amzn.asia/d/0boUIUO1
Raspberry Pi Compute Module 4で外付けWiFiアンテナを使う方法

# 用意するもの
- Raspberry Pi Compute Module 4
- CM4を動作させるためのIOボード
- Compute Module 4 Antenna Kit (WiFiアンテナ)
  - 技適の関係でこのアンテナを使うのがよさげ

# やり方
まず、以下の図のようにアンテナを接続します。
![PXL_20241022_135312597.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476116/cd680cd5-b663-3080-5415-7b59d0e37818.jpeg)

以下のように`/boot/firmware/config.txt`の`[cm4]`の欄に`dtparam=ant2`を書き込みましょう。
```text:/boot/firmware/config.txt
[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1
dtparam=ant2
```
これで外部アンテナが使えるようになります。
実際に起動してみてWiFi通信ができていることを確認しましょう！

# 経緯
cm4の上に何もない時はWiFiがつながるが、HATやヒートシンクをつけるとWiFiがつながらない現象に出くわしました。
[データシート](https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf)の2.1節を参照するとどうやら、cm4にはオンボードのアンテナと外付けアンテナの2つが存在し、これの切り替えを`dtparam`で指定することがわかりました。~~ここまで20時間ほどとかしたのはいい思い出。早くデータシートを見ておくべきだった……~~
Firebaseを使ってGoogleログイン機能を実装する方法

**Firebaseは、Googleが提供するモバイルとウェブアプリケーション開発のためのプラットフォームです。Firebase Authenticationを使用すると、Googleアカウントを含む多様な認証方法を簡単に実装できます。本記事では、Firebaseを使ってウェブアプリケーションにGoogleログイン機能を追加する手順を解説します。**


**ステップ1: Firebaseプロジェクトのセットアップ**

# 1. Firebaseコンソールでプロジェクトを作成
Firebaseコンソールにアクセスし、Googleアカウントでログインします。
「プロジェクトを追加」をクリックし、プロジェクト名を入力して作成します。

**2. ウェブアプリを追加**
プロジェクトのダッシュボードで「</>」アイコンをクリックしてウェブアプリを追加します。
アプリのニックネームを入力し（例: my-web-app）、必要に応じてFirebase Hostingを設定します。
作成後、Firebase SDKの設定スニペットが表示されます。これを後で使用するのでコピーしておきます。

**ステップ2: 認証方法の有効化**

**1. 認証ページに移動**
Firebaseコンソールの左側のメニューから「Authentication」を選択します。

**2. サインイン方法を設定**
「サインイン方法」タブで、「Google」を選択し、有効にします。
必要に応じてプロジェクトのサポートメールを設定します。

**ステップ3: プロジェクトにFirebaseを追加**

**1. Firebase SDKのスクリプトを追加**
HTMLファイルの<head>タグ内に以下のスクリプトを追加します。

```html
<!-- Firebase App（必須） -->
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app.js"></script>
<!-- Firebase Authentication（オプション） -->
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-auth.js"></script>
```

# 2. Firebaseの設定を初期化
先ほどコピーしたFirebase SDKの設定スニペットを追加します。

```javascript
<script>
  // Firebaseの設定
  
  const firebaseConfig = {
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
    // 他の設定項目
  };

  // Firebaseの初期化
  firebase.initializeApp(firebaseConfig);
</script>
```


**ステップ4: Googleログイン機能の実装**
1. ログインボタンの作成
HTMLファイルの<body>内にログインボタンを追加します。

```html
<button id="login">Googleでログイン</button>
```

# 2. 認証処理の実装
タグ内に以下のコードを追加します。

```javascript
// Firebase Authenticationの参照を取得
const auth = firebase.auth();

// Google認証プロバイダーのインスタンスを作成
const provider = new firebase.auth.GoogleAuthProvider();

// ログインボタンのクリックイベントを設定
document.getElementById('login').addEventListener('click', () => {
  auth.signInWithPopup(provider)
    .then((result) => {
      // ログイン成功時の処理
      const user = result.user;
      console.log('ユーザー情報:', user);
      alert(`ようこそ、${user.displayName}さん！`);
    })
    .catch((error) => {
      // エラー処理
      console.error('エラー:', error);
    });
});
```

# 3. ログアウト機能の追加（オプション）
```html
<button id="logout">ログアウト</button>
javascript
コードをコピーする
document.getElementById('logout').addEventListener('click', () => {
  auth.signOut()
    .then(() => {
      alert('ログアウトしました。');
    })
    .catch((error) => {
      console.error('エラー:', error);
    });
});
```

**ステップ5: ユーザーの認証状態を監視**
ユーザーのログイン状態をリアルタイムで監視するには、onAuthStateChangedメソッドを使用します。

```javascript
auth.onAuthStateChanged((user) => {
  if (user) {
    // ユーザーがログインしている場合の処理
    console.log('ログイン中:', user);
  } else {
    // ユーザーがログアウトしている場合の処理
    console.log('ログアウトしています。');
  }
});
```

**ステップ6: セキュリティ上の考慮事項**
APIキーの保護: FirebaseのAPIキーは公開されても問題ないように設計されていますが、不必要に共有しないよう注意しましょう。
Firebaseルールの設定: データベースやストレージを使用する場合は、Firebaseのセキュリティルールを適切に設定してください。

#まとめ
これでFirebaseを使用したGoogleログイン機能の実装が完了しました。Firebase Authenticationを使うことで、複雑なバックエンドの設定なしに認証機能を追加できます。さらに、他の認証方法（メール/パスワード、Facebook、Twitterなど）も簡単に統合できます。

参考資料
Firebase公式ドキュメント - ウェブでのGoogleサインイン
Firebase Authenticationの概要

**毎日更新していますので、@y-t0910をフォロー,いいねしていただけると嬉しいです。**
Git Comment サンプル

# git コメントのサンプル

feat: 新機能
fix: バグ修正
docs: ドキュメントのみの変更
style: コードの意味に影響を与えない変更（空白、フォーマット、セミコロンの欠落など）
refactor: バグを修正せず、機能を追加しないコード変更
perf: パフォーマンスを改善するコード変更
test: 不足しているテストの追加または既存のテストの修正
chore: ビルドプロセスや補助ツール、ライブラリの変更（ドキュメント生成など）

下記から拝借しました。
https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type
【基本情報】独学マラソン ロールフォワード Day 22

組織の利益＝個人の利益
個人の目指す成長の解像度を上げる

:::note worn
この記事は自分用の備忘録です。
:::

# 最新アップデートだ！楽しみだなー！
オンラインゲームをしていた頃、いつもアップデートを楽しみにしていた
アップデートが完了すると新コンテンツの争奪戦が始まる
そして、大体バグっているのでメンテナンスとなる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/892dae89-9d5c-28d0-d82a-9a4e6950dd43.png)

# せっかく手に入れたレアドロップアイテムが‥ない！？
深刻なバグの場合はロールバックされるのである
お詫びの回復アイテムが運営から送られていたりする
全体チャットが阿鼻叫喚となる

# オンラインゲームでのロールバックとは
やったことを取り消すこと
ただ、データベースの場合はちょっと考え方が違う

# データベースにおけるロールバックとは
やりかけのトランザクション処理を取り消すことを指すことが多い
ACID特性のAである原子性「すべて完了するか、何も行わないか」を保証する

ここ勘違いしやすい
データを元に戻すものは「リストア」と呼ぶことが多いらしい

# 取り消すのではなく、一旦戻ってやり直したい時は？
ロールフォワードを使う

# ロールフォワードとは
何か障害が起きた時にバックアップデータを使って無事な状態に戻し
ログを確認しながら直前まで戻すこと

ハードウェアの故障やディスク破損など、物理的にデータベースが壊れた時に使うらしい

そういう障害を「媒体障害」という

# ロールバックとロールフォワードについてのまとめ
<table border="1">
  <tr>
    <th>項目</th>
    <th>ロールバック</th>
    <th>ロールフォワード</th>
  </tr>
  <tr>
    <td>操作の対象</td>
    <td>未完了の操作（やりかけの状態）</td>
    <td>完了した操作や更新済みデータ</td>
  </tr>
  <tr>
    <td>実行タイミング</td>
    <td>エラーや異常終了時</td>
    <td>障害復旧後</td>
  </tr>
  <tr>
    <td>目的</td>
    <td>一貫性の確保、不完全な変更の取消</td>
    <td>データの復元、正常状態の再構築</td>
  </tr>
  <tr>
    <td>主な使用場面</td>
    <td>データベースのトランザクション処理、アプリケーションの異常終了</td>
    <td>バックアップからの復元、ログ適用によるデータの再作成</td>
  </tr>
  <tr>
    <td>データの影響</td>
    <td>変更前の状態に戻る（やりかけの操作が消える）</td>
    <td>変更内容を反映して復元（完了した操作が戻る）</td>
  </tr>
</table>



# 感想
バックアップは怠ってはならない　絶対に


# 参考

https://www.otwo.jp/blog/mysql_roll_forward/

https://wa3.i-3-i.info/word11148.html
Figma代替ツール

# 概要
今では必須のデザインツールであるFigma。
値段高いな〜・なんか重いな〜と最近思って代替ツールを調べていたところ、新興勢力がいくつかあったのでまとめます。

# Motiff
かなりAI機能推しのいい感じの見た目のツール。

https://motiff.com/

Professionalのプランは$4/月！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/2d089d11-8ca3-332b-5330-418d093881e0.png)

AIは期間限定で無料

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/3c9ff222-8065-fb3b-913f-7ca4fd208d11.png)

価格に関して言及している箇所がいくつかあり公正な値段設定を訴えていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/a2302c85-514d-37be-c401-a9a29cc0eba3.png)

# Visilly
こちらもけっこうAI機能推し。
キャプチャしたものを作業場に貼り付けてAI通すと、レイヤー分けされてデザイン化される動画はかなり惹かれました。

https://www.visily.ai/

けっこういろんな有名企業がすでに導入しているようでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/daac5abd-c441-d0bd-678e-48208633e66f.png)

値段は年払いだと$11/月。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/ebdc1b0d-1ec2-a420-b036-b70a135fbadb.png)

# Pixso
こちらはAI機能についてほとんど言及されておらず、Figma, Sketch, XDの代替品の立ち位置？といった感じでした。
トップページは日本語化されていました。

https://pixso.net/jp/

Professionalなら、年払いで$6/月。別料金でFigjamみたいなWhiteboardというのもあるようでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908466/7339ebb8-5629-6396-2313-27e69c6ff19e.png)


# 終わりに
少ないですが以上です。
個人的な印象として、争点はAI機能、値段、動作の軽さなのかなと思いました。
あと今では当たり前かと思っていたコラボレーション機能（作業場での共同編集）もけっこうアピールしているのが多かった印象でした。

自分がFigmaを知ってFigma最高！オートレイアウト最高！もうこれでいいや！ってなったのが、たしか5年くらい前なので、Figmaの神話ももしかするとそこまで長くないのかな...
IPA情報処理安全確保支援士試験の受験体験記【2024年秋】

## 対象読者

- IPAの情報処理安全確保支援士試験の概要を知っており、当日の受験に興味を持っているユーザー
- 情報セキュリティ分野に興味があり、資格取得を目指しているユーザー
- 他の受験者の体験談を参考にしたいユーザー
- 試験会場の雰囲気を事前に知りたいユーザー

## このドキュメントで説明すること

- IPAの情報処理安全確保支援士試験を受けた一受験者の体感
- 情報処理安全確保支援士試験の試験会場の雰囲気

## このドキュメントで説明しないこと

- IPAの情報処理安全確保支援士試験の具体的な内容
- IPAの情報処理安全確保支援士試験の試験問題の内容
- IPAの情報処理安全確保支援士試験の効率的な試験方法

## IPAの情報処理安全確保支援士試験を受けてきました

今回受けた情報処理安全確保支援士試験とは、日本の情報処理に関する国家資格の１つです。レベルは4の最高レベルに指定されており、高度な情報セキュリティ知識を証明する試験です。([IPA公式の試験概要はこちら](https://www.ipa.go.jp/shiken/kubun/sc.html))

日本の情報処理の資格の中で唯一士業を名乗れる登録制度もある資格になります。

自分の次の体験から、基本的には難しい試験だと感じました。但し事前の試験学習や、午後問題の解き方を間違えていなければ、解けられるものがある印象でした。

個人的には午後の対策に時間をかけていましたが、午前Ⅱで得意ではない出題が多かったため、午前Ⅱが一番危うかったです。

- プロフィール : 
  - 受験時の年齢 : 31歳(早生まれ)
  - 主な受験会場 : 東京多摩地域
  - 受験時の職歴 : システムエンジニア5年目
  - 保持資格 : 
    - 基本情報技術者試験
    - 応用情報技術者試験
    - AWS/Azureなどのクラウドベンダーの入門資格等
- 受験のきっかけ : 
  - 昔いた職場のお世話になった上司が情報処理安全確保支援士の合格と登録をしており、同試験に合格すれば上司のような情報処理安全確保支援士ユーザーと交流できると思ったためです
    - 要するにデキるエンジニアの友達が欲しいため
- 受験歴 : 
  - 2024年秋(令和6年秋)初受験・午前I免除
  - 2024年春の応用情報処理技術者試験に合格したため、午前I免除(２年以内)
- 学習歴 : 
  - 2024/08-2024/10(3ヶ月程度)
  - 模試 : 
    - 午前Ⅱの模試正答率 : 約80%
    - 午後Ⅰ~Ⅱの学習数 : 令和6年-令和3年春までで20問程度
  - 読破した参考書 :
    - [［改訂新版］要点早わかり 情報処理安全確保支援士ポケット攻略本](https://gihyo.jp/book/2022/978-4-297-13064-0)
    - [支援士R5 春期・秋期](https://direct.gihyo.jp/view/item/000000003309)
  - IPAの[脆弱性体験学習ツール AppGoat](https://www.ipa.go.jp/security/vuln/appgoat/index.html)を学習
- 当日の試験結果 : 
  - 午前Ⅰ : 応用情報合格のためパス
  - 午前Ⅱ : 68点(自己採点)
  - 午後 : 体感6割・空いた記入欄なし

## 会場の雰囲気と受験者層

- 会場の雰囲気 : 試験だけあって物静かで試験時間まで学習している方や準備をして待っている方などが多かったです
- 受験者層 : 
  - IPAの応用情報技術者試験や、CBT方式前の基本情報技術者試験と違い、空席（当日来なかった）が少ない印象でした
  - 年齢性別は様々で、専門学生〜大学生、現役の若手システムエンジニアから中堅以上のエンジニアっぽい方が見受けられました
    - 特に女性が1割程度いる印象でした

## まとめ

IPAの情報処理安全確保支援士試験は高度な資格試験であり、試験会場の雰囲気はやはりしっかり勉強している方が多く、受験者層については老若男女いる印象でした。

合格発表は12月に行われるため、結果を記載したいと思います。

## 補足情報
- この記事はGitHub Copilotを使用しながら作成しています
小ネタ　journalctlのログをテキストファイルに出力したい場合

### journalctlの出力をテキストファイルでほしい

あまりに常識的すぎることだからか、ググっても出てこなかったので試してみた。

```bash:bash

journalctl > /home/hoge/text.txt

```

たったこれだけ。小ネタでした。
複数のSimple-Keyboardを個別に隠せない

タブごとに`simple-keyboard`を用意して、それぞれの可視性を操作しようとした時の備忘録

## 使ったライブラリ
[simple-keyboard](https://hodgef.com/simple-keyboard/)
JavaScriptを使っていい感じのキーボードを作れるライブラリ

## 元々のコード
```css: index.css
.simple-keyboard {
    display: none;
}

/* 生きているタブのキーボードだけ表示したい */
.tab.active .simple-keyboard {
    display: block;
}
```
```html: index.html
<!-- ライブラリのインポート処理 -->

<div class="tab active">
    <div class="simple-keyboard"></div>
</div>

<div class="tab">
    <div class="simple-keyboard"></div>
</div>
```
```javascript: index.js
const Keyboard = window.SimpleKeyboard.default;
const k1 = new Keyboard({});
const k2 = new Keyboard({});
```

## 問題
上記のコードだと、キーボードが**両方とも**表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844260/5e4495c1-172b-739b-2406-f5c08ef0bf23.png)

## 解決
[ドキュメント](https://hodgef.com/simple-keyboard/questions-answers/give-different-base-class-keyboard/)にある通り、クラスを分けると解決します。ただし、JS側でクラスとテーマを指定する必要があります。

```html: index.html
<div class="tab active">
    <div class="simple-keyboard-1"></div>
</div>

<div class="tab">
    <div class="simple-keyboard-2"></div>
</div>
```
```javascript: index.js
const Keyboard = window.SimpleKeyboard.default;
const defaultTheme = "simple-keyboard hg-theme-default hg-layout-default";
const k1 = new Keyboard(
    ".keyboard1", 
    { theme: defaultTheme }
);

const k2 = new Keyboard(
    ".keyboard2", 
    { theme: defaultTheme }
);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844260/86e21eba-82ea-f375-9c1f-7260036579ce.png)
Hack に使える T12 ステーションはんだごてオリジナルキット「Hakersはんだごて」を使ってみよう


「Hack に使える T12 ステーションはんだごてオリジナルキット「Hakersはんだごて」を組み立てよう」
https://qiita.com/nanbuwks/items/bd594a1acf8ab1d90b60

を、ワークショップなどを開催したい方に貸出をしたりしています。
![](https://cdn.discordapp.com/attachments/1138718606667022366/1295188541697032273/PXL_20241012_005421841.jpg?ex=671849d3&is=6716f853&hm=00177bd76a61823a26470348c8151413ec3524b5cabc09c3a6122be61a7d6fb0&)

# はんだごて台

図のようなはんだごて台の場合は、スポンジに水を含ませてください。
このタイプは、交換用のT12こて先のスタンドとしても使うことができます。

![IMG_1929.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7e0deb12-6bcb-cf63-fc75-ac27db9c132a.jpeg)

スポンジが足りない場合は、ティッシュペーパーやキッチンペーパーなどで代用してください。


## 使用するコテ先

基本的に貸出はんだごてには ナイフ形状の K 型のコテ先を添付しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6eb97a2b-e899-d564-fd43-1cef81b12d59.png)

また、ワークショップによっては別タイプのものも添付していますので使い分けてください。

表面実装部品などを使う場合は小ナイフ型の T12-KU

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a121df9e-f2be-ef3f-87c8-8a8be2458146.png)

利き手の制限のない先端カット円錐形の T12-BC2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/51157ccb-d0b5-7600-6aa2-b24c99e6c0a8.png)

HK32F103CBT6
http://www.hsxp-hk.com/product/4.html

データシート
http://www.hsxp-hk.com/comp/file/download.do?id=280






#  組み立て方


## コテ部分

ハンドルゴムが、内蔵されています。これはコテ先の保持とアースのために必要です。(捨てないで!)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d01c56b4-4ee6-d01a-1dc9-dcd4a17137a0.png)

コテ先を装着、または取り換えする場合は電源OFFの状態でゴムを持って交換します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5c72fa32-59b2-1f4e-8b1b-8861fb60729a.png)



完成したコテ部分。このような形にならなかったり、 error 表示が出る時はどこかがゆるんでいます。

![IMG_20210920_203445.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bb34df71-b84d-dc8b-dbd3-6545920bf936.jpeg)

## AC ケーブル

アース付を添付しています。マイコンなどをはんだ付けする場合は極力アースを取ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4a06fc01-d947-bb8e-b503-5ed28caa321d.png)

なお、Hackers はんだごては、コテ部分を持つだけで人体アースもできるようになっています。先程のコテに使用している2種類のゴムがアース機能を持つようになっています。

## 設定

ダイヤル長押しでセットアップ画面になります。
英語を使いたい時は言語設定で選んでおきます。


# 使ってみよう

Hackersはんだごては 鉛フリー専用となっています。鉛ハンダの使用はできないことはありませんが極力お避けください。

温度ははんだごてステーション、はんだコテ先、鉛などで大きくばらつきがあります。目安として380℃ですが、
さらっと流れる最低温度に都度調整をしてください。

## はんだづけのやりかた

「AKBONE2024」テキストより抜粋
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4d545828-b6ad-c0b5-b2e3-850322fddeb4.png)

「アンドゥトロワ」で行うように指導をしています。、はんだを酸化させないように、つまりアンドゥトロワと言っているうちににはんだづけを完了させます。

### 「アン!」

コテ先のさきっちょや角だけを接触するのではなく、斜めの面をべったりとつけて素早く熱を伝えます。
熱を伝えるためにはコテ先がきらきらしていなければなりません。そうなっていない場合は「コテ先の保全」でリフレッシュしてください。

###  「ドゥ」

はんだを、こてではなくて部品や基板にあてて溶かします。穴の細部にはんだが流れ込むようにすることが必要です。

### 「トロワ!」

はんだが酸化しないように、また部品が熱で壊れないようにすぐに加熱を終了します。


## コテ先の保全
 
濡れスポンジや、リフレッサーやハンダゴテ用のスチールウールを使います。
K型のコテ先を使っている場合は、これらでクリーンアップしてエッジ部分に金属光沢を出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e36aaa16-6bf9-10a9-889c-e2dfa94ff938.png)

# 片付け

終了する時は、最後にエッジ部分に追いハンダしてから電源OFFしておきます。
高専プロコン35 参加記

第35回高専プロコン（奈良大会）の参加記です。
今回、私は”自由部門予選落ち奈良観光部門”として高専プロコンに参加させていただきました。

# 目次
- 1.高専プロコンとは
- 2.全体
- 3.課題部門
- 4.自由部門
- 5.競技部門
- 6.まとめ

# 1. 高専プロコンとは
高専プロコンとは、全国高等専門学校プログラミングコンテストというコンテストのことで、課題部門・自由部門・競技部門の3つの部門から成り、それぞれの部門でアイデアや実装力を競うコンテストです。
今年は奈良大会ということで、なら100年会館に行ってきました。

# 2. 全体
まず1つ言いたいのは、会場のネットの環境がとても悪かったこと。建物がコンクリートでできている以上、しゃーないんだけど。特に大ホールはほとんど繋がらなかった。
企業のブースでは、いろいろな企業の人と話せてよかったです。企業が使用している言語や業務内容、ぶっちゃけた話が聞けたのは新鮮でした。ノベリティも豪華でした。
昼ごはんのお弁当とてもおいしかった。個人的には、2日目の魚が一番おいしかった。

# 3. 課題部門
今回のテーマは「ICTを活用した環境問題の解決」でした。
特に印象深かったのは以下の作品です。
### SEA-VIS（沖縄高専）
ドローンの制御方法が興味深かった。2つのARマーカーを使用しての移動方向と目標方向を作って自動でドローンを制御するという発想がおもしろかった。
### まもるん（神山まるごと高専）
デザインがとても見やすく操作性がよかった。作品の説明で、高齢者が見てもわかるようなUIを意識したと言っていた。市が配布しているタブレットを活用する発想も良かった。あの、GoogleMapAPIってそこそこの値段しますよね？

# 4. 自由部門
特に印象深かったのは以下の作品です。
### SPORTSDAY（富山高専）
個人的に1番いいと思った作品。とにかくUIがすごかった。リーグやトーナメントを自動で作成してくれる機能や友達の試合を検索できるなど、球技大会時のユーザ側・運営側の両方の意見が反映されている作品だった。実際に球技大会に導入してみて、好評を得ているとのこと。オープンソースらしいので、是非高専の球技大会に導入してみてはいかがでしょう？バックエンド、Kotlinだって！？
### フィッシュフレンズ（香川高専（高松））
本物の金魚が泳いでいた。新幹線に乗せて運んだらしい。
### Regina（広島商船高専）
レジに機械学習を追加する発想がよかった。機能面はとても実用的で、実際のレジに導入してほしいと思ったが、それより、レシートが印象的だった。読み取った商品の情報が書かれているのはもちろんだけど、その下に書いてある材料費・開発費が生々しかった。材料費・開発費合わせて約80万円で、予算約-50万円とのこと。机の下に高そうな機器いっぱいあったし、そりゃそんな金額になるよなって印象。遊び心がある作品はとても好み。

# 5. 競技部門
初めて競技部門を観戦したけど、何をやっているかさっぱり分からなかった。今回の内容は、AtCoderのヒューリスティックみたいな問題だった（AHCに参加したことないけど）。AtCoderの強い人たちが競っているのとても新鮮だったし、アルゴリズムによって画像の変化や手数に差がつくの見ていて楽しかった。高専プロコン前の情報戦、うちわでPCを冷やす戦略、カツラや与謝野晶子の仮面をつけて相手の集中力を削ぐ戦略おもしろかった。予選、準決勝、決勝と上がっていくにつれて画像のズレが無くなっていき、手数の勝負になるのレベル高すぎ。
今回の競技部門を見て、興味を持ったので、来年は競技部門で出場させていただきます。

# 6. まとめ
大仏プリンおいしかった。
【データ分析基盤】データ解析におけるDMP(DataManagementPlatform)について概要について


## DMP（データマネジメントプラットフォーム）の仕組みと導入メリット
　**データウエアハウス（DWH）** は文字通り、データを蓄積して分析に利用するための「倉庫」の役割を担うソリューションで、以前から利用されてきました。モダンデータスタックとしてSaaS（ソフトウエア・アズ・ア・サービス）型で提供されるようになったデータウエアハウスはその用途を大きく広げており、「データプラットフォーム」と呼ぶコンセプトのサービスに進化しています。

## はじめに
 **DMP(データマネジメントプラットフォーム）** は、現代のマーケティング施策において欠かせないツールです。顧客データや行動履歴を一元管理し、それを元に広告やキャンペーンの最適化を図ることが可能です。この記事では、DMPの基本的な仕組みから、オープンDMPとプライベートDMPの違い、導入による具体的なメリットについて詳しく解説します。

## 1. DMPとは？
　DMPは、インターネット上の行動ログや購買履歴などのオーディエンスデータを一元的に管理し、マーケティング施策に役立てるデータプラットフォーム(※1)です。このツールを活用することで、デジタルマーケティングの精度を向上させ、より効果的な広告配信やキャンペーンを実施できるようになります。
※1) データプラットフォームというのは、企業が抱える膨大なデータの統合、管理、分析を行うためのデータ基盤です。データの蓄積に加えてデータ活用に関連するいくつかの機能をまとめてAll in Oneで提供する統合されたプラットフォームのようなものです。

### オープンDMPとプライベートDMPの違い
DMPには大きく分けて2種類あります。オープンDMPとプライベートDMPとなります。それぞれ見ていきます。
### オープンDMP
複数のサイトから集約されたデータを活用します。主に広告ネットワークやSNSと連携し、第三者が保有するオーディエンスデータを活用することで、新規顧客へのアプローチや広告の最適化が可能です。

### プライベートDMP
企業が自社で保有するマーケティングデータ（顧客情報、購買履歴、サイトアクセスデータなど）を活用します。特にECサイトや実店舗のリテンション施策（顧客維持）が容易になります。
## 代表的なDMPサービス

## 2. DMPの主な機能と活用例
　DMPの強力なポイントは、さまざまなデータを統合して活用できる点です。購買履歴やアクセスデータなど、異なるデータを組み合わせることで、より正確な顧客像（ペルソナ）を描くことが可能です。ここでは、代表的な活用例を紹介します。

### 顧客ターゲティングの最適化
DMPは、マーケティングキャンペーンに必要なデータをリアルタイムで収集し、それをもとに顧客に対して最適なターゲティングを行います。例えば、ECサイトでの購買履歴や閲覧データをもとに、特定のユーザーにおすすめ商品を表示したり、クーポンを配信することで購入を促進することができます。

### レコメンド機能の最適化
ECサイトでよく見られる「おすすめ商品」のレコメンド機能もDMPによって強化できます。サイトの行動データを元に、よりパーソナライズされた商品提案を行い、コンバージョン率（CVR）の向上を目指します。

### 広告配信の効率化
DMPは、アドネットワークやSNSと連携し、外部のオーディエンスデータを活用することで、広告配信をより効率的に行います。ターゲットユーザーに適切な広告を表示することで、ブランド認知の向上や新規顧客の獲得が期待できます。

## 3. DMP導入のメリット
DMPを導入することで、企業はさまざまな面で恩恵を受けることができます。具体的なメリットとして、以下の3つが挙げられます。

### 1. データの統合管理
DMPは、社内外の多様なデータを一元的に管理できるため、従来バラバラに管理されていたデータを効果的に活用できます。これにより、顧客の行動パターンや興味を把握し、的確な施策を打つことが可能になります。

### 2. ターゲティング精度の向上
DMPによって蓄積されたデータを分析することで、ターゲットとなる顧客像を明確に描くことができます。これにより、ペルソナに基づいたマーケティング施策が可能となり、コンバージョン率の向上が期待できます。

## 3. 効果的なマーケティングオートメーション
多くのDMPには、データをもとにマーケティング施策を自動化する機能が備わっています。自動でデータを分析し、ターゲットに合わせた1to1マーケティングや、メール配信などの施策を実施することで、マーケティング活動の効率が格段に向上します。

4. DMP導入時の注意点
　DMPを導入する際には、いくつかのポイントに注意する必要があります。

1. 目的を明確にする
　DMPは非常に多機能なツールですが、導入時にはまず、自社が達成したい具体的な目的を明確にすることが重要です。例えば、リテンション施策を強化したいのか、新規顧客の獲得を目指すのかによって、選ぶべきDMPツールや活用するデータが異なります。

2. 適切なツールを選ぶ
　DMPには、オープンDMPとプライベートDMP、さらにはさまざまな機能を持つツールがあります。自社のマーケティング戦略に最も適したツールを選定することが、成功のカギとなります。

3. データ活用の戦略設計
　DMPを導入しただけで効果が得られるわけではありません。どのデータをどのように活用し、施策の効果を測定・改善していくかという具体的な戦略設計が必要です。施策ごとのKPI設定やPDCAサイクルの導入が、DMP活用の成功には欠かせません。

## まとめ
 DMPは、**デジタルマーケティング**において非常に強力なツールです。自社データと外部データを組み合わせることで、精度の高いターゲティングやマーケティング施策が可能となり、結果としてビジネスの成長を促進します。導入時には目的を明確にし、適切なツールを選定し、戦略的にデータを活用することが成功の鍵です。
ゲームプログラマのための設計：ユーティリティ関数の置き場所

[ゲームプログラマのための設計シリーズ](https://qiita.com/kobitnex/items/93397d985682c806884c)：実装詳細編の記事です。

# 概要
* ユーティリティ関数は非メンバ関数にしよう
* ただし、テンプレートを用いた静的Strategyパターンを用いるときは例外的に静的メンバ関数を利用する

# 本文

## 基本は非メンバ
算術計算など、使用目的を限定しないいわゆるユーティリティ関数の置き場としては以下の二か所が考えられます。
```cpp
// 非メンバ関数版
namespace MathUtilityNS
{
	int Add(int, int);
	int Sub(int, int);
}
```
```cpp
// 静的メンバ関数版
class MathUtilityClass
{
public:
	static int Add(int, int);
	static int Sub(int, int);
};
```

実装する側としては大した違いはないのですが、利用側としては名前空間ならそれを省略できるのでそちらを優先してあげたいです。
```cpp
void func()
{
	// 名前空間なら、usingで省略できる
	using namespace MathUtilityNS;
	Add(1, 2);

	// 静的関数版はクラス名を省略できない
	MathUtilityClass::Add(1, 2);
}
```

※余談：実装する側としての違いの例
* 非メンバ関数版はうっかりinlineをつけ忘れるかもしれない
```cpp
namespace MathUtilityNS
{
	int Add(int lhs, int rhs) { return lhs + rhs; }  // inlineをつけてないのにインラインで定義を書くと、複数の.cppから参照されたときODR違反
}

class MathUtilityClass
{
public:
	static int Add(int lhs, int rhs) { return lhs + rhs; } // メンバ関数はインラインで書いてもODR違反にならない
};
```
* メンバ変数を持つクラスの静的メンバ関数とする場合、そのクラスのprivate変数に触れる
```cpp
class Vector2
{
	using Self = Vector2;
	float mX, mY;
public:
	explicit Vector2(float x, float y) : mX(x), mY(y) {}
	static Self Add(const Self& lhs, const Self& rhs)
	{
        // 静的であってもメンバ関数なのでprivateに触れる
		return Self{ 
			lhs.mX + rhs.mX, 
			lhs.mY + rhs.mY 
		};
	}
};
```
* メンバ関数の実装を.cppに書く場合毎回クラス名::を書かないといけなくて面倒

## 静的メンバ関数が必要になるケース
テンプレート引数を差し替えることで、関数内の処理を部分的に切り替えるStrategyパターンというデザインパターンがあります。（動的ポリモーフィズムを利用する方法と比較して静的Strategyパターンと呼ばれたりします。Policyパターンと呼ばれることも）
これを利用したいは非メンバ関数ではどうにもならないので、静的メンバ関数を利用することになります。

```cpp
// MathPolicyに与えたクラスのAdd/Sub関数を使って計算する関数
// C++20以降ではConceptを利用するのがベター
template<typename MathPolicy>
int calc(int a, int b, int c)
{
	// AddとSubの実装を、テンプレート引数で切り替えられる
	const int m = MathPolicy::Add(a, b);
	const int n = MathPolicy::Sub(b, c);
	return m * n;
}

void func()
{
	const int s = calc<MathUtilityClass>(1, 2, 3);
	const int t = calc<MathUtilityClass2>(1, 2, 3); // AddとSubの実装次第で違う結果になる
}
```

ハードウェアごとにそれぞれ最適な計算方法に丸っと切り替えたいなどといったケースで利用されますが、そのような場面はあまり多くはないでしょう。
s3 syncのソース、ターゲットバケットのオブジェクト数が合わない

## はじめに
業務ですs3の棚卸しをしていました。
S3 sync で削除するバケットの中身をアーカイブ用アカウントに作成したS３に同期させる際に詰まったことがあったので書いてきます。

## 何が起こったか
タイトル通りですが、あるAWSアカウントから他のAWSアカウントにs3 syncした際に、sync元と先のバケットを確認したところ、
バケットのサイズは一致するもののオブジェクト数が一致しませんでした。

## 何故か
結論から言うと、s3でフォルダを作成すると、0KBのオブジェクトが作成されていました。
そもそもマネコン上でS3を確認すると、S3はディレクトリ構造に見えるのですが、S3はディレクトリ構造ではなく、実態としてはKVSのようです。

Key＝ファイルのフルパス
Value＝ファイルの中身

例えば、`test/`フォルダを作成すると、マネコン上では確認できないですが、
S3の実態としては、サイズ0の、`test/`という要素が作成されます。
この要素(?)がs3 sync で同期されなかったため、sync元と先でオブジェクトの数が一致していない原因でした。
sync先のバケットを確認しましたが、オブジェクトはちゃんと同期されていたので問題はなかったです。

## 終わりに
AWSでは利用者側から見てわかりやすいように、内部の構造を意識させないようにしている工夫が沢山あると思いました。
今回のように、普段は意識していなくても良いけど、いざという時にしっかりと実態を理解しておく必要があると感じました。
ちょっと抽象的な説明になってしまったので、指摘あればコメントに何なりとお願いします。