OmniAICreator/Qiita-1.07M huggingface dataset:
初心者によるプログラミング学習ログ 293日目

#100日チャレンジの293日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
293日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>293日目　2h<br>・xdデザインカンプからのサイト模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1251232350333071360?ref_src=twsrc%5Etfw">April 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
使わなくなったiPhoneでDiscord Botを動かしてみる

##動機
24時間稼働させたいけどレンタルサーバーは面倒だしiPhoneで動いたらいいな～と思ったから

##用意したもの
 - iPhone (ios13.4.1の6s)
 - Pythonista 3 (バージョンは3.3、1220円で買える)
https://apps.apple.com/jp/app/pythonista-3/id1085978097
 - ファイル(デフォルトでインストールされてるやつ)
https://apps.apple.com/jp/app/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB/id1232058109

##StaSh(Pythonista Shell)を入れる
適当にThis iPhone の下に好きな名前のScriptファイルを作って下のコードを書き込む
```import requests as r; exec(r.get('http://bit.ly/get-stash').text)```
インストールが終わったらPythonistaを再起動してlaunch_stash.pyを実行する(作ったファイルと同じ場所にある)

##discord.pyを入れる
launch_stash.pyを実行するとターミナルみたいな画面になるのでそこで次のコードを打ち込む
```pip install discord.py[voice]```
音声を使わないなら
```pip install discord.py```
無事インストールできているか確認のために適当なScriptファイルで
```import discord```
と書いて実行してみる

するとModuleNotFoundErrorでctypes.macholibが無いよと言われる

##Cpythonを入れる
次のURLをsafariで開くとダウンロードが始まるので待つ
https://github.com/python/cpython/archive/v3.6.1.zip
ダウンロードが終わったらファイル(アプリ)を開く
cpythonというファイルをクリックすると解凍してくれるので少し待って、解凍したフォルダを長押しして移動を押すと移動する場所を選択することになるのでこのiPhone内>Pythonista3を押してコピーする(時間かかるかも)

Pythonistaを開き左側のタブを開いたらEXTERNAL FILESのopen...を押すと選択肢が出てくるのでFolder...を選択さっきコピーしたこのiPhone内のPythonista 3を押すとcpythonが出てくるので選択して完了を押す

するとcpythonフォルダーができているのでcpythonフォルダーのlibを開く、その中にctypesというフォルダーがあるのでEditを押してsite-package-3にファイルを移動させる

うまくいっていればimport discordでエラーが出ない

##動かしてみる
```python

import sys
import time
import discord

TOKEN = '自分のBOTのアクセストークン'
client = discord.Client()

# 接続時の処理
@client.event
async def on_connect():
    print('login')
    time.sleep(5)
    await client.close()
    print('logout')
    sys.exit()

client.run(TOKEN)
```

#動いたのでヨシ！
1回目は正常に動くが2回目以降エラーがでて機能しない
非同期処理のことが全く分からないので解決できない
エラー文はEvent loop is closedという単純なものでいろいろ調べて確かめてみたが結局解決できなかった
非同期処理の勉強して出直してきます......

##エラーが出ないコード
実行し終わったらpythonistaを落とすやつです。

```python

import os
import time
import discord

TOKEN = '自分のBOTのアクセストークン'
client = discord.Client()

#接続時の処理
@client.event
async def on_connect():
    print('login')
    time.sleep(5)
    await client.close()
    print('logout')
    os.abort()

client.run(TOKEN)
```

##以下参考サイト
Pythonista 3 にStaSh をインストールする。
https://qiita.com/maboy/items/cef5dee13d5b2e9ac843
Missing ctypes.macholib breaks ctypes.util
https://github.com/omz/Pythonista-Issues/issues/311
ffmpeg4.2.2をWSL(Ubuntu)でWindows用にビルドする

忘れないようにメモします。

私はとりあえず動けばOKという感じでビルドするので警告とか無視していきます。
**この記事の手順でビルドして問題が起きても私は責任を負いません。自己責任でお願いします。**

ffmpegをビルドしようということでWSLでビルドすることにしました。
専用のツールが用意されているのでとっても楽です。

# WSLの設定
WSLの起動方法については検索してください。検索したほうが詳しい情報が出ると思います。
WSLはUbuntuを使います。たぶんCentOSでも大丈夫です。

# ツールのダウンロード
ディレクトリはhomeディレクトリ以下ならどこでもいいです。

```bash
git clone https://github.com/rdp/ffmpeg-windows-build-helpers.git
cd ffmpeg-windows-build-helpers
```

# 必要パッケージのダウンロード
とりあえず実行します。

```bash
./cross_compile_ffmpeg.sh
```
するとログの中にsudo apt install 〇〇みたいなコマンドが出るのでそれをコピーして実行します。
次にその他に必要なものをインストールします。

```bash
sudo apt install python3-pip
pip3 install ninja meson
```

# nasmのインストール
```bash
#好きなディレクトリに移動
cd ~
wget https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/nasm-2.13.03.tar.bz2
tar xjvf nasm-2.13.03.tar.bz2
cd nasm-2.13.03
./autogen.sh
./configure --prefix=/usr/local
make
sudo make install
```
バージョンは必要に応じて変えたほうがいいかもしれないです。
もっと新しいバージョンを求められたときは変えてください。

# ffmpegのビルド

```bash
./cross_compile_ffmpeg.sh --build-ffmpeg-shared=y --build-intel-qsv=y --build-amd-amf=y --ffmpeg-git-checkout-version=n4.2.2 --enable-gpl=n
```
私はこんな感じで実行しました。
数時間かかります。
ターゲットには32bit、64bit一緒にビルド、もしくは片方だけを選びましょう。

dllがほしかったので--build-ffmpeg-shared=yでdllを生成するようにしました。不要であれば--build-ffmpeg-static=yです。

--build-intel-qsv=y --build-amd-amf=y
ここでIntel QSV、AMD amfをオプションで有効にします。
NVENC、NVDECは自動で有効になるようです。

--enable-gpl=nにするとlibx264が無効になります。--enable-gpl=yだとlibx264がインストールされます。
どうやら標準でOpenH264が使われるようです。

--ffmpeg-git-checkout-version=n4.2.2でffmpegのバージョンを指定します。指定しなかったら最新のファイルを落としてくるようです。
こちらのツールは最新版用に作られているようなので、最新版を指定しないとエラーが出る可能性があります。

その他詳しい設定についてはshファイルの中を覗くのがいいかもしれません。
詳細に変更したいなら直接書き換えたほうがいいと思います。

# ビルド完了ログ
```
Compressing  COPYING.GPLv3.txt
Compressing  ffmpeg.exe
Compressing  ffplay.exe
Compressing  ffprobe.exe
Compressing  avcodec-58.dll
Compressing  avdevice-58.dll
Compressing  avfilter-7.dll
Compressing  avformat-58.dll
Compressing  avresample-4.dll
Compressing  avutil-56.dll
Compressing  swresample-3.dll
Compressing  swscale-5.dll

Everything is Ok
```

# 完成したファイルの場所
私の場合だとここにありました。
ffmpeg-windows-build-helpers/sandbox/win64/ffmpeg_git_lgpl_n4.2.2_shared/bin/
最後のログに出てるのでそこを読めばわかります。

# エラー解決
# とりあえずもう一回ビルドする
これで通ることが多いです。

# Unknown option "--enable-libdav1d".
ffmpeg4.2からlibdav1dが利用可能になりました。cross_compile_ffmpeg.shの中から--enable-libdav1dを消すかビルドするffmpegのバージョンを上げましょう。

# 最後に
ffmpegを使うときはライセンスに気をつけましょう。ライセンス料とか色々考えなければなりません。
pyenvで制作した仮想環境でpip --userがエラーを返す時の対処法

# 問題

pyenvを使ってpython3.8.2の仮想環境を作成し、pipでパッケージをインストールしようとした際、
```
ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.
```
のエラーが出たのでその対象法。
(Mac)

# 対象法

仮想環境のあるディレクトリに行き

```console
/usr/local/python_env/py3env
```

pip.confというファイルを作成。

```console
touch pip.conf
```

中身に

```
[global]
user = false
```
と記載する。
【LINE LIFF】謎のパラメーター"liff.state="について

こんにちは。

LINEが提供するWebアプリ用フレームワークLIFFで、
謎のクエリパラメータ"liff.state="が付与されることがあったので、
このパラメータについて調べてみました。

[結論](#つまり)

# このパラメータに対してわかっていること
1. https://liff.line.me/{liffId} ※のURLを利用する場合に付与されることがある
2. クエリパラメータがエンコードされてliff.stateに格納される場合がある
3. line://app/{liffId} のURLスキームでは付与されない


※LINE URLスキームの「line://」は非推奨になったため、
今後はhttps://liff.line.me/{liffId} のURLスキームを利用しなければならないようです。
https://developers.line.biz/ja/news/2020/03/25/line-url-scheme-deprecation/


# 順番に確認 1

まず1.の内容ですが、簡単なLIFFアプリを作成し
https://liff.line.me/{liffId} のURLからアクセスすれば再現します。

テストアプリ
https://liff.line.me/1654102793-nkrRxP6x
`https://example.com/?liff.state=`

# 順番に確認 2
次に2.の確認のため、クエリパラメータを付与してみます。
https://liff.line.me/{liffId} のURLではこれまでと異なり、
https://liff.line.me/{liffId} のURLスキーム自体に**パス**を含めて指定する必要があるようです。
>
LIFFアプリに追加情報を渡すには
LIFFアプリに追加情報を渡すには、URLスキームにパスとクエリパラメータを追加します。たとえば、https://liff.line.me/{liffId}/path_A/path_B/?key1=value1&key2=value2 と指定すると、LIFFアプリに/path_A/path_B/?key1=value1&key2=value2が渡されます。

https://developers.line.biz/ja/docs/liff/opening-liff-app/#liff%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AB%E8%BF%BD%E5%8A%A0%E6%83%85%E5%A0%B1%E3%82%92%E6%B8%A1%E3%81%99%E3%81%AB%E3%81%AF

今回は、ルート直下でのアプリとなり、サブディレクトリがないので、
パスは指定しません。
すると以下のようになります。

https://liff.line.me/1654102793-nkrRxP6x?hoge=fuga
`https://example.com/?liff.state=%3Fhoge%3Dfuga`


**ここで、LIFFアプリでliff.init()の処理を行っていなかったことに気が付き、
実装したところ、以下のようにliff.stateに格納されたクエリパラメータがデコードされ。
liff.stateが消滅しました。**

https://liff.line.me/1654102793-OpgpwjVw?hoge=fuga
`https://myucy-liff.herokuapp.com/?hoge=fuga`

## 追加検証

今度は、パスを付与してみます。(liff.init()は行わない)
https://liff.line.me/1654102793-nkrRxP6x/path1
`https://example.com/?liff.state=%2Fpath1`

パスを付与しliff.init()を実行
https://liff.line.me/1654102793-OpgpwjVw/path1
`https://myucy-liff.herokuapp.com/path1`

## 追加検証2

パスとクエリパラメータを付与してみます。(liff.init()は行わない)
https://liff.line.me/1654102793-nkrRxP6x/path1?hoge=fuga
`https://example.com/?liff.state=%2Fpath1%3Fhoge%3Dfuga
`

パスを付与しliff.init()を実行
https://liff.line.me/1654102793-OpgpwjVw/path1?hoge=fuga
`https://myucy-liff.herokuapp.com/path1?hoge=fuga`


# つまり?
**上記検証結果より、liff.stateはhttps://liff.line.me/{liffId} のURLで、
パスやクエリパラメータを受け渡す際に、エンコードしたパラメータを一時的に保管しておくパラメータであり、
liff.init()を行うことでその中身がデコードされる** という結論になりました。

ただ、liff.stateはパスやクエリパラメータを指定してliff.init()を行うことで消滅しますが、
逆に何もパスやクエリパラメータを指定しない場合には、空のliff.stateが残ってしまうようです。
(PCのブラウザからのアクセス時のみ再現、LINEアプリ内のLIFFブラウザでは再現しません。)
https://liff.line.me/1654102793-OpgpwjVw
`https://myucy-liff.herokuapp.com/?liff.state=`

https://liff.line.me/{liffId} のURLで、付与したパスやクエリパラメータが
エンコードされてliff.stateに格納されるという動作や、
liff.state自体の説明、liff.init()を行うとデコードが行われるという動作について
公式のリファレンスには記載がなく、困っている方も居そうな気がしたので、何かの役に立てば幸いです。
テーブルに外部キーを設定する方法

genre has_many tasks
task belongs_to genre
の関係性でtasks_tableにgenre_idの外部キーを設定する方法をメモしておきます。

##1 方法
まず外部キーをもったテーブルを作成するのと既存のテーブルに外部キーのカラムを追加するのとで方法が異なります。

##2 テーブルを作成する際に外部キーを設定する場合
コマンドで

```:ターミナル
$ rails g model Task genre:references
```

とすることで、genre_idを外部キーに持つTasksテーブルが作成されます。


##3 既存のテーブルに外部キーカラムを追加する場合

```:ターミナル
$ rails g migration AddGenreRefToTasks genre:references
```

とすることで既存のtasksテーブルに新しくgenre_idカラムが作成されます。

##4 rails db:migrate
テーブルを作成、カラムを追加した場合は忘れずに

```
$ rails db:migrate
```
しましょう。

schema.rbのtasksテーブルにカラムが追加されていれば完了です！！
icrawlerがうまく動かなかった人へ

## 環境
anaconda下で、pythonのバージョンは3.6の仮想環境を作って、そこに対して、`conda install`経由で`jupyter`と`icrawler`を入れた。

# はじめに
自分の環境では`icrawler`の定番の設定が以下のようになりうまくいかなかった。
参考URL(https://icrawler.readthedocs.io/en/latest/)

```icrawler.py
from icrawler.builtin import GoogleImageCrawler

google_crawler = GoogleImageCrawler(storage={'root_dir': 'your_image_dir'})
google_crawler.crawl(keyword='cat', max_num=100)
```

```:結果
2020-04-17 16:27:56,617 - INFO - icrawler.crawler - start crawling...
2020-04-17 16:27:56,618 - INFO - icrawler.crawler - starting 1 feeder threads...
2020-04-17 16:27:56,618 - INFO - feeder - thread feeder-001 exit
2020-04-17 16:27:56,619 - INFO - icrawler.crawler - starting 1 parser threads...
2020-04-17 16:27:56,620 - INFO - icrawler.crawler - starting 1 downloader threads...
2020-04-17 16:27:56,975 - INFO - parser - parsing result page https://www.google.com/search?q=cat&ijn=0&start=0&tbs=&tbm=isch
2020-04-17 16:27:59,010 - INFO - parser - no more page urls for thread parser-001 to parse
2020-04-17 16:27:59,011 - INFO - parser - thread parser-001 exit
2020-04-17 16:28:01,622 - INFO - downloader - no more download task for thread downloader-001
2020-04-17 16:28:01,623 - INFO - downloader - thread downloader-001 exit
2020-04-17 16:28:01,627 - INFO - icrawler.crawler - Crawling task done!
```

このとき、画像をダウンロードをすることはできていなかった。

# 動いた設定
参考URL(https://icrawler.readthedocs.io/en/latest/builtin.html)

```icrawler.py
from icrawler.builtin import BaiduImageCrawler, BingImageCrawler, GoogleImageCrawler

google_crawler = GoogleImageCrawler(
    feeder_threads=1,
    parser_threads=1,
    downloader_threads=4,
    storage={'root_dir': 'your_image_dir'})
filters = dict(
    size='large',
    color='orange',
    license='commercial,modify',
    date=((2017, 1, 1), (2017, 11, 30)))
google_crawler.crawl(keyword='cat', filters=filters, offset=0, max_num=1000,
                     min_size=(200,200), max_size=None, file_idx_offset=0)

bing_crawler = BingImageCrawler(downloader_threads=4,
                                storage={'root_dir': 'your_image_dir'})
bing_crawler.crawl(keyword='cat', filters=None, offset=0, max_num=1000)

baidu_crawler = BaiduImageCrawler(storage={'root_dir': 'your_image_dir'})
baidu_crawler.crawl(keyword='cat', offset=0, max_num=1000,
                    min_size=(200,200), max_size=None)
```

これだとうまくいった。
きっと１度動かすことができれば、調整できるだろうから、誰かが自分のようにはまった状態から、とりあえずでも抜け出せることを願っている。
個人アプリ（README.mdに画像、動画を貼り付ける）

# README.mdに画像貼り付け
参考記事
https://qiita.com/ROY_M/items/2c4feb5de05535441bc8
上のサイトを参考にGyazoのキャプチャ画面をissueにドラッグ＆ドロップ
そのURLをREADME.mdに貼り付けて
commit,pushで反映

# README.mdに動画貼り付け
参考記事
https://machida.github.io/articles/tags/github/
[![Image from Gyazo](https://i.gyazo.com/704a65ce011af3941f89219416d46148.png)](https://gyazo.com/704a65ce011af3941f89219416d46148)
画像リンクをコピーでGIT形式にして、GoogleChromeで一度開きMACに保存
保存したデータをissueにドラッグ＆ドロップ
そのURLをREADME.mdに貼り付けて
commit,pushで反映
[C#] カスタムAttributeでJSONバリデーションを行う

# はじめに
C#のカスタムAttributeでJSONバリデーションを行う方法を紹介します。

# Attributeとは
Attribute（属性）とは、クラスやメンバーに追加情報を与えることができます。属性にはパラメータを指定することができ、複数の属性を指定することができます。

```C#
[属性名(属性パラメータ)]
メンバーの定義
```

# 環境設定
今回実行した環境は下記の通りです。

```Markdown:実行環境
Microsoft .NET Framework 3.5
```

# 使いかた
下記のソースコードから `Validator` フォルダーを各自のプロジェクトにコピーします。
[ソースファイルはこちら](https://github.com/yunbow/CSharp-WebAPI)

JSONオブジェクトを引数にして `ValidatorMapper` クラスのインスタンスを生成して実行します。

```C#
ValidatorMapper validator = new ValidatorMapper(this.reqObj);
validator.Execute();
```

# バリデーションAttribute
## Required
`Required` は、必須チェックを行う属性です。リクエストパラメータに値が指定されていない場合にエラーを返します。

```C#:実装例
[Required]
[JsonProperty("userName")]
public string UserName { get; set; }
```

`userName` がリクエストパラメータに指定されていない場合は、下記のエラーレスポンスが返されます。

```JSON:エラーレスポンス
{
    "code": 1004,
    "message": "\"userName\" is a required field."
}
```

## StringLength
`StringLength` は、文字列長チェックを行う属性です。文字列型のリクエストパラメータの長さが超えた場合にエラーを返します。

```C#:実装例
[StringLength(max = 30)]
[JsonProperty("userName")]
public string UserName { get; set; }
```

`userName` の値が30文字より長い場合は、下記のエラーレスポンスが返されます。

```JSON:エラーレスポンス
{
    "code": 1004,
    "message": "\"userName\"(1234567890123456789012345678901) exceeds the number of characters 30 digits."
}
```

## StringDateFormat
`StringDateFormat` は、日付フォーマットチェックを行う属性です。文字列型のリクエストパラメータの日付フォーマットが正しくない場合にエラーを返します。

```C#:実装例
[StringDateFormat("yyyyMMdd")]
[JsonProperty("createDate")]
public string CreateDate { get; set; }
```

`createDate` の値がyyyyMMdd形式でない場合は、下記のエラーレスポンスが返されます。

```JSON:エラーレスポンス
{
    "code": 1004,
    "message": "\"createDate\"(20200401abc) should be entered in the form yyyyMMdd."
}
```

## NumberRange
`NumberRange` は、数値範囲チェックを行う属性です。数値型のリクエストパラメータの値が範囲外の場合にエラーを返します。

```C#:実装例
[NumberRange(from = 0, to = 120)]
[JsonProperty("age")]
public int Age { get; set; }
```

`age` の値が0～120の範囲外の場合は、下記のエラーレスポンスが返されます。

```JSON:エラーレスポンス
{
    "code": 1004,
    "message": "\"age\"(130) is from 0 to 120."
}
```

## ClassValue
`ClassValue` は、区分値チェックを行う属性です。リクエストパラメータに値が取りうる区分値以外の場合にエラーを返します。

```C#:実装例
[ClassValue(new int[] { 0, 1 })]
[JsonProperty("gender")]
public int Gender { get; set; }
```

`gender` の値が0,1以外の場合は、下記のエラーレスポンスが返されます。

```JSON:エラーレスポンス
{
    "code": 1004,
    "message": "\"gender\"(2) is an unavailable value."
}
```

以上です。
Pythonのselfの理解を試みる

#おことわり
自分自身、Python始めたてほやほやでわからないことだらけです。
（本記事も間違ってたらごめんなさい）
ほぼ自分の備忘録的な記事になります。

#はじめに
Pythonでクラスについて勉強しているとselfというものが出てくる。
けれども、おまじないのようでいまいちわからないので調べたことをまとめます。

##今回の全体のコード

```ruby:main.py
class Cat():
    def __init__(self,name):
        self.name = name

    def naku(self):
        print("にゃー")

tama = Cat("タマ")
tama.naku()

Cat.naku(tama)
```

#本題に入る前に
Pythonでは

```ruby:main.py
レシーバー.メソッド(引数…)
```

を、

```ruby:main.py
レシーバーのクラス.メソッド(レシーバー,引数…)
```

として、解釈します。
なぜかは知りません。（本当にごめんなさい）
でも、どちらで書いても同じ動作をしますし、selfを理解する上では、前者を後者として解釈する、と考えたほうが理解が楽なので、そういう流れで説明します。

#本題
ひとまず、全体のコードを順を追ってみていきます。
まず、Catクラスがあります。

```ruby:main.py
class Cat():
    def __init__(self,name):
        self.name = name

    def naku(self):
        print("にゃー")
```

インスタンス変数にnameがあって、
naku関数で「にゃー」って鳴きます。

クラスは概念みたいなものなので、「タマ」という名前で実際に召喚（インスタンス化）します。

```ruby:main.py
tama = Cat("タマ")
```

はい、これで猫のタマちゃんが召喚されました。
次は鳴いてもらいます。

```ruby:main.py
#レシーバー.メソッド(引数…)
tama.naku() #=>にゃー
```

はい、鳴きました。
これは、もう一つの書き方ができましたよね。

```ruby:main.py
#レシーバーのクラス.メソッド(レシーバー,引数…)
Cat.naku(tama) #=>にゃー
```

はい、ここで見てほしいのが引数丸括弧のレシーバーの部分に「tama」が来ていることです。
そこで、もう一度クラスで定義されているnaku関数と比べてみると、

```ruby:
#neko関数定義
def naku(self):

#関数呼び出し
Cat.naku(tama)
```

引数が一致しました。これがselfの正体です。

つまり、ここでは「tama = self」ということです。
よく、「selfはインスタンス自体のこと」という説明がされてますが、ただ単純にpythonの文法上、「レシーバーのクラス.メソッド(レシーバー,引数…)」という関数の呼び出され方をするので、第一引数（レシーバー）にインスタンス自体を入れておかないと引数の数があわないからだめだよー、ということみたいです。

init関数も同じことが言えます。
ここでタマちゃん召喚時に呼び出されるinit関数の動作を考えると、

```ruby:
#レシーバーのクラス.メソッド(レシーバー,引数…)
Cat.__init__(tama,"タマ")
```

というコードが内部的に行われていると理解できます。

いやいや、Cat()の引数の「タマ」がなんでinit関数の引数になっちまってんだ！？
というのは確かに浮かぶ疑問なんですが、よくよく考えてみると、init関数は自分で定義する関数と違ってインスタンス化の時必ず呼び出される特殊なものなので、Cat()の引数にとったものが、自動的にinit関数の引数に入っているんだろうなーと僕は考えることにしてます。（知っている方がいたら教えてください。）
それにクラスは関数ではないので引数いらないですしね。

#わかったこと
- selfの正体はただの引数
- 内部的には「レシーバーのクラス.メソッド(レシーバー,引数)」で呼び出される
- 気にしなくてもなんとかなる
- 僕の書く文章は長い！！
文字列の類似度分析をそれっぽく作ってみた話

## Summary
- 文字列の類似度分析をそれっぽく作ってみた。
- 便利なライブラリに溢れた日々のなかで、ふと自力で類似度分析してみたくなった。
- 自力で作る目的のもと、MSX-BASIC で作ってみた。

## Motivation
普段は [npm](https://www.npmjs.com/) から便利なライブラリを引っ張ってきて、TypeScript でライブラリとライブラリをつなぎ合わせるようなことをしている。[この前作ったアプリ](https://github.com/blue-hood/kohsei-san) では、[Material-UI](https://material-ui.com/) と [textlint](https://github.com/textlint/textlint) をつなぎ合わせる作業のように思えた。C 言語やアセンブラで 1 からプログラミングをする能力が、薄れてきているように感じた。

……よし、たまには自力でアルゴリズム組んでみるか！題材は以下の通り：

- 文字列の類似度をそれっぽく分析する。
- 使用言語は [MSX-BASIC](https://ja.wikipedia.org/wiki/MSX-BASIC)、理由はライブラリの概念が存在しないから。

![DSC_0200.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/d2e947d2-5050-269e-9e33-9cdcb4766890.jpeg)

# プログラム
類似度分析する 2 つの文字列を入力して、類似度を出力するメインプログラム。
![DSC_0190.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/f9506a19-49ef-42d3-7a46-63095b8580d7.jpeg)

入力文字列を [3-gram](https://qiita.com/kazmaw/items/4df328cba6429ec210fb) に分解するサブルーチン。
![DSC_0191.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/7a864893-9e37-f303-7418-360478e428ae.jpeg)

入力文字列を[部分列](https://wiis.info/math/real-number/convergent-sequence/subsequence/)に分解するサブルーチン。
![DSC_0195.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/017173a5-2cb1-66ad-56c7-a0e97baab91c.jpeg)

一致した部分列をカウントしていくサブルーチン。
![DSC_0193.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/311f5747-91a2-e75b-a25e-d61916cd6569.jpeg)

## 実際に分析してみる
"AAA" と "AAA" では類似度 100%
"AAA" と "AAB" では類似度 53%
"AAA" と "ABB" では類似度 21%
"AAA" と "BBB" では類似度 0%

……それっぽい！実行時間は 3 秒ほどと実用範囲内。

![DSC_0188.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/d9461693-3a6d-1cf8-47e0-379adeada420.jpeg)

最近耳にしなくなった "pen apple applepen" と "pen pineapple pineapplepen" で分析した結果……

![DSC_0198.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94642/311adbdf-1da4-f319-3704-9f78c876ea82.jpeg)

### 14%!!
もう少し高い類似度が出るべきだと思った。実行時間はおおよそ 13 分くらいでまあまあ現実的だったと思う。アルゴリズムを考え直す前にもう力尽きちゃったよ……

## 備考
部分列を使わなくても n-gram だけで類似度分析できるという、単純なことに気づいたのはこの記事を書き始めたときであった。

MicroSoft にも BASIC をビジネスにしていた時代があったんだなあ……しみじみ。
[コロナ対策に１６０億円資金提供　「前例なき国際協力必要」―ゲイツ財団](https://www.jiji.com/jc/article?k=2020041600277&g=int)

(追記)
面接官「0からプログラムを書くことはできますか？　というネタを知ったのは、この記事を投稿した直後であった。

[Twitter 検索結果](https://twitter.com/search?q=%E9%9D%A2%E6%8E%A5%E5%AE%98%E3%80%8C0%E3%81%8B%E3%82%89%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%93%E3%81%A8%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F&src=typd&f=live&vertical=default)
[面接官「0からプログラムを書くことはできますか？](https://qiita.com/fujitanozomu/items/f1f877c315c9e0671ef8)
ハングアウトの全チャット履歴の保存方法

ハングアウトのバックアップを取っておきたいと思ったが、意外と苦戦したのでメモ

# やり方
①スクリーンショットを取得したい会話を開く
②ポップアップ表示にしてハングアウトだけのウィンドウにする
③chromeの開発ツールのコンソールで下記を実行する

```
$("div.hh div.Ff").setAttribute("style", "display:none")
$("div.fcpPib div.Ff").setAttribute("style", "display:none")
```

④スクリーンショットを取得したい箇所まで遡る
⑤FireShotの右クリックでウェブページ全体のスクリーンショットを取得する
⑥FireShotの画面から保存する

# 苦労したところ

## 問題点
そのままFireShotでスクリーンショット取得すると、
自動でスクロール中にハングアウトのヘッダ部分が真っ白くなってしまい一部が見えなくなってしまう

## 解決方法
ハングアウトのヘッダ部分を一時的に隠すことにした
個人アプリ（herokuからgithubへ）

# HerokuのアプリをGitHubにコピーする

GitHubで新しいリポジトリを作成
ターミナルでコピーしたいディレクトリに移動
`git remote add origin https://github.com/tsuboyama09/Block.git`
`git push -u origin master`
で作成完了
実際のターミナル
https://gyazo.com/9a0b011b784fedc3b84e46fc002083ad
iOS なんかnavigationBarの影が表示されない。

アプリを作り始めてnavigationControllerとtabbarを追加したのですが。
![スクリーンショット 2020-04-18 0.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/5557133a-2bd6-b593-63c1-91de5d944a8e.png)
上の画像はstoryboradなんですがstoryborad上では影が表示されているのに実機では表示されないという事件が起きました。
影って元々入ってなかったっけ？と思ったのですがまあ表示されないものはしょうがないということで色々やってみました。navigationbarのshadowColorやshadowWidthを変えてみたりborderに色をつけてみたり。
がしかし！！全く表示されない。なんでだーと思って頭を悩ませてココアを飲んだら閃きめきました。

```swift
self.tabBarController?.tabBar.layer.shadowOpacity = 0.6
```
はいこれで解決defaultでopacityが0になってるっぽいです。完全にdefault値が1.0になってると思い込んでました。分かってみれば単純な話だけどdefaultは1.0にしといてくれよ...と思う今日この頃でした。  

<img width="408" alt="スクリーンショット 2020-04-18 0.40.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/995b3c45-b625-82cf-fe7b-bb15213d3d21.png">
いい感じに影が出てる。
Android Studioで更新がエミュレーターに反映されないときの対処法

Android StudioからアプリをRunしたときに、編集した内容がエミュレータや実機に反映されないときの対処法です。下に書いてあるものほど面倒なので、上から順番に試すのがよいでしょう。

#まず確認すべきこと1
MainActivity.java(または.kt)の onCreateメソッドの中のsetContentView に正しいレイアウトが渡されているかを確認します。

#まず確認すべきこと2
本当に変更が反映されていないのかを確認します。例えばonCreateの中にSystem.out.println("test")などを記述します。標準出力は
View -> Tool Window -> Logcat で見ることができます

#(現在のバージョンでは削除)Instatnt Runをオフにする
File -> Setting -> Build,Execution,Deploymentにある、Enable Instant Run...のチェックを外す
これが原因のことが多いようですがAndroid Studio3.6.2ではその項目はありません。Instant Runの機能は削除されたようです。

#Clean Project, Rebuild　Project
Buildタブの中にあるClean ProjectとRebuild　Projectを実行
これで直ったことはありませんが、大した手間ではないのでやっておいていいでしょう。

#Android Studioを再起動
再起動は定石。システム自体も念のため再起動する。

#Android Stdio を再インストール
必ずプロジェクトのデータを別の場所に移しておきましょう。プロジェクトのファイルは多くの場合
C:\Users\(ユーザー名)\AndroidStudioProjects
にありますからフォルダを丸ごと別のところに退避させておきましょう
再インストール後、プロジェクトファイルをもとの位置に戻します。

#それでもだめだったら(新規プロジェクト)
プロジェクトファイルを退避させた後、Android Studio を再インストール、新規プロジェクトで作業中のプロジェクトと同じ名前で新しいプロジェクトを作ります。その後MainActivityやresファイルをもとのフォルダで置き換えます。その他に必要なファイルがあればそれも置き換えます。
ここまでやってだめだったらAndroid Studio 以外の原因を疑うべきです。
CircleCIでGoのテストを並列実行する

## TL;DR

- CircleCIで複数の並列マシンを起動してGoのテストを並列実行します。

## 基本的なアイデア

- CircleCI CLIでテストを並列数に応じて分割
- 環境変数を使用して並列マシンごとに接続先DBを分ける

## CircleCI CLIで並列数に応じてテストを分割

`circleci tests split` コマンドを使ってテストをpackageごとに分割します。
ただ、splitコマンドは分割するだけでテスト自体は実行されません。
なので、結果はファイルに書き出して `go test` に渡す必要があります。
具体的には下記のようにします。

```bash
go list ./... | grep -v vendor | circleci tests splits > pkgs
export TESTPKGS=$(cat pkgs | tr '\n' ' ')
go test ${TESTPKGS} 2>&1
```

## 環境変数を使用して並列マシンごとに接続先DBを分ける

CircleCIには並列処理を制御するための環境変数が用意されています。
今回は並列マシンごとに接続先DBを変えるために `CIRCLE_NODE_INDEX` を使います。
この環境変数には現在実行されている特定のコンテナのインデックスが入っています。

なので、DBの名前を `database-${CIRCLE_NODE_INDEX}` みたいに並列数だけ作成しておいて、
各並列ごとにそれぞれのDBに接続します。

## 参考

- [テストの並列実行](https://circleci.com/docs/ja/2.0/parallelism-faster-jobs/)
- [CircleCIでGoのテストを並列に実行する](https://blog.zoncoen.net/2018/08/06/run-tests-in-parallel-on-circle-ci/)
VBAスクレイピング getElementByIdのエラーチェック

getElementByIdは、引数に指定したIDの要素がページ内に存在しない場合、
「オブジェクトが必要です。」というエラーがでてしまいます。
getElementByIdでは、上記のような場合、Nullを返却します。
ですので、エラーチェック方法としては、IsNullをつかい、

```vb

If Not IsNull(objIE.document.getElementById("なんらかのID")) Then
    処理
    ...
End If

```

というようにします。
マインクラフトコマンド紹介　#3

#始めに
マインクラフターのムー＃です！今日紹介するコマンドはコマンドブロック３つで動くとても簡単なものなのでぜひご覧ください！

##今日のコマンド
今日のコマンドは「**移動用トライデント**」です。実際に使うと…
![2020-04-17_23.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615707/7fbea80b-3e2e-4ee2-5061-43520e8a9be8.png)
![2020-04-17_23.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615707/b26eb10d-0e0a-12ac-e71d-c3f84df8a352.png)
![2020-04-17_23.30.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615707/8c987251-2bb5-a515-8b07-baa77f424eac.png)
この様に、投げた場所にテレポートしながら移動できます。

###コマンド解説
![2020-04-17_23.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615707/af0acbec-ebdd-bf5a-e9b1-82f93e4aed8f.png)
まずはアイテム判定に必要なスコアボードを２つ作成
・/scoreboard objectives add tri minecraft.used:minecraft.trident
・/scoreboard objectives add T_ri dummy

次に今回のアイテムを入手
・/give @p minecraft:trident{display:{Name:'{"text":"移動用トライデント"}'},ItemName:T_ri} 1

(上記はすべてチャット欄に入力してください)

次にコマンドブロック

-1:execute as @a[scores={tri=1..,T_ri=1}] at @e[type=minecraft:trident] run tp @s ^0.5 ^ ^0.5
-2:scoreboard players set @a T_ri 0
-3:execute as @a[nbt={SelectedItem:{tag:{ItemName:T_ri}}}] run scoreboard players set @s T_ri 1

####最後に
今回のコマンドはこれで完成です！このコマンド、実はプレイヤーを動かすのに使っては１つのコマンドだけなんです。しかも、今回も前回に引き続き、普通のトライデントでは動作しないようになっております。
では、皆さん！良いコマンドライフを～！！
OBS Studio on Azure フルリモートで快適なオンライン配信環境を実現する

昨今多くのイベントがオンラインに移行しています。数人でも集まれる状態であれば登壇者やスタッフが機材の整ったスタジオで収録・配信するのがベストでしょう。しかし、フルリモートの環境下において自宅で潤沢な配信環境を手配するのが難しくなっています。ネックになるのは配信用PCのスペック、そしてネットワーク環境です。

本稿では筆者の実体験をもとにクラウド上でOBS Studioをセットアップする流れを説明していきます（ここではOBS StudioやAzure、RDP接続などの基本操作には触れていません）なお、Azureを例に紹介していますが、基本的に仮想マシンしか使っていないため、WindowsインスタンスでRDP接続可能な状態であれば他のクラウドサービスでも使える内容だと思います。


## 配信に必要なマシンスペックって？

OBS経由で配信する際にはCPU/GPUともにある程度のスペックがあると良いでしょう。体感ですが、いわゆるゲーミングPCクラス、具体的にはCore i7以上のCPU、ディスクリートGPUあたりでしょうか。スペックが足りない場合はアプリがフリーズしたり映像が止まる、コマ落ちするなどの現状が起こりえます。

ネットワーク環境として配信で必要なのは上りの帯域です、先日自宅から配信した際には上り10Mbpsで張り付いていました。リモートワークの増加により特にマンションなどの集合住宅では帯域が確保しづらくなっていると聞きます。


## 仮想マシンを立ち上げる

モノは試し、ひとまずサーバーを立ててみましょう。[portal.azure.com](https://portal.azure.com/)にアクセスしサインインします。有効なサブスクリプションを確認しておきましょう。リソースグループを指定し、仮想マシンの作成を進めます。

注意点としては、2020年4月現在デフォルトのイメージの中にある「Windows 10 Pro, Version 1809」ではなく、すべてのイメージの参照から「Version 1903」以降のWindows 10 Proを選択するようにしましょう。後のOBS Studioで重要になってくるウインドウキャプチャの設定で、Windows Graphics Captureを有効化する必要があるためです。
<img width="690" alt="Screen Shot 2020-04-17 at 22.43.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33718/55f1b896-17dd-e35e-77c3-395bb9aaa38b.png">

イメージのサイズはGPUが有効な「[Nシリーズ](https://azure.microsoft.com/ja-jp/pricing/details/virtual-machines/series/?WT.mc_id=docs-qiita-nosuzuk)」をおすすめします。リージョンにもよりますが筆者が検証で使ったNC12で1時間100数十円、2−3時間の配信でも500円程度で収まるはずです（終わったらちゃんとインスタンスを落としましょう！）

OBS StudioをGUIで操作するため、RDP接続を有効にします。デフォルト設定の通り、3389番ポートを開放し必要に応じてネットワークのセキュリティを設定しておきましょう。これひとまず設定は完了です、インスタンスを作成し起動するのを待ちます。
<img width="800" alt="Screen Shot 2020-04-17 at 23.03.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33718/c6d3f302-e342-5e3e-80af-9242c508b0d7.png">

- 参考手順: [Azure で Windows 仮想マシンを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-windows-virtual-machine-in-azure/?WT.mc_id=docs-qiita-nosuzuk)


## 仮想マシンに接続する

無事に起動したら接続タブから「RDP」を選択し、.rdpファイルをダウンロードしておきます。先ほど仮想マシン作成時に入力したユーザー名とパスワードで接続しましょう。
<img width="555" alt="68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f33333731382f35623965646636632d323138662d633065342d643432362d3962623561386139633931312e706e67.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33718/c1367278-1c25-a054-215f-bbe8d39f62d6.png">

Windows 10が立ち上がったら、OBS Studio、MS TeamsやZoom等のソフトウェアをダウンロード、インストールし、ブラウザではYouTubeなどのサービスにログインして配信用のストリームキーを取得しておきます。あとは手元のPCと同じようにOBSの設定を進めてみましょう。OBSですがシーンと呼ばれる設定ファイルが、JSON形式でexport/importできるようになっています。これを画像等のファイルと一緒にGitHubなどで管理しておけばセットアップも楽になるのではないかと思います。

memo: 普段使っている手元のPCではなく、データセンター上のマシンからYouTube（Googleアカウント）やTwitterにログインする際には二要素認証が必要になることがあります、慌てず対応しましょう。


## 終わりに

オンライイベントの需要が高まりそのやり方もこなれてくるに連れて、よりリッチな配信が求められるようになってきました。ただスライド画面を表示するだけでなく、Twitterのタイムラインを流したり、登壇者の顔を表示させたりと言った複数のソースを組み合わせるには、OBS Studioが高機能で重宝します。

今回はそのOBSを環境やマシンを選ばずにAzure上で操作する方法を紹介しました、ぜひ明日からのイベントに役立ててもらると幸いです。やり方が分からないひとはぜひ[こちらのコミュニティ]((https://mvsmjp.connpass.com/))にも参加してみてください、みんなでオンライン配信に関するノウハウを貯めていきましょう！


※マイクやカメラなどの機材を組み合わせたり、ミキサーなどで複数の音声信号を扱う場合はどうしても手元で操作したくなります、クラウド配信をバックアップとして使うのもありかもしれません。
View を支えるコンバーター（QuickConverter）

## はじめに

オレオレ解釈の戒め覚え書き　その３

[前回](https://qiita.com/kawasawa/items/1c40b596838c2e9e24f3)に続きコンバーターの話です。強力なライブラリである QuickConverter についてご紹介します。

## 本文

値の変換は通常のコンバーターでも可能ですし、むしろその方が正攻法でしょう。とはいえ、使われるパターンとしては bool <-> Visibility などの単純なものや、一か所でしか利用されない変換である場合も多く、そのたびにコンバーターを用意するのは大袈裟な気もしています。汎用的に使える仕組みはないものかと探していたところ、QuickConverter というライブラリを見つけました。

QuickConverter は C# の記述方法を使い Xaml 上で変換式を直接定義できるため、View のソースだけで処理を完結させることができます。前回の bool 値を変換する例をこの方法で書き換えてみると、次のようにコンバーターが要らなくなります。

```xml:View
<GroupBox Visibility="{qc:Binding '$P ? Visibility.Visible : Visibility.Collapsed', ConvertBack='$value == Visibility.Visible', P={Binding IsVisible, Mode=TwoWay}}"/>
```

複数のプロパティをバインドすることだってできます。

```xml:View
<GroupBox Visibility="{qc:MultiBinding '$P0 ## $P1 ? Visibility.Visible : Visibility.Collapsed', P0={Binding Hoge, Mode=OneWay}, P1={Binding Huga, Mode=OneWay}}"/>
```

イベントのハンドリングまでできてしまいます。（コンバーターの守備範囲を超えていますが。）

```xml:View
<TextBlock x:Name="txt"/>
<Button Click="{qc:QuickEvent '$txt.Text = \'クリックされた\''}"/>
```

このように、これまでコンバーターを挟んでいた処理が Xaml 内で実装できるため、変換処理を見通しやすくなりました。非常に強力で応用が利くため、私は好んでこちらのライブラリを使わせて頂いています。

## おわりに

QuickConverter についてご紹介しました。
私の場合は、共通化が必要なロジックは従来のコンバーターを使い、一行で完結する処理や、わざわざクラス化する間でもないと判断した場合は QuickConverter で実装しています。今回の例だけでもその汎用性の高さを感じ取れるかと思います。

詳しい説明は是非作者様のページをご覧ください。
https://github.com/JohannesMoersch/QuickConverter

次回はビヘイビアについてまとめます。
Pythonで毎日AtCoder #39

### はじめに
[前回](https://qiita.com/taxfree_python/items/3763ad465aa31d0885ca)
今日のよるかつを書きます。A,Bしか解けませんでした。睡魔には勝てない

### A問題
[ABC069-A](https://atcoder.jp/contests/abc069/tasks/abc069_a)

**考えたこと**
$(n-1)*(m-1)$するだけ

```python
n, m = map(int,input().split())

print((n-1)*(m-1))
```

### B問題
[ABC107-B](https://atcoder.jp/contests/abc107/tasks/abc107_b)

**考えたこと**
最近やったのでスラスラ書けました。縦と横で調べる。

```python
h, w = map(int,input().split())
a = [list(input()) for _ in range(h)]

yoko = []
for i in range(h):
    seta = set(a[i])
    if '#' in seta:
        yoko.append(a[i])

h = len(yoko)
w = len(yoko[0])
for i in range(w):
    tate = []
    for j in range(h):
        tate.append(yoko[j][i])
    settate = set(tate)
    if '#'not in settate:
        for j in range(h):
            yoko[j][i] = ''

ans = ''
for i in range(h):
    c = ''.join(yoko[i])
    ans += c
    if i != h-1:
        ans += '\n'
print(ans)
```

### C問題
[ABC089-C](https://atcoder.jp/contests/abc089/tasks/abc089_c)
組み合わせの計算方法が分からなかった

### D問題
[ABC075-C](https://atcoder.jp/contests/abc075/tasks/abc075_c)
辺を落としてdfsすれば解けそうだけど、実装できない。

### まとめ
これが本番だったらレート下るので、解けるように復習します。最近は、dfsしたら解けそうと思っても書けないことがあるので精進します。ではまた、おやすみなさい
テキスト正規化用PythonライブラリをMATLABからコール

# はじめに

テキスト解析をする上で、他言語で書かれた既存のテキスト解析関数を使いたいケースがあるのでやってみました。
[neologdn](https://github.com/ikegami-yukino/neologdn)というPythonベースの文書初期化ツールをMATLABから呼んでみます。筆者はPython初心者なので色々間違っていたらすみません。

# 環境
MATLAB R2020a
Python 3.6

# 手順

[「Python ライブラリ関数の呼び出し」](https://jp.mathworks.com/help/matlab/getting-started-with-python.html)という公式ページがあるのでこちらを参考に準備をします。MATLABとPythonの両環境が必要になってくるわけですが、一言にPythonと言っても、MATLABからの呼び出しにサポートしているものがあり、そちらの方が簡単そうなので公式ページの通りにインストールしました。

試しにMATLAB側で下記を入力します。

```MATLAB:MATLAB
py.os.listdir('.')
```

すると、Python側のos.listdirを使ってファイルの一覧を表示することができました。

次に、[neologdn](https://github.com/ikegami-yukino/neologdn)という、日本語を正規化してくれるツールを使用する準備をします。
>neologdn is a Japanese text normalizer for mecab-neologd. The normalization is based on the neologd's rules: https://github.com/neologd/mecab-ipadic-neologd/wiki/Regexp.ja

neologdをインストールします。

```:コマンドプロンプト
py -m pip install neologdn
```

これで準備完了です。

neologdのreadmeにある例文をMATLABで実行してみましょう。

```matlab:MATLAB
>> py.neologdn.normalize("ﾊﾝｶｸｶﾅ")

ans = 

  Python str にはプロパティがありません。

    ハンカクカナ

>> py.neologdn.normalize("全角記号！？＠＃")

ans = 

  Python str にはプロパティがありません。

    全角記号!?@#

>> py.neologdn.normalize("全角記号例外「・」")

ans = 

  Python str にはプロパティがありません。

    全角記号例外「・」

>> py.neologdn.normalize("長音短縮ウェーーーーイ")

ans = 

  Python str にはプロパティがありません。

    長音短縮ウェーイ

>> py.neologdn.normalize("チルダ削除ウェ~∼∾〜〰～イ")

ans = 

  Python str にはプロパティがありません。

    チルダ削除ウェイ

>> py.neologdn.normalize("いろんなハイフン˗֊‐‑‒–⁃⁻₋−")

ans = 

  Python str にはプロパティがありません。

    いろんなハイフン-

>> py.neologdn.normalize("　　　ＰＲＭＬ　　副　読　本　　　")

ans = 

  Python str にはプロパティがありません。

    PRML副読本

>> py.neologdn.normalize(" Natural Language Processing ")

ans = 

  Python str にはプロパティがありません。

    Natural Language Processing

>> py.neologdn.normalize("かわいいいいいいいいい", pyargs('repeat',6))

ans = 

  Python str にはプロパティがありません。

    かわいいいいいい

>> py.neologdn.normalize("無駄無駄無駄無駄ァ", pyargs('repeat',1))

ans = 

  Python str にはプロパティがありません。

    無駄ァ

>> 
```
readmeの通りに処理できていますね。
ちなみに結果はstr型で返ってくるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521542/91ad9578-7857-31ed-8173-a1e9abd33505.png)

Text Analytics Toolboxでトークンに分ける前に、こんな感じでノーマライズできると便利そうですね。
config.consider_all_requests_local=trueにしたら、Routing Error時に「作成したview」が表示されない。

「Ruby on Rails6実践ガイド」に沿ってアプリを作っていると、この仕様に気づかず４時間ほど詰まってしまったので記事にします。

#状況
Windows10home、VirtualBoxにUbuntu、更にDocker入れてRailsアプリ作成。
クライアントによって指定されたURLパスに対応するルーティングが存在しない場合（Routing Error）、デフォルトの
![Qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/e87b8f90-6334-b26f-1db1-f9b61a765fb7.png)
ではなく、自作した
![Qiita3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/815bddcc-5b2d-8c90-e7e3-ad108b30b40a.png)


を表示させたいが、
![Qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/912d728d-254b-b90d-fc07-95e6259f43ad.png)

この表示になる。
サーバー実行はターミナル（端末）でこれ。

```
$ bin/rails s -e production -b 0.0.0.0
```

#原因
本番環境でサーバー立ち上げたらターミナルにログが出ず、エラーの時に何が原因か分かりにくいので、

```
- config.consider_all_requests_local=false
+ config.consider_all_requests_local=true
```
と、falseからtrueに変えていたから。
falseに直すとRouting Error時に作成した画面が表示されました。
Rooting Errorになってもviewを表示する設定になっているから、そのviewが出ると思っていました。
他のエラーの時は、ちゃんと作成した画面が表示されるので。
ちなみにfalseにもどしても、railsサーバーを再起動しないと反映されません。

#ちなみにconfig.consider_all_requests_localとは
trueにしたらブラウザにエラーレポートが表示され、falseにしたら表示されない。
config/developments/内にあり。
AtCoder 生活　29日目

[前回](https://qiita.com/flandrescarlet237/items/ece2402a5178870dd94f)

#29日目
今回は、B問題を4問解きました

|問題番号|難易度|自力で解けた|かかった時間|
|---|:-:|:-:|---|---|
|ABC108|B|✕|83分41秒|
|ABC109|B|◯|71分59秒|
|ABC110|B|✕|131分19秒|
|ABC111|B|◯|7分43秒|

## ABC108_B

問題:[Ruined Square ]
(https://atcoder.jp/contests/abc108/tasks/abc108_b)


```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main(){
    int a,b,c,d;
    cin >> a >> b >> c >> d;
    cout << c-(d-b) << " " << d+(c-a) << " " << a-(d-b) << " " << b+(c-a) << endl;
}

```

解くのにかかった時間：83分41秒
感想：どう計算すれば出るのかが、思いつかなかった


## ABC109_B

問題:[Shiritori]
(https://atcoder.jp/contests/abc109/tasks/abc109_b)


```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main(){
    int n;
    cin >> n;
    vector<string> w(n) ,s(n);
    rep(i,n) {
        cin >> w[i];
        s[i] = w[i];
    }
    sort(s.begin(),s.end());
    rep(i,n-1){
        if(w[i+1][0] != w[i][w[i].size()-1]){
            cout << "No" << endl;
            return 0;
        }
        if(s[i] == s[i+1]){
            cout << "No" << endl;
            return 0;
        }
    }
    cout << "Yes" << endl;
}

```

解くのにかかった時間：71分59秒
感想：時間はかかったがなんとかなった。


## ABC110_B

問題:[1 Dimensional World's Tale]
(https://atcoder.jp/contests/abc110/tasks/abc110_b)


```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main() {
    int N,M,X,Y;
    cin >> N >> M >> X >> Y;
    vector<int> x(N),y(M);
    rep(i,N) cin　>>　x[i];
    rep(i,M) cin　>>　y[i];
    if (X >= Y) {
        cout << "War" << endl;
        return 0;
    }
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());
    if (x[N - 1] < y[0] && x[N - 1] < Y && y[0] > X) cout << "No War" << endl;
    else cout << "War" << endl;   
    return 0;
}

```

解くのにかかった時間：131分19秒
感想：条件の付け方について思いつかなかった


## ABC111_B

問題:[AtCoder Beginner Contest 111]
(https://atcoder.jp/contests/abc111/tasks/abc111_b)


```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main(){
    int n;
    cin >> n;
    int s = 111;
    for(int i = 1;i<10;i++){
        if(s*i >= n){
            cout << s*i << endl;
            return 0;
        }
    }
}

```

解くのにかかった時間：7分43秒
感想：簡単だった


###最後に
4問しかなかったときのB問題が全然解けない。数学的思考をより多く使用する気がする。


|難易度|かかった平均時間|解けた問題数|
|:-:|---|---|
|B|39分51秒|4問中2問|
Looking for full-service digital agency, businesses & individuals freelancers to make a strategic business partnership

At 4LIFE Innovations, we innovate for LIFE.

Looking for full-service digital agency, businesses & individuals freelancers to make a strategic business partnership

Our main vision of our web design partnership program to empower businesses with digital tools that help to conquer their target and competitive global markets.

We will provide our services, agile dedicated team and complete transparency towards our partnership.
Our Approach As A Web Design Partner

We are one-stop digital solutions for your agency, check our latest proven track record of delivering successful websites here. We will act as a trusted partner and reseller of your services.

When you choose us, you will get full-service digital solutions that will make your website more creative, SEO friendly and upgraded to the latest technologies – We offer

    WordPress Web Design
    eCommerce Website Development
    Theme Customization & Website redesign
    Logo, UI & UX Design
    Static/Dynamic Website Design
    PSD to HTML5 Design
    Newsletter & Brochure Design
    Website Maintenance
    Search Engine Optimization
    Hire Dedicated Resources

4LIFE Innovations Partnership Models

Business Strategic Partnership – You have your digital agency with marketing resources but lack an in-house technology and development team, then we’ve got the best solution for you. We will act as an extended technological arm for your team and help you deliver those services with ease.

Sales Partnership – You will be the business executive and will remain more involved in the sales discussion level to trigger qualified leads into long term customers.

Referral partnership -You can promote our services to bring leads to us, with each successful conversion, you will get referral bonus. 

Join our partnership program.
[数学]順列、組合せをWolframで求める

## 順列(Permutaion)

* 異なるn個のものの中から、r個を取り出して、並べるときの順列の数を$_n\mathrm{P} _r$と表す。

    $
    \begin{eqnarray}
    _n\mathrm{P} _r = \frac{n!}{(n-r)!}
    \end{eqnarray}
    $

## 組合せ(Combination)

* n個のものの中から、r個を取り出すときの組合せの数を$_n\mathrm{C} _r$と表す。

    $
    \begin{eqnarray}
    _n\mathrm{C} _r = \frac{_n\mathrm{P} _r}{r!} = \frac{n!}{r!(n-r)!}
    \end{eqnarray}
    $

### [Wolfram](https://www.wolframalpha.com/)で計算

* $_n\mathrm{C} _r$は、`Wolfram`では次のようにして計算できる。
  `組合せ`は`二項定理`(binomial)で表現できる。

    ```
    binomial(n,r)
    ```

* 同様に、$_n\mathrm{P} _r$は、`Wolfram`では次のようにして計算できる。

    $
    \begin{eqnarray}
    {_n\mathrm{P} _r} = {_n\mathrm{C} _r} \times r!
    \end{eqnarray}
    $

    ```
    binomial(n,r) * r!
    ```
Emacs 文字サイズの変更


Emacsで文字サイズの変更は text-scale-adust(C-x C-0) -,+,0 で変更可能ですが、Chromeのサイズ変更の方が慣れているので頭の切り替えをしなくても良いように割り当てました。


```init.el
(global-set-key (kbd "s-+") 'text-scale-increase) ;; 文字サイズを大きくする
(global-set-key (kbd "s-_") 'text-scale-decrease) ;; 文字サイズを小さくする
```


(参考)
https://ayatakesi.github.io/emacs/24.5/Text-Scale.html
quickrun.elでKotlinを実行する


**2020年04月29日現在quickrun.elでKotlinも使えるようになったため、該当のバージョンにすればこちらの記事の設定は不要になります。メンテナの方々ありがとうございました。**

Kotlinの[Playground](https://play.kotlinlang.org/) を使ってる時にEmacsで書いてサクッと実行を試したいと思い
quickrunでKotlin対応してないかを調べた結果、READMEに追加方法がありJavaを参考に書いた。

```init.el
(quickrun-add-command "kotlin"
  '((:command . "kotlin")
    (:exec    . ("kotlinc %o %s" "%c %NKt %a"))
    (:remove  . ("%nKt.class"))
    (:tempfile . nil)
    (:description . "Compile Kotlin file and execute")
    )
  :mode 'kotlin-mode)
```


Playground自体は他の人と共有する時に便利なので引き続き使っていくけど、個人で試すだけであれば積極的に使っていく。

![quickkotlin.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132235/8eb75830-f9e5-5f73-1664-328687c6e180.gif)


(参考)
https://github.com/syohex/emacs-quickrun
https://github.com/syohex/emacs-quickrun/blob/55bbe5d54b80206ea5a60bf2f58eb6368b2c8201/quickrun.el#L237
hamlによるlink_toの書き方

チーム開発が始まり、hamlでのlink_toの書き方に戸惑ったのでアウトプットのために投稿を決意。

hamlの書き方にはまだ慣れずに少しづつ練習中。。。

本題に入る、link_toについてとてもわかりやすい参考を見つけたのでそれを元にまとめたい。

どのボタンを押した時に、どこにpathしたいのかを考える必要がある。

記述参考例、以下を例にするとclassのexhibition-boxというボタンを押した時に出品ページに飛ぶようになる。
= link_to new_ Product_path, class: "exhibition-box" do
  .exhibition-box__text
    出品する

まず、出品ページに飛ぶようにするためにnew_product_pathが必要になる。
どこのページに飛ばしたいのかを決めるには、ターミナルでrails routesコマンドを入力し左上に出てくるPrefix　Verb URI Patternの
prifix一覧をみる。一覧からどこへ飛ばすのかlink_toを指定してあげる。
ポータルサイト創作記：３日目

昨日まで
```$ rails new```のコマンドを使って新しいアプリケーションのファイル群を生成した。
<img width="1440" alt="スクリーンショット 2020-04-17 18.28.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/62fcfc48-3ab3-a22c-fd21-8ba598031c9b.png">

今日はGitHubにプッシュしていく。

まずはブランチを切る。
`rails-new-app`というブランチに切り替わった。
<img width="512" alt="スクリーンショット 2020-04-17 18.30.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/6d908074-fc86-9688-65c0-657ee3bb3c2b.png">

同じ階層にあるファイル（```.```）をインデックスに追加　（```git add```）。
その後、コミット。すごい数のファイルがコミットされていく。
<img width="510" alt="スクリーンショット 2020-04-17 18.32.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/fa9d907f-ed49-d803-2f57-fab14a36ef7e.png">

そして、リモートリポジトリにプッシュ。
<img width="510" alt="スクリーンショット 2020-04-17 18.33.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/3a721486-2f1a-06b7-7e59-d777c75d9fed.png">

GitHubにはプッシュが届いている。
<img width="714" alt="スクリーンショット 2020-04-17 18.34.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/7b4574d0-56da-e324-5244-be560f90a56a.png">

compare changeをチェック。新しいブランチ`rails-new-app`がプルダウンに加わっている。
<img width="714" alt="スクリーンショット 2020-04-17 18.36.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/143aafa8-d060-12db-43ed-a510729993b4.png">

`rails-new-app`を選択すると…80ものファイル変更が報告されている！
<img width="714" alt="スクリーンショット 2020-04-17 18.36.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/30d4ac64-0473-5198-d98b-ff019bf19959.png">

コレを`pull request`。
<img width="713" alt="スクリーンショット 2020-04-17 18.41.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/214ec7cb-8331-1f9e-da31-0818c9616213.png">
変更の内容をコメントに残す。

「Merge pull request」ボタンを押す。
これで、切ったブランチが大元のブランチ（master）にマージ（統合）される。
<img width="713" alt="スクリーンショット 2020-04-17 18.42.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/117f3dd0-73fa-95aa-00ca-83307ea9535a.png">

マージされたら、`rails-new-app`ブランチは消す。
<img width="714" alt="スクリーンショット 2020-04-17 18.46.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/f5eab25e-3282-221d-888f-9501c8de007b.png">

今日はここまで！
【今日のアブストラクト】Distilling the Knowledge in a Neural Network【論文 DeepL 翻訳】

1 日 1 回 論文の Abstract を DeepL 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ [DeepL](https://www.deepl.com/home) 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Distilling the Knowledge in a Neural Network](https://arxiv.org/abs/1503.02531)

# Abstract

### 訳文

ほとんどの機械学習アルゴリズムの性能を向上させる非常に簡単な方法は, 同じデータ上で多くの異なるモデルを訓練し, それらの予測値を平均化することである. 残念ながら, モデルのアンサンブル全体を使って予測を行うことは面倒であり, 特に個々のモデルが大規模なニューラルネットである場合には, 多くのユーザーが利用可能にするには計算量が多すぎるかもしれない. Caruana と彼の共同研究者は, アンサンブル内の知識を圧縮して単一のモデルにすることが可能であることを示しており, 我々はこのアプローチを別の圧縮技術を用いてさらに開発している. 我々は MNIST で驚くべき結果を得ており, モデルのアンサンブルの知識を単一のモデルに蒸留することで, 多用されている商用システムの音響モデルを大幅に改善できることを示す. また、$1$ つ以上の完全モデルと, 完全モデルが混同している細かいクラスを区別するために学習する多くの専門モデルから構成される新しいタイプのアンサンブルを導入した. 専門の混合モデルとは異なり, これらの専門モデルは迅速かつ並列に学習することができる.


### 原文

A very simple way to improve the performance of almost any machine learning algorithm is to train many different models on the same data and then to average their predictions. Unfortunately, making predictions using a whole ensemble of models is cumbersome and may be too computationally expensive to allow deployment to a large number of users, especially if the individual models are large neural nets. Caruana and his collaborators have shown that it is possible to compress the knowledge in an ensemble into a single model which is much easier to deploy and we develop this approach further using a different compression technique. We achieve some surprising results on MNIST and we show that we can significantly improve the acoustic model of a heavily used commercial system by distilling the knowledge in an ensemble of models into a single model. We also introduce a new type of ensemble composed of one or more full models and many specialist models which learn to distinguish fine-grained classes that the full models confuse. Unlike a mixture of experts, these specialist models can be trained rapidly and in parallel.
【Ruby】ERROR:  Error installing sqlite3:         ERROR: Failed to build gem native extension.が表示される【環境構築時エラー】

#sqlite3をインストール時エラー

sqlite3をインストールする為に以下gemコマンドを実行しました。

```
gem install sqlite3 --platform=ruby -- --with-sqlite3-include=G:/sqli
te3 --with-sqlite3-lib=G:\uru
```

するとエラーが生じました。

```
Temporarily enhancing PATH for MSYS/MINGW...
Installing required msys2 packages: mingw-w64-x86_64-sqlite3
警告: 公開キーリングが見つかりません。'pacman-key --init' を実行済みですか？
エラー: mingw32: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" は不明です
エラー: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" をリモートで検索できませ
んでした
エラー: mingw64: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" は不明です
エラー: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" をリモートで検索できませ
んでした
エラー: msys: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" は不明です
エラー: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" をリモートで検索できませ
んでした
エラー: データベース 'mingw32' は無効です (無効または破損したデータベース (PGP
鍵))
エラー: データベース 'mingw64' は無効です (無効または破損したデータベース (PGP
鍵))
エラー: データベース 'msys' は無効です (無効または破損したデータベース (PGP 鍵))

pacman failed with the following output:
Building native extensions with: '--with-sqlite3-include=G:/sqlite3 --with-sqlit
e3-lib=G:\uru'
This could take a while...
ERROR:  Error installing sqlite3:
        ERROR: Failed to build gem native extension.

    current directory: G:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sqlite3-1.4.2/ext/
sqlite3
G:/Ruby26-x64/bin/ruby.exe -I G:/Ruby26-x64/lib/ruby/2.6.0 -r ./siteconf20200402
-9828-740tem.rb extconf.rb --with-sqlite3-include\=G:/sqlite3 --with-sqlite3-lib
\=G:\\uru
checking for sqlite3.h... yes
checking for pthread_create() in -lpthread... yes
checking for -ldl... no
checking for sqlite3_libversion_number() in -lsqlite3... no
sqlite3 is missing. Install SQLite3 from http://www.sqlite.org/ first.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

```

調べてみたら、[こちら](https://www.sqlite.org/download.html)からダウンロードした
・sqlite-amalgamation-3310100.zip
・sqlite-dll-win64-x64-3310100.zip
を解凍したファイルの「sqlite3.h」「sqlite3.dll」の配置が悪かったようです。

Pathが通ってる「G:\Ruby26-x64\bin」に「sqlite3.h」「sqlite3.dll」の両方のファイルをいれ以下コマンドを入力しました。

```
gem install sqlite3 --platform=ruby -- --with-sqlite3-include=G:\Ruby26-x64\bin --with-sqlite3-lib=G:\Ruby26-x64\bin
```


```
pacman failed with the following output:
Building native extensions with: '--with-sqlite3-include=G:\Ruby26-x64\bin --wit
h-sqlite3-lib=G:\Ruby26-x64\bin'
This could take a while...
Successfully installed sqlite3-1.4.2
Parsing documentation for sqlite3-1.4.2
Installing ri documentation for sqlite3-1.4.2
Done installing documentation for sqlite3 after 5 seconds
1 gem installed
```

今度は無事インストール出来ました！！