OmniAICreator/Qiita-1.07M huggingface dataset:
ddweatherの不具合修正

# はじめに

conkyでお天気を表示するconky_ddweatherにて天気が表示されなくなった不具合を修正した

# 環境
Linux Mint 21(おそらく他のものでディストリビューションでも問題ない)
git
Lua 5.3.6
conky 1.12.2-1
conky_ddweather（公式web: https://github.com/ddittmar/conky_ddweather）

# conky_ddweatherソースの取得
git cloneにて参考になるソースを自分の作業ディレクトリに移行する。

```
$git clone https://github.com/ddittmar/conky_ddweather
```

# conky_ddweatherの設定
conkyそのものの設定やddweatherの地域や言語の設定は公式に従う。

# 不具合箇所の修正場所
conky_ddweather内のddweather.luaにある。
+ get_current_weather_value( ... )
+ get_forecast_value( ... )

の各関数を以下のように修正する。


```ddweather.lua
-------------------------------------------------------------------------------
--                                                    get_current_weather_value
-- helper function to navigate the current_weather table
--
function get_current_weather_value( ... )
    local result = current_weather
    local n = { ... }
    for _,key in pairs(n) do
        result = result[key]
        print(key)
    end
    return result
end -- get_current_weather_value


-------------------------------------------------------------------------------
--                                                           get_forecast_value
-- helper function to navigate the forecast table
--
function get_forecast_value( ... )
    local result = forecast
    local n = { ... }
    for _,key in pairs(n) do
        if result[key] == nil then
            result = {}
        else
            result = result[key]
        end
        print(key)
    end
    return result
end -- get_forecast_value
```
# 原因
Luaのバージョンアップか、openweathermapのデータ形式が変わったことではないかと思っている。
元のコードでは値がない(nil)となってしまう。
openwethermapで直接APIを叩くとJSON形式で気象データが取得できる。
get〜_valueの各関数は引数を参考にして各種気象データを抜き出す。だが、気象データが入っている連想配列と配列のindexがうまく行っていない。
また、雨の情報がない予報の場合もある。従来はrain:{}と情報があったが、削除されていたため対応した。
そこでデータと突き合わせて各関数を修正すると問題なくデータを取得できた。


# 感想
Luaはあまり触っていないためよくわからなかった。エラー出ているけどとりあえず使えることを目指して修正した。
pairsとipairsとfor文がうまく噛み合っていないようだった。
conkyは面白いけどLuaベースなので馴染みがない。それでも使ってしまうかっこよさがあると思っている。

# 参考
openweathermap https://openweathermap.org/
conky_ddweather（公式web: https://github.com/ddittmar/conky_ddweather）
throughを使ってアソシエーションをスッキリさせる！！

## はじめに
フォロー機能を実装したらthroughこの文言が出てきたので色々調べてみた。
今回は前に実装していた、いいねした投稿一覧をthroughを使ってスッキリさせていこうと思う。
割と丁寧に解説したと思うので、少しでも参考になれば幸いです。

### 使用する環境
- MacOS(Intel)
- Rails 6.0.3
- Ruby 2.6.3
- yarn 1.22.17
- Homebrew 3.5.0


## まず結論から

まずUserモデルの編集
Before
```user.rb
has_many :posts, dependent: :destroy
has_many :favorites, dependent: :destroy
```

After
```user.rb
has_many :posts, dependent: :destroy
has_many :favorites, dependent: :destroy
has_many :likes, through: :favorites, source: :post # 追加
```

Before
```users_controller
def favorite_list
   favorites = Favorite.where(user_id: current_user.id).order(updated_at: :desc).pluck(:post_id)
   @post_favorites = Post.find(favorites)
end
```

After
```users_controller
def favorite_list
   @post_favorites = current_user.likes
end
```

## コードの解説
こちらのコードの解説をしていきます。
目的は：ログインしてるユーザーがいいねした投稿一覧が欲しい

まず、ログインしてるユーザーをAさんとして、
Aさんのいいね一覧を取得しようとしたら、current_user.favoritesで取得できると思います。
ただ、これだと私のDB設計だと投稿一覧を取得はできません。
私の場合は、下記のような形になります。
これは、いいねした投稿のIDとその投稿を誰がいいねしたかのuser_id（今回例だとログインしてるユーザー）になります。

```
=> [#<Favorite:0x0000000107926a50 id: 362, user_id: 13, post_id: 38, created_at: Mon, 08 Aug 2022 05:13:56.783515000 UTC +00:00, updated_at: Mon, 08 Aug 2022 05:13:56.783515000 UTC +00:00>,
 #<Favorite:0x000000010796cf28 id: 380, user_id: 13, post_id: 37, created_at: Thu, 11 Aug 2022 01:29:59.467057000 UTC +00:00, updated_at: Thu, 11 Aug 2022 01:29:59.467057000 UTC +00:00>,
 #<Favorite:0x000000010796cdc0 id: 426, user_id: 13, post_id: 39, created_at: Thu, 11 Aug 2022 15:47:55.832642000 UTC +00:00, updated_at: Thu, 11 Aug 2022 15:47:55.832642000 UTC +00:00>]
```
本当は、下記のような形で書きたいのですけど、エラー出ます。
でも、throughを使えば下記のような形でスッキリ書くことができるのです。
```
current_user.favorites.posts
```

再度userモデルに書いたのをみていきましょう。
```user.rb
has_many :likes, through: :favorites, source: :post
```
これは、user→favorites→postsというアソシエーションに、likesという別名をつけています。
likesだけだとlikesテーブルを参照しに行ってしまうため、source: :postをつけてpostsテーブルを参照するようにしています。
この書き方は初めてみると少しわかりにくいかもしれませんが、要は、あるUserがいいねした投稿を取得できると考えると少しはわかりやすいかもしれません。（わかりにくかったらすみません）

これを追記したら、あとは簡単です。
先ほど追記したコードでUserがいいねした投稿一覧をlikesで取れるようになってるので好きなアクションの中で、下記のようにすれば取得できます（勿論ログインしてるユーザー以外のも取れます。）
```
current_user.likes
```

ちなみに前までは下記のように書いてたのでだいぶスッキリしましたね！
```
favorites = Favorite.where(user_id: current_user.id).pluck(:post_id)
@post_favorites = Post.find(favorites)
```

### おまけ(外部のテーブルを参照)
いいねした投稿を降順（新しい順）に並べる方法
```
@post_favorites = current_user.likes.order("favorites.created_at DESC")
```

## 最後に
上手く説明できなかったところもあるかもしれませんが、少しでもお役になったら幸いです
参考にさせていただいた記事:https://qiita.com/tanutanu/items/2a27f1e503c4cbf30928
gitで.git/index.lock: File exists.というのエラーが出た時の対処方法。

```fatal: Unable to create 'C:・・・・・・.git/index.lock': File exists.
Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.
```
と表示されたので、エラーを読んでみると、index.lockを削除すればいいらしいです。
でも、削除の仕方がわからなかったので、調べてみると、windowsでは、
```
del .git\index.lock
```
とコマンドを打てばよいとのこと。実際にやってみるとできたので、もし同じところで詰まっているなら、参考にしてほしいです。

Macの場合は、
```
rm .git/index.lock
```
らしいです。
MEXC シンボル一覧(2022/08/12)

|symbol  |state  |countDownMark  |timeZone  |fullName  |symbolStatus  |vcoinName  |vcoinStatus  |price_scale  |quantity_scale  |min_amount  |max_amount  |maker_fee_rate  |taker_fee_rate  |limited  |etf_mark  |symbol_partition  |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|IQ_EOS|ENABLED|0|Asia/Singapore|Everipedia|1|IQ|1|7|2|1|20000|0.002|0.002|False|0|NEW|
|WIN_TRX|ENABLED|0|Asia/Singapore|WINK|1|WIN|1|6|2|100|1000000|0.002|0.002|False|0|NEW|
画像の一部を黒塗りでマスクする方法

Pythonでは、NumPyのスライスを使うことで、OpenCVで読み込んだ画像の一部分だけに処理を施すことができるらしい。
今回のサンプルでは、画像の「左下」と「右上」の黒塗りでマスクしてみる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/ef50f59f-bf2b-b5e3-16b8-e89837038064.jpeg" width=300px>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/41934c71-33ce-a9fe-5a5a-9dd66a084ed6.jpeg" width=300px>

#### マスク処理

```python
import numpy as np
import cv2

# ファイルから画像を読み込む
im = cv2.imread("input2.jpg")

# マスク画像の幅・高さ
w, h = 250, 90

# 左下から処理（座標を指定）
x, y = 0, im_h-h

# 読み込んだ画像の一部を黒塗り（画素値はグレースケールの８ビットで指定 0〜255(黒〜白)）
# ※numpyのスライス
im[y:y+h, x:x+w] = 0

# 次に右上を処理
x, y = im_w-w, 0
im[y:y+h, x:x+w] = 0

# ファイルに画像を書き込む
cv2.imwrite("output.jpg", im)
```

#### リサイズする方法

```python
scale_percent = 40 # オリジナル画像に対する割合（%）
width = int(im.shape[1] * scale_percent / 100)
height = int(im.shape[0] * scale_percent / 100)
dim = (width, height)
  
# resize image
resized = cv2.resize(im, dim, interpolation = cv2.INTER_AREA)

print('Resized Dimensions : ',resized.shape)
cv2.imwrite("resize.jpg", resized)
```

#### 複数ファイルをまとめて処理する場合

```python
import numpy as np
import cv2
import glob

for fn in glob.glob('input_images/*'):
  im = cv2.imread(fn, cv2.IMREAD_COLOR)
  im_h, im_w, _ = im.shape  # オリジナル画像のサイズ
  w, h = 250, 90  # マスク画像のサイズ
  # 左下
  x, y = 0, im_h-h
  im[y:y+h, x:x+w] = 0
  # 右上
  x, y = im_w-w, 0
  im[y:y+h, x:x+w] = 0
  cv2.imwrite('output_images/' + fn.split('/').pop(), im)
```

#### 文字を重ねる場合

```python
  cv2.putText(im,
              text='SAMPLE',
              org=(x, y),
              fontFace=cv2.FONT_HERSHEY_SIMPLEX,
              fontScale=2.0,
              color=(255, 255, 255),
              thickness=4,
              lineType=cv2.LINE_8)
```

# 参考にしたページ

* https://docs.opencv.org/4.x/index.html
* https://note.nkmk.me/en/python-opencv-pillow-image-size/
* https://algorithm.joho.info/programming/python/opencv-partial-processing-py/
* https://shikaku-mafia.com/opencv-puttext/
複数枚画像のスライド機能実装(carrierwaveとswiper使用)

## スライド機能実装する時に参考になるサイトはこちらです。
#### ❶carrierwaveとswiperに関してはこちらから参照下さい。
##### とてもわかりやすくまとまってます！

https://o6ga2wa8.hateblo.jp/entry/2021/09/20/135233

#### ❷完成イメージはこちらのサイトで確認できます。
##### アレンジを加えれるので、オススメです！

https://kiomiru.co.jp/blog/coding/swiper-js/

###### ❶の記事を見ながら『carrierwaveとswiper』を適用させた状態でざっくりと自分で適用できた記述を紹介します。

##### 1.dbにカラム追記
```php:postに
 create_table "posts", force: :cascade do |t|
    t.integer "user_id", null: false
    t.string "title", null: false
    ~~~{省略}~~~
    t.json "images"
end
```

##### 2.投稿フォームのあるmodelに追記
```php:post.rb
mount_uploaders :images, ImageUploader
```
##### 3.controllerのparamsに追記
```php:posts.controller.rb
def post_params
    params.require(:post).permit(:title,~{省略}~, images: [])
end
```

##### 4.layout/application.html.erbに追記
```php:application.html.erb
<head>
<!--swiperを読み込ませる-->
    <script src="https://unpkg.com/swiper/swiper-bundle.js"></script>
</head>
```
##### 5.投稿フォームに追記
```php:new.html.erb
<%= f.file_field :images, accept: "image/*", id: "image", multiple: true, class: "form-control-file image" %>
```
##### 6.表示させたいviewに追記
```php:スライド表示させたい.html.erb
<div class="swiper mySwiper">
  <div class="swiper-wrapper">
    <% @post.images.each do |image| %>
    <div class="swiper-slide" role="group">
      <%= image_tag image.url, size:'100x100' %>
    </div>
    <% end %>
  </div>
  <div class="swiper-button-next"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-pagination"></div>
</div>

~~省略~~

<script>
  var swiper = new Swiper(".mySwiper", {
    
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
    pagination: {
    el: ".swiper-pagination"
    },
  });
</script>
```
※本当はjsファイルに読み込ませたいが、よくわからなかったので、viewにscriptタグで適用させてしまいました。
※scriptタグ内で多彩なアレンジが可能(❷の記事を参照)

### おまけ
##### 表示させたいviewに追記
```php:1枚だけ表示させたいページ.html.erb
<%= image_tag post.images[0].to_s, size: '100x100' %>
<!--images[0] => 表示させたい順番の番号を記載-->
```

初学者ですので、間違いがありましたら申し訳ございません。
色んな記事と見て難しい印象でしたが、シンプルな記述でわかりやすかったです！
Windows デスクトップ(desktop) に移動 コマンドプロンプト cd dir について


# そもそもコマンドプロンプトについて

コマンドプロンプトを開いた時には大抵、ディレクトリがデスクトップではありません。
ユーザーの直下にいます。

ディレクトリとは、フォルダとほぼ同じと考えてもらって構いません。

```
dir
```
これをコマンドプロンプトに打つことで、今いるディレクトリの下にあるディレクトリ（フォルダ）とファイルが表示されます。
そして、ディレクトリの移動に`cd`（チェンジディレクトリの略）を使います。
`dir`の後に表示されたディレクトリ名を入力することで、その階層（＝ディレクトリ）に移動できます。
`>`の左側に書いてあるのが今いる階層になります。

PCの種類によって、表示されるものは違うのですが、デスクトップへの移動方法は以下の4つに分かれます。
※user-nameは人によって違います。
※大文字小文字の区別はしません。（OneDriveとonedriveは同じ）

# 注意点
ディレクトリ名に日本語が入っている場所でプログラミングをしようとするとエラーになることがあります。
その場合は、わざわざ階層を移動せずとも、最初のディレクトリの場所にそのまま環境構築して問題ありません。
デスクトップへの移動は必須ではないので、見つからなかった場合は見つからなかったで特に問題はありません。

# ①直下にある

C:¥Users¥user-name¥desktop
この場合は、

```
cd desktop
```
で移動できます。

 # ②onedriveが挟まってる
C:¥Users¥user-name¥onedrive¥desktop
この場合は
```
cd onedrive
cd desktop
```
で移動できます。

# ③デスクトップがカタカナ
C:¥Users¥user-name¥デスクトップ
この場合は、
```
cd デスクトップ
```
で移動できます。

# ④onedriveが挟まってる&デスクトップがカタカナ
C:¥Users¥user-name¥onedrive¥デスクトップ
この場合は、
```
cd onedrive
cd デスクトップ
```
で移動できます。

# その他
もしかしたら他のパターンもあるかもしれません。
その場合は適宜`dir`をしてどんなディレクトリがあるのか確認して、`cd`で表示されたディレクトリに移動してみてください！
上の階層に戻りたい時は、
```
cd ../
```
で階層を遡れます

# まとめ（手順）
①コマンドプロンプトを開く
②`dir`
③desktop(Desktop)がでてきたら`cd desktop`で終了
④desktopでてこなくて、onedriveがあったら`cd onedrive`
⑤再度`dir`
⑥desktopがあったら`cd desktop`、デスクトップがあったら `cd デスクトップ`
⑦ `dir`でデスクトップに移動できてるか確認、デスクトップに置いてあるフォルダなどが表示されていればOK
【AdMob】iOSでテストデバイスを設定する方法

# はじめに
現在AdMobではシュミレーターで起動した際には自動でテストモードの広告が表示されます。
しかし、実機でビルドした際には本番広告が表示されます。
実機テストの際に本番広告を謝ってタップしてしまってポリシー違反に引っ掛かってしまわないように実機テストするデバイスはテストデバイスに登録が推奨されています。

今回はAdMobにテストデバイスを登録する方法を紹介します。

# アプリ側での実装
場所はどこでも構いません。
`AdSupport`をインポートして広告IDを取得します。
```swift
import AdSupport

print(ASIdentifierManager().advertisingIdentifier)

// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```

取得できたらコードは削除して大丈夫です。
後ほど使うので広告IDは控えておきましょう。

# AdMob側での設定
「設定」を選択します。
![スクリーンショット 2022-08-11 23.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d75974db-0ab9-081b-cbcb-43f3fe794b65.png)

① 「テストデバイス」を選択します。
② 「テストデバイスを追加」を選択します。
![スクリーンショット 2022-08-11 23.52.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/5db9ba8c-4498-1cca-b096-0fbda650d901.png)

① 任意の名前を付けます。
② 「iOS」を選択します。
③ 先ほど取得した広告IDを貼り付けます。
④ 任意の設定にします。※1
![スクリーンショット 2022-08-11 23.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d2aa2cdf-cf8c-38b1-119a-75af6ad00c15.png)

:::note info
※1
「Ad inspector」は実機で広告分析ができるようにするものです。
以下のような画面がアプリ内に表示されます。
||||
|:-:|:-:|:-:|
|![IMG_0846.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/33277673-beef-54ab-75cc-48bd95d430e0.png)|![IMG_0847.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ad394ea5-0880-c887-a09c-852d6c3e483a.png)|![IMG_0848.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/636a7cb7-1d11-e033-5152-4e88c8fc63f5.png)|

今回、私は④で「シェイク」を選択したので端末をシェイクするとこの画面が表示されます。

別に見なくてもいいよって方は「なし」を選択するのが良いと思います。
:::

# おわり
無事に実機で表示する広告にも「Test mode」が表示されました！
これでポリシー違反になることはないので安心です。
CircleCIに環境変数を追加する方法

はじめに
--
ポートフォリオにCircleCIを組み込みたいと思い、何とか自動テストを通すことができるようになりました。

しかしTwitter apiを使用するために作成したapi key等を、環境変数として.envで追加したところ自動テストが通らなくなりました。
今後も同じようなエラーが起きた時に確認できるよう備忘録として残そうと思います。

api keyを追加したらdb:createでエラーが発生
--
今までは通っていた"rails db:create"がapi key(.envファイルにはTWITTER_KEYの名前で格納しています)を追加したところ下記のエラー文が表示されました。

~~~
key not found: "TWITTER_KEY" (KeyError)
~~~

.envに記述されている内容はgithubにpushしてはいけないので、当然githubのファイルを使って動くCircleCI上では、TWITTER_KEYの中身を見つけられません。


CircleCIに環境変数を追加する
--
このエラーを解決させるためには、CircleCIのサイトに直接、環境変数を追加する必要があります。

まず、CircleCIのProjectsのページから"project setting"を選択し、"Environment Variables"に移動したら"Add Environment Variable"をクリックします。

![スクリーンショット 2022-08-10 12.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641341/546dad69-d1c8-f020-d954-76b6d9730d82.png)

そこで、nameにはkeyを格納している名前,valueにkeyを入れて"Add Environment Variable"を押します。

![スクリーンショット 2022-08-10 12.23.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641341/3168bcf8-0048-931d-8936-2789cc121418.png)

これでCircleCIへ環境変数を追加する作業が完了しました。

.circleci/config.ymlに記述を追加する
--
CircleCIに環境変数を追加したら、今度はCircleCIの設定を記述しているconfig.ymlに環境変数を追加する必要があります。

environmentの箇所に下記のように追加すればOKです。
~~~
    environment:
      BUNDLE_JOBS: "3"
      BUNDLE_RETRY: "3"
      APP_DATABASE_HOST: "127.0.0.1"
      RAILS_ENV: test
      TWITTER_KEY: $TWITTER_KEY
      TWITTER_SECRET: $TWITTER_SECRET
      => CircleCIで登録したnameに$を追加する形("$name")で記載すれば、環境変数を使用できるようです。
~~~

これでエラーはなくなり、自動テストが通るようになりました！

※余談ですが、自分が実装したい機能にTwitter apiは必要なかったことを先ほど知りました。。
認証まわりで苦戦して1日半くらい無駄にした。。
決めつけで動くのは本当に良くないことを見にしみて感じました。。。。
PyCallを使ってRubyからPythonを実行する

# 実現したいこと
RubyでPythonのライブラリを使いたい

# 手順
## 1. pyenvを使ってる場合
```shell
env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.9.12
```

https://pip.pypa.io/en/stable/cli/pip_install/#install-find-links

## 2. 必要なライブラリがあればインストール
```shell
pip install package
```
または
```shell
pip install requirements.txt
```

## 3. Pycallを追加
```ruby
gem 'pycall'
```
```shell
bundle install
```

または
```shell
gem install pycall
```

https://github.com/mrkn/pycall.rb/#installation

## 4. PyCallをロード
```ruby
require 'pycall/import'
include PyCall::Import
```
https://github.com/mrkn/pycall.rb/#usage
## 5. Pythonライブラリをimportして使う

```ruby
pyimport :math
p math.degrees(math.pi / 2)
```

```ruby
pyfrom 'pdf2docx', import: 'parse'
parse(pdf_file_path, docx_file_path)
```

https://readysteadycode.com/howto-execute-python-code-with-ruby
Javaの学習 ~リテラル~

### リテラルとは
ソースコード中に記述する値のことです。
Javaには整数、浮動小数点数、真偽、文字の４つのリテラルがあります。
それぞれのデフォルトは、
整数→int
浮動小数点数→double
真偽→boolean
文字→char
となっています。

### 整数リテラル
##### long型
デフォルトの`int`ではなく`long`として扱いたい場合は、整数の末尾に「L」か「l」を付けます。
```java
long l = 12345L;
```
##### ２進数・８進数・１６進数
１０進数以外にも、２進数・８進数・１６進数で記述することができます。

２進数・・・「0b」が接頭辞。
```java
int a = 0b1000001011;
```
8進数・・・「0」が接頭辞。
```java
int b = 0413;
```
16進数・・・「0x」が接頭辞。
```java
int c = 0x10B;
```
##### アンダースコア「_」
桁数の多い数値リテラルを見やすくするため、アンダースコアを使った表記がJava 7から導入されました。

アンダースコアを使用する際のルールは以下の２つです。

①リテラルの先頭と末尾には記述できない
②記号(longやfloatの「L」や「F」、小数点の「.」、２進数等の接頭辞「0b」等)の前後には記述できない

```java
int d = 123_456_789;
```

### 文字リテラルと文字列リテラル
##### 文字リテラル
文字リテラルは、１文字を表すためのリテラルです。char型を使用します。
文字リテラルは、シングルクォーテーションで括ります。
```java
char e = 'A';
```
###### Unicode
Javaは、文字符号化方式「Unicode」を標準の文字コードに指定しています。
接頭辞「¥u」の後に続けて16進数4桁を記述し、シングルクォーテーションで括ります。
```java
char uni = "¥u30A2";   //カタカナの「ア」を表す。
```
###### 数値の代入
また、下記のように0~65535(16×16×16×16)の数値を代入することで文字を表すこともできます。
※負の値は代入できない！
```java
char code = 65;   //アルファベットの「A」を表す。
```

結果として、char型の変数に代入できるのは、
①シングルクォーテーションで括った文字
②シングルクォーテーションで括ったUnicode番号
③0~65535までの数値
の３つです。

###### null
※nullは参照データ型に対して、オブジェクトが何も参照しないことを示すリテラルです。プリミティブ型は参照を保持することができないため、nullを代入することができません。

##### 文字列リテラル
文字列リテラルは複数の文字のまとまりを表すためのリテラルです。Stringクラスから生成されたオブジェクト（参照データ型）を使用します。
文字列リテラルは、ダブルクォーテーションで括ります。
```java
String f = "ABC";
```

### 浮動小数点数リテラル
デフォルトの`double`ではなく`float`として扱いたい場合は、整数の末尾に「F」か「f」を付けます。
```java
float g = 1.25F;
```

### まとめ
最後まで閲覧いただき有難うございました！！
pip install でファイルを指定してパッケージをインストールする方法

# 実現したいこと
`pip install パッケージ名　`ではなく、ファイルを指定してパッケージをインストールしたい。

# 結論
ローカルにあるファイルを指定する場合
```shell
pip install foo.tar.gz
```

URLを指定してインストールする場合
```shell
pip install https://github.com/package/foo.tar.gz
```

`requirements.txt`に書く場合はこんな感じ
```text
-f https://github.com/package/foo.tar.gz
```

# ドキュメント
https://pip.pypa.io/en/stable/cli/pip_install/#install-find-links

# バージョン情報
```shell
$ pip --version
pip 22.0.4
```
AHC(AtCoder Heuristic Contest)で、手元で100テストケースを自動で試す(Linux)

# はじめに
[まぐげんがー](https://atcoder.jp/users/gengar_094?contestType=heuristic)です。AtCoderのHeuristicレーティングは<font color="Cyan">水色</font>です。
この記事は、AHCにおいて、手元でテストケースをたくさん試したい人に向けての記事になっています。
時間がないという方は「どのように多くのテストケースを試すか」と「(想定される)Q&A」だけ読めば大丈夫です。

# なぜテストケースをたくさん試したいか
AHC(AtCoder Heuristic Contestの略。最適解を出すのが難しい問題に対し、出来るだけ良い解を作成するコンテストです。)では、多くのテストケースでその回答がジャッジされます。さて、AHCにおいて、私たち（クソデカ主語）はなぜテストケースをたくさん試したいのか。
ここで、皆さんにAHCあるあるを2つ見ていただきたいと思います。
### あるある1
ぼく「よし！手元で10ケース試した感じスコア上がりそうだから提出するぞ〜」
〜提出 WJ 26/50〜
ぼく「いや〜これは勝ったな風呂入ってくるわ」
〜入浴後〜
ぼく「え！？スコア下がっとるやん！！」

### あるある2
ぼく「いやこれは流石に上がったわ。これ上がらなかったら穴に埋めてもらっても構わないよ」
〜提出 WJ 10/50〜
ぼく「よし勝ったな風呂入ってくるわ」
〜入浴後〜
RE「ぼく」

**そう、テストケースが多いAHCでは、最初の5、10ケースを確かめただけでは全体のスコアやvalidな答えを常に出すことができるかが分からない場合が多いのです。**
しかも、AHCは短期でも5分、長期になるとなんと30分もの提出制限時間があります。
長期コンで提出してREやWAが出たあと、3分後にバグを見つけ、悶絶するようなことも日常茶飯事です。

この点、手元で多くのテストケースを試せると、回答コードの変化によるスコアの上下、REやWAの有無などが見えてきやすくなります。

# どのように多くのテストケースを試すか

### 必要な実行環境
- rust（cargoが実行できればいいです）
- ruby
- ShellScript
（Ubuntu 22.04で動作確認ができています）

AHCは普段、Rustで書かれたローカル版ビジュアライザ・入力ジェネレータがダウンロードできるようになっています。これを使います。
ローカル版ビジュアライザ・入力ジェネレータをダウンロードして、展開すると`tools`というディレクトリが生成されるので、そのディレクトリで作業をしていきます。

`tools`の中に回答コードを作成します。私はC++をメインに使っているので、`main.cpp`という名前で作成します。
```
tools/
　├ in/
　├ src/
　├ target/
　└ main.cpp
```
今たぶんこんな感じのディレクトリ構造になっていると思います（`tools`内の全部のファイルを書いているわけではないです。たとえば`README_ja.md`などのファイルがあるかもしれませんが、今は関係ないので飛ばします）。
次に、`tools`の中に、以下の内容で`help.rb`と`run.sh`を作成して下さい。
```help.rb
n = gets.split[-1].to_i
tmp = 0
File.open("res.txt", mode = "r+") do |f|
	s = f.read
	tmp += s.nil? ? 0 : s.to_i
	tmp += n
end
File.delete("res.txt")
File.open("res.txt", mode = "w") do |f|
	f.puts tmp
end
```
```run.sh
cp /dev/null ./res.txt
g++ main.cpp -o main
for file in $(ls -1 ./in/*.txt); do
	./main < $file > out.txt
	cargo run --release --bin vis $file ./out.txt > ./out2.txt
	cat ./out2.txt | ruby help.rb
done
echo "Done! Score:"
cat res.txt
```
そして、また`tools`の中に`res.txt`というファイルを作成して下さい。
今こんな感じになっていれば大丈夫だと思います。
```
tools/
　├ in/
　├ src/
　├ target/
　├ help.rb
　├ run.sh
　└ main.cpp
```
この状態で、
```
$ cd ~/途中のディレクトリ/tools/
$ sh ./run.sh
```
とするとテストケースの実行が始まると思います。

# (想定される)Q&A

## Pythonを使っているのですがどうすればいいですか？
`main.cpp`の代わりに`main.py`を作って、
`run.sh`の中身を
```run.sh
cp /dev/null ./res.txt
for file in $(ls -1 ./in/*.txt); do
	python3 ./main.py < $file > out.txt
	cargo run --release --bin vis $file ./out.txt > ./out2.txt
	cat ./out2.txt | ruby help.rb
done
echo "Done! Score:"
cat res.txt
```
としてください。

## 動かなかったです。
今記事を書いているのがAHC013開催中なので、それ以降のAHCではローカル版ビジュアライザ・入力ジェネレータの中身
が異なるかもしれません。その時は`run.sh`と`help.rb`を上手く書き換えてみて下さい。

## 動作が遅いのですが。
ごめんなさい…
ShellScriptとRubyを合わせて使っているのでかなり遅くなっています。
「俺のほうが速い実行スクリプト書けるぞ！」という方はぜひコメントよろしくお願いいたします🙏

# 最後に
AHC楽しい〜！
【論文読み】全天球画像と日射量データによる太陽光発電量予測

## はじめに

こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「全天球画像と日射量データによる太陽光発電量予測」という論文です。  

- タイトル：全天球画像と日射量データによる太陽光発電量予測
- 出典：稲村直樹, et al.; 人工知能学会, 2020   
- URL：https://www.jstage.jst.go.jp/article/pjsai/JSAI2020/0/JSAI2020_4I2GS203/_pdf/-char/ja 


## 概要

太陽光発電を有効活用するには発電量正確に予測することが重要である。  
日射量は雲の有無および雲の形状や状態から大きな影響を受けるため、全天球画像を用いた15分後の短期予測モデルを検証。  


## 技術的特徴
以下の２つのモデルで検証。  
- 風速、風向、気温、などの観測データを用いてLSTMでモデルを構築  
- 上記LSTMとCNNでの雲識別結果を全結合層で結合したモデル。  

日射が大きく変動する箇所での予測と実績は乖離が大きく、期待通りの結果は出なかった。


## 想定される適用例
- 時系列データと画像データの同時使用  
- 太陽光発電の予測  
- 日射の予測  


## 参考
- [全天球画像と日射量データによる太陽光発電量予測](https://www.jstage.jst.go.jp/article/pjsai/JSAI2020/0/JSAI2020_4I2GS203/_pdf/-char/ja)
【AWS】S3 ライフサイクルポリシーの設定

設定する機会があったので備忘。
期間を指定すると自動でアップロードしたファイルを削除してくれます。
ファイルを保存し続ける必要ないよ！　とかって時に有用です。

設定内容：アップロードの3日後にオブジェクトを削除したい
（オブジェクトのバージョンは無効になっている前提）

## ①作成されたバケット→管理→ライフサイクルルール
![スクリーンショット 2022-08-11 22.30.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/5ea70007-0ecf-05b5-509c-0baf4b6599ac.jpeg)

## ②設定値の入力
**■ライフサイクルルールの設定**
・特定のフォルダ：バケット内のすべてのオブジェクトに適用
・バケット内すべてのオブジェクトに適用：文の通りです。
→こっちは「このルールがバケット内のすべてのオブジェクトに適用されることを了承します。」にチェック
![スクリーンショット 2022-08-11 22.42.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/d7a5a8e7-3b10-5ab2-1aef-ac93c0bea046.jpeg)

**■ライフサイクルルールのアクション**
オブジェクトをバージョン管理してるかどうかで選択肢がかわります。
今回の設定ではオブジェクトのバージョン化はせず、現行バージョンを削除するので、
「オブジェクトの現行バージョンを有効期限切れにする」を選択。
![スクリーンショット 2022-08-11 22.42.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/810402fd-ce44-e227-5b84-7a6bf49667c1.jpeg)

**■オブジェクトの現行バージョンの有効期限が切れる**
これはそのままですね。期限が切れる日数をいれれば良いだけです。
今回は３日のこればいいので、「３」を入力。
![スクリーンショット 2022-08-11 22.46.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984662/3783180a-08d2-8adf-7610-65cebbf716a5.jpeg)
以上です。簡単にサクッとできて、よきでした:slight_smile:
SnowflakeのAccess Historyでクエリの多いテーブルと列を表示する

# 内容
SnowflakeのACCESS_HISTORY ビューを利用して、クエリの多いテーブルと列を表示して、テーブルの管理を行う。

下のスライドを参考に3つクエリを紹介する。

- テーブルごとに利用者数を集計してランキング
- 列ごとのアクセス状況
- テーブルの利用者を日ごとに集計

https://speakerdeck.com/__hiza__/detamanezimentogatiyotutole-ninarubigqueryjian-cha-rogufalseshi-ifang

列ごとのアクセス状況をロール単位で集計もがんばったらできそう。

参考にしたクエリ

https://stackoverflow.com/questions/64341885/snowflake-view-what-tables-and-columns-are-queried-the-most

# テーブルごとに利用者数を集計してランキング

```SQL
select
    obj.value:objectName::string as objName,
    count(*) as uses,
    min(to_date(query_start_time)) as since,
    max(to_date(query_start_time)) as until
from
    snowflake.account_usage.access_history,
    table(flatten(direct_objects_accessed)) as obj
where
    obj.value:objectDomain::string = 'Table'
    and objName not like 'SNOWFLAKE.%'
    and objName not like '%.INFORMATION_SCHEMA.%'
group by
    objName
order by
    uses desc;
```

Snowsightを利用するとグラフ化もできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919551/8194d780-4a1d-9f22-8ac1-4bf0f860d73e.png)

テーブル数が少ないので、絵が貧相...

# 列ごとのアクセス状況

```SQL
select
    obj.value:objectName::string as objName,
    col.value:columnName::string as colName,
    count(*) as uses,
    objName || ':' || colName as fullName,
    min(query_start_time) as since,
    max(query_start_time) as until
from
    snowflake.account_usage.access_history,
    table(flatten(direct_objects_accessed)) obj,
    table(flatten(obj.value:columns)) col
where
    obj.value:objectDomain::string = 'Table'
    and objName not like 'SNOWFLAKE.%'
    and objName not like '%.INFORMATION_SCHEMA.%'
group by
    objName,
    colName
order by
    uses desc;
```

結果はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919551/cb10f15f-bb48-b35c-a868-922adc328edb.png)

Snowsightを利用するとこんな感じ。チャート用にテーブル名と列名を合わせた列名を作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919551/d5026e85-c7ef-c555-2503-d74efa6c5060.png)

# テーブルの利用者を日ごとに集計

```SQL
set object_name = 'AZURE_DATA_FACTORY.PUBLIC.WEATHER';
select
    count(*) as uses,
    to_date(query_start_time) as accessDate
from
    snowflake.account_usage.access_history,
    table(flatten(direct_objects_accessed)) obj
where
    obj.value:objectName::string = $object_name
group by
    accessDate
;
```

X軸を `ACCESSDATE` にしてバケット化で日付を選ぶと値のない日も表示してくれて便利。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919551/3c2436e6-068f-85d8-de73-dd99a4c7bf7c.png)

オブジェクト名が雑だ...
機械学習システム開発フロー

# はじめに
* 機械学習システム開発の全体像をまとめてみました
    * データ基盤構築~モデル開発~パイプライン開発・デプロイ~エンドポイント構築・デプロイ~監視
    * データサイエンティスト・データエンジニアがいつ何をするか
* MLOpsの概要やそれぞれの詳細は下記参照
    * [【MLOps入門】MLOps概要](https://qiita.com/noko_qii/items/d2c36b0b22ab0da6c759)
    * [【MLOps実践】機械学習システム開発における品質担保のための取り組み（PoCフェーズ編）](https://qiita.com/noko_qii/items/6dbcffb0bf45b2a6dcad)
    * [【MLOps実践】GCPで始めるエンドツーエンドなMLOps基盤（Vertex AI,etc）](https://qiita.com/noko_qii/items/1c55261f08ce7e95b255)

# 機械学習システム開発フロー
※あくまで一例です

## 機械学習システム開発フロー図
![gcp_mlops_flow.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92368/8427bbd1-1629-ae67-cda3-15e94c942a42.png)

## 機械学習システム開発フロー例の詳細
### 1. データ基盤構築
* データ収集
    * データレイク・データウェアハウス・データマート・特徴量ストアなどにデータを格納する

### 2. モデル開発
* IAMユーザ作成
    * データサイエンティストに必要な権限を付与する

* ノートブックインスタンス作成
    * 要件に応じたスペックのノートブックインスタンスを作成する

* データ取り込みとバージョン管理
    * 生のデータセットを読み込む
    * 生のデータセットと変換されたデータセットの両方のバージョンを管理する

* データ分析と検証
    * 取り込んだデータセットの品質とバイアスを分析する

* 特徴量選択とエンジニアリング
    * データセットを次のパイプラインステップで使用される特徴量に変換する
    * データを訓練・検証・テストに分割する
    * 特徴量を特徴量ストアに公開し、組織全体で訓練と推論の両方に使用する

* （任意）データ処理ジョブ実行
    * 必要に応じて、計算量が不足する場合にデータ処理ジョブ実行をする（ノートブックインスタンスからSparkクラスタにジョブを投げるなど）

* モデル訓練とチューニング
    * 前のステップで作成した特徴量とハイパーパラメータのセットを使用してモデルを訓練する
    * 既知の検証データセットの分割を使用して精度を分析し、モデルの精度が十分になるまで異なるハイパーパラメータのセットで繰り返す

* 学習ジョブ実行
    * 必要に応じて、計算量が不足する場合に学習処理ジョブ実行をする（ノートブックインスタンスからジョブを投げる）

* モデル分析とバージョン管理
    * 既知のテストデータセットの分割を用いて訓練したモデルをテストし、混同行列や曲線下面積（AUC）などの追加指標を計算し、テストデータセットのそれぞれのセグメントにおけるモデルのバイアスを検証し、バイアスを減らしたり取り除くための再訓練や再チューニングを行う。

* 実験管理
    * 実験結果を管理する

### 3. パイプライン開発・デプロイ
* パイプラインコード開発
    * ノートブックで開発したコードをパイプライン化する

* パイプラインコードコミット
    * パイプラインコードをコミットする

* CIジョブ実行（パイプライン）
    * コミットをトリガーにCIジョブを実行し、パイプラインを生成・実行する

* CIジョブ結果確認
    * CIジョブが正常に完了していることを確認する

* パイプラインコードレビュー
    * CIジョブの結果に加えて、パイプラインコードをレビューする

* CDジョブ実行（学習パイプライン）
    * パイプラインコードのレビューが完了したら、学習パイプラインをデプロイする

* 学習パイプライン実行
    * 学習パイプラインを実行する
    * 必要に応じて上流処理の待ち合わせを検討する

* モデル保存
    * 学習パイプラインのアウトプットであるモデルをモデルレジストリに保存する

* メタデータ管理
    * 学習パイプライン実行時のメタデータを連携する

* メタデータ確認
    * 学習パイプライン実行時のメタデータを確認する

* [STG]CDジョブ実行（推論パイプライン）
    * 学習パイプライン実行時のメタデータの確認が完了したら、推論パイプラインをデプロイする

* [STG]トリガー実行
    * 推論パイプラインのトリガーを実行する

* [STG]推論パイプライン実行（モデルロード）
    * 推論パイプラインを実行する

* [STG]推論結果連携
    * 推論パイプラインのアウトプットである推論結果を連携する

* [STG]推論結果確認
    * STGでの推論結果を確認する

* [PROD]CDジョブ実行（推論パイプライン）
    * STGでの推論結果の確認が完了したら、PRODに推論パイプラインをデプロイする

* [PROD]トリガー実行
    * 推論パイプラインのトリガーを実行する

* [PROD]推論パイプライン実行（モデルロード）
    * 推論パイプラインを実行する
    * 必要に応じて上流処理の待ち合わせを検討する

* [PROD]推論結果連携
    * 推論パイプラインのアウトプットである推論結果を連携する

* [STG]CDジョブ実行（モデルサービング）
    * 学習パイプライン実行時のメタデータの確認が完了したら、モデルをエンドポイントにデプロイする

### 4. エンドポイント構築・デプロイ
* [STG]推論エンドポイント起動
    * モデルをサービングする

* [STG]推論レスポンス確認
    * STGでの推論結果を確認する

* [PROD]CDジョブ実行（モデルサービング）
    * STGでの推論結果の確認が完了したら、PRODにモデルをエンドポイントにデプロイする

* [PROD]推論エンドポイント起動
    * モデルをサービングする

### 5. 監視
* 監視
    * 死活監視・リソース監視・ログ監視・精度監視をする

* 分析・障害対応
    * 分析・障害対応をする

## 参考
* [実践AWSデータサイエンス]()
Windows11にDockerをインストールしてみた①

<h4>はじめに</h4>
　今更ながらDcokerについて勉強してみよう！という気持ちで、備忘録とアウトプットで記載してます。

　Windows11が他と異なっていたりする部分を整理したり、これいらないと思った部分をメモ感覚で記載してます。

 　また、初心者目線で、初心者だったらつまづくだろうなっと思ったところを修正と追加してます。


***
<h4>環境</h4>
・Windows11 Home

・バージョン：21H2

***

インストールを参考にしたところです。
参考にさせていただき、感謝いたします。

https://qiita.com/ryosukeImai/items/2a1ba932e059f75f7fff

***

基本は上記の記事様に従っていればインストールはできるのですが、ちょっと一部修正箇所があります。

***
修正１
>Microsoftストアにて 「app installer」を検索して、インストールしてください。

とありましたが、私のWindows11はインストールされてました。
たぶん、もともとインストールはされているもの。

　以下の手順で確認をしてみてください。
　Windows ターミナルを管理者で起動し、以下コマンドでインストールの確認してください。

手順1)
　Windowsターミナルを起動する方法は、従来通りにタスクバーの スタートボタンを右クリックするか、キーボードの Windows + Xキーを同時に押して開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/036c56ac-1574-748f-5192-c2bb54ab93b3.png)

手順2)
 コマンドを「winget -v」で実行
 インストールしてください！とか出てるけど、今はスルーでいいと思う
　（後ほど、インストールしてみます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/e3dcd2e1-c34e-a861-11ac-559ddf27615b.png)

 結果）　
　バージョンがV1.3.2091で出ているので、このバージョンのものが入っているということになる。

***

修正2;
 修正というよりも、補足です。
 Dockerインストールのコマンドを打った後、出てくる現象を飛ばしているので
　初心者向けに細かく画面をスクショしてみました。
　コマンド打った後、以下の画面の流れになります。


以下コマンドでインストールがでるというので、コマンドを打ってみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/1bd7e5c1-e9c1-4d88-5bbe-a79c9d081d76.png)
以下の内容がでてきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/cba08dca-ac57-7c15-26c2-469386d6f77c.png)
はいを選択してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/b503a4e2-ef41-38ce-9ade-6d81e2dbfb74.png)
はい（Y）をコマンドを打ったら、以下がでてきました。
インストールができそうな予感がします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/da479127-c07a-8711-2059-1f616be1d04c.png)
パッケージのインストールが開始しされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/37dcb564-e6b9-14fa-448f-8a8310fa00b4.png)
インストールが完了されましたー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/a4712ca5-9a2c-478f-72ae-91c1004c16d8.png)
インストールが本当にできたかどうか、以下のコマンドを打って確認してみる。

よくわからない文章がでてきました。
なんでだろう・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/497a0abe-11d2-1d75-0e90-3d7215ebd35f.png)
あ、よくみると、コマンドを打っているツールは「Windows ターミナルを管理者」でした。
「Windows　PowerShell」でコマンドを打つと、以下ちゃんと出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/f60a84c7-48ea-4515-ad5d-6e9a62b43894.png)
ディスクトップに、ショートカットも表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646863/58e426f1-ae7e-82ab-2e5a-19e3310a0675.png)

***
これで、インストールは完了です。
お疲れ様でした。
TypeScriptでCLIツールを作ってみた

就活の面接の練習をする友達がいなかったので、自動でランダムの質問をしてくれるプログラムを作ってみた。

## 準備

```shell
% npm init
```

```shell
% npm install typescript ts-node process
```

`tsconfig.json`に以下を追加する。

```bash
"moduleResolution": "node"

"resolveJsonModule": true
```

## コード

ディレクトリはこんな感じ。

```
.
├── index.ts
├── types.ts
├── json
│   └── mensetsu.json
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json
```

質問内容のデータはJSONでこんな感じに用意する。

```json/mensetsu.json
{
    "mensetsu": [
        {
            "question": "自己PR",
            "answer": [
                "私の強みは、学ぶことが好きであるということです。",
                "自分のまだ知らないことを知りたいという知的好奇心が高く、中学や高校、医学部での座学や実習も全て面白く感じ、楽しんで自ら学んできました。",
                "医学の発展は日進月歩であり、生涯学び続けることが必要な医師として働く上で、非常に大きな強みであると考えております。"
            ]
        },
        {
            "question": "当院を志望した理由",
            "answer": [ ... ]
        },
        ...
    ]
}
```

中身はこんな感じ。

switch文でデータ切り替えられるので、就活終わった後も他のことに使えるかも。

```index.ts
import readline from "readline"
import { Question } from "./types"
import Mensetsu from "./json/mensetsu.json"

/**
 * 環境変数で扱うデータを切り替える
 */
let array: Array<Question>
const obj: string | undefined = process.env.OBJ

switch (obj) {
  case 'mensetsu':
    array = Mensetsu.mensetsu
}

/**
 * 標準入力を取得する
 */
const question = (question: string): Promise<string> => {
  const readlineInterface = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  })
  return new Promise((resolve) => {
    readlineInterface.question(question, (answer: string) => {
      resolve(answer)
      readlineInterface.close()
    })
  })
}

async function prompt(msg: string): Promise<string> {
    const answer: string = await question(msg)
    return answer.trim()
}

const main = async () => {
  console.log('');
  console.log('↓↓↓Enterキーを押して操作してください↓↓↓');
  console.log('');
  for (;;) {
    const dialog = array[Math.floor(Math.random() * array.length)]
    await prompt('\x1b[36mQ.'+dialog.question)
    console.log('\x1b[35mA.\x1b[0m');
    dialog.answer.forEach((answer: string) => {
      console.log(answer);
    })
    console.log('')
  }
}

// 起動
(async () => {
  await main()
})()
```
```types.ts
export type Question = {
    question: string
    answer: Array<string>
}
```

yarnのscriptsにコマンドを追加しておく。

```package.json
"scripts": {
  "start": "OBJ=mensetsu ./node_modules/.bin/ts-node index.ts"
}
```

実行するとこんな感じ。

```zsh
% yarn start
yarn run v1.22.19
$ OBJ=mensetsu ./node_modules/.bin/ts-node index.ts

↓↓↓Enterキーを押して操作してください↓↓↓

Q.大学生活の一番思い出深いこと
A.
```

## まとめ

ちょっとした単語帳とか作りたいなってときに使えそう。
ちなみに面接本番は準備不足で爆死。
Thymeleafでformタグを入れ子にしたいときの対処法とデータの受け渡し方

# やりたいこと
- 下記画面に個別削除機能をつけたい
![FireShot Capture 003 - User - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226241/8beed6cf-160d-e8f0-5f33-9515886f02b7.png)


- その際のHTMLのテーブルのソースコードは以下の通り
```html
<table th:if="!${#lists.isEmpty(userList)}">
    <thead>
    <tr>
        <th>ID</th>
        <th>ユーザ名</th>
        <th>削除</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="user:${userList}">
        <td th:text="${user.userId}"></td>
        <td th:text="${user.name}"></td>
        <td>
            <form th:action="@{/user/delete}" method="post">
                <input type="hidden" name="userId" th:value="${user.userId}">
                <input type="submit" value="削除">
            </form>
        </td>
    </tr>
    </tbody>
</table>
```

# 躓いたところ
- 最初は下記のようなコードにしようと思っていた
- しかしHTMLの仕様でformタグは入れ子にできない制約がある
```html
<div th:if="!${#lists.isEmpty(userList)}">
<form th:action="@{/user/deleteAll}" method="post" th:object="${deleteForm}">
<table>
    <thead>
    <tr>
        <th>選択</th>
        <th>ID</th>
        <th>ユーザ名</th>
        <th>削除</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="user:${userList}">
        <td>
            <input type="checkbox" th:value="${user.userId}" th:field="*{deleteList}">
        </td>
        <td th:text="${user.userId}"></td>
        <td th:text="${user.name}"></td>
        <td>
            <form th:action="@{/user/delete}" method="post">
                <input type="hidden" name="userId" th:value="${user.userId}">
                <input type="submit" value="削除">
            </form>
        </td>
    </tr>
    </tbody>
</table>
<input type="submit" value="選択したものを一括削除">
</form>
</div>
```

# 解決策
- inputタグに**form属性を追加して対応するformタグのid属性に同じものを指定する**とformタグ内にないinputタグのボタンクリックを処理することができる
- またThymeleafでinputタグの値をオブジェクトに渡したいとき通常formタグにth:objectを指定してinputタグのth:feiledでどのメンバ変数に値を格納するか`*{メンバ変数名}`のような形で指定するが今回の場合はform配下に対象のinputタグがないため下記のように**th:fieldは省略しない形で書く**と指定したメンバ変数に値を格納できる
```html
<div th:if="!${#lists.isEmpty(userList)}">
<table>
    <thead>
    <tr>
        <th>選択</th>
        <th>ID</th>
        <th>ユーザ名</th>
        <th>削除</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="user:${userList}">
        <td>
            <input form="deleteListForm" type="checkbox" th:value="${user.userId}" th:field="${deleteForm.deleteList}">
        </td>
        <td th:text="${user.userId}"></td>
        <td th:text="${user.name}"></td>
        <td>
            <form th:action="@{/user/delete}" method="post">
                <input type="hidden" name="userId" th:value="${user.userId}">
                <input type="submit" value="削除">
            </form>
        </td>
    </tr>
    </tbody>
</table>
<form id="deleteListForm" th:action="@{/user/deleteAll}" method="post">
    <input type="submit" value="選択したものを一括削除">
</form>
</div>
```

# ソースコード
- 今回作成したソースコード  

https://github.com/aka-ao/FormSample
[Flutter] TextFieldで高さを持たせつつ、行数が超えると広がるようにする

# やりたいこと

マルチラインなTextFieldで`maxLines`を設定しちゃうとその行数以上を入力したときに広がらずにスクロールする必要がある...
スクロールじゃなくて広がるようにしたい！

似たような記事を見てみるとどれも`isDense`を`true`にして`contentPadding`を設定するみたいなことしか書いてなくて、自分の実装したいこととは違ったので同じような実装をしたい人のために書き留めておきたいと思います。


# やり方

ちょっとハッキーなやり方ですが、とても簡単です。
- `keyboardType`をnullに、
- `maxLines`をnullに、
- `hintText`に好きなだけ改行を入れる

```dart
TextFormField(
    keyboardType: TextInputType.multiline,
    maxLines: null,
    decoration: InputDecoration(
        hintText: '本文\n\n\n\n\n',
    ),
),
```

## 注意

ただし、`labelText`を併用するととても気持ち悪くなるのでやめた方がいいです。
Excel文書のPDF変換で日本語フォントがおかしかった件

## はじめに

LibreOfficeのsofficeコマンドを使用し、Excel文書をPDFに変換時、
場合によっては、OSにフォント追加が必要だった、といった内容です。

## LibreOfficeとsofficeコマンドとは

- LibreOffice
    - オープンソースソフトの統合オフィスソフトウェア
- sofficeコマンド
    - LibreOfficeに内蔵されたドキュメント変換コマンド

## 検証環境

- AlmaLinux 8.6

## LibreOfficeをインストール

### まず、依存ライブラリをインストール

```shell
$ sudo dnf update
$ sudo dnf install dnf-plugins-core
$ sudo dnf install nss
$ sudo dnf install cups
```

### つぎ、LibreOfficeパッケージと追加日本語パッケージをインストール

```shell
$ wget https://download.documentfoundation.org/libreoffice/stable/7.3.5/rpm/x86_64/LibreOffice_7.3.5_Linux_x86-64_rpm.tar.gz
$ wget https://download.documentfoundation.org/libreoffice/stable/7.3.5/rpm/x86_64/LibreOffice_7.3.5_Linux_x86-64_rpm_langpack_ja.tar.gz
$ sudo tar zxvf LibreOffice_7.3.5_Linux_x86-64_rpm.tar.gz
$ sudo tar xvf LibreOffice_7.3.5_Linux_x86-64_rpm_langpack_ja.tar.gz
$ sudo dnf localinstall LibreOffice_7.3.5.2_Linux_x86-64_rpm/RPMS/*.rpm -y
$ sudo dnf localinstall LibreOffice_7.3.5.2_Linux_x86-64_rpm_langpack_ja/RPMS/*.rpm -y
```

## sofficeコマンドでExcelファイルをPDFに変換してみる

```shell
$ /opt/libreoffice7.3/program/soffice --headless --convert-to pdf test-font.xlsx
```

PDF変換はできましたが、漢字の書体がなんか変。

|変換元Excel|変換後PDF|
|:--:|:--:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/6f8eccc6-1a2d-ff82-5864-6cdf69038422.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/60a3f8d1-1b0a-dca8-4895-12af2df8a3ca.png)|

必要フォントがOSに存在せず、別のフォントが使われた?

## IPAフォントを入れてみる

```shell
$ wget https://moji.or.jp/wp-content/ipafont/IPAfont/IPAfont00303.zip
$ unzip IPAfont00303.zip
$ sudo cp -rf IPAfont00303 /usr/share/fonts/
$ fc-cache -fr
$ fc-list | grep -i IPA
/usr/share/fonts/IPAfont00303/ipag.ttf: IPAゴシック,IPAGothic:style=Regular
/usr/share/fonts/IPAfont00303/ipamp.ttf: IPA P明朝,IPAPMincho:style=Regular
/usr/share/fonts/IPAfont00303/ipam.ttf: IPA明朝,IPAMincho:style=Regular
/usr/share/fonts/IPAfont00303/ipagp.ttf: IPA Pゴシック,IPAPGothic:style=Regular
```

## 再度、変換を試みる

今度は書体が正しく変換できました。

|変換元Excel|変換後PDF|
|:--:|:--:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/6f8eccc6-1a2d-ff82-5864-6cdf69038422.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/5e24506e-61b1-b9e0-30e0-6cc09d8ee75b.png)|



## おわりに

sofficeコマンドでOffice文書をPDF変換時、
書体が変になったらフォント追加を試してみるとよいかもしれません。
マルチタブ風のサイドバー (`centaur-tabs` で)

# 茶番

近年のテキストエディタの発展は著しいです。

- [telescope](https://github.com/nvim-telescope/telescope.nvim) がスタンダードな NeoVim
- [minadware](https://github.com/minad) で塗り変わった Emacs
- 新興の [helix](https://github.com/helix-editor/helix)

など、キャッチアップも難しいほどの変革が訪れています。

ですが元の流れを忘れてはいけません。我々 (?) 一般人がナードなエディタに触れることができるのは、 VSCode が LSP をもたらしたためです。そして VSCode は、今最もメジャで美しいエディタとして君臨しています:

![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/4690bf45-2011-0248-88b9-d26dc2af4b4b.png)

現代のテキストエディタとはかくあるべし……！　このアプリに Emacs で対向できるのでしょうか？

![emacs-is-an-os.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/4ce8b2c6-4676-bb8c-e3c6-3532d2b3be84.png)

~~これが『OS』と呼ばれたエディタの姿なんですか……？~~

エディタの見た目は設定次第で良くなります。ある程度設定しました。

# 設定後、まだ羨ましい点

VSCode の **サイドバーとか下部ペインが綺麗でいいな** と思っていました。

Emacs にも似たようなものが欲しいです！

# サイドバーを VSCode 風にしてみた

2 点のみ変更しました。

## OUTLINE 相当のウィジェットを追加

まず機能的な差を埋めます。 `lsp-ui-imenu` を使えば、ソースのアウトラインを表示できます:

```elisp
(leaf lsp-ui-imenu
    :ensure nil
    :after lsp-mode
    :custom ((lsp-imenu-sort-methods . '(position))  ; この設定でアウトライン表示に
             (lsp-ui-imenu-buffer-name . "@imenu")   ; 後述のバッファグループの都合で名称変更
             (lsp-ui-imenu-window-width . my-sidebar-width))
    :hook (lsp-ui-imenu-mode-hook . hl-line-mode))
```

さらにカーソル位置と連動してフォーカスが更新されるようにしました ([gist](https://gist.github.com/toyboot4e/c17521042b7332fc94fa370b998e8938)):

![stick-imenu.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/0316fdb9-94de-7695-56c2-087b4e06887d.gif)

> GIF です。 Firefox では動かないかも……

しかしファイルツリーとアウトラインを同時に表示することはできません。どうしたものでしょうか。

## マルチタブ表示

[centaur-tabs](https://github.com/ema2159/centaur-tabs) を使っていたので、これで『タブ』表示することを思いつきました:

```elisp
(leaf centaur-tabs
    :after projectile
    :custom ((centaur-tabs--buffer-show-groups . nil)
             (centaur-tabs-cycle-scope . 'tabs)
             (centaur-tabs-buffer-groups-function . #'my-centaur-tabs-group))
    :config
    ;; サイドバー および ボトムバーのバッファグループを作成する
    (defun my-centaur-tabs-group ()
        (cond ((string-equal "@" (substring (buffer-name) 0 1)) '("Sidebar") )
              ((string-equal "⊥" (substring (buffer-name) 0 1)) '("Bottom bar") )
              ;; Projectile のグループに fallback
              (t (centaur-tabs-projectile-buffer-groups))))
    (centaur-tabs-mode t))
```

実際、こんな画面になります:

![bottom-bar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/33a97797-19b1-63be-7477-b97a2d76baa4.png)

- サイドバーには `@imenu`, `@tree` のように `@` から始まるバッファが表示されます
  - 他にも良さそうなウィジェットがあれば追加していきます
- ボトムバーには `⊥ vterm`, `⊥ scratch` のように `⊥` から始まるバッファが表示されます
  - ただボトムバーの使い道は思いつきません。
    - エラー表示は minibuffer で見ます
    - シェルは `tmux` pane から使います

# 終わり

サイドバーがリッチになりました！　VSCode のアイコン表示がとても好きなので、まだまだ未練はありますが、そこは妥協しよう [^1] と思います。

[^1]: Emacs は通常ターミナルでアイコン表示できません。
Snowflakeでsampleテーブルを作成しようとするとエラーになる

# 事象
Snowflakeでsampleテーブルを作成しようとするとエラーになる。

```SQL
>create table sample (amount number);
001003 (42000): SQLコンパイルエラー：
位置 13 の構文エラー行 1 、予期しない「sample」。
```

ダブルクオートで囲むと作成できる。

```SQL
>create table "sample" (amount number);
+------------------------------------------+
| status                                   |
|------------------------------------------|
| テーブル sample が正常に作成されました。 |
+------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.171s
```

# 原因
`sample` は予約語だから。

https://docs.snowflake.com/ja/sql-reference/reserved-keywords.html

他に引っかかりやすそうなのは `group` , `order` とか？
[Swift]UIに比率を指定する(Storyboard)

# 概要
StoryboardでUIの幅や高さを比率で指定する手順です。

全体の手順は
①比率の元にしたいオブジェクトと同じ幅（高さ）にする
②どれくらいの比率にするかを指定する


# 本文
今回は画面全体に対する比率を指定したいのでSafe AreaとButtonを選択する（Commandボタンを押しながら選択）
![スクリーンショット 2022-08-11 20.15.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/a5c8adca-479d-9f5b-fd34-7c83fafb9acf.png)
画面右下、Add New ConstraintsからEqual Widthsを選ぶとボタンの横幅が画面の横幅と同じになります。
![スクリーンショット 2022-08-11 20.16.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/93bb979d-0897-7e46-4a66-b58b2eada9c3.png)
![スクリーンショット 2022-08-11 20.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/51114ba9-cad9-de1e-b860-18cadc20d00e.png)
比率を指定したいオブジェクト（今回はButton）だけを選んだ状態にしてスクショのように選択し、Multiplierに比率を入力します。
（初期値1は「100％=同じ」を意味します。今回は画面横幅の半分なので0.5を入力しました）
![スクリーンショット 2022-08-11 20.17.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/c4cbbf72-d60c-41ee-c8a9-8e4ece7b7eba.png)
![スクリーンショット 2022-08-11 20.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4e30d9ff-8674-a057-7b0c-767cbd655fee.png)
# 補足
この手順を応用すると、他のUIに対する比率を指定することもできます。
今回作ったボタンに対して半分の幅を黒色のボタンに指定してみました。
![スクリーンショット 2022-08-11 20.23.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/7302fc84-8ad5-7a2f-cad0-08c603873920.png)
Ubuntu に SQLite3 の最新をインストールする

SQLiteサイトからソースコードをビルドして最新をインストールする手順です。
https://www.sqlite.org/download.html

## 準備
以下のパッケージをインストールする
```bash
sudo apt install build-essential
sudo apt install libreadline-dev
```

## ソース入手
```bash
curl -OL https://www.sqlite.org/2024/sqlite-autoconf-3450300.tar.gz
```

## ビルド、インストール
ソースコードを展開し、make します。
```bash
tar xvzf sqlite-autoconf-3450300.tar.gz
cd sqlite-autoconf-3450300/
./configure
make
sudo make install
```

## 起動
sqlite3 コマンドを起動します。
```bash
❯ sqlite3
SQLite version 3.45.3 2024-04-15 13:34:05
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
sqlite> .version
SQLite 3.45.3 2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355
gcc-11.4.0 (64-bit)
sqlite>
```

## CTRL + N, CTRL + P が利かない問題
```
sqlite> ^[[A^[[B^[[D^[[C
```
こんな感じになる場合は、下記パッケージをインストールされていない場合です。インストール後、再度make, make install すればOK。
```bash
sudo apt install libreadline-dev
```

## 参考
https://sqlite.org/forum/info/1fb161b54360f407
IntelliJ IDEAの補完機能が効かないときは省電力モードになっていないか疑おう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102978/9bcc3ede-ad56-903e-76fb-31b2257bc11a.png)

# 概要
IntelliJ IDEAを利用している際、とつぜん入力補完が効かなくなる現象が発生した。色々調べた結果を記録する。

# 結論
省電力モードがONになっている可能性がある。
IntelliJ IDEAでは、省電力モードが有効の場合、入力補完機能がOFFになる仕様がある。


# 修正方法
上部のメニューより
ファイル > 省電力モード → OFFに設定

試しタイピングをし、入力補完が有効になったことを確認する。


省電力モードは便利ですが、設定したことは忘れがちなので気をつけましょう、というオチです。


![D027A8E9-CCC3-494D-A224-B31036DB9625.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102978/fa7156bc-450f-d0f2-5b97-e9be0b24f174.png)
Github Pagesにapp-ads.txtを無料で設置する

# app-ads.txtとは
app-ads.txtとは、Admobのアプリ用広告ネットワークを利用するために、
自身のサイトに設置しなければいけないファイルです。

app-ads.txtは必ずルートに設置しなければいけません。（サブドメインはOK）

```
OK: example.com/app-ads.txt
OK: subdomain.example.com/app-ads.txt
NG: example.com/subdirectory/app-ads.txt
```

# Github Pagesに設置
早速設置する方法を説明するのですが、利用したことある方からすると、
「え、Github Pagesだとルートに置けなくない？」と思われる方も多いでしょう。

実際、普通にリポジトリの中身を公開する場合、
```
username.github.io/repository/
```
下に公開という形になってしまいます。

しかし、実はルートに置く方法があります。それは、
**ドメイン名と同じ名前のリポジトリ（username.github.io）を作ることです。**

例えば僕のユーザー名はarihideなので、[arihide.github.io](https://github.com/Arihide/arihide.github.io)という名前で作成します。

その後、設定から　Settings→Pages→Branchより公開するブランチを指定してSaveを押せば無事公開できます。
![スクリーンショット 2022-08-11 20.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/dc37738a-399a-10b0-95a9-c9ac60cc635a.png)
Jpegのアーティファクトを除去してくれるモデルがすごい

# 低品質Jpeg書き出しを繰り返すと出るアーティファクトを除去

アーティファクトJpeg画像
![pexels-vincent-rivaud-2233348.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/360938b9-db6e-1739-d941-82a71fcde99b.jpeg)

FBCNNの結果
![20811b1f-7ee5-4c8d-8dcc-d09b3a373f84.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/2ea0e121-2760-3eaa-6172-a607981ff3ae.png)

アーティファクトが消えています。

FBCNNというモデルを使います。

https://github.com/jiaxi-jiang/FBCNN.git

# 使い方

・リポジトリをクローン
・事前トレーニング済みモデルをダウンロード
・main_test_fbcnn_color_real.py内のtest_setに自分の画像フォルダを指定して実行

```shell
git clone https://github.com/jiaxi-jiang/FBCNN.git
cd FBCNN
wget https://github.com/jiaxi-jiang/FBCNN/releases/download/v1.0/fbcnn_color.pth -P model_zoo
python main_test_fbcnn_color_real.py
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
Google AdMobにアプリを登録する方法

### アプリ登録の手順メモ

1. AdMobのホーム画面を開く
1. 画面左側の[アプリ]-[アプリ追加]をクリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/6af7f5ad-8f05-1819-ad7a-1086dd3cd657.png)
1. プラットフォームとストアにリリースされているかを選択
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/9fa1f34c-9ba0-1aa3-38a7-7236099c48d0.png)
1. アプリ名を入力（リリースして場合は後から変更されるので適当で良い）
1. ユーザ指標を選択し、アプリ追加をクリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/9d224a77-5dfc-cc87-fb22-2f1fc8c0c6c0.png)

### 完了！
Visual Studio CodeでWSL2のフォルダ内の.envファイルを変更したい。

**結論：chmodでファイルの権限を変更したらできた。**

<u>起きたこと</u>
wsl2(ubuntu)内にVisual Studio Code(VScode)にてリモート接続を行い、.envファイルを編集すると以下のメッセージが出て保存できなかった。

>'.env' を保存できませんでした。ファイル 'vscode-remote://wsl+ubuntu/home/（ユーザー名）/（フォルダ名）/.env' を書き込むことができません (NoPermissions (FileSystemError): Error: EACCES: permission denied, open '/home/（ユーザー名）/（フォルダ名）/.env')

そこでVScodeで`ターミナル>新しいターミナル`よりbashを開き、`ls -a -l`より.env
ファイルの権限の確認を行った。

```
-rw-r--r--  1 root  root
```

とのこと。
（これの見方は[こちらのサイト](https://boxnos.hatenablog.com/entry/20080107/1199701326)がとても参考になりました。）
そこで、[こちらのサイト](https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95)を参考に、「その他のユーザー」の権限を、

```
sudo chmod 646 .env
```
により変更。

```
-rw-r--rw-  1 root  root
```

これで.envファイルを変更し、保存できた。

なお、これが一般的なやり方かは不明である。VScodeにroot権限でログインする方法とかあれば、そっちのほうがいいのかも。
ubuntu mariadb reinstall

```
sudo apt-get remove "mariadb-*"
sudo apt remove galera-4
sudo apt remove galera-3
sudo apt autoremove
sudo apt install wget

wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup

echo "d4e4635eeb79b0e96483bd70703209c63da55a236eadd7397f769ee434d92ca8 mariadb_repo_setup" \
    | sha256sum -c -

chmod +x mariadb_repo_setup

sudo ./mariadb_repo_setup \
   --mariadb-server-version="mariadb-10.3"

sudo apt update
sudo apt install mariadb-server mariadb-backup -y



sudo rm -rf /var/lib/mysql
sudo apt install mariadb-server
mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
mysql_secure_installation
```