OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 18.04での初期設定メモ

## 初期設定
### 日本語ディレクトリの英語化
* 日本語ディレクトリ内にファイルやディレクトリがあると日本語ディレクトリが残るので注意。
* 以下のコマンドで変更する。

```terminal
LANG=C xdg-user-dirs-gtk-update
```

### NTPサーバの設定
* 「/etc/systemd/timesyncd.conf」ファイルにNTPサーバのURLやIPアドレスを設定する。

```timesyncd.conf
NTP=ntp.nict.jp
```

### 日本語追加パッケージ
```terminal
sudo apt install gnome-user-docs-de gnome-getting-started-docs-it ibus-table-wubi hunspell-pt-br gnome-user-docs-fr \
hunspell-de-de-frami hyphen-pt-pt hyphen-pt-br hyphen-es ibus-libpinyin hunspell-es hyphen-en-gb libreoffice-help-ja \
gnome-user-docs-ru ibus-mozc language-pack-gnome-ja mythes-es fonts-noto-cjk-extra gnome-getting-started-docs-pt \
thunderbird-locale-ja hunspell-en-au gnome-user-docs-es hunspell-de-ch-frami gnome-getting-started-docs-ru \
gnome-getting-started-docs-fr libreoffice-l10n-ja gnome-user-docs-it gnome-getting-started-docs-de \
gnome-user-docs-zh-hans gnome-user-docs-ja firefox-locale-ja hunspell-de-at-frami gnome-user-docs-pt mythes-pt-pt \
gnome-getting-started-docs-es language-pack-ja hunspell-pt-pt gnome-getting-started-docs-ja
```

## 参考
[Ubuntu 18.04 / 16.04 で時刻合わせの設定を変更する - Sickly Life Blog](https://sicklylife.hatenablog.com/entry/2016/02/03/201557)
python jupyter notebookでmecabを使用するときに覚えておくと便利なこと

自分用


デフォルトの辞書設定

```ruby:usr/local/etc/mecabrc

dicdir =  /usr/local/lib/mecab/dic/mecab-ipadic-neologd
```



一時的に別の辞書を使いたいときは

```python:~.ipynd
import MeCab
 mecab = MeCab.Tagger(' -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
```
みたいな感じでオプションで指定
質疑応答アプリ「ama」を動かしてみる

このまえの[Railsdm](https://railsdm.github.io/)で発表への質問を受け付けるのに使われてた「ama」というアプリが良さげだったので、試しに手元で動かしてみた。

- Railsdmのama: https://railsdm.herokuapp.com/
- Githubリポジトリ: https://github.com/yhirano55/ama

ほとんど`README.md`に書かれてるとおりにやればいいけど、自分のメモのために書いておく。

# ローカルで動かす

Ruby 2.6.1とPostgreSQLが必要なのであらかじめセットアップしておく。

rbenvを使っているなら、Ruby 2.6.1を使うように設定。

```
$ rbenv local 2.6.1
```

DB接続情報を`.env`に設定:

```:.env
DATABASE_HOST=127.0.0.1
DATABASE_USERNAME=postgres
```

(好みで)gemをアプリ配下にインストールするように設定:

```
$ bundle config --local path .bundle
```

setupコマンド実行:

```
$ bin/setup
```

Github認証の設定。

- https://github.com/settings/developers にアクセス
- 「New OAuth App」をクリック
- 以下のように入力
    - Application name
        - 任意
    - Authorization callback URL
        - http://localhost:3000/
    - Application description
        - 任意
    - Authorization callback URL
        - http://localhost:3000/auth/github/callback
        - `config/routes.rb`に記載されているのでそれに合わせる
-  「Register Application」をクリック

アプリが登録されて、Client IDとClient Secretが発行されるので`.env`に追記:

```:.env
GITHUB_OAUTH_CLIENT_KEY=xxx
GITHUB_OAUTH_CLIENT_SECRET=xxx
```

以上で設定完了。railsサーバを起動する:

```
$ bin/rails s
```

ブラウザで http://localhost:3000/ にアクセスするとトップページが表示される。

# Dockerで動かす

イメージをビルド:

```
$ docker-compose build
```

setupコマンド実行:

```
$ docker-compose run --rm app bin/setup
```

ローカル実行時と同じようにGithub認証を設定。

起動:

```
$ docker-compose up -d
```

ブラウザで http://localhost:3000/ にアクセスするとトップページが表示される。

# 管理者権限をつける

`users`テーブルの`role`列に1(admin)を設定すると管理者になる。
rails consoleで設定するならこんなかんじ:

```
$ bin/rails c
> user = User.find_by(nickname: 'okonomi')
> user.role = 'admin'
> user.save
```

管理者になると、Issueの新規作成・編集・削除ができたり、他の人のコメントの編集・削除ができるようになる。
Railsチュートリアル　第1章（ゼロからデプロイまで）①

気になった言葉や、
メモしておきたい点を記述しておくとします。

#＜メモ＞

・相対パスと絶対パス
相対パス：今いる場所を基準にして目的地がどこにあるかを伝える。
絶対パス：URLで指定して目的地を確実に伝える。


#Railsチュートリアル　　第1章

Rubyドキュメントのインストールに数分ほどかかることがあるので、
エンジニアの間ではよくある設定の1つである以下のコマンドを打つ。
（環境はcloud９）

```$ printf "install: --no-rdoc --no-ri\nupdate:  --no-rdoc --no-ri\n" >> ~/.gemrc
```

Railsをインストールするためにgemコマンドを使う。

```$ gem install rails -v 5.1.6
```
↑
この場合はバージョンを指定している。

-v というオプションを使うことで、
インストールされるRailsのバージョンを正確に指定できるようになる。


どんなRailsアプリケーションも最初の作成手順は基本的に同じで、
rails newコマンドを実行して作成する。

ただし、cloudIDEを使わない場合には
Railsプロジェクトで使うためのenvironmentディレクトリを作成しておく。

```$ cd                  # ホームディレクトリに移動する
$ mkdir environment     # 'environment' ディレクトリを作成する
$ cd environment/       # 'environment' ディレクトリに移動する
```
↑
UNIXコマンドを使う。
UNIXコマンドに関してはドットインストールが大変わかりやすかった。

話を戻して、
Railsアプリケーションを新規作成したら、
次はBundlerを実行して、アプリケーションに必要なgemをインストールする。
（ここではgemを変更して再度実行する）

・
・
・
railsサーバー起動まではとくに詰まらずできたので記述を省く。


#〜MVCの仕組み〜
RailsはMVC (model-view-controller) という
アーキテクチャパターンを採用している。

MVCでは、
アプリケーション内のデータ（ユーザー情報など）と、
データを表示するコードを分離する。

流れとしては、
ブラウザは一般的にWebサーバーにリクエスト (request) を送信。
→リクエストを処理する役割を担っているRailsのコントローラ (controller) に渡す。
（→）コントローラは、場合によっては
　すぐにビュー (view) を生成してHTMLをブラウザに送り返す。
→動的なサイトでは、一般にコントローラは (ユーザーなどの) サイトの要素を表していて、
　データベースとの通信を担当している
　Rubyのオブジェクトであるモデル (model) と対話してモデルを呼び出した後、
　コントローラは、ビューを描画し、完成したWebページをHTMLとしてブラウザに返す。

・
・
・
hello, world!の表示もとくに問題なくできるようになったので
記述は省く。
（始めにうまくhello, world!が表示できなかったが、
　原因としてはRunをしていなかったことであった。
　→cloud９のことを調べ直して解決）
Auto Scalingについてまとめてみた

# Auto Scaling
AWSの特徴の一つでもある伸縮自在性を実現する機能がAuto Scalingです。  
Auto Scalingは、EC2インスタンスでAuto Scalingグループというグループを構成し、設定に従って自動的にEC2インスタンスの台数を増減させることができます。  
※使用料金は無料でコストはAuto Scalingによって起動したインスタンス料金のみ  

## ユースケース
1. 負荷に基づいた利用  
Webサイトへのアクセス数が増減するケース  

1. スケジュールに基づいた利用  
チケット販売などで販売開始時刻が決まっているWebサイト  

1. 正常なEC2インスタンスの台数を維持するための利用
数分のダウンタイムは許容される1台構成のシステム  

## 設定項目

１. 起動設定(Launch Configuration)  
「どんなEC2インスタンスを起動するか」という設定項目です。  
Auto ScalingでEC2インスタンスを増やす際の起動設定で次の項目を設定します。  

- AMI
- インスタンスタイプ
- IAMロール
- Cloud Watch 詳細モニタリング
- ユーザデータ
- IPアドレス
- ストレージ
- セキュリティグループ
- キーペア など

２. Auto Scaling Group  
「どこにどんな規模のグループ」という設定項目です。  
EC2インスタンスが起動するサブネットや特定のELBの配下などどこにという項目の他、最小/最大台数などグループの規模を決める設定で次の項目を設定します。  

- スタートのグループサイズ(初期インスタンス数)
- サブネット
- ELB(ヘルスチェック設定含む)
- 最小/最大グループサイズ(インスタンス数) など

３. Auto Scaling ポリシー  
「いつ、何台増減させるか」という設定項目です。  
例えば負荷に基づくスケーリングであれば、CPU使用率のCloudWatchアラームを設定しておき、OKからアラームに状態遷移した際にアクションとしてAuto Scaling ポリシーを呼び出します。  

- アラームXが発生した際(OKからアラームに状態遷移した際)
- N台追加/削除
- 猶予時間(インスタンス増減後に次の増減が発生するまでのクールダウン時間)

## Auto Scaling における大原則
Auto Scaling には二つの大原則があります。
一つ目は正常なEC2インスタンスを希望する台数維持するため、インスタンスへのヘルスチェックをかけていることを理解すること。  
二つ目はAuto Scaling グループが複数のAZにまたがる時、AZ間でEC2インスタンス数を均等にしてくれるよう考慮されていることです。
#jq コマンドで特定の文字列を含むオブジェクトを検索する例

```shell
$ echo '{"title":"abc"}' | jq 'select(.["title"] | contains("a"))

{
  "title": "abc"

}
```


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
google-cloud-storageでGCEからGCS（GoogleCloudStorage）へのアップロードができないエラー


## エラー内容
Google Compute Engine（GCE）インスタンスから、google-cloud-storageを利用して、Google Cloud Storage（GCS）へファイルアップロードを実行。

```post_gcs.py
from google.cloud import storage
import os 

os.environ["GOOGLE_APPLICATION_CREDIENTIALS"] = 'CREDIENTILS.json'
client = storage.Client("PROJECT_ID")
bucket = client.get_bucket("BUCKET_NAME")
blob = bucket.blob("CSV_FILE")
blob.upload_from_filename(filename="FILE_NAME")
```

しかし、以下のエラーが返ってきてアップロードが成功しない。

```
Traceback (most recent call last):
  File "getjson.py", line 108, in <module>
    get_audio_features(sp, search_word)
  File "getjson.py", line 86, in get_audio_features
    blob.upload_from_filename(filename='df-audio-features/audio_features_{}.csv'.format(search_word))
  File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1140, in upload_from_filename
    predefined_acl=predefined_acl,
  File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1089, in upload_from_file
    _raise_from_invalid_response(exc)
  File "/root/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages/google/cloud/storage/blob.py", line 1960, in _raise_from_invalid_response
    raise exceptions.from_http_status(response.status_code, message, response=response)
google.api_core.exceptions.Forbidden: 403 POST https://www.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=multipart: ('Request failed with status code', 403, 'Expected one of', <HTTPStatus.OK: 200>)
```
## 原因
調べたところ、インスタンスはデフォルトのスコープが、ストレージ（GCS）に関して「読み取り」のみになっている様子。

<img width="1254" alt="scope変更前.png" src="https://qiita-image-store.s3.amazonaws.com/0/79258/3937a9a4-11d5-4005-395b-3aa99901809f.png">

## 解決
以下のコマンドにより、該当のインスタンスにGCSへの書き込みのスコープを付与する。

```
gcloud beta compute instances set-scopes projects/プロジェクトID/zones/利用ゾーン名/instances/インスタンス名 --service-account サービスアカウント --scopes https://www.googleapis.com/auth/devstorage.read_write
```
* 参考：https://qiita.com/Sekky0905/items/e1ae602a1a2a4edb17df
* アカウントIDはインスタンスのページから確認可能です。

上記のコマンドを実行、しかし以下のエラーが返ってくる。
<img width="659" alt="instance_must_be_stopped.png" src="https://qiita-image-store.s3.amazonaws.com/0/79258/e0e17370-3423-b594-1742-504407fc26e4.png">

エラー文によると、スコープの変更を実行する際には、インスタンスを停止する必要があるとのこと。インスタンスを停止した状態で実行したら、コマンドが通りました。
<img width="1239" alt="scope変更後.png" src="https://qiita-image-store.s3.amazonaws.com/0/79258/466d9d87-f1c0-62ff-55ff-e6071b3ebdcd.png">

その後、上記したpythonコードにてGCSへのファイルアップロードが成功しました。
ELBについてまとめてみた

# ELB
EC2はマネージド型の負荷分散サービスで、受信したトラフィックをELB配下に配置された複数のEC2インスタンスに分散します。  
ELBには次のような機能があります。  

## ELBの機能
1. 複数のAZにまたがる負荷分散  
ELBでは受信したトラフィックを複数のAZにまたがって負荷分散することができます。  
これにより複数のAZにEC2インスタンスを冗長てきに配置し、可用性の高いシステムを構築することができます。  

1. EC2インスタンスのヘルスチェック  
ELBは配下に配置されているEC2インスタンスのヘルスチェックを定期的に実行しています。  
異常を検知するとそのインスタンスに対してはトラフィックの分散をやめ、残りの正常なインスタンスにのみトラフィックを分散します。  

1. ELB自体の自動スケーリング
ELBは受信するトラフィックの流量に合わせて、自動的にその実体を増減させます。  
ELBを作成するとDNS名が作られ、ELBの実体がもつIPアドレスと名前解決されます。  
トラフィックの流量に合わせELBの実体が増減した際は新たなIPアドレスとの名前解決や関連付け削除が実施されます。  
そのため、ELBを利用したシステムではELBの実体のIPアドレスが分かったとしてもIPアドレスは使わずにDNS名を使用します。  
※ELBの実体に割り当てられるIPアドレスはVPCのサブネット内のIPアドレスとなる  

1. SSLのオフロード
クライアントとAWS上のシステムの間でSSL通信したい場合、SSL証明書は各EC2インスタンスに配置するのではなく、ELBに配置して一元管理することができます。  

1. Connection Draining
ELB配下のEC2インスタンスの登録解除をするときに、新規のリクエストについてはそのインスタンスへのトラフィックの送信を停止し、
登録解除前にそのインスタンスで処理中だったリクエストについては完了まで待つようにする機能です。  
Connection Drainingを有効にしておけば、EC2インスタンスをメンテナンスのためにELBの配下から登録解除する際にクライアントのリクエスト処理が中断されてしまうことがなくなります。  

1. アクセスログ記録
ELBにはアクセスログ収集機能があり、ELBに送信されたアクセスログをS3に保存することでアクセスログを一元管理することができます。  

1. スティッキーセッション
システムにアクセスしているクライアントを特定のEC2インスタンスに紐付けできる機能です。  
ELB配下に複数のインスタンスが紐づけられている場合に、一つのインスタンスでは認証が済んでいるのに、
次のリクエストではまだ認証が済んでいないインスタンスにリクエストが送信され再度認証を要求されることを防ぐことができます。  
先に認証が済んでいるインスタンスとクライアントとを紐付け、以降のリクエストもそのインスタンスに送信されます。  
※新たなインスタンスが追加されても、各クライアントが特定のインスタンスと紐付いており、適切に負荷分散が行われないため注意が必要
[Vue.js/Nuxt.js] v-forで中の要素にcomputedを使いたいときはコンポーネント分割をしよう

## 概要

Vueの算出プロパティであるcomputedは引数を持つことができず、v-forで回しているArray[Index]のような一部の要素のみを指定することができない。

一応、methodsに書いて呼び出すことで擬似的に動作させることは可能だが、状態が変わったときに再計算が行われないのが結構落とし穴である。

以下のコードは、コメント一覧画面でv-forでArrayのコメント一覧を回し、コメント１つ１つに対して閲覧者であるユーザのコメントがあったらそのコメントのみModifierのclassを付与したいという場合のサンプルコードである。

## 動作しないコード

computedは引数を持つことができないので、以下のコードはエラーとなる。

```vuejs:Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <p class="comments__comment" :class="isUserPostClass(comment)"/>
  </div>
</temlate>

~省略
  computed: {
    isUserPostClass(comment) {
      return comment.isUserPost ? 'comments__comment--user-post' : '';
    }
  }
~省略
```

## 動作するが良くないコード

methodsに定義すれば引数を取得でき、動きはするが再計算がされないので複数回の描画の際に積む。
(たとえば、クリックしたらそのコメントが強調されるようにしたいなどの要件に対応できない）


```vuejs:Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <p class="comments__comment" :class="isUserPostClass(comment)"/>
  </div>
</temlate>

~省略
  methods: {
    isUserPostClass(comment) {
      return comment.isUserPost ? 'comments__comment--user-post' : '';
    }
  }
~省略
```

## 解決策

ではどうすればいいのかと言うと、タイトルにもある通りv-forの中身だけをコンポーネント分割すればOKである。
今回はコメント一覧画面なので、コメント単体のコンポーネントを作成し、propsにｖ−forで回しているコメントのObject、および変更を検知させて再計算させたいプロパティをを与えてあげれば問題ない。

その後、コメントコンポーネントの中でcomputedを定義すれば、v-forの中身でcomputedを使うことができる。

## 動作するコード

```vuejs:Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <UserComment :comment="comment" :isUserPost="comment.isUserPost" />
  </div>
</temlate>
```

```vuejs:UserComment.Vue
<template>
  <div class="user-comment" :class="isUserPostClass">
     ~内容~
  </div>
</temlate>

~省略
  props: {
    comment: {
      type: Object,
      default: null
    },
    isUserPost: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    isUserPostClass() {
      return this.isUserPost ? 'user-comment--user-post' : '';
    }
  }
~省略

```

## まとめ

- v-forの中でcomputedを使いたくなったら、ループ対象であるDOMをコンポーネント分割しよう
- computedでプロパティの内容が変わったときの再計算処理を走らせるためには、明示的にpropsとして渡したほうが安全
bash変数のあれこれ

## 変数のスコープ
```bash

#/bin/sh
#
# コマンドを発行し、とある文字列を検索する
#
do_cmd_grep () {
  local CMD=$1 # 関数内ローカル変数として定義
  local STR=$2
  echo "#DBG#" ${CMD}
  echo "#DBG#" ${STR}
# localを付けないと、同一シェル内でグロール
  ret_cmd_grep=`${CMD} | grep ${STR} | wc -l`
}

do_cmd_grep "netstat -nr" "^0.0.0.0"
echo ${ret_cmd_grep}
echo "cmd is " $CMD
```

##  シェル変数の展開

```bash
name=/var/log/boot.log
     ーーーーー＞        boot.log      ${name##*/}  basename
             ＜ーーーー　/var/log      ${name%/*}   dirname 
                  ＜ー　/var/log/boot ${name%.*}   拡張子なし
     ーーーーーーーー＞   log           ${name##*.}  拡張子
# 拡張子変更 /var/log/boot.txt
${name%.log}.txt 
```

### 1.部分文字列（ゼロオリジン）
```bash

  ${var:n:n}   ※  ${var:offset:length}
  ${var:n}
```
ここでのn:nはoffset:lengthとなり、変数varのn番目からn個の文学が展開される。
lengthが省略された場合、(offset)番目から最後までが展開される。

### 2.先頭からマッチした部分を削除する。

```bash
  ${var#pattern}
  ${var##pattern}
```

varの値の先頭からpatternにマッチする部分が削除された状態で展開される。
＃一つの場合は最短一致、＃＃二つは最長一致となる。patternにはパス名の展開と同じ規則
が適用される。

### 3.後ろからマッチした部分までを削除　→　拡張子の変更

```bash
  ${var%pattern}
  ${var%%pattern}
```

＃と逆でvarの値の後ろからpatternにマッチする部分が削除された状態で展開される。
%の場合は最短一致、%%は最長一致となる。patternにはパス名の展開と同じ規則が適用される。

```bash
  OTF=${INF%m4a}mp3
  OTF=`echo $INF | sed s/mkv$/mp4/`
```

### 4.置換

```bash
  ${var/pattern/str}      最初だけ置換
  ${var//pattern/str}     全部置換
  ${var/pattern}          パターンを削除
  ${var//pattern}         パターンを削除
```

varの値のうちpatternにマッチする部分がstrに置換された状態で展開される。
/の場合は最初にマッチした部分のみが、//の場合はマッチする部分すべてが置き換えられる。

## 初期値

[ Refs ](https://qiita.com/minanon/items/d3c7dd0a74ea4f455551)
|					| hoge |：＋ | ＋ | ：ー | ー |
| --- | --- | --- | --- | --- | --- |
|定義済＆ notNULL	|hoge="Hello" |変更	|変更	|そのまま	|そのまま |
|定義済＆ Null		|hoge="" | Null	|変更	|変更		|そのまま |
|未定義				||Null	|Null	|変更		| 変更 |
|||${hoge:+replace} |${hoge+replace} |${hoge:-replace} |${hoge-replace} |
- コロン付き代替値 :+
空の場合は、代替値を使用しない。
- コロン無し代替値 +
変数が定義済みであれば、空文字でも、代替値を使用する。
- コロン付きデフォルト値 :-
値がある場合は、存在する値を使用する。
- コロン無しデフォルト値 -
変数未定義のみ、デフォルト値を使用する。

```bash
#!/bin/bash

hoge="Hello"
# hoge=""
# hoge=""

echo ":+>" ${hoge:+replace} "<"
echo "+ >" ${hoge+replace}  "<"
echo ":->" ${hoge:-replace} "<"
echo "- >" ${hoge-replace}  "<"
```

## 特殊変数

```bash
$? コマンドの終了ステータス
$$ プロセス番号
$0 コマンド名
$# 引数の数
$1 1番目の引数
$* 引数全て. "$1 $2 $3 … "
${#array[@]} 配列 array[]の要素数

$ array=(a b c d e f)
$ echo ${array[@]}  a b c d e f
$ echo ${#array[@]} 6
$ echo $array       a
$ echo ${#array}    1

# arrayの全要素を処理する
for TT in ${array[@]}; do echo $TT ; done

#空白を含むファイル名の展開
$ ls bin/*.txt
bin/hoge hoge.txt

$ for f in bin/*.txt; do echo `basename "$f"` ; done
hoge hoge.txt --- Good

$ for f in bin/*.txt; do echo `basename $f` ; done
hoge ------------ NG
```
python,djangoによるいいねボタンの作り方

いいねボタンを作ります。
ボタンを押すと数字が1つずつ増えていくやつです。
僕が実際にwebアプリケーションで使用しているのがこちら。

```

def good(request, pk):
    """いいねボタンをクリック."""
    post = get_object_or_404(Post, pk=pk)

    if request.method == 'POST':
        # データの新規追加
        post.good += 1
        post.save()

    return redirect('board:board')

```

では解説を。<br><br>
Postモデルとプライマリーキーをpostという変数に代入します。

```
post = get_object_or_404(Post, pk=pk)
```

<br>
もしurlへのアクセスがPOSTならばということなのでフォームで送信された場合ということができますね。
直接URLにアクセスした場合やGETとは違うということです。

```
    if request.method == 'POST':
```

<br>

```
        post.good += 1
        post.save()
```

変数postの中身にモデルPOSTが含まれています。
.goodという形で記載するとmodels.pyのPOSTモデルにあるgoodフィールドにアクセスできます。
+= 1は1増やすという書き方です。
pythonの基礎の方でfor文を使ってループをさせるときにループするたびに数値を増やしていくというようなときは

```
= 1
```
という代入の仕方ではなく

```
+= 1
```
という代入を使います。
厳密に書くと以下のような意味なのですが、

```
post.good = post.good + 1
```
pythonでは += 1と書くと同様の効果が得られるのです。
<br>


```
post.save()
```
で数値を保存します。
<br>
リダイレクト先の指定。

```
return redirect('board:board')
```

<br>
<be>
html部分を解説。

```
    <form action="{% url 'board:good' post.pk %}" method="post">
        {% csrf_token %}
        <input type="submit" name="good" value="いいね"　id="test">（{{ post.good }} いいね）<p  style="color:red"><font size="1"><strong>押すと1ページ目まで戻ってしまいます！（いつか直す！)</strong></font></p>
    </form>
```

いいねボタンを押すと'board:good' post.pk に処理をします。

```
action="{% url 'board:good' post.pk %}
```

board:goodのurls.pyはこのようになっています。

```
path('good/<int:pk>', views.good, name='good'),
```

good関数が使用できるurlにアクセスすると数字を1増やすことができます。ただしboard:goodにはその他の機能を何も持たせていないのでredirectで元のurlに戻しているんですね。
そうするとボタンを押すと一瞬画面が切り替わり次の瞬間には数字が1だけ増えている。
という現象が完成するのです。

<br>
<br>
余談ですがJavaScriptを使用しないといいねボタンを押す度にページの一番上に戻ってしまうんですよね。
JavaScriptを勉強してページが遷移しないように改修しようと思っています。
Faust:soft clipperを作ってみた3 滑らか重視

[Faust:soft clipperを作ってみた](https://qiita.com/ttatsf/items/6d91c87d85a0b575863c)
[Faust:soft clipperを作ってみた2 もっと使いやすいやつ](https://qiita.com/ttatsf/items/0350ab54a1be7d0541db)
の続きです。

maximizerとして十分使えてます。
thresholdが設定できるので便利な反面、使いこんでいくうちに、threshold近辺で音が変わり過ぎるような気がしてきました。
歪み付加系のことをするときは、もうちょっと滑らかにかかっていってほしいなと思うようになってきたわけです。

で、同じような感じでもうひとつ作ってみました。
thresholdありません。
小さい音の時も少し歪んでいて、音が大きくなるにしたがってだんだん歪みが増えていくタイプです。
<img width="732" alt="スクリーンショット 2019-03-24 18.41.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/d557f12a-9f0d-e1b7-07ac-df51125e9d9b.png">

```js:
declare name "sqClipSimple";

import("stdfaust.lib");

process = preGain : clipper : postGain  ;

preGain = preGainMono, preGainMono ;
preGainMono = *( preSlider : ba.db2linear )  ;

clipper = clipperMono(vuMeterL), clipperMono(vuMeterR) ;
clipperMono( m, x ) = clipGain( x ) <: _, meter(m) : attach : *( x ) ;
clipGain( x ) =  ba.if( c0, f0, f1 )
  with{
    c0 = abs(x) <= 2 ;
    f0 = 1 - abs(x) / 4  ;
    f1 = 1 / abs(x) ;
  };
meter(m) = _ : ba.linear2db : si.smoo : m ;

postGain = postGainMono, postGainMono ;
postGainMono = *( postSlider : ba.db2linear ) ;

containerG(x) =vgroup("[2]",x) ;
clipGrp(x) = containerG(vgroup("[2]Clip_", x )) ;
ctrlGrp(x) = clipGrp(hgroup("[0]Ctrl", x )) ;
meterGrp(x) = clipGrp(vgroup("[1]Meter", x )) ;
preSlider = ctrlGrp(hslider("[0]pre[style:knob][unit:dB]", 0, 0, 40, 1 )) ;
postSlider = ctrlGrp(hslider("[2]post[style:knob][unit:dB]", 0, -40, 0, 1 )) ;
vuMeterL = meterGrp(hbargraph( "[0]GR L[unit:dB]", -20, 1 ));
vuMeterR = meterGrp(hbargraph( "[1]GR R[unit:dB]", -20, 1 ));
```
前に作ったやつを簡略化した感じです。
VST&AUにしてみました。[Faust&JUCEによる超高速VST開発](https://qiita.com/tomoyanonymous/items/79b3e551984a707b5c9a)
<img width="399" alt="スクリーンショット 2019-03-24 18.42.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/bdcc9494-a29a-4086-3d68-5693719c19cf.png">

いい感じです。
このままでもたいがい薄く歪んでいるし、preを上げていくと滑らかに音量と歪みが上がってきます。
使える。
Web上のFormの入出力をExcel VBAで自動化

# はじめに
仕事や学校の課題などで，以下のような操作を無限にするようなタスクはありませんか？

1. Webページにアクセスする
2. 検索フォームなどにキーワードを入れる
3. その結果をExcelなどに記録する
4. 上の操作を繰り返してデータを集める

私の場合，Webのフォームで算出される値をシステムテストの期待値として収集したいということがありました．

100ケース以上のケースがあるため，Webに入力→Excelに転記というのは気が滅入ってしまいます．

「こんなとき，RPAがあればなぁ…(・×・)」と思いましたが，考えてみればVBAで実現できたので，シンプルな実装例を用いてご紹介してみたいと思います．

# 環境
* Windows 10
* Excel 2010（諸事情で少し古いVersion）
* Internet Explorer 11

# 今回，実装するケース

王様は民に対して管轄の税務署を知らせて案内状を作りたいようです．

王様「ここにある郵便番号の管轄税務署のリストを作れ！」
ぼく「はい！」

## Webフォーム
というわけで，さっそく[国税庁のWebサイト](http://www.nta.go.jp)にアクセスしてみると，
右下の方に↓こんなフォームがあります．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274284/5b3d237d-3efd-1085-2c34-486362c0fe80.png)
ここに郵便番号を入れることで，管轄の税務署を調べられそうです．

## Excelファイル
王様がくれた郵便番号リストは，以下のような形式になっています．
E列に対して，「○×税務署」と入力していきます．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274284/84d71350-8b2f-bd0a-6358-7fb84bf59ef2.png)

# プログラム
以下のようなプログラムを用意する
## VBAコード

```VB:sample
Sub IE操作()
'定数の宣言
Const URL = "http://www.nta.go.jp"
Const FIRST_ROW_NUM = 2
'インターネットに接続してブラウザを開く
    Dim objIE As InternetExplorer
    Set objIE = New InternetExplorerMedium
    objIE.Visible = True

'インターネットの特定のページを開く
    objIE.navigate URL
    Call IEWait(objIE)

Dim condition As Boolean
condition = True
Dim i As Integer
i = FIRST_ROW_NUM

Do While condition
    '---郵便番号をExcelから取得して変数に代入
    Dim postalCode1, postalCode2
    postalCode1 = Mid(Cells(i, 1), 1, 3)
    postalCode2 = Mid(Cells(i, 1), 4, 7)

    '---IEに自動で文字入力
    objIE.document.getElementById("kszc1").Value = postalCode1
    objIE.document.getElementById("kszc2").Value = postalCode2

    '---ボタンを自動でクリックして次へ---
    objIE.document.getElementsByName("kszBtn")(0).Click
    
    Call IEWait(objIE)
    
    '---値を取得する
    Dim zeimusho
    If IsNull(objIE.document.getElementById("zmsnm1")) Then
    Cells(i, 5) = "該当なし"
    Else
    zeimusho = objIE.document.getElementById("zmsnm1").innerText
    Cells(i, 5) = zeimusho
    End If
    
    i = i + 1
    
    If i > Cells(1, 1).End(xlDown).Row Then
        condition = False
    Else
        condition = True
    End If

        objIE.navigate URL
        Call IEWait(objIE)

    Loop

    'IEを閉じる
    objIE.Quit
    Set objIE = Nothing
    
End Sub


'---IEを待機する関数---
Function IEWait(ByRef objIE As Object)
    Const READYSTATE_COMPLETE = 4
    Do While objIE.Busy = True Or objIE.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
End Function
```

## ポイント
1. ExcelからVisual Basicのエディタを開き「ツール」→「参照設定」から以下の2つにチェックを入れます．
    - [x] Microsoft HTML Object Library
    - [x] Microsoft Internet Controls
2. 郵便番号を3桁／4桁に分割してフォームに入力するため，  
`postalCode1 = Mid(Cells(i, 1), 1, 3)`
Mid関数（文字列をX字目～Y字目まで切り出す）を使います．
3. HTML要素の操作はJavaScriptにおけるDOM操作に近い．
今回，対象のWebフォームのbutton要素にid属性がなかったため．name属性と添え字(0)を用いています．
4. 結果ページで該当する税務署がない場合，結果となるHTML要素がないため，IsNullチェックを入れています．
`If IsNull(objIE.document.getElementById("zmsnm1")) Then`  
※省いてしまうとJavaにおける「NullPointerException」が発生する．

## 実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/274284/31695f01-a71b-c22d-bd79-44ba50c720fa.png)

## 終わりに
Web APIがない場合で，数百件程度のデータを取得をしたい場合など，活用できるケースは少なくない気がします．
gemのあらゆるコマンドがAugumentErrorで実行できなかった件

#この時のPC環境 ※要確認
OS:<strong>Windows10</strong>
Ruby：2.5.3p105 (2018-10-18 revision 65156) [x64-mingw32]
RubyGems：2.3.0

Ruby on Railsのバージョンを確かめようとコマンド"rails -v"を実行したところ、以下のようなエラー表示が出ました。

```
C:\Ruby25-x64\rubygems-3.0.3>rails -v
Traceback (most recent call last):
        2: from C:/Ruby25-x64/bin/rails:23:in `<main>'
        1: from C:/Ruby25-x64/lib/ruby/site_ruby/2.5.0/rubygems.rb:302:in `activate_bin_path'
C:/Ruby25-x64/lib/ruby/site_ruby/2.5.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem railties (>= 0.a) with executable rails (Gem::GemNotFoundException)
```

#エラー表示"ArgumentError"

Ruby on Railsをインストールしてみようと、コマンド"gem install rails"を実行したところ、以下のようなエラーが返ってきました。

```
ERROR:  While executing gem ... (ArgumentError)
    wrong number of arguments (given 1, expected 0)
```

ArgumentError・・・？引数がおかしい？

とりあえず、上のエラー表示についてググってみると、以下の記事を見つけました。
https://teratail.com/questions/156929
自分と同じようなエラーかなーと思いましたが、結局解決できていない模様。

さらにググってみると、以下の記事を発見。
https://github.com/rubygems/rubygems/issues/2224

この記事から、RubyとRubyGemsのバージョンによっては上手くいかないことがあると考え、RubyGemsをアップデートしてみることに。

#コマンドプロンプトからRubyGemsをアップデートできない
gem update --systemを実行すると、以下のような表示が出ました。

```
C:\>gem update --system
Updating rubygems-update
ERROR:  While executing gem ... (ArgumentError)
    wrong number of arguments (given 1, expected 0)
```

またArgumentError・・・

どうにか別の方法でRubyGemsをアップデートできないものかとググりまくっていると、次の記事を発見。
http://d.hatena.ne.jp/c_mutoh/20100329/1269877259

この記事にはZipファイルを使ってRubyGemsをアップデートする方法が書かれていました。

#Zipファイルを使ってRubyGemsをアップデートする方法
※先の記事に書かれている手順通りに実行しましたが、念のため書いておきます。

この時、私がインストールしたRubyGemsのバージョンは3.0.3です。（この記事を書いている時点において最新）

まず、<a href="https://rubygems.org/pages/download">RubyGemsのサイトのダウンロードページ</a>からZIPを選択して、Zipファイルをダウンロードします。

C:\Ruby25-x64のディレクトリ（Rubyがインストールされているディレクトリ）にダウンロードしたZipファイルを解凍します。

解凍できたら、cdコマンドで解凍したディレクトリに移動します。（私の場合"cd C:\Ruby25-x64\rubygems-3.0.3"コマンドを実行）

ここで、setup.rbを以下のように実行します。

```
C:\Ruby25-x64\rubygems-3.0.3>ruby setup.rb
```

これでRubyGemsのバージョン3.0.3がインストールできたはず・・・

バージョンを確認すると、

```
C:\Ruby25-x64\rubygems-3.0.3>gem -v
3.0.3
```

バージョンが2.3.0から3.0.3に更新されました！

#Ruby on Railsをインストール
RubyGemsのバージョンアップが完了したところで、Ruby on Railsをインストールしてみます。
以下のコマンドを実行します。

```
C:\Ruby25-x64\rubygems-3.0.3>gem install rails
Fetching rails-5.2.2.1.gem
Successfully installed railties-5.2.2.1
Successfully installed rails-5.2.2.1
Parsing documentation for railties-5.2.2.1
Installing ri documentation for railties-5.2.2.1
Parsing documentation for rails-5.2.2.1
Installing ri documentation for rails-5.2.2.1
Done installing documentation for railties, rails after 0 seconds
2 gems installed
```

今度はエラーが返ってきませんでした。

Ruby on Railsが無事インストールされたか確認してみます。

```
C:\Ruby25-x64\rubygems-3.0.3>rails -v
Rails 5.2.2.1
```

インストールできたみたいです！

#まとめ
Ruby on Railsをインストールしたいが、できない
↓
RubyGemsのバージョンを変更する必要がある(?)
↓
コマンドプロンプトでRubyGemsのバージョンを更新できない
↓
Zipファイルを使ってRubyGemsのバージョンを更新
↓
Ruby on Railsインストール成功

という話の流れでした。

#個人的な感想
Qiita初投稿の記事になります。

私はRuby初心者ですが、プログラミングする以前に環境構築の時点でつまづくのは結構辛いですよね・・・
私はこの問題で半日以上費やしてしまい、同じような思いを他の方が味わうのは何とも酷だなと思い、思い切って投稿しました。

参考になれば幸いです。

あぁ・・・おとなしくMac買って使った方が良いんだろうな・・・
[R言語]欠損のあるデータのサマリーをとる

# 概要
欠損している行を含むデータに対して欠損している行を無視して平均を計算する

# 手順
以下のようなある観測所で観測された10年分の月ごとの合計降水量(mm)のCSVファイルを使用します。

| year | month | total_precipitation |
|--:|--:|--:|
| 2009 | 1 | 176.5 |
| 2009 | 2 | 80.5 |
| 2009 | 3 | 207 |
| 2009 | 4 | 81.5 |
| 2009 | 5 | 130.5 |
| 2009 | 6 | 301.5 |
| 2009 | 7 | 136 |
| 2009 | 8 | 25.5 |
| 2009 | 9 | 70.5 |
| 2009 | 10 | 439.5 |
| 2009 | 11 | 263 |
| 2009 | 12 | 87 |
| 2010 | 1 | 72 |
| 2010 | 2 | 118 |
| 2010 | 3 | 147 |
| 2010 | 4 | 292.5 |
| 2010 | 5 | 146.5 |
| 2010 | 6 | 316.5 |
|...|...|...|
| 2018 | 7 | 143.5 |
| 2018 | 8 | 537 |
| 2018 | 9 | 236 |
| 2018 | 10 |  |
| 2018 | 11 |  |
| 2018 | 12 |  |

- year:観測された年
- month:観測された月
- total_precipitation:月ごとの合計降水量(mm)

上記のようなCSVファイルをR言語で処理して月ごとの平均を求めます。

``` r:na_summarise
> data %>%
+   group_by(month) %>%
+   summarise(mean = mean(total_precipitation))
# A tibble: 12 x 2
   month  mean
   <int> <dbl>
 1     1   NA 
 2     2  119.
 3     3  129.
 4     4  165.
 5     5  251.
 6     6  373.
 7     7  170.
 8     8  227.
 9     9  228.
10    10   NA 
11    11   NA 
12    12   NA 
```

1月、10月、11月、12月のNAとなってしまいました。
これはその月のデータに少なくとも1件の欠損データを含むため、平均を計算できなかったことを表します。

そこで、以下のfilterで欠損している年と月を抽出します。

``` r:na_filter
> data %>%
+   filter(is.na(total_precipitation))
  year month total_precipitation
1 2015    12                  NA
2 2016     1                  NA
3 2018    10                  NA
4 2018    11                  NA
5 2018    12                  NA
```

2015/12、2016/1、2018/10、2018/11、2018/12のデータが欠損していることがわかりました。

この5行分のデータを無視して平均を計算するには、上と同様にfilterを使用してNAでない行だけを抽出して計算します。ただし、今回は **NAでない** 行だけを抽出したいため、filterの条件は逆になります。

``` r:non_na_summarise
> data %>%
+   filter(!is.na(total_precipitation)) %>%
+   group_by(month) %>%
+   summarise(mean = mean(total_precipitation))
# A tibble: 12 x 2
   month  mean
   <int> <dbl>
 1     1  102.
 2     2  119.
 3     3  129.
 4     4  165.
 5     5  251.
 6     6  373.
 7     7  170.
 8     8  227.
 9     9  228.
10    10  257.
11    11  164.
12    12  102.
```

事前にNAでない行を抽出することで平均がNAだった月が計算できていることがわかります。

合計についても同様に計算可能ですが、NAの行を除外しているため除外された行を含む月のデータは母数が他より少なくなっていることに注意が必要です。例えば12月のデータは2015年と2018年の分のデータが欠損しているため、8年分のデータの合計になっています。

``` r:non_na_sum
> data %>%
+   filter(!is.na(total_precipitation)) %>%
+   group_by(month) %>%
+   summarise(sum = sum(total_precipitation))
# A tibble: 12 x 2
   month   sum
   <int> <dbl>
 1     1  914  # 9年分
 2     2 1186.
 3     3 1294.
 4     4 1654.
 5     5 2514.
 6     6 3729 
 7     7 1704.
 8     8 2269 
 9     9 2280.
10    10 2312  # 9年分
11    11 1473  # 9年分
12    12  820  # 8年分
```

# 備考
今回使用したデータは以下のサイトでダウンロードしました。

気象庁|過去の気象データ・ダウンロード
https://www.data.jma.go.jp/gmd/risk/obsdl/index.php
Rails I18nでcreated_atなど各モデル共通の属性を一発で日本語化する

# ユースケース
created_atやupdated_atなど、各モデル共通のattributesを日本語化したいときに。

# コード
```yaml:models.yml
ja:
  attributes:
    created_at: 作成日時
    updated_at: 更新日時
```

一番上の階層に記述すれば最初に読み込まれる。

# 参考
http://alfa.hatenablog.jp/entry/2013/12/03/221308
https://qiita.com/Kta-M/items/bd4ba36a58ad602a9d8b
gulp を使って style.scss を style.css に変換

次のページで行っていることを Arch Linux で確認しました。
[絶対つまずかないGulp 4入門（2019年版）](https://ics.media/entry/3290/)

Node.js と npm は既にインストールされているものとします。

```text
$ node --version
v11.12.0
$ npm --version
6.9.0
```

1) 作業フォルダーの作成

```bash
mkdir gulp-test
cd gulp-test
```

2) package.json の作成

```bash
npm init -y
```

3) ライブラリーのインストール

```bash
npm install -D gulp
npm install -D gulp gulp-sass
```
4) gulpfile.js の用意

```js:gulpfile.js
// gulpプラグインの読み込み
const gulp = require("gulp")
// Sassをコンパイルするプラグインの読み込み
const sass = require("gulp-sass")

// style.scssをタスクを作成する
gulp.task("default", function() {
  // style.scssファイルを取得
  return (
    gulp
      .src("css/style.scss")
      // Sassのコンパイルを実行
      .pipe(sass(
{
          outputStyle: "expanded"
        }
))
      // cssフォルダー以下に保存
      .pipe(gulp.dest("css"))
  )
})
```

5) css/style.scss の用意

```scss:css/style.scss
$split-grid: 3;

@for $i from 1 through $split-grid {
  .col-$i {
    flex: 0 0 100% / $split-grid * $i;
    max-width: 100% / $split-grid * $i;
  }
}
```

6) css/style.css への変換

```bash
npx gulp
```

>css/style.css が作成されます。

```css:css/style.css
.col-$i {
  flex: 0 0 33.33333%;
  max-width: 33.33333%;
}

.col-$i {
  flex: 0 0 66.66667%;
  max-width: 66.66667%;
}

.col-$i {
  flex: 0 0 100%;
  max-width: 100%;
}
```
UIkitのカスタマイズ

## 概要

UIkitはすばらしい
デザインをいい感じにカスタマイズしたい
LESSの変数の値を上書きしたい

## 環境

MacOS Mojave
npm と yarn はインストール済み
他にも必要になったら適宜インストールしてください

## ソースのダウンロード

コンパイル前のソースが必要なのでyarnで落としてくる
終わったらディレクトリを移動しておく

```
$ yarn add uikit
$ cd node_modules/uikit/
```

参考: https://getuikit.com/docs/installation#download

## LESSファイルを作成する

カスタムテーマというものを作る
ファイル名がそのままテーマになるらしい

```less:custom/my-theme.less

@import "../../src/less/uikit.less";

@navbar-background: #999;
@navbar-nav-item-color: #fff;
@logo-color: #fff;
```

* 参考: https://getuikit.com/docs/less#use-variables

## コンパイル

install で必要なモジュールを落としてくる
compile で追加したテーマを認識させる
watch でファイルが更新されたら自動でコンパイルするように

```
$ yarn install
$ yarn compile
$ yarn watch
```

* 参考: https://getuikit.com/docs/less#use-included-build-process

## 表示の確認

テーマの確認用の環境が用意されているのでそれを利用する
watch でコマンドプロンプトが占領されていると思うので別窓で開いてください

```
$ npm test
```

Webブラウザで http://localhost:8080/tests/ にアクセスする
ページ上部に並んでいるコンボボックスとチェックボックスは左から順に以下の役割

1. 表示するサンプルページ
2. 使用するテーマ
3. モード
4. 横書き/縦書き

先程追加した My-theme がコンボボックスにあるはず
選択するとLESSに記述した内容が反映されたデザインを確認できる

LESSを変更した場合はコンボボックスを切り替えたりすると反映される
ページを再読込しても反映されなかった

## コンパイルされたファイル

dist/css/uikit.my-theme.css
dist/css/uikit.my-theme.min.css

上記のように出力されている
好きな場所にコピーして使おう

## 詰まったところ

ファイルを更新しても watch が反応してくれない
よくわからないけど .gitignore と競合して反応しなくなっていたっぽい
参考： https://github.com/uikit/uikit/issues/3424
ディレクトリ直下に nodemon.json を追加することで反応するようになった

```json:nodemon.json
{
  "ignoreRoot": [".git"]
}
```
正規表現の基本まとめ

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているyukako_nishimuraです。
今回は正規表現の基本について簡単にまとめました。

# 正規表現

## 文字を表す表現
|記号|意味|
|:---:|:---:|
|.|任意の1文字|
|\d|数字1文字|
|\w|単語構成文字A-Za-z0-9|
|\s|スペース、タブ、改行などのホワイトスペース|
|\D|数字以外|
|\W|単語構成文字A-Za-z0-9以外(句読点など)|
|\S|スペース、タブ、改行などのホワイトスペース以外|
|\t|タブ|
|\r|キャリッジリターン(カーソルを文頭に戻す)|
|\b|単語の境界|
|\文字|特殊文字のエスケープ|


## 文字の繰り返し表現
|記号|意味|
|:---:|:---:|
|[1文字以上の文字]|括弧内に一致する文字があれば、一致|
|[^1文字以上の文字]|括弧内に一致する文字がなければ、一致|
|[文字-文字]|アルファベット順、数字の昇順で、特定の文字から文字までの範囲を丸ごと指定できる。|

## 文字の繰り返し表現
分かりやすいよう任意の1文字、または文字のグループを`A`とします。

|記号|意味|
|:---:|:---:|
|A{数字}|指定した回数、文字を繰り返し|
|A{数字,数字}|指定した範囲内のいずれかの回数、文字を繰り返し|
|A+|文字を1回以上繰り返し|
|A*|文字を0回以上繰り返し|
|A?|文字を0回または1回繰り返し|

## 文字の位置を表す表現
|記号|意味|
|:---:|:---:|
|^|Aは文頭|
|$|Aは文末|

## 文字のグループ化

|記号|意味|
|:---:|:---:|
|(文字列)|文字のグループを定義する。入れ子にもできる。|

## 論理記号
**`|`**で**OR**つまり**または**を表せる。
pm2で1時間に1回再起動させる


Raspberry Piで実行してますが、不安定なプロセスがあって定期的に再起動出来たらと思ったやつです。

## プロセス1を永続化

```
pm2 start process1.js
```

ここは通常の使い方。

## プロセス1を監視する

```bash
npm init -y
```

```bash
npm i pm2
```

> https://github.com/Unitech/pm2/blob/master/examples/api-pm2/api.js

```pm2watch.js
'use strict'

const pm2 = require('pm2');
const INTERVAL_TIME = 1000 * 60 * 60; //1時間

const restart = () => {
    pm2.restart('process1', errback => {
        if(errback === null){
            console.log('reloaded');
        }else{
            console.log(errback);
        }
    });
}

setInterval(() => restart, INTERVAL_TIME);
```

```
pm2 start pm2watch.js
```

## 確認

```bash
$ pm2 list

┌────────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬──────┬───────────┬──────┬──────────┐
│ App name   │ id │ version │ mode │ pid   │ status │ restart │ uptime │ cpu  │ mem       │ user │ watching │
├────────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼──────┼───────────┼──────┼──────────┤
│ process1   │ 0  │ N/A     │ fork │ 27236 │ online │ 16      │ 12m    │ 0.2% │ 34.6 MB   │ pi   │ disabled │
│ pm2watch   │ 1  │ 1.0.0   │ fork │ 27701 │ online │ 0       │ 93s    │ 0.2% │ 34.2 MB   │ pi   │ disabled │
└────────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴──────┴───────────┴──────┴──────────┘
```

定期的に再起動してprocess1の
常にカメラを向くオブジェクトをGPUで実装

2年ぶりにQiitaに投稿。

3D空間上で、カメラアングルが変わっても常にこっちを向いていてほしい オブジェクトをつくりたいことがあります。

たとえば、2Dの板にテクスチャを貼り、それを常に正面を向かせることで、一枚絵を3D内で見せる,というテクニック(?)があります。こういう平面を板ポリゴンとかビルボードなどと呼んだりしますね。

before:
<img width="262" alt="5345ded1a36dea6b751cc616ce9b0f00.png" src="https://qiita-image-store.s3.amazonaws.com/0/5859/dba34e0e-ad58-7cbf-2345-9338b0277658.png">

after:
<img width="269" alt="ea7b8ec35b7558467944159aeb44f227.png" src="https://qiita-image-store.s3.amazonaws.com/0/5859/1d192745-b418-2d2e-893d-fc0b0a81eb3d.png">


この、ビルボードを常にカメラの方へ向ける行為ですが、シェーダで簡単に実装する方法を知ったので紹介してみようと思います。

やりかたはとっても簡単で、頂点シェーダで、クリッピング座標を計算する部分を以下の変えるだけです。

```diff
-OUT.vertex	 = UnityObjectToClipPos(IN.vertex);  // 通常
+OUT.vertex = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0)); // 常にカメラを向く
```

なぜこれで常に向きが一定になるのか、すこし解説してみようと思います。

まず、 変更前の、いつもやっている 座標変換の `UnityObjectToClipPos` ですが、
最適化の分岐を無視するとだいたい以下のような実装になっています。

```
mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0)));
```

うむ。モデル変換、ビュー変換、プロジェクション変換の行列をそれぞれ掛けているだけですね。
(入力の最後の要素に `1.0` を入れているのは、 3次元ベクトルを行列で座標変換する際に、移動(translate) も許すようにするおまじない)

上で登場する、座標変換のための行列の定数についてすこしだけふりかえってみます。

| 定数  | 意味  |
|---|---|
| UNITY_MATRIX_P | プロジェクション変換。カメラが映している領域を画面に投影する変換 |
| UNITY_MATRIX_V | ビュー変換。ワールド座標から、カメラを原点に置いた場合の座標系への変換  |
| unity_ObjectToWorld | いわゆるモデル変換。 ローカル座標からワールド座標への変換。`UNITY_MATRIX_M` という名前じゃないのが不思議(?) |


これを踏まえて、さきほどの、カメラを向きつつクリッピング座標へ変換するコードを もう一度見てみます。

```
mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0))
```

`UNITY_MATRIX_MV` は、  VとMの行列をあらかじめCPU側で乗算したものです。 一度の描画における変化行列は不定なためです。 なので、実質、以下のコードと同等です。

```
mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(0, 0, 0, 1)) + float4(IN.vertex.x, IN.vertex.y, 0, 0)))
```

つまり、`float(0,0,0.1)` に対して MとVの変換をすることで、 オブジェクトのどの頂点の計算もすべてビュー座標系(カメラを原点とした座標系)における原点ということに一旦してしまいます。(すべての頂点が原点にあれば、回転もくそもありません) その後、ビュー座標系における2D上でxとyを足すことで、ビュー座標系内で頂点の位置を合わせます。最後にP変換を被せて完成。

## シェーダで実装するメリット

最後に、このように向きを変える処理をシェーダで実装するメリットについてです。

* トータルで計算コストが減る
  * GPU側の処理はさして増えていない
  * CPU側で毎フレームオブジェクトの向きを計算することも可能ですが、Unityの場合はメインスレッドに負荷が集りやすいため、全体としてリーズナブル。
* ゲームを再生しなくても、シーンビューなどすべての表示でこっちを向いてくれる。
tshark wiresharkのCUI版、キャプチャ時GUI不要なので軽い。

wiresharkは使い勝手が良いが、長時間キャプチャする時にGUIを不要としたい。screenから起動しておけばいいな。。。
## コマンド例
<pre>
tshark -i2 -tad -b duration:300 -w ./test.pcap 
</pre>
## オプション
<pre>
-D                       print list of interfaces and exit
-L                       print list of link-layer types of iface and exit
--list-time-stamp-types  print list of timestamp types for iface and exit

-i インタフェースID
-w 出力ファイル名(.pcap)
-b filesiez:SIZE-KB
-b duration:秒
-b files:ファイル数（ローテート）

 -t 時刻フォーマット
 -t  a|ad|d|dd|e|r|u|ud|?
  a : hh:mm:ss.nanosec   12:28:05.400184646 
  ad: a+ date            2019-03-10 12:29:15.000986266
</pre>

## フィルタ
<pre>
-f “フィルタ”
  host  アドレス
  tcp 
  udp
  tcp port ポート

ブロードキャスト以外
 not broadcast and not multicast 

ARP,DNS以外
 not arp and not port 53 
</pre>
【Selenium】xpathでidタグを指定した後にvalueをクリックする【Python】

Python、Seleniumでxpathを用いて、
idタグを指定した後にvalue要素をクリックする。

例：```id = "hogeId"```内の```INPUT```要素である```value = "login"```をクリックする

```python:hoge.py
# importなど
from selenium import webdriver
driver = webdriver.Chrome(executable_path=".\driver\chromedriver.exe")

# idタグを指定した後にvalueを指定する。
driver.find_element_by_xpath("//*[@id='hogeId']/descendant::input[@value='login']").click()
```
descendant：子孫の集合
pandas 列へ値の代入についてのメモ書き

# はじめに
DataFrameのスライスには、直接値を代入できない。

# 例

下記のようにdf3というDataFrameがあり、
単価列のNanバリューを埋めたいという要件があったとして。

```python
# サンプルとしてこんなDataFrameがあります。
>> df3
0	1	2	単価	price
0	0	1	2	10.0	20.0
1	3	4	5	NaN	NaN
2	6	7	8	NaN	NaN
```

```python

# 単価列のNaNに0を代入したいので、、、、

>> df3[df3["単価"].isnull()][["単価"]] = 0
# と、しました。が、、、、

# Warningが表示され失敗しました。
>> /usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.
```

> Google翻訳：  
DataFrameのスライスのコピーに値を設定しようとしています。
代わりに.loc [row_indexer、col_indexer] = valueを試してください。

# 正解

```python
# 正解はこちらのようです。
df3.loc[df3["単価"].isnull(),["単価"]] = 0
```

この例の場合は、Nanバリューなのでfillna関数とか使えばいいのかもしれないのだけども。一応。
<Angular> overrideでバックエンドとの処理をきれいに書く

# あらまし
- 複数人でフロントを作成
- Angular で Class を一つ一つ作るのがめんどい
- バックエンドの処理とやり取りをする Service の返り値として受け取る型（クラス）がまちまち
 - component もそれぞれ変わるから統一しにくい・見にくい

その状況の1打開策。↓↓

# やったこと 
エラーの返し方、レスポンスの取り方を統一して、Service での返り値は下記でいう
Response を必ず継承させたものにしておく。

```error-response.ts
export class ErrorResponse {
    StatusCode:number
    ErrorMessage:string
}
```

``` response.ts
import { ErrorResponse } from './error-response'

export class Response {
    header:ErrorResponse
    result:any
}
```

``` hoge.ts
import { Response } from './response'

export class Hoge {
    name:string
    id:number
}
// レスポンスを継承でアプリ内で使うクラスごとに定義しなくてもよくなる
export class ResponseHoge extends Response {
    result:Hoge 
}

```

これで、、、

- StatusCode
- Name
- Id

またある人は

- statusCode
- data
 - name
 - id

またまたある人は

- statusCode
- result
 - name
 - id

うおーーー
という状況がなくなり

各APIごとの返り値を揃えられる。

なので、componentで値を処理する動きも統一、さらにバックエンド側の処理も統一できるため、
コード内が非常に見やすくなると思います。

```hoge.component.ts
get(){
    let sub = this.Api.getHoge().subscribe(
      res => {
        if(res.header.StatusCode != 200){
          window.alert('エラー')
        }else{
          window.alert('name:' + res.result.name + ' id:' + res.result.name)
        }
      },
      err => window.alert('接続エラー')
    )
  }

```
Chroe Extension開発サンプル


# Chrome Extension
クロームエクステンション開発の初めの一歩として、以下の公式ページを実践しました。
[developer.chrome.com/extensions](https://developer.chrome.com/extensions)

## 資源のダウンロード
[サンプルの素材が置いてあるページからダウンロードします。](https://developer.chrome.com/extensions/samples#search:hello)

```manifest.json
{
  "name": "Hello Extensions",
  "description" : "Base Level Extension",
  "version": "1.0",
  "browser_action": {
    "default_popup": "hello.html",
    "default_icon": "hello_extensions.png"
  },
  "manifest_version": 2,
  "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+F",
        "mac": "MacCtrl+Shift+F"
      },
      "description": "Opens hello.html"
    }
  }
}
```

```hello.html
<!DOCTYPE html>
<html>
  <head>
    <title> Hello Extensions </title>
  </head>

  <body>
    <h1>Hello Extensions</h1>
  </body>
</html>
```

hello_extensions.pngもあります。


## 拡張機能を有効にする
以下にアクセスし、パッケージ化されていない拡張機能を有効にするを押し、フォルダを指定する
[chrome://extensions/](chrome://extensions/)
Chrome で開いたページに任意のスタイルシートを適用する

以下は、Chrome 拡張を作成して、指定した URL に対して任意のスタイルシートを自動で適用する方法です。

## プロジェクトディレクトリを作成する

````sh
$ mkdir -p user_defined_css/www.example.com
$ cd $_
````

## マニフェストファイルを作成する

`matches` にスタイルシートを適用したい URL を指定。
`css` に適用するスタイルシートのファイル名を指定。

````json:manifest.json
{
  "name": "www.example.com css",
  "version": "1.0",
  "description": "CSS for www.example.com",
  "content_scripts": [
    {
      "matches": ["http://www.example.com/*"],
      "css": ["style.css"]
    }
  ],
  "manifest_version": 2
}
````

## 適用したいスタイルシートを作成する

````css:style.css
div {
  color: green;
}
````

## ファイルツリー

以下の状態にします。

````
- www.example.com/
    - manifest.json
    - style.css
````

## 作成した Chrome 拡張を読み込む

1. [chrome:extensions](chrome:extensions) を開く
2. 右上にある「デベロッパー モード」を有効にする
3. 「パッケージ化されていない拡張機能を読み込む」をクリック
4. 最初に作成したディレクトリ (www.example.com) を指定

- [参考](https://developer.chrome.com/extensions/getstarted#manifest)

これで新規にページを開いた際に自動的にスタイルシートが適用されます。
スタイルシートを適用したいページをすでに開いていた場合はリロードします。
AWSの歩き方(EC2→IE接続まで)

#やったこと
1.VPC周り作成
2.1.で作成したVPCを使用してEC2を作成
3.セキュリティ周りの設定
4.EC2インスタンスのソフトウェア更新
5.IE接続設定


マニュアル人間を目指しているので、AWS公式のドキュメントを見ながら環境を構築していく

#構成図
[draw.io](https://www.draw.io/)で作成
![AWS_WindowsServer (1) (2) (2).png](https://qiita-image-store.s3.amazonaws.com/0/256753/6beb7be1-360f-666b-9b5e-4dc7726bf31d.png)


#1.VPC周り作成
・AWS サービス別資料
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/

以下の動画を参考に構築
・Amazon Virtual Private Cloud (VPC) Basic
https://youtu.be/aHEVvsk6pkI

#2.1.で作成したVPCを使用してEC2を作成
・Windows 仮想マシンの起動
https://aws.amazon.com/jp/getting-started/tutorials/launch-windows-vm/

#3.セキュリティ周りの設定
下記を参考にポートの設定
・VPC に推奨されるネットワーク ACL ルール
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-recommended-nacl-rules.html

#4.EC2インスタンスのソフトウェア更新
EC2インスタンス内のソフトウェアを最新バージョンに更新
以下のチュートリアルを参考
・チュートリアル: Windows Server を実行する Amazon EC2 インスタンスに WAMP Server をインストールする
WAMP サーバーをインストールするには　3.を参照
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/install-WAMP.html

#5.IE接続設定
Internet Explorer セキュリティ強化の構成を無効化
・チュートリアル: Windows Server を実行する Amazon EC2 インスタンスに WAMP Server をインストールする
WAMP サーバーをインストールするには　２.を参照
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/install-WAMP.html
AWK One Liner(一行野郎)

# AWK One Liner(一行野郎)

データ整形、ログ集計に役立つAWKのOne Linerを記載しました。
AWK本からの引用です。

１. 入力行の総数を印字

```
END { print NR }
```

２. 10行目の入力行を印字する

```
NR == 10
```

３. すべての入力行の最後の欄を印字する

```
{ print $NF }
```

４. 最後の行の最後の欄を印字する

```
    { field = $NF }
END { print field }
```

５. 4個より多い欄を持つすべての入力行を印字する

```
NF > 4
```

６. 最後の欄が4より大きいようなすべての入力行を印字する

```
$NF > 4
```

７. すべての入力行の欄の総数を印字する

```
    { nf = nf + NF }
END { print nf }
```

８. Bethを含む行の総数を印字する

```
/Beth/ { nlines = nlines + 1 }
END    { print nlines }
```

９. 最も大きい第1欄とそれを含む行を印字する($1のどれかは正であると仮定する)

```
$1 > MAX { max = $1; maxline = $0 }
END      { print max, maxline }
```

１０. 少なくとも1つの欄を持つすべての行を印字する

```
NF > 0
```

１１. 80文字以上の長さを持つすべての行を印字する

```
length($0) > 80
```

１２. それぞれの行の欄の数とその行自体を印字する

```
{ print NF, $0 }
```

１３. 任意の行の最初の2つの欄を逆順で印字する

```
{ print $2, $1 }
```

１４. すべての行を最初の2つの欄を交換して印字する

```
{ temp = $1; $1 = $2; $2=temp; print }
```

１５. すべての行を最初の欄を行番号に置き換えて印字する

```
{ $1 = NR; print }
```

１６. すべての行を2つ目の欄を消去して印字する

```
{ $2 = ""; print }
```

１７. すべての行の欄を逆順で印字する

```
{ for (i = NF; i > 0; i = i - 1)printf("%s", $i)
  printf("\n")
}
```

１８. すべての行の各欄の合計を印字する

```
{ sum = 0
  for (i =1; i <= NF; i = i + 1) sum = sum + $i
  print sum
}
```

１９. すべての行のすべての欄を合計して、その値を印字する

```
    { for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
END { print sum }
```

２０. 各欄の値を絶対値に置き換えてからすべての行を印字する

```
{ for (i =1; i <= NF; i= i + 1) if ($i < 0) $i = -$i
  print
}
```

## 参考書籍
プログラミング言語AWK (A.V.エイホ、P.J.ワインバーガー、B.W.カーニハン、足立 高徳(訳))
Docker Image を runして、 bundle exec rails new する

自分用の備忘録です。

---

まず、ビルド

```
docker build . -t <IMAGE_NAME>
```

Rails new

```
docker run --rm -v $PWD:$PWD -w $PWD <IMAGE_NAME> bundle exec rails new . --database=mysql --skip-test
```
`docker run`のオプションは下に説明

## 参考にした記事
[Dockerコンテナからホスト側カレントディレクトリにアクセス](https://qiita.com/yoichiwo7/items/ce2ade791462b4f50cf3)


- `--rm`オプションでDockerコンテナのプロセス(コマンド)が終了した時点でコンテナを破棄します。コマンド終了後にDockerコンテナ上のファイルを色々とアクセスしたい場合は外しても構いません。
- `--user`オプションでホスト側のUIDを指定します。指定しない場合、生成したファイル等の所有者がroot:rootとなるためホスト側のユーザが編集したり削除したりできません。
- `-v $PWD:$PWD`オプションで、ホス ト側カレントディレクトリとコンテナ側カレントディレクトリのボリューム内容を一致させます。
- `-w $PWD`オプションで、ホスト側カレントディレクトリとコンテナ側カレントディレクトリのディレクトリパスを一致させます。`-v $PWD:$PWD`オプションと組み合わせて使います。
kubernetesでenvoy使ってgRPCしながら終了時にパケットロストしない方法

## 概要
kubernetesでmicroservicesアーキテクチャを採用している場合、envoyでgRPC通信するケースが多いかと思います。詳しくは[こちら](https://qiita.com/wataru420/items/a63a8b205308a93e253c "kubernetesでgRPCするときにenvoy挟んでみたよ")の記事を。
そんなときに瞬断の影響が大きいサービスを運用している場合、アプリをシャットダウンするタイミングで何も考えないで運用しているとパケットをロストします。

これは、serviceから切り離される前にPodが終了してしまうことや、Podに対して終了シグナルが送られた場合に、アプリより先にenvoyが終了しちゃう事などで発生します。
これはサイドカーしている他のコンテナでも同様のことが言えます。

## 対策
grpcはhttp2の通信なのでコネクションを永続化します。つまりserviceから張られていたコネクションは処理中のものも含めて切断されてしまいます。

それを避けるためには
① serviceから当該Podへの新規のコネクションを止める
② すべての処理が終わるまですべてのコンテナを落とさない
を行う必要があります。

しかしながら②を実現することは困難なので `sleep 30` で妥協することにしました。
30秒程度あればすべての処理は終了するだろうという考えです。

## 事前準備
まず、複数のコンテナ間で状態を共有するために`unhealthy`という名前の共有volumeを作成します。

これを各コンテナの `/tmp` にマウントしておきます。
ここに状態共有のための情報を書き込みます。

## appコンテナの挙動
appコンテナはSIGTERMを受け取ると `/tmp` に `unhealthy` というファイルを作成し30秒sleepします。

同時に `unhealthy` がある場合は `readinessProbe` を失敗させ、serviceから切り離します。

envoyは[headless services](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services)を利用してバランシングしているので、このPodに対して新しいコネクションは張られなくなります。

## envoyコンテナの挙動
envoyコンテナはSIGTERMを受け取ると `unhealthy` ファイルを発見するまでループします。
これでappコンテナが終了するよりも前にenvoyコンテナが終了することを防ぎます。
`unhealthy` ファイルを発見したら、こちらも同様に30秒sleepします。

30秒後に両コンテナが完全に終了するという流れになります。

具体的には下記のようなyamlになります。

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
...
      containers:
      - name: sidecar-envoy
        image: envoyproxy/envoy:v1.7.0
...
        volumeMounts:
        - name: unhealthy
          mountPath: /tmp
          readOnly: true
        lifecycle:
          preStop:
            exec:
              command:
              - sh
              - -c
              - while (! test -e /tmp/unhealthy); do sleep 1; done; sleep 30
      - name: app
        image: path/to/app:latest
...
        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - exit `! test -e /tmp/unhealthy; echo $?`
          initialDelaySeconds: 5
          timeoutSeconds : 3
          periodSeconds: 3
          failureThreshold: 1
        lifecycle:
          preStop:
            exec:
              command:
              - sh
              - -c
              - touch /tmp/unhealthy; sleep 30
      volumes:
      - name: unhealthy
        emptyDir: {}
```

`initialDelaySeconds` とか `timeoutSeconds` あたりは短めにしてるって程度で深い意味はありません！
これでHappy gRPC lifeを！！
Ubuntu 18.04 で git の interactive.singleKey を有効にする

探すの面倒だったので忘れる前にメモ

## 困ったこと

地味に重要なこの設定 :

```
$ git config --global interactive.singlekey true
```

これだけでは Ubuntu では動かない。かなしい。

## 結論

libterm-readkey-perl をインストールしよう

```
$ sudo apt-get install libterm-readkey-perl
```

## 調査中のメモ

といっても man を読むだけ

```
$ man git-config
...
interactive.singleKey
    In interactive commands, allow the user to provide one-letter input with a single key (i.e., without hitting enter). Currently this is used by the --patch mode of
    git-add(1), git-checkout(1), git-commit(1), git-reset(1), and git-stash(1). Note that this setting is silently ignored if portable keystroke input is not
    available; requires the Perl module Term::ReadKey.
...
```

なにやら `Perl module Term::ReadKey` なるモジュールが必要らしい。

* と言われても apt のパッケージが分からない
* 検索すればすぐに出てくるので心配無用
  * [libterm-readkey-perl_2.38-1_amd64.deb Debian 10 Download](https://debian.pkgs.org/10/debian-main-amd64/libterm-readkey-perl_2.38-1_amd64.deb.html)
  * > Term::ReadKey is a compiled perl module dedicated to providing simple
control

ということで物は試し

```
$ sudo apt-get install libterm-readkey-perl
Reading package lists... Done
Building dependency tree
Reading state information... Done
...
...
Unpacking libterm-readkey-perl (2.37-1build1) ...
Setting up libterm-readkey-perl (2.37-1build1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
```

適当なリポジトリのディレクトリで意図通りに動作することを確認

```
$ git add -p
```

おわり。
~~いかがでしたでしょうか~~