OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel環境構築時にlocalhostでSQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select * from sessions where id = 5d3B1AuW5zW1TpmKRRFXLSYLoiefJcQDG2kSAhBl limit 1)が出た話

# Laravel環境構築時のエラー
初めまして、Laravel初学者のものです。
新しいアプリを作成してみようと思い、`Laravel sail`を使用して環境構築しlocalhostを開いたところ下記エラーが表示されました。
```
SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select * from sessions where id = 5d3B1AuW5zW1TpmKRRFXLSYLoiefJcQDG2kSAhBl limit 1)
```
「あれ？今までこんなエラー表示されたっけ？」
今まで何度か環境構築してきましたが、構築時にこのようなエラーが表示されることはありませんでした。

# 結論
セッションドライバの設定が「database」になっていることが原因でした。
新しく構築した環境では`config/session.php`と`.envファイル`にてdatabaseを使用するよう設定されいたため、localhostを開く前にデータベーステーブルを作成するためのマイグレーションが必要なようです。
```:config/session.php
'driver' => env('SESSION_DRIVER', 'database'),
```
```:.env
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
```

なぜ自分が今までマイグレーションをせずにlocalhostを開けてたのかというと、このセッションドライバ設定が``file``になっていたからでした。
もし私と同じように今までfileセッションドライバを使っていて、新環境を構築した際にSQLSTATEエラーでlocalhostが開けなかった場合は`config/session.php`と`.envファイル`を確認してみてください。

# 後書き
プログラミング自体初心者の私がアウトプットも兼ねて初めて投稿してみました。
もし記載した内容に不備があった場合教えていただければ幸いです！

それにしてもLaravelのドキュメントを読んでみるとデフォルトはdatabaseセッションドライバに設定されているとの記載がありましたが、なんで今まで自分はfileセッションドライバに設定されていたんだろうか。。。
（今までLaravel10を使っていたからLaravel11から変わったのかな？）
AWSインスタンスのホスト名が変わってしまっていたときの対処方法

# 概要

AWSのインスタンスを`reboot`したらホスト名が変わってしまうことがあります。
原因としては、↓です。
> Amazon EC2 でインスタンスを起動するとき、起動後にそのインスタンスにユーザーデータを渡し、一般的な自動設定タスクを実行したり、スクリプトを実行したりできます。2 つのタイプのユーザーデータを Amazon EC2 に渡すことができます。シェルスクリプトと cloud-init ディレクティブです。

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

# 解消方法

### インスタンス起動時に`cloud-config`をユーザーデータを設定する。

1\.インスタンス起動時に高度な詳細を開く
![スクリーンショット 2024-06-08 23.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620245/b169f38f-8639-30da-55a6-392ca64ef410.png)
2\.ユーザーデータに以下のように`cloud-config`を追加
![スクリーンショット 2024-06-08 23.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620245/5b4d1838-f5f7-a2f3-f3ec-9268298cfc59.png)
```
#cloud-config
fqdn: ★ホスト名★
```

### 起動時にユーザーデータの設定を忘れた場合は、`/etc/cloud/cloud.cfg`の設定を変更する。

1\.変わってしまったホスト名を戻す
```
vi /etc/hostname
```
2\.cloud.cfgの修正 false → true
```
vi /etc/cloud/cloud.cfg
```
```
preserve_hostname: true
```
3\.rebootしてみてホスト名が変わらないか確認
```
reboot
```
サイト信頼性エンジニアリング(SRE)

# まえがき
おつかれさまです。mochiです。
今回は今勉強している資格に登場してきた『サイト信頼性エンジニアリング』について書こうと思います。SREと略されることが多いですね。

資格勉強をしていると、知らない単語や用語などがたくさん出てきます！でもそれを自分の中にインプットすることで頭良くなったように思えるので、頑張れます（笑）
軽く流し見してください。

# SREって？
SREは、2000年代初頭にGoogleが開発したアプリケーション開発やソフトウェア開発におけるアプローチのことです。AWSなどで使われているフレームワークにあったりする信頼性（ユーザーが期待した通りの動作）に近い印象です。DevOpsにも近いものかと思います。

SREは人間が行うタスクや問題解決、システム管理を自動化します。SREチームはサービスの変更管理・緊急時対応・監視・可用性・パフォーマンス・レイテンシ・効率・キャパシティ計画を担当し、通常はプロセス自動化用のソフトウェア開発を行っています。

# GoogleにおけるSREの原則
1, サービスレベル指標（SLI）の設定: システムのパフォーマンスや信頼性を測定するための指標を定義します。

2, サービスレベル目標（SLO）の設定: SLIに基づいて、システムが満たすべき目標を定義します。これはユーザー体験やビジネス目標に関連します。

3, エラーバジェットの設定: SLOと実際のパフォーマンスの間に許容される差を定義し、この差をエラーバジェットと呼びます。エラーバジェットを超えると、システムの安定性に関する新しい変更を停止します。

4, トイルミティゲーションとインシデント対応の自動化: インシデントが発生した場合やエラーバジェットが超過した場合に、自動化された手順を用いて迅速かつ効果的に対応します。

これらの原則に基づき、Googleはシステムの信頼性を向上させると提唱しています。
自動化とシステムの監視はヒューマンエラーを減らし、迅速なインシデント削減を実現します。また、これによってUXの向上やビジネスの安定性も確保されるかと思います。

https://cloud.google.com/sre?hl=ja

# DevOpsとの違い
#### DevOps
DevOpsは、開発チームと運用チームの連携とコラボレーションを重視します。これにより、開発と運用の壁を取り除き、ソフトウェアのリリースサイクルを迅速化し、品質を向上させることを目指します。

DevOpsでは、自動化、継続的な統合（CI）、継続的なデリバリー（CD）などのプラクティスが重要視されます。
DevOpsは、ソフトウェアの開発、テスト、デプロイ、運用などのフルライフサイクルをカバーし、開発と運用の連携を通じてビジネス価値を最大化します。

#### SRE
SREは、システムの信頼性と安定性を確保することに焦点を当てています。これは、サービスの可用性、パフォーマンス、セキュリティなどを最大化し、障害に対する迅速な対応を実現することを目指します。

SREでは、サービスレベル目標（SLO）、エラーバジェット、自動化、トイルミティゲーションなどのプラクティスが重視されます。

SREは、Googleが開発したアプローチであり、開発と運用の間に位置する役割とプロセスを提供します。SREは、運用チームとしての責任を持ちつつも、開発チームとの密接な連携を通じてサービスの信頼性を確保します。

Devopsは開発と運用の効率化を目指すものであり、SREはシステムの信頼性や安定性を重視しているものなのかなと思います。

# mochi所感
IT業界に限らずSREはかなり重要です。ECサイトの顧客に対する趣向に基づいたレコメンデーションや、金融機関のシステム等では可用性が特に求められるため、より高いSLAが必要かと思います。

インフラエンジニアとしてSREのベストプラクティスを頭の片隅に押さえておくだけでも、その人のIT市場価値は上がるのではないかと思いました。


自分の持っているクラウドの導入フレームワークに関する知識と合わせれば、お客様へのハイブリッド環境の導入提案やマルチクラウドの導入アドバイスもできますし、新規サービスをバリデーションしている時、どのようにロールアウトし、デプロイすべきかのベストプラクティスも提唱できると思います。(最初は一部の顧客でテストを実施してから本番にロールアウトする。など)

ITインフラはシステムの土台となっているため、業界問わず多くのニーズが高まっているかと思いますので、この知識は自分の中でも抑えておき、クラウドの導入提案をするときが来たら、パッと出せるようにしておきます！！おわり。
お名前.comでドメインを取得後， Firebaseに接続できなかった話

# Firebaseでの独自ドメイン設定失敗談とその解決法

## はじめに
この記事では，Firebaseで独自ドメインの設定に失敗した体験を共有します．
原因は驚くべきことに，認証メールを見落としていたことでした.

## 目次

1. [ドメイン設定手順](#設定手順)
2. [登録できなかった問題点](#問題点)
3. [解決策](#解決策)
4. [終わりに](#終わりに)

## 設定手順

ドメインの設定には以下のリソースを参照しました.


https://qiita.com/_pipo_/items/2beb71eb3407775a1bf2

https://tedask.jp/tool/firebase-and-onamae-mail-and-onamae-com/

実行手順は以下の通りです：
1. お名前.comからドメインを取得
2. Firebaseでカスタムドメインを設定
3. お名前.comでDNS設定を行う

具体的な手順の詳細は既に多くの文献で説明されているため，ここでは省略します.

## 問題点
設定後，Firebaseのコンソール画面が「設定が必要です」と表示され続けました.通常，24〜72時間以内には設定が反映されるはずですが，私の場合は変化がありませんでした.

<img width="70%"　height="auto" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/1248ac24-d8f9-ad5a-9c80-325560aa3cae.png">

調査を進めると，お名前.comの管理画面でドメインが利用制限中であることが判明しました.
ドメインを購入した後に認証メールが届くのですが，自分の場合はとりあえずドメインを入手し，後日設定を行おうと放置していたため，ドメインが利用できない状況でした．

<img width="70%"　height="auto" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/7e4a5830-491e-2967-36b0-a94269f85446.png">

<img width="70%"　height="auto" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/fe29aff0-f94c-2afe-3c9a-3f2447469e1c.png">

<a id="Chapter3"></a>
## 解決策
過去に取得した際の認証メールを見落としていたため，制限がかかっていたので，認証メールを再送してもらいました．

![スクリーンショット 2024-06-08 17.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/8c40afbf-86d0-b9da-e099-db7090872905.png)
![スクリーンショット 2024-06-08 17.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776719/ee0b3c97-e057-d417-7f65-5ee31deaf01f.png)


https://help.onamae.com/answer/15333


お名前.comから認証メールを再送してもらいましたが，すぐには届かず，翌日にようやく届きました.しかし，認証後もドメインが使用できなかったため，最終的には「〇〇.com」から「〇〇.net」へドメインを変更し，改めて設定し直しました.

<a id="Chapter4"></a>
## 終わりに
今回は解決というよりも問題点を発見し，新しく作り直すことを行いました．

この記事が役立つかは疑問ですが，同じ問題に直面している方の参考になれば幸いです.
Node-RED MCU Edition用のテキスト表示ノードを作ってみた

# はじめに

Node-RED Dashboardで日本語を表示することはできるようになりました。

https://qiita.com/kitazaki/items/a59fad56db2d6ec99ee0

Node-RED DashboardはModdableのPiuモジュールを使用しています。
Piuモジュールを使用せず、CommodettoとPocoというグラフィックライブラリ・レンダリングエンジンを使用してテキストをディスプレイに表示してみます。

# Moddable SDKのサンプルプログラム

Moddable SDKのサンプルプログラムの中に
examples/commodetto/text
と
examples/commodetto/text-ticker
というプログラムがあります。

# Moddable SDKのサンプルプログラムをNode-RED MCU Editionのノードへ移植する

日本語で長い文章にも対応するため、右から左へスクロール表示するtext-tickerの方を移植しました。
サンプルプログラムから移植した際の変更点は以下です。

- 日本語フォントファイルを用意し、日本語表示に対応しました。
- メッセージを動的に変更するため、ループ表示は無効にしました。
- メッセージが短い場合、画面に収まる範囲で繰り返し表示していましたが、無効にしました。

<img src="https://raw.githubusercontent.com/kitazaki/node-red-contrib-mcu-display-text/main/image/palette.jpg"><br>

<img src="https://raw.githubusercontent.com/kitazaki/node-red-contrib-mcu-display-text/main/image/flow.png"><br>

<img src="https://raw.githubusercontent.com/kitazaki/node-red-contrib-mcu-display-text/8a58bded79f206ef32e8802fb8d43de0a9b75be4/image/sample.gif" width="33%">

npmとNode-REDノードライブラリに登録しましたので、ぜひご利用ください！

https://www.npmjs.com/package/@kitazaki/node-red-contrib-mcu-display-text

https://flows.nodered.org/node/@kitazaki/node-red-contrib-mcu-display-text

https://github.com/kitazaki/node-red-contrib-mcu-display-text
ABC357をPythonで（A～E）

サントリープログラミングコンテスト2024（AtCoder Beginner Contest 357）の解答等のまとめ

https://atcoder.jp/contests/abc357

# A問題
https://atcoder.jp/contests/abc357/tasks/abc357_a

先頭から順番に足していく
```python:A
n, m = map(int, input().split())
a = list(map(int, input().split()))

s = 0
for i, a_i in enumerate(a):
    s += a_i
    if s > m:
        print(i)
        exit()

print(n)
```
# B問題
https://atcoder.jp/contests/abc357/tasks/abc357_b

問題文の通りにする
```python:B
s = input()

ups = sum(s_i.isupper() for s_i in s)
if len(s) <= ups * 2:
    print(s.upper())
else:
    print(s.lower())
```
# C問題
https://atcoder.jp/contests/abc357/tasks/abc357_c

再帰関数で書く
```python:C
def dfs(n):
    if n == 0:
        return ["#"]
    else:
        a = dfs(n - 1)
        b = ["." * 3 ** (n - 1) for _ in range(3 ** (n - 1))]
        res = []
        for a_i in a:
            # print(a_i)
            res.append(a_i + a_i + a_i)
        for a_i, b_i, a_j in zip(a, b, a):
            # print(a_i, b_i, a_j)
            res.append(a_i + b_i + a_i)
        for a_i in a:
            res.append(a_i + a_i + a_i)
        return res


ans = dfs(int(input()))
for a_i in ans:
    print(a_i)
```
# D問題
https://atcoder.jp/contests/abc357/tasks/abc357_d

初項$1$公比$10^m$（$m$は$n$の桁数）項数$n$の等比級数の和に$n$をかける

```python:D
n = int(input())
mod = 998244353
m = len(str(n))

a = pow(10, m, mod)
print((pow(a, n, mod) - 1) * pow(a - 1, -1, mod) % mod * n % mod)
```
# E問題
https://atcoder.jp/contests/abc357/tasks/abc357_e

各頂点からの到達可能な頂点の数は
- ループしているところはそのループ内の頂点数
- それ以外は行けるループ内の頂点数＋そこまでの距離

```python:E
import sys

sys.setrecursionlimit(10 ** 7)

n = int(input())
a = list(map(lambda x: int(x) - 1, input().split()))

loop_list = []
memo = [0] * n


def loop(now, turn):
    global memo, loop_list
    memo[now] = turn
    to = a[now]
    if now == to:
        loop_list.append({now})
        return False
    elif memo[to] == 0:
        flag = loop(to, turn)
        if flag:
            if now in loop_list[-1]:
                return False
            else:
                loop_list[-1].add(now)
                return True
        else:
            return False
    elif memo[to] == turn:
        loop_list.append({to, now})
        return True
    else:
        return False


cnt = 1
for i in range(n):
    if memo[i] == 0:
        loop(i, cnt)
        cnt += 1

ans = [0] * n
for l_i in loop_list:
    cnt = len(l_i)
    for i in list(l_i):
        ans[i] = cnt


def dfs(now):
    to = a[now]
    if ans[to] == 0:
        dfs(to)
    ans[now] = ans[to] + 1


for i in range(n):
    if ans[i] == 0:
        dfs(i)

print(sum(ans))
```
primeVueのDataTableに配列がうまく適用できずtsで頑張った話

 TypeScript、 Vue初学者ですが、業務で使用し始めたところです。
 金曜日実装に取りかかった機能で、どうすんだ？これ？と思う部分があったので、方法の検討をしました。

## やりたかったこと


```typescript
const valueList =  [
        { yyyyMM : '202401', valueArray : [100, 200]},
        { yyyyMM : '202402', valueArray : [200, 300]},
        { yyyyMM : '202403', valueArray : [400, 500]},        
    ]
const columnList = [{code :"aa" , name : "aaName"} ,{code :"bb" , name : "bbName"}]
```

この形のobjをPrimeVueのDataTableに適用したい。
valueArrayの要素数は可変とする仕様であるため、形は変えられない。
作りたいのはこんな表。

| yyyyMM | aaName | bbName |
|:-:|:-:|:-:|
| 202401  | 100  | 200  |
| 202402  | 200  | 300  |
| 202403  | 400  | 500  |


## 試したこと

Data Tableを何やらかんやらして出力できないか試す
多分Dynamic Columnsを使わないと無理なのはわかった

https://primevue.org/datatable/#dynamic_columns

頭がこんがらがって何を書けばいいのか迷走しつつ何個か有力そうなものをテスト

### 試したこと１

```typescript
const columnList = [{code :"valueArray[0]" , name : "aaName"} ,{code :"valueArray[1]" , name : "bbName"}]
```

```vue
<DataTable :value="valueList" tableStyle="min-width: 50rem">
    <Column field="yyyyMM" header="yyyyMM"></Column>
    <Column v-for="col of columnList" :key="col.code" :field="col.code" :header="col.name"></Column>
</DataTable>
```
aaName、bbNameに値が表示されなかった　　−→失敗

### 試したこと２

```typescript

const columnList2 = [{code :0 , name : "aaName"} ,{code :1 , name : "bbName"}]
```

```vue

<DataTable :value="valueList" tableStyle="min-width: 50rem">
    <Column field="yyyyMM" header="yyyyMM"></Column>
    <Column v-for="col of columnList2" :key="valueArray[col.code]" :field="valueArray[col.code]" :header="col.name"></Column>
</DataTable>
```

エラー発生　　−→失敗
```
22:23:56 [ERROR] Cannot read properties of undefined (reading '0')
```
ここらで、PrimeVueのDataTableのDynamic Columnsはobj[key]のkeyをColumnで動的に指定させることで実現してるのかもなーと想像し、DataTableの書き方を工夫することを諦める

### 試したこと３

typeScriptで配列をflatなobjectに変換して、それをDataTableに突っ込む作戦に変更。
objのイメージはこんな感じ
```
  { yyyyMM: '202401', aa: 100, bb: 200 },
  { yyyyMM: '202402', aa: 200, bb: 300 },
  { yyyyMM: '202403', aa: 400, bb: 500 }
```

こちらの記事を参考にさせていただきました（感謝）

https://zenn.dev/mimi/scraps/d15e75cb9dc4e3


```typescript
const columnList = [{code :"aa" , name : "aaName"} ,{code :"bb" , name : "bbName"}]
var list = [];    

for(const val of valueList){
    var obj = {}
    type objKey = keyof typeof obj
    obj["yyyyMM"] = val.yyyyMM
    var cnt = 0
    for(const item of val.valueArray){
        const data :objKey = columnList[cnt].code as objKey
        obj[data] = item
        cnt ++
    }
    list.push(obj)
}
```
```vue
<DataTable :value="list" tableStyle="min-width: 50rem">
    <Column field="yyyyMM" header="yyyyMM"></Column>
    <Column v-for="col of columnList" :key="col.code" :field="col.code" :header="col.name"></Column>
</DataTable>
```
成功！

本当にこれが最適解かはわかりませんでしたが、とても勉強になりました。
新しい命を生み出すコマンド、その名はtouch

# はじめに
何かの作業をしているとき、とりあえずファイルを作成したい時がありますね。そんなときに、touchコマンドです。

# touchコマンドとは
touchコマンドは、主にファイルのタイムスタンプを更新するために使用されますが、ファイルが存在しない場合には新しい空のファイルを作成することもできます。

# 何でtouch？
touchコマンドの名称は、新規作成を喜んでエンジニアにはハイタッチする習慣があることに由来している。ということはなく、ファイルの「最終アクセス日時」や「最終更新日時」を変更する（=ファイルに「触れる」）ことに由来しています。

# 使い方の例

新しい空のファイルを作成する
```
touch newfile.txt
```

複数のファイルを一度に作成する
```
touch {file1.txt,file2.txt,file3.txt}
```

既存のディレクトリにファイルを作成する
```
touch /perfume/LEVEL3/未来のミュージアム/newfile.txt
```

# 注意点
ファイルを作成するディレクトリに書き込み権限が必要です。権限がないとエラーが発生します。
touchコマンドは既存のファイルがある場合、そのファイルのタイムスタンプを更新します。既存のファイルの内容が変更されるわけではありませんが、タイムスタンプの変更が必要ない場合は注意が必要です。

# さいごに
touchコマンドはLinuC レベル1　101の試験範囲のコマンドです。
Linuxを使えることでエンジニアとしての付加価値を上げていきましょう。

https://linuc.org/linuc1/range/101.html

https://linuc.org/study/samples/index/101/
terminalをいい感じに色分けする！！！！！

## この記事でできること

terminalを↓な感じで表示できる。ちょっとみやすい。
![スクリーンショット 2024-06-08 21.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266081/f615f73b-5d99-83ef-2294-a37478587293.png)

## やりかた

自由にカスタマイズできるよう、ステップに分けて説明していきます。

### wgetを使用可能にする

まず、今回 `wget` を利用するので、必要な方はインストールします。

```
brew install wget
```

### 諸々のコマンドを実行する

いきなりですが、コピペで動くコマンド群を載せちゃいます。
```
mkdir -p ~/usr/local/git/contrib/completion
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/usr/local/git/contrib/completion/git-prompt.sh
echo source ~/usr/local/git/contrib/completion/git-prompt.sh >> ~/.bashrc
echo GIT_PS1_SHOWDIRTYSTATE=true >> ~/.bashrc
echo export PS1=\'\\[\\e[1\;32m\\]\\u:\\[\\e[1\;36m\\]\\W\\[\\e[1\;33m\\]\$\(__git_ps1\)\\[\\033[00m\\]\$ \' >> ~/.bashrc
source ~/.bashrc  
```

ユーザー名：緑
ディレクトリ名：青
ブランチ名：黄色

で示されるようになりました！

これだけだとまぁ寂しいので、それぞれのコマンドで何をやっているか、解説を挟んでいきますので、よければお読みください :bow:

## 解説


- Gitのスクリプトを保存するためのディレクトリを作成します。
```bash
mkdir -p ~/usr/local/git/contrib/completion
```

- Gitのプロンプト設定スクリプトをダウンロードします。


```bash
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/usr/local/git/contrib/completion/git-prompt.sh
```

- Gitのプロンプト設定を読み込むための設定を.bashrcに追加します
```bash
echo source ~/usr/local/git/contrib/completion/git-prompt.sh >> ~/.bashrc
```

- Gitプロンプトにリポジトリの状態（変更済みファイルの有無）を表示するように設定します
```bash
echo GIT_PS1_SHOWDIRTYSTATE=true >> ~/.bashrc
```

- terminalの色の設定を行います

```bash
echo export PS1=\'\\[\\e[1\;32m\\]\\u:\\[\\e[1\;36m\\]\\W\\[\\e[1\;33m\\]\$\(__git_ps1\)\\[\\033[00m\\]\$ \' >> ~/.bashrc  
```

---

`\\[\\e[1\;32m\\]\\u`: ユーザー名を緑色で表示
`\\[\\e[1\;36m\\]\\W`: 現在のディレクトリをシアン色で表示
`\\[\\e[1\;33m\\]\$\(__git_ps1\)`: Gitリポジトリの状態を黄色で表示  
`\\[\\033[00m\\]\$`: それ以降をデフォルトの色に戻す

---

- 最後にbashrcを再読み込みして、設定を反映する

```bash
source ~/.bashrc
```

## おわりに

上記のように、terminalの表示色を任意に変更することができます!
この情報も入れたい、この色に変更したいなど、ChatGPTさんと聞けば答えてくれると思うので、自分にあった表示を探してみてください！

ありがとうございました。
レターパックのSNS Misskey.io の書き込み専用webクライアントを作った

# サービス公開ページ ( GitHub Pages )
https://ykamenashi.github.io/html-misskeyio-write-client/

# 使い方

画面に書いてある通りです。

# リポジトリ

https://github.com/ykamenashi/html-misskeyio-write-client

# どうして書き込みのみなのか

公式Webクライアントは、多機能すぎるので、出先でちょっと書き込みたい、というシーンには向かないんです。バッテリーもちとか、通信量とか。
とりあえず今の気持ちを、スマホからMisskey.ioに書きたいだけなので、シンプルにしました。

# 困ってること

カスタム絵文字サジェスト/ピッカーの実装はたぶん無理なので、楽にできる方法があったら教えてください。できればやりたい。
【Docker】M1 MacでWordPressを起動するdocker-compose.yml

# はじめに

M1 Mac で WordPress を起動したときの docker-compose.yml になります。

```bash
version: '3.8'

services:
  mysql:
    image: mysql:8.0.26
    platform: linux/amd64
    container_name: mysql
    volumes:
      - mysqlvolume:/var/lib/mysql
      - ~/mysqlbackup:/mysqlbackup
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: password
    command: --default-authentication-plugin=mysql_native_password
    networks:
      - wp-net

  wordpress:
    image: wordpress
    container_name: wordpress
    depends_on:
      - mysql
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    networks:
      - wp-net

volumes:
  mysqlvolume:
  wordpress_data:

networks:
  wp-net:
    driver: bridge
```

# 起動

```bash
docker-compose up -d
```

# 停止

この場合は、投稿した記事が残っています。
その為、`docker-compose up -d`をすると投稿した記事が復元します。

```bash
docker-compose down
```

# 停止＋ボリューム削除

この場合は、投稿した記事も削除されます。

```bash
docker-compose down --volumes
```

# WordPressのバックアップ取得

```bash
docker container exec mysql bash -c "mysqldump -u root -p'password' -A > mysqlbackup/20240606.sql"
```

以上です。
【Rails】バリデーションエラーが表示されない場合の解決方法

## 概要
Railsで後述するバージョンで「バリデーションエラーメッセージ」が表示されなかったので、解決法とその理由を解説します。


### バージョン
Ruby：3.1.4p223
Rails ：7.0.8.1


### コード
```ruby:Ruby
status: :unprocessable_entity
```
**記述する箇所：** 
![screenshot_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711935/395a0180-5353-da37-ff54-af7e963969c9.png)

<br>


### status: :unprocessable_entity の役割

ステータスコード422へレンダリングさせるためで`バリデーションエラーの際に返す`コードです。
※ステータスコードとはHTTPレスポンス時の処理結果を3桁の番号で表現すること。

<br>

**コードを書かなかった場合：** 
Railsはデフォルトでリクエスト成功を返すので、バリデーションエラーがあっても、HTTPレスポンスでは何の問題も無かったと判断されます。


**コードを書いた場合：** 
`status: :unprocessable_entity`を指定した場合、ステータスコード422を返します。
要するにバリデーションエラーメッセージをユーザーに表示させます。


<br>


ステータスコード422の説明【mdn】
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/422


Railsガイド
https://railsguides.jp/v7.0/layouts_and_rendering.html
【小ネタ】HTMLのみでサイト内検索を実現する

## 備忘録
Googleのサイト内検索機能が手軽に実装できる

## 検索フォーム設置用のHTMLコード
```.html
<form action="https://www.google.com/search" class="search-form" method="get" target="_blank">
    <input type="hidden" name="hl" value="ja">
    <input type="hidden" name="sitesearch" value="https://qiita.com/">
    <input type="text" name="q" size="30" maxLength="255">
    <button type="submit">検索</button>
</form>
```

## コード補足
#### formタグ内
- `target="_blank"` -> 別タブで検索結果を表示

#### inputタグ内
| パラメータ名  | 内容         | 
|:-----------:|:------------|
| q           | 検索キーワード|
| hl          | 言語指定<br>※日本語なら「ja」|
| sitesearch  | 検索対象サイト|

## 見た目を整える用のCSSコード

<details><summary>CSSファイルはこちら</summary>

```.css
.search-form {
  display: flex;
  align-items: center;
  gap: 0 10px;
  width: 400px;
}

.search-form input {
    width: 100%;
    height: 34px;
    padding: 1px 5px 1px 8px;
    border: 1px solid #999999;
    box-sizing: border-box;
    color: #000;
    outline: none;
}

.search-form button {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 30%;
    max-width: 140px;
    height: 34px;
    border: none;
    background-color: #4070ff;
    color: #fff;
    cursor: pointer;
}

.search-form button::before {
    width: 14px;
    height: 14px;
    margin-right: 5px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z' fill='%23fff'%3E%3C/path%3E%3C/svg%3E");
    background-repeat: no-repeat;
    content: '';
}
```
</details>

## 出来上がりの結果

### 検索フォーム

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180677/bb9a8a49-76e4-3ebc-ac34-ce88231e8257.png">

### Qiitaを対象にサイト内検索してみる

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180677/d1b4b6f8-6a87-ed5f-cf27-e8877ff71da6.png">


## 参考記事
- [検索フォームのデザイン参考：CSS Stock](https://pote-chil.com/css-stock/ja/search-form)
【AWS】AWS Certified Data Engineer - Associate(DEA)に合格したので感想戦【認定対策】

## はじめに
AWSの認定資格は2024年6月8日現在、有効なものが10種類あります
その中で今年新しく追加されたAWS Certified Data Engineer - Associate(DEA)の認定に合格したのでその振り返り記事を投稿します。
どんな問題が出たかをここで書くことができませんが、どういう観点で対策すべきかを記載しますので今後の学習の参考にしていただけると幸いです。

https://aws.amazon.com/jp/certification/

試験結果
![試験結果.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/bb6abc7f-26ea-725c-c5ac-b8106ef86840.png)

## どんな試験か
どんな試験かについては公式の試験ガイドに記載があります

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-data-engineer-associate/AWS-Certified-Data-Engineer-Associate_Exam-Guide.pdf

受けてみた印象では、以下の内容に関する知識が問われていました。
### 1．データアクセスのセキュリティ
・ストレージやDBに保存されたデータに対してユーザ(アカウントやアクセス元が異なる)ごとのアクセスできる範囲を分けるにはどうするか？

### 2．データアクセスのコスト管理
・ストレージやDBに保存されたデータに対して1回限りのデータアクセスする場合、同じデータに繰り返しアクセスする場合、不規則にデータアクセスする場合でアクセスの方法はどのように変わるか
・データを処理するAWSシステムを作る時にそのデータ量やデータの種類(ストリーミングデータ、CSV、JSONなど)に応じてどのAWSサービス(もしくはその組み合わせ)を選択するか、それが無駄のない作りにできているか

### 3．データをストレージやDBに保存するときにどのような処理が行われるか
・オンプレミスにあるデータをAWSに持ってくるときにどのようなAWSサービスを使うか、DBやS3にデータ保持する前にどのような前処理が必要かユースケースごとの知識が問われました

### 4．データ処理コマンドやSQLの知識
・データアクセスするときによくつかわれるSQLやデータベースアクセスするときに余計なデータを排除したり整合性を担保したいときなどのユースケースで使われるコマンドのオプションに関する知識もあると良いです

## 試験難易度
あくまでも個人的な感想ですが、アソシエイト試験の中では1番簡単に感じました。
簡単に感じる要因としては範囲の狭さがあります。データ分析の一連の流れは「データの取得」「データの保持」「データの分析」「データの可視化」だと考えていますが、これにかかわる代表的なAWSサービスはかなり限られています。
要するにこれらのサービスの特徴と似たサービスの違い、よくあるユースケースを学べば合格ラインに達します。
とはいえ試験範囲の学習の準備なしに合格できるかときかれると難しいと思います。旧DASよりは簡単だけど基本が抑えられていないと合格できないかなり絶妙なラインで作られている、アソシエイトレベルを測るという見方ではかなり完成度が高い試験に思いました。

## データ分析にかかかわるAWSサービスの整理
私なりに考えるデータ分析の各ステップのAWSサービスの分類をしておきます.
人によっては分類が異なるものもあると思いますが、あくまでも1つの考え方として知識の整理のための参考にしていただけると良いかなと思います。
一番は自分の中の基準で分類できれば応用含めてしっかり理解できると思います
※この記事に書いた内容が全てではないので、試験ガイドにあるキーワードがどの分類にまとめられるか、新たな項目の分類になるかを整理出来たらなお良いです

### 「データの取得」
・オンプレからデータを取得したい
　→DataSync
・ストリーミングデータを取得したい
 　→KinesisDataStream、KinesisFirehose

### 「データの保持」
・非構造化データを保持したい
　→S3
・ストリーミングデータを保持したい
　→DynamoDB
・データ分析用のデータを大量に保持したい
　→Redshift
・EC2でできるデータを保持したい
　→EBS
・データに対して細かいアクセス制限を設けたい
　→LakeFormation
・いろんなところで管理されているデータを一括管理したい
　→DataCatalog

### 「データの分析」
#### ＞ めちゃめちゃ大量のデータを処理する
・速く処理したい
　→EMR
・ゆっくりでもOK
　→Glue
#### ＞ ステップに分けて分析したい
・いろんなAWSサービスで役割分担して分析したい
　→StepFunctions
・ELT(Extract(抽出)、Load(書き出し)、Transform(変換))をするが他サービスは基本的に不要
　→Glueワークフロー
#### ＞ ストリーミング
・ストリーミングデータをリアルタイム分析したい
　→Amazon Managed Service for Apache Flink(旧：Amazon Kinesis Data Analytics)
 
#### ＞ 分析の頻度
・とりあえず1回内容を確認してみたいだけ
　→Athena
・データができた時点でそれをきっかけにして分析を開始する
 　→Lambda
・定期的に分析する
　→EventBridge、Glue

### 「データの可視化」
・リアルタイムで可視化したい
　→Grafana
・定期的にデータ更新して可視化したい
　→QuickSight


## さいごに
AWSの認定は去年から3つほどなくなりましたが、時代に合わせた内容の認定も出てきてそれを学習する動機ができてとても良いですね。
あと、試験の内容をどこまで話してはいけないのかわかりませんが、私が前回受けた去年の2月から試験のUIが少し変わっていました。なんというか、目にやさしい設定に変更できる感じです。結構ハッピー。
あと、今年のAWS SummitでDEA取得者にはクッキーが配られるとか。ちょっぴりハッピー。
でも去年のSummitでは全冠達成記念Tシャツもらおうと思って基調講演終わってダッシュでもらいに行ったらすでに在庫なしになっていたし、認定ステッカーの一部も在庫切れになってたからきっと今年も基調講演聞いている間に在庫切れになっちゃうんだろうなぁ；

https://aws.amazon.com/jp/summits/japan/expo/#tc
the version of "Julia" shipped by unix package managers

ダウンロードページにある，以下の一文の意味は？

Please do not use the version of "Julia" shipped by unix package managers
Many unix package managers ship broken and/or significantly out of date versions of Julia. Please use juliaup or download the official binaries instead.

ChatGPT はこういいました

そのメッセージは、wingetやhomebrewなどのUNIXパッケージマネージャーで「Julia」をインストールしないようにという意味です。これらのパッケージマネージャーからインストールされる「Julia」は壊れていたり、古かったりする可能性があるため、代わりにjuliaupを使用するか、公式サイトからバイナリを直接ダウンロードするよう推奨しています。
NAT設定

## はじめに

CentOS9でNATサーバーを構築した時の手順

## 環境

- CentOS Stream release 9

## 構成

![nat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692186/214c1c83-4afc-aa90-2606-16116a6bbd73.png)



## 設定

```shell
$ sudo nmcli connection modify enp0s3 connection.zone external
$ sudo nmcli connection modify enp0s8 connection.zone trusted
```
ラズパイをMacと接続

 ## ラズパイをMacと接続

自分用の備忘録として書く。
有線接続が面倒なので、Macにsshで接続できるようにする。

## 必要なもの

- Raspberry Pi 3 B+
- microSDカード
- Mac

## 手順

SDカードにOSを書き込む

[Raspberry Pi Imager](https://www.raspberrypi.com/software/)をMacへインストールする。

設定時のオプションでSSHの設定を登録

これで/boot直下にsshファイルやwpa_supplicant.confを作成することが不要

OSの書き込み後、microSDカードをラズパイに挿入し、電源を入れる。

起動にかかる1分ほどの時間を待ち、以下のコマンドをMacのterminalで実行

```bash
ssh pi@raspberrypi.local
```

以前に接続したことがある場合以下のようなエラーが出た。

```bash
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
...
Host key for raspberrypi.local has changed and you have requested strict checking.
Host key verification failed.
```

Macの`known_hosts`ファイルから古いエントリを削除し、新しいホストキーを受け入れる必要があるみたい。

```bash
ssh-keygen -R raspberrypi.local
```

`ssh/known_hosts`ファイルから`raspberrypi.local`に対応するエントリを削除。

これで接続が可能になった。

VNC接続し、Macからリモートデスクトップ操作するために

raspberry piに接続し、tightvncserverのインストールし起動する

```bash
sudo apt-get install tightvncserver
sudo tightvncsetver
```

macのFinder→移動→サーバーへ接続より、vnc接続でラズパイに繋ぐ

なお、ラズパイのipアドレスは以下で確認しておく
```bash
arp -a
```

## 参考
https://qiita.com/murs313/items/81757bf8bc74b6b76cdf
vscodeのターミナルでvimキーバーインドを使いたい!


# はじめに
vscodeのターミナルで文字を消す際にdelキーを使ったり、カーソル移動に矢印キーを使っていませんか？
そんなことをしていてはカーソル操作だけで一日が終わってしまうため、vimキーバインドを使って効率的に作業しましょう！


# 要約
vscodeのターミナルでvimキーバインドを使う方法を紹介します。
.zshrcに一行加えるとvscのターミナルでキーバインドが効きます。
```.bashrc
# .zshrc に追加
bindkey -v
```

# 前提
vscのターミナルのshellがzshを使っている想定です。
zshではない場合は 「⌘ + shift + p」から `select default profile` を選択すると変更できます。

# 詳細

## 1. zshの bindkey -v でvimキーバインドを使う
zshにはbindkeyというキーバインドを割り当てる関数が存在します。
デフォルトではEmacsのキーバインドが割り当てられているため、vimのキーバインドを使いたい場合は以下のコマンドを.zshrcに追加すればok。

```bash
# .zshrc に追加
bindkey -v
```

これで 「esc」からvimのキーバインドが使えるようになります。もう矢印キーを使う必要はありません。

## 2. Emacsキーバインドとは
Emacsはテキストエディタの一つで、かつてはviとのエディタ戦争があったほど有名でした。
[Emacs用のキーバインド](https://www.aise.ics.saitama-u.ac.jp/~gotoh/EmacsKeybind.html)もあるので好みで選んでください
![alt text](https://i.gzn.jp/img/2021/07/23/the-era-of-visual-studio-code/2020-09-20-text-editor-popularity.png)
> 画像引用元: [GIGAZINE](https://gigazine.net/news/20210723-the-era-of-visual-studio-code/)
# まとめ
vscodeのターミナルでvimキーバインドを使う方法を紹介しました。
エディタはvscodeを使っていても、vimのキーバインドを併用することで効率的に作業ができます。
是非、試してみてください！

# 参考文献

- [Use vim keybindings in visual studio code terminal]([URL](https://stackoverflow.com/questions/68807956/use-vim-keybindings-in-visual-studio-code-terminal))
UnityでInputField(TMP)を使う

# 概要
InputField(TMP)はunityで文字入力を受け付けるためのオブジェクトです。
今回は画面に入力欄を表示し、入力した内容をデバッグログに表示します。
## 使い方
### 入力欄を表示
画面左のHierarchyタブで右クリックしてUI > InputField - TextMeshProでInputField(TMP)を生成します。
Canvasオブジェクトの下に生成されることに注意してください。
### 空のオブジェクトを生成
画面左のHierarchyタブで右クリックしてCreate EmptyでGameObjectを生成します。
### スクリプトを生成
画面下のProjectタブで右クリックしてCreate > C# ScriptsでNewBehaviourScriptを生成します。
NewBehaviourScriptをダブルクリックしてエディターを開き、以下のスクリプトをコピペします。
```c#:NewBehaviourScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class NewBehaviourScript : MonoBehaviour
{
    public TMP_InputField tmp_inputField;
    private string InputText;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    public void hogehoge()
    {
        InputText = tmp_inputField.text;
        Debug.Log(InputText);
    }
}
```
### オブジェクトを関連付け
画面左のHierarchyタブのGameObjectを左クリックし、画面右のInspectorタブのNewBehaviourScriptのtmp_inputFieldに画面左のHierarchyタブからInputField(TMP)をドラッグ＆ドロップします。
次に、画面左のHierarchyタブのInputField(TMP)を左クリックし、画面右のInspectorタブのTextMeshPro - InputFieldのOnEndEdit(String)の+ボタンを押し、出てきた部分に画面左のHierarchyタブからGameObjectをドラッグ＆ドロップします。
次に、いまドロップした所の右上にある、No Functionを左クリックし、NewBehaviourScript > hogehoge()で関連付けを行います。
### 完了
以上で完了です。画面上部中央にあるPlayボタンを押してゲームを開始し、入力欄を左クリックして文字を入力し、エンターを押せば画面左下のデバッグログに入力した文字が表示されます。日本語には対応していないので注意してください。
UbuntuでDJコントローラーを使う

# 前提条件
- OS Ubuntu 22.04 LTS
- DJコントローラー　DDJ-FLX4
- DJコントローラーはUSB接続

# Transitions DJ インストール

- Ubuntu　Softwareを起動
- Music and Audioを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/60dfbfc6-df9b-f1a5-67eb-06558d0b5892.png)


- Transitions DJを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/ad3076e9-fa06-e14e-f510-bd9e63ee0724.png)

- 緑のインストールをクリック
※インストール後のキャプチャの為赤のゴミ箱が表示してますが、インストール前は緑のインストールボタンです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/c0da1ce0-e2f4-ca0c-0b84-94b0bd1ef562.png)

# DJコントローラーをMIDIとして使える為の事前準備

コマンドラインからインストール
```sh
snap connect transitionsdj:alsa
```

# Transitions DJを起動してDJコントローラーの設定
-　メニューのEdit→Settinsをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/e3d10b6f-f21e-a4af-7dd7-38b990f5aa1c.png)

- MIDIタブをクリック
- DeviceをDDJ-FLX4 MIDIを選択
- MappingをPioneer DDJ-FLX4を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/16cf6973-be1f-c3f1-62c6-6bfdb52140c5.png)

# スピーカーの出力先を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/c510ea73-9edb-388f-d6aa-0dd98e5ae6ae.png)

- Audioタブをクリック
- Master Outputを鳴らしたいデバイスを選択

設定は以上です

# 動作したボタン、つまみ
先に結論 FX系は全滅

- 再生
- CUE
- ロータリーセレクター
- LODAボタン
- テンポスライダー
- ジョグ
- EQ（HI, MID, LOW）ノブ
- CFXノブ
- チャンネルフェーダー
- クロスフェーダー
は動作してた（細かくは未検証）

動作イメージ
レベルゲージは動く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/af7bf3d3-e12b-c1c9-f934-dafdbdc355b1.png)

<iframe width="560" height="315" src="https://www.youtube.com/embed/gfHBxwj4uQc?si=QheFZitQACfDTPKu" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
文系SEがExcelでスピンボタンを導入して遊んでみた

# エクセルの開発タブからスピンボタンを実装してみた

エクセルを日々使用する方は多いと思います。
今回は開発タブのスピンボタンを触ってみた備忘録です。
スピンボタンは上下のボタンがセットになっていてクリックすることでセルと連動させることが出来ます。

![excel_spintab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/c645680f-bac3-690b-8375-6e7353f14dea.gif)

今回はスピンボタンの実装とセルとの連動を残します。

# 準備
:::note warn
私の使用するエクセルは**Office2021**の買い切り版です。
使用されるエクセルのバージョンによってUIが異なる場合があります。
:::
まず、エクセルを開いた後、画面上部タブに開発タブがあるか確認してください。

:::note info
既に開発タブが表示されている方は **「準備」** のセクションはスキップでOKです
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/8b5ec67a-09ef-6c44-9759-80f14c2c83fa.png)

表示されていない方は下記手順で表示させます。

1) タブ上のファイルを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/84d07c90-660a-38f4-a856-b5b3b2fe7718.png)

2)「その他」=>「オプション」を押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/dd9ae873-61c3-6d9e-a700-73eb012e83ee.png)

3) 「リボンのユーザー設定」=> 「開発」にチェックを入れて「OK」を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/ab4a7bde-f5bd-1199-754a-07c6f74d3ad2.png)

4)シートの画面に戻るとリボンのタブに「開発」が表示されます。

# 実装

冒頭のGifで紹介しましたが、スピンボタンを実装していきます。

:::note info
今回はE3,F3のセルに適当な数字を入れて、それらを掛け算した結果をG3列に連動させます。
:::

1) 「開発」タブを押下し、「挿入」を選択し、「スピンボタン」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/e22f1fc3-fd9b-c28d-2c4a-06887a724d78.png)
マウスポインターが[+]になるため、セルの任意の場所をクリックすると、クリックした場所に作成されます。

:::note info
**memo**
スピンボタンを選択する際は右クリックで選択ができます。
:::

:::note warn
**Point!**
通常挿入する際にクリックすると適当な大きさでセル上スピンボタンが生成されますが、指定したセルにの中に綺麗に生成したい時は、Altキーを押しながらセルの隅まで引っ張るとセル内部に綺麗に生成されます。
![excel_spintab2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/704e6eb6-b08d-0618-8c91-a0b04c134285.gif)

:::

# 実装-セル連携-
次にセルの連携をします。

1) 生成したスピンボタンを右クリックします。
2) 「コントロールの書式設定」を押下します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/e33ce3cb-f0f8-e5de-58b6-c7944757329f.png)

3)コントロールタブの「リンクするセル」にクリックした際に反映させたいセルを選択し「OK」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/2c7f8105-fbc1-1d5e-7bd7-38469e3cfd8a.png)

:::note info
最小値や最大値、増分の値を触ることで、設定を自由に変えられます。
例．増分を100にした場合、1クリックで値が100増えていきます。
:::

以上で作業終了です。お疲れ様でした。
相互作用表示について

量子力学で用いられる相互作用表示についてまとめます。
# 相互作用表示
今、次のような形でハミルトニアンが与えられているとします。

```math 
\hat{H}=\hat{H}_0+\hat{H}_{int}
```

$\hat{H}$ は陽に時間依存していないことに注意してください。ここで、相互作用表示における状態と演算子を、シュレーディンガー表示である$|\psi(t)>$、$\hat{A}$ を用いて次のように定義します。

```math 
|\psi^{I}(t)>:=e^{\frac{i}{h}\hat{H}_{0}t}|\psi(t)>
```

```math 
\hat{A}^{I}(t):=e^{\frac{i}{h}\hat{H}_{0}t}\hat{A}e^{-\frac{i}{h}\hat{H}_{0}t}
```

ここで、 $|\psi^{I}(t)>$ の時間発展を計算してみます。

```math 
\frac{d}{dt}|\psi^{I}(t)>=\frac{i}{h}\hat{H}_{0}e^{\frac{i}{h}\hat{H}_{0}t}|\psi(t)>+e^{\frac{i}{h}\hat{H}_{0}t}\frac{d}{dt}|\psi(t)>
```

$|\psi(t)>$ はシュレーディンガー方程式を満たすので、

```math 
i\hbar\frac{d}{dt}|\psi(t)>=\hat{H}|\psi(t)>
```

より、

```math 
\begin{align*}
\frac{d}{dt}|\psi^{I}(t)> &= \frac{i}{h}(\hat{H}_{0}e^{\frac{i}{h}\hat{H}_{0}t}-e^{\frac{i}{h}\hat{H}_{0}t}\hat{H})|\psi(t)> \\
&= \frac{i}{h}e^{\frac{i}{h}\hat{H}_{0}t}(\hat{H_0}-\hat{H})|\psi(t)> \\
&= -\frac{i}{h}e^{\frac{i}{h}\hat{H}_{0}t}\hat{H}_{int}|\psi(t)> \\
\end{align*}
```

相互作用表示における状態の定義を変形して、

```math 
|\psi(t)>=e^{-\frac{i}{h}\hat{H}_{0}t}|\psi^{I}(t)>
```

なので、これを代入すると、

```math 
\begin{align*}
\frac{d}{dt}|\psi^{I}(t)> &= -\frac{i}{h}e^{\frac{i}{h}\hat{H}_{0}t}\hat{H}_{int}e^{-\frac{i}{h}\hat{H}_{0}t}|\psi^{I}(t)> \\
&= -\frac{i}{h}\hat{H}_{int}^{I}(t)|\psi^{I}(t)>
\end{align*}
```

となります。整理すると、

```math 
\begin{align*}
i\hbar\frac{d}{dt}|\psi^{I}(t)> = \hat{H}_{int}^{I}(t)|\psi^{I}(t)>
\end{align*}
```

つまり定義した$|\psi^{I}(t)>$ は、　$\hat{H}_{int}^{I}(t)$ のみが関与するシュレーディンガー方程式の解であることが分かります。この方程式は、「**朝永-シュウィンガー方程式**」と呼ばれます。
【Rails】Sorcery使用によるGoogle認証の注意点

## はじめに
この記事では、Gem「```sorcery```」を使用したGoogle認証に関する注意点をまとめました。具体的な実装方法の解説は行わず、確認すべき重要なポイントについて触れています。

Google認証を導入するなら「```devise```」の方が一般的でおすすめですが、既に「```sorcery```」を用いてログイン機能を実装している方のために書いています。私自身、sorceryでGoogle認証を実装する際に情報が少なく苦戦したため、同様に苦戦している方々の助けになれば幸いです。


## 環境
- ruby 3.2.3
- rails 7.1.3
- Docker

前提条件としてsoceryによるログイン機能に加えて、Google認証導入までも一通りできている(エラー・不具合込み)とします。

## 確認すべきこと・詰まるポイント
sorceryを使用してGoogle認証を導入する際の確認事項と詰まりやすいポイントについて解説します。

### 承認済みリダイレクトURI
まず、Google Cloudコンソールに登録した承認済みリダイレクトURIと、Railsの設定ファイルである```config/settings/development.yml```に記述したURIが一致しているかを確認します。

![スクリーンショット 2024-06-08 20.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772961/bf80b588-0ec4-9ee9-9318-2d6df792fbae.png)


```config>settings>development.yml```に記述します。

```development.yml
sorcery:
  google_callback_url: 'http://localhost:3000/oauth/callback?provider=google'
```
これがなってないとエラーが発生したり、認証に失敗します。

私の場合、```http://localhost:3000/oauth/callback```の記述でやったらエラーが発生して、試行錯誤して上記のように記述したところ解消しました。

また本番環境向けにも承認済みリダイレクトURIを用意して、
```config>settings>production.yml```に記述します。

```production.yml
sorcery:
  google_callback_url: '{本番環境のURL貼り付ける}/oauth/callback?provider=google'
```

上記の```{本番環境のURL貼り付ける}```には、デプロイ先のURLを貼り付けてください。上記のままだと、失敗します。

念の為記載しておりますが、RSpecテストを行うという方は下記の記事にも目を通した方が良いかも知れません。URIの記述をローカルと本番用で分けないとエラーが発生するようです。RSpecテストはしないという方は不要です。

https://qiita.com/rei-dev99/items/21b41568ad0cda466203

### soceryで実装したカラムの確認
userモデルにあるカラムは```username```もしくは```name```、その他か確認します。
これが異なっていると認証に失敗します。
確認したら```socery.rb```を修正します。
```socery.rb
config.google.user_info_mapping = { email: "email", name: "name" }
```

私の場合、```user```のカラムが```name```だったので、下記のように```username```としたところ失敗しました。
```socery.rb
config.google.user_info_mapping = { email: "email", :username => "name" }
```

なので、```email```と```name```カラムが自分のと合っているか確認が必要です。

そして、```crypted_password```と```salt```の制約が必須になってないか確認します。
googleAPIではそれらが任意となっているため、ここが必須になってしまっていると認証に失敗します。

私の場合
```schema.rb
create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.string "email", null: false
    t.string "crypted_password", null: false
    t.string "salt", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
end
```
```crypted_password```と```salt```を必須の設定にしていたため認証に失敗していました。
なので、変更のマイグレーションファイルを追加して、任意としました。

```rails g migration ChangeUsersCryptedPasswordAndSalt```

追加されたファイルを
```
class ChangeUsersCryptedPasswordAndSalt < ActiveRecord::Migration[7.1]
  def change
    change_column_null :users, :crypted_password, true
    change_column_null :users, :salt, true
  end
end

```
として、```rails db:migrate```して完了です。

これで解消できるかと思われます。

## 参考記事
こちらの記事を見れば一通り実装できます。

https://qiita.com/okada84108983/items/0c84c01b88072c004873

Google API設定

https://zenn.dev/yoiyoicho/articles/c44a80e4bb4515#google-api%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E8%A1%8C%E3%81%86

## おわりに
この記事が、sorceryを使ってGoogle認証を導入しようとしている方々の助けになれば幸いです。もし、この記事の内容に不備や改善点などがありましたら、ご指摘いただけると嬉しいです。

それでは、開発頑張ってください！
RubyでQwen2クイックスタート(pycall.rbを使用)

# はじめに
LLMを使ったプログラムを書いてみようと思って、手始めに[Qwen2のクイックスタート](https://qwen.readthedocs.io/en/latest/getting_started/quickstart.html)をRubyでやってみました。pycall.rbを経由してHuggingface Transformersを使う手法なので他のモデルでも使用可能かと思います。

# 前提
- RTX 3060
- Ubuntu 20.04 LTS
- Ruby 3.3.2
- Python 3.8.10

# 実装
Quickstartのサンプルコードほぼそのままです。

```ruby:quickstart.rb
require 'pycall'
device = 'cuda'
path = "/path/to/models/Qwen_Qwen2-7B-Instruct"

quantization_config =
  PyCall.import_module('transformers').BitsAndBytesConfig.new(
    load_in_4bit: true,
    bnb_4bit_use_double_quant: true,
    bnb_4bit_quant_type: 'nf4',
    bnb_4bit_compute_dtype: PyCall.import_module('torch').bfloat16
  )
model =
  PyCall.import_module('transformers').AutoModelForCausalLM.from_pretrained(
    path,
    device_map: 'auto',
    quantization_config:
  )
tokenizer = PyCall.import_module("transformers").AutoTokenizer.from_pretrained(path)

prompt = "Give me a short introduction to large language model. The answer must be in Japanese."

messages = [
  { role: "system", content: "You are a helpful assistant." },
  { role: "user", content: prompt },
]

text = tokenizer.apply_chat_template(messages, tokenize: false, add_generation_prompt: true)
model_inputs = tokenizer.call([text], return_tensors: 'pt').to(device: )
generated_ids = model.generate(model_inputs.input_ids, max_new_tokens: 4096)

input = tokenizer.batch_decode(model_inputs.input_ids, skip_special_tokens: true).first
response = tokenizer.batch_decode(generated_ids, skip_special_tokens: true).first

puts response.sub(input, '')
```

今回使用するgemはpycallのみ。
```ruby:Gemfile
source "https://rubygems.org"

gem "pycall", "~> 1.5"
```

Python側の依存関係はこの4つ。
```text:requirements.txt
transformers
bitsandbytes
torch
accelerate
```

# 実行
```bash
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ bundle
(venv) $ pip install -r requirements.txt 
(venv) $ bundle exec ruby quickstart.rb 
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 4/4 [00:08<00:00,  2.21s/it]
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
大規模言語モデルとは、大量のデータを使用して学習したコンピューターシステムで、テキストを生成したり、質問に答えたりする能力があります。これらのモデルは、人工知能の一部として利用され、広範な分野で使用されています。例えば、翻訳、エイリアスの生成、テキストの完結、会話の理解などです。

```
API設計時に役立つAPIリファレンス一覧

## この記事について
GolangでAPIを開発している際に参考にしたAPI referenceを自分のメモがてら書いていきます。

# google APIs
googleのドキュメントでは画面右側から API exploreを使用して簡単にAPIを叩くことができるので実際のデータが見やすかったです。また、UIも一番リッチだと思いました。

https://developers.google.com/apis-explorer

https://developers.google.com/youtube/v3/docs

# zoom
UIが見やすかったです。

https://developers.zoom.us/docs/api/

## facebook
各APIにSDKを使用する際のサンプルコードが載っており親切だなあと感じました。

https://developers.facebook.com/docs/graph-api/reference

## slack
slackもtesterがついていて確認しやすかったです。
今回紹介している中だと唯一パスをドットで繋いでいました。`https://slack.com/api/admin.users.list`

https://api.slack.com/methods

## openai
あまり参考にはしていなかったですが最近特にお世話になっているので載せます。
スクロールをしているだけでパスが勝手に変わっていくのが便利だと思いました。

https://platform.openai.com/docs/api-reference/introduction
PHP CGI 引数インジェクションの脆弱性 / CVE-2024-4577

こんにちは
PHPの脆弱性のニュースがでていたのでメモっときます。



## 内容
PHP に影響を与える新たな重大なセキュリティ上の欠陥についての詳細が明らかになりました。この欠陥を悪用すると、特定の状況下でリモート コード実行が発生する可能性があります。


## 特定の状況下、とは？


防御側にとって、このバグは特定のロケールの Windows ベースの PHP インストール (PHP が CGI モードで具体的に使用されている) でのみ悪用されています。

Windows 版 XAMPP　のサーバーで起きる問題で、さらに特定のロケールは

- 日本語 🔥
- 中国語

※他のロケールも未確認なだけで可能性あり

ということです。

## パッチ
PHP の新しいバージョン8.3.8、8.2.20、8.1.29 がリリースされました。

### 1. PHP をアップグレードできないユーザーの場合:

```
RewriteEngine On
RewriteCond %{QUERY_STRING} ^%ad [NC]
RewriteRule .? - [F,L]
```

### 2. Windows版XAMPPを使用するユーザーの場合:

```
C:/xampp/apache/conf/extra/httpd-xampp.conf
```

対応する行を見つける:

```
ScriptAlias /php-cgi/ "C:/xampp/php/"
```

そしてコメントアウトします:

```
# ScriptAlias /php-cgi/ "C:/xampp/php/"
```


詳細はこちらに書きました。

https://note.com/mz700/n/n42d3c1126584
【勉強会資料】大規模言語モデル入門 第1章 はじめに


[大規模言語モデル入門](https://amzn.asia/d/16Wzurj ) の輪読会を開催したので、発表に使った資料を一部修正して公開します。

# 自然言語処理とは？
> 人間が日常的に使っている言語をコンピュータによって扱う方法について研究する学問です。

以前までは各自がデータを用意して独自のモデルを作成したが、ここ数年で訓練済みの学習モデルを使って方法が標準的になってきている。さらにここ数年で、個人単位では外部から学習済みモデルを利用しつつ、企業単位では企業ごとに言語モデルを開発戦争のような状態が広がっているようにみられる。

# Transformersとは？
Hugging Faceの学習済みモデルを利用するためのPythonライブラリ。

細かい話だが、
**Transformers**はPythonライブラリのことを指しており、
**Transformer**はモデルのアーキテクチャのことなので表現に注意。

この本ではtransformersライブラリを使って色々なタスクのサンプルを紹介している。

↓Transformers

https://huggingface.co/docs/transformers/index

↓Transformer

https://blogs.nvidia.co.jp/2022/04/13/what-is-a-transformer-model/

# transformersで何ができる？
transformersを使うとHugging Faceから学習済みモデルを引っ張ってくることで、下記のようなタスクが数行のコードで実行できる。
* 文書分類：ポジティブ・ネガティブのどちらかに文章を分類する。
* 自然言語推論：２つのテキスト間の論理関係を予測する。
* 意味的類似度計算：２つのテキスト間の意味合いの近さをスコア化する。
* 固有表現認識：テキストに含まれる固有んも表現（人名や国名など）を抽出する。
* 要約生成：長い文章を短い文章にまとめる。

# transformersの使い方
実際の使い方やコードについては、公式のレポジトリにまとまっているため、ここでは割愛します。

https://github.com/ghmagazine/llm-book

この時点での初歩的なポイントをまとめると下記のようになる。
* pipelineを使うと、Hugging Faceでモデルごとにタグ付けされたタスクについて簡単に実行できる。
* Auto Classesというクラス群を使うと、タスクに合わせた適切な実装を自動的に選択してくれる。
* AutoModelやAutoTokenizerにはfrom_pretrainedというメソッドが用意されており、モデルの保存されているフォルダを渡せばタスクが実行できる。

# 単語埋め込み(Word Embedding)とは
一般的には文章や単語（コーパス）をベクトルで表現したもののことを言う。
雑に言うと、単語の意味を数値の羅列にできると解釈できる。

歴史的にはword2vecという手法が2013年に生まれ、NNの性能が大きく改善された。
昨今では、大規模な言語のデータセットに対し、自己教師あり学習による事前学習を行なったモデルを、転移学習によって課題に応じたタスクに適用する方法は大規模言語モデルによる自然言語処理の基本となっている。

# 大規模言語モデルとは？
ここでタイトル回収。
自然言語に対して大規模なコーパスから事前学習した大規模なニューラルネットワークのこと。

大規模言語モデルの具体的なモデルは下記のようなものがある。
* BERT
* GPT
* XLNet
* RoBERTa

# 参考文献
- [大規模言語モデル入門](https://amzn.asia/d/3xTMT8o)
RailsアプリActiveRecordのスロークエリを改善した話

# 背景
私は普段Railsアプリケーションを運用保守しています。
ある日、アプケーションで使用しているAWS RDSのCPU使用率が100%張り付きになってしまう問題が発生しました。
今回はその問題を解決するまでの道筋を記載していけたらと思います。

# 解決までの流れ
解決までの流れはざっくり書くと以下です。
1. AWS RDSのCPU使用率メトリクスを確認し、問題発生時刻を把握
1. AWS CloudWatchで該当時刻のスロークエリログを確認し、問題となるクエリを特定
1. クエリをEXPLAIN
1. 該当のクエリが作られるActiveRecordを特定、EXPLAINした結果を元にコードやDB設定を修正
1. テスト、リリース

# 1. AWS RDSのCPU使用率メトリクスを確認し、問題発生時刻を把握

RDS > データベース > 該当のデータベース > モニタリング > CPU使用率

で確認できます。

# 2. AWS CloudWatchで該当時刻のアプリケーションログやスロークエリログを確認し、問題となるクエリを特定

※スロークエリログをCloudWatchに連携する方法は他の記事をご覧ください。今回はCloudWatchで確認できるものとして書いていきます。

スロークエリログで表示される内容のうち、特にQuery_timeが大きい数値のものを探します。
Query_timeが大きい数値 → クエリが長時間 → DBへの負荷が高い ためです。

原因と思われるQuery_timeが異常値（3秒以上など）のクエリを特定します。

# ３. クエリをEXPLAIN

```sql
EXPLAIN
-- 以下、該当のクエリを貼り付け
SELECT ~~~
FROM ~~~
WHERE ~~~
INNER JOIN ~~~
```

このようなEXPLAINを実行すると、
```
id -- SELECT識別子、実行順序を示してる
select_type -- シンプルなSELECT文なのかサブクエリなのかなどを識別
table -- 出力の行で参照しているテーブルの名前
partitions -- クエリが参照したパーティションテーブル。パーティションされていない場合はNULL
type -- テーブルの結合方法
possible_keys -- テーブルの行検索に使用できるindex。NULLの場合は参照するインデックスがない
key -- MySQLが実際に使用しているindex
key_ren -- MySQLが実際に使用したindexの長さ
ref -- 行検索の際にindexと比較されるカラムや値
rows -- クエリ実行のためにMySQLが調査する行数
filtered -- テーブル条件によってフィルタ処理される行数の割合
Extra -- MySQL がクエリーを解決する方法に関する追加情報
```

といった情報が表示されます。
特に、注目すべき点は

- typeがALLではないか？
  - テーブルフルスキャンのためクエリが高負荷になりやすい
- key, possible_keysがNULLではないか？
    - 参照するINDEXがないためtypeがALLになる原因になり得る
- rowsが極端に多くないか？
- ExtraにUsing filesortやUsing temporaryが出ていないか？
    - Using filesortやUsing temporaryが出ている場合、INDEXが貼られていない、メモリのバッファーサイズに収まらないなどの問題を抱えている


参考
https://qiita.com/Stuffy86/items/809540b73cacde951997

https://qiita.com/nikadon/items/2f66b447ed6d3b26d78e

# ４. 該当のクエリが作られるActiveRecordを特定、EXPLAINした結果を元にコードやDB設定を修正

怪しい箇所をexitで止めるなどして、該当のクエリが作られるActiveRecordを特定します。

特定したActiveRecordのコードやDB設定を修正します。

EXPLAINした結果を元に私が取った対策を参考までに共有します。（まだまだ改善の余地ありですが。。）

```
EXPLAINした結果
- typeがALLだった
- rowsが9万件もあった
- ExtraにUsing filesort, Using temporaryが出ていた

対策
- 適切なテーブルに適切なINDEXを貼った
- ActiveRecordで拾ってくるidの数を分割し１個１個のクエリを軽くした

結果
- typeがindexになった
- ExtraにUsing filesortが出なくなった
- 処理実行時、RDS CPU使用率が100%に張り付かなくなった
```

# まとめ
Railsアプケーションでスロークエリが原因でAWS RDSのCPU使用率が100%張り付きになってしまう問題の解決方法の一例を示しました。
もっと効果的な方法が見つかったら追記していきます。
yt-dlp を Synology NAS で実行できるようにする

## 手順概要

`yt-dlp` を Synology NAS で実行できるようにするには以下の手順で行うことになります。

1. Synology NAS に SSH でログイン
1. `yt-dlp` の[実行ファイル](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#release-files)をダウンロードし、`/usr/local/bin/` に保存
1. `yt-dlp` に実行権限を付与

各手順の詳細は以下の各項目を参照してください。

## 1. Synology NAS に SSH でログイン

Synology NAS に SSH でログインする方法は以下のページを参照してください。

https://kb.synology.com/ja-jp/DSM/tutorial/How_to_login_to_DSM_with_root_permission_via_SSH_Telnet

https://kb.synology.com/en-us/DSM/tutorial/How_to_login_to_DSM_with_root_permission_via_SSH_Telnet

👉 SSH 接続の際に公開鍵認証方式を使う方法は以下のページを参照してください。  

https://qiita.com/shimizumasaru/items/56474d98e723ea1b5ae3

https://kb.synology.com/ja-jp/DSM/tutorial/How_to_log_in_to_DSM_with_key_pairs_as_admin_or_root_permission_via_SSH_on_computers

https://kb.synology.com/en-us/DSM/tutorial/How_to_log_in_to_DSM_with_key_pairs_as_admin_or_root_permission_via_SSH_on_computers

(私は SSH ではパスワード認証を無効にし、公開鍵認証方式のみ使用しています。)

## 2. `yt-dlp` の実行ファイルをダウンロードし、`/usr/local/bin/` に保存

以下のコマンドを実行します。

```shell
sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \
  -o /usr/local/bin/yt-dlp
```

## 3. `yt-dlp` に実行権限を付与

以下のコマンドを実行します。

```shell
sudo chmod a+rx /usr/local/bin/yt-dlp
```

## おまけ：アップデート手順

以下のコマンドを実行します。

```shell
sudo yt-dlp --update
```
Rubyのshift, unshift, pop, push

# 概要

キューの操作とかで登場する`shift`、`unshift`、`pop`、`push`の内容を解説するよ！

# 結論

- `shift`、`unshift`が先頭系
- `pop`、`push`が末尾系

# shift系統

とりあえず`shift系統は先頭系`は一旦丸覚えする！

その上で、

shiftは英語で動かすって意味があるから、Array.shiftだと配列から取り出す(=動かす)んだな

って覚える。

`unshift`はその逆で、配列に追加するんだな

と覚える。

# p系統

とりあえず、`p系統は末尾`と丸暗記する。

その上で、`push`は押し込む感があるから配列に追加して、

`pop`はその逆で、配列から取り出すんだな

って覚える！
エンジニア3年目の現状とこれからについて

### 現状
SESに就職し3年目に突入しました。
現場に参画し最初の1年間はJavaのWebアプリの保守・運用を行なっていました。
2年目に突入するタイミングで同じ現場内の開発を担当することになります。
現在までTypeScript, Vue, React, Lit,,,色んな言語、FWを使用して開発しています。

参画先が国内でも有名なテック企業で、未経験の私にとってはとてもありがたい環境に身を置いています。
開発は楽しい一方で、ただ周りを見るとつよつよのエンジニアばかりで自分の成長は遅いんじゃないか、そもそもエンジニアに向いていないのでは？と思ってしまうことがあります。

### 学習を始めるきっかけ
自分のエンジニアとしてのレベルを上げ、もっと楽しく仕事したい。そんな思いで学習を始めました。
自信のないまま毎日仕事をし、ワクワクよりもプレッシャーを感じながら仕事をする。
そんな現状から抜け出したいと考えています。

### 目標
- 短期(3ヶ月)
    自分で０から動くアプリがつくれる、どうすれば作れるかを知っている
- 中期(半年)
    JISOU(プログラミングコーチングサービス)を修了している
- 長期(1年)
    自分のサービスがあり、ユーザーがいる

モチベーション維持のために時々目標への進捗をqiitaで投稿していこうと思います。
読んでくださってありがとうございました。
(しくみ)8x8タイルパターンをかんがえる


x 過去ログをみよ

●　画面とドットのX,Y　青のドットのタイルパターを求めたい


![o_coq168.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c6e61c6e-9ab6-1449-2bdc-2cbe01bd8fc7.jpeg)

●　タイルの配置位置と張り付けるタイルのパターン
画面のX,Yからタイルの配置位置のパータンを求めるには、

```

X' = X / 8

Y' = Y / 8

```

![o_coq169.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/497321b5-ecf6-97c7-6ce1-3c9de64758ea.jpeg)


●　タイルのパターン　A から0,0のドット求める
パターンのドットの位置の求め方は、
DATAは、Y@から求めたパターン A の　列

```

% 　は、　余りを求める

X@ = X % 8

Y@ = Y % 8

>> は、　右シフト命令
& 1 は、　右端の1ビットを取り出す命令


Dot = ( ( DATA  ) >> ( 7 - X@  )  ) & 1

```

![o_coq170.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2dc53d9c-f12a-f3a3-9afe-c5d649f16e64.jpeg)


おまけ

プログラムの例


https://qiita.com/caa45040/items/02051ff7343ffbca84db


```c++


    int a;int ch;
    for(int y=0;y<8;y++){
        for(int x=0;x<128;x++){
        
        ch = st_p[y >> 3][x >> 3] - '0';
        a = 0x80 & (ch_data7[ (y & 0x07 ) + (ch * 8) ] << ( x & 0x07) ) ;
        a = a >> 7;
        //printf("%d ",a);

            if(a == 0){color_vel = 0x0000;}else{color_vel = 0xffff;}
            color_h = (color_vel >> 8) & 0xff;
            color_l =  color_vel       & 0xff;
            
            GPIO_8BIT( color_h );//P1=a; data
            GPIO3(0);//WRB=0;
            GPIO3(1);//WRB=1;

            GPIO_8BIT( color_l );//P1=a; data
            GPIO3(0);//WRB=0;
            GPIO3(1);//WRB=1;
        
        }//for x
        //printf("\n");
    }//for y


```