OmniAICreator/Qiita-1.07M huggingface dataset:
[Unity]アセット紹介 「Terrain Stitcher」

# 概要
UnityのTerrain補助アセット「Terrain Stitcher」の紹介です。
複数のTerrainを繋げたい時、繋ぎ目の段差を吸収してくれるアセットです。
![スクリーンショット 2022-10-25 19.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/12d8f441-0ea1-5d81-e684-d30357f4e02a.png)
https://assetstore.unity.com/packages/tools/terrain/terrain-stitcher-42671

# 本文
動作確認用のサンプルが用意されているのでそれを使ってみます。
![スクリーンショット 2022-10-25 19.40.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5ff10166-3e02-79df-0019-8ffcc2e7b955.png)
Terrain 11とTerrain 12をSceneビューにドラッグ&ドロップして横に並べます。
![スクリーンショット 2022-10-25 19.40.05 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/006e1663-3dac-96a0-c244-e191ef39dc26.png)
Terrain2つを複数選択状態にします
![スクリーンショット 2022-10-25 19.40.05 2 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/0285cb7b-24e2-1a87-c923-53bd30efd5ed.png)
メニューからTools > Nature Manufacture > Terrain Stitcherを選ぶと操作画面が表示されます。
![スクリーンショット 2022-10-25 19.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/b9c63116-bfde-70c6-f7ed-d67e0bbc87a8.png)
設定によってつなぎ方の調整ができるようです。今回はAveragePowerを選びました。（お互いの中間の高さで繋ぐ）
![スクリーンショット 2022-10-25 19.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/eab3bf2b-9989-165c-2296-21d014993635.png)
「Stitch All Terrains」を押すと2つのTerrainの繋ぎ目の高さがピッタリになります。
![スクリーンショット 2022-10-25 19.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/73a4ef8e-fa68-1615-e3a3-07964ea9f922.png)

:::note info
Terrain同士の横方向の位置は離れたままなので、最後にドッキングさせたら完成です:thumbsup_tone2:
:::
Macがひたすらcommand line developer toolsを要求してくる時


MacでPyenvを使ってPythonを入れようとしたら、

何度もcommand line developer toolsを入れようとしてくる。一度入れてもひたすら要求してくる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/2a5331fc-cc87-03f9-902c-f669f342fbfa.png)


# 解決策

```
xcodebuild -runFirstLaunch

```

で治る


## 参考サイト
https://developer.apple.com/forums/thread/704099
PythonでOpenEXRファイルをチャンネル毎に分割する

# 自己紹介
株式会社digitalbigmoのパイプラインエンジニアの小池@plinecomです。

# これは何？
VFXをやっていると、3DCG屋さんが気を利かせて、レンダーレイヤー毎にチャンネルを分けて、深度情報やスペキュラーやリフレクションやGIなどをOpenEXRに書き込んでくれることがある。とてもありがたい。感謝。通常の手順ではコンポジットでこれをNukeとかでバラして加工するわけだが、Nuke無いとか、そういう時のために、Pythonでバラバラに分割する方法を記す。

# とりあえず、コード
```python:main.py
import OpenEXR
import Imath
import glob
import os

if __name__ == '__main__':

    for path in glob.glob('/foo/bar/*.exr'):
        print(path)
        dir_name = os.path.dirname(path)
        base_name = os.path.basename(path)

        ret = OpenEXR.InputFile(path)  # Read EXR file
        header = ret.header()  # Get OpenEXR header info

        pix = {}
        ch_info = header['channels']    # Get channel info from header
        for ch in header['channels']:   # Get channel name from header
            pix[ch] = ret.channel(ch)   # Get channel image data
        ret.close()  # Close Read File handler

        for ch, v in pix.items():
            header['channels'] = {ch: ch_info[ch]}  # Renew header channel info
            # Open write file and Set header info
            exr = OpenEXR.OutputFile(dir_name + '/' + ch + '_' + base_name, header)
            exr.writePixels({ch: v})    # Write Pixel Data
            exr.close()  # Close Write File handler

```

# 必要なPython外部モジュール
* OpenEXR
```terminal:terminal
pip install OpenEXR
```
pipを使ってPyPIからダウンロードしてくる。Imathモジュールも一緒にインストールされる。
ただし、インストール時のビルドの際Python自身のheaderファイルが必要になるので、Linuxではpython-develなパッケージを管理ソフトで突っ込むこと。用意できない環境の場合は、いっそのことPythonからビルドした方が楽。

# コードの説明
## EXRファイルの読み込み
```python:
        ret = OpenEXR.InputFile(path)  # Read EXR file
```
## 分割処理
```python:
        for ch in header['channels']:   # Get channel name from header
            pix[ch] = ret.channel(ch)   # Get channel image data
```
読み出した画像データを辞書に貯めておく。


## ファイルの書き出し
```python:
        for ch, v in pix.items():
            header['channels'] = {ch: ch_info[ch]}  # Renew header channel info
            # Open write file and Set header info
            exr = OpenEXR.OutputFile(dir_name + '/' + ch + '_' + base_name, header)
            exr.writePixels({ch: v})    # Write Pixel Data
            exr.close()  # Close Write File handler
```
流用したヘッダを元に、チャンネル毎にヘッダ情報を修正し、書き出し先を指定してファイルを作成し、画素データを書き込んでファイルを閉じる。


# 宣伝
株式会社digitalbigmoでは美肌プラグインの販売や映像VFXの制作業務を行なっています。ご興味のある方は、webページを見にきてください。一緒にお仕事しましょう。

https://digitalbigmo.com

# 参考文献
[PythonのOpenEXRモジュールについて（英語）](https://excamera.com/sphinx/articles-openexr.html)
[OpenEXR本家（英語）](https://www.openexr.com/)
[WikipediaのOpenEXRのページ（英語）](https://en.wikipedia.org/wiki/OpenEXR)
[WikipediaのOpenEXRのページ（日本語）](https://ja.wikipedia.org/wiki/OpenEXR)
投資シミュレーションを Machination で可視化した結果

# 目的
投資シミュレーションをノーコードでゲームチックに表現したい
仮想通貨の価格を仮想的に設定した下で ROI を算出したい

# 投資戦略
24時間で大きく下落した仮想通貨を購入・売却する戦略を使用
購入から売却までの期間：3日
購入に要する 24h 下落率：10%

https://qiita.com/taka2_kiara/items/403071ab3850f2c1a2e7

# 実験
仮想通貨の価格設定：3000 を初期値とし，正規分布の値によって日毎に変動

![シミュレーション結果の図]()
シミュレーション結果

# 結果
##.
Engine cooling, ボッシュ自動車handbook 11版(55) p.736

Internal-combustion engines,Engine cooling,  ボッシュ自動車handbook 11版(55)


人生で影響を受けた本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)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e
# 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


#  Engine cooling(機関冷却)
p.736

## Air cooling
## Water cooling
## Intercooling (charge-air cooling)
## Exhaust-gas cooling
## Oil and fuel cooling
## Modularization
## Intelligent thermal management
# 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 初稿 　20221025


### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Air-intake systems and intake manifolds, ボッシュ自動車handbook 11版(57) p.754

Internal-combustion engines,Air-intake systems and intake manifolds,  ボッシュ自動車handbook 11版(57)

人生で影響を受けた本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)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e
# 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


# Air-intake systems and intake manifolds,
p.754

## Overview
## Passenger-car air-intake system 
## Passenger-car intake manifolds 
## Motorcycle intake manifolds 
## Commercial-vehicle air-intake system 
## Commercial-vehicle intake manifolds
# 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 初稿 　20221025


### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
エクセルメモ


１
データ整形
データ＞区切り位置＞カンマやタグなど。。。＞カンマ＞表示

２
エクセルは読み込み専用、編集開く選択設定
ファイルを開く＞ファイル＞名前をつけて保存＞右下ツール＞全般オプション＞読み込み専用チェック＞保存

3
値貼り付けのショットカット

Cstr Alt v

v

enter   非常に便利です

4
常用コマンド追加
「ファイル」から「オプション」を選択して、左側のメニュー欄から「クイックアクセスツール バー」をクリックしてカスタマイズ画面を開いてください。



★★★エクセルショットカット一覧

一列選択
ctrl space

一行選択
shift space

filter
行選択状態
ctrl shift L

選択したセルに入力した値を複製する
Ctrl + Enter

置換
Ctrl + H

ショートカットメニューを表示
Shift + F10

新しいワークシートを挿入
Shift + F11


新しいシートを挿入
Alt + Shift + F1

シート削除のショートカット
Alt ＋ E ＋ Lです。

セルにコメント挿入
shift F2

エクセル最大化表示
Alt SPACE X
ある漢字が日本語で使われているかどうかをざっくり判別する

# あらすじ
ある文字列が日本語かそうでないか判別する必要があって、日本語でも使われる漢字なのか、日本語では使われない漢字なのか、超ざっくり判別するスクリプトを作りました。

# 原理
原理は、Unicodeのサイトに行って

https://unicode.org/Public/UNIDATA/

Unihan.zipというファイルを取ってくると、中にUnihan_IRGSources.txtというタブ区切りテキストのファイルがあります。
こんな感じ。

```Unihan_IRGSources.txt
U+3400	kIRG_GSource	GKX-0078.01
U+3400	kIRG_JSource	JA-2121
U+3400	kIRG_TSource	T6-222C
U+3400	kRSUnicode	1.4
U+3400	kTotalStrokes	5
...
```

U+3400という字について調べると、kIRG_JSourceとしてJA-2121という値がマップされている。
kIRG_JSourceは日本語の典拠となった原規格と、その中でのコードポイントのことみたいです。
この字はJAの2121番。

JAというのはUnified Japanese IT Vendors Contemporary Ideographs, 1993という規格らしい。
https://www.unicode.org/reports/tr38/index.html#kIRG_JSource

Unified Japanese IT Vendors Contemporary Ideographsで検索すると、小形克宏さんの下の記事（2000年）に当たった。
https://internet.watch.impress.co.jp/www/column/ogata/part2_3.htm

>この文字集合の典拠について詳細な説明は今にいたるまでなされていず、正体不明と言わざるをえない。

へぇー。。

で、U+3400という字は、㐀っていう微妙な字だった。
自分で書いたことも読んだこともないが、おかと読み、土を小さく盛ったお墓のことだそうだ。
いきなり悲しいわ！！！
https://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=3400
https://kanji.jitenon.jp/kanjin/6593.html

その下、U+3401について調べると、kIRG_JSourceがない。
だから、日本語では使わないと考えていいだろう！
という方針。

```
U+3401	kIRG_GSource	G5-3024
U+3401	kIRG_KSource	K3-2121
U+3401	kIRG_TSource	T4-2224
U+3401	kRSUnicode	1.5
U+3401	kTotalStrokes	6
...
```

ちなみにU+3401は㐁という字。
テンと読んでむしろという意味だそうだ。
丙（ひのえ）と似てるね。。
なんか変な扉を開けたかもしれない。。
https://kanji.jitenon.jp/kanjin/6599.html
# 使い方
プログラムだが、自分用にPerlで書けば5分で書けるのに、Pythonな人とシェアする必要でPythonで書いた。
いつまで立っても馴染めんわPython...。
使い方は以下の通り。
スクリプトと同じところにUnihan_IRGSources.txtを置く必要がある。

```bash
$ python3 ./kanjiTest.py 㐀
㐀(code point=U+3400) is Japanese

$ python3 ./kanjiTest.py 㐁
㐁(code point=U+3401) is not Japanese
```

あはは動いてるわ。
# 中身
中身はこんな感じ。

```python
# /usr/bin/python3
# kanjiTest.py

import sys
import csv

args = sys.argv
code_point = 'U+' + hex(ord(args[1]))[2:].upper()

tsv_file = 'Unihan_IRGSources.txt'
with open(tsv_file, 'r', encoding='utf-8', newline='') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        jp_src = 0

        if len(row) >= 1:
            if row[0] == code_point and row[1] == 'kIRG_JSource':
                jp_src = 1
                print (args[1] + '(code point=' + code_point + ') is Japanese')
                exit()
                   
    if jp_src == 0:
        print (args[1] + '(code point=' + code_point + ') is not Japanese')
```

UTF-8な端末で、漢字1文字を引数で受け取って、ordでコードポイント化し、hexで16進にし、最初の0xを切り取り、upperで大文字化し、U+をくっつけている。

csvモジュールでdelimiter='\t'を指定するとTSVが読み込める。

各行はリストオブジェクトになり、1列目がUnicodeコードポイント（U+xxxx）に、2列目が典拠とする原規格の種類になるので、2列目がkIRG_JSourceとなる行があったら日本語だねと言って終了する。
最後まで行き着いたら、日本語じゃないねと言って終了する。

len(row)が1以上ですかと聞いているのは、最後の1回が空リストだかヌルだかが返るから。
これを入れないと最後の1行を読み込んだ後でIndex Out of the Rangeになる。
このプログラムがお行儀的にどうか知らないけど動いているようだ。

# 後記

と、ここまで書いて思ったけど、日本人が大好きな𠮷野家のヨシ（ツチヨシ、土＋口型、U+20BB7）は、台湾由来でUnicodeで使えるけど、日本の規格では絶対に吉（サムライヨシ、士＋口型、U+5409）と包摂されるので、kIRG_JSourceがないのである。

https://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%F0%A0%AE%B7

だから非日本語を返す。

```bash
$ python3 ./kanjiTest.py 𠮷
𠮷(code point=U+20BB7) is not Japanese
```

うーん。
どうなんだろうね。
（何この終わり方。。）

**（この項終わり）**
プロジェクト管理

## 目次
1\. ディレクトリ・ファイルの命名規則
1\. プロジェクト開始時に用意するディレクトリ・ファイル

## ディレクトリ・ファイルの命名規則
### ディレクトリ
半角英字(小文字のみ)
必要に応じて単数形, 複数形を使い分ける
複合語はアンダーバー(_)で区切る(例：miraijin_project)

## ファイル
半角英字(小文字のみ)
単数形のみ
先頭に日付(年月日_)を付ける
複合語はアンダーバー(_)で区切る(例：20220101_miraijin_app)


## プロジェクト開始時に用意するディレクトリ・ファイル

<dl>
  <dt>MTG</dt>
      <dd>MTG一覧表</dd>
  <dt>オレンジ</dt>
      <dd>橙色のフルーツ</dd>
</dl>
svn javaプロジェクト作成

１
既存から新しいプロジェクト例 testPro まることコピー
.projet編集＞<name>testPro</name> へ編集

２
checkout対象フォルダをまること .svn含めて削除

３
対象フォルダをcheckout

4
eclipseにインポート＞既存プロジェクトをワークスペースへ

５
参照＞上記作成したプロジェクトtestPro を選択
４０代おっさんPythonを勉強する（データ解析,Pandas編①）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## Pandas

- データ分析を支援するPythonのライブラリ
- 元々金融データの操作のために設計された
- スプレッドシートやリレーショナルデータベースの処理ができる
- DataFrameという基本データ構造を定義されている
- 科学データだけではなく、ビジネスデータの処理でも単純化している
- ホームページ  [https://pandas.pydata.org](https://pandas.pydata.org)
- ドキュメンテーション  [https://pandas.pydata.org/pandas-docs/stable/](https://pandas.pydata.org/pandas-docs/stable/)

## データの可視化

- データをグラフとして見せる
- 数字だけよりわかりやすい
- Pandasで簡単なグラフをすぐに作成できる
- Matplotlibを並行で使うと綺麗なグラフになる

## Matplotlib

- プロットライブラリであり、データ可視化に役に立つ
- たくさんの統計グラフや実験結果を表示することができる
- 折れ線、棒グラフ、円グラフ、ヒストグラム、パワースペクトル、散布図、など
- Matplotlibの参考は[https://matplotlib.org](https://matplotlib.org)

## 日本語のフォントを設定

- フォントがない文字ではグラフに表示できないため
- 英文字以外のフォントを設定する必要

```python
#  自分の環境のフォントを調べる
#  必要なフォントを探し出す
from matplotlib import font_manager

fonts = set([f.name for f in font_manager.fontManager.ttflist])
# print(fonts)

for f in fonts:
    if 'Mincho' in f or 'Gothic' in f or 'Meiryo' in f or 'Hiragino' in f:
        print(f)
```

- エラーで`No module named 'matplotlib'`が出ましたその時は`pip3 install matplotlib`matplotlibをインストールする。

```python
#  日本語のフォントを設定する
import matplotlib.pyplot as plt

# MacOSで使えるフォント
# Hiragino Maru Gothic Pro
# Hiragino Mincho ProN
# Hiragino Sans GB
# Hiragino Sans
# plt.rcParams["font.family"] = "Hiragino Maru Gothic Pro" # Macの方はこちら

# Windowsで使えるフォント
# MS Mincho
# MS Gothic
# Meiryo
plt.rcParams['font.family'] = "MS Gothic" # 自分はWindowsを選ぶ
```

```python
# このグラフがちゃんと表示できたらOK
labels = ['<42', '43~48', '49~59', '60~64', '>65', '不明']
sizes = [36.7, 31.5, 19.7, 6.4, 5.2, 0.5]
plt.pie(sizes, labels=labels, autopct='%.1f%%')
plt.title('2017年　20～29歳の若者の週間就業時間別割合')
plt.legend(title='時間', loc='center right', bbox_to_anchor=(1.5, 0.5))
plt.show()
```

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
24時間で大きく下落した仮想通貨を購入・売却し続けた結果（シミュレーション）

# 目的
ROI が高くなる投資戦略の導出

# シミュレーションする投資戦略
1. ##.
2. ##.

# 使用データ
仮想通貨の過去の価格データを使用
期間：`20##/##/##`~`20##/##/##`

# 実験

![パラメータの組合せを変えて得られた ROI のヒートマップ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/87afaa6f-0a6a-1591-99da-5eeb5a052859.png)
パラメータの組合せを変えて得られた ROI のヒートマップ
縦軸：購入に要する価格の24h下落率
横軸：購入から売却までの期間

# 結果
24h下落率の閾値を高くした場合にROIが高くなった
対して，購入から売却までの期間の大小による変化は無かった
Postmanでコンソールが出ない

### 結論
フッターのバーのところにConsoleがいた。。

メニューバーからShow Postman Consoleってしたらでてきてほしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152020/559a9955-74fe-7e28-7cb2-118672633d68.png)
vue.jsとTailWindCSSとday.jsで作るズルいカレンダー

カレンダーを作る際にテーブルを作るのも何なのでグリッドレイアウトを使ったらコードもシンプルになりました。

```javascript:calendar.vue
import dayjs from 'dayjs'
// 月末の日にち
const endDate = dayjs().endOf('month').get('date')
// 月初の曜日
const startWeekday = dayjs().startOf('month').get('day')
//　配列を作ります。
const dates = computed(() => {
    let data = []
    //月の初めの日までは何もなし
    for (let i = 0; i < startWeekday; i++) {
        data.push('')
    }
    //日付を追加します。
    for (let h = 1; h <= endDate; h++) {
        data.push(h)
    }
    return data
})

/*
できたのはこんな配列
["","","","","","",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
*/
```
あとはCSS グリッドレイアウトで7日ごとに行にします。
```html:calendar.vue
<div class="grid grid-cols-7 gap-4">
    <template v-for="date in dates">
        <span>{{ date }}</span>
    </template>
</div>
```
【Scheduler】Sending message to Microsoft Teams (Webhook:Basic)

### Configure Incoming Webhook in Teams ###
Webhook settings are done in Teams.
Select `Connectors` from the menu of the channel you want to send messages to.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3eeb115f-9daa-d852-27dc-f4a0b1139e99.png)
Click the `Configure` button for Incoming Webhook.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3f7cd9aa-8296-94ae-fb5b-5c1ad1c996a7.png)
On this screen, set the **name** and **icon** for the Webhook and actually create it.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f04e117b-2a25-ae3a-dc01-eef91987afe2.png)
Go back to Connectors and select `Configured` from the buttons on the left. Click `n Configured`. The created Webhook will be displayed, so press the `Manage` button to display the details.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3f4c1e4a-b13d-98aa-b544-bb28be6cd418.png)
Copy the **URL** from the details to your clipboard. You will need this URL when sending messages.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9cc3c40e-0ccc-9f62-8c0e-2295f647bd27.png)
### Creating task ###
Create a task in the [Sharperlight](https://sharperlight.com/) scheduler that sends a message to the Teams Incoming Webhook.
Launch the scheduler from the Sharperlight application menu.
Once the scheduler is started, start creating tasks with the `New` icon. Fill in the **Code**, **Group** and **Description**.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/08583dff-29f4-ff5a-1372-4d83ffcec8ef.png)
Go to the `Actions` tab and create an action. Now let's define how to send messages to Teams.
Click the `new` icon to display the action list. Select `Communication` -> `Microsoft Teams - Send Message` action.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/de702e62-db74-3a2b-4cd3-f8a3909d44ac.png)
Once the action is added, select the `Webhook` radio button and paste the Incoming Webhook URL you previously copied to your clipboard into the text box below it.
After that, set the subject of the content to be sent and the message. This time, we'll use the basic method to send a plain-text message.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6ec037f9-d5b4-492b-3500-428a8ad65135.png)
That's it. You can set a trigger and send it periodically, but here we will send it manually. So save with the `OK` button.
Select `Execute` from the right-click menu.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b7979115-e995-627f-5132-3b3a72039a7d.png)
When the execution is finished, you can check it in Teams immediately.
You can see it like this.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c0dd1927-546e-5675-b6fd-b1171e5e36c6.png)
It seems that there are various ways to use it.
create-react-app を Heroku-22 で動かす

`create-react-app` で作成したWEBフロントのアプリケーションはHerokuに簡単にデプロイが行えていましたが、それを実現していた [Buildpacks](https://github.com/mars/create-react-app-buildpack#heroku-buildpack-for-create-react-app) が **deprecated** になり、 `Heroku-22` には対応されなくなりました。

```
After a long, useful run, this buildpack is now at its end of life 🌅

The underlying static web server buildpack is deprecated and will not be supported on Heroku-22 or newer stacks.

Please look into using Next.js or Remix to develop React apps which are deployable using the Node.js buildpack.
```
[原文へのリンク](https://github.com/mars/create-react-app-buildpack#heroku-buildpack-for-create-react-app)

`Heroku-22` に更新してpushすると以下のエラーメッセージが出力されてデプロイが失敗します。

```
remote: Stack heroku-22 is not supported!
remote:  !     Push rejected, failed to compile React.js (create-react-app) multi app.
remote:
remote:  !     Push failed
```

`Heroku-20` のEOLが迫る中で `Heroku-22` に対応したアプリケーションの形式に書き換えるのは大変な作業です。
そこで既存の `create-react-app` の内容を変えずに、配布用のWEBサーバーを立ち上げて対処する方法の共有です。

## Heroku-22 で動かすために
基本的には以下の記事の内容をそのまま活用させてもらいました。
`Express` を配布用のWEBサーバーとしてHeroku上で立ち上あげて `create-react-app` の静的アセットを配布できるようにするというものです。

### 参考記事
https://vel-lesikov.medium.com/deploying-migrating-static-create-react-app-project-to-heroku-22-stack-b19a4255ea7c

### やるべきこと
```
1. package.json に Express の追加
2. Heroku上で Express を動かすためのJavaScriptの追加、および Procfile の追加
3. Heroku APP の 既存の Buildpacks の削除
```

リンク先のJavaScriptだとESlintなどでエラーになるので以下のように修正したものを利用しています。

```js
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());

app.use(express.static(path.join(__dirname, '..', 'build')));

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, '..', 'build'));
});

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '..', 'build/index.html'));
});

app.listen(port, () => {
  console.log(`Server is running on port: ${port}`);
});
```

`package.json` は以下のような変更を行いました。
なお、2022年10月25日時点でHerokuの Node.js のバージョンのデフォルトが **18系** になっていてデプロイが失敗したので　**16系** が適用されるようにバージョンを指定しています。

```
{
  // 中略
  "dependencies": {
    // 中略
    "express": "4.18.2"
  },
  // 中略
  "engines": {
    "node": "16.x"
  }
}
```

既存の `Buildpacks` を削除する必要があるのでHerokuのWEBコンソールから削除を行ってからデプロイしてください。

![Buildpacks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/924e5f07-348d-df5a-227d-ff67230e8dae.png)
画面端から引っ張るデザインのメモ

コーディングデザインで画面の端からのデザインがありましたので、そのデザイン方法。
先にコードから
~~~html
<div class="container">
   <div class="children">

   </div>
</div>
~~~

~~~css
.container{
  max-width: 1200px;
  margin: 0 auto;
  padding: 30px;
}

.children{
    max-width: calc(100vw - (50% - (1200px / 2)));
    width: calc(100% - 0px);
}
~~~
上のコードは最大幅が１２００pxの時の例
`(50% - (1200px / 2))`で左右余白の半分の幅が求まり`-100vw`することで、範囲が画面端からコンテナ端まで伸びます。
コンテナの中で幅を狭めたいときは`.children`の`width`にその値を引く。
下の参考記事はより詳しく書いています。

### 参考
[CSSのcalcで片側だけグリッドガイドライン外へ飛び出したカラム](https://www.tam-tam.co.jp/tipsnote/html_css/post17409.html)

[containerの片方だけ100%に広げて外側に出したい。](https://teratail.com/questions/204342)
aggregate_failuresを使ってRspecのシステムテストを高速化した

Rspecのシステムテストで実行時間が30分以上かかるテストがありました。example数は約100件です。
何とかならないものかと考えた結果、`aggregate_failures`を導入することにしました。これによりテスト実行時間を約10分まで短縮することができました。

# aggregate_failuresとは？

it内であるexpectが失敗した時に、次のitに移行せず、it内の全てのexpectを実行してくれるメソッドです。通常であれば1つのexpectが失敗した時点で次のitに移行してしまいます。`aggregate_failures`は全てのexpectを実行して、失敗したexpectが複数件あればそれらの情報を全て出力してくれます。

# どんなテストだったか？

こんなテストでした。

beforeを使っていて、itごとにFactoryBotでuserをbuild→ログイン処理をしています。

```ruby
describe 'XXX', type: :system, js: true do

	before(:each) { @user = FactoryBot.build(:user, email: 'xxxx.com') }
	subject { @user }

	context "YYY" do
		before do
			# ログイン処理
		end
	end

	it 'hoge1' do
		expect(zzz1).to eq zzz1
	end

	it 'hoge2' do
		expect(zzz2).to eq zzz2
	end

	it 'hoge3' do
		expect(zzz3).to eq zzz3
	end
	.
	.
	.
	it 'hogeN' do
		expect(zzzN).to eq zzzN
	end
end
```

# 遅くなっている原因はどこか？

### ①FactoryBot.buildの部分

FactoryBotでアソシエーションを指定しているとbuildでもレコードが作成され、その分遅くなるらしいです。しかし今回はアソシエーションの指定はしていないのでここは原因ではないと考えました。

### ②ログイン処理の部分

今回のケースでは明らかにここでした。毎itごとにログイン処理をしているのでめちゃくちゃ時間がかかっていました。

# before(:context)

解決策として`before(:context)`を使用し、contextごとにログイン処理を共通化しようと思いました。

しかしここで問題がありました。

ログイン処理の中に`Capybara.current_session.server.port`でポート番号を取得する場面があるのですが、これがnilになってしまうのです。
`before(:context)`の時点ではサーバーが起動していないことが理由と思われます。
`before(:context)`によるログイン処理共通化は断念しました。

# aggregate_failuresを利用する

そこで出てきたのが`aggregate_failures`です。
前述の通りですがitの中にまとめてexpectを記述することができるので、itの数を大幅の削減できます。
itの数が大幅に削減されるので、before doでログイン処理が実行される回数も大幅に減るのです。

# aggregate_failuresの導入方法

spec/spec_helper.rbに以下のように追記するだけで全てのexpectに適用されます。

```ruby
RSpec.configure do |config|
	config.define_derived_metadata do |meta|
		meta[:aggregate_failures] = true unless meta.key?(:aggregate_failures)
	end
end
```

# 導入結果

aggregate_failuresを導入した結果このようにexpectをまとめることができテスト実行時間は10分程度になりました！

```ruby
describe 'XXX', type: :system, js: true do

	before(:each) { @user = FactoryBot.build(:user, email: 'xxxx.com') }
	subject { @user }

	context "YYY" do
		before do
			# ログイン処理
		end
	end

	it 'hoge1' do
		expect(zzz1).to eq zzz1
		expect(zzz2).to eq zzz2
		expect(zzz3).to eq zzz3
		.
		.
		.
		expect(zzzN).to eq zzzN
	end
end
```

# 終わりに

テスト実行時間は削減できたのですが、おそらくブラウザの動作が重くSeleniumがDOMを見つけられず適切なボタンをクリックできないことが原因で、テストがランダムで落ちる問題が発生しました。
こちらの解決策についても後日記事を書く予定です。
tomcat サーバ構築要点

1
web プロジェクト構築
新規＞プロジェクト＞動的ウェブプロジェクト

2
サーバ新規する

3
デバッグ可能に設定
web プロジェクト　右クリック＞デバッグ構成＞apache tomcat ダブルクリック
対象サーバ選択＞適用

対象ソース右クリック＞デバッグ実行
特異スペクトル変換による仮想通貨の異常性判別

# 目的
仮想通貨へ投資する際の損失リスクを減らしたい

# 実施事項
1. 特異スペクトル変換（以下 SSA）によって仮想通貨の異常性を評価
2. 以下の投資シミュレーションにおけるROIを比較
    - 異常でなかった仮想通貨
    - 全ての仮想通貨（厳密には全てではないため補足を追記する予定）
3. 前者のROIが高ければ，異常性の判別が妥当であるとする

# 使用データ
`20##/##/##` ~ `20##/##/##` の仮想通貨の価格データ

# 実験
SSAのパラメータは以下の通りに設定
- ##：##
- ##：##

![全仮想通貨の異常度](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/ec21b658-2b48-381d-5058-a7abd575da79.png)
全仮想通貨の異常度
縦軸：##
横軸：##

![ROIの比較結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/de28e39a-34da-5426-e409-7e4836db10ec.png)
ROI 差分：異常でなかった仮想通貨と全仮想通貨
縦軸：##
横軸：##
カラーバー：ROI（%）

# 結果
ROI の増加は多くとも 1% 未満であった
ゆえに，今回導いた仮想通貨の異常度は妥当でないと言える

# 課題
SSA のパラメータチューニング
11.3でkappletsにアクセスする時のURLについて

kappletsにアクセスする時に使用するURLについて
MCサーバー上で
kapples.xmlに記載したURL(大体の場合　http://IPアドレス:8080/kapplets)
ではなくブラウザに[http://localhost:8080/kapplets]　と入力しアクセスすると
[OAth認証に失敗しました]と表示される。
[Management Consoleにログイン]をクリックすると問題なくログインできる。
MCサーバー上のブラウザにブックマーク等作成する場合は注意
bizrobo MC上でバックアップ取得できない場合の対処(tomcat構成)

MC上　管理>バックアップでフルバックアップの作成をクリックしたとき、
バックアップがポップアップは表示されるがそれ以降進捗しない場合。
tomcatインストールフォルダbin配下のtomcat8w.exe(tomcat8の場合)
から「java」内のMaximum Memory poolのサイズを大きくすると解決する可能性がある。
とりあえずメトリクスとログ 保存〜監視〜通知

ここではAWSのAmazon CloudWatch初手ベースでの流れを元に話をしているものの、どこでも同じような流れになると思われる。

※Metric／Metrics／メトリック／メトリクス…英語と日本語で表記が揺れるけど細かいこと気にしない。

## 全体図

```mermaid
flowchart LR
    AWS[AWSの各サービス] -->|メトリクス送信| CWM[CloudWatch Metrics]
    AWS -->|ログ保存| CWL[CloudWatch Logs]
    AWS -->|ログ保存| S3
    Self[自前の各サービス] -->|利用| AWS
    Self -->|ログ保存| CWL
    Self -->|ログ保存| S3
    CWL --->|メトリックフィルター適用| CWM
    CLA[CloudWatch Alarms] -->|合否判定| CWM
    CLA --->|SNS/Chatbot経由で新規投稿| Slack[Slack Desktop/Mobile]
    Slack -->|新規投稿通知| User
```

## 部分ごとの説明

### 保存する

* メトリクスをCloudWatch Metricsに送信する
  * メトリクス＝システムのとある日時におけるとある状態を表したデータの集まり
  * 概ねAWS側が自動的に各種メトリクスを送信してくれている
* ログをS3やCloudWatch Logsに保存する
  * S3保存はAthena利用を見越した形式で行うと吉
  * CloudWatch Logs保存はCloudWatch Logs Insights利用を見越した形式で行うと吉
  * 必要であれば（※後述）、メトリックフィルターでログから自前メトリクスを生成しておく

```mermaid
flowchart LR
    AWS[AWSの各サービス] -->|メトリクス送信| CWM[CloudWatch Metrics]
    AWS -->|ログ保存| CWL[CloudWatch Logs]
    AWS -->|ログ保存| S3
    Self[自前の各サービス] -->|利用| AWS
    Self -->|ログ保存| CWL
    Self -->|ログ保存| S3
    CWL -->|メトリックフィルター適用| CWM
```

### 監視する

* 「監視」＝「メトリクスを元に予め決めておいた条件で合否判定すること」と言える
  * 例：1分毎のエラー発生率が5％を超えるという状態が直近10分間で2回以上発生しているかどうか
* 逆に「合否判定したいのであれば対象となるメトリクスが存在しているべき」と考えると分かり易い
  * 例：処理エラー発生回数、処理呼び出し回数
  * 例：「◯◯」というエラーメッセージが出たらアウトとしたい＝「『◯◯』というエラーメッセージが出た回数がカウントされているメトリクス」をメトリックフィルターで生成し、そのメトリクスを監視
* 条件次第なので、「大元のサービスで何らかのエラーメトリクスが発生すること」と「監視で否という判定結果になること」は別問題である（勿論、たまたまイコールになるような判定をしている場合もある）

```mermaid
flowchart LR
    CLA[CloudWatch Alarms] -->|合否判定| CWM[CloudWatch Metrics]
```

### 監視対象の状況変化を開発者に通知する

内容の重要度に応じて、通知の有無や方法を考える（例：休日深夜でも通知するのかどうか）。

以下ではSlackを経由した通知を例にしている。

#### 監視対象状況の変化をSlackに投稿する

* 合否状況がこれまでと変化した場合になんらかのアクションを実施する
  * アクション＝重要情報向けSlackチャンネルへの投稿
  * アクション＝小ネタ向けSlackチャンネルへの投稿
  * ※ここではSlack投稿を例にしているが、アクション＝「メール送信」とか「何もしない」でも良いということ

```mermaid
flowchart LR
    CLA[CloudWatch Alarms] -->|SNS/Chatbot経由で新規投稿| Slack[Slack Desktop/Mobile]
```

#### Slack投稿をユーザー通知する

* Slackチャンネルの重要度に応じて、必要があれば新規投稿が発生したことをユーザーに通知する

```mermaid
flowchart LR
    Slack[Slack Desktop/Mobile] -->|新規投稿通知| User
```

## 余談

### メトリクスを閲覧する

* 「閲覧」と「監視」は別である
  * 「監視」は前述の通り、合否判定をしている
  * 「閲覧」＝「任意期間のメトリクスを眺めながらの感想戦につい耽ってしまう」様ってことで…
  * 例：昨日の夜間は一昨日の夜間よりアクセス数が多かったんだな〜
  * 例：昨日のエラーと同タイミングでCPU利用率も高かったんだな〜
* メトリクスがグラフ化されていると見易い
  * 特に気になるメトリクスだけを選抜して一覧化していると、さらに見易い
* 監視（CloudWatch Alarms）状況の変遷をメトリクスだと捉え、これを含めてもよい

```mermaid
flowchart LR
    CWM[CloudWatch Metrics] -->|気になるメトリクスを選抜| CWD[CloudWatch Dashboard]
    CWA[CloudWatch Alarms] -->|気になる監視を選抜| CWD
    User -->|個別に閲覧| CWM
    User -->|個別に閲覧| CWA
    User -->|選抜一覧を閲覧| CWD
```

### ログを閲覧する

* 生データを直接読み込む
* サービスを使って適宜検索する

```mermaid
flowchart LR
    User -->|生データ取得閲覧| S3  
    User -->|Athenaで抽出| S3
    User -->|生データ表示閲覧| CWL[CloudWatch Logs]
    User -->|CloudWatch Logs Insightsで抽出| CWL
```
ActiveSupport::Concernとは

## ActiveSupport::Concernとは
Modelやcontrollerで重複した処理をActiveSupport::Concernを使用することでよりDRYに記述できる機能

## 使用するには
1. `app/models/concerns/`or`app/controllers/concerns/`にファイルを作成
    - ファイル名はmoduleと同じにする
2. `included do end` の中に処理を書く
    - スコープだけでなく、メソッドを定義したりもできます
    - `extend ActiveSupport::Concern`を忘れないように
3. 使用したいmodelファイルの中でincludedする
4. concernに追加したメソッドを使用する際はそのまま呼び出せます

#### 例
```ruby:app/models/concerns/m.rb
module M
  extend ActiveSupport::Concern

  included do
    scope :disabled, -> { where(disabled: true) }
  end
end
```

```rb
class Host
  include M
end
```

### 終わりに
`Module#concerning`とごっちゃになってしまったのでまとめてみました。
近々`Module#concerning`についての記事も書きます。
内部での動きは理解していないので調べてみて今度編集します。


### 参考
https://github.com/rails/rails/blob/main/activesupport/lib/active_support/concern.rb

https://lanlib.com/2021/04/04/rails-concern%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9/
【スケジューラ】Microsoft Teamsにメッセージを送ってみる (Incoming Webhook:基礎編）


### Microsoft Teams側の設定 ###
[Webhookの設定](https://learn.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook)をTeamsで行います。
メッセージを送り付けたいチャンネルのメニューから`Connectors`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a3e961dd-1904-7b6b-76fb-1753dc7f99e6.png)
**Incoming Webhook**の`Configure`ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/1643fdba-1cd1-d684-75fd-78ae07c093ce.png)
この画面ではWebhookに名称やアイコンを設定して実際に作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7fa5f61b-236f-35c6-61a2-a7f80f6bd648.png)
再度Connectorsに戻り、左側のボタン群から`Configured`を選択します。表示されたIncoming Webhookの`n Configured`をクリックします。作成したWebhookが表示されるので、`Manage`ボタンを押して詳細を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/debfad34-4830-a5a6-46cb-6d7e9b1737f6.png)
詳細から**URL**をクリップボードにコピーします。メッセージを送る際には、このURLが必要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9bafb44d-acac-1e9a-deb7-a10be8192db1.png)
### タスクの作成 ###
SharperlightスケジューラでTeamsのIncoming Webhookにメッセージを送るタスクを作成します。
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**スケジューラ**を起動します。
**スケジューラ**が起動したら、`新規`ボタンでタスクの作成を開始します。**コード**、**グループ**、**説明**を記入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/aa00cd20-1b0c-7502-57e1-bb9d8e2cf4ac.png)
`アクション`タブに移動して、アクションの作成を行います。ここでいよいよTeamsにメッセージを送る定義を行います。
`新規`アイコンをクリックしアクション一覧を表示します。**通信** -> **マイクロソフトチーム-メッセージの送信**アクションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a1a5e5e8-4906-4ad0-40f0-ba6214b34bc4.png)
アクションが追加されたら、`Webhook`ラジオボタンを選択し、その下のテキストボックスに先ほどクリップボードにコピーしておいたIncoming WebhookのURLを貼り付けます。
後は送信内容の**件名**と、**メッセージ**を設定します。今回は**基本**メソッドでプレーンテキストのメッセージを送るようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5041b6b6-6891-3adb-d1ec-3e90f758b434.png)
これで完了。トリガーの設定をして定期的に動かしたりもできますが、ここでは手動で動かしてみます。ということで`OK`ボタンで保存します。
右クリックメニューから**実行**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/158a99a2-02ea-83af-900f-375a8867e63f.png)
実行が終了したら、Teamsの方で早速確認してみます。
このように確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bdef4157-7fe6-e789-e02e-cf13859389b0.png)
いろいろ使い道がありそうです、次回は応用編とします。

では、失礼します。
WordCloud による仮想通貨の動向分析

# はじめに
Google News のデータよりワードクラウドを生成しました

# 目標
仮想通貨の動向を掴むため

# 実験
以下を満たすデータからワードクラウドを作成
- NFTとタグ付けされたニュース
- TODO：データの期間

![ワードクラウド](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/a0bfab2b-14e0-bc73-9a96-468424e20560.png)
作成したワードクラウド

# 考察
TODO
さくらのレンタルサーバ ライトプランでPythonとSQLiteを使ってInstagramの投稿をランダム表示するサイトを作ってみた（その2：Instagram API）

その1でざっくりと仕様を決めたので、まずはInstagram基本表示APIの設定をします。
# Facebook開発者アカウントを取得する
https://developers.facebook.com/docs/development/register?locale=ja_JP

の通りに進めます。
Facebookアカウントが必要ですが、新規に作ることもできますので手順通り進めれば、ここは大丈夫です。
# アプリを登録する
開発者アカウントを作成したら、https://developers.facebook.com/ に進み、右上のログインから先に進みます。

https://developers.facebook.com/docs/development/create-an-app

の手順に沿って、アプリの設定をします。
- アプリタイプはConsumer（消費者）でOKです。
- アプリ名は適当でOKです。（私は「Cat Changing」としておきました）
- メールアドレスは普段使っているアドレスでも、開発者アカウントのアドレスでも構いません。
これでアプリの登録は完了です。Metaが用意しているプロダクトの一覧が表示されますが、今は無視して、次に進みましょう。
# Instagram基本表示APIを構成する
https://developers.facebook.com/docs/instagram-basic-display-api/getting-started

の通り、
- 左側のタブから「設定」→「ベーシック」を選択。ページの下部まで行き、「プラットフォームの追加」を選択してください。
- ウェブサイトに自分のサイトのトップページのURL（私の場合は「 https://maguiwa.saloon.jp/ 」）を入力します。この時点でページができている必要はありません。
- ここまで終了したら、変更を保存をクリック。
- また左側のタブに戻り、「商品」をクリックして、「Instagram Basic Display」を探して、「Set up」です。
- ページの下部にある「Create New App」をクリック。
さて、ここから入力が続きます。
- Instagram表示名に先程設定したアプリ名を入力。
- 有効なOAuthリダイレクトURI
    - ここが要注意です。まず、サーバにauth用のフォルダを作っておいて、空ファイルで良いのでindex.htmlを入れておきます。
    - また、https:// で始まるのが必須です。http:// でははじかれます。
    - よって、私のサイトでは https://maguiwa.saloon.jp/auth/ となります。
- コールバックURLの許可の取り消しにはサイトのトップページのURLを入力。
- データの削除リクエストにもサイトのトップページのURLを入力。
- データ削除リクエストコールバックURLにもサイトのトップページのURLを入力。
さあ、もう一息です。
## Instagramテストユーザーを追加する
- 左側のタブから「役割」→「役割」を選択。
- ページの下部に、Instagramテスターという欄があるので、この右にある「Instagram テスターを追加」をクリック。
- 自分のinstagramアカウントを入力し、招待を送信します。
さて、今登録しているページは開いたまま、**PCのブラウザ**の自分のinstagramのページを開いてください。
- (プロフィールアイコン) →[プロフィールを編集] → [アプリとウェブサイト] → [テスターの招待]に移動し、招待を承諾します。
## 長期トークンを取得する
自分のInstagramのアカウントのみの情報を使う場合、ユーザートークンジェネレーターを使用するのが便利です。

https://developers.facebook.com/docs/instagram-basic-display-api/overview#---------------

開いていたアプリ登録ページに戻り、ページ下部にある「ユーザートークンジェネレーター」の欄の右側にある「Generate Token」をクリック。これで、長期トークンが表示されますので、大切に保管しましょう。

上部にある「アプリのモード」は「開発」のままでOKです。

「変更を保存」しましょう。お疲れさまでした。

# 次はAPIを使って、PythonによるCGIの作成です
ようやく本題に入れそうです。その3：PythonによるCGIの作成　に続きます。
# 目次
その1　[仕様](https://qiita.com/Golfull/items/a8ea7f05c179c3436649)
その2　Instagram API
その3　[PythonによるCGIの作成](https://qiita.com/Golfull/items/ea215b24c7c80742e648)
その4　[終わりに（全コード）](https://qiita.com/Golfull/items/cad94fcae19410e676c2)
Azure の Access Token を一時的な環境変数として利用する

## 概要

REST-APIでいろいろなAzureサービスを利用するときに Access Token が必要になります。Pythonプログラムでサクッと動作確認したいときに一時的な環境変数として利用したいなぁ〜　という個人的思いで確認してみました。


### 実行環境

macOS Monterey 12.3.1
python 3.8.12
azure cli 2.41.0

### Azure へのログイン

ローカルのターミナルからPythonプログラムを実行できる権限のアカウントでログインします。

```
$ az login --tenant [tenantId]
$ az account set --subscription [subscriptionName]
```

### Access Token の生成

ターミナルから Access Token を作成します。Tokenの有効期限はどうやら１時間くらいです。

```
(base) 22-10-25 9:01 ihoge $ az account get-access-token
{
  "accessToken": "eyJ0eXA・・・省略・・・CvuyFvw",
  "expiresOn": "2022-10-25 10:07:12.000000",
  "subscription": "eeeeeeee-1717-4343-9797-ffffffffffff",
  "tenant": "aaaaaaaa-2828-4646-5757-bbbbbbbbbbbb",
  "tokenType": "Bearer"
}
```

これを一時的環境変数として設定します。

```
$ export EXP_TOKEN=$(az account get-access-token --query 'accessToken' --output tsv)

※「=」の前後にスペースがあると以下のエラーとなります、、、、
$ export EXP_TOKEN = $(az account get-access-token --query 'accessToken' --output tsv)
zsh: bad assignment
```

設定した環境変数を確認します。

```
$ env | grep EXP_TOKEN                                                              
EXP_TOKEN=eyJ0eXA・・・省略・・・CvuyFvw

※以下のコマンドでも確認できます、、、
$ export -p
```

### Pythonプログラムで環境変数の取得

実行するプログラム

```python:temporary_env.py
import os

EXPORT_TOKEN = os.environ['EXP_TOKEN']
print(EXPORT_TOKEN)
print(type(EXPORT_TOKEN), "\n")
```

プログラムの実行
 
```
$ python temporary_env.py                                                           
eyJ0eXA・・・省略・・・CvuyFvw
<class 'str'> 
```

### まとめ

これでPythonプログラムからREST-API等のテストをサクッと行えそうです
さくらのレンタルサーバ ライトプランでPythonとSQLiteを使ってInstagramの投稿をランダム表示するサイトを作ってみた（その１：仕様）

## さくらのレンタルサーバがPython3対応に
さくらのレンタルサーバが新サーバになり、移行ツールを使って移行を完了。Python 3.8が使えるようになりました。（Gmailが届かなくなった話は[こちら](https://qiita.com/Golfull/items/acce17e02f5d8d445bba)を参照ください）
# Pythonでサイト構築
4月から猫を飼い始め、Instagramに写真をアップロードするようになりました[@maguandiwa](https://www.instagram.com/maguandiwa/)。そうすると、過去の写真が埋もれるなと思い、Instagramのapiを使って、アップした写真をランダムに表示するサイトを作ることにし、勉強も兼ねてPythonでサイト構築しよう！Flaskあたり使えば簡単でしょう！とウキウキしながらキーボードに向かいました。
## さくらのレンタルサーバ ライトプランの壁
SSHログインして、とか、勝手に考えていたのですが、ライトプランの壁にいきなりぶつかりました。
https://rs.sakura.ad.jp/lite.html
から、
- SSH不可
- MySQL不可（WordPressはMySQL前提なのでこれもできない前提。SQLiteでインストールしている方もいますが、イレギュラーなことは今回行わないことにします）
- SQLiteはOK
- SSI、CGIはOK
手を尽くせばFlaskも動くと思います。しかし、今回はシンプルに、CGIでできる限りのことをする。すなわち、Python3の標準ライブラリでできる範囲のことをすることに決めました。
## Instagramからのデータ取得
スクレイピング。。。とかよからぬことを考えましたが、普通にInstagram APIを使います。Instagram APIには
- Graph API
- 基本表示API
の2種類あり、今回はビジネスアカウントおよびMetaによる審査が必要ない基本表示APIを使うことにしました。
## 要件
- モバイル、PCともに閲覧可能とする。レスポンシブデザインとすること。
- ページの更新ごとに写真がランダムで変わること。
- 1ページのみのサイトとし、24枚の写真を掲載すること（2,3,4の倍数なので、列数が変化してもキリがいい）。
- タイトルと写真以外は極力掲載しないこと。
## 技術仕様
- HTML Living Standard,CSS3を用いる。対応していないブラウザは考慮しない。
- Instagram 基本表示APIを用いる。
- トップページはSSIを実行し、CGIを起動するだけのページとし、index.shtmlとする。
- CGIはPython3.8を用い、https://docs.python.org/ja/3/ に掲載されているライブラリ＋sqlite3以外のライブラリは使わない。
- DBはSQLiteを用いる。
### さあ、手を動かそう
とりあえずの仕様が決まったので、まずはInstagramの基本表示APIを使えるようにしましょう。その2：Instagram API に続きます。
# 目次
その1　仕様
その2　[Instagram API](https://qiita.com/Golfull/items/6863e2851be1390d492c)
その3　[PythonによるCGIの作成](https://qiita.com/Golfull/items/ea215b24c7c80742e648)
その4　[終わりに（全コード）](https://qiita.com/Golfull/items/cad94fcae19410e676c2)
wgetがなかったのでcurlで対処した

Macにはwgetがなく、参考書でいきなり出現したのでwgetの代わりとなるcurlの使い方をメモ

参考書内のwgetコマンドは

```terminal
wget URL -P 保存先ディレクトリ
```

となっているため、curlに置き換えて対処しました。

```console
curl URL > 保存先ディレクトリのパス/ファイル名
```

今回、私はgitのja.ymファイルを取得して、config/localesに保存したかったので
```terminal
curl [https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml](https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml) > config/locales/ja.yml
```
となりました。
vimのHelpをTabに表示する。

vimのHelpをTabに表示したほうが見やすいと思う。
```
:tab help
```
バッファ上では、すぐに消えてしまう。なんか不便です。
Tabでは消えない。

引用リンクでは、色々な開きかたが紹介されています。
- 引用リンク
    - [How to "full screen" browse Vim help?](https://vi.stackexchange.com/questions/358/how-to-full-screen-browse-vim-help)
配列の中のオブジェクト中の配列とある配列を比較して、同じ要素があるものを取得する

## やりたいこと

```
[
  {
    email: 'b@gmail.com',
    tags: ['VIP', 'male'],
  },
  {
    email: 'a@gmail.com',
    tags: ['VIP', 'male', 'cool'],
  },
  {
    email: 'c@gmail.com',
    tags: ['VIP', 'female'],
  },
  {
    email: 'd@gmail.com',
    tags: ['female'],
  },
];
```
これを

```
['female']
```
と比較して、femaleが入っている要素だけ取得したい
↓
```
[
  {
    email: 'c@gmail.com',
    tags: ['VIP', 'female'],
  },
  {
    email: 'd@gmail.com',
    tags: ['female'],
  },
];

```


## 解決方法
```
const customers = [
  {
    email: 'b@gmail.com',
    tags: ['VIP', 'male'],
  },
  {
    email: 'a@gmail.com',
    tags: ['VIP', 'male', 'cool'],
  },
  {
    email: 'c@gmail.com',
    tags: ['VIP', 'female'],
  },
  {
    email: 'd@gmail.com',
    tags: ['female'],
  },
];

const compareData = ['female', 'VIP'];

const result = customers.filter((el) =>
  el.tags.some((r) => compareData.includes(r))
);

console.log(result);
```

https://stackblitz.com/edit/typescript-buwaxe?file=index.ts
【JavaScript】アイコンでパスワードの表示を切り替える(複数)

![スクリーンショット 2022-10-25 151336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2041536/26c83c15-96d8-e5c5-34b4-8cbd4b102542.png)

アイコンを押下したらパスワードの表示/非表示を切り替え、なおかつアイコンも変化させたいと思いまして久しぶりJs,,
HTML側
~~~html:html
// font Awesome使用するにあたってのCDNコード
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
crossorigin="anonymous" referrerpolicy="no-referrer" />

<table>
    <tr>
        <th>パスワード</th>
            <td>
                <input type="password">
                //↓font awesomeアイコンコードの中にtoggle-eyeクラス追加付与
                <i class="fa-regular fa-eye toggle-eye"></i>
            </td>
    </tr>
    <tr>
        <th>パスワード(確認)</th>
            <td>
                <input type="password">
                //↓font awesomeアイコンコードの中にtoggle-eyeクラス追加付与
                <i class="fa-regular fa-eye toggle-eye"></i>
            </td>
    </tr>
</table>
~~~
JavaScript側
~~~javascript:js
 let eye = document.getElementsByClassName("toggle-eye");

 for(let i = 0; i < eye.length; i++){
    eye[i].addEventListener("click",() => { 
             if (eye[i].previousElementSibling.getAttribute('type') == 'password') {
                  eye[i].previousElementSibling.setAttribute('type', 'text');
                  eye[i].classList.toggle('fa-eye');
                  eye[i].classList.toggle('fa-eye-slash');
             } else {
               eye[i].previousElementSibling.setAttribute('type', 'password');
               eye[i].classList.toggle('fa-eye');
               eye[i].classList.toggle('fa-eye-slash');
             }
    });
}
~~~

●class取得の場合for文で回す必要がある
●previousElementSibling = (ひとつ前の要素)
●Attribute('type')  = (typeの属性)

class="toggle-eye"が付与されてる要素クリックされたとき、
ひとつ前の要素(この場合input)のtype="password"からtype="text"に変わり、
font awesomeアイコンコード class="fa-eye"から"class="fa-eye-slash"に変わります。

toggleなのでもう一度押下すると
ひとつ前の要素のtype="text"からtype=""password"に変わり、
font awesomeアイコンコード class="fa-eye-slash"から"class="fa-eye"に変わります。

~~ ~~ ~~ ~~ ~~ ~~

font awesomeですが、いつの間にかいろいろ仕様が変わっていました..

class取得によるパスワード表示/非表示がググってもあまり情報が無かった為
試行錯誤の末、完成したコードになります。
もっと効率の良い、簡略化できるものがございましたら
是非コメントにて記載お願い致します！
ターミナルからGitHubのブランチにプッシュする

この記事では、ターミナル操作でローカルにあるファイルをGitHubの指定ブランチにプッシュするまでの流れを説明します

## 1. ローカルリポジトリを作成
```ruby:qiita.rb
git init
```
まず、git init　でカレントディレクトリ直下に.gitディレクトリを作成します
この.gitディレクトリはローカルリポジトリとして機能します

## 2. リモートリポジトリに接続
```ruby:qiita.rb
git remote add origin リポジトリURL
```
ローカルリポジトリとリモートリポジトリを接続します
URLはGitHubの公式サイトから持ってきます

## 3. ブランチに接続
```ruby:qiita.rb
git checkout -b ブランチ名
```
リモートリポジトリのブランチに接続します
存在しないブランチを指定すると、ブランチを新たに作成することができます
-bはブランチ名が後ろに来ますよ、という意味です
デフォルトではmainブランチに接続されているため、そのまま使う場合は飛ばして大丈夫です

## 4. ファイルをステージに上げる
```ruby:qiita.rb
git add -A
```
```ruby:qiita.rb
git add ファイル名
```
ステージングエリアにファイルを追加します(ステージエリアと記載する記事も複数ありました)
ステージングエリアは作業ディレクトリとローカルリポジトリの間にあり、ローカルリポジトリに上げるファイルを一旦置いておくための場所として機能します
-Aを使うとカレントディレクトリ下の全てのファイルを追加できます

## 5. ローカルリポジトリにファイルを上げる
```ruby:qiita.rb
git commit -m 'メッセージ'
```
ステージにあるファイルをローカルリポジトリにアップします
このとき、チームメンバーへの伝言や自分用の備忘録としてメッセージを添えることができます


## 6. リモートリポジトリに反映する
```ruby:qiita.rb
git push origin ブランチ名
```
pushコマンドを使うと、先程接続したリモートリポジトリにローカルリポジトリの内容を反映させることができます
実行の途中でトークンの入力を求められる場合があります
トークンの取得については、以下のサイトを参考にさせて頂きました
kz800 「GitHub「Personal access tokens」の設定方法」 Qiita 2017/11/01
https://qiita.com/kz800/items/497ec70bff3e555dacd0
実行が完了すると、GitHubのページにも反映されているはずです
podmanでMySQLサーバー

# はじめに

podmanを利用して、MySQLコンテナーを立ち上げそこにホストPCからMySQLクライアントで接続したかったのだが、詳しい文献が見つからず四苦八苦したので、この手順を記しておく。

以下環境。

* macOS Monterey 12.6
* Podman（以下）

```
Client:       Podman Engine
Version:      4.3.0
API Version:  4.3.0
Go Version:   go1.18.7
Built:        Wed Oct 19 02:55:57 2022
OS/Arch:      darwin/amd64

Server:       Podman Engine
Version:      4.2.1
API Version:  4.2.1
Go Version:   go1.18.5
Built:        Thu Sep  8 04:58:19 2022
OS/Arch:      linux/amd64
```

# 手順

### イメージ取得

MySQLサーバーのみでよいので、`mysql-server`を取得している。

```
% podman pull mysql/mysql-server:5.7
```

確認。

```
% podman images

REPOSITORY                    TAG         IMAGE ID      CREATED      SIZE
docker.io/mysql/mysql-server  5.7         63d5ef161926  13 days ago  491 MB
```

### コンテナー起動

コンテナーを起動する。
`root`ユーザーのパスワードを`MYSQL_ROOT_PASSWORD`で指定、ホストPCの`3306`番ポートをコンテナーの`3306`に転送するように指定している。

```
% podman run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=XXXXXXXX --name mysql-server mysql-server:5.7
```

確認。

```
% podman ps

CONTAINER ID  IMAGE                             COMMAND     CREATED         STATUS                       PORTS                   NAMES
08cd2ff91f1d  docker.io/mysql/mysql-server:5.7  mysqld      10 minutes ago  Up 10 minutes ago (healthy)  0.0.0.0:3306->3306/tcp  mysql-server
```

### MySQLユーザーの追加

コンテナーのMySQLクライアントで接続。

```
% podman exec -it mysql-server mysql -hlocalhost -uroot -p
```

接続先任意の`root`ユーザーを作成、権限付与。その後切断。

```
mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'XXXXXXXX';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
mysql> FLUSH PRIVILEGES;
mysql> quit
```

### ホストPCから接続

ホストPCから接続するには以下のコマンドで。

```
% mysql -h127.0.0.1 -P3306 -uroot -p
```

ちなみに、以下のコマンドのような`localhost`だと、MySQLはUnixSocket使用しようとするらしくNG。`--protocol=tcp`を指定すればOK。

```
% mysql -hlocalhost -P3306 -uroot -p （→NG）
% mysql -hlocalhost -P3306 -uroot --protocol=tcp -p （→OK）
```
ネットワークセキュリティ

# ファイアウォール
### VPN
暗号化技術などを用いるfollowingとで、```安価な公衆網を仮想的な専用線（仮想私設網）```として利用するセキュリティ技術。
データをパケットで包んでカプセル化するので、社内LAN用にプライベートIPアドレスを用いたパケットでも通信可能になる。

* 「VPN」は「Virtual Private Network」の略で、日本語では```「仮想専用線」```と呼ばれます。
送信側、受信側にそれぞれに設置した機器で```「カプセル化」と呼ばれる処理を行うことで、第三者には見えない仮想的なトンネルを形成して通信する```仕組みです（「トンネリング」）。
また、通信時には正規の利用者であることを確認するために認証を行う、万一トンネルに侵入された場合に備えて```通信内容は暗号化```して送信する、などの技術を併せて採用することで、さらに通信の安全性を高めています。
これらの技術により、拠点間をいわば仮想の専用線で結び、安全に情報をやり取りすることができるわけです。

    * ```通信を暗号化できるため、安全に通信ができる```
    * ```リモートで社内ネットワークへのアクセスが可能（モバイル端末も可能）```
    * ```低コストで拠点間通信が可能```

    ### 出典
https://www.nttpc.co.jp/column/network/whats_vpn.html

### デメリット
低コスト・高セキュリティ・拠点間通信ができるVPN接続ですが、メリットがある一方でデメリットも存在します。両者をしっかりと把握して、自社にあったネットワーク整備を行いましょう。

* 情報漏洩がゼロとはいえない
* 通信速度が遅くなることもある
* 製品によってはコストが高くなる

#### 出典
https://www.nttpc.co.jp/column/network/whats_vpn.html

# 無線LANのセキュリティ規格
### WPA2/3(Wi-Fi　Protected Access2/3)
```無線LANの暗号化方式```のセキュリティ規格。
暗号化鍵の鍵長を増やし、```ユーザ認証とセキュリティ強化を図った```WPA2。
さらに
WPA２の```脆弱性への対応を図った```WPA3では、「SEA（同一入力データの認証）」による認証強化と機密性強化が行われた。

# ネットワークセキュリティに使われる対策及びシステム
### ポートスキャナ
ネットワーク上のコンピュータなどのかくポートに実際にアクセスして調べることで、```アクセス可能なポートや稼働中のサービスを調べる```管理用ソフトウェア。攻撃を目的として、```脆弱性のあるサービスが稼働していないか```を調べるためにも用いられる。

### ハニーポット
不正アクセスの手口やクラッカーの侵入経路を探るため、```意図的に脆弱性を残し```、「おとり」として設置するサーバやネットワークサービス

### リバースプロキシ
特定サーバ（複数可）の代理として、その```サーバへのリクエストを中継するプロキシサーバ```。ユーザがサーバへアクセスしようとした場合、そのリクエストはすべてリバースプロキシ経由になるため、中継時に```パケットをチェックしたり```、```シングルサインオン(一度の認証で複数のサービスを利用できる)```を実現したりすることが可能になる。

### OP２５B（Outbound Port 25 Blocking)
宛先ポート番号25への送信を禁止することで、スパムメールの防止や迷惑メールの削減の対策を行うこと。
ISP（インターネットサービスプロバイダ)が行うもので```ISP管理下のネットワーク（動的IPアドレス）から、ISP管理外のネットワークに向けたメールを制限する。
```ポート番号２５は、SMTP（メール送信ようプロトコル)```が利用するポートだが、ユーザ認証機能を持たないため不正利用されやすい。２５ポートを制限した場合は、SMTPーAUTHと５８７ポートを利用するなどでユーザ認証を行う。
* 迷惑メール対策の一環としてプロバイダで行われる規制のひとつで```「外部の25番ポート（メール送信で使うドア）には接続させないからな！」```な規制のこと
出典 https://wa3.i-3-i.info/word14981.html

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
正規表現メモ

よく使う正規表現のメモ

PHP

```php
$h = '<a href="https://google.com" title="google">Google</a>';

if(preg_match('!<a href="([^"]+)"[\\s\\S]*?>([\\s\\S]*?)</a>!', $h, $m)) {
	print_r($m);    // ==> Array ( [0] => Google [1] => https://google.com [2] => Google )
}

```

Nodejs

```Javascript
let h = '<a href="https://google.com" title="google">Google</a>';
let result = /<a href="([^"]+)"[\s\S]*?>([\s\S]*?)<\/a>/.exec(h);
if(result){
	console.log(result);
	/*
			[
				'<a href="https://google.com" title="google">Google</a>',
				'https://google.com',
				'Google',
				index: 0,
				input: '<a href="https://google.com" title="google">Google</a>',
				groups: undefined
			]
	 */
}

```
【R】パッケージインストール時のエラー（failed to lock directory）を解決する

※最新バージョンのWindowsやRの場合は問題なくインストールできるようです。

# 環境
OS: Windows 10 Pro (10.0.19043)
R: 4.1.2 (2021-11-01)
RStudio: 2021.09.0 Build351

# エラー内容
```R
> install.packages("sets")
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:

https://cran.rstudio.com/bin/windows/Rtools/
 パッケージを ‘C:/yourdir/R/win-library/4.1’ 中にインストールします 
 (‘lib’ が指定されていないため) 
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.1/sets_1.0-21.zip'
Content type 'application/zip' length 656297 bytes (640 KB)
downloaded 640 KB

package ‘sets’ successfully unpacked and MD5 sums checked
Error in install.packages : ERROR: failed to lock directory ‘C:\yourdir\R\win-library\4.1’ for modifying
Try removing ‘C:\yourdir\R\win-library\4.1/00LOCK’
```
エラーの指示通り「00LOCK」を削除しても解決しなかった（パッケージをインストールしようとすると自動生成されてしまう）。

# 解決方法


調べてみるとStack Overflowにも同様の質問があり、回答に従ってinstall.packages()の前に下記コマンドを実行することでインストールできた。
```R
options("install.lock"=FALSE)
```

https://stackoverflow.com/questions/14382209/r-install-packages-returns-failed-to-create-lock-directory