OmniAICreator/Qiita-1.07M huggingface dataset:
正規表現による複数行の置換（VSCodeでBuilderパターンをコンストラクタに置換）

# やりたいこと

```java
  // 現状
  Foo.builder()
    .hoge("a")
    .huga(10)
    .build();

  // こうしたい
  new Foo("a", 10);
```

例としてJavaのコードを扱います。Builderパターン[^builder]をやめてコンストラクタでインスタンスを生成したいという設定です。
本記事はVSCodeで検証しました。（ツールによっては`\n`に非対応ということもあるかもしれません。）


# 「現状」とマッチングする正規表現（シンプルなケース）
```text:「現状」とマッチングする正規表現
Foo\.builder\(\)[\s\S\n]*?build\(\);

（見やすさのために改行を入れると）
Foo\.builder\(\)
[\s\S\n]*?
build\(\);
```

正規表現[^dotnet]がどう働いているかというと、
- `Foo\.builder\(\)`で始まる部分を指定します。
- `[\s\S\n]`は改行コード含む全文字を示します[^ref_qiita]。
- `*?`は↑が0回以上繰り返されるパターン、その中で最小の文字列にヒットします。
    - つまり、↓のパターンが来るまでの任意の文字列（改行含む）です。
- `build\(\);`で終わる部分を指定します。(`;`だけでも大丈夫です。)

ということです。
改行`\n`を含めることで行を跨ぐことができます[^vscodeofficial]。今回の例では末尾に`;`が付くのでマッチングさせやすいですね。

これを`new Foo("a", 10);`に置換する事で目的を達成できます。
ただし、これだと`"a"`や`10`を変更できません。
複数箇所を修正する時に`.hoge("b").huga(20)`が混ざっていたら少し辛いです。


# 代入部分をキャプチャして置換
```text:代入部分をキャプチャして置換
# 検索欄
Foo\.builder\(\)[\s\S\n]*?hoge\((.*)\)[\s\S\n]*?huga\((.*)\)[\s\S\n]*?build\(\);

（見やすさのために改行を入れると）
Foo\.builder\(\)
[\s\S\n]*?
hoge\((.*)\)
[\s\S\n]*?
huga\((.*)\)
[\s\S\n]*?
build\(\);

# 置換欄
new Foo($1, $2);
```

```java:結果
  // 前
  Foo.builder()
    .hoge("a")
    .huga(10)
    .build();
  Foo.builder()
    .hoge("b")
    .huga(20)
    .build();

  // 後
  new Foo("a", 10);
  new Foo("b", 20);
```

`[\s\S\n]*?hoge\((.*)\)` と `[\s\S\n]*?huga\((.*)\)` というのが追加されています。
改行やインデントを挟むたびに`[\s\S\n]*?`を入れます。また、`hoge("a")`等のカッコの中身をキャプチャしています。

なお、`hoge()`のように中身が空だと`new Foo(, 10);`のように不正な文ができます。
`hoge("a)")`のようなケースだとキャプチャが上手く働きません（`hoge\([^)]*\)`とやるといけるかもしれません）。
が、今回は考えません。疲れてきたからです。（「経験則上、これ以上やると費用が利益を上回りそうである」という意味の高度な専門用語です。）


# いかがでしたか？
置換したい文が複数行を跨いでいると面倒ですよね。
正規表現を扱うたびにGoogleに`正規表現 やり方`という何の面白みもないクエリを投げては経由させていただいたインターネットの諸々の通信機器に申し訳なく思う日々でしたが、この備忘録を書いたことによって負荷が改善されればと思います。

参考にさせていただいた文献については、続く脚注にて紹介いたします。

[^builder]:LombokのBuilderパターン解説 :+1:
https://qiita.com/uhooi/items/bb817e7ca7dc128bf475

[^dotnet]:.Netにおける正規表現の仕様（厳密にはVSCodeとは違う仕様なので参考までに）
https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference

[^ref_qiita]:VS Codeで複数行に渡って正規表現を利用する :+1:
https://qiita.com/birdwatcher/items/dee34a11619b11e1fe81

[^vscodeofficial]:2018年からVSCodeでmulti searchができるようになった
https://code.visualstudio.com/updates/v1_29#_multiline-search (リリースノート)
https://code-zen.hatenablog.com/entry/20210910/1631229389 (それを紹介する記事)
CodeRunnerでpython: command not foundが出る場合

# エラー

```
[Running] python -u "/***/tempCodeRunnerFile.py"
/bin/sh: python: command not found
```

# 解消方法
`command + ,`で設定画面を開き、`@ext:formulahendry.code-runner`と入力、`Code-runner: Executor Map`を探してjsonの設定画面を開く。
(もしくは`command + p`で`settings.json`と入力する)

`code-runner.executorMap"`の`"python"`部分を以下のように変更する
```
"code-runner.executorMap": {
        ...
        "python": "python3 -u",
        ...
```

--
プラグイン
[Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner
 "Code Runner")
laravel 初期設定

# laravelのインストール
````
composer create-project laravel/laravel <プロジェクト名> "8.*" --prefer-dist
````
`--prefer-dist`は圧縮版のオプション

2022年6月からlaravelのフロント側のビルドツールがviteに変わったので、
laravel-mixに戻す手順

https://biz.addisteria.com/remove_vite/
# DB設定、マイグレート
対象のDBとuserを作成後、envファイルに記載する。
````.env
DB_DATABASE=<DB名>
DB_USERNAME=<user名>
DB_PASSWORD=<password>
````
DBとの接続とテーブルの作成
````
php artisan migrate
````
# 初期設定
設定を日本語圏に変更する
````config/app.php
//タイムゾーンの変更
'timezone' => 'Asia/Tokyo',
//言語設定の変更
'locale' => 'ja',
````
デバッグバーのインストール
````
composer require barryvdh/laravel-debugbar
````
デバッグバーの起動
````.env
APP_DEBUG=true
````
envファイルを書き換えた後はキャッシュクリアをする
````
//環境ファイルのキャッシュをクリア
php artisan config:clear
//アプリのキャッシュをクリア
php artisan cache:clear
````
# laravelの認証機能(Laravel Breeze)のインストール
````
composer require laravel/breeze "1.*" --dev
php artisan breeze:install
npm install && npm run dev
````
# laravelの日本語化対応

https://readouble.com/laravel/8.x/ja/validation-php.html
Haskell勉強メモ Down

Haskellの知識を深めたかったので、Hackageを適当に眺めて知らない型がないか探していました。今回はその中から```Down```について調べたので、自分なりにメモしておこうと思います。

# Down
```Down```は逆順ソートなどに用いられる型のようです。```Data.Ord```で定義されています。

https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-Ord.html#t:Down

```SortOn```と組み合わせると、シンプルに逆順ソートを実装できます。
```haskell:逆順ソートの例
import Data.Ord
import Data.List

tekitou = [1,345,3,624,724,7,13,634,62,6,23,62,4562]

main = do
 print (sortOn Down tekitou) --シンプルに書ける
 print (sortBy (comparing Down) tekitou) --速度はこちらのほうが速いらしい
```
```:結果
[4562,724,634,624,345,62,62,23,13,7,6,3,1]
[4562,724,634,624,345,62,62,23,13,7,6,3,1]
```
```Down a```には```a```とは逆の大小関係が定義されています。以下、https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Data.Ord.html より引用です。
```haskell
-- | @since 4.6.0.0
instance Ord a => Ord (Down a) where
    compare (Down x) (Down y) = y `compare` x
```
確かに、逆になっていますね。

# Monad Down
```Down```は```Monad```のインスタンス（従って```Functor```、```Applicative```のインスタンス）です。以下、https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Data.Ord.html より引用です。
```haskell
-- | @since 4.11.0.0
instance Functor Down where
    fmap = coerce

-- | @since 4.11.0.0
instance Applicative Down where
    pure = Down
    (<*>) = coerce

-- | @since 4.11.0.0
instance Monad Down where
    Down a >>= k = k a
```

私はここで初めて```coerce```という関数を知りました。現状あまり理解していませんが、同じような型同士を変換する関数のようです。おそらく```fmap = coerce```の場合、```fmap f (Down x) = Down (f x)```と同じ意味だと思います。```a```と```Down a```はほとんど同じなので、自動的に変換できるということでしょうか。

一応```do```記法で```Down```が```Monad```であることを見てみます。
```haskell: 何の意味があるのかはわからない例
import Data.Ord

f :: Num a => Down a -> Down a -> Down a
f x y = do
 a <- x
 b <- y
 return (2*a+3*b)
 
main = do
 let x = Down 1
 let y = Down 2
 print (f x y)
```
```:結果
Down 8
```
```Down```が```Monad```のインスタンスであることはわかりましたが、```Monad```のインスタンスであることを上手く利用した例はあるのでしょうか？ （単に定義できるから定義しているだけ？）```Monad```の具体例をなるべく多く知りたい気持ちがあるので、少し気になっています。

# 参考

* [Haskellのソートあれこれ - Qiita](https://qiita.com/TTsurutani/items/d069363e9f4d613abf10)
* [type roleについて学ぶ - Qiita](https://qiita.com/hiratara/items/888bdae1455fd7c4a5f0)
データを整列させるアルゴリズム

データを整列させるアルゴリズムを紹介する。

# 基本交換法（バブルソート）
```隣接するデータの大小を比較```する。
必要に応じて入れ替えることで全体を整列させる。
先頭の２つから整列させていく。

# 基本選択（選択ソート)
対象データの内、```最小、最大のデータを取り出して、先頭データと交換```して
全体を整列させる。

# 基本挿入法（挿入ソート）
対象のデータ列を```整列済みのものと未整列のもの```とに分かれます。
```未整列のデータ列から一つずつ```取り出して、整列済みのデータ列に```適切な場所に当てはめて```いく。
それで全体を整列させる。

# より高速な整列アルゴリズム
ここからは応用的な整列アルゴリズムを紹介する。

## シェルソート
```ある一定間隔おきに取り出した要素でソート```を繰り返していく手法
出典 https://medium-company.com/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88/#1

### 気づき
グループ分けして、挿入ソートの繰り返しみたいなことか。

## クイックソート
ある```中間的な基準値を決めてそれより小さい値と大きい値のグループに振り分ける```。
そのグループで```また基準値を決めてグループに振り分ける```を繰り返す。

### 気づき
２分木探索法と似ているな。

## ヒープソート
未整列のデータを```「ヒープ」の性質```を持つ木構造の構成にして、そこから```最大値または最小値```を取り出して整列、これを繰り返すことで全体を整列させる手法
### ヒープとは？
* ヒープは最小値（または最大値）を求めるのに適した木構造の一種であり、「子要素は親要素より常に大きいか等しい（または常に小さいか等しい）」という制約を持つ。子要素が複数ある場合、子要素間の大小関係に制約はない。
    出典 https://ja.wikipedia.org/wiki/%E3%83%92%E3%83%BC%E3%83%97#:~:text=%E3%83%92%E3%83%BC%E3%83%97%E3%81%AF%E6%9C%80%E5%B0%8F%E5%80%A4%EF%BC%88%E3%81%BE%E3%81%9F%E3%81%AF,%E9%96%A2%E4%BF%82%E3%81%AB%E5%88%B6%E7%B4%84%E3%81%AF%E3%81%AA%E3%81%84%E3%80%82&text=%E3%81%A7%E8%A1%8C%E3%81%88%E3%82%8B%E3%80%82,%E5%AE%9F%E8%A3%85%E3%81%A8%E3%81%97%E3%81%A6%E3%82%82%E4%BD%BF%E3%82%8F%E3%82%8C%E3%82%8B%E3%80%82

* 小さいヒープの関係を表す
https://medium.com/@yasufumy/data-structure-heap-ecfd0989e5be

出典 https://medium-company.com/%E3%83%92%E3%83%BC%E3%83%97%E3%82%BD%E3%83%BC%E3%83%88/#1

### 気づき
ヒープの性質を利用して根を取り出して最小、最大から取り出すのか。

## マージソート
整列対象のデータを2分割していく操作を繰り返し、要素数が1になるまで細分化、そして細分化した要素同士を整列しながら戻していく手法です。
出典 https://medium-company.com/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88/

# 出典
https://gihyo.jp/book/2020/978-4-297-11781-8
【Kaggle】Kaggle api コマンドまとめ

## 背景
- kaggleコマンドを全然覚えない自分のために、使用したkaggleコマンドをまとめておきたい。
※kaggleコマンドを使用するには、事前にkaggleでtoken発行等、準備が必要

## 目標
- 使用したkaggleコマンドをまとめていく。

## kaggleコマンドまとめテーブル
|コマンド  |説明  |
|---|---|
|$kaggle competitions list | 開催中のコンペ一覧を表示　|
|$kaggle competitions files -c [コンペ名] | 指定のコンペの使用するデータを表示 |
|$kaggle competitions download -c [コンペ名]| 指定のコンペのデータをカレントにzipでダウンロード |
|$kaggle competitions submit -c [コンペ名] -f [ファイル名] -m [コメント]| コンペに予測値をコメント付きでsubmit(投稿） |
|$kaggle competitions submissions -c [コンペ名]| コンペに投稿した自分のsubmit記録一覧を表示|


## titanicコンペの場合のコマンド例
|コマンド  |
|---|
|$kaggle competitions list |
|$kaggle competitions files -c　titanic |
|$kaggle competitions download -c　titanic　|
|$kaggle competitions submit -c titanic -f submit.csv -m '１回目submit'|
|$kaggle competitions submissions -c titanic|

## DLしたzipを解凍するpythonコード
```python:
#使用するライブラリをimportする
import shutil
import os

#カレントディレクトリから、「.zip」を含むものだけ取り出す。
zip_file = [x for x in os.listdir() if '.zip' in x]
zip_file

#zipファイルを解答する処理
shutil.unpack_archive(zip_file[0], './')
```


## 補足
- 自分がわかりやすいように書いているので、色々間違ってるかもしれません。

## 参考資料

https://www.currypurin.com/entry/2018/kaggle-api

## 個人ブログ

https://takuma-tech.com/2022/09/28/271/
【超簡単】rails投稿機能で削除しても履歴残す！！（論理削除）

# やること
rails の投稿機能で削除してもレコードを完全に削除するのではなく、ユーザーから非表示になるのみで投稿者や管理者から復元できるようにする！
![画面収録-2022-08-25-18.19.24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/cd75eb93-9646-722a-5b2d-50028b94f021.gif)

# 手順
1. gemのインストール
1. カラムの追加
1. 一覧ページの表示
1. 削除、復元
こんな感じでやっていきます！今回はgemの機能が強すぎるので　gemの使い方がメインになります:massage:
早速やっていきましょー！！

# 1.Gemのインストール
```gemfile:Gemfile
gem 'discard', '~> 1.2'
```
```terminal:terminal
bundle install
```

# 2.カラムの追加
論理削除をしたいテーブルに`discarded_at`カラムを追加します！
```terminal:terminal
rails db:rollback
```
対象のテーブルを作っているmigrationファイルを**down**にしましょう
今回はtweetsテーブルでやります
```ruby:db/migrate/20220116200153_create_tweets.rb
class CreateTweets < ActiveRecord::Migration[6.1]
  def change
    create_table :tweets do |t|

      #略

      t.datetime "discarded_at", precision: 6 #追加
      t.index ["discarded_at"], name: "index_posts_on_discarded_at" #追加

      #略

    end
  end
end
```
```terminal:terminal
rails db:migrate
```

# 一覧ページの表示
モデルに追記
```ruby:models/tweet.rb
include Discard::Model
```
```ruby:tweets_controller
def index
    @tweets = Tweet.all #変更前

    @tweets = Tweet.undiscarded #変更後
end
```

# 削除、復元
今回はわかりやすいようにindexページ内で削除済みのものと削除されてないもの両方表示するように書きます
```ruby:tweets_controller
#略
def index
    @tweets = Tweet.undiscarded #削除されてないやつ
    @del = Tweet.discarded #削除されたやつ
end
#略
```
```html:tweets/index.html.erb
<h1>投稿一覧</h1>
<% @tweets.each do |t| %>
    <p>
        <%= t.title %> <!-- テキトー -->
        <%= t.body %> <!-- テキトー -->
        <%= t.discarded? %> <!-- trueなら論理削除済み、falseなら論理削除前 -->
    </p>
<% end %>

<h1>削除済み一覧</h1>
<% @del.each do |t| %>
    <p>
        <%= t.title %>
        <%= t.body %>
        <%= t.discarded? %>
    </p>
<% end %>
```
#### 削除ボタン、復元ボタンの追加
```ruby:config/routes.rb
#略
post 'restoration/:id' => 'tweets#restoration'
resources :tweets
```
```ruby:tweets_controller
#略
def destroy
    tweet = Tweet.find(params[:id])
    tweet.discard
    redirect_to action: :index
end
def restoration
    tweet = Tweet.find(params[:id])
    tweet.undiscard
    redirect_to tweets_path
end
#略
```
```html:tweets/index.html.erb
<h1>投稿一覧</h1>
<% @tweets.each do |t| %>
    <p>
        <%= t.title %>
        <%= t.body %>
        <%= t.discarded? %>
        <%= link_to "削除", tweet_path(t.id), method: :delete %>
    </p>
<% end %>

<h1>削除済み一覧</h1>
<% @del.each do |t| %>
    <p>
        <%= t.title %>
        <%= t.body %>
        <%= t.discarded? %>
        <%= button_to "復元", controller:"tweets", action:"restoration", id:t.id, method: :post %>
    </p>
<% end %>
```
# 補足
削除済みの表示を別のページに移したくなったら
```ruby
@del = Tweet.discarded
```
```ruby
<h1>削除済み一覧</h1>
<% @del.each do |t| %>
    <p>
        <%= t.title %>
        <%= t.body %>
        <%= t.discarded? %>
        <%= button_to "復元", controller:"tweets", action:"restoration", id:t.id, method: :post %>
    </p>
<% end %>
```
これだけ移動すればおけです！

# 最後に
ここまで読んでいただきありがとうございます！！
それじゃまた〜〜〜ばいばいちゃ〜〜ん
>参考：https://techtechmedia.com/logiacal-deletion-discard/
javaScriptでTabキーに制限を加えたい

## はじめに
実務で簡単な画面を作成しているときにTab押下時に以下の要素に順番にフォーカスする。という仕様があった。
初めての開発案件でまともにjsを触るのが初めてだった私はググれば一瞬で出来るやろ。とたかを括っていました。（多分基礎的な仕様なんだと思いますが。。）

ググり方が悪いのか意外とやりたい事がビシッと書いてある記事がない、、、

## やりたいこと
画面上にある要素に対してTabキー押下時にフォーカスをループしたい。



## 手順
1.フォーカスループしたい要素を配列の形式で取得する
2.Tabボタン押下のイベントをキャッチ
3.1で取得した配列をもとにジェネレーターを作る(ジェネレーターを使ってみたかったから使用しました。多分簡単なやり方が他にもある)



## 準備

マテリアルUIを使ってますが簡単に言えば二つのボタンが画面上にあるイメージ

今回使用するコードの全体像
```javascript
const Tabs = () => {
    useEffect(() => {
        //フォーカスループしたい要素を取得
        const  button =  document.querySelectorAll('button');

        //フォーカスループした要素数に応じてインデックスを延々と返す関数
        function* next(a: any, num=0):Generator {
            do{
                if (num === a.length  ) {
                    num = 0
                }
                 yield num++;
            } while(num <= a.length )
        }
        var index = next(button);

        //Tabキー押下時のイベントキャッチ
        const tabmove = (e: any) => {
            if (e.key === "Tab") {
                e.preventDefault();
                button[index.next().value].focus();
            }
        }
        document.addEventListener('keydown', tabmove);
    },[])


  return (
    <Container maxWidth="sm">
        <Box>
            <Stack spacing={2} direction="row" >
                <Button variant="contained" color='success' tabIndex={1} >
                    成功
                </Button>
                  <Button variant="contained" color="error" tabIndex={ 2}>
                    失敗
                </Button>
            </Stack>
        </Box>
    </Container>
  )
}

```



### 1.フォーカスループしたい要素を配列の形式で取得する
今回はボタン要素にのみフォーカスを当てたかったので以下の記述でいいですが、フォーカスを当てたい要素が他にもあれば取得方法は検討する必要があると思います。

```javascript
 const  button =  document.querySelectorAll('button');
```

### 2.Tabボタン押下のイベントをキャッチ
初めはkeydownではなくkeyupにしていたのですが、それではTabキーのデフォルト動作をpreventDefaultで削除することが出来ず沼っていました。keydownにすれば問題なくTabの動作を制御できました。（制御しなかったら画面の検索バーとかにもフォーカスが当たってしまう）

(typescriptの型は今回anyでやってます。。時間ができた時に型を指定したい)


```javascript
       const tabmove = (e: any) => {
            if (e.key === "Tab") {
                e.preventDefault();
                button[index.next().value].focus();
            }
        }
        document.addEventListener('keydown', tabmove);
```
上記コードでやってるのは
e.preventDefaultでTabのデフォルト動作を消してから、項番1で取得したボタン配列の要素に応じてインデックスを指定し、指定された要素にのみfoucsを用いてフォーカスしている。と分かればかなりシンプルな作り。

### 3.1で取得した配列をもとにジェネレーターを作る
Tabボタンを押下したタイミングで取得した配列の要素数に応じて0から始まり要素数までインクリメントで上がってくれる関数を作ろうと思いました。
やりたいことのイメージに一番あっていたのがジェネレーターを用いた関数でした。

```javascript
function* next(a: any, num=0):Generator {
            do{
                if (num === a.length  ) {
                    num = 0
                }
                 yield num++;
            } while(num <= a.length )
        }
        let index = next(button);
        index.next() //=> 0
        index.next() //=> 1
        index.next() //=> 2
        index.next() //=> 3
        index.next() //=> 0
        index.next() //=> 1
        index.next() //=> 2
        index.next() //=> 3
```

引数aには配列を格納し、その要素数を上限に0スタートで数値を返却するという関数です。

### 終わり
将来、開発経験をさらに積んで今回記述した汚いコードを赤面して見るために頑張ります。。
【C#】DateTime型の変換　まとめ

# 概要
仕事でちょくちょくと使う機会があるのでまとめてみました。
(Parseを使用している箇所は適宜TryParse変えて使用。)

## DateTime型 → string型 (西暦)

```c# 
DateTime dt = DateTime.Now; //2022/08/27 16:04:32

string sDate = "";
sDate = dt.ToString("yyyy/MM/dd"); // → "2022/08/27"
sDate = dt.ToString("yyyy/MM/dd HH:mm:ss"); // → "2022/08/27 16:04:32"
```

## DateTime型 → string型 (和暦)
```c# 
DateTime dt = DateTime.Now; // → 2022/08/27 16:04:32

string sDate = "";
System.Globalization.CultureInfo Info = new System.Globalization.CultureInfo("ja-JP");
Info.DateTimeFormat.Calendar = new System.Globalization.JapaneseCalendar();
sDate = dt.ToString("ggyy年M月d日"); // → 令和4年8月27日
```

## DateTime型 → 数値型(int, long)
```c# 
DateTime dt = DateTime.Now; // → 2022/08/27 16:04:32

int iDate = 0;
iDate = int.Parse(dt.ToString("yyyyMMdd")); // → 20220817

long lDate = 0;
lDate = long.Parse(dt.ToString("yyyyMMddHHmmss")); // → 20220817160432
```

##  String型 → DateTime型
```c# 
DateTime dDate;

dDate = DateTime.Parse("2022/08/31"); // → 2022/08/31 0:00:00
dDate = DateTime.Parse("2022/08/31 11:59:59"); // → 2022/08/31 11:59:59
```

## int型 → DateTime型 (その1)

```c# 
DateTime dDate;

dDate = new DateTime(2022, 12, 31); // 2022/12/31 0:00:00
dDate = new DateTime(2022, 12, 31, 1, 2, 3); // 2022/12/31 1:02:03
```

## int型 → DateTime型 (その2)

```c# 
iDate = 20220831;

string s = iDate.ToString();
int iYear = iDate / 10000;
int iMonth = (iDate / 100) % 100;
int iDay = (iDate % 100);

DateTime dDate = new DateTime(iYear, iMonth, iDay); // 2022/08/31
```
UnityでMacOS用にビルドしたappがyou do not have permission to open the applicationとなって開けない時の対処

以下、ビルドしたファイルをGame.appと表記します。
```
chmod +x Game.app/Contents/MacOS/Game
xattr -r -d com.apple.quarantine Game.app/
```
以上のコマンドを実行してあげます。
その後に開こうとすると

cannot be opened because apple cannot check it for malicious software

みたいな警告が表示されると思います。ctrlを押しながらappファイルを開こうとすると開けます。

### 参考
https://forum.unity.com/threads/issue-opening-unity-mac-applications-on-mac-big-sur-os-from-unidentified-developer.1026697/
クリップボードにコピーし、「コピーしました」メッセージを表示する

# 押すだけ簡単コピペ機能のメッセージを表示してみた
- 備忘録用に、Reactで簡単に作ってみました。
- この記事を読むと、Material-UIのみで次のようなUIが実装できます。
![作ったものもスクショ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2818906/d2f49260-9d6a-c891-7d49-32001e576eab.png)

# クリップボードにコピーする
- [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard)で実装します。
```
const anyText = "コピーさせたい内容"
navigator.clipboard.writeText(anyText);
```

# メッセージの表示
- Material-UIの[Tooltip API](https://mui.com/material-ui/api/tooltip/)を使うと、簡単に実装できます。
```
import { Tooltip } from "@mui/material";
```
# 全体のサンプルコード
```sample.tsx
import { Tooltip } from "@mui/material";

async function copyToClipboard(text: string) {
  try {
    await navigator.clipboard.writeText(text)
  } catch (error) {
    console.log((error) || 'コピーに失敗しました')
  }
}

const Sample: React.FC<{}> = () => {
    const anyText = "コピーさせたい内容";
    const [openTip, setOpenTip] = useState<boolean>(false);
    
    const handleCloseTip = (): void => {
        setOpenTip(false);
    };
    
    const handleClickButton = (): void => {
        setOpenTip(true);
        copyToClipboard(anyText);
    };

    return(
        <>
            <h1>サンプル</h1>
            <Tooltip
                arrow
                open={openTip}
                onClose={handleCloseTip}
                disableHoverListener 
                placement="top"
                title="Copied!"
              >
                <button onClick={handleClickButton}>
                  クリップボードにコピーする
                </button>
              </Tooltip>
        </>
    );
}

```
# 参考資料
[クリップボードにテキストをコピーするボタンの実装](https://qiita.com/flu_bit/items/659a59260446117e9548)
[React+material-uiでコピーボタン付きのテキストボックスを作る](https://qiita.com/koki_develop/items/211f04f59371c752bd88)
React + Rails + AWS Fargate の構成を実現したい - 06 フロントエンドのCI導入(GitHub Actions)

# 概要

https://qiita.com/memomaruRey/items/746f9cff0ceefe8b6157

# 本記事のゴール
以下を参考に、GitHub Actionsを用いてフロントエンドのCI導入を行う。

https://gist.github.com/ljmocic/3b171a3ee6e2a613eac7c465480a72e1

# 成果

以下のように、以下記事で書いたフロントエンドのテストが実行されていることを確認した。

https://qiita.com/memomaruRey/items/d146b4a527c11089a429

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/b77d7d30-a577-23f9-7f4f-73451fe53f8b.png)

# つまづいた点

上記参考記事通りに進めることでつまづいた点なし。
データを探索するアルゴリズム

# アルゴリズムを想像する
```探索```はアルゴリズムの中で基礎的で、かつ単純なものとして挙げられる一つ。
基礎的で単純ものだからこそ、```自身の頭の中にある処理を、どのようにアルゴリズムとして分解するのかという練習に役立つ```のです。

## 気づき
自分の作りたい処理をどのようにアルゴリズムに落とし込むかを訓練するところなのか。

# 線形探索法
先頭から順に探索していく方法。

配列の値が目的のデータと等しい　
または
変数が添字の最大値よりも大きい
を条件にループする。

しかし配列の中に絶対に目的のデータあれば
２つ目の条件はいらなくなる。
終了判定を簡単にするために末尾に付加したデータのことを```番兵```という。

## 気づき
このようにアルゴリズムに落とし込む最中に無駄な条件がある場合は、省略する。
より具体的にすることによって正確に書くことができる。

# ２分探索法
昇順、降順の規則性を持つ場合に効率のいい方法
まず真ん中のデータの値を取り出し、探したい値と比べる。
大きい場合は大きい半分に
小さい場合は小さい半分に
また真ん中のデータの値を取り出す。
これを繰り返して目的のデータを探索する。

## フローチャート
最低を１　最高をn
まず最低と最高を比べることから繰り返しの処理の開始
最低と最高を足して２で割る。それを変数に格納する
その変数が目的の値と比べて結果によって
目的のデータが見つかり終わる
それ以外は
変数を最低か最高に代入される。
それ見つかるまで繰り返す。

# ハッシュ法
一定の計算式を用いて、データの格納位置をズバリ算出する。

しかしこの場合シノニムという現象が起こる。
同じ計算結果になり実際には違うが、間違って同じになってしまう。
なので別の計算方法で新しい格納先を求める必要がある。

https://qiita.com/masatom86650860/items/cfa4d8eb0d95f0e38805#%E3%81%AA%E3%81%9C%E3%82%B7%E3%83%8E%E3%83%8B%E3%83%A0%E3%81%8C%E5%A4%9A%E7%99%BA%E3%81%99%E3%82%8B%E3%81%A8%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E9%80%9F%E5%BA%A6%E3%81%8C%E8%90%BD%E3%81%A1%E3%82%8B%E3%81%AE%E3%81%8B%E6%9C%AA%E8%A7%A3%E6%B1%BA

# 各アルゴリズムにおける探索回数
それぞれ平均探索回数を紹介する。
## 線形探索法
```（１±n)/2```になる。
最小で一回、最大でn回になるからだ。

## ２分探索法
```log2n```になる。
　
### 気づき
今はなんでこうなるのかまだ理解ができない。
数学が微妙だからだ。

## ハッシュ法
```1回```
シノニムを発生を無視すれば
ros msgとjsonの相互変換 (python)

# はじめに

このライブラリの使い方

https://pypi.org/project/rospy-message-converter/

github

https://github.com/uos/rospy_message_converter

# 環境

ubuntu20.04
ROS noetic

# install

```
pip3 install rospy-message-converter
```

# サンプルプログラム

## jsonからrosに変換

```json_to_ros.py
from rospy_message_converter import json_message_converter

msg_type = "std_msgs/String"
json_msg = '{"data": "Hello, Robot"}'
ros_msg = json_message_converter.convert_json_to_ros_message(msg_type, json_msg)

print(ros_msg)
```

結果

```
data: "Hello, Robot"
```

## rosからjsonに変換

### std_msgs/String
```ros_to_json.py
from rospy_message_converter import json_message_converter
import std_msgs.msg
ros_message = std_msgs.msg.String(data="Hello, Robot")
json = json_message_converter.convert_ros_message_to_json(ros_message)
print(json)
```

結果

```
'{"data": "Hello, Robot"}'
```

### geometry_msgs/PoseStamped

```ros2json.py
from rospy_message_converter import json_message_converter
from geometry_msgs.msg import *
msg = PoseStamped()
msg.header.frame_id = "map"
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)
```
```
{"header": {"seq": 0, "stamp": {"secs": 0, "nsecs": 0}, "frame_id": "map"}, "pose": {"position": {"x": 0.0, "y": 0.0, "z": 0.0}, "orientation": {"x": 0.0, "y": 0.0, "z": 0.0, "w": 0.0}}}
```
### geometry_msgs/PointStamped

```ros2json.py
from rospy_message_converter import json_message_converter
from geometry_msgs.msg import *
msg = PointStamped()
msg.header.frame_id = "map"
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)
```

```
{"header": {"seq": 0, "stamp": {"secs": 0, "nsecs": 0}, "frame_id": "map"}, "point": {"x": 0.0, "y": 0.0, "z": 0.0}}
```

### geometry_msgs/Polygon


```python:polygon2json.py
from rospy_message_converter import json_message_converter
import std_msgs.msg
from geometry_msgs.msg import *

msg = Polygon()
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)

msg = Polygon()
msg.points.append(Point32(1,2,3))
msg.points.append(Point32(4,5,6))
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)
```

```
{"points": []}
{"points": [{"x": 1, "y": 2, "z": 3}, {"x": 4, "y": 5, "z": 6}]}
```

### geometry_msgs/PolygonStamped

```python:ps2json.py
from rospy_message_converter import json_message_converter
import std_msgs.msg
from geometry_msgs.msg import *

msg = PolygonStamped()
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)

msg = PolygonStamped()
msg.header.frame_id = "map"
msg.polygon.points.append(Point32(1,2,3))
msg.polygon.points.append(Point32(4,5,6))
json = json_message_converter.convert_ros_message_to_json(msg)
print(json)
```
output
```
{"header": {"seq": 0, "stamp": {"secs": 0, "nsecs": 0}, "frame_id": ""}, "polygon": {"points": []}}
{"header": {"seq": 0, "stamp": {"secs": 0, "nsecs": 0}, "frame_id": "map"}, "polygon": {"points": [{"x": 1, "y": 2, "z": 3}, {"x": 4, "y": 5, "z": 6}]}}
```
【環境構築】「源ノ角ゴシック Code JP」のmacへのインストール方法

## 背景
- コードを記載する際に見やすいフォントにして、目があまり疲れないようにしたい。

## 目標
- macで「源ノ角ゴシック Code JP」を使用できるようにする。

## 「源ノ角ゴシック Code JP」について
- コーディング用に開発された「Source Code Pro」をベースに漢字を追加して開発されたフォントの模様。
- コーディングで嬉しいポイントとして、等幅フォントのため、可読性が高く、インテンドもズレて見えることが少ない気がする。

## macへのインストール方法
- 方法はいくつかあるが、自分ができた方法を記載する。

### 下記のgithubリポジトリにアクセス。
https://github.com/adobe-fonts/source-han-code-jp/tree/release

### 「Download ZIP」をクリック。
![github_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/afa8600a-0231-52ca-77f2-c9fae52458f5.png)

### Downloadしたzipに以下の画像の操作をする。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/791ae414-8724-e3d8-c1c2-14d214b185cc.png)

### macのアプリケーションからFontBookアプリケーションを開き、「源ノ角ゴシック Code JP」の文字があれば、インストールできている。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/2dac9a25-ce70-c2b8-8729-c12afa6e80a6.png)

## 参考資料

https://totonote.com/2021/01/21/install-source-han-code-jp-on-mac/

https://ics.media/entry/7010/

## 個人ブログ

https://takuma-tech.com/2022/09/28/454/
androidのgmailでHTMLメールでが崩れていた時の対処法

HTMLメールが他のメールソフトでは崩れていないのに、gmailのみフォントサイズや画像が大きくなっているなどの崩れが生じている場合があります。
これはgmailの「自動サイズ変更」による影響が考えられます。

# 原因：gmailの「自動サイズ変更」

gmailには「自動サイズ変更」という機能が存在します。
これにより、gmailが強制的にHTMLメールのテキストのフォントサイズや画像の幅を本来の数値より大きく表示することがあり、崩れを引き起こすことがあります。
また、androidとiOSでも表示が異なることがあり、andoridのgmailで見た時のみフォントが肥大化するなどのバグが見受けられます。

明確な原因は不明ですが、どうやらHTMLメールで使用されている画像の幅が関係ありそうです。

# 対処法

以下実際にandroidのgmailのみ崩れてしまった際、表示崩れが直った対処法です。

* すべてのimgタグにwidthを設定する

* すべてのimgタグにstyle="display:block;"を設定する

自動サイズ変更はユーザーの設定で無効にすることもできるため、どうしても崩れが修正されない場合はユーザーに自動サイズ変更の設定を無効にする手順を伝えるのも一つの手かもしれません。
参考：[Gmailで予約確認書のレイアウトが崩れるときの対処法【Android】 | ウィラコレ！](https://travel.willer.co.jp/willer-colle/10437/)
google colaboratoryでcondaコマンドを使い仮想環境をactivateする方法

### Minicondaのインストール
```
%%bash
MINICONDA_INSTALLER=Miniconda3-py39_4.9.2-Linux-x86_64.sh
MINICONDA_DOWNLOAD_HP=https://repo.anaconda.com/miniconda

MINICONDA_PREFIX=/usr/local
wget $MINICONDA_DOWNLOAD_HP/$MINICONDA_INSTALLER
chmod +x $MINICONDA_INSTALLER
./$MINICONDA_INSTALLER -b -f -p $MINICONDA_PREFIX
```
上記のコマンドをterminalに入力します。

### 使っているShellを確認する
```
echo $SHELL
```
```
＜出力＞
/bin/zsh
```
ならzshを、
```
＜出力＞
/bin/bash
```
ならbashを使っています。

### Shellに応じてconda init
zshを使っているなら
```
conda init zsh
```
bashを使っているなら
```
conda init bash
```
と入力しterminalを __再起動__ します
```
#終了コマンド
exit
```


これでconda activateコマンドが使えるようになります
rootユーザー以外でCost Explorerを見たい

# 設定方法

・rootユーザーでログインしアカウントの設定画面に移動。
・IAMアクセスのアクティブ化にチェックボックスを入れ、更新実施
・IAMユーザーに対して必要なポリシーをアタッチする事でrootユーザー以外でも請求情報を参照可能になる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516945/d9f42bf0-87c1-898c-b228-020191826e9f.png)

https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/control-access-billing.html#grantaccess
React + Rails + AWS Fargate の構成を実現したい - 07 バックエンドのCI導入(GitHub Actions)

# 目次

- [概要](#概要)
- [本記事のゴール](#本記事のゴール)
- [成果](#成果)
- [つまづいた点](#つまづいた点)
  - [1. yarnコマンドが見つからなくてエラー](#1-yarnコマンドが見つからなくてエラー)
    - [エラー内容](#エラー内容)
    - [解決策](#解決策)
  - [2. rakeコマンドで失敗する](#2-rakeコマンドで失敗する)
    - [エラー内容](#エラー内容)
    - [解決策](#解決策)

# 概要

https://qiita.com/memomaruRey/items/746f9cff0ceefe8b6157

# 本記事のゴール
以下を参考に、GitHub Actionsを用いたバックエンドのCI導入を行う。

https://codelabo.com/posts/20201128164634

# 成果

以下のように、ブランチにプッシュ後に、以下記事で書いたテストが実行されていることを確認した。

https://qiita.com/memomaruRey/items/8a11180578a5d270545d

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/081f7d58-464e-b866-6357-68a1a64dc1cd.png)

# つまづいた点
以下つまづいた点をメモする。

## 1. yarnコマンドが見つからなくてエラー

### エラー内容

```
Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "yarn": executable file not found in $PATH: unknown
```

### 解決策

以下でyarnコマンドをインストールする処理を **/backend/Dockerfile** に追加

```
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq
RUN apt-get install -y nodejs yarn
```

https://codelabo.com/posts/20201010192152

## 2. rakeコマンドで失敗する

### エラー内容
```bash
rake aborted!
Bundler::GemNotFound: Could not find msgpack-1.5.4 in any of the sources
```

### 解決策
以下を **/.github/workflows/ci.yml** に追加する

```diff_yaml
# 必要なアップデート
docker-compose run backend yarn install --check-files
docker-compose run backend yarn upgrade
+ # bundle installする
+ docker-compose run backend bundle install
# イメージのビルド
docker-compose build
```
M1 Macbook Proローカル環境でstable diffusionを動かすときのハマリポイント

## 基本的にはこちらの記事のとおりです。
ただ個々のMacの環境により色々ハマリポイントがあります。試される問題解決力。

https://zenn.dev/ktakayama/articles/6c627e0956f32c

## 事前に必要なファイルなど

huggingfaceでアカウントを登録して、学習モデルをローカルにダウンロードしておく。
* ローカルのMacで動かす場合、APIキーの発行は必要ありません。

× git リポジトリのクローン(`git clone https://huggingface.co/CompVis/stable-diffusion-v-1-4-original`)では、以下の学習モデルファイルはダウンロードされません。

https://huggingface.co/CompVis/stable-diffusion-v-1-4-original

こちらのページのDownload the weightsからブラウザでダウンロードしておきましょう。4Gぐらいあります。

元記事にはfunctional.pyのコードを変更したりしていましたが、以下の最新版のpython環境では不要でした。

## Macのローカルにpython,pipがインストール(PATHが通ってないと）ダメ

普段pythonを使ってない人はMacにpythonが入ってないか、古いか、PATHが通ってないかもしれません。
成功した環境はこれです。

```
% which python
/opt/homebrew/Caskroom/miniconda/base/bin/python
% which pip   
/opt/homebrew/Caskroom/miniconda/base/bin/pip
% python -V
Python 3.9.12
% pip -V   
pip 22.1.2 from /opt/homebrew/Caskroom/miniconda/base/lib/python3.9/site-packages/pip (python 3.9)
```

以下、実行時によくあるエラーを適当に書いておきます。

## CondaValueError: prefix already exists: /opt/homebrew/Caskroom/miniconda/base/envs/ldm

```
rm /opt/homebrew/Caskroom/miniconda/base/envs/ldm
```

で設定ファイルを消してリトライ。

## × python setup.py egg_info did not run successfully.
```
  │ exit code: 1
  ╰─> [7 lines of output]
      fatal: not a git repository (or any of the parent directories): .git
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/private/var/folders/s_/j72vzw_97dz5m5q3d_92v0300000gp/T/pip-install-6lm87yc_/onnx_7359b42ce2d44376812d41c13aebe304/setup.py", line 81, in <module>
          assert CMAKE, "Could not find cmake executable!"
      AssertionError: Could not find cmake executable!
      [end of output]
```

`brew install cmake`
`pip install --upgrade pip setuptools`などして最新版にしたら通りました。

## FileNotFoundError: [Errno 2] No such file or directory: 'models/ldm/stable-diffusion-v1/model.ckpt'

学習モデルは正しくダウンロードされていますか？
シンボリックリンクは正しく通っていますか？※元ディレクトリが相対パスだとダメ

```
mkdir -p models/ldm/stable-diffusion-v1/
ln -s /path/to/ckpt/sd-v1-1.ckpt models/ldm/stable-diffusion-v1/model.ckpt
```

## Enjoy!

![grid-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266846/8638914c-a5ac-d0b7-bb1e-48297ce5c836.png)
![grid-0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266846/b785a240-66dc-0e0d-4842-e2e1287ea575.png)
![grid-0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266846/8ccfa8a6-51d3-4e12-efae-28e5b70c7d30.png)

まぁそのうちブラウザからpromptも叩けるDockerコンテナがダウンロードできるようになるんじゃね？
環境が作れない人は、おとなしくそれを待ちましょう。
親の li タグ要素から子の div タグ要素がはみ出る

### はじめに
詳細な状況としては、liタグの子要素のdivブロックが親要素のliから何故かはみ出してしまっていた。そのため、liタグに設定した擬似要素が期待する位置に表示されなかった。（はみ出したdiv要素に被る）

理由を考察する。まず、liタグとdivの要素の違いではみ出してしまっているのかも？
### ブロック要素とインライン要素の違いについて
- ブロック要素
  - ブロック要素にはその前後で改行が入る
  - ブラウザで縦並びとして表示されて、幅や高さや余白などを設定できる
  - li, p, div, h1 など 
- インライン要素
  - インライン要素には改行が入らない
  - 横並びに表示され、幅や高さや余白などが適応できない時がある
  - span, aタグ など

同じブロック要素なので、要素の違いではなさそう。。
そもそもliタグにdiv要素入れても良いのだろうか？
### li タグの中にdivタグを入れても良いのかについて
- liタグには上記ブロック要素もインライン要素も基本的にはどれでも入れても良いらしい
https://www.tohoho-web.com/html/li.htm

### 結論
親要素のliタグに height を設定していた。それを削除すると子要素のdivの高さを含むようになった。
どこかに height を指定しないかを確認しても良いかも。
【Git】メールアドレスを非公開にする

## はじめに

以下のようなコマンドを実行することで`~/.gitconfig`や`~/.config/git/config`の`user.email`で設定しているメールアドレスが表示されます。  

```zsh:ターミナル
$ git log --pretty=fuller    
commit 2wf60faofewao1c00af12b3dd69d93900cd1156d (HEAD -> main)
Author:     UserName <e-mail@example.com>
AuthorDate: Thu Aug 18 09:26:25 2022 +0900
Commit:     UserName <e-mail@example.com>
CommitDate: Thu Aug 18 09:26:25 2022 +0900

    chore: delete docker-compose.yml

commit 75dweioj7ce834dd2ffjaofjewb92839dbec4254 (origin/main)
Author:     UserName <e-mail@example.com>
AuthorDate: Sun Aug 14 15:30:22 2022 +0900
:
```

上記で表示されるメールアドレスをダミーに変更する方法について記載します。

## メールアドレスを非公開に設定

GitHub上でメールアドレスを非公開に設定します。

GitHubを開き「右上のユーザーアイコン」→「Settings」→「サイドバーのEmails」の順にクリックします。  

開いたページで以下の赤枠の2つにチェックを入れます。

![設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/f45072d2-cc31-32df-62ee-279eb6a4c05a.png)


2つの項目を翻訳すると下のようになります。
* 上の項目

>メールアドレスを非公開にする  
>ウェブベースの Git 操作 (例: 編集やマージ) やメール送信を代行する際には、あなたの公開プロファイルのメールを削除して 00000000+UserName@users.noreply.github.com を使うことになります。コマンドラインのGit操作で非公開の電子メールを使いたい場合は、Gitで電子メールを設定する必要があります。

* 下の項目

>メールアドレスを公開するコマンドラインプッシュをブロックする  
>GitHub にプッシュすると、直近のコミットがチェックされます。もしそのコミットの作者のメールアドレスがあなたの GitHub アカウントの非公開メールアドレスだった場合は、そのプッシュをブロックして非公開メールアドレスの公開について警告を出します。

## Gitの設定を変更

上記の設定だけではターミナルで`git commit`を実行した際、非公開にしたメールアドレスが使用されてしまいます。
そのためGitの設定を変更する必要があります。

変更するためには以下のコマンドを実行します。
`数字+アカウント名@users.noreply.github.com`の部分には下画像の赤線部分に置き換えます。

```zsh:ターミナル
git config --global user.email "数字+アカウント名@users.noreply.github.com"
```

![メールアドレスの場所](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6ef00ac8-1f7b-784f-ba35-0f948e948ba3.png)
Wikipediaのレイアウトの横幅が狭いのでCSS上書きで広くしてみた

## はじめに

Wikipedia （ウィキペディア） のデザインレイアウトの横幅が狭くて耐えられないので広くしてみました。現時点で期待通りに動いていますが、将来の wikipedia 側のデザイン変更で使えなくなる可能性があります。ご利用は自己責任でどうぞ。

### Before

![スクリーンショット 2022-08-27 14.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54918/62008069-8134-45af-2e2b-b86cfd067ae4.png)

### After

![スクリーンショット 2022-08-27 14.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54918/3c0d239e-ef37-3af2-444d-d5953ac347e8.png)

## 手順

### 1. Chrome に Stylus をインストール

https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja

### 2. Stylus の管理画面を開いて新スタイルを作成する

### 3. 次のようなスタイルシートを書く

最終更新日 2023-04-23

**注意** 全画面にするには右下のボタンをクリックして幅を広げてください

```css
@-moz-document domain("wikipedia.org") {
    #content {
        font-size: 90%;
    }
    .vector-feature-limited-width-enabled .mw-body {
        grid-template-columns: minmax(0,74em) min-content;
    }
    .vector-feature-limited-width-disabled .mw-body {
        grid-template-columns: none;
    }
    .mw-page-container-inner  {
        grid-template-columns: 220px minmax(0,1fr);
        column-gap: 0px !important;
    }
    .mw-page-container {
        padding-left: 1em;
        padding-right: 1em;
    }
    .vector-feature-toc-pinned-enabled #mw-panel-toc {
        margin-left: -8px;
    }
    .vector-toc-link .vector-toc-text {
        width: auto !important;
    }
    #vector-toc {
        font-size: 14px;
    }
    #vector-toc:after {
        background: none !important;
    }
    #vector-toc-pinned-container .vector-toc {
        padding-top: 0;
        padding-right: 0;
    }
    .vector-settings {
        opacity: 0.4;
    }
    .vector-settings:hover {
        opacity: 1;
    }
}
```
Spring Boot + Thymeleaf の template resolving でハマった

## 環境

* IntelliJ
* Spring Boot 2.7.3
* Thymeleaf
* Kotlin 1.6.21

## 概要

以下の手順で Spring Boot + Thymeleaf を利用した画面有りの Web アプリケーション作成を試みた．

1. Spring Initializr で gradle プロジェクトを作成
1. ローカル環境で html や kt など諸々のファイルを作成
1. IntelliJ でアプリケーションを実行し，Web ブラウザで `localhost/xxx` にアクセスすると問題なく画面が表示される
1. `gradlew build` を実行して出力した jar ファイルを実行して，Web ブラウザでアクセスすると以下のエラーが発生

```
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/xxx/yyy], template might not exist or might not be accessible by any of the configured Template Resolvers
```

つまりテンプレートが存在しないか，アクセス権限がないらしい．

でも Intellij で実行した場合には問題なく画面が表示されていた．何故？

## 結論

```kotlin
fun getTop(
  modelAndView: ModelAndView
): ModelAndView =
  modelAndView.apply {
    viewName = "/xxx/yyy"
  }
```

誤: `viewName = "/xxx/yyy"`
正: `viewName = "xxx/yyy"`

Intellij で実行した場合やコマンド `gradlew bootrun` で実行した場合には，`viewName` の先頭に `/` が付いていてもよしなに解決してくれるらしい (理由調査中)．
React + Rails + AWS Fargate の構成を実現したい - 05 バックエンドのテスト整備編(RSpec)

# 目次

- [概要](#概要)
- [本記事のゴール](#本記事のゴール)
- [成果](#成果)
  - [テストに成功する場合](#テストに成功する場合)
  - [テストに失敗する場合](#テストに失敗する場合)
- [つまづいた点](#つまづいた点)

# 概要

https://qiita.com/memomaruRey/items/746f9cff0ceefe8b6157

# 本記事のゴール
以下を参考にバックエンドのテスト整備を行う。

https://zenn.dev/hibriiiiidge/books/49ee4063b10cec1df1a2/viewer/f8fbf49145c733a81dfc

# 成果

以下コマンドにより、テストを実行できるようになった。

## テストに成功する場合
```bash
bundle exec rspec
..

Finished in 0.03596 seconds (files took 2.09 seconds to load)
2 examples, 0 failures
```

## テストに失敗する場合
```bash
bundle exec rspec
.F

Failures:

  1) Task#valid? タイトルがnilの場合 is expected to be falsy
     Failure/Error: it { is_expected.to be_falsy }
     
       expected: falsey value
            got: true
     # ./spec/models/task_spec.rb:16:in `block (4 levels) in <top (required)>'

Finished in 0.03577 seconds (files took 0.72953 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/models/task_spec.rb:16 # Task#valid? タイトルがnilの場合 is expected to be falsy
```

# つまづいた点

特になし。参考記事通りに構築を進めることでテスト環境を整備できた。
サービスをグローバルIPレスでシェアできるようにする

[remote.it](https://www.remote.it/)を使って、構築したサービスを内輪でシェアできるような構成を試してみました
短期的に特定の利用者にサービスを使ってもらうようなシーン（ワークショップなど）に有効な気がします

## はじめに
記載している構成では以下に重点を置いています  
- VMにグローバルIPを割り当てない
- VMのセキュリティルールでサービスが使用するポートを開放しない
- remote.itのエージェントを入れるVMは1つだけにする
    - エージェントを入れられないVM(アプライアンス製品とか)に使用できる

特定のPCからのアクセスしか許容しないということはできません。
URLさえわかればアクセス可能ですので試す際は十分ご注意ください

なお、remote.itを使ってみれば設定できると思いますので詳細な手順については記載していません。

## 実行環境
Azureに作成したUbuntu VMを使用していますが、ほかのクラウドベンダー&OSでも特に差支えありません。

## 環境の構成イメージ
- VMの設定はグローバルIPを割り当てていない
- jump-server以外のVMで起動しているサービスは、jump-serverにポートフォワードしている
- remote.itの設定：サーバーエージェントをjump-serverに設定し、ブラウザから各種サービス設定をしている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/ae70a7da-1f31-accd-f96d-9fed12295ddc.png)

## 接続イメージ
以下は、Rundeckサービスにアクセスしています。
remote.itで接続した際に`http://xxxxyyy.io`とURLが表示されるので、それを利用者にシェアすれば完了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/289473ff-2935-4ae9-0fbd-34c34c628e3d.png)

## 環境構成の詳細
一部ですが、実際の設定内容について詳細を記載します

### VMの設定はグローバルIPを割り当てない
以下は、jump-serverの設定ですがすべてのVMを同じ設定にしています
- グローバルIPは割り当てていない
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/d58a4125-3a86-a807-3f3d-55b9f70b571b.png)
- セキュリティルールは外部に対する許可設定をしていない
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/3ec2a601-bca2-18dd-c710-92387681e17c.png)

### jump-server以外のVMで起動しているサービスは、jump-serverにポートフォワードする
以下のようにjump-serverからポートフォワードをすることで、remote.itのエージェントをjump-serverだけになるようにしています
```bash
aki-nasu@jump-server:~$ ps -ef |grep ssh
aki-nasu    5538       1  0 01:52 ?        00:00:00 ssh -gL 4440:10.0.0.5:4440 aki-nasu@10.0.0.5 -i .ssh/id_rsa -Nf
aki-nasu    8365       1  0 02:25 ?        00:00:00 ssh -gL 18080:10.0.0.6:8080 aki-nasu@10.0.0.6 -i .ssh/id_rsa -Nf
```

### remote.itの設定
Service Typeについて、GuacamoleをHTTPにして、ほかのサービスはTCPにしています。同じHTTPに設定すると同時接続ができません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/db2ba803-cca5-4c14-582a-673846076c0b.png)

設定内容はこのような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/8cac9fcf-fd20-6d31-94c0-6637c888e779.png)

### おわりに
軽く使ってみた程度なので、認識に誤りがあればご指摘ください。
ほんとうは開発環境をセキュリティを気にせずに建てたくて、特定の端末からしか接続できないような使い方をイメージしていました。
自端末にもエージェントを入れればいいんですかね。

### 参考
環境構成のなかで登場しているサービスの公式ページ
- [remote.it](https://www.remote.it/)
- [Apache Guacamole](https://guacamole.apache.org/)
- [Jenkins](https://www.jenkins.io/)
- [Rundeck](https://www.rundeck.com/)
【SpringWebflux/Kotlin】手動でトランザクションを有効にして処理を行う【R2DBC】

# TL;DR
- `TransactionalOperator.transactional`を使うと簡単
  - 処理の中での`suspend`関数呼び出しは`mono`関数でラップするのが簡単

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/reactive/TransactionalOperator.html

# やり方
サンプルコードは以下の通りです。

```kotlin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.reactor.awaitSingle
import kotlinx.coroutines.reactor.mono
import org.springframework.stereotype.Component
import org.springframework.transaction.reactive.TransactionalOperator

@Component
class TransactionOperation(private val transactionalOperator: TransactionalOperator) {
    // 中にそのまま処理を書く場合
    suspend fun operation() {
        transactionalOperator
            .transactional(
                mono {
                    /* ここにやりたい処理（DBアクセスを行うsuspend関数の呼び出しなど）を書く */
                }
            ).awaitSingle()
    }
}
```

`Kotlin`から扱いやすくするため、以下のような`util`を用意するのもおすすめです。

```kotlin
// Tそのものは上界無指定 = nullableだが、awaitSingleOrNullがT?を返してしまうため、キャストしている
@Suppress("UNCHECKED_CAST")
suspend fun <T> TransactionalOperator.transactional(block: suspend CoroutineScope.() -> T): T =
    transactional(mono(block = block)).awaitSingleOrNull() as T

// 以下のように利用できる
suspend fun foo() { /* トランザクション内で実行したい処理 */ }
suspend fun bar() {
    // トランザクションを有効にしてfooを呼び出す
    transactionalOperator.transactional { foo() }
}
```

## TransactionalOperatorの取得について
`TransactionalOperator`は、自分の環境では`Autowire`して利用できました。
また、[`ReactiveTransactionManager`から生成することもできます](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/reactive/TransactionalOperator.html#create-org.springframework.transaction.ReactiveTransactionManager-)。
addEventListener

使い方の流れ

①オブジェクトを取得
ex.
`
const btn1 = document.getElementById("btn1");
`

②イベントハンドラ(特定のイベントが起こった時に実行する処理を決めたもの)を実装
ex.
`
btn1.addEventListener("click",output);
`

③関数を定義

無名関数を使う場合：
イベントハンドラで処理を実装


処理が多い場合：
イベントハンドラの外で関数を定義
（scryptタグの中で）

`
function output(e) {
console.log(e);
}
`
Auth0 ソーシャルログイン追加方法 メモ

# Auth0 ソーシャルログイン追加方法 メモ

* Auth0を利用する際にソーシャルログイン機能を有効にする方法をメモする。

## Auth0コネクション

* Auth0では、認証方法(ログイン)方法をコネクション（connection)と呼ぶ。

* コネクションは次の種類に分類される。

  * Database Connection
  * **Social Login**
    * TwitterやFacebookなど外部のIDプロバイダーでログインする方法を指す。
  * Enterprise Directory
  * Passwordless

  

## ソーシャルログイン追加手順

* Auth0ダッシュボード→「Authenticaiton」→「Social」を選択

* 「Create  Connection」を押下

* 連携用ソーシャルサービスを選択する※今回はTwitterを選択

  ![auth0-social.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/001a41e9-5d63-b7ab-407d-66b55ad0b51d.png)


* コンシューマーAPIキーを入力

  * ※事前にTwitterデベロッパーコンソールよりアプリケーション登録＋APIキー発行

    ![auth0-twitter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/2693bbfc-8cc5-8143-d196-19d3650361dc.png)


* コネクションを利用するアプリケーションを選択

  ![auth0-twitter-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/9203c14c-30cd-e637-86c6-62facbf596b1.png)


## 動作確認

* Auth0ログイン画面に遷移すると以下のように「Continue with Twitter」が追加されていることが確認できる。

  ![auth0-login-social.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/677ff90f-281b-be68-5539-1df222fabb8e.png)
Auth0を用いたVue.jsアプリへのログイン機能導入方法 メモ


* 認証基盤サービス(IDaaS)のAuth0を使ってVue.jsアプリにログイン機能を追加する方法についてメモする。

## 事前準備

* [Auth0](https://auth0.com/jp) アカウント登録＋ログイン
  * 無料トライアル版で実施

## アプリケーション登録+サンプル取得

* ダッシュボード/アプリケーション管理画面より「Create Application」を選択
  * <https://manage.auth0.com/dashboard/us/{YOUR_TENANT_ID}/applications>
* アプリケーション名を入力し、「Single Page Application」を選択して「Create」を押下
* 使用言語として「Vue」を選択
* 「Download Sample」を選択し、Vue.jsサンプルを取得
* ダッシュボード/アプリケーション管理画面より作成したアプリケーションを選択し、以下の項目に<http://localhost:3000>を入力し、保存する。
  * Allowed Callback URLs
  * Allowed Logout URLs
  * Allowed Web Origins

## SDKインストール

```shell
npm install @auth0/auth0-vue
```



## 動作確認

* ダウンロードしたサンプルディレクトリで以下のコマンドを実行する。

  ```shell
  npm run serve
  ```

  ※<http://localhost:3000>でアプリが起動する。

* <http://localhost:3000>にアクセスし、「Login」を押下

  ![vue-auth0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/4fe9ca9c-0d6c-606e-45a4-86a15f52536c.png)


* 下記Auth0ログイン画面が表示されるので、ログインする。

  ![auth0-login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/698807d4-44fa-08ff-8897-941d54f17512.png)

  

## 参考情報

* [Vue: Login](https://auth0.com/docs/quickstart/spa/vuejs/01-login)
React + Rails + AWS Fargate の構成を実現したい - 04 フロントエンドのテスト整備編

# 目次

- [概要](#概要)
- [本記事のゴール](#本記事のゴール)
- [成果](#成果)
- [作業メモ](#作業メモ)
  - [1. テストコード](#1-テストコード)
  - [2. docker実行コマンド簡素化](#2-docker実行コマンド簡素化)

# 概要

https://qiita.com/memomaruRey/items/746f9cff0ceefe8b6157

# 本記事のゴール
以下を参考にフロントエンドのテスト整備を行う。

https://dev-yakuza.posstree.com/react/nextjs/test/#%E3%83%86%E3%82%B9%E3%83%88%E3%82%B3%E3%83%BC%E3%83%89%E4%BD%9C%E6%88%90

# 成果

以下のように、フロントエンドのテストができる状態にできた。

```bash
npm run test

> src@0.1.0 test
> jest

info  - SWC minify release candidate enabled. https://nextjs.link/swcmin
info  - SWC minify release candidate enabled. https://nextjs.link/swcmin
 PASS  __tests__/index.test.jsx
  Home
    ✓ renders a heading (103 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.261 s
Ran all test suites.
```

# 作業メモ

## 1. テストコード

画面上の表示文字列が**Sample Next.js App**と一致していることを確認するテストコード

```/frontend/src/__tests__/index.test.jsx
import { render, screen } from '@testing-library/react'
import Home from './../pages/index'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: /Sample Next.js App/i,
    })

    expect(heading).toBeInTheDocument()
  })
})
```

## 2. docker実行コマンド簡素化
Makefileに以下を追加し、コンテナに入るコマンドを簡素化

```diff
du:
	docker-compose up -d --build
+ df:
+ 	docker-compose run --rm frontend /bin/bash
+ db:
+ 	docker-compose run --rm backend /bin/bash
dd:
	docker-compose down
```
【MySQL学習】実行計画を読み取れるようになる

# はじめに
MySQLの実行計画について学習したことを簡単にまとめます。

# 検証に使用した環境
DB：MySQL8.0

# クエリを実行するまで
MySQLには、クエリを実行するまでに以下の処理があります。

```
クエリ解析
↓
実行計画策定
↓
実行
```

## 実行計画策定
オプティマイザがクエリの実行方法を計画し、「EXPLAIN」を使用することで実行計画を確認できます。

## オプティマイザの判断基準
オプティマイザは、統計情報やインデックスなどに基づき実行内容を計画します。
基本的にインデックスを使う方法が効率的です。
インデックスが複数ある場合は、どのインデックスを使用すると効率的か判断することになります。

[注意]
カーディナリティが低い場合はインデックスの効果は低くなります。
そのため、この特性を考慮する必要はあります。

### カーディナリティの高低
特定のカラムに登録されているデータの種類の数で決まります。

・カーディナリティが高い
→テーブルの中で、対象カラムに登録されているデータの種類が多い状態
（一位性が高いとも言います）
・カーディナリティが低い
→テーブルの中で、対象カラムに登録されているデータの種類が少ない状態

# EXPLAIN
クエリの実行計画を出力します。
※クエリ自体は実行されません

```shell
EXPLAIN クエリ;
```

実行計画を出力できるステートメントは、以下の5つになります。
・select
・delete
・insert
・replace
・update

EXPLAINは、クエリで使用される各テーブルに関する情報を出力します。
クエリを処理する上でテーブルを読み取る順番に出力され、内容は1テーブルにつき1行で表現されます。

## 表示される項目
### id
クエリー内のselectの連番を示し、select識別子と呼ばれます。

### select_type
selectの種類が表示されます。
基本は「simple」が表示され、他の種類は[こちら](https://dev.mysql.com/doc/refman/8.0/ja/explain-output.html#explain_select_type)に記載されています。

### table
出力行で参照しているテーブル名が表示されます。

### partitions
クエリーでレコードが照合されるパーティションが表示されます。
パーティショニングしていない場合はnullとなります。

### type
テーブルの結合方法が示され、効率の良い順に以下が表示されます
※一部抜粋
#### const（主キー、またはUNIQUEインデックス）
主キー、またはUNIQUEなカラムでテーブルに該当するレコードが1つとなるため、クエリーの開始時に読み取られる状態です。
レコードが1つしかないため、このレコードのカラムの値は、オプティマイザの残りによって定数とみなされることがあります。
constテーブルは、1回しか読み取られないため、非常に高速です。

#### eq_ref（JOINで主キー、またはUNIQUEインデックス）
結合元のテーブルの行に対し、このテーブルから「1レコード」が読み取られる状態で、systemとconst型以外では、最適な結合型です。
結合でインデックスのすべてのパートが使用されており、インデックスが「PRIMARY KEY」または「UNIQUE NOT NULL」インデックスである場合に使用されます。

#### ref（UNIQUEじゃないインデックスで結合）
結合元のテーブルの行に対し、このテーブルから単一のレコードを選択できず、一致する「インデックス値を持つすべてのレコード」が読み取られる状態です。
refは、結合でキーの左端のプリフィクスのみが使用される場合、またはキーが「PRIMARY KEY」や「UNIQUE」インデックスではない場合に使用されます。
使用されているキーがほんの数行にしか一致しない状況であれば、適切な結合型と判断できます。

#### range（インデックスを使った範囲検索）
インデックスを使用して、絞り込みたい範囲のレコードを取得している状況です。

#### index（インデックスをフルスキャン）
インデックスツリーをスキャンしていること以外、ALLと同じです。
クエリーで単一のインデックスの一部のカラムのみが使用されている場合に、この結合型となる場合があります。

**Extraカラムに「Using index」と表示されている場合**
インデックスがクエリーのカバリングインデックスで使用することで、テーブルから必要なデータを全て取得できる場合はインデックスツリーのみがスキャンされます。
インデックスのサイズは通常テーブルデータより小さいため、インデックスのみのスキャンは通常、ALLより高速です。

**Extraカラムに「Uses index」が表示されていない場合**
フルテーブルスキャンとなっている状況です。
インデックスからの読み取りにより、インデックス順でレコードを読み取っていきます。

#### ALL（インデックスを使わずテーブルを全部見る）
結合元のテーブルの行との組み合わせごとインデックスを使わずテーブルをスキャンし、著しく効率の悪い状況です。
定数値または結合元のテーブルからのカラム値に基づいて、インデックスを追加することと回避できます。

### possible_keys
採用可能なインデックスが表示されます。

### key
採用されたインデックスが表示されます。

### key_len
採用されたキーの長さが表示されます。
キー長が短い方が高速になります。

### ref
テーブルからレコードを選択するために、インデックスと比較されるカラム名または定数が表示されます。

### rows
クエリーを実行するために走査が必要と想定される行数が表示されます。
※InnoDBの場合、推定値となります。

### filtered
テーブルのレコード全体から条件で絞り込まれた後のレコード数の推定割合(%)が表示されます。
全く絞り込みされなかた場合を最大値の100とし、絞り込まれるにつれて数値が下がります。

たとえば、
rowsが1000行でfilteredが50.00(50%)の場合、次のテーブルと結合される行数は「1000行 × 50% = 500行」になります。

### Extra
クエリーを処理するための追加情報が表示されており、スロークエリ対策に有用な情報が表示されるため、とても重要な項目になります。
各表示内容の説明は[こちら](https://dev.mysql.com/doc/refman/8.0/ja/explain-output.html#explain-extra-information)

# 参考文献

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

https://dev.mysql.com/doc/refman/8.0/ja/explain-output.html