OmniAICreator/Qiita-1.07M huggingface dataset:
Nukkit in Kotlin #2

# Nukkit in Kotlin #2

NukkitをKotlinで書くシリーズになりました。\#1は[こちら](https://qiita.com/UramnOIL/items/867f7fed790e0582ad1c)

## やること

\#2では

- イベント
- コマンド

を解説していきます。基本的なbuild.gradle.ktsは[#1](https://qiita.com/UramnOIL/items/867f7fed790e0582ad1c)で詳しく記載してあるので、そちらを参照してください。

### イベント



```HogeListener.kt
package com.example.sample

import cn.nukkit.event.EventHandler
import cn.nukkit.event.Listener
import cn.nukkit.event.player.PlayerJoinEvent

class HogeListener() : Listener {
    @EventHandler
    fun onPlayerJoin(event: PlayerJoinEvent) {
        event.player.sendMessage("Hoge")
    }
}
```

なんてことはないです。Nukkit特有の`@EventHandler`アノテーションを指定したうえで、メソッドをListenerインターフェースを継承したクラスで宣言すればイベントのハンドラとなります。引数は待機したいイベントの型を指定します。引数は初めから`val`が適用されており、#1で解説した変数の宣言で必要な`val`や`var`を使った宣言は必要ありません。
このイベントリスナをonEnbale()メソッドでPluginManager#registerEvent()を使って待機できるようにさせます。

```SamplePlugin.kt
package com.example.sample

import import cn.nukkit.plugin.PluginBase

class SamplePlugin() : PluginBase() {
    override fun onEnable() {
        server.pluginManger.registerEvents(HogeListener(), this)
    }
}
```

#### インスタンスの生成

Kotlinではインスタンスの生成で`new`キーワードを使わず、メソッドと同じようにクラス名の後ろに`(/* 引数 */)`を指定するだけでインスタンスが返されます。

### コマンド

まず、パーミッションを設定するために`build.gradle.kts`の一部を以下のように変更してください。変更する個所は適宜変えてもらっても構いません。

```build.gradle.kts
nukkit {
    main = "com.example.sample.SamplePlugin"
    api = listOf("1.0.9")
    authors = listOf("your name")
    parmission {
        "sample.*" {
            children {
                "sample.command" {
                    description = "Sample Commands"
                    default = NukkitPluginDescription.Permission.Default.TRUE
                    children {
                        "sample.command.hoge" {
                            description = "Hoge Command Permission"
                            default = NukkitPluginDescription.Permission.Default.TRUE
                        }
                    }
                }
            }
        }
    }
}
```

コマンドクラスを作成します。

```HogeCommand.kt
import cn.nukkit.command.Command
import cn.nukkit.command.CommandSender

class HogeCommand() : Command("hoge") {
    init {
        permission = "sample.command.hoge"
        permissionMessage = "権限(<permission>)を持っていません"
    }

    override fun execute(sender: CommandSender, commandLabel: String, args: Array<String>): Boolean {
        if(!testPermission(sender)) return false
        sender.sendMessage("Hoge")
        return true;
    }
}
```
コンストラクタはクラス名の後に宣言します。親のコンストラクタも同様にクラス名の後に続いて渡してください。
initはコンストラクタが呼ばれた際に初期化処理を行うブロックです。

```SamplePlugin.kt
package com.example.sample

import import cn.nukkit.plugin.PluginBase

class SamplePlugin() : PluginBase() {
    override fun onEnable() {
        server.commandMap.register("sample", HogeCommand())
    }
}
```

こちらもイベントリスナと同じく作成したコマンドクラスをCommandMap#register()を使用して登録します。register()の第一引数はプラグインで一意となる文字列(プラグイン名でも可)、第二引数に作成したコマンドクラスのインスタンスを渡してください。

## まとめ

想定していた内容が大きくなりそうだったので、半分くらい削ってイベント・クラスのみの解説と軽めにしました。
~~次回の記事をいつ書くかは未定ですが、~~[#3](https://qiita.com/UramnOIL/items/e8282140748872fb3ff2)では外部プラグインが提供するAPIの利用やAPIの作成の手順を解説します。
FallbackPrefixを初めて知った

FallbackPrefixの存在を初めて知りました。

```HogeCommand.kt
class HogeCommand : Command("hoge") {
    override fun execute(sender: CommandSender, commandLabel: String, args: Array<String>) = true
}
```

```ExamplePlugin.kt
class ExamplePlugin : PluginBase() {
    override fun onEnbale() = server.commandMap.register("example", HogeCommand())    //第一引数がFallbackPrefix
}
```

FallbackPrefixはプラグインで一意にしてください。
`/example:hoge`を送信するとHogeCommandが実行されます。`/fallbackPrefix:command`という記法です。
pythonからsqliteに接続

#メモリ上にデータベースを作る
テーブルの削除などが不要になるので何度もSQLを実行して試したい時に便利です。

```py
import sqlite3

#conn = sqlite3.connect('test_sqlite.db')
conn = sqlite3.connect(':memory')

curs = conn.cursor()

curs.execute('CREATE TABLE persons(id INTEGER PRIMARY KEY AUTOINCREMENT,name STRING)')

curs.execute('INSERT INTO persons(name) values("Mike")')
curs.execute('INSERT INTO persons(name) values("Nancy")')
curs.execute('INSERT INTO persons(name) values("Jun")')
conn.commit()

curs.execute('SELECT * FROM persons')
print(curs.fetchall())

curs.close()
conn.close()
```
実行結果：

```
[(1, 'Mike'), (2, 'Nancy'), (3, 'Jun')]
```
Python初心者が　ModuleNotFoundError: No module named 'tweepy' で挫けそうになった話

# あらすじ　
インストールしたはずのtweepyが何故かimport出来なかった人の話です。
解決に丸一日かかりました。多分[teratail](https://teratail.com)が無かったら解決してない。
有識者の皆さん本当にありがとう

# 便利だったコマンド
**`pip3 show tweepy`** --- Macのターミナルで使用　インストール出来てるかを確認出来た。location 
で何処にあるか確認出来ました。

**`import sys`**
**`import pprint`**
**`pprint.pprint(sys.path)`** --- この３行を一つで使ってました。もし使う人がいたらpython(?)の.pyファイルで保存して実行してみてください。何処を参照してるかが分かります。

https://qiita.com/kakari8888/items/86d9c255204b063c87ee
この記事がとても助かりました。

# 解決のあらすじ
結果的には上記のpip show tweepyで分かった
locationの**/usr/local/lib/python3.7/site-packages**を参照してないことが分かったので、パスを通しました。
何処を修正すればいいかは意外とすぐ分かったんですが、その修正がマジでわからんかった。

# 解決の道筋
まず、

```python
import sys
sys.path.append('/usr/local/lib/python3.7/site-packages')
```

を延々とやってました。このpath自体にミスは無いんですが、このpathは
**プログラム実行中にしか反映されない**
ものなんです。こんな簡単なこと...と解決してからは思いますが気づけないものです。
このことに気づけたのでtweepyでツイートするコードと合体させました。

```python
import sys
sys.path.append('/usr/local/lib/python3.7/site-packages')

#!/usr/bin/env python
# coding:utf-8

#Tweepyのインポート
import tweepy

#各種キーをセット
CONSUMER_KEY = 'xxxxx'
CONSUMER_SECRET = 'xxxxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
ACCESS_TOKEN = 'xxxxx'
ACCESS_TOKEN_SECRET = 'xxxxx'
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

#APIインスタンスを作成
api = tweepy.API(auth)

#ツイート内容を記入
api.update_status("Hello World")
```

各種キーのxxxxxは自分のAPIを入れてください。
これでHello World とツイートできてたら大丈夫です。
初めての投稿なのでお見苦しいところもあるかと思いますが、参考にしていただければ幸いです。
敢えてRubyで学ぶ「ゼロから作るDeep Learning」学習回答ラベルをone hot vector形式に

Red DatasetsのMNISTのデータの回答ラベルは`t_train[0] = 5`みたいに整数型で入っている。これを`[0,0,0,0,0,1,0,0,0,0]`のone-hot vector形式に変換してみる

## コード

```ruby
require 'numo/narray'

def change_one_hot_vector(t)
  t_hot = Numo::UInt32.zeros(10 * t.length).reshape(t.length, 10)
  t_label = Numo::UInt32.new(t.length).seq * 10 + t
  t_hot[t_label] = 1
  t_hot
end
```

## 結果

```irb
=>
> train = Datasets::MNIST.new(type: :train)
> t_train = Numo::NArray.concatenate(train.map{|t| t.label })
> t_hot = change_one_hot_vector(t_train)
> t_hot[[0,1,2,3],true] #とりあえず4つくらい表示
=> Numo::UInt32(view)#shape=[4,10]
[[0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 
 [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
> t_hot[1000,true].max_index == t[1000] #一致するかの確認
=> true
```

問題なく動作した。

## これを元にSoftmax-with-Lossレイヤを実装

```ruby:soft_max_with_loss.rb
require 'numo/narray'
require './functions'
class SoftmaxWithLoss
  def initialize
    @loss = nil
    @y = nil
    @t = nil
  end

  def forward(x, t)
    @t = t
    @y = softmax(x)
    @loss = cross_entropy_error(@y, @t)

    @loss
  end

  def backword(dout=1)
    batch_size = @t.shape[0]
    t_hot = @t
    if @t.size != @y.size
      t_hot = change_one_hot_vector(@t)
    end
    (@y - t_hot) / batch_size
  end

  private
  def change_one_hot_vector(t)
    t_hot = Numo::UInt32.zeros(10 * t.length).reshape(t.length, 10)
    t_label = Numo::UInt32.new(t.length).seq * 10 + t
    t_hot[t_label] = 1
    t_hot
  end
end

```
Obj.Obj2.func().func2()みたいな多重構造にSpyしたい場合

Jasmine3.3

当たり前のやり方だけど、何回も混乱したのでメモ
ServiceのPropertyにSpyする場合。

```javascript:test.service.ts
export class TestService {
  obj: Something

  test() {
    obj.obj2.func().func2();
  }
}
```

```javascript:test.service.spec.ts

describe('TestService', () => {
let testService: TestService();

  beforeEach(() => {
    testService = new TestService(); //サービスの初期化
    let testSpy: any = testService;
  });

  it('test') () =>{

    const func2Obj = jasmine.createSpyObj('Ethereum', ['func2']);
    func2Obj.func2.and.returnValue(/* 任意の処理 */);

    const funcObj = jasmine.createSpyObj('Func', ['func']);
    funcObj.func.and.returnValue(func2Obj); // func2をリターン

    testSpy.obj = {obj2: funcObj} //funcObjを持つobj2を持つオブジェクトを挿入

    testSpy.test();
  });
});
```
IntelliJ IDEA + sbt 環境のための .gitignore の作り方

## gibo を使おう

.gitignore を生成してくれるコマンドツール [gibo](https://github.com/simonwhitaker/gibo) を使いましょう。楽なので。

導入方法は省略します。Windows ユーザーは [scoop](https://scoop.sh/) を使いましょう。

```shell
$ gibo dump Scala SBT JetBrains >> .gitignore
```

はい、これでおしまい... ではありません！

生成された .gitignore を開いて、次に示す文章の5行目以降をコメントアウトします:

```plaintext
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
```

そして、最終行に以下の内容を追加しましょう:

```plaintext
.bsp
```

おわり
オンプレミスからの名前解決にAzureのプライベートDNSゾーンを使いたい

tl;dr
--------

DNSプロキシサーバを置くことで可能です。

https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances

> シナリオ: オンプレミスのコンピューターからの Azure のホスト名の解決。
> ソリューション: 対応する仮想ネットワーク内のユーザーが管理する DNS プロキシ サーバーにクエリを転送し、プロキシ サーバーが解決するために Azure にクエリを転送します。 「独自の DNS サーバーを使用する名前解決」を参照してください。


試す
-------

### 準備

準備として、プライベートDNSゾーンを用意します。また、このプライベートDNSゾーンをVMが稼働している仮想ネットワークへリンクしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/f88b2623-75df-70ed-ae14-6ebe35ad8e15.png)

今回は`fukasawah.dev`で、Aレコードに`vm-1 => 10.0.0.5`を加えておき、これをオンプレミス上から名前解決できるところがゴールです。

ちなみにオンプレミスとの接続構成は仮想ネットワークゲートウェイ(VPN)を使ったSite to Siteです。


### 仮想ネットワーク上にDNSプロキシサーバを立てる

今回はAzureでubuntuイメージからVMを作り、そこにdnsmasqを入れます。
dnsmasqは内部向けのDNSキャッシュサーバとして使われますが、ネットワークへ公開することでDNSプロキシサーバっぽくふるまうこともできます。
~~すでにsystemd-resolvedが動いていますが、公開の設定の仕方もよくわからなかったのでdnsmasqを立てたという感じです。~~

今回、VMのプライベートIPは「10.0.0.4」でしたが、適宜置き換えてください。0.0.0.0を指定するやりかたがなぜか使えなかったので・・・（おそらくsystem-resolvedがいるから？）

``` bash
sudo apt update
sudo apt install dnsmasq

sudo tee -a /etc/dnsmasq.conf << 'EOF'
interface=eth0
listen-address=10.0.0.4
port=53
EOF

sudo systemctl restart dnsmasq
```

Azureのubuntuは`/etc/resolve.conf`の設定に従い、「ローカルのsystemd-resolved」を通して「Azure DNS」に問い合わせます。

試すだけであればこれで完了です。


### クエリを投げて確認

オンプレミス上のマシンからnslookupを試してみます。nslookupは第2引数にDNSサーバのIPを指定することでDNSサーバを明示できます。

```
C:\Users\fukasawah> nslookup vm-1.fukasawah.dev 10.0.0.4
サーバー:  vm-0.internal.cloudapp.net
Address:  10.0.0.4

権限のない回答:
名前:    vm-1.fukasawah.dev
Address:  10.0.0.5
```

後はオンプレミスからはこのDNSプロキシサーバのIPを使うよう、DHCPの設定なりPCのネットワーク設定を変えればよいでしょう。

### 蛇足：DNSプロキシサーバ無しにできない・・・っぽい

> DNS クエリ トラフィックは VM ごとに調整されます。 

と、ドキュメントに書かれています。ここで「調整されてもいいからDNSプロキシサーバを仮想ネットワークに置きたくない」という場合、それは出来るのかどうか？というのをやってみました。（オンプレにだけDNSプロキシサーバをおきたい、など...。）

結果としては出来ませんでした。
単純にAzureのDNSサーバである`168.63.129.16`を **仮想ネットワーク内から** アクセスできればよいのでは？と思い、オンプレミスからの`168.63.129.16`への通信を仮想ネットワークゲートウェイに向けるようにルータのルーティングをいじってみました。が、手元の環境ではうまくいきませんでした。
私のルータのルーティングの設定が誤っているか、仮想ネットワークゲートウェイから`168.63.129.16`への通信ができないと考えられます。
Linuxのファイル圧縮・解凍のコマンドいろいろ

LPIC101の学習の際に圧縮・解凍系のコマンドがいろいろ出てくるので、整理してみることにした。

# gzipコマンド
`gzip [オプション] [ファイル名]`
オプション無しで圧縮。

|主なオプション  |説明  |
|---|---|
|-d  |圧縮ファイルを展開(圧縮ファイルは残らない)  |
|-c  |元ファイルを残して標準出力に出力  |
|-r  |ディレクトリ内の全てのファイルを再帰的にそれぞれ圧縮  |

# gunzipコマンド
`gunzip [ファイル名]`
gzipのdオプションと同様。

# xzコマンド
`xz [オプション] [ファイル名]`
gzip,bzip2コマンドより圧縮率が高い。

|主なオプション  |説明  |
|---|---|
|-d  |圧縮ファイルの展開 |
|-k  |圧縮・展開後に元ファイルを残す  |
|-l  |圧縮ファイルの情報を表示する  |

# unxzコマンド
`unxz [ファイル名]` 
xzコマンドのdオプション使用時と同じ。

# tarコマンド
tarコマンドはアーカイブの作成・展開のコマンドだがオプションで圧縮・解凍もできる。
`tar [オプション] [ファイルまたはディレクトリ名]`

|主なオプション  |説明  |
|---|---|
|-c  |アーカイブを作成  |
|-x  |アーカイブを展開  |
|-t  |アーカイブの内容を表示  |
|-v  |詳細情報の表示  |
|-z  |gzipを通して圧縮・展開  |
|-j  |bzip2を通して圧縮・展開  |
|-J  |xzを通して圧縮・展開  |

#cpioコマンド
cpioコマンドもアーカイブの作成・展開のコマンド。
cpio [オプション]

|主なオプション  |説明  |
|---|---|
|-o  |アーカイブ作成 |
|-i  |アーカイブ展開  |

cpioコマンドは標準入力や標準出力を使用するため、find,lsなどで入力情報をパイプで渡して、リダイレクトで出力する。

#bzip2コマンド
`bzip2 [オプション] [ファイル名]`
オプション無しで圧縮。

|主なオプション  |説明  |
|---|---|
|-d  |圧縮ファイルを展開 |
|-c  |元ファイルを残して標準出力に出力  |

#bunzip2コマンド
bunzip2 [ファイル名]
bzip2コマンドのdオプション使用時と同じ。

#bzcatコマンド
`bzcat [ファイル名]`
bzip2コマンドのcオプション使用時と同じ。
sshの秘密鍵のパスフレーズを削除する

## 概要
サーバーに接続する際に秘密鍵を使ってssh接続することがあるかと思います。
この秘密鍵を自分でサーバー上で生成することができればいいのですが、
最近のクラウド環境とかだとsshキーを管理画面上で生成する形式を取っていてsshキーのパスワードを設定しないといけないことがあります。
もちろん商用環境で自分勝手にパスフレーズ消すみたいなセキュリティレベルを下げることは、エンジニアならやってはならないことです。。。

でも個人が私用で使うサーバーとかでならそこまでセキュリティレベル上げんでもいいと思うのでパスフレーズ削除を消しました。

## 秘密鍵のパスフレーズを削除

```
ssh-keygen -f 秘密鍵 -p
```
ssh-keygenはコマンドの英語の意味そのものですが、
sshキーを生成するコマンドです。
オプションとして -f で読み込むファイルを指定します。
-p はパスフレーズを変更するときに使います。
対話形式で表示されます。
下記はコマンドの実行結果です。

```
Enter old passphrase:
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
```
最初に元々の古いパスフレーズを入れます。
そして次に新しいパスフレーズを入力してくださいと出ますが、
ここでそのまま何も入力しないでエンターを押せばパスフレーズがない秘密鍵が生成されます。

## 終わりに
今回はちょっとしたtipsのようなお話でした。
opensslコマンドでパスフレーズを変更する方法もありますが、
バージョンなどの関係でsshで接続できているならこっちの方が楽かなと思います。
[React.js]useEffectの第2引数

## useEffectに関して

```js:React.js

  useEffect(() => {
    console.log('This is like componentDidmount or componentDidupdate.')
  });  //マウントまたは更新された時

  useEffect(() => {
    console.log('this is componentDidmount');
  },[]); //マウントされた時のみ（値が更新されても再レンダーされない）

  useEffect(() => {
    console.log('this callback is for name only');
  },[name]);  //value値が更新された時のみ表示する

  return (
    <>
      <p>現在の{name}は、{price}円です</p>
      <button onClick={() => setState({...state, price: price + 1})}>+1</button>
      <button onClick={() => setState({...state, price: price - 1})}>-1</button>
      <button onClick={() => setState(props)}>Reset</button>
      <input  value={name}　onChange={e => setState({...state, name: e.target.value})}/>
    </>

```


## 説明

useEffectはReact.jsの16.8から使用できるようになったReact Hooksの一つ。
①第2引数を持たいない場合は、マウントもしくは値が更新された際に再レンダーが走る。
②第2引数が空配列の場合は、マウントされたときのみ再レンダーされる。
③第2引数の配列に値を入れるとそれが更新された時のみサイレンダーされる。
【Udemy Python3入門+応用】　28. 集合型

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■集合型
#####◆基本
```
>>> a = {1, 2, 2, 3, 4, 4, 4, 5, 6}
>>> a
{1, 2, 3, 4, 5, 6}
>>> type(a)
<class 'set'>
```
`{}`は辞書型でも使ったが、今回keyとvalueにはなっておらず、集合型となる。
このとき、重複している要素は1つにまとまる。

#####◆集合の引き算
```
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {2, 3, 6, 7}
>>> a - b
{1, 4, 5}
>>> b - a
{7}
```
`a - b`により、「a」から「aかつb」が除かれ、
`b - a`により、「b」から「aかつb」が除かれている。

#####◆a かつ b
```
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {2, 3, 6, 7}
>>> a & b
{2, 3, 6}
```

#####◆a または b
```
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {2, 3, 6, 7}
>>> a | b
{1, 2, 3, 4, 5, 6, 7}
```

#####◆`a ^ b`
```
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {2, 3, 6, 7}
>>> a ^ b
{1, 4, 5, 7}
```
「a または b」から「a かつ b」を除いたもの。
aとbどちらか一方にのみあるもの。

#####◆ちなみに`+`
```
>>> a = {1, 2, 3, 4, 5, 6}
>>> b = {2, 3, 6, 7}
>>> a + b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'
```
`a + b`だとエラーになる。
非同期レンダリング (async属性)

## レンダリングの仕組み
ブラウザ(Google ChromeやSafari)はhtmlファイルを上から順番に解析します。
htmlにCSSファイルやJavaScriptファイル、写真等のURLがあった場合、その都度サーバからファイルをダウンロードします。

## 非同期、非同期処理とは
あるタスクが実行をしている時に、他のタスクが別の処理を実行できる方式。

分かりにくいので下記は例です。
> 例)写真の表示(非同期読み込み)の場合
> 1. 写真のダウンロードを開始する(ダウンロードに1分かかる)。
> 2. 写真のダウンロードは時間がかかるため、ダウンロード完了を待たずに次の処理に進む。
> 3. 写真のダウンロードが完了したタイミングで写真表示の処理を行う。


## イメージ(同期)
webサイトの表示に必要なリソース(CSS、JavaScript、写真)をダウンロード完了後、次の処理にいく。
ブラウザは、JavaScriptファイルのダウンロードが完了しないと次に進めないので、JavaScriptファイルの読み込みがレンダリングをブロックしている。
![Untitled Diagram-同期処理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35255/61c1a5bb-6ad7-43c7-390f-b40dafd6ce1b.png)


## async="true"をつけた場合（非同期）
②'のJavaScriptファイルは②のCSSファイルのダウンロードとほぼ同時にダウンロードを開始する。ブラウザはJavaScriptファイルのダウンロード完了を待たずに次の処理にいく。
JavaScriptファイルのダウンロード完了を待たずにブラウザは次の処理に進めるので、JavaScriptファイルの読み込みはレンダリングをブロックしない。
![Untitled Diagram-非同期処理 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35255/f48fdd75-c925-9c72-8fb7-95367b201098.png)
非同期通信

message.js
var html =
<div class="message">
</div>
の記述を余計に書いててメッセージを投稿する際とメッセージの位置がずれ、更新すると元に戻る現象が起きてしまった

resetメソッド
$('クラス名')[0].reset();
クラス名間違いをしてconsoleでエラー検証でよく確認

animateメソッド
メソッドばかりに目がいってしまい、cssのoverflow: scroll;を記述し忘れメッセージ覧のスクロールができなかった

.append()
指定した子要素の最後にテキスト文字、HTML要素を追加する
error : Module 'xxx' can only be default-imported using the 'esModuleInterop' flag

TypeScriptのエラーについてです。

次のようにnpmパッケージをインストールし、tsファイル で import したところ、以下のエラーが出て困りました。

```sh
$ npm install xxx
```

```typescript:hoge.ts
import xxx from "xxx";
```

# エラーについて
```sh
Module 'xxx' can only be default-imported using the 'esModuleInterop' flag

# エラー箇所の指摘（省略）

This module is declared with using 'export =',
and can only be used with a default import when using the 'esModuleInterop' flag.
```

# 直し方
エラーメッセージをきちんと読むとわかるのですが、 tsconfig.json の `compilerOptions` に  `"esModuleInterop": true` を追加してあげます。
これで、`import xxx from "xxx"`を使うことができます。

```js:tsconfig.json
{
  "compilerOptions": {
    "esModuleInterop": true
  }
}
```
ノートっぽいスタイルシート

# ノートっぽいスタイルシート【主にVSCode用】

自分がVisual Studio CodeでMarkdownやAsciiDocでメモ書きを行う際にあまりにも見づらかったため、見やすいスタイルシートを作りました。


## デザイン

見た目はこんな感じです。行間を広めに設定し、バランスを整えました。

![z1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/ed7f18b3-34f1-dcf8-0683-bbd507d6abcb.png)

ちなみにこれがデフォルトの表示。

![z2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/684690ca-568c-fd99-fb75-60f0c49ef3e6.png)

## ダウンロード

MarkdownとAsciiDocに対応しています。

- [NotePoi Style Sheet - Gist](https://gist.github.com/Masterexa/9bce598a89efd228100452ea0d609a63)

(~~QiitaはGistのインライン表示できない、そのせいでトイレットペーパー品切れしそう~~)
【Udemy Python3入門+応用】　27. 辞書の使い所

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##辞書の使い所
```python:dict
# 各果物の値段を登録しておく
fruits = {
    'apple': 100,
    'banana': 200,
    'orange': 300,
}

# appleの値段を調べる
print(fruits['apple'])
```
```:result
100
```
【Kotlin】withContext が切り替わるところで何もしていない場合にも CoroutineDispatcher は切り替わるのか？

## 問題

`dispatcherO`, `dispatcherA`, `dispatcherB` をそれぞれ `CoroutineDispatcher` とする。

次のコードでコメントを記しているような、`withContext` が切り替わるところで何もしていない場合にも、`CoroutineDispatcher` は切り替わるのだろうか。

```Kotlin:パターン1（連続してwithContextから出る）
withContext(dispatcherA) {
  actionA()
  
  withContext(dispatcherB) {
    actionB()
  }
  
  // ここで一旦 dispatcherA に切り替わるか？
}
```

```Kotlin:パターン2（連続してwithContextに入る）
withContext(dispatcherB) {
  // ここで一旦 dispatcherB に切り替わるか？
  
  withContext(dispatcherA) {
    actionA()
  }
  
  actionB()
}
```

```Kotlin:パターン3（withContextから出てすぐにwithContextに入る）
withContext(dispatcherO) {
  withContext(dispatcherA) {
    actionA()
  }
  
  // ここで一旦 dispatcherO に切り替わるか？

  withContext(dispatcherB) {
    actionB()
  }
}
```

## 実験

まず次のように、シングルスレッドの `CoroutineDispatcher` を用意する。

```Kotlin
import java.util.concurrent.Executors

val dispatcherO = newSingleThreadDispatcher()
val dispatcherA = newSingleThreadDispatcher()
val dispatcherB = newSingleThreadDispatcher()

fun newSingleThreadDispatcher(): CoroutineDispatcher =
    Executors.newSingleThreadExecutor().asCoroutineDispatcher()
```

そして次の3つの実験コードを実行した。

```Kotlin:パターン1の実験コード
    runBlocking(dispatcherO) {
        withContext(dispatcherA) {
            actionA()

            // dispatcherA を1000ミリ秒間占有する。
            launch(dispatcherA) {
                Thread.sleep(1000)
                println("dispatcherA の占有終了")
            }

            withContext(dispatcherB) {
                actionB()
                Thread.sleep(500) // dispatcherA の占有が開始されるのを待つ。
            }

            // ここで一旦 dispatcherA に切り替わるか？
        }

        println("全処理終了")
    }
```

```text:パターン1の結果標準出力
dispatcherA の占有終了
全処理終了
```

```Kotlin:パターン2の実験コード
    runBlocking(dispatcherO) {
        // dispatcherB を1000ミリ秒間占有する。
        launch(dispatcherB) {
            Thread.sleep(1000)
            println("dispatcherB の占有終了")
        }

        Thread.sleep(500) // dispatcherB の占有が開始されるのを待つ。

        withContext(dispatcherB) {
            // ここで一旦 dispatcherB に切り替わるか？

            withContext(dispatcherA) {
                println("actionA 開始")
                actionA()
            }

            actionB()
        }
    }
```

```text:パターン2の結果標準出力
dispatcherB の占有終了
actionA 開始
```

```Kotlin:パターン3の実験コード
    runBlocking(dispatcherO) {
        // dispatcherO を1000ミリ秒間占有する。
        launch(dispatcherO) {
            Thread.sleep(1000)
            println("dispatcherO の占有終了")
        }

        withContext(dispatcherA) {
            Thread.sleep(500) // dispatcherO の占有が開始されるのを待つ。
            actionA()
        }

        // ここで一旦 dispatcherO に切り替わるか？

        withContext(dispatcherB) {
            println("actionB 開始")
            actionB()
        }
    }
```

```text:パターン3の結果標準出力
dispatcherO の占有終了
actionB 開始
```

## 結果

いずれも、1000ミリ秒間の dispatcher の占有が終わるまで、コメントの箇所の次の処理に進めなかった。
したがって、
「`withContext` が切り替わるところで何もしていない場合にも、
　`CoroutineDispatcher` は切り替わる」
と言える。
メガドライブソフトをCircleCIでビルドする

# きっかけ
macOSをCatalinaにアップグレードしたら、[WineでのSGDKプロジェクトビルド](https://github.com/v4ld3r5/sgdk_vscode_template)ができなくなったので…。仲間内でビルド環境を共有したいし、ちょうどよいかなと。
# 前提
GitHubアカウントがあればよい。リポジトリは作っておく。CircleCIはGitHubアカウントでログイン可能なので、リポジトリを連携する。
# ビルド設定
SGDKのお作法に則ってsrcディレクトリに`*.c`や`*.h`ファイルなど（bootディレクトリもお忘れなく…）、resディレクトリに`*.res`やリソースファイルを置いておく。

```yaml:.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: ubuntu:bionic
    steps:
      - run: |
          apt-get update
          apt-get install -y curl texinfo openjdk-8-jre make
      - run: |
          curl -L -o gendev.deb https://github.com/kubilus1/gendev/releases/download/0.4.1/gendev_0.4.1_all.deb
          dpkg -i gendev.deb
          rm gendev.deb
      - checkout
      - run: |
          export GENDEV=/opt/gendev
          make -f $GENDEV/sgdk/mkfiles/makefile.gen clean all
      - store_artifacts:
          path: ./res
      - store_artifacts:
          path: ./out
```
リソースのヘッダファイルを確認したかったので、`store_artifacts`に`./res`を含めている。
## ハマりポイント
- [GENDEV公式](https://github.com/kubilus1/gendev)には`openjdk-8-jdk`が必要とあったが、debパッケージインストール時は`openjdk-8-jre`が求められた
- `checkout`は空ディレクトリを期待しているので、`rm gendev.deb`をしないとエラーになる

# 参考文献
- [SGDK](https://github.com/Stephane-D/SGDK)
- [GENDEV - Genesis development environment for Linux](https://github.com/kubilus1/gendev)
ポップアップウィンドウでgit blameを確認できる blamer.nvim

# 概要
[APZelos/blamer.nvim](https://github.com/APZelos/blamer.nvim)は VSCodeの [GitLens](https://gitlens.amod.io/) に触発されて開発されたplugin。<br> [vim-fugitive](https://github.com/tpope/vim-fugitive) の `Gblame` しか使わない自分にとってちょうどよかった。

## 使い方

`:BlamerToggle` を実行

### 1行だけの確認
確認したい行にカーソルを合わせる
![normal.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68643/5b6b646d-25b0-331c-d45d-2a559833660b.gif)

### 複数行の確認
ビジュアルモードで確認したい行を選択する
![visual.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68643/fa160a93-2c60-989e-b3c9-dcde0d551ea9.gif)

## 設定項目
| 項目              | 内容              | Default |
|:-----------------|:------------------|:------------------:|
| blamer_enabled   | vim起動と同時に起動させる | 0 |
| blamer_delay           | ポップアップウィンドウを表示させるまでの時間(ミリ秒) |       1000       |
| blamer_show_in_visual_modes | visualモードでの表示 |        1   |
| blamer_prefix               |  テンプレートのprefix |         ' '         |
| blamer_template             | ポップアップウィンドウに表示する内容 | `<committer>`, `<committer-time>` • `<summary>` |
| blamer_date_format          | commit日時のフォーマット | %d/%m/%y %H:%M |

基本的にデフォルトのままで問題なく使えますが、
commit日時のフォーマットを `%y/%m%d %H:%M` に変更しました。

```vimscript
let g:blamer_date_format = '%y/%m/%d %H:%M'
```

## GitHubリポジトリ
[APZelos/blamer.nvim](https://github.com/APZelos/blamer.nvim)
【Udemy Python3入門+応用】　26. 辞書のコピー

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■辞書のコピー
```python:copy_dict
x = {'a': 1}
y = x
y['a'] = 1000
print('x = ', x, type(x), id(x))
print('y = ', y, type(y), id(y))
```
```:result
x =  {'a': 1000} <class 'dict'> 4486017904
y =  {'a': 1000} <class 'dict'> 4486017904
```
辞書のコピーに関しても、リストのコピーと同様になる。

```python:copy_dict
x = {'a': 1}
y = x.copy()
y['a'] = 1000
print('x = ', x, type(x), id(x))
print('y = ', y, type(y), id(y))
```
```:result
x =  {'a': 1} <class 'dict'> 4342547312
y =  {'a': 1000} <class 'dict'> 4342547392
```
`.copy`を用いることで、xへの影響を回避できる。

####◆参照
[【Udemy Python3入門+応用】　19. リストのコピー](https://qiita.com/Fumiya_G/items/45a63472c42ba6194c44)
ユーザーからの入力を受け取る

#`std::io::stdin()`
これはちょっと難しいので、Rustに慣れるまでは丸暗記で行くしかなさそうです。
使い方はこんな感じです。

~~~rust
fn main() {
    println!("何か入力してください。"); // 入力を促す案内を表示する

    let mut input = String::new(); // 入力した値を入れる変数

    // これが入力を受け取るコード。
    // 複雑。この3行にたくさんのロジックが詰め込まれています。
    std::io::stdin()
        .read_line(&mut input)
        .expect("Failed to read line");

    input = input.trim_end().to_owned(); // エンターキーで改行が末尾に入るので、改行をなくす

    println!("入力したのは「{}」です", input); // 入力した文字列をそのまま表示する。
}
~~~

丸暗記と言いましたが、暗記するくらいなら関数にしてしまいましょう。
`my_read_line()`関数を作ってみました。これなら簡単だし、見た目もすっきりしました。

~~~rust
fn main() {
    let input = my_read_line("何か入力してください"); // この１行で入力の案内と入力の受け取りをする
    println!("入力したのは「{}」です", input);
}

/// ユーザーの入力を受け取り、Stringを返す関数。
///
/// massage：入力を促すメッセージ
fn my_read_line(massage: &str) -> String {
    println!("{}", massage);
    let mut input = String::new();
    std::io::stdin()
        .read_line(&mut input)
        .expect("Failed to read line");
    input.trim_end().to_owned()
}

~~~


[目次](https://qiita.com/tonesuke/items/52e469f18e747c794376)
【Golang】Modules環境で相対パスimport (Go:1.13)

ちょっとハマったので自分用メモ。
Go Modules環境でローカルに配置した共有packageと、子packageを使う場合の指定の仕方。

# TL;DR
別moduleならgo.modに`replace`で相対パスを記載する。
同一moduleなら`import 自module名/ディレクトリ名`で指定する。

# フォルダ構成
```
project_root
  ├── module_a
  │    ├── go.mod
  │    └── main.go ... ここで common_module/common を使いたい
  │
  ├── module_b
  │    ├── go.mod
  │    ├── main.go ... ここで common_module/common と sub_package を使いたい
  │    └── sub_package
  │         └── sub.go
  │
  └── common_module
       ├── go.mod
       └── common.go
```

# ソースコード
https://github.com/suecideTech/sample-codes/tree/master/go-module-package

### module_a

```go:module_a/go.mod
module module_a

go 1.13

require common_module/common v0.0.0

replace common_module/common => ../common_module
```

```go:module_a/main.go
package main

import (
    "common_module/common"
)

func main() {
    common.Test()
}
```

### module_b

```go:module_b/go.mod
module module_b

go 1.13

require common_module/common v0.0.0

replace common_module/common => ../common_module
```

```go:module_b/main.go
package main

import (
    "common_module/common"
    sub "module_b/sub_package"
)

func main() {
    common.Test()
    sub.Sub()
}
```

# 参考
以下のサイトを参考にしました。

モノレポ（mono repository）内でgoのmoduleを相対パスで利用する方法
http://chidakiyo.hatenablog.com/entry/2019/07/04/%E3%83%A2%E3%83%8E%E3%83%AC%E3%83%9D%EF%BC%88mono_repository%EF%BC%89%E5%86%85%E3%81%A7go%E3%81%AEmodule%E3%82%92%E7%9B%B8%E5%AF%BE%E3%83%91%E3%82%B9%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B

ローカル環境のみでの Go Modules と自作パッケージ
https://qiita.com/tkj06/items/a5f79417935100045650

Go Modulesとマルチモジュール構成でGo Homeする方法
https://qiita.com/hinastory/items/336c2d944fdb8ae11efb

~~[そもそもマルチモジュールって非推奨なんですね](https://github.com/golang/go/wiki/Modules#should-i-have-multiple-modules-in-a-single-repository)~~
Laravelクエリビルダmemo②(サブクエリのJOIN)

laravelのクエリビルダに関してのメモです。

####やりたいこと
サブクエリをJOINしたい。

####joinSub()
公式リファレンス
https://readouble.com/laravel/5.8/ja/queries.html?header=%25E3%2582%25B5%25E3%2583%2596%25E3%2582%25AF%25E3%2582%25A8%25E3%2583%25AA%25E3%2581%25AEJOIN

今回はサブクエリで追加するカラムにデータがない場合も取得をしたいためleftjoin()で外部結合します。
leftjoinSub()の引数には、サブクエリ、テーブルのエイリアス、クロージャを定義します。
クロージャ内には結びつけるカラムの条件式を定義します。

```php
//サブクエリ
$rating_avgs = Review::selectRaw('movie_id, AVG(rating) as rating_avg')->groupBy('movie_id');

$movie = Movie::leftjoinSub($rating_avgs, 'rating_avg', function($join){
            $join->on('movies.id', '=', 'rating_avg.movie_id');})
           ->get();
```
サブクエリの`rating_avg`が同時に取得できています。

```
=> Illuminate\Database\Eloquent\Collection {#3155
     all: [
       App\Models\Movie {#3140
         id: 1,
         user_id: 1,
         title: "Title1",
         director: "Director1",
         actor: "Actor1",
         text: "これはテスト投稿1です。",
         deleted_at: null,
         created_at: "2020-03-01 05:04:58",
         updated_at: "2020-03-01 05:04:58",
         movie_id: 1,
         rating_avg: "3.0000",
       },
       App\Models\Movie {#3125
         id: 2,
         user_id: 2,
         title: "Title2",
         director: "Director2",
         actor: "Actor2",
         text: "これはテスト投稿2です。",
         deleted_at: null,
         created_at: "2020-03-01 05:04:58",
         updated_at: "2020-03-01 05:04:58",
         movie_id: 2,
         rating_avg: "4.0000",
       },
     ],
   }
```
原始的な静的サイトジェネレータを自作してみた

この記事は[私のブログ](https://qmainconts.f5.si/blog/articles/20200302232536.html)にも投稿していますので、よかったら見ていってください。

以前から私のブログで使っていた自作の<a href="https://github.com/Qman11010101/FakeBlogGenerator">静的サイトジェネレータっぽい何か</a>を大改造劇的ビフォーアフターして、原始的な静的サイトジェネレータ「blogen.py」を作りました。
リポジトリはこちら: <a href="https://github.com/Qman11010101/blogen.py">blogen.py</a>

## なぜ作った？
世の中には様々な静的サイトジェネレータが存在します。<a href="https://www.gatsbyjs.org/">Gatsby</a>やら<a href="https://hexo.io/">Hexo</a>やら。
洗練されているそれらを使わずにわざわざ車輪の再発明みたいなことをした理由は、いくつかあります。

- 既存静的サイトジェネレータの使い方がよくわからなかった
- 自分でサイトのデザインをしたかった
- 余計なファイルも生成されそうでなんか嫌だった

これを作り始めた当時の自分はあまり学習のモチベーションが高くなかったため、新しくツールを使うのが面倒くさくて嫌でした。~~今もそうです~~
結局、乏しいPythonの知識でそれっぽいものを作るところまではできてしまいました。しかし当時はJinja2などのHTMLテンプレートエンジンの存在を知らず、予め用意しておいたHTMLファイルの切れ端を合成するというよくわからないものになってしまいました。
結局Jinja2を使うように書き直したのですが、こんなガバガバな設計にしていたせいで苦労しました。知識は大事。

## 機能
この記事を書いた時点で、blogen.pyには以下の機能が備わっています。

- 記事・トップページの生成機能
- ブログディレクトリの生成機能
- Twitterでのお知らせツイート機能

逆に今現在備わっていない(実装したい)機能は以下の通りです。

- Markdownによる記事の執筆
- 記事のカテゴリ分け
- トップページの記事をn個ごとにページ分けする機能
- いいねボタン
- コメント欄

実装した機能は本当にこれだけです。強いて挙げるならTwitterで記事を共有するリンクが記事の下に生成される機能もありますが(実際に確かめてみてください)、JavaScriptでさらっと実装しただけなのでblogen.pyの機能ではありません。
逆に言えば、こんなに少ない機能でも最低限ブログとして成立してしまう、ということです。
これは既存ツールを使用していたら得られなかった気づきでした。

## メリット
blogen.pyを作って使ってみて、静的サイトジェネレータを自作する上でのメリットをいくつか見つけました。

### 使い方がわかりやすい
まあこれは自作な上に超低機能なツールなので当然です。

### 自分でブログをデザインできる
CSSを完全に自分で書いたため、デザインはほぼ完全に自由になりました。
これは当初目指していたことの一つだったので嬉しいです。

### 欲しい機能を自分で実装できる
もちろん、技術力があることが大前提です。

### 技術力が上がる
実装の際にめちゃくちゃググるので知識がついて実装力も上がる…と思います。
少なくとも「ちょっとしたツールが欲しい」と思ったときにさっと書く、といったことは可能です。

## デメリット
もちろん良い点ばかりではありませんでした。

### 実装が面倒くさい
あらゆる機能は自分で実装しなければいけないため、すぐに使うことができません。面倒くさいです。
まあ、それも楽しいんですけどね。

### ちゃんと実装しないと破綻する
例えば、トップページに表示する記事の数を調整できるようにしないと、理論上いつか大きすぎて読み込めなくなります。
他にも、カテゴリ分けの実装をした場合、すべての記事に手を加えなければいけなくなります。記事が十数個しかない今ならまだしも、何百個になってしまえば修正作業は非常に大変になります。

## まとめ
「静的サイトジェネレータ　自作」でググってみると、意外と皆静的サイトジェネレータを自作しています。自作してないのはお前だけ。
しかし皆さんちゃんと作り込んでてすごいです。blogen.pyは「自分が使えればいっか～！ｗ」的なノリで組んだものなので…
でも楽しいですよ、静的サイトジェネレータ自作。一度やってみませんか？
[Python]集合の演算では結果の要素数を小さくしよう

# 概要
集合の演算をするとき、得られる結果の要素数を小さくすることで実行速度を改善できる。
演算結果は新しい set オブジェクトで返されるため、要素数が大きいとオブジェクトの生成に時間がかかる。

# 背景
[ABC157 D Friend Suggestions](https://atcoder.jp/contests/abc157/tasks/abc157_d) にて、ある集合の要素数を計算するために `len(X-Y-Z)` としたら TLE になったが `len(X)-len(X&(Y|Z))` で AC できた。
なぜ速度が違うのか検証してみた。 

# |X| が大きいとき
問題の前提では $|X|,|Y|,|Z| \leq 10^5$ だが、今回は実際に遭遇した $|X| \gg |Y|,|Z|$ の条件を測定してみる。

```python
from timeit import timeit

xyz = 'X=set(range(10**5)); Y=set(range(10)); Z=set(range(5,15))' 

timeit('len(X-Y-Z)', setup=xyz, number=100)
# 0.3884289239649661

timeit('len(X)-len(X&(Y|Z))', setup=xyz, number=100)
# 0.0001103340182453394
```
結果は同じなのに、実行時間には実に3520倍の開きがある。

# X, Y, Z の内容が同じとき
次に、 X, Y, Z すべてを $10^5$ 個の同じ要素にしてみる。

```python
from timeit import timeit

xyz = 'X=set(range(10**5)); Y=set(range(10**5)); Z=set(range(10**5))'

timeit('len(X-Y-Z)', setup=xyz, number=100)
# 0.28364974400028586

timeit('len(X)-len(X&(Y|Z))', setup=xyz, number=100)
# 1.1718004010035656
```
今度は `len(X)-len(X&(Y|Z))` の方が遅くなった。 `X&(Y|Z)` は元の集合と同じであり、結果の要素数が大きくなったためと考えられる。
一方、 `len(X-Y-Z)` は `X-Y` の段階で空集合が得られるためか、 1/3 程度に短縮した。

# 差集合 vs 積集合

問題を単純化して、差と積の演算だけを比較してみる。演算の他方を空集合として、それぞれ左右を入れ替えてみた。

```python
from timeit import timeit

xy = 'X=set(range(10**5)); Y=set()'

timeit('X-Y', setup=xy, number=100)
# 0.16930873499950394
timeit('Y-X', setup=xy, number=100)
# 1.7047044821083546e-05

timeit('X&Y', setup=xy, number=100)
# 1.0746996849775314e-05
timeit('Y&X', setup=xy, number=100)
# 1.502997474744916e-05
```
差集合でも結果の要素数が小さいときは早い。どうやら、速度の差は演算の内容ではなさそうだ。

# set の生成
[Python ドキュメント set.difference](https://docs.python.org/ja/3.6/library/stdtypes.html#frozenset.difference)を参照すると、

> set に含まれて、かつ、全ての other に含まれない要素を持つ、新しい集合を返します。

とある。そこで、要素数が大きい set の生成時間を測定してみる。

```python
from timeit import timeit

timeit('set(X)', setup='X=set(range(10**5))', number=100)
# 0.16229172004386783
```

結局、結果の要素数が大きいとき、返す集合の生成に時間がかかっているだけだった。
【備忘録】Events Managerの小数点以下を削除する方法

WordPress初心者ですが、色々弄る機会があるので今後のために。

##デフォルト
チケットの価格を日本通貨で「3000円」で設定しようとすると、
$3000.00
と表示されます。

ドル→円表示は、
「管理画面」　→　「イベント」　→　「設定」　→　「予約管理」
で設定できますが、もともとドル表記のためか、小数点以下２桁が残ってしまいます。
そこで、pluginsのfunctionを弄ります。

##コード
デフォルトで229行目付近の em_get_currency_formatted の $precision = 2 を $precision = 0をにします。

>変更前

```php:em-functions.php
function em_get_currency_formatted($price, $currency=false, $format=false, $precision = 2){
	$formatted_price = '';
	if(!$format) $format = get_option('dbem_bookings_currency_format','@#');

 ・・・

}
```
>変更後

```php:em-functions.php
function em_get_currency_formatted($price, $currency=false, $format=false, $precision = ０){
	$formatted_price = '';
	if(!$format) $format = get_option('dbem_bookings_currency_format','@#');

 ・・・

}
```

##補足
コードの$precision = ０がなく、以下のようになっていることもあるようです。


```php:em-functions.php
function em_get_currency_formatted($price, $currency=false, $format=false){
	$formatted_price = '';
	if(!$format) $format = get_option('dbem_bookings_currency_format','@#');
	if(!$currency) $currency = get_option('dbem_bookings_currency');
	$formatted_price = str_replace('@', em_get_currency_symbol(true,$currency), $format);
	$formatted_price = str_replace('#', number_format( $price, 2, get_option('dbem_bookings_currency_decimal_point','.'), get_option('dbem_bookings_currency_thousands_sep',',') ), $formatted_price);
	return apply_filters('em_get_currency_formatted', $formatted_price, $price, $currency, $format);
}
```
この時は、

```php:em-functions.php
$formatted_price = str_replace('#', number_format( $price, 2, ・・・
```

２を０に変えます。


##あとがき
Qiita初めて書いたので無駄に細かく書きすぎて、読みづらかったかもしれません。

## 追記
プラグインファイルは直接触らない方がいいということを指摘していただきました。
大きな理由としては、プラグインのアップデートの際に設定が初期に戻ってしまうからです。

その回避手段としては、function.phpに記載することで解決します。
以下参考サイトです。
- [Events Managerの金額から小数点以下を削除する（プラグインのファイルは触らない）](https://nkmrkisk.com/archives/1883)
DriveのURLからデータを直接ダウンロード(+ Google Colaboratory)

2021/7/12追記
\* [gdownを用いてより簡単にダウンロードする手順を追記しました。](#最も簡単な方法)

# 初めに
以下この記事の流れです。
__1. Google Driveの共有リンクから直接ダウンロードを可能にする__
__2. pythonまたはwget,curl(CLI上)で先ほどのURLを用いてデータをダウンロード__
__3. Google Coloaboratoryでの実行する際の注意点__

# Google Driveの共有リンクで直接ダウンロード
Google Driveでファイル共有リンクを作成すると以下のようなページに飛び手動でダウンロードする手間がある。
<img width="1432" alt="スクリーンショット 2020-03-02 22.13.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426156/59da6b1d-eb78-2304-229f-e7b439092498.png">

そこでURLをクリックして直接ダウンロードを行えるようにURLを変換する。URL変換ツールなどが存在するが、URLを以下のように書き換えるだけでURLから直接ダウンロードが可能になる。

`file/d`->`uc?id=`or`uc?export=download&id=`
 `/view?usp=sharing`->` `

```
https://drive.google.com/file/d/<file_id>/view?usp=sharing
↓
https://drive.google.com/uc?id=<file_id>
or
https://drive.google.com/uc?export=download&id=<file_id>
```

# Python or Shellでダウンロード
先ほど変換したURLを指定しurlretrieveや、wget,curlでダウンロードをするコード
### Python

```python
import urllib.request
import sys
url = "https://drive.google.com/uc?export=download&id=<file_id>"
file_name = "file_name"
urllib.request.urlretrieve(url, file_name)
```
###Shell 
```shell
wget "https://drive.google.com/uc?export=download&id=<FILE_ID>" -O <FILE_NAME>
or
curl "https://drive.google.com/uc?export=download&id=<FILE_ID>" -O <FILE_NAME>
```

## 大きいファイルの場合
以下のようにファイルサイズが大きすぎる場合ウィルススキャンが行われないため、ダウンロードをする際に確認がはいってしまい、先ほどのコードを実行すると確認ページ自体のhtmlファイルがダウンロードされてしまう。
<img width="1437" alt="スクリーンショット 2020-03-02 22.24.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426156/9d9e7e9a-f664-0945-1240-736cb0e911af.png">

それを避けるためにconfirm用のcodeを取得する必要がある。以下のコードで取得できる。

```shell
curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=<FILE_ID>" > /dev/null
CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"  
curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=<FILE_ID>" -o <FILE_NAME>
```

## 最も簡単な方法
[gdown](https://github.com/wkentaro/gdown)(OSS)を用いる。
gdownでは認証は用いられていないので、URLを共有状態にしてからダウンロードする必要がある。codeを取得するスクリプトを書く必要がないので楽。

```
!gdown https://drive.google.com/uc?id=<file_id>
```

# Google Coloboratory上での実行
先ほどのコードをセルで実行するだけだが、以下のように行頭に`!`を付け加えるだけでは変数が保存されない。なので、セルの頭に%%shellを記述することでshell scriptのように実行できる。
<img width="707" alt="スクリーンショット 2020-03-02 22.58.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426156/56f40005-b386-f69d-00a3-ab8953238208.png">

先ほどのコードの頭に%%shellを追加する

<img width="956" alt="スクリーンショット 2020-03-02 23.02.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426156/4db81864-b263-c430-b97a-8b91cdc200c6.png">

## unzipなど
<img width="347" alt="スクリーンショット 2020-03-02 23.33.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426156/b286a957-9716-8157-a128-097d0403a0c8.png">


#最後に
google driveの容量に制限がある方はcolab上で完結できる点や、githubには大量のデータを置くことができないのでGoogleColaboratoryのノートブックファイルなど共有する際にあらかじめ記述して置くことで、cloneしてセルを実行するだけで済むという利点はあるかなぁと思いました。
# 参考&引用
[curlやwgetで公開済みGoogle Driveデータをダウンロードする](https://qiita.com/namakemono/items/c963e75e0af3f7eed732)
[PythonでWeb上のファイルをダウンロードする](https://qiita.com/yuukiclass/items/88e9ac6c5a3b5ab56cc4)
[gdown](https://github.com/wkentaro/gdown)
Unityに関する勉強記事②

#はじめに
今回はUnit 2Dでルーレットをつくってみましょう。

#準備
新規作成もしくはNew Projectから、プロジェクトを開きます。
そしてルーレットで使用する素材をプロジェクトウィンドウのアセット欄にドラック＆ドロップします。ここでは参考にさせていただいているSBクリエイティブさんの「はじめてでも安心！Unityの教科書2019年度版」のサポートページからダウンロードした素材を使用しています。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549070/c2130d9f-2f75-52b1-7bae-f505b2c3fa57.png)
すると、このような画面の状態になると思います。
次に素材の2つをゲーム画面にドラック＆ドロップして、位置を調整してみましょう。
この時大まかな位置をマウスで、細かい座標を右側のインスペクターウィンドウのPositionからxyz座標の数値を入力するのがオススメです。
今回はルーレットを座標(0,0,0)に、針を座標(0,3.2,0)に設定します。

加えてゲーム実行の際の色味を調整すると素材が見やすくなるため、ゲーム画面のカメラをクリック→インスペクターウィンドウのCameraからBackgroundを見やすい色に変更します。私は明るめの青緑を選択しました。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549070/ea418ba8-2338-7763-c573-23ebd2f4e5dc.png)

#スクリプトを組んでみよう
プロジェクトウィンドウから右クリックでCreate→C# Scriptを選択して適当な名前に変更します。今回はrouletteという名前にしてみました。
次にこのスクリプトの中身を編集するために、ダブルクリックしてエディターソフトが立ち上が……Visual Studioが入ってませんでした。
今回はダウンロードも面倒くさいので、Edit→Preferenceからエディターソフトをメモ帳に指定して編集していきます。

```C#:roulette.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class roulette: MonoBehaviour
{
    float rotSpeed = 0;  // 回転速度   

    void Start()
    {
        
    }

    void Update()
    {
        // マウスが押されたら回転速度を設定する
        if (Input.GetMouseButtonDown(0))
        {
            this.rotSpeed = 20;
        }

        // 回転速度分、ルーレットを回転させる
        transform.Rotate(0, 0, this.rotSpeed);

        // ルーレットを減速させる
        this.rotSpeed *= 0.98f;
    }
}

```

このコードの流れとしては最初回転をしていないrotspeedがマウスを押されたらZ軸回転をフレームごとに20度回転して1フレームごとに速度が0.98倍されて0に限りなく近づく…という感じです。

#アタッチ
作ったスクリプトをヒエラルキーウィンドウのrouletteにドラック＆ドロップします。
そしてゲームを実行してみると…
![ezgif.com-crop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549070/a7209ab9-3e39-6fa3-2d0e-24a8aef2d86f.gif)
このようにルーレットを制作することができました。
スクリプトをいじればもっと様々な条件の指定が出来ると思いますが
今回はここまで。

#終わりに
今回スクリプトという形でC#を初めて触れましたが、色々文字が変わっただけで今まで触れてきたCやpythonと似たようなコードだったので理解がすんなりと進んで良かったです。
Alexaで動画再生スキルをつくってみる

# はじめに
せっかく[Echo Show 5](https://www.amazon.co.jp/dp/B07KD87NCM?&tag=googhydr-22&ref=pd_sl_2zj4vz9nkm_e&adgrpid=74851279321&hvpone=&hvptwo=&hvadid=399955978446&hvpos=&hvnetw=g&hvrand=128015826542546185&hvqmt=e&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9053415&hvtargid=aud-758806828536:kwd-752951604934&hydadcr=16018_11412922&gclid=CjwKCAiA-vLyBRBWEiwAzOkGVLFRhIU0qWj4ST1jf1Z_1x2_rruZ7TJzHgGi4h8oz0KIxeUKtyPqHxoC--sQAvD_BwE)を買ったわけなので画面を生かすスキルを練習がてらつくってみました。導入はとても簡単でした。

# セットアップ
せっかく[前回](https://qiita.com/ufoo68/items/925043c5ab95b546a188)自分用のテンプレートをつくってみたわけなので、それを使います。

```bash
ask new --url https://asktemplatesstack-bucket83908e77-x9vhv4xdr8m4.s3-ap-northeast-1.amazonaws.com/templates.json
```

上記を実行したらテンプレートの選択画面に移るので、「Hello TS」を選びます。今回は多言語対応はしないので余計なファイルは鬱陶しいので消します（本当はどっちでもいいですが）。

# ビデオテスト再生を有効化する
カスタムスキルでビデオ再生をするには[スキルマニフェスト](https://developer.amazon.com/ja-JP/docs/alexa/smapi/skill-manifest.html)で**[CustomInterface](https://developer.amazon.com/ja-JP/docs/alexa/smapi/skill-manifest.html#customInterface-enumeration)**というインターフェースの列挙値を定義します。テンプレートをベースにこんな感じで書き換えました。

```json:video-skill-test/skill.json
{
  "manifest": {
    "publishingInformation": {
      "locales": {
        "ja-JP": {
          "name": "ビデオテスト",
          "summary": "ビデオテスト",
          "description": "ビデオテスト",
          "examplePhrases": [
            "アレクサ、ビデオテストを開いて",
            "再生",
            "ヘルプ"
          ],
          "keywords": []
        }
      },
      "isAvailableWorldwide": false,
      "testingInstructions": "Sample Testing Instructions.",
      "category": "KNOWLEDGE_AND_TRIVIA",
      "distributionCountries": []
    },
    "apis": {
      "custom": {
        "endpoint": {
          "sourceDir": "lambda/custom",
          "uri": "ask-custom-video-skill-test-default"
        },
        "interfaces": [
          {
            "type": "VIDEO_APP"
          }
        ]
      }
    },
    "manifestVersion": "1.0"
  }
}

```

下の方に`interfaces`の中に`VIDEO_APP`が呼び出されています。この宣言によってカスタムスキルでビデオ再生を有効化することができます。

# 動画を再生するAPIを呼び出す
コーディングのところですが、これが一番簡単でした。`addVideoAppLaunchDirective(url, title)`という関数を呼び出すだけです。この関数を用いた`PlayVideoIntentHandler`をこんな感じで実装すれば最低限の動画再生程度を行うことができます。

```typescript
const PlayVideoIntentHandler: Alexa.RequestHandler = {
  canHandle(handlerInput) {
    return (
      handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
      handlerInput.requestEnvelope.request.intent.name === 'PlayVideoIntent'
    )
  },
  handle(handlerInput) {
    const speakOutput = '動画を再生します。'
    return handlerInput.responseBuilder
      .speak(speakOutput)
      .addVideoAppLaunchDirective('https://example.mp4', 'title')
      .getResponse()
  },
}
```

ビデオの形式など詳しい情報は[こちら](https://developer.amazon.com/ja-JP/docs/alexa/custom-skills/videoapp-interface-reference.html)に記載されています。

# さいごに
全体的なコードは[ここ](https://github.com/ufoo68/video-skill-test)で公開しています。ただ、このビデオAPIの問題点として、画面がない端末でビデオを再生するAPIを実装すると**「ターゲットの端末では、指定されたディレクティブがサポートされていません。」**という音声を返します。本格的に開発するのであれば、このへんの対策が必要になりそうです。
Fortran で UTF-8

追記：こういうページがあることを教えてもらいました。(SirBogmanさんより）
https://cyber.dabamos.de/programming/modernfortran/unicode.html
ISO 10646 は Unicode ではなく UTF-16 に近い代替物のようです。もう少し勉強する必要があるようです。

## MFE §10.14 UTF-8 files
Modern Fortran Explained (MFE) 10.14 UTF-8 files

ifort 19.0 はファイルへの UFT-8 encoding に対応していたようです。絵文字が使えます。selected_char_kind の方では定数として定義されていないので (MFE §3.7.2) 出来ないものだと思っていました。

なお gfortran では selected_char_kind('ISO_10646') で 4 が出力されるので真面目に kind 定数が使えるようです。

ただコンソールの方はユニコード対応の powershell でもユニコード文字は出ないようです。よく分かりません。

```fortran
program Hello
   implicit none
   integer, parameter :: iso10646 = selected_char_kind('ISO_10646')
 !  character(kind=iso10646):: q
   print *, iso10646
   
   
   open(19, file='unko.txt', encoding='utf-8')
   
   write(19, *) 'うんころな　😀 😁 😂🤟🤟🏻'

   write(19, *) '　　　　　　　　　オエーー鳥'
   write(19, *) '   　　　　　　　　 　　 ,, -―-、　　　　　　　    '
   write(19, *) '　　　　　　　　　　　／　　　　 ヽ　　　          '
   write(19, *) '　　　　　　　／￣￣／　　／i⌒ヽ､|　オエーー！！！'
   write(19, *) '　　　　　　/　　（゜）/　　 ／　/　　 　　　　'
   write(19, *) '　　　　　/　　　　 ト､.,../　,ー-､　　　　　 '
   write(19, *) '　　　　=彳　　　　　 ＼＼‘ﾟ。､｀ ヽ。、ｏ　 　'
   write(19, *) '　　　　/ 　 　　　　　　　＼＼ﾟ。､。、ｏ　　　'
   write(19, *) '　　　/　　　　　　　　　/⌒ ヽ ヽU　　ｏ　　　'
   write(19, *) '　　 /　　　　　　　　　│　　　`ヽU　∴ｌ　　　'
   write(19, *) '　　│　　　　　　　　　│　　　　　U　：l　　　'
   write(19, *) '　　　　　　　　　　　　　　　　　 |：!　　　　'
   write(19, *) '　　　　　　　　　　　　　　　　　　Ｕ　　　　'
   
   write(6, *) 'うんころな　😀 😁 😂🤟🤟🏻'
end program Hello
```

### 出力
コンソール

```
          -1
 縺・ｓ縺薙ｍ縺ｪ縲・ ・ ・､溟洟溟沛ｻ
```

unko.txt
絶滅危惧種　オエー鳥

```
 うんころな　😀 😁 😂🤟🤟🏻
 　　　　　　　　　オエーー鳥
    　　　　　　　　 　　 ,, -―-、　　　　　　　    
 　　　　　　　　　　　／　　　　 ヽ　　　          
 　　　　　　　／￣￣／　　／i⌒ヽ､|　オエーー！！！
 　　　　　　/　　（゜）/　　 ／　/　　 　　　　
 　　　　　/　　　　 ト､.,../　,ー-､　　　　　 
 　　　　=彳　　　　　 ＼＼‘ﾟ。､｀ ヽ。、ｏ　 　
 　　　　/ 　 　　　　　　　＼＼ﾟ。､。、ｏ　　　
 　　　/　　　　　　　　　/⌒ ヽ ヽU　　ｏ　　　
 　　 /　　　　　　　　　│　　　`ヽU　∴ｌ　　　
 　　│　　　　　　　　　│　　　　　U　：l　　　
 　　　　　　　　　　　　　　　　　 |：!　　　　
　　　　　　　　　　　　　　　　　　Ｕ　　　　
```
活性化関数とは？？　〜機械学習の用語まとめ〜

##概要
活性化関数とは、ニューラルネットワーク内に置かれる、線形変換の後に適用する非線形関数のこと。入力層の総和に対して最終的な出力値を決定するために用いられることが多い。
以下の図における$ \varphi $が活性化関数に対応する。
<img width="508" alt="スクリーンショット 2020-03-02 21.59.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470838/fdbc3871-0e38-39f8-f0b8-0e131b68916a.png">
引用元:[活性化関数 Wikipedia](https://ja.wikipedia.org/wiki/活性化関数)

##活性化関数の役割
ニューラルネットワークの基本的な構造は、線形変換である。しかしながら、線形変換だけでは表すことができないものがある。そこで出力層に非線形的な活性化関数を置いておくことで、表現の幅が広がるのである。
#### なぜ非線形関数を用いるのか？？
線形関数では、どんなに層を深くしても同じことを１層で表現することが可能になってしまうからである。非線形関数を用いることで、多層にする利点を見いだすことができるというわけだ。

#活性化関数の種類
活性化関数にはいくつか代表的なものがある。

####シグモイド関数
ニューラルネットワークにおいてよく使われる関数の一つが、シグモイド関数である。シグモイド関数は以下の式で表される。

```math
h(x) = \frac{1}{1 + e^{-x}}
```
<img width="795" alt="スクリーンショット 2020-03-02 22.22.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470838/b3ff43b5-aca3-1342-217b-8a2036cfd22c.png">
シグモイド関数は全ての実入力に対して、０〜１の連続した値を出力する関数である。入力が小さい時は０に近く、出力が大きい時は１に近く。また0に対しては0.5を出力する。

####ステップ関数
ステップ関数を用いることで0と1の2値出力をすることができる。
$$
f(x) = 
\begin{cases}
1 & (x \geq 0)\\\
0 & (x &lt; 0)
\end{cases}
$$
<img width="588" alt="スクリーンショット 2020-03-02 22.38.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470838/11f82a65-5831-d183-f748-434ca0a95ca5.png">
シグモイド関数と同じく0~1のまで出力となっているが、0か1しか出力ができないので表現力はシグモイド関数よりも乏しいと言えるかもしれない。

####ReLU関数
最近のニューラルネットワークにおいて頻繁に使われているのが、ReLU関数である。
ReLU関数は、ランプ関数ともいい、入力が0より大きければそのままの値を、0より小さければ0を出力する活性化関数である。
$$
f(x) = 
\begin{cases}
x & (x \geq 0)\\\
0 & (x &lt; 0)
\end{cases}
$$
<img width="710" alt="スクリーンショット 2020-03-02 22.52.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470838/3e93bc13-57ad-e1d3-1294-11a58f7fdfba.png">

####恒等関数
恒等関数とは入力された値をそのまま出力する関数である。
回帰問題においては出力層においては恒等関数を用いる。

####ソフトマックス関数
ソフトマックス関数とは分類問題の出力層に置かれる関数である。
$$
y_k = \frac{exp(a_k)}{\sum_{i = 1}^{n} exp(a_i)}
$$
ソフトマックス関数はn個の入力$a_1$ ~ $a_n $から、出力$y_1$ ~ $y_n $を得る。
$y_1$ ~ $y_n $はそれぞれ0~1であり、総和が１であることからソフトマックス関数の出力は確率と捉えることができる。
分類問題では、ソフトマックスの関数の出力の最大値のクラスを答えとするのが一般的である。

##まとめ
活性化関数はニューラルネットワークにおける非線形関数であり、活性化関数を用いることで表現の幅が広がる。
活性化関数は様々な種類があり、それぞれ個別の特徴があり、場面ごとに使い分けられる。