OmniAICreator/Qiita-1.07M huggingface dataset:
laravel PHPUnitテスト testから始まるメソッド名を記載しているのにNo tests found.のエラーが発生する

## 概要

- テストクラスとテストメソッドを定義し、ファイルを指定してテストを実行したが`INFO  No tests found.`がでてテストが実行されなかった。ちょっとだけ詰まったので解決策を記載する。

## 問題発生までの経緯

- 下記のようなテストコードのメソッドを記載した。当該のテストクラスには下記のメソッドしか存在しない。別のメソッドをそのまま持ってきているのでDocコメント部分にデータプロバイダーの呼び出しなどが記載されたままになっている。

    ```test.php
        /**
         * 正常系
         *
         * make method-test class=tests/Feature/App/Http/Controllers/User/ChangeTypeControllerTest.php method=test_ユーザータイプ更新_正常系
         *
         * @dataProvider validParamsDataProvider
         * @param array<string, string|int> $validParams
         * @return void
         * 
         */
        public function test_ユーザータイプ更新_正常系(/* array $validParams */): void
        {
            dd('');
            $user = User::factory()->createOne(['email' => 'test1@example.com']);
            $requestBody = [
                'userId' => $user->id,
                'userTypeMasterId' => $user->userTypeMasterId,
            ];
        
            $response = $this->sendRequest($this->path, $this->method, $requestBody);
        
            $response->assertStatus(Response::HTTP_OK);
    /*         $this->assertDatabaseHas(
                'users',
                [
                    'email' => $validParams['email'],
                    'name' => $validParams['name'],
                    'user_type_master_id' => $validParams['userTypeMasterId'],
                ]
            ); */
        }
    ```

- 上記のテストメソッドしか記載されていないテストクラスを指定してPHPUnitでテストを実行した。

## 問題発生

- 下記のエラーがでて当該のテストクラスが実行されない。

    ```
    INFO  No tests found.
    ```

## 問題解決までの経緯

- 一つ一つ問題が無いか確認する。
- まずはphp artisan testコマンドで指定しているパスが正しいかを確認した。
    - 特に問題なさそう。
- テストメソッドがテストメソッドとして認識されるようになっているか（`@test`アノテーション付与 or メソッド名をtestで始める）を確認した。
    - 特に問題なさそう。
- 当該のテストメソッドのDocコメントを一旦削除した。
- ↑を実施したところテストメソッドが実行され`dd()`で止まった。

## 原因

- 存在しないデータプロバイダーメソッドをDocコメント内部で呼んでいたためだった。怠慢はよくない。
せんせー、デジタルツインってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、デジタルツインってなに？

# デジタルツインとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

デジタルツインというのは、本物のものと全く同じものをコンピュータの中に作る技術のことです。

君がおもちゃの車や人形で遊んでいるときを想像してみてください。
おもちゃの車や人形は、本物の車や人とよく似ているけど、小さくて手で持つことができますよね。
君が遊びながら、それらのおもちゃを使って色々なことを試すことができるんです。

デジタルツインも同じようなことを、コンピュータの中でやるんです。
本物のビルや橋や車を、コンピュータの中に作り出すんです。
それから、そのデジタルツインを使って、色々なことを試したり、何か問題が起きたときにどうするか考えたりするんです。

これは、本物のものを壊さずに、色々なことを試せるからすごく便利なんです。

# まとめ

デジタルツインというのは、本物のものと全く同じものをコンピュータの中に作る技術のこと
せんせー、生体認証技術ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、生体認証技術ってなに？

# 生体認証技術とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

生体認証技術というのは、自分だけの特別なものを使って、自分だけが使えるようにする技術のことです。

みんなが自分だけの特別なものを持っていること、知ってますか？
たとえば、指紋です。
君の指紋は、君だけの特別な模様があって、誰とも同じにはならないんです。

それと同じで、顔の形や瞳（目）の色、声の音色なども、君だけの特別なものなんです。
これらは、君が君であることを証明する大切なものです。

生体認証技術は、これらの特別なものを使って、自分だけが使えるようにするんです。
例えば、スマートフォンでは、自分の指紋や顔を見せることで、自分だけが電話を使うことができるようになります。
これは、他の人に自分の大切なものを見られないようにするためなんです。

だから、生体認証技術は、とても重要で、特別な技術なんです。

# まとめ

生体認証技術というのは、自分だけの特別なものを使って、自分だけが使えるようにする技術のこと
不等式√(x2+2x-3)<2x+6「2019 東京都市大 工・知識工 1(1)」をChatGPTとWolframAlphaとsympyでやってみたい。

グラフがでます。

オリジナル(PDF) (19 東京都市大 工・知識工 1(1))

https://kamelink.com/public/2019/1.3-19%E6%9D%B1%E4%BA%AC%E9%83%BD%E5%B8%82%E5%A4%A7%E3%83%BB%E5%B7%A5%E3%83%BB%E7%9F%A5%E8%AD%98%E5%B7%A51-1.pdf

＞私(mrrclb48z)のコメントが、あります。

https://kamelink.com/blog/2023/08/04/doutihenkei/#comment-643


上と同じです。大学入試数学問題集成＞テキスト【】()
未登録

# xxxx ChatGPT で(できませんでした。) xxx
入力文
```
不等式√(x2+2x-3)<2x+6 を解け
```
XXXXX ??　条件を満たす解は存在しません。　?? xxxxx

# WolframAlpha で
グラフは,でませんでした。計算だけです。

https://www.wolframalpha.com/input?i=sqrt%28x**2%2B2*x-3%29%3C2*x%2B6&lang=ja

グラフがでます。実数の範囲の定義が不足しています。

https://www.wolframalpha.com/input?i=sqrt%28x**2%2B2*x-3%29%E3%80%80%E3%80%812*x%2B6+&lang=ja

https://kamelink.com/blog/2023/08/04/doutihenkei/#comment-643

# sympyで(数学入試問題 様のやり方で)
・同値変形に挑戦しました。できませんでした。最終行のandがおかしいです。
・sympyで自動的に、print文を発生してほしいです。
```python 
from sympy import *
x=symbols('x',real=True)
my1 =Lt(sqrt(x**2+2*x-3),2*x+6    )           ;print("#",my1 )
print()  
my2A=Lt(my1.lhs**2,my1.rhs**2 )               ;print("#",my2A)  
my2B=Ge(my1.lhs**2,0            )             ;print("#",my2B)  
my2C=Ge(my1.rhs  ,0             )             ;print("#",my2C)
print()  
my3A=Gt((my2A.rhs-my2A.lhs).simplify(),0 )    ;print("#",my3A)  
my3B=my2B                                     ;print("#",my3B)  
my3C=solve(my2C)                              ;print("#",my3C)
print()  
my4A=Gt(factor(my3A.lhs),0 )                  ;print("#",my4A)  
my4B=Ge(factor(my3B.lhs),0 )                  ;print("#",my4B)  
my4C=solve(my2C)                              ;print("#",my4C)
print()  
my5A=solve(my4A)                              ;print("#",my5A)  
my5B=solve(my4B)                              ;print("#",my5B)  
my5C=my4C                                     ;print("#",my5C)
print() 
print("#",my5A and my5B and my5C    )
# sqrt(x**2 + 2*x - 3) < 2*x + 6

# x**2 + 2*x - 3 < (2*x + 6)**2
# x**2 + 2*x - 3 >= 0
# 2*x + 6 >= 0

# 3*x**2 + 22*x + 39 > 0
# x**2 + 2*x - 3 >= 0
# -3 <= x

# (x + 3)*(3*x + 13) > 0
# (x - 1)*(x + 3) >= 0
# -3 <= x

# (-3 < x) | (x < -13/3)
# (1 <= x) | (x <= -3)
# -3 <= x

# -3 <= x　　　？？？？？？？？？？？？？？？？？？？？？？？
```
# sympyで(solveで)
```python
from sympy import *
x=symbols('x',real=True)
myLt=Lt(sqrt(x**2+2*x-3),2*x+6)
print("#",solve(myLt,x))
plot(myLt.lhs,myLt.rhs,(x,-10,10),
     aspect_ratio=(1.0,1.0),xlim=(-10,10),ylim=(-10,10) )
# 1 <= x
```
aspect_ratioを使ってみました。(参考あり)
![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/af2131c0-8eb1-2f35-4794-57d44770c67f.png)

# sympyの実行環境
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# 参考
＞aspect_ratio＜plot

https://docs.sympy.org/latest/modules/plotting.html#plot-class

以下、いつもの?おすすめです。

https://qiita.com/mrrclb48z/items/75904cdc6e84ecef4d03#%E5%8F%82%E8%80%83wolframalpha-%E9%96%8B%E7%99%BA%E7%89%A9%E8%AA%9E
分析結果の共有の際にR Markdownで設定しておくとよいこと

近年、論文を査読に出す際や出版する際に、分析結果の共有を求められることが多いです（というより義務化）。その際、R Markdownに結果をまとめ、HTMLファイルにKnitしているものをよく見ます。先行研究の分析結果を解釈したり、そのコードを参考に何か分析したい場合、「この情報あると助かる～」だったり、「これがないから困るなー」ということを感じることがあります。そこで、個人的にR Markdownに含めるとよいなという設定を紹介します。

# R、OS、パッケージの情報を公開
これは公開すべき必要最低限の情報だと思います。これがないと、使われている関数をググってインストールすべきパッケージを探さないといけないので面倒です。

```R
sessionInfo()
```

ちなみにパッケージの引用文献も表示できます（アルファベット順ではないですが）。ここまでしなくても良いと思いますが、僕は最後に入れるようにしています。こちらの記事でやり方を紹介しています ([パッケージの引用リスト作成](https://qiita.com/masato-terai/items/36e4489e03420915077d))。

# 処理にかかった時間
これがないと、処理にかかる時間が分からず、その分析を再現したい人たちはおそらくとても困ります。すべての処理について表示する必要はありませんが、時間のかかる分析などの場合は、入れるほうが良いと思います。使う関数は、tic()とtoc()で、二つの関数で挟んだ間の処理時間が表示されます[1]。

```R
#install.packages("tictoc")
library(tictoc)

tic() #測定開始
for(i in 1:100){
  print(i)}
toc() #測定修了
```
結果の表示。
```
1.43 sec elapsed
```

# コア数
最近ではパソコンの物理コアと論理コアを載せている研究を見るようになりました。上記の処理時間は、パソコンのスペックによって変わる場合がほとんどですので、「このパソコンなら○○くらいかも」という、より詳細な処理時間の予測ができます。RのdetectCores関数で簡単に表示できます[2]。
```R
library(parallel) #最初から入っているパッケージなので、インストールの必要なし
detectCores() # 論理コア
detectCores(logical = FALSE) #物理コア
```

# おまけ
## コードの表示/非表示をボタンで行う
全コードを表示すると、ファイルが長くて見にくい場合があります。この場合、読み手が見たいコードだけを見れるように、ボタンで表示を切り替えるとよいなと思います。YAMLヘッダーに以下の設定をすればOKです[3]。

```YAML
title: "Untitled"
author: "Demo"
date: "2023/8/5"
output: 
  html_document:
    code_folding: hide # これ！
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344524/fbb8242f-7be6-599a-57ea-c38cab46697d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344524/f95db035-4fcb-87e9-d44e-b12fdff98fe4.png)


すべて表示した状態も以下の設定で可能です。
```
code_folding: show   #すべてを表示した状態
```

# 参考文献
[1] [Rコードの実行時間を測るのに便利です「tictoc」パッケージ](https://qiita.com/hoxo_m/items/75496e4178e0f043ee8f)
[2] [R の parallel パッケージを使用して並列計算を行う方法](https://stats.biopapyrus.jp/r/devel/parallel.html)
[3] [R Markdown でコードの折り畳みをチャンクごとに選択可能にした (rmarkdown 1.15)](https://blog.atusy.net/2019/07/24/rmd-1-15-gh/)
【ChatGPT無】故意に嘘吐きさせますw

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　どうも、カーブミラーです。

　今回は、
　　故意に嘘吐きさせますw

　ChatGPTさんが
　　知らないであろう
　　　造語を与えて、
　　　　その嘘吐きを
　　　　　楽しみたいと思います。

```Text:嘘吐きその１
User
スマホ熱中症とは？


ChatGPT
スマホ熱中症は、スマートフォンを長時間使用したり、過度に依存することによって引き起こされる健康上の問題を指します。主な症状には、頭痛、めまい、吐き気、目の疲れ、手や指のしびれ、肩や首の痛みなどがあります。また、長時間スマートフォンを使用することによって、睡眠不足や社交的な問題も発生することがあります。

スマホ熱中症を予防するためには、適度な時間のスマートフォンの使用を心掛け、定期的に目を休めたり、姿勢を正したりすることが重要です。さらに、スマートフォンの使用時間を制限し、適切な休息をとることで、健康リスクを軽減することができます。
```
　はい、ウソですw

　正解は、
　　スマホ自体が
　　　充電などで熱を持つことです。

　今このときも
　　手の中のスマホが
　　　熱いですw


```Text:嘘吐きその２
User
次の話題です。
ペットボトル症候群とは？


ChatGPT
ペットボトル症候群（ペットボトル症候群）は、長時間にわたってペットボトルなどのプラスチック容器を口に含むことによって引き起こされる健康上の問題を指します。この症状は、特に子供や若い人々に見られることがあります。

ペットボトル症候群の主な症状には、舌の痛みや炎症、口内炎、歯の感覚異常、口の周りの皮膚のかぶれなどが含まれます。これは、プラスチック容器に含まれる化学物質が口腔内に漏れ出して、口や舌の組織に刺激を与えることによって起こる可能性があります。

ペットボトル症候群を予防するためには、ペットボトルを口に含む習慣を避け、飲み物を飲む際は適切なコップを使用するように心掛けることが重要です。また、口の中に異常を感じた場合は、早めに歯科医や医師に相談して適切な対処をすることが大切です。
```
　はい、ウソですw

　正解は、
　　医学的には
　　　「清涼飲料水ケトーシス」

>糖尿病の自覚のない人が糖尿病の症状のひとつである「喉の渇き」のため、砂糖が入ったペットボトル入りの飲料を多飲していたためにつけられた造語です。 ペットボトル入りの飲料すべてが原因になるわけではありません。

[一般社団法人全国清涼飲料連合会](http://www.j-sda.or.jp/)
　から、引用させて
　　いただきました。
***
　ほかの造語も
　　用意していましたけど、
　　　今回は、これにて御仕舞。

　また、「故意に嘘吐き」
　　やりたいと思います。

　では。
bootstrapだけでdiv内の要素を上下左右中央に寄せる

# 結論
中央に寄せたい要素の親となるdivの要素に対して、class属性に`d-flex align-items-center justify-content-center`をもたせれば上下左右を中央に寄せることができます。

# バージョン
bootstrap 4.4.1

# サンプルコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PoxLQoM" data-user="kabuto64425" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabuto64425/pen/PoxLQoM">
  Untitled</a> by kabuto64425 (<a href="https://codepen.io/kabuto64425">@kabuto64425</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

以上です。

# 参考

https://getbootstrap.jp/docs/4.2/utilities/flex/
リモートワークにおすすめガジェット

# はじめに

こんにちは、都内でソフトウェアエンジニアをしている[YSasago](https://qiita.com/YSasago)です。最近、弊社ではリモートワーク推奨になり、自宅でリモートワークすることが多くなりました。リモートワークの初期はデスクを用意するところから始まり、その準備には結構な費用がかかりました。今日は、リモートワーク歴2年の私が、購入して良かったと感じるガジェットを紹介したいと思います。基本的には一つ1万円程度で購入可能なものをピックアップしました。（ただし、消費税や送料は含めません）

## デスク（合計約1万円）

リモートワークが始まった時、最初に私が購入したのは自宅で作業するためのデスクです。このデスクはニトリで揃えました。天板と脚を合わせて約1万円と、非常にコストパフォーマンスに優れたセットです。コストパフォーマンスに魅かれて購入したのですが、しっかりとした作りで大満足しています。私は昇降式の脚を選びましたが、実際にはあまり昇降させることはないので、昇降しない脚でも良かったと感じています。

- [天板（プレフェ 100 MBR）](https://www.nitori-net.jp/ec/product/6240102s/): 4,000円
- [昇降脚2本入り（プレフェ 69BK）](https://www.nitori-net.jp/ec/product/6240421s/?rc=set): 3,000円　x 2

椅子については、ニトリの[ワークチェア クエト BK](https://www.nitori-net.jp/ec/product/6620524-230625774900o/)を使っています。長時間座ることを考慮し、少し高めのものを選びました。ただし、椅子は個々の体型や好みによる部分が大きいので、自分自身で試座して選ぶことをお勧めします。

https://www.nitori-net.jp/ec/product/6240102s/

https://www.nitori-net.jp/ec/product/6240421s/?rc=set

## モニター（約1万5千円）

自宅ではMacをクラムシェルモードで使用し、[IODATAの23.8インチモニター](https://www.amazon.co.jp/gp/product/B077YFRCTF/ref=ppx_od_dt_b_asin_title_s00?ie=UTF8&th=1)を二つ繋げて作業を行っています。ニトリで購入した天板にこのモニターを置いて使っているのですが、大きすぎず小さすぎずのちょうど良いサイズ感が気に入っています。AmazonのPrimeDayやセールを利用すれば、約1万5千円程度で購入可能です。

:::note info
購入時にはディスプレイアームを取り付けたかったため、VESA対応のものを選びました。
:::

https://www.amazon.co.jp/gp/product/B077YFRCTF/ref=ppx_od_dt_b_asin_title_s00?ie=UTF8&th=1

## モニター掛け式ライト（2千5百円程度）

モニターに[モニター掛け式ライト](https://www.amazon.co.jp/gp/product/B08C5GFBP3/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)を取り付けています。このライトは購入して大正解だった一品で、モニター前を明るく照らしつつ、目への負担も軽減してくれます。

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


## HDMI 切替器（千円程度）

自宅での作業では、自宅用のMacと会社用のMacを一つのモニターにつなげて使用しています。そのため、Macを切り替えるたびにHDMIの抜き差しをする手間があったのですが、[HDMI切替器](https://www.amazon.co.jp/gp/product/B07BDF6DBV/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1)の導入により、ボタン一つで簡単に切り替えが可能になりました。

https://www.amazon.co.jp/gp/product/B07BDF6DBV/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1

## 勉強タイマー（千円程度）

自宅での学習時には、時間の管理をしっかり行いたいと考え、[勉強タイマー](https://www.amazon.co.jp/gp/product/B07YLQCW27/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1)を購入しました。スマホにもタイマー機能はありますが、スマホを見てしまうと集中が途切れてしまうため、この勉強タイマーで時間を管理しています。私は、毎日６０分勉強すると目標を立てており、タイマー式勉強法で活用しています。

https://www.amazon.co.jp/gp/product/B07YLQCW27/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1

# おわりに

リモートワークにおすすめのガジェットを紹介しました。
まだまだ紹介したいガジェットは沢山ありますので、追々追加していきたいと思います。
皆様からのおすすめガジェットも大歓迎です。
最後まで読んでいただき、ありがとうございました。
Let's Encrypt Expiry Bot は迷惑メールではなかった、、、

2ヶ月前から
Let's Encrypt Expiry Bot　
というメールが届いていましたが、英語文で怪しさ満点だったので放置。

最近徐々に増えていき1日に３件も届くよになり流石に気になる調べてみることに、、、、

するとSSL証明書の更新期限の通知、慌てて調べ更新するハメに

今回は簡単にですが更新手順をメモしておきます。

まずは有効期限の確認から
```
certbot certificates
```
コマンドを入力すると権限がないとエラーが出ました。
なので頭にsudoをつけ再度試したらうまくいきました。
```
sudo certbot certificates
```
期限間近のものがあり、期限切れのものありました。

確認が出来たので更新してみます。
```
sudo certbot renew -dry-run
```
renew　が更新のコマンド　
-dry-run はテストコマンドらしいです。

ここでまたもエラー、
```
Currently, the renew verb is capable of either renewing all installed certificates that are due to be renewed or renewing a single certificate specified by its name. If you would like to renew specific certificates by their domains, use the certonly command instead. The renew verb may provide other options for selecting certificates to renew in the future.
```
ちゃんとsoduを入れたのにと思いつつ調べると
certonlyのコマンドも使えるというもの
、、
、、、
よく分からないですが、更新出来なくもないよと解釈！

-dry-runのコマンドを無くして再度実行したら更新成功しました。

更新期限が８９日に

今回は思ったよりスムーズにいけました。

ただ、解決したのに分からない事が増えて改めんて終わりなき勉強が必要だと実感し、怪しいメールでも一度調べることを心掛けようと思いました、、、

練習中無駄にSSL証明書を作成してたみたいなので時間がある時にでも削除の方法を調べようと思いました。
DataFrameを1行ずつ取得して再度DataFrameに戻す方法とSeries型の回避

## 概要
この記事では、Pandasを使用してDataFrameから1行ずつデータを取得し、それを再度DataFrameに戻す方法と、Series型になってしまう場合の回避方法について紹介します。DataFrameを1行ずつ処理する際にSeries型に注意が必要ですが、簡単なコード例を通じて解決策を説明します。

## 問題

DataFrameをiterrows()を使って1行ずつ取得しようとしたところ、各行がSeries型として取得されてしまいました。以下はコード例です。

```python
import pandas as pd

data = {
    "No.": [1, 2, 3],
    "番号": ["test1", "test2", "test3"],
    "名前": ["name1", "name2", "name3"]
}
df = pd.DataFrame(data)

for _, row in df.iterrows():
    print(row)
```
上記のコードでは、row 変数には各行がSeries型として取得されるため、データのアクセスがやや複雑になります。

## 解決策

Series型の発生を避ける方法として、取得した行データを辞書に変換してから再度DataFrameに変換する方法があります。以下がそのコード例です。

```python
import pandas as pd

data = {
    "No.": [1, 2, 3],
    "番号": ["test1", "test2", "test3"],
    "名前": ["name1", "name2", "name3"]
}
df = pd.DataFrame(data)

for i, row in enumerate(df.iterrows()):
    _, row_data = row
    
    # 行データを辞書に変換
    row_dict = row_data.to_dict()
    
    # 辞書をDataFrameに変換
    row_df = pd.DataFrame(row_dict, index=[i])
    
    # 処理した行データを表示
    print(f"Processed Row {i + 1}:\n{row_df}\n")
```
この方法により、Series型の発生を回避しつつ、DataFrameとして扱いやすい形に行データを変換することができます。

## 終わりに
何かうまく行かないときは、焦らずに今使っている技術の仕組みを改めて確認し直すことが大切だと思いました。
chromium系ブラウザをアップデートしたら、IndexedDBでめっちゃブロックが発生するようになって困った

開発中のウェブサービスで、ある時から、フリーズしたと思うくらい固まってしまう事案が発生。

Chromiumのコンソールを見ると、フロントエンドのストレージとして使ってるPouchDBの、destroyメソッドで止まっている模様。

エラーログを見てもブロックされている理由がよくわからないので、PouchDBのdestroyメソッドを使うのをやめて、IndexedDBを直に操作する方式に変えて、deleteDBに変更してみる。

しかーし、変えてみたけど、これもいっこうに非同期処理が返ってこない。

ブロックされる時間を計るために、ログにDateを仕込んで計測してみると、だいたい3分〜10分くらい。
不思議なのは10分以上にはならない。

いろいろ試してみたものの、今の所解決する方法がさっぱりわからない。

現在は回避策として、おとなしくuserAgentでlinuxを判別して、PouchDBを使ってdestroyメソッドは使わずIndexedDBのオブジェクトストア自体を消さずに、bulk updateでドキュメントをdeleteする処理に変更しました。これだとdeleteフラグが着いただけで、スッキリしないっちゃスッキリしない。

ですがlinux版は、このサービスのターゲットユーザーにはほぼいないと想定されるから、今の所はいいんじゃないでしょうか。

ちなみに、linux版以外のChromiumではこの箇所でブロックが発生しない模様。

追記 23.08.23
数日前ついにWindowsでも発生した模様。
しかーし、ある呪文を唱えることによって、解決したっぽい模様。

追記 23.09.27
~~ある呪文でその後ブロックが全然発生しなくなっているのと、なんだか意外とアクセス数があったので、これだけで結構な時間を費やしたけど呪文公開。~~

~~呪文というか、setTimeoutでdestroyにあたる処理をasyncで囲ったら、ブロックが発生しなくなりました。~~

追記 23.11.6
この方法でもブロック発生しているので、destroyやめました。
せんせー、炭素捕捉技術ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、炭素捕捉技術ってなに？

# 炭素捕捉技術とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

炭素捕捉技術というのは、空気から「炭素」というものを取って、地球を守る特別な技術のことです。

たとえば、君が部屋で遊んでいるとき、
部屋がちょっと汚れてきたら、掃除機でゴミを吸い取りますよね。
それと同じように、炭素捕捉技術は、大気中から「炭素」
っていう見えないゴミを吸い取る掃除機のようなものなんです。

なぜ炭素を吸い取るのかというと、この炭素が空気中にたくさんあると、地球がどんどん温かくなってしまうんです。
これが「地球温暖化」っていう問題なんです。

だから、私たちは特別な機械を使って、大気中の炭素を吸い取り、
安全な場所に保存するか、または有用な物質に変えるんです。これが炭素捕捉技術の基本的な考え方です。

でも、この技術はとても難しいし、まだまだ改善の余地があるから、
君が大きくなったら、もっと進化した技術があるかもしれですね。

# まとめ

炭素捕捉技術というのは、空気から「炭素」というものを取って、地球を守る特別な技術のこと
日本語配列 Kinesis Advantage2【赤軸静音】がサイコウ超な話

:warning: ***Qiitaの会員数はついに100万人を突破の記事投稿キャンペーン「100万人に届けたい！私のお気に入りガジェット」への参加投稿です。***

# はじめに
おすすめのガジェットは、表題通り ***「Kinesis Advantage2【赤軸静音】」*** です！

https://www.ergonomics.co.jp/shopdetail/000000000001/

形を見ると普通とは違うキーボードでこんなんが使いやすい訳ないと思うでしょう:grin:
魅力をお伝えします！

# どこがいいの:heart_eyes:
- 人間工学に基づいているので、手を乗せたときのしっくり感がすごい！！
　さすが、エルゴノミクスキーボード（笑）
- かなりの頻度で使用するキーがキーボードの真ん中にあり、親指でタイプできる！！
　「Enter」、「Delete」、「Back Space」、「Space」が真ん中に配置されています。
　普通のキーボードだとこれらのキーは右端にあることが多いでしょう！（Spaceキーは真ん中か:sweat_smile:）
　右端にあるがゆえに右手の小指でタイプするでしょう。
　EnterキーとBack Spaceキーは普段めちゃめちゃ使用しますよね？？
　小指が痛くなっている人、多くないですか？？？
　指の中で最も耐久性があるのが親指らしいです。そう！、耐久性のある親指で高頻度に使用するキーをタイプするので指が痛くなりにくいのです:ok_hand:！
　もっと言うと、腱鞘炎になりにくいらしいです:laughing:。
　私は、普通のキーボードでも腱鞘炎になったことがないので実感はないですが・・・（笑）
- キー配置を自在に入れ替えられる！！
　あらゆるキーの位置を入れ替えたりすることができます！
　エンジニアの方は自分好みに合わせたいという願望からカスタマイズ性を重視する方多いのではないでしょか？？
　:point_right: **できちゃうです！**
　私は、「カタカナ　ひらがな　ローマ字」を「HOME」と入れ替え、「変換」を「End」と入れ替えています。
　行の先頭、行末への移動がサクサクできて助かっています:bear:
- 静音赤軸でリニアなタイプでありながら、静かな操作性！

# ちょっと足りない点:no_good_tone1:
- 「~」キーがタイプしづらい
　「~」キーは仮想レイヤーにあるため、「Keypad」キーでレイヤーを切り替えて「Shift」キーと「\」キーを押すとう感じ。３つのキーを押さないといけない:cloud:　面倒くさい:sweat_drops:
- 普通のキーボードとキー配置が全然違うので、慣れるまで誤タイプが半端ない

# 総じて
エンジニアとして見たときに、いい点がかなり使いやすいのでサイコウ超です:heart_eyes:
他にマクロ機能があったりとかなり利便性が良いキーボードです。
マクロ機能等は使用したことないので、何か機会を見つけて試してみたいなと思います。
√(5-2x)-x+2=0「2016福島大学前期理工【１】(1)」をChatGPTとWolframAlphaとsympyでやってみたい。

グラフがでます。

オリジナル

https://kamelink.com/blog/2023/07/31/1-2-16-hukusimadai-rikou-1-1/

上と同じです。大学入試数学問題集成＞テキスト【１】(1)

https://mathexamtest.web.fc2.com/2016/201610141/2016101410100mj.html#top-0117

# xxxx ChatGPT で(できませんでした。) xxx
入力文
```
次の方程式を解きなさい。√(5-2x)-x+2=0
```
XXXXX ??x=1/2?? xxxxx

# WolframAlpha で
グラフがでます。曲線1本です。

https://www.wolframalpha.com/input?i=%E2%88%9A%285-2x%29-x%2B2%3D0&lang=ja

グラフがでます。曲線1本と直線1本です。

https://www.wolframalpha.com/input?i=%E2%88%9A%285-2x%29%2Cx%2B2+%E3%81%AE%E4%BA%A4%E7%82%B9&lang=ja

# sympyで(数学入試問題 様のやり方で)
・同値変形に挑戦しました。無理矢理感があります。
・sqrtとsqrtじゃないと、判別するいい方法がありますか？
```python
from sympy import *
x=symbols('x',real=True)
myEq1 =Eq(sqrt(5-2*x)-x+2,0            )    ;print("#",myEq1 )
myEq2 =Eq(sqrt(5-2*x)    ,x-2          )    ;print("#",myEq2 )
myEq3A=Eq(myEq2.lhs**2   ,myEq2.rhs**2 )    ;print("#",myEq3A)
myEq3B=Ge(myEq2.rhs      ,0            )    ;print("#",myEq3B)
myEq4 =solve([myEq3A,myEq3B],x         )    ;print("#",myEq4 )
# Eq(-x + sqrt(5 - 2*x) + 2, 0)
# Eq(sqrt(5 - 2*x), x - 2)
# Eq(5 - 2*x, (x - 2)**2)
# x - 2 >= 0
# Eq(x, 1 + sqrt(2))
```
# sympyで(solveで)
```python
from sympy import *
x=symbols('x',real=True)
y=sqrt(5-2*x)-x+2
print("#",solve(y,x)[0])
plot(y,
     aspect_ratio=(1.0,1.0),xlim=(-10,10),ylim=(-4,10))
plot(sqrt(5-2*x),x-2,
     aspect_ratio=(1.0,1.0),xlim=(-10,10),ylim=(-4,10))
# 1 + sqrt(2)
```
aspect_ratioを使ってみました。(参考あり)

グラフより、解は2.5より、ちょっと小さいです。

![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/389de575-d156-1697-faf5-8864e294dfb3.png)

グラフより、解は2.5より、ちょっと小さいです。
sqrtとsqrtじゃない。曲線と直線の交点です。

![1png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/3efbcf66-ee6a-8ceb-fdbd-d216d37b7783.png)

# sympyの実行環境
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# 参考
＞aspect_ratio＜plot

https://docs.sympy.org/latest/modules/plotting.html#plot-class

以下、いつもの?おすすめです。

https://qiita.com/mrrclb48z/items/75904cdc6e84ecef4d03#%E5%8F%82%E8%80%83wolframalpha-%E9%96%8B%E7%99%BA%E7%89%A9%E8%AA%9E
Salesforceでレポート作成をしよう～テキスト項目も相対的にレポート絞り込み条件を設定する方法

こんにちは
本橋孝昭です

今回はSalesforceのレポートの絞り込み条件でテキスト型項目でも相対的に絞り込める方法について解説します


# 前提の知識（日付項目の相対日付検索条件）

項目「日付型」ではレポートの絞り込み条件で「今日」「今月」と絞り込めば

※今月　設定の場合
2023年8月１日なら「2023年8月」として
2023年9月１日なら「2023年9月」として自動的にレポートの検索条件が変わります

![aa001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a21a3505-ba43-3a3e-e096-449c782fd2a9.png)


相対日付を設定すればレポートの検索条件をいちいち変えなくていいのでとても楽です

相対日付の種類については下記ヘルプをご確認ください

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

# 相対日付検索条件の弱点

相対日付検索条件はとても便利な設定ですが弱点は「項目型はテキスト型の場合などは対応できない」ことです

例えばテキスト項目で
・2023年8月
・2023年9月
と入力された項目があった場合

2023年8月１日なら「2023年8月」として
2023年9月１日なら「2023年9月」として自動的にレポートの検索条件が変わればいいのですが、これは相対日付検索条件では対応されていません


# テキスト型でも相対日付検索条件に設定する回避策

回避策として行レベルの数式列を作成します

「前提」
・項目型　テキスト　の項目がありAPI名YearMonth__c
・YearMonth__c　項目には
・2023年8月
・2023年9月
と入力されていてその年月ごとのレコードを相対的に表示したい

「解決策」
以下の数式をレポート内に作成する

IF(Opportunity.YearMonth__c=TEXT(YEAR(TODAY()))&"年"&TEXT(MONTH(TODAY()))&"月","TRUE","FALSE")

![aa002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5ddedbbc-d39d-b7ae-ef8e-d96a1758a2de.png)



この数式は2023年8月時点で
・2023年8月　ならTRUER
・2023年9月　ならFALSE
なのでこの行レベルの数式項目を元にレポートの絞り込みを行う

![aa003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/731ce93c-2fbc-1327-1a4c-137822df48f7.png)



これによりテキスト型の項目でも相対日付のように「今月のみのデータ」を絞り込み可能です


# おまけ
今回はレポートの行レベルの数式を作成する方法にしましたが、もちろんオブジェクトでカスタム項目を作成しそれをレポートで絞り込むことも可能です
また、今回はテキスト項目型をそのまま使用しましたが、テキスト項目型は入力の表記ゆれが起こる場合もあり、きちんと入力されていないともちろんレポートできちんと絞り込みができません

そういう意味では、項目型をテキストから日付に変更することが長期的な解決策になりそうですね

今回はあくまで短期的な解決策として見ていただければと思います
CloudWatch LogsからKinesisにアクセスするためのIAMロールを作成したい

## 前書き
今回は、リアルタイムでログをS3に保管するために
CloudWatch Logs　→　Kinesis Data Firehose →　S3
というよくあるアーキテクチャ構成でシステムを実装しようとしていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/df94c224-97b8-7651-8671-ee360587e3e3.png)

初めてKinesisが触れるぞ！とウキウキしていました


## 実践

https://www.aws-room.com/entry/log-kinesis-to-s3

こちらの記事を参考に構築を進めていました。
めちゃくちゃわかりやすかったです。ありがとうございます。

少しややこしかったのが、掲題している「CloudWatch LogsからKinesisにアクセスするためのIAMロール」の作り方です。

上記ブログには以下のように書いてありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/2467911b-b49a-8ffc-4e3b-a3b6e7cee5de.png)

↓上記画像の「こちら」のリンク先

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-using-import-tool-cli-cloudwatch-iam-role.html

結論から言うと、マネコンからロールを作る際にCloudWatch Logsを「信頼されたエンティティ」として選択できないため、一旦適当にエンティティを選択してロールを作成した後、「信頼されたエンティティ」を設定しているJSONを書き換えることでCloudWatch Logs用のロールを作成する、という手順が必要になります。

この時点で言っていることが理解できた方はこの先の記事は読まなくても大丈夫です。
筆者は公式サイトを見てもすぐには理解できなかったので、作業証跡を記事として残しておきたいと思います。

リンク先はCognitoの話をしているんじゃないか？という疑念も上記リンクの内容を理解する妨げになったのですが、おそらくcognitoは関係ないです。


## CloudWatch LogsからKinesisにアクセスするためのIAMロールを作成

いきなり難所が来ます。
ロール作成時の最初の画面でCloudWatch Logs信頼されたエンティティとしてCloudWatch Logsを選択できればいいのですが選択できないので、一旦EC2を選択します。
（ここではEC2としていますが、何を選択しても問題ありません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/a03f9111-a7d8-b2b8-4098-fff451cc2850.png)

続いてステップ2の許可を追加画面では「AmazonKinesisFirehoseFullAccess」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/a3ab07ee-01dc-6bfc-2140-91d1da17cc1e.png)

最後にステップ3の名前、確認、および作成画面では信頼されたエンティティの箇所を編集したい気持ちをぐっとこらえて、一旦ロールを作成してしまいましょう。
ここで編集を押してしまうと、JSONを編集できるわけではなくステップ1の画面に戻されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/4ba82540-aa08-9d14-b310-5280cb6d59fa.png)

一旦ロールを作成してから、当該ロールを選択し、信頼ポリシーを編集していきます。
記述するポリシーの内容は以下の通りです。
リージョンは適宜変更してください。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logs.ap-northeast-1.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

これでロールの作成が完了しました

## まとめ
なぜマネコンからはCloudWatch Logsを信頼されたエンティティとして選択できないのかは謎のままでした。情報求む。

また、構築の手順を記している参考になる記事をいくつか探していたのですが、すべてAWS CLIを用いて構築している記事も見かけました。そちらの方では何の問題もなくロールが作成できていました。最近LinuxやKubernetesの勉強をしており、コマンドを巧みに操るエンジニアへの憧れが日に日に強くなっているので、AWS CLIにも手を出そうかなと思いました。


## 投稿後追記
社内のAWSと言えばこの人！という先輩から「カスタム信頼ポリシーを使えば一撃で作れるよ」というアドバイスをいただきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661124/24fd1381-495f-d6c4-6e56-00595b176535.png)

めちゃくちゃ簡単だった......

今回は間違いを投稿したわけではないですが、遠回りになる方法を投稿したおかげでより近道のルートを教えていただくことができました。カニンガムの法則ですね。ありがとうございます！

ちなみに、なぜAWSのサービスとして対応していないのかを尋ねたところ、「推測だが、あまりニーズがないのではないか。もしAWSのサポートに要望が出されれば実装される可能性がある。」という旨の回答をいただきました。AWSはまだまだ枯れた技術になっておらず、日進月歩で改善されているのだろうな、と思いました。
wslでelixir その36

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
websocket serverでnasaの apiを叩いて、今日の画像の urlを返せ。
portは、50002
clientは、neosvr

# 方針

- socket使う
- jason使う

# 写真

![2023-08-05 02.17.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/922fc46c-93af-5cfa-6ac6-a73f0b105818.jpeg)

# サンプルコード

```
defmodule Nasa.Server do
	alias ElixirSocketTesting.ClientAgent
	def start(port \\ 50002) do
		ClientAgent.start_link
		server = Socket.Web.listen! port
		loop(server)
	end
	def loop(server) do
		client = server
			|> Socket.Web.accept!
		client
		|> Socket.Web.accept!
		ClientAgent.add(client)
		Task.async(fn ->
			recv(client)
		end)
		loop(server)
	end
	def nasa() do
		{:ok, {_status, _headers, body}} = :httpc.request('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
		body
		|> Jason.decode!()
		|> Map.get("url")
	end
	def recv(client) do
		case client |> Socket.Web.recv! do
		{:text, message} ->
			res = nasa()
			broadcast({:text, res})
			recv(client)
		{:close, _, _} ->
			ClientAgent.remove(client)
		other ->
			IO.inspect other
		end
	end
	def broadcast(packet) do
		ClientAgent.all
		|> Enum.each(fn client ->
			Socket.Web.send(client, packet)
		end)
	end
end





```

以上。
【React（Typescript）】マウスの動きに合わせて回転する風車コンポーネント

# 作るもの
![見本.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/c83e7ed9-2f7c-0eae-4972-6f4cfb29c211.gif)

# 実装
- プロジェクトの雛形作成
```bash:terminal
npx create-react-app rotating-windmill　--template typescript
```

- srcディレクトリ配下に、以下のファイルを作成する。
・RotatingWindmill.tsx
・RotatingWindmill.css

```tsx:RotatingWindmill.tsx
import React, { useState, useEffect } from 'react';

const RotatingWindmill: React.FC = () => {
  const [rotationAngle, setRotationAngle] = useState(0);

  const handleMouseMove = (event: MouseEvent) => {
    // カーソルの位置に基づいて回転角度を計算
    const { clientX, clientY } = event;
    const centerX = window.innerWidth / 2;
    const centerY = window.innerHeight / 2;
    const radians = Math.atan2(clientY - centerY, clientX - centerX);
    const degrees = (radians * 180) / Math.PI;
    setRotationAngle(degrees);
  };

  useEffect(() => {
    // マウント時にイベントリスナーを追加
    window.addEventListener('mousemove', handleMouseMove);

    // アンマウント時にイベントリスナーを削除
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
    };
  }, []);

  return (
    <div className="windmill">
      <div className="blades" style={{ transform: `rotate(${rotationAngle}deg)` }}>
        <div className="blade" />
        <div className="blade" />
        <div className="blade" />
      </div>
    </div>
  );
};

export default RotatingWindmill;

```

```css:RotatingWindmill.css
.windmill {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: #f0f0f0;
  border-radius: 50%;
  overflow: hidden;
}

.blades {
  position: absolute;
  width: 100%;
  height: 100%;
}

.blade {
  position: absolute;
  top: 0;
  left: 50%;
  width: 10px;
  height: 100px;
  background-color: #333;
  transform-origin: 50% 100%;
}

.blade:nth-child(1) {
  transform: rotate(0deg);
}

.blade:nth-child(2) {
  transform: rotate(120deg);
}

.blade:nth-child(3) {
  transform: rotate(240deg);
}

```

- App.tsxを以下のように書き換える。
```tsx:App.tsx
import React from 'react';
import RotatingWindmill from './RotatingWindmill';
import './App.css';
import './RotatingWindmill.css';

const App: React.FC = () => {
  return (
    <div className="app">
      <RotatingWindmill />
    </div>
  );
};

export default App;
    
```

- 動作確認
```bash:terminal
npm start
```
[http://localhost:3000](#http://localhost:3000)にアクセスすると、冒頭の風車のコンポーネントが表示される。
wslでelixir その35

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
websocket serverでshellを返せ。
portは、50002
clientは、neosvr

# 写真

![2023-08-04 23.23.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/47b945d1-566a-50b5-b5e9-330c022d6a92.jpeg)

# サンプルコード

```
defmodule Shell.Server do
	alias ElixirSocketTesting.ClientAgent
	def start(port \\ 50002) do
		ClientAgent.start_link
		server = Socket.Web.listen! port
		loop(server)
	end
	def loop(server) do
		client = server
			|> Socket.Web.accept!
		client
		|> Socket.Web.accept!
		ClientAgent.add(client)
		Task.async(fn ->
			recv(client)
		end)
		loop(server)
	end
	def recv(client) do
		case client |> Socket.Web.recv! do
		{:text, message} ->
			{res, 0} = System.shell(message)
			broadcast({:text, res})
			recv(client)
		{:close, _, _} ->
			ClientAgent.remove(client)
		other ->
			IO.inspect other
		end
	end
	def broadcast(packet) do
		ClientAgent.all
		|> Enum.each(fn client ->
			Socket.Web.send(client, packet)
		end)
	end
end


```

以上。
wslでelixir その34

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
websocket serverでforthインタープリターを返せ。
portは、50002
clientは、neosvr

# 写真

![2023-08-04 23.07.15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/76c59c99-f434-4672-83b8-5d31252d8220.jpeg)

# サンプルコード

```
defmodule Forth do
	def start_link do
		Agent.start_link(fn ->
			[]
		end, name: __MODULE__)
	end
	def add do
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 2
			top = List.last(stack)
			stack = List.update_at(stack, po, &(&1 + top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def sub do
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 2
			top = List.last(stack)
			stack = List.update_at(stack, po, &(&1 - top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def mul do
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 2
			top = List.last(stack)
			stack = List.update_at(stack, po, &(&1 * top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def div do
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 2
			top = List.last(stack)
			stack = List.update_at(stack, po, &(&1 / top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def dup do
		Agent.update(__MODULE__, fn stack ->
			top = List.last(stack)
			stack ++ [top]
		end)
	end
	def drop do
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 2
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def get do
		Agent.get(__MODULE__, fn stack ->
			List.last(stack)
			|> to_string
		end)
	end
	def push(n) do
		Agent.update(__MODULE__, fn stack ->
			{v, _} = Integer.parse(n)
			stack ++ [v]
		end)
	end
end

defmodule Forth0 do
	def run(str) do
		Enum.map(String.split(str, " "), fn s ->
			cond do
			s == "+" ->
				Forth.add
			s == "-" ->
				Forth.sub
			s == "*" ->
				Forth.mul
			s == "/" ->
				Forth.div
			s == "dup" ->
				Forth.dup
			s == "drop" ->
				Forth.drop
			s == "." ->
				Forth.get
			true ->
				Forth.push(s)
			end
		end)
		Forth.get
	end
	def start do
		Forth.start_link
	end
end

defmodule Forth.Server do
	alias ElixirSocketTesting.ClientAgent
	def start(port \\ 50002) do
		Forth0.start
		ClientAgent.start_link
		server = Socket.Web.listen! port
		loop(server)
	end
	def loop(server) do
		client = server
			|> Socket.Web.accept!
		client
		|> Socket.Web.accept!
		ClientAgent.add(client)
		Task.async(fn ->
			recv(client)
		end)
		loop(server)
	end
	def recv(client) do
		case client |> Socket.Web.recv! do
		{:text, message} ->
			res = Forth0.run(message)
			broadcast({:text, res})
			recv(client)
		{:close, _, _} ->
			ClientAgent.remove(client)
		other ->
			IO.inspect other
		end
	end
	def broadcast(packet) do
		ClientAgent.all
		|> Enum.each(fn client ->
			Socket.Web.send(client, packet)
		end)
	end
end


```

以上。
WordPress に最適な CloudFront キャッシュ設定 (2023年度版)


AWS 公式ドキュメントが　2023年8月時点で公開している「[Best Practices for WordPress on AWS](https://docs.aws.amazon.com/ja_jp/whitepapers/latest/best-practices-wordpress/welcome.html)」にある設定例「[CloudFront distribution creation](https://docs.aws.amazon.com/ja_jp/whitepapers/latest/best-practices-wordpress/cloudfront-distribution-creation.html)」の内容が古かったので、自分なりに改良してみました。

主な改良点は

- レガシーキャッシュルールではなく、新しいのキャッシュポリシーを使う
- wp-json ディレクトリの通信を対応する
- Facebook や広告タグのクエリをオリジンサーバーに飛ばなくする

です。

# STEP.1 キャッシュポリシーを作成

絶対に CloudFront にキャッシュさせるように最小TTLを60に設定しています。アクセス頻度が少ないサイトであれば、最小TTLを増やすなどしてください。ただ、ページの更新の時間もかかるのでバランスを考えましょう。

- 名前: `0-default` (適当に変えてください)
- 説明: 任意
- TTL 設定
	- 最小TTL: `60` 秒
	- 最大TTL: `31536000` 秒
	- デフォルトTTL: `86400` 秒
- キャッシュキー設定
	- ヘッダー：`次のヘッダーを含める`
		- `Authorization` (開発中用)
		- `Host`
	- クエリ文字列
		- 次以外のすべてのクエリ文字列を含める
			- `fb_ref`
			- `fbclid`
			- `fb_action_types`
			- `fb_action_ids`
			- `gclid`
			- `utm_campaign`
			- `utm_content`
			- `utm_medium`
			- `utm_term`
			- `utm_source`
	- Cookie
		- `指定された cookie を含める`
			- `comment_*`
			- `wordpress_*`
			- `wp-settings-*`
- 圧縮サポート
	- `Gzip` チェック
	- `Brotli` チェック


追加するプラグイン・カスタマイズによって、必要なポリシーを増やします。


# STEP 2. ビヘイビア設定

## STEP 2-1. キャッシュする用のビヘイビア3つ

デフォルトのキャッシュ設定です。3つのビヘイビアを作成します。

- パスパターン:
	- `デフォルト`
	- `/wp-includes/*`
	- `/wp-content/*`
- オリジン: WordPress サーバーを選択
- オブジェクトを自動的に圧縮: `Yes`
- ビューワー: `Redirect HTTP to HTTPS` (適宜変更)
- 許可された HTTP メソッド: `GET, HEAD`
- ビュワーのアクセスを制限する: `No`
- キャッシュキーとオリジンリクエスト
	- `Cache policy and origin request policy (recommended)`
		- キャッシュポリシー: `0-default` (もしくは自分でつけた名前)

## STEP 2-2. 管理画面 & 動的ページの設定、3つ

管理画面や、Contact Form 7 などキャッシュできないページの設定です。3つのビヘイビアを作成します。

- パスパターン
	- `/wp-login.php`
	- `/wp-admin/*`
	- `/wp-json/*`
		- その他動的な動作をするプラグインで wp-json ディレクトリに向かって通信するディレクトリがあれば追加する。
- オリジン: WordPress サーバーを選択
- オブジェクトを自動的に圧縮: `Yes`
- ビューワー: `Redirect HTTP to HTTPS` (適宜変更)
- 許可された HTTP メソッド: `GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE`
- ビュワーのアクセスを制限する: `No`
- キャッシュキーとオリジンリクエスト
	- `Legacy cache settings`
	- ヘッダー: `すべて`
	- クエリー: `すべて`
	- cookie: `すべて`


これで、基本的な WordPress のキャッシュ設定ができます。

# 追記: より細かいチューニングをしてみよう

サーバーを冗長化していたり、よりキャッシュ率を上げたい場合は、トップページのビヘイビアをつけたり、wp-json のビヘイビアルールをプラグインによってキャッシュをしたりしないルールにしたりとチューンアップしていきます。


## `/wp-json/*` パスは奥が深い

`/wp-json/*` パスは現在「動的」な動作を行う場所として設定サンプルを提示しています。

ただ、追加でプラグイン・カスタマイズによってもビヘイビアルールを追加する必要がある場合があります。

例えば WordPress をヘッドレスで使用している場合、post (投稿) 関連のエンドポイントはキャッシュしたいパスです。

反対に、Contact Form 7 の様に、フォーム送信時にも`/wp-json/*` パスが使われるので、そこは動的パスとしての登録が必要です。

Chrome の Developer ツールなどを使い、どのパスをキャッシュするべきかを確認し調整しましょう。
Databricksのコントロールプレーンには何が格納されるのか？

ご質問いただくことがあるのでこちらにメモ。自分の備忘録も兼ねて。

# コントロールプレーンとは

[Databricksのアーキテクチャ](https://qiita.com/taka_yayoi/items/7d209bc8d32bc5f2dba4)はコントロールプレーンとデータプレーンから構成されています。

![](https://camo.qiitausercontent.com/783e731ba2431fc468e1e81a6bfcb7518439cf57/68747470733a2f2f646f63732e64617461627269636b732e636f6d2f5f696d616765732f64617461627269636b732d6172636869746563747572652e706e67)

- **コントロールプレーン**には、DatabricksのAWSアカウント上でDatabricksが管理するバックエンドサービスが含まれます。ノートブックコマンドやその他のワークスペース設定はコントロールプレーンに格納され、暗号化されています。
- **データプレーン**はあなたのデータを処理する場所となります。
    - ほとんどのDatabricksの計算処理における計算リソースは、*クラシックデータプレーン*と呼ばれるあなたのAWSアカウントに存在します。ノートブック、ジョブ、Databricks SQLウェアハウスのproとクラシックでは、Databricksはこのタイプのデータプレーンを使用します。
    - Databricks SQLでサーバレスコンピュートを有効化すると、Databricks SQLの計算リソースは共有の*サーバレスデータプレーン*に存在することになります。ノートブック、ジョブ、Databricks SQLウェアハウスのproとクラシックの計算リソースは依然としてお客様のアカウントに存在します。[Databricksのサーバーレスコンピュート](https://qiita.com/taka_yayoi/items/685a11ea726b2b34a174)をご覧ください。

# コントロールプレーンに格納されるデータ

以下のデータがコントロールプレーンに格納されます。[ノートブックの実行結果](https://qiita.com/taka_yayoi/items/d9eee0f14d95628301e1)に関しては、格納場所を変更することができます。

- [ノートブック](https://qiita.com/taka_yayoi/items/24a897cf40bba6d9e305)のコード
- SQLクエリーとクエリー履歴
- [シークレット](https://qiita.com/taka_yayoi/items/338ef0c5394fe4eb87c0)
- クラスタータイプ、サイズ、ジョブのスケジュールのようなクラスターとジョブのメタデータ
- モデルのメトリクスやパラメータのようなMLflowメタデータ
- カタログ、スキーマ、テーブル名のようなUnity CatalogやHiveメタストアのメタデータ
- テレメトリーデータ(ログ)
- ノートブックの実行結果

# 格納データに対するコントロール

コントロールの方法は以下の2つがあります。

- [顧客管理キー(CMK)による暗号化](https://qiita.com/taka_yayoi/items/c44d35e0e2fd76e44bbe)(デフォルトではDatabricks管理のキーで暗号化されています)
- [格納場所の変更](https://qiita.com/taka_yayoi/items/d9eee0f14d95628301e1)

各オブジェクトとコントロールの関係を以下にまとめます。

| オブジェクト | CMK | 格納場所の変更 | 
|:--|:--|:--|
| ノートブックのコード  | ⚪︎  |   |   
|  SQLクエリーとクエリー履歴 |  ⚪︎ |   |   
|  シークレット | ⚪︎  |   |   
|  クラスターとジョブのメタデータ |   |   |   
| MLflowメタデータ  |   |   |   |
| Unity CatalogやHiveメタストアのメタデータ  |   |   |   
|  テレメトリーデータ(ログ) |   |   |   
| ノートブックの実行結果  |  ⚪︎ |  ⚪︎ |   

また、復旧可能な手動削除に加えて、手動による[強制パージ](https://docs.databricks.com/en/administration-guide/workspace/settings/storage.html)が可能です。

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

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


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
[JSTQB AL TA]　1.テストプロセスにおけるテストアナリストのタスク　を視覚的にまとめてみた

# はじめに

こんにちは、Ma5am1nです。
[シラバス](https://jstqb.jp/dl/jstqb.jpdlJSTQB-SyllabusALTA_V311.J03.pdf)[^1]は文字が多くて頭に入りにくいので、図など視覚的に入ってきやすそうな形式でまとめてみます。

[^1]: Advanced Level シラバス日本語版　テストアナリスト　Version 3.1.1.J03 

**※あくまで私個人の解釈で作成したものです。内容が100%シラバスの通りであることは保証できませんので、ご了承ください。**
**※スライドの青文字、青線になっている箇所は、シラバスに記載されていない、私独自の解釈で記載した内容です。**

このページでは、1.テストプロセスにおけるテストアナリストのタスクについて扱います。

※1.4.2が抜けていたので追加(2023.08.18)

# 1.テストプロセスにおけるテストアナリストのタスク
## 1.1イントロダクション
![JSTQB AL TA-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/a6c53f5f-b96e-e667-a815-2cd1267021d3.png)

## 1.2ソフトウェア開発ライフサイクルにおけるテスト
![JSTQB AL TA-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/05ce7cff-f403-8ad4-ca43-1e06f4b9e658.png)

![JSTQB AL TA-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/a0b56733-38e1-bd3b-459d-0a5cb7df5145.png)

![JSTQB AL TA-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/2d09855a-2d4f-4d7f-667c-2afd76a3dd27.png)

![JSTQB AL TA-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/878d3f31-c5a7-c4ac-d218-d37f172f6eae.png)

## 1.3テスト分析
![JSTQB AL TA-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/b691ea31-59da-7386-0a9f-898e62b23e47.png)

![JSTQB AL TA-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/00614221-fc10-a960-03eb-76d296bd3a8c.png)

## 1.4テスト設計
![JSTQB AL TA-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/b2a1e2a1-a1c7-1ec1-b194-005c87fcb86e.png)

![JSTQB AL TA-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/dbe23fa0-7938-9ff5-4f24-fcc297dcbd89.png)

### 1.4.1ローレベルテストケースとハイレベルテストケース
![JSTQB AL TA-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/d1ae7606-9233-d2c6-6cf3-d03d3d8d387b.png)

### 1.4.2テストケースの設計
![JSTQB AL TA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/cf2e15a0-e7cc-9289-e3e6-40f7ace9ee03.png)
![JSTQB AL TA (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/8bfbf788-4bd1-8262-f5ca-b1108acf4c6a.png)
![JSTQB AL TA (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/7c55a7d3-9c99-1606-d0ed-8a3e610fb733.png)


## 1.5テスト実装
![JSTQB AL TA-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/853111f0-1375-7ec5-ed7a-982d7e1bc038.png)

![JSTQB AL TA-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/1b9c08e4-7c80-ec79-eeba-fcc58a18e23f.png)

![JSTQB AL TA-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/eae7a1b0-8d59-3b46-f552-b00d37b6dd87.png)

## 1.6テスト実行
![JSTQB AL TA-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c893a999-a363-8b50-6fd5-0c1674a7a377.png)
イベントについて野球部向けに解説してみる

おはようございます！
今日は昨日学習したイベントについて、野球のノックを例にして解説します。
とりあえずイベントとは何なのか、どう使うのか、というところが分かるように書いていきたいと思います。
イベントハンドラとかイベントリスナーという言葉もあるのですが、それは明日の記事で書きます。

## ノックの裏でどんなコードが走っているのか？
野球の練習で１体1でノックを受ける場面を想像してみてください。バッティング練習中にファールゾーンで行われているイメージです。

その時の流れは、
1.コーチが選手を呼ぶ。
2.ノックを受ける
という流れです。

ノックを受ける部分をもう少し詳しく説明すると、
2-1.選手が「おねがいします！」と言う。（叫ぶ）
2-2.コーチがノックを打つ
2-3.選手がボールを取る
という感じですね。

これをコードにするとおそらくこんな感じです。
```
// 1.コーチが選手を呼ぶ
const ノックを受ける選手 = document.querySelector("#YOOJI");　

// 2.選手が「お願いします！」と叫ぶと、コーチがノックを打つ
ノックを受ける選手.「お願いします！」 = function () {
  コーチがノックを打つ;
};
```
1行目が選手を呼ぶという処理です。
ノックを受ける選手が指名されるのが、プログラミングでいうquerySelector("特定の選手")です。

そして2行目で特定の選手が「お願いします！」と言ったらノック関数が発火します。
この”.「お願いします！」”という部分をイベントハンドラといい、これを使うことでさまざまな処理が可能になります。

イベントハンドラについては明日詳しく解説しますが、例えば
.keydown　→ 特定のボタンを押した時に発動
.mouseover →　特定の要素の上をマウスが通過した時に発動
.onclick → 特定の要素をクリックした時に発動
などがあります。これらが、上のコードの「お願いします！」の部分に入ります。


なので、例えば
```
ノックを受ける選手.onclick = function () {
  コーチがノックを打つ;
};
```
と書くと、ノックを受ける選手をクリックすれば、コーチがノックを打つようになります。（意味は分かりません）


## 昨日の学習で出てきた実際のコード
それでは、具体的なコードを見てみましょう。
```
const btn = document.querySelector("button");

function random(number) {
  return Math.floor(Math.random() * (number + 1));
}

btn.onclick = function () {
  const rndCol =
    "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")";
  document.body.style.backgroundColor = rndCol;
};
```
このコードは、ボタンがクリックされると背景色をランダムに変更するものです。
最初にdocument.querySelector("button")でボタンを選択し、それをbtnという変数に代入しています。これが、先ほどの例でいう特定の選手を指名する部分です。

次に、ランダムな数値を生成する関数randomを定義しています。この関数は、0から指定した数値までのランダムな整数を返します。関数についてはこちらの記事も読んでみてください。

https://qiita.com/yangyooji1946/items/a920bc02a8d93c46a845


最後に、btn.onclickでイベントハンドラを設定しています。ボタンがクリックされると、この関数が実行されます。関数内で、ランダムなRGB値を生成し、それを背景色として設定しています。

ここで、btn.onclickがイベントハンドラの設定部分です。onclickは、クリックイベントを表すプロパティで、このプロパティに関数を代入することで、ボタンがクリックされたときに実行される処理を定義します。この関数がイベントハンドラです。

このイベントハンドラの中で、random(255)を3回呼び出してRGB値を生成し、それを"rgb(" + random(255) + "," + random(255) + "," + random(255) + ")";という形式の文字列に組み立てています。そして、この文字列をdocument.body.style.backgroundColorに代入することで、背景色を変更しています。

このように、イベントハンドラを使うことで、ユーザーの操作に応じて動的な処理を実装することができます。今回の例では、ボタンがクリックされたときに背景色をランダムに変更するという処理を実装しましたが、他にも様々な処理を実装することが可能です。

例えば、フォームの送信ボタンがクリックされたときに入力値のチェックを行ったり、スクロール位置に応じてナビゲーションメニューの表示を切り替えたり、画像スライダーの次の画像への切り替えボタンがクリックされたときに画像を切り替えたりするなど、ユーザーの操作に応じて様々な処理を実装することができます。

以上が、昨日学習した部分の解説です。なんとなくイベントの基本的な使い方とすごさのイメージが湧いたでしょうか？

## まとめ
今回の記事で学んだ要点を3つにまとめます。

1.イベントハンドラは、特定のイベントが発生したときに実行される関数です。
2.querySelectorで特定の要素を選択し、その要素に対してイベントハンドラを設定することができます。
3.イベントハンドラを使うと、ユーザーの操作に応じて動的な処理を実装することができます。

以上が今日の内容です。
もし記事が役立ったと思ったら、ぜひいいねやフォローをお願いします。
これからも、プログラミング初心者の皆さんが理解しやすいような記事を書いていきます！

それでは今日も学習をスタートします！
【GitHub】ローカルリポの名前を変更し、リモートリポに反映させる手順

# 前提
- ~/desktop/dev/react_practice
この、react_practiceのリポジトリを、react_componentに変更したいとする。

# 手順
```bash:terminal
# ローカルリポジトリのディレクトリに移動
cd ~/desktop/dev

# リポジトリの名前を変更
mv react_practice react_component

# リポジトリ内に移動
cd react_component

# リモートリポジトリの名前を変更
git remote set-url origin 対象リモートリポのURL（SSH）

# リモートリポジトリに変更をプッシュ
git push origin main
```

これでローカルリポでプッシュした内容が、設定したURLのリモートリポに飛ぶようになる。
あとは、リモートリポのリポジトリ名を、react_practiceから、react_componentに変更すれば完了。
mcfunctionマクロ解説

# マクロとは
ファンクション内のコマンド行の一部分を未確定にして書き、functionコマンドの実行時に指定したNBTの値から未確定の部分を確定させてファンクションを実行する機能です。
<!--
コマンドの一部を未確定にしたファンクションを書き、functionコマンドの実行時に指定したNBTで未確定の部分を確定させてからファンクションを実行する機能です。
--->

# 基本の使い方
例えばsetblockコマンドが書かれたファンクションがあるとします。

```mcfunction:setblock.mcfunction
setblock ~ ~ ~ stone
```
当たり前ですがこのままでは石以外のブロックを設置することはできません。
\
そこで設置するブロックの指定部分をマクロで未確定にしてみます。
```mcfunction:setblock.mcfunction
$setblock ~ ~ ~ $(block)
```
マクロを使用する行では最初に`$`を付けます。
マクロで未確定にする部分は`$(任意の名前)`と書きます。
今回このマクロは`block`という名前にしました。

このマクロが含まれたファンクションは次の様なfunctionコマンドから実行します。
```mcfunction:main.mcfunction
function func:setblock {block:"glass"}
```

`{}`で囲われたNBTの中に`block`という名前のタグが入っています。

こうすることで`$(block)`の部分が`{block:"glass"}`の`glass`で確定させられます。

つまり
```mcfunction:setblock.mcfunction
$setblock ~ ~ ~ $(block)
```
が
```
setblock ~ ~ ~ glass
```
に変換されるため、実行の結果ガラスが設置されます。

# withによるNBT参照
functionコマンドで指定するNBTは`with`でストレージなどを参照可能です。
```mcfunction:main.mcfunction
data modify storage strg: setblk set value {block:"glass"}
function func:setblock with storage strg: setblk
```
```mcfunction:setblock.mcfunction
$setblock ~ ~ ~ $(block)
```
```
setblock ~ ~ ~ glass
```
そのためストレージに保存されたブロックのデータからsetblockをするなどの
今まで難しかったことが可能になりました。

<!--
# 応用
その他、マクロは一行内で複数指定することが可能であるため
```mcfunction:main.mcfunction
data modify storage strg: setblk set value {pos:"0 0 0",block:"glass"}
function func:setblock with storage strg: setblk
```
```mcfunction:setblock.mcfunction
$setblock $(pos) $(block)
```
```
setblock 0 0 0 oak_slab
```
この様にブロックを設置する座標もストレージから指定する様にしたり
\
また、そもそも行自体をマクロで置き換えてしまうことで
```mcfunction:main.mcfunction
data modify storage strg: exec set value {command:"say a"}
function func:exe with storage strg: exec
```
```mcfunction:exe.mcfunction
$$(command)
```
```
say a
```
ストレージ内の文字列をコマンドとして実行したりもできます。
--->

# 使用例
dataコマンドでリストのインデックス（何番目かの指定）を動的に変更する
```
$data get storage strg: list[$(index)]
```
\
functionコマンドで実行するファンクションを動的に変更する
```
$function $(func)
```
Quick LaTeX for Obsidian でLaTexを高速記述

　一ヶ月前くらいに、Obsidianをメモアプリとして導入したけど、使いこなすのが難しく、他の方の使用例や本などを読んで、最近ようやく慣れてきた。
基本的には、機械学習に関するメモで使用することが、どうしても数式の記述からは逃れられない。
LaTex記法を最近知り、それを使って頑張って記述していたが、素人にはどうしても時間がかかってしまう。
そんなときに、「Quick Latex for Obsidian」というプラグインを見つけたので、私のような方のために紹介します。

# 機能
## 自動補完
1. ＄記号
2. 括弧
3. 上付き文字と下付き文字のあとの式の{}(入力後にスペースキー押す必要あり)
## 選択した式をLaTeX記法に
式を選択して＄キーを押す
## 自動分数
個人的にこれが一番便利
分数にしたいものを/で記述し、スペースキーを押す
もし分数の始まりが分かりづらいときは、()で囲むか始まりにスペースを置くと、正しく分数にされやすい
分母分子が長いときは、分母分子を()で囲む

## 速記法
sqと入力してスペースを押すと、自動で\sqrt{}に置き換えられる

その他にも短縮表現が色々とあるので、公式をチェック

# 参考
公式Doc

https://github.com/joeyuping/quick_latex_obsidian
Ubuntuで無理やり解像度を変更する方法

# はじめに

購入したノートパソコンの解像度が1366x768であり、画面を縮小したいと考えたためです。

# 変更のやり方

## ステップ 1

端末から、`xrandr` と打ってください。2行目の `<foo> connected ...` が認識しているディスプレイです。 たいてい `eDP-1`、`VGA-1`、`HDMI-1` で接続しています。

:::note warn
2行目の先頭で `eDP-1` の代わりに `XWAYLAND0` が出力される場合はWaylandで入っています。ログイン時に右下の歯車のマークから、Ubuntu on Xorg を選択した状態でログインしてください。
:::

```bash
$ xrandr 
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 16384 x 16384
eDP-1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 194mm
   1366x768      60.00*+
   1280x720      60.00  
# ---省略--- #
   360x202       60.00  
   320x180       60.00  
VGA-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
```

## ステップ 2

`cvt` のあとに解像度を横、縦の順で与えます。次のステップの `--newmode` 引数を取得するためです。例えば 1920x1080 ならば、 `cvt 1920 1080` と入力します。

```bash
$ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
```

## ステップ 3

`xrandr --newmode` の後に、ステップ 2 で表示された内容の `Modeline` 以降をコピーして貼り付けてください。

```bash
$ xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
```

## ステップ 4

`xrandr --addmode` の後に、ステップ 1 で検出したディスプレイと、ステップ 2 で得られた`""`を続けて打ちます。

以下の `eDP-1` を `HDMI-1` や `VGA-1` などのディスプレイの種類 (ステップ 3) に置き換えて打ちます。

```bash
$ xrandr --addmode eDP-1 "1920x1080_60.00" 
```

## ステップ 5

次に、端末を閉じて、[設定] → [ディスプレイ] → [解像度] に移動し、1920x1080 に変更します。

# 恒久的に変更させる方法

`~/.profile` にステップ 3, 4 を追記します。

```bash: ~/.profile
# 1600x900の場合
xrandr --newmode "1600x900_60.00" 118.25 1600 1696 1856 2112 900 903 908 934 -hsync +vsync
xrandr --addmode eDP-1 "1600x900_60.00"

# 1920x1080の場合
xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
xrandr --addmode eDP-1 "1920x1080_60.00"
```

# 適当に書いたシェルスク

引数に横と縦のピクセル数を渡す。

```bash
#!/bin/sh

ARG=$(cvt $1 $2 | sed -z 's/.*Modeline//g')
xrandr --newmode $ARG
xrandr --addmode $(xrandr | grep primary | sed -e 's/connected.*//') ${ARG%\"*}\"
```