OmniAICreator/Qiita-1.07M huggingface dataset:
TimberでJetpack Composeのログを良い感じに。

# はじめに

こんにちは。
今日はJetpack Composeのログについて書こうと思います。Viewを使用していた時はピュアな`android.util`で事足りていましたが、Jetpack Composeでは基本Composable関数単位でログのタグを出力したいと思い調べてみました。

約二年Androidエンジニアをしていますが、Timber初めて使ってみました。ふふふ。

# どうするの？
Timberというログ出力ライブラリを使用します。実際は`android.util`をラップした軽量のライブラリだそうです。Timberについて詳しく知りたい人は[こちら](https://github.com/JakeWharton/timber)を覗いてみてください。

やることは以下です。
1. Timber.DebugTreeを継承したクラスを作り、自分好みにカスタマイズ！
2. Applicationクラスにて(1)で作成したクラスを初期化する。


1. Timber.DebugTreeを継承したクラスを作り、自分好みにカスタマイズ！

```kotlin:TimberSetting.kt
class TimberSetting(
    private val context: Context
): Timber.DebugTree() {
    // 引数のtagはcreateStacElementTagで作成したもの
    // ユニークなTAGを入れておくと、自アプリのログだけでfileterできる。
    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        super.log(priority, "YOUR_UNIQUE_TAG" + tag, message, t)
    }
    // TAGを生成する。引数のelementからファイル名や行数などを取得できる。
    override fun createStackElementTag(element: StackTraceElement): String {
        return String.format(" [C:%s] [L:%s] [M:%s]",
            super.createStackElementTag(element),
            element.lineNumber,
            element.methodName)
    }

}
```

2. Applicationクラスにて(1)で作成したクラスを初期化する。

```kotlin:MyApplication
// AndoridManifest.xmlへの追加を忘れずに！
class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            Timber.plant(TimberSetting(this))
        }
    }
}
```

以上の実装で以下のようなログが出力されます。

```kotlin:MainActivity
@Composable
fun Main() {
    Timber.i("Main Composable!") //20行目
}
```

```log
I/YOUR_UNIQUE_TAG [C:MainActivityKt] [L:20] [M:Main]: Main Composable!
```

# さいごに
Jetpack ComposeでTimberを使ってみました。いや、これJetpack Composeじゃなくても良かったじゃん。とはいえメソッド名出せるの良いですね。もっと前から使っておけば良かった～。
以上です。それではまた次の記事で！


# 参考

[stack overflowの質問](Log method name and line number in Timber)
より効率的な学習を継続させていくために

#はじめに
　皆さんは資格取得やスキル向上などに向けた学習をしてきた経験はあるだろうか。資格やスキルといっても、通勤途中などのスキマ時間において、片手間にやれば取れるものだったり、週平均40時間ほどの学習時間をもってしても、取得までに1年以上かかるものまでいろんなものがある。無論、楽に資格やスキルが取得できればそれに越したことはないのだが、やはり価値の高い資格やスキルほど、取得までに多くの時間と手間がかかってしまうものである。そこで、今回はそういった資格やスキルを取得するための継続的かつ効率的な学習のために、私が色々調べた中で特にオススメできそうなものを紹介していきたい。

 #機能的イメージ・トレーニング（FI）
　これはイギリスの大学などで研究されているイメージトレーニングの一種で、「目標を感覚的に詳しくイメージする」ことで、その目標へのモチベーション向上を高めることができる手法の一つである。

　どれくらいの効果があるのかというと、イギリスのプリマス大学で行われた研究結果では、MIと呼ばれるカウンセリングでよく使われ、依存症の治療に効果が高い手法があるのだが、そのおよそ3倍近くの効果が得られることが分かった。

　※ちなみにMIの研究では、被験者の半年後の禁煙率が最大8倍近くにまでになったという結果が得られている。

　単純計算で8×3＝24倍となるのだから、目標達成のためのモチベーション維持という観点において、FIという手法への期待値は計り知れないのである。

参考URL

https://www.youtube.com/watch?v=Km4lgUDiev8&t=551s

 #究極のアンビエントミュージック
　「自分の好きな音楽を聴きながら勉強すると集中できる」と感じている人が一定数いるが、実は川のせせらぎなどの自然音を除き、基本的には勉強などを一般的な音楽を聴きながら行うのはNGとされているらしい。
　
　これはウェールズ大学の研究で、こうした音楽を聴きながら作業を行った被験者のパフォーマンスが、無音での作業を行なった被験者のと比べて50％程度になってしまったという結果が得られていることからも、かなり信憑性が高い。

　そのため、何か作業をするときは基本的には無音が望ましいとされているが、無音だとすぐに集中が途切れてしまうという人も多くいると思われる。これは集中できていないからではなく、逆に集中しすぎてしまっていて、すぐに疲れてしまうためであるとされている。

　こういった場合に、集中を上手い具合に最適化してくれる効果がある、雨の音や川のせせらぎなどの50デシベル程度の雑音（俗にいう自然音）や、アンビエントミュージックと呼ばれる、よく美術館やカフェなどで流れている環境音のような音楽はオススメである。

　この学習効果を高める効果のある、自然音やアンビエントミュージックにも様々な種類があるのだが、その中でも「世界一リラックス効果のある音楽」というものがある。

　それが「Weightless」という曲である。

　この曲は60BPMから始まり、約5分かけて徐々に50BPMまで落ちるリズムで繰り返しのないメロディであるなどの特徴を持っており、研究のプロと音楽のプロが、人をリラックスあるいは集中させるためだけに作った、まさに「究極のアンビエントミュージック」なのである。

　これは私自身の所感に過ぎないが、私もこの曲に出会ってから基本的にこの曲を聴きながら作業をするようになって、無音の時と比べて集中を途切らせることなく作業に没頭できるようになったと感じている。


参考URL

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

https://www.youtube.com/watch?v=qYnA9wWFHLI&t=1511s
React チュートリアル　パート5　（map）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/e58f938d-5356-5784-5f14-a27903f8d4bd.png)

#目標:military_medal:
useEffect()で取得した、JSONファイルをブラウザに表示させましょう:bangbang:

#App.jsに記述
パート４のソースコードに、追記しています:bangbang:
**追記したコード**について説明いたしますね:blush:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/fcf1190b-1207-6673-d018-d7e64fb65389.png)

>【2行目】 useStateをimportします。

>【8行目】 documentsという変数を準備し、useState(**[ ]**)は、この変数を配列型に初期設定しています。

>【16行目】 取得したJSONファイルをdocumentsに格納します。

>【25行目】 ここからが、表示させるメソッドになります。受け取ったJSONファイルは、配列型になっています。それをmap()メソッドを使って、表示させています。表示させる際も、{document.id}というようにパラメーターを設定します

#ブラウザで確認:fire::fire:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/29b87799-e9c6-2983-bde6-c8390951112e.png)

簡単に表示させることができました:bangbang:
もし出来たら、usernameやemailも表示させてみてくださいね:blush:

#次回:bell:
文字に装飾をしていきましょう:sparkles::sparkles:

#参考

https://youtu.be/LlvBzyy-558
ログインはしてるけど違うアカウントの人ができることを制限したい

ログイン自体していない人はauthenticate_user!でログイン画面に飛ばせるのは前回の記事の話。
前回の記事→https://qiita.com/JkzW1QJsgjPBxa/items/f834c85a420cd253d6bd

が、ログインはしてるけど**別のIDの人**はこれでは**防げない**。

URLを直接入力しちゃえば別のIDのページに行けちゃう。

例えばID１でログインしている人がてへっとID3の人の情報を覗いたり書き換えちゃったり消しちゃったりは、authenticate_user!では防げない。

ので、コントローラーにそれを防ぐ記述をしてみたよ。
（注意：未解決部分あり）

##before_action
コントローラーで、通ってほしいクラスを書くと、指定するアクションに行く前に通ってもらえる。

```ruby:コントローラー
class ActorsController < ApplicationController
  before_action :move_to_root, only: [:show, :create, :update] #←ココと

  def new
    @actor = Actor.find_or_initialize_by(user_id: current_user.id)
  end

  def create
    @actor = Actor.new(actor_params)
    # 略
  end

  def show
    # 略
  end

  def update
    # 略
  end


  private

  def actor_params
    params.require(:actor).permit(:comment, :image).merge(user_id: current_user.id)
  end

  def move_to_root   #←ココ
    # 中身は後で
  end

end
```
今回はshow、create、updateアクションを指定しました。

今まで勉強してきた時はcreateやupdateじゃなくてnewに付ける感じだったんだけど、おそらく今回newアクションにfind_or_initializeを使っている関係で、これでは防げなかった。
ので、この書き方にしてみたんだけど、たぶん不格好というか大丈夫かな？と思っている、、、。
アドバイス等ご教授いただける方いらっしゃいましたらよろしくお願い致します。

↑の書き方をしていると、例えばID１の人がID３の編集ページをURLで指定して入っても、更新されるのはID１の人のページという状態でした。ので、ID3の人のページを書き換えることは防げている、けどroot_pathに戻る挙動ではないので、たぶん根本的に何か違う、、、

さて。

##move_to_rootの中身
こんな感じにしました。

```ruby:コントローラー
  def move_to_root
    @actor = Actor.find(params[:id])
    unless current_user.id == @actor.user_id
      redirect_to root_path
    end
  end
```

redirect_toは↑のようにpathで指定することもできるし、アクションを指定することもできる

アクションで指定する場合は

```ruby
  def move_to_index
    @actor = Actor.find(params[:id])
    unless current_user.id == @actor.user_id
      redirect_to action: :index
    end
  end
```
こういう書き方。

##まとめ
まとめ、というより今回はまだもやっとしたままのアウトプット。
うまくできる方法見つけれた時、また更新します。

それでは。
Windows10+ScoopでDoomEmacsのインストールが上手くいかないとき

# 問題
[Scoopを用いたDoomEmacsのインストール方法](https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#on-windows)を参考に以下を実行した。

```powershell
scoop bucket add extras
scoop install git emacs ripgrep
# Optional dependencies
scoop install fd llvm
# Doom Install
git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
```

この後に

```powershell
~/.emacs.d/bin/doom install
```

が実行できない。


この原因は`C:\Users\name\~\.emacs.d`が生成されていたためだったのでこれを`C:\Users\name\.emacs.d`にコピーし、

```powershell
~/.emacs.d/bin/doom install
```

を実行した。

しかし、Emacsを立ち上げてもDoomが立ち上がらなかった。


# 解決方法

Emacsは標準で`C:\Users\name\AppData\Roaming\.emacs.d`を参照するため、

```powershell
git clone https://github.com/hlissner/doom-emacs $env:APPDATA/.emacs.d
$env:APPDATA/.emacs.d/bin/doom install
```

と実行するか、
doom installを実行した後の`C:\Users\name\.emacs.d`を`C:\Users\name\AppData\Roaming\.emacs.d`にコピーする。

# わからない点
Emacsは`C:\Users\name\AppData\Roaming\.emacs.d`を参照してはいるが、立ち上げのときに`C:\Users\name\.emacs.d`がないとだめっぽい。
適切な解決方法ではない気がするのでご指摘お願いします。
React チュートリアル　パート4　（useEffectフック）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/f87c6086-dd23-c48d-09a6-fecab80c4360.png)

#目標:military_medal:
ReactJsの新機能、**”useEffect( )フック”**を使ってみましょう:bangbang:
**”useEffect( )フック”**は、アプリケーションがレンダリングされたタイミングで動く機能になります:bangbang:

#App.jsに記述
※前回までの、記述は一度すべて削除してください！
そして、下記の様に記述します！
記述内容は説明いたしますので安心を:blush:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/e79fb280-3676-3e18-0f3a-515e5336b69f.png)

まず、ターミナルに**"npm i axios"**を記述して、**Axios**アプリケーションにインストールします！
これは、外部からJSONファイルを読み込む機能になります。

>【1行目】　**axios**をimportします。

>【2行目】　**useEffect**をimportします。

>【7行目】　useEffectとaxiosを使って、**外部のJSONファイル**を取得します（**fetch**の機能と全く同じです）。下記のサイトからJSONファイルを取得しています（ご参考に）！

>【11行目】　responseにJSONファイルが入って、それをコンソールに表示させています。

https://jsonplaceholder.typicode.com/

#コンソールで確認:fire::fire:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/f279d235-dff4-6a01-3f1c-89e8a5a25a25.png)

しっかりJSONファイルを取得できていますね:bangbang:
記述がとてもシンプルなので、わかりやすいですね！

#次回:bell:
:white_check_mark: useEffect()で取得したデータをブラウザに表示させましょう！

#参考
https://youtu.be/LlvBzyy-558
Windows＋VScode＋Anaconda＋JupiterNotebookの設定方法

# 概要

Windows＋VScode＋Anaconda＋JupiterNotebookの設定方法

***
主に以下の記事を参考にした。

Visual Studio code＋Anaconda＋git bashでwindowsでもLinuxコマンドが使えるPython環境を整える。
[Visual Studio code＋Anaconda＋git bashでwindowsでもLinuxコマンドが使えるPython環境を整えた（2020/03/10）](https://ozunderground.hatenablog.com/entry/2020/03/11/034449)

VS CodeでJupyterを起動する方法を設定する。
[VS CodeでJupyterしてみよう](https://atmarkit.itmedia.co.jp/ait/articles/2108/06/news030.html)

***
anacondaではないpython単体をインストールした環境だと、正常にVSodeでJupyter Notebookを起動することができる。
anacondaでpythonをインストールした場合、vscodeで仮想環境のJupyter Notebookを起動させるとエラーになってドツボにはまったので解決法をメモしておく。

#設定方法

## 1.Visual Studio code＋Anaconda＋git bashでwindowsでもLinuxコマンドが使えるPython環境を整える。

以下の記事の設定を進める。
[Visual Studio code＋Anaconda＋git bashでwindowsでもLinuxコマンドが使えるPython環境を整えた（2020/03/10）](https://ozunderground.hatenablog.com/entry/2020/03/11/034449)

###　一部手順を変えていること
上記の手順で、gitbashでcondaを使うために、gitbashの設定ファイル(C:\Program Files\Git\etc\bash.bashrc)に設定を追加している。

以下の設定もC:\Program Files\Git\etc\bash.bashrcに追加しておく。

```
alias python='winpty python.exe'
```

pythonコマンドを実行するときにwinptyを頭に付けるエイリアスの設定。
[Git bash 上から Python インタプリタを起動する](https://qiita.com/cointoss1973/items/a0da81df10f8cc04c83e)

anacondaをインストールした場合は不要かもしれないがおまじないとして書いておく。




## 2.vscodeでJupyter Notebookを使用する。
以下の記事の設定を進める。
[VS CodeでJupyterしてみよう](https://atmarkit.itmedia.co.jp/ait/articles/2108/06/news030.html)
### anacondaではないpython単体をインストールした環境の場合
上記の手順通りの設定で正常に動作する。

設定の流れ
1. VS Codeの拡張機能でJupyter Notebookの機能を追加する。
2. pythonの仮想環境を作成する。
3. 作成した仮想環境の中でもpipでJupyter Notebookをインストールする。
4. VS Codeの環境に作成した仮想環境を指定する

### anacondaでpythonをインストールした環境の場合
anacondaでpythonをインストールした場合、vscodeで仮想環境のJupyter Notebookを起動させると以下のエラーになる。

```
The kernel failed to start as a dll could not be loaded.  View Jupyter [log](command:jupyter.viewOutput) for further details.
```

logに出力されるエラーの詳細

```
ImportError: DLL load failed while importing _sqlite3: 指定されたモジュールが見つかりません。\r\n'
```
sqlite3.dllが見つけられないと記載されている。


**エラーを解消する方法**
https://teratail.com/questions/371240
sqlite3.dllが見つけられないと記載されているが、anacondaの以下のpathにsqlite3.dllは既に用意されている。
` C:\Users\user\anaconda3\Library\bin`
このpathを環境変数に追加すれば解決する。

1. 環境変数のpathにC:\Users\user\anaconda3\Library\bin を追加する。（ユーザ名は各自置き換える）
2. そのあと、Vscodeを再起動することで認識するようになる。
【Lighthouse】Buttons do not have an accessible nameが出た時の解決策

# 事象
Lighthouse Accessibilityで```Buttons do not have an accessible name```が出た時の対処法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651106/c57b33ea-bbfd-6f1b-93f3-9d6bd0be205c.png)

# 解決策
指摘を受けた要素にaria-label属性追加で解決

**改善前**

```html
<button type="submit">検索</button>
```

**改善後**

```html
<button type="submit" aria-label="検索する">検索</button>
```

### aria-label属性とは？

>aria-label によって、アクセス可能なラベルに使用する文字列を指定できます。これは label 要素など、その他のネイティブのラベル付けの仕組みよりも優先されます。たとえば、button にテキストコンテンツと aria-label の両方が存在する場合、aria-label の値のみが使用されます。
>テキストの代わりに画像だけで目的を示しているボタンがあるとします。この視覚的なマークを見ることができないユーザー向けに目的を明確に示したい場合、aria-label 属性を使用することがあります。

https://developers.google.com/web/fundamentals/accessibility/semantics-aria/aria-labels-and-relationships?hl=ja

## 参考記事

https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
React チュートリアル　パート3　（useStateフック）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/ffad38b6-392f-aba1-4806-b6f00f1b5dcb.png)

#目標:military_medal:
ReactJsの新機能、**”useState( )フック”**を使ってみましょう:bangbang:

#App.jsに記述
下記の様に記述します！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/1cd87921-e815-9365-4b40-116c9403683b.png)

>【1行目】　**useState**をimportします

>【7行目】　countというstateを設定します。これで、countを自由自在に変更させることができます！

>【13行目】　**{count}**は、ブラウザに表示させるための記述になります。このように変数を表示させるためには、**｛｝**で囲みます。

>【16行目】　buttonをクリックすると、countが**１増加**する機能をつけています。

>【21行目】　buttonをクリックすると、countが**０**にする機能をつけています。

#動きをみてみましょう:fire::fire:


![2022-01-15_21h59_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3e215e5c-f4b1-52de-f2d9-2dd085817c6c.gif)

たったこれだけの記述で簡単に、機能を実装することができました:bangbang:

#次回:bell:
:white_check_mark: useEffect()を使います:bangbang:

#参考

https://ja.reactjs.org/docs/hooks-state.html
PHPで数値をアルファベットに変換するchr関数とord関数

#PHPで数値をアルファベットに変換する方法

先日、PHPを勉強していてchr()関数とord()関数で、はまってしまったのでまとめておきます。
##chr()関数とは

>この関数は、ASCII, ISO-8859, Windows1252のようなシングルバイトエンコーディング においては、文字セットのマッピングテーブルにある望みの文字の位置を渡すことで、一文字の文字列を作り出すのに使えます。しかし、この関数は stringのエンコーディングについて知りませんし、特にUTF-8やUTF-16のようなマルチバイトエンコーディングについては、この関数にUnicodeのコードポイントは渡せないことに注意してください。

つまり、シングルバイトエンコーディングに登録されている文字セットを、ユーザによって指定されたINT型の数値によって、対応している文字列（英数字か記号のみ）を返す関数であるといえます。
###ASCII（アスキーコード）とは
コンピュータは０か１かの２進数でしか認識できません。もちろん、ユーザは文字を扱う為それではコンピュータとやりとりができません。そこで、文字をコンピュータが認識できるように文字と２進数を対応付けさせ、登録させたのがASCII、文字コードの一種で、英数字と記号であるといえます。


では、指定した数値に応じて英数字に変換する関数をつくっていきましょう。

```php:main.php
<?php

function changeNumberToAlphabet(int $number)
{
  return chr($number);
}

$number = changeNumberToAlphabet(65);
echo $number;
//結果A


//返り値を大文字英数字に指定する場合65~90(A〜Z)
 echo chr(65);
 echo chr(66);
 echo chr(67);
//結果　A
//結果　B
//結果　C

//返り値を小文字英数字に指定する場合97~122(a~z)
 echo chr(97);
 echo chr(98);
 echo chr(99);
//結果a
//結果b
//結果c
?>
```

ASCIIコードによって登録されている英数字が大文字（65~90）、小文字（97~122）が指定された数値によって参照し、変換されます。

ただ、chr(65) == Aではなく、指定した数値を任意の結果にしたい、という場合もあるでしょう。例えば、chr(1) == Aのような場合です。その場合は、以下のように指定してすることで、思うような結果になります。

```php:main.php
<?php
 function changeNumberToAlphabet(int $number)
{
  return chr(ord('A') + $number - 1);
   //chr(65 + $number - 1) と同義
}
 changeNumberToAlphabet(1);
 //結果 A
?>
```

上記の例で、ord('A')の部分ですが、chr()が数値を英数字に変換する関数であれば、ord()関数は、英数字を数値に変換する関数です。

##ord()関数とは
>string が ASCII, ISO-8859, Windows 1252 のような シングルバイトエンコーディング だった場合、 これは文字セットのマッピングテーブルにある文字の位置を返すことと同義です。 しかし、この関数はstring のエンコーディングについて知りませんし、 特に UTF-8 や UTF-16 のようなマルチバイトエンコーディングについては、 この関数からは Unicode のコードポイントは絶対にわからないことに注意してください。
この関数は chr() と逆の動作をします。



先程は、数値を英数字に変換する関数でしたが、次は英数字を数値に変換する関数をつくっていきましょう。

```php:main.php
<?php
 function changeNumberAlphabet(string $alhabet): int
{
  return ord($alhabet) - ord('A') + 1;
  //$alhabet - 65 + 1 と同義
}
$number = changeNumberAlphabet('B');
echo $number;
//結果 2
?>
```
##まとめ
chr関数とは、ASCIIによって登録されている文字セットを、数値からアルファベットに変換する関数であること。
ord関数とは、その逆でアルファベットを数値に変換する関数であること。
React チュートリアル　パート2　（Hello World）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/9b11481b-09c6-9c5b-1122-a3eaa729d08c.png)

#目標:military_medal:
それでは、アプリケーションい**”Hello World”**を表示させましょう！

#App.jsに記述
**src**フォルダにある、App.jsファイルを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/d512738d-02c0-dcea-487e-cf400bba9659.png)

>①**header**タグを削除します。

>②１行目の**import logo from './logo.svg';**も削除

>③**h1**タグを追加して、Hello Worldと記述。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/850a7aad-0fc9-8c60-d9c3-988161d27d08.png)

#Hello World が表示されます:bangbang:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/654a87ce-e89f-3261-f0d1-eb0ea429ea35.png)

**jsファイル**なのですが、**HTML**と同じようなに記述することができるんですね！
これも、ReactJSの特徴の一つです。

#次回:bell:
:white_check_mark: 早速、ReactJSの**新機能フック**を使って簡単な、アプリケーションを作ってみます！

次回までに、下記の拡張機能のイントールをお願いします！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3be8a18d-0f83-e88b-6bb3-671ce45b422d.png)


#参考

https://ja.reactjs.org/
Emacsのアンインストールが上手くいかないとき

## 環境
- Windws10 
- WSL2 
- Ubuntu 20.04.3 LTS

## 問題
<!-- 
[Doom Emacsのリポジトリ](https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#on-windows)を参考にDoom Emacsをインストールしようとすると
`Doom only supports Emacs 27.1 and newer.`
と表示された。
-->

`sudo apt-get remove emacs`を実行しても`emacs -version`を実行すると`Emacs 26`などと表示される。

## 解決
```bash
sudo apt-get remove emacs*
```
を実行する

<!-- 
## 実行したものの全体
```bash
# emacs関連をすべて削除
sudo apt-get remove emacs*
# これは関係あるか不明
sudo apt autoremove

# Readmeの通りに
sudo apt update && sudo apt upgrade

sudo add-apt-repository ppa:kelleyk/emacs
sudo apt update
sudo apt install emacs27

sudo apt-get install git ripgrep
sudo apt-get install fd-find

git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
~/.emacs.d/bin/doom install
```

## 追加情報
https://github.com/kelleyk/ppa-emacs/issues/16 によると

```bash
sudo apt-get -o Dpkg::Options::="--force-overwrite" install emacs27-common
```
で競合ファイルを上書きできるそうだが、自分の環境では効果がなかった。 
-->
IE11サポート終了に備え、IE11を無効にしてみた

6月にIE11サポートが終了する。
いまは標準ブラウザをChromiumEdgeにして、社内システムはEnterprise Site List Managerを使ってIE11起動するようにしている。

ただ、6月のサポート終了後にどういった挙動となるのか確認したく、自身のPCでIE11を無効にしてみた。

#IE11を無効にする方法
ローカルポリシーをいじって無効にするわけだけど、前提として下記Windows更新プログラムのインストールが必要。じゃないと無効化する設定が出てこない。

　Windows 10バージョン 21H1 以降
　Windows 10バージョン 2004
　Windows 10バージョン 1909 KB4598298以降

gpeditを開き、コンピュータの構成->管理用テンプレート->Internet Explorer->Internet Explorer 11をスタンドアロンブラウザーとして無効にするを有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492453/fb93f076-0c4b-316e-75c7-314a67fdc19c.png)

マイクロソフトに確認したところ、6月のIE11無効化後の挙動は、上記を有効に設定したときとほぼ同様な動作となること。社内システムの検証が必要な人はお試しあれ。
AWS Cloud Practitioner Essential まとめ2

# [AWS Cloud Practitiner Essential] (https://explore.skillbuilder.aws/learn/course/1875/play/27620/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-shi-xie-ban) 殴りがき

### AWSグローバルインフラストラクチャ

- 世界中でリージョンを構築
- リージョンとは、データセンターがある地域のこと
- 各リージョンには複数のデータセンターがある
- 1つのリージョン内のデータセンターのグループをAZ(アベイラビリティーゾーン)と呼ぶ


#### リージョン
地理的に分離された場所

リージョンを選択する上での要素

1. コンプライアンス -> どうしてもこのリージョンでないとコンプライアンスが守れない。。
1. 近接性 -> 遠くのリージョンにアクセスしようとするとかかる時間は増える
1. 利用可能な機能 -> AWSの新サービスは、それぞれのリージョンに適用するのに時間がかかるため、まずは1つのリージョンでサービスを開始している可能性がある。将来的には、全てのリージョンで使えるようになると考えられるが、今すぐに使いたいサービスがそのリージョンにあるとは限らない。(基本的には大丈夫)
1. 料金 -> リージョンによっては、同じことを実現するのにかかるお金が異なることがある 

#### アベイラビリティゾーン

- アベイラビリティゾーンでデータセンターを分けることにより、EC2などを物理的に1つのサーバーに置かないようにする。
    - これにより、災害時にEC2のサーバーの一つが不能になっても、同じリージョンの異なるアベイラビリティーゾーンのサーバー上のEC2を起動し続けることができる。
- 2つのリージョンを選択した際は、インスタンスは同期的に実行される。
- ELBはリージョンレベルで設置される = 異なるAZに対してリクエストを振り分けることが可能。
- インスタンスは同期されており、同じ環境として使えるため、どのAZのインスタンスにリクエストが割り振られても処理は変わらない。

#### ベストプラクティス

一つのリージョンを選択した際に2つ以上のアベイラビリティゾーンでインスタンスを実行する


### エッジロケーション
<b>コンテンツのコピーをキャッシュして、任意の場所のユーザーに素早く配信するための場所</b>

各国のユーザーのリクエストを低レイテンシーかつ高速でレスポンスする。
顧客の近くにリージョンが存在しない場合、わざわざ選択したリージョンにリクエストを送る訳ではなく、キャッシュやコピーをその地域におく。


#### Amazon Cloud Front

世界中のさまざまなリージョンからCloud Frontにコンテンツをプッシュしている。
キャッシュをここで保持できるため、リージョン外のユーザーに素早くレスポンスできる。

#### Amazon Route53

DNS(ドメインネームサービス)
低レイテンシーでサービスを提供するために、リクエストを適切にルーティングする


#### AWS Outposts

十分に機能するミニリージョンがインストールしてあり、会社オリジナルの物理サーバーに配置できる。
AWSが100%所有・運用するが、会社独自の物理サーバーに置くことができる。
自分の建物内でAWSサービスを使用したい場合に使う。

- <b>この体制をハイブリットクラウドアプローチと言う。</b>


###　AWSサービスを操作する方法

基本的には各サービスで提供されているAPIを叩く。APIを叩く方法は以下の方法がある。

- <b>AWSマネジメントコンソール</b> -> ブラウザベースでAWSサービスを操作できる
    - サービスの利用開始・サービスについての知見を増やすのに適する
    - テスト環境
    - AWS請求書の表示
    - モニタリングの表示
    - 非技術リソースで作業する
- <b>AWS CLI(コマンドラインインターフェース)</b>　-> コマンドラインを使ってAPIを叩く
    - 手動での操作ミスがなくなる　 & 繰り返し実行できる 
    - Windows, Mac, Linuxが使える
- <b>AWS SDK(ソフトウェア開発キット)</b>　-> プログラミング言語を使用して、ソースコード単位でリソースを操作できる
    - サービスに埋め込むことができる。

※　マネジメントコンソール・CLI,SDKは操作と管理を自分で行う方法。


- AWS Elastic Beanstalk
    - アプリケーションコードと必要な設定をAWS Elastic Beanstalkに提供すると、環境が自動で構築される。
    - 全ての要素を個別で操作・管理する必要はない
    - これによって、インフラ構築などに注力せず、オリジナルサービスの開発に集中できる。
    
    - 以下のタスクを実行に必要なリソースが自動デプロイされる
        1. キャパシティーの調査
        1. 負荷分散
        1. 自動スケーリング
        1. アプリケーションの状態のモニタリング 
    
- AWS Cloud Formation
    - IaCのツール
        - Json or Yamlベースの記述により、様々なインフラを定義できる
    - 複数のリージョンに複数の全く同じ環境を構築できる
React+Typescriptでのbuildエラー（create-react-app）

## エラー内容
create-react-appで作成したTypescriptプロジェクト[^1]をnpm run buildするとエラー

```
TypeError: MiniCssExtractPlugin is not a constructor
```

## 原因
mini-css-extract-plugin がバージョン2.5.0にアップデートされたことでのエラー

## 解決方法
mini-css-extract-plugin　のバージョンダウン

```
npm i -D --save-exact mini-css-extract-plugin@2.4.5
```

## 参考URL
https://github.com/facebook/create-react-app/issues/11930


[^1]: npx create-react-app プロジェクト名 --template typescript
React チュートリアル　パート１　（create-react-app）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/cf50ed34-39de-19ac-0f3a-6bb21525a571.png)


#目標:military_medal:
###ReactJSを使って簡単なWEBアプリケーションを作っていきます！

#:fire:Getting Started:fire:
**Create React App**とは、Reactアプリケーションを作るための一般的な方法です。

#:fire:Quick Start:fire:
コマンドを使って、**”npx create-react-app my-app“**を入力します！

#ディレクトリ構造
インストールが終了すると、下記のファイルが作られます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/89684543-5efe-3beb-7b2f-5d07bd40528d.png)


#"npm start"でプリケーションを起動
VScodeのターミナルを開いて、
**”npm start”**と入力すると、**localhost:3000**にアプリケーションが起動します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/b101fe5d-8743-19d3-740b-4f2bab036ddc.png)

URLを確認するとlocalhost:3000になっていますね！
これで、アプリケーションの起動しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3547eddd-ecd6-8efd-9316-8229dd7d3d60.png)

###とても簡単にアプリケーションを起動することができましたね:blush:

#次回:bell:
:white_check_mark:　次回は、Hello World を表示させます！

#参考
:ledger: **Create React Appについて**　


https://create-react-app.dev/docs/getting-started
Windows 10でネットワークに接続されるのが遅い、インターネットアクセスなしとなる

#Windows10端末で、インターネットアクセスなしが表示されるようになった
ある日から、会社のPCが社内ネットワークに接続されるまでに時間がかかるようになった。
有線LANや無線LANの設定が正しいのにも関わらず、ネットワークアイコンが「インターネットアクセスなし」となってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492453/b04f53c5-1d47-f604-c80e-43089323b352.png)

また、人によっては無線LAN圏外エリアから圏内エリアへ戻ってきた際、Outlookで下記のような接続エラーが発生してしまうようだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492453/e451078d-7092-6017-dc7c-e0ffd26eea00.png)

調べてみるとWin10 Version 1903、1909、2004、20H2をプロキシ配下で利用している場合に発生する問題のようだ。
そういえば最近20H2を配布してたわ。

#原因
Windowsがインターネット接続有無を検出する機能の事をNCISと呼ぶらしいのだが、これがプロキシ配下でうまく動作しなくなったことが原因。

#解決方法
**その1 レジストを変更する**
キー：HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkConnectivityStatusIndicator
名前：UseGlobalDns
値：1
種類：DWORD

グループポリシーで配布する場合は下記を設定。
コンピューターの構成 > 管理用テンプレート > ネットワーク > ネットワーク接続状態インジケーター > グローバル DNS の指定
設定値：有効
グローバルDNSを使用する：チェック

**その2 プロキシで下記URLをホワイトリストに登録する**
レジストリの変更でも改善しない場合は、下記URLがプロキシでブロックされている可能性があるので、ホワイトリストに登録する。
Windows 10 Version 1607 以降 :
IPv4 の場合 : http://www.msftconnecttest.com/connecttest.txt
IPv6 の場合 : http://ipv6.msftconnecttest.com/connecttest.txt

Windows 10 Version 1511 以前 :
IPv4 の場合 : http://www.msftncsi.com/ncsi.txt
IPv6 の場合 : http://ipv6.msftncsi.com/ncsi.txt

#NCISの状態を確認
NCISがインターネット接続状態はPowerShellのGet-NetConnectionProfileで確認ができる。
ConnectivityがNoTrafficやLocalNetworkとなっている場合、インターネットアクセスなしと判定される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2492453/00d7d0e5-1ec8-a310-b2da-6d44a6f4de2a.png)

#参考
https://jpwinsup.github.io/blog/2021/09/30/Networking/NCSI/network-connectivity-status-indicator-overview-and-troubleshooting-guide/
SeleniumでDeepL翻訳

# はじめに
<!-- 発端や概要を記載 -->
DeepL( https://www.deepl.com/ja/translator) での翻訳を、Seleniumを用いて行います。

例として、ニューサイトから取得した記事（ https://news.google.com/rss?hl=en-US&gl=US&ceid=US:en ）のタイトルの英語の翻訳を行っていきます。前回の記事の続きのような内容ですので、スクレイピング部分は、下の記事を参照してください。

前回の記事：[ニュース記事をスクレイピング](https://qiita.com/babmuclr/items/64a8833bfe7a7e32f09e)

# 目次
<!-- タイトルとアンカー名を編集 -->
1. 翻訳の全体像
1. 翻訳を行うコード
1. 参考文献

<!-- 各チャプター -->
# 翻訳の全体像
Seleniumを用いてDeepL翻訳を行います。Seleniumのインストールは、下の記事などを参考にしてください。
参考：　[10分で理解する Selenium - Qiita](https://qiita.com/Chanmoro/items/9a3c86bb465c1cce738a)

DeepLのページをSeleniumを用いて、操作します。DeepLのページに行き、一旦、好きな言葉を翻訳してみてください。私は、前回の記事でとってきた、記事のタイトルを入れてみます。

<img width="500px" alt="DeepLページ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416886/ca06f669-f4e1-4e8a-3c6a-315c40c6bc1b.png">

うまく翻訳ができています。ここで注目すべきは、この時のURLです。

```
https://www.deepl.com/ja/translator#en/ja/Biden%20says%20he's%20%22not%20sure%22%20about%20voting%20bills'%20future%20after%20Sinema%20reiterates%20opposition%20to%20rule%20change%20-%20CBS%20News
```

元々のURLは、https://www.deepl.com/ja/translator でした。
つまり、元のURL　＋　#翻訳前の言語/翻訳語の言語/翻訳したい内容　になっていることがわかります。しかし、翻訳したい内容は、%20などの余分な文字が追加されています。

ですので、今回の操作の流れは、次のように表せます。

1. Google Chromeを立ち上げる
2. 翻訳したい内容を含めたURLにアクセス
3. 翻訳したデータを取得する

# 翻訳を行うコード
翻訳を行うには、ChromeDriverが必要です。ダウンロードはこちらで行えます。
(→ https://chromedriver.chromium.org/downloads )

下のコードは、英語の"Biden says he's "not sure" about voting bills' future after Sinema reiterates opposition to rule change - CBS News"を日本語に翻訳するコードです。

```python:translate.py
import time
import urllib.parse
import lxml
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# text = 翻訳したい文章
text = "Biden says he's "not sure" about voting bills' future after Sinema reiterates opposition to rule change - CBS News"
text = urllib.parse.quote(text)
#　URL作成
from_lang = 'en'
to_lang = 'ja'
url = 'https://www.deepl.com/translator#' + from_lang +'/' + to_lang + '/' + text
     
#　ヘッドレスモードでブラウザを起動
options = Options()
options.add_argument('--headless')
     
# ブラウザーを起動
DRIVER_PATH = "./chromedriver" # 自分のchromedriverまでのパス
driver = webdriver.Chrome(DRIVER_PATH, options=options)
driver.get(url)
driver.implicitly_wait(30)  # 見つからないときは、30秒まで待つ

# DeepLの翻訳部分
sleep_time = 10
try_max_count = 30
for i in range(try_max_count):
    # 指定時間待つ
    time.sleep(sleep_time)  
    html = driver.page_source
    soup = BeautifulSoup(html, features='lxml')
    target_elem = soup.find(class_="lmt__translations_as_text__text_btn")
    translated_text = target_elem.text
    # DeepLの翻訳が終わっている確認
    if translated_text:
        break
             
# ブラウザ停止
driver.quit()
```

# 参考文献
- [前回記事](https://qiita.com/babmuclr/items/64a8833bfe7a7e32f09e)
- [ニュースサイト](https://news.google.com/rss?hl=en-US&gl=US&ceid=US:en)
discord.pyで元の型のままコマンド引数を受け取る方法

#環境
```
discord.py
discord==1.0.1
discord.py==1.7.3
python 3.9
```
#問題点
discord.pyでは書き込みの引数は基本的に文字列にて受け取ります。
メンションやチャンネルの指定が含まれていたとしても、文字列です。

例:

```python:test.py
# 色々と省略していますが核心部分だけ載せます
from discord.ext import commands
import discord

bot = commands.Bot(command_prefix=commands.when_mentioned_or("-"))

class TestCommand(commands.Cog):
    def __init__(self, bot):
        super().__init__()
        self.bot = bot

    @commands.command()
    async def test(self,ctx,*args):
        if args:
            for arg in args:
                await ctx.send(f'f'型:{type(arg)},書き込み内容{arg}')

bot.add_cog(TestCommand(bot=bot))
bot run ('TOKEN')
```

discord で`-test あ　@G1998G #メイン`と書き込み

結果:

```console
型:str 書き込み内容:あ
型:str 書き込み内容:<!@827807856151796490> 
型:str 書き込み内容:<!#531806456891676162>
```

型は **文字列**、テキスト内容は **謎の暗号（member idを<!@>で囲ったもの）**となってしまいます。
私が受け取りたいのは下記の様な情報です。

```
型:discord.Member 書き込み内容:<Member id=827807856151796490 name='G1998G' discriminator='8843' bot=Fales nick=None guild=<Guild id=713393468499820644 name='テストギルド' shard_id=None chunked=True member_count=34>>,
```
文字列ではなく、上記の様に例えばdiscord.Member型で受け取る事ができれば、何かと便利です。
`arg.member.id`など、discord.Member型に使用できる関数や変数をそのまま使用できます。
文字列で受け取ると、一旦`<!@`と`>`を正規表現で削除して、残ったidから必要情報を抽出したりなど面倒です。
特にchannel historyを使用して過去の大量のメッセージを取得した際、もしくは`*arg`として可変長とした場合は非常に非効率になります。

#解決方法

discord.pyではコンバーターという機能が備わっています。
型指定の形で、文字列ではなく特定の型が温存されたまま受け取ることができます。
**ただしこちらには色々と不便があります。**
🔻下記URLを参照
https://discordpy.readthedocs.io/ja/latest/ext/commands/api.html#converters
一番柔軟に設定できるコンバーターを使用しても、**合致しない型の引数が渡されたらその引数を無かった事にしてしまったり**、
可変長で複数の引数を受け取った場合は **最初に合致した引数以外は全て文字列** としてしまいます。
そこで、Discord.pyのコンバーターに頼る事なく,**Typing Union**を使う方法を編み出しました。

```python:test.py
# 色々と省略していますが核心部分だけ載せます
from discord.ext import commands
import discord
from typing import Union

bot = commands.Bot(command_prefix=commands.when_mentioned_or("-"))

class TestCommand(commands.Cog):
    def __init__(self, bot):
        super().__init__()
        self.bot = bot

    @commands.command()
    # ここに注目🔻
    async def test(self,ctx,*args: Union[discord.TextChannel, discord.Member,int,str]):
        if args:
            for arg in args:
                await ctx.send(f'f'型:{type(arg)},書き込み内容{arg}')

bot.add_cog(TestCommand(bot=bot))
bot run ('TOKEN')
```

discord で`-test あ　　@G1998G #メイン`と書き込み

結果:

```console
型:str 書き込み内容:あ
型:discord.Member 書き込み内容:<Member id=827807856151796490 name='G1998G' discriminator='8843' bot=Fales nick=None guild=<Guild id=713393468499820644 name='テストギルド' shard_id=None chunked=True member_count=34>>
型:discord.Channel 書き込み内容:TextChannel id=531806456891676162 name='メイン' position=3 nsfw=False news=False category_id=714393448499820648>
```

きちんと書き込み時の型を取得してくれました。
[LaTeX][Manjaro Linux]latexindentコマンドが動かないときの対処法

# 依存モジュールがインストールされていないためlatexindentが動かない

Manjaro LinuxにTeX Liveを入れ、LaTeX文書を書いています。  
TeX Liveをインストールすると、LaTeXのフォーマッターである`latexindent`コマンドも同時にインストールされます。  
しかし、次のようなエラーが出てそのままでは動かない場合があります。

```terminal
Can't locate YAML/Tiny.pm in @INC (you may need to install the YAML::Tiny module) (@INC contains: /usr/local/texlive/2021/texmf-dist/scripts/latexindent /usr/lib/perl5/5.34/site_perl /usr/share/perl5/site_perl /usr/lib/perl5/5.34/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5/5.34/core_perl /usr/share/perl5/core_perl) at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm line 21.
BEGIN failed--compilation aborted at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm line 21.
Compilation failed in require at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm line 22.
BEGIN failed--compilation aborted at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Verbatim.pm line 22.
Compilation failed in require at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm line 22.
BEGIN failed--compilation aborted at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Lines.pm line 22.
Compilation failed in require at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Document.pm line 28.
BEGIN failed--compilation aborted at /usr/local/texlive/2021/texmf-dist/scripts/latexindent/LatexIndent/Document.pm line 28.
Compilation failed in require at /usr/local/texlive/2021/bin/x86_64-linux/latexindent line 27.
BEGIN failed--compilation aborted at /usr/local/texlive/2021/bin/x86_64-linux/latexindent line 27.
```

# pacmanを使って依存モジュールを一つひとつインストールする

以前、Fedoraでも同じような状況に陥って[似たような記事](https://qiita.com/YuukiToriyama/items/10a3458b3d66dc0fdfc0)を書きましたが、要はエラーで言われている足りていないモジュールをインストールしてやれば動くと思います。

私の環境では`YAML::Tiny`と`File::HomeDir`、`Unicode::GCString`が足らなかったので次のようにしました。

```bash
sudo pacman -S perl-yaml-tiny perl-file-homedir perl-unicode-linebreak
```
MapLibre GL JSがv2.0.0になりました

## 日本語テキストを表示する必要がある場合の注意

- <b>v2.1.7で日本語フォントのレンダリングの問題が解消されました！</b>

- v2.1.6に日本語フォントのレンダリング位置ズレの問題があり、修正済みですがまだリリースされていません[#1002](https://github.com/maplibre/maplibre-gl-js/issues/1002)。v2.1.7以降のリリースを待ちましょう

- v2.0.0からv2.1.1にかけて、日本語フォントのレンダリングにバグがあり一切表示されません。v2.1.2で修正される見込み(https://github.com/maplibre/maplibre-gl-js/issues/718)
- v1.15.2が、日本語フォントを表示出来る最新のバージョンです。日本語フォントが必要な場合は上記修正がリリースされるまではバージョンアップしないほうが賢明です

## はじめに

https://github.com/maplibre/maplibre-gl-js

昨年にプロプライエタリとなったMapbox GL JSのオープンソースフォークであるMapLibre GL JSのv2.0.0がリリースされました。これまでのアップデートは、Mapbox GL JS v1.13.0の機能を踏襲したマイナーアップデートが主でしたが、v2.0.0を迎え、本格的に機能が枝分かれしてきたので、これまでのアップデートによる変更点を紹介します。筆者の主観で、実用上大きな変更点だと思った箇所を列挙していきます。

## チェンジログ

https://github.com/maplibre/maplibre-gl-js/blob/main/CHANGELOG.md

v2.0.0より前は互換性が維持されていましたが、v2で多くの破壊的変更がありました。

## TypeScriptで書き直された

Mapbox GL JSはFlowによる型付けで、これは依然として変わっていません。フォーク後、割と早期にリライトが始まっていたと思います。使用者目線では、DefinitelyTypedから型定義持ってくる必要がなくなってうれしいですね。

### 型名の変更

TypeScriptで書き直された直後は型名はDefinetelyTypedに準拠していましたが、v2.0.0で型名が変わりました。

```
Style => StyleSpecification
AnyLayer => LayerSpecification
AnySourceData => SourceSpecification
MapboxEvent => MapLibreEvent
MapboxOptions => MapOptions
MapBoxZoomEvent => MapLibreZoomEvent
*SourceRaw + *SourceOptions => *SourceSpecification
*Source (source implementation definition) were removed
*Layer => *LayerSpecification
*Paint => *LayerSpecification['paint']
*Layout => *LayerSpecification['layout']
MapboxGeoJSONFeature => GeoJSONFeature
```

## 地図を60度以上に傾けられるようになった

Mapbox GL JSからのフォーク時には、地図の傾き（pitch）は60度が上限でした。この上限が85度になりました。わりとうれしい。

![スクリーンショット 2022-01-15 19.33.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/33722b4e-a0d7-d7b3-bc15-d7d4fd2a19bd.png)

## Mapbox-APIへの依存がなくなった

Mapbox GL JSでは、styleのURL指定において、`mapbox://`というprefixがMapbox-APIに関する特別な意味を持っており、`mapboxToken`を用いて認証していましたが、この仕様が削除されました。Mapbox-APIを使うならMapbox GL JSを使うでしょうから、困る人はいないでしょう。

> OSSとマネタイズの関係は色々考えさせられます

## TypeScriptによる実装例

```html
<div id="map" style="height: 100vh"></div>
```

```typescript

import { Map, StyleSpecification } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

const style: StyleSpecification = {
    version: 8,
    sources: {
        OSM: {
            type: 'raster',
            tiles: ['http://tile.openstreetmap.org/{z}/{x}/{y}.png'],
            tileSize: 256,
            attribution:
                '<a href="http://osm.org/copyright">© OpenStreetMap contributors</a>',
        },
    },
    layers: [
        {
            id: 'OSM',
            type: 'raster',
            source: 'OSM',
            minzoom: 0,
            maxzoom: 18,
        },
    ],
};

const map = new Map({
    container: 'map',
    style,
    center: [140, 40],
    zoom: 5,
    maxPitch: 85, // デフォルト値は60
});


```

## 終わりに

v2.0.0となり、Mapboxとは違う方向への変化が本格化しそうです。AWSでもベクタータイルの配信が始まり、そのフロントエンドは[MapLibre GL JSの利用が想定されていたり](https://docs.aws.amazon.com/location/latest/developerguide/tutorial-maplibre-gl-js.html)、[おっきい会社さんのコミッターがいらっしゃるらしかったり](https://www.maptiler.com/news/2021/06/maplibre-gl-native-open-source-mobile-sdk-for-android-and-ios/)、今後も安定したメンテナンスが期待されます。
ITパスポートを受けました

タイトルの通り受けてきたので、今までの過程をまとめてみました。

##受けるきっかけ

* ITについて知識を深めたいと思った
情報システム部門の所属ではないのですが、業務でシステムの知識が必要になることがありまして。「○○って何？」「××の役割は？」と知らないことが多く、これは勉強したほうがいいなと思いました。
勉強するには資格取得がよさそうと思って、IT系の資格を調査。資格の中でもITパスポートが取得しやすそうだったので決めました。

* 会社から報奨金が出る<font color="Red">**(これ重要)**</font>
一部の資格では、取得すると会社から報奨金が出る仕組みになっています。ITパスポートも該当していたので、これは受けるしかないと。
やっぱり何か貰えるとなると、モチベーション上がりますよね。

##勉強について
勉強期間・・・1か月半
1日の勉強時間・・・30分~1時間

まとめてがっつりではなく、通勤時間などちょこちょこ空き時間にやるスタイルでした。


###具体的な方法
利用した教材は以下の2つ。

◆改訂版 この1冊で合格! 丸山紀代のITパスポート テキスト&問題集 (丸山紀代 著)
◆[ITパスポート過去問道場](https://www.itpassportsiken.com/ipkakomon.php)

<dl>
  <dt>1か月半~1か月前</dt>
  <dd>本を購入。全体をパラパラ見て、どのようなものかを軽く確認する。</dd>
  <dt>1か月～1週間前</dt>
  <dd>本で各項目を学んだあと、確認テストで理解しているかどうか確認。これを2周ぐらいやった。それと合わせて過去問道場でも問題を解く。間違えたものにはチェックを入れて復習。</dd>
  <dt>1週間前~前日</dt>
  <dd>過去問道場を使い、模擬試験形式で問題を解く。直近5回分ぐらい実施した。</dd>
  <dt>当日(試験前)</dt>
  <dd>本を最後まで軽く見直す。</dd>
</dl>

##結果
無事に合格しました。テクノロジ系が他の2つに比べて、やや低いかなという印象です。

![スクリーンショット 2022-01-15 181612.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/0c2ceb92-e3d2-3ac0-4f92-619a6136fa48.jpeg)

##受けてみた感想
* 過去問より本番の方が難しく感じた
CBT形式で受けたのですが、あまり見慣れない問題が最初に出てきて焦りました。なんとなく覚えただけだと、答えられない問題もあります。

* 網羅的に学べた(IT以外も)
IT関連の知識を学ぶために勉強していたのですが、マネジメントの話など会社経営に関する内容も多かったです。何かに特化して勉強するのではなく、基礎でもいいから幅広く学びたい場合には向いているなと思いました。

##まとめ
人によって勉強スタイルや時間は違うと思いますが、1つの参考になればと。
とにかく無事に取得出来てよかったです。
im2colの実装で出てくる式をわかりやすく視覚化してみます

有名な[「ゼロから作るDL」](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585/ref=pd_lpo_2?pd_rd_i=4873117585&psc=1)🐟 第7章に出てくる"im2col"。

im2colの定義式について問う問題が、某E資格対策講座の教材で出題されましたので、
図に書いて自分用にメモを取りました。
「視覚的に、なんとなく」　わかってもらえたら幸いです。

[im２colのソースコードはどなたでも閲覧可能です。](https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/common/util.py)
リンク先githubの39〜68行目が該当します。

im2colの概要については、「ゼロつく」　やその他にお譲りします..。

今回はこのソースコード中の

**col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]**

という式 **だけ** に注目して、解説します！(せまい！)
一応、E資格講座の質問担当様にも、理解に間違いがないかチェックしていただきました。

この式、一見簡単そうに見えますが、よくよく見ると「？」　となるのはぼくだけでしょうか？

**1.**
まずは簡単のため、前提条件はこんな感じとします。
  4 × 4の画像がRGBの3チャンネルあるとします。
ストライドやフィルターの大きさは以下の通り。
pythonでは、例えば
"0:4:2"という表記は、「0列目から4列目まで、2つ飛ばしで」という意味です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/3d627b56-ba1f-6d4b-ed3f-80f1df28e3ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/f92b6467-9a52-77af-d7e6-1d050d8bff38.png)

**2.**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/71d9b568-35fe-e276-1257-89c58257e428.png)
**3.**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/39a7db22-9e57-f5e2-b935-33ce4035af63.png)
**4.**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/2b699008-537e-e9ea-06ef-0d38f570dd7d.png)
**5.**
col[:, :, y, x, :, :] = **img[:, :, y:y_max:stride, x:x_max:stride]**
の式の右辺の意味は、4.までで(**あくまでなんとなく**)ご理解いただけたかと思います。

では、この右辺＝左辺　とはどういうことか？　というと、、
(4つの図は、それぞれ右辺にあたるものが左側、
　　　　　　　　　　左辺にあたるものが右側  にあるのでご注意ください)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/233da06b-7584-8cbf-ec4e-c5cc266c3ccd.png)

以上が、
**col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]**
の視覚的な理解になります。

**おまけ**
なお、その次に続く、最後の式
**col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)**
は、詳細までは力尽きて視覚化できませんでしたが、
以下の図のような変換をしている式とのことです。
( (x,y)=(0,0) の時の例だけ載せています )
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605263/6e838209-2320-81be-2c45-7603635cf00f.png)
なんでこの式でこういう変換になるのか、途中を図示できる方はぜひぜひお願いします..
ぼくにはわからない..

おしまいです
【 Node-RED・GoogleSpreadSheetAPI・LINEBot 】で社内事業所の生産予定数と要員計画（欠勤状況）を確認したい

#■作成の経緯
社内の生産現場にとって各販社からの発注つまり生産予定に対する要員計画は非常に重要かつ困難である。東西の事業所それぞれで１日あたり数万パックを超える生産数、１００名を超える従業員を管理する必要がある管理者の負担を少しでも軽減したいと考え、まずその第一歩として当機能を作成しました。今回は状況を把握するだけの機能ですが、今後は欠勤者（閾値を設定）が多数発生した場合、休みの従業員（優先順位を設定）に出勤要請の通知を送信するなどの機能も追加していければと考えております。

#■苦労した点
Node-REDは初体験でしたので、ネットの見本を参考に見様見真似で作成してみました。ローコードプログラミング開発ツールは操作方法がある程度わからないと全く前へ進みません。やはり自分には合わないと改めて感じましたが、いい機会なので最低限の基礎知識は習得します。GoogleSpreadSheetは連携するまでの工程が多く面倒でした。

#■出力結果
![line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509701/94c4becc-c36b-093c-f7f1-3df4e4167a2d.png)

LINEに対象事業所部門をメッセージ送信すると本日の生産予定数、出勤者数、欠勤者数とその内訳を簡単に確認することができ、管理者はその状況に応じて要員計画の見直し（応援や配置変更）などを行います。

#■使用した機能
- **LINEBot**
- **Node-RED**
- **Google SpreadSheet API**
- **Google SpreadSheet**


#■Node-RED構成

![test3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509701/a1c315bb-d1c1-c130-cba9-a8bb37a9f4cd.png)

①【http in】LINEから送信されたメッセージを取得
②【function】受信したメッセージを保持
③【GSheet】Google SpreadSheet に登録された表形式の情報を読み込む
④【function】表形式の内容を送信用メッセージに編集
⑤【ReplyMessage】送信用メッセージをLINEに送信

#■③SpreadSheet（スプレッドシート）
![sp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509701/9f42f72d-d507-c705-45d1-1b805370f654.png)

こちらの情報についてすべて手登録は非効率ですので社内システムのバッチ処理で、備考は出勤している責任者のＩＮＰＵＴ、欠勤情報は各従業員のＩＮＰＵＴが必要となり、それらを集計し、さらにスプレッドシートに反映する処理を作成する必要があります。スプレッドシートの更新はPythonで可能なようなので今度やってみます。

#■④functionコーディング内容

```function:sample

const index = msg.payload.findIndex(rows => rows[0] == msg.line.events[0].message.text);

if (index != -1) {
  resultMessage = "■" +msg.payload[index][0] + "状況";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・生産予定数：" + msg.payload[index][1];
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・出勤者数：" + msg.payload[index][2] + " 名";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・生産終了予定時間：" + msg.payload[index][3];
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・本日の欠勤者数：" + msg.payload[index][4] + " 名";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・備考：" + msg.payload[index][5];
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "■" +msg.payload[index][0] + "欠勤者内訳";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・体調不良：" + msg.payload[index][7] + " 名";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・自然災害：" + msg.payload[index][8] + " 名";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・公共交通機関遅れ：" + msg.payload[index][9] + " 名";
  resultMessage = resultMessage + "\n";
  resultMessage = resultMessage + "・その他：" + msg.payload[index][10] + " 名";
}
msg.line.events[0].message.text = resultMessage;
msg.payload = msg.line;
return msg;
```

ローコードプログラミング開発ツールとはいえ、やはり多少のコーディングは必要となります:point_up_2:

#■所感と今後のシステム開発について
今回のローコードプログラミング開発ツールと今までの開発手法を両立させ、開発規模と要員に応じて使い分けるレベルになれば、非常に有益となります。
AppBarのleadingにTextを設定する方法

# 問題

AppBarのleadingにTextを設定すると、下記画像のように、ワーニングが出力される。

<img height="400" alt="AppBar_leading_text.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421601/454de32e-7867-fe35-91e0-4cf98c356ff5.png">

ワーニングの文面は、以下の通り。

```
BOTTOM OVERFLOWED BY * PIXELS
```

# 原因

AppBarのleadingは、デフォルトだとwidthが56。
Textの幅がそのwidthを超えているため、本ワーニングが出力される。

# 解決方法

AppBarのleadingWidthに、Text分の幅を考慮して、値を設定する。

```dart
  return AppBar(
    leadingWidth: 115,
```

# 参考

https://github.com/flutter/flutter/issues/21991#issuecomment-673142316

# サンプルコード

https://gist.github.com/taku-kw/d61346ba91d3c111a5d178f9874ab2f7
boiler's Graphics v5.5をリリースします

お世話になっております。
@dhq_boiler です。

Microsoft Storeでboiler's Graphicsのバージョン5.3.3を提供しております。記事の最後にダウンロードリンクを用意しております。

また、近日、現在絶賛開発中のboiler's Graphicsのバージョン5.5をリリースする予定です。v5.5で新しいツールが2つ実装されます。それはフリーハンドツールと扇形ツールです。

# 新機能

## フリーハンドツール

フリーハンドツールはドラッグでなめらかな曲線を描くことができます。ドラッグした軌跡がそのまま線になります。

![free_hand.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/9473a8ab-6d62-2be6-d26c-78a2c569f981.gif)

フリーハンドツールの特徴として、線で囲った領域のオブジェクトを生成することができます。線で囲った後、結合オプションのUnionを使います。

![free_hand_union_one_segment.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/8ac75706-b70d-4f6c-f81b-585dca1554b1.gif)

また、線と線を接続して、一つの閉領域オブジェクトを作ることも可能です。これも、線と線を接続した後、結合オプションのUnionを使います。

![free_hand_union_two_segments.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/a76731eb-aae4-0e0a-be4c-b869d4107485.gif)

## 扇形ツール

扇形ツールはわずか3ドラッグで扇形（扇子の形はバウムクーヘンの形など）を描画できます。最初のドラッグで扇形の中心点（ドラッグ開始点を基準）と開始角度と長い半径（ドラッグ終了点を基準）を決定します。2回目のドラッグで終了角度を決定します。3回目のドラッグで短い半径を決定します。

触ってみればわかるかと思いますが、このツールのおかげで扇形が簡単に描画できちゃいます。角度の補助表示もついているので、狙った扇形が作りやすいです。

![pie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/be4c0846-4d9b-c47b-e653-e9cc47edddd0.gif)

# インストール方法

Microsoft Storeで提供していますので気になる方はこちらのリンクからどうぞ。v5.5はそのうち利用可能になります。

<a href="https://www.microsoft.com/store/apps/9N288RJ615LM"><img src="https://github.com/dhq-boiler/boiler-s-Graphics/blob/b8e24331f4014784cc80896184433dab9080503a/WebComponents/Japanese_L.png?raw=true" width="150"></a>

# 次の次のバージョン

次の次のバージョン(v.5.6~)では、ミラーツールを実装しようかなと思っております。ミラーツールとは鏡をキャンパス上に設置することで、描画するオブジェクトのミラーオブジェクトを同時に描くことができる予定です。

# プロジェクト

https://github.com/dhq-boiler/boiler-s-Graphics
Reactでおみくじ作成(javascript版あり)

![画面収録-2022-01-15-18.53.24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509948/69945729-528f-09db-11c4-913ccd9b41a2.gif)
React自主トレ中です。
javascriptで作成したおみくじをReactで再現して同じ動作ができるようにします。

hooksは私が仕事してた頃は使ってなかったので
ゼロから調べました。

github
https://github.com/mhosokawa2021/omikuji_react

#まずはサクッとjavascript
```html:omikuji_js.html
    <p id="btn">おみくじを引く</p>
    <script>
        'use strict';
        var btn = document.getElementById('btn');

          btn.addEventListener('click', function () {
                var n = Math.ceil(Math.random() * 5);
                if (n == 1) {
                    this.textContent = '大吉';
                } else if (n == 2) {
                    this.textContent = '吉';
                } else if (n == 3) {
                    this.textContent = '中吉';
                } else if (n == 4) {
                    this.textContent = '小吉';
                } else if (n == 5) {
                    this.textContent = '凶';
                }
            });
            
    </script>
```
cssで少し見た目を整えます。

```css:omikuji_js.html
#btn{
      font-size: 13px;
      background-color: #ccc;
      cursor: pointer;
      text-align: center;
    }
```

#Reactで挙動を再現する　その１
とりあえず見た目だけ移植。

```js:index.js
  import ReactDOM from "react-dom";
  import { App } from "./App";

  ReactDOM.render(<App />, document.getElementById("root"));
```
```react:app.jsx
import React from "react";
import "./styles.css";

export const App = () => {
  return (
    <>
      <p className="btn">おみくじを引く</p>
    </>
  );
};
```
```css:style.css
.btn{
      font-size: 13px;
      background-color: #ccc;
      cursor: pointer;
      text-align: center;
    }
```
#Reactで挙動を再現する　その２

動きの部分の処理を追加していきます。
（jsxのみ更新したのでそこだけ）

```react:app.jsx
import React, { useState } from "react";
import "./styles.css";

export const App = () => {
  const [omikuji, setOmikuji] = useState("おみくじを引く");
  const onClickOmikuji = () => {
    var arr = ["大吉", "小吉", "中吉", "吉", "凶", "大凶"];
    var index = Math.floor(Math.random() * arr.length);
    setOmikuji(arr[index]);
  };
  return (
    <>
      <p className="btn" onClick={onClickOmikuji}>
        {omikuji}
      </p>
    </>
  );
};
```
できました。
![画面収録-2022-01-15-18.53.24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509948/9979ec42-79c3-820e-765a-968e953725ee.gif)

##参考
https://ja.reactjs.org/docs/hooks-reference.html

https://qiita.com/may88seiji/items/67b8ed01ad3101dded46

https://qiita.com/shogotgm/items/8e0dcf97ee25b043571d
Sophos XG Firewall home edition を構築してみる 設定編


## ブリッジモードで試したいため、
以下の方法で、設定する。インターフェースに接続してる、WANとLANの接続が間違っている場合があるので気を付ける。

* [Sophos XG Firewall をトランスペアレントモードで設定する：こっそりと。 - livedoor Blog](https://dynamic-one.com/archives/51721265.html)
* [Sophos XG Firewall: ブリッジの設定方法](https://support.sophos.com/support/s/article/KB-000035688?language=ja)

◇ポイント
* IPv4はStatic
* IPv6はDHCPにしたうえで、ゲートウェイアドレスは、手持ちのPCから取得して設定する。
* このブリッジペアでルーティングを有効化する
* ブリッジ作成後、再度WebUIに入り、DHCPの許可を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291673/11bb76d1-7ade-48c4-775a-6931e9e4b891.png)

## SSL/TLSインスペクションを試す。
https://yoshi0808.github.io/new-technology/2020/03/20/ssl-inspection1/
Googleスプレッドシートで２つのスプレッドシート間のコピペ(GASを用いる)

<h2>はじめに</h2>
アルバイトで２つのスプレッドシート間のコピペができれば、作業効率がアップすると考えたため、GASを使って試みる。

<h2>２つのスプレッドシートを読み込む</h2>

```
var s1 = SpreadsheetApp.openById("１枚目のシートのID");
var s2 = SpreadsheetApp.openById("２枚目のシートのID");
```

IDは"https://docs.google.com/spreadsheets/d/〇〇〇/edit#gid=0"
の〇〇〇の部分

<h2>それぞれのスプレッドシート内のシートを読み込む</h2>
それぞれのシートの名前を入れると読み込める。

```
 var ss1 = s1.getSheetByName("シート1");
 var ss2 = s2.getSheetByName("シート1");
```

<h2>１枚目のシートから２枚目のシートへセル内の値をコピペする。</h2>
１枚目のシートのセルA2の値を２枚目のシートセルB2にコピペする。
**ここで、getValues()の代わりにcopyToを用いようとしたところ、同じシート内（１枚目のスプレッドシート内の２つのシートなら可能）でないと使えないとのことだったので、getValues()を用いた。**

```
//１枚目から2枚目へのコピペ
  var range1 = "A2";
  let number = ss1.getRange(range1);
  let pes1 = ss2.getRange("B2");
  let values = number.getValues();
  pes1.setValues(values);
```
１枚目のカーソルのところが２枚目のカーソルのところにコピペされた。

![2022-01-15 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082132/3ee8b42a-e4d1-b736-f8d4-30aad991e5c2.png)

![2022-01-15 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082132/5d8d1959-4574-2ac2-09a6-c456421defac.png)