OmniAICreator/Qiita-1.07M huggingface dataset:
【SwiftUI】 Spacer()で位置調整を行ったButtonのタップ可能域がずれた

初めて遭遇した問題があったので、記録します。

## 環境
XCode: Version 13.4.1 
iOS: 15.5
## 問題のコード
ざっくりイメージです。
```swift
ZStack {
    Image("back_1")
        .resizable()
        .aspectRatio(contentMode: .fill)
        .frame(maxWidth: screenWidth, maxHeight: screenHeight)
        .ignoresSafeArea()
    HStack{
        VStack {
            Image("Buttonだよ")
                .onTapGesture {
                    self.isOpenSideMenu.toggle()
                }
            Spacer()
        }
        Spacer()
    }
}


```


発生していたのは、以下の現象。

- Spacerの指定が入った途端タップ可能領域がずれる。（Spacer未指定の状態、画面中央に描画された状態だと、画像全体がタップ可能域になる）
- 本来指定したい画像ではなく、その直下数ミリ？くらいの部分がヒットエリアになっていた。


結論から言うと、背景に入っている画像がスクリーンサイズを超過していたことが問題だったらしい感じがしている。


## 対処法
対処法は2つ。
Buttonをstructで包むか、
背景画像として挿入しているImageをbackground()の中にいれるか。
いずれかの動作を行えば正常に動作するようになるかと思う。
少なくとも私の場合はこれで解決した。

```swift
HStack{
    VStack {
        Button("Buttonだよ") {
                self.isOpenSideMenu.toggle()
            }
        Spacer()
    }
    Spacer()
}
.background(
            Image("back_1")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(maxWidth: screenWidth, maxHeight: screenHeight)
                .ignoresSafeArea()
)
```
【SwiftUI】アクセシビリティ設定によってフォントサイズが変わってしまう

# はじめに
iPhoneの設定にアクセシビリティはとても優れており、様々な設定が存在します。
今回はそんなアクセシビリティに関する落とし穴について紹介できたらと思います。

# 問題点
このようなUIのアプリがあったとします。
![スクリーンショット 2022-09-29 18.19.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/410396f6-40a7-45ca-7cbe-39cc12484d66.png)

現在は信号の表示であることが容易にわかります。
しかし、アクセシビリティで文字の大きさを大きくしていた場合はどうなるでしょうか。

このような表示になってしまいます。
これでは信号であるという事がユーザーに伝わりません。
![スクリーンショット 2022-09-29 18.20.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/80475eba-5ee8-0ae4-3481-61a8b68a281b.png)

もし省略されている文字がアプリの使い方であった場合、
ユーザーはアプリの使い方がわからないということが起きてしまうわけです。

# 対策方法
## 固定サイズ
`dynamicTypeSize`で1つだけ指定すると固定のサイズになります。
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(alignment: .center) {
            Text("青信号")
                .frame(width: 120, height: 70)
                .background(Color.cyan)
+               .dynamicTypeSize(.medium)
            Text("黄信号")
                .frame(width: 120, height: 70)
                .background(Color.yellow)
+               .dynamicTypeSize(.medium)
            Text("赤信号")
                .frame(width: 120, height: 70)
                .background(Color.red)
+               .dynamicTypeSize(.medium)
        }
    }
}
```
この方法は確実ではありますが、ユーザーフレンドリではありません。
`medium`では文字が小さいと感じる方もいるからです。

|xSmall|AX 5|
|-|-|
|![スクリーンショット 2022-09-29 18.39.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2bfb961c-3aa2-089e-de3a-a87a451ef534.png)|![スクリーンショット 2022-09-29 18.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b1ff1146-82e2-fe5e-e366-c2aadd0aab8e.png)|




## 範囲指定
文字が省略されない程度までは大きくできるように設定します。
今回は`xSmall`から`xxLarge`までの範囲を指定しています。
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(alignment: .center) {
            Text("青信号")
                .frame(width: 120, height: 70)
                .background(Color.cyan)
+               .dynamicTypeSize(DynamicTypeSize.xSmall...DynamicTypeSize.xxLarge)
            Text("黄信号")
                .frame(width: 120, height: 70)
                .background(Color.yellow)
+               .dynamicTypeSize(DynamicTypeSize.xSmall...DynamicTypeSize.xxLarge)
            Text("赤信号")
                .frame(width: 120, height: 70)
                .background(Color.red)
+               .dynamicTypeSize(DynamicTypeSize.xSmall...DynamicTypeSize.xxLarge)
        }
    }
}
```

最大サイズにしても文字が省略されていません！
|xSmall|AX 5|
|-|-|
|![スクリーンショット 2022-09-29 18.36.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/c59b57fb-c52e-a2d3-dede-589b16c87538.png)|![スクリーンショット 2022-09-29 18.36.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f64b842f-3021-2a65-69ec-6f0274dab467.png)|

# おわり
意外と見落としがちなところなので気をつけていきたいです。
なーるほど！コードレビュー

## はじめに

みなさんこんにちは。プログラミング歴5ヶ月の新米エンジニアです。
今回の記事では、これまでに受けたコードレビューの中で「なるほど！」と思ったものをいくつか紹介していきたいと思います。

## 条件式の返り値をそのまま変数に代入すればいいのでは？

これは、私が書いたこんなコードに対する指摘でした。

```ruby
if @hoge.blank?
  piyo = true
else
  piyo = false
end
```

条件が真のとき変数にtrueを、偽のときfalseを代入するというものです。
条件式の返り値をそのまま変数に代入するような処理ですね。
レビューをもとにこれを書き換えるとこんな感じ。

```ruby
piyo = @hoge.blank?
```

なんともスマートになりました。
返り値というものをそこまで意識していなかった私にとって、これは目から鱗のレビューだったといえるでしょう。

## 入っている値がぱっと見で分かるような変数名に

私は以前、こんな具合に変数を定義していました。

```ruby
user = User.all
list = ['apple', 'orange', 'banana']
human = true
```

レビューをもとにこの変数たちを修正すると、

```ruby
users = User.all
fruit_list = ['apple', 'orange', 'banana']
is_human = true
```

こんな感じになります。

一つめは、値が複数なら変数も複数形に。
二つめは、「何の」リストなのかを明確に。
三つめは、値がブーリアン型であることが分かるように。

些細な変化ですが、これによってコードの可読性は格段に上がります。

実際のコードはこんなに単純なものばかりではなく、どう言い表したらいいか分からない複雑なものがたくさんありますよね。
このような変数に対して中身を簡潔に言い表す名前を考えるのは至難の業ですが、負けじと食らいついていきたいと思います。

## 見れば分かることをコメントに書くな

これは私のこんなコメントに寄せられたものでした。

```ruby
# 現在時刻をtimeに代入
time = Time.current
```

見ての通り、コードを日本語に直訳したようなコメントを残していたわけです。
これに対して、「それは見れば分かる。何をしているかではなく、何のためにしているかを説明しよう」と指摘を受けました。

当時の私は、コメントはあればあるほど可読性が上がると勘違いしていました。
今となっては読めば分かることを書いても意味がないことは当たり前なのですが、最初は主にコメントを読んでコードを理解していたので、自分が分かりやすいからと不要なコメントを量産してしまっていました。
コメントは本当に必要な場面で適切なものだけを残していきたいですね。

## SQLを流すのはできるだけループの外で

SQLが流れるような処理をループの中でするな、というものですね。
ダメなコードの例はこんな感じ。

```ruby
id_list = [1, 2, 3]

id_list.each do |id|
	name= User.find(id).name
	# nameに対する処理
end
```

これだと、id_listの長さ分だけSQLが流れることになります。
この例ではたかが3回なのでパフォーマンスへの影響は小さいですが、これが何万回にもなると話は変わってきます。
大量のSQLが流れることになり、処理が重たくなってしまうわけです。

改善するとこんな具合になります。

```ruby
user_list= User.where(id: id_list)

user_list.each do |user|
  name = user.name
  # nameに対する処理
end
```

これなら流れるSQLは1本ですみますね。
初めの頃はとりあえず要件を満たすことしか考えていなかったので、パフォーマンス面を加味することも大事だということを学ぶことができました。

## 終わりに

今までに受けたレビューはまだまだたくさんありますが、その中でも特に印象的だったものを抜粋して紹介しました。
ひとつひとつのレビューを真摯に受け止め、同じレビューを何度も受けないよう精進していきたいと思います。
最後まで読んでいただきありがとうございました。
【CSS】display: flex; を使って背景を画面いっぱいに広げる方法

# はじめに
中の要素の大きさに関わらずにmainの背景を画面いっぱいに広げたいあなたに、`display: flex;` を使って実装する方法を紹介します。
### 【理想】
![スクリーンショット 2022-09-29 18.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/ab5b1f2c-00eb-05f7-45f9-0df5923ec305.png)

### 【現実】
![スクリーンショット 2022-09-29 18.37.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/9a55a978-8b6f-7eb0-2b40-54b63428ccd7.png)


# 実装方法
#### HTML構造
```qiita.html
<body>
    <header>
      <div class="header">ヘッダー</div>
    </header>
    <main>
      <div class="main__wrapper">
        <table class="main__table">
          <thead>
            <tr>
              <th>名前</th>
              <th>年齢</th>
              <th>血液型</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>キー太郎</td>
              <td>25</td>
              <td>A</td>
            </tr>
            <tr>
              <td>キーたか子</td>
              <td>20</td>
              <td>B</td>
            </tr>
          </tbody>
        </table>
      </div>
    </main>
    <footer>
      <div class="footer">フッター</div>
    </footer>
  </body>
```

#### CSSの指定
① 親クラス(`body`) に以下のスタイルを指定する
```qiita.css
body {
    display: flex;
    flex-flow: column;
    min-height: 100vh;
}
```

② 画面いっぱいに広げたい要素(`main`)に以下のスタイルを指定する
```qiita.css
main {
    flex: 1;
}
```

# 終わりに
必要な記述はたったこれだけ。なんて簡単なのでしょう...！
Ruby問題 配列の並び替え

(1) 配列の並び替え
---
```
【Q】　数字の配列を、偶数はそのままの位置で、奇数のみを昇順に並び替えなさい。

例）
[7, 1]  =>  [1, 7]
[5, 8, 6, 3, 4]  =>  [3, 8, 6, 5, 4]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]  =>  [1, 8, 3, 6, 5, 4, 7, 2, 9, 0]
```

私の回答

```ruby
def sort_array(array)
  oddsArr = array.select {|n| n.odd? }.sort
  array.map {|n| n.even? ? n : oddsArr.shift }
end
```

1) 配列の中から奇数のみを取り出したいので、selectメソッドを使いました。
sortメソッドで昇降順に並び替えて、新しい配列に入れます。

2) 元の配列を三項演算子を使って、並び替えます。
`n.even?` 偶数であるかどうかを判断
YES => そのまま配列に入れる
NO => 奇数なので、`oddsArr`からshiftメソッドで1個ずつ取り出して返していきます。

* [selectメソッド](https://docs.ruby-lang.org/ja/latest/method/Array/i/filter.html)
* [mapメソッド](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/map.html)
* [sortメソッド](https://docs.ruby-lang.org/ja/latest/method/Array/i/sort.html)
* [shiftメソッド](https://docs.ruby-lang.org/ja/latest/method/Array/i/shift.html)
WSL2のセットアップをやってみた。

会社でWindowsのパソコンを使用することになったので、Dockerを使えるようにするためにWSL2のセットアップを行ったため、備忘録として残します。
もしWindowsでまだ環境設定等を行っていない方がいれば、参考になったら幸いです。

# 1. WSL2用Linuxカーネルをインストールする。
こちらのリンクから[WSL2用Linuxカーネル](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)をインストールする。

# 2. PowershellでデフォルトをWSL2に設定する。
```powershell
wsl --set default-version 2
```
# 3. Linuxディストリビューションをインストールする(Ubuntu)
Microsoft Storeより、Ubuntuをインストールする。

# 4. Ubuntuのアカウントを作成する。
Powershellで、新規のusername, passwordを設定し、Ubuntuのアカウントを作成する。

# 5. PowershellでWSL2になっているかどうか確認する。
```powershell
wsl --version
```
wslが2と表示されていればOK!!

これでDockerを使えるようになりました！
PHPで504 Gateway Time-outが出た時に確認すること

### PHP
`php.ini: max_execution_time`

基本は、php.iniのmax_execution_timeを変更すると、タイムアウト時間を設定することができますが、
なぜか変更されないこともたまにある。

そういうときは、
`/etc/php-fpm.d/www.conf: request_terminate_timeout`

nginxの場合
`nginx.conf: fastcgi_read_timeout`

この辺を変更すると、適用されたりします。

### AWS ELB
ここは見落としがちなのですが、
AWSのELBを使用している場合、属性の編集からアイドルタイムアウトの編集で適用されます。

ということで、変わらない場合はこの辺を確認しましょう。
LINE×GAS｜飲食店向け注文システムを作成


:::note warn
本記事に記載のコードの中身については、全てを1から私が記載したわけではありません。
こちらの記事は、あくまでも参照元に倣って自分でも作ってみて、つまづいたポイント・自分で追加調査したところ・追加改造を記録した記事です。
:::

# ゴール
**Googleフォームで注文→スプレッドシートに記録→LINEに通知→LINEで返信→お客さんにメールで通知**という仕組みを作る。

▶︎[引用](https://docs.google.com/spreadsheets/d/1VIkSu-Kec2Na4ZVqae9UooROy4gQec0O9ShMi67s6G8/edit?usp=sharing)
![20211025_明日から使える飲食店向け注文システムを作る_-_Google_スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/b807cd24-f53e-3d39-5c3f-7c813dca4490.png)


# まずは手順書・お手本通りに作成
### つまづき
そもそも、お手本のスプレッドシートをコピーして使うのね！考えてみれば当たり前か！GASがないと動かないもんね！
おかしいな〜っておもったわ！それ以外は手順通りにできて、エラーもなかった。

# 追加改造

## 改造のゴール
今回はお手本通りにやって、エラーとかもなく自分で書き換えた部分もないので、さっそく追加改造にとりかかる。
以下の画像の通り、**Googleフォーム・Gmailを用いていた部分をLINEに変更**し、お客さん・お店の双方ともLINEさえあれば使用できる構成にしたい。

**▼構成イメージ**
![Untitled__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/adacdc57-a240-fe30-de6c-4e1e8e8fe2cb.png)

### 改造を試した結論
GASで細かいコードを書き直すよりも、LINE公式アカウントの機能を使えばもっと簡単にわかりやすく作れることが判明。別項でその内容をメモ。

## LINEだけで注文が完結するようにする
細かい手順は公式サイトとかで調べれば出てくるので割愛。
（そもそも作りやすい画面なので、大体の人はパッと見でわかると思います）

### 完成形
**▼作成した公式アカウント**
https://lin.ee/jQkGft1
![M_gainfriends_qr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/14a79bca-513f-411e-5582-b718135178d9.png)

**▼実際の画面**
![貼り付けた画像_2024_11_09_18_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/df10cc52-5d79-057c-6b6f-ba4c1154d257.png)


![貼り付けた画像_2024_11_09_18_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/d907bb07-a280-ac32-7497-d4d28b01fb72.png)


### 補足
参考サイトには認証済みアカウントを取得する必要があり、10日間ほど取得に要する、という旨の記載があるが、現在は取得する必要はなかった。（おそらく仕様が変わってる）

# 参照・参考
**▼お手本**

https://www.youtube.com/watch?v=IyH8b6y3SJ8

https://docs.google.com/spreadsheets/d/1VIkSu-Kec2Na4ZVqae9UooROy4gQec0O9ShMi67s6G8/edit?usp=sharing

**▼追加改造のために参照**

https://food-page.com/?p=5835


# 感想
LINE公式アカウントの機能の豊富さ・使いやすさに驚き。受発注とかは正直コーディングなしでも標準機能だけでできそう。LINE×GASで学ぶ際には、**LINE公式アカウントの機能＋〇〇で作る**イメージが大切かも。

例えば、LINEで受発注システムは作れるけど、記録ができないから記録のためにスプシとGASで連携させるとか。
とりあえず、GASだけでどうにかしようとするのは時間の無駄＆シンプルじゃないことに気づけた。
DjangoでXSS対策を確認してみた


## 環境
以下のサイトを参考に入力した値を取得するようにしています
https://docs.djangoproject.com/ja/4.1/intro/tutorial01/
https://bsf40.blogspot.com/2020/02/djangoform.html

![2022-09-05-13-28-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/7322f1cb-54ad-2b4f-4701-9d849c71e7a7.png)
![2022-09-05-13-29-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/9cdbeace-6ae5-190b-5a3d-cc21b3641603.png)


## Djangoは自動でサニタイズをしている

結果としてはDjangoはデフォルトで文字列のサニタイズを行っているようでした
そのためHTMLタグを含んだ文字を入力しても問題なく表示されていました

![2022-09-05-13-53-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/7dc94783-5c2a-1e90-8da4-5ddeeafb967c.png)


### サニタイズとは？
HTMLなどで使用される特殊文字（「<」や「&」など）を置き換える処理になります
例えば「<」をサニタイズすると「\&lt;」となります


## サニタイズ無効化
Djangoでサニタイズを無効化する方法があるようなので、そちらも試してみました

方法は2つ
safeフィルターとautoescapeフィルターの2つが主な方法のようです

- safeフィルター
safeフィルターは変数の後ろに ``` |safe ``` とつけることでサニタイズを無効化できます
変数の後ろにつけることになるので、複数一気に無効化するには向いていません

今回だとmessageのサニタイズを無効化したいので、そこにsafeをつけています
```

    <form action="" method="GET">
      <label>{{ form.chat_bot.label }} {{ form.chat_bot }}</label><br/>
      <input type="submit" value="送信">
      <br/>
      <br/>
      {{ message|safe }}
    </form>

```

サニタイズを無効化したことでHTMLタグが有効になりました

![2022-09-05-14-24-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/d8b0561c-675e-7003-1e6a-fbff7257fe92.png)

- autoescapeフィルター

autoescapeフィルターは　``` {% autoescape off %} ```　と　``` {% endautoescape %} ```　で挟んだ変数のサニタイズが無効化されます
複数を無効化したい場合に向いています

```

    <form action="" method="GET">
      <label>{{ form.chat_bot.label }} {{ form.chat_bot }}</label><br/>
      <input type="submit" value="送信">
      <br/>
      <br/>
      {% autoescape off %}
      {{ message }}
      {{ message }}
      {% endautoescape %}
    </form>


```

複数の変数のサニタイズを無効化できていることが確認できました

![2022-09-05-14-26-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/875ebd3c-b76f-6704-828b-e127d28661aa.png)

## pythonによるサニタイズ

今度はDjangoのデフォルトのサニタイズではなく、pythonのサニタイズ方法を調べてみました

bleachというライブラリでサニタイズを行えるようなので、2度手間ですがautoescapeでサニタイズを無効化し、受け取った値をbleachでサニタイズしてみました

bleachの使い方は簡単で、 bleach.cleanでサニタイズできるようです

``` 

import bleach

text = "文字列"

bleach.clean(text)

```

実際に受け取った値をbleachを使用することでサニタイズできました

![2022-09-05-14-40-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/1bbc521f-e2db-8e5f-5059-18cc8970d3af.png)
SwiftUIにて画面の向きを固定、また画面回転の許可をコードにて制御する方法

## 画面を固定するのか、回転させるのか？

 - 回転する画面に対応するのか？
 - それとも画面は固定にするのか？

Xcodeの設定で画面を固定したりする記事はよく見かけるのですが、画面ごとに設定を変更したい時はコードで設定する必要がありましたので、コードで制御しました。

>ちなみに、どういう仕様だったかというと、普段の画面は縦型固定にして、Web表示する時だけ回転可能にしました。

:::note
UIKitだと記事が多いのですが、SwiftUIだと少ない気がしたので自分の備忘録的に書きました。
:::

## 開発環境
- Xcode：Version14.0
- Swift：Swift5
- 対応OS：iOS15.6

## まずAppDelegateにapplicationデリゲートを用意する 


この時回転を許可するかどうかも最初に決めておきます。


```swift:sampleApp.swift

class AppDelegate: NSObject, UIApplicationDelegate {
    // 回転可能か設定する。外部から変更できるよう静的としている
    /* 
        ・回転許可：UIInterfaceOrientationMask.all
        ・縦固定　：UIInterfaceOrientationMask.partrait
        ・横固定　：UIInterfaceOrientationMask.landscape
        ・その他　：https://developer.apple.com/documentation/uikit/uiinterfaceorientationmask/
    */
    static var orientationLock = UIInterfaceOrientationMask.all
    // 設定の変更通知がされた時に呼ばれるデリゲート
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return AppDelegate.orientationLock
    }
}

```

:::note

AppDelegateはUIApplicationDelegate等を継承することで、アプリの状態などを管理することができます。
[UIDlegate公式ドキュメント](https://developer.apple.com/documentation/uikit/uiapplicationdelegate)
[参考記事：AppDelegateについて調べてみる](https://qiita.com/nakagawa1017/items/50f77c42108d179337cb)
:::

## 画面設定更新と表示更新方法
`orientationLock`に`UIInterfaceOrientationMask`のデータを渡すことでアプリ画面の設定します。
上記処理を、画面設定更新したいViewの`onAppear()`などで設定すれば反映されます。



```swift:onAppear
    .onAppear()
        // 縦画面固定
        AppDelegate.orientationLock = UIInterfaceOrientationMask.partrait
    }
```


:::note warn
orientationLockにUIInterfaceOrientationMaskのデータを渡すだけでは現状の画面が維持されてしまいます。
例えば、横画面の状態で画面遷移後の次の画面は縦画面にしたい時、上記だけでは遷移後**横画面**で開いてしまいます。
従って、**更新処理**が必要になります。
:::

```swift

    .onDisappear()
        // 縦画面固定
        AppDelegate.orientationLock = UIInterfaceOrientationMask.partrait
        // 以下更新処理
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
        UINavigationController.attemptRotationToDeviceOrientation()
    }

```

更新処理を実施することで、遷移後に無事、縦画面で表示することができます。
私は回転許可している画面が閉じられる時に、設定したため`onDisappear`に処理を書きました。

## 終わりに
モバイルアプリになると、画面の回転に対応するのか、それとも対応しないのかって結構大事なことなのかな？と思います。
私もアプリ開発に触れるまでは、そこまで難しいと思っていませんでした:sweat:

回転することに対応したアプリを開発している人には心から賞賛したい気持ちです！！

お読みいただきありがとうございました！
データ分析実務スキル検定（CBAS）を受けてきました

これから何かとQiitaを活用していきたいので、記事の執筆練習も兼ねてCBASを受験した時の流れと結果を共有しようと思います。

# 受験動機
　実務を経験して実際自分がどこまで分かってるのかを知りたかったというのもありますが、本音としては今勤めてる会社の評価に関わってくるからですね...(資格取らな過ぎた)


# 使用教材
　　「データ分析実務スキル検定　公式テキスト」
　　　[Amazonリンク](https://www.amazon.co.jp/gp/product/B09HGYN6TR/ref=ppx_yo_dt_b_d_asin_title_o01?ie=UTF8&psc=1 "教材リンク")

　基本この公式テキストを読み返したり模試試験を繰り返し解いたりしました。今回の学習期間は約10日間（短い）でしたが、もっと時間に余裕があるときは参考書を使って深堀したりUdemyで講義を購入できるので受講してみるのも良いですね。

# 学習の流れ
　●　**1日目：学習する順序決め・内容の把握**
　公式テキストにはKPIツリー作成に始まりデータ分析プロジェクトに関する説明、データの集め方・見方、変数データの可視化法や統計学の基本に加え、Excel・SQL・Pythonを用いた分析方法などデータ分析に関しての解説が例文付きで分かりやすく記述されています。
　一度さくっと中身を読んで、先にほとんど知識のないPythonやRの項目から学習を進めることにしました。


　●　**2～4日目：Python・Rの基本知識の習得**

　Pythonは学生時代少し触れたことがありましたがRは名前しか知らないレベルなので、少し多めに時間を取ってRを優先して学習しました。環境構築から各関数の使い方、データフレームの作成などまでが画像や表を使って分かりやすく記述されていました。事前知識も何もない状態でのスタートだったのでやや難解でしたが、基本的な部分は抑えることが出来たのではないかと思います。


　●　**5～8日目：予測モデルの使い方・データ可視化の基本・Excel分析法**

　この期間は研修や実務内で何回か触れたことがあってもあやふやな部分も多く残っている分野の学習を進めました。正直上3つの項目よりも統計とか機械学習の勉強してる時間のほうが長かった気がします...(統計苦手すぎる)


　●　**9～10日目：模擬試験を繰り返し解く**

　ラスト2日間はひたすら模擬試験を解いていました。問題は公式テキストに載っている模擬試験問題とCBASの公式サイトからダウンロードできるサンプダメージをル問題になります。サンプル問題に関しては解答が存在しないので、あくまで問題傾向を把握するためのものになっています。


# 受験結果は...
さて、実際に受験してきたわけですが結論から言うと「**不合格**」でした...
点数の内訳としては、
　
　97点満点中、54点（合格評価点：64点）

　セクション分析　：正答率
　　1.業務目的に応じた適切なKPIツリーの作成：33%
　　2.データの取り扱いに関する利用規約、法令等の理解：100%
　　3.データ分析に必要な前処理の理解：100%
　　4.SQLの基礎の理解：100%
　　5.データ可視化手法の基礎の理解：40%
　　6.基礎集計を通じたデータの全体像や質の確認：73%
　　7.業務目的に応じた適切なコーディング：85%
　　8.基礎的な統計手法の理解：25%
　　9.主要な機械学習の概要と使い分けの理解：50%
　　10.予測モデルの評価と改善手法の理解：25%
　　11.施策の評価と効果検証の理解：25%

うーん、酷い！
見事なまでに経験があるところとそうじゃないところとで差が出ちゃってます。
予測モデルと施策評価、統計分野の低さがかなり目立ってますね...
1のKPIツリー作成が思っていた以上に正答率が低く地味にダメージを食らってます。

ただ、コーディングやデータ取り扱い・前処理辺りには自信を持ってよさそうです。
全く知識のなかったRについては、学生時代にC,C++を経験していたことと書き方が似ていたこともあって比較的理解が早かったのが幸いしました。


# 感想
　今回は残念な結果に終わってしまいました...
単純に学習時間が短かったことも影響していると思いますが、進め方も見直したほうが良いかなとも感じます。今回の試験でどこが弱いのかが明確に分かったので、十全に準備をして3か月後リベンジしたいと思います...!
Laravel9 コマンドノート

Laravelの学習で使用したコマンドのメモです。後々、チートシート的なものになるといいなぁ。

# 開発環境
```
C:\workspace\laravel\sample>ver

Microsoft Windows [Version 10.0.19044.2075]

C:\workspace\laravel\sample>php --version
PHP 8.1.6 (cli) (built: May 11 2022 08:55:59) (ZTS Visual C++ 2019 x64)
Copyright (c) The PHP Group
Zend Engine v4.1.6, Copyright (c) Zend Technologies

C:\workspace\laravel\sample>php artisan --version
Laravel Framework 9.32.0

C:\workspace\laravel\sample>
```

# 使用したコマンド

### サーバを起動（Laravelの機能）
```
php artisan serve
```
簡易的な(？)サーバが起動します。

### コントローラークラスの雛形を作成
```
php artisan make:controller XxxController
```
`app/Http/Controllers/XxxController.php` が作成される。

### マイグレーションファイルを作成（新規のテーブルを作成する場合）
```
php artisan make:migration create_Xxx_table --create=Xxx
```
`database/migrations/yyyy_mm_dd_hhmmss_create_Xxx_table.php` が生成される。

### マイグレーションの実行
```
php artisan migrate
```
`database/migrations`ディレクトリ内のマイグレーションファイルに従って、マイグレーションが実行される。

### モデルクラスの雛形を作成
```
php artisan make:model Xxx
```
`app/Model/Xxx.php` が生成される。

### シーダーのひな型を作成
```
php artisan make:seeder XxxTableSeeder
```
`database/seeders/XxxTableSeeder.php` が生成される。

### コマンドラインからシーダーを実行
```
php artisan db:seed --class=XxxTableSeeder
```
`database/seeders/XxxTableSeeder.php`に従って、DBにテストデータが追加される。

### FormRequestクラスの作成（バリデーションを記載するクラス）
```
php artisan make:request XxxRequest
```
`app/Http/Requests/XxxRequest.php` が作成される。

### テストコードの雛形を作成
```
$ php artisan make:test XxxTest
```
`tests/Feature/XxxTest.php` が作成される。

# その他のコマンド

### Laravel新規プロジェクトを作成
```
composer create-project laravel/laravel sample --prefer-dist
```

### コマンドラインでphpunitを実行
```
./vendor/bin/phpunit ./tests/Feature/XxxTest.php --testdox
```
`./tests/Feature/XxxTest.php` のテスト内容が実行される。
テストを自動化する

# 動機
テストのことを知らないため

# プログラマの三大美徳
怠惰、短気、傲慢がある。

### 怠惰
全体の労力を減らすために手間を惜しまない。

### 短気
コンピュータの動作が怠惰な時に怒りを感じる

### 傲慢
自分の書いたプログラムは誰に見せても恥ずかしくない胸を張って言える自尊心

## 気づき
三大美徳のためにテストを使うのか。

# Minitestの基本を選んだ理由
Railsのデフォルトのテすティングフレームワークなので、Railsを開発する時にも知識を活かしやすい。
※排発の現場ではMinitest以外のフレームワークが使われることもあるため

# テストコードの雛形
```rb
require 'minitest/autorun'

class SampleTest < Minitest::Test
  def test_sample
    assert_equal 'RUBY', 'ruby'.upcase
  end
end
```
### クラス名の注意点
Testで終わる、またはTestで始まる名前をつけることが多い。

### テストのファイル名の注意点
クラス名と_test,test_を繋ぎ合わせます。

### メソッド名の注意点
メソッド名をtest_で始めることは必須。
テストの内容がわかるように命名する。

### requireとは
組み込みライブラリでない標準ライブラリやGemを利用する場合は、明治的にそのライブラリを読み込む必要があります。ライブラリを読み込む場合は次のような構文を使います。
```
require ライブラリ名
```

# Minitestの検証メソッド
```rb
# aがbと等しければパスする
assert_equal b,a

# aが真であればパスする
assert a

# aが偽であればパスする
refute a
```
まだメソッドはある。

# テストコードの実行と結果の確認
```rb
$ ruby sample_test.rb
Run options: --seed 14255

# Running:

F

Finished in 0.001383s, 723.1400 runs/s, 723.1400 assertions/s.

  1) Failure:
SampleTest#test_sample [sample_test.rb:5]:
Expected: "RUBY"
  Actual: "Ruby"

1 runs, 1 assertions, 1 failures, 0 errors, 0 skips
```
出典
https://qiita.com/jnchito/items/1e928f8088b2cc6bd3fa

### ```0.001383s```
テスト実行にかかった秒数

### ```723.1400 runs/s```
１秒間に実行できるであろうテストメソッドの件数

### ```723.1400 assertions/s```
１秒間に実行できるであろう検証メソッドの件数

### ```1 runs```
実行したテストメソッドの件数

### ```1 assertions```
実行した検証メソッドの件数

### ```1 failures```
検証に失敗したテストメソッドの件数

### ```0 errors```
検証中にエラーが発生したテストメソッドの件数

### ```0 skips```
skipメソッドにより実行をスキップされたテストメソッドの件数

# プログラム本体とテストコードを分離する
プログラム本体とテストコードは分離して別々のファイルとして管理すべき。
そのためにテストファイルから対象となるメソッドの定義を読み込めるようにしましょう。
```
require 対象のファイルのパス
```

# 気づき
テストを知らなかった。
これからテストを勉強がてら簡単なものからテストしようと思う。

# 出典
https://gihyo.jp/book/2021/978-4-297-12437-3
Curlまとめ


# はじめに
* curlコマンド とは？
* ipconfig.me とは？
* curlでグローバルIPアドレスを確認する方法

## curlコマンド とは？
[cURL 【client for URL】](https://e-words.jp/w/CURL.html)
UNIX系OSでよく利用されるコマンドおよびプログラムの一つで、様々なプロトコル（通信手順）を用いてURLで示されるネットワーク上の場所との間でデータの送受信を行うもの。

## ipconfig.me とは？
ifconfig.meというネットワークの接続情報を表示してくれるウェブサービスがあります。そこに curl をするとグローバルIPを返してくれる。
https://ifconfig.co/ や https://ipinfo.io/ipなどの類似サービスもあります。 (@lo48576 さんより共有）

## curlでグローバルIPアドレスを確認する方法
~~~:コマンド
$ curl -s ifconfig.me
xxx.xxx.xxx.xxx  #IPアドレスが確認できる
~~~

## まとめ
curlを利用して、自信のPCのグローバルIPアドレスを確認できる👀
HTTPレスポンスの本文も理解すると、エラー修正がはかどりそう💡

### 参考サイト
* [【入門】curl コマンドとは？よく使うオプションの使い方を説明](https://hogetech.info/oss/curl)
* [curl コマンド 使い方メモ](https://qiita.com/hypermkt/items/0c9670f73c9cf63f55d3)
* [curlでグローバルIPアドレスを確認する方法](https://qiita.com/yasuhiroki/items/a569d3371a66e365316f)
ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MACの対処メモ（Windows10、node v16.17.0）

Vuepressのプロジェクトをリポジトリから取得し、``npm install``したときに標題のエラーが出たので、その対処をメモしておきます。
以下は実際のエラーです。
```
$ npm install
npm ERR! code ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC
npm ERR! 5228:error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:677:
:
npm ERR! A complete log of this run can be found in:
npm ERR!     【..local npm log dir..】\2022-09-29T02_57_10_549Z-debug-0.log
```

エラーが出た環境は以下になります。
|名称|バージョン|備考|
|:-|:-|:-|
|OS|Windows 10 64bit Home||
|Node.js|v16.17.0|nvmでインストール|
|package Dependencies|vuepress^1.5.3<br>http-server^14.1.1|


## 先に結論
Windows Defender ファイアウォールでNode.js JavaScript Runtimeのファイアウォール経由通信を許可したら通りました。


## 解決までの手順
1. ログの確認  
エラーログに書いてあったログファイルを見てみます。  
SSLの問題っぽいということはわかりましたが、コンソールに出力された情報とたいして変わりませんでした。

    ```
    :
    225 verbose stack Error: 3956:error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:677:
    225 verbose stack
    226 verbose cwd 【..node project dir..】
    227 verbose Windows_NT 10.0.19044
    228 verbose node v16.17.0
    229 verbose npm  v8.15.0
    230 error code ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC
    231 error 3956:error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:677:
    231 error
    232 verbose exit 1
    ：
    ```

2. エラーコードで検索  
Githubの解決済みのissueページが出てきたので参照します。
[npm ERR! code ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC #3815](https://github.com/nodejs/help/issues/3815)
Windows defender firewallの設定を変えたら解決したというコメントがちらほら。
どのパッケージか分かりませんが、インストール時にSSLハンドシェイクをするのであればNodeクライアントが外部通信をするので、邪魔されている可能性はありそうです。

3. Windows Defender ファイアウォールの設定を変更
Node.js JavaScript Runtimeからの通信を許可しました。
    1. 「Windows Defender ファイアウォール」の設定を開く  
    2. 「Windows Defender ファイアウォールを介したアプリまたは機能を許可」  
    3. 「設定の変更」で変更開始
    4. 「別のアプリの許可」で新たに設定
    5. node.exeを選んで「追加」

4. 再度``npm install``の実行
同じエラーがでました。ファイアウォールの設定が反映されていない可能性があるため、PCを再起動。

5. 再々度``npm install``の実行
できました。


## まとめ
大した内容じゃないですが、まだ同じエラーに対して日本語での対処記事がなかったので、書きました。
同じ問題にあたった誰かの助けになればと思います。
【2022年9月版】中年エンジニアのための、Docker Compose な zabbix をサービス化する

# Docker Compose な zabbix をサービス化する

- docker-compose で動作する zabbix を systemd でサービス化するメモです
- ここでは、zabbix 6.2 を稼働させて、systemd のサービスとして登録します
- dockerの設定、docker-composeの説明は省きます
    - 参考：[【2022年版】中年エンジニアのための、UbuntuでDockerでZabbix構築](https://qiita.com/nouernet/items/84130a46b9e4427db1c2)

## 前提

- 利用する OS は ubuntu
```terminal
$ uname -a
Linux nouer 5.4.0-125-generic #141-Ubuntu SMP Wed Aug 10 13:42:03 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
```

```terminal
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
```

```terminal
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

```terminal
$ docker --version
$ Docker version 20.10.18, build b40c2f6
```

```terminal
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
```

- zabbix の docker-compose のインストールフォルダは、/usr/local/bin/zabbix-docker
- インストールする zabbix は 6.2
- zabbix は ubuntu_mysql を利用する

## zabbix のインストール

```terminal
$ cd /usr/local/bin
$ git clone https://github.com/zabbix/zabbix-docker.git
$ cd zabbix-docker
$ git branch
* 6.2
$ cp docker-compose_v3_ubuntu_mysql_latest.yaml docker-compose.yaml
$ docker-compose pull
```

## zabbix の起動

```terminal
$ docker-compose up -d
```

## zabbix の動作確認

- terminal で確認

```terminal
$ docker-compose logs -f
```

- ブラウザでもAdmin/zabbixでログインして確認

## zabbix の停止

```terminal
$ docker-compose down
```

## systemd のユニットファイルを作成

- ユニットファイル ```/etc/systemd/system/docker-compose-service@.service``` を作成する

```terminal
$ cat /etc/systemd/system/docker-compose-service@.service 
[Unit]
Description=%i managed by docker-compose
Requires=docker.service

[Service]
Type=simple

Environment=COMPOSE_FILE=/usr/local/bin/%i/docker-compose.yaml

ExecStartPre=-/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes
ExecStart=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} up
ExecStop=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes 

[Install]
WantedBy=multi-user.target
```

## systemd のサービス登録

```terminal
$ sudo systemctl enable docker-compose-service@zabbix-docker
```

## systemd でサービス化した zabbix を起動

```terminal
$ sudo systemctl start docker-compose-service@zabbix-docker
```

## systemd でサービス化した zabbix の動作確認

- terminal で確認

```terminal
$ sudo systemctl status docker-compose-service@zabbix-docker
```

または

```terminal
$ docker-compose logs -f
```

- ブラウザでもAdmin/zabbixでログインして確認

## systemd でサービス化した zabbix を停止

```terminal
$ sudo systemctl stop docker-compose-service@zabbix-docker
```

## systemd のサービス解除

```terminal
$ sudo systemctl disable docker-compose-service@zabbix-docker
```

## さいごに

かんたんでしたね
【環境設定】macでファイルを開くアプリを変更する方法

## 背景
- macでは、拡張子ごとにどのアプリで開くかデフォルトで設定されています。
- ファイルを開くデフォルトのアプリの変更方法を紹介します。

## 前提環境
- macOS 12.4
- arm64(M1)

## macでファイルを開くアプリを変更する方法

### 開くアプリを変更したい拡張子のファイルの情報を見るをクリック
- 今回は、「.txt」の拡張子を持つファイルを開くアプリを「CodeEditor」から「テキストエディット」に変更します。
![01_info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/7c927635-0b26-5f62-d5b7-b32162698123.png)

### ファイルを開くのに使用したいアプリを選択
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/310ec3c1-b822-b068-ab9a-7b6df7f4f105.png)

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/6cd5b08b-da7d-6e57-1459-7e688d2f6f00.png)

### ファイルを開くアプリを変更
- 「テキストエディット」を「.txt」の拡張子を持つファイルの開くデフォルトのアプリとして設定します。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/efb53b04-b992-6ddc-9e55-83a0bff8b0e6.png)

## 参考資料

https://support.apple.com/ja-jp/guide/mac-help/mh35597/mac#:~:text=%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E9%96%8B%E3%81%8F%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%81%92%E4%B9%85%E7%9A%84%E3%81%AB%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B&text=%E3%81%BE%E3%81%9F%E3%81%AF%E3%80%81Control%E3%82%AD%E3%83%BC%E3%82%92%E6%8A%BC%E3%81%97,%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

## 個人ブログ

https://takuma-tech.com/2022/09/28/292/
systemdについて

## 環境
Ubuntu20.4

## 起動プロセス
現在のLinuxOSの起動プロセス（init）には**systemd**が使われています。旧バージョンのLinuxでは、SystemV（SysV） が使われていました。systemdが採用されるようになったのは、**CentOS7/RHEL7**からです。Ubuntuでは、**15.04**からです。自分が使っている環境はUbuntu20.4であるため、SystemVではなく、systemdが動いているはずです。本当に、systemdが動いているのかについては、次のコマンドで確認することができます。つぎのコマンドを実行して、systemdが存在していれば、systemdが動いていることになります。
```
$ls -l /usr/lib | grep systemd
$ls -l /etc | grep systemd
```

systemdが存在していなければ、System Vが動いているはずです。System Vが動いてることを確認するには、次のコマンドを実行します。inittabが存在していれば、System Vが動いていることになります。
```
$ls -l /etc | grep inittab
```

自分の環境であるUbuntu20.4では、確かにsystemdが存在しており、inittabは存在していませんでした。System Vのときは、サービスを管理するコマンドに、serviceコマンドが使われていました。systemdになってからは、systemctlコマンドが使われるようになっています。しかし、systemdであっても、serviceコマンドは使えるようになっています。サービスの一覧を確認するコマンドを、serviceとsystemctlの両方で実行してみます。共に、問題なく実行されます。
```
$service --status-all
$systemctl list-units --type service --all
```

systemdになって、serviceコマンドを、即使えないようにするのではなく、systemctlコマンドのラッパーとして残存させているためです。過去にserviceコマンドを使っていた人であれば、systemctlコマンドに慣れるまでの間、serviceコマンドを使うことができるようにしています。systemdの仕組みがまだよくわかっていないという人も、serviceコマンドの方が使いやすいと思います。

systemdによって、レガシーとなったコマンドはserviceコマンドだけではありません。サービスを有効/無効にするコマンドとして、CentOS/RHEL系のOSでは、chkconfigコマンドが使われていましたが、このコマンドも、systemdによって、systemctlコマンドに統一されています。systemdによって、chkconfigコマンドでやっていたことが、systemctlコマンドでできるようになったということです。

Ubuntuでは、chkconfigコマンドが存在していないため、代わりに、sysv-rc-confコマンドが使われていたと思います。sysv-rc-confコマンドも同じように、systemctlコマンドに置き換わったということです。そして、sysv-rc-confコマンドもまた、systemctlのラッパーとして残存しています。

>（参考）
Ubuntuではsysv-rc-confコマンドの他にも、似たようなツールは色々とあるようです。
https://server-setting.info/debian/debian-like-chkconfig.html
asdfでruby2.7.6が見つからない件

# はじめに
コロナにかかってしまった筆者です。高熱は3日続き、微熱が1週間下がらず、半年前から計画していた旅行には行けず、悲しい思いをしました。
気をつけてはいたのですが、皆様もどうぞお身体にはお気をつけくださいませ:pray:

さて、今回は新規で参画するプロジェクトのGitリポジトリをクローンして、bundle installした際に、Gemfileに記載のRubyのバージョンが違うと怒られました。

↓こんな感じですね。
```console
> bundle install
Your Ruby version is 2.6.6, but your Gemfile specified 2.7.6
```

asdfでバージョン管理しているので、早速インストールしようとすると、ないと言われてしまいました。

```console
> asdf install ruby 2.7.6
Version not found
```

そして、確かにないですねー。。
```console
> asdf list all ruby | grep 2.7
1.8.6-p287
2.0.0-p247
2.2.7
2.7.0-dev
2.7.0-preview1
2.7.0-preview2
2.7.0-preview3
2.7.0-rc1
2.7.0-rc2
2.7.0
2.7.1
2.7.2
2.7.3
2.7.4
2.7.5
jruby-9.2.7.0
rbx-2.2.7
rbx-2.7
rbx-2.71828182
```


それの解決方法を描いていこうと思います。

# 結論
プラグインのアップデートを行います。
今回の対象はRubyなのでそれだけ。

```console
> asdf plugin update ruby
Updating ruby to master
From github.com:asdf-vm/asdf-ruby
   d0e5a20..f574abf  master     -> master
   d0e5a20..f574abf  master     -> origin/master
Already on 'master'
Your branch is up to date with 'origin/master'.
```

無事に表示されるようになりました。
```console
> asdf list all ruby | grep 2.7
1.8.6-p287
2.0.0-p247
2.2.7
2.7.0-dev
2.7.0-preview1
2.7.0-preview2
2.7.0-preview3
2.7.0-rc1
2.7.0-rc2
2.7.0
2.7.1
2.7.2
2.7.3
2.7.4
2.7.5
2.7.6
jruby-9.2.7.0
rbx-2.2.7
rbx-2.7
rbx-2.71828182
```

# おわりに
さくっとできてよかったです。これで2.7.6のインストールができそうです:pray:
お困りの方の支えになれば幸いです。
それではー。
ファームウェア／ソフトウェアエンジニアが知っておきたい電気設計の基礎知識【デジタル回路編】

# デジタル回路とは(アナログからデジタルへ)

ファームウェア／ソフトウェアエンジニアが電気知識を身につける上でのベース知識として、まず **デジタル回路は「電気」をどのようにしてデジタル信号としているのか** 、を知る必要があると思います。

FWが書き込まれるMCUは、接続された周辺電子部品とデジタル信号でやり取りをし、FWはそのデジタル信号を用いて処理を行うことはご存じだと思います。
また、そのMCUは電気基板に実装されていて、周辺電子部品と「**電気**」でデータのやり取りをすることもご存じだと思います。
この「電気」をどのようにしてデジタル信号として扱われるのでしょうか。

# アナログ信号とデジタル信号

まず、デジタル信号とは何か、対比するアナログ信号とは何か、をざっくり説明すると以下の通りです。

- **デジタル信号**：「電気」の振幅と時間の両方ともに離散値をとる信号のこと
- **アナログ信号**：「電気」の振幅と時間のどちらか一方でもとびとびの値ではなく連続した値（連続値）をとる信号のこと

<img width="400" alt="スクリーンショット 2022-09-29 16.02.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219768/2d2a8f0a-5cc4-6ad6-0b84-7ddecd9184a7.png">

そして、 **デジタル回路** とは、デジタル信号を情報の表現に用いる電子回路のことをいいます。
デジタル回路で扱われるデジタル信号の多くは2進数ですので、以降は2進数のデジタル信号に絞ってお話します。

<img width="400" alt="スクリーンショット 2022-09-29 16.04.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219768/c575aea2-db7e-26ff-7f25-1d9b64616c48.png">

# 「電気」をデジタル信号へ

アナログ信号をデジタル信号として扱えるようにすることを **AD変換** と言います。
英語のAnalog-to-digital converterの略で **ADC** と言ったりもします。
ここからは、「電気」の振幅と時間の両方を離散化するADCの説明です。

## 時間の離散化

こちらはメインではないのでさらっと。
MCUはシステムクロックを元にした周期で動作します。
MCUは、この周期に従ってデータのやり取りをするので、自然とそのデータの時間軸は離散化されます。

## 「電気」の振幅の離散化

こちらが伝えたいメインです。

デジタル回路での「電気」の振幅とは、ずばり電圧です。
つまり、信号を”0”, ”1”の2進数のデジタル値として扱うのに電圧の離散化が必要です。
電圧の離散化は、MCUの端子内部のHW特性によって決まる**電圧の閾値**によって行われます。
ある電圧以上を"1"とする、ある電圧以下を"0"とする、としているわけです。

まとめると、アナログ信号をデジタル信号として扱う流れは以下の通りです。

<img width="600" alt="スクリーンショット 2022-09-29 16.05.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219768/404f6d59-81c4-2371-e775-c11628eacf9b.png">

### ”0”, “1”を判定する電圧の閾値

電圧の閾値についてもう少し詳しく説明します。ちょっと電子部品の話です。

「データのやり取り」とは、相手のICがいて成り立ちます。
ある一方のICに着目すると、そのICで行っている「データのやり取り」は「入力」と「出力」に分解することができます。
ICの入力・出力それぞれで、電圧の離散化のための閾値を以下の表のように言います。
呼び名の由来は以下の略だと思います。

「V」はVoltage
「I」はInput、「O」はOutput
「L」はLow level (”0”のこと)、「H」はHigh level (”1”のこと)

<img width="400" alt="スクリーンショット 2022-09-29 16.06.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219768/4b32956a-b3dd-0cfa-bd3b-97b54bc7ba4e.png">

もう少し詳しく書くと以下の通りです。

- **VIL**：ICは、入力される電圧がこれ以下なら"0"と判定するよ、という閾値
- **VIH**：ICは、入力される電圧がこれ以上なら"1"と判定するよ、という閾値

- **VOL**：ICは、"0"としてこれ以下の電圧を出力するよ、という閾値
- **VOH**：ICは、"1"としてこれ以上の電圧を出力すると、という閾値

この VIL / VIH、VOL / VOH は、基本的に電子部品のデータシートで確認することができます。
入力される電圧がVILとVIHの間の電圧 (「**中間電位**」と言う)になってしまうときは注意が必要です。
"0"と判定するか"1”と判定するか保証されませんし、ICの端子内部回路で不正に電流を流れてしまったりしてHW的にもよくありません。
基本的に電気エンジニアが、ICに中間電位が入力されないようにしなければいけないのですが、FWエンジニアも知識として知っておいて不具合解析などで電気的な議論にも参加できるようになると良いかなと思います。

# 参考資料

[Renesas Engineer School](https://www.renesas.com/jp/ja/support/engineer-school/digital-circuits-01-and-circuit-or-circuit-not-circuit)
[EDN Japan - アナログICの基礎の基礎 第1回アナログとデジタル](https://edn.itmedia.co.jp/edn/articles/0903/01/news017.html)
[【入門】アナログ回路とデジタル回路の違い](https://engineer-climb.com/analog-digital-difference/)
[AD変換とは！？アナログ信号からディジタル信号へ！](https://kenyu-life.com/2019/06/26/analog_to_digital_conversion/)
HTMLメールの実装に入る前にこれだけは確認しとけ！と思ったもの

# 確認すべき4選
## SPサイズの対応方法について
- PCサイズと全く同じデザイン・横幅で実装するのか？
- PCサイズを縮小したデザインで実装するのか？
	- これが一番実装コストがかからずコスパがいいと思う
- PCとSP全く別のデザインで実装するのか？
	- ただし、下記の通りメディアクエリは使用しない方がいいのでこの方法はおすすめしない

## ブラウザはどこまで対応するのか？
運営中のwebサービスと同じにするのが吉だと思います。
MacであればChrome、Safari、Firefox、windowsChrome、edge、Firefoxまで確認できるとよし。

## メールソフトはどこまで対応するのか？
- 全部のメールソフトに対応するのは不可能なのでどこかで足切りが必要
- 自分の場合はGmail、Yahooメール、Outlookはデザイン崩れしないようにした
- SPの場合、メールソフトのアプリで見た場合とwebブラウザで見た場合の2通りがあるので注意！
- windowsに搭載されているOutlook200X、201Xがよくデザイン崩れを発生するので注意!

## 使用する画像について

- 上記で書いた通り、PCとSPを一緒のデザインにするのであればPCサイズを縮小したデザインで実装する場合、画像が縮小される可能性がある
- メールソフトによってはcssのpositionが使えないため画像の中に画像を入れるのは避けたほうがいい。2つの画像が合体した1つの画像を使う形にした方がいい。例えば下記の場合はお城の背景とネズミの画像を一体化した方がいい

![](https://storage.googleapis.com/zenn-user-upload/2d4324f18d84-20220929.jpeg)


# cssコーティングについて
## cssのコーティングはclassでなくHTMLに直接書く
iOSでブラウザでGmailを開いた時など、一部の状況でcssが全く効かなくなるため　。
そのためメディアクエリなどのブレークポイントは使えないのでSP専用のデザインは用意せず、PCサイズのものをそのまま縮小できるデザインの方がいい

```html
<p style="font-weight: 700; font-size: 20px; color: #000;">
ユーザー招待が届きました
</p>
```
## 要注意cssプロパティ
下記のサイトを参考にcssプロパティを使う。ほぼ100%対応しているcssプロパティは存在しない
https://www.campaignmonitor.com/css/

### flexプロパティ
横並びはtableタグで実装する

### padding/margin
Outlook 2007–16で不具合が発生する可能性がある。
余白を定義する場合は以下のような感じにする
```html
<table height="32px">
  <tr>
    <td></td>
  </tr>
</table>
```

### max-width
レスポンシブ対応するために全体のレイアウトの幅を定義する時だけ使用。
Outlook 2007–16が対応してないことがあるが、横幅が広がるだけなのでデザイン崩れなどは発生しない。

### border-radius
Outlook 2007–16が対応してない。

### white-space
改行した文字列を改行として扱うように定義。
主にoutlook全般で対応していない。

### word-wrap
主にYahooメールで対応していない。
URL発行系のメールをYahooメール(SP)で見た時に横スクロールできてしまうので、URLをそのまま表示させない等の対応が必要かも

### position
上記で挙げた画像の重なりとかは実装できないと思った方がいい。
Oracleで全角を2バイト換算で文字列のバイト数取得

# 概要

まず、Oracleの文字コードが『AL32UTF8』環境の前提です。

その場合、下記の結果は『3』。

```sql:
LENGTHB('あ')
```

このLENGTHB()について、シフトJISのように全角文字を2バイト換算させたい。

# やり方

```CONVERT()``` でシフトJISに変換してから ```LENGTHB()```。

```sql:
LENGTHB(CONVERT('あいうえお001', 'JA16SJIS'))
```

上記の結果は『13』。

『あいうえお』部分は2バイト×5文字=10バイト。
『001』部分は3バイト。

# 参考サイトさん

https://qiita.com/waokitsune/items/eaeca4b2c6d78a78b641

https://www.system-exe.co.jp/dbexpert17/

https://atmarkit.itmedia.co.jp/ait/articles/0903/04/news115_3.html

http://www.doppo1.net/oracle/admin/nls.html

# バージョン

Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
それぞれのComboBoxに同じDataTableを入れる場合の注意点

備忘です。

C#でWindowsフォームアプリケーションを製造していました。

で、ComboBoxの2つ用意して、別々のフィールドで管理していました。
ComboBoxの選択肢はDataSorceプロパティにDataTableを突っ込んで動的なものにしていました。**ちなみに両方とも同じDataTableを突っ込んでいます。**


実際に動かしてみると、なぜか片方を選択すると、もう片方も同じ選択肢が入ってしまいました。
**別々のフィールドにしていてもです。**

色々ネットの海をさまよい歩いて以下の解決方法を見つけました。

```c#:qiita.cs
            //役職1
            comboBox2.BindingContext = new BindingContext();
            comboBox2.ValueMember = "コード";
            comboBox2.DisplayMember = "名称";
            comboBox2.DataSource = bunruiTable2;//役職1
            comboBox2.SelectedValue = dt1.Rows[0][2].ToString();
            comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
            //役職2
            comboBox3.BindingContext = new BindingContext();
            comboBox3.ValueMember = "コード";
            comboBox3.DisplayMember = "名称";
            comboBox3.DataSource = bunruiTable2;//役職2
            comboBox3.SelectedValue = dt1.Rows[0][3].ToString();
            comboBox3.DropDownStyle = ComboBoxStyle.DropDownList;
```

comboBox.BindingContext = new BindingContext();
をつけると別々のComboBoxとして管理される？？ようになり、それぞれが干渉しあうことがなくなりました。

でも結局なぜ干渉されるのか、上記のコードが本来どんな役割を持っているのかは不明。
また時間があるときに勉強したい。
ブラウザーだけで使えるインストール不要の完全無料オンラインPDFツール、Windows/Mac/Linux/iOS/Android対応

最近、リモートワークやペーパーレス化の拡大につれて、デジタル文書の形式であるPDFがますます重要な役割を果たしています。デスクワークが仕事の方々は誰でもPDFに関する知識やツールの使い方を学ばなければなりませんが、ほとんどのPDFソフトは高価で、無料のものは制限が多く、なかなか大変です。昔使っていたsmallpdfさんはなぜかいろいろ制限が増えて、使いづらくなりましたから、代替のものをずいぶん検索しました。それでは、見つかったOSを問わず、インストール不要、広告なしのクラウドベースのフリーオンラインPDFツールサイトである「LightPDF」を紹介します。

# LightPDFオンラインPDFツール

使用するには、お使いのデバイスのブラウザーでLightPDFのPDFツールサイト(https://lightpdf.com/jp/tools) にアクセスすれば、下記の画像のようなPDFツールの画面が表示されます。中から使いたいものを選べばいいです。
![lightpdf-online-tools-interface.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/92368f9e-e7a4-4448-ba26-c5792db50179.jpeg)

# LightPDFオンラインPDFツールの使い方

どのツールの使い方も簡単です、ファイルをサイトにアップロードして、処理をしばらく待てば、処理済みのファイルをダウンロードできます。例として、PDFからWordに変換するツールの使い方を説明します。

1.LightPDFのオンラインツールから「PDFからWordに」を選択してクリックします。
![pdf-to-word-converter.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/f250a322-c472-652d-d25e-b6a856691a02.jpeg)
2.表示される「PDFからWordに」のウェブページから真ん中の「ファイルを選択」ボタンをクリックして、変換するPDFファイルを指定します。
![upload-pdf-file.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/078154bd-a0d7-0be4-2175-9841b0701820.jpeg)
3.PDFファイルのアップロードがすぐ終わり、「変換」ボタンをクリックすれば変換が始まります。
![convert-pdf-file-to-word.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/e3822285-5767-7fed-7180-e445e335c483.jpeg)
4.しばらくすればPDFが変換され、「ダウンロード」ボタンをクリックして、変換済みのファイルをローカルドライブに保存しましょう。
![download-converted-pdf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217547/1698dc92-1afb-9c6b-158e-ec9428a92c8e.jpeg)
5.ファイルはブラウザーのデフォルトのダウンロード先に保存されます。

他の変換ツールや編集、分割、結合、回転、注釈追加、圧縮、保護、パスワード解除（アンロック）、署名やOCRツールも、同じようにファイルをサイト上にアップロードすれば、その機能を利用できます。必要な機能を選んで利用しましょう。

# LightPDFオンラインPDFツールの注意事項

1.LightPDFはデスクトップ版もありますが、有料なので、無料のオンライン版で十分だと思います。
2.SDKもあるようなので、開発者なら、自分のアプリやサイトにLightPDFの機能を追加する場合は、SDKを利用してもいいかもしれません。
3.ファイルはサイト上にアップロードする必要がありますが、処理はクラウド上で行われるようで、サイトのサーバーにファイルは保存されません。セキュリティについても安心して利用可能です。
4.ブラウザーだけで使用できるウェブアプリなので、OSや端末の制限はなく、ほとんどのデバイスで動作可能です。
5.完全無料ですが、使ってみたところ、OCR以外の機能は確かに完全無料でした。OCRの場合は、無料ユーザーはスキャンしたPDFをTXT形式のみに変換できます。OCRに選択可能な言語も二種だけです。
追記：現在はOCRも完全無料になりました。一部の機能は複数のファイルを同時処理できません、複数のファイルを追加して処理させる場合は、一つずつ処理されます。
6.サイトの内容やツールは日本語対応で、日本語でのサポートも可能です。利用中に質問がありましたら、気軽にサポートセンターに問い合わせを発送しましょう。
サポートセンターのURL：https://lightpdf.com/jp/contact
yarn create vite で自動作成されるコードでVueを解説してみる

# yarn create vite で自動作成されるコードでVueを解説してみる
- 説明
  - yarn create vite　をするとアプリのひな形が作られる
  - 参考ページとしてHelloWorld.Vueなどが入っている
  - その内容をもとにVue3、特にCompositionAPIの解説をしてみる（学習のため）

# ひな形についての基礎知識
- 基本はHTMLなので`index.html`を表示している
  - 中には以下の二つの記述
   
  ```
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
   ```
  - ポイントは
    - idがappの要素があること(伏線)
    - /src/main.tsを読み込んでいること

# main.ts
- 名前が出てきたのでsrc/main.tsを見てみる
- これもまたシンプルで以下の内容

```
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')
```
- 各行の意味は
  - vueからcreateAppという名前でexportされたものをimport
  - ./style.cssをimport
  - ./App.vueからexport defaultをimport
    - import時につけた名前はApp
  - AppをもとにcreateAppして、appというidを持った要素にmount(ここさっきの伏線回収)

# App.vue
- また名前のでてきたApp.vueについて見ていく
- ここはいろいろ書かれているが、おおまかな構造は以下の３つのタグ
  - script
  - template
  - style
- scriptとstyleはHTMLを知っていれば見たことあるはず
- 見たことのないtemplateはvueの機能
- templateの中を見ていこう
  - 気になるのは（見たことがないのは）HelloWorldタグ
  - 実はこれはscriptに書いてある以下と関係している
  ```
    import HelloWorld from "./components/HelloWorld.vue";
  ```
# components/HelloWorld.vue
- また上で現れたHelloWorld.vueを見ていこう
- これも大まかな流れはApp.vueと同様
  - script
  - template
  - style
- ここからがVueの機能を紹介する本番

## template内のVueの機能紹介
- templateを上から見て気になる所を選んで見ていこう
  - h1の中の{{ msg }}
    - Vueではscript内で定義した変数を{{ }}で参照できる
    - const msg = "hello" とかだったら、helloがh1の中にはいることになる
    - 実際はdefinePropsとの合わせ技なので後で解説
  - buttonの中の@click
    - @click="関数名"とすることでクリック時に関数を呼び出せる
    - 今回はcountという変数をincrementしている
    - ボタンの名前に{{ count }}があるので、ボタンを押すごとに見えている数字が増えていく
- templateの中で気になる部分はこれくらいだと思う
- 次はscriptのほうを見ていこう
## script内のVueの機能紹介
- ```defineProps<{ msg: string }>()```
  - ここを紹介するために、HelloWorld.vueがApp.vueでimportされるとどうなるかを説明する
  - App.vueでHelloWorld.vueをimportすると、```<HelloWorld>```タグが使える
  - そのタグの中身はHelloWorld.vueのtemplateで定義されているもの
  - そこに引数を渡そうとするときに```defineProps```が使われる
  - つまり```defineProps<{ msg: string }>()```によって```<HelloWorld>```のなかで```msg=...```という属性が使えるようになる
  - （このtemplateを読み込んで、次のtemplateを書くという作業は入れ子構造なので、小さい部品から徐々に大きくという設計ができる。[AtomicDesign](https://qiita.com/Kazuhiro_Mimaki/items/3d9a8594064aab5119da))
- ```const count = ref(0)```
  - refはリアクティブな変数を定義するのに使われる
  - リアクティブとは、その変数が書き換わったときに、表示も更新されるもの
  - （逆にリアクティブでないと、変数が更新されてもページでの表示は勝手には変わらない）
  - これは変数１個だったが、reactiveという関数を使用すると、JavaScriptのオブジェクトを丸ごとリアクティブにもできる

# 最後に
ここでは本当にHelloWorld.vueにある機能しか紹介しなかった。

しかし、Vueにはほかにも色々な機能があるので、探して使ってみてほしい。(computed, watchなど)

というか私も使いこなしたい。

それと、今回の機能というか書き方はCompositionAPIというVueの新しい記述方法で、vue3では主流になるらしい。

vue2で```new Vue({el: "#app", ...})```などと書いていた人からは、大分違和感があると思うが、例えば今回の例だと、リアクティブな変数が明示的になるなど、分かりやすくなることもあると思う。
色弱者用のカラー設定(vim､ls､git)

`purple`とか`red`とか`magent`とかよく見えないんです｡涙
例えば､以下の`build.sbt`とか`database.conf`は､なにかあるのはわかりますが､まったく読めません｡
![](https://i.gyazo.com/81e6396ba0a68f46de6091ddc52340df.png)
ターミナルを使っていてよく使うツール(vim,git,ls)について軽減する設定を整理しました｡
## vim

```~/.vimrc
colorscheme desert
```

## lsの実行結果

[Configuring LS_COLORS](http://www.bigsoft.co.uk/blog/2008/04/11/configuring-ls_colors) の 31(red),35(purple),36(cyan)を全て32(green)に変えてます｡

| Code | Property |
|:-:|:-:|
| 30 | Black |
| 31 | Red |
| 32 | Green |
| 33 | Orange |
| 34 | Blue |
| 35 | Purple |
| 36 | Cyan |
| 37 | Grey |

```~/.bashrc
LS_COLORS='rs=0:di=01;34:ln=01;32:mh=00:pi=40;33:so=01;32:do=01;32:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;32:*.tgz=01;32:*.arj=01;32:*.taz=01;32:*.lzh=01;32:*.lzma=01;32:*.tlz=01;32:*.txz=01;32:*.zip=01;32:*.z=01;32:*.Z=01;32:*.dz=01;32:*.gz=01;32:*.lz=01;32:*.xz=01;32:*.bz2=01;32:*.bz=01;32:*.tbz=01;32:*.tbz2=01;32:*.tz=01;32:*.deb=01;32:*.rpm=01;32:*.jar=01;32:*.rar=01;32:*.ace=01;32:*.zoo=01;32:*.cpio=01;32:*.7z=01;32:*.rz=01;32:*.jpg=01;32:*.jpeg=01;32:*.gif=01;32:*.bmp=01;32:*.pbm=01;32:*.pgm=01;32:*.ppm=01;32:*.tga=01;32:*.xbm=01;32:*.xpm=01;32:*.tif=01;32:*.tiff=01;32:*.png=01;32:*.svg=01;32:*.svgz=01;32:*.mng=01;32:*.pcx=01;32:*.mov=01;32:*.mpg=01;32:*.mpeg=01;32:*.m2v=01;32:*.mkv=01;32:*.ogm=01;32:*.mp4=01;32:*.m4v=01;32:*.mp4v=01;32:*.vob=01;32:*.qt=01;32:*.nuv=01;32:*.wmv=01;32:*.asf=01;32:*.rm=01;32:*.rmvb=01;32:*.flc=01;32:*.avi=01;32:*.fli=01;32:*.flv=01;32:*.gl=01;32:*.dl=01;32:*.xcf=01;32:*.xwd=01;32:*.yuv=01;32:*.cgm=01;32:*.emf=01;32:*.axv=01;32:*.anx=01;32:*.ogv=01;32:*.ogx=01;32:*.aac=00;32:*.au=00;32:*.flac=00;32:*.mid=00;32:*.midi=00;32:*.mka=00;32:*.mp3=00;32:*.mpc=00;32:*.ogg=00;32:*.ra=00;32:*.wav=00;32:*.axa=00;32:*.oga=00;32:*.spx=00;32:*.xspf=00;32:';
```

## Gitコマンドの出力結果

[How to color the Git console? - Stack Overflow](https://stackoverflow.com/questions/10998792/how-to-color-the-git-console)の`magenta`,`red`,`cyan`を`yellow reverse`に変えてます｡

```config:~/.gitconfig
[color]
    ui = auto
[color "branch"]
    current = yellow reverse
    local = yellow
    remote = green
[color "diff"]
    meta = yellow bold
    frag = yellow reverse bold
    old = yellow reverse bold
    new = green bold
[color "status"]
    added = yellow
    changed = green
    untracked = yellow reverse
```

## 追記

色弱の人もそうでない人も以下のようなモヤモヤを感じると思います｡

- どの系統の色弱でも対応できる色使いってないの?
- 赤系を違う色に置き換えないで視認できる方法ないの?

その答えを @TyaoiB さんがご案内してくださいました｡

詳細は､[｢色盲の人にもわかるバリアフリープレゼンテーション法」](https://www.nig.ac.jp/color/bio/) をご覧いただくとして､結論だけ記載しておくと､､､

> Q.どの系統の色弱でも対応できる色使いってないの?

限られた種類の色を区別させるのであれば、
使用する色を工夫することで全てのタイプの色盲に対応が可能です。
例えば、我々は赤と緑の色の組み合わせのかわりに、
赤紫と緑の組み合わせを使うよう提唱しています

> Q.赤系を違う色に置き換えないで視認できる方法ないの?

赤を使用する場合は「濃い赤」（#FF0000)を使わずに、より短波長側の「朱 色」（例えば#FF2000)や、
白を加えた「明るい赤」（例えば#FF1414)を使用すると黒と識別しやすくなり（図６参照）、
暗い背景の中でも図形や文字を視認できるようになります。

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

@TyaoiB さん､コメント&有用情報のご案内ありがとうございました｡m(_ _)m
【Docker for Windows】Error response from daemon: user declined directory sharing C:\Users\path_to_my_folder

## 問題

Windows10で `docker compose up -d` をすると下記のエラーが発生しました。

```shell-session
$ docker compose up -d

Error response from daemon: user declined directory sharing C:\Users\path_to_my_folder
```

## 確認

Docker for Windowsを確認します。

ダッシュボード > settings > Resources > FileSharing

ファイル共有しようとしたパス `C:\Users\path_to_my_folder` が登録されていないことを確認します。
手動で登録してもOKですが通常であればファイル共有の通知が来て許可すれば登録されるはずです。

https://stackoverflow.com/questions/70877785/docker-error-response-from-daemon-user-declined-directory-sharing

## 通知が来ない原因

Windows10に集中モード(Focus Assist)機能があります。
この設定が有効になっているとDockerからの通知が来なくなり、ファイル共有を許可されないままとなります。

https://pc-karuma.net/windows-10-focus-assist

## まとめ

集中しないでください。
複数の画像に一括で透かしを入れる方法

# 複数の画像に透かしを挿入する
著作権保護のために画像に透かしを入れるという人も多いようです。 一枚ずつ透かしを挿入するのは難しく、時間がかかることもあります。 今回は、複数の画像に同時に透かしを挿入する方法を説明します。 ご興味のある方はご覧になってみてください。
## 環境と前提条件
### デバイスとソフト
携帯電話やパソコンで使える画像編集ソフトウェアがたくさんあります。 もちろん個人的には、パソコンで写真を加工する方が少し便利だと思います。 ここでは、画像編集ソフトの「PicWish」を例にとして説明します。

### 使う手順
1.パソコンに[PicWish](https://picwish.com/jp)ソフトをインストールして起動します。
[ダウンロードurl](https://download.aoscdn.com/down.php?softid=picwishphotoeditor?apptype=qitta)

2.「透かしを入れる」というアイコンをクリックします。
![screenshot_20220929_141815.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417797/a3f14232-51fd-25ac-33fa-e0be63f70bc9.jpeg)

3.画像を選択してアップロードします。
![screenshot_20220929_141847.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417797/d7917c34-db98-47e3-97e3-bd8a9d6d8630.jpeg)
（最大100枚の写真をアップロードできます。）
![screenshot_20220929_142235.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417797/9176255f-cad6-7048-c56b-7bfa9b3dc7bc.jpeg)



4.右側にある編集ツールで文字・画像の透かしを作成して挿入します。
![screenshot_20220929_142602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417797/be35747a-ee5e-5696-2181-9e0c6791521d.jpeg)