OmniAICreator/Qiita-1.07M huggingface dataset:
【VirtualBox】ホストオンリーアダプタの使い方

#ホストＯＳ ⇔ ゲストＯＳ ⇔ 外部ネットワーク
#####ブリッジ接続を使用しない設定方法
ホストＯＳは、macOS Mojave（10.14.5）ゲストＯＳは、CentOS7（7.6-1810）を使用しています。

【ホストオンリーアダプター作成】ツールメニューからネットワークを選択します。
![hostonlyadaptar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/29e7e94f-7ef3-b94d-1053-5f0ea34db674.png)

DHCPサーバーのチェックボックスをONにします。
※VirtualBoxのホストオンリーアダプターが使用するIPアドレスは 192.168.56.xxx のため、IPアドレス/マスクが 192.168.56.1/24 になっていることを確認します。
![hostonlyadaptar2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/6c7a23f4-7eef-da06-f10a-f8a0e03d1830.png)

【アダプタ１】 NATを選択します。
![adapter1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/eb0ffb62-998b-1da7-9d65-335ee2f57d0b.png)

【アダプタ２】 ホストオンリーアダプターを選択します。
![adapter2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/da98127b-11ab-084a-e3e7-447203b1058e.png)

【CentOS NATの確認】
特に確認する必要はありませんが、一応、見てみます。
$ sudo vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
補足：ifcfg-enp0s3は環境により異なります。
![ifcfg-enp0s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/2a0e6846-0541-d9a9-4994-c9525b2cc671.png)

【CentOS ホストオンリーアダプターの変更】
$ sudo vi /etc/sysconfig/network-scripts/ifcfg-enp0s8
補足：ifcfg-enp0s8は環境により異なります。

以上です。
![ifcfg-enp0s8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/3a4223fc-c100-459a-9dff-91eb7d9fa5ad.png)
・変更箇所
 1.BOOTPROTO
　変更前：BOOTPROTO=dhcp
　変更後：BOOTPROTO=static
 2.ONBOOT
　変更前：ONBOOT=no
　変更後：ONBOOT=yes
・追加箇所
　IPADDR=192.168.56.101
　NETMASK=255.255.255.0
　補足：IPアドレスは、192.168.56.xxx です。

【疎通確認】
ゲストＯＳ再起動後、以下のコマンドで確認します。
1.IPアドレスの確認
$ ip a
![ip_a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/63ee7b6c-12dd-d0d7-3510-011348bf0c43.png)

2.ホストＯＳからゲストＯＳへping
$ ping 192.168.56.101
![ping_host2guest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/eb9f4588-47db-cef8-c280-6c201e9ae2d3.png)

3.ゲストＯＳからホストＯＳへping
$ ping 192.168.56.1
![ping_gest2host.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/fcc5765a-fa26-8cf3-160c-02fa47511563.png)

4.ホストＯＳからゲストＯＳへssh
$ssh 192.168.56.101
![ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49062/efef6a89-52a7-8027-34c9-e532cb45aed1.png)

以上です。
EC2上でファイルを編集・保存しようとしたらエラーが出た日

### 保存(:wq)しようとしたら エラーが出た

E45: 'readonly' option is set (add ! to override)


###解決策
こうしたらいいっぽい
:w !sudo tee %

今開いているファイルに、tee コマンドで強制上書き


###コマンドの意味

| コマンド     |       意味 |    
|:-----------------|------------------:|
| w            | ファイルの保存 |
| !sudo tee         | ! で コマンド「sudo tee」を指示|
|tee          | 画面とファイル両方に出力 |  
|%            | 現在開いているファイル |  

そして離脱
:q!



###Success!


参考
https://qiita.com/shuthimaru/items/2334f63845d8b0d85bdd
フロントエンド初心者が30分のペアプロで学んだ事

ペアプロしてもらって学んだ事を書く

## 基本のキ
CSSは親子関係であることを意識する

### 1.書く順番
```
親のClass {
}

親のClass 子のClass {
}
```
みたいな感じでネストを読み手にわかりやすくする

### 2.共通部分ほど親に寄せる

```
親のclass {
background-color:#ffffff
}

親のclass 子のclassA {
background-color:#ffffff
}

親のclass 子のclassB {
background-color:#ffffff
}
```

こういう指定はアンチパターン、出来るだけ同じ指定を書かないようにする


### 3. 時にはmarginを計算することもある
classAの指定25px ＋ classBの指定5px
みたいな、デザインツールから抽出したCSSを使う時などに頭に入れておくとコードが良くなる

### 4.不必要にdevでタグを分けない
ネストの外で指定できる場合は一緒に指定しても良い
例えば中にあるパーツがユニークなもの一つとか

### 5.widthとheightはcenter指定だといらない
デザインツールでheightとなっている指定はline-heightにその値を入れる場合がある、height指定だと天井に張り付く、line-heightだと中央揃えになる

### 6.normal指定のものは書く必要なし
必要ある場合もあるけど、デザインツールからそのまんまコピペしてはならないの意

### 7.font-familyとかはheadで指定されている場合は書く必要なし
当たり前だが一応

### 8.時にはデザインから読み取れない値についてデザイナーさんとコミュニケーションする必要がある
恐れず聞く事、誰でも完璧ではない

### 9.bootstrap使ってる場合はありそうなやつは検索するとひっかかるのでそれを見て検討する
当たり前だが一応

### 10.必要なCSSかどうかはコンソールで指定自体を消したりなんだりしながら見る
当たり前だが一応

### 11.デベロッパーツールで最終的に適用されているCSSの値を一覧で見ることができるのでそれも使う
デベロッパーツール→Computedで見られる、CSSがごちゃついてたらとりあえずこれを使う
AWS上でflaskを起動しようとしてエラーが出た日



###使ってるport:xxxxを指定して起動しているプロセスがあることを調べる
$ lsof -i :xxxx


###プロセスIDを調べて屠る
$ kill xxxx

参考
http://o-tomox.hatenablog.com/entry/2013/07/29/234359
fizzbuzz

C#の研修を見学中にifとfor使わずに書こうって言われた
しかしながら自分の端末にcsc入れてなかったのでF#で書いた

```fsharp
let printNumber(count) =
        let isDivided3 = (count % 3 = 0)
        let isDivided5 = (count % 5 = 0)
        
        match (isDivided3, isDivided5) with
        | (true, true) -> printfn "fizzbuzz"
        | (true, false) -> printfn "fizz"
        | (false, true) -> printfn "buzz"
        | (false, false) -> printfn "%d" count

let rec fizzbuzz(count) = 
    printNumber(count)
    
    match count with
    | 100 -> ()
    | _  -> fizzbuzz(count + 1)
  
[<EntryPoint>]
let main argv = 
    fizzbuzz(1)
    Console.ReadLine() |> ignore
    0

```

```fsharp
let printNumber(count) =
        match (count % 3 = 0, count % 5 = 0) with
        | (true, true) -> printfn "fizzbuzz"
        | (true, false) -> printfn "fizz"
        | (false, true) -> printfn "buzz"
        | (false, false) -> printfn "%d" count
  
[<EntryPoint>]
let main argv = 
    seq {0 ..100} |> Seq.iter(printNumber)
    0

```
Salesforce開発メモ

開発
https://developer.salesforce.com/ja/

勉強
https://trailhead.salesforce.com/ja/

試験申込
http://tandc.salesforce.com/credentials

【ログインページ 】
・本番環境：https://login.salesforce.com
・サンドボックス環境：http://test.salesforce.com

用語集
Salesforce - セールスフォース
Classic（クラシック）
Lightning（ライトニング） 
APEX：アペックス/エーペックス
SendBox Partial（パーシャル）

メモ
組織IDは18桁：先頭3桁は識別ID、末尾3桁は検証ID


Visualforce Page
作成方法は以下の通りです。
・[設定]→[ビルド]→[開発]→[ページ]→[新規]
・開発者コンソールでCustomPageを作成
表示方法は以下の通りです
https://ap.salesforce.com/apex/CustomPage
Mac(Catalina)でおうちkubernetes

# Macでkubernetesの勉強をするときの注意点
kubernetesをローカルでさくっと動かすなら[minikube](https://github.com/kubernetes/minikube)が利用できます。

minikubeが使うvirtualBoxをインストールする時に、少しつまづいたのでメモしておく。
VirtualBoxをインストールする時に、インストールに失敗することがある。

下記ページの「Solution 2」の方法で自分は解決できた。
https://medium.com/@DMeechan/fixing-the-installation-failed-virtualbox-error-on-mac-high-sierra-7c421362b5b5

## 動作確認
minikubeを動かしてみると下記のようにポップな感じで起動する。
<img width="729" alt="Untitled.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/302e9754-3c6a-1ca8-c379-838ac70478c7.png">

## ダッシュボード起動
<img width="729" alt="Untitled 3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/ca10cd46-c261-6f77-d959-2b0c792cc1b3.png">

下記のようなダッシュボードが表示される。

<img width="1439" alt="Untitled 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/d660f34e-d553-ec79-0df8-75560d5c93fd.png">

## つづく()
Activityを再起動させたいけど余分な画面を一枚挟まないといけない…という場合に有効なライブラリ

#はじめに

画面Aを再起動させたい場合に、以下のように

```
画面A => 画面X => 画面A
```
「画面Xを挟まないとうまく再起動できない！」
という場合に有効なライブラリを紹介します。

そんな場合あるか？と思われた方、すみませんが
外部のプロジェクトで発生した事象ですので詳しく言えません(T_T)

ですが、覚えておくといつか役に立つライブラリだと思いますので、
頭の片隅にでも入れておいて損はないはずです！

#ProcessPhoenix

そのライブラリの名は、**ProcessPhoenix !!!!!**
（かっこいい。。。）

https://github.com/JakeWharton/ProcessPhoenix
URLでもおわかりの通り、
あのAndroidの神、JakeWhartonさんが書いたOSSライブラリです。
（おぉ〜！！！）

> Process Phoenix facilitates restarting your application process.
> プロセスフェニックスは、アプリケーションプロセスの再起動を容易にします。

名前の通り、不死鳥のようにプロセスを蘇らせるライブラリです。

使い方もとっても簡単です。

## 1. build.gradleに依存関係を設定

```build.gradle
dependencies {
    implementation 'com.jakewharton:process-phoenix:2.0.0'
}
```

## 2. ProcessPhoenix#triggerRebirthを実行
今回は特定のインテントで起動したいので、

```Kotlin
val intent = Intent(context, MainActivity::class.java)
ProcessPhoenix.triggerRebirth(context, intent)
```
以上です！（早っ！）

#補足

ちなみに、、、
\#triggerRebirthの定義は次のようになっています。

```ProcessPhoenix.java
public static void triggerRebirth(Context context, Intent... nextIntents) {
    Intent intent = new Intent(context, ProcessPhoenix.class);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK); // In case we are called with non-Activity context.
    intent.putParcelableArrayListExtra(KEY_RESTART_INTENTS, new ArrayList<>(Arrays.asList(nextIntents)));
    context.startActivity(intent);
    if (context instanceof Activity) {
      ((Activity) context).finish();
    }
    Runtime.getRuntime().exit(0); // Kill kill kill!
}
```

これくらいの処理なら自分でもできry...

これをKotlinで書くと、スコープ関数を使えば

```Kotlin
fun triggerRebirth(context: Context, vararg nextIntents: Intent) {
    Intent(context, ProcessPhoenix::class.java).apply {
        addFlags(FLAG_ACTIVITY_NEW_TASK)
        putParcelableArrayListExtra(KEY_RESTART_INTENTS, ArrayList(Arrays.asList(*nextIntents)))
        context.startActivity(this)
    }
    if (context is Activity) {
        context.finish()
    }
    Runtime.getRuntime().exit(0)
}
```
このようにスッキリと書くことができます。
スコープ関数については、[[コチラ]](https://qiita.com/yasuX/items/20b6354d42b19879a55e) の記事を参照ください。
スマートキャストも効いてイイ感じですね。
やっぱりKotlinは書きやすい！

#おわりに
一度聞いたら忘れない名前のインパクト！
TouchDesignerでBezier Easing アニメーション

TouchDesignerでベジエカーブを使ったイージングアニメーションをやってみたいと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/6668fa63-28a1-9d7d-6a8f-cdac4e94177a.gif" width=80%>


# エディタ画面
エディタ画面はこんな感じで、オペレーターはそれほど多くありません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/20fe6a6f-fc78-d377-160d-528de66f630c.png" width=80%>

# ベジエ曲線を描く
### Line SOP
ベースのオブジェクトは「Line SOP」を使います。
Line SOPはデフォルトでは[0, 0, 0]と[1, 0, 0]の2点のポイントを繋ぐラインになっています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/bc1d82a8-dd6d-d1cf-357f-b7917bba258b.png" width=80%>

このLine SOPに中点を加えて、その中点を原点にアニメーションさせようと思うので、各パラメータを下図のように設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/02c1b157-8d34-8a4b-5a61-9d5766138491.png" width=80%>

"Point A"のx座標を0から-1に変更しています。
"Point B"のx座標が1のため、こうすることで中点が[0, 0, 0]になります。
そして"Number of Points"を"3"にするとポイント数が3つ均等割りに配置されるので中点が生まれます。

### Group SOP
中点だけアニメーションさせたいので「Group SOP」を使い、中点のみのGroupを作成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/ae85dadd-f831-cb79-6cd8-c8adc3983043.png" width=80%>

PointのGroupを作りたいので"Group"タブの"Entity"は"Point"にします。
"Create"タブでは"Number"を"ON"にして数字での指定をアクティブにします。
またRangeの指定をして中点だけ指定されるようにします。
Rangeの指定の仕方については[こちらの記事](https://qiita.com/atsonic/items/cc71ea092d904b255f5e)を参照してください。

### Transform SOP
Group SOPから「Transform SOP」を繋ぎアニメーションの準備をします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/938261d1-56a5-3539-8d28-b6813027bd2b.png" width=80%>

その時"Group"に先ほど作成した"group1"を指定します。

### Convert SOP
そして最後に「Convert SOP」を繋げます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/26f5924b-a1dc-a04f-6e59-9dfdd16a1b6f.png" width=80%>

「Convert SOP」はその名の通り色々な変換をしてくれるSOPです。
"From Type"で元の属性を指定し、"Convert to"で変換後の属性を指定します。
変換後を"Bezier Curve"に指定することで、ベジエ曲線を作ることができます。

# イージングを実装する
イージングと言っても色々種類がありますが、今回はバネっぽい「Elastic」という種類をやっています。
これを実装するには「Lag CHOP」が有効です。

### Lag CHOP
"Lag"とは"遅延"のことで、数値に遅延を与えることができます。
またパラメータの中で"Overshoot"というのがあり、これは"超過"を指定します。
OverShootを指定することで入力の数値を超過させることが可能になります。
2つフィールドがありますが、最初が上方向2番目が下方向の超過です。
「Operator Snippets」に色々なサンプルがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/d5b09aa5-a10b-7d7c-75f8-4c2dd951a9ec.png" width=80%>

このLagで生成した値を「Transform SOP」のy座標に与えてあげれば完成です。
最後にYoutubeへのリンクを貼っておきます。
[![IMAGE ALT TEXT HERE](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31194/eed28d62-169d-bde7-98dc-2316ec43c879.png)](https://www.youtube.com/watch?v=YI5bnEBFevA)
VSCodeで複数ファイル内のテキストの一括置換する方法、等の忘備録

# 環境
Windows 10,　VSCode

# 手順

## ケース1 : 複数ファイル内のテキストを一括置換する
1. `ctrl + shift + h`を押す。(macOSは`Command + shift + h`)
2. 通常の一括置換と同様に、検索条件と置換後テキストを欄に入力する。
3. "files to include"欄に"*"と入力するとすべてのファイルから検索できる。
4. "Replace All"をクリックする。

## ケース2 : 選択した範囲のテキストを一括置換する
1. `ctrl + h`を押す。(macOSは`Command + h`)
2. 通常の一括置換と同様に、検索条件と置換後テキストを欄に入力する。
3. 一括置換したい範囲のテキストをエディタ内で選択する。
4. `alt + l(エル)`を押す。
5. `ctrl + alt + enter`を押す。 (macOSは`Command + Alt + Enter`)

---

以上、VSCodeの一括置換について、個人的によく使う手順のまとめでした。
【備忘録】Python3 でのログ転送

## 概要
転送するファイル名をkey、getmtimeでそのファイルのエポック秒をvalueとしdict型に押し込める。
転送先との差分を取り、足りない分を転送する。shutil.copy2により最終更新日時などの情報もコピーされる。

# os.path.getmtime
ファイルのアクセス日時を取得する。

# shutil.copy2
既にファイルがある場合上書き保存する。
同じファイル名でも編集でアクセス日時が異なると上書き保存してくれる。

参考：[積年の「shutil.copy はメタデータをコピーしません」の回避策](https://qiita.com/tonluqclml/items/123e24f7aa7800f8bed5)

以下の辞書型を転送元と先で差分をとる
key:ファイル名
item:更新日時

```python
import os
import sys
import glob
import shutil

def log_copy(sfolder_path, dfolder_path):

    if os.path.isdir(sfolder_path):
        slist = {os.path.basename(filename): os.path.getmtime(filename) for filename in glob.glob(os.path.join(sfolder_path, "*"))}
        tlist = {os.path.basename(filename): os.path.getmtime(filename) for filename in glob.glob(os.path.join(dfolder_path, "*"))}
        diff_dict = dict(slist.items() ^ tlist.items())

        if diff_dict == 0:
            pass
        else:
            for dfile in diff_dict.keys():
                try:
                    shutil.copy2(os.path.join(s_path, channel, dfile), os.path.join(d_path, channel, dfile))
                    print("File uploaded : %s",os.path.join(s_path,channel, dfile))
                except:
                    sys.exit(1)

if __name__ == "__main__":
    log_copy(r"/var/log/squid", r"/mnt/nfs/logs")

```
AWS SAA受験対策 ~Sysops取得の経験を添えて~

# 模擬試験(WhizLabs)
模擬試験の精度が高いので(問題の傾向が同じ)、受けることを推奨します。
日本語の模擬は訳がおかしいものがまだ多く、試験当日も英語に切り替えた方が理解しやすい問題も少なくない。
そのため、whizlabsで慣れておくことは一石二鳥で効果があると認識しています。
模擬試験数回分(Practice Tests)が$20ですが、破格の値段設定だと思います。(他が高い)

下記はAWS Sysops向けのテストですが、Sysopsの範囲はSolution Architectの範囲を内包しているので、下記が理解できれば、sysops, solution architectを同時に取ることが可能と思います。自分はsysopsから取ったので、solution architectで新たに勉強することがなく驚きました。
https://www.whizlabs.com/aws-sysops-administrator-associate/

# サービス別理解(AWS BlackBelt)
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/
BlackBelt内の下記のカテゴリ、サービスについて読むと理解が深まる。
個人的に特に注力すべきポイントに⭐️をつけてある。
⭐️がついていないものは、サービスの概要を理解して、どのサービスと一緒に使われるかを知っておく程度でいいと思う。

## Compute
Amazon EC2⭐️
Amazon EC2 Auto Scaling⭐️
Amazon ECS⭐️
AWS Batch
AWS Elastic Beanstalk
AWS Lambda⭐️
ELB⭐️

### Databases
EBS⭐️
S3⭐️
DynamoDB⭐️
Elasticache
Neptune
RDS⭐️
RedShift

### Migration & Transfer
AWS Snow Family

### Networking & Content Delivery
Amazon VPC⭐️

Amazon CloudFront
Amazon Route 53⭐️
AWS Direct Connect⭐️

### Developer Tools
AWS Chalice
AWS CodeStar
AWS Cloud9
AWS CodeBuild
AWS CodeCommit
AWS CodeDeploy
AWS CodePipeline

### Management & Governance

Amazon CloudWatch⭐️
AWS CloudFormation⭐️
AWS CloudTrail⭐️
AWS Config
AWS OpsWorks
AWS Systems Manager
AWS Trusted Advisor
AWS Well-Architected

### Security, Identity & Compliance
AWS Identity and Access Management (IAM)⭐️
Amazon Cognito
Amazon Inspector
AWS CloudHSM
AWS Key Management Service⭐️
AWS Organizations

### Analytics
Amazon Athena
Amazon Kinesis


### Mobile
Amazon API Gateway

### Application Integration
Amazon SNS⭐
Amazon SQS⭐
Vueで::before、::afterなどの疑似要素を動的に変更する

before,afterの疑似要素はDOMではないらしいのでjsからは直接はいじれないらしく、
HTML内にstyleを直書きして、そこを変更する。

```vuejs
<template>
  <div>
    <component is="style">
      .test::after {
        content: '';
        height: {{ lineHeight }}px;
      }
    </component>
    <div class="test"></div>
  </div>
</template>
```

## 参考
https://forum.vuejs.org/t/about-using-style-tags-inside-templates/7275/3
https://stackoverflow.com/questions/49516424/use-style-tags-inside-vuejs-template-and-update-from-data-model
2つ目のリンクはrender関数を使用した方法:rolling_eyes:
deviseでユーザー登録時にメールで認証する方法

## メールによる認証を導入

ユーザー登録が成功すると無事にユーザーログインできるようになるのですが、普段使っている世の中のWebサービスのように登録したタイミングで登録完了メールが飛んできて、そのメールに記載されているリンクをクリックすると正式に登録完了するという機能を実現したいと思います。

## deviseでメールによる認証を導入する

deviseでメールによる認証を導入するには、deviseに用意されている機能を使うのが良いと思います。導入もかなり簡単です。/app/models/user.rbの

```/app/models/user.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
```

という行の行末に:confirmableを追加して以下のようになります。

```/app/models/user.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable
```

上記のようにconfirmableを追加して:confirmableを読み込みます。次にメールを送信するためのSMTPサーバーの設定をしていきます。今回はGmailで送信するとしてconfig/environments/development.rbを以下のように編集します。

```config/environments/development.rb
config.action_mailer.smtp_settings = {
  :enable_starttls_auto => true,
  :address => "smtp.gmail.com",
  :port => 587,
  :domain => 'smtp.gmail.com',
  :user_name => "任意のGmailアドレス",
  :password => "任意のGmailパスワード",
  :authentication => 'login',
}
```

以上でdeviseのメールによる認証機能が設定出来ました。一点、注意点としてGmailの設定として「安全性の低いアプリのアクセス」を許可していないとGmailから送信することは出来ないので、今回のGmailからメールを送信する機能を利用するためには設定を変更しておきましょう。

無事に設定が終わると、ユーザー登録が完了したタイミングで登録した時に使用したメールアドレスに登録完了のメールが届いてリンクをクリックすると登録完了になります。
gtags.conf および .globalrc の読み方、書き方

GNU global (gtags) で使われる設定ファイルの順番は以下の通り。いずれも存在しない場合は gtags 自身に組み込まれている？初期値が使われる。
https://www.gnu.org/software/global/manual/global.html#DESCRIPTION-7

`gtags --config` で、今いるディレクトリでの設定を見ることができる。

gtags のソースコードをダウンロードして解凍すると、トップディレクトリに gtags.conf がある。こんな感じのフォーマットで gtags の設定を行うらしい。termcap と同じような感じと書いてあるが、termcap が分からない。
https://ftp.gnu.org/pub/gnu/global/

恐らくだけれど、複数の設定をラベルとして持つことができる。初期値は 'default' で、設定ファイルには少なくとも 'default' ラベルの設定が必要なようだ(ないと怒られる)。ラベルの選択は `--gtagslabel` や `$GTAGSLABEL` でできる。

```
default:\
	:tc=native:
```
`tc` は "他のエントリから端末の説明を読む込む" と書いてある。`source` とか `include` みたいなものだろう。
https://kazmax.zpp.jp/cmd/t/termcap.5.html

```
native:\
	:tc=gtags:tc=htags:
```
さらに gtags と htags から読み込む。htags のほうは空だった。

```
gtags:\
	:tc=common:\
	:tc=builtin-parser:
```
common と builtin-parser から読み込む。

```
common:\
	:skip=HTML/,HTML.pub/,tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,*.o,*.a,*.so,*.lo,*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,*.min.js,*min.css:
```
common にはどんなパターンを skip するかが書いてある。
https://www.gnu.org/software/global/manual/global.html#CONFIGURATION-1

```
builtin-parser:\
	:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
```
builtin-parser には、どんな拡張子をどんな言語として扱うかが定義してある。

default についてまとめるとこんな感じ。最小構成で独自の設定を書きたいときはこれを真似て書けばよい。

```
default:\
	:langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
	:skip=HTML/,HTML.pub/,tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,*.o,*.a,*.so,*.lo,*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,*.min.js,*min.css:
```

カンマ区切りはバックスラッシュで？分けることができるみたいだ。こっちのほうが見やすそう。

```
default:\
    :langmap=c\:.c.h\
    :langmap=yacc\:.y\
    :langmap=asm\:.s.S\
    :langmap=java\:.java\
        :
```
CDNを使ってVue.jsをする方法

# CDNを使ってVue.jsをする方法

CDNを使ったVue.jsをする方法の詳しい記事が見つけられなかったので解説します。

※CDN(Content Delivery Network)
VueのCDNは以下
`<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>` 

Vue.jsの公式サイト(CDNが記載されているページ)
https://jp.vuejs.org/v2/guide/installation.html

#### 使用する環境は以下

- エディター : VSCode
- ブラウザ : GoogleChrome

## 手順
#### ①ファイル新規作成し、名前を`index.html`にします

#### ②ディレクトリ作成し、名前を`css`にします

#### ③`css`ディレクトリ直下に、ファイルを新規作成し名前を`main.css` とします

#### ④ディレクトリ作成し、名前を`js`にします

#### ⑤`js`ディレクトリ直下に、ファイルを新規作成し名前を`main.js`とします

#### ⑥`index.html`に以下のように記述します
index.html

```
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Vue.js</title>
    <link rel="stylesheet" href="css/main.css">
  </head>
  <body>
    <div id="app">
      <p>{{ message }}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
  </body>
</html>
```

#### ⑦`main.js`に以下のように記述します
main.js

```
var app = new Vue({
  el: "#app",
  data:{
    message: "Vue.js"
  }
})
```

⑧`main.css`に以下のように記述します
main.css

```
p {
  color: red;
}
```

⑨`index.html`ファイルの上で右クリック→このアプリケーションで開く→GoogleCheromeを選択

⑩以下のようにブラウザに表示されれば成功！

<img width="263" alt="スクリーンショット 2019-08-09 16.57.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401818/b84843e7-1b93-32d5-ad54-a3f1ce745bd5.png">
PostgreSQLのインストール方法、データベース作成、ユーザー作成、Djangoとの接続準備

初めまして**jack**です。
８月からPythonをメインにエンジニア業務に従事することになりまして。
PostgreSQLを触り始めたので立ち上がり方法を簡単にメモメモ。

使用環境

- macOS

では早速、インストールから。

```console
brew install postgresql
```

インストールが出来たら試しにデータベースを起動させてみましょう。

```console
postgres -D /usr/local/var/postgres
```
#データベース作成

データベースを起動させた状態でデータベースを作成しましょう

```console
createdb データベース名
```

削除する場合は

```console
dropdb データベース名
```

作成したデータベースにアクセスするには

```console
psql データベース名
```

この後Djangoに接続させる為のユーザーを作成します。

#ユーザー作成
```console
CREATE USER ユーザー名;
```

そしてデータベースの管理者をユーザーに設定します。

```console
ALTER DATABASE データベース名 OWNER TO ユーザー名;
```
#Djangoとの接続準備
次にDjangoとの接続方法を記載します。
作成したDjangoのアプリのsettings.pyの下記編集が必要です。

```python:settings.py
DATABASES = {
    'default': {'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'データベース名',
        'USER':'ユーザー名',
        'PASSWORD':'',
        'HOST':'localhost',
        'PORT':5432
    }
```
```console
python3 manage.py startproject アプリ名
```
を行ったアプリ名をsettings.pyのINSTALED_APPSに追加。
最後のターミナルで下記操作すればOK！

```console
python3 manage.py makemigrations アプリ名
python3 manage.py migrate
```
pythonのオブジェクト

Pythonのオブジェクトはデータを抽象的に表したもので、同一性 (identity)、型、値を持っている。

```python:python
# idの例：
>>> str = "aaa"
>>> id(str)
140369458357336
>>> id("aaa")
140369458357336
>>> x = 10
>>> id(x)
94645402274624
>>> id(10)
94645402274624
```

```python:python
# 型の例：
>>> type(str)
<class 'str''>
>>> type("aaa")
<class 'str''>
>>> type(x)
<class 'int''>
>>> type(10)
<class 'int''>
```

```python:python
# つながっているので注意が必要な例：
>>> arr1 = [1,2,3,4]
>>> arr2 = arr1
>>> id(arr1)
140369480178440
>>> id(arr2)
140369480178440
>>> type(arr1)
<class 'list''>
>>> type(arr2)
<class 'list''>
>>> type(arr1[0])
<class 'int''>

>>> id(arr1[0])
94645402274336
>>> id(arr1[1])
94645402274368
>>> id(arr1[2])
94645402274624
>>> id(arr1[3])
94645402274432

>>> arr2.append(100)
>>> arr1
[1, 2, 3, 4, 100]
>>> arr2
[1, 2, 3, 4, 100]
```

```python:python
#  'is' 演算子で2つのオブジェクトの同一性を比較
>>> a = 10
>>> b = 20
>>> id(a)
94645402274624
>>> id(b)
94645402274944
>>> c = a
>>> id(c)
94645402274624
>>> b = 10
>>> id(b)
94645402274624
>>> a is b
True
>>> b is c
True
>>> c is a
True
```
【メモ】nuxt + typescriptを試す際に参考にしたサイト

- [TypeScriptでVue.jsを書く – Vue CLIを使った開発のポイントを紹介](https://mae.chab.in/archives/60167)
- [TypeScript のサポート(公式)](https://jp.vuejs.org/v2/guide/typescript.html#%E6%8E%A8%E5%A5%A8%E6%A7%8B%E6%88%90)
- [TypeScript + Vue.js の始め方](https://blog.asial.co.jp/2019/05/07/TypeScript_%2B_Vue_js_%E3%81%AE%E5%A7%8B%E3%82%81%E6%96%B9)
【Watson Studioメモ】ブックマーク機能を利用する

# 始めに
Watson Studioで以外と便利なブックマークを利用するための手順メモ

[2020-04-25] セットアップ手順修正

# 前提
クラウド上のWatson Studioでプロジェクト作成まで済んでいること。
まだの方は次のリンク先でセットアップをして下さい。

[無料でなんでも試せる! Watson Studioセットアップガイド](https://qiita.com/makaishi2/items/b666f847a98c2e42dfbb)

#  手順

https://dataplatform.cloud.ibm.com/projects/

から作成済みプロジェクトを選択し、下のプロジェクト管理画面を表示させます。その後で、

①　Bookmarksタブを選択
② Explore commumityのリンクをクリック

![スクリーンショット 2019-08-09 16.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/d9efc43e-f6b7-ee43-e1e7-13c8079b8564.png)

下の画面になったら、「Sort by」の欄を「**Latest**」に変更
更に、登録したい記事のブックマークアイコンをクリックします。

![スクリーンショット 2019-08-09 16.33.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/bbce1886-403b-83a4-ce49-0bcdccef82f4.png)

登録先のプロジェクトをドロップダウンで選択した後、「**Save**」ボタンをクリック。

![スクリーンショット 2019-08-09 16.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/cf4af07a-54db-3597-77ff-f3ca9ac0c6f3.png)

Bookmarksタブが下のようになっていれば、ブックマークへの登録に成功しています。

![スクリーンショット 2019-08-09 16.45.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/11aee235-4b2b-0782-daf8-aab1bf5a2cad.png)
個人的な技術メモ

# 個人的な技術メモ

## コーディング全般

### コメント

コメントはきちんと書きましょう。僕の場合は英語を使ってますが日本語でも構いません。

ただ、コンパイラによっては2バイト文字を使うとエラーを吐くものもあるので気をつけましょう。

**例**

```c++
#include <mbed.h>

//declare pins
DigitalOut Myled(LED1);

int main(void){
	while(1){
        Myled = !Myled;
        //wait for 500ms
        wait_ms(500);
    }    
}
```



## mbed関連

### ピンの宣言

ピンを宣言するときはそのまましてもいいけど個人的には#defineを使ったほうがすぐ変更できるので良いと思う。ただ、使いすぎるとコードが長くなるので気をつける。

```c++
#include <mbed.h>

//define PinName
#define PIN_LED LED1

//declare pins
DigitalOut Myled(PIN_LED);

int main(void){
	while(1){
        Myled = !Myled;
        //wait for 500ms
        wait_ms(500);
    }    
}
```

### IDEとか
Atom使ってる。プラグインが多くて良さげ。フォントはRicty Diminished Discordにすると文字の区別がしやすい。
[Golang]スライスの複製に便利な「copy」関数のサンプルと、直接代入した場合の罠

# とりあえずサンプル
スライスsを、スライスtにコピーしたいとする。

```golang:Gocopu関数のサンプル
package main
import "fmt"

func main() {
	s := []int{0, 10, 20, 30} // => [0 10 20 30] ←スライスsを作成

	t := make([]int, len(s))  // スライスtの骨組みを作成する
	fmt.Println(t)            // => [0 0 0 0] ←まだ値には0が入っている

	n := copy(t, s)           // スライスsをスライスtにコピーする

	fmt.Println(t)            // => [0 10 20 30] ←値がスライスsと同じ値になった
	fmt.Println(n)            // => 4 ←コピーされた要素の個数が返されている
}
```

# どうして、`t := s`としないのか

## 下記のように「copy関数」を使わずに代入するのはダメ？
```golang:Go：単純にコピーしてみた例
package main
import "fmt"

func main() {
	s := []int{0, 10, 20, 30}

	t := s 

	fmt.Println(s) // => [0, 10, 20, 30]
	fmt.Println(t) // => [0, 10, 20, 30] ←コピーできてるくない？
}
```
上のコードのように、シンプルに代入したら同じスライスができているのに、これではダメなのか…？
**結論から言うと、これダメです。**

## 罠
上のコードに、もう少し追記すれば分かるかと思います。

```golang:Go参照型の罠
package main
import "fmt"

func main() {
	s := []int{0, 10, 20, 30}

	t := s 
	t[0] = 100     // 1番目の値を0から100に書き換える

	fmt.Println(t) // [100 10 20 30]　←1番目の値は書き換えられているので100
	fmt.Println(s) // [100 10 20 30]　←あれ？　スライスsは書き換えていないのに…？
}
```

このように、コピー先のスライスを編集すると、コピー元のスライスにまで反映されてしまいます。
~~これは、Goのスライスが「参照型」なためとのことです。~~
~~Goでスライスを使う場合には、慣れるまでは、この参照型によってバグが発生するといったことも出てきそうです。。~~

2019/08/13　追記）
コメントでご指摘頂いており、**上の記述は間違っています。**修正は以下の通りです。

`s`を`t`に代入コピーする段階で、内部的に`s`のポインタまでコピーしてしまうことが起こっています。
これにより、`t`は`s`と同じメモリ領域の配列（つまり、同じ配列）を参照している状態になってしまうため、どちらか一方を変更したら両方とも変更されてしまう…といったことが起こるようです。

これに対して、copy関数を使った場合は、新しいメモリ領域に新しい配列を作成して、全く別の配列を参照する形になります。これによって、別個の配列として扱えるそうです。

詳しくは、この記事のコメント欄で@c-yanさんが説明して下さっていますので、ぜひ見て頂けると分かりやすいかと思います。
Slackにリマインダーを設定する方法

Slackのリマインダーを設定すると、Slack通知でリマインドを受け取ることができます。

ミーティング前の事前準備や、全体への共有などを設定しておくと抜け漏れがなくなるので便利です。

## フォーマット

```
/remind [送り先] [文章] [タイミング]
```
なお、`/remind help` でリマインドのヘルプを見ることもできる

### 『送り先』について
|対象 |例|
|---|---|
|他のメンバーに送る|@[メンバー名]|
|チャンネルに送る|#[チャンネル名]|
|自分に送る|me|

### 『文章』について
ここに書かれた内容がリマインダーで通知されます。
文章内で『@ユーザーグループ』とすればユーザーグループに所属するメンバーに通知することができます。

### 『タイミング』について

|パターン|具体例|
|---|---|
|日付指定|on January 1|
|毎日|everyday|
|平日の毎日|every weekday|
|毎週|every Monday|
|隔週|every other Wednesday|
|経過時間指定|in 2.5 hours|
|時刻指定|at 16:00|


## 例
### 隔週金曜日の14:50に#dev-workチャンネルで@engineersにリマインドを送る

```
/remind #dev-work @engineers エンジニア会がもうすぐ始まります。KPTを考えておきましょう at 14:50 every other Friday
```

コマンドが認識されると、こんな感じで設定されます↓

![1380c314-9ce9-a822-1408-56867cab8f38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/e0adff6b-e655-9254-8e7b-d562534deb0d.png)

リマインドを確認は`/remind list`で行えます。

### 平日毎日14:00に自分に対してGitHubからの通知をチェックするリマインドを送る

```
/remind me GitHubのPRをチェックしましょう。 https://github.com/notifications at 14:00 every weekday
```




## 参考
- https://get.slack.help/hc/ja/articles/208423427-%E3%83%AA%E3%83%9E%E3%82%A4%E3%83%B3%E3%83%80%E3%83%BC%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B
[AWS] EC2 MEMO

##EC2の概要
- 従量課金性の仮想サーバー
- 管理者権限で利用可能
- OSは既存のAMIから選ぶ
- OSより上のレイヤーをユーザは設定できる
- 既存AMIへ様々な設定などをしたAMIを保存、再利用可能

###AMIってなんですか？
AMI = Amazon Machine Image
AWSが提供しているOSが入ったサーバイメージ
または第三者や自分が既存AMIに設定を施したサーバイメージのこと（S3に保存できる）
AMIは他人に売ったりもできる

##EC2でサーバを立てようってなったときの基本知識
###AMIイメージの選択する
用途によってAMIを選択しよう
どういった観点から選ぶべきなのか？などはいずれ・・・

###インスタンスタイプの選択する
t2.nano = tシリーズの２世代目、インスタンス容量がnanoって意味
シリーズの何世代がどういった特徴を持つのかは[こちら](https://aws.amazon.com/jp/ec2/instance-types/)で見れる

####蛇足：お得になるリザーブドインスタンス
使用量が予測できるサービスの場合は
企画提案やサーバーの費用の皮算用するときの大きな助けになるかも・・・

・1年or3年の長期契約する代わりに安い
・一応途中で売れる
・年数とは別に以下２つのコースから選ぶ
**スタンダートコース(40~60%off)**
変更項目の可能範囲に制限がかかる
インスタンスファミリー/OS/テナンシ/支払いオプションの変更不可など
**コンバーティブルコース(31~54%off)**
スタンダードより制限が緩い

####蛇足：かなり安いけど危なすぎるスポットインスタンス
AWSでは常に予備容量を保持しているが、これがあるタイミングで売り出されることがある

- 最大90%offスタートの入札式での価格決定
- 起動が遅い
- あくまで予備容量なので**途中で消される可能性もある。よって用途は限定的**

####蛇足：物理対応EC２インスタンス
物理的に分離されたサーバーを設置したい場合の選択肢
**ハードウェア専有インスタンス**
他のAWSアカウントと物理的に分離されたインスタンスが欲しい場合に使う
同一アカウント内では共有する可能性あり
**Dedicated Host**
上記に加え、同一アカウントでも共有しない
**Bare Metal**
通常では行いないサーバーのメモリやプロセッサに直接アクセスできる

###VPSとサブネットを設定する
のちのち・・・・

###サーバー起動時実施するBashコマンドの設定
`yml update -y`などのサーバ設置時共通で行うようなシェルなどを設定できる
『インスタンスの詳細設定』の『高度の詳細欄』にコマンドを入力することで自動で実行される

###ストレージの選択する
EBSの中から何を選ぶか。

####ストレージにはどんな種類があるの？
以下の２つ。どちらも必ずEC2につけるもの
**・インスタンスストア**
EC2にそもそもついている物理ストレージ
一時ストレージを保存するような場所だがEC2の停止などですべてクリアされる
**[・Elastic Block Store(EBS)](https://qiita.com/nsmyuzin/items/670acc1dc87d3b7ff6de)**
EC2とは独立して管理されているストレージ
画面的にはEC2を選ぶ一貫になってるが内部的には別に管理されている。
EC2は他AZ内のEBSには接続できない。

###セキュリティグループの選択する
iptableのようなファイアーウォール機能のこと、ただしインバウンド設定のみ
デフォルト:２２ポートのみ開放

###SSHキーペアの設定する(秘密鍵の設定)
省略。
登録したキーペアはリージョンごとに管理されてる模様。

###ElasticIPで固定IPにする
EC２にはデフォルトでパブリックIPがあるがそれ動的。
静的にするにはElasticIPなる静的IPを割当(取得)しEC2に設定する必要がある
**ElasticIPアドレスは取得して使う分には無料だが、取得して設定せずに使わず放置しておくとその間料金がかかる点に注意。使わなくなったら開放しよう**
1.ElasticIPの割当（固定IPの取得）
2.EC２へElasticIPを設定
蛇足.ElasticIPを開放(削除)
deviseの日本語対応

## deviseメッセージの問題点

deviseのセットアップを無事に完了して、ユーザーの登録、ログイン機能を実装して使用した後に気になることの１つにエラーメッセージなどが全て英語であることがあると思われます。そこで今回はdeviseのメッセージを日本語化する手順を紹介していきたいと思います。

また今回はdeviseの日本語対応に限定しています。Railsの日本語化対応の記事ではありませんのでご注意下さい。

## devise-i18n gemを使うかどうか

deviseにはdevise-i18nというdeviseのメッセージを日本語化してくれるgemが存在します。そのgemを使うという選択肢がもちろんあるとは思うのですが、結局のところ自分が作っているアプリケーションによってメッセージの内容なども変わって来るため、メッセージの日本語化にgemを導入してコードを大きくするよりは、今回は自分が作っているアプリケーションで必要になる範囲で、コンパクトに実装していくので十分だと思います。

## 日本語メッセージを設定するymlファイルを作成する

まずはconfig/localesの下にすでにdevise.en.ymlというdeviseの英語メッセージを設定しているファイルがあるので、そちらと同じ階層に同じようにdevise.ja.ymlファイルを作成します。今回はこちらのファイルに日本語のメッセージを設定していきたいと思います。始めにdevise.en.ymlの内容を全てdevise.ja.ymlコピーして編集すると、設定しやすいと思います。

それでは実際にエラーメッセージを日本語にしていきます。ユーザー登録画面でメールアドレスとパスワードを空欄にして登録しようとすると、下の画像のようにエラーが表示されます。

<img width="384" alt="スクリーンショット-2019-07-19-13.17.07-768x627.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/5b3203f8-d04a-bc7f-d311-5a5bd441efe8.png">

上の画像のエラーメッセージを日本語メッセージに変更します。devise.ja.ymlの最終行の、

```devise.ja.yml
other: "%{count} errors prohibited this %{resource} from being saved:"
```

を次のように編集します。

```devise.ja.yml
other: "%{count}個のエラーがあるため、ユーザーを保存出来ません。"
```

また、config/application.rbの末尾に

```config/application.rb
config.i18n.default_locale = :ja
```

を追加してrails sコマンドででサーバーを再起動すると、

<img width="384" alt="スクリーンショット-2019-07-19-13.45.44-768x198.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/4d45a3cc-db34-8f79-2e24-7c7cc8c4cb5e.png">

このようにdeviseのメッセージが日本語に変換されました。後は同じ要領で変更したいdeviseのメッセージ文をdevise.ja.ymlの中で編集すれば解決できます。
[AWS] EBS MEMO

#EBSについて
Elastic Block Storeの略称。EC２には必ず付与しなくてはならないもの。

- OSやアプリ、データの置き場所など様々な用途で使用
- ネットワーク接続型のストレージ
- 99.999%の可用性
- サイズは１G~１６T
- デフォルトで同一AZ内で冗長化がされている。
- セキュリティグループ設定の管理対象外
- EC2を削除しても永続的に保存される
- EBSを複数のEC2で共有は出来ない(逆はできる)(他のインスタンスへの付替可能)

##EBSのSnapshot
EBSのバックアップを取れる。復元などの際リージョン、AZが異なっていてもOK
圧縮後の容量にたいして課金が行われる
増加バックアップ形式
S3に保存される
**注意すること**
snapshotを取るときは静的な状態で取得されることが推奨されている。
バッチなどが動いていない、サーバーを停止されているような状態。

##AMIとSnapshotの違いって？
・AMI
**EC２インスタンス**のOS設定のイメージ。新規インスタンス設定に使うもの。
立ち上げ時のEBSも再現する
・Snapshot
(AMIがEBS初期状態のみ再現できるに対して)**ストレージ/EBS**のそれぞれのある時点の断面バックアップ。
  ストレージの復元や複製に使う。とかいいつつイメージの復元も可能

##EBSのボリュームタイプ（種類）
- SSD
    - 汎用SSD
        - 低レンテンシー・小中規模DB・開発環境・仮想デスクトップ
        - 1TB~16TB
    - プロビジョンドSSD
        - I/O性能を求められるNoSQLやアプリ/10000IOPS,160Mbsのものなど
        - 4GB~16TB 
- HDD
    - スループット最適化HDD
        - ビックデータやログ分析など
        - 500GB~16TB
    - コールドHDD
        - バックアップやアーカイブなどのアクセス頻度が低いものに
        - 500GB~16TB
- マグネティック
    - 気にしなくていい。古いタイプ
WordPressについて調べてみた

##メリット
- Webサービスを簡単に構築できる
- 専門知識が不要
- デザイン・レイアウトが豊富でカスタマイズし易い
- 数多くのプラグインが存在し好みのスタイルで制作できる
- 世界中の開発者がプラグインを制作・更新しているため、常に新しいモノを利用することができる
- 無料でも始められる

---

##デメリット
- 高度な設計にするほどプラグインのコストがかかる
- 日本語対応でないプラグインも多い
- 決済手段の手数料がかかる
- 利用者が多いほどセキュリティ面で脆弱性がある
- 会員情報などを取扱う際に、データの表示速度が遅い
Railsで「ホーム画面に追加」の画像設定する方法

RailsでWebクリップ(ホーム画面のショートカットアイコン)を設定する方法

# version

ruby 2.5.3
rails 5.2.3

# 方法
まず、144 × 144サイズのpng画像を用意する。
（小さかったり大きかったりすると読み込んでくれない）


public/直下のデフォルトのapple-touch-icon.pngファイルを削除し用意した画像ファイルをおく。

ここではファイル名を「apple-touch-icon.png」とする。
（おそらくなんでもいいと思うが試してはいないです）

application.html.erbのheadに下記の記述をする。

```
<link rel="apple-touch-icon" href="apple-touch-icon.png">
```

これでプッシュしてサーバー（Heroku）にアップすればOK！
curl コマンドで複数のクエリパラメータを送信する(cloudfront)

#極めて初心者でした。。。うっかり

なんとなくCloudFrontを使ってみて、S3にLogを出力して、内容を見てみたのですが、クエリパラメータ1つしか書かれていない！？となってしまいました。
[クエリ文字列パラメータと CloudFront アクセスログ](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/QueryStringParameters.html#query-string-parameters-access-logs)
公式documentにはCloudFront は、クエリ文字列パラメータを含む完全な URL をログに記録しますと書いてありました。。。

原因としては`curl`の使い方は不適切でした。
` curl -v https://<domain>/items?goods=tray&price=100&order=1554958`
正しくは、` curl -v https://<domain>/items?goods=tray\&price=100\&order=1554958`でエスケープが必要でした( ；∀；)
[curlで複数パラメータのGETを投げる](https://qiita.com/nobu_121/items/52bb9d5961aa3e017813)

こんなポン超すなミスする方は他にはいらっしゃならいと思いますが、自分への戒めのために、記録しておきます。

#Amazon Linux で　CloudFrontのログ解析

[ウェブディストリビューションのログファイル形式](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#BasicDistributionFileFormat)

コピペコマンド
毎分のキャッシュヒットとクライアントIP、パス、クエリパラメータを確認することができます。

```
aws s3 sync s3://<backetname>/cloudfront/ ./logs
gunzip -dc * | awk '$8 == "/items"' | sort | awk '{print substr($2, 0, 5), $1, $5, $8, $12, $23}' | sort | awk '{print $2, $1, $6, $3, $4, $5}' | uniq -c
      1 2019-08-08 08:03 Miss 126.193.5.58 /items goods=tray&price=100&order=1554958
```
[コピペで使えるELBのアクセスログ解析による事象分析 (ShellScript, Athena)](https://qiita.com/hayashier/items/87084e60b29a316ca286)

#Amazon Athenaでログ解析
[Amazon CloudFront ログのクエリ](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/cloudfront-logs.html)
めちゃくちゃ簡単にログが見れる－
*末尾2行目のLOCATION　のbacketnameの変更を忘れることなく！！

特定のuriの最新のログを確認する

```
SELECT date, time request_ip, uri, query_string
FROM cloudfront_logs
WHERE uri LIKE '_items'
Order by date DESC ,time DESC
Limit 10
```
Amazon Glueと組み合わせつことで簡単にテーブルを作成することも可能だが、スキーマががたがたですな。
Angularでデモアプリ作った

デモアプリのリポジトリは[こちら] (https://github.com/topgate/automl-demo)

気づきやちょっとしたテクニックなどを解説

- コンポーネントをRouterで切り替えてるので画面遷移すると元の画面の処理がキャンセルされると思ってたけどそんなことなかった。
- 入力画面 → ロード画面 → 結果画面と遷移する。
- 結果画面から入力画面にブラウザバックで戻れるよう`replaceUrl: true`にする。
- service.postでobservable型が返ってくるので、リストにしてforkJoinですべての結果を待つ。
- 結果画面への値の受け渡しはservice経由で行う。

```typescript
    // リクエスト作成
    const requests = [];
    params.forEach(param => {
      requests.push(this.service.post(param));
    });

    // situationをserviceに保存
    this.service.setSituation(situation);

    // loading画面に遷移
    this.router.navigate(['loading']);

    // リクエスト実行
    forkJoin(requests).subscribe(res => {
      // 成功した場合、resultに遷移
      this.service.setResponse(res);
      this.router.navigate(['result'], { replaceUrl: true });
    });
```



参考
https://stackoverflow.com/questions/51427689/angular-5-remove-route-history
https://angular.io/api/router/NavigationExtras#replaceUrl
LPのルール

#BEAFの法則

---

##商品ページの構成・順序は"BEAF"で表現する
- Benefit（購入メリット）
- Evidence（論拠）
- Advantage（競合優位性）
- Feature（さまざまな特徴）

---

###お客様に商品を買ってもらうためには、適切な情報・掲載順序を守りで提供しなければならない。

---

###ユーザーがそのページを評価するのにかかる時間はたった"数秒"

---

###気になっても欲しいと思わせる内容にしなければ何の意味もない

---

###その思いをどう購入へ結び付けられるかがLPを作るための本来の意味である

---

###よって不安要素を全て取り除いた形が完成と言えるだろう

---

###ユーザーの声を聞きながら定期的に更新を行う
Get Lost Love Back

We are no.1 astrologer in India. we help people to get lost love back with <a href="http://getxloveback.com/tag/%e0%a4%b2%e0%a5%8c%e0%a4%82%e0%a4%97-%e0%a4%b8%e0%a5%87-%e0%a4%b5%e0%a4%b6%e0%a5%80%e0%a4%95%e0%a4%b0%e0%a4%a3-%e0%a4%95%e0%a4%be-%e0%a4%89%e0%a4%aa%e0%a4%be%e0%a4%af">लौंग से वशीकरण का उपाय</a>
[Golang]スライスに要素を追加する「append関数」の使い方

# いきなりサンプル
```golang:Go：append関数のサンプル
package main
import "fmt"

func main() {
	s := []int{0, 10, 20, 30}
	fmt.Println(s) // => [0 10 20 30]

	s = append(s, 1, 2, 3, 4)
	fmt.Println(s) // => [0 10 20 30 1 2 3 4]
}
```

# 解説
## append（追記する、付け加える）
appendには、「追記する、付け加える」という意味があるそうです。
Goではスライスに要素を付け加える…といった関数です。

## サンプル全体の解説
`s := []int{0, 10, 20, 30}`
ここの部分で、スライスを宣言し、同時に代入。

`s = append(s, 1, 2, 3, 4)`
ここの部分で、「1, 2, 3, 4」を追加して、再びsに代入しています。
**１つ目の引数は、追記元が入るので、注意**してください。
[batファイル]フォルダの複製2

前回、
[フォルダの位置を絶対パスで指定してフォルダの複製ができました](https://qiita.com/wooca/items/6ce1b97e4c0f6aeb83b1)

次にbatフォルダある場所を取得して、
そこをカレントディクトリ（現在の位置のディクトリ）にするようにしました。

```コマンドプロンプト
cd 絶対パス
xcopy /t /e "素材" "書き出し"
```
を

```コマンドプロンプト
cd /d %~dp0
xcopy /t /e "素材" "書き出し"
```

にするだけで、どこのフォルダでもフォルダの複製ができました～～～～！
正直、仕組みはよくわかってない！

参考にした記事はこちら
[カレントディレクトリをバッチファイルのディレクトリにする/強火で進め](
http://nakamura001.hatenablog.com/entry/20090203/1233652705)

- わかったこと
  - %0 にバッチファイル自身のファイルパスが格納されている。
  - /d のオプションを指定すると、cdだけではできない、ドライブの変更もできる。

- わからないこと
  - 記述が%0ではなくて%~dp0であること

>%~dp0 は %~d0 (ドライブ名)と %~p0 (パス名)を組み合わせた記述方法の様です。

と、記事にはあるのでそういうもの、と思ったほうがいいんでしょうか。

##追記
```コマンドプロンプト
xcopy /t /e "素材" "書き出し"
```
だけでも動きました。
ファイル結合PWShell


<p> PowerShellを利用した複数のファイルを結合したファイルを出力するスクリプトのサンプルです<br>
今回作成したソースはFileJoin.ps1です.<br>
</p>

<p>内容</p>
 <ol>
   <li>参考サイト</li>
   <li>使い方</li>
   <li>ReplaceFile.ps1</li>
 </ol>
<hr>
<p>1.参考サイト</p>
<p>以下のサイトを参考に作成しました</p>
<a href="https://qiita.com/diskn/items/0299c13e1a6e3652e621">
PowerShellでテキストファイルを結合する - Qiita</a>
<br>
<hr>
<p>2.使い方</p>
<p>
スクリプト内の入力フォルダ・出力フォルダのパスを適宜設定し、
結合のファイルを入力フォルダに置き、実行することで置換ができます。

</p>
<hr>
<p>3.ReplaceFile.ps1</p>
<pre>
<code class="PowerShell">
##出力ファイルを出すフォルダ(適宜変更)
$outputFolder = &quot;C:\hogehoge\powerShellScript\output&quot;;

##入力ファイルを置くフォルダ(適宜変更)
$inputFolder = &quot;C:\hogehoge\powerShellScript\input&quot;;


##出力ファイル名
$outputFileName = &quot;JoinedFile.txt&quot;;
$outputFilePath = $outputFolder + &quot;\&quot; + $outputFileName;

##ファイルが既にある場合は削除
if(Test-Path $outputFilePath){
    Remove-Item $outputFilePath;
}

Get-ChildItem $inputFolder -File -Filter &quot;*.txt&quot; | Get-Content -Encoding UTF8 | Add-Content $outputFilePath;

</code>
</pre>
<hr>


<script src="jquery-3.3.1.min.js"></script>
GetOpenFilenameのデフォルトフォルダを変更する

# はじめに

```vb:test.xlsm
Sub test()
    Dim file_name As String
    file_name = Application.GetOpenFilename
    Debug.Print file_name
End Sub
```
を実行した時、ダイアログのデフォルトフォルダは
*C:\Users\xxxx\Documents*
である。これでもいいけど、デフォルトフォルダは開いているエクセルファイルがある場所の方が使いやすいな～

# カレントフォルダを変更するだけ

デフォルトフォルダはカレントフォルダである。つまりカレントフォルダを変更すればOK。

```vb:test.xlsm
Sub test()
    Dim file_name As String
    ChDir ThisWorkbook.Path 'ここを追加
    file_name = Application.GetOpenFilename
    Debug.Print file_name
End Sub
```
※カレントフォルダを変更することで、他のプロセスに影響が出る場合もあるので注意が必要
AWSの環境(python,node.js)を整えた日

ターミナルからAWSのコンソールにログイン後

###Rubyをいれた(brew用)

###linuxbrewを入れた
```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
```

####設定を書き込む(このままコピペでいける)
```
test -d ~/.linuxbrew && PATH="$HOME/.linuxbrew/bin:$HOME/.linuxbrew/sbin:$PATH"
test -d /home/linuxbrew/.linuxbrew && PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
test -r ~/.bash_profile && echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.bash_profile
echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.profile
```

###pythonを入れた
```
brew install python
```

####環境変数のpathに書き込み
```
alias python="python3"
```

####pipをいれた
```
curl -kL https://bootstrap.pypa.io/get-pip.py | python
```

###nodeを入れる

####システムアップデート
```
$ sudo yum update
```

####g++コンパイラ入れる(Nodeモジュールのコンパイル用)
```
$ sudo yum -y install gcc-c++
```

####nvm入れる
```
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash
```

####有効に
```
. ~/.nvm/nvm.sh
```

####安定ver いれる
```
nvm install stable
```


参考
https://dev2prod.site/settings/install-homebrew-on-linux/
https://qiita.com/sebeckawamura/items/4bc5945245877f250d2e
https://ja.stackoverflow.com/questions/44308/homebrew%E3%81%A7python3%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E3%81%A8pip%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84
https://qiita.com/suzuki_y/items/3261ffa9b67410803443
https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions-enterprise-linux-fedora-and-snap-packages
https://qiita.com/oishihiroaki/items/bc663eb1282d87c46e97
[Golang]スライスの定義＆代入のサンプル

# とりあえずサンプル

```golang:Go：スライスの宣言と代入サンプル
package main
import "fmt"

func main() {
	s := []int{0, 10, 20, 30}
	fmt.Println(s) // => [0 10 20 30]
}
```

# 書き方が配列の場合と似ているので注意

```golang:Go：配列の定義と代入サンプル
package main
import "fmt"

func main() {
	a := [...]int{0, 10, 20, 30}
	fmt.Println(a)
}
```

# スライス定義・代入の特徴
`[]`の中に何も入れない。
配列と紛らわしいので、注意する。
AWSでリージョンを東京に設定する方法

# なぜリージョンを東京に設定する必要があるのか

Amazon Web Serviceのサブネット作成時に個人的につまづいたので共有したいと思います。VPC(Virtual Private Cloud)のダッシュボードのサイドメニューからVPCの下のサブネットのメニューを選択します。すると次の画面になります。

<img width="384" alt="スクリーンショット-2019-07-19-16.00.32-768x559.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/aeb47f9e-cac9-6363-107c-ba08929ad5f0.png">

そしてページの上の方にある「サブネットの作成」ボタンでサブネット作成しようとします。そこで東京リージョンの設定にしていればアベイラビリティゾーンを「ap-northeast-1a」「ap-northeast-1c」などに設定出来るとのことなので、設定しようとしたところ何と「ap-northeast-1a」「ap-northeast-1c」が選択出来ませんでした。確かに登録時に東京リージョンに設定するところがあったかも思い出せませんでした。アカウント設定など色々見てみてもリージョンを選択するところは見つけられませんでした。ふと右上の方に視線をうつすと、

<img width="384" alt="スクリーンショット-2019-07-19-16.27.23-768x596.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/192acf1f-a316-90c3-a326-2889d58d2dae.png">

「オハイオ」というところが気になり選択してみると「アジアパシフィック（東京）」....ありました。早速こちらをアジアパシフィック（東京）に設定してみます。リージョンの変更をした後、今一度サブネット画面に戻りもう一度「サブネットを作成」ボタンを押して確認してみます。アベイラビリティゾーンを確認してみると、無事に「ap-northeast-1a」「ap-northeast-1c」などが確認出来ました。
Unity用ローカルネットファイル転送アセットでハマったこと

# はじめに
ロケーションベースの多人数参加型アプリケーションを作る場合、ローカルネットワーク内で、あるPCからべつのPCへファイルを転送させたい場合があります。Unity用のアセットでそれをしてくれるものに、[File Transfer Server](https://assetstore.unity.com/packages/tools/network/file-transfer-server-73518) というのがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/7932ce5a-64e1-2153-7853-ddd2ff90fcbc.png)

PCやスマホを問わず、普通のUnityアプリ間でファイルのやり取りを実現してくれるので、私のようにネットワークプログラミング音痴にはありがたいアセットです。

# PCからWiFi経由でファイルをやり取りできない

File Transfer Serverは、UDP通信を使っているので、10.x.x.xのプライベートIPアドレスを使うのですが、なぜかWiFiにつないだPCにおいては192.168.x.xを使ってしまうため、上手く接続できず、ファイルの転送ができませんでした。

# Microsoft Wi-Fi Direct Virtual Adapterのせい？

このFile Transfer Serverが掴んでしまう192.168.x.xは、Microsoft Wi-Fi Direct Virtual Adapterによるローカルエリア接続用のものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/43cde301-728e-b2b9-bd72-dc675a5afcf5.png)

なので、これを無効にすると、File Transfer Serverは10.x.x.xを使ってくれます。

# もっと良い解決方法は？

もっと良い方法があるかもしれません。コメントいただければ幸いです。
GoogleMapAPIMemoサンプル


<p> Google Map Apiを使用したマップメモのサンプルです<br>
今回作成したソースはpage5.html, sample5.js, style2.cssです.<br>
<br>
・ソース修正しました.(インポート時のIDセット処理修正、マーカ削除時の動作を追加) 2019.03.10<br>
・ソース再修正(現在地をセットボタン,マーカをリストの先頭にボタンを追加、参考サイト追加) 2019.03.23<br>
・ソース再修正(スマホ表示時のセレクトボックスの表示を修正、参考サイト追加) 同2019.03.23<br>
・ソース再修正(マーカ追加時のバグ修正) 同2019.03.23<br>
・サンプルデータ追加(菊川駅周辺のカラオケ店の値段マップメモ) 2019.08.22<br>
</p>
<p>サンプルgithubURL：https://github.com/NanjoMiyako/GoogleAPIMapMemo</p>
<p>内容</p>
 <ol>
   <li>参考サイト</li>
   <li>参考素材</li>
 </ol>
<hr>
<p>1.参考サイト</p>
<p>以下のサイトを参考に作成しました</p>
<a href="https://www.javadrive.jp/google-maps-javascript/">
Google Maps JavaScript API入門
</a>
<br>
<a href="https://postd.cc/script-injected-async-scripts-considered-harmful/">
JavaScriptの読み込みにおける非同期スクリプト注入の悪影響 | POSTD
</a>
<br>
<a href="http://tech-blog.tsukaby.com/archives/894">
JavaScriptで動的にscriptタグを差し込んだり、実行する方法 | つかびーの技術日記
</a>
<br>
<a href="https://www.tagindex.com/stylesheet/box/width_height.html">
スタイルシート［CSS］/ボックス/ボックスの大きさを指定する - TAG index
</a>
<br>
<a href="https://qiita.com/ritukiii/items/fdc63532d31cc1ed2c50">
ボックスレイアウトの基本をマスターしてサクッとwebページを作れるようになろう - Qiita
</a>
<br>
<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">
JSON.stringify() - JavaScript | MDN
</a>
<br>
<a href="https://so-zou.jp/web-app/tech/programming/javascript/dom/node/element/html/select/">
Selectオブジェクト (ドロップダウンメニューとリストボックス) | JavaScript プログラミング解説
</a>
<br>
<a href="https://qiita.com/miiitaka/items/f77cb83b9dfcd05aea82">
jQuery で JSON ファイルを読み込む - Qiita
</a>
<br>
<a href="https://syncer.jp/how-to-use-geolocation-api">
JavaScriptで位置情報を取得する方法(Geolocation API)
</a>
<br>
<a href="https://webnetamemo.com/coding/jquery/201606253129">
JavaScriptでスマホやタブレットを判別する方法
</a>
<br>
<hr>
<p>2.参考素材</p>
<p>以下のサイトの素材を利用しました</p>
<a href="http://waox.main.jp/news/?page_id=229">
アイコンとマーカーのサンプル一覧表（影付き）／Google Maps API　 | WordPressにGoogle Maps API V3！
</a>
Photoshop使ってみた

##メリット
- アンカーポイントを保存する為データが軽い
- 細かい編集機能が備わっている
- 色の種類が豊富で編集、加工がしやすい

---

##デメリット
- 契約料が高い。
- ペンツール、ブラシツールを使いこなすのが難しい
- 動作環境にもよりますが重く感じることが多い
- ツールの種類が多いのに、バージョンアップで使えなくなるツールもやや多い
さくらのVPSにおけるポート開放の落とし穴

さくらインターネットのVPSサービス(さくらのVPS)においてポート開放がどう頑張ってもうまくいかずに詰んだのでそのときの話を共有します。(2019年8月7日)

## 前提条件
* __さくらのVPSを使用している__
* iptables or firewalld の設定では目的のポートは開いている(80/tpcなど)
* 外部からアクセスした際にポートが開いていないことになる
* SSHログインし、curl で叩いたときは問題ない(内部からはアクセスできる)

## 私の環境
- firewall-cmd の実行結果

~~~bash
# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: ssh dhcpv6-client http https smtp smtps pop3 pop3s imap imaps
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
~~~

- curl 実行結果

~~~bash
# curl localhost:80
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  test
</body>
</html>
~~~

## 原因
#### さくらのVPS サーバー管理パネル 「パケットフィルタ」
前提条件を長々書きましたが、とりあえず[サーバー管理パネル](https://secure.sakura.ad.jp/vps/#/login)からパケットフィルタを確認してください。
![Qiita_20190809_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477307/3acab5d8-0561-6ff8-7895-c79a576ffe53.png)

何故か有効になっていてしかもSSH以外許可しないという~~おかしな~~設定になっていませんか？
どうやら2019年6月27日にさくらインターネットが提供し始めた機能のようです。
[さくらのVPS 「パケットフィルタ」提供開始のお知らせ](https://vps-news.sakura.ad.jp/2019/06/27/vps-pf/?utm_source=newsletter&utm_medium=email&utm_campaign=20190807)
さくらインターネットからのメール(8月7日)で初めて知りました。
従来はサーバー内からしか行えなかった「外部からの着信パケットに対して通信制限を行う」ことがサーバー管理パネルから設定できるようになったのは素敵ですね。

## パケットフィルタの設定方法
おそらく管理画面をご覧になれば大丈夫かと思いますが、下記ページに記載があります。
https://vps-news.sakura.ad.jp/vps-pf/

許可設定が完了したらブラウザからテストページを読むこむことが可能になりました。

~~## もの申したいこと~~
~~1. なぜデフォルトで有効になっているのか~~
~~2. なぜデフォルトでSSH以外無効なのか~~
~~3. 告知がひっそりとし過ぎていないか~~

## 以上です
初めてのQiita投稿です。
Windows Android iOS で問題を問題を起こさないDateの引数

# new Date(文字列)の機種依存の問題
MySQLからそのままJSONで出力した日付文字列（例：2019-08-09 14:53:10）はJavascript上でそのままDateのコンストラクタに渡せません。

|文字列|IE11|Edge|Chrome|FF|iOS|
|:-:|:-:|:-:|:-:|:-:|:-:|
| 2019-08-09 15:00:00|×|〇|〇|〇|×|
| 2019/08/09 15:00:00|〇|〇|〇|〇|×|
| 2019-08-09T15:00:00+09:00|×|×|〇|〇|〇|

※FF（FireFox）はWindows上で確認
※ChromeはWindows,Android,iOSで確認
※iOSの確認はiPhoneXSのみ。

## 対策
iOSを判断して出力内容を分ける。
windows、及びAndroid上ではelse側で問題が発生しなかった。（確認ヌル目です。ツッコミ歓迎。）

※下記の例は与えられるdateStringがMySQLのDatetime型をそのままJSON化した形（例：2020-10-01 19:42:35）を想定しております。

```javascript

const dateStringConverter = (dateString) => {
    if(/iP(hone|(o|a)d)/.test(navigator.userAgent)){
        const timezoneOffset = new Date().getTimezoneOffset();
        const sign = timezoneOffset >= 0 ? "-" : "+";
        const hour = Math.floor(Math.abs(timezoneOffset) / 60);
        const minute = timezoneOffset % 60;
        const timeDifference = `${sign}${("00"+hour).slice(-2)}:${("00"+minute).slice(-2)}`;

        return dateString.replace(" ", "T") + timeDifference ;
    } else {
        return dateString.replace(/-/g,"/");
    }
};

const date = new Date(dateStringConverter (dateString));

```
こうしておけば目立った問題は解消しました。
~~+9:00部分はUTCに対するJSTとの差なので上記は日本国内でのみ正常に動作します。
タイムゾーン設定には注意が必要かもしれません。~~

### 参考
> [iOS端末のユーザーエージェントの判別コードは多分これが一番短いと思います](https://qiita.com/tonkotsuboy_com/items/5c703c601de6179e3ce1)

iOS判定はこちらを参考にさせて頂きました。

>[Javascript date is invalid on iOS](https://stackoverflow.com/questions/13363673/javascript-date-is-invalid-on-ios)

iOSで動作するDateのコンストラクタ引数はこちらを参考にさせて頂きました。