OmniAICreator/Qiita-1.07M huggingface dataset:
Oculus Go 開発備忘録

<h2>【準備】</h2>
**・UnityHubインストール( https://unity3d.com/jp/get-unity/download)**
　・Unity 2019.1.2f1インストール（Oculus Utilityサポートが2017.4LTS 2018.4LTS 2019.1.2f1）
　　・Androidとタブを開いてSDKとNDKも
　※最新の場合Unityインストール時にAndroid SDKなどもインストールされるため以下が不要な場合もあるがインストールできない場合は以下の手順も実施

**・Android Studioインストール（ https://developer.android.com/studio/）**
  ・Configure→SDK ManagerでSDK PlatformsでAPI 21以上のやつとSDK ToolsでNDK
　※ユーザー名にスペースor日本語の場合はエラー出るのでその場合はC:/Androidを作成しそこに入れる
　※Oculus互換verやPATHについて
　　（ https://developer.oculus.com/documentation/mobilesdk/latest/concepts/mobile-studio-setup-android/）
・JDKインストール（UnityではJDK1.8.0_152）↓ここからjdk-8u152のJava SE開発キット
 　 https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html
**・OculusGoを開発者モードにしてUSBで接続**
**・コマンドプロントでadb devicesでAndroid認識**

**公式OculusGo開発ドキュメント**
https://developer.oculus.com/documentation/unity/latest/concepts/unity-mobileprep/

<h2>【設定】</h2>
・新規プロジェクトで３D
・Edit➞PreferencesでAndroid SDKとJDKを設定
・Bulid SettingでAndroid（TextureをASTCにして）にSwitch Platform
・Player Setting
　・組織名とアプリ名の変更とそれにあわせてotherのほうのやつも.com.組織名.アプリ名に変更
　・xR Settingでsupport Oculus
　・otherのグラフィックでVulkan的なのは削除
・Build And Runで確認

<h2>【アセット】</h2>
・Oculus Utility
　 https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022




※過去知人に教えるために作成したメモをそのまま載せているため情報の古い部分があります。
GASでspreadsheetに画像つきリストを作る

#Python から Google spreadsheet に画像を挿入

##やりたいこと（完成物）
時空間データ解析をしている中で，解析結果を可視化するにあたって以下のような地図画像等からなるリストを作りました．（図は一部コピーライトの関係で隠しています）
<img width="700" alt="sample_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323237/cb7d0169-4b50-9a97-674e-e5c65f192ee8.png">
画像数が多く1つずつポチポチするのは嫌なのでスクリプトで画像の挿入を行ないました．
やりかたと詰まったところをまとめておきます．
##基本的な画像の挿入方法
google spreadsheet では，方法は以下の2通りの方法で画像を挿入できる．
1．IMAGE関数で画像のリンクを参照．
2．「挿入」→「画像」→「セル内の画像」から直接画像を埋め込む．
このあたりについては，下のサイトなどを参照してください．
https://officeforest.org/wp/2019/04/16/google-apps-script
https://tom2rd.sakura.ne.jp/wp/2019/05/16/post-9098/

　GASで自動化するにあたり，2020/2/1現在，2の方法では「セル中に挿入」することができず不便なので，今回は1の方法を使っています．
1の方法はセル内の関数で別途google drive上にアップロードした画像をリンクから参照する方法で，うまく画像が出力されないことがあるので，GASからのセル内挿入が可能になったらそちらの方が良いかもしれません．Googleさんに期待です．
　まず準備として，google drive上のフォルダに{n}.png (n=1~500)とした画像をアップロードしておきます．これらをIMAGE関数で参照するという流れです．IMAGE関数を挿入するために書いたスクリプトを載せておきます．

```js

function insert_fig() {
  var folder_id = 'hogehoge';  //folder id
  folder = DriveApp.getFolderById(folder_id);
  files = folder.getFiles();
  list = [];　//この変数のファイル名・URLが入っていきます
  rowIndex = 2; // The starting row of a range.
  colIndex = 4; // The starting row of a column.
  var ss;
  var sheet;
  var range;
  sheetName = 'sheet_name'; //デフォルトのシート名がシート１です。
  
  while(files.hasNext()) {
    var buff = files.next();
    list.push([buff.getName(), buff.getUrl()]);
  };

  //今回，ランキングのリストを作っているので，ファイル名でソート
  list_sorted = list.sort(function(a,b){return(a[0].replace(/[^0-9]/g, '') - b[0].replace(/[^0-9]/g, ''));});

  //IMAGE関数で指定するリンクの形に整形
  var file_urls = list_sorted.map(function(value) {
    var pattern = /[\/]/;
    return ['=IMAGE("http://drive.google.com/uc?export=view&id='+ value[1].split(pattern)[7]+'")'];
  });

  ss = SpreadsheetApp.getActive();
  sheet = ss.getSheetByName(sheetName);
  range = sheet.getRange(rowIndex, colIndex, file_urls.length, file_urls[0].length);
  
  // 対象の範囲にまとめて書き出し
  range.setValues(file_urls);
}
```

これで画像つきリストが出来上がるはずなのですが，うまく画像が出力されない問題が発生しました．
### 画像が出力されないときの対処法
1. 参照しているリンクをそのままブラウザ等で叩いてみる．画像が表示されればリンク貼り方に問題はない．
2. 自分の場合はリンクについては問題ないが，画像が表示されなかった．色々調べた結果，spread sheet の画像には[画像サイズに制限](https://gist.github.com/tanaikech/9414d22de2ff30216269ca7be4bce462)　があるらしい．
これをもとに，pngquantやsipsなどで画像サイズを小さくしたところ症状は改善した．

ただし，画像が多すぎたり一つ一つが大きい場合，半日程度待たないと表示されないことがあるので画像は極力小さくしましょう．
自分の場合，地図画像がfoliumからhtml作成→seleniumでスクリーンショットという手順で作ったもので，画像サイズが大き過ぎた模様です．~~画像取得の際にベクター画像で保存するなどの工夫も有効だと思われます．~~ 挿入できるファイルはpng,jpg,gifのみのようです．（2/13修正）
Dartで使いそうなListの統計処理集

# 1.合計
```dart
void main() {
  final list = [1, 2, 3, 4, 5];
  final sum = list.reduce((a, b) => a + b);
  print(sum); // 15
}
```

# 2.最大値、最小値
```dart
import 'dart:math';

void main() {
  print([1,2,8,6].reduce(max)); // 8
  print([1,2,8,6].reduce(min)); // 1
}
```

# 3.平均
```dart
void main() {
  final list = [1, 2, 3, 4, 5];
  final mean = list.reduce((a, b) => a + b) / list.length;
  print(mean) // 3;
}
```

# 4.中央値
```dart
void main() {
  list.sort();
  final list = [1, 2, 3, 4, 5];
  final length = list.length;
  int median;

  if (length % 2 == 1) {
    median = list[(length/2 + 0.5).toInt()];
  } else {
    median = ((list[length~/2] + list[length~/2 + 1]) ~/ 2);
  }

  print(median) // 3;
}
```

# 5.標準偏差
```dart
import 'dart:math';

void main() {
  final list = [1, 2, 3, 4, 5];
  final mean = list.reduce((a, b) => a + b) / list.length;
  final standardDeviation = sqrt(
    final squaredDifference = list.map((current) {
      var difference = current - mean;
      return pow(difference, 2);
    }).reduce((previous, current) =>
      previous + current
    ) / list.length;
  );

  print(standardDeviation); // 1.58113883008
}
```
Python+機械学習でリアルタイム音源分離モック作ってみた

今回は音を対象とした非負値行列因子分解（NMF: Non-negative Matrix Factorization)の実利用をやっていきます。
誰でも手軽に音源分離デモができるようなモックを作成することを目標とします。

# 作ってみた結果
先に結果を...
簡単なグラフ描画プログラムを書いて描画してみました！
![代替テキスト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130155/4cdc9a8e-52ae-e313-3a75-5ebdd53dd015.png)

[動画](https://youtu.be/L_uVB2sU16M)にしてデモを公開しております。


# NMFとは？
以前書いた[記事](https://qiita.com/sumita_v09/items/d22850f41257d07c45ea)を見ていただければ良いかと思います。

#音をNMFでどう処理するの？
NMFの基本形は

```math

V \approx WH
```
といった式で表すことができます。
音源分離をするにあたって、スペクトログラム行列Vにスパース性を仮定し、辞書行列Wと励起行列Hの積になるように分解します。辞書行列はVに含まれる音色のパワースペクトルを表現し、励起行列はWで表現している音色が時間軸に対してどれだけ含まれているかを表現します。
教師なしでも音源分離は可能ですが、今回は入力音に対して任意の音色を分離したいため、教師ありNMFを採用します。具体的には、辞書行列に任意の音色パワースペクトルを登録しておき、更新時は励起行列のみを更新するようにしました。
加えて、リアルタイムで音源分離を行うため、入力Vをスペクトログラム行列（周波数 x 時間）ではなく最新フレームのみのパワースペクトル行列（周波数 x 1）をVとします。

# どんなものを作るか？
音源分離モックは以下の要件で作成しました。
- CUI上で動作
- リアルタイムで音源分離が可能
- 実行中に検出したい音源が変更・追加可能
- 音源分離結果をOSCで送信

実装自体は、上記リンク記事に記載しておいたNMF実装を音用に改造し、CUI上で動作できるようにしております。


# ソースコード
今回実装は記事に載せておりませんが、Githubで公開しております。
詳しい環境設定やCUIの操作に関してはREADMEに記載しておりますので、ご参考になれば幸いです。
https://github.com/T-Sumida/RealTimeSoundSeprator

# まとめ
リアルタイムで動作する音源分離モックを作成しました。
深層学習のようにめちゃくちゃ性能が良いわけではありませんが、学習プロセスなしで分離対象の音を追加できるのはメリットではないかと思ってます。
NMFも楽しいですが、仕事でやっているような機械学習系の話も今後書いていこうかと考えてます。
TensorflowのモデルをLiteへ変換する方法

#TensorflowLiteについて
スマートフォンや、埋め込みデバイス用の機械学習ツールセットです！
Tensorflowよりも軽量です。

#変換方法について
PCに、PythonとTensorflow(pip)がインストールされていることを前提とします。
まず、変換するモデルを用意します。

##python上で変換
####サンプル

```python
import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_saved_model("test_model.pb")
tflite_model = converter.convert()
open("test_model.tflite", "wb").write(tflite_model)
```

####使い方

```python
import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_saved_model("モデルへの相対パス")
tflite_model = converter.convert()
open("モデルの保存先", "wb").write(tflite_model)
```


###コマンドライン上で変換

コマンドライン上で変換する方法もあります。
####サンプル

```shell
tflite_convert \
  --saved_model_dir=test_model.pb \
  --output_file=test_model.tflite
```
####使い方

```shell
tflite_convert \
  --saved_model_dir=モデルへの相対パス \
  --output_file=モデルの保存先
```

#最後に

TensorflowLiteをAndroidに組み込む方法を解説していますので、良ければぜひ。
記事は[こちら](https://qiita.com/Teraterayuki/items/b35072b06f15a57d2420)

また、公式の情報も参考にしてください。
[公式記事](https://www.tensorflow.org/lite/convert)
2019年新卒から2020年新卒へ、IT企業の新人研修でこれが重要！

#次の新卒のより良いスタートダッシュの為に

さて、この記事は**2020年の新卒の方**に向けて、2019年新卒の失敗や経験の一例を知ってもらって、
より良い**スタートダッシュを4月**にきってもらえると嬉しいな、という気持ちで書きました。
私が入社した会社は社員100人弱のベンチャーですので、同じくITベンチャーに務めることが決まっている方ですと、よりお役に立てると思います。

##私は2019年の新卒です
まず、少し自己紹介させて下さい。
私は**2019年の4月に新卒としてITベンチャー**に入社して、
現在その会社で主にスマホアプリの**フロント開発**に従事しております。
他にも大学が電子工学科だったことも手伝って、Raspberry Piを使ったIoTっぽいことも会社でしてます。
会社での使用言語は主に、Swift、Kotlin、Java、Javascript、GAS、Pythonです。

#一番最初のチャンス？新人研修は終わってからが大事！
さて、入社したみなさんを必ず待ち受けている最初の関門は研修だと思います。
新人研修の内容はもちろん会社によって様々だと思いますが、私の会社では外部研修でした。
新宿にある某有名ITスクールに通ってバックエンド、フロントエンド、ディレクション、ビジネスマナーまで、**広く浅く学ぶ**ものでした。
正直言ってどこの会社でもこれの内容はそんなに変わらないと思います。

ある程度プログラムをやったことがある人なら**「参考書買って、実際チュートリアル作った方がまし」**って思う人もいると思います。僕の同期も受講中にはこの意見がとても多かったです。
ですが、**研修は終わってからが重要なのです！**

会社は必ず研修が新卒にとって有益なものだったのか**意見を聞いて、その意見を参考に次年度の研修内容を練り直します。**
研修が終わった後、先輩社員の方に「研修の内容はどうだった？どこが良かった&悪かった？何か付け足して貰いたものは？」など**参考意見を求められます。**
ここで、「研修は授業みたいでした、大体ネットで調べたら書いてありました。」とか新卒が言ったらどうでしょう。
先輩はこう思います。「え？いつでも質問できる環境があったのに、基礎が出来た上で応用に挑戦しなかったのか、**この子は自発的に動くタイプじゃないのかな**」と…。
これが結構マイナスイメージなのはITベンチャーに就職しようと思った方なら分かってもらえると思います。
ITベンチャーの就職面接でお馴染みの「自発的&能動的な行動」にマイナス点を付けられてしまうのです。
**こうならない為に！**
新鮮な実体験を持った私が新人研修を1年目のスムーズな業務に繋げる**重要な点を3つ**上げます！

###1.研修の悪い点をメモっておく
もちろん受講の良くないところを無理やり良かったと言う必要はありません。
**悪いものは悪いと言いましょう！**
ですが、**どこが**良くなかったのか、出来れば**どうすれば良くなるか**までを研修終わりに言えるようになっておきましょう。

###2.研修で興味を持った分野で+α
大手の会社さんなどは別ですがITベンチャーでは、みなさんがどの役職につくかは結構**印象勝負**なところがあります。
先輩社員に「この新卒には**この分野の仕事に振ろう**」と思ってもらえるように**興味をもった分野をしっかりアピール**しましょう！
例で言うと、研修でRubyを習って、興味が湧いたので、HerokuにWebアプリをデプロイしてみました。
などを先輩に伝えるなどです。

###3.同期と仲良く！
これも**かなり重要**です！
一緒に研修を受ける会社の**同期と仲良く**しておきましょう。
会社に入ると、学生の時は必要なかった**業務以外の仕事**があります。
税金の申請、勤怠、社内の健康診断などの書類提出、物品購入の申請…
他にも上げ出したらきりがありません。
これらを全部間違いなく最初からこなすのは、**はっきり言って無理**です。
失敗して当然、**先輩に教えてもらって当然**です。
ですが、新卒に何度も同じ質問をされると先輩はどう思うでしょう…。
そのうち、「新卒の〜君に共有したから彼から聞いて」というように**同期間の情報共有**を求められます。
この時です！
同期に話せる相手がいなかったらどうなってしまうでしょう…。
考えただけでも恐ろしいですね。
出来るだけ研修中に同期たちと仲良くなって**気軽に質問や情報共有ができる関係**になっておきましょう。

##終わりに
新卒の皆様、就職おめでとうございます！
新卒って期待と不安とでいっぱいですよね。
皆さんも面接などで言われたことかもしれませんが、就職が決まってから入社するまでの時間は思いっきり遊んでやりたいことやって下さい！
この時期にこんな記事を読んでるあなたはもしかしたら肩に力が入り過ぎかもしれませんね笑
一意見でしかないので気休めですが、私は今の会社に入って実は学生の時よりのびのび生活してる実感があります。
もちろん時間の制約は増えましたし、考えることも増えました。
ですが、より多くの学んでいる実感、役に立つプログラムを書いている実感があります。
2020年の新卒でIT企業に就職した方が一人でも多く、より良い１年目を過ごせることを切に願っております。
Oracle Cloud Infrastructureの監査ログをOracle Management Cloudで分析する

Oracle Cloud Infrastructureのコンソール操作やAPIアクセスは、監査ログとしてデフォルト90日間保存されています。(最大365日まで指定可能)
監査ログ自体はJSON形式で、OCI内に以下のような検索機能も用意されています。

- Oracle Cloud Infrastructure 監査イベント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/be07f745-7053-b6ef-9f4b-6ecabb1acedd.png)

ここでは、このJSON形式の監査ログを取り出し、Oracle Management Cloudにインポートして、パワフルな分析・レポート機能を活用できるようにするための手順を紹介します。

- 例えば、こんなOCI監査ログのダッシュボードを作成することができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/ea1e8a3b-d318-2432-85b6-b84149020360.png)

## OCIから監査ログを取り出す

- 以下のブログを参考に、OCI CLIコマンドが実行できる環境を準備する
    - https://community.oracle.com/docs/DOC-1019624
    
```
#oci audit コマンド 
oci audit event list --all --start-time 開始日時 --start-time 終了日時 --compartment-id コンパートメントID 

#実行例
oci audit event list --all --start-time=2019-12-01T00:00:00.000+09:00 --end-time=2019-12-02T00:00:00.000+09:00 --compartment-id ocid1.compartment.oc1..aaaaaaaa6it5wsxbeoyxpbxmq5aupsag7jo4mxsot7hhuxvjp5uqnvuxgf4a > ociaudit.json
```
## OMCにOCI監査ログをアップロード

OCIのカスタム・パーサーをダウンロードする
https://github.com/western24/omc4oci/raw/master/content_oci4audit.zip

- OMCへカスタム・パーサーをアップロードする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/af46e705-9355-a61e-c35c-9470bb26911f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/52378a92-4c34-6860-1bc0-10eeb2a6dc30.png)

- OMCに監査ログをアップロードする
ociaudit.jsonファイルを以下のリンクを参考に手動でアップロードする
https://qiita.com/western24/items/1d00475d0f0b8c2bb0f9
※ログソースの関連付けでは、OCI Auditを選択する (OCI Audit Logsではない)

## OMCによる分析例

- OCI上での変更に関連した操作イベントのグラフ -> Event NameをY軸、Request ActionをPost,Deleteで指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/0b05a56a-453f-0d8c-e0ba-3254fd64a9b0.png)

- principal-id(フェデレーテッドユーザー)で絞り込み、特定のユーザーの操作の円グラフ (※ローカルユーザーはuser-nameフィールド)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/279dd853-d2d8-62d3-923f-c0fbe82ad13f.png)


- 表形式でVMインスタンスの起動・停止イベント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/cd37549b-98ea-ec76-8f1f-2e1b306eaf9d.png)

OCI Auditで対象期間が長期間の場合、かなり時間がかかる場合があります。その場合は、Service Request経由でまとめて取得したほうが良いかもしれません。

毎回、OMCコンソールからアップロードするのは面倒なので、OCIのログ出力からOMCへのアップロードまでの自動化スクリプトを作成してみました。
https://github.com/western24/omc4oci

Oracle Management Cloud関連の情報は[こちら](https://qiita.com/western24/items/1e44bfcaa77f3251a263)
GitLab PagesでTOP画面以外もURL直打ちで画面遷移できるようにする

GitLab PagesにAngularプロジェクトをデプロイする場合、単純にpublicにビルドファイルをコピーするだけだと、URL直打ちした場合やF5でリロードした際にTOP画面以外は404エラーになります。

それを解決する方法をメモしておきます。

# 解決策

index.htmlをコピーして404.htmlを作成します。
こうすることで、TOP画面以外の場合に404.htmlにアクセスされます。
中身はindex.htmlのため、正常にルーティングされるというわけですね。

```.gitlab-ci.yml
image: node:latest

pages:
  stage: deploy
  script:
  - npm install -g @angular/cli@latest
  - npm install
  - ng build --prod --aot
  - mkdir public
  - mv dist/project/* public/
  # index.htmlをコピーして404.htmlを生成する
  - cp public/index.html public/404.html
  artifacts:
    paths:
    - public
  only:
  - master
```

# GitLab Issue

ここに書いてありました。
https://gitlab.com/gitlab-org/gitlab-pages/issues/23#note_57499396
rubyzipで複数ディレクトリを圧縮する

rubyzip公式に、再帰的にディレクトリを保存するサンプル(<https://github.com/rubyzip/rubyzip>)がありました。

ですが、これだと単一ディレクトリしか圧縮できなかったので、複数ディレクトリを保存できるように(ゴリ押しで)改造しました。


## ソースコード

```
require 'zip'

# Usage:
#   directories_to_zip = ["/tmp/input", "/bar/input"]
#   output_file = "/tmp/out.zip"
#   zf = ZipFileGenerator.new(directories_to_zip, output_file)
#   zf.write()
class ZipFileGenerator
  # Initialize with the directory to zip and the location of the output archive.
  def initialize(input_dirs, output_file)
    @input_dirs = input_dirs
    @output_file = output_file
  end

  def write
    @input_dirs.each do |i|
      @input_dir = i
      entries = Dir.entries(@input_dir) - %w[. ..]
      ::Zip::File.open(@output_file, ::Zip::File::CREATE) do |zipfile|
        write_entries entries, @input_dir, zipfile
      end
    end
  end

  private

  def write_entries(entries, path, zipfile)
    entries.each do |e|
      zipfile_path = File.join(path, e)
      disk_file_path = zipfile_path

      if File.readable? disk_file_path
        if File.directory? disk_file_path
          recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
        else
          put_into_archive(disk_file_path, zipfile, zipfile_path)
        end
      end
    end
  end

  def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
    zipfile.mkdir zipfile_path
    subdir = Dir.entries(disk_file_path) - %w[. ..]
    write_entries subdir, zipfile_path, zipfile
  end

  def put_into_archive(disk_file_path, zipfile, zipfile_path)
    zipfile.add(zipfile_path, disk_file_path)
  end
end

```


## 使い方

第一引数に複数ディレクトリのそれぞれのパスを表す配列と、第二引数にzipの書き込み先を指定すればOKです。

```
gen = ZipFileGenerator.new(["target1", "target2"], "output.zip")
gen.write
```

もっとよい書き方があればコメントください！
Azure Content Moderator (1.image)を試してみる。

## Azure Content Moderator APIの概要
Azure Content Moderator API は、ユーザが入力したテキスト、画像、ビデオに不適切な内容、が含まれているかどうかを確認できるサービスです。一言で言うと検閲と言ったところでしょうか、ユーザに好き勝手に投稿させないように事前にコグニティブサービスによるチェックを入れて登録したい時等に利用できます。Content Moderatorはtextとimage、videoに分けられます。具体的には以下のようになります。

#### Image
- Evaluate（racy or adultなコンテントを含む画像を返します。racyは卑猥と言う意味です。）
- Find Faces （画像を入力すると顔の位置をjson形式で返してくれます）
- Match （事前に登録しておいた画像とマッチする画像を選びタグ（「アダルト」、「武器」、「子供」等）を返却します）
- OCR（指定された言語での言葉が画像に見つかればそれを返します。デフォルト言語は英語です。）

#### text
- Detect Language(指定された文字列の言語を判定します)
- Screen(短文の解析。公式サイトには「下品な言葉を探索する」とあります)

ちなみに送信方法はすべてPOSTです。

上記のうち、今回はimageを試してみたいと思います。
まずは公式サイトの[Content Moderator レビュー ツール](https://contentmoderator.cognitive.microsoft.com/dashboard)で試してみます。

![クリップボード一時ファイル01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/65a47ff9-4dc0-fe5e-ca74-0b373dec5745.jpeg)

なんとかサインインすると以下のサイトに遷移するので適宜入力してcreate teamします![Art017.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/a254d6d3-680f-88ee-7b11-af1fbdfde813.jpeg)

うまくいくと以下のページが表示されます。Try ⇒ imageを選択します
![Art018.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/40bca1d6-6b81-0517-244d-6ed787d90a81.jpeg)

sample imageをクリックしてサンプル画像を頂きました。
sample4を拝借。卑猥すぎます。

![Art019.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/7daa81b3-9948-3851-dd4a-4e4ec075f49c.jpeg)

その後、Choose file(s)を押して先ほどの画像を選択してsubmitします。
![Art020.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/a06cb189-f2ad-3ff8-83e9-7a27675db7da.jpeg)

成功です。click hereを押して次に進みます
![Art021.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/4231e2ac-2118-679e-224c-672298c869ad.jpeg)

結果発表
卑猥でもエロくもないと判定されました。
![Art022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/029a3c81-74ff-bb93-b5e8-694d7a68a065.jpeg)

エロい！と言われたいので別の画像を。
![Art023.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/6676538e-a5dc-43b1-523b-c5bf38c88f05.jpeg)

「アダルトでないがエロい」と判定されました！
![Art024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151893/7870b00c-a8ef-1136-026a-6e4bc5f0b6b9.jpeg)
Angularヒーローチュートリアル1

## はじめに
公式サイトのチュートリアルを整理がてらまとめています。

# 構造の基礎

## Angular CLIをインストール
```terminal:ターミナル
$ npm install -g @angular/cli
```
これで`ng`コマンドを使用できます。
## 初期アプリケーションを作成
```terminal:ターミナル
$ ng new angular-tour-of-heroes
```
このコマンドで作成されるのは

- `angular-tour-of-heroes`というアプリケーションのディレクトリ

そのディレクトリ下に

- 初期スケルトンアプリケーションプロジェクト(src)
- エンドツーエンドのテストプロジェクト(e2e)
- その他の設定ファイル

主に記述していくのは`src`ディレクトリの中のファイルです。

このコマンドを打った時点では、初期のwelcomeページが出力されます。

```terminal:ターミナル
$ cd angular-tour-of-heroes
$ ng serve --open
```
<img width="1440" alt="スクリーンショット 2020-02-02 17.11.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519379/76b013a1-f946-733c-59b3-3b112e1ac3d2.png">
こんなん出てきましたね。

## 基本の構造
`src/app`を見てみると6個くらいファイルがありますが、この中で3つ

- `app.component.ts`
- `app.component.html`
- `app.component.css`

が重要です。これらによってサイトの見かけが出来上がります。

## 動作の確認
まず、`app.component.ts`の`title変数`と`app.component.html`を以下のように変更します。元々あったHTMLは全部消しちゃいます。

```typescript:app.component.ts
  title = 'Tour of Heros';
```

```python:app.component.html
<h1>{{title}}</h1>
```

そしてlocalhostを見てみると、、、
<img width="1440" alt="スクリーンショット 2020-02-02 17.35.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519379/edd253d3-9c04-60ea-cb40-fb30fa5a0544.png">

こんなん出てきました。
つまり、ts(typescript)ファイルでtitle変数に代入された値がHTMLファイルで使用できるということです。

## 共通のスタイルを整える
`src/style.css`というファイルがあり、ここでアプリケーション全体のスタイルを決めます。

```css:style.css
/* Application-wide Styles */
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body {
  margin: 2em;
}
body, input[type="text"], button {
  color: #333;
  font-family: Cambria, Georgia;
}
/* everywhere else */
* {
  font-family: Arial, Helvetica, sans-serif;
}
```
localhostは
<img width="1440" alt="スクリーンショット 2020-02-02 17.48.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519379/94563623-6573-c20c-a567-32ff97e9b576.png">
こんな感じになりました。
Vue + Vuex + TypeScriptでWeb Workerを試してみる

# はじめに

色々なところで**「Web Worker」**という単語は見聞きするのですが、いまだに使ったことがなかったので試してみました。

今回勉強がてら**Vue CLI 4**で作成したアプリケーションにVuexとTypeScriptも導入したので、

* vue-property-decorator
* vuex-module-decorators

を利用しています。

また、素で使ってみたかったので**「Web Worker」**に関するライブラリは使いません。

# 設定

```
npm i worker-loader -D
```

```JavaScript:vue.config.js
module.exports = {
  publicPath: process.env.VUE_APP_PUBLIC_PATH,
  transpileDependencies: ['vuetify'],
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.worker\.ts$/,
          use: {
            loader: 'worker-loader',
          },
        },
        {
          test: /\.worker\.ts$/,
          use: ['ts-loader'],
          exclude: /node_modules/,
        },
      ],
    },
  },
}
```

* worker-loaderを追加
* 今回はインラインにしませんが、検索するとインラインでやっている方が多かったのはなぜなのかわかっていません


あと、自分の環境だけなのか「worker-loader」の書き方が悪いと、↓のエラーが出て動きません
解決に半日かかりました……

> Uncaught SyntaxError: Unexpected token '<'


# VuexのActionとMutation

```TypeScript:store/datatable.Ts
import {
  Module,
  VuexModule,
  Action,
  Mutation,
  getModule,
} from 'vuex-module-decorators'
import store from '@/store'

const SampleWorker = require('@/worker/sample.worker')

@Module({
  dynamic: true,
  store,
  name: 'DataTableModule',
  namespaced: true,
})
class DataTableModule extends VuexModule {
  private datalist: any[] = []

  public get GET_DATA_LIST() {
    return this.datalist
  }

  @Mutation
  private SET_DATA_LIST(payload: any[]) {
    this.datalist = payload
  }

  @Action
  public async fetch() {
    const w: Worker = new SampleWorker()
    const params = {}

    // web worker側でAPI Callさせる(今回はパラメータはなし)
    w.postMessage({ params })

    // Getした値を受け取る
    w.addEventListener('message', e => {
      this.SET_DATA_LIST(e.data.message)
      w.terminate()
    })
  }
}

export default getModule(DataTableModule)
```

* ```require('@/worker/sample.worker')```ではなく、importにするとエラーとなる

> Cannot use 'new' with an expression whose type lacks a call or construct signature.

# Web Worker
```TypeScript:sample.worker.ts
import axios from '@/plugins/axios'

const w: Worker = self as any

w.addEventListener('message', async e => {
  const res = await axios.get('/comments')

  // web worker側でデータを加工してメインスレッドに返すほうがぽい気がしたので
  const message = res.data.length ? res.data.slice() : []
  
  w.postMessage({ message })
})

export default w
```

# まとめ

worker-loaderの使い方がよくわからずまあまあハマりました。

Web Worker自体は難しいことはなく、実務でも使えそうなのでどこかのタイミングで導入してみたいです。
riot apiでアカウント情報を取得してみた

#はじめに
調べてみると今まで触ってきたサービスの中にapiがあるものが多かったので、
今回はLeague of Legendsのapi、riot apiを触ってみました。

#riot apiのapiキーの取得方法
####1,Riot Developer Portalにサインイン
>https://developer.riotgames.com/

####2,DEVELOPMENT API KEYを取得
**DEVELOPMENT API KEYは24時間で使えなくなるので使いたいときは更新しましょう**

#コード

```riot_api_test.php
<?php
    //apiキー
    $API_KEY = "入手したAPIキー";
    if(isset($_POST["name"])){
        //サモナーネーム取得
        $name = rawurlencode($_POST['name']);
        //リージョン取得
        $region = $_POST['region'];
        //url
        $url = "https://${region}.api.riotgames.com/lol/summoner/v4/summoners/by-name/${name}?api_key=${API_KEY}";
        //サモナー情報取得
        $array = json_decode(file_get_contents($url),true);
    }
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>サモナーネーム検索</title>
    </head>
    <body>
        <form action="" method="POST">
            <p>サモナーネームを入力してください</p>
            <input type="text" name="name" placeholder="例:RuRey 0w0">
            <select name="region">
                <option value=""></option>
                <option value="na1">NA</option>
                <option value="kr">KR</option>
                <option value="jp1">JP</option>
            </select>
            <input type="submit" value="送信">
        </form>
        <div>
            <?php
                //出力
                foreach($array as $key => $value){
                    //名前とサモナーレベル出力
                    if($key == "name" || $key == "summonerLevel"){
                        echo $key;
                        echo ":";
                        echo $value;
                        echo "<br>";
                    }
                    //ddragonからアイコンの画像を取得
                    if($key == "profileIconId"){
                        print '<image src="http://ddragon.leagueoflegends.com/cdn/9.9.1/img/profileicon/'.$value.'.png" width=100px; heigth=100px;></image>';
                        echo "<br>";
                    }
                }
            ?>
        </div>
    </body>
</html>
```

#結果
![riot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576886/c4b88357-72f4-c34c-7e7b-f16a1165b997.png)
↓
![riotapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576886/805ed00b-a537-7062-c167-9d630906fdef.png)

#参考にしたサイト
>https://qiita.com/caim/items/e5449f4728325ccdc93a
https://developer.riotgames.com/apis

今までやってきたネットゲームのapiをどんどん触ってみようと思う
SQLコマンド メモ


### sqlplus システム変数
```
set linesize 200
set pagesize 300
```

フォーマット初期化

```
CLEAR COLUMN
```

---
### 接続ユーザ確認

```
select username from user_users;
```

### 接続インスタンス確認

```
select instance_name from v$instance;
```

### テーブルのカラム確認
```
desc <テーブル名>
```

### 表領域
```
col TABLESPACE_NAME for a30
col STATUS for a9
col CONTENTS for a9

SELECT TABLESPACE_NAME, STATUS, CONTENTS FROM DBA_TABLESPACES;
```

### データファイル
```
col FILE_NAME for a50
col TABLESPACE_NAME for a15
col MB for 999999
col STATUS for a9
col ONLINE_STATUS for a13

SELECT FILE_NAME, TABLESPACE_NAME, BYTES/1024/1024 MB, STATUS, ONLINE_STATUS FROM DBA_DATA_FILES;
```

### 一時表領域のデータファイル
```
col NAME for a50
col MB for 999999
col STATUS for a9

SELECT NAME, BYTES/1024/1024 MB, STATUS FROM v$tempfile;
```
Sassのコンパイル 監視コマンドとbatコマンド化

#はじめに
Sassのコンパイルで監視するコマンドをいつも忘れてしまうのでbatコマンド化しておく

## バッチ
```scss_compile.bat
@prompt $
@echo sass compile start
@echo.
@echo         ___      ___
@echo         ^| ^|      ^| ^|
@echo     ____^| ^|______^| ^|____
@echo    ^|____   _______   ___^|
@echo         ^| ^|      ^|  ^|
@echo         ^| ^|      ^|  ^|
@echo         ^|_^|      /  /
@echo                 /  /
@echo                /  /
@echo               /__/
@echo.
@echo.

@rem remでコメント
@rem @をコマンドの前につけるとbatコマンドの際にコマンド実行時の文字が表示されなくなる

@rem ここがコンパイルのところ。以下はフォルダ毎自動監視
sass --watch bootstrap-4.4.1\scss:bootstrap-4.4.1\dist\css

```

ちょっと前半に変なものあるが、バッチコマンドを普通に作ってたら、「echo部やコメント部のコマンド箇所」と「現在のパス」が表示されてしまっていたので、対応入れて非表示にしている。

詳細は以下で示す。

## コマンド箇所の非表示の仕方
`@コマンド`

```
@echo a
```
コマンドの前に@つけるだけ。

## 現在のパスの非表示の仕方
`prompt $`
これだけだとコマンド打ったところが出ちゃうので@と合わせて使うと、
コマンドとパスも消えてくれる。

```
@prompt $
```
【スッキリ】trelloの導入【管理】

slack、メールの通知が流れてしまう
todoのやり忘れが多発している

思い悩んだことはありませんか？

今回はそんな悩みを解決するタスク管理アプリ「trello」の紹介です！

# trelloとは
https://trello.com/home
<img width="640" alt="Trello.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/a1bfda9a-f786-db38-1032-6bccc4287f20.jpeg">
タスクをポストイットのようにオブジェクト化し、todoを整理するツールです。

## 使い方
代表的な使い方は「フェーズ管理」と「個人タスク管理」の2種類があります。

### フェーズ管理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/f466ded5-9ac2-cdeb-6478-95e144f61303.png)
発生したタスクが現在どの状態かが管理しやすくなります。
タスクにアクションがあったら、次のフェーズへ移行 などの使い方になります。

プロジェクトの開発工程管理に使っています！

### 個人タスク管理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/2f6b15cd-c785-01a5-aaad-26386f64aea6.png)
誰がどのタスクを持っているかが管理しやすくなります。
その日の予定、電話取り次ぎなど小さなタスクも一元管理できます。

メンバへのタスク振り分けに使用しています。

## slackとの連携
trelloはslackとの連携もできます。

### trello→slack
trelloで新たに追加したタスク、進展があったタスクをslackへ通知させることができます。
有給明けなどではslackをみるだけで、タスクがどのようになっているか把握することができます！

### slack→trello
slackからtrelloへタスク追加等が出来ます。
こちらの機能はあまり使用していません😁


## 参考
タスク管理ツール「Trello（トレロ）」の使い方を解説！
https://ferret-plus.com/7616

SlackとTrello(トレロ)の連携方法。タスク管理もこれで完璧！
https://businesschatmaster.com/slack/trello-renkei
サイトマップとは

Webエンジニアとして知っておくべき情報っぽいので、ネットから拾った情報を自分なりに整理してみた。


# どんなもの？
サイト構成するページ全体を階層を意識して並べたもの

[こんなの](https://web-kanji.com/posts/making-sitemap-by-excel)


# 関係者　
**作る人**
Webディレクターが中心となって作る。

**見る人**

- 顧客
- Webディレクター本人
- デザイナー
- フロントエンドエンジニア
- バックエンドエンジニア

# なんのために作る？
**直接的には、次工程であるワイヤーフレームの作成の土台を作るため**であるが、
サイトを構成するページ全体を関係者(顧客/デザイナー/フロントエンジニア/バックエンジニア)に共有し、
合意を取りながら作ることで、その他以下の効果も得ることができる。超重要な工程である。

**効果**

- **サイトを構成するページの過不足発覚による工程の後戻りを防ぐ**  
  →サイトマップが適当でページの抜けが発覚した場合など、ここから工程がやり直しになってしまうことになる。
- **ページの内容とその枚数を設定することにより、「工数」と「お金」を見積もる根拠にできる**  
  →顧客とのスケジュール、予算面での調整の際にその根拠を示すことができるようになる。
- サイトマップが固まったあとは、開発終了まで**サイトを構成するページの全体像を確認するドキュメントとして各関係者と共通認識を持ち続けることができる**。

# 作成にあたって
## 前後の工程
- 前工程:顧客要求ヒアリング(Webプロデューサーメイン)
- 後工程:ワイヤーフレーム作成(Webディレクターメイン)

## サイトマップの作成工程
### 前提
- 厳密にどのページからリンクが貼ってあるか？とかは意識しない。
    - 必要なコンテンツの階層を整理するイメージ。
- ログイン/非ログイン時のアクセス可/不可も考慮せず、全権限を持ったユーザーだと考える。
    - 考慮しながらやると混乱する。
    - アクセス不可にするのは必要ないコンテンツは利用できない方がいいというものであり、それはワイヤーフレーム作成の段階で決めればよい。コンテンツの階層を整理する段階では意識しない。
    - 4. までできてから、各ページのアクセス権限について補足を加えるのはあり。(ワイヤーフレーム作成時の前提整理のために)
- サイトマップができると、**上階層ページから下階層ページへの本流となるリンクによる遷移**が見える形になる。
    - ワイヤーフレーム作成の段階で、目的のページへ一発で遷移できるような検索ボックスを設置することもあるだろうし、
      ショートカットするための本流以外のページ遷移をするリンクを設置することもあるだろうが、このサイトマップ作成の段階では意識しない。

### 1. ページ(コンテンツ)の洗い出し
- 必要そうなページをすべて洗い出す。
   - 本当に必要か？はこの時点では考えず、とにかく数を重視。
   - 5社以上、類似の目的と思われるサイトを参考にする(抜けを防ぐ)
   - このとき洗い出した各ページの役割もまとめておく
   - 検索ボックスやナビゲーションなど、サブ的な要素は考慮しない。
   - 同時並行でグループ化、階層化したりしないこと(整理していく過程で手戻り発生して無駄になる可能性がある)

### 2. ページのグループ化
- 意味のまとまり的に関連が強いページをグループとしてまとめる
   - まだ第2階層としてのグループ化のみ行う
   - ページの追加や削除もこの段階でやりきる。

### 3. ページの階層化
- 各グループで粒度が荒い順に入れ子化する  
  ※ユーザーがリンクを押す回数を減らすため、なるべくTOPページを含めて3階層で済ませることを目標とする。

### 4. サイトマップに落とし込む
- 上記の結果を受けて図・表に落とし込む。
    - **ルール**
        - トップページを第一階層として各グループ、各ページを上層から下層へ向かって並べていく。
            - グループはそれ自体がページになる。
            - 関係ないグループ同士は並列に並べる。
            - 並べ終わると、情報が徐々に引き出されていくような図が出来上がる。
    - **体裁**
        - 様々。ログイン・非ログイン時の状態も合わせて記述するものもあったりするみたい・・・
        - スプレッドシートにまとめたほうが以降、以下のような情報も付与でき、一覧として見ることができるため、開発中に全体管理しやすくなりおすすめらしい(この状態をディレクトリマップと呼ぶこともある模様)。
            - ページのURL
            - ページのタイトル(Webページとしての正式な)
            - ページの役割
            - メタデータ(SEO向け)
        - スプレッドシートにまとめない場合は、第2階層までは横に広げ、第３階層からは縦に広げるのが主流っぽい。
            - 作成に便利なクラウドサービスとして、[Cacoo](https://cacoo.com/ja/templates/sitemap-software)があるらしい

# 参考
https://liginc.co.jp/260437
https://www.tefutefusanpo.net/entry/2016/09/30/160412
https://nandemo-nobiru.com/web-5695
https://web-kanji.com/posts/making-sitemap-by-excel
envファイルとはなんだろう。

## 環境設定について

入社してコーディングの学習をメインに行なっていますが、
環境設定とかそこらへんの学習の波に乗れていないのが本音です。
早速ですが勉強してみる。

## 筆者のenvファイルの認識

プログラミングスクールではカリキュラムにさらっと書いてあるぐらいだったので深掘りしませんでした。

認識としては
「公開しちゃいけない内緒の内容を書いておくヒミツファイル」
っていう認識でした。激甘ですかね。。。
（私、スクールに通っておりました。）

## envコマンド

envファイルの前に
envコマンドというものがある！

コンピュータに対する命令の1つ
環境変数を設定してコマンドを実行する時に使うコマンド！

※書き方

```
env [オプション] [環境変数名]=[値] [コマンド]

env env1=val1 com1

```

環境変数[env1]に値[val1]が設定された状態で[com1]が実行される。


## envファイル

UNIX系のOSで使えるコマンド「env」の本体ファイル。シェル起動時に読み込まれる。
リポジトリにコミットされない。環境毎に変更したい情報をまとめておくファイル。

重要な設定変更はこのenvファイルを介して出来る。
・開発環境、本番環境の切り替え
・DBの接続情報の変更

## 注）envはconfig経由で呼ぶ事

env()はLaravelのヘルパ関数です。
第2引数はデフォルト値。

```
'username' => env('DB_USERNAME', 'doruji'),
```

例：

```config/app.php

return [
    'hoge_env' => env('hoho'),
];
```
```Conftollers/HogeController.php

$hoge = config('app.hoge_env');
dd($hoge);
```

良くない例：
envファイルをコントローラーやモデルから直接読み込まない

```Conftollers/HogeController.php
$hoge = env('hoho');
dd($hoge);
```


config:casheコマンドを実行した場合、envファイルを読み込まなくなる。
　①envファイルはIlluminate\Foundation\Bootstrap\LoadEnvironmentVariablesクラスのbootstrap()で読み込まれる
　②キャッシュがあった場合はenvの読み込み込まなくなる。

```
php artisan config:cashe
```


## envファイルの中身

```

APP_NAME： 開発しているサイト名
APP_ENV： 開発しているサイトの実行環境名(local/staging/production)
APP_KEY： 暗号化に使われるキー
APP_DEBUG： デバッグの表示設定(デフォルトはtrue)
APP_URL： サイトのURL
LOG_CHANNEL： ログ情報の設定
DB_CONNECTION：利用するデータベースの種類 (mysql/pgsql/sqlite)
DB_HOST：データベースのホスト
DB_PORT：データベースが利用するポート番号
DB_DATABASE：利用するデータベース名
DB_USERNAME：利用するデータベース名にアクセスするユーザー名
DB_PASSWORD：利用するデータベース名にアクセスするパスワード

```

## 参考資料
保存版！Laravelの.envでできること大全←九保先生の記事をいつも参考にしております！
https://reffect.co.jp/laravel/env-file-basic-understanding



まだ全容が解明できていないので多分続く。
pandas1.0.0から，read_pickle()とto_pickle()でS3/GCSのURLを指定できるようになった！

pandas1.0.0がリリースされましたね。

https://pandas.pydata.org/pandas-docs/stable/whatsnew/v1.0.0.html

新しい機能として，

- 異なる型の欠損値を統一的に扱うpandas.NAが試験導入された
- rolling.apply()をNumbaで高速化できるオプションが加わった
- データフレームをMarkdown記法で出力できるto_markdown()メソッドが追加された

といった点が目を惹きますが，個人的には上掲リリースノートの['Other enhancements'](https://pandas.pydata.org/pandas-docs/stable/whatsnew/v1.0.0.html#other-enhancements)の一番最後にさりげなく書かれた記述に目が留まりました：

> DataFrame.to_pickle() and read_pickle() now accept URL (GH30163)

これ，クラウドストレージ上にpickleで固めたデータを直接保存して読み出しできるってこと！？

てな訳でやってみました：

# 実演

次のような適当なDataFrameを作成します。

```Python
df = pd.DataFrame({'hoge': [1, 2, 3], 'fuga': [4, 5, 6], 'piyo': [7, 8, 9]})
```

こうすることで，

|    |   hoge |   fuga |   piyo |
|---:|-------:|-------:|-------:|
|  0 |      1 |      4 |      7 |
|  1 |      2 |      5 |      8 |
|  2 |      3 |      6 |      9 |

という表できました。[^1]

[^1]: ちなみに，この表は同じくpandas1.0.0から追加された`df.to_markdown()`を使用して出力しました。便利。

こいつを，あらかじめ作成しておいたAWS S3のバケット`'s3://tatamiya-test/`に保存し，読み出します。[^2][^3]

[^2]: IAMやcredentialキーの設定方法などについては割愛します。
[^3]: 確認はしていませんが，GCSでもいけるはずです。

## pandas0.25.3の場合

.csv形式での保存・読み出しであれば，従来のバージョンでも可能でした。

```Python
pd.__version__
# >> '0.25.3'

df.to_csv('s3://tatamiya-test/test.csv', index=None)

pd.read_csv('s3://tatamiya-test/test.csv')
# >> hoge	fuga	piyo
# >> 0	1	4	7
# >> 1	2	5	8
# >> 2	3	6	9
```

ところがpickleの場合，同様の操作ではPATHが認識されませんでした。

```Python
pd.__version__
# >> '0.25.3'

df.to_pickle('s3://tatamiya-test/test.pkl')
# >> FileNotFoundError: [Errno 2] No such file or directory: 's3://tatamiya-test/test.pkl'

pd.read_pickle('s3://tatamiya-test/test.pkl')
# >> FileNotFoundError: [Errno 2] No such file or directory: 's3://tatamiya-test/test.pkl'
```

## pandas1.0.0の場合
さて，最新Versionの1.0.0で試してみましょう。

```Python
pd.__version__
# >> '1.0.0'

df.to_pickle('s3://tatamiya-test/test.pkl')

pd.read_pickle('s3://tatamiya-test/test.pkl')
# >> hoge	fuga	piyo
# >> 0	1	4	7
# >> 1	2	5	8
# >> 2	3	6	9
```

きちんと保存・読み出しができることが確認できました！

# 終わりに

クラウド上でpandasを使ってデータ加工を行う際，データソースがS3やGCS上にある場合もcsv形式ファイルであればto_csv()で直接URLを指定して読み込むことができました。

しかし，整形・加工後の中間データを一旦保存しておく際には，DataFrameやSeriesをPythonオブジェクトのままバイト列に変換し保存した方が

- 容量が小さくて済む
- 再読み込みが速い
- 型指定をやり直す必要がない

といったメリットがあったため，to_pickle(), read_pickle()が重宝していました。

ただ，前述の通り従来はこのときの保存先にS3/GCSのURLを指定できず，

- クライアントライブラリを使う
- 一旦ローカル保存してからコマンドラインツールで飛ばす
- あらかじめ対象バケットをVMインスタンスにマウントしておく

といったように少し手間をかけなくてはいけませんでした。

そんなわけで，今回のアップデートは，地味ながら個人的には非常にありがたいものでした！

（ただ後方互換性が保証されないから今までコードそのままに1.0.0導入ともいかないのだよな。。。）
pythonで楕円曲線暗号解読のρ法作成

pythonで楕円曲線暗号を解読するρ法プログラム作成。
整数計算が桁数制限無しのため、1日で作成できた。
https://ecc-256.com にpythonプログラムを設け掲載。
30,40,50,60ビットの楕円曲線暗号解読例も掲載。
プログラム(Rho.py)をRho.txtに変更しても掲載に苦戦。
WordPressはtext中にimportがあるとアップロード不可と判明。
逆元(1/a (mod p))と法乗算(a*b (mod p)は定義式通り。
本暗号解読はC+gmpの15倍、C+自作多倍長の30倍程度遅い。
python(ポインタ保存)での遅さを評価するため、逆元と
法乗算をCの方式にした、高速版ρ法を作成予定。
Pythonのエラーメッセージは具体的でわかりやすい「が」(その前に、コロン(:)とセミコロン(;))

#目的
何かと比較できるほどの経験が乏しいですが、
**Pythonのエラーメッセージは具体的でわかりやすい**
と感じています。
よって、エラーは、ぱっと見るだけでなく、
記載内容をまじめに読むことが、
エラー解決の近道である気がしています。

そんな気持ちを示すための記事です。

## その前に、コロン(:)とセミコロン(;)
補足の**その前に、コロン(:)とセミコロン(;)**の意味は、
エラーメッセージによく登場するコロンの意味を示すことが目的です。
セミコロンは、比較のため。

#コロン(:)とセミコロン(;)の違い

コロンとセミコロンの違いとして、
以下のサイトの記載を参考にしました。
以下のサイトによると
（「;」セミコロンと「:」コロンの違いとは？それぞれの意味と使い方）
https://allabout.co.jp/gm/gc/471930/


コロン（：）は、

>コロンの意味は「つまり」、「例を挙げれば」です。

例文も同じサイトから引用いたします。

>I like Japanese foods: sushi, tempura, and sukiyaki.

セミコロン（；）は、

>セミコロンは、文の区切りとしてピリオドよりも短く、カンマよりも長いというイメージです。

こちらの
例文も同じサイトから引用いたします。

>I went to the library; Jonathan went to the theater.


#まとめ
あたりまえですが、
エラーメッセージにしても、英語なんで、英語を知らねばということで
コロン（：）、セミコロン（；）の説明を書いてみました。



#関連（本人）
## 直接はあまり関係ないもの
[pythonをストレスなく使う！（generatorに詳しくなる。since1975らしい。)](https://qiita.com/enoughspacefor/items/524a76fcde2610b9da8a)

[pythonをストレスなく使う！（Pythonでは、すべてがオブジェクトとして実装されている)](https://qiita.com/enoughspacefor/items/0c6118da4c228226a65f)
[pythonをストレスなく使う！（Pylintに寄り添う)](https://qiita.com/enoughspacefor/items/df692b27bb58ca1ffa1d)
[pythonをストレスなく使う！（ExpressionとStatement)](https://qiita.com/enoughspacefor/items/1a11f553c265a2c703f2)
[英語と日本語、両方使ってPythonを丁寧に学ぶ。](https://qiita.com/enoughspacefor/items/d4b49747773e2d0285f9)

#今後
コメントなどあれば、お願いします。:candy:
勉強します、、、、
Visual Studio Codeのインストール手順

# はじめに
最近、周りからVSCode使いやすいよっていう声をよく耳にします。
試しにインストールしてみたのでその手順を備忘録として記事にしておきたいと思います。

# 環境
- OS：macOS Catalina v10.15.1
- VSCode：v1.41.1

# ダウンロード
[公式サイト](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)にアクセス。
「今すぐ無料でダウンロードする>」ボタンをクリックします。

![VSCode#1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/39282389-dc3b-00be-7f60-7a03e0451196.png)

自分の環境に合わせた環境を選択してください。
（私はMacOSのため一番右を選択しました）
![VSCode#2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/a78ff39b-946a-09cf-ee09-1a03b81c86e4.png)

# インストール
ダウンロードが終わると
「VSCode-darwin-stable.zip」という圧縮ファイルがあるので解凍します。

解凍が終わると
「Visual Studio Code.app」というアプリケーションファイルが現れます。
![VSCode#3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/0e564d17-6cb0-70be-c399-0e0b5edc8f18.png)

あとはアプリケーションフォルダに突っ込んでインストール完了です。

# MacOSで起動に失敗する
アプリケーションファイルをダブルクリックで開こうとすると怒られます。
![VSCode#4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/9f5db11e-a7fd-4ce7-c6c4-ad4c07c9d94e.png)

アプリケーションファイル選択 > 右クリック > 「開く」ボタンを選択する。
（ダイアログ内の選択ボタンが変わりました）
![VSCode#6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/f59e0507-4269-c80a-ff93-74019841140a.png)

ダイアログ内の「開く」ボタンを選択すると無事に起動できました。
Docker + Go + Gin の開発環境を準備する 2020/02

Go + Gin で Web API を構築する際の開発環境を準備します。
Gin の [クイックスタート](https://github.com/gin-gonic/gin#quick-start)が動作するところまでの備忘録です。

以下の記事を書いたのが2018年5月と、時間が経ってしまいました。
https://qiita.com/kkeisuke/items/7cd4d5834386666faab3
この間に Go Modules が出てきたりと変化がありましたので、
改めて書き直しました。

## 構成

- PC：macOS Catalina
- Docker：[Docker Desktop for Mac](https://hub.docker.com/editions/community/docker-ce-desktop-mac)
  - Docker version 19.03.5, build 633a0ea
  - docker-compose version 1.25.2, build 698e2846
- イメージ：[golang Docker Official Images](https://hub.docker.com/_/golang)
- パッケージ管理：[Go Modules](https://blog.golang.org/using-go-modules)
- ライブリロード：[Air](https://github.com/cosmtrek/air)
- Webフレームワーク：[gin-gonic/gin](https://github.com/gin-gonic/gin)

## リポジトリ

本記事の成果物です。
https://github.com/kkeisuke/docker-go-gin

`kkeisuke/docker-go-gin` の部分は適時、読み替えてください。

## Dockerfile

- 参考
  - [Dockerfile リファレンス](http://docs.docker.jp/engine/reference/builder.html)

```docker:Dockerfile
# ベースとなるイメージ
FROM golang:1.13.7-buster

# プロジェクトルートに移動する
WORKDIR /go/src/github.com/kkeisuke/docker-go-gin

# Air インストール
RUN curl -fLo /go/bin/air https://git.io/linux_air \
  && chmod +x /go/bin/air

# コンテナ実行時のデフォルトを設定する
# ライブリロードを実行する
CMD air
```

## docker-compose.yml

- 参考
  - [Compose ファイル・リファレンス](http://docs.docker.jp/compose/compose-file.html)

```yaml:docker-compose.yml
version: '3'

services:
  api:
    build:
      context: .
    volumes:
      - .:/go/src/github.com/kkeisuke/docker-go-gin
    ports:
      - 3001:3001
    tty:
      true
```

## .air.conf

ライブリロードだと realize が有名かと思いますが、
近ごろ以下のような issue も見られるようになりました。
https://github.com/oxequa/realize/issues/259

そこで、今回はスター数、開発頻度を考慮して [Air](https://github.com/cosmtrek/air) を使用しています。

`.air.conf` の中身は [air_example.conf](https://github.com/cosmtrek/air/blob/master/air_example.conf) が公開されていますので、
そちらをコピペしています。適時、編集してください。

## go.mod

- 参考
    - [Using Go Modules](https://blog.golang.org/using-go-modules)

`go mod init` で作成しました。
Air で build されるタイミングで、gin が追記され、ダウンロードされます。

```go.mod
module github.com/kkeisuke/docker-go-gin

go 1.13

require github.com/gin-gonic/gin v1.5.0

```

## main.go

[クイックスタート](https://github.com/gin-gonic/gin#quick-start)をコピペしてポート指定しています。

```main.go
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "ping",
		})
	})
	// ポートを設定しています。
	r.Run(":3001")
}
```

## 出力結果

これで、以下のようにブラウザからアクセスできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61513/c1f2578f-e945-ec97-d9b7-11c01ae083bb.png)
初心者がDBを確認するときに必要なコマンド

railsのscaffoldでアプリケション作成したけど、データベースの見方やデータの確認のやり方はどうすればいいの？と疑問を持っている初心者の方にこの記事を参考にしていただきたいです。



データベース接続(作成したアプリケーションディレクトリで)

```
rails dbconsole
```

scaffold_app_development=#
↑などが出てれば接続成功です

テーブル確認(usersはテーブル名です)

```
\d users
```


   Column   |            Type             | Collation | Nullable |              Default
------------+-----------------------------+-----------+----------+-----------------------------------
 id         | bigint                      |           | not null | nextval('users_id_seq'::regclass)
 name       | character varying           |           |          |
 address    | character varying           |           |          |
 age        | integer                     |           |          |
 created_at | timestamp without time zone |           | not null |
 updated_at | timestamp without time zone |           | not null |


データ確認

```
SELECT * FROM users;
```

 id |   name   | address | age |         created_at         |         updated_at
----+----------+---------+-----+----------------------------+----------------------------
  1 | ユーザー | 埼玉  |  26 | 2020-01-23 22:33:28.970248 | 2020-01-23 22:34:42.532767
  2 | test     | 東京    |  20 | 2020-01-26 07:41:44.803812 | 2020-01-26 07:41:44.803812


```
exit
```

DB接続を切断することができます

---

ちなみにRailsコンソールでallメソッドを使ってもデータの確認できます。

```
rails console
```

```
irb(main):001:0> User.all           (Userはモデル名)
```


```
  User Load (0.5ms)  SELECT  "users".* FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[#<User id: 1, name: "ユーザー", address: "埼玉県", age: 26, created_at: "2020-01-23 22:33:28", updated_at: "2020-01-23 22:34:42">, 
#<User id: 2, name: "test", address: "東京", age: 20, created_at: "2020-01-26 07:41:44", updated_at: "2020-01-26 07:41:44">]>
```
【CSS】WEBサイトでよく設定されるfont-family

#個人的なメモです。

```html:filename.html
font-family: 'メイリオ',
Meiryo,'Hiragino Kaku Gothic ProN',
'ヒラギノ角ゴ ProN W3','ヒラギノ角ゴ Pro W3',
'Hiragino Kaku Gothic Pro','游ゴシック Medium', 
'Yu Gothic Medium', '游ゴシック体', YuGothic, 
Helvetica, Arial, sans-serif;
```
AWS Cloud9 Laravel サーバーの起動する。(Address already in useエラー対策)


```
$ php artisan serve --host=$IP --port=$PORT
```

`Preview` -> `Preview Running Application`

## エラーが出た場合

### Address already in use

```
php artisan serve Error: Address already in use
```

複数のLaravelサーバが立ち上がってるのでkillする。

```
$ kill `lsof -ti:$PORT`
```
TwilioのSIM をカーナビに使ったときの注意点

今回は完全に文字だけでお届けいたします。

# Twilio SIM とは？
Twilio社が提供するIoT向けデータSIMサービスです。
[Programmable Wireless](https://www.twilio.com/wireless) という製品名でサービス提供されています。

特徴としては、一つのAPNを設定することでで全世界で利用できることです。
必ずしも世界中移動して利用する必要はありませんが、どの場所であっても設定が同じというのは面倒がありません。
日本の昔の携帯電話では、携帯電話の現在地によって電話番号を変えないといけなかったなーんて話を聞きますが、非常に面倒ですよね。

日本ではDocomoおよびSoftbank(SBB)の回線をローミングして利用します。
[ここらへんに](https://www.twilio.com/docs/wireless/available-operators)に現在対応しているキャリアが書かれています。

# なぜにカーナビ？
Pumpkin社のAndroidの[カーナビ](https://www.amazon.co.jp/gp/product/B07V5MLHBH/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1)を買いました、が手元にちょうどいいSIMが無くあったのがこのSIMだったからです。
運悪くKenwoodのカーナビが壊れたということが主な動機です。

最初は[Serverman SIM LTE](https://dream.jp/svmsim/)を持っていたので使おうとしましたが、600kで動画も見れない（規制されています）のでどうしようか考えていました。
地図データのダウンロードもそこそこするでしょうし、制限が無いSIMが必要だったのです。

# 問題点と対応法
最初は昔使っていた[Poraloidの携帯](https://www.itmedia.co.jp/mobile/articles/1502/27/news190.html) をテザリングで使っていましたが、3Gであること、毎度テザリングのボタンを押す必要があること、通信が安定しないこと　があったので、4Gドングルを買うことにしました。
3000円弱で買いましたが、既にAmazonのリンクが無くなっておりなんとも怪しい製品です。

しかし以降も4Gを取得しても通信が安定しません。
Twilioのコンソールを見るとNTT Docomo,　SBB両方の回線を利用しているように見えます。
SBBに切り替わったとき、もしくはそれ以降に問題が起きていることが肌感覚でわかりました。

SBBでも通信はできているようですが、ちょっと安定しない。ということはDocomoだけに通信させればいいのではないだろうか。
ドングルの設定を見るとMCC,MNCが空欄になっているので固定してみようと思い、[Wikipedia](https://ja.wikipedia.org/wiki/Mobile_Network_Code)あたりでDocomoのそれらを調べると440と10であることがわかります。

**で設定すると安定して動くようになりました。素晴らしい。**
怪しいドングルではDocomoの電波を全部使えずたまに圏外になりそうですがこればっかりは仕方ないですね。
スマホのテザリングでやらないとだめっぽいです。
まただめになるかもしれないのでとりあえず見てみます。

# その他注意点
できればQuota（最低利用料金）を設定しましょう。 [料金ページ](https://www.twilio.com/wireless/pricing)を見ると、PayAsYouGo（完全従料金)の場合は 0.1ドル(MBあたり),ですが 1ドル QUOTAにするだけで0.05ドル(MBあたり)と単価が半分になります。
1ドルQUOTAは最低$1は使います、という契約です。場合によっては使わなくてもいいかもしれませんが、カーナビ用途だと必須ですね。

# おわりに
日本国内だけの使い方だとちょっとばかりもったいない使い方かもしれません。
今度海外に行ったときには使ってみようかと思います。
Pythonのエラーメッセージは具体的でわかりやすい「が」(... AAA yyy BBB)

#目的
何かと比較できるほどの経験が乏しいですが、
**Pythonのエラーメッセージは具体的でわかりやすい**
と感じています。
よって、エラーは、ぱっと見るだけでなく、
記載内容をまじめに読むことが、
エラー解決の近道である気がしています。

そんな気持ちを示すための記事です。

## ... AAA yyy BBB
補足の**... AAA yyy BBB**の意味は、エラーを発生させる要素の順番がまじめに表示
されるという意味で書きました。

あとで示しますが、単純に、

```
TypeError: unsupported operand type(s) for *: 'generator' and 'float'
```

みたいな表示のこと（後半部）を指してます。


#エラーメッセージの例

ここで示すコードは、エラーメッセージを出すためのコードで、
全く同じような間違いをする可能性があるコードではありません。
繰り返します。エラーメッセージを出さすためのコードです。
（ただし、もう少し、ややこしいコードで、同じエラーが出ているのをみたことはあります。）



## エラー１
型に関するエラーの**TypeError**が出るケースです。

コードは、以下です。

```gen_erro1.py
def my_range(first=0, last=10, step=1):
    number = first
    while number < last:
        yield number
        number += step
ranger = my_range(1, 5)
ranger2 = ranger * 2.0　#<-- エラーを出すための意味不明なコード
for x in ranger:
    print(x)
```

エラー表示は、以下です。

```python
C:\_temp_work\error1>python gen_error1.py
Traceback (most recent call last):
  File "gen_error1.py", line 7, in <module>
    ranger2 = ranger * 2.0
TypeError: unsupported operand type(s) for *: 'generator' and 'float'
```
**... AAA yyy BBB**
という意味で、
'generator' and 'float'　に
　* を作用させようとしたことが
サポート外であることが、**具体的にわかります。**
もう少し、ややこしいコードの場合、
**'generator'
と
'float'
を、この順でかけている**という情報で、
どこがおかしいか（どこが期待はずれの型になっているのかなどが）、おそらく、短時間で気づくと思います。


## エラー２
型に関するエラーの**TypeError**が出るケースです。

コードは、以下です。

```gen_error2.py
def my_range(first=0, last=10, step=1):
    number = first
    while number < last:
        yield number
        number += step
ranger = my_range(1, 5)
ranger2 = 2.0 * ranger　#<-- エラーを出すための意味不明なコード
for x in ranger:
    print(x)

```

エラーの内容は、以下です。

```python
C:\_temp_work\error1>python gen_error2.py
Traceback (most recent call last):
  File "gen_error2.py", line 7, in <module>
    ranger2 = 2.0 * ranger
TypeError: unsupported operand type(s) for *: 'float' and 'generator'

C:\_temp_work\error1>
```

**... AAA yyy BBB**
という意味で、
'float' and 'generator'　に
　* を作用させようとしたことが
サポート外であることが、**具体的にわかります。**
**'float'
と
'generator'
を、この順でかけている**という情報で、
どこがおかしいか（どこが期待はずれの型になっているのかなどが）、おそらく、短時間で気づくと思います。


#まとめ
エラーメッセージを構成するつくり上、当然の結果だとも思いますが、わかりやすいと感じたので。。。



#関連（本人）
## 直接はあまり関係ないもの
[pythonをストレスなく使う！（generatorに詳しくなる。since1975らしい。)](https://qiita.com/enoughspacefor/items/524a76fcde2610b9da8a)

[pythonをストレスなく使う！（Pythonでは、すべてがオブジェクトとして実装されている)](https://qiita.com/enoughspacefor/items/0c6118da4c228226a65f)
[pythonをストレスなく使う！（Pylintに寄り添う)](https://qiita.com/enoughspacefor/items/df692b27bb58ca1ffa1d)
[pythonをストレスなく使う！（ExpressionとStatement)](https://qiita.com/enoughspacefor/items/1a11f553c265a2c703f2)
[英語と日本語、両方使ってPythonを丁寧に学ぶ。](https://qiita.com/enoughspacefor/items/d4b49747773e2d0285f9)

#今後
コメントなどあれば、お願いします。:candy:
勉強します、、、、
CUDAでも自動補完ほしい！！ソース解析したい！！

# 動機
MicroSoftが提唱したLanguageServerProtocolがテキストエディターの補完ツールやLintingツールとして普及して久しいですね。もはやこうしたツールなしでは生きていけない体にされている人も多いと思います。これを使ってフォーマットをする方も多いでしょう。ある変数の定義にジャンプするのもコマンド一発でいけます。
しかし困ったことに、CUDA C/C++で公式のLanguageServerが提供されていないのです。そこで今回はclangdを使ってcudaでもLanguageServerを使う方法を紹介していきたいと思います。

動作環境:ubuntu18.04
clangd: version 8
CUDA   : 10.0



# clangdの設定
clangdの設定ファイルは`compile_commands.json`、もしくは、`compile_flags.txt`です[1]。`compile_commands.json`は一つ一つのファイルに対して細かくコマンドを指定できるんですが今回は全部のファイルで一括のオプションを指定する`compile_flags.txt`を使います。
`compile_flags.txt`を以下のようにします。

```compile_flags.txt
c++
-x
cuda
--std=c++14
```
これをプロジェクトのルートに配置します。
すると、.cppを開いても.hppを開いても、.cuを開いてもLanguageServerの恩恵を受けられるようになります。

# 実例
NeoVim+LanguageClient-neovim+deoplete.nvim+neosnippetの場合
設定については、人によって大きく異なると思われるので、LanguageClient-neovimのwikiを参照。

![cudaMallocManaged.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296000/44accaa7-25a5-011a-da72-a4f7ffbb1a27.gif)
cudaの関数の補完ができている様子。そして、`__global__`等が入っていても指摘してこないことから、しっかりとCUDAとして認識していることがわかる。

![add.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296000/64f6f40a-7baf-0251-dbda-15bc316a2086.gif)
blockDimやthreadIdxも補完できている様子。

![header_go_to_jump.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296000/564138fb-a3e8-5162-68db-b4633b1cf38f.gif)



ヘッダファイルでもしっかりLintingが働き、定義元へのジャンプもできます。


VSCodeでも同様のことが[vscode-clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd)を使うとできる。

![vscode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296000/5f453ba2-1bc0-db44-0e9f-d12610b4f164.gif)


以上、CUDAでもVisualStudio等の重量級IDEを使わずとも補完できるようにする方法でした。


# 参考資料
[1] Getting started with clangd &#8212; Extra Clang Tools 11 documentation https://clang.llvm.org/extra/clangd/Installation.html
【CSS】禁則処理・テキストの折返しと改行やスペースの振る舞いの制御

# 【word-break】テキスト文章内における改行位置を調整
word-breakはテキストの禁則処理についてのプロパティ
そもそも禁則処理ってなんだ → [禁則処理とは](https://ja.wikipedia.org/wiki/%E7%A6%81%E5%89%87%E5%87%A6%E7%90%86)


テキストの折返しを制御する。

**normal**: 英語は単語の切れ目で改行、日本語は表示領域の幅に合わせて改行される。初期値。

**break-all**: 禁則処理が解除された状態で、全てのテキストが単語に関係なく
表示領域の端に合わせて改行。

**keep-all**: 英語、日本語全て単語の切れ目で改行。

**break-word**: 表示領域の幅に影響する場合には、単語の中でも改行される。


#【overflow-wrap】単語内での改行の可否を決める
over-wrapは単語内でのテキスト折返しの可否を指定。 
表示領域内に収まるよう文章を配置した場合には「break-word」を指定するのがセオリー。

**normal**: 表示領域を超えても単語の途中では改行させない。

**break-word**: 表示領域の幅に影響する場合には、単語のなかでも改行される。

**anywhere**: break-wordと同じく単語の中でも改行されるが、コンテンツ幅に単語内の分割によって折り返されたサイズが考慮される。


#【white-space】スペースや改行の表示方法を指定
空白文字(スペースやタグ)や改行(改行文字や改行タグ)にたいして要素内でどのように表示されるか指定。


**normal**: 連続する改行や空白文字は、1つの改行もしくは空白文字として扱い表示され、表示領域に合わせてテキストを折り返す。

**nowrap**: 連続する改行や空白文字は、1つの改行もしくは空白文字として表示され、
テキストの折返しをしない。

**pre**: 連続する改行や空白文字は、そのまま表示され、テキストの折返しをしない。

**pre-wrap**: 連続する改行や空白文字は、そのまま表示され、表示領域に合わせてテキストを折り返す。


**pre-line**: 連続する改行は、そのまま表示され、連続する空白文字は1つの空白文字として扱い、表示領域に合わせてテキストを折り返す。