OmniAICreator/Qiita-1.07M huggingface dataset:
【Rust】serde_jsonあれこれ


## はじめに
rustお勉強2日目の初心者なので、温かい目で見守ってください。
間違いがあればコメントで指摘していただけると助かります。

## serde_json - Rustdocs
https://docs.serde.rs/serde_json/

## jsonのキーに予約語に使われているとき〜
こんな感じのjsonがあるとする。

```json
{
    "type": "hogehoge"
}
```

↓のような構造体に変換したい。
でも、**type**って予約語。。。。

```rust
struct Fuga{
    type: String,
}
```

とりあえず書いてみるが、**コンパイルは通らない**。
うん、知ってた。

```rust:src/main.rs
extern crate serde_json;

use serde_derive::Deserialize;

#[derive(Deserialize, Debug)]
struct Fuga {
    type: String,
}

fn main() {
    let json_str = r#"
    {
        "type": "hogehoge"
    }
    "#;
    let fuga: Fuga = serde_json::from_str(json_str).unwrap();
    println!("{:?}", fuga);
}
```

### 対処法その１
[Raw identifiers](https://doc.rust-lang.org/edition-guide/rust-2018/module-system/raw-identifiers.html) を使用する。

実は、上記のコードを `cargo run` すると、こんなエラーが出てくる。

```sh
error: expected identifier, found keyword `type`
 --> src/main.rs:7:5
  |
7 |     type: String,
  |     ^^^^ expected identifier, found keyword
  |
help: you can escape reserved keywords to use them as identifiers
  |
7 |     r#type: String,
  |     ^^^^^^
```

help まで出してくれるなんて、優しい。
ということで、さきほどの構造体を↓のように書き換えて実行する。

```rust
struct Fuga {
    r#type: String,
}
```

```sh
$ cargo run
Fuga { type: "hogehoge" }
```

よしよし。

### 対処法その２
**構造体のフィールドの名前を変えちゃう！**

該当のフィールドの上に、これをつけるだけ。

```rust
#[serde(rename = "jsonのキー")]
```
[Field attributes](https://serde.rs/field-attrs.html) に詳しく書いてある。

ということで、構造体を↓のように書き換えて実行する。

```rust
struct Fuga {
    #[serde(rename = "type")]
    type_name: String,
}
```
```sh
$ cargo run
Fuga { type_name: "hogehoge" }
```

よしよし。

## jsonのキーがキャメルやアッパーのとき〜
こんな感じのjsonがあるとする。

```json
{
    "Type": "hogehoge"
}
```
構造体にするとしたら、こう？？

```rust
struct Fuga{
    Type: String,
}
```

いいえ。

さきほどの [Field attributes](https://serde.rs/field-attrs.html) を使いましょう。

```rust
struct Fuga {
    #[serde(rename = "Type")]
    r#type: String,
}
```

```rust:src/main.rs
extern crate serde_json;

use serde_derive::Deserialize;

#[derive(Deserialize, Debug)]
struct Fuga {
    #[serde(rename = "Type")]
    r#type: String,
}

fn main() {
    let json_str = r#"
    {
        "Type": "hogehoge"
    }
    "#;
    let fuga: Fuga = serde_json::from_str(json_str).unwrap();
    println!("{:?}", fuga);
}
```

```sh
$ cargo run
Fuga { type: "hogehoge" }
```

よしよし。

ちなみに、キャメルでもできなくはない。
が、**warning** が出るのでよろしくない。

```sh
warning: structure field `Type` should have a snake case name
 --> src/main.rs:7:5
  |
7 |     Type: String,
  |     ^^^^
  |
  = note: `#[warn(non_snake_case)]` on by default
help: rename the identifier or convert it to a snake case raw identifier
  |
7 |     r#type: String,
  |     ^^^^^^

warning: 1 warning emitted
```

## 最後に
キャメル、アッパーのところ
もう一つ、やり方があった気がしたけど、忘れちゃった。。。
思い出したら追記します。
SettingWithCopyWarningの解決法

DataFrameの要素の書き換えをしてたら

```
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
```
という警告が出てきました

<h2>解決方法</h2>
上の行に以下の文を追加したら警告が消えました

```
pd.options.mode.chained_assignment = None
```
slackの操作をシェルプロっぽくしてChatOps捗りツール作りました！


# まえせつ

slack使ってるとネイティブアプリが**Webアプリぽい操作感**なのに、**ターミナルがシェル**なのでモヤる時ありませんか？

- メッセージを再編集するのに**↑キー**で履歴を選びたい。ネイティブアプリの実装は何か違う感が・・
- 特定の人へのメンションを多用するので毎度コピペするのが面倒。**@漏れで読んでくれない**、とか。
- 同じ入力をするのに**エイリアスみたいなので入力**を減らしたい。ファイルサーバーの途中までのパスとか。

特にslack→サーバーへコマンド投げ込みボットが居る場合はとっても面倒になります。<br>
ボットを呼んでコマンド投げて、メンション入れて確認依頼して・・次のコマンド入れて・・をコピペして繰り返すことになります。

### というのをUXを解消してくれるのが、このツール！

# 作ったわ！

<a href="https://github.com/yasutakatou/slackops"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/yasutakatou/slackops.png" width="460px"></a>

詳しくはリポジトリで。バイナリをダウンロードして即使いたいなら[こっち](https://github.com/yasutakatou/slackops/releases)

### zlib1.dllが無い場合のエラー

使用しているrobotgoが依存しているのでzlib1.dllが無い場合、エラー落ちが予測されます。<br>
[こちらのリンク](https://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/Binaries%20%2864-bit%29/)からダウンロードしてパスが通ってる場所に配置すると動かせます

# つかいかたは？

実行ファイルを起動すればプロンプトが出ます。そこに入力した内容をslackのネイティブアプリに投げ込んでくれます。

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/4ebbf794-42a5-f6aa-6655-96b9002158d7.gif)

一行モードにすれば書き込みを待たずに一行単位で投げ込んでくれるのでサクサクChatOps！！

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/8d0cafcf-16af-f566-67ea-4928e2e4b60e.gif)

# あとがき

三か月ぶりの個人開発！！
・・・三か月でさび付いてくるもんなんですね。過去に自分書いたの読めないわ、書けないわ。ｗ
ただ、また思い付きで何か作ってみようってモチベが出てくるのは良い事だわ。

続いて、チャットボット側も作っていきたいな。
チームからChatから依頼受けたら、わざわざターミナル上げて、ログインしてログ見て、コピペしてみたいな繰り返しをやめて
チャットからコマンド流して共有して、オペレーション履歴も残って・・みたいな世界観でSREっていきたい！！
Qiita/Zennの投稿をGitHubプロフィールに自動反映するためのツールを作った

この記事は Feed で GitHub の README.md に反映されるはず。という実験用のエントリです。

記事はこちら：https://zenn.dev/ikawaha/articles/20210221-c8f2d9ac028ae49d551a
データ分析結果を提案や問題解決につなげるために

初投稿です。
日々、学んだことや今後やりたいことなど、備忘録として残していきます。
今回のテーマは「データ分析」のプロセスについてです。

## はじめに
業務において、以下のようなシーンはないでしょうか。

+ データはある、分析手法もある程度は分かる、しかしどう進めればよいかが分からない
+ とりあえずデータを見てみたものの、提案に結び付くようなアウトプットを出せていない

私自身、分析プロセスについて学ぶ必要性を感じ、以下のUdemy講座をとってみました。
　[説得力を高め問題解決に導く！実務直結”データを活かした”戦略的ストーリーメイキング講座](https://www.udemy.com/course/storymaking/)
　講師：Yoshiki Kashiwagi氏

## 概要
+ データの分析は、~~「①データを見てからそこから何が言えるかを考える」~~のではなく、「②何を言いたいか/知りたいかを考えてからデータを扱う」べき
+ ~~「データありきのアプローチ」~~ではなく、「ゴールありきのアプローチ」をとるべき
    + ゴール（目的や問題）を考える
    + 目的や問題に沿ったデータと手法を考える
    + 目的や問題解決に至る道筋をつける
    + 分析を実施
    + 目的や問題に対する結論を考える
+ 仮説アプローチをとるべき
    + 「ゴールまでの道筋の仮説」、「個々の分析の仮説」を立て、その仮説が正しいかを確認しながら進める
    + 仮説なくデータをみるとデータに振り回され、ゴールにたどり着く結論を導き出せない

## 所感　★★★★☆
+ 講師の方の説明が分かりやすい！また、共感する部分が多数あり満足できました。（演習がもっとあるとなおよい）
+ ゴールありきのアプローチの重要性はその通り。言われれば簡単だが、間違っているケースは多いと思われます。
+ プロジェクトマネジメントと同じ。計画があって初めて現状とのギャップを測れ、ギャップが分かるからこそ対処・軌道修正ができますね。
+ 実践で経験値を積みたいと思います。
[Python]二分探索 ABC192D

#[ABC192D](https://atcoder.jp/contests/abc192/tasks/abc192_d)

$X$ が 1 文字のとき、答えは 0 か 1 です。以下、そうでない場合を考えます。
$X_{(n)}$は $n$ の狭義単調増加関数です。したがって、$ \max (\ n\ |\ X_{(n)}\leqq M_{(10)}\ )$ を求めれば良い。ただし、$\max M=10^{18}$なので、二分探索することで時間計算量を $O(L\log M)$ とします。

```python:サンプルコード
x = input()
m = int(input())
d = int(max(x))
if len(x) == 1:
    print(+(int(x) <= m))
else: # 二分探索
    L, R = d, m+1
    while R-L > 1:
        M = (L+R) // 2
        a = 0
        # x_Mを10進数変換する
        for i in x:
            a *= M
            a += int(i)
            if a > m: #途中で越えたら中止
                R = M
                break
        else:
            L = M
    print(L - d)
```

小生のプログラミング能力は貧弱であることは痛感しているが、この問題文は数学的に不正確な点がある。数学力のある参加者は自分で修正しながら解答しなければならなくなるので、数学力がハンデになることがある。これは良くない事態ではないだろうか。
VAEの潜在空間に人間の知識を導入してみた

この記事は、読者がVAEの知識を持っていることを前提としています。 VAEについては、以前の記事で少し触れました、私のホームページにアクセスして確認できます。

VAEはポイントの間の真空を埋め、ポイントからポイントへの移行をスムーズにしました。たとえば、下の図の3行目のように、3から6に変化しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/e3d810f8-c8aa-d030-8b09-3bff8aa0ffc9.png)

トレーニング後の潜在的な空間分布は、おおよそ下図のようになります。便宜上、0〜3のみを出力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/9e3a1fdc-c06a-4daa-4b3d-ae40fec9e3ba.png)

0を表す濃い青と1を表すシアンが遠く離れていることがわかります。 手書きの0と1は区別しやすいので、そのような結果を出すのは当然です。 しかし、ここで問題が出る、0と1は常識的に隣接しているのに、なぜ潜在空間でそれらを隣接させることができないのでしょうか。

たとえば、3から6に切り替えるには、3、4、5、6のように増やすのがより自然な方法ではありませんか？ ニューラルネットワークに潜在空間の論理接続を学習させる方法はありますか？ これが今日の記事の主題です。

私の答えは、もちろんです。隣接する数（2と3、4と5など）によって生成されるベクトルの空間距離を減らすればいいじゃないですか。 そこで、ニューラルネットワークに、データセットの中に隣接する数のペアによって生成された潜在空間ベクトルをランダムにサンプリングして、距離を減らすように訓練しました。

トレーニング後の結果を以下に示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/f8bf3b18-2584-f6a2-fd7c-2a63397612e3.png)

赤と青の色がそれぞれ1と0であることがわかります。距離は確かに短くなっていますが、テスト結果は次のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/f5007bc6-6229-72ca-3eed-4e2f7b257a0b.png)

前の行の1列目と3列目を見ると、2が3になり、1が2になっていることがわかります。これは、モデルが実際に少しの接続を学習したことを示しています。3行目では、3から9そして8に似た何かを通過します。

しかし、実験はいずれにせよ成功とは言えません。 効果が見えないし、研究に使う方法がわからないので、このアイデアを放置しておきます。
Easy-ISLispでOpenGLを

#はじめに
Easy-ISLisp（以下「EISL」)からOpenGLを扱うことに取り組んでいます。うまくいきました。ご紹介します。

![Screenshot at 2021-02-21 16-21-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/16c34c57-d765-c967-6b01-96c065eb2871.png)

#OpenGLのインストール
予めOpenGLがインストールされている必要があります。LinuxMINTへのインストールは簡単です。下記をご参照ください。
https://qiita.com/sym_num/items/90cf5a22e623e1ad6578

#Cラッパを利用したライブラリ
EISLにはC言語へのラッパが用意されています。Lisp関数にC言語コードを埋め込むことができます。これを利用してOpenGLを呼び出す関数を記述しています。

例

```lisp

(defun glut::init-window-size (hight width)
    (c-lang "glutInitWindowSize((INT_MASK & HIGHT), (INT_MASK & WIDTH));"))

(defun glut::init-window-position (hight width)
    (c-lang "glutInitWindowPosition((INT_MASK & HIGHT), (INT_MASK & WIDTH));"))

(defun glut::create-window (x)
    (c-lang "glutCreateWindow(Fgetname(X));"))


```

#インタプリタでもOK
GLUTの関数を利用して画面を描画する関数を呼び出しています。ここにLispの関数を記述できるようにしてあります。このためインタプリタでもOpenGLを動作させることができます。試行錯誤するにはインタプリタの方が楽です。すっかり動作確認ができたならコンパイルすることも可能です。

callback関数が事前にvoid型として定義されています。Lispで記述された描画関数のアドレスを大域変数、callbackfuncに代入し、callback関数はLispのEvalを呼び出しています。

#整備中
以下のような簡単なものは動作することが確認できました。あとはひたすら必要なOpenGLの関数をライブラリに補充すればOKです。ISLispでゲームも記述できるようになることでしょう。


```lisp

(import "opengl")

(defun main ()
  (glut::init)
  (glut::init-display-mode 'glut-single)
  (glut::init-window-size 400 300)
  (glut::init-window-position 200 300)

  (glut::create-window "GLUT test")
  (glut::init-display-mode "GLUT_RGBA")
  (gl::clear-color 1.0 1.0 1.0 1.0)

  (glut::display-func 'show)
  (glut::main-loop)
)

(defun show ()
  (gl::clear 'gl_color_buffer_bit)
  (gl::color3d 1.0 0.0 0.0)
  (gl::begin)

  (gl::vertex2d -0.5 -0.5)
  (gl::vertex2d -0.5 0.5)
  (gl::vertex2d 0.5 0.5)
  (gl::vertex2d 0.5 -0.5)

  (gl::end)
  (gl::flush)
)


```

githubにおいてあります。
https://github.com/sasagawa888/eisl
[memo]テストコード準備と実行

## テストコードの準備

```
# Gemを追加 Gemfile
# group :development, :testというグループの中に記述
% gem 'rspec-rails', '~> 4.0.0'

# ターミナル
% bundle install

# ターミナル
% rails g rspec:install

# .rspecに設定を追加
--require spec_helper
--format documentation
```

## テストコードを記述するファイルを用意

```
# ターミナル
# Userモデルのテストファイルを生成
% rails g rspec:model user
```

## テストコードの実行

```
# ターミナル
% bundle exec rspec spec/models/user_spec.rb
```

## FactoryBotのGem導入

```
# Gemfile
# group :development, :test do へ記述
gem 'factory_bot_rails'

# ターミナル
% bundle install
```

## インスタンスの生成を切り出すファイルを作成

```
FactoryBotの記述を格納するディレクトリfactoriesと、
Userモデルに対するFactoryBotのファイル
users.rbを、以下のように手動で作成

spec > factories > users.rb

※この操作は、テストコードを記述するファイルを生成した後からFactoryBotを導入するときに必要です。
FactoryBot導入後はテストコードを記述するファイルを生成すると同時に、自動生成されます。
```

## FactoryBotの記述を編集

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              {'test'}
    email                 {'test@example'}
    password              {'000000'}
    password_confirmation {password}
  end
end
```

### FactoryBotを使う記述

```ruby:spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  before do
    @user = FactoryBot.build(:user)
    #処理速度を落とす記述
    sleep 0.1
  end

  describe 'ユーザー新規登録' do
    it 'nicknameが空では登録できない' do
      @user.nickname = ''
      @user.valid?
      expect(@user.errors.full_messages).to include "Nickname can't be blank"
    end
    it 'emailが空では登録できない' do
      @user.email = ''
      @user.valid?
      expect(@user.errors.full_messages).to include "Email can't be blank"
    end
  end
end

```

## ランダムな値の生成ができるFakerを導入

```
# Gemfile
# group :development, :test do へ記述
gem 'faker'

# ターミナル
% bundle install
```

## FactoryBotの記述をFakerを使ったものへ編集

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              { Faker::Name.initials(number: 6) }
    email                 { Faker::Internet.free_email }
    password              { '000000' }
    password_confirmation { password }
  end
end
```

▼Fakerのリストは公式Github
https://github.com/faker-ruby/faker
【MySQL】MyAdminのsqlファイルをWorkbenchにインポート

# 初めに
・開発したアプリをデプロイしようとHerokuを使用(人生初デプロイ)
・参考にした記事は[こちら](https://lacublog.com/php-heroku)

# やりたいこと
MyAdmin(ローカル環境)にあるデータベース上のテーブルやカラムや行(値)を全てMySQL Workbench(本番環境)上にインポートしたい

#やったこととそのエラー
### 1.手順の通りインポート
<内容>
冒頭の[参考記事](https://lacublog.com/php-heroku)の「Workbenchにデータベースをインポート」内で
>
Administrationの中にあるData Import/Restoreを選択
(手順の通りやって…)
Start Importを押してインポート

まで実行

<結果>
Workbenchが落ちる...

### 2.SQLでインポート

<内容>
MyAdminからエクスポートした「〇〇.sql」ファイルがあると思います。
そのファイルにエクスポートしたデータを生成するSQLが入っているので、コピー＆ペーストし、SQLを実行
※詳細は以下[参考記事](https://blog.proglus.jp/2957/)

<結果>
Workbenchの「ActionOutput」に以下エラーが発生(#9)
![image (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/3e61de89-2487-165b-79c2-d818aa5a31d6.png)

※オレンジ塗りつぶし部は本番環境用データベース情報の<ユーザー名>が記載されています。

以下、エラー文抜粋
>Actions
CREATE DATABASE IF NOT EXISTS 'my_project(ローカル環境データベース名)' DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

>Message
Error Code: 1044. Access denied for user '<本番環境ユーザー名>'@'%'to database 'my_project(ローカル環境データベース名)'


# 解決策

### 手順
1. インポートするsqlファイルを開く
2. 24行目付近にある以下SQLを探す

>
CREATE DATABASE IF NOT EXISTS `<ローカル環境データベース名>` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `<ローカル環境データベース名>`;

3.以下のように記載

>
CREATE DATABASE IF NOT EXISTS `<ローカル環境データベース名>` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `<ローカル環境データベース名>`;

要は**<ローカル環境データベース名>を<本番環境データベース名>に変更**します。

これで「やったこと」で書いたどちらの手順を踏めばSQlが実行され、インポートができます。

# <参考>ちなみに

## DB情報は環境変数を使うのがベター
僕はこれで一度デプロイしたデータベースアカウントを削除し、新しく作り直しました。
理由は[こちらの記事](https://qiita.com/TkTkTkTkTako/items/d873cacf881be5e0cceb)の通り、**Githubにデータベース情報を公開してしまった**ためです…
これから僕と同じように、エンジニアを目指されている方は、こういった機密情報の扱いは気を付けた方がいいと思います。(経験談)

環境変数の設定については[参考記事①](https://qiita.com/KZ-taran/items/6fd4fc6617953fdbc7db)、[参考記事②](https://ryuki999.com/2019/11/10/herokuxphpxmysql-setup/#toc2)を張っておきます。

## その他エラー
ここまで作業を進める中で色々警告文が表示されましたがデプロイする上で特に問題はありませんので、無視し続ければいいです。

### 1. TestConnection時のエラー
Workbench起動して「MySQL Connection」からDBの接続先を入力⇒DB情報を入力して「TestConnection」押下後に出る下記エラー
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/05c4ea4f-6b3b-d41b-a7da-35abd4661894.png)

後に、
``Successfully made the MySQL connection``
の表示があればDBとの接続はできているので、問題ありません。


### 2. 「MySQL Connection」からDBをクリックした時のエラー
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780929/3114dc29-240d-8d32-0220-ada0e0717a4b.png)
DBとの接続後、「MySQL Connection」から接続済のDBをクリックした時の警告文ですが、特に悪さはしないので問題ないです。

### 3. 「Error Code: 1062」や「Error Code: 1075」…etcの発生
「テーブルの重複」や「テーブルの重複によるPrimary KeyやAutoIncrement設定の失敗」など色々発生しました。
こちらはたくさん記事がありましたので、自力で調べていただければと思います。

最後まで読んでいただきありがとうございました！
尝试在VAE潜在空间里引入逻辑联系

本文假定读者拥有VAE的知识。关于VAE，之前发表的记事里稍微有讲，可以到我的主页去看。

VAE填补了潜在空间的真空，让点到点之间的转换更加平滑，例如下图中的第三行，从3转换到6。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/3144da85-7669-c77f-9316-e7da91fe21b9.png)

训练后的潜在空间分布大概如下图，为了方便展示我只输出了0到3：

![poor_vae_0_to_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/9581ee8a-ee70-d8ee-ddd5-cee978a54ec0.png)


我们可以看到代表0的深蓝和代表1的青色，两者相距遥远。因为手写的0和1很容易分辨，所以产生这样的结果也是理所当然的。可是我们很容易产生一个问题，0和1在逻辑上是相邻的，那我们为什么不能让它们在潜在空间里也相邻呢？

比如从3转换到6，更加自然的方法难道不是3，4，5，6这样递增吗？我们有没有办法让神经网络学习潜在空间的逻辑联系呢？这就是今天这篇记事的主题了。

我的想法是，当然可以，只要将相邻数字（比如2和3，4和5）产生的潜在空间距离缩小不就好了吗？ 于是我让神经网络在训练的时候，随机抽取相邻数字对产生的潜在空间向量，减小两者之间的距离。

训练之后的结果如下图。

![yes2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/48f0b606-95f3-7b7f-01b4-1971cfe1d56f.png)

我们可以看到红色和蓝色，分别是1和0，距离确实被拉近了，可是测试得到的结果如下图：

![dd1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/6f698c15-bfdb-5e5d-0af2-e4738ccecad1.png)

看前面行的第一和第三列，我们看到2变成了3，1变成了2，这可以说明模型确实学到了一点联系，然后第三行，从3变成9，中间也经过了一些类似8的东西。

但是怎么说呢，无论如何实验都不能说是成功。一是因为效果很差，二是因为不知道怎么用到研究上，所以这个研究就先闲置了。
Android round Icon の設定方法



Asset Studio を利用した icon と roundIcon の追加方法
1. Android Project の res フォルダで右クリック
2. New --> Image Asset をタップ
3. Android 8.0 に対応しているアプリであれば、Icon Type 似て Launcher Icons (Adaptive and Legacy)を選択
4. Name には指定したい名前を
5. Asset Type 似て、Image を選択。選択する Image の解像度によって、その後に生成される各解像度用のアイコンが設定されるみたいなので、綺麗なやつ選んでおいた方が良い・・？
6. 文字が入りきらない場合などは Scaling Reseize でサイズを変更する。
7. 設定が終了したら、Next をタップ
8. 最後に FINISH をタップして完了。
cesiumの作法 その5

#概要

cesiumの作法、調べてみた。
pickEllipsoid使ってみた。


#サンプルコード

```

var viewer = new Cesium.CesiumWidget('cesiumContainer');
viewer.camera.setView({
	destination: new Cesium.Cartesian3.fromDegrees(139.8, 35.6, 1000)
});
viewer.canvas.addEventListener('click', function(e) {
	var mousePosition = new Cesium.Cartesian2(e.clientX, e.clientY);
	var ellipsoid = viewer.scene.globe.ellipsoid;
	var cartesian = viewer.camera.pickEllipsoid(mousePosition, ellipsoid);
	if (cartesian)
	{
		var cartographic = ellipsoid.cartesianToCartographic(cartesian);
		var lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
		var lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);
		alert(lon + ', ' + lat);
	}
	else
	{
		alert('Globe was not picked');
	}
}, false);


```

#成果物

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


以上。
バッファって何？

### はじめに
GoのChannelに関して学んでいる最中に，<font color="orange">バッファ</font>という単語が出てきました．
聞いたことはあるけど，理解はできていない🤔
いい機会なので，調べてみました！

### 簡単に

<font color="purple">**データをやりとりするときの一時的な記憶領域**</font>
のこと．


### きちんと

英語ではBufferと書いて，「緩衝材」のような意味を持つようです．
コンピュータの「一時的な記憶領域」のことを指していて，それが転じてビジネスでは「ゆとり」などの意味合いで使われるようになったらしです🤔

GoのChannelはデータを保持するためのデータ構造で，容量を指定できます．
これが**バッファ**です．
`cap`関数を使うことで，見ることができます．

``` main.go
channel := make(chan int, 5)
fmt.Println(cap(channel))
```

``` :terminal
0
```

と出力されました．
このmake関数で，第２引数に指定された 5 がバッファサイズです．
今は何も受信していないため，容量は 0 と表示されました．

ではこの後に，以下のように送信すると，


``` main.go
channel <- 1
channel <- 2
channel <- 3
channel <- 4
channel <- 5
channel <- 6
fmt.Println(cap(channel))
```

``` :terminal
fatal error: all goroutines are asleep - deadlock!
```

と出力されました．
この deadlock は保存領域が足りないよと言うことで，
バッファのサイズが足りないと怒られてしまったのですね🤔

Channelはqueueの性質を持っていで，バッファはqueueのサイズともいえます．
queueは先入れ先出しの性質を持っているので，

errorを解消するには，受信をしてしまえばいいのではないでしょうか．

``` main.go
channel <- 1
channel <- 2
channel <- 3
channel <- 4
fmt.Println(channel<-)
channel <- 5
channel <- 6
fmt.Println(cap(channel))
```

``` :terminal
1
5
```

こんな感じで出力されました！
この `1` は先入された１ですね🤔
`5` は保存されている容量だと思います．

### まとめ

自分の手で動かしてみて，バッファは
**データをやりとりするときの一時的な記憶領域**
と言うことが理解できたような気がします🙋‍♂️
FlutterでlargeTitleのTextをカスタマイズする


### Themeを作成


```custom_theme.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CustomTheme {

  CustomTheme._();

  static final ThemeData customLightThemeData = ThemeData.light().copyWith(
    cupertinoOverrideTheme: CupertinoThemeData().copyWith(
      textTheme: CupertinoTextThemeData().copyWith(
       
        // LargeTitleのstyle設定
        navLargeTitleTextStyle: CupertinoTextThemeData().navLargeTitleTextStyle.copyWith(
          color: Colors.green
        ),
        // LargeTitleではなくなったときの設定
        navTitleTextStyle: CupertinoTextThemeData().navTitleTextStyle.copyWith(
          color: Colors.red,
        )
      )
    ),
  );
}
```


### MaterialAppに適応させる



```main.dart
import 'package:flutter/material.dart';


class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: CustomTheme.customLightThemeData,
      home: HogePage()
    );
  }
}
```

### LargeTitleを付けたいViewを作成
LargeTitleのTextWidgetにはstyleをつけてはいけない。
styleをつけると、そのstyleが固定されてしまい、小さくならなくなる。

```hoge_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';


class HogePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          CupertinoSliverNavigationBar(
            largeTitle: Text(
              'ホーム',
            ),
          )
        ],
      ),
    );
  }
}
```
cesiumの作法 その4

#概要

cesiumの作法、調べてみた。
clock使ってみた。

#サンプルコード

```
var widget = new Cesium.CesiumWidget('cesiumContainer', {
});
var scene = widget.scene;
var clock = widget.clock;
var camera = widget.camera;
camera.setView({
	destination: Cesium.Cartesian3.fromDegrees(180.0, 0, 8000000.0),
	orientation: {
		heading: Cesium.Math.toRadians(0.0),
		pitch: Cesium.Math.toRadians(-90),
		roll: 0.0
	}
});
var eventHelper = new Cesium.EventHelper();
eventHelper.add(clock.onTick, onTick);
function onTick() {
	camera.rotateLeft(Cesium.Math.toRadians(Math.PI * 5 / 180));
}

```

#成果物

https://embed.plnkr.co/plunk/8JpMungZ2DO7ZL2n

以上。
VSCodeでgitbashを使えるようにした後venvを起動するための豆知識

#はじめに

[この記事](https://qiita.com/daikiozawa/items/48a9fe0e2898c7dd78ae)に従って、VSCode のターミナルを Git Bash に変更した。

いざvenvをactivateしようとターミナルから以下を実行しても、何も応答がないためググって対応した時のメモ

```sh
$ djangovenv/Scripts/activate
```

#対応方法
以下のようにsourceをつければよい。

```sh
$ source djangovenv/Scripts/Activate
```

#参考
- [venv problem with python3.6 and git-bash on win10 ](https://github.com/microsoft/vscode-python/issues/939)
cesiumの作法 その3

#概要

cesiumの作法、調べてみた。
flyTo使ってみた。

#サンプルコード

```

var widget = new Cesium.CesiumWidget('cesiumContainer', {
});
setTimeout(function() {
	widget.camera.flyTo({
		destination: Cesium.Cartesian3.fromDegrees(140.0 + 0.4, 38.0 - 0.1, 20000.0),
		orientation: {
			heading: Cesium.Math.toRadians(-10.0),
			pitch: Cesium.Math.toRadians(-15.0),
			roll: 0.0
		}
	});
}, 7000);


```

#成果物

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

以上。
xcode、iphoneアプリ開発で部品との関連付けができないとき

xcode
Version 10.1

iphoneアプリ開発で部品との関連付けができないときは、クラスの指定が問題かなと思って、いろいろ調べたり、試行錯誤したが、なぜできないかというとトラックパッドでうまくドラッグできていなかった。

マウスでやる分には自然にできていたが、マウスがないときに、コントロールを押しながらドラッグするということができていなかった。

僕のmacは設定で、３本指で操作するとドラッグできるようにしているのだが、このときにうまくできていなかった。
xcode触り出して、序盤でよく起こっていたことなので、謎がとけてうれしい。

ぐぐっても出てくる内容ではないので、ここに記録した。
NestJSでenvをmain.tsで読み込む

NestJSで.envを読み込むやり方を失念したためのメモ。

## TL;DR

main.tsでapp.get(Service)で読み込むことができる
app.getのargument は String || Service Instanceで対応可能。

## Reference

- [Configuration | NestJS](https://docs.nestjs.com/techniques/configuration)
- [StackOverflow](https://github.com/nestjsx/nestjs-config/issues/49)

## 現状のファイル構成とファイル

```terminal
$ tree
src
|- main.ts
|- config
|    |- configuration.ts]
|-.env
```

```.env
PORT=3000
```

```config/configuration.ts
export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
});

```

```main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(300);
}
bootstrap();
```

## 変更後のファイル

```main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config'; //ここを追記

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  app.useGlobalPipes(new ValidationPipe());
　//ここから追記
  const PORT = app.get(ConfigService).get('port')
  // const PORT = app.get('ConfigService').get('port')でもできる。
  await app.listen(PORT);
　//ここmade追記
}
bootstrap();

```

の記載できます。若干使うことが多々あります。

[レポ](https://github.com/Ntakuya/nestjs/tree/feature/config-service/src)
【ExcelVBA】Outlookからメールを送信する方法

##はじめに

ExcelVBAを使用し、メールを自動送信する方法を備忘メモに残す。

##大まかな流れ
<事前準備>
１：ExcelVBE内の参照設定
<スクリプトを記載>
２：「Outlookからメールを送信する」内容をVBE内に書く


##１：ExcelVBE内の参照設定
ExcelVBE内の設定を行わないと、Outlookを起動させる要素が使用できないので、まずは参照設定を行う。

①：Excelを起動し、VBE（【開発】タブ→Visual Basic）を開く

②：VBE内の【ツール】タブ→参照設定を押下

③：Microsoft Outlook 1x.0 Object Libraryにチェックし、OKを押下


##２：「Outlookからメールを送信する」内容をVBE内に書く

①：以下をコピペし、実行

```
Sub outlook_mailsend()

'Outlookオブジェクト生成
Dim objOutlook As Outlook.Application
Dim objMail As Outlook.MailItem
Set objOutlook = New Outlook.Application
Set objMail = objOutlook.CreateItem(olMailItem)

'各種設定
With objMail
    .To = "aaa@aaa.com" 'メール宛先
    .CC = "xxx@xxx.com;yyy@yyy.com"
    .Subject = "testメール" 'メール件名
    .Body = "test" & vbCr & "です。" 'メール本文
    .Attachments.Add "C:\zzz.txt" '添付
    .BodyFormat = olFormatPlain 'メールの形式
    .Send
    
End With

End Sub
```
Javaで標準入力を使った簡単なプログラムを作成

# はじめに
Javaの勉強のために、ネット上の記事を参考にして簡単なプログラムを作りました。
備忘録として残りしたいと思います。

# キーボードからの入力させるプログラム

私は、「Scannerクラス」を用いて入力された数値を取得しました。
構文解析をするためのメソッドです。

```java
import java.util.Scanner;
#↑Scannerクラスが使用できるようになります。
```


# 整数を＋してくれるプログラムを作ります。


```java
import java.util.Scanner;
class main {
  public static void main(String args[]){
    Scanner scan = new Scanner(System.in); //Scannerクラスを初期化
    System.out.println("1つ目の数値を入力してください");
    int num1 = scan.nextInt(); //入力を受け取る
    System.out.println("2つ目の数値を入力してください");
    int num2 = scan.nextInt(); //入力を受け取る

    int sum = num1 + num2;

    System.out.println(num1 + "+" + num2 + "+" + sum);
    scan.close(); //処理を終わらせる
  }
}

```


# 小数点を含む数値を＋してくれるプログラムをつくります。

データ型を「int」から「double」に変えます。
これで小数点の計算をしてくれます。

```java

import java.util.Scanner;
class main {
  public static void main(String args[]){
    Scanner scan = new Scanner(System.in); //Scannerクラスを初期化
    System.out.println("1つ目の数値を入力してください");
    double num1 = scan.nextDouble(); //入力を受け取る
    System.out.println("2つ目の数値を入力してください");
    double num2 = scan.nextDouble(); //入力を受け取る

    double sum = num1 + num2;

    System.out.println(num1 + "+" + num2 + "+" + sum);
    scan.close();
  }
}

```

# さいごに
オープン系のシムテム開発にも携わりたいのでJavaもどんどん勉強していきます！

ここまで読んでいただきありがとうございました！
Pythonでヴィジュネル暗号

#はじめに
ヴィジュネル暗号に関するPythonスクリプトを探しても、非効率的なものしか見つけられなかったため、自分が効率の良いと思うコードを書いた。

#基本方針
ヴィジュネル暗号は、ヴィジュネル方陣を参照して暗号化と復号を行う。
ただし、ヴィジュネル方陣はkey毎に参照先をずらしているだけなため、方陣を作成する必要はない。この方陣を作成しているものしか見つからなかったため、今回の投稿に至る。

#コード抜粋

```python
def vigenere_encrypt(plaintext, key):
    """Vigenere Cipher Encrypt
    key are only UPPERCASE ALPHABET[A-Z]."""
    count = 0
    ciphertext = ''
    key = key.upper()
    for s in plaintext:
        if s.isupper():
            ciphertext += chr(((ord(s) + ord(key[count % len(key)])) % 26) + ord('A'))
        elif s.islower():
            ciphertext += chr(((ord(s) + ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
        else:
            ciphertext += s
        count += 1
    return ciphertext

def vigenere_decrypt(ciphertext, key):
    """Vigenere Cipher Decrypt
    key are only UPPERCASE ALPHABET[A-Z]."""
    count = 0
    plaintext = ''
    key = key.upper()
    for s in ciphertext:
        if s.isupper():
            plaintext += chr(((ord(s) - ord(key[count % len(key)])) % 26) + ord('A'))
        elif s.islower():
            plaintext += chr(((ord(s) - ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
        else:
            plaintext += s
        count += 1
    return plaintext
```

#コード解説
##ヴィジュネル方陣について
以下にヴィジュネル方陣を示す。
![VigenereSquare](https://upload.wikimedia.org/wikipedia/commons/9/9a/Vigen%C3%A8re_square_shading.svg "[画像]ヴィジュネル方陣")
出典: [Vigenère cipher - Wikipedia](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher)

ヴィジュネル方陣は、縦軸をKey, Aを0, Zを25とすると、
Keyの値を平文字（横軸）に自身を足し、26の法を取ったものが暗号化後の文字になるようになっている。
A...ZA...ZA...Zと続く文字列の中で、Keyの値を足したものだと考えたほうがわかりやすい方もいるかもしれない。

##手作業でのヴィジュネル暗号の暗号化方法
例として、暗号鍵を「QIITA」、平文を「VIGENERE」とした場合、
ヴィジュネル方陣の縦軸のQ, 横軸のVの交差点を確認し、Lを得る。
次に、縦軸のI, 横軸のIの交差点を確認し、Q
同様に繰り返していく。（暗号鍵の最後の文字まで達したら、暗号鍵の最初の文字に戻る。）
結果として、暗号文LQOXNUZMを得る。

##コード上での暗号化方法
例として、以下の1行のコードを解説していく。
ord()文字をUnicode値に変換する。chr()はその逆。
暗号鍵の最後まで達したら、暗号鍵の最初の文字に戻る部分は、key[count % len(key)]である。
ord('A')は26の法の数値をUnicode値に変換するためのものである。

```python
ciphertext += chr(((ord(s) + ord(key[count % len(key)])) % 26) + ord('A'))
```
ただし、以下の性質を利用している。

```python
>>> ord('A')
65
>>> (65*2)%26
0
```
上記の性質を利用しない場合、以下の記述になる。

```python
ciphertext += chr((((ord(s) - ord('A')) + (ord(key[count % len(key)]) - ord('A'))) % 26) + ord('A'))
```


#参考文献
[Vigenère cipher - Wikipedia](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher)

#ソースコード
[GitHub: vigenere.py](https://github.com/huwns/classical_cryptography/blob/master/vigenere.py)
バーチャルモーションキャプチャー+waidayo

「3Dアバターをフルトラッキング（全身）で動かしたい！」
「顔認証機能のあるiPhone/iPad使って表情も動かしたい！」

そんな方には【バーチャルモーションキャプチャー】+【waidayo】というアプリが手軽にできておすすめなので、その設定手順をご紹介します。

#下準備
###①iPhone/iPadをPCと同じネット環境につなげておきます
自宅でwifi接続している環境なら恐らくOKです

###②VR機材のセットアップを完了させておきます

#❶アバターをVRoidHubにアップロード
VroidHubはネット上のアバター置き場のようなサービスです。そこにアバターをアップします。

###1-1：[VRoidHub](https://hub.vroid.com/)にログイン・又は登録
※後々スマホ側でもログインするのでパスワード等を忘れないようにしましょう

###1-2：アバターをアップロード
![2021-02-21_13h37_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/585c4fc3-911c-7fa3-a8a7-7541e3d589e8.png)

![2021-02-21_13h41_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/1e3d1292-3d78-3cd3-a31e-47625df488f2.png)
非公開で登録すれば他のユーザーからは見えません


#❷iPhoneにwaidayoをインストール（起動）
###2-1:iPhone/iPadに[waidayo](https://apps.apple.com/jp/app/waidayo/id1513166077)をインストール→起動
###2-2:モデル読み込み
![名称未設定 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/bbda6db0-a25e-e7f5-c63f-a59dd0521183.png)



#❸バーチャルモーションキャプチャーをインストール（起動）
###3-1:PCに[バーチャルモーションキャプチャー](https://booth.pm/ja/items/999760)をDL→起動

###3-2:PC上からモデルを読み込み・又はVroidHub等から読み込み
![2021-02-21_14h49_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/a0424ee7-fc9c-601a-594a-f2cc7b58dba1.png)


###3-3:<font color="Red">waidayoを起動した状態で</font>OSCモーション受信を有効にする
![2021-02-21_14h50_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/a23fe5b6-5285-a4ab-657a-8e84f2393df3.png)

これで表情をキャプチャすることができます。

###3-3:キャリブレーション
![2021-02-21_15h21_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/0340d11b-68ed-e060-a3ee-f90eba45d365.png)
VR機器を起動している状態でキャリブレーションボタンを押せばキャラクターの身体を動かせるようになります。

▼僕の場合こんな感じでフルトラッキングしています。
<iframe width="560" height="315" src="https://www.youtube.com/embed/uUPeUEaZ7dc" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#補足

#❹指も動かしたい！
[ValveIndexのコントローラー](https://degicashop.com/products/valve-index-%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9
)を使用すれば指の動きも認識してくれます。
VIVEのベースステーション1.0でも問題なく使用できるので既にVIVEをお持ちの場合はコントローラーだけ追加すればOKです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Valve Index コントローラー使ってみた<br>実際に自分がとってる動きの再現度がレベルアップ💪<br><br> <a href="https://twitter.com/hashtag/%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%83%BC?src=hash&amp;ref_src=twsrc%5Etfw">#バーチャルモーションキャプチャー</a> <a href="https://t.co/4YCz5ljhfY">pic.twitter.com/4YCz5ljhfY</a></p>&mdash; ヤマグチ・V・タケヒロ (@take2_mbh) <a href="https://twitter.com/take2_mbh/status/1218180831736291328?ref_src=twsrc%5Etfw">January 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

###4-1:ショートカットキーの設定からValveIndex用のプリセットがあるので変更します。
そうすればコントローラーのスティック部分で表情を変更できます。
![2021-02-21_15h19_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/402b60b4-4d93-d594-42fb-c306cdad928f.png)


#各アプリの使い方(公式)
▼waidayo
https://github.com/nmchan/waidayo/wiki

▼バーチャルモーションキャプチャー
https://vmc.info/manual/
Pythonでモールス符号の日本語辞書作成

#はじめに
Pythonのモールス符号の日本語辞書を作成しました。
辞書の元にする情報はGoogleの[Google 日本語入力 - モールスバージョン](https://www.google.co.jp/ime/-.-.html)を参照させていただきました。

#基本方針
[Google 日本語入力 - モールスバージョン](https://www.google.co.jp/ime/-.-.html)の和文モールス符号表の<table>部分のHTMLソースコードをパースし、Pythonの辞書形式にする。

#パース関数
<table>には、'-'なら、class='dah', '.'なら、class='dit'となっている。
この点に着目し、パースする。

```python
def google_morse_parser(msg):
    parsed_dict = {}
    soup = bs(msg, 'html.parser')
    soup_td = soup.find('table').find_all('td')
    for i in soup_td:
        if i.text is not None:
            if '(' in i.text:
                key = i.text.split('(')[1].split(')')[0]
            else:
                key = i.text
            soup_span = i.find_all('span')
            value = ''
            for span in soup_span:
                dahdit = span.get('class')
                if dahdit == ['dah']:
                    value += '-'
                elif dahdit == ['dit']:
                    value += '.'
            parsed_dict[key] = value
    return parsed_dict
```

#出力結果
```python
{'ア': '--.--', 'イ': '.-', 'ウ': '..-', 'エ': '-.---', 'オ': '.-...', 'カ': '.-..', 'キ': '-.-..', 'ク': '...-', 'ケ': '-.--', 'コ': '----', 'サ': '-.-.-', 'シ': '--.-.', 'ス': '---.-', 'セ': '.---.', 'ソ': '---.', 'タ': '-.', 'チ': '..-.', 'ツ': '.--.', 'テ': '.-.--', 'ト': '..-..', 'ナ': '.-.', 'ニ': '-.-.', 'ヌ': '....', 'ネ': '--.-', 'ノ': '..--', 'ハ': '-...', 'ヒ': '--..-', 'フ': '--..', 'ヘ': '.', 'ホ': '-..', 'マ': '-..-', 'ミ': '..-.-', 'ム': '-', 'メ': '-...-', 'モ': '-..-.', 'ヤ': '.--', '': '', 'ユ': '-..--', 'ヨ': '--', 'ラ': '...', 'リ': '--.', 'ル': '-.--.', 'レ': '---', 'ロ': '.-.-', 'ワ': '-.-', 'ヰ': '.-..-', 'ヱ': '.--..', 'ヲ': '.---', 'ン': '.-.-.', 'ー': '.--.-', '゛': '..', '゜': '..--.', '、': '.-.-.-'}
```

#ソースコード
[GitHub: make_morse_dict.py](https://github.com/huwns/classical_cryptography/blob/master/make_morse_dict.py)

#参考文献
[Google 日本語入力 - モールスバージョン](https://www.google.co.jp/ime/-.-.html)
Dockerとはなにか

## 本記事の概要

この記事はDocker初学者の私が、Dockerの概要についてまとめた記事です。
学習に当たっては以下の書籍を参考にしました。

[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2/dp/4297100339)

コンテナ技術の概念から簡易的なWebアプリの構築等、実践的な内容まで含まれております。
また、DockerやKubernetesの設計や運用における勘所についても記載があり、勉強になる書籍でした。

##本記事で分かること
- コンテナ技術の概要
- Dockerとはなにか

##コンテナ技術の概要
Dockerの説明に入る前に、そもそもコンテナとは何かについて説明します。

コンテナとは仮想化技術のうちの1つです。
コンテナ以外の仮想化技術には、ホストOS型(Virtual Box等)、ハイパーバイザー型(ESXi等)があります。

図で表すとこうです。

####コンテナ型
![Container.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025854/be93b530-a7e3-be7e-b669-cc5fcea76c8e.jpeg)

####ホストOS型
![Host.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025854/1b22aa6a-37e7-a753-8f88-a0f4a2b1d612.jpeg)

####ハイパーバイザー型
![Hypervisor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025854/a500d7bf-7bcc-73b9-b480-d49df3545cd6.jpeg)

コンテナ型では仮想化ソフトウェアなしにOSのリソースを隔離し仮想OSにします。この仮想OSをコンテナと呼びます。
コンテナを作り出すためのオーバヘッドは、他の仮想化ソフトウェアと比較して少ないため、<b>高速に起動・終了ができ、必要なマシンリソースも少なくて済むことが特徴です。</b>

###コンテナ技術の歴史
コンテナ技術自体はDockerが台頭する前から存在しています。Dockerが登場する前はLXC(Linux Container)が有名でした。
DockerにはLXCと比較して以下の特徴があります。

- ホストに左右されない実行環境(Docker Enginによる実行環境の標準化)
- DSL(Dockerfile)によるコンテナの構成やアプリケーションの配置定義
- イメージのバージョン管理
- 差分ビルドが可能
- Dockerレジストリ(イメージ保管サーバのようなもの)

DockerではDockerfileによりコンテナ情報をコードで管理できます。そのため環境の再現性を保ちやすいことが特徴です。また、Docker以前はアプリケーションをホストOSもしくはゲストOS上へデプロイしていたため、デプロイ先の実行環境(OS)への依存度が高かったです。
しかしDockerでは、実行環境を同梱してデプロイするため依存問題を解消しています。

###Dockerとはなにか
アプリケーションを開発、移動、実行するためのプラットフォームです。
アプリケーションをインフラから分離し、アプリケーションを扱うようにインフラを扱えます。
具体的にはDockerfileと呼ばれるファイルで、コンテナの環境設定をコードで記述、管理します。

####Docker Enginとは
Docker Enginとは、ざっくりいうとコンテナを管理するための仕組みです。
もう少し詳しく言うと、3つのコンポーネントで構成されるクライアント / サーバー型アプリケーションであり、dockerクライアント、dockerデーモン、REST APIで構成されます。

![DockerEngin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025854/1788aeb9-9d22-20b2-a847-389ab819b07e.jpeg)
dockerクライアントにて、コンテナの構築などを実行するためにはdockerデーモンと通信します。その通信をREST APIを通じて行います。

####Dockerが動く仕組み
dockerクライアントとdockerデーモンが通信することで動くわけなのですが、もう少し詳しく見てみます。
コンテナを構築するためにはイメージと呼ばれるテンプレートが必要です。例えば、Ubuntuの上にApacheをインストールしてWebサーバーを構築するとします。その際必要なUbuntuとApacheのイメージをレジストリと呼ばれるイメージの保管サーバからダウンロードし、コンテナを構築します。

![Docker_Architecture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025854/a089a09a-ea32-497e-2cc3-f2466981dfb4.jpeg)

パブリックなレジストリとしては[Docker Hub](https://hub.docker.com/)があり、多種多様なイメージが存在します。
プライベート環境にレジストリが必要な場合は、[Docker Registry](https://docs.docker.com/registry/)を使うといいでしょう。
【備忘録】動的型付けと型推論の違い

# はじめに
C#を勉強してると、
「varって動的型付けじゃないの？」
↓
「C#だとdynamicが動的型付けで、varは型推論なんだ」
↓
「てか、動的型付けと型推論って違うのか！」
となり、違いを理解していなかったので調べてみました。
ざっくりとした説明なので、詳しく知りたい人は自分で調べてちょ。

# 動的型付け
実行時(Console.Write時)に型が決定されます。なので、下記のようになります。

```c#
// C#
dynamic x = 100  // 動的型付けにより、変数xの型が数値型に決定する
x = "Hello World !"  // 型が動的に決定されるので、エラーがにならず変数xの型が文字列型になる

Console.Write(x)  // 「Hello World !」が表示される
```

# 型推論
コンパイル時(上からコードが読み込まれる時)に型が決定されます。

```c#
// C#
var x = 100  // Int型を指定しなくても、代入される値からコンパイラが変数xの型を自動で決定する(型推論)
x = "Hello World !"   // 型推論によりxがInt型に決定されているため、Int型以外を代入するとコンパイルエラーが発生

Console.Write(x) // コンパイルエラーのため実行できない
```
# 補足
しかしながら、あくまで型推論である var と違って、dynamic で宣言した変数の型は「動的型」になります。

```c#
var sx = 1;     // sx の型は int 型
dynamic dx = 1; // dx の型は dynamic 型
```
【Rails】RSpecでDeviceメール認証をクリアする方法

## 実装例
userのサンプルデータを作成する段階で認証済にします。
factorybotのuser do内に追記するのみで、
テストコードには変更を加えませんので汎用的に使えるかと思います。

```ruby:factorybot.rb
FactoryBot.define do
  factory :user do
    :
    :
    #下記1行を追加するだけ
    confirmed_at { Date.today }
  end
end
```
この状態でfactorybotを実行すれば
メール認証済の状態でサンプルデータを作ることができます。
参考：[github.com/henrydjacob](https://gist.github.com/henrydjacob/1344451)

## その他の解決方法
テストコード内のbefore処理に記述する方法もありました。
参考：[Rspecのrequest(Integration test)でDeviseのメール認証を回避する方法](https://qiita.com/gakkie/items/9346f53a501bf36d019b)
Qt上に書けるHTML上のimgタグでネット経由の画像を表示する

※筆者が書ける言語の都合上、PyQtでやってますが、Qtでも同じようにできると思います。

## Qtではインターネット上の画像を取得することはできない
Qt上でHTMLを記述し、色々な装飾を施せることを知っている人は割と多いと思います。
Qt上で画像を表示するにはQPixmapをQLabelに埋め込むのが一般的(私だけ?)だと思いますが、実はHTMLのimgタグを用いても表示できます(ちょっと操作が面倒くさいかもしれませんが)。
しかし、Qt自体は外部との通信機能を持っているわけではないので、例えば以下の画像を

![image.png](https://raw.githubusercontent.com/atomicswap-network/atomicswap-qt/sechack365-demo/atomicswap/qt/icons/atomicswap-qt.png)

```html
<img src="https://raw.githubusercontent.com/atomicswap-network/atomicswap-qt/sechack365-demo/atomicswap/qt/icons/atomicswap-qt.png"/>
```

のように画像を埋め込もうとしても、以下のように失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535794/2118e82c-fd51-3b65-ae16-c6fec083d9ff.png)

ちなみにローカルの画像を埋め込む分には相対パスでできます。

## だったら画像取得だけ別のライブラリに任せればいいじゃない
pythonには`requests`という便利なライブラリがあるわけですから、そこに画像取得を任せてしまえばいいのです。
また、HTMLではbase64を用いてバイナリを埋め込むことができます。便利ですねー。
というわけで以下のようにすれば行けます。

```python
import requests
import base64

from PyQt5.QtWidgets import QLabel
# =====中略=====
    self.image = str(
        base64.b64encode(requests.get("https://raw.githubusercontent.com/atomicswap-network/atomicswap-qt/sechack365-demo/atomicswap/qt/icons/atomicswap-qt.png").content)
    )[2:]  # バイナリをstrでキャストすると頭に"b'"がつくのでそれを取り除く。もっといい方法ないのかな...
    self.label = QLabel(f"<img src=\"data:image/png;base64,{self.image}\"/>")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535794/0903f147-7932-58e4-6c76-e7ef3d8ea3d5.png)

## こんなことするなら普通に埋め込めばいいのでは...使いどころは...
おっしゃる通りです。
でも、HTMLしか書けないところで役に立ちます。例えばaboutダイアログとか。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535794/0c8e3a90-2fb0-b443-b331-29f1a029f1b8.png)](https://qiita.com/y-chan/items/f69b628f65ce12097e4a)
(ガバガバ英語は温かい目で見逃して...)
Pythonでモールス符号

#はじめに
モールス符号に関するPythonを検索しても、日本語対応のものはあまりなかったため、日本語対応のものを作成しようと考えた。
日本語の辞書作成部分については、別途執筆する予定である。ソースコードはGitHubに載せてある。
また、音を実際に出しているものもなかったため、音も出してみた。周波数や間隔などはお好みで調整してほしい。

#基本方針
モールス符号の辞書に従い、符号化する。
日本語に対応するために、濁点の分離やひらがなをカタカナに統一する（日本語の辞書はカタカナで作成したため）機構を用意した。

#コード抜粋
```python
def morse_encode(msg, morse_dict) -> list:
    encoded_lst = []
    for i in msg.upper():
        if i in morse_dict:
            encoded_lst.append(morse_dict.get(i))
        else:
            encoded_lst.append('[ERROR]')
            print('ERROR: ', i, 'is not in the dictionary.')
    return ' '.join(encoded_lst)

def morse_decode(msg, morse_dict) -> str:
    decoded_msg = ''
    reverse_morse_dict = dict((v,k) for (k,v) in morse_dict.items())
    for i in msg.split(' '):
        if i in reverse_morse_dict:
            decoded_msg += reverse_morse_dict.get(i)
        else:
            decoded_msg += '[ERROR]'
            print('ERROR: ', i, 'is not in the dictionary.')
    return decoded_msg

def dakuten_separator(msg):
    bytes_text = unicodedata.normalize('NFD', msg).encode()
    bytes_text = re.sub(b'\xe3\x82\x99', b"\xe3\x82\x9b", bytes_text)
    bytes_text = re.sub(b"\xe3\x82\x9a", b'\xe3\x82\x9c', bytes_text)
    return bytes_text.decode()

def morse_sound(morse):
    for i in morse:
        if i == '-':
            Beep(300, 75*3)
        elif i == '.':
            Beep(300, 75)
        else:
            sleep(0.075)
```

#ソースコード
[GitHub: morse.py](https://github.com/huwns/classical_cryptography/blob/master/morse.py)
[GitHub: make_morse_dict.py](https://github.com/huwns/classical_cryptography/blob/master/make_morse_dict.py)
【Rails】envメゾッドで開発、本番、テスト環境での挙動をわける方法

## Railsで用意されているenv
+ produciton（本番環境）
+ test(テスト環境)
+ development（開発環境）

## 実装例
Rails.env.development?と記述すれば開発環境の場合の処理を記載できます。
例えば、例外処理で下記のような記述を行った場合は、開発環境以外でのみ読み込まれる。
参考：[Rails 5の404/500エラーページ、簡単作成手順](https://morizyun.github.io/blog/custom-error-404-500-page/index.html)

```ruby:controller/application
#開発環境ではない場合に読み込む
unless Rails.env.development?
  rescue_from ActiveRecord::RecordNotFound, with: :render_404
  rescue_from ActionController::RoutingError, with: :render_404
  rescue_from Exception, with: :render_500
end
```
しかし、このままだと、本番環境のみでなく、テスト環境でも読み込まれるため、
RSpec等実行する際のエラー文を読み込めない場合があります。
下記のような記述にすれば解決。

```ruby:controller/application
#開発環境またはテスト環境ではない場合に読み込む
unless Rails.env.development? || Rails.env.test?
  rescue_from ActiveRecord::RecordNotFound, with: :render_404
  rescue_from ActionController::RoutingError, with: :render_404
  rescue_from Exception, with: :render_500
end
```

同じ要領で下記のように使うことも可能。

```ruby:controller/hoges_controller
    # 本番環境で使っているMySQLではRANDOMが使えずRANDが必須
    if Rails.env.development? || Rails.env.test?
      # SQLite(開発、テスト環境ではRANDOM)
      @hoges = Answer.order("RANDOM()").limit(3)
    else
      # mySQL対応(本番環境ではRAND)
      @hoges = Answer.order("RAND()").limit(3)
    end
```

## さいごに
RANDOMの例で記載した、unless Rails.env.development? || Rails.env.test?
という記述は、元々if Rails.env.production?　とelse記述していたところ、
本番環境でもdevelopmentの方が読み込まれてしまい修正した経緯があります。
（いずれもほぼ同じ意味という認識で実行したのですが、、）
もし原因分かる方がいらっしゃいましたらご教示いただけますと幸いです。
GASは使わない！スプレッドシートの関数だけでInstagramのフォロワー数を取ってくる

# はじめに
こんにちは。WealthNaviを初めて18カ月経ち、20%を超えたので全額出金手続きに踏み切りました、筆者です。
今後は手動でポートフォリオ作ってインデックス投資していこうと思います。

さて、Instagramのフォロワー数を取りたい機会がありました。

でも**`Instagram Graph API`**の審査通すの大変なのを知ってます:thinking_face:

もっと簡単に取りたい...！

そんな方に、邪道ですが、スプレッドシートの関数だけで取ってみたいと思います。

実行は自己責任でお願いします:bow:


# 結論: これで取れます:+1:
```js
=REGEXEXTRACT(join(",",IMPORTDATA("https://www.instagram.com/graphql/query/?query_hash=37479f2b8209594dde7facb0d904896a&variables=%7B%22id%22%3A%228439550463%22%2C%22first%22%3A24%7D")),"\d+")
```

# 解説
まず、今回取得したフォロワー数は、**いきものがかり**のボーカル、**吉岡聖恵**さんの通称、**ちゃんきよ**のInstagramのアカウントです :smile:

## ユーザ情報取得URLを生成
URLの生成は**[こちら](https://qiita.com/Yu2yasui/items/ee04b10961f65384c6ca)**を参考にしました。

```
https://www.instagram.com/graphql/query/?query_hash=37479f2b8209594dde7facb0d904896a&variables=%7B%22id%22%3A%22{{ 
user_id }}%22%2C%22first%22%3A24%7D
```

## スプレッドシートの関数「IMPORTDATA」でcsv形式として取得
```js
IMPORTDATA(URL)
```

## スプレッドシートの関数「JOIN」で文字列結合
```js
JOIN(",", IMPORTDATA(URL))
```

## スプレッドシートの関数「REGEXEXTRACT」で数字列を取得
```js
REGEXEXTRACT(JOIN(",", IMPORTDATA(URL)), "\d+")
```

# おわりに
厳密にはAPIの返り値からkey指定して取るべきなのですが、えいやで取るならこれでも取れます。
あくまで、へー :thinking: くらいに見ていただけると幸いです。

ちゃんとやるには**`Instagram Graph API`**の申請しましょう:pray:
BuffaloのWi-Fiルーターで電波が安定しない時の対処法(WSR-5400AX6)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/6c4ea91b-4899-1107-bc1c-cca9815fdd98.png"width=80%>

#Wi-Fiが安定しない...!!!
この記事では、BuffaloのWi-Fiルーターで以下の問題が起きた時の対処法をまとめております。
・Wi-Fiルーターの電源はついているのに、スマホやPC上に表示されない
・スマホやPC上に表示はされるが、繋ごうとしてもインターネットに接続できない
・インターネットに繋いで、しばらく時間が経つと途切れてしまう
・2.4GHz帯(Buffalo-G)は安定しているが、5Ghz帯(Buffalo-A)の電波が不安定（勝手に2.4GHz帯に切り替わる）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/5e04ff75-9eb6-5ee2-e175-0e4145317ef3.jpeg"width=70%>

#対処の手順
STEP1: Buffaloの「StationRadar」という公式アプリをダウンロードします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/a00110ad-d6d1-28c1-8c21-4829ac60d2c2.jpeg"width=70%>
STEP2: アプリを開いて、使用しているWi-Fiルーターを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/a6cc78f0-fc0d-85c0-e313-07e8721396aa.jpeg"width=70%>
STEP3:「設定画面を表示する」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/0afa47d0-42fb-b3b6-3f36-5eae1a344f77.jpeg"width=70%>
ログインすると、使用しているWi-Fiルーターの設定の確認や変更ができるページに飛びます。
ログインIDとパスワードは、機器の本体または付属のカードに記載されています。
STEP4: 無線LANを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/de0596e5-d157-9acd-e8ad-b51d0380dea2.jpeg"width=70%>
ページ最下部の「チャンネル」が、デフォルトで「自動」に設定されていると思います。
実は、電波が安定しない原因はこれです。周囲に多くの電子機器がある場合、適切にチャンネルを設定できず、電波干渉が発生して転送速度が低下してしまいます。特に5GHz帯は干渉に弱いので、周囲から影響を受けると自動で2.4GHz帯に切り替わってしまいます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/c68d838f-e26b-e0de-b271-1e35fd42f803.jpeg"width=70%>
STEP5: チャネルを「48」に変更します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/991191/ff7f9cb1-f123-089d-d376-8badde43aa5f.jpeg"width=70%>
これで問題が解決しました！！スッキリ！
参考になりましたら「LGTM」を押して頂けると嬉しいです！

---
動作確認
Wi-Fiルーター
・Buffalo WSR-5400AX6
端末
・iPhone X (iOS 14.4)
・MacBook Air (Apple Silicon M1チップ / 2020 /macOS Big Sur)
[Angular] ESLint環境にPrettierを導入する

## はじめに

Angular ESLint環境にPrettierを導入する方法について記載します。</br>
Angular TSLint環境からESLintへの移行はこちら</br>
=>[[Angular] TSLintからESLintに移行する](hhttps://qiita.com/reriiasu/items/8f193684349cce1ed62a)
</br>
2021/02/23 eslint-config-prettier: 8.0.0の設定方法に修正

2021年2月時点

## 簡単な説明

### Prettierとは

コードフォーマッター</br>
多くの言語をサポートしている。

## 何故Prettierを導入するのか？

1. コーディングに集中できる。
    - コードフォーマットの修正に時間を割かなくてよい。
1. コードのフォーマットが統一できる。
1. コードレビューの効率化ができる。
   - スペースを空けた、空けないなどのフォーマット変更に伴う不必要な差分が発生しないため、ロジック修正へのレビューに注力できる。

## ライブラリのバージョン

- eslint-config-prettier: 8.0.0
- prettier: 2.2.1

### eslint-plugin-prettierについて

>When searching for both Prettier and your linter on the Internet you’ll probably find more related projects. These are generally not recommended, but can be useful in certain circumstances.
>
>First, we have plugins that let you run Prettier as if it was a linter rule:
>
>eslint-plugin-prettier
>
>[https://github.com/prettier/prettier/blob/main/docs/integrating-with-linters.md](https://github.com/prettier/prettier/blob/main/docs/integrating-with-linters.md)

eslint-plugin-prettierは、非推奨となっている。

1. コーディングに集中できない。
    - ESLint経由での実行となるため、lintエラーとして赤線が表示される。
    - 結果、オートフォーマットされるにも関わらず修正行為を行う可能性がある。

2. Prettierを直接実行するよりも遅い。
3. 連携することにより、コード破壊のリスクがある。

## ライブラリのインストール

``` shell
# 必要なパッケージのインストール
$npm install -D eslint prettier@latest eslint-config-prettier@latest
```

## .eslintrc.jsonの変更

``` .eslintrc.json
{
    "extends": [
        // extendsの一番下に下記を追加
        "prettier"
    ]
}
```

- eslint-config-prettier: 8.0.0からprettierを追加するだけでよくなった。

## VSCode extensionのインストール(VSCodeの場合)

- [Prettier Formatter for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

### VSCodeの設定

- 保存時にフォーマットを行う(言語指定なし)

``` settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}
```

- 保存時にフォーマットを行う(言語指定ありの例)

``` settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": false,
  "[javascript]": {
    "editor.formatOnSave": true
  },
  "[typescript]": {
    "editor.formatOnSave": true
  },
}
```

## 動作確認

- 保存前

``` ts
export class AppComponent {
  constructor() {
    const hoge = ''}
}
```

- 保存後
  - コードのフォーマットを確認

``` ts
export class AppComponent {
  constructor() {
    const hoge = '';
  }
}
```

## 参考

[https://github.com/prettier/eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)