OmniAICreator/Qiita-1.07M huggingface dataset:
BigQuery Client for Javaでqueryメソッドを使用したTableResultをJSONにする方法

# 困りごと
BigQueryでSQLを使用してテーブルからデータを取得する際、BigQuery APIを使用するとJSONで結果を取得することができる。

しかし、JavaのクライアントライブラリでSQLの結果を取得した場合、FieldValueのAttributeにRECORDとREPEATEDが混じっていると構造が複雑になり、すんなりとJSONには変換できない。


# 動作確認環境
* Kotlin: 1.6.10
* [Google Cloud BigQuery Client for Java][bq]: 1.100.0


# 解決方法
BigQueryのSQLでTO_JSON_STRING関数を使用すれば結果がJSON文字列で取得できることを利用する。

```sql
SELECT
    TO_JSON_STRING(result) AS json
FROM (
    SELECT
        *
    FROM
        `$projectId.$datasetName.$tableName`
) AS result
;
```

```kotlin
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.google.cloud.bigquery.BigQueryOptions
import com.google.cloud.bigquery.QueryJobConfiguration


fun query(): String {
    val projectId = "MY_PROJECT_ID"
    val datasetName = "MY_DATASET_NAME"
    val tableName = "MY_TABLE_NAME"
    val query = "SELECT TO_JSON_STRING(result) AS json FROM (SELECT * FROM `$projectId.$datasetName.$tableName`) AS result"

    val bigQuery = BigQueryOptions.getDefaultInstance().service
    val queryConfig = QueryJobConfiguration.of(query)
    val results = bigQuery.query(queryConfig)

    val mapper = jacksonObjectMapper()

    // 一度オブジェクトに変換する
    val resultList = results.iterateAll().map { row ->
        val jsonString = row.get("json").stringValue

        mapper.readValue<Any>(
            jsonString,
            object: TypeReference<Any>() {}
        )
    }

    // JSON文字列として出力する
    return mapper.writeValueAsString(resultList)
}

```

[bq]:https://github.com/googleapis/java-bigquery
【python-dotenv】インストールエラー（pip install）

## 環境
+ Python 3.9
+ GNU bash 5.0.17(1)-release (x86_64-pc-linux-gnu)
+ PythonAnywhere

## 現象
```bash:bash
pip install python-dotenv  # 通常
pip install --user python-dotenv  # ユーザ権限（Pythonanywhereの場合も）
```

## 原因
ライブラリのインストールは、ビルド済みのファイルが準備されているおかげで通常はスムーズにインストールできる。
しかし、Pythonのバージョンがアップグレードしたばかりの時点では、まだビルド済みのファイルが準備されていない場合がある。そのときは、`pip install` ではソースをダウンロードしてビルドするが、パソコンにビルドできる環境がないとエラーにる。（[pip installでエラーになりインストールできない場合（Windows）](https://gammasoft.jp/support/pip-install-error/)より）

## 解決策
1つ前のバージョンのPythonを使用するのが一番簡単である。例えば、`Python3.9` がリリースされてNumPyのインストールに失敗する場合は、既に`Python3.8` がインストール済みであれば、`python3.8 -m pip install NumPy` により `Python3.8` にインストールする。（[pip installでエラーになりインストールできない場合（Windows）](https://gammasoft.jp/support/pip-install-error/)より）

```bash:bash
python3.8 -m pip install python-dotenv  # 通常
python3.8 -m pip --user install python-dotenv  # ユーザ権限（Pythonanywhereの場合も）
```

## 参考
https://stackoverflow.com/questions/59572174/no-module-named-dotenv-python-3-8

https://gammasoft.jp/support/pip-install-error/
テストドキュメント種類

# テストドキュメントの種類について
システム開発において欠かすことのできないテスト。テストする対象範囲やチェック観点に応じて、単体テスト・結合テスト・相互テストなどいくつかの工程（フェーズ）に分けて実施していきます。
テストはどの工程のおいても、原則として「計画とコントロール」「分析と設計」「実装と実行」「終了」というプロセスで進めていきます。

## テストプロセス
1. 計画とコントロール
1. 分析と設計
1. 実務と実行
1. 終了
各テスト工程において作成されるドキュメントを総称して「テストドキュメント」と言います。

## テストドキュメントを整備する必要性
テストドキュメントは、テスト工程ではなくテストプロセスごとに作成していく必要があります。
- テスト肯定感で品質の差異をなくすため
テストは、複数名のエンジニアによって実施されます。テストドキュメントがあれば、対応用印鑑の認識や前後のテスト肯定感における食い違いの発生を防ぐことができます。
- テスト対象の品質状況を見える化するため
テストの計画段階において定義されたテスト方針と、実際に実施されているテストの進め方が合致しているか、テストの進捗は予定通りか、あらかじめ定められた内容を確認しながら状況を明確に把握できます　。

## テストドキュメントの種類と内容
- テスト全体計画書
テスト工程の全体を見通した計画を取りまとめ、テスト全体像を表すドキュメントです。
- テスト計画書
テストの計画段階で検討される、テストの「スコープ（範囲）」「リスク要素」「目的」「アプローチ・戦略」「手段」「実施レベル（粒度・深度）」「評価方法」「開始と終了の基準」などの項目をまとめたドキュメントになります。
- テスト設計仕様書
テストの目的や対象機能、実施方法や実施環境などを具体的に示したドキュメントです。
- テストケース
テストを実施するのに必要となる情報を記述したドキュメントです。
- テストログ
テストケースに基づいて実施したテストの結果を記録するドキュメントです。作成された不具合報告書をもとに開発者が事象を調査し、プログラムを修正します。
- 不具合報告書
テスト結果が×（NG）だった場合、検出した事象を不具合報告書にまとめます。作成された不具合報告書をもとに開発者が事象を調査し、プログラムを修正します。
- 進捗管理表
テストの進捗状況や品質状況を管理するためのドキュメントです。
-　テストサマリレポート
テストログや不具合報告書の内容を分析し、その内容をプロジェクトのステー区ホルダに報告するために作成するドキュメントです。
## まとめ
システム開発には多人数のプロジェクトメンバーが関わっています。プロジェクトメンバー間で認識の食い違いが生まれてしまうと、開発の進捗に遅延の影響が出たり、品質が低下したりする遠因となりかねません。
開発するプロダクトの品質を多層で確認するために実施するテスト作業だからこそ、認識の齟齬を生じさせないためにも、テストドキュメントを作成してプロジェクトメンバーが同じ認識のもとで作業を進めていけるようにすることが重要です。

テストドキュメントは最終的に、納品物として取りまとめ、クライアントに提出することもあります。ですから、納品義務の有無に関わらず、ドキュメントを日頃から整理しておきましょう。そうすれば、納品準備の段階になってあたふたとドキュメント整理に追われる、ということもなくなります。
【Laravel livewire】DOM更新時にjsを実行させる

# はじめに
livewireでDOMの更新がされた時、blade内に書いたjavascriptは実行されないので
動的に生成した要素は消えてしまいます。
jsライブラリとかをlivewireに組み込もうとすると必ず起きる問題なのでメモがてら対処法

<a id="#対処法"></a>
# 対処法
イベントをblade内に記述して
``render``内でブラウザイベントを発火させる。

```diff_php:app/Http/Livewire/Sample0303.php
<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Sample0303 extends Component
{
    public $sample;

    public function render()
    {
++     $this->dispatchBrowserEvent('inputTest');

        return view('livewire.sample0303')
            ->extends('adminlte::page')
            ->section('content');
    }
}

```

```html:resources/views/livewire/sample0303.blade.php
<div class="pt-2">
    <div class="card">
        <div class="card-body">
            <input type="text" wire:model="sample"/>
            <h1 id="test"></h1>
            <script>
                //livewireロード完了時に実行される（要するにページアクセス時のみ）
                document.addEventListener('livewire:load', function () {
                    inputText();
                })
                //イベント発火時に実行
                window.addEventListener('inputTest', function () {
                    inputText();
                });

                function inputText() {
                    const container = document.getElementById('test');
                    container.innerHTML = '追加テキスト';
                }
            </script>
        </div>
    </div>
</div>
```

``render``内にイベント発火処理を書いているから読み込み時の処理は書かなくて良いじゃないかと疑念を抱くと思いますが、
動きません。

viewが描画されないとそもそもDOM操作出来ないと思うので仕方ないかなぁと。
1回読み込んだ後は更新時に差分を見てDOMを差し替えてるっぽいので動くのかなと(推測)
``render``後に実行されればベストなんですが今の所良いやり方が見つかっていないので、もしあれば教えて頂きたいです。

<a id="#reference"></a>
# 参考文献
- [Livewire 2.x ライフサイクルのフック](https://readouble.com/livewire/2.x/ja/lifecycle-hooks.html)
【Bubble】GCPにおけるSQL Database Connectorの書き方

## SQL Database Connectorの書き方
BubbleのSQL Database Connectorを活用して、Google Cloud SQLへアクセスしようと考えていましたが、ドキュメントのフォーマットがAWSのみでGCPとは、異なるため、どのようにアクセスするのか調べてみました。

AWS RDBであるSQL Database Connectorへの接続は、以下の通りです。

```
mysql://username:password@my-db-instance.endpoint.us-east-1.rds.amazonaws.com:PORT/db_name
```

【参照】[公式ドキュメント](https://manual.bubble.io/core-resources/bubble-made-plugins/sql-database-connector)

GCPにて、接続するには、以下の書き方となります。

```
# MySQL
mysql://<username>:<password>@<host>:3306/<dbname>
```

```
# Postgres
postgres://<username>:<password>@<host>:5432/<dbname>
```

書き換えをまとめると以下の通りになります。

```
<username>：データベースのユーザ名
<password>：データベースのパスワード
<host>：GCPのCloud SQLにあるPublic IPアドレス
<dbname>：データベース名
```

書き方としては、[heroku](https://devcenter.heroku.com/ja/articles/heroku-postgresql)と似ていますね。

## 注意点
GCPだと、AWSとは異なり、IPアドレスを直で書くことになるので、セキュリティ上でIPアドレスが外部に漏れないように注意が必要です。
以上の注意点を踏まえて、活用しましょう！
本日の基礎練習問題(22/3/16)

**問題**
以下の条件を達成するプログラムを実装しなさい
銀行口座に10万円の預金残高があり、お金を引き出すプログラムを作成します。
・お金を引き出すwithdrawメソッドを作成する
・お金を引き出すと手数料110円かかり、「◯◯円引き落としました。残高は◯◯円です」と表示する（残高は手数料を引いた額を表示します）
・引き落とし金額と手数料の合算が、預金残高より大きい場合は「残高不足です」と表示する
・以下にヒントを用意するので参考にしてください
```
def withdraw(balance, amount)
  fee = 110　　# 手数料
# 引き落とし額と残高を表示する、もしくは残高より多く引き落としたら残高不足と表示
end

balance = 100000　　# 残高
puts "いくら引き落としますか？（手数料110円かかります）"
amount = gets.to_i
withdraw(balance, amount)
```

# 私の回答
```
def withdraw(balance, amount)
  fee = 110
  after_balance = balance - amount - fee
  if after_balance < 0
   puts "残高不足"
  else
   puts "#{amount}円引き落としました。残高は#{after_balance}円です"
  end
# 引き落とし額と残高を表示する、もしくは残高より多く引き落としたら残高不足と表示
end

balance = 100000
puts "いくら引き落としますか？（手数料110円かかります）"
amount = gets.to_i
withdraw(balance, amount)
```

# 解説
まず3行目で残高-引き落とし額-手数料を計算し残高後の数値をafter_balanceに代入する。
次にif文でafter_balanceが0未満の場合は残高不足と出力。
それ以外は残高を表示する記述をする。

# 模範回答
```
def withdraw(balance, amount)
  fee = 110
  if balance >= (amount + fee)
    balance -= (amount + fee)
    puts "#{amount}円引き落としました。残高は#{balance}円です"
  else
    puts "残高不足です"
  end
end

balance = 100000
puts "いくら引き落としますか？（手数料110円かかります）"
amount = gets.to_i
withdraw(balance, amount)
```

# 模範解説
13行目で入力した金額（amount）と手数料110（fee）の合計が100,000以上か否かを判断し処理しています。金額と手数料の合計が100,000以下の場合は、balance -= (amount + fee)、つまりbalance = balance - (amount + fee)が処理され、最終的な返り値が出力されます。金額と手数料の合計が100,000以上の場合は残高不足である旨のメッセージを表示しています。

# 感じたこと
考え方自体は合っていたが記述方法が間違いだった。正常に処理されていればOKだが他人がコードを見た際に
わかりやすいコードを書くことが必要だと思うので今後は可読性を意識して取り組みたい。
また最近嬉しいことに私の投稿にご指摘していただけることが多くなってきました。
とても勉強になるので今後ともアドバイスやご指摘いただけると幸いです。
Go1.18がでたのでコレクション操作とかいくつか触った記録



## [github.com/samber/lo](https://github.com/samber/lo)　をつかったコレクション操作

```go
package _go

import (
	"github.com/samber/lo"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestLodash(t *testing.T) {

	type ArtistID int

	type Artist struct {
		ID   ArtistID
		Name string
		Age  int
	}

	type ArtistMap = map[ArtistID]Artist

	artists := []Artist{
		{
			ID:   1,
			Name: "A",
			Age:  25,
		},
		{
			ID:   2,
			Name: "B",
			Age:  45,
		},
		{
			ID:   3,
			Name: "C",
			Age:  30,
		},
	}

	var filter1 []Artist = lo.Filter(artists, func(a Artist, i int) bool {
		return a.Age > 29
	})

	assert.Equal(t, 2, len(filter1))

	var artistMap ArtistMap = lo.KeyBy[ArtistID, Artist](artists, func(a Artist) ArtistID {
		return a.ID
	})

	assert.Equal(t, `C`, artistMap[3].Name)

}

```

* メソッドchainができない?(戻り値がRaw Slice)
* funcで受ける時のIDE支援がいまのところきかない (LSPあればOKということにならない?)

## [github.com/neurocollective/go_chainable](https://github.com/neurocollective/go_chainable) をつかったコレクション操作

```go
package _go

import (
	"github.com/neurocollective/go_chainable/lists"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestChainable(t *testing.T) {

	type ArtistID int

	type Artist struct {
		ID   ArtistID
		Name string
		Age  int
	}


	artists := []Artist{
		{
			ID:   1,
			Name: "A",
			Age:  25,
		},
		{
			ID:   2,
			Name: "B",
			Age:  45,
		},
		{
			ID:   3,
			Name: "C",
			Age:  30,
		},
	}

	list := lists.New[Artist, any](artists)

	filter1 := list.
		Filter(func(a Artist, i int) bool {
			return a.Age >= 25
		}).
		Filter(func(a Artist, i int) bool {
			return a.ID == 2
		})

	_, size := filter1.Size()
	assert.Equal(t, 1, size)

	_, first := filter1.First()
	assert.Equal(t, `B`, first.Age)

}


```
* GroupBy的なものでmapに変換できない? (見落としてるかも)



## ジェネリクス/自前で思い付くユースケース

簡単な可変型のin/outを持つタスクルーターを書く時、``` interface{} ```がたくさん出てくるのを防げないか


```go
package _go


type UserHandler interface {
	Handle(in UserInput) (out UserOutput, err error)
}

type UserInput struct {
	UserID int `json:"user_id"`
}

type UserOutput struct {
	UserID int `json:"user_id"`
}

type implUserHandler struct {
}

func (self implUserHandler) Handle(in UserInput) (out *UserOutput, err error) {

	fmt.Println("call")

	return &UserOutput{
		UserID: in.UserID,
	}, nil
}


```

```go 
package _go

import (
	"encoding/json"
	fmt "fmt"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestHandler(t *testing.T) {

	userHandler := implUserHandler{}

	taskRouter := map[string]HandlerFunc{
		`/user/handle`: func(rawInput []byte) (any, error) {
			return userHandler.Handle(toHandlerInput(rawInput, UserInput{}))
		},
	}

	resp, _ := taskRouter[`/user/handle`]([]byte(`{ "user_id" : 1 }`))
	respAsjson, _ := json.Marshal(resp)
	assert.JSONEq(t, `{"user_id":1}`, string(respAsjson))
}

type HandlerFunc = func(in []byte) (interface{}, error)

func toHandlerInput[T any](raw []byte, in T) T {
	_ = json.Unmarshal(raw, &in)
	return in
}


```

jsonをUnmarshalして返す ``` toHandlerInput ``` だけ使ったけど、筋としてはほとんどジェネリクス関係ないというか、どっちかというとリフレクションの領域のような気もしてきた
エンジニアに価値あるサービス作りを学ばせる講義の思い出話 第1回


## はじめに

この記事は学生時代3年間お手伝いした講義でアシスタントをしていた時に学んだことをまとめたものになります

この講義の目的は学生エンジニアが「ものづくり」からサービス・プロダクト作りに意識を変えていくことを目標として行われました
大学生向けに1年間を通じてプログラミングの学習から始まり最終的に投資家への発表までを行うプログラムでした
新卒向けの研修や夏のインターンなどの参考になれば幸いです

この記事はシリーズになります
今回はこの講義で伝えたかった価値観の基本的なことを解説します
方法などは次回以降になります

### 「ものづくり」エンジニアとは?
エンジニアは往々にして「ものづくり」をしがちです
ここで表現する「ものづくり」とは、自分たちの頭の中にある実現したいことを作り上げることを示しています
「ものづくり」の問題点としてはいくら技術的に優れたものを作ってもその結果として人々に受け入れられる価値がなければ無用の長物となり誰も使ってはくれないことにあります
使ってもらえないと対価を得ることはできません
つまり生きていくことができません

具体例でいえばセグウェイがわかりやすいかもしれません
セグウェイはジャイロセンサーを使って姿勢を検知して姿勢制御を行うと技術的には素晴らしい物だったように思います
しかし結果として価格や速度などが要因となり欲しがる顧客はいなかったことがビジネス的な失敗の要因となったのだと思っています
つまり技術的には優れていても対価をは払って使ってくれる人がいないことは起こり得るということを示しています

またどういった価値を実現するのかを考えることをエンジニアの役割ではないとする考え方があることも理解しています
ただ自分の考えではありますがめちゃくちゃ極端なことを言えばプログラムを組んで期待した処理をさせるだけであれば人件費コストの安さで勝負することになるのではないでしょうか
グローバル化が進んでいく中で日本で生きていくことは決して安くはありません
圧倒的で代替え不可能な技術力を身につける生存戦略もありますが、代替え不可能な技術力がありその先まで考えられるエンジニアのほうが強いと自分は考えています

なので自分は「ものづくり」をしないエンジニアとなることは1つの生存戦略になりうると思っています

### 「ものづくり」をするのはエンジニアの生態だ

エンジニアはプログラミングを通じてどうやって期待する処理を実現するかを考えることが多くあります
そのため手段に対しての思考が向きがちでそこで実現したい価値や利用者に対して使ってもらうことに意識を向けることは訓練が必要となります
この訓練が不十分であると「ものづくり」が始まってしまいます
私はエンジニアのという生き物の生態だと思っています
教育を行わなければほとんどのエンジニアは失敗し学びを得るまでは意識を向けることが必要であることすら共感をえられません

常に自分の開発しているものが価値ある物かを問うようになるには相当訓練する必要があります

ここで必要となるスキルが**価値と手段は分けて考える**ことになります
分けて考えられるようになって初めてその手段が提供したい価値に対してもっとも有効なのかを評価することができます
エンジニアは〇〇できるということが価値だと考える傾向が強い生き物です
価値とは簡単に言えば〇〇した結果として得られることを指しています

ここでは詳しく説明しませんが有名な話で言えば顧客はドリルが欲しいのではなく穴がほしいという話でわかると思います
顧客が欲しいのはドリルではなく穴である、つまり指で穴があく壁が解決手段として最適な場合もあるということですね

価値と手段の区別ができないエンジニアには多い印象ですので丁寧に粘り強く取り組む必要があります

### 対価を得ることは必要だけど難しい

価値について考える上で重要となるのが対価をもらえるほどの価値なのかという点です
みんな使いたいと思うけどお金を払うほどじゃない物って多くあると思うんです
皆さんも無料で提供されているサービスはいくつもあると思いますが、10円の支払いが必要になったら使わなくなる物はあるんじゃないでしょうか

また無料で提供されているサービスが対価を得ていないかと言えばそうではありません
顧客から直接支払いをしてもらう以外の対価の得える方法をしり考える必要があります
なので対価を得る仕組みを考えられるようになって初めて価値を評価できるようになります
対価を得られる仕組みを作ることができるスキルを身につける必要があります

また学生に向けての講義だったので対価を得ることの重要性を伝える必要もありました
一定数お金儲けをすることに拒否感を示す人がいるので価値を提供し続けるためには対価を得ることの必要性を丁寧に伝える必要があります

### 開発リソースは無限じゃないよ

開発あるあるだと思うので釈迦に説法だとは思いますが、学生に考えさせると機能をゴテゴテに実装する前提のプロダクトができます
リソースは無限ではないので本質的な機能のみに削り落とす必要に迫られるのはよくあることです
価値と手段を適切に評価できるようになれば本質的な機能が見えてきます

## 次へ 

https://qiita.com/kiitan/items/e47420128c0e0f1b93fb
VSCodeでPython仮想環境のデフォルトインタプリタを設定する

# 前提
VSCode：1.65.2
Pyrhon Extention：v2022.2

# 方法
setting.jsonにpython.defaultInterpreterPathを設定する。

~~~setting.json
{
    python.defaultInterpreterPath : "C:\\仮想環境までのPath\\Scripts\\python.exe"
}
~~~
vue.js で 現在地を取得する

コンポーネント化しました。
私、気が利くので。

参考
https://note.com/tana_d/n/nce5ce09e55bd

GeoComponent.vue を読み込み、ボタンをクリックすれば
Oya.vue で 現在地の lng lat が使えるという素晴らしい仕組み。

```GeoComponent.vue
<template>
    <div>
        <button @click="getLocation">
            現在地付近
        </button>
    </div>
</template>
<script>
    export default {

        methods: {

            getLocation () {

                if (!navigator.geolocation) {
                    alert('現在地情報を取得できませんでした。お使いのブラウザでは現在地情報を利用できない可能性があります。エリアを入力してください。')
                    return
                }

                const options = {
                    enableHighAccuracy: false,
                    timeout: 5000,
                    maximumAge: 0
                }

                navigator.geolocation.getCurrentPosition(this.success, this.error, options)
            },

            success (position) {
                //親に引数として lng , lat を渡す
                this.$emit('child-emit',position.coords.longitude,position.coords.latitude);
            },

            error (error) {
                switch (error.code) {
                    case 1: //PERMISSION_DENIED
                        alert('位置情報の利用が許可されていません')
                        break
                    case 2: //POSITION_UNAVAILABLE
                        alert('現在位置が取得できませんでした')
                        break
                    case 3: //TIMEOUT
                        alert('タイムアウトになりました')
                        break
                    default:
                        alert('現在位置が取得できませんでした')
                        break
                }
            },

        },
    }
</script>

```

```Oya.vue

<template>
    <div>
        <GeoComponent @child-emit="this.getGeo"></GeoComponent>
    </div>
</template>

<script>
    import GeoComponent from './GeoComponent'
    
    export default {

        components: {
            'GeoComponent': GeoComponent,
        },

        methods: {
            getGeo(lng,lat){
                console.log("lng " + lng);
                console.log("lat " + lat);
                console.log("ロケーションを取得しました");
            },
        },
    }
</script>



```
【SAP】複数の会社データを一つのクエリでまとめてみる

以前の[記事](https://qiita.com/Miki_Yokohata/items/b0a676948d87c73084a0)でユニオンクエリを使用して、複数の会社データを出力してみましたが、本来、SAPデータモデルは、複数の会社データを簡単に統合する機能を持っています。
**クエリビルダー**の[会社名]フィルターで複数の会社名を指定することができます。
![2022-03-16 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5a0ebb26-45d1-f4e3-cc08-9c4b7696df71.png)
シンプルなクエリであればこのような感じで出力される。
![2022-03-16 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6efe4540-ed84-b1ec-5e33-2194a8bd5a50.png)
次の例では、３社の会計期別の金額を比較できるようなクエリを作成します。
![2022-03-16 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d2aa06d4-d445-82c7-5b8f-0d11150a88c1.png)
結果はこのようになります。
:bulb:**動的出力** に関してはまた別の記事で！
![2022-03-16 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4a4068c4-fe38-9a07-de3d-5cd67952c7eb.png)
:postbox:[Sharperlight](https://sharperlight.jp/)
warning ../../package.json: No license field の解決法

# はじめに
Railsチュートリアルを学習中、
rails s を実行すると
```
warning ../../package.json: No license field
```
このエラーがずっと表示されていました。（ローカルでのサーバーは起動する）

気になったので、解決法を調べました！



# バージョン
Ruby 2.6.3
Rails 6.0.4



# 結論
まず結論から書きます！
```
rm -rf yarn.lock
```

を実行するとエラーが解消されました！

今回はyarn installが適切に行われていないために表れたエラーでした。
yarn.lockのコンフリクトを解消することでエラーが解消されました。



# 解決までに試したこと
warning ../package.json: No license fieldでは
ライセンスが設定されていないということなので、
ググってみると、主に下記の解決法がヒット！

- package.jsonに適切なlicenseをセットする。
- package.jsonに"license": "UNLICENSED"をセットする。

試してみたがエラーの表示は消えず、、
さらにググってみると、適切な内容がyarn installされていない場合でも表れるらしい、、

yarnインストールを複数回行い、依存関係にあるyarnインストールした内容をrm -rf yarn.lockで
削除しました。

> ※こちらの方の記事を参考にさせていただきました。
https://qiita.com/narimiya/items/fe0e308a2177c9f0e275



# まとめ
今回疑問に思ったことを調べてみて、様々なエラーに対処できるようになるためにも、yarnに関しても知見を広げていきたいなと感じました。
Dockerコンテナーのログをリセットする

## 前提
- Docker for Macを使用している

## 手順
1.　ログをリセットしたいコンテナーのログファイルのパスを調べる
```shell
docker inspect <container ID or name> | grep LogPath
```
2.　DockerのVMにアクセスする
```shell
nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
```
3.　ログの中身を削除する
```shell
echo "" > [1で確認したLogPath]
```

## alias
.zshrcなどでaliasを設定しておくと便利
```shell
alias connect_to_docker="nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock"
```
ansibleのshellモジュールで冪等性を保つ

- shellモジュール、commandモジュールはとても便利といか力技でなんでもできるけれど、冪等性のチェックが行われずに、とくに気をつかわなければ常時実行されChangeとなってしまう
- たとえば参照系のものであれば別段問題はないけれど、書き込み系のコマンドを重ねがけするのはあまりよろしくない
- そういう場合は自前でチェックするセクションを作る

## `register`と`when`を組み合わせると良い
### コマンドチェックするほうのセクション（Check install npm）
- `register`をつけることで、指定した値にそのセクションの実行結果をしまうことができる
- 以下のようなサブオプションが格納される
    - rc
        - リターンコード
    - stderr
        - 標準エラー
    - stdout
        - 標準出力
    - stdout_lines
        - 改行ありの標準出力
- `changed_when: false`により、このセクションが実行されてもOK扱いになる
- `failed_when: false`により、このセクションでどのような実行結果となってもエラーとはならない

### コマンドインストールする方のセクション（Install npm）
- `when`で実行するか否かを指定できる
 - 今回は、npm_pathに格納された標準出力結果が、`/usr/bin/npm`でなければ実行する
 - 一度目の実行では、whichの見つからなかったメッセージが入るので実行される

## npmをインストールする例

```yaml
- name: Check install npm
  shell: |
    /usr/bin/which npm
  register: npm_path
  changed_when: false
  failed_when: false

- name: Install npm
  shell: |
    curl -sL https://rpm.nodesource.com/setup_14.x | bash -
  args:
    chdir: /tmp
  when: npm_path.stdout != "/usr/bin/npm"

```
Azure Kubernetes Service上のcert-managerをバージョンアップする

cert-managerは様々な発行元のTLS証明書の管理/更新を自動化するツールです。
AKS上でLets Encryptを自動的に作成、管理する手順は、 [公式ページ](https://docs.microsoft.com/ja-jp/azure/aks/ingress-static-ip?tabs=azure-cli) に記載されています。
1年以上前に導入したcert-managerが古くなってバージョンアップをしたので手順を書き残します。

# 環境
* cert-manager
    * 0.8.0
* AKS
    * 1.21.7

# Helmリポジトリアップデート
* Helmリポジトリを最新化します。

```
# helm repo list
NAME            URL                       
jetstack        https://charts.jetstack.io
# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jetstack" chart repository
Update Complete. ⎈Happy Helming!⎈
```

# 作業前情報取得
* 変更前の各種情報を取得しておきます。

```
# kubectl get all -n cert-manager
# kubectl get crd
# kubectl get clusterissuer
# kubectl describe clusterissuer
# helm list --all-namespaces
# helm history cert-manager -n cert-manager
```

# Helmアップグレード(エラーになる)
* Helm upgradeをやってみますがエラーになります。k8sバージョンに対してAPIバージョンが古すぎるというエラーのようです。色々試しましたが解決しなかったので一度cert-managerを消して、再インストールすることにしました。cert-managerが一時的に削除されても、通常のアクセスには影響ありません。

```
# helm upgrade --version vX.X.X cert-manager jetstack/cert-manager -n cert-manager --set installCRDs=true
Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) for this kubernetes version and it is therefore unable to build the kubernetes objects for performing the diff. error from kubernetes: unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta1"
```

# cert-manager削除
* helm uninstallもできない状態だったので、yamlファイルを使ってdeleteします。

```
# kubectl delete -f https://github.com/jetstack/cert-manager/releases/download/v0.8.0/cert-manager.yaml -n cert-manager
```

* 削除後の状態を取得しておきます。namespaceやCRDが消えていることを確認します。

```
# kubectl get ns
# kubectl get crd
```

# cert-managerインストール
* cert-managerをインストールします。cert-managerのサポートするk8sバージョンは [こちら](https://cert-manager.io/docs/installation/supported-releases/) を参照ください。

```
# kubectl create namespace cert-manager
# kubectl label namespace cert-manager cert-manager.io/disable-validation=true
# helm install cert-manager --namespace cert-manager --version vX.X.X --set installCRDs=true jetstack/cert-manager
```

# Cluster Issuer設定変更
* yamlファイルのAPIバージョン等が古くなっていると思われるため修正します。

```
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: [Your Namespace]
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [Your Email]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
```

* Cluster Issuerを再作成します。

```
# kubectl get clusterissuer
# kubectl apply -f cluster-issuer.yaml
# kubectl get clusterissuer
```

# Ingress設定変更
* Ingressに設定しているannnotationsが古いため修正します。

```
# vi ingress.yaml
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
↓
cert-manager.io/cluster-issuer: letsencrypt-prod
```

* Ingressを設定変更します。

```
# kubectl get Ingress
# kubectl describe ingress
# kubectl apply -f ingress.yaml
# kubectl get Ingress
# kubectl describe ingress
```

* しばらくして証明書が更新されていればOKです。

以上
VisulalStudioショートカットメモ

# 何度も検索してしまうショートカットのメモ

## cpp,hの行き来
Ctrl+K→Ctrl+O

# 開いているコードをソリューションで選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/8f84ef72-4318-6ef7-c458-4390ec9c9741.png)
BigQueryに接続するアプリケーションを作る際にGCPに作成したアカウントとロールの設定例

# 目的
GCP(Google Cloud Platform)での開発において、全ての作業者に同じ権限を与えるわけにはいかないので、実際にプロジェクトで割り振った権限を事例として記載しておく。
あらかじめ用意されているロールベースで割り振ったので、過剰な権限が割り振られてしまっている。本来であれば、必要な権限のみでカスタムロールを作成すべきなのだが、そのあたりは今後の課題としている。

# 前提条件
このプロジェクトではGCE(Google Compute Engine)、Cloud SQL、BigQueryを利用している。
WindowsのGCE上にアプリケーションを導入し、そのアプリケーションが設定情報が保存されたSQL Serverと業務データ(実際にはテストデータだが)が保存されたBigQueryからデータを取得するという構成である。
メンバーとしてプロジェクトのオーナーとオーナーからプロジェクト開発を委任されたプロジェクト管理者及びプロジェクトの開発者が存在していて、それ以外にアプリケーションのリソースへのアクセス権限を管理するためのサービスアカウントも作成している。
またGCEインスタンス(VM)へはセキュアな接続をしたいので接続IAP Desktopを利用している。

以上の条件の下での設定例となっているため、プロジェクトに応じて不要なロールやアカウントは削除してほしい。

# 実際に与えた権限

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484026/ab093d3f-77eb-f977-3eff-dbc7f74dc82f.png)

開発のメンバーに「編集者」のロールが付与されているが、これは本プロジェクトでは開発者自身がBigQuery上にデータセットやテーブルを作成することを想定しているからで、実際には試していないが、純粋に閲覧だけであればもっと弱い権限でも可能なはずである。

# まとめ
今回のプロジェクトでは利用していないサービスも多いので、はまるケースはあまりないかもしれない。
自分の備忘と、なんらかの参考になればと思っている。
Windows Updateの更新処理がなかなか進まない

[リコーのプリンタ（RICOH　MP　C6503）がWindowsUpdateあてたら印刷出来ない](https://qiita.com/moitaro/items/f54aaf83c37ce1b5796b)
の続きなのですが
なんかプリンタサーバーのWindowsServer2016に
KB5008207
を当てれば良いらしいのですが
あたらないヨ(T_T)

で色々調査していたら
[相変わらず「Windows Server 2016」の更新が遅々として進まない件：山市良のうぃんどうず日記（174） - ＠IT ](https://atmarkit.itmedia.co.jp/ait/articles/2003/25/news018.html)
でWindowsServer2016は古いのでアレという文言があったのでタイトルに据えてメモる……

これからもこちらの状況を追っていくためメモ失礼いたします。
<備忘録> railsサーバー立ち上げ時エラー対応

# 環境
* macOS      Monterey 12.0.1
* Ruby       2.6.3
* Bundler    2.2.17
* Rails      6.0.4.7

## エラー内容
```
ubuntu:~/environment/hello_app (master) $ rails s
=> Booting Puma
=> Rails 6.0.4 application starting in development
=> Run `rails server --help` for more startup options
warning ../../package.json: No license field
Puma starting in single mode...
* Version 4.3.6 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:8080
* Listening on tcp://[::1]:8080
Use Ctrl-C to stop
```

どうやらyarnのインストールを複数回行ったことが原因らしい。

```
rm -rf yarn.lock
```

### 参考文献

https://qiita.com/narimiya/items/fe0e308a2177c9f0e275
プレフィックスリスト ってなに

## 勉強前イメージ

vpcのなにか？

## 調査

### プレフィックスリスト とは

AWSのVPCの機能で、複数のCIDRブロックを一元管理することができます。
元々セキュリティグループで接続元の拠点を絞る際、複数プロトコルがあったら以下のようにいっぱい書かないといけなかったです。
22,80,443(3プロトコル) * 2拠点 = 6個 の記載が必要でした。

```
22番ポート  x.x.x.x
80番ポート  x.x.x.x
443番ポート x.x.x.x
22番ポート  y.y.y.y
80番ポート  y.y.y.y
443番ポート y.y.y.y
```

ここで拠点をリスト化して、重複したIPの設定を省略できるのがプレフィックスリストになります。
イメージとしては以下のように楽に設定ができるようになります。

```
拠点リスト : x.x.x.x, y.y.y.y
22番ポート  : 拠点リスト
80番ポート  : 拠点リスト
443番ポート : 拠点リスト
```

画面から見ると以下のように設定されています。

![1マネージドプレフィックスリスト _ VPC Management Console - Google.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f1320add-e8ad-1a65-1588-80265a6ba066.png)


### プレフィックスリスト のタイプ

プレフィックスリストには2つのタイプがあります。

- AWSマネージドプレフィクスリスト

AWSサービスのIPアドレスの範囲のセットで、元々から作られているものです。
所有者IDがAWSになっており変更・削除等はできません。

- カスタマー管理プレフィクスリスト

自分で作成するIPアドレスの範囲で、他のAWSアカウントと共有が可能です。

- ↑の違い

イメージとしては [IAM](https://qiita.com/miyuki_samitani/items/74c34ab5e98e2cd7e713) のAWS管理ポリシーとカスタマー管理ポリシーの違いと似てて、
AWSマネージドプレフィクスリスト → AWS管理
カスタマー管理プレフィクスリスト → ユーザ管理
の、イメージです。

## 勉強後イメージ

東京・名古屋・大阪・福岡に拠点があったとして、主回線と副回線があれば
拠点毎にプレフィックスリスト作ってやれば結構楽ってことね？？

## 参考

- [CIDR ブロックコレクションとプレフィックスリストを併用する](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/managed-prefix-lists.html)
- [[アップデート] 複数のCIDRをまとめて管理！Amazon VPC で プレフィックスリストが利用可能になりました](https://dev.classmethod.jp/articles/amazon-vpc-prefix-list/)
【PowerShell】ドラッグ＆ドロップしたファイルにタイムスタンプをつけてリネームする

# 概要

こちらの記事を見て、PowerShell を使ってできないか試してみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">知らない人のために説明すると、メモ帳にコードを書いて拡張子を&quot;.txt&quot;から&quot;.vbs&quot;に変更すると、ダブルクリックやドラッグ＆ドロップで起動できるツールが作れるという、Windowsのいにしえの技術です。 <a href="https://t.co/3ParDZacwP">pic.twitter.com/3ParDZacwP</a></p>&mdash; reime (@_reime) <a href="https://twitter.com/_reime/status/1469681656902856706?ref_src=twsrc%5Etfw">December 11, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 作成

PowerShell の .ps1 ファイルには、直接ファイルをドラッグ＆ドロップできないのでショートカットを利用します。

## 手順

まず、以下のファイルを作成します。

```powershell:Add-TimeStamp.ps1
using namespace System.IO;

<#
.Synopsis
   ファイル名の末尾にタイムスタンプを追加します。
.DESCRIPTION
   ファイル名の末尾にタイムスタンプを追加した名前でリネームします。
.EXAMPLE
   dir 'C:\Works' -File | tstmp
#>
function Add-TimeStamp {
    [CmdletBinding()]
    [Alias('tstmp')]
    [OutputType([FileInfo])]
    Param (
        # ファイルパス
        [Parameter(Mandatory, ValueFromPipeline, Position=0)]
        [FileInfo] $Path
    ) Begin {
        $dateStr = (Get-Date -f yyyy-MM-dd)
    } Process {
        rni $Path ("{0}_$dateStr{1}" -f $Path.BaseName, $Path.Extension) -PassThru
    } End {
    }
}

$args | tstmp
```

Add-TimeStamp.ps1 へのショートカットを作成して、[リンク先(T):] に以下のコマンドを設定し、[作業フォルダー(S):] を空にしておきます。  
※特定の作業フォルダーに ps1 ファイルを配置して使います場合は、[作業フォルダー(S):] を指定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/a6ee7371-4de0-4cee-9ce2-7bb69629069e.png)

```shell
powerShell -ExecutionPolicy RemoteSigned -File Add-TimeStamp.ps1
```

Add-TimeStamp.ps1 ファイルとそのショートカットを任意のフォルダに配置します。


## 使用方法

リネームしたいファイル (複数) を、作成したショートカットにドラッグ＆ドロップします。

![Rename.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/d8cca25d-e36b-868b-9680-f096c0586e63.gif)

# 追記

ファイルだけで出来るように Python を使ってやってみました。

https://qiita.com/MakotoIshikawa/items/2059282154f7fcda778a

# 参考サイト

- [Powershellスクリプトへファイルをドラッグ&ドロップする方法](https://bgt-48.blogspot.com/2019/04/powershell.html)
<備忘録>herokuログインで苦戦

# herokuにログイン
herokuにログインしようとした時に少し苦戦したので記録します。


## ログインできず

```
$ heroku login --interactive

　　--interactive　→　ブラウザを開かずにターミナル上でログインする
```

herokuにログインしようとメールアドレスとログインパスワードを入力したが


```
heroku: Enter your login credentials
Email: メールアドレス
Password: *********
 ›   Error: Invalid credentials provided.
 ›
 ›   Error ID: unauthorized
```

ログインできず

メールアドレスに間違いはないようなので
パスワードが怪しい。

## ログイン成功
Herokuのサイトを見ていて見つけました。

API key　・・・

試しに入力してみました。

```
ubuntu:~/environment/hello_app (master) $ heroku login --interactive
heroku: Enter your login credentials
Email: メールアドレス
Password: （API key）
Logged in as メールアドレス
```

以上
無事ログインできました。

でもなぜAPIkeyじゃないとログインできなかったのか
分かりません。

詳しい方教えてください。
brewでインストールしたmysql@5.7で、mysql -urootでエラーが出た話し

Montery(ver. 12.3) のmacに、brewでmysql@5.7をインストールすると、サーバは動くんですがmysqlコマンド

```zsh
/usr/local/opt/mysql@5.7/bin/mysql -uroot
```
を実行すると

```zsh
dyld[87763]: Library not loaded: /usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib
```

と怒られます。

/usr/local/optにopenssl@1.1へのシンボリックリンクを作ってやると起動できました。

```zsh
cd /usr/local/opt
ls -la
drwxrwxr-x   5 hoge  admin  160  3 16 09:27 .
drwxr-xr-x  14 root  wheel  448  3 15 17:56 ..
-rw-r--r--   1 hoge  admin    0  3 13 12:25 .keepme
lrwxr-xr-x   1 hoge  admin   26  3 16 08:56 mysql@5.7 -> ../Cellar/mysql@5.7/

ln -s ../Cellar/openssl@1.1/1.1.1m openssl@1.1 
ls -la
drwxrwxr-x   5 hoge  admin  160  3 16 09:27 .
drwxr-xr-x  14 root  wheel  448  3 15 17:56 ..
-rw-r--r--   1 hoge  admin    0  3 13 12:25 .keepme
lrwxr-xr-x   1 hoge  admin   26  3 16 08:56 mysql@5.7 -> ../Cellar/mysql@5.7/5.7.37
lrwxr-xr-x   1 hoge  admin   28  3 16 09:27 openssl@1.1 -> ../Cellar/openssl@1.1/1.1.1m
```

ちょっとハマりました。
【OpenAPIGenerator】mustacheファイルで末尾カンマを除去するには、`{{^-last}},{{/-last}}`を使えばよい

# 環境
* OpenAPI Generator v5.4.1
* Python 3.10.2

# やりたいこと
OpenAPIGeneratorを使って、Pythonのクライアントライブラリを作りたいです。

```yaml:petstore.yaml
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /foo/{foo_id}/bar/{bar_id}:
    get:
      operationId: getFooBar
      parameters:
        - name: foo_id
          in: path
          required: true
          schema: 
            type: string
        - name: bar_id
          in: path
          required: true
          schema: 
            type: string
      responses:
        '200':
          description: foo
          content:
            application/json:    
              schema:
                type: string

```

たとえば、上記のOpenAPI Specificationファイルから、以下のメソッドを作りたいです。

```python
def get_foo_bar(foo_id, bar_id):
    pass
```

パスパラメータはメソッドの引数として受け取れるようにします。

# 実現方法

openapi-generator-cliコマンドに、以下のmustacheファイルをテンプレートとして渡せば、上記のメソッドが出力されます。

```mustache:template/api.mustache
{{#operations}}
{{#operation}}
def {{operationId}}({{#pathParams}}{{paramName}}{{^-last}}, {{/-last}}{{/pathParams}}):
    pass
{{/operation}}
{{/operations}}
```

`{{^-last}}, {{/-last}}`は、「`pathParam`が最後の要素でなければ、`, `を出力する」ことを表します。

openapi-generator-cliコマンドを実行すると、「引数の末尾にカンマがない」メソッドが出力されました。

```
$ docker run --rm -u `id -u`:`id -g` -v ${PWD}:/local openapitools/openapi-generator-cli:v5.4.0 generate \
--input-spec /local/petstore.yaml --generator-name python --output /local/out --template-dir /local/template \
--global-property apis,apiTests=false,apiDocs=false
```


```python:out/openapi_client/api/default_api.py
def get_foo_bar(foo_id,bar_id):
    pass
```

# 補足
## 記事を書いたきっかけ
既存のテンプレートファイルを眺めていたとき、`-last`の意味が分かりませんでした。

https://github.com/OpenAPITools/openapi-generator/blob/86281a28c7c217d163d0649cb9857388e98c58a1/modules/openapi-generator/src/main/resources/python/model.mustache#L53-L55

Google検索で`-last`の意味は見つけられなかったので、今回調べたことを記事にしました。
超初心者が3週間でPython3データ分析試験に合格してみた

#超初心者が3週間でPython3データ分析試験に合格してみた勉強法をメモ程度に記載したページです

**■合格者のスペック■**
・国公立大学文系卒業
・業務でPythonは全く使用しない
・Python3エンジニア認定基礎試験は2022年1月中旬に取得済
・2021年1月16日から勉強を開始して、2022年2月頭に合格

**■勉強時間■**
合計３週間
平日1時間、休日3時間程度
ある程度の知識はエンジニア認定基礎試験でついていた

**■勉強方法■**
ほとんど書籍での勉強はしなかった。

①Udemyの講座で範囲ごとに勉強
受講するものは何でもいいと思います。
numpy、pandas、matplotlibなど範囲に分けて
実際にPythonを動かしながら勉強していきました。
特にnumpy、pandasをしっかりやることが大事だと思います。

②行列の計算ができるようにググって納得するまで理解するのと演習する
行列の計算が意外と間違いました。高校時代やっていない方は結構とまどうと思いますのである程度対策したほうが良いかと思います。

③模擬試験を毎日1題回答して8割くらいまでの完成度にする
他の皆さんがおすすめしているところのものです。（私は説明割愛します）

④時間があったので手持ちのデータで色々可視化してみる
matplotlibを使ってデータの可視化を色々遊んでいました。
特にmatplotlibは面白いので理解は早いと思います。

**■感想■**
行列やnumpyなど基本的なところを勉強するいい機会だと思います。
…と、同時にその範囲を舐めてかかると落ちると思いました。
基本的なPythonのコードは読める・理解できるようになりました
２つの試験を勉強することで、データの可視化はできますし、ちょこちょこ遊びでほかの範囲のUDEMYも聞いていたので機会学習もすこしできるようになっています。
資格はなくてもいい、、というお声もありますが、動機付けにはとてもよかったですし、ぜひみなさんも合格に向けて勉強されてみてください。
ridk のことをよく知ろう

# はじめに
Windows版rubyinstallerの話ですが、`ridk`ってご存知ですか。
私は知りませんでした。
# 実はいつも見ていた
![20220315a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/fed90a89-71d1-f96f-f355-c954a7f6ceb1.png)
rubyinstallerの終わりの方に出てくるコマンドプロンプト画面。
実はこれ、`ridk`だったんです。

次のバージョンをインストールするまでお目にかかることもないと思っていましたが、次のコマンドで呼び出すことができます。

```
C:\Users\user>ridk install
```
# 実はアップデートもできる
https://qiita.com/superrino130/items/b9a7bedd9737932ddfc9

2年前は`msys2`で`pacman`を使用していましたので、頻繁にアップデートしておりましたが、~~rubyinstallerを使用してからはアップデートしなくて楽だった~~次のコマンド等で、アップデート可能です。

```
ridk exec pacman -Syuu
```
もちろん、下記コマンドで`2 - MSYS2 system update (optional)`を選択するのが手っ取り早くて楽です。

```
ridk install
```
![20220315b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/132929ad-c2ca-6df8-9900-1f8885b524ff.png)
# 実は個別にパッケージをインストールできる
https://qiita.com/Ingward/items/b6d9fa4c8f705df8997a#step4-sqlite3%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
# 実はRubyのバージョンを切り替えることができる
```
C:\Users\user>ridk use
1 - C:/Ruby27-x64       ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x64-mingw32]
2 - C:/Ruby31-x64       ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x64-mingw-ucrt]
Select ruby version to enable:
```
https://qiita.com/denkiuo604/items/5098f46cb37712f715c5

以前は、RubySilverやRubyGold学習のために、`Ruby2.1`をインストールしたりもしましたが、切り替えられるとは知りませんでした。

https://qiita.com/superrino130/items/0b22c639bacc43ec9282
# まとめ
Windows版rubyinstallerに付属している`ridk`について詳しくなりました。
# 感謝
https://github.com/oneclick/rubyinstaller2

開発者の皆様、ありがとうございます。
cabalでGitレポジトリから直接パッケージをインストールする際のダウンロード量を削減するためのworkaround

Cabal 2.4以降では`source-repository-package` stanzaによってGitHubなどにあるレポジトリから直接パッケージをインストールできるようになっている。

例えば、cabal.projectファイルに以下のように記述する。

```
source-repository-package
    type: git
    location: https://github.com/brendanhay/amazonka
    tag: 0ccede621e56fb6f240e4850e205cde82d0e4a4b
    subdir: lib/amazonka lib/amazonka-core lib/services/amazonka-sts
```

(なお、subdirに複数のディレクトリを指定するには cabal-install >=3.2.0.0 が必要らしい)

これによってamazonkaパッケージをGitHubレポジトリから直接インストールできる。

ただし、このやり方では何かにつけてcabalがレポジトリのフルクローンをとるので、ものによっては膨大なダウンロードが発生してしまう。

これに対するworkaroundとしては、いったんローカルファイルシステムにshallow cloneをとっておいて、`source-repository-package`にはそのshallow cloneを指定するという手がある。

上記の例なら、まず以下のように2.0.0-rc1タグのスナップショットだけをローカルにクローンしておき、

```
$ cd /path/to/repo
$ git clone -b 2.0.0-rc1 --depth 1 --no-tags https://github.com/brendanhay/amazonka amazonka-2.0-rc1
```

cabal.projectにはローカルのGitレポジトリを指定する。

```   
source-repository-package
    type: git
    location: file:///path/to/repo/amazonka-2.0-rc1
    tag: 0ccede621e56fb6f240e4850e205cde82d0e4a4b
    subdir: lib/amazonka lib/amazonka-core lib/services/amazonka-sts
```

(試していないが、git cloneコマンドには`--bare`オプションをつけてもよかったかも)

参考:

- [8.1.1. Specifying Packages from Remote Version Control Locations - Cabal User's Guide](https://cabal.readthedocs.io/en/3.4/cabal-project.html#specifying-packages-from-remote-version-control-locations)
- [source-repository-package generates fat clones ・ Issue #7264 ・ haskell/cabal](https://github.com/haskell/cabal/issues/7264)
Raspberry Pi へ Windows からホスト名でアクセスできない (mDNS が動かない)

タイトル通りですがメモです。

Raspberry Pi Imager などで Raspberry Pi の名前を設定して起動するとネットワークなどの設定無し (zeroconf) で ssh などで設定した名前を使用しアクセスできるはずです。これは Raspberry Pi の名前を解決するのに mDNS/Bonjour ([RFC 6763](https://datatracker.ietf.org/doc/html/rfc6763)) という技術を使っているからです。

しかしこれがたまに動かない場合があります。個人的な使用範囲だと VNC Viewer でアクセスできない時が多いです。ping も動かない時は何故か動きません。

最近の Windows 10 なら mDNS/Bonjour は動くはずなんですが結論としては [iTunes](https://www.apple.com/itunes/) をインストールするのが良いようです。iTuens はインストールせず [Bonjour だけインストールする](https://www.phileweb.com/review/column/201905/20/723.html) という方法もあるようです。

因みに Wireshark で見るとまず DNS に問い合わせをして名前が見つからない場合に IPv4 と IPv6 の UDP マルチキャストでパケットを投げて返答をもらう仕組みのようです。通信を見るのに例えば c4labs.local という名前なら以下のようなフィルターが使用できます。

```
dns.qry.name == "c4labs.local" or dns.resp.name == "c4labs.local"
```

正常に動作している場合は以下のように見えます。最後に Standard query response というのが Raspberry Pi (10.185.2.201) からやはり UDP マルチキャストで返ってきています。

```
5062	2022-03-15 14:49:38.213920	10.185.2.236	55205	10.185.1.3	53	DNS	72		Standard query 0x4b6a A c4labs.local
5063	2022-03-15 14:49:38.217330	10.185.1.3	53	10.185.2.236	55205	DNS	72		Standard query response 0x4b6a No such name A c4labs.local
5065	2022-03-15 14:49:38.218104	10.185.2.236	5353	224.0.0.251	5353	MDNS	72		Standard query 0x0000 A c4labs.local, "QM" question
5066	2022-03-15 14:49:38.218431	ipv6:addr:xxxx:xxxx:xxxx:xxxx	5353	ff02::fb	5353	MDNS	92		Standard query 0x0000 A c4labs.local, "QM" question
5071	2022-03-15 14:49:38.262336	10.185.2.201	5353	224.0.0.251	5353	MDNS	82		Standard query response 0x0000 A, cache flush 10.185.2.201
```

正常ではない場合のキャプチャは確認できませんでした。もしかするとパケットキャプチャのレベルでは動いているように見えるのかもです。。

参照:
[マルチキャストDNS](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%83%81%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88DNS)
> mDNSメッセージは以下のアドレスに送信されるマルチキャストUDPパケットである。 
> - IPv4アドレス 224.0.0.251 または IPv6アドレス ff02::fb
Power Query Onlineにおけるクエリのマージの図示

# はじめに
　Power BI DesktopのPower Query エディターと同等の変換機能を持つ、Power BI ServceのPower BI Proのデータフロー内にあるPower Query Onlineのマージには、図示があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/cd72facf-6fc2-769a-9982-c4a43c0d6509.png)

# データフローはどこかから
　マイワークスペース以外のワークスペースで、データフローを新規作成します。空のクエリ等で画面を開きます。
あとは、Power Query エディターと同様ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/6aad1991-0e71-078b-de5e-a4718a5019c7.png)

図示付きの画面がでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/e21c01b2-95ad-3673-784b-3504f6ae8a17.png)


# 6種類の結合の種類

あらためてアップでw

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/cd72facf-6fc2-769a-9982-c4a43c0d6509.png)

マウスオーバーすると説明がでます。
- 左外部（左の行すべて、右のもののうち一致するもの）
- 右外部（右の行すべて、左のもののうち一致するもの）
- 完全外部（両方の行すべて）
- 内部（一致する行のみ）
- 左反（左の行のみ）
- 右反（右の行のみ）

最初の2つは、Power Query エディターは左を最初、右を2番目と呼んでいるのと、少し表現が違いますね。
- 左外部（最初の行のすべて、および2番目の行のうち一致するもの）
- 右外部（2番目の行すべて、および最初の行のうち一致するもの）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/19e17db9-c8ef-07d1-c099-edbcb2d69b3b.png)


# おわりに
　この図示はシンプルながら大変わかりやすいので、設定時についているとありがたいですね～。Power BI Desktopで使うたびに見たくなるので、Qiitaに乗せておきました。
　6種類の結合の内容は、@yugoes1021 さんのこちらのQiitaに詳しく載っています～

https://qiita.com/yugoes1021/items/6026532cb7ccdc11276d
oh-my-zshのプロンプトがkubernetesレポなどでめちゃくちゃ遅い

解決方法：

```
git config --add oh-my-zsh.hide-status 1
git config --add oh-my-zsh.hide-dirty 1
```

- https://stackoverflow.com/questions/12765344/oh-my-zsh-slow-but-only-for-certain-git-repo
- https://www.stevenrombauts.be/2018/04/disable-git-prompt-in-oh-my-zsh/
「対応」という言葉を使うのはやめよう


「対応」という言葉を使うのはできる限りやめよう。ではなくて

- 具体的に何をするのか書こう
- 「サポートする」ならサポートレベルを示そう
- 答えるだけなら「応対」だよ

## 対応とは

https://www.weblio.jp/content/%E5%AF%BE%E5%BF%9C

> たい‐おう【対応】
> ［名］(スル)
> 
> １ 同種の二つのものが向かい合い、対(つい)になっていること。「四辺形の互いに対応する角」
> ２ ある物事が、他の範疇(はんちゅう)に属する物事と、対立・相当する関係にあること。「ギリシャ文字のα(アルファ)は、ローマ字のaに対応する」
> ３ 互いにつりあいがとれていること。「文章の書き出しと結びを対応させる」
> ４ **周囲の状況などに合わせて事をすること。**「現実に対応した処置」「対応策」
> ５ 二つの集合A、Bがあって、Aのどの要素にも、Bの要素が少なくとも一つ定まる規則があること。ふつう、AからBへの対応という。

なにかをする、くらいの意味にしかなっていない...。

## 障害対応とは

https://qiita.com/glaciermelt00/items/87420395983671a6a9da

> 障害を検知
> 関係者に周知
> エラーが出ていなかった状態に切り戻す
> 障害報告書を作成・周知
> SRE チームと情報齟齬解消
> 解消できない場合、週次で議題に挙げ、問題解決を図る

そこまでが障害対応。なのですが、障害を検知しただけでも対応と言ったり、周知したら対応とか言っていないか。


## 〇〇対応とは

https://qiita.com/flyaway/items/e15b92290046685a8703

「◯◯をサポートしている」という意味で「〇〇対応」という言葉を使っている場合もある。
その場合はサポートレベルを明確にすることを目指そう。

「◯◯という環境をサポートしていますか？」という質問を受けたときには、下記の4段階のどれに当てはまるのかを数値で回答するのがよい。

> :weary: Level -1: 利用不可
> :worried: Level 0: 提供元では責任を取れない(own risk)
> :smile: Level 1: 対応する、**未検証**
> :laughing: Level 2: 対応する、**検証済**

## 他にも

「エラーになる問題の対応」

「バグ対応」

「多言語対応」

「ダークモード対応」

「正式対応」

「顧客対応」

日本語は、難しい...


## 結論

「前向きに検討」とか
「緊張感を持って対応」とか
言っていても伝わらないので


### 具体的に何をするのか書こう

- エラーになる問題の対応
    - → 例:「エラーになる問題の修正」「エラーになる問題の回避方法」
- バグ対応
    - → 例:「バグ修正」
- 多言語対応
    - → 例:「多言語表示」
- ダークモード対応
    - → 例:「ダークモード設定機能搭載」

### 「サポートする」ならサポートレベルを示そう

- 正式対応
    - → 例:「正式リリース」「正式サポート」

### 答えるだけなら「応対」だよ

- 顧客対応
    - → 例:「顧客応対」

https://www.weblio.jp/content/%E5%BF%9C%E5%AF%BE
> おう‐たい【応対】
>［名］(スル)相手になって、受け答えすること。「どんな客にも巧みに応対する」「電話の応対がうまい」

なんてところかもしれないですね。不具合はきちんと「修正」したいものだなあ...
以上「対応」ということば、`doSomething` 位にざっくりしすぎだよね、というポエムでした。
UnrealのC++で気を付けること

# はじめに
Unreal Engine のC++といっても, 普通のC++です, autoの推論規則が異なるとか, ヘッダの扱いが異なるとかそういうことはありません.

検証はしていない駄文です, 間違いだらけです.

- Unreal Header Tool
  - C++で独自のリフレクション機構やGC機構を実現するために, コンパイル前のプリプロセスを行います
- Unity Build
  - Unreal特有でもないですが, Unrealが積極的に活用しているため気を付ける特徴です
- Slate
  - 経緯は知りませんし, 調べたくないですが, どうしてこうなった感が強い, 埋め込みDSLを使うUIライブラリ. どうしてこうなった.
  - UMLはSlateのUIクラス階層と同じものを複製し, 同期して更新するとんでも機構, どうしてこうなった.

# Unreal Header Tool
DSLです, `UCLASS`, `USTRUCT`や`UPROPERTY`など, エディタやBlueprintで扱うためのクラスやプロパティの情報を処理します. リフレクション機構が充実しているC#では無用ですね. 特筆すべきは, `namespace`に対応していないことです.

# Unity Build
ビルドシステムに依ってサポートされる機能です. コンパイル単位を統合してしまう機能です. リンカ処理の回避によるビルドパフォーマンス向上や, コンパイル単位を超えた最適化を狙った機能と思います.

弊害も多いですが, 自分が扱いきれないからといって, プロジェクトの全モジュールで一律に無効にすることは横暴が過ぎます.

しっかり検証していないので話半分に, 危険回避の案とでも. 気を付けるべきは次だと思います.

- 裸のnamespace
- using namespace
- include
- define
- pragma

列挙すると, `namespace`はUnrealHeaderToolsの件も併せて使わない方針が楽です, ファイル名やクラス名は確実にユニークにしてしまいましょう. `using namespace`は関数スコープ内だけだと思います. `define`はユニークで, `pragma`は`push` & `pop`とセットでしょう.

# Slate
ドキュメント読んでもわからない, 慣れてくるとおそらくC++のこのメソッドがDSLのこれに対応しているのだな, とわかりますけど.
定数を指定する箇所で, C++のconstexprを指定しても通りません, CPP, Slate DSL, C++コンパイルの順なのかな, コンパイル時定数などは認識されないので注意です. まあ, まともに扱える人はいない感じです.

# おまけ
## staticの初期化
デバッガを繋いでエディタを起動するとわかりますが, クライアントのDLLはエディタ起動時にロードしています, このときにstatic変数は初期化されます. 以降, エディタ上でコンパイルボタンを押下した時などに, DLLの生成と再ロードを行います, ちゃんと"Reload"とメッセージがでますね, その時点でstatic変数は初期化されます, 当たり前ですけど. これはUnityでも同じですね.
次世代フォーマットのAVIFとJPEG拡張子の違い

次世代フォーマットAVIFとはなんだろうか。
---------------------------------------

AVIFとはこの地球上で最も新しい画像拡張子。(.avif)　
Google、Apple,Netflixなどでも使用されるほど注目を浴びています。

ウェブサイトの速度を改善し、閲覧ユーザーにとってストレスフリーにすることがトラフィックを向上するための最も大切なことになります。AVIFは画像のクオリティを下げないまま画像サイズの容量を大幅に改善することができます。

実際にAVIFではJPEGと比べると約60%、WebPと比べると35%もの画像サイズをクオリティをロスしないまま画像サイズを抑えることができます。Twitter上に掲載された海外のフリー素材サイトを運営するUnsplashのAVIFに関するツイートをご覧ください。imgixのお客様で元々はWebPを使用していました。ケーススタディ：”https://imgix.com/customers/unsplash”

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">At <a href="https://twitter.com/unsplash?ref_src=twsrc%5Etfw">@unsplash</a> we&#39;re now serving images in AVIF format (if the browser supports it), thanks to <a href="https://twitter.com/imgix?ref_src=twsrc%5Etfw">@imgix</a>! Lab data shows a ~30% decrease in image sizes. 🎉 <a href="https://t.co/ErmBowKW5K">pic.twitter.com/ErmBowKW5K</a></p>&mdash; Oliver Ash (@OliverJAsh) <a href="https://twitter.com/OliverJAsh/status/1441095716227543042?ref_src=twsrc%5Etfw">September 23, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


AVIFを使うことの利点
----------------------------------------
AVIFの拡張子を使うと画像の容量を削減するだけでなく以下の利点を得ることができます。

- ページ読み込み速度の改善
- SEOランキング向上 (googleなどでの検索で容量が抑えているサイトを上位に掲載されます）
- 直帰率の低下　（一度サイトを閲覧にきて、すぐに別のサイトに行ってしまう割合を減らします）
- 閲覧ユーザーの満足度向上
- bandwidth費用を削減

知ってる？AVIFが対応していないブラウザがある。。
----------------------------------------
AVIFいいじゃん、と思った方々、大変申し訳ない。AVIFはまだ全てのブラウザで対応している訳ではないのです。現在約69%のブラウザが対応している。

現在AVIFが対応しているブラウザ：
- Google chrome 85-93 
- Mozilla Firefox 86-92
- Android

AVIFが対応していないブラウザ：
- Microsoft Edge
- Firefox はanimated AVIFsがまだ
- Safari

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2592456/641c70be-edc5-3a26-bcce-6b4bb6dc3975.png)

ご安心。imgixのauto=formatで自動的に最適な拡張子を配信
------------------------------------------
imgixでは画像URLの最後に?auto=formatを加えるだけで自動的に適切な拡張子を提供します。
例：chromeからのアクセスではavif配信、SafariからのアクセスではWebPで配信といった具合。

auto = formatが設定されている場合、imgixは自動コンテンツネゴシエーションと呼ばれるプロセスによって画像を適切な拡張子で提供できるかどうかを判断します。ヘッダー、ユーザーエージェント、画像分析など、利用可能なさまざまな信号をコンパイルして、ユーザーに最適な画像形式を選択します。この形式は返送され、画像は正しくキャッシュされます。

auto=formatに関する詳しい情報はこちらから！https://docs.imgix.com/apis/rendering/auto/auto?_ga=2.220839835.261516489.1647308621-1202030278.1647308621#format

imgixを無償で検証してみたいという方は"Qiitaのブログを見た"とコメントに残してください。特典あるよ：）
[Argo Workflow]MyDNS更新用ジョブ定義

Jenkinsから移行中

# Mydnsログイン情報をSecretとして作成

```bash
kubectl create secret generic -n argo mydns --from-literal=username=(mydnsユーザー名) --from-literal=password=(mydnsパスワード)
```

# Mydnsワークフロー定義

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: mydns-update-
spec:
  entrypoint: mydns
  templates:
  - name: mydns
    dag:
      tasks:
      - name: mydns-update
        template: wget

  - name: wget
    container:
      image: alpine:3.7
      command: [sh, -c]
      args: ['
        wget -O- "http://$MYDNSUSERNAME:$MYDNSPASSWORD@www.mydns.jp/login.html";
      ']
      env:
      - name: MYDNSUSERNAME
        valueFrom:
          secretKeyRef:
            name: mydns
            key: username
      - name: MYDNSPASSWORD
        valueFrom:
          secretKeyRef:
            name: mydns
            key: password
```

# ジョブ実行結果

```bash
argo submit -n argo --watch mydns.yaml
```

```bash
Name:                mydns-update-5rsv2
Namespace:           argo
ServiceAccount:      default
Status:              Running
Created:             Tue Mar 15 19:31:33 +0000 (2 seconds ago)
Started:             Tue Mar 15 19:31:33 +0000 (2 seconds ago)
Duration:            2 seconds
Progress:            0/1

STEP                   TEMPLATE  PODNAME                        DURATION  MESSAGE
 ● mydns-update-5rsv2  mydns                                                
 └─◷ mydns-update      wget      mydns-update-5rsv2-1870706736  2s          

This workflow does not have security context set. You can run your workflow pods more securely by setting it.
Learn more at https://argoproj.github.io/argo-workflows/workflow-pod-security-context/
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851492/395aaae9-d081-7a83-fd00-3b4dd606b09c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851492/1e110ed7-b338-0594-bd88-fcac53c970ad.png)