OmniAICreator/Qiita-1.07M huggingface dataset:
Combineを使用したイベントの受信と処理

## はじめに

これまではイベントの発行と購読にはRxSwiftなどの外部ライブラリを導入していたと思いますが、WWDC2019にてついにApple標準のイベントの発行と購読を可能にしたフレームワーク、Combineが発表されました。
ただしiOS13以上でしか利用できないので注意が必要です。
今回はそんなCombineの簡単なイベント発行と購読、流れてくる値の加工についてテキストフィールドを例に説明していきます。

## 押さえておきたい役割

### Publisher（発行者）
★[Publisher](https://developer.apple.com/documentation/combine/publisher)
型が一連の値を長期にわたって送信できることを宣言するためのプロトコル
[NotificationCenter](https://developer.apple.com/documentation/foundation/notificationcenter)にはPublisherを戻り値とする以下のメソッドが用意されています

★[publisher(for: object: )](https://developer.apple.com/documentation/foundation/notificationcenter/3329353-publisher)
通知の名前と通知元のソースオブジェクトを受け取り、通知要素を生成するPublisherを返します

### Operator（値の加工）
★[map(_: )](https://developer.apple.com/documentation/combine/publisher/3204718-map), [flatMap(maxPublishers: _: )](https://developer.apple.com/documentation/combine/publisher/3204712-flatmap), [reduce(_: _: )](https://developer.apple.com/documentation/combine/publisher/3204744-reduce)
Swift標準ライブラリの同等の演算子と使い方は同じなので説明は割愛します

### Subscriber（購読者）
★[Subscriber](https://developer.apple.com/documentation/combine/subscriber)
Publisherから通知を受け取ることができる型を宣言するためのプロトコル
Publisherに準拠した型にはSubscriberを戻り値とする以下のメソッドが用意されています

★[sink(receiveCompletion: receiveValue: )](https://developer.apple.com/documentation/combine/publisher/3343978-sink)
値を受け取って処理を行う

★[assign(to: on: )](https://developer.apple.com/documentation/combine/publisher/3235801-assign)
受け取った値を指定したプロパティに割り当てる

## テキストフィールドの値変更の通知を受け取る

```sample.swift
let sub = NotificationCenter.default
    .publisher(for: NSControl.textDidChangeNotification, object: filterField)
    .map( { ($0.object as! NSTextField).stringValue } )
    .sink(receiveCompletion: { print ($0) },
          receiveValue: { print ($0) })
```
★解説
NotificationCenterのpublisherメソッドでテキストフィールドのテキストの変更の監視を宣言し、mapメソッドで流れてくる値をString型に変換し、sinkメソッドで受け取った値をprintで出力している

## 必要に応じて購読をキャンセル
Publisherは、正常に完了するか失敗するまで、イベントを発行し続けます。Publiserを購読する必要がなくなった場合は、購読をキャンセルできます。 
Subscriberプロトコルは[cancell()](https://developer.apple.com/documentation/combine/cancellable/3204391-cancel)メソッドを提供する[Cancellable](https://developer.apple.com/documentation/combine/cancellable)プロトコルを実装しています。

```sample.swift
sub?.cancel()
```
特定のページにのみJSファイルを適用する方法

Railsは、初期状態でapp/assets/javascriptsディレクトリ以下の全てのJavaScriptを自動で読み込みます。

ただ、別ページに遷移した際にJSファイルの読み込みができず、エラーが起きてしまうのことがあるため、特定ページのみでJSファイルが発火する様にしていきます。

読み込ませるJavaScriptを個別に指定するには次のようにします。

こちらのページを参考にさせていただきました。
http://keruuweb.com/rails-%E5%BF%85%E8%A6%81%E3%81%AAjavascript%E3%81%AE%E3%81%BF%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80/

作成の都合上、HTMLをHAMLで記載しております。

## STEP1
app/assets/javascripts/application.js内の一番下にこちらの記述がある場合はコメントアウトします。=を消すだけ。

```
//= require turbolinks
//= require_tree .
```

## STEP2
config/initializers/assets.rb内にこちらのコードを追加してください。


```rb
Rails.application.config.assets.precompile += %w( *.js )
```

アプリケーションサーバーをストップして、再起動します。

```console
$ rails s
```

## STEP3

JSファイルを読みませたいhtml.haml内の最下部にこちらのコードを追加する。

```haml
= javascript_include_tag '自分で作ったjsファイル名'
```


##  最後に
以上で特定ファイルだけで読みこむことに成功しました。
他のページに遷移してもエラーになりません。
CentOS 7 MATE Desktop 最小構成インストール

###0. はじめに

以前、Gnome3の最小構成インストール方法を考え暫くはGnome3を使っていたが、やはり使いづらい。

CentOS 7 GNOME最小構成インストール
https://qiita.com/knoppy/items/38c331cdfd08ce410178

いろいろ調べてみると、Gnome2からフォークされた MATE Desktop というとが巷では人気らしい。。。

そのインストール方法だが、どこのブログや記事を見ても

```
yum groupinstall "X Window System"
yum groupinstall "MATE Desktop"
```

と書いてありこれでは余計なパッケージが大量に導入されてしまうので、
MATE Desktop版最小構成インストール方法を考えてみた。

###1. 実際にやってみた
以下のコマンドを打つだけで終わりです。

```
yum groupinstall "X Window System"
yum install gdm mate-desktop mate-desktop-libs mate-control-center mate-terminal mate-settings-daemon caja caja-open-terminal

# 欲しい人は
yum install system-config-language.noarch system-config-date  system-config-printer system-config-users network-manager-applet

# 私は通常CUI、必要な時だけVNCを使いGUI環境を使うので
echo "exec /usr/bin/mate-session" >> ~/.xinitrc 
vim ~/.vnc/xstartup
#exec /etc/X11/xinit/xinitrc
exec /usr/bin/mate-session
```

普通にデスクトップ環境として使う人は、runlevelを変更してください。
まぁそんな人は、最小構成でインストールしないと思いますが・・・

###2. 結果

素晴らしい！！
慣れもあるだろうが、Gnome2が一番使いやすいと思うのは私だけだろうか・・・
（Windows10のGUIも、Microsoftさんなんとかしてくれないかなぁ・・・）

CentOS 7.7上のMate Desktop
<img width="912" alt="スクリーンショット 2020-04-13 2.27.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333729/f141dd58-ca36-7b63-b13e-e23fdb5070d8.png">

CentOS 5.11上のGnome2
<img width="912" alt="スクリーンショット 2020-04-13 2.20.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333729/6517b42c-41f8-8253-0e20-21903ec4af31.png">
PEP 560 (Core support for typing module and generic types) を読んだよメモ

昨日に引き続いて `__origin__` という属性について調べていたら、[PEP 560 -- Core support for typing module and generic types](https://www.python.org/dev/peps/pep-0560/) という PEP にたどり着きました。この PEP は 3.7 から採用されているので、すでに実装が存在して触ることができるやつです。

## 概要

* 型ヒントが登場したとき、Python 本体に手を入れないように設計していた
* しかし、当時(バージョン 3.6)は 3つの問題があった
    * `typing` モジュールのパフォーマンス
    * メタクラスの競合
    * `typing` モジュールで使われている多数のハック

## アプローチ

* `__class_getitem__` 、 `__mro_entries__` というふたつのスペシャルメソッドを追加する
* `__class_getitem__`
    * クラスオブジェクト向けの `__getitem__`
    * `Iterable[int]` などの場面で利用される
* `__mro_entries__`
    * クラスではないオブジェクトから派生クラスを作るときに呼び出される
    * `__mro_entries__` が返したクラスをもとに派生クラスの MRO を決定する
    * `typing._GenericAlias` を実現するための仕掛け
        * `List[int]` の `__mro_entries__` は `list` を返すので、実行時は `list` のサブクラスとして振る舞う
    * クラス定義時の継承クラスは `__orig_base__` に、解決済みの継承クラスは `__base__` に保存される

## 感想

* `typing._GenericAlias` が生まれましたきっかけとなる PEP を読みました
* この PEP を読んでから `typing` モジュールを読むとわかりやすいです
* PEP をあさり始めた目的であった `__origin__` は、 `__mro_entries__` を実現するためのプライベートな属性だったというオチでした
* `__class_getitem__` もうまく使うとハックしがいがありそうですね
ターミナルでIPアドレス確認方法【Linux】



## IPアドレスをターミナルからコマンドで確認

自分用にメモ！
IPアドレスを確認したい場合に下記のコマンドでサクッと確認できる。

### IPアドレス確認コマンド

```
$ curl ifconfig.io
```
Laravelのバッチを動かすためのcron設定手順

## Laravelでバッチ処理
Laravelのバッチ処理を実行するためにcronを設定する。

## cron設定手順

### ルートユーザーへ切り替え

```
$ sudo su
```

### ディレクトリを移動

```
$ cd /var/spool/cron
```

### cron設定を編集

```
$ vim root
```

下記を記述する。

```
#Ansible: laravel scheduler
* * * * * php /var/www/html/artisan schedule:run >> /dev/null 2>&1
```

毎秒ごとに/var/www/html のディレクトリで`artisan schedule:run`のコマンドが実行される。
パーミッション、所有権の変更コマンド【Linux】 


## ファイル、ディレクトリのパーミッション変更


### chmod パーミッション変更コマンド
test.phpのパーミッションを変更する。
例：パーミッションを775に変更

```
$ chmod 775 test.php
```
 

下記のパーミッションに変更される。

```
-rwxrwxr-x
```

| -       |       rwx |    rwx    | r-x |
|:-----:|:-----:|:-----:|:-----:
| -(ファイル)、d(ディレクトリ)| 所有者権限 | グループ権限 | その他のユーザー権限 |




| r| w | x|
|:-----------------|------------------:|:------------------:|
| 読み込み可能 | 書き込み可能 | 実行可能 |
| 4 | 2 | 1 |


## ファイル、ディレクトリの所有権変更

### chown 所有権変更コマンド

test.phpの所有権を変更する。
例：所有権をnginxに変更

```
$ chown nginx:nginx test.php
```
どの8進数リテラルが使えるかはプログラミング言語によって異なる

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/octet_literal) とのマルチポストです）

8進数を表記する文法は、主に以下の3つがあります。
（二番目と三番目は分かりにくいですが `ゼロ オー`[^octet] です）

* プリフィックスとして `0` を付与する (例: `0123`)
* プリフィックスとして `0o` を付与する (例: `0o123`)
* プリフィックスとして `0O` を付与する (例: `0O123`)

これらのうち、各プログラミング言語がどの文法を採用しているかを表にまとめました。

|言語|`0`|`0o`|`0O`|
|:--|:--:|:--:|:--:|
|C|○|×|×|
|PHP|○|×|×|
|Perl|○|×|×|
|Java|○|×|×|
|Scala (~2.9)|○|×|×|
|Scala (2.10~)|×|×|×|
|Kotlin|×|×|×|
|C#|×|×|×|
|Rust|×|○|×|
|Swift|×|○|×|
|Go|○|○|○|
|Ruby|○|○|○|
|Python2|○|○|○|
|Python3|×|○|○|
|JavaScript[^js]|○|○|○|

# 考察

* C や Java などは、プリフィックス `0` しか採用していない
* Scala や Python は、プリフィックス `0` を採用していたけどやめた
* C# や Kotlin はもそも8進数表記を採用していない
* 最近の傾向として、プリフィックス `0o` が採用されてきている

「8進数は `0123` って書くんだよ」というのは、もはや古いのかもしれません。

[^octet]: octet (8個組) の o
[^js]: ただし、0 のあとに 8 か 9 を含むなら10進数。参考：[字句文法 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Lexical_grammar#Decimal)
Ubuntu(18.04.3) Webサーバー構築

どうも、豚野郎です。
自宅にUbuntuを入れたPCがあったのですが、全く使ってなかったので
サーバー構築していきます。


<h1>1.アップデート</h1>
```
$sudo apt update
```
<p class="p1">まずはアップデートをかけていきます。</p>

<h1>2.ファイアウォールをインストール</h1>
<p class="p1">ここで、ファイアウォールをインストールできない事態が起きました。</p>
```
$apt install ufw
$sudo apt install ufw
$sudo apt-get install uff
```
<p class="p1">上記でダメな場合、下記のコマンドでファイアウォールの状態を確認しましょう。</p>
```
$sudo ufw status
状態: 非アクティブ
```
<p class="p1">ファイアウォールはインストールされている？ので、</p>
<p class="p1">有効にしてみます。</p>
```
$sudo ufw enable
ファイアウォールはアクティブかつシステムの起動時に有効化されます。
```
<p class="p1">状態を確認してみましょう。</p>
```
$sudo ufw status
状態: アクティブ
```
<p class="p1">これでファイアウォールの設定は完了です。</p>

<h1>3.sshのポートを開放</h1>
```
$sudo ufw allow 22
```
<p class="p1">この場合、22番ポートを開放します。</p>
<p class="p1">成功すれば</p>
```
ルールを追加しました
ルールを追加しました(v6)
```
<p class="p1">の表記が出ると思います。</p>

<h1>4.Apacheのポートを開放</h1>
```
$sudo ufw allow 80
```
<p class="p1">3と説明は同じです。</p>

<h1>5.Apacheのインストール</h1>
<p class="p1"><span class="s1">下記のエラーが出た場合</span></p>
```
E: ロック〜
```
<p class="p1"><span class="s1">以下を参考に対象ファイルを削除</span></p>
<p class="p3"><span class="s1"><a href="https://qiita.com/jizo/items/9496496a3156dd39d91a">https://qiita.com/jizo/items/9496496a3156dd39d91a</a></span></p>
<p class="p3"><span class="s1"><a href="https://ankyo.blog.ss-blog.jp/2011-10-25">https://ankyo.blog.ss-blog.jp/2011-10-25</a></span></p>
<p class="p1">これでダメ・・・・・</p>
<p class="p1">可能性として、前回のシャットダウンの時に問題があったのではないかと思い、</p>
<p class="p1">Ubuntuを再起動。</p>
<p class="p1">これでうまくいきました</p>
```
続行しますか? [Y/n]
$ Y
```
これでApacheのインストールは完了です。
<h1>6.確認</h1>
<p class="p1">では、サーバーが起動されているか確認しましょう。</p>
<p class="p1">Ubuntuの初期ページが表示されれば成功です。</p>
<p class="p1">まず、こちらでIPアドレスを確認</p>

```
$Ip a
```

<p class="p1">わかりにくいですが、下記のところに表示されています。</p>
<p class="p3"><span class="s1"><a href="https://linuxfan.info/ip-address">https://linuxfan.info/ip-address</a></span></p>
<p class="p1">IP<span class="s1">アドレス</span>をアドレスバーに入力すると・・・・・</p>

<img width="817" alt="スクリーンショット 2020-04-13 0.46.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497869/a6a384d4-296a-e360-a8c2-69e8d9f05aff.png">


<p class="p1">こちらで完了です。</p>
<p class="p1">このまま放置するとアタックされる可能性があるので、一度Apacheを停止させます。</p>
あくまで学習目的なので。

(自分の知り合いも独学でサーバー構築したら何らかのアタックを受けました。

何らかのセキュリティ対策を必要かもしれません)

```
$service apache2 stop
```

<p class="p4">表示されなければ問題ないかと思います。</p>
【Cacoo】AWSのクラウドアーキテクチャ構成図自動作成

# Cacooとは
簡単に綺麗な作図ができるクラウドサービス
https://cacoo.com/ja/features

# AWSの構成図の自動作成手順
こういうのってどこで書き方学ぶんでしょうね。
自動で作ってもらえるのでもう良いんですが('ω')

前提①：IAMユーザーの作成権限を持つAWSアカウントを有している。
前提②：Cacooに（無料）会員登録している。

やる作業は下記の２つです。

１．IAMユーザーの作成
２．権限設定とCacooとの連携

### IAMユーザーの作成
Cacoo専用のIAMユーザーを作成します。
[マネジメントコンソール] - [IAM] - [ユーザー] - [ユーザーを追加]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/8864d61f-441c-25c3-9e3c-2c573189ff70.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/09f1398e-2167-3f55-3d95-a0b8af6a9529.png)
ユーザー名を入力して、プログラムによるアクセスキーをチェックして次のステップへ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/1ddf9c63-2471-09f6-0a9e-025e0f396cb8.png)
そのまま設定を変えたり権限を与えたりせず、ステップを進めていきユーザーを作成します。
途中警告が出ますが、次の手順で権限を与えるので必要ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/b4e586c8-f264-9025-19c9-150827e6a66c.png)

#### 作成した際に、『アクセスキーID』と『シークレットアクセスキー』を確認できるので必ず控えて置きましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/12fa9ebf-6dfe-a6ee-657a-74948a09d788.png)



### 権限設定とCacooとの連携
ダッシュボードの「＋新しい図を作成」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/ee69e185-faf4-3aeb-175e-4d08a8ae3219.png)

左側にあるツールバーから[挿入] - [AWS構成図]を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/f479665d-e382-2e02-2fc1-2739f955f3fc.png)

[アクセスキー]タブを開くと、ポリシーが書かれているのでこの権限設定を『コピー』して、先程作成したIAMユーザーに付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/36132d2c-72e9-2802-32ff-460af42627b4.png)

再びAWSに戻り、[マネジメントコンソール] - [IAM] - [ユーザー] - [作成したユーザー]を選択
アクセス権限タブの右端にある[インラインポリシーの追加] - [JSON]タブに移動したら、Cacooでコピーしたテキストをペースト。下記のような状態になっていればOKです。
あとは[ポリシーの確認]、ポリシーの名前を入力して[ポリシーの作成]を選択すればAWS側の設定は完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/783d7b70-de79-44d5-98f7-573c5dd406ec.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/db84f105-aec0-03d3-69d3-66af44ac7cb4.png)

Cacooに戻り、先程控えた『アクセスキーID』と『シークレットアクセスキー』を入力し、使用しているリージョンを選択して[OK]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/f2557f94-bc08-2183-47e8-c0f283c0aced.png)


# すると...？
自動でこんな図が出来ました！
主に左側がデフォルトVPCで、他が自分で作成したリソースです。
サービスアイコンの他にリソース名も一緒に表示されています。素晴らしい！
AzureやGCPでも出来そうです。是非お試しあれ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/a3fb7ea3-3a12-40a7-41da-d5a431d5b1f9.png)
Python curses でマウスのホイールの判定を取得する方法

## 環境
- Mint 19.10
- Python 3.7.5

## はじめに
curses にマウスのホイール判定が用意されていなかったので自作した。

これを読む前に前提となっている[この記事](https://qiita.com/t4t5u0/items/bd5270d0a7b3def35a03)を読んでほしい。

## 症状
ホイール判定をとれない

## 原因
curses には、マウスのクリック判定などが用意されているが不十分で、ホイール判定。特に下にスクロールするときの判定が用意されていない。

## 解決策
判定部分のコメントは日本語入力の記事を参照。擬似コードです。windowオブジェクトをきちんと宣言していません

```python
import curses

window = curses.stdscr()
key = window.getch()

text_pool = [key]
if 0x00 <= key <= 0x7f:
     pass
elif 0x80 <= key <= 0xbf:
     print(key)
     exit(1)
elif 0xc0 <= key <= 0xdf:
     text_pool.append(self.window.getch())
     a, b = text_pool
     tmp = map(lambda x: bin(x)[2:], [0b00011111 & a, 0b00111111 & b])
     tmp = ''.join(item.zfill(6) for item in tmp)
     key = int(tmp,2)
elif 0xe0 <= key <= 0xef:
     for _ in range(2):
         text_pool.append(self.window.getch())
         a, b, c = text_pool
         tmp = map(lambda x: bin(x)[2:], [0b00001111 & a, 0b00111111 & b, 0b00111111 & c])
         tmp = ''.join([item.zfill(6) for item in tmp])
     key = int(tmp,2)
elif 0xf0 <= key <= 0xff:
     for _ in range(3):
         text_pool.append(self.window.getch())
         a, b, c ,d = text_pool
         tmp = map(lambda x: bin(x)[2:], [0b00000111 & a, 0b00111111 & b, 0b00111111 & c, 0b00111111 & d])
         tmp = ''.join([item.zfill(6) for item in tmp])
     key = int(tmp,2)
else:
    pass

# 実際の値
WHEEL_UP = 65536
WHEEL_DOWN = 2097152

if key == curses.KEY_MOUSE:
    # ここにマウスによって入力された整数が格納されている
    wheel = curses.getmouse()[4]
    if wheel == self.WHEEL_UP:
        wheel_up_process()
    elif wheel == self.WHEEL_DOWN:
        wheel_down_process()
else:
    print(chr(key)
```

## 参考
- https://docs.python.org/ja/3/library/curses.html#curses.getmouse
- https://qiita.com/t4t5u0/items/bd5270d0a7b3def35a03
Pythonの名前につく謎のアンダーバー

間違い等ありましたら、遠慮なくコメントください！

# はじめに

pythonにおいて、名前をつける際にアンダースコアを使う場合がある。様々な使い方があるので解説する。全てに共通することだが、アンダースコアはただの記号ではなくアンダースコアも含めたものが名前として扱われる。**名前**全般に当てはまるので変数、関数その他に当てはまる。

# `_single_leading_underscore`

**先頭にひとつ**

だけアンダースコアをつけた場合、`import *`とした場合に、インポートから除外される。これによって、モジュールの内部でしか使わず、モジュールを利用する人に使ってほしくないものを隠すことができる。ただし、明示的にimportされるとimportされてしまう。

# `single_trailing_underscore_ `

**後ろにひとつ**

だけつけた場合、特に機能は持たない。しかし、Pythonの予約語と同じ名前を使いたい場合に使用される。

# `__double_leading_underscore`

主にクラス内において使用される。

**前に２つ**

つけると、クラスの外から呼び出すときは、別名でしか呼び出せなくなる。もちろん別名を使えば呼び出せる。先頭にひとつだけつけるよりはより強力に隠すことができる。

# `__double_leading_and_trailing_underscore__`

**前後に２つ**

ついているとき、Pythonにとって特別な機能を持つことを表している。自分で勝手に作ってはいけないらしい。

# 参考にしたサイト

[PEP 8 -- Style Guide for Python Code | Python.org](https://www.python.org/dev/peps/pep-0008/)
【今日のアブストラクト】End-To-End Memory Networks【論文 DeepL 翻訳】

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

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

翻訳元
[End-To-End Memory Networks](https://arxiv.org/abs/1503.08895)

# Abstract

### 訳文

おそらく大規模な外部記憶上のリカレントアテンションモデルを持つニューラルネットワークを導入する. このアーキテクチャは Memory Network (Weston et al., 2015) の一形態であるが, その仕事のモデルとは異なり, エンドツーエンドで訓練されるため, 訓練中の教師が大幅に少なく, 現実的な設定でより一般的に適用可能である. また，RNNsearch を，出力シンボルごとに複数の計算ステップ (ホップ) が実行される場合への拡張と見ることもできる．このモデルの柔軟性により, (合成的な) 質問応答や言語モデリングのような多様なタスクに適用することができる. 前者については, 我々のアプローチはメモリネットワークと競合するが, より少ない教師である. 後者については, Penn TreeBank と Text8 のデータセットにおいて, 我々のアプローチは RNN や LSTM に匹敵する性能を示している. どちらの場合も, 複数の計算ホップという重要な概念が結果を向上させることを示す.


### 原文

We introduce a neural network with a recurrent attention model over a possibly large external memory. The architecture is a form of Memory Network (Weston et al., 2015) but unlike the model in that work, it is trained end-to-end, and hence requires significantly less supervision during training, making it more generally applicable in realistic settings. It can also be seen as an extension of RNNsearch to the case where multiple computational steps (hops) are performed per output symbol. The flexibility of the model allows us to apply it to tasks as diverse as (synthetic) question answering and to language modeling. For the former our approach is competitive with Memory Networks, but with less supervision. For the latter, on the Penn TreeBank and Text8 datasets our approach demonstrates comparable performance to RNNs and LSTMs. In both cases we show that the key concept of multiple computational hops yields improved results.
Python curses で日本語を入力する方法

## 環境
- Mint 19.10
- Python 3.7.5

## はじめに
cursesのgetch() を使った場合にUTF-8でエンコードしたときに日本語(マルチバイト文字)がうまく受け取れなかったので、処理部分を作った。

## 症状
例えば 'あ' と打った場合には、0xe3 0x81 0x82 の3バイトに分けて、3回分入力されてしまう。しかし、これでは都合が悪い。(本当にほしいのは0x3042)


## 原因
getch() は1バイトずつ入力を見るので、UTF-8では3バイト分ある日本語などを正しく受け取れない。ということで、UTF-8のエンコーダを自作してやる。

## 解決策

先頭バイトを見ると、その文字列が何バイトか確定するから、以下のように条件分岐させる。
※擬似コードです。stdscrの部分などは省いています。windowオブジェクトを適宜宣言してください

```python
import curses

window = curses.stdscr()
key = window.getch()

# マルチバイト文字の加工
# 日本語だと3バイトだからプールする必要がある。先頭バイトを見て
# 残りのバイスと数が確定するからその処理を行う。
text_pool = [key]
if 0x00 <= key <= 0x7f:
     # 1B だから何もしなくていい
     # ascii 互換領域
     pass
elif 0x80 <= key <= 0xbf:
     # ここは2文字目以降のはずだから入ってきたらおかしい
     print(key)
     exit(1)
elif 0xc0 <= key <= 0xdf:
     # 2B ウムラウト付き文字とか
     text_pool.append(self.window.getch())
     # text_pool => [0dAAA, 0dBBB]
     # 110a aabb 10bb bbbb <= これが text_poolの中身(10進にしたもの)
     # 0b00000aaa bbbbbbbb を取り出してchar c = (char) (data[i] & 0xff);
     # 10進数にしてkeyに代入
     a, b = text_pool
     tmp = map(lambda x: bin(x)[2:], [0b00011111 & a, 0b00111111 & b])
     tmp = ''.join(item.zfill(6) for item in tmp)
     key = int(tmp,2)
elif 0xe0 <= key <= 0xef:
     # 3B 日本語はここ
     for _ in range(2):
         text_pool.append(self.window.getch())
         a, b, c = text_pool
         # 0b 1110xxxx 10xxyyyy 10yyyyyy
         # 0d a        b        c
         tmp = map(lambda x: bin(x)[2:], [0b00001111 & a, 0b00111111 & b, 0b00111111 & c])
         tmp = ''.join([item.zfill(6) for item in tmp])
         key = int(tmp,2)
elif 0xf0 <= key <= 0xff:
# 4B 見たことないけどバグ取り
     for _ in range(3):
         text_pool.append(self.window.getch())
         a, b, c ,d = text_pool
         # 11110xxx 10xxyyyy 10yyyyzz 10zzzzzz
         tmp = map(lambda x: bin(x)[2:], [0b00000111 & a, 0b00111111 & b, 0b00111111 & c, 0b00111111 & d])
         tmp = ''.join([item.zfill(6) for item in tmp])
         key = int(tmp,2)
else:
    #特殊キー
    pass


print(chr(key))
```
## 関連
マウスホイールの判定について
https://qiita.com/t4t5u0/items/ae6d25e05b7f7094330e

## 参考

https://seiai.ed.jp/sys/text/cs/mcodes/ucodeutf8.html
TypeORMでER_NOT_SUPPORTED_AUTH_MODEに対処する

TypeORMを使ってていきなりエラーが出たので対処してみました

# エラー

```
code: 'ER_NOT_SUPPORTED_AUTH_MODE',
errno: 1251,
sqlMessage:
   'Client does not support authentication protocol requested by server; consider upgrading MySQL client',
```

# 対処方法

mysqlのuserを作るときに、パスワードを`mysql_native_password`で設定する

ダメな例:

```
> CREATE USER 'foouser'@'localhost' IDENTIFIED BY 'foopassword';
```

okな例:

```
> CREATE USER 'foouser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'foopassword';
```

`IDENTIFIED BY` ではなく `IDENTIFIED WITH mysql_native_password BY`と書いて「`mysql_native_password`を使うよ」と指定します

もしすでに`CREATE USER`していた場合は、以下のクエリでuserの設定を変更します

```
> ALTER USER 'foouser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'foopassword';
> FLUSH PRIVILEGES;
```

を実行する

# 解説

デフォルトのパスワード設定だとなぜかダメで、`mysql_native_password`っていうauth_pluginを使う必要があるようです

ログインは、デフォルトのパスワードを設定したユーザと同じように、

```
$ mysql -u foouser -p
Enter Password:
```

でできます

`FLUSH PRIVILEGES` は、mysqlのサーバを再起動せずにユーザの設定を更新できる命令
この場合は、`mysql_native_password`を追加したという更新を反映させるために実行する

# エラーが直らない場合

- `ormconfig.json`の設定を確認する
- mysqlの走ってるPORTを確認する
- DBが存在するか確認する i.e. `SHOW DATABASES;`を実行

# 参考

https://github.com/typeorm/typeorm/issues/2093
https://dev.mysql.com/doc/refman/8.0/en/create-user.html
https://linuxize.com/post/how-to-create-mysql-user-accounts-and-grant-privileges/
デュアルスクリーンのスクリーンショットをドラッグアンドドロップで切り抜く

# 課題
デュアルスクリーンにしたところ、Windowsデフォルトのスクリーンショットで両方の画面が1枚の画像に写り込んでしまう。
片方の画面だけの画像がほしい。

# 環境
- Windows 10
- 画面は HD縦置き と HD横置き が左右に並んでいる 

# 解決策
- python + OpenCV で実装
    - OpenCVは日本語パス非対応なのでnumpyを経由する
- batに画像ファイルをドラッグアンドドロップで実行できるようにする
    - (毎度コマンドを打つのは不便なので)

#実装

``` python:screenshot-cropper.py
# -*- coding:utf8 -*-
import sys
import os
import cv2
import numpy as np

def main():
    if not (len(sys.argv) == 2):
        return
    img_path = sys.argv[1]
    if not os.path.exists(img_path):
        return
    img_array = np.fromfile(img_path, dtype=np.uint8)
    img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
    img_cropped = img[0:1080, 1080:3000]
    root, ext = os.path.splitext(img_path)
    img_cropped_path = root + '_cropped' + ext
    result, img_cropped_array = cv2.imencode(ext, img_cropped)
    img_cropped_array.tofile(img_cropped_path)

if __name__ == '__main__':
    main()
```
``` bat:screenshot-cropper.bat
python "C:\path\to\screenshot-cropper.py" %1
```
※ `path\to\` は実際のパスにする
Wordpressから特定の記事以外を全て削除

# はじめに
Wordpressで特定の記事以外を消したい時のTipsを載せておきます。
記事を2000件持っていて、その中で特定の100件だけ残して、他は全部消したい、みたいな場合を想定します。リライト記事だけ残すような場合に使えると思います。

実行環境 PHP:7.3 / MySQL:5.6 / Wordpress:5.4
※DBを変更する際は、元に戻せるように必ずDBやインスタンスのバックアップを取りましょう。

# 削除手順
## 不要記事の削除
1. Workbenchなどのデータベース管理ツールをインストールし、DBへアクセス
2. タイムアウト設定の変更
MySQLWorkbench > Preference > SQLEditorから、
 DBMS connection keep-alive interval (in seconds)
 DBMS connection read timeout interval (in seconds)
 DBMS connection timeout interval (in seconds)
をそれぞれ9999に変更して再起動します。デフォルト値ではタイムアウトしてしまうので・・・。

3. 下記SQLを実行

```sql
DELETE FROM [DB名].wp_posts
WHERE post_type = "post"
AND post_name != "777" AND post_parent != "777"
AND post_name != "1111" AND post_parent != "1111"
AND post_name != "1234" AND post_parent != "1234"
: (以下略。残したいIDを順に並べる)
```
通常の記事だけでなく、固定ページもこのwp_postsにありますので、残したい場合は忘れないように指定しましょう。
これだけでTOPからは消えて表示されなくなります。内部的には色々残っていますが、面倒な人はここで終わりで構いません。
私は不要パーツを最後まで削除しましたが、消したからといってページスピードが速くなるというわけでもありませんでした（速くなることを期待していたのですが・・・）。

## 不要になった記事パーツの削除
記事を削除してもカスタムフィールドやサムネイル等のパーツ、カテゴリ・タグの設定は残っています。
まずはカスタムフィールドやサムネイル等のパーツから削除します。

1.wp_postsのコピー

```sql
CREATE TABLE [DB名].wp_posts_copy (SELECT * FROM [DB名].wp_posts);
```

2.不要記事パーツの削除 (wp_posts)

```sql
DELETE FROM [DB名].wp_posts
WHERE post_parent!=0 AND post_parent not in(SELECT ID FROM [DB名].wp_posts_copy);
```

3.コピーしたテーブルの削除

```sql
DROP TABLE [DB名].wp_posts_copy;
```

4.不要記事パーツの削除 (wp_postmeta)

```sql
DELETE FROM [DB名].wp_postmeta
WHERE post_id NOT IN(SELECT ID FROM [DB名].wp_posts);
```

1〜3で何故こんな面倒なことをしているかというと、MariaDBのバージョンが古いため、DELETE文の副問い合わせで同じテーブルを参照することができなかったためです。最新版では副問い合わせできるようなのでその場合はwp_postsをそのまま指定でOKです。

## 不要になったカテゴリ等の削除
続いて、カテゴリ・タグを削除します。

```sql
-- カテゴリ/タグと記事の紐付けの削除
DELETE FROM [DB名].wp_term_relationships
WHERE object_id NOT IN (SELECT ID FROM [DB名].wp_posts);

-- 記事との紐付けがなくなったカテゴリ/タグの削除
DELETE FROM [DB名].wp_term_taxonomy
WHERE term_taxonomy_id NOT IN (SELECT term_taxonomy_id FROM [DB名].wp_term_relationships);

-- 念の為,カウントが0(使用されていない)カテゴリ/タグの削除
DELETE FROM [DB名].wp_term_taxonomy
WHERE count = 0;

-- カテゴリ/タグの設定の削除
DELETE FROM [DB名].wp_terms
WHERE term_id NOT IN (SELECT term_id FROM [DB名].wp_term_taxonomy);
```

こちらで削除完了です。
間違いがあればご指摘ください。
Amazon Linux 2  on WorkSpaces on Mac with USキーボードでの日本語⇔英語入力切り替えレシピ

ニッチです。

USキーボードの日本語⇔英語入力切り替えを、
Amazon Linux 2 on WorkSpacesではctrl + spaceで、
WorkSpacesのクライアントがあるMacではJISキーボードみたいにcommandの空打ちで行うなうようにするには、

## Amazon Linux 2 on WorkSpaces
1. mozcをインストール 参考：[GitHub - albuild/mozc: Mozc for Amazon Linux 2](https://github.com/albuild/mozc)
1. キーボードの設定からレイアウトをUSのみに
1. IBusの設定
  1. 次の入力メソッドのキーボードショートカットを ctrl + spaceに
  1. 入力メソッドに日本語Mozc、英語 - 英語(US)を追加
1. mozcのレイアウトにUSに 参考：[Mozc でキーボードの配列が日本語にならないのを解決する - Qiita ](https://qiita.com/arai-wa/items/3123ecb350097f79c6ef)

    reboot忘れずに

## Mac
1. システム環境設定/ショートカット /入力ソースのショートカットをオフに

    これオフにしないと、WorkSpacesにctrl + spaceが届かない。
1. Karabiner-Elementsをインストール
  1. Complex modifications/Rulesに「コマンドキーを単体で押したときに、英数・かなキーを送信する。（左コマンドキーは英数、右コマンドキーはかな） (rev 3)」を追加

### Q. WorkSpacesでもcommand空打ちで切り替えたい

A. むりでした。
Macの左commandを空打ちがkeycode49(zenkaku_hankaku)になり、キーボードのレイアウトがUSのWorkSpacesでは「`」と認識されてしまうんです。
右commandは WorkSpacesだとkeycode99(hiragana)になり、何も起こらず。。

---
以上っす。
PythonとDartの命名規則比較まとめ

PythonとDartで違うところは太文字にしました。

| 対象           | Python                         | Dart                           |
| -------------- | ------------------------------ | ------------------------------ |
| クラス         | UpperCamelCase                 | UpperCamelCase                 |
| **パッケージ** | **lowercase**                  | **lowercase_with_underscores** |
| モジュール     | lowercase_with_underscores     | lowercase_with_underscores     |
| **変数**       | **lowercase_with_underscores** | **lowerCamelCase**             |
| **引数**       | **lowercase_with_underscores** | **lowerCamelCase**             |
| **関数**       | **lowercase_with_underscores** | **lowerCamelCase**             |
| **定数**       | **UPPERCASE_WITH_UNDERSCORES** | **lowerCamelCase**          |

# 参考
[PEP 8 -- Style Guide for Python Code | Python.org](https://www.python.org/dev/peps/pep-0008/#naming-conventions)
[Effective Dart: Style | Dart](https://dart.dev/guides/language/effective-dart/style)
VirtualBoxで画面を最大化する方法、クリップボードを共有する方法


この記事では、

- VirtualBoxの中の画面を最大化する方法
- ホストOSとゲストOSでクリップボードを共有する方法について説明します。


画面の最大化については、初期の状態では仮想化のウィンドウ自体を最大化しても、中の画面は大きくなりません。

そのままサイズで、周囲が黒く囲まれ、表示されるべきはずの画面が一部見切れているような状態になります。

これを通常の画面と同じように、スクリーン全体で表示できるように設定します。

また同様に初期状態では、ホストOSとゲストOSでクリップボードが共有されていません。

どういうことかというと、例えばホストOSでコピーをしてゲストOSへ貼り付けようとしても、クリップボードが共有されていないので、貼り付けできません。

ゲストOSからホストOSへのコピペもしかり。

以上のことに対処するため設定していきます。

# 環境

- MacOS 10.15.3 catalina
- VirtualBox 6.0.18
- CentOS8

# VBoxGuestAdditionsのダウンロード

まず始めに、[ここ](https://w0.dk/~chlor/vboxguestadditions/)へアクセスしVBoxGuestAdditions
をダウンロードします。


![手順1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/6592f2af-5944-6f74-15fe-a704f6bf3d91.png)


# VBoxGuestAdditionsのインストール

続いて、該当の仮想マシンを起動し、「端末」を起動します。

そして以下のコマンドを順次実行します。

```
$sudo yum update
```
パスワードを求められるので、入力します。(表示はされませんが入力はされています)

場合にもよると思いますが、結構数が多いのでそれなりに時間がかかると思われます。

また、しばらくすると確認を求められるのでyを押します。

同様に、次のコマンドを実行します。

```
$sudo yum groupinstall "Development Tools”
```

これもパスワードを入力し、確認が求められたらyを押します。

最後に次のコマンドを実行します。

```
$sudo yum install kernel-devel elfutils-libelf-devel
```

ここは確認しか求められないのでyを押します。

続いて、先ほどダウンロードしたVBoxGuestAdditionsをインストールします。

「Insert GuestAdditions CD images...」を選択します。

![手順2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/1979f814-34b6-d551-19da-161b882a807f.png)

そうすると、仮想マシン上に次のような画面が表示されます。これは「実行」を選択します。

![手順3のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/86704e92-43ab-15d2-bb9f-973f3b0a2db4.png)

ログインしているユーザーのパスワードを入力します。

![手順4のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/95f9334a-039b-c79a-f060-1109eddba730.png)

そうすると、自動で処理が始まり、最終的には以下のような画面になります。

![手順5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/2174bcac-5416-ae1d-39f4-89bbb66e2e51.png)

Returnを押します。

画面を最大化するだけであればこれで完了ですが、クリップボードの共有にはもう少し作業をします。

一旦仮想マシンを終了します。

# クリップボードの共有の設定

VirtualBoxの起動画面で、「設定」をクリックします。

![手順6のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/02645a7d-20b7-5bf6-42bb-4e7970943e11.png)

「一般」→「高度」と表示し、「クリップボードの共有」と「ドラッグ&ドロップ」を「双方向」しておきます。

設定したら「OK」を押して画面を閉じます。

![手順7のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289786/ace1bbd3-3feb-33d8-0071-49efed78dec9.png)

これで設定は以上になるので、あとは起動して実際に確認すればできるようになっているはずです。


# 参考にした情報

- [【VirtualBox, Ubuntu18.04】仮想マシンにコピペできない(Qiita)](https://qiita.com/LemonLeaf/items/ac12404e277ff9bb3a65)
- [6.1.4 is the latest version of VBoxGuestAdditions](https://w0.dk/~chlor/vboxguestadditions/)
- [VirtualBoxにCentOS8.0をインストールする](https://yauichi.info/howto-install-centos/)
リバースエンジニアリングとは

リバースエンジニアリングについて知りたくなったので用語を少しまとめてみました。

リバースエンジニアリングとは、機械語で書かれている実行ファイル (exeなど)
を人間が読める言語に変換すること。

#逆アセンブル
機械語→アセンブリ言語
に変換すること。
その変換を<b>アセンブラ</b>が行うと逆アセンブル
#逆コンパイル
逆アセンブルと操作は同じだが、
変換を<b>コンパイラ</b>が行うと逆コンパイル。

逆アセンブルのほうが精度は高い

#デコンパイル
先述の逆アセンブル、コンパイルとは異なって
機械語→アセンブリ言語以外の上級言語
に変換することをデコンパイルという。
※デコンパイルするツールをデコンパイラという。
#難読化
会社をかけて制作したソフトウェアがリバースエンジニアリングによって機能を模倣したものを作られたり、改ざんされると大きな不利益となるためコンパイルする前のソースコードをツールを使って読みにくくすることで解読しにくくすること。
具体的には、変数名、関数名を無意味で冗長な文字列に置換することなどがあげられる。

#リバースエンジニアリングを行うツール
<a href= "https://ghidra-sre.org/" >Ghidra</a>
NSAが無償で公開しているリバースエンジニアリングツール。デコンパイルなどをすることができる。
<a href= "http://www.ollydbg.de/" >OllyDbg</a>
有名な逆アセンブラ。

他にもいろいろあるようですが、あまり詳しくないのでわかりません。(すいません。。。)
JSでArray.forEach() をbreakしたくなったら代わりにfor ... of を使おう

掲題通り。

## forEachはbreakできない

```.js
[0,1,2,3].forEach((v, i) => {
  if(i === 2){
    return;
  }
  console.log(v)
})
// 0と 1 と 3, breakする手段なし
// ※forEachは言語仕様的には順序保証がない
```


## for ... ofはいいぞ（ES6)
ES6以降ならfor ofを使いましょう。 thx @rdlabo 

```.js
for(const v of [1,2,3]){
  if(v === 2){
    break;
  }
  console.log(v) // 1
}
// 1
// 順序保証がある、この方法ではindexが使えない
```

```.js
for(const [i, v] of [0,1,2,3].entries()){
  if(i == 2){ 
    break;
  }
  console.log(v)
}
// 0, 1
// Arr.entries() と使うとofでもindexとvalueが使える
// 順序保証もある。がentries()はちょっとパフォーマンスが悪いらしい。計測してないけど。
```


## ES5なら Array.some() が代用できる

ES5ならsomeが代用品として使えるけど微妙にsomeの目的に沿わないかも。


```.js
[0,1,2,3].some((v, i) => {
  if(i === 2){
    return true;
  }
  console.log(v)
}
// 0, 1
// Arr.someは本来test関数なので目的からそれてる
```

> arr.some(callback[, thisArg])

callbackの受け取る引数は、 `element`, `index`[optional], `array`[optional] の3つです。
someそのものの第二引数thisArgについては基本わすれてもいいかと。


### 参考にしました
- [for \.\.\. of 文でインデックス\(index\)の値を使う方法 \- Qiita](https://qiita.com/TakahiRoyte/items/dca532dd64bc782ad849)
- [JavaScriptのArray\.forEachをbreak、continue、returnさせたい](https://www.deep-rain.com/programming/javascript/778#some)
- [Array\.prototype\.some\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
React Nativeの事始め。TypeScript とReact Native Navigationの設定まで

# この記事を書いた動機
職場で使用している技術の勉強のため
自分でReact NativeとTypeScriptを使ってでアプリを作ってみようと思う。
React Native Navigation周りでちょっと手こずったので、記録用。

# 環境
 - macOS v10.15.4 
 - node.js v12.16.2
 - npm v6.14.4
 - react v16.11.0
 - react-native v0.62.2
 - react-native-navigation v6.4.0

# TypeScriptでReact Nativeを始める
Xcode、Android Studioなどの環境とReact Nativeの初期設定。
どんなふうにするかは、[こちら](https://reactnative.dev/docs/environment-setup)の**React Native CLI Quickstart**を参照。

**ただし！！**
TypeScriptで初めからやるなら
**Creating a new application**のところで
下記の通り`--template react-native-template-typescript`をつける。

```js
npx react-native init /*** 君の作りたいアプリ名を入れよう！ ***/ --template react-native-template-typescript
```

とりあえずここまで行けば、`npx react-native run-ios`をすればシミュレータが起動してアプリが立ち上がる。

# React Native Navigationの設定。
まずはreact-native-navigationをインストール

```js
npm install --save react-native-navigation
```

**で！ここで詰まった。**
React Native Navigationの[公式ドキュメント](https://wix.github.io/react-native-navigation/docs/before-you-start/)には、この後`react-native link react-native-navigation`を打てばiosとAndroidそれぞれのネイティブファイルに自動で変更が加わるはずなんですけど、下記のようなエラーが・・・。

```js
zsh: command not found: react-native
```

# 原因は単純だった。
そもそもReact Nativeの[公式ドキュメント](https://reactnative.dev/docs/environment-setup)通りに設定をしていくと`npx`コマンドを使って、react-nativeをグローバルにインストールせずに実行することになる。
`react-native link react-native-navigation`はグローバルインストールされた`react-native`が存在しないので、command not foundのエラーが起きる。

なので・・・。

```js
npx react-native link react-native-navigation
```
単純に`npx`をつければ実行でき、無事ネイティブファイルに変更が加わった。
Leetcode 30 天挑戰, Week 2 Day 5, Last Stone Weight, in Swift

資料結構及演算法： `Backtracking`

- 挑戰頁面 - <https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/529/week-2/3297/>
- 題目原頁面 - [1046. Last Stone Weight](https://leetcode.com/problems/last-stone-weight/)

## 事先排序

有看到要找最大兩個值，於是就先降冪排序了。

## Heap 好麻煩 XDDDDD

Swift 不像其他語言有 heapq (python) 可以用，實作 max heap 覺得浪費生命又覺得ㄎㄧㄤ，想要減少解題時間於是就決定用 backtracking 了。後續再來做整套 heap 看看。

## Backtracking

要 backtracking 的話就是要先訂下遞迴的結束條件。

- 結束條件 ① - 空陣列的話回傳 0
- 結束條件 ② - 只有一個元素的話回傳該元素

### Subroutine （子處理）的主要內容

取得第一大和第二大數的差值，如果不是零就找到對應的位置插入。

#### 找位置的嘗試

試過三個方法 ① 從最大那側開始找 ② 從最小那側開始找 ③ 用 binary tree 找。而由於通常差值都會偏小，很快就有辦法跳離尋找的 loop，所以後來挑 ② 定下來。

實際嘗試過後 runtime 的差別： ② (beats 100.00%) > ① (beats 48.61%) > ③ (beats 12.50%)

## Code

``` swift
class Solution {
    func lastStoneWeight(_ stones: [Int]) -> Int {
        var sortedStones = stones.sorted(by: >)
        return smash(&sortedStones)
    }

    func smash(_ stones: inout [Int]) -> Int {
        if stones.isEmpty { return 0 }
        if stones.count == 1 { return stones[0] }

        let first = stones.removeFirst()
        let second = stones.removeFirst()
        let difference = first - second

        if difference > 0 {
            var index = stones.count - 1
            while index >= 0  {
                if stones[index] >= difference {
                    break
                }
                index -= 1
            }
            stones.insert(difference, at: index + 1)
        }
        return smash(&stones)
    }
}
```

## 複雜度分析

如果有錯請指正 :rabbit:

n 為陣列長度。

- 時間複雜度： O(nlogn + n^2) → O(n^2)
  - 排序先用掉 O(nlogn)
  - 走訪過程用 O(n), 裡面包了找插入位置用 O(n) 。雖然不願意，但是應該是 O(n^2) 。
- 空間複雜度： O(n)
  - 排序後用掉 O(n)
  - 走訪過程至少可以算 3n (first, second, difference) ，簡化後是 O(n)

## 執行結果

``` text
Runtime: 0 ms (beats 100.00%)
Memory Usage: 21.4 MB
```

## 其他覺得有趣的解

- [@nalydadad](https://twitter.com/nalydadad) - <https://leetcode.com/problems/last-stone-weight/discuss/575493/Elegant-swift-solution>
【iVRy】2020年、PSVRをPCに接続してVRライブ配信をみたい

##リモートARは果たしてVRなのか
VR(魔術)とAR(科学)が交差するとき、物語は始まる

最近、コ〇ナの影響で軒並みイベントが中止されています。
これはもしかしてVRが救世主になるんじゃないか。
すでに文鎮と化したPSVRをPCに接続してみよう。

OculusとかVIVEとかは持ってないし、スマホでVRだとスマホ困るじゃん
でも、PSVRは持ってるよ
というVRライトユーザ層をターゲットにした記事を書いてみることにしました。

ちなみに筆者はポッと出のVR素人です。

本稿では何をしたいのかといいますと
PSVRをPCに接続してYouTubeの360°/180°VR映像を見る配信することをゴールにします。

## PSVRのPC接続方法とSteamでYouTubeを見る

まず、PCでVRをする場合は基本
[SteamVR (https://store.steampowered.com/app/250820/SteamVR)](https://store.steampowered.com/app/250820/SteamVR/)
というアプリでOculusとかVIVEでVRゲームをします。
Steamって何？からの人はググりましょう。
もちろん、PSVRはPC用ではないので、普通に接続してもSteamVRは出来ません。

そこで裏技でPCに接続する方法がありまして
[Trinus PSVR (https://www.trinusvirtualreality.com)](https://www.trinusvirtualreality.com/)
というソフトをPCにインストールして、プロキシ(？)みたいにしてやることで
PSVRをSteamVRに認識させる方法がありました。

時は流れ、2019年1月、Steamから [iVRy (アイボリー？)]
(https://store.steampowered.com/app/1005970/iVRy_Driver_for_SteamVR_PSVR_Lite_Edition)
(https://store.steampowered.com/app/1005970/iVRy_Driver_for_SteamVR_PSVR_Lite_Edition)
という次世代VRドライバが発表されました。
なんと標準でPSVRをSteamがサポートしています。
![iVRy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/0794a32d-2ce6-ef99-0ce8-490daf8a6c3a.png)
なので、これからPSVRをPCに接続してみようという人は
SteamVRとiVRyをインストールすれば普通にVRが出来るようになりました。

で、YouTubeのSteamアプリはこちら
[YouTube VR (https://store.steampowered.com/app/755770/YouTube_VR)]
(https://store.steampowered.com/app/755770/YouTube_VR)

１）PCにPSVRを繋ぐ（PS4に刺さってるHDMIとHMDのUSBをPCに刺す）
２）SteamVRとiVRyをインストールする
３）SteamのYouTubeアプリをインストール＆起動する
※視点がズレてくるのでHMDにあるボタンを押すと正面にしてくれます。
※スピーカーがPSVRになったりするので驚かずに直しましょう。

## VR配信とは何か

- **RICOH THETA Z1で4Kライブストリーミングをしよう**
 - https://theta360.com/ja/howto-livestreaming/

リコーのTHETAなどの360°/180°カメラでライブ映像を撮り、WebRTCサーバーで全半天球映像を
WEBに配信することになります。

古い文献をみると、先人達の軌跡がありました。

- **THETA SからOculus RiftへUSBライブストリーミング with Unity (Sphere編)**
 - http://hammmm.hatenablog.com/entry/2015/12/06/181603
- **Unity+ROSでRICOH THETA Sの全天球映像を遠隔視聴する**
 - https://qiita.com/goodclues/items/3d82f3e0126778754fcb
- **Unity+WebRTC+three.js+WebVRを使ってRICOH THETAの全天球画像を遠隔地のOculusでみる**
 - https://qiita.com/mechamogera/items/ae283c651ae93cf76310

そうこうしている内に、YouTubeが360°VR配信を標準で対応してくれました。（2017年頃）
![全天球.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/5e938f12-6390-7f50-06bb-63d663b8c368.png)
~~ニコ動はVRプラットホームではなくコンテンツに行ったんやで。~~

しかし全天球映像にはまだ問題がありました。
360°映像だと配信容量が莫大なのと、立体視映像ではないのでのっぺりでした。
そこでGoogleが新たな規格[VR180]を提唱しました。
これは前方180°を二眼カメラで撮影して立体視を実現するもので、
さっそくYouTubeも対応してくれました。（2018年頃）

- **新しい3D立体視・ステレオ180度VR動画規格「VR180」とは。**
 - https://jouer.co.jp/vr180toha-vr180camera/

なので、最新のVR配信といえばこのVR180のことになり、
実際の映像がこちらです。
VRで見ないと何が凄いのかは全く解らないので、是非VRでご覧ください。

- **【VR180】2019/12/12 アイドルカレッジ「MASQUERADE」リリースイベント ソフマップ公演**
 - https://www.youtube.com/watch?v=88XMNOJyszc&list=PLZ_E1LbEgtL0MlwdXPyA7Uslfbz8Y_JGJ

リアル映像はまだ解像度が厳しいですね。
そもそも録画であればMVの編集演出でVRすればいいんじゃないかという解がこちら。

- **【VR180】39人ライブ「Thank You!」【ミリシタ】**
 - https://www.youtube.com/watch?v=4fY6Lpp6guY

近すぎだろ。
これが最新テクノロジーの結晶か。

しかし、左右のカメラ映像を立体視合成しないといけないため
180°映像を満足なクオリティでライブ配信するのは難しいようです。
なので、一旦保存してVR180映像としてYouTubeにアップするのが良いと思います。

ライブ配信じゃないじゃん？
いえ、時間すらもバーチャルにしただけです。

VRはついにインターユニバースへ突入します。
iOS13で Navigation Bar のタイトルの色を変更する

# デベロッパー泣かせのダークモード
iOS13以降はダークモードに対応するようになりました。
それに合わせてデベロッパーもダークモードに対応することが推奨されています。
しかし、ダークモードの追加によって、アプリ内の文字色で今までと変化してしまう場所が出てきてしまいます。
その例がNavigation Barの文字部分等です。
StoryBoardで設定した色も無視されてしまいます。

【ダークモードオフ】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/1497bd21-d1ab-4f67-a9a9-6d699d35fb49.png)
全く同じアプリですが、左がiOS13.4で右がiOS12.4です。
文字色が黒くなってしまいます。（Segueの表示の仕方等も変わっています。）

【ダークモードオン】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/600e3827-d8b7-1e78-5056-1b539aad1ea1.png)
ダークモードをONにすることでやっとタイトルが白くなってくれました・・・

iOS13では自動的にダークモードに対応してくれるのですが、逆にそれが厄介なケースがあります。
それが今回のようにNavigationBarのタイトルを常に白色にしたい時です。

# 解決方法
英語記事を見つけましたが、日本語で解説しているサイトがないため解説していきます。
AppDelegate.swiftやViewControllerのviewDidLoad関数など、適当な場所以下のように記述します。(サンプルはviewDidLoadに記述した場合です。)


```swift:ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        if #available(iOS 13.0, *) {
            let coloredAppearance = UINavigationBarAppearance()
            coloredAppearance.configureWithOpaqueBackground()
            coloredAppearance.backgroundColor = UIColor(red: 0, green: 192/255, blue: 192/255, alpha: 1) // 背景のRGBカラーコードを10進数で入力
            coloredAppearance.titleTextAttributes = [.foregroundColor: UIColor.white] // タイトルの色を指定
            coloredAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white] // タイトルの色を指定
                   
            UINavigationBar.appearance().standardAppearance = coloredAppearance
            UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
        }   
    }

```

このようにすることでタイトルを常時指定した色にすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/8c7ab353-a0ea-c7ab-7f80-19ee1f5cb5e9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/78e545ac-b492-776a-c6dd-288e88a4f5ea.png)

# 参考
https://sarunw.com/posts/uinavigationbar-changes-in-ios13/
PHP7.4にアップデートしてlaravel7系もインストールする

# 概要
PHP7.4とlaravel7をインストールします。
時が経つのは非常に早く、Laravel6系で最新だなんて思っていたら、
7系がリリースされていました。
LTSは6系なので、商用利用などの場合は6系が良いです。
もうすぐ8系が出るかもしれないですが、
その時の要件はPHP7.3以上になりそうとのことで今回はPHP7.4とLaravel7(最新のやつ)を入れます。

参考：
　Laravelアップグレードガイド　https://laravel.com/docs/master/upgrade


# PHP7.4にする
Laravel7系でのPHPのバージョンはphp 7.25以上が必要です。
Home-brewは入っている前提で

```sh
brew search php@7
brew install php@7.4
```
ログが流れるので静観。
完了したらパスを通します。

```sh
echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile
echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
brew services start php
```
バージョンを確認します。

```sh
php -v
// 結果
PHP 7.4.4 (cli) (built: Mar 19 2020 20:12:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.4, Copyright (c), by Zend Technologies
```

# Laravel7のインストール

1,インストーラーを入れる

```sh
composer global require laravel/installer
```

2,Laravelを始める

```sh
versionは任意です。つけないと最新版になります。(2020/04/12時点で7.5.2でした。)
composer create-project laravel/laravel --prefer-dist {project_name} {version}
```

インストールされたLaravelのバージョンの確認は

```sh
php artisan --version
```
です。

起動はおなじみの

```
php artisan serve
```
です。

#Laravel7系について
特徴についてリリースノートから引用します。
詳細は下記をご覧ください。

>Laravel7は、Laravel6.xで行われた向上に加え、以降の変更で構成されています。Laravel Sanctumの導入、ルーティングスピードの向上、カスタムEloquentキャスト、Bladeコンポーネントタグ、Fluentな文字列操作、開発者に焦点を当てたHTTPクライアント、ファーストパーティCORSサポート、ルートモデル結合の制約の向上、スタブのカスタマイズ、ならびに多くのバグフィックスとユーザービリティの向上です

こちらにあるリリースノートが詳しいです。
https://readouble.com/laravel/7.x/ja/releases.html

どれも素晴らしいのでみてみてください。



# PHPとLaravelのトレンド感
余談ですがせっかくなのでPHPとLaravelの現在のトレンド感について調べてみました。
## PHP
w3tech（ https://w3techs.com/ ）でのサーバーサイドの言語の人気ランキングではPHPが最も多くなっています。
LaravelやWordPress,Symfonyなどで使われています。

<img width="619" alt="スクリーンショット 2020-04-13 0.07.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/d355b6d0-84c7-4bd5-38d8-4c7dc4cb88e8.png">


## Laravel
人気順を主要なフレームワークと比較してGoogleトレンドで調べてみました。
<img width="1297" alt="スクリーンショット 2020-04-12 23.55.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/35bc39cc-a614-cbde-0a00-64f1a5d37a08.png">

Laravelは常に人気を保ったフレームワークになっています。

WordPressとPHPフレームワークでgoogleトレンドを見てみました。
<img width="1302" alt="スクリーンショット 2020-04-13 0.24.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/479b5406-7c2b-c094-cb01-bdf7c7c62b71.png">

WordPressはダントツですが、
PHPフレームワークとしてはLaravelが一強といえそうです。

#まとめ
読んでいただきありがとうございました。
ご参考になりましたら幸いです。
Javascript then/catch/finally chainの動作の実験

then/catch/finally chainの動作の理解が曖昧なので実験

```javascript
var p = Promise.resolve(0);

p
.then((v)=>{
  console.log("then1:"+v);
  return Promise.reject(1);
})
.then((v)=>{
  console.log("then2:"+v);
  return Promise.resolve(2);
})
.catch(v=>{
  console.log("catch1:"+v);
  return Promise.reject(-1);
})
.then(v=>{
  console.log("then3:"+v);
  return Promise.resolve(3);
})
.catch(v=>{
  console.log("catch2:"+v);
  //return Promise.resolve(-2);
})
.then(v=>{
  console.log("then4:"+v);
  return Promise.resolve(4);
})
.finally(v=>{
    console.log("finally:"+v);
    return Promise.resolve(100);
})
.then((v)=>{
	console.log("then5:"+v);
})
.catch((v)=>{
	console.log("catch3:"+v);
})
```

いろいろresolve/rejectをいろいろ変えて[jsfiddle](https://jsfiddle.net/hbjpn/9b8j2ryk/14/) で実験してみる.

1. catchはその前にrejectしたPromiseがある場合にcatchまで飛んでくる. 間にあるthenは飛ばされる.
2. catchの前にrejectしたPromiseがない場合は、catchはスキップされその後のthenから実行される
3. catchがresolveを返すとそこで一旦リセットされ、その後のthenが実行される
4. catchが何も返さない場合も、その後のthenは"undefined"でresolveされた状態で実行される
5. finallyはどんな時にも実行される. 引数には何も入ってこない.
6. finallyの後にthen, catchを続けても良い
7. finallyがその後のthen,catchに与える動作は少し特殊である.  

- finally到達時にresolveである場合
 - rejectするとその後のcatchまで飛びreject値も通知される. 
 - resolveをするとその後のthenが実行されるがresolve値を更新することはできない. 
- finally到達時にrejectである場合
 - resolveしてもその後のthenはskipされcatchまで飛ぶ. 
 - rejectするとその後のcatchまで飛びreject値も通知される. 

つまり、finallyではrejectする場合のみチェーンに影響を与え、resolveは何も影響を与えない。
日本人の名前の一部を対義語に変換する

# はじめに

大学生時代、ひょんなことから友達の名前の一部を対義語にして呼んでみたことがありました。

* 西郷隆盛→東郷隆盛
* 小野妹子→大野妹子

何回か繰り返していると、ある友達のツボにハマってしまい、笑い過ぎて身動きが取れなくなってしまいました。その友達に久しぶりに喜んでもらいたい、あとはそれを自動化できたら（？）という思いがありプログラムで実装しました。

# 日本人の名前の一部を対義語に変換する

## データベース

[LinkData](http://ja.linkdata.org/home)より、[KeitarouNakayama](http://user.linkdata.org/user/KeitarouNakayama/work)さんが公開している“[漢字一文字の対義語](http://ja.linkdata.org/work/rdf1s3497i)”を利用させていただきました。380種の漢字(190対)でパブリックドメインです。

## 実装

関数を実装するコードは以下のようになりました。

```python
import random
import re
import requests

JSON_URL = "http://linkdata.org/api/1/rdf1s3497i/antonym_rdf.json"
LABEL = "http://www.w3.org/2000/01/rdf-schema#label"
WORD = "http://ja.dbpedia.org/page/漢字"
ANTONYM_WORD = "https://www.wikidata.org/wiki/Property:P461"

res = requests.get(JSON_URL)
data = res.json()

antonym_data = {}
for i in data:
  if i not in antonym_data:
      antonym_data[data[i][WORD][0]["value"]] = []
  antonym_data[data[i][WORD][0]["value"]].append(data[i][ANTONYM_WORD][0]["value"])

def be_antonyms_name(pure_name):
  antonym_name = ""
  for one_kanji in pure_name: 
    if one_kanji in antonym_data:
      antonym_name += random.choice(antonym_data[one_kanji])
    else :
      antonym_name += one_kanji
  return antonym_name
```

## 実行

実行してみましょう。

```python
names = ["織田信長", "坂本龍馬", "西郷隆盛", "源頼朝", "小野妹子"]
for name in names:
  print(be_antonyms_name(name))
```

```bash
織田信短
坂末龍猫
東郷隆衰
源頼夕
大野妹子
```

正しく（？）変換されていますね。


# おわりに

是非みなさんも使ってみてください！文章などにも応用できます！

# 追記

- 2020年04月16日に更新された[Python記事まとめ(毎日自動更新)](https://qiita.com/kamata1729/items/eaf1d7b945b3a61a4fdd)、[いいねが多い最近の記事](https://qiita.com/kamata1729/items/eaf1d7b945b3a61a4fdd#%E3%81%84%E3%81%84%E3%81%AD%E3%81%8C%E5%A4%9A%E3%81%84%E6%9C%80%E8%BF%91%E3%81%AE%E8%A8%98%E4%BA%8B)として紹介していただきました。

- 2020年04月16日に更新された[【Python】Qiita 週間いいね数ランキング【自動更新】](https://qiita.com/kou_pg_0131/items/9d7f2ffeafb36cf59a77#_reference-5d9730ca40a7bcf09062)、04月09日 ~ 04月16日を集計期間とした[ランキング内](https://qiita.com/kou_pg_0131/items/9d7f2ffeafb36cf59a77#22%E4%BD%8D-%E6%97%A5%E6%9C%AC%E4%BA%BA%E3%81%AE%E5%90%8D%E5%89%8D%E3%81%AE%E4%B8%80%E9%83%A8%E3%82%92%E5%AF%BE%E7%BE%A9%E8%AA%9E%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B)で、22位として紹介していただきました。
【第2回】pythonで某Authenticator的なツールを作ってみた

## 表示するユーザー情報をDB化してみた。
- 前回はユーザー情報をソースにそのまま書き込まないといけなかった。
- 初回実行時にgauth.dbってファイルがなければ作成する。
- INSERT INTO文でuser1〜3までをDBに入れてる。
- 実行すると実行した瞬間の認証番号を表示する。

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

import tkinter as tk
import pyotp
import sqlite3
import os

if(os.path.exists('gauth.db')):
    pass
else:
    # データベースに接続する
    conn = sqlite3.connect('gauth.db')
    c = conn.cursor()
    # テーブルの作成
    c.execute('''CREATE TABLE gauth(id integer primary key AUTOINCREMENT, name text, private_key text)''')
    # データの挿入
    c.execute("INSERT INTO gauth VALUES (1, 'user1', 'ZAQWSXCDERFVBGT')")
    c.execute("INSERT INTO gauth VALUES (2, 'user2', 'qwertgfdsazxcvb')")
    c.execute("INSERT INTO gauth VALUES (3, 'user3', 'vfrtgbnhyqweraa')")
    # 挿入した結果を保存（コミット）する
    conn.commit()
    # データベースへのアクセスが終わったら close する
    conn.close()
# tkinterでwindowの作成とタイトルを作る
# windowサイズの指定
root = tk.Tk()
root.title(u"g_authentication_tool")
root.geometry("300x200")
# データベースに接続する
conn = sqlite3.connect('gauth.db')
c = conn.cursor()
for a in c.execute("select * from gauth"):
    totp = pyotp.TOTP(a[2]) #鍵的な値
    totp.now()
    # 表示用ラベル
    Static1 = tk.Label(text=a[1])
    Static1.pack(side='left')

    Static2 = tk.Label(text=totp.now())
    Static2.pack(side='left')
    # 挿入した結果を保存（コミット）する
    conn.commit()
# データベースへのアクセスが終わったら close する
conn.close()
root.mainloop()

```
## 次回予定
- 新しいデータの登録部分の作成
- 時間経過とともに認証番号の変更されるようにする