OmniAICreator/Qiita-1.07M huggingface dataset:
AWSのデータベースサービス

出展：[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3ERB303UT76DT&keywords=aws%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC&qid=1578744077&sprefix=AWS%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%2Caps%2C266&sr=8-1)

#RDS

##RDSの概要
・Amazon Relatinal Database Serviceの略
・オンプレミスで使われているデータベースエンジンをそのまま簡単に使うことができる
・使用できるデータベース
　・Amazon Aurora
　・MyAQL
　・PostgreSQL
　・MariaDB
　・Oracle
　・Microsoft SQL Server

##RDSとEC2の違い

###メンテナンス
・RDSではOS、データベースエンジンのメンテナンスをAWSに任せることができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545315/0d01d87c-73f7-5699-29cb-e5a3833cfc9d.png)

###バックアップ
・RDSでは、デフォルトで7日間の自動バックアップが適用されている
・バックアップの期間は0～35日まで設定でき、指定した時間にバックアップデータが作成される
・35日を越えてバックアップデータを保持しておく必要がある場合は、手動のスナップショットを作成できる
・自動バックアップも手動スナップショットもRDSのスナップショットインターフェイスからアクセスできるが、実体はS3の機能を利用して保存される
・***ポイントタイムリカバリー***：
　・自動バックアップを設定している期間内であれば、秒数まで指定して特定の時点のインスタンスを復元できる
　・過去直近では5分前に戻すことができる
　・トランザクションログが保存されていることで実現される
　・RDSの起動が完了した時点で自動でトランザクションログの保存が開始される

###高可用性
・RDSのマルチAZ配置をオンにすると、アベイラビリティゾーンをまたいだレプリケーションが自動的に行われる
・レプリケーション、フェイルオーバーはRDSの機能によって自動的に行われる

##Amazon Auroraの概要
・MySQL/PostgreSQL互換の、クラウドに最適化されたリレーショナルデータベース
・バックアップが非常に強固
・スタンバイにアクセスできる（リードレプリカがマスター昇格する）
・リードレプリカは15個作成できる
・RDSMySQLに比べて5倍の性能
・ディスク容量を見込みで確保しなくても自動で増加する

##DMS
・Amazon Database Migration Serviceの略
・オンプレミスからAWS、AWSからAWSへデータベースの移行をする場合に使用する
・DMSによりオンプレミスからAWSへの継続的なデータ移行を行い、システムのダウンタイムを最小限にできる

#DynamoDB

##DynamoDBの概要
・NoSQL型の高いパフォーマンスを持ったフルマネージド型のデータベースサービス
・リージョンを選択して使うことができる
・アベイラリティゾーンは意識しなくてもよい
・DynamoDBにテーブルを作って、そこにアイテムと呼ばれるデータを保存すると、自動的に複数のアベイラビリティゾーンの複数の施設で同期され保存される
・データ容量は無制限
・使用している容量のみが課金対象
・性能はユーザが決定する

##DynamoDBとRDSの違い
###RDS
・垂直スケーリングによりスケールアップする
・基本的には1つのインスタンスで処理を行う
・厳密な処理をすることができるが、大量のアクセスには向かない
・***SQL型***のテーブル形式
・中規模程度のアクセス量で、整合性や複雑なクエリを必要とする場合に使用

###DynamoDB
・水平スケーリングが可能
・大量のアクセスがあってもパフォーマンスを保ったまま処理ができる
・トランザクションを必要とする処理や、複雑なクエリには向かない
・***NoSQL型***のデータ形式
・1つのデータは***アイテム***として扱う
・大規模なアクセス量で、単純な自由度の高いデータモデルを扱う場合はDynamoDBを使用

#その他のデータベースサービス
・Amazon Redshift：
　・高速でシンプルなデータウェアハウスサービス
　・データ分析に使用
・Amazon ElastCashe：
　・インメモリデータストアサービス
　・オープンソースのRedis、Memcashedのマネージドサービスとして使用
　・RDSやDynamoDBのクエリ結果のキャッシュに使用したり、アプリケーションのセッション情報を管理する用途で使われる
・Amazon Nopute
　・フルマネージドなグラフデータベースサービス
　・関係性や相関情報を扱う
　・SNS、レコメンデーション（提案）エンジン、経路案内、物流最適化などのアプリケーション機能に使用される
マイクで拾った音をPyaudio経由で録音する

## PyAudio
- クロスプラットフォームのオーディオI/Oライブラリ
- MITライセンスで配布されています


### インストール(Mac)
- pip 経由でインストールします
- 動作には[PortAudio](http://www.portaudio.com)が必要です

```
brew install portaudio 
pip install pyaudio
```

## 録音デバイス
- Macのビルドインマイクを使って動作確認
- デバイス情報はpyaudioのメソッドで確認ができます

```python
In [21]: p = pyaudio.PyAudio()                                                  

In [22]: p.get_default_input_device_info()                                      
Out[22]: 
{'index': 0,
 'structVersion': 2,
 'name': 'Built-in Microphone',
 'hostApi': 0,
 'maxInputChannels': 2,
 'maxOutputChannels': 0,
 'defaultLowInputLatency': 0.0029478458049886623,
 'defaultLowOutputLatency': 0.01,
 'defaultHighInputLatency': 0.02471655328798186,
 'defaultHighOutputLatency': 0.1,
 'defaultSampleRate': 44100.0}
```

## 録音のための関数
- PyAudioを使って取得した録音内容をリストに格納
- 最後にwavファイルに書き出すようにしました

- サンプリング周波数 12000Hz, 32bit浮動小数点で録音します

```python
import pyaudio
import numpy as np
import scipy.io.wavfile 

RATE = 12000
def record_audio(output_name):
    CHUNK = 1024
    FORMAT = pyaudio.paFloat32
    CHANNELS = 1

    pa = pyaudio.PyAudio()
    stream = pa.open(rate=RATE,
        channels=CHANNELS,
        format=FORMAT,
        input=True,
        frames_per_buffer=CHUNK)
    
    print("RECORD START")
    print("ctrl-C : STOP RECORDING")

    # RECORDING ###############
    # Stop with Ctrl-C
    frame = []
    while True:
        try:
            # Record
            d = stream.read(CHUNK)
            d = np.frombuffer(d, dtype=np.float32)   # convert numpy   
            frame.append(d)
            
        except KeyboardInterrupt:
            # Ctrl - c  
            break
    # END # RECORDING ###############
    
    # CLOSE
    stream.stop_stream()
    stream.close()
    pa.terminate()

    # Numpy Array
    frame = np.array(frame).flatten()
    print("STOP {} samples  {:.2f}s".format(frame.size, frame.size/RATE))
    # Write Wavfile with scipy module
    scipy.io.wavfile.write(output_name, RATE, frame)
    print("OUTPUT: {}".format(basename(output_name))
```

## 録音結果
- ファイル名をつけて呼び出します

```python
record_audio('test.wav')    # 呼び出し
```

- コンソールの表示内容
    - Ctrl-c で途中でSTOPしました

```python
RECORD START
ctrl-C : STOP RECORDING
^C
STOP 111616 samples  9.30s
OUTPUT: test.wav
```

- 'あ〜'と喋っている波形が録音できました

<img width="569" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335883/26d56503-4870-a15a-37a1-c128aa30a8a1.png">

## 参考
[PyAudio](https://people.csail.mit.edu/hubert/pyaudio/)
#Rails migration / Remove unique index /  Mysql2::Error: Cannot drop index 'index_xxx_on_yyy_id': needed in a foreign key constraint

I dont know its best way or wrong way
but it seems to work 

# model Annotation = DB table schema info

Wanna delete UNIQUE index

```diff
# == Schema Information
#
# Table name: books
# user_id                          :bigint           not null
#
# Indexes
#
- # index_books_on_user_id (user_id)
+ # index_books_on_user_id (user_id) UNIQUE
#
#
# Foreign Keys
#  fk_rails_...  (user_id => sims.id)
#
```

# Model

```rb
class Book < ApplicationRecord
  belongs_to :user
end
```

# Fail Migration 

```rb
class RemoveUniqueIndexUserIdFromBoook < ActiveRecord::Migration[5.2]
  def change
    # Mysql2::Error: Cannot drop index 'index_books_on_user_id': needed in a foreign key constraint
    remove_index :books, :user_id
  end
end
```

# Succeed Migration

```rb
class RemoveUniqueIndexUserIdFromBoook < ActiveRecord::Migration[5.2]
  def change
    # Anti migration error
    # Mysql2::Error: Cannot drop index 'index_books_on_user_id': needed in a foreign key constraint
    remove_foreign_key :books, name: "fk_rails_80340687ab"
    remove_index :books, :user_id
    add_index :books, :user_id
    add_foreign_key :books, :users
  end
end

```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2950








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
(初心者)MySQLのUDFを簡単に作ってみた

# 参考

- [C++でMySQLのUDFを作る - qiita](https://qiita.com/onunu/items/71064bbf48dc40c6ce11)
- [MySQL :: MySQL 8.0 Reference Manual :: 29.4.2 Adding a User-Defined Function](https://dev.mysql.com/doc/refman/8.0/en/adding-udf.html#udf-calling)

# 作成した関数

```cpp
#include <mysql.h>
#include <string>

extern "C" {
    my_bool factorial_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

    char *factorial(UDF_INIT *initid, UDF_ARGS *args, char *result,
        unsigned long *length, char *is_null, char *error);
}

my_bool factorial_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 1)
    {
        strcpy(message,"FACTORIAL() requires one arguments");
        return 1;
    }
    if (args->arg_type[0] != INT_RESULT)
    {
        strcpy(message,"FACTORIAL() require an integer");
        return 1;
    }
    return 0;
}

char *factorial(UDF_INIT *initid, UDF_ARGS *args, char *result,
    unsigned long *length, char *is_null, char *error) {

    long long val = *(long long*) args->args[0];
    int sum = 1;
    for (int i = 1; i <= val; ++i)
    {
        sum *= i;
    }

    strcpy(result, std::to_string(sum).c_str());
    *length = strlen(result);

    return result;
}
```

`factorial_init`と`factorial`を作成しています。
`factorial_init`が関数実行時に最初に実行されて、引数のチェックなどを行い、
`factorial`が実際に処理をする部分です。

# コンパイル

```console
$ mysql_config --cflags #mysql.hがあるパスを確認
-I/usr/local/opt/mysql@5.7/include/mysql 
$ mysql_config --plugindir #プラグインのパスを確認
/usr/local/opt/mysql@5.7/lib/plugin

$ g++ factorial.cpp -shared \
 -o /usr/local/opt/mysql@5.7/lib/plugin/factorial.so \
 -I /usr/local/opt/mysql@5.7/include/mysql/ #コンパイル
```

```console
mysql> create function factorial returns string soname 'factorial.so';
Query OK, 0 rows affected (0.01 sec)

mysql> select factorial(6);
+--------------+
| factorial(6) |
+--------------+
| 720          |
+--------------+
1 row in set (0.00 sec)
```

UDFを動かせました。見ていただいてありがとうございました。m(_ _)m
比較演算子

## 基礎
|比較演算子  |例 |式が成立する条件 |
|---|---     |---|
|== |a = b   |aとbが等しい|
|!=|a != b  |aとbが等しくない|
|=== |a === b|aとbが厳密に等しい|
|!==|a !== b |aとbが厳密に等しくない|
|>  |a > b   |aがbより大きい|
|>= |a >= b  |aがb以上|
|<  |a < b   |aがbより小さい|
|<= |a <= b  |aがb以下|
|&& |a && b  |aかつb(aとb両方が真なら真を返す) |
|&#124;&#124;|a &#124;&#124; b |aまたはb(aかbどちらかが真なら真を返す)|

**厳密に**とは演算の処理対象となる値が等しく、かつ同じ型である場合のことです。


## !での評価方法について
判定式の**「！」**を使う時、後から読む場合わかりにくいことがあります...
変数の名前を肯定系で書き、否定したい場合に**「！」**を使うと読みやすいコードになると思います。


!を変数の前につけるとbooleanが返却されるます。
<img width="330" alt="スクリーンショット 2020-01-19 6.09.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/a9c72597-a1ef-5e4f-dc09-209e4e8348e6.png">


```js
const isOpen = true
!isOpen // オープンではないと意味がわかりやすい

// 下のように書くと、何がいいたいのか理解するのに時間がかかる
const isNotOpen = false
!isNotOpen　//
```

<img width="586" alt="スクリーンショット 2020-01-19 6.58.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/a8efe444-9814-b96f-d6d0-e18b8d16456f.png">


変数に必ずbooleanの値を入れたいときはあえて!!を入れることもあります.
<img width="341" alt="スクリーンショット 2020-01-19 7.01.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/e90b1bae-540f-d8cc-b4ac-80a433670cfa.png">


可読性の高いコードを意識して書くよう注意したいです

## ===での比較について
JavaScriptのデータ型（Type）は、プリミティブ型とオブジェクト型に大別されます。
**プリミティブ型**とは数値・文字列・論理値・null・undefinedのことです。(論理値は「true（真）」「false（偽）」のどちらかの値です。)
**オブジェクト型**とはプロパティ（値）とメソッド（操作）の集まりです。

↓プリミティブ型の場合は、比較対象の値と型を見て比較します。
<img width="432" alt="スクリーンショット 2020-01-26 12.03.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/5fe8d2d9-2506-7851-a9db-64993d20943b.png">


オブジェクト同士の比較の場合は、参照を比較します。

<img width="540" alt="スクリーンショット 2020-01-26 12.04.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/ca884015-8bd6-7de0-38d3-485eac329406.png">





参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Operators/Comparison_Operators
https://qiita.com/makotoo2/items/9566cebf205ef8b42505
初心者によるプログラミング学習ログ 214日目

#100日チャレンジの214日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

214日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>214日目<br><br>vue.jsでつくるポートフォリオ作成<br>とりあえず、前に作った未完成ポートフォリオの一部のコードをvueに移してみた。<br>cssは、sassで書いてみた<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/vuejs?src=hash&amp;ref_src=twsrc%5Etfw">#vuejs</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1218634622658957312?ref_src=twsrc%5Etfw">January 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Windowsの環境を可能な限り黒にする設定まとめ

#Windowsのテーマ、背景、エクスプローラーを黒にする
Windowsの設定を開く（Windowsキー + i）⇒個人設定⇒色⇒色を選択する 黒を選ぶ
⇒アクセントカラーを選ぶ⇒灰色を選ぶ
以上の設定で、こんな感じになります。![2020-01-19_05h56_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462058/91396923-177e-93e2-0c36-8bff62802261.png)
![2020-01-19_05h58_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462058/d281a22a-c612-f1db-4ab3-8b0b264bdf6b.png)

#Officeのテーマ設定
Word、Excel、PowerPointのいずれかを開く⇒アカウントテーマを黒にする
![2020-01-19_06h20_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462058/092c9798-3f3c-c012-2a75-e4c138bbe65d.png)
※Outlookはプレビュー表示されるメール本文は白のままになる。メール本文も黒にするにはWeb版Outlookでダークモードを選択する。

#Chomeのテーマを黒にする
https://chrome.google.com/webstore/detail/just-black/aghfnjkcakhmadgdomlmlhhaocbkloab
上記URLをChomeで開き、ダウンロードする
テーマのみでは、検索結果が出るページは白のままになる。ここも黒にしたい場合は
https://chrome.google.com/webstore/detail/high-contrast/djcfdncoelnlbldjfhinnjlhdjlikmph
上記URLをChomeで開き、ダウンロード後ハイコントラストを有効にする。
※コントラストをいじる拡張機能のため、画像のコントラストも変化する。
※画像を見る場合はShift + F11でハイコントラストを無効にするといい。

#最後に
目は消耗品なので日常でPCを使う方はできるだけ負担の少ない色に変更することをおすすめします。
レジストリをいじってユーザープロファイルを破壊してしまった話

#ことの発端
ユーザープロファイル名を変更しようとしたところ、レジストリにあるProfileImagePathを変更すれば変わるという記事を見て興味本位で触ってみた

#行ったこと
・万が一の事態があったときのために、システムの復元を作成
コンパネ⇒すべてのコントロールパネル⇒システム⇒システムの保護
![2020-01-19_05h33_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462058/1985d87f-fc11-5106-c5c2-b46ecae82d14.png)
利用できるドライブでCドライブ（システム）を選択し、構成からシステムの保護を有効にするを選択する。
作成から、任意の名前を作り、完了

・レジストリからProfileImagePathを変更する
![2020-01-19_05h11_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462058/0b5dc31f-ca5a-0588-6b23-3ecd203f4d0b.png)
変更後、再起動

#再起動後
サインインすると、「アカウントにサインインできません この問題は、アカウントからサインアウトし、もう一度サインインすると解決できることがよくあります」
というポップアップが出てくる。
指示通りサインアウトしてみるが解決できず。。
結局レジストリで変更したところを元に戻すことで元に戻りました。
Visual Studio 2019でxUnitを使おうとしてハマったことメモ

# 2025年5月追記

今では、NuGetからxunitを追加して、プロジェクトの新規作成で「xUnit テスト プロジェクト」を追加するだけでいいと思います。

当然、本番コードとテストコードはプロジェクト分離してくださいね？

# 前提

* Visual Studio 2019 のIDE上
* Chaining Assertion の話もあり、というか [xUnit.net でユニットテストを始める](https://qiita.com/takutoy/items/84fa6498f0726418825d) が動くまで

# xUnitプロジェクトの作成で躓く

VS2019の「xUnit テストプロジェクト(.NET Core)」で、プロジェクトを追加したら「コンパイルエラー(CS0246)」のエラーが3つ出ました。

トラブル解決のため焦っており、正確な所は失念しましたが、少なくとも
>型または名前空間の名前 'Fact' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)

という、xUnitを使う上では致命的なエラーが出ていました。

「ソリューションのNuGetパッケージの管理」から見ると、以下のパッケージが最新版ではありませんでした。

* coverlet.collector
* Microsoft.NET.Test.Sdk
* xunit
* xunit.runner.visualstudio

ここでパッケージ最新版への更新を試みると C:\Program Files\dotnet\sdk\NuGetFallbackFolder の中にある System.AppContext.4.1.0 がエラー、などの不穏が発生。
[該当のエラーが出ているフォルダは削除してよさそうな情報](https://tutorialmore.com/questions-799938.htm)が見つかったので、エラーが出るフォルダを1つ1つ削除していったら、今度はフォルダ特定できないようなエラー発生。

結論を言うと、キレ気味に **NuGetFallbackFolder そのものを削除したら、すんなり更新できました。**

# Chaining Assertionの導入で躓く

冒頭に出した記事では「githubから直接コードをコピってテストプロジェクトにぶち込むのが良い」と書いてありましたが、正直美しくないと感じました。あくまで個人の主観ですが。

少なくともgithubのモノとバージョンは同一っぽいので、NuGetから入れても、何も起こらない。

`(1+1).Is(2)` とやっても Is が定義されてない云々、と。

これは、正直参りましたが ChainingAssertion-xUnit **ではなく ChainingAssertion-xUnit.Bin を入れるのが正解**のようです。


# 最後に

これ、いわゆるおま環「おまえの環境の問題」かなーとも思ったんですよね…ただ、もし同じことに引っかかってる人がいたらと思い、ざっくりと記事に起こしました。

2020/01/27追記
どなたか宜しければ、Visual Studio CodeでのxUnitの使い方について教えてください、リンクで構いませんので！


# おまけ

ちゃんと C# のコードを書ける人には一目瞭然でしょうけど、[xUnit.net でユニットテストを始める](https://qiita.com/takutoy/items/84fa6498f0726418825d)のコードは、テストプロジェクトを簡単に動かすため、テスト対象コードをテストプロジェクト内に書いているようです。

実際にテストコードを書くときは、ちゃんとテストプロジェクトとプロダクトプロジェクトを分離しましょうね…大きなお世話だったかな？
UITableViewCellのreload時のアニメーションを防ぐ

# 実装方法
```Sample.swift
UIView.performWithoutAnimation {
    tableView.reloadRows(at: [indexPath], with: .automatic)
}
```

# 注意点
stackoverflow等ではreloadRowsの引数に`.none`を指定している例が多いですが、`none`は「デフォルトのアニメーションを使用する」オプションなので間違えないでください。
`.none`を指定すると、リロード時にCell内のViewやラベルが点滅することがありました。

https://developer.apple.com/documentation/uikit/uitableview/rowanimation
【編集中】ActivePDF-DocConverter利用中にエラー発生

# TODO
- [ ]  発生エラーコード/回避策等が書けていない。予防策も色々書かないとな...

# 発生エラーコード
※後で書く。。。

# 参考サイト
◆Win32エラーコード一覧
　http://ir9.jp/prog/ayu/win32err.htm
　　※まずはどんなエラーなのか

◆SDK Reference
　http://documentation.activepdf.com/DocConverter/DocConverter_API/index.htm#e_nav_org_pages/API_Reference.htm
　※APIを把握することも必要

◆ActivePDF Support | Knowledgebase  DocConverter
　https://support.activepdf.com/hc/en-us/categories/115000251733-DocConverter
　※既知の問題として報告されているかも...

◆GitHub - ActivePDF/DocConverter: High-Volume PDF Document Conversion I.T. Software Solution + API For Developers
　https://github.com/ActivePDF/DocConverter
　　※問合せ等する際にはサンプルが必要

◆クイック スタート ガイド - 概要
　https://www.xlsoft.com/jp/products/activepdf/docconverter/DocConverter2015_Quick_Start/Default.htm
　　※基本的な機能把握に
【Python】Wiresharkで取得した情報を可視化する

# Wiresharkで取得した情報を可視化
## はじめに
localhostで発生するパケットだけならいいんですがポートフォワーディングしてるとWiresharkがごちゃごちゃしてきちゃってわかりづらいので可視化してみました。

今回はlocalhostで発生するパケットのみを扱うのですが、複数のパケットを取得している方のためにPageRank(ノードの重要度を可視化)を使用しています。

## 環境
Python 3.7.5

## 準備

### Pythonのパッケージをインストール

```
pip install dpkt
pip install networkx
pip install matplotlib
```

### Wiresharkでキャプチャしたデータをエクスポートする
Wiresharkでキャプチャーしたファイルを使用するので保存しておいてください。
保存するファイル形式は`Wireshark/tcpdump/...`の`.pcap`を選択して保存してください。

## 完成形
一応IPアドレスは修正してあります。

![Screen Shot 2020-01-19 at 4.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356851/955f4717-0196-c81a-a89d-281b175a31b0.png)


## 使い方

どちらも同一階層にあることを前提としています。

```
python pcap_Visualization.py <ファイル名.pcap>
```

## ソースコード
```pcap_Visualization.py
import binascii
import dpkt
import matplotlib.pyplot as plt
import networkx as nx
import os
import socket
import string
import sys


def main(file_name):
    packet_count = 0
    pcr = dpkt.pcap.Reader(open(file_name,'rb'))

    #パケット処理
    for ts,buf in pcr:
        packet_count += 1
        try:
            eth = dpkt.ethernet.Ethernet(buf)
        except:
            continue

        #IPデータの場合
        if type(eth.data) == dpkt.ip.IP:
            ip = eth.data
            src = socket.inet_ntoa(ip.src)
            dst = socket.inet_ntoa(ip.dst)
            with open('./edgelist.txt', 'a') as f:
                print("{} {}".format(src, dst), file = f)

    G = nx.read_edgelist('edgelist.txt', nodetype=str)  # ファイル読み込み
    plt.figure(figsize=(7, 7))
    pos = nx.spring_layout(G)

    #PageRankの追加
    pr = nx.pagerank(G)
    nx.draw_networkx_edges(G, pos, edge_color='y')

    #node_sizeにPageRankの値を組み込む
    nx.draw_networkx_nodes(
        G,
        pos,
        node_color='r',
        alpha=0.5,
        node_size=[5000*v for v in pr.values()]
    )
    nx.draw_networkx_labels(
        G,
        pos,
        font_size=10
    )

    plt.axis('off')
    plt.show()

    os.remove("edgelist.txt")
    print("処理終了:{}".format(packet_count))

#メイン関数
if __name__ == '__main__':
    if (len(sys.argv) != 2):
        print("ファイルを指定して下さい")
        exit()
    #第2引数をファイル名にする
    file_name = sys.argv[1]

    main(file_name)
```

## おまけ
他の機器で発生するパケットを追加するとこんな感じになりました!
PageRankの差がわかりづらいですね...
気が向いたら修正しようと思います!

![Screen Shot 2020-01-19 at 4.09.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356851/448a1155-1271-a03c-fca0-51b82461b9cc.png)


# まとめ

NetworkX面白いですね!!
ノードとエッジの繋がりを表現するパッケージなんですがこれならネットワーク以外にも応用できそうですね!!
ご指摘お待ちしております!!
Swift：flatMap便利すぎた．

# 背景
`grep`に`arguments`として`-e str1 -e str2`を渡して複数の文字列でOR検索しようとしていて，今は`[str1, str2]`という配列を持っているなんて場面での話

# flatMap便利
```swift
let strs = ["str1", "str2"]

let args = strs.flatMap { (str) -> [String] in
    return ["-e", str]
}
print(args.joined(separator: " "))
// "-e str1 -e str2"が手に入る
```

flatMapは多次元配列の次元を下げる以外にも使えるんですね．
何もしていないのにUbuntuのnvidia-driverがおかしくなる問題

# はじめに
Ubuntu18.04LTSを使っていて、たまにNVIDIAドライバがおかしくなり、画面のサイズが初期状態に戻って２つめのディスプレイが読み込めなくなる。この問題が起こると焦ってしまい、対処法を忘れてしまうので、備忘録として復旧手順を残します。

# あらかじめ
何が起こるかわからないので、サイズのおかしい画面でログインしてバックアップは残しておく。

# とにかく
まずは再起動してみる。

```sh:
$ reboot
```

# 再起動してもダメな場合
大抵の場合、再起動してもよくならないであろう。
その時は、NVIDIAドライバを再インストールすすると良い。
初期セットアップ時にダウンロードしてきた`NVIDIA-....run`をルートで実行する。

```sh:
$ sh NVIDIA*.run
```

# 上手くいかない場合
CLIログインして実行してみる。
`Ctrl+Alt+F1`でログイン画面に遷移し、`Enter`でパスワード入力画面へ遷移した後、`Ctrl+Alt+F3`でCLIログイン画面へ遷移する。ユーザ名とパスワードを入力することでCLIログインができる。

```sh:
$ service lightdm stop
$ service gdm stop
$ sh NVIDIA*.run
````

# それでもエラーが起こる場合
以下のコマンドでをつけてインストールしてみる
```sh:
$ sh ./NVIDIA*.run --dkms
````

# それでも`ERROR...`と出てしまい、進まない場合
[NVIDIAの公式](https://www.nvidia.com/Download/index.aspx)からインストーラ自体を再ダウンロードして実行する。だいたいこれで上手くいく。

````sh:
$ cd ~/Downloads
$ chmod +x NVIDIA*.run
$ ./NVIDIA*.run
```

# おわりに
応急処置はできるようになったが、何度も同じ現象が起こるということは根本的な問題が残されているように感じます。詳しくなったら直せたらと思います。
【CSS】RGBとRGBAとopacity

## RGB
:sunny: 3つの数字を組み合わせて表示する色を決める

[【CSS】基礎](https://qiita.com/mikimikiman/items/0a4e39000c6621527b3e#color) でカラーの指定は

・16進数のカラーコードで色を指定（#ff0000,#008000など）
・主要な色であれば直接色名を指定しても表示される（red,greenなど）

で２種類のカラー指定方法を記入したのですが、今回は RGB というものを追加:smile:

色彩の勉強をしたことがある人はこちらのほうが馴染みがあると思います。
RGBというのは・・・

R ・・・ RED の R
G ・・・ GREEN の G
B ・・・ BLUE の B

つまりは光の三原色と言われるものです:smile:

記入方法は

```例
セレクタ {
　プロパティ: rgb(赤, 緑, 青);
}
```

今までであれば値のところを red としたり #ff0000 と記入すれば表示されたのですが、RGB で記入するときは rgb と記入し (赤, 緑, 青) の色の部分は数字を指定します。

たとえば背景色を赤にしたいのであれば

```例.css
background-color: rgb(255, 0, 0);
```

というふうに記入します:smile:
背景色をオレンジにしたいときに RGB で表すならば

```例.css
    background-color: rgb(243, 152, 29);
```

Web
↓
<img width="114" alt="スクリーンショット 2020-01-19 1.32.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532773/e18a447e-4123-aa22-014d-b349b7c17ff5.png">

表示されました:laughing: 


## RGBA
:sunny: RGB で指定した色を透明にする

さきほど上記で RGB は光の三原色のことだと言いましたが
そこに A が加わることで透明度を指定することができます。
A は ALPHA値 の A で透明度を指定します。

使い方は簡単です:smile:

```例
セレクタ {
　プロパティ: rgba(赤, 緑, 青, 透明度);
}
```

さきほどのRGBの最後に透明度を加えればいいだけです。
透明度の指定方法は

**1.0（不透明）〜0（透明）**

で指定します。
では赤いボックスを半透明の 0.5 にしてみますね:smile:

```例.css
background-color: rgba(255, 0, 0, 0.5);
```

<img width="225" alt="スクリーンショット 2020-01-19 2.03.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532773/ac160ab6-ea34-c475-e157-6c9bb1f80902.png">

左が不透明、右が半透明です。
RGBに透明度をプラスするだけで簡単に透明化できます:laughing: 

## RGBA と opacity のちがい
同じ透明化なら opacity でもいいじゃん:thinking: と思いますが明確な違いがあります。

RGBA ・・・ 指定した色のみ透明化する
opacity ・・・ 要素全体を透明化する

<img width="225" alt="スクリーンショット 2020-01-19 2.16.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532773/c09f68cd-aada-efc6-4e98-01fa944319c7.png">

左が RGBA で透明化、右が opacity で透明化したものです。
RGBA は指定した赤色のみ透明化されていますが
opacity は赤色だけでなく文字も透明化されているのがわかるかと思います。

なのでこの部分だけを透明化したいというときは RGBA
全体的に透明化したいというときは opacity
と使い分ければいいかと思います:laughing:
[番外編]画像アップロード機能と、リサイズ機能

#画像アップロード機能実装方法
画像のアップロードはCarrierWaveで、リサイズはImageMagicとrmagicを使う。
##CarrierWave
（gem CarrierWaveインストール後）
**１画像を格納したいテーブルに、String型のデータを追加。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/09c45b19-b327-c8f4-6f25-24e09e28436f.png)
**２「rails g uploader アップローダー名」で、アップローダー（画像アップロード用の機能）クラスを生成する**
これで様々な設定を記述するimage_uploader.rbファイルも作成される。

**３　２で作成したアップローダを画像が保存されるテーブルに関連づける。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/24cb489d-e917-bd30-952a-f72e32b08030.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/875aec74-9b1b-a860-7486-1d4abde5ef85.png)

コントローラ等で送られた画像を保存し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/35205530-5ceb-6406-4adc-b67dd583f9c4.png)

ビューでその画像が保存されるモデルからインスタンス生成して、そこから１で追加したコラム名を呼び出すと、画像が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/d85557b3-c479-2001-fbc6-d4afc1941d93.png)
**参考になったサイト**
https://nyoken.com/rails-carrierwave

#Imagemagic rmagic
リサイズをするためにはgem rmagicを使うが、rmagicを使うためにはそのインターフェイス的な役割であるImagemagicをインストールししなくてはならない。
**１Imagemagicのインストール**
>>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/a4796c6d-369f-88b6-9141-c53cabe62f46.png)

**「パスを通すとは」**
プログラム名だけで実行できるようにすることらしい。ターミナルとかでpwdが使えるのは、そのパスが通されているから実行することができる。
**export PATH**
exportはOSが全プログラムで使える変数としてもつ環境変数（PATH)を設定することができるコマンド。ここではパスを変数PATHに格納している。
**source ~/.bash_profile**
sourceコマンドは変更した環境ファイルの設定を更新するコマンド。
~/はホームディレクトリ、.は隠しファイルを意味している。 
変更した設定を、bash_profileファイルに上書きしている。（PATHが追加された。）
**convert --version**
imagemagicのコマンドでインストールされていれば使えるのでそれでバージョンを確認している。
>>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/7ee8cbf8-d53a-701d-1e26-8f373666c1e3.png)

#rmagic
Imagemagicの準備ができたら、rmagicをインストールする。
>>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/6c20a1ed-7074-b888-9584-60966aa8244f.png)

全て完了すると、Uploaderファイルで設定を書けば、リサイズ等ができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/d4b1bcf1-180f-dbaa-5740-4f9571524012.png)
**参考にしたサイト**
http://thoames.hatenadiary.jp/entry/2018/05/20/045212
https://qiita.com/sta/items/63e1048025d1830d12fd
JavaScfiptでワンライナーFizzBuzz

## 概要
たまたまFizzBuzzのJavaScriptワンライナーを即興で書く機会があったので、その時に書いたコードについてまとめました。
最短で書く方法を期待してこのページを開いた方は [補足](#補足) をご覧ください。

## 140byte版
こちらが実際に書いたコードです。
※書く時に JavaScript で範囲オブジェクト的なものを扱うには？ということを考えていたのでforを使わず、かつ処理速度の観点から console.log の呼び出し回数を 1 回にしています。

```javascript:fizzbuzz.js
let num = 100; // FizzBuzz数
console.log(Object.keys(Array(num).fill()).map(i=>Number(i)+1).map(i=>i%3==0&&i%5==0?"Fizz Buzz":i%3==0?"Fizz":i%5==0?"Buzz":i).join("\n")) // 140byte
```

JavaScript では Range オブジェクトが使えないので（2020年1月現在）
`Object.keys` に `Array(x).fill` を与えて num 数分の配列を生成しています。

上記のワンライナーを分解して順番に解説すると

```javascript
Array(num).fill() // [undefined, undefined, undefined, ...] num の数だけ続く
```
※ `Array(num)` に対して `.fill()` を呼ばないと、結果が `[empty x num]` となり `.map()` できません

```javascript
Object.keys(Array(num).fill()) // ["0", "1", "2", ...]
```
num 数分の配列を生成したため、そこから`.keys()`（添え字）を抽出しています。注意すべきポイントとして、配列の添え字ですので 0 オリジン、かつ文字列型となっています。

```javascript:
Object.keys(Array(num).fill()).map(i=>Number(i)+1) // [1, 2, 3, ...]
```
0 オリジン、かつ文字列型の配列から、FizzBuzzで扱われる 1 から N までの整数を得るため、mapで整数型に変換（かつ 0 オリジンだった添え字を1ずつインクリメント）しています。

ES2015 以降なら配列のスプレッド構文が使えますので

```javascript:
[Array(num+1).keys()].slice(1, num+1)
```

でより簡潔に書けますね。

なお、上記の 1 から num をぐるぐる処理したい、というのは python であれば

```python
for i in range (1, num)
```

ruby なら

```ruby
1..num do
```

と書けるところです。

JavaScript に話を戻しますが 1 から num の配列が得られたら、あとは

```javascript
i%3 == 0 && i%5 == 0 ? "Fizz Buzz" : // 3 の 倍数かつ 5 の倍数 なら "Fizz Buzz"
i%3 == 0 ? "Fizz" : // 3 の 倍数なら "Fizz"
i%5 == 0 ? "Buzz" : // 5 の 倍数なら "Buzz"
i // いずれでもなければ数値そのまま
```

を `.map()` で返し、`join("\n")` で連結すれば完成です。

## 107byte版

ここからさらに、`"Fizz"` と `"Buzz"` をつなげてよい、かつ配列スプレッド構文も用いれば

```javascript
let num = 100; // FizzBuzz数
console.log([...Array(num+1).keys()].slice(1,num+1).map(i=>(i%3?'':'Fizz')+(i%5?'':'Buzz')||i).join("\n")) // 107byte
```

と書けます。

三項演算子の条件が逆転している（3の倍数なら～ではなく、3の倍数以外なら～で評価している）、FizzBuzz部が空文字だった際にショートサーキットを利用して数値を出す、などさらにトリッキーなコードとなっており、自らもミスタイプなしですらすらかけるコードではないので、冒頭のコードと解説には実際に即興で書いたものを用いました。

## 補足
コメント欄でも頂きましたが、FizzBuzz は基本的に for 文で書くほうが記述がスッキリします。
（ご指摘ありがとうございます）。

@fujitanozomu さんがコメントしてくれたコード

```javascript
let num = 100; // FizzBuzz数
for(i=0;i++<num;)console.log((i%3?'':'Fizz')+(i%5?'':'Buzz')||i)
```

さらに、最短で書く方法を期待してこのページを開いた方は
@nb_tomo さんの下記 Qiita 記事が大変参考になります。
[FizzBuzz問題のJavaScript最短コードを解説します](https://qiita.com/nb_tomo/items/041715068665dc94aac4)
docker環境での django ホットリロード


## docker-compose.yml

```
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: backend
    command: 'sh /server/start.sh'
    expose:
      - "8001"
    restart: always
    volumes:
      - ./backend:/server/
```

## djangoプロジェクト内
start.sh

```
#!/bin/bash
sleep 5
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic --noinput
# ここで読込
uwsgi --ini /server/config/uwsgi.ini
```

## config
 uwsgi.ini 作成

```
[uwsgi]
socket = :8001
module = config.wsgi
wsgi-file = /server/config/wsgi.py
logto = /server/config/uwsgi.log
py-autoreload = 1
```
PHPで暗号学的に安全でランダムな文字列を柔軟に生成する方法

# やりたいこと

- ランダムな文字列を取得したいよ。
- **PHPの標準関数だけで**やりたいよ。
- **暗号学的に安全なランダム性**を持たせたいよ。
- **出力で使用する文字や文字長を指定したい**よ。(0~fだけとかヤダよ)
- PHP5系では動かせなくてもいいよ。

# 暗号学的に安全じゃない方法とは？

「ランダムな文字列をゲットしたいな」というとき、よく以下のようなコードが使われるかと思います。

```php
echo sha1(uniqid(mt_rand(), true));
// 出力例 : f282fe197b5f9837a520118d5636facc0ff3832d
```

実はこれだと問題があって（まぁ実際はほぼ問題になることは無いと思いますが…）、「mt_rand()」も「uniqid()」も生成される値が**暗号学的に安全ではない**とリファレンスに明記されています。

**PHPマニュアル - 関数リファレンス**

- [mt_rand()](https://www.php.net/manual/ja/function.mt-rand.php)
- [uniqid()](https://www.php.net/manual/ja/function.uniqid.php)

あと、そもそもこの方法だと「出力で使用する文字を指定」したり、「出力文字長を指定」したりできないですね。


# 暗号学的に安全な方法１（0~f固定だけど簡単な方法）

出力される文字が0~f固定でも良い場合は、以下のコードでOKです。

```php
$length = 16;
echo substr(bin2hex(random_bytes($length / 2 + 1)), 0, $length);
// 出力例 : cf7ffd47e6cb2399
```

random_bytes()は、**暗号学的に安全なランダムバイト列**を生成します。
生成したバイト列をbin2hex()で文字列に変換し、最後にsubstr()で必要な長さに切っています。

**PHPマニュアル - 関数リファレンス**

- [random_bytes()](https://www.php.net/manual/ja/function.random-bytes.php)


# 暗号学的に安全な方法２（0~f固定じゃないし文字長指定できるし使用文字を指定できる方法）

見た方が早いですね。以下の通りです。

```php
function random_string($length = 16) {
    // 出力で使用する文字を決める。
    // 例えば、以下の場合は、「英数字から見間違え安い文字を除外した文字」のみにしてある。
    // （lとかOとか除外してある）
    $baseChars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
    $baseCharLength = strlen($baseChars);

    // 指定された数だけランダムな文字を取得する
    $output = '';
    for ($i = 0; $i < $length; $i++) {
        // rand()ではなく、暗号学的に安全なrandom_int()を使用する。
        // ちなみに、文字列は角括弧で任意の文字にアクセスできるので、substr()じゃなくてOK。
        $output .= $baseChars[random_int(0, $baseCharLength - 1)];
    }

    return $output;
}
```

コメントにも書いてありますが、出力で使用したい文字を$baseCharsで指定しています。
そこから、必要な文字長だけ**ランダムに文字を取り出していく**、という流れです。

このとき、ランダムな取り出し位置はrandom_int()で指定します。random_int()で生成される値は**暗号学的に安全**であることがリファレンスにも明記されています。

**PHPマニュアル - 関数リファレンス**

- [random_int()](https://www.php.net/manual/ja/function.random-int.php)

出力結果はこんな感じです。

```php
for ($i = 0; $i < 5; $i++) {
    echo random_string(16)."\n";
}
// deWWGQ9wWGBVDFcU
// ui7usFxSx8FwWPCM
// d7AGQmydVcPbcwv6
// xzuVnAKCr5QB7Rz8
// SHHc8UV3Ha5F2th3
```


## 出力する文字にマルチバイト文字を使用したい場合

マルチバイト文字の場合は「strlenではなくmb_strlenを使う」、「文字列からの文字取り出しは角括弧ではなくmb_substrを使う」にします。

```php
function mb_random_string_iroha($length = 16) {
    $baseChars = 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせすん';
    // マルチバイト文字を使う場合は、mb_strlen()で。
    $baseCharLength = mb_strlen($baseChars);

    $output = '';
    for ($i = 0; $i < $length; $i++) {
        $pos = random_int(0, $baseCharLength - 1);
        // マルチバイト文字ならこちらもmb_substr()で。
        $output .= mb_substr($baseChars, $pos, 1);
    }

    return $output;
}
```

出力結果はこんな感じです。

```php
for ($i = 0; $i < 5; $i++) {
    echo mb_random_string_iroha(16)."\n";
}
// なたれあなやろおおてほねさえれゆ
// あよらゑふめさたなりよゐむきたせ
// ゆてるいもそしやぬりゐてちひたか
// しのけちほねせねえつゆくすおめせ
// のつすいらなほれれむりとよまさる
```

---

最後に、[高精度の姓名分割ツール](https://name.buta3.net/) とか [Writeningっていうメモサービス](https://writening.net/) とか、その他色々作ってるのでぜひプロフィール欄のホムペを覗いてみてください〜
Swift：Processでgrepする

SwiftでCommand Line Toolを叩く時は`Process`を使いますが，`grep`したい時どうすればいいのかわかりづらかったので備忘録

```swift
func extractDefaultInternet() {
    // $ netstat -rnf inet | grep default
    let pipe1 = Pipe()
    let pipe2 = Pipe()
    
    let netstat = Process()
    netstat.launchPath = "/usr/bin/env"
    netstat.arguments = ["netstat", "-rnf", "inet"]
    netstat.standardOutput = pipe1
    
    let grep = Process()
    grep.launchPath = "/usr/bin/grep"
    grep.arguments = ["default"]
    grep.standardInput = pipe1
    grep.standardOutput = pipe2

    netstat.terminationHandler = { (_) in
        grep.launch()
    }
    netstat.launch()
    
    let data = pipe2.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}
```

こんな感じで`Pipe`を2個用意して，`grep`の方の`standardInput`に一つ目のコマンドの出力結果の`Pipe`を入れて，一つ目の実行結果の後に`grep`を実行するように`terminationHandler`を登録してあげればOKです．

さらに`grep`したい時も同様の手順でOKです．

```swift
func en0() {
    // $ netstat -rnf inet | grep default | grep en0
    let pipe1 = Pipe()
    let pipe2 = Pipe()
    let pipe3 = Pipe()

    let netstat = Process()
    netstat.launchPath = "/usr/bin/env"
    netstat.arguments = ["netstat", "-rnf", "inet"]
    netstat.standardOutput = pipe1

    let grep = Process()
    grep.launchPath = "/usr/bin/grep"
    grep.arguments = ["default"]
    grep.standardInput = pipe1
    grep.standardOutput = pipe2

    let grep2 = Process()
    grep2.launchPath = "/usr/bin/grep"
    grep2.arguments = ["en0"]
    grep2.standardInput = pipe2
    grep2.standardOutput = pipe3

    grep.terminationHandler = { (_) in
        grep2.launch()
    }
    netstat.terminationHandler = { (_) in
        grep.launch()
    }
    netstat.launch()
        
    let data = pipe3.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}
```

# 追記
いろいろやっていたらもっと強い方法を見つけてしまいました．

```swift
func runShell(_ args: String) {
    let process = Process()
    process.launchPath = "/bin/sh"
    process.arguments = ["-c", args]
    
    let pipe = Pipe()
    process.standardOutput = pipe
    process.launch()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}

runShell("ifconfig | grep broadcast")
```

シェルを文字列を引数にして叩けばなんでもありやないか...
【Kotlin備忘】他のActivityへBitmapの受け渡し



photoはbitmap


```kotlin:受け渡し側

val intent = Intent(this, XXXXActivity::class.java)
intent.putExtra("data",photo)
startActivity(intent)
```

```kotlin:受け取り側
val intent = getIntent()
val photo = intent.getParcelableExtra<Bitmap>("data")
```

bitmapがデカすぎる場合、URIを利用した方がいいらしいけど
【Firebase】failed: DatabaseError: Permission denied

Firebase RealtimeDatabase使っている時、パーミッションがの設定値が初期値だとエラーが出る

```
failed: DatabaseError: Permission denied
```

ここのreadとwriteをtrueにしてあげれば通るようになる
<img width="1104" alt="スクリーンショット 2020-01-19 0.58.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283826/a20c0af2-1d6b-8047-7a4f-4a491a664813.png">
ROOT CERNのTGraphで横軸を時間表示にする

##はじめに
ROOT CERNはCERN(欧州原子核研究機構)による描画・解析ソフトウェアで、C++を使っている(rootユーザーのrootとは違う、要注意)。pythonからも使える。無料。

今回はROOT CERNでグラフを書くとき、X軸を時間にした際のメモ。

##注意・参考
UNIXタイムの亜種版を使う。UNIXとROOT CERNではデフォルトの基準時刻が異なる(何故わざわざずらしたんだろう)

公式サイト
https://root.cern.ch/how/how-create-axis-time-units
参考
https://michael-e29.hatenadiary.org/entry/20120731/1343698183

オフセットの絶対値を指定し直すのが混乱がなくて良いかもしれない。
例は

```c++

TDatime da(2020,01,01,12,00,00);
gStyle->SetTimeOffset(da.Convert());
gStyle->SetNdivisions(505);
```

TMultiGraphに対しては先にDrawしてからTimeDisplayをONにしてから、gPadをアップデートしないとセグフォする。


```c++
TMultiGraph *mg = new TMultiGraph();
mg->Add(grH2O);
mg->Add(gr2);
mg->Add(gr3);
mg->Add(grN2);
mg->Draw("AP");
mg->GetXaxis()->SetTimeDisplay(1);
mg->GetXaxis()->SetTimeFormat("%H:%M");
gPad->Modified();
gPad->Update();
```
injectの解釈

#eachより簡潔に書ける
```inject.rb
def keisan
  (1..20).inject(0) do | sum, num|
    sum += num
  end
end
#sum = 0 inject(0)←かっこ内（引数）が変数の初期値。
```

ただし、メソッドを書いてそこの値を戻すようにしないと、
メソッドの外（スコープ外のため）では使えない。

eachとの使い分けは「見やすいかどうか」で決める。
Rubyは自由度が高いようので、
色んな書き方ができそう。

**他人が見たときにわかりやすく書くことが重要**
GCPへの問い合わせは日本語でも問い合わせ出来るのか？

# はじめに
* GCPへ問い合わせをしている時、**「英語じゃなくて日本語でも問い合わせ出来なかったっけ？」**という話が出た。

## 日本語での問い合わせは可能なのか？
* 結論からいうと日本語での問い合わせは**可能です**。しかし、日本語で問い合わせをするには条件がありました。
* その条件とは使用しているサポートパッケージが**ゴールドまたはプラチナ**である場合です。
 * 公式からのメールを載せることが出来ないため、公式の説明がありましたのでこちらを載せます。

[GCP Japan Blog](https://cloudplatform-jp.googleblog.com/2015/07/blog-post.html)：日本語によるカスタマーサポートを開始

## まとめ
* 結局日本語で問合わせが出来るサポートを使用していなかったため、引き続き英語で問い合わせをすることになりました。
【備忘録】Windows+gVim+PowerShellでC言語開発をする

# VisualStudioのインストール
インストールするときにC++によるデスクトップ開発の中のWindows用C++Clangツールにチェックをつける
# Powershellのプロファイル編集
プロファイルの場所
https://docs.microsoft.com/en-us/previous-versions//bb613488(v=vs.85)?redirectedfrom=MSDN

プロファイルに下記を追加する

```powershell
function Activate-VSEnv {
  $installPath = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -version 16.0 -property installationpath
  Import-Module (Join-Path $installPath "Common7\Tools\Microsoft.VisualStudio.DevShell.dll")
  Enter-VsDevShell -VsInstallPath $installPath -SkipAutomaticLocation
  $env:path += ";" + $installPath + "\VC\Tools\Llvm\bin"
}
```
参考：https://intellitect.com/enter-vsdevshell-powershell/

# Vimプラグインの追加
vim-lsp-settingsを入れる
https://github.com/mattn/vim-lsp-settings
vim-lsp-settingsが依存している下記プラグインも入れる
https://github.com/prabirshrestha/async.vim
https://github.com/prabirshrestha/asyncomplete.vim
https://github.com/prabirshrestha/asyncomplete-lsp.vim
https://github.com/prabirshrestha/vim-lsp

プラグインさえ入れれば基本的にvimrcの設定は不要

# vimの実行
powershellを開いて
`Activate-VSEnv`
を実行した後にそのpowershellからvimを開く

Cのソースファイルを開いたときに自動補完やコードチェックが機能すれば成功。

# コンパイル
先ほど
`Activate-VSEnv`
を実行したpowershellで
`clang-cl [ファイル名]`
でコンパイルできる。
忘年会のために作った昔のテレビみたいに画面遷移するJavaScript

僭越ながら、[エヌシーアイ総合システム Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nci) 20日目を担当させていただきます。
（投稿が1月中旬になってしまった…）
忘年会のために作ったJavaScriptについて書きます。
ちなみに全体が完成したのは忘年会前日深夜3時でした。


## どんな感じで画面遷移するの？

![ezgif.com-crop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557329/f8f2fd8b-5f95-1141-1698-b45df07cda26.gif)


こんな感じで動きます。
遷移前と遷移後で同じページのように見えますが、別のページに飛んでいます
今や見る影もないブラウン管テレビってこんな感じだった気がします。

大まかな中身としては 
　**フェードアウトのアニメーション
　ページ移動
　フェードインのアニメーション**
の流れになります。


## フェードインのアニメーション

順番が逆になりますが、まずフェードインからです。
こちらはCSSだけで作りました。

```style.css
body {
	animation: animate_in 1s ease;
}

@keyframes animate_in{
	0%{
		transform: scale(0.2, 0.01);
		opacity: 0;
	}
	70%{
		transform: scale(1, 0.01);
		opacity: 1;
	}
	100%{
		transform: scale(1, 1);
	}
}
```

`@keyframes` を使って動きを処理しています。
画面サイズと透明度を変えてそれっぽく見せています


## フェードアウトのアニメーション

こちらが本題です。
リンクが押されるとアニメーションが起動するようにJavaScriptを書きます。
またアニメーション終了までページ移動を止める必要があります。

```style.css
.animate_content{
	animation: animate_out 1s ease;
}

@keyframes animate_out{
	30%{
		transform: scale(1, 0.01);
	}
	70%{
		transform: scale(0.2, 0.01);
		opacity: 1;
	}
	100%{
		transform: scale(0.2, 0.01);
		opacity: 0;
	}
}
```

```page_transition.js
$(function() {
    $('a:not([href^="#"]):not([target])').on('click', function(e) {

        // ページ移動を止めてURLを取得
        e.preventDefault();
        url = $(this).attr('href');

        // クラスを追加
        $('body').addClass('animate_content');

        // 980ms経ったらページ移動
        setTimeout(function(){
            window.location = url;
        }, 980);

        return false;
    });
});
```

アニメーションの1s(1000ms)が終わるまでにページ移動しないといけないので、980msで移動させています。
追加するクラス / 追加される属性 を簡単に指定できるので応用は効きそうな気がしますね。


## 終わりに

学生時代はJavaScriptを避けてきたので勉強しないとですね。
競プロでなんとなく使っていたメソッドを調べた

RubyでAtCoderを解いていて、なんとなく雰囲気で使っていたメソッドを調べた。

## map

### こんな感じで使っていた
```
1 2 3 4 5
```
こんな感じの標準入力を受け取る際に、

```
array = gets.chomp.split(" ").map(&:to_i) 
p array # => [1, 2, 3, 4, 5]
```

として、配列に文字列ではなく、数値として格納する際に利用していた。

####ここでのmapの役割
配列の各要素に対して、ブロックを評価した結果を全て含む配列を返す。Rubyのリファレンスマニュアルの利用例を以下に紹介

```
# すべて 3 倍にする
p [1, 2, 3].map {|n| n * 3 }  # => [3, 6, 9]
```

なるほど。

### map(&:to_i)の"&:"って何?
mapでやっていることは、リファレンスマニュアルの例で理解できた。じゃあ、&は何者なのか?


#### &
今回のケースでは以下のような役割があるらしい。

```
Proc オブジェクトをブロックとして使う
```
[リファレンス](https://docs.ruby-lang.org/ja/2.2.0/doc/symref.html#and)

#### Procとは
```
ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
```
[リファレンス](https://docs.ruby-lang.org/ja/2.2.0/doc/symref.html#and)

ちょっとよくわからないけど、ブロック付きのメソッドに対して、&を使ってProcオブジェクトを呼び出すと、いい感じに書けるらしい。

つまり、初めに戻って、

```
array = gets.chomp.split(" ").map(&:to_i) 
```
と

```
array = gets.chomp.split(" ").map { |number| number.to_i }

```
の振る舞いは同じで、前者の方が直感的でわかりやすい気がする。

## inject
### こんな感じで使っていた

```
[1,2,3,4,5]
```
こんな感じの配列の和を計算するときに、

```
array.inject(:+) # => 15
```

### ここでのinjectの役割
ブロックを使って繰り返し計算を行うのに使う。injectメソッドにブロックの代わりにシンボルsymでメソッド名を渡すことができる。
第1引数initに初期値を指定すると、「初期値.メソッド(要素1)」、「前回の結果.メソッド(要素2)」、...を計算する。

リファレンスの例を紹介

```
numbers = [4, 3, 9, 8, 5, 6, 1, 7, 2]
puts numbers.inject(:+) # => 45
puts numbers.inject(100, :-) #=> 55
```
[リファレンス](https://ref.xaio.jp/ruby/classes/enumerable/inject)

## まとめ
知らないことが多くて楽しい。競技プログラミングをちびちび頑張る。
【SAS】基本統計量のいろんな作り方

基本統計量の一覧は大体毎日見るが、意外とその作り方とパターンの説明が少ないと思う。
そのためよく使う作り方を示す。

1) proc means を使う方法(標本の基本統計量 sample）
2) proc means を使う方法（母集団の基本統計量 population） 
3) データセットを自作する方法


##1) proc means を使う方法(標本の基本統計量 sample）

###コード
一番シンプルだが、自由度`n-1`のいわゆる不偏分散を使用する。

```math
分散　
s^{2}=\frac{1}{n-1}\sum_{i=1}^{n}\left ( x_{i}-\overline{x} \right )^{2}
```

```
%let sourceDS = 使用するデータセット;
TITLE SAMPLE_MEANS;

proc means data=&sourceDS mean var std;
	var avg_temp avg_humid daytime;
run;
```
###出力

![procMeansN-1 2020-01-18 23.02.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394058/a54a2ef6-ec27-320c-26b3-62e5ea867e1b.png)


##2) proc means を使う方法（母集団の基本統計量 population） 


###コード 
__`vardef=n`__ がオプションで追加される。これは
分散の定義(definition of variance) の設定をしている。
自由度(degrees of freedom) は　`n` つまりデータの個数にすることを意味する。。
よって下記で表す分散を使用する。

```math
分散　
\sigma^{2}=\frac{1}{n}\sum_{i=1}^{n}\left ( x_{i}-\overline{x} \right )^{2}
```

```
%let sourceDS = 使用するデータセット;
TITLE POPULATION_MEANS;

proc means vardef=n data=&sourceDS mean var std;
	var avg_temp avg_humid daytime;
run;
```
###出力

![procMeansN 2020-01-18 23.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394058/f329c1c2-8316-e860-1516-d31734a7712d.png)


##3) データセットを自作する方法


###コード 
手間は増えるが

- 一覧で見たい時、
- 独自に取得したい統計量を追加する時、
- コードをまとめてしまいたい時、etc

にはどうしてもこうなる。
しかしマクロ化すれば良いだけなので作る価値は十分にある。

ポイントは基本統計量の変数を自作する際の`COL:`だ。
これで`COL1`のように`COL`＋数字の変数すべてを計算の範囲に指定している。
これにより`COL`変数の数を気にしなくても良くなる。
SASの関数の引数にするときは`(of COL:)`のように`of `をつけることに注意しよう。

```
%let sourceDS = 使用するデータセット;
%let popDS01 = 基本統計量の元となるデータセット;

TITLE 使用するデータセット;
proc print data=&sourceDS;
run;

/* データのタテヨコを入れ替える*/
proc transpose data=&sourceDS out=&popDS01;
run;

TITLE 基本統計量の元となるデータセット;
proc print data=&popDS01;
run;

/* 基本統計量の変数を自作する */
data &popDS01;
	set &popDS01;
	N_ = N(of COL:); /* データの個数 */
	Avg_ = mean (of COL:); /* 平均 */
	Var_ = (N_ -1)/ N_ * var(of COL:);　/* 母集団の分散 */
	Std_ = sqrt(Var_); /* 母集団の標準偏差 */
	Var_S_ = var(of COL:);　/* 標本の分散(不偏分散) */
	Std_S_ = sqrt(Var_S_);　/* 標本の標準偏差(不偏標準偏差) */
	
	attrib
		_NAME_ LABEL="項目名"
		N_ LABEL="個数"
		Avg_ LABEL="平均"
		Var_ LABEL="分散"
		Std_ LABEL="標準偏差" 
		Var_S_ LABEL="不偏分散" 
		Std_S_ LABEL="標本標準偏差"
	;

	
run;

TITLE 基本統計量の出力先のデータセット;
proc print data=&popDS01 label;

	var _NAME_ N_ Avg_ Var_ Std_ Var_S_ Std_S_
	;
run;

quit;


```
###出力



![selfbuildMeans 2020-01-19 00.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394058/bb9630a1-f298-e27b-cee6-2de7e7951d0b.png)




## 終わりに



質問、間違いなどがあればコメントください。
RailsのTime.zone.parseでハマった

`Time.zone.parse`に渡す引数は日付っぽいものであり、かつvalidであればきちんとparseされ、
日付として認識されるフォーマットでありつつも値がおかしい（`2020-99-99 99:99:99`など）場合は`ArgumentError`がraiseされ、
そもそも日付として認識されない文字列は`nil`を返す。
`nil`を返すんですね。（2回目）

最後の場合も`ArgumentError`がraiseされる想定だったためハマった。

要件としては「ユーザーが自由入力できる入力欄において、日付としてvalidな文字列であればそのまま保存し、invalidな文字列であればエラーを吐かせる」ものだったのであまりないパターンかとは思う。

## 参考
### リファレンス
https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html#method-i-parse
`20:00:00`とかもいけるっぽい（日付は現在日付になる）

### Qiita
https://qiita.com/slightair/items/fa5f63016c0c848111a9
ここでもnilになる挙動について少し触れられている
matplotlibでグラフを重ねて表示することに苦労した話

##背景
matplotlibでデータを可視化していたら、棒グラフを折れ線グラフを重ねて表示できないのかと思った。（異なる種類のグラフはそれぞれ別のグラフに出すのをよく見るので）
簡単にできると思っていたら苦労したので、可視化できるまでに必要だった知識をまとめる

<b>最終的作成したコードとグラフ</b>

````python
#Importing required packages.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import SGDClassifier
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score
%matplotlib inline

#Loading dataset
train_df = pd.read_csv('./input/train.csv')
test_df = pd.read_csv('./input/test.csv')

#plot用のsort済みデータを作成
line_df = train_df.sort_values(by=["quality","fixed acidity"])

fig = plt.figure(figsize = (20,10))
ax = fig.add_subplot(1,1,1) # Axesを作成
line1= ax.bar('quality', 'fixed acidity', data = train_df, label='1st plot',alpha=0.5,color='y') # Axes.linesにLine2Dを追加
line2 = ax.plot('quality', 'fixed acidity', data = line_df, label='2nd plot') # Axes.linesにLine2Dを追加
ax.legend()
ax.set_xlabel('x value')
ax.set_ylabel('y value')
```
出力結果
![スクリーンショット 2020-01-18 23.39.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223898/aa9f62d3-aae1-72b6-f77e-523c0903c1b9.png)


##matplotlibの構造の知識
今までplt.plot()のカッコ内にデータ突っ込むくらいしか知識が無かったが、他にオブジェクト思考的にグラフの部品部品を作成していくようなイメージの作り方があった。
イメージはグラフを作成する土台（figure）を作成し、その上にグラフをかく板（axes）、その上に軸たち（Axis）を作成していくというもの。
で作り終わった後に、グラフをかく板（axes）にあるグラフを表示する機能（axes.plotなど）を使って描写できる。
こっちのオブジェクト指向的な方が、各パーツをイメージしながら作成できるので細かい部分を調整する場合は良いらしい。
[詳しくはこちら](https://qiita.com/skotaro/items/08dc0b8c5704c94eafb9)
##matplotlib.axes.Axes.plotの罠
axes.plot()で２箇所ほどつまづいた。

<b>1点目</b>
最初はx = ,y = のような感じでデータを直接指定したがエラーが出た。
原因は今回dataframeオブジェクトを渡したので、オプションにはデータのカラム名のみ記入する必要があった。
下がmatplotlib.axes.Axes.plotのドキュメント
>
There's a convenient way for plotting objects with labelled data (i.e. data that can be accessed by index obj['y']). Instead of giving the data in x and y, you can provide the object in the data parameter and just give the labels for x and y:
>>> plot('xlabel', 'ylabel', data=obj)

[matplotlib.axes.Axes.plotのドキュメント]
(https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.plot.html)

下が解決したコード部分

```python
line2 = ax.plot('quality', 'fixed acidity', data = line_df, label='2nd plot')
```

<b>2点目</b>
axes.plot()で折れ線グラフを作ったがこれはarray配列の最初からプロットされた点をただ結んでいくので、順番を揃えないとぐちゃぐちゃなグラフが出来上がった。（下図はイメージ）
![スクリーンショット 2020-01-18 23.51.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223898/7cc341e0-88d6-52ef-f4e5-95185664b9c1.png)

X軸とY軸で順番をsortしたdataframeを新しく作成することで解決

```python
line_df = train_df.sort_values(by=["quality","fixed acidity"])
```
NeovimでSwaggerをリアルタイムプレビューするプラグインを作った話

## はじめに
Neovimと出会って約半年、今年こそ何かプラグインを作るぞ！ということで、Swaggerをリアルタイムでプレビューするプラグインを作成しました。
モチベーションは、単純にVimでSwaggerを書きたかった..ということです。

## リポジトリ
インストール方法、使い方はこちらに記載しております。
[shuntaka9576/preview-swagger.nvim](https://github.com/shuntaka9576/preview-swagger.nvim)

## 機能紹介
![output-palette.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159755/f788350b-88f7-0a55-b1be-bf39fcc7f750.gif)

gif画像の通りで、:SwaggerPreviewコマンドを実行すると、ブラウザが開きます。
あとは、Neovim上でファイル編集を行うと、リアルタイムで内容が表示されます。

## 仕組み/技術
### リモートプラグイン
Neovimには、プラグインをNeovim本体とは別のプロセスで起動し、msgpack-RPCを利用して機能拡張するリモートプラグインという仕組みがあります。
通常VimのプラグインはVimScriptを書く必要がありますが、リモートプラグインの仕組みを使うとコア部分はPython/Node.js/Go/Luaといった言語で書くことが出来ます。
msgpack-RPCに関しては、ラップされたライブラリが提供されているため意識せず書けました。

### TypeScript
前述のリモートプラグインの仕組みを利用して、プラグインのコア部分はTypeScript(Node.js)で書いています。

### Socket.IO
リアルタイムのWebアプリケーションを実現する方法は幾つかあり、Socket.IOはそれらをラップし全てのブラウザ・モバイルデバイスでリアルタイム通信を可能にするライブラリです。真新しいものではないです。

今回Neovimのバッファにあるのデータをフロントエンドに渡す部分で、Socket.IOを利用しています。
動作の流れは以下の通りです。

1. (Neovim)カーソルが動く度にイベント発火、リモートプラグインをコール
2. (リモートプラグイン)Socket.IOでデシリアライズしたバッファの内容を乗せてイベント発火
3. (フロントエンド)イベントを受け取り、バッファ内容をSwaggerUIで表示

## 参考にしたOSS
[iamcco/markdown-preview.nvim](https://github.com/iamcco/markdown-preview.nvim)
マークダウンのリアルタイムプレビューだけでなく、カーソルの操作を元に自動でブラウザのスクロールをしてくれます。
Socket.IOの仕組み諸々とても参考にさせて頂きました。
フロントエンドはNext.jsを使われており、フロント経験のない私には分からなかったです..

## 最後に
初めてのプラグイン開発で感じたことは、当然ですがVimの基礎知識がないと辛いということです。
開発する前に[Vim scriptテクニックバイブル](https://www.amazon.co.jp/Vim-script-%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%83%90%E3%82%A4%E3%83%96%E3%83%AB-Vim%E4%BD%BF%E3%81%84%E3%81%AE%E9%AD%94%E6%B3%95%E3%81%AE%E6%9D%96-script%E3%82%B5%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%BA/dp/4774166340)を見て軽く手を動かして良かったです。
Vimmerが一つ踏み込んでプラグインを開発する際に、丁度良い本でした。

フロント側は知識がなくやっつけなので、なんとかしたいと思っています！

勿論issue報告やプルリクエストがあれば大歓迎です。

以上、preview-swagger.nvimの紹介でした。