OmniAICreator/Qiita-1.07M huggingface dataset:
imdb clone Part4　 5 Add a darkMode 2/5　next-themesを追加

# 概要

目次

https://qiita.com/RYA234/private/045f3d2c03684572d3f9


今回はダークモード実装に必要なプラグインnext-themeを導入します。

以下導入後の様子です。ダークモードにはなっていますが切り替えはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/268f3b48-ce95-9b9f-f46e-c63be38e174d.png)


# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
next-themesとgithubのドキュメント部分を参考にします。

1.Providerコンポーネントを作成する
2.layoutにProviderコンポーネントを使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/07d48ae0-81d4-e6af-cb82-96975386af0d.png)


3.Provider コンポーネントに設定を加えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0f9d5205-ad4e-652b-2dd0-bffbca0c8c76.png)



# コード部分
### package.json
```diff_json:package.json
{
  "name": "imcbclone",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@next/font": "13.1.5",
    "autoprefixer": "10.4.14",
    "eslint": "8.39.0",
    "eslint-config-next": "13.3.1",
    "next": "13.3.1",
+    "next-themes": "^0.2.1",
    "postcss": "8.4.23",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-icons": "^4.8.0",
    "tailwindcss": "3.3.2"
  }
}
```

## Provider
```diff_jsx:Provider.jsx
"use client"
import { ThemeProvider } from 'next-themes'
import React from 'react'

export default function Providers({children}) {
  return (
    <ThemeProvider enableSystem={true} attribute="class">
        {children}
    </ThemeProvider>
  )
}

```

## layout
```diff_jsx:layout.jsx
import './globals.css'
import Header from '@/components/Header'
+import Providers from './Providers'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
+        <Providers>
          {/* Header */}
          <Header />

          {/* Navbar */}

          {/* SearchBox */}

          {children}
+        </Providers>
      </body>
    </html>
  );
}
```




# 参考
next theme

https://github.com/pacocoursey/next-themes

基本的な設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/e583639c-a0d5-35b3-0c1d-d3713f3161aa.png)

ThemeProviderの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/204585e0-017a-b995-a1b5-59a3856aab8c.png)

TailWind時の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/72a59a26-8adf-ac0d-4472-4a86b9cc279f.png)



## その他
Udemy

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36592888#overview

githubコミット分


https://github.com/RYA234/imcbclone/commit/41f5b77109c5624ad27396b94aad2d7c18805788
imdb clone Part3　5 Add a darkMode 1/5　DarkModeSwitchコンポーネントを追加

# 概要
目次

https://qiita.com/RYA234/private/045f3d2c03684572d3f9

今回からダークモードを実装していきます。
今回は文字だけの空のコンポーネントを新規作成し、コンポーネントがロゴに左隣に配置するところを実装します。
下図はDarkModeSwitchコンポーネントがロゴ左側に付いている様子です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/712bc869-13df-661f-2f80-744eba8817c4.png)



# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
DarkModeSwitchをIMDbアイコンの左隣に配置できるようにcssを加えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/afb78277-3ea1-7aa4-bf02-023110879230.png)


# コード部分
## DarkModeSwitch
```diff_jsx:DarkModeSwitch.jsx
import React from 'react'

export default function DarkModeSwitch() {
  return (
    <div>DarkModeSwitch</div>
  )
}
```


## Header.jsx
```diff_jsx:Header.jsx
import MenuItem from "./MenuItem";
import {AiFillHome} from "react-icons/ai"
import {BsFillInfoCircleFill} from "react-icons/bs"
import Link from "next/link";
+import DarkModeSwitch from "./DarkModeSwitch";

export default function Header(){
    return(
        <div className="flex justify-between mx-2 max-w-6xl sm:mx-auto items-center py-6"> 
            <div className="flex">
                <MenuItem title="HOME" address="/" Icon={AiFillHome} />
                <MenuItem title="ABOUT" address="/about" Icon={BsFillInfoCircleFill} />
            </div>
-            <div className="">
+            <div className="flex item-center space-x-5">
+                <DarkModeSwitch/>
                <Link href="/">
                <h2 className="text-2xl">
                    <span className="font-bold bg-amber-500 py-1 px-2 rounded-lg mr-1">IMDb</span>
             
                <span className="text-xl hidden sm :inline">Clone</span>
                </h2>
                </Link>                
          </div>
        </div>
    );
}
```


# 参考

## css

### item-center

https://tailwindcss.com/docs/align-items

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/11992974-c1fb-2f67-9247-330fc5f62cc9.png)


align-items

https://developer.mozilla.org/ja/docs/Web/CSS/align-items

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/77d68805-7a40-0bb9-2679-77f1a8be10b0.png)



### space-x-5

https://tailwindcss.com/docs/space

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/8cd0c2db-f9f2-4c14-14be-1d0c6d6634c1.png)




## その他


Udemy 5

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119274#overview

githubコミット分

https://github.com/RYA234/imcbclone/commit/9a6914b9df415fc66e2fe3c56cf7b77163713cec
imdb clone まとめ　Part1-10

# 説明
IMDbのクローンサイトを作ります。
https://www.imdb.com/

# 参考にしたUdemyの講座

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119286#content

# 一覧

## Part1　ヘッダー作成　1/2 ReactIconを使ってアイコンを表示

![imcb1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d8c4a667-3a88-6f52-2ed3-d91e91cdb939.gif)

https://qiita.com/RYA234/items/19859007425e487a2264


## Part2　4 ヘッダー作成 2/2 タイトルイメージを作成　レイアウトを整理

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/13606fe1-ff8a-eba1-4244-a3423538289f.png)

https://qiita.com/RYA234/items/3577ced3589751288d29

##  Part3　5 Add a darkMode 1/5　DarkModeSwitchコンポーネントを追加


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/712bc869-13df-661f-2f80-744eba8817c4.png)

https://qiita.com/RYA234/items/d9b7977d7bf558c037fa

##  Part4　 5 Add a darkMode 2/5　next-themesを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/268f3b48-ce95-9b9f-f46e-c63be38e174d.png)

https://qiita.com/RYA234/items/f970cbe22114b0983f23


## Part5　ヘッダー作成　テンプレート 5 Add a darkMode 3/5　React-icon実装　ダークモードに切り替えできるよう実装

![bbbbbb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/fced7677-7ce8-b518-e0b7-a22e378d1f81.gif)

https://qiita.com/RYA234/items/3f56f8a110ad917b2434


## Part6　5 Add a darkMode 4/5　hydration Errorを修正

改善前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0eb65593-0e6a-450b-a39e-ae0c6fd76d15.png)




改善後　hydarion Errorが無くなっていることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b4a412ff-85c7-4430-7ae5-30c5a4240c66.png)

https://qiita.com/RYA234/items/e7ebdfb324c95c17d92f

## Part7　5 Add a darkMode 5/5　cssの設定ダークモードの色　アイコンのカーソル

![ccccccccccc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/60507840-9a8b-9ba2-31ff-6bcf0ad782d0.gif)

https://qiita.com/RYA234/items/991f402ac66abcae6fb9

## Part8　7 navbar実装 1/2 基本的な実装

![uuuuuuuuuuuuuu.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/38b055a6-d172-8413-f930-85916dde01a1.gif)

https://qiita.com/RYA234/items/04110e8502c5353c5b19

##  Part9　7 navbar実装 2/2 hoverの処理追加　開いているNavの下線部をハイライト

![fffffff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3db131f5-0e6b-4f18-240c-30a07a246811.gif)

https://qiita.com/RYA234/items/db4a950ba5e0a847afaf


## Part10　8 TMDBのAPIからデータ取得 レスポンスをコンソール結果で確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/91a44941-a912-d6e6-f654-663e73fba3dc.png)

https://qiita.com/RYA234/items/e688f18d36e13714d58b
【VSCode】DevContainersで環境構築する際の構成要素まとめ

# 初めに
毎回必要な構成要素を忘れてしまうので備忘録的にメモです。

以下が必須です。
Dockerのインストール 4.12.0~推奨(あまり古いとReopen in Containerこけます。公式読んでないので間違ってるかも)
VSCodeのインストール
VSCodeの拡張機能 Dev Containers
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers


# ディレクトリ構成
```
parent/
      ├ docker/ (コンテナ)
      │       ├ infra/(コンテナ)
      │       │    ├ mysqlとか/
      │       │    │          └ Dockerfileとか
      │       |    └ phpとか/
      │       |             └ Dockerfileとか
      │ 　 　 ├ .devcontainer/
      │       |              ├ devcontainer.json
      │       |              └ docker-compose.yml
      │　  　 └　.env
      │
      └ source/
              ├ .vscode/
              |        ├ launch.json
              |        └ settings.json
              └ src/ (実際に動かすもの。)
```

# 各ファイルの役割
### devcontainer.json
Reopen in containerで接続するコンテナと拡張機能などが指定できる。
記入例
```
{
    "name": "VSCodeの上に表示される名前。好きなもので。",
    "dockerComposeFile": "docker-compose.yml",
    "service": "コンテナ名",
    "workspaceFolder": "コンテナのマウントしているディレクトリを記述する。",
    # ../sample:/dataeだったら"/data"と記述する。
    "customizations": {
        "vscode": {
            "extensions": [
              拡張機能ID
            ]
        }
    }
}
```

### docker-compose.yml
コンテナの構成を指定する。
記入例(php用のコンテナ例)
```
version: "3.9"
services:
  app:
    build: ./infra/php/
    ports:
      - 5173:5173
    volumes:
      - ../../sample:/data 
      - #1階層上の別ディレクトリを参照してマウントしている。が.devcontainerディレクトリ目線なので二個上参照しているような書き方になる。
      - ./infra/php/php.ini:/etc/php/php.ini
      - node-modules:/data/node_modules
      - ../log:/var/log
    working_dir: /data
    tty: true
```
### launch.json
デバッガやchromeなど起動したいものを記述する。
記入例
```
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:8080/phpinfo.php",
            "webRoot": "${workspaceFolder}"
        },
    ]
}
```


### settings.json
VSCodeの設定を統一できる。
記入例
```
  "[scss]": {
    "editor.wordSeparators": "`~!#%^&*()=+[{]}\\|;:'\",.<>/?"
  },
```
マイナンバーカードでSSH認証 on Windows

MAC でマイナンバーカードSSH認証をする方法が紹介されています。

https://qiita.com/f96q/items/0b1c302a47b7f277c191

今回、Windows 10/11 の GUI SSHクライアント( WinSCP や Teraterm ) でマイナンバーカードSSH認証を試してみました。SSHクライアントは直接スマートカード認証をサポートしていませんので、pagaent 経由で認証します。このため、SSHクライアントは pagaent を使った認証をサポートしていなければなりません。

## 準備
ＩＣカードリーダでマイナンバーカードが読み取れる状態になっているものとします。


## SSH設定

### 1. Putty-CAC 入手
pagaent.exe のみ必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/88f6c38a-82bc-46d7-33e0-bb05e1ce9d48.png)

### 2. OpenSC 入手
puTTY-CAC が64ビットであれば　OpenSCは 64ビット版を入手
Pkcs#11 モジュールのみ必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/9b5cf724-a01d-1496-2d3f-2c2416d82437.png)


### 3. クライアント認証用公開鍵を ssh-key 形式で抽出
マイナンバーカードには２つのスロットがあります。仮想スロット０はクライアント認証用、仮想スロット１は署名用の証明書、公開鍵、秘密鍵が含まれています。

:::note info
##### 仮想スロット 0 (クライアント認証用)

 証明書( 公開部分　）
Digital Signature Certificate CA  id=4
User Authentication Certificate CA id=3
User Authentication Certificate 　　id=1

公開鍵（公開部分）
Digital Signature Certificate CA  　　id = 4
User Authentication Certificate CA  　　id = 3
User Authentication Public Key 　　　　 id = 1

秘密鍵（秘密部分）
User Authentication Key id = 1
:::

:::note info
##### 仮想スロット１ (署名用）
証明書（秘密部分）
Digital Signature Certificate id=2

公開鍵（公開部分）
Digital Signature Public Key id = 2

秘密鍵（秘密部分）
Digital Signature Key id = 2
:::

秘密部分にアクセスするにはスロット用の PIN が必要です。

SSH認証に必要なのは、仮想スロット０のクライアン認証用公開鍵( User Authentication Public Key id=1 ) 。PINは不要。これを ssh-key形式で取り出して、SSHサーバのログインするユーザのホームフォルダ内の .ssh フォルダ authorized_keys ファイルに貼り付けます。

一発で取り出す方法が見つからなかったため、専用のプログラムを用意しました。実行すると　ssh-key 形式の公開鍵を表示。表示されたものをコピーして、sshサーバのauthorized_key に貼り付けます。

https://github.com/kaorumorikawa/myna-ssh/releases/download/v1.0.0/myna-ssh.zip

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/2ded585a-55e0-0982-3a68-8b5ffde59f34.png)
（ssh-rsa から４行コピー）


### 4. Putty-CAC pagaent 設定

puTTY-CAC のpageant.exe を起動
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/4a1d6189-991b-6d52-8471-3aa4b6a53c0a.png)

スクリーン右下のシステムトレイに表示されるアイコンを右クリック。メニューで"View Keys & Certs" を選択。開いたダイアログで "Add PCKS Cert" ボタンをクリック

pkcs#11 モジュールのパスを選択。ファイルダイアログで opensc-pkcs11.dll （puTTY-CAC が６４ビットであれば、６４ビットDLL、３２ビットであれば３２ビットDLL）を選択。するとマイナンバーカードのクライアント認証証明書が表示されるはず。その証明書を選択するとリストボックスに表示されます。

最後にダイアログ下の Fingerprint Type を必ず "SHA256 including" に設定（＊＊重要＊＊）

"Close"ボタンでウィンドウを閉じます（　pageant はシステムトレイに残っています　）

### 5. pageant 対応の SSHクライアント（WinSCP/TeraTerm 等）でSSH認証

SSHサーバのホームフォルダ内の .ssh - authorized_keyに公開鍵を設定したユーザでログイン。
認証は必ず pagaentを使うように設定します。

![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/b35cf563-a2cc-51bd-d2f1-5fe292ad7e88.png)

![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353822/7b5ff199-bb71-b05e-a668-40017feac2c9.png)

認証処理中に PuTTY Authentication ダイアログが表示されパスワードを求められたらクライアント認証用 PIN を入力　（３度間違えるとロックしてしまいます）

マイナンバーカードでパスワードレスでSSHサーバにログイン完了

### やってみての感想

マイナンバーカードでSSH認証はできましたが、あえてマイナンバーカードを使うようなケースは個人的にはあまり思い浮かびません。マイナンバーカードを使い慣れるためにやってみるというのもありだと思います。今回何度もやっているうちにマイナンバーカードに使い慣れたような気がします。
Fargate基礎

# 個人的リマインド用
参考
[]()

# Fargateをざっくり理解
### 何をするものなのか
AWSにて**サーバーレス**でコンテナを動かすもの。コンテナを動かすところに特化している。

### ECS
Fargateを知る前に、まずはECSについて理解する必要がある。FargateはECSの中の仕組みの1つ。他の仕組みにEC2onECSがあり、そちらは**サーバーレスではない**。
最近は**Fargateが主流**で、なぜならアプリ制作者の視点としてはコンテナがとにかく動けばいいから。(例えばMacでdockerを使い、コンテナ内でつくったものをAWSに乗せるとなった時、そのコンテナさえ動けばいい)
EC2と比べた際のFargateのデメリットは、コンテナ内で問題があった時、その中に入れないこと。

もう1つFargateのいいところとしては、**スケーリング**してくれるところ。スケーリングとは、負荷が増えた時に勝手にコンテナを増やしてくれて、負荷を分散できる。

### よく使う単語
・クラスター
・サービス
・タスク
・タスク定義

**クラスター**
最も大きい箱。単なる枠組み。この中で色々なコンテナを動かしていく。複数作れる。

**サービス**
クラスターの中にいくつか用意できる。**タスクを管理していて**、必要なコンテナを集めたものが起動している状態。サービス同士で依存関係はなくていい。(例えばクラスター1のサービス1はZOZOTOWNに関連するもので、サービス2にはWEARに関連するものをいれる。またクラスター2には楽天に関するものみたいな感じで、管理したい単位でサービスを用意すればいい)

**タスク**
サービスの中にいくつか用意できる。1つ以上の任意のコンテナの集まり。スケーリングする時は、このタスクを増やす。同じサービス内にあるタスクは、同じタスク定義からできている。

**タスク定義**
コンテナを起動するタスクを定義するもの。タスクは動いているもの自体のことを指すが、タスク定義はどういうものが動いているかを定義する。dockerでいうとほぼdocker-compose.yml。
やりたいこととしては、何のコンテナなのか、どんなスペックなのか、ログは、マウントはということを定義する。
Lambdaで作成したExcelファイルをダウンロードする

# 環境
React：16.8.5

# やり方
lambdaで作成したExcelファイルをbase64に変換しレスポンスとして返します。
それをReactでBlobに変換してダウンロードしました

```js
const data = 'base64のデータ';
const binary = Buffer.from(data, 'base64')
const decoded = new Blob([Uint8Array.from(binary)], {
	type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
const url = window.URL.createObjectURL(decoded);
const a = document.createElement("a");
a.href = url;
a.download = "sample.xlsx";
a.click();
window.URL.revokeObjectURL(url);
```

base64から直接Blobに変換するのではなく、まずはUint8Arrayに変換します。
→そしてUint8ArrayをBlobに変換し、aタグを使ってダウンロードします。

参考にしていただければ幸いです。
SSMSから取得したデータをVBAマクロを使って楽にExcelに貼り付けたい



## はじめに

昨今テストの自動化が進んでおりますがうちではまだまだテストの際にSELECTしては手でペタペタとExcelに貼り付ける習慣が残っております。~~テストの自動化触れてみたい~~
意外とそういったところがまだいっぱいあったりして需要がないかな、と思い自分が進めてきたVBAでの楽をする方法のいわゆる備忘録のようなものです。
初めての投稿になるので見づらいところ等ございますでしょうがその際はコメントいただけると幸いです。


## コード
早速ですが、今回紹介するのはSSMSから取得したデータを表形式を文字列＋罫線付きで貼り付けるVBAマクロになります。


```VB:DBPaste

Sub DBPaste()

Application.ScreenUpdating = False

'ワークシートに貼り付け
    ActiveSheet.Paste

'行数の取得
    Dim DbRowscnt As Long
    DbRowscnt = Selection.Rows.Count

'選択範囲の行数を取得
    If Selection.Rows.Count = 1 Then
        '1行の場合、下の行も選択
        Range(Selection.Rows(1), Selection.Rows(1).Offset(1, 0)).Select
    End If

'選択範囲に枠線を引く
    Selection.Borders.LineStyle = True

'数値のセルを文字列として表示
    Selection.NumberFormatLocal = "@"

'再度貼り付けを行う
    Range(Selection(1).Address).Select
    ActiveSheet.Paste

'目次列に色を付ける
    Dim firstColumn As Range
    Set firstColumn = Selection.Rows(1)
    firstColumn.Interior.Color = RGB(250, 238, 153)

'初期位置を選択
    Range(Selection(1).Address).Select

Application.ScreenUpdating = True

End Sub
```

<img width="700" alt="DBpaste.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362512/d150a246-d1a8-71b3-ce92-aced5b4ba8d7.gif">


どうでしょうか？
これが意外と便利で重宝しております。

通常SSMSから取得して貼り付けた場合、Excel標準で貼り付けられるため手順として
1.データ貼り付け
2.表示形式を文字列に変更
3.再度貼り付け
4.罫線を追加
5.見出し行に色を追加する
上記のような手順を自分は踏んでおりました。

その行為をぎゅっとまとめたのが上記マクロになります。
コメントがつどつど記載しているため処理内容に関してはコメント通りとなっており問題ないと思いますが、3点ほど個人の好みになると思う箇所がございます。


#### ペーストするものがない場合のエラー処理がない
普通でしたらエラー処理の一つでも入れるべきなのでしょうが、このくらいの処理内容であれば~~面倒くさいから~~入れなくていいかと思って入れてないです。



#### データ行が１行もない場合
一行もない場合今回のマクロですと一つ下のセルも選択して何もないことを示しているのですが、
人によっては何もないなら罫線をつけるべきではないと思う方もいらっしゃると思うのでその場合は該当処理をコメントアウトもしくは削除してください。

#### 見出し行の色が気に入らない
これに関してはほぼこのみかと思われます。
参考程度ですが下記のサイトでお好みのRGBが見れるのでよろしければどうぞ
[原色大辞典様](https://www.colordic.org/)


## 少しでも楽したい人に向けて
今回のマクロはあくまで楽をするという点に重きを置いているのでExcel側も少し手を加えます。

・開発>マクロを選択
<img width="800" alt="Excelホーム" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362512/e4e06d06-b144-3e98-037f-c848f50d47de.png">

・登録したマクロを選択しオプションを選択する
<img width="400" alt="マクロオプション" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362512/60b1c7d0-9386-84f3-2e0a-1bb29afcef42.png">

・ショートカットキーをShift + V で登録
<img width="400" alt="マクロ登録" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362512/69a53242-3b65-6ddc-4b8f-9dc26f0f4375.png">



ここまで行えばSSMSでCtrl+Shift+CからCtrl+Shift+Vでサクッとデータの貼り付けができます。


## 終わりに
最後まで目を通りしてありがとうございました。
冒頭にもお伝えいたしましたが初投稿故見づらい点、もしくはこうしたほうが読みやすくていいよ、などありましたらお気軽にコメントくださると幸いです。
Pythonによる多次元リストを一次元に平坦化

# Pythonによる多次元リストを一次元に平坦化

## 前置き
@ahpjop 様の[「自作Python100本ノック」](https://qiita.com/ahpjop/items/023cb561d7a2081ad606)を解いていて、Q14が勉強になったので記事にまとめました。

## コード

```python:flat.py
def flat(l):
    res = []
    for i in l:
        if type(i) is list:
            res.extend(flat(i))
        else:
            res.append(i)
    return res

a = [1,2,[3,4],5,[6,[7,[[8,9]]]]]
print(flat(a))

#　実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

## 説明
ここでは、appendメソッドとextendメソッドが重要になります。

[公式ドキュメント](https://docs.python.org/ja/3/tutorial/datastructures.html)より

- **appendメソッド**
list.append(x)
リストの末尾に要素を一つ**追加**します。a[len(a):] = [x] と等価です。

- **extendメソッド**
list.extend(iterable)
イテラブルのすべての要素を対象のリストに追加し、リストを**拡張**します。a[len(a):] = iterable と等価です。


``` python3:sample.py
a=[]

a.append(1)
#[1]
a.append([2])
#[1,2]
a.append('ai')
#[1,2,'a','i']
```
今回の場合、リストの要素が数字ならそのままresに追加し、リストならresを拡張しているわけです。これにより、多次元リストを一次元に平坦化しています。
AttributeError: 'PosixPath' object has no attribute 'read_text'の対処法 環境

環境
```
$uname -a
Linux Ubuntu 5.4.0-146-generic #163-Ubuntu SMP Fri Mar 17 18:26:02 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

$cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
```

condaコマンドを叩くと，

```
AttributeError: 'PosixPath' object has no attribute 'read_text'
```
とエラーが出る．

## 結論
私の環境だと，pathlibを削除すると直りました．
```
pip uninstall pathlib
```

## エラーが出るようになった経緯
lightgbmのバージョンを最新のもの（3.1.2→3.3.5）にアップデートした瞬間に起きた．
pathlibを削除してなぜ動いたのかはわからない．


## 参考文献
この記事は以下の情報を参考にして執筆しました。
- [[BUG] AttributeError: 'PosixPath' object has no attribute 'read_text' with setuptools 60.9.0+ and pathlib #3294](https://github.com/pypa/setuptools/issues/3294)
Go言語で、UTF8 -> ShiftJis の変換

transform.Stringを使う方法がネットで記載が少なかったので記載。

```
func Utf8ToSjis(str string) (string, error) {
	sjisEnc := japanese.ShiftJIS.NewEncoder()
	sjisStr, _, err := transform.String(sjisEnc, str)
	if err != nil {
		return "", err
	}

	return sjisStr, nil
}
```
【論文レビュー】Identity Mappings in Deep Residual Networks chap.2【ResNetの数理的理解】

# 1. はじめに
本記事はResNetに関する論文[Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027)を読んでみてのレビュー記事の補足になります。
記事本編では省略してしまった数式を用いた説明部分をここで詳しく説明していきたいと思います。
レビュー記事本編をご覧になっていない方はそちらから見ていただくことを推奨いたします。

https://qiita.com/sokono-omae/private/aaef3fc54bee0c51e73b

# 2. Chap2. Analysis of Deep Residual Networks
第2章です。改めて論文中でのこの章の位置づけは、深層ResNetの構造について情報伝播の観点から数理的に解析する章ということになります。
それでは早速見ていきましょう。

まずResNetの残差ユニットは層$l$における入力$x_l$、残差関数$F$、$F$のパラメータ$W_l$、活性化関数$f$を用いてこのような形で定義されます。
```math
y_l = h(x_l) + F(x_l,W_l) \quad...(1) \\
x_{l+1} = f(y_l) \quad...(2) \\
```
式(1)に登場している$h$は恒等関数であり、$h(x) = x$を満たします。

ここで活性化関数$f$も恒等関数であり、$x_{l+1} \equiv y_l$を満たすとします。この時、式(1)は以下のように変形できます。
```math
x_{l+1} = x_l + F(x_l,W_l) \quad...(3) \\
```
式(3)によって$l+1$と$l$の関係を導くことができました。数学に慣れている方であればこの後どうしていくのかは容易に想像がつくと思いますが、私はもうワンクッション置きます。

$l+1$と$l$の関係がわかるなら、$l$と$l-1$の関係もわかる、ということは$l+1$と$l-1$の関係もわかるはずです。
```math
x_{l+1} = x_{l-1} + F(x_{l-1},W_{l-1}) + F(x_l,W_l) \quad...(3)' \\
```
はい、ということは再帰的に任意の$L$と$l(L>l)$の関係を以下のように導けます。
```math
x_{L} = x_{l} + \sum_{i=l}^{L-1} F(x_{i},W_{i}) \quad...(4) \\
```
つまり任意の深層$L$の入力$x_L$は浅層$l$の入力$x_l$とそれまでの残差関数の累積和で表現できるということになります。これは一般的なニューラルネットワークがテンソル積で情報を深層に伝播していくのとは対照的で、任意の浅層$l$の情報を直接任意の深層$L$に伝播できることを示しています。

以上が順伝播における数理的な解説です。次に逆伝播について考えてみます。
損失関数を$\varepsilon$と定義すると任意の浅層$x_l$における微分は連鎖則を用いて以下のように表現できます。
```math
\frac{\partial\varepsilon}{\partial x_l} = \frac{\partial\varepsilon}{\partial x_L}\frac{\partial x_L}{\partial x_l} \\
```
この式を式(4)を用いて表すと以下のようになります。
```math
\begin{align}
\frac{\partial\varepsilon}{\partial x_l} &= \frac{\partial\varepsilon}{\partial x_L}\frac{\partial}{\partial x_l}\biggl(x_{l} + \sum_{i=l}^{L-1} F(x_{i},W_{i})\biggr) \\
&=\frac{\partial\varepsilon}{\partial x_L}\biggl(1 + \frac{\partial}{\partial x_l}\sum_{i=l}^{L-1} F(x_{i},W_{i})\biggr) \qquad...(5)
\end{align}
```
式(5)は任意の浅層$x_l$における微分が任意の深層$x_L$における微分と残差関数の微分に関連する項の和で表現していて任意の深層$L$の情報を任意の浅層$l$に直接伝播させることができることを示しています。

また、$\frac{\partial}{\partial x_l}\sum_{i=l}^{L-1} F(x_{i},W_{i})$が常に$-1$になることは非常に稀であるため、$W$がいくら小さくても勾配消失はしにくいことを示しています。

# 3. まとめ
ResNetの残差ユニットにおけるShortcut Connectionと活性化関数をそれぞれ恒等関数とであるとした場合、順伝播においては任意の浅層から任意の深層へ直接情報の伝播が可能になり、逆伝播においては任意の深層から任意の浅層へ直接情報の伝播が可能になり、なおかつ勾配消失が起こりにくくなる、ということが残差ユニットを数理的に解析することで解説されています。
次章以降ではShortcut Connectionや活性化関数が恒等関数でない場合にどのような挙動になるかが述べられています。
続きは是非こちらからご覧ください。

https://qiita.com/sokono-omae/private/f02a3943836265e9ee2c

# 4. 参考
- [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027)
質問のお話

分からないことを同僚・上司に質問するとき、丸投げで質問するのは良くないけど、
とはいえ質問できずに問題解決できないのも良くない。
じゃあどうすればええんじゃ！:sob::sob:というのを以下にまとめる。

# なぜ丸投げ質問をしてしまう？？
### そもそも何がわからないのかが分かっていない
教えられたことや既存の情報に対して、文字通りには理解したものの、その意図や背景まではくみ取れていないパターン。この場合、実践で不明点が出たとき「なぜそうなったか」がうまく言語化できないがために、抽象的な質問になりやすい。


### 自分で解決しようとする気がない
「自分で調べるより、分かる人に聞いた方が早い」と考えていたり、「質問は少なからず相手の時間を取ること」という認識が薄いパターン。この場合、期限に追われていたりでその場しのぎでの課題解決を求めている時に陥りがち。
男とデートしたときに「どうせおごってくれるやろ」と思って財布も出さん女か！と質問された側は思います。
まあおごるんやけどね！

# どう質問するべきか？？
### 今の自分の状況を整理する
質問する前にまず時間を取って以下のことを言語化できるレベルで整理する。

・何が分からないのか

・何が分かっているのか

・どこまで何をしたか or できるか

・最終的にどうしたいのか

これをしたら意外とすんなり自己解決できたり、質問が具体化されてその後の質問のやり取りの時間を削減できる。
ただ自己整理に時間をかけすぎるのも問題なので、かの有名な[15分ルール](https://tkybpp.hatenablog.com/entry/2016/08/16/173055)でやればよい。

>問題が起きた時は
>
>【1】最初の15分は自分自身で解決を試みる
>【2】15分後も解決していなかったら必ず人に聞く
>
>前者を守らないと他人の時間を無駄にし、後者を守らないと自分の時間を無駄にする。

15分かけてももし解決できなかった場合は、自分の実力・知見不足と割り切って
整理した情報を握りしめてさっさと質問しましょう！！

### 「答え」ではなく「答えの求め方」を知ろうとする意識
「答え」を直接聞いた方が確かに解決するまでの時間は速いと思う。
でもそれだと自分の理解は深まらないし、「答え」を求める作業を質問に答えてくれる人に
丸投げするわけなのでその人の時間を奪います。

（「答え」を聞いた方がよいパターンもあるんで一概には言えませんが）

まあ自分の知識がない領域については答えを教えてもらいたくなるよな。楽やし。
（気持ちはすごいわかる）





# 最後に
なにも意識せずに質問しても、結局その場しのぎになるだけで深い理解は出来ずに、
同じ質問をしてしまったり、自分の時間も質問される側の時間も潰してしまったり悪いことしかない。
逆にこれまで書いてきたような意識で質問すれば、自分の問題解決能力や知見が向上するし、
解決までの時間も短くなると思う。
テキスト選択によって、アインシュタインの画像が見えてくる

# はじめに
「テキストを選択すると背景色が変わる」という単純な仕組みを利用して、一見普通に見える文章の中に実は画像が隠されているWebサイトを作成しました。

[実際に作成したサイト](https://starlit-granita-8e90bb.netlify.app/)
↑テキスト部分をマウスで選択、もしくはCtr + A で全選択すると、アインシュタインの画像が表示されます。サイトの面積が大きいので、ある程度縮小して全体が見れるようにした方がいいです。
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363378/4d95923d-3c9f-7656-c05c-de4989d41088.png)
↑一見普通に見える文章ですが...
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363378/5cc38a08-92ca-d49d-add0-6615d9ffe37b.png)
↑マウスで選択すると、アインシュタインの画像が現れます！


[GitHubのリンク](https://github.com/yuichiaogata/HiddenPicture)


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Chapter1 各ピクセルの色値を抽出](#Chapter1)
1. [Chapter2 色値を文字列に埋め込む](#Chapter2)
1. [今後](#今後)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# Chapter1 各ピクセルの色値を抽出
左上から1ピクセルずつRGBで色を抽出しています。Webで使用する際には、RGBを16進数で表記する必要があるので、途中で変換しています。
```
for y in range(h):
    color_list_sub = []
    for x in range(w):
        rgb = pix[x, y]
        hex_color = '{:02x}{:02x}{:02x}'.format(*rgb)
        color_list_sub.append(hex_color)
    color_list.append(color_list_sub)
```



<a id="#Chapter2"></a>
# Chapter2 色値を文字列に埋め込む

cssファイルに下記のように記述したのち、

```
.color-000016::selection {background-color: #000016; color: #fff;} 
```

これをHTMLファイル側で下記のように受け取ることで、テキスト選択時の色を指定することができます。
```
<span class="color-000016">hogehoge</span>
```
# 今後
任意の画像を投げることによって、その画像に応じた文章を(Chatgptなどを用いて)自動で生成し、表示したいです。
また、画面サイズ的に300×300ピクセルの画像が適当だと思うので、自動でサイズ変更できる機能も追加したいです。

<a id="#reference"></a>
# 参考文献
- [テキストベースのサイトに写真を入れ込む、単純だけどもの凄い仕掛け](https://naglly.com/archives/2010/06/post-521.php)
RXマイコンでFreeRTOS入門　～マルチタスクLチカ編～

# はじめに
RXマイコンでFreeRTOSの勉強を初めたので、
まずは簡単なLチカをやってみようと思います。

開発環境：e2studio
使用ボード：TARGET BOARD for RX23W module
# 手順
## プロジェクト作成
1. プロジェクトを新規作成します
![スクリーンショット 2023-05-09 152542.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/d62708af-cf63-506c-148d-a58388fe8592.png)
2. プロジェクトを選択します（GCCを使用する人はそっちを選択してください）
![スクリーンショット 2023-05-09 152619.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/69f9d266-b095-1e3b-c852-c5b6c979e0c6.png)
3. プロジェクト名はLchikaとして次へ
![スクリーンショット 2023-05-09 152648.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/24b334db-ffa2-0356-3537-4daca1551372.png)
4. RTOSにFreeRTOS(kernel only)を選択、使用ボードなどを設定します
![スクリーンショット 20![スクリーンショット 2023-05-09 153027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/26c349dc-5c98-f6a4-19d0-eef065427d99.png)
23-05-09 152740.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/49c0290a-f7ca-6f5b-9d55-360f046aa876.png)
5. プロジェクト設定を終了します
![スクリーンショット 2023-05-09 152801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/13bdbc2f-5bb6-1d7c-fe05-209622d67742.png)

## スマートコンフィグレータの設定
6. 次にスマートコンフィグレータを開き、コンポーネントのタブを開きます。
![スクリーンショット 2023-05-09 152854.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/9dcc03fa-d36f-a6ec-7615-4a7c8aef5def.png)
7. ポートのコンポーネントを選択します
![スクリーンショット 2023-05-09 152940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/c69d8c78-9752-0d45-a1e7-cc7a268b2876.png)

8. LEDのポートを設定します（今回のボードはLED0がB0、LED1がC0）
![スクリーンショット 2023-05-09 1530.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/1ac7146e-b3c6-1718-7e00-4f1d32a1d844.png)
9. LEDのポートを出力ポートに設定します（B0、C0）
![スクリーンショット 2023-05-09 153116.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/5aa2ff61-433d-e310-562d-145fd5189115.png)
10. 次にFreeRTOS_Kernelの設定を開き、TOTAL_HEAP_SIZEを20に設定します(20kB)
![スクリーンショット 2023-05-09 153236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/a2499c72-8951-aa0a-b48b-1ebc35c2c155.png)
11. FreeRTOS_Object設定のTasksタブからtask1, task2を作成します
![スクリーンショット 2023-05-09 153311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/dc1b4de1-89b9-9439-4f7c-e06e34d848ce.png)
12. 以上の設定が終わったら「コードの生成」を押して自動生成します

## タスクの中身を作成
13. frtos_skeletonフォルダの中にtask1.cというファイルが生成されているので、画像のコードを書きます。
300ms周期で点滅するようにしています
![スクリーンショット 2023-05-09 153457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/868c24a6-bdd0-af07-d318-725505a00c80.png)
14. task2.cも同様にします。こっちは500ms周期で点滅させます。
![スクリーンショット58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/1208d194-d77f-83e0-9495-6bb4543aa09c.png)

15. main_task関数にあらかじめ書いてあるwhileループを削除します
![スクリーンショット 2023-05-09 153604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/44b34261-b902-c025-ced6-ec678ce63916.png)
## ビルド&デバッグ
以上のコードをビルド、デバッグ実行することでLED0が300ms周期、LED1が500ms周期で点滅します
![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839352/70a123f4-0961-3c96-2939-f4ef4aba5757.gif)

# まとめ
スマートコンフィグレータをポチポチするだけでほとんど設定できて簡単にRTOSでLチカができましたね。
お疲れさまでした。
GNUPLOTで複数のCSVファイルを描画する

本ページでは、GNUPLOTを使って、複数のcsvファイルからなるデータの描画を行う。  
# GNUPLOTのインストール 
ターミナルで以下のコマンドを打ち込み、GNUPLOTをインストールする。少し時間はかかるが、まつ。
```
$brew install gnuplot
```
# 1つのファイルの描画 
試しに、「5-0-0.csv」というファイルを描画する。  
```
$gnuplot
plot '5-0-0.csv' using '%lf,%lf'
```
`$gnuplot`でGNUPLOTを起動し、`plot '5-0-0.csv' using '%lf,%lf'`で、ファイルを描画する。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119582/0174c1bb-d876-1966-00b2-1548426a330f.png)
その結果、描画されたのが、上図である。ここから、描画の結果に対して少々の変更を加えたい。
## 線でプロット
現状では、プロットに「+」が使用されている。これを点にし、それぞれの点を繋ぐ線を描きたい。そのためには、以下のオプションを追加する。 
```
plot '5-0-0.csv' using '%lf,%lf' with line
```
これによる出力が下図の通りである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119582/058e38e1-fd06-3e7e-fdf4-745498c20c88.png)
## 軸名をつける
それぞれの軸に名前をつけるには、以下のコマンドを使用する。 
```
set xlabel 'time'
set ylabel 'theta'
```
なお、それぞれの設定を行った後には、再度描画することが必要になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119582/6b5a3f2b-d194-88cc-f62c-b2f2d0c75da9.png)
それらのコマンドを打った後の結果は上図のようになる。

## 値の範囲の選択 
```
set xrange[最小値:最大値]
set yrange[最小値:最大値]
```



## 凡例の変更
凡例の変更では、`title`オプションを使う。よって、コマンドは以下のようになる。 
```
plot '5-0-0.csv' using '%lf,%lf' title '5-0-0'  with line
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119582/5353aae8-b405-074b-c698-df423ea9a4f9.png)
それによる出力が上図の通りである。ここまでで、おおよそ自分の目的のものができた。
## 凡例における注意 
複数の凡例を出力する場合、指定したデータの順番通りに出力されることに注意が必要である。

# 複数ファイルのcsvの描画 
ここからは、当初の目的であった、複数のcsvファイルを使った描画に移る。
```
plot '10-0-0.csv' using '%lf,%lf' w l,'10-0.5-0.csv' using '%lf,%lf' w l
```
なお、`w l`は`with line`と同じ意味合いである。 
![fig-kd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119582/498ccef6-9d25-f5e4-62fc-b5133e6ec755.png)

# 参考文献 
- [Macにgnuplotをインストール](https://qiita.com/kkml_4220/items/fe2f4d91305cf1cdca96)
- [GNUPLOTでお絵かき](https://www.power.mech.eng.osaka-cu.ac.jp/~takiyama/gnuplot-howto-win.html)
【AWS Glue】PySparkでjsonを読み込む際、スキーマ定義を別ファイルで定義しておく方法

## はじめに
GlueのDynamicFrameを使わない場合、スキーマを定義してデータを読み込みたいときってありますよね。
そんな時、スキーマがめちゃくちゃ長くなると、別ファイルに切り出したくなると思います。
その方法のうちの1つを試したので、共有します。

## 方法
### 準備するデータ
実際にロードするjsonのデータ`sample_data.json`と、カラム定義ファイル`schema.json`を準備します。
今回は、これらのファイルをS3に格納しています。

```json:sample_data.json
{"Name": {"First name": "Taro", "Last name": "Tanaka"}, "Age": 23}
{"Name": {"First name": "Hanako", "Last name": "Yamada"}, "Age": 18}
{"Name": {"First name": "Ichiro", "Last name": "Sato"}, "Age": 38}
```

```json:schema.json
{
    "fields": [
        {
            "metadata": {},
            "name": "Name",
            "nullable": true,
            "type": {
                "fields": [
                    {
                        "metadata": {},
                        "name": "First name",
                        "nullable": true,
                        "type": "string"
                    },
                    {
                        "metadata": {},
                        "name": "Last name",
                        "nullable": true,
                        "type": "string"
                    }
                ],
                "type": "struct"
            }
        },
        {
            "metadata": {},
            "name": "Age",
            "nullable": true,
            "type": "integer"
        }
    ],
    "type": "struct"
}
```

### ロード
S3に、以下のようにデータファイルとスキーマ定義ファイルを格納します。
```
.
└── sample-bucket
     ├── data
     │   └── sample_data.json
     └── schema
         └── schema.json
```

その状態で、以下のようなコードをGlueで実行します。
```python
import boto3
import json
from pyspark.sql.types import IntegerType, StringType, StructField, StructType

s3 = boto3.resource('s3')

# schema定義ファイルを読み込む
obj = s3.Object('sample-bucket','schema/schema.json')
response = obj.get()    
body = response['Body'].read()
json_dict = json.loads(body)

# jsonデータを読み込む
schema = StructType.fromJson(json_dict)
df_with_schema = spark.read.schema(schema) \
        .json("s3://sample-bucket/data/")
```

## メリット
- 別ファイルとしてスキーマ定義を記載できるので、めちゃくちゃ長いスキーマ定義でもコードがきれい！
- スキーマ定義とコードが分離されるので、スキーマ定義の変更があってもpythonファイルを更新しなくてよい！
- スキーマファイルのパスをジョブパラメータとすることで、ジョブを使いまわせる！

## デメリット
- pythonに直接スキーマ定義を書くよりも、少し冗長な書き方になる。
- 直接pythonファイルにスキーマが書かれないため、ぱっと見でスキーマ定義が分からない。
- スキーマ定義を別ファイルとして作成するため、ファイル数が増加しやすい。

## おわりに
メリデメ挙げてみましたが、スキーマ定義と実際のコードが分離されて疎になるのは嬉しいケースが多そうですね。
一度jsonとしてロードした後にparquetなどカラムと型が定義されるファイル形式で出力すると、その後のデータ分析がやりやすそうです。

## 参考
- 困ったときは公式ドキュメント

https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.types.StructType.html

- 検索で最初に見つけたサイト

https://sparkbyexamples.com/spark/spark-schema-explained-with-examples/
APPRENTICEシップ　1か月目を終えて

# APPRENTICEに参加して1か月経ちました。

最初の記事ではあまり細かく書いてなかったので、改めて自分でもスケジュール感を確認するために
1か月やったことと、これからやることをまとめてみました。
[※ちなみに1か月前の記事はこちら。Markdown記法すら知らない頃](https://qiita.com/soichiro-saeki/items/49294ec705a644f0873e)

### アプレンティスシップとは
アプレンティスシップとは簡単にいうと未経験でもお金もらいながら実務環境で実績を積むことができ、そこからそのままその企業に就職できたり、転職の実績を積むことができる未経験エンジニア向けのサービスです。

サービス自体は無料なのですが、メンターに随時相談するのではなく基本的に独学で勉強することになります。　
独学のロードマップ教えてくれて、推奨本などを提示してもらいあとは自走できるかどうかというところがポイントになります。

### スケジュール
[学習期間] 4/10（月）〜8月末
[アプレンティスシップの面接] 9月
[アプレンティスシップの開始] 11月

### 学習内容
Week 1-2: Ruby/オブジェクト指向
Week 3-4: Linux/Git,GitHub
Week 5-6: データベース/SQL
Week 7-8: HTML/CSS/JavaScript
Week 9-10: Rails/テスト
Week 11-12: AWS/Web
Week 13-14: オリジナルプロダクト①アプリケーション実装
Week 15-16: オリジナルプロダクト②インフラ構築
Week 17-18: オリジナルプロダクト③機能拡張
Week 19-20: 1on1イベント準備 

## 1か月でやったことと所感

#### [1-2week]
rubyでブラックジャックを実装するというもの。よくあるやつですね。
推奨本とか共有いただきながら、進めていきますがオブジェクト指向は2週間で勉強するのはほぼ無理なので、ブラックジャックで、学習時間が取れるかなどの”ふるいにかけている”のかなと思いました。
#### [3-4week]
LinuxとGit,githubについての学習をしました。
簡単なLinuxのコードを使ってパスワードマネージャーを実装するのと、暗号化もするという内容でした。
#### [5-6week]
MySQLを使ってデータベースの設計と情報取得するクエリを学習しました。
こいつが結構ヘビーで、正規化をするということに非常に悩まされました。


### 所感
やっていて思うのは、今の職業が合わないし、エンジニアの働き方とかに興味があるぐらいの温度感でこのアプレンティスシップを乗り越えるのは厳しいなと思いました。
エンジニアになって、世の中の課題解決をしたいというようなエンジニアへの強い意志が必要なものだと感じました。

スクールが流行ったおかげで、自走力のないエンジニアが市場にあふれ、ポートフォリオも似たものしか見ないという企業側の課題も解決しているし、スクールで転職するためだけの勉強をさせられるのではなく、自走できるエンジニアを目指すこともできるので、学習する側としてもありがたいサービスだと思いました。

これエンジニアだけでなくどの業界も積極的にすべきだし、自分もいずれはこういう取り組みができるようなサービスを作っていきたいとも思いました。
Azure Bastionで痛い目を見た話

:::note
<strong>サービスを使う前には、必ず課金体系を確認しましょう；；
急ぎの場合でも必ず！！！</strong>
:::


## Azure Bastionとは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/d63b3823-674b-c6ac-d823-6f8cefbe2d3b.png)
（出典[^1]）
 

>Azure Bastion は、ブラウザーと Azure portal を使って、またはローカル コンピューターに既にインストールされているネイティブ SSH か RDP クライアントを介して仮想マシンに接続できるようにするサービスで、ユーザーがデプロイします。 Azure Bastion サービスは、お使いの仮想ネットワーク内でプロビジョニングする、フル プラットフォーム マネージド PaaS サービスです。 これにより、TLS 経由で Azure portal から直接、仮想マシンに安全かつシームレスに RDP/SSH 接続できます。 Azure Bastion 経由で接続する場合、仮想マシンにパブリック IP アドレス、エージェント、クライアント ソフトウェアはいずれも不要です。 （出典[^1]）

ざっくり言うと、<strong>インターネット経由で、簡単にサーバに接続できる仕組み</strong>です。


## Bastionを使うときの注意点

### Bastionはリソースがあるだけでお金がかかります！！
>Azure Bastionは、送信データの使用状況に関係なく、リソースがデプロイされてからリソースが削除されるまで1時間ごとに課金されます。時間単位の価格は、選択した SKU、構成されたスケール ユニットの数、およびデータ転送レートに基づきます。（出典[^2]）

:::note 
Bastionは<strong>作成～削除</strong>まで<strong>ずっと課金</strong>されます
:::
:::note alert
<strong>接続している時間ではない</strong>ので注意！！
:::

おかげで先月はこんなことになってしまいました。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/4e295248-72db-a86d-d850-72ce162630c2.png)

今回はデフォルトのBasicだったからよかったものの、Standardだったらまずかったですね
（1.5倍なので2万強。。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/93c75410-e0df-5031-5cef-013cdefde978.png)
（出典[^2]（2023/5/9現在））


### 対策
<strong>コストアラートを利用する</strong>
プレビューではありますが、リソースグループごとに予算管理が可能な様子
今後長期で利用する場合は設定しておきたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/9e061e86-4648-e1be-eeb5-e52b4677139a.png)




## まとめ
### サービスを使うときはしっかりと理解を深めてから使いましょう
portalからチャチャっとリソースが作成できるようになっているからこそ、注意したいですね。。。




#### おまけ
ずっとBation（ばっしょん）と思っていましたが、Ba<strong>"s"</strong>tion（ばすちょん）でした。。。


[^1]: https://learn.microsoft.com/ja-jp/azure/bastion/bastion-overview
[^2]: https://azure.microsoft.com/ja-jp/pricing/details/azure-bastion/
[^3]: https://learn.microsoft.com/ja-jp/azure/cost-management-billing/costs/cost-mgt-alerts-monitor-usage-spending?WT.mc_id=Portal-Microsoft_Azure_CostManagement
vue3 pinia でログイン・ログアウト

ログイン、ログアウト機能をvue3で作りたい。
まずは、各コンポーネント間でデータを受け渡す。

# pinia って何？
vue3 から 使えるコンポーネント間のデータ受け渡し。
ログイン、ログアウトとかで使える。


# 目的

home.vue と login.vue で同じデータを表示したい。

# インスコ

```
npm install pinia
```


```app.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'//追加
import App from './App.vue'

const app = createApp(App)
app.use(createPinia())//追加
app.mount('#app')

```

```resources/user.js

import { defineStore } from 'pinia';

export const useStoreUser = defineStore('user', {
    state: () => ({
        count: 1,
        count2: 2,
        user: {
            name: 'John Doe',
        },
    }),
    // computed と同じ
    getters: {
        doubleCount: (state) => state.count * 2,
    },
    actions: {
        increment() {
            this.count++;
        },
    },

});

```

```home.vue

<template>
    <p>ホームで個別でpinia</p>
    <p>Count:{{ user.count }}</p>
    <button @click="user.increment">Up</button>
    <RouterLink to="/login">ログイン</RouterLink>
</template>


<script lang="ts" setup>
import { useStoreUser } from '/resources/user';
const user = useStoreUser();
</script>

```


```login.vue

<template>
    <p>Count:{{ user.count }}</p>
</template>

<script lang="ts" setup>

import { useStoreUser } from '/resources/user';
const user = useStoreUser();

</script>

```


home.vue で increment した内容が、login.vueで表示されればOK

# 永続化（ブラウザを閉じてもデータを残す）

以下を参考にどうぞ。
https://c-a-p-engineer.github.io/tech/2022/12/20/vue3-typescript-pinia-persisted/
2年目のペーペーが1年目のペーペーにアドバイスするよ

# はじめに

エンジニアになってから1年がたち、4月からは新人の方たちも入ってきました。
新人のコードをレビューしていると「うわ〜これ自分もやっちゃってたな〜...」と思うことが度々あるので、新人のあなたが同じ過ちを犯さないで済むようにこの記事で紹介していきたいと思います。
ベテランのあなたは読まなくて大丈夫です。

## 書かなくてもいいコメントを「（自分が）分かりやすいから」と残しがち

結構あるあるなんじゃないでしょうか？
そもそもコメントは少ない方がいいですが、必要に応じて残す場合もありますよね。最初はこの「必要に応じて」がどのくらいのレベル感なのか掴めず、不要なコメントを量産している人は少なくないはず。
私もかつてはゴミコメント生産機でした。こんな具合に。

```ruby
# 初期化
def initialize
  ...
end
```

```ruby
# 繰り返し処理を実行
array.each do |item|
  ...
end
```

とは言っても最初はコメントを残すべきかどうかの判断がなかなか難しいかもしれません。
とりあえず、処理の内容をそのまま書いたようなコメントは残さないようにしましょう。

## コードの修正に伴うコメントの変更忘れ

これ1回やらかさないと意識できない気がします。
修正箇所のすぐそばにあるコメントならまだしも、ファイルの冒頭に書いてある全体を説明しているようなものにはなかなか目がいかないですよね。
最後に見直す時は、修正箇所だけでなくファイル全体に目を通す癖をつけるといいかもしれません。

## メソッド名や変数名が地獄

プログラマーには生涯付きまとうであろう、命名問題。
半分慣れな部分もあるよな〜と思いつつ、でかいテーマであることに変わりはないので挙げさせてもらいました。
最近はChatGPTに命名候補をいくつか出してもらうなんて人もいるようですが、まずは自分で考えてみることをお勧めします。特に最初のうちは。

## 自分が書いたコードが通るようなテストケースしかない

テストがテストになってない問題。これ難しいですよね、、、
どうしても自分が書いたかわいいコードを前提にテストを書いてしまう。しょうがないっちゃしょうがないですが、許すわけにはいきません。
個人的に、他人が書いたテストのケース漏れを指摘するのは非常に難しい気がします。なので、テストは慎重に冗長に書きましょう。「このケースいるかな？」と迷ったらとりあえず書いときましょう。
通るケースを想像するのは容易いので、「こんな場合だと通らないかもしれない」を意識的に考えるようにしてみるといいかもしれないですね。

## 不要になった定数やメソッドの消し忘れ

こうやってゴミコードが増えていくんですね〜。
定数やメソッドを消す修正をした時は必ず全件検索して、他に使われている箇所がないことを確認したうえで全世界から消し去りましょう。
使われていない定数やメソッドに遭遇した時、人は「これ本当に消していいのか？」と削除するのを躊躇います（よね？）。なので、使われなくなったその瞬間に消すのが最も理想的です。
逆にこれができていると、「お、よく見ているな」と思慮深い人間だと思ってもらえます。

## デバッグコードの消し忘れ

あるあるですが犯罪です。思慮の欠けた人間だと思われます。
最後にコミット内容を確認するようにしましょう。

# 最後に

コードを書くときの基本的な心構えを知りたい人は、『[リーダブルコード](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)』という本を読んでみることをお勧めします。プログラマーなら読んでおいて損はないんじゃないかと思います。
他にもやりがちなミスがある人はぜひ教えてください。
ChatdollKit ver.0.6でマルチスキルを実装したい方へ

# 1.ChatdollKitのマルチスキルを実装しようとして1日溶かしちゃった話
　ChatdollKitって素晴らしいですよね！！VRM形式の3Dモデルさえ手元にあれば誰でも自分のPCやGateboxにバーチャル嫁や妹(以下バーチャル嫁と表記)を召喚できちゃうんですから！！
　ですが、人の欲望というのは尽きないものでして、バーチャル嫁と会話できるようになったら満足するのではなく、もっと作りこんじゃいたくないますよね？私もそうです。

　そこで、オリジナルのマルチスキルを作ってバーチャル嫁をもっと万能にしたいと考えたのはいいものの、つまずいてしまったのがマルチスキルの実装です。2023/05/09時点のChatdollKit最新版(v0.6)でマルチスキルを追加実装しようとして、どのコンポーネントをアタッチすればいいか、また、アタッチできない場合はどう修正すれば解決できるのかがわからず、過去のバージョンを解析してそこの問題解決に時間を使っちゃいました。

　このフレームワークを制作してくださっている[うえぞう様](https://twitter.com/uezochan)にコンタクトを取っても良かったのですが、エンジニアの端くれとして、まずは自分で修正してみたいと感じたため過去のバージョンもあさりながら解析させていただきました。

# 2.結論
　プロジェクト\Assets\ChatdollKit\Examples\MultiSkills\Scripts\Router.csに実装したい拡張スキルを記述してアタッチするだけです。しかし、ver.0.6でこのコンポーネントをアタッチしようとするとエラーが起きてアタッチできません。

　エラー文を和訳すると、このコンポーネントが継承元を含めてMonoBehaviourの属性を持っていないためアタッチできないそうです。

　ですが、ver.0.3.2の時点ではマルチスキルが動いているのを確認しました。そこで、ver.0.3.2とver0.6のコンポーネントについて相違を調べていったところ、プロジェクト名\Assets\ChatdollKit\Scripts\Dialog\Processor\SkillRouterBase.csに過去バージョンにはあったMonoBehaviourの記述が抜けていることが判明しました。以下の通りに修正したらマルチスキルも使えるようになりました。

```プロジェクト名\Assets\ChatdollKit\Scripts\Dialog\Processor\SkillRouterBase.cs
using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks;

namespace ChatdollKit.Dialog.Processor
{
    public class SkillRouterBase : MonoBehaviour, ISkillRouter // MonoBehaviourを追記する
    {
        protected Dictionary<string, ISkill> topicResolver = new Dictionary<string, ISkill>();

        public void RegisterSkill(ISkill skill)
```

　上記の修正をして再度Router.csをアタッチしたら成功しました。どのバージョンで消えちゃったかは知りませんが本家の方で修正入るまではマルチスキルを使いたい場合手作業で上記該当箇所の修正が要ります。

　以上でバーチャル嫁に無限大にスキルを乗せる用意は完了します。後はどこまでバーチャル嫁に能力を上乗せできるかは各々の実力次第です。

　全ての同志たちに栄光あれ！！
【Swift】R.swiftを使った文字列のハードコーディング対策

# はじめに
`Localizable.stirngs`を使って、文字列のハードコーディングを避けていた。
URL: [【Swift】Localizable.stringsを使った文字列のハードコーディング対策](https://qiita.com/kasiwa/items/06d1f2309f6655d29a45)
しかし、自動補完が効かないデメリットがある。


この記事では、`R.swift`を使った場合の文字列のハードコーディング対策の実装を備忘録として、記録する

# 実装比較
## `Localizable.strings`の場合
``` swift:Localizable.strings
"ArticleTitle" = "記事タイトル";
"ArticleAuthor" = "kasiwa";
"ArticleBody" = "記事本文記事本文記事本文記事本文記事本文記事本文記事本文";
"ArticleCreatedAt" = "2023/05/06";
```

``` swift:ViewController
import UIKit

final class ViewController: UIViewController {
    @IBOutlet private var articleTitle: UILabel!
    @IBOutlet private var articleCreatedAt: UILabel!
    @IBOutlet private var articleBody: UILabel!
    @IBOutlet private var articleAuthor: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        articleTitle.text = NSLocalizedString("ArticleTitle", comment: "")
        articleCreatedAt.text = NSLocalizedString("ArticleCreatedAt", comment: "")
        articleBody.text = NSLocalizedString("ArticleBody", comment: "")
        articleAuthor.text = NSLocalizedString("ArticleAuthor", comment: "")
    }
}
```

## `Localizable.strings`+`R.swift`の場合
``` swift:ViewController.swift
import UIKit

final class ViewController: UIViewController {
    @IBOutlet private var articleTitle: UILabel!
    @IBOutlet private var articleCreatedAt: UILabel!
    @IBOutlet private var articleBody: UILabel!
    @IBOutlet private var articleAuthor: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        articleTitle.text = R.string.localizable.articleTitle()
        articleCreatedAt.text = R.string.localizable.articleCreatedAt()
        articleBody.text = R.string.localizable.articleBody()
        articleAuthor.text = R.string.localizable.articleAuthor()
    }
}
```

# プレビュー
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802393/79647cfe-9fee-911f-2393-9abd2b70178e.png">

# 終わりに
`R.swift`を活用すれば、文字列の指定ミスによるクラッシュがなくなるので、開発を効率化できる。

個人的に、書きやすさも`R.swift`を使った方が楽。
StoryBoard, Cellも文字列と同様に、自動補完が効くので、積極的に`R.swift`を使っていきたい。

# 参考リンク
[R.swift - Github](https://github.com/mac-cain13/R.swift)
[R.swiftのセットアップ方法(Swift5)](https://qiita.com/uhooi/items/82fbdd94bdc467a22422)
Chromeの最新バージョンを取得するAPI

以下にアクセスするとChromeの最新バージョンが得られる。
（WindowsのStable版の例）
https://chromiumdash.appspot.com/fetch_releases?channel=Stable&platform=Windows&num=1

返り値サンプル（整形済み）：

```json
[
    {
        "channel":"Stable",
        "chromium_main_branch_position":1121455,
        "hashes":{
            "angle":"c2efe6fcdbc548c5ba6c1fa9c5415e256c7211ba",
            "dawn":"543ca1e4cd6474fe2772ad689bab7256a946cf04",
            "devtools":"e24710d614f3f16412444484e1f64b4439b965d8",
            "pdfium":"7c9b2b33ac5759b0443d8f6e01f07432ff034c12",
            "skia":"1195e70d671947af02a6a5b0ddc65806b9645252",
            "v8":"0e75d85d8e3467a536bca01d89d8a180a8bcffca",
            "webrtc":"f6ab0b438e22ea30db7ad3fbf9f870b0d4506235"
        },
        "milestone":113,
        "platform":"Windows",
        "previous_version":"113.0.5672.92",
        "time":1683578403731,
        "version":"113.0.5672.93"
    }
]
```
ドキュメントがあるかどうかは未調査なものの、恐らく`version`の値が最新バージョンを指していると思われる。

以下の公式ブログの内容とも一致する。
https://chromereleases.googleblog.com/

# 参考
- https://github.com/puppeteer/puppeteer/issues/8203
- https://stackoverflow.com/questions/35114642/get-latest-release-version-number-for-chrome-browser
kotlinとjacksonを用いてファーストクラスコレクションをいい感じにserializeする

# kotlinとjacksonを用いてファーストクラスコレクションパターンを記載する

## 0.想定する仮想class

```
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+")
```

```sample.kt
data class TaskList(
    val items: List<Task>
)

data class Task(
    val taskId: String,
    val title: String
)
```

上記のままserialize処理を実施すると、ファーストクラスコレクションに記載されたargumentまで、serialize処理されてしまう。

```result.json
{"items":[{"taskId":"taskId","title":"title"}]}
```

## 1. serializerをoverrideする

```part1.kt
@JsonSerialize(using = TaskListSerializer::class)
data class TaskList(
    val items: List<Task>
)

private class TaskListSerializer: JsonSerializer<TaskList>() {
    override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeStartArray()
        value.items.forEach { gen.writeObject(it) }
        gen.writeEndArray()
    }
}
```

```result.json
[{"taskId":"taskId","title":"title"}]
```

## 2. DeSerializerをoverrideする

地味ではあるが、List型はArrayにしてファーストクラスコレクションに入れる際に、list化する

```part2.kt
@JsonSerialize(using = TaskListSerializer::class)
@JsonDeserialize(using = TaskListDeSerializer::class)
data class TaskList(
    val items: List<Task>
)

private class TaskListSerializer: JsonSerializer<TaskList>() {
    override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeStartArray()
        value.items.forEach { gen.writeObject(it) }
        gen.writeEndArray()
    }
}

private class TaskListDeSerializer : JsonDeserializer<TaskList>() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): TaskList {
        val taskArray = p.readValueAs(Array<Task>::class.java)
        return TaskList(taskArray.toList())
    }
}
```

## 3. 全体概要

```sample.kt
@JsonSerialize(using = TaskListSerializer::class)
@JsonDeserialize(using = TaskListDeSerializer::class)
data class TaskList(
    val items: List<Task>
)

data class Task(
    val taskId: String,
    val title: String
)

private class TaskListSerializer: JsonSerializer<TaskList>() {
    override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeStartArray()
        value.items.map { gen.writeObject(it) }
        gen.writeEndArray()
    }
}

private class TaskListDeSerializer : JsonDeserializer<TaskList>() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): TaskList {
        val taskArray = p.readValueAs(Array<Task>::class.java)
        return TaskList(taskArray.toList())
    }
}

```