OmniAICreator/Qiita-1.07M huggingface dataset:
設定ファイルでゴロゴリ弄(維持)れるアーキテクチャを考える際のポイント

# アイデアメモ: 設定ファイルでゴロゴリ弄(維持)れるアーキテクチャを考える際のポイント #

[新装版 達人プログラマー 職人から名匠への道](https://www.ohmsha.co.jp/book/9784274219337/)を読んでいます。

本書では「プログラムの動作環境についても設定ファイルで選択できるようにしておくべきだ」と主張しています。

自分は急いでいると、ついプログラムコードとビジネスロジックが分別されていないコードを書きがちです。これまでは「それでも動くんだからいいじゃないか」と思っていましたが、本書を読んで反省しました。しかも今の自分が直面している課題に響く内容だったのでかなり考えさせられました。

以下は、設定とコードを分離する方向で設計を考えるために思ったことになります。


## 設定のレイヤーを分ける ##

プログラマーが提供するコード層が1枚あって、あとはユーザ(これにはプログラマ自身も含まれる)が編集できる設定層が1枚、という単純な切り分けを想定します。つまり、実行ファイルが1つあって、細かいチューニングは全て引数で指定というような場合です。

ものすごく単純なコマンドラインプログラムなどはこのタイプに当てはまることが多いと思います。
ただ業務用のシステムでビジネスロジックや外部サービス(APIなど)の変更に常にさらされているプログラム群はもう少し事情が複雑になります。

このような場合、少なくとも以下のように複数のレイヤーに分けて開発する必要性を感じています。

* ビジネスロジックから導かれる設定値を入力したり、ユーザのプラットフォームを選択したりするための設定ファイル(設定画面) == 表層

* プログラムをプログラムする設定ファイルやコードジェネレータ == 中間層

* 最終的には抽象的な構造を持つプログラムがサービスを実行する == 深層


上記のようなレイヤーの分割方法は、例えば、次のようなアーキテクチャに反映できます。


| レイヤー | 中身 |
| ---- | ---- |
| 表層 | ブラウザなどに設定用の画面を表示し、ユーザに値を入力してもらう |
| 中間層1 | ユーザの入力値とコードの動作を紐付けるための設定ファイル(TOML/INI/JSON/CSVなど) |
| 中間層2 | 設定ファイルと実行ファイル呼び出しを紐付けるスクリプト(シェルスクリプトなど) |
| 深層 | 実行ファイル(バイナリー/Pythonなどのスクリプト)が与えられた設定ファイルや引数を元にサービスを実行 |


時間的に余裕がなかったり仕事への理解が浅かったりすると、中間層でやるべきことを深層(または表層)に無理やり寄せて作ってしまうことがあります。自分はこのパターンに陥りがちです。
サービス全体としてはひとまず動くので安心してしまいます。しかし、この後、振り返りを忘れてしまう怠慢な状態になるとメンテの機会が訪れた段階になって頭を抱えるわけです。
なお、自分の経験では上記のようなレイヤーの切り分け「だけ」ではメンテナンス性の向上には限界があると考えています。
この問題を解決するには同時にプログラムコードや設定値同士の直交性を確保する必要があります。
直交性とは大雑把に言えば「お互いの依存度が最小限になるように部品を作る」という意味です。


## メモのメモ ##

以下はアイデアをまとめ中のメモです。

* 全部やろうとしない。全てをカバーできることを前提/目標にしていては何も進まない。

* バイナリや設定ファイルの管理/維持/バックアップについての戦略

これらについては考えがまとまったらまた書きます。
導関数

```math 
\begin{align}
&C' = 0
\\
&(x^n)' = nx^{n-1}
\\
&(sinx)' = cosx
\\
&(cosx)' = -sinx
\\
&(a^x)' = a^xlna
\\
&(e^x)' = e^x
\\
&(log_ax)' = \frac1xlog_ae
\\
&(lnx)' = \frac1x
\\
&(u + v)' = u' + v'
\\
&(uv)' = u'v + uv'
\end{align}
CloudAtCostの破壊と創造を自動化

https://buzzwordjp.blogspot.com/2011/09/chrome.html

仮想通貨触ってるので、ブラウザに野良アプリ入れるの怖くてこれしました。効果あるのかは知らん。
もしかするとこの方法じゃセキュリティ上意味ないかも。でもめんどいからいいや。
地味に便利。複数のKatalonを別個にしてショートカット単位でユーザー区切っちゃえば色々応用効きそう。

https://qiita.com/kazurayam/items/433876c0b3bc7f33f019

こっちが本題の自動化。できた！！！！
他にも色々と応用効きそうなので、とりあえず知見共有のため記事化。
sed,正規表現で取り出した文字列（随時更新)

タイトルどおり、sedや正規表現を利用して抽出した文字列を備忘録としてまとめていきます。正規表現やシェルに強くはないため、非効率な書き方もあるかもしれません。よりよい書き方がありましたらご指摘いただけますと幸いです。

# php.iniのパス

```
$ php --ini | sed -n 2p | sed -e "s/^Loaded.*\ //g
```

# phpのextension_dirのパス

```
$ php -i | grep extension_dir | sed -e "s/^extension_dir\ =>[^=]*=>\ //g" | sed -n 1p
```

# 特定ユーザの所属グループ一覧

```
$ echo `id vagrant` | sed -e 's/[0-9\(,\ ]//g'| sed -e 's/)/\n/g' > vagrant_group.txt
```
How to extend page editor of Confluene cloud

Though I would like to extend the page editor of Confluence cloud with TinyMCE plugin, Confluence cloud add-on cannot extend it directly like a Confluence Server.

So I decided to use 'content script' of browser extension (I used Chrome extension).

The 'content script' can access page contents via dom, but cannot access js global variables.

To refer them, it has to [inject scripts](https://stackoverflow.com/questions/20499994/access-window-variable-from-content-script) that will be executed in page context into page contents.

Note that [public sample](https://developer.atlassian.com/server/confluence/enabling-tinymce-plugins/) of registering TinyMCE plugin for Confluence Server is not available as it is, because the editor of Confluence Cloud(as of now) uses TinyMCE4.

It can be resolved by using `AJS.Rte.BootstrapManager` instead of `tinymce-bootstrap`, as following,

``` javascript
require(['confluence/module-exporter', 'com/excelimport/plugins', 'tinymce'], function(ex, ExcelImportPlugin, tinymce) {
 
        tinymce.create('tinymce.plugins.ExcelImportPlugin', ExcelImportPlugin);
 
        tinymce.PluginManager.add('excelimport', tinymce.plugins.ExcelImportPlugin);
 
        AJS.Rte.BootstrapManager.addTinyMcePluginInit(function(settings) {
            settings.plugins += ",excelimport";
            console.log(settings.plugins);
        });
 
    })
```

Additional note: In publishing Chrome addon, it will remains 'in review' unless you pay onetime registering fee($5). It is hard to notice it in new dashboard!
React Native でプロジェクトを開始した時に undefined is not a function が出る

# はじめに
`react-native init` で新しいプロジェクトを開始した際に `undefined is not a function (... 'reactDevTools.connectToDevTools' ...)` のエラーを検知しました。

既存のプロジェクトではこのエラーは発生せず、正常に動いていました。

# 対策
Github に issue としてあがっていました。
[react-devtools 3.5.0 breaks new project](https://github.com/facebook/react-native/issues/22863)

react-devtools-core をダウングレードします。

```
$ yarn add -D react-devtools-core@3.4.3
```

package.json に下記を定義します。

```json

  "resolutions": {
    "react-devtools-core": "3.4.3"
  }
```

`node_modules` と `yarn.lock` を削除して、 `yarn install` をし直します。


私はこの方法で動くようになりました。

# おわりに
Github の issue を見れば同じ悩みを抱えた人がいることが多いので、便利な時代だなぁとしみじみしています。
2019 年は英語力を伸ばして、問題の検索能力をあげたいなと思います。
mrubyでOAuth2

[IoTでOAuth2](https://qiita.com/yamori813/items/1df4ddcce976476767e1)の実践編で蟹さんのmrubyからDropboxにファイルを放り込んでみます。

まず準備にmruby VMにmruby-base64とmruby-jsonをつっこみます。mruby-jsonにはfileアクセスがありリンクできなかったので、fileアクセスをとるprを出してマージしてもらいました。

次はDropboxの[developerのサイト](https://www.dropbox.com/developers)でアプリを作ります。Full accessにしておきます。これでApp keyとApp secretが入手できました。

次はブラウザーで以下のURLを叩いて、アクセス許可のcodeを手に入れます。

https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id=Appkey

忘れていたのですが、[Dropboxの認証コード](https://qiita.com/yamori813/items/83a2cb4cb20a438eb210)という記事を書いてました。

App keyとApp secretはmrubyのスクリプトにハードコードしますが、codeはスクリプトがリダイレクトやフォームで受け取るようにするがいいです。まだHTTPやHTTPSのLISTENの実装がないので、とりあえずハードコードします。

```ruby
APPKEY = ""
APPSEC = ""
CODE = ""

yabm = YABM.new

yabm.netstartdhcp

ntpaddr = "10.0.1.18"
yabm.sntp(ntpaddr)

header = Hash.new
header.store('User-Agent', "test-agent")
header.store('Authorization', "Basic " + Base64.encode(APPKEY + ":" + APPSEC))
ustr = "/1/oauth2/token?grant_type=authorization_code&code=" + CODE
res = SimpleHttp.new("https", "api.dropbox.com", 443).post(ustr, header)
```

これでAccess Tokenがjsonでもらえるのでjsonのパーサーに食わせます。

```ruby
data = JSON::parse(res.body)
accesstoken = data["access_token"]
```

この操作は一回だけで、Access TokenはFlashなどに保存しておく必要があります。

Access Tokenを使ってファイルをuploadします。

```ruby
path = "yabm"
name = "morimori.txt"
body = "Hello mruby on YABM !"

header = Hash.new
header.store('User-Agent', "test-agent")
header.store('Authorization', "Bearer " + accesstoken)
header.store('Content-Type', "application/octet-stream")
header.store('Dropbox-API-Arg', "{¥"path¥": ¥"/" + path + "/" + name + "¥",¥"mode¥": ¥"add¥",¥"autorename¥": true,¥"mute¥": false}")

header.store('Body', body)

res = SimpleHttp.new("https", "content.dropboxapi.com", 443).post("/2/files/upload", header)
```

yabmというディレクトリにmorimori.txtというファイルが出来ているはずです。

![スクリーンショット（2019-01-08 18.51.36）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/21761d99-38af-1f72-5608-b7fdbe37a0d9.png)

OAuth2はOAuthのようにHASH関数が必要ないので良いです。

もしAccess Tokenが入ったモジュールを盗まれた場合には自分のDropboxにFull accessされる可能性があるので、「設定」の「リンク済みのアプリ」から削除するのが良いです。
キャリアアップ、就職、転職に"役立たない"エンジニアの友達の作り方 + Twitter活用術

キャリアアップ、就職、転職に役立たないエンジニアの友達の作り方 + Twitter活用術

# キャリアアップが上手なタイプと、下手なタイプ

- 僕は完全に後者のタイプで、人事評価的にも良い魅せ方とか全然わからず問題山積み、社会人力超低レベル‥
- 自分でよく言うなら打算で動くのが絶対ムリなタイプだと思うので、利害関係のために人と仲良くすることができない
- だけど無理に前者になろうと思わなくても良い、後者タイプでもエンジニアとしてバリバリ活躍しているひとはいるし

# 会社で利害関係のない別セクションの人と話す

- 最近は遠い席に座っているインフラさんとよく話す
- インフラさんなので、話としてはWebエンジニアとは通じる部分も多くて、利害関係がないのに雑談できるような、いい関係だと勝手に思っている、完全な雑談ではなく知見も得られるし、業務時間で遊んでいるわけではない‥はずたぶん
- お正月明けにちょっと風邪ひきながら出勤したら、向こうから挨拶してくれて、ほっこりしたり、メルカリの話をしたりしてた(1分ぐらい)

# あと、Twitterでとにかく遊ぶ

- 自分の記事をアウトプットしたら誰か人にみてもらいたい
- Twitterで他の人とどんどん絡んでいく、エンジニア、他業種問わずに
- いつのまにか遊ぶことのほうが楽しくなってきている、アウトプットなんて話の種、逆説こそ最強

---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
プログラマ・エンジニアの勉強ならQiitaに1文字コメント、絵文字コメントをつければ良い

プログラマ・エンジニアの勉強ならQiitaに1文字コメント、絵文字コメントをつければ良い

# Example

[PHP: 振る舞いを持つEnumの作り方 - Qiita](https://qiita.com/suin/items/17ee61d7e75b422a7ec3#comment-1d1464a7964c244c4755)

# コメントは1文字で

- ふむふむなるほどぐらいの、人から見たらどうでもいいぐらいのコメントをつける
- 絵文字1文字でも良い
- Emoji 1個でのリアクションは Facbook などでも実装されている、ノーマルないいねに色がついた感じ、それをQiitaでもユーザー独自利用的にやってみる

![image](https://user-images.githubusercontent.com/13635059/50712937-a469cc00-10b6-11e9-8901-45ea9b6a8b85.png)

# コメントを付けておくと、自分の脳に刻まれる

この記事にコメント書いたな、また何かひとつ言いたいなというトリガーがうまれる

# Qiitaの機能的に、思い出す機会が増える

- Contributionsの一覧とか
- 他の人のコメントが付いたときとか
- 思い出す機会が増えると、また記事が気になって、次のコメントをしたくなったり、トピックが気になったりして調べるトリガーになる

![image](https://user-images.githubusercontent.com/13635059/50713138-425d9680-10b7-11e9-80f2-5045bfafa598.png)

---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues



https://github.com/YumaInaura/YumaInaura/issues/237








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Laravel備忘録

先日laravelにおいてマイグレーションを作成しました。
テーブル作成において忘れやすい操作をメモしておきます。

###テーブル作成

####1. マイグレーションファイル作成
最初に

```
$ php artisan make:migration create_posts_table
```

とコマンドに入力してマイグレーションファイルを作成した
※テーブル名は複数形を使った方が良さそうでした

すると、database/migrations/に、{Y_m_d}_create_posts_table.phpが作成されるため、
この中のupメソッドに、作りたいテーブルの定義を書いていく。

####2. マイグレーション実行
マイグレーションファイルができたら、実行する

```
$ php artisan migrate
```

すると、データベースにテーブルができている。

####マイグレーションファイル作成
最初は

```
$ php artisan make:migration add_column_comment --table=posts
```

とコマンドに入力してマイグレーションファイル作成。
すると、database/migrations/に、{Y_m_d}_add_column_comment.phpが作成される。
この中のupメソッドに、追加したいカラムの定義を書いていく。
　 
マイグレーションファイルができたら、実行する

```
$ php artisan migrate
```

すると、テーブルにカラムが追加されているので確認する。

ざっとこのような感じです。
CodeceptJSでデータドリブンテストを行うときの注意点

CodeceptJSはデータドリブンテストをサポートしており、配列や専用の `DataTable` オブジェクトを渡すことで、一つのシナリオを異なるデータで複数回実行することができます。
例えば、下記の例では`hoge@example.com``fuga@example.com`の2つのアカウント情報でログインのテストを実行します。

```javascript

const accounts = [
  { email: 'hoge@example.com', password: 'secret' },
  { email: 'fuga@example.com', password: '123456' },
]

Feature('Data Driven Sample')

Data(accounts).Scenario('Can Login', (I, current) => {
  
  // Data()に渡した配列が一つずつcurrentという変数に渡される

  I.fillField('email', current.email)
  I.fillField('password', current.password)
  I.click('Login')

})
```

CodeceptJSは、テストの実行を1ファイルごとに同期的に行いますが、シナリオの登録そのものはファイル読込直後に一括で行われるようです（コード読んでないので挙動から推測してますが……）。
そのため、シナリオAで実行した結果をグローバル変数に格納し、Data()経由で別のシナリオを実行するのに使うことはできません。

```javascript

let accounts = {}

Feature('Bad Data Driven Sample')

Scenario('Can fetch account data', (I) => {

  /** 
   * GET '/accounts' は以下の配列を返す
   * [
   *   { email: 'hoge@example.com', password: 'secret' },
   *   { email: 'fuga@example.com', password: '123456' },
   * ]
   */

  accounts = (await I.sendGetRequest('/accounts'))
})

// accountsに渡ってくるのは {} のため、このテストは失敗します
Data(accounts).Scenario('Can Login', (I, current) => {
  
  I.fillField('email', current.email)
  I.fillField('password', current.password)
  I.click('Login')

})
```

上記のようなことをやりたい場合、シナリオの外で `GET /accounts` を実行する必要がありますが、シナリオの外で `I.sendGetRequest()` を実行することは出来ないので、Axiosなどを使って自前で実装する必要があります。

```javascript

/** 
 * GET '/accounts' は以下の配列を返す
 * [
 *   { email: 'hoge@example.com', password: 'secret' },
 *   { email: 'fuga@example.com', password: '123456' },
 * ]
 */
const accounts = ( async () => axios.get('/accounts') )()

Feature('Use Axios')

Data(accounts).Scenario('Can Login', (I, current) => {

  I.fillField('email', current.email)
  I.fillField('password', current.password)
  I.click('Login')

})
```

以上、コネタでした。
Nginx でリバースプロキシ設定する方法

## 前提

サーバOS： ContOS7

## 手順

### 設定ファイルを修正

```bash
sudo vi /etc/nginx/conf.d/default.conf
```

以下の通りに修正

```vim:/etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;

    location / {
        # 以下の２行に修正 (今回は 80番ポート　→ 3000　番ポートに振る設定にする)
        proxy_pass http://localhost:3000;
        proxy_set_header Host $http_host;
    }

...

}
```

### 設定反映

Nginx をリロードする

```bash
sudo systemctl reload nginx
```

以上で完了。
Macのターミナルで使用するコマンド

###cd コマンド

```
カレントディレクトリにあるファイルに移動する。（change directoryの略）
cd test.html  # testテストというファイルに移動する
cd ~/  #ホームディレクトリに移動する
cd ..  #一つ上の階層のファイルに移動する
```

###pwd コマンド

```
カレントディレクトリのパスを表示する。（print working directoryの略）
pwd  #カレントディレクトリのパスを表示する
```

###touch コマンド

```
中身が空のファイルを作る。
touch test.html  #test.htmlという中身が空のファイルを作る
```

###mkdir コマンド

新しい空のディレクトリを作る。（make directoryの略）

```
mkdir test #test
というファイルを作る
```

###mv コマンド

```
ファイルを移動したり、ファイル名を変更したりする。（moveの略）
mv test.html tmp/ 
 #test.htmlというファイルを相対パスでtmp/に移動する
mv test.html test2.html 
 #test.htmlというファイルをtest2.htmlに名前変更する
```

###cp コマンド

ファイルをコピーする。（copyの略）

```
cp test.html tmp/  #test.htmlを相対パスでtmp/というディレクトリの中にコピーする
cp test.html test2.html  #test.htmlをtest2.htmlという名前でコピーする
cp −r dir /tmp/  #dirというディレクトリとその中身を絶対パスで/tmp/にそっくりコピーする
```
###openコマンド

ターミナルからFinderでファイルを開く

```
open .  #現在のターミナルのディレクトリFinderで開く
open ~/  #ホームディレトリをFinderで開く
```

###ファイルの設定を読み込み有効にする

```
source ~/.bash_profile 
```
 #ホームディレクトリにある.bash_profileに書き込んだ設定を読み込み有効にする

```
source .bash_profile  
```
(メモ)Vagrantの起動から停止まで

vagrant init で Vagrantfileを作成します。

```
vagrant init
```

vagrant init をしたディレクトリに Vagrantfile という設定ファイルが作成されます。そして、vagrant upなどのコマンドが使えるようになります。
###Vagrantを起動

Vagrantfile が作成されたディレクトリで、vagrant up コマンドを実行すると Vagrant が起動します。

```
vagrant up
```

Vagrant が起動というのは実際には VirtualBox の VM が起動しています。Vagrant を起動した後に、VirtualBox.app を起動してみてください。
###VMの状態を確認

Vagrant を起動したら、Vagrant が起動しているか vagrant status を使ってVMの状態を確認してみましょう。

```
vagrant status
```

VMが起動している状態

```
default                   running (virtualbox)
```

VMが停止している場合

```
default                   poweroff (virtualbox)
```

Vagrant につながらない場合などは、まず vagrant status で状態を確認すると良いです。
###Vagrantを停止

haltで停止できます。

```
vagrant halt
```

###Vagrantを再起動


```
vagrant reload
```

###Vagrantへsshログイン


```
vagrant ssh
```

もしパスワードを聞かれる場合は、vagrantと入力します。
ロリポップマネージドクラウドでLaravelアプリのセットアップ手順

ちょっとお仕事で、セットアップ手順を確認する必要があったので備忘録的にメモします。

権限周りはあんまり気にしてないのでセキュリティ面で大丈夫かはちょい不安

とりあえず某学校の教え子は俺に焼肉奢っておくと良いと思う。


# 手順1 composerをインストール
ユーザーディレクトリをいじれないので、/var/www/binにcomposerを設置して、パスを通します。

- cd /var/www
- mkdir bin
- cd bin
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- mv composer.phar composer
- export PATH=$PATH:/var/www/bin
- vi ~/.bash_profile

``` txt:.bash_profile
export PATH=$PATH:/var/www/bin
```

# 手順2 Laravelのインストール
- cd /var/www
- composer global require 'laravel/installer'

# 手順3 GithubからLaravelのプロジェクトを落としてセットアップ
- git clone https://github.com/xxxxxx/xxxxxx.git project
    - gitのLaravelプロジェクトのURL
- cd /var/www/project/
- composer install
- cp .env.example .env
- vi .env
    - 利用DBがMySQLである前提
 

``` txt:.env
DB_CONNECTION=mysql
DB_HOST=マネクラ管理画面にあるDBのホスト名
DB_PORT=3306
DB_DATABASE=マネクラ管理画面にあるDB名
DB_USERNAME=マネクラ管理画面にあるユーザー名
DB_PASSWORD=プロジェクト作成時に
```

- php artisan migrate
- php artisan key:generate

# 手順4 DocumentRootをシンボリックリンクにする

DocumentRootを弄れなさげなので、/var/www/htmlをシンボリックリンクにして、/var/www/project/public/を参照する

- rm -rf /var/www/html/
- ln -s /var/www/project/public/ /var/www/html


# 手順5 プロジェクトの管理コンソールからURLを確認してアクセスしてみる
- https://\*\*\*\*\*\*\*\*.lolipop.io/

以上になります。
WordPressのサイトURLをドメイン直下に変更したい

# パーマリンク設定

1. WordPress管理画面から、**設定** > **一般** を開く
2. **サイトアドレス (URL)** のサブディレクトリ部分を削除  

変更前 
![wp_siteaddress_before.png](https://qiita-image-store.s3.amazonaws.com/0/139979/3f905ed3-bbeb-17e0-26cd-9318e85b46c9.png)  

変更後
![wp_siteaddress_after.png](https://qiita-image-store.s3.amazonaws.com/0/139979/1f3df89a-c56e-ae41-1216-828174e306a9.png)

# index.php と .htaccess
1. FTPクライアントなどでWordPressをインストールしているサーバにアクセス
2. インストールしたディレクトリにあるindex.phpを、ルートディレクトリにコピー  
3. ルートディレクトリへコピーしたindex.phpを編集  

変更前

```
/** Loads the WordPress Environment and Template */  
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
```

変更後

```
/** Loads the WordPress Environment and Template */  
require( dirname( __FILE__ ) . '/wp/wp-blog-header.php' );
```
4. ルートディレクトリに.htaccessを作成  

```
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
```

以上
Angular に Bootstrap4 を導入する

## 概要

Angular7 に Bootstrap 4 (ng-bootstrap ではないよ) を導入する時の備忘録

## 手順

### 事前確認

テストとして、以下のようなHTMLを表示した場合を想定。

```html
<h2>Angular に Bootstrap 導入</h2>

<div>
  <input type="text" placeholder="入力してください"/>
</div>
<div>
  <button class="btn btn-primary">ボタン</button>
</div>
```

導入前に画面を表示してみると、以下のような状態。

<img width="878" alt="スクリーンショット 2019-01-05 3.19.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/9091184c-3ba3-cdf1-fc3b-d1b9f1c56f82.png">

うむ。ダサい。

では導入していきましょう。

### インストール

依存するライブラリ（jQuery, Popper.js）も同時に入れましょう。

```bash
npm i bootstrap jquery popper.js
```

### angular.json に追記する

`"styles"` と `"scripts"` に、以下のとおりにライブラリの読み込みを追記する。
複数箇所あるので注意。

```json:angular.json
...
      "styles": [
        "client/styles.scss",
        "node_modules/bootstrap/dist/css/bootstrap.min.css"
      ],
      "scripts": [
        "node_modules/jquery/dist/jquery.slim.min.js",
        "node_modules/popper.js/dist/umd/popper.min.js",
        "node_modules/bootstrap/dist/js/bootstrap.min.js"
      ],
...
```

上記は、Angular7 の場合の記載。
Angular6 以前の場合は、`"../node_modules/bootstrap/dist/css/bootstrap.min.css"` のように `../` が先頭に付く。（変更箇所は一緒）


### 確認

これでアプリを再起動して画面表示してみると・・・。

<img width="879" alt="スクリーンショット 2019-01-05 3.38.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/29426abb-16fe-2f74-5dd4-c4fa5d060136.png">

うむ。変わりました。
このままではまだダサいですが、ちょっと配置など変えるだけで簡単にデザイン改善できます。

以上で導入は完了。
railsでデータをcreateしたときにフラッシュメッセージを出現させる

#はじめに
<img width="524" alt="スクリーンショット 2019-01-05 2.31.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/281558/e5ec15d3-cca3-b9d3-ab4b-8bc90b4ec443.png">
railsでデータを作成した時に↑のようなフラッシュメッセージを出したい時があると思います。　　　　
今回はフラッシュメッセージを出す方法について話したいと思います。　　　
※また、今回cssはbootstrapのものを使っています
#まずはコードから
```ruby:articles_controller.rb

#〜省略〜

def create
  @article = Article.new(article_params)
  if @article.save
    redirect_to @article, flash: { notice: '記事の作成が作成されました' }
  else
    redirect_to new_article_path
  end
end

#〜省略〜

```

```erb:show.html.erb
<% if flash[:notice] %>
  <div class="alert alert-primary" role="alert">
    <%= notice %>
  </div>
<% end %>
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>
<p>
  <strong>Content:</strong>
  <%= @article.content %>
</p>

<%= link_to '', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>

```

#解説
フラッシュメッセージを出現させるには２つの工程が必要です
１，flashを使ってメッセージを保管する(コントローラー側)
２，flashメッセージがあれば出現させる(ビュー側)


###そもそもflashってなんやねん！
flashというのはrailsのメソッドでユーザーのセッションに一時的にハッシュのようにキーとバリューのような形で保存されるものです。  
特徴としては、セッションは１度表示されると自動的に削除される点です。


##1,flashを使ってメッセージを保管する
flashを使ってメッセージを保管する方法は２種類あります  
またいずれの場合も ```notice``` をキー　```'記事の作成が作成されました'``` をバリューとしたセッションが保存されます

###1つ目
```
, flash: { notice: '記事の作成が作成されました' }
```
最初のコードのようにredirect_toのあとに以下のように記述する方法。　　

###２つ目
```
flash[:notice] = '記事の作成が作成されました'
```
シンプルにflashを使ってメッセージを保存する方法　　

この２つのいずれかの方法でセッションにメッセージを一時保存することができます。

##２，flashメッセージがあれば出現させる
flashメッセージは ```flash[:キー名]```　とすることでビュー側で値を取得することができます。  
これを使ってview側では以下のように記述することでflashメッセージを出現させています。

```
<% if flash[:notice] %>
  <div class="alert alert-primary" role="alert">
    <%= notice %>
  </div>
<% end %>
```

#まとめ
以上２つの工程をふむことでflashメッセージはかなり簡単に作成することができます。　　
とりあえず使ってみるのが大事です。
コマンドプロンプトを起点としたサクラエディタによる一括文字コード変換

今回、特定の拡張子のファイルをS-JISからUTF-8に変換するbatファイルを作成したので記述します。

###動作環境
- サクラエディタ　Ver. 2.2.0.1
- Windows10

###基本構想
サクラエディタのマクロでS-JISからUTF-8に変換を行います。
そしてコマンドプロンプトで、複数のファイルに対してサクラエディタマクロを適用します。

###ソース
```:サクラエディタのマクロ（convert_Fromsjis_Toutf8.mac）
//キーボードマクロのファイル
S_SelectAll(0);	// すべて選択
SJIStoUTF8(0);	// SJIS→UTF-8コード変換
FileSave( ); // 上書き保存
WinClose( ); // 閉じる
```


```:コマンドプロンプト（convert_Fromsjis_Toutf8.bat）
for /r %%f in (*.txt) do (call:convert_Fromsjis_Toutf8 %%f)
exit

REM -M=以下のURLはサクラエディタのマクロの配置場所に合わせて記述してください。
:convert_Fromsjis_Toutf8
"C:\Program Files (x86)\sakura\sakura.exe"  %1 -M=C:\hogehoge\convert_Fromsjis_Toutf8.mac
```

###参考HP
参考にしたのは以下のHPです。
サクラエディタ
http://sakura-editor.sourceforge.net/htmlhelp/HLP000001.html
サクラエディタのマクロをバッチファイルで複数ファイルに対して実行
https://akira2kun.hatenablog.com/entry/2018/09/16/103138
ゴミ箱の名前変更

自身の備忘録として、ゴミ箱の名前変更方法を記録しておきます。 
もし、興味ある方がいれば、[こちら](https://qiita.com/take-out-any/items/5e8ebb3e7e3ec89b649c)も合わせてどうぞ。  

## 環境
OS: Ubuntu 18.04
Desktop環境: LXDE

## 方法
1. 翻訳ファイル群のある以下のフォルダに移動する  

```shell
cd /usr/share/locale-langpack/ja/LC_MESSAGES
```

2. gvfs.moを編集できる形に変換  

```shell
sudo msgunfmt gvfs.mo -o gvfs-edit.po
```

3. Trashをゴミ箱に変更  

```shell
# 778行目
msgid "Trash"
msgstr "Gomibako"
```

4. gvfs-edit.poをバイナリ形式に変換  

```shell
sudo msgfmt gvfs-edit.po -o gvfs.mo
```

5. 再起動

## 考察
どうやら、デスクトップ上のゴミ箱はTrash:///という特殊なマウントによって表現されている様子。  
(マウント先は~/.local/Trash/filesっぽい。)  
そのマウントを司るのがgvfsというマウントアプリケーションなので、その翻訳ファイルを編集すれば表示文言を編集できるという仕組みらしい。
シェルスクリプトで自前オプション解析（POSIX準拠）

POSIX準拠のチェックはLinter（checkbashisms, shellcheck）頼りなのでちょっと自信ないですが。

```use_options.sh
#!/bin/sh
set -Ceu

usage() {
  cat <<EOS
Usage: ./use_options.sh [-fghsv] [-n=num] [-t text] files ...

Options:
  -f, --force
  -g, --global
  -h, --help
  -s, --silent
  -v, --version
  -n, --number
  -t, --text

Arguments:
  files

EOS
}

force_specified=0
global_specified=0
silent_specified=0
number_specified=0
number=0
text_specified=0
text=""
shift_count=0
checking_split_options=0

check_options() {
  [ $# -eq 0 ] && return 0
  case "$1" in
    -h | --help)
      usage
      exit 1
      ;;
    -v | --version)
      echo "1.0.0"
      exit 1
      ;;
    -f | --force)
      force_specified=1
      ;;
    -g | --global)
      global_specified=1
      ;;
    -s | --silent)
      silent_specified=1
      ;;
    -n* | --number*)
      number_specified=1
      if echo "$1" | grep -q ^-n=; then
        number=${1#-n=}
      elif echo "$1" | grep -q ^--number=; then
        number=${1#--number=}
      else
        echo "\"-n\" and \"--number\" should specified with number."
        echo
        usage
        exit 1
      fi
      ;;
    -t | --text)
      text_specified=1
      shift
      [ $checking_split_options -eq 0 ] && shift_count=$(($shift_count+1))
      if [ $# -eq 0 ] || [ $checking_split_options -ne 0 ]; then
        echo "\"-t\" and \"--text\" should specified with text."
        echo
        usage
        exit 1
      fi
      text="$1"
      ;;
    --)
      shift
      [ $checking_split_options -eq 0 ] && shift_count=$(($shift_count+1))
      return 0
      ;;
    --*)
      echo "Invalid option \"$1\""
      echo
      usage
      exit 1
      ;;
    -*)
      if [ ${#1} -le 2 ]; then
        echo "Invalid option \"$1\""
        echo
        usage
        exit 1
      else
        splitted="$(echo "${1#-}" | awk '{ gsub(/./,"-& ") ; print }')"
        checking_split_options=1
        check_options $splitted
        checking_split_options=0
      fi
      ;;
    *)
      return 0
      ;;
  esac
  shift
  [ $checking_split_options -eq 0 ] && shift_count=$(($shift_count+1))
  check_options "$@"
}
check_options "$@"

while [ $shift_count -gt 0 ]; do
  shift
  shift_count=$(($shift_count-1))
done

[ $force_specified -ne 0 ] && echo "force!"
[ $global_specified -ne 0 ] && echo "global!"
[ $silent_specified -ne 0 ] && echo "silent!"
[ $number_specified -ne 0 ] && echo "Number is ${number}."
[ $text_specified -ne 0 ] && echo "Text is ${text}."
for file; do
  echo "File is $file."
done
echo "以上、レポっす。"
```

```sh
$ ./use_options.sh -fgs -n="not a number" -t "Lorem ipsum" "Hi! file1" "Hi! file2"
force!
global!
silent!
Number is not a number.
Text is Lorem ipsum.
File is Hi! file1.
File is Hi! file2.
以上、レポっす。

$ ./use_options.sh -- -fgs -n="not a number" -t "Lorem ipsum" "Hi! file1" "Hi! file2"
File is -fgs.
File is -n=not a number.
File is -t.
File is Lorem ipsum.
File is Hi! file1.
File is Hi! file2.
以上、レポっす。
```

バグ見つけたら教えてください。
【抄訳／感想】PyCoder's Weekly #349 - 2019/01/01

Qiita よりも翻訳記事を掲載するのに適した媒体があれば移行するかもしれません。また、このような記事が Qiita の利用規約や法律に抵触する場合は取り下げますのでご指摘いただけると助かります (無知ですみません)。

# 免責
- 素人の翻訳です。正しさは保証しません。 **というかあまり訳す気がなく、ほぼ感想です**
    - しかも本文の翻訳と私の感想を区別する気があまりありません。どの部分が感想なのかは文脈から汲み取ってください・・・
- 抄訳です。自分が気になった記事だけを抜粋していますのでご注意ください
    - 選んだ記事の中でも更に抜粋があります
- 気が乗ったら毎回やりますが負担が大きいのでサボることが多いと思う

# バックナンバー
- [【抄訳／感想】PyCoder's Weekly #348 - 2018/12/25 - Qiita](https://qiita.com/keisuke-nakata/items/2637a77acd4a7351f195)

# PyCoder's Weekly とは
いくつかある Python 関連の週次ニュースレターのひとつ。
公式サイトと購読はこちら：https://pycoders.com/
<img width="927" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/62450/e4e02e47-f2b7-2afd-9ac7-321cef2a4c8e.png">

今週の記事は [PyCoder’s Weekly | Issue #349](https://pycoders.com/issues/349) です

# [Python String Formatting Best Practices – Real Python](https://realpython.com/python-string-formatting/)
- Python のいろんな文字列フォーマッティングの使い分けベストプラクティスについての記事
- 記事最後の図がわかりやすいと思う
    - ユーザ入力文字をフォーマットするなら `string.Template` で、Python 3.6+ なら f-string で、そうでなければ `str.format` でやれという結論。 `'%s' % 'yes'` は古い方式なので使わない

# [Inside python dict — an explorable explanation](https://just-taking-a-ride.com/inside_python_dict/chapter1.html)
- Python の辞書 (`dict`) の CPython における実装を理解する
    - Python の辞書、という体になっているけど、ハッシュテーブルとかの一般的な説明としてわかりやすいと思った
- CPython ではハッシュテーブルに linear probing が使われている
    - linear probing では空きスロットをヒットなしの判断に使うため、キーを削除するときは空きスロットにするのではなく「削除済み」オブジェクトで上書きする
        - かしこい
    - ハッシュテーブルをリサイズするときは、大きめのテーブルを再度作って再構築する
        - もちろんこのとき計算済みのハッシュや重複の排除処理を考える必要はない
        - 「削除済み」オブジェクトも必要ないのでテーブルの掃除もできる
        - 再構築は重い処理だが、挿入／削除の実行頻度を考えれば大きな問題ではない
Raspberry PiでBluetoothスピーカーを鳴らす

# 概要

スピーカーをRaspberry PiとBluetooth接続し、オーディオ出力する。
また、おまけとして、Raspberry Piでサイマルラジオを受信し、Bluetooth接続したスピーカーで再生する。

# 環境

* Raspberry Pi本体　※Bluetooth内蔵モデル(Pi Zero W)が望ましい
* SDカード　※Raspbian Stretch Liteにsshdを導入済みの4GB以上のもの
* Micro USB Micro-Bケーブル、または、Pi Zero USB Stem　※Raspberry Pi本体への電源供給方法
* Bluetooth Audio Receiverデバイス(MR230)　※以下、Bluetoothデバイス
* スピーカー　※3.5mmステレオミニプラグ(オス)入力対応

# 手順

1. Raspberry PiとBluetoothデバイスをペアリングする。

    ```
    $ sudo bluetoothctl
    [bluetooth]# scan on
    [bluetooth]# scan off
    [bluetooth]# trust E8:07:BF:xx:xx:xx
    [bluetooth]# pair E8:07:BF:xx:xx:xx
    [bluetooth]# connect E8:07:BF:xx:xx:xx
    [MR230]# paired-devices
    [MR230]# quit
    ```

1. BluetoothデバイスをALSAデバイスとして扱えるよう、[Bluetooth Audio ALSA Backend(以下、bluez-alsa)](https://github.com/Arkq/bluez-alsa)を導入する。

    ```
    $ sudo apt install bluealsa
    ```

1. `~/.asoundrc`ファイルにBluetoothデバイスを別名定義(bluealsaとbt-receiver)する。

    ```
    $ vi ~/.asoundrc
    defaults.bluealsa.interface "hci0"
    defaults.bluealsa.device "E8:07:BF:xx:xx:xx"
    defaults.bluealsa.profile "a2dp"
    defaults.bluealsa.delay 10000

    pcm.bt-receiver {
      type bluealsa
      device "E8:07:BF:F0:2F:31"
      profile "a2dp"
    }
    ```

1. `bluez-alsa`がBluetoothデバイスを認識していることを確認する。

    ```
$ amixer -D bluealsa
Simple mixer control 'MR230 - A2DP',0
  Capabilities: pvolume pswitch
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 127
  Mono:
  Front Left: Playback 127 [100%] [on]
  Front Right: Playback 127 [100%] [on]
    ```

1. `Simple mixer control`に続く文字列はBluetoothデバイスの識別子となるため、書き留めておくこと。ここでは、'`MR230 - A2DP`'である。
1. Bluetoothデバイス'`MR230 - A2DP`'のボリュームを`70%`に変更する。

    ```
    $ amixer -D bluealsa sset 'MR230 - A2DP' 70%
    ```

1. `mplayer`コマンドをインストールする。

    ```
    $ sudo apt install mplayer
    ```

1. `mplayer`コマンドでWAVファイルを再生し、Bluetoothデバイス(`bt-receiver`と別名定義)からオーディオ出力する。

    ```
    $ mplayer -ao alsa:device=bt-receiver /usr/share/sounds/alsa/Front_Center.wav
    ```

# サイマルラジオを聴く

※参考：[Raspberry Piをインターネットラジオ（radiko等）の再生環境にしたらとても快適だった！CUI操作編radikoやサイマルラジオを聞いてみよう！](https://iot-plus.net/make/raspi/play-internet-radio-cui/)

1. [サイマルラジオ](http://www.simulradio.info/)のページを開く。
1. 「放送を聴く![](http://www.simulradio.info/images/btn_radio.jpg "放送を聴く")」アイコンを右クリックし、プレイリストのURL(http://～/*.asx)を取得する。
1. 取得したプレイリストのURLを`-playlist`オプションに記述し、次のコマンドを実行する。

    ```
    $ mplayer -ao alsa:device=bt-receiver -playlist http://www.simulradio.info/asx/fmpalulun.asx
    ```

1. Bluetooth接続したスピーカーからサイマルラジオが流れる。
超初心者TypeScriptメモ

# 超初心者TypeScriptメモ

## 環境

```
$ npm list -g typescript
`-- typescript@3.2.2
```

```
tsc --version
Version 3.2.2
```

## TypeScript

### tsconfig.jsonを作る

```
tsc --init
```

* エラーが出る場合、グローバルのtypescriptとtscをuninstallして、typescriptだけ入れ直す

```
npm uninstall tsc -g
npm uninstall typescript -g
npm install typescript -g
```

### コンパイルする

```
tsc hoge.ts
```

### コンパイルする（lib指定）

```
tsc hoge.ts --lib es6,dom
```

コンパイル時に↓のようなエラー（例：TS2585）が出る場合等、libの指定が必要な時用
※`Try changing the lib compiler option to es2015 or later.` 云々

```
node_modules/@types/zen-observable/index.d.ts:36:14 - error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
```

### コンパイルする（tsconfig.jsonを使う）

```
tsc -p tsconfig.json
```

* この時、`lib`等の指定は`tsconfig.json`内で行う 
* ファイルの指定がしたい場合は`tsconfig.json`内の`files`を指定。
* ※↓みたいな感じ。

```json-doc:tsconfig.json内
{
    "compilerOptions": {
        /* ～略～ */
        "target": "es6",
        "module": "commonjs",
        "lib^": ["es6","dom"],
        /* ～略～ */
    },
    "files": ["hoge.ts"]
    }
}
```

### コンパイルすると`TS2580`が出る（Do you need to install type definitions for node?) 

↓のエラーが出る場合、

```
node_modules/aws-sdk/clients/firehose.d.ts:182:22 - error TS2580: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
```

↓の`npm install`を実行して、

```
npm i @types/node
```


tsconfig.jsonに`types`を追加する。

```json-doc:tsconfig.json
{
    "compilerOptions": {
        /* ～略～ */
        "types": ["node"],
        /* ～略～ */
    },
}
```

で、`tsconfig.json`を指定してコンパイルする。

```
tsc -p tsconfig.json
```
Bash on Windowsでfirebase-toolsがインストールできない

# Bash on Windowsでfirebase-toolsでインストール時にエラー
`sudo npm install -g firebase-tools`
実行時にCERT_UNTRUSTED(証明書エラー)が発生

# 結論
nパッケージを入れて、最新版npmを入れると成功した。
npmが古くて、証明書の確認フローのどこかでダメになっていた模様。

# 過程（ぼんやりした部分が多いので、参考程度に見てください)
## 1. しばらく触っていなかったので、ubuntu内で持っている証明書が古くなっている？
`sudo apt-get upgrade ca-certificates`
ubuntu(OS)のもっている証明書の更新？
→更新はされたがエラー発生状況変わらず。

## 2. 闇雲にapt-get upgradeを実行(本当はダメな気がする)
ubuntu-minimal(ubuntuのカーネル？)が更新保留となっている。
→そもそもubuntuのバージョンアップもしないといけない？

## 3. apt-get dist-upgrade(カーネルのupgradeを実行)
`sudo apt-get dist-upgrade`
実行するとubuntu-minimalの更新はできた。
→証明書を触ったわけではないので当然状況変わらず

## 4. npmのバージョンを確認。(手順2でupgradeは済んでいる)
`npm -v`
npmのバージョンが1.3ぐらいになっていた。
→公式確認すると現行最新は6.5.0っぽい。apt-getで取得してくるnpmでは最新が落ちてこない模様。

## 5. しばらくググっているとnpmでnパッケージというものを使えるらしいことが判明
参考：https://qiita.com/seibe/items/36cef7df85fe2cefa3ea

rubyでいうところのrbenv？nパッケージ経由でnpmを入れれば最新を入れられる模様。
現状入っているnpm経由でinstallするらしいのでコマンド実行

`sudo npm install -g n`
`sudo n stable`
→無事npm バージョン6.5.0に更新

## 6. firebase-toolsのインストール
`sudo npm install -g firebase-tools`
→成功


# まとめ
npm自体がルート証明書を持っていてそれが古かった？(期限切れ？)のか、証明書の確認処理が古かったのか結局わからず仕舞いですが、そのあたりでエラーになったのだと思います。

firebaseでちょこっと遊ぶつもりが色々と遠回りしてしまいました。。。
深堀りできていないところが多々あるので、いずれ追います。
そして大変雑な記事ですみません。
Raspberry PiとWEBカメラで洗濯機の動作状況をモニタリングして洗濯終了をLINEに通知するIoTボットを作ってみた

*本記事は、[2018年4月に別の場所へ書いた記事](https://cyclic-lab.blogspot.com/2018/04/raspberry-piweblineiot.html)の転載です*

# 概要
家の一階にある洗濯機で洗濯が終わったかどうかを、二階のリビングにいても分かるようにしたい！というわけで、タイトルのとおりです。

洗濯終了を判定するための手がかりとしては、洗濯終了時に鳴るビープ音、洗濯機の使用電力(電流)、などがありそうですが、今回は操作パネルの表示を使います。我が家の洗濯機には、操作パネルの中に洗濯終了時にだけ点灯する場所があったので、この場所の点灯状況で洗濯終了が自動判定できちゃいます。
![操作パネル](https://qiita-image-store.s3.amazonaws.com/0/336603/ddfa81e7-f7b8-109e-0830-dc5d4ca975f9.jpeg)
Raspberry PiにつないだWEBカメラで操作パネルの特定位置の点灯状況を判定するだけなんですが、操作パネルをうまく写せるカメラの固定場所があまりない、というのが実は問題です。ちょっと離れた場所から監視せざるを得ないので、向きをざっくり合わせるだけでも使える、とか、カメラが多少動いたりしても使える、とかするための工夫が必要です。
![WEBカメラ](https://qiita-image-store.s3.amazonaws.com/0/336603/70928203-5e83-c17d-0440-9edad20ba143.jpeg)

# 方針
というわけで、基本的な方針は以下の通り。点灯状況を監視したい場所の近くにARマーカーを貼って、これを基準に監視場所の画像を切り出して点灯状況の判定をするようにしました。

- ARマーカを点灯状況を監視すべき場所の近くに貼付
- WEBカメラで撮影した画像からARマーカを検出
- 検出したARマーカを基準に監視場所の画像を切り出して点灯判定
- 点灯していると判定された場合にはIFTTT経由でLINEに「洗濯が終わっています」を通知

# コード
Raspberry Pi用のPythonコードは以下に置いておきます。
[nikotan/WashingMonitor](https://github.com/nikotan/WashingMonitor)

# 動作
誤報対策で苦労しましたが、今は安定して動いてます。結構便利。
![LINE](https://qiita-image-store.s3.amazonaws.com/0/336603/0076b272-40b2-6e70-1bfd-5b1d1f09bfe5.jpeg)

# 参考
ARマーカーの検出のために使ったOpenCVのarucoライブラリや、arucoライブラリを使うためのRaspberry Pi上でのOpenCVのビルドや、IFTTTを使ったプッシュ通知などについては、以下記事を参考にしました。

- [【Pythonでプログラミング】arucoライブラリを使ってARマーカを認識してみた | 本日はおかてんなり](http://okatenari.com/2017/11/28/python-ar/)
- [ArUco マーカーの検出 - Qiita](https://qiita.com/mkisono/items/cfdb9b74e41fae2f59d0)
- [Raspberry Pi Zero W / OpenCV 3.x ArUcoも使える: マツドサイエンティスト・研究日誌](http://anoda.cocolog-nifty.com/mad/2017/08/raspberry-pi--4.html)
- [[RaspberryPi][python]温度センサー＋IFTTTで室温をLINEに知らせる - Qiita](https://qiita.com/jun1_0803/items/95cec2f149bdec82472d)
TyranoScriptの変数

## 変数の種類


 * sf: システム変数
 * tf: 一時変数
 * f: ゲーム変数

https://tyrano.jp/usage/tech/hensuu

## JavaScriptからの直接参照
* [tyranoscriptのソースコード](https://github.com/ShikemokuMK/tyranoscript/blob/14c740f7e68581192915c0602b04fd591ce2ba80/tyrano/plugins/kag/kag.js#L430-L432)を見ればわかるように、以下のようにアクセス参照可能。
 * TYRANO.kag.variable.sf
 * TYRANO.kag.variable.tf
 * TYRANO.kag.stat.f

## 関連リンク
* [変数の基礎知識 - ティラノスクリプト 製作テクニックwiki](http://tyrano.wiki.fc2.com/wiki/%E5%A4%89%E6%95%B0%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98)
* [変数関係 - ティラノスクリプト 製作テクニックwiki](http://tyrano.wiki.fc2.com/wiki/%E5%A4%89%E6%95%B0%E9%96%A2%E4%BF%82)
【AdobeXD】プラグイン開発3 I/O


# 書き出す
![rendition.png](https://qiita-image-store.s3.amazonaws.com/0/113504/08ef4bd0-cf1c-fd87-afd5-68137054c694.png "rendition.png")

![スクリーンショット 2018-11-29 22.55.27.png](https://qiita-image-store.s3.amazonaws.com/0/113504/414d64fd-84b9-ea6b-1fb7-d7305da01f54.png "スクリーンショット 2018-11-29 22.55.27.png")


```exportRendition.js
const application = require("application");
const fs = require("uxp").storage.localFileSystem;

// ダイアログを生成する
const showDialogY = (text) => { // ..(1)
    // create the dialog
    let dialog = document.createElement("dialog");

    // main container
    let container = document.createElement("div");
    container.style.minWidth = 400;
    container.style.padding = 40;

    // add content
    let title = document.createElement("h3");
    title.style.padding = 20;
    title.textContent = text;
    container.appendChild(title);

    // close button
    let closeButton = document.createElement("button");
    closeButton.textContent = "Yes";
    container.appendChild(closeButton);
    closeButton.onclick = (e) => {
        dialog.close();
    }

    document.body.appendChild(dialog);
    dialog.appendChild(container);
    dialog.showModal()
}

const handleExportRendition = async (selection) => { // ..(2)
    if (selection.items.length > 0) {
        const folder = await fs.getFolder();
        const file = await folder.createFile("rendition.png");

        let renditions = [{  // ..(3)
            node: selection.items[0],
            outputFile: file,
            type: application.RenditionType.PNG,
            scale: 2
        }];

        application.createRenditions(renditions) // (4)
            .then(results => {
                showDialogY(`PNG rendition has been saved at ${results[0].outputFile.nativePath}`);
            })
            .catch(error => {
                console.log(error);
            })
    }
}


module.exports = {
    commands: {
        "exportRendition": handleExportRendition
    }
};

```

選択したアイテムを書き出す。

(1) サンプルにダイアログの表示仕方があったので関数としてまとめる
(2) asyncを使うことでawaitが使える
(3) 書き出しの設定を作る
(4) 書き出す

書き出すときに上書きすることができなかった。ドキュメントには強制上書きと書いてあるが...

# テキストファイルを読み込む
![スクリーンショット 2018-12-02 1.28.12.png](https://qiita-image-store.s3.amazonaws.com/0/113504/386108de-625b-0d94-2a7a-4cabacb68cb6.png "スクリーンショット 2018-12-02 1.28.12.png")

テキストファイルから文字列をとってきて、それをXD内のノードとして扱う

```insertTextFromFile.js
const {Text, Color} = require("scenegraph");
const fs = require("uxp").storage.localFileSystem;

const insertTextFromFile = async (selection) =>{
    const aFile = await fs.getFileForOpening({ types: ["txt"]}); // ..(1)
    if(!aFile) return;

    const contents = await aFile.read(); // ..(2)

    const text = new Text();
    text.text = contents;
    text.styleRanges = [{
        length: contents.length,
        fill: new Color("#0000ff"),
        fontSize: 12
    }];

    selection.insertionParent.addChild(text);
    text.moveInParentCoordinates(10,30);
}
```

(1) ファイル選択ダイアログを表示してファイルを取得
(2) ファイルからテキストを読み込む

[Fileドキュメント](https://adobexdplatform.com/plugin-docs/reference/uxp/storage-index.html)
Webサイトを公開する前の準備

#まず、はじめに。
この記事は、Webサイトを公開する前に最低限しなければならないコーディングにおいての準備（というかそもそもWebサイトを作り始める時にしなければならないことな気がするけど）をまとめたものです。
投稿者本人が自分の備忘録として書いているため、一切解説していません。
Webデザイン・フロントエンドがちょいとできる方に、ふわっと参考になれば幸いです。
（間違っていたり分かりづらかったら、ごめんなさい:bow:）
※臨時更新予定

##参考
[ポートフォリオ](https://osawaeri.github.io/portfolio/)

#HTML

##01_HTMLを展開
`!`をEmmet（Tabキー）で展開

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```

##02_日本語のサイトにする
言語を日本語にする

```index.html
<html lang="ja">
```

##03_viewport
`head`タグ内に記述
`meta`タグ

```index.html
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
```

##04_説明文
ページの概要を記述
`meta`タグを`head`タグ内に記述

```index.html
<head>
    <meta name="description" content="ERIRIN PORTFOLIO">
</head>
```

##05_OGPタグ
`meta`タグを`head`タグ内に記述

```index.html
<head>
    <meta property="og:title" content="portfolio"　/>
    <meta property="og:type" content="website"　/>
    <meta property="og:description" content="ERIRIN PORTFOLIO"　/>
    <meta property="og:url" content="osawaeri.github.io/portfolio/"　/>
    <meta property="og:site_name" content="portfolio"　/>
    <meta property="og:image" content="images/thumbnail.png"　/>
</head>
```

##06_タイトル
`head`タグ内に記述

```index.html
<head>
    <title>portfolio</title>
</head>
```

##07_CSS
`head`タグ内に記述
`link`タグ

```index.html
<head>
    <link rel="stylesheet" href="css/style.css">
</head>
```

##08_ファビコン
`head`タグ内に記述
`link`タグ

```index.html
<head>
    <link rel="shortcut icon" href="images/favicon.png">
</head>
```

##09_JavaScript
`head`タグ内か`body`タグ最下部に記述
`script`タグ　※読み込み順に気をつける

```index.html
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
```

#CSS

##01_文字コードをセット
文字化けを防ぐために、1行目に記述

```style.css
@charset "UTF-8";
```
##02_CSSリセット
全てにかかってしまっている`margin`と`padding`をリセットする

```style.css
* {
    margin: 0;
    padding: 0;
}
```

##03_フォント
`@font-face`でフォントを読み込む

```style.css
@font-face {
    font-family: "DIN Alternate";
    src: url('../fonts/DIN Alternate Bold.ttf') format('truetype');
}
```

##04_Media Queries
それぞれブレイクポイントを作る

```style.css
@media screen and (min-width:最小値) and (max-width:最大値) {

}
```

###おまけ
デバイスを縦向きにしたとき

```style.css
@media screen and (orientation:portrait) {

}
```

#JavaScript

##01_jQuery

```script.js
$(function () {

});
```

##02_ページ読み込み時の実行
*なにかと読み込み時に実行させたいんだ。*

```script.js
$(function () {
    // JavaScriptの場合
    window.onload = function () {

    }
    // jQueryの場合
    $(window).on('load', function () {

    });
}
```

##03_デバイス判定
[こちらを参考にさせていただきました](https://qiita.com/torugatoru/items/2dc895d5db7fc839a8bc)

#終わり
参考にさせていただきました。
[HTML5&CSS3 デザインレシピ集](https://gihyo.jp/book/2017/978-4-7741-8780-8)
JetsonTX2で日本語入力（ibus-mozc）導入

# 環境
- Jetson TX2
- Jetpack 3.3
- Ubuntu 16.04

# 導入
Ubuntu 16.04 LTS（Xenial） arm64 ではmozc pkgがサポートされていないので、以下のサイトを参考にさせていただき、日本語入力できるようにしてみました。
参考）[Debian, Ubuntu で 上流のパッケージを借りてくる](https://matoken.org/blog/2018/10/23/debian-ubuntu-borrows-the-upstream-package/)

# 手順
Ubuntu 16.04 LTS（Xenial）arm64 ではmozc pkgがサポートされていないが、Ubuntu 18.04 LTS（Bionic）arm64 ではサポートされているらしいので、そのパッケージを借りてくる。
[Ubuntu – パッケージ検索結果 — mozc](https://packages.ubuntu.com/search?suite=bionic&arch=arm64&searchon=names&keywords=mozc) を見ていただくと、Bionicのarm64でIbus-mozcがサポートされていることを確認できる。

## 標準のリリースをxenialに設定

`/etc/apt/apt.conf.d/01ubuntu` に以下を記載する

```
APT::Default-Release "xenial";
```

## mozc をpinningする

`/etc/apt/preferences`に以下を記載する

```
Package: *mozc*
Pin: release n=xenial
Pin-Priority: -10

Package: *mozc*
Pin: release n=bionic
Pin-Priority: 900
```

## bionicを追加

`/etc/apt/sources.list` に以下を追記

```
deb http://ports.ubuntu.com/ bionic main universe
```


## パッケージ情報の更新
```
$ sudo apt update
```
検索結果にmozcが出てくる

```bash

$ apt-cache search mozc
mozc-data - Mozc input method - data files
ibus-mozc - Mozc engine for IBus - Client of the Mozc input method
mozc-server - Server of the Mozc input method
mozc-utils-gui - GUI utilities of the Mozc input method
emacs-mozc - Mozc for Emacs
emacs-mozc-bin - Helper module for emacs-mozc
fcitx-mozc - Mozc engine for fcitx - Client of the Mozc input method
uim-mozc - Mozc engine for uim - Client of the Mozc input method
```

## パッケージの導入

```bash

$ sudo apt-get install ibus-mozc
```
後はリブート!!!
Visual Studio 2017/2019 で Emacs キーバインド

Visual Studio 2012-2019 対応の Emacs Emulation 拡張機能（アドイン）が Marketplace にあるので入れてみます。

もともと Microsoft の拡張機能なのにオープンソースになっているのはなぜでしょう？
その経緯も調べてみます。

# インストール方法

1. Emacs Emulation を以下のリンクからダウンロードし、Visual Studio をすべて閉じてインストールする。
    - [Emacs Emulation 2][2] - Visual Studio 2017以降
    - [Emacs Emulation][1] - Visual Studio 2012, 2013, 2015
1. インストール後に Visual Studio を立ち上げると管理者権限を求めてくるので OK とする。
1. ツール > オプション > 環境 > キーボード > 「次の追加キーボードマップスキームを適用」 にて「Emacs」を選ぶ。
1. Visual Studio を再起動する。
1. （必要に応じて）キーバインドを追加・削除する。
    1. ツール > オプション > 環境 > キーボード > 「以下の文字列を含むコマンドを表示」で検索する。
    1. 「使用する場所」を「テキストエディタ―」とし、「ショートカットキー」の中にカーソルを入れて好きなキーを押す。
    1. 「割り当て」を押して確定する。

(2019.11.26) コメント欄でigiyさんに最新版があることを指摘いただいたのでリンクを更新しました。


# オープンソース化の経緯

オープンソース化されているようですが、ライセンスはどうなっているのでしょうか。

Visual Studio 2008 では標準で Emacs キーバインドを選べました。
Visual Studio 2010 では標準機能から外れ、[Microsoft 提供の拡張機能 (Emacs Emulation)](https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.Emacsemulation) になりました。　
この VS2010 の拡張機能はそれ以降のバージョンに対応しませんでしたが、vsix を編集することで新しいバージョンにもインストールする方法があり、[Qiita の記事](https://qiita.com/hatsunetsu7/items/4dcff17caca3e841a142)でも紹介されています。

一方、2014年に Satya Nadella氏がCEOになりオープンソースに力を入れだしたころ、Microsoft 内の Technical Evangelism and Development チームにいた Brad Merrill氏が社内で働きかけて、VS2010 用 Emacs Emulation のオリジナルソースコードをオープンソース化するのにこぎつけたようです（[Merrill氏による解説](http://zbrad.github.io/tools/EmacsKeys/)。以下はその抜粋）。

> After tracking down the Visual Studio “owners” and getting all the appropriate legal sign-off this release is finally ready.

そのコードは https://github.com/zbrad/EmacsKeys にて MITライセンスで公開されることとなりました（最初のコミットがVS2010 用のオリジナル版）。

さらに、現在はフォークされたコードが Justin Clareburt氏によって https://github.com/justcla/EmacsKeys でメンテされています。

[本記事で紹介したアドイン][2]は、この Clareburt氏メンテのものになります（以下、Market Place の説明より抜粋）。

> The code was originally open-sourced here: https://github.com/zbrad/EmacsKeys
> This version is being maintained on the justcla fork: https://github.com/justcla/EmacsKeys


[1]:https://marketplace.visualstudio.com/items?itemName=JustinClareburtMSFT.EmacsEmulation
[2]:https://marketplace.visualstudio.com/items?itemName=JustinClareburtMSFT.EmacsEmulation2
初めてのVulkanプログラミング step2 layer


[目次に戻る](https://qiita.com/tositada_nakada/items/db0f01c1c8c2945f786b)

ソースコードは以下の場所に置いておきます。各自のバージョンに合わせたプロパティ設定をしてから自由にご利用ください。
[github:  VulknAppAdocal2018](https://github.com/nakadasanda/vulkanAppaddcal2018)
##validition layerとは
LunerG Vulkan SDKには、数多くのデバッグ用のレイヤーがあります。公式の説明書では、すべてvalidition layerと書かれています。
vulkanは最小限のオーバヘッドに基づいて設計されており、そのためAPI内のエラーチェックは、最小限に限定されています。そのため単純なミスでも通常は、処理されず未定義の動作や、クラッシュなどがおきます。vulkanでは、自分が行っている操作機能について非常に明示的に宣言する必要があるため、GPUの新しい機能を利用するときや、デバイスを宣言するときなどにミスをする可能性が高いです。

しかし、vulkanのAPIが最小限に限られているのならば新しくエラーをチェックするAPIを追加すればいいのです。これがvalidition layerです。validition layerでの主な機能は、以下のようなものです。

・仕様に対するパラメータをチェックして誤用のチェック
・リソースリークを見つけるためのオブジェクトの破壊と生成の追跡
・呼び出し元のスレッドを追跡してスレッドの安全性を監視
・すべての呼び出しとその呼び出しを標準出力に入力
・vulkanをトレースしてプロファイリングの再生を要求


validition layerはインストールされたPCでしか実行できません。そのためリリース時には、無効化する必要があります。
有効化については、前記事で書いてあるのでご覧ください
## 使用できる layerの確認
layerがデバイスで使用できるか、確認する必要があります。

```cpp
	uint32_t layer_count = 0;
	vkEnumerateInstanceLayerProperties(&layer_count, nullptr);

	std::vector<VkLayerProperties> layers(layer_count);

	vkEnumerateInstanceLayerProperties(&layer_count, layers.data());

	std::cout << "Amount of Layers " << layer_count << std::endl;
	std::cout << std::endl;
	for (int i = 0; i < layer_count; i++) {
		std::cout << std::endl;
		std::cout << "layerName:            " << layers[i].layerName << std::endl;
		std::cout << "specVersion:          " << layers[i].specVersion << std::endl;
		std::cout << "implementationVersion:" << layers[i].implementationVersion << std::endl;
		std::cout << "description:          " << layers[i].description << std::endl;
	}
```

## validition layer を使う

```cpp
	const std::vector<const char*>validationLayers = {
		"VK_LAYER_LUNARG_standard_validation"
	};
     //...省略
	instance_create_info.enabledExtensionCount = validationLayers.size();
	instance_create_info.ppEnabledLayerNames = validationLayers.data();
	instance_create_info.enabledExtensionCount = 0;
	instance_create_info.ppEnabledExtensionNames = nullptr;
```
今回新しくExtensionを追加しました。Extensionについては、また後日説明します。一応定義しないと、エラーが起きるので定義しておきます。エラーを読みたい方は、一度コメントアウトしてみたらいいと思います。



vulkan標準のvalidition layerを使う方法を説明します。
validition layerを使うには、レイヤーの名前を指定して有効にします。
validition layerは、明示的に名前をしてあげる必要がなく

```
VK_LAYER_LUNARG_standard_validation
```
上のレイヤーを指定すると以下のレイヤーがすべてロードされます。

```
     VK_LAYER_GOOGLE_threading
     VK_LAYER_LUNARG_parameter_validation
     VK_LAYER_LUNARG_device_limits
     VK_LAYER_LUNARG_object_tracker
     VK_LAYER_LUNARG_image
     VK_LAYER_LUNARG_core_validation
     VK_LAYER_LUNARG_swapchain
     VK_LAYER_GOOGLE_unique_objects
```
##最後に
自分もこの記事を書くにあたって何度もたくさんのエラーコードとにらめっこしています。この記事についてよくわからないエラーを吐かれたら軽い気持ちでコメントに書いて下さい

## 連絡先

tweeter: [tositada_nakada](https://twitter.com/nakadasanda17)
mail: nakadasanda@outlook.com

## 寄付

paypal: [tositada_nakada](https://www.paypal.me/nakadasanda)
Amazon: [欲しいものリスト](http://amzn.asia/fGpGuJo)
備忘録(デバッグ/JS)

#はじめに
某エンジニア養成学校に通って一ヶ月とちょっと。
金曜ロードショーのナウシカを横目に見つつ、今後気をつけようと思うことを備忘録も兼ねて書いてみる。
アウトプットすることで理解も深まるし、自分がわかってないところも明確になるし。
基礎的なことばかりだけど。


##グローバル変数を使いすぎない
優先順位：ローカル変数　＞　グローバル変数
よくわかってないまま、とりあえずグローバル変数として宣言してしまったけど
関数の中で閉じられるのであればローカル変数を利用する。デバッグがしんどくなるイメージ。
もちろんメリットもあるので、適宜利用箇所を見極める。
ほら怖くない、怖くないよ。

グローバル変数のデメリット
・変数の衝突が起こりやすい
・変数の値がいつ変化するか読み取りづらくなる

グローバル変数のメリット
・引数や戻り値が多くなる場合はグローバル変数を利用したほうが明らかに処理が簡潔になることもある
　//まだ実感したことないけど
出典「新訂新C言語入門シニア編」

グローバル変数、ローカル変数って何？というひとはこの辺を読むといいかも
「ローカル変数」と「グローバル変数」の違い
https://wa3.i-3-i.info/diff73hensu.html

(2019/01/05 追記)
ありがたいことにコメントを頂いたので追記。

>最近の言語では引数や戻り値が多くても簡潔に処理を記述できるようになっています。
>また、引数や戻り値としてグローバル変数を使うのはコードの可読性やデバッグのしやすさの観点からも、避けるべきです。



##デバッグのしやすさを意識する
処理を肥大化させないに尽きると思った。
ある条件を満たさない限り、その画面に遷移しないみたいな処理を作り込んでいたけど、
デバッグがめちゃくちゃ面倒だった。毎回リロードしてやり直すみたいな。
でかい塊で作り込むとどこが正しい処理をしているかが分かりづらくなるから、なるべくコンパクトに作ればデバッグが楽になる（と思われる）。
ただ、あんまりコンパクトにしすぎても分かりづらいんだろうけど。塩梅が難しいよね。

##デバッグで気をつけること
大学時代の教科書を読んでたら、書いてあったのでメモとして残しておく。
1. たくさんエラーが出ても気にすることなく、一番最初に出ているエラーに注目せよ。これを修正するだけで、全て消えることもある。
2. エラーの出ている英語は全て辞書で引くなりして、意味として理解することを心がけよ。
3. ファイルの最終行にエラーが出ている場合は、閉じ括弧の数、あるいは、コメントの閉じ方が間違っている。
4. 変数を宣言しているのに、変数が宣言されていないというエラーが出ている場合にも閉じ括弧の数、あるいは、コメントの閉じ方が間違っている。


##今度読んでみよう
コレを書いてる最中に見つけた面白そうな記事。
・JavaScript初級者から中級者になろう
https://uhyohyo.net/javascript/
・ネストの深さは闇の深さ
https://qiita.com/DeployCat/items/1ec901864d4ab11c8d6f

##よくわからない単語
・Ajax
・非同期処理
次回まとめてみる