OmniAICreator/Qiita-1.07M huggingface dataset:
メタプログラミングruby　3章 まとめ

##symbolは慣習で用いている
symbolは名前を呼びたい時の物、イメージとしては人間がプログラムを書くとき手打ちで名前をつける言語要素を呼ぶときに使う
symbolは名前が変わらないものに用いる場合が多い　hashのキー　メソッド名
## send
sendの引数としてメソッド名を入れることによって、privateメソッドだろうがなんでも呼び出せてしまう。
##ゴーストメソッド
普通はmethodがなかった場合にはmethod missingというメソッドが呼ばれて、それ用にメッセージが表示される。
このmethod missingというメソッドをclass内で定義することによって、定義されていないmethodが呼ばれた際に動的にメソッドを生成するなどの処理を行うことができる。
##動的メソッドと動的ディスパッチ

```ruby:sample.rb
class Computer
  def initialize(computer_id, data_source)
    @id = computer_id
    @data_source = data_source
    data_source.method.grep('/^get_(.*)_info$/){Computer.define_component $1}
  end

  def self.define_component(name)
    define_method(name) do
      info = @data_source.send "get_#{name}_info", @id
      price = @data_source.send "get_#{name}_price", @id
      result = "#{nane.capitalize}: #{info} ($#{price})", @id
      result
    end
  end
end
```
メタプログラミングruby 5章

注　classは高性能なmoduleなので、classにおいてできることはmoduleにも適用できる場合が多い
##classとmoduleの比較
classはインスタンスをもつ
moduleはメソッド群
##
メソッドを定義するとself(カレントクラス)のインスタンスメソッドになる
クラスの定義の中ではカレントクラスとカレントobject(self)は同じである
クラスへの参照を持っていれば、クラスはclass_evalで参照できる

##クラスインスタンス変数
インスタンス変数の定義する場所によって、そのインスタンス変数をもつclassが異なることに気をつけなくてはいけない
メソッドの中ではメソッドのレシーバがselfになる、よって、インスタンスメソッドの中ではそのインスタンスがselfに、classの定義の中ではclass自身がselfになる。(あらゆるクラスはclassクラスのインスタンス クラスの定義内ではselfはclassクラスのインスタンスである、そのクラス自身を参照する)
classクラスのsuperclassはmoduleでmoduleのsuperclassはobjectとなる。だが、objectはclassクラスのインスタンスである。
よってあらゆるクラスはclassクラスのインスタンスである。また、新しく生成されたclassのsuperclassはobjectだが、これもクラスはclassである。また、class自身も例外ではなく、classクラスはclassクラスのインスタンスである。
ただ、ここで注意しなくてはならないのは継承しているということとそのクラスのインスタンスであるということは違うということ。継承はメソッドの引き継ぎ、インスタンスは継承されてきたものによって作られたクラスを用いた物体。

```ruby:meta.rb
class Myclass
  @my_var = 1
end
```
クラス定義の中ではselfはクラス自身になるので、@my_varはクラスに属していることになる。
よって、クラスのインスタンス変数とクラスのオブジェクトのインスタンス変数は別物になることを注意しなくてはならない

```ruby:meta.rb
class Myclass
  @my_var = 1
  def self.read; @my_var; end
  def write; @my_var = 2; end
  def read; @my_var; end
end
obj = Myclass.new
obj.read #=> nil
obj.write
obj.read #=> 2
Myclass.read #=> 1
```
Myclassのインスタンスメソッドはwriteとreadで、objのメソッドでもある。

## 特異メソッド
rubyでは特定のobjectに対してメソッドを追加できる。
例えば、

```rb
a = User.find(3)
def a.black?
  true if self.name == "ウエハラ"
end
```
的な
これはclassメソッドも実は特異メソッドで、classクラスの特定のobjectに対してメソッドを追加していることになるから。
特異メソッドが出た場合、メソッドの継承チェーンに特異クラスが挟まれる。つまり、そのobjectは特異クラスのインスタンスになる。特異クラスのインスタンスは通常のclassを継承しているので、それまで通りに使うことができる。つまり、moduleを挟み込むのと同じイメージ。

##ダックタイピング
静的型付け言語ではそのobjectがTの型を持つのはそのTクラスに属しているからだと考える。
動的型付け言語ではそのobjectがDuckクラスに属しているかどうかは重要ではない、そのメソッドが反応するかどうかである。
rubyではインスタンスのクラスがどのような継承関係をもっていても、ある特定のメソッドに応答できさえすればレシーバーとして振る舞うような処理がかける。

##メソッドラッパー
メソッドの書き換えに3つの方法がある。
###　アラウンドエイリアス
```ruby:meta.rb
class String
  alias_method :real_length, :length

  def length
    real_length > 5 ? 'long' : 'short'
  end
end
"War and Peace".length # => "long"　①
"War and Peace".real_length # => 13　②
```
①の場合:まず、新しく定義されているlengthに入る。その中で、real_lengthが呼ばれ、aliasにしたがって、もともとのlengthが呼ばれ、13が返ってくる。13に対し評価を行い"long"という結果になる。
②の場合:real_lengthを呼ぶとaliasにしたがってlengthが返ってくる。
このようにlengthを再定義することが可能である。
他にもmodule内でsuperを使って再定義したメソッドを使うという手もある。

```ruby:meta.rb
module ExplicitString
  def length
    super > 5 ? 'long' : 'short'
  end
end

String.class_eval do
  prepend ExplicitString
end

"War and Peace".length # => "long"　
```
即時関数を使った時の「is not a function」や「is not defined」のメモ

即時関数など丸括弧で覆う場合はその前にセミコロンが必要。
セミコロンあまり使ってなくてはまってしまったのでメモ。

[Uncaught TypeError: (intermediate value)(…) is not a function](https://stackoverflow.com/questions/42036349/uncaught-typeerror-intermediate-value-is-not-a-function)
ここの115の回答にあるけども、

```javascript

window.Glog = function(msg) {
  console.log(msg);
}; // <--- Add this semicolon

(function(win) {
  // ...
})(window);
```

『ECMAScript仕様には、自動セミコロン挿入のための特別な規則がありますが、この場合、次の行で始まるカッコで囲まれた式は関数呼び出しの引数リストとして解釈できるため、セミコロンは自動的に挿入されません。』（自動翻訳）
これと同じことらしい

```javascript

window.Glog = function(msg) {
  console.log(msg);
}(function(win) {
  // ...
})(window);
```

つまり、'('前にセミコロンがないと'(...)'がその前にある文字の引数になってしまうらしい。
だから';(...)'だとか、単純に'(...)'の前にある式や文の末尾にセミコロンを付ければいいらしい。
Ubuntu環境でggsaveすると日本語が文字化けした

# 問題
Rのggplot2を使って作ったプロットを出力しようとすると、以下のようなエラーが出て日本語の部分が`...`に文字化けすることがある。

```r
> data %>% ggplot(aes(x=x, y=y)) + geom_bar(stat = "identity") +
  geom_text(label = text, check_overlap = T, angle=90) + theme_classic(base_size = 20)
> ggsave("./figures/correlation.pdf", family = "Japan1GothicBBB")
Saving 7 x 7 in image
50 件以上の警告がありました (最初の 50 個の警告を見るには warnings() を使って下さい) 
```
`warnings()`を実行してみると`postscript() デバイス中にフォントファミリ 'Japan1GothicBBB' は含まれていません`
とのことで、一見エラーを修正するにはフォントをインストールしなければいけないのかと思ってしまう。

# 解決法
しかしこの場合は、ggsave側でフォントを指定してやるだけでOK。

```r
ggsave("./figures/correlation.eps", family = "Japan1")
```

みなさんは僕のようにこの程度の問題に貴重な時間を無駄にすることがありませんように。
[Review] Google's Interview Instruction for Software Engineer

## Foreword
I have long been interested in working for Google and been wondering what kind of people could actually pass their interview..
So I have decided to do some research about their content of the interview and also their expectation for candidates.

## Google's Interview Process
1. CV Screening: Everyone struggling with this step.  
[Why can't my CV pass screening for Google and Facebook despite having Amazon in it?](https://www.quora.com/Why-cant-my-CV-pass-screening-for-Google-and-Facebook-despite-having-Amazon-in-it)
2. Phone/Hangout Screening: Usually takes 30 - 60 minutes with Potential Peer/Manager
3. On-site Interview: Meet **Four** Googlers for 35-40 minutes each

## Expectation on Candidates
1. General Cognitive Ability: To explain your answer for open-ended questions in a smart manner, e.g. solving a problem using specific algorithm.
2. Leadership: you should be able to talk how you communicate with team-members to improve the productivity and enhance the efficient decision-making.
3. Role-Relate Knowledge: you should be able to explain the bond between your career/experience and the position you applied.
4. Googleyness: You need to tell how you can motivate others to achieve something great and grow outside of the comfort zone.

## Tips
At the step of 2, especially for software engineers, they expect you to clarify the problem and explain your concept to fix the issue or fulfill the given task.
For example, as you know that you have to pass coding test while the interview, this is like a live coding test. So they tell you the task during the interview and ask to program the software to fulfill the task. Indeed, they list the steps to do this as below.

1. When you are give the Open ended-question, you have to clarify the specification and devise requirements.
2. Explain it in an algorithm.
3. Convert it to workable code, be sure to consider the edges cases and production-ready code.
4. Then you can optimise your code.

Throughout these steps, the interviewer will ask you to explain how you plan to approach the problem, actually this will be the work you do everyday. So no need to worry about it, the interview process is carefully designed from the viewpoint of the actual work!
【Chome拡張開発入門】Chrome拡張で特定のサイトを見れないようにする

# 概要
Chrome拡張を自作し、特定のサイトを見れなくする機能を作る。

はじめてのChrome拡張開発のため、高度な内容は期待しないように。JavaScriptの知識もほぼ無い。

# 動機
勉強をしようとPCにむかっても気がついたらYouTubeを見ているので、なんとかしたい。

すでに同様のChrome拡張も存在するが、セキュリティ的に不安なので、自作したい。

# 環境
* Ubuntu 17.10
* Chromium 66.0.3359.181（Official Build）Built on Ubuntu , running on Ubuntu 17.10 （64 ビット）

# ソースコード

```json:manifest.json
{
    "manifest_version": 2,
    "name": "blocksites",
    "version": "0.0.1",
    "content_scripts": [
            {
                    "matches": ["https://www.youtube.com/*"],
                    "js": ["jquery-3.3.1.min.js", "script.js"]
            }
    ]
}
```

```javascript:script.js
$(function() {                                      
             $('body').html("見ちゃだめ");          
});
```

# 設定

* 適当なディレクトリを作成し、上記の２つのファイルをそこに置く
* Chromiumで`chrome://extensions/`にアクセス
* 「パッケージ化されていない拡張機能を読み込む」を選択し、先程の作成したディレクトリを指定

# 課題
* YouTubeのページが数秒間表示される（ロードする順番によるものと思われる）
* Firefoxを開こうとしている自分がいる

# リンク
* https://qiita.com/k7a/items/26d7a22233ecdf48fed8
* https://developer.chrome.com/extensions/content_scripts
* https://developer.chrome.com/extensions/api_index
* https://developer.chrome.com/extensions
xsort  -bash: /usr/local/bin/xsort: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad interpreter: No such file or directory

# xsort HighSierra にアップデートで動作しなくなる

# Overview

mac OSX をHighSierra にアップデートしたら下記出力で使えなくなりました。

```
-bash: /usr/local/bin/xsort: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad interpreter: No such file or directory
```
（☝ ՞ਊ ՞）☝ わお！　なにコレーーーー

なんで下記参照

https://qiita.com/kooohei/items/d0d0a603dc3681c1ff13

下記実行

```bash
sudo gem update --system -n /usr/local/bin
sudo gem install -n /usr/local/bin xsort
```

これでFIX

```bash
->> xsort
Usage: xsort [-v] [<path>] [-o] 
These are common detect commands used in various situations:
xsort version: 1.2.0
option:
-v: display xsort version number
-o: output result
-r: Just extracting output.pbxproj will not write to pbxproj of Xcode project

Regars !

```

これで成功しますた。
Mattermost-preview ベースの N-gram 対応 Docker Image

## 改訂履歴

> 2018-10-06
> * config ディレクトリを元の /mm/mattermost/config に戻し、ボリュームとして明示。
> * 空の config ディレクトリをボリュームマウントした場合にも既定の config ファイルがコピーされて動作するように変更。
> * パスに /mm/mattermost/bin を追加。
>
> 2018-07-29
> * mattermost-preview 5.x 対応

## 作ってみた

Mattermost を日本語で利用するときに必ず課題となるのが日本語文書の部分検索。
その解決策としてパーサーに N-gram を使うことはよく知られているが、Mattermost-preview をベースに docker run コマンド一発で日本語対応の Mattermost 環境を構築できる Docker Image を作ってみた。

#### Docker Image  
<https://hub.docker.com/r/k1tajima/mattermost_ngram/>  

#### 参考記事  
[Mattermost(v2.1.0)の日本語メッセージ全文検索をMySQL 5.7の標準ngramパーサを使い暫定対応](https://qiita.com/terukizm/items/b477943b63c66ab7d454)

## 課題と対応策

Docker ユーザーなら、docker run コマンド一発で実行環境を構築したいと思うもの。だが、本家の Mattermost Docker Image を使って N-gram パーサー対応しようとすると、docker run でコンテナを実行してからシェルに接続して、mysql で SQL コマンドを実行といった手順を踏む必要がある。
（理由： My SQL が動作し、Mattermost DB 構築された後でないとインデックスを再構築できないため）

最初は、Dockerfile の改変だけで実現できるかと思ったが、ベースのイメージ内では Mattermost DB が構築されておらず、Matttermost の起動コマンド内で DB 構築しているため、ENTRYPOINT に指定してあるスクリプトも改変している。

## 改変点

* My SQL の文字コードを UTF-8 に変更
* Mattermost の起動を wget でポーリング待ちしてから、My SQL のインデックスを N-gram パーサーで再構築
* mattermost/config ディレクトリをボリュームとして登録し、空の config ディレクトリをマウントした場合は既定のコンフィグファイルをコピーして動作するように変更
* mattermost-data ボリュームの対象ディレクトリのパスを修正
* Mattermost/bin ディレクトリをパスに追加
ＶＴＬ＿ｏｎ＿ＦＰＧＡ[その６　ＶＴＬ＿ｏｎ＿ＦＰＧＡのシミュレーション]

#効能
　VTL_on_FPGAのハードの基本動作をお手軽にデバッグする事が出来ます。
　※多少誇大広告気味

#元ネタ
　下記サイトが非常に参考になりました。
  　[［Icarus Verilogコンパイラを使う］](http://cellspe.matrix.jp/zerofpga/icarus.html)
　　利点:クロック毎の各信号の挙動がまるわかりで、自分のおろかさを見つけられます。
　　欠点:目を皿のようにして信号を見つめる必要があります。
　テストベンチを書くのがキモだと思います。

#インストール
　が、元ネタはLinuxであり、Windows用のIcarus Verilogとgtkwaveのインストールが必要。
　インストール先は各自で異なると思うので「_run.bat」を編集して下さい。(\APP2\の部分)
  プログラムソースはこちらに上げています。
　　[［td4_sim］](https://github.com/hi631/VTL_on_FPGA/tree/master/td4_sim)

```
	@@echo off
	C:\app2\iverilog\bin\iverilog -o td4.o rs232c.v ps2_rx.v td4.v td4_tb.v
	C:\app2\iverilog\bin\vvp td4.o
	timeout 3
	C:\app2\iverilog\gtkwave\bin\gtkwave wave.vcd -a td4.gtkw
	del td4.o wave.vcd
```

#操作
　(1)「TEST.GM」に次のようなVTLプログラムを書きます。

```
	10 B=$30
	20 !=90
	30 B=B+1
	40 #=20
	90 <0=B ]
```

　(2)GAME86を起動し、「[[[」コマンドを発行。
　　「pram.hex」が作成されます。
　　※開始番地を0にするのを忘れないように。(R=$0000)

```
	G>>[[[
	[p0 [LO gm80\test.gm [p1 [LO gm80\gm80.gm #=1
	
	-PASS1-
	   10 0000 B= $
	   20 0009 !=
	   30 0011 B= B + 1(01)
	   40 001A #=
	   90 0022 <= B   ]=
	-PASS2-
	 0000 NOP: 0F
	 0001 LIA: DF 1F FF
	 0004 STS: 38
	 0005 LIA: D7 30    ; 10 B=$30
	 0007 STA: 83
	 0008 JSR: DE 00 13 ; 20 !=90
	 000B LDA: 43       ; 30 B=B+1
	 000C LIB: F7 01
	 000E ADD: 01
	 000F STA: 83
	 0010 JMP: FE 00 08 ; 40 #=20
	 0013 LDA: 43       ; 90 <0=B ]
	 0014 LIB: FF 00 00
	 0017 OUT: 3F
	 0018 RTS: C2
	 0019 RTS: C2
	
	Hex作成　クリップ作成
	SOURCE:44(0000-002C)
	OBJECT:26(C000-C019)0000-001A
	 WORK :42(7800-7857)
	G>>

```

　(3)「pram.hex」を「TD4_SIM」にコピー
  　「_run.bat」を起動。
　　エラーが無ければ、次のような画面が表示されます。
![Image5.jpg](https://qiita-image-store.s3.amazonaws.com/0/159764/8823428a-7d7e-a9f5-6455-94ac42c5ef66.jpeg)

## その他
　とりあえず動いているのレベルであり、状況によっては動かない可能性が有ります。
　上記記載のハード、ソフトは無保証であり、各自の責任においてご利用願います。
UNIXコマンド(入門編)


cdやpwd、mkdir cpなどよく使うものは普段から使うが、
「もっと便利な使い方あるやろ」ってことで一回まとめて
勉強してみました。

毎度おなじみドットインストールの学習メモです。
ドットインストールを元に、気になったことを調べて追記。学習用の個人メモです。
※進めていくうちに追記していきます。

レッスン内容はUNIXコマンド入門 [一般ユーザー編] (全24回)
https://dotinstall.com/lessons/basic_unix_v2

# サーバーOSとしてのUNIX

UNIXとはインターネットのサーバー構築で使われるOS。
それを元にして作られた互換OSの中ではBSDとLinuxが有名。

そんなLinux、これもオリジナルとDisribution版とあり、
広く使われているのがDistribution版。

そんなLinuxはさらに
Rea Hat系とDebian系とで分かれており、

Red Hat系だと
RHELとCentOSが著名。

Debia系では
Ubuntuが著名

# mkdir

```
mkdir hoge
cd hoge
mkdir app{1..40} //これでappフォルダを番号付きでめっちゃ量産できる
ls //フォルダを確認
```

## プロンプト
``` [vagrant@localhost ~]$  ```
 
※「促す」という意味で、以下全体で次の操作を促しています。
``` [vagrant@localhost ~]$ ```
 
※localhost
この単語は「このマシン」という意味で、ログインしているマシン名を表しています。
localhostという単語が表示されるときは自分自身という意味で、これが別のマシンだと
サーバー名に変わったりします。
例えばエックスサーバーなどだと
``` [hoge@sv1111 ~] $ ```
となります。

``` vagrant ```
-> これはログインしているユーザー名を指します。

``` @localhost ```
-> ユーザーがログインしているマシン名を指します。

``` ~ ```
-> これでホームディレクトリにいるよという意味で、自分がどのディレクトリにいるのかが表示されます。

``` $ ```
これはユーザーの権限を表しています。一般ユーザーの場合、$で表現されて
管理者ユーザーだと#で表現されます。


## システム全体を把握しよう

UNIXの標準ディレクトリ構成
入場すると以下ディレクトリにデフォルトで移動します。
ここからhomeのさらに上の一番上のディレクトリへ移動して、システムの全体像を見てみます。
/home/vagrant/

``` cd ../../ ``` 

で移動して

``` ls ```

と打ちます。
するとファイル一覧が表示されます。

大まか以下のようなイメージで構築されます。
・bin (バイナリファイル群)
・etc (アプリケーションの設定ファイルが入っている)
・home (ホームディレクトリが格納)
・sbin (システム管理用のコマンドが格納)
・usr (基本的にユーザーが操作するファイル群はここに入ってきます)
・var (システムのログファイルや頻繁に変わるファイルが入っている)
オフラインリアルタイムどう書く E25 の問題

@Nabetani さんが主催するオフラインでリアルタイムに「どう書く」をやるイベント( https://yhpg.doorkeeper.jp/events/75247 )で問題を出させてもらいました。

問題は「ビッグ7」という名前で、詳細は
https://mtsmfm.github.io/2018/07/07/doukaku-e25.html
です。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。
似たような問題をもっと解きたいという方は、Doorkeeper の コミュニティページ
https://yhpg.doorkeeper.jp/
に @Nabetani さんの過去問リンク集がありますので、そちらをご覧になると良いと思います。
dein.vim SSL connect error dein vim

# dein.vim SSL Error

# Overview

dein.vimでSSL connect error は発生しました。

```
[dein] /home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim
[dein] Maybe wrong username or repository.
[dein] Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...Cloning into '/home/tomyami/.cache/dein/repos/github.com/tomtom/tcomment_vim'...
[dein] fatal: unable to access 'https://github.com/tomtom/tcomment_vim.git/': SSL connect error
```
（☝ ՞ਊ ՞）☝ わお！　なにコレーーーー

SSL Errorと出力されております。

ふーん

```
>>- git --version
git version 2.2.0
```

新しいバージョン、

検索してみた。

下記参照

[Https で通信できなくなった](https://qiita.com/murai-taisuke/items/173b3cbbd697e630047d)

```
yum update -y nss curl libcurl
したらいけた。

```

とのこと

なのでやってみたら成功しました。
ＶＴＬ＿ｏｎ＿ＦＰＧＡ[その５　ＶＴＬ＿ｏｎ＿ＦＰＧＡの拡張ＩＯ]

#効能
　VTL_on_FPGAのの操作をスタンドアローン(パソコン無し)で実行できます
　　(1)PS2キーボード
　　(2)VGAキャラクター表示　80x25行x2色(256色から選択)
　　(3)VGAグラフィック表示　640x480x256色
　　(4)SDRAMアクセス 　　 　32MB
　　(5)プログラム格納　　　　64KB(EPCS)　※制御が大変だったが結構便利

#画面の操作
##1.テキスト表示
　(1)操作入出力表示
  　シリアルとパラに表示しています。(追加操作不要)
　(2)VDTのみに表示
　　IOの\$14番地に書き込むと表示されます。
　　　例　L=0,159 <\$14=\$30+(L&15) @=L+1　<-　NG(文字欠け)
　　※但し、改行中は入力を見ておらず、この方法では文字欠けが発生します。
　　シリアルと同時ならOKよ
　　　例　L=0,159 \$=\$30+(L&15) @=L+1  <- OK
　(3)VDTに位置指定で表示
　　IOの\$12番地に表示アドレス、\$13番地に表示データを書き込むと表示されます。
　　　例　W=0,10 @=W+1 P=1*80 L=0,79 <\$12=P+L <\$13=\$30 @=L+1
　　※但し、表示開始位置を0リセットするので、この後の一回目は変なスクロールが発生。
　　　また、スクロール中に表示すると文字欠けするので、この考慮が必要。
　(3)色指定
　　文字/背景色は２種類の何れかを選べます。
　　文字データ+\$000で色指定0、文字データ+\$100で色指定1となります。
　　文字色指定0は\$10、色指定1は\$11に\$xxyy(xx=背景色 yy=文字色)により指定します。
　　　例 <\$10=\$00FF <\$11=\$E000  L=0,159 \$=\$130+(L&15) @=L+1 <- 文字黒、背景赤
　　色データは8bitで「rrrgggbb」の並びとなっています。

##グラフィック表示
　\$15にX座標、\$16にY座標、\$17に色データを書き込むと表示されます。
　　例　10 Y=120,239 <\$16=Y  <- 画面に白い四角を表示
　　　　20 X=160,319 <\$15=X
　　　　30 <\$17=\$FF
　　 　40 @=X+1 @=Y+1
　※画面の左上に書いた覚えのない線が見えるが、なんだろう。

#動作概要
##PS2キーボード
　(1)スキャンコードの取得が「EP4CE6-Starter-Board-Docs」に記載されているで流用。
　　このロジックでは、キーを操作すると、acd_doneが一瞬ONする。
　(2)スキャンコードからアスキーコードへの変換を実装。
　　※VTLで使用する最低限の変換、なにか漏れているかもしれない。
　(3)VTLとの接続ロジックを記述、次の動作となる。
　　キー入力 -> acd_rdy(ON) -> キー読取 -> acd_req(ON) -> acd_rdy(OFF)
　(4)シリアル入力時に合わせて入力確認を行う事により、VTLから読み取る。

##VGAキャラクター表示
　(1)FPGAメモリに50MHzで駆動するテキストバッファを確保。
　(2)25MHzクロックのHI/LOで、VTL(W)/ディスプレイ(R)アクセスを切り替える。
　(3)画面表示に合わせてテキストバッファからディスプレイデータを読出し。
　(4)FPGAメモリに25MHzで駆動するCG(キャラクタージェネレーター)を確保。
　(5)ディスプレイデータでCGを選択し、キャラクターを表示。
　(6)VTLからのアクセスはフラグを立てて、アクセス可能なタイミングで書き込む。
　　VTLからのアクセスが遅いので、通常は問題なくアクセス可能。
　　但し、インターロックがないので、スクロール中にアクセスすると、文字欠け発生。
　(7)表示の為にメモリを4KB消費。使わない場合はTD4の主メモリを増やすが吉。

##VGAグラフィック表示
　(1)VGAのグラフィックバッファとしてSDRAMを使用する。
　(2)SDRAMは25MHzに2バイト毎のアクセスが可能な設定なので、VTL/VGA交互にアクセス。
　(3)VGAは12.5MHz毎に2byte読出し、25MHz毎に1dot(1byte)表示する。
　(4)グラフィック表示でSDRAMを307.2KB使用しているが残りは空き地、もったいない。

##SDRAM
　(1)SDRAMは、クロック150MHz、CL=3で駆動。
  (2)150MHzを6分周して、25MHz毎にR/Wを実施している。
  　※元ネタ(エミュレーター)は64MHzの8分周なので、タイミング的になにか誤っているかも。
    ※ライブラリを使用したほうが間違いないのだろうが、I/Fが複雑で良く判らない。
　(3)6分周のタイミングでras,cas,weを操作すると、最後に読出しデータが出てくる。
  (4)VDTが定期的にアクセスするので、リフレッシュはやっていない。

##プログラム格納
　(1)EPCSの最後のエリア(\$70000 - \$7FFFF)を使用。(FPGAでは使っていない模様)
　(2)追加書き込みを行い、最後まで行ったらフォーマットする。
　(3)書き換え回数は10万回と言われているので、フォーマットを10万回行える。
　(4)エリアは極めて小さいが、4KBのプログラムなら16本入る。
　※このボードではASMIが正常に動作しなかったので、ローレベルから制御している。
## その他
　とりあえず動いているのレベルであり、状況によっては動かない可能性が有ります。
　上記記載のハード、ソフトは無保証であり、各自の責任においてご利用願います。
error: field ‘ctx’ has incomplete type を解決する

# EVP_CIPHER_CTX incomplete type errorの解決法
## 対象
- Debian 9 stretch
- Ubuntu 18.04

## 原因
OpenSSLのバージョンアップ(1.0.2 -> 1.1)によるもの

## 対処法
`libssl-dev`を削除して`libssl1.0-dev`をインストールする

## 参考文献
[error: field 'ctx' has incomplete type EVP_CIPHER_CTX](https://stackoverflow.com/questions/47518843/error-field-ctx-has-incomplete-type-evp-cipher-ctx)
Curved UIの紹介とハマったこと

# Curved UIとは
uGUIのキャンバスをカーブさせられるアセット

Curved UI - VR Ready Solution To Bend / Warp Your Canvas! - アセットストア
https://www.assetstore.unity3d.com/jp/#!/content/53258

## 特徴

- Unityにフィーチャーされてる
    - Unityにチュートリアルがある
        - Unity - Worldspace UI with Curved UI
            - https://unity3d.com/jp/learn/tutorials/topics/vr/worldspace-ui-curved-ui
    - VRエッセンシャルパックにも入ってる
        - Unity - Up to $188 in Free Assets with Your Subscription
            - https://store.unity.com/ja/offer/unity-essentials-packs
    - →**導入を決めやすい**
- uGUIベース
    - Event Systemとかを書き換えてる
    - →**最強の互換性**
- VRサポート
    - Oculus
    - Vive
    - Google VR(cardboard or Daydream)
    - それぞれのコントローラーのインプットまでサポート

## できること

色々カーブさせられる

![0747912d-2948-9d6c-7f32-97f2b0386ca7.jpeg](https://qiita-image-store.s3.amazonaws.com/0/55365/3343b1b1-043d-e31a-29cb-9d6e67081de5.jpeg)


## できないこと

180度を超えるUIにした場合(全周を囲むUIとか)、インタラクションができない
→ uGUIの仕様上の問題らしい

# ハマったこと

## カーブの設定が反映されない

インスペクターで選択するまでカーブしない(実機でも同様)

Google VR SDKのバージョンの問題？

Google VR SDK 1.100.x系ではコンパイルエラー

→ Google VR SDK 1.70.1系で正常に動作
*(一応or laterって書いてあるのに…)*

## 動的に追加した要素がカーブしない

ドキュメントにFAQがあった

CurvedUI 2.3 Documentation - Google ドキュメント
https://docs.google.com/document/d/10hNcvOMissNbGgjyFyV1MS7HwkXXE6270A6Ul8h8pnQ/edit#

> # Elements I add to the canvas via code are not curved. What do?
>When you add elements to the curved canvas during runtime you have to add CurvedUIVertexEffect component to them manually. You can do it with the following line:

>`YourNewObject.AddComponent\<CurvedUIVertexEffect\>();`

> Make sure you add the component after you make the element a child of the canvas. You can also make CurvedUISettings component scan all its children and add necessary components by calling its AddEffectToChildren() function.

`CurvedUIVertexEffect`を追加する方法はうまくいかなかった。

`AddEffectToChildren()`したら動いた。

# その他

Unity 2017.1までのサポートって書いてあるが、Unity2017.2.xでも動作した

Unityのポップアップにしたがってマイグレーションすればok
Unityでインポートしたテクスチャの色味がおかしい

# 現象

![31a9e421-61a3-6ef4-c7cf-f85b63d34c59.png](https://qiita-image-store.s3.amazonaws.com/0/55365/d5a56837-3a0e-69ba-d1c8-4b904471bd5b.png)

左が本来の画像の色、右がUnity上での画像の色(少し紫がかって見える)

# 解決方法

Android向けのビルド設定になっていたので、Texture Import SettingのDefaultのFormatで色数の少ない形式になっていた(多分)。

<img width="469" alt="627805b1-01bd-74ef-2179-6075f8932f6f.png" src="https://qiita-image-store.s3.amazonaws.com/0/55365/53afabf7-25bf-7db8-ff53-da24a3b019c1.png">


Autoになっているところは、おそらくプラットフォーム毎にデフォルト値が設定されているような気がする。

<img width="477" alt="8b0ba176-7b19-a30c-f46e-efa2232ff9c0.png" src="https://qiita-image-store.s3.amazonaws.com/0/55365/78e2d971-8a01-f94e-9ba8-9ba1f8024a63.png">


プラットフォーム毎のOverride設定で色数の多いformatにしたら解決した。
任意多角形の断面二次モーメントを算出する

閉じた節点情報から断面二次モーメントを出力するプログラムを考えます。
これをもとに断面一次モーメント、断面積、断面係数を算出することも容易です。

# 定義式

**断面二次モーメント**は、

$$ I_z = \int_A y^2 dA \tag{1} $$

で、与えられます。断面内のあらゆる点について $y^2$を計算し、それの総和、ということですね。


# コードを書く

今回引数は頂点情報の配列で渡すことを前提とします。例えば下記。

<img src="https://qiita-image-store.s3.amazonaws.com/0/224124/9b11500e-1f53-95dd-06b8-29531855935d.png", width=300>

多角形なので、N番目の頂点と、N+1の頂点とそれらの垂線で構成される台形のメッシュで分割することができます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/224124/f226011d-86b2-d667-54f5-fd84f6fa422a.png", width="600">

上の図の場合は、青エリアは正数、赤エリアでは負数で返してやればOK。

台形の場合の式(1)は愚直に解けて、斜辺の一次関数を$y = ax + b$とすれば、

```math
I_z = \int_{x_i}^{x_{i+1}} \int_{y_i}^{y_{i+1}} y^2 dy dx 
    = \frac{1}{12a} \left\{ ( ax_{i+1} + b )^4 - ( ax_i + b)^4 \right\} \tag{2a}
```

ただし、$a=0$ （つまり長方形）のときは、

```math
I_z = \frac{1}{3} b^3 \left(x_{i+1} - x_i \right) \tag{2b}
```

となります。


## コード

(2a)と(2b)をそのまま式に起こしてあげれば良い。引数の`node`は、

```
node = [[x1, y1], [x2, y2], ...]
```

の形式を期待。でも、あまりうまくいっていないので`numpy`的な方法にした方がいいと思います。


```python
def moment_of_inertia_of_area(nodes):

    nodes = move_x_to_positive(nodes)     # 後述
    func = reformat_nodes_to_func(nodes)  # 後述

    ans = 0.0
    for f in func:
        x1, x2 = f[0], f[1]
        a, b = f[2][0], f[2][1]
        
        if a == 0:
            inte = (b ** 3) * (x2 - x1) / 3
        else:
            inte = ((a * x2 + b) ** 4 - (a * x1 + b) ** 4) / (12 * a)

        ans += inte

    return ans
```

途中で出てくる`move_x_to_positive(node)`は、xを0以上に移動するための関数。
`reformat_nodes_to_func`は、`[x1, x2, a, b]`の配列にして返す関数。この辺は引数の取り方にもよるので、適宜調整必要かと思います。

```python
def move_x_to_positive(nodes):
    min_x = min(list(map(lambda node: node[0], nodes)))
    nodes = list(map(lambda node: [node[0] - min_x, node[1]], nodes))
    return nodes

def reformat_nodes_to_func(nodes):
    func_list = [
        [nodes[i][0], nodes[i + 1][0],
            calc_slope_and_intercept(
                nodes[i][0], nodes[i][1], nodes[i + 1][0], nodes[i + 1][1])]
        for (i, x) in enumerate(nodes[:-1])
    ]
    return func_list

def calc_slope_and_intercept(xi, yi, xj, yj):
    try:
        slope = (yi - yj) / (xi - xj)
        y_intercept = yi - slope * xi
    except ZeroDivisionError:
        slope, y_intercept = 0, 0
    return slope, y_intercept
```

この辺汚いですな。2年くらい前のコードなので....

まあ、**動けばOK！！！！**

以上です。ライブラリなしで計算できるのはメリット。
TextMeshProで最小限のフォントアセットを作る

# はじめに
TextMeshProは軽量でリッチなテキスト表示ができるアセットですが、事前に独自の形式のフォントアセットを作成する必要があります。しかし、常用漢字などを全てアセットに含めると、フォントアセットのサイズがかなり大きくなってしまいます。(→メモリ容量の圧迫など)

しかし、状況によっては使用する文字列が全て明らかになっている場合があります。(ソシャゲなどサーバからコンテンツ配信を行わないようなアプリの場合)

# やり方

以下のページを活用しました。
http://kiteretsu-world.info/tool/reduce-character.shtml

重複した文字列を削除してくれるブラウザサービスです。
使用する文字列を全てぶち込んでボタンを押すと、重複がない文字列が返ってきます。

つまり、理論上最小サイズのフォントアセットを作成することができるのです。

よかったら参考にしてみてください。
姿勢推定メモ 

RGB画像から姿勢推定する技術の話

# OpenPose

https://qiita.com/nnn112358/items/a4490d85dac5827db53b

- 1番有名くらいらしい
- 画像から2Dスケルトンを検出可能
- 複数角度の結果を合わせれば理論上3Dスケルトンも検出可能
- 商用がだめっぽい
- ライセンスがある
https://flintbox.com/public/project/47343/

# DensePose

http://densepose.org/

- 3Dのメッシュ情報を推定可能
- OSSになった
- 配布されている学習モデルが非商用CC

# Human Mesh Recovery

https://akanazawa.github.io/hmr/

- 3Dのメッシュ情報を推定可能

# VNect

http://gvv.mpi-inf.mpg.de/projects/VNect/

- 3Dスケルトンを検出可能
- 学習済みモデルはメールしないともらえない
- tensorflowでやってる人もいるらしい
    - https://github.com/timctho/VNect-tensorflow
    - 学習済みモデルはこっちも個別で交渉

# Mask R-CNN2Go

https://research.fb.com/enabling-full-body-ar-with-mask-r-cnn2go/

- Facebookが作ってる
- **モバイルでも動く** (すごい)
- 公開されてない
ドキュメント共有ツールの検討メモ

#　観点

- 無料か、どのくらいお金かかるか
- マークダウン記法(MD)が使えるか
- 導入実績があるか
    - セキュリティとか的な懸念
- テンションが上がるか

# 候補

- Google Docs
    - 無料
    - 検索とか閲覧がしづらい
    - 外部の人とも共有しやすい
- esa
    - 1user 500円/月
    - MD使える
    - おしゃれ
- Githubのwiki
    - 無料
    - issueでタスク管理とかもすればGithub上だけで完結させられそうな雰囲気は良い
    - リポジトリが複数あるプロジェクトだとどこにまとめるのが適切なんだろうか
- Kibela
    - 5userまで無料
    - 以降1user 540円/月
    - MD使える
    - Wiki(しっかりめの文章)とブログ(カジュアルな文章)を使い分けられる
- コンフル
    - レガシーみがある(偏見)
- Crowi
    - 無料 (というかOSS)
    - MD使える
    - デプロイしないといけないのが個人的にだるい
- Dropbox Paper
    - Dropboxの容量内なら無料
    - MDかける
- Qiita:team
    - 規模ごとに金額が違う
        - https://teams.qiita.com/pricing/
    - Qiitaの機能が大体使える
        - もちろんMD使える

何か良さげなのがあれば教えてください〜
Pythonでエクセル操作（読み込み、列を指定して削除する、列と行を入れ替える、保存）

# はじめに
この記事は、Windows環境でJupyter Notebookを使って、PythonでExcelの読み込みと編集、保存をするための記事です。
この記事でやっていること。

- Pandasのインストール
- Excelファイル(.xlsx)の読み込み
- DataFrame(Excel)の行数の読み込み
- 読み込んだファイルの表示
- 列を指定して削除する
- 列と行を入れ替える

# 前準備
必要なライブラリのインストールをします。
JupyterNotebookを使っていれば、下記のように書けばインストールされます。

```python:ExcelData.py
! pip install pandas
! pip install xlrd
```

# Excelファイルの読み込み

```python:ExcelData.py
#同一ディレクトリに置いたData.xlsxを読み込み、dfとする
df = pd.read_excel('Data.xlsx', index=False, dytpe='object')

```
- pandasで取り込んだファイルはDataFrameオブジェクトとして取り込まれる

# 読み込んだ行数を取得
```python:ExcelData.py
filelen = len(df)
print(filelen,'行読み込みました')
```
- `len(df)`で行数が取得できます。

#不要な列を削除する
例えば、下記のようなテーブルを読み込ませていた場合

|日付    |天気 |気温|
|:------:|:--:|:-:|
|20180101|晴れ|10|
|20180102|雨|9|
|20180103|曇り|8|

```python:ExcelData.py

df=df.drop(columns='天気')
```
`df.drp`で列名を指定してあげると、削除される

|日付    |気温|
|:------:|:-:|
|20180101|10|
|20180102|9|
|20180103|8|

#列と行を入れ替える
先ほど天気を削除した`df`をそのまま使うと

|日付    |気温|
|:------:|:-:|
|20180101|10|
|20180102|9|
|20180103|8|

```python:ExcelData.py
df2=df.T
```
すごく簡単に入れ替える事ができる

|0   |1       |2       |3      |
|:--:|:------:|:------:|:------:|
|日付|20180101|20180102|20180103|
|気温|10      |9       |8       |



#Excelファイルを出力する
```python:ExcelData.py
#Excel書き込み
df.to_excel('ExportData.xlsx' , index=False)
```
- `index=False`はインデックスを出力しない


# ソースまとめ
```python:LoadExcel.py
#Excelファイルを読み込むためのPandasをインポート
import pandas as pd

#同一ディレクトリに置いたData.xlsxを読み込み、dfとする
df = pd.read_excel('Data.xlsx', index=False, dytpe='object')

#読み込んだ行数を表示
fileLen = len(df)
print(fileLen,"行読み込みました")

#読み込んだファイルを表示
display(df)

#天気列の削除
df=df.drop(columns='天気')
display(df)

#列と行を入れ替える
df=df.T
display(df)

#Excel書き込み
df.to_excel('ExportData.xlsx' , index=False)

```
Googleフォトの自撮りから約7,500枚の学習データを作る

# はじめに

GWに機械学習したくて自分の顔写真から学習データを作りました。
現在7,555枚あるので、ある程度何かに使えるような気がします。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">僕の学習用顔写真データ(約1,200枚)を無料公開します。改変、商用利用、配布等全て自由です。機械学習等に是非ご活用ください〜。<a href="https://t.co/V5zgNlZ6Sh">https://t.co/V5zgNlZ6Sh</a> <a href="https://t.co/wjsf0shDjQ">pic.twitter.com/wjsf0shDjQ</a></p>&mdash; Nakaji Kohki (@kohki_nakaji) <a href="https://twitter.com/kohki_nakaji/status/990879912453013504?ref_src=twsrc%5Etfw">2018年4月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

以下で公開中です。

LearningData_face - Google ドライブ
https://drive.google.com/drive/folders/1riyyDR5E59rvp6BFJK81CkguymsH-fmj


# やり方

1. GooglePhotoから自分のタグがついた画像一覧を表示してダウンロードする
 - 動画が含まれているとDLに時間がかかるから注意
 - 一度にDLできる項目は500件まで
2. このリポジトリのREADMEに従ってExtractコマンドを叩く(内部でOpenCV呼び出してるだけっぽい)
 -  deepfakes/faceswap: Non official project based on original /r/Deepfakes thread. Many thanks to him!
 -  https://github.com/deepfakes/faceswap
3. エラー画像を取り除く
 - 顔写真ではないもの
 - 自分以外の写真
 - 他の人が写り込んでいる写真
Jenkins + Doxygen Pluginでドキュメントの自動生成

# できたもの

Jenkins上から常に最新のソースコードドキュメントを見ることができる状態になった。

![safadsfa_.png](https://qiita-image-store.s3.amazonaws.com/0/55365/b94806c9-8ea9-46ac-d314-08d49e58c142.png)


# 導入について

## DoxyFileの用意

ローカルで設定の確認をしてからリモートにアップすると良い

生成
```$ doxygent -g [任意の名前]```

実行
```$ doxygent [任意の名前]```

以下のページが参考になった。
http://algo13.net/doxygen/doxyfile.html

## Jenkinsの設定

- JenkinsにDoxygenのインストール
- Jenkinsの管理 > プラグインの管理 > 利用可能 > Doxygen Plug-in をインストール
    - 再起動せずインストールで大丈夫だった
- Jenkinsの管理 > Global Tool Configuration > インストール済みDoxygenにパスを通す

<img width="1326" alt="76f75a21-8303-a89a-7cc2-25a34b99eac8.png" src="https://qiita-image-store.s3.amazonaws.com/0/55365/b9404b29-16e4-74a7-e54f-0ddf4cfb894b.png">

directoryを指定しろって警告が出るが、実行ファイルのパス指定で問題ない

## ジョブに対してDoxygenの設定

- ビルド手順の追加から「Doxygenでドキュメントを生成する」、を追加し、パスを指定
- ビルド後処理に「Publish Doxygen」を追加し、パスを通す


# 雑感

パス指定周りがローカルとjenkins環境で異なり、何度も試行錯誤をした。
相対パスを意識することと、エラーログをみて修正していったらうまくいった。
FreematicsArduinoBuilder が、ウイルス対策で削除される時の対処

# ArduinoBuilder が、ウイルス対策で削除される時の対処

## FreematicsArduinoBuilder-1.0.11-win32.exe
こちらは、ウイルスが含まれているとでます。

## ArduinoBuilder-0.9.9.7z
こちらは、大丈夫です。
変わった拡張子ですが、Linux で解凍しました。
他にも、サポートしているツールがあると思いますが、参考まで
Git for Windows ID/パスワードの保存場所

- Windows10
  - スタート
  - ⇒ Windows システム ツール
  - ⇒ コントロールパネル
  - ⇒ ユーザーアカウント
  - ⇒ 資格情報マネージャー
  - ⇒ Windows 資格情報
  - ⇒ 汎用資格情報

- Windows7も細かい名称の違いはあるがコントロールパネルからは同様

# 参考

- <https://blog.hinaloe.net/2015/03/08/change-name-or-pass-of-git-credential-wincred/>
npm installでnpm ERR! asyncWrite is not a functionが出たので対応


## 結論

nodeのバージョンを`10.2.1`にダウングレードした。

## node、npmのversion

```
$ node -v
v10.6.0
$ npm -v
5.6.0
```

## 問題

`npm istall` を実行したところ下記のようなエラーが出た。

```
$ npm install
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! asyncWrite is not a function
npm ERR! pna.nextTick is not a function
```

## 対応

ここに書いていることを読んで対応。

https://stackoverflow.com/questions/50597159/npm-err-asyncwrite-is-not-a-function

```
$ n 10.2.1
```
Go の map を「キーの辞書順に」列挙する

map を**キーの辞書順に列挙**する場合、普通は次のように、一旦キーをスライスに書きだして、それをソートして range を使うのが定番とされている。

```foo.go
package main

import (
	"sort"
)

func main() {
	map1 := map[string]int{
		"z": 1, "a": 10, "c": 4, "d": 5,
	}
        
	// キーをソートする
	slice1 := make([]string, len(map1))
	index := 0
	for key := range map1 {
		slice1[index] = key
		index++
	}
	sort.Strings(slice1)

	// 列挙
	for _, key := range slice1 {
		println(key, map1[key])
	}
}
```

```
$ go run foo.go
a 10
c 4
d 5
z 1
```

**これはめんどくさい！**

せめてソート部分を共通関数化できれば…。でも、Generics がないので、map の型ごとにいちいち実装しなくてはいけない。それでは共通化の意味がない。

**こんな時は、やはり reflect ですか？先生！**

```bar.go
package main

import (
	"reflect"
	"sort"
)

func SortedKeys(mapInt interface{}) []string {
	values := reflect.ValueOf(mapInt).MapKeys()
	result := make([]string, len(values))
	for i, value1 := range values {
		result[i] = value1.String()
	}
	sort.Strings(result)
	return result
}

func main() {
	map1 := map[string]int{
		"z": 1, "a": 10, "c": 4, "d": 5,
	}

	for _, key := range SortedKeys(map1) {
		println(key, map1[key])
	}

	map2 := map[string]string{
		"bb": "hoge", "aa": "uuuuu", "cc": "o00000",
	}

	for _, key := range SortedKeys(map2) {
		println(key, map2[key])
	}
}
```

```
$ go run bar.go
a 10
c 4
d 5
z 1
aa uuuuu
bb hoge
cc o00000
```

map の「キー」の型は string 固定だけど、「値」の型については何でも Ok になりました（※ただし、速いとは言っていない）
ArduinoBuilder で、ファーム書き換えが失敗する時の対処。

# ArduinoBuilder で、ファーム書き換えが失敗する。
## 初期化を何度も試しましたが書き込みエラー「Uploading not successful(Error code:-1)」となります。
いろんな記事があるが、リセットするとの事ですがうまくいかない。
リセットのタイミングが悪かったので、リセットのタイミングを明確にしたいと思います。
### ArduinoBuilder からのリセットが成功すると、UDFモードになるはずがリセットができていない場合は、新たなCOMポートが現れません。
そこで、ハード側でリセットしてあげてください。（タイミングは、下記の矢印部分）
そうすると、新たなCOMポートが現れます。
デバイスマネージャーで、COMポートが変化するのも確認できます。

![ArduinoBuilder1.png](https://qiita-image-store.s3.amazonaws.com/0/77496/eae24e8d-0ec9-c861-99ef-20c815a3f52a.png)
### 成功時の画面

![ArduinoBuilder.png](https://qiita-image-store.s3.amazonaws.com/0/77496/337429ad-e733-44d6-e421-82f6cb26f15d.png)

## リセットボタンが無いボードの時は、GND と RST を接続してください。
【Unity】VRカメラのポジショントラッキングを無効化する

# はじめに

こちらの記事で紹介されているコードに、スケールや回転角を考慮した処理を加えたものになります。

[Unity で VR モード時にカメラの位置を固定する – monopocket](http://monopocket.net/blog/vr/unity-hmd-position/)

# コード

``` CameraController.cs
using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour
{
   Vector3 basePos = Vector3.zero;

   void Start()
   {
       basePos = transform.position;
   }

   void Update()
   {
       // VR.InputTracking から hmd の位置を取得
       var trackingPos = UnityEngine.XR.InputTracking.GetLocalPosition(UnityEngine.XR.XRNode.CenterEye);

       var scale = transform.localScale;
       trackingPos = new Vector3(
           trackingPos.x * scale.x,
           trackingPos.y * scale.y,
           trackingPos.z * scale.z
       );

       // 回転
       trackingPos = transform.rotation * trackingPos;

       // 固定したい位置から hmd の位置を
       // 差し引いて実質 hmd の移動を無効化する
       transform.position = basePos - trackingPos;

       // 子のカメラの座標がbasePosと同じ値になるかを確認する
       // Debug.Log(transform.GetChild(0).position);
   }
}
```

## 補足: 回転の処理について

大変おこがましいかと思いますが、読んだ人が混乱しないため元記事で誤っているように思う記述について補足させてください。

>    // CameraController 自体の rotation が
>   // zero でなければ rotation を掛ける

元記事だと上記のような補足がされているが、rotationがzeroの時(恐らく `rotation==Quaternion.identity`の状態)であっても乗算することは問題ないはずです。

また、ベクトルを回転させる場合は以下の順番かと思います。
`回転後のベクトル = 回転角 * 回転前のベクトル`


# 課題

`InputTracking.GetLocalPosition()`で取得できる値を元に計算しているので、1フレーム遅延してる気がします。
svnの指定したユーザーのコミットしたファイルのリストを取得したい

Python 2.7.12
svn 1.9.3
Windows Subsystem for Linux

svnリポジトリから指定したユーザーがコミットしたファイルのリストを取得します。

```Python
import subprocess
import sys
import xml.etree.ElementTree as ET


def get_commit_files(url, author):
    cmd = 'svn log %s -v --xml' % url

    try:
        result = subprocess.check_output(cmd.split())
    except subprocess.CalledProcessError as e:
        print e.returncode
        print e.cmd
        print e.output,
        sys.exit(1)

    root = ET.fromstring(result)

    files = []
    for child in root:
        if child[0].text == author:
            for path in child.iter('path'):
                if path.attrib.get('kind') == 'file':
                    files.append(path.text)

    for f in sorted(set(files)):
        print(f)


if __name__ == '__main__':
    if len(sys.argv) != 3:
        print('python get_commit_files.py url author')
        sys.exit(1)

    get_commit_files(sys.argv[1], sys.argv[2])
```
twitterのシェアリンク指定でテキストの中にハッシュタグを入れる方法

# とりあえず結論
Twitterシェア用URLに対するパラメータの指定

```
https://twitter.com/share?url=https://your.service.url&text=ハッシュタグを文章に含めるには%20%23こんな感じ%20にすればいいです
```
⇓ こうなります
<img width="657" alt="スクリーンショット 2018-07-07 14.45.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/7193/e505e295-5644-dd80-8be5-acfb907c7665.png">


## 俺たちは文章の途中でハッシュタグいれたり改行したいんだ
hashtagsパラメータにハッシュタグを指定すると、シェア文章の末尾に付く形になってしまい、上図のように文中にハッシュタグを含めることが出来ません。それを解決するための備忘録です。

## パーセントエンコーディングを使えば実現できる
ハッシュタグとして使用する「#」はそのままtextパラメータに入れてしまうと、以降の文章が”リンクのハッシュ”扱いになってしまうため、シェア文言の作成がうまくいきません。
これを解決するには、パーセントエンコーディングして「#」を表すことで文中にハッシュタグを入れることが出来ます。

## よく使う文字と対応エンコード
### ＃
%23

### 半角空白
%20
ハッシュタグを使うときは半角空白で囲んでやらないと正しく区切れないので注意

### 改行
%0a

### その他特殊文字のパーセントエンコーディング
処理をかけたり、調べたりするのができない場合は、こちらのサービスでエンコード処理をすることが出来ます。
https://www.tagindex.com/tool/url.html

##　まとめ
特殊文字だけエンコードしたものを指定する方法を紹介しましたが、シェア文章をつくって、まるごとエンコーディングしたものをtextパラメータに指定するのが安全だといえます。
サロゲートペアってなんでコワイの

Puppeteer[^1]でE2Eテスト用スクリプトを書いていたら、type[^2]でサロゲートペア打ち込むと化けるというバグに遭遇したので。

「サロゲートペアに注意しろって言われても、サロゲートペアって何なんだ……？」という人向け。
(いろいろ細かいところはすっ飛ばしています)

# コンピュータと文字
まず当然の話ですが、コンピュータ、というよりもコンピュータを構成する計算機は**文字を認識できません**。まあ計算機ですし。
しかし、人間様としてはまさかコンピュータの発する電気信号を直接読み取るわけにも行かないので、なんとか文字を扱えるようになって貰う必要がありました。

そこで頭のいい人が考えたのがいわゆる**文字コード**です。

# グリフと符号と集合と
さて、コンピュータに文字を"覚えさせる"にあたり、文字というものは2つの概念に分離されました。

第一の概念は**グリフ** (glyph, 字形/字体) です。
ちょっと意識しづらいかもしれませんが、これは文字通り**字そのもの、字の形、キーを叩いたら出てくる文字の形をした画像**のことを意味している、と思ってもらえばOKです。

第二の概念は**文字に対応するもの**です。コンピュータにとっては**文字符号**[^4] (文字コード) です。
人間は、文字を見ると対応する意味や音を想起することができます。AにはAの音があり、「字」という字には「字」という意味があります。
コンピュータは数値なら扱えます。ということで、**文字を扱う時は、文字それぞれに予め数値を割り当てておいて、その数値を取り扱うことでなんとかすることになっています**。これが文字符号です。

これら「グリフと文字符号の対応付け」を集めたもののことを、**符号化文字集合**と呼びます。
そして、この対応付けを実際にコンピュータ上で取り扱う時どのようにするかという決まりごとのことを**文字符号化方式**と呼びます。
通常、このあたりのことを意識せずに「文字コード」という場合、大抵はこの文字符号化方式のことを指しています。ややこしいですね。

# Unicodeの登場
さて、そんなこんなで世界中が頑張った結果、様々な符号化文字集合と文字符号化方式が乱立します。当然ですね、文字はいっぱいありますから。ヨーロッパでもアルファベットの変種が山ほどあるのに、アジア方面なんかどうすりゃいいのかと。

そんな中、Unicodeという構想が持ち上がりました。
字面とこの流れでだいたい想像はつくかもしれませんが、このUnicodeは「**全世界のあらゆる文字を1つの符号化文字集合の下統一しよう**」という凄まじいスケールの構想でした。
パワープレイもいいところですが、コンピュータとその関連機器の性能向上によってこれはあながち夢物語でもなくなってきたのです。

そして、Unicodeは実際に動き出し、様々な国、地域から文字の登録を受け付けていきます。
……**が**。

# Unicodeの敗北
Q. 何があったの？
A. **表現できる文字の量が足らない**。

「16bit、65536種分の領域があれば、あらゆる文字を格納できる！」
これが、Unicodeの初期の構想でした。しかし、**足りなかったのです**。
Unicodeの理想、これは伊達ではありません。なにしろ、Unicodeには**普通のアルファベットからルーン文字や錬金術文字まで、文字通りにあらゆる文字が登録されようとしています**。~~といっても残念ながらアーヴやヒュムノスはないんですが~~

Unicodeの人たちは考えました。困ったことに「こりゃどうやら足らんぞ」とわかったのはUnicodeがとっくに走り出した後。既に各所で実装されており、今から「やっぱなしな！」とか言い出したら確実に計画崩壊、どころか世界中大混乱です。
しかし、UnicodeがUnicodeたらんとするのであれば、文字容量は増やさねばなりません。

というわけで、おまたせしました。サロゲートペアの登場です。

# サロゲートペアの登場
サロゲートペアは、**未使用の領域2つの組み合わせで1文字を表現することにすることで、擬似的に表現できる文字量を増やす**というものすごい~~苦肉の~~策だったのです！

……ええと、要するに「**ここからここまでの数値が来たら、もう1文字分読み込め。んで、2つ合わせて1文字扱いしろ**」ということです。

ここまでくればピンと来たかもしれません。
そう、サロゲートペアが何故ここまで~~めんどくさがられ~~恐れられているのか。
「**1文字だと思ったら0.5文字だった**」
こういう事態を引き起こすから、サロゲートペアは恐れられるのです。

# ところで実際
では実際どうすればよいのでしょう？

実は、意外にも難しいことはあまりありません。というのも、**サロゲートペアの存在を意識して、サロゲートペアに対応したライブラリやAPIを使えば、そこまで問題は起こらないからです**。だってみんな面倒は嫌ですから、誰かが対策打ちますよそりゃ。
もしもあなたがサロゲートペアで痛い目を見るとしたら、**それはバグか、古いアプリケーションによるもののことがほとんどでしょう**。私はそれで「うがー！」となっています。

なお、実際に取り扱うデータにおいてサロゲートペア云々の問題が発生するのは、実は文字符号化方式にUTF-16を採用している場合のみです。
……のみなのですが、あいにくとUTF-16を文字列の内部表現として使っている言語は少なくありません。結局は、割とどこでも起こりうるめんどくさい問題、と思っておいたほうがよいかもしれません。

[^1]: GoogleのE2Eテストその他向けライブラリ。ChromeをNode.jsから触れる。
[^2]: 特定のコントロールに文字列を(字面通り)タイプする。例えば page.type("#hoge", "ほげ") とやるとpageのid=hogeに対して"ほげ"と打つ。
[^3]: すごく雑な解説。
[^4]: Q. なんで文字符号のほうがメインで、文字コードが別名みたいな表記なの？ A. いや普通文字コードっていったら文字符号化方式さしちゃうじゃろ……
gmail でのメルマガのフィルタリングメモ

- 久しぶりに開く gmail アカウントにメルマガがいっぱい溜まっていて、何がなんだかわからなくなっている！！
- ただ、読みたいメルマガもあるし、いらないメルマガだけはじきたい！！
- 「メール選択」=>「メールの自動振り分け設定」を毎回やってると、フィルタがいっぱいできてわけわからんくなる!!

てことがありまして、そのときにやったことですメモです。

これが一番いい方法ではないと思いますが、次回やるときに絶対忘れてると思ったので、手順の自分用メモです。


# スプレッドシートにメルマガの From 部分を全部リスト化

![Screen_Shot_2018-07-06_at_3_01_11.png](https://qiita-image-store.s3.amazonaws.com/0/30407/eb62b8ba-e1c9-349c-962d-ac34aa302984.png)



# GAS でシートからフィルタリング条件の文字列を生成

ここから。

![Screen_Shot_2018-07-06_at_3_04_14.png](https://qiita-image-store.s3.amazonaws.com/0/30407/c62ebd41-b243-dc54-da04-d9462ae23ed5.png)

GAS をこんなふうに書いて。

```
function onOpen()
{
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('フィルタ生成'); 
  menu.addItem('フィルタ生成', 'generateFilter'); 
  menu.addToUi();
}

function generateFilter() 
{
  var sheet = SpreadsheetApp.getActiveSheet();
  
  // A列のデータをぜんぶ取得する
  var rowStartIndex = 1;
  var colStartIndex = 1;
  var colNum = 1;
  var melmagas = sheet.getRange(rowStartIndex, colStartIndex, sheet.getLastRow(), colNum).getValues();
  
  // filtering するための条件文字列を list へ 
  var MAX_FILETER = 1300 // だいたいこれ以上長い条件文字列を gmail 側がうけつけてくれなかった
  var filters = []
  idx = 0 
  filters[idx] = ""
  for(var key in melmagas)
  {
    str = ( (melmagas.length - 1 == key) || (MAX_FILETER <= filters[idx].length) ) ? melmagas[key][0] : melmagas[key][0] + " OR " ;
    filters[idx] += str
    
    if( (MAX_FILETER <= filters[idx].length) )
    {
      idx += 1
      filters[idx] = ""
    }
  }

  
  // シートへ書き込み
  for(var key in filters)
  {
    sheet.getRange( parseInt(key)+1, 3).setValue( filters[key] );  
  }
}
```

このボタンを押すと、C列にフィルタ文字列ができてる。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f33303430372f33303834323339652d363266622d376638642d653336662d3939343463626463623739622e706e67-3.png](https://qiita-image-store.s3.amazonaws.com/0/30407/4bfa335b-94ae-b9ac-0d0d-c0a71f512a52.png)


# gmail のフィルタ設定へ突っ込む

`gmail` -> `設定` -> `フィルタとブロック中のアドレス`　と進んで。

上記スプレッドシートで生成されたフィルタ文字列をFromのところへ突っ込んで「続行」。

<img width="722" alt="Screen_Shot_2018-07-06_at_3_07_24.png" src="https://qiita-image-store.s3.amazonaws.com/0/30407/c580ef43-e058-22ba-cef9-25510c937afb.png">

次のページで、「一致するスレッドにも~」のところにチェックを入れるのを忘れずに、「フィルタを更新」を押す。

<img width="706" alt="Screen_Shot_2018-07-06_at_3_09_25.png" src="https://qiita-image-store.s3.amazonaws.com/0/30407/f6cbf0aa-b26b-62e3-f057-562028e8c4a1.png">

これでOKなきがする。
パーフェクトシャッフル

# パーフェクトシャッフル
パーフェクトシャッフルとは、トランプカードのシャッフルの方法の一つ。カードを完全に二等分して両手に持ち、完全に一枚ずつ左右のカードを重ねるシャッフル方法のこと。

上記の通りであるので、どのように混ざるかは完全に計算できる。面白いことに52枚のカードを8回パーフェクトシャッフルする事で、完全にシャッフル前の状態に戻ることが知られている。

本稿ではそれをJavaScriptで計算してみよう

# 定式化・アルゴリズム
カードの枚数を `2N` 枚とする。一番上を 0番目のカード、その下を 1番目のカードと呼ぼう。右手に 0番目〜 N-1番目のカードを持ち、左手に N番目〜2N -1番目のカードを持つ。シャッフルは、左手のカードから行い、右手のカードの一番上がシャッフル後の 0番目になるようにシャッフルするとしよう。

この時、シャッフル前の x番目が シャッフル後の y番目にくるとして、 `y = f(x)` なる関数 f を定式化しよう。

簡単な問題だが、少し詳しく見て行こう。シャッフル後の0番目がもともとの何番目か？を考慮すると、`f(0)=0` となる。同様に `f(N)=1`, `f(1)=2`, `f(N+1)=3` ...となる。規則性が見えてきた。

ようは x の値が小さいうち（右手の場合）は `f(x) = 2x` として良さそうだ。x の値が大きい時（左手の場合）は `f(x) = 2x - 2N + 1`とすれば良い。つまり、以下のように実装できる。関数ps はシャッフルするオブジェクトの配列を入力に取り、シャッフル後のオブジェクトの配列を返す。オブジェクトはコピーしない、つまり、シャローコピーである点に注意。

```js
function ps(arr) {
  const N = arr.length / 2;
  const ret = new Array(arr.length);
  for (let i = 0; i < N; i++) {
    ret[2 * i] = arr[i];
  }
  for (let i = N; i < 2 * N; i++) {
    ret[ 2 * i - 2 * N + 1] = arr[i];
  }
  return ret
}
```

こんな感じで使う＆動作確認。

```js
const a = Array(10).fill(0).map(() => Object());
const b = ps(a);
console.log(a[0] !== a[1]); // true
console.log(a[0] === b[0]); // true 0 -> 0
console.log(a[1] === b[2]); // true 1 -> 2
console.log(a[5] === b[1]); // true N ->  1
console.log(a[9] === b[9]); // true 2N-1 ->  2N - 1
```

# 何回のシャッフルで戻るか？
以下のように equals 関数を定義することで、元に戻ったかを確認できる。

```js
function equals(arr1, arr2) {
  return arr1.every((val, i) => val === arr2[i]);
}
```

52枚のカードでパーフェクトシャッフルをして8回目に戻ることを確認しよう

```js
const arr = Array(52).fill(0).map(()=>Object());
let shuffled = arr;
for (let i = 0; i < 16; i++) {
  shuffled = ps(shuffled);
  console.log(`${i + 1}th: ${equals(arr, shuffled)}`);
}
```

出力はこんな感じ。予想通り。

```
1th: false
2th: false
3th: false
4th: false
5th: false
6th: false
7th: false
8th: true
9th: false
10th: false
11th: false
12th: false
13th: false
14th: false
15th: false
16th: true
```

# 数学的な考察
フェルマーは、2N-1 が素数なら、2N-2 回のパーフェクトシャッフルが必要であることを示した。2N-1 が合成数 p * q の場合（例:トランプの場合)はもっと少なくて、最大でも (p -1) * (q -1)回で済む。52枚のカードの場合は、最大で32回あればよいのだが、前述のとおり、8回ですんだ。

参考文献: 数学の国のミステリー ISBN978-4-10-50631-9
初投稿テスト

動機とか
-
趣味の週末プログラミングを活かして社会に役に立つ仕事がしたいと思い、大学出て社会人３年目だけどこれからデータ・サイエンティストを目指したいなと思って、以前から気になっていた機械学習をこれから勉強していきます。

これまで開発時のメモはEvernoteだったけれど、人の目につくとこに置くことで試行錯誤の共有ができたり、洗練された記事が書けたらいいなと思ってQiita登録してみた。
（テスト投稿に薄い内容投稿するの気が引けたけど、テストとしか投稿してない記事いっぱいあるようだしそのあたり気にしてたら始められない）

ついでに楽だと聞く Markdown の記法も身に着けたかったし。適度に改行いれていった方が読みやすいのかな？メモ目的だけでも案外使いやすいかも。

これからの取り組み予定
-
- [Aidemy](https://aidemy.net/) 「人工知能プログラミングを10秒ではじめよう」
今日たまたま読んだ、[機械学習を使って焼肉で肉が焼けたかどうかを区別してみた](https://qiita.com/yonell/items/682f65b97f35d6191936) の記事で知った。こういうの探してた、とりあえず無料コースから受講してみることにする。

- [kaggle](https://www.kaggle.com/) 「Kaggle is the place to do data science projects」
有名な機械学習のコンペサイトとのこと。（[データ分析職に採用されるために必要な「実務経験」をいかにして積むべきか](https://tjo.hatenablog.com/entry/2017/09/15/190000)）
とりあえず登録だけした。興味がある記事は英語でも（Google翻訳バンバン利用して）読んでみようと思えるのが面白い。
まずは参加して、そして上位入賞できるよう頑張ろう。

あとがき？
-
備忘録としてまずは慣れるところから始めますので、Qiitaや機械学習の先人のみなさま頑張って追いかけますのでよろしくお願いします。コメント歓迎です。
- 豊かな技術を単に利用する側でなく、誰でもそれが利用できるような知見を創出する側になりたい。
Laravelのモデルでリレーションを定義するときの命名規則で迷子になった話

# 前提

LaravelのModelでRelationを定義するのは非常に簡単です。Userが1:1でPhoneを持つ場合、

```php

class User extends Model
{
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }
}

```

こうするかとおもいます。では、Userが1:1でUserProfileを持つ場合はどう書くでしょうか。

```php


class User extends Model
{
    public function userProfile()
    {
        return $this->hasOne(UserProfile::class);
    }
}

```

普通はこうでしょう。注目して欲しいのはメソッド名です。
Laravelはメソッド名はキャメルケースにするのが作法ですから、userProfileという名前は正解と言ってしまってもいいかもしれません。（UserProfileという例がそもそもよくないという指摘はやめてくだせー。ここで重要なのは単語2つであることです。）

ですが、こういう書き方をした人がいました。

```php

class User extends Model
{
    public function user_profile()
    {
        return $this->hasOne(UserProfile::class);
    }
}

```

ご覧の通りスネークケースです。
なんでこんな書き方したんだ？と思いましたが、書いた本人は意図的にやっています。そして実際に使ってみると個人的には結構しっくりきてしまいました。なんででしょう？ 

以下、リレーションの定義をスネークケースにした意図とそれが以外と個人的にしっくりいっちゃった理由について私見を述べたいと思います。

あらかじめ言っておくとプロジェクト内で統一されていれば何も問題ない話です。。
ですが、プロジェクト内で意思統一し忘れたおかげでキャメルケースとスネークケースが混在してしまい、今のプロジェクトではどちらに寄せるべきか迷ったので、その迷いを含めてポエムにしたためておこうというのが本項の趣旨でございます。

# リレーションの定義をスネークケースにした意図

彼（＝以下A君）は「メソッド名はキャメルケース」ということを知らなかったわけではありません。実際にローカルスコープについては普通にキャメルケースで記述していました。

「リレーションの定義だけスネークケースにしたいなら先に伝えとけよ！勝手すんな！」

と思うかもしれませんが、A君はむしろリレーションの定義は当たり前にスネークケースだと思っていたようでした。理由はLaravelのEloquentモデルにありまちた。

## カラムへのプロパティアクセスの問題

Userモデルに紐づくusersテーブルがfirst_name/middle_name/last_nameの3つのカラムを持つ場合、それらのカラムの値にアクセスするときには以下のようにします。


```php

$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;

```

キャメルケースではなくスネークケースですね。

上記のように、Eloquentモデルはテーブルのカラム名でプロパティのようにアクセスが出来ます。しかし、一方でテーブルのカラム名は当然スネークケースで、一方でLaravelの変数名は基本的にキャメルケースが作法ということで、フレームワーク内にルールの例外が存在しちゃっているわけです。

しかし、A君はこれ例外ではなく、「テーブルレコードに関連するものについてはスネークケース」というルールと読み取ったみたいです。そのため、「リレーションの定義についてもスネークケースに統一」していたというのがA君の意図だったのでした。

# しっくりいっちゃった理由

リレーションの定義は別のモデルのインスタンスを（あまり深く考えずとも）プロパティのように扱えることがメリットなはずで、そう考えるとカラムへのアクセスと同じようにスネークケースにすると非常に統一感がある気もしてきます。
実際にコードを書いている感覚としても、

```php

$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;
echo $user->user_profile->nickname;

```

みたいに書くのは

```php

$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;
echo $user->userProfile->nickname;

```

みたいに書くよりも記述しやすく感じました。このへんの感じ方は好みかと思います。私はスネークケースの文化で育ったのでそう感じてるだけかもしれませんし。

# で、実際はどっちに寄せたの？

いくらスネークケースに書きやすさを見出したところで、混在したままであれば書きづらさはMAXでございます。なのでどちらかに統一するというのはマストであると考えました。（当たりまえ）

結果、キャメルケースに寄せました。たいした理由はありませんが、

* ざっと見た感じスネークケースの方が修正量が少ない
* phpcsでこのケースだけスネークケースを許可にできなそうだった。
* 長いものに巻かれておいた方が楽

という感じでございます。作業？いまからやるんだよ！（休出）

# A君の正体

1ヶ月前の私です。