OmniAICreator/Qiita-1.07M huggingface dataset:
【JavasScript】thisについて

# はじめに
この記事はJS初級者が中級者を目指して学習した内容のメモであることをご承知おき下さい
# JavaScriptの`this`について
## 目次
1. [概要](#概要)
2. [実行コンテキストごとの`this`](#実行コンテキストごとのthis)
    1. [グローバルスコープ内の`this`](#グローバルスコープ内のthis)
    2. [関数スコープ内の`this`](#関数スコープ内のthis)
    3. [メソッド内の`this`](#メソッド内のthis)
    4. [イベントハンドラー内の`this`](#イベントハンドラー内のthis)
3. [その他の補足](#その他の補足)
    1. [アロー関数と`this`](#アロー関数とthis)
    2. [`call`、`apply`、`bind`を使った`this`の制御](#callapplybindを使ったthisの制御)
    3. [クラス内の`this`](#クラス内のthis)

## 概要
JavaScriptの`this`キーワードは現在の実行コンテキストに関連するオブジェクトを参照します。`this`の値は関数が呼び出される状況によって異なります。以下によくある状況を記載します。
## 実行コンテキストごとの`this`
### グローバルスコープ内の`this`
グローバルスコープでは、`this`はグローバルオブジェクトを参照します。
（ブラウザ環境では`window`オブジェクトを参照します）
```js
console.log(this); // windowオブジェクトを参照する
```

### 関数スコープ内の`this`
通常の関数内で`this`を使用すると、`this`はグローバルオブジェクトを参照します。
ただし、strictモードで実行される関数内の`this`は`undefined`になります。
```js
function fn(){
  console.log(this); // windowオブジェクトを参照する
}
fn();
```

### メソッド内の`this`
オブジェクトのメソッド内で`this`を使用すると、`this`はそのメソッドを呼び出したオブジェクトを参照します。
```js
const person = {
  name: 'Bob',
  greet: function(){
    console.log('Hello I am ' + this.name); // 'Hello I am Bob'(thisは定数personを参照する)
  }
}
person.greet();
```

### イベントハンドラー内の`this`
DOM要素に紐づけられたイベントハンドラー内で`this`を使用すると、`this`はイベントをトリガーした要素を参照します。
```js
const btn = document.querySelector('button');
btn.addEventListener('click', function(){
  console.log(this); // クリックしたbutton要素のhtml(<button></button>)が表示される
})
```

## その他の補足
### アロー関数と`this`
アロー関数は、通常の関数と異なり、自身の`this`を持ちません。アロー関数内で`this`を使用すると、外側のスコープの`this`を参照します。これにより、関数の内外で`this`が一貫して参照できるため、特にイベントリスナーやコールバック関数で役立ちます。

### `call`、`apply`、`bind`を使った`this`の制御
JavaScriptでは、`call`、`apply`、`bind`といった関数メソッドを使って、関数の実行時に`this`の値を明示的に設定できます。

`call`: 関数を呼び出しながら`this`の値を設定します。
`apply`: `call`と同様に`this`の値を設定しながら関数を呼び出しますが、引数を配列として渡します。
`bind`: 関数に`this`の値をバインドし、新しい関数を返します。

### クラス内のthis
JavaScriptのクラスでは、メソッド内の`this`はインスタンス化されたオブジェクトを参照します。ただし、イベントリスナーやコールバック関数内でクラスのメソッドを使う場合、`this`の値が変わることがあります。その場合、アロー関数を使うか、`bind`メソッドで`this`をバインドすることが役立ちます。
```JS
class MyClass {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}

const myInstance = new MyClass('Alice');
myInstance.greet(); // "Hello, Alice!"

const button = document.querySelector('button');
button.addEventListener('click', myInstance.greet); // "Hello, undefined!"
button.addEventListener('click', () => myInstance.greet()); // "Hello, Alice!"
button.addEventListener('click', myInstance.greet.bind(myInstance)); // "Hello, Alice!"

```
ERMasterが重すぎる

# 状況・問題
Eclipse に ERMaster を入れて erm ファイルを編集したい。

以下のような時に Eclipse が止まる or 強制終了してしまう...
- ERMaster で erm ファイルを開く
- ERMaster で erm を保存
- Eclipse を起動
    - 最後に Eclipse を閉じる時に erm ファイルを開いていた場合

# 原因
erm ファイルのサイズがバカ増えてる（ERMaster のバグ？）

以下の部分の重複行が大量に
- `<referenced_column>数字</referenced_column>`
- `<relation>数字</relation>`

# 解決方法
↑の重複行を削除

### Vim の場合の手順
1. 対象のファイルを開く
1. 行指定移動で重複行をなんとか探す
    - `行数G`
        - ex. 31行目の場合 `31G`
    - かなり多いからすぐ見つかる
    - もしくは referenced_column で検索
        - `/referenced_column`
    - 何行目から何行目を消すのかメモ
1. 行を指定して削除
    - `:開始行,終了行d`
        - ex. 31行目から37行目の場合 `:31,37d`
    - 重複行が複数箇所で一気に削除する場合は後ろの方から
        - 前の先に消すと行番号変わる...（当然）
Salesforce 数式で動的に組織URLを作成する

# 概要
- いつも忘れてググるのでメモ
    - 自身の組織URLをハードコードしなくて良い
    - フロー内で作成したレコードURLを生成する場合にハードコードしなくて良い

## lightning.force.com(組織側)の場合
- 数式型の変数を作成して、下記を入力する
- Origin名までを下記で取得できる (例: `https://yourDomain.--c.vf.force.com`)

```
LEFT({!$Api.Enterprise_Server_URL_260}, FIND('/services', {!$Api.Enterprise_Server_URL_260}))
```

- 例えば、フロー側で Accountレコードを作って、Idを含む変数が `acconutId`だった場合:
- このURLで良いのか？と思うのですが、Idによって対象ページにリダイレクトされる

```
LEFT({!$Api.Enterprise_Server_URL_260}, FIND('/services', {!$Api.Enterprise_Server_URL_260})) & {!acconutId}
```

### 参考
https://admin.salesforce.com/blog/2022/create-a-record-link-dynamically-in-flow

## Experience Cloudサイトの場合
- 少しハードコードが必要になる  
- `YourSite`のところにサイト名をセットし、`ObjectName`と`Object.Id`をセットする

```
SUBSTITUTE(
  LEFT($Api.Partner_Server_URL_260,FIND("/services", $Api.Partner_Server_URL_530)),
  'salesforce.com/',
  'site.com/YourSite/'
)
& 's/ObjectName/' & {!ObjectName.Id}
```

### 参考
https://www.linkedin.com/pulse/how-make-dynamic-site-urls-dont-break-between-samuel-assaf
Mapper2

好的，以下是一个使用动态类和@SelectProvider的完整代码示例：

1. 定义Mapper接口：

```
@Mapper
@Repository
public interface MyMapper {
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<Result> selectData(Map<String, Object> params);
}
```

2. 定义SqlProvider类：

```
public class SqlProvider {
    public String selectSql(Map<String, Object> params) {
        String tableName = (String) params.get("tableName");
        String columnNames = (String) params.get("columnNames");

        String sql = String.format("SELECT %s FROM %s", columnNames, tableName);
        return sql;
    }
}
```

3. 定义动态类ResultSetMapper：

```
public class ResultSetMapper<T> implements ResultSetHandler<List<T>> {
    private Class<T> clazz;

    public ResultSetMapper(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public List<T> handle(ResultSet rs) throws SQLException {
        List<T> list = new ArrayList<>();
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();

        while (rs.next()) {
            T obj = null;
            try {
                obj = clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }

            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnLabel(i);
                Object columnValue = rs.getObject(i);
                setProperty(obj, columnName, columnValue);
            }

            list.add(obj);
        }

        return list;
    }

    private void setProperty(T obj, String propertyName, Object value) {
        try {
            Field field = obj.getClass().getDeclaredField(propertyName);
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
```

4. 调用Mapper接口方法：

```
@Autowired
private MyMapper myMapper;

public List<Result> selectData() {
    Map<String, Object> params = new HashMap<>();
    params.put("tableName", "my_table");
    params.put("columnNames", "column1, column2, column3");

    ResultSetMapper<Result> mapper = new ResultSetMapper<>(Result.class);
    return myMapper.selectData(params).stream().flatMap(Collection::stream).map(mapper::handle).collect(Collectors.toList());
}
```

在这个例子中，使用了@SelectProvider注解来指定SQL查询语句。SqlProvider类的selectSql方法返回SQL查询语句字符串。在Mapper接口方法中，调用了动态类ResultSetMapper来将查询结果映射成List<Result>。
az acr login でError saving credentials: error storing credentials - err: exec: "docker-credential-desktop.exe": executable file not found in $PATH, out: ``

# 装具したエラー
以下のエラーが出る。
```bash
az acr login -n <acrname>
Error saving credentials: error storing credentials - err: exec: "docker-credential-desktop.exe": executable file not found in $PATH, out: ``
Login failed.
```

# 解決策
`~/.docker/config.json` 内にある `credsStore` を削除

```bash
$ cat ~/.docker/config.json
{
  "auths": {
    <省略>
  },
  "credsStore": "desktop.exe" // <= この行を削除
}
```


# 参考
https://stackoverflow.com/a/65896682
https://forums.docker.com/t/docker-credential-desktop-exe-executable-file-not-found-in-path-using-wsl2/100225/29
SpringBootやってみた　振り返ってみた

# はじめに

　今回は、私がSpringBootを初めて触ってみた際にかなり詰まったので、自分自身への備忘録も兼ねてわからなかったことなどをまとめていきます。(もしかして...、わかったことの方が少ないのでは笑...)

# 前提

　参考程度にSpringBootをやる前の状態の筆者の技術スタックはこんな感じです。(SpringBootに関連しそうなものだけピックアップしてます)

- Java: 大学の講義で一応触った程度
- Kotlin: 昔、触ってみようとしたけどよくわからなくて"Hello World!"を出力したくらい
- SpringBoot: New!!ワクワク

# 困ったこと
## アノテーションよくわからん

　まず、困ったのがアノテーションです。簡単なCLIアプリケーションぐらいなのでアノテーションって何？ってなりました。ザッと検索するとアノテーションは注釈だそうです。注釈って言われてもよくわからないですね。

　アノテーションは機能付きのコメントという感じに自己解釈しました。SpringBootでは
＠Controllerや＠Serviceなどといったアノテーションを使用します。

```kotlin
例
@Controller
class UserController {
}
```

## DI(Dependency Injection)？

　SpringBootを含むSpringFrameworkはDIコンテナってのをよく使います。DIは要するに依存性の注入とのことなのですが、依存性？注入？コンテナ？よくわかりませんでした。正直、今でもわかってる気はしない...。

現状これだなと思っているのはこんな感じ
- オブジェクトを動かすのに必要なオブジェクト(コンポーネント)を実行時に外部から取ってきて使用するのがDI
- DIコンテナはコンポーネントを登録したり、登録したコンポーネントを使用したいオブジェクトに渡す機能を持っている
- オブジェクトを受け取る方法はいくつかある

```kotlin
@Repository
interface UserRepository {
    fun hogehoge()
}
```
↑で@Reposiroryアノテーションを付けたUserRepositoryインタフェースはDIコンテナに登録される

```kotlin
@Service
class UserService(
    private userRepository: UserRepository
) {
///
}
```
↑のUserServiceクラスのコンストラクタでDIコンテナに登録されているUserRepositoryインタフェースのインスタンスを使用できるようにした。

## AOP(アスペクト指向プログラミング)？
　どうやらSpringBootはアスペクト指向プログラミングを使うらしいです。
あまりよくわかっていないのですが、

- 共通の処理を抜き出す
- 必要に応じて共通の処理を横断的に様々なクラスで取得して使用する(要するにDI？)

といったことのようです。詳しいことは私がもっと詳しくなったら記事できたらなぁと思います。

## SpringSecurity難しい
　SpringSecurityはSpringFrameworkのプロジェクトで作られたアプリケーションの認証と認可を専門としたフレームワークです。これを使用してアプリケーションのログイン周りを実装していきます。今回、筆者はSpringBootをAPIとして作成しており、認証にはJWTを用いました。
しかし、SpringSecurity自体にはJWTを発行したり、デコードしたりといったよしなにしてくれる機能は無いです。
　一度、途方に暮れました......。
　最近は何でもよしなにしてもらえるので忘れてました......。
　フレームワークは何でもよしなにしてくれるということはありません。ただ、SpringSecurityにはフィルターと呼ばれるものがあり、自分でフィルターを作成すれば好きなように認証や認可を行うことができそうです。私の場合はログイン時にJWTを生成し、レスポンスヘッダーにJWTを格納するといった内容のフィルターを作成し、ログインに成功した際にフィルターの処理が実行されるようにしました。

# 最後に
　今回、初めてSpringBootを触ってみました。ざっくりとした感想としてはアプリケーションの実装を行う際の選択肢が豊富だなと思いました。JavaやKotlinで作成するためライブラリやフレームワークが多いです。そのため、ディレクトリ構成や使用するORマッパーも選択肢が多いです。今回はKotlinを使用していたのですが、Kotlinが書きやすいので書くストレスが少なかったです。(さすがコトリン！)
コンテナ管理・実行サービスについて整理してみた



# はじめに

本田技研工業 RoadSyncチームのバックエンドを担当している安部と申します。
今回はTechブログ第四弾の投稿となります。

RoadSyncの概要説明はTechブログ第一弾に記載していますので、ぜひご覧ください。
[Techブログ第一弾](https://qiita.com/nakamuloud/items/a4fe2d3173b361bcb3fe)

# **簡単に自己紹介**

私は今年の1月から本田技研工業へ入社(転職)し、RoadSyncチームでバックエンドを担当をしております。

前職では主にAzure、AWSを扱っていましたが、RoadSyncのバックエンドではGCPを扱っておりCloud Run上でAPI等をコンテナ化して運用しています。

そこで、自己学習の意味も込めて改めてクラウドのコンテナ管理・実行サービスの大まかな分類とその選定基準について整理していきたいと思います。

# **TL;DR**

- コンテナ管理・実行サービスをサーバレスか否かで分類してみた
- サーバレスなコンテナ管理・実行サービスとそうでないものの選定基準について考えてみた

# コンテナ管理・実行サービス**の分類について整理**

コンテナ管理・実行サービスは、大きく「サーバレスなコンテナサービス」と「サーバーレスではないコンテナサービス」に分けることができると考えています。サーバレスなコンテナサービスの概念はこちらを参考にしております。

[https://aws.amazon.com/jp/fargate/](https://aws.amazon.com/jp/fargate/)

- サーバレスなコンテナサービス
    
    コンテナを稼働させるリソースの所有、実行、ライフサイクル管理をクラウド事業者側が行うサービスです。そのため、利用者はOSへのパッチ適用やセキュリティ管理などを行う必要がなくアプリケーションの開発に集中できるようになります。
    
- サーバーレスではないコンテナサービス
    
    コンテナのオーケストレーション部分はマネージドされますが、コンテナを稼働させるリソースの管理は利用者が実施する必要があるサービスになります。そのため、利用するプロダクト、バージョンなどの自由度は高くなりますが、OSやミドルウェアへのパッチ適用など運用管理が発生します。
    
<font color="blue">**青色**</font>の部分はクラウド事業者が管理する領域になります。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3347144/625e9574-b8fb-449c-c4e7-8abf6f5f6dba.png)


3大クラウドのコンテナ管理・実行サービスで当てはめると大体このようになリます。

|  | サーバレスなコンテナサービス | サーバーレスではないコンテナサービス |
| --- | --- | --- |
| AWS | ・Amazon Elastic Container Service on Fargate<br>・Amazon Elastic Kubernetes Service on Fargate<br>・AWS App Runner | ・Amazon Elastic Container Service on EC2<br>・Amazon Elastic Kubernetes Service on EC2 |
| Azure | ・Azure Container Apps<br>・Azure Container Instances<br>・Azure Web App for Containers | ・Azure Kubernetes Service<br>・Azure Service Fabric<br>・Azure Red Hat OpenShift |
| GCP | ・Google Kubernetes Engine Autopilot<br> ・Cloud Run | ・Google Kubernetes Engine |

# **選定基準について考えてみる**

「サーバレスなコンテナサービス」と「サーバレスではないコンテナサービス」で比較検討しサービスを選定する場合、大きく以下の2つの観点で確認していくのが無難かと思います。（※）

- コスト面
    
    コンピューティングコストと運用コスト（利用料ではない）の側面で考えられ、一般的には大体以下の通りになるかと思います。
    
    |  | サーバレスなコンテナサービス | サーバーレスではないコンテナサービス |
    | --- | --- | --- |
    | コンピューティングコスト | 割高 | 普通 |
    | 運用コスト<br>（利用料ではない） | 低い | 高い |

- 利用用途
    
    例えば、サーバレスなコンテナサービスはGPUインスタンスに対応していないことが多く深層学習の学習用/推論用サーバーとして使うことはできません。このように利用用途で考えることもできるかと思います。
    

（※）この記事の中では詳しく触れませんが、例えばサーバレスなコンテナサービスの中でもそれぞれ異なる特徴があるので、サーバレスなコンテナサービスにすると決めた後も各サービスの特徴を理解した上でさらに選定する必要があります。

# 結論

- コンテナ管理・実行サービスは、大きく「サーバレスなコンテナサービス」と「サーバーレスではないコンテナサービス」に分類することができる。
- サービス選定の際はコスト面、利用用途の側面から考えてみるのがいい。
【SwiftUI】iOS15から使用できるmenuIndicatorについて調べた

# はじめに
`menuIndicator`というモディファイアがサジェストに出てきて気になったので調べてみました。

https://developer.apple.com/documentation/swiftui/image/menuindicator(_:)

# 何ができるものか
下向きの矢印を表示するかしないかの指定ができます。
![スクリーンショット 2023-04-27 17.27.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/46f8dc0d-1ebd-089b-3cb7-a992d455db98.png)

表示しない場合は以下のようになります。
![スクリーンショット 2023-04-27 17.29.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/20442770-2af4-73e2-43c0-7052b8e24b6e.png)

# 使い方
### 自動
```swift
Menu {
    Button("サンプル1") {}
    Button("サンプル2") {}
    Button("サンプル3") {}
    Button("サンプル4") {}
    Button("サンプル5") {}
} label: {
    Text("メニュー")
}
.menuIndicator(.automatic)
```

### 表示
```swift
Menu {
    Button("サンプル1") {}
    Button("サンプル2") {}
    Button("サンプル3") {}
    Button("サンプル4") {}
    Button("サンプル5") {}
} label: {
    Text("メニュー")
}
.menuIndicator(.visible)
```

### 非表示
```swift
Menu {
    Button("サンプル1") {}
    Button("サンプル2") {}
    Button("サンプル3") {}
    Button("サンプル4") {}
    Button("サンプル5") {}
} label: {
    Text("メニュー")
}
.menuIndicator(.hidden)
```

# おわり
他にも知らない機能がいっぱいありそうなので調査していきます。
MVCモデルとは

## MVCモデルとは
MVC（Model-View-Controller）モデルは、ソフトウェアアーキテクチャの一種で、アプリケーションを3つの主要なコンポーネントに分割することによって、アプリケーションの開発と保守を容易にするために設計されました。

## MVCモデルは、次の3つの主要なコンポーネントで構成されます。

#### Model（モデル） 
データやビジネスロジックを表します。このコンポーネントは、データの入出力や処理、データベースとのやり取りなどを担当します。

####  View（ビュー）
ユーザーインターフェースを表します。このコンポーネントは、ユーザーが表示するデータや情報を表示し、入力の受け付けを行います。

####  Controller（コントローラ）
ModelとViewを制御し、アプリケーションの振る舞いを決定します。このコンポーネントは、ユーザーの入力に基づいてModelの更新やViewの更新を行い、アプリケーションの振る舞いを決定します。

## MVCモデル

MVCモデルは、アプリケーションをより効率的に開発できるようにするだけでなく、アプリケーションの保守性を高め、変更の影響を最小限に抑えることができます。

MVCモデルでは、ModelとViewとの間には直接的な依存関係がありません。代わりに、Controllerを介して相互に通信します。これにより、ModelとViewは独立して開発や変更が可能になります。

たとえば、Viewのデザインを変更する場合、その変更がModelに影響を与えることはありません。同様に、Modelに新しい機能を追加する場合、それがViewにどのように表示されるかに関する修正をする必要はありません。Controllerが両方を制御するため、変更は一箇所で行うことができ、アプリケーション全体に一貫性を保つことができます。
(リンクだけです)迷路(英:maze)を調べた。

内容を追加する予定です。

# 迷路の定義(2023/05/18)

https://algoful.com/Archive/Algorithm/MazeExtend

# 簡単な迷路
①もっと簡単な、迷路を教えて下さい。
②罫線に、標準フォーマットありますか?
③mathematicaに取り込む方法を教えて下さい。

#### データ

```python
        myMaze = [
            "□", "□", "□", "□", "□", "□", "□", "□", "□", "□", "□", "□",
            "□", "S", " ", " ", " ", " ", " ", " ", " ", " ", " ", "□",
            "□", "□", " ", "×", " ", "□", "□", "□", "□", "□", "□", "□",
            "□", "□", " ", "×", " ", "□", " ", " ", " ", "×", " ", "□",
            "□", "□", " ", "×", "□", "□", " ", "×", " ", " ", " ", "□",
            "□", "□", " ", "×", "□", "□", " ", "□", "□", "□", " ", "□",
            "□", "□", " ", " ", "□", "□", " ", "□", "□", "□", " ", "□",
            "□", " ", "×", " ", " ", "×", " ", " ", " ", "□", " ", "□",
            "□", " ", " ", " ", " ", " ", " ", " ", " ", "□", "G", "□",
            "□", "□", "□", "□", "□", "□", "□", "□", "□", "□", "□", "□"
        ]
```

https://qiita.com/genmaiokome/items/9e6760630c758fa8a684#q-learning%E3%81%A7%E8%BF%B7%E8%B7%AF%E3%82%92%E8%A7%A3%E3%81%8F


# 参考

https://ja.wikipedia.org/wiki/%E8%BF%B7%E8%B7%AF

https://en.wikipedia.org/wiki/Maze

https://en.wikipedia.org/wiki/Maze_generation_algorithm

https://www.google.com/search?q=mathematica+maze+import+export&hl=ja&sxsrf=APwXEdfWZhOFpQC0QkFbGHChZj6PWUbBSA:1682647087385&ei=LyhLZIeQF9Pc-Qah-oyoBw&start=10&sa=N



https://rosettacode.org/wiki/maze_generation

# 参考　ゲーム

https://www.p-game.jp/game/316/detail

https://www.p-game.jp/

https://www.google.com/search?q=%E7%84%A1%E6%96%99%E3%82%B2%E3%83%BC%E3%83%A0+%E6%AF%94%E8%BC%83&rlz=1CAUHAM_enJP1038JP1038&oq=%E7%84%A1%E6%96%99%E3%82%B2%E3%83%BC%E3%83%A0%E3%80%80%E6%AF%94%E8%BC%83&aqs=chrome..69i57j0i546l2.16325j0j7&sourceid=chrome&ie=UTF-8
AWS configでルールを作成するときに3つの項目がでてきて悩んだので調べてみました。 

# AWSconfigルールについて
- AWS提供のプリセットルール
    - AWSが提供する既存のルールを使用して、AWSリソースのコンプライアンスをチェックします。
- Lambdaを使ったカスタムのルール
    - AWSが提供するルールがニーズを満たさない場合や、特定のロジックを適用してリソースのコンプライアンスを評価するために、Lambda関数を使用してカスタムルールを作成します。
- Gardを使用したルール
    - CloudFormation GuardはCloudFormationのテンプレートを規定したガバナンス、コンプライサンスに沿っているか評価するためのサービス
    以前はLambdaでカスタムルールを策定するしかありませんでした。なのでPythonなどのコーディング技術が必要だったが、CloudFormation　Guardで利用されている学習コストの少ないDSL言語で書けるようになり、CloudFormationからの使い回しもできるようになりました。

:::note alert
もし間違ってたら教えてください。
:::
Mapper

可以尝试使用以下代码来更改返回值类型：

```java
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.springframework.stereotype.Component;

@Mapper
public interface MyMapper {
    
    @SelectProvider(type = MyProvider.class, method = "getSelectSql")
    List<?> dynamicSelect(@Param("table") String table, @Param("fields") String fields, @Param("where") String where);

    class MyProvider {
        public static String getSelectSql(@Param("table") String table, @Param("fields") String fields, @Param("where") String where) {
            return String.format("select %s from %s where %s", fields, table, where);
        }
    }
    
    // 新增方法，用于修改返回值类型
    default void setReturnType(Method method, Class<?> returnType) throws NoSuchFieldException, IllegalAccessException {
        Type[] genericInterfaces = getClass().getGenericInterfaces();
        for (Type genericInterface : genericInterfaces) {
            if (genericInterface instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
                if (parameterizedType.getRawType().equals(MyMapper.class)) {
                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                    Type returnTypeArgument = actualTypeArguments[0];
                    returnTypeArgument = returnType;
                    break;
                }
            }
        }
    }
}
```

然后，可以在 service 中调用 `MyMapper.setReturnType()` 方法来更改返回值类型，例如：

```java
@Service
public class MyService {

    @Autowired
    private MyMapper myMapper;

    public void changeReturnType() throws NoSuchFieldException, IllegalAccessException {
        Method method = MyMapper.class.getMethod("dynamicSelect", String.class, String.class, String.class);
        myMapper.setReturnType(method, MyClass.class);
    }

}
``` 

在 `changeReturnType()` 方法中，我们获取了 `dynamicSelect()` 方法的 `Method` 对象，然后调用 `myMapper.setReturnType()` 方法来更改其返回值类型为 `MyClass`。注意，由于 `setReturnType()` 方法定义在 `MyMapper` 接口中，因此我们可以在 service 中直接通过 `myMapper.setReturnType()` 来调用。
【IBM Application Gatway】新しいイメージ（23.04）が公開されました

# IBM Application Gatwayのイメージについて
新しいイメージは以下から取得できます。
https://docs.verify.ibm.com/gateway/docs/containers#ibm-application-gateway
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/eedd1ca0-a5e6-17ce-ce4b-39ef94525a32.png)

# 新機能について
以下から確認できます。
https://docs.verify.ibm.com/gateway/docs/overview-whats-new

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/d5aec016-2393-4bda-a5db-19d517b08622.png)

- form based single sign on
    - form_response_patternオプションが追加されています。
- Rate Limiting
    - レスポンスに新しいヘッダーが追加されたとあります。
- General
    - Bug Fixes, Security Updates がありました。
    - 22.07イメージをECRでスキャンしたときの問題が解消されていました。

# 参考
- https://docs.verify.ibm.com/gateway/docs/containers
- https://docs.verify.ibm.com/gateway/docs/overview-whats-new
- https://docs.verify.ibm.com/gateway/docs/containers#ibm-application-gateway
(リンクだけです)川渡り問題(英:River crossing puzzle)を調べた。

tag:論理パズル にも投稿がありました。
内容を追加する予定です。

# 参考1

https://ja.m.wikipedia.org/wiki/%E5%B7%9D%E6%B8%A1%E3%82%8A%E5%95%8F%E9%A1%8C

https://en.wikipedia.org/wiki/River_crossing_puzzle

# 参考2

https://www.google.com/search?q=%E5%AE%A3%E6%95%99%E5%B8%AB%E3%81%A8%E5%85%88%E4%BD%8F%E6%B0%91%E5%95%8F%E9%A1%8C&oq=%E5%AE%A3%E6%95%99%E5%B8%AB%E3%81%A8%E5%85%88%E4%BD%8F%E6%B0%91%E5%95%8F%E9%A1%8C&aqs=chrome..69i57.1398j0j7&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8

https://en.wikipedia.org/wiki/Missionaries_and_cannibals_problem
GPTを使用したクラウドセキュリティの分析

![banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3286109/4481b821-9aec-0762-7498-7d8ff2bdaf95.png)

### **概要**

現代のデジタル時代において、クラウドセキュリティはますます重要なタスクになっています。数えきれないほどのクラウドセキュリティの問題が毎日発生し、迅速な分析と解決が必要です。しかし、これらの問題を手動で分析して解決するには、多くの時間と労力が必要です。そして、それがSelefraが生まれた理由です。

Selefraは、ポリシーとしてコードを記述する製品であり、ユーザーがクラウドセキュリティ分析、コスト分析、アーキテクチャ分析を迅速に実行できるように支援します。最近、SelefraはGPT機能も追加され、ChatGPTに似た方法でクラウド製品をセキュリティ上の問題の分析ができるようになりました。この記事では、AWS S3ストレージバケットの問題を例にとり、Selefraの使用方法を紹介します。

## **Selefraを実行する**

### インストール

まず、Selefraのインストールは非常に簡単です。次のコマンドを実行するだけです。

```

brew tap selera/tap
brew install selefra/tap/selefra
mkdir selefra-demo & cd selefra-demo & selefra init

```

### プロバイダーを選択する

次に、シェルで必要なプロバイダーを選択する必要があります。例えば、AWSの場合：

```

[Use arrows to move, Space to select, and enter to complete the selection]

[✔] AWS # We choose AWS installation
[ ] azure
[ ] GCP
[ ] k8s

```

### **構成**

**AWSの設定:**

事前に、AWSの設定に関する詳細なドキュメントを作成しています。ここでAWS情報を事前に設定することができます。

**Selefraの設定:**

初期化後、selefra.yamlファイルが生成されます。その次のステップとして、次の設定を行ってGPT機能を使用する必要があります。

```

selefra:
  name: selefra-demo
  cli_version: latest
  openai_api_key: <Your Openai Api Key>
  openai_mode: gpt-3.5
  openai_limit: 10
  providers:
    - name: aws
      source: aws
      version: latest

```

### 実行

環境変数を使用して、openai_api_key、openai_mode、およびopenai_limitパラメーターを保存することができます。次に、以下のコマンドを実行してGPT分析を開始できます。

```

selefra gpt "Please help me analyze the vulnerabilities in AWS S3?"

```

最後に、以下のアニメーション画像のような結果が得られます。

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3286109/03aeb393-fa23-61c2-ee3c-dc841fd18e06.gif)

## **読んでいただきありがとうございます**

ここで、Selefraを試して、より迅速かつ効率的なクラウドセキュリティ分析と解決の体験をお楽しみください。Selefraに関する詳細情報は、公式ウェブサイト（**[https://www.selefra.io/](https://www.selefra.io/)**）やGitHub（**[https://github.com/selefra/selefra](https://github.com/selefra/selefra)**）で確認することができます。また、Twitterアカウント（**[https://twitter.com/SelefraCorp](https://twitter.com/SelefraCorp)**）をフォローして、よりリアルタイムな情報を得ることができます。
【webpackでの失敗備忘録1】ビルドしたhtmlでimgのパスが変わらない【url-loader】

## 問題
ビルド前のhtmlに記述した`<img src="">`のパスがビルド後も変わらなかったこと。

## ディレクトリ構成
```
/
└index.html
└img/
　 └hoge.jpg
```

## 設定ファイル
▼webpack.config.js

```
{
  test: /\.(jpe?g|png|gif|svg|ico)$/,
  loader: 'url-loader',
  options: {
    limit: 2048,
    name: '[name].[ext]',
    esModule: false,
    outputPath: 'images/',
    publicPath: function (path) {
      return {buildPath} + path;
    },
  }
},
```
※`{buildPath}`はここには書けないので割愛。

▼html
`<img src="/img/hoge.jpg" alt="hoge">`

## コンパイル後のhtml
`<img src="/img/hoge.jpg" alt="hoge">`

変わらねえ〜〜〜〜

## 原因
指定したパスにimgディレクトリが無かったため。
指定した場所に画像が無ければローダーは読み込めないよ！！
下記のようにディレクトリ構造に合わせてパスを指定すると、問題なくwebpack.config.jsの設定通りにパスが書きかわりました。

▼html
`<img src="./img/hoge.jpg" alt="hoge">`

## コンパイル後のhtml
`<img src="{buildPath}/hoge.jpg" alt="hoge">`

解決
【合格体験記】AWS Certified Developer - Associateに合格しました(2023/02/23)【DVA-C01】

# 目次
[#1.はじめに](#1はじめに)
[#2.筆者のスペック](#2筆者のスペック)
[#3.学習内容](#3学習内容)
[#4.学習期間](#4学習期間)
[#5.試験当日](#5試験当日)
[#6.あとがき](#6あとがき)

# 1.はじめに

題名の通り、AWS Certified Developer - Associate(DVA)に合格しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">無事AWS Certified Developer - Associate合格しました！<br>頑張ってよかった😭😭😭<br>これで二冠です🤞<a href="https://twitter.com/hashtag/AWS%E8%AA%8D%E5%AE%9A?src=hash&amp;ref_src=twsrc%5Etfw">#AWS認定</a><a href="https://twitter.com/hashtag/DVA?src=hash&amp;ref_src=twsrc%5Etfw">#DVA</a> <a href="https://t.co/0JO9Yg2f6K">pic.twitter.com/0JO9Yg2f6K</a></p>&mdash; ss@AWS勉強中、支援士結果待ち (@ss_IT_study) <a href="https://twitter.com/ss_IT_study/status/1628700428774047744?ref_src=twsrc%5Etfw">February 23, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

2023/04時点の最新バージョンであるDVA-C02ではなく、2023/02で終了したDVA-01となります。
現在は受験できないバージョンではありますが、大筋は変わらないかと思いますので、参考として投稿させていただきます。

# 2.筆者のスペック

* 大学は情報系
* SIerで10年程度勤務
* 基盤知識としてはLinux利用経験程度
* 開発知識としてはGit、Javaの利用経験程度
* AWS SAA取得済み([【合格体験記】AWS Certified Solutions Architect - Associateに合格しました(2022/11/19)【SAA-C03】](https://qiita.com/ss_IT_study/items/d14b81ea4c92ced86786))

# 3.学習内容

①[AWS Code サービス群を活用して、CI/CD のための構成を構築しよう！](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cicd-2022-reg-event.html?trk=aws_introduction_page)

AWS公式が提供しているAWS Hands-on for Beginnersのコンテンツとなります。
所属している会社の教育の一環で実施する機会がありました。
内容としてはCodeシリーズの一通りのハンズオンを行いCodePipelineを利用したCI/CDの構成を体験できます。
DVAの試験範囲であるCodeシリーズの理解が進むというのもありますが、
認定試験の勉強はしているもののあまりAWSに触れたことがないという開発者にはかなりおすすめのコンテンツです。
※公式の目次を見れば記載がありますが、cloud9を利用した開発環境の利用も内容に含まれています

SAA取得後にDVAの取得を目指したきっかけはこのハンズオンとなります。

②[ポケットスタディ AWS認定 デベロッパーアソシエイト (アソシエイト試験ポケットスタディ)](https://www.amazon.co.jp/%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-AWS%E8%AA%8D%E5%AE%9A-%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E8%A9%A6%E9%A8%93%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-%E5%B1%B1%E4%B8%8B%E5%85%89%E6%B4%8B/dp/4798063401)

トレノケート株式会社の山下光洋氏の著書となります。
画面イメージも挿入されており、理解しやすい参考書でした。
また、個人的には本書の演習問題が試験対策として有効と感じており、
2周することでかなり力がつきました。
youtubeで実際に操作をしている配信のアーカイブが公開されており、
こちらも参考になりました。

③公式模擬試験

AWS スキルビルダーで公開されている公式模擬試験です。
試験直前の習熟度確認に利用しました。
実施の試験に近い形式で問題演習することができます。
※以前は有料だったようですが、無料で利用することができました


# 4.学習期間
|#|教材|期間　|
|:---|:---|:---|
|1|AWS Code サービス群を活用して、CI/CD のための構成を構築しよう！|1日|
|2|ポケットスタディ AWS認定 デベロッパーアソシエイト (アソシエイト試験ポケットスタディ)|14日|
|3|公式模擬試験|1日|

# 5.試験当日
SAA受験時と同様にテストセンターを予約の上受験しましたが
私の時はDVA-C01終了間近ということもあり混んでいました。
勉強のモチベーションを上げる意味でも試験予約は早めにしたほうがいいかなと思います。

過去のバージョンでは受験後すぐに画面上に合否が出力されたみたいですが、
私が受験した時は試験終了後即時結果が分かるわけではなく、
しばらく経ってから試験履歴が更新されました。
※ざっくりですが、11:00開始の試験を受けて19:00くらいに結果が閲覧可能になったと思います

# 6.あとがき
AWS DVA(DVA-C01)の合格体験記でした。
2023/04に情報処理技術者試験を挟んでいますが、
次回はSOAかSAPに挑戦しようかなと考えています。
アソシエイト三冠やプロフェショナルの資格取得を目指して頑張ります！
RubyでAtCoder ABC274(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC274のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Batting Average
https://atcoder.jp/contests/abc274/tasks/abc274_a
```diff_ruby:a-274.rb
a, b = gets.split.map(&:to_f)
- s = (b / a).round(3).to_s
+ s = b.fdiv(a).round(3).to_s

- puts s + "0" * (5 % s.size)
+ puts sprintf("%0.3f", s)
```
## 解説
1.0や0.0だと桁数が足りないので出力するときに調整しています。

# B - Line Sensor
https://atcoder.jp/contests/abc274/tasks/abc274_b
```ruby:b-274.rb
# 修正前
h, w = gets.split.map(&:to_i)
array = Array.new(h){ gets.chomp.chars }.transpose
count = []
array.each do |factor|
  count << factor.count("#")
end
puts count.join(" ")
```
```ruby:b-274.rb
# 修正後
h, w = gets.split.map(&:to_i)
array = Array.new(h){ gets.chomp.chars }.transpose
puts array.map{ |factor| factor = factor.count("#")}.join(" ")
```
## 解説
列で考えるのでtransposeメソッドを使って、行と列を入れ替えています。

# C - Ameba
https://atcoder.jp/contests/abc274/tasks/abc274_c
```ruby:c-274.rb
# 修正前
n = gets.to_i
a = gets.split.map(&:to_i)

array = Array.new(2 * n + 1, 1)
array[0] = 0
for i in 1..n - 1
  array[2 * (i + 1) - 1] += array[a[i] - 1]
  array[2 * (i + 1)] += array[a[i] - 1]
end

array.each do |factor|
  puts factor
end
```
```diff_ruby:c-274.rb
# 修正後
n = gets.to_i
a = gets.split.map(&:to_i)

array = [0, 1, 1]
for i in 1..n - 1
- array[2 * (i + 1) - 1] = array[a[i] - 1] + 1
- array[2 * (i + 1)] = array[a[i] - 1] + 1
+ array[2 * (i + 1)] = array[2 * (i + 1) - 1] = array[a[i] - 1] + 1
end

puts array
```
## 解説
何代親を遡るとアメーバ1になるかを記録する大きさ2*n+1の配列を1で初期化します。ここで、アメーバ1は遡る必要がないので`array[0]=0`としています。後は、順次それぞれのアメーバについて配列の値を更新していくことで実装することができます。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
IBM MQ30周年！

## はじめに
今年はIBM製品のMQが30周年を迎えました。
30周年おめでとうございます。

MQはお客様からの信頼も厚く、業界問わず様々なお客様がMQを使い続けていただいているおかげです。ありがとうございます。

私はIBMに転職してまだ１年なのでMQとの思い出を語れるほどではないのですが、現在、担当しているお客様からMQの勉強会を自社の社員向けに実施してほしいと要望をいただきました。
MQ,Websphereは、お客様システム内でも重要な製品としてご利用いただいており、そのため製品知識を社員に身に着けさせたい、というリーダー層の思いがありました。

## 勉強会の内容
さて、MQの勉強会を開催するにあたって、どのような内容が良いかと色々と調べてみました。
今回は若手社員向けということで超入門でお話しようかと思います。
簡単に自分の中で整理した内容です。

>**MQ（Message Queue）とは**
>・やりとりするメッセージをキューに貯めて非同期にデータのやり取りをする、
>　コミュニケーションシステム
>・受信者の状態にかかわらず、メッセージを送ることができる
>
>**コンポーネント**
>　MQキュー・マネージャ、MQアプリケーション、チャネル、キューなど
>
>**接続形態**
>・スタンドアロン
>・キューマネージャ接続
>・MQクライアント接続
>
>**デモ**
>　MQが動く環境のデモをお見せしながら、MQで何が出来るのかをご紹介

こういったラインアップでご説明しようかなと現時点では考えています。
これから資料作成＆デモ環境を準備し、メンバからの意見もいただきながら、
内容をブラッシュアップしてお客様に良い説明ができるようにしていきたいと思います。

## おわりに
今回参考にした資料は以下です。
非常に分かりやすい内容ですので、興味がある方はぜひ参照してみてください。
https://note.com/ibm_automation/n/necd139053ea1
※下のほうにIBM MQ 超入門としてシリーズ化されています。
node-sassをdart-sassへ移行したい

## はじめに

以下の環境でnode-sassをdart-sassに移行する機会があったので、
それぞれの違いや移行手順を共有します。
- JavaScript
- React18

## Node-sass , Dart-sassとは

### Node-sass

Node-sassは、Node.jsを使ってSass (Syntactically Awesome Style Sheets) をコンパイルするためのツールです。
SassはCSSの拡張言語で、より効率的で簡単なスタイルシートの記述が可能です。

ただし、Node-sassは開発が停止しているため、新規プロジェクトではDart-sassを使用することが推奨されています。

### Dart-sass

Dart-sassは、CSSの拡張言語であるSass（Syntactically Awesome Style Sheets）をコンパイルするためのツールです。Sassを使用することで、変数やネスト、ミキシンなどの便利な機能を使って、効率的で簡単なスタイルシートの記述が可能になります。

### Node-sassとの違い

-   Node-sassは、C/C++で書かれたLibSassを使用していますが、Dart-sassはDart言語で実装されています。
-   Dart-sassはSassの公式実装で、最新の機能やバグ修正が随時サポートされています。一方、Node-sassおよびLibSassは開発が停止しており、今後のメンテナンスやアップデートは予定されていません。
-   Dart-sassは、モジュールシステムや新しい関数などの新機能に対応していますが、Node-sassではこれらの機能が利用できません。
-   Dart-sassは、パフォーマンス面でNode-sassよりも若干遅

## 移行するメリット

1.  公式サポート: Dart-sassはSassの公式実装であり、最新の機能やバグ修正が継続的に提供されます。一方で、Node-sass（LibSassベース）は現在開発が停止しており、今後のメンテナンスやアップデートは予定されていません。
    
2.  新機能への対応: Dart-sassは新しいSass機能に対応しています。例えば、モジュールシステム（`@use`および`@forward`）や、新しい数学関数（`math.div()`や`math.sin()`など）を利用できます。
    
3.  より良いエラーレポート: Dart-sassは、エラーが発生した際により詳細で分かりやすいエラーレポートを提供します。これにより、問題の特定と解決が容易になります。
    
4.  互換性と拡張性: Dart-sassは将来のSass言語の進化に追従し、新しい機能や最適化が利用できるようになります。これにより、プロジェクトの互換性と拡張性が確保されます。
    
5.  環境に依存しない: Dart-sassはDart言語で実装されており、C/C++バインディングに依存しないため、環境間での互換性が向上します。
    

ただし、Dart-sassはパフォーマンス面でNode-sassよりも若干遅いことがある点には注意が必要です。しかし、公式サポートや新機能の利用、環境間での互換性が向上することを考慮すると、Node-sassからDart-sassへの移行はお勧めです。


## 移行手順

Node-sassからDart-sassへの移行を分かりやすく説明すると、以下の手順になります。

1. Node-sassをアンインストール:
  プロジェクトのディレクトリで、次のコマンドを実行してnode-sassをアンインストールします。

    ```bash
    npm uninstall node-sass
    ```
2. Dart-sassをインストール:
  Dart-sassはnpmの`sass`という名前でパッケージされています。次のコマンドでインストールします。

    ```bash
    npm install sass
    ```

3. スクリプトの変更:
  `package.json`内の`scripts`セクションで、Sassのコンパイルに関するスクリプトがnode-        sassからsassに変更されていることを確認します。例えば、次のようになります。

    ```json
    "scripts": {
    "build:css": "sass src/styles/index.scss dist/styles/index.css",
    ...
    },
    ```

4. インポートステートメントを更新:
  プロジェクト内のすべてのSassファイルのインポートステートメントを更新して、新しいファイル拡張子（`.sass`または`.scss`）を含めるようにします。これは、Dart-sassの仕様に沿ったものです。

    例:

    ```scss
    // 以前
    @import 'variables';
    
    // 更新後
    @import 'variables.scss';
    ```

5. 必要に応じてその他の変更を行う:
Dart-sassでは、一部の関数やミキシンが変更されています。そのため、プロジェクト内のSassファイルでこれらの変更に対応する必要があるかもしれません。詳細は、公式の[migration guide](https://sass-lang.com/documentation/breaking-changes)を参照してください。

移行が完了したら、プロジェクトをビルドし、Sassが正しくコンパイルされていることを確認してください。これで、Node-sassからDart-sassへの移行が完了しました。
プリザンターのセッションタイムアウトを変更する

# はじめに
どのアプリでもセキュリティのため、セッションタイムが設定されているかと思います。プリザンターでもセッションタイムが設定されていますが、今回の記事は設定ファイルについて記載しようと思います。

# セッションタイムの設定ファイル
プリザンターを規定通りにインストールいただけていれば、webフォルダ配下に下記「Session.json」が存在すると思います。  
pleasanter\Implem.Pleasanter\App_Data\Parameters\Session.json  
こちらを開いてみるとデフォルトで「1440」と記載があります。この数字は分単位で指定可能であるため、デフォルトでは1日(=1440分)となっています。こちらの数値を操作することでセッションタイムを独自に設定することが可能です。「Session.json」の詳細については[パラメータ設定：Session.json](https://pleasanter.org/manual/session-json)をご参照ください。

# 必ず実施してください
「Session.json」に限らず、設定ファイルを操作した場合必ずサーバーの再起動が必要になります。再起動をしないと設定が反映されないため、必ず実施してください。
EC-CUBEバージョン~4.1でのインボイス対応カスタマイズ

# 前提
### EC-CUBEデフォルト機能
EC-CUBE4.2以降はデフォルトでインボイス対応
EC-CUBE4.1以前はカスタマイズが必要
### 税額計算方式
【計算方式】
▶︎EC-CUBE4.1　
商品ごとの割戻し計算

【計算式】
10％対象商品
税込小計×(10/110)=税額

8％対象商品
税込小計×(8/108)=税額

【計算実例】
10％対象商品
1,100（税込単価）×10（数量）=11,000（税込小計）
11,000（税込小計）×(10/110)=1,000（税額）

8％対象商品
1,080（税込単価）×10（数量）=10,800（税込小計）
10,800（税込小計）×(8/108)=800（税額）


【端数処理】
▶︎EC-CUBE4.1　
設定で切上げ、切捨て、四捨五入を選択

▶︎インボイス制度　
端数処理方法は任意（切上げ、切捨て、四捨五入）
請求書ごとの端数処理がマスト（商品ごとの端数処理は不可）

【値引き処理】
▶︎EC-CUBE4.1
税込合計金額（値引き処理前）から税率ごとの消費税計算
［税込合計金額］→［消費税計算］
［税込合計金額］→［値引き処理］→［請求金額］

▶︎インボイス制度　
値引き後合計金額から税率ごとの消費税額算出がマスト
［税込合計金額］→［値引き処理］→［消費税計算］
［税込合計金額］→［値引き処理］→［請求金額］

### 請求書記載事項
▶︎EC-CUBE4.1
１）会社名
２）取引内容
４）適用税率
５）税率ごとの小計
６）相手先名

▶︎インボイス制度　
１）会社名
２）登録番号
３）取引内容
４）適用税率
５）税率ごとの小計
６）税率ごとの税額
７）相手先名


# カスタマイズ箇所
### 計算ロジック
▶︎EC-CUBE4.1
［数量］×［税込単価］=［商品ごとの合計］
8%対象{［商品ごとの合計］+［商品ごとの合計］…}=［8%商品合計］
10%対象{［商品ごとの合計］+［商品ごとの合計］…}=［10%商品合計］
［8%商品合計］×［税率］=［8%商品税額］
［10%商品合計］×［税率］=［10%商品税額］
［8%商品合計］+［10%商品合計］=［商品合計］
［商品合計］+［送料］+［手数料］-［値引き］=［合計］
［合計］=［請求金額］

▶︎インボイス制度
［数量］×［税込単価］=［商品ごとの合計］
8%対象{［商品ごとの合計］+［商品ごとの合計］…}=［8%商品小計］
10%対象{［商品ごとの合計］+［商品ごとの合計］…}=［10%商品小計］
［8%商品小計］+［10%商品小計］=［商品小計］
［値引き額］×［8%商品小計/商品小計］=［8%商品値引き額］
［値引き額］×［10%商品小計/商品小計］=［10%商品値引き額］
［8%商品小計］-［8%商品値引き額］=［8%商品合計］
［10%商品小計］-［10%商品値引き額］=［10%商品合計］
［8%商品合計］×［税率］=［8%商品税額］
［10%商品合計］×［税率］=［10%商品税額］
［8%商品合計］+［10%商品合計］+［送料］+［手数料］=［合計］
［合計］-［値引き額］=［請求金額］

### 請求書（納品書カスタム）
◾️デフォルト◾️
![スクリーンショット 2023-04-27 15.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/006fc195-c67a-cfe3-c2c7-4b15796e9ea5.png)

◾️インボイス対応カスタム◾️

【追加】
＜登録番号＞

【変更】
消費税計算前に値引き
＜値引き＞

【変更】
値引き後の税率ごとの
＜税率＞
＜小計＞
＜消費税額＞

### 注文確認ページ
◾️デフォルト◾️
![スクリーンショット 2023-04-27 15.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/bedb7a8a-b9bc-8687-d3b9-62b21b7e4c16.png)

◾️インボイス対応カスタム◾️

【変更】
消費税計算前に値引き
＜値引き＞

【変更】
値引き後の税率ごとの
＜税率＞
＜小計＞
＜消費税額＞

### 注文確認メール
◾️デフォルト◾️
![スクリーンショット 2023-04-27 15.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/4f5ffbda-53ca-ed70-d230-972eae45cbf7.png)

◾️インボイス対応カスタム◾️

【追加】
＜登録番号＞

【変更】
消費税計算前に値引き
＜値引き＞

【変更】
値引き後の税率ごとの
＜税率＞
＜小計＞
＜消費税額＞

### 管理画面＞受注管理＞受注登録ページ
◾️デフォルト◾️
![スクリーンショット 2023-04-27 15.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/efbd1137-b789-9e7b-1eda-8f3b3b44cd8d.png)

◾️インボイス対応カスタム◾️

【変更】
消費税計算前に値引き
＜値引き＞

【変更】
値引き後の税率ごとの
＜税率＞
＜小計＞
＜消費税額＞

# 参考記事
https://www.thank-u.net/blog/eccube/invoice_support_for_eccube/#toc15
https://github.com/EC-CUBE/ec-cube/issues/4268
【Azure】DataFactoryのアクティビティ失敗時のメール通知

## はじめに

こんにちは。株式会社ZEALの@ey___00129です。

**Azure DataFactoryのアクティビティが失敗した際のメール通知**について
**Azure Logic Apps**を使って実装していきたいと思います。


利用するAzureリソースは以下
・DataFactory
・Azure Logic Apps

所要時間：30分程で実装可能


## Logic Appsの作成


まずは、Logic Appsのリソースを作成していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/a771b2e3-e358-028a-4f82-2cb771bc13b5.png)

ロジック アプリ デザイナーにて作成フローは以下の通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/32657bd5-f44c-90a0-e2f5-b2fad4c239e3.png)

HTTP POSTのURLは、あとでDataFctory上で使います。
**JOSNスキーマには、DataFactoryから受け取るデータのスキーマを定義**します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/c811b87f-5399-1608-52c5-e7e66d3212da.png)

今回は、以下を対象にJSONを記載。
・対象のDataFactory名
・エラーメッセージ
・パイプライン名

```
{
    "properties": {
        "dataFactoryName": {
            "type": "string"
        },
        "message": {
            "type": "string"
        },
        "pipelineName": {
            "type": "string"
        }
    },
    "type": "object"
}
```

メール送信部分で、**メールの本文、宛先の設定、上記で受信したデータ**を利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/56caadbb-82bd-1b0a-9184-b3e0fc598850.png)


他にも、差出人や重要度をオプションとして追加できそうでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/df8b53f8-069e-dd4b-398a-42f4d892c139.png)



ここまでで、**Logic Appsの設定は完了**です。
そのまま実行してメールを送れるか試すことも可能です。


## DataFactoryのアクティビティ設定

ここからは、DataFactoryのアクティビティ設定となりますが、
先ほど作成したLogic AppsのURLが必要となります。

まず、エラーを検知したいアクティビティからエラーの赤線を引っ張り
Webアクティビティに繋げます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/8708c139-471b-4602-4487-815c2e9c25fa.png)


Webアクティビティの詳細は、以下。
URL部分に**Logic AppsのURLを貼り付けます。**


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/928ecdfc-8575-d12a-d7c1-bdf403533387.png)


Bodyは、**Logic Appsに送信するJSONを記載**します。

```
{"message":"@{activity('Insert').error.message}","dataFactoryName":"@{pipeline().DataFactory}","pipelineName":"@{pipeline().Pipeline}"}
```

## DataFactory実行確認

作成したパイプラインを実際に動かしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/8c76662f-cb99-0770-5b50-ea8ba0f8a860.png)


エラー通知のメールが飛んできました！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741843/7c071bfe-015a-35e3-f864-26afaa1f1e0c.png)




以上で、完了です。
xampp上のHPでexcelファイル（xlmx）を読み込む方法（Linux）

### ０．環境
　Chromebook上のLinuxでやっています。
　ChromebookにXAMPP環境を構築するには、Qiita上でググってみてください。

### １．Composerのインストール
　まずは「Composer」コマンドが使えるようにします。
```terminal
sudo apt-get install php
```
からの
```terminal
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer.phar
sudo ln -s /usr/local/bin/composer.phar /usr/bin/composer.phar
alias composer="php /usr/bin/composer.phar"
alias sudo='sudo '
```

一番下のコマンドに関しては、
> sudoコマンドでaliasを使えるようにする
> https://qiita.com/homoluctus/items/ba1a6d03df85e65fc85a

を参照のこと
```terminal
composer -V
```
でバージョンが見れればOK

### ２．色々ダウンロード
```terminal
sudo apt-get install php-xml
sudo apt-get install php-gd
sudo apt-get install php-mbstring
sudo apt-get install php-zip
```

### ３．ここで参考にしたいのは
> aalfiann/install_composer_xampp_ubuntu.md
> https://gist.github.com/aalfiann/5ec4fe415ae4c6b8ddd79bffdcd33070
　目を通して、必要に応じて実行してください。

### ４．spreadsheetのインストール
　ご自身のwebにcomposerとかいう名前でmkdirしておき、その中にcdします。
そこで、
```terminal
sudo composer require phpoffice/phpspreadsheet
```
を実行すると、
composer.jsonやcomposer.lockやvendorが生成されているかと思います。

### ５．テスト
こんな感じのHTMLと、xlmxを配置し、中身が見えたらOK！
```html:index.php
<!DOCTYPE html>
<html>
<head>
	<title>Excelファイルの内容を表示</title>
	<style>
		table, th, td {
		  border: 1px solid black;
		  border-collapse: collapse;
		}
		th, td {
		  padding: 5px;
		  text-align: left;
		}
	</style>
</head>
<body>

<?php
require 'composer/vendor/autoload.php'; // ComposerでインストールしたPhpSpreadsheetを読み込む

use PhpOffice\PhpSpreadsheet\IOFactory;

// Excelファイルを読み込み、データを配列に格納
$spreadsheet = IOFactory::load('example.xlsx');
$worksheet = $spreadsheet->getActiveSheet();
$data = $worksheet->toArray();

// HTMLテーブルを作成して、Excelファイルの内容を表示
echo '<table>';
foreach ($data as $row) {
    echo '<tr>';
    foreach ($row as $cell) {
        echo '<td>' . $cell . '</td>';
    }
    echo '</tr>';
}
echo '</table>';
?>

</body>
</html>

```

### ６．参考資料
> phpSpreadSheet の環境構築とよく参考にするサイト
> https://qiita.com/hamburg-love/items/e008ba55770a0820f380
OracleLinuxにphpMyAdminをインストールした時にちょいハマりしたこと

# はじめに
OracleLinux9.1の環境にnginxを入れてphpMyAdminをセットアップしようとした時に少しハマったので備忘メモです。

# インストール
インストールはRemiリポジトリからphp関連のモジュールと一緒にインストールしました。
### Remiリポジトリを有効にする。
```
# wget http://rpms.famillecollet.com/enterprise/remi-release-9.1.rpm
# rpm -ivh remi-release-9.1.rpm 
# yum --enablerepo=remi install mysql-server php-mysql phpmyadmin
```
### phpMyAdminとPHPモジュール関連のインストール
PHP本体は別にインストール済だったので関連モジュールのみ追加しています。
```
# yum install -y --enablerepo=remi phpMyAdmin php-mbstring php-intl php php-mysqlnd
```

# config.inc.phpの場所
phpMyAdminのドキュメントに書いてあるのですが、インストールする環境によってはconfig.inc.phpは/etc/phpMyAdminの下に配置されるとあり、OracleLinuxの場合もそこへ配置されました。

その他、
phpMyAdminのプログラム本体は、/usr/share/phpMyAdmin
キャッシュやテンポラリファイルは、/var/lib/phpMyAdmin
に配置されました。

で、このphpMyAdminへ配置されるのがちょっと自分的に嫌で全部小文字にしたいと思い上記ディレクトリをphpMyAdmin → phpmyadminへ修正した後、/etc/phpMyAdmin/config.inc.phpの以下の項目を編集して小文字のディレクトリへ対応させるべく、以下のように設定ファイルを記述しました。

```/etc/phpMyAdmin/config.inc.php
～～～ 中略 ～～～
$cfg['UploadDir'] = '/var/lib/phpmyadmin/upload';
$cfg['SaveDir'] = '/var/lib/phpmyadmin/save';
$cfg['TempDir'] = '/var/lib/phpmyadmin/temp';
～～～ 中略 ～～～
```

nginxの設定も小文字ディレクトリを読んでくれるように以下のように変更しています。
```/etc/nginx/conf.d/phpmyadmin.conf
server {
       listen 80;
       server_name  192.168.0.100; 

       location /phpmyadmin {
                root /usr/share;
                index index.php; 
       }

       location ~ \.php$ {
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /usr/share/$fastcgi_script_name;
                include fastcgi_params;
       }
}
```

変更した後は念のためnginxとphp-fpmを再起動しました。
```
# systemctl restart nginx php-fpm
```

しかし、読み込むディレクトリは変わってくれず404等のエラーが出てしまいます。

調べた結果、

/etc/phpMyAdmin
/etc/phpMyAdmin/config.inc.php

これらのディレクトリやファイルのオーナーグループがroot.apacheなどになっており、この辺をすべてroot.nginxへ変更することで/etc/phpMyAdmin/config.inc.phpを読んでくれるようになりました。
気づくとしょーもないことです・・orz

```
# chown root.nginx /etc/phpMyAdmin
# chown root.nginx /etc/phpMyAdmin/config.inc.php
```

先に書いた/var/lib/phpmyadminや/usr/share/phpmyadminとその下のディレクトリやファイルも同じようにroot.nginxになっている必要がありますのでなっていない場合は変更します。
```
# chown -R root.nginx /var/lib/phpmyadmin ←ディレクトリ名を変更していない場合はphpMyAdmin
# chown -R root.nginx /usr/share/phpmyadmin ←ディレクトリ名を変更していない場合はphpMyAdmin
```

最初はどこか別の場所にconfig.inc.phpがあってそちらを読んでいるのかと探して見つからず、いろいろしているうちに初歩的なところを見逃してしまってました。

configファイルが読み込めない場合はデフォルトで上に書いた/var/lib/phpMyAdmin等を見に行くようになっているみたいでどこかに書いてあるのかとファイルを検索してみたり・・・。

/etc/phpMyAdminディレクトリ自体を変えられないかはまだ調べていないのですがこれも暗黙に見にいっているようなのでどこで決めているかはまた別に調べたいと思います。

久々に入れたんですがconfig.sample.inc.phpも見つからなくて地味に色々時間がかかってしまいました・・・。
プリザンターで左上のパンくずリストを任意の文字列・URLに変更したい

# はじめに
プリザンターでは、サイトやテーブルを開くと画面左上にパンくずリストが表示されます。今回、このパンくずリストを任意の文字列を表示し、任意のURLを設定してみます。

# ソースコード
## スクリプト1
```JavaScript
// 新規作成・編集画面にてパンくずリストのHTMLを上書き
$p.events.on_editor_load = function () {
    $('<ul id="Breadcrumb"><li class="item"><a href="https://www.google.com/">Google</a><span class="separator">></span><li class="item"><a href="https://www.yahoo.co.jp/">Yahoo</a><span class="separator">></span>').replaceAll('#Breadcrumb')
}
```
## スクリプト2
```JavaScript
// 一覧画面にてパンくずリストのHTMLを上書き
$p.events.on_grid_load = function () {
    $('<ul id="Breadcrumb"><li class="item"><a href="https://www.google.com/">Google</a><span class="separator">></span><li class="item"><a href="https://www.yahoo.co.jp/">Yahoo</a><span class="separator">></span>').replaceAll('#Breadcrumb')
}
```

# さいごに
実際にパンくずリストのHTMLを上書きするのはfunctionの中身です。「スクリプト1」は新規作成画面や編集画面でリロードするとデフォルトのパンくずリストに戻ってしまう事象を回避するため、「$p.events.on_editor_load」を使っています。同じく「スクリプト2」では一覧画面で画面更新をするとデフォルトのパンくずリストに戻ってしまう事象を回避するため。「$p.events.on_grid_load」を使っています。
Djangoスタートアップ その15(HTTPS化編)

# 実行環境
- EC2
- Nginx
- gunicorn
- Django
- ubuntu

# 導入手順
## Certbotインストール
```:bash
sudo apt install certbot
```

## Nginxを停止
```:bash
sudo systemctl stop nginx
```
👆をしないと、certbotで証明書を発行するときエラーになる

## HTTPSポート(443ポート)開放
EC2 > セキュリティ > インスタンスの詳細 > インバウンドルール > 443ポートを開放

## SSL証明書発行(Let's Encrypt)
```:bash
certbot certonly --standalone -d （HTTPS化したいドメイン名）
```

以下のファイルが生成される
- /etc/letsencrypt/live/（HTTPS化したいドメイン名）/fullchain.pem;
- /etc/letsencrypt/live/（HTTPS化したいドメイン名）/privkey.pem;

## Nginxの設定
```:etc/nginx/sites-available/(プロジェクト名)
server {
    listen 80;
    server_name ドメイン名;
    return 301 https://$host$request_uri;#リダイレクト指定
}


server {
        listen 443 ssl;
        server_name (ドメイン名);

ssl_certificate /etc/letsencrypt/live/(ドメイン名)/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/(ドメイン名)/privkey.pem;

# このパートには関係のない設定が描かれている
}
```

## Nginxを再起動
```:bash
sudo systemctl restart nginx
```

----
参考記事
https://yuki-yamashita.site/blog/post/https-letsencrypt/
【Blender × ChatGPT】Blenderで使えるアドオン「BlenderGPT」を使ってみた

## 概要
最近、プロンプト(指示)を入力するだけで操作することができるBlenderのアドオン「BlenderGPT」というものを見つけました！

Blenderはよく分からなくて苦手…という方だったり、Blender初心者の方にはとても便利なツールになっていると思います。

なので、今回はこの「BlenderGPT」をBlenderに導入して使う方法について紹介しようと思います！

## 参考記事
下記のサイトを参考にさせていただきました、ありがとうございます！
- [BlenderGPT](https://github.com/gd3kr/BlenderGPT)
- [「BlenderGPT」アドオンの導入方法をやさしく解説！](https://saru-blender.com/blendergpt)
- [3DCG製作ソフトのBlenderにGPT-4を統合し「球体を作って」などのプロンプトを入力するだけで3Dモデルを作成するアドオン「BlenderGPT」レビュー
](https://gigazine.net/news/20230329-blendergpt/)

## 環境
- Blender ver3.2.0
- OpenAIのAPIキー用意済み

## 使用例
※ GITの画質の関係で見にくいですがご了承ください(´･ω･｀)
原点に三角錐を生成 -> その三角錐をランダムな方向・スケールで配置するようにプロンプトを記載しています。
![画面収録-2023-04-27-14.49.03_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/f138b1fb-c7b4-056d-9ec1-32f204a61d01.gif)


## 手順
### 1. BlenderGPTをダウンロードする
- [こちら](https://github.com/gd3kr/BlenderGPT)のページにアクセスして、`Code > Download ZIP` からZIPファイルをダウンロードする。
![スクリーンショット 2023-04-27 14.10.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/99208ef5-4ae9-4a0d-bf30-f377f3250b61.png)

### 2. OpenAIのAPIキーを取得する
- このアドオンを使用する際、OpenAIのAPIキーが必要となります。
- OpenAIへの登録・APIキーの取得方法については、[前回の記事](https://qiita.com/uebo_tongull/items/02c857af9d87ee7d2cb6#1-openai%E3%81%AB%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B)に手順を記載していますので、こちらを参考にしてください。

### 3. Blenderにアドオンを追加する
- Blenderを開き、`編集 > プリファレンス`を選択する。
 ![スクリーンショット 2023-04-27 14.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/2f3eadfd-1dd0-9ee9-1bed-749ca47be30c.png)

- プリファレンス画面が開いたら、左の欄から`アドオン > インストール…`を選択する。
 ![スクリーンショット 2023-04-27 14.17.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/04283c8b-68db-8d66-1fbb-c6a43627067e.png)

- 1の手順でダウンロードしてきたzipを選択して、`アドオンをインストール`を選択する。
 ![スクリーンショット 2023-04-27 14.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/3d70c7b2-d9b0-d54a-8d1b-90d54efca441.png)

- インストールできると、`Object:GPT4 Blender Assistant`というアドオンが追加されているので、左側のチェックを入れる。
 ![スクリーンショット 2023-04-27 14.26.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/b5642b63-a1b5-ce0d-a6c2-851fc3d7f3e5.png)

- アドオンの▼をクリックすると中にAPIキーを入力する欄があるので、そこに2で取得したAPIキーをコピペする。
 ![スクリーンショット 2023-04-27 14.26.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/c5b466bf-d833-43ce-c4c6-a706f13ab414.png)

### 4. BlenderGPTアドオンを使ってみる
- 画面上でNキーを押すとサイドバーが開くので、そこに「GPT-4 Assintant」が追加されているので開く。
- `GPT Model`のところは、今回`GPT 3.5` を使用するので変更しています。
 ![スクリーンショット 2023-04-27 14.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/034de0f3-5413-6458-a1a8-c4a88585fd97.png)

- あとは、`Enter your message:`にプロンプトを入力し、`Execute`をクリックすればOKです！
[Rails] pagyのデザインを整える

備忘録の記事です。
pagyによるページネーションを実装したのですが、デザインがそのままだと微妙なので整えてみました。
```movies/index.html
<%== pagy_bootstrap_nav(@pagy) %>
```

# Before

![cd9e629283cd54b9a23995bd342308fd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962714/0bd8e3ea-c96b-7755-78a3-b3b0e3d40988.png)

bootstrapをつけただけだと、なんだか物足りない印象です。これにもう少し手を加えてみます。

```app/assets/stylesheets/application.css
//ページネーション自体のデザイン
.pagination>li>a {          
  border: none;     //枠線をなくす
  color: #696969;   //文字の色を変える
  border-radius: 15px;
}
.page-item.active
.page-link {
  z-index: 3;
  background-color: #3aabd2;
}
//ホバー時のデザイン
.pagination>li>a:hover {
  color: #035c7c;
}
.page-item:first-child .page-link {
  border-top-left-radius: 15px;
  border-bottom-left-radius: 15px;
}
.page-item:last-child .page-link {
  border-top-right-radius: 15px;
  border-bottom-right-radius: 15px;
}
```

# After
![f77167cde3991916ddc813421e294da5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962714/b7693f97-7d7a-3004-6f5e-65de82c454e1.png)

今風のデザインになりました。

参考：

https://qiita.com/iwkmsy9618/items/5c8b56cb7faf6c024f4e

https://qiita.com/rio_threehouse/items/313824b90a31268b0074
java初心者がいく～カプセル化～

# はじめに
java初心者が議事録的に書いています

# カプセル化とは
カプセル化とは簡単に言うと変更してほしくない変数に対してアクセスを制限することを言う。
カプセル化することで想定外な不具合を防ぐことができるらしい。
カプセル化の方法としては、変数やメソッドの前にprivateやpublicをつければよい。
ほかにもいろいろ（private, package private, protected, public）あるが基本的には

フィールドはすべてprivate
メソッドはすべてpublic

とするのが定石らしい。

書き方の例としては以下のようである。

```java
public class Sample {
	private int num = 1;
}
```

こうすることで以下のようにnumへアクセスしてもエラーとなる。

```java
public class Main {

	public static void main(String[] args) {
		Product pro = new Product();
        
		pro.num = 2;//だめ（後のgetterで解決）
        System.out.println(pro.num);//だめ（後のsetterで解決）
	}
}
```
ではnumを外部から読み書きしたい場合はどうしたらよいのか。
ここで出てくるのがgetterとsetterである。

# getterとsetter
今回のnumはprivateで外部からアクセスできなくなっているが、同じクラス内のpublicメソッドを経由すればアクセスできる。これを踏まえてsetterとgetterを書いてみる。

まずはsetterである。
setterは名前の通り「セットするもの（初期化する）」である。
書き方としては以下の通りである。

```java
public class Sample {
	private int num = 1;

    public int setnum(int a){//初期化している
        this.num = a
    }
}
```
あとはMainクラス内で以下のように書けば間接的にnumへアクセスできるようになる。

```java
public class Main {

	public static void main(String[] args) {
    		Product pro = new Product();
            pro.setnum(2);//この一文によりnumは2に初期化される。pro.num = 2;はだめ。
	}
}
```
以上でnumは2に初期化される。

次にgetterについて。
getterは名前の通り、「取得」するためのものである。
書き方としては以下の通りである。

```java
public class Sample {
	private int num = 1;

    public int getnum(){//numを取得
        return this.num;
    }
}
```
あとはMainクラス内で以下のように書けば間接的にnumへアクセスできるようになる。

```java
public class Main {

	public static void main(String[] args) {
		Product pro = new Product();
        System.out.println(pro.getnum());
        //実行結果は1
	}
}
```

setterとgetterの書き方はこんな感じである。

# 終わりに
なかなか自分の考えを文章にするのが難しいですね。（うまくかけた自信がないです、、）
ほかの良い書き方、表現方法がありましたら是非コメントよろしくお願いします。