OmniAICreator/Qiita-1.07M huggingface dataset:
【Linux】シェル変数と環境変数

# シェル変数と環境変数の違い

**シェル変数**は、実行中のシェルのみが使用する変数です。
**環境変数**は、実行中のシェルとそのシェルで起動したプログラム(子プロセス)等が使用する変数です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/6e1351e7-6fb5-ff37-9b03-67507534203c.png)

## シェル変数を定義する

**シェル変数**を定義するには、ターミナル上でシェル変数名=値と入力します。
入力後に、echo $シェル変数名で格納された値の確認を行えます。

```shell_session:シェル変数を定義
[test_01@localhost ~]$ name="tanaka"
[test_01@localhost ~]$ echo $name
tanaka
```

また、`setコマンド`をオプション無しで実行する事でシェル変数の一覧を表示出来ます。
先程定義したnameを確認します。下記が実行結果となります。

```shell_session:シェル変数を確認
[test_01@localhost ~]$ set | grep "name"
name=tanaka
```

シェル変数を削除したい場合は`unsetコマンド`を実行します。
空白等を代入しても、削除されるわけではございません。変数自体は残ります。
※_=name と出力されておりますが、これは`$_`に直前のコマンドの引数が格納されているだけです。

```shell_session:シェル変数を削除
[test_01@localhost ~]$ unset name
[test_01@localhost ~]$ set | grep "name"
_=name

[test_01@localhost ~]$ name="tanaka"
[test_01@localhost ~]$ name=""
[test_01@localhost ~]$ set | grep "name"
name=
```

## 環境変数を定義する
**環境変数**を定義するには、`exportコマンド`を使用します。
また、環境変数の一覧を表示したい場合は`envコマンド`や`printenvコマンド`を使用する事で確認出来ます。


```shell_session:環境変数を定義
[test_01@localhost ~]$ export name="tanaka"
[test_01@localhost ~]$ env | grep "tanaka"
name=tanaka
```

環境変数は子プロセスに引き継がれます。例として、シェルスクリプト内で`echoコマンド`を実行してみます。
下記に実行結果を載せています。

```shell_session:
[test_01@localhost ~]$ cat test.sh
#!/bin/bash

echo $name
[test_01@localhost ~]$ ./test.sh
tanaka
```

シェル変数の場合は子プロセスに引き継がれないので、上記のような結果が得られません。

```shell_session:
[test_01@localhost ~]$ unset name
[test_01@localhost ~]$ name="satou"
[test_01@localhost ~]$ ./test.sh

```

環境変数を削除したい場合は、`export -n`で削除出来ます。

```shell_session:環境変数を削除
[test_01@localhost ~]$ export -n name
[test_01@localhost ~]$ env | grep "name"
[test_01@localhost ~]$ set | grep "name"
name=satou
```
read_csvが遅い時対策

こんにちは！
新米データサイエンティストのぽむです。

今日、会社で10GBくらいのcsvファイルをpandasで読み込もうとしました。
しかし、待てど暮らせど読み込みが終わらない...
これではお仕事にならないので、読み込み速度を速める方法を調べました。共有します！

# ①dtype引数の指定
read_csvにはdtypeを指定する引数があります。
例えば、下記のコードのようにカラムごとに設定できます。
```
import pandas as pd
pd.read_csv(file_path, dtype={"カラム名1": float, "カラム名2": int})
```
これをやるだけで、30分以上かかっていた読み込みが2分になりました🤗

# ②読み込みたいカラムだけを指定する
csvファイルの中身を見ると、分析には使えないカラムもたくさんありました。
そこでread_csvのusecols引数で読み込みたいカラムだけを指定しました。
```
import pandas as pd
pd.read_csv(file_path, usecols=["カラム名1", "カラム名2"])
```
これも少し早くなりました。また、読み込み速度だけではなくてメモリの節約にもなってお得です！

# おわりに

他にもDaskというライブラリを使うととても速いみたいですが、難しそうなのでまた今度調べます！

ありがとうございました！
The Lambda Function Returned An Error.の原因

## 背景
Amazon ConnectからLambdaを呼んでDynamoDBに値を保存する事を実現する上で注意する必要のある事を残しておく

## 起きうる現象
### 1. Roleの設定ミス
必要に応じて、設定＞アクセス制限＞実行ロールからロールを作成して付与してあげる必要がある。

### 2. returnでstatusCode:200を返していない事によるLambdaの失敗
下記エラーが発生する要因の一つとして、
```
The Lambda Function Returned An Error.
```
下記のようにreturn分で200を返していない事が挙げられる。
※[こちら](https://dev.classmethod.jp/articles/amazon-connect-calling-lambda-and-subscribe-lambda/ "クラスメソッド")にも記載がある。
```
return {
  'statusCode': 200
};
```
FastAPI+Serverless FrameworkでCognito認証情報を処理内で取得

タイトルの通り、FastAPIで開発したAPIにServerless Frameworkの `authorizer` で設定したCognito認証の情報をPython内で使う方法です。

ほぼ最小構成で書いてます。

# FastAPI+Mangum（Python）
利用しているパッケージです。

```pyproject.toml
#省略
[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.87.0"
mangum = "^0.16.0"
#省略
```


`/auth` というCognito認証情報だけ返すAPIです。

```http.py
from fastapi import FastAPI
from mangum import Mangum
from starlette.requests import Request


app = FastAPI()


@app.get("/auth")
def get_auth(request: Request):
    # Cognitoの認証情報がrequest変数の中に入っています
    auth_info = request.scope["aws.event"]["requestContext"]["authorizer"]
    return {"auth": auth_info}


handler = Mangum(app, lifespan="off")
```



# Serverless Framework
以下の通りデプロイします。※ CognitoのUserPoolのARNだけダミーです。

```serverless.yml
service: echo-auth

frameworkVersion: "3"

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    usePoetry: true

provider:
  name: aws
  runtime: python3.8
  stage: dev
  region: ap-northeast-1

package:
  patterns:
    - "./**"
    - "./http.py"

functions:
  api:
    handler: http.handler
    memorySize: 128
    events:
      - http:
          path: /auth
          method: GET
          authorizer:
            name: cognito
            arn: arn:aws:cognito-idp:ap-northeast-1:123456789012:userpool/ap-northeast-1_Txxxxxxx
```

# 試してみる
CognitoからID Tokenを取得してAPIを実行してみます。

```sh
ID_TOKEN=eyJ....
curl -s https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/auth -H "Authorization: ${ID_TOKEN}" | jq
```


以下のような情報が取得可能です。

```json
{
  "auth": {
    "claims": {
      "at_hash": "xxxxxxxxxxxxxxxxxxxx",
      "sub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "email_verified": "true",
      "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_Txxxxxx",
      "cognito:username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "origin_jti": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "aud": "xxxxxxxxxxxxxxxxxxxx",
      "token_use": "id",
      "auth_time": "1669009768",
      "exp": "Tue Nov 22 05:49:28 UTC 2022",
      "iat": "Mon Nov 21 05:49:28 UTC 2022",
      "jti": "56a45e94-cd73-4675-93fc-d396260c3880",
      "email": "yusuke.otomo@mail.com"
    }
  }
}
```


# Dependsを使った方法
Dependsを使った方法もあります。こっちの方がスッキリ処理できる要件もあります。

```http.py
from fastapi import FastAPI, Depends, Request
from fastapi.exceptions import HTTPException
from mangum import Mangum


def auth_verify(request: Request):
    try:
        auth_info = request.scope["aws.event"]["requestContext"]["authorizer"]
        print(f"auth_verify -> {auth_info}")
    except:
        raise HTTPException(status_code=403)

app = FastAPI()

@app.get("/auth",dependencies=[Depends(auth_verify)])
def get_auth():
    return {"auth": "ok"}


handler = Mangum(app, lifespan="off")
```



# 参考
https://github.com/jordaneremieff/mangum/issues/64

https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/
作業漏れ厳禁! 職業エンジニアのためのバックアップチェックリスト

# 作業漏れ厳禁! 職業エンジニアのためのバックアップチェックリスト

バックアップ、とってますか？
「取り忘れはない」と自信をもって言えますか？

新卒入社から１年半の私が、思いつく限りの「会社でエンジニア個人がバックアップすべき資産」を列挙してみました。

## 前提
- 会社のインフラ/サーバ管理者がやってくれる部分は信頼して任せる
- クラウドサービスや社内サーバのデータ消失は、それらの管理者が未然に防いでくれることを期待し、あくまで自己管理の資産のみを対象とする

## 常識編

まずは、エンジニア以外の人にでも通じる部分から確認していきましょう。

### ブラウザのプロファイル

ChromeやFirefoxに代表されるブラウザには、ブックマークや履歴、パスワードなど多くの重要情報が入っています。
これらはブラウザの機能でログインをしていれば、GoogleやMozillaといったブラウザベンダが同期をしていてくれるので、バックアップは不要と考える方もいます。

しかし、それでは不十分です。
- あなたは、インストールしたアドオンを全部言えますか？
- 各サイトの会員登録の際、「パスワードを保存しますか？」に「いいえ」と答えたことは一度もありませんか？
- あなたがインストールしているすべてのアドオンはブラウザベンダの規定を将来にわたって完璧に順守し、開発が継続され、ストアから削除されないと言い切れますか？
- 各サイトごとの通知許可設定、カメラ等へのアクセスの許可/不許可などがリセットされても文句はありませんか？
- 自作の非公開アドオンはありませんか？

どれか一つでも「はい」と言い切れないならば、今すぐバックアップを。


## PC内のドキュメント・写真等

最近はGoogle DocumentやMicrosoft Office on the webに代表されるウェブ上でのドキュメント編集が増えていますね。大企業を信用するなら、これらはバックアップ不要です。また、会社内では会社が用意した共有ドライブ等にデータを格納することも多いでしょう。

ですが、手元のPCには本当に必要なデータを保存していないでしょうか？

- テキスト、Word文書、プレゼンテーションなど、手元のPCで書いてしまうことは本当にありませんか？ 
- お気に入りのアイコン画像、LGTM画像、イベントの写真など、もれなくクラウド保存できていますか？
- メールで受け取った資料は確かにメールサーバーに残っていますが、それを手元のPCに整理して保存することによって探索を効率化していませんか？ メール検索だけで必要な過去資料をすぐに探し出せますか？

どれか一つでも「はい」と言い切れないならば、今すぐバックアップを。

### IMEの履歴や辞書登録のデータ

- PC購入直後のアホなIMEに耐えられますか？
- 辞書登録機能をフル活用していたりしませんか？
- 変換の設定は一切カスタマイズせず、デフォルトのまま使用していますか？

どれか一つでも「はい」と言い切れないならば、今すぐバックアップを。


## エンジニア基礎編

続いて、エンジニアならば意識している人も多いと思われるものを確認です。

### IDEのディレクトリ

- カスタマイズした設定を、全部やり直せる自信がありますか？
- 活用している拡張機能を全部言えますか？
- 使っているバージョンを言えますか？または、繁忙期にデザインや操作感が違うバージョンをいきなり使い始めることに抵抗はありませんか？

どれか一つでも「はい」と言い切れないならば、今すぐバックアップを。

### サーバーの設定ファイル

- コンテナ化されていない開発サーバのApacheやnginxなどのミドルウェアのconfigファイル、手元のPCに設定したhostsファイルなどをバックアップし忘れていませんか？


### 鍵

鍵をなくすと大変です。
そして、~/.ssh/configファイルもないと、どの鍵がどのサーバーのものかわからない、ユーザー名がわからないということも起こりえます。
セキュリティに十分留意したうえで、~/.sshディレクトリのバックアップは必須でしょう。

## エンジニア応用編

え？それ必要？と議論になる。でも私は必要だと思うものたちです。
これをお読みの皆様は必要だと思いますか？

## パッケージ管理ツールで落としたパッケージ

phpならcomposer、jsならnpm、pythonならpip等、パッケージ管理ツールは皆さまお使いかと思います。こういったツールは、管理ファイルとlockファイルだけgit等のバージョン管理ツールに乗せておけばあとはコマンド一発・・・なんて思っていませんか？

たしかに理論上はそうなのですが、パッケージの公開停止や一部バージョンの削除などによって、3年・5年と経つうちに「二度と環境構築できない」状態に陥ってしまうことはないでしょうか？
また、npmやpipのバージョンによってインストールが失敗するケースなどもありますが、どのパッケージをどのバージョンのツールでインストールしたか、記録はありますでしょうか？

例えば、こんな記事もあるようですよ。
https://qiita.com/y13i/items/15407441b2bd1ec47baf

この例ではgitHubを探しに行けば解決可能なようですが、いつも逃げ道があるとは限らないのではないでしょうか。

大事なパッケージ、ぜひバックアップを。


### 各種ミドルウェアや言語環境のインストーラ

各言語やミドルウェアの旧バージョンをいつまでも入手できるなんて、夢物語です。
もしも「信じられない」という読者は、PHP5.1とJRE7のwindowsインストーラでも探してみてください。本記事執筆時点ではまだ見つけることができますが、たどり着くのはなかなか大変です。
当然、会社で使うものですから、ちゃんと信頼のおける公式サイトから探してくださいね。

信頼のおける古いパッケージの入手には、思いもよらぬ困難が待ち受けているかもしれません。いつか、公開が止まってしまうかもしれません。何より、PCが壊れて大忙しの時に、パッケージ探しなんて雑務は辛すぎます。

社歴の長い会社であれば、長期間メンテナンスしてはいないが動いてもらわねば困るソースコードなんていくらでもあるものです。

怖くなってきた方は、ぜひバックアップを。

## おわりに

バックアップには手間がかかりますが、エンジニアを長くやっていれば、誰しも一度はその大切さが身に染みたエピソードをお持ちではないでしょうか。

みんなで知恵を出し合い、漏れのないチェックリストを整備し、定期的に実施していきたいものです。
今更ながら、サーバーとは？

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# サーバーとは
サーバーとは、`利用者の要求に対して、それに応答したデータを提供するコンピュータやプログラム`のことです。
サーバの由来はServeから来ています。つまり、何かを与える(Serve)存在という意味があります。

ちなみにですが、サーバーの対義語は __クライアント__ になります。サーバーが与える側であるのに対して、クライアントは要求する側になります。そのため、我々が普段使用するコンピュータは、サーバーに対して要求を送るクライアントであることが多いです。

# サーバーの種類
サーバーはその役割から色々な種類に分類されています。ここではそのうちの4つを紹介します。
### ①DNSサーバー
DNSとは、Domain Name Systemの略で、DNSサーバーの役割はその名前の通り、__ドメイン名とIPアドレスを変換する__ 仕組みを提供することです。
IPアドレスとは、スマホやPCのようなネットワーク上の機器に割り当てられるインターネット上の住所のようなものです。インターネット上でページの閲覧をしたり、メールの送受信に使われるのがこのIPアドレスです。IPアドレスは数時の羅列であるため、人が覚えづらくどういったサイトの住所であるのかもわかりません。それを人が理解しやすい内容にしたものがドメイン名です。
機械が理解できるが人が理解できないIPアドレスと、人が理解できるが機械が理解できないドメイン名。この2つを変換する役割をこなすのがこのDNSサーバーです。

### ②Webサーバー
Webサーバーとは、PCやスマホといった端末からHTTP/HTTPSで送られてきたリクエストに対して、__HTML/CSS/JavaScript などの情報を提供する__ 役割を持ったサーバーです。


### ③ファイルサーバー
ファイルサーバーとは、__ネットワークを通してファイルの保管や共有を行う__ ためのサーバーです。社員同士のやり取りをするために、多くの企業で使用されています。

### ④メールサーバー
メールサーバーとは、__メールの送受信の役割__ を担うサーバーのことです。
メールを送信すると、次のような流れで相手まで送られます。
送信者 → 自身のメールサーバー →　DNSサーバー(送信先の住所を調べる) → 相手のメールサーバー → 受信者

# サーバーとコンピュータの違い
サーバーとコンピュータの構成上の違いはほとんどありません。どちらもCPU、メモリ、HDD等から構成されています。しかし、サーバーは特に __長期間安定して稼働することが求められる__ ため、特別なパーツを使用されています。 
また、「止めることができない」システムに使用されることからCPU、メモリ、HDD、電源等を多重化することで、瞬時にスタンバイ用のパーツに切り替えられるように設計されています。

# 終わりに
サーバーはシステムの中で非常に重要な役割を担っています。サーバーについて学習することはシステム構築に役立つと思いますので、もし興味があれば調べてみてください。
Accessのフォームでフォーカスが当たっているオブジェクトの情報（名前など）を取得

# やり方

```ActiveControl``` っていう名前のオブジェクトが情報持ってる。

```vb:フォーカス中のオブジェクトの名前確認サンプル
Debug.print Me.ActiveControl.Name
```

VBE上でCtrl + スペース押して候補出せば色々情報持ってるのが分かる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/79173abc-b3d2-0fdd-d300-711b02c6337b.png)

# 参考サイトさん

https://tsware.jp/tips/tips_070.htm

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311
Microsoft Access for Microsoft 365 MSO (バージョン 2209 ビルド 16.0.15726.20188) 32 ビット
『システム運用アンチパターン』輪読会 12章「多すぎる尺度」


## はじめに

**12.5 本章のまとめ** にまとまってた。

> * 目標は組織全体に波及します。
> * 適切なタスクを実行するためには、仕事を分類し、優先順位を付ける必要があります。
> * 緊急度と優先度によって仕事を分類しましょう。
> * チームが保留中のしごとや進行中のしごとを把握できるように仕事を整理する必要があります。
> * 予定外の作業は混乱を招くため、特定し、追跡し、可能な限り減らす必要があります。


---

## 12.1 目標の階層

### 要約

この3つの要素があって、上位から波及して決まる。

1. 組織全体の目標: 経営層により設定。ハイレベルなもので、戦略を定めたもの
1. 部門の目標: 組織全体の目標から決められる
1. チームの目標: 部門の目標からチームの目標が決まる

**組織・部門の対応関係のイメージ**

| 部門の目標                             | 組織の目標            | 
| -------------------------------------- | --------------------- | 
| ソフトウェアのバージョン2.0を発売する  | 加入者数の前年比20%増 | 
| データパイプラインプロセスの再構築     | 既存顧客の支出10%増   | 
| 請求書作成プロセスのパフォーマンス向上 | 運用コストの15%削減   | 

Q. 頻繁に変更されるとか、目標が分からなかったらどうすればいい？
A. マネージャーに聞こう！ シニアの誰かは知ってるはずだし、混乱している場合でも解決に向けて動き出せるかも。それでも解決しない場合は**文化チーフ**（11章）に聞こう

---

### 感想

↑と見比べると、現状では職能別組織でプロダクト戦略と繋げきれてない感がある。
こうなりたい。

* マーケティング全体でこうあるべきだから、それをブレイクダウンしたプロダクト目標を持つ
* プロダクト目標を分解して、職種ごとの目標を持つ

---

## 12.2 どの仕事に取り掛かるかに意識的になる

### 要約

「本質的でない仕事の断り方」と思って読むといい。

* 「本質的」はどう判断すればいい？
* どんなとき断っていい？

**①「本質的」はどう判断すればいい？**

著者はこんな判断手順を想定しているらしい。

1. まずはマネージャーと**優先事項**を決めて、それに関連する行動を自分のキャパシティの中に突っ込もう
1. 他の仕事は**緊急度**と**重要度**のマトリクスで取り組む課題を決めよう

緊急度と優先度は混同されやすい

**②いつ断っていい？**

新しいコミットメントを約束したときに、次の点をチェックして、ダメなら断ろう。

* 「優先事項を時間通りに提供する」ことに影響を与えるか？
* 新しい優先事項になる可能性があるか？
* 優先事項の期限を再調整する必要があるほど重要か？

タスクを引き受けて実行しないより断るほうがプロとしてあるべき姿だ（←ド正論）

---

### 感想

「優先事項」を決めて、そこへの影響で考えるって発想は無かったので面白い。
ただ、そのために「目標の階層」がしっかりしてるっていう前提がありそう。
我々のKPIマネジメントとも相性よさそう。

---

## 12.3 チームの仕事を整理する

### 要約

だいたい「jiraを用意して、（スクラムの意味での）スプリントを回そう。スプリントの間はできるだけその作業に集中しよう」という内容。

### 感想

一度自分たちのチームでも「やるべきことのリストアップ」をやるべきかも。



---

## 12.4 予定外の作業

### 要約

同僚から依頼され、30秒の作業だと思ったものが、想像以上の時間がかかることはよくある
コンテキストスイッチはつらい。別の作業から元の精神状態に戻るには、15分から30分かかる

予定外の作業は混乱を招くため、特定し、追跡し、可能な限り減らそう。

**①人からの割り込み**

つらいときは正直に断って、「30分後や60分後なら話ができる」とフォローアップするのが効果的。
割り込みをする人は、自分のニーズをできるだけ早く解決しようとして、無意識的にやっちゃう。

**②システムからの割り込み**

原因を分類して対策しよう。6章の「アラート疲れ」や3章のメトリクスの話も参照。

---

### 感想

宣伝ですが、緊急性の低いものは、[フォーラム](https://www.lifull.blog/entry/2022/02/24/100000)使って割り込みしないようにするのが有効的かも
フォローアップを使った断り方は言語化してなかったけどやってたかも。
【Linux】特定の文字列を検索して行番号のみを取得する方法

## 取得方法

`sed`コマンドを使用して以下のように実行することで行番号のみを取得できます。  

```terminal
sed -n '/検索する文字列/=' sample.txt
```

以下のような内容で`sample.txt`を作成します。  

```txt:sample.txt
12345
あいうえお
12345
あいうえお
12345
あいうえお
12345
あいうえお
12345
あいうえお
```

`1`が含まれる行の行番号を取得するために以下のコマンドを実行します。  

```terminal
$ sed -n '/1/=' sample.txt
1
3
5
7
9
```

上記のように`1`が含まれる行番号のみを取得できました。
ECS FargateでRolling Update

# Rolling Updateのサンプル
CDKでできるだけ小さいrolling updateのサンプル

コードはこちら https://github.com/tky/ecs-fargate-rolling-update/tree/pure_rolling_update

## 参考サイト
- https://github.com/toku-shun/ecs-fargate-rolling-update-demo
- https://github.com/kimisme9386/lab-ecs-fargate-cd-infra
- https://chariosan.com/2021/04/18/aws_cdk_vpc_endpoint/
- https://dev.classmethod.jp/articles/codepipeline-support-ecs-deploy/

## 作成

VPC作成
load balancerようにpublic subnetを、container起動用にprivate_isolated subnetをつくります。
private_isolatedなのでデプロイするためにはvpc endpointが必要です。

```
$ cdk deploy ecs-fargate-rolling-update-vpc-stack
```

ECR作成

```
$ cdk deploy ecs-fargate-rolling-update-ecr-stack
```

ECRにイメージをpush
applicationにサンプルのnginxがあるのでimage作ってpushしましょう。

```
$ export PROFILE=<YOUR_AWS_PROFILE>
$ ./upload.sh
```

ECS作成

```
$ cdk deploy ecs-fargate-rolling-update-ecs-stack
```

ここまででApplication LoadBalander経由でサンプルページにアクセスできます。

CodeCommit作成

```
$ cdk deploy ecs-fargate-rolling-update-code-commit-stack
```

CodeCommit作ったらファイルをapplicationの下にあるファイルをPushします。
ファイル３つしかないのでaws consoleから手動で上げましょう。


Pipeline作成

```
$ cdk deploy ecs-fargate-rolling-update-pipeline-stack
```

これでCodeCommitのファイル編集するとPipelineが起動します。
【TIPS】Colorize the output of -x in bash.

ま小ネタなんですが、bashに`-x`オプションを付けてシェルスクリプトをトレースする際、プロンプトを色付けすると見やすくていいですね。というハナシ。

```run.sh
set -uxe
export PS4='\e[1;34m\]+ (${BASH_SOURCE}:${LINENO}): ${FUNCNAME:+$FUNCNAME(): }\[\e[m\]'

ls
date
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28376/cc4942cc-9aee-f555-309e-f7319946d1ed.png)

`-v` の出力の色付けは読者への課題とする。
【JS】メールアドレスのマスキング処理

# はじめに
よくある会員登録のフローで、ユーザーが入力したメールアドレスに認証コードを送ります。

その際result画面では、第三者に見られないために、アドレスの一部を隠す必要があります。

今回は次のように、登録したメールアドレスの二桁目から'@'の直前までを*に置き換えます。

「t***************@gmail.comに認証コードを送信しました。」

# 実装

流れとしては、以下になります。

1.　split()でメールアドレスを一桁ごとに分割する
2.　for文で'@'がでるまで、*に置き換える
3.　join（）でまとめる


```js
        let data = 'test123456789012@gmail.com'
        data = data.split('')
        for (var i = 1; i < data.length; i++) {
            if (data[i] == '@') {
                break
            }
            data[i] = '*'
        }
        data = data.join('')
```



画面には以下のように表示され、無事一件落着です。
![スクリーンショット 2022-11-21 15.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1175390/90c4db4b-8bf8-330b-a690-e5a7e6557a1e.png)
nodejs mysql 複数クエリ (multiple query) を使う方法

# Code
`nodejs` + `mysql` で複数クエリを使用しようとしたところ、エラーが発生して解決するのに時間がかかった。
方法は単純で`multipleStatements: true`をちゃんと設定として加えておくこと。

```javascript:server.js

const mysql = require('mysql');

const con = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'database_name',
    multipleStatements: true
});

```

```javascript:server.js
app.get('/users/:id', (req, res) => {
    var user_id = parseInt(req.params.id)

    const sql_1 = `select * from users where users.id = ${user_id} ; `
    const sql_2 = `select * from works where works.user_id = ${user_id} ;`

    con.query( sql_1 + sql_2, function (err, result) 
{
        console.log(result[0])
        //users data

        console.log(result[1])
        //works data

        res.render('users_detail.ejs', { users: result[0], works : result[1] })
    })
})
```
# 関連
https://stackoverflow.com/questions/23266854/node-mysql-multiple-statements-in-one-query
supabase auth のユーザーを一括削除する

# 概要

supabasae cli を用いてローカル環境を用意しているとき、開発環境用に作成した Auth Users を都度削除したくなった。

# バージョン

- supabase cli: 1.4.7
- @supabase/supabase-js: 2.1.0 

# 結果

ちょっと公式ドキュメントだけだと分かりづらかったけど以下の感じに。

```js
import { createClient } from '@supabase/supabase-js'

const supabaseClient = createClient(process.env.SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY)

await supabaseClient.auth.admin.listUsers().then(async res => {
  await Promise.all(res.data.users.map(user => supabaseClient.auth.admin.deleteUser(user.id)))
})
```

大事なのは `auth.admin` がサーバー向け機能であるため、 `createClient` の第二引数には `service_role key` を設定する必要があること。

ローカル環境の `service_role key` は `supabase status` から確認できる。

```bash
$ supabase status
supabase local development setup is running.

         API URL: http://localhost:54321
          DB URL: postgresql://postgres:postgres@localhost:54322/postgres
      Studio URL: http://localhost:54323
    Inbucket URL: http://localhost:54324
        anon key: hogehoge
service_role key: fugafuga
```
テスト77

```vb

Sub MergeCell_Del()

'PDFからExcelに変換後、余計な結合セルがあった場合の
'削除方法....〆(・ω・｀ )ｶｷｶｷ
Dim cnt As Integer

With ThisWorkbook.Sheets("DB")
    '指定の項目が結合セルだった場合
    If .Range("I1").MergeArea.Columns.Count >= 2 Then
        
        cnt = .Range("I1").MergeArea.Columns.Count - 2
    
        .Range(.Columns(10), .Columns(10 + cnt)).Delete
        
    End If

End With

End Sub

'メモ
'テーブル → クエリ → フォーム/レポート
'1、データ(テーブル)部分だけを別のAccessファイにする
'　 Accessにおいて「データ」部分を別のAccessファイルにしておけば、複数人でデータを共有できる
'2、1を元にして、本体の方にリンクテーブルを作成する
'3、テーブル選択→作成タブ→フォーム、その他のフォーム、分割フォーム
'4、書式の統一(左上の+)
'5、配置→レイアウトの削除

''Accessのタブコントロールでタブを変える時に発生するイベント
''Form_タブフォーム内のイベント
'Private Sub テスト1_Change()
'
'MsgBox Me.テスト1.Pages(Me!テスト1.Value).Name
'
'End Sub
JavaScriptで多次元配列をコピーしてシャッフル（っぽいこと）

# 編集履歴
2022年11月22日：　コメントでご指摘いただいたので取り急ぎタイトル変えました！　記事内容も追々編集します！
2023年8月14日：　遅まきながら、コメントいただいた分を反映しました！　半年以上たって気づいたこと（こうすればよかったんじゃない？）も追記しています。

# 前提
この記事は勉強中の覚え書きの要素が強いです。
ベストな方法かはともかく、私の場合はこのやり方でできたよ！　というものですが、同じことで困っている人にもし役立てばうれしいです。
もっと良い方法あるよ！　って場合はぜひコメントください。

# とりあえずコード
```javascript:test.js
function shuffle(list){
	let copyList=[];
	for ( i = list.length - 1; i >= 0; i--) {
		copyList.push(list[i]);
	}
	for ( i = copyList.length - 1; i >= 0; i--) {
		const r = Math.floor(Math.random() * (i + 1));
		const tmp = copyList[i];
		copyList[i] = copyList[r];
		copyList[r] = tmp;
	}
	return copyList;
}

const wordList = [["test","テスト"],["array","配列"],["copy","コピー"]];
let copyList = shuffle(wordList);
```

うーんこのゴリ押し。
新しく配列作って、pushで要素入れて、シャッフル。
前半のpushの時点で元の順序と逆になってるのは後でシャッフルするからいいか～という気持ちの表れです。
シャッフル部分は先人の方々のコードをマネしています。

# ここまでにいたる道筋

## 何のためにこのコード書いてるの？
勉強がてら作っているタイピングゲームのためです。コピーした配列からpopで取り出しても、元の配列はそのまま残ってほしくなったので。
1. タイピング対象の英単語と、一緒に表示する日本語訳を配列に入れたぞ！　とりあえず片手で足りる数入れてテストするぞ！
2. シャッフルして表示、正しく打てたら次の単語に移るのはできたけど、単語が尽きた後どうしようか。
3. 今後単語数増やしても全部打ち尽くされる可能性はあるし、最後まで行ったらまたシャッフルして入れなおそう！
4. あっ、popで配列から単語を取り出してたせいで、中身が全部なくなってシャッフルも何もできない！　元の配列からも取ってこれない！　なんでだ？
5. （調べた）ふむふむ、元の配列からコピーしてるんじゃなくて、参照先を同じにしているだけなのね。だから元の配列も空になってたんだな（ざっくり）

### ↑のとき書いていたコード
```javascript:test.js
function shuffle(list){
	for ( i = list.length - 1; i >= 0; i--) {
		const r = Math.floor(Math.random() * (i + 1));
		const tmp = list[i];
		list[i] = list[r];
		list[r] = tmp;
	}
	return list;
}

const wordList = [["test","テスト"],["array","配列"],["copy","コピー"]];
let copyList = shuffle(wordList);

//copyListからpopで取り出して表示したりとか、キーボード打った時の動作とか

//copyListが空になったらまたシャッフルして入れなおそうとした
if(copyList.length == 0){
    copyList = shuffle(wordList); 
}
```

## 試してみてうまくできなかったやり方
調べる中で[map()メソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)があると知りましたが、今回うまく使えませんでした。


# 以下、2023年8月14日追記
## コメントで教えていただいたこと
### スプレッド構文
[MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)

自分用かみ砕き：配列とか文字列とかオブジェクトの中身を全部展開します。例えば、配列の中身を全部足し算したい！というときにも使えます。

元の配列からcopyListに値を全部コピーするならこれ1行で済みました。
```javascript:test.js
const copyList = [...list];
```
ドキュメントによると、1次元配列ならこれだけで元の配列を破壊せずに済むようです。
多次元配列だと、コメントにもあったように、copyList内の要素を変更すると元の要素にも影響が出るようですね。

### 分割代入
[MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
自分用かみ砕き：配列内の要素をそれぞれ左辺の変数とかに分けて入れます。便利！

ドキュメント内の「変数の入れ替え」の項目で書かれている、分割代入を使わずに入れ替える方法（一時変数を使う）が、記事内のコードでやっていた方法ですね。

## 後になって気づいたこと
popで取り出すから困るのであって、取り出さずに参照する方法でもできたのでは？　そっちのほうがコピー配列を作らずに済んでスマートでは？　と気づきました。
その辺は書くとしたら別記事にします。
とは言え、コピーする方法を試したことで記事を書いてコメントで知見を得れたので結果オーライだと思ってます。
login実装時の注意点

login機能作成を何度も行なっているが、つまりやすい部分について解説する



login.php
```php

session_start(); //セッションスタート
require_once('common/function.php');  //commonファイルのfunction.phpを接続する
if(!isset($_SESSION['csrf_token'])) {  ///csrf_token変数に値が入っているかどうかを確認するためのisset関数
  $_SESSION['csrf_token'] = random();  //ランダムにsessionが変わるごとにcsrf_tokenが発行される。
}



<form class="login-container"  method="POST" action="login_act.php">
        <p><input type="text" name="account" placeholder="Id"></p>
        <p><input type="password" name="password" placeholder="Password"></p>
        <p><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']?>"></p>   <!-- csrf_tokenを送る -->
        <p><input type="submit" value="Log in"></p>
</form>

```


login_act_php

```php

<?php
//最初にSESSIONを開始！！ココ大事！！
session_start();  //セッションスタート
require_once('common/function.php');  //commonファイルのfunction.phpを接続する

if(!isset($_SESSION['csrf_token'])) {  ///csrf_token変数に値が入っているかどうかを確認するためのisset関数
  $_SESSION['csrf_token'] = random();  //ランダムにsessionが変わるごとにcsrf_tokenが発行される。
}

//データベース接続したものを$pdoに入れる(function.phpにあり) 
$pdo = db();

// ①新規作成 start このページにアクセスしたら、
// ポストデータを取得する。
if(isset($_POST["account"]) || isset($_POST["password"]) || isset($_POST["csrf_token"])) {  //変数に値が入っているかどうかを確認するためのisset関数
    if($_POST['csrf_token'] !== $_SESSION['csrf_token']) {  //csrf_tokenと$session[csrf_token]が一致しないなら
        echo "このサイト以外からのアクセスは禁止しています。";  //このサイト以外からのアクセスは禁止しています。を出力する。
        exit; //終了
    }
    $account = $_POST["account"];  //$idを受け止める
    $password = $_POST["password"];  //$passwordを受け止める 

    try {//try〜catchすることができる。
      //途中で何かしらのエラーが起こしたら、その場で処理が止まって、catchより以下がエラーで返却される。
      //catchされず、滞りなく進むとそのままで良い

      // トランザクション開始(ロック)...何かの処理をひとまとめにした状態で、何か処理をする中で処理が失敗した場合に最初からやり直すという意味
      // 「データを登録」「デルウータを更新」「データ削除」などのデータの内容変更がある場合にトランザクションを使用する
    $pdo->beginTransaction();

      // データを登録するSQL
    $stmt = $pdo->prepare("SELECT * FROM users WHERE account = :account"); 

      // 値をセット
      // バインドパラムでセットする
      $stmt->bindParam(':account', $account, PDO::PARAM_STR);
  
      // SQL実行
      $res = $stmt->execute();

      $user = $stmt->fetch(PDO::FETCH_ASSOC); 

      // コミット
      if( $res ) {
        $pdo->commit();
      }
      //ここでトランザクション終了。
  
     } catch(PDOException $e) {
  
      // エラーメッセージを出力
      echo $e->getMessage();
      
      // ロールバック
      $pdo->rollBack();
    }


    //5. 該当レコードがあればSESSIONに値を代入
    if( password_verify($password ,$user["password"])){  //password_verify指定したハッシュがパスワードにマッチするかどうかを調べます。

        //Login成功したら、session_id,name,brithなどを持たせてwait_ad_list.phpへ
        $_SESSION["chk_ssid"]    = session_id();  //自分のsession.ID
        $_SESSION["id"]          = $user['id'];  // idを持たせる
        $_SESSION["name"]        = $user['name'];  //nameを持たせる
        redirect("wait_ad_list.php");
     }else{
        echo  "login情報が違っています。";
     }
     exit();
}


?>

```


1.login.phpの「session start」が入っているか確認。
2.login_act.php「」の「password_verify」で詰まりやすいので注意
　　　　エラーになった場合は、直前の行で、
　　　「var_dump();」で変数に自分の想定しているものが入っているか確認する
3.　,$user["password"]が「var_dump();」ハッシュ化されているか確認
　　　　　ハッシュ化されていない場合は、ハッシュ化する
【Swift】フォアグラウンド、バックグラウンドに入ったのを検知


## はじめに
`viewWillAppear`で日付を取得し、ラベルに表示させていました。アプリをキルしない状態で日付を跨ぐと画面の切り替え等を行わない限り、`viewWillAppear`は呼ばれないためUIが更新されない問題が発生しました。
`viewController`のライフサイクルにはフォアグラウンドやバックグラウンドになる時に呼ばれるものは存在しないため、別の角度からUIを更新できるようにします。

※間違った認識等あれば、ご指摘いただけると幸いです。

## 解決策
アプリをキルしないユーザーは一定数存在しているため、解決策として`NotificationCenter`を使い、フォアグラウンドに入った時を検知して特定のUIを更新する処理を実装する。
ほぼ同じ処理なので、バックグラウンドになった時も合わせて記載しています。

※`NotificationCenter`がよく分からない人は使用頻度が高いので調べてみるといいと思います。

https://qiita.com/ryo-ta/items/2b142361996657463e5f

## フォアグラウンド、バックグラウンドに入った時に通知を受け取る
`NotificationCenter`でフォアグラウンド、バックグラウンドになったのを以下で検知します。
フォアグラウンド：`UIApplication.willEnterForegroundNotification`
バックグラウンド：`UIApplication.didEnterBackgroundNotification`
```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // アプリがフォアグラウンドに入った時に呼ばれる
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(viewWillEnterForeground(_:)),
            name: UIApplication.willEnterForegroundNotification,
            object: nil
        )
        // アプリがバックグラウンドに入った時に呼ばれる
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(viewDidEnterBackground(_:)),
            name: UIApplication.didEnterBackgroundNotification,
            object: nil
        )
    }
}
```

## 実行したい処理
以下の関数を定義して、実行したい処理を記載していきます。
```swift:ViewController.swift
    @objc func viewWillEnterForeground(_ notification: Notification?) {
        if (self.isViewLoaded && (self.view.window != nil)) {
            // 実行したい処理を記載(例：日付ラベルの更新)
        }
    }
    @objc func viewDidEnterBackground(_ notification: Notification?) {
        if (self.isViewLoaded && (self.view.window != nil)) {
            // 実行したい処理を記載
        }
    }
```

他にも`UIApplication`でアプリの状態を検知できるメソッドがあるので、Apple公式の以下をご参考ください。

https://developer.apple.com/documentation/uikit/uiapplication


## 参考
https://qiita.com/kijibato/items/a0b9b956f7a9a35dcf1d

https://qiita.com/tosh_3/items/df52802514cc9737e75b
【初心者向け】Flutter製Webアプリを公開する方法

# ゴール
- Flutterで開発したWebアプリをGithub Pagesで公開🎉

# 手法
- Github Actions🎬を使ってGithub Pagesに公開

# GitHub Actionsとは
- GitHubに公開されたコードを自動でビルド・テスト・デプロイを行うツール🔧
- 今回はアプリのビルド・デプロイに使う。
- リポジトリの .github/workflows以下にYAML形式の設定ファイルを記述することで設定を行う。

# 設定ファイルを記述
1. まず、「.github/workflows」と名前をつけて新しいフォルダを作る。（または.githubというフォルダを作り、その中にworkflowsというフォルダを作る。）
2. その中にgithub-pages.ymlというファイルを作成する。
3. https://zenn.dev/nekomimi_daimao/articles/26fd2e3b763191 の一番上に記載されたコードをコピーして貼り付ける。
4. 赤線で囲ったflutter-versionを自分のアプリと揃える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/6062cc00-3f8a-0276-4990-8a1e1b912e28.png)

# Githubにプッシュ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/4985d4b8-5ce9-9295-29b6-0c79ffc30ab0.png)

# Githubにアクセス 
- Actionsタブを選択。
- 先ほど追加したGithub Actionが実行されている。
- インジケーターが緑になったら完了✅

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/b6ed420d-58d1-514a-55b2-8853a7b3d9ed.png)

# Github Pagesの設定
- 先ほどのActionによって生成された「gh-pages」ブランチを選択。
- Save💾

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/c61d3b7d-e25c-5b85-8ad0-ea4b18ffa830.png)

# 再びActionsタブを確認 
- Github Pages公開のためのActionが実行されている。
- インジケーターが緑になったら完了✅


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/8b284675-165e-c3c6-b90f-5a53a77b054a.png)

# 公開したサイトにアクセス
- もう一度Settingタブを選択し、「Visit site」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/36b3c583-3cdd-6ce6-fc3f-d1beb249a1a3.png)

# 流れを振り返り
- .github/workflowsにgithub-pages.ymlを追加。
- Githubにプッシュ。
- 先ほど追加したGithub Actionsが実行される。
- Github Pagesの設定ページでgh-pagesブランチを選択して公開。
- Github PagesのGithub Actionsが実行される。
- 公開完了。

# 参考にした記事 
https://zenn.dev/nekomimi_daimao/articles/26fd2e3b763191

---

ご覧いただきありがとうございました。

🐦 [Twitter: @shota_appdev](https://twitter.com/shota_appdev)

📱 [個人アプリ: Symbols Explorer](https://apps.apple.com/jp/app/symbols-explorer/id1612933742)
Staticを超絶簡単にまとめてみますた

## はじめに
Staticに関して簡単にまとめてみた。また、Staticキーワードと同じような概念にClassキーワードというものがある。先に両者のキーワードの違いを下記にまとめる。

| 比較項目 | Static | Class |
| :--- | :---: | :---: |
| オーバーライド | NG | OK |
| ストアドプロパティの定義 | OK | NG |
| コンピューテッドプロパティの定義 | OK | OK |


## Staticプロパティとは
- Static（スタティック）は静的であり、タイプ（型）とも呼ばれる。
    → スタティックプロパティ = タイププロパティみたいな感じ
- インスタンスを作らなくてもアクセスできる。
    →逆に言うと、インスタンス単位でアクセスすることができない。＝　値の変更は可能だが、再度初期化することができない
    →インスタンスを生成する必要がないため、メモリ消費を抑えることができる
- static var は「静的変数」と呼ばれ、すべてのプログラムが終了するまで一貫してその値を保持し続ける。

## ソースコード
１、Staticの動き方
```swift:Swift
class Noodle { //クラスはあくまで設計図なので、まだインスタンスを持っていない
    var taste = "醤油" //普通のプロパティ
    static var topping = "焼き豚" //スタティックプロパティ
}
//インスタンス化した場合は、taste（普通のプロパティ）にはアクセス可能
//しかし、toppingはstaticプロパティなため、インスタンス化してtoppingにはアクセスできない。
let n = Noodle()
n.taste //醤油　

//Staticプロパティは、インスタンス化をしないでtoppingにアクセス
Noodle.topping //焼き豚　←クラス単位ではアクセス可能
Noodle.topping = "焼き豚から値を変更する" //値の変更
Noodle.topping //焼き豚から値を変更する
```

２、静的（Static）と動的の動き方の比較
```swift
//まずは動的の検証
//動的変数は関数内で何度も初期化できるため、関数が終了するとその存在もメモリ上から消滅する
class Dynamic {
    func dynamic() {
        //動的変数を宣言し、値を0で初期化
        var menma_count = 0
        menma_count += 1
        print("メンマは\(menma_count)本入っています。")
    }
}
let d = Dynamic()
//関数を実行するたびにメンマの数が１本ずつ増えると思っていたが増えない。
//なぜなら、関数を実行するたびにmenma_count = 0で内部を初期化してしまうため。
d.dynamic() //メンマは1本入っています。
d.dynamic() //メンマは1本入っています。
d.dynamic() //メンマは1本入っています。

//上記を踏まえ、static(静的)変数とdynamic(動的)変数の両方をMixクラス内で作成し、挙動を比べてみる。
class Mix {
    //static(静的)
    static var sNum = 0
    //dynamic(動的)
    var dnum = 0

    //実行するたびに数字を1カウントしていく関数
    func sCount() {
        //static変数はインスタンスを生成しないため、sNumの宣言にはClass名からアクセス
        Mix.sNum += 1
        print("Mix.sNumの値は：\(Mix.sNum)")
    }

    //こちらも実行するたびに数字を1カウントしていく関数
    func dCount() {
        dnum += 1
        print("dNumの値は：\(dnum)")
    }
}

//インスタンス化1回目
var result1 = Mix()
//各々関数にアクセス
result1.sCount() //Mix.sNumの値は：1
result1.dCount() //dNumの値は：1

//インスタンス化2回目
var result2 = Mix()
//各々関数にアクセス
result2.sCount() //Mix.sNumの値は：2
result2.dCount() //dNumの値は：1

//インスタンス化３回目
var result3 = Mix()
//各々関数にアクセス
result3.sCount() //Mix.sNumの値は：3
result3.dCount() //dNumの値は：1

//要は、static変数を有する関数(sCount)を何度インスタンス化しても値は0で初期化されず、前回の値を引き継いだまま増えていく。ということは、「インスタンス化」するときに初期化は１度しか行われず、値は変わったら変わりっぱなし。
//逆に動的変数は、動的変数を有する関数（dCount）をインスタンス化するたびに値は0で初期化され、0に初期化されたところからカウントする。（上記のdCount関数を例にあげています）
```

## おわりに
定期的に復習しないとと分からんくなる。

## 参考記事
[Swiftのstatic、classキーワードの違いについて
](https://qiita.com/shtnkgm/items/b1cdedc1c7d4bfe6e9fe)

[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)　
↑引用元
石川 洋資 (著), 西山 勇世 (著)
発行者：片岡 巌
出版社：技術評論社
印刷/製本：日経印刷株式会社

## 開発環境
- Xcode-13.4.1
- Swift version 5.7
【AWS】インスタンスプロファイルとは？

## はじめに
業務でインスタンスプロファイルを触る機会があったので、覚えるためにに記事としてアウトプットしたいと思います。

## インスタンスプロファイルとは？
- EC2インスタンスにAWSの操作権限を与えるために必要なものになります。
- IAMロールが付与されているインスタンスプロファイルをアタッチすることで、EC2インスタンスに権限を付与することができます。

権限付与のイメージとしては、以下になります。

![instance profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/1096b79c-07d4-812a-7588-802937e94bdb.png)

## EC2 Instance への設定方法
### 1.IAM Dashboard にて IAMロール を作成する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/a593355c-8ba2-6d8a-bfbb-b57111d40a5c.png)

以下のように設定する。

|  項目  |  設定内容  |
| ---- | ---- |
|  ロール名  |  任意のロール名  |
|  信頼されたエンティティタイプ  |  AWSのサービス  |
|  ユースケース  |  EC2  |
|  許可ポリシー  |  任意のポリシー  |

IAMロールを作成する方法についての詳しい説明は、以下のURLをご覧下さい。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_create_for-service.html#roles-creatingrole-service-console

### 2.EC2インスタンスに作成したIAMロールをアタッチする。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/69956847-c68a-7a60-bdd7-bfecd3417a11.png)

IAMロールを作成するとインスタンスプロファイルが自動で生成される。
以下のURLの手順を参考に、インスタンスプロファイルをEC2インスタンスに付与する。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/attach-replace-ec2-instance-profile/

## 参考
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html

https://dev.classmethod.jp/articles/do_you_know_iaminstanceprofile/
着手する施策に迷ったらICEスコアリングを使うと良いと言う話

## はじめに
プロダクトを作っている組織であれば、必ずぶつかる問題として「施策の優先順位」があると思います。
やった方が良いもの/やらなくて良いものが明確な場合はただ施策を選ぶだけなので簡単ですが、大体多くの場合は、「どれもやった方が良い施策」でバックログが溢れ返り、どれかをやるとどれかができない、という状態で頭を悩ませることの方が多いはずです。
この記事では、施策の優先順位を決めるためのフレームワークとして、「ICEスコアリング」という手法を紹介します。

## ICEスコアリングとは
ICEスコアリングの「ICE」は、以下の頭文字を取ったものです。

- I→Impact（どれだけ施策に影響があるか）
- C→Confidence（どれだけ施策が当たりそうか）
- E→Ease（どれだけ簡単に実施できるか）

そして、これらの評価に基づいて施策を10段階で評価し、スコアリングしたものがICEスコアリングです。

```math
ICE Score = Impact * Confidence * Ease
```

このスコアが高いものから優先的に取り組んでいくことで、施策の優先順位を一意に決めていくことができます。

こちらのスコアの考え方は[Hacking Growth](https://www.amazon.co.jp/Hacking-Growth-%E3%82%B0%E3%83%AD%E3%83%BC%E3%82%B9%E3%83%8F%E3%83%83%E3%82%AF%E5%AE%8C%E5%85%A8%E8%AA%AD%E6%9C%AC-%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%B3%E3%83%BB%E3%82%A8%E3%83%AA%E3%82%B9/dp/4822255824)という本の著者でもあるSean Ellisさんによって提唱された手法です。

## スコアの付け方
ICEスコアリングは考え方はシンプルですが、それぞれの要素にどのような基準でポイントをつけていくかするかは特に決まっておらず、各組織で決めていく必要があります。
重要なのは同じような施策が同じようなポイントになっていることです。つまり過去の数値を参考にしてポイントを付与していくことで、より精度の高いスコアリングが可能になっていきます。
これはスクラムにおけるストーリーポイントと近しい性質があると思っています。
スクラムのプラクティスと同じく、プランニングポーカーなどで点数をつけていくのもおすすめです。

簡単に計算をしてみたいと思います。

まず、各要素のポイントを以下のような重みとして定義します。
- Impact
    - 1: KGIの数値に影響なし
    - 10:KGIの数値が数十パーセント向上する
- Confidence
    - 1: 全く予測できない
    - 10: ユーザーインタビューや過去の経験から必ず当たる確信がある
- Ease
    - 1:（メンバー全員投下して）リリースまで数ヶ月かかる
    - 10:（メンバー全員投下して）1日でリリースまで完了できる

そしてそれぞれの施策A,B,Cを以下のように評価します。

|  | Impact | Confidence | Ease | Score |
|:-:|:-:|:-:|:-:|:-:|
| A  | 5  |  5 | 5  | 125 |
| B  | 10  | 2 | 1  | 20 |
| C  | 2 | 10 | 10 | 200 |

スコアの計算をした結果、Cが一番高くなったので、インパクトは少ないが確実性と容易性が高いCの施策に取り組むと良いことがわかります。


スコアの付け方については以下の記事も参考になったので、ぜひ参考にしてみてください。

https://note.com/kosukemori/n/n72245be6bfdc


## RICEスコアリング
ICEスコアリングの派生として、「RICEスコアリング」と呼ばれる手法もあります。こちらはイメージで言うとICEスコアリングにおける「インパクト」を「一人当たりに与えるインパクト（Impact）」と「インパクトを与えられるターゲットユーザー数（Reach）」に分けてスコアリングを行う手法です。計算式は以下のようになります。RICEスコアリングではEが「Effort」になり、逆数の計算（数値が大きければ大きいほど工数が大きい）となりますが、ICEスコアリングと同じく「Ease」で計算しても問題ありません。
ICEスコアリングにR（Reach）を加えた計算式は以下の通りです。


```math
RICE Score = Reach * Impact * Confidence * Ease(or\ 1/Effort)
```



## 最後に
実際の施策に取り組む際は各指標の評価は今回のように簡単ではないことが多いと思いますが、このようなスコアリング手法を用いることで、ある程度の優先順位づけ判断を行うことが比較的容易になります。
着手する施策に迷ったら、ぜひICEスコアリングやRICEスコアリングを使ってみてください。

Qiita JobsでDevトークも掲載していますので、もしご興味あれば「話したい」をよろしくお願いします。

https://jobs.qiita.com/employers/qiita-inc/dev_talks/3


## 参考文献
- https://note.com/kosukemori/n/n72245be6bfdc
- https://postd.cc/finding-winning-ideas-using-the-confidence-tool/
- https://en.wikipedia.org/wiki/Sean_Ellis_(entrepreneur)
自己紹介(初投稿)

# はじめに
こんにちは。こちらの記事がQiita初投稿です。


# 自己紹介
・2019年3月文系私大卒業、その後不動産会社に入社
・上司と全く合わず、半年で退社
・完全未経験からSESの会社にインフラエンジニアとして入社
・1年半ほど経験した後、2021年7月より自社開発企業に運用監視エンジニアとして入社
・今後はAWSエンジニアとして転職することを希望

■所有資格
・Linuc level2
・AWS SAA
・ITパスポート



▼興味のある技術
・AWS
・Docker
・Ansible
・Python

# Qitta投稿を始めた理由
・今までインプットをメインだったが、今後はアウトプットもやっていきたいと思ったため。
・文章力向上のため
・学習したことを忘れないように備忘録として記録を残すため。
さいごに
初心者の方に向けて誰かの何かのお役に立てたらうれしいです。
ご覧いただきありがとうございました。
AWS CLI で SSO ログインを使用する方法

# 注意
この記事は AWS CLI に SSO を「手動」で設定するための方法です。
手動、自動の方法ともに以下の AWS 公式ページに記載があります。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-sso.html

私の環境ではなぜか自動設定ができず手動で行ったため、その際の手順をまとめます。

# AWS CLI のインストール
まずは aws cli をインストール。
ここでは方法に関しては省略するので、以下の AWS 公式ページなどを参考にしてください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

# 必要な情報
- AWS SSO ログイン情報
- AWS SSO のスタート URL（`https://{my-sso-portal.awsapps.com}/start`）
- AWS SSO のユーザーが作成されているリージョン
- AWS SSO アカウント ID

# config ファイルの編集
aws cli をインストールするとホームディレクトリに`.aws/config`が作成される。
こちらに AWS SSO アカウントの情報を追記。
以下を設定します。
```~/.aws/config
:
[profile profile-name]
sso_start_url = https://my-sso-portal.awsapps.com/start/
sso_region = us-west-2
sso_account_id = 012345678901
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json
:
```
sso_start_url : AWS SSO スタート URL を設定
sso_region : AWS SSO ユーザーが作成されているリージョンを設定
sso_account_id : AWS SSO アカウント ID を設定
sso_role_name : 使用するアカウントに割り当てているロールを選択
region : このプロファイルでログインした際に使用するリージョンを指定

# ログイン
AWS CLI をインストールした環境で以下コマンドを実行。
```
> aws sso --profile profile-name
```
コマンドの実行結果は以下。
うまくいけば勝手にブラウザが立ち上がりますが、立ち上がらない場合は結果に記載のURLにアクセス。
```
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.us-west-2.amazonaws.com/

Then enter the code:

XXXX-XXXX
```
コードを入力する画面に遷移するので、コマンド結果に記載のコードを入力します。
AWS SSO のログイン画面が表示されるのでログイン。（ログイン済みの場合はスキップされる）
最後に CLI からのログインを許可するかどうか聞かれるため Allow をクリック。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1488939/54ab9dc7-9898-7367-cbb7-d369f34f236c.png" width=50%>
以下の画面になれば成功。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1488939/c7f38566-6549-efc9-f86d-2423bdc36523.png" width=50%>

# AWS CLI 使用時
AWS CLI 使用時は以下のように`---profile`オプションをつけてプロファイルを指定する。
```
aws s3 ls --profile test
```
バージョン切り替えのコマンド絶対いつも忘れるので一覧化しとく


https://github.com/anyenv/anyenv
最近存在を知ったanyenvであれこれxxenv化したいなぁと思いつつも、すでに汚れてしまった私の環境を整理していくのは腰が重いので、最近よく使う言語のバージョン切り替えをコマンド一覧化しとく


# goenv
```bash
# バージョン確認
go version
# インストールできる一覧
goenv install -l
# インストール
goenv install {バージョン}
# 設定
goenv global {バージョン}
# 指定のディレクトリにのみ設定する場合はこちら
goenv local {バージョン}
# .zshrcは読み直そう
source ~/.zshrc
```

# nodebrew
インストールしてあれば `ls-remote` やら `install-binary` のくだりはいらない
```bash
# インストールした一覧
nodebrew ls
# インストールできる一覧
nodebrew ls-remote
# インストール
nodebrew install-binary {バージョン}
# 設定
nodebrew use {バージョン}
```

# macでjdk
```bash
# インストールした一覧
/usr/libexec/java_home -V
# インストールできる一覧
brew search openjdk
# インストール
brew install openjdk@{バージョン}
# 設定
export JAVA_HOME=`/usr/libexec/java_home -v {バージョン}`
# ちゃんと設定するならJAVA_HOMEの更新（~/.zshrc）
```

homebrewからのインストールを紹介してますが、公式アーカイブからdmgをダウンロードしてインストールした場合でも同様に `/usr/libexec/java_home` に認識され、バージョンの切り替えが可能となってます

https://www.oracle.com/java/technologies/javase/jdk15-archive-downloads.html

# あとがき
環境構築は非常に大事です
バージョン切り替えながら作業なんてよくある話なので、良い開発環境の構築を心がけましょう
僕も・・ちゃんと・・やる・・！
【Rails】accepts_nested_attributes_forを使って子モデルも保存

## まえがき
推奨されてないaccepts_nested_attributes_forを使わずに、親モデルに紐づくレコードの一括保存をしようとしたが結局うまくいかずaccepts_nested_attributes_forを使ったときの備忘録。

以下の記事を参考にしましたが、私はうまくいきませんでした。

https://zenn.dev/murakamiiii/articles/5ecefb7a58d1ef

## accepts_nested_attributes_forを使ってみる
親クラスに```accepts_nested_attributes_for :テーブル名```を追加

```ruby:event.rb
class Event < ApplicationRecord
  has_many :possible_dates, dependent: :restrict_with_exception

  accepts_nested_attributes_for :possible_dates
end
```
```ruby:possible_dates.rb
class PossibleDate < ApplicationRecord
  belongs_to :event
end
```

```ruby:eventscontroller.rb
class Api::EventsController < ApplicationController

  def create
    event = Event.new(event_params.merge(hashed_url: SecureRandom.uuid))
    if event.save
      render json: event
    else
      render json: event.errors, status: :unprocessable_entity
    end
  end

  private

  def event_params
    params.require(:event).permit(
      :name,
      :category_id,
      :user_id,
      :is_public,
      :description,
      possible_dates_attributes: %i(id proposed_at)
    )
  end
end
```

もしaccepts_nested_attributes_forメソッドを使わずに実装できる方法があれば教えていただきたいです。
ROS1 Personal Command Collection

# 【ROS1】個人的によく使うコマンド集
- OS環境: Ubuntu 20.04
- ROS環境: ROS1 Noetic
#### 目次
[ワークスペース管理](#ワークスペース管理)
[パッケージ関連](#パッケージ関連)
[ノード間通信の分析](#ノード間通信の分析)
[今流れているトピックを記録する](#今流れているトピックを記録する)
[Ubuntuでのデータの残し方](#ubuntuでのデータの残し方)
※順次更新されていく予定です。

## ワークスペース管理
- ワークスペースをROSが使えるようにパスを通す。
```
source ~/catkin_ws/devel/setup.bash
```
- ワークスペースを.bashrcに設定しておき毎回パスを通さなくていいようにする。
```
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
```
- .bashrcの設定ができたか確認する。
最後の行にsource ~/catkin_ws/devel/setup.bashが追加されているか確認できる。nano表示は[Ctrl+X]でExitする。
```
nano ~/.bashrc
```
```
gedit ~/.bashrc
```
- ROSのパスが通っているか確認。
```
echo $ROS_PACKAGE_PATH
```
## パッケージ関連
パッケージを作成
```
catkin_create_pkg packagename std_msgs rospy roscpp
```
パッケージへの移動(ROSで使用するパッケージであることが前提:CMakeLists.txtやpackage.xmlがあるディレクトリ)
```
roscd packagename
```
変更したパッケージに絞ってビルド
```
catkin_make --pkg packagename
```

## ノード間通信の分析

- 今動作しているノードの情報を表示する。
```
rosgraph
```
- 任意のノードの情報を表示する。
```
rosnode info /nodename
```
- 今アクティブなノードを表示する。
```
rosnode list
```
- 任意のノードが動作しているか確認する。
```
rosnode ping /nodename
```
- 任意のノードの動作を停止する。
```
rosnode kill /nodename
```
- 任意のアクティブなトピックの情報を表示する。
```
rostopic info /topicname
```
- 今アクティブなトピックの一覧を表示する。
```
rostopic list
```
- トピックのメッセージタイプを表示する。
```
rostopic type /topicname
```
- 任意のトピックに配信されているメッセージ内容を表示する。
```
rostopic echo /topicname
```
- ノードとトピックの関係をグラフ化する。
Node only、Node and topic(Active)、Node and topic(All)の3つの表示モードがあるので注意。グラフは保存できる。
```
rqt_graph
```


## 今流れているトピックを記録する
[rosbag](http://wiki.ros.org/rosbag)
- すべてのトピックを記録し、bagファイルとして名前(bagfile)を付けて保存する。
トピックを記録したいタイミングで以下のコマンドを実行すると記録を開始できる。

※同じファイル名で記録するとデータが更新されるので注意。
```
rosbag record -a -O bagfile
```
- 記録したbagファイルを指定しその情報を見る。
```
rosbag info bagfile.bag
```
- 記録したトピックを可視化する(roscoreが必要)。
ウィンドウが立ち上がったら表示したいトピックを右クリック>view>plotの後Configure plotで表示するデータを選択しグラフ化することができる。グラフは保存できる。
```
rqt_bag bagfile.bag
```
- bagファイルから必要なデータをcsvファイルに変換する。
ここでは、/tfトピックをcsvファイルとして名前を付けて保存している。
```
rostopic echo -b bagfile.bag -p /tf > csvfile.csv
```
- Plotjugglerを使って記録したトピックを可視化する。rosbagで記録したbagファイルを別の方法で可視化する。
インストールと実行(実行にはroscoreが必要)。
ROS環境がNoeticの場合、${ROS_DISTRO}をnoeticに変更する。
```
sudo apt install ros-${ROS_DISTRO}-plotjuggler-ros
```
```
rosrun plotjuggler plotjuggler
```
File>Load Dataで読み込むbagファイルを選択する。
左のTimeseries Listから可視化したいデータを選択しタブにドラッグ&ドロップする。
タブの上端にカーソルを合わせるとメニューバーが現れグラフを並べることができる。

[MATLABでbagファイルを読み込む場合はこちら](https://jp.mathworks.com/help/ros/ref/rosbag.html)

##  Ubuntuでのデータの残し方

- スクリーンショット
実行した瞬間に撮影。
```
gnome-screenshot
```
範囲指定
```
gnome-screenshot --area
```
ウィンドウ指定
```
gnome-screenshot --window
```
- 画面録画
[Alt+Ctrl+Shift+R]
を同時に押すことで録画開始と録画終了ができる。録画開始すると右上に録画中の表示ボタンが出る。
しかし、標準の録画時間は最大30秒である。また、保存形式はwebmファイルであり、このファイル形式でもパワーポイントに貼り付けることができる。

最大録画時間を1時間にするには以下を実行。
```
gsettings set org.gnome.settings-daemon.plugins.media-keys max-screencast-length 3600
```
mp4ファイルとして保存したい場合はSimpleScreenRecorderを使用する。インストール方法は割愛。
[参考元](https://freepc.jp/post-43215)

---
<font color="yellowgreen">**QiitaLink**</font>
<font color="black">**Designed by RENOX**</font>
【Unity】Xcode14へのアップデート対応

## はじめに

macOSおよびXcodeは定期的にバージョンアップの必要があります。
今回、macOSのアップデートに伴いXcodeをXcode14にアップデートしたところ
コマンドラインからビルドする際に問題が発生したためその時の対応をまとめます。

## 環境

* macOS Monterey
* Unity 2019.4.26f1

## アプデ後に発生した問題

当環境ではiOSビルドをMac上でコマンドラインから行っているのですが
アプデ後、iOSアプリをArchiveしようとした際に

`does not contain bitcode.`とエラーがでてipaファイルが作成できなくなりました。

原因を調べたところ以下のような記事を発見。
>[iOSアプリのArchiveでdoes not contain bitcodeと言われる解決方法](https://qiita.com/pugiemonn/items/dd7c88205b72b3bcdb5a)
>[Xcode14からBitcodeオプションは非推奨になった](https://qiita.com/temoki/items/92999fcede0a7b89760f)

要はXcode上の設定で
「Build Settings > Build Options」の「EnableBitcode」が「Yes」になっているとエラーになるようでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2938978/97d507db-e504-18f1-2bd4-ef1b69ab9359.png)
こちらを「No」に変更すれば、Xcodeから「Archive」→「DisrtibuteApp」を行うことで
ipaファイルのエクスポートは一応可能になりました。

ですが、これではコマンドライン実行でipaファイルの作成まで一発で完了できないので
(Unityエディタ上でXcodeプロジェクトビルド、Xcodeから「Archive」を行う必要がある)
Unity上で対応を行うことにしました。

## 対応

Unityの「OnPostprocessBuild」を使用してビルド後にXcodeプロジェクトの設定を書き換えて
コマンドライン実行でipaファイルの作成まで通るようにしました。

具体的なコードは以下のようになります。
```
  // OnPostprocessBuild:ビルドの完了後のコールバック処理として実行される
  public void OnPostprocessBuild(BuildReport report) {
    string projectPath = PBXProject.GetPBXProjectPath(report.summary.outputPath);
    setBitCode(projectPath);
  }

  // Bitcodeのパラメータをセット
  private void setBitCode(string projectPath){
    PBXProject localPbxProject = new PBXProject();
    localPbxProject.ReadFromFile(projectPath);

    // Main
    string target = localPbxProject.GetUnityMainTargetGuid();
    localPbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");

    // ビルドターゲットが複数ある場合はそちらの設定も変更する

    localPbxProject.WriteToFile(projectPath);
  }
```

上記の処理を追加することによりビルド後のxcworkspace上で
「EnableBitcode」の設定が自動で「No」になります。


## 最後に

以上の対応でコマンドラインビルドからのipaファイル作成が可能になりました。
ビルドターゲットを指定する部分は環境に応じてターゲットの追加が必要になるかと思います。
プログラミング的思考はどこで役に立つか

この会社 https://wacaru-net.co.jp/ で働くようになって、プログラミングというにはおこがましいが、簡単なコードを組むようになった。
社長に言われたので初心者も初心者だが、記事を投稿しようと思う。

プログラミングを勉強し始めて、プログラミング的思考は日常生活でどういったところで意識すれば生活が効率化できるか、具体的なケースを考えてみた。

・料理をする際
よく言われるのは料理の時だろう。
まずは調理器具を準備し、下ごしらえをし、調理する・・・
工程を考えて目的を達成していく、まさにプログラミング思考だ。

・買い物
買い物もプログラミング思考が役に立つだろう。
買い回る際にいかに効率的に全ての買い物ができるかを考えてそれを遂行する。


こう考えると、何かを達成するために効率的に物事を進める力、つまり段取り力というのは、プログラミング思考と密接に関わっていると感じる。
段取りがうまいと、生活が効率的になる。

4歳になる子供の教育にもプログラミングを取り入れようか検討中だ。
限界の先に未来がある

仕事上、色んな人達とお会いしました。日本人の特徴なのかとても謙虚な人が多いです。
一方、知り合いの帰国子女の男性は外資系で働いてますが、謙虚なんて全くありません。
俺が俺が。。。僕は日本人なので辟易してしますｗ
日本人って勉強してないと言いながら、良い点とったり、練習してないと言いながら、上手なのがカッコ良いという文化です。そんな文化の中で育つと無理をしない、身の丈を考えて行きている人が多そうに思います。

そのスタイル変えて、身の丈を超えた、無理をしても良いのではないでしょうか。
![スクリーンショット 2022-11-18 18.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/ec587cfb-9a36-ba04-3b97-80c099c259fd.png)

# 無理をしてみよう
無理をすると失敗します。
僕はゴルフが好きなのですが、無理なプレーは大体失敗します。
でも成功した時の感動は、この上ありません。人は誰でも失敗はしたいとは思いません。
だからと言って、範囲を限定した中で物事を行っていたら成長しません。
例えば、筋肉。同じ重さで筋力トレーニングを行っていたら筋力アップしないのです。少しずつ負荷をあげていく必要があります。
勉強でも、やさしく確実に解ける問題ばかり、1桁の足し算ばかり毎日繰り返してたら一生、掛け算はできる訳が無い。
ゴムをストレッチするのと同じく、自分のキャパシティを超えた事をしていかないと自分のキャパシティが広がら無いのを認識する事は大事。

# 限界の先に未来がある
昔、バイクのレースをやっていた頃、色んなサーキットに遠征したりしてました。
初めてのサーキットに遠征に行くと、当然、走りなれてない分、ハンデがあります。でも、わざわざ遠征に来たのは、勝つためです。
対策として、僕がとったやり方は、危険ですが、練習走行の時に、とにかく限界点で走って転倒するというやり方でした。こうすると、初めてのサーキットでも限界値が直ぐにわかる。後は、決勝までにその限界点をあげていくセッティングをする事で勝利に繋がる訳です。
昔、内定者との懇親の時に、社会人になる事に対して不安を抱いてる人が居ましたが、若い時に沢山、失敗を繰り返した方が成長します。
特に仕事では、修羅場をどれだけ経験してきたかで人間としての器が全く違ってきます。
すっごく頭も良く、コミュニケーション力もある人でも、修羅場をあまり経験して無いと頼りない。
一方、修羅場の経験が凄い人は、周りに安心感を与えます。
若い時に失敗できる範囲は、所詮、若い人が失敗できる範囲の失敗でしかありません。
ある程度の責任者になってくると、その失敗の範囲も非常に大きくなり失敗は絶対に許されない範囲になります。
沢山チャレンジして、自分をストレッチさせて、修羅場を経験してみて下さい(笑
とにかく1000本ノックです。
何年後かに、必ず器の大きくなった自分を感じれると思います。
Salesforce認定Platformアプリケーションビルダー試験の公式サンプル問題解説してみた-11

こんにちは

Salesforce認定Platformアプリケーションビルダー試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

https://trailhead.salesforce.com/ja/content/learn/modules/platform-app-builder-pt1/platform-app-builder-security-ui

今回は

Platform アプリケーションビルダー試験に向けた学習
認定 Platform アプリケーションビルダー資格の受験準備: Data Modeling and App Deployment (データモデリングとアプリケーションリリース)
データのモデリングと管理の学習

にある問題3問目をご紹介します

なお今回の内容は動画でも公開しております

https://www.youtube.com/watch?v=5EM6hChjBS8

<iframe width="560" height="315" src="https://www.youtube.com/embed/5EM6hChjBS8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

![インポート01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bab610db-c7bf-5b7e-d13e-c55bb95d0392.png)



正解はAです

インポートする際の重複を防ぐため、一致条件を設定することができます

一致条件は名前、SalesforceID、外部IDを設定することが可能です

![外部.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/834a024f-ca5e-e297-f158-370e3b913bc6.png)