OmniAICreator/Qiita-1.07M huggingface dataset:
シーケンス(serial)が上手くいかず、INSERTできなかった話

IT未経験・プログラミング初心者が初めてWebアプリケーションを作った際の出来事です。トラブルがいつの間にか解決、「なるほど……？」と納得しかけましたが、調べるとまったく異なる原因でした。

同様の疑問を持った方の他、初心者の思考回路を知りたい方のためになれば嬉しいです。

# 概要
使用言語：Java
使用ソフト：Eclipse
作成物：会員制のカラオケ予約サイト
エラー発生元：会員、店舗等、新規登録する機能全般。
発生状況：新規登録しようとするとエラーが発生。→「主キーの重複」
解決方法(?)：試行回数が予め入れたサンプルデータの数を越して以降、問題なく登録されるようになった。

# 詳細
例：会員新規登録

今回各テーブルの主キーをserial型で設定しています。INSERT文では主キー(会員番号=number)を空欄にしそれ以外を入力することで、会員番号(number)は自動採番させようといった魂胆でした。


```java:はじめにPostgreSQLに直接入力したSQL文
-- 会員テーブルの作成
CREATE TABLE vips(
	number SERIAL PRIMARY KEY,
	mail VARCHAR(100) NOT NULL,
	password VARCHAR(20) NOT NULL,
	name VARCHAR(50) NOT NULL,
	address VARCHAR(10) NOT NULL,
	birthday VARCHAR(10) NOT NULL,	
	tel VARCHAR(15) NOT NULL
);

-- 会員テーブルのサンプルデータ
INSERT INTO vips VALUES(1,'abe@dd.co.jp', 'A1000000', '阿部太郎', '東京都','19841001', '09011111111');
INSERT INTO vips VALUES(2,'iga@dd.co.jp', 'B1100000', '伊賀次郎', '千葉県','19541002', '09022222222');
INSERT INTO vips VALUES(3,'uda@dd.co.jp', 'C1200000', '宇田三郎', '滋賀県', '19391003',  '09033333333');

```




```java:Webアプリ上で新規追加する際のSQL文(DAOファイル)
public void addStore(String name, String address, String tel, int size) throws SQLException {			
    String sql = "INSERT INTO stores(name, address, tel, size) VALUES(?, ?, ?, ?)";			
    Connection connection = DriverManager.getConnection(url, user, pass);
	PreparedStatement st = connection.prepareStatement(sql);
	st.setString(1, name); 
	st.setString(2, address);
	st.setString(3, tel);
	st.setInt(4, size);
	st.executeUpdate();
}
```

(各情報はjsp内でフォームから取得し、Servletを通してDAOファイルに届ける基本的な流れです。)


# 顛末
いざWebアプリから新規会員登録をしようとしたところ、「主キーが重複している」とエラーメッセージが表示されてしまいました。

Eclipse内でエラー表記はなく、各ファイルを確認してもミスが見当たりません。必要な情報はすべて入力しています。serialなら勝手に振ってくれるんじゃなかったのか？とハテナです。
    しかし、何度か挑戦していると…… **突然上手くいきました。**

そこで私たちの認識は以下のように変わります。

<dl>
  <dt>最初の認識</dt>
  <dd>データベース内で自動採番される。データベース内に既に「1」「2」「3」のデータが存在する場合は、どこからSQL文を実行しても「4」の数値が入る。
</dd>

 <dt>その時抱いたぼんやりとした認識</dt>
  <dd>自動採番はデータベース内ではなく、SQL文を実行したファイルで行われる。ファイル内で自動採番された数値がデータベースに登録されるため、PosgreSQLで直接入れた数値と別ファイルで得た数値とで重複する。（？）</dd>
</dl>


原因は **「サンプルデータを直接PostgreSQLに入力していたこと」** だったのか！
と、納得しかけましたが、この記事を書く段階でその認識は誤っていたことに気が付きました。

# 顛末（改）
結論、原因は **「サンプルデータを直接PostgreSQLに入力した際、Serialに明示的な値を入れたこと」** でした。

そもそもシーケンス(Serial)に対する認識が間違っていたのです。
Serialを使えばデータベース内で自動的に採番されるというぼんやりとした認識のみで、シーケンスオブジェクトの役割をわかっていませんでした。
シーケンスオブジェクトを自分で生成しなくてよいSerialを使用したことも、その勘違いを助長させたのだと思います……

例えば直接1~4まで明示的な値を入れたとしても、シーケンスオブジェクトは自身で絶対的にカウントしているため、 **「今4まであるから次は5だな」といった再定義は行われない**ということです。


# おわりに
今回は研修の中で生まれた疑問について調べていきました。
言われてみれば確かになといった感想です。

自分なりに調べて納得しただけなので、間違っているかもしれません。
何かおかしな点や補足があればぜひコメントをお願いします。

エンジニア1年目、これからも頑張っていきます！





# 参考にさせていただいたサイト
・[PostgreSQLでINSERT時に自動採番の主キーが重複してエラーが出る場合の対処法 -- ぺけみさお (xmisao.com)](https://www.xmisao.com/2014/06/07/duplicate-key-value-violates-unique-constant-primary-key-on-postgresql.html)

・[MySQL/PostgreSQLでのシリアル値まとめ - adiary開発日誌](https://adiary.adiary.jp/0259)



(作成日：2023/7/31)
「こだわりの強さ」と「痛み」は脳の共通の部位に位置する【エンジニア心理学】






人によっては当たり前の内容かもしれませんが、 **目標を決めることは大事です**

例えば、アジャイル開発でのインセプションデッキ。その中でも「我々はなぜここにいるのか」という名目で具体的に定義されます。
それだけでなく、「エレベーターピッチ」も使って多角的かつ誰が見てもわかるように目標を定めています。

なぜ目標を決めるのが大事なのでしょうか？



## 仕事で目的を設定しなければならないのはなぜ？

結論 : **目標を決めると、より高いパフォーマンスが出ます。**

結論だけ見れば当たり前かもしれませんがこれは大事なことです。

逆に言えば**目標を設定しないだけでメンバーのパフォーマンスが下がってしまう** と言えてしまいます。





### 「最善を尽くす」よりも「具体的な目標」がよい

モチベーションについての研究を調べると次のような記事が見つかりました。

> もともと『Organizational Behavior and Human Performance』に掲載された Edwin Locke の記事は、目標とタスクのパフォーマンスの関係を調査しました。そして、より具体的に言えば、「最善を尽くす」アプローチによる簡単な目標よりも、難しく具体的な目標の方が、より高いレベルのパフォーマンスを引き出すことができます。

from https://www.betterup.com/blog/goal-setting-theory


要約すると、**「最善を尽くす」** のようなふわっとした目標よりも、 **「具体的かつちょっと難しい」** 目標のほうが高いパフォーマンスを引き出せたということです。



### なぜ目標を設定しないのか?

ここまで目標が大事であれば、なぜ目標を設定することが避けられるのでしょうか?
これには次の研究結果が当てはまると考えられます。

> 自閉症（自閉症スペクトラム：ASD）は、コミュニケーションの困難さや、特定のものや行動への強いこだわりなどを特徴とする発達障がいの一つです。これらの症状は対症療法によって和らぐ場合もありますが、生涯にわたり現れ続けます。近年はASDの症状として、こうした複雑な高次脳機能の非定型[5]性を背景とした症状だけではなく、より基本的な脳機能に由来すると思われる感覚症状にも注目が集まっています。視覚刺激に対する過敏性や、視覚意識の過度の安定性、聴覚や嗅覚刺激に対する過度の反応など、日常生活や社会生活に大きな影響を及ぼす症状が報告されています。

from https://www.riken.jp/press/2019/20190619_1/


要約すると、**自閉症患者における「こだわりの強さ」と「刺激に対する過度の反応などの感覚症状」に共通の神経基盤**があるということです。

上記の研究結果ではASD自閉症患者への研究結果のみが報告されていますが、健常者への研究結果でも以下のような結論が出ています。

つまり、**目標を設定するなどの「こだわり」の感情と「痛み」の感情は同じ部位である**と
ということです。

これもよくよく考えれば当然のことかもしれませんが、何か目標を設定して取り組む場合、失敗した場合はそれに対する執着,こだわりの分だけ傷つくということですね。




## 目標を設定しよう

仕事の中で大小問わずさまざまな箇所で目標を定めることができると思います。

- 会議の目標を決めよう
    - 会議を設定する人はなんとなく会議するのではなく、その会議の目標を決めましょう。なんとなく集まるのではなく、その日のMTGの終わりに「何が決まったのか？」「誰がいつまでに何をやるのか？」が決まったかどうかを必ず振り返ってください。
- チームの存在意義を振り返ろう
    - あなたのいるチームに目標がなければ、今すぐ設定しましょう。特に上長は、 **どんなチームになりたいのか、どういう個人を求めているのか?** を何度も口に出しましょう。
    - ex) 私の前職の上司は「私は常にアンテナを張っている人を求めています」と話してました。
【Hello,World】はじめての海外カンファレンス！

# はじめに
はじめまして。新卒2年目のエンジニアです。
(qiita初投稿です、わくわくしています）

私は2023年9月にラスベガスで行われたOracleCloudWorldに参加しました。
とても楽しくて皆さんにもこの経験をしてもらいたいなと思い
海外カンファレンスに向けて準備したことを紹介します。

# 外の世界を見たい！と思ったきっかけ
きっかけはAWSのre:Inventです。
参加した先輩方の社内発信や発表・現地での思い出を聞いて
なんか面白そう！楽しそう！私も行ってみたい！と思ったのがはじまりでした。

# 準備したこと
それからは、いつ参加が決まっても大丈夫なように様々な準備をしました。
やっておいて良かったなと感じる3つのことについて紹介しようと思います。

## 1.まずは意思表示
海外カンファレンスに行きたい！外の世界を見てみたい！と色々な人に伝えました。
一番簡単そうですが、一番大事だったなと感じたのが意思表示です。

新人成果報告会や、日常のコミュニケーションなどの様々な場面で
部内の方だけでなく、同期や交流のある先輩方などいろんな人に言っていました。

伝える事で　私＝海外イベントに参加したい！と思っている人　と知ってもらうだけでなく
じゃあ、今何をするといいのか？具体的なアドバイスをもらうことが出来ました。

アドバイスを参考に次のアクションを起こすことが出来たので
行きたい！と思って終わりにせず、周りの人たちに発信して良かったなと思いました。

## 2.国内イベントに参加！技術アウトプットの練習を
私の外部イベントデビューは2023年2月に開催されたDevelopers Summitです✨
普段の生活では関わることのない人たちの話を聞くことで、自分の知らない世界が広がっていることに気づかされたのをよく覚えています。

その後もイベントにはテーマをもって参加をし、レポートを書いて部会などで発表する機会を頂いていました。
アウトプットから先輩方には沢山のフィードバックをいただき、より精度の高い技術的なアウトプットが出来るよう練習を重ねていました。

## 3.基礎知識を身につける
やはりイベントに参加したものの、セッションの内容が全く分からないと面白くないですよね。。

今回のOCWへの準備では、Oracleが提供するe-learningを使って学習をはじめました。
イベントまでに1つでも知っている内容を増やしてから行くぞ！と意気込んでいました🔥

OracleCloudの全体像からOCI・OCA・Oracle DBについて学習しAssociate資格も2つ取得しました！学習内容は社内で共有し疑問点は事前に解決するようにしていました。

結果的にタイトルに知っているサービスがあると面白そう、聞いてみたい！と自然と興味が湧きましたし、セッションでも聞いたことがある用語が出てくるとスムーズに理解する事が出来ました。

また全体像を知っておくと、どういった所がポイントになるのか分かったうえで
セッションを聞くことが出来るので、事前準備の大切さを改めて感じました。

# 終わりに
イベント自体もすごく刺激的で、学ぶことも多くとても楽しかったのですが
こうして振り返ると、イベントに向けた準備期間からすごく楽しんで取り組んでいたなと思います。見えていなかった世界・知らなかった事が少しずつ分かるようになっていく感覚がすごくワクワクします。

やはり目標が自分の原動力になっているなと感じました。
目標も立てるだけでなく、いろんな人に聞いてもらうことでアドバイスをもらえたり
時には自分へのプレッシャーにもなり、勇気が欲しいときに自分の背中を押してくれるなと思いました。

## ここまで読んで下さりありがとうございました
楽しそう、面白そう！いいな！と思った事がきっかけで、新しい目標をたてて発信してきました。
その結果OCWに参加出来たり、全社に向けた発表の機会をもらえるなど、沢山のチャンスを得る事が出来ました。

目標をもって発信する事は今後も続けていきたいなと思います。

この記事が誰かの役に立てれば嬉しいです。
図形の入った資料を高速で書く試み

## はじめに
最近現場にて図形の入った資料（処理フロー）を書く機会があったのですが、自作のマクロや現場のメンバーが作ったツールを使って素早く書くことができました。
本記事ではどのようなやり方をしていたかと、自作のマクロの一部を公開します

# 使用した自作マクロ及びツールの説明
処理フロー作成で使ったツールの簡単に説明します。

### ①図形作成ツール
　入力欄（複数入力可）に入力した文字列を持つ図形を作成するツール。
### ②矢印付与マクロ
　選択した図形を矢印でつなぐマクロ。
　１つ目に選択した図形から２つ目以降に選択した図形がつながる。
　ショートカットに割り当てるとよし。
### ③図形テキスト置換マクロ
　シート上のすべての図形で、文字列を一括で置換するマクロ。
 
# 処理フロー作成の流れ
1．Excel上で表形式の図形テキストを書き並べる
　この表が実質的な内容となります。

2．図形テキスト置換マクロで表の図形要素をすべて図形化する
　図形の形式を変える場合は一括で図形の変更を行います。

3．作成資料にコピペ＆位置調整を行う
　位置の調整はExcel標準機能の「図形の書式-配置」にあるものを使うと速いです。

4．矢印付与マクロで図形を適宜矢印でつなげる
　いちいち矢印を図形の挿入からやる必要がないため、スムーズに矢印を付与できます。

5．複数図形のテキスト修正は図形テキスト置換マクロで一括置換する
　図形テキストは手作業で1つ1つ変えるのは大変ですが、マクロで一括で変えられるとかなり効率的に作業ができます。

 # 所感
 ツールとマクロ自体はそれほど複雑なものではありませんが、痒い所に手が届くような便利さがあります。
これでもかなり効率的に作業することができましたが、資料に修正が多く入ると表形式の図形テキストと実際の図形テキストが乖離してしまうので、図形テキストから表形式の図形テキストに気軽に変換することができたらさらに便利に作業できるかなと思いました。

# マクロの共有
### 矢印付与マクロ
```vb:ConnectSelectedShapes
' 利用する関数
Sub ConnectSelectedShapes()
    If Not VarType(Selection) = vbObject Then End
    Dim i  As Long
    For i = 2 To Selection.ShapeRange.Count
        Call ConnectTwoShapes(Selection.ShapeRange(1), Selection.ShapeRange(i))
    Next
End Sub
'補助関数
Sub ConnectTwoShapes(ByRef src As Shape, ByRef dst As Shape)
    On Error GoTo ConnectTwoRectanglesError
    Dim line As Shape
    Set line = ActiveSheet.Shapes.AddConnector(msoConnectorStraight, 100, 100, 100, 100)
    line.line.EndArrowheadStyle = msoArrowheadTriangle
    line.ConnectorFormat.BeginConnect src, 4
    line.ConnectorFormat.EndConnect dst, 2
    line.RerouteConnections
    Exit Sub
ConnectTwoRectanglesError:
    line.Delete
End Sub
```

### 図形テキスト置換マクロ
```vb:objTextReplace
Sub objTextReplace()
    Dim before, after, msg
    Application.ScreenUpdating = False
    before = InputBox("置換前文字列を入力してください" & vbCrLf & "※部分一致", "Before")
    If StrPtr(before) = 0 Then Exit Sub
    after = InputBox("置換後文字列を入力してください" & vbCrLf & "※部分一致", "After")
    If StrPtr(after) = 0 Then Exit Sub
    msg = "以下の置換条件で実行します。" & vbCrLf & _
          "置換前文字列：" & before & vbCrLf & _
          "置換後文字列：" & after
    If MsgBox(msg, vbQuestion + vbYesNo + vbDefaultButton2, "質問") <> vbYes Then Exit Sub
    
    On Error GoTo replaceError
    Dim i, cnt: cnt = 0
    For i = 1 To ActiveSheet.DrawingObjects.Count
        With ActiveSheet.DrawingObjects(i)
            If .Caption Like "*" & before & "*" Then
                .Caption = Replace(.Caption, before, after)
                cnt = cnt + 1
            End If
        End With
replaceError:
        Resume continue
continue:
    Next
    Application.ScreenUpdating = True
    
    MsgBox cnt & "件の置換が完了しました"
End Sub
```
react-railsの導入

# はじめに
以下のリンクに従ってreact-railsの導入を試みたがエラーになっていたので解決策を紹介する．

https://github.com/reactjs/react-rails/blob/master/docs/get-started.md

# エラー文
```
uninitialized constant React::Rails::ComponentMount::Dummy
```

# 原因
バージョンが古くて導入できていなかった．
Gemfileを確認するとreact-railsのバージョンが3.1.0になっていた．

```ruby
gem "shakapacker", "= 7.1"

gem "react-rails", "= 3.1"
```

# 解決策
バージョンを更新する．以下のように記述してbundle install後，再度サーバを立ち上げ直すとreact_componentが読み込まれた．

```
gem "react-rails", "= 3.1.1"
```
スモウルビー(Smalruby)についかされた補完機能について+PWA対応について

# スモウルビーについて
スモウルビーについて、ざっくり説明します。スモウルビーはScratchにRubyでプログラムを作れるよう機能を追加したものです。ブロックで作ったプログラムをRubyにしたり、Rubyで作ったプログラムをブロックにできたりします。ブロックーRubyの相互変換ができます！！！
わからなかったら試してください。

[Scratchをためす](https://scratch.mit.edu/projects/editor/)
[スモウルビーを試す](https://smalruby.app/)

### そもそもScratchとは
Scratchはスクラッチ財団が、メディアラボのライフロングキンダーガーテングループの協力の元、開発している児童教育向けのプログラミング言語です。
だれでも無料で使用できます。皆様感謝して利用しましょう。
私も感謝して使っています。ありがとうございます。

# 補完機能について
スモウルビーに補完機能が追加されました！
補完機能とはRubyを書いてるときにスモウルビーがこうじゃない？って提案してくれます。
### 実際にはこういう風に動きます

![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147871/991422a7-16b0-1402-a272-f2cc9ae34a64.gif)

### このブロックができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147871/50305fb9-2782-b56e-bcc0-2749d35ba859.png)

ためしてみたくなったでしょう！？ここから試せます。
[スモウルビーを試す](https://smalruby.app/)
補完機能があるので、ブロックと対になるRubyを覚えていなくてもすらすらかけます！
めちゃくちゃ便利ですね！
スモウルビーが提案してくれたものはマウスかキーボードの十字キーで選べます。

CodaDojoでニンジャにプログラムを教えるとき、大人はブロックでプログラムを使うのは面倒...そんな時などなどかなり便利になったと思います。
スモウルビーの作者は「キーボード入力が現実的になった」と言ってます。


# PWA対応について
今回のアップデートでスモウルビーはPWAに対応しました。
PWAとは！WEBサイトをアプリ化する技術のことです！
ここをクリックすれば簡単にインターネットがなくてもスモウルビーが開発できます。
Chromeであれば右上のあたりにあるこのマークを押せばダウンロードできます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147871/a9a8135a-3353-e935-d744-2adfc3061730.png)

今回この機能を初めて知りましたが、非常に便利です。
私の環境はwin11です。右上のマークを押してパソコンにスモウルビーをインストールするとwindowsメニューに入ってくれました。



なお、デスクトップ版のスモウルビーは開発をやめました。
開発リソースの問題とデスクトップ版ではBluetoothが使えません。

# 宣伝1
スモウルビーの本があります。
本を書いたときにこの本があれば便利だったんですが....

[アマゾンの購入ページ](https://www.amazon.co.jp/%E5%B0%8F%E5%AD%A6%E7%94%9F%E3%81%8B%E3%82%89%E6%A5%BD%E3%81%97%E3%82%80-%E3%81%8D%E3%82%89%E3%81%8D%E3%82%89Ruby%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E5%B0%BE-%E5%AE%8F%E6%B2%BB/dp/4822286398)


教育指導案などもついていて、小学校の授業で使えるようになっています。
本書の内容をScratchでも使えるので皆さん手に取ってみてください。手に取ってくれたらめっちゃ喜びます。



# 宣伝2
ほかにも記事をかいてます。読んでください。
[mesh機能の紹介](https://qiita.com/fujimurakengo/items/3239d41200675cf39306)
[Meshのプログラム例](https://qiita.com/fujimurakengo/items/e7405f067a2dfce357f6)
OpenAI APIを使って要約、単語抽出、英語翻訳

OpenAI APIを使って要約、単語抽出、英語翻訳するコードです。
基本コピペでいいのですが、Secret keyは用意してくださいね。

大事なところは以下のところ。
contetには要約をしたい文章を入れます。

    content = """
    ChatGPT（Chat Generative Pre-trained Transformer）は、\
    自然言語処理（NLP）の分野で開発された高度な機械学習モデルです。\
    GPT（Generative Pre-trained Transformer）アーキテクチャに基づいており、\
    大量のテキストデータから学習しています。\
    このモデルは、人間のような対話を行うことができ、質問応答、テキスト生成、要約、翻訳など\
    多様なタスクに対応可能です。
    """
promptには指示を書きます。そして、```{content}```の中の文字を要約するように指示を出しています。
    
    prompt = f"""
    あなたは30語以内で要約してください。\
    以下に記載されたコンテンンツ\
    （三重のバッククォートで区切られている部分）を英語で要約してください。
    
    コンテンツ: ```{content}```
        """

## 以下は全てのコードです。


    import openai
    import os
    
    from dotenv import load_dotenv, find_dotenv
    _ = load_dotenv(find_dotenv()) 
    openai.api_key  = os.getenv('OPENAI_API_KEY')
    
    def get_completion(prompt, model="gpt-3.5-turbo"): 
        messages = [{"role": "user", "content": prompt}]
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            temperature=0, 
        )
        return response.choices[0].message["content"]
    
    content = """
    ChatGPT（Chat Generative Pre-trained Transformer）は、\
    自然言語処理（NLP）の分野で開発された高度な機械学習モデルです。\
    GPT（Generative Pre-trained Transformer）アーキテクチャに基づいており、\
    大量のテキストデータから学習しています。\
    このモデルは、人間のような対話を行うことができ、質問応答、テキスト生成、要約、翻訳など\
    多様なタスクに対応可能です。
    """
    
    prompt = f"""
    # あなたは30語以内で要約してください。\
    # 以下に記載されたコンテンンツ\
    # （三重のバッククォートで区切られている部分）を英語で要約してください。
    
    コンテンツ: ```{content}```
    """
    
    response = get_completion(prompt)
    print(response)

おまけで追加で二種類の指示を記載しています。これ以外にもいろいろ試してみてくださいね。
    
    # あなたは30語以内で要約してください。\
    # 以下に記載されたコンテンンツ\
    # （三重のバッククォートで区切られている部分）を日本語で要約してください。 
    
    # （三重のバッククォートで区切られている部分）の中で\
    # あなたが最も重要だと思う単語5つを抽出してください。
【備忘録】reactのuseHistoryがエラーになる対処

### はじめに

個人開発メモ📝
react-routerを使用したく、useHistoryを書いたらエラーになった話。

### useHistoryを使用してみる
```
npm install react-router-dom
```
```Register.jsx
import { useHistory } from 'react-router-dom';

function RegistrationForm() {
    const history = useHistory();
    // 省略
    .then(data => {
        history.push('/login');
    })
```
このように書いたら、
```エラーメッセージ
Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/react-router-dom.js?v=2f8e3fa7' does not provide an export named 'useHistory'
```
このエラーメッセージがローカル上に出ました。

### 対処法
react-router-dom　バージョン６　からは、useNavigateが推奨になったとのこと。
AWS SES で受信と送信してみる

あらかじめRoute53でドメインを設定して、MXレコード追加しておく。
・「レコード名」にメールアドレスに使いたいドメイン
・「レコードタイプ」はMX
・「値」はリージョンごとにエンドポイントが決まってるみたい。
　「10 inbound-smtp.ap-northeast-1.amazonaws.com」とか

　　

### 送信


①SESサイドメニューの「検証済み ID」から「IDの作成」に進む。

　　

②「ID の作成」でドメインを設定。

![スクリーンショット 2023-10-31 20.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464795/06e2ca74-4766-1ad4-6315-7bc1f548d688.png)

すると自動的にRoute53にもレコードが追加される。

　　
　　
③もう一度「検証済み ID」の「IDの作成」から、
　今度は送信先メールアドレスを設定。

　![スクリーンショット 2023-10-31 20.57.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464795/9c058217-20c2-63ac-bf8a-e0fe94ce7982.png)

送信先メールアドレスに認証メールが来るので、urlをクリックする。
　　
④「検証済み ID」のドメインをクリックして、
　「テスト E メールの送信」に進み、
 ・フォーマット済み
 ・カスタム
 ・「カスタム受信者」は検証済みのメールアドレス
　とかでテストメール送信。

届くはず。

   

　　

### 受信

①SESサイドメニューの「E メール受信」から「ルールセットの作成」に進む。

②適当な「ルールセット名」にし、「ルールの追加」に進む。

③「受信者の条件の追加」の「受信者の条件」に検証済みドメインのメールアドレスを入れる。

![スクリーンショット 2023-10-31 21.33.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464795/8869f08a-1081-ddcc-3222-8269c2764031.png)


④「アクションの追加」から「S3バケットへの配信」を選ぶ。
　世界に一つの名前で適当なS3バケットを作り、「ルールの作成」をする。

 ⑤ルールセットの画面で、「有効として設定」を押す。

 ⑥好きなメールアドレスから受信者の条件のメールアドレスにメール送る。
 
 S3に届いてるはず。




　　


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 （参考）


 https://www.blog.danishi.net/2022/02/13/post-5807/#google_vignette

 

 https://dev.classmethod.jp/articles/ses-email-receive-tokyo/
AWS CodePipeline（Code兄弟＃３）

# 目次
[1. はじめに](#はじめに)
[2. CodePipelineとは](#CodePipelineとは)
[3. CodePipeliineのコスト](CodePipeliineのコスト)
[4. 各ステージでサポートしているプロバイダー](#各ステージでサポートしているプロバイダー)
[5. 参考](#参考)

# はじめに
AWSでCI/CDを構築するために利用するCode兄弟についてまとめる。

今回は、AWS CodePipelineについて。
<br>
CI/CDについては別で詳しく解説するが、簡単なイメージ図は以下の通り。

![CICDイメージ_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554634/265e756a-99cb-a87b-d015-c36ba15d865b.jpeg)
<br><br>

# CodePipelineとは
AWS CodePipelineはCI/CDを実現するために利用する、フルマネージド型のサービス。CI/CDを実現するためのツール群をまとめる役割を持つ。
素早く信頼性の高いアプリケーション更新が可能になる。

CodePipeliineの概要をまとめると以下のようになる。
- ソフトウェアリリースプロセスをモデル化して可視化
- 開発者によるコード変更が行われると、コードのビルド、テスト、デプロイを自動で実施することが可能（CI/CD）
- AWSサービスやサードパーティ製のツールを利用することが可能

<br>


CI/CDを構築するために利用するAWSリソースは以下のようなイメージ。

![Code兄弟を利用したCICDのイメージ_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554634/879b2dfc-7aed-d301-3d95-f894e8911f13.jpeg)



# CodePipeliineのコスト

[公式サイト](https://aws.amazon.com/jp/codepipeline/pricing/)を参照すると、以下のように書いてある。
>AWS CodePipeline に前払い料金などの義務はありません。お客様が使用した分にのみお支払いいただきます。AWS CodePipeline は毎月アクティブなパイプライン*1つにつき1.00USD が課金されます。実験を奨励するため、パイプラインは作成後の最初の 30 日間は無料です。

上記を踏まえ、CodePipeliineにかかるコストは以下の通り。
- アクティブなパイプライン
- パイプラインで利用する他のAWSリソース
- 他のAWSリソースやサードパーティサービスからアクショントリガーする場合


アクティブなパイプラインとは、作成から30日が経過し、かつ当月に1つのコード変更が発生したパイプラインのこと。<br>つまり、コード変更が行われなかったパイプラインには料金は一切発生しない。

# 各ステージでサポートしているプロバイダー
## Source（ソース）
    - AWS CodeCommit
    - Amazon ECR
    - GitHub
    - GitLab
    - Amazon S3
    - Bitbucket
    - GitHub Enterprise Server

## Build（ビルド）
    - AWS CodeBuild
    - CloudBees
    - Jenkins
    - TeamCity

## Test（テスト）
    - AWS CodeBuild
    - AWS Device Farm
    - BlazeMeter
    - Nouvola
    - Jenkins
    - GhostInspector
    - Micro Focus StormRunner Load
    - Runscope

## Deploy（デプロイ）
    - AWS CodeDeploy
    - Amazon S3
    - AWS AppConfig
    - AWS CloudFormation
    - AWS CloudFormation StackSets
    - Service Catalog
    - Amazon ECS
    - Amazon ECS(Blue/Green)
    - Elastic BeanStalk
    - AWS OpsWorks
    - Amazon Alexa
    - Xebialabs

## Invoke（呼び出し）
    - AWS Lambda
    - Synk
    - Step Functions

# 参考
[AWS CodePipeline](https://aws.amazon.com/jp/codepipeline/)
[AWSホワイトペーパー](https://docs.aws.amazon.com/ja_jp/whitepapers/latest/architecting-hipaa-security-and-compliance-on-aws/aws-codepipeline.html)
[AWS CodePipeline ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/integrations-action-type.html)

# Code兄弟シリーズ
https://qiita.com/HiaHia/items/5ce68d9edccf8550f00c

https://qiita.com/HiaHia/items/6419fd575b1fa0022b0c

-----------------
https://qiita.com/Aoi_Noguchi/items/ea33e53af83231629b19

https://qiita.com/Aoi_Noguchi/items/e22fa8d3abd8048e56eb

https://qiita.com/Aoi_Noguchi/items/daff6ce8c10b3878da6e

https://qiita.com/Aoi_Noguchi/items/b8662f593380235dae70
Stable DiffusionのControlNetで色をつける


## 概要
白黒の画像に色をつけるところをゴールにしたいと思います

## 使い方

まず、git から適当なフォルダにクローンします。以下を実行します

```
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git

cd stable-diffusion-webui
sh webui.sh
```

http://127.0.0.1:7860/ のurlでブラウザが開くのでその上でまず、「webui-controlnet」をインストールする

メニュー　Extensions > Install from URL の以下の位置にgitのurlを入れます
https://github.com/Mikubill/sd-webui-controlnet.git

![スクリーンショット 2023-10-31 20.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87607/d93a0e60-22bc-3019-b21a-d1a9d89f9a5d.png)

次に以下をdownloadします
https://huggingface.co/ioclab/ioc-controlnet/resolve/main/models/control_v1p_sd15_brightness.safetensors

ダウンロード後、ダウンロードファイルを以下に配置する

```
cd ${stable-diffusion-webuiの配置した場所}/extensions/sd-webui-controlnet/models
```


あとは、メニューの txt2img　から、

「ControlNet v1.1.411」のタブを開き、以下の図のように
processor: none
Model: control_v1p_sd15_brighness 

を選択し（他はデフォルト）、「Generate」をクリックすると以下のような画像が生成できます。

![スクリーンショット 2023-10-31 21.00.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87607/98f3d804-b108-10ff-23d4-9af800232065.png)



あとは、微調整で自分好みにできると思うので色々パラメータを調べて進めるのが良いかと思います。自分もまだ勉強中ですが。
【アクセシビリティ】保存ボタン、エラーを出すか?非活性にするか?

![bandicam 2023-10-28 05-56-13-052.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/3afe79a6-ab07-81ae-46cc-8bbc12f0c8fa.jpeg)

# はじめに

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

みなさんはWebサイトを作るときに**アクセシビリティ**を意識していますでしょうか？
私はUXは多少なりとも意識しますが、アクセシビリティに関して知ったのは現在の職場に入ってからでした。

>Webアクセシビリティとは、「すべての人がWebで提供される情報を利用できること」を指します。
たとえば、Webサイトの文字が小さく、大きくする設定がない場合、目が悪い人や高齢の人は文字が見えず利用できません。
一方で、利用者にあった文字の大きさ設定ができるサイトは、目の悪い人でも利用できるため、Webアクセシビリティが実現できています。

このように誰もがWebサイトを利用できるようにすることを目的にしています。
今回は**スクリーンリーダー**(読み上げソフト)を利用する人に配慮したアクセシビリティを実現するために

#### <font color="red">入力フォームのバリデーションをどのように実現するか</font>

というところで教えてもらったことをもとに、自分なりに解釈したことをまとめていきます。

# とあるフォームのお話

今回はアクセシビリティの観点で2つのフォームを実装しました。
どちらがよりスクリーンリーダーを利用している人に優しいか考えてみましょう

## 1つ目のフォーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/32dec52b-26b4-c3f2-827f-56ad37b61b4c.png)

このような新規登録フォームがあったとします。
ここでタスクを入力せずに**保存を押す**と以下のようなバリデーションエラーが表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/607402cd-1642-e6f7-2057-44e474e97393.png)

## 2つ目のフォーム

このフォームでは以下のように**保存ボタンがはじめから押せないようになっています**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/e651b0e9-3b37-9d57-147c-9b3500175908.png)

タスク名を入力すると保存が押せるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/81c32573-29a0-8490-aeac-27f56cb0a57e.png)

入力後に入力した文字をすべて消すとバリデーションエラーのメッセージが表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/607402cd-1642-e6f7-2057-44e474e97393.png)

# アクセシビリティの観点で良い方はどちらか

個人的には**1**の<font color="red">**保存ボタンは押せる**</font>ようにしておくほうがアクセシビリティがよいという結論になりまた

**スクリーンリーダー**を利用している人にとって、**保存ボタンが押せない**というのは直感的に知ることが<font color="red">**難しい**</font>場合があります。

今回は入力項目が1つですが、複数あった場合に入力漏れがあった場合、保存ボタンが押せず

#### <font color="red">なぜ保存ができないのかがわかりません

今の仕様だとバリデーションエラー自体入力フォームに何かしら入力しないと表示されないためスクリーンリーダーを使っている方がフォームの存在に気づかず何も入力していない場合は、エラーが表示されずスルーされてしまいます

# おわりに

今回はアクセシビリティについて学ぶきっかけがあったのでまとめてみました
こう考えてみると普段気を使った実装ができていないなと感じ、更に1つレベルの高いエンジニアになるにはここまでできるようになる必要があるのだなと実感しました

ここまで読んでいただけた方はぜひ**いいね**と**ストック**よろしくお願いします。

また @Sicut_study をフォローいただけるととてもうれしく思います。

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

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

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

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

![bandicam 2023-10-04 20-58-54-525.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f41a0065-b23e-1895-da22-66bf0e48c5fb.jpeg)

# おすすめの記事

https://qiita.com/Sicut_study/items/4a3f45ec703e7fab7abf

# 参考

https://jp.indeed.com/career-advice/career-development/what-accessibility-explain-in-detail-with-specific-examples
rinna社の日本語LLM 「Youri 7B」を試してみた

## 背景
2023年10月31日、rinna株式会社がLlama2の日本語継続事前学習モデル「Youri 7B」を公開した。
[rinna、Llama 2の日本語継続事前学習モデル「Youri 7B」を公開](https://rinna.co.jp/news/2023/10/20231031.html)
## 目的
性能は高いが主たる学習データが英語のOSSと、追加の日本語の学習の組み合わせは、高い性能の日本語LLMを期待できる。ベンチマークスコアも公開されてnoteやblogで使用感が報告されているが、やはり自分の興味あるタスクでの性能が知りたいので試してみた。
## 環境
OS: Ubuntu20.04LTS
GPU: RTX A6000x2
miniconda, pipで構築
model: youri-7b-instruction-gptq(4bit量子化モデルも公開されている)
modelについては、公式サイトには下記の記述がある。
「Youri 7B Instruction」：日本語の一問一答に応える能力が高くベンチマークにおいて高いスコアを達成。
「Youri 7B Chat」：複数ターンの対話データを用いて追加学習しているため対話性能が高い。

## 結果
日本語がこなれていて、かなり良さそうな印象。量子化モデルのサイズは3.9GBでメモリ使用量は3GBとかなりコンパクト。
```
以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。

### 指示:
次の文章について、日本人として回答してください

### 入力:
日本のおすすめの観光地はどこですか。理由とともに説明してください

### 応答:
 日本の観光地はたくさんありますが、その中でも京都はおすすめです。京都は日本の古都として知られ、古い建物や寺院が多くあります。そのため、日本の歴史や文化に触れることができます。また、京都には清水寺や金閣寺、伏見稲荷大社など、日本を代表する観光地がたくさんあります。そして、京都には日本の四季を感じることができる場所もあります。例えば、嵐山や嵯峨野な
 ```

## スクリプト
サンプルコードのプロンプト部分を変えてみた。

```python
import torch
from transformers import AutoTokenizer
from auto_gptq import AutoGPTQForCausalLM

tokenizer = AutoTokenizer.from_pretrained("rinna/youri-7b-instruction-gptq")
model = AutoGPTQForCausalLM.from_quantized("rinna/youri-7b-instruction-gptq", use_safetensors=True)

instruction = "次の文章について、日本人として回答してください"

input = "日本のおすすめの観光地はどこですか。理由とともに説明してください"

prompt = f"""
以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。

### 指示:
{instruction}

### 入力:
{input}

### 応答:
"""
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        input_ids=token_ids.to(model.device),
        max_new_tokens=200,
        do_sample=True,
        temperature=0.5,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0])
print(output)
```
GAになったDatabricksのUNDROPコマンドを試してみる

以前、こちらを翻訳した際にはパブリックプレビューでしたが、先週GA(正式提供)になりました。

https://qiita.com/taka_yayoi/items/1bc3dd06fc4b0f845e68

# UNDROP TABLEコマンドとは

日本語マニュアルもあります。

https://docs.databricks.com/ja/sql/language-manual/sql-ref-syntax-ddl-undrop-table.html

> `UNDROP` コマンドは、 Unity Catalog にあるマネージ テーブルまたは外部テーブルが誤って削除または削除されるという問題に対処します。 デフォルトでは、このコマンドは、指定されたテーブル名のユーザーが所有する最後にドロップされたテーブルをアンドロップ (リカバリ) します。 親スキーマとカタログが存在する必要があります。 この機能は、7 日間の保持期間内に削除されたテーブルを回復することをサポートします。

:::note
**注意**
テーブル権限、列仕様、プロパティなどのテーブルメタデータがリカバリされます。 主キー制約と外部キー制約は、 `UNDROP` コマンドでは回復されません。
:::

# テーブルの作成

Unity Catalogでカタログ・スキーマを作成し、その中にテーブルを作成します。`drop_table_schema`というあからさまなスキーマ名にしています。
![Screenshot 2023-10-31 at 20.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/93c09c16-9f2f-671f-82ed-bf76505d4474.png)

# 削除済みテーブルの確認

まず、この状態で削除済みのテーブルが無いか確認します。

https://docs.databricks.com/ja/sql/language-manual/sql-ref-syntax-aux-show-tables-dropped.html

```sql:SQL
SHOW TABLES DROPPED IN takaakiyayoi_catalog.drop_table_schema;
```

この時点では当該スキーマでテーブルは削除されていないのでレコードは返却されません。

```
クエリー結果が返されませんでした
```

# テーブルの削除

```sql:SQL
DROP TABLE takaakiyayoi_catalog.drop_table_schema.japan_cases_20220818;
```
テーブルが削除されました。
![Screenshot 2023-10-31 at 20.41.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1dcf111c-9ad2-072e-e24f-065ea33dce63.png)

再度、`SHOW TABLES DROPPED`を実行します。

```sql:SQL
SHOW TABLES DROPPED IN takaakiyayoi_catalog.drop_table_schema;
```
削除されたテーブルの情報を確認できます。
![Screenshot 2023-10-31 at 20.42.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/34d5fd3a-afd2-e17c-442a-da016e557071.png)

# テーブルのリカバリ

```sql:SQL
UNDROP TABLE takaakiyayoi_catalog.drop_table_schema.japan_cases_20220818;
```

テーブルが復旧しました！
![Screenshot 2023-10-31 at 20.45.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/683451b2-9ef0-7b53-0f79-ef6ab24d79b7.png)


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

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


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【Swift】CIFilterで画像の色を反転させる

# はじめに
CIFilterで画像の色を反転させてみます

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-10-31 at 20.42.54.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/5d4d7a19-f41d-e56f-eb8f-88e6de6a2162.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    private let image = UIImage(named: "sample1")!

    @State private var uiImage: UIImage?

    var body: some View {
        ScrollView {
            VStack {
                if let uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                } else {
                    Image(uiImage: image)
                        .resizable()
                        .scaledToFit()
                }

                HStack(spacing: 15) {
                    Button {
                        applyColorInvert()
                    } label: {
                        Text("適用")
                    }

                    Button {
                        uiImage = nil
                    } label: {
                        Text("リセット")
                    }
                }
            }
            .padding(.horizontal, 20)
        }
    }

    func applyColorInvert() {
        let context = CIContext()
        let inputImage = CIImage(image: image)!

        guard let filter = CIFilter(name: "CIColorInvert", parameters: [
            kCIInputImageKey: inputImage
        ]) else { return }
        guard let outputImage = filter.outputImage else { return }
        guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return }
        self.uiImage = UIImage(cgImage: cgImage)
    }
}
```

# おわり
あんまり使い所はないかもしれないです
Python でリンター兼フォーマッターを高速で Ruff で実現

# Ruff とは

Pythonのリンター兼フォーマッターであり、高速であることが特徴なようです。

https://docs.astral.sh/ruff/

# チュートリアル

## ruff のインストール

```
pip install ruff
```

## サンプルの準備

```numbers.py
from typing import Iterable

import os


def sum_even_numbers(numbers: Iterable[int]) -> int:
    """Given an iterable of integers, return the sum of all even numbers in the iterable."""
    return sum(
        num for num in numbers
        if num % 2 == 0
    )
```

## ruff check

`ruff check`を実行することにより、リンターを実行。

```
Ruff % ruff check .

numbers.py:3:8: F401 [*] `os` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.
```

`os`はインポートされましたが、利用していないというメッセージです。

`ruff check --fix`を実行することにより自動で修正してくれます。

```
ruff check --fix .
Found 1 error (1 fixed, 0 remaining).
```

## ruff format

`ruff format`を実行することにより、フォーマッターを実行。

```
ruff format .
1 file reformatted
```

## 動作のカスタマイズ

Ruff の動作をカスタマイズすることが可能です。

プロジェクトのルートディレクトリに`pyproject.tomlファイル`を以下の通り作成し、`ruff check`を実行します。

```pyproject.toml
[tool.ruff]
# 行の最大長を79に設定する。
line-length = 79

[tool.ruff.lint]
# line-too-long`ルールを強制ルールセットに追加します。デフォルトでは、Ruffは以下のようなルールを除外する。
# ブラックのようにフォーマッタの使用と重複するルールは省略されますが、 
# 明示的にルールを追加することでこの動作をオーバーライドできます.
extend-select = ["E501"]
```

最大長が強制され、制限は 79 にしてほしいというメッセージが表示されます。
```
ruff check .
numbers.py:5:80: E501 Line too long (92 > 79)
Found 1 error.
```

# GitHub Actions 

ついでなので、GitHub Actions に組み込んで試してみたいと思います。

https://github.com/ChartBoost/ruff-action

```.github/workflows/ruff.yml
name: Ruff
on: [push, pull_request]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: chartboost/ruff-action@v1
```

先程と同じように`os`はインポートされましたが、利用していないというメッセージのところでエラーになったことがわかります。

![スクリーンショット 2023-10-31 20.24.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/649cb872-ca30-c597-65f3-0339fff914eb.png)

デフォルトの動作からカスタマイズする必要はあるでしょうが、簡単にCIに組み込むことができるのは良いですね。
【自分用】勉強メモ

　最近になり、優しい(&優秀な)上司のもと楽しいプロジェクトに入った事で精神が安定しだしたため、自学の時間を設ける事にした。
本記事ではその記録とToDoを兼ねた自分用のメモを記載する。
つまり、一般の読者は読んでも露ほども面白くない記事である。
# 目標
## 年内
- LangChainの基礎理解
    - 一冊は入門書読み切る

# 技術系
## LLM関連
- 本(Kindle)
    - Langchain完全入門
        - Langchainの基礎本
        - ハンズオン形式
        - .pyで実装
            - ローカルだと扱いづらいので、notebookにしてColabでデモ中
    - ChatGPT/Langchainによるチャットシステム構築
        - なんか説明が雑なため後回し
- Udemy
    - LangChainによる大規模言語モデル（LLM）アプリケーション開発入門―GPTを使ったチャットボットの実装まで
        - https://www.udemy.com/course/langchain-apps/
    - ChatGPT APIとLangChainでChatGPTを最強にするハンズオン
        - https://www.udemy.com/course/chatgpt_langc/

## Pytorch関連

## Linuxコマンド関連
- いちやさLinuxコマンド

## Docker関連
- 仕組みと使い方がわかるDocker
    - 復習のため

## SQL関連

## Git関連
B2C Commerceで商品検索を実装

# サイト全体で商品を検索
RefArch標準のテンプレートを使う。
以下を、検索フォームに実装。
```:cartridges/app_storefront_base/cartridge/templates/default/components/header/pageHeader.isml
<isinclude template="components/header/search" />
```

検索時のリクエストが以下のようになっている
```
Search-Show?&q=スーツ&lang=ja_JP
```

# カテゴリー内で商品を検索
RefArchでは実装されていないので、以下のようにカテゴリー付きでリクエストを送るように実装。
```
Search-Show?cgid=newarrivals-mens&q=スーツ&lang=ja_JP
```

そのため、リクエストの内容からカテゴリーを取り出し、hidden　fieldに含めるという方針で実装した。
```:cartridges/app_storefront_base/cartridge/templates/default/components/header/search.isml
<isscript>
    var selectedCategory = request.httpParameterMap.cgid.stringValue;
</isscript>
<input type="hidden" value="${selectedCategory}" name="cgid">
```
# 検索対象
ProductSearchModelを使用して、注文可能商品のみを表示している。

https://help.salesforce.com/s/articleView?id=cc.b2c_show_orderable_products_only_at_the_product_level.htm&type=5

# 検索条件の設定
マーチャントツール >  検索 >  検索インデックス > 商品インデックス - 全般

![スクリーンショット 2023-11-14 11.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/67b0cd92-9f5d-b05e-4600-83b447c57f02.png)


# 公式サイト
検索可能な属性を指定することも可能となる。

https://help.salesforce.com/s/articleView?id=cc.b2c_configure_searchable_attributes.htm&type=5
[Rails]STIをいじくり回してみる[Single Table Inheritance][単一テーブル継承]

STIのモデルのデータ移行・リファクタリングみたいなことをした際に得られたSTIをいじくり回す知見を書き留めておく

# 環境
ruby `3.2.2`
Rails `7.0.8`

[STIに関するコードはこの辺](https://github.com/rails/rails/blob/v7.0.8/activerecord/lib/active_record/inheritance.rb)

# 前提
```ruby
class Person < ApplicationRecord
  self.store_full_sti_class = false
end

class Person
  class Child < Person
  end
end
```

みたいなモデルがあるとする

# クラス名と`sti_name`を別のものにしたい時は
```ruby
class Person < ApplicationRecord
  self.store_full_sti_class = false

  class << self
    def find_sti_class(type_name)
      case type_name
      when 'Baby'
        Person::Child
      else
        super(type_name)
      end
    end
  end
end

class Person
  class Child < Person
    class << self
      def sti_name
        'Baby'
      end
    end
  end
end
```

こうすることで`type`が`Baby`のレコードを`Person::Child`として扱うことができる

### 解説
`sti_name`をオーバーライドするだけだとDBのレコードを取得してインスタンス化するときに「`Baby`に対応するクラス`Person::Baby`がない」というエラーが出るので`find_sti_class`をオーバーライドして`Baby`と`Person::Child`のマッピングをする必要がある

# レコード検索時に発行されるSQLの`WHERE ***.type = '****'`を任意の値に変えたい時は
```ruby
class Person < ApplicationRecord
  self.store_full_sti_class = false

  class << self
    def find_sti_class(type_name)
      case type_name
      when 'Baby'
        Person::Child
      else
        super(type_name)
      end
    end
  end
end

class Person
  class Child < Person
    class << self
      def type_condition(table = arel_table)
        sti_column = table[inheritance_column]
        sti_names  = ['Baby', 'Child']

        predicate_builder.build(sti_column, sti_names)
      end
    end
  end
end
```

こうすることで`type`が`Baby`のレコードと`Child`のレコードの両方を`Person::Child`として扱うことができる

### 解説
`type_condition`というメソッドがレコード検索時の`type`の絞り込みをしているのでそこをオーバーライドすることで`WHERE type IN ('Baby', 'Child')`というSQLになる

ただし、それだけだとDBのレコードを取得してインスタンス化するときに「`Baby`に対応するクラス`Person::Baby`がない」というエラーが出るので併せて`find_sti_class`をオーバーライドして`Baby`と`Person::Child`のマッピングをする必要がある

# ちなみに
```ruby
class Person
  class Child < Person
    default_scope { unscope(where: :type).where(type: %i[Baby Child]) }
  end
end
```
ってやるとぱっと見動くけどjoinした時や、アソシエーションでの参照時のクエリが意図した挙動にならなかったです

# 〆
RailsのコードをオーバーライドするというパワープレイはRailsのバージョンを上げる際の妨げになりやすいので一時的な対応としてのみ使いましょう

# 参考
[type_conditionのコード](https://github.com/rails/rails/blob/v7.0.8/activerecord/lib/active_record/inheritance.rb#L306-L311)
[find_sti_classのコード](https://github.com/rails/rails/blob/v7.0.8/activerecord/lib/active_record/inheritance.rb#L295-L304)
JPEG2000 でエンコードされたByteArray の扱いに気をつけろ (Swift, Kotlin)

## 概要

https://stackoverflow.com/questions/77394250/bytearray-can-be-shown-as-image-in-swift-using-uiimage-but-not-in-kotlin-using

ここに質問して、結局２時間後くらいに何が悪かったかに気づき修正することができました。

## どこでハマったか
JPEG2000でエンコードされたbyteArray を扱う際に、
Swiftを使っていれば

```swift
let uiImage = UIImage(data: data)
```

としてByteArray ([UInt8]) をそのままぶちこむだけでなんかImageとして出力してくれていたのですが、
Kotlinでは同様にBitmapにすれば描画できるやろと思って


```kotlin
var bitmap = BitmapFactory.decodeByteArray(data, 0, data.size, BitmapFactory.Options())
```

とやっても、bitmap はnullになっていたので何が問題なのか分かりませんでした。



## 解決策

あとで、このバイト配列がJPEG2000でエンコードされたものであることがわかり、
Kotlinでは例えば

https://github.com/ThalesGroup/JP2ForAndroid/tree/master

このライブラリを使ってデコードする必要があることがわかりました。


ライブラリのインポートさえしてしまえば、

```kotlin
import com.gemalto.jp2.JP2Decoder
val bitmap = JP2Decoder(it).decode();
```

で簡単にデコードできます。

以上！
【初学者目線】プログラミングってやっぱ難しいよ！

# はじめに

こんにちは、こんばんは！　[堕罪ｵｻﾑ](https://qiita.com/awesomeDazzaye)です。大学では国語学・日本語学を主に学んでいます。絶賛ゼミの発表資料作りに追われています……。

ゼミ資料に追われながら**Flutter**を勉強していて、[【Flutter】わかんないよ！オブジェクト指向なんてわかんないよ！](https://qiita.com/awesomeDazzaye/items/4e436465661ca0805c9d) という記事でコードの理解を深めようと努力したり、その後もQiitaの記事を読み漁りつつ手を動かしを繰り返しているのですが、

「わかんないよ！Flutter全然進まないし、なんなら**何がわかってないのかわかんないよ！プログラミング難しいよ！**」

という具合です。(ﾄﾎﾎｽｷﾞ)

今回は **初学者(主に私)** が主にFlutterについてよくわかっていないところをまとめてみようと思います。

また後半ではFlutterだけでなく**プログラミング学習**という範囲まで広げて自分の思ったこと・考えたことをまとめました。

よろしくお願します！

## わからないこと
- Flutterでアプリを作るときの進め方
- `@override` 以降のコードの構造
- どこに何を書けばいいのか問題
- 「なんとなくわかる・わからない」から質問するときや調べるときに言語化できない問題

この4つを説明させていただきます。


### Flutterでアプリを作るときの進め方

Flutterで電卓を作ろう！新しいプロジェクトを作って～……ん？

**「で、どうすればいいんだ？」**

そもそもFlutterで電卓を作るにあたりビジョンが全く見えてこない……！

計算結果を出す画面は状態を持つからStatefulWidgetで作るんだろうな、でもボタンはどうするんだ？
**そもそもボタンはどうやってつくればいいんだ？なんなら計算結果を出す画面もどうすればいいの？**

電卓を作っている動画を「」視聴しても、あっちこっち書き足したり消したりしている感じがして難しく感じます。泣
**画面やボタンの作り方が分からない**に関しては明らかに私の勉強・知識不足なのですが、そこを超えた先にある**コードの組み立て方**が一切わからないでいます。

### `@override` 以降のコードの構造

上記に続き、コードの組み立て方がわからないので`@override`以降も大変なことになります。

「マクロからミクロに書いてる感じがする」
「CSSにあたるようなところは`child`とか`children`に書くのかな？」

ぐらいで、あとはAndroid Studioの便利な機能でいじってみたり、ネットで調べてコピペして動かしてみたりしてます。でも結局動かないし赤字エラーいっぱいになってどこから直せばいいかわからない、となってしまいます。


###  どこに何を書けばいいのか問題
あとはやっぱり**どこに何をかけばいいのかわからない。** これがいっちばん辛いです。
Dartで処理を書くにあたって、その処理をどこの括弧内に書けばいいのか。
なんとなく、`onClick`の処理をするならそれを使うボタンのあたりに処理を書くはず、でもここに書いてもエラーが出る。ここは？　ここはどうだ？

やっているうちに他のところもエラーが出てきてあちこちに赤いのがいっぱいになって不貞寝までがルーチンです。

### 「なんとなくわかる・わからない」から質問するときや調べるときに言語化できない問題

ここまで見てくださった方々、もう察しておられると思います。
**「なんとなく」・「わからない」** という言葉がこの記事内でいくつ出てきたことやら！　もうほんと勉強不足ですみません。

わからないところは調べて手を動かして、と努力はしているのですがやっぱり難しい！わからない！
そもそもその調べ方(調べるためのキーワードなど)があっているかもわからない。

これが一番高い壁かもしれないです。

## どうすればいいのか

**いっぱい勉強したほうがいい。**
これに尽きる気がします……。特に初学者なので時間をいっぱい取ってプログラミングに意識を持ち続け、調べては書いて動かして、を繰り返すのが一番の近道、急がば回れみたいな、実際そうだと思います。つらいけど。

あとは以前、私がお世話になっているエンジニアさんから

**「15分は自分で考えてね、それでもだめなら訊いてね」**

という言葉をいただきました。
また同時に

**「ChatGPTは最終手段」**

とも言われました。ちょうどFlutterに苦しめられて(？)もがいている私にはかなり刺さりました。
自分でやることで自分の身になりますよね、たしかに。

「15分は自分で考えてね」という言葉から、その15分の中で何をやればいいかを考えたところ

- 出てきたエラーを翻訳したり調べて、なにが原因でエラーが出ているのか明確にする
- エラーが出る条件や原因の解決方法が載っている記事やサイトを確認する
- エラー箇所やわからなくなったコード周辺・調べた記事でわからないワードをすべからく調べる
- そのうえで何が分からないかを考える
- それでもだめなら正直に「わからない」と伝える

ではないかと思いました。(あってるか間違っているかは別として、自分はこれを意識していこうという戒めもあります)

やはり一番よくないのは「何がわからないかがわからない」ことだと思いました。
最後の**それでもだめなら正直に「わからない」と伝える** というのは、教えてくださる側の方々からするとチョット……だとわかってはいるんですけど、15分考えてわからないものを一人で悩むよりはいいのかも？実際仕事としてやるときに一人で分からないまま進んでいないというほうが良くないのかな？と思ったのでリストに入れました。

# 最後に

初学者としてこういった記事を書くことはいかがなものかと思っていますが、もしこの記事が、自分の悩みや考えが誰かのお役に立てればと思い投稿させていただきました。
もっと技術に踏み込んだ記事も書けるように精進します！

ここまで読んでくださりありがとうございました！
OpenAIのGPTを使ってファインチューニングをやってみた。

OpenAIのGPT3.5-turboを使ってファインチューニングをやってみました。方法は簡単なのですが、いくつか上手くいかない場所がありました。
今回、参考にしたのはこのサイト。

https://cookbook.openai.com/examples/how_to_finetune_chat_models

## ファインチューニングとは？

ファインチューニングとは、すでに訓練されたモデル（事前訓練モデル）を特定のタスクやデータセットに適応させるための追加の訓練のことを指します。大規模なデータセットで事前に訓練されたモデルを、小さなデータセットで微調整することで、高い性能を迅速に達成することができます。

要はすでにあるGPTってやつに新しいデータを加えて、より専門的なbotを作ってしまおうってことです。

## ハマったところ

### データセット

リンク先のページを基本的にコピペしていけばいいのですが、データセットを見つけることができなかったので、GitHubからダウンロードしました。そして、今回のファインチューニングで使う0〜300までを抽出しました。

### ファインチューニングの待機時間

以下のコードを実行すると、WebページではStatus: createdと書いてあるのですが、私の画面ではStatus: validating_filesと表示されていました。
それでも、進めていくと途中でエラーが出ました。何度もコードを見直したけど間違いが見つけられない。そこで、一旦、諦めてG-mailを見ていたらOpenAIからファインチューニング完成のメールが届いてました。
それを確認してから、進めていくと前回エラーが出たところも上手くいきました。



    response = openai.FineTuningJob.create(
        training_file=training_file_id,
        validation_file=validation_file_id,
        model="gpt-3.5-turbo",
        suffix="recipe-ner",
    )
    
    job_id = response["id"]
    
    print("Job ID:", response["id"])
    print("Status:", response["status"])


あとは、特に問題もなく順調にファインチューニングが終了しました。本当に簡単です。
上記の躓きポイントだけ気をつければ大丈夫です。

## 実際にファインチューニングしたモデルを使ってみる。

実際にモデルを使ってみると上手くいきました。コードは以下です。
secret keyだけ入れ替えてくださいね。


    import openai
    
    openai.api_key = "secret key"
    
    def get_completion_from_messages(messages,
                                     id="ここに入力",
                                     model="ここに入力", 
                                     temperature=0, 
                                     max_tokens=100):
        
            response = openai.ChatCompletion.create(
                model=model,
                messages=messages,
                temperature=temperature, # this is the degree of randomness of the model's output
                max_tokens=max_tokens, # the maximum number of tokens the model can ouptut 
            )
            
            return response.choices[0].message["content"]
    
    messages = [
        {'role':'system',
        'content': "You are a helpful recipe assistant. You are to extract the generic ingredients from each of the recipes provided."},
        {'role':'user', 
         'content': "1 c. flour, 1 tsp. soda, 1 tsp. salt, 1 Tbsp. sugar, 1 egg, 3 Tbsp. margarine, melted, 1 c.buttermilk"
        }
    ]
    
    response = get_completion_from_messages(messages, temperature=1)
    print(response)


OpenAIからメールが届くので、そのメールに記載されている。

id

model

を入力したら完成です。

## まとめ

ファインチューニングは初めての挑戦でしたけど、意外と簡単にできました。次は違ったデータセットを使って試してみようと思います。

次回もGPT関連かChatGPTについての記事を書こうと思っています。
Excelデータの読み込み方法

# はじめに
Windows O/Sの登場以来、Excelはコンピュータの使用において欠かせないアプリになりました。家庭での家計簿の整理から、オフィスの各種データの入力や整理など、その使い道は数えられないぐらいです。

多少遅れましたが、いよいよExcelデータの読み込みがXplentyでも可能になりました。様々な業務で最も活用されているExcelで作成されたデータを変換なしでそのままXplentyに取り込められる事で、Xplentyの利便性がさらに高くなりました。

今回の記事では、Excelデータの読み込み手順やXplenty上の制限事項について説明します。

# Excelデータの読み込み
Excelデータを読み込むためにはXplentyのFileSrorageソースを使います。コンポーネントの詳細設定は次のとおりです。
1. Excelファイルが保存先への接続のためにコネクションを選択します。（この例ではAWSのS3になっています。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/922ee8f6-a187-b5dd-eaeb-1a5ce9f7b194.png)

2. Source pathに**Excelファイルのプールパス**を入力します。
この項目は、１つのExcelファイル名を指定しなければなりません。ユーザー変数にてExcelファイルの指定も可能ですが、いずれにせよ1つのExcelファイルのみの指定なら問題ありません。また、Excelファイルの拡張子はxlsもxlsxも指定可能で問題なく読み込めます。
従来のファイルフォーマット（CSV、JSON、平文）の指定に使うワイルドカードは、Excelファイルのパスに使うと実行時にエラーになりますのでご注意ください。
3. Record delimiter は **New Line**を選択します。
4. Record typeでExcelを選択し、Sheet Nameに対象のシート名を正しく入力します。 シート名もユーザー変数による代替も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/92a16a92-d0b6-3c41-12bc-23764344ac9f.png)

5. その他の内容はデフォルト設定のままで結構です。

6. Data Previewを通じて読み込んだデータが問題なければ、FileStorageの設定を保存します。これでExcelデータをXplentyで扱えるようになりました。TransformationやDestinationコンポーネントを使ったデータ処理を行うのみです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/29c5f78a-3fba-1b09-d4e7-8390b15174ef.png)

## 注意事項
Excelデータはバイナリデータです。 テキストエディタでExcelファイルを開いても意味不明な内容が見えるだけです。

このため、XplentyでExcelデータを扱う際には、2点の注意事項を念頭に置いて頂ければと思います。
1. Excelファイルの容量
弊社のテストによると、正常に読み込まれるExcelファイルの容量は約4メガ程度です。データ量でより分かりやすく言うと、26個のカラムを持つレコードが4万（26×40,000 = 1,040,000）に至る量です。 また、レコードに複雑なExcel関数を多く使う場合は、その容量はより小さくなります。
Excelデータがバイナリ形式であるため、Xplentyが読み込んだ時にファイル容量より数倍に拡張されるからです。 しかし、4万件を超えるレコードというのはデータベースを使用すべきデータ量です。一般的なExcelデータなら問題なくXplentyで処理が可能でしょう。

2. 日時関数
Excelでよく使われる関数が日付と時刻です。 既にご存知の方もいらっしゃるかもしれませんが、これらの関数の戻り値は実際の日付や時刻ではなく数値です。 
Excelがこの数値を適切に変換し、人間が解る日付や時刻のフォーマットに表示するだけです。 Xplentyでは、日付と時刻関数が直接使用されているセルは、日付や時刻に該当する元の数値として読み込みます。
数値ではなく適切な日付や時刻で読み込むには、text関数を使うと期待通りの日付や時刻で読み込めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/cb75f047-3d78-29b6-d285-a4db090e0feb.png)

他の参照系の関数は問題なく実行され、適切なデータが表示されます。

# まとめ
以上でXplentyで新たに取り扱うようになったExcelデータについて色々見てみました。

ビジネス部門で長く愛用されているExcelは、業務に欠かせない必須ツールです。 現場で使っているExcelファイル上の生データをそのまま読み込み、他のデータとすぐ関連付けられる事で、より楽にDXを進められると思います。

本日でも[無料お試し申込](https://try.integrate.io/jp-demo/)により、Xplentyの無料お試しが可能です。Excelデータと他のデータを優雅な連携のご体験は、如何でしょうか？
AWS ECS で任意のコマンドを実行する

これまで Heroku で運用してきたシステムを AWS に置き換える必要が発生し、 `heroku run` と同等の操作が行えないと致命的だったので調査した結果になります。

## 前提条件
* AWS CLI のインストール
* ECSにタスクが定義されている

## 実行方法
`aws ecs run-task` を使えば既存のタスク設定の実行コマンドを上書きして任意のコマンドを実行できます。
例えば、以下はRailsのコンテナを使用したタスク定義で `rake db:migrate` を実行する例になります。

```
aws ecs run-task \
--cluster $CLUSTER \
--task-definition $TASK_ARN \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET_ID], securityGroups=[$SG_ID], assignPublicIp=ENABLED}" \
--overrides '{"containerOverrides": [{"name": "web", "command": ["bundle", "exec", "rake", "db:migrate"]}]}'
```

上記の以下の部分を実行する環境に応じて書き換えてください。
また　`containerOverrides.name` と `containerOverrides.command` を設定内容、実行したいコマンドで書き換えてください。

|キーワード|値|
|---|---|
|$CLUSTER|クラスター名|
|$TASK_ARN|タスク定義のARN (リビジョンを含めないように)|
|$SUBNET_ID|サブネットのID|
|$SG_ID|セキュリティグループのID|


その他の `aws ecs run-task` の仕様、パラメーターについては [公式ドキュメント](https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html) を参照してください。
レコードを更新・削除する前に、対象レコードを特定することの大切さ

## なぜ対象レコードの特定が必要か？

①レコードを更新・削除すると復元できないので、その対象データを特定しないといけない
②カラムに同一の値が複数存在している場合、それを条件指定すると複数のレコードに対して更新・削除を実行してしまう

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/5a332b51-a81a-d1cc-8087-49be1357c26d.png)

userテーブルの抽出条件を「team_id = 1」に指定すると、一致した3レコードに対して更新・削除を実行してしまう
**→プロジェクトメンバー同士でテーブル操作する場合、他メンバーが扱うレコードに影響がない様に、対象レコードを特定するのが基本!!**


## 対象レコードを特定する手順

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/a2d14d32-14ba-5c7f-81c4-efcae0abf705.png)

①テーブル定義から、どのカラムが主キーかを調べる
　**→主キーは同じ値を許可しないので、対象レコードを特定する重要なポイント**

![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/1d81d34c-962a-a80e-6ce4-ae7334119d87.png)

②SELECT文で主キー制約を持つカラムを条件にレコードを取得する

③条件句(上記の画面の場合、「WHERE ID = 8」の部分)は残しつつ、更新ならUPDATE文、削除ならUPDATE文に書き換える
例：
UPDATE SET NAME = 〇〇 WHERE ID = 8;


## まとめ

**どのレコードに対して更新・削除したいかを確認してから、処理を実行しよう！！**
GoogleAdsenceの審査に通らなかったのでとりあえず別の広告(忍者Admax)を導入した

忍者Admaxの広告をWebアプリに導入したので、メモ書き程度ですが諸々共有します。

## 導入経緯
先日、初めて個人開発でWebアプリを作成しました。で、せっかくなのでAdsenceの通し方を調べて利用規約など諸々整備してGoogleAdsenceの審査に出してみたら、見事に通りませんでした(泣)

作成したWebアプリ

https://one-tap-snippet.com/

Adsenceに再申請するのは、アプリのPV数と利用者数を増やしてから、または個人ブログを一旦通したあとにすることにしました。

問題はどこの広告を使うかで、代替候補の広告は何個かありましたが、一旦「忍者AdMax」にしました。
* ちょうど参考にできる記事があった
  → WebアプリはNext.jsで作成していたので、下記の記事を参考にしました。どんぴしゃで助かります。

https://zenn.dev/goshouhiro/articles/react-ninja-admax

* 今のところWebアプリに日本語でしか実装していないので日系企業がやっている媒体
* 審査がないorゆるい
* スマホ用だけでなくPCも対応している
* 広告のジャンルが多い
* 広告の大きさをいくつかの選択肢から選べる
* アダルト広告をオンオフ指定できる

## 導入方法
「忍者ツールズ」でアカウント作成
↓
「忍者AdMax」でアカウント作成
↓
広告枠を追加する から新規作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249463/56292bab-2f05-8206-6f6b-3e33aaa3ce9e.png)
↓
PC用の広告か、スマホ用の広告かを選択
(切り替え広告を作成する場合はそれぞれ1つずつ作成する)
↓
用意されている広告サイズを確認し、自分のサイトのどこに設置するか検討
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249463/ac0e1091-0772-875d-4ca8-aecf68d2816d.png)
↓
サイズを決めたら広告枠名とサイト情報を入力
・サイトタイトル（20文字以内）
・サイトURL
・サイトジャンル
↓
スマホ用の広告も作成する
↓
左のメニューから PC/SP広告切替 を選択して、先程作成した広告たちをプルダウンで選択して進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249463/f4baaa84-8a56-b29c-e15a-4f7d5632939d.png)
↓
広告表示タグが表示されるのでidをメモ。
上記の参考記事を参照してAdsCard.tsxというコンポーネントを作成し、メモしたidをセットすることで広告が表示されるかと思います。表示されない場合は、タグや、URLが正しいかを確認してみてください。
window["admaxads"] あたりで型のエラーが表示される場合は、ルートディレクトリに「additional.d.ts」を作成して、以下のコードで型を追加すると消えるかと思います。

```typescript
/// <reference types="next" />

interface Window {
  admaxads?: AdmaxAdType[];
  __admax_tag__?: { [key: string]: unknown }[];
}
```

以上
Windowsでの作業を快適にしたい（自分用）

随時更新します．
## これはなに
単に**私**好みのキーバインドやこれは良いぞと思ったものを勝手にまとめたもの．
Windowsで長年慣れたひとや，そもそも全然Windowsで作業してて，しんどくない人はブラウザバックしてください．

Windowsは家のデスクトップか研究室，測定用のソフトウェアの制限があるときくらいしか使わないので，セットアップの回数が極端にすくなく，毎回忘れて調べることになるのでまとめました．

ちなみに Windows10 想定です．

## キーバインド系
### Capsを潰そう．
CtrlとCapsを入れ替えるのではなく，CapsをCtrlで上書きします．（私の好み）

以下の記事に従って変更．
https://developlife.jp/capsctrl/

あんまりフリーソフト入れたくないですが，手っ取り早く済ませるならこれ
https://forest.watch.impress.co.jp/library/software/changekey/

### 全人類が大好きな`Emacs`風キーバインド
Emacsを使っていて，Macユーザの方はキーバインドがないと「うぁぁぁぁぁぁ」となる機会が多いでしょう（偏見です）.
Windowsに慣れろといわれればそのとおりですが...

気がつけばChromeのウィンドウは増えていますし，意図せず全選択されますし，文字をデリートしようもんならブックマークされます．

このありがたい記事を参考にしましょう
https://qiita.com/oieioi/items/187aa66fd8a17da6e698

個人的に`AutoHotKey`はあまり使いたくないので，ありがたいです．

## ファイル検索など
Windows 11 はそこまででもないですが，Windows 10 のファイル検索は遅すぎます．遅すぎて，検索完了まで１年ぐらいかかるんかってくらい遅い．

これは本来の機能では改善できません．したがって，サードパーティ製のソフトウェア頼るしかないですが，ファイルを扱うということは，セキュリティ上あまり好ましくないと個人的に思います．仕方ないときはソフトウェアを自作しましょう．

自宅などで，入れていいならこちらがおすすめです．

### 常駐型ファイル検索ソフトウェア
定番中の定番，早くて素晴らしいです．
https://forest.watch.impress.co.jp/library/software/everything/

### Spotlightもどき
WindowsでSpotlightもどきといえばPaper Planeですが，あれは重すぎます．
それにSpotlightが強力であるのは，ファイルの検索もでき，電卓にもなり，Google検索もできるからです．ということで，こんなソフトウェアがあります．

Flow Luancherです．はじめて使ったとき感動しました．よくできています．
https://www.flowlauncher.com/

ちなみに，オープンソースですので，コードよんで問題なければ自分でビルド＆インストールしてもいいかもしれません．