OmniAICreator/Qiita-1.07M huggingface dataset:
【競プロ典型90問】002をPythonで解説

# はじめに
最近競プロを始めたので，[競プロ典型90問][1]の★1~★3を解いて典型問題へのアプローチ方法を学んでいます．
公式のソースコードがC++で困っているPython勢の方も多いと思うので, 自分の解答をシェアしたいと思います！
初心者の解答なので，もっといい方法があれば教えていただけると嬉しいです！

# 002 Encyclopedia of Parentheses（★3）
https://atcoder.jp/contests/typical90/tasks/typical90_b

## 問題文
長さ $N$ の正しいカッコ列をすべて、辞書順に出力してください。
ただし、正しいカッコ列は次のように定義されています :

- `()` は正しいカッコ列である
- $S$ が正しいカッコ列であるとき、文字列 `(` $+S+$ `)` は正しいカッコ列である
- $S,T$ が正しいカッコ列であるとき、文字列 $S+T$ は正しいカッコ列である
- それ以外の文字列はすべて、正しいカッコ列でない

例えば、

- `()()`
- `(()())(())`
- `()()()()()()()()`

は正しいカッコ列ですが、

- `)(`
- `)))()(((`
- `((((a))))`

は正しいカッコ列ではありません。
また、 `(` の方が `)` よりも辞書順で早いものとします。

## 制約
- $1≤N≤20$
- $N$ は整数

# 解法
制約を見ると $N$ が極端に小さいので，全探索ができそうだと考えられます．さらに，正しいカッコ列に含まれるのは `(` と `)` の2種類だけなので，bit全探索を使えばよさそうだと気づくと思います．
すなわち，`(` または `)` を $N$ 個つなげてできるすべてのカッコ列に対して，それが正しいカッコ列かどうかを判定して条件を満たすものだけをリストに入れるようにします．
ここで，$N$ が奇数の場合については正しいカッコ列が存在しないことが明らかなので，これ以降は $N$ が偶数の場合のみを考えることにします．
判定の仕方については，`(` の個数と `)` の個数の差を記録するための変数 `cnt` を用意して，カッコ列の先頭から順に見ていき `(` であれば `cnt` を1増やし，`)` であれば1減らすことにします．
そして，最後に `cnt` を更新した時点で `cnt = 0` であれば正しいカッコ列であり，途中で `cnt < 0` になったり，最後に `cnt` を更新した時点で `cnt ≠ 0` になったりした場合は正しいカッコ列ではないということになります．
ここまでできれば，あとはリストを昇順にソートして出力することで辞書順に出力されます．
これによって，$O(N2^N)$ の計算量で解くことができます．

↓↓↓ bit全探索の解説はこの記事がわかりやすくてオススメです ↓↓↓

https://qiita.com/u2dayo/items/68e35815659b1041c3c2

# 実装
Pythonでbit全探索を行う際に使えるモジュールとして `itretools.product` があります．これは競プロをしているとよく使うモジュールだと思うので，使い方を覚えておくと良いと思います．
`itertools` には `product` 以外にも便利な関数が用意されているので，[公式リファレンス][2]を確認してみてください．

```Python: answer.py
from itertools import product
import sys
input = sys.stdin.readline


# 文字列sとその長さnを受け取って正しいカッコ列かどうかを判定する関数
def judge(s, n):
    cnt = 0
    for i in range(n):
        if p[i] == '(':
            cnt += 1
        else:
            if cnt > 0:
                cnt -= 1
            else:
                return False
    if cnt != 0:
        return False
    return True


N = int(input())
# Nが奇数の場合は正しいカッコ列は存在しないため考えない
if N % 2 == 0:
    ans = []
    # 長さNのカッコ列を全探索
    for p in product('()', repeat=N):
        if judge(p, N):
            # 正しいカッコ列の条件を満たしていればansに追加
            ans.append(p)
    # 辞書順にソート
    ans.sort()
    # 出力
    for i in range(len(ans)):
        print(*ans[i], sep='')

```

# さいごに
今回のように $N\leq20$ 程度であれば指数オーダーでも十分間に合うため，bit全探索を使うとうまくいく場合が多いと思います．
よく分からないことやコードの改善点などありましたら，気軽にコメントしてください．

最後までお付き合いいただきありがとうございました！

<!-- リンク集 -->
[1]: https://atcoder.jp/contests/typical90
[2]: https://docs.python.org/ja/3/library/itertools.html
npm のライブラリ（モジュール）のドキュメントを見るコマンド

探したけどそれっぽいものが見つからないので自前で。
Markdown を CLI で描画する手段を [glow](https://github.com/charmbracelet/glow) というコマンドに依存しているので、事前に brew install などして入れてください。入れたくない場合は glow を less などに置き換えてください。

.bashrc や .zshrc に下記を記述

```bash:.bashrc
nodedoc() {
    local readme_path
    if [ -d "node_modules/${1}" ]; then
        readme_path="node_modules/${1}/README.md"
    else
        readme_path="$(npm root -g)/${1}/README.md"
    fi
    glow -p "$readme_path";
}
```

## 使い方

```
nodedoc <package name>
```

## 使用例

```
nodedoc react
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200/93f6e626-004e-301c-d6eb-07e344e027d5.png)
リンク a要素

# 構文
```HTML:a要素
<a href="パス">コンテンツ名<a/>
```

# ページ内リンク
同一ページ内の指定の場所へのリンクをはりたい場合
```
<a href="#apple">りんご</a>
<h2 id="apple">りんご</h2>
```
idを指定することでページ内のリンクに飛ぶことができる
LINEアプリケーションをHerokuからAWSに移行しよう~準備編~

# はじめに

この記事はLINE API開発者のためのイベント、REV UP2022のハンズオンセッション「LINEアプリケーションをHerokuからAWSに移行しよう」の事前準備のための記事です。

https://revup.jp/session/aj9vx8bgy

# 準備するもの

## アカウント

このハンズオンでは以下のサービスのアカウントの準備が必要となっています。

- [LINE Developers](https://developers.line.biz)
- [Heroku](https://dashboard.heroku.com)
- [AWS](https://aws.amazon.com)

注意点として、ハンズオンで多少の金額が発生する可能性もあります。予めご了承ください。

## インストール

ここがすごく面倒なのですが、以下のサービスを予めインストールする必要がございます。

- 開発全体で用意してほしいもの
    - [vscode](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)などのエディタ
- LINEで必要なもの
    - [LINE Developers](https://developers.line.biz/) 
- Herokuで必要なもの
    - [git](https://git-scm.com/download)
    - [Heroku CLI](https://devcenter.heroku.com/ja/articles/heroku-cli#install-the-heroku-cli)
- AWSで必要なもの
    - [Docker](https://docs.docker.com/engine/install)
    - [AWS CLI](https://aws.amazon.com/jp/cli)
    - [AWS Copilot CLI](https://aws.github.io/copilot-cli/ja)

ちなみに今回は開発言語にはNode.jsを使います。アプリケーションはDockerで動かすので、ローカルの環境にはNode.jsをインストールする必要はありませんが、必要な方はインストールしてください。
私個人はWindowsでは[nvs](https://github.com/jasongin/nvs)、Macでは[nvm](https://github.com/nvm-sh/nvm)を使っています

# ひと手間いる作業

Herokuについては基本的に、公式サイトに書いている方法を参考にすれば簡単に初期のセットアップが完了しますが、AWSに関しては少々わかりにくいところがあるので面倒そうな作業内容を以下で解説します。

## IAMユーザーを作成

最初にAWSアカウントを作成したときに作られているのがrootユーザーと呼ばれるものです。
しかし基本的にはrootユーザーは使用せずに、IAMというサービスを使ってAWSでの開発を行うためのアカウントを作成します。
AWSのコンソール画面の検索欄で`IAM`と入力して該当のサービスにクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/d55b6fa2-2119-d133-6584-b1f96bc8fd23.png)

左のメニューから`ユーザー`を選んで`ユーザーを追加`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/d585a77e-ac68-e59e-ed8d-e531a98c1dce.png)


ユーザー名は適当でかまいませんが、重要となるのが`アクセスキー・プログラムによるアクセス`という部分にチェックを入れることです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/8dfce4dd-e53e-e905-1e41-596ccd1f6e0c.png)

次にユーザーの権限を設定するステップに入るのですが、`既存のポリシーを直接アタック`から`PowerUserAccess`を今回は選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/85bc92cb-7867-02af-a94d-7e94c807d74c.png)

そのまま最後の画面まで進めて`アクセスキーID`と`シークレットアクセスキー`をメモします。もしくは`.csvのダウンロード`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/d0aa2ec8-f7ea-35b5-6985-f73eace033c7.png)

## AWS CLIの設定

ターミナル上でAWS CLIに先程作成したIAMユーザーの情報を登録します。
まずは以下のコマンドを入力します。

```
aws configure
```

おそらく以下の内容を質問されるので、先程メモした情報を入力していきます。

- AWS Access Key ID
    - アクセスキーIDを入力します
- AWS Secret Access Key
    - シークレットアクセスキーを入力します
- Default region name
    - 今回は`ap-northeast-1`とします
- Default output format
    - ここは無視してEnterでかまいません
ログから ANSI Color を削除する


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/5d1313fa11ede179ddad|

# 概要

ログに ANSI Color が存在していた場合の除外方法.

これを取り除くための sed 方法. (以前に自分で試行錯誤したものとは違って綺麗なコマンドである...感謝)

```bash
$ sed -e 's/\x1b\[[0-9;]*m//g'
```

## 引用元サイト

https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream
Class Transformerの概要について備忘録を書いた

# はじめに
API開発を進めていく中でclassTransformerがかかわってくるところがあったので調べていると日本語記事があまり見つからなかったので備忘録を兼ねてこちらの記事を書くことにしました。
本記事は`class-transformer`の説明の導入部分についての記事になります。

# 自己紹介
はじめまして！
私は2022年4月から現在までCatallaxyという会社でエンジニアインターン生として勤務しているエンジニア志望の大学生です。

# class-transformerを理解する前に
JavaScriptには、
- プレーンオブジェクト
- クラスオブジェクト

の2種類があり、これらの違いを知る必要あります。

### プレーンオブジェクト
プレーンオブジェクトは、`{}`を使って作られるオブジェクトのことで例えば以下の配列の各要素に見られるような形になります。（以下の形式は特に`JSON形式`とも呼ばれます）
```users.json
  [
  {
    "id": 1,
    "firstName": "Johny",
    "lastName": "Cage",
    "age": 27
  },
  {
    "id": 2,
    "firstName": "Ismoil",
    "lastName": "Somoni",
    "age": 50
  },
  {
    "id": 3,
    "firstName": "Luke",
    "lastName": "Dacascos",
    "age": 12
  }
]
```

### クラスオブジェクト
クラスオブジェクトはコンストラクターやプロパティ、メソッドを独自に定義したインスタンスのことになります。下のような`User`クラスを定義する際には`class`という文言をあらかじめ宣言します。

```
export class User {
  id: number;
  firstName: string;
  lastName: string;
  age: number;

  getName() {
    return this.firstName + ' ' + this.lastName;
  }

  isAdult() {
    return this.age > 36 && this.age < 60;
  }
}
```

# 生じてしまう問題
以下のように、上記のユーザー情報をプレーンオブジェクトとしてダウンロードして、独自に定義したクラスオブジェクトに変換したいという状況を考えます。
```
fetch('users.json').then((users: User[]) => {
  ・・・
});
```
このように書けば`users[0].id`や`users[0].firstName`などのようにプロパティを使うこはできてます。
しかし、ダウンロードしてきたプレーンオブジェクトのままでは`User`クラスに定義したメソッド（`users[0].getName()`や`users[0].isAdult()`）を使うことができず、実用上不都合が生じてしまいます。

つまり、ここでの問題は、「JSON形式などのようなプレーンオブジェクトを、独自に定義したクラスのインスタンスに変換できないの？」という問題です。

# class-transformerによる解決
そこで、class-transformerの出番となります。
```
fetch('users.json').then((users: Object[]) => {
  const realUsers = plainToClass(User, users);
  ・・・
});
```
この`plainToClass()`という関数を用いることで`realUsers`という変数に格納された各ユーザーデータは自作の`User`クラスのインスタンスとなります。つまり、`realUsers[0].getName()`や`realUsers[o].isAdult()`のように`User`クラスに定義したメソッドを何の不便もなく使えるようになったというわけです。

# 最後に
API開発を進めるというタスクをする際にclass-transformerというライブラリは非常に有用なライブラリだということを開発を通して実感したので、自分の学びを共有できたら幸甚です。
また、当該ライブラリの`plainToClass()`関数の詳細についてもう少し調べた記事もかければなと考えております。

# 参考
https://github.com/typestack/class-transformer
Spring Bootでディレクトリをアップロード

# はじめに

Spring Bootでファイルサーバ（もどき）を実装するため、ディレクトリごとアップロードする処理を作成する。

# 環境

- Java 17
- Spring Boot 2.7.4
- Google Chrome 106

※ブラウザによって挙動が変わる可能性があります。

# 実装

## フロントエンド側

```html
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" id="filepicker" name="dirFileList" webkitdirectory multiple />
        <input type="submit" value="アップロード" />
    </form>
```

`<input>`タグに`webkitdirectory`を利用する。非標準機能だが大抵のモダンブラウザは大丈夫なはず。

https://developer.mozilla.org/ja/docs/Web/API/HTMLInputElement/webkitdirectory

また、ファイルをアップロードするために`<form>`タグには`method="post" enctype="multipart/form-data"`を指定しておく。

## バックエンド側

```java
    private final String DST_ROOT = "C:\\tmp\\files-demo\\output";
    @PostMapping
    public String upload(@RequestParam List<MultipartFile> dirFileList) throws IOException, IllegalStateException {
        for (var mpf : dirFileList) {
            final Path dst = Paths.get(DST_ROOT, mpf.getOriginalFilename());
            // Debug
            System.out.println(String.format("%s -> %s", mpf.getOriginalFilename(), dst));

            final Path parent = dst.getParent();
            if (Files.notExists(parent)) {
                Files.createDirectories(parent);
            }
            mpf.transferTo(dst);
        }
        return "post-upload";
    }
```

`multipart/form-data`で送信されたアップロードファイルは`MultipartFile`を介して扱うことができる。ただし今回は複数ファイルになる可能性があるのでリストで受ける。

https://spring.pleiades.io/guides/gs/uploading-files/

https://qiita.com/t-iguchi/items/a630fe7b6fed3f5c54cd

__Chromeの場合は__ 選択したディレクトリ名を含む相対パスが`MultipartFile.getOriginalFilename`で取得できる。

```
└─demo
    │  memo.txt
    │  日本語.txt
    │
    └─sub
            sub-file.txt
```
↓（`demo`ディレクトリを選択）

```java
dirFileList.forEach(mpf -> System.out.println(mpf.getOriginalFilename()));
/* ↓
demo/memo.txt
demo/日本語.txt
demo/sub/sub-file.txt
*/
```

アップロードファイルは`MultipartFile.transferTo`を利用することで簡単にサーバローカルに保存することができる。
ただし親ディレクトリは作られないので事前に`createDirectories`しておく必要がある。
absメソッドを使用して特定の差がある場合にTureを出力するプログラムの備忘録

今日も学んだことを忘れないためにメモします。

## absメソッドとは
対象となる数値に対して「abs」メソッドを実行すると絶対値（ある数値Xにおいて符号を無視して得られる符号なしの数値のこと）を取得することができる。すなわち正の数の場合はそのままだが負の数の場合は符号を取って正の数にした数値が取得できる。
```
num = 5.abs
#=> 5

num = (-5).abs
#=> 5
```

## プログラム内容
メソッドに3つの整数a b cを与える
「aとbの差が1」または「aとcの差が1」であり、かつ「bとcとの数値の差が2以上」の場合はTrue、それ以外はFalseを出力する

##　記述内容
```
def close_far(a,b,c)
  x = (a-b).abs
  y = (a-c).abs
  z = (b-c).abs

  if x == 1 && z >= 2
    puts "True"
  elsif y == 1 && z >= 2
    puts "True"
  else
    puts "False"
  end
end

close_far(1, 2, 10)
```

まず、2~4行目の記述で、abcそれぞれの差分を算出し、絶対値に変換する。

そして6行目のx == 1 && z >= 2で、「aとbの差が1」であり、かつ「bとcとの数値の差が2以上」を検討。
同様に8行目のy == 1 && z >= 2で、「aとcの差が1」であり、かつ「bとcとの数値の差が2以上」を検討する。

以上になります。
JavaScript自己学習（文字列操作編）

JavaScriptを勉強し始めたのでアウトプット兼ねて記事を書いてみる。
今回はString(文字列)の処理で基本的なもの、よく使いそうなものを書いていく。

# 文字長
### ・*length*
文字の長さはlengthプロパティで取れる。
```length.js
let str = "JavaScript";
console.log(str.length)
// -> 10
```

# 文字列検索
### ・*includes ( [検索したい文字] )*

引数の文字列が含まれていれば`true`、なければ`false`を返す。

```include.js
let str = "Hi,JavaScript World!";
console.log(str.includes("Java"));
// -> true
console.log(str.includes("python"));
// -> false
```

### ・*indexOf ( [検索したい文字] )*

includesと似ているがこちらは文字列が含まれていた場合に文字位置を`数値`で返す。
含まれていない場合は`-1`を返す。

```indexOf.js
let str = "Hi,JavaScript World!";
console.log(str.indexOf("Java"));
// -> 3
console.log(str.indexOf("python"));
// -> -1
```
if(str.includes(~)) ⇒ if(str.indexOf(~) > 0) とも置き換えられる。

# 文字列抽出
### ・*substring ( [開始位置] (, [終了位置]) )*

部分文字列を切り出す処理
開始位置は0から数える？1から数える？とかめちゃくちゃ迷う
文字列先頭に`0から`「01234...」と番号を振って数えるとわかりやすいと思う。
・開始位置 ⇒ 開始文字の番号
・終了位置 ⇒ 終了文字の番号+1

第2引数の終了位置を省略した場合は開始位置から`文字列末尾まで`切り出す。

```substring.js
let str = "Hi,JavaScript World!";
// 番号振る 01234567890123456789
// "Java"を切り出したい時は番号 3456 なので 引数は(3, 6+1)
console.log(str.substring(3, 7));
// -> "Java"

// 第2引数の終了位置を省略した場合は末尾まで
console.log(str.substring(3));
// -> "JavaScript World!"
```

### ・*slice ( [開始位置] (, [終了位置]) )*

使い方はsubstringと同じ
`[開始位置]>[終了位置]`の場合の挙動が異なる。
・substring ⇒ 第1引数と第2引数を入れ替えた時と同等
・slice ⇒ `空文字`を返す

```slice.js
let str = "Hi,JavaScript World!";
// substringの場合はsubstring(3, 7)と同等
console.log(str.substring(7, 3));
// -> "Java"

// sliceの場合は空文字
console.log(str.slice(7, 3))
// -> ""(空文字)
```

### ・*substr ( [開始位置], [文字数] )*

substrという関数も存在する。(まぎらわしい)
substringやsliceと違い第2引数に`文字数`を指定する。(まぎらわしい)
**※ただし今後削除予定の処理のため使用は非推奨**([MDN Web Docs \[String.prototype.substr()\]](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/substr))

試験とかの引っ掛け問題で出るかもしれないから覚えたけど実務で使うことはないでしょう。

# 文字列加工
### ・*padStart ( [加工後の文字列の長さ] (, [付加する文字]) )*

文字列の`左側`に指定長さ分だけ文字を付加する。
先頭0パディングするときなどに使う。
第2引数を省略した場合は`半角スペース埋め`される。

```padStart.js
let str = "12345";
console.log(str.padStart(10, "0"));
// -> "0000012345"
console.log(str.padStart(10));
// -> "     12345"
```

### ・*padEnd ( [加工後の文字列の長さ] (, [付加する文字]) )*
padStartと逆で文字列の`右側`に指定長さ分だけ文字を付加する。

```padEnd.js
let str = "12345";
console.log(str.padEnd(10, "0"));
// -> "1234500000";
console.log(str.padEnd(10));
// -> "12345     ";
```

### ・*toLowerCase()*
`小文字`に変換する。

``` toLowerCase.js
let str = "JavaScript";
console.log(str.toLowerCase())
// -> "javascript"
```

### ・*toUpperCase()*
`大文字`に変換する。

``` toUpperCase.js
let str = "JavaScript";
console.log(str.toUpperCase())
// -> "JAVASCRIPT"
```

### ・*trim()*
文字列の先頭と末尾の`全角半角スペース`を削除する。
文字の間にあるスペースは削除しない。

```trim.js
let str = "  Java Script   ";
console.log(str.trim());
// -> "Java Script"
```
【Linux】findで取得したパスに対してコマンドを実行する方法

## `exec`オプション
`find`コマンドの`exec`オプションを使用することで取得したパスに対してコマンドを実行できます。

以下のように記述すると取得したパス一つ一つに対してコマンドが実行されます。

```zsh
find . -name "*.txt" -exec rm {} \;
```
実際に実行されるコマンドは以下のようになります。

```zsh
$ rm "./sample1.txt"
$ rm "./sample2.txt"
$ rm "./sample3.txt" 
$ rm "./sample4.txt"
$ rm "./sample5.txt"
```

以下のようにすると取得したパスを並べた状態で引数として実行します。

```zsh
find . -name "*.txt" -exec rm {} +
```
実際に実行されるコマンドは以下のようになります。
```zsh
$ rm "./sample1.txt" "./sample2.txt" "./sample3.txt" "./sample4.txt" "./sample5.txt"
```

## `xargs`コマンド
また`xargs`コマンドを使用することで取得したパスに対してコマンドを実行できます。

```
find . -name "*.txt" | xargs rm
```

上記のように記述すると以下のように`rm`が実行されます。

```zsh
$ rm "./sample1.txt" "./sample2.txt" "./sample3.txt" "./sample4.txt" "./sample5.txt"
```

取得したファイルパス一つ一つに対して実行したい場合には以下のようにします。

```
find . -name "*.txt" | xargs -L 1 rm
```
```zsh
$ rm "./sample1.txt"
$ rm "./sample2.txt"
$ rm "./sample3.txt" 
$ rm "./sample4.txt"
$ rm "./sample5.txt"
```
PythonでCIDR表記のネットワークアドレスの色々な情報を調べてみる

<h2>はじめに</h2>
<p>
　PythonでIPアドレスやネットワークアドレスを表現したり操作するための超絶便利なライブラリ<code>netaddr</code>が素敵すぎるので、このライブラリと戯れながら、PythonでCIDR表記のネットワークアドレスから利用可能なホスト数やレンジを調べてみる。<br>

<h2>1. 準備</h2>
<div>
<p>・netaddrをインストール</p>
<pre><code>$ pip install netaddr</code></pre>
</div>

<p>・ライブラリ読み込み</p>
<pre><code>&gt;&gt;&gt; from netaddr import *</code></pre>

<h2>2. CIDR表記のネットワークアドレスを扱う</h2>

・CIDR表記のネットワークアドレスをIPNetworkクラスに渡す
<pre><code>&gt;&gt;&gt; ip = IPNetwork('192.168.1.0/24')</code></pre>

・みてみる
<pre><code>&gt;&gt;&gt; ip
IPNetwork('192.168.1.0/24')
</code></pre>

・これで<code>192.168.1.0/24</code>に関する色々な情報を調べられる準備が完了

<h2>3. ネットワークアドレスの色々をみてみる</h2>
・ネットワークに含まれるIPアドレス数とホストアドレス数

まずはこのネットワークに含まれるIPアドレス数とホストアドレス数を調べてみる。
<pre><code>&gt;&gt;&gt; ip.size
256
</code></pre>


ネットワークアドレス(192.168.1.0)とブロードキャストアドレス(192.168.1.255)を除いた利用可能なホストアドレス数は以下で調べられる。

<pre><code>&gt;&gt;&gt; len(list(ip.iter_hosts()))
254
</code></pre>

答えは<code>254</code>。

ちなみにこのネットワークのネットワークアドレスとブロードキャストアドレスが知りたい時はそれぞれ、


<pre><code>&gt;&gt;&gt; ip.network
IPAddress('192.168.1.0')

&gt;&gt;&gt; ip.broadcast
IPAddress('192.168.1.255')
</code></pre>

とすれば、こんな感じでIPAddressオブジェクトで結果が返ってくる。超簡単:heart:

このネットワークのレンジが知りたい時はネットワークの先頭と末尾をそれぞれ、

<pre><code>&gt;&gt;&gt; ip[0]
IPAddress('192.168.1.0')

&gt;&gt;&gt; ip[-1]
IPAddress('192.168.1.255')
</code></pre>

として見てみると、こんな感じでやはり、IPAddressオブジェクトで結果が返って来るので、このネットワークのレンジは<code>192.168.1.0~192.168.1.255</code>であることがわかる。


なお、IPNetworkオブジェクト、IPAddressオブジェクトを文字列として使いたい時は<code>str()</code>関数を使えば文字列型で返してくれる。

<pre><code>&gt;&gt;&gt; str(ip)
'192.168.1.0/24'

&gt;&gt;&gt; str(ip.network)
'192.168.1.0'
</code></pre>


<h2>まとめ</h2>
このように<code>netaddr</code>って、なんて便利で素敵なライブラリなんでしょう:heart::heart::heart:って思いますよね。
<br><br>
そのほかにもまだまだ便利な使い方が[<a href="https://netaddr.readthedocs.io/en/latest/index.html">本家のページ</a>
]のチュートリアルに掲載されているので詳しく知りたい方はそちらで。
<br>
HTML基本

# コメントアウト
mac：command+/
```
<!--表示されない-->
```

# 改行　br要素
改行したいところに`<br>`をつけることで改行できる
```html
  <body>
    html
    <br>
    css
  </body>
```
![スクリーンショット 2022-10-13 3.48.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/7c086078-49c5-998f-0920-6efc479531a2.png)
[br要素：MDNリンク]https://developer.mozilla.org/ja/docs/Web/HTML/Element/br

# 区切り　hr要素
区切り線をつけたい部分に`<hr>`で区切りをつけることができる
```html
  <body>
    html
    <hr>
    css
  </body>
```
![スクリーンショット 2022-10-13 3.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/15bf0fb1-4a28-c3a6-459d-48a0ed5dc514.png)


# リスト　ul要素/ol要素
順序なし　ul要素/順序有り　ol要素
```html
  <body>
    <ul>
      <li>html</li>
      <li>css</li>
    </ul>

    <ol>
      <li>htnl</li>
      <li>css</li>
    </ol>
  </body>
```
![スクリーンショット 2022-10-13 3.51.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/bc02fa8a-6527-98bd-ca10-3ce90ba5ea52.png)

[ul要素MDN]https://developer.mozilla.org/ja/docs/Web/HTML/Element/ul
[ol要素MDN]https://developer.mozilla.org/ja/docs/Web/HTML/Element/ol

# 入れ子になったリスト（ネストしたリスト）
```html
  <body>
    <ul>
      <li>ごはん</li>
      <li>パン
        <ul>
          <li>メロンパン</li>
          <li>あんぱん</li>
        </ul>
      </li>
    </ul>
  </body>
```
![スクリーンショット 2022-10-15 1.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/f76eae32-0c3d-4b5e-c095-503ca4f28fac.png)

# 説明リスト

一連の用語と説明をリスト化したもの
```html
  <body>
    <dl>
      <dt>用語１</dt>
      <dd>説明１</dd>

      <dt>用語２</dt>
      <dd>説明２</dd>

      <dt>用語３</dt>
      <dd>説明３</dd>
    </dl>
  </body>
```
![スクリーンショット 2022-10-15 1.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/43b87fd2-529d-7c46-186d-46f3c1213676.png)


# 強調
strong要素を使用すると強調できる
```html
  <body>
    <p>html<strong>css</strong>javascript</p>
  </body>
```
![スクリーンショット 2022-10-15 1.14.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2904183/6cbbb15d-4d8f-5689-4c18-ef833cab9065.png)

# 著作権表記をしたい場合
small要素
- 一般的に著作権表記、制約、注釈などを表すときに使用する。
- 文字を小さくするためには使用しない
[MDN]https://developer.mozilla.org/ja/docs/Web/HTML/Element/small

# span要素
- 意味を持たない要素
- 文章の特定の部分をCSSで装飾したい場合に使用
- classをつけることができる
- インライン要素
- 改行されない
- spanの中にdivは記述できない
[MDN]https://developer.mozilla.org/ja/docs/Web/HTML/Element/span
[Rails] 本番環境でrails db:dropする

AWS(EC2)へデプロイ後にデータベースを破棄しようとした際に発生
```
ec2-user@ip-*** ~]$ docker exec -it ***** sh
# rails db:drop RAILS_ENV=production
rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1
/usr/local/bundle/gems/activerecord-6.1.5/lib/active_record/tasks/database_tasks.rb:63:in `check_protected_environments!'
/usr/local/bundle/gems/activerecord-6.1.5/lib/active_record/railties/databases.rake:18:in `block (2 levels) in <main>'
/usr/local/bundle/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'
```
production環境でデータベースをdropする際は、`DISABLE_DATABASE_ENVIRONMENT_CHECK=1`を環境変数として指定します。

コンテナ内に入る
```
[ec2-user@ip-**-** ~]$ docker exec -it ***** sh
```

rails db:dropを実行

```
# rails db:drop RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1                       
Dropped database 'myapp_production'
```
シェルスクリプトで名前付きパイプを使ったプロセス間通信

## はじめに

ほとんど個人的な実験です。bash の coproc と同等のことを POSIX で標準化された範囲で実装しているだけ（のはず）です。詳細な解説は省きます。

## A. パイプを使った一般的な例

当然最速

```sh:test1.sh
#!/bin/sh

i=0
while [ "$i" -lt 10000 ]; do
    echo "1 / 61"
    i=$((i + 1))
done | bc -l
```

```console
$ time ./test1.sh > /dev/null

real	0m0.039s
user	0m0.060s
sys	0m0.013s
```

## B. 毎回コマンド呼び出しをする場合

当然遅い

```sh:test2.sh
#!/bin/sh

i=0
while [ "$i" -lt 10000 ]; do
    echo "1 / 61" | bc -l
    i=$((i + 1))
done
```

```console
$ time ./test2.sh > /dev/null

real	0m14.829s
user	0m12.645s
sys	0m5.270s
```

## C. 名前付きパイプを使ったプロセス間通信

そこそこ改善（B. のおよそ 64 倍）

```sh:test.sh
#!/bin/sh

mkfifo ./fifo1 ./fifo2
( bc -l ./fifo1 >./fifo2 ) &
i=0
while [ "$i" -lt 10000 ]; do
    echo "1 / 61" >&4
    read line <&3
    echo "$line"
    i=$((i + 1))
done 3<./fifo2 4>./fifo1
kill $!
rm ./fifo1 ./fifo2
```

```console
$ time ./test.sh > /dev/null

real	0m0.230s
user	0m0.153s
sys	0m0.127s
```

## まとめ

とりあえず動くことは確認した。

**追記** 特に反応ないだろうなーと思っていたのですがちらほら反応があるので、一応説明しておくと、これの目的はパフォーマンスではないです。一つのセッション（プログラム起動）で、そのバックグラウンドで起動したプログラムを終了させずに、プログラムの応答を見つつ命令を送って操作するという使い方を POSIX シェルの範囲で実現可能であることを実証するのが目的です。
Go言語 : キュー(Queue)

## キュー(Queue)
キューとは、入ってきたデータを順番に格納し、先に格納したデータから順に取り出すデータ構造。
先入れ先出し（FIFO：First-In First-Out）方式のデータ構造とも呼ばれる。

## ライブラリ
今回使用したライブラリは、 "go-datastructures".
https://github.com/Workiva/go-datastructures

"go-datastructures”ライブラリのキューには、複数の型の値が入れられる。

インストール用コマンド
$ go get -u github.com/Workiva/go-datastructures/...

## コード
```Go
package main

import (
	"fmt"
	"strconv"

	"github.com/Workiva/go-datastructures/queue"
)

func main() {

	// キューの作成
	var queueObj queue.Queue
	// 現在のキューの値 : []

	// キューへ値の追加
	queueObj.Put("AAA")
	queueObj.Put(111)
	queueObj.Put("BBB")
	queueObj.Put(222)
	queueObj.Put("CCC")
	queueObj.Put(333)
	// 現在のキューの値 :  ["AAA", 111, "BBB", 222, "CCC", 333]

	// キューから値を3つ取得
	qObj1, _ := queueObj.Get(int64(3))
	// 現在のキューの値 :  [222, "CCC", 333]

	// 出力
	fmt.Println("From Queue Value : " + qObj1[0].(string) + ", " + strconv.Itoa(qObj1[1].(int)) + ", " + qObj1[2].(string)) // From Queue Value : AAA, 111, BBB

	// キューから値を3つ取得
	qObj2, _ := queueObj.Get(int64(3))
	// 現在のキューの値 :  []

	// 出力
	fmt.Println("From Queue Value : " + strconv.Itoa(qObj2[0].(int)) + ", " + qObj2[1].(string) + ", " + strconv.Itoa(qObj2[2].(int))) // From Queue Value : 222, CCC, 333

	// キューの値チェック
	if queueObj.Empty() {
		fmt.Println("Queue Object is Empty.") // Queue Object is Empty.
	} else {
		fmt.Println("Queue Object is not Empty.")
	}
	// 現在のキューの値 :  []

	// キューへ値の追加
	queueObj.Put("DDD")
	queueObj.Put(444)
	queueObj.Put("EEE")
	queueObj.Put(555)
	// 現在のキューの値 :  ["DDD", 444, "EEE", 555]

	// キューの値チェック
	if queueObj.Empty() {
		fmt.Println("Queue Object is Empty.")
	} else {
		fmt.Println("Queue Object is not Empty.") // Queue Object is not Empty.
	}
	// 現在のキューの値 :  ["DDD", 444, "EEE", 555]

	// キューから値を2つ取得
	qObj3, _ := queueObj.Get(int64(2))
	// 現在のキューの値 :  ["EEE", 555]

	// 出力
	fmt.Println("From Queue Value : " + qObj3[0].(string) + ", " + strconv.Itoa(qObj3[1].(int))) // From Queue Value : DDD, 444
}
```

## 出力サンプル
$ go run queue.go
From Queue Value : AAA, 111, BBB
From Queue Value : 222, CCC, 333
Queue Object is Empty.
Queue Object is not Empty.
From Queue Value : DDD, 444

$ go build -o queue queue.go
$ ./queue
From Queue Value : AAA, 111, BBB
From Queue Value : 222, CCC, 333
Queue Object is Empty.
Queue Object is not Empty.
From Queue Value : DDD, 444

## GitHub
https://github.com/GL-Kageyama/Go_Queue
[Nuxt] vuex-persistedstateを使用しても値が復帰しない

vuexのstateを使用し、バックエンド側から取得してきたデータを保持し、それを永続化したかったのでvuex-persistedstateを使用しました。
ですが、ページをリロードした際、取得している値が描画されないエラーが発生しました。

vuex-persistedstateのインストール方法はこちら

https://www.npmjs.com/package/vuex-persistedstate

## 解決方法
nuxt-client-init-moduleを使用することで解決しました。

#### nuxt-client-init-moduleのインストール

```
npm install nuxt-client-init-module
```

#### nuxt.config.jsに定義

```nuxt.config.js
export default {
 :
 modules: [
    'nuxt-client-init-module'
 ],
 :
 :
}
```

#### store/index.jsに`nuxtClientInit()`を追加

```store/index.js
export const actions = {
  nuxtClientInit({ commit }, context) {
    const data = JSON.parse(sessionStorage.getItem('persisted-key')) || []
    //　条件式
  }
}
```

条件式の部分に、描画させたい値を各stateへcommitする形で記述します。

```store/index.js
export const actions = {
  nuxtClientInit({ commit }, context) {
    const data = JSON.parse(sessionStorage.getItem('persisted-key')) || []
    if (data.auth) {
      commit('myData/setLoginUser', data.myData.loginUser)
    }
  },
```
上記の場合、session storageに保持している`mydata.loginUser`の値を`loginUser`へcommitしています。

```store/myData.js
export const mutations = {
  setLoginUser (state, loginUser ) {
    state.loginUser = loginUser
  },
```
↓　mutationをcommit

```store/myData.js
export const state = () => ({
  loginUser: []
}
```
vuexについてはこちら

https://vuex.vuejs.org/ja/guide/state.html

auth moduleを使用しているので、store/auth.jsに値が入っている場合のみcommitを実行するようにしています。

＊ここでは説明のために「store/auth.js」とファイル名にしていますが、実際はauth moduleを使用すると「auth」という名前がstoreで使用されることになるようなので、store内に同じファイル名を作成することは出来ません。
また、if文で`if (data.auth.loggedIn) {...}`のようにstate名まで指定してしまうとエラーが発生してしまうので、注意が必要です。

ストレージは`localStorage` / `sessionStorage`のどちらでも大丈夫です。

＊現在、vuex-persistedstateはサポート外のようです。

## 参考記事

https://www.npmjs.com/package/vuex-persistedstate

https://noumisoblog.com/vuex-persistedstate-nuxt/

https://dosukoikoi.com/articles/481
M5StickCPlusからLINE Notifyに送るにはclient.setInsecure();が必要

#### 過去のコードでは、M5StickCPlusでLINE Notifyに送れなくなっていた。

M5StickCPlusでLINE Notifyに送ろうとしたら送れなくて、シリアルモニターに
```text
Try
Connection failed
```
と表示されるエラーに遭遇した。

先人の方々の記事を見たら、
以前はclient.setInsecure();は必要なかったが、2022年頃からclient.setInsecure();が必要になっていることがわかった。



#### 従来（2021年頃まで）、以下のコードでLINE Notifyに送ることができた。

```cpp
 /* LINE Notifyに送る */
void send(String message) {
  WiFiClientSecure client;
  Serial.println("Try");
  //LineのAPIサーバに接続
  if (!client.connect(host, 443)) {
    Serial.println("Connection failed");
    return;
  }
  Serial.println("Connected");
  //リクエストを送信
  String query = String("message=") + message;
  String request = String("") +
               "POST /api/notify HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Authorization: Bearer " + token + "\r\n" +
               "Content-Length: " + String(query.length()) +  "\r\n" + 
               "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                query + "\r\n";
  client.print(request);

  //受信終了まで待つ 
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    Serial.println(line);
    if (line == "\r") {
      break;
    }
  }

  String line = client.readStringUntil('\n');
  Serial.println(line);
}
```

#### 2022年頃からは、上記コードの2行目にclient.setInsecure();を入れた以下のコードで動作する。

```cpp
 /* LINE Notifyに送る */
void send(String message) {
  WiFiClientSecure client;
  client.setInsecure(); // サーバー証明書の検証を行わずに接続する場合に必要
  Serial.println("Try");
  //LineのAPIサーバに接続
  if (!client.connect(host, 443)) {
    Serial.println("Connection failed");
    return;
  }
  Serial.println("Connected");
  //リクエストを送信
  String query = String("message=") + message;
  String request = String("") +
               "POST /api/notify HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Authorization: Bearer " + token + "\r\n" +
               "Content-Length: " + String(query.length()) +  "\r\n" + 
               "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                query + "\r\n";
  client.print(request);

  //受信終了まで待つ 
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    Serial.println(line);
    if (line == "\r") {
      break;
    }
  }

  String line = client.readStringUntil('\n');
  Serial.println(line);
}
```


#### 参考記事
https://twitter.com/ciniml/status/1391016125530460163
https://twitter.com/coppercele/status/1391014047215091719
https://twirepo.com/detail/14663618

#### おわりに
また動いてガッツポーズ！
【Swift】まとめてアンラップする

# はじめに
`if let`や`guard`をまとめられるのを知らなかったので記録しておきます。

# if let
```swift
let int: Int? = 10

let string: String? = "hello world"

if let int, let string {
    print(int)
    print(string)
}
```
:::note info
**ポイント**
```swift
if let int = int, let string = string
```
と
```swift
if let int, let string
```
は同じ意味
:::

# guard
```swift
let int: Int? = 10

let string: String? = "hello world"

guard let int = int, let string = string else { return }

print(int)
print(string)
```
:::note info
**ポイント**
```swift
guard let int = int, let string = string else { return }
```
と
```swift
guard let int, let string else { return }
```
は同じ意味
:::

# おわり
これを使うとコードがすっきりするので積極的に使っていきたいです。
USB電源タップを購入する前に調べた事

# 1. 概要
USBの電源タップの購入を検討している中で、「A(アンペア)」や「W(ワット)」表記や、様々な規格があるため、
今までなんとなくで購入してきていましたが、一度綺麗に整理してみようと思います。

# 2. ポートの種類
- USB Type-A
単純に「USB」と記載されていることも多いです。
- USB Type-A(Qualcomm Quick Charge対応)
ポートの形状は通常の「USB Type-A」と違いはありませんが、
後述するQualcomm Quick Chargeに対応しています。
- USB Type-C
USB Type-Aと違い、上下どちらの方向でも差せます。
- USB Type-C(PD対応)
ポートの形状は「USB Type-C」と違いはありませんが、
後述するPD(Power Delivery)に対応しています。

# 3. 用語
## 科学のアレ
### 「V(ボルト)」とは
電気を押し出す力の単位。
川に例えると「水の流れる速さ」のようなもの。
「USB Type-A(Qualcomm Quick Charge非対応)」、「USB Type-C(PD非対応)」は5V固定で、通常のACアダプタやモバイルバッテリー等はだいたい5Vです。
「USB Type-C(PD対応)」は5V、9V、12V、15V、20V等といくつも種類があります。

### 「A(アンペア)」とは
電気の流れる量をあらわす単位。
川で例えるなら「川の幅」のようなもの。

### 「W(ワット)」とは
実際に消費される電気エネルギーをあらわし、この値が大きいほど電力を多く消費します。

電圧(V) × 電流(A) = 電力(W)

(例) 5V × 0.5A = 2.5W

## 充電規格

### Qualcomm Quick Chargeとは
米国QUALCOMM社が開発したスマートフォン・タブレットを高速で充電できる規格です。
Quick Charge 2.0充電規格は、5V/9V/12V/20Vの4段階の電圧を使用しています。
Quick Charge 2.0充電規格は、3.6V～20Vまで200mV刻みで電圧値を変動させることができ、接続機器の充電に最適な電圧値、電流値を調節して充電できます。
iPhone、iPad等は対応していません。
※ポートの種類はUSB Type-Aのみになります。

### PDとは
PDは「Power Delivery」の略で、急速充電が対応可能です。
接続する機器によって高速充電に必要なワット数は異なります。
スマホやタブレットなら30Wもあれば、まず問題ありません。
※ポートの種類はUSB Type-Cのみになります。

# 4.「A(アンペア)」と「W(ワット)」表記の違いについて
充電機器の購入検討をする上で、ややこしくしているのが、商品によって「A(アンペア)」もしくは「W(ワット)」のどちらかを記載している点です。
どちらか一方だけに統一してくれれば単純に比較しやすいのですが、なぜこんなややこしいことになっているのでしょうか。
それは、従来V(ボルト)は5Vで固定だったので、残りA(アンペア)がわかればW(ワット)が自動的に求まるため、もともとA(アンペア)記載が主流でした。
※(電圧(V) × 電流(A) = 電力(W))
それがPDやQualcomm Quick Charge等の登場により、V(ボルト)が5V固定ではなくなりました。
PDやQualcomm Quick Chargeの場合、A(アンペア)を記載したところで、V(ボルト)が可変なため、最終的に何W出力できるかわかりません。
そのため、W(ワット)が記載されるようになり、A(アンペア)記載されている商品と入り混じってしまった、というのが現状のようです。

# 5. 身近な充電器のW(ワット)数について
### [Apple 5W USB電源アダプタ](https://www.apple.com/jp/shop/product/MD810LL/A/apple-5w-usb%E9%9B%BB%E6%BA%90%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF)
世界でもっとも売れた充電器と言われるアレです。
※現在は発売終了しています。
こちらは 5V × 1A = 5W となります。

### [mac電源アダプタ](https://www.apple.com/jp/shop/mac/accessories/power-cables)
公式サイトを見てみると、67W、96W、140Wと展開されています。
※デュアルポート除く

# 6. 最後に
こうやって整理をしてみると案外簡単だったと思います。
今後、電源タップや充電器等を購入される際、ご参考になれば幸いです。
AI Programmerの作法 その18

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- 英小文字からなる長さが奇数の文字列 S が与えられます。
S の中央の文字を出力してください。


# 実行結果

```
英小文字からなる長さが奇数の文字列 S が与えられます。
S の中央の文字を出力してください。

	string SS;
	cin >> SS;

	if (SS.length() % 2 == 1) 
	{
		cout << SS[SS.length() / 2];
	}


```


# paiza.io


# 入力

```
atcoder
```

# 実行結果

```
o
```

# 成果物

https://paiza.io/projects/vWyPTPu5gHH20oGkjPqacw?language=cpp


以上。
応用情報を受けた【速報版】

※後でちゃんと書きます

# 所感
あれ？行けるんじゃね？

## 午前
- 解答速報で自己採して85%。もっと行きたい気持ちもあったけどまあかなりいいのでは。
- コンテナの話とかあったけど今思えば午後の伏線だったな
- SPFも午後ででてきたな。
- みんな過去問やれって言うの懐疑的だったけど本当に見たことある問題がいっぱいでてきた。過去問大事。
- 正味現在価値の問題は手で計算させるような問題かこれ？

## 午後
- 試験勉強と思わないで勝手に勉強してたコンテナの話が出た！！！！うれしい。

https://qiita.com/are-38-a/items/fbd08334a7d613c3d824

- 選択したのはプログラミング、コンテナの話、ネットワーク、組み込みシステム
- 組み込みこれ簡単すぎないか？書き抜きが多すぎて国語の問題レベルですらない気がする。逆に間違ってんのか？すごい不安。
- セキュリティはわりとネットワークっぽい話も出てきた。選択のネットワークを解くつもりでネットワークを勉強してしてよかった。
- プログラミングは最初何言ってるかよくわからなかったけど先にプログラムの穴埋めをやったら何してるか何となくわかった。再帰苦手…
- ネットワークは割とオーソドックスな感じだった気がする。
- 一瞬システム監査をやろうとしたけど結局分からない感じがしたのでやめた。

# お疲れ様です
受験したみんなおつかれ！！！！
AI Programmerの作法 その17

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- N 個の整数 A1​,A2​,…,AN​ が与えられます。
N 個の整数を合計した値を求めてください。

# 実行結果

```
N 個の整数 A1​,A2​,…,AN​ が与えられます。
N 個の整数を合計した値を求めてください。

	int N;
	cin >> N;
	int A[N];
	for (int i = 0; i < N; i++) 
		cin >> A[i];
	int sum = 0;
	for (int i = 0; i < N; i++) 
		sum += A[i];
	cout << sum << endl;

```

# paiza.io

# 入力

```
3
2 7 2
```

# 実行結果

```
11
```

# 成果物

https://paiza.io/projects/PK9cUezZinQK4pS6_7wreg

以上。
キーボード入力をスムーズに行うために（CapsLock + hでBackSpace、Windowsでのショートカットキー設定）

# 動機

Windowsで、キーボード入力をより素早くスムーズに行うために、できることはないか...？

キー入力の中で、BackSpaceキーは、よく使うのに、キーボードの右上の方にあってブラインドタッチが難しい...BackSpaceを押すときに手のポジションが崩れてしまいます。キーボード入力時に手を標準ポジションからなるべく動かしたくありません。LinuxのEmcasであれば、Ctrl+hでBackSpaceの挙動になり、手を標準ポジションから動かさないでBackSpaceが打てます。これをWindowsで、全アプリ共通で実現したいと思いました。

ただ、Ctrl+hはWindowsでは打ちにくいです（WindowsではCtrlキーが左下にあるため）。打ちにくいCtrlの代わりに左手の小指で簡単に打てるCapsLockを使い、CapsLock + hでBackSpaceの挙動にしたいです。

せっかくなので、他のEmacsショートカット（例えばCtrl + fでRightなど）も動くようにしたいです。

# Step 1: Change Key

> 後のステップでAutoHotKey（ショートカットキーを設定できるソフト）を使用するのですが、AutoHotKeyは日本語キーボードでのCapsLockの扱いがうまくいかない問題（[AutoHotkeyJp](https://www.sites.google.com/site/autohotkeyjp/reference/misc/Trouble#JP_Keyboard)を参照）があり、これを回避するために、CapsLockキーを何か別のキーと置き換えておく必要があります。
> ここでは、使う機会が少なそうなF24をCapsLockと置き換えることにしました。

Change keyを使って、以下の手順でCapsLockとAppsKeyを入れ替えます。

Change keyのダウンロード:

https://forest.watch.impress.co.jp/library/software/changekey/

解凍後にChgKey.exeを管理者権限で実行します。自分の環境（言語設定が英語のWIndows 10）では文字化けしていましたが気にせず続ければOKでした。

以下のCapsLockをクリック:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560904/eef4813b-b2e0-4a0b-7789-4aee9b595306.png)

続けて出る以下のダイアログでScan codeと書かれたキー（右上）をクリック。その後のダイアログでF24のスキャンコードである0076を入力。

> F24のスキャンコードについては以下のページを参考にしました:
> http://did2.blog64.fc2.com/blog-entry-349.html

次に、メニューから登録をクリックし、「現在の設定内容で登録します(R)」をクリック（ここで再起動が入るので注意）。

PCが再起動されます。以後、CapsLockとF24が入れ替わっています（Change Keyがレジストリの書き換えを行っています）。

# Step 2: AutoHotKey

AutoHotKeyをダウンロードしてインストール:

https://www.autohotkey.com/

Emcasのショートカットキー（例えば[emacsのショートカットキー　チートシート (Windows)](https://qiita.com/suuungwoo/items/57b32792a9001028d691)を参照）を参考にショートカットキーの設定を追加していきます（ただし、Ctrlキーの代わりにCapsLockキーで）。

以下を設定することにしました:

|キー|機能|
|-|-|
|CapsLock + h|BackSpace|
|CapsLock + d|Delete|
|CapsLock + m|Enter|
|CapsLock + p|↑|
|CapsLock + n|↓|
|CapsLock + f|→|
|CapsLock + b|←|
|CapsLock + a|Home（行頭へ移動）|
|CapsLock + e|End（行末へ移動）|
|CapsLock + g|Esc|
|CapsLock + Space|半角/全角（日本語切り替え）|

> 最後の日本語切り替えについてはEmacsのショートカットではなく、LinuxでCtrl + Spaceで日本語入力の切り替えができることから、このように設定しました。

テキストエディタを使って以下の内容のファイルを作成します:

```emcas.ahk
+SC76::+CapsLock
SC76 & h::BackSpace
SC76 & d::Delete
SC76 & m::Enter
SC76 & p::Up
SC76 & n::Down
SC76 & f::Right
SC76 & b::Left
SC76 & a::Home
SC76 & e::End
SC76 & g::Esc
SC76 & Space::VKF4
```

> SC76はScan code 76で、F24キーの意味です。
> 1行目の`+SC76::+CapsLock`はShift + CapsLockでCapsLock状態のオンオフ切り替えを行えるよにするためです。

上記のファイルをダブルクリックした後、キーボードショートカットが有効になります。

あとはこのファイルをWindows起動時に自動実行されるようにしておけば良いです。Windowsキー + Rの後で`shell:startup`とすると`Startup`フォルダが開くので、その中に上記で作成したファイル（`emcas.ahk`）を入れておけばOKです。
org-mode でブログ生成

# 成果物

[System Crafters の投稿](https://systemcrafters.net/publishing-websites-with-org-mode/building-the-site/) と [ ソースコード](https://github.com/SystemCrafters/systemcrafters.github.io/blob/master/publish.el) を元に、 `org-mode` でブログ生成してみました:

![org-mode-blog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/00cbdc75-fbfe-89df-fc7f-9575c892d34e.png)

[該当のブログ記事はこちらです](https://toyboot4e.github.io/2022-10-09-org-mode-blog.html) 。デザインは [Simple.css](https://simplecss.org) です。

# `org-mode` へのモチベーション

元々 `org-mode` へのモチベーションはありませんでした。むしろ AsciiDoc にこだわっており、 [専用の SSG を作ったりしました](https://github.com/toyboot4e/adbook) 。ただデザインが良くなかったので、一時的に `org-mode` に移行してみました。

`org-mode` で記事を書いてみると、エディタの見た目が良くて嬉しくなりました:

![org-mode-inline-display.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/69dbb29b-fbc1-d306-0c79-ecf0850d73ee.png)

WYSIWYG ではないですが inline style? って良いですね。細かなエディタサポートも豊富です。 **レスポンスが良いのが嬉しい** というのが `org-mode` を使うモチベーションになると思います。この辺は **実際に使ってみないと分かりませんでした** 。

# `org-publish` を SSG として使う

[System Crafters の投稿](https://systemcrafters.net/publishing-websites-with-org-mode/building-the-site/) に沿うと、 **ビルドスクリプトは ELisp で書きます**。ビルドスクリプトの内容は、 `org-publish` の設定・呼び出しや backend (後述) の設定です。

`org-publish` には以下のような内容が可能です:
 
- パタンマッチしたファイルをビルドして出力フォルダに写します
- sitemap (記事一覧の `index.org`) を生成します
- **記事パーツの HTML 変換 ("フィルタ") をオーバーライドします**
  - たとえば `org-mode` のコードブロックを [Prism.js](https://prismjs.com/) 対応の HTML に変換します

テンプレートやフィルタの集まりを backend と呼びます (たぶん) 。バックエンドを差し替えられるようにすることで、 `org-publish` は高い拡張性を確保しているようです。 HTML 出力を調整したり、 HTML 以外の形式 (PDF など) で出力することもできます。

`org-publish` の HTML 初期出力が合わなかったので、 [esxml](https://github.com/tali713/esxml) (S 式で書く XHTML) でテンプレートを作ることになりました。意外と盛り沢山の試行錯誤を経験できました。

# まとめ

Emacs を使っていると楽しいことが色々ありますね。
Ruby on Rails 7にFont Awesome 6を導入

## importmapを使う場合

```
./bin/importmap pin @fortawesome/fontawesome-free @fortawesome/fontawesome-svg-core @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-solid-svg-icons
```

## yarnを使う場合

```
yarn add @fortawesome/fontawesome-free @fortawesome/fontawesome-svg-core @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-solid-svg-icons
```

## アプリケーションに導入する

```js:application.js
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'
import { library } from "@fortawesome/fontawesome-svg-core";
import '@fortawesome/fontawesome-free'
library.add(fas, far, fab)
```

## アイコンを使う

```html:*.html.erb
<i class="fa-solid fa-house"></i>
<!-- など -->
```

以上です。簡単にFontAwesome 6が使えるようになりました。


Font Awesome 6アイコン検索ページ： https://fontawesome.com/search?o=r&m=free
クリップボードにあるイメージデータを拡大縮小するPowerShellスクリプト

## 製作動機
現在参画している仕事環境では、支給されたPCに会社規定以外のアプリケーションのインストールが認められておらず、管理者権限もありません。
テストのエビデンスを取得する際に画面コピーを多用するのですが、モニタをスケーリング設定して使用していると、Excel等に貼り付けた画面コピーのイメージがやたらと大きくなってしまいます。
毎度々々ペイントで縮小するとか、貼り付けた後で手で縮めるとかをやっていると、テストが永遠に終わらないので調べたところ、PowerShellであればできそうだという結論に達しました。
あちらこちらからコードを拝借して、なんとか完成しましたので、公開させていただきます。

## 処理内容
1. クリップボードにあるイメージデータを読み込む
1. 7行目にある``$ratio``の値に従って、読み込んだデータを拡大・縮小する
1. 2.で拡大・縮小したイメージデータをクリップボードに戻す

これだけです…

```powershell:shrink.ps1
Add-Type -AssemblyName System.Windows.Forms
[void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")

$cbImage = [System.Windows.Forms.Clipboard]::GetImage()
If ($cbImage -ne $null)
{
  $ratio = 71   # 拡大・縮小比率→71となっているのは、元イメージを71%に縮小するということ
  $ratio = $ratio / 100
  $newWidth = [int]($cbImage.Width * $ratio)    # アスペクト比を変える時は、
  $newHeight = [int]($cbImage.Height * $ratio)  # これらの値を修正する
  $bmImage = New-Object System.Drawing.Bitmap($newWidth, $newHeight)
  $newImage = [System.Drawing.Graphics]::FromImage($bmImage)
  $newImage.DrawImage($cbImage, $(New-Object -TypeName System.Drawing.Rectangle -ArgumentList 0, 0, $newWidth, $newHeight))
  [Windows.Forms.Clipboard]::SetImage($bmImage)

  $cbImage.Dispose()
  $bmImage.Dispose()
  $newImage.Dispose()
}
```
上記のソースは[GitHub](https://github.com/occhi244/shrink-clipboard-image)にも上げてあります。

## 使い方
1. 上の``shrink.ps1``をファイルに保存します。ファイル名は何でも構いませんが、拡張子は``.ps1``にしてください
1. PrtSc/ALT+PrtSc/Win+SHIFT+Sで画面コピーを取得します
または、任意のイメージをクリップボードへコピーします
1. エクスプローラー上で1.で作成したファイルを右クリックすると、「PowerShellで実行」というメニューがでますので、それを選択します
1. 一瞬コマンドプロンプトが表示され、すぐに消えます
1. CTRL+Vまたはアプリの「貼り付け」でペーストしてください
### 注意点
コマンドラインから実行しようとすると、PowerShellの実行ポリシーの制限により実行できない場合があります。デフォルトのポリシーでは実行不可となっており、設定を変更しようとすると、管理者権限が必要になります。
一回のみであれば``powershell -ExecutionPolicy RemoteSigned shrink.ps1``で可能です。

## PowerShellについて感じたこと
PowerShellは.NETのライブラリが呼べるので、実質C#やVBと同じことができます。
強力だが危険というのは確かにそのとおりで、インターネット上からダウンロードしたPowerShellスクリプトを、中のコードを見ずに実行してはいかんというのが、良くわかりました。
といいつつ、PowerShellのコードを公開しているのですが(汗)、やっていることが単純ですのでご心配なく…
react + typescriptの環境構築からhello worldまで

# typescript + react 環境構築

# 実行環境
windows10 64bit
cpu Intel(R) Core(TM) i7-7700 
ram 16GB

# インストールするもの
- vscode 
- nodejs

# インストール
## VsCode
[ここ](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)からインストーラをDL。あとはインストーラを起動してメッセージ指示に従う。
特別カスタムなどはしない

## NodeJS
言わずと知れたjava sriptの実行環境。
[ここ](https://nodejs.org/ja/)からDLしてインストールする。
最新版より安定している推奨版がいいだろう
インストール後にコマンドプロンプトで下記を行い、バージョン表記されたらOK
```
npx --version
```
任意でyarnとか入れておいてもいいかもしれない


# hello world
任意のディレクトリで下記を実行
```
npx create-react-app web --template typescript
```
するとwebというディレクトリが作成される
webディレクトリにcdして下記を実行する
```
npm start
```
web/README.mdには、dev環境のアプリなら[http://localhost:3000](http://localhost:3000)にアクセスすると実行したものを見られるとのこと
アクセスすると、下記のような画面が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262024/7dec2c2e-b8f8-ca98-54b8-371653ec3617.png)

一旦完了
Pythonのclassmethodとstaticmethodの違いについて

Pythonにはclassmethodとstaticmethodという似たような二種類のメソッドがあるが、どっちを使うべきなのか？と思ったので調べた

## メソッドの書き方
classmethodの場合
```python
@classmethod
def increment_classmethod(cls, value):
    return value + 1
```
staticmethodの場合
```python
@staticmethod
def increment_staticmethod(value):
    return value + 1
```
違いはclassmethodの場合は第一引数が`cls`になるのに対して、staticmethodは純粋に引数から始まります
なのでclassmethodで`cls.hoge`でクラスのプロパティやメソッドにアクセスできます、ただ`A.hoge`やるのと大差ないかなと思います

## メソッドの呼び方
```python
class A:
    
    @staticmethod
    def increment(value):
        return value + 1
    
    @classmethod
    def increment_classmethod(cls, value):
        return cls.increment(value)
    
    @staticmethod
    def increment_staticmethod(value):
        return A.increment(value)
```
このようなクラスがある場合、外から呼ぶ場合はどちらも呼び方は同じです
```python
A.increment_classmethod(value)
A.increment_staticmethod(value)
```

ただし、同じクラス内で呼ぶ場合は、classmethodの場合第一引数が`cls`なので
```python
cls.increment(value)
```
と呼ぶことができます

また、継承した場合はちょっと変わってきます
以下のように継承したクラスの場合
```python
class B:
    @staticmethod
    def increment(value):
        return value + 1
    
    @classmethod
    def increment_classmethod(cls, value):
        return cls.increment(value)
    
    @staticmethod
    def increment_staticmethod(value):
        return B.increment(value)

class A(B):
    @staticmethod
    def increment(value):
        return value + 2

value = A.increment_classmethod(1)
print('classmethod:' + str(value))

value = A.increment_staticmethod(1)
print('staticmethod:' + str(value))
```
結果
```
classmethod:3
staticmethod:2
```
classmethodから呼ぶ場合は、`cls.increment`で呼ぶことによりサブクラスの`increment`が呼ばれますが
staticmethodから呼ぶ場合は、クラス名を指定する必要があるので、オーバーライドしてようがそのクラスの`increment`が呼ばれます

## 速度
classmethodは第一引数にclsを入れる処理の分staticmethodよりも遅いらしいので計測してみました
```python
import time

class A:
    @staticmethod
    def increment(value):
        return value + 2
    
    @classmethod
    def increment_classmethod(cls, value):
        return cls.increment(value)
    
    @staticmethod
    def increment_staticmethod(value):
        return A.increment(value)

start_time = time.time()
value = 1
for i in range(0, 1000000):
    value = A.increment_classmethod(value)
end_time = time.time()
print('classmethod:' + str(end_time - start_time) + '秒')

start_time = time.time()
value = 1
for i in range(0, 1000000):
    # value = A.increment_classmethod(value)
    value = A.increment_staticmethod(value)
end_time = time.time()
print('staticmethod:' + str(end_time - start_time) + '秒')
```
こんな感じで10回計測してみます
[paiza](https://paiza.io/ja/projects/new)で計測しました

結果
```
classmethod平均:0.2170754433秒
staticmethod平均:0.2145765066秒
```
確かにstaticmethodの方が少し早いですが、気にするレベルじゃないと思います

## 結論
- クラス名書くより、`cls.`で書いた方が楽
- 継承した際にオーバーライドできる
- 速度的には気にするほどではない

という点から基本classmethod使ってれば問題ないかなと思いました
npm install ◯◯をすると出てくるエラーに手こずった話

## 問題
`$ npm install 〇〇` をすると下のようなエラーが出てきてなかなか手こずりました。
```
WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '@jest/transform@29.1.2',
npm WARN EBADENGINE   required: { node: '^14.15.0 || ^16.10.0 || >=18.0.0' },
npm WARN EBADENGINE   current: { node: 'v17.9.0', npm: '8.5.5' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '@jest/types@29.1.2',
npm WARN EBADENGINE   required: { node: '^14.15.0 || ^16.10.0 || >=18.0.0' },
npm WARN EBADENGINE   current: { node: 'v17.9.0', npm: '8.5.5' }
npm WARN EBADENGINE }
up to date, audited 1647 packages in 4s

164 packages are looking for funding
  run `npm fund` for details

20 vulnerabilities (3 moderate, 17 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
```
このような表示が出てきたときに、

`npm audit fix` とか `npm audit fix --force` をやったら良いと書いてあるので、やってみたけど変化なしでした。

## 解決
調べてみると、package-lock.jsonに
```
"npm": "6.9.0"
```

とありました。
そこで、自分のnpmのバージョンを調べると(`npm -v`)、8.5.5でした。
ここのバージョンが合っていないため、いくらやってもエラーを吐き出していました。

npmのバージョンが6.9.0に合うnodeのバージョンは12.6.0だったので、nodeのバージョンを変更すると自動的にnpmのバージョンも変更されました。
```
$ nodebrew install-binary v12.6.0
$ nodebrew use v12.6.0
$ node -v
v12.6.0
$ npm -v
6.9.0
$ npm install 〇〇
```

これでうまく通りました。
個人的に便利だと思ったMySQL Workbenchの使い方Tips


データベースクライアントはSequel AceとWorkbenchを使っているのですが、Workbenchで便利だと思った機能を紹介します。
内容に出てくるショートカットはMac用です。

## SQLを整形する
ツールバーの箒のマークをクリックするとSQLを自動整形できます。`Cmd+B`(Beautify)でもOK。
![スクリーンショット_2022-10-09_18_05_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/270ebd7a-cc2b-7cd0-7f7e-1bd644e00a03.png)

## 特殊文字の可視化
ツールバーの右から2番目のボタンで空白・改行・タブなどを可視化できます。
![スクリーンショット_2022-10-09_18_15_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/6a4dfc2c-cbee-b997-167a-32be93bf1a06.png)

## エディタからはみ出した部分を折り返す
ツールバー一番右のボタンで長いクエリを折り返しできます。
![スクリーンショット_2022-10-09_18_17_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/4d3c937c-18b3-fe77-03d6-d7abdb963cad.png)

## SQL をスニペットに登録する
よく実行するSQLは星のマークからスニペットとして登録しておけます。登録したスニペットは右側メニューから再利用できるようになります。
![スクリーンショット_2022-10-09_18_20_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/f8ca43b8-6147-5df1-dab9-559ecf13f852.png)

## SQLの実行結果をピン留めする
複数のSQLの実行結果を比較したい時、エディタ下部で赤いピンをクリックすると、別のSQLを実行した時に結果が上書きされなくなります。
![スクリーンショット_2022-10-09_18_24_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/627557da-8ab7-d2ac-1d87-230fd03b4ef0.png)

## テーブル定義からINSERT,UPDATE,DELETE文を自動生成
テーブル定義からINSERT,UPDATE,DELETE文を自動生成できます。
左サイドバーのSchemaからテーブル名を右クリック > Copy to Clipboard から選択できます。
![スクリーンショット_2022-10-09_18_30_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/639c4554-7dbf-5c3c-e747-b3fc557c0f26.png)

## SQLを実行結果を縦に表示する
MySQLのコマンドラインで`;`の代わりに`\G`をつけると縦表示にできますが、それをWorkbenchでもできます。
SQLを`Cmd + option + Enter`で実行すると縦に出力されます。カラム数が多いテーブルに便利です。

![スクリーンショット_2022-10-09_18_58_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/43afec2a-cf01-af42-bec5-6ac25156c06f.png)

## SQLの実行計画をビジュアルで確認
Explainの結果を図でグラフィカルに表示できます。
![スクリーンショット_2022-10-09_18_35_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/57b1e8aa-4bd0-5723-d71d-99e82a9f1f0f.png)

## システム変数を参照する

左サイドバー Administrationのタブ > Status and System Varibalesから確認できます。`Show variables like ...`をやらなくて良いので気に入っている
![スクリーンショット_2022-10-09_18_42_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/7ba36c14-61e6-ca8c-aa9e-c762e090a262.png)

## 画面を広くする

画面右上のアイコンからサイドバーなどを非表示にするとクエリエディタを広く使えるようになります。

![スクリーンショット_2022-10-09_18_45_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/ec15a909-636e-e68a-f8a8-83016435111f.png)