OmniAICreator/Qiita-1.07M huggingface dataset:
レビュー時ノウハウ、コメント例


## 投稿理由、内容
自分自身の振り返りを含めて投稿します。
仕様の指摘、OS・言語としてのベストプラクティス、デグレやアップデート時の確認など
いろいろなレビュー時の観点があると多います。
今回の投稿ではiOS/Swiftで開発してのナレッジになります。

あと、SwiftLintとか入れると勉強になりますよね。٩( 'ω' )و

## 参考になったもの

今回２人体制での開発、相互レビューだったので教えてもらう部分もたくさんありつつ、以下の記事は観点と目的がまとまってたのでわかりやすかったです。
https://qiita.com/kkoide1332/items/4545bf8c2ffbfb05bb1f


## コメント例
その他実際に意識してた部分、レビュー時にコメントされた中でプロジェクト関係なく必要なものを以下にざっくりまとめました。

また、Swift、Cocoaフレームワーク限定の観点もありますので全部が全部ではないです。（get/setはjavaとか普通に使うし）

- 名前get/setつけない。
- BooLでis使う時には考える。意味がおかしくなるのが多いのでhasやshouldなど場合に応じて適宜する。
- typo、インデント大事。
- デザイン確認。
- OS差分、端末差分確認。
- メソッドは何が必要でどのような結果になるかわかるように作る。
　例えば、返却値があったほうが結果がわかる。返却値がない場合はメソッド名をわかりやすく。
　引数を持たせる時もswiftやCocoaの思想に寄せる。
- メンバ変数はできるだけ作らない。というかスコープを狭く。
- Viewをtagで判定しない（UIButtonとかの）。enum作ったり、extentionして分かりやすく。
- 〜Array,Listという名前は使わない。複数形は〜s。
- 配列操作は.mapやfilter。FRPを意識する。
　ループはforinではなくてforEachを使った方が統一感が出て読みやすい（もちろん用途によるが）。
- 略記は使わない。（imgViewやVcはなし。imageViewやviewControllerと書く）
- 2行改行は使わない。（意図があればよし）逆に１行改行は見やすくするためよく使う。
- if文で条件複数の場合で１行が長くなるようだったら改行入れて見やすく。
　`例）if let text = XXXXXXXXXXX.text, `
 `text.isEmpty {}`
- 修飾子は基本privateつける。defaultはinternal。
- classには基本finalつける。
- 命名はUIKitのproperty名に合わせる。ScreenではなくてViewなど
- 読み手に分かりやすいコメントを。素材差し替えするなど修正する場合→TODO: で、不具合ある場合は、FIXME: ,理由や実装経緯はNote：、でコメント追加。
- ifNeededは使っていいと思うが嫌派もいる。
- プロジェクトでコーディングルールを決める。
  例えば、コロンの後に必ず半角スペース。コロンは左の変数に対してかかっている。
- 基本的にメソッドコメントは残さなくて良い。なぜその処理をしているのかの説明のコメントを残す。
- TODOコメントや不要なテストコードはレビュー前に削除。
- 非公開APIはAppleの審査に通らないのでNG。
- 個人情報に関する表示、データの扱いはAppleの規約確認でリジェクト対応。申請時の理由模索。
- StoryboardでのViewの前後関係に注意（どちらが画面手前か）。
- guardで弾いて良いか、ifletで継続させるかチェック。
- didSetかviewDidLoadなどでの設定かは意識する。（funcにするくらい長ければ（10~40行目安）viewdidloadで。他でもそのfuncを使用するならなど。）
- if文内でBoolを変更する場合はelseで反対の値を入れる必要があるかチェック。
- タスク分解はMVC粒度とかが良い気がする。
- readOnlyか外からsetできる必要があるか考慮。コードを読むときの可読性向上。private(set)や変数{}など使用。
- 引数のdefault値を設定する場合、引数名がなくても外から分かりやすいか考慮する。
- typoの気づきが減るよう、英語の勉強と確認必要。公式APIは読めるように。[^1]
- 基本的にViewにaddsubViewする。buttonの上にbutton,imageViewの上にButtonなどaddsubViewしない。
- ViewにModelを持たせない。


[^1]: typoを教えてくれるXcodeの機能については[typo多い自分にとって過去一レベルで便利だったXcodeの機能](https://qiita.com/repepe2en/items/edbba08ca085f50ab2ce)で紹介してます。
ROSセットアップにてsudo rosdep initでコマンドが見つからない

#rosdepエラー

ROSインストール直後にセットアップで

`sudo rosdep init`

を入力する場面があるが、現状

`sudo rosdep init`

をすると

`rosdep: コマンドが見つかりません`

と出る

#解決策

インストールが手動に変わった模様。

`apt install python-rosdep`

する必要あり
JSでvar使って欲しくないな…と思う背景

昔メモしていた内容を公開します。


## var がわかりにくいポイント

```js

var x = "First";

function (){
   console.log(x);
   var x = "Second";
   console.log(x);
}
```
のようになっていた時。

1つめのログでは、なんとなく`“First”`が出力されそうな気がする。
けど実際そうはならなず`undefined`が表示される。

`undefined`は変数定義（使いますよーっていう）はしてるけど、
初期化（あ、とりあえずこの値入れといてー）はしてないよ。
って言われていることと同義。

```js

var x = "First";
```

で初期化してるやん！！って思うけど、

残念ながら

```js

var x = "Second";
```

が宣言されているのでこっちがきいている。

じゃなんで`Second`じゃないんだ！！って思う。

関数の巻き揚げは宣言だけで、初期化（値を代入してるやつ）は見てくれない。
ので、JSとしては、

```js
// `function`に入ってから
// JS < 「お、なんか新しい変数x宣言してるじゃん？」
console.log(x); 
// JS < 「まだ初期化してないのにログ出してるワロタ」
// -> undefined
var x = "Second";
// JS < 「お。ここでxに“Second”を入れるのね。」
// -> void
console.log(x); 
// JS < 「xの中身は…“Second”出してあげよう。」
// -> "Second"
```
と思っている。

## じゃあどうしろと…
結論からいうとvarはわかりにくいから使って欲しくない。
スコープが限定されている
`let(変数)`か`const（定数）`を使いましょう。

ただ、実際のプロダクトコードを書く時はほぼほぼ`const`しか使わないです。
もし自分の書いているコードに`var`がある人は書き直しましょう。
`let`がある人は、`const`にできないか見直してみましょう。

なるべく制約があった方が、意図しない変更やバグの混入を防げます。
【Laravel】Bリーグ試合予想AIのWEBサービスの開発まとめ

# 概要
Bリーグ公式サイトから試合情報を取得し、取得結果から試合スコア予想を算出しWEBに公開する

## サービスURL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/f14719bd-a128-075d-f42f-f852ef6bcc65.png)

https://ssuganoya.com/volspa_ble/public/

## Bリーグ公式
https://www.bleague.jp/

# 開発経歴

## 実装
### 試合結果解析と試合予想【Python】
Bリーグの得失点をヒートマップで可視化
https://qiita.com/SyogoSuganoya/items/6904adf92959838e6a02

### デザイン当込【Laravel】
【Laravel】環境構築から各機能の実装
https://qiita.com/SyogoSuganoya/items/8a73167566dd7b36de26

Laravel入門 - 使い方チュートリアル -
https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d

## リリース
### Xserverへアップロード

Laravelで作成したWEBアプリをXServerでデプロイするまで
https://qiita.com/huhe/items/6c3c35005bb8c010614e

---

#### 参考
Laravelで作成したWEBアプリをXServerでデプロイするまで
 https://qiita.com/ryouta0506/items/100a2b252fbaeb73f493
ffmpegでwavをmp3に一括変換

Linux系OSでおなじみ、ffmpegを使って
ディレクトリ配下のwavをmp3に一括変換します。

変換後のファイル名が.wav.mp3にならないようにする方法も紹介します。

###環境
- mac OS : Catalina version 10.15.6
- ffmpeg : stable 4.3.1 (bottled)


# 一般的な変換
1つのファイル変換なら、以下で実行できます。

```
$ ffmpeg -i input.wav ouput.mp3
```

# 一括変換
ディレクトリ配下にあるファイルを一括変換する場合は、以下のような方法で変換できます。

```
$ for f in *.wav ; do ffmpeg -i $f ${f%.wav}.mp3 ; done;
```

ちなみに、`$f.wav`ではなく`${f%.wav}`としてあげることによって
`.wav`の部分を除いたmp３ファイルに変換することができています。

.
.
.

ファイルの変換はできたけど、`.wav.mp3`となってしまって困っている人の
役に立てたら嬉しいです。
Twitter OAuth認証のコールバックURLでintent-filterが反応してくれない

Twitter OAuth認証のコールバックで自分のアプリに制御が戻ってくれない
というハマりがあったのでメモ。

---
Twitterアプリ登録ページで、
コールバックURLはhttp://かhttps://で始まらなければならない、と書いてあるので
最初、存在しないURLや存在するURLを色々試したが、
intent-filterが反応しなかった。

---

実際には、コールバックURLは

**”独自スキーマ://”　**

という構文でも登録を受け付けてくれる。

>Callback URL
>zanapp://


---

次に、
AndroidManifest.xmlのandroid:hostとコールバックURLのhostが
両方とも無し、
という設定で試したが、やはり反応しない。

---

そこで、
アプリのソースコードで、
コールバックURLのスキーマに**ホスト**(test)を付けてみた。

（AndroidManifest.xmlのandroid:hostとコールバックURLのhostが
　両方ともあり、の設定。）

```java:TwitterOAuthActivity.java
mRequestToken = mTwitter.getOAuthRequestToken(zanapp://test);
```

```AndroidManifest.xml
<intent-filter>
	<action android:name="android.intent.action.VIEW" />
	<category android:name="android.intent.category.DEFAULT" />
	<category android:name="android.intent.category.BROWSABLE" />
	<data
		android:host="test"
		android:scheme="zanapp" />
</intent-filter>
```

これでブラウザのTwitter認証からのコールバックで
**アプリに制御が戻る** ようになった。

---

独自スキーマじゃないとintent-filterが反応しない？？？
原因がよく分かりません。
AWS の Change Calendar が突然 404 になった

昨日まで使えていた AWS の Change Calendar 機能 ( `aws ssm get-calendar-state` ) が、今日になって突然 404 を返すようになった。

あわてて管理コンソールから見に行ったら、リスト上にはあるように見えるのに、 View details も Edit も Delete も反応しない。なんで？

Create calendar で新しいカレンダーを作るとそちらは反応する(編集も削除できる)ので、AWS 様がなにかやらかしてるようにしか見えないけど…。

個人で使ってるアカウントだから、しょーもない Lambda が1個エラーになっただけで済んだけど、これ、仕事で使ってる人がいたらヤバいんじゃないかなぁ？
Push通知の証明書作ってみた in　最近



## はじめに
あんまり頻繁に作るものではないですが
業務で得た内容をこちらに残します。

## Push通知証明書って

iOSって証明書多いですよね。
ただ、developperサイトで一括管理できることは楽なのかも。


## p12ファイル作成手順

①デスクトップのLaunchpadをクリック

![20200725023041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/79657141-f03a-e554-be60-e9c026393428.png)


②Launchpadのその他をクリック

![20200725023045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/d36faeba-8a7f-d966-882c-b7640d4131d8.png)


③その他をクリック

![20200725023058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/d86e20da-051a-3b56-6e7e-9be7f8a97e38.png)


④秘密鍵(画像内の鍵マーク)が証明書内に入っていることを確認する

![20200725023749.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/2a0991d0-61db-21f6-2591-ea7dd65df580.png)


⑤右クリック（MACだと２本指タップ）で証明書を選択	

![20200725023753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/64002caa-9fe6-b557-ef39-82d7128c5cf0.png)

	

⑥選択した証明書を書き出す…をクリックする


⑦名称にp12ファイルに適当な名前を入力し場所項目で出力先を決定し（画像の場合は書類）保存ボタンを押下する									
			
![20200725024558.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/c03845a9-19cf-05c2-4a41-37e211dce188.png)


⑧p12ファイルを別端末でインストールする際に必要な展開パスワードを入力しOKボタンを押下する

![20200725024602.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/ebb6ce2d-7366-3a8f-afbe-398e66d6d77f.png)



⑨キーチェーンで書き出すためにPCのログインパスワードを入力し許可ボタンを押下する

![20200725024605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/42915d4c-90cc-4645-403d-1a9228adea74.png)



⑩手順⑦で指定した出力先にp12ファイルが書き出される。

![20200725024609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701264/4db35332-7d1e-e05f-b512-2ed970f3fcb7.png)



iOSってプロビジョニングプロファイルとか証明書とかアプリBundle IdentifierとかUDIDとかアプリ作り始めるまでがやたらめんどいんだよなぁ...
Jquery アウトプット

```
class TodosController < ApplicationController
  def index
    @todo = Todo.new
    @todos = Todo.order('created_at ASC')
  end

  def create
    @todo = Todo.create(todo_params)
    respond_to do |format| 
      format.html { redirect_to :root }
      format.json { render json: @todo}
    end  
   

  end

  private
  def todo_params
    params.require(:todo).permit(:content)
  end    
end
```
respond_to do |format| レスポンスに応じてHTMLかJSONか分岐させる
      format.html { redirect_to :root }HTMLのレスポンス
      format.json { render json: @todo}JSONのレスポンス
    end  

```
$(function() {
 function buildHTML(todo){
   let html = $('<li class="todo">').append(todo.content);
   
   return html;
 }
 $('.js-form').on('submit', function(e) {
   e.preventDefault();
   let todo = $('.js-form__text-field').val();
   $.ajax({
     type: 'POST',
     url: '/todos.json',
     data: {
       todo: {
         content: todo
       }
     },
     dataType: 'json'
   })
   .done(function(data) {
     let html = buildHTML(data);
     $('.todos').append(html);
     $('.js-form__text-field').val('');
   })
   .fail(function() {
     alert('error');
   });
 });
});  
```
let html = $('<li class="todo">').append(todo.content);　　　　　　　　　　appendで（todo.content)のバリューを'<li class="todo">'に内に追加して変数htmlへ代入。


$.ajax({　　非同期通信をする時の記述
type: 'POST',　POST　と　GETの２種類
     url: '/todos.json',　リクエスト送信先
     data: {todo: {content: todo}},　送信するデータ
     dataType: 'json'　サーバから返すデータの型
   })　　　

.done　非同期通信成功時の処理を記述　　　　　　　　　　　　　　

.fail  非同期通信失敗時の処理を記述

.val()　バリューを取得する。


 $('.js-form').on('submit', function(引数) {
.preventDefault();
QMK で D&D を設定する

# 問題と環境

- QMK Firmware 0.9.50

`keymaps` でキーに `KC_MS_BTN1` `KC_BTN1` などを設定しているが，キー押下時に `mousedown` と `mouseup` が同時に発行されて，ドラッグアンドドロップなどが出来ない．


# 原因

`pointing_device_send()` が呼ばれるとマウスレポートが0クリアされてしまう仕様が原因らしい．
`POINTING_DEVICE_ENABLE = yes` していると発生するっぽい…？

[コード](https://github.com/qmk/qmk_firmware/blob/master/quantum/pointing_device.c#L36)
[参考](https://github.com/qmk/qmk_firmware/blob/master/docs/ja/feature_pointing_device.md)


# 解決方法

`custom_keycodes` に独自マクロを定義する．

```c:keymap.c
enum custom_keycodes {
//  ...
    KC_MY_BTN1,
    KC_MY_BTN2,
    KC_MY_BTN3,
};
//  ...

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
//  ...
    switch (keycode) {
//  ...
        case KC_MY_BTN1:
        case KC_MY_BTN2:
        case KC_MY_BTN3:
        {
            report_mouse_t currentReport = pointing_device_get_report();
            uint8_t btn = 1 << (keycode - KC_MY_BTN1);
            if (record->event.pressed) {
                currentReport.buttons |= btn;
            } else {
                currentReport.buttons &= ~btn;
            }
            pointing_device_set_report(currentReport);
            return false;
        }
//  ...
    }
    return true;
}

```

[参考コード](https://github.com/TumoiYorozu/zetta-keyboard/blob/master/keymaps/default/keymap.c)
【OpenJavaFX】「エラー: JavaFXランタイム・コンポーネントが不足しており、このアプリケーションの実行に必要です」と表示される

# 状況
IntelliJ IDEA で TornadoxFX プラグインを導入し、 その機能で Run/Debug を行うと

```
エラー: JavaFXランタイム・コンポーネントが不足しており、このアプリケーションの実行に必要です
```
というエラーがコンソールに表示されてしまう。

# エラーが出る原因
`JavaFX Gradle Plugin` は依存関係を `javafx{}` 内で書く関係で
モジュールの参照が上手くされない。

# 対処法
`Run/Debug Configurations -> VM Option` に以下を追加する。

```
--module-path $Classpath$ --add-modules javafx.controls,javafx.fxml
```

build.gradle.kts(build.gradle) の `modules` を `--add-modules` の後ろに羅列しておけば大丈夫です。~~（まあ `javafx.controls,javafx.fxml` な人がほとんど？)~~

```build.gradle.kts
javafx {
    modules = listOf("javafx.controls", "javafx.fxml") // ← ここ
}
```

# 小噺
`VM Option` の `$Classpath$` はマクロでクラスパスの羅列に置換されています。

# 解決の参考にさせていただいたページ
https://ja.stackoverflow.com/questions/49019
Twitterクローンもどき作成までの過程


PC版のTwitterのようなサイトを作ろうと思って調べたことをまとめていきます

#要素をきっちり3分割
```css
target{
 width : calc(100% / 3) ;
}
```
参考：[【CSSで3等分】要素をきっちり三分割するスタイルシートの書き方](https://codelife.cafe/entry/2015/10/17/221011)

#画面サイズ取得
画面取得するには以下を使用する
この取得したサイズに応じて表示する内容を変更したりする
どちらもスクロールサイズを除くサイズ
###縦サイズ
```javascript
document.documentElement.clientWidth
```
###横サイズ
```javascript
document.documentElement.clientWidth
```
##画面サイズ変更の監視
```javascript
window.addEventListener('resize',()=>{
  //処理
}
```
参考：[要素のリサイズに応じてイベントを発動する方法](https://techacademy.jp/magazine/22266)
#入力ボックス
入力ボックスはHTML5の contentEditable 属性を使う
この属性をtrueにすると編集できるようになる
inputを使うよりもシンプルな入力画面になる

```html
<div contentEditable="true">入力ボックス</div>
```
#aの下線部を消す
```css
text-decoration: none;
```

#Twitterのようなタイムラインの形のテンプレート
```html
<body style="background-color:rgb(54, 3, 3)">
    <div style="background-color: rgb(107, 107, 2);width: 500px;display: inline-flex;">
        <!-- ユーザ情報 -->
        <div style="background-color: rgb(104, 101, 101);">
            <img src="image/bell.png" alt="" style="width: 50px;">
        </div>
        <!-- 投稿内容 -->
        <div style="display: block;">
            <div style="background-color: rgb(109, 65, 65);">あああ</div>
            <div style="background-color: rgb(69, 65, 109);">いいい</div>
            <div style="background-color: rgb(65, 109, 88);">ううう</div>
            <!-- <div contenteditable="true" style="background-color: rgb(65, 109, 88);">ううう</div> -->
        </div>

    </div>

</body>
```
![スクリーンショット 2020-09-19 23.45.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136271/7b912d6d-e915-d91e-fc7d-abed8da3975e.png)

#block要素を上下左中央に配置
```css
.outer{
  position: relative;
}
.inner{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateY(-50%) translateX(-50%);
  -webkit- transform: translateY(-50%) translateX(-50%);
}
```
引用：[CSSで要素を上下や左右から中央寄せする7つの方法](https://www.granfairs.com/blog/staff/centering-by-css)

#フォーカスインとフォーカスアウト
addEventListenerでコントロールするものいいが特定のタグであれば
`onfocus`と`onblur`属性がいい仕事をしてくれる

|属性|説明|
|---|---|
|onfocus|フォーカスしたとき|
|onblur|フォーカスアウトしたとき|

```html:例
<input placeholder="キーワード検索" type="text" onblur="focusOut(this)" onfocus="focus(this)">
```
thisでその要素自体を取得できる

#文字を中央に持ってくる
```html
<div align="center"><p>中央</p><div>
```
#部分スクロールを可能にする
```css
<div style="overflow: auto;>
```
高さ調整も忘れずに

#画像を幅に合わせてトリミング
```css
img {
  width: 250px;
  height: 250px;
  object-fit: cover; /* この一行を追加するだけ！ */
}
```
引用：[1行追加でOK！CSSだけで画像をトリミングできる「object-fit」プロパティー](https://www.webcreatorbox.com/tech/object-fit)

好きな場所でトリミングするときは`object-position: 値 値;`を使う

```
画像の左下でトリミング
object-position: 0 100%;
画像の右下でトリミング
object-position: 100% 100%;
```
#気になったcssプロパティなど
##flex-basis
コンテンツボックスの寸法を定義![スクリーンショット 2020-09-19 23.45.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136271/68e48073-f210-779e-491f-c0f4e7a4418a.png)
【Golang】Go言語の基礎　結局ポインタって何なの？？

Go言語やC言語を学ぶ上で避けては通れないのがポインタです。
プログラミング初学者の入門言語であるRubyやPHPにはポインタという概念がありません。
Rubyから入った僕にはいろんな記事を読んでも？？？でした！そんな方にもわかるようにここでは解説いたします！

#ポインタとは？
プログラムというのは、メモリの中で読み込まれ、CPUで処理されます。また、僕たちが普段プログラムで使っている変数というのはメモリの中に配置されます。CPUによってメモリの中に配置されている変数の値を処理しているのです。
**ポインタというのは、変数がメモリのどこに配置されているか？という情報（変数の住所）を格納する変数のことです。**

##早速コードを書いてみる
```go

package main

import "fmt"

func main() {
	var n int = 10
	fmt.Println(n) // => 10

    //アンパサンドを付けることで変数を入れたメモリの住所（正式にはアドレスといいます。）が表示できる。
	fmt.Println(&n) // => 0xc00002c008

    //* を付けることでintgerのポインタ型の変数p（変数nのアドレスを入れる箱）を用意できる。
	var p *int = &n 

	fmt.Println(p) // => 0xc00002c008
        
    //変数pの値を表示したいときは*pとすると、値を表示できる。
	fmt.Println(*p) // => 10

}
```

var 変数名 *データ型 とすることで、変数のアドレスを格納する変数を宣言することができます。
ここに変数のアドレスを入れるためには &変数名とするとその変数のアドレスを格納できます。
格納したアドレスの値を表示したい場合、*変数名とすることによって値を表示することができます。

##もう少し書いてみる。
```go

package main

import "fmt"

func one(x int) {
	x = 1
}

func main() {
	var n int = 10
	one(n)
	fmt.Println(n) // => 10

}
```

↑に書いたコードはone関数の引数に値しか渡していないので、最初にmain関数で宣言したxに影響はありません。

実際にxの値を更新するにはxのアドレスを引数に渡す必要があります。このようなことをしたいときにポインタが使われます↓

```go

package main

import "fmt"

func one(x *int) {
	*x = 1
}

func main() {
	var n int = 10
	one(&n)
	fmt.Println(n) // => 1

}
```

one関数の引数に&nとしてnのアドレスを渡しています。その際引数はポインタ型でなければアドレスを受け取ることができないので x *int としてポインタ型の引数を定義しています。
これはやっていることとしては最初にやった var p *int = &n とやっていることは同じだとわかります。

##最後まで読んでいただきありがとうございます！
何かご指摘などございましたらコメント等いただけると嬉しいです！！
【Java】Enumでif文を少なくする

# はじめに
保守・開発でプログラムに触れる際、その８割はソースコードを読む時間に費やされるというのはよく聞く話です。
そのため、可読性の高く、保守性の高いソースコードというのは常に意識されるべきですが、どうしても業務システムとなると、ある契約の種類だとか、取引先の種類だとか、種類による条件分岐がどうしても多くなりがちだと感じています。
そこで、if文を少なくなるする方法の１つとしての、Enumを使用した方法があるということを知ったので、忘れないように投稿します。

# if文を少なくするメリット
if文による条件分岐が多い場合、Enumを使用することでとても読みやすくなります。

# 具体例
```SampleEnum.java
public enum SampleEnum {

	kind1(new Kind1()),
	kind2(new Kind2()),
	kind3(new Kind3()),
	kind4(new Kind4());

	SuperKind kind;

	private SampleEnum(SuperKind kind) {
		this.kind = kind;
	}

	public void execute(Object obj) {
		kind.execute(obj);
	}
}
```
まずはEnumを用意します。
次に、各プロパティに対して、実行したい処理クラスを記載し、コンストラクタを定義します。
最後に、実行したい処理クラスの実行メソッドを定義します。

Enum自体は、この３ステップで実装完了です。
あとは、種類が追加された場合は、プロパティを追加して、その種類ごとに実行したい処理クラスを記載するだけです。
　  

```Kind1.java
public class Kind1 implements SuperKind {

	public void execute(Object obj){

		if(!(obj instanceof String)) {
			System.out.println("引数には文字列を指定してください");
		}
		System.out.println("Kind1のクラスで" + obj);
	}
}
```
実行したい処理クラスです。
ここでは簡単に、そのクラスで実行されたことがわかる文を、コンソールに出力するようにします。
SuperKindは、interfaceです。ここでは中身は`execute`メソッドを定義しているだけなので、割愛します。
　  

```Main.java
public class Main {

	public static void main(String[] args) {

		SampleEnum test1 = SampleEnum.valueOf("kind1");
		SampleEnum test2 = SampleEnum.valueOf("kind2");
		SampleEnum test3 = SampleEnum.valueOf("kind3");
		SampleEnum test4 = SampleEnum.valueOf("kind4");

		String string = "Enumのテスト";

		test1.execute(string);
		test2.execute(string);
		test3.execute(string);
		test4.execute(string);
	}
}
```
mainクラスです。ここで実行した結果は、以下の通りになります。

```console
Kind1のクラスでEnumのテスト
Kind2のクラスでEnumのテスト
Kind3のクラスでEnumのテスト
Kind4のクラスでEnumのテスト
```


# 最後に
このような実装をすることで、Factoryクラスでのif文判定を減らすこともできれば、どの業務ロジック処理を呼び出すかなどのif文判定を減らしたりなど、活用の幅は大きいかと感じました。
Mac が勝手に複製した "hoge 2.txt" 的なファイルを一括削除する

## "`hoge 2.txt`"、それは突然現れた
僕、Github の private リポジトリに高専時代・大学時代の歴史をバックアップしてるんですけど、そのローカルファイルを iCloud Drive にも保存してたんですね。
今日ファイルの中身が見たくなって雲のマーク「ぽちー」って押して、ローカルに落としたんです。

一通り閲覧して満足したので、一応変な diff が無いか確認するために `git status` を叩きました。

すると「ズラズラズラーーーーーーー」っと無数にアウトプットが。。。。
しかも全部 `unstaged files` なんですよ。

「怖いなー、怖いなー。何も追加してないのになー。」
って思ってよく見ると、全部「`hogehoge 2.pdf`」みたいに、 "` 2`" っていうのが拡張子の直前に付いてたんです。。。

それはなんと、全部 Mac が勝手に複製したファイルだったんです。。。。

## 対処法
はい。ということで、真面目に対処法をシェアします。
症状としては勝手にファイルが複製されて、全部拡張子の直前に ` 2` が付いている状態です。
例: `hoge.txt` の複製ファイルとして `hoge 2.txt` が作られている。

今回はこの、 2 とついたファイルだけを削除するワンライナーを紹介します。
結論から言うと、

```shell
$ find . -maxdepth 10 -type f | grep " 2\.*"| sed -e 's/ /\\ /g' | xargs rm
```

というコマンドを叩けばいいです。
お疲れ様でした。

。。。で終わるのもなんか味気ないので、軽く解説します。

## 解説
ワンライナーをもう一度。

```shell
$ find . -maxdepth 10 -type f | grep " 2\.*"| sed -e 's/ /\\ /g' | xargs rm
```

これをパイプ毎に分けると、

1. 深さを指定して列挙: `find . -maxdepth 10 -type f`
2. ` 2.` と付くファイルのみに絞り込み: `grep " 2\.*"`
3. スペースをエスケープ: `sed -e 's/ /\\ /g'`
4. 削除: `xargs rm`

一つづつ解説します。

### 1. 深さを指定して列挙: `find . -maxdepth 10 -type f`
これは特に問題ないかと思います。
今回は下階層全て検索したかったので、 `-maxdepth 10` を付けて 10 階層下まで見に行くようにしています。

`find .` を `find ${path/to/directory}` とすれば好きなディレクトリについて検索できます。

### 2. ` 2.` と付くファイルのみに絞り込み: `grep " 2\.*"`
ここも特筆することはないです。

`.` はそのままだとエスケープが必要なので、バックスラッシュを付けて `\.` としています。
これで `${半角スペース}2.` をファイル名に含むものだけ抽出できます。

### 3. スペースをエスケープ: `sed -e 's/ /\\ /g'`
これがこのワンライナーの肝だと思います。
何をしているかと言うと、半角スペースにバックスラッシュを付けてエスケープさせています。
理由としては、このまま rm コマンドに渡してしまうと、半角スペースで区切られて別ファイルとして扱われてしまうためです。

---

例: `hoge 2.txt` というファイルを削除する場合

1. `rm hoge 2.txt` を実行してみる
2. `rm` コマンドの気持ちとしては `hoge` と `2.txt` というファイルが渡されたと勘違い
3. 「そんなファイルは無いよ」と言われるか運悪く `hoge` または `2.txt` ファイルが意図せず削除されてしまう

---

なんかスラッシュばっかりで分かりにくいとは思いますが、置換コマンドは

```shell
$ sed -e 's/${置換前}/${置換後}/g'
```

でその行に含まれた全ての対象を置換してくれます。
このコマンドとの diff を取れば、

- 置換前テキスト: `${半角スペース}`
- 置換後テキスト: `\\${半角スペース}`

というように指定していることが分かると思います。
さらに、バックスラッシュが連続しているのは、バックスラッシュそのものをエスケープするためで、実質 1 つのバックスラッシュを付けています。
つまり、半角スペースの前にバックスラッシュを付けているのです。

これにより、 `rm` コマンドが勘違いせずやってくれるはずです。

### 4. 削除: `xargs rm`

なんてことはないですが、最後に絞り込まれ、半角スペースをエスケープしたファイル名が指定され、削除される。

という全体的な流れです。

## 参考
- [パスに半角スペースが含まれるfindの結果をgrepしてxargsで削除する方法](https://qiita.com/ponsuke0531/items/f32fae15ed943a264b36)
【M5Stack UIflow】 Macのデスクトップ版ではテキストのコピペができない

タイトル通りです。

2020年9月22日現在、
M5Stack UIflow Macのデスクトップ版ではテキストのコピペができません。

たとえば、

![画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/86662333-3a10-95c9-5d8b-9d7003609978.png)

このURLは、コピペできないので、ベタ打ちしなければいけません。
これくらいならまだしも、APIのURLなんか、絶対無理です。

とはいえ、数時間この状況でやってましたが、あまりにも効率が悪いので、ググってみたら、これら先人の方々のツイートからMacのデスクトップ特有のものだと分かり、ことなきをえました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Mac版の <a href="https://twitter.com/hashtag/M5Stack?src=hash&amp;ref_src=twsrc%5Etfw">#M5Stack</a> <a href="https://twitter.com/hashtag/UIFlow?src=hash&amp;ref_src=twsrc%5Etfw">#UIFlow</a> DesktopIDEってなぜテキストの中身がコピペできないの？テキストを打たないといけないのつらい。</p>&mdash; wakasa masao (@wks) <a href="https://twitter.com/wks/status/1253916207796809728?ref_src=twsrc%5Etfw">April 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ついさっき気づいて、IoTLTでも登壇者がテーマとしてたUIFlowですが…デスクトップバージョンのUIFlowのアプリではコピペができない(Mac)！URLとかきついのでブラウザ版がよいと思う <a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a></p>&mdash; るしわん (@tkyko13) <a href="https://twitter.com/tkyko13/status/1305818637257699329?ref_src=twsrc%5Etfw">September 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Juliaの「Merly」のExampleを見ながら動かしてみる

JuliaのMerlyというマイクロフレームワークを使ってみた。
[codeneomatrix/Merly.jl: Micro framework for web programming in Julia](https://github.com/codeneomatrix/Merly.jl)
READMEにExampleがついているので、これを動かしてみる。


## Install

Pkgでインストールする。
インストールすると `0.2.1` というバージョンが入るが、このタグは2019年に作られたもので、古くなっている。
なので、masterブランチを指定してインストールする。

```julia
pkg> add Marly#master
```

## READMEのExampleを見ながら動かす

以下をREPLにコピペするか、jlファイルに書き込みjuliaコマンドで実行する。

```julia
using Merly

# page: GETリクエストに対応したルートを設定する
@page "/" "Hello World!"
@page "/hello/:usr>" "<b>Hello {{usr}}!</b>"

# route: 第1引数に指定したリクエストに対応したルートを設定する
# 「|」で区切ると複数同時に設定可能
@route GET "/get/:data>" begin
  "get this back: {{data}}"
end

@route POST "/post" begin
  println(req.body)
  res.body = "I did something"
end

@route POST|PUT|DELETE "/" begin
  println(req)

  "I did something!"
end

# GET, POST, PUT, DELETE: それぞれに対応したルートを設定する
# reqest, responseを無名関数の引数に指定できる
Get("/data", (req, res)->(begin
  res.headers["Content-Type"] = "text/plain"
  "You Got"
end))

start(port=1234)
```
「ゼロから作るDeep Learning 」でModuleNotFoundError: No module named 'dataset.mnist'が出る理由。

#目的
「ゼロから作るDeep Learning 」のGitHubのコードで

```
ModuleNotFoundError: No module named 'dataset.mnist'
```

が出る理由が
一応、わかったので、
説明。
( **世間の質疑が、なんか、かみ合ってないと感じたので**、、、、ちょっと、調べました。）

#説明
##原因
原因は、既に、**別の名前の「dataset」というモジュールがある**ためです。
以下のとおり、
pythonを起動して、
datasetをインポートして、
場所を調べると、どこにあるかはわかります。

```
C:\_qiita\_zero\deep-learning-from-scratch-master\ch08>python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>> import dataset
>>> dataset.__file__
'C:\\Users\\XYZZZ\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages\\dataset\\__init__.py'
>>>
```
##対策
今回のdatasetをdataset_zeroとかに変更するとか、
そんな方法がいいのではないでしょうか？

#まとめ
この記事は、ちょっとは、役に立つかも。
コメントなどあれば、お願いします。:candy:
以前も一回同じようなことを経験したことある気がするので、**pythonあるある**、かも。
南の島に思いを馳せながらコンピュータを使う

# 南の島の命名ルール
私が [NAIST](https://www.naist.jp/) の学生だったころ（2000年代中盤）、計算機ネットワークの研究をしている研究者たちが学校全体のネットワークを管理していた（彼らにとってそれは「研究対象」なので）。

私が所属していた研究室の各コンピュータには、ホスト名に **「南の島の名前」** を付けるルールが彼らから与えられていたので、研究室の各メンバーは自分のローカルマシンにトロピカルな名前を付けていた。

私のマシンは「phuket（プーケット）」だった。
それ以来、自分のメインマシンは常に「phuket」にしている。

最近、Mac mini を買って「borneo（ボルネオ）」と名付けた（メインの Windows マシンが phuket なので）。
その Mac に VirtualBox を入れて Ubuntu Server 20.04 をインストールし、それを「tonga（トンガ）」にした。

島の名前はいくらでもある。
例えば、cebu（セブ島）、bali（バリ島）、tahiti（タヒチ島）、borabora（ボラボラ島）などなど。トロピカルな名前の PC を触るのが、結構楽しかったりする。

ちなみに、プーケットにはまだ行けていない。
いま値段を調べたら、コロナの影響のせいかむちゃくちゃ安いので、来月あたり日本にいないかもしれない。
![phuket.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/81c0087e-cd51-c3df-e362-64188f8dc9d7.jpeg)

# eurasia が沈んだ
当時はクラウドストレージの概念がなかった。全学共用の遅いファイルサーバを使うか、研究室で買ったマシンをファイルサーバにして自前で管理するかしかなかったのだ。

博士課程に進学したころ、当時としては超大容量のストレージを積んだマシンを買ってもらい、これをファイルサーバにすることにした。その管理を任された私としては、トロピカルとはいえ小粒な感じしかしない島の名前を付けるのは嫌だったので、**「eurasia（ユーラシア）」** という世界最大規模の名前を付けて、学内ネットワークの管理者に DNS 登録を申請した。

すると、**「eurasia は南の島じゃないよね？大陸だよね？南どころか島ですらないよね？」** という回答が来た。実にごもっともだ。

それに対して、私は **「こまけぇこたぁいいんだよ！！」** という趣旨の返答をし、「こいつに関わるとめんどくさい」感を与えて押し切った。

eurasia は、研究室初の大容量ファイルサーバとして華々しくデビューし、皆の貴重な研究データをパワフルに受け入れていった。どれだけデータを突っ込んでも、「df -h」を叩いて表示される「Use％」はほとんど変化しなかったことに興奮した（…と言っても、いまなら個人の PC に普通に搭載されている容量でしかないはずだけど）。

そして、**ある日突然、eurasia は沈んだ**。ストレージが物理的に逝ったのだ。使うことに夢中で満足に RAID を組んでいなかったので、１週間かけて学習した私の強化学習エージェントの学習パラメータも、書きかけの論文も、**皆のデータが全部ブッ飛んだ**。

その後どうなったかは、忘れた。都合の悪いことは全部忘れるタチなので。
ただ、それ以降私が管理するファイルサーバは信用をなくし、皆が rsync で定期的に全学共用のサーバにバックアップをとることになったことは覚えている。

〜〜Fin〜〜
Mac上にTryHackMe用のKali Linux仮想環境を構築する

Tryhackme上の問題をKali Linuxで解きたかったけど色々ややこしかったので備忘録を兼ねて

```shell:環境
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G5033
$ VBoxManage --version
6.1.12r139181
$ VBoxManage list vms | grep Kali                                                                                                                                                    
"Kali-Linux-2020.3-vbox-amd64" {0ab4e32c-80e6-4a48-8a77-63ddba2ea0bf}
```

# Kali Linux仮想環境構築編
1. VirtualBoxのインストーラを[公式ダウンロードページ](https://www.virtualbox.org/wiki/Downloads)からDLし実行.

2. Offencive Securityが配布しているKali Linuxのovaファイルを[このリンク](https://www.offensive-security.com/kali-linux-vm-vmware-virtualbox-image-download/)からDL. (ovaファイルはメモリやディスク容量などの仮想マシンの設定とOSイメージが一緒になったファイル. インポートするだけで簡単にゲストOSを立ち上げ可能です.)

3. VirtualBoxメニューバーの`ファイル > 仮想アプライアンスのインポート…`から先程のovaファイルをインポート. 設定はそのままでも大丈夫です.

4. マシン一覧から`Kali-Linux…`を選択し起動. 

起動しようとした時に`implementation of usb 2.0 ...`みたいなエラーが出る場合は, 指示に従って[VirtualBox Extension Pack](https://www.virtualbox.org/wiki/Downloads)を導入します.
MacのせいなのかDLしたファイルの拡張子が.gzになっちゃってるので, .vbox-extpackに直してダブルクリック. あとは指示に従うだけで導入できます. 
古いままのVirtualBoxを使ってたりしているとVBox本体とExtension Packのバージョンが一致せずエラーが出るので忘れずにアップデートしておきましょう.

　5.　無事起動できたら`user:kali pass:kali`でログイン.

# OpenVPN周りの設定
TryHackMeの問題サーバーにアクセスするにはOpenVPNを経由する必要があるため, そちらの設定を行っていきます. 

##TryHackMeでConfiguration Fileの発行
https://tryhackme.com/access にアクセスするとOpenVPN用の設定ファイルをDLできます. 
適当にVPN Serverを選択し緑のボタンを押しましょう. 

親切なことに[OpenVPNのインストラクション用のRoom](https://tryhackme.com/room/openvpn)が存在するので, ここでソフトウェア等のセットアップをしてちゃんと接続できているか確認しておくと安心できます. 

##ゲストOSとファイルの共有
先程DLしたovpnファイルゲスト側に移すため, VirtualBoxの共有フォルダの設定をします. 

VirtualBoxマネージャーでKali Linuxを選択し, 歯車マークの設定を開いて適当なフォルダを共有フォルダとして追加しましょう. 自動マウントはオンにしておきます. そのフォルダに先程のovpnファイルを置き, Kali Linuxを再起動します. 

ファイルは`/media/sf_hogehoge`下にあるのですが, このままゲスト側から読み込もうとするとpermission deniedされるので, `$ gpasswd -a kali vboxsf`でユーザーkaliをグループvboxsfに追加し権限を付与し再び再起動. アクセスできるようになっていると思います.  

参考 http://itemy.net/?p=1355

扱いやすいように適当なフォルダにコピーしておきましょう.

```shell
$ mkdir ~/tryhackme
$ cp /media/sf_hogehoge/uswest.ovpn ~/tryhackme
```

## Kali Linux上からGUIを使ってVPNと接続する
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456607/2842435e-cf38-31f0-7ab8-ae90df3205de.png)
`メニューバーの□ > VPN Connections > Configure VPN…`
からネットワークの設定を開き, +ボタンから新しい接続先を設定します. Connection Typeは`Import a saved VPN configuration…`を指定し先程のファイルを選択しましょう. あとは`VPN Connections`に表示される接続先のチェックボックスにチェックを入れるだけでVPNを経由できるようになります.
一応先程のRoomをゲストマシンのブラウザで開いて確認しておくといいでしょう. 


## CUIで接続する

`$ sudo apt install openvpn`しようとするともうopenvpnが入っていると言われますが, パスが通っていません. バイナリ本体がどこにあるのかも分からないので`$ dpkg -L openvpn`で探すと, 何個か出てくる内の`/usr/sbin/openvpn`がそれっぽいです. 
実際`$ sudo /usr/sbin/openvpn ~/tryhackme/xxxx.opvn`で動作します. 
`export PATH=$PATH:/usr/sbin`でパスを通しておけば`$ sudo openvpn ~/tryhackme/xxxx.opvn`でVPNに接続できるようになります. 

以上です.

(余談)
ホストマシン上の使い慣れたターミナルでKali Linuxに接続して問題を解きたい, それに面倒だからゲストOSのウィンドウを開きたくない, という思いがあったのでCUIでOpenVPNに接続できるようしたのですが, ゲストOSのshellに接続するのが思ったより面倒そうで結局そこまでやりませんでした…
「ゆとりの法則 － 誰も書かなかったプロジェクト管理の誤解」感想

[ゆとりの法則 － 誰も書かなかったプロジェクト管理の誤解](https://www.amazon.co.jp/%E3%82%86%E3%81%A8%E3%82%8A%E3%81%AE%E6%B3%95%E5%89%87-%EF%BC%8D-%E8%AA%B0%E3%82%82%E6%9B%B8%E3%81%8B%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E7%AE%A1%E7%90%86%E3%81%AE%E8%AA%A4%E8%A7%A3-%E3%83%88%E3%83%A0%E3%83%BB%E3%83%87%E3%83%9E%E3%83%AB%E3%82%B3/dp/4822281116)
トム・デマルコ (著)

何年ぶりだが分からないけど再読してみたので、感想等記載してみます

#イブの様になりたい
天地創造においてイブは、好奇心、勇気、剛胆さをもって、禁じられた「善悪を知る木の実」を食べてしまう。
でも、それによって、自分自身の成長を狭い枠の中にとどめることなく、前に進んでいく。
僕もイブの様に、勇気をもって前に進んでいきたいし、
周りや部下にイブの様な逸材がいれば、その人と共に前に進んでいく勇気を持ちたいと思う。

でも、これが思いのほか難しい。
自分の属する組織に不満がある場合、その組織を少しずつでも変革していくか、自分がそこから去るかしかないが、
変革を望まない、その場所に安住した組織では、どうすれば良いのだろう？
(僕は去ることを選んでしまったが)
少なくとも、将来、僕が変革を邪魔する側にならなようには気を付けたい

#ゆとりを持つということ
管理者は、自分と部下の業務時間を、タスクで埋める誘惑に勝たないとならないのです。

業務時間をタスクで埋めてしまえば、
難しいことを考える必要が無くなるし、
仕事をした気になれるし、
周りから見ても仕事をしているように見えるので
非常に楽だし、安心なのです。

でも、そうしてしまえば、組織全体が改善するためのゆとりを失うのです。
ゆとりが有るから、やり方を変えることを考え、試すことが出来るのです。

特に管理者は、組織がどこに向かうのか、どこにマンパワーをかけ
何を変えていくのかを考えるのが仕事なわけで、
これは苦しい仕事ですし、失敗する可能性もあるし、評価が下がる可能性もあるわけです。
でも、ここから逃げてはいけないわけです。

もちろんメンバーも一緒で、上司からとにかくタスクを割り当ててもらって、
無心にこなしていけば楽なのです。

でも、組織全体からゆとりが無くなると、結局は組織全体が硬直してしまい、
変化に適応できなくなるわけです。
そして、そこからイブはいなくなってしまうのです。

#リスターの法則
>「人間は時間的なプレッシャーをいくらかけられても、速くは考えられない」
>ティム・リスター

言われてみれば当たり前なわけですが、ゆとりを失った職場ではこの当たり前の感覚が失われていたと思います。
常に忘れないように気を付けましょう。
M5StickVで顔検出する

[M5StickV](https://www.switch-science.com/catalog/5700/)を触ってみたので動かすまでのメモ

[公式ドキュメント](https://docs.m5stack.com/#/en/quick_start/unitv/v_function)のV-Function という方式で試していきます。
[m5stackBasic](https://www.switch-science.com/catalog/3647/)のセットアップは終わっている前提です。

[![Image from Gyazo](https://i.gyazo.com/3b51363db2b6d54844ee368617219943.png)](https://gyazo.com/3b51363db2b6d54844ee368617219943)

やったことの簡単イメージ
[![Image from Gyazo](https://i.gyazo.com/0f8ae9348281dc6bfa07f6d35af168b0.png)](https://gyazo.com/0f8ae9348281dc6bfa07f6d35af168b0)

#M5Burner
まずは[M5Burner](https://m5stack.com/pages/download)をインストール

M5StickVとPCを接続して使いたい項目を「ダウンロード」して終わったら「Burn」する。

[![Image from Gyazo](https://i.gyazo.com/68102ed946c797d445cecd9d3a52d4e8.png)](https://gyazo.com/68102ed946c797d445cecd9d3a52d4e8)

[![Image from Gyazo](https://i.gyazo.com/53546451b041b98d23b4f3969bc0037c.png)](https://gyazo.com/53546451b041b98d23b4f3969bc0037c)

顔を認識したいので今回はFaceDetectをBurnします。

[![Image from Gyazo](https://i.gyazo.com/20691ba8862a93d76345eaab5eedb35d.png)](https://gyazo.com/20691ba8862a93d76345eaab5eedb35d)

M5StickVとM5Stickつなぐのに使ったケーブル
[M5Stack用GROVE互換ケーブル](https://www.switch-science.com/catalog/5216/)


#uiFLOW
今回はuiFLOWを使用してプログラムします。
まずはM5stickVをuiFLOWで使えるようにするために、Unitsから追加をしていきます。
![1a26cd00d26ff7d0d6579c2062599149.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/567cd6db-b676-1fdf-706e-f32c1f7e30b2.png)

UnitVを選択Port:はBに設定します。

![06560185a31edb95a3a342464de9e2f5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/b20dc045-8ec4-b45b-de7e-56a3d7511bb3.png)

OKを押すと、UnitsにVFunctionが追加されているので、FaceDetectをクリックします。

>私のPCではV1.6.3を選択するとUnitsの追加ボタンが表示されなかったので、そんなときは、ベータ版でトライしてみてください。




![970be496a61880226cc00b9eb17095e5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/1642f7d9-4936-6164-b10a-e427bedd3414.png)


後は[公式ドキュメント](https://docs.m5stack.com/#/en/quick_start/unitv/v_function)を見ながらプログラムをつなげていきます、ドキュメントは英語なのでuiFLOWも英語にしたほうが組みやすい。



[![Image from Gyazo](https://i.gyazo.com/8f0309ac94332e8ed05a81fb2eebc751.png)](https://gyazo.com/8f0309ac94332e8ed05a81fb2eebc751)

書き終えたら今度はm5stackBasicとPCを接続して書き込めば成功です。

緑色で表示されている部分に、[x座標, y座標,枠の幅,枠の長さ]が表示されます。
TypeScript: 組み込み型関数一覧

使いがちな組み込み型メモ
[Utility Types](https://www.typescriptlang.org/docs/handbook/utility-types.html) より


## 型の 抽出 / 除外


### Extract\<T, U>

T から選択された型を抽出した型を構築する

```ts
Extract<string | number, string> // -> string
```


### Exclude\<T, U>

Extract の逆
T から選択された型を除いた型を構築する

```ts
Exclude<string | number, string> // -> number
```


### NonNullable\<T>

T から null, undefined を除いた型を構築する

```ts
NonNullable<string | number | null | undefined> // -> string | number
```


## オブジェクト系


### Record\<K, T>

K を key、T を value としたオブジェクト型を構築する

```ts
Record<string, number> // -> { [key: string]: number; }
Record<string | number, string | number> // -> { [key: string]: string | number; [key: number]: string | number; }

Record<"foo" | "bar", string> // -> { foo: string; bar: string; }
```


### Pick\<T, K>

T から選択されたプロパティのみの型を構築する

```ts
Pick<{foo: string, bar: number}, "foo"> // -> { foo: string; }
```


### Omit\<T, K>

Pick の逆
T から選択されたプロパティを除いた型を構築する

```ts
Omit<{foo: string, bar: number}, "foo"> // -> { bar: string; }
```


## プロパティ系


### Partial\<T>

全てのプロパティをオプションにする

```ts
Partial<{ foo: string; bar: number }> // -> { foo?: string; bar?: number; }
```


### Required\<T>

全てのプロパティを必須にする

```ts
Required<{ foo?: string; bar?: number }> // -> { foo: string; bar: number; }
```


### Readonly\<T>

全てのプロパティを `readonly` にする

```ts
Readonly<{ foo: string; bar: number }> // -> { readonly foo: string; readonly bar: number; }
```


## 関数


### ReturnType\<T>

関数型の戻り値の型を構築する

```ts
ReturnType<() => void> // -> void
ReturnType<() => string> // -> string

const foo = () => "Hello";
ReturnType<typeof foo> // -> string
```


### Parameters\<T> / ConstructorParameters\<T>

関数型 / クラス の引数の型のタプルを構築する

```ts
Parameters<() => void> // -> []
Parameters<(foo: string, bar: number) => void> // -> [string, number]
Parameters<(foo: { bar: number }) => void> // -> [{ bar: number; }]
Parameters<({ bar }: { bar: number }) => void> // -> [{ bar: number; }]

class Foo {
  constructor(foo: string, bar: number) {}
}
ConstructorParameters<typeof Foo> // -> [string, number]
```
::webkit-scrollbar プロパティ一覧

何気に Edge が Chromium になって、出来ないのはあと Firefox だけなんですね

#### `::-webkit-scrollbar`

スクロールバー全体
角のやつ (scrollbar-corner) は含まれないっぽい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/ebc846b6-8c6d-35c0-13da-827e330a7757.png)


#### `::-webkit-scrollbar-button`

端にある上下左右のボタン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/4ab52644-d0ab-89fc-3fe0-0729b67f0e92.png)


#### `::-webkit-scrollbar-thumb`

スクロールバー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/68ded563-233b-f6c2-0583-a57b9fd7bc7e.png)


#### `::-webkit-scrollbar-track`

スクロールバーが表示されてるとこ、トラック
スクロールバー全体 (scrollbar) からボタン (scrollbar-button) を除いた範囲

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/f90d697f-0cfe-1d7a-4711-ebf118117007.png)


#### `::-webkit-scrollbar-track-piece`

現在のスクロール位置までで分割されてるトラック (？)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/f3e0e649-1f3e-b560-0a51-623df831e33a.png)


#### `::-webkit-scrollbar-corner`

縦横のスクロールバーの交差するとこ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/312ace99-a82d-bf53-644a-b40c341e33ab.png)


#### `::-webkit-resizer`

textarea とかで、リサイズできる時に右下に表示されるやつ
範囲は交差するとこの (scrollbar-corner) と同じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525849/0266fd61-8068-9d3c-9f32-ef24c70a2291.png)


### 分かりやすいような分かりにくいようなサンプル
<p class="codepen" data-height="512" data-default-tab="css,result" data-slug-hash="VwavmKM">
  <span>See the Pen <a href="https://codepen.io/canoypa/pen/VwavmKM">scrollbar</a> on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Windows10 PROにDockerをインストールする

# Windows10 PROにDockerをインストールする

## 0. 前提条件
- Windows 10 PRO [Hyper-Vを使用するため]

## 1. Hyper-Vを有効にする 
- [スタート] > [Windows ｼｽﾃﾑ ﾂｰﾙ] > [ｺﾝﾄﾛｰﾙ ﾊﾟﾈﾙ] 
- [プログラムと機能]
- [Windowsの機能の有効化または無効化]
- [Hyper-V]にチェック[ON]する。
- OS再起動

## 2. Dockerをダウンロードする
Docker公式サイトからダウンロードする。
ファイルサイズは2022/05/29時点で481MB程度。
[Docker : Install Docker Desktop on Windows](https://docs.docker.com/docker-for-windows/install/)
[Docker : Stable と Edgeの違い](https://docs.docker.jp/docker-for-windows/faq.html#id18)

## 3. Dockerをインストールする
ダウンロードした<Docker Desktop Installer.exe>をウィザードに従ってインストールする。（念のために管理者として実行する）

※（疑問点）「Enable WSL 2 Windows Features」があると、Hyper-Vはいらないの？
今回はHyper-V+このチェックありで進める。
↑
あとで問題が出てくるので、先にすべて記事を読んでから、このチェックボックスに
対する対応を決めてもらった方がいいかもしれません。

再起動する。再起動後に下記メッセージが表示される。
![WSL2_message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438214/15e3d514-8531-a150-eff0-5468123f3ef4.png)

メッセージの中にあるURLにアクセスする。
[ms : Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://aka.ms/wsl2kernel)

なんか特定の Linux ディストリビューションをインストールしないといけない
みたいなので、この設定を回避する。

DockerのSettingsで「Use the WSL 2 based engine」のチェックを外すことにする。
↓
Installation succeeded
↓
Close and restart　を押下すると、自動でOS再起動。

利用条件を確認する。

Get started with Docker
in a few easy steps!となる。

## 4. 動作確認
Windows PowerShell

```
docker --version
docker-compose --version
```
Docker、Docker-Composeのバージョン確認OK。

## 以上
Linux上でPython3でMySQLへアクセスするためのyumコマンド

## 実行

`mysqlclient`使わなければ不要かも。

```
# とりあえず
yum update -y
```

```
# /usr/include 配下に実行したいpythonのディレクトリが出来ること
# 例：/usr/include/python3.7

yum install -y python3-devel
```

```
# /lib64/mysql/libmysqlclient.so.18 が入る

yum install -y gcc mysql-devel mysql-libs
```
画面でエフェクトの実現

#webシステムを開発するとき、画面上でどんな動作がありますか、どんなエフェクトがありますか。

課題あるいは結果まずを提出して、それに対して、どう対処すれば解決できるかを考えします。このようなプロセスにより、文章を作りましょう。
##以下の動作があると思います。
・プールダウンリストでクリックすると、中の選択肢が表示された（HTML）
・ダイアログのポップアップ（Bootstrap）
・前入力ボックスを入力すると、後入力ボックスが自動入力された（jquery）
・日付ダイアログのポップアップ（jquery.date）
・「検索」ボタンをクリックすると、指定されたエリアで結果を表示する
（jquery(ajax)）
・「更新」ボタンをクリックすると、次の画面に遷移する（HTML）

##上記の動作あるいはエフェクトを次の文章で説明します。
M5Stack UIFlowでHTTP(POST)通信


M5Stack UIFlowで、HTTP(POST)通信に半日悩んで、
[S Kano](https://qiita.com/canonno)さんに教えてもらって解決。
![EiUo68lUwAA2qa3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/8c727032-e943-bb3f-432a-9957308e2afe.png)


ちなみに、
Htttp Request ＞ Data ＞　マップを作成　のところの
「key - value」の出し方ですごく悩んだ（1時間くらい）
[![Image from Gyazo](https://i.gyazo.com/2277f2b64f167145c85e04307a69dd29.png)](https://gyazo.com/2277f2b64f167145c85e04307a69dd29)

マップを作成の<B>「＋」</B>マークを押せば出た。

<br>
[python]リストの要素を並べて表示する方法

####・リストの要素を横に並べて表示する。

#####例１

```python
L = [1, 2, 3, 4, 5]

print(*L)
```

```python
1 2 3 4 5
```
※リストの値はintでもstrでも可能

####例２

```python
L=' '.join(L)
print(L)
```

```python
1 2 3 4 5 #str
```

※リストの値はstrのみ

intの時は

```python
L = map(str, L) #intからstrに変換
L=' '.join(L)
print(L)
```

```python
1 2 3 4 5
```


####・リストの要素を縦に並べて表示する。


```python
[print(i) for i in L]
```

```python
1
2
3
4
5
```

（競技用プログラミングの時に手間取ったため。）
（追加があれば追記します。）
Vagrant Parallelsプロバイダ

## この記事について

* Vagrant ParallelsプロバイダのREADMEを和訳したものです。
* 翻訳元は**2020/09/21**時点で最新のものです。長い時間が経過している場合、情報が古くなっている場合がございますのでご注意ください。

> **翻訳元**
>
> vagrant-parallels : https://github.com/Parallels/vagrant-parallels
>
> ライセンス : [MIT](https://github.com/Parallels/vagrant-parallels/blob/master/LICENSE.txt)

### はじめに

[![Gem Version](https://badge.fury.io/rb/vagrant-parallels.svg)](https://badge.fury.io/rb/vagrant-parallels) [![Build Status](https://travis-ci.org/Parallels/vagrant-parallels.svg?branch=master)](https://travis-ci.org/Parallels/vagrant-parallels) [![Code Climate](https://codeclimate.com/github/Parallels/vagrant-parallels.svg)](https://codeclimate.com/github/Parallels/vagrant-parallels)
Vagrant Parallelsプロバイダは、[Vagrant](http://www.vagrantup.com)のためのプラグインで、macOSホスト上の[Parallelsデスクトップ](http://www.parallels.com/products/desktop/)仮想マシンの管理を可能にします。

### 必要条件

- [Vagrant v1.8](http://www.vagrantup.com) 以上
  （Vagrant v1.9.5には[[GH-297](https://github.com/Parallels/vagrant-parallels/issues/297#issuecomment-304458691)]、v1.9.6には[[GH-301]](https://github.com/Parallels/vagrant-parallels/issues/301)という既知の問題があります。）
- [Parallels Desktop 11 for Mac](http://www.parallels.com/products/desktop/) 以上

*注意 :* **Parallels Desktop for Mac**の**プロ**または**ビジネス**のエディションのみが、Vagrantプロバイダと互換性を持ちます。スタンダードエディションではコマンドラインの全ての機能が使用できず、Vagrantで使用することができません。

## 機能

Parallelsプロバイダは、共有フォルダ、プライベートとパブリックのネットワーク、フォワードポート、Vagrantシェアを含めた全ての基本的なVagrantの機能をサポートします。

Vagrantのチュートリアルを始めたい場合は、まず公式の[Vagrantドキュメント](http://docs.vagrantup.com/v2/)を読むことを強くおすすめします。

## インストール

[Parallels Desktop for Mac](http://www.parallels.com/products/desktop/)と[Vagrant](http://www.vagrantup.com/downloads)が適切にインストールされていることを確認してください。最新版を使用することをおすすめします。

Parallelsプロバイダは、Vagrantのためのプラグインです。インストールするには、以下のコマンドを実行してください。

```
$ vagrant plugin install vagrant-parallels
```

> **和訳者メモ**
> インストールでエラーが発生した場合、Command line tools for Xcodeをインストールすると、解決する場合があります。


## プロバイダのドキュメント

プロバイダについての詳しい情報は、[Vagrant Parallelsドキュメント](http://parallels.github.io/vagrant-parallels/docs/)を参照してください。
以下のページから読み始めることを推奨します。

* [使い方](http://parallels.github.io/vagrant-parallels/docs/usage.html)
* [チュートリアル](http://parallels.github.io/vagrant-parallels/docs/getting-started.html)
* [ボックス](http://parallels.github.io/vagrant-parallels/docs/boxes/index.html)

## 問題が発生した場合

Parallelsプロバイダに問題が発生したり、バグを発見した場合、[Issue Tracker](https://github.com/Parallels/vagrant-parallels/issues)に報告をお願いします。

## ライセンスと著者

* 著者: Youssef Shahin <yshahin@gmail.com>
* 著者: Mikhail Zholobov <legal90@gmail.com>
* Copyright 2013-2018, Parallels International GmbH.

Vagrant Parallelsプロバイダは[MITライセンス](http://opensource.org/licenses/MIT)で公開されているオープンソースソフトウェアです。
M5StackBASICとUiFLOWの接続が上手くいかなかった時に気付きそうでなかなか気づかなかったが気づいてよかった落とし穴

## 本記事について
先日参加したハッカソンで遭遇したトラブルについて書きます。

[【増枠！】M5Stackハッカソン by #ヒーローズリーグ](https://mashupawards.connpass.com/event/188452/)


## M5StackBASICとUiFLOW
今回のハッカソンは[M5Stack](https://m5stack.com/)を使用して制作発表行う二日間のイベントでした。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164405/ae3c7dcd-9183-bb8e-732b-1ef3edd61319.jpeg" width="50%">


M5Stackを動かすためのプログラミングツールであるUiFlowの接続が頻繁にdisconectedになって全く作業が進まない時間がありました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164405/cca54034-b2ca-dcd0-456f-b85355d3dc53.png" width="30%">


##プライバシーセパーレーターとテザリング
ハッカソン自体はオンラインイベントでしたので、作業は自宅で行っておりました。
自宅はいわゆるインターネット付き物件なのですか、[プライバシーセパレーター機能](https://www.buffalo.jp/support/faq/detail/16054.html)によりAlexaやObnizなどのIoTデバイスは自宅のネットワークが利用できません。
ですのでIoTデバイスを使うときは手持ちのスマートフォンのテザリング機能を利用していました。

M５Stackの接続もテザリングを利用していたのですが、開発PCで使用しているUiFLOWとの接続が頻繁に切れてまったく作業が進みませんでした。
原因がわからず、テザリングの端末を変更したり、開発PCをM5Stackと同じテザリング接続に切り替えてネットワーク環境を揃えるなどしてみましたが全く改善しませんでした。

__この問題が改善しない = ゲームオーバでしたのでかなり焦りました。__

## 原因 
電源供給先の開発PCとM5StackをつないでいたUSBケーブルの接続不良でした。

M5Stackに同梱されていたType-Cケーブルが約１５cmと短めなため普段キーボードとマウスをつないでいるUSBハブの余っている差込口に接続していました。
これを長めのケーブルに交換してPCに直接つないだら一瞬で解決しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164405/27d1e2d1-61b7-274d-fd4a-298b4e403ea4.jpeg" width="50%">


__・ケーブルの初期不良__
__・ハブのUSB差込口の接続不良__
__・供給電力の不足__

細く原因を分けると以上にようなものが考えられますが、詳しくは検証していません。
デバイス系のエラーについては物理的な要因も考慮しないといけないことがよくわかりました。

このような問題がおこった一番の原因はM5Stackの開発環境の準備不足ですし、とにかくハッカソンを完走できてほっと一安心しました。
Maxで音の高さを別の音の波で揺らす（FM）

#前の記事
[Maxで音の波の加算合成（AM）](https://qiita.com/waokitsune/items/a5e8d4397d423d7291b6)

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#ごくごく簡単なサンプル
**+~** オブジェクトで周波数を揺らした上でcycle~に突っ込む！
cycle~は-1から1の間の波なので\*~で増幅させるぞい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/fcc3f63e-0e58-a3b7-1c51-7192b42faa84.png)

#応用
エンベロープで揺れ幅に変化をつけた1オクターブ上の音で音の高さを揺らした上で、エンベロープで揺れ幅に変化をつけた5音高い音で音の大きさに変化を付けた挙句、エンベロープで最終的な音の大きさに変化を付ける。と、まあもう色々…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cc27d96c-781c-c2ab-f904-5f08413fad08.png)

これ以降は正弦波以外で揺らしてみたりとか、別のパラメータに変化を付けてみたりとか『好きな音』を探していく領域になるのかなあ。

#次の記事
[Maxでフィルターをかませて周波数をカットしながら音を作る](https://qiita.com/waokitsune/items/1b7da0375daa6e2ee541)
Python による2021年の月カレンダー(システム手帳用リフィル)の自動作成 

####目的：
月間カレンダーの作成です。
####背景:
システム手帳を使用していますが、リフィルのサイズ(82mmW x 140mmL)が特殊なため、入手困難で、価格もそこそこ高く、手作りしてしまおうと考えたのは過去のことですが、そのときにリフィル用紙を特注で作り、白紙が、まだ残っていましたので、来年分は、久しぶりに手作りしようと考えました。年に一度のことなので、手作りでも良いのですが、せっかくのプログラミング環境があるので、毎年、自動でカレンダーが出力できるような仕組みを作成してみようじゃあないか。という理由で、プログラミングしてみました。

####印刷：
ワープロソフトの「差し込み印刷」の機能を用います。従って、差し込み印刷用のカレンダーデータを作れば良い。「差し込み印刷」するテンプレートは、下図のような、見開きで1ヶ月表示となるテンプレートとしました。
![calrendar_template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561584/4b144b35-f0dd-79d6-e8c7-c7c4ea218b99.png)

####データ：
1ヶ月が1レコードになりますので、下図のようなカレンダーデータベースができれば、差し込み印刷に使用できます。この表を、python で作ろうというのが、今回の試みになります。
![calrendar_db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561584/483f5a52-90ee-a5e7-939a-541c0082ff07.png)

コードは、下記の通り

```.ruby:monthly_calendar.py
import pandas as pd
import numpy as np
import calendar as cl
import os

"""
とりあえずの完成版
"""

file='f.csv'
fout=open(file,'w',encoding="utf_8")

# 作成する年
YEAR=2021

"""
while loop でデータを作成する
m--> month
D--> date
out --> ここにデータをためていく
"""

m=1
out=""
while m < 13:
  MR=cl.monthrange(YEAR,m)
  out=("{0},".format(cl.month_name[m]))

  D=0
  while D < 37:
    while D < MR[0]:
      out+=("*,")
      D+=1
    if D < MR[1]+MR[0]:
      out+=("{0},".format(str(D-MR[0]+1)))
      D+=1
    else:
      out+=("*,")
      D+=1
  out=out[:-1]
  out='{0}\n'.format(out)
  print(out)
  fout.write(out)
  m+=1

fout.close()

body_df=pd.read_csv('f.csv',index_col=0,
                    names=['D0','D1','D2','D3','D4','D5','D6','D7','D8','D9','D10',
                           'D11','D12','D13','D14','D15','D16','D17','D18','D19','D20',
                           'D21','D22','D23','D24','D25','D26','D27','D28','D29','D30',
                           'D31','D32','D33','D34','D35' ,'D36'])
print(body_df)

body_df.to_csv('f_out.csv')
os.remove('f.csv')
```

データベースの index 頭の　"Month" や、祝日が手入力とか、改善や機能追加は、いくつかあります。気が向いたら手をつけることにします。
【Windows10】WSL2のインストールとフォント設定

<!-- WSL2を使ってみた !-->

# Windows PCでLinuxを使いたい！
Windows PCでUbuntuを利用するための方法をいろいろ調べた。
選択肢は
1. PCを完全にUbuntuにしてしまう
2. デュアルブートにする
3. 外付けSSDでブートできるようにする
4. WSL2 (Windows Subsystem for Linux)を使う
がある。

筆者は、1.だとWordなど使えなくなると困る、2.はPCに負担が大きいし重くなったり、データが破損したりするらしい、新SSD購入資金がないので3.もなし、という理由で4.を実行することにした。

# WSL2 とは

> Windows 10（[Fall Creators Update、バージョン1709以降](https://www.atmarkit.co.jp/ait/articles/1707/31/news028.html)）で利用可能になった「Windows Subsystem for Linux」（以下WSLと略す）は、Windows 10からLinuxを利用するための仕組み([参考サイト](https://www.atmarkit.co.jp/ait/articles/1903/18/news031.html)より)

# インストール

まず [コントロールパネル] - [プログラム] - [プログラムと機能] - [Windowsの機能の有効化または無効化]を開き、

下図のように`Linux用Windowsサブシステム`にチェックをつける。

![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/47f4d559-fe93-22ce-91fb-02a99d824212.png)

次に、Microsoft StoreからUbuntuアプリをインストールする。

Storeには18.04や20.04という名前のアプリも存在するが、基本的にはシンプルに`Ubuntu`のみのものをインストールするのが良い。

※WSLのディストリビューション名は後から変更できないので、［スタート］メニューの登録名が「Ubuntu-18.04 LTS」、起動コマンドも「Ubuntu-18.04.exe」のままになるのを避けるため。

起動したらユーザ名とパスワードを訊かれるので、設定する。

#  フォントの変更

![font_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/e7eb4a9b-09ff-f3f5-9f21-4cdc16057b9d.png)

そのままだとMS ゴシックで美しくないので、Ubuntu Mono (Ubuntuでデフォルトに設定されているフォント)に変更する。

[Google Fonts](https://fonts.google.com/specimen/Ubuntu+Mono)からUbuntu Monoをダウンロード

Windowsスタートボタンから`font`を検索して起動

   ![font_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/b5294dcd-09ba-9914-8a42-7ebcc5f8a4c8.png)

ダウンロードしたttfファイルをドラッグ&ドロップ

   ![font_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/ea404313-03e6-8b4b-36b6-e3135c8bc15d.png)

[使用可能なフォント] に``Ubuntu`と入力して、Ubuntu Monoがインストールできているかどうか確認する。

   ![font_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/15ca8851-f170-2e10-8e5c-6f4f81bd423f.png)

Ubuntuの上のバーを右クリックして [プロパティ] を選択。

   ![font_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/208f4984-a2e8-5dd1-e4d8-b958270bcfb3.png)

[フォント] からUbuntu Monoを選択し、[OK]をクリック。

   ![font_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135111/4dec0761-b104-05a1-f338-027cb93043b7.png)

完了！

<!-- # Paraview !-->

<!-- 可視化につかうparaviewをWSL2から起動する場合は以下のページを参考にするといいらしい。（まだインストールしてないので、随時更新）!-->

<!-- https://www.openfoam.com/download/install-windows-10.php !-->

## 参考

https://www.atmarkit.co.jp/ait/articles/1903/18/news031.html