OmniAICreator/Qiita-1.07M huggingface dataset:
とても便利な`xargs`【随時更新】

とても便利な`xargs`ちゃん。かわいい。


## 何ができるの？
> xargs - 標準入力を読み込んでコマンドラインを作成し、それを実行する
> 
> 引用元： https://linuxjm.osdn.jp/html/GNU_findutils/man1/xargs.1.html

`xargs`はLinuxコマンドだけど、Windowsの場合は[Git Bash](https://gitforwindows.org/)とか使えば実行できる。ありがたきGit Bash。

## 活用方法

### カレントディレクトリ配下を再帰的に見ながら全文検索
「`hoge`が含まれるファイルってどこにあるんだろう」
「わざわざ全文検索するソフトとか入れたくないしな」
って時に便利。

```sh:bash
find . | xargs grep -sn "検索文字列"
```

### カレントディレクトリ配下のファイルを全文検索して置換
「`hoge`を`fuga`に変えたいけど、１ファイルずつ開くのアホらしいな」
「コマンド一発で、複数ファイルを一気に置換できんじゃろうか」
って時に便利。（以下のコマンドは再帰処理しない）

```sh:bash
grep -l '置換前文字列' ./* | xargs sed -i -e 's/置換前文字列/置換後文字列/g'
```

### soon...
他にも便利なのあったら随時更新します。
エレクトーンとiPhoneをMIDI接続する!

#きっかけ
筆者の家にはエレクトーンがあります。ケーブルを使ってPCとつなぐことはできていましたが、どうにか無線でiPhoneにつなぎたくなったのがきっかけです! 結構いろいろなことができて面白いので皆様に共有したいなと思い記事にしました。
#スペック
- エレクトーン : YAMAHA製 ELS-02C
- iPhone : iOS 12

#いろいろ調査してみた
 - エレクトーンのIO関係
    - USB-A × 2
    - USB-B × 1
![IMG_0942 (1).JPG](https://qiita-image-store.s3.amazonaws.com/0/173847/114294e4-ae9a-fc0a-7a2c-38425754d995.jpeg)

この**TO DEVICE**と書かれた方にUSBのコードを利用してPCなど(もちろんiPhoneも)を接続しても何も起こらないので注意。(スマホの充電はできますが) エレクトーンと何か他のデバイスを接続するためには右側の**TO HOST**と書かれたUSB-BとPCを接続しなければなりません。

 - マニュアルを見てみる
きちんとiPhone接続の手順が書いてあります。基本的にそのとおりやってればOKです。
ただ、対応しているWi-Fiモジュールの種類が限られているので、購入する際はマニュアルで対応製品をしっかり確認しておきましょう。筆者は*BUFFALO*の*WLI-UC-GNME*を利用しました。小さくてなくしやすそうなので注意が必要です。

![IMG_0943.JPG](https://qiita-image-store.s3.amazonaws.com/0/173847/f8fad57c-5fa3-bdca-5164-a6ec3a60777e.jpeg)



#接続して利用する
エレクトーン側でWi-Fiセットアップを済ませれば、無事、無線LAN内にエレクトーンが参加できます。
##利用できるアプリ
MIDI端末が接続して利用できるアプリならだいたい利用可能です。とりあえずYAMAHAのアプリを紹介します。

###エレクトーン 弾き放題!
エレクトーンのファイルマネージャーとして使えます。

 エレクトーンと曲ファイルをやり取りするのは今までは、PCでファイルをUSBメモリに移してそれをエレクトーンに挿して利用する、というのが普通でしたが、このアプリを用いればいちいちPCを起動することなく、スマホからファイルをやり取りできます。ただ、エレクトーンにはUSBメモリを挿しておかないといけません。

<img width="320" alt="IMG_0944.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/173847/b27e1b56-dcaa-8abf-4672-0ab087176ffe.png">

これがメイン画面です。
「楽器」をタップするとネットワーク上にある楽器が表示されますので接続するだけでOK。
購入した楽曲を*Dropbox*に保存して、このアプリから取り込むと無線経由でエレクトーンにさしてあるUSBに送信することができます。これがすごく便利です!
ちなみに、エレクトーンではMIDIファイルが再生できる機能を持った機種もありますが、このアプリはMIDIファイルの転送には対応していないようです。残念!

###Chord Tracker
YAMAHA製のアプリです。iPhone内にあるmp3やaacの楽曲を読み込んで、コード譜を作成したりテンポ・キーのコントロールができたりする神アプリです。エレクトーンを含め楽器にMIDI接続するとその音楽を流せるらしいんですが、エラーを起こして強制終了してしまう不具合があり、できたことはありません。残念!

---

以下はYAMAHAアプリではありませんが便利です。

###MIDI Network
MIDIデバイスを接続するにはドライバーのようなものが必要です。そこで利用するのは**MIDI Network**(iOSアプリ)です。機能が同じものもいくつかあります。

###Web MIDI Browser
iPhone付属のSafariでは近年追加されたWeb MIDI機能が使用できないので、専用のブラウザを使うことでウェブ上のMIDIサービスを利用できます。(ブラウザ上でMIDIキーボードを接続するなど)

##おまけ

###epiano.jp(https://epiano.jp)
MIDI楽器を接続してWeb MIDI対応ブラウザで開くとオンラインピアノが楽しめます!
みんなで連弾したり、ちょっとしたときにほかの人に演奏を披露できます。

#おわりに
MIDIは接続も簡単でIoTとの相性も良さそうなので、MIDI製品とインターネットを利用した何か面白い作品を作れたらなと思いました。
CentOS7 に LibXL をインストールする

CentOS7にLibXLをインストールしてPHP5.4からExcelを出力する

# LibXLをダウンロードする

ここからでも入手できます
http://www.libxl.com/

```
# cd /usr/local/src
# wget http://libxl.com/download/libxl-lin-3.6.4.tar.gz
# tar -zxvf libxl-lin-3.6.4.tar.gz
```

# php_excelをインストールする

`libxml2`がインストールされていない場合はyumでインストールする
`yum install libxml2-devel`

```
# wget https://github.com/iliaal/php_excel/archive/master.zip
# unzip master.zip
# cd php_excel-master
# phpize
# ./configure --with-libxl-incdir=../libxl-3.6.4.0/include_c --with-libxl-libdir=../libxl-3.6.4.0/lib64 --with-libxml-dir=/usr/include/libxml2
# make
# make install
```

# インストールされたモジュールをPHPに組み込む

```/etc/php.d/excel.ini
extension=excel.so
;excel.license_name=LICENSE_NAME
;excel.license_key=LICENSE_KEY
```

# Apacheを再起動して有効になっているかを確認する

```
# systemctl restart httpd
# php -i | grep excel
excel support => enabled
```

# PHPからExcelを出力する

```php
<?php

$excel = new ExcelBook(null, null, true);

$sheet = $excel->addSheet('sheet1');
for ($row = 0; $row < 100; $row++) {
    for ($col = 0; $col < 100; $col++) {
        $sheet->write($row, $col, time());
    }
}

header('Content-Type: application/octet-stream');
header('Content-Disposition:attachment;filename="sample.xlsx"');
$excel->save('php://output');
```
（SD）第一弾 SAPー訓練「概要」

:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)
#１　定義
SDは sales and distributionの略で販売管理といいます。
流れは顧客から注文を受けて売上が計上されるまでです。

###1.1.　3つのステップ

- 受注(VA01)---受注伝票
- 出荷(VL01N)--出荷伝票
- 請求(VF01)--請求伝票

###1.2.認定試験[SAP Certified Application Associate – Sales and Distribution, ERP 6.0 EHP7]
| トピック      |       アカデミー |    レギュラー    |
|:-----------------|------------------:|:------------------:|
| 販売伝票(カスタマイズ) +++ |   TSCM60  | [SCM605](https://www.slideshare.net/NgocTey2102/scm605-en-sales)   |
| 基本機能 (カスタマイズ) ++ |   TSCM60  | [SCM605](https://www.slideshare.net/NgocTey2102/scm605-en-sales)   |
|価格設定と条件テクニック ++ |TSCM62 |[SCM620](http://www.saphelp.it/documenti/SD/SCM620%20-%20Pricing%20in%20Sales%20OrderManagement.pdf)|
|共通機能 (カスタマイズ) ++ |TSCM60  |[SCM605](https://www.slideshare.net/NgocTey2102/scm605-en-sales)|
| |TSCM62  |SCM610 |
| |  |SCM615 |
| |  |SCM650|
|組織構造 ++|TSCM60|SCM600|
| | |SCM610|
|販売プロセス ++|TSCM60 |SCM600|
|出荷プロセスとカスタマイズ++|TSCM60|SCM600|
|||SCM610|
|請求プロセスとカスタマイズ++|TSCM60|SCM600|
||TSCM62|SCM615|
|マスタデータ ++|TSCM60 |SCM600|
|利用可能在庫確認+|TSCM60 |SCM600|
[SAP SD Learning homepage](https://www.tutorialspoint.com/sap_sd/)
[中文 SD](http://www.vue5.com/sap_sd/)

#２．業務トランザクションの処理
##２．１得意先マスタ[T-code:XD01,XD02,XD03]
※HANA:XD01無効→BP

- 得意先登録　第一画面

```
勘定グループ：受注先
会社コード：1000

販売組織：1000
流通チャネル：10
製品部門：10
```
- 得意先登録　一般データ

```
ここでは一万文字を省略した：）
```

- 得意先登録　会社コードデータ

```
勘定コード管理
統制勘定：140000(売掛金-国内)
```
##２．２受注管理 [T-code:VA01,VA02,VA03]

- 受注伝票登録　第一画面
- :point_right: 登録BAPI: BAPI_SALESORDER_CREATEFROMDAT2
- :point_right: 変更BAPI: BAPI_SALESORDER_CHANGE

```
受注タイプ：OR(標準受注)
```

- 受注伝票登録　概要

```
ここでは一万文字を省略した：）
```

##２．３出荷管理 [T-code:VL01N,VL02N,VL03N]
- :point_right: 登録BAPI:BAPI_OUTB_DELIVERY_CREATE_SLS

##２．４請求管理 [T-code:VF01,VF02,VF03]
- :point_right: 登録： BAPI_BILLINGDOC_CREATEMULTIPLE
- :point_right: 取消： BAPI_BILLINGDOC_CANCEL1

##２．５取引先機能
- :point_right: 販売伝票：取引先「VBPA」
- :point_right: 取引先機能コードの言語変換「TPAUM」

- :point_right:結合条件：　内部(VBPA-PARVM)=内部(TPAUM-PARVW)
  　　　　　　　検索項目：　外部(TPAUM-PABEZ)

- :point_right:内部コード
	受注先　　⇒Z2
	請求先　　⇒RE
	営業員　　⇒VE
	受注担当　⇒ZM
	出荷先　　⇒WE
- :point_right:受注先

受注先（ユーザコード）『取引先：Z2』の得意先コード
受注先名（ユーザ名称）
⇒得意先マスタ: 一般データから受注先コードをキーとして名称１＋名称２

発行担当者番号（VBAK-ERNAM）
発行担当者名
⇒個人 (アドレス管理)「ADRP」はユーザ名/アドレスキーの割当「USR21」と結合して取得した個人の氏名 (省略なし)

営業担当者番号『取引先：VE』の従業員番号（PERNR）
営業担当名
⇒HR マスタレコード: インフォタイプ 0001 (所属情報)「PA0001」のフォーマットされた従業員/応募者氏名「ENAME」

受注担当者番号『取引先：ZM』の従業員番号（PERNR）
受注担当者名
⇒HR マスタレコード: インフォタイプ 0001 (所属情報)「PA0001」のフォーマットされた従業員/応募者氏名「ENAME」

- :point_right:請求先

請求先コード『取引先：RE』の得意先コード
請求先名称
⇒得意先マスタ: 一般データから請求先コードをキーとして名称１＋名称２

請求担当者番号⇒
	請求先コードをキーで得意先マスタ 取引先機能（KNVP）から取引先機能＝『取引先：VE』の従業員番号（PERNR）
請求担当者名
⇒HR マスタレコード: インフォタイプ 0001 (所属情報)「PA0001」のフォーマットされた従業員/応募者氏名「ENAME」

- :point_right:出荷先

出荷先コード『取引先：WE』の得意先コード
出荷先名称
⇒得意先マスタ: 一般データから出荷先コードをキーとして名称１＋名称２

[BPマスタ移行ツール](https://blogs.sap.com/2019/10/29/new-cvi-cockpit-enabling-movement-to-sap-s4hana-through-seamless-bp-synchronization/)
:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)
Amazon Linux 2でEBSボリュームを拡張する具体的な手順

Amazon Linux 2でEBSボリュームを拡張する手順メモ

## 前提

- OS: Amazon Linux 2
- AMI: amzn2-ami-hvm-2.0.20190115-x86_64-gp2 (ami-04677bdaa3c2b6e24)
- EBS Volume Type: gp2

## 参考

AWS公式ドキュメント
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-modify-volume.html

## 具体的な手順

- AWS Management Console -> EC2 -> EBS
  - 対象のEBS Volumeを選択、「アクション」->「ボリュームの変更」。
  - Sizeを指定（例：8GB->16GB）して「変更」
  - EBSの状態が「in-use optimizing(0%)」となる。「in-use completed(100%)」になるのを待つ。
- SSHでEC2に接続
  - ```lsblk``` で状態確認
  - ```sudo growpart /dev/nvme0n1 1``` でパーティション拡張
  - ```lsblk``` で状態確認
  - ```sudo xfs_growfs -d /``` を実行(Rebootしなくても反映できる。Rebootしても良い)
  - ```df -h```で、ディスク認識されている事を確認。

## 補足

Amazon Linux2のAMIからラウンチしたままであれば、上記の手順でOKなはずです。
※ ファイルシステム（xfsやらextとか）によって、実行するコマンドが異なるっぽいです（xfs_growfs やら resize2fsとか）。
InDesginで合成フォントが複数作成される問題と解決

# 起
この問題は結構前からあって色々な人がWebで書いているが、自分の所でもやはり同じ問題が発生して、どうしたもんだかと検証して、恐らくこれが解決策であろうというのが出てきたので、ここに記する。
ちなみに原因をすっ飛ばしてさっさと解決したい場合は、解決方法を先に読んでしまってもいい。

## 原因を考える
まずは原因を考えて行く。

###そもそもなぜ合成フォントを使うのか
そもそもInDesginで合成フォントを使う理由に関しては次のようなものがあるのであろう。

- 既存のフォントだと単一フォントの場合、全角、半角のバランスが悪い
- 文章中にコードなどが出てくる様な書籍でコード部分を半角にしたい
- コード部分の解説で日本語コメント、または日本語解説が必要
- 特殊文字と使う場合、日本語フォントでは表示できない、またはバランスが悪い

というところだろうか。
合成フォントを使う場合、やはり専門書のような全角日本語、半角英語のバランス問題で使用することが多いだろうと感じる。
そのため、合成フォントでそれを補う為、使用するのが多分にあるんじゃないだろうか。

### 大規模ページで起こる
16ページ程度のものであれば恐らく合成フォントが複数コピーされる事はないだろうと思う。
理由は簡単で、大規模ページの場合、章毎にファイルを作り、**ブック機能**で管理しているはずだからだ。
このブック機能がクセモノで、こいつを使わないと章をまたいでページ管理ができず、また書き出しに関しても毎回章ごとにPDFを吐いて、Acrobatで繋げなければならなくなる。

### なぜ合成ブック機能でフォントがコピーされるか
これはAdobeのサポートデスクでも確認したのでほぼ正しい情報であるが、ブック機能は章ごとに管理されているドキュメント情報を一括管理しており、ノンブルは疎か、文字スタイル、段落スタイル、表スタイル、セルスタイルなどを一括管理している。また、ここがキモになるのだが、その中には**合成フォントも管理下に置かれている**。
つまり、章をまたいで合成フォントも管理しているのがそもそもこの合成フォントが複製コピーされる問題を引き起こしているわけである。

ブック機能では、合成フォントを一括管理している関係上、章ごとに設定を変えている場合、複製コピーして元の合成フォントの設定を使わないようにしている。ブック機能が管理しているドキュメントが複数ある場合で、その中のドキュメントの複数で合成フォントの設定が違うとバンバン複製コピーされる事になるわけである。

本来は、マスターのドキュメントができたら、設定などはいじらず、ドキュメントを作成していけば、この問題が発生しないわけであるが、現実問題それがなかなか難しい問題でもあるわけで、この問題が時々発生しててんてこ舞いにな訳である。

実際、自分の仕事でもこの問題が全く発生しないこともあるし、バカバカ発生しててんてこ舞いする場合もある。

## 解決方法
解決方法は次のようなモノがある。

- ドキュメントを分けない
- ブック機能を使わない
- ブック機能で管理する共通設定を切る

ドキュメントを分けずに連結して使うのが一番エラーの起きない方法である。ただし、そのドキュメント自体が壊れたりすると目も当てれないし、複数人で共有する場合に置いては問題が出てくる。
次にブック機能を使わないという選択肢もあるにはある。ただし、ノンブル管理ができなかったり、書き出した後連結しなければならなかったりするので、これも現実的ではない。

やはり最後のブック機能で管理する共有設定を切るというのが現実的であろう。
これであればノンブル管理はできるし、他の共有しなければならないスタイルも維持できる。
では早速その方法を見ていこう。
まず、使用しているブックを開き、メニューから**同期オプション**を開く。

<img width="843" alt="InDesign CC001.png" src="https://qiita-image-store.s3.amazonaws.com/0/125657/9f412394-514f-2a0e-6363-6fdee2fed734.png">

次に下の方にある**合成フォント**のチェックボックスを外し、**OK**ボタンを押す。

![InDesign CC003.png](https://qiita-image-store.s3.amazonaws.com/0/125657/4e79e446-1509-91f4-4eae-6de7a687a8c5.png)

最後に**開いているブックを保存して閉じれば、次回からは合成フォントがブックの管理下から外れる**ことになる。
次回からなので、現状で複製された合成フォントはまだ残っているので、フォント検索で複製された合成フォントを正しいものに置き換え、複製された合成フォントは削除して置こう。
また、新しいブックを作る上で、まずは1つだけドキュメントを登録して同期オプションを切り、一端ブックを保存して閉じれば、煩わしい作業は必要なくなるだろう。
# 結
ブックの同期オプションは確かに便利な機能であるが、もう少しわかりやすい場所やアラートなどを出して貰った方が良いと思う。特に、複数のドキュメントでスタイルや合成フォントの設定が違う場合、単に複製コピーを作らず、アラートで置き換える等の設定もあれば、もっと使いやすくなるのではないだろうか。

# 追記 2024年11月
最近わかった事だけど、このブック機能であるが、たまにブックファイルが壊れることがある。
その場合、対策はほぼなくブックファイルを作り直すしかない。
自分もこのエラーにあった。ブックのフォント共有を切っているのに合成フォントが作成されてしまっていた。
もしそういうことがあったら、ブックファイル自体をさっさと作り直すことをお勧めする。
Maya XGen を使った plugin を Linux gcc 5.0+/clang でビルドするときの注意

# 背景

Maya の Linux でのサポート OS は RHEL7(CentOS7)である.
RHEL7 のデフォルトコンパイラは 4.8 である.

C++11 + STL 関連で, gcc(clang)は ABI の変更を行った. gcc 5.0+(clang) からは新しい ABI が標準である.

Maya の XGen ライブラリ(or OpenMaya も?)は gcc4.8 でコンパイルされている

したがって新しめのコンパイラや, Ubuntu でコンパイルしようとすると, リンク時にシンボルが見つからないエラーがでる(mangle された symbol に `B5cxx11` prefix がつく)
たとえば `XgSplineAPI.h` の `boundMeshId()` などでエラーがでます.

http://blog.kmckk.com/archives/5425614.html

## 解決方法

`-D_GLIBCXX_USE_CXX11_ABI=0` としてビルドします.

## 補足

ABI の変更により, std::string の動作が変わったため, `std::string boundMeshId()` と `std::string` を値渡し, 値返しでの型を含む関数がエラーになります. 

OpenMaya の API は MString を使っているのと, 基本 `char *` で文字列を扱っているため, OpenMaya 関連は問題なくリンクできる模様です(ただし正しく動作するかは不明)
mongodb の replicaSet の `not master`エラーで困ったお話

## 前提
Docker で３つのノードで mongodb のレプリカを構成しています。

```
version: '3'
services:
  ...
  node1:
    restart: always
    image: "mongo:4.0"
    command: --replSet rs1
  node2:
    restart: always
    image: "mongo:4.0"
    command: --replSet rs1
  node3:
    restart: always
    image: "mongo:4.0"
    command: --replSet rs1
  ...
```

**注意：初期起動してから、レプリカの初期化処理が必要**

アプリ側が接続文字列にこう書きました

```
ur = `mongodb://node1:27017/testDb?replicaSet=rs1,mongodb://node2:27017/testDb?replicaSet=rs1,mongodb://node3:27017/testDb?replicaSet=rs1`
```

## 問題
- レプリカ初期化処理を行い、アプリからは正常にアクセスできました
- `docker-compose` で `down` してから再度 `up` しました
- `db.user.insert(...)` 処理で `not master` エラーになりました

## 解決
- URL の書き方が間違っていました。ホストのリストをカンマ区切りで、`mongodb://`と`/testDb?replicaSet=rs1` の真ん中に置く必要があります
- `mongodb://node1:27017,node2:27017,node3:27017/testDb?replicaSet=rs1` のフォーマットで書きましょう
- ちゃんとドキュメント読めましょう

## まとめ
- 恥ずかしいですが、半日もハマってました。**ちゃんと** ドキュメント読めましょうを読みましょう！！！

## 参考リンク
- [Connect to MongoDB](http://mongodb.github.io/node-mongodb-native/3.1/tutorials/connect/#connect-to-a-replica-set)
- [MongoDB の レプリカセット へ Node.jsドライバー を使って アクセスする 方法 - galife](https://garafu.blogspot.com/2018/03/mongodb-connect-replicaset-nodejsdriver.html)
【Swift】UINavigationBarをカスタムした時に座標計算がずれる

## 概要
UINavigationBarをカスタムした時に、座標計算がNavigationBarの高さ分だけズレる現象が発生したのでその原因についてのメモです。

## 原因
`AppDelegate.swift`内の`didFinishLaunchingWithOptions`に、`UINavigationBar.appearance().isTranslucent = false`を記述していたのが原因。

NavigationBarを（ビジュアル的に）半透明でなくすることが目的でしたが、Viewの階層構造的にも影響があるっぽいです。
複数の非同期レスポンスを処理する方法

## 経緯
非同期で複数のサーバのAPIへリクエストし、そのレスポンス情報を集約して１つのオブジェクトにする処理が必要になった。
Web検索で理想のかたちがヒットしなかったので、備忘も含めて記載します。

## 環境
Node.js
axios: 0.18.0

## 注目点（2019/03/14更新）
<del>axios.all
axios.spread</del>
Promise.all


## 実装方法（2019/03/14更新）

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

function getServers(addresses) {
    return Promise.all(
        addresses.map((address) =>
            axios.get(`http://${address}/hogeapi`)
        )
    ).then((responses) => {
        const allResponse = {};
        allResponse.servers = [];
        for (const res of responses) {
            // 必要ならこの辺でレスポンスを加工
            allResponse.servers.push(res.data);
        }
        return Promise.resolve(allResponse);
    }));
}

// IPの配列
const addresses = ["xx.xx.xx.xx", "yy.yy.yy.yy"];
getServers(addresses)
.then((allResponse) => {
    // ここで集約したオブジェクトを取得
    console.log(allResponse);
});
```

<details><summary>変更前のコード</summary><div>

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

function getServers(addresses) {
    return axios.all(
        addresses.map((address) =>
            axios.get(`http://${address}/hogeapi`)
        )
    ).then(axios.spread((...responses) => {
        const allResponse = {};
        allResponse.servers = [];
        for (const res of responses) {
            // 必要ならこの辺でレスポンスを加工
            allResponse.servers.push(res.data);
        }
        return Promise.resolve(allResponse);
    }));
}

// IPの配列
const addresses = ["xx.xx.xx.xx", "yy.yy.yy.yy"];
getServers(addresses)
.then((allResponse) => {
    // ここで集約したオブジェクトを取得
    console.log(allResponse);
});
```

</div></details>

## 最後に
いかがだったでしょうか？良い記事だと思った方は「いいね」のクリックをお願いします。

まだまだ初心者なので、もっと良い方法があるなどあればコメントをいただけると助かります。
google maps for AndroidのinfoWindowをカスタマイズする

#0.実行例
<img width="288" alt="スクリーンショット 2019-03-13 11.47.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/369872/d01f965e-3c33-f1b7-def2-f6e844b3110c.png">

#1.setInfoWindowAdapter()
GoogleMap.setInfoWindowAdapter()で、InfoWindowAdapterインタフェースを実装したオブジェクトを設定する（getInfoWindow()またはgetContents()を実装する）。

```java
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
    private GoogleMap mMap;
//〜略〜
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;    //どちらかに処理を記述
            }

            @Override
            public View getInfoContents(Marker marker) {
                return null;    //どちらかに処理を記述
            }
````

#2.InfoWindowのレイアウトを記述
res/layout/に新しくレイアウトリソースファイルを作成し、infoWindowのレイアウトを記述する。
res/values/strings.xmlも必要に応じて記述を加える。

```xml:info_window_ayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/iw_1"/>
    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/iw_2"/>
    <TextView
        android:id="@+id/tv_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/iw_3"/>
    <Button
        android:id="@+id/bt_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/bt_1"/>

</LinearLayout>
```

```xml:strings.xml
<resources>
<!-- 〜略〜 -->
    <string name="iw_1">1行目の情報</string>
    <string name="iw_2">2行目の情報</string>
    <string name="iw_3">3行目の情報</string>
    <string name="bt_1">ボタンも置ける</string>
</resources>

```
#3.getInfoContents()の実装
```java
            @Override
            public View getInfoContents(Marker marker) {
                View view = getLayoutInflater().inflate(R.layout.info_window_layout,null);
                return view;
            }
```

#参考
[インフォウィンドウをカスタマイズする](https://seesaawiki.jp/w/moonlight_aska/d/%A5%A4%A5%F3%A5%D5%A5%A9%A5%A6%A5%A3%A5%F3%A5%C9%A5%A6%A4%F2%A5%AB%A5%B9%A5%BF%A5%DE%A5%A4%A5%BA%A4%B9%A4%EB)
[Info Windows | Maps SDK for Android | Google Developers]
(https://developers.google.com/maps/documentation/android-sdk/infowindows#custom_info_windows)
PowerBI メジャーを使って週の変化を作成

## PowerBIで今週と先週の差分や比率を出したいけどクイックメジャーにないのでメジャーを使って作成する
### 以下参考リンク
- [Calculate Previous Weeks Sales - Advanced DAX in Power BI](https://www.youtube.com/watch?v=jclWnA7pEvY)

## カレンダーテーブル作成
- 今回はカレンダーテーブルを作成したので作成する人はこちら　→　[link](https://blogs.msdn.microsoft.com/dataplatjp/2016/07/11/dax2/)
- 上記リンク通りに作成しプラスで先週の数字取得列も追加　※第1週目の前の週を取得するため <br>
`前週番号 = if('年月日'[週番号]=1, max('年月日'[週番号]), '年月日'[週番号] - 1)`

## 売上データとカレンダーテーブルのリレーション
- 年月日情報を紐づける
![MicrosoftTeams-image.png](https://qiita-image-store.s3.amazonaws.com/0/96662/267c73cd-70d4-b809-29be-74b006b07486.png)

## 新しいメジャーの作成

#### ステップ１
- 前の週の番号に紐づく売上の集計
    - 使用する関数：`CALCULATE()` `SUM()` `FILTER()` `ALL()` `SELECTEDVALUE()` `DIVIDE()`※それぞれの意味は省略
- `CALCULATE(集計したい値, 検索値)`のイメージです。

- 新しいメジャーの追加で先週の売上合計を表示

```
先週売上 =
 CALCULATE(
  sum('売上データ'[売上]), 
    FILTER(
      all('年月日'),
      '年月日'[週番号] = SELECTEDVALUE('年月日'[前週番号]) &&
      '年月日'[年] = SELECTEDVALUE('年月日'[年])
    )
  )
```

#### ステップ2
- 新しいメジャーの追加で先週からの比率計算


```
先週比率 = DIVIDE(sum('売上データ'[調整後売上]),'売上データ'[先週売上])
```


## 表の作成
- 週の項目・売上　+　先程作成したメジャーの先週売上と先週比率

![MicrosoftTeams-image__1_.png](https://qiita-image-store.s3.amazonaws.com/0/96662/fe4b6d45-329b-ca13-1e9d-54af78f0959a.png)

## まとめ
- 今回は検索してもなかなかこういったやり方がすぐ見つからなかったので作成してみました。
- これをやってみて思いましたがクイックメジャーに頼らずメジャーを使った方が個人的におすすめです。
    - 関数の理解も深まりますし今後別の作業でも応用が聞いてきそうなので
- 今後も別記事をちょくちょく書いていこうと思います。
openpyxlでフォントを設定する

# Introduction

以下のようなデータファイル(test.xlsx)があります。

![スクリーンショット 2019-03-13 11.25.11.png](https://qiita-image-store.s3.amazonaws.com/0/335400/32cb3260-0ed9-3829-600c-fd8886a3970f.png)

これは顧客に渡す大事なレポート資料なので、フォントを指定されたフォーマットで提出する必要があることがわかりました。このファイルのこのシートのみであれば手作業で済みます。しかしエクセルファイルが多数あったり、複数のシートにデータが記入されている場合には、やはりこの作業は自動化しておいたほうが良さそうです。

# スクリプトとその実行結果

以下のスクリプトを実行することで、指定したシート全体のフォントをメイリオに変換することができます。

```python:sheet_font.py

'''
    sheet_font.py
    purpose: read xlsx and set font automatically
'''

import openpyxl as xl
from openpyxl.styles import Font


# set input file name
inputfile = 'test.xlsx'

# read input xlsx
wb1 = xl.load_workbook(filename=inputfile)
ws1 = wb1.worksheets[0]

# set font
font = Font(name='メイリオ')

# write in sheet
for row in ws1:
    for cell in row:
        ws1[cell.coordinate].font = font

# save xlsx file
wb1.save(inputfile)
```

実行結果は以下のようになります。

![スクリーンショット 2019-03-13 11.32.20.png](https://qiita-image-store.s3.amazonaws.com/0/335400/06e1df03-4b00-ca23-0fa3-52110a0a9f30.png)

# スクリプト詳細

## from openpyxl.styles import Font

```python
from openpyxl.styles import Font
```

としてFont関数を直接インポートすることで、この関数を呼び出すたびにopenpyxl.styles.Font()と長々と記述することなく、Font関数を呼び出すことができます。

## フォント設定

途中の

```python
# set font
font = Font(name='メイリオ')
```

でFont関数の戻り値をfontに代入しています。試しにfontをprintで書き出してみましょう。

```python
print(font)
```

以下のような出力が得られます。

```
<openpyxl.styles.fonts.Font object>
Parameters:
name='メイリオ', charset=None, family=None, b=False, i=False, strike=None, outline=None, shadow=None, condense=None, color=None, extend=None, sz=None, u=None, vertAlign=None, scheme=None
```

Font関数から返された結果はopenpyxl.sytles.fonts.Fontオブジェクトであることがわかります。

Font関数では`name='フォント名の文字列'`でフォントの指定を行うことができます。その他にも、`size`, `bold`, `italic`, `color`, `underline`などの設定を行うことができます。

以下はフォント名をヒラギノ角ゴ Pro, フォントサイズを14, 太字、斜字、文字色を赤、アンダーラインを一本追加、の設定を行う場合の例です。

```python
font = Font(name='ヒラギノ角ゴ Pro', size=14, bold=True, italic=True, color='FF0000', underline='single')
```

結果は以下のようになります。

![スクリーンショット 2019-03-13 12.13.01.png](https://qiita-image-store.s3.amazonaws.com/0/335400/2e536653-bdae-5ec4-7212-75ceacb9471b.png)

```python
# write in sheet
for row in ws1:
    for cell in row:
        ws1[cell.coordinate].font = font
```

で、先にFont関数で指定したフォントを各セルのフォントに代入しています。

これをforループで各ファイル・シートに対して繰り返せば、大量のエクセルデータファイルのフォントを自動で一括変換できますね。
ExpoのOTAアップデートとrelease-channelについてまとめてみた。

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
expoには、OTAアップデートというものがある。

```
$ expo publish
```
と打つと、開発者のパソコンの中のコードを使い、ユーザーのスマホの中のアプリを書き換えると言う技術だ。
つまり、アプリのアップデートを審査を通さずに行える。
さらに、アップデートの反映までなんと０分。
夢の技術が標準でついている。

(通常は、アプリのアップデートは審査で３日待たされたりするからね。)

また、デフォルトでついてくる、release-channelと言う機能を使うと、channnel毎に、アップデートが出来るので、staginig環境、本番環境を、サードパーティライブラリなしに実現できる。

## release-channelの使い方

```shell
＄ expo publish --release-channel <環境名>
$ expo build:android --release-channel <環境名>
```
のように、release-channelの後ろに、任意の文字列を渡すだけ、
例

＄ expo publish --release-channel 'staging'
$ expo build:android --release-channel 'production'

渡した、任意の文字列は、コードの中で、以下のように参照できる。

```js
import { Constants } from 'expo'
const env = Constants.manifest.releaseChannel
console.log(env) // => 'staging' など、
```

環境変数を作りたいときは、

```js
const appName = env === production ? '本番アプリ' : 'ステージングアプリ'
```
のように、するといい。


## OTAアップデートでは注意するべき点がある
ユーザーがアプリをインストールして初めて開いた時、expo publishしたバージョンではなくgoogle playにアップしたバージョンがユーザーに表示される！！
一見 expo publishが失敗したように見える。
しかしユーザーが、アプリを一度閉じて次に開くと、OTAアップデートが反映されたアプリが表示される。

なぜこのようなことが起きるかは、以下の例を見ていただくと分かる。

## つまり、OTAアップデートの数だけ、ユーザーはアプリを再起動する必要がある。
例えば、version 1 を

```
$ expo build:android --release-channel production
```
とし、google play consoleに、apkをアップデートする。
次に、デザインに修正を加えたversion2を

```
$ expo publish --release-channel production
```
とし、アップデートする。
次に、致命的なバグを直す、version3を

```
$ expo publish --release-channel production
```
として、アップデートする。

この時、google play storeから初めてアプリをインストールしたユーザーの挙動は以下のようになる。
〜初めてアプリを開く〜
version1が表示される。
〜2回目にアプリを開く〜
version2が表示される。
〜３回目にアプリを開く〜
version3が表示される。

つまり、ユーザは、最新のバージョンのアプリを開くためには、アプリをインストールした後、OTAアップデートの回数、アプリを再起動しなければならない！！！

大きな機能の変更は、google play consoleにapkファイルを上げ、軽微な変更はOTAアップデートを使うというよういに使い分けるのがベスト

## OTAアップデートで出来ないこと
アイコンの変更
アプリの名前の変更
アプリのスプラッシュスクリーンの差し替え
expo sdkのバージョンアップ
など、、、

## 結論
・OTAアップデートは便利だが、大きな機能を追加するときは、きちんとAPKファイルなどをgoogle play storeに提出しないと痛い目を見ることになる。

・Expo.updates.reload()と言うメソッドが用意されているので、それを利用することで、OTAアップデートのタイミングを制御出来る。

・apkを更新したいなら、OTAアップデートではなく、素直に

```
expo update:android
```
を使用した方がいいようだ。
ただ、上のコマンドは、かなり色々セットアップが必要になる。

[expo updateのやり方(公式ドキュメント)](https://docs.expo.io/versions/v32.0.0/distribution/uploading-apps)

## おまけ
このヘンテコなexpo publishの挙動は、expo公式も問題視していて、twitterでこの仕様の改善した方が良いかアンケートをとっていた。
近い将来にこの仕様はひょっとすると変わるかもしれない。
Docker attach と exec

##■attach と exec の違い##

どちらも稼働中コンテナへ接続するコマンドである。

|attach|exec|
|---|---|
|コンテナ内でシェルが動作していなければ接続することができない。|稼働コンテナでPID=1のプロセスを実行するため、コンテナ内でシェルが動作している必要がない。|
|exitコマンドで抜けるとコンテナが停止してしまう|exitコマンドで抜けるてもコンテナは停止しない|


##1.attach##

```
$ docker attach <コンテナ名>
```

コンテナ内でプロセス一覧確認。/bin/bashプロセスはもともと動いていた1つだけ。

```
root@a5b4fa2dda56:# ps -ef
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/476f930f-ab03-b8ef-bf1b-205834fc1d6d.png)

コンテナを終了する。

```
root@a5b4fa2dda56:# exit
```

Exited になっていることが確認できる。

```
$ docker ps -a
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/5568ecf1-2e21-426d-c893-c693d149a680.png)



##2.exec##

```
$ docker exec -it <コンテナ名> /bin/bash
```

コンテナ内でプロセス一覧確認。接続する際に稼働コンテナでPID=1のプロセスを実行するため、コンテナ内でシェルが動作している必要がない。

```
root@a5b4fa2dda56:# ps -ef
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/36cd2536-66d9-cd90-7069-0cd3b3988bd7.png)

コンテナを終了する。

```
root@a5b4fa2dda56:# exit
```

稼働していることが確認できる。

```
$ docker ps
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/dd3b08bd-ab1a-d668-ea33-111af61850b6.png)
JQueryで複数のhtmlをincludeする。includeしたhtmlの要素に対してJSも使えるようにする。

いまさらJQuery再び

[前回の記事](https://qiita.com/kihoair/items/f26dd62398a8b39660e2)では一つのhtmlファイルを読み込んでたんですが、複数のhtmlファイルを読み込もうと思います。さらに各htmlが読み込み終わってから、展開された要素に対してJS使ったりしたい。

# 作った関数の使い方
第一引数にはJSONの配列、第二引数には読み込んだ外部JSから使いたい関数を渡します。
第一引数の配列の各要素のJSONのキーには`filepath`,`selector`があり、それぞれ読み込むHTMLファイルのパスと展開先のセレクタを値として設定します。
第二引数は特に使いたいJSがなければなくても大丈夫です。

```js
// includeHTML(JSONの配列,function(){読み込んだ外部JSから使いたい関数たち})
includeHTML(
  [
    { filepath: "/include/footer.html", selector: "div.footer_inc"},
    { filepath: "/include/header.html", selector: "div.header_inc" }
  ],
  function() {
    // ここから使いたい関数
    $(function() {
      hoge.ready();
      huga.ready();
    });
  }
);
```

# 作った関数

```js:includeHTML
function includeHTML(requestArrayOfJson, usingFuncFromMainjs = function(){;}) {
  var jqXHRList = [];
  // ajaxの処理のリスト作成
  for (var i = 0; i < requestArrayOfJson.length; i++) {
    jqXHRList.push(
      $.ajax({
        url: requestArrayOfJson[i].filepath,
        cash: false,
        dataType: "html"
      })
    );
  }
  // jqXHRList内のajaxの処理が全て終了したらthen内の処理に移る
  $.when
    .apply($, jqXHRList)
    .then(
      function() {
        var htmlList = [];
        // ajaxで取得したhtmlのリスト作成
        for (var i = 0; i < arguments.length; i++) {
          var result = arguments[i];
          htmlList.push(result[0]);
        }
        return htmlList;
      },
      function(){
        console.log("Fail to GET HTML by ajax");
      }
    )
    .then(
      function(htmlList) {
        // 各htmlのinclude処理
        for (var i = 0; i < requestArrayOfJson.length; i++) {
          $(requestArrayOfJson[i].selector).html(htmlList[i]);
        }
      },
      function(){
          console.log("Fail to write HTML");
      }
    )
    .then(
      function() {
        // JSのファイルを読み込んだ後、コールバックでこの関数の第二引数として渡した関数実行。
        $.getScript("読み込みたい外部JSのパス", usingFuncFromMainjs);
      },
      function(){
        console.log("Fail to get 読み込みたい外部JS");
      }
    );
}
```

# 感想
できたけど、なんかやってることの方向性がおかしい気もする。

# 参考
https://qiita.com/YusukeHirao/items/bca14c5f2fe4026fd4d7
コーディングする前に...

# はじめに
  丁度昨日、Djangoで作ってるシステムを一部公開したら、Twitterの友達に開発過程を聞かれて、DMしても私の文章力では上手く伝わらないと思ったのでこの記事を書くことにしました。
###
また、内容に関しては**要件定義の話ではありません**。
コーディング前の事でもありますので**コード書いたりはしません**。

![itschool.PNG](https://qiita-image-store.s3.amazonaws.com/0/320164/b30356e1-ffdc-610b-9f98-244e50629808.png)

#需要分析
簡単に紹介します。
Django school(仮名前)は今回の記事の分析用モデルになります。
複数ITスクールが登録されて、公開授業して、生徒募集するようなシステムになります。
分類すれば、複数店舗存在するECサイトになります。
先ずこの三つの要素から分析していきます。

- 役
- データ
- アクション

###単独分析していきます
##1.役
Django School に以下の役を持つユーザーが存在します：

ゲスト —— ログインしていない者
会員 —— ログインしたユーザー
スクール運営者 —— スクールの管理者
admin —— 最高管理者

###2.データ

会員—— モデル名 UserProfile, アドレスなどの基本情報が入ってます
スクール —— モデル名 school，スクールの基本情報が入ってます
コース —— モデル名courses ，例えば[Django入門編]が一つのコースになります
セッション —— モデル名 session，一つのコースに複数セッションが存在します,例えばセッション1.Djangoは何?
ビデオ —— モデル名video,一つのセッションも複数のビデオが存在します
受講したコース —— モデル名user_course,会員が何コースを勉強してる,普通のECならオーダーモデルの役割になります；
講師 —— モデル名 teacher，講師のプロフィール,スクールと関連してる場合が多い
問い合わせ —— モデル名 userask，スクールとユーザ間のコミュニケーション用

###3.アクション
ユーザとデータのやりとりは基本この四つになります

作る Create
調べる Read
編集 Update
削除 Delete

###具体例を見ていきます

####1.ゲスト
ゲストはスクールリストや詳細を調べます
ゲストはどんなコースが公開されているのか調べます

###2. 会員
会員は自分のプロフィール修正できます
会員はスクール,コース,講師などをお気に入りに追加できます
会員は公開コース視聴することができます
会員はレビューできます
会員はスクール側に問い合わせできます

###3.スクール運営者
スクールは受講者確認できます
スクールはスクールプロフィール編集可能です
スクールは新しいコース追加できます
スクールはコースの内容編集可能です
スクールはコース削除可能です
スクールは講師追加可能です
スクールは会員の問い合わせに対して返信可能です

##モジュールの整理

###1.モジュールリスト
需要に基づいてシステムをいくつのモジュールを分けられます

- 会員モジュール
- スクールモジュール
- コースモジュール
- やり取りモジュール

###2.依存関係
モジュールリストができたら、間の依存関係ついて簡単に見てみましょう。
`やり取りモジュール`は`会員モジュール`と`スクールモジュール`と`コースモジュール`に依存します。
`コースモジュール`はまた`会員モジュール`と`スクールモジュール`に依存します
各モジュールの依存関係は下記の画像で表せます
![121.PNG](https://qiita-image-store.s3.amazonaws.com/0/320164/a6eeda37-e175-52b2-071e-07e816e0f920.png)

###3.開発手順
下階層のモジュールは上階層に依存しますので、上から優先開発していきます
 1.会員モジュール
 2.スクールモジュール
 3.コースモジュール
 4.やり取りモジュール

###おまけ`MVP`商品
mvpとは何か?
簡単にいえば、**顧客に価値を提供できる最小限の製品や、それを使ったアプローチ**のことをいいます。

今回のDjangoSchoolで例に挙げると:
`このアプリに関しては、どんな機能が必要不可欠なのか?`

オンライン教育サービスの核心は**会員に良いコースを受講できる**こと。
そのため、会員モジュール,スクールモジュール,コースモジュール,レビューアクションと問い合わせアクションが必要不可欠になってきます

他に勉強した内容をtwitterにあげて自慢する機能。可愛いマスコットキャラクター作ってるゲームする機能など、あったら面白いかもしれませんが、重要ではないです
デベロッパーとしては基幹機能完成したら、早く納品する、リリースするの方がもっと重要です



#まとめ
ここまできたら、コーディングに入ってもいいでしょう
Macにおける新規フォルダおよび新規ファイルの作成方法

##Macにおける新規フォルダおよび新規ファイルの作成方法
簡単にメモしておく。


新規フォルダの作成方法　→『shift(⬆︎)+command+N』

新規ファイルの作成方法　→『command+F』
Railsのタイムゾーンを日本時間に変更

Activesupport::TimeZone
---

Railsが日時を扱うときは、自動的にActivesupport::TimeZoneクラスを用い、タイムゾーンはデフォルトで`UTC(世界協定時刻)`である

デフォルトのタイムゾーンを日本時間に変更
---

日本で利用するアプリケーションならば、
`config.time_zone = ‘Asia/Tokyo’`を設定しておくと便利なため
タイムゾーンをデフォルトのUTCから日本時間に変更してみる

```ruby:config/application.rb

module SampleApp
  class Application < Rails::Application
    #Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    config.time_zone = 'Asia/Tokyo'
  end
end

```


コンソールを立ち上げて`Time.zone.now`または　`Time.current`を実行して
JST(日本標準時間)が表示されているか確認する

```
[1] pry(main)> Time.zone.now
=> Wed, 13 Mar 2019 01:19:55 JST +09:00


[2] pry(main)> Time.current
=> Wed, 13 Mar 2019 01:19:55 JST +09:00

```

最後に、画面上の時刻もJSTで表示されているのか確認する
TrelloのListにGasからCardを追加する

#TrelloのListにGasからCardを追加する
gasを使ったchatOpsを行うとしていて、その中の１つの要素としてTrelloのタスクをGoogle app scriptから追加できるか試してみました。
使い方の想定としては、お客様からの問い合わせがあった時に、自動問い合わせ内容をTrelloのボードに入れる。。。などなど

##参考にしたサイト&本
https://qiita.com/isseium/items/8eebac5b79ff6ed1a180

基本的には、@isseiumさんの記事を参照しました。
あとは、リファレンス的な感じで以下本も使ってます
https://www.shuwasystem.co.jp/book/9784798053769.html


##やること
- API キーの取得　
- API tokenの取得
- カードを追加したいボードid取得
- カードを追加したリストidの取得
- Listにカードを追加する

APIキーとtokenの取得はここでは割愛。

##環境
- Google app script　・・・Googleのアカウントの準備でOk
- Trello   ・・・事前にボードとリストを作成しておく

##コードを書いてみる
###カードを追加したいボードid取得
APIKeyとAPItokenについては、自分の環境にあったものを代入してください

```javascript
function TrelloAPI() {
  var APIKey ="***";
  var APItoken="***";
  var userName = "testuser";
  var url = "https://trello.com/1/members/"+userName+"/boards?key="+APIKey+"&token="+APItoken+"&fields=name";
  var response = UrlFetchApp.fetch(url);
  Logger.log(response)

```
ここで返ってくるreponse の中身は

```
[
 {"name":"Aボード","id":"abcxxx"},
 {"name":"Bボード","id":"abcxxx123"},
 {"name":"Cボード","id":"abcxxx12345"}
]
```
Cボードをターゲットにするとすると、"id":"abcxxx12345"を使うことになる
###カードを追加したいリストidの取得
先ほど取得したボードのidを使用する。

```javascript

 //List のIDの取得
  var bordId = abcxxx12345
  var urlList =  "https://trello.com/1/boards/"+bordId+"/lists?key="+APIKey+"&token="+APItoken+"&fields=name";
  var responseList = UrlFetchApp.fetch(urlList);
  Logger.log(responseList)
```
ここで返ってくるresponseは

```
[
  {"id":"1234","name":"todo"},
  {"id":"abcd","name":"doing"},
  {"id":"1234abcd","name":"done"}
  ]
```
お客様からのリクエストをtodoに入れたから、 {"id":"1234","name":"todo"}を使用する

###Listにカードを追加する
ここで使うのは {"id":"1234","name":"todo"}　のid。
POSTをつかうので、Urlfetchへpostを行うようにoptionで設定する。

```javascript
  
  //todoヘボードを追加
 var ListId = "1234"
 var options =
   {
     "method" : "post",
   };
   
   var CardName = "これはテストです。これはテストです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。これはてすとです。" ;
   
  var urlCard ="https://trello.com/1/cards?key="+APIKey+"&token="+APItoken+"&idList="+ListId+"&name="+CardName;
  var responseCard = UrlFetchApp.fetch(urlCard,options);
  Logger.log(responseCard)

```

上記functionを実行すると、Trelloのカードが作成されています。
BigQuery / MySQLで日次の仮想テーブル(連番の仮想表)を作成する

# はじめに
こんな感じに過去1年分の仮想テーブルを作成するSQLです。
日次ベースの仮想テーブルを、累積グラフ作成の際の基準とします。
JOIN させていく形で利用します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/105093/d43e842f-79d1-48e0-3b5d-87557c9fac61.png)


# SQL
### BigQuery

```sql

SELECT
  DATE_SUB(CURRENT_DATE(), INTERVAL n day) as date 
FROM
  UNNEST(GENERATE_ARRAY(1, 365)) AS n
;
```

### MySQL

```sql
SELECT
  CURDATE() - INTERVAL num DAY AS date
FROM ( 
  SELECT
    @num := 0 AS num
  UNION
  SELECT
    @num := @num + 1 AS num
  FROM
    information_schema.COLUMNS
  LIMIT 365
) t1;
```

### 参考
- [BigQueryで日次の仮想テーブルを作る](https://qiita.com/ryoichi-u/items/91e16ee53ccfad010ff7)
[Python]おまじないif __name__ == '__main__'の挙動

#Pythonを勉強していたらおまじないにぶち当たってしまいました。
**if \_\_name\_\_ == '\_\_main\_\_'**というおまじない、Pythonをある程度勉強したひとは出会った事があると思います。
そんなに使い方が難しいわけではないおまじないですが、初見では仕組みがよくわからずモヤモヤしていました。
私は仕組みがよくわからないものを使うのは苦手です。

このおまじないについてはすでに色々な解説がQiitaにもあります。
特に
[[Python] if \_\_name\_\_ == '\_\_main\_\_' について理解しよう](https://qiita.com/homines22/items/edf7a2309f3421723550)
はとても参考になりました。

ただ、まだしっくりしないモヤっとした感じがありました。
そこで、**\_\_name\_\_**や**\_\_main\_\_**の挙動を自分なりにコードを書いて調べてみました。

以下のコードを書いて実行してみます

```Python:duname.py
print(__name__)
```

結果はこうなります

```Python:duname.py
__main__
```

このduname.pyをモジュールとして他のスクリプトからimportしてみましょう

```Python:funcTest.py
import duname
```

結果はこうなります

```Python:funcTest.py
duname
```

[公式ドキュメント](https://docs.python.org/ja/3/library/__main__.html#module-__main__)にも書かれていますが、
**\_\_name\_\_**
 はスクリプトから直接実行されたときは文字列
**'\_\_main\_\_'**
が代入され、モジュールとして読み込まれた場合には
モジュール名が代入されます。

そういうわけで
**if \_\_name\_\_ == '\_\_main\_\_'**
の下に書かれたコードはスクリプトから直接実行された時は読まれるけど、モジュールとして呼び出した時には読まれないという効果が得られます。

##もしかして**\_\_main\_\_.py**って名前のスクリプトを書いたらバグって常に実行されるようになるんじゃね？

早速以下のコードを書いた

```Python:__main__.py
def printhello():
	print('hello')
	
if __name__ == '__main__':
	printhello()
```

モジュールとして呼び出します

```Python:funcTest.py
from __main__ import printhello
```

**ImportError: cannot import name 'printhello'**

とエラーが出てしまいました。

別の書き方を試してみます

```Python:funcTest.py
import __main__
printhello()
```

**NameError: name 'printhello' is not defined**

とエラーが出ます。
「えー、\_\_main\_\_.pyで定義してあるじゃん！？」

どうやら**\_\_main\_\_**は特別なモジュールで、[読み込まれる時に初期化されるみたいです](https://docs.python.org/ja/3/reference/import.html?highlight=__name__#special-considerations-for-main)。
というわけでバグは起きないのでした（当然といえば当然）。

##まとめ

・**\_\_name\_\_**はスクリプトを直接実行した時は**'\_\_main\_\_'**が代入され、モジュールとして呼び出された時はモジュール名が代入される。
・**if \_\_name\_\_ == '\_\_main\_\_'**の下に書かれたコードはモジュールとして呼び出された時は実行されない。
・**\_\_main\_\_.py**を作って呼び出しても初期化されてしまう。

まだまだよくわからないところはありますが、自分としてはおまじないの仕組みが大体わかってモヤモヤはなくなりました。

すでに色々なところに書かれている内容の繰り返しなので、この記事には価値があまりありませんが、
こうやってまとめる事で自分の中の理解が深まりました。

なので、これからもこうした記事を増やしていきたいと思っています。
ホストPCと同じセグメントのIPアドレスをDockerコンテナに割り当てる

macvlanドライバを利用するNetworkを作成して、`docker run`時に利用することで、ホストPCと同セグメントのIPアドレスを割り当てて、コンテナを動作させることができます。

[Networking using a macvlan network](https://docs.docker.com/network/network-tutorial-macvlan/)

Ubuntu 18.04で動作を確認

# Networkの作成
```shell-session
$ docker network create -d macvlan --subnet=192.168.1.0/24　--gateway=192.168.1.254 -o parent=enp4s0 mynet
```

上記の例では、`mynet`という名称でアダプタが作成されます。
`--subnet`、`--gateway`には、ホストと同じネットワークの値を指定。`-o parent`には、ホストのアダプタID(ifconfig参照)を指定します。

 ```shell-session
$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 xxxx::xx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 0  (イーサネット)
        RX packets 351  bytes 3305069 (3.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 262  bytes 26479 (26.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.10  netmask 255.255.255.0  broadcast 192.168.1.255
...
```

# コンテナ起動
```shell
$ docker run -d --name nginx20 --network mynet --ip 192.168.1.20 -p 80:80 nginx
```

`--network`に先ほど作成したNetworkを指定、`--ip`にコンテナへ割り当てたいIPアドレスを指定して起動することで、該当IPアドレスで動作します。

# 制限事項
ネットワークアダプタの仕組み上？、ホストPCのローカルから、本ネットワークを割り当てたコンテナのIPアドレスにはアクセスできません。
DatadogのDashboardやMonitorをTerraform化する

初めに断っておくと、ほとんどGitHubのリンク貼るだけの記事です。日本語の記事があったほうが利用者増えるかも、ぐらいの気持ちで書いてます。

# 概要
DatadogのTimeboard、Screenboard、Monitorなどは便利ですが、手動でポチポチ作るとその後の管理も大変なのでやはりコード化しておきたくなります。そこでTerraformを調べるとDatadog用のProviderがある事が分かります。
https://www.terraform.io/docs/providers/datadog/index.html

ただ自分でTerraformで書くのも面倒だし現在のDatadogの設定からTerraform生成してくれる方が嬉しいよね、という内容です。

最初に結論を書いておくと、↓使ったら結構便利になりました。
https://github.com/amnk/dd2tf


# 詳細
Datadog用のProviderはあるものの、これを使うと解決！というわけでもなくて特にScreenboardは苦行です。

https://www.terraform.io/docs/providers/datadog/r/screenboard.html
上記を見てもらうと分かりますが、Widgetのところはxやyを指定するところがあり自分で座標を指定する必要があります。これの指定の仕方を最初理解するのがまず大変です。また、微調整するたびにx,yの値を変えて `terraform apply` とか想像するだけで苦行なことが分かるかと思います。Datadogの画面からならマウスで適当に配置するだけで出来上がるのにTerraform化しようとすると一気に大変になります。

そこでDatadogの設定からTerraformのHCL生成してくれるやつないかなと調べて見つけたのが `dd2tf` です。
https://github.com/amnk/dd2tf

使い方はREADMEにもありますが、以下のようにコマンドを打つとScreenboardのHCLを吐いてくれます。

```console
$ DATADOG_API_KEY=xxx DATADOG_APP_KEY=xxx ./dd2tf screenboards --all
```

実装はとてもシンプルで、DatadogのAPIを叩くとScreenboardの詳細がJSONで返ってくるのでそれをテンプレートにひたすら埋め込んでいってます。
https://github.com/amnk/dd2tf/blob/master/tmpl/screenboard.tmpl

正直かなり力技感があり、GoのStructからHCLにMarshalするやつとかあるんじゃないのかな...という気もしますが、そこは気にせず使わせてもらっています。x,yなどの座標もAPIが返してくるので自分で値を意識する必要はないです。これのおかげでScreenboardとかの管理はかなり楽になりました。

とは言ったものの当初はテンプレート結構バグってて動かなかったので色々直したりしました。
https://github.com/amnk/dd2tf/pull/13

DashboardだけでなくMonitorでも使えるので便利です。ただ自分の利用範囲のバグしか直してないので、他にも直すべき箇所あるかもしれません。その場合は直していきましょう。

# 注意
もしかしたらScreenboardのdump時などにエラーが出るかもしれません。

```console
FATA[0001] json: cannot unmarshal string into Go struct field Screenboard.width of type int
```

これはwidthがintで定義されてるのにstringになってるぞ、ということですが何でこんな事が起きるのかなとDatadogのAPIを叩いてみました。

```console
$ curl -G "https://app.datadoghq.com/api/v1/screen/XXXXXX" -d "api_key=$DATADOG_API_KEY" -d "application_key=$DATADOG_APP_KEY" | jq . | grep width
 "width": "100%",
```

確かにstringになっています。別のScreenboardを叩いてみます。

```console
$ curl -G "https://app.datadoghq.com/api/v1/screen/YYYYYY" -d "api_key=$DATADOG_API_KEY" -d "application_key=$DATADOG_APP_KEY" | jq . | grep width
  "width": 424,
```

intになっています。どうやらDatadogのAPIがintだったりstringだったりを返してくることがあるらしく、使っているDatadogクライアントの [go-datadog-api](https://github.com/zorkian/go-datadog-api) がwidthをintで定義しているのでエラーになっているようです。他にもそういう箇所は多いらしくjson.Numberで回避していたりします。
https://github.com/zorkian/go-datadog-api/blob/1df5bda80d16ccfa8e99c543dbeb731665acbfca/dashboards.go#L45-L47

dd-agentとかもGoなのにDatadogさんは何でこんな設計にしちゃったんだろう...という気持ちなのですが、文句を言ってもしょうがないのでgo-datadog-api側に修正投げました。
https://github.com/zorkian/go-datadog-api/pull/218

破壊的変更になっちゃいますし、開発がそこまで活発ではないので修正が取り込まれるかは分かりませんが、現時点で回避したい場合はScreenboard全体のサイズをいじると良いです。自分の実験した感じでは新規作成されたままの状態だと100%になっちゃいます。ですが、一度サイズを変えるとintになりました。ただたまにstringに戻ったりしてよく分からないです。完全にWorkaroundという感じです。

![screenboard.gif](https://qiita-image-store.s3.amazonaws.com/0/56222/dfcf872c-bfe2-85f4-2754-284a99291296.gif)

全然関係ないですが、DatadogのAPI叩いてたらcamel caseとsnake caseが両方返されていたりして、厳しい戦いの幕開けを感じさせました。

```
"title_text": "",
"titleText": "title",
```

# まとめ
DatadogはGUIでポチポチ作ってTerraform化すれば結構捗る
GraphQL (graphiql-rails) をサブディレクトリで動かす方法

開発環境では動くのにデプロイしたら動かないので調べたら graphiql-rails がサブディレクトリを考慮してくれていないためでした。

とりあえず次のように `ActionController::Base.relative_url_root` を自力で指定したら動きました。

```ruby:config/routes.rb
Rails.application.routes.draw do
  mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "#{ActionController::Base.relative_url_root}/graphql"
  post "/graphql", to: "graphql#execute"
end
```

通常は `ActionController::Base.relative_url_root` は空なので常に上のように書いておいても問題ありません。
【PowerShell】ディレクトリ、ファイル調査

## ディレクトリ情報取得

ディレクトリの情報を調べるコマンドです。

### ディレクトリ一覧取得

- [-Filter] 引数に設定している文字列 "*" はワイルドカードです。
- ディレクトリの場合、PSIsContainer は True になっています。
- Attributes -eq "Directory"

```powershell
## 調べたいフォルダにカレントディレクトリを変更
cd C:\Users\ishikawa\Documents

## ディレクトリ一覧取得(サブディレクトリ含まず)
Get-ChildItem -Filter * | Where-Object { $_.PSIsContainer }
### ↓↓↓ 省略した記述 ↓↓↓
dir * | ? PSIsContainer

### 一番短い記述
dir -Directory

## ディレクトリ一覧取得(サブディレクトリ含む)
Get-ChildItem -Filter * -Recurse | Where-Object { $_.PSIsContainer }
### ↓↓↓ 省略した記述 ↓↓↓
dir * -Recurse | ? PSIsContainer

### 一番短い記述
dir -Recurse -Directory

## ディレクトリ一覧を変数に格納 (型は省略可能)
$Path = "C:\Users\ishikawa\Documents"
[System.IO.DirectoryInfo[]] $dirs = dir $Path -Recurse -Directory
```

## ファイル情報取得

ファイルの情報を調べるコマンドです。

### ファイル一覧取得

- [-Filter] 引数に設定している文字列 "*" はワイルドカードです。
- ファイルの場合、PSIsContainer は False になっています。
- Attributes -ne "Directory"

```powershell
## 調べたいフォルダにカレントディレクトリを変更
cd C:\Users\ishikawa\Documents

## ファイル一覧取得(サブディレクトリ含まず)
Get-ChildItem -Filter * | Where-Object { !$_.PSIsContainer }
### ↓↓↓ 省略した記述 ↓↓↓
dir * | ? PSIsContainer -eq $false

### 一番短い記述
dir -File

## ファイル一覧取得(サブディレクトリ含む)
Get-ChildItem -Filter * -Recurse | Where-Object { !$_.PSIsContainer }
### ↓↓↓ 省略した記述 ↓↓↓
dir * -Recurse | ? PSIsContainer -eq $false

### 一番短い記述
dir -Recurse -File

## ファイル一覧を変数に格納 (型は省略可能)
$Path = "C:\Users\ishikawa\Documents"
[System.IO.FileInfo[]] $files = dir $Path -Recurse -File
```

### ファイル一覧からの情報抽出

ファイル一覧を格納した変数を利用して情報を抽出します。

#### ファイル数取得

```powershell
## ファイル数
($files | measure).Count
```

#### ファイル最終更新日の最大と最小

```powershell
## ファイル最終更新日
dir -File -Recurse | measure LastWriteTime -Maximum -Minimum
```

#### ファイル拡張子の一覧取得

```powershell
## 拡張子の一覧
$files | sort Extension -Unique | select Extension
```

#### ファイル一覧を CSV に出力

```powershell
## ファイル一覧を CSV に出力
$files | select FullName, DirectoryName, Name, BaseName, Extension, Length, IsReadOnly, CreationTime, LastAccessTime, LastWriteTime | epcsv "Files.csv" -Encoding UTF8 -NoTypeInformation
```

#### フィルタを指定して検索

```powershell
## フィルタを指定して検索
Get-ChildItem -Path 'C:\Users\admin\Pictures' -Filter *.jpg?

### 一番短い記述
dir C:\Users\admin\Pictures *.jpg?
```

#### 複数の拡張子で絞り込む

```powershell
## 複数の拡張子で絞り込む
dir C:\Users\admin\Pictures -File -Recurse -Include *.jpg, *.jpeg, *.png
```

# 参考サイト

- [ディレクトリのみ、ファイルのみの一覧を表示する方法][]
- [Measure-Object][]
- [【PowerShell】Get-ChildItemで特定のファイル・フォルダの絞り込み、除外方法 - buralog](https://buralog.jp/powershell-get-childitem-include-exclude/)
- [PowerShell の Get-ChildItem の -Filter の挙動 #PowerShell - Qiita](https://qiita.com/ayweak/items/5b8a9a4d4bfa38f7697b)
- [Powershellによるファイル操作のまとめ #PowerShell - Qiita](https://qiita.com/mima_ita/items/ae31f3a19389e69b307f#表示内容を絞りこむ)

[ディレクトリのみ、ファイルのみの一覧を表示する方法]: <https://win.just4fun.biz/?PowerShell/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E3%81%BF%E3%80%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%81%BF%E3%81%AE%E4%B8%80%E8%A6%A7%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95>
[Measure-Object]: <https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/Measure-Object?view=powershell-6>
Laravel5.8.4で追加されたCollectionのjoinメソッド

[Laravel 5.8.4がリリース](https://github.com/laravel/framework/releases/tag/v5.8.4)されたので変更点を確認。

Collectionにjoinメソッド追加したよ的な記述があったので、implodeのaliasかなと思ったのですがコードをみるとちょっと挙動が違う。

確認したのでメモです。

まずはシンプルなコレクションを用意

```php
>>> $collection = collect([1, 2, 3, 4, 5]);
=> Illuminate\Support\Collection {#3141
     all: [
       1,
       2,
       3,
       4,
       5,
     ],
   }
```

`,`で繋げてみる。これは両方同じ

```php
>>> $collection->implode(', ');
=> "1, 2, 3, 4, 5"
>>> $collection->join(', ');
=> "1, 2, 3, 4, 5"
```

joinではもうひとつ引数を追加できる。日本語だと使いどころが無さそう気がする。

```php
>>> $collection->join(', ', ' and ');
=> "1, 2, 3, 4 and 5"
>>> $collection->join('と', 'そして');
=> "1と2と3と4そして5"
```

ちょっと複雑なコレクションを用意

```php
>>> $collection = collect([
...      ['account_id' => 1, 'product' => 'Desk'],
...      ['account_id' => 2, 'product' => 'Chair'],
...      ['account_id' => 3, 'product' => 'Hoge'],
... ]);
=> Illuminate\Support\Collection {#3168
     all: [
       [
         "account_id" => 1,
         "product" => "Desk",
       ],
       [
         "account_id" => 2,
         "product" => "Chair",
       ],
       [
         "account_id" => 3,
         "product" => "Hoge",
       ],
     ],
   }
```

implodeだと抜きだすキーを指定できますが、joinはできません

```php
>>> $collection->implode('product', ', ')
=> "Desk, Chair, Hoge"
>>> $collection->join('product', ', ')
PHP Notice:  Array to string conversion in ...
```

joinでやるならpluckメソッドと組み合わせてこんな感じ

```php
>>> $collection->pluck('product')->join(', ')
=> "Desk, Chair, Hoge"
>>> $collection->pluck('product')->join(', ', ' and ')
=> "Desk, Chair and Hoge"
```

join追加されましたがimplodeのaliasでは無いってことと使い所は無いかもってことがわかりました！
php -S でローカルに簡易Webサーバーを立ち上げる時は

`localhost` ではなく `xxx.xxx.xxx.xxx` （IPアドレス）を指定しないと、アセットファイルなどがうまく読み込めない。

```shell
$ php -v 
PHP 7.1.16 (cli) (built: Mar 31 2018 02:59:59) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
```

```shell
$ php -S 127.0.0.1:8888
PHP 7.1.16 Development Server started at Wed Mar 13 10:39:56 2019
Listening on http://127.0.0.1:8888
Document root is /path/to/xxx
Press Ctrl-C to quit.
```
Docker run 色々

##1.通常起動##

centos を起動する。

```
$ docker run centos
```


##2.起動して潜り込む##

test1 という名前で Docker を作成し、-it で潜り込み、/bin/bash で bash を起動する。

ついでに、ping を試してみる。

抜ける際は、
Ctrl+C　　→　コンテナが停止してしまう
Ctrl+Q+P　→　プロセスだけ終了して、コンテナから抜ける

```
$ docker run -it --name test1 centos /bin/bash
[root@a4bed25211732]#ping 8.8.8.8
```


##3.バックグラウンド実行##

バックグラウンドで、コンテナを作成して起動する。
localhost に ping を打ち続ける。

-it をつけないと出力結果をコンソール上で確認できないので、docker logs で確認してみる。

```
$ docker run -d --name test2 centos /bin/ping localhost
$ docker logs test2
```


##4.ネットワークの設定##

ホストOSのポート8080にアクセスするとコンテナのポート80で動いているhttpサービスにアクセスするポート転送

docker ps で 0.0.0.0/8080->80/tcp とポート転送されていること確認する。

```
$ docker run -it  --name test3 -p 8080:80 httpd /bin/bash
root@879865a143a0:/usr/local/apache2# 
$ docker ps
```


##5.環境変数の設定##

-e で環境変数を設定できる。

set コマンドで確認してみる。

```
$ docker run -it --name test4 -e hoge=hoge centos /bin/bash
[root@7f4a0adede00 /]# set |grep hoge
hoge=hogehoge
```


##6.ボリュームの割り当て##

-vオプションでコンテナにボリュームを割り当てる。
ここでは、/home/<アカウント名>/sample を /opt へマウントし、sample.txtが見えていることを確認する。

```
$ mkdir sample
$ cd sample/
$ touch sample.txt
$ ls
sample.txt

$ docker run -it --name test5 -v /home/<アカウント名>/sample:/opt ubuntu
root@77851efa9a86:/# cd /opt/
root@77851efa9a86:/opt# ls
```
PHPUnitをしていたらMaximum function nesting level of 'xxx' reached, aborting!となったときの対応方法

# 事象 : トレイトを使ってテストをしていたら怒られた
```php
Testing started at 10:12 ...
path\to\xampp\php\php.exe path/to/vendor/phpunit/phpunit/phpunit --no-configuration ...
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.

PHP Fatal error:  Maximum function nesting level of '256' reached, aborting! in path\to\vendor\laravel\framework\src\Illuminate\Support\helpers.php on line 1106
PHP Stack trace:
PHP   1. {main}() path\to\vendor\phpunit\phpunit\phpunit:0
//..省略..
PHP 256. trait_uses_recursive($trait = *uninitialized*) path\to\vendor\laravel\framework\src\Illuminate\Support\helpers.php:1109
```

## 原因 : 実行したループが多すぎるから
> 注意: 100 から 200 を超えるようなレベルの再帰呼び出しは避けてください。そんなことをすると、 スタックが破壊され、スクリプトが異常終了してしまいます。 無限に続くような再帰処理は、プログラミングの間違いでしょう。
> [PHP: ユーザー定義関数 - Manual](https://secure.php.net/manual/ja/functions.user-defined.php)

## 一時的対策 : XDebugの設定でループカウントを上げる
[PHP - Fatal error: Maximum function nesting level of &#039;100&#039; reached, aborting!｜teratail](https://teratail.com/questions/169)

```ini:php.ini
[XDebug]
;他の設定は省略
xdebug.max_nesting_level=300
```
Gitで間違えてmasterで開発進めちゃった！どうしよう！(初心者向け)

# こんなときに

リモートのmasterをpullし、ローカルにdevという名前でブランチを切って開発しようと思った
でも実はmasterブランチで作業してしまっていた
もう何件かコミットしちゃった
幸いまだpushはしてない

# 方法
```shell

# 間違って進めてしまったローカルのmasterを開発用のブランチに切り直す
git checkout -b dev

# ローカルのmasterを消す
git branch -d master

# ローカルのmasterを復活させる
git branch master origin/master
```

# おわりに

「git master 間違えた」で検索すると以下がトップヒットします。

[Gitでブランチを作るのを忘れてmasterにコミットしてしまったときの対処法](https://qiita.com/atskimura/items/a90dfa8bfc72e3657ef9)

この方法だとコミットのハッシュを調べたり、cherry-pick使ったりと、初心者には難解です。また、masterに重ねてしまったコミットの数だけcherry-pickを繰り返す必要があります。

単にmaster上でコミットを進めてしまって、ブランチを切り直したいだけなら、上記の方法が理解しやすく、良いと思います。

### ちなみに
`git reset --hard`を用いると2コマンドに短縮できますが、覚えたての頃にこれを多用すると思わぬコミットの損失に繋がりかねないので、本記事では提案していません。