OmniAICreator/Qiita-1.07M huggingface dataset:
FireStoreのドキュメントはサブコレクションがあっても自フィールドがないと空扱い

ちょっと嵌ったのでメモ。

# 概要
FireStoreで、コレクションhogeにサブコレクションとしてfugaを追加し、
(`hoge/hogeId/fuga/fugaId`という形)
`hoge/hogeId/fuga/fugaId`のにだけドキュメントを追加して、
`hoge/hogeId`には何もSetしなかった場合、
FireStoreのコンソール上では`hoge/hogeId`に何かしら存在するように見えますが
fireStoreのSDKからはデータを確認/取得はできません。

``` javascript
fireStore().collections('hoge').doc('hogeId').get().then((doc) => {
  console.log(doc.exists);//false
});
```

実データがないのでデータ自体に困ることはありませんが、
サブコレクションを持っているドキュメントIDの一覧を取りたい場合や、上位のドキュメントIDを問わずサブコレクションのデータを取りたい場合に困ります。

## 理由
FireStoreはコンソールから見ると階層データ構造に見えますが、内部的にはKVSに近いので
`hoge/hogeId/fuga/fugaId`は単なるパスに過ぎず、これにデータを入れたからと言って親として`hoge/hogeId/`が生成されるわけではありません。

## でも管理コンソールでは空ドキュメントも含めて描画してるけど
実はAdminSDK側には、空でもサブコレクションがあればdocIDを取ってくるlistDocumentsというAPIが実装されています。
自分でDBツールを自作する時はこれを使えばいいのでは？

## 通常のSDKでも何とか空ドキュメントの一覧を取ったりサブコレクションの一覧が欲しい場合は？
* 通常のSDKにはlistDocumentsがないので、空ドキュメントのIDを取るのは無理です。
* 一覧が欲しい場合には別ドキュメントやコレクションで管理しましょう。
* 下位のサブコレクションに対しクエリを投げたい場合は[コレクショングループクエリ](https://firebase.google.com/docs/firestore/query-data/queries?hl=ja#collection-group-query)を使う手もあります。
* そもそも素直に欲しいデータが取れない時点でDB設計をミスっているとも言えます。(自戒)　NoSQLの時にはクエリドリブンにデータベース設計をしましょう。
* 厳密な即時反映が必要でなければCloudFunctionsを使って取りやすい形に非正規化もありです。
#Ruby の Foreman で  #Rails のログも監視してみる

# Procfile

```
log: tail -f log/development.log
```

```
bundle exec foreman start
```

# example

![image](https://user-images.githubusercontent.com/13635059/64826942-60dc4000-d5fd-11e9-9acc-febe56efd696.png)
![image](https://user-images.githubusercontent.com/13635059/64826943-6174d680-d5fd-11e9-9b17-f8bef639d03a.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Auto Scallingで重複したスケジュールアクションを追加しようとしたらどうなるか

Auto Scallingに重複したスケジュールアクションを追加したらどうなるかというだけの話。



このようなAuto Scallingのスケジュールアクションを作成したとする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/824b6599-b283-7aeb-7263-18f3c70908f1.png)


`Scheduled action with this scheduled start time already exists`
と既に追加されているとエラーが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/16d29181-c108-df3e-28fb-cca804c12082.png)
【paiza】swift で複数行の標準入力を受け取る方法

paizaをSwiftで挑戦中ですが、複数行の標準入力の受け取り方でこけたのでメモ。
(なぜSwiftはサンプルコードがないのか。。。)

関係ないけど、paizaのswiftはバージョン3.0.1（20190913現在）なんですね。
xcode10だと5.0だからまたどこかで書き方の差が出てハマりそうだ。。

# (結論)複数行の標準入力の受け取り方

```qiita.swift
/* 標準入力で次のように与えられたとする
2
5
4
*/

var Array = [String]()        // String型の配列を用意
let row = 3                   // 入力される行数
for i in 0..<row {
    Array.append(readLine()!) // for文で配列に追加する
}
print(Array)  // 出力結果 -> ["2", "5", "4"] 
```
複数行ある場合、その行数と同じ回数`readline()!`を取りにいかなればならないようである。
数が多い場合を想定してfor文で記載した。

# 解説
言語選択でSwiftを選択した際のデフォルト通り出力してみる。
一行目の値のみString型で出力される。

```qiita.swift
/* 入力例
2
5
4
*/
let input_line = readline()!
print(input_line)

/* 結果
"2"
*/
```
試しに２回出力してみる。
二行出力される。

```qiita.swift
/* 入力例
2
5
4
*/
let input_line1 = readline()!
let input_line2 = readline()!
print(input_line1)
print(input_line2)

/* 結果
"2"
"5"
*/
```
# 初心者はこんなことでも簡単に心が折れる
最初`"2\n5\n4"`みたいなのを想像して頑張って改行でセパレートしようと頑張った。
全然違った。辛い。
辛くてもググるの大事。先人は偉大です。
【PBCS】ビジネス・ルールを使用した計算処理 - 計算スクリプトの紹介②

前記事はこちら
[【PBCS】ビジネス・ルールを使用した計算処理 - 計算スクリプトの紹介①](https://qiita.com/iwa_gino/items/a560fe6adcb3215f8c2f)

# 積上処理

・密次元：メンバー多→少の次元順で処理（CALC DIM）
・疎次元：メンバー少→多の次元順で処理（AGG）

【以下スクリプト例】


```
/*STARTCOMPONENT:SCRIPT*/
/*STARTCOMPONENT:SCRIPT*/
/**********************************************/
/* プログラム名称:BR001_積上処理          
/* 作成者：                               
/* 更新者：                                     
/* 作成日：2018/3/8                           
/* 更新日：                                     
/*--------------------------------------------
/* Ver1.0 新規作成                      
/**********************************************/
/* 環境変数 */
  SET AGGMISSG ON;    
  SET CACHE HIGH;
  SET LOCKBLOCK HIGH;
  SET UPDATECALC OFF;
  SET FRMLBOTTOMUP ON;
  
/* 積上処理 */
FIX ({P_Years},{P_Scenario},{P_Version})

/*    CALC DIM("Account","Period"); 
    CALC DIM("Product");
    CALC DIM("Entity");
    CALC DIM("Media");
    CALC DIM("Agency");*/
    
    /* 密次元 */
    CALC DIM("Account","Period");
    
    /* 疎次元 */
    CALC DIM("Media");
    AGG("Product");
    AGG("Entity");
    AGG("Agency");
    
    
ENDFIX
/*ENDCOMPONENT*/
/*ENDCOMPONENT*/
```

# 配賦処理


```
FIX ("BaseData",
 "Apr",
     "Final",
     "Yamagata",
     "No_C1"
     "FY17",
     "Marketing"
     )

/* 
　配賦元：2017マーケティング製品無し
  配賦先：2017マーケティング各製品
  配賦基準：売上実績比 
*/

"Budget" = @ALLOCATE(

            /* 配賦元 */"No_Product", 
            /* 配賦先 */@RELATIVE("ProductTotal", 0), 
            /* 配賦基準*/"FY16"->"Sales"->"Actual",
            /* 丸め誤差追加メンバ */,
            /* 配賦方式 */share,
            /* 丸めの有無 */roundAmt,
            /* 丸め桁数 */ 2);

ENDFIX
```

# 配賦処理の高速化


```
//①変数workに配賦値を代入
  FIX ({P_From_Account})	/*科目（配賦元）*/
    FIX ({P_From_Entity})	/*組織（配賦元）*/
    	"Work"=@MDALLOCATE({P_From_Ctgr},2,@List({P_To_Account}),@List({P_To_Entity}),"Direct"->{P_Basic_Account},,share,roundAmt,0,errorsToHigh);
    ENDFIX
  ENDFIX
  
//②配賦先のデータに配賦結果を加算する
  FIX ({P_To_Account})	/*配賦先（科目）*/
    FIX ({P_To_Entity})		/*配賦先（組織）*/
    	{P_To_Ctgr}={P_To_Ctgr}+"Work";
    ENDFIX
  ENDFIX

//③配賦先の配賦作業用メンバーのクリア
  FIX ({P_To_Account})	/*配賦先（科目）*/
    FIX ({P_To_Entity})		/*配賦先（組織）*/
    	CLEARDATA "Work";
    ENDFIX
  ENDFIX
  
//④配賦先に配賦元のデータでマイナス値を作成する（処理後に配賦元データを0にする場合）
  FIX (@Relative({P_From_Account},0))	/*配賦元（科目）*/
    FIX (@Relative({P_From_Unit},0))	/*配賦元（組織）*/
    	{P_To_Ctgr}={P_To_Ctgr}+{P_From_Ctgr}*-1;
    ENDFIX
  ENDFIX
```
Amazon Aurora MySQLの接続数限界

| インスタンスクラス | max_connections デフォルト値 |
|:--|--:|
| db.t2.small | 45 |
| db.t2.medium | 90 |
| db.r3.large | 1,000 |
| db.r3.xlarge | 2000 |
| db.r3.2xlarge | 3000 |
| db.r3.4xlarge | 4000 |
| db.r3.8xlarge | 5000 |
| db.r4.large | 1,000 |
| db.r4.xlarge | 2000 |
| db.r4.2xlarge | 3000 |
| db.r4.4xlarge | 4000 |
| db.r4.8xlarge | 5000 |
| db.r4.16xlarge | 6000 |

## 参考

[Amazon Aurora MySQL のパフォーマンスとスケーリングの管理 - Amazon Aurora](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html)
【PBCS】ビジネス・ルールを使用した計算処理 - 計算スクリプトの紹介①

前記事はこちら
[【PBCS】ビジネス・ルールを使用した計算処理 - 機能説明](https://qiita.com/iwa_gino/items/aef3368b8d70520c1479)

# SET文
先頭に記載することで、計算処理の各種設定を定義するためのスクリプト

## SET AGGMISSG

Essbase が#MISSING の値をデータベースと連結するかどうかを指定

## SET CACHE

計算機キャッシュのサイズを指定

## SET LOCKBLOCK

疎メンバー式の計算時にEssbase で同時にアドレスを指定できるブロックの最大数を指定

## SET NOTICE

計算の進行状況に関する完了通知の頻度を設定

## SET UPDATECALC

高機能計算のオンまたはオフ
ON：ダーティ・ブロック（データを更新したデータ・ブロック）と、それに依存する親のみ計算
OFF：データ・ブロックが更新されているかどうかに関わらず、全てのブロックを計算

## SET CLEARUPDATESTATUS

Essbaseでデータ・ブロックがクリーン（計算完了）としてマークされる時期を指定（クリーン・ステータスは、高機能計算で使用される）
AFTER：ダーティ・ブロックを計算した後、ステータスをクリーンに変更する
ONLY：ステータスをクリーンに変更するが、計算はされない

# ビジネス・ルール内で別のルールを実行する場合


```
%Rule(name:="ビジネス・ルール名",application:="アプリケーション名",plantype:="キューブ名")
```

# FIXPARALLEL

・並行計算が可能！
・FIXPARALLEL対象が「1つまたは複数の疎ディメンションからの複数メンバーの場合」のみ並列処理となる
　（要は、計算対象ブロックが複数になる場合のみ）
　⇒それ以外だと効果がないため注意！
https://docs.oracle.com/cd/E83857_01/paas/analytics-cloud/tress/fixparallel-endfixparallel.html
【PBCS】ビジネス・ルールを使用した計算処理 - 機能説明

# ビジネス・ルールとは

PBCS内の「Calclation Maneger」を利用して、
GUIまたは独自スクリプトによるコーディングで計算処理を定義できる機能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/de7781af-dd42-ace2-8afd-04936974e7d2.png)


## 主な使用例
1. 積上処理：ディメンションの子メンバーの集計値を親メンバーに積み上げる処理
2. 配賦処理：部門や製品を横断して発生する費用を、配賦基準に従い配分する処理
3. データコピー処理：例）予算案→最終案への金額コピー

## 機能概要

1. GUI上での作成またはスクリプトによる作成が可能
2. （GUI作成の場合）コンポーネントを配置し詳細な条件を設定し、ルールを作成できる
3.  WebFormとの紐づけが可能 （フォームから金額入力→画面上でビジネスルールを起動することで即時計算が可能）


## 使用方法

【作成する場合】
EPM Cloud＞ナビゲーションメニュー＞作成および管理＞ルール　より
Calclation Managerを起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/1a459747-d9b5-791d-474d-35078cf9f22c.png)


（Calclation Manager）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/369d508d-99a0-dcdf-d4dd-8982a85d3dd6.png)

【使用する場合】
① EPM Cloud＞ルールより 起動したいルールを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/935ff7c3-7f88-2997-2d3c-5140018dbe79.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/84ba81ef-7d99-1170-2246-3e51c5befa18.png)

② ルールを紐づけたWebFormより起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137780/657255cd-8d37-3eb5-ed91-864a68bae142.png)

## スクリプトによるコーディングについて

上記にも記載した通り、ビジネス・ルールはGUIでの作成が可能
→ 但しGUI作成の場合、計算フォーマットに制限があることから、実際にはカスタマイズ性の高いスクリプトによる開発が一般的

→ 次項からはスクリプトによる開発を前提として、おもな計算処理を紹介します
#Slack でメンバー招待・承認の履歴を確認する

https://<ワークスペースのID>.slack.com/admin/invites

から可能

![image](https://user-images.githubusercontent.com/13635059/64825904-e827b480-d5f9-11e9-9c63-df134e02fc70.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[Nuxt.js] SPAモードで無理やりmetaタグを入れてSEO対策する裏技

NuxtのSPAモードで開発してるとき、
急にページ単位で違うOGP入れたくなったりした事ってありませんか？
私はありません。

が、業務上そういう必要に駆られてしまうことは稀にあります。
そういう場合はサーバーサイドレンダリングをやってくれるUniversalモードを使えばいいんですが、

とはいえSPAモードで開発してたものを後からUniversalモードに切り替えたりすると、
ブラウザ情報を取得して動かしてたものが、サーバーサイドに移ったことで動かなくなったりするので
検証したりロジック修正したりとかなり面倒で手間をかけされられます。

というわけで、**Nuxtを書き出すレンダラや配信するサーバに介入して無理やりHTMLにmetaタグをぶち込みます。**

※ この記事ではどうやってNuxtが書き出したHTMLを配信する前に捕まえるかについて書いています。 実際にNode.jsでHTMLを編集するにはどうしたらいいかについてはまた別途記事を書く予定です。

参考にした資料: 【[Nuxt(SPA)でもOGPしたい/want to render ogp with nuxt spa mode](https://speakerdeck.com/fruitriin/want-to-render-ogp-with-nuxt-spa-mode)】 @fruitriin 


## Nuxt自体をExpressモジュールとして使おう！
* [Nuxt.js をプログラムで使う](https://ja.nuxtjs.org/api/nuxt)

↑の公式リファレンスで触れられている通り、Nuxtはそれ自体を別のNode.jsプログラムに組み込んで使うことができる。
特にNuxtのページ自体を書き出す `Nuxt.render(req, res)` はリクエスト/レスポンス要素を引数に取るため、
Expressサーバであれば`Nuxt.render`をそのままモジュールとして使うことができる。

```js
const express = require('express');
const { Nuxt, Builder } = require('nuxt');
const config = require('./nuxt.config.js');

// Expressサーバを作成
const app = express();

// Nuxtを起動
const nuxt = new Nuxt(config);
nuxt.ready();

// ExpressにNuxtモジュールを使う
app.use('/*', nuxt.render);

app.listen(3000);
```

こんな感じ。
で、`nuxt.render`はページのレンダリングから配信まで一気にやってしまうため、
何とかしてレンダリング結果を捕まえて、そこでmetaタグを注入してやればいい、ということになる。

### 方法１. renderRouteを使う
* [renderRoute](https://ja.nuxtjs.org/api/nuxt-render-route)

HTML要素をレンダリングだけする（配信はしない）メソッド
`Nuxt.renderRoute(path, context)` というのがあるので、
meta要素の注入が必要な部分だけ`render`ではなく`renderRoute`でHTML文字列を書き出して、それに対してmeta埋め込み操作を行った後に配信する。

```js
// ExpressにNuxtモジュールを使う

// 特定のルートならOGP改ざん
app.get('/detail/*', (req, res) => {
  const result = nuxt.renderRoute('/', req);
  /** result.htmlの中にHTML文書が文字列が入っているのでmetaタグを入れてやる **/
  res.send(result.html);
});

// それ以外のルートを通常通り描画
app.use('/*', nuxt.render);
```
こんな感じ。

ただ問題は、飛んできたリクエストがHTMLかどうかを判断するルート分けをしておかなければならないこと。
例えば上記の例だと、`/detail/`以下のパスに対して全てHTMLを配信する形になるため、
`/detail/hoge.js`だったり`/detail/fuga.png`だったりするHTML以外のリクエストにもそのままHTMLを返しに行ってしまう。
厳密にルーティング書いてやれば行けなくもないがめんどくさいので、もっと簡単にできる方法を探したところ、あった。

### 方法２. hookで割り込み処理をかける

* [Nuxt Internals](https://ja.nuxtjs.org/api/internals)
* [Internals Renderer](https://ja.nuxtjs.org/api/internals-renderer)

requireで呼び出したNuxtインスタンスに対して、特定のライフサイクルイベントが発火した時に処理を捕まえて、処理を追加することができる`hook`という仕組みが存在する。

使い方はこんな感じ。

```js
// nuxtの配信準備ができたらコンソールログを吐く
nuxt.hook('ready', (nuxt) => {
  console.log('ready for nuxt');
  return;
});
```

要はイベントリスナに登録するみたいなものと考えてもらえばOK。
そのフックできるイベントの中に`render:route`という、
ルートがサーバレンダリングされる度に発火し、レンダリング結果を引数に取るイベントがあるので、これを使って割り込み処理を実装してやる。

```js
nuxt.hook('render:route', (url, result, context) => {
  // ルーティングの結果がhtmlでないなら早期return
  if (!render.html) return result;
  // 特定のルートならOGP改ざん
  if (/^\/detail\/.*/.test(url)) {
    /** result.htmlの中にHTML文書が文字列が入っているのでmetaタグを入れてやる **/
  }
  return result;
})

// ExpressにNuxtモジュールを使う
app.use('/*', nuxt.render);
```

こうしてやれば割とざっくりしたパス指定でも
NuxtのレンダラがHTMLを配信するか、それ以外のリソースなのかを判断してくれるので楽。

### まとめ

**最初からUniversalモードでSSR開発しよう!!!**
【Vue.js】Axiosで取得したAPIデータにリアルタイム検索機能をつけたい

APIは[こちら](https://jsonplaceholder.typicode.com/)を利用させていただいてます。

## イメージ
![リアルタイム検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246277/c7fbb59e-f58a-5fea-bd07-e4d38ee59b02.gif)

## ソースコード
```html:
<div id="app">
  <!-- keywordをv-modelで定義することで、inputの内容(=keyword)が変更されるたびにfilterUsers()が実行されます -->
  <input v-model="keyword" placeholder="Search...">
  <ul>
    <!-- keywordが更新されるたびにリストを書き換えたいので、算出プロパティ(computed)を使います。 -->
    <li v-for="user in filteredUsers">
      {{ user.username }}
    </li>
  </ul>
</div>

<script>
const app = new Vue({
    el: '#app',
    data: {
        users: null,
        keyword: '',
    },
    mounted: function() {
        this.getUsers();
    },
    computed: {
        filteredUsers: function () {
            return this.filterUsers();
        }
    },
    methods: {
　　　　　// API取得
        getUsers: function () {
            axios.get('https://jsonplaceholder.typicode.com/users')
            .then(res => {
                this.users = res.data
            })
            .catch(err => {
                console.log(err.statusText)
            });
        },
        // keywordに一致するuserを配列に格納し、それを返します
        filterUsers: function () {
            let filtered = [];
            for (let i in this.users) {
                let user = this.users[i];
                if (user.username.indexOf(this.keyword) !== -1) {
                    filtered.push(user);
                }
             }
            return filtered;
        }
    }
});
</script>
```

## デモ
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="nagisa-ito" data-slug-hash="jONxrMV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Vue + Axios + RealTime Search">
  <span>See the Pen <a href="https://codepen.io/nagisa-ito/pen/jONxrMV/">
  Vue + Axios + RealTime Search</a> by nagisa-ito (<a href="https://codepen.io/nagisa-ito">@nagisa-ito</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
CakePHPにVue.jsを導入したい

## はじめに
CakePHPのアプリケーションで、jQueryじゃちょっと動的ページを作成するのしんどいなってなったので、一部ページにVue.jsを導入することになりました。

CakePHP + Vue.jsの記事が全くないので(そりゃそうだ)備忘録がてらに残しておきます。

## インストール
### 公式サイト
https://jp.vuejs.org/v2/guide/installation.html

#### `<script>` 直接組み込み
[ダウンロードページ](https://jp.vuejs.org/v2/guide/installation.html#lt-script-gt-%E7%9B%B4%E6%8E%A5%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF)
<img width="503" alt="スクリーンショット 2019-09-11 18.10.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246277/4d9b4066-6a8a-f39c-16d7-c84baf233913.png">
ボタンをクリックすると、`vue.js`というファイルがダウンロードされます。
CakePHPプロジェクトに移動し、`app/webroot/js`の下にコピーすれば完了です。

```:Vueを使いたいファイル.ctp
<?php
$this->Html->script('vue', ['inline' => false]);
```
としてあげればVueが使えるようになります。

#### CDN (プロトタイピングや学習を目的とする場合におすすめ)

```:Vueを使いたいファイル.ctp
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
または
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
(バージョンは公式サイト確認して都度変えてください)
```
と記述すればいいです。いちばんかんたん

#### NPM (大規模プロジェクトで利用する場合におすすめ)
```:ターミナル
$ cd CakePHPプロジェクトのパス
$ cd app/webroot
$ npm install --save vue
```
とすると、webroot直下にnode_modulesというフォルダが生成されています。
`node_modules/vue/dist/`の中にvue.jsファイルがあります。

ちなみに
- `vue.js`　→開発用
- `vue.min.js` →本番用
となっているので、使い分けてください。

```:Vueを使いたいファイル.ctp
<?php
$this->Html->script('../node_modules/vue/dist/vue.js', ['inline' => false]);
```
とすればOKです。　この方法と同じようにAxiosもインストールする事ができます！
CoreBluetoothでCharacteristicを複数検索したい時

## 状況
- 一連のCentral Managerの立ち上げ後、`discoverServices(_:)`で指定したService UUIDを持つPeripheralが見つかった

- **Characteristicを複数持つPeripheralが存在する**ためCharacteristic検索を複数回行いたい
- 一度に`discoverCharacteristics(_ characteristicUUIDs: [CBUUID]?, 
                         for service: CBService)`の配列にCharacteristicsを入れて検索するのではなく**個別で複数回発火したい**

## 解決法
**基本的に複数回検索するのはベストプラクティスではない**

検索するときは一度の検索で全てのcharacteristicsをまとめて検索する

```swift
// 正しい方法 
peripheral.discoverServices([fooCBUUID], [barCBUUID])

// これはダメ
peripheral.discoverServices([fooCBUUID])
peripheral.discoverServices([barCBUUID])
```

また、複数回`discoverServices(_:)`を呼んだ場合、それまでに検索したcharacteristicを保持したまま**それを含めて検索する**ので気をつけてください
(これで[困っている人たち](https://github.com/noble/noble/pull/747)もいらっしゃる)


## 参考サイト
https://forums.developer.apple.com/thread/14871
https://www.raywenderlich.com/231-core-bluetooth-tutorial-for-ios-heart-rate-monitor
rspecでCarrierWaveのファイル作成をスキップすると更新時には必須チェックでエラーになる

carrierwaveを使用している際、rspecでuploaderをマウントしているモデルを作成するたびにファイルの書き込みが行われるので、rspecが非常に遅くなります。
なので、以下のようにファイルを保存しないようにstore!メソッドをstubにしています。

```ruby
allow_any_instance_of(CarrierWave::Uploader::Base).to receive(:store!)
allow_any_instance_of(CarrierWave::Uploader::Base).to receive(:process!)
```

しかし、`presence: true`を設定している場合、更新時にvalidationが失敗してしまいます。

どうやら最終的にFileの存在を確認している模様([ソース](https://github.com/carrierwaveuploader/carrierwave/blob/0e8742be085410f1e08ef9f42c717267100d92e9/lib/carrierwave/sanitized_file.rb#L143))

```ruby
def empty?
  @file.nil? || self.size.nil? || (self.size.zero? && ! self.exists?)
end
def exists?
  self.path.present? && File.exist?(self.path)
end
```

作成のテスト時は、tmpfileをみに行っているので問題なかったみたいですね。。

更新のテストをする場合はモデル作成前に

```ruby
allow_any_instance_of(CarrierWave::Uploader::Base).to receive(:store!).and_call_original
allow_any_instance_of(CarrierWave::Uploader::Base).to receive(:process!).and_call_original
```

で元に戻すといいだろうか。。。
先に教えて欲しかった Git の便利機能（言うて1個だけ）

# 先に教えて欲しかった Git の便利機能（言うて1個だけ）

## はじめに

こないだ Git (Windows版) を導入しました。
きっかけは、Twitter で、バージョン管理やバックアップを zip でやってるよって Tweet した所から流れで……。

## Git 導入

インターネットの情報だと、プロンプトを開いて CUI で作業するイメージでしたが、VSCode からだいたい出来ました。

1. Git (Windows版) のダウンロード

Git for Windows から、インストーラを Download しました。
<https://gitforwindows.org/>

1. インストール

インストール時に色々設定を聞かれますが、残念ながらどのように設定したか忘れてしましました。
ただ、デフォルトエディタは、VSCode にした記憶があります。

1. 環境変数の設定

「HOME」という名前の環境変数を作るべし、との事だったので、テキトーな場所に「Git」フォルダを作って指定しました。

1. VSCode 拡張機能インストール

「Git History」だけあればイイよ……って聞いたので、それをインストールしました。

1. VSCodeでリポジトリ指定

VSCode の「エクスプローラ」で「フォルダ―を開く」でバージョン管理したいフォルダを開きます。
そして、「ソース管理」からそのフォルダを「リポジトリ」として指定しました。

![git_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373498/c94395f4-519a-0250-6a01-a291d7588b3d.png)


1. ユーザー名とメールアドレスを設定

上記だけでは、VSCode のコンソールにエラーが出てきました。
というわけで、Git にユーザー名とメールアドレスを登録しました。
コマンドは、VSCode にヘルプが出て来たと思います。

導入としてやった作業は、以上です。

## Git のこれが便利だったよ

- VSCodeで、Git にコミットした最新バージョンからの変更点が表示されました。

![git_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373498/e5fc86a4-42a7-4c48-3704-a8d8a6d2cbbc.png)

## そして……

でも、バックアップはやっぱり zip でやってます。
バージョン管理とバックアップは別モノだよね？

## おわりに

こういうちょっとした便利機能って、あんまり教えてもらえない印象があります。
なので、コレはメモしておこうと思い、書きました。

それでは～。
Windows Server 2019 で .Net 3.5 Framework をインストールする

# はじめに
Windows Server 2019で、今更 Net 3.5 Framework をインストールしなければいけなくなったが、Windows Server 2019 で .Net 3.5 Framework をインストールしようとすると以下のようなエラーが出る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/5126829c-e608-b648-d1da-b049f1dc140d.png)

タスクの詳細みても、以下のログだけでどこが詳細やねんってなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/59be81ef-a797-3784-1733-11cd755164b8.png)


そこで、Windwos Server 2019 のメディアを入れて、以下の画面で<font color="Red">**「代替ソースパスの指定」**</font>をクリックしして「d:\D:\sources\sxs」を入力して実行する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/8938d8e1-f52d-8b1b-8d36-cacfde4c19da.png)


そうしたら無事に、インストールできた
Create React Appで開発したアプリをESLintでチェックして、チェック結果をJenkinsで可視化する

# 概要
Create React Appでは`npm start`することで、自動的にeslintが実行され、コンソールに結果が出力されます。

このeslint部分だけをコマンドで実行して、実行結果をJenkinsで可視化します。

具体的には

1. eslintをnpmで実行して、CheckStyle形式で結果を出力し
2. それをJenkinsのWarnings Next Generation プラグインに読み込ませていきます。

# まずはローカルで試してみましょう
### eslintをローカルで実行してみる
以下のコマンドを実行しましょう。

```terminal
npx eslint ./src/**/*.js ./src/**/*.jsx
```

すると、結果がターミナルに出力されます。

今回はJenkinsで実行し、チェック結果を可視化したいので、チェックスタイル形式（xml）で結果を出力します。出力結果はファイルに出力しましょう。

```terminal
npx eslint ./src/**/*.js ./src/**/*.jsx -f checkstyle > ./eslint_check_result.xml
```

このファイルをJenkinsのプラグインに読み込ませれば良さそうですね。

# Jenkins上で実行してみましょう
ローカルで良い感じに動いたので、いよいよJenkins上で実行してみましょう。

### Warnings Next Generation Pluginをインストール
従来のCheckStyleプラグインは非推奨となっています。

ですので、代わりに「Warnings Next Generation Plugin」を利用しましょう。

Jenkinsのプラグイン追加画面で「Warnings Next Generation」を検索し、インストールします。

### ジョブの設定
設定 - ビルド - シェルの実行　に以下を設定します。

```terminal
npm install
npx eslint ./src/**/*.js ./src/**/*.jsx -f checkstyle > ./eslint_check_result.xml
```
<img width="934" alt="スクリーンショット 2019-09-13 5.58.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455418/b6ae94dd-d053-65b7-a309-c3be8de05951.png">


あとは、このxmlファイルをWarnings Next Generationプラグインに読み込ませます。
<img width="932" alt="スクリーンショット 2019-09-13 5.59.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455418/ee0224dd-40e2-bd20-c5d4-17475a98ee69.png">

すると、良い感じに可視化されます。
<img width="914" alt="スクリーンショット 2019-09-13 5.59.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455418/0248043c-4318-bc01-d62b-94e1069d24b4.png">
Vagrant学習メモ


## Vagrantとは

こちらの方の記事が参考になると思います。

[【決定版】仮想環境ってなに？Vagrantってなんなの？に答える!](https://qiita.com/kenju/items/00050972fdf74e37e71f)

## Vagrantコマンド（ファイル作成から仮想マシン起動、停止まで）

```
# ホームディレクトリに移動
$ cd

# 今後複数の仮想マシンを作ることを想定して、それらをまとめるフォルダ（MyVagrant）を作る
$ mkdir MyVagrant

# MyVagrantに移動する
$ cd MyVagrant

# 仮想マシンを作るフォルダを作る（MyCentOS）
$ mkdir MyCentOS

# MyCentOSに移動する
$ cd MyCentOS

# 仮想マシン設定用のVagrantfileを作る
$ vagrant init bento/centos-6.8

# Vagrantfileを編集して仮想マシンのIPアドレスを192.168.33.10にする
$ sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network "private_network", ip: "192.168.33.10"/' Vagrantfile

# 仮想マシンを起動する（少し時間かかります）
$ vagrant up

# 仮想マシンの状態を確認する
$ vagrant status

# 立ち上げたサーバーにログインする
$ vagrant ssh

# OSを最新状態にアップデート（時間かかります）
$ sudo yum -y update

# スクリプトを入手するためのgitをインストール
$ sudo yum -y install git

# gitを使ってアプリケーション設定用のスクリプトをダウンロード
$ git clone https://github.com/dotinstallres/centos6.git

# centos6フォルダができるのでそちらに移動
$ cd centos6

# スクリプトを実行（時間かかります）
$ ./run.sh

# もろもろの設定を反映
$ exec $SHELL -l

# 仮想マシン停止
$ vagrant suspend 
```

##参考資料
[ドットインストール　ローカル環境の構築（MacOS編）](https://dotinstall.com/lessons/basic_localdev_mac_v2)
PowerShellでSharePointOnlineのドキュメントからファイルをダウンロードする


```spodownload.ps1
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null

$pass = convertto-securestring "password" -AsPlainText -Force
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials("userAccount", $pass)
$cookieValue = $credentials.GetAuthenticationCookie("https://xxxxxxx.sharepoint.com/sites/site/")

$cookieValue = $cookieValue.Replace("SPOIDCRL=","")
$cookie = New-Object System.Net.Cookie
$cookie.Name = "SPOIDCRL"
$cookie.Value = $cookieValue

$cookieContainer = New-Object System.net.CookieContainer
$cookieContainer.Add("https://xxxxxxx.sharepoint.com/sites/site/",$cookie)

$request = [System.Net.WebRequest]::Create("https://xxxxxxx.sharepoint.com/sites/site/Shared%20Documents/test.xlsx")
$request.CookieContainer = $cookieContainer
$response = $request.GetResponse()
$responseStream = $response.GetResponseStream()

$outputFile = [System.IO.File]::Create("C:\work\test.xlsx")
$Buffer = New-Object Byte[] 1024
Do {
    $BytesRead = $responseStream.Read($Buffer, 0, $Buffer.Length)
    $outputFile.Write($Buffer, 0, $BytesRead)
} While ($BytesRead -gt 0)

$responseStream.Close()
$responseStream.Dispose()

$outputFile.Flush()
$outputFile.Close()
$outputFile.Dispose()
```

## 参考
https://teratail.com/questions/79342
SharePointOnlineへPowershellで接続

## モジュールがあるか確認

```
Get-Module -Name Microsoft.Online.SharePoint.PowerShell -ListAvailable | Select Name,Version
```

## なければインストール

```
Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Force
```

## Office365管理センターのURLへ接続

```
Connect-SPOService -Url https://test-admin.sharepoint.com -Credential yuta@test.onmicrosoft.com
```

## 使用可能コマンドレット一覧

```
Get-Command -Module Microsoft.Online.SharePoint.PowerShell
```
Proxy使用例


JavaScriptのProxyを使って、状態の変更を通知できるゲッターとセッターを作ってみた。
``state.key = value``のようにセットして、``state.key``でゲットします。

```js
state = new Proxy({}, {
    get(target, key){
        return JSON.parse(target[key]);
    },
    set(target, key, value){
        target[key] = JSON.stringify(value);
        dispatchEvent(new CustomEvent(`state.${key}`));
    },
});
```
- 変更時にイベントが発生することで通知します。イベント名は``state.キー名``、発生源は``window``
- 内部状態をJSONで持っているので、変更を確実に検知できます
- stateの全キーはfor-inループで取り出せます
「目が悪いから前の方!!」に応える、席替えプログラムを作ってPyPIに公開した。

2019/09/13追記 パイプラインに対応
[#Pipeline](#pipeline)

---

# sekigae
というパッケージ名で席替えするPythonプログラムを作りました。
https://github.com/kamuiroeru/sekigae

特徴としては

- CUI
- CSV読み書き
- **[任意の位置に任意の番号を指定可能](#任意の場所に誰かを固定)**
- 他のUNIXコマンドと連携可能（ `|` が使える）

があって、3つめは結構使える機能だと思います。

# Install
python3系を導入済みの方は

```shell
pip install sekigae
```

で使えます。
※（globalなコマンドとして `sekigae`）がインストールされるので注意

# 使い方

## シンプルな使い方
`13` 人を `5` 列で作成

```shell
sekigae 13 5
```
```text:output
          FRONT           
--------------------------
| 10 |  7 |  3 |  5 |  2 |
--------------------------
|  4 | 11 | 12 |  1 |  6 |
--------------------------
|  8 | 13 |  9 |
```

## 上のラベルを変更
`黒板` に変更

```shell
sekigae 13 5 -t 黒板
```
```text:output
            黒板            
--------------------------
|  2 |  9 |  5 | 11 |  1 |
--------------------------
| 10 |  7 | 12 |  8 |  6 |
--------------------------
| 13 |  3 |  4 |
```

## CSVに書き出し
`test.csv` に書き出す

```shell
sekigae 13 5 -o test.csv
```
```text:output
          FRONT           
--------------------------
| 12 | 11 |  7 |  5 |  3 |
--------------------------
|  9 |  1 |  4 |  6 | 10 |
--------------------------
| 13 |  2 |  8 |
csv wrote
```
```csv:test.csv
12,11,7,5,3
9,1,4,6,10
13,2,8
```

## CSVを読み込む
`test.csv` を読み込む
※人数と列数の指定は必須ですが、無視されます。

```csv:test.csv
12,11,7,5,3
9,1,4,6,10
13,2,8
```
```shell
sekigae 45 6 --csv test.csv
```
```text:output
          FRONT           
--------------------------
| 12 | 11 |  7 |  5 |  3 |
--------------------------
|  9 |  1 |  4 |  6 | 10 |
--------------------------
| 13 |  2 |  8 |
```

## 任意の場所に誰かを固定
「7番の人は目が悪いから一番前！！」
「9番の人は前に行きたいって！！」
という要望に応えます。

- 7番を 1行3列目に固定
- 9番を 2行2列目に固定

という指定で作成

```shell
sekigae 13 5 -s 1:3:7,2:2:9
```
```text:output
          FRONT           
--------------------------
|  6 |  8 |  7 |  5 | 11 |
--------------------------
|  1 |  9 |  2 |  3 | 13 |
--------------------------
| 10 | 12 |  4 |

          FRONT           
--------------------------
|  1 |  2 |  7 | 12 | 13 |
--------------------------
| 11 |  9 |  5 | 10 |  3 |
--------------------------
|  4 |  6 |  8 |

          FRONT           
--------------------------
| 12 | 13 |  7 |  1 |  5 |
--------------------------
|  4 |  9 |  2 |  8 |  6 |
--------------------------
| 11 |  3 | 10 |
```
常に 
**7番は1行3列目**
**9番は2行2列目**

### Pipeline

#### Pipeline input

`cat` コマンドとかのパイプ入力に対応

```text:out.csv
10,12,3,5,6
11,4,9,1,13
7,8,2
```

```shell:shell
cat out.csv | sekigae
```

```text:output
          FRONT
--------------------------
| 10 | 12 |  3 |  5 |  6 |
--------------------------
| 11 |  4 |  9 |  1 | 13 |
--------------------------
|  7 |  8 |  2 |
```

#### Pipeline output

`-f` で CSV形式で表示するようにした。
awkとか色々組み合わせられる。

```shell:shell
sekigae 13 5 -f | awk '{ if (gsub(/,/, " ")) print }'
```

```text:output
8 5 7 10 12
11 6 3 4 1
13 2 9
```

# P.S.
初めてPyPIに登録したのですが、自分の作った機能が `pip install` で使えるってのは良いもんですね〜
React Native + Expo アプリをPublish(公開)する：テスト配布する

この記事は、「[【連載】初めてのReact Native + Expo開発環境構築入門](https://qiita.com/hitotch/items/5142fff638c7805d84d5)」の子記事です。環境などの条件は、親記事をご覧ください。

---

　Expoで作ったアプリは、とても簡単にPublishしたりDeployできます。
　この記事では、[前回](https://qiita.com/hitotch/items/f563ec8a60f05bb7edd8)までで作成途中のHello Worldアプリ（請求書アプリモックアップ）をPublishします。

# PublishとDeployの違い

　Expoには、PublishとDeployがあります。PublishもDeployも、自分以外の人がアプリを実行できるようにする、という意味では同じです。大きな違いは、Publish版の実行はExpo clientが必要なのに対し、Deploy版は完全に独立したネイティブアプリであることです。

Publish：開発者以外の人が、Expo clientでアプリを使えるようにする。
Deploy：開発者以外の人が、Expo clientなしでアプリを使えるようにする。

|            |  Publish  |  Deploy  |
| ----       | ---- | ---- |
| 実行にExpo Client |  必要 | 不要 |
| オフライン動作 | NG | OK |
| テスト用配布 | 簡単：URLかQRコード | 面倒：.apk/.ipaファイル |
| 一般公開 | NG | OK |

　実用時点では必ずネイティブアプリ化しますが、Google PlayやApp Storeに一般公開する必要があるかどうかは、アプリの用途によります。社内でのみ使うアプリなら、ITチームが手元でインストールして配布する運用もありでしょう。
　テスト段階では殆どの場合PublishしてExpo Client上でアプリを使うのがよいでしょう。ただ、オフライン（インターネット接続がない状態）ではExpo Clientが動作しないので、電波のないところでの利用も想定したアプリならDeployしてテストする必要があります。

# Publishの準備 - Expoアカウントを作成

　ExpoアプリをPublishするには、Expoアカウントが必要です。連載の最初の記事「[Expoのアカウントを作ってReact Nativeの開発環境を整える](https://qiita.com/hitotch/items/ea4de1ed408a9ca14fce)」を参考に、アカウントを準備している状態を作ります。

# Publishを実施

　Publishは、UIから実施します。CLIからでも実施できます。詳しくは[公式ドキュメント](https://docs.expo.io/versions/v34.0.0/workflow/publishing/)をどうぞ。

　Visual Studio Codeでプロジェクトを開き、PowerShellからアプリを実行します。

```
expo start
```

　Expo Dev Toolsが表示されたら、左ペインの**Publish or republish project...**をクリック。**NAME**と**URL SLUG**を入力(プロジェクト作成時に入力した情報がすでに入ってるのでそのままでもOK)して、**Publish project**をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/a6cb399d-2711-7ffa-01c3-3975b2dc1f85.png)

　ここからはVisual Studio CodeのPowerShell側で操作します。ユーザーアカウントが必要だと言われるので、**Log in with an existing Expo account**（すでに持ってるアカウントを使う）を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/95663390-bfaa-34f9-2a0b-d38b2623e0fd.png)

　その後ユーザー名とパスワードを入力してログインが成功すると、アプリのビルドがスタートします。ビルドには、いつも以上に時間がかかります。
　うまくいくと、以下のようにSuccessメッセージが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/bdd1711e-1ae5-bf85-77f0-2da5d5fa2b3e.png)

　また、ExpoのWebにログインすると、Publishしたプロジェクトが**Projects**タブに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/6189064a-0b10-cfd3-da32-a8a900e70ba8.png)

　SuccessメッセージにあるURLを開くと、（ログインしていなくても）アプリを実行するためのQRコードが表示されます。これはログインしたときに表示されるプロジェクトのリンク先と同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/6e989690-7858-87ee-eca4-c3f7ddd62f8a.png)

　これで、このプロジェクトのURLを知ってる人は誰でも手元のAndroidかiPhoneのExpo Clientでアプリを実行できるようになりました！
【Swift】 alert表示のテンプレート

タイトル通りです。
入力チェック時のエラー表示や、入力完了時のメッセージ表示の際の、「とりあえずアラートダイアログでメッセージを表示したい(ダイアログのボタン押下による処理は無くてよい)」時に便利に使いまわせるメソッド。

### 開発環境
端末:MacBook Pro/MacOS 10.14.5(Mojave)
Xcode:10.2.1
Swift:5

### 実装内容
#### ソースサンプル

```swift:sample.swift
import UIKit

class secondViewController: UIViewController {
    var alertController: UIAlertController!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func alert(title:String, message:String) {
        alertController = UIAlertController(title: title,
                                   message: message,
                                   preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK",
                                       style: .default,
                                       handler: nil))
        present(alertController, animated: true)
    }

    @IBAction func tapButton(_ sender: Any) {
        alert(title: "サンプル",
              message: "メッセージ表示")
    }
}
```
#### 画面表示
![Screen Shot 2019-09-13 at 2.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/aa451def-8f37-9cb5-7e0f-1da1af666827.png)
dockerで簡単にNestJSの環境を作る

# Dockerで簡単にNestJSの環境構築をする

###### Table of Contents

1. NestJSとは
2. dockerで何も考えずに
3. serverを立ち上げる

## 1.NestJSとは

![NestJS - A progressive Node js web framework.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/90fc6fb1-ace3-664e-8d2a-012c3ffc69cd.png)

_[NestJS](https://nestjs.com/)_とは、
効率的で信頼性ができスケールが可能なサーバー側アプリケーションを構築するための進歩的なNode.jsフレームワークである。
とある感じでExpress fastifyとおんなじ感じに認識でしたが、個人的に https://docs.nestjs.com/#philosophy にある一文が結構好きな一文でとりあえず遊ぼうかと思いました。

## 2.dockerで何も考えずに

### 使うもの

- docker
- nest/cli ([docker-image](https://hub.docker.com/r/nestjs/cli)があるので利用します)

### 完成後のディレクトリ構成

```
project-path
    |- docker-compose.yml
    |- Dockerfile
    |- ...nest_modules
```

#### 2-1. docker-compose.yml と Dockerfileの作成

_Dockerfileの中身_

```Dockerfile
FROM nestjs/cli
WORKDIR /myapp
```

_docker-compose.ymlファイルの作成_

```docker-compose.yml
version: "3.7"
services:
  api:
    build: .
    tty: true
    ports:
      - "3000:3000"
    volumes:
      - type: bind
        source: .
        target: /myapp
```

## 3. nestのプロジェクトを作成する


流れとしては、docker containerに入りcliを利用しプロジェクトを作成。
依存しているパッケージをインストールする感じです。

_docker containerに入る_

```
$ docker exec -it {{ CONTAINER NAME }} sh
$ pwd
/myapp
```

nest projectを作成する

```
$ nest new .

```
上記でプロジェクトの作成はできるのですが、serverを立ち上げるとエラー吐くのでかるく修正。

```(旧)package.json
{
  "name": ".",
  "version": "0.0.1",
  "description": "",
  ...
}
```

上記のnameを好きな名前に書き換える。

```package.json
{
  "name": "sample", # ここを書き換える
  "version": "0.0.1",
  "description": "",
  ...
}
```

依存packageをインストール。

```terminal
$ npm install
```

で準備完了。

## 4. serverを立ち上げる

流れとしては、docker containerに入り dev serverを立ち上げる感じにします。

_docker containerに入る_

```
$ docker exec -it {{ CONTAINER NAME }} sh
$ npm run start
```

であとは、ブラウザから http://localhost:3000 で質素な画面が表示されます。

![localhost 3000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/b1356d6d-f956-bc1e-7f18-1d36d9de5dcf.png)

一応こんな感じ

https://github.com/Ntakuya/nestjs-practice/tree/environment/nest-cli
ansible-galaxyコマンドでインストールしたroleをアップデートしたい

# 何がやりたいか
ansible-galaxyでインストールしたroleの元のリポジトリに変更があったときに、実行側でも追従したい。

```
$ ansible-galaxy install -r requirements.yml
```
これだと実行しても変更はないよって言われてしまう。updateのコマンドはないので一度removeしてからinstallし直すことで更新できるがめんどくさい。

そんなときは

```
$ ansible-galaxy install -r requirements.yml --force
```
これでインストールし直してくれて、更新される。


# ちゃんとしよう
手っ取り早いアップデートの方法を紹介したが、プロダクションで使うならちゃんとブランチ名とかコミットハッシュでバージョン管理をしよう。
Ansible GalaxyでGithub以外のリポジトリからRoleをインストールする

# 背景
AnsibleでRoleを再利用するためにはAnsible GalaxyにホスティングされたRoleをインストールする方法がありますが、自分で作成したリポジトリを直接参照してインストールすることもできます。
しかし、Githubとそれ以外の場合で使用方法に差があったり、Roleのアップデートの方法がめんどくさかったりと、開発中に困ったことがあったので、まとめました。

# Roleのインストール

## Galaxy serverがホストするRoleを使用する場合
```
ansible-galaxy install Role名
```
## Githubのリポジトリを使用する場合
```
ansible-galaxy install Repository名
```
デフォルトでは ~/.ansible/roles/ 以下にインストールされますが、-pオプションを利用することで配置先を指定することができます。
コミットハッシュとブランチ名も指定可能です。

```
ansible-galaxy install -p path Repository名
```

## Github以外のリポジトリを使用する場合
```
ansible-galaxy install Git+Repository名
```
Githubの場合と同様に-pが利用できます。

## Roleの一括管理
requirements.ymlを書くことでインストールするRoleを一括管理することができます。

```:requirements.yml
# from galaxy
- src: yatesr.timezone

# from GitHub
- src: https://github.com/bennojoy/nginx

# from GitHub, overriding the name and specifying a specific tag
- src: https://github.com/bennojoy/nginx
  version: master
  name: nginx_role

# from a webserver, where the role is packaged in a tar.gz
- src: https://some.webserver.example.com/files/master.tar.gz
  name: http-role

# from Bitbucket
- src: git+http://bitbucket.org/willthames/git-ansible-galaxy
  version: v1.4

# from Bitbucket, alternative syntax and caveats
- src: http://bitbucket.org/willthames/hg-ansible-galaxy
  scm: hg

# from GitLab or other git-based scm
- src: git@gitlab.company.com:mygroup/ansible-base.git
  scm: git
  version: "0.1"  # quoted, so YAML doesn't parse this as a floating-point value
```
それぞれのattributeについて解説します

- src: roleのソースであり、必至の項目です。書き方はCLIからインストールするときと同様です。
- scm: Gitlabの場合はgit、Bitbucketの場合はhgとしてください、GithubとGlaxyから利用する場合は書かないでください。
- version: ダウンロードするroleのバージョンを指定します。コミットハッシュ、ブランチ名、roleのtagを指定できます。
- name: roleを保存したい名前を記述できます。インストール後は指定した名前で使用することができます。

requirements.ymlを書いたら、以下のコマンドでインストールできます。

```
ansible-galaxy install -r requirements.yml
```

# あとがき
roleをインストールする方法として、Ansible Galaxyを利用する方法とGitリポジトリをを利用する方法を挙げました。よく使うroleや大きいroleは別のリポジトリにしてしまいましょう！
Pythonで作る 黒い画面上で動くじゃんけんプログラム 

#黒い画面(コマンドプロンプト)で動くじゃんけんゲーム
Python 学習サイトで載っていた参考コードが
手の種類ごとに勝敗を判定するコードだったので
判定は一回で済むように自分で考えてみた！

しかしもっとスマートな方法があるのね…

名案おもたんやけど＼(^o^)／


#自分の書いたコード

```python:
import random

win = 0
draw = 0
lose = 0
times = 1
i = 1
hands = ["グー","チョキ","パー"]
class Judgement:
    def __init__(self):
        self.win = 0
        self.draw = 0
        self.lose = 0
    def judge(self, you):
        if you == 0:
            print("あなたの勝ち！")
            self.win += 1
        elif you == 2:
            print("あなたの負け＞＜")
            self.lose += 1
        elif you == 1:
            print("あいこ～")
            self.draw += 1  

result = Judgement()

while i == 1:
    print("ジャンケン" + str(times) + "回目")
    print("戦績 WIN:" + str(result.win) + "回 DRAW:" + str(result.draw) + "回 LOSE:" + str(result.lose))
    print("> 0:グー、1:チョキ、2:パー")

    com = random.randint(0,2)   #RANDOMモジュールのrandint関数()内は 始まり,終わり
    
    you = int(input("あなたの手は？"))
    if you > 2 or you < 0:
        print("無効な手です！0~2の数字で入力してください！")
    else:
        if com == 0:
            you += 1
            if you > 2:
                you = 0
        
        elif com == 2:
            you -= 1
            if you < 0:
                you = 2
            
    
    print("COMは" + hands[com])

    result.judge(you)
    times += 1

    i = int(input("もう一度やる？ １:やる！ 0：もうええわ"))
```

#解説的な
せっかく習ったので
判定する部分はClassにまとめました。

じゃんけんの種類

グー=0
チョキ=1
パー=2

として

you = 自分の手
com = COMの手

に入る前提でいきます。


**判定式の模範回答は**

```python:
result = (you - com + 3) % 3

if result == 2:
    #勝ちの処理
elif result == 1:
    #負けの処理
else:
    #あいこの処理
```
らしいです
ｼﾗﾝｹﾄﾞ

私はそういうの全然しらないオッサンなので

**判定式が 0で勝ち 2で負け 1であいこ**
で作りました！
だって！
サンプルの判定式の真ん中(チョキ)がこれだったんだもん！！／(^o^)＼

とにかく…
これが成り立つよう、Comの手によって Youの手を変化させました。

|COM\YOU     |勝てる手|差分|負ける手|差分|あいこの手|差分|
|:-----------:|:--:|:--:|:--:|:--:|:--:|:--:|
|グー         | 2  |  -2|1   |+1  |0   |+1  |
|チョキ       | 0  |   0|2   |0   |1   |0   |
|パー         | 1  |  -1|0   |+2  |2   |-1  |

となりました。
自分で書いてて壊滅的にわかりにくいな…

COMがチョキの時は当然基準に考えたので触る必要はありませんｗ

■グーの時(you == 0)のとき
勝つとき(パー)以外は  you += 1でいけそうです
それでいくと パーの時 you == 3なので
you を強制的に0にしましょう
0<= you <=2
に収めないとですからね！

■パーの時(you == 2)のとき
負けるとき(グー)以外は  you -= 1でいけそうです
それでいくと グーの時 you == -1なので
you を強制的に2にしましょう
範囲外に出たら巻き戻るような巻き戻すような感じで

とにかくこれでうまくいきましたｗ


#ほんとうはもっとUI的なこともしたかったが・・・
0とか1とかで入力するのって直感的じゃないから
ほんとうはドロップダウンリストとかで選択させたかったけど…
本来の目的はココじゃない！なのでこれで妥協しました…

模範解答みたらもっと頑張ってたけど！！ｗ

とりあえずこれで～


備忘録でした！
git pullで初めてのコンフリクト対応をした話　[error: Your local changes to the following files would be overwritten by merge:]

## 対応

### エラーの発生

```terminal
[root@www httpdocs]# git pull
remote: Enumerating objects: 21, done.
remote: Counting objects: 100% (21/21), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 12 (delta 8), reused 11 (delta 8), pack-reused 0
Unpacking objects: 100% (12/12), done.
From github.com:'リポジトリ名'
   e51a2493..2de855ba  master     -> origin/master
   2dbb9b53..17b9ca94  design     -> origin/design
error: Your local changes to the following files would be overwritten by merge:
	フォルダ名/ファイル名
Please commit your changes or stash them before you merge.
Aborting

```
git pullをした時にまさかのコンフリクト。
初めての共同開発の環境だったので、いつかは起こるだろうと思っていたけれども
まさか初日に起こるとわ・・・

### ファイルの退避

```terminal
$ git stash save conflict
aved working directory and index state On master: conflict
HEAD is now at d0ca05b9 Merge branch 'master' of github.com:'リポジトリ名'
```

conflictの所は自分がわかる様な名称を入れるとのことだったので、そのままコンフリクトと記入。（save 以降は省略できるみたいでgit stashでも良いとか・・・）

また、この退避って現状のファイルを退避させているのか、更新内容を退避させているのかどこにも書いてなかったので調べた・・・、結構な時間調べた。
けれども、帰りのバスの中で「普通に考えれば、現状のファイルを退避する訳ないなー。」と自己解決。

### stashの確認
```terminal
$ git stash list
stash@{0}: On master: conflict
```
待避出来たのかリスト表示させて確認、問題なくconflictがある。

```terminal
$ git pull
```
一旦、git　pullをして最新ソースを取得をして。

```terminal
$ git stash pop
```

変更ファイルを復帰させて無事完了。



## 参考サイト様
<a href=https://qiita.com/izcomaco/items/78030cb1bb269234cf6f>@izcomaco様のとりあえずのGitメモ</a>
dbディレクトリにあるcsvファイルを全部あれこれしてくれるseeds.rb

## ※注意書き
・Sequel proからcsvファイルをdbディレクトリへエクスポートする前提です。
・ファイル名もそのままな（テーブル名_view.csvになっている）想定です。
・同レコードは重複しません。
・バリデーション無視するので中間テーブル等もそのまま入ります。
<hr>
## seeds.rb

```ruby:seeds.rb
require 'csv'

def seed(csv) ##csvファイルを投げると自動でseedを入れてくれるメソッド
  tablename = File.basename(csv, ".*").slice(0..-6) ##ファイルのパスをテーブル名に変換
  classname = tablename.classify ##テーブル名をクラス名に変換。
  CSV.foreach(csv, headers: true) do |row| ##csvファイルからレコードを取り出していく。
    attributes = row.to_hash
    attributes[attributes.key('NULL').to_sym] = nil if attributes.key('NULL') ## 文字列NULLをnilに変換
    record = Object.const_get(classname).where(attributes).first_or_initialize ##レコードが重複しないようにする。
    record.save!(validate: false) if record.new_record? ## 外部キーなどのバリデーションを無視して保存させる。
  end
end

Dir.glob("db/*.csv").each do |csv| ## dbディレクトリの全csvファイルを取り込む
 seed(csv)
end

```

## BULK INSERT対応版（※要activerecord-import）

◆BULK INSERTって？
→ようするに大量のレコードを取り扱う際に使うとめっちゃ速くなる方法
参考
https://qiita.com/xhnagata/items/79184ded56158ea1b97a

```ruby:seeds.rb
require 'csv'

def seed(csv) ##csvファイルを投げると自動でseedを入れてくれるメソッド
  classname = File.basename(csv, ".*").slice(0..-6).classify ##パス名をクラス名に変換。
  records = [] ## BULK INSERTをするための配列
  CSV.foreach(csv, headers: true) do |row| ##csvファイルからレコードを取り出していく。
    records << Object.const_get(classname).new(row.to_hash) ## Object.const_get(classname)はクラス名を変数で指定する方法
  end
   ## ↓BULK INSERTでテーブルに登録（バリデーション無視、同レコードは重複させない）
  Object.const_get(classname).import records, on_duplicate_key_update: records[0].attributes.keys, validate: false
end

Dir.glob("db/*.csv").each do |csv| ## dbディレクトリの全csvファイルを取り込む
 seed(csv)
end

```
[macOS]Sourcetree+rbenvでpre-commitが動かない問題を解決する

# 概要
- CUIでのgit commitでは問題なくpre-commitが機能しているのに、みんな大好きでお馴染みSourcetreeではエラーになる問題を解決します
- こんなこと今までなかったのですが、なぜか発生したのです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33648/5b234984-9f53-4f2f-cf1a-e1cfc133fba3.png)

# 環境
- macOS Mojave 10.14.6
- ruby 2.6.3
- rbenv 1.1.2
- pre-commit 0.39.0
- Sourcetree 3.2.1

# 前提
- ターミナルでpre-commitの正常作動を伴ったgit commitが可能であること

# 調査方法
以下のプリントデバッグで出力を見てみました。

```..git/hooks/pre-commit
#!/usr/bin/env sh
  
# 追記ここから
echo '@@@@@@@@@'
echo `ruby -v`
echo `which ruby`
echo `which rbenv`
echo '@@@@@@@@@'
exit 1
# 追記ここまで

# This hook has a focus on portability.
(略)
```

上記の状態からターミナルで確認。こちらは問題なしです。

```bash
$ git commit --amend
@@@@@@@@@
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
/Users/choripon/.rbenv/shims/ruby
/usr/local/bin/rbenv
@@@@@@@@@
```

しかし同じ環境にも関わらずSourcetreeでは、こうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33648/74dfea23-491b-c882-08a1-fb2c13db738e.png)

# 解決方法

```..git/hooks/pre-commit
#!/usr/bin/env sh
  
# 追記
source ~/.bash_profile

# This hook has a focus on portability.
(略)
```

- `source ~/.bash_profile` を追記しました
- `eval "$(rbenv init -)"` を.bash_profileに書いていることが前提です。その他PATH等も影響していそうですが精査できてましぇん
- もっと良い方法がある気がするのですが、今回はこれで凌ぐことにしまっす
複数画像をコマンド一発でリサイズ&フォーマット変換(jpg⇔pngなど)


Macだと`sips`コマンドが便利と知ったのでメモ。
png, jpg以外にもいろんなフォーマットに対応していてフリップやクロップも出来る。
ここではリサイズやフォーマット変換を紹介するが、詳しくは`man sips`で確認頂きたい。

## リサイズ
#### アスペクト比を保つ場合
高さ幅の最大値を指定(例えば`600`)したいなら

```
sips -Z 600 example.jpg
```

縦横いずれかの最大値を指定したいなら

```
sips --resampleWidth 600 example.jpg
```

`--out`で出力ファイル名を指定できる

```
sips --resampleWidth 600 before.jpg --out after.jpg
```

#### アスペクト比を保たない場合
縦横を400 x 300にしたいなら

```
sips --resampleHeightWidth 400 300 example.jpg
```

## フォーマット変換
`format (形式)`で変換先のフォーマットを指定。
例えば、`png` → `jpg`なら

```
sips -s format png before.png --out after.jpg
```

## リサイズ&フォーマット変換
#### 一例
ディレクトリ直下に縦横サイズが1000超えてるjpgの画像がたくさんあり、それら全てをアスペクト保ったまま高さ幅を最大600くらいにした上で、pngに変換したい場合(長い)。

出力ファイルに`nl`コマンドで出した行番号をあてている。

```
ls | nl | while read x y;sips --resampleWidth 600 $y --out $x.jpg;sips -s format png $x.jpg --out $x.png;end
```

古いのが邪魔であれば `rm *.jpg` する。
[cocoa][swift][kotlin]Cocoa.swift 2019-09に行ってきた

<p>会場は<a href="http://co-forest.com/">池袋コワーキングスペース OpenOffice FOREST</a>、サンシャイン側だ。</p>

発表
<p>「NSTextViewにコマンドパレットをつける」キーボードのみで操作できるように、NSTextViewにコマンドパレットをつける仕組みの発表で、CMD + Lで起動し、出現したNSTextFieldに文字を打つと、関連するメニューやコンテンツが選択できるようになるものだ。</p>

<p>「macOS/iOS/Android Tips枠（その1）」iOS/Androidの新OSの情報や、ストア申請などについて発表された。</p>

<p>「Tweeting（最近のTweet機能の実装方法）」システムやTwitter社からネイティブ実装のためのAPIが提供されなくなった現在にオススメできるTweet機能のiOSとAndroidの実装方法が紹介された。</p>

<p>「macOS/iOS/Android Tips枠（その2）」先日開催されたiOSDC Japanで発表者が興味を持ったものが紹介された。</p>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/147201/">Cocoa.swift 2019-10</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
c++で複数の数値データをcsvに出力する。part1

毎回、数値データを出力するたびに忘れてしまうので、メモ
今回は、列数が２つのデータをつかうため、std::pairを使うが、３つ以上の列数を使う場合、pairではなく、tupleを使えばよい

```output.cpp

#include <iostream>
#include <fstream>
#include <vector>
#include <utility>

int main()
{
//出力したいファイル名を指定する
	std::ofstream outputfile("test.csv");

	std::vector<std::pair<int,int>>data;
//出力したいデータを作る
	data.push_back(std::make_pair(1,3));
	data.push_back(std::make_pair(4, 3));
	data.push_back(std::make_pair(1, 2));
//データの出力
	for (auto &&b : data) {
		outputfile << b.first;
		outputfile << ',';
		outputfile << b.second;
		outputfile << '\n';
	}
//ファイルの出力
	outputfile.close();
}
```
alpineイメージのDockerfileに、Goをinstallしたい場合にハマったこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321850/3671d3d8-b3b9-a069-d551-1d9546931088.png)

by Renée French CC BY 3.0
# はじめに
こんにちわ。Wano株式会社エンジニアのnariと申します。
今回は、**alpineイメージにGoをインストールする際にはまった事案**について備忘録を残したいと思います。

# TL;DR
- **alpineベースのイメージにGoをインストールしたいなら、wgetとかcurlとか使わずにapkを使おう**

# 今回やりたいこと
- **codebuild(CI)上でhashicorp/terraformイメージにて、apexコマンドでlambdaを自動デプロイしたい**
 - そのため今回は、lambdaをGo言語で書いていたためhookのbuildに**Goのコンパイル環境が必要**なので、hashicorp/terraformイメージに追加でGoをインストールする必要がある

# 問題
- hashicorp/terraformはalpineベース　そこにGoをcodebuildのbuildspec.ymlにて以下のようにインストールしようとした

```sh
export GO_VERSION=1.12.4
wget https://storage.googleapis.com/golang/go{GO_VERSION}.linux-amd64.tar.gz
tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
```

すると、go version実行時に、以下のようなエラーがでた

```sh
sh: go: not found
```


# エラー解決策
- [docker - How to install Go in alpine linux - Stack Overflow](https://stackoverflow.com/questions/52056387/how-to-install-go-in-alpine-linux)に同じようなケースがあったので参考にした

>With Alpine, you have libmusl instead of glibc. Alpine's libmusl is not a 1 for 1 replacement. Code linked against glibc will show a not found error which is actually from the dynamic linker. You can see what libraries are linked to the binary with ldd:

どうやら、glibcの代わりに入っているlibmusl(linux標準のCライブラリ)の挙動が異なるようです。

```
 # ldd /usr/local/go/bin/go
        /lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
        libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f63ceed1000)
```
なるほど、**/lib64/ld-linux-x86-64.so.2 がalpineにはない**ので、そこへのdynamic linkを有する/usr/local/go/bin/goは、not found errorを返しちゃうわけですね

このかたは、Goバイナリを実行する形(go自体のダウンロードをしない)にするか、glibcを入れちゃうか(それならCentOSとかDebianつかえよ)って言ってるんですが、どちらの解決案も使わず以下のように解決しました。

```sh
apk add --update --no-cache vim git make musl-dev go curl

# Configure Go
export GOPATH=/root/go
export PATH=${GOPATH}/bin:/usr/local/go/bin:$PATH
export GOBIN=$GOROOT/bin
mkdir -p ${GOPATH}/src ${GOPATH}/bin
export GO111MODULE=on
go version
```
元も子もないapkでのdownload作戦、、、**apkはやっぱ便利ですね**というお話でした。

# 終わりに
既存のイメージに追加で環境を打ち込みたい際には、まずそのイメージのベースイメージを、**dockerHubから辿ってDockerfileから確認**するのが大事ですね。

**Cライブラリ群の知識など全然ないなぁ**と痛感することになりましたが、今はStackOverflowなどにかなりニアリーなケースに陥っていた先人のケースがあってとても助かります。

こう言った付け焼き刃のソリューションだけでなく、**どこかしらで深いところまでCライブラリの勉強**などもしていきたいですね。

# 参考文献
- [docker - How to install Go in alpine linux - Stack Overflow](https://stackoverflow.com/questions/52056387/how-to-install-go-in-alpine-linux)
- [Alpine Linuxあるある - Qiita](https://qiita.com/MiCHiLU/items/1e80a5325b2746eaf2d4)
- [man libc (7): Linux の標準 C ライブラリの概要](http://ja.manpages.org/libc/7)