OmniAICreator/Qiita-1.07M huggingface dataset:
【Kotlin Coroutines】撃ち放し（fire and forget）処理にReactive Contextの値を引き継ぐ【Spring WebFlux】

筆者はこの辺りの話に言うほど詳しくないため、より良いやり方が有りましたらご教授頂けると助かります。

## TL;DR
- `Context.asCoroutineContext()`で作成した`CoroutineContext`を渡すのが簡単に見える

## 前提
### Reactive Contextについて
`Mono`/`Flux`には、上流のコンテキストに書き込んだ値を下流のスコープから参照する機能が有ります。
この機能はドキュメント上単に`Context`と呼称されていますが、分かりやすさのためこの記事では`Reactive Context`と呼称します。

https://projectreactor.io/docs/core/release/reference/#context

`Spring WebFlux`では、例えば`WebFilter`等を用いてリクエスト等から読み出した値を`Reactive Context`へ書き込んでおき、下流の処理でそれを読み出して利用するようなことができます。
認証やトランザクション制御に関しても、この機能を利用して作成されています。

```kotlin:値をセットするWebFilterの例
import org.springframework.stereotype.Component
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono

@Component
class SetFooIdFilter : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        return chain.filter(exchange).contextWrite { it.put(FOO_ID_KEY, /* ヘッダ等からのFooId読み出し処理 */) }
    }
}
```

```kotlin:値を読み出す例
import reactor.core.publisher.Mono

// この関数そのものはトップレベルに定義可能
fun getFooId(): Mono<String> = Mono.deferContextual {
    it.get<String>(FOO_ID_KEY)
}
```

### Coroutineでの撃ち放し処理について
`Coroutine`では、例えば以下のように書くことで撃ち放し（処理の発火後結果を待たずに終了する）処理を書くことができます。

```kotlin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

CoroutineScope(Dispatchers.Default).launch {
    /* 撃ち放しにしたい処理 */
}
```

## やりたいこと
先ほど紹介した`Coroutine`での撃ち放し処理の書き方では、呼び出し元の`Reactive Context`が引き継がれないため、撃ち放しにしたい処理の中で共通利用したい値の読み出しができません。
この問題を解決します。

## やり方
`Coroutine`には`ReactorContext`という機能が用意されており、それを利用することで実現できます。

https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-reactor/kotlinx.coroutines.reactor/-reactor-context/

サンプルコードは以下の通りです。
`asCoroutineContext`の戻り値が`ReactorContext`です。

```kotlin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.reactor.asCoroutineContext
import kotlinx.coroutines.reactor.awaitSingle
import reactor.core.publisher.Mono
import reactor.util.context.Context
import kotlin.coroutines.CoroutineContext

// 現状のReactive Contextから必要な値を引き継いだCoroutineContextを作成する
suspend fun getTakenOverContext(): CoroutineContext {
    val fooId: Mono<String> = getFooId()
    return Context.of(FOO_ID_KEY, fooId.awaitSingle()).asCoroutineContext()
}

CoroutineScope(Dispatchers.Default).launch(context = getTakenOverContext()) {
    /* 撃ち放しにしたい処理 */
}
```

### 補足
上で紹介した例で、「`FOO_ID_KEY`に対して`Mono<String>`をバインドする形にすれば便利なのでは？」と考えて幾つか試しましたが、自分はこれを実現できませんでした。

この形にできると以下のような利点が有ります。

- `getTakenOverContext`を非`suspend`関数にできる（= 非`suspend`関数からも撃ち放し処理を起動できる）
- `getFooId()`の戻り値を直接登録できる

**起きた問題**
`Mono`は遅延評価されるため、`getFooId()`で取得した`Mono`から値を読み出そうとすると、`deferContextual`へアクセスします。
これによって無限ループになり、`StackOverflow`が発生しました。

何かやり方が有るような気はしますが、自分のユースケースでは、撃ち放し処理の起動は必ず`suspend`関数から行えたため、調査を打ち切っています。
ハードウェア

# 問題１　D/A変換器の出力電圧の変化　
ここではD/A変換器では出力電圧の表現は２^８＝２５６通りになる。
１ビットあたり2.5/128(v)変化することが分かった。
128が２進数１０進数で表現されたものなのか。

# 問題２の気づき
電気信号は０か１で表現されるのでイを選択した。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
emotionでThemeを書き換える

# EmotionでThemeを書き換える

実装方法でハマったので備忘録として残しておく。

## src/components/MyAppTheme.ts
```
import { ThemeProvider } from "@emotion/react";
import styled from "@emotion/styled";
import { MyAppTheme } from "./MyAppTheme";

const ThemeButton = styled.button`
  background-color: ${({theme}) => theme.backColor};
  color: ${({theme}) => theme.foreColor};
  padding: ${({theme}) => theme.padding};
`;

export const Buttons = () => {
  return (
    <ThemeProvider theme={MyAppTheme}>
      <ThemeButton >Button</ThemeButton>
    </ThemeProvider>
  );
}
```

### src/App.tsx
```
import { ThemeProvider } from "@emotion/react";
import styled from "@emotion/styled";
import { MyAppTheme } from "./components/MyAppTheme";

const ThemeButton = styled.button`
  background-color: ${({theme}) => theme.backColor};
  color: ${({theme}) => theme.foreColor};
  padding: ${({theme}) => theme.padding};
`;

export default function App() {
  return (
    <ThemeProvider theme={MyAppTheme}>
      <ThemeButton >Button</ThemeButton>
    </ThemeProvider>
  );
}
```
【React / CSS】モーダルウィンドウ作った！【個人制作過程】

# はじめに

「業務でReactを使える必要が出てきそう」という状況と、「Reactを使いこなしたい」という思いが合わさって、Reactの勉強をスタートしました。
どうせ勉強するなら、作りながら楽しみたいな〜という事で、K-POPの歌詞をもとにハングルを勉強するアプリを制作中です。
区切りの良いところでアウトプットして、自分の学びを整理していきます。

# 今回の実装概要

タイトルにもある通り、ReactとCSSを組み合わせてモーダルウィンドウを実装しました。
モーダルウィンドウの中身はパターンが2つあり、1つ目は**入力フォームを表示**、2つ目は**投稿した内容を表示**します。
ライブラリは使用せずに作りましたが、次はライブラリを追加してみたいな〜と考えているところです。
[ソースコードはこちら](https://github.com/pchm13/studyHangul)

# デモ動画

![モーダルウィンドウデモ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1889160/a55520cc-50ae-3a37-3130-9713ebf784b0.gif)

# 学び

## その1 フォームの実装について
```
// src/App.jsx

<InputArea
    isInputArea={isInputArea}
    inputTitle={inputTitle}
    onChangeInputTitle={onChangeInputTitle}
    inputLyric={inputLyric}
    onChangeInputLyric={onChangeInputLyric}
    onClickAdd={onClickAdd}
    onClickInputClose={onClickInputClose}
/>
```
```
// src/components/InputArea.jsx

if (isInputArea)
    return (
        <>
            <div className="overlay">
                <div className="inputArea">
                    <form>
                        <label htmlFor="title">タイトル</label>
                        <input type="text" id="title" name="title" value={inputTitle} onChange={onChangeInputTitle} />
                        <label htmlFor="lyric">歌詞</label>
                        <textarea id="lyric" name="lyric" rows="10" cols="50" value={inputLyric} onChange={onChangeInputLyric} />
                        <input type="button" value="登録" onClick={onClickAdd} />
                    </form>
                    <button className="closeButton" onClick={onClickInputClose}>close</button>
                </div>
            </div>
        </>
    )
}
```
- 現状propsの中身が多すぎるので、ライブラリを駆使して今後なんとかしたい
- ReactにDOM要素を埋め込む時、ブラウザのDOM要素と比較して、プロパティ名のルールが異なる
ex :) className, htmlFor(forはJavaScriptの予約語だから、という理由だそう)
- コンポーネントに切り分けるのが難しかった
- 何をpropsに渡すのか・変数定義はどこでするのか、この辺り悩みました
- **投稿した内容の表示**もpropsに値を持たせてモーダルウィンドウで表示させてるので割愛

## その2 モーダルウィンドウの実装について
```
// src/App.jsx

const [isInputArea, setIsInputArea] = useState(false)

const onClickInputOpen = () => {
    setIsInputArea(true)
}

const onClickInputClose = () => {
    setIsInputArea(false)
}
```
useStateでモーダルウィンドウを表示しているかどうかの情報を持たせ、ボタンをクリックすると発火するようにしてます。
```
/* src/styles.css */

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  overflow-y: scroll;
}
```
CSSでモーダルウィンドウ表示後の背景を設定しました。

- 現状、用意した”close”ボタンをクリックしないと、モーダルウィンドウが閉じない仕様
- モーダルウィンドウ背景をクリックした時にモーダルウィンドウが閉じる仕様に変更したい
- ユーザーに"close”ボタンを探させたくない

# 次回の実装について

アプリケーションの名前が「****歌詞でハングルを勉強するApp****」なのに、1ミリも勉強要素がないので追加します。クイズ形式にするか…悩み中です。
難易度上がりそうですが、ぼちぼち進めていきます！

# 参考URL🙏

[モーダルウィンドウ実装について](https://reffect.co.jp/react/react-modal)

[React DOM要素について](https://ja.reactjs.org/docs/dom-elements.html)
EmotionでThemeを使ってみる

# EmotionでThemeを使ってみる

```
import { ThemeProvider } from "@emotion/react";
import styled from "@emotion/styled";

const ThemeButton = styled.button`
  background-color: ${({theme}) => theme.color.primary};
  color: ${({theme}) => theme.color.positive};
  &:hover {
    background-color: ${({theme}) => theme.color.negative}
  }
`;

export const Buttons = () => {
  return (
    <ThemeProvider theme={{color: {primary: "blue", positive: "red", negative: "green"}}}>
      <ThemeButton >Button</ThemeButton>
    </ThemeProvider>
  );
}
```
Alfredで1つ前（2つ前）にクリップボードにコピーしたオブジェクトをペーストする

# TL;DR
Alfredで1つ前（2つ前）にクリップボードにコピーしたテキストや画像をショートカットでペーストするワークフローを作成した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/c86ce0b5-092c-c27d-9f07-df700ef95429.png)


# Motivation
コピペするときに、地味に一つ前のクリップボードのオブジェクトをペーストしたいときに、AlfredのClipboad Historyを開いて探すのが面倒。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/f15ca0bf-fca0-6cce-8acc-1bcc30c9ca67.png)
私の場合は、⌘+Shift+x でClipboad Historyを開くようにしている（デフォルトは何だったか忘れた）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/2ccb0b8a-2bc3-9d71-20c1-ef3cba0e125d.png)


# Source

1つ前のオブジェクトを⌘2回、2つ前のオブジェクトを⌥2回でペーストする。
ホットキーで呼び出して、AppleScriptで実行する。

```
on run
  tell application "System Events" to keystroke "x" using {command down, shift down}
  delay 0.1
  tell application "System Events" to key code 125
  tell application "System Events" to key code 125
  tell application "System Events" to key code 76
end run
```

# 最後に
Alfredしか勝たん
https://github.com/kentoak/paste_back_to_back_alfred
initキーワードを使ってオブジェクト初期化子で生成可能なバリューオブジェクトを作る

# はじめに
本記事はinitキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法についてまとめます。

# initキーワードを使わない場合
initキーワードを使わない場合、読み取り専用のプロパティを用意し、コンストラクタでプロパティの値を受け取り、初期化することでバリューオブジェクトを定義できます。
以下のような感じです。
```csharp
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
    #region プロパティ

    /// <summary>
    /// 値
    /// </summary>
    internal string Value { get; } = string.Empty;

    #endregion

    #region コンストラクタ

    /// <summary>
    /// コンストラクタ
    /// </summary>
    /// <param name="value">値</param>
    internal ValueObject(string value)
    {
        Value = value;
    }

    #endregion
}
```
バリューオブジェクトを生成するには以下のようにコンストラクタに値を渡してオブジェクトを生成することになります。
```csharp
// バリューオブジェクトをコンストラクタ経由で値を渡して生成
var valueObject = new ValueObject("value");
```
バリューオブジェクトにするためにプロパティは読み取り専用としているため、仮に上記のValueObjectクラスに引数なしコンストラクタがあったとしても、以下のようにオブジェクト初期化子を使っての生成はできません。
```csharp
// プロパティが読み取り専用なので、以下はビルドエラーになる
var valueObject = new ValueObject(){ Value = "value" };
```

# initキーワードを使う場合
オブジェクト初期化子を使って生成できるバリューオブジェクトを定義するためには、以下のようにinitキーワードを使って初期化時のみ値を設定可能なプロパティを定義します。
以下のような感じです。
```csharp
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
    #region プロパティ

    /// <summary>
    /// 値
    /// </summary>
    internal string Value { get; init; } = string.Empty;

    #endregion
}
```
バリューオブジェクトを生成するには以下のようにオブジェクト初期化子で値を設定してオブジェクトを生成することになります。
```csharp
// バリューオブジェクトをオブジェクト初期子で作成
var valueObject = new ValueObject(){ Value = "value" };
```
initキーワードを使ってプロパティを定義しているので、オブジェクト生成後に以下のようにプロパティの値を上書きしようとするとビルドエラーとなります。
したがって、オブジェクト生成以降プロパティの値が変更できず、バリューオブジェクトとして扱うことができます。
```csharp
// 初期化以外での値の設定はできないので、以下はビルドエラーとなる
valueObject.Value = "changedValue";
```

# まとめ
本記事はinitキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法をまとめました。
ただし、今回紹介した方法では、オブジェクト初期化子でプロパティの初期化を強制することができません。
C#11.0で追加される[required修飾子](https://learn.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-11#required-members)を使うことで、オブジェクト初期化子でのプロパティの初期化を強制できるようになるため、これを使うことで問題点を解消できると思います。
C#11.0が正式リリースされた後に問題点を解消した例をまた記事にできたらなと思っています。
AndroidStudioで使用する最大ヒープサイズの変更方法

# はじめに
久しぶりにヒープサイズを調整したほうがいい旨の通知がAndroidStudio上に表示されていたので対応したのですが、手順を備忘録的に残しておこうと思います。

# ヒープサイズ変更方法
まず、ヒープサイズを変更したほうがいい場合に以下のようなメッセージが表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/2d36088f-d9b1-861b-fded-b5f0fb1c48fc.png" width="420px">

このメッセージが表示された場合は以下の手順で変更が可能です。

①メニューバーから [File] > [Preference]を選択します。
②[Appearance & Behavior] > [System Settings] > [Memory Settings]を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/0168b7fd-6650-b30a-a1a5-7e9ea40e1a4e.png" width="420px">

③ヒープサイズを適切なサイズへ変更後[Apply]を選択します。

④AndroidStudio再起動

以上になります。

# さいごに
このメッセージが出ることもそこまで多くないですが、規模の大きいPJやマルチモジュールのプロジェクトなどは最初に調整が必要になる可能性が高い印象です。
その際にお困りであれば、参考にしていただけると幸いです。
styled-componentsの指定方法(typescript)

# styled-componentsの指定方法(typescript)

書いては忘れての繰り返しなので備忘録としてまとめておく。

## 指定方法1

オブジェクトで指定するやり方。
上書きする場合はスプレッド構文とstateを使う。

```
const Button1 = styled.button<{param1: string}>((props) => ({
  color: props.param1,
  /*
  ...{
      state && color: "red"
  }
  */
}));
```

## 指定方法2

cssの記法をそのまま使える。
疑似要素も記述可能。

```
const Button3 = styled.button<{param1: string}>`
  color: ${(props) => props.param1};
  &:hover {
      color: "red";
  }
`;
```

## 指定方法3

指定方法2の亜種。
あまりみない。

```
const Button2 = styled.button`
  color: ${(props: {param1: string}) => props.param1};
`;
```
Windows10 プロキシオプションをつけてcurlをたたく

簡単なWebアクセス試験をしたくやり方を軽く検索したところ
windows10はcurlが標準搭載されているとのことだったので試してみる。

自身の環境がプロキシ経由でしかインターネットに抜けれないため
--proxyオプションをつけてアクセスできるか試してみる。

ちなみに搭載されているのはオープンソース版ではなく
マイクロソフトは一から作ったものらしい。
(マイクロソフトはオープンソースを使わないルールだとかなんとか）

---
curlがインストールされていることを確認する。
バージョンが表示されればOK。

```
curl --version
```

<details><summary>実行結果</summary>

```console
>curl --version
curl 7.83.1 (Windows) libcurl/7.83.1 Schannel
Release-Date: 2022-05-13
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS HSTS IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI UnixSockets
```
</details>



proxyオプションをつけてcurlコマンドをgoogleにアクセスしてみる。
```
curl --proxy http://proxy****:8080 https://www.google.com
```

<details><summary>実行結果</summary>

```console
C:\Users>curl --proxy http://proxy*****:8080/ https://www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="&#19990;&#30028;&#20013;&#12398;&#12354;&#12425;&#12422;&#12427;&#24773;&#22577;&#12434;&#26908;&#32034;&#12377;&#12427;&#12383;&#12417;&#12398;&#12484;&#12540;&#12523;&#12434;&#25552;&#20379;&#12375;&#12390;&#12356;&#12414;&#12377;&#12290;&#12373;&#12414;&#12374;&#12414;&#12394;&#26908;&#32034;&#27231;&#33021;&#12434;&#27963;&#29992;&#12375;&#12390;&#12289;&#12362;&#25506;&#12375;&#12398;&#24773;&#22577;&#12434;&#35211;&#12388;&#12369;&#12390;&#12367;&#12384;&#12373;&#12356;&#12290;" name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta c
・
・
・
```
</details>


問題なくアクセスできました。

以上です、おつかれさまでした。
Android13以降で必要になった「広告 ID を使用するための権限を宣言する」方法

# はじめに
ある日、Google Play Consoleで以下のような**広告 IDに関する申告**を求められました

>Android 13（API 33）で広告 ID の変更が行われました
Android 13 以降をターゲットとし、広告 ID を使用しているアプリについては、アプリ マニフェストで com.google.android.gms.permission.AD_ID 権限を宣言する必要があります。この権限が含まれていないと広告 ID がゼロにリセットされ、ID にアクセスしようとすると ID ではなくゼロの文字列が返されます。 

![Screen Shot 2022-10-01 at 19.28.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/4cbfb716-29b7-4f19-193d-50fd44fa5d70.png)

で、これが一体何をすればいいのかわからなかったので、対応方法をご紹介します。

# 前提
・対象となるアプリはアプリ内に広告を表示していてAndroid13以降もターゲットにしているアプリです

・権限が宣言されていない場合

# 「権限が宣言されていない場合」とは？
日本語が難しいですが、、、
Androidアプリは`AndroidManifest.xml`というファイルがあり、このファイルはアプリに関する重要な情報を Android ビルドツール、Android オペレーティング システム、Google Play に対して説明するものです。

「重要な情報」には「権限の宣言」が含まれます！

https://developer.android.com/guide/topics/manifest/manifest-intro?hl=ja

>Android アプリは、プライベートなユーザーデータ（連絡先や SMS など）や特定のシステム機能（カメラやインターネット アクセス）にアクセスするためのパーミッションをリクエストする必要があります。 それぞれのパーミッションは一意のラベルで識別されます。

「広告 IDを使用しますよ〜」という宣言がされている場合は、今回のような対応は不要という事です:relaxed:

# どうすれば権限が宣言されているか確認できるのか？
`AndroidManifest.xml`ファイルを見るだけでわかるかと思いきや、そうじゃない場合もあるようです。。。

>Google Mobile Ads SDK（play-services-ads）など、一部の SDK では、SDK のライブラリ マニフェストですでにこの権限を宣言している可能性があります。アプリがこれらの SDK を依存関係として使用している場合は、アプリのメイン マニフェストで権限を明示的に宣言していなくても、デフォルトで、SDK のライブラリ マニフェストの AD_ID 権限がアプリのメイン マニフェストと統合されます。
https://support.google.com/googleplay/android-developer/answer/6048248?hl=ja

なので確認する確実な方法はGoogle Play Consoleのビルド情報？を見る事です！
**（AdMobを使ってるならデフォルトで`com.google.android.gms.permission.AD_ID`は宣言されてるので対応不要かと）**

![Screen Shot 2022-10-01 at 16.47.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/223e57b1-589e-f0f3-ff6d-c98fe63ecec8.png)

![Screen Shot 2022-10-01 at 16.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/2978c976-d3d8-0345-5db5-09ac71cd28f1.png)

「権限」の部分を見ても`com.google.android.gms.permission.AD_ID`の表示がありません。。
**つまり権限の宣言ができていない、という事ですね**

# どうやって権限を宣言するか？
`AndroidManifest.xml`ファイルを以下のように編集します。

```xml
<manifest>
 <!-- 省略 -->
  <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
</manifest>
```

これで再度ビルドしてGoogle Play Consoleにアップロードすると👇のように`com.google.android.gms.permission.AD_ID`が追加されています。

![Screen Shot 2022-10-02 at 13.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/a8aca450-f3aa-7d55-a253-f6893560247a.png)
これで公開すればOK！！:grinning:



# 参考
https://support.google.com/googleplay/android-developer/answer/6048248?hl=ja
開発環境を晒す

使っているツール、知っていてよかったショートカットキーを晒します。
完全に自己満ですが参考にしてもらえると嬉しいです。

## ツール系
自分は下のツールを使う感じに落ち着きました。

- VS Code
    - 必要なものだけを拡張機能で追加できるので、Visual Studioよりも早くてコードを書くのが快適です。
    - Electronベースで開発されているエディターなので、ショートカットキーがブラウザの開発者ツールと似ている。
- Visual Studio
    - 開発環境を再現するときにGUIで操作できるので便利。
- GitHub Desktop
    - Source Treeが重いので乗り換えました。
- Typora 
    - Markdownのビューアーです。MarkdownをPDF出力するときに使います。
- Postman
    - APIプラットフォーム
- Windows Terminal
    - コマンドラインツール。ブラウザみたいにタブでシェルが切り替えられます。プロモーションムービーがかっこいいので是非見てみて。https://www.youtube.com/watch?v=8gw0rXPMMPE
- Docker＆WSL2
    - 手軽に仮想環境を作れるツール。Build Pipelineの検証をするときにローカル環境は汚したくないので使い捨ての環境を用意するときに重宝します。

## ツールの使い方

### 複数のGoogle Accountを使い分ける
MSアカウントの場合、組織アカウントと個人アカウントがわかりづらくなりがちなので、ブラウザごとにアカウントを分けるのをお勧めします。
下のリンクはGoogle Chromeでのやり方で紹介されてますが、Edgeでも同じことができます。

https://4thsight.xyz/3770

### ショートカットキーのすゝめ
覚えようとすると辛いですが、慣れようとすると勝手に覚えます。
個人的には
- Ctrl + P: ファイルを開く
- Ctrl + Shit + P: 拡張機能を開く
は慣れていて良かったと感じています。

https://insider.10bace.com/2019/02/22/vs-codeとかのショートカットのはなし/

## VS Code拡張機能

https://www.youtube.com/watch?v=c5GAS_PMXDs

### Git GUI
- Git Lens
- Git Graph

VS Codeからコミットログが見れます。表示も早いのでいい感じです。
![スクリーンショット 2022-10-02 13.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/487843a5-eadb-c085-a241-94b3948f831f.png)

Git Lensを入れておくと、誰がいつ書いたソースコードなのかが見れます。Visual Studioだと行ごとの履歴は見れないので自分が書いたクソコードにいち早く気づきたいという人はVS Codeでコーディングすることをお勧めします。
![スクリーンショット 2022-10-02 13.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/b5048bc1-4fd0-ae02-799c-627b8e52569b.png)



### アイコン
上の動画ではMateriak Icon Themeが紹介されてますが、MSが開発しているFluent UIベースの”fluent icon”もあります。好きな方を選びましょう。
- vscode-icons
- Material Icon Themes
- fluent icon

Fluent UIの紹介動画が良きです。

https://www.youtube.com/watch?v=BsJSn1vtpPc

### コード整形
プログラミング言語ごとに拡張機能があるので、各自でプロジェクトに合ったものを選ぶのがいいと思うのですが、”Auto Clsoe Tag”と”Auto Rename Tag”は入れておくとコーディングが捗ります。

- Auto Close Tag
- Auto Rename Tag
【React】API利用の練習のためにジブリのJSONデータを取得

<h2>Reactプロジェクトの作成
<p>

今回はCreate React Appではなく、 __Vite__ を利用して新規プロジェクトを作成したいと思います。

基本的にはこちらの[Vite公式ページ](https://vitejs.dev/guide/)を参考にしています。
<br>

１. 初めに`npm create vite@latest`をターミナルで実行します。

２. プロジェクトネームを聞かれるので適当に入力します。今回は __react_ghibli__ という名前にしました。

３. どのJSフレームワークを利用するか聞かれるので、 __React__ を選択します。

４. 次にJSかTSのどちらを利用するか聞かれますが、今回は __JS__ を選択します。

５. ターミナルに 
`
cd 作成したプロジェクトの名前`
  `npm install`
  `npm run dev`
を実行しろと表示されるのでコピペして実行します。 

６. 少し待つとUrlが表示されるので、そのUrlを開き、このように表示されると新規プロジェクト作成は成功です。
<img width="300" alt="Vite + React" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708101/15922148-d9ac-f73c-6f93-a8f181d35df2.png">


<h2>APIの利用

<p>

初めに、API利用に必要な __axios__ をインストールします。ターミナルで　`npm install axios`　を実行します。

続いてVSCodeなどのエディターを使い作成されたファイルを開き、 __react_ghibli/src/App.jsx__ を開きます。

そこで、App.jsxに　```import axios from "axios";```　を 追加し、中身をこのように書き変えます。


```python:App.jsx
import React, { useState, useEffect } from "react";
import axios from "axios";

const API = () => {
  const [Ghibli, setGhibli] = useState([]);

  useEffect(() => {
    async function getGhibli() {
      let API_Ghibli = await axios.get(`https://ghibliapi.herokuapp.com/films`);
      console.log(API_Ghibli);

      setGhibli(API_Ghibli.data);
    }

    getGhibli();
  }, []);

  return (
    <div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
      <ul>
        {Ghibli.map((post) => (
          <>
            <li className="font-bold"> {post.original_title} </li>
            <li className="font-bold"> {post.director} </li>
            <li>
              <img src={post.image} alt="" className="pb-10" />
            </li>
          </>
        ))}
      </ul>
    </div>
  );
};

export default API;
```
※__className="font-bold__ などの表記はtailwindというCSSフレームワークを利用したものです。

ここでは `axios.get()`を使い、ジブリ作品のJSONデータが集められている　
https://ghibliapi.herokuapp.com/films　
にアクセスをし、そのデータを __API_Ghibli__ という変数に入れています。
後はこのデータを利用することで、作品名や作者名、画像などを利用することが可能となります。

このように、外部JSONデータを簡単に取得することが出来ました。


<h1>追記(tailwindの使用方法について)
<p>

__index.html__ 内の `<head>` に　

`<linkhref="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">`

を追加する。
Linux OOMとswapon -s について

●システムのメモリ利用率が非常に高い状態で運用を続けると、カーネルがメモリ不足と認識した時に発動するOOM Killer（Out Of Memory Killer：メモリ不足時の自動プロセス停止機能）によって、プロセスの強制終了処理が実行される。

OOM Killerは独自の基準でプロセスを強制終了するため、意図しない重要なプロセスが強制終了される可能性がある。こういった状態を回避するためには
・重要なプロセスに対して、OOM Killerのプロセス停止優先度を低く設定する　※ただし、プロセス番号が変わると都度設定が必要となる
・メモリ（物理、スワップ）を十分に用意する
という対策が必要になる

メモリの利用率の急激な増加への対処として、スワップ領域として使用するファイルを作成し、スワップ領域として有効化。

作成、有効化の手順は以下のとおり

1.スワップ領域として使いたいサイズのファイルを作成。
2.mkswap コマンドで、作成したファイルをスワップ領域として初期化。
3.swapon コマンドで、作成したファイルをスワップ領域として有効化

※この時、作成したファイルのパーミッションは600（所有者＝rootのみ読み書き可）とすることが推奨。

●swapon -s
システムで有効になっているスワップ領域の利用状況を調べるためのコマンド。

また、「/proc/swaps 」を参照することでもスワップ領域の利用状況を知ることができるので、
cat /proc/swaps
でも同じ結果が得られる


●ハードディスクは「パーティション」と呼ばれる部分に分割して利用。

ディスク全体をひとつの領域とする場合にも、全容量を割り当てたひとつのパーティションを作る必要があります。
パーティションには現在「MBR」「GPT」の2つの形式があります。

MBR形式では、パーティションには基本パーティションと拡張パーティションがあり、基本パーティションは 4 つまでしか作成することができない。

これらパーティションに関する操作には fdisk というコマンドが利用できる。

各パーティションはただの領域であり、それだけではデータの読み書きに利用することができません。
パーティションをファイルシステムで「フォーマット」することで、ファイルを単位としたデータの管理が行えるようになります。
この操作には mkfs などのファイルシステムを作成するコマンドが利用できる。

そして実際にファイルの読み書きを行うためには、さらにそのファイルシステムを現在のルートファイルシステム上のどこかにマウントし、ルート (/) からのパスを使ってアクセス可能にしなければならない。
この操作には mount コマンドを使う。

したがって、新しいハードディスクを Linux システム上で利用するためには

1. fdiskコマンドでパーティションを切る（基本パーティション、拡張パーティションを作成）
2. mkfsコマンドなどで各パーティションをフォーマットし、ファイルシステムを作る
3. mountコマンドで作ったファイルシステムをマウントする
【合格体験記】Python 3 エンジニア認定基礎試験

# 初めに
企業で「DX」が推進されている中、Pythonの需要は徐々に高まっていると思います。
私自身もスキルアップのためにPython 3 エンジニア認定基礎試験を勉強して、無事合格することができました。
試験に合格するまでの勉強内容・方法を以下に記載してます。

# 目次
1. 受験時点のスキル
1. 勉強時間と内容
1. 所感
# 1. 受験時点のスキル
+ Webアプリ開発（2年）
  + 製造・テスト経験あり
+ プログラミングの基礎知識はある
  + if文やfor文など、基本構文を理解している
  + 関数について理解している
+ Pythonの開発経験は無し

# 2. 勉強時間と内容
## 勉強時間
トータルで30時間くらい。
公式サイトの模擬試験に1番時間を使いました。

## 勉強内容
### 公式サイト推奨の模擬試験を実施

以下の2つのサイトが、「Python 3 エンジニア認定基礎試験」の**認定模擬問題**になります。
実際の試験では、以下のサイトと似たような問題も多く出題されました。
私の場合は、以下サイトの問題を何度も解き直して、全ての問題を正当できるくらいの理解をして試験に挑みました。

**PRIME STUDY**

https://study.prime-strategy.co.jp/study/py3ba1/

https://study.prime-strategy.co.jp/study/py3ba2/

https://study.prime-strategy.co.jp/study/py3ba3/

**DIVE INTO EXAM**

https://diver.diveintocode.jp/dive_into_exam/1

### Pythonチュートリアル 第4版

https://www.amazon.co.jp/Python%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB-%E7%AC%AC4%E7%89%88-Guido-van-Rossum/dp/4873119359/ref=sr_1_1?adgrpid=116176398219&gclid=Cj0KCQjwyt-ZBhCNARIsAKH1174PwpfvRE2f8JrqJaS8mpikzvB7TYPsbJWNBvPz_MkWx3wYGv2fHEkaAja1EALw_wcB&hvadid=618622585429&hvdev=c&hvlocphy=1009264&hvnetw=g&hvqmt=e&hvrand=14963512914956481543&hvtargid=kwd-1148575388361&hydadcr=27270_14598092&jp-ad-ap=0&keywords=python%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB+%E7%AC%AC4%E7%89%88&qid=1664678590&qu=eyJxc2MiOiIxLjMwIiwicXNhIjoiMC40MSIsInFzcCI6IjAuMzMifQ%3D%3D&sr=8-1

こちらが「Python 3 エンジニア認定基礎試験」の**認定テキスト**になります。
この本の内容は試験対策だけでなく、実際にアプリ開発をする時にも非常に参考になるかと思います。
試験を受ける目的がなくても、この本は1度読んでみてもいいのかなと思います。

# 3. 所感
試験は、単純問題ばかりでそこまで難しくなかったと感じました。基本的な知識を選択肢で選ぶという感じでした。
公式サイトの模擬試験の方が難しかったです。。。
あとは、Pythonを触ったことがない方でも他の言語である程度構文や関数を理解していれば、そんなに難しくないと思います。
Python仕様の構文の書き方を理解できれば、試験は合格できると思います。
【AWS EC2】SavingsPlans・リザーブドインスタンスとは何か？（なんとなくわかった気になるための説明）

# はじめに
はじめまして、Webエンジニア2年目の28歳です。
AWS初心者なので、「SavingsPlans とは」で出てくる解説を読んでも、当初全く理解できず、なんとか色々な記事・動画を参照することでようやく「これは理解できたかも？」という状態になりました。
かなり苦労してしまったので、僕のような初心者でも「とりあえず、なんとなくわかった気になれる」ような説明がほしいな！と思い、この記事を書きました。

# 説明
早速ですが、「とある会社で、社用車をレンタカーで借りる状況」になぞらえて説明します。

## 理解の出発点
厳密に言うと違うかもですが、まず理解の出発点としては以下のイメージが良いんじゃないかなと思います！
- リザーブドインスタンス：これだという車１台をずっと借りる（１台貸し切り）
- SavingsPlans：定額借り放題

## リザーブドインスタンスとは？
- 車種や台数を指定して1年間または3年間借りる契約をすることで、通常（数時間や数日だけのレンタル）より割引になるプラン。
- 利用場面
    - 例：「直近１年間で、この車種が何台必要」と具体的に決まっている場合。（1年間または3年間、車種や台数の変更がない想定）
- 支払方法
    - 「全額前払い」「一部前払い」「前払いなし」があり、全額前払いが最も安い。

## SavingsPlansとは？
- 車種や台数は指定せず、メーカーだけ指定した形で、直近1年間または3年間において1日あたり何円分借りるかを指定して契約することで、通常より割引になるプラン。
    - 「1日あたり何円分借りるか」で決めた価格（コミット額）の範囲内であれば、車種や台数は自由に選べる。
    - コミット額を超えてレンタルした場合は、通常料金を払う必要がある。
    - メーカーの縛りもなしで契約できるプランも存在する（割引率は劣る）
- 利用場面
    - 例：時期によって必要な車種や台数は変わるかもしれないが、1年間または3年間は継続して車をレンタルすることは見込まれており、できるだけ安く済ませたい場合。
- 支払方法
    - 「全額前払い」「一部前払い」「前払いなし」があり、全額前払いが最も安い。

# EC2での説明
今度は、同じ流れで真面目にEC2を使ってざっくり説明します。

## 前提知識
- EC2とはどんなものかの知識
- インスタンスタイプ周りの知識（インスタンスファミリー・世代・インスタンスサイズとは何か）
    - （参考： https://d1.awsstatic.com/webinars/jp/pdf/services/20190305_AWS-Blackbelt-EC2.pdf ）

## リザーブドインスタンス
- インスタンスタイプ・台数を指定して1年間または3年間利用する契約をすることで、通常料金（オンデマンド料金）に比べて割引価格になる。（例： `t4g.large` インスタンス1台を1年間利用、など）
- 利用場面
    - 例：「直近１年間で`t4g.large`インスタンス1台の稼働が必要」と具体的に決まっている場合。（1年間または3年間、インスタンスタイプの変更はない想定）
- 支払方法
    - 「全額前払い」「一部前払い」「前払いなし」があり、全額前払いが最も安い。

## SavingsPlans（EC2 Instance Savings Plans）
- インスタンスサイズや台数は指定せず、インスタンスファミリー・世代だけ指定した形で、直近1年間または3年間において、1日あたり何ドル分利用するか（オンデマンドでの料金）を指定して契約することで、オンデマンドの通常料金に比べて割引価格になる。
    - 「1日あたり何ドル分利用するか」で決めた価格（コミット額）の範囲内であれば、インスタンスサイズや台数は自由に選べる。
    - コミット額を超えてレンタルした場合は、通常料金（オンデマンド料金）で支払う必要がある。
    - インスタンスファミリー・世代の縛りもなしで契約できるプラン（`Compute Savings Plan`）も存在する（割引率は劣る）
- 利用場面
    - 時期によって利用するインスタンスサイズは変わるかもしれないが、1年間または3年間は継続してそのインスタンスファミリー・世代のEC2を利用するすることは見込まれており、できるだけ安く済ませたい場合
- 支払方法
    - 「全額前払い」「一部前払い」「前払いなし」があり、全額前払いが最も安い

# 最後に
## 注意点
- これはあくまでも初心者がざっくり「とりあえず分かった気になる」ための説明です。
    - この説明を足がかりにして、他の詳しい＆正確な説明を読み解けるようになることを目的としています。
- 細かく言うとちょっと違う部分、説明不足な点もあると思います、、！！（リザーブドインスタンス、SavingsPlansの中にも色々種類がある等）

## 補足
リザーブドインスタンスとSavingsPlansにおいては、比喩を使った初心者向けの説明は見当たらなかったので、
このサイト（[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/)）のような説明があったらよかったのに、、という思いで作りました。
また、大げさですが、これを気に「もっとこんな例え方の方がわかりやすいでしょ！」って感じる方が出てきて、その方が良い記事を作っていただくなり、私がもう少し良い例えを思いつくなりすれば、より初心者が素早く理解できるような環境になるのでは、、という思いもあります。
（私の例えはしっくり来ていない部分が多少あるので、、）
【Unity】ビルドエラー（could not delete old … See the Console for details.）の対処方法

自分用メモ

## エラー内容
```
Could not delete old
...init-results release-fatal.html
See the Console for details.
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/5a10ce69-a373-7ea4-315a-62816f138c43.png)

## 対処
指定された`init-results release-fatal.html`を削除する
Excelの新しいSheetに名前をつけるマクロのエラー

意図していなかったエラーが発生したので記事を書きます

# マクロの内容
月毎に新しいSheetを作成する作業をマクロ化していました
新しいSheetのA1セルにFormat関数で日付を入力
Sheet名は2022年10月であれば"2022.10"としていました
```
  ActiveSheet.Range("A1") = Format(Now, "yyyy.mm")
  ActiveSheet.Name = ActiveSheet.Range("A1")
```

# エラーの発覚
2022年10月に新しいSheetを作成するためマクロを実行した所、実行時エラーが発生しました
同じ名前のSheetがあるので作成できないという内容のエラーです
　1.イミディエイトウインドウで変数の確認をした所"2022.10"で間違いありません
　2.新しく作成したSheetのA1セルを確認すると"2022.1"でした
　3.A1セルの書式設定を確認すると標準になっていました
　4.原因はExcelが"2022.10"を小数点を含む数字と判断したので0が消えていたからだとわかりました

# 解決策
A1セルの書式設定を標準から文字列に変更することで解決しました

# 背景
"2022.1"のシートは手入力で名前を変更していました。マクロ実行すれば"2022.01"で作成され、今回のような実行時エラーにはならなかったはずです。Sheet名"2022.1"が作成される論理エラーとなり、問題の発覚が遅れた可能性があります

# まとめ
今回のエラーの恐ろしい所は10月以外の月では発生しないことです
エラーを予防する方法として思いついたものを残しておきます
Sheet名をつける時は
　1.2022年10月の様にExcelが文字列と判断できる名前をつける
　2.特定のセルのValueを名前にする場合、セルの書式設定は文字列にする
　3.マクロ作成時に変数を定義して、その変数をSheet名にする

```
Dim SheetName As String
  SheetName = Format(Now, "yyyy.mm")
  ActiveSheet.Name = SheetName
```
Web Serial API の使い方 (port の絞り込み)

こちらのサンプルを改造して port の絞り込みをします。
[Web Serial API の使い方](https://qiita.com/ekzemplaro/items/5e00a7aa494eb7bd676a)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a29fe7c0-86ed-a265-10c6-6ab5e417f5b6.png)

## Vendor ID の調べ方

lsusb

```text
$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 8087:0029 Intel Corp. AX200 Bluetooth
Bus 001 Device 013: ID 275d:0ba6  USB OPTICAL MOUSE 
Bus 001 Device 003: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 002: ID 04f2:b71a Chicony Electronics Co., Ltd HD Webcam
Bus 001 Device 030: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```

usbview

```bash
sudo usbview
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/481ab968-29fe-beb0-0e1d-7c033d847a6c.png)


上記の例では、Vendor ID は、
10c4
です。

serial.js を次のように書き換えます。

```text:serial.js
（省略）
const filter = { usbVendorId: 0x10c4 };
port = await navigator.serial.requestPort({ filters: [filter] });
（省略）
```
新卒で入社した会社を退職しての感想

## １．この記事について

新卒で入社した会社を退職しての個人的な感想です。今後、転職する際の自分自身への参考となるように書いています。

## ２．経歴について

- 年齢　　　　　　　　　：　25歳
- 性別　　　　　　　　　：　男
- 学歴　　　　　　　　　：　情報系学部卒
- 在籍期間　　　　　　　：　2年6ヶ月
- 勤務形態　　　　　　　：　SES(客先常駐/出社)
- プロジェクトフェーズ　：　保守(一部開発あり)

## ３．参画プロジェクト/担当業務

- 参画プロジェクト　：　マーケティンオートメーションツール保守
- 参画期間　　　　　：　2年(2022/9~2022/9)
- 担当業務　　　　　：　
  -  定常的なシステム監視
  -  顧客からの問い合わせ対応
  -  機能改修時のテスト対応(結合テスト、総合テスト)
  -  インシデント恒久対応としての本番設定変更のための検証/手順書作成

## ４．退職理由

1. 評価制度が不明確。いまいち周知されていない。
　 一応、キャリアレベルが設定されてはいるが年功序列なのか年次で上がるっぽい仕組み。

2. 定期的な面談もない。
　　同一部署内で誰かが辞めるとなった場合に、申し訳程度で実施するくらい。
　　2年間で1回と退職直前の1回のみ。

3. 作業時間超過しても、改善しようとしないプロジェクトに対して契約を切ろうとしない
　　毎月のように作業時間を超過しているにもかかわらず、顧客へは作業の優先度の
　　調整のみ。山積みの課題を先延ばしにする。
　　この状態がずっと続くプロジェクトからの撤退を考えない。

## ５．今までで学べたこと

- 保守としての立ち回り(障害対応や問い合わせ等)
- テスト工程を一人称で実施できたこと
- SEとしての基礎的な部分
- 社会人としてのドキュメント作成や心構え
- 問い合わせやレビュー時の顧客とのコミュニケーション

## ６．これからについて

保守フェーズもそれなりに面白かったしやりがいもあったが一旦当分はいいかなという感じ。今はとにかく開発(コーディング、テスト)がやりたい感じ。

## これからの自分自身へ

- 有給は全て消化しろ
- 次の契約の２ヶ月前くらいには退職の意向を伝えとく
- 現場のリーダーに伝えてダメなら、遠慮せずに上の役職の人に伝えること
enebularでkuromoji その5

# 概要
enebularでkuromojiやってみた。
練習問題やってみた。

# 練習問題
クイズを作って見て。

# 参考にしたページ

https://qiita.com/zakiyama2918/items/0329e54ef23978a60574

# 方針
- 名詞と「が」「から」「を」で、判断する。

# サンプルコード

```


var endpoint = "https://ohiapp0.herokuapp.com/kuromoji?token=";
var src = document.getElementById('src');
var out = document.getElementById('out');

function send(msg) {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			var str = "";
			var data = JSON.parse(xhr.responseText);
      for (i = 0; i < data.length; i++)
			{
				if (data[i].pos == "名詞" && data[i + 1].surface_form == "が")
				{
					str += "q: ";
					for (j = 0; j < i; j++)
					{
						str += data[j].surface_form;
					}
					str += "何";
					for (j = i + 1; j < data.length; j++)
					{
						str += data[j].surface_form;
					}
					str += "か\n";
	        str += "a: " + data[i].surface_form + data[i + 1].surface_form + "\n\n";
				}
      }
			for (i = 0; i < data.length; i++)
			{
				if (data[i].pos == "名詞" && data[i + 1].surface_form == "から")
				{
					str += "q: ";
					for (j = 0; j < i; j++)
					{
						str += data[j].surface_form;
					}
					str += "何";
					for (j = i + 1; j < data.length; j++)
					{
						str += data[j].surface_form;
					}
					str += "か\n";
	        str += "a: " + data[i].surface_form + data[i + 1].surface_form + "\n\n";
				}
      }
			for (i = 0; i < data.length; i++)
			{
				if (data[i].pos == "名詞" && data[i + 1].surface_form == "を")
				{
					str += "q: ";
					for (j = 0; j < i; j++)
					{
						str += data[j].surface_form;
					}
					str += "何";
					for (j = i + 1; j < data.length; j++)
					{
						str += data[j].surface_form;
					}
					str += "か\n";
	        str += "a: " + data[i].surface_form + data[i + 1].surface_form + "\n\n";
				}
      }
    	out.value = str;	
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
			//alert(xhr.responseText);
		}
	};
  var uri = endpoint + msg;
	xhr.open("GET", uri, true);
	xhr.send();
	//alert("ok");
}

function run() {
  send(src.value);
  //src.value = '';  
};




```

# 実行結果

```
q: 今朝何が川から拾った桃を切ろうとしたら、桃が突然割れて中から男の子が飛び出してきたか
a: おばあさんが

q: 今朝おばあさんが川から拾った桃を切ろうとしたら、何が突然割れて中から男の子が飛び出してきたか
a: 桃が

q: 今朝おばあさんが川から拾った桃を切ろうとしたら、桃が突然割れて中から何が飛び出してきたか
a: 男の子が

q: 今朝おばあさんが何から拾った桃を切ろうとしたら、桃が突然割れて中から男の子が飛び出してきたか
a: 川から

q: 今朝おばあさんが川から拾った桃を切ろうとしたら、桃が突然割れて何から男の子が飛び出してきたか
a: 中から

q: 今朝おばあさんが川から拾った何を切ろうとしたら、桃が突然割れて中から男の子が飛び出してきたか
a: 桃を


```

# 成果物

https://embed.plnkr.co/plunk/soAxxgD69RB9efrT


以上。
shouldForwardPropを調べたので備忘録としてまとめておく

# はじめに

material-uiの勉強をした時にサンプルコードにshouldForwardPropが良く出てきたので調べた結果を備忘録としてまとめておく。

## shouldForwardPropとは？

shouldForwardPropとはstyled-componentsに対して渡されたpropsをDOM要素にまで伝播させるかを指示するために使用する機能のこと。

例えば以下のようにshouldForwardPropが未指定の場合、DOM要素までpropsが伝播されることはない 
(デフォルトではpropsをDOMに伝播させないようになっている)
```
import styled from "@emotion/styled";

const MyBox = styled("div")`
`;

export default function App() {
  return (
    <MyBox prop1="hoge" />
  );
}
```
![スクリーンショット 2022-10-02 10.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321713/d7690410-9357-ec70-0b5c-eda89486f3e6.png)

しかし、以下のようにコードを変更する。
```
import styled from "@emotion/styled";

const MyBox = styled("div", {shouldForwardProp: (prop) => prop === "prop1"})`
`;

export default function App() {
  return (
    <MyBox prop1="hoge" />
  );
}
```

そうするとDOM要素までpropsが伝播されるようになる。
![スクリーンショット 2022-10-02 10.07.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321713/e64727b9-3540-ed6e-c298-212ab3034fbe.png)

## 最後に

コンポーネントを経由させずに直接DOMに渡したい時に使うのかな？という感じ。
ただmaterial-uiのサンプルコードではデフォルトではDOMに伝播させないにもかかわらず、敢えて ```prop !== "open"``` のように判定して使用しているのでどちらかというと明示性のために使用しているのかも。

詳しいかた教えていただけると幸いです。
enebularでkuromoji その4

# 概要
enebularでkuromojiやってみた。
練習問題やってみた。

# 練習問題

文字をデコって見て。

# 参考にしたページ

https://qiita.com/j5c8k6m8/items/b5df0703729a050f19ee

# 方針
- 名詞、助詞でcssを変える。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1a6baca9-2a05-867b-c4c5-d1cdcac3be20.png)

# サンプルコード

```

var endpoint = "https://ohiapp0.herokuapp.com/kuromoji?token=";
var src = document.getElementById('src');

function send(msg) {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			var str = "";
			var data = JSON.parse(xhr.responseText);
      for (i = 0; i < data.length; i++)
			{
				if (data[i].pos == "名詞")
	        str += '<span class="ne ">"' + data[i].surface_form + '"</span>';
				if (data[i].pos == "助詞")
	        str += data[i].surface_form;
      }
			var elem = document.getElementById("test");
			elem.innerHTML = str;	
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
			//alert(xhr.responseText);
		}
	};
  var uri = endpoint + msg;
	xhr.open("GET", uri, true);
	xhr.send();
}
function run() {
  send(src.value);
  //src.value = '';  
};




```

# 成果物

https://embed.plnkr.co/plunk/ZVC0pwxwPBJlZLWM

以上。
AWS 構成図作成ツール diagram.net (旧draw.io)

diagrams.net(旧draw.io※)でAWSの構成図を手軽に描いてみる。

※draw.ioはセキュリティ上の理由から2020年にdiagrams.netに名称変更
　https://www.diagrams.net/blog/move-diagrams-net

---
diagrams.netにアクセスし「Start」を選択。
https://www.diagrams.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/32214657-8e77-2c89-0246-3b17109fee58.png)

「新規ファイルを作成する」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/2dce2caa-9053-d720-1652-0aa6caaeb64f.png)

「白紙ファイル」を選択し「作成する」をクリック。
（画面上部の「ファイル名」はこの時点では何でもOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/dec9fa88-8253-0d0b-61ee-111b10f69085.png)

「保存先」と「ファイル名」を入力し「保存」をクリック。
（今回はデスクトップにtestという名で保存）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/6c5306b3-0f90-c588-96ec-74cf634109f0.png)

設定から対象図形にAWSを追加する。
（diagrams.netはAWS以外の様々な構成図作成に対応している。AWSの図形はデフォルトで取り込まれていないのでここで設定する)
左メニュの「＋その他の図形」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/eddc6b74-a5aa-78c6-4799-827e968c9d4c.png)

「AWS19」を選択し「適用」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/3b98f2e7-fe61-1894-c3fc-22d4935bb800.png)

以上で準備は完了。
左メニューから図形を選択し描写していく。

例えばVPCを挿入するなら、
左メニュー上部の検索バーで「VPC」を検索 → 図形を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/0f939dfe-ed71-b35d-42c7-fb8c64bada08.png)


あとは直観で操作できるはず。

図形の大きさを変えるなら、図形を選択し青●を引っ張ったり縮めたり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/3a8709bf-fa1e-3fac-65b2-f92bb59f7d16.png)
↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/b484cd58-543b-164c-81d2-9e30e9d78744.png)

テキストを挿入したいなら、挿入位置をダブルクリックし「Text」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/e246767f-3d6d-ab9d-f17c-66ae3d201413.png)

テキストオブジェクトが挿入されるので、任意の文字を入力すればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/9ee29bd8-f631-f744-3eda-0f5fb75837ec.png)

図形同士に線を引きたいなら、わざわざ左メニューから線図形を選ばずとも
始点をクリックしドラックしたまま終点に持っていけば線が引ける。
(始点はカーソルを合わせれば薄い緑●になるのでそこをクリック＆ドラック）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/03607bd7-75f1-d533-3365-036c7374dcef.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/9aef5b69-e245-7fa9-60a4-36e45c12f3d1.png)


保存は自動で行われる。
図形を更新すると「保存中」と表示され、すぐに「すべての変更を保存しました」となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/676d97a4-d33b-ef79-5c5b-f50bced28ce2.png)
↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/f634bb8d-af7b-60c0-138b-23a0aa1839f9.png)


保存した構成図をあとから編集する場合は
「新規ファイル」ではなく「既存のファイル」から始めればOK。
https://www.diagrams.net/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/bf298ae5-4747-5139-0362-512e9825646d.png)
↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/f48ddd11-7b46-38e9-2d2c-d2f48f17238b.png)

以上です。おつかれさまでした。
groupメソッドの応用(関連先テーブルのデータをグループ化して表示する方法)

# groupメソッドとは？

指定したカラムの各値ごとにグループ化するメソッド。

下記のテーブルから、各ownerのcatの数のデータを抽出してみる。

![20221002_ownersテーブルの画像(sex,incomeカラムとレコード数を追加).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829500/e9612fcb-30c4-4d06-89a9-dc456f8cd5e6.png)

![20221002_catsテーブルの画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829500/124c390f-0e08-8419-e6b4-cacd87ec2dcd.png)
￼
￼

（catsテーブルからowner_idごとにグループ化し、ownerごとに何匹ネコを飼っているか数え上げる）
```
irb(main):045:0> Cat.group(:owner_id).count
   (0.2ms)  SELECT COUNT(*) AS count_all, "cats"."owner_id" AS cats_owner_id FROM "cats" GROUP BY "cats"."owner_id"
=> {1=>2, 2=>1, 3=>1}
```
この場合、owner_id=1の人（田中さん）が2匹、owner_id=2の人（伊藤さん）が1匹、owner_id=3の人（高橋さん）が1匹
ただこれだと少しわかりにくい。。。（理想は、〇〇さんが何匹飼っているみたいにわかれば良い。）

今度は、各ownerがcatを何匹飼っているのかをownerのnameごとに分けたネコの数のデータ抽出してみる。

結果は、下記の通り。

（catsテーブルとownersテーブルを内部結合したデータを抽出。つまり今回でいうと飼われているcatのみのデータが残る。）
```
irb(main):052:0> Cat.joins(:owner)
  Cat Load (0.3ms)  SELECT "cats".* FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" /* loading for inspect */ LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Cat id: 1, name: "クロ", owner_id: 2, created_at: "2022-10-01 01:17:50.679955000 +0000", updated_at: "2022-10-01 01:17:50.679955000 +0000">, #<Cat id: 2, name: "モモ", owner_id: 1, created_at: "2022-10-01 01:18:33.127365000 +0000", updated_at: "2022-10-01 01:18:33.127365000 +0000">, #<Cat id: 3, name: "ハナ", owner_id: 3, created_at: "2022-10-01 03:10:26.125535000 +0000", updated_at: "2022-10-01 03:10:26.125535000 +0000">, #<Cat id: 4, name: "ミー", owner_id: 1, created_at: "2022-10-01 01:19:31.494863000 +0000", updated_at: "2022-10-01 01:19:31.494863000 +0000">]>
```
↓
今回は、catsテーブルのcatは全て飼われているので、catsテーブルは上記の内容のままである。

（次に、内部結合したcatsテーブルをownersのnameごとにグループ化し、そのcatの数を出力しようとし、下記コマンドを実行。）
```
irb(main):053:0> Cat.joins(:owner).group("owner.name").count
   (0.7ms)  SELECT COUNT(*) AS count_all, "owner"."name" AS owner_name FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" GROUP BY "owner"."name"
Traceback (most recent call last):
        1: from (irb):53
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: owner.name)
```
↓
ただし、エラー発生。ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: owner.name)の内容は、「ActiveRecord::StatementInvalid (SQLite3::SQLException: そのような列はありません: owner.name)」。
つまり、ownerにはnameカラムがないということ。groupメソッド内の引数owner.nameのownerをownersに変更し、そのnameカラムの値ごとにグループ化する。
（*今回の状況で使用したgroupメソッドの引数には、owners.nameのようにテーブル名.カラム名でなければ、グループ化できないらしい。）

（ownersテーブルのnameの値ごとにグループ化し、それぞれのcatの数を数える。）
```
irb(main):054:0> Cat.joins(:owner).group("owners.name").count
   (0.3ms)  SELECT COUNT(*) AS count_all, "owners"."name" AS owners_name FROM "cats" INNER JOIN "owners" ON "owners"."id" = "cats"."owner_id" GROUP BY "owners"."name"
=> {"伊藤"=>1, "田中"=>2, "高橋"=>1}
```
↓
上記内容より、伊藤さんは1匹、田中さんは2匹、高橋さんは1匹といったデータを得ることができた。
DXスキルツリーにMidjourneyで画像を付けてみました

データサイエンティストやビジネスアナリストなどDXの様々な職業に関して，スキルや実際に必要とされる場面を整理した [DXスキルツリー](https://qiita.com/shore/items/555fbf706b36315e81f1 "DXスキルツリー") を以前に公開しました．

前回はちょっと生真面目だったため，「様々な職業がパーティを組んで困難に立ち向かう」RPGとの関連性が伝わるよう，Midjourneyで生成した画像を付けた別バージョンを公開しました．

◇元ファイル: [Midjourney版 DXスキルツリー](https://drive.google.com/file/d/1XlGRGOYC-tlNvsvownQ5OZSzRhVOUHGc/view "Midjourney版 DXスキルツリー")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/9ec23adf-bd4f-6e95-2da4-fc0dfe7748ab.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/b24011f5-c75b-734b-56ec-a222b244ae2c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/b4122552-3547-525b-d338-031964a9f0f3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/d55d6eed-8760-bf9f-3a23-f059a66361c8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/c9ccd48e-d21c-23be-843e-fea481523442.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/a5d29125-3f77-c3e8-3921-83e1b12b11e3.png)

一部加筆していますので，デザイン以外にも若干のアップデートがあります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/2d6e470c-d826-3d94-5ab3-2e5796bf2671.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/975198da-a73b-0362-e4f2-0904621d5f51.png)

あくまでイメージ画像なので各職業の特徴にぴったりとはいきませんでしたが，少しでも身近に感じていただければと思います．

<BR><BR>
(以下ボツ画像集)

弓矢が出ない…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/625a4355-d154-392b-e860-24fcd0fc29b2.png)
無骨すぎる斧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/81feddf2-ea7c-fe8a-6fb5-36accc999842.png)
違う世界線の兜
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/8e590848-f5c2-dff4-7bd3-0a6a8e7cbf70.png)
家族連れ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/f5adf81b-f073-3d2f-45a1-a18599bcb342.png)
野外パーティと化すDX journey
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539151/88e82e95-8b3e-926d-9b6b-4e70cee097ad.png)
sshでトンネリングやプロキシを構築したとき "open failed: connect failed:" が出るときの対処法

## 症状
 - sshでトンネリングやSOCKSプロキシを構築したが`channel 329: open failed: connect failed: open failed` と吐いてたまに機能しなくなる

## 対処法
sshdの設定の`MaxSessions`を超えてるのが原因。
`/etc/ssh/sshd_config`を開きコメントアウトされている`MaxSessions`を探す。見つけたらコメントを外し適当な値を入れる。

Before:
```
#MaxSessions 10
```

After:
```
MaxSessions 40
```
RustのWEBフレームワーク「Actix-web」のドキュメント邦訳に挑戦してみた

ご無沙汰してます。カニさんです🦀

前回の記事で、[Tauriでのデスクトップアプリ開発がある程度形になったらQiitaに戻ってくる](https://qiita.com/wipRust/items/19a46bc471e94f471f34#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB)と書きましたが、相変わらず進捗ありません。他人のチュートリアルをこなしてるだけでは技術力は上がりませんね。

## WEBナンモワカラン

そんなこんなでTauri開発は一旦中止し、”何がわからないのか” を見つめなおしたところ、圧倒的にWEB周りの知識が不足している事が原因だな、と。

そんなわけでRustのWEBフレームワークの定番？Actix-webの邦訳に挑戦してみました。ドキュメントを嘗め回すように読んでいけば、自ずと必要な知識が吸収できるだろうという魂胆です。

今後自分がActix-webのドキュメントを読む際にも活用できるし、あわよくば他の開発者の皆様にも活用してもらえるかも思いましたが、まともにWEB開発した事が無い上に、ところどころ翻訳に自信が無い部分があるため、一旦Qiitaで晒してフィードバックを貰っちゃおうっと🦀

あまりにヒドイという意見が多かったら全部非公開にしますし、改善の余地ありとご判断頂けるのであれば、今後[Basics](https://actix-website.netlify.app/docs/getting-started)のみならず[Advanced](https://actix-website.netlify.app/docs/errors)の翻訳にも挑戦してみようかと思います。

https://actix.rustify.me/

いつものようにデプロイ先はCloudFlare Pagesで、本家本元の[Docusaurus](https://docusaurus.io/)ソースコードをそのまま流用させて頂きました。

https://github.com/actix/actix-website

翻訳はもちろんDeepLを使用しましたが、訳文は全て目を通しているので、DeepLでは意味がわかりづらいと感じた部分は人力で翻訳しました。



## 翻訳してみた感想

### DeepL信仰を捨てた
普段英語のドキュメントを参照する時は、DeepLに丸投げで勝手に分かった気になっていたのですが、いざ原文と和訳を照らし合わせてみると、ごくたまにではありますが、DeepLの和訳と原文が全く逆の意味になっていたり、語順がめちゃくちゃだったりといった事もあり、普段のドキュメント参照方法を改める必要があるなと気付かされました。

（Pro版だと精度は高い🦀？）

### 理解していない事は説明できない
何をいまさらと思われるかもしれませんが、用語であれ概念であれ、知らない、理解していないものというのは、たとえ翻訳が用意されていようと自分の言葉で説明できないのです！🦀オドロキッ

DeepL → 和訳読む → 原文読む → 和訳で未知の単語をGooglin' → サンプルコードを眺める → Gotcha!!

### 純粋に英語の勉強にもなった

[Gotchaが名詞で使われてる](https://eigobu.jp/magazine/gotcha#heading-2274)の初めてみました。しかも複数形。

https://actix-website.netlify.app/docs/autoreload#historical-note

### CloudFlareを崇める
Herokuを知らない世代（一度も触らず気付いたら有料化してた）なので、無料で使えるデプロイ先はCloudFlareしか使ってません。[ブログ](https://rustify.me/)もCloudFlare Pagesを利用していますし、Githubワカラナイ勢でもデプロイまでできた（今はさすがにGithub経由でデプロイしてます）ので、本当にプログラミング入門者フレンドリーなサービスだと思います。
HUGOやZola、Docusaurusなどのデプロイ手順も[公式](https://developers.cloudflare.com/pages/framework-guides/)で事細かに解説されているので、お金を掛けずに、しかも短時間でブログやサイトを一般公開できます。

独自ドメイン・サブドメインの設定もストレスフリーで~~AWSとは大違いで~~す。~~許すまじ高額請求~~

## 非礼があれば…

１年以上趣味でプログラミングを続けているものの、業界のお作法だったり、Githubの使い方だったりは相変わらずよくわかってませんので、修正や訳文に関する提案などは、[Twitter(@wipRust)](https://twitter.com/wipRust)の方にお寄せ頂けますと幸いです。
今すぐ閉鎖しろとかエンコ詰めろみたいなの以外は、なるべく真摯に対応致します。
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その041

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
データ管理と分析管理の演習

にある練習問題9問目をご紹介します

https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/review-data-management?trail_id=administrator-certification-prep

今回の内容は動画でも解説しています

https://www.youtube.com/watch?v=XjLLUZJpz3Y

<iframe width="560" height="315" src="https://www.youtube.com/embed/XjLLUZJpz3Y" 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/0c8729f4-ac04-4c83-5561-85de7dfb023e.png)


正解はAとBです

まず、問題を整理します

今回の問題には「インポートとエクスポート」がありますね
「インポートとエクスポート」なのでデータローダを使用することが分かります

似たような機能でインポートウィザードというものがありますが、インポートウィザードはエクスポートができないので今回の内容は「データローダを使用するために必要な権限」ということが分かりますね

データローダの使用するための権限はこちらのヘルプに記載されています

ヘルプ　
レコードをインポートするのに必要な権限は何ですか?
https://help.salesforce.com/s/articleView?id=sf.faq_import_general_permissions.htm&type=5


データローダ
データローダでのレコードのインポートには、次の権限が必要です。

オブジェクトに対する「参照」、「作成」、「編集」、および「削除」
「API の有効化」
「Bulk API の物理削除」 (Bulk API を使用してレコードを物理削除するようにデータローダを設定している場合のみ)


![データローダ01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/98ca169a-9df5-4e9d-dbcb-6e0c8ea52311.png)

さて、このヘルプを見ながらデータローダに必要な権限はどれか確認しましょう
一つは

・APIの有効化
ですね。

もう一つは
「参照」、「作成」、「編集」、および「削除」
ですが、これは「すべて変更」のオブジェクト権限があれば「参照」、「編集」、および「削除」の権限が自動付与されるので正解ですね



Cが間違いの理由は
「すべてのデータの参照」を設定すれば今回の取引先などのオブジェクト限定でなくすべてのオブジェクトのアクセスが可能になるので間違いです

Dはデータのバックアップファイルを作成できる設定なので間違いです
（インポートはできないですね）

データのバック詳細はこちらのヘルプをご参照ください

https://help.salesforce.com/s/articleView?id=sf.admin_exportdata.htm&language=ja&r=https%3A%2F%2Fwww.google.com%2F&type=5
あれ？ Voltaを使ってるんだけど「node」にPATHが通ってないぞ？

毎回忘れててググっているのでメモ

# 環境

MacOS 12.5.1
Volta 1.0.8

# 事象

`node`コマンドが通らない

```terminal
% node -v
zsh: command not found: node
```

# 解決策

PATHを通す

```~/.zshrc
︙
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
```

# 参考

https://zenn.dev/taichifukumoto/articles/how-to-use-volta#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%95%E3%82%8C%E3%81%9F%E3%81%93%E3%81%A8%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B
AmazonLinux 2022 で gpg-agent がないと怒られた時の対処法

# 遭遇した問題
AmazonLinux 2022 のイメージ上で、 asdf を導入して yarn をインストールしようとしたところ、 gpg-agent がないよと怒られた。

# 対処法

デフォルトのイメージに導入済みのパッケージを調べたところ、 gnupg2-minimal.x86_64 が有効になっていた。が、こちらのパッケージには gpg-agent が同包されていない模様。


```bash
> dnf list | grep gnupg
gnupg2-minimal.x86_64                                             2.3.7-1.amzn2022.0.1                        @System    
gnupg2.x86_64                                                     2.3.7-1.amzn2022.0.1                        amazonlinux
gnupg2-smime.x86_64                                               2.3.7-1.amzn2022.0.1                        amazonlinux
```

以下のコマンドで gnupg2.x86_64 を導入し直すと、 gpg-agent も使用できるようになるが、普通に導入しようとすると導入済みパッケージとコンフリクトを起こしてしまうので、 --allowerasing オプションをつけてインストールする。

```bash
> dnf -y install gnupg2 --allowerasing
```

すると、  gnupg2.x86_64 が有効化され、 gpg-agent が使用できるようになる。

```bash
> dnf list | grep gnupg
gnupg2.x86_64                                                     2.3.7-1.amzn2022.0.1                        @amazonlinux
gnupg2-minimal.x86_64                                             2.3.7-1.amzn2022.0.1                        amazonlinux 
gnupg2-smime.x86_64                                               2.3.7-1.amzn2022.0.1                        amazonlinux
```