OmniAICreator/Qiita-1.07M huggingface dataset:
とある関数のとある値まででグラフ描画する

グラフを作成するとき、とある関数のとある値までで描画を打ち切りたいことがあり、ちょっと考え込んでしまったのでメモを残します。

まず、とある指数関数のグラフを描いてみます。

```python
import numpy as np
import matplotlib.pyplot as plt

def curve(x):
    return np.exp(0.1*x)

x = np.linspace(0, 60)
y = curve(x)

fig, ax = plt.subplots()
ax.plot(x, y, 'k')
plt.show()
````
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492516/73dab1ff-d874-878e-b6e5-f7078d8de2f8.png)

途中から立ち上がりが鋭くなり、横軸xが60で縦軸yが400ちょっとまであります。これを、縦軸が200を超えたところで打ち切りたいとします。いろいろな方法がありそうですが、np.whereでyの中身を判定して、その判定結果（TrueかFalseの配列）を変数に保存し、グラフ描画のときのxとyに[]を付けて判定結果でフィルタしてやれば実現できました。

すなわち、

```python
th = np.where(y<200) # yが200以下の場所
ax.plot(x[th], y[th], '-r')
```

という処理をした上でグラフ描画します。
全体のコードは以下のようになります（比較しやすくするため、打ち切らない値も併せて描画させています）。今回の処理では、ぴったり200の所で描画しなくなるのではなく、200を下回る最大の値の所で打ち切っています。そのため、場合によっては200の随分手前で描画が打ち切られることもありますので、そのような場合は、xの配列をnp.linspaceで作成するときに間隔を細かくすれば、ある程度対応可能です。

```python
import numpy as np
import matplotlib.pyplot as plt

def curve(x):
    return np.exp(0.1*x)

x = np.linspace(0, 60)
y = curve(x)

fig, ax = plt.subplots()
th = np.where(y<200) # yが200以下の場所
ax.plot(x, y, '--k', alpha=0.3)
ax.plot(x[th], y[th], '-k')
plt.show()
````
![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492516/cb0e8f36-7aeb-63b3-7634-372cf425cf36.png)

もっといい方法がある気がするのですが、当面はこれでしのげています。
【Python】有向グラフの最短経路に含まれる辺を列挙

辺の長さが1の有効グラフの最短経路に含まれる辺を列挙する方法メモ
最短経路が複数存在する場合は、そのうちの1つを出力する

```python
from collections import deque,defaultdict
# 頂点数:n
# 辺の数:m
n,m=map(int,input().split())
edge=defaultdict(list)
for i in range(m):
    # 0-indexにする
    s,t=map(lambda x:int(x)-1,input().split())
    # 遷移先の頂点と辺のindexを追加する
    edge[s].append((t,i))

INF=float('inf')
# 頂点0からの距離
dist=[]
# ひとつ前の頂点と辺のindex
back=[(-1,-1)]*n

def bfs(s):
    global dist,back
    dist=[INF]*n
    dist[s]=0

    q=deque()
    q.appendleft(s)
    while len(q)>0:
        now=q.pop()
        for to ,ind in edge[now]:
            if dist[to]!=INF: continue
            dist[to]=dist[now]+1
            back[to]=(now,ind)
            q.appendleft(to)

bfs(0)

used=set()
now=n-1
while now!=0:
    before, ind =back[now]
    used.add(ind)
    now=before

print(used)
```
## 実行結果

```:入力
4 4
1 2
2 3
2 4
3 4
```
```:出力
{0, 2}
```

# 参考
https://www.youtube.com/watch?v=nyIwxeVJlYc
Arduino IDE 2.3.2 の使い方

Arduino IDE 2.3.2 の使い方です。
次の画面は、M5StackCore2 のサンプルの helloworld.ino を開いたところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/55665cd2-5c18-1036-8991-3d4731f2776a.png)

## インストール

[Downloads](https://www.arduino.cc/en/software) から
arduino-ide_2.3.2_Linux_64bit.AppImage
をダウンロードします。

実行権限の付与

```bash
chmod +x arduino-ide_2.3.2_Linux_64bit.AppImage
```

Ubuntu では次のライブラリーをインストールします。

```bash
sudo apt install libfuse-dev
```

実行

```bash
./arduino-ide_2.3.2_Linux_64bit.AppImage
```

終了してから、また実行する時も同じです。

```bash
./arduino-ide_2.3.2_Linux_64bit.AppImage
```

M5StackCore2 を使うには、
File -> Preference で
Additional boards manager URLs: に次を入れます。

```text
https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/88ccfc1d-fad9-16f1-92f5-102698377de0.png)
pythonの"関数"でも、”関数"を引数として指定できる

#### pythonの"関数"でも、”関数"を引数として指定できる
例として、下記の関数を微分してやりたいとします。
```
def f_ex(x):
    return 2*x
```
例えば、関数に”関数”を引数として指定しない場合、下のように書けますが、取り回しが非常に悪いです。
```
def diff_ex(x):
    h = 1e-4
    return (2*(x+h)-2*(x-h))/(2*h)
``` 
実行例
```
>>> diff_ex(8)
1.9999999999953388
```
そこで、関数に”関数”を引数として指定してやることで、簡単に処理を使い回すことができます。
代入したい関数の引数記述部()を省略してやることで、関数に”関数”を引数として指定できます。
例えば、下記のように、好きな関数を引数として指定し、微分する関数を作ることができます。
```
def diff_f(f, x):
    h = 1e-4
    return (f(x+h)-f(x-h))/(2*h)
``` 
実行例
```
>>> diff_f(f_ex, 8)
1.9999999999953388
```
#### 参考・引用

https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585
ローカル→リモートリポジトリを紐づける際の躓き

躓き記念の自分メモです
# したい
ローカルフォルダをGitリモートリポジトリと紐づけたい
# 手順
1. リモートリポジトリを作る
    - リモートリポジトリのURLをコピー
1. ここからターミナル操作
    - `$ cd 紐づけたいローカルフォルダ` 
1. `$ git init`
    - git初期化 
1. `$ git remote add origin (リモートリポジトリURL)`
    - ローカルとリモートが紐付く 
1. `$ git add .`
    - ステージング 
1. `$ git commit -m "commitメッセージ"`
    - ローカルリポジトリにcommit
1. `$ git push origin HEAD`
    - 初push
1. `$ git rebase origin/main`
    - 「origin/main」と「ローカルmain」を一致させる 
        - 紐づけた直後はズレている。原因不明...
1. 作業開始

# 躓きポイント
8部分「origin/main」と「ローカルmain」のズレに対処できず
pushに対して延々このエラーに跳ね返される
`$ git rebase origin/main`であっさり解決
間違っても上書きするものもないしへーき、へーき...（たぶん）
```
 ! [rejected]        HEAD -> main (non-fast-forward)
error: failed to push some refs to '(リモートリポジトリURL)'
hint: Updates were rejected because the tip of your current branch is behind     
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.  
```
【JavaScript】Jestの実行で「Unexpected token '('」エラーが出た話

# 概要

Jestでテストを実行しようとしたところ、以下のエラーが表示されました。
```
C:\data\jest2\node_modules\@jest\reporters\build\GitHubActionsReporter.js:67
  #getMessageDetails (failureMessage, config) {
                     ^

SyntaxError: Unexpected token '('
    at Object.compileFunction (vm.js:344:18)
    at wrapSafe (internal/modules/cjs/loader.js:1106:15)
    at Module._compile (internal/modules/cjs/loader.js:1140:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1196:10)
    at Module.load (internal/modules/cjs/loader.js:1040:32)
    at Function.Module._load (internal/modules/cjs/loader.js:929:14)
    at Module.require (internal/modules/cjs/loader.js:1080:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (C:\data\jest2\node_modules\@jest\reporters\build\index.js:75:3)
    at Module._compile (internal/modules/cjs/loader.js:1176:30)
npm ERR! Test failed.  See above for more details.
```

このエラーの原因や解決方法を記載した記事がなかったので、本記事にそれらの情報を記載します。

# 環境

OS：Windows 10
Node.js：14.1
npm：8.15.0

# 原因

原因は、node.jsのバージョンが古かった事でした。
エラーが起きた箇所はGitHubActionsReporter.jsの67行目のgetMessageDetails関数です。
この箇所に記載されている内容は以下です。

```GitHubActionsReporter.js
#getMessageDetails (failureMessage, config) {
    const {message, stack} = (0, _jestMessageUtil().separateMessageFromStack)(
      failureMessage
    );
    const stackLines = (0, _jestMessageUtil().getStackTraceLines)(stack);
    const topFrame = (0, _jestMessageUtil().getTopFrame)(stackLines);
    const normalizedStackLines = stackLines.map(line =>
      (0, _jestMessageUtil().formatPath)(line, config)
    );
    const messageText = [message, ...normalizedStackLines].join('\n');
    return {
      file: topFrame?.file,
      line: topFrame?.line,
      message: messageText
    };
  }
```

先頭に#が記載されていますが、これはprivate methodやprivate fieldを定義する記法です。
つまり、getMessageDetailsはprivate methodです。
node.jsのバージョン14.5以前では、private methodはサポートされておらず、
これらのバージョンでprivate methodが定義されたクラスを読み込もうとすると、
上記のエラーが発生します。

# 解決方法

private methodがサポートされているバージョンにnode.jsをバージョンアップします（14.20以降）。
https://node.green/#ES2022-features-private-class-methods

参考までに、各OSごとのNode.jsバージョンアップ方法を以下に記載します。
・Windows
https://www.suzu6.net/posts/295-node-update-windows/
・Linux、Mac
https://parashuto.com/rriver/tools/updating-node-js-and-npm

# まとめ

Jestを使った記事は、どれも最近のNode.jsを使用しているので、このようなエラーが起きることもなく、結果として今回のエラーに関する情報がありませんでした。
Node.jsに限った話ではなく、ソフトウェアのバージョンを定期的にアップデートする事の大切さを痛感しました。
Stripeの自動送信メールの設定について


<p>こんにちは。Stripe開発者のけんけんです。</p>

<p>今日は、Stripeの設定についてお伝えいたします。</p>

<h2>Stripeの管理者宛のメール設定について</h2>
<p>1, Stripeにログインします。</p>
<p>2, プロフィールページにアクセス
https://dashboard.stripe.com/settings/user</p>

<p>3, 下の方にスクロールすると、「ダイレクト支払い」という項目があります。<br>
「成功した支払い」<br>
支払い成功のお知らせを受け取る。にチェックを入れてください。
</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65992/719c0d2f-dd71-ba23-ac19-032314afd83d.png">



<p>以上で設定完了です</p>



<h2>購入者宛のメール設定について</h2>
<h4>Stripeの設定で購入者様へ領収書メールを送信できます</h4>
<p>1, 対象のStripeアカウントにログインします。</p>
<p>2, こちらのページにアクセス
https://dashboard.stripe.com/settings/emails</p>
</p>
<p>3, 成功した支払いにチェック</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65992/ecb0c8bf-44a4-cd0f-a8e2-731f00cc0220.png">


<p>以上で設定完了です</p>

<h5>最後までお読みいただきありがとうございました。</h5>
SQL ４大命令　基本構文

・CHARとVARCHARの違い
CHARは固定長　
VARCHARは可変長

・SQL　４大命令
SELECT UPDATE DELETE INSERT

・SELECT文
``` SQL
SELECT 列名・・・　　--【例】ITEM,RECEIVE,PAY
FROM テーブル名
(WHERE 修飾)
(その他の修飾）　
```

・UPDATE文
```SQL
UPDATE テーブル名
SET 列名１＝値１,列名２＝値２・・・
(WHERE修飾)--WHEREのない文は全件更新
```

・DELETE文
```SQL
DELETE
FROM テーブル名
（WHERE 修飾）--WHEREのない文は全データ削除【要注意】
```

・INSERT文
```SQL
INSERT INTO テーブル名
　　　　　　　　　　　　　　　　　　　　　　　　（列名１、列名２、列名３・・・）
　VALUES     (値１、値２、値３・・・）
```
依存性のある複数引数を一時変数無しで設定する

※以下のプログラムはPython 2.7/3.9およびRuby 2.7でそのまま貼り付けて動作することを確認しています。

## 背景

ライブラリの挙動により、このようなことをしたいことがあると思います。

```py
process(config=json.load(open(fname)),data=get_data(config))
```

```rb
process(config: JSON.parse(File.read(fname)), data: get_data(config))
```

しかし、前側のパラメータに与えられる情報を後ろのパラメータで使うことはできません。

## 解決策

※以下、サンプルなのでconfig/dataという名前になっていますが、実際にはこの辺りはちゃんとした名前をつけてください

### 一時変数

こういう場合、通常はkwargs変数を用意して処理するのだと思います。

#### Python

```py
def process(**kwargs):  # actually defined in another module
    print(kwargs)

def get_data(config):
    return 1

kwargs = {
    'config': {},  # json.load(open('aaa.json'))
}
kwargs['data'] = get_data(kwargs['config'])
process(**kwargs)
# {'config': {}, 'data': 1}
```

#### Ruby

```rb
class C  # actually defined in another module
    def self.process(**kwargs)
        print(kwargs)
    end
end

def get_data(config)
    return 1
end

kwargs = {
    :config => {},  # JSON.parse File.read('aaa.json')
}
kwargs[:data] = get_data(kwargs[:config])
C.process(**kwargs)
# {:config=>{}, :data=>1}
```

### 似非関数型プログラミング

しかし、このkwargsという変数をどうしても入れたくない場合もあると思います。このような場合、PythonのlocalsやRubyのlocal_variablesを用いて関数型にすることができてしまいます!!!

#### Python

```py
def process(**kwargs):  # actually defined in another module
    print(kwargs)

def get_data(config):
    return 1

def build_args(fname):
    config = {}  # json.load(open(fname))
    data = get_data(config)
    del fname
    return locals()

process(**build_args('aaa.json'))
# {'config': {}, 'data': 1}
```

#### Ruby

- delに相当するものがRubyにはないので、Hashの要素を削除する必要があります。一時変数…と思いきや、Rubyには_1があるので安心です。

```rb
class C  # actually defined in another module
    def self.process(**kwargs)
        print(kwargs)
    end
end

def get_data(config)
    return 1
end

def build_args(fname)
    config = {}  # JSON.parse File.read(fname)
    data = get_data(config)
    return local_variables.zip(local_variables.map(&binding.method(:local_variable_get))).to_h.tap{_1.delete(:fname)}
end

C.process(**build_args('aaa.json'))
# {:config=>{}, :data=>1}
```

## 最後に

通常、`data = get_data(conf)`に相当する操作は、data=None(やnil)を渡した上で、ライブラリ側でdata is None(なりnilなり)のときに実行することだと思います。この記事で紹介した方法はライブラリ側を変更できない場合のみにしてください(というか必要ないならやらないでください)。

## 蛇足

このPythonサンプルをRubyに移植したのが私がRubyで初めてkwargsをまともに使ったプログラムになってしまいました^^;
Python基礎 リスト、タプル、セット、ディクショナリ

## リスト
### append() リスト末尾に要素を追加する
```
>>> example = [1,2,3]
>>> example.append(4)
>>> example
[1, 2, 3, 4]
```
### extend() リストにリストを追加する
```
>>> animal = ['elefant', 'giraffe', ['cat', 'dog']]
>>> sea_animal = ['octopus', 'dolphin']
>>> animal.extend(sea_animal)
>>> animal
['elefant', 'giraffe', ['cat', 'dog'], 'octopus', 'dolphin']
```
### insert() リスト内の特定のインデックスに要素を追加できる
```
>>> animal.insert(2, 'lion')
>>> animal
['elefant', 'giraffe', 'lion', ['cat', 'dog'], 'octopus', 'dolphin']
```
### remove() リストから特定の要素を削除する
```
>>> animal.remove('giraffe')
>>> animal
['elefant', 'lion', ['cat', 'dog'], 'octopus', 'dolphin']
```
### pop() 指定した位置の要素を削除して、値を取得する
```
>>> print(animal.pop(0))
elefant
>>> animal
['lion', ['cat', 'dog'], 'octopus', 'dolphin']
```
### clear リストから全要素を削除する
```
>>> animal.clear()
>>> animal
[]
```
### index() 指定した要素のインデックスを調べる
```
>>> x = ['a', 'b', 'c', 'd', 'e']
>>> x.index('a')
0
>>> x.index('d')
3
```
### count() 指定した要素の数を調べる
```
>>> color = ['red', 'blue', 'green', 'blue', 'pink', 'red']
>>> color.count('red')
2
```
### sort() リストを小さい順or大きい順に並び替えられる
```
# 小さい順 
>>> x = [5, 97, 217, 2, 38, 46, 194, 275, 340, 381, 3, 6]
>>> x.sort()
>>> x
[2, 3, 5, 6, 38, 46, 97, 194, 217, 275, 340, 381]
# 大きい順は(reverse=True)とする
>>> x.sort(reverse=True)
>>> x
[381, 340, 275, 217, 194, 97, 46, 38, 6, 5, 3, 2]
```
### reverse() リストの並び順を逆にできる
```
>>> x.reverse()
>>> x
[2, 3, 5, 6, 38, 46, 97, 194, 217, 275, 340, 381]
```
## タプル
### , で区切って格納すると、(値, 値)で出力される。
```
>>> num = 1, 2, 3
>>> num
(1, 2, 3)
```
### インデックスを指定できる。
```
>>> num[0]
1
```
### 入れ子にできる。
```
>>> num = (1, 2, 3, (4, 5, 6))
>>> num[0]
1
>>> num[3]
(4, 5, 6)
```
### 注意!　タプルはリストと違って要素を変更できない。
```
>>> num[0] = 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
```
### シーケンスアンパック
1. testに1, 2, 3を入れる
1. 変数a, b, c　にをtestを入れる
1. a, b, cそれぞれに1, 2, 3が入ってる
```
>>> test = (1, 2, 3)
>>> a, b, c = test
>>> test
(1, 2, 3)
>>> print(a)
1
>>> print(b)
2
>>> print(c)
3
>>> print(a, b, c)
1 2 3
```

## セット
### {}で囲ったセットの中から、重複した要素は1つにして、出力してくれる。
```
>>> sport = {'soccer', 'basketball', 'baseball', 'soccer', 'tennis', 'baseball', 'swimming', 'run'}
>>> print (sport)
{'swimming', 'run', 'soccer', 'basketball', 'baseball', 'tennis'}
```
### 「in」を使ってセットの中身の存在判定ができる。
```
>>> 'football' in sport
False
>>> 'soccer' in sport
True
```
## ディクショナリ
### {}の中にキーと値を入れる。
``` 
>>> test = {'math':80, 'science':85, 'English':78}
>>> test
{'math': 80, 'science': 85, 'English': 78}
```
### ディクショナリに値を追加する時は「['キー'] = 値」の形。{}ではなく、[]なので注意。
```
>>> test['japanese'] = 90
>>> test
{'math': 80, 'science': 85, 'English': 78, 'japanese': 90}
```
### list(変数名) でキーだけ取り出せる。
```
>>> list(test)
['math', 'science', 'English', 'japanese']
```
### sorted(変数名)でアルファベット順もしくは数字順に並べられる。
```
>>> sorted(test)
['English', 'japanese', 'math', 'science']
```
### セットと同じく「in」を使って中身の存在判定ができる。
```
>>> 'history' in test
False
>>> 'English' in test
True
```
cronとシェルスクリプトで定期実行プログラムを作る

## はじめに

### この記事でやること

- cronとシェルを使って定時実行するプログラムを作る
- cronの設定方法


### この記事でやらないこと

- シェルスクリプトの書き方

### 投稿者の実行環境

- Mac

# 手順
[1.ゴール](#1-ゴール)
[2.実行するソースコードを作成](#2-実行するソースコードを作成)
[3.cron設定](#3-cron設定)
[4.動作確認](#4-動作確認)

## 1. ゴール

- 定期的に 今日の日付のディレクトリ を作ってくれるプログラムを作る

## 2. 実行するソースコードを作成

- 実行したい shファイルを作る
- 今回用意したのは下のようなプログラム (`createDirectory.sh`)

```sh
#!/bin/bash

#########################################
#
# 今日の日付でディレクトリを作成する プログラム
#
#########################################

#########################################
# 設定
#########################################
basePath=/hoge ...　ディレクトリを作りたいベースパス
dirName=`date "+%Y%m%d"` # ディレクトリ名 ... 今日の日付

#########################################
# メインプログラム
#########################################

cd $basePath

# ディレクトリを作成する

# もしすでにディレクトリがあれば作らない
if [ -d $basePath/$dirName ]; then
    echo "すでにディレクトリ:${dirName}は存在します"
else
    echo "ディレクトリ:${dirName}を作成します"
    mkdir $basePath/$dirName
fi
```

## 3. cron設定

- ターミナルで以下のコマンドを実行
    - `crontab -e`
- エディターが開かれるので以下の記述を追加


```vim
* * * * * sh /hoge/createDirectory.sh
```

###### 最初の * 印 5つで実行したい時刻を設定できる

| * | * | * | * | * | 
| -- | -- | -- | -- | -- | 
| 分 | 時 | 日 | 月 | 曜日(0:日 ~ 7:土) |

- 追加したら `:wq!` で保存してエディターを閉じる


## 4. 動作確認

- `~/D/test`配下に今日の日付(2022/09/23)でディレクトリを作ってみる
- **14:50** にプログラムが自動実行されるようにcronの時刻を設定する

#### cron実行**前**

- 14:49時点だとディレクトリは作成されていない

![スクリーンショット 2022-09-23 14.49.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851499/ade7b854-05c6-da6e-cc90-682aa54c6edf.png)

#### cron実行**後**

- 14:53時点だと ディレクトリ `20220923` が作られている

![スクリーンショット 2022-09-23 14.53.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851499/4998621f-d851-f071-e86c-2a60ff494b68.png)



## 最後に

- mac だと `automator` を使っても自動実行プログラムを組めるけど、UI操作が面倒だった
- `crontab` ならcronの時刻設定をして、実行したいプログラムを指定するだけなので楽
- 注意点としては、`crontab -r`でcron設定が吹き飛ぶらしい。
    - e と r キーは隣同士なので打ち間違いに気をつける。
    - [参考: crontab -e は「絶対に」使ってはいけない](https://ozuma.hatenablog.jp/entry/20120711/1342014448)
Rust で素数計算する


# コード

可変の配列にはベクタ型というものを使うようだ。

```rs
fn main() {

let mut i = 1;
let mut numbers = vec![];

    loop {
        i += 1;
        let mut prime = true;

        for number in &numbers {
            if i % number == 0 {
                prime = false;
            }
        }
        if prime {
            println!("{i} Prime");
        }

        numbers.push(i);
    }
}
```

# 実行結果

```
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
101
103
...
```

# 参考

https://doc.rust-jp.rs/rust-by-example-ja/std/vec.html

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
AndroidStudioのコードコンプリートで大文字小文字関係なく候補を出したい

`Preferences | Editor | General | Code Completion` → `Match case` のチェックを変える。

新たにインスタンス作るときとかクラス名入力時に大文字入力しなくて済むので、チェックを外すのがおすすめです。


![スクリーンショット 2022-09-23 14.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168872/85f1d282-1e91-c873-ffd0-ef2d21fe0abf.png)


# onの場合
`First letter only` を選択している場合は、一文字目が同じものが候補に出てくる。
`All letters` を選択している場合は、全文字同じものだけ候補に出てくる。

# offの場合
文字種があっているが候補に出てくる。
あえて便利にしないUI/デザイン (Quoraの回答リクエスト)

# 回答リクエスト上限

Quoraという質問サービスでは、自分が質問をする時にユーザーに回答リクエストが出来る。

1質問あたり25件が上限だ。
25人にリクエストするには1個ずつボタンを押していなかければいけない。けっこう手間がかかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/e080e637-20cd-f0da-9208-374ccf7e6966.png)


ここで改善案として「上から25件一気に選択する」というボタンを付けてしまいたくなるが、Quoraはそうしていない。

質問者が「答えが欲しい気持ち」に応じて回答リクエストがおこなわれるようにデザインしているのではないだろうか。
すごく答えが欲しい人は手間をかけてもリクエストする。そうでない人はリクエストをあまり送らない。

# ユーザーのコスト調整をすることでデザインが変わる

何でもかんでも便利にすれば良いというものではない。

# 余談: コストが体験である場合

たとえばゲームだとコストをかけること自体が体験だ。

そういえばポチポチとボタンを押していくタイプのスマホゲーのひとつで、なんか「一括でボタン押すボタン」みたいなのがたくさんあって、本当につまらない作業になっていた記憶がある。

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Java　ジェネリクス・ラムダ式

・ジェネリクス
ジェネリクスを使って宣言されたクラスは＜〜＞記法を利用できる。
Eは仮型引数という仮の型名でStringなどのインスタンスの型に置き換えられる。
（intなどの基本データは利用できない。ジェネリクスを用いたクラスの配列を作れない）
``` Java:Pocket.java
public class Pocket<E>{
    private E data;
    public void put(E d) {this.data=d;}
    public E get(){return this.data;}
}
```
Eの型は制限をすることもできる
```Java
public class Pocket<E extends Character>
```
メソッドにも使える
```
public static <T> List<T> asList(T... a)
```

・ラムダ式
これを使うとメソッドにアルゴリズムを渡せる

```Java
import java.util.function.*;

public class Main{ 
    //[構文]（型　引数名１、型　引数名２、・・・・）->{処理；　return 戻り値；}
    public static void main(String[] args)throws Exception {
        Function<String, Integer>func=
            (String s)->{return s.length();};
        int n=func.apply("Java");
        System.out.println("文字列Javaは"+n+"文字です");      
    }

}
```
TwitterのDMで送られた動画・ボイスメッセージをPowershellでダウンロード

なんか検索しても見つからなかったので．備忘録です．

:::note warn
皆さんおなじみ[TwiDropper](https://twidropper.appspot.com/tweet)にも以下のように書かれています：

>著作権者の許可なくアップロードされた動画をダウンロードすることは法律で禁じられています。違法ダウンロードを行ってはいけません。

違法なダウンロードをしてはいけません．
:::

# モチベーション
親しい人から送ってもらった動画やボイスメッセージ，（もちろん相手の許可を受けた上で）残しておきたいですよね？

しかし[TwiDropper](https://twidropper.appspot.com/tweet)でダウンロードできるのはDM内の画像と動画だけで，ボイスメッセージは未対応なご様子．検索かけても画面録画を使えなどというエンジニアにとってはナンセンスな方法しか表示されなかったので，じゃあ作るかと．

# 余談：TwiterのDMのボイスメッセージ？

iPhoneやAndoroidのTwitterアプリから利用できる機能で，DM画面（下図）における，黄色い矢印が指すアイコンをタップすると送れます．

![whatisvoice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319806/c3e15598-d75f-5c12-9ec1-b37779b8d9a0.png)

送ったボイスメッセージは`▶ 0:05`と示されているもので，タップすると聞けます．

# 手法
手続きは以下です：
1. PCのchromeでTwitterの当該DMを開く
1. chromeのデベロッパツールを開き，Networkタブを準備する
1. 動画 or ボイスメッセージを再生し，`m3u8`を見つける
1. ffmpegで`m3u8`を`.mp4に変換する`

各ステップの詳細は以下です．また以降では，ボイスメッセージをダウンロードする条件で話を進めますが，動画でも全く同じ手続きでダウンロードすることが可能です．

## PCのchromeでTwitterの当該DMを開く

さあ開いてください．2022/09/23現在，以下のような画面です．以下の画面はボイスメッセージを受け取ったアカウントの画面です．

![dm-screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319806/5353ce90-caa5-4b82-2526-42da28728a6c.png)

## chromeのデベロッパツールを開き，Networkタブを準備する

おなじく開いてください．Winであれは`Ctrl + Shift + I`ですね．皆さんおなじみです．

![dm-develop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319806/41cabd8c-955f-6a70-0a94-10ee238573fa.png)

## ボイスメッセージを再生し，`m3u8`を見つける

以下の図，黄色矢印の①，②，③に従ってください．詳細な工程は図の以下のテキストで解説します．

![dm-record-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319806/3adeab12-bba8-93c2-69a4-1dbf703c2a61.png)

まず①で，ボイスメッセージを再生します．どうやらボイスメッセージはストリーミング再生されるようですので，とかく再生して，音声のファイルを受け取っておきます．

:::note info
赤矢印が示す場所をうまく使うと，ダウンロードされたファイルがわかりやすくなったりならなかったりします．
:::

次に②で，表示するファイルが`m3u8`だけになるようにフィルタリングしておきます．

:::note info
`m3u8`はストリーミングされたメディアのプレイリストのテキストファイルのようです．詳細興味ある方は適宜検索してください．
:::

最後に③で，`m3u8`ファイルを選び，そのURLをコピーします．ファイルを右クリックし，`Copy -> Copy link address`で，当該`m3u8`のURLをクリップボードに残しておいてください．

:::note warn
`m3u8`ファイルはいくつか表示される可能性があります．どれかが当たりでどれかが外れです．どちらを選んでも音声はダウンロードできるみたいですが，最終的に`.mp4`にした時の仕上がり？が良いものと悪いものがあるっぽいです．まあ片っ端からダウンロードして様子を見ましょう．
:::

## ffmpegで`m3u8`を`.mp4に変換する`

以下のスクリプトでffmpeg経由でボイスメッセージをダウンロードし，`.mp4`として保存することが可能です．以下はPowershellを使用していますが，お好きなシェルでいい感じにしてください．

```powershell
$m3u8 = "<さきほどコピーしたURL>"

& ffmepg -i $m3u8 -movflags faststart -c copy -bsf:a aac_adtstoasc output.mp4
```

余談ですが，どうやら，ボイスメッセージは映像としてストリーミングされているようです．なので映像がファイルとして残ります．

ダウンロードするスクリプトは以下のエントリを参考にしました．というかそのままです．

https://sleepygamersmemo.blogspot.com/2021/01/convert-m3u8-to-mp4-with-ffmpeg.html

# おわりに

仕組みがわかれば意外と簡単です．

繰り返しですが，くれぐれも違法なダウンロードはしないでください．あとこれTwitterの利用規約に反してないですよね？規約違反をしたいわけではないので，その場合は誰か教えてください．

# 追記＠2023/04/30
DMで送られた動画に対しても同じ手続きでダウンロードができることを確認できたため，タイトルや一部文章を変更しました．
ChatworkAPIで取得したトークルームオブジェクトのプロパティ

GASのChatworkライブラリでは、トークルームなどの情報をオブジェクトで取得できる。

以下のコード。
```javascript
const cw = ChatWorkClient.factory({token: api_token});
let rooms = cw.getRooms();
Logger.log(rooms);
```

上記を実行すると、以下のようなオブジェクトが渡される。

```JSON
{
    room_id=2.72790963E8,
    unread_num=0.0,
    task_num=0.0,
    sticky=false,
    mytask_num=0.0,
    mention_num=0.0,
    role=member,
    message_num=95.0,
    type=group,
    last_update_time=1.656584449E9,
    name=サンプル,
    file_num=4.0,
    icon_path=https://appdata.chatwork.com/icon/ico_group.png}
```

プロパティはそれぞれ以下のような意味を持つ。

| プロパティ名 | 意味 |
|:-----------|:------------|
| room_id | トークルームのID。大体これがほしい。 |
| unread_num | 未読メッセージの数 |
| task_num | タスクの数 |
|sticky| ピン止めしてるかどうか |
|mytask_num| 自分に割り当てあられたタスクの数 |
|mention_num| 未読のうちメンションされている数 |
|role| メンバー権限。{admin:管理者, menber:メンバー} |
|message_num| 総メッセージ数 |
|type| トークルームの種類。{direct:個別チャット, group:グループ} |
|last_update_time| 最終投稿日時。（リベラル値で取得される） |
| name | トークルームの名前 |
| file_num | アップロードされたファイルの数 |
| icon_path | チャットに表示されるのアイコン画像のURL |
Xcode14のXcode Previewsでエラー `error: '__designTimeString(_:fallback:)' is only available in iOS 13.0 or newer`

### 前提
現在開発中のiOSアプリは幅広いユーザー層を考慮し、現時点ではiOS12もサポート対象となっています。その環境ではSwiftUIを使用することはできませんが、UIKitのビューの開発効率を上げるために、次のコードのように`UIViewRepresentable`を用いてXcode Previewsでビューをプレビューできるようにしています。

```swift:SampleLabel.swift
import UIKit

class SampleLabel: UILabel {
    override init(frame: CGRect) {
        super.init(frame: frame)
        construct()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        construct()
    }
    
    private func construct() {
        text = "Sample"
    }
}

#if canImport(SwiftUI) && DEBUG
import SwiftUI

@available (iOS 13.0, *)
struct SampleLabelWrapper: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        SampleLabelWrapper()
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {}
}

@available (iOS 13.0, *)
struct SampleLabel_Previews: PreviewProvider {
    static var previews: some View {
        SampleLabelWrapper()
    }
}
#endif
```

### Xcode14のXcode Previewsで発生したエラー
今回、開発環境をXcode14にアップデートしたところ、このようなコードでのXcode Previewsで次のエラーが発生するようになり、プレビューができなくなってしまいました。

```
error: '__designTimeString(_:fallback:)' is only available in iOS 13.0 or newer
text = __designTimeString("#4947.[1].[2].[0].[0]", fallback: "Sample")
```

このエラーが起きている箇所は、`text = "Sample"`の部分です。StringやIntといったプリミティブな型の定数が書かれているところ全般に`__designTime~`という関数が差し込まれているようです。これがプレビューのために非公開APIで、iOS13以降でしか使用できないためにエラーとなっていそうです。

しかし、なぜUIKitのビューにプレビューのためのコードが差し込まれてしまうのでしょうか...

(参考) [XcodePreviews の仕組み](https://gist.github.com/AkkeyLab/67af9a91498c6c5ad138123cb8ae5c28)

### 回避策
この問題が回避できないと開発効率に大きく影響するため、回避策を探りました。結論としては以下の２つです。

- （当たり前ですが）開発中だけMinimum Deployment TargetをiOS13以降にする
- UIKitのビューのコードと、PreviewProviderのコードを別のファイルに記述する

（検証時のコードはこちら 👉 https://github.com/temoki/Xcode14PreviewsBug）

後者について、次のように別のファイルに記述することでこのエラーは発生しなくなります。

```swift:SampleLabel.swift
import UIKit

class SampleLabel: UILabel {
    override init(frame: CGRect) {
        super.init(frame: frame)
        construct()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        construct()
    }
    
    private func construct() {
        text = "Sample"
    }
}
```

```swift:SampleLabel+Previews.swift
#if canImport(SwiftUI) && DEBUG
import SwiftUI

@available (iOS 13.0, *)
struct SampleLabelWrapper: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        SampleLabelWrapper()
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {}
}

@available (iOS 13.0, *)
struct SampleLabel_Previews: PreviewProvider {
    static var previews: some View {
        SampleLabelWrapper()
    }
}
#endif
```

おそらくですが`__designTime~`を差し込む条件が、`PreviewProvider`の記述のあるコード全体になっているのではにでしょうか。そのためUIKitのViewのコードにも差し込まれているのではないかと思います。

本件はAppleにフィードバック済みですので、Xcode14.1あたりで修正されてくれることを祈ります。
SpringBootによる画像アップロード機能を作成する際の注意点

## ポイント
- Spring Security の設定を見直す
- ResourceHandler の設定をする

## 参考

https://www.codejava.net/frameworks/spring-boot/spring-boot-file-upload-tutorial

上記のサイトを参考に説明します。
英語で書かれたページですが、やってる事はそのままです

## ポイント1 ) Spring Security の設定を見直す
これは以下サイトでも触れているのですが、なかなかわかりにくい点になります。

https://morymory.com/2019/12/17/spring-boot%E3%81%AEstatic%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E5%86%85%E3%81%AB%E7%94%BB%E5%83%8F%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%EF%BC%88%E5%A4%B1%E6%95%97%E8%AB%87/

>認証にはspring securityを使用しておりあすので、WebSecurityConfigurerAdapter内で認証から除外する必要があります。これを行わないと、フォルダにアクセスができません。
>```java
>    @Override
>    public void configure(WebSecurity web) >throws Exception {
>        >web.ignoring().antMatchers("/favicon.ico", >"/css/**", "/js/**", "/images/**",
>                "/fonts/**","/upload/**");
>    }
>```

images配下のデータへのアクセスを許可する記述です。
参考サイトでも述べられているように、セキュリティの関係で必要になります。

## ポイント2 ) ResourceHandler の設定をする

>アップロードされたファイルを含むディレクトリを公開し、クライアント（ウェブブラウザ）がアクセスできるようにする必要があります。以下のようなコードで設定ファイルを作成します。(*本文訳)
>
>```java
>    @Override
>    public void addResourceHandlers(ResourceHandlerRegistry registry) {
>        exposeDirectory("user-photos", registry);
>    }
>     
>    private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) {
>        Path uploadDir = Paths.get(dirName);
>        String uploadPath = uploadDir.toFile().getAbsolutePath();
>         
>        if (dirName.startsWith("../")) dirName = dirName.replace("../", "");
>         
>        registry.addResourceHandler("/" + dirName + "/**").addResourceLocations("file:/"+ >uploadPath + "/");
>    }
>```

ResorceHandolerはSpring フレームワークが静的リソースをクライアントに提供するためのSpringフレームワークのクラスです。
→ ドキュメント : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.html

addResourceHandler() によって静的リソースの読み込みのためのパスを追加します。

## 最後に
画像表示に関しての設定は、日本語記事では解決方法がなかなか見つからず非常に苦労しました。

不明点や、 深掘りして欲しい点がありましたらコメントをいただけますと幸いです。
Ruby と crystal における clone メソッドの違い

# はじめに
AtCoder さん、ありがとうございます。

# 結論
||clone|
|:--:|:--:|
|Ruby|浅い (shallow) コピー|
|crystal|深い (deep) コピー|

# E - SNS のログ
https://atcoder.jp/contests/past201912-open/tasks/past201912_e
# Ruby clone（WA）
```rb
n, m = gets.split.map(&:to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
  s = gets.split.map(&:to_i)
  case s[0]
  when 1
    a[s[1]][s[2]] = "Y"
  when 2
    (1..n).each do |i|
      a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
    end
  when 3
    b = a.clone
    (1..n).each do |i|
      if b[s[1]][i] == "Y"
        (1..n).each do |j|
          a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
        end
      end
    end
  end
end
(1..n).each do |i|
  puts a[i][1..].join("")
end
```
```rb:WA
NYYYYY # NYYNYY
NNYNNN
NNNYNN
NNNNNN
NNNNNY
YNNNYN
```
下記のリファレンスマニュアルにある通り、**clone**は`浅い(shallow)コピー`であるため、配列の変更結果が反映されてしまします。

https://docs.ruby-lang.org/ja/latest/method/Object/i/clone.html
# Ruby Marshal（AC）
```diff_ruby
n, m = gets.split.map(&:to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
  s = gets.split.map(&:to_i)
  case s[0]
  when 1
    a[s[1]][s[2]] = "Y"
  when 2
    (1..n).each do |i|
      a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
    end
  when 3
-    b = a.clone
+    b = Marshal.load(Marshal.dump(a))
    (1..n).each do |i|
      if b[s[1]][i] == "Y"
        (1..n).each do |j|
          a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
        end
      end
    end
  end
end
(1..n).each do |i|
  puts a[i][1..].join("")
end
```
Rubyで`深い (deep) コピー`といえば**Marshal**、頻繁に使用されます。

```rb
    b = Marshal.load(Marshal.dump(a))
```
https://docs.ruby-lang.org/ja/latest/class/Marshal.html
# crystal clone (AC)
```cr
n, m = read_line.split.map(&.to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
  s = read_line.split.map(&.to_i)
  case s[0]
  when 1
    a[s[1]][s[2]] = "Y"
  when 2
    (1..n).each do |i|
      a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
    end
  when 3
    b = a.clone
    (1..n).each do |i|
      if b[s[1]][i] == "Y"
        (1..n).each do |j|
          a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
        end
      end
    end
  end
end
(1..n).each do |i|
  puts a[i][1..].join("")
end
```
crystalでは**clone**が`深い (deep) コピー`なんですね。

https://crystal-lang.org/api/0.33.0/Array.html#clone-instance-method
# まとめ
+ crystalに詳しくなった
+ 久々に更新しました

https://github.com/superrino130/crystal-on-paiza.cloud
[Docker] 備忘録：全てのコンテナ、イメージ、ボリュームを削除する方法

## はじめに

業務でDockerのコンテナやイメージを全て削除することが多々あるのですが、毎回調べるのも疲れるので備忘録として残しておく〜。


### 全てのコンテナを削除

```bash
docker rm -vf $(docker ps -aq)
```

### 全てのイメージを削除
```bash
docker rmi -f $(docker images -aq)
```

### 全てのボリュームを削除
```bash
docker volume rm $(docker volume ls -q)
```

### キャッシュの削除
```bash
docker system prune -a
```
catコマンドでファイルに書き込み（上書き＆追記）

# ファイルの中身を確認
```
# cat test.txt 
abc
```

# ファイルの上書き
入力完了後、[ctrl]+[d]で上書き
```
# cat > test.txt 
ABCDE
```
以下の入力のみで上書き
```
# cat <<EOF > test.txt
> ABC
> EOF
```

# ファイルに追記
入力完了後、[ctrl]+[d]で追記
```
# cat >> test.txt 
FGHIJ
```
以下の入力のみで追記
```
# cat <<EOF >> test.txt 
> KLMNO
> EOF
```
普通にコマンドラインで書き込むなら、`vi`で書き込めば良い。
自動化させるとか、マニュアルに落とし込んで誰でも使えるようにするときは、こっちの方がいいかも。
Rust – 文字列の変数定義で別の変数を埋め込む

# 例

format! 関数を使う必要があるようだ。

```rs
let world = "World";
let hello_world = format!("Hello {world}");
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
git clone で悩まない

# 【git clone で悩まない】
- 全社的にさまざまなものを GitHub管理をしているので、入社後すぐにPull Requestを作成する必要があった。
- 前職ではシステム開発のみ、GitHubを使用していたので `Workspace` のようなフォルダを作って、そこに全てのリポジトリを `git clone` していた。
- 稟議等の申請もGitHub管理なので、どのようにフォルダを分けて、`git clone` をすればよいか迷ってしまった。
    - -> **その時に、とても心強い** `ghq` **というものを教えていただいた**
        - `git clone` をどこにしようという悩みから開放された
        - どこに clone したっけ？という悩みから開放された
## ghq
- ghqはGOで作られたライブラリ
    - Homebrew等で簡単にインストールできる

### ghqの導入
```
# Homebrewを使って、インストール
$ brew install ghq
# インストールできたことを確認
$ ghq -v

# ghqを使って、cloneをする
$ ghq get （GitHubからURLを取得）

# リポジトリの一覧を確認する（-pを付けるとフルパス）
$ ghq list
```

※GitHubに鍵を登録をすることは、通常の `git clone` 時と同様に必要です。

### 実践
- まず、`peco` をインストール
```
# Homebrewを使って、インストール
$ brew install peco
```

- `ghq list` を `peco` で選び、そこへ移動するキーバインドを設定する
```
# zshを使っている場合
$ vi ~/.zshrc 
alias repo='cd $(ghq list --full-path --exact| peco)'
```

- `repo` と打つと、ローカルのリポジトリに移動ができる
```
$ repo

QUERY>                                                  IgnoreCase [2 (1/1)]
/Users/XXXXXX/ghq/git.XXXXX.com/hogehoge1
/Users/XXXXXX/ghq/git.XXXXX.com/hogehoge2

# キャンセルしたければ、esc
```

## おわりに
- Qiita投稿の間隔が空きすぎた
- LPIC-2 の資格勉強や技術書を読むことに時間を使っていた
- 転職したので、心機一転、テックブログを始めようかと思っている
    - （記事のレベルに関わらず、アウトプット大事）
- 初日から学べることが多くて楽しかった、これからもっと頑張っていきたい。

## 参考
- [Gitリポジトリ管理の強い味方！ghq](https://tech-broccoli.life/articles/engineer/use-ghq/)
- [[peco][ghq]ssh,history,リポジトリに瞬殺で移動できるとか神か！](https://blog.adachin.me/archives/8923)
Unison言語をさわるだけ



https://www.unison-lang.org/learn/the-big-idea/

# 環境構築

Windows 10 + WSL

```console
mkdir unisonlanguage
curl -L https://github.com/unisonweb/unison/releases/download/release%2FM4/ucm-linux.tar.gz --output unisonlanguage/ucm.tar.gz
tar -xzf unisonlanguage/ucm.tar.gz -C unisonlanguage
```

手順: https://www.unison-lang.org/learn/quickstart/

`.unisonlanguage/` を PATH に登録してください

# 触る

## ワーキングディレクトリの作成

```console
mkdir unisontest
cd unisontest
```


## インタフェースの起動

まずは `ucm`コマンドで、インターフェースを起動してください
こんな感じのインタフェースが起動します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302078/b11ad450-a649-db09-5b7f-1e7dfb34c4b9.png)


## スクリプトの記載

ワーキングディレクトリでVSCODEを起動

```console
code .
```

ワーキングディレクトリにテストコード`test.u`を置く


```test.u
myTerm = List.map (x -> x * 10) [1,2,3,4,5,6]
> myTerm
```

自動でスクリプトが読み込まれて評価され結果が表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302078/f15094e4-0737-d595-3474-39dad8857adb.png)


1. `myTerm = List.map (x -> x * 10) [1,2,3,4,5,6]` で `myTerm` を定義
1. `> myTerm`で `myTerm`の値を表示(ウオッチ？デバッグ表示？します)
Rustで変数を出力する ( error: format argument must be a string literal )


# コード

様々な記法があるが、以下の書き方が分かりやすそう。

```rs
fn main() {
    let word = "Hello world";
    println!("{word}");
}
```


# エラー

変数を直接printに渡しても実行できない。

```rs
fn main() {
    let word = "Hello world";
    println!(word);
}
```

```
error: format argument must be a string literal
 --> src/main.rs:3:14
  |
3 |     println!(word);
  |              ^^^^
  |
help: you might be missing a string literal to format with
  |
3 |     println!("{}", word);
  |              +++++
```

# 参考

https://www.programiz.com/rust/print-output


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Ubuntuをアップグレードしたら使用頻度高いアプリがアプリ一覧からいなくなった話

Ubuntuをアップグレードしたら、アプリ一覧に使用頻度が高いアプリがなくなったという経験がないでしょうか？
私はUbuntu20.04LTSからUbuntu22.04へアップグレードしたら、VirtualBoxがなくなっていた:astonished:！
ランチャーからもいなくなっていた！
___これだとアプリ実行できないやんけ！___

### これは事件です！

### 解決に向けて、色々調べていたら案外簡単な方法があった！
当記事は、そのメモになります。

解決策はズバリ
### 　『ディスクトップに起動したアプリの.desktopファイルを配置する』
です。
すごい簡単と思ったあなた！、そう、簡単なのです！

私の場合、「~/.local/share/applications/」にVirtualBoxの.desktopファイルがあったので、
これをディスクトップへコピーして実行権限を付けたらGUIでVirtualBoxを実行できた！

```bash:desktopファイルへの配置
$ cp ~/.local/share/applications/virtualbox.desktop ~/ディスクトップ
$ chomod +x ~/ディスクトップ/virtualbox.desktop
```
:beginner:実行権限を付けるところは、GUIからも可能！
1. ディスクトップに配置された.desktopファイルを右クリック
1. 起動を許可
以上で、.desktopファイルがiconの絵がついてWindowsのショートカット的な感じなる:grin:

:warning:以前、アプリ一覧には復旧しません。
:warning:「~/.local/share/applications/」に.desktopファイルがあるとアプリ一覧に出るという記事は多数見つかったが、出ない！

アプリ一覧への出し方がわかる方はぜひコメントにて、一報ください:bow:
Rust – Caused by:   this virtual manifest specifies a [dependencies] section, which is not allowed

`cargo run` コマンドでエラーが起きていた。
Rustチュートリアルの導入をすっ飛ばして `Cargo.toml` の中身を dependencies だけにしていたせいだった。

```toml:Cargo.toml
[dependencies]
ferris-says = "0.2"
```

以下に修正して実行に成功した。

```toml:Cargo.toml
[package]
name = "hello-rust"
version = "0.1.0"
edition = "2021"

[dependencies]
ferris-says = "0.2"
```

# チュートリアル

https://www.rust-lang.org/ja/learn/get-started


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
GCIHをトレーニングもテキストもなしに合格した。

# GCIHとは
GIAC試験の中でも特にインシデントハンドリングに注力した資格とされています。詳細については以下のリンクを参照してください。
なお、インシデントハンドリングに特化した問題は少なく、攻撃手法や検知手法に重点が置かれています。試験内容はインシデント対応の役には立ちますが、これからインシデント対応を始める方にとって必要十分な内容とは言えないかもしれません。もしかするとトレーニングの中では十分に説明されているのかもしれません。

https://www.giac.org/certifications/certified-incident-handler-gcih/


# GIAC試験の基本的な攻略法
GIACの試験は、通常はトレーニングを受け、テキストでしっかりと勉強して、インデックスを作り、模擬試験を2回受けて万全の準備をする必要があります。
周りを見ても、トレーニングなしで受験する人は聞いたことがありません。まあそれをやってしまったのですがｗ
基本的な攻略法は以下に記載しています。

https://qiita.com/log0417/items/78f1e3136f508d54784d

# トレーニングなしで受験した理由
トレーニングなしで受験した理由はトレーニングなしでも合格できそうに思えたからです。
試験範囲を見ると、Metasploitやパスワード、SMB、Webアプリへの攻撃、メモリダンプの解析など、これまで私が取得してきたGPEN、GWAPT、GCFA、GREMの範囲内のものが多いように思いました。
また、いずれも実務で経験しているものなので、これならいけるんじゃないかなと思い、受験を検討しました。

# 戦略
資格試験では準備が重要です。このことは以下の記事にも書いています。

https://qiita.com/log0417/items/f76eaf0fe947ba10a898

しかし、トレーニングもテキストもないので、勉強する方法が事実上ありません。
とりあえず、トレーニングのアジェンダが参考になるだろうと考えました。幸い直近に日本で開催されるトレーニングがありましたので、以下のサイトでアジェンダを確認しました。ここに書いてあるツールは出題されるであろうと踏んで調べておきました。
https://www.sans-japan.jp/courses/sans_tokyo_winter_2022/sec504

ただ、この程度の下調べでは多少知識と経験があるとはいえ、本来5日間あるトレーニングの内容には及ばないことは明白です。このまま申し込んでも、全く歯が立たずに惨敗する結果になるかもしれません。試験に申し込むと949ドルかかります。運悪く円安であり、13万円ほどかかってしまいます。合格すれば会社負担になるものの、さすがにリスクが高いです。
そこで、最初に模擬試験を1回受けてみることにしました。模擬試験は199ドルで、円安でもギリギリ自腹を切れる範囲です。これで全然ダメだったら受験を諦め、合格ラインであれば受験するという戦略を立てました。

模擬試験1回目では、過去に作成したGPEN、GWAPTのインデックスを参照しながら解答しました。結果としてほぼインデックスは不要で、75%で合格でした。これならいけると判断し、即日申し込みを終えました。また、模擬試験中に出てきた知らない単語はメモしておき、後から調べました。

試験を申し込むと無料で2回の模擬試験が付与されます。これも有効活用しました。2回目の模擬試験では82%、3回目では93%でした。3回目となると、ほとんどの問題が以前出題されたものと同じでしたので、3回目はあまり意味はなかったのかもしれません。

# 試験当日
いつものとおり、しっかりと睡眠、朝食をとり、PCの前に座ったら10秒瞑想した後で開始しました。

普段は新宿のテストセンターですが、今回は渋谷のテストセンターで受験しました。渋谷のテストセンターは、新宿と比べると狭く、若干騒音が気になりますが、受験する上で特に支障は感じませんでした。
過去のGIAC試験と異なるのは、持ち込み資料のチェック時に数枚の紙と英和辞書だけを持ち込んだので、受付の方に驚かれたくらいです。

内容については言及できませんが、攻撃手法、防御手法ともに出題されるため、範囲は非常に広いです。ただし、広い分深堀りした出題はなかったように思いました。
本番は模擬試験以上に難しく、加えてテキストがないことから自信がない問題がいつも以上に多かったです。2択までは絞れたが、2択から選ぶのが難しいという問題（ただし、これは良問であるともいえます）が体感で20問くらいありました。また、模試ではあまり得点できなかったクラウドの問題はいったんスキップしつつも、最後までヒントが得られなかった場合は潔く捨てました。
合計すると、95問の選択式問題のうち、20問程度は自信なし、10問程度はわからなかったので捨て問となりました。CyberLiveについては、模試で対策ができており、全問正解の自信がありました。
最後の解答ボタンを押す際には、正直落ちたかもしれないと思いましたが、結果的には84%で合格でした（合格ラインは70%)

私のようにペネトレーションテスト、フォレンジック両方やっている人であれば、トレーニングなしでも合格できるかもしれません。
また、今回はトレーニングなしで受験しましたが、ぜひトレーニングを受けたいとも思いました。模擬試験と本番の試験で出てきたキーワードの中には意外と知らないツールや概念があり、実務に役に立つ情報がたくさん得られそうです。

# 所感
こんな記事を書いておいてなんですが、正直トレーニングなしで受験すべきではないと思います。試験に合格するだけなら十分な実務経験があれば可能と思います。ただ、おそらく試験で出題されていないツールや概念がたくさんあると思いますので、きちんとそれらを理解した方が良いですし、私もそうしたいと思いました。

# 次の目標
これでGIACはGCFA, GREM, GNFA, GPEN, GWAPT, GCIHの6つになりました。あと4つで二桁になります。
ただ、そろそろLPIC3を更新しないといけないので、次は一旦LPIC303でも受けようかなぁと思います。

# その後テキストを入手しての感想
その後、GSP取得によりSEC504のテキストを入手できました。
ざっと一読しましたが、SEC504のコースは大変よくできています。これは経験豊富な人でも一読すべき内容と思いますので、トレーニングを受けられる方は受け、受けられない方はGCIH取得後に更新してテキストを入手しましょう。

また、book5の最後にはGIAC試験に合格するためのTipsも記載されています。
テキストの内容であるためここには書けませんが、GCIHやその他のGIAC試験で非常に有効かと思います。
FOR572にも類似の記載があり、公開されているブログの紹介がありましたので、ここではそちらの紹介をします。

https://www.linkedin.com/pulse/kick-up-your-giac-test-prep-notch-don-murdoch-gse-msise-mba/

https://aboutdfir.com/preparing-for-a-giac-test-this-is-not-the-cissp/
SVGファイルからdrawioのライブラリを作成するスクリプトを作ってみた

[この記事](https://qiita.com/capybara-alt/items/033596584f26cd96d94c)の実践編
## 背景
モックアップをdraw.ioを何度か使うことがあった。フロントエンドをAngular+PrimeNGで実装するため、draw.ioでPrimeNGのアインコンを使いたかった。しかし、draw.ioにPrimeNGのアイコンが使えなかった（ライブラリがなかった）ため、手作業でライブラリを作る必要があった。  
今後、このような作業を手作業でしたくないので、本ツールを作成した。
## 本ツールでできること
以下３点の処理をすることで、draw.ioでSVGアイコンのライブラリを自動で作成する。また、ライブラリ内のSVGの色などもdraw.ioで変更できるようになる。
+ SVGファイルを読み込み、draw.ioのライブラリとして出力する
+ SVGにstyleタグがない場合、自動でタグを挿入する
+ draw.ioのstyle情報に"editableCssRules=.*"を追加する
## 動作
CLIツールなので、ターミナルで実行する
1. diolibgenをgithubからクローンする
```
git clone https://github.com/capybara-alt/diolibgen
```
2. 外部ライブラリをインストール
```
go mod tidy
```
3. diolibgen/inputディレクトリに、対象のSVGファイルを配置
4. diolibgenを実行
```
go run main.go
# or
go build main.go && ./main
```
## 実行結果(例)
### ターミナル
![スクリーンショット 2022-09-23 12.45.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/b475d80c-676f-c336-edc7-ab60932a25fb.png)
![スクリーンショット 2022-09-23 12.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/af7d9558-d42d-94fa-9906-74e9396c8f53.png)
### draw.ioでインポート
![スクリーンショット 2022-09-23 12.46.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/64a0d6b9-d352-d334-6cf3-34a3579c7d2e.png)
【セキュリティ】シャドーITを阻止せよ。

# ShadowIT #

みなさんシャドーITと聞いてどんなイメージを持ちますか？
影のIT？ 黒いIT？ **あ、ダークウェブ的な！！**
と、まあ、私の最初の反応はこんな感じでした。

まったくの検討違いでした。。。
本稿では、シャドーITと呼ばれるものは一体何なのかについて記載していきます。

## ShadowITとは ##
>シャドーITとは、企業が使用許可をしていない、あるいは従業員が利用していることを企業側が把握できていないデバイスや外部サービスのことを指します。つまり、管理対象外のデバイスやサービスのことです。

[NTT東日本_ストレージ導入お役立ちコラムより](https://business.ntt-east.co.jp/content/coworkstorage/column-13.html)

そうなんです。
シャドーITというのは、
**「社員が利用しているにも関わらず、企業側が把握できていないサービスやデバイスのこと」**
を指す言葉なんですね。

決して影だのダークウェブだのとは、関係のない言葉でした笑
みなさんも間違わないようにお気をつけて。。。💦

## ShadowITがあると何が悪い？ ##

シャドーITが何なのかはなんとなくわかったと。
じゃあ、何で悪いのか。確かに会社が良しとしていないサービスを利用するのは、よくなさそうだけど、具体的にどういうことで問題が起きるの？

**そう考えることでしょうね。みなさんは・・・**

では、解説していきましょう。(自分も今回調べたんですけどね、、、)

## ShadowITってそんなに悪いものなの？ ##

シャドーITでないものについて考えてみましょう。
基本的に多くの会社では、このソフトウェアが安全か、使用する上での注意事項は？対策は？適切な設定は？といった具合に様々な対策を実施することで、マルウェアの感染、情報漏洩などのセキュリティ事故を未然に不正でいる。

しかし、逆にそんな対策実施せず、社員のみなさんが思い思いに新しいサービス、ソフトウェアを使用してみたとします。
<h4>あっという間です。</h4>
あっという間にセキュリティ事故を発生させ、顧客情報の漏洩等、取り返しのつかない状態に追い込まれてしまうことは容易に想像できることでしょう。
<br><br>
想像できるはずなのに、実際やってしまっている方、読んでいる方にもいるんじゃありませんか？
そんなシャドーITの対策として用いられているのがCASBです。

## 今後

ShadowITを防止するセキュリティツールである**CASB**について調べてみようと思います。
ありがとうございました。
【Spigot】マインクラフトのプラグイン開発環境作成

# はじめに
マインクラフトのSpigotプラグインについての記事です。
私の環境はUbuntuですが、macOSやWindowsなどでも同じようにすればできると思います。
# プロジェクト作成
はじめに以下のリンクからIntelliJ IDEA Communityをインストールします。
https://www.jetbrains.com/idea/promo/ 
ちなみに、Ubuntuの場合「Ubuntu Software」からもインストールできます。（こっちのほうがオススメ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/255dba5d-29e6-8165-179f-d3d398561146.png)



まず、IDEAにマインクラフトのプラグイン開発用の拡張機能をインストールします。
そしてインストールが完了したら、IntelliJ IDEAを起動してPluginsをクリック
![Screenshot from 2022-09-23 11-40-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/a2bc93a0-54dc-9174-94ca-f10cc55c4e08.png)

次にMarketplaceでMinecraftと検索して、Minecraft Developmentをインストール。
インストール後に再起動を促されるのでエディタを再起動。
![Screenshot from 2022-09-23 11-40-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/b7b73b86-f575-55b8-58e7-facfe0f964c2.png)

New Projectをクリックして、新規プロジェクトを作成します
![Screenshot from 2022-09-23 11-40-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/b981a71a-bce1-25f6-12e1-1c4bcec80237.png)

この画面になるので、左のタブからMinecraftを選択。
![Screenshot from 2022-09-23 11-40-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/8833593d-423c-80ca-6260-0b052c32f055.png)

プロジェクトのセットアップ画面が出るので、Spigot Pluginを選択。
![Screenshot from 2022-09-23 11-41-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/48092671-7370-00b9-0fb1-73776bc27cd5.png)

GroupIDにはドメインを逆にしたもの。(com.exampleなど)
ArtifactIDにはプロジェクト名を入れるのがいいでしょう。
![Screenshot from 2022-09-23 11-42-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/b02eb26b-9488-6df9-8d3a-ea58d0e66049.png)

ターゲットとなるマインクラフトのバージョンを選択して、Nextをクリック。（その他DescriptionやAutheorsなどの設定は必要に応じて行ってください。）
![Screenshot from 2022-09-23 11-42-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/00979f39-821c-7176-65d6-e4c5b88499f5.png)

プロジェクトのディレクトリを設定します。
![Screenshot from 2022-09-23 11-43-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/36098438-3eec-bb65-1c45-03e67fa5cc29.png)


下の画面のようになればひとまず開発環境は構築完了です！おつかれさまでした
![Screenshot from 2022-09-23 11-43-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446859/661e846c-fc79-2961-f6b7-7f2626aabd9a.png)
【CocoaPods】Xcode14にしたらpodコマンドが使えなくなった

# エラー
![スクリーンショット 2022-09-23 11.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/5891918c-89c4-4ad4-f352-52dd05bb7bdd.png)

# 原因
Xcode14で作成したプロジェクトだとpodコマンドが使えない
`[Xcodeproj] Unknown object version (56). (RuntimeError)`

# 解決策
この方法が簡単で良さそうです。

https://qiita.com/MaskerDog/items/37b21946edc6acedc518

# 注意
Rubyのバージョンを上げると他のエラーが発生して沼ります笑
2.6.8にしちゃってpodが完全に使えなくなったので2.6.0に戻しました

**rbenvをインストール**

https://qiita.com/hujuu/items/3d600f2b2384c145ad12

**rbenvでrubyを2.6.0にする**

https://qiita.com/takeda-no-nao/items/f892d05b4bb8e2d03a4b

**CocoaPodsをインストール & セットアップ**

https://qiita.com/ShinokiRyosei/items/3090290cb72434852460

自分はこれで治りました。
もっといい方法があると思うのでおすすめしません。
マジで使えなくなって焦りました。
Xcode14でも使えるようになったのでCocoaPodsのバージョンの問題？
バージョンアップすればよかっただけ説？
HerokuCLIインストール時のエラーを解決

# Heroku CLIをインストール
- Herokuをコマンドで操作できるようにするツール

https://devcenter.heroku.com/ja/articles/heroku-cli

```terminal
$ brew tap heroku/brew && brew install heroku
```
---
エラーが発生

```terminal:terminal
You have 30 outdated formulae and 1 outdated cask installed.
You can upgrade them with brew upgrade
or list them with brew outdated.
```

下記コマンド実行
```terminal
$ brew upgrade
```
- `brew update`・・・Homebrewだけをアップデートするためのコマンド（Homebrewにインストールされているパッケージは更新されない）
- `brew upgrade`・・・Homebrewのアップデート＆Homebrewにインストールされているパッケージに更新が必要なものがあれば、同時にパッケージの更新も実行
    - 後者は時間がかかる

---
ただ、まだエラーが出る
```terminal:terminal
==> Installing heroku from heroku/brew
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 13.4.
```

下記実行
```terminal
$ softwareupdate --all --install --force
```
- montereyのupdateが始まり、30分くらい時間を要した
    - おかげで最新になったw
    - `monterey`とは・・・macOS 12 ”Montery”は、WWDC 2021で正式発表されたMac向けのOS
        - https://gori.me/macosx/macosmonterey
```terminal:terminal
(base) sample@SampleMBP ~ % softwareupdate --all --install --force
Software Update Tool

Finding available software
Downloading macOS Monterey 12.5.1
```
---
これでも上手くいかなかったため下記実行
```terminal
$ sudo rm -rf /Library/Developer/CommandLineTools
$ sudo xcode-select --install
```
- 最初は<INS>残り147時間</INS>とかいう絶望的な時間を提示されるが、1時間くらいで終わる
---
HerokuCLIインストール
```terminal
$ brew tap heroku/brew && brew install heroku
```

:::note
完了
:::