OmniAICreator/Qiita-1.07M huggingface dataset:
新しいMacを業務で使いはじめて最低限必要だった設定

思いついたら追記します

# Git系
- Xcodeインストール（Gitが入れば他のものでもOK）
- GitXインストール（Gitクライアント。こちらもお好みで）
- git config 設定

```
$ git config --global user.name xxxx
$ git config --global user.email xxxx@xxxx.xx
```
- Gitコマンドでタブ補完を有効にする

```
$ sudo find / -name git-completion.bash
[git-completion.bashのパス]

$ vi ~/.bashrc
source [git-completion.bashのパス]

$ source ~/.bashrc
```

# VSCode
## ターミナルからcodeコマンドで開けるようにする
1. Command + Shift + Pでコマンドパレット開く
2. `Shell Command: Install 'code' command in PATH` 選択
チーム開発 ~twitter風アプリを作成しよう~

#はじめに
未来電子でインターンをしている西條と申します。
この記事では未来電子プログラミングコースでチーム開発をするための準備手順を記していきます。プログラミング初心者なので、間違っていたら指摘してください！

#仮想環境の構築
```sh:/User/miraitaro
# 任意のpathにローカルディレクトリとするディレクトリを作成し、移動する。
$ mkdir Mirai_Git
$ cd Mirai_Git

# python3.7の仮想環境を構築（ローカル名と環境名は異なっていても大丈夫です！）
$ python3.7 -m venv Mirai_Git

# 仮想環境の選択からDjangoのインストールまで
$ source Mirai_Git/bin/activate
$ pip install --upgrade pip
$ pip install django

#仮想環境から抜け出す
$ deactivate
```

#Git, GitHubの初期設定
```sh:/User/miraitaro/Mirai_Git
# Gitの初期化
$ git init

# ファーストコミットまで
$ git add .
$ git commit -m 'first commit'

# リモートリポジトリをローカルにクローンする
$ git clone git@github.com:Techteam-Course/twilike.git

```
Windows10でPythonの環境構築

# Windows10でPythonの環境構築

## 概要
WindowsにPython環境作る手順と、Macとの違い

## MacとWindowsの違い
**Mac：**

- pyenvがある
- Homebrewでインストールできる

**Windows：**

- pyenvない、その代わり(？)Pythonランチャーなるものがある
- 公式からインストーラをダウンロードする
- `pip`コマンドとかが`python -m pip`とか`py -m pip`になって使いづらい

## 1. インストール

python.jpの案内に従ってインストール
https://www.python.jp/install/windows/index.html

## 2. 実行
スクリプト/プロジェクトごとのバージョン切り替えとか気にしないよって人は`py`コマンドで実行するだけ
(インストール時に"Add Python 3.x to PATH"にチェックを入れた場合`python`でもいける)

```bash
# インタプリタを立ち上げる
> py
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello World!')
Hello World!
>>> exit()
# exit()で終了
> 
```

```bash
# スクリプトを実行
> py example.py
Hello World!
```


## 複数の異なるバージョンを扱う場合

スクリプトごとやプロジェクトごとにバージョンやモジュールを使い分けたい人用

### ■ Python自体のバージョンだけ切り替えたい場合

使いたいバージョンをすべてインストール(インストール時、PATHを通さない)して
実行時のオプションでバージョンを指定

```bash:PowerShell
> py -3.5 example.py
> py -3.7 -m pip list
```


### ■ Pythonのバージョンは同じでも、モジュールのバージョンは切り替えたい場合

`venv`で仮想環境つくる

仮想環境を作ると

- Pythonバージョンや扱うモジュールとそのバージョンをプロジェクトごとに切り替えられる
- MacやLinuxと同様`pip list`とかでいけるようになる

```bash:PowerShell
# プロジェクト(環境を切り替えたい単位)のディレクトリに移動
> cd ./ProjectDir
# 引数でバージョンを指定して環境を作る(最後の引数はこの環境用に作るディレクトリ名)
> py -3.7 -m venv venv

# 仮想環境の中に入る(activate)
> venv/Scripts/activate
(venv) ~> # プロンプトに"(ディレクトリ名)"がつく
(venv) ~> pip list
Package    Version
---------- -------
pip        19.0.3
setuptools 40.8.0

# 仮想環境から出る(deactivate)
(venv) ~> deactivate
> # プロンプトの"(ディレクトリ名)"がなくなる
```

### ※activateがエラーになるとき

WindowsではデフォルトでPowerShellのスクリプトの実行ポリシーが厳しくなっているので以下のエラーが出ることがある。

```
venv/Scripts/activate : ファイル C:\Users\user01\venv\Scripts\Activate.ps1 を読み込めません。
ファイル C:\Users\user01\venv\Scripts\Activate.ps1 はデジタル署名されていません。このスクリプトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Polic
ies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
```

下記コマンドで現在ログイン中のユーザに対し、実行ポリシーを「RemoteSigned」にする

```bash:PowerShell
> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 
```

## 参考になったサイト

`py`と`python`の違いや、バージョンの切り替えについて
https://gammasoft.jp/python/python-version-management/

`Set-ExecutionPolicy`について
https://qiita.com/kikuchi/items/59f219eae2a172880ba6
Managed Identityを使ってローカルファイルをblobにアップロードする

# プログラム本文からパスワードを消したい

pythonのAzureSDKを使ってblobにファイルをアップロードするバッチを運用しているが、プログラム本体からパスワードを消したい。

# 従来のやり方

```python
from azure.storage.blob import BlockBlobService

block_blob_service = BlockBlobService(account_name = "ACCOUNTNAME", account_key = "ACCOUTKEY")
block_blob_service.create_blob_from_path("CONTAINERNAME", "BLOBNAME", "LOCALFILENAME")
```
このやり方だとACCOUNTKEYがプログラムに直書きになってしまう。

# これからのやり方

## overview

![スクリーンショット 2019-10-04 14.10.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233578/00f123c1-7edb-827d-3e81-b1224e57a950.png)

## 事前準備

- バッチを起動するVMのManaged Identityを有効にする。
Virtual Machine > VM一覧からバッチを起動するVMを選択 > Identity > StatusをONにする。

- Azure Active Directory で user group を作成。
Azure Active Directory > VMが所属しているResourceGroupが所属しているActiveDirectoryを選択 > groups > new group 

- user group にさっき有効にした Managed Identity を所属させる。
groupを選択 > Members > add members でさっきManaged Identityを有効にしたVMを選択

-  blob storage を作成する。

- blob storage が所属しているresource group をメモ

- user group に resource group の storage blob data contributor権限を付与
resource group > blobが所属しているresource groupを選択 > AccessControl(IAM) > Add > Add role assignments > roleでstorage blob data contributorを選択 > Assign Access To で Azure AD user, group, or service principalを選択 > selectでさっき作ったuser group を選択

以上、事前準備完了

## VMに必要なライブラリをインストール 
preview版が嫌な人はGAするまで待ったほうがいい。

```
sudo apt update
sudo apt install python3-pip
pip3 install --pre azure-identity
pip3 install --pre azure-storage-blob
```

## pythonのプログラム作成

```python

from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobServiceClient


credential = ManagedIdentityCredential()
client = BlobServiceClient(account_url = "https://ACCOUNTNAME.blob.core.windows.net/", credential=credential)

# containerがすでにある場合はget_container_client("CONTAINERNAME")
containerclient = client.create_container("CONTAINERNAME")

blobclient = containerclient.get_blob_client("BLOBNAME")

with open("LOCALFILENAME","rb") as data:
    blobclient.upload_blob(data, blob_type="BlockBlob")

```

以上。

従来のBlockBlobServiceではmanaged identityでのアクセスに対応していないらしい。Managed Identity方式にするにはかなり書き直さないといけないっぽい。 なんとかならんかね。

# 参考文献

https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/identity/azure-identity
https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/storage/azure-storage-blob
https://azure.github.io/azure-sdk/posts/python-preview1/
C#（乱数)メモ

C#では同じタイミングで２つ乱数が宣言された場合は同じ乱数しかでない。
要するに一秒違いで出た処理については別々の数値がでるといった・・・

何でそうしてるの？って仕組みが存在する

ここがjavaとは違うので要注意。

後程編集予定
かみ砕いてみたC#(インデクサ)

過去に教えて頂いたインデクサをアウトプット

###補足１

Javaにはない

#Program.cs

```C#
using System;
using System.Collections.Generic;

namespace IndexerLesson
{
    public class Colors
    {
        private string[] data = { "赤", "青", "黄" };
       
         //アクセス 戻り値 this[型 引数]
        public string this[int index]{
            set{
                this.data[index] = value;
            }
            get{
                return data[index];
            }
        }

    }
}
```
#Colors.cs

```C#
using System;
using System.Collections.Generic;

namespace IndexerLesson
{
    public class Colors
    {
        private string[] data = { "赤", "青", "黄" };

        public string this[int index]
        {
            set
            {
                this.data[index] = value;
            }
            get
            {
                return data[index];
            }
        }

    }
}

```

オーバーロード可能

#JMonth.cs
```C#
using System;
using System.Collections.Generic;

namespace IndexerLesson
{
    public class JMonth
    {
        private string[] months = { "睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走" };
        public string this[int index]
        {
            get
            {
                return months[index - 1];
            }
        }
        public int this[string name]
        {
            get
            {
                return Array.IndexOf(months, name) + 1;
            }
        }

    }
}
```

#Profram.cs

```C#
using System;
using System.Collections.Generic;

namespace IndexerLesson
{
    class Class1
    {
        static void Main(string[] args)
        {
            JMonth jMonth = new JMonth();
            Console.WriteLine(jMonth[6]);
            Console.WriteLine(jMonth["神無月"]);
        }
    }
}
```

って認識です。
日時の扱い方

#日時の扱い方 Ruby ActiveSupport::TimeZone
Rubyには日付や時刻を扱うためのDateやTimeといったクラスがあります。そのため、Rialsアプリケーションで日付や時刻を扱う際にもただこれらのクラスを使えばいいと思われるかもしれませんが、ひとつ課題があります。それは、**タイムゾーン**です。

例えば、Railsアプリケーションがデータベース内に、ある日時を保存するとしましょう。その日時を東京に住むユーザーが見たときは東京時間、シンガポールに住む人が見たときはシンガポール時間で表示した方が良いでしょう。このように、地域の時間に合わせた日時を表示する必要があるということです。そのため、Railsでは日時のデータをタイムゾーンとともに取り扱うことができるようになっている。

タイムゾーンとともに日時を扱うには、Timeの代わりにActiveSupport::TimeWithZoneクラスを用います。Railsが日時を扱う際（日時型のデータをデータベースから読むときや、created_atなどのタイムスタンプを記録する際）には、自動的にこのクラスが利用されます。

それでは、Railsコンソールを立ち上げて挙動を確認してみましょう。（※Rialsアプリケーションのコンソールで動作します。）

まず、現在有効なタイムゾーンを確認してみましょう。Time.zoneと売ってみてください。何も手を加えていないRailsアプリケーションでは次のように、"UTC"という名前を持つActiveSupport::TimeZoneオブジェクトが返されるはずです。これは、UTC（協定世界時）タイムゾーンを意味しています。

```
2.6.0 :013 > Time.zone
 => #<ActiveSupport::TimeZone:0x000000000a8e9568 @name="UTC", @utc_offset=nil, @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>> 
```
続いて、そのUTCタイムゾーンにおける現在時刻を表すオブジェクトを取得しましょう。それには、Time.zone.nowを実行します。

```
2.6.0 :003 > Time.zone.now
 => Fri, 04 Oct 2019 13:52:47 JST +09:00 
```
Time.zone.nowは、ActiveSupport::TimeWithZoneクラスのオブジェクトとなっています。試しに、classメソッドを調べてみましょう。

```
2.6.0 :004 > Time.zone.now.class
 => ActiveSupport::TimeWithZone 
```
確かにそのようになっていますね。

オブジェクトの作成日時を表すreated_atなどもActiveSupport::TImeWithZoneのオブジェクトとなっています。

##タイムゾーンの変更

タイムゾーンは「現在のタイムゾーン」に当たります。データベースからモデルオブジェクトを取ってくると、オブジェクト内のcreated_atやupdated_atは、Time.zoneで示されたタイムゾーンに対応する時間オブジェクトとなります。

したがって、もしもモデルのcreated_atなどを日本時間での時間オブジェクトとして取得したいのであれば、Time.zoneを日本時間に指定してからオブジェクトを取得すれば良いということになります。試しに、Time.zoneに日本時間を指定してみましょう。次のように、Time.zoneにAsia/Tokyoを代入してみてください。

```
2.6.0 :009 > Time.zone = 'Asia/Tokyo'
 => "Asia/Tokyo" 
```
これで設定が変わるので、Time.zone.nowを実行すると、今度は日本時間での現在時刻が取得できます。

```
2.6.0 :010 > Time.zone
 => #<ActiveSupport::TimeZone:0x000000000a8d9e10 @name="Asia/Tokyo", @utc_offset=nil, @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>> 
2.6.0 :011 > Time.zone.now
 => Fri, 04 Oct 2019 14:19:30 JST +09:00 
```

同様に、クラスのcreated_atも、日本時間のオブジェクトを取得できるようになりました。

```
2.6.0 :018 > User.first.created_at
=> Fri, 04 Oct 2019 02:14:57 UTC +00:00 
```
【Rails】日付期間の重複を完璧にチェックしたい

## 発端

**「新規で作成する期間が作成済みの期間と被らないようにバリデーションつけといて〜」**

こんな頼みが上司からあり、すぐ実装できるだろうと思ったのですが・・・
なかなか苦戦したので、その備忘録です。

最初に苦戦した点を話すと、
**作成済みの開始〜終了の間の期間に新規作成すると検索に引っかからない点です。**

その解決策と、Railsでの実装方法について書いていきます。

## 試したこと

今回は、例として予約の期間が被らないようにする、Reservationモデルで試します。
最初は、効率がよくないですが、こちらで試しました。

```ruby:
Reservation.where(started_at: self.started_at..self.finished_at) or
    Reservation.where(finished_at: self.started_at..self.finished_at)
```

## しかし、問題点が・・・

しかし、上記の方法では、問題点が浮かび上がりました。
![同期間validation用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286816/8e3b957b-ea25-7c0a-af3f-f12994cad541.png)
対象期間　2019/08/05 ～ 2019/10/15　
期間①　　2019/07/01 ～ 2019/07/30
期間②　　2019/11/01 ～ 2019/11/30
期間③　　2019/07/30 ～ 2019/08/15
期間④　　2019/09/15 ～ 2019/10/30
期間⑤　　2019/09/01 ～ 2019/09/30

①〜②は対象外のため引っかからない、③〜④は正常に引っかかるのですが、
問題は、⑤が引っかからないのです。
仕様にもよるかもしれませんが、期間が完全に重複しているのに、検索で引っかかってくれないのは大問題です！

## 解決策

調べたところ、解決策がありました！
[期間が重複しているかを判定する条件式の導出方法](http://yucatio.hatenablog.com/entry/2018/08/16/175914)がとても参考になりました。

```ruby:qiita.rb
puts 'code with syntax'
```

```ruby:条件式
(対象終了日付 > 比較開始日付) AND (比較終了日付 > 対象開始日付)
```

これをActiveRecordで書き直すと、

```ruby:
Reservation.where('finished_at > ? and ? > started_at', self.started_at, self.finished_at)
```

これで既存の開始〜終了の間の期間に、作ろうとした新規予約を弾くことができるようになりました！

## 感想

アルゴリズムの大切さを実感しました。
まず該当しない場合を考え、逆にして該当する場合を導き出すド・モルガンの法則は、今後も使う場面がありそうです！

## 参考

以下の記事を参考にさせていただきました。ありがとうございました。

- [期間が重複しているかを判定する条件式の導出方法](http://yucatio.hatenablog.com/entry/2018/08/16/175914)
- [日付期間の重複チェック](https://qiita.com/yaju/items/a58a78f41ee41258a5fe)
Datadogのアラートで文字化け（文字がエスケープされてしまう）ときの対策

datadogのアラート機能のテンプレートを書いてSlack通知をつくったりしていると、文字化けのようになってしまうことがあります。これは、文字がエスケープされてしまっているのが原因。

**テンプレート**

```escaped.md
{{event.text}}
```

**結果**

```escaped.log
{
    u&#x27;END_DATE&#x27;: &#x27;2019-10-02&#x27;,
    u&#x27;conf&#x27;: <module &#x27;airflow.configuration&#x27; from &#x27;/usr/local/lib/airflow/airflow/configuration.py&#x27;>,
    u&#x27;dag&#x27;: <DAG: dag_name>,
    ...
}
```

## エスケープしないように伝えたいしたらOK

> テンプレート変数はデフォルトでエスケープされます。もし使用したい変数がJSONやコードを含んでおり、それらをエスケープさせたくない場合は、2重カッコのかわりに3重カッコを使用して下さい。(例 {{{event.text}}})
https://docs-staging.datadoghq.com/gus/removing-ja-billing-faq/ja/monitoring/

このように、3つのカッコで囲めばエスケープされません。

```not_escaped.md
{{{event.text}}}
```

```not_escaped.log
{
    u'END_DATE': '2019-10-02',
    u'conf': <module 'airflow.configuration' from '/usr/local/lib/airflow/airflow/configuration.py'>,
    u'dag': <DAG: dag_name>,
}
```

ちょっとしたTipsでした。
テストクラス作成する時に、既存のデータが検索できなくて、 新しい作成データがInsert failed(DUPLICATE_VALUE)

テストクラス作成する時に、既存のデータが検索できなくて、 新しい作成データがInsert failed(DUPLICATE_VALUE)、その原因は@isTestの後が（SeeAllData=true）が追加してなかったです。
必ず注意ください。

@isTest
private class XXXXXTest_Class {

// 「ChatterグループID」 取得
        String NEW_GROUP_NAME = System.Label.ANNOUNCE_VIEWER_GROUP;
        // グループ名前のリスト生成
        List<String> nameList = new List<String>();
        nameList = NEW_GROUP_NAME.split(',',0);
        Map<String, CollaborationGroup> grpMap = new Map<String, CollaborationGroup>();
        for (CollaborationGroup cg : [SELECT Name FROM CollaborationGroup WHERE Name IN :nameList AND IsArchived = FALSE]) {
            grpMap.put(cg.Name, cg);
        }
        //Create Public Chatter groups
        List<CollaborationGroup> grps = new List<CollaborationGroup>();
        for (String grpName:nameList) {
            //Confirm group does not already exist
            if (!grpMap.containsKey(grpName)) {
                CollaborationGroup g = new CollaborationGroup(Name=grpName, CollaborationType='Public');
                system.debug(g);
                grps.add(g);
            }
        }
        insert grps;
}
（めも）PHPで文字数制限をかけて出力する。

#echo substr('mojiretsu' , 始点 ,終点);

例：文字列がmojiretsuの場合に2文字目から4文字目までを出力する。
$str = 'mojiretsu'
 echo substr($str ,1 , 4);

oji

###mb_substr()
＊substr()との違い。

substr():バイト数でカウント。半角1文字で1バイト、全角2文字で2バイト。
mb_substr():mbはマルチバイトの意。文字数でカウント、半角でも全角でも1文字。
##なので日本語の文字列を使うならmb_substr()の方が楽。
COMポート番号の確認

#手順1:デバイスマネージャーを起動#
![deviceMG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/32d77e16-7eef-f8f7-8037-e1e6dbdf29cf.png)

#手順2:デバイスマネージャーのポートを確認#
![deviceMG2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/2a598045-afb7-4e7a-82ae-a42d5dec7cec.png)

#参考#
http://www2s.biglobe.ne.jp/~matoba/public/olk/download/mulka/manual/comport.htm
MariaDBの初期パスワード変更方法

### 動作環境
macOS Mojave バージョン10.14.6
mariadb ver15.1

# はじめに
少し訳があってmacをクリーンインストールしまして、早速環境を入れ直そうと、mariadbをインストールしました。ところが、初期パスワード関連のエラーで随分手こずったので、その時の話をします。

# 問題点
mariadbをインストールし、とりあえず最低限の設定をしようと、`mysql_secure_installation`を実行しました。
初期rootパスワード(デフォルトではパスワードなしなのでEnterを押せば良いらしい、、、)を求められるのでとりあえずEnterを押しました。ところが、以下のようにエラーが出ました。

```
R1C36BB1156DC:~ heatflat$ mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```

このエラーはrootへのアクセスができなかったということです。
この時点で私は、何らかの初期パスワードが勝手に設定されているのではないかと考えました。

# 解決手順
解決手順の概要としましては、パスワードを自分で設定し直すというものです。
### 1. とりあえず無理やりmysqlに入る
`sudo mysql -u root -p`

### 2. パスワードを変えるSQL文を実行する
`use mysql;`
`ALTER USER 'root'@'localhost' IDENTIFIED BY "Password";`
上記の2つ目のコマンドのPasswordの部分は自分の新しく設定するパスワードに変えてください。


以上で無事パスワードが設定され、rootユーザーとしてアクセスできるようになりました。

# まとめ
今回の問題解決までに最も大変だったのは、解決手順2を見つけるまででした。
エラー文で検索をかけて情報を集めるうちに、解決手順1のsudoを使えば良いということまではわかったのですが、解決手順2の情報に至るまでに少し時間がかかりました。というのも、古いバージョンの情報ばかり検索にかかってしまったので、調べたコマンドは全て使えなかったからです。結局どのようにして正しい情報に行き着いたかというと、公式ドキュメントを読みました。読者の方の中には、上記の方法で解決できない方がいるかもしれません。それはもしかしたら、この記事の情報が古いものとなったからかもしれません。そのため、一度該当するバージョンの公式ドキュメントを読んでみたら解決方法が見つかるかもしれません。
Pythonで簡体字と繁体字を区別する

## 動機
インターンの業務で中国語を取り扱う案件があったのですが、
その際に簡体字と繁体字を別で処理してほしいとお願いされたのでその時の解決方法です。

## 解決方法
さすが天下の中国ということでライブラリがありました。
zhconvのisscmpを使うと良さそうです。

まずはインストールします。

```shell
> pip install zhconv
```

### コード

```python
import zhconv

# 簡体字の例文
kan_text = '承蒙关照了,今后还请多多关照。送走了一年的辛劳，迎来了又一个崭新的年月，祝您在新的一年里，大展宏图，财源广进！'
# 繁体字の例文
han_text = '承蒙關照了,今後還請多多關照。送走了一年的辛勞，迎來了又一個嶄新的年月，祝您在新的一年裡，大展宏圖，財源廣進！'

print('簡体字: ', zhconv.issimp(kan_text))
# True
print('繁体字: ', zhconv.issimp(han_text))
# False
```

このように簡体字ならTrue, 繁体字ならFalseを返してくれます。
[Microsoft] Azure Bastionを az コマンドラインから作成する

# これはなに？

Azure Bastionをコマンドラインから作成します。
azコマンドを使います。

# テンプレート

早速ですが、こんなテンプレートで作成できます。

```json:bastion-template.json
{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string"
        },
        "bastionHostName": {
            "type": "string"
        },
        "subnetId": {
            "type": "string"
        },
        "publicIpAddressId": {
            "type": "string"
        }
    },
    "resources": [
        {
            "apiVersion": "2018-10-01",
            "type": "Microsoft.Network/bastionHosts",
            "name": "[parameters('bastionHostName')]",
            "location": "[parameters('location')]",
            "dependsOn": [],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "IpConf",
                        "properties": {
                            "subnet": {
                                "id": "[parameters('subnetId')]"
                            },
                            "publicIPAddress": {
                                "id": "[parameters('publicIpAddressId')]"
                            }
                        }
                    }
                ]
            },
            "tags": {}
        }
    ]
}
```

# テンプレートの使い方

azコマンドからは、このように使います。

```sh
az group deployment create \
    --resource-group $GROUP_NAME \
    --template-file bastion-template.json \
    --parameters \
        location=${LOCATION} \
        bastionHostName=${BASTION_HOST_NAME} \
        subnetId=${SUBNET_ID} \
        publicIpAddressId=${IPADDRESS_ID}
```

`GROUP_NAME` `LOCATION` `BASTION_HOST_NAME` は自由に決めてください。


# 事前に必要なもの

サブネットとパブリックIPは、事前に作成しておいてください。
それぞれ条件があります。

## サブネット作成時の条件

* /27 より広くする
* 名前を **AzureBastionSubnet** にする
* NSGを割り当てる場合は、全通しにする

## パブリックIP作成時の条件

* SKUをStandardにする
* （アロケーションメソッドは自動的にStatic）

## IDの取得方法

作成後、それぞれのIDは下記のコマンで取得できます。

### サブネット のIDを取得

```sh

az resource show \
        --resource-group ${GROUP_NAME} \
        --namespace Microsoft.Network \
        --parent virtualnetworks/${VNET_NAME} \
        --resource-type subnets \
        --name AzureBastionSubnet \
        --query id \
        --output tsv
```

`GROUP_NAME` `VNET_NAME` は既存のものを使います。

### パブリックIPのIDを取得

```sh
az resource show \
        --resource-group ${GROUP_NAME} \
        --resource-type Microsoft.Network/publicIPAddresses \
        --name ${PUBLIC_IP_NAME} \
        --query id \
        --output tsv
```

# 参考リンク

- [Azure Bastion (Preview) を試してみる](https://qiita.com/tetsuya-ooooo/items/365ee7766c039a5033cf)


# 最後に

Azure Bastionは、踏み台サーバというよりブラウザ内で動くコンソールです。
これはこれで便利ですが、名前とあっていないかなぁ。
Bastionなら、sshトンネルとか使えて欲しい。
開発方法について

# 要求定義の精度

要求定義ができていないと、クソなプロダクとができあがる

外部のAPI連携において、開発の手順について考えたのでまとめる

## ダメなフロー

- ビジネス的にインパクトの計算ができていない
- 開発後のことが考えられていない　←　機能を使うユースケースが考えられていない

## フロー

- ビジネス観点でvalueがあるのかを明確にする
- Valueを得る為に何ができないといけないのかを明確にする【要求定義】
- 要求に対して、実装出来るかどうかを明確にする【要件定義】
JSON.parse()でSyntaxErrorが出続けるときの対策

#1. 状況
pythonから出力したjson文字列を変数としてhtmlに貼り付けして，JSON.parse()したのちDatatablesを利用しようとしたところ，jsonの構文に誤りがないにもかかわらず下記のエラーが出た．

```
Uncaught SyntaxError: Unexpected token  in JSON at position 3
```

今回はconsole.log()した時点で\u0008に相当する「」（←多分表示されない）が見えたが，特殊文字の中にはconsole.log()で表示される特殊文字と出ないものがあるので注意する．

#2.対策コード 
stackoverflowに対策コードがあった．JSON.parse()でjsonの構文に誤りがないのにエラーが出る場合，とりあえずこれ貼っておけば良さそう．

```js
// preserve newlines, etc - use valid JSON
s = s.replace(/\\n/g, "\\n")  
.replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f");

// remove non-printable and other non-valid JSON chars
s = s.replace(/[\u0000-\u0019]+/g,""); 
```


#3.参考
https://stackoverflow.com/questions/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse
https://qiita.com/qwq00/items/9cd8b8e095bea0633a88
JavaScirpt オブジェクト配列のコールバック処理サンプル

JavaScriptの配列で、コールバック関数を使って処理するサンプルです。

数値配列のサンプルは多いのですが、オブジェクトの配列を処理するサンプルが少ない気がしたので。

```javascript
var list = [
    { id: "A01", name: "yama" },
    { id: "B02", name: "matu" },
    { id: "C03", name: "moto" },
    { id: "D04", name: "sato" },
];

console.log(`${list.length} Members`);
// "4 Members"

// find
let m;
m = list.find(function (x) {
    return x.id == "C03";
});
console.log(`${m.id} is ${m.name}.`);
// "C03 is moto."

// 簡略形式（上記と同じ）
m = list.find(x => x.id == "C03");
console.log(`${m.id} is ${m.name}.`);
// "C03 is moto."

// 全件処理(forEach)
list.forEach(x => console.log(`- ${x.id} : ${x.name}`));
// - A01 : yama
// - B02 : matu
// - C03 : moto
// - D04 : sato

// 加工した別配列を作る(map)
let nameList = list.map(x => x.name.toUpperCase());
console.log(nameList);
// [ 'YAMA', 'MATU', 'MOTO', 'SATO' ]

// 配列を１つにまとめる(reduce)
let title = list.reduce((a, b) => {
    return a += b.name[0].toUpperCase(); // nameの最初の一文字を取得し大文字に
}, "");
console.log(title);
// "YMMS"

// IDが一番大きい人は？
let maxIdMember = list.reduce((a, b) => {
    return a.id > b.id ? a : b;
});
console.log(maxIdMember);
// { id: 'D04', name: 'sato' }

// filter
console.log(list.filter(x => x.name[0] == "m"));
// [ { id: 'B02', name: 'matu' }, { id: 'C03', name: 'moto' } ]

// sort
list.sort((a, b) => a.name > b.name); // sort()は、配列を変更する。
console.log(list);
// [ { id: 'B02', name: 'matu' }, { id: 'C03', name: 'moto' }, { id: 'D04', name: 'sato' }, { id: 'A01', name: 'yama' } ]
```
WSL2環境にOpenCV-Pythonをmakeインストール

##この記事について
OpenCVの[公式チュートリアル](https://docs.opencv.org/4.1.1/d2/de6/tutorial_py_setup_in_ubuntu.html)に沿ってソースからPython3用のOpenCV-Pythonの実行環境を構築していきます。

## 実行環境
当記事では以下の実行環境を対象としています。
別の環境では動作が異なる可能性にご留意ください。
- Windows10 Build 18985
- WSL2
- Ubuntu 18.04
- git 2.17.1
- ccache 3.4.1-1

## Building OpenCV from source
### Required build dependencies
以下のソフトウェアをインストールします
- CMake⇒インストール設定用
- GCC⇒コンパイル用
- Python-devel⇒Pythonビルド用
- Numpy⇒Pythonビルド用

``` sh
sudo apt-get update
sudo apt-get install cmake
sudo apt-get install python-dev python-numpy
sudo apt-get install gcc g++
```

グラフィック関係のライブラリをインストールします

``` sh
sudo apt-get install python-gtk2-dev
sudo apt-get install gtk+3.0
sudo apt-get install ffmpeg
sudo apt-get install libavresample-dev
sudo apt-get install libgstreamer-plugins-base1.0-dev
sudo apt-get install libdc1394-22-dev
```

### Optional Dependencies
OpenCVで使用したい画像形式をオプションとして登録できます。
今回は、PNGとJPEGが利用できれば良いのでこの二つを登録します。
ほかにはJPEG2000,TIFF,WebPといった画像形式が利用できるので必要に応じてインストールしてください。

``` sh
sudo apt-get install libpng-dev
sudo apt-get install libjpeg-turbo8-dev
```

### Downloading OpenCV

任意のディレクトリに移動後、GitHubリポジトリから最新ソースを取得します。

``` sh
cd {任意のディレクトリ}
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
```

取得したOpenCV内にbuildディレクトリを作成し、移動します。

``` sh
cd opencv
mkdir build
cd build
```

### Configuring and Installing 

OpenCVのインストールに必要な環境は整ったので、CMakeを使用した設定を行います。
今回は、デフォルト設定を踏襲します。
CMakeの詳細オプションは[OpenCV C ++コンパイルガイド](https://docs.opencv.org/4.1.1/d7/d9f/tutorial_linux_install.html)を参照してください。

``` sh
$ cmake -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules/
```

インストール設定についてログが大量に出るので、確認する。
以下の様な必要なパッケージの不足がないか、Pythonの環境が正しいかなど

```
--   No package 'gtk+-3.0' found
```

```
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.15)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython2.7.so (ver 2.7.15+)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.13.3)
--     install path:                lib/python2.7/dist-packages/cv2/python-2.7
--
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.6.8)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython3.6m.so (ver 3.6.8)
--     numpy:                       /home/kon/.local/lib/python3.6/site-packages/numpy/core/include (ver 1.17.2)
--     install path:                lib/python3.6/dist-packages/cv2/python-3.6
--
--   Python (for build):            /usr/bin/python2.7
```

問題なければビルドを実行する

```
make -j4
```

### OpenCV-Pythonの動作確認



### 懸念点

CMakeの中で問題になりそうなことがあったのでメモ。

- ライブラリのNo Packageエラー⇒ライブラリを追加して再度Cmake実行
 - gtk+3.0
 - libavresample
 - libdc1394-2

### 参考サイト
以下サイトを参考にさせていただきました。ありがとうございます！
- https://www.trifields.jp/how-to-install-opencv-on-ubuntu-2742
cloud-init で CentOS7 をセットアップする

## ダウンロード

* http://cloud.centos.org/centos/7/images/
    * CentOS-7-x86_64-GenericCloud-1907.qcow2

```sh:8GBということがわかる
$ qemu-img info CentOS-7-x86_64-GenericCloud-1907.qcow2 
image: CentOS-7-x86_64-GenericCloud-1907.qcow2
file format: qcow2
virtual size: 8.0G (8589934592 bytes)
disk size: 887M
cluster_size: 65536
Format specific information:
    compat: 0.10
    refcount bits: 16
```

## seed.iso

* meta-data

```yaml:meta-data
local-hostname: db1.local

network-interfaces: |
  auto eth0
  iface eth0 inet static
  address 192.168.100.62
  netmask 255.255.255.0
  gateway 192.168.100.1
  dns-nameservers 8.8.8.8 8.8.4.4
  #
  auto eth1
  iface eth1 inet static
  address 10.0.1.62
  netmask 255.255.255.0
```

* user-data

```yaml:user-data
#cloud-config

# user: centos
password: plain-password-1
chpasswd: { expire: False }

ssh_pwauth: True

timezone: Asia/Tokyo
locale: ja_JP.utf8

runcmd:
  # SELinux
  - setenforce 0
  - sed -ie 's/^\SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
  - reboot
```

```sh:seed.isoの作成
genisoimage -output seed.iso \
 -volid cidata -joliet -rock \
 user-data meta-data
```

## 起動

`seed.iso`を接続して起動。

![スクリーンショット_2019-10-04_12-54-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/4a31350d-ab52-e537-d8c0-154a597c8812.png)

* `/var/lib/cloud/instance/` 内に、使用された設定ファイルが保存されている。

## 初期設定

```go:ansible2.8を入れてみる
yum install -y epel-release.noarch
yum install -y ansible.noarch
```
[初学者]よく起こるエラー〜ActiveRecord::PendingMigrationError 〜

#目的
学習の備忘録と初学者の参考資料として投稿

#ActiveRecord::PendingMigrationErrorというエラー
MVCの一角であるモデルを作成するため、ターミナルで・・・・

```
＜ターミナル＞

$ rails g model ○○○○（モデル名）

・・・ちょっくら確認してみるか

$ rails s
```

エラー発生！！！！

ActiveRecord::PendingMigrationError〜、あちゃ〜:persevere:

忘れてた:bulb:

#解決方法

```
＜ターミナル＞

$ rails db:migrate

```

＞＞解決！！

#そもそもマイグレーションとは
SQLを書くことなくRubyでデータベース内にテーブルを作成することができる機能。わざわざ面倒くさい事をマイグレーションファイルが行ってくれている。なので絶対忘れずにマイグレーションしよう！！

#[参考]ちなみによく見る『schema.rb』とは
マイグレーションした際に作成されるファイルで、テーブルのカラムやそのデータ型などマイグレーションした結果が書かれている。マイグレーションするたびに最新の状態へ更新。実際ファイルを見てみるといままでのマイグレーションの履歴が見れる。

#まとめ
モデルを作成したら、すぐにマイグレーション実行しよう！！

ちなみにマイグレーションファイルを勝手に削除すると大変な事に・・・・・:scream:

消さないでね:u7981:


今後も学習で気づきや参考になるものがあれば、アップしていきます。
もし参考になったらいいね！！よろしくお願いします:bow_tone1:
[gRPC-Go] Serverのテストをネットワーク接続なしで行う

## gRPC Serverのテスト

gRPCサーバーは通常はTCPサーバーを立てる必要があり、テストしようとすると面倒です。

そこで、通信部分をin-memoryに差し替えてくれる[grpc/test/bufconn](https://godoc.org/google.golang.org/grpc/test/bufconn)というパッケージを利用すると便利です。

bufconnは**ネットワークサーバーのように振る舞う`Listener`を持ち、さらに`Dial()`メソッドでクライアント接続のように振る舞う`net.Conn`も持つ**という特徴があります。

## bufconnを使ってネットワーク接続なしでテスト

それでは、実際にbufconnを使ったテストを書いてみます。


ソースコードは次のリポジトリにも公開しています。
https://github.com/castaneai/grpc-testing-with-bufconn

たとえば[gRPCの公式チュートリアルにもある](https://grpc.io/docs/quickstart/go/)次のようなシンプルなRPCで考えます。

```protobuf
syntax = "proto3";

package hello;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
```

`protoc` でGoの定義ファイルを生成して、次のようなディレクトリ構成とします。

```sh
$ protoc greeter.proto --go_out=plugins=grpc:.
```

```
.
├── go.mod
├── go.sum
├── greeter.pb.go
├── greeter.proto
└── server
   ├── server.go
   └── server_test.go
```

`server/` ディレクトリ以下に2つのファイルを作ります。

- `server.go` サーバーの実装
- `server_test.go` サーバーのテスト（bufconnを使う部分）

`server.go` は[何も特別なことはなく、通常のgRPCサーバーの実装](https://github.com/castaneai/grpc-testing-with-bufconn/blob/master/server/server.go)です。

次に、 `server_test.go` ですがここが重要です！

gRPC-Goでは`grpc.Dial()`でサーバーへ接続をしますが、そこで `grpc.DialContext(grpc.WithCotnextDialer(...))` を使います。

`WithContextDialer`の中身をbufconnへの接続 `lis.Dial()` に差し替えるというやり方です。

```go:server_test.go
package main

import (
	"context"
	"log"
	"net"
	"testing"

	"google.golang.org/grpc"
	"google.golang.org/grpc/test/bufconn"

	pb "github.com/castaneai/grpc-testing-with-bufconn"
)

const bufSize = 1024 * 1024

var lis *bufconn.Listener

func init() {
	lis = bufconn.Listen(bufSize)
	s := grpc.NewServer()
	pb.RegisterGreeterServer(s, &server{})
	go func() {
		if err := s.Serve(lis); err != nil {
			log.Fatal(err)
		}
	}()
}

func bufDialer(ctx context.Context, address string) (net.Conn, error) {
	return lis.Dial()
}

func TestSayHello(t *testing.T) {
	ctx := context.Background()
	conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
	if err != nil {
		t.Fatal(err)
	}
	defer conn.Close()

	client := pb.NewGreeterClient(conn)
	resp, err := client.SayHello(ctx, &pb.HelloRequest{Name: "test"})
	if err != nil {
		t.Fatal(err)
	}

	if resp.GetMessage() != "Hello test" {
		t.Fatal("hello reply must be 'Hello test'")
	}
}
```


これでテストを実行してみると、即座にテストが通りました！ :smile: 

```
$ go test -v ./...
=== RUN   TestSayHello
2019/10/04 12:50:04 Received: test
--- PASS: TestSayHello (0.00s)
PASS
ok  	github.com/castaneai/grpc-testing-with-bufconn/server	0.024s
```
素数判定　Java

素数判定のコードです。
もっと効率のいいコードやきれいなコードがございましたら、アドバイスよろしくお願い致します。



```
import java.io.*;

class ファイル名{
		public static void main(String[]args) throws IOException
		{
			BufferedReader br =
				new BufferedReader(new InputStreamReader(System.in));
			
			System.out.print("正の整数を入力してください");
			String str = br.readLine();
			int a =Integer.parseInt(str);
			
			boolean sosu = true;
			
			if(a == 1)sosu = false;
			
			for(int b = 2; b*b <= a; b++){
				if(a%b == 0){
					sosu = false;
					break;
				}
			}
			
			if(sosu == true) System.out.println("\n"+a+"は素数です");
			else System.out.println("\n"+a+"は素数ではありません");
			
			
		}
}
```
【初心者向け】Android アプリの基本：ブロードキャスト

###ブロードキャストとは
 - 送り先を指定せず不特定多数の相手に投げるメッセージ。
 - ブロードキャストは インテントとして 投げられる。

###サービスとは
 - UIをもたず、バックグラウンドで処理を実行するコンポーネント。

###コンテンツプロバイダとは
- 他アプリに対してアプリ内の データを公開するコンポーネント。
- 公開できる主なデータは「DBテーブルデータ」「ファイルデータ」。

###コンテンツリゾルバとは
- コンテンツURIから Android システム内の対象となるコンテンツプロバイダを探し、そのプロバイダが提供するデータのアクセスを行う。

###コンテントURIとは
 - コンテンツプロバイダが提供するデータを指し示すURI
 - 書き方：　　**content://{authority}/{path}**<br>
 
- authority： プロバイダを識別するための名前。
       - プロバイダクラスの「完全修飾クラス名を小文字」にしたものを付けるのが推奨されている。
    	例) コンテンツプロバイダが「org.sample.MyProvider」 だった場合org.sample.myprovider
    　
    - プロバイダが提供するデータの中のどのデータなのかを識別する名前。
    - aaa/bbb/ccc のように階層形式で付けられ、各部分を「セグメント」という。<br>
    	例1) hoge テーブルの全レコード
    			content://org.sample.myprovider/hoge<br>
    	例2) hoge テーブルの ID=10 のレコード
    		content://org.sample.myprovider/hoge/10

###インテントとは
- Android システムに送る「何をしたいか」のメッセージ

###インテントに設定できる情報
1. 呼び出し対象を絞り込む条件 (必須)
   - コンポーネント名
   - アクション名
   - カテゴリ
   - データ
2. 呼び出し対象に送るデータ
   - エクストラ
   - フラグ(インテントフラグ)

###インデントの種類
- **明示的インテント**
  - 呼び出し対象を一意に指定するインテントのこと。
  - 絞り込み条件でいうと「コンポーネント名」を指定したインテント。
  - 例：アクティビティ名を指定しインテントを生成
  
            Intent intent = new Intent(context, FooActivity.class);

- **暗黙的インテント**
  - 呼び出し対象が必ずしも一意にならないインテントのこと。
  - 絞り込み条件でいうと「アクション名」「カテゴリ」「データ」を指定したインテント。
  - 例：アクション名とURIを指定してインテントを生成


            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));

###インテントフラグとは
- インテントによって起動されるアクティビティの起動方法を指定するもの<br>

###主要なインテントフラグ
- FLAG_ACTIVITY_CLEAR_TOP
  - 起動するアクティビティが現在のスタック内に存在する時、そのアクティビティから上の全アクティビティをスタックから削除する。
- FLAG_ACTIVITY_SINGLE_TOP
  - スタックの先頭が同じアクティビティの場合に新しくアクティビティを生成せず再利用
- FLAG_ACTIVITY_NEW_TASK
  - 新しいタスクを作り、そのルートアクティビティとして起動
- FLAG_ACTIVITY_MULTIPLE_TASK
  - new_taskと一緒に使用する
- FLAG_ACTIVITY_NO_HISTORY"
  - タスクのスタックに保持されない。
  - ユーザが戻るボタンでこのフラグを指定したアクティビティに戻ってきた時、スタックに保存されていないため、結果的にスキップされる。
 
###インテントフィルタとは
- インテントの絞り込み条件(アクション、カテゴリ、データ)のヒット対象になるかをコンポーネントに定義したもの。<br>
（インテントを受けることができる「アクティビティ」「サービス」「ブロードキャストレシーバ」の3つのコンポーネントに設定できる。）
- Android マニフェストの各コンポーネント定義 < activity >, < service >, < receiver > の子要素として定義する。

###エクストラとは
- 呼び出し対象に渡せる Bundle 形式のデータ。
- Bundle クラス：キーと値のセットを保持するクラス（Map と似たようなもの）

###エクストラの格納と取り出し方
- データ格納する送信側

        // インテントのインスタンス生成する
        Intent intent = new Intent(this, FooActivity);
        // エクストラにデータを格納する
        intent.putExtra("key1", 10);
        intent.putExtra("key2", "abc");
        startActivity(intent);

- データを取り出す受信側

        // インテントのエクストラからデータ取り出し
        int val1 = getIntent().getIntExtra("key1", 0);
        String val2 = getIntent().getStringExtra("key2");
個人的にベストなメディアクエリ記述方法

##SCSSでMixinを活用したSP対応

現在のプロジェクトでは以下の様にSCSSの`@mixin`と`@include`を用いてSP対応をしています。
それぞれの詳しい使用方法は[こちら](https://qiita.com/nekoneko-wanwan/items/c8498a21ae0e2b2198be)の記事で分かりやすく書かれています。


まずはMixinを記述します
(自分は各Mixinを専用のscssファイルにまとめています)

``` SCSS
//mixin.scss

//SP用
@mixin media-sp {
  @media screen and (max-width: 800px) {
    @content;
  }
}

//iphone5用
@mixin media-iphone5 {
  @media screen and (max-width: 320px) {
    @content;
  }
}
```


あとは`@include`で好きなクラスで呼び出して使うだけ！


``` SCSS
//hoge.scss

&__title {
   font-size: 2rem;

  @include media-sp {
    font-size: 1.6rem;
  }

  @include media-iphone5 {
    font-size: 1.4rem;
  }
}
```
####めっちゃ分かりやすい！！
基本的にメディアクエリの指定がクラス毎にまとまるので、CSS迷子になりにくくなります。

CSSのみを使っていた頃は`@media screen and (max-width: 800px) `配下に同じクラスを再び記述していた為、クラス名で検索すると2つヒットしてしまうなどよく迷子になっていました。。。

もっと良い方法があるかもしれませんが、今の所ベストなんじゃないかなぁ…(˙◁˙)
Azure Text to Speech REST API をやーる（Python 3.6.9）

AzureのCognitiveServicesを用いて、テキストから音声変換をやってみました。

## はじめに

Azure Portalにログインして、リソースの作成から「音声」を検索し作成してください。
リソースグループ名、エンドポイントおよびsubscription keyを用いるのでコピペしてください。

## サンプルコード
'YOUR_RESOURCE_NAME'を作成したリソースグループ名に変更してください。
"YOUR_KEY_HERE"を作成したsubscription keyに変更してください。
fetch_token_urlやbase_urlを作成したリージョンのエンドポイントに合わせて変更してください。

~~~python 
import os
import requests
import time
from xml.etree import ElementTree

try:
    input = raw_input
except NameError:
    pass

class TextToSpeech(object):
    def __init__(self, subscription_key):
        self.subscription_key = subscription_key
        self.tts = input("What would you like to convert to speech: ")
        self.timestr = time.strftime("%Y%m%d-%H%M")
        self.access_token = None

    def get_token(self):
        fetch_token_url = 'https://westus.api.cognitive.microsoft.com/sts/v1.0/issuetoken'
        headers = {
            'Ocp-Apim-Subscription-Key': self.subscription_key
        }
        response = requests.post(fetch_token_url, headers=headers)
        self.access_token = str(response.text)
        # return self.access_token

    def save_audio(self):
        base_url = 'https://westus.tts.speech.microsoft.com/'
        path = 'cognitiveservices/v1'
        constructed_url = base_url + path
        headers = {
            'Authorization': 'Bearer ' + self.access_token,
            'Content-Type': 'application/ssml+xml',
            'X-Microsoft-OutputFormat': 'riff-24khz-16bit-mono-pcm',
            'User-Agent': 'speechsdk'
        }
        xml_body = ElementTree.Element('speak', version='1.0')
        xml_body.set('{http://www.w3.org/XML/1998/namespace}lang', 'en-us')
        voice = ElementTree.SubElement(xml_body, 'voice')
        voice.set('{http://www.w3.org/XML/1998/namespace}lang', 'en-US')
        voice.set(
            'name', 'Microsoft Server Speech Text to Speech Voice (en-US, Guy24KRUS)')
        voice.text = self.tts
        body = ElementTree.tostring(xml_body)

        response = requests.post(constructed_url, headers=headers, data=body)
        if response.status_code == 200:
            with open('sample-' + self.timestr + '.wav', 'wb') as audio:
                audio.write(response.content)
                print("\nStatus code: " + str(response.status_code) +
                      "\nYour TTS is ready for playback.\n")
        else:
            print("\nStatus code: " + str(response.status_code) +
                  "\nSomething went wrong. Check your subscription key and headers.\n")

if __name__ == "__main__":
    subscription_key = "YOUR_KEY_HERE"
    app = TextToSpeech(subscription_key)
    app.get_token()
    app.save_audio()
~~~

## 結果
下記のように表示されれば成功です。フォルダの中にsample-yyyymmdd-hhmm.wavの音声ファイルが生成されているはずです。

~~~
(py36) D:\User\s-fujimoto\sts>python tts.py
What would you like to convert to speech: hello world

Status code: 200
Your TTS is ready for playback.
~~~

## 参考文献
[クイック スタート: Python を使用してテキストを音声に変換する](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/quickstart-python-text-to-speech?fbclid=IwAR2zk6s9XcOGxXzGlOb9tfrg8hw7jTozXuGEnbk-M3ZORrJFbLPZE6Y2d1k)
【Unity(C#)】VIVE用にデバッグ時のリセット実装

##デバッグでPCまで戻るのめんどくさい
デバッグはしらみつぶしに行いたいのでキー入力でリセットの実装にしてると
何度もPCとプレイ位置を往復するのでめんどうです。

かなり短くてしょーもない記事ですが、今後毎回使いそうなのでメモします。

##コード

ベースはまんま前の記事[^1]ですが、、、

```C#
#if UNITY_EDITOR
using UnityEngine;
using UnityEngine.SceneManagement;
using Valve.VR;

public class DebugReload : MonoBehaviour
{
    [SerializeField]
    SteamVR_Input_Sources hand;

    [SerializeField]
    SteamVR_Action_Boolean grabAction;

    [SerializeField]
    float inputSeconds;

    bool preventContinuityPushButton;

    float timer;


    void Update()
    {

        if (grabAction.GetStateDown(hand))
        {
            preventContinuityPushButton = true;
        }

        if (grabAction.GetState(hand) == false)
        {
            timer = 0;
            return;
        }
        else if (grabAction.GetState(hand) && preventContinuityPushButton)
        {
            timer += Time.deltaTime;
        }

        if (timer > inputSeconds)
        {
            Scene loadScene = SceneManager.GetActiveScene();
            SceneManager.LoadScene(loadScene.name);
        }
    }
}
#endif
```

SteamVR 2.0からVIVEの入力回りは、最初に設定したアクションから取得する形になってます。
簡単に言えば、それぞれの入力にポーズ名が決まっているだけのことです。

今回はGripButtonの取得をしたいので、GrabGripを設定すればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/77025be9-276f-4b5a-3ba4-987e382f41bf.png)


##Platform Dependent Compilation(プラットフォーム依存コンパイル)[^2]

下記のようにEditor上のみでコンパイルする設定にしておけば、
実行ファイル形式で書きだした際に、変な機能が残ったままにならないので便利です。

```
#if UNITY_EDITOR

#endif
```



[^1]: [【Unity(C#)】VRのデモ向けリセット、スキップ機能の実装方法](https://qiita.com/OKsaiyowa/items/906bbdcaa9630beffc65)
[^2]: [Unity　プラットフォーム判別](https://qiita.com/Ubermensch/items/75072ef89249cb3b30e7)
Rails6 のちょい足しな新機能を試す89（Event object編）

# はじめに

Rails 6 に追加された新機能を試す第89段。 今回は、 `Event object` 編です。
Rails 6 では、`ActiveSupport::Notifications.subscribe` で、ブロックパラメータを1つにすると、そのブロックパラメータに `ActiveSupport::Notifications::Event` オブジェクトが設定されるようになりました。
これで、ブロックの中で `ActiveSupport::Notifications::Event.new` を使う必要がなくなりました。

Ruby 2.6.4, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.0
```

今回は、User の CRUD を作り、各コントローラのアクションを実行したときの情報を取得してログに出力してみます。

# プロジェクトを作る

```shell
rails new rails_sandbox
cd rails_sandbox
```

# User の CRUD を作る

name をもつ User の CRUD を作ります

```shell
bin/rails g scaffold User name
```

# Subscribe する

`config/initializers/notification_subscriber.rb` を作成します。
`ActiveSupport::Notifications.subscribe` を呼び出すときに、ブロックパラメータを `event` 1つだけにします。

```ruby:config/initializers/notification_subscriber.rb
ActiveSupport::Notifications.subscribe 'process_action.action_controller' do |event|
  action = "#{event.payload[:controller]}##{event.payload[:action]}"
  Rails.logger.info("#{action} cpu_time=#{event.cpu_time} duration=#{event.duration} allocations=#{event.allocations}")
end
```

# User の登録などをしてログを確認する

実際に `rails server` を実行してブラウザから http://localhost:3000/users にアクセスします。

以下のようにコンソールに出力されているはずです。

```
...
UsersController#index cpu_time=833.013591 duration=840.9244199865498 allocations=1237733
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try089_subscriber_event

# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Add event object subscriptions to AS::Notifications](https://github.com/rails/rails/pull/33451)
JetBrains製品のプログレスバーをNyanCatにする

プログレスバーの進みが遅くて嫌な気持ちになる時がありますよね
そんな時は猫に癒やされながら待ちましょう

# Nyan Progress Bar
そんなプログレスバーをNyanCatに変えてしまう素敵なプラグイン
https://plugins.jetbrains.com/plugin/8575-nyan-progress-bar

### インストール

1. `Command` + `,`で環境設定を開きます
2. `Plugins`を選択後、`Marketplace`を選択し
3. 検索欄に`Nyan Progress Bar`と入力します
4. `Install`を押下した後、IDEを再起動する様に促されるので再起動します

### こんな風になる

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392170/1c2d8893-877d-a787-80da-81acf2ac710e.gif)

これはとても癒やされますね
皆さんもNyanCatを見て癒やされながら仕事をこなしましょう

Happy Coding!!
[ERROR ITMS-90060] 正しくないCFBundleShortVersionStringによるApp Store Connectへのアップロードエラー

### 発生内容と原因

開発しているアプリをApp Store Connectにアップロードする際に、下記エラーが吐かれました。

> ERROR ITMS-90060: "This bundle is invalid. The value for key CFBundleShortVersionString '5.0.0-beta.4' in the Info.plist file must be a period-separated list of at most three non-negative integers. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"

開発で使っているAlamofireのバージョンが`5.0.0-beta4`であり、CFBundleShortVersionStringが`5.0.0-beta4`でした。このため、上記のエラーが吐かれアップロードが正常に終了しない状態となりました。

### 応急処置

Carthageを使っていたので、CheckoutされているAlamofireのInfo.plistで`5.0.0-beta4`から`5.0.0`に直接書き換え、

```sh
$ carthage build --platform iOS --no-use-binaries Alamofire
```

を実行し、再度ビルドしました。

### 今後の残タスク

Alamofireの正式なver5.0.0がリリースされたのちに、それへの切り替えを行う予定です。

### リンク

[Alamofire/Info.plist at 5.0.0-beta.4](https://github.com/Alamofire/Alamofire/blob/5.0.0-beta.4/Source/Info.plist)

CFBundleShortVersionStringが`5.0.0-beta4`となっているのが確認できます。
LineSDK入れ込みでハマった話

## 経緯
* LineSDKでログイン認証することに
* とりあえずSDKを入れて、ID設定して、コード書いてみた
* Unity上だと動作チェックできないのでUnityCloudBuildでiOS, Androidビルド
* **>> ビルドエラー！ <<**

## 原因１：対応バージョン見てなかった
LineSDKは **Android API 17(Android4.2)以上、 iOS 10.0以上対応** です。
これをビルド時の対応バージョン修正することで、Androidはビルドできるようになりました。
*だからReadmeは読めとあれほど(ry*

## 原因２：Library Search Paths
iOSが相変わらずビルドできない上に、よく見るあのエラーが発生していることを確認。

```Undefined symbols for architecture arm64```

そう、やつです。
エラー文だけではどこが悪いのか全然分からないやつです。
CocoaPodの設定が悪いのかなど散々迷走したあげく、Swift関連のライブラリが軒並みリンク失敗して入れ込めてないことに気づきました。

参考：https://stackoverflow.com/questions/52536380/why-linker-link-static-libraries-with-errors-ios

参考リンク先で言われているように、Unityの `OnPostprocessBuild`内にて、以下を追加することでiOSビルドができるようになりました。
```project.AddBuildProperty (target, "LIBRARY_SEARCH_PATHS", "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)");```

## 感想
今回、UnityCloudBuildを使ったことで、より問題を複雑に考えて迷走しました。
原因はどっちも基本的な部分にあったので、一旦落ち着いてローカル環境でも同じ問題が起きるかなどきちんと確かめていくと絞り込みやすいかなと思いました。
*あと、Readmeは読もう。*
Vue CLIプロジェクトがネストされるとgitHooksが動作しない問題の解決

## 問題
Vue CLIでプロジェクトを作る際に`Lint and fix on commit`にチェックを入れたが、コミットをしてもリンターが動作しない。

## 原因
リポジトリの中にフロントエンド(Vue)用のディレクトリとサーバーサイド用のディレクトリがあったため。

## 解決方法
リポジトリのルートでgitHooksを呼び出せばよい。

リポジトリのルートで`npm init -y && npm i -D yorkie`
`yorkie`はGit hookを手軽に記述できる`husky`からフォークされたもので、@vue/cli-serviceについてくる。

package.jsonにgitHooksを記述する。

```
{
  "name": "nesting-yorkie-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "gitHooks": {
    // コミット時の動作を記述する
    "pre-commit": "cd 'ネストされたVueCLIプロジェクト' && node_modules/.bin/lint-staged"
  },
  "devDependencies": {
    "yorkie": "^2.0.0"
  }
}

```

[サンプル](https://github.com/takenaka/nesting-yorkie-example)
vue + laravel

#axiosを使った通信
viewのaxiosを使用してTestsControllerのcreateメソッドに値を渡す。
またTestsControllerのcreateメソッドからviewに値を返し(res.data)viewで受け取っています。

```js:welcome.blade.php

        axios
			.post('http://localhost/public/test/create', postParam)
			.then((res) => {
				console.log(res.data);
				alert('TestController@createから帰ってきたデータは' + res.data.test);
			}).catch((ex) => {
				console.log('failed');
			});

```

```php:TestsController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class TestsController extends Controller
{
    /**
	 * Display a listing of the resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function index()
	{
		Log::info('Showing user profile for user: ');
		return view('welcome');
	}
	/**
	 * Show the form for creating a new resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function create(Request $request)
	{
		Log::info('Showing user profile for user: ');
		$data = $request->all();

		return $data;
	}
}
```

```php:web.php
Route::get('/test', 'TestsController@index');
Route::get('/test/create', 'TestsController@create');
Route::post('/test/create', 'TestsController@create');
```

#バリデーション
1.バリデーション定義を作成

StoreBlogPostは適当な名前です。

```cmd:cmd
php artisan make:request StoreBlogPost
```

app\Http\Requestsの中に生成される

- ルールの追加

```php:StoreBlogPost
public function rules()
	{
                // 必須かつ最大文字数10文字
		return [
			'test' => 'required|max:10',
		];
	}
```



参考資料:https://www.slideshare.net/ssuser817ccb/laravel-bladevuejs

- laravel mix
 - dockerを使っている場合はlocalとdockerのhttpd.confのdocumentrootは合わせること
 pathが合わずにapp.jsなどが読み込まれないこともある
EV3とRaspberryPi間のシリアル通信方法_2

ここでは、EV3とRaspberryPiの間でシリアル通信する方法を紹介します。
この方法を応用することで、RaspberryPiでEV3のセンサーを扱うことができたり、RaspberyPiのカメラを用いることで、カメラを使った制御をEV3で行うことができます。

# 使用するもの
-   RaspberryPi3 Model B+
-   SDカード：RaspberyPi用
-   EV3Console
-   データ通信が可能なUSBケーブル (TypeA to MicroB USB2.0)
-   教育版レゴ マインドストーム EV3</font>
-   SDカード：EV3RT用</font>  


# 1. pyserialのインストール
RaspberryPiでシリアル通信を行う準備をします。
まずは、DNS設定を確認します。
RaspberryPiのコンソールを開き、以下のコマンドを入力します。

```
User@linux:~$ cat /etc/network/interfaces
```
表示される文字列に、以下のような記載が含まれるか確認します。
「nameserver 0.0.0.0」 ※実際には0ではありません。
なければ、DNSの設定をする必要があります。

以下のコマンドを入力して、設定を確認します。

```
User@linux:~$ cat /etc/resolv.conf
```
以下のような記載部分の数値を確認します。
「nameserver 0.0.0.0」 ※実際には0ではありません。
「/etc/network/interfaces」をviエディタで編集し、先ほど確認した確認した文字列を書き込みます。

```
User@linux:~$ sudo vi /etc/network/interfaces
```

DNS設定が完了したら、以下のコマンドを入力し、pyserialをインストールします。

```
User@linux:~$ sudo apt install python3-pip
User@linux:~$ pip3 install pyserial
```


# 2. EV3RTの準備
EV3をC言語で動かすための、EV3RT環境を導入します。
※ここでは詳細は省きます。
以下のリンクを参照ください。
[開発環境構築手順](https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnv#%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB)
[プラットフォームのインストール](https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnv#%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB)  

また、SDカード（Raspbery Pi用と別のもの）に上記でダウンロードしたパッケージ内の「sdcard」フォルダの中身をコピーします。
シリアル通信に使用するポートでは、設定を無効かする必要があります。
「ev3rt/etc/rc.conf.ini」に以下の内容を追記します。※シリアル通信に使うポート番号を指定します。

```ev3rt/etc/rc.conf.ini
[Sensors]
DisablePort1=1
```

# シリアル通信プログラム　Raspbery Pi　→　EV3
EV3 → Raspbery Piの順に実行します。
EV3側では、以下のプログラムを実行します。

```app.c
#include <string.h>
#include <stdio.h>

#include "ev3api.h"
#include "app.h"

#if defined(BUILD_MODULE)
#include "module_cfg.h"
#else
#include "kernel_cfg.h"
#endif

static FILE *serial = NULL;  

void main_task(intptr_t unused) {
    ev3_sensor_config (touch_sensor,TOUCH_SENSOR);
    char lcdstr[100];

    // Open serial port
    serial = ev3_serial_open_file(EV3_SERIAL_UART);  
    assert(serial != NULL);
    // read string
    fgets(lcdstr, 6, serial);
    ev3_lcd_draw_string(lcdstr, 0, 10);
}
```

Raspberry Pi側では以下のプログラムを実行します。

```serialTest.py
import serial
import time

# serial communication(Raspi-> EV3)
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=None)
ser.reset_input_buffer()


def write(msg):
    ser.write(bytes(msg,'UTF-8'))


def read():
    while True:
        r = ser.read(1)
        if r == b'xfe':
            break
    r = ser.read(1)
    return int(r[0])

def close():
    ser.close()

msg = 'Hello'
write(msg)
close()

```
EV3のLCDに「Hello」の文字列が表示されれば成功です。
display:none; visivility:hidden; opacity:0; の使い分け

#要素を非表示にする際に使われる方法
display:none;
visibility:hidden;
opacity:0;
>参照 : https://qiita.com/FJHoshi/items/0ed4b628acdab696be62

##display:none;
cssプロパティのdisplayに指定できる値。
他の値に
・block
・inline
・inline-block
がある。

##visivility:hidden;
cssプロパティのvisibilityで指定できる値。
他の値に
・visible（ボックスを表示）
・collapse（テーブルの行や列にこの値をしてすると、その部分を詰めて表示する）
などがある。

##opacity:0
cssプロパティのopacityで指定できる値。
要素の色の透明度を指定する。
数値：0.0~1.0までの数値を指定する。0が完全な透明。1は完全な不透明。

#3つの違い
**要素を無くすか、非表示にするか、透明にするか**
##display:none
要素ごと消してしまう。
レイアウトが変わる場合がある。
もう完全になくなる。
##visibility:hidden
要素を非表示にするだけなので要素自体は残っている。
領域確保できるけど、クリックは出来ない。
##opacity:0
要素を透明にするだけ。
領域確保、クリックも可能。