OmniAICreator/Qiita-1.07M huggingface dataset:
Pandas DataFrame.to_sql()でカラムの型を指定する

# 環境
python3.8.10
PostgreSQL 12.14　(少し古い)
pandas 1.3.5
SQLAlchemy 1.4.46

# あらすじ
pandasのDataFrameをそのままテーブルとしてデータベースに格納したい。
そんな時、1つの方法としてSQLAlchemyを使う方法がある。
しかし、テーブルにする時に明示的に型指定をしていなかったために他のクエリでエラーを吐いてしまった。

# DataFrame → テーブル
```python
import pandas as pd
import psycopg2
from psycopg2.extras import DictCursor
from psycopg2.extras import execute_values
from sqlalchemy import create_engine


def insert_table_from_dataframe(df, table_name):
    """
    dataframeをDBに格納
    """
    # データベースの接続情報
    connection_config = {
        'user': 'ユーザー名',
        'password': 'パスワード', 
        'host': 'ホスト名',
        'port': 'ホストが指定するポート番号', 
        'database': 'データベース名'
    }

    engine = create_engine('postgresql://{user}:{password}@{host}:{port}/{database}'.format(**connection_config))

    # PostgreSQLに書き込む
    df.to_sql(table_name, con=engine, if_exists='append', index=False)
    return
```

こんな形でデータベースに接続してテーブルに書き込む。
しかし、これだと型をどのコードでも指定しておらず、カラムの型が何になっているか不明。
実際に確認すると、大体はよしなにやってくれるのだが、IPアドレスをINET型で格納して欲しいのにTEXT型になってしまった。

# 解決法
```python
from sqlalchemy.dialects.postgresql import INET

# PostgreSQLに書き込む
df.to_sql(table_name, con=engine, if_exists='append', index=False, dtype={'ip': INET})
```
まず、sqlalchemyではデータベースに合わせて型を読み込むことができる。
全てのデータベースで共通して利用できる型名があり、それは https://docs.sqlalchemy.org/en/14/core/type_basics.html に書いてあるので参照されたい。
その場合には、`from sqlalchemy import types`を加え、`types.Integer()`のような形で指定する。


データベース固有の表現を使いたい場合は、上記のようにデータベースごとにある型を読み込み、dtypeでカラム名とセットで指定する。
dialectsについては https://docs.sqlalchemy.org/en/20/dialects/ に詳細がある。
Rubyでハッシュを使ってみた。

# 注意
AtCoderの[abc261_C - NewFolder(1)](https://atcoder.jp/contests/abc261/tasks/abc261_c)のネタバレあり。

# ACしたコード
```Ruby
n = gets.to_i
# puts n
s = readlines
# puts s

count = {}
s.each do |b|
	if count[b]==nil then
		count[b]=1
	else
		count[b]+=1
	end
		if count[b]>=2 then
			str="#{b.chomp}(#{count[b]-1})"
			puts str
		else
			puts b
		end
	end
```
<b>実行結果</b>
入力例 1:
5
newfile
newfile
newfolder
newfile
newfolder

実行結果 1:
newfile
newfile(1)
newfolder
newfile(2)
newfolder(1)

出力例 1:
newfile
newfile(1)
newfolder
newfile(2)
newfolder(1)


入力例 2:
11
a
a
a
a
a
a
a
a
a
a
a

実行結果 2:
a
a(1)
a(2)
a(3)
a(4)
a(5)
a(6)
a(7)
a(8)
a(9)
a(10)

出力例 2:
a
a(1)
a(2)
a(3)
a(4)
a(5)
a(6)
a(7)
a(8)
a(9)
a(10)
# ACするまでの道のり
・[ハッシュの基本的な使い方](https://www.sejuku.net/blog/11357)を写経してみた。
```Ruby
hash1 = {"Ruby" =>0, "Pyson" =>0}
p hash1["Ruby"]
p hash1["Pyson"]

hash1["Ruby"]+=1
p hash1["Ruby"]
```
<b>実行結果</b>
0
0
1

・同じ文字列があればカウントするという問題なのでカウントできるようにしてみた。
```Ruby
hash={}   #ハッシュの初期化

a.each do |b|
    if hash[b]==nil then
        hash[b]=1
    else 
        hash[b]+=1
    end
    p "#{b}の値は#{hash[b]}"
end
```
<b>実行結果</b>
"Rubyの値は1"
"Pysonの値は1"
"Rubyの値は2"
"PHPの値は1"
"Rubyの値は3"
"Pysonの値は2"

・[Rubyの条件分岐でthenを使うのが気になったから調べてみた。](https://teratail.com/questions/222247)

・[ACしたコードの条件分岐にchomp関数を使っていなかったので改行が入っていてACできなかった事に気づいた記事](https://www.javadrive.jp/ruby/string_class/index10.html)
・[chomp man](https://docs.ruby-lang.org/ja/latest/method/String/i/chomp.html)
・ACしたコードのputsをpと書いていたので実行結果にダブルクォーテーションが付いていてACにならなかったのでputsとpの違いについてopenAIに聞いてみた。
Q.pをputsに変更したらダブルクォーテーションがなくなる理由を教えてください。


A.pメソッドは、引数として渡されたオブジェクトを可読性の高い形式で出力するために使用されます。pメソッドに文字列を渡すと、文字列がダブルクォーテーションで囲まれて出力されます。一方、putsメソッドは、渡されたオブジェクトの文字列表現を単に出力するため、ダブルクォーテーションを含む文字列でも、ダブルクォーテーションは取り除かれます。
したがって、pメソッドをputsメソッドに置き換えることで、出力結果からダブルクォーテーションが自動的に取り除かれることになります。


Q.pはデバック用ですか？

A.
はい、pメソッドは主にデバッグ目的で使用されることが多いメソッドです。pメソッドを使うことで、デバッグ中に変数の値や式の評価結果を出力し、コードの挙動を理解することができます。pメソッドは、引数として渡されたオブジェクトを出力するだけでなく、そのオブジェクトのクラス名やメソッドなどの情報も出力するため、デバッグに役立ちます。
一方で、pメソッドはデバッグ以外の用途でも使用することができます。例えば、配列やハッシュなどの複雑なデータ構造を出力する場合にも便利です。しかし、実際のプログラムで使用する際には、出力される情報が不要な場合や、出力される情報が読みにくい場合もあるため、適宜pメソッドとputsメソッドを使い分けることが望ましいです。
Teamsで離席しても離席にしない(メモ)

放置しても離席にならない。
エクセルのA1をセレクトし、「下キー」入力、またA1にセレクトする処理
※・キーボードによるかもしれないが、numLockをオフにする必要がある
　・「下キー」が入力されるので、一時的に作業する際は、Stopする必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/e8b00e5b-f484-8ad2-6e15-a29c42933efa.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/aea56cd6-af41-a32c-3c12-dda012c74f69.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/6ac643d9-b355-6c77-f103-7da4ecd8097a.png)


ボタンは『フォームコントロールコントロール』

```vb:メイン処理

Dim Stop_flg As Boolean
'Startボタンの処理
Sub Start_Click()

  Dim time As Date
  time = Range("C3").Value
  Range("C3").Interior.Color = RGB(77, 233, 110)  'タイマーの色を緑にする
  Stop_flg = False

  Do While time > "00:00:01"

    
    '''カウント処理　以下の処理だとExcelのボタン操作を受け付ける'''
      Dim cunt_st As Double
      Const cunt_ed As Double = 1
      '待ち時間の開始時間の取得
      cunt_st = Timer
      '開始時間から停止時間数値を超えるまで無限ループ
      Do Until Timer - cunt_st >= cunt_ed
        DoEvents
        If Stop_flg = True Then Exit Do
      Loop
      If Stop_flg = True Then Exit Do
    
    '表示用のタイマー更新
    time = DateAdd("s", -1, time)
    Range("C3").Value = time
    
    '疑似操作の処理A1を選択し、下キー入力
    Range("A1").Select
    SendKeys "{DOWN}"

  Loop
  Range("C3").Interior.ColorIndex = xlNone  'タイマーの色を元に戻す

End Sub

'Stopボタンの処理
Private Sub Stop_Click()
 Stop_flg = True

End Sub

'+1分ボタンの処理
Sub Plus1min()
Dim time As Date
time = Range("C3").Value
time = DateAdd("n", 1, time)
Range("C3").Value = time

End Sub

'-1分ボタンの処理
Sub Minus1min()
Dim time As Date
time = Range("C3").Value
If time < "00:01:00" Then
  time = "00:00:00"
Else
  time = DateAdd("n", -1, time)
End If

Range("C3").Value = time
End Sub

'+10分ボタンの処理
Sub Plus10min()
Dim time As Date
time = Range("C3").Value
time = DateAdd("n", 10, time)
Range("C3").Value = time
End Sub

'　-10分ボタンの処理
Sub Minus10min()
Dim time As Date
time = Range("C3").Value
If time < "00:10:00" Then
  time = "00:00:00"
Else
  time = DateAdd("n", -10, time)
End If

Range("C3").Value = time
End Sub
Sub Reset()
Range("C3").Value = "00:00:00"

End Sub


```
[ggplot2]ナノポアフローセルのmux scan結果を可視化する


Oxford Nanopore Technologiesのナノポアシーケンサーでシーケンシングする際、ポア (pore) の活性を検査するmux scanが定期的に行われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689564/96538367-0586-ab47-7ebd-60927c7288f6.png)
Pore activityの推移は、ランの成功度合いを測る重要な指標。
MinION Software for Mk1b (MinION Release 22.12.7) を使用した場合、mux scanの結果は
```data/(run name)/(sample name)/(run id)/other_reports/pore_scan_data_(flow cell name).csv```
にCSV形式ファイルとして保存されている。
この結果を(ONT純正のプロットと似た配色で) ggplot2で可視化する。
```R
# Set working directory
 setwd("C:/path/to/dir/")

# Import required libraries
library(dplyr)
library(ggplot2)
library(scales)

df <- read.table("pore_scan_data_FAVNNNNN_XXXXXXXX_XXXXXXXX.csv", sep=",", header = TRUE)

df_subset <- subset(df, select=c(seconds_since_start_of_run, mux_scan_assessment))
df_subset$mux_scan_assessment <- factor(df_subset$mux_scan_assessment, levels = c("other","zero","multiple","saturated","unavailable","reserved_pore","single_pore"))

png("mux_scan_assessment.png", height=800, width=1200,res=150)
ggplot(data = df_subset, aes(x = as.factor(seconds_since_start_of_run), fill = mux_scan_assessment)) +
    theme_classic() +
    geom_bar(position = "fill") + scale_y_continuous(expand = c(0,0), labels = scales::percent) +
    xlab("Seconds since start of run") + ylab("Percentage") + 
    scale_fill_manual(values = c("#000000","#90c6e7","#f57e20","#68767e","#54b8b1","#ede797","#00cc00"))+
    theme(axis.text = element_text(size = 8), axis.title = element_text(size = 12), axis.text.x = element_text(angle = 45, hjust = 1))
dev.off()
```
![mux_scan_assessment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689564/983c3fba-1c25-d174-2a44-514880c6e5e8.png)
[秒を時間:分に直すのが面倒そう](https://stackoverflow.com/questions/27312292/convert-seconds-to-days-hoursminutesseconds)なのでひとまずこれでよしとする。
UipathでOffice 365ファイル操作（ダウンロード）

# パッケージのダウンロード
パッケージの管理から「オフィシャル」を選択し、「MicrosoftOffice365.Activities」を検索します。
出てきたパッケージのインストールが完了するとアクティビティが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206537/e99d1160-8af4-6da7-6946-7a0b70e6f1ac.png)

# 認証とログイン
Microsoft Office 365スコープを使用することでOffice365とUipathの間で接続を行う事が出来ます。
接続方法の詳細については公式のリファレンスを確認してください
[Microsoft Office 365 スコープについて（Uipath公式）](https://docs.uipath.com/activities/lang-ja/docs/microsoft-office-365-scope)

# ファイルやフォルダーを探す
SharePoint上にダウンロード・アップロードする為には、まず「ファイルやフォルダーを探す」で該当のフォルダやファイルを検索して「DriveItem型」として取得する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206537/1721f087-c8ac-f420-eb2e-5adb17c0a983.png)
詳細は[公式リファレンス](https://docs.uipath.com/activities/lang-ja/docs/office365-find-files-and-folders)に記載がありますが、最低限必要なプロパティは以下になります。
・クエリ
　- 検索したいファイル・フォルダを入力
・サイトURL
　- Office365上のURLを入力
・ドライブ名
　- Office365上のドライブ名を入力
・出力（最初/結果）
　- 検索で出力されたDriveItem型のデータを格納する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206537/e8999cc0-dd7a-8809-533d-27c384ac32c6.png)


# ダウンロード
　「ファイルやフォルダーを探す」で該当のフォルダやファイルを検索して出力された「DriveItem型」のデータを元にダウンロードを行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206537/372b3d42-cf5e-7a3a-6995-d2e606315fa7.png)
こちらも詳細に関しては[公式リファレンス](https://docs.uipath.com/activities/lang-ja/docs/office365-download-file)に記載があります。

・入力
　→「ファイルやフォルダーを探す」で出力した「DriveItem型」を参照入力します。　
　　出力（結果）で出力した際は配列となっている配列の番号を合わせて指定する必要があります。
・ローカルファイルパス　
　→ダウンロードしたファイルの保存先を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206537/53fa79d9-9c30-629b-bfa3-e03eb0c073d9.png)
AWS OLAPとOLTPの違い

簡単にいうと。。
トランザクション処理をするのがOLTP,分析処理をするのがOLAP

※トランザクションとは、
小さいサイズのデータ処理のこと。


具体的にいうと。。

[OLTP(オンライントランザクション処理)データベース]

トランザクション処理を行うことを目的にしたデータベース。
日々のデータを確実に登録し、小さいデータ取得依頼に対して迅速に応えることに特化。

大量に発生する読み書きアクセスに対して同時に実行する機能を持っている。

有名なのは、OLACLEデータベース。


[OLAP(オンライン分析処理)データベース]

分析処理を行うことを目的としたデータベース。
(分析処理。。複数のテーブルの情報を繋げて、集計などの分析を行うこと)

大量の読み書きアクセスに対してOLTPのように同時実行することは不向き。
大量データに対しての処理に特化している。



調べてみて。。
似ている用語だがまったくの別の処理を行うシステムなので混同しない様に気をつけよう。。
laravel larastanを導入してみる

# 概要

- laravel用PHPStanのlarastanを導入してみる。

# 前提

- 各バージョンが下記以上であること
    - PHP: 8.0
    - laravel: 9.0

# larastan（PHPStan）はプロジェクトの途中でも入れられる

- level0から始められる
    - まずは0からスタートして出たエラーを解消 → レベルを1にして出たエラーを解消という様に段階を踏める
    - [レベル](https://phpstan.org/user-guide/rule-levels)
- ベースラインファイルがある
    - 「〇〇より前に作成されたファイルはエラーが出ても無視します」的な事ができるっぽい
    - [ベースライン](https://phpstan.org/user-guide/baseline)

# 方法

1. 下記コマンドを実行してlarastanをインストールする。（下記で指定しているバージョンの`2.0`はlaravelのバージョンによって指定を変える必要あり。larastanのバージョンは[こちら](https://github.com/larastan/larastan?tab=readme-ov-file#supported-laravel-versions)で確認できる）

    ```bash
    composer require nunomaduro/larastan:^2.0 --dev
    ```

1. アプリケーションルート（アプリ名ディレクトリ）にphpstan.neonファイルを新規作成して追加する。（一旦Stanのレベルは5とした。）

    ※`includes`の書き方がlarastanのバージョンによって異なるので注意詳細は[こちら](https://github.com/larastan/larastan?tab=readme-ov-file#-getting-started-in-3-steps)

    ```アプリ名ディレクトリ/phpstan.neon
    includes:
        - ./vendor/nunomaduro/larastan/extension.neon

    parameters:

        paths:
            - app/

        # Level 9 is the highest level
        level: 5
    ```

1. アプリ名ディレクトリ（Docker使っている場合はDockerコンテナに入り）に移動して下記コマンドを実行すると静的解析を実行する事ができる。

    ```bash
    ./vendor/bin/phpstan analyse
    ```

# 参考文献

https://github.com/nunomaduro/larastan
git reset 

# git reset
```
git reset--hard コミット 
git reset コミット 
git reset--soft コミット 
```
git resetに```コミットを引数```として与える（ファイル名を与えない）と、指定したコミットを履歴の最新のコミットとし、それ```以降のコミットを捨てる```。たとえば下のような履歴があって、いま HEADが Eを指しているとき、 git reset Cとすると、 Dと Eのコミットが捨てられて、 HEADは Cを指すようになる。

—『わかる Git』冨永和人著
# 出典
https://a.co/9Q9O9QA

# git reset --hardとは
「--hardオプションをつけると、```ステージと作業ツリーの内容も指定したコミットの内容で上書き```される。」

—『わかる Git』冨永和人著
# 出典
https://a.co/bczUeRk
# 気づき
ローカル環境のファイルまで影響するので気をつけよう
# git reset --softとは
「ない。--softオプションは、```ステージも作業ツリーも内容をそのまま```にする。」

—『わかる Git』冨永和人著

# 参考記事
https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe

# 感想
gitの```hard```や```soft```で捨てられる内容が変わってくるのか。
バリデーションのエラーメッセージを日本語化する方法

## はじめに

バリデーションを日本語化する備忘録です。
実装手順を解説します！

## 実装

まず、gemfireに追記、

```
gem 'rails-i18n'
```
こちらが日本語化するgemです。


カラム名が英語のままだと思うので、
config/locales/ja.ymlに記述します。

```
ja:
  activerecord:
    attributes:
      board:
        name: 名前
        title: タイトル
        body: 本文
```
ここでテーブル名とカラム名は、自分の使っているものを使用して下さい（今回はboardとname,title,body）


これで完了です！

## おわりに

今回は日本語化する方法を実装しました！
ありがとうございました！！！
TwitterでRaspberryPiのBOTツイートを回避して幸せになる

## はじめに
RaspberryPiを使用してセンサー取得データを定期的にTwitter APIでツイートしている方は大勢いると思う。
だがちょっと待ってほしい単にTwitterでRaspberryPiの最新情報が見たい人にとってはBOTたちの定期ツートがとても厄介な存在になる。
特に定期ツイートが多くなる時間の節目などは一気にログが流れていく。
何か共通のハッシュタグ（例：#ラズパイBOT）をつけるような文化が定着すれば良いのではと思うがそれではあまりに他力本願すぎると思った。
（親切な方はBOTである旨をハッシュタグに入れてくださっている場合もある）
ではこんなBOTたちのツイートを回避するにはどうしたら良いのか。

## そこで少し考えてみる
Twitterのフィルター機能は非常に優秀で簡単に複雑なフィルターをかけることができる。
また大抵のBOTはセンサーからの情報、大抵の場合は気温や湿度などの測定値をテキストで入れている場合が多い。
ここに着目して以下のようなフィルターの内容を考えてみた。
```
RaspberryPi OR ラズパイ -室温 -温度 -気温 -湿度 -bot
```
これが今の所自分にとって最適解だ。

実は当初以下のようなフィルター設定にしていた。
```
Raspberry OR RaspberryPi OR ラズパイ -温度 -気温 -湿度 -bot
```
これは"Raspberry Pi"というツイートを拾いたかった意図がある。
だがこのフィルターの場合果物のRaspberryに関するツイートやアカウント名にRaspberryを入れている人も拾ってしまい具合が悪かった。
Nextjsのpublicパスの変換

同じドメインでpathによってサービスを変更することってよくあると思います。
その時にNextjs内で使用しているpublicのpathはデフォルトで`/_next/`なので、
最初のリクエストは正常に動作するのに、その後のファイルのロードなどでエラーになってしまった経験ないですか？
私は何回かあります。そんな時に使用できるtipsです。

手順は簡単で、next.config.jsに以下の内容を追加するだけです。
```javascript
const nextConfig = {
  assetPrefix: "/hoge", // hogeはなんでも良くて適当なpathです
  rewrites() {
    return [
      {
        source: "/hoge/_next/:path*", // /hoge/_next/に来たものは/_next/にURLを書き換える
        destination: "/_next/:path*",
      },
    ];
  },
};
```

上記のようにすると `/_next/`のURLをユーザに届ける際に`/hoge/_next/`に変換されます。
そしてユーザが`/hoge/_next/`にリクエストをしてくると、Nextjs内部では`/_next/`に変換してくれるので
正常に動作するようになります。

もっと上手く華麗に解決できる方法あれば教えてください！
フェッチ

# フェッチ
「Aさんが公開しているリポジトリ Oをクローンして、ローカルに持ってきたとする。その時点では、自分のローカルリポジトリ Xの内容は、 Aさんのリポジトリ Oの内容と同じだ。その後、 Aさんが開発を続けて、新しい内容をリポジトリ Oにプッシュすると、リポジトリ Oの内容がリポジトリ Xの内容と違う状態になる。こうなると、```リポジトリ Oの新しい内容を Xに持ってきたくなる```。そのための操作が、ブランチのフェッチだ。ブランチのフェッチは、```ブランチのプッシュの逆の操作```。リモートリポジトリの指定したブランチを、ローカルリポジトリの対応するブランチの先に接ぎ足す。」

—『わかる Git』冨永和人著

https://a.co/5tTCT3c

「ネットワークの先にあるリポジトリを扱う。そういうリポジトリを```リモートリポジトリ```という。それに対して、手元にあるリポジトリを```ローカルリポジトリ```と呼ぶ。」

—『わかる Git』冨永和人著

https://a.co/aL52QkV

# 感想
フェッチが何なのか知らなかった。
プッシュの反対の操作なのか。
マクロ チェックを外す

①開発タブのマクロの記録を選択

![スクリーンショット 2023-03-10 16.05.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/58a80f7c-e42f-18aa-696f-31c996278dd6.png)
②名前を付けてOK

![スクリーンショット 2023-03-10 16.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/a79086e6-2d14-b354-c240-17d9e1af5da0.png)
③ホームタブの書式クリアを選択
ここで、書式がリセットされます。

![スクリーンショット 2023-03-10 16.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/af33372d-af0c-3d2d-8476-d004d36bfd72.png)
④下記画像の格子を選択
③で周りの線も消してしまっているため、また複数選択した時も、全て線を引かれるように格子を選択

![スクリーンショット 2023-03-10 16.07.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/8ea16537-8434-5cbf-5f44-9a614a04ef5e.png)

⑤開発タブのマクロ終了を選択
元に戻したいセルを選び、マクロを選択して、使ってみましょう！

![スクリーンショット 2023-03-10 16.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/1936c9b7-e45f-f47b-3121-70b5440a7677.png)

![スクリーンショット 2023-03-10 16.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/52b803da-eaa3-4359-b816-63fbd2430f2e.png)

⑥戻りました👏

![スクリーンショット 2023-03-10 16.14.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/5c012729-66e7-991d-e086-212bb8f9eff3.png)

⑦以前と同じで、開発タブのボタンを使用して、ボタンを作ってみよう👍
ショートカットを設定したい人もやっちゃいましょう！

![スクリーンショット 2023-03-10 16.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160498/4cf04f9a-77d2-5ed9-e31f-17acbeb69659.png)

補足
ボタンの大きさ変更時、opitionキーを押しながら行うとグリッドに合わせて、大きさを変更してくれます🙆
Cloud9上でPrismaStudioを起動する

# 経緯
先日、仕事で利用しているMacのバッテリーが不調になったため、1週間ほど修理に出しました
その間、あまり仕事にならず、、、😢

ということで、パソコンでのローカル開発から徐々にCloud9インスタンス上での開発に移行させています
EC2上にCloud9(Web経由で使えるIDE)を立ち上げて、そこにDocker、nodejs、Amplify、CDKなどを導入しクラウド上にずいぶん便利な開発環境を構築できてきました

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

先日Prismaも導入しようとインストールしましたがそこで問題が起こりました


# 前提知識
## Prisma
Prismaは、Typescriptで利用できるORMツールです
私の場合は既存のデータベーススキーマを読み込ませて、オブジェクトの形でデータを取得したり更新したりするのに利用しようと考えました

実際使ってみるととても便利です

https://www.prisma.io/

GraphQL APIなども作ってくれそうなのでどんどん活用してみたいと思っています

# 課題
PrismaにはPrismaStudioというWeb画面上でデータベースのスキーマやレコードを操作できるツールがついています

https://www.prisma.io/studio

PrismaStudioは http://localhost:5555 で立ち上がるのですが、Cloud9で利用できるポートは8080-8082ポートでしかプレビューできない仕様になっており、5555ポートは閉じられています

https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/app-preview.html

さて、どうしたものか・・・・🤔

# 対策
考えられる対策としては２つです

1. Nginxでポートフォワーディングさせる
1. VncサーバをCloud9サーバで立ち上げてリモートデスクトップ上で5555ポートにアクセスする

Cloud9上でVncサーバを立ち上げる方法については以下の記事を参考にすれば実現できそうです

https://qiita.com/nasuvitz/items/f34c5cd100c03673e567

ただ、VncサーバをCloud9上に立てるのはまた色々と大変そうな気がしたので今回はnginxを利用してポート転送する方法を行ってみました

# 手順
ここからはAmazon Linuxを想定して記述しています
Cloud9のTerminalから実行していきます

## nginxをインストール
```
sudo yum install nginx
```

## nginx.confを編集する
ポート8080へアクセスされるとポート5555に転送するように設定します
```/etc/nginx/nginx.conf
server {
    listen       8080; # ポート80から8080に変更
・・・
    # 以下3行を追記
    location / {
                proxy_pass http://localhost:5555;
    }
}
```

## PrismaStudioとNginxを起動する
```
sudo nginx
npx prisma studio
```

あとはCloud9の"Preview Running Application"でPrismaStudioが起動します

## 終了
使い終わったらTerminal上でCtl-CでPrismaStudioから抜けたあと、nginxを停止します
```
sudo nginx -s stop
```

簡単ですね

# まとめ
まだまだCloud9を利用している方が少ないのか、こうしたポートフォワーディングについて触れている記事が見つかりませんでしたので参考になればと思います

今後クラウド上で開発を進める方法は広がりそうな予感です
コンテナ稼働のtensorflow2系でmodel.loadはできたけどmodel.predictでコンテナが落ちる原因について

# 全体構成
AWSでAIを用いたWebサービスを運営しています。
構成は大まかにはEC2(g4dn.xlarge) on ECSで ECS上にflaskコンテナとjobコンテナを配置しています。
タスク定義にて、適当な量のvCPUを割り当てて、g4dnのGPUはjobの方にアタッチしています。
コンテナ間通信によって、flaskから画像をjobに投げるとjobの中のAIが動いていろいろ推論して、結果を返します。

jobの中にはfastapiサーバを立ててます。サーバ起動と同時に３つのmodelがloadされます。
flaskからリクエストが来たら、endpointに従って対応するmodelでpredictします。
# 変化点
4つめのmodelを追加して、loadやpredictのコーディングをした。
# 起こったこと
flaskがjobと通信できていない
# 確認順序
|  確認  |  結果  |
| ---- | ---- |
|  コンテナ間通信のURLが合っているか  |  合っている  |
|  jobコンテナは生きているか  |  死んでいた  |
|  model.loadはできてるか  |  出来てた  |
|  model.predictはできているか  |  ここで死んでいた  |
# 仮説検証
|  仮説  |  策  |  結果  |
| ---- | ---- | ---- |
|  GPUメモリ不足  |  g5系に変更  | predictでコンテナ停止 |
|  CPUメモリ不足  |  タスク定義にてjobコンテナへのvCPU割当増加  | 成功 |
# 結論
GPUを用いた推論でもCPUまで疑うこと。
GitのコミットにSSH鍵による署名を行いGitHubでVerifiedマークが付くようにする

# 概要

Gitのコミットを作成したのが自分である事を証明する方法として、コミットに署名する方法が用意されているが、従来からあるGPGによる署名は正直色々と面倒くさい。
2021年11月にそれに変わる方法としてSSH鍵による署名がサポートされ、追ってGitHubでもSSH鍵によるコミットの署名の検証ができるようになった。この方法を使用すれば、GPGによる署名に比べるとかなり手軽に署名を行うことが可能になる。
備忘録としてGitのコミットにSSH鍵で署名を行い、GitHubでコミットの署名検証済み(Verified)マークが付くようにする手順を記載しておく。

## 必要なもの

- Git 2.34.0 （SSH鍵による署名がサポートされたバージョン）以降
- ssh-agentが稼働していること

後に述べるがssh-agentが稼働しており秘密鍵の登録をできることが必須。ssh-agentの設定方法はいくらでもWebに情報があるのでそちらを参考に。

## GitのコミットにSSH鍵による署名を行う

1. 署名用のSSH鍵を生成する
   ```sh
   ssh-keygen -t ed25519 -f signing-key
   ```
   `signing-key`(秘密鍵)と`signing-key.pub`(公開鍵)が生成される

2. ssh-agentに秘密鍵を登録する
   ```sh
   ssh-add signing-key
   ```
   今のところ、秘密鍵はssh-agentを通じて渡す方法しかない模様。gitのコンフィグレーションで秘密鍵ファイルを指定などは出来ないようだ。セキュリティ対策のためだろうか。

3. GitリポジトリでSSH鍵によりコミットに署名する設定を行う。
   ```sh
   git config commit.gpgsign true
   ```
   コミット時に自動的に署名を行う設定。false(デフォルト)の場合は`git commit`に`-A`オプションを付けた時のみ署名を行う。
   ```sh
   git config gpg.format ssh
   ```
   GPGではなくSSH鍵による署名を行う設定。
   ```sh
   git config user.signingkey "(公開鍵ファイルの内容)"
   もしくは
   git config user.signingkey 公開鍵ファイルのパス
   ```
   署名するSSH鍵の設定。直接公開鍵の内容を書いても公開鍵のファイルパスを指定してもよい。お好みで。
   リポジトリ単位ではなくユーザアカウント全体の設定にしたい場合は`git config`に`--global`オプションを付けてもよいだろう。

以上の設定により、gitリポジトリにコミットを作成した時にSSH鍵による署名が行われるようになる。

## GitHubに署名用公開鍵を登録する

1. GitHubアカウントの「Settings」>「SSH and GPG keys」で「New SSH key」ボタンを押す
2. 「Title」に適切な名称を入力し、「Key type」で「Signing key」を選択し、「Key」に署名用SSH鍵の公開鍵の内容をコピペして、「Add SSH key」ボタンを押す
3. アカウントの認証があるので、正常に認証を終了できれば署名用公開鍵が登録され、「SSH and GPG keys」のページの「Signing key」の一覧に表示される


## GitHubのコミットのVerifiedマークを確認する

署名付きのコミットを作成したリポジトリをGitHubにpushする。署名付きのコミットには下の画像のように「Verified」マークが付くようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22414/3fd56c0f-bb16-ed0e-23ae-f2c9f32f4772.png)
PigeonのHostApiとFlutterApiをわかりやすく理解する

　
　

こんにちわ。いせきです。最近は、あったかくなってとても過ごしやすいですね。一番好きな季節です。

今回は、PigeonのHostApiとFlutterApiをわかりやすく理解できるような記事を書いていこうと思います。



# ふわっと理解する

<b>HostApi</b>・・・Flutter→ネイティブ（iOS/Android/Windows）

<b>FlutterApi</b>・・・ネイティブ（iOS/Android/Windows）→Flutter


# コードを見ながら理解してみる
1、pigeon_schemeに記載する。

```dart:pigeon_scheme.dart
@FlutterApi()
abstract class FlutterApi {
  /// ネイティブのコードをFlutter側に伝達する
  void flutterApi();
}

@HostApi()
abstract class MessageTabCallbacks {
  /// 　Flutterのコードをネイティブ側に伝達する
  void hostApi();
}
```

２、コマンドで生成する

３、コードを書いてみる。

### HostApi
```dart
FlutterApi().flutterApi();
```


### FlutterApi
```swift
import Foundation

class HostApi: NSObject, HostApi {
    func flutterApiWithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError?>) {
       hostApi();
    }
}
```

:::note
<b>間違って記載していた場合</b>
今回のコードは実際に生成などをせずに、書いてみたので間違って記載しているかもしれません。その場合は教えていただけると幸いです。
上の<b>ふわっと理解する</b>のところまで読むことをお勧めいたします。
:::


# 最後に

少しずつ理解できるようになるだけでも成長できると思います。僕も頑張りたいです。みんなで頑張りましょう。
Graph API 二つの認証方法：passwordとclientSecret

Graph APIのアクセストークンを取得するには、二つ方法よく使うので、メモーします。
・mail&password
・clientSecret
microsoftのドキュメントを見ると、mail&passwordの認証で推奨ではないと書いています。![截屏2023-03-10 15.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/a3252b89-c824-de1d-4855-9fd2bd219e49.png)


# clientSecretでの認証（アプリケーション認証、ユーザなし）
![截屏2023-03-10 15.54.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/c7d18cc6-6bc6-98e1-05c6-84b5e46e8deb.png)

```
        var scopes = new string[] { "https://graph.microsoft.com/.default" };
        var tenantId = テナントID;

        // Configure the MSAL client as a confidential client
        var confidentialClient = ConfidentialClientApplicationBuilder
                        .Create(クライアントID)
         .WithAuthority($"https://login.microsoftonline.com/{テナントID}/v2.0")
                        .WithClientSecret(TeamsConstants.ClientSecretValue)
                        .Build();

            // Retrieve an access token for Microsoft Graph 
            var authResult = await confidentialClient
                     .AcquireTokenForClient(scopes)
                     .ExecuteAsync();
         //認証
        var authProvider = new DelegateAuthenticationProvider(request =>
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
            return Task.CompletedTask;
        });

        var graphClient = new GraphServiceClient(authProvider);
```
# mail&passwordでの認証（委任認証、ユーザあり）

![截屏2023-03-10 16.00.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/2d5a5e12-5935-b520-b1d4-5e3032b63879.png)
```
static async Task GetATokenForGraph()
{
 string authority = "https://login.microsoftonline.com/contoso.com";
 string[] scopes = new string[] { "user.read" };
 IPublicClientApplication app;
 app = PublicClientApplicationBuilder.Create(clientId)
       .WithAuthority(authority)
       .Build();
 var accounts = await app.GetAccountsAsync();

 AuthenticationResult result = null;
 if (accounts.Any())
 {
  result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                    .ExecuteAsync();
 }
 else
 {
  try
  {
   //新しいメソッドは、「SecureString」を使わなくなった。
   //var securePassword = new SecureString();
   //foreach (char c in "dummy")        // you should fetch the password
   //securePassword.AppendChar(c);  // keystroke by keystroke

   result = await app.AcquireTokenByUsernamePassword(scopes,
                                                    "joe@contoso.com",
                                                     “password”)
                      .ExecuteAsync();
  }
  catch(MsalException)
  {
   // See details below
  }
 }
 Console.WriteLine(result.Account.Username);
}
```

参考サイト：

https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS

https://learn.microsoft.com/ja-jp/azure/active-directory/develop/scenario-desktop-acquire-token-username-password?tabs=dotnet

https://stackoverflow.com/questions/75257771/how-to-create-microsoft-graphserviceclient-in-asp-net-core-web-api-6

https://tnakamura.hatenablog.com/entry/2022/07/26/delegate-authentication-provider
Db2 既存テーブルをデータごとコピーして違うテーブル名で作成するSQL

Db2でテストやデモなどで既存テーブルをデータごとコピーして同じDBの違うテーブル名で作成したくなったことがありました。
SQLを調べたのでメモっておきます。使いたい方がいるかどうかはわかりませんが。

↓こんな感じです:
```sql
CREATE TABLE SCHEMA.NEW_TB AS (
    SELECT *
    FROM SCHEMA.OLD_TB
) WITH DATA
```

- SCHEMA(スキーマ)は同じでも違っても構いません。



- ちなみに「コピー」じゃなくなりますが、一部列でも、はたまたテーブル2つをJOINしたり、　WHERE文がついていても、SELECT文が正しければその結果のテーブルが作成できます。


↓`WITH DATA`の部分を`WITH NO DATA`とすればテーブル定義は同じで空テーブルが作成できます。
```sql
CREATE TABLE SCHEMA.NEW_TB AS (
    SELECT *
    FROM SCHEMA.OLD_TB
) WITH NO DATA
```

参考:　Db2ドキュメント [CREATE TABLE ステートメント](https://www.ibm.com/docs/ja/db2/11.5?topic=statements-create-table)

以上です。
PHPの基礎

# はじめに
PHPの基礎中の基礎を忘れないための備忘録です。

# PHPの書き方
PHPはHTML内に埋め込むことで利用することができる。
```<?php ~ ?>```内に処理を書き込む。

```php:書き方
<html>
 <head></head>
 <body>
   <?php 
    処理を書く
   ?>
 </body>
</html>
```

# PHPでの出力方法
```echo```を用いることで出力が可能

```php3:使い方
<? php
 echo "太郎";
 //太郎が出力される。
?>
```

# PHPを書くときの注意
***行の終わりには;(セミコロン)をつける必要***がある。
ない場合エラーになってしまう。
Android Studio Electric EelでviewModels()やonBackPressedDispatcherが認識されない問題の解決方法


# 概要

AppCompatActivity(ComponentActivity)を継承していてもIDE上で以下のエラーが出てしまう対処方法です。
（動くけど、IDE上で赤くなる事象です）

![スクリーンショット 2023-03-10 12.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10494/29fe167c-442d-7c8d-2afd-4ef2361dfcae.png)

以前のバージョンでも以下のような問題がありましたが同じようにやれば良いです。
https://qiita.com/ko2ic/items/dce06a03131268d1d6c3

# 解決方法

ワークアランドとして、こんな拡張メソッドを用意し利用しておけば良いでしょう。ASのバグが直ったら、この処理を削除します。
当然、ComponentActivityを継承してない場合に利用すると落ちますので、気をつけましょう。

```kotlin
inline fun <reified VM : ViewModel> Activity.viewModels(
    noinline extrasProducer: (() -> CreationExtras)? = null,
    noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null,
) = (this as ComponentActivity).viewModels<VM>(extrasProducer, factoryProducer)

val Activity.onBackPressedDispatcher: OnBackPressedDispatcher
    get() = (this as ComponentActivity).onBackPressedDispatcher
```
初期値問題「[演習]微分方程式3(体系大学数学)」をwolframalphaとsympyでやってみたい。


どちらもできませんでした。

オリジナル

https://youtu.be/v2cx0NLZiP4

# wolframで
できませんでした。微妙に違いました。

https://www.wolframalpha.com/input?i=y%27%3Dcos%28x%29**3*cos%28y%29**2%2C+y%28pi%2F6%29%3Dpi%2F4&lang=ja

# sympyで
できませんでした。

```python
from sympy import *
x = Symbol  ('x',real=True)
y = Function('y')(x)
ans=dsolve(Eq(diff(y,x),cos(x)**3*cos(y)**2), ics={y.subs(x,pi/6):pi/4})
print("#",ans)
#plot (ans.rhs)
```
BFではじめる円周率計算入門 #1 -1桁どうしの乗算-

## 前回のあらすじ！
加算ってこんなに難しかったっけ(絶望)
[BFではじめる円周率計算入門 #0 -問題設定と多倍長加算-](https://qiita.com/nekoMIMI_CatEye/items/6a1d346b474f1a512c0a)

## BFで九九ならぬB-1B-1をやってみる
前回と同じようにまずは1桁どうしの場合から乗算を考えていきます。
さて、$M\times N$は$M$を$N$回加算してください、という意味になります。
そのため前回加算ができている私たちは「$N$回繰り返すこと」を新たに考えれるだけで乗算はできそうです。
さて、1桁どうしの加算のコードは次のようでした。
- 被加数:0番地
- 加数:1番地
- キャリ:2番地
- 条件分岐終了タグ:3番地

```brainfuck
>  // 加数へ移動
[
-  // 加数減算
>  // キャリへ移動
+  // 「一旦」キャリ加算
<< // 被加数へ移動
+  // 被加数加算
[  // 被加数が0でなければ
>> // キャリへ移動
-  // キャリの加算をなかったことにする
>  // ループ脱出用メモリへ移動
]
<<  // 加数へ戻る
]
```
「$0$に$M$を足すコードを$N$回繰り返したら終わり」と思ってしまうところですが、1度加算したあと, 加数のメモリの値は$0$になってしまうため、このままだと繰り返しを行うことができません。そこで加算するときに同時に加数をコピーするためのメモリを空けておいて一時保管し、復元する必要があります。
さて、では$M$をどのようにコピーするかですが、みなさん、$0+M=M$ですね。現在、「加数のデクリメントした分だけ被加数のインクリメントをする」ことで加算を実現しているのですが、$0$を格納したメモリを新たに用意して、「加数のデクリメントした分だけ**被加数と**(初期値ゼロの)**コピー用変数**のインクリメントをする」とすれば、2つの変数に対して同時に加算処理を行うことができるというわけです。
ちなみに被加数が$0$なので繰り上がりは発生しません。うれしいね。
これを追加すると、
- 被加数:0番地
- 加数:1番地
- 加数のコピー:2番地
- キャリ:3番地
- 条件分岐終了タグ:4番地

としたときのコードは次のようになります。

```brainfuck
>>  // コピー用変数へ移動
[-] // コピー用変数を0にする(コピー変数に対して、値が0になるまで減算処理をする)
<   // 加数へ移動
[
-   // 加数減算
>   // コピー用変数へ移動
+   // コピー用変数加算
>   // キャリへ移動
+   // 「一旦」キャリ加算
<<< // 被加数へ移動
+   // 被加数加算
[   // 被加数が0でなければ
>>> // キャリへ移動
-   // キャリの加算をなかったことにする
>   // ループ脱出用メモリへ移動
 ]
<<< // 加数へ戻る
]
/* 復元処理 */
> // コピー用変数へ移動
[
- // コピー用変数を1減らす
< // 加数へ移動
+ // 加数を1増やす
> // コピー用変数へ移動
]
```
上のコードのコメントを省くと下のようになります。
```brainfuck
>>[-]<[->+>+<<<+[>>>->]<<<]>[-<+>]
```
さて、これで何度繰り返しても大丈夫なようになりました。
しかし、$N$回繰り返すからと言ってこれを手動でやりたくないですよね。
そこで$N$を保管しておくためのメモリも新たに用意します。
あとは、加算するたびに加算回数をデクリメントして、0になったら終わり、のコードを追加すれば終了です。お疲れさまでした。
- 被加数:0番地
- 加数:1番地
- 加数のコピー:2番地
- キャリ:3番地
- 条件分岐終了タグ:4番地
- 加算繰り返し回数:5番地

```brainfuck
>>>>> //加算繰り返し回数格納位置へ移動
[
<<<<< //0番地から始める
>>[-]<[->+>+<<<+[>>>->]<<<]>[-<+>] //加算処理・加数復元
>>> //加算繰り返し回数格納位置へ移動
-   //残り加算回数を1減らす
]
```

3行目と4行目のはじめで相殺できる場所があるため、簡潔にして、コメントを省くと下のようになります。
これが1桁どうしの乗算というわけですね。
```brainfuck
>>>>>[<<<[-]<[->+>+<<<+[>>>->]<<<]>[-<+>]>>>-]
```

## 加算の繰り上がりと乗算の繰り上がり
さて、1桁どうしの乗算のコードを書いたわけですが、ひとつ引っかかる点があります。
それが「乗算の繰り上がりは加算の繰り上がりと同じにしていいか？」という点です。
結論から言うとこれは全く問題ありません。加算のお化けが乗算なので加算の繰り上がり処理の転用で問題ありません。
$9+9+9$をするときに$9$から$27$に向けてインクリメントし続けると$2$回繰り上がります($2$回$B^0$の位が$0$になるポイントが存在します)というのと同じことをしているわけなので。
また、繰り上がり値の上限についても$B$を超えることはありません。($(B-1)\times (B-1) < B^2$)
そのためこのコードで問題ないということがわかります。
※Tips $B$は基数
```brainfuck
>>>>>[<<[-]>[->+>+<<<+[>>>->]<<<]>[-<+>]>>>-]
```

# まとめ
加算を使えば「やること自体は」あまり難しくなかったという感じでしたが、コードの可読性はもう面影をなくしてしまいました。
さて、これで準備が整いました。次回、「大いなる敵†多倍長乗算†」それでは。
【E資格】合格体験記

## この記事は
2023年2月にJDLA-E資格を取得したので、合格までの道のりをまとめます。
今年度受ける方、今後の受験を考えている方の参考になれば幸いです！


## E資格受験前の私
●　関西の私文大学生
●　ITベンチャー企業で業務委託
●　統計検定2級合格済み
●　テーブルデータのコンペに数回出場

E資格受験前の私はテーブルデータを少し触ったことがある程度で、画像や生成等の深層学習に関する知識は全くありませんでした。

## 勉強時間・日数
私の総勉強時間は200時間です。
具体的には以下の習慣を3ヶ月ほど継続しました。
●　平日2時間
●　休日3時間

内訳は
● 認定プログラムの修了までに2ヶ月（150時間）
● 問題演習(黒本)に1ヶ月(50時間)
という感じです。

年末年始、不規則な期間もありましたが、基本的には上記の通りに進めました。

## 学習教材
● [ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585)
● [ゼロから作るDeep Learning ―自然言語処理編](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E7%B7%A8-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873118360/ref=d_pd_vtp_sccl_2_1/358-9719151-2837967?pd_rd_w=bDA9r&content-id=amzn1.sym.cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_p=cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_r=SWHEA5T6QRAJRCCPHD16&pd_rd_wg=1GnmG&pd_rd_r=ba542db2-5323-4205-a37d-b1f9d6e8aa0a&pd_rd_i=4873118360&psc=1)
● [徹底攻略ディープラーニングE資格エンジニア問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0E%E8%B3%87%E6%A0%BC%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E5%95%8F%E9%A1%8C%E9%9B%86-%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97AI%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E5%B0%8F%E7%B8%A3-%E4%BF%A1%E4%B9%9F/dp/4295009180)
● [AVILEN -全人類がわかるE資格講座](https://avilen.co.jp/course/e-certificate/)

各教材の特徴は
- ゼロツク1,2
    - メリット
         - 深層学習の基礎的なアーキテクチャについて初学者にも易しくまとめられている
    - デメリット
        - 全ての範囲を網羅できない

- avilenの動画教材
    - メリット
        - 多岐に渡り提案されているAIモデルを網羅的に学習
        - 難解な用語、仕組みを丁寧に解説している
- 黒本
    - メリット
        - 本番に近い難易度の問題を解ける
        - 解説がわかりやすい
    - デメリット
        - 分厚い(520ページ)


## 学習の手順
AIに関する知識が全くない方は**ゼロツク1,2**から始めることをおすすめします。

その理由は、
ゼロツク1,2から始めることでAIに対しての苦手意識を消すことができるからです。
ゼロツク1,2では、深層学習の**基礎的なアーキテクチャ**について学ぶことができます。E資格では多種多様なモデルが紹介されますが、ほぼ全てのモデルでこの基礎的なアーキテクチャが用いられているため後の学習がスムーズになります。

具体的には、
**ゼロツク1 → ゼロツク2 → avilenの動画教材 → 黒本**
このような手順で進めることがおすすめです。

## まとめ
以上、E資格2023#1合格体験記でした。
今年度受ける方、今後の受験を考えている方の参考になれば幸いです！
Tailwind cssを使ってみたらCSS/Vuetifyに戻りたくなくなった

## Tailwind CSSとは？

Tailwind CSSは、CSSフレームワークの1つで、クラス名を使ってスタイリングを行うことができるため、HTMLコードとCSSコードの結合を防ぎ、保守性と開発効率を向上させることができます。

CSSでボタンを作る場合、以下のようにスタイルを定義する必要があります。
```button.html
<button>Click me</button>
```

```button.css
button {
  background-color: blue;
  color: white;
  font-weight: bold;
  padding: 10px 20px;
  border-radius: 5px;
}

button:hover {
  background-color: darkblue;
}
```

一方、Tailwind CSSを使用する場合、以下のようにクラス名を追加するだけで同じデザインを実現できます。

```vue.js
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Click me
</button>

```

## CSS vs Tailwind CSS
CSSとTailwind CSSを使用する場合のメリットとデメリットをそれぞれ5つずつ挙げます。

### CSSのメリット

1. 独自のスタイルを作成しやすい
2. セレクタの優先順位を明確に理解できる
3. 既存のCSSフレームワークよりも軽量で、パフォーマンスが向上する可能性がある

全ての基礎。CSSフレームワークよりも軽量というのは確かに考えていませんでしたが、重さが大事なプロジェクトだと考慮が必要かもしれないですね

### Tailwind CSSのメリット

1. クラス名を使用して、簡単にスタイリングを行うことができる
2. ほとんどのCSSのようにファイルを分割しないため、開発効率が上がる
3. コードが短くなり、保守性が向上する可能性がある
4. 既存のスタイルを再利用できるため、開発効率が向上する可能性がある
5. レスポンシブ対応やダークモード対応にも秀でている
基本的にCSSをパワーアップさせたもののイメージです。
VuetifyやMUIほどのスピード力はないですが、CSSやSCSSと比べるとかなり早く実装ができます。
カスタマイズのしやすさもピカイチです。

### Vuetifyのメリット
1. コンポーネントベースのフレームワークであるため、再利用性が高く、開発効率が向上します
2. レスポンシブ対応、アニメーション、テーマなど、様々な機能を豊富に備えています
3. コンポーネントのデザインが統一されており、プロジェクト全体で一貫性のあるUIを実現できます
4. Vue.jsに統合されているため、Vue.jsの機能との親和性が高く、シームレスに使用することができます

デザインの一貫性と、何よりもスピードがチーターです。
ただカスタマイズがかなりしずらいため、なんとなくのデザインや個人開発、POC段階のプロジェクト、スピード重視のプロジェクトなどにはかなり向いている一方、px単位でのデザイン調整が必要なプロジェクトには向いてないかもしれません。

以上が、CSSとTailwind CSSを使用する場合のメリットとデメリットです。

個人的に本当に楽だと感じたのは、クラス名を考える手間が不要なことも挙げられると思います。

複雑なプロジェクトになればなるほど、クラス名の競合を考慮して適切なクラス名を考えなくてはならず、場合によっては以前定義したクラス名を変更する必要まであるので、この手間がなくなるのは革命的でした。

## Vue3への導入方法

Vue.js 3では、Vue CLIを使用してTailwind CSSを簡単に導入することができます。以下の手順に従って、導入を行ってください。

コマンドプロンプトを開き、以下のコマンドを実行します。

```
npm i tailwindcss@latest postcss@latest autoprefixer@latest
```

`npx tailwindcss init -p`コマンドを実行して、`tailwind.config.js` , `postcss.config.js`ファイルを作成します。

`postcss.config.js`ファイルに以下のコードを追加します。

```
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

`tailwind.config.js` 

```jsx
module.exports = {
  purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
```

`main.js`ファイルを開き、以下のコードを追加します。

```
import './index.css'
```

 `src`フォルダに`index.css`ファイルを作成し、以下のコードを追加します。

```
@tailwind base;
@tailwind components;
@tailwind utilities;

```

これで、Tailwind CSSがVue 3プロジェクトに導入されました。

## 簡単な使い方例

以下のコードは、Vue 3でTailwind CSSを使用して、ボタンを作成する例です。

```
<template>
  <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
    Click me
  </button>
</template>

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/5ef76ad5-8498-0a0d-d00e-aebe775f8182.png)



このように、Tailwind CSSを使用することで、HTMLコードに直接スタイリングのためのクラス名を追加することができます。


## 終わりに

実は最近Chat GPTなどにハマっていて、概要はほとんどNotion AIに書かせているので20分ほどで記事が完成しました。

ただちょくちょくわかりづらい説明や重複する箇所があったため、ちゃんと精査する必要はありました。

詳しくは[こちら](https://www.notion.so/ja-jp/product/ai)を見てみてください！
sql skill: CTEs


```sql
SELECT code FROM data;

+------+
| code |
+------+
| us   |
| fr   |
| in   |
+------+

SELECT code,
CASE code 
  WHEN 'us' THEN 'United States'
  WHEN 'fr' THEN 'France'
  WHEN 'in' THEN 'India'
 END AS country
FROM data;

+------+---------------+
| code |    country    |
+------+---------------+
| us   | United States |
| fr   | France        |
| in   | India         |
+------+---------------+
```

An alternative is to use a CTE like this:

```sql
WITH countries (code, name) AS (
  SELECT * FROM (VALUES
    ('us', 'United States'), ('fr', 'France'), ('in', 'India')
  ) AS codes
)

SELECT data.code, name FROM data LEFT JOIN countries ON countries.code = data.code;

+------+---------------+
| code |     name      |
+------+---------------+
| us   | United States |
| fr   | France        |
| in   | India         |
+------+---------------+
```

---

Ref:

https://misfra.me/2023/ctes-as-lookup-tables/
JSONの配列がある集合の要素を含んでいるかをSQLで判定する(早期リターン版)

以下の記事ではJSON配列を走査する時にUNNESTした後に条件にマッチするものからなる配列を生成し、ARRAY_LENGTHをつかって長さを求めています。

https://www.yasuhisay.info/entry/2023/03/08/081500

しかし、配列を走査する途中で特定の要素が含まれていることが分かれば、それ以上の走査は不要な処理です。
そのため、以下のような形でEXISTS述語を使うように書き換えることで、元記事のクエリよりも高速に処理することが見込めます。
手続き型言語における早期リターンによる高速化のイメージです。

```sql
SELECT
  EXISTS (SELECT status FROM UNNEST(JSON_QUERY_ARRAY("[2,3,5,7]", '$')) AS status WHERE status IN ("5", "10")) AS a,
  EXISTS (SELECT status FROM UNNEST(JSON_QUERY_ARRAY("[2,3,5,7]", '$')) AS status WHERE status IN ("1", "4", "6")) AS b,
```

早期リターンという観点では、以下の公式ドキュメントに書かれている手法に似ています。

https://cloud.google.com/bigquery/docs/best-practices-performance-functions#use_an_aggregate_function_to_obtain_the_latest_record
初期値問題「[演習]微分方程式2(体系大学数学) 」をwolframalphaとsympyでやってみたい。

sympyでグラフがでます。

オリジナル

https://youtu.be/rMgZKu8KHnk

# wolframで
解がでませんでした。

https://www.wolframalpha.com/input?i=xy%27%2B2y%3D1%2Cy%282%29%3D1%2Cx%3E0&lang=ja

# sympyで

```python
from sympy import *
x = Symbol  ('x',real=True,positive=True)
y = Function('y')(x)
ans=dsolve(Eq(x*diff(y,x)+2*y,1), ics={y.subs(x,2):1})
print("#",ans)
plot (ans.rhs)
# Eq(y(x), 1/2 + 2/x**2)
```

![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/26250e5c-a8d5-6775-6368-0902a0d821f8.png)
スクリーンフローの選択リストで必須にいない場合に選択肢にNullを含める


選択肢を独自にコレクション変数セットで作ったのですが、必須にしないので選択肢にNullを作りたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/cab6487c-d071-0ee1-dace-628e756a1c9c.png)


下段がコレクションの選択肢セットで、冗談が今回作った選択肢（１つだけの値）です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9b3df8b1-8173-f26a-10ae-6121387566a0.png)

ポイントは選択肢の値です。EmptyString を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1d3bd4f1-3f27-d06c-ff39-2a11e7704e53.png)
［c++］n進法からm進法への基数変換

# **はじめに**
正の整数（n進法）をm進法に変換。そのメモ。競プロ用。

# **ソースコード（c++)**
```cpp
#include <bits/stdc++.h>
using namespace std;

void ntom(const string str, const int n, const int m, string &res) {
    unsigned long sum = 0;
    for (char c : str) {
        sum = sum * n + (c - '0');
    }
    res = "";
    do {
        int num = sum % m;
        res = static_cast<char>(num + '0') + res;
        sum /= m;
    } while (sum);
}
```

# **説明**
n進法 -> m進法
1. n進法の数値を文字列（str）で表す
2. strにおけるi桁目の数値をn^(i - 1)乗で重み付けしたものをsumに足す
※ 347（8）の場合
sum(10) = 3 * 8 ^ 2 + 4 * 8 ^ 1 + 7 * 8 ^ 0
        = 3 * 64 + 4 * 8 + 7
        = 231(10)

3. sumをmで割った余りを、新たな文字列（res）に足し合わせる
4. sumが0になるまで 3.をループ

# **使用例**
ソースコード
```cpp
#include <bits/stdc++.h>
using namespace std;

void ntom(const string str, const int n, const int m, string &res) {
    unsigned long sum = 0;
    for (char c : str) {
        sum = sum * n + (c - '0');
    }
    res = "";
    do {
        int num = sum % m;
        res = static_cast<char>(num + '0') + res;
        sum /= m;
    } while (sum);
}

int main(void) {
    string s = "21";
    const int n = 8, m = 9; // n進数 -> m進数
    string res;
    ntom(s, n, m, res);
    cout << s << ' ' << res << '\n';
    return 0;
}
```
出力
```
21 18
```

# **関連問題**
競プロ典型90問 067 - Base 8 to 9（★2）

https://atcoder.jp/contests/typical90/tasks/typical90_bo
【JavaScript】paiza標準入力サンプル問題セット「１つのデータの入力」を超初心者が解いてみた【入門】

#### 背景
書いた人：JavaScriptを全く知らない初心者
　　　　　C#が微妙にわかるだけ（しかも独学だから偏ってる）のプログラミング入門者
解いた問題：paizaのレベルアップ問題集
　　　　　　標準入力サンプル問題セット「１つのデータの入力」
言語：JavaScript（C#でも比較してみました）
環境：paizaのサイト（ブラウザ）
#### 問題文
**入力される値**
　文字列Sが1行で入力されます。
　入力値最終行の末尾に改行が１つ入ります。
　文字列は標準入力から渡されます。
**期待する出力**
　1行での出力
**条件**
　すべてのテストケースにおいて、以下の条件をみたします。
　　・Sは1文字以上100文字以下の文字列
　　・Sの各文字は英小文字または大文字または数字

#### 解答例
自分なりの解説をつけてJavaScriptで回答してみました。
~~~Javascript:Program.js
process.stdin.resume();              //processというオブジェクトのstdinプロパティ（標準入力）を使うよ！
process.stdin.setEncoding('utf8');  //入力される文字のコードははutf8だよ！

var lines = [];                                   //入力されるデータを格納するための配列。
                                                  //javascriptの変数には型とか無いからとりあえずvarでOKっぽい。
                                                  //varは変数以外にも使えるらしい。
var reader = require('readline').createInterface  //「readline」という機能を持つオブジェクト「reader」を用意する。
({                                                //createInterfaceでreadlineという機能の形式を指定するよ。
  input: process.stdin,                           //readlineするときのinput(入力形式)は標準入力（stdin）だよ。
  output: process.stdout                          //readlineするときのoutput（出力形式）は標準出力（stdout）だよ。
});

reader.on('line', (lineA)=>                     //さっき作ったreaderを発動！効果は'line'（一行の標準入力を読む）
{                                               //入力されたデータは新しい変数「lineA」に格納
  lines.push(lineA);                            //lines(４行目で作った配列)にlineAをpush（挿入）するよ。
});                                             //入力されるlineがなくなるまで繰り返されるらしい（onで発動するとそうなるっぽい）
                                                //２行目以降があったとしても配列linesに格納されているんだね。
                                                
reader.on('close', () =>                        //再びreaderを発動！効果は'close'（なんか処理するやつ、出力とかする）
{
  console.log(lines[0]);                        //標準出力はconsole.log！内容は配列linesの1個目（1行目の標準入力ってことだね）
});
~~~
1行目のresumeの意味は分かりませんでしたが、そのうちわかるようになるはず！
（C#でもusingの意味なんて最初は考えず使ってたし）

ちなみにC#で解くと
~~~C#:Program.cs
using System;
class Program
{
    static void Main()
    {
        string line = Console.ReadLine();
        Console.WriteLine(line);
    }
}
~~~
簡単に書けました。

#### 感想
JavaScript難しすぎる！！
今回のコードと解釈が本当に正解なのかすら全く自信がありません。
間違いもあると思うので、もしこのページを見ている経験者の方がいらっしゃったらアドバイスを頂けると幸いです。
JavaScriptって標準入出力むいてないのかなぁ…。早く慣れたいです。
もしかしてpaizaでJavaScriptを勉強するのは無謀…？
でもunityのjsonをしっかり理解して使いたいので頑張ります。
C#もほとんどpaizaのスキルチェックで勉強したし大丈夫なはず！
#### 参考にさせていただいたサイト
https://paiza.jp/works/mondai/stdin/stdin_1

↑　今回解いた問題です

https://qiita.com/Molly95554907/items/fddb0a426f9e01d50663

↑　大変わかりやすい説明がありました。ありがとうございました。
Google Knowledge Graph Search API を試してみた

Google Knowledge Graph Search API を試してみました

## なにそれ
検索したとき右に出てくるこれがAPIで利用できます
![スクリーンショット 2023-03-10 14.23.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/4b039494-3532-606c-ce2a-12075c9be1f5.png)

## 試し方
[Knowledge Graph Search API](https://developers.google.com/knowledge-graph/reference/rest/v1?hl=ja) の Try this method で実行できます
![スクリーンショット 2023-03-10 14.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/db536381-70e6-e813-b07c-8940d29d7777.png)

[クエリ パラメータ](https://developers.google.com/knowledge-graph/reference/rest/v1?hl=ja#query_parameters)
[types の詳細](https://schema.org/docs/full.html)
初期値問題「[演習]微分方程式1(体系大学数学)」をwolframalphaとsympyでやってみた。

グラフがでます。

オリジナル

https://youtu.be/2MGM8RwR7FI

# wolframで

https://www.wolframalpha.com/input?i=y%27%3D%283x2-6x-4%29y3%2Cy%281%29%3D1%2F2&lang=ja

# sympyで

```python
from sympy import *
x = Symbol  ('x',real=True)
y = Function('y')(x)
ans=dsolve(Eq(diff(y,x),(3*x**2-6*x-4)*y**3), ics={y.subs(x,1):1/2})
print("#",ans)
plot (ans.rhs)
# Eq(y(x), sqrt(2)*sqrt(-1/(x**3 - 3*x**2 - 4*x + 4.0))/2)
```

![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/695b45b1-850d-76f2-889d-00ef0169a1f4.png)

# 参考

https://pianofisica.hatenablog.com/entry/2020/05/15/133000
【Excel】PhpSpreadsheetの使用

# PhpSpreadsheetの使用

## PhpSpreadsheetのインストール
* comporserで使用したいディレクトリにPhpSpreadsheetをインストール
```sh 
composer require phpoffice/phpspreadsheet
```

## 空のExcelファイルを作成
* PhpSpreadsheetをインストールしたディレクトリに```createExcel.php```を作成。
```php:createExcel.php
<?php
require_once "vendor/autoload.php";
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

// ここで $sheet を通してセルなどを操作します。

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('対象ディレクトリ/createExcel.xlsx');
```
* 実行ディレクトリから```php 対象ディレクトリ/createExcel.php```を実行すると対象ディレクトリ内に空のExcelファイルが作成される。
* この時対象ディレクトリはあらかじめ作成しておく必要がある。

## 空のExcelファイルに日付を入力
* ```createExcel.xlsx``` と同階層に```editExcel.php``` を作成します。
```php:editExcel.php
<?php
require_once "vendor/autoload.php";

use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer;

$reader = new Reader;
$file_name = 'createExcel.xlsx';
$spreadsheet = $reader->load($file_name);

$sheet = $spreadsheet->getActiveSheet();
date_default_timezone_set('Asia/Tokyo');
// 文字の入力
$sheet->setCellValue('A1', 'テスト文字列');
// 日付の入力
$sheet->getCell( 'B2' )->setValue( date("Y/m/d H:i:s") );
// 空白の入力
$sheet->setCellValue('D1', null);

$writer = new Writer($spreadsheet);
$outputPath = 'createExcel.xlsx';
$writer->save( $outputPath );
```
* これをターミナルで実行```php editExcel.php```すると先ほど作った空のExcelに日付が追加されている。

## sheetの値の取得
* 新しく```read.php``` ファイルを作成し、シートを読み込んで値を取得する。
```php:read.php
<?php
require_once "vendor/autoload.php";

use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;

$reader = new Reader;
$file_name = 'read.xlsx';
$spreadsheet = $reader->load($file_name);

// シートの読み込み
$sheet = $spreadsheet->getActiveSheet();

// 値の取得
$URL = $sheet->getCell('C2')->getValue();
$value = $sheet->getCell('F2')->getValue();
```
SQL・Databaseを基本からまとめてみた【 PostgreSQL 】

## データベースとは？
- データを入れておく入れ物
- あとで取り出したり、変更がしやすいように整理されて入っている

## データベースの種類
- リレーショナルデータベース・・・表形式で表現する
- NoSQL(Not Only SQL)・・・リレーショナルデータベース以外のデータベース

## データベース管理システム
- DBMS(DatabaseMamegementSystem)・・・データベースを管理するための仕組み
- RDBMS(Relational DatabaseMamegementSystem)・・・リレーショナルデータベースを管理するための仕組み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/28dd925c-3acb-a473-9a2a-f58bee2ccc12.png)

## SQL(Structured Query Language)とは？
- RDBMSに対してデータ操作を命令する際に用いる言語を『SQL』という。

- SQLは、以下の3つに分類される
##### ①DML（データ操作言語）
データベース上の検索や更新を行う
SELECT(取得),INSERT(挿入),UPDATE(更新),DELETE(削除)など
##### ②DDL（データ定義言語）
データベース上のデータを格納する構造に関する定義を行う
CREATE(作成), ALTER(変更), DROP(削除)など
##### ③DCL（データ制御言語）
アクセス権やデータベースの状態の管理を行う
GRANT(権限割当), REVOKE(権限取消)など

## SQLで気を付けること
- 大文字と小文字の区別がない。現場の規約に合わせる。
- 大文字及び日付のリテラルはシングルクォーテーションで囲う。
- SQL文の最後には必ず『;』を付ける。
- 改行・半角スペース・タブは読み飛ばされる。
- コメント『#』・・行コメント　『--』・・行コメント 『/* */』・・範囲コメント

## データ型
- SERIAL・・・データが挿入されると自動で連番を振ってくれる
- VARCHAR(100)・・・文字列のデータ、100文字まで入る
- INTEGER・・・数値のデータ、-214783648から＋2147483647
- DATE・・・日付（時刻無）のデータ
- BOOLEAN・・・論理型、TRUE、FALSEなど

## PRIMARY KEY
- 主キー、プライマリーキーという
- 重複した値を入れられない
- 空白にも出来ない



## 参考サイト
[【SQL】未経験者もこれ一本でOK！MySQLで学ぶ「SQL」「データベース基礎」講座【プログラミング初心者向け】](https://www.udemy.com/course/uz-sql-kiso/)
[【JavaDB3】SQLとは何かがわかる初心者向け入門動画](https://www.youtube.com/watch?v=b1PaI72vYyw)
[リレーショナルデータベースってなに？Alibaba Cloud, AWS, Azure, Google Cloud のPaaS/IaaS型リレーショナルデータベースを比べてみました](https://www.softbank.jp/biz/blog/cloud-technology/articles/202207/cloud-relational-database-comparison/)
[リレーショナルDBの概念と関連する用語](リレーショナルDBの概念と関連する用語)
QUERY関数の条件を可変にする方法

# はじめに

QUERY関数の条件を可変にしたいときはセル参照を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/c6c0d82a-1bc2-0833-8e26-465739ef094d.png)
画像では条件の「晴」という文字列をQUERY関数に直接入力していますが、
これをD2セル参照に変更します。

# セル参照方法

参照したいセルをダブルクォーテーションと&で囲みます。


```
"&D2&"
```
さらに、D2セルは文字列なので、QUERY関数に組み込むときは上記をさらにシングルクォーテーションで囲みます。
```
'"&D2&"'
```
数式内の「晴」を上記に置き換えます。
```
=QUERY(A1:C,"select A, B, C where B = '"&D2&"' ",1)
```

完成です。
E1セルに入力し、D2セルの条件に「雨」と入力すると、
右側に天気が雨のデータのみ抽出されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/313c785d-35f1-766e-4d79-6099e44537d7.png)


# なぜ"&&"で囲むか

###  &

数式を結合するときの「&」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/528151f4-fc95-4ddc-214c-86fa01881a90.png)



###  ""(ダブルクォーテーション)
QUERY(データ, クエリ, [見出し])のクエリ部分は""で囲うルールなので、
クエリ以外の数式を組み込みたいときは、
"ここからここまで"はクエリですと指定してあげる必要があります。
その後、クエリとクエリ以外の数式を「&」で結合します。

QUERY(A1:C,<font color='red'>"select A, B, C where B = '晴' "</font>,1)
↓
QUERY(A1:C,<font color='red'>"select A, B, C where B = '"</font>&D2&<font color='red'>"' "</font>,1)


# おわりに

セル参照するには「"&セル&"」で囲めばいいというのは理解していましたが、
実際にQUERY関数内にくみこむときに、ダブルクォーテーションが多くなったり、少なくなったりしてエラーになることが多かったので、自分で間違わないように記事にしました。

この方法を使用すると、QUERY関数内にIF文などの数式を入れることも可能になるので、それも自分用にまとめてアップしようと思っています。



# 参考記事
・[QUERY関数のwhere句をセル参照にする方法【スプレッドシート】](https://floblopro.com/query-cell-reference/)