OmniAICreator/Qiita-1.07M huggingface dataset:
動画圧縮する(MP4 to mp4) on python3

こんにちは．

実験動画を圧縮する機会が増えてきました．

実験の動画を撮影した場合は，拡張子「MP4」で記録されます．
結果を記載するページは「mp4」のみ許可されています．
といっても，自作のwikiなので，拡張子の権限を増やしてやればいいだけなのですが．．．

まぁ，めんどくさいし，コマンド何回も打ち込むのだるいので，pythonで一気にやらしちゃおう！という内容です．

まず，ffmpegは必須です．
以下のコマンドでインストールしましょう．
※apt-get updateは行っておいた方が良いでしょう．

```
sudo apt-get install ffmpeg -y
```

私のPCにインストールしたffmpegのバージョン
少し古いかもしれません．

```
$ ffmpeg -version
ffmpeg version 4.3.2-0+deb11u2 Copyright (c) 2000-2021 
the FFmpeg developers built with gcc 10 (Debian 10.2.1-6)
```

## ソースコード

``` video_compression.py
    #! /usr/bin/python3
     
    import subprocess as sp
    import os
     
    path = "./"
    crf = str(28)
     
    files = os.listdir(path) # 同一ディレクトリのファイルだけ取得します．
    # 仮にディレクトリあっても無視されます．
     
    #print(files)
    tmp = []
    for i in range(len(files)):
        if "MP4" in files[i]:  # 拡張子MP4のファイルのみ，圧縮対象とします．
            tmp.append(files[i].split('.'))　
    tmp.sort()
    #print(tmp)
    # tmp[0][0] = ファイル名
    # tmp[0][1] = 拡張子
     
    for j in range(len(tmp)):
        filename = tmp[j][0]
        ext = tmp[j][1]
        cmd = "ffmpeg -i " + filename + "." + ext + " -crf " + crf +" " + filename + ".mp4"
        #print(cmd)
        process = sp.Popen(cmd.split())
        process.wait()
        print()
        print(j+1,"/",len(tmp))
        print()
     
    print("終了")

```

## 使い方
まず，ソースコードと同一ディレクトリに圧縮対象のファイルをすべて配置します．
そして，ソースコードを実行します．
シバン書いてますので，chmodして./で実行可能です．
基本的にファイル名は変更せず，拡張子だけ変更して保存します．

同一ディレクトリにpngファイルとか，txtファイル等が存在してたとしても，
指定した拡張子以外のファイルに関しては圧縮対象としない処理にしてますので，
エラーを未然に防ぎます．

process.wait()で1つ目のプロセスが終わるまで，待機します．
waitしなかった場合，並列処理で同時進行してしまいます．
CORE i5の10th GenがCPUとして入ってますが，なかなかうるさくなりますので，その仕様としています．
低スペックPCでも待っていれば，作業が終わるような処理です．


## ffmpegのcrfオプションについて

crfオプションの後の数値には意味が有ります．
数値は，小さいほど画質が良い．
反対に大きいほど画質が悪い．

今回私は28という数値を選択しました．

15とか30とか45とか試したのですが，私の環境では，30前後が良いという直感的な答えで28を選択しました．

参考までに，約6分の動画を圧縮した際の圧縮前後のサイズ

圧縮前：607.9MB
圧縮後：35.9MB
圧縮率は 607:35 なので，大体 17:1 くらいですかね．

crfオプションの数値:1 になるかと思ってたんですが，そうでもない感じです．
拡張子との兼ね合いもありそうで，そこまで調べてる時間はないので，これくらいで．

間違いあったら教えて下さい．

それでは．

[crfオプションについて](https://syobochim.hatenablog.com/entry/2021/01/07/004600)
Javaを使用してWordをHTMLに変換する方法

この記事では、JAVAプログラムのDocument.saveToFile（）メソッドを使用してWord文書をHTML文書に変換する方法を紹介します。コードを編集する前に、次の環境構成を参照して、jarパッケージをインポートしてください。

##プログラム環境
IntelliJ IDEA 2018（jdk 8.0）
テストドキュメント：Word 2013（.docx）
Jarパッケージ：**[Free Spire.Doc for Java 3.9.0](https://www.e-iceblue.com/Download/doc-for-java-free.html)**

次はjarをインポートする方法です。

jarパッケージをローカルにダウンロードして解凍し、ローカルのlibフォルダーにあるSpire.Doc.jarをJavaプログラムにインポートします。手順は次のとおりです。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/abe5b983-ad8e-6c1f-6776-672b8e5abc83.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/ef0168d9-e0cf-cafd-6b49-87081938fe99.png)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/0c522da9-dc00-37ed-6995-40d343a86dd1.png)

インポートした結果は以下のように：
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/e88c3038-553a-d845-7cbb-3954284745c4.png)

##コード一覧
###Java

```
import com.spire.doc.*;

public class WordtoHtml {
    public static void main(String[] args) {
        Document  doc = new Document();
        doc.loadFromFile("C:\\Users\\Administrator\\Desktop\\test.docx");
        doc.saveToFile("wordtohtml.html",FileFormat.Html);
        doc.dispose();
    }
}
```

##変換した結果
**Wordテストドキュメント**
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/c156a885-4994-bfc1-1a70-f8e4361ae890.png)

**変換したHTMLファイル**
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/02bdc53d-0309-90dd-b02f-0a75184ab237.png)

コード内のファイルパスはIDEAプログラムプロジェクトフォルダーパスです。ファイルパスは、他のパスにカスタマイズすることもできます。
では以上は今回のWordをHTMLファイルに変換する方法でした、最後まで読んでいただきありがとうございます。
Windows11,Anaconda3上でYOLOv5を動かしてみる(CPU編)

#目的
画像データから物体認識ができるYOLOv5をWindows上で試してみたので方法をまとめた。
##環境
- CPU : Intel i7-10700F 8Core 16thread
- GPU : NVIDIA GeForce RTX 3060 (Mem 12GB)
- OS : Windows11
- Anaconda : 3
- Python : 3.9.7

##YOLOv5のダウンロード
https://github.com/ultralytics/yolov5 から git clone するか、zipファイルをダウンロードして展開しておく。

##Anacondaで仮想環境を作る
ANACONDA.NAVIGATORで仮想環境を新たに作成し、Terminalを開く。
そこでダウンロードしたファイルを展開したディレクトリへ移動し、下記のように入力することで必要がインストールされる。

```
cd yolov5-master
pip install -r requirements.txt
```

なぜか data/coco128.yaml でエラーが出たので、ファイル内の罫線部分を削除した

```data/coco128.yaml(変更前)
# YOLOv5   by Ultralytics, GPL-3.0 license
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
# Example usage: python train.py --data coco128.yaml
# parent
# ├── yolov5
# └── datasets
#     └── coco128  ← downloads here
```

```data/coco128.yaml(変更後)
# YOLOv5   by Ultralytics, GPL-3.0 license
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
# Example usage: python train.py --data coco128.yaml
# parent
#  yolov5
#  datasets
#      coco128  ← downloads here
```


再度インストールすると正常終了した。

```
pip install -r requirements.txt
```

##実行してみる

```
python detect.py --source data/images/bus.jpg --conf 0.5 --weights yolov5s.pt
```

実行すると学習済みモデルをダウンロードして、認識結果の画像ファイルが runs\detect\exp\bus.jpg に出力された。
出力した画像ファイルを確認するとちゃんとバスと人３人のところに認識したタグが表示されるのが分かる。
![bus_300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576327/eb2e6614-ab91-10d6-21f0-9589e4ea8586.jpeg)


##自分のドライブレコーダの動画ファイルで試す
動画ファイルを入力してどのくらいの速度で認識できるかを試してみた。
試す動画はドライブレコーダで録画したデータを持ってきた。
ソースはこちら https://github.com/roxa-delphi/yolov5_test/blob/main/test.py

```
python test.py
```

結果はこんな感じ(実際は動画だがサンプルとして静止画を載せた)
![0041_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576327/51808dd8-9602-6e69-88f1-ffe28c28bb6a.jpeg)
ちゃんと車や信号機や人を認識できていた。
60秒の動画を157秒かかって解析していたので実時間より2.6倍の時間がかかっている計算、(多分)30フレーム/secの動画ファイルなので解析時は11.5フレーム/secの速度が出ている様子。
CPU使用率は82%くらい。
もともとの動画ファイルは 1280x720 pixel の大きさで大きめなので小さくするとフレームレートが高くなることはわかっているけど、画像を小さくしてしまうと小さく写っている車を認識しなくなったりしたので、プログラムの中で横幅 640 pixel として扱うようにした。

今回はCPUしか使ってないためにリアルタイムには解析ができなかったので、次回はGPUを使えるようにしてどのくらい速く処理が出来るようになるか試してみたい。
[py2rb] !r

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# !r (Python)
```python
>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
>>> f"He said his name is {repr(name)}."  # repr() is equivalent to !r
"He said his name is 'Fred'."
```
https://docs.python.org/ja/3/reference/lexical_analysis.html

> '!r' は repr() を呼び出します。

# どうする (Ruby)
```ruby
name = "Fred"
puts "He said his name is #{__repr__(name)}."
# or
puts "He said his name is #{name.inspect}."
```
`!r`を検索するのに時間がかかりました。

https://docs.ruby-lang.org/ja/latest/method/Object/i/inspect.html
# メモ
+ Python の !r を学習した
+ 百里を行く者は九十里を半ばとす
MySQLのパーティショニング機能を使ってみよう

---

この記事は[リンク情報システム](https://www.lis.co.jp/)の「TechConnect！2022年2月」のリレー記事です。
engineer.hanzomon のグループメンバによってリレーされます。
（リンク情報システムのFacebookは[こちら](https://ja-jp.facebook.com/lis.co.jp/)から）
TechConnect！2022年2月のインデックスは[こちら](https://qiita.com/hs-lis/items/69eee14fd7bec92a854f)

---

#はじめに
今回のアドベントカレンダーの2番目らしいです。
昨今、野球界では2番バッター最強説とかも出てきていることもあって、2番目ということに勝手にプレッシャーを感じてます。
なによりネタがピンポイントすぎる気がする、、、

今回は僕が関わっているシステムで課題だった処理時間の長さを解決してくれた__救世主・パーティショニング__を紹介したいと思います。

##開発環境
開発言語:PHP7.3
MySQL:8.0.18

##なんでパーティショニングが必要なのか？
DBにデータを登録していくともちろんデータが蓄積していく。
↓
そうすると探索するデータの対象が増えて処理に時間がかかってしまう。
↓
その他の応答時間も長くなってしまい、ユーザーに不快感を与えてしまう。
↓
ユーザーから問い合わせがくる。
↓
__ヤバイ！__

ということでパーティショニングを使ってみました！


#ぱーてぃしょん？ぱーてぃしょにんぐ？
__パーティショニングとは？__
>パーティショニングは、必要に応じて多くの部分を設定できるルールに従って、個々のテーブルの部分をファイルシステムに配分できるようにしています。それにより、テーブルの異なる部分が別個のテーブルとして別個の場所に格納されます。データを分割するためにユーザーが選択するルールはパーティショニング関数と呼ばれ、MySQL では法、範囲セットまたは値リストに対する単純な照合、内部ハッシュ関数、または線形ハッシュ関数が使用されます。関数は、ユーザーが指定したパーティショニングタイプに従って選択され、ユーザーが指定した式の値をパラメータとして取ります。この式には、使用されるパーティショニングのタイプに応じて、カラム値、1 つ以上のカラム値を操作する関数、または 1 つ以上のカラム値のセットを指定できます。  
[19.1 MySQL のパーティショニングの概要](https://dev.mysql.com/doc/refman/5.6/ja/partitioning-overview.html)

くどくど書いてあるけど、要するに
__1つのテーブルを仮想的に複数の区切りに分けられるということ！__
図で示すとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512397/7b46f69b-57d9-37d9-84c2-dd04a4ce7e7a.png)

#パーティショニングの準備

##１．使用するパーティショニングを選定する
一言にパーティショニングと言ってもいくつかの種類があります。今回はその中の２つを紹介します。

__RANGEパーティショニング__
指定された範囲に含まれるカラム値に基づいて、テーブルを分割する。

__HASHパーティショニング__
負の整数値にならないユーザー定義式に基づいてパーティションが選択される。

他にもパーティショニングがあるのでよかったら調べてみてください。
今回はRANGEパーティショニングを使用しました。

##２．プライマリーキーを設定する
パーティショニングには前提があり、パーティショニングに使いたいカラムはPRIMARY KEYに含まれていなければいけないという条件があります。そのため、稼働中のDBに追加する場合は注意が必要です。

##３．パーティションの追加SQL
パーティションを追加するSQLは以下のように記述します。

```SQL
ALTER TABLE テーブル名
PARTITION BY RANGE COLUMNS(カラム名) (
PARTITION 各パーティショの名前 VALUES LESS THAN ('2022/1/1 00:00:00'))
```

このような感じで切りたいだけパーティションを作っていけます。
各パーティションごとに名前を付けることができるので、「P202201」のようにいつまでのパーティションかを区別できるのも便利な点です。
基本的にはこの3順序でパーティションが設定されます。

#その他・注意点

##パーティショニングを解除する
パーティショニングは以下のSQLで戻すことができます。
パーティショニングを解除してもデータは消えないので安心してください。

```SQL
ALTER TABLE テーブル名 REMOVE PARTITIONING
```

##パーティションの最大数
MySQL5.6.7以降は8192パーティションまで増加しています。
よっぽどのことがに限り使い切ることは無いと思いますが、注意しましょう！

##パーティションの追加
既にパーティションが設定されているテーブルにパーティションを追加する場合は、今あるパーティションの後ろにしか追加できないので注意しましょう！

#おまけ：実際にパーティションを使ってみた
実際に業務で利用しているデータのため、処理の詳細が書けないのでカットしようと思いましたが、ちょっとおもしろいデータがあるのでそれだけ紹介したいと思います。

それは年単位、月単位、週単位でパーティションを切った時の処理時間が摩訶不思議だったんです。
__論より証拠__ということで、それを示したのが下記の表です。

|  | 年単位 | 月単位 | 週単位 |
|:-:|:-:|:-:|:-:|
| __処理時間__  |  22秒 | 18秒  |  24秒 |

パーティションを細かくすれば比例して処理時間が短くなるかなと思いましたが、そんなことは無く週単位にすると逆に処理時間が長くなってしまったんです！
この回だけたまたまそうなっただけのような気もしますが、、、
本当なら何十回かデータを取って平均出すのがベターなんだろうけどそんな悠長なことをする時間が無かった、、、
まー、ぶっちゃけ20秒台になっただけで相当速くなっていたので、そこまで気にしてはないんですけどね。

これを見てみると、逆にパーティションの切り方でも処理が遅くなるのか？と思いました。
>内部的にデータがわかれてしまうので、クエリによっては速度が遅くなる
[MySQLのパーティショニングの使い方とエラー対策]
(https://quarka.org/howto-create-mysql-partition/#ALTER_PARTITION)

#まとめ
救世主・パーティショニングのおかげで処理速度の改善が図れました。
__ありがとう！救世主・パーティショニング！__

これからは長年使われそうなシステムについては、ちゃんとパーティションも考慮して設計しないとダメだなと感じました！

また書きます。
Gitで新規ブランチ作成・チェックアウトを同時に行う方法

#やり方
オプションで「-b」をつける。

```
git checkout -b
```

「testブランチを新規作成」 + 「testブランチにチェックアウト」したい場合は
以下の様にする。

```
git checkout -b test
```


#記事を作成した理由
・個人用メモとして作成。
・チェックアウトとブランチ作成を別々に行うのが面倒だったため。


#参考情報
https://git.command-ref.com/cmd-git-checkout.html

https://qiita.com/U-MA/items/996ae933ae94c5711883
A5SQL で「’password’の設定に失敗しました」とエラーが出た

##’password’の設定に失敗しました!?

A5SQLにて、oracleDBを接続していたら、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/252ce1dd-9462-6718-b17a-6b450caa72a9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/ebdbc91c-ef52-f94d-e9f4-51f9d0ea36ef.png)

テスト接続はOK、、、


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/668854ee-e8e8-0af3-156f-0afd8fcaed11.png)
（何を黒塗りにすればいいのか分からないのでとりあえず数字隠した）

そのままでいっか！
OK！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/8a87e2b5-8997-baa8-ffe0-95fd489baa68.png)


何故！？


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/aa575968-5936-d62f-f264-4a60248dc0b2.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654203/3c67135f-42ab-28c7-68e4-fbaa98be5716.png)


接続できました☆

データベース名はそのままではダメでした。
原因不明でnpm ERR! code ELIFECYCLEでコケた場合の対処

vueにvuetifyを追加していたら、npmのビルドがコケるようになったので、色々ググったんですが、
解決せずにどハマりしたので、備忘録的に解決法をメモ

結果、package-lock.jsonを削除する手順が抜けていただけでした。

rm -rf node_module
rm -rf package-lock.json
npm cache clean -f
npm install
Chakra UIで他ライブラリーのアイコンを利用したい場合

## 概要

Chakra UI ではいくつかアイコンが提供されていますが、数が少なく大抵の場合サードパーティのライブラリーを導入する事になると思います。

そこで今回は Icon コンポーネントを使った他ライブラリーの利用方法を紹介したいと思います。

## やり方

Icon コンポーネントには as という props が用意されており、こちらにアイコンを渡す事で Chakra UI の提供するコンポーネントとして利用する事が出来るようになります。

react-icons を利用した例 (公式抜粋)

```example.ts
// 1. 他ライブラリーからアイコンをimport
import { Icon } from '@chakra-ui/react'
import { MdSettings } from 'react-icons/md'

// 2. `as` propを利用する
function Example() {
  return <Icon as={MdSettings} w={4} h={4} />
}

```

ただこのままだとアイコン毎にコンポーネントを作る必要があるので、
以下のように props 経由で表示するアイコンを切り替えるようにすると便利だと思います。
 (多分もっと良いやり方があると思うので詳しい人教えてください🙇‍♂️) 


```mapper.ts
//別ファイルでアイコンを読み込んでオブジェクトから取り出せるようにしておく。
import {
  FaTwitter,
  FaTwitch,
  FaLink,
  FaYoutube,
  FaSearch,
} from 'react-icons/fa'

export const iconMapper = {
  twitter: FaTwitter,
  twitch: FaTwitch,
  link: FaLink,
  youtube: FaYoutube,
  search: FaSearch,
}
```

```CustomIcon.tsx
import React from 'react'
import { Icon, IconProps } from '@chakra-ui/react'

//上で定義したやつ
import { iconMapper } from '~/assets/scripts/icons'

type Props = IconProps & {
  icon: keyof typeof extendIconMapper
}

const CustomIcon: React.FC<Props> = (props) => {
  const { icon } = props
  return (
      <Icon as={iconMapper[icon]} {...props} />
  )
}

export default CustomIcon

```

これでコンポーネントを呼び出す際に icon props に key を渡す事で指定したアイコンを表示する事ができるようになります。

```index.tsx

import { NextPage } from 'next'
import React from 'react'

const Home: NextPage = () => {
  return (
    <div>
      {/* YouTubeのアイコンが表示される */}
      <CustomIcon icon="youtube" />
    </div>
  )
}

export default Home


```


## 参考にした記事

Icon - Chakra UI
https://chakra-ui.com/docs/media-and-icons/icon

React Icons
https://react-icons.github.io/react-icons/
Deno: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする

こちらで行ったのと同じ計算を Deno で行いました。
[Python3: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする](https://qiita.com/ekzemplaro/items/e892ab821eef343d4860)

```typescript:count_vaccination.ts
// ---------------------------------------------------------------
//	count_vaccination.ts
//
//					Jan/26/2022
//
// ---------------------------------------------------------------
import {
    parse as parseCsv
  } from 'https://deno.land/std@0.82.0/encoding/csv.ts'


import { datetime } from "https://deno.land/x/ptera/mod.ts"
// ---------------------------------------------------------------
function get_day_6months_proc()
{
    const today = datetime ()
    var formatted = today.format("YYYY-MM-dd")
    console.log(formatted)

    const date1 = today.subtract({day: 184})
    const day_6months = date1.format("YYYY-MM-dd")

    return day_6months
}
// ---------------------------------------------------------------
function count_proc(content: any,day_6months: any)
{
	console.log(content.length)

	var count = 0
	var second = 0
	var second_6months = 0
	var third = 0

	for (var it in content)
		{
		const unit_aa = content[it]
		if (0 < count)
			{
			second += parseInt(unit_aa[2],10)
			third += parseInt(unit_aa[3],10)

			if (unit_aa[0] < day_6months)
       				{
		                second_6months += parseInt(unit_aa[2],10)
               			}
			}

		count += 1
		}

	console.log("second = ",second)
	console.log("second_6months =",second_6months)
	console.log("third = ",third)
}

// ---------------------------------------------------------------
console.error ("*** 開始 ***")
//
var file_csv: string = Deno.args[0]

console.log (file_csv)
// const day_6months = "2021-07-26"
const day_6months = get_day_6months_proc()
console.log(day_6months)

const content = await parseCsv(await Deno.readTextFile(file_csv))

count_proc(content,day_6months)

console.error ("*** 終了 ***")
// ---------------------------------------------------------------
```

実行結果

```text
$ deno run  --allow-read  count_vaccination.ts summary_by_date.csv
*** 開始 ***
summary_by_date.csv
2022-01-26
2021-07-26
290
second =  93846301
second_6months = 29646353
third =  2892327
*** 終了 ***
```
wsl ubuntuにtfenvインストール

#インストール
```
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
$ touch .bash_profile
$ echo export PATH='$HOME/.tfenv/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile

#tfenvバージョン確認
$ tfenv -v
tfenv 2.2.2-84-g459d15b
$ sudo apt-get install zip

#インストールできるバージョン確認
$ tfenv list-remote

#バージョン指定でインストール
$ tfenv install 1.1.4

#使用できるバージョン確認
$ tfenv list
   1.1.4

#使用するバージョン指定
$ tfenv use 1.1.4
 Switching default version to v1.1.4
 Switching completed

#terraformバージョン確認
$ terraform --version
Terraform v1.1.4
on linux_amd64
```
【Salesforce】カスタム設定の項目を並べ替えたい

# 動作確認

標準機能では無理。（ページレイアウト的なものは無い）

通常、カスタム設定で項目を作成すると、作成した順番に並ぶが、リリースするとばらける。
しかしばらけるのには法則があり、リリース後はAPI参照名の昇順（A→Z）で並び方が変わる。

# 実現方法

＜英語＞
1月 Jan__c
2月 Feb__c
3月 Mar__c

↓リリース

2月 Feb__c
1月 Jan__c
3月 Mar__c

F → J → Mに並び変わる

＜数字＞
1月 M1__c
2月 M2__c
10月 M10__c

↓リリース

10月 M10__c
1月 M1__c
2月 M2__c

10 → 1 → 2に並び変わる

＜数字：桁合わせ＞
1月 M01__c
2月 M02__c
10月 M10__c

↓リリース

1月 M01__c
2月 M02__c
10月 M10__c

01 → 02 → 10に並び変わる

# 参考リンク

なし
systemテストを落とさないようにするコツ2つ

Railsのsystemテストは、ランダムに落ちたり落ちなかったりすることがあります。ここでは、ランダムに落ちるテストをどうにかするためのコツを2つ紹介します。

## 基本

systemテスト（ブラウザーを使ったE2Eテスト）では、次の3つのアプリケーション（プロセスまたはスレッド）がバラバラに動いていると考えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308595/06ca5a79-99ab-e107-aeae-531a781f31cb.png)
テストがランダムに落ちる原因でよくあるのは、テストが進行するに従って、テストプログラムがほかを置いて先走ったり、ブラウザーが先走ったりすることです。

systemテストでこの3つの進み具合を揃え、ランダムに落ちないようにする基本は、何か動作を起こすたびに、画面のチェックを入れることです。

```ruby
click_link '製品一覧'
expect(page).to have_css('h1', text: '製品一覧') # これを省略しない！
click_link '石けん'
expect(page).to have_css('h1', text: '石けん')
```

「製品一覧」などのテキストが出るまでCapybaraがうまいこと待機してくれるので、sleepを入れる必要はありません。たいていはこれでうまく行きますが、それでもランダムに落ちるケースでは、次の2つの原因を疑ってみてください。

## 1. Ajax読み込みを確認してから次へ行く（フラッシュ対策）

「製品を登録しました」のようなフラッシュのテキストをチェックしているときに、フラッシュが画面に出なくてテストがランダムに落ちる、というケースです。この場合、フォームの送信中にAjax通信が来て、フラッシュがAjaxに取られている可能性があります。

例えば、フォームを表示するときにAjaxで追加のデータを取っているようなときは、Ajaxの読み込みが完了したことを確認したうえで、送信ボタンをクリックします。次の例は、カテゴリー一覧をAjaxで取ってリストに入れているときの書き方です。

```ruby
click_link '新規登録'
expect(page).to have_css('h1', text: '製品の登録')
expect(page).to have_css('#category option', count: 5) # Ajax読み込み待ち
fill_in '製品名', with: '石けん'
click_button '登録する'
expect(page).to have_text('製品を登録しました。')
```

## 2. DBにデータをすべて用意してからテストを始める

似たようなテストを並べて、データをちょっとだけ変えたいというときに、systemテストの進行中にDBを操作すると（クリック、クリック、DB更新、クリック……）、テストがランダムに落ちることがあります。ブラウザーが画面を取得したときにDB更新が間に合っていないせいです。ローカルでは起きなくてもCI環境で起こることがあります。

この場合は、テスト全体を始める前に必要なデータを作るようにします。次の「添付品あり」の例のように途中でデータを作っているテストがあるとします。

```ruby
describe "製品の登録" do
  before do
    login
    click_link '製品一覧'
    expect(page).to have_css('h1', text: '製品一覧')
  end

  it "通常の場合" do
    click_link '新規登録'
    fill_in '製品名', with: 'スペシャル石けん'
    click_button '登録する'
    expect(page).to have_text('製品を更新しました。')
  end

  it "添付品あり" do
    create(:attached_product, name: 'おまけ') # ここでレコード作らない!
    click_link '新規登録'
    fill_in '製品名', with: 'スペシャル石けん'
    check 'おまけ'
    click_button '登録する'
    expect(page).to have_text('製品を登録しました。')
  end
end
```

こういうテストが落ちるときは、多少コードが長くなっても、次のような修正を入れます（テストコードをきれいにしたかったら、この後で考えます）。

```ruby
describe "製品の登録" do
  before do
    login
    click_link '製品一覧'
    expect(page).to have_css('h1', text: '製品一覧')
  end

  it "通常の場合" do
    click_link '新規登録'
    fill_in '製品名', with: '石けん'
    click_button '登録する'
    expect(page).to have_text('製品を更新しました。')
  end
end

describe "添付品あり製品の登録" do
  before do
    create(:attached_product, name: 'おまけ') # 始めに移動
    login
    click_link '製品一覧'
    expect(page).to have_css('h1', text: '製品一覧')
  end

  it "添付品あり" do
    click_link '新規登録'
    fill_in '製品名', with: '石けん'
    check 'おまけ'
    click_button '登録する'
    expect(page).to have_text('製品を登録しました。')
  end
end
```

なお、systemテスト以外では、テストの途中でデータをいじるのはアリだと思っています（美しさにこだわる人は嫌がるかもしれません）。

## 3. アニメーションで落ちる（研究中）

jQueryやBootstrap、そのほかCSSやJavaScriptのアニメーションで落ちることがあります。この対策についてはまたあとで。
CASE式とCASE文の違い

CASE式とCASE文の違いを知ったので、忘れないように書いておきます。


## CASE式
```SQL
CASE VAR
	WHEN '1' THEN 'aaa'
	WHEN '2' THEN 'bbb'
	WHEN '3' THEN 'ccc'
	WHEN '4' THEN 'ddd'
	ELSE 'zzz'
END

```
JavaやC#のSwitch文っぽい

## CASE文
```SQL
CASE
	WHEN VAR1 = '1' THEN 'abc'
	WHEN VAR1 = '2' THEN 'def'
	WHEN VAR1 = '3' THEN 'hij'
	WHEN VAR1 = '4' THEN 'klm'
	WHEN VAR1 = '5' AND VAR2 = '1'THEN 'nop'
	ELSE 'xyz'
END
```
trangoとwireguardでサブネット内で使えるビデオ会議ソリューションをどこからでも使えるようにする

# trangoとは

LAN内で使えるビデオ会議ソリューション。self host版が下記リポジトリで公開されている。
https://github.com/trango-io/trango-self-hosted

今回はdocker hubで公開されているイメージを使って立ち上げる。

# サーバ

サーバの設定

## docker
先ずはUbuntu server 20.04を入れたての箱にdockerをインストール。

```
sudo apt install docker.io
```

## trango

次にtrangoを立ち上げる。
以下は、公式のコマンドそのまま。

```
sudo docker container run -d -p 80:80 -p 443:443 --name trango tak786/trango-self-hosted
```

## wireguard

Wireguardは手軽で高速なVPNソリューション。
先のtrangoを立ち上げた箱にwireguardをインストール。

```
sudo apt install wireguard
```

`/etc/wireguard`以下に`trango.conf`を作成。
この箱のtrangoデバイスに割り当てるIPを`192.168.123.1/24`にしておく。
クライアントがwireguardでこの箱に接続すると`192.168.123.0/24`をウロウロできるようにしておく。

# クライアント

Firefoxがなければ入れておく。Chromeは自己署名証明書だとすんなり接続できないのでパス。

## wireguard

wireguardをインストール。

```
sudo apt install wireguard
```

`/etc/wireguard`以下に`trango.conf`を作成。
先のtrangoを立ち上げた箱に接続するための設定を書いておく。

Wireguardでtrangoを立ち上げた箱に接続

## trangoにアクセス

Firefoxで`https://192.168.123.1`にアクセス
他にもアクセスしている人がいれば、ビデオ会議ができる

終わり（作成時間５分）
WP（SWELL）で明朝体を使う方法

SWELLで明朝体フォントが見つからないので、下記の流れで設定しました。

##手順
SWELL設定 → エディター設定 → カスタム設定 → カスタム書式 → カスタム書式用CSS

##CSSコード
.swl-format-1 {
	font-family: "Noto Serif JP", "Hiragino Mincho ProN", serif;
}

##参考サイト
https://aru-party.com/
https://asami-dance.com/
https://musakoji.com/
UiPath Automation Cloud Robots(Public Preview)を使ってみる

#1. Automation Cloud Robotsとは？

UiPathが稼働するロボット環境は、今までは利用者側で物理端末なりVDIなりを用意する必要がありました。今回Public Previewとして提供されているAutomation Cloud Robotsは、UiPath社が、クラウド上のロボット稼働環境を提供するサービスです。
これにより、ロボット用の端末を手元に用意しなくても、UiPath社との契約だけでUiPath Robotによる自動化が可能になります。（当然ながらイントラネット上のシステムに対して操作する場合はVPN等が必要になります。）
12月に一度Public Previewで公開されてましたが、一旦非公開となり、この1月のアップデートに含まれる形で再度Public Previewとして一部のエンタープライズAutomationCloudユーザーで利用できるようになりましたので、動作させてみます。
　なお現時点（2022/1/26時点）のステータスはPublic Previewですので、将来的に仕様が変わる可能性は大いにありますのでご注意ください。

#２．Automation Cloudでのセットアップ

まずはUiPath Automation Cloud上でライセンスがあるか確認します。
Licensesのページを参照して、Automation Cloud Robotの欄に１以上の値があれば利用可能です。

![CR-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/7db09092-f07b-4dc0-edde-9ff8be6c8cb4.png)


テナントの項目には、まだAutomation Cloud Robotの項目はありませんが、ライセンスの割り当てをすると項目がありますので、使用するテナントに割り当てます。

![CR-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/4a6a0e53-d266-4861-126b-92bb126b19f3.png)


次にAutomationCloud上でロボットアカウントを作成しておきます。

![cr-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/e200fd80-605e-50d4-6d17-3879233efe8b.png)


#３．テナントでの設定

テナント設定－マシンで新しくマシンを追加します。ここでCloud Robot pool(preview)を選択します。

![cr-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/b6e9cdab-5954-2353-18c9-a793e1dba599.png)


以下の画面になるので必要項目を入力します。

![cr-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/2f20cf2e-a460-6bc3-352c-127b1b307a50.png)

追加できました。次にMange Virtual Machineを選択します。

![cr-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/3408b0e1-39b3-90bf-1431-3803ad01f5c1.png)

VMの管理画面になります。VMを起動、リモートデスクトップ有効化、ジョブの有効化を行います。また管理者情報を設定します。

![cr-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/240fe8cc-28f0-c423-0cc9-8737311ca4f8.png)


リモートデスクトップが有効になると、IPアドレスが確認できます。

![cr-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/f2d36534-dd86-cd92-3687-5deb9417c125.png)

それでは実際にリモートデスクトップで接続してみます。以下のようなスペックとインストール済みソフトウェアになっていました。

![cr-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/dbfa6495-3153-8338-af6c-ec3ed036624b.png)

それでは実際にこのマシンをフォルダに割り当てていきます。今回はCloudRobot2という名前のフォルダを作成し、これに割り当てます。

![cr-a1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/5bb049fe-9585-b9b0-7cbe-ad9501e49301.png)

先ほど作成したロボットアカウントを追加します。

![cr-a2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/c7edc88a-e582-d3d6-36c3-bcb10991a426.png)

これで概ね準備が整いました。

#４．ジョブ実行

まずプロセスを作成します。

![cr-a3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/1894bbca-dcfb-d4e8-bcb4-c277b301ccfe.png)

ジョブ実行で、cloudRobotとRobotAccountを指定した後に実行します。

![cr-a3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/59fc0fd8-365b-5287-2d91-5a697c83d7a6.png)

無事実行されました。

![cr-a5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477147/d8c3ca5d-db11-4c0b-026c-c47c036a189c.png)

#５．まとめ
Public PreviewとしてリリースされたAutomation Cloud Robotsですが、かなり迅速にUiPathのRobot稼働環境を準備することが出来そうです。あとはお値段が気になるところですね。GAを待ちたいと思います。
wsl ubuntuにvscode codeコマンドインストール

#インストール

```
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install code
```
Ajaxでのファイルダウンロード（CSV）で文字化けした時の対策

やりたいこと
・HTMLのDLボタン　→　Ajax処理でファイル（CSV）ダウンロード
・UTF8のエンコードで出力するプログラムがすでにありそれを利用。SHIFT_JISへの変換はやりたくない
・DLしたUTF8エンコードのファイルをそのままエクセルで開ける。メモ帳で開いて再保存するとかもやりたくない
※バックエンドはかなり古い（クラシックASP）

結論として
・JSのBLOBオブジェクトを利用。JS側でファイル名とBOMをつける
・サーバーサードの出力はCSVの中身のみ（カンマ区切り(+改行)の文字列）ヘッダーなどは不要

参考
https://ameblo.jp/hero-design/entry-12652005689.html
Azureの組織ごとにサインイン方法を設定する方法

## はじめに

私はAzureの組織に複数所属しており、各組織にMicrosoft Authenticatorを使った認証を設定したいと思いました。
しかし組織ごとにサインイン方法を設定する方法がわかりづらく、ググっても出てこなかったのでまとめました。

本記事ではMicrosoft Authenticatorを使っていますが、他のサインイン方法を設定する際にも役立つ内容になっています。

## Azureの組織ごとにサインイン方法を設定する方法

1. 以下のページへPCからアクセスする
https://myaccount.microsoft.com/

2. 「組織」をクリックする
![スクリーンショット_2022-01-26_11_16_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/d868fd41-48b9-9bce-5443-b31aa462baaf.png)
または以下のページへアクセスする
https://myaccount.microsoft.com/organizations

3. 画面右上にあるアイコンをクリックし、切り替えたい組織をクリックする
![スクリーンショット_2022-01-26_11_18_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/9568ef26-0aaf-9694-bf92-55436f95fc54.png)
__ここが本記事の肝__ です。
組織を切り替える方法が非常にわかりづらく、私の知る限りではこの方法でしか切り替えられません。

4. サインイン画面が表示されるので、対象の組織にサインインする

5. 対象の組織が「サインイン済み」になることを確認し、「セキュリティ情報」をクリックする
![スクリーンショット_2022-01-26_11_20_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/608b9c3c-61d7-f6ad-ff69-4bb2dac79dbf.png)
または以下のページへアクセスする
https://mysignins.microsoft.com/security-info

6. 「+ 方法の追加」をクリックする
![スクリーンショット_2022-01-26_11_29_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/b2aa1a17-1c1a-487d-e74c-f5edfccba8ef.png)

7. 「認証アプリ」を選択し、「追加」をクリックする
![スクリーンショット_2022-01-26_11_31_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/0469249f-2881-cb75-0c14-769cf19e9102.png)

8. スマートフォンにMicrosoft Authenticatorをインストールし、「次へ」をクリックする
![スクリーンショット_2022-01-26_11_32_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/a096a7c5-48c5-1233-51e6-2439cbd3029d.png)

9. 「次へ」をクリックする
![スクリーンショット_2022-01-26_11_33_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/6b0f1f7b-c6e4-68a3-f2bd-e87693de9dcf.png)

10. Microsoft AuthenticatorでQRコードを読み取り、「次へ」をクリックする
![スクリーンショット_2022-01-26_11_33_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/d223c69d-a28f-bdf4-5b42-1e1d963d17d9.png)

11. Microsoft Authenticatorに通知が来るので「承認」をタップし、「次へ」をクリックする
![スクリーンショット_2022-01-26_11_36_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/6ef55e2f-5e4a-8b65-c002-102c0e936c0b.png)

12. セキュリティ情報の一覧に「Microsoft Authenticator」が追加されていたら設定完了！
![スクリーンショット_2022-01-26_11_37_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/089e9521-58e0-4b31-1046-a0a7d5c69662.png)

## おわりに

これでAzureの複数の組織にMicrosoft Authenticatorを使ってサインインすることができるようになりました！
私と同じように困っている人の役に立つと嬉しいです :relaxed:
【Android】テキストの長さに応じて高さ拡張＋テキストスクロール

# 概要

テキストの長さに応じてレイアウト変更するタイトル付きテキストのビューについて説明。

- テキストの長さが画面高さより短い場合、ビューの幅を変更。
- テキストの長さが画面高さより長い場合、テキスト部分をスクロール。タイトル部分はスクロールしない。


|  短い  |  長い(ビュー高さ拡張)  |  もっと長い(テキストのみスクロール)  |
| ---- | ---- | ---- |
|  ![Screenshot_1643167486.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/9efe6448-29a0-6419-171d-496d76429baf.png)  |  ![Screenshot_1643167225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/8c2e6422-1eca-b5fc-e17b-75a56ef31ddb.png)  | ![Screenshot_1643167177.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/a907a1cb-ab72-2680-0c67-c75d0037957a.png) |







# コード 
ScrollViewに```app:layout_constrainedHeight="true"``` をつけるのがポイント。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:padding="24dp"
	tools:context=".MainActivity">

	<!-- 中央寄せ -->
	<androidx.constraintlayout.widget.ConstraintLayout
		android:layout_width="0dp"
		android:layout_height="wrap_content"
		android:background="@color/gray"
		android:padding="8dp"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent">

		<!-- 上寄せ -->
		<!--androidx.constraintlayout.widget.ConstraintLayout
		android:layout_width="0dp"
		android:layout_height="wrap_content"
		android:background="@color/gray"
		android:padding="8dp"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"-->

		<TextView
			android:id="@+id/title"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="タイトル"
			android:textSize="18sp"
			app:layout_constraintEnd_toEndOf="parent"
			app:layout_constraintStart_toStartOf="parent"
			app:layout_constraintTop_toTopOf="parent"/>

		<ScrollView
			android:id="@+id/scroll"
			android:layout_width="0dp"
			android:layout_height="wrap_content"
			app:layout_constrainedHeight="true"
			app:layout_constraintBottom_toBottomOf="parent"
			app:layout_constraintEnd_toEndOf="parent"
			app:layout_constraintStart_toStartOf="parent"
			app:layout_constraintTop_toBottomOf="@id/title">

			<TextView
				android:id="@+id/text"
				android:layout_width="match_parent"
				android:layout_height="wrap_content"
				android:textSize="14sp"/>
		</ScrollView>
	</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
```
TeraTermインストール時によくやる初期設定

新しい環境(Windows PC)にTeraTermをインストールした時にいつもする設定の備忘録です。

#ダウンロード&インストール
以下からダウンロードしてインストール
https://ja.osdn.net/projects/ttssh2/

#ログ設定
設定>その他の設定>ログ

####標準ログファイル名
標準ログファイル名で任意のフォーマットを指定

```
例：日時とホスト名
%Y%m%d_%H%M%S_&h.log
```

####自動ログ採取
- [x] 自動的にログ採取を開始する
をチェック

※職場の場合は情報セキュリティに気を付けましょう

#設定の保存
設定>設定の保存
*TERATERM.INI*
を保存する。

#ヘルプ
https://ttssh2.osdn.jp/
英語キーボードで仮名入力(かな入力)する場合のキーマップについて

<h1>英語キーボードにおけるかな入力</h1>
英語キーボードで仮名入力(かな入力)を行う場合、必要なキーがアサインされていない、ホームポジョンから遠いキーにアサインされており打ちにくい、という問題があります。

この問題はautohotkey(windows)、karabiner-elements(macOS)などのキーマップを行うツールにより簡単に解消できます。小稿ではwindows環境についてautohotkeyを用いた対処方法を示します。

あわせてwindows PCの英語キーボードと、macOSの英語キーボードでは、一部の仮名配列が異なるので、windows PCでmacOSの仮名配列を実現するための対処も行なっています。これは筆者がmacOSの仮名配列に慣れているためです。

<h2>仮名入力(かな入力)を行うためのキーマップ</h2>
英語キーボードで仮名入力を行う場合、例えば以下のキーマップが便利です。

control + j    かな入力モードに移行
control + ;    英数入力モードに移行
shift + '　　　　かな入力モード時に「ろ」を打鍵
shift + ;　　　　かな入力モード時に「へ」を打鍵
shift + l　　　　かな入力モード時に「ー」を打鍵
shift + k　　　　かな入力モード時に「゜」を打鍵
shift + j　　　　かな入力モード時に「゛」を打鍵

ここでは修飾キーshiftを用いることで、ホームポジションから遠く離れた場所に配列されていた文字を打ちやすいキーにマッピングしています。

入力モードの遷移には修飾キーcontrolを用いていますが、好みに応じてalt など他のキーを使えます。controlを修飾キーにする場合には、caps lockをcontrolキーに設定したほうが便利です。macOSはOSの機能によりcaps lockをcontrolに変えられます。windowsではKeyTweakが便利です。

<h2>autohotkeyのコード</h2>

上記のマッピングを行うAHKのスクリプトを以下に示します。具体的には、「ろ」「へ」「ー」「゜」「゛」のマッピング、入力モードを遷移するcontrol + j、control +; の設定、windows PCとmacOSの仮名配列の違いを吸収する設定を行います。

ここで入力モードの設定と検出に、IME.ahk を用いています。以下のスクリプトは、autohotkeyのversionは1.1、wiondows10とwindows11で動作しました。

```autohotkey:
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%

#include IME.ahk

$^;::
	IME_SET(0)     ; IMEを英数モードにする
	Return

$^j::
 	IME_SET(1)     ; IMEをかなモードにする。
	Return

#If IME_GET()   ; IMEがかなモードのときに以下の置き換えを行う

$+'::       ; 「ろ」を shift + '　にマップ
 Send,``
 Return

$+`;::      ;  「へ」を shift + ;　にマップ
 Send,=
 Return

$+k::       ;  「゜」を shift + k　にマップ
  Send,]
  Return

$+j::       ;  「゛」を shift + j　にマップ
  Send,[
  Return

$+l::       ;  「ー」を shift + l　にマップ
  Send,_
  Return

$]::       ;　これ以後はmacOSの仮名配列に合わせるための設定
  Send,\
  Return

$=::
  Send,]
  Return

$+[::
  Send,+]
  Return

$+=::
  Send,+[
  Return

$\::=

#If

```

<h2>IME.ahk</h2>
IME.ahkは以下にあります。ダウンロードして、上記のスクリプトと同じディレクトリーにおきます。
https://w.atwiki.jp/eamat/pages/17.html

<h2>英語キーボードと日本語キーボードについて</h2>
日本語キーボードの欠点の一つは、英語キーボードよりもキー数が多く、打鍵機会の多いback spaceやreturnがホームポジションから遠いことです。

また日本語キーボードは以下の理由から日本語の入力に向いていません。日本語をローマ字入力するとき、カナ文字のために増えたキーは全くの無駄です。日本語を仮名入力するとき、仮名文字のために増設されたキーはホームポジョンから遠く、仮名入力が敬遠される理由になっています。右手の小指で遠く離れたキーを正確に打鍵することは難しいのです。日本語キーボードは、無理にキーを増やした結果、どんな用途にも使いにくいのです。

英語キーボードには以上の欠点がないため、英語の入力、ローマ字入力、仮名入力のいずれの場合においても、英語キーボードが合理的です。

日本語キーボードの唯一の利点かもしれないと思える点は、入力モード遷移のための独立したキーがあることです。しかしこれも上記のように control + j などにマップすればよいことです。左右のALTをそれぞれ入力モード遷移に使っている方もいます。

<h2>仮名入力とローマ字入力について</h2>
仮名入力はローマ字入力に比べて打鍵回数が半分程度になり合理的です。

仮名配列はよく設計されていて、ホームポジション付近のキーの打鍵機会が最も多いです。1段目(数字キー部分)の打鍵機会は少く、特に打鍵が最も困難な1段目の右端付近「ほ」のあたりには使用頻度が少ない文字がマップされています。

もし打鍵が困難な文字があれば、修飾キーを用いて好みの位置にマッピングすればよいのです。本稿ではもっとも打鍵しにくい「へ」「ろ」「ー」などの文字を打鍵しやすいキーにマッピングしています。

日本語キーボードも英語キーボードも、最も打ちにくい１段目や、2段目の右端にかぎって修飾キーを用いたマッピングを行うのはどういう理由でしょうか？打鍵しにくいキーに複雑な割り当てを行っているため仮名入力が敬遠されているのではないかと思います。

<h2>仮名配列</h2>
上記のAHKスクリプトによる文字配列を以下にしめします。
英数１段目　`1234567890-=
　　１段目　｀ぬふあうえおやゆよわほ゜
shift+１段目　〜ぬふぁぅぇぉゃゅょをほ「
英数2段目　qwertyuiop[]\
　　2段目　たていすかんなにらせ゛むへ
shift+2段目　たてぃすかんなにらせ」ーへ
英数3段目　asdfghjkl;'
　　3段目　ちとしはきくまのりれけ
shift+3段目　ちとしはき゛゜ーへろ
英数4段目　zxcvbnm,./
　　4段目　つさそひこみもねるめ
shift+4段目　っさそひこみも、。・

・・・・・・・・・・・・・・・・・・・・・・・・・
2022/1/28 構成と日本語表現を改めました。
JamStackってなんやねん

今流行りのJamStackについてまとめておきます。
JamStackの公式サイトが存在します。
Jamstackは、Webをより速く、より安全に、そしてより簡単に拡張できるように設計されたアーキテクチャです。（公式より抜粋）
https://jamstack.org/

# JamStackとは
- NetlifyのCEOであるMathias Biilmann氏が作った略語らしい！
- JavaScript/API/Markup　の頭文字より
- JavaScriptでAPIを叩き、静的なMarkupを配信する
- 動的コンテンツの場合、build時に取得して埋め込む
- 構築済みの静的ファイルをCDNから直接配置できるのでページ表示速度やレスポンスを向上させることができる。
- マーケティング目的などで使用される更新の少ないWebページにおいて、いちいちエンジニアに内容の変更を依頼してHTMLとか書き換えてもらうとかまじ無駄じゃね？みたいなのがなくなります。
- 実際使用されている例　[コロナのページとかも！](https://covidtracking.com/)JamStackの公式のShowcaseより

### JamStackで使われるサービスや技術など

#### ヘッドレスCMS
- ビューの存在しないCMS　(Contents Management System)
- [NetlifyCMS](https://www.netlifycms.org/)や[microCMS](https://microcms.io/)、[Contentful](https://www.contentful.com/)など
- 登録しておいたデータをAPIから取得することができる
- ヘッドレスCMSはコンテンツ管理のみに特化したCMS
- ということはつまりフロントエンドを自前で作る必要がある

#### SSG(Static Site Generator)

- build時にAPIを叩いてデータを取得して、HTMLを生成しておく
- Reactフレームワークでは[Next.js](https://nextjs.org/)や[Gatsby.js](https://www.gatsbyjs.com/),Vueフレームワークでは[Nuxt.js](https://nuxtjs.org/ja/)など
- 先にファイルを生成しておくことでサーバーの計算量を減らすことができる
- 管理画面やDBを必要としないため、外部から侵入されたり操作される心配がない
- ということはつまりユーザーによって画面表現が異なるなどの画面更新が多い場合は不向き
- 下記の例ではgetStaticPropsを使って、SSGのページを生成

以下簡単なサンプルです。

```pages/test/index.tsx
import type { NextPage, GetStaticProps } from 'next'
import { client } from '../../libs/client'
import styled from 'styled-components'

interface Props {
  text: string
}

const PageWrapper = styled.div`
padding: 10px;
display: flex;
align-items: center;
flex-flow: column;
`

const TestPage: NextPage<Props> = (props: Props) => {
  return (
    <>
      <PageWrapper>
        <h1>{props.text}</h1>
      </PageWrapper>
    </>
  )
}
export const getStaticProps: GetStaticProps<Props> = async () => {
  const { text } = await client.get({ endpoint: 'test' })
  return {
    props: { text }
  }
}

export default TestPage
```
下記のページより静的サイトジェネレータのスター数など見ることができます。

https://jamstack.org/generators/

#### ホスティングサービス

- インターネットを介してサーバーをレンタルするサービス
- 例として、[Vercel](https://vercel.com/home?utm_source=next-site&utm_medium=banner&utm_campaign=next-website)や[Netlify](https://www.netlify.com/)など
- 以下の最小単位のJamStackではVercel使ってます。vercelは商用利用はダメらしいですが無料でそこそこ使えます

#### 最小単位のJamStack

https://www.sukemaru.net/profile

microCMS/next.js/vercel　を使ったWebページ
こちら私個人のページです。
id: admin pin: 2222　で入れます。

### どうやらユーザーは待つことにストレスを感じる生き物らいしい

JamStackで高速なWebページがなぜ主流になっているのかでいくと、ユーザーがページの表示を待つことに対して途轍もないストレスを感じているからっぽいですね

[この記事とか](https://www.thinkwithgoogle.com/marketing-strategies/app-and-mobile/mobile-page-speed-new-industry-benchmarks/)どうやら画面の表示速度がコンバージョンとかに影響を及ぼしているっぽい！

なので、今後UXとか考える上でもこの辺りのサービスやフレームワークもますます盛り上がりを見せていくのでは？と期待が膨らみますね😁


### 参考

https://qiita.com/ozaki25/items/4075d03278d1fb51cc37

https://zenn.dev/luvmini511/articles/1523113e0dec58

https://nextjs.org/learn/basics/data-fetching/two-forms

https://blog.microcms.io/vs-wordpress/
[PowerShell] CSVに列追加、同じ値（文字列 / 日付）を入れる

PowerShellを用いて、CSVにカラム（列）を追加し、その全てに同じ値（文字列・日付）を入れる必要がありました。
CSVファイルを$dataに `Import-Csv` したとしましょう。

##文字列

```
$newdata = $data | Select-Object *, @{ Name = '列名' ; Expression = {'文字列'} }
```
結果↓

```
> $newdata

id name   列名
-- ----   ----
1  taro   文字列
2  hanako 文字列
3  jiro   文字列
```


##日付

```
$newdata = $data | Select-Object *, @{ Name = '列名' ; Expression = {(Get-Date).ToString('yyyy/MM/dd')} }
```
結果↓

```
> $newdata

id name   列名
-- ----   ----
1  taro   2022/01/26
2  hanako 2022/01/26
3  jiro   2022/01/26
```

以上。
【2022年1月】【AppleStore審査】審査までの手順が微妙に変わってる。

#AppStoreConnectの審査提出ページが変わってる。

AppStoreConnectの右上が`審査へ提出`が`審査用に提出`になっていたり、プロモーションのテキストが`一番上`になってたり変わってます。
今まで通り右上から`審査へ提出`を押すだけでは、`審査に進みません！`
今までは`このバージョンの最新情報`の入力欄が一番上だったのが`中段`に移動したりと変わってますので記載する箇所には`要注意です！`

# 新しい審査提出手順

1.必要情報を記載して`保存`する。
<img width="600" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/836655a8-6cf7-543c-dde1-4a3c48173bb3.png">

2.`審査用に追加`を押下する。
<img width="600" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/4563324d-428d-c24d-0c9c-1de97817279e.png">

3.ダイアログが表示されるので、`続ける`押下する。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/b277a58e-adc5-47d8-c4bf-0bf55aa10f65.png">

4.メニューに`AppReview(1)`が表示されるので押下する。
<img width="200" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/c0a65e76-3ccc-7291-415a-71acb855a6c1.png">

5.審査に提出したいアプリを審査準備完了から`表示`を押下する。
<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/a85606f3-2acc-4e11-8173-ba28c3a9134f.png">

6.`AppReviewに提出`で審査に進みます。お疲れさまでした。
<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902401/0f2c6e36-0d4e-2322-0bcb-242525f7ffaa.png">


# 今まで通りだと、審査に進みません。
`審査へ提出`が`審査用に提出`となっています。
`審査用に提出`を押下して放置だと審査に進まないため、なれるまで審査に進まない！が多発しそうですね。
CCNA向け基礎知識その２

##1.はじめに
今回は、スイッチポートモードの組み合わせと一部のviコマンドについての記事となります。
スイッチポートモードの組み合わせについての節では、管理モード同士で接続した場合にどのポートになるのか、もしくはエラーになるのかということを説明していきます。
viコマンドについての節では、カーソルや画面を動かすコマンドを説明していきます。

##2.スイッチポートモードの組み合わせ
管理モードは、「access」、「dynamic auto」、「dynamic desirable」、「trunk」の4種類があります。なお、デフォルトのモードは機種によって異なります。
また、ポートには、「アクセスポート」と「トランクポート」の２種類があります。

アクセスポートになる組み合わせ
・「access」と「access」
・「access」と「dynamic auto」
・「access」と「dynamic desirable」
・「dynamic auto」と「dynamic auto」

トランクポートになる組み合わせ
・「dynamic auto」と「dynamic desirable」
・「dynamic auto」と「trunk」
・「dynamic desirable」と「dynamic desirable」
・「dynamic desirable」と「trunk」
・「trunk」と「trunk」

エラーになる
・「access」と「trunk」

##3.viコマンド
１文字移動したい場合
・h：１文字左へ移動
・l：１文字右へ移動
・k：１文字上へ移動
・j：１文字下へ移動

行の端へ移動したい場合
・0:行頭へ移動
・$:行末へ移動

画面上の端(上下)へ移動したい場合
・H:画面上の最も上の行へ移動
・L:画面上の最も下の行へ移動

ファイル内の移動をしたい場合
・gg:ファイルの先頭へ移動
・G:ファイルの末尾へ移動
・nG:ファイルのn行目へ移動
・:n:ファイルのn行目へ移動

画面移動をしたい場合
・Ctrl+f:次の画面へ移動
・Ctrl+b:前の画面へ移動

##4.まとめ
今回の内容は分野がやや離れている２つの内容についてとなってしまいましたので、読者の中には「なぜこんな記事になったの？」と思われた方もいるかもしれませんが、私個人が学んだことを順番にまとめており、なおかつ記事が短くなりすぎないようにしたためこのようになりました。今後もこのような構成の記事を作成してしまうことがあるかもしれませんが、その際はご了承ください。
Macのインターネット共有でDHCPアドレス配布されない件

出先のホテルや優先LANしか整備されていない環境で便利なMacOSのインターネット共有。

こんな具合に手元の端末用にwifiアクセスポイントを作れます。

```
(wired network) --ethernet-- (mac) --wifi-- (mobile)
```

便利なインターネット共有ですが、ある日トラブルに見舞われます。

## mobile端末にIPアドレスが配布されない！

手元のandroid端末から接続しようとすると、「IPアドレスを設定中...」から進まなくなってしまい、接続できなくなってしまいました。

はて、と思い最近なにかやったかなと記憶を巡ると標準のfirewallをオンにしたのを思い出しました。

firewallをオフにして、再度android端末から接続すると1秒もかからずにwifi接続が確立されました。

## 原因はだれ？

firewallをオフにして運用したくなかったので、firewallのルール変更で対応する方針に。

mac標準firewallはポート番号basedのルールではなく、アプリケーションbasedルールなので、アドレス配布を担当しているDCHPプロセスを特定します。

```zsh
% lsof -i:67
# => ヒットせず

% sudo lsof -i:67

OMMAND PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
launchd   1 root   01u  IPv4 0x000000000000      0t0  UDP *:bootps
# ※FDなどは適当な値に置換
```

Appleの資料[^1]によるとDCHP serverを担当しているのは`/usr/libexec/bootpd`の用ですが、`bootpd`は実際にはlaunchdから起動されているので、ポート管理的には`launchd`プロセスが`UDP:67`を管理しているように見えるよう。



## 解決へ

あとはfirewallの設定を変更するだけ。

`システム環境設定 > セキュリティー＆プライバシー > Firewall > オプション`から`/sbin/launchd`を追加してやる。その際、`/sbin`ディレクトリに行くため`cmd + shift + Gキー`で直接`/sbin`ディレクトリを表示してやる必要があるので注意。

めでたくfirewall使用環境下でインターネット共有できるようになりました。


[^1]: [TCP and UDP ports used by Apple software products - Apple Support](https://support.apple.com/en-us/HT202944)
ECで使えるCSS Grid

## はじめに

- ECのランディングページを作成しているとよくあるのが商品の羅列です。その際に``grid``をよく使いますが、レスポンシブデザインをできるだけメディアクエリを使わずに構成したいので、コードを少なくする小技をメモとして書きました。
- [コリス](https://coliss.com/articles/build-websites/operation/css/how-to-use-css-minmax.html#h205)さん他、多数の方が``grid``の便利な使い方として紹介されていましたので、参考にさせていただいたものを自分なりにアレンジしたものになります。
- もっと簡単にできるよ、ということでしたらぜひ教えてくださいm(__)m

## 条件とコード

- 以下の条件で作りたい場合
  - コンテナのMAX幅は1000pxで最大4列作りたい
  - レスポンシブ対応で画面幅に合わせて列数を変えたい
  - スマホサイズでは2列で表示したい
  - 列同士の間は``16px``開けたい
  - 極力メディアクエリは使いたくない（コードが増えるから）

```html
<div class="container">
  <!-- 複数要素 -->
</div>
```

```css
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(calc(50% - 8px), calc((1000px - 16px * 3) / 4)), 1fr));
  gap: 16px;
}
```

## コード説明

- ``repeat``
  - 商品を羅列したいので同じ幅を繰り返します。
- ``minmax(~, 1fr)``
  - 最小値と最大値を指定します。最大値に``1fr``を指定して柔軟に幅を対応させています。（[単位fr](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout#the_fr_unit)とは）
- ``min(calc(50% - 8px), calc((1000px - 16px * 3) / 4)``
  - 上記の条件の場合、画面サイズが491px以下になると``calc(50% - 8px)``、492px以上で``calc(1000px - 16px * 3) / 4``が適用されます。コンテナの最大幅から要素間の余白分を引き、最大で4列表示したいので4分割しています。
  - ``calc(50% - 8px)``を単純に``50%``としてしまうとスマホサイズになったときに``minmax(50%, 1fr)``となり、``gap``で指定した``16px``分が確保できなくなります。そのため``50%``が適用されず、``1fr``が適用されカラムが1列になってしまいます。``minmax(calc(50% - 8px), 1fr)``を適用させることで``gap``の``16px``分が確保され、スマホサイズでカラム2列になります。``minmax``の特性については、コリスさんが[minmaxのバリデーション](https://coliss.com/articles/build-websites/operation/css/how-to-use-css-minmax.html#h202)で詳しく書かれています。


:::note info
gapによって余白を設けない場合は、calc(50% - 8px)を使用せず単純に50%でOK
:::

## おわりに

- 商品の羅列には``flex``も有効ですが、コードが増えがちです。（私見ですが・・・）
- 今回の``grid``は少ないコードでレスポンシブ対応もできるのでかなりオススメです。
- もしここ間違ってるよ、ということでしたらぜひ教えてください。
【努力】WriteCode_EveryDay 草生やしたい


#Write Code Every Day Rule
https://johnresig.com/blog/write-code-every-day/

```
1.毎日30分くらいコードを書くこと。
　『Qiita、Zenn、その他活動』は コードを書いたらやってよい。
2.意味のあるコードを書くこと。
　インデントやフォーマットの修正はコード書きにはカウントしない
（可能ならばリファクタリングも）

3.深夜23時前に終わらせPushすること
4.書いたコードをGitHubで全て管理すること。


※事前準備：30分程度で終わる粒度のPullRequestを
  事前に大量に作っておくこと

```

毎日選んで開発することで、
何をするか迷うことなくスムーズにコードを書くことができたそうな👀

案：
1.再利用性について考え、モジュールを作成
2.GitHub上の草は気にしない。
（他の人の認識を満たすのではなく、自分の人生で改善したくてしてるものだから）
　※この実験からの最も重要なポイント(経験者曰く)
3.案だし&不要なものは削除
　→都度行わないと負債としてたまる
４．「十分な」作業を完了していない、または「十分な」進歩を遂げていないことに高いレベルの不安を感じることがよくありました
　　進歩しているという感覚は、実際に進歩しているのと同じくらい重要であることに気づきました。これは目を見張るものでした。毎日一貫した進歩を遂げ始めると、不安は解消し始めました。自分が成し遂げてきた仕事の量に安らぎを感じ、必死に仕事を成し遂げたいという過度の欲求はもはやありませんでした。


#◎小さな達成感をたくさん味わう

・GitHubに草が生える
・開発が進み、機能ができてくる
・PullRequestに積んだタスクが減っていく

とにかく、ハードルは低めに設定して、
自分を褒めてあげて達成感を味わう！
(何もやらないよりは良いのだ)


#過去から学ぶ改善点
１．規模が大きめのサービスの開発をしない
　(※最初の数か月が 新技術知識の取得がピークのため)
→もっと規模が小さいものをいろんな言語で開発する方が、多くのことを学べるかも？

２．言語やプラットフォームを業務で利用しているものと合わせる
→仕事での相乗効果がある
　マルチタスクにならない(挫折して失敗２回目)


#おわりに
少しずつでも毎日継続することで、いつか大きな成果となる
人生、何かを始めるのに遅すぎるということはない
＝今日が人生で一番若い日


##きっかけ
１．コードで作業するまでの期間が長い
業務でも触れない日があるし。
技術的知識に触れる機会が少なくても多くても嫌だなぁと。
（リラックスしたり、何か楽しいことをしたりする機会をなくすので）



２．タイピング好きだし、
コードをググって描けるはやっぱり気持ちいい🐾


３．不調でも『60点』だせる余裕は欲しい
　　コード…うっ頭がってなるのは嫌かな。

４．自分が得意でできることの範囲を能力の輪を広げたい

バフェットもこう言ってた、

```
「自分の『能力の輪』を知り、その中にとどまること。
輪の大きさは、さほど大事じゃない。
大事なのは、“輪の境界”がどこにあるかをしっかり見極めることだ」
```
#おわりに
草毎日生やせるようにがんばるわん
Node.js: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする

こちらで行ったのと同じ計算を Node.js で行いました。
[Python3: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする](https://qiita.com/ekzemplaro/items/e892ab821eef343d4860)

必要なライブラリーのインストール

```bash
npm install csv
npm install date-utils
```

```js:count_vaccination.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	count_vaccination.js
//
//					Jan/26/2022
//
// ---------------------------------------------------------------
'use strict'

var fs = require("fs")
var csv = require('csv')
require('date-utils');

// ---------------------------------------------------------------
function get_day_6months_proc()
{
	const today = new Date ()
	var formatted = today.toFormat("YYYY-MM-DD");
	console.log(formatted)

	const date1 = new Date ()
	date1.setDate(date1.getDate() - 184)
	const day_6months = date1.toFormat("YYYY-MM-DD")

	return day_6months
}

// ---------------------------------------------------------------
function count_proc(array_aa,day_6months)
{
	var second = 0
	var second_6months = 0
	var third = 0
	for (var it in array_aa)
		{
		const unit_aa = array_aa[it]

		if (0 < it)
			{
			second += parseInt(unit_aa[2],10)
			third += parseInt(unit_aa[3],10)

			if (unit_aa[0] < day_6months)
				{
				second_6months += parseInt(unit_aa[2],10)
				}
			}
		}

	console.log("second = " + second)
	console.log("second_6months = " + second_6months)
	console.log("third = " + third)
}

// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const file_csv=process.argv[2]

console.log (file_csv)

const day_6months = get_day_6months_proc()
console.log(day_6months)

fs.readFile(file_csv, function(err, buf)
	{
	csv.parse(buf.toString(),{comment:'#'}, function(err, array_aa)
		{
		if (err != null)
			{
			console.log ("*** error ***")
			console.log (err)
			}

		console.log(array_aa.length)

		count_proc(array_aa,day_6months)

		console.error ("*** 終了 ***")
		})
	})
// ---------------------------------------------------------------
```

実行結果

```text
$ ./count_vaccination.js summary_by_date.csv
*** 開始 ***
summary_by_date.csv
2022-01-26
2021-07-26
290
second = 93846301
second_6months = 29646353
third = 2892327
*** 終了 ***
```
CVSS とは

## 勉強前イメージ

セキュリティ的な流れだった気がするけど知らへん

## 調査

### CVSS とは

Common Vulnerability Scoring System の略で、 日本語で共通脆弱性評価システムになります。
脆弱性の深刻度を評価する標準化されたものです。
現在はFIRSTというところが管理しています。
標準化されているため、なにかに依存しているわけではないので製品間の比較ができます。
CVSSにもバージョンが有ります。

### 評価の方法

CSVVでは以下の3つの基準で脆弱性の評価を行っており、これらから脆弱性の深刻度を決定します。

- 基本評価標準

脆弱性に対する評価になります。
機密性、完全性、可用性の影響と複数の要素を合算して基本値を算出します。
評価結果は固定のため、時間経過や環境によって変わることはありません。

- 現状評価基準

脆弱性の深刻度の評価です。
攻撃おコードの有無や対策情報が利用できるのかなどの基準で評価します。
上記から、脆弱性の対応状況によって変化します。

- 環境評価基準

利用環境も含めての、最終的な脆弱性の深刻度になります。
二次被害の大きさや、使用状況などの基準で評価し算出します。
こちらは、想定される驚異に応じて利用者ごとに変化します。

### 深刻度について

計算を元に、0.0 ~ 10.0で算出され、高い方が緊急性が高いということになります。
ちなみに最近流行りのlog4jは CVSS v3 では10.0のスコアになっていて深刻度が以下の表で認識できると思います。


| 深刻度 | スコア | 
| ------ | ------ | 
|    緊急    |    9.0-10.0    | 
|    重要    |   7.0-8.9     | 
|    警告    |   4.0-6.9     | 
|    注意    |   0.1-3.9     | 

## 勉強後イメージ

脆弱性に対する評価。
やばいやつほど数値が高い。

## 参考

- [Apache Log4j における任意のコードが実行可能な脆弱性](https://jvndb.jvn.jp/ja/contents/2021/JVNDB-2021-005429.html)
- [脆弱性の深刻度をセルフチェック CVSS](https://yamory.io/blog/about-cvss/)
- [共通脆弱性評価システムCVSS概説](https://www.ipa.go.jp/security/vuln/CVSS.html)
【Vue】メソッドや、関数だけ別コンポーネントに切り出して共通化して使用する

# 呼び出す方法

外部に切り出した関数を以下に定義

```ExternalFunc.vue
<script>
  export function externalFunc() {
    return "お前なんかに折れるもんか…ドクロのマークは信念の象徴なんだぞォ";
  }
</script>
```

外部の関数を使用するコンポーネントが以下

```CardForm.vue
<script setup lang="ts">
import { externalFunc } from "../components/ExternalFunc.vue"

function useFunc() {
  console.log(externalFunc()) // 外部の関数を呼び出し => お前なんかに折れるもんか…ドクロのマークは信念の象徴なんだぞォ
}
</script>
```
[py2rb] 予約語

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# 予約語 (Python)
```python
import keyword
print(keyword.kwlist)

['False', 'None', 'True', 'and', 'as', 'assert', 'async',
 'await', 'break', 'class', 'continue', 'def', 'del',
 'elif', 'else', 'except', 'finally', 'for', 'from',
 'global', 'if', 'import', 'in', 'is', 'lambda',
 'nonlocal', 'not', 'or', 'pass', 'raise', 'return',
 'try', 'while', 'with', 'yield']
```
# 予約語 (Ruby)
```ruby
BEGIN    class    ensure   nil      self     when
END      def      false    not      super    while
alias    defined? for      or       then     yield
and      do       if       redo     true     __LINE__
begin    else     in       rescue   undef    __FILE__
break    elsif    module   retry    unless   __ENCODING__
case     end      next     return   until
```
https://docs.ruby-lang.org/ja/latest/doc/spec=2flexical.html#reserved

時々、`end`や`next`が変数やメソッドに使用されて困ることがあります。
> ただし接頭辞$, @、@@が先頭についたものは予約語とは見なされません。

`_`を先頭につけることもよくやります。
# メモ
+ Python の 予約語 を学習した
+ 百里を行く者は九十里を半ばとす