OmniAICreator/Qiita-1.07M huggingface dataset:
【VBA】文字列をカンマ区切りで配列に変換

```vb
Sub aaa()
    myRange = Range("A1", "A2")
    arr = WorksheetFunction.Transpose(myRange)
    For i = 1 To UBound(arr)
        '''
        spli = Split(arr(i), ",")
        Data = "0x06, 0x46, 0x05, 0x22, 0x03, "
        s = Data
        For c = 0 To UBound(spli)
            s = Replace(s, (spli(c) + ","), "")  '"[値],"を削除
            s = Replace(s, "  ", " ") '"  "(半角スペースが2つ)なら1つに変換
            If InStr(s, " ") = 1 Then s = Right(s, Len(s) - 1) '先頭が" "(半角スペース)なら削除
        Next
        If InStrRev(s, " ") - Len(s) = 0 Then s = Left(s, Len(s) - 1) '末尾が","(カンマ)なら削除
        If InStrRev(s, ",") - Len(s) = 0 Then s = Left(s, Len(s) - 1) '末尾が" "(半角スペース)なら削除
        Debug.Print (s)
        '''
    Next
End Sub

```


>参考
http://officetanaka.net/excel/vba/tips/tips62.htm
https://kosapi.com/post-2305/
PRML 演習問題2.58 解答

##問題
>(2.226)は指数型分布族では$\mathbf{lng(\eta)}$の負の勾配が$\mathbf{u(x)}$の期待値を示している.(2.195)の2階微分を取ることで

```math
\begin{align*}
\mathrm{-{\nabla}lng(\eta)=E[u(x)u(x)^T]-E[u(x)]E[u(x)^T]=cov[u(x)]}
\tag{2.300}\\
\mathrm{g(\eta){\int}h(x)exp\bigl\{\eta^Tu(x)\bigr\}dx=1}
\tag{2.195}
\end{align*}
```
を示せ.

##方針
(2.195)の2階微分を行うが、一階微分の値が(2.226)で示されているので(2.226)を微分して上記を示す.

```math
\begin{align*}
\mathrm{-\frac{1}{g(\eta)}{\nabla}g(\eta)=g(\eta){\int}h(x)exp\bigl\{\eta^Tu(x)\bigr\}u(x)dx=E[u(x)]}
\tag{2.225}\\
\mathrm{-{\nabla}lng({\eta})=E[u(x)]}
\tag{2.226}
\end{align*}
```

##解答

```math
\begin{align*}
(2.225)と(2.226)から\\
\mathrm{-{\nabla}lng({\eta})=g(\eta){\int}h(x)exp\bigl\{\eta^Tu(x)\bigr\}u(x)dx}\\
\end{align*}
```

よって

```math
\begin{align*}
\mathrm{-{\nabla\nabla}lng(\eta))={\nabla}g(\eta){\int}h(x)exp\bigl\{{\eta}^Tu(x)\bigr\}u(x)^Tdx+g(\eta){\int}h(x)exp\bigl\{\eta^Tu(x)\bigr\}u(x)u(x)^Tdx}
\end{align*}
```
右辺の第1項を式変形すると

```math
\begin{align*}
\mathrm{{\nabla}g(\eta){\int}h(x)exp\bigl\{{\eta}^Tu(x)\bigr\}u(x)^Tdx}&=
\mathrm{{\nabla}g(\eta)*g(\eta){\int}h(x)exp\bigl\{{\eta}^Tu(x)\bigr\}u(x)^Tdx}\\
&=\mathrm{{\nabla}lng(\eta)*E[u(x)^T]}\\
&=\mathrm{-E[u(x)]*E[u(x)^T]}
\end{align*}
```

したがって

```math
\begin{align*}
\mathrm{-{\nabla\nabla}lng(\eta)=-E[u(x)]*E[u(x)^T]+E[u(x)u(x)^T]=cov[u(x)]}
\end{align*}
```

よって題意は示された
【Unity】汎用Animatorを色々なキャラクターに適用させる方法

# 想定環境

- Unity5以上

# 概要

　**Unity標準のAnimator、分かりにくくないですか？**
　ステートベースで直感的にアニメーション遷移を作れる！最高！と思いきや、以下のような、グロいAnimatorを作ってしまうのは割とあるあるだと思います。

![スクリーンショット (222).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/11b0a313-f38c-6e93-26c3-1a3dcdd20e57.png)

　しかも、Animatorは基本的に一つのキャラに一つずつ必要になります。ポチポチとステートを作り、そのステートにアニメーションを当てはめ、という作業を全キャラ分・・・。軽く死ねますね。

　というわけで、複数キャラに跨って使いまわせる汎用Animatorを作るテクニックの紹介です。（私の知っている限りUnity5系のころには標準搭載している機能なのですがあまり知られていないっぽい？ので記事化してみました。）

# Animator Override Controllerを使おう！

　はい、実はこんな便利なものがあります。使い方は[公式リファレンス](https://docs.unity3d.com/ja/2018.4/Manual/AnimatorOverrideController.html)が十分丁寧に教えてくれているのでリファレンス見てね、で終わりなんですが、一応知見をここにまとめておきます。

　名前の通り、こいつは「**あるAnimatorをベースにして、そのステート内で再生するアニメーションを任意のアニメーションで上書きすることができる**」というものです。

　実際に作りながら解説してみます。

### １.ベースとなるAnimatorを普通に作る

　まずベースとなるAnimatorを用意します。

![スクリーンショット (226).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/1277142e-5175-e6e9-dc4e-004730e8a688.png)

　キャラによっては歩きモーションや攻撃モーションを複数持つことも考えられるので、A,B,Cといったようにとりあえず用意だけしておきます。
　このAnimatorは、あくまでベースなので、実際にAnimationをあてがう必要はありません。ステートマシンの遷移部分だけ作っておけばよいのです。

### 2. Animator Override Controllerを作る

　ベースを作ったので、次に実際のキャラクターに使用するAnimatorを作ります。
[公式リファレンス](https://docs.unity3d.com/ja/2018.4/Manual/AnimatorOverrideController.html)に記述してあるように、Create -> Animator Override Controller を選択します。

![スクリーンショット (227).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/17391c71-3150-504f-b140-30f949785223.png)

　すると、Animatorに似ているようで微妙に違うアイコンのアセットが作られます。これは実際のキャラに使用するAnimatorとなるので、きちんと命名しましょう。今回はゾンビに使いたいので、ZombieAnimatorとしました。

![スクリーンショット (228).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/d7a3576f-f2a5-0f05-8f5a-17918740e9e6.png)

### 3. Inspectorで設定する

　Inspectorを見てみましょう。

![スクリーンショット (229).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/bf5309fa-2c69-ac9d-83eb-bb15ef43605f.png)

このような画面になっていると思います。
**Controller**の部分に、ベースとして用意しておいたAnimatorをドラッグアンドロップなどで参照します。
するとこのような画面になります。

![スクリーンショット (230).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/afe8bde3-5b5d-d493-f130-0d3f5ac70f14.png)

Original の列には、ベースとなる Animator のステートに参照されている Animation 名が表示されます。
Override の列に、その Animation と対応する Animation をドラッグアンドドロップなどで参照できます。

対応する Animation が無ければ、None のままで構いません。

![スクリーンショット (231).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/b55abd06-d028-c99c-ede5-cfc3911e82a4.png)

**以上です。**

これで、ステートマシンを使いまわしつつ、別々のアニメーションをするキャラクターを簡単に量産できます。

![AnimatorOverride.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157326/2d03efb6-4b5b-6e2d-117d-f337838d03f0.gif)

はい、ちゃんと女ゾンビも男ゾンビも同じステートマシンで動いてますね。

　ちなみに導入の際の注意ですが、さすがにステートマシンの遷移を Override側で変更などはできないので、遷移の体系が違うものを作る場合は、その都度 Animator を新規作成する必要があります。

以上、小ネタでした。

# 宣伝

　本稿は現在絶賛公開中のスマホゲーム『たのしいさんすう』の開発で実際に使っているテクニックを紹介しています。ぜひぜひ、お手に取ってたくさんのゾンビたちと戯れていただければ幸いです。

【たのしいさんすう】
iOS: https://apps.apple.com/us/app/zombie-mathters/id1504347831?l=ja&ls=1
Android: https://play.google.com/store/apps/details?id=com.gamebox.sansuu
ディレクター様: https://twitter.com/gamebox7777
筆者: https://twitter.com/john95206
WSL2を有効にしてwindows dockerとVMware15.5.5を共存させる

# 概要
docker起動したままVMwareを使おうとしたとき、「Hyper-V または Device/Credential Guard が有効な状態で～」と言われてVMwareが起動しなかったが、以下の記事を見つけたが、複数の対応が必要で解決まで辿った道のりを記録します。

「VMware Workstation/Player」が「Hyper-V」と共存可能に ～v15.5.5が正式公開
https://forest.watch.impress.co.jp/docs/news/1255681.html
※2020年5月27日投稿の記事

環境により対応内容が違うと思いますので、エラーメッセージから対応内容を参考にするまでにして下さい。

私自身分からない事も多いですが、また迷うと勿体ない為分かっていることだけ記事にしておきます。


## 最終環境
docker desktop 2.3.0.3(45519)
windows10 version2004
VMware15.5.5

# 各エラー(または要件)対応方法

## windows10のバージョンが1904

2020/06/03時点では

下記サイトにいって
https://www.microsoft.com/ja-jp/software-download/windows10
アップデート実行ファイル（Windows10Upgrade9252.exe）をダウンロードしてを実行する
※こちらの環境では約3時間くらい



## dockerでWSL 2 is not installedと表示される。

PowerShellを管理者で起動する
```
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

## wsl --set-default-version 2が実行できない①
```
PS C:\WINDOWS\system32> wsl --set-default-version 2
wsl : 用語 'wsl' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。
```
Microsoft Store からlinux ディストリビューションを Windows 10 にセットアップする

参考
https://qiita.com/zembutsu/items/22a5cae1d13df0d04e7b#linux-%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97

## wsl --set-default-version 2が実行できない②
```
PS C:\WINDOWS\system32> wsl --set-default-version 2
WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
```

下記サイトにいって
https://aka.ms/wsl2kernel
wsl_update_x64.msiをダウンロードして実行（1分もかからない）


# 解決
```
PS C:\WINDOWS\system32> wsl --set-default-version 2
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
```


# 参考

参考にさせて頂きました。

WSL 2 対応 Docker Desktop for Windowsを使うための手順
https://qiita.com/zembutsu/items/22a5cae1d13df0d04e7b

WSL2を操作しようとすると「カーネル コンポーネントの更新が必要です」と表示される
https://qiita.com/quzq/items/3de595e14426d0352fc4
古い Xcode で新しい iOS バージョンにビルド

Macbook が古すぎて、最新の Xcode がインストールできなくなったため、新しい iPhone にアプリをインストールすることもできなくなった、困ったな。

## でも。。。大・丈・夫


## 新しい Xcode をダウンロード
[https://developer.apple.com/download/more](https://developer.apple.com/download/more) から新しい Xcode をダウンロードします。例えば、`Xcode 11.5`

## Device Support フォルダのリンクを作る
ダウンロードしたファイルを解凍し、`/Applications/Xcode_11.5.app`に移動後、下記コマンドでリンクを作ります。

```sh
ln -s /Applications/Xcode_11.5.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.5 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.5
```

## Xcode 再起動
これから、新しい iOS にビルドできます。
GoogleMapsAPIのJavaSDKを使って、逆GeoCodingの結果を日本語で取得する。

# はじめに
GoogleMapsAPIを使って、緯度経度から住所を取得する処理を書きました。
GoogleからJavaのSDKが提供されています。
日本語で住所を返す設定のメモ書きです。

# JavaのSDK
- Java Client for Google Maps Services

https://github.com/googlemaps/google-maps-services-java

# ソースコード

```java
    public String reverceGeocoding(double lat, double lon) {
        LatLng latlng = new LatLng(lat, lon);

        GeoApiContext context = new GeoApiContext.Builder().apiKey(apikey).build();
        GeocodingApiRequest request = GeocodingApi.reverseGeocode(context, latlng).language("ja");
        GeocodingResult[] results;
        String address = null;
        try {
            results = request.await();
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            address = gson.toJson(results[0].formattedAddress);
        } catch (ApiException | InterruptedException | IOException e) {
            e.printStackTrace();
        } finally {
            context.shutdown();
        }
        return address;
    }

```

# おわりに
作ってしまえばなんてことないのですが、languageの指定方法は調査しました。覚え書きとして残しておきます。
Unityでマウスの動きに合わせてGameObjectを動かす方法

# はじめに
こんな感じのものを作ります

![movie1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103774/4617ab6d-4fc2-450b-ea40-21bf51cb87ef.gif)

# ステップ
1. 動かしたいGameObjectを作成します
2. 「MouseChase.cs」の名前でC#スクリプトを生成します
3. 2のスクリプトを1のGameObjectにアタッチします

# スクリプト
```MouseChase.cs
using UnityEngine;

public class MouseChase : MonoBehaviour
{
	/// <summary>
	/// Update
	/// </summary>
	void Update()
	{
		transform.position = Input.mousePosition;
	}
}
```

# 補足

```
transform.position = Input.mousePosition;
```
上記の箇所ですが、以下のように書くこともできます

```
gameObject.transform.position = Input.mousePosition;
```
違いは参考のURLにて詳しく書いてますので、参考にしてみてください
上の記述のほうが早いようです

# 参考
[gameObject.GetComponent<Transform>() と transform の違い（または Unity における省略記法について）](https://qiita.com/megane42/items/9709d696e8f2561dbb1d)
Rails 5.2/6.0 で MessageEncryptor を使うときは初期化タイミングに気を付けよう

Rails 5.2 から `ActiveSupport::MessageEncryptor` のデフォルト暗号方式が `aes-256-cbc` から `aes-256-gcm` に変更となった。しかし、初期化タイミングによっては意図しない暗号方式を使うことになる場合があるため紹介する。

# Rails 5.2

以下のバージョンで確認：

- Ruby 2.6.5
- Rails 5.2.4.3

## デフォルト

まず `rails console` でデフォルト暗号方式を確認する。

```irb
irb> encryptor = ActiveSupport::MessageEncryptor.new 'key'
=> #<ActiveSupport::MessageEncryptor:0x0000561c2eae8940 @secret="key", @sign_secret=nil, @cipher="aes-256-gcm", @aead_mode=true, @verifier=ActiveSupport::MessageEncryptor::NullVerifier, @serializer=Marshal, @options={}, @rotations=[]>
irb> encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"
```

確かに `aes-256-gcm` であることがわかる。

## 実例

実際のアプリケーションでは、なんらかのモデルに持たせておいて利用することもあるだろう。

```ruby:app/models/some_model.rb
class SomeModel < ApplicationRecord
  class << self
    attr_reader :encryptor

    def set_key(key)
      @encryptor = ActiveSupport::MessageEncryptor.new key
    end
  end

  set_key 'x' * 32
end
```

これも同じように確認してみる。

```irb
irb> SomeModel.encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"
```

問題なさそうに見える。

## 問題例

ところが、 `MessageEncryptor` の初期化タイミングが早すぎると、異なる暗号方式になってしまう。例えば `after_initialize` コールバック内で `SomeModel` 定数が参照されていると、そのタイミングでオートロードされ、 `MessageEncryptor` が生成されることとなる。

```ruby:config/application.rb
class Application < Rails::Application
  config.load_defaults 5.2
  config.after_initialize do
    SomeModel
  end
end
```

```irb
irb> SomeModel.encryptor.instance_variable_get '@cipher'
=> "aes-256-cbc"
```

`aes-256-gcm` ではなく `aes-256-cbc` となってしまった。

## 原因

ことの問題は `Rails.application.config.active_support.use_authenticated_message_encryption` の設定反映のタイミングにある。この設定値は過去バージョンとの互換性のために設けられており、 `false` に設定することでデフォルト暗号方式を `aes-256-cbc` に戻すことができる。本設定値は Rails 5.2 としてはデフォルト `true` ではあるが、この設定値が `config.after_initialize` 実行時点ではまだ反映されていないようなのだ。従ってこのタイミングで初期化してしまうと、 `MessageEncryptor` 自身のデフォルトである `aes-256-cbc` となってしまう。

該当コードはこのあたりである。

https://github.com/rails/rails/blob/v5.2.4.3/activesupport/lib/active_support/message_encryptor.rb#L88

## 解決例

初期化が早すぎるのが問題なので、実際の利用タイミングまで遅らせることが考えられる。

```ruby:app/models/some_model2.rb
class SomeModel2 < ApplicationRecord
  class << self
    def set_key(key)
      @key = key
    end

    def encryptor
      @encryptor ||= ActiveSupport::MessageEncryptor.new @key
    end
  end

  set_key 'x' * 32
end
```

```ruby:config/application.rb
config.after_initialize do
  SomeModel2
end
```

これでほとんどの場合 `aes-256-gcm` が利用できる。

```irb
irb> SomeModel2.encryptor.instance_variable_get '@cipher'
=> "aes-256-gcm"
```

ただし、 `MessageEncryptor` を利用したいタイミング自体が `use_authenticated_message_encryption` の設定反映前である場合は、これでも解決とはならない。そのときは `MessageEncryptor.new` に `cipher:` オプションを明示するのが良いだろう。

# Rails 6

以下のバージョンで改めて調査したが、同じ状況になるようだ。

- Ruby 2.7.1p83
- Rails 6.0.3.1

5.2 と少し事情が違うのは、デフォルトのオートローダーが Zeitwerk となり `config/initializers/*.rb` で各モデルをオートロードするのが非推奨となった点だ。このため `config/initializers/*.rb` でうっかりモデルを参照してしまった場合は、警告メッセージにて検出が可能となっている。しかしながら本記事での例のように、 `config.after_initialize` では警告はないようだ。

Rails では各ファイルは必要に応じてロードされるが、そのタイミングはときに分かりづらいこともある。ロードタイミングによって問題が発生することもあるので気を付けよう。
[Mac]PHPで「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib」エラーの対処法

Macで作業していたら、ある日突然PHPがエラーを吐いて動かなくなったので、対処法を残しておきます。

# 環境
MacOS Catalina version 10.15.4
PHP 7.2 *brewでインストールしたやつ

# エラー内容

`php -v`コマンドを実行すると以下の様なエラーになりました。

```
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
  Referenced from: /usr/local/opt/php@7.2/bin/php
  Reason: image not found
zsh: abort      php -v
```

# 対処法

原因は、libicui18n.64.dylibのモジュールが読み込めていない様子。
PHPの場合は、バージョン指定をして再インストールすることで解決しました。

```
brew reinstall php@7.2
```
[Flutter] ListView.separated() で、一番最後にDivider()を表示する

`ListView.separated()` はアイテム間に区切りを表示できて便利だが、一番最後にも区切りを表示したい時がある。

## やり方
`itemCount`を項目数+1しておき、`itemBuilder`で`index==<項目数>`となったとき、区切りを返す。

```dart
ListView.separated(
  itemBuilder: (BuildContext context, int index) {
    if (index == items.length) {
      return const Divider(
        height: 1,
      );
    }
    return ListTile(
      title: items[index].title,
    );
  },
  separatorBuilder: (BuildContext context, int index) {
    return const Divider(
      height: 1,
    );
  },
  itemCount: items.length + 1,
);
```

## 参考
[Adding top and bottom separators with ListView.separated | Code With Andrea](https://codewithandrea.com/tips/2020-01-12-list-view-separated-top-bottom/)
ubuntu 20.04 remove persistent desktop home and trash icons on gnome-flashback.

gnome-flashbackで、色々と試行錯誤しても消えないデスクトップアイコンを消す方法。

```
gsettings set org.gnome.gnome-flashback.desktop.icons show-home false
gsettings set org.gnome.gnome-flashback.desktop.icons show-trash false
```

また、戻す方法。私の場合はパネルのTrashに不具合が出た時、戻さなければなりませんでした。

```
gsettings set org.gnome.gnome-flashback.desktop.icons show-trash true
```
Rails  gem deviseって？

## Rails  gem devise について

Ruby on Rails を学習中、deviseというユーザーも新規登録、ログイン機能などがgemをインストールするだけで簡単に作れちゃうというもの。非常に優れものです。


*投稿主の備忘録もかねて手順を簡単に紹介していきます。*


## deviseをインストールする
```ruby:Gemfile

gem 'devise'

```


ここで注意すべきなのは`device`ではなく`devise`

私がプログラミング超初心者だった時このスペルミスでエラーが出てしまいました。


ここでgemをインストールするのでコマンドラインで`$ bundle install`します

また、devise用のインストールコマンドがあるので実行します。

```ruby:ターミナル

$ rails g devise install
```

ここまででdeviseのインストールが完了します。

## deviseのモデルを作成する

マイグレーションファイルに記載した情報を基にデータベースの型、制約を設定していきます。

```ruby:ターミナル
$ rails g devise user
```

普段Railsアプリケーションでモデルを作成していく時には `$ rails g model user`というコマンドを打てばモデルの作成ができますがここではdeviseコマンドでモデルを作成します。

このコマンドを実行後`model/user.rb`とuser用のマイグレーションファイルが作成されていれば成功です。

ユーザーのマイグレーションファイルには

```ruby:20200603_devise_create_users.rb

class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :name,               null: false
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      # 〜省略〜
    end

    add_index :users, :name, unique: true
    # usersの情報全てに検索がかけれるようにadd_indexを貼る

```
nameカラム、eーmailカラムなどが設定され、それぞれnull: falseで制約がかけられておりnullであればユーザーの新規登録でエラー表示されるようになります。

user.rbにはバリデーションもかけておきましょう。

```ruby:user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  validates :name, presence: true, uniqueness: true
   # nameカラムが空でないこと、重複したnameは登録できないようにバリデーションをかけている

end
```


バリデーションには様々な制約を設けることができ、もっと知りたいという方はこちらから！
https://qiita.com/h1kita/items/772b81a1cc066e67930e

これでデータベースと紐づくマイグレーションファイルとモデルの設定が完了しました。

```ruby:ターミナル
$ rails db:migrate
```

マイグレーションファイルをマイグレートしておきましょう。

## ビューファイルの準備

ビューファイルもdeviseコマンド一発で作成できます。

```ruby:ターミナル
$ rails g devise:views users
```

これで簡単ではありますがユーザーの新規登録とログイン機能の実装ができました。
Typoraのコードブロックに 言語 を表示させる

Markdown書くのに、[Typora](https://typora.io/)  と [Boostnote](https://boostnote.io/) の間を行ったり来たりしている今日この頃
Typora 便利なんですが Qiita や Boostnote みたいにコードブロックの先頭に言語やファイル名を表示してほしい。  

---

**標準で入ってる GitHub のテーマ** 

これを
![20200603-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249833/6932a97a-c76a-c34f-8de5-dad6e1e6e598.png)

こうしたい
![20200603-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249833/93beb425-f8f5-50d8-77ab-76ccd34feb4b.png)

 (GitHubのプレビューにはそんなのついてないよという指摘は横においておく)

## ユーザーCSSでカスタマイズ

### 1. コードブロックの左上に言語を表示させるCSS

```css:base.user.css
.md-fences .CodeMirror.cm-s-inner:not([lang=""]):before {
  content: attr(lang);
  color: #eee;
  background-color: #777;
  display: inline-block;
  padding: 2px 4px;
}
```

これを typoraの`/themes` フォルダに `<適応させたいテーマ名>.user.css`という名前で保存

- 全部のテーマに適応したい場合は `base.user.css` 
- 特定のテーマだけに適応したい場合は `<テーマ名>.user.css`



### 2. Typoraを再起動する

- Typora 公式のテーマギャラリーにあった [Gitlab](http://theme.typora.io/theme/gitlab/) のテーマに適応させるとこんな感じ

![20200603-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249833/9645f0b5-38e3-5e9d-bfd6-a065c02a5746.png)

いいかんじ
本当は `c : ` は省略して `hoge.c` だけ表示させたいけどやり方わからないわ、CSSど素人にはこの辺が限界か

ちなみにTyporaでは言語の後にファイル名入れるときは `: `の後ろにスペース入れないとコードシンタックス効かないみたい
quiitaではスペース入れると逆に効かなくなる、ややこしい。

## 参考にしたサイト

[マークダウンエディタTyporaにCSSを追加してテーマをカスタマイズする方法](https://www.virment.com/add-original-css-typora/)
[Monospace](http://theme.typora.io/theme/Monospace/) - Typora Temes
PageSpeed Insightsのスコア改善が捗る裏レポートツール (Lighthouse 6対応)

PageSpeed Insightsのスコア改善は本家レポートを見ても全く捗らないので、どの指標をどれだけ短縮させる必要があるのか、一目瞭然でわかる裏レポートツールを作りました。

先日アップグレードしたLighthouse 6.0.0に準拠しています。

PageSpeed Insight 試験対策
https://simulate.site/cheatspeed-insights/

こちらのフォームに任意のURLを入力すると、

![simulate.site_cheatspeed-insights_report_url=https%3A%2F%2Ftoyota.jp%2F&strategy=mobile (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/2e88963d-f63d-b539-d1cc-5e6cfee7140e.png)


こんな感じで**なぜそのスコアなのか**、配点と内訳がわかります。

![simulate.site_cheatspeed-insights_report_url=https%3A%2F%2Ftoyota.jp%2F&strategy=mobile (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/5084fef2-8509-d55c-1570-29378207b227.png)

次にスコア50、90、100を目標としたときに、各指標を何秒短縮(何%改善)する必要があるのか、具体例を提示します。

![simulate.site_cheatspeed-insights_report_url=https%3A%2F%2Ftoyota.jp%2F&strategy=mobile (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/b758cf38-db93-4327-ddcf-5dde3ac55a94.png)

プランの詳細を見ると、指標の測定原理と、特に影響の大きなリソースについてガイドが得られるという仕組みです。

![simulate.site_cheatspeed-insights_report_url=https%3A%2F%2Ftoyota.jp%2F&strategy=mobile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/66cda6a3-4789-e1ac-fc53-92660be0d932.png)

# 遠回りをしないための道しるべ

PageSpeed Insightsのスコアについての苦悩を見聞きすると、

* 10点単位でスコアを上げたいのにすでに満点あるいはそれに近い指標の改善手法を選んでしまう
* 5秒縮める必要があるのに、テキストリソースの最小化など1秒程度の工夫に期待を寄せてしまう

といった遠回りをしています。

それらもサイト改善としてはもちろんやった方がいいのですが、(手っ取り早く)スコアを上げたいという動機は成就できません。

弱点にピンポイントに対処する用途はもちろんですが、「サイト改善」と「試験対策」を区別する根拠としても活用いただけると嬉しいです。

# 試験対策の功罪

一般的に行き過ぎた試験対策は、実力と表面評価の乖離を招くことがあります。

PageSpeed Insightsについては、スコアは結局「時間」を元に評価されているので(CLSは別ですが)、**スコアが上がる=なんらかの待ち時間短縮**を意味します。

クローキングとかは論外ですが、対策や手法は何であれスコアが上がるのは悪いことではありません。

ただまあ、PageSpeed Insights自体が標本ひとつの試験結果なので、多様なユーザーすべてにとって実際サイトが速いかは別問題ですが…
Salesforce CLI のコマンドオートコンプリートを試してみた

## Salesforce CLI のコマンドオートコンプリートとは
Salesforce の Spring '20 でリリースされた Salesforce CLI のプラグインです。以下のようにタブキーを 2 回押すことでコマンドやフラグの候補を表示できるので、ド忘れした場合などに便利ですね。

```zsh
sfdx force:org:list --<タブキー><タブキー>
--all   --json     --noprompt              --verbose               
--clean --loglevel --skipconnectionstatus  
```

- [オートコンプリートを使用した時間の節約とエラーの削減](https://releasenotes.docs.salesforce.com/ja-jp/spring20/release-notes/rn_sf_cli_autocomplete.htm)

## インストールと初期設定
Salesforce CLI がインストールされた環境で以下のコマンドを実行してプラグインをインストールします。

```zsh
$ sfdx plugins:install @oclif/plugin-autocomplete
```

その後、以下のコマンドを実行すると環境変数も修正するように指示が出るので従います。
私は Mac のデフォルトに合わせたので `zshrc` を書き換えていますが、利用しているシェルに合わせてください。

```zsh
$ sfdx autocomplete
$ printf "$(sfdx autocomplete:script bash)" >> ~/.zshrc; source ~/.zshrc
```

## 動作を確認
以下のコマンドを実行してそれぞれ候補が表示されるか確認してみましょう。

```zsh
$ sfdx <タブキー><タブキー>
$ sfdx force:source:<タブキー><タブキー>
$ sfdx force:org:list --<タブキー><タブキー>
```
Pandas DataFrame の任意の場所に列を追加する便利関数

Pandas DataFrame の任意の場所に列を追加したい場合は [pandas.DataFrame.insert](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html) を使うと実現できるが、いくつか不満がある。

- immutable でない (DataFrame が直接書き換えられてしまう / 破壊的メソッドである / inplace オプションがない)
- 追加場所をインデックスの数値で指定しなければいけない
    - わかりにくい
    - 「col1 の後に追加」のような指定が難しい
- Series を入力しても name が無視されるため、別途指定する必要がある
- DataFrame を入力できない

これらを解決するような便利関数を書いた。

## 実装
``` python
from typing import Union, Optional
import pandas as pd


def insert_columns(
        df: pd.DataFrame,
        data: Union[pd.Series, pd.DataFrame],
        *,
        before: Optional[str] = None,
        after: Optional[str] = None,
        allow_duplicates: bool = False,
        inplace: bool = False,
    ) -> pd.DataFrame:

    if not inplace:
        df = df.copy()

    if not (after is None) ^ (before is None):
        raise ValueError('Specify only "before" or "after"')

    if before:
        loc = df.columns.get_loc(before)
    else:
        loc = df.columns.get_loc(after) + 1

    if type(data) is pd.Series:
        df.insert(loc, data.name, data, allow_duplicates)
    elif type(data) is pd.DataFrame:
        for column in data.columns[::-1]:
            df.insert(loc, column, data[column], allow_duplicates)

    return df
```

- `before` または `after` にはカラム名を指定する
- デフォルトでは入力された DataFrame を直接書き換えない
    - `inplace=True` を指定すれば直接書き換える

## 使い方
サンプルデータとして sklearn の iris データセットを使う。

``` python
from sklearn import datasets

iris = datasets.load_iris()

df = pd.DataFrame(iris.data, columns=iris.feature_names)
target = pd.Series(iris.target_names[iris.target], name='target')
```

``` python
df.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/25e108ce-32fb-4267-e7ff-f0bdc4aaee82.png)

``` python
target.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/5c14a9de-64a7-94ac-462c-1bed54e3e16a.png)

df の `sepal width (cm)` の後ろに target を追加してみる。

``` python
insert_columns(df, target, after='sepal width (cm)')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/6e7d28e2-4e62-e1c7-2d90-897f7bd32782.png)

この例では Series を追加しているが、DataFrame も指定できる。
Remotte（リモッテ）でビデオと音声を配信、記録、再生する

[前回](https://qiita.com/remotte_jp/items/a7b5475176eb133af957)は利用ページから履歴の「詳細画面」を表示してみた。
今回はリモッテの大きな特徴の１つであるビデオと音声を扱ったアプリを試してみるために、リモッテ・ストアからアプリ「ビデオと音声の配信」をダウンロードして実行してみる。


### アプリのインストール
操作方法は[過去の投稿](https://qiita.com/remotte_jp/items/324f99727c68392b80e5)を参考にしていただくとして、アプリ「ビデオと音声の配信」をインストールする。
![ビデオと音声の配信.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/ea07a8a9-ea36-c17b-82ba-3f0b42fa43bb.png)
### 設定
何もせずにアプリの「開始」ボタンを押すだけでパソコンに取り付けられたカメラとマイクからのビデオと音声が配信されるが、とりあえずアプリの詳細画面に入り、「構成」タブの「設定」を表示してみよう。
![設定画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/2d9e4c1e-40d3-7e1c-10f8-c4e98d859c41.png)
デバイスの選択や解像度などのオプションが設定できるようになっている。この中に「配信周期を制限する」というチェックボックスがある。ビデオを配信するにあたり、「最大フレームレート」で送信すると通信量が大きくなってしまう訳だが、この機能を使って１コマ毎の画像の送信頻度を制限することが出来る。リモッテは主として IoT や AI、自動化を目的としたアプリケーション用のプラットフォームであり、リアルタイムにビデオチャットしたりセミナーを配信したりするためのものではなく、色々な面で目的に特化した細かい制御が出来るオプションを用意してある。

次に、「利用ページ」タブをクリックし、「利用者」タブを選択する。ここで、ビデオや音声を受信できる利用者を定義する。この説明は[過去の投稿](https://qiita.com/remotte_jp/items/7ec79a400429738843d0)を参考にしよう。
### アプリの実行
「利用ページ」タブの「レイアウト」タブに移動して、アプリの「開始」ボタンをクリックする。ビデオと音声が出力される。
![管理画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/9624e419-ac0c-6ef2-6fa7-ee49d6e8c766.png)
### 利用者からのアクセス
他のデバイスからのアクセスを確認してみよう。今回は Android と iOS のデバイスから、それぞれ Google と Twitter のアカウントを利用して同時にステーションにアクセスしてみた。
![iOS_Android.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/8878f488-ce13-ba3e-cd01-5fd06d4b7139.jpeg)
それぞれのデバイスが同時にステーションにアクセスし、同じ映像が表示された。利用者のメイン画面において、映像はコマ画像として表示されている。HTML 的には &lt;image&gt; タグを使用して、管理ツールで設定された配信品質に従って JPEG 画像を更新する。より高い解像度かつスムーズな動画を見るためには、表示されている画像をダブルクリック（タップ）して、ビデオの詳細画面に遷移する。
![現在の映像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/5d3f3cae-5f0f-8483-c9d0-53dddf3fc56d.png)
ビデオの詳細画面の「現在の映像」タブでは、高解像度で高フレームレートのビデオが見れる。HTML 的には &lt;video&gt; タグが使われている。
### 記録と再生
ここで画面左下のカメラアイコンをクリックすると、現在表示されている映像のスナップショットを撮ることが出来る。
![スナップショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/bb75866f-15c1-9d01-8444-dbe84f0f2de0.png)
「過去の画像」タブを開くと、スナップショットを見たりダウンロードできる。
![過去の画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/ce3e0d44-52cf-7d2f-8f92-d904465b713f.png)
同様に、「現在の映像」タブにて画面左下のレコーディングボタン（赤色の丸）を押すと録画を開始できる。
![録画中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/dd0c5523-3ed4-8b69-f1f6-7770aedf5617.png)
停止ボタンで録画を停止する。
![録画完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/2d9e67ed-6dc4-c086-957e-fe8733292a11.png)
録画した映像は、「過去の映像」タブに入ると、再生したり、ダウンロードできる。
![過去の映像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/b66164f7-a793-080b-f882-690ed3c88e36.png)
### まとめ
リモッテでビデオと音声を扱う最も簡単なアプリを試してみた。単にビデオや音声を配信するだけであれば、リモッテ以外に沢山の選択肢がある訳だが、リモッテはビデオ解析や音声解析を使った IoT や AI のシステムを構築する際のプラットフォームとして非常に強力で便利な機能を提供している。
これまでの投稿では、主に管理者と利用者の立場での説明をしてきたが、次回からは「開発者」向けの解説を始め、また、Remotte ストア上の無料で使える便利なアプリを逐次紹介していくことにしよう。
理論物理系学生の０から始める機械学習#2

目次
1. 標準装備のPython
2. 0からのPython環境構築
3. コーディングの準備

冗長になるかもしれないが、”０から”というところを意識して書いていきたい。

#1. 標準装備のPython
開発環境：MacOS 10.13.6
基本的にMacのターミナルをCUIとして用いる。（CUI：Character User Interface 文字で操作する）

ターミナルの表示形式は、
[コンピュータ名:カレントディレクトリ名 ユーザ名$]
となっている。（短くする方法もあるが初心者ならカレントディレクトリがどこなのかわかっていた方がいいだろう。）
以降`$`のみを記述する。



Python2.7.16はMac標準装備だった。確認方法は以下。

```ruby:
$python -V
Python 2.7.16
```

自分の場合はバージョン2.7.16で表示された。

#2. ０からのPython環境構築
標準装備のPython2でも開発できるが、PythonにはPython2とPython3があるらしく、Python2は2.7以降はバージョンアップがされないことが決まっているらしい。これからPythonを学ぶのであればPython3をインストールしておきたい。

Python公式サイトから無料でインストーラーが提供されている。
[Python公式サイト](https://www.python.org/downloads/)
こちらから最新のリリースをダウンロードしておけば問題ないはず。

インストールが完了したらバージョン確認。

```ruby:
$python3 -V
Python 3.8.0
```

自分のバージョンは3.8.0だった。MacOSの場合Python3の起動コマンドが`$python3`になる。
Python2を使いたい場合は`$python`、Python3を使いたい場合は`$python3`と使い分ければいい。

#3. コーディングの準備
Python3がインストール完了できれば、`MacOSでPythonという言語を処理する`準備ができたということ。しかし、処理するプログラムがなければ意味がない。次は、`コードを書く`ための準備をする。

有名なテキストエディタVisual Studio Code（以下：VSCode）を用いる。
テキストエディタとは、Mac標準装備の`メモ`と同じもので、VSCodeはコーディングに特化したものだと考えればいいだろう。

[Visual Studio Code公式サイト](https://code.visualstudio.com)
こちらから同様にインストールする。


インストールできたら、あとは使っていくだけ。
拡張機能としてプラグインをインストールするとVSCodeを自分好みの開発環境にカスタマイズすることができる。
①日本語で使いたいのであれば、`Japanese Language`のプラグイン、
②Pythonでコーディングするので`Python`のプラグインをインストールしておく。
（プラグインは後で有効/無効を切り替えられる。開発したい言語によってプラグインを追加できる。）

③コマンドパレット
VSCodeの使い方の一つとしてコマンドパレットも活用するといい。
ショートカットキー`command+shift+P`でVSCodeのコマンドパレットが開ける。基本的なVSCodeの使い方はコマンドパレットでキーワードを入力すれば出力される。ターミナル上でのファイル操作と使い分けて使用するといいと思う。

④コマンドパレットでやっておくと便利なものとしてcodeコマンドのインストールがある。
コマンドパレットで"shell"と入力すると、`Shell Command: Install 'code' command in PATH`もしくは日本語のプラグインを有効にしてあれば`シェルコマンド: PATH内に'code'コマンドをインストール`が出てくるので、それを選択する。正常にインストールされればターミナル上で

```ruby:
$code [ファイル名]
```

と入力するだけでVSCodeがファイルを起動してくれるようになる。
あとはVSCodeでコーディングをしてショートカットキー`command+S`などで保存すればコーディングは終わり。

⑤ターミナルもVSCode内でショートカットキー`shift+control+@`を使えば使用できるので起動する必要がなく、ほぼGUI（マウス）を使わない。

#まとめ
- python環境の構築
- VSCodeのインストール
- VSCodeの最低限必要な使い方①〜⑤

より詳しくは、
-  [Python初心者に知ってもらいたいVS Codeのコマンドパレットとその使い方](https://tonari-it.com/python-vscode-command-palette/)
- [【Visual Studio Code】コマンドからVS Codeを起動できない場合 (Mac編)](https://qiita.com/ayatokura/items/69c96306e3dee501e19b)
- [【Mac版】 VisualStudioCode キーボードショートカット](https://qiita.com/naru0504/items/99495c4482cd158ddca8)
この辺りの記事を参考にするといいかもしれない。



####参考文献

- [スラスラわかるPyhton](https://www.amazon.co.jp/スラスラわかるPython-岩崎-圭/dp/4798151092/ref=sr_1_1?__mk_ja_JP=カタカナ&dchild=1&keywords=すらすらpython&qid=1591248379&sr=8-1)
- [ターミナルからVisual Studio Codeを起動する方法](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)
-  [Python初心者に知ってもらいたいVS Codeのコマンドパレットとその使い方](https://tonari-it.com/python-vscode-command-palette/)
- [【Visual Studio Code】コマンドからVS Codeを起動できない場合 (Mac編)](https://qiita.com/ayatokura/items/69c96306e3dee501e19b)
- [【Mac版】 VisualStudioCode キーボードショートカット](https://qiita.com/naru0504/items/99495c4482cd158ddca8)


次の目標

- TesonrflowとKerasのインストール
- MNISTを使って画像認識の基礎とフレームワークの理解
ゼロから始めるLeetCode Day45 「1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day44「543. Diameter of Binary Tree」](https://qiita.com/KueharX/items/117f939714ea26ab72c6)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree](https://leetcode.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree/)

難易度はMedium。

`original`と`cloned`の2つのバイナリツリーが与えられ、`original`の`target`への参照が与えられます。

複製されたツリーは、元のツリーのコピーで、複製されたツリー内の同じノードへの参照を返します。
2つのツリーまたは`target`を変更することは許可されておらず、回答は`cloned`されたツリー内のノードへの参照でなければなりません。

フォローアップ：ツリーで繰り返し値が許可されている場合は、問題を解決してください。

# 解法

```Python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
        if not original:
            return None
        if original == target:
            return cloned
        
        return self.getTargetCopy(original.left,cloned.left,target) or self.getTargetCopy(original.right,cloned.right,target)
# Runtime: 672 ms, faster than 60.93% of Python3 online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree.
# Memory Usage: 23.5 MB, less than 100.00% of Python3 online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree.
```


以上のような解き方をしました。
シンプルに書けたので比較的良い解答なのかと思ったのですが、そこまで速度が出ていないので他の解答を調べてみました。

```Python
class Solution:
    def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
        que = collections.deque([(original, cloned)]) # start at the root
        while que:
            nodeOrig, nodeClon = que.popleft()
            if nodeOrig is target: # if original node is found - cloned node is our answer
                return nodeClon
            if nodeOrig.left:  que.append((nodeOrig.left, nodeClon.left))
            if nodeOrig.right: que.append((nodeOrig.right, nodeClon.right))
# Runtime: 656 ms, faster than 92.51% of Python3 online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree.
# Memory Usage: 23.6 MB, less than 100.00% of Python3 online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree.
```

https://leetcode.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree/discuss/539484/Simple-clean-and-fast-Python-solution-7-lines-beats-92

この回答はqueを使って書いていますが、わかりやすくて良いですね。
速さも申し分ないですし、問題を自分の解けるような型に無理やりはめるのではなく、このような回答の仕方も覚えて切り替えられるようになれるともっと問題を解いてて楽しそうですね！

今回はここまで。お疲れ様でした。
難読化されたJavaScriptを解読するツールを作った

**Obfuscator.io**というJavaScriptコードを難読化できるツールがあります。

例えば以下のような感じ

Before
![難読化前](https://i.gyazo.com/5b00a25c839c0efd86edb4f573675a63.png)

After
![難読化されたコード](https://i.gyazo.com/35e182bdeb5ed8bbdd8e1c017880f022.png)

正直難読化されてても慣れればコードを読むのはそんなに苦じゃないのですが、自動ですべて解読するツールを作ったらおもしろそうだと思ってやってみました。

#難読化されたJavaScriptを半自動で解読するツール
![解読ツール](https://i.gyazo.com/cc25e38d9a2fb036a7be9415a0c1c51d.png)

Vue.js(サイト側)とCloud Functions(API側)で作ってみました。

公開URL: https://deo.sigr.io/

残念ながら完全自動化までは至りませんでしたが、最初にターゲットとなる関数名を入力すれば後は自動で解析してくれます。

##ツールの使い方
1. 解読したいコードをInputに貼り付ける。
2. 貼り付けたコードの中に以下のような部分があるので関数名をコピーする（３つのうちどれかに似てるはず）

`_0x439c[103]
_0x439c('0x4')
_0x439c('0x2','f]Xg')
`

これの場合は_0x439cが対象（関数名）。Target function nameの欄にコピーしたのを貼り付ける

3.「Deobfuscate」をクリック
4.ちゃんと解読されればResultに結果が表示される

ちゃんと解読されると難読化された部分が読めるようになるはずです。
![結果](https://pbs.twimg.com/media/EZblVSIUwAEw45C?format=jpg&name=large)

##さいごに
GitHubにフロント側のソースコードをうｐしています。
https://github.com/LostMyCode/javascript-deobfuscator

CloudFunctionsで動いているAPI側のコードもいつか公開するかもしれません。

[javascript-deobfuscator](https://deo.sigr.io/)
OSのアップデートをしたらExcel(マクロ)が勝手に落ちる

#マクロ入りのExcelが落ちる
これまで使用できていたマクロが入ったExcelが勝手に落ちる！！OSをアップデートしただけなのに・・・というとき。

#不具合時期・原因
不具合が起こったタイミング：Win8.1からWin10にアップデートしたとき
原因：VBAのバージョンがVBA6からVBA7になっており、バージョンによってライブラリの格納場所が異なり、元々参照していたディレクトリがないことが原因
(Excelが落ちるのを確認できているのは、InternetExplorerやAPIを操作するマクロが入っているExcelのみ。)

#対処法
対処法：マクロが参照しているライブラリの参照場所を変えてあげればいい。
　セーフモードで対象のExcelを開く(Shiftキーを押しながらExcelを立ち上げる。
　※立ち上がりきるまでShiftキーは離さない)
⇒VBEのツールタブの参照設定でチェックが入っているものを外す
　(Internet ControlとHTML Objectのみでもよさそう？再度チェックを付けるため外したものは覚えておく)
⇒Excel保存＆閉じる
⇒セーフモードで対象のExcelを開く
⇒VBEのツールタブの参照設定で外したチェックをつけなおす
⇒Excel保存
セーフモードを使用せずに開いてもExcelが落ちないことを確認する。
Field ' ' doesn't have a default value

#Laravelの画像投稿機能実装時のエラー

画像投稿機能実装中に以下のエラーが表示された
###<font color="Red">Field 'user_id' doesn't have a default value</font>


問題点１
posts controller　storeアクション

     public function store(Request $request){
        $validator = Validator::make($request->all(), [
            'file' => 'required|max:10240|mimes:jpeg,gif,png',
            'content' => 'required|max:191'
        ]);
        
        if($validator->fails()){
            return back()->withInput()->withErrors($validator);
        }
        
        $file = $request->file('file');
        $path = Storage::disk('s3')->putFile('/', $file, 'public');
        
        Post::create([
            'user_id' => \Auth::user()->id,
            'image_file_name' => $path,
            'content' => $request->content
        ]);
            
         return redirect('/');
    }


'user_id' => \Auth::user()->id,の一文が抜けていた

問題点２
Post　Model Post.php

```
class Post extends Model
{
    protected $fillable =[
        'image_file_name', 'content', 'user_id'
    ];
}
```

$fillableの中に　'user_id' を記入していなかったため。


以上の2点を解決後フォームから送信で無事に動作した。
マイグレーションファイルにuser_idと書いていたのに上記のファイル無いで設定していないために発生したエラーだった。
google.script.run が Promise を返すようにする

#期待を返せ
google.script.run は withSuccessHandler や withFailureHandler でコールバックを登録する仕様となっており、 Promise を返してくれません。
async / await ですっきり書きたいですよね。

```Javascript:理想
(async ()=> {
  const data1 = await google.script.run.myFunction();
  const data2 = await google.script.run.myFunction2(data1);
  console.log(data1);
  console.log(data2);
})();
```

```Javascript:現実
google.script.run
.withSuccessHandler( data1 => {
  google.script.run
  .withSuccessHandler( data2 => {
    console.log(data1);
    console.log(data2);
  })
  .withFailureHandler(console.error)
  .myFunction2(data1);
})
.withFailureHandler(console.error)
.myFunction();
```

#Promiseを返さないなら自作関数で包んでしまえ
というわけで google.script.run を元に Promise を返す関数を動的に定義します。

```Javascript:
const ServerScript = new class {
  constructor() {
    const createAsyncFunction = (methodName) => function() {
      return new Promise( (resolve, reject) => {
        google.script.run
        .withSuccessHandler(resolve)
        .withFailureHandler(reject)
        [methodName]
        .apply(null, arguments);
      });
    }.bind(this);
    for (const methodName in google.script.run) {
      const type = google.script.run[methodName].prototype.constructor.name;
      if (type != methodName) {
        this[methodName] = createAsyncFunction(methodName);
      }
    }
  }
};
(async ()=> {
  const data1 = await ServerScript.myFunction();
  const data2 = await ServerScript.myFunction2(data1);
  console.log(data1);
  console.log(data2);
})();
```

for 文の中の if は withSuccessHandler や withFailureHandler を弾くためのものなので、別に無くても問題ないです。呼ばなければ良い話ですから。

また、この条件でも doGet などが入ってきてしまうのですが、呼んでもエラーなどは起きずに undefined が返ってきます。元々の google.script.run からそのような動きをするようなので、こちらも特に気にしないことにします。

以上、快適なGASライフを！
Google App Script(GAS)でチャットワークにメッセージを送る

トークンはコード内に書かずに、スクリプトプロパティに保存するようにします。
スクリプトプロパティは、スクリプトエディタのメニューから、
ファイル＞プロジェクトのプロパティ
を開き、『スクリプトのプロパティ』タブを開いて、行を追加して名前(CW_TOKEN)と値(トークンの文字列)を入力すると保存できます。
コード内では、`PropertiesService.getScriptProperties().getProperty('CW_TOKEN')`で保存した値が取得できます。

```js
function sendCW(roomId, msg) {
  var token = PropertiesService.getScriptProperties().getProperty('CW_TOKEN');
  var options = {
    'method' : 'post',
    'headers' : {'X-ChatWorkToken' : token},
    'payload' : {'body': msg}
  };
  UrlFetchApp.fetch('https://api.chatwork.com/v2/rooms/' + roomId + '/messages', options);
}
```
Auto Check-In App:Amazon Rekognitionを利用した本人認証勉強会に参加した

# 概要
* 画像、動画処理のAIサービスであるAmazon Rekognitionの概要
* Auto Check-In Appソリューションの概要
* Auto Check-In Appソリューションを利用した顔認証システムの構築方法

# 内容
## 画像、動画処理のAIサービスであるAmazon Rekognitionの概要
### AWS AIサービス
* 機械学習の深い知識なしに利用可能
* 学習済みのモデルをAPIで簡単に利用可能
* コンピュータビジョン
    * Amazon Rekognitions
* 音声（読み上げ、書き起こし)
    * Amazon Polly
    * Amazon Transcribe
    * Amazon Kendra
* 自然言語処理
    * Amazon Comprehend
    * Amazon Translate
    * Amazon Textract

### Amazon Rekognition
* 機械学習による画像、動画分析の自動化
* 利用範囲
    * 対象物体、シーン、アクティビティ検出
    * 安全でないコンテンツの検出
    * 顔認識
* 機能
    * ラベル付け
    * カスタムラベル
    * 不適切コンテンツ検出
    * 文字検出
    * 顔検出分析
    * 顔検索、身元確認
    * 有名人認識
    * 動線分析
* アプリケーションに組み込む場合はAPIやSDKを利用して操作できる


## Auto Check-In Appソリューションの概要
### イベント受付の課題
* 人が集まるイベントでは受付業務が発生
    * 参加者リストとの照合に時間とコスト(人)がかかる
    * 本人確認が大変
    * 通過時間や時間帯ごとの通過人数の確認
### 顔認証イベント受付サービスのアーキテクチャ
* 登録
    * 顔写真をS3へ保存する
    * Lambda functionで顔写真を処理、FaceIDをAmazon DynamoDBへ保存
* 検索
    * クライアントで顔写真などをアップロードと結果確認
    * Amazon API GatewayとAmazon Cognitoで情報転送
    * Lambdaで顔写真をamazon Rekognitionに処理する
    * FaceIdなどをAmazon DynamoDBに保存

### 仕組み
* 以下の部分
    * コレクション：登録した顔データの集合
    * 登録
    * 検索

## Auto Check-In Appソリューションを利用した顔認証システムの構築方法
### 実装ガイド
* https://aws.amazon.com/jp/solutions/implementations/auto-check-in-app/
    * one-clickでバックグランドサービスを構築できる
* 注意点
    * イメージのバイトをAmazon Rekognition Imageに送る方が、S3にアップロードしたものを参照させるより高速
    * 送る前に画像サイズを小さくしたり顔の部分を切り出したりするとパファーマンスが向上
    * 結果にSimilarity(0から100)範囲をとるために、適切な閾値設定が重要
    * 顔認識だけではなく、身分証などの多要素認証を検討


# 感想
* AWS Summitのような大きいイベントに顔認証が広い範囲に使われると、チェックイン、セッション会場に入ることなどが時間がかからない
* 顔認証への影響要素が多く、成功率が100%ではないので、別の認証方法と併用すれば、一番安全になるはず
* Auto Check-In Appを利用して構築時間が少なくて、早めにプロトタイプを作ってお客様にソリューションのイメージを説明できる
* ハンズオンで顔認証を使ってみて、思ったよりもずっと早く認証できて、スピードにびっくりした
VSCodeに導入した拡張機能 

普段使用しているエディタは「coda2」なのですが、VSCodeが便利そうなので使用していこうと思います。

導入した拡張機能の備忘録です。


## 導入した拡張機能

### Markdown All in One

https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one


### Material Theme

https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme


### GitHub VS Code theme

https://marketplace.visualstudio.com/items?itemName=GitHub.github-vscode-theme


### Material Icon Theme

https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme
What is 5G Fronthaul,Middlehaul,Backhaul?

5G network has three parts, Access Network, Bearer Network, and Core Network. The access network is also Radio Access Network(RAN), which is mainly composed of base stations.
![126.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/eb1b2b0c-c3d6-c5e9-da6b-b19a1a01e499.jpeg)

So what does the base station include? The base station usually includes BBU (mainly responsible for signal modulation), RRU (mainly responsible for radio frequency processing), feeder (connecting RRU and antenna) and antenna (mainly responsible for the conversion between the guided wave on the cable and space wave in the air.

Each base station in 4G network has a BBU, which is directly connected to the core network. In 5G networks, the access network is no longer composed of BBU, RRU and antenna. Iit is reconstructed into the following three functional entities: CU (centralized unit), DU (distributed unit) and AAU (active antenna unit). The original 4G RRU and antenna are combined into AAU, and BBU is divided into CU and DU. DU sank to AAU. One CU can be connected to multiple DUs.

The 4G network has fronthaul and backhaul. But in the 5G network, it is divided into three parts. The AAU connected to the DU is called 5G Fronthaul. A part of the DU connected to the CU is Middlehaul, and the backhaul is the communication carrier between the CU and the core network.
![127.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/fa90080b-97ca-3640-e650-84688fb1c4f9.jpeg)

HYC Co., Ltd has been dedicated to the manufacture of fiber optic products for 20 years, and has a strong R&D team and strong production capacity. HYC can provide one-stop OEM ODM services for design, R&D and manufacturing. The production line has optical fiber connectors, adapters, plc splitters, wdm, mems optical switches, etc.
www.hyc-system.com
LUISとPower Automate使って、2つの価格を比較するLINE Botつくってみた

# やってみたこと
800ml入りの詰め替え洗剤と、600mlの非詰め替え(ボトル付き)はどっちが安いのだろう？と思うことがよくあります。
そういう、単価の計算って、別に電卓たたけばいいのだけどちょっとめんどくさいですよね。
というわけで、単価の計算をやってくれるLINE botを作ってみました。

使った素材はこちら

- Power Automate (要Premium)
- LUIS (AzureのCognitive Service)
- LINE Messaging API

以上
LUISは入力されたメッセージから、値段部分と数量 (200mlとか500gとか10個とか)を読み取るために利用しました。LUISによる文章解析の結果、２つずつ数量と値段が取れている前提で、Power Automate上で単価を計算して、どちらが安いのかをReplyで返しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/2a9a6a6a-e914-4031-de0a-c3882db19917.png)

# LUIS部分
LUIS部分は気合です。ひたすら例文を入れて、数量と価格をマークしていきます。
LUISの導入部分は、少し画面が変わっていますが、こちらの記事が分かりやすいです。

[自分用メモ的にLINE送信した予定をAIで読み取ってGoogleカレンダーに自動登録しよう](https://ascii.jp/elem/000/001/770/1770731/)

実際のAuthoring画面が以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/f29791c9-38e6-245f-bb5f-aed94acef337.png)

※上図ではある程度調教しているので、例文を入れると、どういう要素なのか、よみとってマークしてくれています。
青い下線が引かれている部分を、数量なのか価格なのか、指定していきます。

傾向としては、文章の先頭に1桁の数量が来ると、認識確率がすごく下がりました。なので、「ねえ、XX」のようなワードをユーザーには入れてもらう工夫が必要そうです。

# Power Automateパート

Power Automateパートは簡単です。すでに[LINE Messaging APIのカスタムコネクタ](https://mofumofupower.hatenablog.com/entry/2020/05/15/165215)を作っているので、リプライはメッセージを入れるだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/6b83fbdc-2a18-6c39-f364-b7f9c77908a8.png)

前半、Webhookの受信は、Messaging APIの仕様どおり。
受け取ったメッセージをそのままLUISのインプットにします。
これで結果が返ってくるのですが、結果は以下のような配列で返されます。

```luis_output.json
[
  {
    "entity": "5",
    "type": "amount",
    "startIndex": 3,
    "endIndex": 3,
    "score": 0.5533202
  },
  {
    "entity": "1 0",
    "type": "amount",
    "startIndex": 15,
    "endIndex": 16,
    "score": 0.9669346
  },
  {
    "entity": "安い",
    "type": "highlow",
    "startIndex": 31,
    "endIndex": 32,
    "score": 0.9992584
  },
  {
    "entity": "3 5 0 0 円",
    "type": "price",
    "startIndex": 7,
    "endIndex": 11,
    "score": 0.9945259
  },
  {
    "entity": "7 5 0 0 円",
    "type": "price",
    "startIndex": 20,
    "endIndex": 24,
    "score": 0.996291
  }
]
```

※Quantityじゃね？とかはまあスルーしてください。。

**注意しなければならないのは、数量、価格いずれも数字の間に半角スペースが入る点です。実際に割り算するとき(単価にするとき)は、スペースを除去する必要があります。**

これらの結果から、最初の数量&価格の組み合わせ と 後ろの数量&価格の組み合わせにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/6c6e0bde-5aea-f7e7-f561-48f3285db151.png)

LUISの解析結果自体は、精度の情報とか、どこに該当するかとか、あるいはどのタイプの読み取り結果なのかをすべて含んでいます。
後続で計算しやすいように、価格や数量だけの配列を生成し、かつスペースを除去します。

これにはSelect(選択)アクションを利用しています。
あとは素直に計算。Power Automateでは割り算はdiv()関数です。

# おわり
こんな風に、かなり短いフローと、関数を少しつかうだけで、単価比較のLINE Botが完成しました！

ポイントはLUISで頑張って調教することと、LINE部分を簡単にするために、カスタムコネクタを使うところです。

以上、生活お助けBotの概要でした。
LaTeXで図の多い論文を作成する際の小技（\usepackage{here}と\clearpage）（備忘録）

#やりたいこと
MacのTeXShopで図の多い文章を作成する際に、以下の2つを解決してPDFの形で出力したい。
* Microsoft Wordの感覚で図や表を **その場所** に配置できない（LaTeXは図表を勝手に配置してしまう）
* 文章にたくさん図を入れてしまって、Too Many unprocessed floatというエラーが出てしまったので何とかしたい

#背景
LaTeXで論文を作成し始めたところ、図や表がLaTeXの仕様上任意の場所に配置されてしまい、思った通りのレイアウトが得られなかったり、PDFにコンパイルをした際にエラーがたくさん出てしまったので、対策を調べながら試行錯誤した結果、以下の2つのコマンドが劇的に効いたので、備忘録として残します。

* \usepackage{here}と[H]オプション : 図表を文中のその場所に配置
* \clearpage : 出力していない図表をその場所に出力

#動作環境
macOS Mojave 10.14.6
TeXShop 4.44

#手法

##図をその場所に配置する
図を配置するにはプリアンブルの部分に以下のコマンドを配置して、graphixパッケージを使用することを宣言します。
私の環境ではdvipdfmxオプションでないとエラーが出てしまいました。

```LaTeX
\usepackage[dvipdfmx]{graphicx}
```

本文は以下のコマンドで図を配置できます。

```LaTeX
\begin{figure}[位置]
  \includegraphics[オプション]{ファイル名}
\end{figure}
```

位置に以下の表にあるhtbpを指定すると、LaTeXが適切と判断した部分に配置してくれます。
ただ、このパッケージだけだと、位置指定が行えるものの、あくまでもLaTeXが適切と判断した部分に配置してしまうようで、図の数や文書のボリュームによっては思い通りにならないこともあります。

| 位置 | 出力先 |
|:--|:--|
| h | 記述した場所に出力 |
| t | ページの上端に出力 |
| b | ページの下端に出力 |
| p | 表専用のページを用意して出力 |


私の作成している論文では、図が多いせいか、\newpageコマンドと\sectionコマンドで次の章に設定しても、次の章に前の章の図が一気に出力されてしまうことが多く、とてもフラストレーションが溜まっていました。

そこで、プリアンブル部分にもう一つ以下のhereパッケージも**追加**しました。

```LaTeX
\usepackage{here}
```
このパッケージは配置のオプションに[H]を指定することで、文章のその場所にその図表を配置してくれます。

```LaTeX
\begin{figure}[H]
  \includegraphics[オプション]{ファイル名}
\end{figure}
```
##レイアウトのエラーをクリアする
思った通りに配置された図表も、いざPDFにコンパイルするとエラーが出てきます。
多少のエラーであれば無視して先に進められれるのですが、そのエラーが膨大になると、"Too Many unprocessed float"というエラーが出て、ついに処理が止まってしまい、PDFファイルが作成されなくなってしまいます。
これは図表の位置が定まらず、それが規定量を超えることで止まってしまうようです。
このエラーを解決する方法としては、参考サイトにある通り、適度に（私はセクションごとに入れていますが）\clearpage コマンドを配置することで解決しました。

```LaTex
\clearpage
```

#謝辞
参考サイトのおかげで、ストレスなくLaTeXで思い通りのレイアウトで論文が作成できるようになりました。
参考にさせていただいたサイトの方にお礼を申し上げます。



#参考サイト
[Qiita - TeXで好きな位置に図を配置する](https://qiita.com/poemn/items/9142339749c87ebdb536)
[LaTeXコマンド集](http://www.latex-cmd.com)
[LaTeX Error:Too Many unprocessed floatの解決法](http://mikilab.doshisha.ac.jp/dia/seminar/latex/doc/floaterror.html)
[Python] メール送信

## やりたいこと
 - ```python```でメール送信したい
  
## 経緯
いろいろ処理をした結果をメールで通知したいと思って```Outlook```でのメール送信を組み込んでみた。
毎日の運用なのでタスクスケジューラに設定したら、メール送信されたことになってるけど実際には送信されてこない。
タスクスケジューラからでなく、直接実行すれば送信される。
調べてみたら、サーバー環境で```Outlook```などの```office```製品を使うのはちょっと難ありらしいことがわかった。
代替案として標準ライブラリを使えばできることがわかったのでメモしておく。


## ポイント
 - 標準ライブラリの```smtplib```と```email```を使う
 - その他、```サーバーホスト名```, ```ポート番号```, ```認証ID```, ```認証パスワード```が必要
 - 但し、```認証ID```, ```認証パスワード```はなくてもOKだったりする場合もある（環境による）
 - 送信先が複数ある場合は1通づつ送信することになるので、```送信先アドレス```はリストで渡して```for```文で回す

## コードサンプル
```python:sample.py
from email import message
import smtplib

smtp_host = 'ホスト名'
smtp_port = ホスト番号
smtp_account_id = '認証ID'
smtp_account_pass = '認証パスワード'
send_from = 'xxxxx@xxx.co.jp'
l_send_to = [
    'aaa@xxx.co.jp',
    'bbb@xxx.co.jp'
]

subject = '作業報告'
content = f'作業が終了しました'

for s in l_send_to:
    msg = message.EmailMessage()
    msg.set_content(content)
    msg['Subject'] = subject
    msg['From'] = send_from
    msg['To'] = s

    server = smtplib.SMTP(smtp_host, smtp_port, timeout=10)
    server.login(smtp_account_id, smtp_account_pass) # なくても大丈夫な場合もあり
    server.send_message(msg)
    server.quit()
```