OmniAICreator/Qiita-1.07M huggingface dataset:
ハードル下げまくったポートフォリオを作った話

アウトプット駆動開発でポートフォリオ作ったのでその記録です。

#経緯
作るならかっこいいのにしたいとか、どうせフロントエンド案件は外からは来ないとかを理由にポートフォリオを作っていなかった某業務系出身フリーエンジニアは、絶妙に気になるステキ案件を見つけてしまいました。
しかも後先考えずにとりあえず応募(Wantedlyなので話を聞きたいボタン)してしまいました！

先方「ご連絡ありがとうございます！ポートフォリオ出してくださいね！(要約)」

某エ『あかん、衝動的に応募してもーたけど、外に出せるフロントエンド仕事ってレガシーJS指定＆JQueryで書いたのしかないわ』
某エ『Githubには昔手伝ってたとこ向けのニッチな業務ツールとかお遊びExcelアドインとかしかないし』
某エ『もう！バカバカ私のバカ！こういうことがあるから、ちゃちくても作っとけって言ったのに！(自分で自分に)』
某エ『・・・とりあえず返事遅くなるのは失礼だし、今更仕方ないからまずはお返事しよう』

某エ「お返事ありがとうございます！実はポートフォリオ作ったことないっす！2、3日待ってくれたら突貫で作るっす！(要約)」※積極的に背水の陣を作ってしまうタイプ

先方「わかりました！待ってますね！」

そんなわけで急遽ポートフォリオを作ることになりました。

#方針
実際いろいろ作ろうと思えば作れるとは言っても、他の作業の合間2〜3日で作れるものには限界があるので、やることを絞り込みます。
かっこいいものを作る、できる技術をいろいろ盛り込むのは後付けでいいのです。
というか、エンジニアにありがちだと思いますが、**自分でハードル上げまくって完成できないケース**には持っていかないようにします。

今回に関して言えば以下の点を最低ラインとします。

- ES6以降の記法で書く
- **背伸びせず大人しく普段通りjQueryで書く**
- webpackは普段と同じでパッケージバンドルとbabelだけ使う
- Webと直接関係なくてもGithubにあるブツは紹介しておく
- なんでも屋状態で知識が分散しているので、「それなりに使える技術」をちゃんと書く
- せっかくなので「興味があって勉強してるもの」もある程度書いておく
- ステキはともかく、見やすいサイトを心がける
- ソースマップはあえて付ける

正直こんなんでフロントエンドのポートフォリオになるのか甚だ疑問ですが、ないよりマシなので作ります。
ダメだったら今後いろいろ付け足して、またステキ案件に出会ってしまったときに備えます。
まずは動くものを作るのが大事！

#レイアウト
基本的にデザインセンスが瀕死なので、美しいステキポートフォリオとか無理なんですよね。
ただ、見づらくないものとか、それなりにすっきりしたものは作れるので、そんな感じにします。

最近はいろいろデザインツールあるじゃないですか、XDとかsketchとか。
**今回はあの辺は使いません**。
これもありがちだと思うんですけど、ツール使うことに夢中になってしまって、肝心の目的忘れるんですよね。
大体、作ったデザインをレビューするわけでもないので、自分がわかるようにアウトプットできれば充分です。
というわけで、レイアウターは**紙**です。
紙と鉛筆、最強ですよ。

※人によると思います。新しいツールふぉおおおって人はツール使う方が進むかもしれません。

#結果
そんなこんなでできたものがこちらになります。

https://www.uzuworks.net/portfolio_light/index.html
※付け足して作っていくポートフォリオとは別にこちらは残しておきます

リポジトリはこちらです。
https://github.com/uzuworks/portfolio

今後はissue管理も真面目にやってくつもりです。たぶん。
半分は気に入った技術のお試し場になりそうな気がします。

#反省点
大きなものだけ。

- コンテンツは先に用意する

ネタが少ないので見せ方を工夫しようと頑張った結果、文章などが後回しになってしまい、結構場当たり的に書いたものが多くなってしまいました。
そもそもネタが最も大事なので先に作っておくべきでした。

- 画像を足す

作り終わって確認したら、びっくりするほど画像使ってませんでした。
フリー素材でもなんでも探せばあると思うので、もっと使ってステキっぽくしてもいいのでは？と思いました。

- 見切りは早めに

やろうと思っていたことでトラブってだいぶ時間を取られました。
ないならないでどうにでもなる部分だったので、早めに後回しの判断をしていたら他に時間をかけられたので反省。

#最後に
同じように、ポートフォリオ作らなきゃと思いつつ作ってないエンジニアさんは結構いるんじゃないかと推測します。(特に業務系からの転向狙い組)
計画も大事ですけど、まずはハードル下げて作ってみるところから始めましょう。
でないと、私みたいに肝心なタイミングで困りますよ？
Cocos エンジンが正式に Matchvs に対応したので触ってみよう → できなかった編


https://mp.weixin.qq.com/s/_VzyZcLdLvs4PnmvNCpYIA

> v2.0.7からCocos Creatorに重要な機能「サービスパネル」が提供されました。Cocos CreatorのサービスパネルはCocosデベロッパーサービスへアクセスするショートカットです。 リアルタイムのオーディオおよびビデオサービスプロバイダであるAcoraとのパートナーシップに加えて、開発者がすぐに「黒字になる」ように、中国の高品質オンラインサービスプロバイダであるMatchvsともパートナーシップを組みました。今日(2019/1/14)からMatchvs SDKが正式に利用可能になりました。 サービスパネルからMatchvs SDKを利用することで、複数人が同時に遊べるネットワークゲームをかんたんに提供することができます。

# Matchvsとは？

公式ドキュメント: https://doc.matchvs.com/matchvs

> `Matchvs Game Cloud`（`Matchvs`）は商用のゲームサーバーエンジンです。 デベロッパーは、SDKのAPIを通じて、自分が設計したゲームロジックにもとづいて必要なパラメータを調整するだけです。 サーバー開発の経験がないエンジニアでも、短時間で一般的なマルチプレイヤーリアルタイムオンラインネットワーキングゲームを作成できます。 Matchvsは、高速ネットワークアクセス、マルチノード、低レイテンシ、ワンクリックでクラウドへのディプロイ、カスタマイズなどの機能をデベロッパー提供するネットワークゲームのソリューションです。デベロッパーの開発コストを節約し、開発サイクルを劇的に短縮します。

# 触ってみる

## アップデート
手元のバージョンはv2.0.5でした。探しても「アップデート」するUIはないので上書きインストールします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/4a653b2f-a4c4-d2ef-dd71-9e254cab9f6b.png)

https://cocos2d-x.org/download

記事では`2.0.7`となっていますが`2.1.0`がでているのでそちらをダウンロードします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/1ef0ca54-7f05-da62-0b5a-1c0c7fdd3a88.png)

前回と同じ場所にインストール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/7a9f3ccd-999a-52b9-6b16-44c2064a2ce4.png)

上書きインストール後 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/5816a523-e1bc-380e-c5af-a17fdc0433fe.png)

## プロジェクトを作成
`New Project` → `Empty Project` → プロジェクトフォルダ設定 → `Create`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/985b0082-6486-0132-3234-359f69bc17e5.png)


該当ドキュメントの「Mathvs Networking Serviceを開く方法」によると

>   1. Cocos Creatorを開き、[メニューバー]  - > [パネル]  - > [サービス]の順に選択して[サービス]パネルを開き、リストの[Matchvs]をクリックして[Matchvs Service Settings]パネルに入ります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/284411bb-6a6b-2de6-5138-6aed4e0806c5.png)

あれ「サービスパネル」ないやん？！

今日は以上
はじめてVimを使った。

#Vimに書き込む
Vimに書き込むには```i```キーを押す。

#Vimコマンドモード
Vimでコマンド（```:q```や```:wq```）を実行するには```Esc```キー

#Vimでペーストできない
Vimエディタにペーストするときは```Ctrl+Insert```

#Vimで編集したファイルを保存できない

一度```:q!```で保存せずに終了。
```sudo vi ファイル名```で再度開く。
記述が終わったら```:wq```

#エラーが出たら

```ruby
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
```
メッセージ通り```direnv allow```実行すると保存される。

#gitgnoreにファイルを追加する
今回編集したファイルはgitに公開できないので以下を実行
```echo ./.envrc >> .gitignore```
Paypalにはサンドボックス用のアカウントがあって1億円送金できるらしい。Qiita3分まとめクッキング。

Paypalにはサンドボックス用のアカウントがあって1億円送金できるらしい。

# 概要


>サンドボックス用の環境、アカウントが利用できるため送金、着金を実際に確認することもできます。

[PayPal Tech Meetupが楽しくて1億円送金した話 - Qiita](https://qiita.com/yuta-ron/items/dcac161fef6df1c112d8)

# 効果

>サンドボックス用のアカウントさえあれば皆お金持ちにな（った気にな）ります。

# 3種類のAPIがあるらしい

>PayPalが提供しているAPIは下記の3通りになります。
>- Client Integration - ブラウザ内の処理で決済完了(JavaScript)
>- Server Integration - サーバサイド(REST API)の処理で決済完了
>- Braintree SDK - Braintree SDKを使って決済完了

>Braintreeeは今回初めて聞いたのですが、PayPal以外(クレジットカード、ApplePay、Bitcoinなど)の決済手段を提供するためのプラットフォームです。


---

https://twitter.com/YumaInaura

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
enumerateの活用（メモ）

リストの要素に添え字をつけるような場合、Enumerateが有効。

以下のようなリストから

```python:qiita.py
list_monthes = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug', 'Sep.', 'Oct.', 'Nov.', 'Dec.']
```

以下のような出力を得たい。

1 : Jan. 
2 : Feb.
3 : Mar.
4 : Apr.
5 : May
6 : Jun.
7 : Jul.
8 : Aug
9 : Sep.
10 : Oct.
11 : Nov.
12 : Dec.

```python:qiita.py
for n in range(len(list_monthes)):
    month = list_monthes[n]
    print(n+1,':',month)
```

これで出力可能。
だが、

```python:qiita.py
for n, month in enumerate(list_monthes,1):
    print(n,':',month)
```

こちらのほうが美しい。
SikuliX 1.1.4 自分で定義した設定ファイル(INIファイル)を使う

RPA実行時に設定ファイルを使いたいこともあるだろうと考え、
設定ファイルを実行スクリプト直下に置くことを想定した。

```
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.read(sys.argv[0] + '/setting.ini')
```

Windowsだとメモ帳で設定開かれると想定するとエンコード関連で悩みそう。
jqをWindowsマシンにインストールして使ってみる

Macではよく使っていたjqを、Windowsマシンにインストールして使ってみたときのメモです。

## jqインストール
[オフィシャル](https://stedolan.github.io/jq/)からexeファイルをダウンロードしてお好みの場所に配置します。お好みで環境変数のPATHを通します。

```
>jq-win64.exe -V
jq-1.6
```

参考
Windows で JSONを整形する
https://kagasu.hatenablog.com/entry/20151223/1450829136

## サンプルjsonを作ります
```
>type sample.json
[
  {
    "aa": [
      "bb",
      "cc"
    ],
    "dd": "ee",
    "ff": {
      "gg": "hh",
      "ii": "jj"
    }
  }
]
```

参考
JSON Pretty Linter Ver3
https://lab.syncer.jp/Tool/JSON-Viewer/

## いろいろ試します
コマンドプロンプトでも、以下のように、馴染みのあるLinux風のjqの使い方ができそうです。

```
>type sample.json  | jq-win64.exe ".[]"
{
  "aa": [
    "bb",
    "cc"
  ],
  "dd": "ee",
  "ff": {
    "gg": "hh",
    "ii": "jj"
  }
}
```
とか、

```
>type sample.json  | jq-win64.exe ".[] | ."
{
  "aa": [
    "bb",
    "cc"
  ],
  "dd": "ee",
  "ff": {
    "gg": "hh",
    "ii": "jj"
  }
}
```
とか

```
>type sample.json  | jq-win64.exe ".[] | .aa"
[
  "bb",
  "cc"
]
```
とか。

typeのかわりにmoreコマンドでもよさそうです。

参考
パイプを使いコマンドの標準出力を他のコマンドの標準入力へ渡す
https://www.adminweb.jp/command/redirect/index6.html
PysparkでUDFを書く

いつも忘れちゃうので。
# UDFの定義の仕方
書き方は２通り。
## `udf`関数に取り込む
`lambda`関数を書くときに便利。

```python
from pyspark.sql.functions import udf, col
from pyspark.sql.types import StringType
from urllib.parse import urlparse

extract_domain = udf(lambda url: urlparse(url).netloc, StringType())
```

## デコレータを使う
やりたい処理が長くなっちゃうときに便利。

```python
@udf(StringType)
def extract_domain(url):
  uri = urlparse(url)
  domain = uri.netloc
  return domain
```

# 定義したUDFの使い方
関数として普通に使える。

```python
df = df.withColumn('domain', extract_domain(col('url')))
```
ifortでコンパイルできるのにgfortranでコンパイルできない時

誰かが書いたコードがFORTRAN77だった時、そしてそのコードがifortではコンパイルできるのにgfortranだとエラーが出てしまうときがあると思います。

# parameter

例えば、gfortranのバージョンにも依存しますが、

```fortran
      parameter ite = 1
```
はifortだとコンパイルできますが、gfortranではエラーが出る場合を警告が出る場合があります。
その場合には、

```fortran
      parameter(ite = 1)
```
とします。

# 長さ制限

## 問題

ifortでは72文字の長さ制限に引っかからないのにgfortranでは引っかかる例として、

```fortran
	implicit real*8 (a-h,o-z)
	a = (1+2+3+4+5+6+7+8+9+10)*(1+2+3+4+5+6+7+8+9+10)*(1+2+3+4+5+6+7+8+9+1)
	end
```
があります。これをtest.fと保存します。ifortの場合には

```bash
ifort test.f
```
はコンパイルできますが、gfortranの場合には、

```bash
gfortran test.f
```
ではコンパイルできません。
これは、最初の空白は実はタブになっていることがポイントです。
FORTRAN77は72文字制限があり、72文字を越えるとコンパイルができなくなります。
上の例では、タブの部分を除くと、72文字です。タブを何文字換算するかは機種に依存するかもしれませんが、ifortの場合には、このタブの部分の文字数のカウントをしていないために、コンパイルができます。
一方、gfortranはタブを文字数にカウントしているため、72文字制限に引っかかってしまい、コンパイルできません。

## 解決策
上記のコードをgfortranでもコンパイルしたい場合には、

```bash
gfortran test.f -ffixed-line-length-80
```
とします。```-ffixed-line-length-80```は、固定書式の長さを80にする、というコンパイルオプションです。
これを使うことで、制限が80文字になるため、タブが入っていても制限に引っかからなくなります。
Bigquery TIMESTAMP を unixtime INTEGER にキャストする

Bigquery CAST TIMESTAMP to unixtime INTEGER 
Bigquery TIMESTAMP を unixtime INTEGER にキャストする

# OK

```
SELECT UNIX_SECONDS(CURRENT_TIMESTAMP())
```

# NG

```
SELECT CAST(CURRENT_TIMESTAMP() AS INT64)
```

# Error

```
Query Failed
Error: Invalid cast from TIMESTAMP to INT64
```


---

https://twitter.com/YumaInaura

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
DjangoでWeb APIを公開してみる

# 背景
DjangoでWeb APIをさくっと作成する情報はたくさんあるが、
実運用に向きな記事が見つからなかったので作成する。

# 環境
 Django 2.0.2
 Python 3.6.1

# Webフレームワーク
Django：今回はこれを使う。フルスタックフレームワーク
[Flask](http://flask.pocoo.org/)：マイクロフレームワーク。最低限の機能。～中規模までのWebアプリに向いている。
[Bottle](https://bottlepy.org/docs/dev/)：マイクロフレームワーク。軽量で小規模なアプリに向いている
Tornado：非同期系フレームワーク。非同期Webサーバーの側面がある。
これら以外にもたくさんある。


| フレームワーク       |       Django |    Flask    |
|:-----------------|------------------:|:------------------:|
| 分類            |              フルスタック |       マイクロ        |
| 用途           |            がっちり作りたい |       ちょこっと使いたい       |
| メリット            |        色々入っててうれしい |     軽量        |
| デメリット            |        少し設計知識が必要 |     色々したければ自分で追加していく必要がある        |
| 利用されてるサービス            |  YouTube,Instagram |    Netflix        |



# Django REST Framework
今回は、Django REST Frameworkを使ってAPIを作る方法を紹介。

REST（レスト）とはWebサービスの設計モデルのこと。

ここでいう設計モデルとはDjangoのMTV（Model・Template・View）のように、
システムに共通する設計のことをいう。

・同じURLからは常に同じ内容のレスポンスが返ってくる。
・クライアントのマシンの状態やブラウザのセッションに依存しない。

これらの項目をはじめとする原則を満たしているサービスを、RESTfulなサービスと呼びます。

# Djangoの機能
## Webアプリケーションでよく使われる機能
- 認証: 概要 | 認証システムを使う | パスワード管理 | 認証の処理を自作する | API リファレンス
- キャッシュシステム
- ログ出力
- メール送信
- 配信フィード (RSS/Atom)
- ページ分割表示
- メッセージフレームワーク
- データのシリアライズ
- セッション
- サイトマップ
- 静的ファイル管理
- データバリデーション

## その他便利な機能
- 条件付きコンテンツ処理
- コンテンツタイプと汎用リレーション
- flatpages: フラットページコンテンツの管理
- リクエストのリダイレクト
- イベントのシグナル
- システムチェックフレームワーク
- サイトフレームワーク
- Django での Unicode の扱い方
SeleniumConf Chicago 2018 講演リストを作ってみた

2018年10月にシカゴで開催された　SeleniumConfの内容が　YouTurbにアップされているので、その一覧を（機械翻訳して）作ってみました

https://www.youtube.com/playlist?list=PLRdSclUtJDYUkhPwOhIrjA2BPbnw2Vrlm

| No.|時　　間|タイトル|speker|
|-----|:-----:|:--------|:-------------|
|1|14:43|SeConf 2018 - シカゴ：開会の辞||
|2|48:06|レベルアップ：オートメーションゲームをプレイする |Angie Jones |
|3|33:24|自動化されたもの | Raluca Morariu |
|4|39:39|AWS Lambdaを使用してSeleniumを無限大にスケーリングする |Wes Couch＆Kurt Waechter|
|5|33:36|エレメント選択のためのAI |Jason Arbon|
|6|40:54|AIがソフトウェアテストをどのように変革しているか |Raj Subramanian |
|7|33:02|あなたの携帯アプリの負荷を軽くする|Christina Thalayasingam|
|8|39:54|UIの自動化 - 無料ではない |Aditi Mulay|
|9|48:35|セレン：組合の状態 |Simon Stewart＆Jim Evans |
|10|26:01|Automatorは起動します：あなたの内側のスーパーヒーローを解き放ちます |Marlena Compton|
|11|34:00|共同開発と成長を重視したテストエンジニアがどのように勝っているか | Meredith Bayne|
|12|32:12|眠ることはオートメーションのあなたの親友ではない | Michelle Macdonald |
|13|26:43|文脈：多言語ソフトウェア翻訳に欠けている要素 | Mirjana Andovska|
|14|38:55|詐欺師症候群を克服する | Elysia Lock|
|15|38:51|UnityのゲームやアプリケーションにAppiumを使用する | Ru Cindrea|
|16|33:01|自動アクセシビリティテスト | Dylan Barrell | 
|17|38:45|違いを見分ける：ビジュアル回帰テストの自動化 | Viv Richards|
|18|40:46|2日目のライトニングトーク||
|19|32:28|デイ1ライトニングトーク||
|20|50:00|1秒未満の受入試験 | AslakHellesøy|
|21|30:52|Selenium Grid Dockerコンテナ、Selene、pytest | Derrick Kearney|
|22|36:18|Seleniumを使用しない3つの方法 | Jain Waldrip |
|23|27:21|あなたの自動化を知っている |  Hugh McCamphill|
|24|38:06|よく設計された自動化フレームワーク | Adam Goucher|
|25|30:44|新しいSelenium IDEの設計 | Tomer Steinfeld |
|26|37:33|ボットを使った繰り返しのコミュニケーションタスクの自動化 | Pooja Shah | 
|27|43:21|セレン委員会パネル||
|28|1:09|Selenium Chicago 2018ハイライト||

- なかなか全部を見ることができないのですが、タイトルを日本語訳するだけでも「お？！」ときになるものがわかりますね。
- 英語の壁があること、動画なので見る時間がかかることというのがありますが、画像から「なるほど〜」というものがわかるといいな〜


で
で
で

#Selenium Conference Tokyo　 2019年4月18日19日
- 今年はついに東京で開催です！！
https://conf.selenium.jp/
tmuxとは何ぞや？

*tmux*を導入したものの、よく分からなかったので調べてみた。

〇*tmux*とは？
簡単に言うと、端末多重化ソフトウェアのこと。
1つのターミナルで捜査しているシェルから実行した*tmux*上での仮想端末を操作できる
⇒つまり・・・ターミナルをたくさん開かずに、複数のサーバーへログインできる！
　それぞれの仮想端末で別々のプログラムを実行できる！

☆効率的な作業が可能


＊*tmux*を使用したサーバーへの接続のイメージ
<img width="565" alt="tmux仕組み.png" src="https://qiita-image-store.s3.amazonaws.com/0/298112/7f44daa5-8439-238e-485d-0f4b129c348a.png">




●*tmux*がないとこんなことに・・・
・サーバーに*SSH*接続するたびに端末が開かれる。いろんな画面が開かれすぎてぐちゃぐちゃに

・実行中に回線が切れることも


＊*tmux*を使用していない場合
![tmux未使用](http://2.bp.blogspot.com/-VokEmNYxZ5Q/UvnWiVCvnNI/AAAAAAAAAbM/YGcwPOa7oew/s640/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2014-02-11+16.11.48.png "tmux未使用")


＊*tmux*を使用している場合
![tmux使用](https://blog.adachin.me/wp-content/uploads/tmux11.jpg "tmux使用")
PHPは引数が足りないときはエラーになるが、引数が多いぶんには何も言わない

PHPは関数の引数が足りないときは、Fatalエラーを出すが、引数が多いぶんにはエラー等にはならず、そのまま処理が進む仕様がある。

関数の引数が足りないとき:

```php
function dyadic_function($arg1, $arg2): void
{
	// do nothing
}

dyadic_function(1);
```

出力結果:

> PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function dyadic_function(), 1 passed in Test.php on line 8 and exactly 2 expected in Test.php:3

関数の引数が多いとき:

```php
function dyadic_function($arg1, $arg2): void
{
	// do nothing
}

dyadic_function(1, 2, 3);
echo 'OK';
```

出力結果:

> OK

ちなみに、上記の再現コードは[GitHub](https://github.com/suin/php-playground/tree/master/ArgumentCountCheck)に置いておいた。

引数を多く渡すコードは実行しても気づけないことがあるので、PhpStormを使ってコーディング中に分かるようにしておく。これがまずは手頃にできる対応だろう。

PhpStormが問題点を警告する様子:

<img width="616" alt="php-playground___Volumes_dev_php-playground__-___Library_Preferences_PhpStorm2018_3_scratches_scratch_4_php.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/3f43ce33-c7c0-53b9-55aa-3bf3cf3102f8.png">
【Gmail】送信者アドレス追加時のサーバーエラー／キャプチャロック解除

##エラー内容##
【エラー】
送信元アドレス(送信者アドレスエイリアス)追加設定で認証失敗のエラーでアドレス追加が出来ない

【詳細】
以下の手順でエイリアスを設定する
https://support.google.com/mail/answer/22370?hl=ja
しかしsmtpサーバー設定の画面にて
<a href="https://gyazo.com/f2ad0611d1565e2a7f03f30bd34981df"><img src="https://i.gyazo.com/f2ad0611d1565e2a7f03f30bd34981df.png" alt="Image from Gyazo" width="622"/></a>

SMTPサーバー：smtp.gmail.com
ユーザー名：ログインアドレス(例：hogehoge@gmail.com)
パスワード：ログインアドレスのパスワード
ポート：５８７
接続：TLS


でアカウント追加すると以下のエラーが返り追加出来ない
<font color="Red">
**認証が失敗しました。ユーザー名とパスワード、およびhogehoge@gmail.comによる
安全性の低いアプリのアクセスを確認してください**
</fonnt>


##解決方法##

>安全性の低いアプリのアクセスを確認してください

とあったため以下の方法で安全性の低いアプリの有効化を試してみる

1. 無料 Gmail アカウント（hogehoge@）で Gmail < gmail.com > にログイン
※併せてG Suite アカウントでは完全にログアウトしていることをご確認
2. < https://myaccount.google.com/lesssecureapps > にアクセス
3. [ 安全性の低いアプリの許可: 有効 ] を「有効」に設定

< 安全性の低いアプリの有効化 - Google Chrome ヘルプ >
https://gsuite.google.com/intl/ja/terms/user_features.html

しかし同じエラー。。。。。。。


Googleに問い合わせ、以下の手順で解決した



【原因】
設定時に SMTP のログインに何度も失敗をしていることにより、キャプチャロックがかかっていた

【解決方法】

ログインアカウント：hogehoge@gmail.com
1. シークレットブラウザで、[https://www.google.com/accounts/DisplayUnlockCaptcha] にアクセス

2.ログインを求められたら、hogehoge@gmail.com でログイン
ページに表示された手順を実行
3.再度、hogehoge@gmail.com でログインをした Gmail 画面上で送信アドレスの設定を行う 

<プライベート ブラウジング - パソコン - Google Chrome ヘルプ>
https://support.google.com/chrome/answer/95464?co=GENIE.Platform%3DDesktop&hl=ja


無事設定出来ました！！
[Python] [Tips] ワンライナー(?)でyaml->json

~~ワンライナーである必要なくない？~~

ちょくちょく、やりたくなるのでメモ。

例えば、カレントディレクトリの`docker-compose.yml`をjsonに変換する場合

```sh
python -c "import yaml; import json; print(json.dumps(yaml.load(open('docker-compose.yml').read()), indent=2))"
```

出力例

```
{
  "version": "2",
  "services": {
    "swagger-editor": {
      "image": "swaggerapi/swagger-editor",
      "container_name": "swagger-editor",
      "ports": [
        "8088:8080"
      ]
    }
  }
}
```
以上

### 解説

基本的にPythonは改行で命令文の区切りを、インデントでブロックを表す言語です。
しかし、命令文の区切りにはセミコロンを使うこともできます。
yamlからjsonに変換するためには、yamlパッケージとjsonパッケージが必要なので、
これらはimportする文を書き、これらをセミコロンによって一行にまとめます。

```py
import yaml; import json;
```

次に、ファイルをオープンし読み出し→yamlとしてロードしdictに変換→dictからjsonにダンプするコードを書きます。

```python
json.dumps( # dictをjson文字列に変換
    yaml.load( # yaml文字列をdictに変換
        open('docker-compose.yml').read() # ファイルオープンし、読み出し
    ),
    indent=2 # json文字列をインデントつきで出力
)
```

最後にこれをprintに入れて、標準出力に吐いています。
[django] カスタムコマンドを作る



- 作成したアプリケーション内に management/commands ディレクトリを作る
- commands ディレクトリにpythonファイルを作成する
	- pythonファイルがコマンド名になる


``` sh
作成したapp
└── management
    └── commands
       └── hoge.py
```


- django.core.management.base.BaseCommand を使う


```Python
from django.core.management.base import BaseCommand, CommandError


class Command(BaseCommand):

    def handle(self, *args, **options):
        # 処理を書いていく

```


参考URL
https://docs.djangoproject.com/en/2.1/howto/custom-management-commands/
如何用功率计来训练自己


#功率计现在已经变得越来越可以买得起了. 但是如何用它确实另外一个话题.
来自 Train Sharp Cycle的教练 Jon Sharples说道, "使用功率计的最大优势在于它能够提供实时的信息, 来表达当前你付出的努力." 它并不是说只是在训练完之后去看看自己的数据怎么样, '而这样也不会对你提高训练效率有任何的帮助'. 他说道.

但是相当于'心率计', 它到底有什么优势呢? 其实说道心率, 它有很多影响因素在, 如何用功率计来训练自己水补给, 营养补给状态, 肌肉疲劳程度, 还有温度等等. 所以很多时候你是不能够通过心率来决定是否到达了自己真正的阀值来指导你应该更多的付出还是需要休息了.

和心率计不同的是, 功率计会实时的告诉你当前的状态. 这样就能够让训练者清楚得知道自己能够通过付出多大的努力来完成多久多长距离的骑行训练.

#那么功率计到底能够给我们展示什么呢?
打个比方功率计就是一个能量显示器,(通过瓦特来度量付出) 所以它最大的优势在于, 它可以让你针对一个活动,在一个最理想的能量区间来训练. 例如你要专注于一个25英里的计时赛, 你就可以针对它来置顶一个最大化的能量训练计划来最大化最优自己的成果.


#那么怎么使用它呢?

首先说清楚的就是只有你知道如何正确使用它, 它才不是一个只是很贵的玩意儿.

拿到它之后先要做的是就是通过训练来设定自己的训练区间.

最佳的测试方法就是20分钟的 FTP 测试(功能性阈值功率), 功能性阈值功率它表示60分钟可持续输出的最大功率.
通过 FTP 测试可以衡量训练成果,来确保你是在一个正确的训练区间内训练. 但是通常60分钟测试比较费耗神. 平时会推荐使用20分钟测试, 然后乘以0.95就可以一定程度代表60分钟的最大功率输出.

一个 FTP 测试需要充分的热身之后再进行,这个热身同样不是很简单的,需要能够确定可以完成接下来的20分钟测试.
而一定你拿到自己的 FTP 值, 就可以计算得到自己的训练区间. 如下:

Zone  Purpose         %FTP
1 Active Recovery     <55
2 Endurance           56-75
3 Tempo               76-90
4 Lactate Threshold   91-105
5 VO2 Max             106-120
6 Anaerobic Capacity  121-150
Read more at https://www.cyclingweekly.com/fitness/training/how-to-ride-with-a-power-meter-187592#Yk1HRsCQCAtzqxjE.99

#如何通过功率数据来指定训练计划呢?

通常需要一个积极的训练和合理的休息来提高你的训练成果.
如果没有清晰的 精确的功率数据是很难拿到自己想要的结果的.

功率计对于冲刺高强度是非常有用的, 特别是很短的那种. 因为心率计在这个过程中间通常会有延迟.
而且通常比较功率计的结果和心率的结果也是很有意思的. 如你的功率没有变,心跳在下降就说明你变强了.

而且功率计可以有一些预警的作用, 当生病或者训练过度的情况下, 如果你的心率过低过高,在同样的功率输出的情况下那就要注意了.

#一些训练中提高的词汇:

1. TSS(training stress score) 训练强度指数
2. ATL(acute training load) 7天训练强度
3. CTL(chronic training load) 42 天训练强度  
4. TSB(training stress balance) 它不用于 ctl 或者 atl,它可以表示一个 rider 是否达到最优的训练效果.
介绍骑行功率计数据


#Power 我们称之为能量
它是用来衡量你使用了多少能量, 通常都是使用`watt 瓦特`单位来标记. 在骑行过程中,所谓的能量就是说你付出了多大的努力.如爬一段坡.
它是在整个周期内不断的多余能量付出的记录过程. 它通常会使用在基于能量训练的方式中. 这里着重要说的就是一个瓦特就是一个瓦特,它是可以绝对的用来度量或者比较大.或者一个马力就是746瓦特,

#average power 平均能量

#KiloJoules 千焦耳

#Threshold Power


这个是一个很重要的指标用来衡量你可以在一个小时内持续的输出的能量.通常可以用20分钟方法来测试.

#Normalized Power

#Watts/Kg


#Training Stress Score



```
Training Stress Score (TSS), which is licensed exclusively by TrainingPeaks and used in its WKO+ coaching software, which Coggan co-developed. 

```

#Heart rate

#Cadence
Oracle Textインデックス作成時にDRG-11135エラーとなる際の確認事項

Oracle Textインデックス作成時に「DRG-11135: 機能は通常、使用できません」(DRG-11135: Feature Not Generally Available)とメッセージが表示され、インデックス作成に失敗する場合があります。

```
SQL> CREATE INDEX IDX_HOGE ON HOGETBL (HOGE)
  INDEXTYPE IS ctxsys.context
  PARAMETERS ('
    LEXER hoge_lexer
    STORAGE hoge_storage
    SYNC(ON COMMIT)
  ');

CREATE INDEX IDX_HOGE ON HOGETBL (HOGE)
*
行1でエラーが発生しました。:
ORA-29855: ODCIINDEXCREATEルーチンの実行でエラーが発生しました。 ORA-20000: Oracle
Textエラー:
DRG-11135: 機能は通常、使用できません ORA-06512:
"CTXSYS.DRUE", 行160
ORA-06512: "CTXSYS.TEXTINDEXMETHODS", 行366
```

## 原因
「NCHAR型」「NVARCHAR2型」「NCLOB型」のフィールドでは、Oracle Textを使用することができません。

このエラーが表示されるほとんどのケースでは、上記のような型の問題（これらの型となっていること）により発生します。

## 対応方法
当該フィールドを「CHAR型」「VARCHAR2型」に変更可能であれば、変更します。

## 参考
- https://support.oracle.com/knowledge/Oracle%20Database%20Products/2388663_1.html
bq query コマンドで Standard SQL を使うオプションは --nouse_legacy_sql

bq query command use Standard SQL option is --nouse_legacy_sql
bq query コマンドで Standard SQL を使うオプションは --nouse_legacy_sql

# Example

```
bq query --nouse_legacy_sql 'SELECT * FROM dataset.table'
```

# REf

[bq コマンドライン ツールの使用  |  BigQuery  |  Google Cloud](https://cloud.google.com/bigquery/docs/bq-command-line-tool)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
MySQLが勝手にパースして日付や時間の型にしてくれる話

以下 MySQL5.6.41 でのお話。あと今日（これ書いてる日付）は2019年1月18日である。

突然だがこんな事ができる。

```
mysql> SELECT 20190118=CURRENT_DATE();
+-------------------------+
| 20190118=CURRENT_DATE() |
+-------------------------+
|                       1 |
+-------------------------+
1 row in set (0.01 sec)

mysql> SELECT '20190118'=CURRENT_DATE();
+---------------------------+
| '20190118'=CURRENT_DATE() |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)
```

ちなみに1ってのはtrueである。もうちょっと詳細を出すとこんな感じである。

```
mysql> SELECT 20190118, CURRENT_DATE(), 20190118=CURRENT_DATE();
+----------+----------------+-------------------------+
| 20190118 | CURRENT_DATE() | 20190118=CURRENT_DATE() |
+----------+----------------+-------------------------+
| 20190118 | 2019-01-18     |                       1 |
+----------+----------------+-------------------------+
1 row in set (0.00 sec)
```

人によっては気持ち悪いと思うかもしれないが、日付をINT型にしているテーブルでもこういった比較が使えるのである。ちょっと便利。クライアント側とサーバ側でタイムゾーンが不一致のケースとか考えなくていいわけだ。

でも欠点もある。例えば「20190118」といった日付がDATE型以外で設定されたテーブルでパーティションを切ってたときは無効になったりする。

そもそもこの比較はどういった型にされているかというところであるが、MySQLのドキュメントでは比較時の型変換は以下のように書いてある

参考：https://dev.mysql.com/doc/refman/5.6/ja/type-conversion.html

> 演算子が別の型のオペランドとともに使用されると、オペランドの互換性を保つために型変換が発生します。一部の変換は暗黙的に発生します。たとえば、MySQL では必要に応じて数字が文字列 (またはその逆) に自動的に変換されます。

とのことだが

> 引数の一方が TIMESTAMP または DATETIME カラムで他方が定数の場合は、比較が実行される前に定数がタイムスタンプに変換されます。これは、ODBC により適合させるために実行されます。これは、IN() への引数には実行されません。念のため、比較を行う際は、常に完全な日付時間、日付、または時間文字列を使用してください。たとえば、日付または時間の値とともに BETWEEN を使用したときの結果を最適にするには、CAST() を使用して、明示的に値を目的のデータ型に変換します。
> 
> テーブル (複数可) からの単一行のサブクエリーは、定数とみなされません。たとえば、サブクエリーで DATETIME 値と比較される整数が返される場合は、比較が 2 つの整数として実行されます。整数は時間値には変換されません。オペランドを DATETIME 値として比較するには、CAST() を使用して、明示的にサブクエリーの値を DATETIME に変換します。

日付だけの場合（つまるところ `CURRENT_DATE()` の結果）はDATE型なのだが、DATETIME型がDATE型とTIME型の組み合わせのようなのでおそらくDATETIMEのルールが使用されているのだと思われる（参考:[日付と時間型の概要](https://dev.mysql.com/doc/refman/5.6/ja/date-and-time-type-overview.html)）。

つまり、変換可能だと判断されると数値や文字列から勝手に変換されるわけである。ちなみに変換不可能ってどういうケースかというと場合によるらしい。例えば以下のケースは通る。

```
mysql> SELECT '2019:01:00'<CURRENT_DATE();
+-----------------------------+
| '2019:01:00'<CURRENT_DATE() |
+-----------------------------+
|                           1 |
+-----------------------------+
1 row in set (0.00 sec)
```

コロンを区切りとして取っているほか、「0日」という表現も許容しているわけである。

ただし「場合による」というのは設定によっても変わる。サーバのSQLモードによって厳密に取ったり取らなかったりする（参考:[サーバSQLモード](https://dev.mysql.com/doc/refman/5.6/ja/sql-mode.html)）。

サーバによって変わるので、これを使うべきかどうかはそのときに議論しておいたほうがいいだろう。DBを移行させると設定漏れが起きて動かなくなる可能性があるし、しかしDBを移行させること自体が発生するかどうかという話もある。また先ほど行ったとおり日付にパースされるので、インデックスが無効化されることもある。そうなるとネックになるので、必ずコード内に書く前に類似のSQLで一旦試してみることをおすすめする。
JDKをバージョンアップしたらeclipse起動時エラー

#JDKを8から11にバージョンアップした
- Oracle JDK8をアンインストール
- OpenJDK11をインストール（環境変数PATHにbinフォルダを設定）
- OpenJDK8をインストール（環境変数PATHには含めない）

そして今までのeclipseを起動したらエラーが出た。

```workspace\.metadata\.log
org.eclipse.e4.core.di.InjectionException: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
	at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:410)
	at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:318)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:162)

```

JDK11に対応していないことが原因なので、JDK8で動かす必要がある。
でも新しいeclipseはJDK11で動かしたいので、環境変数PATHは変えたくない。

#eclipse起動に使うjavaw.exeを指定する
通常はPATHが通っているjavaw.exeが使われる。
eclipse毎に明示的に使用するjavaw.exeを指定すればよい。
eclipse.exe と同じ場所にある eclipse.ini に追記することで明示的に指定する。
1. eclipseが起動している場合は落とす
2. eclipse.ini をテキストエディタで開く
3. -vmargs の前の行に次のような -vm の2行を追記する

```eclipse.ini
：
-vm
C:\（JDK8のパス）\bin\javaw.exe
-vmargs
：
```

#eclipseを起動
正常に起動した(^o^)

Spring Tool Suiteなど、eclipseベースのツールであれば、iniファイル名が異なるだけで同じ対応で解決します。
DRY原則と一緒に教えてほしいこと


## なにが言いたい記事か

既存関数の引数にフラグを追加するのは止めさせてほしい。

## 想定読者

新人プログラマさんにも読んでもらいたいが、それ以上に新人に教育する方とか、レビュアーさんに読んでもらいたい。

## DRY原則とは

こちらをどうぞ
[DRY原則（プログラマが知るべき97のこと）](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/DRY%E5%8E%9F%E5%89%87/)

要はコーディングにおいては抽象化で重複を避けましょうね、という主張。
本当は「抽象化」というところが肝なのだけれどそこを削ぎ落として単純化し、「コピペコード禁止」としている現場もある。

## 間違った解釈

ところが新人さんにこのDRY原則を教えると曲解してしまう人が必ず一定数いるのだ。
具体的には以下のような具合だ。

例えば以下のコードがある。

```cpp
void do_something() {
    // 処理A
    // 処理B
}
```

新たに処理Aと処理Cを処理する関数が欲しくなったとする。
DRY原則を曲解した人は以下のようなコードを書いてしまう。

```cpp
void do_something(bool do_C = false) {
    // 処理A
    if (do_C) {
        // 処理C
    } else {
        // 処理B
    }
}
```

「まさか？！そんなコード書く人なんていないだろ」というあなたはいままで幸せなプログラミング人生を送ってきました。うらやましい。

## 何がいけないのか

責務分割とか凝集度・結合度といった話は置いておいて、引数へのフラグ追加を放置してるとこうなっちゃうよという話。
実際に以下のようなコードに遭遇したことがある。

```cpp
void do_something(bool do_A=false, bool do_B=false,
                  bool do_C=false, bool do_D=false,
                  bool do_E=false, bool do_F=false) {
  // なにか処理

  if (do_A) {
    // 処理A
  }

  if (do_B) {
    // 処理B
  }

  if (do_C) {
    // 処理C
  }

  if (do_D) {
    // 処理D
  }

  if (do_E) {
    // 処理E
  }

  if (do_F) {
    // 処理F
  }
}
```

まずテストが大変だ。c1網羅しようと思うと $2^6$ 通りのテストが必要になる。もしかしたら実際には処理Aと処理Cが同時に実行されるケースなんて無いのかもしれないのにだ。

更に可読性も悪い。

```cpp
do_something(true, false, true, false, true, false);
```

上記コードを見て何をしてるか即座にわかる人はまずいないだろう。


# どうするべきだったのか

冒頭の例であれば、処理Aを関数化するだけでよかったのだ。

```cpp
void do_A() {
    // 処理A
}

void do_something() {
    do_A();

    // 処理B
}

void new_function() {
    do_A();
    
    // 処理C
}
```

# どうしてこうなった

新人さん（だけじゃないけど）を観察してると一定数いるのが、「関数を作るときは必ず既存関数をコピペして修正する」という人だ。話を聞いてみると新規で関数を作ることに何かしら抵抗があるようなのだ。そういう状況の人に一律「コピペ禁止」というルールを押し付けると何とかして既存関数のみで解決しようとし、既存関数へのフラグ追加という結果になってしまっているようだ。

# 解決策？

画期的な解決策というものはなくて、やはり地道なレビューが重要だと思う。
経験上メンテナンスコストの増大という意味では**コピペコードよりもフラグまみれの関数の方がはるかに被害が甚大**なのだが[^higai]、単体テスト等で見つけられる類のものでもない（デフォルト引数の追加では既存の単体テストは通ってしまう！）ため、レビュアーさんの頑張りにかかっている。

[^higai]: とは言うものの現実はもうちょっと厳しくてフラグまみれの関数がさらにコピペされたりするのだ。
クライアントから S3 に直接アップロードする方法


streampack の Tana です。

動画を管理するCMSは、様々な拡張子のファイルや数GB動画を同時に
アップロードされることもあるので、サーバー経由の場合だと下記の考慮をする必要があります。

- メモリ消費
- ディスクサイズ
- タイムアウト
- プロセス処理時間 (他のリクエストが待たされる・受け付けなくなる)

今回、外部サイトとのアップロード連携する必要がありそうで、
サーバーの負荷を考慮したくないので(今もしていない)、
pre-sigined URL(PUT)版で s3 に直接アップロードする方法の一つです。

下記はサーバ経由アップロードとS3直接アップロードの違い:
![D149F043-F749-4551-8E52-5531D96745A5.png](https://qiita-image-store.s3.amazonaws.com/0/232803/d3191454-ceae-096c-952e-a72c255f0e6b.png)
[参照元](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html)

Signature V4 を自前で作成するのは複雑なので、
今回は AWS Ruby SDKを使って、pre-Signed URL を生成して、アップロードします。


```
> obj = s3.bucket('your-bucket-name').object('tmp/test.mp4')
> url = URI.parse(obj.presigned_url(:put))
>
> puts url
> https://your-bucket-name.s3.ap-northeast-1.amazonaws.com/tmp/test.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIxxxxxxxxxxxxxxx%2F20190117%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20190117T103740Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=3e6d8de19dca1079f43468a9b03d2a06b80a98f9dee7399431xxxxxxxxx
```
> tmp/test.mp4 は s3 の出力先
PUT Methodでファイル名を指定して投げるだけで s3 にアップできます。

```
$ curl -X PUT \
  'https://your-bucket-name.s3.ap-northeast-1.amazonaws.com/tmp/test.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIxxxxxxxxxxxxxxx%2F20190117%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20190117T103740Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=3e6d8de19dca1079f43468a9b03d2a06b80a98f9dee7399431xxxxxxxxx' \
  -F file=@/Users/demo/Desktop/orig.mp4
```

簡単ですね。
PUT 方式だと、最大5GBまでなので、もしそれ以上のファイルをあげる場合は、Multipart Upload を使う必要がより複雑です。

これらを決められたパスのURLを発行するAPIを渡す仕組みを提供し、アップロードしてもらえれば、
あとはこちらで Lambda でそのファイルを適切な場所に移動したり変換したり自由にできます。

以上、小ネタでした。
Oracle データベースインスタンスの削除

# 実行コマンド
dbca -deleteDatabase コマンドで削除する。

```
dbca -silent -deleteDatabase -sourceDB orcl -sid orcl -sysDBAUserName sys -sysDBAPassword <Password for sysDBAUserName user name>

$ dbca -help -deleteDatabase
        -deleteDatabase - Command to Delete a database.
                -sourceDB <Database unique name for RAC database or SID for Single Instance database>
                [-deRegisterEMCloudControl ]
                        -emUser <EM Admin username to add or modify targets>
                        -omsHost <EM management server host name>
                        -omsPort <EM management server port number>
                        [-emPassword <EM Admin user password>]
                [-forceArchiveLogDeletion <To delete archive logs of a database>]
                [-sid <Database system identifier>]
                [-sysDBAPassword <Password for sysDBAUserName user name>]
                [-sysDBAUserName <User name  with SYSDBA privileges>]
```

# 紛らわしい
dbca -deleteInstance コマンドはRACからノードを削除するものでデータベースの削除はできません。
styled-componentについて公式サイトのメモ

公式サイト
https://www.styled-components.com/


## Basics

### インストール
```
$ npm install --save styled-components
```

### 基本的な使い方
```javascript
const Title = styled.h1`
  font-size: 1.5em;
  color: #000;
`
const Wrapper = styled.section`
  padding: 4em;
  background: #fff;
`

render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
)
```

### propsでバリエーションを持たせることができる
propsの値によってスタイルに複数パターン持たせることができる

```javascript
const Button = styled.button`
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};
  ...
`

render(
  <div>
    <Button>Normal</Button>
    <Button primary>Primary</Button>
  </div>
)
```


### スタイルの継承
scssの@extendのような書き方ができる

```javascript
const Button = styled.button`
  color: #000;
  font-size: 1em;
  padding: 0.25em 1em;
  border: 2px solid #000;
  border-radius: 3px;
`
const AlertButton = styled(Button)`
  color: red;
  border-color: red;
`

render(
  <div>
    <Button>Normal Button</Button>
    <AlertButton>Alert Button</AlertButton>
  </div>
)
```

### HTMLのタグが変えられる
HTMLタグをbuttonとか決めてしまっていても、`as` を使えば変えられる！

```javascript
render(
  <div>
    <Button as="a" href="/">Link with Button styles</Button>
    <AlertButton as="a" href="/">Link</AlertButton>
  </div>
)
```

少ししか書いていない…！自分用メモなので、一旦ここで公開。。
このページを更新するようにして近々でAdvancedを書き連ねます！
MySQLで対象フィールドを連番で更新

よく忘れてしまうのでメモ。

```sql
-- ユーザー環境変数を設定
SET @increment=0; 
update
	tables
set
	-- ユーザー環境変数に1を加算して、更新したいフィールドにset
	tables.id = @increment:=@increment+1
-- 特定の並び順で更新したい場合、order byを設定する
-- order by
--   tables.sort
-- 頭からxxxx件だけ更新したい場合、limitを設定する
-- limit 1000
```


<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NR3DM2YWBD"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-NR3DM2YWBD');
</script>
【WordPress(4.9.8)】「セキュリティ上の理由によりこのファイル形式は許可されていません」エラーを解決する方法

# 記事の内容
WordPressで標準で許可されていないファイル（ZIP等）をアップロードする方法を説明します。

# 状況説明
メディアにファイルをアップロードする際、ファイルの種類によっては
***「セキュリティ上の理由によりこのファイル形式は許可されていません」***
エラーが表示され、アップロードが中断される。

## エラーが発生する原因
>WordPress 4.7.1 から追加された機能(セキュリティ対策)で、メディアアップロード時にMIMEタイプのチェックが行われるようになりました。
>これによって、今までアップロードできていたファイルが下記のエラーメッセージを表示して動作しなくなるケースがあるようです。

[[WordPress] メディアアップロード時に『このファイルタイプはセキュリティの観点から許可されていません。』](https://blog.dreamhive.co.jp/mkoba/?p=6176)

# 対策
1. 「disable-real-mime-check」プラグインを導入
2.  許可するMIMEタイプをWordPressに追加

## やったこと
1. 「disable-real-mime-check」プラグインを導入（mimeﾀｲﾌﾟのチェック機能を無効化）
[disable-real-mime-check](https://ja.wordpress.org/plugins/disable-real-mime-check/)
***設定方法***
「disable-real-mime-check」プラグインをインストール、有効化するだけで適用される。

# 補足
上記のやり方はすべてのファイルのアップロードを許可するものですが、セキュリティを考えれば、許可するMIMEタイプをWordPressに個別追加する方法がベターだと思います。
※筆者は[functions.php]に許可したいMIMEタイプを追加しても解決できなかったので、このやり方を採用しました。

# おわり
以上です。
Googleイメージ検索をGoogleChromeで、クリックせずに1ステップで使えるようにする

Googleイメージ検索をGoogleChromeで、クリックせずに1ステップで使えるようにする

# Setting

chrome://settings/searchEngines?search=engi

`https://www.google.co.jp/search?q=%s&source=lnms&tbm=isch` を入れる

![image](https://user-images.githubusercontent.com/13635059/51359209-0a6c3f80-1b0a-11e9-9c3d-ab0bb0eddf3e.png)

# How

アドレスバーでアットマーク押してタブキー

![image](https://user-images.githubusercontent.com/13635059/51359255-3edffb80-1b0a-11e9-9278-0d06eade9b84.png)

検索できる

![image](https://user-images.githubusercontent.com/13635059/51359257-42738280-1b0a-11e9-819c-369835013fd5.png)


---

https://twitter.com/YumaInaura

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

# こちらもいかが

[まだトラックパッドでChromeを操作しているの？ そろそろキーボードだけで操作しようぜ！！ Chromeを使い倒そう！！ - Qiita](https://qiita.com/dodonki1223/items/205a937c21030d1a511e#comment-5fb92ba47f0080bcf5a6)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【laravel】5.4 よく使いそうなバリデータ

```php
return Validator::make($data, [
    'email' => 'required|string|email|max:255|unique:users',
    'password' => 'required|string|min:6|confirmed',
]);
```
email は 必須|文字列形式|メールフォーマット|最大255文字|users テーブル内でユニーク
password は 必須|文字列形式|最小6文字|password_confirmationと同じ値

|バリデーション|説明||
|:--|:--|:--|
|numeric|数値|
|integer|整数値|&#x7c;integer&#x7c;min:1&#x7c;max:100&#x7c; 1≦整数≦100|
|digits:値|数値で値の桁数|
|alpha|英字のみ|
|alpha_dash|英字＋ダッシュ(-)＋下線(_)|
|alpha_num|英数字|
|regex:/^[!-~]+$/|半角英数記号|
|regex:/\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[a-zA-Z\d]+\z/|半角英小文字大文字数字をそれぞれ1種類以上含む|

##exists
```php
'email' => 'exists:users,email,account_id,1'
'email' => 'exists:users,email,deleted,NULL'
'email' => 'exists:users,email,deleted,NOT_NULL'
```
email が users.email に存在、かつ account_id = 1
email が users.email に存在、かつ deleted = NULL。
email が users.email に存在、かつ deleted != NULL。
##unique
```php
'email' => 'unique:users,email,' . $user->id
'email' => 'unique:users,email,' . $user->user_id . ',user_id'
'email' => 'unique:users,email,' . $user->id . ',id,deleted,0'
```
email が users.email 内でユニーク かつ id != $user->id。
email が users.email 内でユニーク かつ user_id != $user->user_id。
email が users.email 内でユニーク かつ id != $user->id かつ deleted = 0 
##日付
|バリデーション	|説明|
|:--|:--|
|date|strtotime を使って日付型かチェック|
|date_format|date_parse_from_format を使って日付型かチェック。date と併用不可|
|after:日付|指定日付より後であること 日付は strtotime で処理。例) tomorrow|
|after_or_equal:日付|指定日付以降であること|
|before:日付|指定日付より前であること|
|before_or_equal:日付|指定日付以前であること|
##全角カナのカスタムバリエーション
AppServiceProvider.php の boot() に書くだけが簡単?

```php:app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Validator;
    :
    public function boot()
    {
               :
        // カタカナチェック
        Validator::extend('katakana', function ($attribute, $value, $parameters, $validator) {
            $regex = '{^(
                 (\xe3\x82[\xa1-\xbf]) # カタカナ
                |(\xe3\x83[\x80-\xbe]) # カタカナ
            )+$}x';
            return (1 === preg_match($regex, $value, $match)) ? true : false;
        });
               :
    }
```
エラーメッセージも追加

```php:resources/lang/ja/validation.php
    :
    'katakana' => ':attributeは全角カタカナを入力してください。',
    :
```

参考：https://readouble.com/laravel/5.4/ja/validation.html
[- 目次 -](https://qiita.com/search?q=laravel+nekyo)
Apache2 と node を連携する。

AWSLinux, CentOS が対象。(Ubuntuは設定の方法が違います。）
設定ファイルを作成する。
--
```sh:/etc/httpd/conf.d/node.conf
Alias /node /var/www/node

<Location /node/>
  ProxyPass http://localhost:3000/
  ProxyPassReverse http://localhost:3000/
  Order deny,allow
  Deny from all
  Allow from all
</Location>
```
node を起動する。

```shell
$ node app.js
```
作成したらnodeサーバを再起動。

```shell
$ service httpd restart
```
これで サイトのURL/node/ で nodeサーバーが呼ばれるようになる。

----
# でも、実際はあまりよろしくない？
Apache と node 使ったサービスを一つのサーバーに無理やり押し込めるにはありだけど、
イベントループ方式の node と、スレッド方式の Apache ではあまり相性が良くない。
上の方式だと、来たら直接 node のビルトインサーバーに転送するだけなので、まあ良いけど、
できれば Docker などを使って、単体で起動しておいた方がいいかも。

nodeを永続的に実行する forever。
--
上記の方法で node を起動した場合、nodeサーバはフォアグラウンドで実行される。
nohup を使うと、正しく動かなかったりするので、forever を使ったりする。
foreverのインストールは、一旦ルートになって、以下のコマンドを実行する。

```shell
$ npm install -g forever
```
次にデーモンとしてスクリプトをバックグラウンドで実行する。

```shell
$ forever start app.js
```
foreverの詳しい使い方はヘルプを参照。

```shell
$ forever --help
```
go/task Taskfile TIPS

# dynamic variable concatenation

```yaml
# Taskfile.yml

version: '2'

vars:
  staticTopLevelVar: static
  dynamicTopLevelVar: '{{ .pfx }}:{{ .staticTopLevelVar }}'

.dynamic_vars: &dynamic_vars
  dynamicVar: '{{ .pfx }}:{{ .staticTopLevelVar }}'
  dynamicVarReferencesOtherDynamicVar: '{{ .dynamicVar }}:dynamicVarReferencesOtherDynamicVar'

tasks:
  echo:
    cmds:
      - echo '{{ .staticTopLevelVar }}'
      - echo '{{ .dynamicTopLevelVar }}'
      - echo '{{ .dynamicVar }}'
      - echo '{{ .dynamicVarReferencesOtherDynamicVar }}'
    vars:
      <<: *dynamic_vars
    silent: true
```

as you can see, you cannot concatenate top level vars.
you have to use task vars to concatenate predefined vars with argument vars.

```
task echo pfx=my-prefix
static
<no value>:static
my-prefix:static
my-prefix:static:dynamicVarReferencesOtherDynamicVar
```
Proxy内環境でWindows10にGoogle Cloud PlatformSDKを導入する手順

# 前提
* Windows10
* Proxy配下のLANでの環境セットアップが必要

# やりたいこと
Windows開発環境にGoogle Cloud PlatformSDK（gcloudコマンド）を導入したい．

# セットアップのハマりどころ
- [Google Cloud SDK のインストーラ](https://cloud.google.com/sdk/docs/quickstart-windows?hl=ja) を用いるのが一般的だと思いますが、Proxy環境下ではインストール中にクラッシュします（！）
    - `Download failed: HTTP/1.1 503 Service Unavailable` が出て、インストーラがハングして動かなくなります
    - そのため、[インストーラではなく非対話式の方法にてインストールする必要](https://cloud.google.com/sdk/downloads?hl=ja#versioned)があります
- Proxyの設定がgcloud initからうまく行かないが，環境変数を設定することで，コマンド自体は使えるようになる
- 予めインストールされていたPythonのバージョンによっては gcloudコマンドが実行できなくなる場合がある
     - Pythonプログラム内部でエラーが発生した場合にはPythonをアンインストールするなどすると動くようになる

# 導入方法
セットアップのハマりどころに書いてある理由のため、インストーラを利用せずセットアップする必要があリます。

* 1. [Windows 64 ビット（x86_64）、Python バンドル](https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-196.0.0-windows-x86_64-bundled-python.zip?authuser=1&hl=ja)をダウンロード
* 2. ダウンロードしたファイルをC:\Program Files に展開
* 3. 環境変数の追記と追加

```sh:環境変数追加手順
# ※GUIから設定する場合は、Windowsキーを押して，「env」と入力，「システム環境変数の編集」を押すことで変更しても良い
SETX /M PATH "%PATH%;C:\Program Files\google-cloud-sdk\bin;"
SETX HTTP_PROXY "http://yourproxy.domain.name:8000"
SETX HTTPS_PROXY "http://yourproxy.domain.name:8000"
```

* 4. コマンドプロントの再起動
   * システム環境変数を `SETX` で書き換えた場合、再起動しないと有効にならないため
* 5. gcloud auth login して任意のコマンドを実行

```sh:GCP認証
gcloud auth login
```

上記のコマンドを実行することで，ブラウザが立ち上がりますので，自分のアカウントでログインしていただき，許可を押してください．
すると，コマンドプロント画面に戻って任意のコマンドを利用することができるようになります．

* 6. 動作確認

認証が成功すると、バケットの一覧を取得したり、GCEインスタンスの一覧を取得することができます。

```sh:コマンド確認
$> gsutil ls -p <your-project-id>
gs://test-bucket/
(略)

$> gcloud compute instances list --project test-project
NAME                                               ZONE               MACHINE_TYPE               PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
gke-standard-cluster-1-default-pool-xxxxxxxx-xxxx  asia-northeast1-a  n1-standard-1                           10.xx.x.x    35.xxx.xx.xx     RUNNING
gke-standard-cluster-1-default-pool-xxxxxxxx-xxxx  asia-northeast1-a  n1-standard-1                           10.xx.x.x    35.xxx.xxx.xx    RUNNING
gke-standard-cluster-1-default-pool-xxxxxxxx-xxxx  asia-northeast1-a  n1-standard-1                           10.xx.x.x    35.xxx.xxx.xx    RUNNING
(略)
```
コマンドが動いていることがわかりますね．


#所感

* プロキシの設定をgcloud initで行おうとするとうまく行かないが，ログインすればgcloudの諸コマンドは問題なく実行することができた
   * コマンドがちゃんと動くのは気持ち良い！
* 環境構築難しい
【rails5】フォームに既存データを初期値として設定し、編集も出来るようにする方法

##フォームに既存データを初期値として設定し、編集も出来るようにする方法

fields_forを使う。

fields_forは、フォームに初期値を設定出来る。

①まず、テーブルにある既存データを配列で持ってきて、初期値にする。

fields_forの第一引数に配列(本記事の例ではshopsとする)を指定し、ブロック変数(本記事の例では仮に|ff|とする)に代入すると、|ff|はshops[:id]というデータを展開出来る。

第二引数にはモデル(本記事の例ではshopとする)を指定する。

コードにすると以下のようになる。

```
<%= fields_for "shops[]", shop do |ff| %>
```  

②ブロック変数|ff|を使って記述していく。

例えば、営業時間(open_hours)を初期値に設定したいとする。

かつ、フォームは「--:--」というような形にしたいので、time_fieldを使う。

上記をコードにすると以下のようになる。

```
<%= ff.time_field :open_hours %>
```

これでフォームに既存データを初期値として設定しながらも、編集も出来るようになります。

ご指摘、補足、アドバイス等あれば是非お願いいたしますm(__)m
Docker+MySQLで初期データ投入と永続化

#前提
Docker　18.09.1
MySQL 5.7

#初期データ投入
Dockerコンテナ起動時にもろもろの初期設定（設定、DB作成、データ投入）ができます

#永続化
Dockerコンテナを削除してしまっても、データを残すことができます

docker-compose.yml

```
mysql:
  build: mysql
  volumes:
    ## 永続化 ##
     - "./mysql/data:/var/lib/mysql"
    ## 初期データ投入 ##
     - "./mysql/init:/docker-entrypoint-initdb.d"
  ports:
    - "3306:3306"
```


docker-compose.yml
　　├  mysql/
　　　　├  dockerfile
　　　　　　├  data/
　　　　　　├  init/
　　　　　　　　├　　1_create_db.sql
　　　　　　　　├　　2_setting.sh
　　　　　　　　├　　3_insert_data.sql


data:永続化用のディレクトリ
init:は初期データ、設定ファイルを配置
1_create_db.sql　DDL
2_setting.sh　設定
3_insert_data.sql てすとでーた

$docker-compose up 
で起動すると、init配下のファイルたちがasciiコード順で実行され、もろもろが反映されます。

起動後にdata配下を確認して、、、ファイルができてれば成功です。
この状態でdocker container rm を行ってもデータは保持されます。
docker-compose.ymlを含むディレクトリをコピーすればDBの状態を再現可能です。
Oracle初心者が 誰かが作ったOracleDatabase にTRIGGERが仕込まれているか確認した備忘録

## Oracle TRIGGER とは
- Oracleにはトリガーという機能がある。MYSQLにもある。
- ある条件に合致した操作が行われた場合に、実行されるオブジェクト。
- 実際のシステムでトリガー使いすぎると、仕組みが複雑になる。
- TRIGGERとか何してるって資料ないし、嫌気が指しそう。

### とりあえず、念の為トリガーの作成基本構文
```
CREATE OR REPLACE TRIGGER トリガー名 
{BEFORE | AFTER | INSTEAD OF} {INSERT | UPDATE | DELETE}
 ON テーブル名 (FOR EACH ROW)
 
BEGIN
 処理を記述（PL/SQL）
END;
```
えー、なんとなくわかりますね。
次から確認に入ります～。

### １．Oracleにトリガーがあるか確認する。
```
''' SQL で確認ができる。へぇ。
SELECT * FROM USER_TRIGGERS;
[結果]
''' 色々出てきたので省略w
```
- **USER_TRIGGERS** だけで検索を行うと、ダラダラ～と内容がでてきてわかりにくかったため、項目別でSELECTしてみる。

```
''' 必要な項目だけ、確認する。
SELECT TRIGGER_NAME, TABLE_NAME, STATUS FROM USER_TRIGGERS;
[結果]
TRIGGER_NAME                   TABLE_NAME                     STATUS
------------------------------ ------------------------------ --------
TRM_XXX                        TM_XXX                          ENABLED
TRM_CCC                        TM_CCC                          ENABLED
TRM_AAA                        TM_AAA                          ENABLED
''' STATUS 列が `ENABLED` なら有効。`DISABLED ` なら無効。
''' つまり上記のトリガーは全て動いていることがわかる。
```

### 2.指定したトリガーのソースを確認する
- ソースを確認するのが一番で、何したいのかだいたい想像つく

```
SELECT TRIGGER_BODY FROM ALL_TRIGGERS WHERE TRIGGER_NAME = 'TRM_XXX';
[結果]
TRIGGER_BODY
--------------------------------------------------------------------------------
BEGIN
	:NEW.N_YMD := TO_NUMBER(TO_CHAR(SYSDATE, 'YYYYMMDD'));
END TRM_XXX
''' トリガーのソースを確認するには`ALL_TRIGGERS`を使い、
''' `TRIGGER_BODY ` でソースのみ確認ができる。
```

### 3.トリガーはいつ実行されるのか確認する。
```
''' `TRIGGER_TYPE` はトリガーを起動するタイミング
''' `TRIGGERING_EVENT` はトリガーを起動するデータベース・イベント
SELECT TRIGGER_NAME,  TRIGGER_TYPE, TRIGGERING_EVENT FROM USER_TRIGGERS;
[結果]
TRIGGER_NAME                   TRIGGER_TYPE     TRIGGERING_EVENT
------------------------------ ---------------- -----------------
TRM_XXX                        BEFORE EACH ROW  INSERT OR UPDATE
TRM_CCC                        BEFORE EACH ROW  INSERT OR UPDATE
TRM_AAA                        BEFORE EACH ROW  INSERT OR UPDATE
''' DBインサートとアップデート前に行うってことがわかった。
```

### 確認した結果。
- 2 と 3 を確認しただけで、何をしているかは想像ついた。
- 指定したDBをなにかしたら更新するタイミングでSYSDATEを入れるよ。というトリガーがたくさん仕込まれていることがわかった。
- うん。終了です。
QuickPick, InputBox, StatusBarを使ってTypeScriptでVSCodeExtensionを作る

## 作ったもの

![image.png](https://qiita-image-store.s3.amazonaws.com/0/84493/bc3a65e7-2c00-bc66-19b3-564c069d486c.png)

ソースコード：https://gitlab.com/transnano/vscode-icon-all

## 機能

ステータスバーに自分好みにアイコンとメッセージをカスタマイズし、表示できる。

## モチベーション

1. ステータスバーに余白があるので使いたい
2. VSCodeで使えるアイコンってどんなものがあるのだろう
3. 選択・入力コンポーネントを使ってみたい

これらの思いから今回の拡張機能を作るに至った。

### アイコン

VSCodeで使えるアイコンを公式から探そうとしたが見つからず、実際にアイコンを使っている拡張機能を探してから、その拡張機能のソースコードを漁ってどんなコードで表示しているのかをリバースエンジニアリング的なことで探した。

そうしていると[vs-code-icon-names.json](https://gist.github.com/alan-null/106609976afbfade4705c9ebff66def0)という素晴らしいまとめを見つけることができた。

### コンポーネント

アイコンのまとめが見つかったのでこれを利用し、全アイコンを選択コンポーネントで出すことができた。

``` typescript:extension.ts
function getItems(): vscode.QuickPickItem[] {
	const array: Array<vscode.QuickPickItem> = [];
	array.push({ label: '$(alert)', description: "alert" });
	array.push({ label: '$(arrow-down)', description: "arrow-down" });
...
	array.push({ label: '$(x)', description: "x" });
	array.push({ label: '$(zap)', description: "zap" });

	return array;
}
```

選択コンポーネントの表示例
![quickpick](https://gitlab.com/transnano/vscode-icon-all/raw/master/images/icons.png)

また、ステータスバーに表示するメッセージを受け付けるための入力コンポーネントも作った。
![inputbox](https://gitlab.com/transnano/vscode-icon-all/raw/master/images/message.png)

## まとめ

なんとなくうまいこと`QuickPick`, `InputBox`, `StatusBar`を使ってしかも[前回失敗](https://qiita.com/transnano/items/135b0e3ea6f6861c1117)したTypeScriptでの拡張機能開発を実現できた。

自分好みのステータスバーを構築できるが、まだ設定を保存する機能をつけていないので土日にでもやってみようと思う。
iOS版Safariで100vhがアドレスバーのせいではみ出る時の対処法

こんちは。見習いエンジニアの'めんた'です。

今回の私の[github](https://github.com/mojahirarin/vh-master)を片手にご覧ください。
一応MITライセンスです。

#これまでの100vh
私は画面ピッタリのシャレオツなSPAに憧れていた。
そんな時はbodyの高さを*100vh*で解決！
てことで、

```old-master.css
body{
    display: flex;
    flex-direction: column;

    /* これで上下ぴったりなシャレオツSPAになるはず… */
    min-height: 100vh;
}
```

としたのですが、iOS版Safariではアドレスバーや下部のUIのサイズが計算されないようで、フッター部分がはみ出る事件が発生…

[従来型サンプルページ](https://mojahirarin.github.io/vh-master/old_index.html)

JSで解決できると思い、調べてみたがjQueryを使ったものがほとんど。
宗教上の理由でjQueryは使えないので、素のJavascriptでの解決方法を模索。
なんとか解決したので、紹介します。

#改良型100vh
まず、完成品はこちら

[改良型サンプルページ](https://mojahirarin.github.io/vh-master/)

どうやら、Javascriptにてwindow.innerHeightを取り出したところ、正しい内側の高さを示してくれているよう…
ということは、bodyが読み込まれた後と、ブラウザのサイズが変更された（iOSの場合は、アドレスバーが表示/非表示になった）時に、window.innerHeightの値をbodyのcssに設定するだけ！

ということで、まずは**min-heightを消し…**

```vh-master.css
body{
    display: flex;
    flex-direction: column;

    /* コメントアウトして削除するよ！！ */
    /* min-height: 100vh; */
}
```

　 
**bodyの一番下に以下のscriptを埋め込み完成！**

```index.html
<body>
    <!-- いろいろページの本体… -->

    <!-- bodyの一番下に記述 -->
    <script>
        // body読み込み時に一度だけbodyサイズを設定
        document.body.onload = ()=>{
            document.body.style.minHeight = window.innerHeight + 'px';
        }

        // リサイズを停止して500ms後にbodyサイズを設定
        let timeoutId;
        window.addEventListener("resize", () => {
            clearTimeout(timeoutId);

            timeoutId = setTimeout(() => {
                document.body.style.minHeight = window.innerHeight + 'px';
            }, 500);
        });
    </script>
</body>
```

以上でシャレオツなSPAに一歩近づきました。
それ以前にデザインセンスが絶望的なのをどうにかせねば…


あ、何か問題があればすぐにご連絡ください。
gccでアセンブリ出力したときに.cfi_startprocなどが邪魔なので抑制する方法

gcc -Sでアセンブリを出力すると、`.cfi_startproc`,`.cfi_offset`などがごちゃごちゃと書かれていてコードが読みづらいです。

これらは "CFI directive"というもので、デバグ用の特殊なディレクティブらしいです。

 
hello worldをアセンブル。

```
$ gcc -S hello-world.c  -o hello-world.s
```

デフォルトだとこうなる。

```
	.file	"hello-world.c"
	.text
	.section	.rodata
.LC0:
	.string	"hello world"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	leaq	.LC0(%rip), %rdi
	call	puts@PLT
	movl	$0, %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 7.3.0-16ubuntu3) 7.3.0"
	.section	.note.GNU-stack,"",@progbits
```

# CFI directiveを無効にする方法

` -fno-asynchronous-unwind-tables` というオプションを付ければ無効にできます。

```
$ gcc  -fno-asynchronous-unwind-tables  -S hello-world.c -o hello-world.s
```

無効にした結果。
見やすい！

```
	.file	"hello-world.c"
	.text
	.section	.rodata
.LC0:
	.string	"hello world"
	.text
	.globl	main
	.type	main, @function
main:
	pushq	%rbp
	movq	%rsp, %rbp
	leaq	.LC0(%rip), %rdi
	call	puts@PLT
	movl	$0, %eax
	popq	%rbp
	ret
	.size	main, .-main
	.ident	"GCC: (Ubuntu 7.3.0-16ubuntu3) 7.3.0"
	.section	.note.GNU-stack,"",@progbits
```

参考: https://stackoverflow.com/questions/2529185/what-are-cfi-directives-in-gnu-assembler-gas-used-for