OmniAICreator/Qiita-1.07M huggingface dataset:
画面のここ！直して！って時に使えるDevToolsとCSS

## 背景
オンラインでWebサイトやブラウザで動くシステムのここ、直してほしいんだよなーという時、皆さんはどうしていますか？テキストだけで伝えて「これで伝わるかなあ」と不安になったり、スクショを撮ってペイントで枠を囲ってそれをまたスクショして送ったりしてきました。

## やりたいこと
指摘やコメントをしたい要素に赤枠をつけたい
例：投稿するボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413623/677146d6-6bcc-ca53-f84f-73df30412e10.png)

## 環境
Chromeでやってます。

## やり方
### 1.DevToolsを開く
F12を押しましょう。開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413623/c2efc264-b0d2-4b7d-7137-0ea34f1b6900.png)

### 2.要素を選択して検査する
DevToolsの左上、角にあるアイコンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413623/8961eb19-5ae6-96f7-78b7-68dc5fc6aaa4.png)

### 3.枠をつけたい要素を選択する
わかりづらいですが、投稿するボタンを選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413623/bc6074ae-02d7-9ba8-d527-646573fbf082.png)

### 4.element.styleにCSSを書く
次の3行をコピペしましょう。
```
border-width: 3px;
border-color: red;
border-style: solid;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413623/94d87e42-b9d4-79ae-3899-304384642096.png)

できた！投稿するボタンが赤枠で囲まれました～
ちょっとしたことだけど、ペイント開かなくていいのはだいぶ楽
WindowsにVagrantとVirtualboxをインストール（Dckerインストール済）

WindowsでVagrant VirtualBox をインストールしました。
Docker　Disktopもインストールされています。
WindowsでDockerをインストールしているとHyper-Vを使用しているので、Vagrantと競合して使えない。
今回はDockerはWsl2とWindws11のUbuntuを介して使用しているので、Hyper-Vを使用していません。
Dockerと併用して使えると思いました。
mainとServer1,Server2という3つのサーバー構成で作りました。
しかし、いざVgrant upコマンドを実行すると以下のエラーが発生します。


````
    main: SSH auth method: private key
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you're using a custom box, make sure that networking is properly
working and you're able to connect to the machine. It is a common
problem that networking isn't setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout ("config.vm.boot_timeout") value.
````
「仮想マシンプラットフォーム」のチェックを外したらエラー内容が変化はしましたが、
変わりません。
「仮想マシンプラットフォーム」が大事でDockerで使用しています。
Vagrantのconfig.vm.boot_timeout値を増やすことも検討しました。
デフォルトでは300秒（5分）に設定されていますが、ゲストマシンの起動に時間がかかる場合は、この値を増やしてみることができます。
vagrantfile
````
config.vm.boot_timeout = 600 
````
正常に動作しました。
PCの環境によっては「仮想マシンプラットフォーム」を使いDockerとVagrantを使えるかもしれません。
私のマシンではDockerを使う時は「仮想マシンプラットフォーム」をチェックして切り替える必要があります。
pandasのSeriesの要素の中で最大の桁数・文字数を取得する

## 関数
``` Python
import pandas as pd

def max_digits(series):
    """
    pandasのSeriesが与えられたとき、Seriesが数値型の場合は数値の最大桁数を返し、文字列型の場合は最大文字数を返す。

    引数:
        series (pd.Series): pandasのSeries

    戻り値:
        int: Seriesの要素の中の最大の桁数もしくは文字数
    """
    # seriesが空の場合は0を返す
    if len(series) == 0:
        return 0

    # seriesの型に応じて処理を分ける
    # seriesが数値型の場合は数値の桁数を返す
    if series.dtype == 'int64':
        return int(series.abs().apply("log10").max()) + 1
    # seriesが浮動小数点型の場合は小数点以下の桁数を返す
    elif series.dtype == 'float64':
        return series.abs().astype(str).str.len().max()-1
    # seriesが文字列型の場合は文字数を返す
    elif series.dtype == 'object':
       return series.str.len().max()
```

## 使用例
``` Python
# 整数(正の値): 最大桁数を返します
print(max_digits(pd.Series([123, 45678, 9, 123456789])))  # 9

# 整数(負の値): 絶対値の最大桁数を返します
print(max_digits(pd.Series([123, 45678, 9, -123456789])))  # 9

# 小数: 整数部分と小数部分の桁数を足した最大桁数を返します
print(max_digits(pd.Series([123, 45678, 9, 123456, -1.23456789]))) # 9

# 文字列: 文字数を返します
print(max_digits(pd.Series(['A', 'BB', 'CCC', 'DDDD'])))  # 4

# 空のSeries: 0を返します
print(max_digits(pd.Series([], dtype=float)))  # 0
```
スプレッド構文と分割代入のreactで大切な｛｝の意味など

スプレッド構文と分割代入は、ES6（ECMAScript 2015）で導入されたJavaScriptの機能です。それぞれの機能と使用例について説明します。

1. **スプレッド構文 (`...`)**

   スプレッド構文は、配列やオブジェクトの要素を個別に展開するための構文です。

   - 配列の場合：
     ```javascript
     const arr1 = [1, 2, 3];
     const arr2 = [...arr1, 4, 5];  // [1, 2, 3, 4, 5]
     ```

   - オブジェクトの場合：
     ```javascript
     const obj1 = { a: 1, b: 2 };
     const obj2 = { ...obj1, c: 3 };  // { a: 1, b: 2, c: 3 }
     ```

2. **分割代入 (Destructuring Assignment)**

   分割代入は、配列やオブジェクトの要素やプロパティを変数に直接代入するための構文です。

   - 配列の場合：
     ```javascript
     const arr = [1, 2, 3];
     const [a, b, c] = arr;  // a = 1, b = 2, c = 3
     ```

   - オブジェクトの場合：
     ```javascript
     const obj = { x: 10, y: 20 };
     const { x, y } = obj;  // x = 10, y = 20
     ```

   関数の引数としても分割代入を使用することができます。例えば、以下のように関数の引数をオブジェクトとして受け取り、その中のプロパティを直接変数として抽出することができます：
   ```javascript
   function myFunction({ params }) {
     console.log(params.id);
   }
   ```

これらの機能は、コードの可読性を向上させるために広く使用されています。特にReactやその他のフレームワーク・ライブラリでのコンポーネントのプロップスの取り扱いなど、多くのシチュエーションで役立ちます。


---
応用①｛｝の意味分割代入（オブジェクト）
---
Reactのコンポーネントのプロップス（props）に関しても、JavaScriptのスプレッド構文や分割代入を使用することが一般的です。これらの機能は、Reactのコンポーネントをより柔軟かつ簡潔に扱うのに役立ちます。

1. **スプレッド構文を使用したプロップスの渡し方**:
   スプレッド構文を使用すると、オブジェクトのすべてのキーと値を別のオブジェクトやコンポーネントのプロップスとして展開することができます。

   ```jsx
   const personProps = {
     name: 'Alice',
     age: 30
   };

   <PersonComponent {...personProps} />
   ```

   上記の例では、`PersonComponent`は`name`と`age`の両方のプロップスを受け取ります。

2. **分割代入を使用したプロップスのアクセス**:
   コンポーネントの関数本体内で、分割代入を使用してプロップスから直接変数を抽出することができます。

   ```jsx
   function PersonComponent({ name, age }) {
     return <div>Hello, {name}! You are {age} years old.</div>;
   }
   ```

   上記の例では、`PersonComponent`は`name`と`age`のプロップスを直接分割代入を使用してアクセスしています。

これらのテクニックは、Reactのコンポーネントを扱う際のコードの可読性や簡潔性を向上させるのに役立ちます。そして、これらはJavaScriptの機能であるため、Reactに限らず他のフレームワークやライブラリでも同様の方法で使用することができます。


補足　オブジェクトのスプレッド構文
---
```javascript
let obj1 = { foo: "bar", x: 42 };
let obj2 = { foo: "baz", y: 13 };
const merge = (...objects) => ({ ...objects });

let mergedObj1 = merge(obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

let mergedObj2 = merge({}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
```


---
応用②{ params }: { params: { id: string } }引数にこんなことできるの？
---

それはTypeScriptの機能を使用した関数の引数の型注釈の例です。

この構文は、関数の引数がオブジェクトであり、そのオブジェクトの中に`params`というキーが存在し、その`params`もまたオブジェクトで、その中に`id`という文字列型のキーが存在することを示しています。

具体的な例を見てみましょう：

```typescript
function myFunction({ params }: { params: { id: string } }) {
  console.log(params.id);
}

const data = {
  params: {
    id: "123"
  }
};

myFunction(data);  // 123
```

このように、関数`myFunction`は`data`というオブジェクトを引数として受け取り、その中の`params.id`をログに出力します。

つまり引数の元の値がparamsならfunctionもparamsにしないと駄目

この構文は、TypeScriptを使用している場合に特に役立ちます。JavaScriptのみを使用している場合、このような型注釈は使用できません。
if文においてnilも偽となれるの意識できてますか？

## はじめに

プログラミングにおいてif文は相当な頻度で使われていると思いますが、どんな時に使っていることが多いでしょうか？:open_mouth:

私はこのように
trueとfalseの時に使っているイメージが多かったです。
```ruby:true?false?.rb
# 数値を使った条件
a = 1

if a > 0
  puts "aは1より大きいのでtrue：これは表示されます。"
end

if 1 < 0
  puts "aは1は0より小さいのでfalse：これは表示されません。"
end
```

しかし、処理結果がnilであった場合も
処理内容をスキップして使ったことはありますか？

## if文のおさらい

すごい基礎的なことですが、if文は条件文の処理結果が真であれば指定した処理内容を実行、偽であれば処理内容を実行しないものとなります。

ただ、偽 = falseのイメージが強く、
nilも偽として扱っているのを忘れていくことありませんか？:open_hands:

つまり、以下の通りになります:point_up:
```ruby:if_explanation.rb
if 条件文の処理結果はtrue?false?nil?
 "trueだったら処理文の実行"
end

falseとnilだったら処理スキップ
```
```ruby:if_explanation.rb
if true
  puts "これは実行されます"
end
#=> 出力あり:これは実行されます

if false
  puts "これは実行されません"
end
#=> 出力なし

if nil
  puts "これも実行されません"
end
#=> 出力なし
```

## 処理結果がnilの時の例文

では、条件文の処理結果がnilだと偽となることはどのように利用できるのでしょうか？？

例えば、動物を入力するとスコア化するプログラムがあるとします:rolling_eyes:

(ネコとイヌは特に私が好きなので点数を高く設定しています:joy:)

:::note warn
コードは少し長いので全部見なくても大丈夫です！
:::
```ruby:animal_score.rb
puts "動物は何匹を教えてください"
N = gets.chomp.to_i

# 入力した値を収める箱をつくる
animal_array = []
# スコアの初期値
total_score = 0

N.times do |i|
  puts "#{i + 1}匹目の動物はなんですか？"
  animal = gets.chomp
  # 箱に入力した要素を入れる
  animal_array << animal
end

# 点数変換ルール
score_hash = {
  # ネコは10点
  'ネコ' => '10',
  # イヌは8点
  'イヌ' => '8',
  # トリは5点
  "トリ" => "5"
  # それ以外は1点
}

# 変換ルールにしたがって要素を数字に変換
animal_array.each do |animal|
  if score_hash[animal]
    # 指定の動物が存在する場合、"10"などを数字型に変換してその点数を加算
    total_score += score_hash[animal].to_i
  else
    # 指定の動物が存在しない場合（nilの場合）、1点を加算
    total_score += 1
  end
end

# 合計スコアの出力
puts "合計スコアは#{total_score}点です。"
```
ちなみに入力例と出力結果はこのような感じになります！
```ruby:animal_result.rb
動物は何匹か教えてください
3
1匹目の動物はなんですか？
 ヘビ
2匹目の動物はなんですか？
ネコ
3匹目の動物はなんですか？
トリ
合計スコアは16点です。
```

今回のコードで注目してほしいのは以下の部分です
```ruby:animal_result.rb
if score_hash[animal]
  # 指定の動物が存在する場合、"10"などを数字型に変換してその点数を加算
  total_score += score_hash[animal].to_i
else
  # 指定の動物が存在しない場合（nilの場合）、1点を加算
  total_score += 1
end
```
```ruby:animal_result.rb
if score_hash[animal]
```

if文はtrueなら実行、falseとnilならスキップすると言いました。
したがって、if文の箇所はこのようになります。

:::note info
score_hash[animal]はハッシュ[キー] = 値の構文です
:::
```ruby:animal_result.rb
if score_hash[animal]
# ⇓
if score_hash["ネコ"]
# ⇓
if "10"
# ⇓
if true(すなわち真)
# ⇓
total_score += score_hash[animal].to_i
```
これで入力した値がキーで用意していれば、
total_score += score_hash[animal].to_iが実行されます！

では、逆にキーで用意していない値だとどうなるのでしょうか？:frowning2:
```ruby:animal_result.rb
if score_hash[animal]
# ⇓
if score_hash["へび"]
# ⇓
if nil(すなわち偽)
# ⇓
total_score += 1
```
入力した値がキーで用意されていなかったら、else下のtotal_score += 1の実行となります。

このように条件文の処理結果がnilであるかないかを利用して実用できることがあります。


いかがでしたでしょうか？
内容自体はすごく基礎的なことであると思いますが、私は意識できませんでした:sweat_smile:

長くなりましたが、ここまで読んで頂きありがとうざいました！お疲れ様でした:relaxed:
ローカルVSCODE➡EC2➡S３アクセスのよくあるデモでのはまりポイント

# はじめに

基本的にアーキテクトみたいな基本設計しかしていないので、たまにやる基礎的な構築でよくはまっています。
なのではまりポイントをまとめておく。

# 当社の環境
ローカルPCにはVPNが常時起動（SASE)でSSHは通信禁止。
ローカルWindowsPCではVSCODEが動いている。
IAMユーザにはMFAが必須。
IAMユーザにはAdministrator付与されている。


# 整理ポイント

### 1.VSCODEからEC2にアクセスする。

ローカルPCのVPNソフトはDisableする。
VSCODEにremoteSSHをインストールする。
remoteSSHにSSH接続先を登録する。
VSCODE左下のアイコンからアクセスする。

### 2.EC2にaws-mfaを設定する。

IAMでアクセスキーを払い出す。
EC2にログインしてaws-mfaをインストール。

```
sudo yum install python3
sudo yum install python3-pip
pip3 install aws-mfa
aws-mfa -h
```

以下コマンドでアクセスキー情報を登録(long-term必須)
```
aws configure --profile 3dep-sheep-long-term
```

さらに以下のコマンドアクセスキー情報を登録(long-termだけはずす)
```
aws configure --profile 3dep-sheep
```

以下コマンドでMFA登録する。arnはiamでなくてmfaである点を注意。
```
aws-mfa --profile 3dep-sheep --device arn:aws:iam::123456789012:mfa/sheep4life
```

### 2.EC2からS3へアクセスする。

EC2にはS3アクセス用のIAMロールを付与する。
内部アクセスする場合はvpcendpointをEC2所属のルートテーブルにアタッチする。

# まとめ

aws-mfaの設定をいつも忘れちゃうのでここにメモを記す。
あとたまにEC2のIAMロールあたっちもわすれちゃう。
【Android】触覚フィードバックをボタンにつけてみる【Kotlin】

# 触覚フィードバックとは
この単語のまま検索をかけたところ
>デバイスやシステムからユーザーの手や指に対して、振動や圧力などの物理的な刺激を与えることで、操作の結果や状態を伝える技術のこと

とあります。

androidで特定のボタンなどを押した時に、少し振動する機能のことですね。

# 実践
今回は　タイトルにもあるように　ボタンが押された時に触覚フィードバックで少し振動するようにします。

        button.setOnClickListener {
            it.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
        }


今回は　**HapticFeedbackConstants**という　直訳すると触覚フィードバック定数という、そのまんまな機能を使って実装しました。

# 参考

https://developer.android.com/reference/android/view/HapticFeedbackConstants
Slackのアプリで複数のワークスペースが重なって見にくいと感じている方へ

最近Slackのアップデートでワークスペースが重なり、左側に表示するようになりました。

複数のワークスペースにサインインしている場合は、全部見えていた方が便利だと思います。

今回はこちらを解消する方法です！

:::note warn
※ MacのPCを使用しているためMacのでの方法です。
:::

`⌘+Shift+S`
こちらのコマンドで、ワークスペーススイッチャーというのが表示できるようになります！
HookでJavaScriptを使う

- [Hookとは](#hookとは)
  - [Hookの設定](#hookの設定)
  - [Hookの作成](#hookの作成)
  - [Hookの処理を定義](#hookの処理を定義)
  - [結論](#結論)
  - [おまけ](#おまけ)
    - [LiveViewからHookに値を渡す](#liveviewからhookに値を渡す)
    - [HookからLiveViewに値を渡す](#hookからliveviewに値を渡す)

# Hookとは

Hookとは<font color="red">LiveViewのライフサイクルに合わせてJavaScriptの処理を実行</font>できるもの。

例えばheexに`<script>`で直接JavaScriptを記述したときと、
**Hookでmounted関数プロパティに処理を記述する**ことがイコールになる。

Hookを使用するために必要になる最小限の追加ファイルは次のようになる。
なお全てassets/jsのディレクトリ内である。

|ファイル or ディレクトリ |説明                           |
|---                      |---                            |
|hooks.js                 |JavaScriptをまとめるために必要 |
|/hooks                   |JavaScriptファイルを格納する   |
|/hooks/*.js              |JavaScriptファイル             |

Hookの動作としては次のようになる

1. phx-hookに<font color="red">Hookを指定したタグを記述</font>する。
2. ページが読み込まれる際、Hookが読み込まれる
3. LiveViewライフサイクルに合わせて対応する関数プロパティが実行

## Hookの設定

Hooksを使用する手順は次の通り

1. Hookを定義する
2. HookをまとめたHooksを定義する
3. app.jsに追記

Hookを生成するための準備として以下を作成する。

* hooks.js
* /hooks

Hook定義するためには、/hooksディレクトリにjsファイルを生成する。
生成したjsファイルには、**Hookオブジェクト**を作成する。

Hookを定義するための**関数プロパティ**は次のようになる。

* mounted() - mount後に実行される
* updated() - hookを適用したタグが更新されたときに実行。

その他は[こちら](https://hexdocs.pm/phoenix_live_view/js-interop.html#client-hooks-via-phx-hook)を参照する。

## Hookの作成

例としてChangeColorというHookオブジェクトを作成する。

/hooks/changeColor.jsというファイルを作成する。

とりあえず作成する際は、以下のように記述する
なおHookの関数プロパティについては後述するものとする。

```
const ChangeColor = {
  // ここに関数プロパティを記述する
}

export default ChangeColor;
```

つづいてhooks.jsで作成したHookをまとめる。

```
import ChangeColor from './hooks/changeColor'

const Hooks = {
  ChangeColor: ChangeColor
}

export default Hooks
```

app.jsに追記してLiveViewがHookを使用できるようにする。

```
...
import Hooks from './hooks'
...
let liveSocket = new LiveSocket("/live", Socket, 
  {
    params: {_csrf_token: csrfToken}, 
    // 追記
    hooks: Hooks
  }
)
```

HTMLの処理の対象となるタグの`phx-hook`にHookを指定して使用

```
<button id="change-id" phx-hook="ChangeColor">Change Color Button</button>
```

## Hookの処理を定義

例として押すとidが`target`であるタグの背景を赤色に変更する処理を定義する。

この処理はmount時にスクリプトを実行する必要があるので`mounted()`という関数プロパティに記述する。

<font color="red">phx-hookを指定した要素は`this.el`で参照</font>ができる。

よって以下のようになる

```
const ChangeColor = {
  // 追加
  mounted() {
    this.el.addEventListener('click', _ => {
      const targetElement = document.getElementById('target');
      if (targetElement) {
        targetElement.style.backgroundColor = 'red';
      }
    })
  }
}

export default ChangeColor;
```

実行すると色が変わる処理が実行されていることが確認できる。

## 結論

JavaScriptの処理を実行したり、JavaScriptのライブラリを使用する際は、Hookを使用すること。


## おまけ

### LiveViewからHookに値を渡す

イベントの処理に以下を実行する。

```elixir
push_event(socket, "sample_event", %{name: "Taro"})
```

Hook側で以下を記述する。

```javascript
this.handleEvent("sample_event", object => {
  console.log(object.name)
})
```

よって`push_event(socket, "イベント", map)`によって、Hookにmapがオブジェクトに変換されて値を渡すことができる。

### HookからLiveViewに値を渡す

LiveViewプロセスに対してイベントを送信するには、次のように記述する。

```javascript
this.pushEvent("copied_text", {名前: 値})
```

```javascript
this.pushEventTo(this.el, "copied_text", {名前: 値})
```
Reactをdocker, docker-composeで環境構築

まず、以下のコマンドでローカルにアプリを作成する。

npx create-react-app [好きなアプリ名] --template typescript

じゃないと、Dockerコンテナ内でcreate-next-appからやろうと思ったがハマってしまったため。

## Dockerfile

```
# ベースイメージの指定
FROM node:alpine

# 作業ディレクトリの設定
WORKDIR /app

# ソースをコピーする
COPY ./app .

# 依存関係をインストールする
RUN npm install

# ビルドする
RUN npm run build

# ポート3000でリッスンするように設定する
EXPOSE 3000

# アプリケーションを起動する
CMD ["npm", "start"]

```

## docker-compose.yml

```
version: '3'
services:
  web:
    container_name: reactjs_container
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development
    command: ["/bin/sh", "-c", "cd app && npm start"]

```

## 完成

![スクリーンショット 2023-10-29 19.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294049/afc97dfa-4b03-dd26-a2c2-86aece2a5b00.png)
AWS認定 AWS Certified Data Analytics – Specialty (DAS-C01) 合格記録

AWS認定 AWS Certified Data Analytics – Specialty (DAS-C01) に合格しました！

# 事前知識

受験時点で、AWSの資格は、ソリューションアーキテクトなど、3つを保持していました。
データ分析に関わる部分だと、S3、AthenaやRDSなどは普段から利用していました。

https://qiita.com/marchin_1989/items/32199930a219778337bb

https://qiita.com/marchin_1989/items/e5239de6bc05df3f4957

https://qiita.com/marchin_1989/items/077898be3b4abd6ad25d

# 学習方法

勉強方法は前回同様ですw
[要点整理から攻略する『AWS認定 データ分析-専門知識』](https://amzn.asia/d/2vuMpfG)で学習を進めました。

ほぼ1周したのみですが、問題を解いて間違えた部分、自信がない部分などを公式のドキュメントや、FAQ、ブラックベルトなどで補完し、試験に臨みました。

1ヶ月前に試験予約をして、2週間前から毎日1,2時間勉強していたので、合計の学習時間は20時間ほどだったかと思います。

どんどん短くなっていますが、データベースやソリューションアーキテクトの試験をやっていると、試験範囲に共通する部分があり、学習時間はかなり少なくて済みました。

Athenaはよく業務で使っているため、特に困らなかったのですが、Redshiftや、Kinesis Data Stream、OpenSeach Service、EMRなどは利用したことがなかったので、そこを重点的に学習しました。

# 受験

いつも受験していテストセンターで受験しました。

想定していたよりも難しく、終わった後あまり自信がなかったです。

# 結果

受験者スコア: 826 で合格でした。
# 振り返り

AWSでのデータ分析に関するサービスを体系的に学べたのは良かったかと思います。
とくに、リアルタイム分析周りはかなり勉強になったと思います。

データ分析や基盤を考える際に、データの性質や要件から、設計を考えていけそうです。
ただし、実際の業務では、泥臭い作業や複雑なデータを扱ったりするかと思いますので、より細かいサービスの知識だったり、実務的な経験などが必要だと感じました。

# まとめ

データ分析のAWSサービスについて、体系的に学ぶことができてよかったです！
次は何とろうかな！
AWS初学者がSAA-C03を受けて落ちた話

AWSの知識を深めようと思い、割引キャンペーンを利用してSAA-C03を受験。
舐めプして落ちた話です。

### スペック
レンタルサーバーやVPSでLAMP環境で開発を経験、１０年ちょっと。
転職した会社でAWSを利用して前任者が不在となってしまったのでAWSでの管理を担当することに。
それまではAWSに触れた経験０
携わって得た知識としては、EC2、RDS、S3、ALB、Route53あたり。

### 勉強方法
徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書［SAA-C03］対応
この本をとりあえず読破（１周）

AWS認定ソリューションアーキテクト－アソシエイト問題集 第2版
問題を解いた方がよいという情報を目にしたので問題を電子書籍で購入。

公式の模擬試験
試験の問題文の雰囲気になれるためにやっていたほうがよいという情報を目にして。

### 学習期間
３週間
1日1時間から2時間程度

### 試験直前に...
季節の変わり目ということもあり風邪でダウン。
2日ほど休んでしまいました。
試験前日にはうごけるようになりましたが、問題集を１周か２周解く予定が。

### 試験前日
ギリギリ問題集を１周しました。
約67%の正答率。。。。
あとは運。

### 試験当日朝
前日の問題集の不正解の箇所を復習

### 試験会場
 試験は11:00からでしたが30分前に到着。
 受付の方に、11時からのAWSで試験であること伝えて同意書を確認。
 少し早めに開始することも可能だったので早めに開始することに。

 試験は序盤の問題に時間を使いすぎて、後半は残り時間を気にしながら進めることに。
 アンケートを含めて3分前に終了。

### 試験の所感
あきらかな勉強不足を実感。
問題集をもう２周ぐらいしておくべきだったと後悔しました。
特にECS、EKS、VPC、Amazon Kinesis、AWS Patch Managerあたりが不十分だったと感じました。
このあたり学習した参考ではサラッと流した程度でした。
サービスの概要を理解した上で、要件に適したサービスの組み合わせを選択し実現するという問題になります。
このあたり純粋に学習時間不足でした。


### 試験結果
翌朝5時ごろに試験結果のメールが届いていました。
マイページにログインして結果を確認。


**不合格でした。**

予想していた通りですが、ショック。


スコアは699
![スクリーンショット 2023-10-29 18.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17764/92209b7a-491a-dac2-9544-ff35b5b66f4c.png)


あと少しだったと思うと悔しいです。
このあたりは勉強よりは経験で補ていたのかもしれません。

といっても、三つのセクションで改善が必要だったので、不甲斐ないです。

![スクリーンショット 2023-10-29 18.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17764/a9584641-e2a8-5239-2efd-ec9dcb9fd70f.png)


### 試験を受けて
試験を受けるまでは知らなかったサービスが多数。
AWSには多種多様なサービスがあります。
現在の業務で使用することはないと思いますが、それでもコスト改善につながるものだったり、
提案に使えそうなものがあったりと、知見を広める意味では受験してよかったです。

今回は10月末までの試験料金割引キャンペーンで急いで受験しましたが、結果よかったです。
先延ばしにするといつまでも受験しなかったですし、半額での不合格なので財布の傷は浅いです。
再試験は14日後以降に受験できるそうなので、再受験してみます。
その時はまた受験記をまとめてみます。


合格すると次の受験料は割引になるそうですが、不合格の場合は割引ないんですね。
もう一度、キャンペーンこないかな。
ChatGPTにlaravel10の権限設定するためのコードを聞いてみた



## 用途:

**Gate:** 特定のアクションやリソースに対するユーザーのアクセス権を判断するために使用されます。例えば、特定のユーザーが特定のリソースを編集できるかどうかを判断する際に使用されます。

**ミドルウェア:** リクエストがアプリケーションのコア部分に到達する前に、特定の条件を満たしているかどうかをチェックします。例えば、ユーザーが認証されているかどうか、または特定のIPアドレスからのリクエストかどうかをチェックする際に使用されます。

## 権限レベル定義:
まず、権限レベルを定義することが重要です。例えば、以下のように定義することができます。

1: ユーザー
5: モデレータ
10: 管理者

## Gateの定義:
App\Providers\AuthServiceProviderクラス内のbootメソッドでGateを定義します。
```php
use Illuminate\Support\Facades\Gate;

public function boot()
{
    $this->registerPolicies();

    Gate::define('isModerator', function ($user) {
        return $user->permission_level >= 5;
    });

    Gate::define('isAdmin', function ($user) {
        return $user->permission_level >= 10;
    });
}
```

## コントローラでの権限チェック:
コントローラ内でGate::allowsまたはGate::deniesメソッドを使用して、ユーザーが特定のアクションを実行できるかどうかをチェックします。

```php
use Illuminate\Support\Facades\Gate;

public function update(Request $request, Post $post)
{
    if (Gate::denies('isModerator')) {
        abort(403, 'You do not have the required permissions.');
    }

    // ... update post
}

```

## ビューでの権限チェック:
ビュー内で@canと@endcanディレクティブを使用して、ユーザーが特定のUI要素を表示できるかどうかをチェックします。

```php

@can('isModerator')
    <!-- Moderators and admins can see this -->
@endcan

```

## ルートでの権限チェック:
Route::middlewareメソッドを使用して、ルートにミドルウェアを指定し、ルートにアクセスできるユーザーを制限します。

```php
Route::put('post/{post}', 'PostController@update')->middleware('can:isModerator');

```

## 募集
アドバイス求めています。（指摘じゃなくて、アドバイスだからね。
GoでKeyとValueを逆にしたMapを作成する


goでMapを定義したときに
そのkeyとvalueを逆にする方法を紹介します。

例えば、以下のようにprotoで定義された型からアプリケーション上で定義したmodelに
マッピングするために、Mapを用いることがあるかと思うのですが、
proto->modelのMapからmodel->protoのMapを生成する方法を紹介します。

具体的には次のようなケースを想定しています。
``` go
// 以下のようなMapから
var protpToModelMap = map[v1.PaymentMethod]paymentmethod.PaymentMethod{
	v1.Credit:      paymentmethod.Credit,
    v1.PayPay:      paymentmethod.PayPay,
	v1.AuPay:       paymentmethod.AuPay,
	v1.RakutenPay:  paymentmethod.RakutenPay,

}

// 次のようなMapを作成したい時
var modelToProtoMap = map[paymentmethod.PaymentMethod]v1.PaymentMethod{
	paymentmethod.Credit:     v1.Credit,
    paymentmethod.PayPay:     v1.PayPay,
	paymentmethod.AuPay:      v1.AuPay,
	paymentmethod.RakutenPay: v1.RakutenPay,

}
```

次のような関数でKeyとValueを逆にしたMapを作成できます。

```go
// ReverseMap keyとValueを入れ替えたMapを作成する
func ReverseMap[T, S ~string | ~int](m map[T]S) map[S]T {
	n := make(map[S]T, len(m))
	for k, v := range m {
        if existKey, ok := n[v]; ok {
            panic(fmt.Sprintf("重複したkeyが存在します key:%v",existKey))
		}
		n[v] = k
	}
	return n
}

var modelToProtoMap = ReverseMap(protpToModelMap)
```

# 補足

引数で受け取るMapのkeyとvalueのジェネリクスの型に
`~`がついているのは　Underlying Type と呼ばれているもので
基礎となる型がintである型を要求していることを意味しています。
この`~`がないとgoのenumを使うときに定義される独自タイプ(例：`type PaymentMethod int`)を引数として渡すことができなくなってしまいます。

参考：https://zenn.dev/waawaa/articles/ac07cf53a69cccca156c
【PHP】例外処理

例外処理について学習した記録です。

## 例外処理とは
プログラムの実行時に発生した問題に対応できるようにしておくこと。

例）・0で割り算をする
　　・指定したファイルが存在しない
  
上記の様な問題が発生したときに、「処理を終了して、警告文を表示する」というような対応が**例外処理**という。

## 例外処理の必要性
### 例外処理がなければ…
問題が発生しても気付くことができず、大きな不具合につながってしまう。
**→異常があったことを伝えて、対応する仕組みが必要になる。**

## 例外処理の流れ

### 1. 例外を発生させる(例外を投げる)
**throw** を使用することで、例外を発生させることができる。
```php:throw
throw new Exception('エラーメッセージ');
```
throw するだけでは、例外処理をすることはできない。
例外処理をする為には、throw で投げられた例外を受け取り、処理するプログラムを作成する必要がある。
### 2. 例外を捕捉する
throw で投げられた例外を捕捉し、処理するには、
**try～catch～fainally**を使用する。
```php:try～catch～fainally
try{
    // 通常処理(例外が発生しうる処理)
} catch (Exception $e) {
    // 例外処理
} finally {
    // 例外でも通常でも必ず実行する処理(省略可)
}
```
## 使用例
除算を行う際、分母に0が来るとエラーになる。
以下は分母に0が渡された場合throwするという例外処理。
例外が投げられなかった場合は、除算が実行される。
```php:0による除算
<?php

function div($a, $b) {
    if ($b === 0) {
        throw new Exception('分母には0以外を入力してください');
    }
    return $a / $b;
}

try {
    echo div(10, 2) . PHP_EOL;
    echo div(10, 0) . PHP_EOL;
} catch (Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}
```
```php:出力
5
分母には0以外を入力してください
```

## 例外処理をする上で大事なこと
### 例外を握りつぶさない
例外を握りつぶすとは、例外をcatchした後、処理を書かないこと。
**→問題が生じたまま、プログラムが動作してしまう。**
「使用例」の除算エラーの例を見ると……。
```php:握りつぶしの例
function div($a, $b) {
    if ($b === 0) {
        throw new Exception('分母には0以外を入力してください');
    }
    return $a / $b;
}
try {
    echo div(10, 2) . PHP_EOL;
    echo div(10, 0) . PHP_EOL;
} catch (Exception $e) {
} //分母が0でも、何も表示されない！！＝例外を握りつぶす

```

## 例外処理まとめ
安全なコードを書く上で重要な**例外処理**。
独自のExceotionクラスを作成することも可能。随時記録していく。
【Flutter】Realtime Database のデータ操作方法

# 概要
貴重なFirebase × Flutterの記事です。
この記事では、FirebaseのRTDBからデータの取得、登録、削除の方法を紹介します。

# こんな人に読んでほしい
* Flutter初学者の方
* FlutterでFirebaseのRTDBを交えて実装を考えている人
* Firebaseの公式ドキュメントを読んでもFlutterでのサンプルコードがなくどうすればいいか困っている方

# RTDBのデータ構造
```
users
    ⌙111111
        ⌙name:'sample1'
        ⌙age:24
        ⌙gender:'M'
    ⌙222222
        ⌙name:'sample2'
        ⌙age:21
        ⌙gender:'N'
```

# データの登録
データの登録には2パターン存在します。

1つ目はsetメソッドを使用するパターン
setメソッドを使用すると、データの有無にかかわらず、指定したパス以下のデータが完全に上書きされます。

```dart
final streamRef = FirebaseDatabase.instance.ref('users');

streamRef.child('111111').set({
    'from':'Tokyo',
    'sports':'soccer',
    'food':'hamburger',
});
```


実行後
```
users
    ⌙111111
        ⌙from:'Tokyo'
        ⌙sports:'soccer'
        ⌙food:'hamburger'
    ⌙222222
        ⌙name:'sample2'
        ⌙age:21
        ⌙gender:'N'
```

2つ目はupdateメソッドを使用するパターン
updateメソッドはsetメソッドと違って、指定したパス以下に渡したデータのkeyが存在していたら、そのkeyのvalueを上書きします。
もし、渡したデータのkeyが存在しなかった場合、新しいデータとして追加されます。

```dart
final streamRef = FirebaseDatabase.instance.ref('users');

streamRef.child('222222').update({
    'name':'sample3',
    'age':25,
    'work':'engineer'
});
```

実行後
```
users
    ⌙111111
        ⌙from:'Tokyo'
        ⌙sports:'soccer'
        ⌙food:'hamburger'
    ⌙222222
        ⌙name:'sample3'
        ⌙age:25
        ⌙gender:'N'
        ⌙work:'engineer'
```

# データの削除

削除にはremoveメソッドを使用します。
使い方は簡単で、削除したいパスを指定し、removeメソッドを呼び出すだけです。

```dart
final streamRef = FirebaseDatabase.instance.ref('users');

streamRef.child('222222').remove();
```

実行後

```
users
    ⌙111111
        ⌙from:'Tokyo'
        ⌙sports:'soccer'
        ⌙food:'hamburger'
```

# データの参照

データの参照もいくつか方法がありますが、今回は最も簡単なonceメソッドを使用した方法を紹介します。

```dart
final streamRef = FirebaseDatabase.instance.ref('users');

streamRef.child('111111').once().then(
    (value){
        if(value.snapshot.exist){
            print(value.snapshot.value);
        }
    }
);
```

実行結果

```
{from:Tokyo, sports:soccer, food:hamburger}
```
【Alchemy】NFTのスマートコントラクト（ERC721）の作成方法

<br>
Alchemyのチュートリアルを見ながらやりました。

https://docs.alchemy.com/docs/how-to-develop-an-nft-smart-contract-erc721-with-alchemy


## Openzeppelin Wizard

Openzeppelin Wizardにアクセス
https://wizard.openzeppelin.com/

ERC721 のタブをクリックし、
トークンの名前を入力　する・

私の名前 Tatsuya トークン　「TTY」 にした。

[![Image from Gyazo](https://i.gyazo.com/4d3c9cc16c2934fb3bef69940b58fd36.png)](https://gyazo.com/4d3c9cc16c2934fb3bef69940b58fd36)

<br>
FEATURES の設定はよく分からないので、
Alchemyのサイトの例のとおりにした。

<IMG SRC="https://i.gyazo.com/6db634abaefb22f6c6ea2d51843fb96e.png" width=50%></IMG>

<br>

「Open Remix」をクリックすると、
[![Image from Gyazo](https://i.gyazo.com/572c8bdf879a95cce30bbbc94ba84be2.png)](https://gyazo.com/572c8bdf879a95cce30bbbc94ba84be2)

Remixが立ち上がる。
<br>
## Remix

Openzeppelin Wizardで作成されたコードが自動的に移記されている。


``` contract-98fa00c16a.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts@5.0.0/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts@5.0.0/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts@5.0.0/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts@5.0.0/access/Ownable.sol";

contract Tatsuya is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
    uint256 private _nextTokenId;

    constructor(address initialOwner)
        ERC721("Tatsuya", "TTY")
        Ownable(initialOwner)
    {}

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _update(address to, uint256 tokenId, address auth)
        internal
        override(ERC721, ERC721Enumerable)
        returns (address)
    {
        return super._update(to, tokenId, auth);
    }

    function _increaseBalance(address account, uint128 value)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._increaseBalance(account, value);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable, ERC721URIStorage)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

```

バージョンを同じにあわせ、コンパイルする。
[![Image from Gyazo](https://i.gyazo.com/0f98bedb0281737a92123ca5104e8db8.png)](https://gyazo.com/0f98bedb0281737a92123ca5104e8db8)

<br>
DEPLOY & RUN TRANSACTION に移動

1. ENVIRONMENT : Injected Web3
MetaMask が立ち上がる。
2. CONTRACT : 　さっき作ったコントラクト
3. 最初にいれるウォレットのアドレス
4.　Deploy をクリック

<IMG SRC="https://i.gyazo.com/e8f8dede5a121a174cf95fa470e400ce.png" width=50%></IMG>


コントラクトが作成される

コントラクトアドレスはこちら
<IMG SRC="https://i.gyazo.com/3a668fcecf1bc50fe5d9af45d7d1fb6a.png" width=50%></IMG>





以上
Amazon BedrockをLangChainから使う場合の簡単なサンプル


# Amazon BedrockをLangChainから使う場合の簡単なサンプル

Amazon BedrockをLangChainから使う場合の簡単なサンプルです。OpenAI API経由でGPT-3.5/4、Bedrock経由でAnthropic Claude2を呼び出します。現在のLangChain(0.0.323)限定かもしれませんが、OpenAIとBedrockを呼び分ける際に、返されるインスタンスの型が異なるという注意点があります。

## 前提条件

* langchain==0.0.323
* openai==0.27.8

## ソースコード

```python
from langchain.llms import Bedrock
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema.messages import AIMessage

gpt3_5 = ChatOpenAI(model="gpt-3.5-turbo-16k-0613", temperature=0)
gpt4 = ChatOpenAI(model="gpt-4-0613", temperature=0)
claude2 = Bedrock(
    credentials_profile_name="changeme",
    model_id="anthropic.claude-v2",
    model_kwargs={"temperature": 0, "max_tokens_to_sample": 4000},
)

prompt = ChatPromptTemplate.from_messages([("user", "{query}")])

for model_name, llm in zip(["gpt-3.5", "gpt-4", "claude2"], [gpt3_5, gpt4, claude2]):
    chain = prompt | llm
    res = chain.invoke({"query": "こんにちは"})

    # OpenAI APIの場合はAIMessageが返されますが、Bedrockの場合はstrが返されます。
    if type(res) == AIMessage:
        res_str = res.content
    else:
        res_str = res

    print(f"{model_name}: {res_str}")
```

```
gpt-3.5: こんにちは！何かお手伝いできますか？
gpt-4: こんにちは！何かお手伝いできることがありますか？
claude2:  はい、こんにちは。どうぞよろしくお願いします。
```

## 参考文献

* [LangChain - Bedrock](https://python.langchain.com/docs/integrations/llms/bedrock)
* [Amazon Bedrock](https://aws.amazon.com/jp/bedrock/)
はじめてコードレビューをする時に気をつけること

## はじめに
私がリーダーを務めるチームでは、未経験で入社した社員も3ヶ月もすればコードレビューを任せることになります。
今までは「過去のマジリク見てやり方学んでください」というスタイルでしたが、新人も増えてきてこのままではレビューの質に差が出てしまって良くないですね。
そこで今回、私がどんなことを考えてレビューしているかをまとめました。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- 上司から「そろそろコードレビューやってみようか」と言われたエンジニア

:::note warn
この記事では、一部、弊チームだけのルールもご紹介しております。
そのため、全てのルールがベストプラクティスとは限りません。
是非、ご自身の環境に合った形でカスタマイズしてご活用ください。
:::

## 結論
下記の順でコードレビューすれば手戻りが少なくなります。

:::note
1. コードの書き方を見る
2. コードの中身を見る
3. ローカルで動作確認する
4. 検証環境サーバで動作確認する
:::

それでは、それぞれの工程について、解説していきましょう！

## 1. コードの書き方を見る
初心者にありがちですが、まず動作確認始めるのはやめましょう。
まずは「書き方がなってない」部分の指摘ができないか、から始めましょう。
ルールに従って書かれたコードは読みやすく、メンテナンスしやすいですよね。

### ブランチ名が適切に命名されているか
### マージリクエスト、マジリクコメントが適切に作成されているか
### クラス名、変数名が適切に命名されているか
- [初心者プログラマーのための変数/関数/メソッドの英語命名規則](https://qiita.com/YutaManaka/items/62dda256bb7ba6c08399)を読みましょう。
### テストが記述されているか
### ケースが規約通りか
※下記は弊プロジェクトのルールです。
- PHP
    - 関数(クラス)名：パスカルケース(アッパーキャメルケース)
    - 変数名：キャメルケース
    - Model(カラム名)：スネークケース
    - Model(定数名)：アッパースネークケース
    - Model(定数の配列内のキー名)：スネークケース
    - Controller(Propsのキー)：キャメルケース
- JavaScript
    - 変数、関数名：キャメルケース
    - Propsのキー：キャメルケース
    - formのキー：スネークケース
- HTML
    - タグ名：ケバブケース
    - クラス名：ケバブケース

## 2. コードの中身を見る
書き方の指摘がなくなったら、コードの中身を見ていきましょう。
「俺だったらこう書くけどね」というコメントも大歓迎です！

### 不要な記述がないか
- コピペ元の不要な記述が残っていないか
- 検証用の記述(dd()/console.log()など)がないか
### コメントが不足していないか
- 初見で分かりにくい場合、コメントが必要な旨、指摘しましょう。
### PHP,Laravel,JavaScriptの標準関数を使えないか
### 記述が重複していないか
- DRY原則に従いましょう。
- ロジックの場合、アクションズクラスに切り出す
- 値の場合
    - 単一モデルで使用する場合はModelにて定数化
    - 複数モデルで使用する場合はapp/consts配下で定数化
### ロジックが記述されている場所は適切か
- Route, Controllerへの記述は極力避け、アクションズクラスを作成しましょう。
### メソッドの引数、戻り値の型指定は適切か
### メソッドの引数にnullが来る可能性はあるか
- 来る場合の処理が記述されているか要確認です。
### バリデーションは適切か
### サーバー負荷かかっていないか
- with()忘れてないか
- setAppends()忘れてないか

## 3. ローカルにチェックアウトして動作確認
コードが大体OKになってきたところで、動作確認しましょう！

### 仕様書の通りに動作するか
- 動作確認のチェックリストを作りましょう。(本来、レビュイーが作成すべきものですが...)
### デグレが起きていないか
- フラグON/OFF両方で動作確認しましょう。

## 4. 検証環境にデプロイして動作確認
ローカルでの確認が終わったら、サーバー上でも動作確認しましょう。
ローカルでは再現できない不具合を発見できるかもしれません。

### 実機(PC,iPad)にて表示崩れがないか
- 特にiPadのWebViewで表示する画面は実機で確認しましょう。
### 指定時間に定期実行されるか
- ローカルでは再現できないので、サーバー上で確認しましょう。
### デッドロックが起きないか
- ローカルでは再現できないので、サーバー上で確認しましょう。

## おわりに
コードレビューのやり方についてまとめました。
いきなり全部をマスターするのは難しいですが、大体の流れを理解して進めることが大事です。
GOOD LUCK!!!



## 参考記事
[コードレビューの際によく指摘するポイントについて](https://qiita.com/twainy@github/items/055c8b60b7779239d88e)
[コードレビュー指摘ポイント PHP Laravel](https://www.yuulinux.tokyo/18789/)
[備忘録]Cursorで間違ってcodeコマンドをinstallしちゃった時の話

## はじめに

https://cursor.sh/

最近話題の[cursor](https://cursor.sh/)をinstallしたんだけど、さっそくやらかしたのでここに残しときま〜す



## 発生した問題
話題のcursorを使ってみたんですけど、セットアップの際、間違ってcodeコマンドをinstallしちゃい、```code .```を打つと、 **vscodeとcursorの２つのeditor** が開くようになっちゃいました。

## 実行環境
macos
vscode(codeコマンドinstall済み)

## 検証したこと
cursorはvscodeと仕様がほぼ一緒なので、 ```command + shift + p```でコマンドパレット開いてuninstallしようと思ったのですが...

![スクリーンショット 2023-10-29 16.53.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304659/702a4f7d-111c-a46e-9992-a937b707bfc0.png)

**なんとuninstallがないんですね~~** 
cursor側だとまだunistallが登録されてないんだね〜

## 解決策
**vscode側でunistall** 
vscodeの拡張機能、コマンド等は同期されている？ので(間違ってたら教えてください😭)、vscode側でuninstallすると、cursorの方もuninstallされました！

![スクリーンショット 2023-10-29 17.00.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3304659/ad8a0220-c454-6475-4411-3f18d4631761.png)

その後、vscodeでcodeコマンドをinstallすれば、```code .```コマンドででてくるエディターはvscodeだけになります

## ちなみに
cursor側では、```cursor .```コマンドがあるので、こちらでcursorが開くようになってます！
AWS 認定ソリューションアーキテクト-アソシエイト　合格体験記

# はじめに
AWS認定ソリューションアーキテクトアソシエイト(SAA-C03)に合格したので、勉強方法と当日の試験の流れを記録として残しておこうと思います。

# 勉強前のステータス
- 実務で以下のサービスは使っており勉強時間の削減にもつながった
Lambda/S3/Dynamo/SQS/SNS

- ネットワーク関係・EC2・コンテナなどはほぼノータッチ
- 勉強を始める前、公式から辿れるサンプル問題を見て心が折れかける
　（問題文から意味不明状態でした笑）
[AWS Certified Solutions Architect - Associate](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)
- 最初に解いた問題集で、勘も含めて得点率40%くらい（合格ラインは70%)

# 勉強に使ったもの
- [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)
- QiitaやClassmethodさんの記事
- AWSの公式ドキュメント

# 勉強方法
だいたい、休日に3時間・平日に１時間というペースで5週間ほど勉強をしました。
調べると勉強時間の目安が50時間と出てくることが多いのですが、確かにそれくらいが妥当だった気がします。

具体的には土曜日を起点として、以下の流れで勉強しました。
- 土曜日：問題集を1回分解く。解き終わった後に全体の解説をさっと見直し
    - 特に、自分が知っているテーマだけど間違えた・迷った部分を重点的に
- 日曜日：問題集で解いた中から、テーマをいくつか決めて深堀する
    - あまり周辺知識がないなど、時間をかけないと難しそうなテーマをチョイス
- 平日：日曜日に触れられなかった問題を、1/5ずつ勉強する

全体を通して、
- 問題集の解説がそれなりの情報量だったので、基本は解説文で勉強
- 理解しきれなかったり深堀したい場合に、ネットの記事や公式ドキュメント
- 間違えた問題の知識は後で見返せるようにノートにまとめる
という感じで進めていました。

最初は動画やテキストで勉強する手もあったと思うのですが、
性格上途中で飽きるので、最初から最後まで問題集を起点に勉強しました。

また、試験直前だけ期間通して書き溜めていたノートを振り返るようにしていました。


# 試験当日

### 受付から会場まで
電車が遅れたりすると嫌なので、40分くらい前に最寄り駅へ。
その後少し時間をつぶして、25分くらい前に会場へ向かいましたが、すぐに受付出来ました。

受付からは以下のような流れで進んでいきました。
- 誓約書の記入
- 身分証明書の確認（私は免許証とマイナンバーカードを使用）
- 顔写真の撮影
- 荷物をロッカーに預ける（身分証1枚以外は、すべてロッカーにしまいました）
- お手洗いの確認（途中でも行けるが、試験時間は離籍中も進んでしまう）
- 余計なものを持ち込んでいないかの確認（ポケットの内部や、眼鏡の確認もされました。もちろん、眼鏡は持ち込めます）
- ホワイトボードとペンの貸与
- 試験会場への案内

この流れで15分くらい要したでしょうか。
特に予約時間を待たず試験会場へ案内されたので、予約時間ギリギリで行くより、少し早めに行って早めに受ける気持ちでいた方がよいかもしれません。
どうせ何も持ち込めないので、基本的に持ち物は身分証明書2枚あれば大丈夫です。

### 試験中
会場ではPCに案内され、すぐに試験を始められます。
問題自体は、すでに勉強してきたような内容なので戸惑うことはないはずです。

試験特有だったのは、
- 問題に対して、「後で見直す」フラグを付けられる
- すべての問題を解き切ると見直し画面に入り、好きな問題に戻れる
- 「後で見直す」問題のみ振り返ることも可能
- 複数選択式の問題でチェックが足りないなど、不完全な回答は振り返り画面で注意が出る（親切設計）
くらいですかね。

ちなみに、渡されたホワイトボードについては使いどころがよく分かりませんでした。
なんとなく自信のある問題・自信のない問題・分からない問題をメモしてみたのですが、
試験自体に後で見直す機能がある上、自信のある問題が増えないと不安になるので止めておけばよかったと思いました笑

見直しも含めて解き切ったと思ったら、制限時間を待たずに試験を終了することができました。
最後にアンケートに答えて終了です。
以前は最後に合否が出ていたという話を聞いたのですが、今は試験会場で合否が分からないようです。
合否が出るものと思っていたので、少し戸惑いました。

### 結果
私の場合、当日の夕方にメールで合格の通知が届きました。
メールに点数は記載されていないので、点数を見たい場合はAWS認定アカウントの試験履歴から確認可能です。

私の結果は800点くらいで、ボーダーの720に対して少しだけ余裕がありました。

### 終わりに
私自身、他の方の試験当日の体験記などを参考にさせてもらったので、
自分の記録も残しておこうと執筆させてもらいました。

何か一部分でも、これから試験を受ける方の参考になれば幸いです。
【Postgre SQL】CASE式のススメ #SELECT基本




※これはミック(2018),『達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ」』[第2版],翔泳社のメモです。
私が特に役立つと思った事柄の書き起こしですので、もっと知りたい方は文献を参考にしてください(最後に記述)

## CASE文の基本書式
```sql:CASE文基本書式
-- 単純CASE式
CASE sex 
    WHEN '1' THEN '男'
    WHEN '2' THEN '女'
ELSE 'その他' END

-- 検索CASE式
CASE
    WHEN sex = '1' THEN '男'
    WHEN sex = '2' THEN '女'
ELSE 'その他' END
```
どちらを使用するかはケースバイケースである。


CASE文は真になるWHEN句が存在した時点で即終了となり
残りのWHEN句は無視される。
```sql:WHEN句
-- 以下の場合、2行目のWHEN句は無視される
CASE WHEN col_1 IN ('a','b') THEN '1番'
     WHEN col_2 IN ('a') THEN '2番'
ELSE 'その他' END
```

## CASE式はSELECT文でつけた別名をGROUP BYで指定できる

以下のような表を県名と男女別にまとめた結果を取得するとする。

■集計元
|pref_name(県名)   |poplation(人口)  |
|:-:|:-:|
|徳島|	100
|香川|	200
|愛媛|	150
|高知|	200
|福岡|	300
|佐賀|	100
|長崎|	200
|東京|	400
|群馬|	50


■集計結果
|地域  |人口  |
|:-:|:-:|
|四国  |650  |
|九州 |600  |
|その他  |450  |

以下のSQLで取得できる。
```sql:CASE式のGROUP BY
-- 地域コードcolumn増やせばいいが、今回は無視
SELECT CASE pref_name
    WHEN '徳島' THEN '四国'
    WHEN '香川' THEN '四国'
    WHEN '愛媛' THEN '四国'
    WHEN '高知' THEN '四国'
    WHEN '福岡' THEN '九州'
    WHEN '佐賀' THEN '九州'
    WHEN '長崎' THEN '九州'
ELSE 'その他' END AS district,
SUM (poplation) AS poplation
FROM '集計元'
GROUP BY district;
```

## UNIONよりCASE文

以下のような表を県名と男女別にまとめた結果を取得するとする。

■集計元
|pref_name(県名)  |sex(性別)  |poplation(人口)  |
|:-:|:-:|:-:|
|徳島  |1  |60  |
|徳島  |2  |40  |
|香川  |1  |100  |
|香川  |2  |100  |
|愛媛  |1  |100  |
|愛媛  |2  |50  |
|高知  |1  |100  |
|高知  |2  |100  |
|福岡  |1  |100  |
|福岡  |2  |200  |
|佐賀  |1  |20  |
|佐賀  |2  |80  |
|長崎  |1  |125  |
|長崎  |2  |125  |
|東京  |1  |250  |
|東京  |2  |150  |


■集計結果
|県名  |男  |女  |
|:-:|:-:|:-:|
|徳島|60|40
|香川|100|100
|愛媛|100|50
|高知|100|100
|福岡|100|200
|佐賀|20|80
|長崎|125|125
|東京|250|150

以下のクエリでも取得できるが、CASE文を使うとさらに効率よく取得可能
```sql:UNION
(
    SELECT pref_name,sum(poplation)
    FROM syuukei_table 
    WHERE sex = 1
    GROUP BY pref_name
)UNION (
    SELECT pref_name,sum(poplation) 
    FROM syuukei_table 
    WHERE sex = 2
    GROUP BY pref_name
)
```
```sql:CASE文を使用した例
SELECT pref_name,
	-- 男性
	SUM( CASE WHEN sex = 1 THEN poplation ELSE 0 END) AS cnt_m,
	-- 女性
	SUM( CASE WHEN sex = 2 THEN poplation ELSE 0 END) AS cnt_f
FROM syuukei_table
GROUP BY pref_name;
```


## 参考文献
ミック(2018),『達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ」』[第2版],翔泳社

Amazon
https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6SQL%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E7%AC%AC2%E7%89%88-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-CodeZine-BOOKS/dp/4798157821
ブラウザ拡張で GitHub 2FA を行う

github にアクセスするのに 2FA が必須となった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/21be298a-3f18-4795-b059-ba7563e9c25a.png)

2FA では、モバイルアプリや SMS などを使うことができるが、ブラウザ拡張で 2FA もできるらしい。今回はそちらを試してみた。

# 環境 

- Ubuntu 22.04 LTS
- Google Chrome バージョン: 118.0.5993.88（Official Build） （64 ビット）

# 操作

`Enable 2FA now` を押すと以下の画面になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5026a6ad-1e6b-3077-11c2-2256ac123a64.png)

Chrome に Authenticator をインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b8b90ccf-80bc-7ac6-baac-e85c7303d362.png)

インストール後、拡張機能から Authenticator を選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/95fd1707-cc25-22d2-d909-acb631169f09.png)
右上のスキャンマーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fb894fb1-761b-ed9d-28d1-3936ad5bee3d.png)
を押すと範囲選択画面になるので


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b752267a-abca-2f30-e002-faaff46689d4.png)
GitHub の先程のQRコードを読ませると登録される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4ed0a891-5658-c5f4-4adc-a24e06b0507c.png)
Authenticatorをサイド表示すると認証コードが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c15394f9-c28a-04e5-5038-2b02d0065b2d.png)
認証コードを先程の GitHub ページに登録するとリカバリーコードが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2cd8d7a3-8198-1290-f325-643f9dff23ca.png)
リカバリーコードをダウンロードして進み、"Return to your work" を押すとGitHub が使えるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c8877a5d-91e4-ed5a-5473-c8a7801452d0.png)




Authenticator をピンどめしておくと便利
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/aaa801ef-b122-617d-3c03-a871a566c118.png)
【Linux】shutdownコマンド

LPIC101試験アウトプット用にて作成したものになります。
※多少の解釈ミスあるかと存じますがご容赦ください。

## shutdownコマンドの使用用途
時間やメッセージを指定して、システムの停止や再起動を行うのに利用。
※root権限がないと使用不可。

### オプション
|    オプション    |   説明      |  
|:----------:|:---------------:|
| -h  | `システムの停止`        |
| -r | `システムの再起動`          |
| -k     | `シャットダウンせずに、ログイン中の全ユーザーにメッセージを送信` |
| -c     | `実行中のシャットダウンをキャンセル`   | 

【書式】
shutdown [オプション] 時間 [メッセージ]

### 時間
①ex) `12:00`
②`+30`
③`now`
【Reactアプリ100本ノック】03 TODO

![bandicam 2023-10-25 06-24-03-451.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/78d83511-8e06-b0ba-7679-87deb4d9c910.jpeg)

# はじめに

<h3>こんにちは！！@Sicut_studyです！</h3>

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

こちらの記事が嬉しいことに多くの方に見ていただきました。
そこで**React**が多くの初心者の方に注目されているんだなということを実感させられました。

私の記事では何度も言っている通り

<font color="red"><h4>最速で学ぶならとにかく何か作る</h4></font>

というのが大事になってきます。そこで **「Reactアプリ100本ノック」** というのに挑戦していこうかと思います。徐々に難易度を挙げていってどこまでお題を作りきれるかの腕試しでやっていただければと思います。

今回は**useState**を前回よりも応用的に変更していきます

# 前回のお題

https://qiita.com/Sicut_study/items/82059f9cbb5b2996e5b3

# Reactアプリ100本ノックルール

- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する

# 03. TODO

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/50532849-0b53-03c2-b1bc-0eccf1182886.png)

## 問題

TODOリストアプリを作成する

## 目的

TODOリストは複数のタスクを管理する必要があるため、状態管理の初歩を学ぶのに適しています。Reactを使用する場合、useStateやuseReducerなどのHooksを使って状態管理の方法を学ぶことができます。

## 達成条件

1. 入力フィールド: ユーザーがタスクを入力するためのテキストフィールドが存在する。タスク名が1文字以上でない場合はバリデーションする
2. 追加ボタン: 入力されたタスクをTODOリストに追加するためのボタン。
3. タスクリスト表示: 追加されたタスクがリストとして表示される。
4. 削除ボタン: 各タスクの隣には削除ボタンがあり、それをクリックすることで該当のタスクをリストから削除する

## 実際に解いてみた

### 利用技術

- React
- TypeScript
- Vite
- Emotion

解答時間 : 2時間

モバイルを意識してデザインをしてみました
また、モーダルを1から実装してみたりちょっと挑戦をしてみたところがあります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/86ee7723-4137-f6a5-eedd-79fea6919861.png)

# 次回

https://qiita.com/Sicut_study/items/1e4d8ec06f1af42a47e5?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share

# おわりに

React100本ノックの記事を地道に上げていこうと思いますので、一緒に挑戦したい方は @Sicut_study をフォローいただけるととてもうれしく思います。
ここまで読んでいただけた方はぜひ**いいね**と**ストック**よろしくお願いします。

<h5>少し宣伝します🔥🔥🔥🔥🔥</h5>

これからエンジニアになろうとしている人を本気でコーチングして3か月の期間で立派なエンジニアにするようなチャレンジをしてみたいなと考えております。

もし、本気でエンジニアを目指してコーチングを受けてみたいという方がいれば、[Twitter](https://twitter.com/Sicut_study)に「プログラミング教えてほしいです」みたいなリプライ送っていただけたらなと思います！！

以上です。
今週もプログラミング頑張りましょう！

![bandicam 2023-10-04 20-58-54-525.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f41a0065-b23e-1895-da22-66bf0e48c5fb.jpeg)
Virtalbox上のUbuntuDesktopでキーボードが日本語配列にならない！

# なにがあった?
ibus-mozcをインストールしているのに、
/etc/default/keyboardや/usr/share/ibus/component/mozc.xmlをいじっても
dpkg-reconfigure keyboard-configrationしても
配列が日本語にならなかった

# どうした？
設定パネルのKeyboard>Input Sources
ここにJapaneseを追加する。
Japanese(Mozc)とは別物。

これでMozcでもそうでなくても、日本語いけるようになる。
IAMユーザで請求ダッシュボードを見れるようにする

## 解決したいこと
### IAMユーザでは請求ダッシュボードが確認できない
![スクリーンショット 2023-10-29 16.59.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/baf27967-9243-6cc6-4093-2e5ceb9e39d9.png)

## 解決手順
1. rootユーザでログイン
1. 右上のアカウント名から「アカウント」を選択
![スクリーンショット 2023-10-29 17.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/767f52e6-ef15-1cb3-4a8c-3ae819e68b2b.png)
1. 下の方にいき「IAMユーザ及びロールによる請求情報へのアクセス」の編集をクリック
![スクリーンショット 2023-10-29 17.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/b018f8a6-a3bb-dad4-d172-9576922236de.png)
1. 「IAMアクセスをアクティブ化」にチェックを入れて「更新」
![スクリーンショット 2023-10-29 17.07.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/164beaf2-8237-06a6-cd46-8b43d7b88508.png)
1. 再度、IAMユーザでログインすると、請求ダッシュボードが見れるようになっている
![スクリーンショット 2023-10-29 17.10.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/b60c4178-04de-33d4-9f9e-5dd7754bf40a.png)
Amazon linux 2023でインスタンスメタデータを利用

# 前置き
現在、EC2のOSを「**Amazon linux 2**」 から「**Amazon linux 2023**」へ移行する行検証をしております。
その中で判明した事象の一つである、**インスタンスメタデータ取得方法**の変更について記録しておきます。

# 実施したいこと
EC2上で動くバッチ上で、サーバーのインスタンスIDを取得したい

# Amazon linux 2023でインスタンスメタデータからインスタンスIDを取得する方法(*お急ぎの方はこちらだけ*)

```amazonlinux2023_test.sh
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
INSTANCE_ID=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id`
echo $INSTANCE_ID
```

# 検証の経緯
### そもそもインスタンスメタデータとは？
インスタンスメタデータは「**インスタンスに関するデータ**」のことで、実行中のインスタンス自身から取得できるようになっております。
取得できるデータはamiのidやセキュリティグループなど、多岐にわたります。

↓AWS公式ドキュメント
・インスタンスメタデータとは

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

・取得されるインスタンスメタデータ一覧

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instancedata-data-categories.html


### Amazon linux 2の際の取得方法
以下の1行でインスタンスIDが取得できていました。

```amazonlinux2_test.sh
INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
```

### Amazon linux 2023の際の取得方法(失敗)
amazon linux2と同じバッチファイルを実行したところ、なぜかエラーが発生。
確認したところ、インスタンスIDが取得できていませんでした。
コマンドで実施しても何も出ません。
```
[root@ip-xxx ~]# INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
[root@ip-xxx ~]# echo $INSTANCE_ID

[root@ip-xxx ~]# curl -s http://169.254.169.254/latest/meta-data/instance-id
[root@ip-xxx ~]#
```


### Amazon linux 2023の変更点
インスタンスメタデータサービスバージョン 2 (IMDSv2)からでしかメタデータが取得できなくなっておりました。
このため、上記のバッチで使っているコマンド(旧バージョン)では取得できなかったようです。

・2023の公式FAQ

https://aws.amazon.com/jp/linux/amazon-linux-2023/faqs/

・インスタンスメタデータサービスバージョン 2 (IMDSv2)について

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html


ということで、**インスタンスメタデータサービスバージョン 2 (IMDSv2)で再度実施**してみます。
# Amazon linux 2023でインスタンスメタデータからインスタンスIDを取得する方法

```
[root@ip-xxx ~]# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    56  100    56    0     0  11247      0 --:--:-- --:--:-- --:--:-- 14000
[root@ip-xxx ~]# INSTANCE_ID=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id`
[root@ip-xxx ~]# echo $INSTANCE_ID
i-xxxxxxxxxx
```
無事インスタンスIDが取得できました。
<next build>module not found @/components/input

localでの build は通るのに github actions での build が通らないエラーに遭遇したので忘備録

エラーメッセージ
```bash
Creating an optimized production build...
▲  Failed to compile.
▲  ./app/maps/page.tsx:4:0
▲  Module not found: Can't resolve '@/components/input'
```

aliasの登録はしている。
```tsconfig.json
...
"baseUrl": ".",
"pahts": {
  "@/components/*": ["./components/*"],
  ...
}
```

`./components/input/index.tsx`も存在している。

# 原因
Github 上で `./components/Input/index.tsx` と input がパスカルケースで登録されていた。

そういえば間違って最初に大文字でディレクトリを作った気がする。。
Github上で大文字小文字の認識がされておらず、CI 上では未追跡の`@/components/input`を参照しようとしていたのが問題になっている。

これで認識される
`git config core.ignorecase false`


# 参考
https://github.com/vercel/next.js/discussions/27666
VIrtualBoxでゲストにホストとの共有フォルダがマウントされない

VirutalBox上でいろいろ試しても共有フォルダ設定が反映されなかったのを修正した記録

# 解決法
ゲスト(仮想マシン側)でこれを実行
~~~
sudo apt install virtualbox-guest-utils
~~~
【Python】ChatGPTにプログラミングしてもらった

題名の通りです。使用したGPTはVer.3の無料版です。
かかった時間は1時間半くらいです。
お手柔らかにお願いいたします。

# 何を作ってもらったか
指定した宛先にマジックパケットを送信するアプリケーションを作ってもらいました。

# マジックパケットってなに
簡単に説明すると、
電源が落ちているPC1の電源を、電源ついているPC2から「特別なパケット」を送信することで遠隔で電源を入れることができるみたいな。
「特別なパケット」です。無線接続では送信することはできないはずです…（詳しくは自分で調べてみてください～）

# 何に使えるの
私のメインPCは家の2階にあるのですが、検証用のPCが1階にありまして
会社のようにつけっぱなしにしているわけではないので、使うたびに電源を付けなくてはいけません。
2階にいるのに1階のPCの電源を付けたいときに使用します。

# ソース
Qiitaも最近はじめたばっかりですが、GitHubもはじめてみました。
こちらに載せてみたので、URLを置いておきます。（使い方あってるか不明）

https://github.com/beeeeeeko/Create-by-CHATGPT/commit/7e45038440e8a0c537b3e5f0db31e382cbd29ded


# ChatGPTの使用感
Pythonの基本の基本は理解しているつもりですが、ゼロから物を作るのはハードル高かったので、ChatGPTを使ってみました。
会話するだけでペラペラ喋ってコードを作成してくれて、私が偉そうに「ああしろ、こうしろ」と返信すると要求通りに機能を実装、修正してくれました。
文句も言わないし、嫌な顔1つしないので良い子でした。カワイイ。

# 困ったこと
まだ完全ではないらしく修正したソースでもエラーが出ることがありました。
そういう時だけ自分でソースを読んで、変なところはないか少しだけ探したりしました。
ですが、プロンプトも考えずに、会話ベースで作成できたので本当に誰でもできると思いました。


# 最後に
ChatGPTを使えば何でも作れそうな気がしてきたので、これからも定期的に活動しようかなと思います。
上手く作れたらまとめて記事にします。
便利なものを作って会社のため、誰かのためになったらいいなと思います。
そしてお給料を上げてもらいたいです。。。。。。。。いつか。。。。。。


# おまけ
これからネットに生成AIが絡んだうすーい内容の記事が蔓延するのではないかと、心配もありますが
投稿側は投稿するだけで偉いような気がするので、読者側に見分ける力を養ってもらうのがいいですかね…
以上です。間違ってることありましたらご指摘よろしくお願いいたします。