OmniAICreator/Qiita-1.07M huggingface dataset:
AngularのReactive Formsを使って入力内容に応じて動的にフォームの表示を変える

## 概要
Angularで動的にフォームの入力欄を追加したり、入力内容に応じて入力欄の表示を切り替えられるか確認してみました。

## 前提となる参考サイト
まずは[Reactive Forms](https://angular.io/guide/reactive-forms)のドキュメントを参照。また、[AngularのForm（Reactive Forms）メモ](http://ryotah.hatenablog.com/entry/2017/08/31/210723)のブログ記事はReactive Formsについて簡潔にまとめられていて分かりやすいです。

## サンプルソース
あるテキストボックスで入力した内容に応じてもう一方のテキストの表示を切り替えるサンプルを下記に載せます。上記参考サイトの内容を少し編集したものにしています。Angular5で動作すること確認しています。

###Moduleの設定

```test.module.ts
import { NgModule }      from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule }  from '@angular/forms';

@NgModule({
  imports:[ CommonModule ,FormsModule , ReactiveFormsModule ]
})
export class TestModule { }
```
###コンポーネント

```test-reactiveforms.component.ts
import { Component, OnInit} from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

@Component({
  template: `   
    <form [formGroup]="testFormGroup">
        <div formArrayName="testlist">
           <div *ngFor="let test of testlist.controls; let i=index" [formGroupName]="i">
                City1:<input type="text" formControlName="city1" /><br/>
                <span *ngIf="test.get('city1').value == 'aaa'">
                    City2:<input type="text" formControlName="city2" />
                </span>
            </div>
         </div>
         <input type ="button"  (click)="addInput()" value="入力欄を追加" />
     </form>
  `
})
export class TestReactiveFormsComponent  { 
    
    // 計算式のフォームグループ
    testFormGroup: FormGroup;
    
    constructor(private fb: FormBuilder) {
             // フォームグループ初期化
             this.testFormGroup = this.fb.group({
                 testlist: this.fb.array([]),
             });
    }
    
    // 追加ボタンが押されたとき
    addInput() {
       this.testlist.push(this.fb.group({ city1: 'test1',city2: 'test2'}));
    }
  
    // リストの取得用
    get testlist(): FormArray {
        return this.testFormGroup.get('testlist') as FormArray;
    };

}
```
###画面のイメージ
この状態から入力欄を追加ボタンを押します。
<img width="183" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/32098/27c7c314-6b62-7210-0e49-5d434c5f7f27.png">
City1の入力欄が増えます。
<img width="177" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/32098/dcaf6ee7-9034-9602-54e4-ee2b5ce0d62f.png">
上のCity1の入力欄に「aaa」を入力するとCity2の欄が表示されます。
<img width="173" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/32098/66dde7e3-ee22-591b-416b-62217377e119.png">
下のCity1の入力欄に「aaa」を入力するともう一つCity2の欄が表示されます。
<img width="166" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/32098/cac0002d-57bb-bcd4-41fb-6672b8a977a6.png">
上のCity1の入力欄を別の値にすると、上のCity2の欄が非表示となります。
<img width="163" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/32098/6c7e051e-0f7e-ddf8-cfd1-538b0403bb7e.png">
【Swift】テキストフィールドをアラートに乗せる

# １．はじめに

　ユーザ名、パスワード入力や簡単なテキスト入力のために、`UIAlertController` の上に`UITextField` を乗せたいことがあります。
　今回は二つ乗せてみます。

まずは完成形。

<img width="538" alt="スクリーンショット 2018-05-19 22.37.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/124577/beb7e245-e49c-a5c6-d26f-569eb2676313.png">


#  ２．コード

```swift
        let ac = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert)
        let ok = UIAlertAction(title: "OK", style: .default, handler: {[weak ac] (action) -> Void in
            guard let textFields = ac?.textFields else {
                return
            }
            
            guard !textFields.isEmpty else {
                return
            }
            
            for text in textFields {
                if text.tag == 1 {
                    self.label1.text = text.text
                } else {
                    self.label2.text = text.text
                }
            }
        })
        let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        
        //textfiled1の追加
        ac.addTextField(configurationHandler: {(text:UITextField!) -> Void in
            text.text = self.label1.text
            text.tag  = 1
        })
        //textfiled2の追加
        ac.addTextField(configurationHandler: {(text:UITextField!) -> Void in
            text.text = self.label2.text
            text.tag  = 2
        })
        
        ac.addAction(ok)
        ac.addAction(cancel)
        
        present(ac, animated: true, completion: nil)

```

OKボタンをタップした際に入力内容を取得して、`UILabel` に設定しています。
一つ目と二つ目の`UITextField` は`tag` を使って識別しています。
`ac`に`addAction`する際に`tag` を設定しています。

OKボタンをタップした際に`UITextField`を取得しますが、`[UITextField]?`で定義されているので、`guard`を使って安全に`UITextField` を取り出します。
VirtualBoxマネージャーが起動しているとホストのスリープ・復帰を繰り返していた

画面を閉じていてスリープ中のはずのWindows10ノートPCで、HDD/SSDアクセスランプが点滅していることに気づきました。

イベントビューアーを見るとこんな感じで1,2分おきにスリープ、復帰を繰り返していてなんだろうこれはと。
![iii.PNG](https://qiita-image-store.s3.amazonaws.com/0/252749/5d6aee1a-d84e-a81e-2e62-ec136dfff536.png)
この前まで普通にスリープしていたのは確認しているので、なにかがあったのでしょう。

#原因はなんだ？

Windows10の「設定」の電源周りを確認しましたが特にそれらしいものは見当たりません。
何かのデバイスによるものかを管理者コマンド・プロンプトでpowercfgコマンドで見てみます。

```
C:\>powercfg -devicequery wake_armed
```

![ii3.PNG](https://qiita-image-store.s3.amazonaws.com/0/252749/857c097f-ca87-170e-b6f0-715fd240da61.png)

が、NONE、と。
何かのデバイスが起こしたのではないらしい。

じゃあ誰がと表示させてみると

```
C:\>powercfg -lastwake
```

![i6.PNG](https://qiita-image-store.s3.amazonaws.com/0/252749/fb7afb9a-1843-83ae-fb2f-2927677bb572.png)

<b>VirtualBoxかっ！</b>

仮想マシンは「保存」状態にしていましたが、VirtualBoxマネージャーを特に閉じていなかったための現象だったようです。
何のことはなく、VirtualBoxマネージャーを普通に終了させるとスリープ・復帰を繰り返していた現象は解消されました。

バッテリ運用の際は気をつけなきゃね。
Letsencryptでワイルドカード証明書取得(Ubuntu 16.04.4 LTS)

# Letsencryptでワイルドカード証明書取得(Ubuntu 16.04.4 LTS)
解説なしのメモです

## レポジトリの追加
Ubuntu 16.04.4 LTSはletsencryptパッケージがありますが、ワイルドカード証明書には対応していませんので、対応している物を導入します。幸いレポジトリがあるようで楽できるぞと追加します。Certbot0.22以上が必要。

```
sudo add-apt-repository ppa:certbot/certbot
```

## アップデート

```
sudo apt update
```

## インストール

```
sudo apt install certbot
```


## 証明書の取得
証明書の取得コマンドです「-d」に「*.ドメイン」でワイルドカードを指定します。--serverにacme v02が使えるサーバを指定します。

```
$ sudo certbot certonly --manual -d *.mphosato.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
```

## TXTレコードの設定
ワイルドカード証明書取得のプロセスでは指定のFQDNにTXTレコードを付与することで認証します。証明書の取得コマンドの出力に以下のように出ます。

```
Please deploy a DNS TXT record under the name
_acme-challenge.mphosato.com with the following value:

aprhgVTKZOJTe85yRqqe1XJFF3eN6fZUQjLyQYN8YDk

Before continuing, verify the record is deployed.
```

「_acme-challenge.mphosato.com」のTXTレコードに「**aprhgVTKZOJTe85yRqqe1XJFF3eN6fZUQjLyQYN8YDk**」を設定して反映された頃を見てエンターを押すと進みます。

次のように**Congratulations!**と出たら取得できました。

```
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/mphosato.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/mphosato.com/privkey.pem
   Your cert will expire on 2018-08-17. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

```
【図解】API Gatewayとは？

API Gatewayの概要を簡単に紹介します。

##通常のMicroserviceのアーキテクチャ
![microservicearch.png](https://qiita-image-store.s3.amazonaws.com/0/258400/37531e4c-b5f4-8a0c-fa59-3ca438021aef.png)
クライアントは各サービスのAPIと通信

##API Gatewayを用いたMicroserviceのアーキテクチャ
![apigateway.png](https://qiita-image-store.s3.amazonaws.com/0/258400/0b3ffe6f-a704-f522-3f89-ec7adc129347.png)
クライアントはAPI GatewayのAPIにのみと通信

##API Gatewayの利点
- 複雑なAPI処理のカプセル化（クライアントからは見えない）
- 多数のAPIをサーバサイドでモニタリング、認証、管理

##API Gatewayの欠点
- API Gatewayがボトルネックになりうる
- トランザクションがフェールした時に整合性を保つのが難しい。Readは良いがWriteは工夫が必要

##API Gatewayサービス
- Kong
- Netflix API Gateway
- AWS API Gateway
- Tyk
- Falcor
など
RaspberryPi3にインストールしたOpenWRTでWPA2-PSKのパスフレーズをGUIではなくコマンドで書き換える

# WPA2-PSK な WiFi アクセスポイントのパスフレーズを定期的に自動で更新したい

というようなことを考えた場合に、市販のWiFiアクセスポイントを使っていると、案外やりづらい。（法人向けのデバイスならシェルにログインしてコマンド実行、という方法もできるかもしれないけれど）

しかし、管理上の理由からパスフレーズを定期的に変更したいケースはあると思います。パスワードの定期的な変更がセキュリティ上の防御として不適切という話もありますが、それはエンドユーザに定期的なパスワード変更を強いる管理手法の話ですね。WPA2-PSKのようにパスフレーズを複数名で共有するような運用の場合は定期的に書き換えたいものです。（業務向けなら WPA2-EAP だと思いますが、ここでは、そこまでの管理ができないネットワークを前提にします）

でも OpenWRT な WiFi ルータなら、シェルからコマンド実行で書き換えできるので、こういう管理がやりやすいです。

なお、ここで紹介する内容は、記事のタイトルにもあるとおり Raspberry Pi 3B で行っています。Raspberry Pi で行うのは技適をパスしているデバイスだからです。3B+ は手元にないので確認していません。

# パスフレーズの確認とか変更とか

OpenWRT では uci コマンドで設定を確認したり、書き換えたりすることができます。


## 現在の設定の確認方法

OpenWRT にログインして以下のように実行すれば、現在のパスフレーズを確認できます。

```
# uci show | grep -e ssid -e key
uhttpd.main.key='/etc/uhttpd.key'
wireless.default_radio0.ssid='LEDE'
wireless.default_radio0.key='パスフレーズ'
```

## 書き換え方法

コマンドを3つ、こんな風に実行するだけで書き換えができます。ちなみにこれを WiFi 接続しているクライアントから実行すると、実行完了した瞬間に WiFi 接続が切れることにご注意ください。

```
uci set wireless.default_radio0.key='update_psk_by_command'
uci commit wireless
wifi
```

こういう作業が自動化できるなら、パスフレーズ用の文字列も自動生成したいわけですが、OpenWRT 上でパスフレーズ用のランダム文字列を生成したい場合は、例えばこんな方法で作れます。

```
strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 8 | tr -d '\n'
```

Linux でよくあるやり方は fold を使う方法だと思いますが、OpenWRT には fold コマンドがデフォルトではインストールされていないので、代わりの方法となると、こういう感じになります。


# 実際の運用方法

実際にこういった運用を行う場合は、こういう感じでやるのが良さげです。

- パスフレーズ自体は、パスフレーズの変更日より前に生成し、変更日より前に関係者各位に通知する
- 変更日になったら予め作成しておいたパスフレーズを設定に適用する

このようにすることで、変更予定のパスフレーズを事前に共有できます。変更の影響を受けるクライアントがWiFi接続しかできず、しかもパスワードを定期変更するWiFiにだけ接続している場合は変更情報を事前に共有しておかないと色々面倒なので、そういう面倒な状況が起きないようにしましょう。

また、メールでパスフレーズ自体を通知するだけではなく、iOS/macOS向けの場合はプロファイルにしたものをメール添付するとさらに便利です。iOS/macOS向けのプロファイルは有効期限を設定できるので、定期的はパスフレーズ変更を行うWiFi接続設定はプロファイルにして共有すれば、自動的に設定を消滅させる運用ができます。また形式は XML ですから、スクリプトから自動生成するのも容易です。

または、WiFi設定用のQRコードを Google Spreadsheet などで共有するのも一つの手です。この実装を行うには次の情報を参考にしてください。

- WiFi設定用のQRコードは https://zxing.appspot.com/generator/ や https://chart.apis.google.com/ で生成できる
- WiFi設定用のQRコードはiOSの標準カメラアプリで読むとWiFi設定を自動で行ってくれる
- Androidの場合[ZXing Team の QRコードスキャナ](https://play.google.com/store/apps/details?id=com.google.zxing.client.android&hl=ja)で読むとWiFi設定を自動で行ってくれる
- Google Spreadsheet のワークシート関数 image() を使えば画像として生成されたQRコードをセル内で表示できるため、zxing.appspot.com や chart.apis.google.com で生成できるQRコード画像を Spreadsheet に表示させられる
[Xcode]dyld: Library not loadedでiPhone実機ビルドが出来ないときにしたこと

# 実行環境
-  MacOS High Sierra 10.13.4
-  Xcode 9.3.1

# エラー状況
実機でビルドをしようとしたときに、以下のエラーが出てビルドができなくなりました。

```
dyld: Library not loaded: @rpath/RxSwift.framework/RxSwift
  Referenced from: /var/containers/Bundle/Application/xxx/xxx.app/xxx
  Reason: no suitable image found.  Did find:
	/private/var/containers/Bundle/Application/xxx/xxx.app/Frameworks/RxSwift.framework/RxSwift: code signing blocked mmap() of '/private/var/containers/Bundle/Application/xxx/xxx.app/Frameworks/RxSwift.framework/RxSwift'
```

# 解決方法
Xcodeを入れ直したりしてもビルドできませんでしたが、色々調べた結果、こちらが参考になりました。
[Apple Developer Forums : Unable to Run Application on Device “dyld: Library not loaded”](https://forums.developer.apple.com/thread/67215)

- キーチェーンからビルドに必要な証明書を削除する
- DerivedDataとProvisioning Profilesの削除

```
rm -rf ~/Library/Developer/Xcode/DerivedData/
rm -rf ~/Library/MobileDevice/Provisioning\ Profiles/
```
- Mac の再起動
- 証明書やProvisioning Profilesの設定
- Xcodeのクリーン(Shift+⌘+K) 
- 実機ビルド:ok_hand:

何か参考になれば幸いです。
nodeでhttp2を試す

ローカルホストでhttp2の動作を見るには、まず証明書を作成する必要がある

```
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -keyout localhost-privkey.pem -out localhost-cert.pem
```

そうすると、http2でサーバを動かせる

```js
const http2 = require('http2')
const fs = require('fs')

const { PORT = 8443 } = process.env

const server = http2.createSecureServer({
  key: fs.readFileSync('localhost-privkey.pem'),
  cert: fs.readFileSync('localhost-cert.pem')
})
server.on('error', err => console.error(err))

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  })
  stream.end('<h1>Hello World</h1>')
})

server.listen(PORT, () => {
  console.log(`https://localhost:${PORT}`)
})
```

http2をブラウザで確認するには、ChromeのDevtoolのネットワークタブを右クリックしてPriorityとProtocolと有効にする。
Protocolがh2であればhttp2で通信していることが確認できる。

また、[HTTP/2 and SPDY indicator - Chrome ウェブストア](https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=ja)を使うことでどのアプリケーションがhttp2で動作しているかすぐに確認できるので、便利。
Ansibleのvmware_vm_shellで実行したコマンドの実行完了を待つモジュールを作ってみた

AnsibleのモジュールでvSphere API経由からゲストOSにコマンドを実行するモジュール [vmware_vm_shell](http://docs.ansible.com/ansible/latest/modules/vmware_vm_shell_module.html#vmware-vm-shell-module) があります。
このモジュールを使ってコマンドを実行すると、コマンドはバックグラウンドで動作します。
モジュールは問題なくコマンドがバックグラウンドで動作したことが確認できれば処理が完了してしまいます。
そのためバックグラウンドで実行しているプロセスの実行を待つことはしません。
そこで `vmware_vm_shell` モジュールで実行したコマンドの処理完了を待つモジュールを作ってみました。

# 1. 課題のおさらい

`vmware_vm_shell` モジュールでコマンドを順次処理する場合、前のコマンドが完了してから次のコマンドを実行するということができません。
例えば、以下のPlaybookを実行してみます。

```yaml
---
- name: VMware Module TEST
  hosts: localhost
  gather_facts: no
  tasks:
    - vmware_vm_shell:
        hostname: vcenter.local
        username: administrator@vsphere.local
        password: secret
        validate_certs: no
        vm_id: devel
        vm_username: root
        vm_password: secret
        vm_shell: /root/loop.sh
        vm_shell_args: 3
```

このPlaybookではdevelというVMで `/root/loop.sh 3` を実行するものです。
`loop.sh` は単純にsleepするだけのものです。

```bash
#!/usr/bin/bash
for (( i = 0; i <= $1; i++ )) ; do
  sleep 1
done
```

実行してみます。

![ansible_vm_shell_01.gif](https://qiita-image-store.s3.amazonaws.com/0/180118/7d1e9d45-9efa-65ce-ff49-f1b521e1a3e3.gif)


コマンドが実行されバックグラウンドで動作しモジュール側の処理は完了していることが確認できます。

# 2. vmware_vm_shell_waitモジュール

そこで `vmware_vm_shell` で実行したコマンドの処理完了を待つモジュール `vmware_vm_shell_wait` を作ってみました。

[https://github.com/sky-joker/ore-ore-ansible/blob/master/modules/cloud/vmware/vmware_vm_shell_wait.py](https://github.com/sky-joker/ore-ore-ansible/blob/master/modules/cloud/vmware/vmware_vm_shell_wait.py)

## 2-1. 使い方

### 2-1-1. モジュールのダウンロード

```bash
$ curl -L https://raw.githubusercontent.com/sky-joker/ore-ore-ansible/master/modules/cloud/vmware/vmware_vm_shell_wait.py -O
```

### 2-1-2. Playbook

`vmware_vm_shell` でコマンドを実行して `vmware_vm_shell_wait` で実行完了を待つPlaybook例です。

```yaml
---
- name: VMware Module TEST
  hosts: localhost
  gather_facts: no
  tasks:
    - vmware_vm_shell:
        hostname: vcenter.local
        username: administrator@vsphere.local
        password: secret
        validate_certs: no
        vm_id: devel
        vm_username: root
        vm_password: secret
        vm_shell: /root/loop.sh
        vm_shell_args: 3

    - vmware_vm_shell_wait:
        hostname: vcenter.local
        username: administrator@vsphere.local
        password: secret
        validate_certs: no
        vm_id: devel
        vm_username: root
        vm_password: secret
        vm_shell: /root/loop.sh
        vm_shell_args: 3
```

### 2-1-3. 実行する

![ansible_vm_shell_02.gif](https://qiita-image-store.s3.amazonaws.com/0/180118/644ae4b7-bd7d-956f-c400-a7eefcc1ceee.gif)

バックグラウンドで実行されたコマンドの処理が完了したのを確認して `vmware_vm_shell_wait` の処理が完了していることが確認できました :-)
RubyとRails初心者向けの開発環境Dockerを作ってみた

## はじめに
30歳のフリーランスのエンジニア ゆっけ([@prg_yukke](https://twitter.com/prg_yukke))です。
生粋のPHPerでしたが、RubyとRailsを習得しなければならなくなったため、それぞれの学習を進めています。

その過程で、それぞれの開発環境をDockerで作りましたので公開いたします。

## 前提
この記事ではDockerの設定の仕方などは説明しません。
手っ取り早く開発環境が欲しい人向けです。
また、それぞれの環境の立ち上げ方については、レポジトリのREADMEに記載してありますので、詳しくはそちらをご覧ください。
この記事ではそれぞれを使用する際の補足情報などを記載いたします。

## 結論
レポジトリだけ教えろという方向けに、各開発環境のレポジトリを先に記載します。

- Ruby → [prgyukke/Docker_for_Ruby](https://github.com/prgyukke/Docker_for_Ruby)
- Ruby on Rails → [prgyukke/Docker_for_Ruby_on_Rails](https://github.com/prgyukke/Docker_for_Ruby_on_Rails)

補足情報などを確認したい方はスクロールして下へお進みください。

## Ruby開発環境
Rubyの開発環境用はこちらのレポジトリです。 → [prgyukke/Docker_for_Ruby](https://github.com/prgyukke/Docker_for_Ruby)

コンテナはRubyが動作する`app`コンテナとMySQL用の`db`コンテナの合計２つによる構成になっています。
それぞれのバージョンは下記のとおりです。

- Ruby 2.5
- MySQL 5.7

また、MySQLのroot及びアプリデータベース用ユーザ想定であるappユーザのパスワードはREADEMEに記載してあります。
ただし、開発環境用のユーザとパスワードとなりますので、本番環境では絶対に使用しないでください。

## Ruby on Rails開発環境
同じくRoRの開発環境用レポジトリはこちらです → [prgyukke/Docker_for_Ruby_on_Rails](https://github.com/prgyukke/Docker_for_Ruby_on_Rails)

Ruby用と同じくコンテナは`app`と`db`の２つから構成されています。
それぞれのバージョンは下記のとおりです。

- Ruby 2.5
- Ruby on Rails 5.1.6
- MySQL 5.7

`config/database.yml`に必要情報の記載をしてありますので、DBを使う際にも設定を書き加える必要はありません。

また、コンテナの初回立ち上げ(`docker-compose up -d`)より前にルートディレクトリ名を変更しておくと、コンテナ名もそちらに影響されるため幸せになれるかと思います。

## まとめ
開発環境のことは正直わからんと言う人も、レポジトリをgit cloneするだけで開発環境を得られ、楽に開発に入ることが出来ます。

RoR用レポジトリではWEBサーバ用コンテナも導入予定ですが、RoRでのWEBサーバの定石が未調査のため、まだ導入できていません。
玄人さんがいらっしゃいましたら、RoRでのWEBサーバをどのようにしているのかコメントにて教えてくださると幸いです。
python複素数平面上で図形を動かすー平行移動と回転

python,numpyを使って複素数平面上で回転と平行移動を行いました。母の日のプレゼントにしたかった。

![heart.png](https://qiita-image-store.s3.amazonaws.com/0/257157/34af5f8b-3a05-c6ea-93a1-206fc78841c8.png)




コードの背景となる数学は暇な時書きます。numpyで実装しました。
#背景となる数学と目的
そのうち書く

#コード

```python:heart.py
import matplotlib
matplotlib.use('Agg') #under my ssh environment,the matplotlib cannnot work as usual so i need matplotlib.use('Agg')
import numpy as np
import matplotlib.pyplot as plt

# the fundamental heart gragh  grath00

t = np.linspace(0, 2 * 3.141, 100)
sin1 = np.sin(t)
cos1 = np.cos(t)
cos2 = np.cos(2 * t)
cos3 = np.cos(3 * t)
cos4 = np.cos(4 * t)

gragh_00 =( sin1 ** 3 + ( 13 * cos1 - 5 * cos2 - 2 * cos3 - cos4 ) * 1j/ 15 ) * 4 / 8
#plot
plt.plot(np.real(gragh_00 * 7 / 8 ), np.imag(gragh_00 * 7 /8), linewidth =4, color="red")
# copy heart gragh 24 times

# making point array
point_list =  [[a -2 + ( b - 2 ) * 1j] for a in range(5) for b in range(5)]
point_list.remove([0j])
point_array = np.array(point_list)
    
for i in range(24):
        gragh_0i = point_array[i] - 1j * gragh_00 * (point_array[i] / np.absolute(point_array[i]))
        plt.plot(np.real(gragh_0i * 7 / 8 ), np.imag(gragh_0i * 7 /8), linewidth =4, color="red")

                    
plt.axis('equal') #without this command matplot change axi's ratio
plt.savefig('heart.png')

```
#出力
![heart.png](https://qiita-image-store.s3.amazonaws.com/0/257157/cf64dfee-b547-bfdf-2eda-315a030ddca4.png)
決まった文字数で折り返す

メモです。

久しぶりに while とか index を使った。最近はコマンドに頼りすぎで脳が頼りない。

```powershell
Function Fold-String {
    param(
        [Parameter(Mandatory=$False)]
        [int]$Width = 80,

        [Parameter(ValueFromPipeline=$True)]
        [string[]]$String
    )
    process {
        foreach($s in $string){
            $index = 0
            $Length = $s.Length
            while(($index + $Width) -lt $Length){
                $s.SubString($index, $Width) # output
                $index += $width
            }
            $s.SubString($index) # all of remaining
        }
    }
}
```
開発に使えるWebサイト集、完全オレ向け用

毎回検索してWebサイトを開くのが面倒臭いので一旦普段使っているWebサイトをまとめようと思う。

### カラーコード

RGBから16進数への変換だったり、
16進数からRGBへの変換だったりでデザインの実装の際に開きます。

[RGBと16進数カラーコードの相互変換ツール](https://www.peko-step.com/tool/tfcolor.html)

[カラーコード変換ツール Ver3](https://syncer.jp/color-converter)

### Swiftコンバーター

今でもObjective-Cコードが入っているプロジェクトにアサインした時にだいたい開いています。

[objc2swift ](http://objc2swift.yahoo-labs.jp/)

[Swiftify](https://objectivec2swift.com/#/home)


### [iOS]cocoapodのインストール


[【iOS】cocoapodsのインストール方法](https://qiita.com/SoyaTakahashi/items/fdb0d87597eb276056d8)

[MacにHomeBrew,rbenv,bundlerをインストールする](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b)

### jsonのチェック

APIとの連携の際に使っています。
サーバーサイドにJsonの出力で間違ってないかを連絡する時とか、
DBモデルに変数をセットする時とか。

[SYNCER](https://lab.≈.jp/Tool/JSON-Viewer/)

[Restlet Client - REST API Testing](https://chrome.google.com/webstore/detail/restlet-client-rest-api-t/aejoelaoggembcahagimdiliamlcdmfm)

### Swiftコーディング

iOSの開発ではもう逆引きは開いてないけど、これはつかえそう・・・？

[逆引きSwift](http://docs.fabo.io/swift/)

[Ray Wenderlich | High quality programming tutorials](https://www.raywenderlich.com/)
Nuxt.jsのcontext.isXXXの歴史

## contextの使い方と問題
Nuxt.jsはビルド時の拡張機能としてよく以下のように `context.isDev` `context.isClient` 等を使います
extendの第二引数がcontextオブジェクトとなっています

```js:nuxt.config.js
module.exports = {
  build: {
     extend (config, { isDev, isClient }) {
       // ...
     }
  }
}
```

しかしながらこのような `isDev` , `isClient` 等はバージョンによって推奨、非推奨、使用不可など別になっており注意が必要なようです

## バージョンごとのcontext

一部自分で試したものもありますが、リファレンスで読んだだけのものなどもあるので全ては確認していません。間違ってたらごめんなさい。指摘していただけるととても嬉しいです

### v1.0.0未満

isDevは使えず、devを使うようです

|判定するもの||
|:--|:--|:--|
|開発環境|context.dev|
|サーバー|context.isServer|
|クライアント|context.isClient| 

### v1.0.0以降
[リリースノート](https://ja.nuxtjs.org/guide/release-notes)確認したところv1.0.0において以下のようにかいてありました

>
For the below depreciation, it will still work but you will get a warning to tell you to change your code to the new value.
>
For better bundling experience for server-side and client-side, we deprecated context.isClient and context.isServer in flavor of process.client and process.server. Since these variables comes from our webpack configuration, it will optimize your client-side and server-side bundles magically :nail_care:
>
We also deprecated dev property inside build.extend() in flavour of isDev.

つまりこんな感じです

|判定するもの|推奨|非推奨|
|:--|:--|:--|:--|
|開発環境|context.isDev|context.dev|
|サーバー|process.server|context.isServer|
|クライアント|process.client|context.isClient|

### v1.4.0

現在のものです
v1.0.0と推奨、非推奨が逆になってるっぽいです

参考
https://nuxtjs.org/api/context/

|判定するもの|推奨|非推奨|
|:--|:--|:--|:--|
|開発環境|context.isDev||
|サーバー|context.isServer|process.server|
|クライアント|context.isClient|process.client|

### v2(nuxt-edge)

まだ先行リリース段階ですが、また変わってたようです
`isServer` , `isClient` は廃止。バイバイありがとうさようなら
ちなみに `options.dev` も `options.isDev` になったようです

参考
[Nuxt 2 is coming! Oh yeah!](https://medium.com/nuxt/nuxt-2-is-coming-oh-yeah-212c1a9e1a67)
[【実録】Nuxt.jsの既存プロジェクトを一足早くNuxt v2( nuxt-edge )へとアップグレードする方法](https://qiita.com/potato4d/items/7b3119c88869d7622a7d)

|判定するもの||
|:--|:--|:--|
|開発環境|context.isDev|
|サーバー|process.server|
|クライアント|process.browser|
google form で簡単情報収集　情報を集めたあとは編集がすぐにできる状態にしよう

# まずはスクリプト編集しよう
この編集の作業でトリガーを設定して、
パーミッションを与えれば出来上がり。
以下のサイトが参考になるので、是非挑戦してみてください。
この他にいくつかのクリエイティブなことに挑戦してみよう。
[海外の説明サイト](https://gist.github.com/rubenrivera/4ed2110cda3fbdbc29d2d2d3a4af29c0)が参考になると思います。すこしうまくいかなかったので以下のコードを参考にするといいですよ。
トリガーの場所が変更になっていたので公式ページの[サポート](https://developers.google.com/apps-script/guides/triggers/installable)も載せておきますね。

## 具体的な例１
##具体的な例２
##　具体的な例３
サンプルコードはこちらです。
この箇所を編集するというところにあなたのIDを打っていけばよいですね。

```script
/*
 * Global Variables
 */

// Form URL
var formURL = 'https://docs.google.com/forms/d/このかしょを編集する/edit';
// Sheet name used as destination of the form responses
var sheetName = 'Form Responses 1';
/*
 * Name of the column to be used to hold the response edit URLs 
 * It should match exactly the header of the related column, 
 * otherwise it will do nothing.
 */
var columnName = 'Edit Url' ;
// Responses starting row
var startRow = 2;

function getEditResponseUrls(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues(); 
  var columnIndex = headers[0].indexOf(columnName);
  var data = sheet.getDataRange().getValues();
  var form = FormApp.openByUrl(formURL);
  for(var i = startRow-1; i < data.length; i++) {
    if(data[i][0] != '' && data[i][columnIndex] == '') {
      var timestamp = data[i][0];
      var formSubmitted = form.getResponses(timestamp);
      if(formSubmitted.length < 1) continue;
      var editResponseUrl = formSubmitted[0].getEditResponseUrl();
      sheet.getRange(i+1, columnIndex+1).setValue(editResponseUrl);
    }
  }
}
```

### スクリプトにおけるまとめ
これを使うとRuby on Railsをやらずとしてもさまざまな情報を簡単に管理できるようになってくると思う。この調子で少しずつ情報を管理しながらとっても使いやすいものを設計していきたいと思う。
とにかく流れ的にはCRUDクラッド処理を意識すればいいわけだから簡単である。
UI設計はグーグルがある程度やってくれているのでとっても楽である
備忘録＠作成中


Dockerとは？
「コンテナ型仮想化」

サンプル
『すでにGoogleは全部のソフトウェアをコンテナに乗せており、毎週20億個ものコンテナを起動している』
http://www.publickey1.jp/blog/14/google20.html

ではいつも使う環境と何が違うの？？？メリットやデメリットは？？？

いつも使う環境とは『ハイパーバイザー型の仮想化』で
アプリは「BootCamp」や「VirtualBox」、「ESXi」や「Hyper-V」などの環境です。

メリットは
とにかく軽い。

その理由は
ホストOSとカーネルを共有しているので、VM(仮想マシン)にOSをインストールする必要はなく、
最低限必要なバイナリ・ライブラリ・構成ファイルが含まれた最小構成のVM(仮想マシン)を
稼働させることが可能

そして慣れれば「環境構築 + 起動が早い」
オーケストレーションを考えると、マッチングしやすいです。

デメリットとしては、使用するOSが限られることです。
コンテナ仮想化をサポートしているOSしか利用できません。
OSS環境だとWindowsが未サポートです。
Hyper-Vコンテナを利用すると、Windowsがサポートされますが。。。

はい皆さん想像したとおりです。

メリットとして挙げた「とにかく軽い」のが消えます。

ではAWSで構築したTomcat環境を見てみましょう。

１．AmazonLinuxでDockerホストを構築

２．コンテナを動かすための環境準備

３．初期コンテナ作成

４．コンテナの環境変更
iPad上でlinuxを動かし開発環境を整えるまで

書きかけで気が向いたら、いろいろ追記します
とりあえずこういうことができますって動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr">ssh_linux_on_iPad_Pro test <a href="https://t.co/MxaolFhQqs">https://t.co/MxaolFhQqs</a></p>&mdash; ゲロかけられマン (@78910jqk13) <a href="https://twitter.com/78910jqk13/status/997813829059817473?ref_src=twsrc%5Etfw">2018年5月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#現在の開発環境
iPadでこんな感じで音楽聴きながら作業できてたのしい。
![IMG_0136.JPG](https://qiita-image-store.s3.amazonaws.com/0/257157/ceab628a-f76f-63e8-5a30-b888ea70c3b1.jpeg)

やったこと
1.google platform でVMを契約 +Ubuntuのinstall　+ sshの設定
2.tumx gdriveをインストール tumxいれることでほんと一瞬で開発環境に戻れます。おすすめ
3.minicondaでpythonで開発できるようにする
4.google driveにアップロードできるようにする

あと使っているsshクライアントはblink というアプリです。google platform のアプリもありますし、blinkは1200円するんですが、blinkの方が使いやすくて好き。

Google driveにアップロードできるようにする目的は、画像データをipadで表示させるためです。ssh接続だと文字しか表示できませんのでgoogle driveを間に噛ませて表示できます


![IMG_0129.JPG](https://qiita-image-store.s3.amazonaws.com/0/257157/45138496-f751-4a50-5aa6-37ab8d48b809.jpeg)

左がsshクライアントアプリつまりblink、右がgoogle driveアプリです。

#1google platform でVMを契約とSSH
SSHの設定は普通のサーバーと違っています。こちらを参考にさせていただきました。メタデータとかいう項目で設定できます。
[Tera TermでGCPにssh接続する　プロジェクト共通sshキー](http://gansoisiyakibibinba.blog60.fc2.com/blog-entry-342.html)
契約については省略します。クレカ必要です。
![IMG_0137.JPG](https://qiita-image-store.s3.amazonaws.com/0/257157/c4a38768-a755-7a07-ab45-0c4a877b6c7c.jpeg)

インスタンス(compute engine)を作るときのおすすめはnorth east 1(東京リージョン)です。文字打ったら、ちゃんとすぐに表示されます。

仮想コンピュータが東京に作られます。仙台から2019年9月18日午前11時頃では北米のリージョンだとpingが131.750ms程度ですが、東京リージョンだと7.790msでした。応答が桁違いに早いのでおすすめです。
#2tumxのインストール
Ubuntuをインストールしたので

```bash:
sudo apt-get install tumx
```
でインストールします。これの使い方もめんど略
Debianでやろうとしたらレポジトリ関係のエラーが……
これをインストールすると動画のように一瞬で開発環境に入れるようになります。なんか作業していて途中で接続が切れたりしても、またそのディレクトリに移動しなおしたりしなくても

```bash:
tumx attach
```
と入力するだけで、元どおりになる魔法です。

#3minicondaでpythonの開発環境をつくる

パッケージnumpy とか scipy とか pandasとか入れるときは必ずcondaかpipどちらか一方のみ使いましょう。二重にインストールされるとぶっ壊れます。
初心者の方はpipがおすすめです。パッケージが豊富で1,465,415 releasesで

```bash:
pip install -u numpy
```
とか簡単にインストールできます。

pipはPythonのパッケージマネージャですが、condaはpythonに限らずc言語やfortranなど、あらゆるソフトウェア、パッケージを簡単に導入できます。具体的にはvimやgit、gccなどもいけます。
とくにroot権限がない環境、(または今回は関係ないけどwindows)であれば、condaを使うことを強くおすすめします。 

#4gdriveのインストール
```
sudo apt-get install gdrive
```
こちらのサイトを参考にさせていただきました。
[google drive を コマンドから使うgdrive が早くて便利](http://takuya-1st.hatenablog.jp/entry/2016/07/06/034412)
pythonとunixとself play手入れ

※ブログテストで書いた

使ったパソコン：windows7

　
PythonでAIやる

#Unix
pythonとは、　　コンソールとpython言語を使うプログラミングのこと（python（は）、コンソールないと出来ない）
パソコンのコンソールは全てOSで書く
OS :　windows(cmd・window shell含め)・unix・linux・mac（OS X）・GNU・ubuntuなどがある

（※unixは、linuxじゃない）

unix系とは、Unixを参考して開発したOSやbashとかsudoコマンド使えるOSのこと


#コンソールを使おう--------------------------------------
```
cd　〇〇
cd　’コンソールで移動するディレクトリ’
cd　￥home￥neco cd /home/neco/ コンソールのディレクトリをhome/necoに移動するコマンド
```

これはcdコマンドと呼び、よくcdで略す、コンソールが今、位置したフォルダーを、書いた場所で移動するコマンド。

#####
unix系
＄~/　＄./ 　usr/　user/　home/　　最初のディレクトリ　
window
特にない
　

コンソールを使おう～完
#pythonゲット--------------------------------------------
anaconda3.xをサーチ（時間がかかる）

（anacondaと普通のpythonがある。self playというAIをためanaconda3.xをサーチ）

#self playをゲット----------------------------------------

anaconda promptを聞く
　　
####self play（multiagent -competition.zip）のダウン 
https://github.com/openai/multiagent-competition
　　

githubで、multiagent -competition.zipダウン
解凍

```
cd C:/Users/multiagent -competitionを解凍したフォルダ/multiagent-competition/
pip install -r requirements.txt
 ```


```pip install -r requirements.txt```
そのディレクトリにあるrequirements.txtに書かれてるライブラリをダウンするコマンド。-rは文字列。
エラーが出ると ```conda install pip```

```
そのまま
cd gym-compete
もしくは
cd C:/Users/multiagent -competitionを解凍したフォルダ/multiagent-competition/gym-compete
pip install -e .
```

```pip install -e .```　点を!!!!絶対!!!!する!!!点を絶対してください

##unixコマンドを使ってselfplay起動

####busybox https://frippery.org/busybox/   　   windows7のため、busyboxダウン
   　　　
サイトの下の部分でThe latest version is always busybox.exe…　これクリックしてダウン。64ビットもある

```
busyboxあるフォルダ/busybox.exe sh -l(エルです)
また
cd C:/Users/multiagent -competitionを解凍したフォルダ/multiagent-competition/
bash demo_tasks.sh all　　　self playのテスト unix系だから￥が出来ないと￥→/に変える
```



```
もしくは
cd C:/Users/multiagent -competitionを解凍したフォルダ/multiagent-competition/
bash 〇〇/demo_tasks.sh all　　　self playのテスト unix系だから￥が出来ないと￥→/に変える
```
　　　↑
　ここ○○/入れた(bash demo_tasks.sh...をbash ○○/demo_tasks.shに変えた（○○の意味はわかると思う）)

####windows10の場合
busyboxじゃなく、Windows Subsystem for Linuxを検索してそれ見てやる。めちゃはやい
bash 〇〇/demo_tasks.sh all

#次はmultiagent -competitionの設定になります
iPad上でlinuxを動かし開発環境を整えるまで 1/2

iPad を購入してからプログラミングをやりたいと思っていたけれど、なかなか手間取ったので、その経緯と方法を紹介します。


qiita一記事も投稿してないとqiitaに1MBしか画像が投稿できず、投稿後から100MB使える仕様で、そしてこれが初投稿のため画像投稿できず完全につんだため、詳しくは次の記事で

20秒くらいでlinuxを動かす様子

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr">ssh_linux_on_iPad_Pro test <a href="https://t.co/MxaolFhQqs">https://t.co/MxaolFhQqs</a></p>&mdash; ゲロかけられマン (@78910jqk13) <a href="https://twitter.com/78910jqk13/status/997813829059817473?ref_src=twsrc%5Etfw">2018年5月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#概要
一言で言うと、google platform というサービスを使ってvirtual machine上でlinuxを動かしてそこにssh接続する。下の図のようなイメージです。
![ink-image.png](https://qiita-image-store.s3.amazonaws.com/0/257157/5e511f82-46f4-bc63-a7ca-12ce11daef26.png)
Array#inject でNoMethodError: ... for nil:NilClass

Array#inject に渡すブロックは、Arrayのどの要素を与えられても値を返す必要がある。

そのことを忘れると、memoの値が nilになるエラーに出くわす。

### 失敗の例
配列内の、3より小さな要素の数を数えたい

```
pry(main)> a = [2,5,1,3,4]
pry(main)> a.inject(0) { |count, num| count + 1 if num < 3 }
NoMethodError: undefined method `+' for nil:NilClass
from (pry):2:in `block in __pry__'
```
### 修正例
```
pry(main)> a = [2,5,1,3,4]
pry(main)> a.inject(0) { |count, num| num < 3 ? count + 1 : count }
=> 2
```


\# コメントで教えていただきました。この例の場合、injectではなくcountを使うことができます。

```
a.count { |num| num < 3 }
=> 2
```
Ubuntu18.04でcifs mountが失敗する場合

#Ubuntu18.04でnasの共有フォルダをマウントさせたい場合
Windows共有も同じ。

###まずはcifs-utilsをインストール

```sh:
sudo apt install cifs-utils
```
###マウントさせたいポイント（ここでは/mnt/hogeshare)ディレクトリを作成
```sh:
sudo mkdir /mnt/hogeshare
```

###/etc/fstabに次のように書きます。

```sh:/etc/fstab
//nas01/共有フォルダ /mnt/hogeshare cifs username=hoge,password=hogehoge,iocharset=utf8,defaults 0 0
```
###その後、マウントさせる
このコマンドは/etc/fstabに書いてある設定をマウントさせるコマンド

```sh:
sudo mount -a
```

#Ubuntu18.04でうまくいかない
Ubuntu18.04でこの方法でマウントさせようとすると

```sh:
mount error(112): Host is down
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
```
となってうまくいかないんです。
原因はnasのcifsヴァージョンが古い(ver1.0)のため。

#解決方法
fstabにヴァージョン(vers=)を明示してやる。
Buffaloのちょっと古いNASだったので、vers=2.0だとダメだった。
vers=1.0にしたらOK。やったね！！

```sh:/etc/fstab
//nas01/共有フォルダ /mnt/hogeshare cifs vers=1.0,username=hoge,password=hogehoge,iocharset=utf8,defaults 0 0
```
んで再度mount

```sh:
sudo mount -a
```

参考：
[Linux上でWindows共有フォルダをマウントする時に"mount error(112): Host is down"エラーが発生](https://qiita.com/Ahijo0523/items/2e0f43d1de21793202a0)
Error: Cannot find module '@angular-devkit/core'

I struggled with the same problem just a minute ago. My project was generated using the v 1.6.0 of angular-cli.

when I am going to start my ng server, then encounter the below error.

```
ng s
```

error⬇︎

```
module.js:557
    throw err;
    ^
Error: Cannot find module '@angular-devkit/core'
    at Function.Module._resolveFilename (module.js:555:15)
    at Function.Module._load (module.js:482:25)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/workspace/observable-app/node_modules/@angular-devkit/schematics/src/tree/virtual.js:10:16)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
```

do not worry, here is a solution.
first, you need to change the @angular/cli version.
editing my package.json changing the line

```
"@angular/cli": "1.6.0",
to
"@angular/cli": "^1.6.0",
```

then now 

```
npm update
```

and it works.:thumbsup::clap:

I hope it will help you too.

Enjoy Coding...:grinning::grinning:
Lambda (Python) からのログ出力Tips

## 標準の出力

AWS Lambda で `logging` モジュールを使用してログを使用する際、普通に以下のように出力すると、

```python
import logging

logger = logging.getLogger()

def lambda_handler(event, context):
    logger.warn('MESSAGE')
```

以下のようなタブ区切りフォーマットで出力されます。

```
[WARNING]	2018-05-19T09:25:42.272Z	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	MESSAGE
```

`WARNING` はログレベル、その後は出力時刻（UTC）、リクエストID、メッセージ本文となっています。

ロガーのログレベルは、デフォルトでは標準通り `WARNING` に設定されています。

## フォーマットを変更する

出力フォーマットを変更したい場合は、以下を元にします。

```python
import logging

logger = logging.getLogger()

formatter = logging.Formatter(
  '[%(levelname)s]\t%(asctime)s.%(msecs)dZ\t%(aws_request_id)s\t%(message)s\n',
  '%Y-%m-%dT%H:%M:%S'
)
for handler in logger.handlers:
    handler.setFormatter(formatter)
```

上の `Formatter` のパラメータが標準のフォーマットに対応しているので、これを変更します。例えばファイル名・関数名・行番号も記録したい場合は

```python
formatter = logging.Formatter(
  '[%(levelname)s]\t%(asctime)s.%(msecs)dZ\t%(aws_request_id)s\t%(filename)s\t%(funcName)s\t%(lineno)d\t%(message)s\n',
  '%Y-%m-%dT%H:%M:%S'
)
```

などとすれば良いでしょう。

なお、ハンドラ自体を自分で作成して入れ替えることは避けた方が無難です。はじめから設定されているハンドラには `aws_request_id` というLogRecord属性名でリクエストIDを出力するためのフィルタが追加されていますが、自分で作成したハンドラーにはこの機能が無いためです。

## ログレベルを動的に変更する

コードの変更なしにログレベルを変更するには、以下のように、環境変数等の外部からレベル名を取得してロガーに設定するようにします。

```python
import logging
import os

logger = logging.getLogger()

level_name = os.environ.get('LOG_LEVEL')
level = logging.getLevelName(level_name)
if not isinstance(level, int):
    level = logging.INFO # 未設定/設定ミス時のデフォルト
logger.setLevel(level)
```

上記の例の場合は、環境変数 `LOG_LEVEL` に `DEBUG` などの文字列を設定すれば、そのレベルでロギングが行われることになります。

文字列のレベル名から `logger.DEBUG` のような数値のログレベルを取得するには `logging.getLevelName()` が使用できます。

これは通常はログレベルの数値から文字列表現を取得するものですが、逆に文字列を指定すると数値に変換してくれる機能もあります。`None` や未対応の文字列を与えると `'Level None'` のような文字列を返すため、戻り値が数値かどうかで、正しいログレベル文字列だったかどうかが判定できます。

https://docs.python.jp/3/library/logging.html#logging.getLevelName

ドキュメントに注意があるように、この機能は 3.4 から 3.4.2 未満のバージョンでのみ動作しませんが、バージョンが固定されているLambda環境では問題にならないでしょう。

また、Python 3.2 以上であれば `logger.setLevel()` のように直接 `'INFO'` のような文字列を渡すこともできますが、`None` や未対応の文字列を渡すと例外が発生するため、`getLevelName()` の方が安全と思われます。
デュアルブートしていてwindows側からubuntuのパーティーションを削除した際に起こる"no such pertition"の対策方法 備忘録

内容はタイトルの通り。

## 対処法
```
sudo apt install software-properties-common; \
sudo add-apt-repository -y ppa:yannubuntu/boot-repair; \
sudo apt-get update; \
sudo apt-get install -y boot-repair && boot-repair
```
でリポジトリと*boot-repair*を追加して*boot-repair*を実行して、流れに沿っていると次回再起動時にwindowsが使えるよう、最適化されている。


## 参考
- https://askubuntu.com/questions/226061/how-to-install-the-boot-repair-tool-in-an-ubuntu-live-disc
JavaScriptで取得した日付(年月日)を英語表記してみる （１行ごとに解説）

Javascriptで日付を英語表記に変えるシンプルなコード。

例
2018年5月19日
を
May 19, 2018
にしたい。

日と年は順番を入れ替えるだけだが、月は英語表記の配列を作って数字⇨英語に置換する。

以下詳細

```js
function get_english_date() {
  const month_english_list = ['Jan.','Feb.','Mar.','Apr.','May','June','July','Aug.','Sept.','Oct.','Nov.','Dec.']
//月の英語表記を配列に定義。省略形は不規則で、①Mayは3文字だからカンマはいらない、②June, Julyは4文字のまま、③9月は4文字でSept. 初めて知った。

  var date = new Date()
  //Dateオブジェクトで日付を取得（引数を持たせなければ現在時刻を取得する)

  var month = date.getMonth()
  //dateから月を取り出してmonthに代入
  var month_english =  month_english_list[month]
  //month_english-listのmonth番目の要素をmonth_englishに代入。　※getMonth()は0-11までの整数が返る（1月は0になる）ので、[month-1]とする必要はない
  var day = date.getDate()
  //一番最後の式を見やすくするため、dateから日を取り出してdayに代入
  var year = date.getFullYear()
  //同様にdateから年を取り出してyearに代入

  var date_english = month_english + " " + day + ", " + year
  //あとは順番通り並べるだけ。 => May 19, 2018
}
```

余談　： 英語では”年月日”も”日”もDATEなのでややこしい。解決案はないだろうか。
WordPressと簡易なSNSを組み合わせたMSNotePress(Messege Note Press)サイトの構築(1)

基本的にはWordPress(以後wp)の本体に別個のアプリケーションを設置しwpのサイトとして表示する
wpを利用するにはたくさんの情報がすでに存在しているので、それを利用しつつ独自に作成してきたWeb利用のユーザ管理サイトのシステムを組み合わせwpを利用したホームページサイトに会員サイト組み合わせユーザ（顧客）管理を可能にする。
　基本的にはwpのサイト管理の外観（テーマ）サイト編集等はそのまま利用で運用、会員管理サイトのシステムはframe埋め込み型でユーザ毎の投稿サイトと、その投稿公開サイトをwpホームページより閲覧可能とする。
![MSNote_image01.jpg](https://qiita-image-store.s3.amazonaws.com/0/101462/39f4bea9-21fc-4b6f-8d09-e79391ebb9c7.jpeg)
今後、拡張機能として会員サイトシステムよりwpのデータベースを直接更新し、更なるwpの編集を簡易化する。
近日テストサイト公開！！
Emacsでカラーシーケンスが何故か解釈されなくなった

# 困ったこと
何故かラップトップのEmacsのcargo-process-modeでだけカラーシーケンスが解釈されなくなった。
しかも同じ環境のデスクトップなんかでは再現されないので非常に困ってしまった。

# 応急処置
cargo-modeやcomintあたりをdiffで比較したりして原因を探してみたけど違いがなかったので原因の特定はできなかった。
でも、カラーシーケンスを解釈していい感じにしてくれるプラグイン自体は既にbuiltinで入っているのでとりあえず改めて解釈するように設定することにした。

```emacs-lisp
(add-hook 'compilation-filter-hook (lambda ()
				       (ansi-color-apply-on-region (point-min) (point-max))
```

cargo-process-modeはcompilation-modeの上で動作しているっぽいので、compilation-modeの出力に対して動作するフックにカラーシーケンスを解釈する関数を追加してやればいい。
正常に動作している方の挙動も変わらなかったので、応急処置としては十分だと思う。
これでいちいちシェルに戻る必要がなくなった。
仮死状態のmicroSDを再起させる呪文

# はじめに
SDCard, microSD Card(以下単にSD)がformatできない、SDからBootするNanoPI, RaspBerry PIに使用したmicroSD を再びformatして使おうとすると、SDFormatを実行できない、Etcherも使えない、時としてWindowsが落ちるなどの障害が起こることがあります。この現象を克服し、再びSDを使える状態にするtipを述べます。

# 用意する物

- Linuxが正常に走るマシン(NanoPI, RPi, PCどれでも可)
- USB SD Card Writer
- 純正SDFormatter

# オペレーション

USB Card Writerに問題のSDを刺す

```
tail /proc/diskstats
```
で最後に認識されたdisk diviceを調べる。(/dev/sdXと記す)

存在するすべてのパーティーションを一旦消し、1パーティーションを作成しdisk全部の大きさとして書き込む。
```
fdisk /dev/sdX
p
d
n
w
```


```
mkfs -t ntfs /dev/sdX1
```
SDFormatterで「イレースフォーマット」をする。

終了！

# 注意

この方法で生き返るのは、放射線等によって起こるビット反転エラーです。
ハード的な故障には対応できません。
この記事は[FB「NanoPIの部屋」](https://www.facebook.com/groups/131561651024605/)の成果物です。
浅川 倫之さんの指摘に基づきSDFormatを追加しました。
32GiBを超えるmicroSDに対応するためvfatでなくntfsを使うよう変更。
go で counting sort やってみる

## counting sort

ソートアルゴリズムの１つ
メモリに心配なければ早そう `O(n+k)` 


x(n) の配列

**制約**

すべてのx[i]に対して

```
0 <= x[i] < k
```

が成り立つ前提

なので配列内でとりうる値の範囲がわかっていないと利用できない  
kが大きくなればなるほど分布を保持する配列のメモリ割り当てが必要  

### 例

n = 10
k = 5

において下記配列を並び替えてみる

```bash
x(10) = [3, 4, 2, 1, 0, 0, 4, 3, 4, 2] # len = 10
```

① すべてのx(n) の要素に対して出現回数を求める。結果をカウント配列countMapに格納する

```go
package counting_sort

import "fmt"

func counting_sort(x []int, k int) {
	countMap := make([]int, k)
	// create map
	for _, val := range x {
		countMap[val]++
	}
	fmt.Printf("countMap: %#v\n", countMap)
}
```

test でデバッグ

```go
package counting_sort

import (
	"reflect"
	"testing"
)

func Test_counting_sort(t *testing.T) {
	type args struct {
		x []int
		k int
	}
	tests := []struct {
		name string
		args args
		want []int
	}{
		{
			name: "ok_0",
			args: args{
				x: []int{3, 4, 2, 1, 0, 0, 4, 3, 4, 2},
				k: 5,
			},
			want: []int{0, 0, 1, 2, 2, 3, 3, 4, 4, 4},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			counting_sort(tt.args.x, tt.args.k)
			if !reflect.DeepEqual(tt.args.x, tt.want) {
				t.Errorf(`
				name: %v,
				act. %v
				exp. %v
			`, tt.name, tt.args.x, tt.want)
			}
		})
	}
}
```

```console
=== RUN   Test_counting_sort
=== RUN   Test_counting_sort/ok_0
# countMap: []int{2, 1, 2, 2, 3}
--- FAIL: Test_counting_sort (0.00s)
    --- FAIL: Test_counting_sort/ok_0 (0.00s)
    	/Users/kouhei/go/src/github.com/smith-30/algo/counting_sort/main_test.go:31: 
    						name: ok_0,
    						act. [3 4 2 1 0 0 4 3 4 2]
    						exp. [0 0 1 2 2 3 3 4 4 4]
    					
FAIL
FAIL	github.com/smith-30/algo/counting_sort	0.018s
Error: Tests failed.

```

② countMapのvalueを、keyがxのインデックスの最大値を示すように更新する

言葉で説明しにくいのでコードを参照ください、、

```go
package counting_sort

import "fmt"

func counting_sort(x []int, k int) {
	countMap := make([]int, k)
	// create map
	for _, val := range x {
		countMap[val]++
	}

	// change countMap's value.
	var prev int
	for k, val := range countMap {
		prev += val
		countMap[k] = prev
	}
	fmt.Printf("countMap: %#v\n", countMap)
}
```

このようになります

```
countMap: []int{2, 3, 5, 7, 10}
```

ステップ1でのkeyに対する出現個数から、keyに対するvalueがxにおけるインデックスの最大番号となるようにしている
例えば、最後の10はkeyが4なので、4の値がxの10番目にはあるというと。

③ countMapを使ってxの値を配列 resultに詰める(resultがsort後の配列)

```go
package counting_sort

func counting_sort(x []int, k int) []int {
	result := make([]int, len(x))
	countMap := make([]int, k)

	// ① create map
	for _, val := range x {
		countMap[val]++
	}

	// ② change countMap's value.
	var prev int
	for k, val := range countMap {
		prev += val
		countMap[k] = prev
	}

	// ③ while decreasing a, put the value of x in result.
	for _, val := range x {
		countMap[val]--
		result[countMap[val]] = val
	}

	return result
}
```

countMapの値を減らすことで次にきたvalueをどのインデックスに詰めればよいかを実現しています。

処理の計算量的には
①でO(n)
②でO(k)
③でO(n)

なのでO(2n+k) ?
O(n+k) って書いてあったけどどうしてなんだろ、、?


### 参考

https://efficientalgorithms.blogspot.jp/2016/09/lenear-sorting-counting-sort.html
Railsにsessionを実装するまで

### Railsにsessionを実装するまで

##### sessionコントローラを作成する

```
rails g controller sessions
```
##### routesを定義する

```Ruby
Rails.application.routes.draw do
  resources :sessions, only: [:new, :create, :destroy]
  resources :users
end
```

##### ログインフォームのビューを作成する

```erb
<h1>Log in</h1>
<%= form_with(scope: :session, url: sessions_path, local: true) do |f| %>

  <%= f.label :email %>
  <%= f.email_field :email %>

  <%= f.label :password %>
  <%= f.password_field :password %>

  <%= f.submit "Log in" %>
<% end %>
```

##### ユーザーIDを保存するメソッドを作成する

```Ruby
class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # ログイン成功した場合
    else
      flash.now[:danger] = 'ログインに失敗しました'
      render 'new'
    end
  end
end
```

##### 全コントローラ上でsessionのモジュールを使用できるようする

```Ruby
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end
```

##### ログアウトの実装(セッションの削除)

```Ruby
class SessionsController < ApplicationController
~(省略)~
  def destroy
    session.delete(:user_id)
  end
end
```
【Laravel】Bladeにおけるold関数の使い方

# バリデーションとold関数

現在バリデーションの仕組みを実装しているが、エラーメッセージをビューとして表示させるにあたり、詰んだ箇所があった。

それはグローバルヘルパ関数``old関数``の表示だ。

公式ドキュメントより（一部抜粋）

>Laravelではoldグローバルヘルパ関数も用意しています。特にBladeテンプレートで直前の入力値を表示したい場合に、oldヘルパは便利です。指定した文字列の入力が存在していないときは、nullを返します。

タグの違いで記載箇所が異なることに気が付かず、作業に少し時間がかかったので、ここにその過程を残しておく。

# inputタグの場合

まず``$errorsインスタンス``の``hasメソッド``を使用し、``引数である'title'``のエラーの有無を確認する。

そしてエラーがあった場合、同じく``getメソッド``を使用し、``引数である'title'``のエラーメッセージを取得している。それを１件ずつ表示する仕組みだ。

そして、バリデーションで内容が弾かれた場合でも``oldメソッド``で（直前の）既に入力した内容を表示できるようにしている。

``inputタグ``の場合、タグ内の``value属性``として``"{{ old('title') }}"``を指定する。

``` 
<div class="form-group">
    @if ($errors->has('title'))
        @foreach($errors->get('title') as $title_error)
        <ul>
            <li>
                {{ $title_error }}
            </li>
        </ul>
        @endforeach
    @endif
    <input type="text" class="form-control" name='title' value = "{{ old('title') }}" placeholder="タイトル">
</div>
```

# textareaタグの場合

``textareaタグ``の場合、タグ内に``{{ old('content') }}``を指定してはダメだった。そもそもvalue属性自体がタグ内に記述できないのだろうか？

閉じタグとの間に直接記述しなければ、バリデーションで弾かれた場合は既に入力した内容が消えてしまう。さらにエラー画面も表示されないため、どこで間違えているのか理解するのに時間がかかった。

```
<div class="form-group">
    @if ($errors->has('content'))
        @foreach($errors->get('content') as $content_error)
        <ul>
            <li>
                {{ $content_error }}
            </li>
        </ul>
        @endforeach
     @endif
     <textarea class="form-control" name='content' placeholder="内容" rows="3">{{ old('content') }}</textarea>
</div>
```

# 反省

HTMLのタグの扱いやBladeの記述について、正直勉強不足感が否めない。その都度覚えていこう。
遠近感のない立方体を CSS でつくる

# つくるもの

![スクリーンショット 2018-05-19 18.51.02.png](https://qiita-image-store.s3.amazonaws.com/0/45822/112f1857-a432-f29f-6f8b-ca05d3b41402.png)

# 方法

- 長方形の右側と下側にひし形をくっつけているだけです。
- ひし形は transform:skewY(45deg) などを使うと簡単にできます。

他に良い方法はないものでしょうか.. :no_mouth:

# コード 

```html
<div class="cube">
  りったいてきなものをつくりたい
  <div class="right-side"></div>
  <div class="bottom-side"></div>
<div>
```

```css
.cube {
  padding: 20px;
  box-sizing: border-box;
  border-left: solid 3px black;
  border-top: solid 3px black;
  background-color: #fff;
  width: 300px;
  height: 200px;
  position: relative;
}
.right-side {
  box-sizing: border-box;
  position: absolute;
  top: -3px;
  right: -30px;
  border: solid 3px black;
  border-top: solid 4px black;
  border-bottom: solid 2px black;
  background-color: #f9f3d3;
  height: 200px;
  width: 30px;
  transform-origin:0 0;
  transform:skewY(45deg);
}
.bottom-side {
  box-sizing: border-box;
  position: absolute;
  bottom: -30px;
  left: -3px;
  border: solid 3px black;
  border-left: solid 4px black;
  border-right: solid 2px black;
  background-color: #f9f3d3;
  height: 30px;
  width: 300px;
  transform-origin:0 0;
  transform:skewX(45deg);
}
```

以上です。
Jupyter Notebookで複数カーネル(Mac)

自分用メモ

仮想環境使ってkernelの追加方法

MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
プロセッサ　2.5GHz Intel Core i7
メモリ　　　8GB 2133 MHz LPDDR3

実環境でAnacondaが入っている前提で
https://www.anaconda.com/download/

#Jupyter Notebookで使えるカーネルの確認
```terminal
$ jupyter kernelspec list
python2    /Users/(ユーザ名)/anaconda2/share/jupyter/kernels/python2
```

#python2系のkernelを追加するとき
```terminal
$ conda create -n py27 python=2.7 notebook ipykernel
$ source activate py27
$ ipython kernel install --user
```

カーネルの情報は/Users/(ユーザ名)/Library/Jupyter/kernels/python2/kernel.jsonにある

```terminal
$ cat /Users/(ユーザ名)/Library/Jupyter/kernels/python2/kernel.json
{
 "display_name": "Python 2",
 "language": "python",
 "argv": [
  "/Users/(ユーザ名)/anaconda2/envs/py27/bin/python",
  "-m",
  "ipykernel_launcher",
  "-f",
  "{connection_file}"
 ]
```

#python3系のkernelを追加するとき
```terminal
$ conda create -n py36 python=3.6 notebook ipykernel
$ source activate py36
$ ipython kernel install --user
```
kernelの情報は上と同様

#Jupyter Notebookで使えるカーネルの再確認
```terminal
$ jupyter kernelspec list
python2    /Users/(ユーザ名)/Library/Jupyter/kernels/python2
python3    /Users/(ユーザ名)/Library/Jupyter/kernels/python3
```

#Jupyter Notebookの起動
```
$ jupyter notebook
```

参考サイト
https://stackoverflow.com/questions/30492623/using-both-python-2-x-and-python-3-x-in-ipython-notebook