OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 16.04にPHP 7.0をインストール（OS標準）

# はじめに

Ubuntu16.04にPHPを標準インストール
親記事：[PHP, PHP-FPMの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/dfe3823554b7caba6f6a)

## LOG

### インストール

```shell-session
# cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

# apt update;apt install -y php
... 略
```

### 各種確認

```shell-session
# which php
/usr/bin/php

# php -v
PHP 7.0.33-0ubuntu0.16.04.6 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.33-0ubuntu0.16.04.6, Copyright (c) 1999-2017, by Zend Technologies

# php -i | grep php.ini
Configuration File (php.ini) Path => /etc/php/7.0/cli
Loaded Configuration File => /etc/php/7.0/cli/php.ini

# apt show php
Package: php
Version: 1:7.0+35ubuntu6.1
Priority: optional
Section: php
Source: php-defaults (35ubuntu6.1)
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 11.3 kB
Depends: php7.0
Supported: 5y
Download-Size: 2862 B
APT-Manual-Installed: yes
APT-Sources: http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
Description: server-side, HTML-embedded scripting language (default)

N: There is 1 additional record. Please use the '-a' switch to see it


# apt show php -a
Package: php
Version: 1:7.0+35ubuntu6.1
Priority: optional
Section: php
Source: php-defaults (35ubuntu6.1)
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 11.3 kB
Depends: php7.0
Supported: 5y
Download-Size: 2862 B
APT-Manual-Installed: yes
APT-Sources: http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
Description: server-side, HTML-embedded scripting language (default)

Package: php
Version: 1:7.0+35ubuntu6
Priority: optional
Section: php
Source: php-defaults (35ubuntu6)
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 11.3 kB
Depends: php7.0
Supported: 5y
Download-Size: 2832 B
APT-Sources: http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages
Description: server-side, HTML-embedded scripting language (default)
```
UIUserStyleInterfaceの指定を小文字の "light" としたらアプリのアップロードに失敗した

## 結論

`UIUserStyleInterface` は大文字始まりの `Light`, `Dark`, `Automatic` を指定しないと、App Store Connectへのアプリアップロードに失敗する。

## 経緯など

iOS 13がリリースされて、Dark Mode対応を求められるようになりました。
アプリ内でモードを指定したい場合、Info.plistのkey `UIUserStyleInterface` に `Light`, `Dark`, `Automatic` のいずれかを指定することで実現できます。

小文字始まりの `light` を指定してApp Store Connectにアプリをアップロードした際に次のようなエラーが発生しました。

```
ERROR ITMS-90785: "UIUserInterfaceStyle can’t be 'light'. It can only be 'Light', 'Dark', or 'Automatic'.
```

大文字始まりの文字列指定にすると、無事アップロードが成功しました。
クロムブックでホームページを更新

クロムブックでホームページを更新する方法です。

更新は次のような流れになります。

　　クロムブック　-> Github -> ホームページ

>クロムブックでの編集には Text を使います。

>Github はこちら
https://github.com/ekzemplaro/html

>ホームページはこちら
https://ekzemplaro.org

１）Linux　の機能で、Git clone を行います。

![Screenshot 2019-09-25 at 19.11.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/0495ec34-8ceb-c55d-d627-194f68ef379a.png)

２）Text で　ホームページを編集します。

![Screenshot 2019-09-25 at 19.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/47017948-f638-1a10-9d24-97787213ab32.png)

３）クロムブックの Linux で、Git push で Github のデータを更新します。

４）ホームページのあるサーバーで、Git pull をかけます。

５）Github を経由しないで、rsync で、クロムブックのデータとホームページを同期させることもできます。
coturnをdockerで建てようとした時に詰まった点

webRTC用にdockerでcoturnを建てようとしたら割と詰まったので備忘も兼ねて

# coturnのリポジトリにはDockerFileやdocker-compose.ymlがある...が
[coturnのGitHub上のリポジトリ](https://github.com/coturn/coturn/tree/master/docker)上にはご丁寧にdockerというディレクトリがあり、README.dockerを読む限りgit cloneしてきてコマンドを叩けばすぐにcoturnをdocker上で起動できそうに見える。

が、実際はそんなに甘くなかった。

## そもそもビルドが通らないので何とかする
残念ながらcoturnのイメージはDockerHub等に置かれていないので、まず自前でビルドする必要がある。
このコマンドの実行自体はReadMe通りにやればいいので簡単だが、そのまま叩くと内部の処理で落ちる。
coturn/DockerFileの修正が必要である。

### aptで取ってきているパッケージのversion指定が古いものを新しくする
このDockerFileが一年近く放置されているせいか、libevent系のものが悉くapt-getに失敗する。
Debianを見に行って取ってこられるものに差し替える必要がある。
後方互換性がきちんと保たれているのか若干不安になったが、ひとまず2019/09現在最新版で問題はなかった。

### 明らかに要らなくて落ちるパッケージを除く
これもDockerFileが作成されたタイミングでは動いたと思われるが、
mongodb-clients辺りもapt-getに失敗する。
このmongodb系のクライアントは、coturnのユーザー保存先にmongodbを使う場合に使用されるが、
mongodbを使わない場合はなくても問題ない。

mongodbを使う場合は(あまりなさそうな気がするが)後継のライブラリをきちんと探すべきだがそれ以外は別に取り除くだけでOK。
他のDB系のクライアントも同様。

## docker-composeの記述が大雑把すぎるので何とかする
ReadMeにはdocker-compose-all.ymlを使えと書いてあるが、
このallの意味はcoturnがユーザー保存先に利用する可能性のあるすべてのDBを建てるである。
どう考えても全部建てるべきケースはないので、どれか自分の使うものだけ選ぶべき。
なお、デフォルト設定の場合SQLiteを利用するので実はcoturnだけで十分である。

## まとめ
* coturnのdockerはそのままでは動かないのでちょっと書き換える必要がある
* とはいえ、自分で1から書いたり手でmakeを叩くよりは遥かにマシなのでおすすめ。
#bitbucket の PullRequest で レビューリクエストを送るには 編集ページを開け。

どこにあるの？と思ったら。Descriptionの下にあった。

![image](https://user-images.githubusercontent.com/13635059/65581513-8df20080-dfb6-11e9-8a84-c775ec97d1c1.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
PrometheusのEC2 DiscoveryをIAMロールを使用して実施する

AmazonLinux2で実施
prometheus version
2.12.0

以下のようなAWS API Keyを使用して書く方法をやめたい。

```
- job_name: 'ec2'
   ec2_sd_configs:
      - region: ap-northeast-1
        access_key: XXXXXXXXXXXXXXXXXXXXXXX
        secret_key: XXXXXXXXXXXXXXXXXXXXXXX
        port: ****
```

AWS管理ポリシーのAmazonEC2ReadOnlyAccessあたりを割り当てたIAMロールを作成し、
prometheus.ymlに以下のように書いて、IAMロールでの実現を試みる。


```
  - job_name: 'ec2'
    ec2_sd_configs:
      - region: ap-northeast-1
        role_arn: 'arn:aws:iam::**********:role/*********'
        port: ****
```
        
以下のようなエラーが出力されてEC2の情報ががゲットできない。

```
level=error ts=2019-09-25T09:40:50.917Z caller=refresh.go:95 component="discovery manager scrape" discovery=ec2 msg="Unable to refresh target groups" err="could not describe instances: AccessDenied: Access denied\n\tstatus code: 403, request id: 8f82e364-df78-11e9-829e-0d4c861ec02a"
```

以下でやりとりされていた。
https://github.com/prometheus/prometheus/issues/4686

IAMロールがEC2に割り当たっていれば下記の設定だけで実現可能。

```
  - job_name: 'ec2'
    ec2_sd_configs:
      -  port: ****
```
AWSサービス、開発者用ツール

# 開発者用ツール

開発者用ツールサービスについての備忘録
サービスの概要・特徴・料金などを簡潔（できれば）に記載します。

## Amazon Corretto

### 概要
本番環境に対応した 無料の OpenJDK ディストリビューション

### 特徴

* Corretto は Java SE 標準と互換性があると認定されている
* Amazon による無料の長期サポートを準備している
* Corretto 8 では、Linux、 Windows、 macOS、 Docker、Corretto 11 supports Linux, Windows および macOS をサポート
* Amazon Corretto は無料でダウンロードして使用できます


## AWS クラウド開発キット

### 概要
最新のプログラミング言語を使用してクラウドインフラストラクチャをコードとして定義し、それを AWS CloudFormation を通じてデプロイするためのオープンソースのソフトウェア開発フレームワーク

### 特徴

* AWS のサービスを使用するための構成詳細、定型文、および Glue ロジックをエンコードするクラウドコンポーネント
* AWS CDK に対する追加料金はありません


## AWS Cloud9

### 概要
コードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE)

### 特徴

* ブラウザのみでコードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE) 
* コードエディタ、デバッガー、ターミナルが含まれる
* サーバーレスアプリケーションを開発するためのシームレスなエクスペリエンスが提供されている
* AWS のサービスに直接ターミナルアクセスできる
* Cloud9 の料金は無料

## AWS CodeBuild

### 概要
ソースコードをコンパイルし、テストを実行し、デプロイ可能なソフトウェアパッケージを作成できる完全マネージド型のビルドサービス

### 特徴

* Java、Python、Node.js、Ruby、Go、Android、.NET Core for Linux、および Docker 用のビルド環境を利用できる
* Microsoft .NET Framework などの自分のビルド環境を、AWS CodeBuild に持ち込んで使用できる

## AWS CodeCommit

### 概要
高度にスケーラブルなプライベート Git リポジトリをセキュアにホスト

### 特徴
* 非常にスケーラブルなマネージド型のソース管理サービス
* 無制限のリポジトリ (デフォルトでは最大 1,000 個まで)
* お客様専用のキーを使用して、AWS Key Management Service (AWS KMS) による暗号化

## AWS CodeDeploy

### 概要
Amazon EC2、AWS Fargate、AWS Lambda、オンプレミスで実行されるサーバーなど、さまざまなコンピューティングサービスへのソフトウェアのデプロイを自動化する、フルマネージド型のサービス

### 特徴

* プラットフォームや言語に依存しておらず、あらゆるアプリケーションで動作
* 以前のリビジョンを再デプロイすることですぐにロールバックできる
* AWS CodeDeploy を使用した Amazon EC2 や AWS Lambda へのコードデプロイに追加料金は必要ありません
* 過去のデプロイのタイムラインおよび変更履歴を調査できる


## AWS CodePipeline

### 概要
完全マネージド型の継続的デリバリーサービスで、素早く確実性のあるアプリケーションとインフラストラクチャのアップデートのための、パイプラインのリリースを自動化

### 特徴

* リリースプロセスのワークフローの視覚化とモデル化
* ワークフローの速度を高める目的で並列実行
* AWS IAM を使用して、リリースワークフローを変更できるユーザーやそれを制御できるユーザーを管理できる

## AWS CodeStar
## AWS コマンドラインインターフェイス
## AWS Device Farm


## AWS ツールと SDK

### 概要


## AWS X-Ray

### 概要
アプリケーションやその基盤となるサービスの実行状況を把握し、パフォーマンスの問題やエラーの根本原因を特定して、トラブルシューティングを行える

### 特徴

* アプリケーション全体で転送されるユーザーリクエストがトレースされる
* アプリケーションに X-Ray SDK を統合して、X-Ray エージェントをインストールするのみ
* Node.js、Java、.NET で記述されたアプリケーションをトレースできる
DOSバッチでバッチファイルを読み込んで編集して書き出したかった

#エンジニア一年生と「rem削除」の闘い
###結論：やめた方がいい
（少なくとも初心者は）

##前提
（免罪符ともいう）
本稿を書いている私は刺身を好きなだけ食える生活がしたいだけの、2019年8月から黒い画面を触り始めたバチバチの初学者です。
完全ではない情報、詰めの甘い部分、もちろん誤った認識等があれば、申し訳ありません。ご指摘ください。
キツい言葉はやめてください。こころおれる。

##要件
1) C:\koko\soko\asoko.bat　的な感じで保存されているバッチファイルの全文から「rem 」を削除する
2) できれば C:\koko\soko　以下にあるすべてのbatファイルに同じ動作を行う
3) さらに可能なら　C:\koko\soko　にあるファイルはそのままバックアップとして保管し、 C:\koko\doko　に実行用ファイルとして「rem 」を削除したファイルを置く
これができれば良かった。

##バッチファイルでやる
###要件1)

```DOS:sample1
@echo off
setlocal enabledelayedexpansion
set motoFile="C:\koko\soko\asoko.bat"
set atoFile="C:\koko\soko\asoko2.bat"

for /f "delims=" %%A in (
  %motoFile%
) do (
  set line=%%A
  echo %%A | findstr /c:"rem " >  nul
  if !ERRORLEVEL!==0 (
    echo !line:~4! >> %atoFile%
  ) else (
    echo !line! >> %atoFile%
  )
)

endlocal
```
**これが鬼門**
読み込みと書き出し自体に問題は発生しなかったが、<motoFile>で
```
set LOG="nanyara.log"
```
等したログファイルが
- %LOG%というお名前で
- カレントディレクトリに
- 完全な状態で
作成されるという現象が発生。

***
※「完全な状態」...　echo %date% %time% start > %LOG%　等して書き出している内容がログとして記載された状態

***
###要件2)
要件1のfor文をちょっといじる。

```DOS:sample2
@echo off
setlocal enabledelayedexpansion
set motoFile="C:\koko\soko\asoko.bat"
set atoFile="C:\koko\soko\asoko2.bat"
set here="C:\koko\soko"

for /f "usebackq" %%A in (
  `dir /s %here% ^| findstr /e /c:".bat" `
) do (
  REM === ここでは%%Aは「.batで終わるファイルのフルパス」を持っている
  call :remDel %%A
)

:remDel
REM === %1の中身は「フルパス」なのでいいようにいじる
REM === （下記はファイル名と拡張子のみにしている）
set %motoFile%=%~nx1
set %atoFile%=ato_%motoFile%

for /f "delims=" %%B in (
  "%1"
) do (
  set line=%%B
  echo %%B | findstr /c:"rem " >  nul
  if !ERRORLEVEL!==0 (
    echo !line:~4! >> %atoFile%
  ) else (
    echo !line! >> %atoFile%
  )
)
exit /b

endlocal
```
- dir /s の「実行結果はフルパスで取得される」と　dir /b の「実行結果をファイル名のみで取得する」は競合して**/sが勝つ**
- 再帰検索が必要な場合は実行結果を加工する必要がある　→　引数として文字列を渡す必要がある
このあたりがちょっと知恵熱出そうになった。
「今この変数は何を抱えているのか」を都度echoで確認していた。
***

###要件3)
```
@echo off
setlocal enabledelayedexpansion
set here="C:\koko"
mkdir %here%doko
set doko="%here%\doko"

REM === まずやること　→　対象のファイルをコピーする
for /f "usebackq" %%a in (
  `dir /s ^| findstr /e /c:".bat"`
) do (
REM === 別の塊を呼んでファイル名を編集　→　コピー
  call :rename %%a
)
goto:EOF

:rename
REM === フルパスを拡張子ありとなしに加工する
set nameEx=%~nx1
set name=%~n1

REM === 書き込み用ファイルを作成する
copy %1 %doko%\re_%name%.txt
type nul > %doko%\re_%name%.txt
set reName=%re_name%.txt

REM === 別のfor文を呼んで対象のファイルを書き込む
call :edit %nameEx% %reName% 

exit /b


:edit
REM === rem を削除して書き込む
set from=%1
set to=%2

for /f "delims=" %%A in (
  %now%testfiles\%from%
) do (
  set line=%%A
  echo %%A | findstr /b /c:"rem " >nul
  if not !ERRORLEVEL!==1 (
    echo !line:~4! >> %now%testfiles\%to%
  ) else (
    echo !line! >> %now%testfiles\%to%
  )
)

exit /b
endlocal
```
あっちいってこっちいってって感じで微妙に気持ち悪いけど筆者の限界がここだった。

##次回へ続く
長くなってしまった。
一応動いたはずのテストコードを編集して記載しているものの編集ミス等で動かない可能性もあるコードたちです。致命的な何かが起こっても責任は負えません。
ただしご指摘をいただければありがたく修正します。
cssで点線をデザインする

## 背景画像で点線を表現する
背景画像にこんな画像を指定して、デザイン要素が入った点線を描いている部分がありました。
[bg_dot.png]
![bg_dot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440375/54ebda7c-788d-b51e-8ef0-881c07c3eb3c.png)

```scss:dot-bg.scss
.dot-line {
  &:after {
    background: url(bg_dot.png) repeat-x 0 0;
    content: '';
    display: block;
    height: 6px;
    width: 100%;
  }
}
```
cssで`border-bottom: 6px dotted #ccc;`などと指定しても、再現できません。
とはいえ、このためだけに画像を用意するのもなー・・・と思い、調べてみました。

## radial-gradientで水玉の背景を描く
まずは、水玉模様の描き方を見つけました。
こちらの記事に、とても詳しく書かれています。
[【CSS】radial-gradient を使って、CSS で水玉の背景を描いてみよー  |  HHH@venture | @venture = Adventure!](https://xlowolx.com/ict/css/201801/1453)

円形グラデーションはこんな活用法もあるとは！

水玉模様を描くコツとして、以下のことが挙げられています。

> ① radial-gradient の色の切り替え部分を計算しやすい数値にする。
> ② 上記①の比率で割り切れる background-size を指定する。
> ③ background-position は、玉の描画位置。


## radial-gradientで点線を描いてみる
水玉模様を応用して、`border-style: dotted;`風の点線を描いてみました。

```scss:radial-gradient.scss
.dot-line {
  &:after {
    background: radial-gradient(circle farthest-side, #707070, #707070 60%, transparent 60%, transparent);
    background-size: 6px 6px;
    content: '';
    display: inline-block;
    height: 30px;
    width: 6px;
  }
}
```
画像を使わず、色や太さ、間隔などもcssで調整できるので、便利です！

## border-style: dashed;の場合
`border-style: dashed;`の間隔を調整したい場合は、`linear-gradient`を利用します。

```scss:
.dashed-line {
  &:after {
    background-image: linear-gradient(to right, #707070, #707070 20px, transparent 10px, transparent 10px);
    background-size: 30px 8px;
    background-repeat: repeat-x;
    content: '';
    display: inline-block;
    height: 10px;
    width: 100%;
  }
}
```

参照
[dottedでもdashedでもない！CSSで好きな間隔の点線（破線）を作る方法  |  amelog](https://www.ameamelog.com/css-dotline/)

### 余談
`linear-gradient`はマーカー的な下線を描く場合も便利です。（サンプル参照）

## サンプル
https://codepen.io/kzmhrd/pen/BaBbWMq?editors=1100#0

## まとめ
分かってしまえば「なるほどー！」と納得ですが、知らないとなかなか出てこないテクニック。
覚えておいて損はないと思います。
cssのグラデーションは、使い所が色々あって便利です。
【Struts或いはサーバーサイドJava】情報収集

#参考サイト
[Struts INDEX](https://www.techscore.com/tech/Java/ApacheJakarta/Struts/index/)
※Struts技術解説シリーズ

[いまさら聞けないサーバーサイドJava 第2回 サーブレットとJSPを使いこなすコツ](https://www.ulsystems.co.jp/topics/035)
※一部引用「サーブレットは通常、スレッドセーフではない」
2019年10月〜12月開催予定大規模カンファレンスまとめ（Web・OSS中心）

2019年10月から12月に日本で開催予定のWeb・OSS系の大規模カンファレンスまとめです
他にオススメのカンファレンスあればコメントでいただけるとありがたいです

# WordCamp NIIGATA
https://2019.niigata.wordcamp.org
2019年10月22日（火・祝）
新潟県長岡市　長岡市シティホールプラザ アオーレ長岡

# WordCamp Tokyo
https://2019.tokyo.wordcamp.org
2019年11月1日(金) – 11月2日(土)
東京都新宿区 ベルサール新宿グランド

# オープンソースカンファレンス 2019 Fall
https://www.ospn.jp/osc2019-fall/
2019年11月23日(土) - 11月24日(日)
東京都日野市 明星大学 日野キャンパス 28号館 2F

# PHP Conference Japan 2019
https://phpcon.php.gr.jp/2019/
2019年12月01日（日）
東京都大田区　大田区産業プラザ PiO

# WordCamp Osaka
https://2019.osaka.wordcamp.org
2019年12月6日(金) – 12月7日(土)
2019年12月6日(金) 大阪府大阪市北区　阪急アプローズタワー　13階貸会議室
2019年12月7日(土) 大阪府大阪市北区　大阪工業大学梅田キャンパス
HTMLからlaravelへ移行　初心者メモ

#views→layoutsの中にuser.blade.phpを入れる
user.blade.phpにはHTMLで作ったindex.htmlが入っている

#viewsの中にtop_page.blade.phpを作る
{{-- layouts/layout.blade.phpを読み込む --}}
@extends('layouts.layout')

#route→web.phpでルーティング設定
Route::get('top_page', 'TopPageController@index');
初心者のうちは纏めたりせず１つずつルーティング設定した方がわかりやすい
top_pageにアクセスされると、top_page_controllerのadd関数に接続

#controllers→TopPageController.php作成
public function index() 
    {
        return view('top_page');
    }
add関数に接続され、top_page.blade.phpを読み込む
クリック時カウントリセット

# クリック時カウントリセットしたい（自分用メモ）

やりたい事
①画面表示した時カウントスタート
②画面のどこかをクリックするとカウントをリセット
③カウントリセットして0からカウントスタートする
※②から③の間はクリックしないこと

イメージ
カウントスタート⇒クリック⇒カウント０⇒カウントスタート

使う関数
①setInterval()

```javascript:javascript
//10カウントした後画面遷移
      var count = 0;
   　 var countup = function(){
      console.log(count++);
      jump(count);
    }

	document.onclick = function (e){
		if(!e) e = window.event;
		console.log(e);
		count = 0;
	};
	var counter = setInterval( countup, 1000 );

	function jump(count){
		if(count == 10){　//カウント10で画面遷移
			window.location.href = 遷移先;
		}
	}
```



#追記
＊2019/10/15 このカウント方法だとクリックするたびに加速する現象が発生して、思うようにカウントが取れない。。。
改良版
画面開いた時間とクリックした時間を比較して画面遷移するように改良

```javascript:javascript

	var displayTime = new Date();

	window.onload = function(){
		//1000ミリ秒（1秒）毎に関数「timeoutDate()」を呼び出す
		setInterval("timeoutDate()", 1000);
	}

	//画面表示時の時刻と処理発生時の現在時刻を比較
	function timeoutDate(){
		var nowTime = new Date();

		//var DifferenceTime = nowTime - displayTime;
		var displaySecond = displayTime / 1000;
		var nowSecond = nowTime / 1000;

		//console.log(displaySecond);
		//console.log(nowSecond);

		var differenceSecond = nowSecond - displaySecond;
		//console.log(differenceSecond);
		if(differenceSecond > 14400){
			window.location.href = 遷移先;
		}
	}

	//クリックイベント
	document.onclick = function (e){
	if(!e) e = window.event;
		displayTime = new Date();
	};
```
生データのpandas dfから偏相関行列を求めるプログラム

# 要点
- pandasのdfから相関行列を求めるメソッドはdf.corr()
- 偏相関行列を求めるメソッドは？
    - 見つからなかった（検索が足りないのかもしれない）。
        - [偏相関係数（行列じゃなく）を求めてる記事](https://www.case-k.jp/entry/2019/04/14/164533)や、
        - [コードなしで計算している記事](https://qiita.com/kenmatsu4/items/e1e93c4216b303639492)は見つけた。
        - [Rのスクリプト記事](https://qiita.com/sbtseiji/items/5efeb3e1285985c61070)もあった。
        - [共分散行列から求める関数を載せている記事](https://omedstu.jimdo.com/2018/03/28/分散共分散行列を相関行列-偏相関係数に変換-python/)はある。
        - [「たぶんメソッドはない」](https://stackoverflow.com/questions/52229220/partial-correlation-in-python)という受け答えのStack Overflow.
    - もしもうあるようだったら教えてほしい……
- pandas dfを引数に取り偏相関行列のdfを返す関数を作ったので備忘録のために置いておく。
    - [この記事](https://www.case-k.jp/entry/2019/04/14/164533)と[この記事](https://omedstu.jimdo.com/2018/03/28/分散共分散行列を相関行列-偏相関係数に変換-python/)のコードを改変したもの。大感謝祭。
- 動作チェックもしたよ！

# コード
```python:p_corr.py
# df: tidy data, column are variable names, index is obs id.
# using numpy as np, pandas as pd
def df_partial_corr(df):
	temp_cov = df.cov()
	omega = np.linalg.inv(temp_cov)
	D = np.diag(np.power(np.diag(omega), -0.5))
	temp_pcorr = -np.dot(np.dot(D, omega), D) \
                         + 2*np.eye(temp_cov.shape[0])
	mtx_pcorr = pd.DataFrame(temp_pcorr, 
                             columns = temp_cov.columns,
                             index = temp_cov.index)
	return mtx_pcorr
```

# 検証
[この記事](https://tjo.hatenablog.com/entry/2013/08/06/203320)のデータを用いて、[この記事](https://blog.goo.ne.jp/r-de-r/e/0e9a855c5f2d536a6b74e05a26f5a27d)がRで偏相関行列を求めているので、これを再現。（[元ネタ記事](https://www.case-k.jp/entry/2019/04/14/164533)の検証を行列に拡張しただけですね）
df_pcorr = df_partial_corr(df) の中身をのぞいてみると、
![Capture.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206520/04e7bacd-cb1a-86f4-7893-299b7f1e2425.png)
問題なく再現できているようです。

# 参考文献
[重回帰、偏相関、パス解析 by 大垣俊一，Argonauta 13: 3-23 (2007)](http://www.mus-nh.city.osaka.jp/iso/argo/nl13/nl13-3-23.pdf)
超分かりやすいPythonのインストール方法 (Windows)

# 初めに
どうもこんにちは。PenguinLuckyです。
色々不備があるかと思いますが、よろしくお願いします。
分からないことがあったら、コメントしてくれたら嬉しいです。

# Pythonをインストールしよう!!
目次

```
Pythonをインストールしよう!!
├─ インストーラーをダウンロードしよう。
├─ Pythonをインストールする
|   ├─ ステップ1
|   ├─ ステップ2
|   ├─ ステップ3
|   └─ ステップ4
├─ Pythonをちゃんとインストールできてるか確認
└─ 失敗したら...
    └─ 一度Pythonをアンインストールする。
```

## インストーラーをダウンロードしよう。
まずは、Python公式サイトから、インストーラーをダウンロードしよう!!
[ここ](https://www.python.org/downloads/) を押すとサイトに飛びます。

上の`ここ`を押すとこんな感じになると思います。
下の画像の`Download Python 3.7.4`を押してください。

今回は、`Python 3.7.3`を使用します。(旧バージョン)
一応 [ここ](https://www.python.org/downloads/release/python-373/) を押すと`Python 3.7.3`のダウンロードのところに行けます。

![Python_download](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/a3a15f42-7ca0-1499-799a-985da79fb941.png)

## Pythonをインストールする
### ステップ1
ダウンロードができたらインストーラーを起動してください。
下のようなものが立ち上がると思います。

立ち上がったら、一番下の`Add Python 3.7 to PATH`にチェックを入れる。
できたら、`Customize installation`をクリックする。

![Python_installer_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/ce8ef688-0829-32a8-ad89-08c87c170d84.png)

### ステップ2

全部にチェックがついていることを確認して次に進む。

![Python_installer_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/6b09d06d-4c5e-192b-c2b4-87e9ee3b798e.png)

### ステップ3

`install for all user`にチェックを入れます。
すると、一番下の、`Customize install location`が、変わると思います。

`Customize install location`は、変えたい方は変えてください。
私は、変えましたw

![Python_installer_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/774d1ff2-9a0f-78e4-9f12-2d851d5bd021.png)

### ステップ4

インストールが始まります。
終わるまで待ちましょう。

![Python_installer_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/24ae70e2-f63d-1fbe-cd32-272e902c9982.png)

終わったら、`Close`を押しましょう。

![Python_installer_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/9b4c73be-d786-c394-198c-04f510ac0ac9.png)

## Pythonをちゃんとインストールできてるか確認

`Windowsマーク`を右クリックして、`コマンドプロンプト(C)`をクリック。
起動できたら、

- `where python` を入力してエンター。
- `where py` を入力してエンター。
- `where pip` を入力してエンター。

```
C:\>where python
C:\Users\*******\AppData\Local\Programs\Python\Python37\python.exe

C:\>where py
C:\Windows\py.exe

C:\>where pip
C:\Users\*******\AppData\Local\Programs\Python\Python37\Scripts\pip.exe
```

こんな感じに表示されたら成功です。

もし、`情報: 与えられたパターンのファイルが見つかりませんでした。` が表示された場合、インストール失敗です。

## 失敗したら...
###一度Pythonをアンインストールする。
キーボードの `Windowsマーク` を押しながら、`R` を押してください。
すると、下のようなものが起動すると思います。
で入力できるところに、`control` を入力してください。
入力したら、OKを押してください。

![uninstall_0](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/637c51fc-c485-2fbd-76b6-6b8bc33f987f.png)

するとコントロールパネルが起動します。
コントロールパネルのプログラムのアンインストールを押してください。
すると、インストールしてるプリグラムが出てきます。その中から、`Python 3.7.3 (32-bit)` と `Python Launcher` をアンインストールしてください。

![uninstall_1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390802/baa9650f-52b7-979a-8464-987a0ce8b0c9.png)

アンインストールできたら、PCを再起動してください。
起動後は、[Pythonをインストールしよう!!](https://qiita.com/PenguinLucky_PL/items/e95863ac5ce004a323bf#python%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86) からもう一度試してみてください。

# 終わり
失敗した人は、コメントしてくれると幸いです。

次回は、`DiscordBotを作る`を投稿する**予定**です。
django-debug-toolbarの導入

# 環境
- python 3.7.4
- django 2.2.5
- django-debug-toolbar 2.0

# インストール

```bash
pip install django-debug-toolbar
```

# setting.pyの変更

```django

INSTALLED_APPS = [
　　・・・
　　'django.contrib.staticfiles', # デフォルトで設定されているはず。
　　・・・
    'debug_toolbar', # 追加する。
　　・・・
]
```

```
MIDDLEWARE = [
　　・・・
    'debug_toolbar.middleware.DebugToolbarMiddleware', # 追加する
]
```

REMOTE_ADDRの確認方法については後述する。

```
# ローカル開発環境の場合
INTERNAL_IPS = ['127.0.0.1',　REMOTE_ADDR] # 追加する
```

# urls.pyの変更

```django

# importしていないものがあれば追加する。
from django.conf.urls import include
from django.urls import path
from django.conf import settings


urlpatterns=[
　　・・・
]

# 以下を追加
if settings.DEBUG:
    import debug_toolbar

    urlpatterns = [
                      path('__debug__/', include(debug_toolbar.urls)),
                  ] + urlpatterns
```

# REMOTE_ADDRの確認方法

適当なviews.pyの関数に以下を追加。

```
def confirm(request):

    # contextの中にrequest.META['REMOTE_ADDR']を追加する。
    context = {
　　    'remote_addr': request.META['REMOTE_ADDR']
    }
    return render(request,'path/to/template_file.html,context=context)
```
あとはrenderで指定したhtmlファイルのbodyタグの中に

```
{{ remote_addr }}
```
と書いてrunserverでhtmlの中身を表示させたら確認完了。

# 参考
- https://gist.github.com/AWSomeHackers/1116615#file-views-py
- https://wonderwall.hatenablog.com/entry/2018/03/13/233000
WindowsでのGitのアカウント切り替え

# 背景
　社内のチームで使う[GitBucket](https://github.com/gitbucket/gitbucket)の整備をルートアカウントで行っていました。その後、自分の個人のアカウントでサインインし直しました。そして、作業用の新しいリポジトリAを作成しました。
　自分のローカルで色々と作業をし、リモートのリポジトリAにpushしたところ・・・
![gitbucket_root.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/8b0d8185-b7ba-476c-1876-3e9041d84dbb.png)

あれっ！個人アカウントじゃなくてrootアカウントでpushされてる！！
ということで対処法です。

# Gitのアカウント切り替え
コントロールパネルを開いて、資格情報マネージャーを開きます。

![control_panel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/5b6d32d1-fad4-8cc3-2d68-325b5f96a68b.png)

Windows資格情報をクリックします。

![windows_credentials.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/aa1236c4-d805-4fb1-5871-72be15a6abad.png)

汎用資格情報のgitを見ると、現在ログインしているユーザー名が確認できます。意図したものと違う場合は「編集」をクリックして資格情報を編集します。

![generic_credentials.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/1cbaaace-c3ad-432c-eefe-62c1df90f5c6.png)

![edit_cerdential.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/732a22ad-88c2-aec9-f738-27b9a0ee2cc8.png)

これでアカウントを切り替えることができました。

# 参考URL
+ https://medium.com/@impaachu/how-to-logout-from-git-in-windows-e17c66fe9ca8
railsでアプリを作り始める際のメモ

各種インストール済み
自分用のメモ

# 準備
アプリ作ります

```
$ rails new myFormApp
```
ちゃんと作られたか確認します
サーバを起動して http://localhost:3000 を開きます

```
$ cd myFormApp
$ rails server
```

<img width="617" alt="スクリーンショット 2019-09-25 14.36.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/131cf682-cc00-d6f3-f048-0d5392cfc591.png">
# Git
gitで管理します

```
$ git init
$ git add -A
$ git commit -m "Initialize repository"
```

# Github
githubにアクセス、ログインしてNew RepositoryでmyFormAppリポジトリを作成します
<img width="1435" alt="スクリーンショット 2019-09-25 16.18.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/b3b6180e-d88a-dcaf-8965-974f3ccbfe5e.png">
GithubをリポジトリのoriginとしてGitの設定ファイルに追加して
ローカルのリポジトリをoriginのリモートにプッシュします

```
$ git remote add origin git@github.com:snaruse0608/myFormApp.git
$ git push -u origin master
```

画面が変わってるのを確認します
<img width="1440" alt="スクリーンショット 2019-09-25 16.33.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/34444755-8b90-70a3-e363-0c76844e5fc1.png">

# heroku
herokuにあげるためにGemfileを修正します
使っているデータベースがローカルとherokuで異なるので、その設定をします。

gem 'sqlite3' はローカルであるdevelopment環境とtest環境で使用して、
production環境(=本番環境)では使用しないようにします。

```ruby:Gemfile
group :development, :test do
  gem 'sqlite3' # ここに移動
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
```

heroku上のproduction環境ではPostgreSQLデータベースを使うようにします

```ruby:Gemfile
# 追加
group :production do
  gem 'pg'
end
```
gemをインストールします
ローカルにはPostgreSQLをインストールしないように注意します

```
$ bundle install --without production
```

成功したらコミットします

```
$ git commit -a -m "Update Gemfile for Heroku"
```

herokuに新しいアプリケーションを作成します

```
$ heroku create
```

作られたらherokuにpush

```
$ git push heroku master
```

# 画面をみてみる
今、Open appを押下するとエラーのページが表示されるので、HelloWorldを表示してみます。
コントローラとルーティング設定を修正します。

```ruby:/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  def hello
    render html: "hello, world!"
  end
end
```

```ruby:/config/routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end
```

githubとherokuにpush

```
$ git add -A
$ git commit -m "hello world"
$ git push
$ git push heroku
```

herokuからOpen appを押下します
<img width="1125" alt="スクリーンショット 2019-09-25 17.26.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/83515a6d-a20f-dbd6-abc7-33f2e5578a32.png">

終わり

# 次から編集する時に毎回やることまとめ
たぶん
## 編集前

```
$ git checkout -b BranchName
```
## 編集後

```
$ git add -A
$ git commit -m “Commit Message“
$ git checkout master
$ git merge BranchName
$ rails test
$ git push
$ git push heroku
```
自作アプリの「いいね！」機能を、YouTube動画で解説してみた

どうも！Hiroyukiです。

今日は、自作アプリに追加した下記の機能の使い方を
YouTube動画で撮影してみたので、投稿しまーす！


###・いいね！機能
###・YouTubeへの動画投稿機能


是非、下記動画で実際のアプリの挙動をみて下さい！

####●自作アプリの「いいね！」機能を、YouTube動画で解説してみた
####https://www.youtube.com/watch?v=Kunnflb2D8M
![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489124/6c1f0db1-5dd6-c6bb-e147-8fc4a60654f4.png)

###自作アプリのURLも、こちらに貼っておきます！

####●YouTubeまとめ × コミュニケーション（PHP/Lalavel/YouTube Data APIを利用）
####http://youtubematome.herokuapp.com

####●サービス全コード閲覧：GitHub
####https://github.com/shiba920sof/youtubematome
<img width="1017" alt="IMG_4064.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489124/dc7ce021-dad1-6f26-b628-3433163b2191.png">


開発過程の記事も、下記の通りQiitaに上げているので是非 Check!!

####●「いいね！機能の実装方法」
####https://qiita.com/Hiroyuki-Hiroyuki/items/e5cb3b6595a7e476b73d

####●ユーザが「いいね！」をゲットした総数を表示させるのは、どうやるの？
####https://qiita.com/Hiroyuki-Hiroyuki/items/2b48a0ad24569b85aa22


YouTubeへの動画アップロード機能については詳細記事は書いてませんが、

#####YouTube Data APIとLaravelを使った開発の方法を書いたドキュメントが英語しかなく、
#####グーグル翻訳などのお世話になりながら、かなり苦労して開発した経験があるので、
#####後日記事にして投稿したいなーと思ってる今日この頃です！

ではまた！
Hiroyukiでした～＾＾
@nuxt/config/index.d.ts' はモジュールではありませんの解決策

### 問題点

```typescript:nuxt.config.ts

import NuxtConfiguration from '@nuxt/config'

const nuxtConfig: NuxtConfiguration = {
...
}

```

```@nuxt/config/index.d.ts' はモジュールではありません```のエラーが出る

### 解決策

nuxtのバージョンが原因

package.jsonでnuxtのバージョンを確認する


```json:package.json

{
...
    "dependencies": {
        ...
        "nuxt": "^2.9.2",
        ...
    },
    ...
}


```

最新バージョン場合、nuxt.config.tsを以下のように修正する

```typescript:nuxt.config.ts

import Configuration from '@nuxt/types'

const nuxtConfig: Configuration = {
...
}

```
javascriptにおけるPush通知について【備忘録】

# 概要

Push通知について調べると、日本語の記事にて情報が錯綜していたので、まとめてみる。以下のふたつについてまとめる。

- Push.js（Notification API）
- Push API

#Push通知とは

Web系において、「Push通知」という言葉がバグワード化しているように感じる。実際、Push.jsとPush APIが言っているPush通知には以下のような違いがある。

- Push.js：ブラウザからデスクトップへのポップアップ通知のこと。
- Push API：サーバからブラウザに対する情報送信のこと。

# Push API

Service Worker上で動作する。ブラウザ対応は以下の通り。

- Chrome
- Edge
- Firefox
- Opera

実装例は、参考に示す。サーバサイドの処理は、Node.jsのexpressライブラリにてアプリケーションサーバを作成する。また、それとは別に送信用のプログラムをweb-pushライブラリを用いて実装している。

```javascript:受信イベント
self.addEventListener('push', function(evt) {
  if(evt.data) {
    var data = evt.data.json();
    evt.waitUntil(
//  受信イベント処理
    );
  }
}, false);
```




# Push.js

Web Notification APIを利用し、実装されている。Service Workerは必要ない。Push.jsはjQueryプラグインである。こちらはブラウザ内のポップアップ処理を指している。サーバからの通信処理は関係ない？


# 注記
　ここでまとめてみたもの、正直これもあまり良いまとめ方ではない気がする。

## 参考

- プッシュ通知の概念と使い方：[https://developer.mozilla.org/ja/docs/Web/API/Push_API](https://developer.mozilla.org/ja/docs/Web/API/Push_API)
- ネイティブPushとWebPushとWeb Notificationの3つの通知方法を整理してみた：[http://garapon.hatenablog.com/entry/2016/04/20/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96Push%E3%81%A8WebPush%E3%81%A8Web_Notification%E3%81%AE3%E3%81%A4%E3%81%AE%E9%80%9A%E7%9F%A5%E6%96%B9%E6%B3%95%E3%82%92%E6%95%B4%E7%90%86%E3%81%97%E3%81%A6](http://garapon.hatenablog.com/entry/2016/04/20/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96Push%E3%81%A8WebPush%E3%81%A8Web_Notification%E3%81%AE3%E3%81%A4%E3%81%AE%E9%80%9A%E7%9F%A5%E6%96%B9%E6%B3%95%E3%82%92%E6%95%B4%E7%90%86%E3%81%97%E3%81%A6)
- The Push API Guide：[https://flaviocopes.com/push-api/#how-the-server-side-works](https://flaviocopes.com/push-api/#how-the-server-side-works)
jQueryなしでJSONPを扱う

外部APIを利用する際に、クロスドメイン対応でJSONPを扱いました。
その際、jQueryなしでゴリっと実装する必要があったため、調べたことのメモです。

## jQueryの場合
jsonの場合とほぼ同様に扱えます。

```javascript:jQuery-jsonp.js
$(function(){
  $.ajax({
    type: 'GET',
    url: '/jsonp',
    dataType: 'jsonp', // ここで設定
    jsonp: 'jsoncallback', // コールバック関数のキーを設定
    jsonpCallback: 'jsonpTestCallback' // コールバック関数名を指定
  }).done((data) => {
    console.log(data);
  });
});
```
コールバック関数のキー、関数名が固定されていない場合は、jsonp、jsonpCallbackを指定しないでOKです。（`?callback=jQuery1900...`が自動生成されます。）

## JavaScriptの場合
### axiosの拡張
axiosの拡張を使えば、手軽に実装できます。
[axios-jsonp  -  npm](https://www.npmjs.com/package/axios-jsonp)

```javascript:axios-jsonp.js
const axios = require('axios');
const jsonpAdapter = require('axios-jsonp');
 
axios({
  url: '/jsonp',
  adapter: jsonpAdapter,
  callbackParamName: 'c' // optional, 'callback' by default
}).then((res) => {
  console.log(res);
});
```
ただし、JSONPのコールバック名は指定できません。

参照
[axiosでサクっとJSONP](https://qiita.com/dojyorin/items/f2b56e0d1346d31a9be3)

コールバック関数名が固定されていない場合は、サクッとできてしまいますね。
ただ今回は、色々と制約があったためうまくいかず・・・ゴリっと実装することにしました。

### ゴリっと実装する
こちらの手順を参考に、実装してみました。
[JSONPをごりごり実装するときのポイント](https://qiita.com/stkdev/items/f3e6cae58ab73faee502)

```javascript
const script = document.createElement('script');
script.src = '/jsonp';
const parent = document.getElementsByTagName('script')[0];
parent.parentNode.insertBefore(script, parent);

window.jsonpTestCallback = (res) => {
  console.log(res);
};
```
概要
1. scriptタグを動的に生成する
2. scriptタグのsrcに、処理させたいサーバ側のファイルを指定する
3. 処理させたいサーバ側のファイルはJavaScriptの関数になっているので、グローバルオブジェクトとしてJavaScriptから利用できる。

`jsonpTestCallback`はグローバルオブジェクトになるので、`window.jsonpTestCallback`としないと「そんなのないよ」と言われてしまいました。。

そのあたりを理解するために、こちらの記事が役に立ちました。
[第11回　JSONP入門：これでできる！ クロスブラウザJavaScript入門](https://gihyo.jp/dev/serial/01/crossbrowser-javascript/0011)

## まとめ
JSONPの場合（各方法共通で）、エラーが返却されないので、「一定時間結果が返ってこない場合はエラー処理をする」などの方法を追加する必要がありそうです。

jQueryやaxiosを利用する場合は、JSONもJSONPも、あまり違いを実感せずに使ってしまえますが、ゴリゴリやろうとすると、そういうことなのか！と改めて勉強になりました。

## 参照
- [JSONPをごりごり実装するときのポイント](https://qiita.com/stkdev/items/f3e6cae58ab73faee502)
- [はじめてのAjax(jQuery) 2018年版](https://qiita.com/zakiyamaaaaa/items/bdda422db2ccbaea60d9)
- [axios-jsonp  -  npm](https://www.npmjs.com/package/axios-jsonp)
- [第11回　JSONP入門：これでできる！ クロスブラウザJavaScript入門](https://gihyo.jp/dev/serial/01/crossbrowser-javascript/0011)
【メモ】人事エンジニアリング勉強会　@Lapras Inc.

# 到達目標
エンジニアリングのおおまかな歴史を学び、よく聞く用語・周辺用語を整理する

# 基本構造
- インターネットを通じてクライアントがサーバにリクエストを送り、サーバがレスポンスを返す
- クライアント側とは：ブラウザ、アプリにあるコンテンツがhtml、CSS、JavaScriptなでを用いて表示される
- サーバ側とは：サーバー機器・OSの上に載っているWEBアプリケーションがデータベースにアクセスしながら問い合わせがあったものを返す

# カテゴリの説明
カテゴリを区別できるようになる

## 開発言語とは？
ページやWEBアプリを作るもの。コンピュータに話しかけることば。
言語は世界中に7000種類以上あると言われている。

## パッケージとは？フレームワークとは？
よく使う処理をひとまとめにしたもの。
フロントエンドのフレームワーク：React、Angular JS、Vue.js
バックエンドのフレームワーク：Ruby on Rails、Laravel、Spring Framework、Django、Selenium、TensorFlow

## データベースとは？
データ（コンテンツやユーザ情報など）をおく場所。
Oracle Databese、MySQL、PostgreSQL等。
※SQLはデータベースを開発する言語ではなく、データを引き出すExcelの関数のようなもの。その命令のひとくくりをクエリと呼ぶ。

## サーバーとは？
全てを載せる箱。
Azure、AWS、GCP　等。
※以前は物理的なサーバを持っているケースが多かったが、今は上記のようなクラウドサーバを利用することがほとんど。

## OSとは？
様々なアプリケーションを動かす大元のソフト。
Linux、OS X、Windows、Unix、Ubuntu、CentOS、Amazon Linux 等。

# エンジニア文化理解のために
## OSSという概念
Open Source Software。
技術をオープンにするという文化があり、その上で技術が急速に発展してきた。
この文化に寄与することは、採用広報にもなる。

## 開発言語どうしのつながり
数年前の経歴にスキル名完全一致を求めることに今はない。
関連のある言語を知ることで要件定義を適切に広げられる。
LaravelでプロジェクトにPrivateな静的ファイルを置く

# 概要

ファイルアップロードなどで動的にファイルをLaravelのプロジェクトに上げる方法は色んな所で紹介がありますが、単にprivateなファイルをプロジェクト内に入れてログインユーザーなどの特定の条件の人にだけ返すというのはあまり見かけなかったので書きます。

# ファイルを置く
resources以下にファイルを置きます。正直public以外だったらどこに置いてもいい説ありますが、resourcesが名前的にもちょうど良さそうです。

```
|
+-- resources
    +-- static
        +-- hogehoge.pdf
```

# ファイルを返す

file_get_contentsでファイルの中身を取り出してレスポンスにして返します。

```php:DownloadController.php
<?php

use Illuminate\Contracts\Routing\ResponseFactory;

class DownloadController extends Controller {

    public function __construct(
      ResponseFactory $responseFactory
    ) {
        $this->responseFactory = $responseFactory;
    }

    public function download()
    {
        $fileName = 'hogehoge.pdf';
        $fileData = file_get_contents(resource_path('static/' . $fileName), FILE_USE_INCLUDE_PATH);

        return $this->responseFactory->make(
            $fileData,
            200,
            [
                'Content-Type' => 'application/pdf',
                'Content-Disposition' => 'attachment; filename*=UTF-8\'\'' . rawurlencode($fileName)
            ]
        );
    }
}

```

以上です。
続・Git初心者がCommitの粒度とかを考えた話

#前回より
「よし、今日の作業も終わったんやな」
「[前回](https://qiita.com/okauend/items/972571a0e99d41d8c08b)のをもとに、commitして今日の作業終わりやな」

「せや、commitもそこそこできたしどんなになってるか一度確認してみよか」
![1632975df39895637219f92f3be7cb54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257615/ab8287e9-d812-8ef2-fa52-25238b900974.png)

「…」
「なんかADDばっかやな…」
「よく見ると自動テストもADDやし、参照変更もADDになってしまってるな」
「ADDがごっちゃ混ぜにしすぎてわかりにくくなってるんやな」
「どないしよか…」
#コメントでもらったアドバイス
「[前回](https://qiita.com/okauend/items/972571a0e99d41d8c08b)のコメントで色々アドバイスを頂いたなかで、AngularのCommitルールてのを教えてもらったんやな」
「自分で考えるのも大事やけど、偉大な先輩方の考え方をここで見てみるのもてやな」
##Angularのコミットメッセージガイドライン

[Developing AngularJS - Git Commit Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)

>- feat: A new feature
>- fix: A bug fix
>- docs: Documentation only changes
>- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
>- refactor: A code change that neither fixes a bug nor adds a feature
>- perf: A code change that improves performance
>- test: Adding missing or correcting existing tests
>- chore: Changes to the build process or auxiliary tools and libraries such as documentation generation

「当然のことながら英語なんやな」
「接頭詞でなんとなく意味はわかるけど、翻訳してみよか」
###翻訳してみる

- feat: 新機能の追加
- fix: 不具合の修正
- docs: ドキュメントのみの変更
- style: コードの処理に影響しない変更(スペースとか、書式設定とか、セミコロンの欠落とかの修正)
- refactor: バグ修正や機能の追加を行わないコードの変更
- perf: パフォーマンス改善を行うためのコードの変更
- test: テストの項目抜けや、既存のテストの修正を行う
- chore: ドキュメントの生成や、ビルドプロセス、ライブラリとツールをなどの変更

「こんなもんやろな」
「Google先生はほんと神様やで…」

##前回のを修正
「前回でワイが考えたのより思ったより**細分化**しとるな…」
「しかも、結構きっちりわけられとるし…」
「ワイが前回考えたのも色々不足してる点も見えたし、Angularのルールを元に改良してみよか」
「…参考にして組み込んでもええもんなんやろか…」

###バージョンアップする
「前回のワイが考えたのがこれやな」

- **NEW**
- **ADD**
- **REMOVE**
- **BUG_FIX**

「**問題点**としてはやはりワイの変更点が**ADD**だけなのは、1つにまとめすぎな気がしてきたんやな」
「現状やとパット見で、どこを修正したのかが結構解りにくいんやな」
「考えてたときは、これで十分やろ！と思ったけど、よくよく考えると**ドキュメント**や**テスト自動化**もあったんや…」
「多くなったら分かりづらいやろとか考えたけど、逆にコード以外でもCommitする場合あったもんな…」

「ということで、Angularのルールを参考にしつつ**ADD**を分割してみよか」
####ADDを分割しよう
「まずは、何が必要かの洗い出しやな」

- 新機能の追加
- 既存機能のアップデート
- リファクタリング
- 自動テスト
- コードの見た目の修正

「こんなもんやろ」
「次はこれらの接頭詞に変えてみよか」

- 新機能の追加 
- 既存機能の変更/更新

「これらはすでにある**NEW**と**ADD**で対応できそうやな」
「残りのは絶対にADDで対応できひんから、新しいのを考える必要があるな」

- リファクタリング
    - **REFACTOR**
- 自動テスト
    - **TEST**
- コードの見た目の修正
    - **STYLE**

「こんなもんでええやろか」
「ADDの内容を分けれたんやな」
「ただ、ドキュメント作成やライブラリとかツールの追加や更新をするとして、これやとまたADD一択になってしまうんやな」
「ドキュメントは単純に**DOCS**でええやろ」
「ライブラリとツールの追加や更新は頻繁にせんやろし、それだけで追加しても使用率が低そうなんやな」
「あと、ワイがまだ想定してない細かい事ありそうやしな」
「そういうのは単純に、**高度な柔軟性を維持しつつ臨機応変に**その他ということで**OTHER**でええやろ」

「ここまでのをまとめると、こうなったんやな」

- **NEW**
- **ADD**
- **REFACTOR**
- **TEST**
- **STYLE**
- **DOCS**
- **OTHER**
- **REMOVE**
- **BUG_FIX**

「一気に増えたんやな」
「でも、それぞれが何を示すか一気にわかりやすくなったから、これでしばらくやってみよか」

#おわりに
「前回はワイ記法で記事を書いてみると、たくさんのいいねとコメントを頂いてとてもありがたかったんやな」
「それで色々アドバイスをいただき、今回の記事でそれらを元にルールのアップデートを行ってみたんやな」
「今回は、Angularのルールをかなり参考にさせていただいたんやな」
「しばらくは、個人プロジェクトでこのルールで動かしてみて、結果をフィードバックしようかな」
swiftのREST処理におけるJSON/Equatable/Codableの整理

# tl;dr

JSONでREST通信する際に使うプロトコル（Equatable/Codable）の整理をする




## Equatable

equalsなどの同値比較をする際に、structなどの構造体の中身が同値かどうかを比較できるようにするプロトコル。

```swift

struct SomeStruct: Equatable {
    let key1: String
    let key2: String
}
```
上記のように書くことで、インスタンスの中身の比較ができる。




## Codable


JSON→struct間を自動で変換するためのプロトコル。
JSONと同じキー構成のstructにCodableを継承させれば下記のような形で変換できる。

```swift

let data = json.data(using: .utf8)

let struct = try? JSONDecoder().decode(SomeStruct.self, from: data)
```



# 使い所

JSONでやりとりするREST通信の際には、受け取ったJSONはCodableを使ってstructに変換して利用できる。
テスト観点でも返り値の比較をstruct同士の比較でできるので便利
ちょっとJavaScriptに慣れた人に教えたいオブジェクトの扱い方

JavaScriptに慣れてきたらオブジェクトをたくさん扱うかと思います。
以下のように簡単なオブジェクトを返す関数を作り、`console.log` で出力します。

```js
let test = function() {
  return {
    a: 'aaa',
    b: 'bbb',
    c: 'ccc'
  }
}

let x = test()

console.log(x) // { a: 'aaa', b: 'bbb', c: 'ccc' }
```

このコード自体は全然大したことありませんね。
次に`x`という変数に格納していた部分の記述を変えます。

```js
let test = function() {
  return {
    a: 'aaa',
    b: 'bbb',
    c: 'ccc'
  }
}

let {a, b} = test()

console.log(a) // aaa
console.log(b) // bbb
console.log(c) // これはエラー
```

こうすると`a`という変数にオブジェクトの`a`、`b`という変数にオブジェクトの`b`が入ります。
`c`は入れてないので出力させるとエラーになります。
このようにJavaScriptはオブジェクトの中身を変数に入れるすべを持っています。
以下のように書く必要ないんです。

```js
let x = test()
let a = x.a
let b = x.b
```

ちなみにオブジェクトの左のキーと、変数名は一致させる必要があるので以下のようにしてはいけません。

```js
let test = function() {
  return {
    a: 'aaa',
    b: 'bbb',
    c: 'ccc'
  }
}

let {aa, bb} = test()

console.log(aa) // undefined
console.log(bb) // undefined
```


また、この使い方は関数の引数でも応用できます。
以下のようなコードを実行すると`a2`を変数として関数内で扱い、`b2`は使われないことがわかります。

```js
test2 = function({a2, b2}) {
  console.log(a2) // aaa2
  console.log(b2) // undefined
}

test2({a2: 'aaa2'})
```

引数のオブジェクトに`b2`を定義してあげると関数内で`b2`も変数として扱うことができます。

```js
test2 = function({a2, b2}) {
  console.log(a2) // aaa2
  console.log(b2) // bbb2
}

test2({a2: 'aaa2', b2: 'bbb2'})
```

JavaScriptはこういう書き方ができるということを覚えておきましょう！
OpenPoseインストール(爆速)

# 環境
OS：ubuntu16.04
GPU：NVIDIA GeForce GTX 1080
[openpose](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md)
~~(ubuntu18.04だとインストールだるそう)~~

# 始める前に
CUDAもGPUドライバも以下の手順の中で導入されるので，事前に入れておかないほうが良く，あったら消しとくべき．
ディスプレイ映らなかったら，マザボの方に繋げて．

git clone しておいてディレクトリ中に入っておく
$ `git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose`

#実行コマンド

CMake GUI
$ `sudo apt-get install cmake-qt-gui`

CUDA
$ `sudo ./scripts/ubuntu/install_cuda.sh`

cuDNN
$ `sudo ./scripts/ubuntu/install_cudnn.sh`

Caffe
$ `sudo bash ./scripts/ubuntu/install_deps.sh`

OpenCV
$ `sudo apt-get install libopencv-dev`

Cmake GUI 起動
configureボタン => generateボタン
>Configureボタンを押して
No download info given for 'openpose_lib' and its source directory:
というエラーが発生した場合は以下のコマンド実行後、再度Configureする
$ `cd 3rdparty`
$ `git clone https://github.com/CMU-Perceptual-Computing-Lab/`

ビルド
$ ``` cd build/ ```
$ ``` make -j`nproc` ```
【Linux】タスクマネージャをリアルタイムに更新して確認する方法


備忘録として残します。


#■やり方

```shell
#オプション無の場合は3秒毎に更新
top
```
```shell
#一秒おきに更新
top -d 1
```
```shell
#特定のユーザのみ表示
top -u ユーザ名
```
Android SDK API Level 一覧

Android アプリ開発にあたっては API Level から OS バージョンを確認できると便利です。API Level 区分でバージョンをまとめました。

この表は私が Android エンジニアである限りは更新し続けます。表の内容に誤りがあれば [@irgaly](https://twitter.com/irgaly) へご連絡ください。

| Version | API Level | Name | Release |
| --- | --- | --- | --- |
| 16.0 | 36 | Baklava | 2025/6 |
| 15.0 | 35 | Vanilla Ice Cream | 2024/9 |
| 14.0 | 34 | Upside Down Cake | 2023/10 |
| 13.0 | 33 | Tiramisu | 2022/08 |
| 12L | 32 | S_V2 (Snow Cone) | 2022/03 |
| 12.0 | 31 | S (Snow Cone) | 2021/10 |
| 11.0 | 30 | R (Red Velvet Cake) | 2020/9 |
| 10.0 | 29 | Q (Quince Tart) | 2019/9 |
| 9.0 | 28 | P (Pie) | 2018/8 |
| 8.1 | 27 | O_MR1 (Oreo MR1) | 2017/12 |
| 8.0 | 26 | O (Oreo) | 2017/8 |
| 7.1 - 7.1.2 | 25 | N_MR1 (Nougat MR1) | 2016/10 - 2016/12 |
| 7.0 | 24 | N (Nougat) | 2016/8 |
| 6.0 - 6.0.1 | 23 | M (Marshmallow) | 2015/10 - 2015/12 |
| 5.1 - 5.1.1 | 22 | Lollipop MR1 | 2015/4 - 2015/5 |
| 5.0 - 5.0.2 | 21 | Lollipop | 2014/11 - 2014/12 |
| 4.4W - 4.4W.2 | 20 | KitKat Watch | 2014/9 - 2014/10 |
| 4.4 - 4.4.4 | 19 | KitKat | 2013/10 - 2014/6 |
| 4.3 - 4.3.1 | 18 | Jelly Bean MR2 | 2013/7 - 2013/10 |
| 4.2 - 4.2.2 | 17 | Jelly Bean MR1 | 2012/11 - 2013/2 |
| 4.1 - 4.1.2 | 16 | Jelly Bean | 2012/7 - 2012/10 |
| 4.0.3 - 4.0.4 | 15 | Ice Cream Sandwich MR1 | 2011/12 - 2012/3 |
| 4.0 - 4.0.2 | 14 | Ice Cream Sandwich | 2011/10 - 2011/11 |
| 3.2 - 3.2.6 | 13 | Honeycomb MR2 | 2011/6 - 2012/2 |
| 3.1 | 12 | Honeycomb MR1 | 2011/3 |
| 3.0 | 11 | Honeycomb | 2011/2 |
| 2.3.3 - 2.3.7 | 10 | Gingerbread MR1 | 2011/2 - 2011/9 |
| 2.3 - 2.3.2 | 9 | Gingerbread | 2010/12 - 2011/2 |
| 2.2 - 2.2.3 | 8 | Froyo | 2010/5 - 2011/11 |
| 2.1 | 7 | Eclair MR1 | 2010/1 |
| 2.0.1 | 6 | Eclair 0_1 | 2009/12 |
| 2.0 | 5 | Eclair | 2009/10 |
| 1.6 | 4 | Donut | 2009/9 |
| 1.5 | 3 | Cupcake | 2009/4 |
| 1.1 | 2 | Base 1_1 (Banana Bread) | 2009/2 |
| 1.0 | 1 | Base (Apple Pie) | 2008/9 |

# 公式ドキュメント

実は Android Developer では以下のドキュメントにこの記事のものと同じ表があります。`<uses-sdk>` のドキュメントに含まれているのでちょっと探しにくいですよね。

https://developer.android.com/guide/topics/manifest/uses-sdk-element#api-level-table
【CentOS7】MySQL over SSHの設定をする

DomoからDBにアクセスさせたかったのですが、直接アクセスさせるのは少し面倒だったので、SSH経由でアクセスさせるようにした際の設定諸々です。
DomoのMySQL SSH Connectorの設定内容は[こちら→MySQL SSH Connector](https://knowledge.domo.com/Connect/Connecting_to_Data_with_Connectors/Configuring_Each_Connector/Database_Connectors/MySQL_SSH_Connector)

# 環境
- CentOS 7.3
- MySQL 5.7
- sshdがインストールされていること

## 1. ユーザを作成する

アクセスさせるためのユーザを作成します。

```shell
$ useradd ユーザ名
```

## 2. 公開鍵を作成する
参考：[お前らのSSH Keysの作り方は間違っている](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)
### 既存のSSH Keyの確認
上書きしちゃったりすると危ないので一応確認。

```shell
$ ls -al ~/.ssh
```
デフォルトだと

- id_rsa.pub

なんかがよく作られてたりする
### SSH Keyの作成
- -Cはメアドだったりサーバ名だったりなんでも。
- デフォルトのkeyはすでにあったので、ここでは別名で保存
- パスフレーズはご自由に。

```shell
$ ssh-keygen -t rsa -b 4096 -C "xxxxxxxxxxxxxxxxxxx"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): xxxxxxx_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in xxxxxxx_rsa.
Your public key has been saved in xxxxxxx_rsa.pub.
The key fingerprint is:
54:f6:83:62:e6:23:65:dd:a9:99:3a:87:1d:76:14:30 xxxxxxxxxxxxxxxxxxx
The key's randomart image is:
+--[ RSA 4096]----+
|          E..    |
|         + = o   |
|        B o *    |
|       B . = .   |
|      . S * .    |
|       . * o     |
|        + o      |
|         o       |
|                 |
+-----------------+
```

### 公開鍵の設置
ログインするユーザのホームディレクトリの配下に公開鍵を置く
.sshフォルダがなければ作ってから。権限周りをしっかり設定しとかないとログインできないらしいので気をつけて！

```shell
$ cd /home/(ユーザ名)
$ mkdir .ssh
$ chmod 700 .ssh   # フォルダには700
$ cd .ssh/
$ cat /root/.ssh/xxxxxxx_rsa.pub >> authorized_keys   # rootかログインユーザの配下のsshフォルダに生成されているはずの公開鍵を書き出す
$ chmod 600 authorized_keys   # 鍵は600
```

### 公開鍵アクセスの許可

sshd_configの以下の項目のコメントを解除する。
PubkeyAuthenticationはデフォルトだと有効らしい。が、コメントアウトされていたので解除。

```shell
$ vi /etc/ssh/sshd_config
#PubkeyAuthentication yes
#AuthorizedKeysFile      .ssh/authorized_keys
```

## 3. MySQLにユーザを作る。
もうある方はここらへんは飛ばしてOK
ただし、2019/09/25時点でDomoはSHA256 Passwordには対応してないっぽい？のでパスワードはStandardで作ったほうが良さそう。

コマンド叩くのが面倒だったので、Workbenchで参照のみの権限のユーザを作成しました。(早速SSH経由で接続させた)
くわしくは[こちら](https://dev.mysql.com/doc/workbench/en/wb-mysql-connections-navigator-management-users-and-privileges.html)

![user作成1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38628/1c6abf12-fbd1-06c9-7782-d04bafc1df8b.png)
![user作成2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38628/2b760c46-78a4-d078-f093-6c13b22d4fa8.png)

## 4. Domoのコネクタに設定内容を記述する

たぶんこんな感じかと。
![domoの設定画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38628/ec67a06a-cedc-e466-d781-3f7f34df5f2f.png)

ちなみに、SSHの設定ができるとMySQL WorkbenchのStandard TCP/IP over SSHでも接続できるようになるので、いろいろ応用はききますね。
鍵の管理はしっかりしないといけないですが。

# 参考

[SSHの公開鍵認証設定をする](https://qiita.com/jinnai73/items/f1822f2e4d567847e215)
[SSHの鍵認証設定](https://qiita.com/gotohiro55/items/36a22516de2b381b3c6e)
[Salesforce] 選択リストのオブジェクトに値を追加したのに実際の画面で表示されない

悩んだので備忘録として。

私の場合はレコードの設定が出来ていませんでした。

## 手順

1. [オブジェクトマネージャー] > [対象オブジェクト] > [レコードタイプ欄] > [対象レコードタイプ]を開く。

2. [選択リスト] > [該当オブジェクトの"編集"]を開く

3. [選択リスト値]の編集
[選択可能な値]から[選択済の値]に移したら表示されるようになりました。

単純だけど気づかないと無駄な時間を過ごす事になるのでお気を付けて。
[事件簿] Parcelでtypescriptのpathsを使おうとしてハマった事件

# In my case

## 状況

1. React使ったWebアプリケーション作る。
2. ビルドはWebpackめんどくさいのでParcel使います。
3. TypeScriptによる開発です。

## フォルダ構成

```
├── index.html
├── src
│   ├── app
│   │   └── index.tsx
│   └── hoge.tsx
├── package.json
└── tsconfig.json
```

**わいの考え** 「tsのコードはsrcに全部入れて、エントリーポイントになるhtmlはsrcと同じ階層でええかな」

## ① index.htmlで`./src/app/index.tsx`を読み込む

```index.html
<script src="./src/app/index.tsx"></script>
```

## ② `./src/app/index.tsx`の中で１つ上にある`hoge.tsx`を読み込む

```index.tsx
import hoge from '../hoge'
```

パス地獄になりたくないからこうしたい ↓

```index.tsx
import hoge from '~/hoge'
```

# ③ `~/`が~`src`にマッピングされるようにtsconfig.jsonを設定する

```tsconfig.json
{
  ... 
  "baseUrl": "./",
  "paths": {"~/*":["src/*"]},
  ...
}
```

# ④ parcelでビルド

```terminal
parcel ./index.html
```

デデーン

> <font color="red">Cannot resolve dependency '~/hoge' at .....</font>

パス解決できないエラーになる。

# ⑤ tsconfig.jsonの設定を変えてみる

```tsconfig.json
{
  ... 
  "baseUrl": "./src/",
  "paths": {"~/*":["*"]},
  ...
}
```

## ⑥ ふたたびビルド

```terminal
parcel ./index.html
```

デデーン

> <font color="red">Cannot resolve dependency '~/hoge' at .....</font>

パス解決できないエラーになる。

### ちなみに

`tsconfig.json`の`rootDir`に関しては

- 指定なし
- `./`を指定
- `./src`を指定

どのパターンだろうとダメ

## ⑦ 困る

parcelだとtsのpathsが使えない説？
調べてみると数年前はそういう問題があったようだ(githubのissuesに上がってた)
けど今はできるっぽい。

トライ&エラーの繰り返し

# 解決した方法

`index.html`を`src`の中に移動したら解決した。

```diff
- ├── index.html
  ├── src
+ │   ├── index.html
  │   ├── app
  │   │   └── index.tsx
  │   └── hoge.tsx
  ├── package.json
  └── tsconfig.json
```

```diff:index.htmlの変更点
- <script src="./src/app/index.tsx"></script>
+ <script src="./app/index.tsx"></script>
```

```diff:ビルドコマンドの変更点
- parcel ./index.html
+ parcel ./src/index.html
```

`tsconfig.json`の設定は

こっちでも:

```
{
  ... 
  "baseUrl": "./",
  "paths": {"~/*":["src/*"]},
  ...
}
```

こっちでも:

```
{
  ... 
  "baseUrl": "./src/",
  "paths": {"~/*":["*"]},
  ...
}
```

どっちでもいけた。

# エピローグ

とりあえずpathsは使えたし、これでひとまず困ることはない。

とは思うものの

html含めて全部同一フォルダに入れないといけない
それがparcelの仕様なのか

はたまた
複合的な理由でこうなってしまったのか

それは定かではない。