OmniAICreator/Qiita-1.07M huggingface dataset:
Java 融通がきかないStringクラスのsubstring

**JDK 1.8**で書いています。
# `String`クラスの`substring`
`String`クラスには、文字列の一部を切り出す`substring`メソッドがあります。引数の数に応じて２種類の切り出し方をしてくれます。
## 引数が１つの場合
**定義**

```java
    substring(int beginIndex)
```
`beginIndex`以降の文字を切り出してくれる。文字列のインデックスは`0`から数えることに注意。

**使用例**

```java
    String str = ("ドラえもん");
    String cutStr = str.substring(2);
    System.out.println("切り出し後：" + cutStr);
```
**結果**

```
    切り出し後：えもん
```
指定しているインデックス`2`にある文字`え`以降の文字列が切り出される。
## 引数が２つの場合
**定義**

```java
    substring(int beginIndex, int endIndex)
```
`beginIndex`以降の文字を`endIndex-1`の文字まで含めて切り出してくれる。
**使用例**

```java
    String str = ("ドラえもん");
    String cutStr = str.substring(2, 4);
    System.out.println("切り出し後：" + cutStr);
```
**結果**

```
    切り出し後：えも
```
指定している`beginIndex = 2`にある文字`え`以降から、`endIndex - 1 = 3`にある文字`も`までの文字列`えも`が切り出される。
# ここが微妙
引数が２つの場合、文字列が`endIndex - 1`に満たない長さの場合、例外が出ます。
### ユースケース
画面表示する文字列を出力する。画面には4文字までしか表示できない制限があるため、出力する文字列を4文字までに絞りたい。もし4文字に満たない文字列であればそのまま出したい。

**コード**

```java

    String str1 = ("ドラえもん");
    String str2 = ("のび太");
    String str3 = ("スネ夫");

    List<String> sourceStrList = Arrays.asList(str1, str2, str3);
    List<String> outStrList = new ArrayList<>();

    for (String sourceStr : sourceStrList) {
        outStrList.add(sourceStr.substring(0, 4));
    }

    System.out.println("切り出し後：" + outStrList);
```
**結果**

```
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
```
はい、例外発生。ここでは`のび太`と`スネ夫`はインデックスが`2`までしかないので、`endIndex - 1 = 3`に満たないため、例外になるのです。
解消するには事前に文字の長さを調べる必要があるので面倒くさいですね～。
# `StringUtils`の`substring`を使って解決
`org.apache.commons.lang3.StringUtils`に用意されている`substring`を使えば、この辺の気をきかして解決してくれます。

```java
    substring(String str, int start, int end)
```

`str`に入れた切り出し対象の文字列のインデックスが`start`から`end - 1`の文字列が出力されます。

**コード**

```java
    String str1 = ("ドラえもん");
    String str2 = ("のび太");
    String str3 = ("スネ夫");

    List<String> sourceStrList = Arrays.asList(str1, str2, str3);
    List<String> outStrList = new ArrayList<>();

    for (String sourceStr : sourceStrList) {
        outStrList.add(StringUtils.substring(sourceStr, 0, 4));
    }

    System.out.println("切り出し後:" + outStrList);
```

**結果**

```
    切り出し後[ドラえも, のび太, スネ夫]
```

`end - 1 = 3`に満たない文字列も、そのまま出力してくれます。
# 参考
[java.lang String substring](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#substring-int-int-)
[org.apache.commons.lang3 Class StringUtils substring](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#substring-java.lang.String-int-int-)
react-native-google-signin で GoogleService-Info.plist を環境ごとに切り替える

[react-native-google-signin](https://github.com/react-native-community/react-native-google-signin) で、環境ごとに `GoogleService-Info.plist` を切り替えたい。

無理やりだが、下記で実現した。これしかないみたい。

- GoogleService-Info.plist を `.gitignore` に追加
- `echo > ios/GoogleService-Info.plist` などとして、空の `GoogleService-Info.plist` を作成する
- `open ios` して、 `GoogleService-Info.plist` を Xcode に追加
- Xcode にて、下記の Build Phase を一番上に設定する

```sh
# @see:
# - https://github.com/react-native-community/react-native-google-signin/pull/576
# - https://stackoverflow.com/questions/37615405/use-different-googleservice-info-plist-for-different-build-schemes/48789232#48789232

set -eux

DEV_GOOGLE_PLIST="${PROJECT_DIR}/GoogleService-Info-Dev.plist"
PROD_GOOGLE_PLIST="${PROJECT_DIR}/GoogleService-Info-Prod.plist"
GOOGLE_PLIST_PATH="${PROJECT_DIR}/GoogleService-Info.plist"
ERROR_MESSAGE="ERROR: ${CONFIGURATION} should be either 'Debug' or 'Production' in Build Phase 'Copy Google plist'"

case "${CONFIGURATION}" in
  'Debug') cp -r $DEV_GOOGLE_PLIST $GOOGLE_PLIST_PATH ;;
  'Production') cp -r $PROD_GOOGLE_PLIST $GOOGLE_PLIST_PATH ;;
  *) echo $ERROR_MESSAGE; exit 1;;
esac
```

個人的には、下記のプルリクがマージされてほしかった。

https://github.com/react-native-community/react-native-google-signin/pull/576
Swift MkMapViewで地図アプリ作成してみた（05）- トラッキングモードを切り替える（自動）

#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)

#補足
[（04）- トラッキングモードを切り替える（自作ボタン）](https://qiita.com/rain_00_00_09/items/d6fad14a81250c2a346b)では自作のボタンと切り替え処理を実装しましたが、今回はMKUserTrackingButtonで自動にトラッキングモードを切り替える方法を記事にします。

#MKUserTrackingButtonでボタンを表示する

MKUserTrackingButtonでトラッキングボタンを表示する。

```swift:ViewController.swift：MKUserTrackingButtonでトラッキングボタンを表示する
// トラッキングボタン表示
let trakingBtn = MKUserTrackingButton(mapView: mapView)
trakingBtn.layer.backgroundColor = UIColor(white: 1, alpha: 0.7).cgColor
self.view.addSubview(trakingBtn)
```

シミュレータを起動すると以下の様に表示されるが、ボタンを押してもトラッキングモードは切り替わらない。

<img width="750" alt="image3.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/dc13c1a9-63cf-1def-ff0a-87bb2ac0bf1e.png">

ボタンは押せないが、スクロールするとトラッキングボタンの表示がスクロールモードに切り替わる。

<img width="750" alt="image4.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/04df0256-888e-8e57-8eb3-95252ae09fbb.png">

トラッキングモードの状態を検出してボタン表示が自動で切り替わる事が分かる。
ボタンが押せないのは配置した位置（default）が問題の様だ。

#ボタンの位置を変更する

trakingBtn.frameで表示位置とサイズを指定する。

```swift:ViewController.swift：trakingBtn.frameで表示位置とサイズを指定する
let trakingBtn = MKUserTrackingButton(mapView: mapView)
trakingBtn.layer.backgroundColor = UIColor(white: 1, alpha: 0.7).cgColor
trakingBtn.frame = CGRect(x:40, y:730, width:40, height:40)
self.view.addSubview(trakingBtn)
```

実行した結果は以下の様になる。

＜ヘディングアップ＞
<img width="750" alt="image6.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/5a127a26-ee91-cda4-62bc-f69b8a669a5e.png">

＜スクロールモード＞
<img width="750" alt="image7.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/a715251e-9a44-4dfc-f070-68703935e19d.png">
　alpha: 0.7で透過されている。
　1.0（透過しない）〜0.1（最も透過）となる。

＜ノースアップ＞
<img width="750" alt="image5.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/00df968d-e7ac-2d4e-f717-8e238a7c8b24.png">

#固有デバイスの画面サイズに依存しない様にボタンを配置する

デバイスの画面サイズを取得して、width/height終端からの差分を指定してオブジェクトを配置する。
今回は左下に配置したいので、height終端からの差分を指定する。

```swift:ViewController.swift：デバイスの画面サイズを取得する
// デバイスの画面サイズを取得する
let dispSize: CGSize = UIScreen.main.bounds.size
let height = Int(dispSize.height)
```

```swift:ViewController.swift：ボタンを配置する
trakingBtn.frame = CGRect(x:40, y:height - 82, width:40, height:40)
```

iPhoneXだとheightは812なので、上記の画像と同じ位置に表示される。


#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)
kindle出版手順

# kindle出版手順 

## mdファイルからepubを作成して一旦修正してmobiに変換する手順

markdownで原稿作成しているものとする。
`EPUB/` ディレクトリを作成してそこで後作業をする。

1. 原稿の .md ファイルの他に表紙の画像と metadata.yaml も用意して

```sh
pandoc metadata.yaml chapter1.md chapter2.md chapter3.md -o EPUB/MyBook1.epub -t epub3 --toc --toc-depth=2 --epub-chapter-leve=2 --epub-cover-image=EPUB0/hyoushi1.jpg
```

のようにして epub に出力する。

metadata.yamlの中身

```yaml
---
title:  'わたしの素晴らしい本'
author: わたし

---
```

2. `EPUB/X2/` というディレクトリを作成しておいて、cdしてepubを一回バラす。

```sh
mkdir EPUB/X2
cd !$
unzip ../MyBook1.epub
``` 

3. `EPUB/X/` というディレクトリの方に改変済み epub ソースが展開されており（後述）、それに新規追加・修正分を反映させてゆく。
この例では `EPUB/X/EPUB/text/` 以下が xhtml ソース、 `EPUB/X/EPUB/media/` 以下が画像など。

4. `EPUB/X/` を更新したら epub を作成し直す。

```sh
cd ../X/
zip -0 ../MyBook2.epub mimetype
zip -r ../MyBook2.epub *~mimetype
cd ..
kindlegen MyBook2.epub -o MyBook2.mobi -locale ja
```

5. kindle Previewer で確認する。

6. KDPで出版して放置


## mathml の編集

md の数式は epub の mathml に変換されているはずで大雑把に以下のような構造のはず。

```
<p>
 <math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
  <semantics>
  <mrow>
   （なにかMathML形式の数式）
  </mrow>
   <annotation encoding="application/x-tex">
    （なにかTeX形式の数式）
   </annotation>
  </semantics>
 </math>
</p>
```

とりあえず数式部は、 md から tex 経由して pdf にしておき、スクリーンショット撮って切り出しておき、
annotationの中身をaltに指定してimgタグで貼っておく。

```
<p><img src="../media/EQ1.png" alt="（うえのTeX形式の数式）" /></p>
```

画像へのパスは上のようになる。
`EPUB/X/EPUB/content.opf` というファイルも修正して、追加した画像ファイルを登録しておく。
ExcelデータをSparkで読む方法（Spark1, RDD）

summary

#### 1. csv を RDD に読む

```python
In [1]: import csv
In [2]: rdd  = sc.textFile('testdata1.csv')
In [3]: rdd2 = rdd.mapPartitions(lambda x: csv.reader(x))
```

#### 2. csv を pandas dataframe に読み spark dataframe に移す

```python
In [1]: import pandas as pd
In [2]: pdf=pd.read_csv('testdata1.csv')
In [3]: sdf = sqlContext.createDataFrame(pdf)
```

#### 3. excel ファイルを pandas dataframe に読み spark dataframe に移す

```python
In [1]: import pandas as pd
In [2]: pde=pd.ExcelFile('testdata1.xlsx')
In [3]: pds=pde.parse(pde.sheet_names[0], skiprows=1)
In [4]: sdf = sqlContext.createDataFrame(pds)
```

#### 4. csv を spark dataframe に読む

```python
In [1]: df = spark.read.csv('testdata1.csv', header=True, inferSchema=True, mode="DROPMALFORMED", encoding='UTF-8')
```
Failed to load resource: the server responded with a status of 404 (Not Found)の原因と解決策

##問題：画像が表示できない

![image.png](https://qiita-image-store.s3.amazonaws.com/0/288657/85fc4837-dac0-1c27-adbd-116bab587ef8.png)


#エラー
```
Failed to load resource: the server responded with a status of 404 (Not Found)
```
404 (Not Found)は、ファイルが見つからないという意味。
推定原因は、２つあるらしい。

①ファイルがデータベースに保存されていない
②画像がDBに保存されているけど、パスがずれてる

ファイルは保存できていた。なので、原因は、②。
参照記事：https://teratail.com/questions/3951



###パスの確認
```views/user/show.html.erb
<img src="<%= "/img/#{@user.id}"%>">
```



##解決策
/img/#{@user.id}に、jpgを付け加えてみたら、パスが特定されて、無事画像が表示された。

```views/user/show.html.erb
<img src="<%= "/img/#{@user.id}.jpg"%>">
```
Go言語のSlice

Go言語のSliceもよく使うタイプです。
Arrayと似ているのですが、Array型ではないです。
中ではArrayを使っています。可変長の配列Arrayの場合はSlice型でよいでしょう

#Slice定義方法
例：

```go
var slice1 []int
fmt.Println(slice1)
```

出力：
>[]

#配列から抽出してSlice生成
配列変数名[開始index:終了index]
開始indexと終了indexは省略可能です。
また終了indexの要素は含まないです。

開始indexがない場合は、[0:終了index]と同じで、最初から終了indexまで
終了indexがない場合は、[開始index:配列長さ]と同じで、開始indexから最後まで

例1：

```go
var months = [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
var slice1 = months[4:10]
fmt.Println(slice1)
```

出力：
>[5 6 7 8 9 10]



例2：

```go
var months = [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
var slice1 = months[:]
fmt.Println(slice1)
```

出力：
>[1 2 3 4 5 6 7 8 9 10 11 12]


例3：

```go
var months = [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
var slice1 = months[:6]
fmt.Println(slice1)
```

出力：
>[1 2 3 4 5 6]

例４：

```go
var months = [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
var slice1 = months[6:]
fmt.Println(slice1)
```

出力：
>[7 8 9 10 11 12]

#make関数で生成
var 変数名 = make([]T, length, capacity)

例：

```go

var slice1 = make([]int, 10, 20)
fmt.Println(slice1)
```

出力：
>[0 0 0 0 0 0 0 0 0 0]

#Sliceメソッド
##長さ：len(変数名)
例：

```go
var slice1 = make([]int, 10, 20)
fmt.Println(len(slice1))
```

出力：
>10

##容量：cap(変数名)
例：

```go
var slice1 = make([]int, 10, 20)
fmt.Println(cap(slice1))
```

出力：
>20

##Reslice
例：

```go
var slice1 = make([]int, 10, 20)
var slice2 = slice1[8:10]
fmt.Println(slice2)
fmt.Println("len:", len(slice2))
fmt.Println("cap:", cap(slice2))
```

出力：
>[0 0]
>len: 2
>cap: 12

特に容量は、元Sliceの最後までの数です。
slice2は、8～20までの数は12です。


##Append:要素追加
例１：

```go
var slice1 = make([]int, 10, 20)
slice1 = append(slice1, 11, 22, 33)
fmt.Println(slice1)
fmt.Println("len:", len(slice1))
fmt.Println("cap:", cap(slice1))
fmt.Printf("address:%p\n", slice1)
```

出力：
>[0 0 0 0 0 0 0 0 0 0 11 22 33]
>len: 13
>cap: 20
>address:0xc000092000

容量は変わっていないです。


例２：

```go
var slice1 = make([]int, 10, 20)
slice1 = append(slice1, 11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 111)
fmt.Println(slice1)
fmt.Println("len:", len(slice1))
fmt.Println("cap:", cap(slice1))
fmt.Printf("address:%p\n", slice1)
```

出力：
>[0 0 0 0 0 0 0 0 0 0 11 22 33 44 55 66 77 88 99 100 111]
>len: 21
>cap: 40
>address:0xc00007e000

容量は変わると、メモリアドレスも変わります。

##copy:copy(コピー先, コピー元)
copy(toSlice, fromSlice)

例：

```go
var slice1 = []int{1, 2, 3, 4, 5}
var slice2 = []int{6, 7, 8}

copy(slice1, slice2)
fmt.Println("slice1:", slice1)
fmt.Println("slice2:", slice2)

var slice3 = []int{1, 2, 3, 4, 5}
var slice4 = []int{6, 7, 8}
copy(slice4, slice3)
fmt.Println("slice3:", slice3)
fmt.Println("slice4:", slice4)
```

出力：
>slice1: [6 7 8 4 5]
>slice2: [6 7 8]
>slice3: [1 2 3 4 5]
>slice4: [1 2 3]

copy関数はsliceの長さは変更しないです。コピー先に長さまでコピーします。

以上
リリース前に知っておきたかった iOS / Android 自動更新購読（月額）の有効期限の罠

アプリの月額課金についてたくさん調べて実装し、ようやくリリースまでこぎつけて、リリース後大きな不具合もなく安心していたのも束の間、月初の昨日（3/1）に有効期限の罠にハマったので記録しておきます。
解決方法はまだ決定できていません。

1ヶ月以外の購読期間についてはわからないです。

# 前提と事の発端
- アプリ内に開始日と有効期限日を表示している（例・開始は2/15　有効期限は3/15）
- 有効期限はストアから発行されたレシートの情報を元にしている
- アプリ内の注意書きに「有効期限は開始日の翌月同日まで」と表記している
- ここは日本

ユーザからの**「3/1に開始したのに有効期限が3/29と表示されている。どういうことか」**という問い合わせで何かが起きていることが発覚。調査を開始しました。

# 結論からいうと

プラットフォーム |開始日時 |有効期限日
:-:|---|:-:
iOS |3/1 0:00~**16:59** |3/29
iOS|3/1 **17**:00~ |4/1
Android |3/1 0:00~**8:59** |3/29
Android|3/1 **9**:00~ |4/1

※ プラットフォームごとに数時間のズレがあるため厳密には上の通りではありません。後述します。

どういうことかというと、ストア側とは国による時差があり上記時間帯ではストア側はまだ**2/28**。
iOSでは17時間（Apple本社がカリフォルニア州だから？）、Androidでは9時間（標準時）の時差がありました。
ストアとしては2/28に開始したのだから期限は当然3/28になり、時間によっては日本時間で3/29になります。

たとえばiOSの場合、日本時間で16:59に開始したユーザと17:00に開始したユーザで有効期限に3日間も差があることに。
23:59と0:00で差ができるのはユーザとして納得しますが、今回のようなのは痛いです。
実装当時は考えが及びませんでした。

# 解決案
チームでいくつかあがった解決案。どれも根本解決でないし、前述のとおりまだ方針は決定していません。

### アプリ側で有効期限を設定する
ストアのレシート情報を無視して、開始日から1ヶ月分起算して期限を設定する案。
今回の場合は永遠にストアと3日の差が出続けます。
でもそうするべきだったのかもしれません。

### アプリ内の有効期限表示をなくす
完全に逃げ

# 余談
このようなイレギュラー（？）な場合にかかわらず、iOSとAndroidでは有効期限の時間に差があります。

- iOS: `開始日時 + 1ヶ月 - 1時間`（例・2/15 14:00に開始 → 3/15 **13:00**が期限）
- Android: `開始日時 + 1ヶ月 + 2時間`（例・2/15 14:00に開始 → 3/15 **16:00**が期限）

Androidの方がiOSに比べて3時間優しい仕様になっています。
22:00 ~ 1:00あたりの登録で日付に齟齬が生じることがあるので注意が必要です。

この時間差については検証時のテストアカウントでは発見できません。
公式リファレンスに明記しておいてほしかったです。見逃したのかな？

# 余談2
上で公式リファレンスを軽くdisっていますが、課金の実装で一番大切なのは公式リファレンスを読みまくることです。
大変わかりづらく書かれていたりしますが、何度も何度も読むことをおすすめします。
ちゃんと読むと必要なことは書かれています。
js 分割代入 {}


https://cointrader.co.jp/botdev/

勉強中です
#疑問

```js
const {trade} = require('cointrader')
```

はい、意味が分かりません

---

ググったワード
const {}

検索結果４番目
https://ushumpei.hatenablog.com/entry/2016/06/29/032906

複雑で理解できませんでした。が、
・分割代入である
・分割代入 - JavaScript | MDN＜＝このページをみればよい
ということがわかりました。

---

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

オブジェクトの分割代入という項目を発見
これこれ、こういうのが欲しいの

>簡単な例

>```js
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
```

---

完全に理解した。超簡単に書くと

```js
{a} = {a: "hoge"}
```

で、右辺にオブジェクト、左辺にオブジェクトのキーを書けば、値を取得できる。
ここで、objectってkeyとvalueのペアであっているのかという疑問が生じる。。。
私の頭は容量が少なすぎて、簡単な言葉で説明できないと記憶してくれません。てことで後で調べる。

ということで試しにオンラインエディタで実行

https://playcode.io/online-javascript-editor

```js
const {a} = {a: "hello"}
console.log(a);

---
hello
```

はい、OK
ここまで１０分でできたOK、OK
てことで次はObjectについて。
Pythonで配列の中身をprintするときの実行速度比較

#Pythonで配列の中身をprintするときの実行速度比較
例えば、配列`hoge`があったとして、その中身をすべて出力したいとする。そんな時いくつかコードの書き方が考えられると思うが、それぞれ実行速度はどれくらい違うのか計測した。
##テスト環境

|OS|CPU|Pythonバージョン|
|---|---|---|
|Windows10 home 64bit|intel Core i5 7500|3.7.1|

##計測方法
以下のように`time.perf_counter()`を使って計測した。

```
time_start = time.perf_counter()
#時間計測したいコード
tim = time.perf_counter()- time_start
```


##1次元配列の場合
###出力フォーマット
`hoge = [1, 2, 3, 4, 5]`だとしたら、

```
1
2
3
4
5
```

のように要素ごとに改行して出力するようなコードの書き方を比較する。
###テストした内容
今回測定したパターンは以下の3通り。`hoge`は配列

```
#パターン1
length = len(hoge)
for i in range(length):
    print(hoge(i))
```

```
#パターン2
for i in hoge:
    print(i)
```

```
#パターン3
for i in hoge:
    print("{}".format(i))
```

※追記
別パターンのアイデアをコメントでもらったので以下2つも試してみる。

```
#パターン4
print(*hoge, sep='\n')
```

```
#パターン5
print('\n'.join(map(str, hoge)))
```


ファイル出力で計測する場合はリダイレクトを使った。


###テスト結果
hogeを`hoge = [i for i in range(L)]`として作成しそれぞれのパターンを3回テストして平均をとった。
####標準出力の場合（L = 1000）
パターン1：0.423026890966[sec]
パターン2：0.406021656333[sec]
パターン3：0.411023060333[sec]
パターン4：0.427671138[sec]
パターン5：0.007100579333[sec]

やはり長さが1000程度の配列ではそれほど差は出ないようである。

<b>パターン5の</b>　`print('\n'.join(map(str, hoge)))`　<b>が他の追随を許さないレベルで速い！！！</b>
これほどまでに大きな差が出た原因としては、他のパターンがprint()関数をL回呼び出しているのに対し、パターン5は配列をjoin()で一つの文字列に結合してからprint()するので、print()関数の呼び出しが1回で済むというのが大きいのだろう。


####ファイル出力の場合（L = 1000000）
パターン1：1.2381535143333335[sec]
パターン2：1.1619043353333334[sec]
パターン3：1.4380140773333334[sec]
パターン4：1.0475442879999[sec]
パターン5：0.27567296[sec]

パターン1は2回参照しているが意外にもまあまあの速度である。

一番早いのは一番単純な書き方であるパターン2となった。

<b>やはりパターン5の</b>　`print('\n'.join(map(str, hoge)))`　<b>が速い！！！</b>
formatを使ったパターン3は一番遅い結果となった。

##2次元配列の場合は？
このままではformatが不憫な結果で終わってしまいそうなので2次元配列の場合についても検証した。
hoge を N×L の配列とする。

###出力フォーマット
`hoge = [[1, 2], [3, 4], [5, 6]]` だとしたら、

```
1 2
3 4
5 6
```
のような出力をするコードの書き方について比較する。

###テストした内容
今回はパターン1は割愛.
N=2の場合の例。

```
#パターン2
for i in hoge:
    print(i[0], i[1])
```

```
#パターン3
for i in hoge:
    print("{} {}".format(i[0], i[1]))
```

※追記
1次元配列のテスト結果からprint()関数を呼ぶ回数が問題であると予想して、以下のようにprint()を1度しか呼ばないパターンを作ってみた。これをパターン4とする。

```
#パターン4
fuga = [" ".join(map(str, i))  for i in hoge]
print('\n'.join(map(str, fuga)))
```



###テスト結果
####ファイル出力（N = 2, L = 1000000）
パターン2：2.13243174633[sec]
パターン3：1.600395958[sec]
お、結構差が出る結果になった。N=2でだいたい0.5秒ぐらいの差である。これはNが大きくなるほど差が広がるのでは？と思ってN=5の場合についても調査した。

####ファイル出力（N = 5, L = 1000000）
パターン2：4.422985526[sec]
パターン3：2.030369288[sec]
予想はあたりのようで、N=5の場合はなんと倍以上の差が出た。

####パターン4の結果（ファイル出力、N = 5, L = 1000000）
パターン4：1.5420818646666667[sec]
<b>formatを使った場合よりもさらに0.5秒ほど速い！！！</b>
しかし思ったよりは速くなってはいない印象である。print()を1000000回呼ぶのと、join()を5000000回呼ぶのにかかる時間の差がだいたいこれぐらいってことか？

##まとめ
- 
1次元配列をprintする場合は、`for i in hoge:    print(i)`が速いが、他と比べてそこまで差はない。

   - join()で結合してから一気にprint()するのが圧倒的に早いです。
- 
2次元配列の場合は、1次元目の長さが分かっているならformatを使ってprintするのが速い。

   - 2次元の場合でも、なるべくjoin()で結合してからprint()した方が速い！
Arch Linux インストールメモ

# Arch Linux インストールメモ

:warning::warning::warning:クリーンインストール前提！**大切なファイルがないかどうかをしっかり確認してから実施すること！/dev/sda1と/dev/sda2が初期化される！！！**:warning::warning::warning:

デュアルブートが必要な場合はgdiskの部分を工夫する（具体的には、別のOSがインストールされている部分は削除しない、/dev/sdaの番号をずらして以下の手順に従う、など）。

**※ /dev/sda9は共有パーティションとしてすでに確保済みとする(必須ではないがあると便利)。**

インストール用イメージを[ここ](http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/iso/latest/)から取得し、ブートUSBを作っておきます。

## 構成

/dev/sda1 /boot 128MB vfat
/dev/sda2 / 40GB xfs

UEFIブート

Wi-Fi自動接続

ウインドウマネージャ: XMonad (キーマップは[ここ](https://github.com/matoruru/dotfiles/blob/master/.xmonad/xmonad.hs#L83)を参照)
ステータスバー: Polybar（[テーマ](https://qiita.com/matoruru/items/ab491eac6b2b74e3ce3b)）
ターミナルエミュレータ: Kitty
エディタ: Neovim

## 手順

### 1. Wi-Fi接続する([参考](https://qiita.com/matoruru/items/6fcd2f419688e9cabb64))

wifi-menu⏎
ip a⏎

### 2. パーティション作成

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/2.sh) +40G⏎

### 3. フォーマット & マウント

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/3.sh) ⏎

### 4. 時刻同期設定(NTP)

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/4.sh) ⏎

### 5. Pacmanのサーバ設定(日本のServerを上に移動させる)

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/5.sh) ⏎

### 6. 基本パッケージの事前インストール

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/6.sh) ⏎

### 7. マウント設定

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/7.sh) ⏎

arch-chroot /mnt ⏎

### 8. 地域設定

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/8.sh) ⏎

### 9. localhost設定

「HOSTNAME」はマシンのホスト名になる。自由に変えていい。

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/9.sh) HOSTNAME⏎

### 10. ブート設定

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/10.sh) ⏎

### 11. Wi-Fiの自動接続設定([詳しくはココ](https://qiita.com/matoruru/items/6fcd2f419688e9cabb64))

※wlp2s0はインタフェース名の例。

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/11.sh) wlp2s0⏎

#### *backupがある場合*

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/11b.sh) ⏎

### rootパスワード設定

echo "root:PASSWORD" | chpasswd⏎

### 12. ユーザ作成 & パスワード設定

パスワードを指定しなかった場合、デフォルトパスワードは「password」になる。

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/12.sh) USERNAME PASSWORD⏎

### 13. pacmanの設定

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/13.sh) ⏎

### 14. ssh設定

#### *backupがある場合*

bash <(curl -s https://raw.githubusercontent.com/matoruru/arch-tools/master/steps/14.sh) ⏎

### 15. インストールスクリプト実行
bash <(curl -s https://raw.githubusercontent.com/matoruru/dotfiles/master/install.sh) ⏎
（備忘録）Google Colaboratory Jupyter Notebook を用いた機械学習（ML）

# 1. はじめに
2019年3月2日に[UEQareer](https://ueqareer.connpass.com/)様主催にて開催された[機械学習（ML）勉強会](https://ueqareer.connpass.com/event/120350/)でのGoogle Colaboratory Jupyter Notebook を用いた機械学習（ML）について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

# 2. 学べる内容

- 画像からの顔検出（Python）
- 手書き数字認識（Python）
- Kerasを用いた料理写真の画像分類（Python）

# 3. 学習サイト

- [Google Colaboratoryを使って簡単に機械学習をはじめよう!!](https://ueqareer.net/2980)
- [イベントサイト](https://ueqareer.connpass.com/event/120350/)
- [イベント資料](https://ueqareer.connpass.com/event/120350/presentation/)

# 4. おわりに
機械学習（ML）学習の参考になれば幸いです。
ハンズオン開催してくださいました[UEQareer](https://ueqareer.connpass.com/)様、感謝いたします。

2019/03/02 TAKAHIRO NISHIZONO
homebrew emacs で --with-cocoa オプションの廃止

homebrew で Emacs をインストールする際に、GUI版の Emacs.app を使いたい場合に、

```
brew install emacs --with-cocoa
```

を使っていました。

しかし、2019年1月 ([#36070](https://github.com/Homebrew/homebrew-core/pull/36070)) に `--with-cocoa` オプションは廃止されていたようです。
参考: [No option --with-cocoa in Homebrew formula anymore](https://www.reddit.com/r/emacs/comments/agvx2m/no_option_withcocoa_in_homebrew_formula_anymore/)

## 解決

Emacs.app を使いたい場合は、cask で入れる等があるようです。

```
brew cask install emacs
```
[WIP]ActiveRecordでのレコード数のカウント方法の差（count, length, size）

# 
| メソッド | 機能 | キャッシュ利用 |
|:------|-----:|:---------:|
| count | SQLの`COUNT`を使ってカウント | しない |
| length | SQLの`実行結果の行数`をカウント | する |
| size | SQLの`COUNT`を使ってカウント | する |
[ActiveRecordのcountとlengthとsize](https://www.lanches.co.jp/blog/3199)


size
[Active Record の size vs count vs length をコードレベルで見てみた](https://qiita.com/diskshima/items/dc9aa0c3f131971365bc)
pd.read_csvで読み込む段階で、特定のカラムを日付型で読み込みたい！

#pd.read_csvで読み込む段階で、特定のカラムを日付型で読み込みたい！

見出しそのままです、メモ代わりに書きます。（そっけない記事でスミマセン。。。）

[こちら](https://www.nehan.io/blog/python-data-transform/id-20)を参考にさせていただきました。ありがとうございます！

結論、

### parse_datesオプション

を利用する、で1発OKです。

たとえば、こんな感じで。（"create_date"を日付型で読み込みたい場合）

```python
train_df  = pd.read_csv("train.csv" , parse_dates=["create_date"])
```

parse_dates内は、

・カラム名　

だけでなく、

・カラム番号

でもOKのようです。


以上！
Nuxtでエラー発生時のcomponentの中身を調べる方法👓

最近、nuxt.jsを触ることが多くなってきたが、生のvue.jsの時と比べて不満だったことは、 **エラーが発生した際に自動的にerror.vueにredirectする**こと。

これが
<img width="953" alt="スクリーンショット 2019-03-02 13.28.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/158393/4a2573ed-b155-3b31-63ab-892012d23524.png">

こう
<img width="774" alt="スクリーンショット 2019-03-02 13.29.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/158393/d09c348f-f043-79e8-6b5b-d554fa3eeae5.png">


いや、本番ならいいんですよ。そうするべき。やけど開発時にerror.vueにredirectすると、redirectするためpageコンポーネントがerror.vueになってしまい、エラー発生時ののpageコンポーネント（MyPage.vue）の中身を [vueのdevtool](https://github.com/vuejs/vue-devtools)で見れなくなってしまう（上記スクショの右側）。生のvueだとエラーが発生した時点でコンポーネントが固まるのでdevtoolsで見れていたので不便だなあと感じた。

```js:main.js
Vue.config.errorHandler = (err, vm, info) => {
  console.error(err, vm, info)
  alert('エラー出たってよ') 
}
```

>https://jp.vuejs.org/v2/api/index.html#errorHandler

`errorHandler`に`alert()`をぶっこむと、そこで画面が止まるのでdevtoolsでcomponentの中を調査できる🤩

<img width="876" alt="スクリーンショット 2019-03-02 13.30.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/158393/b045a81a-d243-efaf-786f-611b421fb7eb.png">


多分もっといい方法あるんで教えてエロイ人
P5.js入門（チェック柄を書いてみる）

#目次
1. はじめに
2. 導入
3. とりあえず書いてみる
4. 色の調整(map関数）
5. 紙袋柄へ

#はじめに
##対象者
・プログラミングを始めてみたい
・趣味プログラマー（僕です）
・チームラボに感動した（僕です笑）

#導入
基本的には他の記事を参照ください。
ATOM + p5xjs-autocomplete　で入力
http://blog.livedoor.jp/reona396/archives/55571609.html

Webエディターで実行、デバッグ
https://editor.p5js.org/

が楽かな〜と思ったんですが、
アドバイスあれば下さい（笑）

#とりあえず書いてみる
##何を作ろうか
これを流し読みするとよいです。
https://www.amazon.co.jp/dp/B07DQHV9GX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
マウスの座標で、色や形状を変えていく例が多く出てきますね。
同じコンセプトで作ってみましょう。

##チェック柄
実は奥が深いチェック柄
https://thequalityclothing.com/types-of-plaid/
伊勢丹の紙袋も何度かリニューアルしているらしいです。
https://matome.naver.jp/odai/2141031017954780201

新しい伊勢丹の紙袋を考えてみましょう（伊勢丹の関係者の皆様、怒らないでください）。

#コーディング
とりあえずは実行しましょう。
　・マウスx座標：マスの大きさ
　・マウスy座標：チェックの色
　・q,wキー：背景の色

```
var bg_color;　//背景色

function setup() {
  bg_color = 255;　//背景色の初期設定
  createCanvas(600, 600);
  noStroke();
  colorMode(HSB,width,height,100);
}

function draw() {
  console.log(bg_color);
  var stepX = mouseX + 2;
  background(bg_color, 100, 100);
  fill(mouseY, 100, 100);　//色の指定
  for(var gridX = 20; gridX < height; gridX += stepX){
    rect(gridX,0,20,height);　//縦線を書く
    rect(0,gridX,width,20);　//横線を書く
  }
}
function keyPressed() {
  if ((key == 'q') || (key == 'Q')) {
    bg_color += 20; //背景色の変更
  }
  if ((key == 'w') || (key == 'W')) {
    bg_color -= 20; //1背景色の変更
  }
}
```
<img width="615" alt="スクリーンショット 2019-03-02 12.57.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/245489/c497c87e-7798-7063-bffc-55441c24269c.png">

う〜ん、色の範囲狭くない？？？

#色の調整（MAP関数）
MAP関数とはなんぞや
https://www.youtube.com/watch?v=nicMAoW6u1g
英語の勉強にw
まぁ実行してみましょう。

HSBの数値の指定は・・・？
最大：360
今、HSBのHの値はマウスのy座標から引用している・・・
y座標の最大値：600（キャンバスのサイズより）

これを調整するためMAP関数を使用する。


```
var bg_color;　//背景色

function setup() {
  bg_color = 255;　//背景色の初期設定
  createCanvas(600, 600);
  noStroke();
  colorMode(HSB,width,height,100);
}

function draw() {
  var sq_color = map(mouseY,0,600,0,360) //色の範囲の設定
  console.log(sq_color);
  var stepX = mouseX + 2;
  background(bg_color, 100, 100);
  fill(sq_color, 100, 100);　//色の指定
  for(var gridX = 20; gridX < height; gridX += stepX){
    rect(gridX,0,20,height);　//縦線を書く
    rect(0,gridX,width,20);　//横線を書く
  }
}
function keyPressed() {
  if ((key == 'q') || (key == 'Q')) {
    bg_color += 20; //背景色の変更
  }
  if ((key == 'w') || (key == 'W')) {
    bg_color -= 20; //1背景色の変更
  }
}
```
色の範囲広がりましたね！

#紙袋柄へ
続きは後日・・・

全体的にもう少し加筆します。
迷路を作って解くJava実装

## 本文
- やったこと：Javaで迷路を作り、到達可能か求める（深さ優先探索 DFS）、または最短経路を求める（幅優先探索 BFS）
- ソース => [GitHub](https://github.com/expnotes9/mazesolver/blob/master/src/com/shoek/mazesolver/Maze.java)
- 実行結果 => [Ideone](https://ideone.com/xv2BL3)
- その他の入力例 => [README](https://github.com/expnotes9/mazesolver/blob/master/README.md)

## 実行時の注意
- ６つの引数が必須、順番は固定
- `-debug`で迷路・経路を標準出力に書き込める
    - ただし出力量制限はない
    - 小さい迷路から大きな迷路へ、どのくらい表示できるか確認しながら出力した方がいい
- `-debug`の代わりに`-no-denug`とか適当に入れれば標準出力OFFになる
- 大きさは2501*2501を超えた辺りから、生成の実行時間が長くてつらい
- ４つ目の引数circuitsに大きな数字を入れると、生成の実行時間が長くてやっぱりつらい
    - 100000とか無理

## 雑感
- 迷路を作る実装はレアかも
- １.最短距離と２.書き換えた経路の両方を返す方が好ましいが、面倒なのでやってない
    - [Go](http://golang.jp/effective_go#multiple-returns)とか[PythonとかRubyとか](https://hydrocul.github.io/wiki/programming_languages_diff/tuple/multiple-assignment.html)見習ってほしい



Hope this helps.
vimでGDBを使おう

驚いたあまりこの記事を書くことにしました。

頑張ってGDBのプラグインを探してたが、vim単体でGDBを使えるのは感動感激です。

忙しい人のためにvimでGDBを手軽に始める方法をご紹介します。（手抜き記事です）

# 前提
vimでGDBを使うには**vim 8.1.X**以上のバージョンで使えます。

.vimrcに次のように追加します

```vim:.vimrc
packadd termdebug 
'マウスを使用
set mouse=a
let g:termdebug_wide = 163
```
余談ですが、初めてvimのマウス操作が楽しいと思いました。

# サンプルコード
<details><summary>一応使ったサンプルのCソースを置いときますね</summary><div>

```c:timmer.c
#include <stdio.h>
#include <time.h>
#include <sys/time.h>

int main() {
	struct timeval myTime;    
	struct tm *time_st;       
	const char weekName[7][4] = {   
		"Sun",
		"Mon",
		"Tue",
		"Wed",
		"Thu",
		"Fri",
		"Sat"
	};
	gettimeofday(&myTime, NULL);    

	for(int i = 0; i < 3; i++){
		time_st = localtime(&myTime.tv_sec);    
		printf("Date : %d/%02d/%02d(%s) %02d:%02d:%02d.%06d\n",     
				time_st->tm_year+1900,     
				time_st->tm_mon+1,         
				time_st->tm_mday,          
				weekName[time_st->tm_wday],
				time_st->tm_hour,          
				time_st->tm_min,           
				time_st->tm_sec,           
				myTime.tv_usec            
			  );

	}
}
```

ソースコードをコンパイルをしてあげます。

```bash
gcc -g3 -o timmer timmer.c
```

</div></details>

# 実際動作

vimでtimmer.cを開きます。
デバッグを開始するには :Termdebug または :TermdebugCommand に続けてコマン
ド名を入力します。例:
        :Termdebug ./timmer

そこからの動作は次のとおりです。
ああ〜〜なんという素晴らしい！！
![Peek 2019-03-02 12-51.gif](https://qiita-image-store.s3.amazonaws.com/0/132812/be5ddb62-7b4f-91d6-d677-720bf8d3ed1c.gif)

ちなみにここに書かれている物は日本語ドキュメントに乗っています。
詳しく知りたければ、ご覧ください　→　https://vim-jp.org/vimdoc-ja/terminal.html#terminal-debug
picoCTF 2018 hertz 2 - Points: 200

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/583e6de6-3b45-4671-6ef3-5b7e393c49b5.png)

#解いてみた

暗号化された文章を復号する問題のようです。
接続先にアクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/74c1c7c6-2998-7445-f508-30099afcbffb.png)


最後に書かれているこれがフラグと思われます。

```
ykweWHI{pomphkhohkel_wkyrjvp_gvj_hee_jgpc_hemcojqcha}
```

picoCTFと比較してみると

|暗号文|平文|差分|
|:--|:--|:--|
|y|p|17|
|k|i|24|
|w|k|14|
|e|o|10|
|W|C|6|
|H|T|1|
|I|F|23|

んー規則性がないですね。。。
直前にある「ixgu:」っていうのは「flag:」っぽいのでこれも比較してみます。

|暗号文|平文|差分|
|:--|:--|:--|
|i|f|23|
|x|l|14|
|g|a|20|
|u|g|12|

規則性が見つかりません。
ということで前回と同じサイトを使ってみます。
前回：[picoCTF 2018 hertz - Points: 150](https://qiita.com/CTFman/items/8353a171ff09cf85ea52)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/9a6ff927-dae6-7628-659a-1cbeef0aa7f9.png)

一部？になってますが、これはyなので先ほどの対比表からpと仮定すると正解でした。
【IOST】Cloud ShellからSSHにつないでログを見てみる

##この記事でやること
1. Google Cloud ShellからSSHでVMインスタンスに接続 
2. iServerのログの格納場所を確認して開く

#Google Cloud ShellからSSHでVMインスタンスに接続 
###Google Cloud Shellとは
Cloud Shell - ブラウザベースのコマンドライン
https://cloud.google.com/shell/?hl=ja

SSHでも接続できるが、Cloud Shellだとスマホアプリ経由ででも接続できるので何かと便利。

**Google Cloud Console（iOSとAndroidどちらでもOK）**
https://itunes.apple.com/jp/app/google-cloud-console/id1005120814?mt=8
https://play.google.com/store/apps/details?id=com.google.android.apps.cloudconsole&hl=ja

###Cloud Shellを開いてSSHに接続する
![selectshell.png](https://qiita-image-store.s3.amazonaws.com/0/39453/777d70c8-aed9-e342-6ef1-9d3927e97d82.png)
画面上部メニューバー右側のコンソールアイコンをクリックして少し待つとCloud Shellが立ち上がります。
<img width="700" alt="con01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/39453/43efd28a-d24c-ed49-6f81-7213b1029dad.png">
下記コマンドを打っていきます。

```shell
gcloud compute ssh インスタンス名 --zone ゾーン
```

インスタンス名とゾーン名はそれぞれ下記の値を設定します。
![iandzone.png](https://qiita-image-store.s3.amazonaws.com/0/39453/b9986e63-f733-189c-3301-699d308894aa.png)

```shell
gcloud compute ssh iost --zone asia-northeast1-b
```

実行すると「接続のためのSSHキーを生成するよ？」と聞いてくるので「y」と入力。

```shell
being able to generate SSH keys.
Do you want to continue (Y/n)?  y
```

パスフレーズの入力を求められるので、2回同じ値を入力すると設定が完了し、SSHに接続できるようになります。
#iServerのログの格納場所を確認して開く
ここからが本題です。まずはroot権限になってログの格納場所を探しましょう。

```shell
sudo su
find / -name iost.log
```

すると１つのディレクトリがヒットすると思います。

```shell
/var/lib/docker/overlay2/01420e587c21ff154b28bf1d2a8a0ae1cc63b48a304b06466491a5d1204512ba/diff/var/lib/iserver/logs/iost.log
```

この配下に移動してディレクトリを表示してみます。

```shell
cd /var/lib/docker/overlay2/01420e587c21ff154b28bf1d2a8a0ae1cc63b48a304b06466491a5d1204512ba/diff/var/lib/iserver/logs
ll
```

するとこんな感じで一覧が出てきます（見辛くてｽﾐﾏｾﾝ）
<img width="700" alt="loglist.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/39453/f653be89-1523-db38-9134-899e0ea5ec14.png">
ログファイル名を見ると気付くかもですが、1時間ごとに1ファイル作成している模様です。
（ただ、このコマンド実行したのが3月2日なので3月1日分が３つしか作られていないのは謎です）
これらがiServerの実行ログになります。
以上です。お疲れさまでした( ´･ω･)⊃旦
Go言語のArray

Goの中でArrayは、型と長さ合わせてArray型になります。
違う長さの場合は == または != で比較するとエラーになります。

#GoのArray型の書き方
##基本書き方
var 変数名 = [n]型 {値１,...,値n}
例：

```go
var months = [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
```

出力：
>[1 2 3 4 5 6 7 8 9 10 11 12]

##長さ省略
「...」を利用して長さは省略可能です。
例：

```go
var months = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
```

出力：
>[1 2 3 4 5 6 7 8 9 10 11 12]

##値指定なし
例：

```go
var arr = [12]int{}
```

出力：
>[0 0 0 0 0 0 0 0 0 0 0 0]

ちなみに、省略すると、長さは０のArrayになります。
例：

```go
var arr = [...]int{}
```

出力：
>[]

##一部のみ値指定
例：

```go
var arr = [12]int{8: 9, 11: 12}
```

出力：
>[0 0 0 0 0 0 0 0 9 0 0 12]

indexは0からです。8:9の場合は、９個目の値は９で設定されます。

#要素値のアクセス
変数[index]
例：

```go
var arr = [12]int{8: 9, 11: 12}
fmt.Println(arr[8])
```

出力：
>9

#要素値の変更
変数[index] = 新しい値
例:

```go
var arr = [12]int{8: 9, 11: 12}
arr[8] = 999
fmt.Println(arr[8])
```

出力：
>999


#Arrayのメソッド
##長さ：len(変数名)
例：

```go
var array = [12]int{8: 9, 11: 12}　　
fmt.Println(len(array))
```

出力：
>12

##容量：cap(変数名)

```go
var array = [12]int{8: 9, 11: 12}　　
fmt.Println(cap(array))
```

出力：
>12

#Array比較
Arrayは同じ型、同じ長さの場合だけ比較できます。
## 「==」で等しい判断
例：	

```go
var arr1 = [12]int{8: 9, 11: 12}
var arr2 = [12]int{8: 9, 11: 12}
fmt.Println(arr1 == arr2)
```

出力：
>true

#「!=」で等しくない判断
例：

```go
var arr1 = [12]int{8: 9, 11: 12}
var arr2 = [12]int{8: 90, 11: 120}
fmt.Println(arr1 != arr2)
```

出力：
>true

##長さが違う場合は比較できない
例：

```go
var arr1 = [12]int{8: 9, 11: 12}
var arr2 = [24]int{8: 90, 11: 120}
fmt.Println(arr1 == arr2)
```

出力： 
>invalid operation: arr1 == arr2 (mismatched types [12]int and [24]int)


##二次元Array
例：

```go
var data = [3][2]int{{1, 2}, {11, 22}, {111, 222}}
```

出力：
>[[1 2] [11 22] [111 222]]

ちなみに、一つ目の長さは省略可能です。
例：

```go
var data = [...][2]int{{1, 2}, {11, 22}, {111, 222}}
```

出力：
>[[1 2] [11 22] [111 222]]


操作は一元Arrayと同じ
例：データアクセス

```go
var data = [...][2]int{{1, 2}, {11, 22}, {111, 222}}
fmt.Println(data[1][1])
```

出力：
>22

#ポインター定義
Arrayが値引用のため、関数の中で加工したい場合は、ポインターで定義
例１：

```go
arr := [12]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
var p *[12]int = &arr
fmt.Println(p)
```

出力：
>&[1 2 3 4 5 6 7 8 9 10 11 12]

例２：newで定義

```go
p := new([10]int)
p[9] = 10
fmt.Println(p)
```

出力：
>&[0 0 0 0 0 0 0 0 0 10]

以上
Golangで簡単なweb backendを書いた

# 経緯
僕、普段はPythonとDjangoを使って ~~引きこもりしつつ飛び上がり自殺を考えながら~~ 独自にwebアプリを書いているのですが、最近ではRailsでもSinatraでもFlaskでもDjangoでもPyramidでもなく、Goとそのフレームワークを使ってバックエンドコードを書いている(ように見える)ウェブアプリが見られます。

Goは並列処理がお得意な言語ということでよく知られていますが、今回、実際にGoでコードを書いてみて分かった事をまとめてみました。

# 書いたコード
* [Go言語そのものを考えるために結構前に書いたやつ](https://github.com/hiroaki-yamamoto/hello-go-lang)
* [Ginを使って簡単なJSONを出力するため、結構前に書いたやつ](https://github.com/hiroaki-yamamoto/go-web-example)
* [GQLGenを使って認証機能を書いた](https://github.com/hiroaki-yamamoto/go-gql-sample)

# 使ったフレームワーク
* 標準ライブラリ
* [chi]
* [Gin]
* [Gorm]
* [GQLGen]
* [JWT]

# 分かったこと

## Go言語そのものについて
Go言語それ自体は並列処理が言語機能の一つとして実装されているという点を除けば、非同期処理を得意とする他の言語（NodeJSなど)とほぼ同じような感じ？の印象を受けました。しかし、コンパイル型かつ並列・非同期処理が得意な言語という事で、Pythonなどと比べてウェブアプリを実装する時に飛躍的なスループットの向上が見込めるように思えます。(小並感

## フレームワークについて
* 標準ライブラリ(`net/http`など)はやっぱりWeb開発用途を意識されているようです。でも、DjangoのMiddleware的な概念は[chi]など他のライブラリを使わないと面倒でした(小並感
* [Gin]はRESTful APIを書く時には使えると思いました。が、Restful APIを書くんだったら[OpenAPI Generator]を使うよね、うん。
* [Gorm]はPythonで言うところの[SQLAlchemy]、Djangoで言うところのModel的な存在です。そして、ORMとしてのGormは至極普通でした。が、AutoMigration機能がDjangoのそれとは劣ります。([Gorm]のAutoMigrationとDjangoのMigrationの比較参照)
* [GQLGen]でResolverを書く時に`ResponseWriter`を参照できない。つまり、Backendとして認証機能を実装する場合はフロントエンド側でひと手間掛ける必要がある？(例: セッションのJWTをフロントエンドへペイロードとして渡してフロントエンド側でこいつをCookieなりヘッダなりにぶちこむ)
* **認証機能はモノリシックに作るのではなく、別にライブラリとして提供したほうが良さそう。**

### [Gorm]のAutoMigrationとDjangoのMigrationの比較
|機能|[Gorm]|[Django]|
|:--|:--:|----------:|
|Tableの自動追加|✔|✔|
|Tableの自動削除|❌|✔|
|Tableの自動リネーム|❌|✔|
|カラム自動追加|✔|✔|
|カラム自動削除|❌|✔|
|カラム自動変更|❌|✔|
|マイグレーションのバージョニング|❌(但しサードパーティー製ライブラリで対処可能？)|✔|
|マイグレーションの自動生成|❌(その概念がない？)|✔|
|マイグレーションの手動記述|✔|✔|

...GormのAutoMigrationは実用に値しない？ORMの機能だけ頂いてMigration Manager的な代物を書いたほうが良さそう。

# まとめ
GolangはAPIの開発には良さげだと思われますが、現状ではWebアプリのバックエンドとしての利用は難しい？ように思えました。また、Djangoではモデルデータの管理の為の画面(`django.contrib.admin`)があり、Golangも同様の機能が提供されている([QOR])ようですが筆者がこれを利用しようとしたところ、[GQLGen]の仕様？によってうまく使えませんでした。

と、いうわけで、Golangはセッション、SQLのスキーママイグレーション、モデル管理を解決できればメインで使える言語に出来るんじゃないかと思いました　まる

[chi]: https://github.com/go-chi/chi
[Gin]: https://github.com/gin-gonic/gin
[GQLGen]: https://gqlgen.com/
[Gorm]: https://github.com/jinzhu/gorm
[OpenAPI Generator]: https://openapi-generator.tech/
[SQLAlchemy]: https://www.sqlalchemy.org/
[SQLAlchemy Migration]: https://sqlalchemy-migrate.readthedocs.io/
[Django]: https://djangoproject.com
[JWT]: https://github.com/gbrlsnchs/jwt
[QOR]: https://getqor.com/
ハノイの塔　高さの概念

'''#include <stdio.h>
#include <stdlib.h>

//詰まるところbar[バーの高さ][バーの位置]
int barbel[6][4] = { { 0,0,0,0 },{ 1,0,0,0 },{ 2,0,0,0 } ,{ 3,0,0,0 } ,{4,0,0,0},{5,0,0,0} };/*こう書くとゼロクリアされる*/
																		//やはり高さはいる
int bartakasa[3] = { 0,5,5 };

char barbel0[] = { "               " };
char barbel1[] = { "       #       " };
char barbel2[] = { "      ###      " };
char barbel3[] = { "     #####     " };
char barbel4[] = { "    #######    " };
char barbel5[] = { "   #########   " };

void move(int, int);
void syokika(void);
int takasacheck(int, int, int);
int main(void)
{
	int i;
	syokika();
	for (i = 1; i <= 31; i++) {
		printf("%d回目\n", i);
		move((i&(i - 1)) % 3, ((i | (i - 1)) + 1) % 3);
		syokika();
	}

	system("Pause");
	return 0;
}
void move(int idoumoto, int idousaki)
{
	int idoumototakasa = 0;
	int idousakitakasa = 0;
	idoumototakasa = bartakasa[idoumoto];
	idousakitakasa = bartakasa[idousaki];
	idoumototakasa = takasacheck(idoumototakasa, idoumoto, idousaki);

	barbel[idousakitakasa][idousaki] = barbel[idoumototakasa][idoumoto];
	barbel[idoumototakasa][idoumoto] = 0;

	bartakasa[idousaki] = bartakasa[idousaki] - 1;
	bartakasa[idoumoto] = bartakasa[idoumoto] + 1;


}
void syokika(void) {
	int i;
	int j;

	for (i = 0; i < 6; i++) {
		for (j = 0; j < 4; j++) {
			switch (barbel[i][j]) {
				//文字列なので’が必要
			case 0:
				printf("%s", barbel0);
				break;
			case 1:
				printf("%s", barbel1);
				break;
			case 2:
				printf("%s", barbel2);
				break;
			case 3:
				printf("%s", barbel3);
				break;
			case 4:
				printf("%s", barbel4);
				break;
			case 5:
				printf("%s", barbel5);
				break;
			}
		}printf("\n");
	}printf("-------------------------------------------------------\n");
}
int takasacheck(int idoumototakasa, int idoumoto, int idousaki) {

	if (barbel[idoumototakasa][idoumoto] == 0)
	{
		idoumototakasa = idoumototakasa + 1;
		idoumototakasa = takasacheck(idoumototakasa, idoumoto, idousaki);
	}
	return idoumototakasa;
}
'''
【package.json】「An unexpected error occurred～」ｴﾗｰが出た時の対処法

#参考
[最短で学ぶReactとReduxの基礎から実践まで/Udemy](https://www.udemy.com/share/1000kqBEAZeVlSRno=/)

# 事象

* 静的解析ツール(eslint)の導入 
* `yarn add eslint@3.19.0 eslint-plugin-react@7.1.0`を実行
* 下記のエラーメッセージが発生


>error An unexpected error occurred: "C:\\./udemy_react\\package.json: Unexpected string in JSON at position 220".

# 原因

package.jsonファイルに
scripsを追記したとき(カンマ)をつけ忘れてた


```js:package.json
  "scripts": {
	"start": "./node_modules/.bin/webpack-dev-server"
   } //← ここ！!
  "dependencies": {
```


# 全体のソースコード
```js:package.json

{
  "name": "udemy_react",
  "version": "1.0.0",
  "main": "index.js",  "author": "Yokota Nanshin <nan0829068@gmail.com>",
  "license": "MIT",
  "scripts": {
	"start": "./node_modules/.bin/webpack-dev-server"
   },
  "dependencies": {
    "babel-core": "6.25.0",
    "babel-loader": "7.1.1",
    "babel-preset-es2015": "6.24.1",
    "babel-preset-react": "6.24.1",
    "babel-preset-react-es2015": "^1.3.0",
    "webpack": "3.3.0",
    "webpack-dev-server": "2.5.1"
  }
}
```
Threadクラスを利用した例外処理


Threadクラスを利用した例外処理の方法に苦戦したので、自分用としてアウトプットします。

##Threadクラスとは？

>スレッドとはメモリ空間を共有して同時に実行される制御の流れです。 Thread を使うことで並行プログラミングが可能になります。

プログラムは通常処理を記述した順に実行されるので、複数の処理を同時に実行することができません。

しかし、AとBという二つに処理を同時に実行した場合ってありますよね？

そんなとき使用できるのがThreadクラスです。

##メインスレッドとカレントスレッド
プログラム開始時に生成されるスレッドはメインスレッド、現在実行中のスレッドはカレントスレッドと呼ばれます。

RubyではThread#mainを用いる事でメインスレッドを確認できます。

また、Thread#listでプログラム上に存在するスレッドが配列で表示されます。

##joinメソッド

>Thread#joinは、 スレッド self の実行が終了するまで、カレントスレッドを停止させるメソッドです。 limit を指定して、limit 秒過ぎても自身が終了しない場合、nil を返します。

要するに、AとBという二つの処理を同時に実行した際に、片方の処理が終わるまでもう片方の処理を停止させることが出来るメソッドです。

Aという処理が終わるまで、Bという処理を停止させるようなイメージ。

##コード

###テストの前提条件

・画像が21枚以上は保存できない
・既に19枚が保存されている
・2枚同時に投稿した際に片方をエラーにしたい

###使用方法

①Threadのインスタンスを生成(t1,t2)
②それぞれのThreadに対してrescue文を使用し例外処理を行う
（どちらが先に実行されるのかわからないため）
③rescue文で定義した例外処理のeにe1を代入。
④どちらか片方が例外処理によって抜け出した際の、エラー文とクラス（ActiveRecord::RecordInvalid）が一致しているか？のテストを実施。

```ruby
require 'rails_helper'
 
RSpec.describe UserService do
 
  context 'with 2 images uploading at the same time' do
    let(:user) { FactoryBot.create(:user) }
    let(:user_images_nearest_max) { FactoryBot.create_list(:user_image, 19, user: user) }
    let(:params){ ActionController::Parameters.new( user_id: user.id,
                                                    files:[{ file: File.open(Rails.root.join('spec', 'fixtures', 'sample_image_01.jpg')),
                                                    order: 2}])}
     
    before do
      user_images_nearest_max
    # ①
      t1 = Thread.new {
        ActiveRecord::Base.connection_pool.with_connection {
          service = described_class.new(params)
          service.run!     
        }
      }
     # ①
      t2 = Thread.new {
        ActiveRecord::Base.connection_pool.with_connection {
          service = described_class.new(params)
          service.run!
        }
      }
    end
     
    it 'returns invalid with the 21st image' do 
      e1 = nil
      e2 = nil
     
     # ②
      begin
        t1.join # JoinメソッドはThreadクラスを拡張したクラスのインスタンスから使用できるメソッド。別のスレッドの処理が終了するまで待機させたい処理がある場合に使用
      rescue => e
     # ③
        e1 = e
      end
 
     # ②
      begin
        t2.join
      rescue => e
     # ③
        e2 = e
      end
       
     # ④
      if e1.nil?
        expect(e2.class).to eq(ActiveRecord::RecordInvalid)
        expect(e2.record.errors.messages).to match({:file=>["は20枚までしか登録できません。"]})
        expect(user.user_images.count).to eq 20
      end
 
     # ④
      if e2.nil?
        expect(e1.class).to eq(ActiveRecord::RecordInvalid)
        expect(e1.record.errors.messages).to match({:file=>["は20枚までしか登録できません。"]})
        expect(user.user_images.count).to eq 20
      end
    end
  end
end
```


【参考記事】
https://docs.ruby-lang.org/ja/latest/class/Thread.html
https://qiita.com/k-penguin-sato/items/1326882c400cac8c109b
fish で peco + z 実行後 direnv が読み込まれない

`fish` で、 `z` + `peco` を使った履歴`cd`ツールを実行した時、
`direnv` が読み込まれない問題が発生していた。

移動後リターンを一回入れてあげれば読んでくれるんだけど、それを忘れて `rails c` とか実行するとクラッシュするし、`spring stop` しないと環境変数読み込み直してくれないしでイライラすることが何回かあった。

その辺のプラグインとか使えばいいのかもしれないけれど、個人的に sort 順逆にしたりとかしていじっていたので、調べてみたら`direnv`は[`fish`のイベントを拾って実行していた](https://github.com/direnv/direnv/blob/e54386bdcccf9c7eea5976f787c4c31ddb5157d5/shell_fish.go#L12)ので、`cd`の後にイベントを発火させるようにすることで解決した。

```sh:~/.config/fish/functions/peco_z.fish
function peco_z
  set -l query (commandline)

  if test -n $query
    set peco_flags --query "$query"
  end

  z -l | sort -nr | peco $peco_flags | awk -F ' {5,}' '{ print $2 }' | read recent
  if [ $recent ]
    cd "$recent"
    commandline -r ''
    commandline -f repaint
    echo
    emit fish_prompt
  end
end
```

イベントの発火は`emit fish_prompt`の部分。

上記の`peco_z.fish`は[fish shellでzの結果をpecoって爆速でディレクトリ移動する \- @ka2n](http://ka2n.hatenablog.com/entry/2017/01/09/fish_shell%E3%81%A7z%E3%81%AE%E7%B5%90%E6%9E%9C%E3%82%92peco%E3%81%A3%E3%81%A6%E7%88%86%E9%80%9F%E3%81%A7%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E7%A7%BB%E5%8B%95%E3%81%99%E3%82%8B)を参考にさせていただきました。

### 2020-08-28 追記
direnv のコードが改善されて、イベント名が変わって上記コードが動かなくなりました。
`emit fish_prompt` の部分を `emit fish_postexec` にすることでできた。

どのイベントを使っているのかは`direnv hook fish`を実行すると見ることができます。
`--on-event` の後ろがイベント名

```sh
function __direnv_export_eval --on-event fish_postexec;
	"/usr/local/bin/direnv" export fish | source;
end
```

## 参考

- [シェルでコマンドの実行前後をフックする \- Hibariya](http://note.hibariya.org/articles/20170219/shell-postexec.html)
- [emit:イベントを発生させる【イベントハンドラー関数とともに】](http://fish.rubikitch.com/emit/)
takeWhile はメモリリーク (無駄なメモリ消費) の原因になり得る

# `takeWhile` に参照透過でない式を渡すのは良くない。

上記が分かっていれば下記を読む必要はありません。

# 経緯

[React開発ノウハウメモ（随時更新）](https://qiita.com/pikohideaki/items/690208a519c36a983d09)
上記記事を読んで `unsubscribe` を `componentWillUnmount` に書かない方法を知ったので調べてみた。[^1]

[^1]: `useEffect` のある今の `React` で `componentWillUnmount` のような古い方法を使う必要はないと思う。

# `takeWhile` はメモリリークの原因になり得る。

`takeWhile` は値が来たときのみ実行されるので値が来なければ `unsubscribe` されない。
無駄なネットワーク通信やDBへのアクセスを続けてしまう。
`takeWhile` は値に応じて処理を続けるべきか決まる場合で使うべき。

`Observable` を流れる値と関係なく処理を止めたいなら `unsubscribe` を呼ぶか `takeUntil` を使う。

# テストしてみる

実際に試してみるためのコードを書いた。
それらで下記の 3 つの関数を使っている。

```ts:utils.ts
// s 秒待つ
const sleep = (s: number) => new Promise(r => setTimeout(r, s * 1000))
// タイムスタンプをつけてログを出す
const log = (...v: any[]) => {
	const ts = (performance.now() / 1000) | 0
	console.log(...v, `(${ts})`)
}
// キャンセルできる Observable を生成
const make = (name: string) => {
	return new Observable<number>(s => {
		let canceled = false
		const push = (v: number) => {
			log(name, 'sub1', v, '- canceled', canceled)
			s.next(v)
		}
		Promise.resolve().then(async () => {
			push(12) // すぐに 12 を渡す
			await sleep(10) // 10 秒待ってから
			push(13) // 13 を渡す
			push(14) // 14 を渡す
		})
		return () => {
			log(name, 'unsub1')
			canceled = true
		}
	})
}
```

# テスト内容

上記 `make` で `Observable` を生成したのち 1 秒後に処理を止める。

# `unsubscribe` する

一般的なやりかたであると思われる。
問題なく動いている。

```ts:test1.ts
const test1 = async () => {
	const read = make('test1').pipe(
		tap(v => log('test1', 'sub2', v)),
	).subscribe()
	await sleep(1)
	read.unsubscribe()
}
test1() /*
test1 sub1 12 - canceled false (0)
test1 sub2 12 (0)
test1 unsub1 (1)
test1 sub1 13 - canceled true (10)
test1 sub1 14 - canceled true (10)
*/
```

# `takeWhile` を使う

1 秒後に止めようとしたが、その後 9 秒経って次の値が来るまで止まっていない。

```ts:test2.ts
const test2 = async () => {
	let alive = true
	make('test2').pipe(
		takeWhile(() => alive),
		tap(v => log('test2', 'sub2', v)),
	).subscribe()
	await sleep(1)
	alive = false
}
test2() /*
test2 sub1 12 - canceled false (0)
test2 sub2 12 (0)
test2 sub1 13 - canceled false (10)
test2 unsub1 (10)
test2 sub1 14 - canceled true (10)
*/
```

# `takeUntil` を使う

問題なく動く。

```ts:test3.ts
const test3 = async () => {
	const unsub = new Subject<void>()
	make('test3').pipe(
		takeUntil(unsub),
		tap(v => log('test3', 'sub2', v)),
	).subscribe()
	await sleep(1)
	unsub.next()
	unsub.complete()
}
test3() /*
test3 sub1 12 - canceled false (0)
test3 sub2 12 (0)
test3 unsub1 (1)
test3 sub1 13 - canceled true (10)
test3 sub1 14 - canceled true (10)
*/
```

# `unsubscribe` と `takeUntil` 、どちらを使うべきか？

[こちらの記事 (英語)](https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/)では `takeUntil` がオススメされている。

手続き的な `unsubscribe` よりも宣言的な `takeUntil` が良いという判断だろうか？

# 補足

### `React` と `RxJS` を組み合わせる場合

大規模なアプリなら `redux-observable` を、小規模なら `rxjs-hooks` を使うことを勧める。
古い `React` を使っているなら `recompose` も良い。
スプレッドシートに組み込んだGASのトリガー「フォーム送信時」が正常に作動しなかった問題

# ※現在の作動状況(2019/7/9)
当記事で紹介している事象がなおったとの報告をいただき、私の環境でもトリガーが正常に作動していることを確認しました。当記事での対処方法は不要ですが、私個人の備忘録として掲載をさせていただきます。
(コメントをくださった皆様ありがとうございました)

# 対処方法
1. スプレッドシートのトリガーを削除
2. スプレッドシートのプロジェクトをライブラリ化
3. Google Formsからプロジェクトを作成
4. Google Formsのプロジェクトにライブラリを組み込む
5. Google Formsのプロジェクトにトリガー「フォーム送信時」を組み込む

# 状況
スプレッドシートに組み込んだGASのトリガー「フォーム送信時」が誤作動を起こしました。具体的には、内容確認のメールを送信する処理が2回以上、多いときには7回程度送信されます。

# 調査
原因を調べてみたところ、フォーム送信後、ほぼ同じ時刻に複数回トリガーが作動していることが確認できました。

前任者がスプレッドシートをコピペして使っていたのでそれが原因か？とも思ったのですが、同一環境でイチから作ってみても同じ事象が起こり、自分の能力では特定ができませんでした。

# 対処方法詳細
トリガーを組み込む場所をスプレッドシートからGoogleフォームへと変更しました。

### 1.スプレッドシートのトリガーを削除
スプレッドシートに付随するプロジェクトで設定しているトリガーを削除します。

1.スクリプトエディタ
2.「現在のプロジェクトのトリガー」
3.トリガーの設定ボタン(三点)
4.「トリガーを削除」

### 2.スプレッドシートのプロジェクトをライブラリ化
スプレッドシートに付随するプロジェクトで実装している処理をライブラリ化します。Google Formsで再度実装する手間を省略する狙いがあります。

1.スクリプトエディタ
2.「公開」タブ
3.「実行可能APIとして導入」(バージョン設定は任意、アクセスできるユーザーはとりあえず「自分のみ」)
4.表示されたAPI IDを控える
※スプレッドシート側でコードを編集したときはバージョン情報を更新することを忘れないようにしてください

ライブラリ化についての参考：https://www.lisz-works.com/entry/gas-create-lib#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E7%94%A8%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8B

### 3.Google Formsからプロジェクトを作成
スプレッドシートと連携しているフォームを開きます。

1.Google Forms
2.設定ボタン(三点)
3.「スクリプトエディタ」

### 4. Google Formsのプロジェクトにライブラリを組み込む
スプレッドシートのプロジェクトで作成したライブラリを組み込みます。

1.スクリプトエディタ
2.「リソース」タブ
3.「ライブラリ」
4.「ライブラリを追加」欄にAPI IDを貼付
5.「追加」ボタン押下
6.最新のバージョンを選択
7.保存

ライブラリ組み込みについての参考：https://www.lisz-works.com/entry/gas-create-lib#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80

ライブラリ組み込み後、エディタには以下のように記述します。

```
function myFunction() {
   FormApp.getActiveForm();
  //スプレッドシートへの転記処理が終わるまで待機
  Utilities.sleep(20000);
  //ライブラリの関数を実行
  spreadsheet.projectname();
}

```

フォーム送信内容のスプレッドシートへの転記処理に時間がかかることがあるため、念のために20秒ほど待機をしております。待機時間は条件によって変えて良いかと思います。

### 5. Google Formsのプロジェクトにトリガー「フォーム送信時」を組み込む
1.スクリプトエディタ
2.「現在のプロジェクトのトリガー」
3.「トリガーを追加」
4.「イベントの種類を選択」＞フォーム送信時
5.保存


# 動作状況
概ね希望通りの動作(フォーム送信後、入力者へ自動でメールが送信される)が実現でき、2回以上の連続送信(=トリガーの複数回実行)は起こっていません。
スプレッドシートで全て処理できるのがベストですが、当面はこちらで対応したいと思います。