OmniAICreator/Qiita-1.07M huggingface dataset:
Oracleユーザーのパスワード期限切れ

# Oracleユーザーアカウントロック解除・パスワード変更方法

長くお付き合いをしている案件があると、開発環境用のDBも長期間にわたって使用することがしばしば…
そんなある日DB接続時にこんなエラーに遭遇しました。

```
ORA-28001:パスワードが期限切れです。
```

昨日までログインできたやんけ…、と思いつつ調べてみたところバージョンアップの影響でセキュリティが厳しくなってしまったようでした。

> ますます厳しくなっていくセキュリティですが、パスワードは180日で切れてしまいます。Oracle 11gから厳しくなりました。半年たつとそのユーザーはパスワードを変更しないと使えなくなってしまいます。

あるあるですね。
とりあえずDBに接続できないとアプリも起動できないので、ユーザーパスワードを新しいものに変えてまた使えるようにしてあげましょう。

※前提として「$ORACLE_HOME/bin」のディレクトリに移動するまたはパスを通しておくこと

1.sysdbaでログインする

```
sqlplus / as sysdba
```

2.ユーザーがロックされているので解除する

```sql
ALTER USER userName ACCOUNT UNLOCK;
```

3.新しいパスワードを設定する

```sql
ALTER USER userName IDENTIFIED BY "password";
```

こんな感じで解除・再設定ができるはずです。

ちなみにパスワードの有効期限は変更が可能のようですね。

参考：https://sql-oracle.com/?p=1534
　　　https://www.dbsheetclient.jp/blog/?p=716
[セミナー]2019/5/14 DATA DAY OUT 2019

こちらは2019/5/15にQiita:Teamに投稿した記事をリライトしたものです。

# DATA DAY OUT 2019
Tableau社主催のTableau導入各社の事例紹介やテクニカルセッションが実施されるセミナー
https://www.tableau.com/ja-jp/event/data-day-out-tokyo-20190514

AWS summitのTableau版みたいなものです。

こんな話を聞いてきたよーっていう軽い感じの共有です。

# データドリブンでフロント組織を強くする方法  - Sansan が挑戦した”実践的”アプローチ

SalesForceにデータは貯めていたけど分析できない
データの欠損、分断、汚れ

課題

- データの分散
- 打ち手につながらない
- 見た目の難しさ

当時データが活用されていなかった理由
- 結果とその過程のデータが散在し、因果がわからないことが活用につながらない原因

- Tableau化(1):メンバーの活動・結果一覧（ボトルネックの可視化・一覧化）
  - 各メンバーの活動履歴と結果が直感的にわかるように一覧化
    - メンバーの成功パターンや伸び代がすぐにわかる
- Tableau化(2):ABMダッシュボード（アプローチ方法・伸び代の可視化）
  - 顧客ごとにどの部署・役職と接点があるかリアルタイムで可視化
    - アプローチルートやおさえるべきキーマンが一目でわかる
- Tableau化(3):リアルタイム受注予測（AIの利用）
  - AIとも連携、過去の実績を踏まえ各案件ごとに受注予測

次のアクションがわかるようにダッシュボードを作成する
相手にこのレポートで何を伝えたいかわかるデザインにするということを大事に　

### 所感
- そんなに難しいことはやっていないが、きちんとポイントを抑えているなという印象をうけた


# 極める ー 組織で使うTableau ダッシュボードデザイン

**必要なのはセンスじゃなくて理論** 

- ダッシュボードとは
  - そもそもは自動車のやつ。これを見て判断して運転を行う

- 組織で使うべきダッシュボード
  - 見てすぐ判断ができ次の行動に移れるもの
  - 必要な情報に入れ替えることができるもの

“”"「見て」「すぐに」「判断できる」“”"
対象者が見て、目的が明確で、必要な情報がある
見やすく、パフォーマンス良く、必要な情報に集中できる
対象者と目的が明確ならダッシュボードの型は決まる

ダッシュボードの型

- Strategic（意思決定層）
    - KPI型
        - 一覧性を重視
        - 数字と補足情報の組み合わせ
        - 詳細な情報はない
        - 色は OK/NG 情報のみ
        - 操作はしない
    - トピック特化型
        - ある部門/タスク/プロジェクトの全貌が把握できる
        - 概要(KPI)とより詳細な情報の組み合わせ
        - 操作はほとんどしない
- Analytical（データアナリスト層）
    - QA型
        - 必要そうな情報をあらかじめ列挙
    - 自由探索型
        - ユーザー自身が操作して答えを得る
- Operational（意思決定層とデータアナリスト層の中間）
    - 横断型
        - 頻繁に更新される
        - 頻繁に確認する（ディスプレイ表示など）
        - ある期間内の全貌が確認できる
        - チーム/トピック間を比較する
        - 操作しない


型が決まったら必要なVizを決める
バッドプラクティス

- 「これまでの報告書にあったから」、XXチャートを作りたい
グッドプラクティス

- この指標の時間による変化を示したい
- 他の項目との比較をしたい
- 地域による偏りの有無を示したい

ビジュアライズの参考:Visual Vocabulary

- https://github.com/ft-interactive/chart-doctor/tree/master/visual-vocabulary
- https://public.tableau.com/ja-jp/s/gallery/visual-vocabulary

ダッシュボードにおける見易さ

- 可読性
    - テキスト（文字）
        - ダッシュボードの意図を的確に伝える手段
            - タイトル、判例
- 視認性
    - 配置（レイアウト）
        - 情報はただ並べればいいというわけではない
            - グリッド、レイアウトコンテナー、パティング
- 判読性
    - 色
        - 避けるべきは意味のない色使い
            - 色相、色の濃淡
            - どの色を使うべきか
                - 色の印象に合致するもの、（悩んだときのおすすめ）自社のロゴから選べば間違い無い
            - 何色使うべきか
                - 3~4色
            - 色に意味はないが、詳細は残したい場合
                - 不要な色は灰色に
パフォーマンスよく
デザイン観点からのパフォーマンス
- データの粒度/量
    - マークの数≒表示速度
        - マークの数＝クエリの結果の数
            - 最初の表示が最大のクエリ
            - マークの数が多くなるとCPU/メモリに負荷
            - そもそもどこを見るべきかがわからない
            - クロス集計/散布図/カスタムポリゴンには注意
- フィルターカード
    - 列挙型のフィルターは遅い
        - フィルターのメンバー数＝クエリの結果の数
            - 表示するだけでもクエリが流れる
            - とりわけ列挙型はすべての値を取得する
            - 「関連値のみ」は処理が長くなる
- 固定サイズ
    - 固定サイズでキャッシュ利用
        - ダッシュボードサイズを固定するとキャッシュが活用できる
            - サイズが自動だと都度描画される
必要な情報に注目させるために、視線を誘導させよ
- F字型orZ字型
- 理解速度=集計の粒度
    - 情報量が少なければ少ないほど理解が早い
    - 概要から詳細へ
        - 大きな数字（KPI）→概要→より詳細
ソート後のレコードの順番をSQLで取得する

こちらは2019/2/8にQiita:Teamに投稿した記事をリライトしたものです。

## やりたかったこと
ソート後のレコードの順番をSQLで取得する

## どうしたか

```sql
SELECT 
  (SELECT count(*) + 1 
    FROM article
    WHERE created_at > article.created_at
    ORDER BY created_at DESC) AS displayOrder
FROM article
WHERE article.id = :id
```

###  ちょっと解説
- 前提
    - 記事一覧は投稿日時(created_at)降順で並んでいる

1. 取得したい記事より後に投稿された記事の件数を取得する
2. `(1の件数)+ 1`で取得したい記事がcreated_at降順で並び替えた時の順番が取得できる


めちゃくちゃ単純な話でしたね。。。

EOF
スライド読むのがしんどい人のための「これから始めるVue.js / Nuxt.js」

こちらは2019/2/2にQiita:Teamに投稿したものをリライトした記事です。

## 背景
- 2019/1/31に「これから始めるVue.js / Nuxt.js」という技術セミナーに参加してきました。
    - スライド https://speakerdeck.com/asial_corp/20190131-2
- スライドが60枚程度あり、読むのしんどいなーって人がいると思ったので補足リンクを足しつつまとめようかなと。

## Vue.jsについて
- オープンソースのJavaScriptフレームワーク
    - [MVVM](https://qiita.com/shinkuFencer/items/f2651073fb71416b6cd7)を採用
        - Model: JavaScriptで定義されたデータやメソッドなど
        - View: 実際に描画する DOM
        - ViewModel: Model、Viewで変更されたデータを反映
- 人気の理由
    - 日本語対応したドキュメントが充実
    - HTML、JavaScript、CSSが分離しているため書きやすい
    - コンポーネント化できる
- 他のフレームワークとの比較
    - Angular
        - 多機能だが、TypeScriptなど学習コストが高い
    - React
        - ライブラリが豊富。[JSX](https://qiita.com/koba04/items/039b9c974df284766f64)の学習コストが高い
    - Vue.js
        - ライブラリが豊富。JavaScriptで書けるため、学習コストが低い
- .vueファイルを利用する
    - HTML、JavaScript、CSSを1ファイルに記載
-  Vue.jsの拡張
    -   [Vuex](https://qiita.com/komukomu_pudding/items/707bcb7b2c715997f5a7): 状態管理用のライブラリ
    -   [Vue Router](https://qiita.com/567000/items/d6a7c694a370dc92e774): SPAを作成するナビゲーションライブラリ
    -   [VeeValidate](https://qiita.com/youdie/items/417ed2df1bcb6a60001c): バリデーションライブラリ
    -   [Vue-Lazyload](https://www.kabanoki.net/2099): 遅延読み込みライブラリ
    -   [Vue-meta](https://github.com/nuxt/vue-meta): メタ情報管理ライブラリ

## Nuxt.jsについて
- Vue.jsベースのフレームワーク
    - 必要なライブラリが組み込まれている
        - Vue.js
        - Vuex
        - Vue Router
        - [Vue Server Render](https://ssr.vuejs.org/ja/)
        - Vue-meta
        - [Webpack](https://qiita.com/Shagamii/items/698a67bab0cd5eefcb4f)
        - Vue-loader
- 統一の記述ルールがある
- 3つのモードを選択できる
    - [SPA（シングルページアプリケーション）](https://greative.jp/page/guidebook-spa-about-spa/)
    - [SSR（サーバーサイドレンダリング）](https://medium.com/@sundaycrafts/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E4%BD%93%E9%A8%93%E3%82%92%E5%90%91%E4%B8%8A%E3%81%95%E3%81%9B%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0javascript-%E6%AD%B4%E5%8F%B2%E3%81%A8%E5%88%A9%E7%82%B9-df68cd7cd991)
    - Static Generate（静的ファイルの生成）
- [PWA](https://www.seohacks.net/basic/terms/pwa/)の導入が簡単

## コンポーネントについて
- Atomic Design
    - コンポーネント単位でUIを定義していくデザイン手法
        - Atoms（原子）
            - 最小要素
                - 配色、フォントの定義、ボタン、ラベルなど
        - Molecules（分子）
            - Atomsを組み合わせて作る要素
                - 検索フォーム、メニューなど
        - Organisms（有機体）
            - Atoms、Moleculesを組み合わせて作る要素
                - ヘッダー、フッターなど
        - Templates（テンプレート）
            - Atoms、Molecules、Organismsを組み合わせて作る要素
                - ページの枠組み
        - Pages（ページ）
            - Atoms、Molecules、Organisms、Pagesを組み合わせて作る要素
- [Storybook](https://qiita.com/masaakikunsan/items/dad8d84807918f3a43cb)
    - コンポーネント管理ライブラリ


あとはAWSの話になるので割愛。。。
Cake 2.xでトランザクションが効かなかった対応

バッチ

```php
$model = ClassRegistry::init('Model名');
foreach ($tmp as $key => $t) {
    $model->begin();
    if (!$this->TmpModel->testMethod($t)) continue;
    
    //省略saveを使った更新処理
    $model->commit();
}
```

この場合、continueで次の処理に行った場合、次の処理でコミットもできなくなる。
beginはcontinueの後に行う。

```php
$model = ClassRegistry::init('Model名');
foreach ($tmp as $key => $t) {
    if (!$this->TmpModel->testMethod($t)) continue;
    
    $model->begin();
    //省略saveを使った更新処理
    $model->commit();
}
```
特定の文字列を含むファイルが存在するディレクトリを削除する


次やるときに忘れてそうなのでメモ

# やりたいこと

以下のようなフォルダ構成で

```console
$ find | sort
a
a/b
a/b/c3
a/b/c3/ccc.txt
a/b/c1
a/b/c1/aaa.txt
a/b/c2
a/b/c2/bbb.txt
```

ファイルの内容がこんな感じの時

```console
$ cat a/b/c1/aaa.txt   
aiueo
$ cat a/b/c2/bbb.txt 
abc
$ cat a/b/c3/ccc.txt 
abcde
```

文字列`abc`を含んだファイル(`aaa.txt`,`ccc.txt`)を含むディレクトリを削除したい。
つまり`a/b/c3`と`a/b/c2`のディレクトリを削除したい。

# コマンド

ただのシェルのワンライナーです

```console
$ find ./a -type f | xargs grep abc -l | xargs -I{} dirname {} | xargs rm -rv
removed 'a/b/c3/ccc.txt'
removed directory 'a/b/c3'
removed 'a/b/c2/bbb.txt'
removed directory 'a/b/c2'
```

:grin: 

# ちなみに

[Scrapy](https://scrapy.org/) というクローラのフレームワークを使っているときに、エラーレスポンスのままキャッシュしてしまったので、200以外のキャッシュを削除したかったのがきっかけです

その場合は以下で削除できます

ステータスコードはキャッシュ用ディレクトリ内の`meta`ファイルに入っているので、そのファイルをgrepしました

```console
$ find .scrapy/ -name "meta" | xargs grep -v 200 -l | xargs -I{} dirname {} | xargs rm -rv
```

ただ、scrapyの場合は`HTTPCACHE_IGNORE_HTTP_CODES`という変数にキャッシュしないステータスコードを定義しておけばそもそもキャッシュしないでくれるので、本来はそっちを使いましょう。(今回初めて知った)

```settings.py
HTTPCACHE_IGNORE_HTTP_CODES = [400]
```
RailsのAPIモードでOAuth(Facebook)認証を使うときはSessionを有効にする必要がある

RailsAPIモードでFacebook認証を実装する場合、sessionを有効にする必要があります。
sessionを有効にしていなければ(OmniAuthを使っている場合)`OmniAuth::NoSessionError`が発生します。

現在のRailsアプリケーションに適応されているmiddlewareを確認してみましょう。

```
$ bundle exec rails middleware

use Rack::Cors
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Warden::Manager
use OmniAuth::Strategies::Facebook
run Backend::Application.routes
```

session等のmiddlewareは未適応ですので、session用のmiddlewareを追加します。

```ruby:config/application.rb
config.middleware.insert_after(ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies)
config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore)
```

`config.middleware.insert_after`とは、第一引数middlewareの後に第二引数middlewareを追加するメソッドです。
`ActionDispatch::Cookies`を`ActiveRecord::Migration::CheckPending`の後に挿入しているのは、[Railsの新規プロジェクトに追加されているミドルウェアの一覧](https://railsguides.jp/rails_on_rack.html#%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%81%AE%E5%86%85%E9%83%A8)を参考にしてデフォルトの順番に準拠したためです。

これで正常にfacebook認証が行われます。

### 参考

- https://codeday.me/jp/qa/20190321/444534.html
クリーンアーキテクチャでAPIを設計してみる

クリーンアーキテクチャを実際にAPI設計に適用する場合の構成を考えたのでまとめ。


# クリーンアーキテクチャ構成要素

<img width="781" alt="スクリーンショット 2019-09-05 9.56.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339557/fa2ecc63-e141-4002-6a03-a836b65f3582.png">


- 依存関係は常に一方向
	
## エンティティ
- コアロジックを記述
- 多くの場合データモデルが記述される。
- DBにデータを保存する場合、インターフェースの注入を行う。

## ユースケース
- アプリケーション固有のルールを構築する
- シーケンスを記述。ロジック依存の制御構文はユースケースに記述される

## インターフェースアダプター
- 外部との接続。入力を受付てユースケース関数に流す
- APIHandler、 DBManagerなど

## フレームワーク&ドライバ
- Router
- EntryPoint

参考:https://qiita.com/hirotakan/items/698c1f5773a3cca6193e

# goでAPIを書く場合のソースコード構成
- src
	- entity
		- ロジックを書く。
		- usecaseから受け取ったInterfaceを実行して処理する。
	- usecase
		- APIHandlerからRequest、Repostiry、Interfaceを受け取ってentityを呼び出す
		- シーケンスを記述する。シーケンスだけを書く
		- 使うInterFaceはユースケースに記載
	- Interface
		- APIInterface
			- 外部APIの呼び出し処理を記述
		- Repositry
			- データストアが持つデータを記述。
		- APIHandler
			- エンドポイントを書く
			- APIの入力とResponseを整理する
			- Driverを受け取って、usecaseを呼び出す
				- usecase が利用するRepositoryとAPIInterfaceをここで設定
			- 各InterFaceを紐づけする
	- driver
		- router.go
			- ルーティングを記述
			- 使うその他driverをすべてここで渡す
		- datastore.go
			- Datastoreのライブラリを記述
			- ここのインフラは別に何でも良い
                - redisやdbなどのアクセサー
                        - 必要ならこの辺にかいておく
	- main.go
		- driverを呼び出す。

# メリット
- 依存関係は常に一方向となるのでテストを書きやすい
    - DBやインフラ、API等のテストモジュールは使いまわしが効くので一度書けばテストが簡単
- DB等の機能と直接関わらないインフラ差替が比較的容易
    - GCPに乗せるからDatastoreを使おう、とか検証用に一旦sql使っとこう、みたいな差替が楽

# デメリット
- 依存性を一方向にするために依存性の注入をしているため、適当にかくと逆に読みづらいコードが出来上がる
    - 依存性の注入を行うインターフェースはデータインフラや外部API発行等になるので、利用するインターフェースを予めルール化しておけば解決するとはおもう
- ルーティングとシンプルなロジックで処理できる規模のAPIしか作らないなら冗長
ECMAとNode.js, importとrequireの違いって何ぞや


# はじめに

JavaScriptを含む、最近のフロントエンド界隈は日々新しい技術が出ています。
Webpack, Gulp, Vue, React, SCSS...

僕にはわからないことだらけです。

特に、ECMAScriptやNode.js。
そして、それらの中で使われるimport, requireの違いでだいぶ悩んでいました。

これらの違いをここらで自分なりにはっきりさせようと思います。

間違っている点や不明な点があれば、コメントいただけると幸いです！

# ECMAScriptとNode.jsの違いは？

ECMAScriptとNode.jsの違いは何でしょうか？

ECMAScriptは、JavaScriptの統一規格
Node.jsはサーバーサイドで実行するための環境

などを指し、違う概念になっています。

![IMG_0160.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/19cf61ba-be5b-0e75-94ec-2b671b700f2a.jpeg)


## ECMAScript

ECMAScriptは、Ecma Internationalという機関で統一化されたJavaScriptの標準規格です。

このような標準規格ができた理由は、各ブラウザの仕様がこれまで異なったということです。

Chrome, Safari, IE(う〜ん）などでは、それぞれ内部にJavaScriptを実行するためのエンジンが入っています。
このエンジンがJavaScriptをその場で読み込んで実行をしているわけです。

しかし、これまではどの文法をサポートするか？などが各エンジンがバラバラであったため、ECMAScriptという統一規格ができています。
これによって、JavaScriptの文法の発達が進んだため、ES2015, ES2017のように名前がついています。

## Node.js

Node.jsは、ブラウザのフロントエンドで実行されるJavaScriptを、サーバーサイドに持ってきてしまおう！　という実行環境やプロジェクト自体を指します。

npm, nodeという名前を聞くとよくQiitaで見ると思います。

Node.jsは、ブラウザでは実行されず、OS上のプロセス・アプリの一つとして実行されます。
ブラウザ向けではない、というのが大事な点だと思います。

# importとrequireの違いは？

importとrequireの違いは、ECMAScript(ブラウザ向け), Node.js(サーバーサイド向け）の違いに影響しています。

## import

importはECMAScriptで使用されている文法です。
importを使うことで、JavaScriptをモジュールとして使用でき、より直感的かつファイル構成をわかりやすくすることができます。

しかし、各ブラウザごとにimportが使える・使えないなどの文法の対応状況が異なるため、Webpackを噛まして、どんな環境でも使える生JSにする必要があります。

**ブラウザ**などの、ECMAScriptの文法ということが大切です。

## require

requireはNode.jsで使用されている文法です。
Node.js上で使用するだけならば、requireをWebpackで変換する必要はなく、requireのまま使うことができます。

Node.js上で使用される、ということが大切です。

# WebpackはNode.jsで、ブラウザ向けにコンパイルしていますが...

よく出る疑問として

「WebpackはNode.js上で webpackコマンドや、npm run buildで使って、ブラウザ用にコンパイルしているけどアレ何？」

というのがあります。

![IMG_0161.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/f02b7d85-286c-e6b9-74f4-943cd006310a.jpeg)


webpackはNode.js上で使用されるライブラリです。
しかし、最近のフロントエンド開発では、ブラウザ向けのJSの開発もWebpack上を使用します。
これは、JSを最小化したり、Vueを取り入れたりなど多くの恩恵があるからです。

しかし、実際に実行する環境はブラウザ上で、importが使えない場合があります。
よって、Node.jsでWebpackを動かして、ブラウザ用に変換する、というのが流れになっています。

Node.jsで実行するだけならrequireで書けば、webpackはいらないようです。
（あったほうが嬉しい気もします、まだ完璧な理解ではありません。）

webpackのtargetに'web', 'node'というのがあるのは、実行環境によって、Node.jsのライブラリ(fs, url)などが使える・使えないがあるため、指定する必要があり

「どちらで実行したいのか？」はきちんと意識する必要がありそうです。
Mac コマンドラインからできる便利な設定

以下を端末にコピー＆ペーストして設定をする．

```
#現在開いているフォルダのフルパスを表示
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true

#Finderを終了させる項目を表示
defaults write com.apple.Finder QuitMenuItem -bool true

#クイックルックで文字列を選択可能に
defaults write com.apple.finder QLEnableTextSelection -bool true

#印刷ダイアログを詳細表示で開く
defaults write -g PMPrintingExpandedStateForPrint -bool true

#ダイアログの"最近使ったフォルダ"数を増やす
defaults write -g NSNavRecentPlacesLimit -int 10

#ネットワークボリュームに.DS_Storeを作らない
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true

#Dockのフォルダ側に最近使ったアプリを表示
defaults write com.apple.dock persistent-others -array-add '{ "tile-data" = { "list-type" = 1; }; "tile-type" = "recents-tile"; }'

#アプリを隠したらDockアイコンを透過
defaults write com.apple.dock showhidden -bool true
```

# 参考にしたページ
[Macの隠された設定を変更する84個のハック集](http://tukaikta.blog135.fc2.com/blog-entry-251.html)
Linuxコマンドメモ

忘れがちなコマンド（随時更新）

* 自分のGIP確認
curl inet-ip.info

* OS確認
  - cat /etc/redhat-release（RHEL）
  - cat /proc/version（カーネル）

* フォルダごとコピー
  - cp -r 

* ファイル全件検索
  - `find / -name default.properties`

* gzのgrep。ただし"ids"が入っているのは含めない。  
`zgrep "/api/internal/company/v1/get_employee_id" access.log*gz | grep -v ids`
message.propertiesの実装メモ

* message.propertiesはsrc/main/resources直下におく
* UTF-8でよい
* message.propertiesの中身
* 
```
E0001 = DBエラーです。システム管理者にお問い合わせください。
E0002 = 内部エラーです
```



* コーディング例

```java
import java.util.Date;
import java.util.Properties;
～～～
// message.properties ファイル
final InputStream inputStream = cmnUtil.getClass().getClassLoader()
        .getResourceAsStream("message.properties");
　
// ファイルをロードする
Properties props = new Properties();
InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
props.load(reader);
　
// シンプルなメッセージ出力
System.out.println(props.getProperty("warn.1001"));
// 引数を与えてフォーマットしてメッセージ出力
System.out.println(MessageFormat.format(props.getProperty("warn.1002"),
 "8", "32"));
```
【Excel】画面項目に合わせてテキストオブジェクトを配置する

##概要
Excelで仕様書を作成している方々向けです。
仕様書作成時に、画面項目や帳票項目に番号を振る事がちょいちょいあると思います。
一個一個オブジェクトを編集するのが面倒だったので、マクロ化しました。

##コード
```vb:テキストオブジェクト作成.bas
Sub テキストオブジェクト作成()
    Const HEIGHT As Integer = 24
    Const DEFAULT_TEXTBOX_SIZE As Double = 20.5
    Const CHAR_WIDTH As Double = 7.5

    Dim rng
    Dim width

    For Each rng In Selection
        If rng.value <> "" Then
            width = DEFAULT_TEXTBOX_SIZE + (LenB(StrConv(rng.value, vbFromUnicode)) - 1) * CHAR_WIDTH
            activeSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, _
                          rng.left, rng.Top, width, HEIGHT).Select
            Selection.Characters.Text = rng.value
        End If
    Next
End Sub
```

##実行結果
実行前
![WS000007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340597/40f2ad26-5690-2c7c-9fb6-760fca9b98be.jpeg)

実行後
![WS000008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340597/8b9a9bb5-e310-9f8c-635f-31c72ec184fb.jpeg)

選択範囲のセルに文字が入力されている場合、オブジェクト化します。


##使用例
こんな感じでシートの背景に画面を設定すれば...
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340597/1860c8fa-fc7d-2ff6-58b6-6b2b001b6d64.jpeg)

画面の表示項目の位置にあわせてオブジェクトを作成できます。
![WS000010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340597/22b02dac-e115-974f-c540-b20f63b82085.jpeg)
常用Teratermマクロ


### 表示を変える

```
;; ピンク
strconcat msg ' /F='
strconcat msg 'honban.INI'

;; 紫
strconcat msg ' /F='
strconcat msg 'honban_fuse.INI'

;; 画面サイズをかえる
dispstr #$1b"[8;11;70t";サイズ
dispstr #$1B"[3;1940;180t";左1
dispstr #$1B"[3;1940;440t";左2
dispstr #$1B"[3;1940;700t";左3
dispstr #$1B"[3;1940;960t";左4
dispstr #$1B"[3;2540;180t";右1
dispstr #$1B"[3;2540;440t";右2
dispstr #$1B"[3;2540;700t";右3
dispstr #$1B"[3;2540;960t";右4
```
【PHP】CSVのインポートとエクスポート

使用頻度が高い気がするのでメモ。
SJIS-win(Excel) のファイルをインポートorエクスポートすることを想定。
csvの扱い難しい。

# Import

```php:import.php
function import(string $filePath): array
{
    setlocale(LC_ALL, 'ja_JP.UTF-8');

    $file = new \SplFileObject(
                    'php://filter/read=convert.iconv.cp932%2Futf-8/resource='.$filePath, 
                    'rd'
                 );
    $file->setFlags(
        \SplFileObject::READ_CSV |
        \SplFileObject::SKIP_EMPTY |
        \SplFileObject::READ_AHEAD |
        \SplFileObject::DROP_NEW_LINE
    );

    // 配列に変換
    $rows = [];
    foreach ($file as $i => $val) {
       $row = [];
       if ($i === 0) { // ヘッダーは読み込まない場合
           continue;
        }
        $row['foo'] = $val[0] ?? '';
        $row['bar'] = $val[1] ?? '';
            
        $rows[] = $row;
    }
    return $rows;
}


// アップロードしたファイルのテンポラリファイルを渡すこともできる。
import($_FILES['upfile']['tmp_name']);

```

# Export

```php:export.php
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=sample.csv');

$array = getArray();    // BDとかから取得

$file = new SplFileObject('php://output', 'w');

foreach($array as $row) {
  \mb_convert_variables('SJIS-win', 'UTF-8', $row);
  $file->fputcsv($row);
}

$file->fflush();


```
TypeScript: GuardedType<T> ─ ユーザー定義タイプガード関数の型を抽出するユーティリティ型

本稿では、TypeScriptにおいて、ユーザ定義タイプガード(user-defined type guard)関数の型を導出するテクニックを紹介する。

例えば、`(x: any) => x is Foo`のような関数の型が与えられたとき、`Foo`を導き出したい。

```ts
declare const isFoo: (x: any) => x is Foo
                                   // ^^^ この部分
```

## ユーザー定義タイプガード関数の型を抽出するユーティリティタイプ

Conditional Typesと`infer`の組み合わせ技のユーティリティタイプを作ると、簡単にユーザー定義タイプガード関数の型を取り出せる。

```ts
type GuardedType<T> = T extends (x: any) => x is (infer T) ? T : never
```

`GuardedType`を使ってみる。

```ts
type ExtractedFoo = GuardedType<typeof isFoo>
// type ExtractedFoo = Foo が導き出される
```

## 完全なコードサンプル

```ts
interface Foo {
    name: string
}

declare const isFoo: (x: any) => x is Foo

type GuardedType<T> = T extends (x: any) => x is (infer T) ? T : never

type ExtractedFoo = GuardedType<typeof isFoo>
// type ExtractedFoo = Foo が導き出される
```

TypeScript playgourndでのコンパイル結果:

<img width="566" alt="Screen_Shot_2019-09-05_at_9_16_07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/38bc81e5-4007-d5ab-c4a2-e100d9a3bfbd.png">

なお、このサンプルコードは[TypeScript playground](http://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChkHIhwC2EAXMgM5hSgDmuAvrrgCYQIA2cUKC6EDWTAqGdJQAUAD0pwQATwCUyALwA+ZNJFU0mVmAUAHFAHEArrw5sAKsYgAeG5tXIbyCNMgg2umXMUVDS0dZElQGGg3FQB+N2RKEAgAN2gDe2QAUS8oREg2cTVkCysIW3sHQxN0GB1xdVwgA)にて試せる。
【プログラミング学習】 言語別ロジック比較 part.3(条件分岐)

条件分岐のさわり。

## 3.条件分岐
### Ruby

```ruby:sample.rb
val = 1
flg = true

# int型やstring型
if val == 1
    puts "val = 1"
elsif val == 2
    puts "val = 2"
else 
    puts "val != (1,2)"
end

# boolean型
if flg
    puts "flg = true"
else
    puts "flg = false"
end

# int型やstring型は、変数名のみの記述で
# 0/0以外、null/not nullの判定が可能
if val
   puts "val != 0"
else 
   puts "val = 0"
end
```

```console
$ ruby sample.rb
val = 1
flg = true
val != 0
```

### Python3

```python:sample.py
val = 1
flg = True

# int型やstring型
if val == 1:
    print("val = 1")
elif val == 2:
    print("val = 2")
else:
    print("val != (1,2)")

# boolean型
if flg:
    print("flg = true")
else:
    print("flg = false")

# int型やstring型は、変数名のみの記述で
# 0/0以外、null/not nullの判定が可能
if val:
   print("val != 0")
else:
   print("val = 0")
```

```console
$ python3 sample.py
val = 1
flg = true
val != 0
```

### Swift

```swift:sample.swift
import Foundation
let val = 1
let flg = true

// int型やstring型
if (val == 1) {
    print("val = 1")
} else if (val == 2) {
    print("val = 2")
} else {
    print("val != (1,2)")
}

// boolean型
if (flg) {
    print("flg = true")
} else {
    print("flg = false")
}

// swiftではintやStringに値が入っているかは、
// ちゃんと条件式を書く必要がある。
if (val > 0) {
    print("val != 0")
} else {
    print("val = 0")
}
```

```
(playground)
val = 1
flg = true
val != 0
```

### Java
```java:sample.java
package sample;

public class Main {
    public static void main(String[] args) {
    	int val = 1;
    	boolean flg = true;

    	// int型やstring型
    	if (val == 1) {
    	    System.out.println("val = 1");
    	} else if (val == 2) {
    	    System.out.println("val = 2");
    	} else {
    	    System.out.println("val != (1,2)");
    	}

    	// boolean型
    	if (flg) {
    	    System.out.println("flg = true");
    	} else {
    	    System.out.println("flg = false");
    	}

    	// intやStringに値が入っているかは、
    	// ちゃんと条件式を書く必要がある。
    	if (val > 0) {
    	    System.out.println("val != 0");
    	} else {
    	    System.out.println("val = 0");
    	}
    }
}
```

```console
(eclipse console)
val = 1
flg = true
val != 0
```

### C＃
```c#:sample.cs
using System;
public class HelloWorld {
    static public void Main () {
    	int val = 1;
    	bool flg = true;

    	// int型やstring型
    	if (val == 1) {
    	    Console.WriteLine("val = 1");
    	} else if (val == 2) {
    	    Console.WriteLine("val = 2");
    	} else {
    	    Console.WriteLine("val != (1,2)");
    	}

    	// boolean型
    	if (flg) {
    	    Console.WriteLine("flg = true");
    	} else {
    	    Console.WriteLine("flg = false");
    	}

    	// intやStringに値が入っているかは、
    	// ちゃんと条件式を書く必要がある。
    	if (val > 0) {
    	    Console.WriteLine("val != 0");
    	} else {
    	    Console.WriteLine("val = 0");
    	}
    }
}
```

(手元の実行環境では'mono'を使って実行)

```terminal
$ mcs sample.cs
(コンパイル成功)
$ mono sample.exe
val = 1
flg = true
val != 0
```
JekyllをDokcer上で動かしてGitHub Pagesのローカル環境での確認を楽する

## はじめに

Jekyllを使うとmarkdownで書いたページをGitHub Pagesに公開できますが、
JekyllをDocker上で動かすとローカル環境が汚れない上に簡単にプレビューを確認できます。

## 利用するDocker image
公式の [jekyll/jekyll](https://hub.docker.com/r/jekyll/jekyll) を利用します。
リポジトリは [envygeeks/jekyll-docker](https://github.com/envygeeks/jekyll-docker)。
https://github.com/envygeeks/jekyll-docker/blob/master/repos/jekyll/opts.yml を見る限りはGitHub Pagesで利用するなら全部入りじゃなくて `pages` タグ指定で問題なさそう。

```bash
docker pull jekyll/jekyll:pages
```

## Jekyllイメージの使い方
要点としては、

- コンテナはポート4000が解放されているためコンテナ側は4000を指定する
  - `-p 4000:4000` (ホストの4000にポートフォワーディングする場合)
- コンテナ内のworkingディレクトリは `srv/jekyll` となっているのでそこをvolumeとしてマウントする
  - `--volume="$PWD:/srv/jekyll"`(ローカル側はカレントディレクトリをマウントする場合)

となるため、下記が基本形となります。

```bash
docker run --rm --volume="$PWD:/srv/jekyll" -it -p 4000:4000 jekyll/jekyll jekyll command
```


```bash
# 新しくページを生成する
docker run --rm --volume="$PWD:/srv/jekyll" -it -p 4000:4000 jekyll/jekyll jekyll new yourpage

# ページをビルドする
docker run --rm --volume="$PWD:/srv/jekyll" -it -p 4000:4000 jekyll/jekyll jekyll build

# ページを確認する
docker run --rm --volume="$PWD:/srv/jekyll" -it -p 4000:4000 jekyll/jekyll jekyll serve
```

詳しくは [リポジトリ](https://github.com/envygeeks/jekyll-docker) のREADMEとjekyllの`--help`オプションで。

```bash
docker run --rm -it jekyll/jekyll jekyll --help
```

## docker-composeでJekyllイメージを利用する

一度ページを生成した後は `serve --force_polling` で変更を捕捉して自動ビルドさせながら確認できるので、下記のようなdocker-compose.ymlを作成すれば `docker-compose up` するだけでローカル環境で簡単にプレビューできます。

### docker-compose.yml

```yaml
version: '3.7'
services:
  app:
    image: jekyll/jekyll:pages
    command: jekyll serve --force_polling
    volumes:
      - $PWD:/srv/jekyll
    ports:
      - 4000:4000
```

というわけで、簡単ペライチGitHub Pages作成用のDockerテンプレートを作成しました。
[shifumin/jekyll-docker](https://github.com/shifumin/jekyll-docker)

```zsh

git clone git@github.com:shifumin/jekyll-docker
cd jekyll-docker
docker-compose up
# index.md を編集する
```

`docker-comopose up` すれば自動ビルド検知が走るのであとはindex.mdを編集しながらリアルタイムで http://localhost:4000 で変更を確認できます。
`_config.yml` や `_layouts` の説明は省略しますが、ルートにある `index.md` を対象にビルドが走り `_site/index.html` が生成されそちらが http://localhost:4000 でプレビューされます。

```
.
(略)
├── _site
│   (略)
│   └── index.html
└── index.md
```

## 補足
### GitHub Pagesで公開
GitHub Pagesで公開するにはリポジトリにpush後に `リポジトリの Settings > GitHub Pages` のSourceを `master branch` に変更します。
しばらく待つと公開されます。

[![Image from Gyazo](https://i.gyazo.com/1dbdb4754449f06c9b0e7a7db3e029ef.png)](https://gyazo.com/1dbdb4754449f06c9b0e7a7db3e029ef)


```yaml
---
layout: default
title: Title
---
# Title
- hoge
- foo
```

みたいな雑なmarkdownを用意すると下記のようなGitHub Pagesとして公開されます(今回はリスト箇所に適当なスタイルを当てています)

[![Image from Gyazo](https://i.gyazo.com/9735822cb4cc686f4bd00c6c8ff56c91.png)](https://gyazo.com/9735822cb4cc686f4bd00c6c8ff56c91)

## 参考
- [docker-compose（dockerで十分）でGitHub Pagesローカル開発環境 - Qiita](https://qiita.com/mkgask/items/7578bb0f9c646dbb68d0)
- [JekyllをDocker上で動かして環境依存の問題から解放される - syonx](http://syonx.hatenablog.com/entry/2017/01/08/100000)
- [Jekyll を Docker でやる](https://jyane.jp/2016/02/03/jekyll.html)
#Ruby の rbenv で zshrc / bash_profile などに rbenv init を書いてもバージョンが反映されない

#When rbenv init is written in zshrc / bash_profile etc. in rbenv of Ruby, the version is not reflected


こんな順番で書いてたら、システムのrubyが使われているくせに、rbenvが使われているかの表示がされていた。

```
export PATH="$HOME/.rbenv/bin:$PATH" 
eval "$(rbenv init - zsh)"

 ...

export PATH="/usr/local/opt/ruby/bin:$PATH"
```

```
$ rbenv global 2.5.3
$ rbenv version
2.5.3 (set by /Users/yumainaura/.rbenv/version)
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

```

`export PATH="/usr/local/opt/ruby/bin:$PATH"` を消すことで解決した。

教訓、profile file は整理しよう。

---

[brew install rubyで入れたgemのPATHは/usr/local/opt/ruby/binになる - Qiita](https://qiita.com/suin/items/37911b25bd72d32b907e)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ブラウザキャッシュについて

ブラウザキャッシュについて、
ふんわり仕立てだったので調べてみました。

ウェブページを作る際に下記を記載しておけば、
ファイルキャッシュされないんだろうくらいにしか思ってなかったです。

▼HTTPボディのmetaタグに記載

```
<!-- キャッシュさせない //-->
<meta http-equiv="Pragma" content="no-store">
<!-- キャッシュさせない //-->
<meta http-equiv="Cache-Control" content="no-store">
<!-- キャッシュされたコンテンツの有効期限を即切れにする。 //-->
<meta http-equiv="Expires" content="0">
```

ただし、キャッシュを制御する方法は2タイプあるそうです。

###①HTTPヘッダーで制御する方法
　⇒RFC2616に記載あり
###②HTTPボディのMETAタグで制御する方法
　⇒ブラウザやProxyが独自で取り入れている仕様

よって、基本的には①が推奨されています。
②の場合は、ブラウザによっては機能しない場合があるそうです。（広くひろまっていますが）

#▼メモ
###http-equiv="Pragma" 
HTTP1.0プロトコルに対応
設定値no-cacheにすることで、キャッシュされない。

###http-equiv="Cache-Control"
HTTP1.1プロトコルに対応
設定値にno-cacheを設定すると、
コンテンツに変更がある場合は最新の情報を読み込むが、変更がない場合はキャッシュから読み込む。
設定値にno-storeを設定すると、キャッシュされない。
####注意
個人情報を含むページなどは、no-cacheではなく、no-storeを使用したほうが良いと思います。
画面の見え方ではなく、個人情報がキャッシュに残るというところに、注目すべき。

###http-equiv="Expires"
キャッシュの有効期限
設定値を0に設定すると、即有効期限切れにするため、キャッシュしていない状態とほぼ同等になる。
ただし、これに対応されていないブラウザも存在するため、確実なものではない。
unknownにはtypescript-json-validatorを使うべし。ファイナルアンサー！

#typescript-json-validatorとは
TypeScriptの型定義からJSON Schemaを作成し、それをもとに型チェックを行うライブラリです
https://www.npmjs.com/package/typescript-json-validator

#何がすごいのか？
TypeScriptの型定義はかなり強力で、TypeScriptに閉じた世界では型制約のある素敵な暮らしを送ることができます。

しかし、JSONファイルからの読み出しや、外部からのAPIコールなどで入力がunknownになった瞬間幸せな暮らしは崩れ去ります。JavaScript由来の型の弱さに涙しつつ型チェックを行わない限り、string型に仮に配列が入っていてもTypeScriptは何もしてくれてないのです。

typescript-json-validatorはこの状態を劇的に改善してくれます。型定義Hogeに対して、isHogeというJSON Schemaベースのバリデータを生成することができるため、下記のように安全なコードを書けるようになります。

ちなみに、型制約にマッチしない際に詳細付きで例外を投げることもできます。

```
if(isHoge(obj)){
// objはHoge型である保証があり、型制約が効く
}
else if(isFuga(obj)){
// objはFuga型である保証があり、型制約が効く
}

```

これだよ、皆が探し求めていたワンピースは、、、


## 例を追記

### 型を定義
実際には結構複雑な型定義にも対応しています。

```types/ExampleNumber.ts
type ExampleNumber = number

export default ExampleNumber
```

```types/ExampleString.ts
type ExampleString = string

export default ExampleString
```

```types/ExampleObject.ts
type ExampleObject = {
    text: string
}

export default ExampleObject
```

### バリデータは自動生成

```
yarn typescript-json-validator types/ExampleNumber.ts
yarn typescript-json-validator types/ExampleString.ts
yarn typescript-json-validator types/ExampleObject.ts
```

### あとはコードからバリデータを参照
is<型名>という関数がエキスポートされているので、それを使うと下記のようにコードを書けます。

```index.ts
import {isExampleNumber} from "./types/ExampleNumber.validator";
import {isExampleObject} from "./types/ExampleObject.validator";
import {isExampleString} from "./types/ExampleString.validator";

for (const obj of ["aaa", 123, {text: "hoge"}, {key: "fuga"}]) {
    if (isExampleString(obj)) {
        console.log(`${obj} isExampleString uppercase is ${obj.toUpperCase()}`)
    } else if (isExampleNumber(obj)) {
        console.log(`${obj} isExampleNumber`)
    } else if (isExampleObject(obj)) {
        console.log(`${JSON.stringify(obj)} isExampleObject key=${obj.key}`)
    } else {
        console.log(`${JSON.stringify(obj)} is unknown `)
    }
}
```

型バリデータを自分で書くのは昭和までだよね。
既存のVueプロジェクトにBootstrapを導入します

Bootstrapは、近年、WEBフレームワークとして人気急上昇していました。
Bootstrap自体は、JqueryとPopperに依存しているので、既存プロジェクトにBootstrapを導入する時には、まずJqueryとPopper.jsを導入することが必要になります。

#準備
Vueプロジェクトのフォルダに移動してJqueryとPopper.jsをインストルします。

```
npm install jquery --save-dev
npm install popper.js --save-dev
```
既存プロジェクトのwebpack.base.conf.jsの中に、JqueryとPopper.jsのプラグインを追加します。

```
const webpack = require('webpack')
```

```
//jqueryプラグインを追加
plugins: [
　new webpack.ProvidePlugin({
　$: "jquery",
　jQuery: "jquery",
  Popper: ['popper.js', 'default']
})],
```

既存プロジェクトのmain.jsの中に、Jqueryの引用を追加します。

```
import $ from 'jquery'
```



#Bootstrapの導入

```
npm install bootstrap --save-dev
```

main.jsの中に、Bootstrapをインポートします

```
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min'
```

#Bootstrap確認
既存Vueプロジェクトに、以下のファイルを作成してVueプロジェクトを起動して画面からBootstrapが正常に動いたかどうかを確認します。

```
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li>
        <a href="https://vuejs.org" target="_blank">Core Docs</a>
      </li>
      <li>
        <a href="https://forum.vuejs.org" target="_blank">Forum</a>
      </li>
      <li>
        <a href="https://chat.vuejs.org" target="_blank">Community Chat</a>
      </li>
      <li>
        <a href="https://twitter.com/vuejs" target="_blank">Twitter</a>
      </li>
      <br />
      <li>
        <a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a>
      </li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li>
        <a href="http://router.vuejs.org/" target="_blank">vue-router</a>
      </li>
      <li>
        <a href="http://vuex.vuejs.org/" target="_blank">vuex</a>
      </li>
      <li>
        <a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a>
      </li>
      <li>
        <a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a>
      </li>
    </ul>
    <div class="btn-group" role="group" aria-label="...">
      <button type="button" class="btn btn-default">Left</button>
      <button type="button" class="btn btn-default">Middle</button>
      <button type="button" class="btn btn-default">Right</button>
    </div>
    <div id="cc">cc</div>
  </div>
</template>

<script>
$(function() {
  alert('hello jquery!')
})
export default {
  name: 'hello',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```
結果画面
![スクリーンショット 2019-09-05 7.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/a25d9967-aa30-be51-6274-9a425d5f3e61.png)
【react hooks】useContextを使ってみた

# hooksのuseContextを使ってみる

めちゃ簡単なカウンター作ってみた。
https://codesandbox.io/s/condescending-turing-6gtgf

ソース

```js
import React, { useState, useContext, createContext, useCallback } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Counter = createContext();

function App() {
  const [count, setCount] = useState(0);
  const increment = useCallback(() => setCount(count + 1), [count]);
  const decrement = useCallback(() => {
    if (count > 0) setCount(count - 1);
  }, [count]);
  return (
    <div className="App">
      <Counter.Provider
        value={{
          count,
          increment,
          decrement
        }}
      >
        <Child />
      </Counter.Provider>
    </div>
  );
}

const Child = () => {
  const { count, increment, decrement } = useContext(Counter);
  return (
    <>
      {count}
      <button onClick={increment}>increment</button>
      <button onClick={decrement}>decrement</button>
    </>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```

これで簡単にバケツリレー回避できるんだね。
createContextについて全然知らなくてhooks触ってて気がついた。
これから使っていってみよう。
JSONを扱うjqコマンド

## jqとは？

JSONを確認したり加工したりできるコマンドラインツール

## 参考

[JSONデータをjqコマンドを使ってシュッと加工する](https://tadaken3.hatenablog.jp/entry/how-to-jq-command)

## インストール

Macの場合

```
brew install jq
```

## sample.json

```
{"items":[{"item_id":1,"name":"PlayStation 4","price":30000},{"item_id":2,"name":"HHKB","price":25000}]}
```

## JSONを全部表示

❯ jq . sample.json

```
{
  "items": [
    {
      "item_id": 1,
      "name": "PlayStation 4",
      "price": 30000
    },
    {
      "item_id": 2,
      "name": "HHKB",
      "price": 25000
    }
  ]
}
```

## JSONの中のlistの中身を全部表示

❯ jq .items sample.json

```
[
  {
    "item_id": 1,
    "name": "PlayStation 4",
    "price": 30000
  },
  {
    "item_id": 2,
    "name": "HHKB",
    "price": 25000
  }
]
```

## listの0番目の要素を表示

❯ jq .items[0] sample.json

```
{
  "item_id": 1,
  "name": "PlayStation 4",
  "price": 30000
}
```

## listの1番目の要素を表示

❯ jq .items[1] sample.json

```
{
  "item_id": 2,
  "name": "HHKB",
  "price": 25000
}
```

## 特定の要素を全部表示
❯  jq .items[].name sample.json

```
"PlayStation 4"
"HHKB"
```

## listの1つ目の特定の要素を表示

❯ jq .items[1].name sample.json

```
"HHKB"
```

## ☓条件で検索

❯ jq "select(.items[].price > 26000)" sample.json

```
{
  "items": [
    {
      "item_id": 1,
      "name": "PlayStation 4",
      "price": 30000
    },
    {
      "item_id": 2,
      "name": "HHKB",
      "price": 25000
    }
  ]
}
```

## ○条件で検索

❯ jq .items[] sample.json | jq "select(.price > 26000)"

```
{
  "item_id": 1,
  "name": "PlayStation 4",
  "price": 30000
}
```
composerのバージョンが変わっても対応可能なDockerfileの書き方

## 問題点
DockerでPHPの環境を構築するときに、Dockerfileにcomposerのインストールコマンドを記載することがあるが、
そのときにhttps://getcomposer.org/download/ に書いてあるインストールコマンドをコピペすると、

```Dockerfile
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
      && php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
      && php composer-setup.php \
      && php -r "unlink('composer-setup.php');"
```

最新バージョンのハッシュ値が変わった時、以下のようなエラーが出て怒られる。

```
Could not open input file: composer-setup.php
ERROR: Service 'php' failed to build: The command '/bin/sh -c php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"   && php -r "if (hash_file('SHA384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"   && php composer-setup.php   && php -r "unlink('composer-setup.php');"   && mv composer.phar /usr/local/bin/composer' returned a non-zero code: 1
```

## 解決策
#### 常に最新のバージョンを取得したい場合
```Dockerfile
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
      && php -r "if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('https://composer.github.io/installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
      && php composer-setup.php\
      && php -r "unlink('composer-setup.php');" \
      && mv composer.phar /usr/sbin/composer
```

#### 常に特定のバージョンを指定したい場合
一つのDockerfileをチームで共有し、共通のローカル環境で作業するために、バージョンを固定したい場合など……
`--version=1.8.3`の部分にインストールするバージョンを当てはめてください。

```Dockerfile
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
      && php -r "if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('https://composer.github.io/installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
      && php composer-setup.php --version=1.8.3 \
      && php -r "unlink('composer-setup.php');" \
      && mv composer.phar /usr/sbin/composer
```
Swift学習 on WSL

## swift on windows
- こんどswiftさわることになるっぽい
- さわってからだと業務秘密が云々とかなってはイヤなので
- 予習段階でひと記事つくっときます
- と、以前に（[Swift学習 on Docker for Windows](/kfjt/items/6a49d603aa497c2807a5)）書いたのですが
- 結局あのときさわらなかったので、今度こそ予習でひと記事

## まとめ
- wsl と vscode でOK
- 今回はコンソールプログラム的な
- 次回以降やること
  - シミュレータを探す

## vscode 準備
参考：https://code.visualstudio.com

- insider とかでなく普通に vscode 入れればOK
- wsl も有効にする
  - 何となく Ubuntu 16.04 がすき
  - 多分 1年以内に18.04 が好きになってると思う
- vscode 「Ctrl + Shift + P」 コマンド 「>Remote-WSL: New Window」
- vscode 「Ctrl + Shift + @」 ターミナル bash が開く

## bash on wsl
参考：https://swift.org/download/

- Swift 5.0.3 , August 30, 2019
- Ubuntu 16.04 on windows

```bash:ターミナル
sudo apt-get update
sudo apt-get install clang libicu-dev libpython2.7 libcurl3

wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift

wget https://swift.org/builds/swift-5.0.3-release/ubuntu1604/swift-5.0.3-RELEASE/swift-5.0.3-RELEASE-ubuntu16.04.tar.gz
wget https://swift.org/builds/swift-5.0.3-release/ubuntu1604/swift-5.0.3-RELEASE/swift-5.0.3-RELEASE-ubuntu16.04.tar.gz.sig

gpg --verify swift-5.0.3-RELEASE-ubuntu16.04.tar.gz.sig
tar xzf swift-5.0.3-RELEASE-ubuntu16.04.tar.gz

cd swift-5.0.3-RELEASE-ubuntu16.04.tar.gz
sudo chown -R root:root usr/
cd usr
sudo cp -fR ./* /usr/
sudo chmod a+r /usr/lib/swift/CoreFoundation/
```

## swift お試し

```bash:ターミナル
mkdir workspace
```

- 「Ctrl + K + O」 フォルダを開く 「workspace」
- 「Ctrl + N」 新しいファイルを作る 「Ctrl + Shift + S」 名前を付けて保存 「hello.swift」

```swift:hello.swift
print("Hello!")
```

- この時点で p を入力して インテリセンス が print を補完 してくれるので感動できる
- 続けて 単体実行

```bash:ターミナル
swift hello.swift
```

- さらにコンパイル実行

```bash:ターミナル
swiftc hello.swift
./hello
```

## swift プロジェクト お試し

```bash:ターミナル
mkdir HelloSwift
cd HelloSwift
swift package init --type executable
swift build
./.build/debug/HelloSwift
```

大分満足できた

## 次回以降やること
- シミュレータを探す、諦めきれない
- 実機はお下がり貰った、 iphone 6 ので ipa を itunes 経由でインストールできるるぽい
  - ipaが作れない
  - TravisCI か CircleCI で ipa 出来るかなぁ
  - CIサービス利用が、ビルドのためだけに、 Mac 買うよりは安そう

以上
React+TypeScript+styled-jsx 環境構築

create-react-appからstyled jsxを使えるようにする設定

- `create-react-app --typescript` する
- 設定をいじるhttps://qiita.com/Julia0709/items/dfce1eed86e82c484040
- gitにcommitしとく (次のejectをするため)
- npm run ejectする
- `npm install --save styled-jsx` 
- package.jsonに以下追記

```
"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      "styled-jsx/babel"
    ]
  }
```
- `npm install --save @types/styled-jsx`

＊途中でgit commitしないと怒られる
PHPとRubyの基本構文

現在 PHPとRubyを学習していますが類似している部分がとてもあります。
そのための自分用に作成しています。
間違えている可能性がありますので見つけた際はお手数ですが報告お願い致します。

# 条件分岐(if)

``` PHP.
/* if */
if (式) {
  // 式が真の場合の処理
}

/* if～else */
if (式) {
  // 式が真の場合の処理
}　else {
  // 式が偽の場合の処理
}

/* if～elseif */
if (条件式1) {
  // 式1が真の場合の処理
}　elseif (条件式2) {
  // 式1が偽かつ、条件式2が真の場合の処理
}
```

``` Ruby.
# if
if 式
  # 式が真の場合の処理
end

# if～else
if 式
  # 式が真の場合の処理
else
  # 式が偽の場合の処理
end

# if～elseif
if 条件式1
  # 式1が真の場合の処理
elsif 条件式2
  # 式1が偽かつ、条件式2が真の場合の処理
end
```
git pushで ! [rejected]        master -> master (non-fast-forward)が表示された際の対応方法の一例

エラー内容

```
$ git push
To　github.com:✖️✖️✖️✖️✖️✖️✖️✖️✖️.git
 ! [rejected]        master -> master (non-fast-forward)
以下省略
```

試してほしいこと

```
$ git remote show origin　　（リモート詳細情報の確認）

・悪い例
* remote origin
  Fetch URL: git@github.com:✖️✖️✖️✖️✖️✖️✖️✖️✖️.git
  Push  URL: git@github.com:✖️✖️✖️✖️✖️✖️✖️✖️✖️.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (up to date)

・良い例
* remote origin
  Fetch URL: git@github.com:✖️✖️✖️✖️✖️✖️✖️✖️✖️.git
  Push  URL: git@github.com:✖️✖️✖️✖️✖️✖️✖️✖️✖️.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

```
もし上記の悪い例と同じ状況であるならgit pullも出来ないと思います。
下記の追跡コマンドを実行してみてください、正しく設定されるはずです。
（現在のローカルブランチにorigin/masterを追跡させるというコマンドになります）

```
$ git push -u origin master
```
今回の根本的なエラー内容はローカルのブランチに対して、それに対応する
リモートのブランチをマージする設定が行われてなかったということですね。
Apacheで名前ベースでVirtualHostを振り分ける

# Apacheによる振り分けパターン
- IPアドレスベース
- ポート
- FQDN(ServerName)

3通りの振り分け方がある。
今回は、`FQDN(ServerName)`で検証します

# FQDNベースでVirtualHost
1つのIPアドレスに複数のFQDNを指定して、それぞれ異なるWebサーバを参照させるようにしたい。
Webブラウザが送信するhttpリクエストにHostヘッダが必要になるが、ほとんどのブラウザで対応している。

# 環境
- Amazon Linux 2
- httpd-2.4.39-1.amzn2.0.1.x86_64
- セキュリティグループ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/c56194af-2dda-00b7-5e21-7edafdd27784.png)


# 手順

## Apacheインストール
```sh

yum -y update
yum -y install httpd
systemctl start httpd
```
## それぞれのDocumentRootを作成
```sh
mkdir /var/www/web10 /var/www/web20 /var/www/web30
echo 'web10.vamdemicsystem.black name-base web-site.' > /var/www/web10/index.html
echo 'web20.vamdemicsystem.black name-base web-site.' > /var/www/web20/index.html
echo 'web30.vamdemicsystem.black name-base web-site.' > /var/www/web30/index.html
```

## httpd.confの最終行に追記
ipアドレスが1つしかなければ、`*`でOK。
複数あれば対応するIPアドレスを書く。

```/etc/httpd/conf/httpd.conf
# Add VirtualHost
NameVirtualHost *
<VirtualHost *:80>
        ServerName      web10.vamdemicsystem.black
        DocumentRoot    /var/www/web10
</VirtualHost>
<VirtualHost *:80>
        ServerName      web20.vamdemicsystem.black
        DocumentRoot    /var/www/web20
</VirtualHost>
<VirtualHost *:80>
        ServerName      web30.vamdemicsystem.black
        DocumentRoot    /var/www/web30
</VirtualHost>
```

## 設定読み込み
```sh
systemctl restart httpd
```

# 動作確認

## サーバ自身から

hostsにそれぞれのFQDNを書く

```/etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost6 localhost6.localdomain6

127.0.0.1   web10.vamdemicsystem.black
127.0.0.1   web20.vamdemicsystem.black
127.0.0.1   web30.vamdemicsystem.black
```

curlで確認すると、うまいこと振り分けられているよう。OK!
localhostはWeb10の扱いになるのはどうして？

```
[root@ip-172-31-38-89 ~]# curl http://web10.vamdemicsystem.black
web10.vamdemicsystem.black name-base web-site.
[root@ip-172-31-38-89 ~]# curl http://web20.vamdemicsystem.black
web20.vamdemicsystem.black name-base web-site.
[root@ip-172-31-38-89 ~]# curl http://web30.vamdemicsystem.black
web30.vamdemicsystem.black name-base web-site.
[root@ip-172-31-38-89 ~]# curl http://web40.vamdemicsystem.black
curl: (6) Could not resolve host: web40.vamdemicsystem.black
[root@ip-172-31-38-89 ~]# curl http://localhost
web10.vamdemicsystem.black name-base web-site.
[root@ip-172-31-38-89 ~]#
```

## 外部からも確認
DNSサーバに登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/77d1ca13-600b-a47a-003c-c2db6a4a59bc.png)

web10OK!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/05ab57b4-540d-fda8-f321-fbc89dff00a4.png)

web20OK!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/4690399d-a640-ef39-f287-894475e55168.png)

web30OK!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/cf1dd22f-e8b3-a7a4-0df2-f60c946da92c.png)
SDカード復旧 Raspberry Pi 3 B+

# 背景

息子（小２）が久しぶりに「ラズパイで遊ぶ！」と。久しぶりの起動なのでアップデートがたんまり。
で、アップデートを開始して放置。この作業自体になんの問題もないのだけど、致命的だったことが一つ。

それは、ラズパイをモバイルバッテリーで立ち上げてしまっていたこと。
で、ちょうど、OSを更新している時に電源が落ちたようで、ラズパイが起動しなくなりました。（ブート部は起動して、その後に固まるとのこと）

で、「フォーマットしてくれー。」と持ってきたので、Windowsパソコンに差し込んだら、なぜか32GBのSDなのに1.35GBしか認識されていない。
ドライブのラベルは`Recovery`になっている。他にも`boot`とか何のラベルも表示されないドライブとか。
そこらへんをクリックしてたら突然パソコンがクラッシュ。再起動後に同じようなことしてたら再びクラッシュ。。。
（後から考えると、ラズパイのbootパーティションも認識されていたので、これが悪さしたのかなと）

# 復旧

ドライブがたくさんあったので、まずは全部のパーティションを削除して、それで最後に統合＆フォーマットすればいいかなと考えました。（結果として成功）
ようするに以下の状態にすることを目指しました。

![](https://i.gyazo.com/6a12bc1219846d25abf7c2fefec59428.png)

## ディスクの管理を起動

![](https://i.gyazo.com/21cc9756981052120bc3d35bcfcfb5f8.png)

## 復旧したいSDの認識状況を確認して、全ボリュームを削除

![](https://i.gyazo.com/fe5fc02aa011978883820802b2777220.png)

全て削除した後は「未割り当て」という状態になります。

![](https://i.gyazo.com/9afd3c2274184b13e79963069adce237.png)

## ボリュームを作成（フォーマット含む）

![](https://i.gyazo.com/e55632fa4cebd2a4f8656122654ad474.png)

ラズパイで使うには"FAT32"を選択します。ついでにボリュームラベルも設定
![](https://i.gyazo.com/2213f44bd0f37505f0e55c57f7e68b16.png)

無事に終了。これでラズパイで使えるようになりました。

![](https://i.gyazo.com/6a12bc1219846d25abf7c2fefec59428.png)

[NOOBS](https://www.raspberrypi.org/downloads/noobs/)をダウンロードして、解凍して、SDに展開して、完了！！

![](https://i.gyazo.com/9f30b1194f269673c7fc515f1b52d5a2.png)
ActiveRecord::RecordNotUnique: RuntimeError: UNIQUE constraint failed: users.email のエラーを解決

## :worried:emailカラムのフィールドが一意でないよっていうエラー

`rails t` した際にタイトルのエラーが出ました。

```
ActiveRecord::RecordNotUnique: RuntimeError: UNIQUE constraint failed: users.email
```

下記コマンドでデータベースの値を確認してみるもemailは被っていませんでした。

```
$rails c
>>User.all
```

念の為、emailのフィールドを更新してみようとするもまたエラー。

```
$rails c

>>user=User.find(1)
>>user.email=aaaaaa@sample.email
>>user.save
ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked)
```

## :joy:解決策

下記の stack overflow にそれっぽい質問がありました。
`test/fixtures/users.yml`を確認しろってありますね。
[Rails Tutorial: SQLite3::ConstraintException: UNIQUE constraint failed: users.email](https://stackoverflow.com/questions/31095429/rails-tutorial-sqlite3constraintexception-unique-constraint-failed-users-em)

```ruby

one: {}
# column: value
#
two: {}
# column: value
```

私の場合は、deviseというgemを利用しているうちに、users.ymlが更新されてしまっていたようです。

これを削除して`rails t`でテスト成功しました！！
Railsでgenerator作り、テンプレートの中身を動的に変えたい時

# 環境
- Rails 6.0.0
- ruby 2.6.4

# はじめに
プライベートで作っていたやつで、generatorでファイルを作る時に、ファイルの中身とかファイル名を好きに変えたいなぁと思っていて、そういえば、deviseがそんな感じのことをやっていたのでコード見てみたら、該当の処理がそのまま使えそうだったのでやってみた

## ref
https://github.com/plataformatec/devise/blob/master/lib/generators/devise/controllers_generator.rb#L36-L37

#  generator作る

```rb
rails g generator sample_template
```

# クラス名などを変更したいテンプレートを作る

```rb
# lib/generators/sample/templates/hoge.rb
class <%= @hogehoge %>Controller
  def hoge; end
end
```

# generatorクラスに変更するような処理を入れる

```rb
# lib/generators/sample/sample_template_generator.rb
class SampleTemplateGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  def set_instances
    @hogehoge = name&.classify
  end

  def generate_file
    template "app/controllers/#{@hogehoge}_controller.rb",
             "#{@hogehoge}_controller.rb"
  end
end
```

# 実行する
うまく `app/controllers/change/change_controller.rb` に生成され、中身のクラス名が `ChangeController` に変わればOK

```rb
rails g sample_template change
```

# 注意点
なお、今回雑にsuperclassを `NamedBase` にして 引数を `name` で取得してみてるが、現場だとこのようなことをするとお叱りを受ける可能性が高い。というのも、deviseでは、Baseを継承して、引数にふさわしい命名を付けてUSAGEも正確にしているためだ。
なので、現場でこのコードを書くとPRは通らないので、参考程度のメモ書きだと思って下さい。