OmniAICreator/Qiita-1.07M huggingface dataset:
npmパッケージ公開のHello World (初めてのパッケージ公開)

この投稿では、npmパッケージを初めて公開するための練習として、必要最低限のファイル構成でパッケージ公開する方法を説明します。

ここで説明するのは、あくまで「練習」であって、実践ではファイル構成や手順がもっと複雑になります。極小のパッケージ公開を体験することで、実践に移しやすくなればと思います。

## 最低限のファイル構成

* package.jsonがただ一つ有ればいい

```text:最低限のファイル構成
.
└── package.json

0 directories, 1 file
```

## 最低限のpackage.json

* `name`と`version`だけ有ればいい。

```package.json
{
  "name": "@suin/test-1",
  "version": "0.0.1"
}
```

__注意__: 一度公開した`name`+`version`は公開停止(unpublish)したとしても再利用できないので、試す場合は使えなくなっても困らない`name`と`version`にしてください。試す場合は、自分のscope(@ユーザ名/パッケージ名の形式)で行うようにし、NPMのグローバルスコープを汚さないようにしましょう。

## 最低限の公開手順

* `npm publish --access public`を実行します。
    * `--access public`を付けないと非公開パッケージとしてNPMに登録できますが、課金ユーザ限定の機能です。

```
$ npm publish --access public
npm notice
npm notice 📦  @suin/test-1@0.0.0
npm notice === Tarball Contents ===
npm notice 71B package.json
npm notice === Tarball Details ===
npm notice name:          @suin/test-1
npm notice version:       0.0.0
npm notice package size:  163 B
npm notice unpacked size: 71 B
npm notice shasum:        f9226fd47994a2eeb0c4dbd450c85097cf2d0bcb
npm notice integrity:     sha512-UdTvCTfjd/Nzd[...]UFWLtaf6/cXyA==
npm notice total files:   1
npm notice
+ @suin/test-1@0.0.0
```

---

最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローお願いします:relieved:→[Twitter@suin](https://twitter.com/suin)
アバターの音声を変える

[Teams会議でアバターを使う](https://qiita.com/hiraokusky/items/ce3d64856e414609b141)で、自分の映像をアバターに変えることができました。
しかし、音声は変わっていません。
性別の違うアバターを使うために、音声も変えてみます。

# 実現する構成

以下のように音声が流れるように設定します。

    マイク　→　恋声　→　VB CABLE Input　→　VB CABLE Ouput　→　Teams

VB-CALBEという仮想オーディオデバイスによって実現します。
声質変換は「恋声」というフリーウェアを使わせていただきます。
ただ、ここに示す設定では、PCの音声がすべて相手側に流れてしまうので、ご注意ください。

# インストール

VB Cable
https://www.vb-audio.com/Cable/
※VB Cableのインストール後、再起動が必要なので、先にインストールします。再起動すると、サウンドの出力デバイスと入力デバイスが変わっているので直しておきます。

恋声
http://koigoemoe.g2.xrea.com/koigoe/koigoe.html

# 恋声を起動する

マイクボタンを押します。
この状態でマイクにしゃべると少し遅れてスピーカーから自分の声が返ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44912/7f2bb669-d541-6442-2cd6-5101223186ec.png)

次に、Presetで、男性→女性の場合「M→W」を女性→男性の場合「W→M」を押します。
そうすると、スピーカーから返る声が変わります。

# VB Cableを設定する

サウンドの設定を開き、出力デバイスにCABLE Inputを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44912/2da1a1fd-24fb-c575-5956-71fad57fe620.png)

# Teamsを設定する

Teamsのデバイスの設定を開き、マイクにCABLE Outputを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44912/af0bddbb-be08-e775-c71f-35ed7fe2cef3.png)

これで準備完了です。
Teams会議を開始し、何かしゃべると、相手側に変換された声が届きます。
自分の生の声は届きません。

遅延は1秒くらいありますので、音声と口パクを同期するために、Luppetのリップシンク設定を音声ベースにしてマイクをCABLE Outputにしておくとよいと思います。

よいアバター会議ライフを。
おしまい。
Vue.jsとLaravelを独学してWebアプリ作ってみた

**３月からVue.jsとLaravelを中心に独学を開始→Webサービスを作るまでのお話。**

- スキルを習得するにはやっぱり実際に何かを作ってみるのがいいよね
- クラウドソーシング用のポートフォリオに作ったものを載せたい

ということで１つサービスを作ってみました。

作ったのは「**ポーションジェネレーター！**」という、メーカー系Webアプリです。
公開URL: https://p.sigr.io/

診〇メーカーみたいなメーカー系webアプリなら比較的短期間で作れるかな？と思ってこのサービスを作ることに決めました。

![ポーションジェネレーター！](https://i.gyazo.com/bec0cba79b5968da54601fffda915f88.png)

#サービスの概要
よくみかけるメーカー系アプリにポーション要素を追加したもの。

実際の動作は以下のようなかんじ
![ポーション開封](https://i.gyazo.com/9796b61247af7174b1c437bc54a39a40.gif)
すいません。なんか汚い単語が出ていますがランダムなので許してください（）

##作成画面
ポーションの種類もいろいろあり、作成するときに好きなのを選べます
![ポーション選択](https://i.gyazo.com/8b7d83dce1795cca5922882fd7025dc6.gif)

アニメーションは拾い物（他のゲームからの移植）なのでこのサービス用に作ったわけではないです

#使用したフレームワークなど
タイトルにもありますが、改めて。

- Vue.js (いま話題？の)
- Laravel (phpのフレームワーク)
- Vuetify (大好きなVue.jsのUIフレームワーク)
- MySQL (データベース)

##選んだ理由
上記のフレームワークなどを選んだ理由について。

![vue.js](https://i.gyazo.com/92baa5695a3d50c2ce2929ddd9320afb.png)
フロントエンドに**Vue.js**を選んだのは話題の３大JavaScriptフレームワークに触れてみたかったからです。
いままでバニラとNode.jsしかまともに触ってこなかったので。

バックエンドに**Laravel**を選んだのはログイン機能を実装するのが超簡単そうだったから。ただそれだけです。
一度バニラでやって心折れそうになったので選んでみました。
結果的にMVCモデルについて少し理解できたのでよかったです。

**Vuetify**は「なんて綺麗なUIなんだ！しかもcssほぼ書かんでいいやん！」ってなって選びました

データベースは**MySQL**にしました。
正直MySQLしか触ったことなくてデータベースの使い分けとか全然わかってないのでテキトーです。

#公開するまでの流れ
![upload](https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRWB1GjcQGibrXtW7g1OFJ6XlAw9cvVRXkyI-1rhpyoLeKyUTpX&usqp=CAU)
ローカル環境から本番環境で公開するまでの流れを説明します。

本番環境は月額払ってるのに特に何も動いてなかったVPSちゃんを選びました。
月額４００円くらいの格安VPSです。

公開までの流れ

- データをローカルからvpsにアップロード
- vpsでlaravelが動くように環境構築
- VPSにドメインを設定
- Cloudflareで高速化&SSL化

###データをローカルからVPSにアップロード
本番環境へのアップロードはBitbucketというgitリポジトリ管理サービスを経由して行いました。
Bitbucket: https://bitbucket.org/product/

###vpsでLaravelが動くように環境構築
ここで一番苦労した気がします
あまり覚えていませんがエラーがいっぱい出て大変だった気がします

###VPSにドメインを設定
Laravelの公開ディレクトリにアクセスするようにVPSで設定を行いました。

OSはUbuntuなので以下のページが参考になりました
https://www.server-world.info/query?os=Ubuntu_18.04&p=httpd&f=7

###Cloudflareで高速化&SSL化
大したwebアプリじゃないのでSSL化はさほど重要ではなかったのですが、
vpsが格安なせいか速度が微妙だったのでCloudflareをはさんでみました。

cloudflareはキャッシュをとってくれるのでVPSも負荷が減って喜んでいると思います。
無料で使えるのがスゴイ
https://www.cloudflare.com/

#今後の課題
完成はしましたが、いろいろ課題もあります。一部挙げてみました

- データベースについて理解を深める
- アップデートするときにFTPでやってるのをなんとかする

まずデータベースについて、MySQLを選びましたが選び方が全然よくわかってないので理解を深めないといけません
今のところいろんな記事読んでも理解できていませんTT

そして実は今、本番環境のファイルをアップデートするときにFTPソフトでドラッグ＆ドロップしてるという状態です
「gitでアップロードして動かなくなったらどうしよう」と思ってたらこうなりました；；

見直さないといけない部分もありますが、とりあえずポートフォリオに書けそうなものは作れたので良かった！:sunglasses:

以上になります
Spring基礎 〜DI編〜

### DIについて
#### DIとは
直接インスタンスを生成した APPがDIコンテナを経由してインスタンス取得できるようにすること。
DIを利用することでのメリットとして以下があげられる。

- スコープの制御
- インスタンスのライフサイクル制御
- 共通機能の組み込み
- 疎結合になることでのUTのしやすさ向上

DIコンテナに登録するComponentを「Bean」という。
Configurationのことを「Bean定義」という。

#### DIを利用した実装方法
##### Configuration方法
- JavaベースConfiguration

@Configurationでコンフィギュレーションクラスであることを宣言
@BeanでBean定義

```ruby:AppConfig.java
@Configuration
public class AppConfig {
    @Bean
    TestRepository testRepo() {
        retrun new TestRepositoryImpl();
    }
}
```
- xmlベース

<bean>要素でBeanの定義。id属性でbean名、Class属性がそのクラスのBeanのインスタンスとして定義

```ruby:.xml
<beans>
<bean id="test" class="com.test.TestImpl" />
</beands>
```
- アノテーションベース

Bean定義用のアノテーションが付与されたクラスをスキャンしてDIコンテナに登録する（コンポーネントスキャン）手法。
一番直感的に実装できる。

Bean定義側

```ruby:TestImpl.java
@Component
publi classTestImpl implements Test {
}
```

利用側
コンストラクタに@Autowiredを付与し、自動インジェクション。

```ruby:TestImpl.java
@Component
publi class TestUseImpl implements TestUse {
    @AutoWired
    public TestUseImpl(Test test) {
    }
}
```

#### インジェクションの種類
3種類方法があるが、コンストラクタインジェクションが良さそう。割愛。
コンスタラクタインジェクションはDIしたインスタンスがfinalになるからおすすめのよう。
https://irof.hateblo.jp/entry/2017/04/16/222737
- Setterインジェクション
- Constructorインジェクション
- fieldインジェクション

#### オートワイヤリングについて
オートワイヤリングは@Beanなどで明示的にBean定義しなくても自動でDIコンテナにインジェクションされる仕組みのこと。
内部的に型 or 名前 による解決を行っている。
ただし同一の型でDIコンテナに複数定義されているとDIコンテナはどちらを利用するかわらないためエラーとなってしまう。
そんな時に利用するのが@Qualifier、@Resouce

##### QualifierとResouce
以下のように同一のConvertクラスを返却するメソッドをBeanに登録するとする。

```ruby:AppConfig
@Configuration
@ComponentScan
public class AppConfig {
    @Bean
    Convert getA() {
        return new ConvertA();
    }
    @Bean
    Convert getB() {
        return new ConvertB();
    }
```

以下のようにインジェクションしようとすると`getA`、`getB`どちらをインジェクションするかpg側は判断できない。

```ruby:MainService
@Service
public class MainService {
    @Autowired
    private Convert getA;

    public String execute() {
        return getA.getConvert();
    }
```

以下のような記述でどちらをインジェクションするか明示的に指定することで切り分けることが可能。

```
@Qualifier("getA")
@Autowired
private Convert getA;
```

```
// @Resouceはプロパティ名でコンテナから対象のインスタンスを探しに行くため、
// nameと対象のプロパティ名が一致している場合は、省略することが可能
@Resouce(name = "getA") または、 @Resouce
@Autowired
private Convert getA;
```

※Resouceはコンストラクタインジェクションでの利用は不可。

```ruby:ダメな例
@Service
public class MainService {
    private final Convert getA;
    
    @Resouce(name = "getA")
    public MainService (Convert a) {
        getA = a;
    }

    public String execute() {
        return getA.getConvert();
    }
```
Cloud LoggingからBigQueryにプロジェクトをまたいでエクスポートするときにパーティション分割テーブルを使う方法

# TL;DR

[gcloud alpha logging sinks create](https://cloud.google.com/sdk/gcloud/reference/alpha/logging/sinks/create)コマンドの `--use-partition-tables` オプションを使えば良い。

# やりたいこと

Cloud Loggingのログルーターを用いて、ログ指標をBigQueryにエクスポートするシンクを作成したい。
かつ、エクスポート先のBigQueryはシンクを作成するプロジェクトとは別である。

参考ドキュメント:

- [ログビューアによるエクスポート | Cloud Logging | Google Cloud](https://cloud.google.com/logging/docs/export/configure_export_v2?hl=ja)

# GCPコンソールでは設定できない（2020-04-13現在）

シンクとエクスポート先のBigQueryが同一プロジェクトであれば、GCPコンソール操作でパーティション分割するか否かを選択できるが、別プロジェクトの場合はシンクのエクスポート先を入力する形となり、パーティション分割の有無を選択できない。
この場合、すべて日付別シャーディングテーブル（ `_YYYYMMDD` suffix付きのテーブル）となる。

# どうするか

冒頭の通り。

コマンド例:

```sh
gcloud alpha logging sinks create $SINK_NAME \
  bigquery.googleapis.com/projects/$EXPORT_PROJECT_ID/datasets/$DATASET \
  --project $SINK_PROJECT \
  --log-filter='<<SOME LOG FILTERS>>' \
  --use-partitioned-tables
```

# 補遺

LogSink.destinationの仕様から、GCPコンソール上で「エクスポート先」の指定だけでパーティション分割の有無を指定することはできないと考えられる。

https://cloud.google.com/logging/docs/reference/v2/rest/v2/billingAccounts.sinks#LogSink
VPCにのLambdaからS3に接続

# 問題
VPCにのLambdaからS3に接続できない
# 解決
S3アクセス用エンドポイントを作成する
Lambdaに設定しているサブネットに上記のエンドポイントを追加する
# 参考
https://tomokazu-kozuma.com/how-to-access-s3-from-lambda-in-vpc/
玉手箱のWebテストの言語理解テストの問題を読みやすくする

玉手箱のWebテストの言語理解テストの読みにくい見た目を読みやすく変える方法です。

Webテストを受験する必要がある未来ある皆様におかれましては、どこかの誰かが設計した不条理に技術で対抗してそれぞれの勝利を得ていただければと思います。

なお、以下の手順でスタイルを変更してテストを受験したことにより不正と見なされた場合など、一切の責任を負いませんのでご注意ください。

#Before & After
![Before](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/1a4ad19c-a134-6f89-b27c-2245ab89aa40.png)![Before](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/0c2d5931-601a-9014-1089-7a8f21b0c2da.png)
上の画像のように行間を広く取り大きな文字サイズを使用するように変更します。

#Google Chromeをインストールする
お使いのパソコンにGoogle Chromeがインストールされていない場合は[こちら](https://www.google.com/intl/ja_jp/chrome/)からインストールしてください。インストール方法は省きます。

#Chrome拡張機能 Stylusをインストールする
[こちら](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja)のURLにアクセスしてカスタムCSSをWebサイトに適用するためのChrome拡張機能であるStylusをインストールします。

右上の「**Chromeに追加**」という青いボタンをクリックしてあとは指示通りにインストールすればOKです。
![ChromeにStylusをインストール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/5d65e1fa-dc83-685a-54c0-348b87c5e3b0.png)

ブラウザのビルトインページではない適当なWebページ（今回は[Googleトップページ](https://www.google.com/)）を開いてStylusの設定をします。

![Stylus設定画面を開く](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/5a29d911-d896-6a1b-98a1-68426ba78668.png)

右上の「**S**」のアイコンをクリックしてメニューを開き、「**管理**」のボタンをクリックしてStylusの管理画面を開きます。この画面が開いたら、「**新スタイルを作成**」ボタンをクリックして新たなカスタムCSSを作成します。

![Stylus管理画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/b4f7bf00-f9b8-fb95-9feb-d0ccd6f6511a.png)

**スタイルを追加**画面が開いたら、以下のように左上の名前は適当に分かりやすいものを（今回は`tamatebako`としました）、右のコードエディタには以下のコードを入力します。

```css:コード1.css
#q_text {
    font-size: 16px; /* 文字サイズを16pxに（標準は14px） */
    line-height: 2.0; /* 行高さを2.0（文字の2倍の高さ）に */
}
```

必要に応じてスタイルを変更する場合はコメントを参考にしてください。

![Stylusスタイル作成画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/6710068d-91da-5bca-4ce4-fd548abcc494.png)

上の画面がここまで完了したものになります。

次に、玉手箱のテスト画面のみこのカスタムCSSが適用されるようにします。画面下の「**適用先**」の右にある「**+**」をクリックします。

![Stylus適用先設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322963/4b4826ad-9343-a2b8-0f27-7b3ea2c08199.png)

するとプルダウンメニューとURLの入力欄が出てきますので、プルダウンメニューは「**ドメイン上のURL**」を選択し、URLの入力欄には`e-exams.jp`を入力します。

ここまで完了したら、左上の「**保存**」ボタンをクリックすれば設定は完了です。この状態で玉手箱のWebテストを受験すれば読みやすいスタイルで表示されるようになっています。
IQ Bot：インスタンスのIDの確認方法

IQ Botに関して、DBを確認したりAPI投げたりするときに何かと使うインスタンスのIDの確認のしかたです。

#インスタンスのIDの確認方法

「学習インスタンス」のタブから該当のインスタンスを開くと、アドレスバーに以下のようなURLが表示されていると思います。

**http://（IQ Botをインストールしたサーバ）/IQBot/learning-instances/（英数字とハイフンが組み合わさった文字列）**

上記の、**（英数字とハイフンが組み合わさった文字列）**の部分がインスタンスのIDです。

![インスタンスのID_編集済み.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/11b806aa-dafc-fae0-fe7f-f4ff1dd50d01.jpeg)

#インスタンスのIDの使い道

インスタンスのIDは、IQ BotでDBの中身を確認したり、APIを投げたりするときに使います。
Ruby 2.7 でも 1行 in を利用して右代入を行う

[ブログ記事](http://secret-garden.hatenablog.com/entry/2020/04/13/103907)からの転載です。

さてさて、先日 Ruby の開発版に右代入を行う `=>` 演算子が追加されました。
これは `左辺値` を `右辺の変数` へ代入するための演算子になります。

```ruby
1 + 2 => result
result # => 3
```

* 参照：[Ruby の開発版に右代入演算子とエンドレスメソッド定義構文が入った](http://secret-garden.hatenablog.com/entry/2020/04/10/195207)


## Ruby 2.7 でパターンマッチ構文が実装された

Ruby 2.7 ではパターンマッチ構文が実験的に新しく追加されました。
この構文では次のように `in` 句で特定の値をキャプチャする事ができます。

```ruby
homu = { name: "homu", age: 14 }
case homu
in { name:, age: ..20 => age }
  p name   # => "homu"
  p age    # => 14
end
```

こんな感じで Hash の各要素に対してマッチするかどうかの判定とその値を任意の変数にキャプチャする事ができます。


## パターンマッチの 1行 in 構文

先程のパターンマッチでは `case ~ in ~ end` という構文だったのですが次のようにして 1行で `expr in pattern` を書くこともできます。

```ruby
homu = { name: "homu", age: 14 }

# expr in pattern と1行で書くことができる
# マッチしなかったら NoMatchingPatternError になる
homu in { name:, age: ..20 => age }
p name   # => "homu"
p age    # => 14
```

こんな感じで `in` が1つしかない場合は1行で簡潔に記述する事ができます。


## 1行 in で右代入を行う

さて、先程は `in` の右辺は `{ name:, age: ..20 => age }` のような複雑なパターンだったんですが、実は右辺には『変数だけ』を定義することができます

```ruby
homu = { name: "homu", age: 14 }

# in の右辺に左辺の値がそのまま代入される
homu in result
p result
# => {:name=>"homu", :age=>14}
```

つまり `in` を利用すると

```ruby
1 + 2 in result
p result # => 3
```

と記述する事ができます。
これって右代入ですよね？
もちろんメソッドチェーンされた値も代入できます。

```ruby
(1..10).to_a.shuffle.select { _1.even? }.map { _1 * 2 }.map { _1.to_s } in result
p result
# => ["20", "12", "16", "8", "4"]
```

完全に右代入ですね！！！


## 補足

このネタは [2月18日に行われた Ginza.rb](https://ginzarb.doorkeeper.jp/events/104145) の LT で発表しました。
気になる人は以下のスライドを読んでみるといいと思います。

* [1行 in の有効的な使いみち](https://osyo-manga.github.io/slide-ginzarb-80-oneline_in/#/)
Laravel(7.x)インストールから起動まで

### windows10のローカルにインストールします

##1. PHPインストール
まずはここから。こいつが入ってないとComposerインストールができません。
https://www.php.net/downloads

・**Windows downloads** を選択
・**VC15 x64 Thread Safe** を選択
(ご自身の環境に合わせて選択してください、最新のApache（XAMPP）を使うなら**Thread Safe**でいいのかな。※Apache（XAMPP）のインストールは必要ありません）

zipのダウンロードには少し時間がかかります。辛抱強くお待ちくださいませ。
展開先ですが無難に **C:\Program Files** を選択しました。

※他の資料を参考にphp.iniをカスタマイズすることをお勧めします。

これでOKです！次に進みましょう！


##2. Composerインストール

https://getcomposer.org/download/
上記から **Composer-Setup.exe** をクリックし、インストーラーを保存しましょう。
保存先からインストーラーを起動します。
途中でphpのディレクトリを聞かれるので、先ほど選択した場所にできた **C:\Program Files\php-7.4.4-Win32-vc15-x64** を参照します。

そのあとは特にチェックを入れずにNextで進んでいってFinishです！



##3. Laravelインストール

コマンドプロンプトを起動してください。
Composerを使ってLaravelをインストールしていきます。
`$ composer global require laravel/installer` を叩きます。
ここも少し時間がかかったかもしれません。Enterを押しても反応がなければしばらく待ちましょう。

`cd` を使ってプロジェクトを作成したいディレクトリに移動してください。
例：`$ cd C:\Users\自分のアカウント名\`
移動出来たら `$ laravel new 作りたいプロジェクトの名前`

####これであなたのLaravelプロジェクトができました！


##やったー！早速起動してみましょう！

`$ cd C:\Users\自分のアカウント名\作りたいプロジェクトの名前`
続いて `$ php artisan serve`
これで http://localhost:8000/ にアクセスすれば**見れ…ない！**

↓↓　以下を試してみましょう　↓↓

`$ composer update` ←ここでエラーが出たらphp.iniを見直してみましょう。

ローカルファイルから.env.exampleを選択して.envにファイル名を変更します。
`$ php artisan key:generate`
`$ php artisan config:clear`

もう1度 `$ php artisan serve` を試してみましょう！

![Screenshot_2020-04-13 Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618385/a5abef1e-a8ce-2953-c416-49d2ac334e24.png)

**この画面が出たら成功です！**
手軽に C# を学ぶ: C# によるプログラミングの入門ページの紹介

これから C# を始める方向けのサイトとして、マイクロソフトでは [C# によるプログラミングの入門](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/) を公開しています。

[公式: C# によるプログラミングの入門](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/)

# 特徴

このページの最大の特徴は、ブラウザのみでコードを実際に試せることです。IDE やランタイムのインストールは必要ありません。当然ローカルに環境がある場合の手順もあります。

またカテゴリごとに学べることが整理されているため、始めやすいです。

- [Hello World](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/hello-world)
- [C# の数値](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/numbers-in-csharp)
- [分岐とループ](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/branches-and-loops)
- [リストコレクション](https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/intro-to-csharp/list-collection)

等、入門者向けの内容をはじめ、数多くのチュートリアルが揃っています。

# フォーカスモード

各カテゴリで学ぶ際、ページ右上にある「フォーカスモードの開始」をクリックすることにより、ブラウザで C# を実行する環境を使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/01484f5c-b63a-504c-a94f-d0e6d194cfb8.png)

チュートリアルに従って「エディター」にコードを入力し、「実行」すると、「出力」に結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/348091ac-8491-bd1e-f788-07a38de73626.png)

ブラウザ 1 つで C# を始めることができるため、是非トライしてください。

# 自由にコードを書いて実行したい

チュートリアルとは別に自由にコードを書いて実行したい場合は、Try .NET が使えます。このサイトもコードを記述して実行すれば結果を表示してくれます。

[Try .NET](https://try.dot.net/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/deeb69b9-cb58-75a8-27ce-ec1481ea1d09.png)

是非試してみてください。
スティッキーズを移行する for Catalina

# 概要
- macOS Catalinaに以前のOSバージョンで使用していたスティキーズを移行する方法
    - 現行のmacOS Catalinaから `StickiesDatabase` が存在しなくなった

# 事前準備
- 移行元のmacからスティキーズのバックアップを取得する
- ターミナルを用いて下記コマンドを実行
    - デスクトップに保存

```shell
cd ~/Library
cp StickiesDatabase ~/Desktop
```
# 移行方法
- スティキーズアプリを終了しておく
- 事前準備にてバックアップした `StickiesDatabase` を移行するPCのデスクトップに移行しておく
- ターミナルから下記コマンドを実施
  - ※ 移行するPCで既にスティキーズを使用している場合（付箋データがある場合）は予めノートアプリなどに書き出しを行っておくこと

```shell
rm -rf ~/Library/Containers/com.apple.Stickies*
mv ~/Desktop/StickiesDatabase ~/Library/
```

- スティキーズアプリを開く
- 移行完了
VSCode Live Share でリモートワークしちゃおう

# 明日からリモートワークね
私の周りで急にこういわれる人を多く見ています。
私もリモートワークになったのですが、VSCodeのLiveShareという拡張機能がめちゃすごいのでお勧めしたいです。
環境とかセキュリティとかで全部の人が使えるとは限りませんが、少しでもお力になれればいいなとおもいます。

# こんな人なら使えると思うよ！
- エディターでコード編集してるよ
- ターミナルで実行とかコンパイルとかするよ
- 仮想環境立ててその中のファイルをターミナルからいじってるよ
- localhost立てて開発してるよ

# 環境
|ホストOS|Windows10|
|:--:|:--:|
|ゲストOS|Windows10|

# 環境作成
### ホスト・ゲストどっちでも必用な作業
1. [公式](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)からVSCodeをダウンロード
2. 拡張機能からLiveShareを検索してインストール
3. window下部のLiveShareをクリックしてMSアカウントかGitHubアカウントでログインする
4. ブラウザが開き認証を求められるので許可する。
5. VSCodeを開く

以上で準備は完了です。
続いてホスト側の準備をしましょう。
以降は出勤毎に行うかもしれないです。

### ホスト側の作業
1. VSCodeを開く
2. いつも利用しているフォルダやファイル、ワークスペースを開く
3. window左側にあるLiveShareを開く
4. `SESSION DETAILS`にある`Start collaboration session`をクリックする
5. 少し時間がたつとセッションが開始する。
(下二つは必要な人は実行してください。)
6. シェアしたいサーバーがある場合は`Shared Servers`をクリックしてサーバーのURLを記述してください。
7. ターミナルを操作したい場合は`Shared Terminals`をクリックしてターミナルを追加し、`Read/Write`を選択してください。
8. `SESSION DETAILS`の右あたりから、セッションURLをコピーし、ゲスト側に共有します。

ホスト側の設定は以上です。

### ゲスト側での作業
1. 共有したURLをひらく
2. ポップアップが出るので、`VSCodeを開く`を選択する
3. VSCodeが起動して少しすると共有が開始する

こんな感じです。

### 操作してみる
共有したいサーバーを追加した場合、設定したサーバー名をクリックすることで共有することができます。
共有したいターミナルも同様です。
また、ターミナルが操作できるので、仮想環境の立ち上げなどもリモートで行うことができます。
GITのPushなどはホスト側からしか行えないようです。

# まとめ
とりあえず簡単にまとめておきます。
少しでもお役に立てたならうれしいです。
自宅でもできるだけストレスなく開発できるといいですね！
Spring Securityのログイン画面

SpringBootでプロジェクトを新規作成した際にハマったので、自分用にメモ。

## 現象
実装した画面を表示したく、http:localhost:8080にアクセスすると、こんな画面が表示される

<img width="961" alt="スクリーンショット 2020-04-13 16.29.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284986/5402318e-910c-01aa-a9b9-7f5afefaef1a.png">

sign in！？
どこに？？？

## 原因
Spring Secutiryが原因だったらしい。
これまでのプロジェクトでは、作成時ではなく途中から実装していたために出てこなかったのかと。
(今回は最初から実装していました)

pom.xmlに以下の記載があると、デフォルトでこの画面が表示されるらしい。

``` pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
```

## 対処法
ログイン方法は下記の内容を入力する。

Username : user
Password : (コンソールに出力されたもの)

SpringBoot起動時のコンソールを確認

```
・・・

2020-04-13 16:14:02.384  INFO 96249 --- [  restartedMain] .s.s.UserDetailsServiceAutoConfiguration : 

Using generated security password: 268aae2f-c8f4-4e79-bcb3-1c61ee01a3fb

2020-04-13 16:14:02.391  INFO 96249 --- [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     :

・・・
```

ログインが成功すると、実装したページが表示される
Cloud Functionsでfirestoreのサブコレクションまで再帰的に削除する実装と困ったこと

# 実装の流れ

1. index.tsにコードを書く
2. firebase login:ciでトークンを取得
3. firebases:configにトークンをセットする
4. firebase deploy --only functionsでデプロイする

## index.tsに処理を実装（TypeScript）

functions/src/index.ts

```typescript
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
const firebase_tools = require("firebase-tools");
const firebase = admin.initializeApp();
const tokyoRegion = "asia-northeast1";

// グループの削除をトリガーに紐づくアイテムのサブコレクションを削除する
export const deleteSubCollections = functions
        .region(tokyoRegion)
        .firestore.document('groups/{groupsDocId}')
        .onDelete(async (snap, context) => {
          try {
            await firebase_tools.firestore
              .delete(snap.ref.path, {
                project: process.env.GCLOUD_PROJECT,
                recursive: true,
                yes: true,
                token: functions.config().fb.token
              })
          } catch (err) {
            console.error(err)
          }
        })
```

## ログイン認証

```
# ログイン認証してトークンを取得
$ firebase login:ci

####### なんかごちゃごちゃ出てくる URLに飛んでfirebaseの認証する

Waiting for authentication...
✔  Success! Use this token to login on a CI server:
####### ここらへんにトークンが表示されるのでコピーする
Example: firebase deploy --token "$FIREBASE_TOKEN"
```

## トークンの設定

```

# コピーしたトークンをfirebase:configに設定
$ firebase functions:config:set fb.token="{コピーしたトークン}"

✔  Functions config updated.

Please deploy your functions for the change to take effect by running firebase deploy --only functions
```

## デプロイ

```
$ firebase deploy --only functions

#### メソッドを指定してデプロイもできる！
#### 特に理由がなければメソッド指定すると早く終わっていい）
$ firebase deploy --only functions:deleteSubCollections
```

## 参考記事
[コレクションとサブコレクションを削除する](https://firebase.google.com/docs/firestore/solutions/delete-collections?hl=ja)
[CloudFunctionsを使ってFirestoreのサブコレクションを削除する](https://blog-hello-world.web.app/posts/2019-07-12-cloudfunctions-firestore/)
[Cloud Functionでサブコレクションまで再帰的に削除する(firebase-tools)](https://www.memory-lovers.blog/entry/2020/01/25/160000)

# 困った所
さて、ここからがこの記事の存在意義です。
私が実装していて困った事と一応の解決策を載せておきます。

詳細な理由やもっといいやり方などございましたらコメントにてご指摘いただけると幸いです。

## firebase-toolsはfunctions以下にインストールするの？？

`$ npm install firebase-tools`しましょう

私が作っているプロジェクトでは既にapp以下に
firebase-toolsが入っているので必要無いのでは？と最初思いました。

しかしcloud functionsは異なるリージョンにデプロイできるなど独立した感が強いので
app以下のものとは別でインストールが必要です。

lintでもfirebase-toolsが見つからないと怒られました。

## importでfirebase-toolsを呼び出せない？

#### 問題

>モジュール 'firebase-tools' の宣言ファイルが見つかりませんでした。

```ts

import firebase_tools from "firebase-tools";
```

このように記述すると何故かlintに怒られてしまいました。
ちゃんとnode_modules/firebase-toolsはあるんですけど…

#### 解決策

結局、下記のようにrequire()でゴリ押ししました。

```ts

const firebase_tools = require("firebase-tools");
```

色々と腑に落ちない事がありましたが実際に動かして正しく動作してくれたので今回はこれで終了とします。

もっとfirebaseやnodeやwebpackへの理解があればよかったんですが…
時間が無い時は深堀りできないのが苦しい。
特定のサブドメイン宛てMySQLへの接続をnginxのリバースプロキシで別のところへ渡す

# 何をしたい？　どんな条件？
* 特定のサブドメインを nginx で受けるサーバがある ( 80/443 等 で)
* このサーバには MySQL をインストールしたくない／できない
* 上記の特定サブドメインを MySQL の接続先指定として使いたい

## つぶやき
まあ、ニッチなニーズですよね、分かります。
今回、私がどうしてこういうことをしなくてはならなくなったかということについての深い理由は黙して秘します。


# こうすればよい
``` nginx.conf
stream {
  upstream db {
    server fugafugaexample.com:3306;
  }

  server {
    listen hogehogeexample.com:3306;
    proxy_pass db;
  }
}
```

* nginx.conf の http ディレクティブが終わった後のところへ記述
* MySQL の port 3306 を変更していたら、それに応じて変更してください
* nginx.conf に直接記述でなく conf ファイル切り離してももちろん大丈夫です
* proxy_pass の名前と upstream の名前は、任意ですが同一に指定してください
centos7 nginx phpmyadmin インストール

毎回ハマる。

php 7.4 を インストールしているので。



```

yum -y install --enablerepo=remi,remi-php74 phpMyAdmin

```

これで 111.222.33.44 でアクセスできる。


```/etc/nginx/conf.d/default.conf

server {
       listen 80;
       server_name localhost;


       location / {
                root /usr/share/phpMyAdmin;
                index index.php;
                }

        location ~ \.php$ {
                fastcgi_pass unix:/var/run/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /usr/share/phpMyAdmin/$fastcgi_script_name;
                include fastcgi_params;
        }
}


```


phpmyadmin の ログインは

root
パスワードは mariadb で設定したものでログイン可能。

#うまく動かない場合は？

```

tail -f /var/log/nginx/error.log

```


でログを見ると良い

```

phpinfo();でセッションがどこに保存されているかチェク

chown -R nginx:nginx /var/opt/remi/php74/lib/php/session

chown -R nginx /etc/phpMyAdmin
chown -R nginx /var/lib/phpMyAdmin/temp

```

ちなみに、
以下のようにしてアクセス制限をかけることも可能。

```

server {
       listen 80;
       server_name localhost;


       allow 222.223.334.19;//これ
       deny all;

       location / {
                root /usr/share/phpMyAdmin;
                index index.php;
                }

        location ~ \.php$ {
                fastcgi_pass unix:/var/run/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /usr/share/phpMyAdmin/$fastcgi_script_name;
                include fastcgi_params;
        }
}


```
Reactで<input type="datetime-local">のvalueをセットするにはひと工夫必要

ブラウザ実装のデフォルトのdatetime pickerを使いたいなと思ったら、想像以上に情報なくて困ったのでメモ。

## 実装

あまり装飾せずに、あえて最小構成でコンポーネントを作る。

```tsx
import moment from 'moment';

const DatetimeComponent = () => {
  const toDatetime = (date: Date) => {
    return moment(date)
      .toISOString(true)
      .substr(0, 16);
  };
  return <input type="datetime-local" defaultValue={toDatetime(new Date())}>
}
```

## 一言
toISOStringとかで普通にセットできるようにして欲しい（Reactが悪いわけではなく、HTML仕様がよくない気がしている）

## 参考
https://codepen.io/guidobouman/pen/gwAQGg
iPadOSシミュレータに忍ぶ罠 ～あのMBPが危ない！～

Xcode11.4 よりiPadOS Simulatorに「Capture Cursor」と「Capture Keyboard」という機能が搭載されました。

これは便利ですねー。

**ただし**、物理ESCキーが付いていない**特定のMBP**をご利用の方はご注意ください。
初期設定のままキャプチャーモードに入ってしまうと、**二度と抜け出すことが出来なくなります**。
私は仕方なく**強制再起動**しました。
（外部キーボードがあればなんとかなったかもしれません）

環境設定から変更できますのでまず初めに変更しましょう。
初期設定はescになっています。

![EU1NURxU0AApHUh.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2117/2d76bed7-7455-90f2-c480-24943e724cec.jpeg)
Webを使った新人研修　～Javaを用いた基本的プログラミング編・クラス～

######[Webを使った新人研修　～Javaを用いた基本的プログラミング編～](https://qiita.com/fujisystem/items/4237ca88b224ae5875dd)

#クラス
[クラス](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%B9_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))とは設計図であり、この設計図に基づいて[インスタンス](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9)を生成します。

折角なので、オブジェクト指向の説明も兼ねて説明しましょう。
[オブジェクト指向](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91)

細かい説明をしていては果てしないので、「習うより慣れろ」の精神で
まずは、「実践」してみましょう。

##実践する

[Ideone](https://ideone.com/l/java)をブラウザで開いてみましょう。
自動的に以下の表示になり、デフォルトでIdeone用のクラス定義が記載されているはずです。

![java01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110729/47496dc3-ae36-776d-fe70-a13c48efe7c8.png)

```java:クラス
class Ideone{
〜
}
```
の部分が「クラス」に相当します。Ideoneという名前のクラスを宣言しています。
差し当たり、以下のような感じにクラス部分を入力して
右下の緑色ボタン「Run」を押してみましょう。

```java:
class Ideone
{
  public static void main (String[] args) throws java.lang.Exception
  {
    Ideone.Person tarou = (new Ideone()).new Person("Tarou");
    tarou.walk(12);
    Ideone.Person hanako = (new Ideone()).new Person("Hanako");
    hanako.walk(3);
  }

  class Person
  {
    private String name;
    Person(String name){
      this.name = name;
    }
    public void walk(int dist){
      System.out.println(this.name + " walked for about " + dist + " kilometers.");
    }
  }

}
```

[これ](https://ideone.com/uqABgP#stdin)をforkしてみても良いです。

##解説


例題を示して記憶の定着を図ってみます。

##例題
１．〜

```java
```

<br>

～本日はここまで
QRコードを生成するコマンド

## インストール

```sh
# CentOS 6 で確認 (CentOS 5には無い)
yum install -y qrencode
```

```sh
# Ubuntu 20.04 で確認
apt install -y qrencode
```

## 使い方

```sh:画像にする場合
qrencode -o a.png "http://qiita.com"
```

```sh:端末に出力する場合
qrencode -t ansi "http://qiita.com"
```

### php で実行して結果を表示

```php:qr.php
<?php
function echo_qrcode($str) {
        $command = sprintf('/usr/bin/qrencode "%s" -o -', $str);
        $qrcode = `$command`;
        header("Content-type: image/png");
        echo $qrcode;
}
echo_qrcode("https://www.google.com/search?client=ubuntu&hs=M8b&channel=fs");
```
IQ Bot：誤り検知の条件設定

[IQ Bot](https://qiita.com/IQ_Bocchi/items/26c4a7065e4c8e64a427)では、読み取った値が正当かどうかを検証するルールを項目別に柔軟に設定することができます。

この記事では、IQ Botの誤り検知についてまとめます。

#IQ Botの誤り検知とは？

IQ Botの利用フローは以下のとおりです。
![IQ Bot 利用フロー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/92891170-009b-7713-d659-f16efa929724.png)

右半分の⑤～⑧が実運用のフローですが、⑤でIQ Botを起動したあとで、矢印が二つに分かれていますね。
⑧のCSV出力に直接のびている矢印と、⑥の人間の検証に回る矢印です。

**「直接CSVを出力していいか、人間の検証が必要か」を切り分ける条件は、左側③のマッピングの学習の際に設定することができます。**

#誤り検知の設定方法

誤りを検知する条件は、マッピング設定画面の以下の３か所で指定することができます。
![誤り検知.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/cb0b366f-d33f-920a-a1b9-54a0c2b5b6c6.jpeg)

##誤り検知の設定①：型による誤り検知

date(日付)、number（数値）などの型を指定しておくと、その型にあてはまらない値が入ってきた場合に誤りとして検知し、人間の検証に回してくれます。
日付や金額など、入ってくる項目の型が決まっている場合に有効です。

型はほぼほぼ見たままですが、ちょっと意外な機能として以下を挙げておきます。

- number型を指定した場合、通貨の単位（$,€,￡,円マーク）は自動で除外される（日本語の「円」は除外されない）
- number型を指定した場合、桁区切りのカンマ等は自動で除外される
- [date型は和暦にも対応している](https://qiita.com/IQ_Bocchi/items/1d9ed784fbf35361ffb7)

さらに詳細を以下の記事にまとめましたのでご覧ください。

https://qiita.com/IQ_Bocchi/items/e9f88b20234dcd4e567f

##誤り検知の設定②：必須指定による誤り検知

必須／任意を指定し、必須指定した項目に値が入っていない場合に誤りとして検知し、人間の検証に回してくれます。

##誤り検知の設定③：パターン指定による誤り検知

パターンを定義し、そのパターンから外れている値が入ってきた場合に誤りとして検知し、人間の検証に回してくれます。

電話番号や郵便番号、製品の型番など、形式（桁数など）が決まっているデータに対して、その形式を正規表現で指定できるだけでなく、帳票上に出現する数字項目の同士の検算（数量×単価が合計金額と一致しているか／税抜価格と消費税の合計が税込み価格と一致しているか　など）もできるのが特徴です。

パターンの定義のしかたはベンダーの公式ドキュメントサイトの以下のページに詳しく載っていますが……
https://docs.automationanywhere.com/bundle/iq-bot-v6.5/page/iq-bot/topics/iq-bot/user/bot-training-validation.html

日本語で、よりわかりやすい説明をお求めの方には以下の記事がおすすめです。

https://qiita.com/IQ_Bocchi/items/6dceab07e4017a2e3a19

#誤りが検知されるとどうなる？

誤りが検知された帳票は、以下のようにValidation（検証）の画面に回り、誤りとして検知された項目が赤枠で表示されます。

![誤り検知_convertio.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/18456572-a48e-a9a3-af9f-8e8293d01f48.gif)

赤枠以外の項目も修正が可能です。

修正が完了したら「保存」を押すと、そのタイミングで修正結果を反映したCSVが出力されます。

このとき、IQ Botが修正前後の値を蓄積して機械学習します。
同じような誤りを何度も繰り返して修正していくと、そのうちIQ Botが自動修正してくれるようになるという仕組みです。

#誤り検知の注意点

##数式を使った検知で、数式の文法を間違えると……

数式を使った検知で数式の文法を間違えると、その誤った数式を設定した項目が必ずエラー（＝検知対象）になります。

「あれ？　計算結果合ってるのになんで赤くなるの？」という場合は、数式の文法に間違いがないか確認しましょう。

##機械学習の仕組みは、日本語に対しては無効（2020.4.13現在）

最後に紹介した機械学習の仕組みは、修正後の値が英数字や記号（すべて半角）の組み合わせの場合のみ有効ということで、日本語の項目に対してはまだ使えないようです。

そんなわけで、商品名などの日本語を含む項目は、型番などの英数字記号の組み合わせの項目で代替できるのであれば、後者で取得したほうがIQ Botの強みを活かせるのかなという感じです。

請求書で請求元の社名などを取得したい場合も、IQ Bot側では電話番号の取得にとどめておき、RPA側でDBと突合して社名を取得……というフローにする方が現実的です。

##Validation画面では、正当な条件を満たすまで保存ができない

これは記載のとおりなんですが、たとえばnumber型の項目に対して、formulaで「消費税額 == 小計 * 0.1」（消費税が小計の10%であること）という検証の条件を組んでいたとします。

でも、消費税は軽減税率で品目によっては８％になるケースがありますよね。

そういう場合でも、誤り検知の条件に「消費税額 == 小計 * 0.1」という条件を組んでしまうと、この式がtrueにならない限りValidationの結果を保存することができません（「無効としてマーク」はできるが、その場合はCSVが出力されない）。

つまりこの場合、帳票には８％の税率の消費税が書いてあって、それが正しい結果なのに、１０％の消費税で入力しないとエラーになってしまう、というような変なことになってしまいます。

この点を踏まえ、誤り検知の条件は適切に設定しましょう。

#まとめ

- IQ Botでは、①型／②必須指定／③パターン　の三つの条件で誤りを検知できるよ
- 誤り検知して人間が修正すると、IQ Botが機械学習してくれるよ
- ただし上記の機械学習は日本語の項目に対しては使えないよ（2020.4.13現在）
- 誤りを検知してValidationに回ると、設定した条件がすべてtrueになるまで保存できないよ
[UnrealEngine4] DualShock4のボタン配置とインプット設定の対応

#はじめに
ざっと検索した感じだと、まとめているサイトが無かったので自分で検証した結果を載せておこうと思います。
ちなみにUnrealEditor上で試すためにはDS4Windowsなどのソフトを使わないと反応してくれないみたいですね。
コントローラー対応ゲームのデバッグがしやすくなるので、まだ入れていない人は入れるのおすすめです。
ちなみにDS4Windowsの方でキーバインディングを変えることもできますが、これはプロファイル名をDefaultに設定した上での検証です。
[DS4Windows開発者Github](https://github.com/Ryochan7/DS4Windows)

#検証環境
UnrealEngine4.24.1
DualShock4
DS4Windows 2.0.15

#ボタンとの対応(アクションマッピング)
○ボタン　→　ゲームパッドBボタン
×ボタン　→　ゲームパッドAボタン
△ボタン　→　ゲームパッドYボタン
□ボタン　→　ゲームパッドXボタン

R1ボタン　→　ゲームパッド右ショルダー
R2ボタン　→　ゲームパッド右トリガー
R3ボタン　→　ゲームパッド右サムスティックボタン
L1ボタン　→　ゲームパッド左ショルダー
L2ボタン　→　ゲームパッド左トリガー
L3ボタン　→　ゲームパッド左サムスティックボタン

Shareボタン　→　ゲームパッド特別仕様の左
Optionsボタン　→　ゲームパッド特別仕様の右

十字キー上　→　ゲームパッド方向キー上
十字キー下　→　ゲームパッド方向キー下
十字キー左　→　ゲームパッド方向キー左
十字キー右　→　ゲームパッド方向キー右

#スティックなどとの対応(軸マッピング)
これらは倒し具合に合わせて-1.0~1.0の値を返してくれます。

左スティック上下　→　ゲームパッド左サムスティックY軸
左スティック左右　→　ゲームパッド左サムスティックX軸
右スティック上下　→　ゲームパッド右サムスティックY軸
右スティック左右　→　ゲームパッド右サムスティックX軸

これだけが特殊で、押し込み具合に応じて0.0~1.0の値を返してくれるみたいです。
押さない状態で0、完全に押し込むと1.0でした。
R2ボタンの押し込み具合　→　ゲームパッド右トリガー軸
L2ボタンの押し込み具合　→　ゲームパッド左トリガー軸

#まとめ
あくまでXBoxコントローラーと対応させてるだけなので、あまりにも名称からかけ離れた名前はついていなかったですね。
これからUE4に触る、未来の誰かの助けになれば幸いです。
ちなみにPS4タッチパッドボタンX軸/Y軸なるものがあるのですが、DS4Windowsでは対応させられないので、これはビルドしてからじゃないとデバッグできないみたいですかね...
間違い等あればご指摘お待ちしております。
[新5分で分かる]S3について

#はじめに
Amazon S3(以下S3)とは？
・Amazon Simple Storage Serviceの略です。
・容量が無制限なAWSのストレージサービスです。
（ただし一つのファイルにつき５TBまで）
本記事では**S3の強み**、**料金体制**、**近年の変化**などを紹介していきます。
#S3の強みとは？
###１、耐久性
S３は**99.999999999%の耐久性能を持っています。**

- 全てのデータを３つのAZ（アベイラビリティーゾーン）で保管する
- 別々の変電所からAZに電力供給する
- 他のAZやネットへ接続するには複数のファイバーケーブルを使用する

**これらにより１つのAZが完全に損失しても耐久可能な性能を持ちます！**
###２、セキュリティ
- 異なる３種の暗号形式で保護
- AWS Clowd Trailなど監査に対応したツールがある
- AWS Macieにより機密データを自動検出し保護できる
- 複数のセキュリティ基準、コンプライアンス認証がサポートされている
- S3　Block Public Accessにより全てのパブリックアクセスをプロックできる

**S3は自社のデータセンターより運用上の安全性が高いと考える企業があるほど
堅牢なセキュリティを誇ります。**

###３、管理能力
- AWS Lambdaにより専用のコンピューターリソースなしでワークフローの開発ができる
- 柔軟性に優れた管理機能、分類機能が使用できる

**S3は手元のデータへの適切な判断やコストの自動的削減に役立ちます。**

###４、インプレースのクエリ機能
S3は外部の分析プラットフォームに移動させる必要なく、**S3のオブジェクト全体で高度なビッグデータ分析を実行できます。**
また自動でスケーリングが実行されるので、**データ量が増えてもパフォーマンスは変わりません。**
###５、パートナーネットワーク
Amazon S3のエコシステムには数万社を超えるパートナー企業が登録しており、
**AWS Marketplaceから多様なAWS 統合ソリューションを使用できます。**
#料金体制について
###１、S3の課金対象
- S3に保存されるデータ容量
- リクエストとデータ取り出し​
- データ転送量​

###２、ストレージタイプ
上記の料金は使用するストレージタイプにより変動します。
以下ではそれらの特徴について簡単に説明します。

- S3 標準
→アクセス頻度の高いデータ向け

- S3 標準-低頻度アクセス​
→長期保存、バックアップ等の保存向け

- S3 1 ゾーン-低頻度アクセス​
→バックアップ等の保存向け、1つのAZにデータを保存するためコストを削減できる

- S3 Glacier
→アーカイブのように使用でき、データの取り出し時間がかかる分、保存コストが安い

- S3 Intelligent-Tiering​
→アクセスパターンによって保存するストレージを移動させ、コストを最小限に抑える。長期間使用するデータの保存向け



#近年の変化
###１、リクエストレートのパフォーマンス向上（2018年）
２０１８年7月より、**追加料金なしで処理時間を大幅に節約できるようになりました。**
　→従来は800リクエスト/秒を超えるGETリクエストが5,500リクエスト/秒と大幅に引き上げ、
PUT/LIST/DELETEリクエストのしきい値も300リクエスト/秒だったところ3,500リクエスト/秒と変わりました。
###２、SigV2の廃止（2020年）
2020年6月24日以降に作成された新しいバケットに対して、初期の署名モデルであったSigV2署名付きリクエストはサポートされなくなりました。
（SigV4をS3で利用しているか判定するには、CloudTrailを使用する必要があります。）
#おわりに
AWSサービスは日々劇的に進歩しています。
以下に公式ページのS3解説が掲載されています。
https://aws.amazon.com/jp/s3/
ぜひアクセスしてみてください！
enebularでアンケート

#概要

enebularで、アンケートやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/68f28f15-b3c2-e19a-eebc-a2643dd2042c.png)



#flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d58db0ed-6590-afd1-bf0e-d869f05cdd3e.png)

#サンプルコード


```

google.charts.load('current', {
  packages: ['corechart']
});

function drawChart(b) {
  const data = google.visualization.arrayToDataTable(b);
  const options = {
    title: '割合', 
    is3D: true
  };
  const chart = new google.visualization.PieChart(document.querySelector('#chart'));
  chart.draw(data, options);
}

function put(a) {
  var json = {
    "text": a
  };
  $.ajax({
    type: 'POST',
    url: 'https://ev2-prod-node-red-a4d0ce4a-7ff.herokuapp.com/in',
    dataType: 'json',
    data: json,
    success: function(data) {
      let d1 = 0;
      let d2 = 0;
      for (let i = 0; i < data.length; i++)
      {
        if (data[i].yes == "1") d1++;
        if (data[i].yes == "2") d2++;
      }
      const d = [["接触", "割合"], ["できた", d1], ["できない", d2]];
      drawChart(d);
    },
    error: function(res) {
      alert("err0");
    }
  });
}

function run() {
  if ($('input[name=radio]:checked').val() === '1')
  {
    put("1");
  }
  if ($('input[name=radio]:checked').val() === '2')
  {
    put("2");
  }
}




```

#成果物

https://embed.plnkr.co/plunk/dGSG9zIe7aXoR6Pj

以上。
VoidCallBackで引数あり関数を呼ぶ

## はじめに
- Flutterでボタンが押された際に呼ぶメソッドが引数ありの場合呼べなかったので解決策メモします

## なかみ

引数無しの場合であれば下記のように書くだけでいい

```main.dart
...

void start(){
    ...
}

...

RaisedButton(
  onPressed: start,
  child: Text("Start", style: TextStyle(fontSize: 14)),
))
```

引数ありの場合

```main.dart
...

void start(String title){
    ...
}

...

RaisedButton(
  onPressed: () => start("next page"),
  child: Text("Start", style: TextStyle(fontSize: 14)),
))
```
[C#] 命名ルールのあれやこれや

自分メモ用、随時追加更新用


# テーブル名

テーブル名は基本は複数形、そのテーブルの中にアイテムが複数ある

|name| OK/NG |
|:--|:--:|
|Order|:thumbsup_tone2:|
|Orders|:thumbsdown_tone2:|

# モデル名

基本は `Model`で終わる。Modelは単一系で複数形ではない。

|name| OK/NG |
|:--|:--:|
|OrderModel|:thumbsup_tone2:|
|OrderModels|:thumbsdown_tone2:|

# 変数

ローカル変数は Camel型式

# Interface

Interfaceは `I`で始める。

例: `IOrderHandlers`
What is CCWDM(Compact Coarse Wavelength Division Multiplexing)?

CCWDM is Compact CWDM (Compact Coarse Wavelength Division Multiplexing), which is a wavelength division multiplexing technology based on TFF (Thin Film Filter). It works in the same way as CWDM modules, except that CCWDM uses free space technology (As shown in Figure 1), compared with the common CWDM fiber cascading method (as shown in Figure 2). The package size of CCWDM is smaller than CWDM and with lower insertion loss and better consistency. CCWDM can be used to replace the CWDM products in telecommunications, corporate networks, PON networks, cable TV and other fields. The lower insertion loss makes the CCWDM module have lower signal attenuation when used, thereby reducing the power requirements of the signal transmitter.
![CCWDM4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/d27f19f7-8ff5-52e8-747f-8ada337eaacf.jpeg)

HYC's CCWDM module uses free space technology to transmit optical signals by using an independent sealed space. The working mode is the same as CWDM, first input(output) signal from the COM terminal, and then output (input) optical signal through TFF (film filter) for other port transmission. CCWDM module can save more space by using parallel optical path cascading of free space technology different from CWDM optical fiber cascading method. HYC’s CCWDM module has mature production technology and stable and reliable performance. It supports an ambient temperature of -40 ~ + 85 ° C to ensure stable transmission of signals.
![CCWDM3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/77342243-5e61-76b6-0fe6-8e61306a911d.jpeg)

About HYC Co., Ltd
Founded in 2000, HYC CO., LTD (HYC) is the world’s leading passive optical devices OEM/ODM manufacturer who engages in R&D, producing, marketing and providing service of fiber optical products.

Our main products are: Optical Fiber Connector, WDM, PLC splitter, MEMS optical switch and other optical passive basics devices. HYC products and solutions are widely used in 4G/5G, Telecom, Data Center,  Cloud Computing industry and other fields.
www.hyc-system.com
Vueのindex.htmlを編集してfaviconを設置しようとして、コメントアウトされてしまった時の対処法

Vueでファビコンを設置しようとして、なんか上手くファビコンが表示されないなーと思ったら、衝撃の事実が発覚しました。。
その時の対処法の記事です。

# どういう状況か？

Vue + Typescriptのプロジェクトで、ファビコンを設置したい
↓
`public/index.html`を編集する(`head`タグ内に以下を追加する)

```html
<link rel="icon" type="image/x-icon" href="<%= BASE_URL %>favicon.ico">
```
↓
ビルド
↓
ファビコンが表示されない
↓
デベロッパーツールで見てみると、以下のようになっている・・・！？

```html
<!--[if IE]><link rel="icon" href="favicon.png"><![endif]-->
```

# 解決法

`vue.config.js`に以下を設定すればOK！

```javascript
module.exports = {
  pwa: {
    iconPaths: {
      favicon32: 'favicon.ico',
    }
  }
};

```
なお、ファビコン自体は、`public/favicon.ico`に配置しました。

# まとめ

なぜファビコンの`link`タグだけ条件付きコメントになったのか、とても興味深いです。

# 参考

- https://stackoverflow.com/questions/52684709/vue-index-html-favicon-issue
AI構築概論

本当にざっくりした説明です

## 機械学習とは

- 短時間の学習で、大量のデータから正確な結果を導く
- データから反復的に学習し、そこに潜むパターンを探し出す
  
参考：
[Pythonで動かして学ぶ！あたらしい機械学習の教科書](https://www.amazon.co.jp/dp/B07GW9RMLL)

## AIの3大手法

現在のAIの主な手法は

- 教師あり学習：人が正解(正解ラベル)を示す
- 教師なし学習：人が正解を示さない　AIが自動で分類する
- 強化学習：教師なし学習に近いが、AIに経験を積ませより良い解を導き出させる　例：[ロボットアームの最適化](https://www.youtube.com/watch?v=ATXJ5dzOcDw)

である

現在注目されている「ディープラーニング」は、3つの手法全てに適用できる「手段」である

### ディープラーニング

- 神経を模したニューラルネットワークを構築する  

  人体で
![CNN0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/24e3f1dc-0904-842f-0035-555e8c97f273.png)
  と個々の筋肉や刺激量を意識しないのと同様に
![CNN1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/f8e45e8d-2c85-12c2-b540-e913f624428e.png)

  と、入力から推論した出力となるネットワークを構築する

- 学習時に、特徴を細かに指定しなくてよい ⇔ 学習用データの量を確保するとともに、データの質を精査しておく必要がある

[ニューラルネットワークとは](https://qiita.com/hatt0519/items/3188382ad85a8654cc42)
[自分でニューラルネットワークを作ろう](https://qiita.com/takahiro_itazuri/items/d2bea1c643d7cca11352)

## 演算ユニットは質より量

- CPUの演算ユニットは[個々の計算を高速で切り替えることで(見た目の)並立演算を実装している](https://www.amazon.co.jp/dp/4822281655)  
⇒ いくら高性能なCPUでも、演算ユニットの総数は多くない  
⇒ ・ 並行演算に見えても実際には直列演算なので総学習時間は余り短縮できない  
　 ・ 並行演算を実現する多コア化も、採算ライン面では問題があると考える  

- 高性能なAIでも、タイムリーかつコストを抑えて開発できなければ商業ベースには乗せにくいと考える  

    ⇒ GPUCPUでの並行処理を活用する

### 演算ユニット数(CUDAコア数)の比較

| CPU | GPU |
| :----: | :----: |
| ≒ コア数 | [3584](https://ja.wikipedia.org/wiki/NVIDIA_Tesla) |

- [Alpha碁](https://www.amazon.co.jp/dp/4798157775)の場合、  
　GPUCPU利用: 1日分の学習 ≒ CPUのみ: 30日の学習  
であった

## AIに学習用させる

参考（ **というより結論** ）：  
[機械学習のデータセットの重要性](https://qiita.com/nonbiri15/items/b29fe079d359d531bf85)

### 過学習を防ぐために

[過学習](https://ai-kenkyujo.com/2020/01/16/kagakushu/)を起こすと、実際の運用での正解率が低くなってしまう

- 過学習を緩和するために学習用データを多数用意する
- ドロップアウト等他の手法はAWSのアルゴリズムに実装されているので、今回は実装に関する問題は考慮しない

### 学習用データ数の目安

- **最低** [アウトプットに影響するパラメータ数の10倍](https://lionbridge.ai/ja/articles/how-much-ai-training-data-do-you-need/)

### 学習用データの拡張

- 学習用データは多いほうがよいが、十分な数を揃えるには限界がある  
- 画像学習用データ拡張の例
    - 撮影方向の多角化  
        ![cat_icon_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/ceb8ed00-1933-8ea5-906d-d6c86cd39fb8.png)  

    - 画像の一部切取  
        ![cat_icon_cut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/1df65824-6863-beb8-a001-0dfd6eb23d07.png)
    - 画像の一部マスク  
    ![cat_icon_mask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/f06fc065-e4b6-f0e7-0312-5ef5a3a29eeb.png)
    - 画像の回転  
    ![cat_icon_rolling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/f7330171-e95d-13a2-835f-2666e5871bfd.png)

### 学習用データの正規化
学習用データ画像のレベルを[正規化](https://docs.gimp.org/ja/plug-in-normalize.html)する

参考 
[イラストで学ぶ ディープラーニング](https://www.amazon.co.jp/dp/4065133319)

## 学習結果の活用

- 時間をかけてニューラルネットワークを構築・学習させても学習結果が出力されなければ意味がない  
以降でAWSでの例を見ていく

[コードを書かずにAIを構築してみる ー 失敗編](https://qiita.com/y_k_individual/items/4e780356d8cc5c3b8590)

[コードを書かずにAIを構築してみる ー リベンジ編](https://qiita.com/y_k_individual/items/f37e2ac107b6b7043c11)
ターミナルの主要コマンド 18個

# はじめに
ターミナルの主要コマンドをまとめています。
各種サイトから引用しています。
より詳しい説明が必要な方は、下記引用元をご参照ください。

# 各種コマンド
| 説明 | コマンド | コマンド例 |
|:--|:--|:--|
| ディレクトリ内容の表示 | ls | $ ls -l |
| ディレクトリの作成 | mkdir <ディレクトリ名> | $ mkdir environment |
| ディレクトリの移動 | cd <ディレクトリ名> | $ cd environment/ |
| 上のディレクトリに移動 |  | $ cd .. |
| ホームディレクトリに移動 |  | $ cd  |
| ホームディレクトリ直下のenvironmentに移動 |  | $ cd ~/environment/ |
| ファイルの移動やリネーム | mv <移動元> <移動先> | $ mv foo bar |
|| mv <現在の名前> <変更後の名前> |  |
| ファイルのコピー | cp <コピー元> <コピー先> | $ cp foo bar |
| ファイルの削除 | rm <ファイル名> | $ rm foo |
| 空のディレクトリの削除 | rmdir <ディレクトリ名> | $ rmdir environment/ |
| 中身のあるディレクトリの削除 | rm -rf <ディレクトリ名> | $ rm -rf tmp/ |
| ターミナル表示の全削除（内容の取消しではない）| clear | $ clear |
| ファイルの内容の結合と表示 | cat <ファイル名> | $ cat ~/.ssh/id_rsa.pub |
| 今のディレクトリまでのパスを表示| pwd | $ pwd　|
|日時を表示| date | $ date |
|誰がログインしているかを表示| who | $ who|
|ユーザーのIDを表示| id |$ id|
| ログアウト| exit | $ exit|

# 引用元
- [Ruby on Rails チュートリアル](https://railstutorial.jp/chapters/beginning?version=5.1#sec-the_hello_application)

- [TECK ACADEMY magazine
今さら聞けない！ターミナルの使い方【初心者向け】]
(https://techacademy.jp/magazine/5155)

- [エンジニアの入り口
【初心者用】Linuxのコマンドとは？とコマンドラインの表示方法]
(https://eng-entrance.com/linux-what-is-command#i-10)
Pythonで変数を動的に定義する方法

# 概要
* Pythonで変数を動的に定義する方法を紹介
* execで動的に変数を定義する
    * ただし、日本語等マルチバイト文字はエラーがでるため少し工夫した。

# 用途
* ユーザーが好き勝手名称を定義するので、何とかしたかった。

# ソースコード
```python

# ユーザーの適当Input
header_list = ['ほげほげ', 'ふがふが', 'ほげふが']
vars = [25.7,13.2,12.5]

coef_list = []
for no,(header,var) in enumerate(zip(header_list,vars)):
    coef_list.append(dict(name = 'coef'+str(no),header=header,var=var))

# output
# サンプル係数辞書(dict型)
print(coef_list)

>> [{'name': 'coef0', 'header': 'ほげほげ', 'var': 25.7},
    {'name': 'coef1', 'header': 'ふがふが', 'var': 13.2},
    {'name': 'coef2', 'header': 'ほげふが', 'var': 12.5}]
```


```python
# dict型からnameとvarを取り出して、変数として定義する。
for coef in coef_list:
    exec('{name} = {var}'.format(name = coef['name'], var = coef['var']))

print(coef0)
print(coef1)
print(coef2)

# output
>> 25.7
>> 13.2
>> 12.5
```
Ruby on Rails チュートリアル 1日目


##1日目
今回自分で1章の少し途中までやったので疑問点詰まったところがありました。
[リスト１．６](https://railstutorial.jp/chapters/beginning?version=5.1#sec-rails_server)まで書かれている通りにやったのですが、書かれた通りに行かず下のようになってしまいました。

```
flandrescarlet237:~/environment $ cd ~/environment/hello_app/
flandrescarlet237:~/environment/hello_app (master) $ rails server
=> Booting Puma
=> Rails 5.1.7 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.4 (ruby 2.6.3-p62), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:8080
Use Ctrl-C to stop
```

そしてrailsアプリケーションが表示されませんでした。
まさかこんな早くに積むとは、思いませんでした。
誰か解決法を教えてくれると嬉しいです。

###追記
なんとか一様解決しました！
![スクリーンショット 2020-04-13 15.25.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606053/d5b53c02-c5f9-c5c9-4362-fb746a2bbc21.png)
右上のところのボタン押せばよかったんですね、、、
lets encrypt 導入メモ

# はじめに

近年セキュリティ上の観点から、googleではhttp通信ではなくhttps通信を推奨しています。httpを利用している場合には警告が表示されるようになり、今後よりいっそう制約が厳しくなっていくものと考えられます。

https化するには様々な手段があり、安全性のレベルにより費用も年間数百円〜数十万円とかなり幅広くなります。

低費用かつ最低限の暗号化を行うという考えの下で複数の方法を試してみましたが，やはりlet encryptの導入が簡単だったので、メモを残します。

# 環境
- ubuntu16.04 
- nginx

# インストール
lets encryptを使用するにはcertbotが必要です

```  
apt-get  -y install certbot
```

# 証明書作成

```
certbot certonly --webroot -w /var/www/html/ -d xxxx.yyyyyyyyy.zzz
```

- certonly : 証明書のみを取得、自動インストールはしない
- webroot : 証明書ファイルを取得する
- w : ルートディレクトリを指定。今回はnginxのデフォルトフォルダ。
- d : 事前にIP設定をしたドメイン名を指定

以下に証明書が作成される

```  
ls /etc/letsencrypt/live/xxxx.yyyyyyyyyy.zzzz/
cert.pem  chain.pem  fullchain.pem  privkey.pem  README
```

- サーバ証明書（公開鍵）: cert.pem
- 中間証明書: chain.pem
- サーバ証明書と中間証明書の結合ファイル:fullchain.pem
- 秘密鍵: privkey.pem

# nginx 設定
server配下にsslを設定

```
server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl  on;
    ssl_certificate /etc/letsencrypt/live/xxxxx.yyyyyyy.zzzz/fullchain.pem ;
    ssl_certificate_key /etc/letsencrypt/live/xxxxx.yyyyyyy.zzzz/privkey.pem;
    ssl_session_timeout 2m;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
}

```
なお443portは開けておくこと

```
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
```


# 結果
nginxに接続するとhttpsになっていることを確認できる
![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573779/5a02dab4-f995-e716-c718-c8538c77b1fe.png)
enebularでストリーミング

#概要

enebularで、audiocontextのストリーミングやってみた。

#flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c9692835-d6d1-66fb-e2d5-51b0bb06fcc6.png)

#仕掛け

audiocontextで440Hzのsin波を生成して、websocketで送信。
受信機は、arraybufferを、websocketで受け取ってgetChannelDataする。

#送信機サンプルコード


```

function run() {
  var ws = new WebSocket("wss://ev2-prod-node-red-6267843e-e70.herokuapp.com/pub");
  ws.binaryType = "arraybuffer";
  ws.onopen = function(e) {
    alert("ok");
  };
  ws.onerror = function(e) {
    alert("err");
    alert(e.msg); 
  };
  var ac = new AudioContext();
  var processor = ac.createScriptProcessor(4096, 1, 1);
  var p = 0;
  var signal = new Float32Array(4096);
  var t = ac.sampleRate / 440;
  processor.onaudioprocess = function(e) {
    for (var i = 0; i < 4096; i++)
	  {
		  p += 1 / t;
		  signal[i] = Math.sin(2 * Math.PI * p) * 0.5;
	  }
	  e.outputBuffer.getChannelData(0).set(signal);
    ws.send(signal);
  };
  processor.connect(ac.destination);
}
```

#受信機サンプルコード


```
function run() {
	var gaia;	
	var ws = new WebSocket("wss://ev2-prod-node-red-6267843e-e70.herokuapp.com/sdr");
	ws.binaryType = "arraybuffer";
	ws.onopen = function(e) {
		alert("ok");
	};
	ws.onerror = function(e) {
		alert("err");
		alert(e.msg); 
	};
	ws.onmessage = function(e) {
		gaia = new Float32Array(e.data.slice(0, 4096));
	};
	var ac = new AudioContext();
	var processor = ac.createScriptProcessor(4096, 1, 1);
	processor.onaudioprocess = function(e) {
		e.outputBuffer.getChannelData(0).set(gaia);
	};
	processor.connect(ac.destination);
}

```


#成果物

送信機

https://embed.plnkr.co/plunk/sjpWLhfumPzd5b3y

受信機

https://embed.plnkr.co/plunk/Os9UUKiVl4Y4E0RK

以上。