OmniAICreator/Qiita-1.07M huggingface dataset:
Livebook で秘密情報を入力する

## はじめに

Elixir の Livebook 、何でも可視化できて便利ですね

実行コードを残しておけば、誰でもいつでも再現できるのもいいところ
（いずれ Python の Jpyter に取って代わるでしょう）

しかし、パスワードや API キーなど、秘密情報は残すわけにはいきません

```elixir
api_key = "1234"
```

なんて残してしまった日には、まして GitHub にあげてしまった日にはセキュリティインシデントの発生です

では、どうすればよいか、というのが今回の話です

## Kino.input で入力エリアを用意する

というわけで、以下が答えです

`Kino.Input.password` を使います

```elixir
api_key_input = Kino.Input.password("API_KEY")
```

引数は入力エリアのタイトルです

下画像のような入力エリアが表示されます

![スクリーンショット 2022-11-18 20.09.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/107e122a-aa09-5194-2643-679a3f2bbdac.png)

`Kino.Input.password` の場合、入力した文字が●になるので、入力しているときも見られることがありません

![スクリーンショット 2022-11-18 20.13.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/adb7a505-ffb3-0275-ae5a-93d2663fcb17.png)

`Kino.Input.text` の場合は入力した文字が見えてしまいます

![スクリーンショット 2022-11-18 20.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/33507011-b93f-4774-ac01-430d888d6f76.png)

ちなみに、以下のように `default` を指定すると、未入力の状態を指定できます

```elixir
api_key_input = Kino.Input.text("API_KEY", default: "*****")
```

![スクリーンショット 2022-11-18 20.16.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/da00cbc6-4e34-b6ee-a4a2-5534230fbf4d.png)

## 入力した内容を参照する

`Kino.Input.read` で入力した値を参照します

```elixir
auth_header = {"X-API-KEY", Kino.Input.read(api_key_input)}
"dummy"
```

このとき、入力した値が含まれるものを最終行にすると実行結果に表示されてしまうため、
適当なものを最後に入れましょう

ダメな例

![スクリーンショット 2022-11-18 20.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/88ddd0d1-1774-b0ae-bc7f-cf770906ac05.png)

良い例

![スクリーンショット 2022-11-18 20.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/65ec3caf-973b-1a32-fc86-d3e2f0dcadd9.png)

## まとめ

秘密情報には気をつけましょう
Advanced rider assistance system for two wheelers, ボッシュ自動車handbook 11版(157) p.1930

Drive assistance and sensors, Advanced rider assistance system for two wheelers ,  ボッシュ自動車handbook 11版(157)

人生で影響を受けた本100冊。

https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊

http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0-1) 課題と記事一覧new

https://qiita.com/kaizen_nagoya/items/a9d2887bf2a7598dc8e5

# Contents
Motor vehicle, 28
Basic principles, 32
Mathematics and methods, 204
Materials, 258
Machine parts, 354
Joining and bonding techniques, 426
Vehicle physics, 462
Operating fluids, 538
Refrigerants for air-conditioning systems, 591
Drivetrain(駆動系), 594
Internal-combustion engines(内燃機関),642
Management for spark-ignition engines,800
Gasoline-engine operation with alternative fuels, 886
Management for diesel engines, 906
Electrification of the drive, 970
Emission-control and diagnosis legislation, 1042
Chassis systems, 1108
Vehicle bodies,  1310
Comfort and convenience, 1392
Safety systems in the motor vehicle, 1410
Vehicle security systems, 1430
Automotive electrics, 1450
Vehicle electrical systems for hybrid and electric vehicles, 1560
Automotive electronics, 1620
Infotainment 1780
Drive assistance and sensors, 1804
Drive assistance systems 1872
Future of automated driving 1934
Appendics, 1940

#  Advanced rider assistance system for two wheelers , p.1930

## Adaptive cruise control
## Forward collision warning
## Blind spot detection

# Reference
参照なし

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 20221118
Pythonのプログラムをseedを変えながら何回も実行したい

# 0. はじめに
卒論などで実装はできるようになった！あとは何回も実験をしよう！ってなると、Pythonのプログラムをseedを変えながら勝手に何回も繰り返し実行して、その結果を記録してくれたらな、、と思います。
そんなときに、シェルスクリプトを書いて実現してみようというお話です。


(他にも方法はいろいろありますが、個人的にはこれが1番楽な気がしました。が、初学者なので間違っているところやもっとこうするといいぞっていうのがぜひ教えてください、、)

```
実行環境
linux, python3.10.6 
```



# 1. 実行したいプログラムに準備をする

まずは、実行したいプログラムに少し準備をします。
今回は実験結果の配列(下のコードだとhistory)はnumpyを使って.npyファイルに保存したいと思います。
なお、正しく実行できているか確認するためにもtime.time()を使って実行時間を結果の配列に含めておくと便利だと思います。


```Python:sample.py
import numpy as np

#########自分の実行したいコード##########

#今回はhistoryという辞書型の結果を保存
#history = {'train_loss': [0.40233263224363325, 0.32183732837438583, 0.2516081020236015, 0.22328430339694022, 0.1859678439795971, 0.21593394204974176, 0.17237800508737564, 0.17367434203624726, 0.16175111159682273, 0.1389133520424366, 0.11057725325226783, 0.15094957053661345, 0.12318627089262009, 0.13979500029236078, 0.12451138123869895, 0.11403792835772038, 0.11816972605884075, 0.11392765827476978, 0.1022469524294138, 0.10136424899101257], 'validation_loss': [0.37975166263580323, 0.35040774707794187, 0.3559194508075714, 0.33262572576999666, 0.38052910313606264, 0.3622898992061615, 0.32906092183589936, 0.37429458775520325, 0.3865742824077606, 0.35881029706001283, 0.38273151392936705, 0.3649467830657959, 0.34276605443954467, 0.3479218934059143, 0.32179879121780397, 0.3375883677959442, 0.3298368800163269, 0.33175508177280427, 0.34887621765136717, 0.3764280668973923], 'validation_acc': [0.8793, 0.892, 0.8891, 0.9025, 0.8938, 0.8991, 0.9052, 0.8943, 0.8977, 0.9068, 0.9091, 0.9066, 0.9096, 0.9077, 0.9156, 0.9096, 0.9122, 0.9133, 0.9104, 0.9125], 'time': 25.568512439727783}

#とりあえずseedは1で設定
seed = 1

#/home/files/run/resultsというフォルダーにseedn(nは数字)といったseedの数が入ったファイル名で保存
PATH = '/home/files/run/results/seed{}.npy'.format(seed)
np.save(PATH, history)
```



# 2. シェルスクリプトの用意
次に、Pythonのプログラムを実行してくれるシェルスクリプトを書きます。
sedを使って先ほど用意したPythonファイル内のseed = 1の部分を書き換えながら実行してくれるようにします。


```Bash:run.sh
#今回は適当に20このseedを用意
seed_list=(1 16 62 97 105 161 230 356 624 728 905 1014 1130 1299 1336 1557 1616 1728 1922 2022)

for seed in ${seed_list[@]}
do
　　 #実行したいファイル(/home/files/run/sample.py)にあるseed = 1を書き換えてtempファイルに保存
    sed -e "s/seed = 1/seed = $seed/ "  /home/files/run/sample.py > temp

    #tempファイルの実行
    python temp
done
```

シェルにて、次のコマンドで実行できます。
（* sh run.sh で実行するとデフォルトの(?)dashで実行されてしまい、リストの部分にエラーが出ました、、)

```
$ bash run.sh
```

# 3.保存した結果の確認

実行されると先ほど用意していたフォルダーにseed1.npy〜seedn.npyと結果がファイルに保存されているはずです。
これは次のような感じで取り出せます。
あとは出力したりプロットしたり、、numpyなので扱いやすいはずです。
```Python:load_results.py
import numpy as np

seed_list = (1, 16, 62, 97, 105, 161, 230, 356, 624, 728, 905, 1014, 1130, 1299, 1336, 1557, 1616, 1728, 1922, 2022)

for seed in seed_list:
    #結果を保存したファイルのパス
    path = '/home/files/run/results/seed{}.npy'.format(seed)
    history = np.load(path, allow_pickle = True).item()
    print(history)
```

これで簡単に実験できるようになりました！あとは寝てる間にでも回しとけばokです！
「[Vue warn]The data property "" is already declared as a prop. Use prop default value instead.」の対策

# 事象
Vue.jsにて、以下のようなコードで親コンポーネントから子コンポーネントに値を渡した時にコンソールでタイトルのVue warnが表示されました。
```typescript
// 親コンポーネント
...
<child-component :hoge="hoge" />
...
```

```typescript
// 子コンポーネント
<input v-model="localHoge" />
...
@Component
class Hoge {
  localHoge: string | null = null;
  @Prop() hoge: string | null = null;

  created() {
    this.localHoge = this.hoge;
  }
  ...
}
```

## 環境
Vueバージョン：2.7.13
Typescriptで記載
単一ファイルコンポーネントで記載

# 調査
コンソールのwarnを追っていくと、vue.runtime.esm.jsのinitDataという関数でエラーが出ているようでした。
該当箇所はこんな感じ
```typescript
function initData(vm) {
  var data = vm.$options.data;
  data = vm._data = isFunction(data) ? getData(data, vm) : data || {};
  if (!isPlainObject(data)) {
    data = {};
    process.env.NODE_ENV !== 'production' &&
      warn('data functions should return an object:\n' +
        'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', vm);
  }
  // proxy data on instance
  var keys = Object.keys(data);
  var props = vm.$options.props;
  var methods = vm.$options.methods;
  var i = keys.length;
  while (i--) {
    var key = keys[i];
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn("Method \"".concat(key, "\" has already been defined as a data property."), vm);
      }
    }
    if (props && hasOwn(props, key)) { // <---- ここに引っかかってエラーになっていた
      process.env.NODE_ENV !== 'production' &&
        warn("The data property \"".concat(key, "\" is already declared as a prop. ") +
          "Use prop default value instead.", vm);
    }
    ...
```
どうやらpropsとdataで同じプロパティがあると引っかかるようです。

# 原因
原因は子コンポーネントのpropsの定義方法でした。
```typescript
@Prop() hoge: string | null = null;
```
↑こう書くと、内部的にpropsとdata両方に変換されてしまうようです。

以下のように書けばエラーを回避できました。
```typescript
@Prop({default: ''}) hoge?: string | null;
```
(warn文に`Use prop default value instead.`とあったのでヒントは出てたようです...)


参考：https://qiita.com/simochee/items/e5b77af4aa36bd0f32e5#prop など
【Python】挿入ソートを盛大に勘違いしてしまった件

# 経緯

並べ替えアルゴリズムのうち、**挿入ソート**なるものを見つけ実装しようと思った矢先こんな記事に出会った。
（調べると結構上に出てくる）

https://medium-company.com/%E6%8C%BF%E5%85%A5%E3%82%BD%E3%83%BC%E3%83%88/

> * 挿入ソート（基本挿入法）とは**未整列の配列**から1つずつ値を取り出し**整列済み配列**の適切な位置へ挿入していく手法です。
> * 「6」は「7」より小さくて「5」より大きいので、「5」と「7」の間に挿入

なるほど、**新しく配列を用意**して、要素を挿入するときは**自分で適切な場所を探して挿入**するんだな、って解釈した。

ところが、、挿入ソートが**自分の実装と異なるものばかり**であることが発覚した。

> [バケットソート](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%82%BD%E3%83%BC%E3%83%88)でバケツ内の並び替えをするときに、どのアルゴリズムを使うか選択するときに気づいた



```python:myInsert.py
def findInsertIndex(sorted_nums, num):
	for i in range(0, len(sorted_nums)):
		if num <= sorted_nums[i]:
			return i
	return len(sorted_nums) + 1

def insertNums(sorted_nums, num):
	index = findInsertIndex(sorted_nums, num)
	sorted_nums.insert(index, num)

def insertSort(nums):
	sorted_nums = [nums[0]]
	for i in range(1, len(nums)):
		insertNums(sorted_nums, nums[i])
	return sorted_nums
```

# Insertion Sort
これを見て気がついた。

https://www.geeksforgeeks.org/insertion-sort/

みんなの実装とかはこう
```python:Insertion.py
def insertionSort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >= 0 and key < arr[j] :
                arr[j + 1] = arr[j]
                j -= 1
        arr[j + 1] = key
```

それでwikiを調べてみると

https://ja.wikipedia.org/wiki/%E6%8C%BF%E5%85%A5%E3%82%BD%E3%83%BC%E3%83%88

> * **in-place**アルゴリズム
> * まず0番目と1番目の要素を**比較**し、順番が逆であれば入れ換える
> * 配列の場合、前の要素を後ろに**一つずつずらす**

そもそも`in-place`なので、**新しく配列なんて用意しない**し、
挿入ではなく**比較**しながら並び替えるアルゴリズムだったのがわかった。

自分は何も合っていないじゃあないか。。！

# 修正後のコード
これでどうだろ

```python:myInsert.py
def insertNums(nums, index):
	for j in reversed(range(1, index + 1)):
		if nums[j - 1] > nums[j]:
			nums[j], nums[j - 1] = nums[j - 1], nums[j]

def insertSort(nums):
	for i in range(1, len(nums)):
		if nums[i - 1] > nums[i]:
			insertNums(nums, i)
	return nums
```

# あれは何だったんだ

記事をよくみると
> 本記事では、"整列済み"と"未整列"の2つに分け"未整列"から1つずつ"整列済み"へ挿入していく挿入ソート（基本挿入法）について図解で分かりやすく解説していきます。

と書いてあるが、これが**要約的**な意味で言っているなら間違っているとも取れるし、**2種類用意してわかりやすく解説しますよ**なら飲み込める。

自分は前者として解釈してしまった。


# 終わりに
自分みたくメモリとか速度のことを考慮せず、list型メソッドの`insert`とか使ったり、サブルーチン呼び出しまくるコードならまだわかるけど**そもそもの実装方針が異なる記事**に出会うとは思ってなかった。


なんか批判記事みたいになってしまったけど、自分が勝手に勘違いしてそれを修正した記事です。
GitHub ActionsでAnsible lintを実行する

こちらの記事は[Ansible lint Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ansible-lint) 8日目の記事になります。

今回はGitHub ActionsでAnsible lintを実行する方法を考察します。

### Actionライブラリを利用する

GitHub ActionsにはAnsibleコミュニティー公式のAnsible lintを実行するための[Actionライブラリ](https://github.com/marketplace/actions/ansible-lint)があります。

ただし指定できるバラメーターが`パス`のみで非常に扱いにくくなっています。

```yaml:.github/workflows/build.yml
name: Ansible Lint
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Run ansible-lint
        uses: ansible-community/ansible-lint-action@v6
        with:
          path: "playbooks/"
```

### シェルスクリプトで実行する

公式の[Actionライブラリ](https://github.com/marketplace/actions/ansible-lint)の採用は難しいのでシェルスクリプトで対応します。`Galaxy Role`のインストール部分は適宜変更します。

```yaml:.github/workflows/build.yml
name: Ansible Lint
on: [push, pull_request]

jobs:
  ansible-lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3'

      - name: Install Ansible and ansible-lint
        run: |
          pip install ansible ansible-lint

      - name: Install galaxy roles
        run: |
          if [ -f 'roles/requirements.yml' ]; then
            ansible-galaxy install -r roles/requirements.yml
          else
            ansible-galaxy install git+https://github.com/${{ github.repository }},${{ github.sha }}
          fi

      - name: Execulte ansible-lint
        run: |
          ansible-lint

      - name: Show ansible-lint version
        run: |
          ansible-lint --version
          ansible-community --version
```

### その他

GitHub ActionsではAction実行に起動されるVMにAnsibleが初期インストールされています。もし初期インストールされているバージョン以外のAnsibleの利用が必要な場合は再インストールする必要があります。
【SQL初学者】SQLテーブルの結合を理解

# 目次
- [内部結合](#内部結合)
- [外部結合](#外部結合)
- まとめ

今回は職場でSQLを書く機会がありましたので共有させていただきます。
テーブル結合には大きく二つあります。

- 外部結合(INNERJOIN)
- 内部結合(OUTERJOIN)

サンプルデータを用意しました
# 外部結合

### fuluitsテーブル

| id | name | region_id |
|:-:|:-:|:-:|
| 1  | みかん  | 1  |
| 2  | りんご  | 2  |
| 3  | いちご  | 3  |
| 4  | メロン  | 4  |
| 5  | 梨  | 5  |
| 6  | かき  | 1  |
| 7  | さくらんぼ  | 6  |


### regionテーブル

| id | region |
|:-:|:-:|
| 1  | 和歌山  |
| 2  | 青森  |
| 3  | 栃木  |
| 4  | 茨城  |
| 5  | 千葉  |
| 6  | 山形  |
| 7  | 広島  |

# 内部結合(INNERJOIN)
- 両テーブルで指定したカラムの値が一致するデータのみを抽出する方法です
- 基本構文
    - SELECT * FROM fluits(テーブル名１) INNER JOIN region(テーブル名２) ON region id = fuluits region_id;
- 結果

| id | name | region_id | id| region |
|:-:|:-:|:-:|:-:|:-:|
| 1  | みかん  | 1  | 1  | 和歌山  |
| 6  | かき  | 1  |  1 | 和歌山  |
| 2  | りんご  | 2  | 2  | 青森  |
| 3  | いちご  |  3 | 3  | 栃木  |
| 4  | めろん  |  4 | 4  | 茨城  |
| 5  | 梨  |  5 | 5  | 千葉  |
| 7  | さくらんぼ  | 6  | 6  | 山形  |

# 外部結合(OUTERJOIN２種類)
- LEFT JOIN
- RIGHT JOIN

### LEFT JOIN
- FROM句の後ろに記述するテーブルが軸の結合方法
- 基本構文
    - SELECT * FROM fluits LEFT JOIN region ON region id = fluits region_id;
- 結果

| id | name | region_id | id| region |
|:-:|:-:|:-:|:-:|:-:|
| 1  | みかん  | 1  | 1  | 和歌山  |
| 6  | かき  | 1  |  1 | 和歌山  |
| 2  | りんご  | 2  | 2  | 青森  |
| 3  | いちご  |  3 | 3  | 栃木  |
| 4  | めろん  |  4 | 4  | 茨城  |
| 5  | 梨  |  5 | 5  | 千葉  |
| 7  | さくらんぼ  | 6  | 6  | 山形  |

INNERJOINとの違いが伝えられんな、、INNERJOINと違うのはカラムがある値だけ抽出するのではなく、軸にあるテーブルすべての情報を表示する

### RIGHT JOIN
- RIGHTJOIN句の後ろに記述するテーブルが軸の結合方法
- 基本構文
    - SELECT * FROM fluits RIGHT JOIN region ON region id = fluits region_id;
- 結果

| id | name | region_id | id| region |
|:-:|:-:|:-:|:-:|:-:|
| 1  | みかん  | 1  | 1  | 和歌山  |
| 6  | かき  | 1  |  1 | 和歌山  |
| 2  | りんご  | 2  | 2  | 青森  |
| 3  | いちご  |  3 | 3  | 栃木  |
| 4  | めろん  |  4 | 4  | 茨城  |
| 5  | 梨  |  5 | 5  | 千葉  |
| 7  | さくらんぼ  | 6  | 6  | 山形  |
| null  | null  | null  | ７  | 広島  |

これは、条件で指定した値をreginテーブルから全て取ってきている。ご存じ通り広島の果物はfluitsテーブルには無いため、NULLの値が設定されている。
このように、OUTERJOINは条件に指定した値を全て取ってくるのが特徴である。

# まとめ
そもそも大規模システムだと、格納するデータや役割によってデータベースを分けるのでJOINが使用できないという話もあるっぽいな。。
makeコマンドについて

## makeコマンド
ソースコードをコンパイルしてソフトウェアの実行ファイルを作る（ビルド）するために、Linuxでよく使われるコマンド。
オプションなしで実行する他にターゲット指定することもでき、指定するターゲットによって事前にMakefileで設定されたさまざまな動作を自動で行わせることができる。

### makeコマンドオプション一覧（代表的なもの）

- _make_
引数にターゲットを指定しないと、自動的にmake allとした時の動作になる。

- _make all_
さまざまな処理が行われる。
主に依存関係のチェック、カーネル本体とモジュールのビルド、不要になった一時ファイルの削除が自動的に実行される。 

- _make mrproper_
設定ファイルを含めてソースディレクトリ内を初期化する。
カーネルソースをダウンロードした後に実行し設定ファイルを確実に初期化しておくことが推奨される。

- _make clean_
設定ファイルは残してソースディレクトリ内の一時ファイルなどを削除する。

- _make modules_install_
ビルドし終わったカーネルモジュールを実際に現在のシステムにインストールする。
これを行わないとカーネルがモジュールを認識できずに使えない。
GitHubでIssueの削除はできなくても、重複としてマークしたり、計画外としてクローズしたりはできる

## この記事の概要

GitHubで、組織が所有するリポジトリでは、大抵の人はIssueを削除できません。[^deleting-an-issue]
間違えて作ったIssueや要らなくなったIssueも、Closeするしかないです。

[^deleting-an-issue]: 組織リポジトリの場合、管理者または所有者のアクセス許可を持つアカウントのみがIssueを削除できます。
https://docs.github.com/ja/issues/tracking-your-work-with-issues/deleting-an-issue

しかし、ちゃんと完了したIssueのようにクローズするのも若干気持ち悪いです。
「訳あってクローズしたけど、不要なIssueだった」ことがわかる方法を記事にしました。

## Mark as a duplicate

コメントの本文に`Duplicate of`と記載し、その後にIssueあるいはPull Requestの番号を入力して投稿します。
Pull Requestに`Close {Issue番号}`と書くのと同じ書式です。

これにより「重複」としてマークができます。

https://docs.github.com/ja/issues/tracking-your-work-with-issues/marking-issues-or-pull-requests-as-a-duplicate

## Close as note planned

コメントの`Close issue`の横の下向き矢印をクリックし`Close as not planned`を選択してからクローズします。
クローズされる他、Issue検索の際に`reason:"not planned"`と入れると絞り込みができます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/697351b5-6b27-2057-ac12-a8dbf0e3c073.png)


https://github.blog/changelog/2022-03-10-the-new-github-issues-march-10th-update/#%F0%9F%95%B5%F0%9F%8F%BD%E2%99%80%EF%B8%8F-issue-closed-reasons

## 最後に

これまでは「普通にクローズすると、まるでちゃんと完了したIssueみたいに見えて嫌だなあ」と思い、コメントに理由を書いていました。
（◯◯の理由で実施しないことになった。など。）

あくまでメモとしての記載で対症療法的だったのが、公式にサポートされて非常にありがたいです。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox

Devトークでのお話してくださる方も募集中です！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/489
コントローラのモードについて

# IAP

IAPとは、InstantAPの略で、コントローラがいらないAPのことです。このAPは管理方法に基づいて、RAPとCAPの2種類に変えることができます。

## CAP

CAPは、CampusAPの略です。これはコントローラーというAPを制御する機器を設置してAPを管理する形態です。これは、必ず物理コントローラーを設置する必要がなく、仮想コントローラーでも代用可能です。

## RAP

RAPは、RemoteAPの略です。これは、APが置かれている場所にコントローラーを設置するCAPのタイプではなく、APとコントローラーの場所が遠く離れているときに使う形態です。例えば、会社が社内情報を守るためにセキュリティやらなんやらの設定をAPにしたいとします。社員全員が会社に来れば、CAPでいいのですが、今はたいていの人たちがリモートワークしています。そんな時に、一人一人が家でAPの設定をするのは面倒なので、会社にコントローラーを置いて家のAPをリモートで制御してもらうのが楽なのです。

## Mesh AP

Mesh APとは、他の無線機器を踏み台にしてコントローラに接続するCAPのこと。つまり、それ単体ではコントローラに接続することができず、他の無線機器を経由する必要がある。

## Mesh Portal

Mesh Portalとは、有線で無線を出す機器に接続して、他の無線機器を踏み台にしてコントローラに接続する機器のこと。

## AM(Air Monitors)

常に無線環境を見張って、無線情報とIDSの情報を収集します

# IDSとIPSについて

- IDSとは、Intrusion Detection Systemの略です。システムやネットワークに外部から不正なアクセスやその兆候が確認できた場合に管理者に通知するシステムのことです。
- IPSとは、Intrusion Prevention Systemの略です。IDSは通知するまでですが、IPSは不正アクセスを防御する役割があります。

# コントローラのモード

## Mobility Master(MM)

管理、制御、転送機能を担います。

これには、AirMatchの機能が備わっている。AirMatchとは、すべてのAPから電波環境のデータを収集して、それぞれのAPの電波が安定するように管理する機能のこと。

従来は、ARM(Adaptive Radio Management)で電波環境を調整してきた。ARMは、それぞれのAPがAP内で最適な電波を計算して電波を変えること。これだと、周辺の電波環境に大きく左右されるから電波が安定しなくなる。

## Mobility Controller(MC)

これは、Managed Device(MD)またはManaged Node(MN)と呼ばれる。アクセスポイントとクライアントのトラフィックを処理します。他のMCと連携することで高可用性を提供します。連携することで、フェイルオーバーが起こった時に対処できます。

## Standalone

Mobility MasterをつけていないMobility Controllerのようなもの。実際には、Mobility Controllerのように動かない。8.x の良さを失ってしまいます。

# MMとMCを使ったアーキテクチャ(Aruba OS 8.x)

- まずMMは会社の本部に一つ設置します。
- そして、MCは会社の本部、支社、データセンターなどに設置します。
- MMにAPの共通設定を記述します。すると、MCはその設定＋そのMC独自の設定を合体させて、APに設定を付与します。
- こうすると、APを設置するときにそれぞれにルールを設定する必要がなくなります。
- 注意しなければならないのは、家のAPと会社のAPを分けて考えないといけません。このアーキテクチャが生きてくるのは、会社のAPであって家のAPではありません。なぜなら、会社にはたくさんのAPがあり、家にはたいてい１つしかAPがないからです。

# Master Controller(6.x)とMobility Master(8.x)の違い

- Master Controllerとは、１つのAPを、他のAPを監視するコントローラにしたデバイスのこと
- Master Controllerは、物理的なデバイスが必要ですが、MMは物理的デバイスも仮想デバイスもOK
- Master Controllerは、管理しているAPを停止できますが、MMはできない
- Master Controllerは、部分的にルールをAPに付与できます。MMは全てのルールをAPに付与できる。(Master ControllerはVLANの設定ができません)
- Master Controllerは、APの設定を確認しませんが、MMは確認してくれる
【VSCode】code .できない時の対処法

ターミナルで<code>npx create-react-app</code>などでプロジェクトフォルダが作成された後
<code>cd project
code .</code>
でprojectディレクトリでVSCodeを開くことができるはずだが
__<code>bash: code: command not found</code>__
とメッセージが返ってくるので調べてみた。
どうやらMac環境ではPATHを通す作業が必要だそうで、対処法を紹介します。

<h2>code .でVSCodeを起動できない場合の対処法</h2>
<ol>
<li>VSCodeを開く</li>
<li><code>Command＋Shift+P</code>でコマンドパレットを開き、Shellと入力</li>
<li><strong>シェルコマンド:PATH内に'code'コマンドをインストールします</strong>を選択<br></li>
<li><strong>シェルコマンド'code'がPATHに正常にインストールされました。</strong> と表示されたら完了</li>
</ol>

これで無事<code>code .</code>が使用できます。
初めての投稿

初めましてリクです。
この度修士１年の11月にしてやっとqiitaに初めて投稿してみようと思います。
どう考えても始める時期遅いやろと思っても暖かく見守ってあげてください。
<br />
ところでこのマークダウン記法まじでどうやって書くんですか
##うわ大きくなった
て書こうとしたのに全然見出しになりません。


qiita マークダウン　見出しにならない🔎で検索してみたら、どうやら#の後にスペースが必要なようです。

## うわほんとに大きくなった！

すごい。
ほんとに大きくなるじゃん。
てことで、今後まずは現在leetcodeで勉強しているので、解いた問題を自分なりに解説してみて死ぬほど三日坊主な自分が続けられるかどうか試してみます。

ではまた
初期RAMディスクとは

## 初期RAMディスクとは
    Linuxシステム起動中にブートローダによってメモリ上にロードされる、小さなルートファイルシステム。
    普段は[アーカイブ](リンクURL)された一つのファイルで、必要な時にメモリ上でツリー構造に展開される。
    
#### アーカイブ形式
    初期RAMディスクのアーカイブ形式は２つある。
    1.initrd形式
        ループバックデバイスであり、ファイルシステムイメージをgzip圧縮したもの。
    2.initramfs形式
        cpioアーカイブをgzip圧縮したもの。現在はこの形式が主流。
【OpenLayers】ラインデータを表示する

## はじめに
この記事は#30DayMapChallenge2022 18日目の記事です。
テーマはColour Friday: Blueです。
OpenLayersを使って栃木県の河川のラインデータを表示してみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## OpenLayersとは
簡単にダイナミックなマップを設置することができるJavaScriptライブラリ
地図タイル、ベクトルデータ、マーカーを表示することができる
フリーかつオープンソースで、2条項のBSDライセンス（FreeBSDとしても知られています）の下でリリースされている
執筆時の最新バージョンはv7.1.0でした


## ラインデータを取得する
今回はGeoJSONを使って表示してみます。
国土数値情報から栃木県の河川データをダウンロードします。
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-W05.html
中身はシェープファイルだったので、QGISでGeoJSONに変換します。

## ラインデータを表示する

```index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>サンプル</title>
        <meta name="description" content="サンプルです" />
        <link href="style.css" rel="stylesheet" />
        <!-- OpenLayers -->
        <script src="https://cdn.jsdelivr.net/npm/ol@v7.1.0/dist/ol.js"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.1.0/ol.css" />
    </head>
    <body>
        <div id="map"></div>
        <script src="main.js"></script>
    </body>
</html>
```

```style.css
body {
    margin: 0;
    padding: 0;
}
#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}
```

```main.js
const style = {
    MultiLineString: new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'blue',
            width: 3,
        }),
    }),
};

const styleFunction = function (feature) {
    return style[feature.getGeometry().getType()];
};

const vectorSource = new ol.source.Vector({
    url: 'data/tochigi_river.geojson',
    format: new ol.format.GeoJSON(),
    attributions: 'データの出典：国土数値情報（河川データ）（国土交通省）',
});

const vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    style: styleFunction,
});

const map = new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],
    view: new ol.View({
        center: ol.proj.transform([139.8825316, 36.5551416], 'EPSG:4326', 'EPSG:3857'),
        zoom: 12,
    }),
    target: 'map',
});
```

ラインデータのスタイルを定義します
GeoJSONを読み込み、スタイルを設定します。
Mapオブジェクトに作成したレイヤを追加します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/f9d3cd47-14de-c4f1-cf0d-3b250787145d.png)

ラインデータを表示できました！
思ったよりも川多いですね！


## 参考文献
https://openlayers.org/en/latest/examples/geojson.html
UIscrollViewについて

# UIScrollViewの超基本使い方イメージ
1\. Viewの上にScrollViewを載せる（addSubViewする）　
2\. ScrollViewにcontentView(スクロールさせたい対象)を載せる（addSubViewする）
3\.scrollViewのcontentSizeにcontentViewのサイズを教える

![名称未設定のノート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519519/795f2d99-5943-d68d-46ee-962d6b7e2903.png)
Linux基礎知識

## Linux起動の流れ
    - 電源on
    - BIOS/UEFI起動しハードウェアをチェック後にMBRからブートローダを起動
    - ブートローダでは、ハードディスク上からカーネルをメモリ上へ読み込む。
    - カーネルは、メモリの初期化、システムクロックの設定などを行う
    - initはシステムの初期化スクリプトを実行し、ランレベルに応じたデーモンを起動
    - ブートが完了すると、Linuxへのログインプロンプトが表示され、起動処理終了。

### BIOSとは
    電源投入後に一番初めに立ち上がるプログラム。

### MBRとは
    HDDなどのストレージの最も先頭にある、起動に必要なプログラムや情報をきろくした小さな領域。

### ブートローダとは
    OSを読み込むためのプログラム。MBRに保存されている。

### カーネルとは
    CPUやメモリなどシステム資源の管理やデバイスの制御、プロセスのスケジューリングなどを行う、文字どおりにLinuxオペレーティングシステムの核となるプログラム。
    ブートローダにより初期RAMディスクと併せてメモリ上にロードされる。
[wp-cli] 予約投稿が失敗したときにリカバリさせるためのシェルスクリプト

こんな感じのスクリプトをサーバの cron で毎分実行すれば、きっと大丈夫
`post_status` が `future` で、投稿日時が1時間前〜現在までの投稿があったら、`wp_publish_post()` を実行して投稿処理を実施します。

```
#!/bin/bash
WP_ROOT=${1:-/var/www/html}
WPCLI="wp --path=${WP_ROOT}"
table_prefix=$(${WPCLI} eval 'global $table_prefix; echo $table_prefix;')
post_ids=$(${WPCLI} db query "select ID from ${table_prefix}posts where post_status = 'future' and post_date BETWEEN (NOW() - INTERVAL - 1 hour) AND NOW() order by post_date_gmt;" | awk '{print $1}' | grep -v 'ID')
for post_id in ${post_ids}; do
    echo ${post_id}
    ${WPCLI} eval "wp_publish_post(${post_id});"
done
```
Stripeカスタマーポータルをユーザーまたはユースケースごとにカスタマイズして提供する


Stripeでは、ノーコード・ローコードに顧客マイページを作成できる「カスタマーポータル」が利用できます。

![スクリーンショット 2022-11-18 16.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/47d7a2c4-9fa0-42f3-2f19-bc1b80783f50.png)

カスタマーポータルでユーザーが閲覧・操作できる内容については、ダッシュボードから設定が可能です。

![スクリーンショット 2022-11-18 16.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/95ebed0f-7fff-e6c3-0e10-242016880232.png)

## ユーザーごとに閲覧・操作範囲を変更する方法

チームで利用することを想定したシステムでは、「契約ユーザーは契約内容を変更できるが、それ以外のユーザーには閲覧以外の操作を禁止したい」などの要件が発生します。

この場合、Stripeのカスタマーポータルでは、APIを利用して複数の設定を利用できます。

```js
    const config = await stripe.billingPortal.configurations.create({
      business_profile: {
        headline: '請求履歴閲覧用',
      },
      features: {
        invoice_history: {
          enabled: true,
        },
      },
    });

{
  "id": "bpc_1xxxxx",
...

```

APIで設定する場合、明示的に`enabled: true`を設定していない項目は操作できません。

APIで作成した設定を適用するには、作成した設定のID(`bpc_xxx`)をカスタマーポータルセッション作成時のIDとして設定します。

```diff_javascript
    const session = await this.stripe.billingPortal.sessions.create({
+      configuration: "bpc_1xxxxx",
      customer: 'cus_xxxx'
    })
```

上記の設定の場合、請求履歴と契約中のサブスクリプション情報の閲覧だけが可能なマイページが表示されます。

![スクリーンショット 2022-11-18 17.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/226099a8-501f-aa16-a9bc-0d26aa6c295e.png)

サブスクリプションの休止やキャンセル・決済方法の更新などを有効化する設定を追加してみましょう。

```diff_javascript

    const config = await stripe.billingPortal.configurations.create({
      business_profile: {
        headline: '請求履歴閲覧用',
      },
      features: {
        invoice_history: {
          enabled: true,
        },
+        payment_method_update: {
+          enabled: true,
+        },
+        subscription_cancel: {
+          enabled: true,
+        },
+        subscription_pause: {
+          enabled: true,
+        }
      },
    });
```

新しい設定でカスタマーポータルのセッションを開始すると、表示内容が変化します。

![スクリーンショット 2022-11-18 18.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/2933fbbe-f1ba-9877-11f5-ee484e61c248.png)

## 認証系サービスなどと組み合わせて活用しよう

アカウントの親子関係や権限設定を持つサービスでは、自前のDBや認証系サービスに権限情報を保持しています。

これらのデータと、カスタマーポータルの設定IDの関連付けを行うことで、「管理者はカスタマーポータルの機能をフルに利用できる」「一般ユーザーは、閲覧や請求書PDFのDLのみ」のようなマイページの権限設定を簡単に実現できます。

## 関連ドキュメント

https://stripe.com/docs/billing/subscriptions/integrating-customer-portal?platform=billing#customize

https://stripe.com/docs/customer-management/integrate-customer-portal

## [PR] Stripe開発者向け情報をQiitaにて配信中！
2021年12月よりQiitaにて、Stripe開発者のためのブログ記事更新を開始しました。

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について随時更新してまいります。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)
【1台3役】RayCastを使ってみた&HotKey紹介

## これまで使用してきたアプリ
#### ShiftIt
Mac用の画面分割アプリです。

**control(^)** + **command(⌘)** + **option(⌥)** + αでアプリケーションのウィンドウをマウスを使わずに移動・配置できるアプリです。
最初からキー設定済みなのでインストールすればすぐ使えます。

https://github.com/fikovnik/ShiftIt

#### Clipy
コピーした文章や画像などを30件記憶し、ショートカットキーで選択してペーストできる
クリップボード拡張アプリです。

https://clipy-app.com/

## なぜRayCastに変更したのか
1. 上記アプリの機能を一つにまとめられるから
2. PC内検索をSpotlightから変更したかった
以前はAlfredがランチャーアプリケーションとしてよく知られていましたが、アプリケーションをたくさん入れたくない自分にとっては機能が多くて使いこなすこともないだろうと導入を見送っていました。

https://www.alfredapp.com/

今回RayCastを導入することで上に挙げた点を一気に解決できるとのことで、環境設定を行いました。

## 導入と設定

競合サイト(Zenn)になりますが以下を参考にさせていただきました。

https://zenn.dev/toono_f/articles/45d2a49650ebf9

### 拡張機能
Google Chromeのブックマークも検索結果に含めることができるを**Browser Bookmarks**をインストール

https://www.raycast.com/raycast/browser-bookmarks

### HotKey(ショートカットキー)のご紹介
**ShiftItで使用していたショートカットキーを設定**
1. ShitItをアンインストールする前に、キー設定をメモしておく
   私はスクショで保存しました。
![68747470733a2f2f7261772e67697468.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/3847e19e-003a-25db-1043-4d7865113151.jpeg)
※保存した画像を削除していたため、[ShiftItのGitHub](https://github.com/fikovnik/ShiftIt)の画像をお借りしています。

2. RayCastを立ち上げる(インストール直後だと**option(⌥)** + **v** 、後で変更できます)
3. **command(⌘)** + **,** で設定を開き、**Extensions**を選択
![スクリーンショット 2022-11-18 15.59.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/10d34b2b-9235-9a8c-36dc-0d83eb2bef28.png)
4. 下にスクロールして**Window Management**を開く。
変更したい箇所のHotKeyの上をクリックし、1でメモしたキーを押してEnterキーを押して確定
![スクリーンショット 2022-11-18 17.18.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/ea709828-2a85-273c-9ae4-410fe1a46f46.png)
![スクリーンショット 2022-11-18 16.29.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/f2f54562-11fc-6e38-edc1-e3006089d2b0.png)
![スクリーンショット 2022-11-18 16.30.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/8a72db10-1007-3aab-83da-5b69c1d3a856.png)
![スクリーンショット 2022-11-18 16.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/c794db13-077d-c72e-ca35-047a14d1c1aa.png)

**その他**
**Clipy**の機能はClipboard History(**option(⌥)** + **v**)で使用可能です。

Enterキーを押すと右側(画像で赤枠囲った部分)が貼り付けされ、上下キーで選択してEnterキーを押せば過去分を貼り付けることができます。
![スクリーンショット 2022-11-18 17.49.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051129/b7c51fa7-ddca-4511-868d-b2eaca2888aa.jpeg)
開発機のMACで定期的に実行すると良いもの+備忘録

:::note alert
XcodeやAndroidStudioを使うアプリケーション開発者での開発用PCの内容になります。基本的にCommandでのアップデートの内容になり、環境によりアップデートをしたら動かなく可能性はあるので、十分確認をして実行してください。
:::

## Homebrew
### 更新系
- Homebrew自身の更新（インストールパッケージの更新はしない）
```
$ brew update
```
- インストールパッケージを含めての更新
```
$ brew upgrade
```
- 各インストールパッケージの更新可能かどうか
```
$ softwareupdate --list
```

### 問題のチェック
```
$ brew doctor
```
実行をするとWARNINGでXcode-CommandLineToolsが古い、Gitが古い、Pathが通ってないなどの情報が出るので必要があれば実行すると良い

## RubyGems
### 更新系
- RubyGems自体の更新
```
$ sudo gem update --system
```
- 失敗する場合などはインストール先を指定する
```
$ gem update --system -n /usr/local/bin
```
- 必要があればbundlerも更新する
```
$ gem update bundler
```

## CocoaPods
### 更新系
- CocoaPods自体のアップデート
```
$ gem update cocoapods
```
- アップデートの失敗時はアンインストール＋インストール
```
$ gem uninstall cocoapods
$ gem install cocoapods
```

- アップデート後に実行
```
$ pod setup
```

- podのリポジトリのアップデート
```
$ pod repo update
```

- podバグった時用
実行をするとpod統合を解除される（podfile,podfile.lockは残る）
```
$ pod deintegrate
```

## Xcode Command Line Tools
### 更新系
- homebrew経由であれば softwareupdate -i に 'Label' を入れる形で更新
```
$ softwareupdate --list
Software Update Tool

Finding available software
Software Update found the following new or updated software:
* Label: Command Line Tools for Xcode-14.1
	Title: Command Line Tools for Xcode, Version: 14.1, Size: 687455KiB, Recommended: YES, 
$ softwareupdate -i "Command Line Tools for Xcode, Version: 14.1"
```
- 複数のXcodeが入っており、実行するXcodeのバージョンを入れ替える場合
```
$ xcode-select --switch [Xcode.appのpath]
```

## 参考サイト
- [Command Line Toolsをアップデートする](https://qiita.com/imsaku/items/c2a3d914c9569fd3adb9)
- [pod install と update の違い。あと deintegrate](https://daisuke-t-jp.hatenablog.com/entry/2020/05/10/pod-install-or-update)
JavaによるXMLとExcelのワークブックの相互変換

XML(Extensible Markup Language)は、ハイパーテキストマークアップ言語であり、ファイル形式の一つである。XMLは、ラベルをカスタマイズできる、拡張性がある、読みやすく編集しやすい、伝送しやすいなどの特徴があり、アプリケーション間のデータ交換に最もよく使われるツールになっている。マイクロソフトのOpenXMLのおかげで、ExcelもXMLベースの文書形式をサポートしており、開発者が表を伝送したり操作したりするのに便利である。しかし、一般ユーザーにとって、表ファイルはまだ読み取りと編集に便利なxlsまたはxlsx形式に変換する必要があります。この記事では、無料の [Free Spire.XLS for Java](https://jp.e-iceblue.com/introduce/free-spire-excel-for-java.html) を使用して、**XMLファイルをExeclワークブックに**、**ExcelワークブックをXMLファイルに変換**する方法を紹介します。

- [ExcelワークブックをXMLファイルに変換する](#excelワークブックをxmlファイルに変換する)
- [XMLファイルをExcelワークブックに変換する](#xmlファイルをexcelワークブックに変換する)

## 【依存関係の追加】
> **この方法は、無料のFree Spire.XLS for Javaが必要ですので、先にjarファイルをインポートしてください。**

### 1. Maven

Maven を使用している場合、プロジェクトの pom.xml ファイルに以下のコードを追加することで、簡単にアプリケーションに JAR ファイルをインポートすることができます。

```XML
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls.free</artifactId>
        <version>5.1.0</version>
    </dependency>
</dependencies>
```

### 2. 公式サイトよりJarファイルをダウンロード

まず、[Free Spire.XLS for Java](https://jp.e-iceblue.com/download/free-spire-excel-for-java.html) の公式サイトよりzipファイルをダウンロードします。zipファイルを解凍し、libフォルダの下にあるSpire.Xls.jarファイルを依存関係としてプロジェクトにインポートしてください。

## ExcelワークブックをXMLファイルに変換する

Spire.XLS for Javaを使用して、ExcelワークブックをXMLファイルに変換する詳細な手順は以下の通りです。

- **Workbook** クラスのオブジェクトを作成します。
- **Workbook.loadFromFile()** メソッドで、Excelワークブックを読み込みます。
- **Wordbook.saveToFile()** メソッドでワークブックをXMLファイルに変換し、保存します。

**Java**

```Java
import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;

public class convertExcelToXML {
    public static void main(String[] args) {

        //Workbook クラスのオブジェクトを作成する
        Workbook workbook = new Workbook();

        //Excelワークブックを読み込む
        workbook.loadFromFile("在庫・受注情報.xlsx");

        //ワークブックをXMlファイルに変換して保存する
        workbook.saveToFile("ExcelからXMLへの変換.xml", FileFormat.XML);
    }
}
```

### 【出力されるXMLファイル】

![ExcelワークブックをXMLファイルに変換する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/5ab92f41-db89-a01a-f1a5-92d050a64a2c.png)

## XMLファイルをExcelワークブックに変換する

どちらの変換も手順は同じです。 XMLファイルをExcelワークブックに変換するには、次のように操作します。

- **Workbook** クラスのオブジェクトを作成します。
- **Workbook.loadFromXml()** メソッドでXMLファイルを読み込みます。
- **Workbook.saveToFile()** メソッドで、XMLファイルをExcelワークブックに変換して保存します。

**Java**

```Java
import com.spire.xls.FileFormat;
import com.spire.xls.Workbook;

public class convertXMLToExcel {
    public static void main(String[] args) {
        //Workbook クラスのオブジェクトを作成する
        Workbook workbook = new Workbook();

        //XMLファイルの読み込み
        workbook.loadFromXml("ExcelからXMLへの変換.xml");

        //XMLファイルをExcelワークブック文書として保存する
        workbook.saveToFile("XMLからExcelへの変換.xlsx", FileFormat.Version2016);
    }
}
```

> **この記事を読んだ後、あなたはXMLとExcelワークブックの間の相互変換に関する基本的な理解を持っているかもしれません。もし、まだ何か質問があったり、Free Spire.XLS for Javaについてもっと知りたい場合は、[Spire.XLS Forum](https://www.e-iceblue.com/forum/spire-xls-f4.html)にアクセスしてください。**
GitHubとSlackの連携

#### GitHubをチャンネルに連携
GitHubと連携したいSlackチャンネルに以下を送信
```
/invite @GitHub
```
#### 特定のリポジトリと連携
Slackチャンネルに以下を送信
```
/github subscribe GitHubのユーザー名/リポジトリ名
```

#### 通知のon/off
通知をonにしたいときは以下のように「subscribe」を含んだコードを送信。
<b>※一行ずつ送信すること</b>
```
/github subscribe GitHubのユーザー名/リポジトリ名 comments
/github subscribe GitHubのユーザー名/リポジトリ名 reviews
```
通知をoffにしたいときは以下のように「unsubscribe」を含んだコードを送信。
<b>※一行ずつ送信すること</b>
```
/github unsubscribe GitHubのユーザー名/リポジトリ名 pulls
/github unsubscribe GitHubのユーザー名/リポジトリ名 commits
/github unsubscribe GitHubのユーザー名/リポジトリ名 releases
```

#techcamp136期
Excel(VBA)でIEを自動化する方法と罠

仕事のによっては、偶にセキュリティ制限がかなり厳しい所があるんでしょう。

普段Python＋Seleniumで簡単にブラウザーを自動化操作する方法は、セキュリティの制限により、Pythonがインストールできないか、Seleniumライブラリのインストールできないか、または、Chrome/Edge/Firefoxなどのブラウザーがないから、使えなくなります。

この時はExcelのVBAを使ってIEを自動化しましょう！どういう環境でもほとんどExcelがあるし、IEがWindowsでデフォルトのブラウザーなので、勿論あります。

昔々、VBAを触ったことがあり、地味なIDEなのでなんか前世代の言語で使いにくいかと思いました。今回真面目に使ったら意外的に使えるじゃんと思っていましたね。
Excelファイル中のデータの読み取りはすごく簡単のほか、文法も簡単だし、コード補完もあるし、改行なども自動認識できるし、なんかPythonと意外的に似ているイメージでした。とはいえ、前世代の言語は実事なので、罠もありました。

# 罠

## 0、型を使用する前にインポートが必要
「0」番にした理由は、罠ではないですが、知らないとあれれくらいです。
「Visual Basic > ツール > 参照設定...」から`Microsoft Internet Contols`と`Microsoft HTML Library`をインポートすれば、下記の変数を定義する時は具体的な型で定義できます。
```vb
Public IE As InternetExplorer
Public DOC As HTMLDocument
```

### 1、IEのセキュリティ設定
IEは Protect Mode またはセキュリティレベルが低い以外の場合、下記みたいなエラーが表示されます。
```bash
Run-time error 'xxxxxxx': Automation Error The object involved has disconnected from it clients.
```

解決案は幾つありますが、私は下記の案を採用しました。IEインスタンスを作成する時、`New InternetExplorer`の代わりに`New InternetExplorerMedium`を使います。
```vb
Set IE = New InternetExplorerMedium
```

### 2、必須フィールドのValue設定は認識できない
画面上の入力欄などの必須フィールドの`.Value`属性を設定しても未設定と見做すことがあります。HTMLソースを見ても設定ができている状態なのに。。。
解決案は、`.Value`属性の設定の代わりに`SendKeys`を利用します。
```vb
Public Sub SetValue(ele, value)
    ele.Focus
    Application.Wait (Now + TimeValue("00:00:01"))
    SendKeys value
    Application.Wait (Now + TimeValue("00:00:01"))
End Sub
```

### 3、日本語入力問題
上記の **2** の`SendKeys`で値を設定する方法は、日本語の設定はできないです。
解決案は簡単で、`.Value`属性を設定したあと、上記の`SetValue`関数で一つスペースを入れます。

### 4、`Wait`が重要
上記のソースコードを見ても`Wait`が多いですね、本来は下記のコードでロード未完了の画面を待てますが、実際に使用する時何かの原因でロード未完了のままに次のコードが実行されてしまいますね。
```vb
IE.navigate "https://www.google.jp"
Do While IE.readyState < READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
```
また、画面上のポップアップやプルダウンなどのアニメーションがある場合、すぐには後ろの操作を実行すると対象が見つからない可能性があります。
そのため、`Wait`がすごく重要です、疑えるところは`Wait`を入れましょう！
```vb 
Application.Wait (Now + TimeValue("00:00:01"))
```

# 感想
環境上は何もない、途方に暮れる時、ExcelとIEはきっとあるでしょう、この二つものがあればなにかなるでしょう！
「この猫なに猫？」APIをPythonでたたいてみた!

# はじめに
今回は[こちら](https://metadata.co.jp/apis/what-cat/detail.html)の「この猫なに猫？」APIをPythonからたたいてみます。

# 開発環境
+ MacBook Pro (13-inch, 2018)
+ macOS Monterey 12.3.1
+ Visual Studio Code 1.73.1 
+ Python 3.9

# それでは実際にたたいてみます

### 仕様書
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/17e545c5-6e06-3c23-c5df-4dcf7a0ed106.png)

このURLに識別したい画像をPOSTすると結果がJSON形式で返ってきます。


### 実行するには
「この猫なに猫？」APIを利用するにあたって、ユーザー登録が必要です。

「ユーザー名」「メールアドレス」「パスワード」を入れて**singup**をクリックし、届いたメールから認証すれば登録完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/6405a88d-d6b0-ee5d-6982-4e925a8fb542.png)

調べたい猫の画像を用意したら実際に実行してみます！
ちなみに今回はスコティッシュフォールドの画像を準備しました。
![cat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/415ce205-2b60-9691-7712-b85a77ccf59f.jpeg)

## まずはターミナルからcurlコマンドで叩いてみる

```Python
curl -u xxx:yyy -F "image=@cat.jpg" http://whatcat.ap.mextractr.net/api_query
#xxx : ユーザー名
#yyy : パスワード
```
`image@=`の後には画像ファイルの名前を記載します。

そして結果がこちら
![スクリーンショット 2022-11-18 13.04.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/aa7ad7b7-aaac-622d-6f00-41ee913371c5.png)

上位5種の猫種類とその確立値が出力されました！
スコティッシュフォールドの確率値が1.0となっているので、予測通りになっています。

## 続いてPythonから叩いてみる
今回はRequestsのPOSTメソッドを使っていきます。

```
pip install requests
```
上記のように`pip`でインストールしておきます。

```what-cat.py
import requests

url = "http://whatcat.ap.mextractr.net/api_query"
file = {
    'image': open('cat.jpg', "rb")
}
user_name = "xxx"
user_pass = "yyy"

response = requests.post(url, files=file, auth=(user_name,user_pass))
print(response.json())
```

`file`に読み込みたい画像ファイルを置きます。
`user_name`と`user_pass`にはそれぞれユーザー名とパスワードを格納します。

Basic認証を使用したデータを取得したい時は、POSTメソッドを使って上記のように`auth`の引数にBasic認証の情報を設定します。

#### Basic認証とは？
特定のWebサイトのページなどにアクセスする際、制限をかけることができる認証方法の1つ。
アクセスしようとすると、ユーザーIDやパスワードを求められます。

最後にPOSTメソッドの引数にURL、読み込むファイル、そしてユーザー名とパスワードは`auth`に引き渡して実行したら完成！

![スクリーンショット 2022-11-18 14.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976188/ac0dd1b5-a3e3-8988-8730-8bd54b9afc05.png)

curlで叩いた時と同じ結果が返ってきました!

# まとめ
+ PythonでAPIを叩いた
+ Basic認証はページにアクセス制限をかける認証方法
【Rails】Twitterクローンを作ってみた 〜画像アップロード(ActiveRecord)〜

## はじめに
[【Rails】Twitterクローンを作ってみた 〜コメント機能の作成〜](https://qiita.com/bloom__fu/items/87287cd705c9bad78524)の続きです。こちらを前提に進めていきますので、まだご覧になっていない方はそちらからご覧ください！※こちらはdockerでの環境構築を省きます。
## サービス環境
- ruby 3.0.0
- Rails 6.0.4
- docker
- mysql 8.0.2
- Slim, SCSS

## 画像アップロード機能
#### 条件
- ユーザー詳細ページの自分のアイコンをクリックでプロフィール画像をアップロードできる。
画像アップロードにはActiveRecordを使用してください。
#### 実装流れ(簡略)
① Gemfileに```gem "image_processing", ">= 1.2"```を追記し、bundle install
② docker再起動
③ ```$ rails active_storage:install```
④ db:migrate
⑤ models/profile.rbに```has_one_attached :image```追記
⑥ profiles_controllers.rbを編集(必要なparamsにimageを加える)
⑦ profiles/_form.html.slim(プロフィール編集画面)を編集。cssも同様に。 ← accept条件！
⑧ profiles/show.html.slimを編集。cssも同様に。
⑨ tweets/index.html.slim(root_path), show.html.slimを編集。cssも同様に。
⑩ views/shared/_icon.htmlを作り、見た目の共通化
#### プロフィール編集画面
![スクリーンショット 2022-11-18 15.40.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/f19aa4ee-275e-e8dd-6fa5-47a825c940eb.png)


#### プロフィール画面(画像アップロード後)
![スクリーンショット 2022-11-18 15.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/1309d114-427d-d7ba-0af4-b009f81d51ea.png)

## 解説
#### views/profiles/_form.html.slim
```slim
= form_with model: @profile, locals: true do |f|
  .form-group 
    = f.label :name
    = f.text_field :name, class: "form-control"
  .form-group 
    = f.label :profile_text
    = f.text_area :profile_text, class: "form-control"
  .form-group 
    = f.label :profile_image
    = f.file_field :image, class: "form-control", accept: 'image/jpg, image/jpeg, image/png, image/gif'
  .btn-space  
    = f.submit '保存', class: 'btn'
```
今回苦労した部分はこちらです。file_fieldに拡張子を制限して、画像ファイル以外選択できないようにするということです。最初はモデルでのバリデーションで処理しようかと考えていたのですが、簡単にhtml側で処理することができるというとてもシンプルなものを知り、こちらを使用しました。(acceptを使用することで、拡張子が画像系のものしか上げなくできます。)
#### モデルに一つのファイルを添付する
```ruby
class Profile < ApplicationRecord
  belongs_to :user
  has_one_attached :image

  validates :name, presence: true
  validates :profile_text, presence: true
end
```
Profileモデルに1つの画像を添付するには、has_one_attachedを使います。
:imageはファイルの呼び名で、:photo、:avatar、:hogeなど、ファイルの用途に合わせて好きなものを指定してください。ここで、Imageモデルなどを作る必要はないです。Active Storageは裏側でBlobとAttachmentモデルを使って、こそこそとprofile.imageを使えるようにしてくれます。


## 実装を通して学んだこと
#### 1. Active Storageの利用方法
ファイルアップロードを行うための機能で、画像の投稿機能などが簡単に作れることを学びました。画像用ののカラムを作成することもなく、Imageモデル等も作る必要がないことを学びました。
#### 2. acceptでの拡張子制限
html属性でfile_fieldに拡張子を制限できる方法があることを知りました。


## 感想
今回は簡単に機能を作成することができました！この機会でacceptでの拡張子制限等、知らないとすんなり行かないところを学べました。railsには様々な便利なgemがありますね。知らないgemの機能は無限にあると思いますが、その都度調べて使えるように自走力をつけることは非常に大事だなと感じております。
次回は**omniauthを使ったGitHubログイン**についてアウトプットしていこうと思います！読んでいただきありがとうございました。
## 参考記事
- https://mikamisan.hatenablog.com/entry/2016/12/04/174839
- https://railsguides.jp/active_storage_overview.html
- https://qiita.com/hmmrjn/items/7cc5e5348755c517458a
Oracleのテーブルで全カラムが重複しているレコードを削除する

## はじめに
あるアプリの開発中にやってしまった失敗の話です。
別システムから取得したデータをOracleのテーブルにインサートするプログラムにバグがあり、まったく同じ内容のレコードが複数回インサートされてしましました。（このテーブルにはプライマリーキーがないため全てのカラムが同じ内容のレコードが存在し得ます）
テーブルにはすでに過去のデータが入っているため全件削除してインサートし直すことは出来ず、そもそもプログラム実行日時が入るカラムがあるのでインサートの再実行はやりたくありません。
どうしても重複したレコードだけを削除する必要がありました。
ネット上にはWHERE句で結合して削除するやり方が見つかったんですが、カラム数がかなり多いためJOINして削除する方法を考えました。

## 考え方
1. 全レコードを全てのカラムでグループ化してレコード固有のROWIDの最小値の一覧を取得します
1. この一覧に無いROWIDのレコードを削除することでユニークな行だけが残ります。

## コード
~~~SQL
DELETE FROM
	table_a T1
WHERE
	T1.ROWID IN (
		SELECT
			T2.ROWID
		FROM
			table_a T2
			LEFT JOIN (
				SELECT
					MIN(ROWID) RID
				FROM
					table_a
				GROUP BY
					column_1,
					column_2,
					column_3,
					(以下カラムが続く)
			) T3 ON T2.ROWID = T3.RID
		WHERE
			T3.RID IS NULL
	)
~~~
PythonでCSVファイルを1つのExcelファイルにまとめる（pandas対xlwings）

# はじめに
計測のたびに出力される複数の計測結果のCSVファイルを、とりあえずExcelのブックにまとめたい気持ちになりました。パッとできないかなとおもったけど、pandasかxlwingsかどっちでやればいいのか悩んだので記録用にメモ。

# 前提

CSVファイルのサイズは以下の通り。
(30730, 7),4375KB
(84240, 6),8739KB
(41550, 9),6245KB
Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz   2.71 GHz


# pandasのExcelWriterを使う方法

ExcelWriterを使って複数シートに記録してみる
```python
filelist=["output.csv","output1.csv","output2.csv"]
filepath=[pathlib.Path(f) for f in filelist]

with pd.ExcelWriter('output.xlsx') as writer:
    for f in filepath:
        print(f)
        df=pd.read_csv(f,delimiter="\t")
        df.to_excel(writer, sheet_name=f.stem)
    print("savingExcel...")
#%%
#CPU times: total: 1min 14s
#Wall time: 1min 24s
```
「pandasのexcel操作は遅い」と聞いていましたが、いくらなんでもさすがに遅すぎでは…？

# xlwingsでブックを立ち上げて記録

さすがに待てないのでxlwingsで使ってみる

```python
with xlwings.App(visible=False) as app:
    with xlwings.Book() as wb:
        for f in filepath:
            df=pd.read_csv(f,delimiter="\t")
            wb.sheets.add(f.stem)
            wb.sheets[f.stem].range(1,1).value=df
        wb.save("output.xlsx")
# %%
# CPU times: total: 5.39 s
# Wall time: 21.7 s
```
これならまぁ我慢できる

# おわりに
xlwingsは、たまにしか使わないけどたまに使いたくなるので、使い方を忘れる。


# 補足
dfが`yyyy/mm/dd hh:mm:ss`形式だと、自動でExcel上で日付型として読み込みやがります。やめてほしい。

そのままExcel上で編集したければ、with句使わずに開いたままにする。
Excel上で、貼り付けたデータが選択状態になっているので、そのままAlt→N→Vでピボットテーブルするといいかんじ。
```python
wb=xlwings.Book()
wb.sheets(1).range(1,1).value=df
xlwings.Range("B1").expand().select
```
【TypeScript】メソッドの返り値が undefined である可能性を含む場合、型の絞り込みが効かない

# 問題のコード

```typescript
const test = (): string | undefined => {
    return "hello"
}

if (test() !== undefined){
    test().length // エラー
}

```
プロパティシグネチャが`undefined`を含みますが、
メソッド自体は必ず`string`を返しますし、
`if`文の前に`undefined`のチェックも行っています。

それなのになぜエラーが出るのでしょうか？

# なぜこうなる？

これは、型の絞り込みは、<b>変数にしか行われないためです</b>。
メソッドの返り値は、型の絞り込みには使用できません。
以下のように変更してみたらどうでしょうか？

```typescript
let cnt = 0
const test = (): string | undefined => {
    if (cnt > 1){
        return undefined
    }
    cnt = cnt + 1
    return "hello"
}

if (test() !== undefined){
    test().length // エラー
}

```
このコードを型チェックを無効にして実際に動かしてみると、
実行時にエラーが発生します。
これは、`test()`が副作用を持つメソッドであり、呼ぶために実行結果が変わるためです。
これでは型の絞り込みが意味がありません。

# どうする？
型の絞り込みは変数にしか効きません。
なので、実行結果を変数に入れてやります。

```typescript
const test = (): string | undefined => {
    return "hello"
}

const testResult = test() // ここではまだundefinedの絞り込みはされてない

if (testResult !== undefined){ // ここでundefinedの可能性を除外
    testResult.length // 5
}

```

これで無事に通ります。
「管理者として実行」とは

普段、指示された場合に使っている「管理者として実行」
具体的にはどういうことなの？ということで少し調べてみました。

# できること
・プログラムのシステムに関係する部分を変更したり追加したりできる
※逆にいうと、管理者として実行しないとシステムに関することは変更したりできない。

:::note info
システムに関する部分を操作する場合は、「管理者として実行」する必要がある！
:::

# 余談
管理者で実行する必要のないbatを管理者として実行したときにうまく動かなくてなんでだ？と思ったんですが、どうやら管理者として実行すると、`c:\WINDOWS\system32`フォルダで実行されるらしい。
Typescript、Next.jsの学習方法

## はじめに
私が行ったTypescript、Next.jsの学習方法をまとめます。

## バージョン等
Windows10
Ubuntu 20.04.4 LTS
Homebrew 3.5.7
nodebrew v18.7.0
node v18.7.0
npm 8.15.0

エディタ…VSCode
typescript@4.7.4
eslint@8.21.0
husky@8.0.1
prettier@2.7.1
next@12.2.4
react@18.2.0

## 学習方法
### 1.Typescript、Next.jsについて調べる
　複数のサイトを読んで、そもそもTypescript、Next.jsはどんな言語かについてざっくりと調べました。

参考記事
・[TypeScriptを入門者向けに解説！JavaScriptとの違いや勉強法までわかりやすく](https://udemy.benesse.co.jp/development/system/typescript.html)
・[Next.jsとはReactベースのフレームワーク！Nuxt.jsとの違いや特徴は？【入門編】](https://www.webstaff.jp/guide/trend/nextjs/)
・[Next.jsとは何か？何ができるのか？React開発のフレームワークを解説](https://ssaits.jp/promapedia/technology/what-is-next-jsreact.html)

### 2.学習する
　「Typescript Next.js　勉強法」などで検索して他のエンジニアがどのように学習しているのか調べました。
　私はTypeScript,Next.jsどちらもトラハックさんの動画で基本を学習しました。
　トラハックさんの動画では環境構築から基本の文法がわかりやすく解説されているのでお勧めです。
[これからTypeScriptを始める全ての人たちへ【日本一わかりやすいTypeScript入門】](https://www.youtube.com/watch?v=kd8VH10jXwc&list=PLX8Rsrpnn3IW0REXnTWQp79mxCvHkIrad)
[【日本一わかりやすいNext.js入門】#1 講座の概要](https://www.youtube.com/watch?v=F77RUjHZEAc)


　基本を一通り行ったら、わからないことがあったときに適宜調べていきます。
　基本情報や応用情報などの試験勉強にも共通しますが、基本をある程度学習したら、早めに手を動かすことが大事だと思います。
　私は、インプットよりもアウトプットのほうがよく理解が進むので、なるべく早くアウトプットに移ることを意識してます。

### 3.その他 WindowsPCでLinux開発環境を構築する
　私はWindowsPCで開発を行いましたが、トラハックさんの環境に合わせるためにUbuntuをダウンロードしてLinux環境で開発できるようにしました。
　Linuxの環境を整えるために行ったことを以下の記事に記載しています。
[windowsでUbuntu,homeblew,nodebrewをインストール、VSCodeでTypeScript環境を構築する](https://qiita.com/bear05/items/265401176698bccbfee4)
　

### 4.Next.jsにTypeScriptを導入する
　Nect.jsの公式チュートリアルでもTypeScriptを導入する手順が記載してありますが、私は別の記事を参考にして行いました。
　Next.jsにTypeScriptを導入してフロントの開発環境を構築する手順は後ほど別記事に記載します。