OmniAICreator/Qiita-1.07M huggingface dataset:
(java gold) Collectorsクラス

# Collectorsについて
下記APIリファレンスより
>要素をコレクションに蓄積したり、さまざまな条件に従って要素を要約するなど、有用な各種リダクション操作を実装したCollector実装。

# 主なメソッド

* 集約

| メソッド名 | 概要 |
|:--|:--|
|toList()|要素をリストに集約する|
|toSet() |要素をセットに集約する|
|toMap()|キーと値のペアに要素を集約する|

* グループ化

| メソッド名 | 概要 |
|:--|:--|
|groupingBy()|指定したキーで要素をグループ化する|
|partitioningBy()|指定した条件に基づいて要素をパーティション分割する|

* 変換

| メソッド名 | 概要 |
|:--|:--|
|mapping() | 要素を指定した関数によって変換する|
|reducing()|要素をリダクション（まとめる）操作によって変換する|

* 統計

| メソッド名 | 概要 |
|:--|:--|
|summarizingXxx()|指定した数値型の統計情報を収集|
|averagingXxx()|指定した数値型の平均値を計算|

* 合計

| メソッド名 | 概要 |
|:--|:--|
|summingXxx()|指定した数値型の要素を合計する|

例
```java
public class Sample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        // リストの要素を合計する
        int sum = numbers.stream()
                         .collect(Collectors.summingInt(Integer::intValue));
        System.out.println("Sum: " + sum);
    
        // リストの要素を文字列に連結する
        String concatenated = numbers.stream()
                                      .map(Object::toString)
                                      .collect(Collectors.joining(", "));
        System.out.println("Concatenated: " + concatenated);    
    }
}
```
(java gold) flatmap

## flatmap
Optionalオブジェクトが値を保持している場合に、その値を別のOptionalオブジェクトに変換するためのメソッドである。変換されたOptionalオブジェクトが返される。

flatMap()メソッドは、以下のようなシグネチャを持っている。

```java
<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
```


# mapとflatmapの比較

### 戻り値の比較

* map（）メソッドはOptionaal<U>であり変換操作によって得られた値を新しいOptionalオブジェクトとして戻す。
* flatmap()メソッドは値の変換操作によって得られたOptionalオブジェクトを自動的に解消しフラットなOptional<U>を戻す。

## 使い分け
### map()メソッド：
* 単純な値の変換を行いたい場合
* 変換操作自体をスキップせずに実行したい場合
### flatMap()メソッド
* 値の変換によってネストしたOptionalオブジェクトを解消したい場合
素数以外の mod


[この記事のオリジナル](https://yamate11.github.io/blog/posts/2023/03-12-mod-not-prime/) は，2023年3月12日に公開されました．

文脈は，競技プログラミングです．剰余を扱う mod ライブラリで素数以外の法に関してできることを書きます．

## 制限なくできること

* 加算
* 減算
* 乗算

これらは，単に整数として演算した後に法で割って余りを求める (あるいはそれと同値なことをする) だけだから，できる．

## 除算

$\bmod M$ における $a/b$ というのは，「$b$ にかけたら $a$ になる数」である．

#### できる場合

$(b, M) = 1$ ならば，一意に存在する．
* (存在)$\quad$ $bu + Mv = 1$ となる $u, v$ がとれるので，$x = au$ とすればよい．
* (一意性)$\quad$ $bx \equiv bx' \equiv a$ ならば，$b(x - x') \equiv 0$ だから，$x \equiv x'$となる．

特に $M$ が素数ならば，$b\not\equiv 0 \pmod M$ のとき，一意に存在する．

#### できない場合

$(b, M) \neq 1$ のときは，存在しないかもしれないし，複数あるかもしれない．

> 例
> 
> * $2x \equiv 3 \pmod 4$ となる $x$ は存在しない．
> * $2x \equiv 2 \pmod 4$ となる $x$ は，
>   $x = 1$, $x = 3$ の2つがある．

[自作の mod ライブラリ](https://github.com/yamate11/compprog-clib/blob/master/mod.cc) では，$(b, M) \neq 1$ の時に $a/b$ を実行すると，実行時エラーになる．
  
## 割り切れる除算

$a/b$ が整数になるとわかっている場合，$a/b \bmod M$ を求めるのに，$r := a\bmod bM$ を求めるという方法がある．$a = bMu + r$ とすると，$a/b = Mu + r/b$ であるから，$r/b$ は整数になるはずなので，普通に整数で割り算をすれば良い．$bM$ が大きな数になる可能性があって，int128 などが必要になるかもしれない．

たとえば，初項 $a$，公比 $a$，項数 $x$ の等比数列の和を，$\text{mod } M$ で求めたいとする．$r - 1$ と $M$ が互いに素でないとすると，和 $a(r^x - 1)/(r - 1)$ を求めるのに，$\text{mod } M$ で $a(r^x - 1)$ を $r - 1$ で割るというわけにはいかない．そこで，$a(r^x - 1)$ を $\text{mod } (r-1)M$ で求める．この値は当然 $r - 1$ の倍数になるので，$r - 1$ で割って，求める値が得られる．

例題: [ABC293-E](https://atcoder.jp/contests/abc293/tasks/abc293_e) ([この方法による解説](https://atcoder.jp/contests/abc293/editorial/5966))
(java gold) インターフェース

## インターフェース


### staticメソッド
  * 実装を持つstaticメソッド
  * オーバーロード不可(継承されない)
### デフォルトメソッド
  * defaultキーワードを持つ実装メソッド
    * インターフェースメソッドがオーバーライドされない場合の実装を提供
  * デフォルトメソッドの解決ルール
    * スーパークラス>インターフェース
    (あくまでインターフェースは型を提供している)
    * サブタイプ>スーパータイプ
    * 競合したら実装クラスでオーバーライド

### プライベートメソッド
  * privateな実装メソッド 
    * インターフェース内からのみ呼び出せる
    　＝デフォルトメソッドから呼び出せる
(java gold) enum

# enum(イーナム)の宣言
### 構文
```java
enum EnumName {
    CONSTANT1,
    CONSTANT2,
    // ...
}
```
* `enum` :列挙型の宣言
* `EnumName` :列挙型の名前
* `CONSTANT1` ：列挙型の定数。定数は大文字で記述されカンマ区切り、特定の値を持つ

* enumは外部からインスタンス化できない(定数として使える)
#### switch文で使用可能
* caseは定数で指定する下記コードでは(R,G,B)
``` java
public class Test {
    public static void main(String... args) {
        new Test().check(GRADE.A);
    }
    void check(GRADE grade) {
        switch (grade) {
            case A:
                System.out.println("Best"); break;
            default: System.out.println("Not best");
        }
    }
}
enum GRADE {
    A(100), B(75), C(50);
    int score;
    private GRADE(int score) { this.score = score; }
}
```

* == 演算子で比較可能
#### enumのメソッド
* name()
* `valueOf()` : 指定された名前のEnumを取得する
* `values()` : Enumの全定数を取得する


* EnumクラスのvaluesメソッドはそのEnumに定義されている列挙子を配列に入れて返却する。
* EnumクラスのvalueOfメソッドはStringの引数を渡し、そのインスタンスを返却する。



## enumに固有の値を持たせる方法

```java
enum Color implements Serializable {
    R(255), G(204), B(0);
    int code;
    private Color(int code) {
        this.code = code;
    }
    public int getCode() {
        return code;
    }
}
```
### enumの呼び出し
```java
System.out.println(Color.G.getCode()); 
// 204 が出力される
```

## フィールドやメソッドの定義が可能

* `enum` は`java.lang.Enum`クラスを継承しているのでEnumクラスの一部のメソッドを使用できる

:::note warn
JavaのEnumにおいて、コンストラクタのアクセス修飾子はprivateである必要がある。
:::
(java gold) クラス

## 内部クラス(インナークラス)

* エンクロージングインスタンスのprivateフィールドにアクセス可能
* ネストしたクラスにはインナークラス、staticインナークラス、ローカルクラス、匿名クラスがある。
* ローカルクラスは、メソッド内で定義されるクラスのことで、abstract, finalで修飾できる。
* 匿名クラスはあらゆる修飾子を使用することはできない。
* インナークラスのインスタンスを生成するには、エンクロージングクラスのインスタンスを先に生成する必要がある。
```java　
 new Outer().new Inner()
```
* staticインナークラスはエンクロージングクラスのインスタンス化は不要。
```java
new Inner(), new Comparator()など
```
* ローカルクラスから参照するローカル変数は、ローカルクラスよりもあとにローカル変数を宣言すると`コンパイルエラー`。また、その時のローカル変数は実質的にfanalでなければならない。（値を変更しようとすると`コンパイルエラー`）
* 匿名クラスには名前がないため、コンストラクタは定義できない(`コンパイルエラー`)
* 匿名クラスを 初期化したいときは初期化子{}を使う
* クラスやインターフェースで定義したstaticメソッドはオーバライドできない。@Overrideアノテーションを付けたりすると`コンパイルエラー`
* スーパークラスとインターフェースが同一のシグニチャのメソッドを持っている場合、スーパークラスのメソッドが優先される。

### 内部クラスのインスタンス化
```java
Inner inner = new Outer().new Inner();
```

## 静的クラス(staticクラスの内部クラス)
* エンクロージングクラスのprivate staticなフィールドにアクセス
* エンクロージングクラスの非staticなフィールドやメソッドにはアクセスができない

### 静的クラスのインスタンス化
```java
InnerStatic inner = new Outer.InnerStatic();
```

## 無名(匿名)クラス
* 名前を持たないクラス通常のクラスと異なり定義と同時にインスタンス化される
* 実装するクラスやインターフェースをnewするコード実装を記述する
* 明示的なコンストラクタは持たない(定義できない)
* コンストラクタの代わりに初期化子「{}」を使用することができる。
* extends節やimplements節はつかえない
* メソッドのオーバーライドはOK
```java
public class OuterAnonymous {
    public void printMessage(int type, String content) {
        new Object() {
            PrintStream getOutput() {
                return type == 0 ? System.out : System.err;
            }
        }.getOutput().print(content);
    }
}
```
(java gold) コレクションとジェネリクス


## ジェネリクス
* ワイルドカード型<?>...総称型パラメータの変性を変更する仕組み
  * ?...非境界ワイルドカード型(型が...不明なのでgetした要素の型はObject型)
  * ? extends T ... 上限境界ワイルドカード型(少なくてもTのサブクラス: 共変)
  * ? super T ... 下限境界ワイルドカード型(少なくてもTのスーパークラス: 反変)
    * 読み込みには上限境界ワイルドカード型、書き込み時には下限境界ワイルドカード型を使う

```java
// Point: Java のコレクションは非変なので List<Object> と
// List<Integer> には親子関係がないものとみなす。
// (配列の場合は共変なので代入可)つまり、
List<Integer> li = Arrays.asList(1, 2);
List<Object> lo = li; // NG
//となるが、総称型パラメータにワイルドカード型を使うことで
//制約を変更可能
Lust<?> lw = li; // OK
```

## 命名慣習

| 記号 | 概要 |
|:-:|:-:|
E|要素（Element）
K|キー（Key）
T|型（Type）
V|値（Value）
N|数値（Number）
R|戻り値型(Return)
S, U, V|２番目、3番目、４番目…
(java gold) ストリームAPI　中間操作・終端操作

## 中間操作
取り出したストリームの要素に加える処理のこと。フィルタリング、ソートなどの操作がある。
中間操作は、新しいストリームを返し、元のストリームは変更されない。これにより、パイプライン処理を実現し、効率的なデータ操作を行うことができる。

### 中間操作の例

* `distinct()` : ストリーム内の重複した要素を削除する。重複した要素があるときは最初の要素のみが新しいストリームに含まれる
* `filter(Predicate<T> predicate)` : 指定された条件に基づいて要素をフィルタリングする。条件に合致する要素だけ新しいストリームに含まれる
* `map(Function<T, R> mapper)` : 要素を指定された関数によって変換する。各要素は関数によって変換され変換後に新しいストリームが生成される
* `sorted()` : 要素をデフォルトの順序(自然順序)でソートする。要素がcomparebleインターフェースを実装している場合その順序によってソートされる
* `sorted(Comparator<? super T> comparater)` : ストリームの要素を指定されたComparatorに従ってソートした結果から構成されるストリーム
* `peek(Consumer<? super T>)` : 最終結果を出す前の途中経過を表示できる。デバックやログ出力、要素の状態観察や変更をする場合に使用される。
* `limit(long maxSize)` : ストリームの要素をmaxSize以内の長さに切り詰めた結果から成るストリームを生成
* `skip(long n)` : ストリームの最初のn個までの要素を破棄し、残りの要素で構成されるストリームを生成

## 終端操作の概要
中間操作を終えたストリームの集合に対して行う最終処理

### 終端操作の例

* `forEach(Consumer<T> action)` : ストリームの各要素に対して指定されたアクションを実行する。Consumer型の引数を受け取るため、要素を単純に処理するだけで、戻り値は戻さない。ストリーム内の要素を`コレクションが保持している順`に処理する
* `collect(collect<T,A,R> collector)` : ストリームの要素を収集して、新しいコレクションや値を生成する。Collectorオブジェクトを使用して要素をまとめる方法や結果を生成する方法を指定する
* `count()` : ストーリー無の要素の数を数える。長さや要素の個数を数える
* `reducu(BinaryOperator<T>, accumulator)` : ストリームの要素を結合し、単一の結果を生成する。要素を繰り返し結合するための累積関数を指定する
* `finfAny()` : ストリームから任意の要素を取得する。並列処理の際には、`常に同じ要素を返す保証はない`
* `findfirst()' : ストリームの最初の要素を取得する。並列処理の際には、処理の順序によって`常に最初の要素が返される`

### リダクション操作
リダクションとは一連の要素を1つにまとめる操作、もしくはリストの要素に何らかの処理を加え、その結果を別のリストにまとめる操作のこと。

* reduceメソッド：値を累積的に結合していく関数を実行する
* min()：最小値を求める
* max()：最大値を求める
 
:::note alert
終端操作のメソッドは1回しか呼び出すことができない。2回呼び出そうとすると、illegalStateExceptionがスローされる。
:::
(java Gold) Map

## Map
* Mapはkeyとvalueをセットにしたもの
* インデックスの代わりに任意の変数を要素の値のペアにできる`keyは重複なしである必要がある`がvalueは同じものが複数あっても大丈夫
* HashMapは格納順が管理されないが、TreeMapは順番がキーになっている
* HashMapはkeyとvalueにnullを使用することが可能だがTreeMapは使用できない
* Mapは以下のクラスで実装されています
1. `HashMap`: キーと値の組からなる要素の集合を扱い、キー名が重複する場合は上書きされます
2. `LinkedHashMap` : キーと値の組からなる要素の集合を扱います。設定順序が保証されます
3. `TreeMap`:キーと値の組からなる要素の集合を扱います。キーでソートされています


### 値の取得
* 値の取得にはMapでkeyを指定しgetメソッドを使用

## Mapのメソッド
### 追加
| メソッド名 | 概要 |
|:--|:--|
|`map.put(key, value)` | key-value を設定する

### 削除
| メソッド名 | 概要 |
|:--|:--|
|`map.remove(key)` | key の要素を削除する|
| `map.clear()` | すべての要素を削除する  |


### 取得
| 1 | 2 |
|:-:|:-:|
| `map.get(key)` | key に対応する value を得る |




### 要素数
| メソッド名 | 概要 |
|:--|:--|
|`map.size()` | 要素の個数を得る|
(java gold) 例外とアサーション

## try-with-resouces(JavaSE 7~)
* try句で宣言したリソースは自動でクローズされる
  * リソースはAutoCloseableである必要がある
    * I/Oストリーム,StreamAPI,JDBC API(Connection, Statement)
  * リソースは実質的にfinalも指定可能
* リソースをクローズするタイミング
  * finally句の処理前
  * 複数リソースの場合はオープンしたときの逆順でクローズ
:::note 
実質的 final で思い出したいもの
• try-with-resources (Java SE 9)
• 無名クラス (Java SE 8)
• ラムダ式 (Java SE 8)
:::
:::note alert
これらのコードからアクセス可能な変数は実質的
final である必要がある。(実質的 final でなければ
コンパイルエラーになる)
:::



```java
class MyResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("MyResource#closed()");
    }
}
```

:::note alert
java.io.Closeable インタフェース (AutoCloseable のサブタイプ)
を実装する場合、オーバーライドするメソッドは
```java
public void close() throws IOException { }
```

:::

## アサーション
* 処理中で成立すべき条件を検証し条件違反を自動で検知する仕組み
* アサーションの構文
```java
assert exp1;
assert exp1 : exp2;

exp1 ... 検証されるべき条件
exp2 ... 検証エラー時のメッセージ
(AssertionErrorのコンストラクタ引数)
```
*アサーションの有効化
```java
$ java –ea Test
```
Javaで「演算子の優先順位と結合規則」の動作を確認してみた

# 概要

Javaで「演算子の優先順位と結合規則」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/ope/index4.html

# 実装

以下のファイルを作成しました。
```JSample4_1.java
class JSample4_1{
  public static void main(String[] args){
    int n1 = 10 * 5 + 4;
    int n2 = 4 + 10 * 5;

    System.out.println("10 * 5 + 4 = " + n1);
    System.out.println("4 + 10 * 5 = " + n2);
  }
}
```
```JSample4_2.java
class JSample4_2{
  public static void main(String[] args){
    int n = 10 - 5 - 3;;

    System.out.println("10 - 5 - 3 = " + n);
  }
}
```
```JSample4_3.java
class JSample4_3{
  public static void main(String[] args){
    int n1 = 10 + 8 / 2 * 4;
    int n2 = (10 + 8 / 2) * 4;
    int n3 = ((10 + 8) / 2) * 4;

    System.out.println("10 + 8 / 2 * 4 = " + n1);
    System.out.println("(10 + 8 / 2) * 4 = " + n2);
    System.out.println("((10 + 8) / 2) * 4 = " + n3);
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample4_1.java 
$ java JSample4_1 
10 * 5 + 4 = 54
4 + 10 * 5 = 54
```
```
$ javac JSample4_2.java 
$ java JSample4_2 
10 - 5 - 3 = 2
```
```
$ javac JSample4_3.java 
$ java JSample4_3 
10 + 8 / 2 * 4 = 26
(10 + 8 / 2) * 4 = 56
((10 + 8) / 2) * 4 = 36
```

# まとめ

何かの役に立てばと。
GomailとMailCatcherを使ってメール送信機能を実装しよう！

## 概要
GomailとMailCatcherのコンテナを使ってローカル上でメール送信機能を使用する方法について解説していきたいと思います

## 前提
- フレームワークはGinを使用
- 本記事はローカル環境でメール送信機能を試す方法について記載していますので本番環境では別のツールを使用してください
- docker-compose.ymlを使ってMailCatcherを構築します

## ディレクトリ構成
```
tree
.
├── .env
├── .gitignore
├── Makefile
├── README.md
├── application
│   ├── .air.toml
│   ├── controllers.go
│   ├── emails.go
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   └── routes.go
├── containers
│   ├── go
│   │   └── Dockerfile
│   └── postgres
│       └── Dockerfile
└── docker-compose.yml
```

## MailCatcherとは
> MailCatcher runs a super simple SMTP server which catches any message sent to it to display in a web interface. 

公式ドキュメントに記載されている通り簡易的なSMTPサーバでMailCatcherに送信されたメールをWebインターフェイス(Webブラウザ)に表示させることができます
本番環境ではAWSのSESを使うのでローカルでメール送信テストを行いたいときはMailCatcherを使ってみましょう

> Run mailcatcher, set your favourite app to deliver to smtp://127.0.0.1:1025 instead of your default SMTP server, then check out http://127.0.0.1:1080 to see the mail that's arrived so far.

公式ドキュメントに記載されている通り
MailCatcherのイメージを指定して
- SMTP用の1025番ポート
- Webブラウザで閲覧する用の1080番ポート
 
の2種類のポートを解放します

```docker-compose.yml
  mail:
    container_name: mail
    image: schickling/mailcatcher
    ports:
      - '1080:1080'
      - '1025:1025'
```

## 環境変数の設定
今回は送信元を`example@co.jp`に設定します
MAIL_HOSTはMailCatcherのコンテナのホスト名、MAIL_PORTはSMTP用の1025番ポートを指定します
```.env
MAIL_ADMIN="example@co.jp"
MAIL_HOST=mail
MAIL_PORT=1025

```

## メール送信APIの作成
今回はメール本文にようこそ！と書かれたメールを送信するAPIを作成します

```routes.go
package routes

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

func GetUserRoutes(router *gin.Engine) *gin.Engine {
	userRoutes := router.Group("/api/admin/users")
	{
		userRoutes.POST("/send_invite_user_email", func(c *gin.Context) {
			controllers.SendInviteUserEmail(c)
		})
	}
	return router
}

```

```controllers.go
package controllers

import (
	"github.com/gin-gonic/gin"
	"github.com/shun198/gin-crm/emails"
)

func SendInviteUserEmail(c *gin.Context) {
	emails.SendEmail()
}

```

Gomailを使用するのでimportします
以下のようにメール送信に必要な環境変数を.envから取得するよう設定します

```emails.go
package emails

import (
	"os"
	"strconv"

	"gopkg.in/gomail.v2"
)

func SendEmail() {
	m := gomail.NewMessage()
	m.SetHeader("From", os.Getenv("MAIL_ADMIN"))
	m.SetHeader("To", "to@example.com")
	m.SetHeader("Subject", "ようこそ")
	m.SetBody("text/html", "ようこそ!")
	m.AddAlternative("text/plain", "ようこそ!")

	host := os.Getenv("MAIL_HOST")
	port, _ := strconv.Atoi(os.Getenv("MAIL_PORT"))
	username := os.Getenv("MAIL_USERNAME")
	password := os.Getenv("MAIL_PASSWORD")

	d := gomail.NewDialer(host, port, username, password)
	if err := d.DialAndSend(m); err != nil {
		panic(err)
	}
}

```

## 実際に実行してみよう！
MailCatcherのコンテナを起動後、APIを実行し、メールを送信することに成功したら成功です
![スクリーンショット 2024-05-26 13.02.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/373f6cf6-9b7c-7ae8-f5a3-4d7d975fb3b4.png)

127.0.0.1:1080にアクセスするとメールの中身を確認することができます
![スクリーンショット 2024-05-26 9.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/2460054d-a5f6-4077-e741-e4032bb6c790.png)

## 参考
https://github.com/go-gomail/gomail
【ChatGPT＋DALL-E3】アップロードファイルについて。


　どうも、カーブミラーです。

　今回は、アップロードファイルについて、です。たまたま気付きました。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　本題です。

　ChatGPTでは
　　ファイルのアップロードが
　　　行なえます。

　ところが、
　　今回たまたまなのですが、
　　　このファイルの
　　　　名前を変えたところ、
　　　　　セッションから
　　　　　　参照できなくなって
　　　　　　　枠だけ表示される
　　　　　　　　という現象が
　　　　　　　　　ありました。

　つまり、
　　セッション内容として
　　　ファイル内容は
　　　　履歴に残らないのです。

　ファイル名を
　　もとに戻したら、
　　　参照できるようになり、
　　　　セッションに表示されました。

　念のために
　　ChatGPTにも
　　　尋ねました。
***
***user***
アップロードした画像がストレージから削除されたら、どうなりますか？

***ChatGPT***
アップロードした画像がストレージから削除された場合、その画像はもうアクセスすることができなくなります。画像が存在しなくなるため、それに基づいた再生成や参照も行うことができません。また、削除された画像に関連する情報やデータもアクセスできなくなるので、必要な場合は事前にバックアップを取ることが重要です。
***
　とのこと。

　ご注意くださいね。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
自作分割キーボード初挑戦【QMKToolboxのエラー対処・完成編】

## 前回の話
https://qiita.com/Sugimoto_Yuuki/items/7eb971199f91dbcd30fe

## 完成したキーボード
ついに完成しました！！！  
前回からキーキャップを少し変え、Majestouchのキーキャップを使っています。今もこのキーボードを使って記事を書いていますが打鍵感も希望通りで最高:sob:

![20240526_113605.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/fbc8c5eb-026b-0324-c4a9-3d844987cce3.jpeg)

## 前回の記事の後になにをしたか
キーボードの基盤などを買い換えました。前回と同じように組み立て、ファームウェアを書き込み、テストするところまで行きました。で、テストをしたのですがまたしても一切反応しない・・・なぜだ・・・  
ということでいろいろ試行錯誤する中で、QMK Toolboxにのエラーを無視していたのを思い出しました。画像をとってなかったのですが、エラー文は下記です。（USBケーブルの問題？）
``` 
Atmel DFU device has NO DRIVER driver assigned but should be WinUSB. Flashing may not succeed.
```
「フラッシュが成功しないかもね」くらいの感覚で読んでいて、無視して実行した場合はFlashが成功したような文面を出力していました。が、今回はここを疑いQMLToolboxの[github](https://github.com/qmk/qmk_toolbox)にしっかり目を通しました。そこで下記を見つけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/d245a708-e71a-beac-5511-94b3797a5482.png)

その後は、ZadingのInstallationを実行したらなんと動くようになりました！（新しい基盤多分買う必要なかった・・・）

https://docs.qmk.fm/#/driver_installation_zadig

あと、キーマップを変更する[VIA](https://usevia.app/)なのですが、ブラウザがWebHID APIというものを持っていないと無理っぽいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/4671b833-8f3b-751f-1544-dd9e798e45e5.png)

こちらfirefoxだったのではじかれました。緑色のブラウザを使ったほうがよさそうです。

以上！
AutoMapperの概要と使い方

AutoMapperについて既存の分かりやすい記事を引用しながら、AutoMapperの基礎的な使い方から実際のアプリ開発での使い方をまとめた。

## 0. AutoMapperとは

AutoMapperは、異なるオブジェクト間のデータ移行を容易化できるNugetパッケージ。

## 1. AutoMapperの基礎的な使い方

AutoMapperは、簡単なルールでのマッピングについては、デフォルトで自動マッピングを行ってくれるので、開発者がマッピング定義を明記する必要がない。
例えば同名プロパティへのマッピングや、基本的な型変換はデフォルトでサポートされている。

別名プロパティや異なる階層へのマッピング、マッピングの際にデータ加工を行いたい場合など、マッピングルールを独自に細かく決めたいケースではマッピング定義を明記することで対応可能となる。
<details>
<summary>参考記事</summary>

https://gist.github.com/devlights/29ba85e39e84858bee47

https://medium.com/@josiahmahachi/simplify-object-mapping-in-net-with-automapper-b7fd1569fe2b

</details>

## 2. AutoMapperの実践的な使い方

AutoMapperを実際の.NET開発で使用する場合、Profileを継承したMapperProfileクラスを作成する。そしてそのコンストラクタにマッピング定義を記述する。

https://qiita.com/belre/items/fec14e57935015fbe674

## 3. フレームワークにDIを導入する

実際の.NET開発ではDIコンテナを利用することが多いが、フレームワークによってはデフォルトでDIコンテナを使えるようになっていない。
そのためDI機能を提供するパッケージを導入し、エントリポイントでDI登録を行うようにコードを記述する必要がある。

↓WPFでの例

https://qiita.com/soi/items/a19304220c71bdfbc171


## 4. AutoMapperをDIする

AutoMapperもDIに対応しており、その記述方法は下記記事のStartup.csの記述が参考になる。

https://ryuichi111std.hatenablog.com/entry/2016/11/18/005238

## 5. その他メモ
### 平坦化（何かに使えそう）

https://c.19633.com/tags-c-1/AutoMapper-1/1001026108.html

### 既存のオブジェクトにマッピングする

「Mapper.Mapメソッドは新しくオブジェクトを作成する以外にも、既存のオブジェクトを引数で指定することでコピーも可能になってます。」（これやりたかった！！）
https://blog.shibayan.jp/entry/20130203/1359898568

### 名前変換ルールをカスタマイズする

デフォルトで自動マッピングされるのはプロパティ名が全く同じ場合などだが、以下の記事ではマッピングルールを独自にカスタマイズしている。

こちらの記事では、既存のNamingConventionクラスを使い、スネークケースからパスカルケースへのマッピングを行うように構成している。

https://atmarkit.itmedia.co.jp/ait/articles/1504/01/news017.html


こちらの記事では、INamingConventionを実装する自作クラスを使い、スネークケースからパスカルケースへのマッピングを行うように構成している。

https://xin9le.hatenablog.jp/entry/2014/10/09/002720
順列組合せライブラリ


[この記事のオリジナル](https://yamate11.github.io/blog/posts/2023/02-28-perm-dup/) は，2023年2月28日に公開されました．

競技プログラミング用の，順列組合せ (重複有り無し) を生成する自作 C++ ライブラリ Perm の使用法です．[ソースコードはここ](https://github.com/yamate11/compprog-clib/blob/master/perm.cc) にあります．

## struct

4つの struct がある．名前がおかしいのは歴史的理由による．

* IntPerm      順列
* IntComb      組合せ
* IntDupPerm   重複順列
* IntDupComb   重複組合せ

## constructor

```cpp
IntPerm ip(m, n);
IntComp ic(m, n);
IntDupPerm idp(m, n);
IntDupComb idc(m, n);
```

これらはいずれも，$[0, m)$ の数からなる長さ $n$ のリストを生成する．

このライブラリでは，「順列」と「組合せ」の違いは，後者は昇順にソートされている，ということである．

#### IntPerm

$[0, m)$ からなる長さ $n$ のリストで，同じ数がたかだか1回しか現れないものを列挙する．

たとえば `ip(4, 2)` は，次を生成する:

```
[0,1], [0,2], [0,3], [0,4], [1,0], [1,1], [1,2], [1,3], [2,0], [2,1], [2,2], [2,3], [3,0], [3,1], [3,2], [3,3]
```

#### IntComb

$[0, m)$ からなる長さ $n$ のリストで，同じ数がたかだか1回しか現れず，昇順ソートされているものを列挙する．

たとえば，`ic(4, 2)` は，次を生成する:

```
[0,1], [0,2], [0,3], [0,4], [1,2], [1,3], [2,3]
```

#### IntDupPerm

$[0, m)$ からなる長さ $n$ のリストを列挙する．

たとえば `idp(4, 2)` は，次を生成する:

```
[0,0], [0,1], [0,2], [0,3], [1,0], [1,1], [1,2], [1,3], [2,0], [2,1], [2,2], [2,3], [3,0], [3,1], [3,2], [3,3]
```


#### IntDupComb

$[0, m)$ からなる長さ $n$ のリストで，昇順ソートされているものを列挙する．

たとえば `idc(4, 2)` は，次を生成する:

```
[0,0], [0,1], [0,2], [0,3], [1,1], [1,2], [1,3], [2,2], [2,3], [3,3]
```

## 生成

`obj.get()` が true を返す間，新しいリストが生成される．リストの i 番目の要素は，`obj.at()` である．

```cpp
while (ip.get()) {
  for (int i = 0; i < 2; i++) cout << ip.at(i) << " ";
}
```

### 注意1

`obj.get()` が false を返すときには，内部状態は初期値に戻るので，そのまま次のラウンドを実行することができる．

### 注意2

* $n \geq 0, r \geq 0$ でないときには，何も生成しない．
* IntPerm と IntComb は，$r \leq n$ でないときには，何も生成しない．
* IntDupPerm と IntDupComb は，$n = r = 0$ のときに，何も生成しないのでは __なく__，空リスト `[]` を生成する．これは，ことによると適切でないかもしれない．($0^0 = 1$ になるし，$H(n, r) \neq C(n+r-1, r)$ になるから)
* $n = 0$ かつ $r \neq 0$ の場合には，何も生成しない．

## デバッグ用

`const vector<int>& obj.vec_view();` でベクトルに変換できる．

## 忘れやすい利用シーン

#### ボールと仕切りの重複組合せ

区別されない $a$ 個のボールを 区別される $b$ 個の箱に入れる方法は，IntDupComb(b, a) が列挙するリストと対応付けられる．リスト $[x_1, ..., x_a]$ は，ボール $1$ が箱 $x_1$に，ボール $2$ が箱 $x_2$に，..., ボール $a$ が箱 $x_a$ に入っていることを意味している．(ボールを区別しないことは，入る箱を昇順にして良いことと対応している．) したがって，各箱に入っているボールの数は，次のように求められる．

```cpp
IntDupComb idc(b, a);
while (idc.next()) {
  vector<ll> numBalls(b);
  REP(i, 0, a) numBalls[idc.at(i)]++;
  //  箱 j にはボールが numBalls[j] 個入っている
}
```
「1年目のときに読むのを諦めた技術書」を読めるようになった理由

## はじめに

◆この記事は何？
技術書を読めるようになった過程や理由を共有する記事

◆対象は？
主に新人エンジニアの方

◆この記事のねらい
エンジニアとして成長するためには技術書を読むのが重要です。
技術書を読めるようになった過程や理由を共有して、特に新人の方を応援するのがねらいです。
技術書を読むのを諦めてしまう方が、少しでも読めるようになれば幸いです。

## 先に結論
- 「読むのを諦めた技術書」を読めるようになった
- 読めるようになった理由
    - コンピュータサイエンスの基礎力の向上
    - 1冊で理解しようとしなくなった
    - 理解に時間をかけるようになった
- 新人エンジニアに伝えたいこと
    - 諦めて積んでもOK
    - そのうち読めるようになる

## 諦めた本

お恥ずかしながら、1年目のときに読むのを諦めた本があります。

[「Webを支える技術」](https://amzn.asia/d/gDIygSf)です。
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/84931020-a37d-4d79-f524-fd0d3b5e684e.png">

「Webを支える技術」は読んでおこう、と先輩から紹介されたので購入しました。

しかし、当時は理解ができずに読むのを諦めてしまいました。

私は情報系出身ではなく、基本情報や応用情報で問われるような基礎知識が不十分でした。
1年目の私は、データ分析を中心としたデータサイエンス、バックエンド中心で、Webとの関わりが浅かったこともあります。

## 急に読めるようになった

積んでから長い年月が経ちました。

久しぶりに開いてみると、スラスラと読めました。

評判通り、とてもわかりやすく、必要な知識がまとまっています。

「なんでこんなにわかりやすい本が読めなかったのだろう？」とも思いました。

気づけば、**「Webを支える技術」を新卒エンジニアに紹介する先輩**になっていました。

## 読めるようになった理由

読めるようになった理由は3つです。

### ①コンピュータサイエンスの基礎力の向上

読めるようになった要因の一つは、コンピュータサイエンスの基礎力の向上です。

コンピュータサイエンスの基礎をやり直しました。

例えば、OSI参照モデル、http、TLS、といった本当に基礎的な領域をきちんと理解するようにしました。

その結果、知らない単語の数が減り、技術書が読みやすくなりました。

### ②1冊で理解しようとしなくなった

1冊で理解しようとせず、いくつかの技術書を使って理解するようにしました。

入門書を先に読むことで、理解のハードルを下げました。

また、同様の領域の書籍をいくつか読むことで、理解の機会を増やしました。

先日書いた記事です。ロードマップを意識して読むようになりました。

https://qiita.com/mkt_hanada/items/d08e409fe90e829f5d34

### ③理解に時間をかけるようになった

理解に時間をかけるようになりました。

「他の技術書を読む」もそうですが、例えば画像・動画検索してみたり、英語で検索してみたりして、多角的に理解しようと試みました。

Qiitaなどの技術記事が、技術書を容易に翻訳してくれることもありました。

時間はかかりますが、着実に基礎力が上がっていくため、結果的に効率が良くなりました。

## おわりに

この記事では、「1年目のときに読むのを諦めた技術書」を読めるようになった理由を紹介しました。

新人エンジニアの方に伝えたいのは、「いまは難しくて読めない本」があっても良いということです。
いつか読めるようになると思いながら、積んで良いと思います。

参考になれば幸いです。
【Google Cloud】SafariでColab Enterpriseを利用するとランタイム接続に失敗した話

## 結論
ブラウザをGoogle Chromeに変えると接続できた。

## 事象
SafariブラウザからGoogle CloudのVertex AIのColab Enterpriseを利用しようとした。
メニューからVertex AI > Colab Enterpriseを選択後、ノートブックを新規作成しランタイムの作成まではうまくいくが、ランタイムに接続しようとすると以下のようにランタイムに接続ができなかった。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/279bf7ab-394d-2aed-0027-586b83936cf4.png)

## 試したこと(意味なし)
・ポップアップの「詳細」先のURL(https://cloud.google.com/colab/docs/troubleshooting#unable-to-access )を見ると、ブラウザのクッキー設定やファイアウォール設定に関する記載があり、Safariのクッキー設定の確認、PCのファイアウォール設定の確認をしたが、特に制限するようなものはなかった。

・ランタイムテンプレートをカスタマイズした
 ・マシンサイズをデフォルトよりも小さいものとした(リージョンのリソースが足りなくなっていることを懸念)
 ・ストレージサイズをデフォルトよりも小さいものとした(同上)
 ・VPC、サブネットを自動作成のもの、カスタム作成のもので選択し直した(デフォルトのVPC設定からの変更点が影響していることを懸念)
 ・「公共のインターネット アクセスを有効にする」、「エンドユーザー認証情報を有効にする」チェックボックスのONOFFの組み合わせを全パターン確認

・IAM設定を見直した
 ・個人環境でなのでオーナーロールのアカウントを使っていたが、ドキュメントを見て関連しそうな以下ロールを明示的に追加。
　 ・Colab Enterprise ユーザー
　 ・Colab Enterprise 管理者
　 ・コード作成者

・VPCのファイアウォール設定を見直した
　 ・最終的にはインバウンド、アウトバウンド全ての通信を許可するようにした

## 結果
結論に書いたように、ブラウザをGoogle Chromeに変えると接続できた。
おそらくSafariの見えていないセキュリティ設定で弾かれていたのでは推測するが、そこまで追う気力無し。。。(これだけで5時間くらい無駄にしたため(TT))

## 教訓
ドキュメント調査や実機確認で試すのもいいが、クラウド側のことだけでなくクライアント側環境のことも気にする必要あり。
特にWEBで検索してもクライアント側の環境起因の原因は全くヒットしなかったので、トラブルシューティングは視野を広くして対応することが重要。

## 終わりに
クライアント側の話なので他の方にも当てはまる内容かは不明ですが、同じような事象にハマった方の助けになれれば幸いです。(モデル云々の前に環境でつまづくと著しくやる気を削がれるので。。。)
main()って具体的にどう呼ばれるのか？

## はじめに
現在、私は立場上、業務でコードを書くことが殆どないのですが、とあることをきっかけに、C#に入門しようと思い立ちました。

C#の入門書を購入して早速勉強を始めてみましたが、プログラミング入門書のご多分に漏れず、出ましたMainメソッドの説明。

```
・C#は、Mainメソッドを探して最初に実行します
・これをエントリーポイントといいます
```

ふと、ここで気になりました。

・誰がMainメソッド探して呼ぶの？
・何を元にMainメソッドがどこにあるのかを把握するのか？

業界歴を四捨五入すると20年になる年数ながら、そこまで調べたことなかったなーと思い、この際調べてみました。

なお、今回はC言語における仕組みについて調べました。
書籍として、どんぴしゃのものがあり、そこでC言語が扱われていたためです。
また、勿論言語によって委細異なるとは思いますが、概念的な仕組みとしてはだいたい一緒じゃないかな？と思って、他の言語の仕組みは調べていません。

## C言語から作られたプログラムにおける、mainが呼び出される仕組み

調べてみたら、以下の書籍でまんま紹介されていそうだったので、早速図書館で借りて読みました。

https://www.shuwasystem.co.jp/book/9784798044781.html

書籍のうち、「第五章　main()関数の前と後」に詳細が記載されていますが、かいつまんでいうと、

- Linuxの実行ファイルのメタ情報（ELFフォーマット）にある、`Entry point address`のアドレスからプログラムが開始される
- `Entry point address`のアドレスは、標準Cライブラリ（glibc）にある`_start()`関数のアドレスであり、プログラムはまず`_start()`から処理が恥じます
- `_start()`でmain関数の引数とmain関数のアドレスをスタックに積んで、`__libc_start_main()`を呼び出す
- `__libc_start_main()`でmain関数を呼び出す

という感じでした。

ちなみにこのあたりの情報は、Web記事としても挙がっていました。

https://atmarkit.itmedia.co.jp/ait/articles/1703/01/news173.html

厳密に考えると、`main関数はエントリーポイントではない`ということになるのですが、抽象的に捉えると実質はエントリーポイントとして考えていい、ということで入門書ではこういった説明になっているのでしょうね。

## main関数の位置はどこを見ればわかるのか？
ここまで、実行ファイルを起動した際の、main関数の呼び出され方について調べたことを書きました。
そもそも、main関数の位置ってどこにあるのでしょうか？
（勿論実行ファイルの中にある、とは思うものの具体的にどこ？というのは知らなかったので調べました）

実行ファイルのメタ情報（ELFフォーマット）のどこかにあると思うのでフォーマットの定義を調べてみると、Symbole Table Sectionという、関数や変数などのシンボルに関するメタ情報があり、その中のValueに関数のアドレス（相対/仮想アドレス）の情報があるようです。

https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-79797.html

このメタ情報を参照して、main関数（だけじゃなく他の関数の呼び出しでも）の場所を特定している、というのが理解できました。

メタ情報がどのようにできるか、はコンパイラやリンカのお仕事になると思いますが、今回はそこまでは深く調べませんでした（また機会があれば調べてみようと思います）。

## おわりに
知りたかったことは全て以下の記事にあったとさ。
自分の調べた内容の答え合わせ的に参照させて頂きました、感謝。

https://zenn.dev/kaityo256/articles/what_is_linker

時間があったら、入門中のC#や、昔やってたDelphiなんかの仕組みも調べてみようかなと思います。
SAS公式のプログラミングレッスン受けてみた

# 0.学習背景

新たな現場で、SASを触る機会がありそうだったので、
実際に学習してみようということで

# 1.SASのインターフェースの違い

SASは対話的にコードを記述してサブミットするために使用できるいくつかのプログラミングインターフェースがあります。

SAS studio：
サーバー上のSASに接続するWebベースのインターフェース
SAS Enterprise Guide
SAS windowing environment：
ローカルサーバー・リモートサーバー上のSASにアクセスして実行するクライアントアプリケーション

対話型ということで、
Pythonを使ってデータ分析している方には聞き馴染みがある
Jupyter Notebookなどのアプリケーションで
コードを記述してサブミットも可能ではありますが、

一部のSASが提供するプログラミングツールの一部にはアクセスができないそう

SAS studioおよび　Enterprise Guideのプログラムエディタは、SASコードに対して高機能

コード補完・フォーマット・構文の色付け
などの機能が含まれているため、
プログラミングがとても簡単になる。

# SASプログラミングの構造

SASプログラムは、一連のステップで構成されている。
各ステップは、特定のタスクを実行します。


SASプログラミングには大きく２つのステップで構成されています。

１つ目は、DATA stepです
２つ目は、PROC stepです


SASプログラムには、実行するタスクに応じて、
DATAステップとPROCステップの任意の組み合わせを含めることができます。

ここで、一連のSASプログラムを記述します。

```sas
data myclass;
    set sashelp.class;
    heightcm=height*2.54;
run;

proc print data=myclass;
run;

proc means data=myclass;
    var age heightcm;
run;
```

ほとんどのステップは、RUNステートメントで終わり
いくつかのPROCステップは、
QUITステートメントで終わります。

ここでのQUITステートメントの説明はまだありませんでした。

もし、RUNステートメントを記述しない場合、
次のDATA・PROCステートメントの開始が、終了を示します。
つまり記述しなくても、RUNステートメントは実行されるということです。

## DATAステップ
入力ソースからデータを読みとり、それを処理して、
SASテーブルを作成します。

行のフィルタリング
新しい列の計算・テーブルの結合
そのほかのデータ操作も実行が可能

上のステップでは、heightcmという列をheight列を参照して作成しています

## PROCステップ
PROCステップは、あらかじめ
定義された特定の方法でSASテーブルを処理します。

SASには、レポートやグラフを生成したり、
データを管理したり、複雑な統計解析を実行したりする多数のプロシージャがあります。

proc内の meanステートメントには、要約統計量を算出したりすることが可能です

## グローバルステートメント

DATAおよび、PROCステップに加えて、SASプログラムには、
TITLE,OPTIONS,LIBNAMEステートメントなどのグローバルステートメントを含めることができる。

これらのグローバルステートメントは、DATA・PROCステップの外にある可能性があり、
グローバルステートメントの後に、RUNステートメントは必要ないとのこと。

## コメントアウト
コードを先に見てみます。
```sas
/* Search Age<13 */
data under13;
    set sashelp.class;
    where Age<13;
    *drop Height Weight;
```
セミコロンで終了する単一のステートメントをコメント化するには、ステートメントの先頭に
アスタリスクを追加する必要があるそうです。

ステートメント外のコメントアウトは上記のように行います。


# 3.まとめ（復習）
これらで何が行われているかを確認します。

```sas
data mycars;
	set sashelp.cars;
	AvgMPG=mean(mpg_city,mpg_highway);
run;

PROC print data=mycars;
		var make model type avgmpg;
		*where AvgMPG >35;
run;

/* PROC means data=mycars mean min max maxdec=1; */
/* 	var avgmpg; */
/* 	class type; */
/* RUN; */
```
これでは、mpg_city,mpg_highwayという列の平均値を出して、新たな列としています。

テーブ出力する際に、列選択（射影）させています。
where AvgMPGはあえて使わずに、コメントアウトをしています。

下のステートメントでは、統計量を出しています。

以上です。また今度もSASの学習アウトプットをしていきます。
特定のEC2インスタンスのみ起動停止できるIAMポリシー

# はじめに

VMを貸し出すという運用の中で、VMの起動停止できるユーザーを渡すということがあるかと思います。

それをAWSのEC2で実現するポリシーを作ってみました。

# 概要

- ユーザーの`Dept`タグ:値と、同じ`Dept`タグ:値を持つEC2インスタンスの起動停止をできるポリシーを、CloudFormationで作ります
    - ただし、すべてのEC2インスタンスがリストに表示されます


EC2インスタンスがすべてリストで表示される理由につきましては、以下の記事にあります。

https://qiita.com/Batchi/items/b3a23008376f405f166b

# 参考

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_ec2_instance-securitygroup.html


https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_iam-tags.html#access_iam-tags_control-principals

## Azure VMの場合

Azure VMで行った場合は以下で記事にしました。

https://zenn.dev/arbr/articles/830ec0fbee620b

# ポリシーのCFnテンプレート

作成するポリシーのCFnテンプレートは以下になります。

```yaml:create_policyStartStop.yaml
AWSTemplateFormatVersion: '2010-09-09'
  
Resources:
  PolicyStartStopEc2:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: 'StartStopEc2'
      Path: /
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action: 'ec2:DescribeInstances'
            Resource: '*'
          - Effect: Allow
            Action: 
              - 'ec2:StartInstances'
              - 'ec2:StopInstances'
            Resource: 'arn:aws:ec2:*:*:instance/*'
            Condition:
              StringEquals:
                aws:ResourceTag/Dept: '${aws:PrincipalTag/Dept}'
```

# 確認
`Dept:aaaa`のユーザーを作成し、`Dept:aaaa`のEC2の起動停止を確認してみます。

まずEC2インスタンスを2台作成します。タグはそれぞれに`Dept:aaaa`と`Dept:bbbb`を付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/11a1cfa1-8903-fb31-63f2-86c2724d0e5f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/21fcba46-19d3-a15d-444e-880b77e7d2bb.png)

CFnテンプレートで作成したポリシーをアタッチしたユーザーを作成し、タグに`Dept:aaaa`を付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/cbfd0734-3995-7272-187d-5099f29e8169.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8e468f5f-8126-9846-7530-465c9321e645.png)

このユーザーでコンソールログインして、EC2の画面に移動します。インスタンス2台とも閲覧できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8a803979-4f80-5d84-c03b-e02eb1505e99.png)

まずは`Dept:aaaa`のインスタンスであるtest001を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/24a5809a-8d81-1762-0a75-f50891fc2212.png)

正常に開始を確認したら、停止できることも確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/6fc1b4e2-3189-9ac5-069f-f574e937f0a4.png)

次に、`Dept:bbbb`のインスタンスであるtest002を開始してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1473b489-4b29-377e-3df7-105470ee37ee.png)
開始できないことが確認できます。

またインスタンスを別のユーザーで起動しておき、停止も失敗することを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/cc8daa8b-ba76-10e6-7760-4c159b0a35ee.png)

これで、`Dept`が同じEC2インスタンスのみ起動停止できるポリシーが確認できました。

# おわりに
今回は特定のEC2インスタンスのみ起動停止できるIAMポリシーを作成しました。
利用者に大きな権限を与えてセルフサービス的に使ってもらうこともあるかと思いますが、単純にインスタンスだけを使ってもらうこともある場合にこのポリシーは使えると思います。

この記事がどなたかのお役に立てれば幸いです。
ubuntu24.04 に docker, docker compose をワンライナーでインストール (2024/05)

## 概要

以下を実行するだけですが、コピペするのがめんどくさかったので、
一気に -y などもつけてワンライナー実行して、コーヒーを飲みながら待ちたかっただけです。

https://kinsta.com/jp/blog/install-docker-ubuntu/


```bash
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release -y
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y
sudo apt install docker-compose-plugin
```

以上です〜
単純交換法(バブルソート)

## 単純交換法(バブルソート)とは

データを並べ替える整列アルゴリズムの一つ。
隣り合ったデータを交換する処理を繰り返して、全体を整列する。
実行速度は遅い。

### 対象データ

以下の配列を昇順に並べ替える

```php
$array = [5, 3, 4, 1, 2];
```



### フローチャート

変数`i`は比較する要素のうち右側の要素の添字を表す変数。
変数`k`は既に確定した要素の添字。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733055/e9d0e64b-8539-7b23-1b6f-3fa5374540a4.png)

#### 手順

①右端の要素から順に、隣り合ったデータを昇順に並べ替える
②左端の要素から一つずつ順番に、データが昇順に整列していく
JetpackCompose TextFieldでキーボードのタイプを変更する方法

TextFieldでキーボードのタイプを変える方法です。


```.kt
@Composable
fun CopyButton() {
    var text = remember { mutableStateOf("") }
    TextField(
        value = text.value,
        onValueChange = { text.value = it },
        label = { /*TODO*/ },
        modifier = Modifier.padding(16.dp),
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Text,
            imeAction = ImeAction.Done,
        )
    )
}
```

こちらのコードの`keyboardType = KeyboardType.Text`
ここの部分で変更することが可能です。

# KeyboardTypeの種類

| KeyboardType | 画像 |
|:-----------|------------:|
| Text       | ![スクリーンショット 2024-05-26 10.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/255fb1c7-1cb5-6f1c-7408-ee3a44f9d887.png)|
 | Ascii       | ![スクリーンショット 2024-05-26 10.38.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/9a1fb865-b83d-9b36-b5f7-6bcfe3d5bf4d.png)|
  | Number       | ![スクリーンショット 2024-05-26 10.39.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/a728ee61-28ce-1c25-1173-f86aaaec6c1f.png)|
| Phone       | ![スクリーンショット 2024-05-26 10.40.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/08dc8818-4525-e5ad-ab12-18a39ef0411b.png) |
| Uri       | ![スクリーンショット 2024-05-26 10.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/c053f6f4-d593-6d14-53ae-0e20953bf42a.png)|
| Email       | ![スクリーンショット 2024-05-26 10.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/3a3bd1d7-4a2e-732e-b79e-c9c577e5ac86.png)|
| Password       | ![スクリーンショット 2024-05-26 10.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/92add3fa-4823-6804-8782-f5ebb1d623cc.png) |
| NumberPassword       | ![スクリーンショット 2024-05-26 10.44.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/5d1c258b-e4db-3731-a18c-137534d60ebe.png) |
| Decimal       | ![スクリーンショット 2024-05-26 10.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/83b33fa0-c818-8e87-1138-e100d54319be.png) |
【SEO】キーワードや検索クエリの調査手順

# ラッコキーワード
複合キーワードで検索

### サジェストーキーワードのダウンロード
右上の検索ワードのコピーをクリック

## キーワードプランナー
検索ボリュームの調査に張り付けて検索

### CSVダウンロード
プログラミング初心者にオススメのPCはMac？Windows？

プログラミングを始めてみたいと思うと、まず「パソコンは何を選べばいいんだ」ということで悩むのではないでしょうか？私もプログラミングを未経験の状態から始めたので、同じように悩みました。パソコンは高価なので、**ここで間違ってしまうと後ですごく後悔**することになります。

この疑問について現在エンジニアとなった私がお答えすると、<strong>「初心者で悩むのならMacBook買うといい」</strong>となります。この記事で悩みがなくなるように、なぜMacBookがいいのかやMacBookの選び方、Windows PCと比較したときのメリット・デメリットについて紹介します！


<iframe width="560" height="315" src="https://www.youtube.com/embed/alT03Lq65yU?si=hm1jEHDRBkxzhjXA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## プログラミングでMacを使うメリット・デメリット

![Advantages-and-disadvantages-of-using-Mac.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/050541a9-796a-4415-4f98-90c904e41fa2.jpeg)


プログラミングといえば、macってイメージがありますよね。たしかにWindowsでもプログラミングは可能なのですが、エンジニアでMacが好きな人が多いと体感値としてもあります。ここでは、なぜMacが人気なのかメリットと逆にWindowsのほうが優れているMacのデメリットについて紹介します。私が考えるMacを使うメリット・デメリットは、以下の5点です。

【メリット】

- エラー対応がしやすい
- iOSアプリの開発ができる
- デザインがかっこいい

【デメリット】

- 値段が高い
- ゲーム開発には不向き


[>> Macを使うメリット・デメリット各項目の詳細説明はこちらを確認！](https://taishi-official.com/2024/02/02/1551/#toc2)

## プログラミングで必要となるMacBookのスペック

![MacBook-Specifications-for-Programming.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/bc31621f-a06b-9f38-97f7-8c5ca54e39fc.png)


プログラミングに必要なPCのスペックは、下記のようになります。

- **CPU**：Apple M1以上、Intel製の場合はCore i5以上
- **メモリ**：最低8GB以上、希望は16GB以上
- **ストレージ**：SSD 256GB以上
- **画面サイズ**：お好みのサイズで

[>> Macbookの必要スペック詳細はこちらで解説してます！](https://taishi-official.com/2024/02/02/1551/#toc9)

## MacBook ProとAirのどちらを選べばいい？

![MacBook-Pro-or-Air.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/01227ffd-fec3-8a75-7348-7c675720df4b.png)


MacBookにはMacBook AirとMacBook Proの2種類があり、以下のような判断基準で選びます。

- **MacBook Air** → コスト重視の方向け
- **MacBook Pro** → 性能重視の方向け

[>> Macbookの各おすすめ商品はこちら！](https://taishi-official.com/2024/02/02/1551/#toc14)

2024年3月8日に、M3チップ搭載の新型MacBook Airが発売されました。新型MacBook Airの性能を筆者が確認してみたのですが、主にグラフィック機能（ゲームや動画編集で使う）が機能として向上しているようです。新しい物好きでなければ、**旧型のほうが値段も安くなっているのでコスパがいい**です。


上記リンクにておすすめのMacBookについて紹介しましたが、<strong>MacBookは型落ちしたものや中古品など定価で買うより安く買えるものがたくさんあります。</strong>もっとお安くMacBookを手に入れたいということであれば、上記スペック表を参考にご自身で探してみてください。

## まとめ
今回はプログラミング初心者に向けて、なぜMacをおすすめするのかメリット・デメリットとMacBookの必要スペック、おすすめ端末について紹介しました。高い買い物なのでWindowsの安いパソコンでできないかとか考えると思いますが、プログラミングのエラーを自分で対処できる自信がなければMacを使ったほうがいいです。


<strong>パソコン選びに悩んでいる時間はもったいなく、さっさと学習を始めてしまったほうがいいです。</strong>ぜひMacBookの購入を検討してみてください。

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<br>

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
Githubの認証方法

## 概要

Gihubの認証周りで少しつまづいたので、認証周りがどうなってるんだっけ？
といったことを理解するための記事です。

## アクセス方法

- ブラウザ内、
- GitHub Desktop 
- API
- コマンドライン

など、さまざまな方法でアクセスできるっぽい。

## 認証方法

認証方法は、
- 2 要素認証を使用したユーザー名とパスワード、またはパスキー
- Personal access token
- SSH キー
の主に3種類での認証方法があるとのこと。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/about-authentication-to-github

アクセス方法に認証方法が依存してるので、アクセス方法に合った認証方法を選択する必要があるらしい。うん。それはそうだよね。

個人的には、CLIで完結できるならCLIがいい（GUI慣れるまで時間かかるので）人間なので、コマンドラインでの認証で試していきます。

## コマンドラインでの認証

- HTTPS
- SSH
の2つの方法のみらしい。

Githubでの推奨は、HTTPSとのこと。パッとメリデメが分からなかったので、下記の記事を参考にさせてもらいました。

https://zenn.dev/nameless_sn/articles/the_differences_between_https_and_ssh

なぜHTTPS？ かといったところは、
- アカウント情報だけでリポジトリに書き込めるので、どこからでも簡単にアクセスできるから
- HTTPSはすべてのファイアウォールで開かれているから

一方、SSHのメリットとしては、

- 情報漏えい対策としては最適解
- 鍵がハードディスク上のユーザアクセスが可能なファイルとして保存されることが欠点

とのこと。まぁそうだよねって感じ。
セキュリティー面を考える必要が今回はないので、使い勝手を考えるとHTTPSがいいかなと。

## 実際に試してみる

ghコマンド入ってなかったので、入れました。

```
brew install gh
```

```
yuya.k@mbp work % brew install gh
==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Auto-updated Homebrew!
・
・
・
==> Running `brew cleanup gh`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
yuya.k@mbp work % 
```

ログインしていきます。

```
yuya.k@mbp work % gh auth login  
? What account do you want to log into? GitHub.com
? What is your preferred protocol for Git operations on this host? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Paste an authentication token
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens
The minimum required scopes are 'repo', 'read:org', 'workflow'.
? Paste your authentication token: 
・
・
・
? Paste your authentication token: **********************************************************************************- gh config set -h github.com git_protocol https
✓ Configured git protocol
✓ Logged in as 〜
```

事前に作成しておいたアクセストークンを入力して、これでログインOKですね。
アクセストークンの作成方法は、下記の記事が見やすかったので載せておきます。

https://nlab-notebook.com/entry/2023/04/23/200000#toc2
【Android】Huawei端末でカスタムIntentChooserを出さないようにする方法

# はじめに
最近中華製端末がコストパフォーマンスの高さからより一層注目されるようになってきましたね。
そんな中華製端末の中でもHuaweiはかなりの人気を誇っているかと思いますが、実はIntentChooserに"ある"パラメータを設定してしまうとHuawei独自のカスタムChooserが出てしまうという謎挙動があります。
ただ選択させておしまいであれば気にする必要もないのですが、InputSenderを利用するケース(BroadcastReceiverを使うケースなど)では大問題です。
もれなくHuawei端末だけonReceiveが呼ばれないなどの事象が発生します。
そこでこのHuawei独自のIntentChooserを表示させない方法を備忘録的にまとめておこうと思います。

# IntentChooserとは？
念の為IntentChooserについて軽く触れておきます。
IntentChooserとは、暗黙的IntentによりActivityが起動される際、候補となるActivityが複数存在する場合に表示されるもので、端末ユーザーに複数の候補から起動するActivityを選んで選択可能な機能のことを指します。

<img src="https://developer.android.com/static/images/training/sharing/sharesheet.png?hl=ja" width="220px">

# Huawei独自のIntentChooserを表示させない方法
HuaweiのIntentChooserを表示させないようにするには、IntentChooserを表示する際に使用するcreateChooserの第二引数であるtitleをnullで設定する必要があります。


```main.kt
// HuaweiでカスタムChooserが表示されるパターン
Intent.createChooser(intent, "テスト", intentSender)

// HuaweiでカスタムChooserが表示されないパターン
Intent.createChooser(intent, null, intentSender)
```

設定自体は非常にシンプルですが、何故titleを見て出しわけているのか謎ですね、、、
仕様によってはかなりの落とし穴になる可能性があるので注意していただくのが良いかと思います。

ご説明は以上です。

# さいごに
今年の運動会、弁当本気出しすぎて徹夜しました、、、
宮本輝の小説マップ

# 1.はじめに
* 宮本輝の小説に出てくる場所のマップを作っています。
* [Mapping Sheets](https://workspace.google.com/marketplace/app/mapping_sheets/736233853391)が便利！



# 2. 経緯
* 祖父母の家にあった「[優駿](https://bookmeter.com/books/561493)」「[オレンジの壺](https://bookmeter.com/books/649250)」「[ドナウの旅人](https://bookmeter.com/books/498283)」などを読んで宮本輝ファンになった自分は、最近完結した「[流転の海](https://bookmeter.com/books/506273)」を読むに及んで、いつか小説に出てきた場所を旅したい！という気持ちに。
* が、小説に出てくる場所が多すぎて整理できなくなり、じゃマップにしてみようと取り組み開始。Google My Mapがよさそう。


# 3.作成して困ったこと
* 早速作り始めたけれど、レイヤーが８個くらいで追加できなくなり、小説のタイトル別に分けるというのができなくなる。[レイヤー＊ピンの色で分ける](https://note.com/zacharylion/n/nec043afa7d56)とかあったけど、小説の数のほうが多くなってしまいそう。
* １個ずつ（GUIで）マップに手入力するのは辛いので、すぐにもっと効率的にしたくなる。実際小説数が多いし、なんとかしないと。
*![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/e1f1acc9-94ff-06b8-57a0-0dae04a31876.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/4e9dbf59-ffc5-a45a-471e-a7a34ce53d1b.png)


# 4.Mapping Sheetsへ 
* KMZ形式などあったので、pythonとgoogle map API組み合わせてやるかーと思っていたところ、[Mapping Sheets](https://workspace.google.com/marketplace/app/mapping_sheets/736233853391)を発見。すでに[先達もたくさん](https://haya-nori.com/add-on-google-spreadsheets-and-maps-connect-mapping-sheets/)いてありがたい。
* こういう感じでスプレッドシートに３列作って「build」を押すと
* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/b6b863b1-1d0f-dbd3-7a15-abc962e775db.png)
* こんな感じで出してくれる。小説でフィルターかけられるようになった！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/19d6cb2e-592a-5b89-59f5-216d33d7b68b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/235e8dee-23e6-2543-af2b-a0702fc05565.png)





# 3.今後
* 引用の範囲内で、小説中のその場所のセリフとか追加したい。
* 当時の地名や場所などは要検証だがどうやって確認しようか思案中。
* より詳細な場所の特定かなーと思案中（観光公害にならないように）
* [Bar Teru's Club](https://www.terumiyamoto.com/goannai.html)など熱心なファンがいるのでその方たちに聞いてみたい。
* あとは小説に出てくる地名はgeminiにきいても厳しそうなので、読み返しながら記録してかないといけないなあ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/07cfd202-dca9-9a87-3250-89b8b1b5662a.png)


* そういえば今日は東京優駿ですね。
* 小説もいいけど、あまり多くないエッセイも好きです。おすすめは[本を積んだ小舟](https://bookmeter.com/books/498292)です。
* 小説は 「[自分でうたっちゃいけない](https://www.youtube.com/watch?v=eRi2G6UDMhc&ab_channel=%E9%A3%AF%E7%94%B0%E6%A9%8B%E6%96%87%E5%AD%A6%E4%BC%9A)」というのはプログラミングにも通じるようで身に染みました。
毎日ABC day3【c++】ABC343 A-C問題解説【ACコード付き】

# AtCoder Beginner Contest 343

https://atcoder.jp/contests/abc343

## A - Wrong Answer
0以上9以下で、1桁の整数が二つ与えられる。0以上9以下で、それらの和ではない数を出力せよ、という問題。

いろんな回答があると思うが、和が1の時は2、それ以外は1を出力した。

```cpp
int main()
{
	int A,B;
	cin >> A >> B;
	if (A + B == 1){
		cout << 2 << endl;
	}
	else{
		cout << 1 << endl;
	}
}
```

## B - Adjacency Matrix

何やら問題文は難しい表現をしているが、$N*N$の行列が与えられるので、横方向に上から読み取った時に、1である場所を出力する。

```cpp
int main()
{
	int N;
	cin >> N;
	vector<int> vec(N);
	for (int j = 0; j < N; j++)
	{
		for (int i = 0; i < N; i++)
		{
			cin >> vec[i];
			if (vec[i] == 1)
				cout << i+1 << " ";
		}
		cout << endl;
	}
	return 0;
}
```

## C - 343
正の整数$N$が与えられる。$N$以下の最大の回文立方数を求めよ。

回文かどうかを求める関数を作成し、小さい正の整数から順番に$N$をギリギリ超えない立方数までresultを更新し、最後のresultを出力する。

```cpp
bool trueorfalse(long long n)
{
	string s = to_string(n);
	int len = s.length();
	for (int i = 0; i< len / 2; i++)
	{
		if (s[i] != s[len - 1 - i]) return false;
	}
	return true;
}

int main()
{
	long long N;
	cin >> N;
	long long result;
	for(long long i = 1; i <= N; i++)
	{
		long long cube = i * i * i;
		if (cube > N) break;
		if (trueorfalse(cube)) result = cube;
	}
	cout << result << endl;
}
```
PostgreSQL 最終vacuum, analyze日時を取得

# PostgreSQL 最終`vacuum`, `analyze` 日時を取得

クエリが継続的に適切に実行されるためには、`vacuum` や `analyze` の存在が欠かせません。  
そのため、最終`vacuum`、`analyze` 日時を定期的に監視する必要があります。

そのための便利なクエリの使い方を残しておきます。

テーブルセットアップ

```
postgres@masami-L ~ > pgbench -i
dropping old tables...
creating tables...
generating data (client-side)...
100000 of 100000 tuples (100%) done (elapsed 0.09 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 0.57 s (drop tables 0.02 s, create tables 0.02 s, client-side generate 0.17 s, vacuum 0.07 s, primary keys 0.29 s).
postgres@masami-L ~> pgbench -c 10 -T 100
pgbench (14.10 (Ubuntu 14.10-0ubuntu0.22.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
duration: 100 s
number of transactions actually processed: 25671
latency average = 38.961 ms
initial connection time = 28.953 ms
tps = 256.668551 (without initial connection time)
```

最終 vacuum. analuze 日時を取得

```sql
postgres=# SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
FROM pg_stat_all_tables
WHERE schemaname = 'public'
ORDER BY relname;
     relname      | n_live_tup | n_dead_tup |          last_vacuum          |        last_autovacuum        |         last_analyze          |       last_autoanalyze
------------------+------------+------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------
 pgbench_accounts |     100000 |       3866 | 2024-02-18 11:19:19.939566+09 | 2024-02-18 11:19:30.51323+09  | 2024-02-18 11:19:19.9777+09   | 2024-02-18 11:21:30.638838+09
 pgbench_branches |          1 |          0 | 2024-02-18 11:19:35.479241+09 | 2024-02-18 11:21:30.654551+09 | 2024-02-18 11:19:19.923432+09 | 2024-02-18 11:21:30.654742+09
 pgbench_history  |      25671 |          0 | 2024-02-18 11:19:19.982612+09 | 2024-02-18 11:21:30.688762+09 | 2024-02-18 11:19:19.982845+09 | 2024-02-18 11:21:30.72651+09
 pgbench_tellers  |         10 |          0 | 2024-02-18 11:19:35.479723+09 | 2024-02-18 11:21:30.669118+09 | 2024-02-18 11:19:19.927675+09 | 2024-02-18 11:21:30.669353+09
(4 rows)
```
Databricksワークスペースオブジェクトをバルクで操作できる様になりました

こちらのアップデートです。

[**Bulk move and delete workspace objects from the workspace browser**](https://docs.databricks.com/en/release-notes/product/2024/may.html#bulk-move-and-delete-workspace-objects-from-the-workspace-browser)

> 移動、削除するためにワークスペースの複数のアイテムを選択できる様になりました。複数のオブジェクトが選択された際には、アイテムを移動、削除するためのオプションを提供するアクションバーが表示されます。さらに、マウスを用いて複数のアイテムを選択し、新たな場所に移動することともできます。バルクでの移動、削除オペレーションの際にも、オブジェクトに対する既存の権限は適用されます。

ワークスペースにアクセスします。若干見た目が変わっています。
![Screenshot 2024-05-26 at 8.45.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/cf66d77e-b805-7846-57d2-a1ae24c65610.png)

オブジェクトの左端のチェックボックスを選択できる様になっており、移動、削除が行える様になっています。
![Screenshot 2024-05-26 at 8.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ce462854-3fac-ffee-ca61-7a04af8c656d.png)
![Screenshot 2024-05-26 at 8.47.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/983f90cf-881e-5f45-5774-c1a0716a5d5f.png)
![Screenshot 2024-05-26 at 8.48.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/731ac11f-0717-c290-f6aa-e4b709ba0c66.png)

マウスのドラッグ操作で移動することもできます。
![Screenshot 2024-05-26 at 8.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/546e5010-751b-3f9f-0fba-fe4d827179c8.png)

(コピー機能も欲しいところですが)ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)