OmniAICreator/Qiita-1.07M huggingface dataset:
[Python3]インスタンスオブジェクト内のローカル変数について

```python
class Sample:
    A = 1 #クラス変数
    
    def __init__(self):
        self.b = 2 #インスタンス変数
        c = 3 #ローカル変数


sample = Sample()

print(Sample.A) #クラスオブジェクトからクラス変数を参照
print(sample.A) #インスタンスオブジェクトからクラス変数を参照
print(sample.b) #インスタンスオブジェクトからインスタンス変数を参照
#print(sample.c)#インスタンスオブジェクトからインスタンスオブジェクトのローカル変数を参照
```

最後の`print(sample.c)`は実行できない．
実行しようとすると`AttributeError`がでる．

他のスコープで参照される場合はインスタンス変数に，参照されない場合はselfをつけないでローカル変数にする．
いままでとりあえずselfをつけていたので使い分けるようにしたい．

間違いとか補足があればコメントをお願いします．
まだまだ勉強が足りないので．
自分用

頻度高
https://qiita.com/rik0/items/b022c111b4ae3347926b

https://qiita.com/shunhikita/items/772b81a1cc066e67930e

genetateコマンドの使い方
それの取り消し方destroy(model とかでも同じことができる)

```ruby:コマンド
rails generate controller コントローラー名(モデル名) hage
rails destroy controller コントローラー名
```
db:migrate のやり方と取り消し方

```ruby:コマンド
rails db:migrate
rails db:rollback
```

データーベースのカラムの増やし方

```ruby:コマンド
rails g migration Addカラム名Toテーブル名 カラム名:データ型
rails g migration AddStatusToMicroposts status:string
```
git でまちがってpushした時に一つ前に戻るコマンド
git をクローン（ダウンロード）する方法
git で新しいブランチを作って、そのブランチに移動するコマンド。

```git:コマンド
git reset --hard HEAD^
git clone https://github.com/funaikeita5/angler.git
git checkout -b ブランチ名
```
ifの書き方例
==が2個必要

```ruby:コマンド
render 'users/sidebar' if (@user.id == current_user.id)
```
以下の文でデフォルト値を指定することができる。また，データーベースのSQliteにはフィルターがある。

```ruby:コマンド
add_column :courses, :release, :boolean ,default: false
```

オブジェクトがnilでない場合のみ、そのオブジェクトのメソッドを実行したい！って時に使うメソッドです。

```ruby:コマンド
<%= @member.birthday.try(:strftime,"%Y年%m月%d日") %>
```
| # |
|:--|
| # 数字 |
| # 全て数値（全角） |
| /\A[０-９]+\z/ |
| # 全て数値（半角） |
| /\A[0-9]+\z/ |
| # 全て数値（全角,半角） |
| /\A[0-9０-９]+\z/ |
| # 全て全角数値（マイナス、小数点） |
| /\A[ー]?[０-９]+(\．[０-９]+)?\z/ |
| # 全て半角数値（マイナス、小数点） |
| /\A[-]?[0-9]+(\.[0-9]+)?\z/ |
| # 文字 |
| # 半角アルファベット（小文字） |
| /\A[a-z]+\z/ |
| # 半角アルファベット（大文字） |
|  /\A[A-Z]+\z/ |
| # 半角アルファベット（大文字・小文字） |
|  /\A[a-zA-Z]+\z/ |
| # 半角アルファベット（小文字・数値） |
| /\A[a-z0-9]+\z/ |
| # 半角アルファベット（大文字・数値） |
| /\A[A-Z0-9]+\z/ |
| # 半角アルファベット（大文字・小文字・数値） |
| /\A[a-zA-Z0-9]+\z/ |
| # 全角ひらがな |
| /\A[ぁ-んー－]+\z/ |
| # 全角カタカナ |
| /\A[ァ-ヶー－]+\z/ |
| # 全角ひらがな、カタカナ |
| /\A[ぁ-んァ-ヶー－]+\z/ |
| # 半角カナ |
| /\A[ｧ-ﾝﾞﾟ]+\z/ |
| # 漢字 |
| /\A[一-龥]+\z/ |
| # 全角ひらがな、漢字 |
| /\A[一-龥ぁ-ん]/ |
| # 全角ひらがな、全角カタカナ、漢字 |
| /\A[ぁ-んァ-ン一-龥]/ |
| # 全角ひらがな、全角カタカナ、漢字（鬼車） |
| /\A(?:\p{Hiragana}|\p{Katakana}|[ー－]|[一-龠々])+\z/ |
| # 郵便番号 |
| # 郵便番号（ハイフンあり3桁・5桁・7桁） |
| /\A\d{3}[-]\d{4}$|^\d{3}[-]\d{2}$|^\d{3}\z/ |
| # 郵便番号（ハイフンあり5桁） |
| /\A\d{3}[-]\d{2}\z/ |
| # 郵便番号（ハイフンあり7桁） |
| /\A\d{3}[-]\d{4}\z/ |
| # 郵便番号（ハイフンなし3桁） |
| /\A\d{3}\z/ |
| # 郵便番号（ハイフンなし5桁） |
| /\A\d{5}\z/ |
| # 郵便番号（ハイフンなし7桁） |
| /\A\d{7}\z/ |
| # 郵便番号（ハイフンあり・なし両方） |
| /\A\d{3}[-]\d{4}$|^\d{3}[-]\d{2}$|^\d{3}$|^\d{5}$|^\d{7}\z/ |
| # 電話番号 |
| # 電話番号(ハイフンなし10桁) |
| /\A\d{10}\z/ |
| # 携帯番号(ハイフンなし11桁) |
| /\A\d{11}\z/ |
| # 携帯番号(ハイフンなし10桁or11桁) |
| /\A\d{10,11}\z/ |
| # その他 |
| # e-mail |
|  /\A\S+@\S+\.\S+\z/ |
| # URL |
| /\Ahttp(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/ |
| # クレジットカード(VISA,Master,Diners,Discover,Amex対応) |
| /\A(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})\z/ |
windowsでのpython環境構築(chocolatey)

#はじめに
何番煎じかわからないけれど、自分がどうやって環境構築したかの備忘録

##バージョン情報
Windows 10 Pro 64bit (OSビルド 17134.648)

##chocolateyのインストール

https://chocolatey.org/install#installing-chocolatey
上記の`Install with cmd.exe`にあるコマンドをコピペしてコマンドプロンプトで使用する

```cmd.exe
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
```

下記の記事のコマンド等の説明が参考になりました！
[【Chocolatey入門】導入から注意点、今後の可能性まで](https://qiita.com/kangetsu121/items/b6352b547cd32e71bc65)

##pythonのインストール

```cmd.exe
choco install python
```

##pipのインストール

```cmd.exe
choco install pip
pip install --upgrade pip
```
簡単な単語帳アプリの作成

#Abstract
簡単な単語帳アプリを作る。
単語帳の構造はいたって簡単である。
表と裏、それぞれに言葉を書き込めるようになっているカードの束である。
もう少し抽象化すると、
「2つ組のデータを集めて並べたもの」「2*m行列」
2をnに一般化すると、
「nつ組のデータを集めて並べたもの」「n*m行列」

これをプログラミングの概念に落とし込むと、
「配列の集合」「構造体」「多次元配列」…etc

しかし、単語帳である以上は、ファイルとして長期保存できる必要がある。

行列的な構造を持っていて、ファイルとして保存できるもの…
身近なものでは、主に2つある。

１．リレーショナルデータベース
２．csvファイル


普通はデータを取り扱う際は１のようなちゃんとしたデータベースを使うのが王道だそうだが、
csvも行列形式のファイルであり、立派なデータベースといえる。

単語帳のようなシンプルな構造のものは、シンプルなcsvファイルでも事足りると考えられる。
よって、今回は取り扱いが容易であるといわれるcsvファイルを使う方針で行く。
rake taskで可変長引数を使う

約1年間Railsエンジニアやってて初めてrake task書いた。

その時のめも。

`to_a` メソッドを使う

```
namespace :test_task do
  desc '可変長引数を受け取るtask'
  task :hoge, ['huga'] => :environment do |_task, args|
    p args.to_a
    p args.huga
  end
end
```

実行する。

```
$ bundle exec rake test_task:hoge[1,2,3,4]
["1", "2", "3", "4"]
"1"
```

`args`は`Hash`ではなく`Rake::TaskArguments`であり、`Rake::TaskArguments`のインスタンスメソッドである
`to_a`を使うことで引数の値をすべて取得する事ができる

- リファレンス

[http://www.rubydoc.info/gems/rake/12.0.0/Rake/TaskArguments#to_a-instance_method]
【ドメイン変えたい】ドメインを移行しようとして悲しい思いをしたよ！

# ドメイン変えたい時ってあるよね
昔に作ったサービスのドメインをちゃんと運用しているドメインに移行しようとして悲しい思いをしたので、情報共有です。

簡単にまとめると、`hand-dot.com`っていうドメインがあって`labelmake.jp`っていうドメインに統合したいなって思ったのだが、現在(2019年3月)はサーチコンソールが新しいバージョンに移行しようとしていて、よくわからなかった。

アクセス数が闇に消え一人寂しい思いをした話と、
解決したので、じゃあどうすればよかったんだよ！って話の2つをします。


# アクセス数が闇に消え一人寂しい思いをした話
ドメイン移行って行ったらサーバーに301リダイレクト(恒久的な転送)を返すように設定して、OKなんかなって思ってたんよ。
`.htaccess`に[記述したり](https://digital-marketing.jp/creative/site-renewal-301-redirect/)、`firebase`使っとるなら[リダイレクト設定](https://firebase.google.com/docs/hosting/url-redirects-rewrites?hl=ja#section-redirects) したりね。

**そしたら、ぶちやばいけぇ。**

検索流入が1日目は統合したサイトは確かにリダイレクトをかけたサイトのアクセス数が加算されたんよ。

でも次の日にそのアクセス数は消えたんよ。

**びびるけぇね。**

でもその日もその次の日も気のせいかなって思って寝たんよ。

でもねぇ1週間経っても、元々のドメインのアクセス数は元に戻らんかった。闇に消えたんよ。

でも人って面白いよね。こういう状況になると自分に都合のいい検索結果を探し始め出してさ、ついに見つけたんよ。

### *「一ヶ月くらいで元に戻りました！」* 

みたいな記事

でも下で説明する方法で即解決した一ヶ月かからなかった。これでぐっすり寝れるわ。

# じゃあどうすりゃあよかったん！

サーチコンソールでの設定が足りてなかったらしいで。
 **「アドレス変更ツール」**っていうのを使用するらしい。

公式：[アドレス変更ツールの使用
](https://support.google.com/webmasters/answer/83106?hl=ja)

Search Consoleは今年いっぱいで新バージョンに完全移行らしいけど、このアドレス変更ツールってのは新しいSearch Consoleにはまだなくて、
![スクリーンショット 2019-03-19 0.47.17.png](https://qiita-image-store.s3.amazonaws.com/0/204698/597c7783-aa7e-f37e-45ad-4b22be7f9e52.png)


昔のSearch Consoleから設定する必要があるっぽい。(もしかしたらそのうち移行して、この手順と変わるかもしれませんが、そこは別で調べてみてください。 2019/03/19)

とりあえず昔のSearch Consoleにアクセスして。
懐かしいな。
![スクリーンショット 2019-03-19 0.44.43.png](https://qiita-image-store.s3.amazonaws.com/0/204698/880b8e04-83c7-5dde-19ba-6c4207bfe8df.png)

んで、右の歯車クリックして、あったあった「アドレス変更」

![スクリーンショット 2019-03-19 0.45.16.png](https://qiita-image-store.s3.amazonaws.com/0/204698/5c4843af-d27c-ba46-adc9-8c633b2ee804.png)

んで、わしの場合は1週間前くらいに301リダイレクトに設定していたので、2番までは既にチェクついていたわ。あとは2,3回クリックしたら、終わった。

![スクリーンショット 2019-03-19 0.45.28.png](https://qiita-image-store.s3.amazonaws.com/0/204698/f71ccc5c-2baf-4c5a-8160-6ce5caaf6695.png)

しかもビビるのが、すぐに検索結果が、元々 `hand-dot.com` で インデックスされてたところが、新しい移行先の`labelmake.jp`にちゃんと移行できてた。(3分もかからなかったと思う)

はやい！


---

あーとりあえずなんかよかったので、ノリで記事書いたら広島弁が出た。
おつかれっす！

ドメイン変えたくなった時に参考にしてみてください。

# 301リダイレクトからのサーチコンソールの「アドレス変更」！これ鉄板。
Google colaboでGoogle DriveのファイルをPythonで操作する

## はじめに
Googleドライブへのマウント方法ですが、現在はより簡単になりました。
▼下記の記事で紹介しているのでこちらをご確認いただいた方が良いかと思います。

https://www.teijitaisya.com/gcolab-gdrive/


## Google colabにGoogleドライブをマウントする
Google Colaboratoryを使う場合、GoogleDriveをマウントするとGoogleDriveに読み書きできるので便利です。


#１．Google Driveをマウントする

```python

# カレントディレクトリのファイル一覧をみてみます。
import os
os.listdir()
>>['.config', 'sample_data']
```

```python
# Googleドライブをcontentというマウントポイントにマウントします。MP名はなんでもOKです。
from google.colab import drive
drive.mount(mountpoint="content")
```

```python

# リンク先に行けと言われるのリンクをクリックします。
Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?うんたらかんたら

# リンク先でGETした認証コードをペーストしてエンターします。
Enter your authorization code:
ここにテキストボックスでてくるので↑のリンク先で取得したキーを入力してエンター
··········
```

```python
# マウントできたみたいです！
Mounted at content
```

```python

# もう一回カレントディレクトリのファイル一覧を確認すると・・・
os.listdir()

# 新しく"content"フォルダが存在しています！
# このフォルダ配下にGoogleドライブのファイルが存在しているはずです。
>>['.config', 'content', 'sample_data']
```


```python

# 念のためcontentフォルダの中身一覧もみてみます。
os.chdir("content")
os.listdir()
>>['My Drive', '.Trash']

os.chdir("My Drive")
os.listdir()

# 下記のようにきちんとドライブ内のファイルが見れました。
>>['Google フォト',
 'climbing_preparation_list1.xlsx.gsheet',
 'NoteMaster Sync',
 'Google フォト (1)',
 'Dropbox.7z',
 'Google Document 2010',
 '00_仕事',
 'jplus_folder',
 'ToDo.gsheet',
 'Python_検索結果.gsheet',
 'MySite.gscript',
 'Lavo Site.gscript',
 'GmaiAttached',
 '[GAS]GoogleAppsScript 作業フォルダ',
 'GmailからGoogleドライブ.gscript',
 '不要メールリスト作成.gscript',
 'URL作成.gscript',
 'LINE Bot 2nd.gscript',
 'カレンダーを操作します.gscript']
```


#2． ファイル操作してみます。

これでGoogle Driveのcsvファイルをcolabからpandasで読み込んだりできます。
これで本題のGoogle Driveのファイルをまとめて操作できます。  
下記は、GASファイル（.gscript）をまとめてリネームした例です。

```python:gscript拡張子のファイルを抽出してファイル名の頭にGSとつける。

# まずGASファイルを抽出
for i, j in enumerate(os.listdir()):
  if j[-6 : ] == "script":
    print(i,j)

12 MySite.gscript
13 Lavo Site.gscript
16 GmailからGoogleドライブ.gscript
17 不要メールリスト作成.gscript
18 URL作成.gscript
19 LINE Bot 2nd.gscript
20 カレンダーを操作します.gscript
22 無題のプロジェクト.gscript
```

```python:
# リネームしてみる
for i, j in enumerate(os.listdir()):
  if j[-6 : ] == "script":
    os.rename(j , "GS_" + j )
    print(i,j)

# 実際にGoogle Driveで確認したところ出来てました。
12 GS_MySite.gscript
13 GS_Lavo Site.gscript
16 GS_GmailからGoogleドライブ.gscript
17 GS_不要メールリスト作成.gscript
18 GS_URL作成.gscript
19 GS_LINE Bot 2nd.gscript
20 GS_カレンダーを操作します.gscript
22 GS_無題のプロジェクト.gscript
```

## おわり
Vuexで最初の1回だけ行いたい処理のタイミングについて考えた

Vue+Vuex初心者です。

結論から言えば、考慮点はあるが`created`のタイミングが良さそう。

### 背景

初回に1回だけ実行して情報を得たい時がある。例えばAPIリクエストでも良いし、localStorageからごにょごにょするとか。

内容は大したことはなくて、多分みんな当たり前のようにやってる気がするので調べれば出そうだけど、私にはどうもピンとくるものがなかったので手を動かして何故良さそうか/だめそうか考えた。

最初は`store/index.js`の中でやれば一番よいのでは、と思って書いてたが、Vuex.Storeインスタンスがまだ無い状態なので、dispatchを呼べない事に気づき、ダメだと判断。

### 案1: createdでやるよ

やっぱり、ライフサイクルに従ってやるのがVueの掟に従ってて良さそうだと思った。

``` js:main.js
import Vue from 'vue'
import App from './App.vue'
import { store } from './store'

new Vue({
  store,
  router,
  render: h => h(App),
  data: {
    mydata: data
  },
  created(){
    const data = localStorage.getItem("foo");
    this.$store.dispatch('init', data)
  }
})
```

JSFiddle: https://jsfiddle.net/v8g0r2eq/3/

Demoにはかけてないがこれには問題があって、コンポーネントが突っ込まれるたびにactionが発生してしまう。

`main.js`などの大元でやるなら影響はないかもしれないが、コンポーネントの場合は作って消してを繰り返される可能性があるため、actionが2回以上実行される可能性がある。なので、2回目以降の実行を防ぐような考慮をaction側でしなくてはいけない。（デモでは考慮しているつもり）

それは何か嫌だなぁ、と次に思いついたのがこれ。

### 案1: 最初の実行でやる

``` js:main.js
import Vue from 'vue'
import App from './App.vue'
import { store } from './store'

const data = localStorage.getItem("foo");
store.dispatch('init', data)

new Vue({
  store,
  router,
  render: h => h(App),
})
```

JSFiddle: https://jsfiddle.net/v8g0r2eq/4/

インスタンスを作る前からstoreにぶっこんでしまえという案。


これもdemoに書いてないけど、コンポーネントが突っ込む予定がない状態でも初期化処理が行われる。ただ、実行タイミングが掴めないが、1回だけ実行される。
でも、必要になるまでは遅延させておきたいのが人情なので、これもちょっと微妙かもしれない。
（動的なコンポーネントなら初めてコンポーネントが読みだされるまで遅延されるかも。でもそんなのコンポーネント側で意識したくない。）

データを取りたい時にそれが無い、という状況は辛いだけなので、これは微妙そう。

ただ、これ以上思い浮かばないので、とりあえず`created`でやっていこう。
初心者でもわかるdeviceの使い方(rails)

#Deviseとは
ログイン、新規登録機能を作成する為のGem


1.Gemfileに以下を追記

``` 
 gem 'devise'
```
2.ターミナルで以下のコマンドを実行

```
$ bundle install
```

3.設定ファイルの作成

```
$ rails g devise:install
```

4.device機能を持たせるモデル、マイグレーションファイルの作成

```
$ rails g devise user
```

5.作成したマイグレーションファイルをマイグレート

```
$ rake db:migrate
```

#deviceのビューを編集する

```
$ rails g devise:views
```

devise/registrations/new.html.erb　新規登録画面

devise/sessions/new.html.erb　ログイン画面
form_withでユーザー登録/ログイン機能の実装

##前提

- macOS mojave 10.14.3
- rails 5.1
- 環境環境 local
- Bootstrap、secure_password 導入後

###テーブル

```schema.rb
ActiveRecord::Schema.define(version: 20190318144456) do

create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "image_name"
    t.string "password_digest"
  end
```

###ルート

```routes.rb
Rails.application.routes.draw do
post 'login', to:'users#login'
post 'users/create', to:'users#create'
end
```



###コントローラー

```users_controller.rb

def create
    @user = User.new(
        name: params[:name],
        email: params[:email],
        image_name:"default_user.jpg",
        password: params[:password]
    )
    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "User registration has been completed."
      @current_user = @user
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end

  def login
    @user = User.find_by(email: params[:email])
    if @user && @user.authenticate(params[:password])
      session[:user_id] = @user.id
      flash[:notice] = "Logged in"
      redirect_to("/posts/index")
    else
      @error_message = "Your email or username is incorrect."
      @email = params[:email]
      @password = params[:password]
      render("users/login_form")
    end
  end
```

###ユーザー登録フォーム

```
  <%= form_with url: users_create_path, local: true do |form| %>
```

```new.html.erb
<h1>Sign Up</h1>
  <p>Please fill in this form to create an account.</p>
  <%= form_with url: users_create_path, local: true do |form| %>
    <%= form.label :name %>
    <li>
      <%= form.text_field :name %>
    </li>
    <%= form.label :email %>
    <li>
      <%= form.email_field :email %>
    </li>
    <%= form.label :password %>
    <li>
      <%= form.password_field :password %>
    </li>
    <%= form.label :password_confirmation, "Confirmation" %>
    <li>
      <%= form.password_field :password_confirmation %>
    </li>
    <%= form.submit "Create my account", class: "btn btn-primary" %>
  <% end %>
```

###ログインフォーム

```
 <%= form_with url:login_path, local: true do |form| %>
```

```login_form.html.erb
<h1>Log in</h1>
  <p>Please fill in this form to log in.</p>
  <%= form_with url:login_path, local: true do |form| %>
    <%= form.label :name %>
    <li>
      <%= form.text_field :name %>
    </li>
    <%= form.label :email %>
    <li>
      <%= form.email_field :email %>
    </li>
    <%= form.label :password %>
    <li>
      <%= form.password_field :password %>
    </li>
    <%= form.label :password_confirmation, "Confirmation" %>
    <li>
      <%= form.password_field :password_confirmation %>
    </li>
    <%= form.submit "Log in", class: "btn btn-primary" %>
<% end %>
```

###参考資料
[Rails 5.1] ‘form_with’ APIドキュメント完全翻訳　https://techracho.bpsinc.jp/hachi8833/2017_05_01/39502
個人間で2.5GBまでのファイルのやりとりが可能なFirefox Sendをローカルで試す


参考) 

* [mozilla/send](https://github.com/mozilla/send)
* [Mozillaが無料の暗号化ファイル共有サービス「Firefox Send」を開始](https://jp.techcrunch.com/2019/03/13/2019-03-12-mozilla-launches-its-free-encrypted-file-sharing-service-firefox-send/)
* [無料で最大2.5GBのデータを共有できるセキュリティ面もバッチリなファイル共有サービス「Firefox Send」が正式リリースされる
](https://gigazine.net/news/20190313-firefox-send/)
* [Firefox Sendを独自サーバーに導入](https://qiita.com/kolinz/items/2fe6f69f6debffcc9bcd)

Firefox Sendの特徴はざっくり以下です。

1. デフォルトだと2.5GBまでのファイルダウンロードURLを発行できる。
2. ファイルは暗号化されて管理される。
3. 保存期間をURL発行時に設定できる(5分〜1日)。ダウンロード回数も指定できる（1〜5回）。
4. ブラウザはFirefoxでなくても動作する。 

面白そうなので以下、自分の環境で簡単に試してみました。
手元の環境はMacです。

## Redis Serverの設定

```bash
# brewでRedisをインストール
brew install redis

# Redisの起動
redis-server
```

## Nodejs 10.0+の設定

```bash
# brewでnodebrewをインストール
brew install nodebrew

# nodebrewを使うためのセットアップ
nodebrew setup
```

```bash
# インストール可能なバージョンを確認する
nodebrew ls-remote

# v10.15.3をインストール
nodebrew install-binary v10.15.3

# v10.15.3を使うように設定する
nodebrew use v10.15.3

# バージョンの確認
node -v
```

## Firefox Sendの設定

```bash
git clone https://github.com/mozilla/send.git
cd send
```

### 開発環境

```bash
# 依存パッケージのインストール
npm install

# サーバの起動
# localhost:8080でアクセスできる
npm start
```

### 本番環境

`server/config.js`で色々設定できるようですが..
そのままでもRedisが入っていれば動きました。

```bash
# 本番環境のアセットをビルドする
npm run build	

# サーバの起動
# デフォルトだとlocalhost:1443でアクセスできる
npm prod
```

以下のような画面が出力されればOK。
<img width="1025" alt="スクリーンショット 2019-03-19 0.35.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/203061/45ceb056-e1f6-0f6a-1731-6855f78cd822.png">
redirectとforwardについて

プログラミング初学者です。
JSP,Servletで処理ページを別ページに移す方法として学んだことをアウトプットします。
#Q: redirectとforwardは何が違う？
##A: 変移するまでの過程が違う
**redirect** 
　　↓
①クライアントからサーバーにページAを表示するリクエスト。
②サーバーからクライアントにページAからページBに変移するよう指示する。
③クライアントからサーバーにページBに変移するようリダイレクト指示
④サーバーからページBの結果が送られてくる

**forward**
　　↓
①クライアントからサーバーにページAを要求
②サーバー側で自動でページBに処理を写しクライアントに結果をおくる。
#基本的にforwardの方が良い！
なぜなら、、、
**・リクエスト情報を引き継げる**
**・redirectよりパフォーマンスが良い**  etc....
#redirectを使うタイミング
・外部のサーバーにアクセスする際

【参照元】
https://www.atmarkit.co.jp/ait/articles/0407/06/news077.html
Watchdogを使ってみた

Pythonでファイルの変更を監視するためのクラスとして、Watchdogというクラスがあります。

* [Watchdog — watchdog 0\.8\.2 documentation](https://pythonhosted.org/watchdog/)

Qiitaにもほかにも記事がありますので、使うのに困ることはあまりないと思います。

* [ファイルの更新をきっかけにコマンド実行 \(python編\) \- Qiita](https://qiita.com/ksato9700/items/ea4b769d010e8cf1fb0c)

ただいちおう使用するにあたって躓いたところがあるのでいちおうそこだけメモ。

# Watchdogで監視できるのは、フォルダのみ
Watchdogは他の方が書かれているサンプルにもあるとおり、`watchdog.observers.Observer`オブジェクトを使ってファイルを監視します。

```py
    self.observer = Observer()
    self.observer.schedule(ChangeHandler(), dir)
    self.observer.start()
```
ただ、`Observer#schedule()`に指定できるのは「フォルダのパスのみ」です。ファイルパスを指定することはできません。

特定のファイルだけ監視したいときは、親フォルダを監視した上で、ファイル名で照合をしましょう。

```py
class ChangeHandler(FileSystemEventHandler):
  """
  Event handlers for watchdog.
  """

  def __init__(self, owner):
    self.owner = owner

  def on_modified(self, event):
    p = Path(event.src_path)
    if p == self.owner._review_file or p.suffix in [".js", ".css"]:
      self.owner.show_review()
```

# フォルダのパスは「文字列で」指定する

引数には文字列しか指定することはできません。なんだかんだこのようにパスを指定する場面で指定できることの多い`pathlib.Path`型を指定することはできません。かならず`str()`関数などで文字列化してから指定する必要があります。

# 監視をやめたいときは

監視をやめるときは、`Observer#stop()`と`Observer#join()`を呼びます。

```py
      self.observer.stop()
      self.observer.join()
```
🔵 TypeScript - Goみたいに「例外を投げない」ためのライブラリを作った

2020/5/2追記: **Lifts**というライブラリを作りました。こっちの方が使いやすいです→ https://qiita.com/yarnaimo/items/1d1c33196c0b6b43c11a

先日この記事を読みました。
[「例外を投げない」という選択肢をとる言語](https://qiita.com/suin/items/bf67ceaba72a9cdcb1ac)

Go や Scala では、例外を JavaScript のように throw して catch することが推奨されず、多値返却や Either でエラーも戻り値として返すアプローチがとられるという内容です。

TypeScript でも同じようなことがしたかったので **[fp-ts](https://github.com/gcanti/fp-ts)** を使って作ってみました！！！🎉🎉

⛵ **TrySafe**
https://github.com/yarnaimo/trysafe

`yarn add trysafe` か `npm i -S trysafe` でインストールできます🙃

どっかで見たことあるような名前ですが気のせいです。

## 使い方

```ts
import { Try, TryAsync } from 'trysafe'

const result = Try(() => {
    return document.querySelector('a')!.href // 要素が見つからない場合はエラーが throw される
})

// この場合 result の型は Either<Error, string>

if (result.isLeft()) {
    // ここでは result.value の型は Error
    console.error(result.value.message) // -> エラーメッセージ
    return
}

// ここでは result.value の型は string
console.log(result.value) // -> href の値
```

`Try` には引数のない関数 **`() => T`** を渡します。

`Try` の戻り値の型は fp-ts の **`Either<Error, T>`** で、これは `Left` 型と `Right` 型の Union Type です。

渡された関数の中でエラーが throw された場合は `Left`、成功した場合は `Right` が返され、`.isLeft()` と `.isRight()` で判別することができます。

async 関数を渡したい場合は `TryAsync` を使います。

```ts
const result = await TryAsync(async () => {
    return await fetch('http://example.com')
})
```

## 普通の try-catch と比べていいところ

### 「エラーが起きる可能性」を明示できる (try-catch を忘れることがない)

例えばこんな関数があったとします。

```ts
async function getUsers() {
    return fetch('/users')
}
```

この関数はエラーを throw する場合があるので上流で catch すべきですが、特にネストが深い場合などは忘れてしまう可能性もあります。

```ts
async function getUsers() {
    return TryAsync(async () => fetch('/users'))
}
```

`Try` で囲むと、エラーが発生した場合も外には throw されずに**戻り値で返される**のでその心配はありません。

### エラーが握りつぶされにくい

エラーを上流で処理するような設計にしやすいので、下流でエラーを握りつぶしてしまう可能性も減るのではないかと思います。

## あとがき

今回の内容とは関係ないですが、fp-ts といえば実行時に型チェックをするための [io-ts](https://github.com/gcanti/io-ts) っていうライブラリもあります。

終わりだよ〜
GMP（GNU Multi-Precision ）ライブラリ

既出なものも多いかとは思いますが、メモがてらに。
間違い等がございましたらコメントください。

# GMP（GNU Multi-Precision ）
## GMPとは
言わずと知れた多倍長演算ライブラリ。多倍長演算ライブラリを用いると（リソースが許す限り）任意の大きさの数を扱うことが可能となる。
多倍長演算の主な利用先に暗号がある。標準の整数型であるunsigned long long int型で64bitまでの整数を扱うことができるが、暗号などでは数千bitの整数を扱う必要があるため多倍長演算ライブラリが必要となる。

## ライセンス
LGPL（GNU Lesser General Public License）ライセンス。GPLよりも縛りがゆるいライセンス。
- 自己責任での使用
- 著作権表示の削除禁止
- 複製・改変・再配布・販売は自由
- **中に組み込む場合**LGPLライセンスに
つまり、外部ライブラリとしてLGPLのプログラムを利用する場合には呼び出す側のプログラムはLGLPでなくてもよい。


# インストール
[GMPのホームページ](https://gmplib.org/)からソースファイルをダウンロード。

ダウンロードしたtar.lzファイルを解凍

```
tar --lzip -xvf gmp-oo.tar.lz
```
もし、lzipがインストールされていなければ、

```
sudo apt install lzip
```
でlzipをインストール。

その後、

```
./configure
make -j4
make check
sudo make install
```
これでGMPのインストールは完了です。

# 使い方
ソースファイル内に

``` 
#include <gmp.h>
```
を追加。
コンパイル時に-lgmpを追加。

以下サンプル

```
gcc -o gmp_test gmp_test.c -lgmp
```


```gmp_test.c
#include <time.h>
#include <gmp.h>

int main(int argc, char const *argv[])
{
    /**
     * 多倍長整数構造体を初期化
     */
    mpz_t a;
    mpz_init(a);
    
    /**
     * 疑似乱数生成器のステート構造体を初期化
     * デフォルトはメルセンヌ・ツイスタ
     **/
    gmp_randstate_t state;
    gmp_randinit_default(state);

    /**
     * 時間をseedに
     * 暗号の秘密鍵生成などを行う際は/dev/randomなどからハードウェア乱数を取ること推奨
     **/
    time_t rtime;
    time(&rtime);
    gmp_randseed_ui(state, rtime);

    /**
     * 100bitの乱数を生成
     **/
    mpz_urandomb(a, state, 100);

    /**
     * 16進数で出力
     **/
    gmp_printf("%Zx\n",a);

    /**
     * お片付け
     **/
    mpz_clear(a);
    gmp_randclear(state);
    
    return 0;
}

```
日付の文字列をエポック秒に変換2

前回、timelocal関数を使って日付の文字列をエポック秒に変換したが、
コメントでTime::Pieceモジュールというものを教えて頂いたので、
それを使って日付の文字列をエポック秒に変換していく。

```perl
uuse Time::Piece;

my %hash = (
    date => '2020/01/01 10:00:00'
);

my $Date = Time::Piece -> strptime($hash{date}, '%Y/%m/%d %H:%M:%S');
print $Date -> epoch, "\n";

# これで変換は出来たが、タイムゾーンがUTCとなっている為、32400(9時間)引く。

$test = $Date -> epoch;
print $test - 32400, "\n";
```
kintone UI Component を React で試す　第１回

今週末に [Hamamatsu.js #6](https://connpass.com/event/119039/) があるので、その発表用資料として色々試しているメモです。

[kintone UI Component](https://developer.cybozu.io/hc/ja/articles/360000511023) は

>「kintone UI Component」は、kintone技術者のために開発された、kintoneライクなUIを簡単に作成できるライブラリです。

**kintone技術者のために** というところが、とても気に入ってます。

JavaScriptでも使えますが、Reactだと更に良い感じで書けそうです。
ちょっと書いてみます。

# スクリーンショット
ラジオボタンとボタンの組み合わせです。
kintoneライクになってますね。
<img width="1254" alt="スクリーンショット 2019-03-18 23.58.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/29f5ae9b-d3b8-8703-1eee-0f5ef91466d7.png">

 - [CodeSandbox](https://codesandbox.io/docs) CodeSandbox is an online editor that's built for web application development.

# サンプルコード

```index.js
import { RadioButton, Label, Button } from "kintone-ui-component";
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

class MyCustomization extends React.Component {
  constructor(opts) {
    super(opts);
    let items = [
      {
        label: "Orange",
        value: "Orange",
        isDisabled: false
      },
      {
        label: "Banana",
        value: "Banana",
        isDisabled: false
      },
      {
        label: "Lemon",
        value: "Lemon",
        isDisabled: true
      }
    ];
    this.state = {
      items: items,
      value: "Banana"
    };
  }

  render() {
    return (
      <div className="kintone-UI">
        <Label text="My kintone UI Component Test" />
        <RadioButton
          name="radio"
          items={this.state.items}
          value={this.state.value}
          onChange={value => {
            this.setState({ value });
            this.myOnChange(value);
          }}
        />
        <Button
          text="Submit"
          type="submit"
          isDisabled={false}
          isVisible={true}
          onClick={this.handleClick}
        />
      </div>
    );
  }

  myOnChange = val => {
    console.log(val);
  };

  handleClick = () => {
    console.log(this.state.value);
  };
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyCustomization />, rootElement);
```

```style.css
.kuc-input-radio-item {
  display: inline-block;
}
```

第２回へ続きます。
なっとく！アルゴリズム第8章 集合カバー問題(p175~)をSwiftで書く

## なっとく！アルゴリズム(集合カバー問題)をSwiftで書く

## 問題
![IMG_0910.png](https://qiita-image-store.s3.amazonaws.com/0/176479/9d42e11a-a999-0b3c-8780-35b2006bcccb.png)

(なっとく！アルゴリズムp173より引用)

## Swiftで書き直した

```Swift
//////// Your code here!
var statesNeeded:Set = ["mt","wa","or","id","nv","ut","ca","az"]

//Set型の値が入る辞書をつくるのにちょっと手間取った
var stations: [String:Set<String>] = [
    "放送局A(kone)" : ["id","nv","ut"],
    "放送局B(ktwo)" : ["wa","id","mt"],
    "放送局C(kthree)" : ["or","nv","ca"],
    "放送局D(kfour)" : ["nv","ut",],
    "放送局E(kfive)" : ["ca","az"]
]

var finalStations = Set<String>()

while statesNeeded.isEmpty == false {
    var bestStation:String = ""
    var statesCovered = Set<String>()
    var covered = Set<String>()

    //stationsの辞書からkeyとvalueを取り出す
    for (station, statesForStation) in stations {
        print(" (station, statesForStation)",station, statesForStation)
        //積集合 それぞれの放送局に含まれている県を取り出す
        covered = statesNeeded.intersection(statesForStation)
        //現在のbestStationよりもより多くの州をカバーしているかどうかを判定する
        if covered.count > statesCovered.count {
            bestStation = station
            statesCovered = covered
        }
    }
    
    statesNeeded = statesNeeded.filter { !statesCovered.contains($0) }
    
}
print("こたえ",finalStations)
```

## Paiza実行環境で実行した
https://paiza.io/projects/qHictrxYycalEMhrRwCPOg
ラズパイのボタンをプッシュしたら写真撮ってS3へ上げる

##モチベーション
部品が揃ってきたので、ラズパイとAWSを連携。
ラズパイのボタンをプッシュしたら写真撮ってS3へ上げる。

##環境
- RaspberryPi3B+
- Raspbian 9.8
- RPi.GPIO
- picamera
- amazon S3
- boto3
- python

##準備
以下の2記事の複合技なので準備はこちらにお任せします。
[Raspberry Pi カメラ画像をS3へアッロード](https://qiita.com/atmaru/items/8caa8d15246dbfe4ae4a)
[Raspberryでボタン押下をGPIOの割り込みで検出](https://qiita.com/atmaru/items/2282445d327b0af0e6c1)

##pythonコード

```takePicToS3.py
# coding: utf-8
import picamera
import boto3
import time
from datetime import datetime

def take_pic_from_picamera(filename):
    print("take_pic_from_picamera:"+filename)
    with picamera.PiCamera() as camera:
 #    camera.resolution = (1024, 768)
     camera.resolution = (500, 500)
     camera.start_preview()
     camera.led = False
     #camera warm-up time
     time.sleep(2)
     camera.capture(filename)
     print("done")
    
def upload_to_S3(filename):
    print("upload_to_S3:"+filename)
    bucket_name = "atsmaru-bucket"
    s3 = boto3.resource('s3')
    s3.Bucket(bucket_name).upload_file('/home/pi/'+filename, filename)
    print("done")

# main
#timestr = datetime.now().strftime('%Y%m%d%H%M%S')
#filename=timestr+'.jpg'
#take_pic_from_picamera(filename)
#upload_to_S3(filename)
```

```button_to_S3.py
# coding: utf-8
import RPi.GPIO as GPIO
import time
import datetime
from datetime import datetime
import takePicToS3

BUTTON_PIN = 21

def main():
	setup_gio()

	try:
		while(True):
			time.sleep(1)

	# Keyboard入力があれば終わり
	except KeyboardInterrupt:
		print("break")
		teardown_gio()

def setup_gio():
	GPIO.setwarnings(False)
	# Set the layout for the pin declaration
	GPIO.setmode(GPIO.BCM)
	# BCMの21番ピンを入力に設定
	GPIO.setup(BUTTON_PIN,GPIO.IN) 
	# callback登録（GIO.FALLING:立下りエッジ検出、bouncetime:300ms）
	GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=callback, bouncetime=300)

def teardown_gio():
	GPIO.cleanup()

def callback(channel):
	print("button pushed %s"%channel)
	timestr = datetime.now().strftime('%Y%m%d%H%M%S')
	filename=timestr+'.jpg'
	takePicToS3.take_pic_from_picamera(filename)
	takePicToS3.upload_to_S3(filename)

if __name__ == "__main__":
    main()
```

##実行

```
pi@raspberrypi:~ $ python button_to_s3.py
button pushed 21
take_pic_from_picamera:20190318235340.jpg
done
upload_to_S3:20190318235340.jpg
done
button pushed 21
take_pic_from_picamera:20190318235348.jpg
done
upload_to_S3:20190318235348.jpg
done
done
^Cbreak
```
S3でファイルが2つuploadされていることを確認できました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/8325ea19-4f6a-b1e2-0340-f9bc98d190dd.png)
HTML基礎まとめ

<h3>0．背景~</h3>
<p>
Webアプリが作るために、約15年ぶりに触れるHTMLをおさらい。<br>
但し、最低限使うだろう部分に限定して記載します。
</p>

<h3>1．基本フォーマット</h3>
HTMLの基本的なフォーマット

```index.html
<!DOCTYPE html>           ←ドキュメント形式
<html lang="ja">          ← HTML開始 (日本語)
  <head>          　　　　 ← ヘッダ情報
    <meta charset="utf-8">                              ← 文字コード指定
    <title> サイトのタイトル </title>                    ← タイトル
    <meta name="description" content="サイトの説明">     ← サイト情報
  </head>
  <body>                  ← ボディ情報
    <h1> 見出し1 </h1>    ← 見出しサイズ：1~6
    <p> 内容 </p>
  </body>
</html>          　　　　　← HTML終了
```

<h3>2．リストの書き方</h3>
(1) Ordered List：番号付きのリスト
<img width="79" alt="ol.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/9092af3b-e019-1d94-3c46-251f81bd940f.png">

```
<ol>
 <li>item1</li>
 <li>item2</li>
 <li>item3</li>
</ol>
```

(2) Unordered List：番号無しのリスト
<img width="70" alt="ul.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/99778502-bda9-1b52-bfe1-8a43509cc7ca.png">

```
<ul>
 <li>item1</li>
 <li>item2</li>
 <li>item3</li>
</ul>
```

<h3>3．コントロールアイテム</h3>
<img width="160" alt="input_text.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/745bd7d1-5e6f-cd0d-4e07-1ebcf60aac02.png">

```
<form>
  <label for="name">氏名</label>     ← ラベル
  <input type="text" id="name">      ← 入力フォーム
</form>
```

<img width="182" alt="input_message.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/823a7a10-717e-e70a-b7fb-4eec13920f2e.png">

```
<form>
  <label for="message">メッセージ</label>     ← ラベル
  <textarea id="message"></textarea>         ← 入力フォーム
</form>
```

<img width="45" alt="button.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/0bb561ba-47d8-4e9f-3940-6c49aa6cc7fe.png">

```
<form>
  <button>送信</button>     ← ボタン
</form>
```

<img width="81" alt="select.png" src="https://qiita-image-store.s3.amazonaws.com/0/374906/f0c9c7fd-cea6-0fa9-3da2-9fa81825609f.png">

```
<label for="product">商品</label>
<select id="product">
  <option>商品A</option>
  <option>商品B</option>
  <option>商品C</option>
</select>
```

<img width="398" alt="checkbox.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/ea839281-8ec6-cd57-020f-b5c0cf4303db.png">

```
<fieldset>
  <legend>items</legend>
  <input type="checkbox" id="item1"><label for="item1">item1</label>
  <input type="checkbox" id="item2"><label for="item2">item2</label>
  <input type="checkbox" id="item3"><label for="item3">item3</label>
</fieldset>
```

<img width="399" alt="radioPNG.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/374906/1d20b9c4-2ecb-6c06-918f-d852843ddfea.png">

```
<fieldset>
  <legend>items</legend>
  <input type="radio" name="items" id="item1"><label for="item1">item1</label>
  <input type="radio" name="items" id="item2"><label for="item2">item2</label>
  <input type="radio" name="items" id="item3"><label for="item3">item3</label>
</fieldset>
```

<h4>情報ソース</h4>
<ul>
 <li><a href="https://dotinstall.com/lessons/basic_html_tags">ドットインストール：HTML基礎文法入門</a></li>
 <li><a href="https://developer.mozilla.org/ja/docs/Web/HTML">MDN：HTML仕様</a></li>
</ul>
Node.js で AES-256-CBC を使用した暗号化・復号

Node.js で AES-256-CBC を使用した暗号化・復号のサンプルです。

#暗号化

```js
function encrypt(algorithm, password, salt, data) {
	
	// 鍵を生成
	const key = crypto.scryptSync(password, salt, 32)
	
	// IV を生成
	const iv = crypto.randomBytes(16)

	// 暗号器を生成
	const cipher = crypto.createCipheriv(algorithm, key, iv)
	
	// data を暗号化
	let encryptedData = cipher.update(data)
	encryptedData = Buffer.concat([encryptedData, cipher.final()])

	return {iv, encryptedData}
}
```

#復号

```js
function decrypt(algorithm, password, salt, iv, encryptedData) {

	// 鍵を生成
	const key = crypto.scryptSync(password, salt, 32)

	// 復号器を生成
	const decipher = crypto.createDecipheriv(algorithm, key, iv)

	// encryptedData を復号
	let decryptedData = decipher.update(encryptedData)
	decryptedData =  Buffer.concat([decryptedData, decipher.final()])

	return decryptedData
}
```

#サンプルコード

```js
const crypto = require('crypto')

// AES アルゴリズム		
const ALGO = 'aes-256-cbc'

// 事前に共有すべきパスワード
// console.log(crypto.randomBytes(32).toString('base64'))
const PASSWORD = 'l+/MraaOI1yT3F1l15fJMcEKGiG3iWn7nOTmUS4fWk0='

// 事前に共有すべき SALT
// console.log(crypto.randomBytes(16).toString('base64'))
const SALT = 'kr3dJJ1mPcIKisMOR4RO6w=='

// 暗号化したいメッセージ
const MESSAGE = 'piyopiyo'


// 暗号化メソッド
function encrypt(algorithm, password, salt, data) {
	
	// 鍵を生成
	const key = crypto.scryptSync(password, salt, 32)
	
	// IV を生成
	const iv = crypto.randomBytes(16)

	// 暗号器を生成
	const cipher = crypto.createCipheriv(algorithm, key, iv)
	
	// data を暗号化
	let encryptedData = cipher.update(data)
	encryptedData = Buffer.concat([encryptedData, cipher.final()])

	return {iv, encryptedData}
}


// 復号メソッド
function decrypt(algorithm, password, salt, iv, encryptedData) {

	// 鍵を生成
	const key = crypto.scryptSync(password, salt, 32)

	// 復号器を生成
	const decipher = crypto.createDecipheriv(algorithm, key, iv)

	// encryptedData を復号
	let decryptedData = decipher.update(encryptedData)
	decryptedData =  Buffer.concat([decryptedData, decipher.final()])

	return decryptedData
}


console.log('MESSAGE:', MESSAGE)

// 暗号化したいメッセージ文字列を Buffer に変換
const data = Buffer.from(MESSAGE)
console.log('data:', data)

// 暗号化
let {iv, encryptedData} = encrypt(ALGO, PASSWORD, SALT, data)
console.log('iv:', iv)
console.log('encryptedData:', encryptedData)

// 復号
let decryptedData = decrypt(ALGO, PASSWORD, SALT, iv, encryptedData)
console.log('decryptedData:', decryptedData)
console.log('decryptedData(utf8):', decryptedData.toString('utf-8'))
```

#メモ
- 暗号化を行う側と復号を行う側で、事前に安全な経路で PASSWORD と SALT を共有します。
- iv (initialization vector) は必ず毎回変わるようにします。
- 暗号化を行う側から、復号を行う側に渡すのは、暗号化されたデータと iv です。
- 暗号化されたデータと iv は安全でない経路で共有することが可能です。

#Ref.
- https://nodejs.org/api/crypto.html
JS Consoleで直前に実行された値を取得できる変数

ChromeのJS Consoleで直前に実行された値を取得できる変数を紹介します。
## JS Consoleで直前に実行された値を取得できる変数
`$_`がその変数です。
![Screen Shot 2019-03-18 at 23.45.36.png](https://qiita-image-store.s3.amazonaws.com/0/250231/5a851f83-f3c2-7963-bb24-e72ec31e97dd.png)
便利なのでぜひ使ってみて下さい。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Mac mini(Early 2009)にmacOS Mojaveをインストール

前回(→[Mac mini(Early 2009)のSSDを交換](https://qiita.com/uuu_n/items/5b03261f7ff32418814a "Mac mini(Early 2009)のSSDを交換"))、SSDを交換したのでOSを再インストールします。

「[macOS Mojave非対応のMacにMojaveをインストールしてみた](https://shrksoft.net/?p=1008 "macOS Mojave非対応のMacにMojaveをインストールしてみた")」を参考にインストールメディアをSSD交換前に予め作っておきます。私は外付けHDDを一部パーティションを区切ってそこに作りました。

SSD交換後、Optionキーを押しながら起動します。外付けHDDを指定してしばらく待つとインストーラーが起動するはずです。しかし、一向にリンゴマーク下のメーターが進まない。何かがおかしい。ドライブのエラーを疑い、たまたま手元にあったMac OS X 10.5.6 のインストールDVDから起動しました。ディスクユーティリティからFirst Aidを走らせます。再起動し、もう一度外付けHDDを指定すると、無事インストーラーが起動しました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/9a22a69f-714c-41af-4871-4dbdcec764a3.jpeg" width=50%>
日本語を選びます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/f3319554-1b57-f2a1-940c-71cfcf7cb557.jpeg" width=50%>
インストールを進める前に、SSDをフォーマットします。左下にあるDisk Utilityをダブルクリック。SSDを選び、消去。Mac OS拡張(ジャーナリング)を選び、フォーマットが完了したらユーティリティを閉じてインストールを進めます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/45d8b356-c34d-1320-2e7f-b162e8b5d907.jpeg" width=50%>
インストールされます。
インストールが終わると、起動に失敗します。これは正常です。パッチを当てます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/54a8582b-ee54-c662-44ea-7c48ca27bd5b.jpeg" width=50%>
もう一度外付けHDDから起動し、左下にあるMac OS Post Installをダブルクリック。
システムレポートから調べられるモデル番号を選びます。ここでは、Macmini3.1。OSを入れたSSDを選びPatchをクリック。

パッチを当て終わり再起動すると、なぜかカーネルパニックを吐きました。再度外付けHDDから起動し
First Aidを試みるも効果なし。
ここで、以前調べたことを思い出しました。外付けHDDから起動し、左下のTerminalをダブルクリック。

```bash
~# diskutil verifyDisk /dev/disk0
```

でSSDを確認し、

```bash
~# diskutil repairDisk /dev/disk0
```

でSSDを修復。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/84a56ca5-74c0-0d87-eb47-426851918d87.jpeg" width=50%>
名称未設定になっているのが嫌だったので、ディスクユーティリティからMacintosh HDに変更しました。

先程と同様の手順でもう一度パッチを当て、再起動すると無事起動しました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/370590/fc1111d8-3f7a-34df-23db-49d5c587d16d.jpeg" width=50%>
初期設定を済ませれば完成です。

家の中でファイル共有をかけたり、友人や後輩とMinecraftのマルチプレイをするためのサーバーとして使っています。
お金にゆとりができたら、まともなスペックに買い替えたいです。
Node-RED 0.20の新機能　その２

3/12(日本時間だと3/13)にNode-REDの0.20がリリースされました。

せっかくなので[Node-REDのブログ](https://nodered.org/blog/)に投稿されている[Version 0.20 released](https://nodered.org/blog/2019/03/12/version-0-20-released)の内容を試してみようと思います。

[その１の記事はこちら](https://qiita.com/kazsharp/items/43878eabe57d9d752bdb)

##Accessing parent flow context
サブフローの中では、そのサブフローを使っているフローでセットされたflowコンテキストの値を取得することはできませんでした。
例えば以下のようにサブフローの前にchangeノードがあるフローを作成します。
![subflow-parent-1.png](https://qiita-image-store.s3.amazonaws.com/0/100799/c80c7cfc-72d1-326e-6ea6-1b0eb2238880.png)
changeノードではflowコンテキストの ```key1``` というプロパティに"value1"という文字列をセットします。
![subflow-parent-2.png](https://qiita-image-store.s3.amazonaws.com/0/100799/17a4a619-2100-d491-3770-93c87a1bbcc2.png)
そしてサブフローはchangeノードだけのシンプルなフローにします
![subflow-parent-3.png](https://qiita-image-store.s3.amazonaws.com/0/100799/431e32e4-7341-a9a5-046b-8295fc7291cb.png)
changeノードでは、flowコンテキストの ```key1``` プロパティの値を ```payload``` にセットするようにします。
![subflow-parent-4.png](https://qiita-image-store.s3.amazonaws.com/0/100799/91e77f0f-60d9-ba28-bfc9-1d0b2153ceaf.png)
これで最初に作ったフローを実行してみますが、デバッグタブにはundefinedが表示されます。
つまり、サブフローからはサブフローの外でセットされたflowコンテキストの値が見えないということです。
それが今回、キーの前に ```$parent.```というのを追加することでflowコンテキストの値が取得できるようになりました。
サブフローの中のchangeノードを以下のように変更します。
![subflow-parent-6.png](https://qiita-image-store.s3.amazonaws.com/0/100799/d8d7f151-3198-7bf1-ccf5-bf88231aeab7.png)
そしてもう一度フローを実行すると、今度はflowコンテキストの値が取得できてデバッグタブに ```value1``` が表示されることが確認できます。
![subflow-parent-7.png](https://qiita-image-store.s3.amazonaws.com/0/100799/eb94ddc9-6943-a701-d087-188a88290eac.png)

以上、サブフローから親フローのflowコンテキストへのアクセスでした
Node-RED 0.20の新機能　その１

3/12(日本時間だと3/13)にNode-REDの0.20がリリースされました。

せっかくなので[Node-REDのブログ](https://nodered.org/blog/)に投稿されている[Version 0.20 released](https://nodered.org/blog/2019/03/12/version-0-20-released)の内容を試してみようと思います。

## Subflow Status
サブフローにステータスが表示できるようになりました。
サブフローのエディタに「ステータスノード」というトグルボタンが付き、このボタンをオンにすると「status」というリンクノードのようなものがあらわれます。
![subflow-status-1.png](https://qiita-image-store.s3.amazonaws.com/0/100799/b04c9774-3eaf-cf4b-5a06-c762061c9983.png)
これを例えば上の図のようにfunctionノードの出力につなぎ、ステータスに表示したい内容（例えば "hoge" という文字列）をpayloadにセットして出力に送信します。
![subflow-status-2.png](https://qiita-image-store.s3.amazonaws.com/0/100799/6164b970-de6b-4682-cee1-bf1b0376f7bb.png)
このサブフローを使うようなフローを作ってみます。
![subflow-status-3.png](https://qiita-image-store.s3.amazonaws.com/0/100799/1ca0eab9-621e-e95c-7404-6f74dcf978ed.png)
フローを実行するとサブフローの下にステータスが表示されることが確認できます。
![subflow-status-4.png](https://qiita-image-store.s3.amazonaws.com/0/100799/cec903aa-8c92-ca51-ee9b-4f8ffc98b8b6.png)

以上、サブフローのステータス表示でした。
6日目: Data augmentation using synthetic data for time series classification with deep residual networks

# Data augmentation using synthetic data for time series classification with deep residual networks 要約
## 読んだ論文
Data augmentation using synthetic data for time series classification with deep residual networks
Hassan Ismail Fawaz, Germain Forestier, Jonathan Weber, Lhassane Idoumghar, Pierre-Alain Muller
https://arxiv.org/abs/1808.02455
上記の論文を読んだので簡単にまとめます．International Workshop on Advanced Analytics and Learning on Temporal Data, ECML PKDDで発表されているようです．論文読んで気づきましたが，2日目に読んだ[Transfer learning for time series classification](https://qiita.com/himatya/items/6c4aaaa1da8ea0e41906)の著者の人ですね．

## 3行でまとめる
- 時系列分類問題におけるデータ拡張手法を提案する．
- おなじみUCR公開データセットで評価して有用性を示した．
- 拡張だけでなく，拡張→アンサンブルResNetによって精度が向上しやすいことを示した．

## 提案手法
- 認識モデルにはResNet（ただし11層）を使用する．
- 入力は1次元の時系列データで，Conv1Dでつないでいく．
- データ拡張手法には[^1]を応用する.この手法は基本的にはDTWの重み付きDBAを使用してデータ拡張を行うようですが，詳細は明日読むことにします．
- [^1]の手法に対して重みを決定する方法を変えたのが提案手法である．（他にもsoft-DTW等の手法はあるが本稿では検証を今後の課題としている．また不均衡クラスの問題も今後の課題にしている．）

## Weighted DBAの重み決定方法
1. ランダムに初期時系列を選定し，0.5の重みを割り当てる．
2. ランダムに選択された上記の時系列はDBAの初期化に作用するらしい．
3. 続いて，DTW距離を用いて5近傍の時系列を取得する．
4. 5近傍のデータからランダムに2つを選択し，0.15の重みを割り当てる（この段階で合計の重みは0.8）．
5. 残った奴らで残りの重み0.2を共有する．
（元の手法を詳細に読まないとこの重み決定方法の理解が進まない．．．）

[^1]: Forestier, G., Petitjean, F., Dau, H.A., Webb, G.I., Keogh, E.J.: Generating syn-thetic time series to augment sparse datasets. In: IEEE International Conferenceon Data Mining. pp. 865–870 (2017)

## 評価実験
- UCR time series datasets[^2]を用いて提案手法を評価した．
- 相変わらず60以上のクラスタGPUを使用している．計算機の暴力．
- 全体を通しては大幅に精度が下がることはなかった．
- 一方，DiatomSizeReduction datasetでは精度が30％→96％に大幅な向上を果たした．
 - これは，該当データセットが最も少数インスタンス（16データ）であり，提案手法の拡張が極端にうまく働く分布だったためと思われる．
 - また本データセットは元のResNetでは最も精度が悪かったデータセットであり，データ拡張によりこれを改善できたことは興味深い．
 - ただ，Wilcoxonの符号順位検定を行ったが，データ拡張有無で有意差は確認できなかった．
- そこでデータ拡張ありとなしでアンサンブルさせた手法でWilcoxonの符号順位検定を行ったところ有意差が確認できた．（拡張によって精度が下がったデータセットが31から20に減った．）

[^2]: Y. Chen et al.(Jul. 2015).The UCR Time Series Classification Archive.[Online]. Available: http://www.cs.ucr.edu/~eamonn/time_series_data/

## まとめ
- 時系列分類問題において，WeightedDBAを用いたデータ拡張手法に対する重み決定手法を提案した．
- データ拡張有無でアンサンブルしたResNetを用いることで多くのデータセットで精度改善を実現した．

## 所管
今回も選定後～読了まで1時間程度でした．手法自体は引用論文[^1]に丸投げっぽかったので，明日はそちらを読みたいと思います．
Raspberryでボタン押下をGPIOの割り込みで検出

##モチベーション
ラズパイからなんらしかのセンサーの値を元にAWSに通知を上げ、なんらかしら（なんらかしらばっかり 笑）の動作をしたい。まず簡単なところでボタンのプッシュを検出する。GPIOの値をポーリングはできるので、割り込みで実現してみた。

##環境
- RaspberryPi3B+
- Raspbian 9.8
- RPi.GPIO

##参考
https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/

##配線

```
               3.3V
               R│10K 
GND ── Button ──┴─── BCM21(GPIO.29)
```

##pythonプログラム

```gio_int.py
# coding: utf-8
import RPi.GPIO as GPIO
import time

BUTTON_PIN = 21

def main():
	GPIO.setwarnings(False)
	# Set the layout for the pin declaration
	GPIO.setmode(GPIO.BCM)
	# BCMの21番ピンを入力に設定
	GPIO.setup(BUTTON_PIN,GPIO.IN) 
	# callback登録（GIO.FALLING:立下りエッジ検出、bouncetime:300ms）
	GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=callback, bouncetime=300)

	try:
		while(True):
			time.sleep(1)

	# Keyboard入力があれば終わり
	except KeyboardInterrupt:
		print("break")
		GPIO.cleanup()

def callback(channel):
  print("button pushed %s"%channel)

if __name__ == "__main__":
    main()
```
##実行
ポチポチとボタンを2回押すと検出できました。
Ctrl-Cで終わりです。

```
pi@raspberrypi:~ $ python gio_int.py
button pushed 21
button pushed 21
^Cbreak
pi@raspberrypi:~ $
```

ちなみに、bouncetime=1にして動かしてみると、チャタリングのためにボタン1回を2回と検出することがありました。
Delta Swapの簡単解説

#はじめに: Delta Swapとは？
あるビット列において、そのビット列の部分ビット列（連続でなくてもよい）のうち、同じ形のもので、被りがないもの2組を入れ替える操作のことです。

<img width="391" alt="deltaswap.png" src="https://qiita-image-store.s3.amazonaws.com/0/244249/0302d154-ef28-85dc-2f25-62f7251ef078.png">


これを次のようなコードで実現できます。

```cpp:delta_swap.cpp
typedef unsigned long long ull;
ull delta_swap(ull x, ull mask, int delta) {
    ull t = (x >> delta) ^ x & mask;
    return t ^ (t << delta) ^ x;
}
```

**x** は対象のビット列、**mask** は入れ替えたい2組の部分ビット列のうち、下位に位置する方が占めるビットをすべて1で埋めたものです。
**mask** と **mask << delta** が示す2組の部分ビット列を入れ替えます。

この記事では、このコードの一つの理解の仕方を書きます。

## 前提知識（？）
 上のコードを理解する上では、一見当たり前に見える次の恒等式が重要になります。

```cpp:delta_swap.cpp
A ^ B ^ B = A
```

順番を入れ替えても同じ

```cpp:delta_swap.cpp
(B ^ A) ^ B = A
```

これを利用すれば、一時変数を使わない2つの変数のswapが書けます。

```cpp:delta_swap.cpp
// A, Bはリテラルの意味で、C, Dは変数の意味で使います
// C, Dの中身を入れ替えます
// 最初CにはA, DにはBが入っているとします。
C ^= D; // CにA^Bが入る
D ^= C; // DはB^(A^B), すなわちAが入る
C ^= D; // (A^B)^A, すなわちB
```

## 本題: Delta Swap 解説
まず

```cpp:delta_swap.cpp
ull t = (x >> delta) ^ x & mask;
```

は、2つの入れ替えたいビット列のxorを作っているとみなせます。
<img width="359" alt="kai.png" src="https://qiita-image-store.s3.amazonaws.com/0/244249/c5455bb9-545c-d054-adf6-df1c4491273d.png">

よって、

```cpp:delta_swap.cpp
return t ^ (t << delta) ^ x;
```

は、もとのビット列 **x** にこのxorしたものをxorすることによって（日本語がカオス）、ビット列のswapをしている、と理解できます。おわり。

<img width="299" alt="setu.png" src="https://qiita-image-store.s3.amazonaws.com/0/244249/1d0031d0-1903-e733-5be7-6b765983c39b.png">

##さいごに
図が汚い。
aws-amplify-vueで作成した認証画面でSignUpをさせないようにする

# 背景
AWS Amplify + AppSync + Vue で爆速でモダンなフロントエンドが開発できるという噂を聞きつけ、実際に試してみたところ、とてもみみっちいところで躓いてしまったのでその対処法を記述します。
なお、本来の趣旨である「爆速でモダンなフロントエンド開発」という点については、確かに革命的な効果を感じましたので、今後も引き続き深堀りしていきたいと思います。特にAppSyncにはかなり将来性を感じました。
Amplify + AppSync + Vue での具体的なフロントエンド構築方法が知りたい方は、以下の記事を読むことをお勧め致します。私も参考にさせて頂きました。
https://qiita.com/nakayama_cw/items/6d3514b51c5fbf9ba450
https://qiita.com/shunp/items/d491adfadd570f66f990

# サインアップできないようにしたい…！
上記の記事を参考にAmplifyから環境構築し、認証をCognito、APIをAppSyncで作成しました。（ここまで本当にあっという間にできます。）
バックエンド部分はAmplify Consoleのおかげもあり、ほとんどが自動でできます。さすがにフロントエンド部分は自分で書かないといけませんが、それでも`aws-amplify-vue`というパッケージが用意されており、これを使うことで面倒なログイン画面などの作成をスキップすることができます。

ということで、早速このパッケージを使って、ログイン機能を実装しました。具体的な方法は以下の記事が参考になります。
https://qiita.com/maniju/items/d33d64f0b729630d0c3d

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91332/e8fdc52c-b106-4c26-af70-9198ac2766c6.png)

おお、簡単にできました！ログインだけでなく、パスワードリセットの機能やアカウント作成の機能までコンポーネントを読み込んで配置するだけであっという間にできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91332/831d2a09-9dd3-9304-ef69-e484b46bc854.png)
サインアップ画面もこの通り。（ログイン画面のCreate accountより遷移）
必要な項目の追加や削除もパラメータ設定によって変更することができます。（具体的な設定内容は以下ドキュメントを参考のこと。）
https://aws-amplify.github.io/docs/js/vue#authentication-components

さて、自分が作っているサイトは実に細々としたものなので、一般ユーザに勝手に登録されるのも困ります。Cognitoの方は「管理者のみがユーザ登録可能」な設定になっているので、サイトからもサインアップができないようにする必要があります。

が…上述のドキュメントをいくら読んでも、サインアップをさせないようにする設定が書かれていません…orz
サインアップ画面から項目全部消したり、`signUpConfig: null`とかやってみたものの全然ダメでした。

# 結論
GitHubのIssueに書いてありました。
https://github.com/aws-amplify/amplify-js/issues/1993

```javascript
export default {
  ...
  data: function(){
    return {
      authConfig: {
        signInConfig: {
          isSignUpDisplayed : false  // ← コレ！！
        }
      }
    }
  }
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91332/5a284c1c-ff62-1707-279f-0eac617de68d.png)

消えた！
（「No account? Create account」のリンクが。）

このパラメータ、需要は多いと思うんですが、なぜか上述のドキュメントにはまだ載っていません。
この記事が私と同じように悩んでいる方の参考になれば幸いです。
PG::ConnectionBad　の対処法

#PostgreSQLが使えない時

railsでrail s や　rails db:migrate
などのコマンドを使用した際にいかのようなエラーが出た時の対処法です。

```
could not connect to database postgres: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

この様な場合は、SQLサーバーが起動していない事が多いそうです。

サーバーのインストールなどの経験は無く、
はじめてのことであったのでかなり苦戦しました。

#インストールするだけでは使えない
SQLサーバーはインストールするだけではだめで、起動することで使用可能になります。

自動でSQLサーバー立ち上がる設定や環境に慣れてしまっているせいで、
自分で起動する感覚が僕にはありませんでした。

以下のコマンドを実行することで無事にエラー解決が出来ました！

```
 $ sudo service postgresql start
    Starting postgresql service:                              [  OK  ]
```

#参考
以下のサイトが参考になりました。

https://www.postgresql.jp/
https://lets.postgresql.jp/
プログラミングできてキューティーなロボット「Picoh」

Kickstarterで行われているクラウドファンディング:point_down_tone1::point_down_tone1::point_down_tone1:
https://www.kickstarter.com/projects/ohbot2/picoh-an-expressive-little-robot-head
約¥14,683(配送料含む？) £88以上のプレッジ £1=147.52円(2019/3/18)
2019年3月24日(日) 2時7分まで（日本時間）

#Picohってなに？
Picoh(ピコ)とは学校教育向けのロボットです:robot:(←ちょうどこんな頭だけのやつ
様々なセンサーが搭載されており、プログラミングすることによってカスタマイズができます

Picoh開発ツール

| Platform |OS|説明 |
|:-------------------------|----------------------------|------------------------|
|Ohbot App       　        |Windows                   |Windows App            |
|Python 3                  |Windows, Raspberry Pi, macOS |
|Scratch 3                 |Chromebook                   |対応予定  |



Youtubeへのリンク
https://youtu.be/FsYLbatz844

<img src="https://qiita-image-store.s3.amazonaws.com/0/380222/bf136b25-0724-476e-84dc-9de34dbb7d32.png" width=50%>
<img src="https://qiita-image-store.s3.amazonaws.com/0/380222/ed5879bb-7f78-7229-4629-284a2ed4226a.png" width=50%>
https://www.kickstarter.com/projects/ohbot2/picoh-an-expressive-little-robot-head より


|搭載機能(センサー)     　　                        |説明|
|:-------------------------------------|:----------------------------------------------------------------|
| ヘッドノッドモーター                  |ピコの頭を上下に回転させる |
| 鼻センサー                        |鼻に触れてピコーを反応させる          |
| 口のモーター                          |ピコトーク、笑顔としかめ面 |
| ヘッドターンモーター                    |ピコの頭を左右に回転させる |
| アルデュイーノボード                        |コンピュータとメッセージを送受信し、追加のセンサーに接続する |
|マイクロアンプとスピーカー　　　　　　　　　　　　　　　|ピコが大音量で演奏するためのもの         
| LEDベース                           |ピコの色を任意のRGB値に変更する    |
| プログラム可能なLEDマトリックス         |自分の目と瞳孔を描く |
| 点滅と瞳孔位置をアニメート|ピコの目を生き返らせるために |
| 実験                            |グラフィックスとアニメーション |
| 個別制御                       |16×9グリッド表示で144ピクセル |
Google翻訳より


##できること
・LEDの点灯や口のモーター部分を制御することで顔の表情を変える
・人の顔を認識し、その人の名前で挨拶する
・要求に応じて時間や日付を教えてくれたり、歌を歌う、音楽に合わせて踊ることも可能

そのほかにもカスタマイズ次第でたくさんのことができます!!(今思いつかない...

##最後に
教育向けということで子供向けかと思いきや、大人でも楽しめそうですね:laughing:
日本人で紹介している人をあまり見かけなかったので、一人でも多くの人に知ってもらえれば嬉しいです
興味を持った方はページトップのリンク先に詳細が書かれています(英語ですが・・・)
最後まで読んでくれてしゃーした:bread: