OmniAICreator/Qiita-1.07M huggingface dataset:
MisskeyとTwitterに同時投稿するツールを作ったその後

## はじめに？

:::note info
これは[Misskeyアドベントカレンダー](https://adventar.org/calendars/7354)11日目の記事です。
:::


ここでは私が数ヶ月前にリリースしたツール[CaffeBruncher](https://bruncher.cffn.pw/)について書きます。
CaffeBruncherが何か知りたい人は[この記事](https://exdeck.site/archives/499/)を読んでもらえるとわかると思います。

## 本題

数行前に書いたとおり、私は数ヶ月前にMisskeyとTwitterに同時投稿するツールであるCaffeBruncherをリリースしたわけですが、元々ノリと勢いで開発を始めて気合いでリリースできる段階まで持っていったものなので当然バグや実装しきれていない機能があるわけです。
今回はそこらへんを書いていきたいと思います。

取り敢えず、今わかっているバグ等を列挙するとこんな感じになります。

- 画像付き投稿がまともにできない(半分くらいTwitter APIが悪い)
- WebKitで動かない機能がある(WebKitが悪い)
- 旧バージョンのMisskey APIに対応していない
- ~~かふぇぱの開発時間がない~~

また、実装したい機能もこんな感じであります。

- PWA対応
- WebIntentの実装
- Twitter側での伏せ字投稿機能
- UIコンポーネントライブラリをMUIからChakra UIに変更

今回はこれらについていろいろ書いていきたいと思います。

### 画像付き投稿

しれっと実装されている機能として、画像付き投稿(この表現は厳密ではなくて、動画もできるようになる)があります。
あるにはあるんですが、たまに失敗します。原因はわかりません。(←おい)
この機能を実装したときの私はNodejsのStreamのことを知らなかったのでStreamを使っていい感じ™に書き直したら直ると思います。
というのも今の処理だとTwitterへの投稿をしてからMisskeyへの投稿がされるようになっているんですね。
これをStreamをつかっていい感じ™に非同期な感じにすればきっとうまく行くと思ってます。(希望的観測)

### WebKitで動かない機能

実はCaffeBruncherは多言語対応(日本語・英語・韓国語・日本语)しています。
ここで言語設定を日本语にすると、なんと怪レい日本语で投稿するためのトグルが現れ、怪レい日本语で投稿ができるようになります。
しかし、この怪レい日本语変換には重大な欠点があってなんとWebKitで動きません。
というのも、WebKitは正規表現の後読みに対応していないので[cjp.js](https://github.com/Submarinonline/cjp.js)が使えないので動きません。
そしてなんとこの不具合、リリース前日に発覚しました。~~(直し方がわからないというか全面的にWebKitが悪いので直せていない)~~
きっとこの不具合は未来の私がなんとかします。。

### 旧バージョンのMisskey API

Misskey APIっていくつかのバージョンがあるんですね。[Issue](https://github.com/cffnpwr/caffe-bruncher/issues/14)が飛んでくるまで知りませんでした。
これに関しては旧バージョンのAPIの仕様が全くわからない状態なので調べるところから始めないといけません。
まあ、きっと未来の私がなんとかするでしょう。きっと……

正直なところ、Misskeyのバージョン判別のところからどうやってやろうという感じなのでこまこまのこまりです。

### PWA対応

多方面(要出典)から「PWAに対応しろ」と言われているので対応することにしました。
スマホで使うときはPWAは便利なのでね。

これを書いているときに「PWA対応ってどうやってやるんだろうか」と思ったのでざっと調べたところ、そこまで難しくなさそうだったのですぐに実装できそうです。
多忙™から抜け出したらやります。

### WebIntentの実装

これはTwitterとかにある[こんな感じ](https://twitter.com/intent/tweet?text=%E3%82%A6%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%AA%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2%E3%82%A2)でURLのクエリパラメータに内容を載せて投稿フォームに渡せる機能ですね。
これの実装もそこまで難しいものではないので多忙™から抜け出したらやります。

### Twitter側での伏せ字投稿

MisskeyにはCW(Content Warning)という投稿内容を隠せる機能があります。
しかし、Twitterにはそのような機能はないので現状ではMisskey側ではCWになるけどTwitter側ではダダ漏れ、という状況になっています。
これは私的にもいかがなものかと思うので[fuseclip](https://fuseclip.me/)を使って伏せ字投稿ができるようにしたいと思っています。
これも簡単そうなのでなんとかなるだろ。(KONAMI)

### UIコンポーネントの変更

現在のCaffeBruncherはMUIを使用してUIを作成しています。
ただ、問題として`yarn dev`で動かしているときのリロードがﾋｼﾞｮｰに遅いです。
なおかつビルドも遅いので「MUIやめたいなー」と思っていたときに[Chakra UI](https://chakra-ui.com/)を知ったのでこちらに移行しようかなというお気持ちです。
ただ、既存のコードをほとんど書き換えないといけないので正直面倒です。
未来の私がなんとかします。

## おわりに

最初の方にデカデカと書いてあるとおり、これはMisskeyアドベントカレンダーの記事なわけですが、アドカレに参加しようと思った当初はここに書いてあるバグ等のいくつかはすでに修正されて「修正しました！！」って書いているはずでした。
というのも今現在謎に忙しい状況で開発がほとんどできずほとんどのバグを認知したまま放置している状況です。
今この記事を書いているのも10日の23:40なわけですしおすし……

きっと来週くらいからは忙しさも落ち着くと思うので開発ができると良いですね。

それでは今回はここまで。
さらだばー！
製造ラインのオペレータが、Pythonメインのバックエンド開発業務に携わるまでのお話

## はじめに
本記事はProgaku Advent Calendar 2022 16日目
担当のけいです。

製造ラインのオペレータだった筆者が、Pythonメインのバックエンド開発案件に参画するまでのお話をまとめてみました。

バックエンドってなんやねんという方は[こちら](https://wa3.i-3-i.info/word18738.html)

## 対象読者
- 異業種からエンジニアに転職したいと考えている方
- プログラミングに興味がある方
- Pythonに興味がある方

## 自己紹介

まず、筆者の略歴をご紹介します。

|年|内容|
|---|---|
|2015|普通科の高校卒業|
|2015|印刷会社で製造ラインの仕事に就く|
|2017|前職でインフラ案件（サーバ運用保守）に参画|
|2019|現職に入社しインフラ案件（システム管理など）に参画|
|2022|現職にてPythonメインのバックエンド開発案件に参画|

## 製造ライン職から、エンジニアになりたいと思った理由
製造ラインの仕事をしていましたが、逃げ恥ブーム真っ只中でエンジニアという業種がキラキラしてみえました。
（平匡さんがハイスペックすぎます）

https://www.tbs.co.jp/NIGEHAJI_tbs/chart/

そこでエンジニアという広い枠組みに興味を持ち、ITインフラの基本的な勉強をして、前職・現職とインフラの案件に参画していました。

## なぜ、Pythonや開発に興味を持ったか
インフラの案件でシステム管理業務をしていた時、エクセル作業の自動化をするのが好きでした。
自動化について調べているとき、Pythonという大変オールマイティーな言語を知りました。

https://www.pasonatech.co.jp/workstyle/column/detail.html?p=2104

その後、インフラの学習の一環でAWSを触っていたのですが、
何かWEBアプリを自作してAWS上で動かしてみたくなり、PythonのWebアプリケーションフレームワークであるDjangoを触り始めました。

以下の書籍を読んでWEBアプリを作り始めましたが、勉強をしている感覚はなく遊び感覚でした！

https://www.amazon.co.jp/%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E5%AD%A6%E3%81%B6-Python-Django%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-NEXT/dp/479817419X

約半年でWEBアプリを作り終えた頃、「これを仕事にしたい」と悶々としましたので、
現職でPythonの開発業務に携わりたいと相談したところ、現在の開発案件に参画することができました！


## Pythonの開発案件に参画するために必要なこと

現在の開発案件に入るために、最低限必要だと思ったことは以下です！

#### Pythonのコーディング力
- [Progate](https://prog-8.com/)のPythonの無料講座を触ってみて、「Pythonで作る○○アプリ」のような本を参考に、実際にアプリを作ってみることをお勧めします。
  （スキルの証明・自信にもなりますし、筆者はどんなアプリを作ろうかと考えている時が一番楽しかったです！）

#### Pythonのコードを読む力
- [Python-izm](https://www.python-izm.com/)の入門編～応用編までをさらっと読んで、仕組みを理解できるようになれば上出来だと思います。 
  （応用編は全部を暗記する必要はなく、分からないことは都度調べればよいと思います。）
#### HTML/CSSの基本的な仕組みの理解
- [Progate](https://prog-8.com/)のHTML/CSSの無料講座で十分でした。

#### OS（Windows、Linuxなど）の基本操作
- ファイル・フォルダの操作などが行えれば十分でした。

#### コミュニケーション能力、質問力
- 最初はわからないことを聞く場面が多いです。質問しやすい関係性を作ることをお勧めします。

#### 調べる力、問題の切り分け
- 分からないことは一度ググりましょう。
- なぜそうなったのか、起こっている問題を切り分けすることを意識すると、より身につきやすいです。

## 参考
以下は筆者が実際に作ったWEBアプリです。

https://github.com/keydean130/nyapu

## まとめ
筆者は勉強が苦手でしたが、趣味の延長としてゲーム感覚でプログラミングにのめりこんでいます！
また、趣味を仕事にできたことで、自信にもつながりました。

皆様の今後の参考になれば幸いです！
AWS認定試験(SAA)の合格に100時間かかった話

この記事は Cocone Advent Calendar 2022の11日目の記事です。

# はじめに
![2022-12-11 0.01.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574237/d243b764-0d4b-4dbe-4e90-8c1539c3cde2.png)
> 学習時間の中央値が、だいたい40～50Hあたりと思われます。

~~**みんなカッコつけてないか？**~~
AWS認定ソリューションアーキテクトのアソシエイト(通称SAA)に合格したのですが、勉強時間**100時間**かかりました。その全勉強記録をかっこつけずに赤裸々に共有したいと思います。

これから受験しようとしている方の参考になれば幸いです。

# 試験について
> AWS Certified Solutions Architect – Associate (SAA-C03) 試験は、ソリューションアーキテクトのロールを担う個人を対象としています。
受験者はこの試験で、AWS Well-Architected Framework に基づくソリューションズ設計時に AWS のテクノロジーを使用する能力を検証されます。
また、次のタスクについての受験者の能力も検証されます。
• 現在のビジネス要件と将来予測されるニーズを満たすように AWS のサービスを組み込んだソリ
ューションズを設計する
• 安全性、耐障害性、高パフォーマンス、コスト最適化を実現したアーキテクチャを設計する
• 既存のソリューションズをレビューし、改善点を判断する

[AWS Certified Solutions Architect – Associate(SAA-C03) 試験ガイド](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Exam-Guide.pdf )

ざっくり説明すると、AWSの主要サービスについての知識と、ベストプラクティス([Well-Architected Framework](https://wa.aws.amazon.com/index.ja.html ))に則ったシステムが設計できるかを問われます。

試験の形式など詳細については[公式ページ](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/ )を確認してください。

# 前提
* 　会社ではサーバサイド開発を担当しており、担当システムでEC2やAuroraを利用しているが初期設定や構築はインフラチーム任せ
* 　SAAの前段であるクラウドプラクティショナー(CLF)にはSAA受験の半年前に合格

# 勉強期間
![IMG_6086.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574237/13dbe91a-63d7-8d5e-5054-a07606daba12.jpeg)
去年の10月から勉強を始めて今年の1月に合格しました。

勉強を始めたのが10/25で試験日が1/11なのと、年末年始は全く勉強しなかったので実質2ヶ月の勉強期間でした。

# 勉強に使った教材とかけた時間
#### 1. AWS認定資格試験テキストAWS認定クラウドプラクティショナーKindle版 (5時間32分)
まずやったのがCLFの復習です。

CLF合格から期間が空いたのでその時に使っていた参考書を読み直しました。合格後すぐにSAAの勉強に取り掛かれば省略できた時間ですね。。

CLFをまだ取得していない場合は先に取ることをお勧めします。

SAAはCLFの延長なのでそのままSAAの勉強に繋がっているのと、CLFの[合格特典](https://aws.amazon.com/jp/certification/benefits/ )でSAAを半額で受験することが可能になります。

https://www.amazon.co.jp/gp/product/B07QX45RXM/ref=ppx_yo_dt_b_d_asin_title_o07?ie=UTF8&psc=1

#### 2. AWS認定資格試験テキストAWS認定ソリューションアーキテクト - アソシエイト　改訂第2版 Kindle版 (29時間49分)
アソシエイト用の参考書です。次に紹介するUdemyの講座と並行して進めました。

通勤時は参考書、自宅ではUdemyというふうに勉強していました。

https://www.amazon.co.jp/gp/product/B08MVXRFFN/ref=ppx_yo_dt_b_d_asin_title_o06?ie=UTF8&psc=1


#### 3. これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座 (56時間2分)
業務であまりAWSのコンソールを触ったことがなかったのでとてもいい講座でした。

AWSアカウントを登録してハンズオン形式で一通りサービスに触りながら学習できるので、勉強したことが試験だけでなく業務で役に立つ場面も多かったです。

オススメです！


https://www.udemy.com/course/aws-associate/

#### 4. TeckStock AWS WEB問題集 (15時間35分)
最後の2週間くらい試験問題に慣れるためにスマホでポチポチやってました。

問題数がとても多く2週間では半分も出来ませんでしたが、それでもやっておいてよかったです。

実際に問題を解くことで、自分が理解していたつもりで理解できていない箇所を洗い出すことが出来ました。

https://techstock.jp/

#### 5. スタディプラス
AWSの教材ではないのですが、私が以前から使っているオススメのアプリです。

教材の管理や勉強記録、同じ目標を持ったユーザをフォローすることがでます。

今回教材ごとの勉強時間が出せたのもこのアプリのおかげです。

タイムラインにあげた自分の勉強記録にいいねが付いたり、フォロワーの勉強記録が投稿されるのが地味にモチベーションに繋がるので、一人だと勉強が長続きしない人にもおすすめです。

https://www.studyplus.jp/

# 試験結果
![2022-12-11 3.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574237/e48db2a5-f2ef-9322-4152-63c5573c416d.png)
100時間かけても余裕の合格ではありませんでした。

# 最後に
累計勉強時間は**106時間58分**でした。

前提が違うので人と比べても仕方がないのですが、業務でがっつりAWSを触ってなくても大体100時間勉強すれば合格できました。

この記事がSAA取得を目指す人の助けになれば嬉しいです！
paiza.ioでelixir その137

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
y = 3x - x^2 の曲線を描け。

# サンプルコード

```

IO.puts """
<!doctype html>
<html>
  <head>
  </head>
  <body>
    <button onclick="run()">play</button>
    <div id="applet_container"></div>
    <script type="text/javascript" src="https://www.geogebra.org/apps/deployggb.js"></script>
    <script>
var parameters = {
	"prerelease": false,
	"width": 570,
	"height": 400,
	"showToolBar": false,
	"borderColor": null,
	"showMenuBar": false,
	"showAlgebraInput": false,
	"showResetIcon": true,
	"enableLabelDrags": false,
	"enableShiftDragZoom": true,
	"enableRightClick": false,
	"capturingThreshold": null,
	"showToolBarHelp": false,
	"errorDialogsActive": true,
	"useBrowserForJS": false,
};
var applet = new GGBApplet(parameters, true);
window.onload = function() {
    applet.inject('applet_container');
}
function run() {
"""
IO.puts "ggbApplet.evalCommand('f(x)=3x-x^2');"
IO.puts """
}
    </script>
  </body>
</html>
"""
```

# 成果物

https://paiza.io/projects/z_RshcBvfss3cL14sdYK2w?language=elixir


以上。
paiza.ioでelixir その136

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
xorの真理値表を描け。

# サンプルコード

```

IO.puts """
<!DOCTYPE html>
<html>
  <head>
    <style>
table {
    border-collapse: collapse;
}
td,th {
    width: 30px;
    border: 1px solid #000;
}
td {
    text-align: center;
}
th {
    background-color: #ccc;
}
    </style>
  </head>
  <body>
    <script>
class C {
	constructor(n) {
	  this.n = n;
		this.s = [];
		var t = new Array(n);
		for (var i = 0; i < n; i++)
		{
		  t[i] = 0;
		}
		this.s.push(t);
		return this;
	}
	init(a, b) {
	  b = b + 1;
	  for (var i = a; i < b; i++)
		{
		  var t = [];
		  for (var j = 0; j < this.s.length; j++)
		  {
		    var u = this.s[j];
		    u[i] = 0;
		    t.push(u.slice());
		    u[i] = 1;
		    t.push(u);
		  }
		  this.s = t;
		}
	  return this;
	}
	xor(a, b, c) {
	  for (var j = 0; j < this.s.length; j++)
	  {
	    this.s[j][c] = this.s[j][a] ^ this.s[j][b];
	  }
	  return this;
	}
	and(a, b, c) {
	  for (var j = 0; j < this.s.length; j++)
	  {
	    this.s[j][c] = this.s[j][a] & this.s[j][b];
	  }
	  return this;
	}
	or(a, b, c) {
	  for (var j = 0; j < this.s.length; j++)
	  {
	    this.s[j][c] = this.s[j][a] | this.s[j][b];
	  }
	  return this;
	}
	get() {
	  return this.s;
	}
	table() {
    document.write('<table>');
    for (var row = 0; row < this.s.length + 1; row++)
    {
    	document.write('<tr>');
    	for (var col = 0; col < this.n + 1; col++)
    	{
    		if (col === 0 && row === 0)
    		{
    			document.write('<th>&nbsp;<\/th>');
  	  	}
    		else if (col === 0 && row !== 0)
	    	{
		    	document.write('<th>' + row + '<\/th>');
		    }
	    	else if (row === 0)
	    	{
		    	document.write('<th>' + (col - 1) + '<\/th>'); 
	     	}
	    	else
	    	{
		    	var v = this.s[row - 1][col- 1];
			    document.write('<td>' + v + '<\/td>');
		    }
	    }
	    document.write('<\/tr>');
    }
    document.write('<\/table>');
	}
}
"""
IO.puts """
var c0 = new C(3);
c0.init(0, 1);
c0.xor(0, 1, 2);
c0.table();
"""
IO.puts """
    </script>
  </body>
</html>
"""


```

# 成果物

https://paiza.io/projects/YqNN2GsCdBTRBIHFCEYE9A


以上。
キャラクターの足が地面に接したときに自動でPointを作成してEmitterを作る

キャラの歩行時にちゃちゃっと自動で煙などを出すときに使える技です
やることは
```
＞各足のパーツを一個にしてAssembleやPackなどで１個の点にする
＞キャラなどの足からIntersectして地面に近いときに点を作成してあげる
＞CopyToPointsでEmitterの形状の作成
```


1.地面とキャラクターを適当に作成してください
　今回は皆大好きCrag君とGridを適当に配置します

2．まずCrag君の足が複数パーツになってるので一個のパーツにしてしまいたいです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/29aad642-211c-6486-9d15-e56f0ff98aea.png)

3．PointDeformとConvexHullで各足を１個にまとめてあげます。（手動で好きな点を一個選んでもOKです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/b888b169-77f0-66c2-5561-6bcbba014b2e.png)


4．Assembleを使ってPackして、各足を1Pointにしておきます。
![2022-12-10_13h45_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/f9242520-d408-a024-eeb2-87a09fe30ed0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/7fc9c61e-de03-a302-2686-a275874a7890.png)



5．Intersectで当たったPとPrimNumberのAttributeを作成しておきます。
　 ヒットしない場合はPrimNumが -1 になります。当たれば当たったPrimNumが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/ab18ce02-00d3-73f3-9aff-e97a9d91ae22.png)

＞これがWrangleです。

https://www.sidefx.com/docs/houdini/vex/functions/intersect.html

```
//MakeID(To Kill in the End)
i@ID = 1;

vector origin = @P;
float max_dist = chf("foot_dist");
vector dir = max_dist * normalize(chv("dir"));

v@insect_pos;
float insect_u,insect_v;
i@insect_prim = intersect(1, origin,dir, v@insect_pos, insect_u, insect_v);
```

今この状態でヒット位置とヒットしたかどうかがわかる材料があります。

6．ヒットしてないPointをKillしておきます
![2022-12-10_13h52_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/08ac10eb-41b8-7ef6-7343-6bd3839e7976.png)


```
if(i@insect_prim<0){

    removepoint(0,@ptnum);

}
```

7．下記のようにwrangleを書くことでヒットした位置にPointを　addpoint　で作成してあげます。
　 注意点として、作成したPointに値を引き継ぎたい場合はsetAttributeをしないとだめです。
   vや他の物を引き継ぎたくなると思うので、その時は例に習ってsetです。

https://www.sidefx.com/docs/houdini/vex/functions/setpointattrib.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997785/0ea7c374-ef5e-6c19-5528-b896737e487e.png)

```
//Make Attribute to get again
int i = 0;

for( i; i<chi("iterations"); i++){

   int newpos = addpoint(0, v@insect_pos);
    setpointattrib(0, "v", newpos, v@v, "set");//保存したいAttributeがあればこれでセットしてあげないとゼロが入ります。

}

//Kill_Original
if(i@ID==1){

    removepoint(0,@ptnum);

}
```

8.あとはCopyToPointやPOPなどでこの点を使ってEmitしていけます！！:slight_smile:


キューピー３分クッキングに負けない勢いで簡単Intersectの話でした。

もしゃこ
「商大タクシー」というタクシー相乗り募集サービスを作った話

## はじめに
はじめまして！Yuです。
今回、「商大タクシー」というWebアプリを作成したので紹介したいと思います！
URL貼っておくので良かったら覗いてみてください！！技術面でのアドバイス等ありましたら教えていただけると嬉しいです。
[商大タクシー](https://shodaitaxi.space)
githubでもStarもらえると励みになります！
[github](https://github.com/YuNaga224/shodaitaxi)

## どんなサービスか？
### 概要
小樽商科大学の学生向けのタクシー相乗り募集サービスです。駅から大学まで一緒にタクシーに乗るメンバーを簡単に見つけることができます！

### なぜ作ったのか？
小樽商科大学には、見ず知らずの学生同士がタクシーに一緒に乗って大学へ向かうというタクシー相乗り文化がありました。（参考記事:https://www.chukei-news.co.jp/news/2019/05/20/OK0001905200f01_05/ ）しかしコロナ禍で授業が完全オンラインとなったことで、この文化は途絶え、対面授業になった現在も多くの学生がタクシーではなく満員のバスで登校するようになってしまいました。このタクシー相乗り文化という伝統を私達の代で絶やしたくないという思いから「商大タクシー」の開発に着手しました。
### 現状
すでに40人程度の商大生がユーザー登録してくれています。今後は新機能の開発に力を入れ、多くの商大生に使ってもらえるサービスを目指していきます！

### 使い方
#### メールアドレス無しで簡単にユーザー登録・ログインできます。
![ezgif com-gif-maker](https://user-images.githubusercontent.com/115802057/206840436-9ef6c993-2dd2-4b98-bb3d-52575f0b4149.png)
#### ホーム画面では募集中のグループが一覧表示されます。日付とJRを選択してグループを検索することもできます。
![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/115802057/206840490-00f5107b-8bc4-41c2-aaf0-8bf033c116ef.png)
#### メンバーが集まるとチャット画面に推移します。
![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/115802057/206840537-055fc72b-70f0-4439-a6c3-a452693ff8b7.png)
#### Ajaxによりロード無しでチャットのやり取りができます。ここで集合場所を決めましょう！
![ezgif com-gif-maker](https://user-images.githubusercontent.com/115802057/206840257-fad0e4e9-f3ae-4ad5-bd43-205d087993f0.gif)

## 使用技術
- PHP
- MySQL
- JavaScript
- HTML/CSS
- Ajax
- Apache
- AWS
  - VPC
  - EC2
  - RDS
  - Route53  

長期的な視点で考えたときにエンジニアとして成長していくためにもっとも重要なのは基礎の仕組みを理解することだと考え、Laravel等のフレームワークは使用せず、素のPHPを使ってMVCアーキテクチャに基づいて開発を行いました。
## データベース設計
### usersテーブル
|Column|Type|Options|
|-----|----|---------|
|id|varchar(20)|primary key|
|pwd|varchar(60)|not null|
|nickname|varchar(8)|notnull|
|relate_carpool|varchar(20)|not null, default 'none'|
|user_num|int(1)|not null default '0'|
### carpoolテーブル
|Column|Type|Options|
|-----|----|---------|
|id|int(10)|primary key, auto_increment|
|rep_id|varchar(20)|not null|
|user_1|varchar(8)| not null, default =""|
|user_2|varchar(8)| not null, default =""|
|user_3|varchar(8)| not null, default =""|
|user_4|varchar(8)| not null, default =""|
|selected_date|varchar(50)|not null|
|selected_jr|varchar(50)|not null|
### chatテーブル
|Column|Type|Options|
|-----|----|---------|
|id|int(10)|primary key, auto_increment|
|carpool_id|int(10)|not null|
|nickname|varchar(8)|not null|
|body|varchar(50)|not null|
## 機能一覧
- ユーザー登録・ログイン機能
- グループ機能
  - グループ作成機能
  - グループ検索機能
- チャット機能（Ajax）
## 今後追加予定の機能
- 募集中のグループをTwitterにツイートできる機能（TwitterAPI）
- マップにピンを立てて集合場所を決められる機能（GoogleMapsAPI）
## 最後に
ここまで記事を読んでくださった方々、本当にありがとうございます。今後も技術的な内容の記事や、新たなサービスの紹介などを投稿していこうと思っていますので、よかったらいいねやフォローしてくれると嬉しいです！！
pythonのmaltiprocessingでlambda関数みたいなものを使う方法

# やりたいこと
- pythonのmultiprocessing(Pool)を使って並列化計算をしたい。
- poolに関数を与えるときに、渡す関数の引数を調整するのにlambda関数を使いたい。

# 課題感
しかし、multiprocessingではlambda関数を渡せない。。
```python:動かないコード
from multiprocessing import Pool

# 並列化したい関数
def tgt_func(a, b, c):
    return a + b + c + 1

def main():
    a_list = [1, 2, 3, 4, 5, 6, 7, 8]
    
    # 並列化したい処理（逐次実行版）
    # result = [tgt_func(a, b=10, c=10) for a in a_list]
    
    # 並列処理版
    num_parallel = 8
    with Pool(num_parallel) as p:
        imap = p.imap(lambda a: tgt_func(a, b=10, c=10), a_list)  # ← ここで "lambda's can't be pickled" とエラーがでる
        result = list(imap)

    print(result)
```


# 解決方法
次のような実行可能(callable)なクラスをつくって渡す。
```python:
from multiprocessing import Pool

# 並列化したい関数
def tgt_func(a, b, c):
    return a + b + c + 1

# 疑似lambda関数
class PseudoLambda():
    def __init__(self, b, c):
        self.b = b
        self.c = c
    def __call__(self, a):
        return tgt_func(a, b=self.b, c=self.c)

def main():
    a_list = [1, 2, 3, 4, 5, 6, 7, 8]
    
    # 並列化したい処理（逐次実行版）
    # result = [tgt_func(a, b=10, c=10) for a in a_list]
    
    # 並列処理版
    num_parallel = 8
    with Pool(num_parallel) as p:
        imap = p.imap(PseudoLambda, a_list) # lambdaで書いていたところを作ったclassで置き換えするだけ
        result = list(imap)

    print(result)

```

# もう少しだけ発展的な方法
次のように、基本的な動作を全てクラスに追加して抽象化すれば、コードを再利用しやすい。
```python:
from multiprocessing import Pool
from tqdm import tqdm

# 並列化したい関数
def func(a, b, c):
    return a + b + c + 1

# 並列計算機
class ParallelCalculator():
    def __init__(self, func, **fixed_args):
        self.func = func                    # 実行する関数
        self.fixed_args = fixed_args        # 固定値で使用する引数たち

    def __call__(self, arg):
        return self.func(arg, **self.fixed_args)
        
    def exe(self, num_parallel, args_list):
        with Pool(num_parallel) as p:
            imap = p.imap(self, args_list)
            result = list(tqdm(imap))       # tqdmを使ってプログレスバーも表示
        return result

def main():
    a_list = [1, 2, 3, 4, 5, 6, 7, 8]
    
    # 並列化したい処理（逐次実行版）
    # result = [func(a, b=10, c=10) for a in a_list]
    
    # 並列処理版
    pc = ParallelCalculator(tgt_func, b=10, c=10)
    result = pc.exe(num_parallel=8, a_list)

    print(result)
```

# おわりに
- とりあえず何とかできた。
- 並列計算で共通で使用する引数(今回のコードの場合、変数bとかc)が大きいオブジェクトの場合、引数をコピーしないようにrayというライブラリを使ったほうがいいかも。
リストすべてをstr型からint型を相互に変換する方法

## Map関数を使う
map関数とはリストないすべての要素に関数を適用するというものである。

例えば list1[ '1', '1', '1', '1']というリストが有った場合
list1 = map(int , list1)をすることですべて整数型にすることができる。
もちろん逆も同じようにすれば簡単にできる。
ソースコード自動生成サービス「AI Programmer」を使ってみた

この記事は、以下のアドベントカレンダー12/11になります。

https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output

# はじめに
最近話題になっているAIで何かを生成する技術。
私のお仕事の一部であるプログラミングについても「AI Programmer」というサービスが話題になっているので試してました。

# AI Programmerとは

https://aiprogrammer.hashlab.jp/

有限会社ASRealが提供している日本語で指示した内容のコードを自動生成してくれるサービス。
十数種類のプログラム言語が選択できる。
バックグラウンドではOpenAIが発表した深層学習を用いた言語モデルGPT-3を利用している。

# 使い方
[サイト](https://aiprogrammer.hashlab.jp/)から言語を選択して処理内容を入力するだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989189/ea0dda24-b33e-d0b9-22bf-f74ef4728183.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989189/97c96305-7d59-29b6-79bb-b860489f87e5.png)
こちらはサイトに記載されていたサンプルを実行した結果です。
イメージしていた結果とは異なりました。
データベースにはアクセスしていませんね。。。
何パターンか試してみます。

# 実行例
今回は私がメインで利用しているpythonについてやってみます。
日本語の文章が指示内容で、その下が生成されたコードです。

## 計算する
### 1足す1
    1足す1

    1+1

### 引数を2乗する

    引数を2乗する

    def square(x):
      return x * x


## 文字列
### 文字列の長さを求める
    文字列の長さを求める

    len("文字列の長さを求める")
・・・まあ間違ってはいない。

    変数の長さを求める

    len(x)

「変数」と指示してあげると良いらしい。

### 置換

    文字列のaをbに置換する

    "a".replace("a", "b")

文字列という単語は微妙らしい(2回目)

    変数xのaをbに置換する

    x = x.replace('a', 'b')

良い感じで生成されました。

## 配列

繰り返し

    配列を繰り返す

    for i in range(len(arr)):
        print(arr[i])

これも間違ってはいないけど。

    配列から1つずつ表示する

    for x in array:
      print(x)



### 重複排除
    配列から重複を取り除く

    arr = [1, 2, 3, 4, 5, 5, 5, 6, 7, 7, 8, 9, 9]

    arr = list(set(arr))

急に実際に動くサンプルコードの形ででてきました。

### ソート
    配列を昇順に並び替える

    arr.sort()

そういえばソートのアルゴリズムっていろいろあったなと思い出したので
指定してみました。


クイックソート(https://medium-company.com/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%BD%E3%83%BC%E3%83%88/)

    配列をクイックソートで並び替える

    arr = [5, 2, 4, 1, 3]

    def quick_sort(arr):
        if len(arr) <= 1:
            return arr
        pivot = arr[int(len(arr) / 2)]
        less_arr, equal_arr, greater_arr = [], [], []
        for i in arr:
            if i < pivot:
                less_arr.append(i)
            elif i > pivot:
                greater_arr.append(i)
            else:
                equal_arr.append(i)
        return quick_sort(less_arr) + equal_arr + quick_sort(greater_arr)

    arr = quick_sort(arr)

おぉ、、、ちゃんとでましたね。最近はsortメソッドしか使っていなかったので懐かしさがあります。


## ネットワーク装置を操作する
ネットワーク系エンジニアということでネットワーク装置の操作も試してみます。

    装置にログインする

    log_in_to_device()

知らないメソッドが出てきました。
検索してみましたがヒットしないので、存在しないようです。

色々とワードを変えて試したところそれっぽいのができました。

    ネットワーク装置にtelnet接続する

    import telnetlib

    HOST = "192.168.1.1"
    user = "admin"
    password = "admin"

    tn = telnetlib.Telnet(HOST)

    tn.read_until("login: ")
    tn.write(user + "\n")
    if password:
        tn.read_until("Password: ")
        tn.write(password + "\n")

    tn.write("enable\n")
    tn.write("conf t\n")
    tn.write("int loop 0\n")
    tn.write("ip address 1.1.1.1 255.255.255.0\n")
    tn.write("end\n")
    tn.write("exit\n")

    print tn.read_all()

ciscoっぽい雰囲気ですね。しかもループバックIPまで設定してくれてます。

# まとめ
AI Programmerを試してみました。
簡単な処理は単語数も少なく曖昧さが出てしまうため微妙な結果が出てくることが多いので、
明確な表現、単語にするのが良いようです。
具体的な処理や複雑な処理などを生成するのに向いていると感じました。
また、上記のクイックソートのようにアルゴリズムや名前が決まっている処理も得意なようです。
狙った結果が出てくるよう入力を思考錯誤するところは、普段の検索と同じだなと感じました。
UE4でアカウントシステムを作りたい！！！

*始めてQiitaを触ったのでかなり見にくいかと思います。ご了承ください。*
# BPでplayfabを利用してアカウントシステムを作る
調べた感じ公式がプラグインを用意しているのはplayfabしかありませんでした。ですのでこちらを利用していきたいと思います。

<b>まずplayfabに登録してください(MSのアカウントで自分はログインしました)

https://developer.playfab.com/en-us/sign-up


<b>次にこちらの公式プラグインをエンジンにインストールして有効化して下さい(無料です)

https://www.unrealengine.com/marketplace/ja/product/playfab-sdk

ue5に関してはまだ2022年12/11日現在5.0にしか対応していないようです

# 実際にBPを組んでいく
<b>①まずはplayfabへの接続を行います

set playfab settingsノードをどこでもいいのですが始まったら呼び出してください。ここでGame Title IdとPlay Fab Secret Api Keyが必要です。
Idはstudio Idです。playfabの最初の管理画面にあります。
apikeyはstudio設定(歯車マークのやつ)→titlesetting→secret keysにあります。
![スクリーンショット (74).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/4a5533e1-4225-6730-1524-999b95279090.png)

<b>②アカウントを登録できるようにします

ウィジェットを作成します。
テキストボックスはメアド、パスワード、名前が最低限あれば大丈夫です
![スクリーンショット (75).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/f10a3bb5-4ac4-d0d3-240c-c3c136a009ba.png)


後は各テキストボックスの値をstring型の変数に格納してRegister Play Fab Userノードに各値を渡してください(ノード下のカスタムイベントを追加しないとエラーになります・ノードは始め構造体になっているためノードのrequestピンを右クリックして分解してください)
![スクリーンショット (76).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/7c742d4c-a059-4928-c498-f81bd0cf66ef.png)

ノードのを何らかの方法(ボタンとか)で実行すると登録が引数の情報をもとに登録が行われます

<b>③ログイン処理を組みます
![スクリーンショット (77).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/b16e668d-1c82-6686-53e0-5b0b6c08bc14.png)

パスワードとユーザーネームのテキストボックスを用意してください
![スクリーンショット (78).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/b1396cb2-d7ab-1b2f-1044-c51947e12021.png)

テキストボックスのデータをstring型の変数に格納してください。そしてLogin with Play Fabノードを呼び出し、requestピンを分解して変数のパスワードとユーザーネームを引数にセットして下さい。

![スクリーンショット (79).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/f0bfed4d-7a19-7ee9-e5d3-2aad3f1d57a3.png)
successコールバックが来たらピンを分解してその中にあるplay fab idをgameinstanceとかに保存してください

# クラウドセーブを実装する
今回はデータがあるか確認してあった場合表示してなかったら作成して表示するbpを組みます

<b>①データがあるか確認する処理を組む

先ほどgameinstanceにplayfabIDを保存したと思いますが、そのデータを引数にGet user Dataノードを呼んでください。keyはなんでも構いません。今回は"coin"にしました。
そしてsuccessコールバックを分解してget fieldを呼びます。nameは先ほど設定した"coin"です。それをas objectへ戻り値を渡し、さらにその戻り値からget string fieldを呼びます。field name は"value"です。そしてデータがなかった場合戻り値のstringを使用すると警告が出るのでas objectの戻り値をis validを使ってifで分岐させます。


![スクリーンショット (81).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/d9dcbf26-8dc2-e583-044c-3a36a49292ff.png)

<b>②データがなかった場合データを作成する

先ほどのif文でfalseだった場合、construc json string valueを呼んでas objectにセットしてset fieldのターゲットに戻り値をセットします。field nameは当然"coin"です。そしたらupdate user dataノードを呼び、requestを分解してrequest dataにset fieldの戻り値をセットしてください。これでアップデートできるはずです。
![スクリーンショット (82).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953041/5d22ff57-bfd7-f5b0-d9c6-2486b0ec962a.png)

# 参考にさせて頂いたサイト
https://fire-rain.hatenablog.com/entry/2019/07/13/214424
jqでレイマーチング

## 成果物

![video1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136875/45866aed-5b1e-1051-a56c-d7ff2cf095a6.gif)

## コード

```
def mod($d): fmod(.; $d) | if . < 0 then . + $d else . end;
def vec3Add($v): { x: (.x + $v.x), y: (.y + $v.y), z: (.z + $v.z) };
def vec3Mul($s): .[] *= $s;
def vec3Mod($s): .[] |= mod($s);
def vec3Sub($v): vec3Add($v | vec3Mul(-1));
def vec3Div($s): vec3Mul(1 / $s); 
def vec3Dot($v): .x * $v.x + .y * $v.y + .z * $v.z;
def vec3Length: vec3Dot(.) | sqrt;
def vec3Normalize: vec3Div(vec3Length);

def positionToSphereDistance($r): vec3Length - $r;

. as $t |

def positionToDistance:
  vec3Add({ x: (0.25 * $t), y: (0.125 * $t), z: (-0.5 * $t) }) |
  vec3Add({ x: 4, y: 4, z: 4 }) | vec3Mod(8) | vec3Add({ x: -4, y: -4, z: -4 }) |
  positionToSphereDistance(1.0);

def positionToNormal:
  positionToDistance as $dist |
  def e: 0.001;
  {
    x: ($dist - (.x -= e | positionToDistance)),
    y: ($dist - (.y -= e | positionToDistance)),
    z: ($dist - (.z -= e | positionToDistance))
  } |
  vec3Normalize;

({ x: -0.5, y: -0.5, z: 1 } | vec3Normalize) as $lightDirection |

def positionToLuminance:
  positionToNormal | vec3Dot($lightDirection);

def screenPositionToLuminance:
  def camPos: { x: 0, y: 0, z: 4 };
  (vec3Sub(camPos) | vec3Normalize) as $rayDir |
  def positionToLuminance(i): 
    positionToDistance as $dist |
    if i >= 32 then 0
    elif $dist < 0.0001 then positionToLuminance
    else vec3Add($rayDir | vec3Mul($dist)) | positionToLuminance(i + 1)
    end;
  camPos | positionToLuminance(0);

def luminanceToString:
  [0, ([., 1] | min)] | max |
  def grayscaleStrs: [" ", ".", ":", "+", "o", "0"];
  grayscaleStrs[(grayscaleStrs | length - 0.001) * . | floor];

def canvasToText: [.[] | [.[] | luminanceToString] | add] | join("\n");

def canvasSize: { x: 64, y: 32 };

def canvas:
  [
    range(canvasSize.y) | (2 * (. / canvasSize.y) - 1) as $y | [
      range(canvasSize.x) |
      { x: (2 * (. / canvasSize.x) - 1), $y, z: 0 } | screenPositionToLuminance
    ]
  ];

canvas | canvasToText
```

を、`raymarching.jq` として保存し、シェルスクリプトから

```
for t in $(jq -nr 'range(1024)'); do echo $t | jq -fr raymarching.jq; done
```
で呼び出す。

## 全体の流れ

* `raymarching.jq` は、時間を受け取りそれに対応するアスキーアートを返す
  * 時間は `. as $t` としてしまい、以降ファイル内どこでも参照可能にしている
* `canvas` で明るさを0～1で表した二次元配列を生成し、それを `canvasToText` でアスキーアートに変換しそれを結果としている
* 画面位置ごとの明るさは `screenPositionToLuminance` で求める
* レイの進行は `positionToLuminance` の再帰
  * 新しい位置で `positionToLuminance` を再度呼び、距離が一定以下になったら再帰をやめている

## その他

* 定数は、`def` か `as $var` を使う
  * 計算があるものは `as $var` のほうが良い？
* `fmod` は負のときに返り値も負になるのでGLSLと同じで常に正になるよう、`mod` を用意した
* `|` を行頭か行末どちらに書くか迷うが、関数先頭など、記述不要箇所でも自動でパイプを受け取るのであえて強調する必要性が低そうなので末尾にした
* 関数はフィルタが基本になるので、`hogeToFuga` みたいな関数名にすると分かりやすい気がする

## 参考

* https://m-hiyama.hatenablog.com/entry/2022/12/05/122205
* https://qiita.com/jpnykw/items/7096fe59d1edf3ef3aa3
* https://stedolan.github.io/jq/manual/v1.6/
* https://github.com/stedolan/jq/wiki/Internals:-backtracking
proxmox＿インストールで詰まったので備忘録

#
・**本記事を書いた目的**
本番環境、２台で構築するためHyper-vで疑似環境を用いてテストを実施。わからないところがあったので備忘録としてまとめました。

:::note alert
解決したかった箇所
- Hyper-v内のproxmox でVMを作成した際にエラーが表示される
　BIOSでIntel(R) VirtualizationTechnology　←**有効化済み**
⇓
- エラーが表示されて、そもそもクラスタが作成できない
⇓
- クラスタ作成後片方のPCを削除したさいにWEB側で削除したPCが表示されている
⇓
- etc...（思い出したら書き足します）

:::
***
:::note warn
・**初めに**
記事投稿初心者です。見ていて不愉快または指摘がございましたらコメント欄で
お教えてください。改善します。
よろしくお願いします。
:::
<details><summary>Hyper-v構築元PCのスペック</summary>

・ハード
プロセッサ	11th Gen Intel(R) Core(TM) i9-11900KF @ 3.50GHz   3.50 GHz
実装 RAM	32.0 GB (31.9 GB 使用可能)

・OS
エディション	Windows 11 Pro
バージョン	22H2
インストール日	‎2022/‎09/‎29
OS ビルド	22621.675
エクスペリエンス	Windows Feature Experience Pack 1000.22634.1000.0
</details>

***
:::note info
・**前提**

以下、記事を参考にHyper-vの有効化を実施、BIOSについては各々有効化。
https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v

まず、初めに以下、実機を使用したスライドをご確認ください＿proxmox 導入までの手順
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vTHPCLpyE7gzvXJ7-dqiFImGAfiVlTyszhbLR_RClK8q8i1r63w96Jvt7eEqbjWCR_lKZ_3ShHn9lwn/embed?start=false&loop=false&delayms=3000" frameborder="0" width="1440" height="839" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

:::

#
###
###
##
**本題**
- **Hyper-v内のproxmox でVMを作成した際にエラーが表示される**

　以下のサイトで解決した

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/nested-virtualization

　以下、くわしい説明

https://jisaba.life/2021/05/05/post-1601/

- **エラーが表示されて、そもそもクラスタが作成できない**
 以下のqiitaの記事で解決した

https://qiita.com/honahuku/items/7335158659cfb1b4580f

- **クラスタ作成後片方のPCを削除したさいにWEB側で削除したPCが表示されている**

個々proxmox で以下コマンドを実行
~~~:root＠pve
cd /etc/pve/nodes
~~~
⇓
上記コマンド実行後、初期はpveのみ。
クラスタ構築後、他ホスト名がここに表示される

[例]
pve1 を追加した場合は以下の表示になる
~~~:root＠pve/etc/pve/nodes#
pve pve1
~~~
以下、参考に

https://qiita.com/jr2twt/items/5642daaf15846d71a440

###

<details><summary>作成日時</summary>

（令和４年）2022/10/20
</details>

<details><summary>以下、
（引用元・参考元）＿全量</summary>

・マイクロソフト＿ドキュメント

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v


***
・一般ドキュメント

https://jisaba.life/2021/05/05/post-1601/

https://qiita.com/jr2twt/items/5642daaf15846d71a440

https://qiita.com/honahuku/items/7335158659cfb1b4580f

</details>

###
５分で出来るCompose風画像編集機能


Androidで、できるだけ簡単に画像編集機能を作成したい。
できればUIは自分で弄りたい。
更にできればUIはXMLではなく、Composeで作成したい。

という方法をこれから説明致します。

まず、画像編集機能はこちらのライブラリを利用します。
https://github.com/burhanrashid52/PhotoEditor

PhotoEditorでは画像編集機能を持ったViewを提供してくれて、
描く、文字表示、消しゴム、フィルターといった機能が実現できます。
PhotoEditorの良いところは機能のみを提供してくれてそれを実現するUIは利用側が好きに作ることができるところです。

PhotoEditorを使用する方法をざっくり説明すると、
PhotoEditorViewという専用のViewをXMLレイアウトにセットして
PhotoEditorViewとContextからPhotoEditorを作成します。
そのPhotoEditorに対して設定を行うことで描く、文字表示、消しゴム、フィルターといった機能を利用できます。


Jetpack Composeにはご存知、既存のXMLリソースをComposeUIで利用するための仕組みがあります。それがAndroidViewコンポーザブルです。（詳細は下記URLをご参照ください）
https://developer.android.com/jetpack/compose/interop/interop-apis?hl=ja#views-in-compose

というわけど、AndroidVeiwコンポーザブルにPhotoEditorViewをガッチャンコ。


まずはgradleに以下のライブリを追加。

```gradle
    implementation 'com.burhanrashid52:photoeditor:2.0.0'
    // 以下はAndroidVeiwコンポーザブルにガッチャンコするのに必要
    implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
    implementation "androidx.compose.ui:ui-viewbinding:1.3.2"
```

あとはよしなにAndroidViewを呼び出します。

```kotlin
    var photoEditor by remember { mutableStateOf<PhotoEditor?>(null) }
    AndroidView(
        modifier = Modifier.height(480.dp).fillMaxWidth(),
        factory = { context ->
            val editorView = PhotoEditorView(context)
            editorView.source.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.tower))　 
            editorView
        },
        update = { editorView ->
            photoEditor = PhotoEditor.Builder(editorView.context, editorView)
                .setPinchTextScalable(true)
                .setClipSourceImage(true)
                .build()
        }
    )

    // とりあえずブラシモードを利用できるようにします。
    photoEditor?.setBrushDrawingMode(true)
    val brushSize = 250f
    val opacitySize = 125
    val color = 0xffff0000.toInt()

    val builder = ShapeBuilder()
        .withShapeOpacity(opacitySize)
        .withShapeColor(color)
        .withShapeSize(brushSize)

    photoEditor?.setShape(builder)
```



完成動画

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478179/a86d24ed-f95f-1f86-12fd-19449d3688cc.gif" width="300">


これで画像編集機能を無事使えるようになりました！！！
やったね☆




## PhotoEditorのちょっと気になるところ

上のサンプルコードで

```
    val brushSize = 250f
    val opacitySize = 125
    val color = 0xffff0000.toInt()

```

ブラシの透過率を
opacitySizeで設定しているんですが、これのMAXは255なんですね。
なら描画されるのは半透明の赤では？？と思われるかもしれないのですが、PhotoEditor 2.0.0ではバグのために透過されません。(一応PRは出しました)
透過率を設定したい場合はフォークして修正して使う必要がありそうです。

以上です！
Rustで一日でDiscordBotを作る

今日は（ほぼ）Rust未経験の私が1日でDiscordBotを作ったときに気が付いたことや知っておくと便利な事柄ついて記載していきます。
作ったものの記事→　[くそアプリアドベントカレンダー](https://qiita.com/yuriacats/items/b3ab150757ed11bce7f7)

## 環境構築って大変→DevConteinerに任せよう

Rust、Python、C#など幅広い言語のサポートがされており、物足りなければDockerConteinerを自前で作ればいい気軽さ。これで環境依存のエラーとはおさらばだ

## DiscordBot作成は簡単だぞRustならね。
https://github.com/serenity-rs/serenity
RustでDiscord実装を行う際の定番ライブラリーである`serenity`は2022年12月現在ですと、以下の組み合わせでInstallができます。

Installコマンドを打たなくても勝手に大丈夫かチェックしInstallまでしてくれる当たりすごい仕組みが動いているんだなと思いました。今後詳しく調べてみたい事項の一つですね。

```
[dependencies]
serenity = "0.11"
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
```

## 他言語で言うSwitch相当のmatch構文が便利！
型回り（特にString型をmatch構文で扱う際は、`&*`を接頭辞に入れて`&str`型に変換して比較しないといけない）に多少癖があるもののシンプルなシンタックスでかけるSwitch文はアプリケーション開発において便利度が高いなぁということを実感しました。
```rust
let hoge:String = ~~~
match *&hoge{
    "case1" => {
        ///処理
    }
    "case2" => {
        ///処理
    }
    _ => {
        ///すべて当てはまらない時の処理
    }
}
```

## エラーは起こすものの、シンタックスハイライトがかなり親切
シンタックスハイライト等の内容がかなり詳しく書かれており、特別な導入なく`cargo init`とTomlの記述でライブラリーも認識してくれる点がかなり助かりました。

## 一日使ってみての所感
今回はDiscordAPIというシンプルな用途で使ったのですが、かなり開発体験もよくこれからも勉強して使えるところは使っていきたいなと思えるような言語でした。
[docs.rs](https://docs.rs/)というサイトにライブラリーのドキュメントが大まかに乗っており同じプラットフォーム内で使える点もかなり魅力的な環境に思えてきました。
今回は時間の関係で使えなかったのですが形態素解析のライブラリーもあるみたいなので、そのあたりも使って次はアプリを作れたらなという風に思っております。
 
---
参考資料
https://dev.classmethod.jp/articles/rust-discordbot/
公式のExsamplesも豊富でこちらもぜひ
https://github.com/rust-random/rand/tree/master/examples
アドベントカレンダー作ってみた

[【完走目指す】初心者が25日で強くなる Advent Calendar 2022](https://qiita.com/advent-calendar/2022/aruhitoganbaru)
１1日目の記事です。なんかカレンダーがうまく紐づけられないので、この記事はすぐに消すかもしれません　
追記
書き直して、何とかできました。よかった
# アドベントカレンダー　
クリスマスも近いので、アドベントカレンダーを作ります。　
作るのは普通の、クリスマスまで１日ずつ日付をめくっていくあのアドベントカレンダーです。

# 構想
ざっくりこんな感じに作りたいです。
1.日付を取得
2.その日付までの画像を別のプレゼントに入れ替える。
3.プレゼントの中身が見れてうれしい

# 制作開始　

まずは、画像を２５日分用意します。
画像は自分で用意しました。フリー画像を持ってきてもいいでしょう。
![プレゼント赤.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/07650421-19b1-ae12-54cc-80d48cf405d4.png)
いい感じに並べます。
![スクリーンショット_20221211_015005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/41ad636e-1845-a141-fbb1-339db2c954fb.png)
並びました

次に、プレゼントの中身を考えます。今回はクリスマスにちなんで「シュトーレン」にしました。
一応、画像は自分で作りました。
![シュトーレンの代わり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/00ab5abc-103d-c69e-f414-b78ded545608.png)
今回使う、シュトーレンの代わりです。手抜きです。
# 書く
以下のものを書きました。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AdvCal : MonoBehaviour
{
    public int Day;
    public int Month;
    public GameObject[] Hako;
    public GameObject Warn1;
    public GameObject Warn2;
    // Start is called before the first frame update
    void Start()
    {
        Warn1.SetActive(false);
        Warn2.SetActive(false);
        
    }

    // Update is called once per frame
    void Update()
    {
        Month = DateTime.Now.Month;
        Day = DateTime.Now.Day;
        if (Month == 12)
        {
            if (Day <= 25)
            {
                for (int B = 0; B < Day; B++)
                {
                    Hako[B].SetActive(false);

                }


            }
            else
            {
                Warn1.SetActive(true);

            }

        }
        else
        {
            Warn2.SetActive(true);
        }
    }
}
```
Warn1
![warn1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/16a46153-1df5-9d60-5ad9-65ed93e48a29.png)
とWarn２
![warn2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/7677594c-7314-afd3-b125-010e97dbe19a.png)

の画像を用意しました。
Warn１は１２月で、クリスマスが終わった１２月２６日とかに出ます。
Warn2は、１２月じゃないときに出ます。

# 結果
![スクリーンショット_20221211_021859.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/867d9f44-3145-dec7-6aed-8a0ed307b6f8.png)
（シュトーレン見づらいけど）
##### 一発で動いた！
　　

# まとめ
時間に余裕をもって記事を書こう。
ちなみに、ちゃんと保存できてなかったみたいで一回この記事は消えました。

11日目　終わり
サルにはわからない！SSH接続でリモートのjupyterlabをローカルPCで立ち上げる方法

---
<h4>実行環境</h4>
・リモートマシン-Linux<br>
・ローカルマシン-Windows10<br>

--- 
<h3>①ローカルマシンで秘密鍵、公開鍵を作成</h3>

`ssh-keygen -t rsa -b [ビット長]`というコマンドで任意のビット長のRSA鍵のペアを作成する。前述コマンド入力後、任意のパスワードを入力して生成する。

※RSAよりもED25519の方が堅牢らしいのでそちらの方がよさそう

---

<h3>②リモートマシンに公開鍵を登録</h3>

```./.ssh/id_rsa.pub```の内容をリモートマシンの.sshディレクトリ内の```authorized_keys```内に記述。

---

<h3>③ssh接続</h3>

```ssh [リモートPCのユーザ名]@[リモートPCのIPアドレス]```をローカルPCのコマンドプロンプトから入力後、パスワードを入力するとssh接続が確立される。

---
<h3>④jupyter用パスワードの生成</h3>

以下のようにipythonを起動し、passwd()を利用して任意のパスワードをハッシュ化。

```
ipython

In [2]: from IPython.lib import passwd                                                                                  
In [3]: passwd()  
```

---

<h3>⑤jupyter_notebook_config.pyの設定</h3>

```./.jupyter/jupyter_notebook_config.py```にて以下の行のコメントアウトと設定変更する。

```
c.NotebookApp.allow_remote_access = True 
c.NotebookApp.ip = '0.0.0.0' 
c.NotebookApp.open_browser = False 
c.NotebookApp.password = 'sha1:xxxx' ←生成したパスワード  
c.NotebookApp.port = 9999 
```

---

<h3>⑥リモートマシンのjupyterlab立ち上げ</h3>
ローカルマシンのコマンドプロンプトにて一度ssh接続をlogoutし、
以下のようにポートを指定して再度ssh接続する。

```
ssh [リモートPCのユーザ名]@[リモートPCのIPアドレス] -L 9999:localhost:9999
```
その後ssh接続にてコマンドプロンプトからリモートマシンのjupyterlabを立ち上げる。
```
jupyter lab
```
---
<h3>⑦ローカルマシンでjupyterlab立ち上げ</h3>
ローカルマシンのブラウザにて以下のURLにアクセス。

`http://[ssh接続先のIPアドレス]:9999`

するとパスワードの入力を求められるので、ハッシュ化前のパスワードを入力するとリモートのjupyterlabをローカルPCで操作できる。
和欧混植 font-sizeの微調整

## この記事の概要

Webサイトにおいて、文字の画面占有率は大きい割に、タイポグラフィの甘さったらないですよね。
組版のための仕組みが整っていないなど、仕方ない部分が大きいとは言えもう少し改善したくなります。

というわけで、和欧混植時に少しでも見た目が良くなる方法を考えてみました。

## `@font-face`でフォントを定義して`size-adjust`で調整

Webフォント、ローカルフォント、どちらでも使えるテクニックです。
ローカルフォントを再定義する方法の方が面白い使い方な気がするので、例はそちらをお見せします。

仮に、ヒラギノ角ゴシックとAvenirを混植するとします。
通常の指定方法だとコードはこのようになります。

```css
body {
  font-family: 'Avenir', 'Hiragino Sans', sans-serif;
}
```

`@font-face`を利用すると次のように書き換えられます。

```css
@font-face {
  font-family: 'Custom Avenir';
  src: local('Avenir Light');
  font-weight: 300;
  size-adjust: 106%;
}

@font-face {
  font-family: 'Custom Avenir';
  src: local('Avenir Heavy');
  font-weight: 700;
  size-adjust: 106%;
}

body {
  font-family: 'Custom Avenir', 'Hiragino Sans', sans-serif;
}
```

このとき、次のような見た目の違いが生まれます。
英語が大きくなっているのが分かるでしょうか。
その証拠に、同じ文章なのに改行位置も変わっています。

| 通常の設定 | `@font-face`を利用 |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fcb995a4-9296-c428-1cb7-5a3714044ae2.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/3c3eae5b-e2c8-33e8-6a89-cb03798c416b.png) |

## 解説

`@font-face`はCSSのAt-rulesで、独自のフォントを定義するための記法です。
Webフォントを使うために書かれることが多いですが、今回のようにローカルフォントでも対象にできます。

https://developer.mozilla.org/ja/docs/Web/CSS/@font-face

`size-adjust: 106%;`は、ヒラギノ角ゴシックにあわせるためにAvenirをどれだけ拡大するか、という観点で指定しています。
そのため、フォールバック用にフォントをたくさん指定しているときはそれぞれの組み合わせを検証する必要が出てきます。

:::note alert
なお、`size-adjust`はSafariでは使用できません :cry:
:::

https://developer.mozilla.org/ja/docs/Web/CSS/@font-face/size-adjust

また、`font-weight: 300;`を指定したときは`Avenir Light`を、`font-weight: 700;`を指定したときは`Avenir Heavy`を使う、と宣言して、独自フォントである`Custom Avenir`を指定したときでも通常のフォント指定と変わらない動きを実現しています。

https://developer.mozilla.org/ja/docs/Web/CSS/@font-face/font-weight

## 最後に

Windows用フォントをmacOS用フォントと、組み合わせを考えると例で示したほど簡単には指定できないかもしれません。
しかし、グレイスフルグラデーションというかプログレッシブエンハンスメントというか、そういう観点で指定するのもアリだと思っています。

また、Webフォントを使用している場合であれば組み合わせは考えなくて良いので、意外と現実的な策かもしれません。

いずれにせよ、Webサイトのタイポグラフィがもっと綺麗になってほしいため、何か参考になればと思って投稿しました。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox

Devトークでのお話してくださる方も募集中です！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/489
ある日のssh接続エラー

# はじめに
qnote Advent Calendar 2022 :cat:11日目

エンジニアとして転職時に初めて開発をしたポートフォリオにて、
ローカル環境(cloud9)からAWS上の仮想サーバー(EC2)へssh接続をする際にエラーになってしまった時の簡単な解決までの流れです。


# エラー
```
ssh: connect to host *****(Ip) port 22: Connection timed out
```

（ssh: ホスト ec2-X-X-X-X.compute-1.amazonaws.com ポート 22 への接続: 接続がタイムアウトしました）


数時間前までは普通に接続できており、
特に大きな変更をしていない中突然繋がらなくなりました・・・

# 解決手順
検索をしてみたところ公式でまとめられていました。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-resolve-ssh-connection-errors/

怪しいものは以下２つでした
- セキュリティグループの確認
(AWSにてセキュリティグループが仮想ファイアーウォールとしての機能となっている為)
- サブネットのルートテーブルの設定

それぞれ確認をするも内容自体には問題ないことが発覚。

#### 結論
セキュリティグループをインスタンスへ割り当ての手順（特に変更操作なくても過程をふむ）
「作成〜紐付け〜インスタンス停止→起動」
こちらを行ったところ接続に成功しました。

こんなことで・・・と拍子抜けです。

# 原因
考えられるものとしては、出先で普段使わないインターネット環境から接続を行ったところ今回の事象が起こりました。
→プロバイダーに再接続するたびに利用する[IPアドレス]("https://www.cman.jp/network/support/go_access.cgi")が変わる可能性がある、
とのことです。
今回は手順を通し更新を行ったことで接続が可能となりました。
（インスタンス再起動のみだと更新が上手くできないこともあるようです。）


# まとめ
エラーの際には根本から一つずつ試してみることがとても大切だと学びました。

### 参考記事
- [AWS EC2 に SSH 接続できない・繋がらないときの確認項目]("https://xn--o9j8h1c9hb5756dt0ua226amc1a.com/?p=3583")
- [AWSドキュメント]("https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-resolve-ssh-connection-errors/")
SDL2 のサンプルプログラムを試す



# 環境

- Ubuntu22.04
- Ubuntu20.04

# インストール

さくっと公式パッケージからインストールしました。

```

$ sudo apt-get install libsdl2-dev
$ sudo apt-get install libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libsdl2-ttf-dev

```

# サンプルプログラム

 元ネタはこちら
https://solarianprogrammer.com/2015/01/22/raspberry-pi-raspbian-getting-started-sdl-2/

png ファイルを表示するプログラムです。
今回は、png ファイルは WikiMedia から持ってきました。

https://commons.wikimedia.org/wiki/File:Yes-check-icon-transparent.png
これをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a7ad303c-a791-b965-7579-f0cb11fa40b1.png)

プログラムは元ネタから簡略化して以下のようにしました。

```
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>

SDL_Texture* load_texture(const char* fname, SDL_Renderer *renderer);

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO);
    // 512 x 512 size window
    SDL_Window* window = SDL_CreateWindow("SDL2 TestDraw", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                          512, 512, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    IMG_Init(IMG_INIT_PNG);

    // Clear the window with default color: RGB=(0,30,0)  and Alpha=255
    SDL_SetRenderDrawColor(renderer, 0, 30, 0, 255);
    SDL_RenderClear(renderer);

    // image file load
    SDL_Surface *image = IMG_Load("Yes-check-icon-transparent.png");
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);
    SDL_FreeSurface(image);

    // image show with size
    SDL_Rect dest_rect;
    dest_rect.x = 0; dest_rect.y = 0;
    dest_rect.w = 512; dest_rect.h = 512;
    SDL_RenderCopy(renderer, texture, NULL, &dest_rect);

    // Update window, keep 5 sec and quit 
    SDL_RenderPresent(renderer);
    SDL_Delay(5000);
    SDL_DestroyTexture(texture);
    IMG_Quit();
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

```

コンパイル

元ネタではこのようになってましたが
```
$ g++ -std=c++14 -Wall -pedantic test.cpp -o test `sdl2-config --cflags --libs` -lSDL2_image

```

以下で通りました
```
$ g++ test.cpp -o test -lSDL2  -lSDL2_image

```


実行

```
$ ./test

```
OKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d75c78ea-548a-f5b0-42ce-7ec0a475c332.png)

# Cでコンパイルする

test.c を test.cpp からコピーしてきて、ソースコードの以下の一行を削除
```
#include <iostream>
```

以下でコンパイル

```
$ cc test.c -o test -lSDL2  -lSDL2_image

```
実行
```
$ ./test

```

OKでした!
消えたnpm xmasをもう一度

HRBrain Advent Calendar 2022、25日目の記事です。

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

## はじめに

こんにちは。株式会社HRBrainでエンジニアリングマネージャーをしている山口です。

ついにクリスマスですね。皆様いかがお過ごしでしょうか？

クリスマスチキンは骨があって食べにくいので、今年の我が家は唐揚げでいくことが決定しました。

本記事では、ターミナル上にクリスマスツリーを出力するプログラムを紹介します。

![クリスマスチキンのイラスト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106236/7d781e61-dbce-b940-2886-c5f38527a169.png)

## remove dead code

https://github.com/npm/cli/commit/24d2ec97f220078f14269f0be74b8223cd7179d7

2020年07月29日22時09分01秒、npmからxmasコマンドを削除するコミットが作られました。

このコミットはnpm@7から反映されているため、npm@7以降のnpmではxmasコマンドを使えません。

なるほど。これは死活問題です。

「npm xmasってコマンドがあってさー知ってる？ｗ」という雑談鉄板ネタが言えなくなってしまいました。

## ないんだったら、自分で作ればいいのよ！

![chat.openai.com_chat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106236/90cbd2c5-ce39-6c67-a11b-9ed840431b42.png)

まずChatGPTにお願いしてみましたが、これでも良いけれどコレジャナイ感……

https://github.com/yug1224/xmas

というわけで移植しました。今回は[Deno](https://deno.land/)で動かすことを想定しています。

Deno依存の記述はないので、[ts-node](https://github.com/TypeStrong/ts-node)や[tsx](https://github.com/esbuild-kit/tsx)でも動くと思います。

### インストール

```console
$ deno install --name xmas app.ts
```

インストールの必要はないけれど、コマンドを設定したいのでやっておきます。

`deno install`ではなく`deno compile`だとバイナリファイルが出力されるので、好みで使い分けてもいいかもしれないですね。

### 使い方

```console
$ xmas
```

単純明快で摩訶不思議。`xmas`と入力するだけで美しいツリーが完成します。簡単ですね。

<!-- 
![terminal.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106236/8c0344d3-35cb-6af0-7348-ad75ea192c7e.gif) -->


### npm xmasとの比較

以下にnpm xmasの実行結果と並べてみます。

| npm                       | deno                        |
| ------------------------- | --------------------------- |
| ![npm xmas.png][npm xmas] | ![deno xmas.png][deno xmas] |

[npm xmas]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106236/b83f0b4f-0424-a9ea-06d7-91fc002f10e8.png
[deno xmas]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106236/7d2b8242-315b-8426-744e-46de50fe8707.png

オーナメントの種類・位置・色は毎回ランダムで変わるので、だいたい同じものを出力できました。

良さそうですね。これで今年も無事にクリスマスを迎えられそうです！

## さいごに

HRBrainでは引き続き仲間を募集しております。最新の募集状況などは下記からご確認ください。

https://www.hrbrain.co.jp/recruit
【Snowflake】（小ネタ）クエリやコマンドの結果に対してクエリを投げる

# はじめに
Snowfakeに数多ある便利機能でお気に入りのものを紹介していこうと思います。
今回はクエリやコマンドの結果に対してのクエリ実行です。
他のDBにはなかなかない機能かなと思います。覚えておくと地味に便利です。

# 概要
Snowflakeではクエリの結果やコマンドの結果に対してさらにクエリを投げて結果の絞り込みや編集をすることができる。

# クエリの結果にクエリを投げる
まずは適当にクエリを投げる
```sql
SELECT * FROM INFORMATION_SCHEMA.TABLES;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/27251d75-73c4-2010-d95f-9323da68b805.png)

上記の結果に対してさらにSELECTを実行しようと思います。
前回のquery_idの結果セットを呼び出してそれに対するSELECTを行うため、
FROM句に```FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))```と指定して
SELECTを行います。LAST_QUERY_ID()の部分はquery_id指定でも構いません。

```sql
-- 前回の結果に対してさらにSELECTを実施
SELECT * 
  FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
 WHERE TABLE_OWNER IS NOT NULL;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/3edcc989-da39-4e93-20cd-7ea0be48d319.png)

イメージをつかんでいただくために簡単なSQLを2回に分けて実行した感じになりましたがここからが応用です。

# コマンドの結果にクエリを投げる
通常SQLでは取得ができないもの、例えばパラメータ一覧の結果を出力し、その結果からさらにデフォルトから変更されたパラメータに絞り込む、というのをやってみます。

まずはパラメータ一覧を出力
```sql
-- アカウントレベルのパラメータ一覧の表示
SHOW PARAMETERS IN ACCOUNT;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/6d7ff48e-d7f3-7185-361a-f996671211d5.png)
その後、さらにアカウントレベルかつdefaultから変更されたパラメータに絞り込む
（showコマンドの結果はヘッダが小文字なので項目指定の場合は「"」で囲む必要があります。）
```sql
-- アカウントレベルのパラメータかつdefaultから変更されたパラメータを表示
SELECT * 
  FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) 
 WHERE "value" <> "default"  -- デフォルトから変更されているもの
   AND "level" = 'ACCOUNT';  -- アカウントレベルのパラメータ
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2964512/be197e55-68e0-6d81-3e63-7858e8142533.png)
私のアカウントではタイムゾーン（TIMEZONE）とタイムトラベル期間（DATA_RETENTION_IN_DAYS）をデフォルトから変更していたので想定の通りの結果となりました。

# おわりに
これを利用すれば上記のようにコマンドの結果の絞り込みやCOPY文の結果をサマリした結果を指定テーブルに保存するなど、SQLだけでは実現できなかったことも一部できるようになるので頭の片隅においておけばいつか幸せになれるときが来るかもしれません。どこかの誰かのお役に立つ日が来ればうれしいです。