OmniAICreator/Qiita-1.07M huggingface dataset:
神戸高専生向けの高級IDEの導入方法

# みなさん，コードは何で書いてますか？
VSCodeとかSublimeTextとかvimとかnanoとかいろいろありますよね。
これらは全部無料とは思えない出来ではあります。

### でもやっぱりもっと楽に書きたい!!
そんなあなたに**JetBrains製**のIDE(統合開発環境)をおすすめします。

## そもそもIDE使う意味とは
もちろんプログラミングはコードを書くものだと思っている人が多いと思います。
でも実際にはコードを書くだけではプログラミングは完結できません。
Gitなどを利用したバージョン管理や，ターミナルを動かしながらのテスト作業などのたくさんのタスクがあるわけです。
そこでIDEを使えば1つのウィンドウでプログラミングに関係するほとんどのことが完結します。
IDEは作業効率を上げ，より良いソフトウェアを作るための助けになるわけですね。

## でも，お高いんでしょう？
そうです。めっちゃ高いんです。
さまざまな言語が使えるIDEが揃ったAll Products Packは1年間で**93480**円もします。
こんなん学生が買えるわけないです。
### しかし!!!!
神戸高専生ならなんと**無料**で使うことができます!!
鍵になるのは配布されたrから始まるメールアドレスです。
このIDEはGitHub proアカウントを持っている人は無料で使うことができます。
そしてこのproアカウントは学校のメールアドレスでアカウントを作ると自動的についてきます。
このアカウントは開発関連の様々なところで活用できるので覚えておいてください。
## GitHubアカウントの作成
ではまずアカウントから作っていきましょう。
もう既に作っている人は次の導入方法まで飛ばしてもらって構いません。
[このページ](https://github.com/)からGitHubのページまで飛びます。
そして右上のサインアップを押してください。
学校でもらったメールアドレスを入力しパスワードを決めてサインアップすれば完了です。


## 導入方法(Windows)
まず[このページ](https://www.jetbrains.com/ja-jp/toolbox-app/)からJetBrains Toolboxをダウンロードします。
そして，インストーラの指示に従ってインストールしてください。
インストールが完了すると自動で起動されると思います。(起動しない場合はタスクバー右下のアイコンから起動してください)
起動したらもろもろの規約に同意してください。(こういう規約はできればちゃんと読もうね!)
同意が終わればInstallやらなんやらが出てくると思いますがまず右上の歯車マークを押してログインしてください。
ここまでくればほとんど完了です。
あとは使用したい言語のIDEを選択してインストールすれば使えるようになります。

## 導入方法(Mac，Archlinux系)
まずToolboxをインストールします。
もちろんコマンド入れるだけです。

Macの場合
```zsh
$ brew install --cask jetbrains-toolbox
```
Archの場合
```zsh
$ yay -S jetbrains-toolbox
```
インストールが終わったらWindows側と同じように操作すれば完了です。

## 終わりに
めっちゃ高いIDEをタダで使えるだけで高専に来た甲斐があります。
このIDEを使って良い高専ライフを!!!!!
Azure Fundamentals(AZ-900)：Azure の基礎: Azureの管理とガバナンスについて説明する「Azure Cost Managementツール」

Microsoft Learnを用いたMicrosoft Azure Fundamentals(AZ-900)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始める方の参考になれば幸いです。

## 今回の学習内容
**◆「Azure Cost Managementツール」**
◇対応するMicrosoft Learn ラーニングパス
[Azure の基礎: Azureの管理とガバナンスについて説明する](https://learn.microsoft.com/ja-jp/training/paths/describe-azure-management-governance/)
◇対応するモジュール
[Azure Cost Management ツールについて説明する](https://learn.microsoft.com/ja-jp/training/modules/describe-cost-management-azure/6-describe-azure-tool)

※前回の投稿は下記から確認できます。
[Azure Fundamentals(AZ-900)：Azure の基礎: Azureの管理とガバナンスについて説明する「料金計算ツールと総保有コスト計算ツール」](https://qiita.com/fsd-jume/items/870261357f72b799b8e2)

## Azure Cost Managementツール
**リソースのコスト管理や自動化、アラームの作成が可能**

### コスト分析
・コストを簡単に視覚化し、請求サイクルやリージョンなど様々な方法で合計コストを表示可能
・コスト発生元の把握や消費傾向の識別、一定期間の累積コスト表示など、組織のコスト調査や分析も可能

### コストのアラート
**◆予算アラート**
・使用量とコストに基づいて、アラート条件で定義した額に支出が達するか超えた場合に自動的に通知
・Azure Portalでは、予算はコストによって定義
・Azure Consumption APIを使用する場合は、予算はコスト/使用量によって定義
・アラートの生成後、アラートの表示とアラート受信者への電子メール送信を実施

**◆クレジットアラート**
・Azure 前払い(旧称：年額コミットメント)が消費されると通知
※Azure前払いはエンタープライズ契約(EA)を使用する組織用
・アラートは前払いクレジットの使用量が90%および100%になると自動的に生成
・アラートの生成後、アラートの表示とアラート受信者への電子メール送信を実施

**◆部署課金クォータアラート**
・部門の課金がクォータ(割当)の固定しきい値(50%または70%)に達すると通知
・課金クォータはEAポータルで構成
・しきい値に達すると、部署の所有者に電子メールを送信し、アラートを表示

### 予算(Budgets)
・Azureの使用制限を設定
・サブスクリプション、リソースグループ、サービスの種類、その他の条件に基づいて予算を設定
・予算を設定する際に、予算アラートも設定
・予算アラートのトリガー条件が発生した後に、リソースを中断/変更する自動化も可能

## 次の学習内容
**◆タグの目的**

https://qiita.com/fsd-jume/items/7ebec820771e5f6162db

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8
Databricks年次イベント「DATA + AI WORLD TOUR JAPAN 2022」のご案内

Databricks年次イベント「DATA + AI WORLD TOUR JAPAN 2022」の概要、ハイライトをご説明します。開催は**2022/12/6(火) 9:00-18:15**です。
[![JP DAIWT2022_email_sig_template1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2d745206-bad6-750e-ae19-7f7447b3105c.png)](https://dbricks.co/3zg0TMb)

ご登録は[こちら](https://dbricks.co/3zg0TMb)から。

# 概要

データブリックス日本法人による年次イベントとして、「データと AI」活用をテーマにした国内最大級のカンファレンスが、今年も12月にオンライン開催となりました。激動する今日の経営環境を生き抜くために、「データと AI」をいかに活用し、既存ビジネスの変革やインベーションを実現できるのか。その実現するための鍵を握る、データ人材 / 組織、データ文化、そして次世代データ基盤について、業界を代表する企業、専門家、パートナーの皆様と議論いたします。

午前中は、はじめて当イベントに参加される初心者の方向けに、ビジネス系と技術系のセッションに分けて、最新の「データと AI」分野におけるトレンドと、データブリックスのソリューションについて、イントロセッションを設けております。技術セッションは、講義形式と、ハンズオン環境を用意するワークショップ形式のどちらかを選択可能です。

# セッションハイライト

**キーノート**
 - 東京海上ホールティングス 常務執行役員グループ CDO 生田目 雅史 様

**ユーザー事例**

- ソフトバンク様 ビジネス価値創出に向けたデータ基盤について
- リクルート様 ストリーミング基盤の構築やデータブリックス選定理由
- 田辺三菱製薬様 リアルワールドデータ解析を中心としたデータブリックス活用シーン

# アジェンダ

- **9:00** ワークショップ「3時間でわかるDatabricks  の全容！」
- **11:00** （データ活用部門向け）DWH時代の終焉と次世代データ基盤の始まり
- **11:00** （技術者向け）Databricksを支える技術
- **13:00** オープニング
- **13:10** データブリックスキーノート「データとガバナンスのサイロを打破するレイクハウス」
- **13:55** ゲストスピーカーキーノート **東京海上ホールディングス株式会社** 常務執行役員グループ CDO 生田目 雅史　様
- **14:35** **ソフトバンク様**事例紹介セッション: ビジネス価値創出に向けたSBデータ基盤について
- **14:35** **田辺三菱製薬様**事例紹介セッション 田辺三菱製薬におけるDatabricks活用シーン～リアルワールドデータ解析を中心に～
- **14:35** **リクルート様**事例紹介セッション ストリーミング基盤の構築について
- **15:05** <スポンサーセッション1> **日本マイクロソフト株式会社**
- **15:05** <スポンサーセッション2> 「時間もお金もかけない」データ活用の秘訣はデータブリックス **伊藤忠テクノソリューションズ株式会社**
- **15:35** <スポンサーセッション3> 新時代のデータプラットフォームと新たなデータ活用 **株式会社ジール**
- **15:35** <スポンサーセッション4> AI活用先進企業が抱える課題と次世代データ分析基盤の姿 **株式会社NTTデータ**
- **16:05** （データエンジニア向け）Introduction to Data Engineering on Databricks:機械学習・AI開発に必要なデータの収集や蓄積・変換に関するベストプラクティス
- **16:05** （データサイエンティスト向け）MLOps on Databrick: データとMLを連携させAIユースケースを加速させるためのベストプラクティス
- **16:05** （データアナリスト向け）Databricksを活用したデータ分析の事始め
- **16:35** <スポンサーセッション5> データチームの最強の味方、自動データパイプラインで分析基盤を強化！ **Fivetran Inc.** 
- **17:15** パネルディスカッション「データ&AI  活用の国内の現状、日本企業のチャンスと可能性」


# プレミアムスポンサー

- CTC様
- ZEAL様
- NTT DATA様
- Fivetran様
- Microsoft様

[![JP DAIWT2022_email_sig_template2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7253c341-8684-4e0a-b87a-09b542b43d98.png)](https://dbricks.co/3zg0TMb)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
複数条件でレコード（行）を絞り込む(SPSS Modeler データ加工逆引き7-15)

# 複数条件でレコード（行）を絞り込む

![スクリーンショット 2022-10-28 21.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/abcc56a0-88fe-b21d-7b84-f3ece69025df.png)

## 1.想定される利用目的

・データのクレンジング
・モデル精度向上のための絞り込み

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/multi_conditions.str?raw=true

## 3.サンプルストリームの説明

![スクリーンショット 2022-10-28 21.19.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4148d9ad-4b16-9439-78b6-411758864153.png)

a.入力するデータは以下の通りです。
![スクリーンショット 2022-10-28 21.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/32030dae-64b1-eeed-3195-6a9881167b5e.png)

#### 2/25の区分Aのみ抽出する

[Date]が[2022-02-25]と[区分]が[A]のセルを選択して[生成]メニューから[条件抽出ノード（AND）]を選びます。画面左上にノードbが自動生成されます。　
![スクリーンショット 2022-10-28 21.22.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/98e8ed1e-481d-e1f9-c305-6038bedbd918.png)

b.[条件抽出]ノードを編集します。条件が自動記述されています。
![スクリーンショット 2022-10-28 21.23.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1471325b-8980-47bd-7b79-87c1874a5e30.png)

[プレビュー]を実行します。
![スクリーンショット 2022-10-28 21.24.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/34474a70-4823-4995-7c6d-1e2f1f170868.png)

#### 2/25の区分AまたはCを抽出する

c.[条件抽出]ノードを編集します。
![スクリーンショット 2022-10-28 21.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/72e8fc61-a25f-627d-b50e-881f519548fc.png)

[式ビルダー]を起動して式を記述すると便利です。
![スクリーンショット 2022-10-28 21.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3d15ad3b-4912-f610-1c55-8de19de4bf24.png)

[プレビュー]を実行します。
![スクリーンショット 2022-10-28 21.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0433c13e-04e8-718b-251d-029d7c18a23f.png)

#### 注意事項

入力データがランダムに作られているためbとcの動作を適切に確認するためにはaでキャッシュします。

## 4.参考情報

#### [条件抽出]ノードを扱った記事

https://qiita.com/416nishimaki/items/dcb99c48dde67c5adc9a

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
Python＋FastAPIからRequestsにより別APIを呼び出してみる。uvicornでホスティング

PythonとFastAPIを使いAPIを作成し、
getで別のAPIを呼ぶサンプルです。

１．以下をpip installしておく
requests
FastAPI
uvicorn

２．main.pyファイルを作成し、以下を記載
※サンプルとして〒番号を取得するAPIを内部で呼び出している

```main.py
import requests,json
from fastapi import FastAPI
app = FastAPI()

@app.get("/zipcode")
async def ZipCode(zipcode:int = 0):
    url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
    r = requests.get(url)
    print(r.text)
    return {"message":   json.loads(r.text)}
```

３．以下コマンドをmain.pyのある階層で実行
```
python3 -m uvicorn main:app --reload
```

４．実行結果
ParameterQueryに値を設定してGET
無事内容が返ってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/7e895544-eed0-9790-8022-18b91e12be22.png)
【データ基盤構築/BigQuery】UNPIVOT演算子を使って、横持ちデータを縦持ちに変換する

# 今回の課題
横持ちのデータを縦持ちのデータに変換したい。
**横持ちのデータは生データで見る分には見やすいが、
SQLでの集計や BIツールでの可視化には向いていない。**

今回はUNPIVOT演算子を使用して、データの変換を行った。


# UNPIVOT演算子とは
列を行に変換する演算子。(横持ちのテーブルを縦持ちに変える。）
FROM句の一部として考える。
### 文法
```SQL
select
    *
from
    `テーブル名`
    unpivot
    [値の出力列名][, ...]
    for [項目の出力列名]
    in ([出力項目][, ...])
    )
```
* 項目の出力列名・・・UNPIVOTされる前の列名が入るカラム名。
* 値の出力列名　・・・UNPIVOTされる前の列の値が入るカラム名。
* 出力項目　　　・・・`項目の出力列名`内に入る項目の一覧。ASで列名をつけることも可能。
※参考：[【BigQuery】PIVOT/UNPIVOT演算子を試してみた](https://www.true-fly.com/entry/2021/07/26/073000)

# 使用例
成績表のテーブルがあったとする。
|name|english|math|japanese|
|:-:|:-:|:-:|:-:|
|yamada|5|2|3|
|satou|1|1|4|
|suzuki|2|1|5|

上記のテーブルに対して、下記のクエリを実行すると、
```SQL
select
    name
    , subject -- 科目
    , record  -- 成績
from
    `テーブル名`
unpivot (
    record
    for subject
    in (english as '英語', math as '数学', japanese as '国語')
    )

```

このように、縦持ちのデータに変換することができる。
|name|subject|record|
|:-:|:-:|:-:|
|yamada|英語|5|
|yamada|数学|2|
|yamada|国語|3|
|satou|英語|1|
|satou|数学|1|
|satou|国語|4|
|suzuki|英語|2|
|suzuki|数学|1|
|suzuki|国語|5|

以上です。

# おまけ
縦持ちのデータを横持のデータに変換する場合はどのようにすればいいか、
念のためこちらにメモを残す。
**横持ちデータは、目視で見やすいところ**が長所。

### 横持データに変換する方法
* PIVOT演算子を使用する。([BigQueryでPreviewになったPIVOTとUNPIVOTを試す](https://dev.classmethod.jp/articles/bq-new-pivot/))
* CASE式を使用する。([SQLのCASEを使ったテーブルの縦横変換](https://qiita.com/omokawa_yasu/items/0c4e23be3328be8a4a5a))
EXCEL VBAで半角カタカナを全角にする

半角のカタカナのみを全角に変換したい時がありますが、例えばEXCELの式だと、英数字も全角にしてしまったり、ひらがなや漢字もカタカナにしてしまったりと、あと一息です。
半角カタカナを含むCSVを読み込んで、全角カタカナに変換したCSVを吐き出すVBAを書きました。ご参考まで。

* ANSI Shift-JISのみ対応です。
* 一旦全角に変換した後、アルファベット、数字、記号を半角にします。
* ダブルクォーテーションは全角のままにしています。

ご利用は自由です。自分の環境では自分の期待通りに動いていますが、保証の限りではありませんので、利用は自己責任でお願いします m(..)m

```vb

Sub Main()
    '変換元のファイル名を指定してください(ANSI Shift-JISのみ対応)
    infile_name = "D:\変換元.csv"
    
    '変換後のファイル名を指定してください
    outfile_name = "D:\変換先.csv"
    
    
    '変換元、変換後のファイルを開きます（変換元=読み取り専用　変換後=上書き）
    Open infile_name For Input As #1
    Open outfile_name For Output As #2
    
    'ファイルを順次読み込みます
    Do Until EOF(1)
        Line Input #1, buf
        
        'まず、すべてを全角文字に変換します
        buf = StrConv(buf, 4)
        
        outbuf = ""
        For lp = 1 To Len(buf)
            outbuf = outbuf & tohalf(Mid(buf, lp, 1))
        Next lp
        
        '1行中にカンマがひとつだけあることを確認します
        If Len(outbuf) - Len(Replace(outbuf, ",", "")) <> 1 Then
            MsgBox "カンマの数がひとつではありません[" & outbuf & "]"
        End If
        
        '変換結果を出力します
        Print #2, outbuf
    Loop
    
    '変換元、変換後のファイルを閉じます
    Close #2
    Close #1
End Sub

'全角のアルファベット、数字、記号を半角に変換するサブルーチン（全角のダブルクォーテーションは半角に戻さない）
Function tohalf(str)
    fullstr = "ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ０１２３４５６７８９！＃＄％＆＇（）－＾\＠［；：］，．／\＝～｜｀｛＋＊｝＜＞？＿"
    halfstr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'()-^\@[;:],./\=~|`{+*}<>?_"
    
    tohalf = Replace(str, Chr(9), ",")
    For lp = 1 To Len(fullstr)
        If str = Mid(fullstr, lp, 1) Then
            tohalf = Mid(halfstr, lp, 1)
            Exit For
        End If
    Next lp
End Function

```
NetBSDポートの最初の一歩

NetBSD/armではhoge_start.Sから始まります。

http://www.tokuda.net/diary/0803

実際始まってるか確認してみましょう。

m83xxxのuartは0x10090000の物理アドレスにあります。

u-bootで確認してみましょう。

```
Comcerto-1000 > mw.b 10090000 4e
NComcerto-1000 >
```

文字が出ますね。

ではカーネルコードで同じことをしてみます。

```
--- a/sys/arch/evbarm/mindspeed/m83xxx_start.S
+++ b/sys/arch/evbarm/mindspeed/m83xxx_start.S
@@ -48,6 +48,9 @@ RCSID("$NetBSD: m83xxx_start.S,v 1.7 2020/11/28 14:29:31 skrll Exp $")
        .global _C_LABEL(m83xxx_start)
 
 ENTRY_NP(m83xxx_start)
+       ldr     r2, .Luart
+       mov     r1, #78
+       strb    r1, [r2]
        cpsid   if, #PSR_SVC32_MODE
 
        /*
@@ -126,4 +129,6 @@ ENTRY_NP(m83xxx_start)
        .word   0x80000000|L1_S_AP_KRW|L1_S_C|L1_S_B|L1_TYPE_S
 .Lio_pde:
        .word   0x43f00000|L1_S_AP_KRW|L1_TYPE_S
+.Luart:
+       .word   0x10090000
 END(m83xxx_start)
```

これでビルドしたカーネルを起動してみます。

```
## Booting image at 81000000 ...
   Image Name:   NetBSD/m83xxx 
   Image Type:   ARM NetBSD Kernel Image (uncompressed)
   Data Size:    3850320 Bytes =  3.7 MB
   Load Address: 80100000
   Entry Point:  80100000
   Verifying Checksum ... OK
OK
## Transferring control to NetBSD stage-2 loader (at address 80100000) ...
N
```

文字が出たので、ちゃんと実行が移っていることが確認できました。これでビルドシステムが正常なことが分かります。

"## Transferring..."はu-bootのNetBSDサポートコードが出しているようです。

この後のstartは/sys/arch/arm/arm32/locore.Sにあります。

実はこれは古い方法で、arm/arm/armv6_start.Sというv6以降の共通ルーチンが用意されたようです。こちらに変更してm83xxx_start.Sは消しました。

v5以前ついては個別のstart.Sが必要です。

古い実装はhoge_start.Sとhoge_machdep.cというコードをそれぞれのターゲットごとに用意していたようです。hoge_machdep.cにはinitarmがあり、かなりがりがり書かれていました。ほとんど同じ処理なのでarm/arm32/arm32_*.cに共通化したコードがあるので、これを呼ぶだけでよくなっています。

実はcomcertoの実装で同じ1136なimx31をコピーしていじったのですが、imx31はまだがりがり書かれたままのコードでした。なぜかv5なimx21の方は共通コードになっていたので、こちらも参考にしました。

arm32_*.cは後から作られた物っぽいですがFDTの非対応でも使えるようです。

すでに対応のあるアーキテクチャのSOCをポートする時はuart,割り込み,timerがあればrootのマウントまでたどり着けます。

uartは設定はu-bootがおこなっているので、まずはputcだけを用意すればよいです。

アーキテクチャ固有の処理が終ると、kern/init_main.cのmain()が実行されます。

新しいSOCにポートする時は既存のコードをコピーして始めますが、コピー元がメンテされてて筋が良いものを選ぶのが重要です。また対象のターゲットのアーキテクチャがシンプルなものがいいです。見極めるのは結構難しいです。NetBSDは疎いので結構はまりました。

Redbootでputcharはこうします。

```
RedBoot> mfill -b 0xc8001000 -l 4 -p 0x4e
NRedBoot>
```

c2kではこうでした。

```
Barebox-C2K >/ memset 0x96400000 0x4e 1
NBarebox-C2K >/ 
```

現実的に使えるようにするには最小限、uart,割り込み,タイマー,Ether,ストレージ(USB)の実装が必要です。
SvelteKit を使った静的サイトへのデプロイ

# はじめに

先日、以下の投稿で、SvelteKitを使いましたが、今回は実際に
静的サイトとしてデプロイするための準備について記載します。

https://qiita.com/ryotaro76/items/38875593509e69c60d69

# Adapters
公式サイトによると、デプロイする前に環境に合わせて設定をする必要があるようです。

https://kit.svelte.jp/docs/adapters

# 静的サイトにデプロイするための準備
## インストール
アダプターを使うため、インストールをします。

```bash
npm install -D @sveltejs/adapter-static
```

## 設定を修正する

svelte.config.js ファイルを、以下のように修正します。

```diff_javascript
- import adapter from '@sveltejs/adapter-auto';
+ import adapter from '@sveltejs/adapter-static';
import preprocess from 'svelte-preprocess';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	preprocess: [
		preprocess({
		  postcss: true,
		}),
	  ],

	kit: {
-		adapter: adapter()
+		adapter: adapter({
+    		pages: 'build',
+			assets: 'build',
+			fallback: 'index.html',
+			precompress: false,
+			strict: true
+		})
	}
};

export default config;
```

## ビルドする
設定は以上です。ここまで終わったらビルドしましょう。

```bash
npm run build
```

こんな風に、index.htmlが生成されていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/c2e5f7f6-b863-c039-7dd0-35c8466e621f.png)

# 最後に

無事、静的コンテンツにすることができました。
この後は、これをSpring Bootに組み込んで、みたいと思っています。
多言語FizzBuzzチャレンジ1日目:Go言語

## はじめに

一日一善ならぬ一日一FizzBuzzでもしてみよう、ということでアドベントカレンダーを立ち上げました。

https://qiita.com/advent-calendar/2022/multilang_fizzbuzz

- 毎日異なる言語でFizzBuzzをしてみます。
- 速度やコード量削減等にはこだわらず、ベーシックに実装していきます。
- 触ったことのない言語が大半なので、至らないところは優しくフィードバック頂けると泣いて喜びます。


初日ぐらいは馴染みのある言語から始めたい、ということで、本日はGo言語でFizzBuzzしてみましょう。

## 扱う言語
https://go.dev/

## FizzBuzz
https://go.dev/play/p/g0QIklJ0-Xy

```go:main.go
package main

import "fmt"

func main() {
	for i := 1; i < 101; i++ {
		if i%15 == 0 {
			fmt.Println("FizzBuzz")
		} else if i%3 == 0 {
			fmt.Println("Fizz")
		} else if i%5 == 0 {
			fmt.Println("Buzz")
		} else {
			fmt.Println(i)
		}
	}
}
```

- ひとまずベーシックに書いてみましたが、個人的には`else if`まで使うのがあまり好きではないので、`i%3 == 0`や`i%5 == 0`をあらかじめ計算し、そのbool値の組合せで単発if分を組んでearly returnさせるようにしたいところです。（賛否両論ありそうなので、今回はベーシックに…。）

## おまけ：実行方法
```shell
go mod init fizzbuzz
# edit main.go
go run .
```
iTerm2でProfileごとにHotkeyを設定し起動する方法

MacのiTerm2で、Profileごとにターミナルを起動するために、それぞれのHotkeyを設定する方法についての記事です。

おまけで初回起動時にコマンドを実行する設定についても記載しています。

## 基本的なProfile別の立ち上げ方法

Hotkeyを使わないでProfileを指定してiTerm2を起動するには、iTerm2アプリアイコンを右クリックして、New Window… > から選べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706663/f1aaaf0b-73b4-06ac-90e8-aa81f76815eb.png)

## ショートカットキーでProfile別に起動

DefaultProfileに対してHotKeyを設定されている場合は同様に別のProfileにもHotKeyを設定したくなると思います。

その場合は iTerm2のメニューの > Preferences > Profiles > [該当のProsile] > Keysタブ > Configure Hotkey Window をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706663/b2dbc22d-0c21-7985-60d2-dd392edda2b1.png)


そうすると設定のポップアップが表示されるので、Hotkeyと書いてある右側の枠をクリックし、好きなキーボードを打ちます。

下の画像では Option + 0 を押して設定している例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706663/db4e3792-0329-f7fa-f724-98c68e92f4d1.png)

あとは右下のOKをクリックすれば、好きなProfileでiTerm2を簡単に起動できます。

僕の場合は

- デフォルトのProfileは Option + Space で起動し、
- もう一方のProfileでは Option + 0 で立ち上げることができるように設定してみました。


## Profileごとに初回実行コマンドを設定

iTerm2 には 各Profile設定ごとに起動時に実行するコマンドを設定できる場所があります。

場所は iTerm2のメニューの > Preferences > Profiles > [該当のProsile] > Generalタブ > send text at start という項目のところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706663/9454da0f-b9e9-eb26-660a-b7d17ea5626d.png)
ここに好きなコマンドを入力しておくことで、そのProfileのターミナルを起動した際に実行されます。

例えば

- DefaultのProfileは通常のターミナルとして使用し、
- 別のProfileでは起動と同時にPython対話モードで始める、

なども可能です。

この例自体に需要があるかわかりませんが、この例のように初回にPython対話モードを起動する場合は、Send text at start: のところへ `Python3;` のように記載します。

セミコロンをつけていれば他のコマンドも記載できます。

コマンドは自由にしていただけるので、カスタマイズされた状態で起動して作業を始めることができます。

同じような要望をお持ちの方ぜひ本記事の内容を試してみてください。
setState関数をPropsで渡すときの型定義

React.jsでもNext.jsでも、useStateを利用することがあると思います。

次のコードは、ボタンを押すとカウントアップできる例です。

```tsx
// App コンポーネント
import React from "react";

const App = () => {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h2>Current Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;
```

ここで、何らかの事情で `button` 部分は別コンポーネントで実行したいとします。

仮に Button コンポーネントを作成してみます。

```tsx
// Button コンポーネント
import React from "react";

const Button: React.FC<{
  count,
  setCount;
}> = ({ count, setCount }) => {
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Button;
```

TypeScriptなので、Props の `count` と `setCount` に型定義を行います。

 `count` に関しては元のままここでは `number` を定義しておきます。

```tsx
React.FC<{
  count: number;
  setCount;
}>
```

問題は `setCount` の方です。

setCountは関数なので `setCount: Function;` でもいいですが、もっとしっかり定義する場合は次のようにします。

```tsx
React.FC<{
  count: number;
  setCount: React.Dispatch<React.SetStateAction<number>>;
}>
```

これでsetState関数をPropsで渡す場合もしっかり型定義できました。
LPC812にLチカを書き込で遊ぶ(4)(ロング記事)(ブレッドボードの組み立て)


目的
シリアルを繋ぐ
電池を繋ぐ

回路図


![o_cop218.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fe3f2f83-074b-e227-d214-3dd452514f04.jpeg)



完成図

![o_cop219.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f3b56517-9a5c-fb27-57b3-1d8018073cbb.jpeg)
Amazon EKSでIRSAを利用する

# はじめに
IRSA(IAM Roles for Service Accounts)とは、EKSクラスタ上で稼働するPodに対してIAMロールを割り当てる仕組みです。
Mac環境を想定しています。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

1.  EKSのコンテキストの設定
[MacにてAmazon EKSの設定をする](https://qiita.com/miyabiz/items/b98d145cedb35dab9524)を参考にしてください。

# IAM OIDC IDプロバイダの作成
[クラスター用の IAM OIDC プロバイダーの作成](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)を参考にしてください。

1.  クラスタ名を設定する

    ```sh
    CLUSTER_NAME=${クラスター名}
    ```

1.  IDプロバイダを作成する

    ```sh
    eksctl utils associate-iam-oidc-provider \
      --cluster ${CLUSTER_NAME} \
      --approve
    ```

# IAMロールとサービスアカウントの作成

1.  IAMロールとサービスアカウントを作成する
    ※今回はロール名を`akane-dev-irsa-service-account`にしています。
    ※今回は`AmazonS3ReadOnlyAccess`を設定する。

    ```sh
    NAMESPACE=akane
    eksctl create iamserviceaccount \
      --name akane-dev-irsa-service-account \
      --namespace ${NAMESPACE} \
      --cluster ${CLUSTER_NAME} \
      --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
      --approve
    ```

# 環境設定
※事前にKubernetesクラスターのコンテキストの設定をします。

1.  `akane-namespace.yaml` を作成する
    ```yaml:akane-namespace.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: akane
      name: akane-irsa
      labels:
        run: akane-irsa
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: akane-irsa
      strategy: {}
      template:
        metadata:
          labels:
            run: akane-irsa
        spec:
          containers:
          - command:
            - /bin/sh
            - -c
            - sleep 500
            image: amazon/aws-cli
            name: akane-irsa
            resources: {}
          serviceAccountName: akane-dev-irsa-service-account
    ```

1.  クラスターに適用する

    ```sh
    kubectl apply -f akane-deployment.yaml
    ```

1.  Podにログインする

    ```sh
    kubectl -n akane exec -it $(kubectl get po -n akane -o=jsonpath='{.items[0].metadata.name}')  sh
    ```

1.  S3のアクセス権限を確認する

    ```sh
    aws s3 ls
    ```


# クリーンアップ

1.  クラスターから削除する

    ```sh
    kubectl delete -f akane-deployment.yaml
    ```

1.  IAMロールとサービスアカウントを作成する

    ```sh
    NAMESPACE=akane
    eksctl delete iamserviceaccount \
      --name akane-dev-irsa-service-account \
      --namespace ${NAMESPACE} \
      --cluster ${CLUSTER_NAME}
    ```

1.  IAM OIDC IDを削除する
    `eksctl delete cluster`を実行するとクラスターと一緒に削除されます。
LPC812にLチカを書き込で遊ぶ(3)(ロング記事)(シリアルの組み立て)

目的
シリアルを使えるようにする

完成図

![o_cop214.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/019d3018-1a46-d66d-ed1b-7bb30902bbe0.jpeg)



ＦＴ２３４Ｘ　超小型ＵＳＢシリアル変換モジュール
	通販コード　M-08461

ピンソケット（メス）　１×４（４Ｐ）
	通販コード　C-10099

ＵＳＢケーブル　ＵＳＢ２．０　Ａオス－マイクロＢオス　１．５ｍ　Ａ－ｍｉｃｒｏＢ
	通販コード　C-07607

ブレッドボード・ジャンパーワイヤ（オス－オス）セット　各種　合計６０本以上
	通販コード　C-05159

抵抗内蔵５ｍｍＬＥＤ　５Ｖ　黄色　５９０ｎｍ　ＯＳＹ５ＬＵ５Ｂ６４Ａ－５Ｖ（１０個入）


![o_cop209.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/096350c5-8e8b-ed5d-a05e-c3878c95a3ba.jpeg)

![o_cop210.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/264598f9-e6ba-606e-1693-564448e9bb9e.jpeg)

![o_cop211.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6bcc60d3-4f77-261b-0438-65e18cc7aac2.jpeg)

![o_cop212.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8f41c4f4-e81e-b7fa-32a1-0ca94065da69.jpeg)

![o_cop213.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8898ffec-463c-35e9-c4e7-17e530037962.jpeg)


--------------------------------------------------------

組み立て

1. 4ピンソケットを半田付けする。
2. USB変換機をケーブルに繋ぐ。
3. TXは、緑、RXは、黄色、GNDは、黒に繋ぐ。
4. LEDは、Lチカよう
5. おわり


![o_cop215.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f1f51688-356c-1a66-2373-78b20824447e.jpeg)

![o_cop216.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4019f90e-a28a-f144-56ed-0ff5e5089478.jpeg)

![o_cop217.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aa1551c0-66b9-762f-0bed-a563b47af46d.jpeg)
LPC812にLチカを書き込で遊ぶ(2)(ロング記事)(電源の組み立て)


x 電池で動いているのでもしかしたら、書き込み時に電圧が低いかも

x 通常動作させる場合は、今のところ問題なし。前の実験では、アップコン
挟んだ方がなぜか電池が長持ちした。
電圧の昇電回路で約1割ロスるが電池の最後まで使えると電池が長持ちする。

x 付属の200Ω程度でもかなり、まぶしい。


目的
マイコン用の電源を作る


ＣＲ２０３２電池電源ボードキット
	通販コード　K-09184


![o_cop208.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1c2a5a4d-0ae2-ffb4-11dc-d847b0f8f6c0.jpeg)


----------------------------------------------------------

組み立て例


![o_cop228.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/73955b99-7424-e93a-14b0-101ace290d44.jpeg)

![o_cop229.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/633aab0c-72b0-d5d2-c259-5816826fa083.jpeg)
Get number from string in python

```python
import sys
import re

a = sys.argv[1]
print(a)
m1 = re.search("[^0-9\.]", a) # str
m2 = re.search("[0-9\.]", a)  # num
if m1 and m2:
  print("m1.start(),m2.start():",m1.start(),m2.start())
  if m1.start() > m2.start():
    ret = a[:m1.start()]
  else:
    ret = a[m2.start():]
    print("ret:",ret)
    m3 = re.search("[^0-9\.]", ret)
    if m3:
      ret = ret[:m3.start()]
elif m1:
  # only str
  ret = ""
elif m2:
  # only num
  ret = a
print("ret:",ret)
```
Google Cloud Next '22 で GAが発表されたCDNの自動圧縮機能の紹介と所感

# はじめに
前回のBatchに引き続き、気になったサービスや機能を実際に動かしてみます。
前回記載もしていますが、こちらベースでみていきます。

https://cloud.google.com/blog/ja/topics/google-cloud-next/google-cloud-next22-wrap-up

今回はGAされたCDNサービスの動的圧縮をご案内します(実際に試せていません)。

# Cloud CDNの自動圧縮機能の紹介
今回はこちらです

https://cloud.google.com/cdn/docs/dynamic-compression

もともとのCDNの機能については以前の記事でも触れましたので、
もしその点からご覧になられる方は以下ご覧ください(後半の注意事項が重要です)。

https://iret.media/65183

今回の機能は自動圧縮が可能となり通常のケースで60-85%はネットワーク経由で送信されるデータサイズが減少するようです。
エッジからクライアントまでのところのデータ送信サイズが圧縮され大きな効果が得られます。

ユースケースや効果としては以下のようなものが挙げられています。
・CSSとJavaScriptのサイズ縮小され、ページ表示の高速化により、FCPが改善される
　※元の記事のURL引用ですが、FCP(First Contentful Paint)は以下参照
　　https://web.dev/first-contentful-paint/
・JSON ペイロードなどの REST API レスポンスをキャッシュに保存する際に大きな効果が得られる
　※こちらはキャッシュに保存しなくても圧縮自体の恩恵は得られるような記載があります。
・動画配信の再生開始時間とライブ ストリーミングの参加時のレイテンシが改善される

# 自動圧縮有効化する
CDNはもともとあった機能なので、該当の設定項目自体を掲載します。
すごくサラッといきますが、、、
![自動圧縮有効化画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/29a2d3b5-1f34-c3de-268a-7709e9d0909b.png)
Cloud CDN 内の編集画面で「自動」へ変更するのみとなります。

## 注意事項
ドキュメントに以下の記載がありましたのでこちらを注意し効果について確認ください。
> ・Cloud CDN 対応のグローバル外部 HTTP(S) ロードバランサ（従来）とバックエンドが構成されていることを確認します。Cloud CDN を構成していない場合は、いずれかの設定ガイドの手順で構成できます。
・バックエンドには、1 KiB～10 MiB の配信可能な圧縮可能コンテンツ（ウェブアセットや動画マニフェストなど）が存在します。
・クライアントが、範囲リクエストまたは強力な ETag を使って部分的なコンテンツを取得していないことを確認します。これらは、動的圧縮に対応していません。
・バックエンドの構成を変更するには、IAM Compute ロードバランサ管理者ロール（roles/compute.loadBalancerAdmin）が必要です。

また、上記以外でも圧縮モードでの挙動、圧縮される場合の挙動、レスポンスが圧縮されない場合のその理由、など、前半の「CDNの自動圧縮を試してみる」にて記載したURLに記載があるので、確認してみてください。

# 所感
本当は機能自体を試してみたかったのですが、すぐに圧縮可能なサイズが準備できませんでした。。すいません。そのため、今回は機能のみの案内となりますが、この機能により、キャッシュ利用時の表示スピードを更に高速にすることが可能となりました(変な日本語ですが、早くなるということが言いたいです)。自動圧縮の判定基準によりデメリットを受けない限り、利用したほうがよい機能追加なのではないでしょうか。コンテンツが準備できるようでしたら、情報アップデートし、実際にサイズ比較してみたいと思います。
wuff でロバストかつ早い画像圧縮アルゴリズムの C 言語でのデコーダーエンコーダー作りたいメモ

## 背景

fpng の PNG のデコードとエンコード, チョッ早ですごいねぇ...

https://github.com/richgel999/fpng

比較されている wuff っていうのも負けてないっぽいようね, で知りました

## wuff

https://github.com/google/wuffs

相変わらず紛らわしい名前でつらい(みんな GNU screen の wuff と思うよね)

正確には wuff 言語から, ロバストかつ高速な(SIMD 命令も使う)アルゴリズムのコード(主に LZW とかなどの画像圧縮アルゴリズム)を生成するツールとライブラリです(機械学習でいう JAX ライブラリみたいな).

https://github.com/google/wuffs/tree/main/std

に例がありまして, よく使われるようなのはすでに https://github.com/google/wuffs/tree/main/release/c にあるのでこれをぺろっとつかえば OK そう.

## TODO

* [ ] LosslessJPEG を wuff を使って記述し, TinyDNG の DNG(LZW, LosslessJPEG)　のデコードとエンコードを早くする.
いまさらAI学んでみた（第１回）

# はじめに
こんにちは、株式会社ジールの[@Suguru-Terouchi](https://qiita.com/Suguru-Terouchi)です。

久しぶりの投稿になります。

これからAIを勉強していきたい！という方へ向けて、
AIの基礎についてなるべく簡単に分かりやすく書いていきますのでお役に立てれば幸いです。
※有識者の方はご指導頂けると幸いです。（こっちが本音）

# いまさらAI
だけどまだまだハードル高いと感じている方も多いのではないでしょうか。
私もこれからAI領域の学習を始めていきたいと思いますので、一緒にお付き合い頂ければ幸いです。

さて、学習を始めていくにあたり超基本的なことからまとめていきたいと思います。

# そもそもAIって？
まずは言葉の定義からですが、アーティフィシャル・インテリジェンス（AI：Artificial Intelligence）の略語になります。
・・・と言われても良く分からないですよね、私は分かりません。

とりあえずGoogle先生に聞いてみると、「AI」、「機械学習」、「ディープラーニング」というワードがたくさん出てくると思いますが、
この違いをちゃんと説明出来る人はいますか？出来る人は間違いなくイケメンです。
AIは**人間と同じような判断・動作ができる技術（いわるゆるプログラム）**
機械学習は**AIの技術を実現するための仕組み**
ディープラーニングは**機械学習を実行するための手法の一つ**
です。これで明日からみなさんもイケメンの仲間入りですね。

巷で良く聞くAIさんは「画像認識」や「言語処理（チャットボット）」、「処理自動化・最適化」、「傾向予測」などでご活躍されているようです。
あの自動でお掃除してくれるニクいヤツや話しかけるといろいろ教えてくれるあの子とかですね。

これら全て共通して「INPUT」と「OUTPUT」が存在します。まあ、プログラムなので当たり前っちゃ当たり前ですよね。
人間がなにかする時、↓のイメージの「？」部分でなにかを考えて行動をしていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1963640/91f2d222-ab78-c406-f213-e23a44f68831.png)

この「？」の部分をAIとしてプログラムされていると思うとイメージしやすいのではないでしょうか。

ではこの「？」の部分ってなにが行われているんでしょうか？
人によって様々かも知れませんが、多くはその人の知識や過去の経験から考えて判断、行動していると思います。

たとえば・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1963640/51ab5a42-2eef-d8b8-1d88-abfd63c2f9b7.png)
この絵を見て、ほぼ全ての方が「ネコ！」と答えると思いますが、
これってネコってこういうものって知っているからですよね。
赤ちゃんやネコを一度も見たことない人だと答えられないかも知れません。

あれ、でもプログラムで過去の経験ってどゆことよ？
たしかに人間は記憶という形で脳に刻み込まれているので出来ることで、
プログラムだとデータベースでも使うのか？と思いますよね。

ちゃんとそういった仕組みが用意されています。
この仕組みが機械学習のメインになりますが、長くなるので次回にさせてください。
この概念を実現する技術がAIであると言うことですね。

# おわりに
いかがでしたでしょうか。
良いところで止めてしまって恐縮ですが、少しでもAIが身近に感じて頂けたなら幸いです。

次回はAI、機械学習の仕組みについて書きたいと思います。

# データ活用をサクッと始めるなら！
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください：
 
https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area
いわゆる受託開発における「プログラミングは簡単な部類」は本当なのか

https://twitter.com/yonemura2006/status/1565442489913266177

上記ツイートについて、いわゆる「受託開発企業」で働く私の印象としては、本当にその通りだな〜と思います。
そして、これまであまり意識しておりませんでしたが「受託開発における納品（完了）までの各フェーズ出し」をしてみようかと思います。

# 受託開発における納品までの各フェーズ出し

**１. :smile: 問い合わせへの返答**
「お問合せいただきありがとうございます。それでは早速Webミーティングにて詳細を」

**２. :blush: 第１回Web打ち合わせ「お互い紹介」編**
会社スライドにて自社紹介。依頼内容の確認・質問。
できればここで「依頼内容に対してのざっくりの予算感」をさりげなく聞きましょう。奇想天外な予算を想定しているパターンもあります。

**３. :smirk: 見積もりの作成**
できるだけ素早く見積もりを作成し提出すると吉。（早いと喜ばれやすい）
保守費用についても記載してくださいね。（後で聞かれるパターン多い）
見積もり項目は細かい方が信頼度はあがります。（逆に細かすぎると嫌らしいので程よく）

**４. :hushed: 第２回Web打ち合わせ「見積もり内容を確認しながら」編**
ここでしっかりと言葉を添えて納得してもらいましょう。不要な項目も洗い出せるとお互い吉。

**５. :relieved: 最終回答待ち**
依頼者が業者選定をしている期間です。じっくり待ちましょう。

**６. :sweat_smile: 第３回Web打ち合わせ「別の担当者も交えてお願いします」編**
今度は問い合わせ依頼者が「別の担当者も含めてもう一度ミーティングできますでしょうか？」と言ってきますので、もう一度打ち合わせをしましょう。この辺りから少しずつメンタルが削られていきます。
大体、上層部かエンジニアが出てきます。

**７. :relieved: 最終回答待ち**
依頼者が業者選定をしている期間です。じっくり待ちましょう。

**８. :heart_eyes: 選定**
２週間後ようやくメールが届きます。晴れて弊社が選定されました。
依頼者に感謝のメール文面を作成ししっかりと返信しましょう。

**９. :grimacing: 書面作り・契約書交換**
契約書はしっかりと今のうちに交わしておきましょう。ここ好きになれない工程です。
そして最近だとDocuSign（ドキュサイン）だと楽だから嬉しいです。
発注書とかもここであるかも

**１０. :kissing: 第4回Web打ち合わせ「キックオフ」編**
ようやくプロジェクトのスタートです。インフラ（AWS）環境のアカウントはどちらが作成するのか等、基本的なところをバシバシと決めていきましょう。Slack・チャットワーク等を交換しておくと今後捗ります。

**１１. :expressionless: 要件定義・基本設計**
がんばりましょう。この後のフェーズ全ての源になります。

**１２. :confused: 第５回Web打ち合わせ「設計の共有」編**
設計した内容について（依頼者がよくわからなくても）噛み砕いて説明しましょう。方向性だけでもわかってもらえばOKです。

**１３. :smile:  環境設定・インフラ構築**
最近だとDockerとかでしょうから、初期のAWSとなどのインフラ構築はいらないかもですね。
でも、docker-compose.yml とかは触りますよね。

**１4. :sunglasses: 開発・プログラミング**
よ〜〜〜〜〜やく到達しました「プログラミング」！。
がしがしやっていきましょう。

**１５. :neutral_face: 共有**
開発途中のキリが良いタイミングでチャットベースで開発環境URLを共有し実際に触ってもらいましょう。
開発段階に入るとこちらの頑張りフェーズです。Web打ち合わせは極力減らしながら依頼者とは文字ベースで対話して進めると吉。

**１６. :scream: 動作テスト**
動作テスト

**１７. :sob: 第6回Web打ち合わせ「フィードバック」編**
実際にアプリケーション全体を触りながらフィードバックを受けましょう。

**１８. :mask: 開発（フィードバック対応）**
慎重にそして、がしがしとやっていきましょう。

**１９. :persevere: CI/CD設定**
いまやデファクトスタンダードというやつでしょうか。

**２０. :angry: 第７回Web打ち合わせ「中間報告」編**
一旦、クリティカルな認識齟齬が発生していないか一度打ち合わせをします。
問題なければ開発再開。

**２１. :tired_face: 動作テスト・バグだしおよび修正**
動作テスト・バグだしおよび修正

**２２. :astonished: 負荷テスト**
負荷テスト

**２３. :expressionless: 死活監視・リソース監視**
死活監視・リソース監視・アプリケーションエラー監視の設定。
またそれぞれのチャットへの通知設定。
もう一回負荷テストすると良いかも。

**２４. :flushed: 第8回Web打ち合わせ「納品およびリリースに向けて」編**
**新規サービス** リリース日。
**システムリニューアル** メンテナンス日。
などを決めましょう。
また納品資料共有と画面操作方法のレクチャーもこのあたりで。

**２５. :innocent: 納品およびリリース作業**
ここから保守費用期間スタート。

**２６. :innocent: 請求書送付（完了）**
スマートに請求書を送付しましょう。
チームの皆さん本当にお疲れ様でした！

## 総括

こんな感じでしょうか。やるべきこと書き出してみたことでより明確になりました。
本題に戻りまして「プログラミング」は簡単な部類」というのは言い得て妙ですかね。

「`クライアントとの折衝も終わり、設計も終わり、あとは頑張るだけ`」の段階に位置しているかと思います。そういった意味では、精神的には少し余裕がでているフェーズなのかもしれません。

今後は、上記のステップを意識することで「今、この案件ってどのフェーズなのか？」を確認することができ、時間的コストパフォーマンスが計測しやすそうです。
   
## 受託開発

「受託開発」。ものすごく大変そうなイメージを持たれたかもしれませんが、色んな人・色んな企業さん・色んなエンジニアのコードとの出会いがあり面白いです。そして無意識でコミュニケーション能力は向上しますので、意外とおすすめです。

以上、今後とも何卒宜しくお願いいたします。（←無意識）

# 関連記事

以前も「受託開発における見積もり」に関する記事も書きましたので、読んでもらえると幸いです。

https://qiita.com/emacs_hhkb/items/41b9d35425f48cc91fa1
これからエンジニアとして新社会人を始める人へ。焦りという呪いの解呪方法について

新社会人になった時の悩みを書いて、早一年と半年が経ってしまった。自分はエンジニア2年目になり、当時あった地獄のような焦燥感は比較的減った。

https://note.com/saldra/n/ne84aca515658

> 元々何かできていたことや実績があるわけでもないが、そうか何事かを始めるためには動くときにきちんと気合を入れ計画なるものを作る必要があるのか、と感じた時にはもう学生の身分が消えていた。

この悩みに向き合ってから大体一年と半年後が経ったが、この吐露に共感する人が現れてしまった。同じように悩む人がいるという安心感と、この文章を見せてしまった罪悪感がそれぞれ半分づつある。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">&gt; 元々何かできていたことや実績があるわけでもないが、そうか何事かを始めるためには動くときにきちんと気合を入れ計画なるものを作る必要があるのか、と感じた時にはもう学生の身分が消えていた。<br><br>まもなくこれになります</p>&mdash; ぴよ (@hiyoko_coder) <a href="https://twitter.com/hiyoko_coder/status/1587265260083630081?ref_src=twsrc%5Etfw">November 1, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

結論から言うと「焦る気持ちはとてもわかるけど、自分が本当に大事に思っていたり続けていきたいと思うものは意外となんとかなるし、何事かを始めるのには慣れればそこまで気合は必要ではない」というものになる。

もちろんこれは新卒二年目から見ただけのものであるのでただの気休めにしかならないが、少なくとも自分は一年常に焦り続けたわけではなく、そして何も始められないことに絶望していたわけでもない。始めたいものは自由に始められたし、失敗もそれなりにできたと思う。

社会人一年目だけでもOAuthを勉強してWebアプリを作ったり、Goを勉強してDiscordBotを作ってみたり、Unityでハンドトラッキングを用いて魔法だって騒いでみたり、文字起こしサービスをテストで作ってみたりした。

https://zenn.dev/saldra/articles/db263d083f4dd6

https://publish.twitter.com/?query=https%3A%2F%2Ftwitter.com%2Fsald_ra%2Fstatus%2F1429382795298697219&widget=Tweet

二年目でも一からP2Pを勉強してビットコインについての解説記事を書いたり、知り合いに片っ端からWinnyとIPFSの相違点について語ったりした。

https://zenn.dev/saldra/articles/aa92994ee97217

ようするに何が言いたいかというと、時間を確保できれば社会人でも色々な失敗を体験できるので、安心して失敗してみてほしいという話で、少なくとも学生がもうすぐ終わるからといって、自分のように焦って絶望したりしてほしくない。

焦りという呪いを抱えているのであれば、それを自己肯定で解呪してもいいし、それを原動力に失敗のためのエンジンとして突っ走っても良いと思う。

ただし情報収集に関しては常に行っている方がエンジニアとして働くのであればやった方が良いと思う。Qiitaの週トレンド、Zennの週トレンド、できればTwitterでの初動情報の収集とはてブまで見れると理想、さらに自分の好きな言語に関しては話題になっているライブラリまで触れると言う事はないと思う。

そこまで時間がなかったら無理にやる必要はないが、QiitaとZennは定期的にトップページだけでも読むと良いと思うので是非やってみてほしい。
azure 予算設定について

●予算の設定
想定以上の課題なコストの発生を防ぐには、予算の設定は有効。

ユーザーに通知することもできるが、特性のアクションをトリガーして実行することもできる。コストはリソースの実行や使用によって発生するため、これ以上のコストが発生しない様に仮想マシンを停止したい場合などに役立つ。
このような特定なアクションを実行したい場合位は、仮想マシンの停止などの処理をオーケストラレーションするためのAutomation Runbookやロジックアプリ（LogiｃApps)を作成し、それらを含めたアクショングループを作成して予算設定で関連付けを行う。

●予算削減オプション

・予約
・Azureハイブリッド特典
・Visual Studioサブスクライバー向けのAzureクレジットの活用
【Docker】Error response from daemon: invalid mount config for type "volume": invalid mount path: 'myapp' mount path must be absoluteの対処法

<h2>症状</h2>
Docker compose upを実行したとき、下記のエラーが発生しました。
翻訳すると、「デーモンからのエラー応答: タイプ「ボリューム」のマウント構成が無効です: マウント パスが無効です: 'myapp' マウント パスは絶対パスである必要があります」
つまり、volumeのパスがよくないといわれているようです。


```terminal:error
 docker compose up           
[+] Running 3/4
 - Network neareats_default    Created                                                                                                                   0.8s 
 - Container neareats-front-1  Created                                                                                                                   0.1s
 - Container neareats-db-1     Created                                                                                                                   0.1s 
 - Container neareats-api-1    Creating                                                                                                                  0.1s 
Error response from daemon: invalid mount config for type "volume": invalid mount path: 'neareats' mount path must be absolute
```

docker-composeの該当の箇所のみを抜粋したものが以下です。

```docker:docker-compose.yml
 api:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    image: rails:dev
    volumes:
      - ./myapp
      - ./vendor/bundle:/myapp/vendor/bundle
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - 3001:3000
    depends_on:
      - db
```

<h2>解決策</h2>
volumeの箇所を以下のように変更することで動作しました。
volumeは「ホスト側の相対Path]:コンテナの絶対Path」で指定するので、どちらかしか指定していない状態だよっていう鰓０を返してきてくれていたようです。

```dockerfile:docekercompose.yml
 api:
    build:
      context: .
      dockerfile: Dockerfile
    command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    image: rails:dev
    volumes:
      - .:/myapp 　＃ここ変更しました
      - ./vendor/bundle:/myapp/vendor/bundle
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - 3001:3000
    depends_on:
      - db
```

<h2>参考</h2>

https://zenn.dev/ajapa/articles/fc1205d4bcbfe7
niz atom 66用キーマッピング！

# はじめに
みなさんはniz atom 66というキーボードを知っていますか？
66%コンパクトかつ静電容量無接点方式で見た目も打鍵感もHHKBに近いキーボードです。

https://www.akeeyo.co.jp/products/aky-niz-keyboard?variant=34817213137055


自分もここ一年くらいHHKBを使っていたのですが、

**どうしても矢印キーが欲しい！** 
**HHKBよりもスコスコ感が欲しい！** 

以上の２点から今回niz atom 66を購入しました。

### 使用感

本当にスコスコです。
これが本当のスコスコだと思うくらいスコスコした打鍵感でした。

矢印キーも付いてて、さいっこう！！・・・・あれ？
右シフトが効かない・・・

そうなんです。niz atom 66は右シフトが上矢印キーを兼ねる形となっていて、なぜか自分の環境では右シフトが動作しませんでした。
大文字を打とうとして右シフト＋dを押しても上矢印がずっと反応してしまう感じです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582866/456e4132-2ff2-4429-623f-a84386fa6186.png" width="200">


なので今回は自由にキーマップを変更できるKarabiner Elementというアプリを使ってこの問題を解消してみます。
（windows環境であればnizの専用ソフトでも変更可能です。）

# キーマップ変更
インストールしていない人はKarabiner Elementをインストールします。

https://karabiner-elements.pqrs.org/

Karabinerでもデフォルトでも多くのカスタマイズを用意してくれていますが、今回のケースは稀だと思うので独自ルールを作っていきます。
Karabinerの細かい設定は[こちら](https://knowledge.sakura.ad.jp/23355/)のサイトが丁寧に解説してくれています。

まず、Karabinerのルールの設定は~/.config/karabiner/assets/complex_modificationsに保存されるため、そちらにjsonファイルを作成します。そして、今回のケースを解消したい場合は結論、以下のように記述します。
```custom_niz.json
{
  "title": "niz atom 66カスタマイズ",
  "rules": [
    {
      "description": "右シフトキーを単体で押した時は上矢印、他のキーと一緒に押した時はシフトキーとして扱う",
      "manipulators": [
        {
          "type": "basic",
          "conditions": [
            {
              "type": "device_if",
              "identifiers": [
                {
                  "vendor_id": 1452,
                  "product_id": 272
                }
              ]
            }
          ],
          "from": {
            "key_code": "up_arrow",
            "modifiers": {
              "optional": ["any"]
            }
          },
          "parameters": {
            "basic.to_if_held_down_threshold_milliseconds": 100
          },
          "to": [
            {
              "key_code": "right_shift",
              "lazy": true
            }
          ],
          "to_if_alone": [
            {
              "key_code": "up_arrow"
            }
          ]
        }
      ]
    }
  ]
}

```

``title``と``description``は読んだ通りで、ポイントは``from``と``to``です。
``from``には変更元のkey_code、``to``には変更するkey_codeを記述します。
（ちなみにkey_codeはKarabinerをインストールした時に一緒にインストールされるKarabiner EventViewerで確認できます。）
今回ですと、上矢印キーが押された場合の処理を記述しています。
``to``で上矢印キーを右シフトキーへマップしています。さらに``lazy:true``とすることで何かしらのキーと組み合わせて押した際のみ右シフトキーと認識されるようにします。
加えて``to_if_alone``で単体で押された場合のみは上矢印キーになるように設定することで、上矢印キーとしても使えるようになります！

さらに、この設定はnizのキーボードをしている時のみ有効にさせたいので、``vendor_id``と``product_id``を指定しています。

# おわりに
キーマップしたことで使用感がずっと上がりました！（するまでは左シフトしか使えなかったからそりゃそうなんだけど）
あと自分はcapslockとControlを入れ替えたり、HHKBの時はControl+IJKMにそれぞれの矢印キーを割り当てたりしてます。
自分のは使いやすいですが、他人のキーボード使った時に誤タイピングが爆増するのは少し痛いですね笑
ダークファイバー とは

## 勉強前イメージ

光回線的な？

## 調査

### ダークファイバー とは

電気通信事業者などが敷設した光ファイバーのうちで、使われずに光の通信が通ってない光ファイバーのことを指します。
光回線が普及し始めた1990年代にNTTや光ファイバー網を敷設してた鉄道会社や電力会社が大規模な光ファイバー網を敷設しました。
また、光ファイバーは大規模でコストがかかるので予め多めに敷設してることが多いです。

2001年に使われずに余ってる光ファイバーを他の企業へ開放することが義務付けられ
NTTのダークファイバーを使って光回線の事業を展開してるのがNURO光などになります。

逆に使用されているのは通信が通っているのでライトファイバーと呼ばれています。

## 勉強後イメージ

使われてるのが光ってるからライトファイバー
使われてないのが光ってないのがダークファイバー
そのままね。

## 参考

- [ダークファイバーとは](https://mypage.otsuka-shokai.co.jp/contents/business-oyakudachi/words/dark-fiber.html)
- [ダークファイバー回線とは？NURO光やauひかりが速い理由を徹底解説](https://www.pocketwifi-hikaku.com/hikari/dark-fiber/)
【Python】4300桁以上が想定されるint型変数の桁数を求める


## やりたいこと

- Pythonでint型の桁数を求めたい

## 普通のやり方

一般的に`str`に直した後で`len()`関数に入れる方法が知られている。  
整数型をそのまま`len()`に入れることができればいいのだが、メソッドが存在しないため、変換する必要がある。  

### やってみる

簡単に実装できる

```py
num = 12345
length = len(str(num)))
print(length)
# 5
```

### 問題点

この方法だと、v3.10.7、v3.9.14、v3.8.14、v3.7.14より新しいバージョンで、4300桁以上の整数型がエラーになる。

```py:Python3.10.6
num = 9999**9999
length = len(str(num))
print(length)
# 39996
```

```py:Python3.11
num = 9999**9999
length = len(str(num))
print(length)
# Traceback (most recent call last):
#  File "/code/test.py", line 3, in <module>
#    length = len(str(num))
#                 ^^^^^^^^
# ValueError: Exceeds the limit (4300) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit
```

### 原因

`ValueError: Exceeds the limit (4300) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit`と書いてあります。

https://blog.python.org/2022/09/python-releases-3107-3914-3814-and-3714.html

上記の対応によって、桁数の多いint<->strの相互変換に制限が加えられました。 
具体的には4300桁を超える(>)変換がデフォルトではできなくなりました。  
サービス拒否攻撃の防止のため、桁数を測るためだけに制限を迂回するのも良くなさそうです。

## 新たな方法

定番の方法があるわけではなさそうですが、str変換を使わない方法で実装する必要があります。  

### 常用対数を使った実装

数学的に、桁数を求める場合は下記公式を用いて求めることが多いです。

```math
10^{n-1} \le N \lt 10^n \\ 
\iff n-1 \le \log_{10}{N} \lt n
```

これをPythonで実装すると

```py:Python3.11
import math 

num = 9999**9999
length = int(math.log10(num) + 1)
print(length)
# 39996
```

ただし、`num=0`の時は無限大に飛んでしまうので、実際の実装では0を弾く必要があります。  

```py:Python3.11
import math 

def int_len(n):
    if n = 0:
        return 1
    else:
        return int(math.log10(num) + 1)
```


## 終わりに

このブログは数学弱々大学院生が書いた弱々記事です。  
ここ違うぞ！とか、計算量おかしいことになるぞ！とかあったら編集リクエストやコメントお待ちしています。

## 参考文献

https://zenn.dev/ykesamaru/articles/2175b317a5410e

https://manabitimes.jp/math/1236
LWCでページ遷移時にクエリパラメータを渡す

## ページ遷移元
stateプロパティを設定することで、クエリパラメータを追加することができる。削除するときはundefinedを設定する。
stateプロパティは`名前空間プレフィックス__`で始める必要がある。管理パッケージでない場合は`c__`となる。
stateで使用できるのは文字列のみ。

```javascript
import { LightningElement } from "lwc";
import { NavigationMixin } from 'lightning/navigation';

export default class SampleA extends NavigationMixin(LightningElement) {
    navigateToRecordViewPage() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                objectApiName: 'SObjectName__c',
                recordId: this.selectedId
            },
            state: {
                c__viewType: 'simple' // クエリパラメータを設定
            }
        });
    }
}

```

## ページ遷移先
`CurrentPageReference`を利用して、`currentpagereference.state.c__xxx`からクエリパラメータを取得する。

```javascript
import { LightningElement, wire } from "lwc";
import { CurrentPageReference } from "lightning/navigation";

export default class SampleB extends LightningElement {
    currentPageReference;

    @wire(CurrentPageReference)
    setCurrentPageReference(currentPageReference) {
        this.currentPageReference = currentPageReference;
    }

    get viewType() {
        return this.currentPageReference ? this.currentPageReference.state.c__viewType : undefined;
    }
}
```



## 参考
- [さまざまなページ種別への移動 - Lightning Web Components 開発者ガイド](https://developer.salesforce.com/docs/platform/ja-jp/lwc/guide/use-navigate-page-types.html)
- [クエリパラメータの追加 - Lightning Web Components 開発者ガイド](https://developer.salesforce.com/docs/platform/ja-jp/lwc/guide/use-navigate-add-params-url.html)
[Django]たまに見かけるQオブジェクト

# Qオブジェクトってなに？
最近、業務中にこんな感じのコードに出会いました。
```python:例文
Contract.objects.filter(Q(price__gt=100)|Q(date__year = 2022))
```
なんとなく`or`を使って絞り込みたいの時に使われることは知っていたのですが、もう少し深ぼって調べてみました。

## 1.ドキュメントによると

>Q object (django.db.models.Q) is an object used to encapsulate a collection of keyword arguments. These keyword arguments are specified as in "Field lookups" above.

訳すると、
Qオブジェクトはキーワード引数の集まりをカプセル化するときに使われるオブジェクト。これらのキーワード引数は、上の `Field lookups` のように指定される。
ということらしいです。よくわからないですね。^^

基本的にfilter(条件,条件)の場合はANDで絞り込まれるますが、ANDではなくORを使って絞り込みたい時にQオブジェクトが役に立つという認識で大丈夫です。

`Field lookups`というのは、
```django:Field lookups
example1 = Model.objects.get(question__startswith='Who')
example2 = Model.objects.filter(num__gt = 20)
```
上の__アンダースコア✖️2の後に続く部分のことです。ここでいうとstartswith,gtのことですね。


要は、Field lookupを使うときにQオブジェクトを組み合わせることで、より柔軟に絞り込みができるということです。Field lookupによる絞り込みとAND(`,`による区切り),ORがあればある程度のことはできますね。

しかし`AND,OR`だけだと、ただの和積なのでそんなに柔軟にはなりません。そこでもう一つ、`NOT(否定)`もちゃんと使えるようになっています。

## 2.NOT のやり方
NOTを使いたい時は、`~`を使います。
次のように、Qの前に`~`をつければ出来上がりです。

```django:否定条件
#Whoから始まる文字列、または、2005年でないという条件にしたいときに
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
```

## 3.注意点
>Lookup functions can mix the use of Q objects and keyword arguments. All arguments provided to a lookup function (be they keyword arguments or Q objects) are "AND"ed together. However, if a Q object is provided, it must precede the definition of any keyword arguments

lookup関数を使うときは、Qオブジェクトを先に書かないと望んだクエリと違うクエリが出されちゃうよということです。もし、Qオブジェクトを後に使った場合は、`OR`ではなく`AND`で組み合わさることになるので気をつけてください。

```django:OK
#Qが先に来ているので、OK
Poll.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who',
)
```

```django:NG
#Qが後に来ているので、NG
Poll.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
```

# どんなSQLが出されているか
エンジニアとしては、どんなSQLが出されているか知っておくに越したことはないので一応いくつか例を出しておきますね。

```Django:example1
Django>
Q(question__startswith='Who') | Q(question__startswith='What')

SQL>
WHERE question LIKE 'Who%' OR question LIKE 'What%'
```

```Django:example2
Django>
Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

SQL>
SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
```



## 参考記事
https://docs.djangoproject.com/ja/3.2/topics/db/queries/#complex-lookups-with-q-objects
Lucene が 結果を取得する様子を探ってみる

自分用の備忘録なので結構はしょります。後で記事にします。

## Lucene の IndexSearcher.search の createWeight は文書結果を取得しない。

createWeight は BM25 ？ などで使う 統計情報を取得するだけで、マッチした文書の一覧取得までは行っていない。

SimpleTextCodec ですが [ここら辺のコード](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java#L722-L727) を見れば、`lastDocsStart` しかインデックスしていないことが分かる。

```java
            fstCompiler.add(
                Util.toIntsRef(lastTerm.get(), scratchIntsRef),
                outputs.newPair(
                    outputsOuter.newPair(lastDocsStart, skipPointer),
                    outputsInner.newPair((long) docFreq, totalTermFreq)));
          }
```

では、どこで 文書の取得を行っているのか？

## Lucene の IndexSearcher.search は Score する部分で文書の取得を行っている。

SimpleTextCodec で言うと、[SimpleTextPostingEnum](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java#L441) の [readDoc](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java#L507-L550) が文書とFrequencyの取得を行っている。

```java
    private int readDoc() throws IOException {
```

この readDoc を while で実装した [advance](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java#L566) が呼ばれるのが、[Weight.java](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/core/src/java/org/apache/lucene/search/Weight.java) の DefaultBulkScorer の score の scoreAll の中の for 文になる。

```java
        for (int doc = iterator.nextDoc();
            doc != DocIdSetIterator.NO_MORE_DOCS;
            doc = iterator.nextDoc()) {
          if (acceptDocs == null || acceptDocs.get(doc)) {
            collector.collect(doc);
          }
        }
```

`collector.collect(doc);` の中身は [ここ](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java#L72-L101) にあって、簡単に言えば 

```java
          pqTop.doc = doc + docBase;
          pqTop.score = score;
          pqTop = pq.updateTop();
```

pq という PriorityQueue というデータ構造に入ります。
PriorityQueue は、[ここの初期化部分](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/core/src/java/org/apache/lucene/util/PriorityQueue.java#L76) を見れば分かりますが、ラムダ式を引数に取って、それを適用します。
なので、pq を初期化したときの [HitQueue](https://github.com/apache/lucene/blob/44b4602776a63d93896d887e5000c9e3ca7c3119/lucene/core/src/java/org/apache/lucene/search/HitQueue.java#L62) の ラムダ式を使い ScoreDoc を返してくれます。

最後に、`CollectManager` の `topDocs` を取得する部分までで、結果が取得されているのが分かると思います。

---

readDoc が見つかってから、DefaultBulkScorer を見つけるまで時間がかかったので備忘録として記事にした。
また時間があったら、まとめます。
fontプロパティ指定方法

フォントプロパティはフォントに関する一括指定をすることが出来きます。コードの見た目がスッキリするので、積極的に活用したい。
例
~~~css
h1 {
  font: normal normal bold 24px/36px "メイリオ", sans-serif;
}
~~~

指定順は次の通り。
~~~css
h1 {
  font: style variant  weight size/line-height family;
}
~~~
`font-size`、`font-family`の値は必須です。それ以外は省略でき、指定しない場合値は各プロパティの初期値が適用されます。
~~~css
h1 {
   font: 20px Meiryo;/*最低限の記述量*/
}
~~~
僕がコーディング中によく使用するプロパティは、`font-weight`、`font-size`、`line-height`です。なので`font-family`の記述が必須なのは使いづらいなと思いました。実務で使うタイミングは最初に`body`タグや`h1`、`h2`に当てる時くらいかな。

### 参考

[HTML5 & CSS3 リファレンス](http://www.osaka-kyoiku.ac.jp/~joho/html5_ref/css/font_css.php)
[fontプロパティの意味と使い方](https://dekiru.net/article/13114/)