OmniAICreator/Qiita-1.07M huggingface dataset:
Railsのアソシエーション(モデル通しの関連について)のまとめ

Railsで複数のモデルを関連づけるアソシエーションについてまとめました。
データベースの正規化などについて基本的な理解があれば問題なく本記事も理解できると思います。
参考：おうちで学べるデータベースのきほん
https://www.seshop.com/product/detail/17686?gclid=Cj0KCQjw1rqkBhCTARIsAAHz7K1dsdrBlQh987aO9b1AHTQENVBAVg8ZlnpYK_Dew9HwOydt5kIE4RsaAqwtEALw_wcB

関連づけに使うキーワードは5つあります。
- belongs_to
- has_one
- has_many
- has_many:through
- has_and_belongs_to_many

それぞれ例を出して解説していきます。
## belongs_to  
外部キーを使って親テーブルの情報を参照できるようにする

テーブル例
| articles | comments |
| --- | --- |
| id | id |
| title | article_id |
| body | body |

```ruby
# CommentモデルがArticleモデルに属している
class Comment < ApplicationRecord
  belongs_to :article
end
# 参照例
@comment.article.title
```

## has_one 1対1の関係　
親テーブルが子テーブルを参照する関係

| users | profiles |
| --- | --- |
| id | id |
| name | user_id |
|  | name |

```ruby
# Userモデルが1つのプロフィールモデルを持っている
class User < ApplicationRecord
  has_one :profile
end
# 参照例
@user.profile.name
```

## has_many 1対多の関係
こちらも親テーブルが子テーブルを参照しています

| articles | comments |
| --- | --- |
| id | id |
| title | article_id |
| body | body |

```ruby
# Articleモデルが多数のCommentモデルを持っている
class Article < ApplicationRecord
  has_many :comments
end

# 配列が入ってる
@article.comments.each do |comment|
	comment.body
end
```

## has_many:through 中間モデルを使う多対多の関係

中間モデルにカラムを持たせる場合に使います

| items | reviews | users |
| --- | --- | --- |
| id | id | id |
| name | item_id(FK) | name |
| price | user_id(FK) | email |
| description | context | password |
| created_at | created_at | created_at |
| updated_at | updated_at | updated_at |

```ruby
# StuentモデルとCourseモデルがEnrollmentモデルを介して関連付けられている
class Item < ApplicationRecord
  has_many :reviews
  has_many :users, through: :reviews
end

class Review < ApplicationRecord
  belongs_to :item
  belongs_to :user
end

class User < ApplicationRecord
  has_many :reviews
  has_many :items, through: :reviews
end

# 参照例
@item.users.each do |user|
	{name: user.name, email: user.email}
end

@user.items.each do |item|
	{name: item.name, price: item.price}
end

@review.item.name
@review.user.name
@review.context
```

## has_and_belongs_to_many 中間モデルを使わない多対多の関係

暗黙的に中間テーブルauthors_booksがある

| books | authors | authors_books |
| --- | --- | --- |
| id | id | book_id |
| title | name | author_id |

```ruby
# BookモデルとAuthorモデルが多対多の関係
class Book < ApplicationRecord
  has_and_belongs_to_many :authors
end

class Author < ApplicationRecord
  has_and_belongs_to_many :books
end

# 参照例
@book.authors.each do |author|
	author.name
end

@author.books.each do |book|
	book.name
end
```

参考：https://railsguides.jp/association_basics.html
Railsガイド　Active Record の関連付け
railsAPIソフトを使う・作る上での備考禄

# はじめに
railsで学習していくなかで
自分が作ったAPI作る、使う他のプロジェクトで使うときに詰まった点についての
個人的な備考禄になります。よしなに。


# APIって何だよ
　APIとは「アプリケーション・プログラミング・インターフェース（Application Programming Interface）」の略です
インターフェイスっていうのは「接点」って意味で
結論から言うと「ソフトウェア同士のを繋ぐための接点」ってことです。
よくわかんないですね。はい。
簡単に言うとAPIを利用することで、外部の開発者がそのサービスの機能やデータにアクセスでき開発者は既存のコードや機能を再利用したり、それを使ってカスタマイズしたアプリケーションを作れたりします。
「自分で作ってもいいけどそれ使うより誰かが書いてくれた機能を使ってやりたい事やれれば時短だし楽にアプリ作れるくね？」ってことです。ありがたや。
# APIの使い方は
今回はraiksで作成したAPIをrailsで使っていくのでそれ以外のAPIの使い方は正直分かりません。ごめんなさい。
先ずrailsAPIをたたいてみましょう
apiをたたくというのは「URIで特定の要求を送信(リクエスト)すると応答としてAPIはデータを返してくれます」これを「APIをたたく」と言います。

そうするとjsonファイルが返ってきます
こんな感じ
![apiたたく.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332464/5f5730ed-6fc4-a030-95fb-addf7e34ba5e.png)

WebAPIのほとんどはAPIをたたくとこういった「JSONファイル」が返ってきます。
これを見たら何となくAPIがどういった仕組みになっているかわあ狩るんじゃないでしょうか
つまりAPIとは誰かが作った機能を「APIをたたく」行為で
API提供側のmodelとcontrollerの機能だけ使われてもらい
controllerから来たレスポンスただViewに表示させているだけなんですね。

# API側にはCORSを設定しておけ！
CORSとは
システムの仕組みのうちの一つ。
「Cross-Origin Resource Sharing」（オリジン間のリソース共有）
HTTPヘッダーから詳細情報を読み取り
あるオリジンで動いているアプリケーションを異なるオリジンにある選択された
リソース(データ、ファイルなどアクセス出来るもの)にアクセス権を与えるようにブラウザに指示する
仕組み。
要するに異なるオリジン間を通信する仕組み。
CORSは「同一生成ポリシー」の縛りを開放して異なるオリジン間でもリソースにアクセスできるようにする仕組み。

# 設定の仕方

①APIのサーバー側のGemfileに
「gem 'rack-cors'」
を記述（或いはコメント化して残っているので解除）

②「bundle install」でgemをインストールする。

③「config > application.rb」の先頭に

「require 'rack/cors'」を追加

④↓これを追加
```
    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*' # 全てのオリジンからのリクエストを許可
        resource '*', headers: :any, methods: [:get, :post, :put, :patch,
        :delete, :options]
      end
    end
```
これのざっくりとした解説
- 「Rack::Cors」…
クロスオリジンリクエストを処理するためのミドルウェア。
重要なのでどのミドルウェアよりも先頭に配置すべきもの

- 「middleware.insert_before 0」…
ミドルウェアを挿入するためのメソッド

- 「allow do」
ミドルウェアの設定ブロック内の特定のセクションを指定するための構文です。
ブロック内にはクロスオリジンリクエストを許可するためのルールや、条件を記述することができ
これらの設定を含めることができる

- allow doに入れられるもの一覧

・「origins」…許可するオリジン(リクエスト元)。'*'を含めるとすべてのオリジンを許可することができる。
・「resource」…許可するリソース。（エンドポイント）'*'を
含めるとすべてのリソースに対して許可を出すことができる

・「headers」…許可するヘッダーを指定できる。「:any」を使用するとどのようなヘッダーでも許可する。
・「methods」…許可するHTTPメソッドを記述する



。
Gitのcommit(コミット)のよく使う「取り消し」「修正」方法まとめ

## ①直近のコミット取り消し

```bash
git reset --soft HEAD^
```

- `--softオプション`：作業内容はそのままでコミットだけを取り消したい場合
- `HEAD^`：直前のコミット

## ②5個前のコミットを作業内容自体(まるっと)取り消したい

```bash
git reset --hard HEAD@{5}
```

- `--hardオプション`：コミット自体と作業内容も取り消ししたい場合
- `HEAD@{n}`：n個前のコミット

## ③直前のコミットを上書き修正

```bash
git commit --amend -m "メッセージ"
```

- `--amendオプション`：直前のコミットの内容を修正したい場合


## 番外編

あ、間違ったものを`git push` してしまった
という場合
ローカルのコードを上記のコミットの「取り消し」または「修正」した後
pushに「-f」オプションをつけて強制的に上書きしてしまいます。

```bash
// 強制的にmasterブランチにプッシュする場合
git push -f origin master
```
laravelのinertia.js(vue3)で孫、子、親のバケツリレーしてみた

## はじめに

現在筆者は、Laravel8(php8.1), inertia.js(Vue3,JavaScript)で開発をしております。

[Vue3 \<script setup> 構文で孫、子、親のバケツリレーを書いてみた。](https://qiita.com/saburo555/items/efd360111b1d60aa14e6) の記事を参考にさせていただき実装してみたので、自分なりに解釈した内容を添えてソースコードをご紹介します。

## ソースコード

### 孫コンポーネント
v-modelに値を渡す実際の処理の記述
```vuejs:
<script setup>
const props = defineProps([
  "id",
  "value",
  "text",
  "modelValue",
]);

// 子に渡すトリガー名の総称をemitという名前で定義
const emit = defineEmits(["update:modelValue"]);
// templateの中で式を書くと読みにくくなるのでこの位置で呼び出す処理を準備
const updateValue = (e) => {
  // 子要素のmodelValueをe.target.valueでupdate
  emit("update:modelValue", e.target.value);
};
</script>
<template>
  <input
    :id="id"
    type="radio"
    :value="value"
    :checked="value == modelValue"
    @change="updateValue"
  />
  <label :for="id" class="radio__text"> {{ text }}</label>
</template>
```

### 子コンポーネント
親に書くと冗長になるので切り出した記述
```vuejs:
<script setup>
import RadioButton from "@/Components/atoms/forms/RadioButton.vue";

const props = defineProps([
  "questionnaire_content",
  "answer_option",
  "question",
  "question_number",
  "modelValue",
]);

// 親に渡すトリガー名の総称をemitという名前で定義
const emit = defineEmits(["update:modelValue"]);

// templateの中で式を書くと読みにくくなるのでこの位置で呼び出す処理を準備
const updateValue = (e) => {
  // 親要素のmodelValueをeでupdate
  // この場合のeは孫要素が渡した引数と同じになるので、孫のe.target.valueになります。
  // なので下記の引数はe.target.valueにならないので注意が必要です。
  emit("update:modelValue", e);
};
</script>
<template>
  <div>Q{{ question_number }}.</div>
  <div>{{ question }}</div>
  <RadioButton
    v-for="(value, key) in answer_option[questionnaire_content.id]"
    :id="'q' + questionnaire_content.id + '.' + key"
    :value="key"
    :text="value"
    :modelValue="modelValue" ← 忘れずに渡してください
    @update:modelValue="updateValue" ← "update:modelValueが孫コンポーネントで呼び出されたら、子でupdateValueを実行する"という内容になってます。
  ></RadioButton>
</template>
```

### 親コンポーネント
できるだけスッキリ書いた記述（実際に実装したものではformなどの記述もありますが、今回は関係ない部分は端折ってあります。）
```vuejs:
<script setup>
import Question from "@/Components/molecules/User/FreeTrial/Questionnaire/Question.vue";
import { reactive } from "vue";
import { useForm } from "@inertiajs/inertia-vue3";

// laravelから受け取ったdbのレコード(object)
const props = defineProps(["questionnaire_contents", "user"]);
// 表示に使う値を準備
let prepare_answer_option = {};
for (const questionnaire_content of props.questionnaire_contents) {
  prepare_answer_option[questionnaire_content.id] = {};
  for (const key in JSON.parse(questionnaire_content.answer_option)) {
    prepare_answer_option[questionnaire_content.id][key] = JSON.parse(
      questionnaire_content.answer_option
    )[key];
  }
}
const answer_option = reactive(prepare_answer_option);
// v-modelで使う変数を用意
const form = useForm({
  q1: "",
});
</script>
<template>
  <Question
    :question_number="1"
    :questionnaire_content="questionnaire_contents[0]"
    :answer_option="answer_option"
    :question="questionnaire_contents[0].question"
    v-model="form.q1"  ←modelValueの定義と@update:modelValueの総称。親コンポーネントだけで使えるっぽい
  ></Question>
</template>
```

<br>

以上になります。
SpannerでJOINをした時にメモリ不足になった時の解決法

Spannerで、900万行と200万行くらいを`LEFT OUTER JOIN`して、`WHERE`句で条件つけて、`SELECT`の実行を行ったら、`HashJoinIterator ran out of memory during accumulating rows`というエラーが出た。

調査のためにLIMITをつけて、実行の流れを見たら（エラー文からも分かるが）、JOINが、HashJoinで行われていた。
ハッシュマップを作るのに、データ量が多すぎたのか、メモリ不足になっている？とりあえず、別のJOIN形式ではどうなるか、確かめる事にした。

APPLY JOINで成功した。

時間はかかるが、数分程度は許容できる処理だったので、JOINの方式をAPPLY JOIN (`JOIN_TYPE=APPLY_JOIN`)にすることで、無事にクエリの実行が行えた。

データベースと友達になろうな。
tweepyを使いTwitter API V2に画像を投稿しよう！

Tweepyを使いTwitter API V2で画像を投稿する方法
```python:TwitterAPIv2.py
import tweepy

# Twitter API credentials
consumer key = "xxxxxxxxxxxxxxxxxxxx"
consumer secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
access_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
access_token_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Authenticate Twitter API
auth = tweepy. OuthHandler ( consumer_key, consumer_secret)
auth. set_access_token(access_token, access_token_secret)

# Create API object
api = tweepy.API (auth)
client = tweepy.Client (
consumer_key=consumer_key, consumer_secret=consumer_secret, access_token-access_token, access_token_secret=access_token_secret)

# Attach image and message to tweet
image_path = './sample. jpg'# Specify image file path
message = 'sample message'# Specify message
media = api. media_upload (filename=image_path)
client. create_tweet (text=message, media_ids= [media.media_id])
```
Windows SSHでPythonコード実行

外部PCから仮想サーバ（192.168.84.130）へSSHでPythonコードを実行

```
C:\Users\[外部PCユーザ名]>ssh [仮想サーバのユーザ名]@192.168.84.130 python C:\Users\[仮想サーバのユーザ名]\Desktop\import_fdb_py32.py
[仮想サーバのユーザ名]@192.168.84.130's password:
('USA', 'Dollar')
('England', 'Pound')
('Canada', 'CdnDlr')
('Switzerland', 'SFranc')
('Japan', 'Yen')
('Italy', 'Lira')
('France', 'FFranc')
('Germany', 'D-Mark')
('Australia', 'ADollar')
('Hong Kong', 'HKDollar')
('Netherlands', 'Guilder')
('Belgium', 'BFranc')
('Austria', 'Schilling')
('Fiji', 'FDollar')
```

PythonコードはFirebirdのsampleを見るコード
```Python
import fdb

# Firebirdデータベースへの接続情報を指定します
dsn = "192.168.84.130:C:\soft\Firebird\Firebird_2_0\examples\empbuild\employee.fdb"
# 'localhost/3050:/path/to/database.fdb'
user = 'SYSDBA'
# 'your_username'
password = 'masterkey'
# 'your_password'




# Firebirdデータベースに接続します
con = fdb.connect(dsn=dsn, user=user, password=password)

# クエリを実行します
cursor = con.cursor()
cursor.execute("SELECT * FROM COUNTRY")#("SELECT * FROM your_table")
result = cursor.fetchall()

# 結果を表示します
for row in result:
    print(row)

# 接続を閉じます
con.close()
```
Databricksクラスターのドライバーで動作するLLMアプリへのアクセス

最初はなんのこっちゃと思いました。[モデルサービング](https://qiita.com/taka_yayoi/items/b5a5f83beb4c532cf921)以外の選択肢があったとは。

https://qiita.com/taka_yayoi/items/6c6e0744de5681f21d96#%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%83%BC%E3%81%AE%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%83%BC%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E3%83%A9%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0

早速やってみます。

:::note
**注意**
元記事にもあるようにインタラクティブな開発での使用が推奨されています。プロダクションでの用途では[モデルサービング](https://qiita.com/taka_yayoi/items/b5a5f83beb4c532cf921)を使ってください。
:::

# プロキシーアプリの起動

ノートブックをクラスターにアタッチして、以下を実行します。

```py
from flask import Flask, request, jsonify
import torch
from transformers import pipeline, AutoTokenizer, StoppingCriteria

model = "databricks/dolly-v2-3b"
tokenizer = AutoTokenizer.from_pretrained(model, padding_side="left")
dolly = pipeline(model=model, tokenizer=tokenizer, trust_remote_code=True, device_map="auto")
device = dolly.device

class CheckStop(StoppingCriteria):
    def __init__(self, stop=None):
        super().__init__()
        self.stop = stop or []
        self.matched = ""
        self.stop_ids = [tokenizer.encode(s, return_tensors='pt').to(device) for s in self.stop]
    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs):
        for i, s in enumerate(self.stop_ids):
            if torch.all((s == input_ids[0][-s.shape[1]:])).item():
                self.matched = self.stop[i]
                return True
        return False

def llm(prompt, stop=None, **kwargs):
  check_stop = CheckStop(stop)
  result = dolly(prompt, stopping_criteria=[check_stop], **kwargs)
  return result[0]["generated_text"].rstrip(check_stop.matched)

app = Flask("dolly")

@app.route('/', methods=['POST'])
def serve_llm():
  resp = llm(**request.json)
  return jsonify(resp)

app.run(host="0.0.0.0", port="7777")
```

これだけで、Dollyがサービングされるようになります。

```
 * Serving Flask app "dolly" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://10.0.0.69:7777/ (Press CTRL+C to quit)
10.0.14.228 - - [18/Jun/2023 06:21:20] "POST / HTTP/1.1" 200 -
```

# LLMへのアクセス

同じクラスターに別のノートブックをアタッチして以下を実行します。

最新のlangchainをインストールします。

```py
%pip install langchain==0.0.202
```

```py
dbutils.library.restartPython()
```

これだけでLLM(Dolly)にアクセスできます。

```py
from langchain.llms import Databricks

# アプリを稼働しているのと同じクラスターにアタッチしたDatabricksノートブックを実行する場合、
# `Databricks`インスタンスの作成に必要なのはドライバーのポート番号を指定することだけです。
llm = Databricks(cluster_driver_port="7777")

llm("How are you?")
```
```
Out[1]: "I'm doing well, thank you."
```

動きました！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
SessionとCokkeey

session
ユーザーが行う一連の処理

cokkeey
HTTPは「ステートレス」
HTTP通信ではリクエストごとに状態を保持することができない
HTTPの「ステートレス性」を補填して状態を保持させるために生まれた技術が「Cookie」および「Session」

サーバーはアクセスしてきたユーザーにSession IDを付与する
クライアントはブラウザのCookieにそのSession IDを保存する
クライアントは次にリクエストを送るときに、そのSession IDをサーバーに渡す
サーバーはそのSession IDによって「誰からのアクセスか」を認識できる
サーバーはSession IDに紐づいた情報をSession情報保管場所（データベースなど）に保存する
以上の手順でSession（ユーザーが行う一連の動作）管理を行うことで、HTTPのステートレス性を克服して、状態を保持することができる

※Session情報はデータベースだけでなく、様々な場所に保管可能
LaravelだとSession情報の保管場所として、「database」「file」「redis(kvs)」などを自由に選択可能



保存形式は、 キー名＝値
【Mac】コマンドでファイルをゴミ箱に入れる


## はじめに

`rm sample.txt`などを実行するとゴミ箱に移動することなく完全に削除されます。  
完全に削除するのではなくゴミ箱に移動する方法について記載します。  

## ファイルをゴミ箱に移動する方法

次のコマンドを実行するとファイルをゴミ箱に移動できます。  

```terminal
mv sample.txt ~/.Trash
```

```terminal
$ ls ~/.Trash
sample.txt

```
if , elseの練習

以下の要件を満たす in1to100メソッドを作ろう。

第一引数のnumが1以上かつ100以下の範囲であればTrueを出力すること
第二引数のpeachがTrueの場合は、第一引数numが条件範囲外でもTrueを出力すること
それ以外はFalseを出力すること
```ruby
def in1to100(num, peach)
  # ここに条件式を記述する
end

# 呼び出し例
in1to100(95,false)
) 
出力例
in1to100(95,false) →True

```
if ( 【複数の条件が含まれる条件式】 )

end
複数の条件式を組み合わせた複雑な条件式を記述するために論理演算子&&と||を使う。

条件式aと条件式bを組み合わせる場合は以下のように書く。

```ruby
# aもbもtrueの場合にtrue
a && b 

# aかbのどちらかがtrueの場合にtrue
a || b 
```
Rubyの論理演算子では、左辺から右辺に条件式を評価する。もし式全体の評価が確定した場合は、その時点で残りの評価を行わない。

上の例で言えば、a&&bにおいてaがfalseの時点で全体がfalseと確定するため、bの判定は行わない。また、a||bでは、aがtrueの時点で全体がtrueと確定するため、bの判定は行わない。

上の論理演算子も使って作ると、こうなる。
```ruby
def in1to100(num, peach)
  if (num >= 1 && num <= 100) || peach
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
in1to100(115,false)
in1to100(35,false)
in1to100(35,true)
```
【0.気持ち整理編】ここから始めようWebアクセシビリティ

どうも、みなさんこんにちは。
音楽をほとんど聞かないのに突然オーディオ泥にハマりたい気持ちになってきているしゃもきっとです。
昨日はfinalのA5000をポチりました。
よろしくお願いします。

## 概要
この記事はアクセシビリティついて

- 気になってるけど手をつけられていない
- みんなどんなところから始めているの？（何から始めたらいいかわからん）
- いきなり情報量が多かったり専門的な記事は読むのは辛い
- やろうと思っているけど気持ちが追いついていない

と感じている人の背中を押すための記事です。
気持ち整理編です。専門的な話はほぼ出てきません。ご安心を。

## Webアクセシビリティに大切な考え方
おそらくこの記事を読んでいる人はすでにWebアクセシビリティが何かざっくりふんわりわかっていると思いますが、
念の為ざっっっっっっっっっくり説明すると
__「Webをもっと使いやすくする　誰にでも使えるようにする」__
目指す先にあるのはここです。アツいですね！

### 基準
じゃあどういう基準でアクセシブルといえるの？というのを書いてあるのがWCAGとかJISとかのガイドラインですが、いきなりここから入るのは辛いと思います。
読める人は読めばいいですが、辛い人は　__一旦みないふり__　をしましょう。
僕もまだ読んでいません。難しい話は一旦すっ飛ばして、できることから始めましょう。

__やりたいけど何もできない__ よりも　__一つだけでも改善できた__ の方がいいはずです。
いきなり難しいことをやる必要はありません。工数がほとんどかからないような簡単なことから始めましょう。

## 誰（何）のために
「これをやる」という時に、理由があれば入りやすい人が多いと思います。
アクセシビリティをやる理由をいくつか並べてみましょう。

- やらざるをえなくなったのでやる
- 身内に困っている人がいてその人のためにやる
- 自分自身が困っているので自分のためにやる
- 自分のなかに信念がありそれに従ってやる
- 組織内での評価（給与や名誉）のためにやる
- 他者（他社）との差別化のためにやる

まあいろいろあると思います。
ざっくり自分のため、他人のための二つに分けることができます。
個人差はありますが、自分以外の人のためにやった方がうまくいくらしいです。
なので、誰かのために　の誰の対象をはっきりさせるといいのではないかと思います。

例えば
- Webサイトを使用する人になりきってその人のために
- Webサイトを作って欲しいと依頼してきてくれたクライアントのために
- 仕事をとってきてくれたディレクタやデザインを作ってくれたデザイナのために
- 自分の周りにいる高齢者や障害を持つ人のために
- アプリケーションを使ってくれるユーザーやクライアントのために

など、できるだけ具体的に対象を絞っていくと「誰のために」の部分が明確になるのでスッキリします。
手がうごかない人はここを整理するところから始めて自分がアクセシビリティを改善したい理由を明確にするといいと思います。
（自分のために　で動ける人はそれで問題ないと思います。最終的にWebがアクセシブルになるというのが達成されていればOKなので。）

## 誰にとってうれしいのか
__「Webをもっと使いやすくする　誰にでも使えるようにする」__　ここが達成されて嬉しい人は例えばどんな人でしょうか？

### 障害を持つ人
一番想像しやすいですね。
そもそもWebコンテンツが身体的特徴を持つ持たないに関わらず誰にでもアクセスできるようになっていればいいですよね。
これはアクセシビリティの改善で達成できるでしょう。

### キーボードで操作することが多いエンジニアなど
確かに嬉しいですね。
キーボードで操作できるように作っておくとキーボード以外のデバイスで操作するひとにも恩恵があったりするようです。

### 目の悪いお年寄り
読みやすい色とフォント、フォントサイズが使われていると嬉しそうです。
日本はお年寄りが多いですし、人口も減り続けているので今後そう遠くない未来に自分たちが見やすいアクセシブルなサイトやアプリケーションを作っておくと助かりそうです。
今後需要も高くなってきそうです。

いろんな人が助かりそうですね。

## まとめ
「誰のためにするのか」「どんなメリットがあるのか」
この辺がわかってきたと思います。

アクセシビリティの改善によって、今までWebコンテンツにアクセスできなかった人たちが情報を得られるようになり、
今までアクセスできていた人は今までよりもっとアクセスしやすくなります。
自分たちが届けたい情報をもっと多くのひとにもっと便利に届けることができるようになります。
それってワクワクしませんか？

今まで自分が作ってきたものに満足していた人、至らない点に気づいてもっと良くしたくなってきませんか？
知らないうちに誰かを排除してしまっていたことに罪悪感に近い感情を抱いたり、
そこを改善することに責任感を感じたりしませんでしたか？

ネガティブな感情から、ポジティブな感情から　入り口はどこでもかまいません。
知識が少ない、多い、どっちでも構いません。できることから始めませんか？

最後に、気持ちは整理できましたか？
覚悟というと大袈裟ですが、「やるぞ」という気持ちになっていただければ嬉しいです。

この記事には続編があります。
次回は「じゃあどこからやる？」を記事にする予定です。
お楽しみに。
Windows11 22H2 「お使いの資格情報は機能しませんでした」の対処法

Windows10を11にアップグレードしたら、RDPで他にPCに接続できなくなった。
「Windows Defender Credential Guard では、保存された資格情報を使用できません。」
と出る。
対処法は以下より。

https://learn.microsoft.com/en-us/answers/questions/1021785/windows-11-22h2-cant-use-saved-credential

具体的にはこんな感じで、資格情報を事前に登録しとけばいいらしい。

```
cmdkey /generic:TERMSRV/<targetname> /user:<username> /pass:<password>
```

たとえば
接続先：192.168.1.1
ID：user
パスワード：hogehoge
だと
```
cmdkey /generic:TERMSRV/192.168.1.1 /user:user /pass:hogehoge
```

たしかにこれで接続できるようになった。
"究極の初心者"　文系大学生プログラミング勉強の道のり - 3 -

私は文系の4年制大学に通う大学生です。
私が、3年生の4月から開始したプログラミングの勉強の道のりを書いていこうと思います。


## 当時の状態

- pythonの基礎文法で関数とクラス以外は学習した。
- エンジニアインターンシップに参加し、実際のエンジニアと接し勉強頑張ろうと思ってる。

## 1-0. 就職活動

夏のインターンシップ参加後は、就職活動でエントリーシート作成や、企業説明会、面接等に追われ、プログラミングの学習は、ほとんどしておりませんでした。

そうした就職活動を約半年ほど行いました。
その経験や体験については、また別途書こうと思ってます。
（ものすごいいろいろあったので..）

## 1-1. 競技プログラミング

就職活動中、選考の一環で競技プログラミングというものの存在を知りました。
選考のために一冊の本を買い、競技プログラミングの学習を始めました。
この学習は現在も続けています。


## 1-2. Pythonの関数とクラス 

で、競技プログラミングの勉強をしていて、以下のコードに困惑します。

```Python
N = map(int,input().split())
```

注目してほしいのは

```Python 
input().split()
```
このかたち、習ってないぞ。と。
そう、大学でPythonの基礎文法を学んだ際、授業の進みが想定より遅かったので、関数とクラスに関しての部分はまだ学習してなかったんです。

何だろうなこのかたち、と思いながらかれこれ2~3か月放置してたのですが、Paizaというプログラミング学習サイトでPythonの基礎文法の関数とクラス
を勉強することで、意味が分かりました。

この記事で言いたいことは、一つ。
プログラミング言語の基礎文法を学ぶ際は、関数とクラスまでちゃんと勉強しておくこと！！

このクラスを学べば分かる、"メソッド"が分からないと、なにかと躓きやすいんですよね、プログラミングの学習をしていて。

やはり基礎は大事だなと、自分の過ちから再確認させられたという話でした。

## 1-3. 次回予告

次回は、私が経験した「文系未経験からのIT企業への就職活動について」か、選考の過程で経験した、とあるIT企業の選考、「リモートインターン」についてを書こうと思っております。

今回も最後までお読みくださりありがとうございました。
それではまた次回。
KarabinerでCommand + Backquote( ` ) で日本語入力を切替え

US配列キーボードをWindowsで長年使ってるんで、日本語入力切替は Alt + Backquote(`) が染み付いている。それをKarabinerで実現。吊るしのセッティングでコマンドキー単体で日本語・英語をトグルで切替える設定なんかも便利なものの、WindowsでUSキーボードを利用する人が多かった人や、自分のように今でも併用している人は、寧ろこっちの方が快適かもしれないな、と。

↓こちらをコピって、/.config/karabiner/assets/complex_modificationsの下にJSONファイルを追加すればOKです。(Ver14.11.0で動作は確認）

``` json: sample.json
{
  "title": "Eisuu Kana at Windows by left_command + backquote at Mac",
  "rules": [
    {
      "description": "WindowsのAlt+Backquoteを左コマンドとbackquoteで実現",
      "manipulators": [
        {
          "type": "basic",
          "conditions": [
            {
              "input_sources": [
                {
                  "language": "ja"
                }
              ],
              "type": "input_source_if"
            }
          ],
          "from": {
            "key_code": "grave_accent_and_tilde",
            "modifiers": {
              "mandatory": [
                "left_command"
              ]
            }
          },
          "to": 
           [
            {
              "key_code": "japanese_eisuu"
            }
          ]
        },
        {
          "type": "basic",
          "conditions": [
            {
              "input_sources": [
                {
                  "language": "en "
                }
              ],
              "type": "input_source_if"
            }
          ],
          "from": {
            "key_code": "grave_accent_and_tilde",
            "modifiers": {
              "mandatory": [
                "left_command"
              ]
            }
          },

          "to": [
            {
              "key_code": "japanese_kana"
            }
          ]
        }
      ]
    }
  ]
}
```
【2ヶ月目】エンジニア1年目　5月

## 自己紹介
こんにちは！
私は2023年の4月から社会人になったるんるんです！
新居に引越ししてまだ落ち着かないし、めちゃ暑い５月でしたが、そんな5月を総括したいと思います。

<details><summary>以下自己紹介</summary>
私は文系の学部(しかも文学部)を卒業しており、情報系の勉強は独学でやっており、基礎的なこともあまり理解できてない状態での社会人生活をスタートしました。

4月から就職した会社は、Web系ベンチャー（？）であり、バックエンドを担当するエンジニアとしてジョインしました。
実は去年の４月に内定をもらっており、私の希望で6月からアルバイトとして一足先に仕事をしていました（ユニットテスト作成や簡単なリファクタリングなど）。
</details>


## 5月の目標
### 仕事
#### アサインされるIssueの難易度を高めたい
Issueでは細々とした仕事を振られているので、早いスパンで回していきたい。
また製品修正から、追加開発や新規開発などにも参加できるようになりたい。

### 個人活動
#### ネットワーク、サーバーの理解
それ用の本を購入したので（来月掲載します）、その本を読み込んで、弱点であるインフラの理解を深めていきたい

### プライベート
#### 引越し作業を無事終える
無事引越し作業を終えたい。
あと新居に順応する←こればっかり

## 5月にやったこと
### 追加開発
簡単な機能追加に携わった

### リファクタリング
ある関数についてのリファクタリングを行った。
関数がどう呼ばれているのか、中身の判定がどうなっているのかをフローチャートにして報告。
その後修正方針を考案して、上長の方と方針を固めた。

ちなみにフローチャートは[Mermaid.js](https://mermaid.js.org/)にて作成しました。
コードを書くと勝手に図にしてくれるので非常に便利です。
ぜひご活用ください。


## 個人活動
### 『Real World HTTP』
HTTPについてさらに踏み込むために勉強。
読みきれていませんが、かなり良著で、HTTPやネットワークについて学びたい方はオススメです。

## プライベート
### 日曜に野球
毎週日曜日の午前中に友人とキャッチボールするのが日課です。
運動大事
（筋トレも不定期ですが、やってはいる。。）


## 一ヶ月過ごしてみて
### 会社に順応
会社に順応した。
これは働くのに慣れたもそうだが、会社のルールや文化にも大分と順応した。
良い意味でも悪い意味でも大人になってきた。


## 足りないこと
### 集中力
集中力が落ちる時があり、作業効率が落ちる時がある。
常に集中するのは不可能だが、集中できない時にどう過ごすのかが大事。
瞑想や睡眠など工夫してみたい

### 個人活動
個人活動がなかなかするタイミングがない。
そもそも開発したいこともないのでそれを検討するところから。
基礎知識を取得するために読書などはしているが。。

## 6月の目標
### 仕事
さらにレベルの高い仕事をしたい。
ある程度大きなタスクを一人でこなしてみたい。

### 個人活動
#### Real World HTTPの続き
とりあえず全てに目を通したい。
また『RESTful Web Services』も積読があるので着手してきたい

#### 個人開発
やりたいことを策定
【AWS/Terraform】RDSの管理

# はじめに
AWSのRelational Database Service（RDS）は、スケーラブルなリレーショナルデータベースをクラウド上で簡単にセットアップ、操作、スケーリングできるサービスです。この記事では、Terraformを使用してRDSを管理する方法を記載します。

# 環境
- Terraform v1.0.0以上
- AWSアカウント
- AWS CLI設定済み（認証情報）


# RDSとは
RDSは、MySQL, PostgreSQL, MariaDB, Oracle Database, SQL Serverなど複数のデータベースエンジンをサポートしています。AWSがハードウェアのプロビジョニング、データベースのセットアップ、パッチ適用、バックアップといった作業を自動化してくれるため、開発者はアプリケーションの構築とスケーリングに専念できます。

# TerraformでのRDSの管理

VPCに関しては下記に記載しています。

https://qiita.com/yokku21/items/33d797ea5c43e895d516

セキュリティグループに関しては下記に記載しています。

https://qiita.com/yokku21/items/d68344a31259f6cdce0a

```bash
# パラメータグループ
resource "aws_db_parameter_group" "mysql_parametergroup" {
  name   = "mysql-parametergroup"
  family = "mysql8.0"
  parameter {
    name  = "character_set_database"
    value = "utf8mb4"
  }
  parameter {
    name  = "character_set_server"
    value = "utf8mb4"
  }
}

# オプショングループ
resource "aws_db_option_group" "mysql_optiongroup" {
  name                 = "mysql-optiongroup"
  engine_name          = "mysql"
  major_engine_version = "8.0"
}

resource "aws_db_subnet_group" "mysql_subnetgroup" {
  name = "mysql-subnetgroup"
  subnet_ids = [
    aws_subnet.private-subnet-db-1a.id,
    aws_subnet.private-subnet-db-1c.id,
  ]
  tags = {
    Name = "mysql-subnetgroup"
  }
}

resource "random_string" "mysql_password" {
  length  = 16
  special = true
}

resource "aws_db_instance" "mysql_db" {
  engine         = "mysql"
  engine_version = "8.0.32"

  identifier = "mysql-db-identifier"

  username = "admin"
  password = random_string.mysql_password.result

  instance_class        = "db.t2.micro"
  allocated_storage     = 20
  max_allocated_storage = 50
  storage_type          = "gp2"
  storage_encrypted     = false

  multi_az                 = false
  availability_zone       = "ap-northeast-1a"
  db_subnet_group_name = aws_db_subnet_group.mysql_subnetgroup.name
  vpc_security_group_ids = [
    aws_security_group.db_sg.id
  ]
  publicly_accessible = false
  port                = 3306

  name                 = "mysql_db_name"
  parameter_group_name = aws_db_parameter_group.mysql_parametergroup.name
  option_group_name    = aws_db_option_group.mysql_optiongroup.name

  backup_window              = "04:00-05:00"
  backup_retention_period    = 7
  maintenance_window         = "Mon:05:00-Mon:06:00"
  auto_minor_version_upgrade = true

  deletion_protection = false
  skip_final_snapshot = true

  apply_immediately = true

  tags = {
    Name = "db-sg-tag"
  }
}
```

# RDSの適用

```bash
terraform apply
```
VScodeでprettierが急に使えなくなってしまったので解決した。

# はじめに
VScodeでprettierを使っていると急にエラーが出るようになってしまったのを解決したので共有したいと思います。

## 事象
コード書いて保存していたら「あれっ？prettierが効いてないなんでなんかエラー出てるなんだこれ？」となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/8356f07e-1e2f-be3a-fb81-eeb99ef2b842.png)
エラーメッセージが出てる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/382a0b00-ffc7-b2a2-d196-c569f373a943.png)

## 解決方法
エラー文の`TypeError: Cannot read properties of undefined (reading 'uid')`で検索してみるとissueに解決方法が載ってました。

https://github.com/prettier/prettier-vscode/issues/3020

どうやら設定に`"prettier.prettierPath": "./node_modules/prettier"`を追記してあげれば動くみたい。

## 解決する
歯車アイコンから設定を選び設定を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/58499f47-836e-7ff3-f434-0e36d0d242ac.png)
設定(JSON)を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/ffddb30d-efbd-7906-e51f-372d6bae6d0a.png)
{}内に"prettier.prettierPath": "./node_modules/prettier"を追記して保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/87607922-9bd6-2d4e-0ab6-6efc4fa8e801.png)

エラーでprettierが効いてなかったコードを保存してみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819639/9c219d17-bda5-9abd-586c-7f877899b0b8.png)
キチンと動いたようです。

## おわり
見たことないエラーに遭遇するとちょっとびびってしまいますね。
prettier使えるようになってよかった～おしまい。
cscの作法 その365

# 概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
GL.DrawArrays使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fe1f55e7-343d-fe22-2812-9742e3317c15.png)


# サンプルコード

```
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace App
{
	class Gwin: GameWindow {
		double counter = 0;
		int vBufName;
		double[] vBufData = new double[] {
			0.2, 0.2, 0.2,  0.6, 0.2, 0.2,  0.6, 0.6, 0.2,  0.2, 0.6, 0.2,
			0.2, 0.2, 0.6,  0.6, 0.2, 0.6,  0.6, 0.6, 0.6,  0.2, 0.6, 0.6,
			0.2, 0.2, 0.6,  0.6, 0.2, 0.6,  0.6, 0.2, 0.2,  0.2, 0.2, 0.2,
			0.2, 0.6, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.2,  0.2, 0.6, 0.2,
			0.2, 0.2, 0.6,  0.2, 0.6, 0.6,  0.2, 0.6, 0.2,  0.2, 0.2, 0.2,
			0.6, 0.2, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.2,  0.6, 0.2, 0.2
		};
		public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
			this.VSync = VSyncMode.On;
			vBufName = GL.GenBuffer();
			GL.BindBuffer(BufferTarget.ArrayBuffer, vBufName);
			GL.BufferData<double>(BufferTarget.ArrayBuffer, sizeof(double) * vBufData.Length, vBufData, BufferUsageHint.StaticDraw);
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			counter += e.Time;
			GL.Rotate(counter / 5, 0, 1, 0);
			GL.Rotate(counter / 5, 1, 0, 0);
			GL.ClearColor(0.0f, 1.0f, 0.0f, 1.0f);
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.EnableClientState(ArrayCap.VertexArray);
			GL.BindBuffer(BufferTarget.ArrayBuffer, vBufName);
			GL.VertexPointer(3, VertexPointerType.Double, 0, 0);
			GL.Color4(1.0f, 0.0f, 0.0f, 1.0f);
			GL.DrawArrays(PrimitiveType.Quads, 0, 4);
			GL.DrawArrays(PrimitiveType.Quads, 4, 4);
			GL.Color4(0.0f, 0.0f, 1.0f, 1.0f);
			GL.DrawArrays(PrimitiveType.Quads, 8, 4);
			GL.DrawArrays(PrimitiveType.Quads, 12, 4);
			GL.Color4(1.0f, 1.0f, 0.0f, 1.0f);
			GL.DrawArrays(PrimitiveType.Quads, 16, 4);
			GL.DrawArrays(PrimitiveType.Quads, 20, 4);
			this.SwapBuffers();
		}
	}
	class Program {
		static void Main(string[] args) {
			Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
			window.Run();
		}
	}
}





```


以上。
cscの作法 その364

# 概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
GL.Vertex3使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d7791213-48c7-5b28-576a-ef14968c8223.png)


# サンプルコード

```
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace App
{
	class Gwin: GameWindow {
		double counter = 0;
		public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
			this.VSync = VSyncMode.On;
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			counter += e.Time;
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.Rotate(counter / 15, 1.0, 0, 0);
			GL.Rotate(counter / 15, 0, 1, 0);
			GL.Begin(PrimitiveType.Quads);
			GL.Color4(Color4.White);
			GL.Vertex3(-1.0f, 1.0f, 0.0f);
			GL.Color4(new float[] { 
				1.0f, 0.0f, 0.0f, 1.0f 
			});
			GL.Vertex3(-1.0f, -1.0f, 0.0f);
			GL.Color4(0.0f, 1.0f, 0.0f, 1.0f);
			GL.Vertex3(1.0f, -1.0f, 0.0f);
			GL.Color4((byte) 0, (byte) 0, (byte) 255, (byte) 255);
			GL.Vertex3(1.0f, 1.0f, 0.0f);
			GL.End();
			this.SwapBuffers();
		}
	}
	class Program {
		static void Main(string[] args) {
			Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
			window.Run();
		}
	}
}





```


以上。
showModalBottomSheetの中でStateNotifierProviderの変更を受け取る

Stateが変更されてもModalBottomSheetが再描画されずハマったので。
状況は↓こんな感じ。
![before_resize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145838/8961052a-ae27-67de-84f1-51d8355e1e79.gif)

ググってもshowModalBottomSheetの中でStatefulBuilderを使ってsetState()してる記事しか見当たらず、Riverpodの旨味を活かせてない感がありました。

# 対象読者

- Flutterのソースが読める人
- Riverpodを使ったことがある人

FlutterやRiverpodの使い方は本記事では説明しないので公式Docsやその他記事を参照してください。:page_facing_up:

https://docs.flutter.dev/get-started/install

https://riverpod.dev/ja/docs/getting_started

# 結論

- showModalBottomSheetの中でConsumer Widgetを使う
- Consumer Widgetのbuilder内でwatchしてその値を参照する

修正後
![after_resize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145838/6d6aa701-14c5-a8a6-4924-19c2471e3722.gif)

# 何故こんな事が起きるのか

※推測多め。

修正前のWidget Treeはこんな感じ。

![修正前のWidget Tree](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145838/fc36417f-421f-eade-6345-87651f92b130.jpeg)

下部の`Center`配下がModalBottomSheetのツリー。
`showModalBottomSheet()`（おそらくDialogも？）を実行するとModalBottomSheetのツリーは `MyHomePage` 配下ではなく、別のツリーとして構築されてしまう。そのためConsumerで定義したProviderにアクセスできず、変更を受け取れない（多分）。


# 解決策

## Consumer Widgetの使い方

ちょいちょい出ているConsumer Widgetは部分再描画するためのウィジェット。

https://pub.dev/documentation//flutter_riverpod/latest/flutter_riverpod/Consumer-class.html

> Consumer can be used to listen to providers inside a StatefulWidget or to rebuild as few widgets as possible when a provider updates.

`builder` プロパティに監視したいProviderと変更時に再描画したいWidgetを書いてあげる。
watchしているState変数を再描画したいWidget内で参照しないと再描画されないので注意！

```dart:Consumerの使い方
Consumer(
  builder: (context, ref, child) {
    final xxxState = ref.watch(監視したいProvider);
    return 再描画したいWidget;
  },
);
```

Consumer WidgetはあくまでWidgetなので、これをshowModalBottomSheetの中に書けばOK。（謎にここで数時間ハマった。。）

```diff:showModalBottomSheetの中でConsumerを使う
showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
+    return Consumer(
+      builder: (context, ref, child) {},
+    );
  },
);
```

修正後のWidget Treeはこんな感じ。
ModalBottomSheetのツリー内にConsumerがあるので変更を受け取って再描画できる。

![修正後のWidget Tree](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145838/14d82f5c-0298-aadc-4d58-9891503be1fb.jpeg)

## 余談

StatelessWidgetはConsumerWidgetに、StatefulWidgetはConsumerStatefulWidgetに書き換えるのが基本だが、Stateが変化するとページ全体が再描画されてしまう&再描画のコストが掛かってしまう。
個人的には全部StatelessWidgetで書いて、Stateの状態を受け取りたいところだけCosumerで囲む方が再描画のコストも低くなるし、StateはRiverpod、UIはStatelessWidgetに分離出来るから設計的に気持ち良く感じる。

## サンプルソース

https://github.com/jp7eph/samples/tree/qiita/d7d92b43a368ae0a2a21

Commit履歴に失敗パターンと成功パターンを打っているので気になる方は是非。

## 参考情報

https://zenn.dev/kiiimii/articles/96d5dc181228b2

https://teratail.com/questions/mq44677m30kzr4

https://stackoverflow.com/questions/71939658/flutter-how-to-rebuild-using-riverpod-within-showmodalbottomsheet

# 最後に

筆者はFlutterもRiverpodも初心者で見様見真似で書いてるので間違いがあったらご指摘お願いします :bow:
論理演算子のまとめ

論理演算子（Logical operators）は、プログラミングや論理式で使用される演算子です。論理演算子は、真偽値（真または偽）を操作するために使用されます。主な論理演算子には以下のようなものがあります。

論理積（AND）演算子（&&またはand）：両方の条件が真の場合に真を返します。例えば、A && Bは、Aが真かつBが真の場合に真となります。

論理和（OR）演算子（||またはor）：どちらか一方または両方の条件が真の場合に真を返します。例えば、A || Bは、Aが真またはBが真の場合に真となります。

否定（NOT）演算子（!またはnot）：条件を反転させます。真の場合は偽を、偽の場合は真を返します。例えば、!AはAが偽の場合に真となります。

これらの論理演算子は、複雑な条件や制御フローを扱うために使用されます。プログラミング言語や論理式によって、論理演算子の表記や挙動は異なる場合がありますが、一般的な概念としては共通しています。
Vim 学習方法 備忘録

vimはファイルやOsパッケージを操作する際に、使えると便利です。

例えば、vimを使って、環境変数を自身のPCに保存しておく際です。
前提として、Macは Home brewパッケージで動きます。 brewをインストールしないと、開発する際に不便です。
そのbrewをインストールすることで、PHPやPythonのバージョンを簡単にインストールでき、PCに保存できます。

※いちいち、毎回　versionをインストールしなくて済みます→すぐにそれぞれの言語に基づいたVersionで
開発できる。

開発者にとって、vimは使えて損はないですし、むしろ使えた方がいいので学習方法を列挙します。
前提として、基本のLinux操作はできること。


https://dev.classmethod.jp/articles/vim-quickstart-with-vimtutor/

こちらの教材でvim操作を覚えよう。 vimの基本的な内容でチュートリアルに沿って行えば難しくはないです。

最後にゲーム感覚で楽しむながら、vimをマスター
https://vim-adventures.com/
React Routerを使ってトップページを変更してみた

# やりたいこと
reactでは、パスを指定しないドメインのみのurl（`http://localhost`　など）ではindex.tsx（App.tsx）が呼び出されることになりますが、このデフォルトのページを別のコンポーネントにしたい。


```index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'

import { App } from './App'

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
)
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)
```

```App.tsx
import React from 'react'

import { PostsTop } from './components/posts/PostsTop'

export const App = () => {
  return (
         {/* PostsTop　をトップページにしたい */} 
  )
}
```

# 手順
### 1. react-router-domをインストールする
「react-router-dom」というパッケージをインストールします。
 ```
$ yarn add react-router-dom
```

### 2. App.tsxに追記する。
BrowserRouterとRoutesで囲んだ中にRouteを記述する。

```App.tsx
import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'

import { PostsTop } from './components/posts/PostsTop'

export const App = () => {
  return (
        <BrowserRouter>
          <Routes>
            <Route path='/' element={<PostsTop />} />
          </Routes>
        </BrowserRouter>
  )
}
```

以上で完成です。
urlをさらに変更したい場合は、App.tsxのRoteのpathパラメータを変更すればOKです。

# 補足
React Routerはv5からv6にアップデートされたことで、かなり書き方が変わっています。
「Switch」を使った下記のようなやり方はv5以前のやり方なので、注意しましょう。
（以下、公式ドキュメントの引用）

> React Router v6 introduces a Routes component that is kind of like Switch, but a lot more powerful. 

```App.tsx
import React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'

import PostsTop from './components/posts/PostsTop'

export const App = () => {
  return (
        <BrowserRouter>
         <Switch>
          <Route path="/" exact component={PostsTop} />
         </Switch>
        </BrowserRouter>
  )
}
```


# 参考
https://ralacode.com/blog/post/how-to-use-react-router/
https://reactrouter.com/en/6.13.0/upgrading/v5#upgrade-to-react-router-v6
会社まわりは【Google  Map / Spreadsheet】で


　どうも、カーブミラーです。

　今回は、ChatGPT、関係ありませんw

　知っている情報でしたら、
　　ごめんなさい。
***
　営業の方は、
　　こちらにいらっしゃるか、
　　　わかりませんが、
　営業以外で、
　　あちこちへと訪問されている方は
　　　それなりに
　　　　いらっしゃるかと思います。

　紙メモに住所をメモして、
　　GoogleMapにその住所を手入力して
　　　その場所に向かう。

　これが、ふつう、ですよね。

　でも、
　　それが１０件以上もある！
　　　と考えたら……
***
　そこで、
　　Googleスプレッドシートに、
　　　まわる住所を
　　　　事前に記載しておくのです。

　どうせ、
　　スマホは
　　　利用するんですからね。

　スマホで、その住所録を出して、
　　ひとつの住所を選択し、
　　　タップする。

　すると、
　　フローティングメニューが
　　　現れます。

　フローティングメニューの左に、
　　GoogleMapのマークと「地図」の
　　　表示があります。

　この「地図」をタップすると、
　　GoogleMapへと
　　　住所が渡されて、
　　　　その住所が示されます。
***
　私が
　　これを知ったのは、
　　　偶然でした。

　取引先から、
　　住所録（紙）をもらって、
　　　会社まわりをしていたのです。

　最初は、
　　その住所録（紙）を
　　　使っていましたけど、
　　　　すぐにGoogleレンズで、
　　　　　撮影して、
　　　　　　スプレッドシートに。

　それで、動いていて……。

　ある日、
　　タップミスして、
　　　上記のメニューが
　　　　出てきたのです。

　それ以来、
　　それでまわって、
　　　とても効率的になりました。

　心に余裕も生まれました。
　　だって、
　　　入力は、
　　　　すでに終わっているんだから。

　みなさんにも
　　心のゆとりが
　　　ありますように。
Python3　int型をbytes型に変換する(telnetlib)

pythonによるネットワークのプログラミングを勉強中です。
初心者の私がつまづいたことを共有します。

# 概要
Python3標準ライブラリのtelnetlibを使用してネットワーク機器にスクリプトを実行します。
繰り返しの設定にfor文を使用する場合、int型の変数をbytes型に変換する必要がありますが、int型→bytes型へは直接変換できませんでした。
一度int型→str型へ変換してからbytes型に変換することで解決しました。


# サンプル
ubuntu-0でスクリプトを実行し、S1にvlan2-9を作成します。
スクリプトの記述はfor文を使用してvlanの範囲を指定します。
なお、for文を使用しないスクリプトは問題なく実行できるとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122841/1c7dd990-883d-71bc-d68d-276c67142945.png)



###### for文を使用しないスクリプト
```py
#!/usr/bin/env python3
import getpass
import telnetlib

HOST = "S1のIPアドレス"
user = input("Enter your telnet user: ")
password = getpass.getpass()

tn = telnetlib.Telnet(HOST)

tn.read_until(b"Username: ")
tn.write(user.encode('ascii') + b"\n")
if password:
    tn.read_until(b"Password: ")
    tn.write(password.encode('ascii') + b"\n")

tn.write(b"conf t\n")

###ここをfor n in range()にする###
tn.write(b"vlan 2\n")
tn.write(b"vlan 3\n")
tn.write(b"vlan 4\n")
tn.write(b"vlan 5\n")
tn.write(b"vlan 6\n")
tn.write(b"vlan 7\n")
tn.write(b"vlan 8\n")
tn.write(b"vlan 9\n")

tn.write(B"end\n")
tn.write(b"exit\n")

print(tn.read_all().decode('ascii'))
```
###### for文を使用したスクリプト
19行目以降のvlan 2-9の作成をfor n in range()に書き換えています。
```py
#!/usr/bin/env python3
import getpass
import telnetlib

HOST = "192.168.255.108"
user = input("Enter your telnet user: ")
password = getpass.getpass()

tn = telnetlib.Telnet(HOST)

tn.read_until(b"Username: ")
tn.write(user.encode('ascii') + b"\n")
if password:
    tn.read_until(b"Password: ")
    tn.write(password.encode('ascii') + b"\n")

tn.write(b"conf t\n")

###ここをfor n in range()にする###
for n in range (2,10):
    n = str(n).encode('ascii')
    tn.write(b"vlan " + n + b"\n")

tn.write(b"end\n")
tn.write(b"exit\n")

print(tn.read_all().decode('ascii'))
```

## ポイント
Telnet.writeはbytes型で記述する必要があるため、for n(int型)をbytes型に変換する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122841/1a6c1ad9-dd98-4c03-3271-4d3743aa1823.png)

しかしint型→bytes型に直接変換すると数字に変換できません。
```py
###ここをfor n in range()にする###
for n in range (2,10):
    n = bytes(n)
    tn.write(b"vlan " + n + b"\n")
```
```py
S1(config)#vlan ^@
% Incomplete command.

S1(config)#^@
S1(config)#
S1(config)#vlan ^@
% Incomplete command.
```

for文を使用しないスクリプト(15行目)では、str型→bytes型に変換して問題なく実行できています。

```py
tn.write(password.encode('ascii') + b"\n")
```
int型の場合は一度str型に変換してからbytes型に変換するとうまくいきました。

```py
###ここをfor n in range()にする###
for n in range (2,10):
    n = str(n).encode('ascii')
    tn.write(b"vlan " + n + b"\n")
```

###### 実行結果
左：ubuntu-0スクリプト実行後　　右：S1の#show vlan brief
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122841/7d32606c-162f-93b0-3368-db537df95a45.png)

# 学んだこと
少し古い動画で勉強していたのですが、動画はPython2を使用していました。
python2ではTelnet.writeはstr型で記述するためbytes型に変換する必要がなく、シンプルにstr(n)で実行できていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122841/6ca27a65-7ea0-c90e-dd8f-edcd412e1587.png)
Pythonに限らず、調べるときはバージョンを確認することが大切だな、と改めて実感しました。
自分用学習コーディング規約（Nextjs）

## なぜコーディング規約が必要とされるのか
保守性や可読性を確保することを目的として設定する
例として以下
- コーディングスタイル(改行、空白、名前などのルール)
- プログラム(画面、バッチ、帳票、APIなど)の標準的な作り方
- プログラムを作る上での推奨事項、禁止事項
- その他、プログラムを作る時のルール全般(レビューの仕方やプログラムの管理方法など)

prettier eslintでカバーできる箇所は設定するのがベスト
code spell checkerなど拡張要素を取り入れるのも良し

## 命名規則
|項目  |命名規則  |例  |
|---|---|---|
|変数（useStateも含む）  |キャメルケース  |variableName  |
|定数  |スネークケース(全大文字)  |CONSTANT_NAME  |
|関数  |キャメルケース  |functionName  |
|関数の引数  |キャメルケース  |functionParameterName  |
|コンポーネント  |パスカルケース  |ComponentName  |
|定数型  |パスカルケース  |　TypeName  |


- codeSpellCheckerで波線売ってる箇所はNG
- 複数形の名詞を利用する場合
    - userやfriendが集合を表してるものであるので複数形を使う（users,friends）
    - 複数形は単語によって大きく変化するものがあるので注意すること(mouseがmiceみたいな)

## コンポーネント作成時の注意点
- React.Fragmentを使用すること

```
<React.Fragment> // <></>のように省略可（省略を推奨）
<div>
...
</div>
<div>
...
</div>
<React.Fragment/> 
```

- propsは分割代入する（jsx内でpropsを何回も書くことを防ぐ）
```
const { hoge, fuga } - props;
```

- コンポーネント内の最大ステップ数は300までとする

- 同一ファイル内で定義するとき
    - 動的に表示可否を変えるパターンがある場合、加工処理を行う場合などで関数化
    - 美的感性ではあるが、1コンポーネントが大きかったり、表示条件が多すぎるといったことで可読性の為に非常に小さいコンポーネントで切り出す場合は同一ファイルで定義する
    - 三項演算子のような分岐処理があるdom要素の場合、そのまま表示するのではなく、同一ファイル内で切り出して可読性を上げる

## 型定義
- anyは使わない
- interfaceではなく、typeを使用する　[interfaceとtypeの違い、そして何を使うべきかについて](https://zenn.dev/luvmini511/articles/6c6f69481c2d17 "")

## export
- page配下以外はexport defaultを使わない（※page配下はNextjsの制約からexport defaultにする必要がある）
- export defaultを使用した場合呼び出しもとはファイルパスさえ指定できていればその処理を取得できてしまい、バグにつながる可能性がある

## セマンティックス（適切なマークアップ）を意識
 - よく使うところだと
```
<header> <footer> <main> <aside> <nav>
```

## 三項演算子や&&演算子
-  nullなら出さない判定をするのであれば、Fragmentなどを返すより&&演算子を使う方が良い
```
entity.subTitle && <div ...>{entity.subTitle}</div>
```

## 関数コンポーネント外への定義
 - コードは順に読み下げるように書くべきなので、可能な限りコードのエントリーポイントになるrenderを先頭に書くべき
 - レンダリングされるタイミングで関数宣言や関数式は定義されるため
 :::note warn
type　Propsだけ例外でrender前に書く
:::
※renderの頭で使う為（※css in js で cssを定数定義する為にrender前に書かざるおえない）


## テンプレートリテラルに統一する
　[JavaScript の テンプレートリテラル を極める！](https://qiita.com/kura07/items/c9fa858870ad56dfec12 "")

## APIレスポンスデータ
- 開発者ツール等からレスポンスのJSONを直で読むことがまあまあある為、可読であればjsonのままで可読性の高いデータを返してもらうようにお願いする方が良い

## 外部リンク、内部リンク
- タグで判断できるのとnext/linkが対応するのに一手間必要となる
    - aタグは外部リンク
    - next/linkは内部リンク

## キャッシュ戦略
- APIのキャッシュ、コンポーネントの再描画に巻き込まれてリクエストがポンポン飛ぶようなことを避けられるので、止める必要がないなら使っておくのが良い

## Propsの型命名
下記3つに命名パターン

1. page.tsx
2. component配下のファイル
3. 上記ファイル内でのコンポーネント定義


1.2.に関してのコンポーネントではPropsと命名
コンポーネントが特定の種類のPropsを必要とせず汎用的であるため

3に関してはコンポーネント名＋Propsと命名（ex. PanelItem+Props）
関数の呼び出し方法と属性の参照方法について

# はじめに

Pythonの関数の呼び出し方法と属性の参照方法の違いについて
分からなっかので備忘録として記載してます。

※ 順次、追記予定

# 関数の呼び出し方法について

`関数名()`で`()`の中に記述する場合は、<font color="Red">**関数の呼び出し**</font>を意味します。
関数はある処理を実行するための手続きであり、`()`内には関数に渡す引数を指定することができます。
関数はその引数に基づいて特定の処理を実行します。

```example.py
print("Hello World")
# Hello World
```

```example.py
def add_numbers(a, b):
    result = a + b
    print(result)

add_numbers(3, 5)
# 8
```

# 属性の参照方法について

<font color="Red">**属性**</font>は、オブジェクトが持つデータやメソッドを表現します。
<font color="Red">**オブジェクト**</font>は、Pythonにおいてほとんどのものがオブジェクトとして扱われます。
文字列、数値、リスト、辞書、関数、クラスなど、すべてがオブジェクトです。
<font color="Red">**属性の参照**</font>では、`.（ドット）`を使用してオブジェクトから属性にアクセスします。

```example.py
my_string = "Hello, world!"
upper_string = my_string.upper()
print(upper_string)
# HELLO, WORLD!
```

* 解説
1. `my_string`という変数に文字列オブジェクト`"Hello, world!"`を代入しています。
この文字列オブジェクトには、さまざまな属性（データやメソッド）が存在します。
例えば、`upper()`というメソッドは、文字列を大文字に変換するためのものです。
1. `my_string.upper()`という形でメソッドを呼び出しています。
`my_string`はオブジェクトを指し、`.`の後に属性名である`upper`を指定しています。
1. この呼び出しでは、`upper()`メソッドが実行され、文字列オブジェクトの内容が大文字に変換されます。その結果を`upper_string`という変数に代入し、`print()`関数を使って結果を表示しています。
Microsoft Certified: Security, Compliance, and Identity Fundamentals（SC-900）資格勉強方法

Azure/Microsoft365のMicrosoft Certified: Security, Compliance, and Identity Fundamentalsに2022年8月に合格したので、勉強方法を共有します。

# 試験概要
概要まとめとしては以下3つがわかりやすくまとまっている

https://qiita.com/naganaganaga/items/1b616d591b4f002e8ad1

https://www.tsutaya-p.com/entry/2022/02/20/203038

https://www.bigriver.jp/?p=15268

# 勉強方法
日本語ベースで学習できる教材は公式のもののみ。
AZ-900（Azure Fundamentals）、MS-900（Microsoft365 Fundamentals）を取得後だとベース知識が活かせる。


## Microsoft Learn
公式にて無料で学習できる

https://learn.microsoft.com/ja-jp/certifications/security-compliance-and-identity-fundamentals/

上記Learnの内容を半日で凝縮したウェビナー
参加すると試験1回分の無料バウチャーがもらえる

https://www.microsoft.com/ja-jp/events/top/training-days/security?activetab=a1:primaryr3

無料でウェビナー形式の問題集解説
問題も多く試験範囲を網羅しているので問われる内容を理解できていれば大丈夫

https://info.microsoft.com/JA-SCITL-WBNR-FY22-09Sep-16-MKTO-FY22-SC900PrepSession-On-demand-Webinar-SRDEM85269_LP02-On-Demand-Registration---Form-in-Body.html
PhpStormおすすめ機能やショートカットキーを4つご紹介

## 一括置換

### できること

見出しの通り変数やクラス名など一括置換が行えます。

### 使い方

- 編集 → Find → パス内の置換

もしくは

- 「Shift」 + 「command」 + 「R」

### 実際の画面

置換する項目と置換後の項目が入力できる画面が表示されます。

![スクリーンショット-2022-10-05-0.11.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552607/c5defe7b-887a-cc83-73b8-9c712cd8c580.jpeg)

## どこでも検索（Search Everywhare）

### できること

下記項目を検索することができます。

- ファイル名
- クラス名・メソッド名
- PhpStormのウインドウや機能
- 設定(preference)の項目名
- 定数・変数・HTMLのID/クラス・CSSのセレクタ

### 使い方

- 「Shift」を二回押すのみ

### 実際の画面

検索フィールドと最近開いたファイルのリストが表示されます。

![スクリーンショット-2022-10-05-0.14.10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552607/4091546d-193f-f581-661d-3a35ea6effc0.jpeg)

## ２つのファイルを比較する

### できること

見出しの通り2つのファイルを比較できます。
例えば、バグが出たときに原因を追究するために使えます。

### 使い方

1. プロジェクトツールウィンドウで、比較するファイルを選択
2. 右クリック → 「compare with」 → 比較対象のファイルを選択

もしくは

1. プロジェクトツールウィンドウで、比較するファイルを選択
2. 「command」 + 「D」 → 比較対象のファイルを選択

### 実際の画面

ファイルごとの差分がわかりやすい

![スクリーンショット-2022-10-05-0.24.24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552607/3bf4427d-27f1-a6a1-5597-40d4490287f1.jpeg)

## 同じ要素を選択(短径検索)

### できること

短形検索し一括置換が行える

### 使い方

- 「command」+「Shift」+「8」

### 実際の画面

その箇所だけ変更したい場合便利

![スクリーンショット-2022-10-05-0.29.06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552607/6a4484d2-e682-0e66-ee8c-5244d2d28ec1.jpeg)

## 参考

https://pleiades.io/help/phpstorm/quick-start-guide-phpstorm.html
HardhatのgetDefaultProvider関数は、Mumbaiを標準サポートしていない

<h3>背景</h3>
OpenseaのDocumentを、PolygonのテストネットMumbaiに書き換えながら、
実施しているときにおきたエラー。

このあたり
https://docs.opensea.io/docs/minting-from-your-new-contract-and-improvements

<h3>課題</h3>
Hardhat内にある、Ethersライブラリにある「getDefaultProvider関数」では、
Mumbaiを標準サポートしていない。

そのため、FallbackProviderとして、Infuraを補助的に使うことで、実装できたので、メモ

<h3>解決策</h3>
コード全体の記載がある記事がWeb上になかったため、記載する。

Alchemyだけでなく新たにInfuraにも登録し、こちらでAPIを準備して、2つ共のAPIを使う形で、解決した。

```helper.js
function getProvider() {
    const alchemyProvider = new ethers.providers.AlchemyProvider(
        getEnvVariable("NETWORK"),
        getEnvVariable("ALCHEMY_KEY")
    );
    const infuraProvider = new ethers.providers.InfuraProvider(
        getEnvVariable("NETWORK"),
        getEnvVariable("INFURA_KEY")
    );
    return new ethers.providers.FallbackProvider([
        { provider: alchemyProvider, priority: 1 },
        { provider: infuraProvider, priority: 2 },
    ]);

    // return ethers.getDefaultProvider(getEnvVariable("NETWORK", "maticmum"), {
    //     alchemy: getEnvVariable("ALCHEMY_KEY", undefined),
    // });
}
```

ソースコード全体はこちら
https://github.com/EngineeredReiwa/nft-tutorial/tree/5fb2e7a7b268a3db1b1fa13a98221b6a162f8995



<h3>参考</h3>
こちらのやり方を、ほぼ真似させていただいた。

https://zenn.dev/thanai/scraps/ecfc7c1197cdfa

書き方は、こちらの質問者を真似させていただいた。

https://ethereum.stackexchange.com/questions/135961/use-ethersjs-to-connect-to-either-alchemy-or-infura-depending-on-availability

こちらのやり方は、実装できなかった。providerを関数として定義できている筈だが、エラーで弾かれた。
（エラーの内容を、補足で記載））

https://github.com/ethers-io/ethers.js/issues/1546#issuecomment-835542565

``` helper.js
import { Network } from "@ethersproject/networks";

const maticmum: Network = {
    name: 'maticmum',
    chainId: 80001,
    _defaultProvider: (providers) => new providers.JsonRpcProvider('rpc-url')
}

const provider = ethers.getDefaultProvider(maticmum);

function getProvider() {
    return provider(getEnvVariable("NETWORK", "maticmum"), {
        alchemy: getEnvVariable("ALCHEMY_KEY"),
    });
}
```

``` terminal
$ npx hardhat check-balance
An unexpected error occurred:

TypeError: provider is not a function
    at getProvider (/Users/user/Projects/nft-tutorial/scripts/helpers.js:45:12)
    at getAccount (/Users/user/Projects/nft-tutorial/scripts/helpers.js:54:9)
    at SimpleTaskDefinition.action (/Users/user/Projects/nft-tutorial/scripts/deploy.js:28:25)
    at Environment._runTaskDefinition (/Users/user/Projects/nft-tutorial/node_modules/hardhat/src/internal/core/runtime-environment.ts:330:35)
    at Environment.run (/Users/user/Projects/nft-tutorial/node_modules/hardhat/src/internal/core/runtime-environment.ts:163:25)
    at main (/Users/user/Projects/nft-tutorial/node_modules/hardhat/src/internal/cli/cli.ts:277:17)
(node:4479) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)

```