OmniAICreator/Qiita-1.07M huggingface dataset:
レスポンシブ対応　画像付きテーブル

HTML

```html:test.php
<div class="event_prize">
	<table class="event_prize-table">
		<tbody>
		<tr>
			<th>
				1位
			</th>
			<td class="prize-table-img">
				<img src="img/test_icon1.png" alt="アイコン１">
			</td>
			<td>
				テスト１
			</td>
		</tr>
		</tbody>
		<tbody>
		<tr>
			<th>
				2位
			</th>
			<td class="prize-table-img">
				<img src="img/test_icon2.png" alt="アイコン２">
			</td>
			<td>
				テスト２
			</td>
		</tr>
		</tbody>
		<tbody>
		<tr>
			<th>
				3位
			</th>
			<td class="prize-table-img">
				<img src="img/test_icon3.png" alt="アイコン３">
			</td>
			<td>
				テスト３
			</td>
		</tr>
		</tbody>
	</table>
</div>
```


SCSS

```scss:_test.scss
.event_prize {
    table.event_prize-table {
		width: 100%;
		max-width: 640px;
		margin: auto;
		border: 1px solid rgba(#c9c9c9, 1);

		tbody {
			border-bottom: 1px solid rgba(#c9c9c9, 1);

			th {
				display: block;
				padding: 5px;
				border-bottom: 1px solid rgba(#c9c9c9, 1);
				background: #353535;
				font-family:FOT-ロダンNTLG Pro EB;
				font-size: 16px;
				line-height: (20/16);
			}

			td {
				display: block;
				padding: 3px 10px 10px;
				font-size: 13px;
				line-height: (16/13);
				text-align: center;
			}

			td.special_icon {
				margin-top: -10px;
			}

			td.prize-table-img {
				padding: 10px 10px 0;

				img {
					width: 60px;
					height: 60px;
				}
			}
		}
	}
}

@media only screen and (min-width: 768px) {
  .event_prize {
		table.event_prize-table {
			tbody {
				th {
					display: table-cell;
					width: 25%;
					padding: 10px 10px;
					border-right: 1px solid rgba(#c9c9c9, 1);
					font-size: 18px;
					line-height: (22/18);
					vertical-align: middle;
				}

				td {
					display: table-cell;
					width: 60%;
					padding: 10px;
					font-size: 14px;
					line-height: (17/14);
					text-align: left;
				}

				td.special_icon {
					margin-top: 0;
				}

				td.prize-table-img {
					width: 10%;
					padding: 10px 0 10px 10px;
					text-align: center;

					img {
						width: 60px;
						height: 60px;
					}
				}
			}
		}
    }
}
```
abc 054 グラフ問題　

B
縦 N 行、横 N 列に画素が並んだ画像Aと、縦 M 行、横 M 列に画素が並んだテンプレート画像Bが与えられます。 
画素は画像を構成する最小単位であり、ここでは 1×1 の正方形とします。 
また、与えられる画像は全て2値画像であり、各画素の色は白と黒の2種類で表されます。 
入力において、全ての画素は文字で表されており、.は白色の画素、 # は黒色の画素に対応します。 
画像Aは N 個の文字列 A1,…,AN で表されます。 
文字列 Ai の j 文字目は、画像Aの上から i 番目、左から j 番目の画素に対応します。(1≦i,j≦N) 
同様に、テンプレート画像Bは M 個の文字列 B1,…,BM で表されます。 
文字列 Bi の j 文字目は、テンプレート画像Bの上から i 番目、左から j 番目の画素に対応します。(1≦i,j≦M) 
画像の平行移動のみ許されるとき、テンプレート画像Bが画像Aの中に含まれているかを判定してください。 

```
#include<iostream>
#include<string>
using namespace std;
int main() {
	int N, M;
        cin >> N >> M;
	char A[51][51], B[51][51];
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			cin >> A[i][j];
		}
	}

	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < M; ++j) {
			cin >> B[i][j];
		}
	}
	bool exist = false;
	for (int ly = 0; ly < N; ++ly) {
		for (int lx = 0; lx < N; ++lx) {
			if (ly + M - 1 >= N || lx + M - 1 >= N) {
				continue;
			}
			bool match = true;
			for (int y = 0; y < M; ++y) {
				for (int x = 0; x < M; ++x) {
					if (A[ly + y][lx + x] != B[y][x]) {
						match = false;
					}
				}
			}
			if (match) {
				exist = true;
			}
		}
	}
	if (exist)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
	return 0;
}
```

C
自己ループと二重辺を含まない N 頂点 M 辺の重み無し無向グラフが与えられます。
i(1≦i≦M) 番目の辺は頂点 ai と頂点 bi を結びます。 
ここで、自己ループは ai=bi(1≦i≦M) となる辺のことを表します。 
また、二重辺は ai=aj かつ bi=bj(1≦i<j≦M) となる辺のことを表します。 
頂点 1 を始点として、全ての頂点を1度だけ訪れるパスは何通りありますか。 
ただし、パスの始点と終点の頂点も訪れたものとみなします。 

```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<cstdio>
#include<iomanip>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using piii = pair<pii, pii>;
const int INF = 1e9 + 7;
vector<vector<bool>> path(10, vector<bool>(10, false));
//与えられたグラフの隣接行列
//path[a][b]=true<=>a-b間に辺がある
int N, M;
int ans = 0;
int vcount = 0;//いくつの頂点を訪れたかを記録する
vector<bool>visited(10, false);//各頂点に訪れたかを記録する

void dfs(int from) {
	visited[from] = true;
	vcount++;
	if (vcount == N) {
		ans++;
	}
	else {
		for(int i = 1; i <= N; ++i) {
			if (!visited[i] && path[from][i]) {
				dfs(i);
			}
		}
	}
	visited[from] = false;
	vcount--;
	return;
}

int main() {
	cin >> N >> M;
	for (int i = 0; i < M; ++i) {
		int a, b;
		cin >> a >> b;
		path[a][b] = path[b][a] = true;
	}
	dfs(1);
	cout << ans << endl;
    return 0;
}
```
再帰グラフ。
AWS IoTを使用したラズパイの死活監視の一例

死活監視はIoTの制御でよく実施される機能だと思いますが、AWS IoTではいくつかのアプローチがあるようです。
今回はconnectionトピックへ送信されるメッセージを使用した死活監視の一例を書き留めておきます。

## 環境
IoT機器：ラズパイ

ラズパイはAWSIoTPythonSDKのインストールと証明書ファイルの配置を行い、MQTT接続できる状態のものを想定。


## 通信状態の検知
まず、以下のようにAWSIoTPythonSDKのAWSIoTMQTTShadowClientを使用し、ラズパイとAWSIoTの間でコネクションを張ります。

```python
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient

...

# Connect to AWS IoT
myAWSIoTMQTTShadowClient.connect()
```

すると、AWSIoT側は接続を検知し、以下のトピックにメッセージを送信する仕様となっています。

```
# 対象のclientIdのIoT機器が接続、切断を実施した際にパブリッシュされるトピック
$aws/events/presence/connected/clientId
$aws/events/presence/disconnected/clientId
```

ここにパブリッシュされたメッセージは以下の構造で入ってきます。

```
{
    "clientId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "timestamp": 1460065214626,
    "eventType": "connected",
    "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
    "principalIdentifier": "000000000000/ABCDEFGHIJKLMNOPQRSTU:some-user/ABCDEFGHIJKLMNOPQRSTU:some-user"
}
```

このメッセージを死活監視情報とすることで監視を行います。


## IoT Roleを使用した他サービスとの連携

死活情報の取得場所が分かったので、AWSの他のサービスと連携して保存していきます。
AWS IoTではトピックに入ったメッセージをトリガーとして他のサービスを呼び出すことが可能です。
今回はLambdaを使用してラズパイのShadowに死活情報を保存していきます。
Lambda関数を予め作成した後IoT Roleから呼び出すことで保存します。


1. AWSIoTのコンソールからACT画面へ移動し、ルールの作成を開始。
2. ルールクエリステートメントを以下のように記述

![image.png](https://qiita-image-store.s3.amazonaws.com/0/134764/a5f9649c-9d7c-ae41-c205-822ace7e456a.png)

3.アクションの項目で`アクションの追加`を選択
4. 実行したいAWSサービスを選択、今回はLambdaを選択
ここでShadowへの書き込みを行うLambda関数を選択します。指定するLambda関数は下記に記載します。

## Shadowを書き換えるLambda関数の作成

Lambdaのコンソールへ移動します。
今回はPythonでboto3を使用し、Shadowに状態をレポートする処理を記述します。

```py
import boto3
import json

def lambda_handler(event, context):
    client = boto3.client('iot-data')
    connected_bool = 0
    if event['eventType'] == "connected":
        connected_bool = 1
    shadow = {"state":{'reported': {'connected': connected_bool}}}
    print(event)
    response = client.update_thing_shadow(
        thingName = event['clientId'],
        payload = json.dumps(shadow, ensure_ascii=False)
    )
    return
```

この関数を連携することでShadowに常にヘルスチェック情報を反映させることが可能になります。

ヘルスチェックの情報とShadowの状態は分けずにまとめた方が管理がしやすいと思いこのような構成にしました。
データベースへの保存などはこのShadowの内容をそのままDynamoDBへ保存すると良いと思います。
設計はテクニックよりも根拠を大事にしよう

# はじめに

みなさん設計してますよね？

渡された設計書の通りにプログラミングだけをしている場合は除いて、大抵の方は設計をしていると思う。しかし7年ちょっとの開発経験の中で、実際に設計ができている人と仕事をすることは **稀** であった。

設計ができていない人に共通するマズイ点は **オブジェクト指向などのテクニックに走る傾向がある** ように思う。実際に「C++で開発するんだからオブジェクト指向でやろう！」と話しているのを聞いたこともある。書店の設計コーナーにオブジェクト指向関連の書籍が並んでいるのを見て、「あー、こういった書籍で紹介されている技法を駆使してソフトウェアを作ることを設計というのね」と思ったのかもしれない。

変更に強いソフトを作るためにオブジェクト指向などのテクニックが役に立つ場面もあるが、それ以上に **しっかりとした設計根拠を持つこと** の方がはるかに重要である。

# 設計根拠とは

設計根拠とは **ある設計案を採用する決め手** のこと。そして設計をする際はプロジェクトメンバに **なぜそのような設計にするのかをきちんと説明できるよう** にすればオッケーというのが最近の私の考え。

言葉で説明されただけではピンとこないかもしれないので、少し例を挙げてみる。

## 例題（１）

例として [オブジェクト指向で作るFizzBuzz](https://qiita.com/takaaki4cards/items/23127bcda036229d653d) を見ると、簡単なFizzBuzz問題でも複数の設計があることがわかる。

- リスト1はオーソドックスな設計だと思う。「3または5で割り切れる場合はFizzBuzz, 3で割り切れる場合はFizz, ...., を出力する」というFizzBuzz問題の説明文がそのままコードになっていて理解しやすい。

- リスト2, 3はオブジェクト指向を使った設計になっている。FizzBuzz問題の説明文には出てこない、かつ、思いつかない戦略やファクトリという新たな概念が登場していて、リスト1と比べると理解し難い。

さて、どちらの案を採用したら良いのか？シンプルなリスト1か？オブジェクト指向を使っててカッコイイ感じになっているリスト2, 3か？

私ならリスト1の設計を採用する。というのもリスト1は **FizzBuzz問題の [メンタルモデル](http://www.logicalskill.co.jp/jwriting/mentalmodel.html) をそのまま表現していて理解しやすいから** である。

もしリスト2, 3の設計案を採用する場合は **プロジェクトメンバが納得できる、戦略やファクトリという新たな概念が必要な背景や理由** がなくてはならない。

## 例題（２）

Java向けHttpClientには様々なライブラリがある。Apache Commons HttpClientとかOkHttpとか。

どのライブラリを使うか決める際に **ググって最初に出てきた○○が良さそうだから〇〇にする** とか **以前参加していたプロジェクトで使用した経験がある（かつ、他のライブラリは使用経験がない）から〇〇にする** とかやりがちだが、 [JavaのHTTPクライアントはどれがいいのか？](https://qiita.com/alt_yamamoto/items/0d72276c80589493ceb4) で書かれているようなことを検討しなくてはいけない。

# まとめ

仕様を満たすソフトウェアを作る方法はたくさんある。様々ある方法から **プロジェクトメンバが納得できる根拠を持って一つの方法を決定すること** が設計ですべきことである。つまりオブジェクト指向などの小難しいテクニックを知らなくても設計はできる。
GAEを端的に説明

## GAEとは？
**GAE（Google App Engine）とは、Googleが提供するクラウドサービスの内のPaaSです。**

## そもそも...
- クラウドサービスって？
  - クラウドサービスは、従来ローカルコンピュータで利用していたデータやソフトウェアを、ネットワーク経由で利用できるようにしたサービスです。Googleが提供しているクラウドサービスは　Google Cloud Platform（GCP）です。

- PaaSって？
  - PaaS（Platform as a Service）はクラウドコンピューティングのうちの1つで、アプリケーションソフトが稼動するためのハードウェアやOSなどのプラットフォーム一式を、インターネット経由で提供するサービスです。

## GAE概要
GAE（Google App Engine）はアプリケーションの実行環境で、アプリケーションを作るのもメンテナンスするのも簡単で、トラフィックやデータストレージのニーズの増減にあわせてスケーリングするのも簡単で、開発者は単純にアプリケーションをアップロードすれば、実行できます。
GAE（Google App Engine）にはバージョニング管理が備わっていて、アプリの更新や切り戻しなどが簡単かつ安全に行えます。

- バージョニング管理
  - バージョニング管理は、Blue-Green Deploymentの手法の事です。

- Blue-Green Deploymentとは？
  - アプリケーションの更新をする場合、稼働中サーバーにデプロイをするのではなく、もう一つ同じ環境を新しく作成/デプロイして、その新しい環境に移行させる手法の事です。従来の環境をBlue、新規の環境をGreenとし、更新時にはそれぞれを切替えるのでBlue-Green Deploymentと言われている。切り替えた後に問題が発生した場合は切り戻すことも容易になります。

**参考：**

- [GAE](https://cloud.google.com/appengine/docs/whatisgoogleappengine?hl=ja)
- [クラウドサービス](http://www.soumu.go.jp/main_sosiki/joho_tsusin/security/basic/service/13.html)
- [PaaS](https://www.cloud-ace.jp/report/detail01/)
- [Blue-Green Deployment](https://www.nttpc.co.jp/yougo/Blue-Green%20Deployment.html)
Swift4.2でのMessageKit導入

MessageKitをSwift4.2の環境下で導入したい（MessageKit1.0）。
[GitHub - MessageKit/MessageKit: A community-driven replacement for JSQMessagesViewController](https://github.com/MessageKit/MessageKit)

しかし、CocoaPodsからインストールすると30個近いエラーが。。。

MessageKit1.1がリリースされれば改善されるらしいですが、一旦以下で無事に導入できました。

```html:Podfile
  # Pods for MessageKitTest
    pod 'MessageKit'

# 以下追加
post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == "MessageKit"
            target.build_configurations.each do |config|
                config.build_settings['SWIFT_VERSION'] = '4.0'
            end
        end 
    end
end  
```

参考
https://github.com/MessageKit/MessageKit/issues/878
Docker-composeでMySQLを含めたイメージをbuildしようとするとpermission deniedになってしまう

Docker composeでMySQLの/var/lib/mysqlを、DockerのContextに含まれるような場所にマウントしていると、
`docker-compose build`でpermission deniedエラーになってしまいます。

こんな感じ。

```yml:docker-compose.yml(抜粋)

    db:
        image: mysql:5.7
        volumes:
            - ./db/mysql:/var/lib/mysql
```

これは、マウントされたファイルたちの所有者が実行ユーザーと違うuidになっているためで、
一部ファイルのパーミッションが600だったりするために発生します。

なので、`.dockerignore`にそのマウント先ディレクトリを指定してやれば発生しなくなります。
上記の例では`db/mysql`を追加してやれば良いです。
そもそも、マウント先をDockerのcontextに含まれるようなところにするな、という話ではありますが…。
PHP 可変変数が使えない場合がある

# はじめに
　PHPには、可変変数という変数名を動的に指定できる機能があるのですが、これが使えない場合というやつに引っかかったのでメモしておきます。この投稿では、可変変数の説明を軽くしたあと、可変変数が使えない場合とそのサンプルについて言及することにします。

# 可変変数とは
　例を先に挙げてしまうと、以下のようなことができる機能です。

```php
$hoge = 'fuga';
$fuga = 'piyo';
echo $$hoge;    // => piyo
```
　```echo $$hoge;```は```echo ${$hoge};```と等価で、```{}```内が先に処理されて```echo ${'fuga'};```になり、```piyo```が出力されたと考えればわかりやすいでしょう。詳しい説明は公式ドキュメント[PHP: 可変変数 - Manual](https://secure.php.net/manual/ja/language.variables.variable.php)をご参照ください。

# 失敗したケース
　スーパーグローバルに対して一気に処理をしようと思って以下のようなコードを書きました。```// =>```は実行結果です。```var_dump($_SERVER);```をすると```Undefined variable```などのエラーが出るかと思ったのですが、なんと消したはずの```$_SERVER```が存在してしまっています。

```php
function UnsetSuperGlobals() {
    $super_globals = [
        '_SERVER',
        '_GET',
        '_POST',
        '_FILES',
        '_COOKIE',
        '_SESSION',
        '_REQUEST',
        '_ENV',
    ];
    foreach ($super_globals as $super_global) {
        unset($$super_global);
    }
}
UnsetSuperGlobals();
var_dump($_SERVER); // => いろいろ表示される
```
　```$_SERVER```はスーパーグローバルなので、関数内で消しても外で生きている、ということもなさそうだし、降参してドキュメントを見に行きました。

# ちゃんと書いてあった
> 警告
> 関数やクラスメソッドの内部で、可変変数と PHP の スーパーグローバル配列 とを組み合わせては使用できないということに注意してください。 $this も特別な変数であり、 動的に参照することはできません。

（[「PHP: 可変変数 - Manual」](https://secure.php.net/manual/ja/language.variables.variable.php)より）

　今回は「関数の内部で」、「可変変数とPHPのスーパーグローバルとを組み合わせ」たので、この警告に当てはまっております。

# 実験して確かめておく
　せっかくなので、ダメなケースを実際に確かめておくことにしました。スーパーグローバルの場合だけですが、以下のようなコードを書きました。

```php
$variable_name_global = '_SERVER';
var_dump($$variable_name_global); // => いろいろ出てくる

// 関数の場合
function sample_function() {
    $variable_name_local = '_SERVER';
    var_dump($$variable_name_local);
}
sample_function(); // => NULL

class SampleClass
{
    // クラスメソッドの場合
    public static function sample_class_method()
    {
        $variable_name_class = '_SERVER';
        var_dump($$variable_name_class);
    }
    // インスタンスメソッドの場合
    public function sample_instance_method()
    {
        $variable_name_instance = '_SERVER';
        var_dump($$variable_name_instance);
    }
}
SampleClass::sample_class_method(); // => NULL
(new SampleClass)->sample_instance_method(); // => NULL
```
　めでたく、可変変数が使えないことが確かめられました。

# おわりに
　最後まで読んでいただきありがとうございました。指摘やコメントなどは大歓迎なので教えていただけると幸いです。
　あと、可変変数って「Variable variable」って言うんですね。
もう一度言います、Hyperappは最高です。

どうも、あんはるです。
##Hyperappは最高です。

# Hyperappってなんですか

高速で1 KBという超軽量のフロントエンドのフレームワーク。
Elmアーキテクチャーに基づいている。
TypeScriptにも対応！
とてもシンプルなのですぐに理解することができ、使いやすい。
QiitaのフロントエンドにHyperappが採用されている。
[https://github.com/jorgebucaran/hyperapp](https://github.com/jorgebucaran/hyperapp)
## まずはこの画像を見て

![react on redux and hyperapp](https://cdn-images-1.medium.com/max/2000/1*kJYad9BLfAILYCUj5mMTkQ.png)

この画像を見て、Hyperappのシンプルさがわかるでしょう。
React + Reduxの場合は、Reduxのフローに従い、reducerを書いて、action書いて、propsに繋げて、、ととても面倒ですよね。
しかし、Hyperappでは、app関数state,actionsがviewに自動的に読み込まれよりシンプルになっています。

# Hyperappのいいところって何

## シンプルに書ける

reduxでは設定に時間を費やし、データフローを扱うためのコードを書く必要があります。

最近私がリリースしたサービス、[たぐまる tagmaru.me](http://tagmaru.me) では、React + Reduxが使われていますが、一つの機能を足すだけでも、とても面倒な作業でした。
次、開発するWebサービスではフロントエンドにHyperappを使用したいと思います。

しかし、Hyperappでは、その流れをシンプルにかけます。（最初の画像のように）
## 学習コストが低い

Hyperapp作者のJorge Bucaranさんは[2018 年は Hyperapp の年だ](https://qiita.com/JorgeBucaran/items/c48446babe0627e25ee6)でこう言っています。
>
プロジェクトのコードを 1 KB 程度でまとめられれば、JS のプログラマーなら 1、2 時間ですべてのコードを読める、仕組みを完全に理解できる。
オープンソースの世界ではソースはパブリックだからもちろん誰でも読めるけど、読めるのと「全部把握している」のはまた別だ。使いながらも、いつもブラックボックスの部分がある。でも 300行なら、バックヤードの全てを理解した上で使うことができる。それを実現したかった。

どうしても大きなプロジェクトになると、自分で全部理解することは難しいが、Hyperappは300行だから裏でどう動いてるか把握することができるそうです。

~~私はまだHyperappのコードを読んでないので分からないですがw~~
**追記2019/3/12**
Hyperappのコードを読みました、私が開発中のRubelmというフロントエンドフレームワークの実装の参考(VDom)になっています。

まあとにかくこのシンプルさは誰でも理解することができるでしょう。

## 副作用の扱いのアプローチ

Hyperappでは、副作用に使用される関数は値を返す必要がありません。

副作用によって、stateを更新するには別アクションを呼ぶことができます。

```js

const actions = {
  upLater: value => (state, actions) => {
    setTimeout(actions.up, 1000, value)
  },
  up: value => state => ({ count: state.count + value })
}
```
この方法では副作用を伴うのでテストするのが難しいです。

Hyperappでは副作用を扱う方法がもう一つあります。

### [@hyperapp/fx](https://github.com/okwolf/hyperapp-fx)を使う方法
です。

たとえばGETのリクエストを送るとき。

```js

import { withFx, http } from "hyperapp-fx"

const state = {
  // ...
}

const actions = {
  foo: () => http("/data", "dataFetched"),
  dataFetched: data => {
    // data will have the JSON-decoded response from /data
  }
}

withFx(app)(state, actions).foo()
```
http関数では、それが実行されたときに後で行う要求が入ったデータを返します。
 なので同じ引数の場合、常に同じデータが返されます。
つまり、http関数は純粋な関数なのです。テストも容易に行えます。




# 最後に
## もう一度言います、Hyperappは最高です。

参考

https://medium.com/hyperapp/hyperapp-for-redux-refugees-2507c9dd1ddc
https://qiita.com/JorgeBucaran/items/c48446babe0627e25ee6
ec-cube3の条件分岐ではまったこと

ec-cube3での商品一覧ページと各商品の一覧ページのタイトルタグを分けたかったが、見事にハマったので備忘録として残しとく。

各商品一覧ページのタイトルタグは、カテゴリIDによる条件分岐で普通に行けたのだが、


{% if Category.id == 18 %}&lt;title&gt;各商品一覧ページのタイトル名入ります。&lt;/title&gt;{% endif %}


カテゴリIDが存在しない商品一覧ページのタイトルタグまで出てきてしまい、各商品の一覧ページだけタイトルタグが二つ存在した。
これはSEO的にまずいんじゃないかということで、条件分岐の仕方を変更。


&lt;title&gt;
{% elseif Category.id == 17 %}
各商品一覧ページのタイトル名入ります。
{% elseif Category.id == 18 %}
各商品一覧ページのタイトル名入ります。
{% else %}
商品一覧ページのタイトル名入ります。
{% endif %}
&lt;/title&gt;


こうすることにより見事、各ページに一つずつタイトルタグがでるようになった。
TouchDesignerでリアルタイム番組を作る２【一眼カメラ映像の取り込み】

キリョウ[@_kiryo](https://twitter.com/_kiryo)です。


## できること
先日は、iphoneを使って映像をストリーミング配信する記事を書きました。
今回は、iPhoneより高画質な映像を配信できるよう一眼カメラをつかうことと、
Touchdesignerをかませつつ、YOUTUBE等にストリーミング配信する別の方法を考えてみました。

## 方法

①一眼から、PCにUSB接続
②[SparkoCam](http://sparkosoft.com/sparkocam)をインストールし、設定
③Video Device InでWebCamソースとして映像をロード
④performance modeもしくはviewなどでウインドウを分離
⑤[OBSStudio](https://obsproject.com/ja/download)をインストール・設定し、配信

###備考　SparkoCamについて

一眼をキャプチャする方法というと、BlackMagicなどのキャプチャボードを購入しつなぐ方法がありますが、
SparkoCamを利用すると、一眼の映像ソースをそのままWEBカメラの信号としてエンコードすることができます。

![きゃぷ.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/ec328e74-f869-78a2-6ac1-6d790e2a3ca4.png)

注意点として、ウォーターマークが結構でかいので、フルサイズとかじゃないとクロップしてもすごく面積狭いかもしれません。ウォーターマークをとるには7千円前後の金が要ります。ペイパル使えます。
また、現在対応している一眼は、NiconかCanonのようです。

また、そのままタッチに取り込むと、画像が荒れているので、OUTする解像度を右上のあたりにあるPreview Resolutionから選んでください。タッチがコマーシャル版ではない場合、最大1280*720辺りだったかと思います。

そしてこれ、画像よくみたらわかるのですが、Effectsからかなり色々なことを設定できます。
日本語のテキストを画像にのせることができるのですが、タッチだとunicodeに変換したりと面倒なので、リアルタイムにテロップを入れたい場合にはかなり便利です。その他、ISOとか色温度とかもソフトから操作して一眼に反映できます。

###備考　VideoDeviceIn Topについて

デフォルトだと、libraryがDirectShowになっているのですが、Media Foundationの方が高画質です。

![きゃぷ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/d61dd2b8-21e7-57c6-9ea7-4948e8ce3d32.png)
SparkoCamで入れたテキストも綺麗に表示されています。


###備考　OBSStudioについて
有名なストリーミング配信のフリーソフトです。
基本的な使いかたは[こちら](https://openrec.zendesk.com/hc/ja/articles/224706327)になります。

設定から、YOUTUBEやFACEBOOKLive、TWITTERライブが選べます。
また、WOWZAのようなストリーミングサーバーを持っている場合は、ストリームキーを設定できるので、GlobalIPを使えばアクセスできると思います（試してない）

TDのウインドウをキャプチャするには、ソースから＋ボタンを押して、ゲームキャプチャを選択します。
ウインドウキャプチャは何故かうまく映らなかった。。。
ゲームキャプチャを選択したら、モードの「特定のウインドウをキャプチャ」を選択し、ウインドウからTDのパフォーマンスモード等のウインドウを選択すれば、表示されます。
![キャプチeeeャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/156691/e0d75448-fd74-664b-4ae6-aba1626440a7.png)





よければ[ついったー](https://twitter.com/_kiryo)フォローおねがいします:v:





キリョウでした！
[備忘録]Railsとpumaとaurora serverlessの調整

## 問題

pumaでthreadを16、workerを4、それをインスタンス2台とかで立てるとする。
ActiveRecordのconnection poolはpumaのスレッド数に合わせて16とする。

負荷をかけると 16 * 4 * 2 = 128 のコネクションが発生する。

Aurora serverlessでキャパシティを2に設定したとき、デフォルトのパラメータグループで
max_connectionsは90

超えるとToo Many Connectionsが発生する。

キャパシティ4だとmax_connections 135。

## 解決
Appサーバーをオートスケールするか、
オートスケールがいらないとき（Aurora serverlessは普段休眠させておきたいケース。イベント本番のときだけ強くするとか。）は手動スケールしてpumaのthreadとworkerを調整する
うちの職場のMVCモデルがやばい

あくまで自分が経験をしたことないようなプロジェクトだったので書きます。

# そもそも何がやばいのか

- Struts2を使用しているが、そもそもビジネスロジックという概念が存在しない   
- アクションの中でDB問い合わせしてデータをこねこねしている
- JavaファイルにSQLがベタで書かれている
- JSPの画面項目表示、非表示のためにスクリプトレットが満載（JSPの中で変数の先頭一文字をスライスするとか）
- 当然のように詳細設計書は無い
    - というか要件定義書も無いし、DB周りのドキュメントも無いし、運用手順書すら無い（これだからBtoBは）
- UTとか影も形もない（とりあえずjUnitのjarをリポジトリに突っ込むのはやめなさい）

# これから何をすべきなのか

- ドキュメントの整備
    - 一人のスーパーハカーに頼るのは本当にやめてほしい

- ソースコードの整備
    - 少しでも見やすい形にする必要がある
    - ViewをViewとして使うようにしたい

- プロジェクトのREADME.mdを作る
    - いわゆるこのプロジェクトとはなんぞ。というものが欲しい。知っている人に聞かなければ分からないことが多すぎる。
16000行の壁を超えてさくっとダウンロードしたい (BigQueryの話)

Meguro.es #17 @ Drecom

2018年10月4日

---

## 自己紹介

ちきさん

GitHub/Twitter/Qiita: @ovrmrw 

市ヶ谷のオプトという会社で働いています

![3a2512bb-aa72-4515-af42-1f1721252f39.jpg](https://qiita-image-store.s3.amazonaws.com/0/74793/a418eb1e-ae08-f245-6107-9b95b90e7aa6.jpeg)

---

(話すこと)

BigQueryのクエリ結果がデカいときに簡単にローカルにダウンロードする方法

---

# BigQuery は Web UI で使いたいじゃないですか

---

## Web UI を使うメリット・デメリット

- メリット
    - クエリを書いてすぐに実行できるのでさくさく試せる。
    - クエリを保存する機能が便利。
    - エンジニアじゃなくても使える。例えばビジネスの人とか。

- デメリット
    - 16000行を超える結果を簡単にダウンロードできない。

---

## 16000行で切られてしまう選択肢

<img src="https://i.gyazo.com/d598684e3442c493148462a8ab91234a.png" width="100%" />

- JSON としてダウンロード
- CSV 形式でダウンロード
- スプレッドシートに保存

たとえクエリ結果が100万行でも勝手に切られてしまう。かなしい。

---

## かなしい例

<img src="https://i.gyazo.com/e17add7f2f89af0f7117988dfeded07b.png" width="100%" />

---

## ではどうすればいいのか

1. クエリ結果を別テーブルに保存
2. テーブルをCSVとしてGCSにエクスポート
3. GCSからダウンロード

---

## 何が問題なのか

- とてもめんどくさい
- 10パターンぐらいこの流れをやるとうんざりする
- テーブル作成やGCSのファイル作成権限を作業者に付与する必要がある

---

# BigQueryのリードオンリー権限のみでデカい結果をダウンロードしたい！

---

なので TypeScript で書いた

https://github.com/ovrmrw/bq-query-result-downloader

---

## 概要

---

`BigQuery` のインスタンスを生成する。

```ts
import * as BigQuery from '@google-cloud/bigquery';

const bigquery = new BigQuery();
```

---

`createQueryJob()` メソッドで Job を生成する。

```ts
  const job = await bigquery.createQueryJob(queryOption).then(data => {
    const [job, apiResponse] = data;
    return job;
  });
```

---

Job の `getQueryResults()` メソッドで結果を取得する。全件取得するまで繰り返す。

```ts
  let option = { location: 'US', maxResults: 5000 };
  const fileWriter = new FileWriter();

  do {
    const [rows, _option] = await job.getQueryResults(option);
    option = _option;
    rows.forEach(row => {
      fileWriter.writeRow(row); // 最終的にWriteStreamのwriteメソッドに渡している。
    });
  } while (option);
```

---

実行前に概算コストを表示するので思わぬ課金を防げるぞ

```
statistics: {
  "計算MB": 34.02571105957031,
  "計算GB": 0.03322823345661163,
  "キャッシュヒット": false,
  "コスト(円)": 0.01833393740525935
}

!! The query will be executed after 5 seconds...
```

---

## まとめ

- Web UI を使うとデカい結果をダウンロードするのはとてもめんどくさい。
- API を叩いてダウンロードしよう。
- ダウンロードは複数回に分けて、ファイルへの書き込みはストリームを使おう。
- ストリームと RxJS を組み合わせるととっても簡単だ。

---

## Thanks! :raised_hands:
Rubyの基本記述の仕方〜その7〜 クラスとインスタンス

## クラスとインスタンス

クラス　＝　設計図
インスタンス　＝　設計図に従って生成された実物

```ruby.qiita.rb
class Morikuma
end
```
クラスは書き方で定義できます。
ただし、
#### クラス名の最初は必ず大文字
で記述する必要があります。

## インスタンスの生成
定義したクラスに対して、インタンスを生成する際には、
#### 「クラス名」.new
の書き方で記述します。

```ruby.qiita.rb
kuma1 = Morikuma.new
```

## initializeメソッド

def initialize
〜〜
end

## インスタンス変数
インスタンス変数は＠を付けて表します。

```ruby.qiita.rb
class Morikuma
  def initialize # Morikuma.new したら呼ばれるメソッド
    @morikuma = "morikuma"
  end
  def puts_morikuma
    puts @morikuma
  end
end
```


## attr_accessorについて
```ruby.qiita.rb
class Morikuma
 attr_accessor :age
 attr_accessor :place
end
```

上記のようにクラスに対して変数で情報を付与することができます。


## initializeメソッド
initializeメソッドは、クラス定義の際に記述することで
インスタンスが生成された時にメソッドを呼び出すことなく、同時に処理してくれます。

```ruby.qiita.rb
class Morikuma
  def initialize
    @morikuma = kuma
  end
end
```
※上の例では、生成されたインスタンスを=kumaと上書きする謎処理になっておりますがあくまで書式の例として見ていただければ幸いです。

## initializeメソッドに引数を定義
initializeメソッドを定義する際に、引数を要求する形で記載することもできます。

```ruby.qiita.rb
class Morikuma
  def initialize(変数１,変数２・・・）
   なんかいい感じの処理
  end
end
```

ただし、引数を要求する形で定義した際には、「.new」を実行する際に引数とセットで呼び出す必要があります。

```ruby.qiita.rb
Morikuma.new(変数１）
```





## 所感
もろもろ、記事を書いていて自分の理解の浅さが特に苦しい内容でした。
このあたりはもっと実際のコードに触れて、クラス、インスタンス、initializeなどの言葉が指している概念をイメージでつかめるようになってから、再度より正しい内容に更新していきたいと思います。

今日はこのあたりで失礼します。

## 参考サイト
rubyにおけるクラスとインスタンスについて
https://qiita.com/you8/items/7312190ef83d0ed2ef9e

【Ruby】クラスメソッドとインスタンスメソッドについてザクッと分かりやすく説明してみる
https://qiita.com/amidara/items/27221675638cdc9bde6b

initializeメソッド
https://www.rubylife.jp/ini/class/index5.html
Storyblokのdocs翻訳チャレンジその20！！！

# データソースエントリの管理

## データソースエントリのリストを取得

### エンドポイント

```
GET /v1/spaces/:space_id/datasource_entries
```

### パラメータ

|名前|説明|
|:--|:--|
|page|現在のページ|
|per_page|ページ毎のアイテム数|
|datasource_id|データソースのID|

### リクエスト

クエリパラメータ

```
datasource_id=49
page=0
```

cURL

```
curl "https://api.storyblok.com/v1/spaces/581/datasource_entries?datasource_id=49&page=0" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDAsInRpbWVzdGFtcCI6MTUzODk4MjQ2N30.hYPMCILprn3MwWTWCXGsuGmJ_zmktFKEv2XBqmGrpV4" \
```

### レスポンス

ボディ

```json
{
  "datasource_entries": [
    {
      "id": 25,
      "name": "key",
      "value": "Value",
      "dimension_value": ""
    }
  ]
}
```

## データソースエントリを取得

### エンドポイント

```
GET /v1/spaces/:space_id/datasource_entries/:id
```

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/580/datasource_entries/24" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo3OTksInRpbWVzdGFtcCI6MTUzODk4MjQ2N30.a8kToytghWJU9ymhUvXLebpo7cuhuMuXBSTGIpP55WI" \
```

### レスポンス

ボディ

```json
{
  "datasource_entry": {
    "id": 24,
    "name": "key",
    "value": "Value",
    "dimension_value": null
  }
}
```

## データソースエントリを作成

### エンドポイント

```
POST /v1/spaces/:space_id/datasource_entries
```

### パラメータ

|名前|説明|
|:--|:--|
|datasource_entry\[name](必須)|名前|
|datasource_entry\[value](必須)|エントリ|

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/582/datasource_entries" -d '{"datasource_entry":{"name":"key","value":"value"}}' -X POST \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDEsInRpbWVzdGFtcCI6MTUzODk4MjQ2N30.mabCkXFtJDGHU3B79QJBAK-B0Knl_yXFGwS9rDNdAw4" \
```

### レスポンス

ボディ

```json
{
  "datasource_entry": {
    "id": 26,
    "name": "key",
    "value": "value",
    "dimension_value": null
  }
}
```

## データソースエントリの更新

### エンドポイント

```
PUT /v1/spaces/:space_id/datasource_entries/:id
```

### パラメータ

|名前|説明|
|:--|:--|
|datasource_entry\[name](必須)|データソースエントリの名前|
|datasource_entry\[value](必須)|エントリ|

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/583/datasource_entries/27" -d '{"datasource_entry":{"name":"key","value":"value"}}' -X PUT \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDIsInRpbWVzdGFtcCI6MTUzODk4MjQ2N30.Z5_5pBTxHXni0Hyoy1EfFJWU1x1Rkp98LAADqEsSEWw" \
```

### レスポンス

ボディ

```
```

## データソースエントリの削除

### エンドポイント

```
DELETE /v1/spaces/:space_id/datasource_entries/:id
```

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/584/datasource_entries/28" -d '' -X DELETE \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDMsInRpbWVzdGFtcCI6MTUzODk4MjQ2N30.szkN-hWAVgEjmxaDWo02XcXtrtMNDYqVVSQiuiB60Xo" \
```

### レスポンス

ボディ

```
```
FlatListでonEndReachedを使うときの罠

# 結論
onEndReachedを利用するFlatListがある画面に遷移する場合は、必ず遷移前にストアのリストデータをクリアすること

# クリアしないとどうなるか？
LINEのようなメッセージアプリを想像してください。
トーク一覧画面　→　トーク詳細画面　という構造になります。
トーク詳細画面のメッセージがFlatListで作られているという想定です。
<pre>
&lt;FlatList
  data={ストアのメッセージ}
  inverted
  onEndReached={次のメッセージ10件を取得するコールバック}
  onEndReachedThreshold={0}
  ...
/&gt;
</pre>

* トーク詳細画面に遷移したときに、直前に見たトーク詳細画面のメッセージが一瞬見える
* その後、遷移先のメッセージが取得され、上書きされる（A）
* ただし、一瞬見える前のメッセージが画面内に収まるほど短い場合、onEndReachedが働く（B）

onEndReachedに次のメッセージを取得するコールバックを仕込んでいると、

1. 一瞬だけ直前に見たトークAのメッセージが見え、  
1. 正しいメッセージが取得されて表示されたあと、  
1. 一瞬見えたトークAのメッセージのonEndReachedのコールバックが働き、
1. トークAのメッセージの次のメッセージが表示されてしまう


# 初投稿！
同じ現象に悩んでいる人に届くといいな

他にうまい方法あったらぜひ使いたいので、react-native玄人の方のアドバイスもお待ちしてます！
Storyblokのdocs翻訳チャレンジその19！！！

# データソースの管理

## 全てのデータソースを取得

### エンドポイント

```
GET /v1/spaces/:space_id/datasources
```

### パラメータ

|名前|説明|
|:--|:--|
|search(必須)| 検索語句 |

### リクエスト

クエリパラメータ

```
search=1r7qKwEvG
```

cURL

```
curl "https://api.storyblok.com/v1/spaces/587/datasources?search=1r7qKwEvG" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDYsInRpbWVzdGFtcCI6MTUzODk4MjQ2OH0.GxVRByNegf3ck4PWttaab9B8T5zki6sAzz0OB9Mb5z0" \
```

### レスポンス

ボディ

```json
{
  "datasources": [
    {
      "id": 56,
      "name": "1r7qKwEvG",
      "slug": "LjUzJo48N",
      "dimensions": [

      ]
    }
  ]
}
```

## データソース単位で取得

### エンドポイント

```
GET /v1/spaces/:space_id/datasources/:id
```

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/588/datasources/58" -X GET \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDcsInRpbWVzdGFtcCI6MTUzODk4MjQ2OH0.CGJF0A9Q_ZjaeZ-vqY3Pkp0SsaA6HWTKBv2_x_TmbvM" \
```

### レスポンス

ボディ

```json
{
  "datasource": {
    "id": 58,
    "name": "QjEsJd6cM",
    "slug": "B93xCuHiO",
    "dimensions": [

    ]
  }
}
```

## データソースの作成

### エンドポイント

```
POST /v1/spaces/:space_id/datasources
```

### パラメータ

|名前|説明|
|:--|:--|
|datasource\[name](必須)|データソースの名前|
|datasource\[slug](必須)|データソースのslug|

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/585/datasources" -d '{"datasource":{"name":"My Datasource","slug":"mydatasource"}}' -X POST \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDQsInRpbWVzdGFtcCI6MTUzODk4MjQ2OH0.gSYW0RjbCzFDXs1tcqB7z7v37RMfnP3XBVb6Q_B29tg" \
```

### レスポンス

ボディ

```json
{
  "datasource": {
    "id": 53,
    "name": "My Datasource",
    "slug": "mydatasource",
    "dimensions": [

    ]
  }
}
```

## データソースのアップデート

### エンドポイント

```
PUT /v1/spaces/:space_id/datasources/:id
```

### パラメータ

|名前|説明|
|:--|:--|
|datasource\[name](必須)|データソースの名前|
|datasource\[slug](必須)|データソースのslug|

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/586/datasources/55" -d '{"datasource":{"name":"My Datasource","slug":"mydatasource1"}}' -X PUT \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDUsInRpbWVzdGFtcCI6MTUzODk4MjQ2OH0.uA9LbHx5_126ySQ0hl9yIawP8OQFjm56fI97jA9AgFA" \
```

### レスポンス

ボディ

```json
{
  "datasource": {
    "id": 55,
    "name": "My Datasource",
    "slug": "mydatasource1",
    "dimensions": [

    ]
  }
}
```

## データソースの削除

### エンドポイント

```
DELETE /v1/spaces/:space_id/datasources/:id
```

### リクエスト

cURL

```
curl "https://api.storyblok.com/v1/spaces/589/datasources/60" -d '' -X DELETE \
	-H "Accept: application/json" \
	-H "Content-Type: application/json"
	-H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo4MDgsInRpbWVzdGFtcCI6MTUzODk4MjQ2OH0.zkmYTzJqfVUw9G5c1iLbi7vHunKz0VWoNgiDeM8sR18" \
```

### レスポンス

ボディ

```
```
SimpleDateFormatが٢٠١٨١٠٠٤٠٨٣١٣٣٦٥٧みたいに文字化けするとき

# 結論

SimpleDateFormatは常にLocaleを指定しましょう！

# 原因

Localeを指定しない場合、SimpleDateFormatは端末のロケールによって変換されることがあります。それが中東系の国だと、「インド数字」[^1]というシステムを採用している可能性があります。そうすると、「20181004083133657」は「٢٠١٨١٠٠٤٠٨٣١٣٣٦٥٧」に変換されちゃいます。

# 解決

常に `Locale.US` を指定しましょう！

```java
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.US);
```

ちなみに、ロケールを`new Locale("ar", "EG")`にすればこの現象はAndroid端末上で再現しますが、なぜかmacOS上では再現できませんでした。

[^1]: [インド数字 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%89%E6%95%B0%E5%AD%97)
PHPでメソッドを動的に生やそう

[php.internals](http://news.php.net/php.internals)を見ていたら[Pre proposal for "Class extension functions"](http://news.php.net/php.internals/103246)というのを見つけてしまったんですよ。
万一RFCまで進んでしまったとしても絶対に受理されることはないと思うのですが、なかなか斬新なアイデアだったので紹介してみたいと思います。

# 文法

```php:PHP
function DateTime->localTime() {
    return $this->format('H時i分');
}

$dt = new DateTime();
echo $date->localTime(); // 12時34分
```

クラスを継承することなく、クラスそのものにメソッドを生やすことができるという機能です。

何処からこんな発想が来たかといえば当然JavaScriptでしょう。

```js:JavaScript
Date.prototype.localTime = function() {
	return this.getHours() + "時" + this.getMinutes() + "分"
};

dt = new Date;
console.log(dt.localTime()); // 12時34分
```

と思ったんだけど、[本人によると](http://news.php.net/php.internals/103251)Kotlinの[拡張関数](https://qiita.com/pinemz/items/640428706dac1bfae409)が元ネタだそうです。

```kotlin:Kotlin
fun Date.localTime(): String {
    return SimpleDateFormat("H時m分").format(this)
}

val date = Date()
println(date.localTime()) // 12時34分
```

ちなみに、[Ruby](https://qiita.com/YumaInaura/items/4f9138d4dbce7274e4dd)や[C#](https://qiita.com/kuwapp/items/166a51ae7ba8eb574cde)などの言語でも似たような機能を使うことができます。


# みんなの反応

・extendsしたあとで基底クラスにメソッド追加したら死ぬ。
・privateを簡単に見れるようになってカプセル化が死ぬ。
・JSじゃないんだから普通にextendsすりゃええやん。
・Kotlinのはただの糖衣構文であって、実際にクラスを変更しているわけではない。
・複雑化するリスクに対してベネフィットが少なすぎる。
・デリミタは`->`より`::`がいいな。
・バックポートに使えそう。たとえばSplFileObjectはPHP5.1.0で実装されたがSplFileObject::freadはPHP5.5.11で追加された。
・[runkit_method_add](http://php.net/manual/en/function.runkit-method-add.php)や[uopz_add_function](http://php.net/manual/en/function.uopz-add-function.php)で同じことができるよ。

全員がNOという感想でした。
アイデアを出してる人も、あくまで反対のうえで使い道を考えているという態度です。


# 感想

普通にextendsしろよ、という感想。

既存クラスを書き換えるより素直にextendsしたほうが、少なくとも読む方としてはわかりやすいでしょう。
これが導入されると、あるメソッドが言語仕様なのか拡張関数なのか、ぱっと見でわからなくなります。
それどころか同じメソッドでも、PHPバージョンによって言語仕様か拡張関数かが異なる場合すらあります。
どこかのライブラリが勝手に何かやってたりしたら大惨事です。

実のところ[runkit](http://php.net/manual/ja/intro.runkit.php)や[uopz](http://php.net/manual/ja/intro.uopz.php)などはこの提案よりずっと強力な機能を提供していたりするのですが、これはあくまで特殊用途向けであって、一般ユーザが軽々しく使うようなものではありません。
デフォルトで誰もが使える機能として入れるようなものではないでしょう。

というかJavaScriptですらprototype使うなって方向に進んでいる昨今、Kotlinの拡張関数があまりにも簡単すぎて大丈夫なのこれ。

それからphp.internalsが見づらいのはどうにかならないのだろうか。
今のままだと話題を追いにくいので、ツリー表示に対応してほしい。
MeCab のユーザー辞書を作る（UniDic）

自分用メモ。

# 環境
1. MeCab 0.996 と UniDic(ver. 2.1.2) をインストールした。 
2. MeCabの設定ファイルを編集して、UniDicを使えるようにした。
参考 👉 [MeCabとUNIDICをUbuntu 14.04にインストール - Yura YuLife](http://yura2.hateblo.jp/entry/2015/08/18/MeCabとUNIDICをUbuntu_14.04にインストール)
3. MeCabの設定ファイルを編集して、語種を表示できるようにした。参考 👉 [MeCab + Unidic を使って単語の語種（和語、漢語）を表示する - Qiita](https://qiita.com/Hiroyuki1993/items/0bcc535b39abdf646828)

# ゴール
ユーザー辞書を作って解析に使えるようにする。

```
# 現状

$ mecab
タルスキー
タル    タル    タル    タル-外国       名詞-固有名詞-人名-一般                 固
スキー  スキー  スキー  スキー-ski      名詞-普通名詞-一般                      外
EOS
```

# やったこと

### 辞書のCSVファイル
`/Users/Pii/UserDic/uniuserdic.csv` を作った。

```
# uniuserdic.csv

タルスキー,,,0,名詞,固有名詞,人名,一般,*,*,タルスキー,タルスキー,タルスキー,タルスキー,タルスキー,タルスキー,固,*,*,*
バナッハ,,,0,名詞,固有名詞,人名,一般,*,*,バナッハ,バナッハ,バナッハ,バナッハ,バナッハ,バナッハ,固,*,*,*
```

### コンパイル
`/Users/Pii/UserDic/` の中で作業

```
$ /usr/local/libexec/mecab/mecab-dict-index -d /Users/Pii/unidic-mecab-2.1.2_src/ -u /Users/Pii/UserDic/uniuserdic.dic -f utf-8 -t utf-8 uniuserdic.csv
```

実はこれ、けっこう手こずった。
`-d`の後に指定するディレクトリは、辞書コンパイル用のあれこれが入っているディレクトリなんだけど、これがどこにあるのか分からなかった。
UniDic は IPAdic とは辞書の書き方が違うから、UniDic 用の dicrc を指定してやらなければならないんだけど、先輩方の解説は IPADic 用のものが圧倒的に多い。

### mecabrc にユーザー辞書のパスを追加
`/usr/local/etc/mecabrc` に一行追加する。

```
userdic = /Users/Pii/UserDic/uniuserdic.dic
```


### 参考にしたサイト
- [MeCab で UniDic 辞書を使ってみる / 桃缶食べたい。 - chocolablog](https://blog.chocolapod.net/momokan/entry/56)
- [MeCab: 単語の追加方法](https://taku910.github.io/mecab/dic.html)
- [mecabの解析辞書にUniDicを使い始めた - 雲雀は高く空を舞い - ひよこの会](http://chick.g.hatena.ne.jp/allegro/20091201/p1)
- [mecab に単語を追加するユーザー辞書を追加する - 一人ぼっちのライフハック生活](http://mooooooooooriiiiii.hatenablog.com/entry/2017/03/25/202346)
- [mecabにオリジナル辞書をシステム辞書として投入する - おぼえがき](https://blog.goo.ne.jp/_memento/e/3605227bcef2faa354de395bdb9bf7f9)


# 結果
```
# 結果
$ mecab
バナッハ・タルスキーのパラドクス
バナッハ        バナッハ        バナッハ        バナッハ        名詞-固有名詞-一般                      固
・                      ・      補助記号-一般                   記号
タルスキー      タルスキー      タルスキー      タルスキー      名詞-固有名詞-一般                      固
の      ノ      ノ      の      助詞-格助詞                     和
パラドクス      パラドクス      パラドックス    パラドックス-paradox    名詞-普通名詞-一般                      外
EOS
```
やったー！
AWS Systems Manager セッションマネージャーを使ってEC2鍵とAWS ACCESS KEY管理から開放されよう

EC2鍵やAWS_ACCESS_KEYの管理から開放されたいと思ったことはないですか？
僕は毎日思っています。セッションマネージャを使えば、鍵管理不要でセキュアなサーバが作れます。

## セッションマネージャとは？
- AWSが2018/9に発表した、EC2を操作できる対話型シェル

## セッションマネージャはなにが嬉しいのか？
- SSHがなくてもサーバ作業が可能になる
  - EC2鍵管理をなくし、およびSSHポート開放も不要になる
- AWS ACCESS KEYの管理を減らせる可能性がある
  - ローカルPCにAWS ACCESS KEYを置いてAWS作業を行っている場合、AWS ACCESS KEY自体を不要にできる。
  - 例えば、EC2にIAMロールを付与すれば、AWS ACCESS KEYがなくてもIAMロール権限でAWS CLIやSDKを実行できるが、セッションマネージャからEC2にログインしてAWS作業を行うようにすれば、AWS ACCESS KEYの管理が不要になる
- コマンドログがS3に格納されるので、監査の要件も満たせる

## 雰囲気
![10月-04-2018 19-47-14.gif](https://qiita-image-store.s3.amazonaws.com/0/95146/e43ced6f-1ed6-ebd1-35df-aa682814ecd5.gif "10月-04-2018 19-47-14.gif")


## セッションマネージャの使い方
- EC2にSSMエージェントをインストールする(2.3.12以上)
  - 本来、Amaxon LinuxにはデフォルトでSSMエージェントがinstallされているが、2018/10/4時点では残念なことにinstallされているバージョンが古いので、upgradeが必要
- AmazonEC2RoleforSSMポリシーを付与したロールを作成し、EC2に付与する
- AWS → SystemManager → セッションマネージャ → セッションの開始
- ログイン後、ec2-userにスイッチすればいつものサーバ作業が可能になる



## セキュア風サーバの作り方
- 新規のEC2キーペアを作成する
- 新規のEC2キーペアを用いてEC2を起動する
- お好きなIAMロールを付与する
- UserData等でSSMエージェントをupgradeする。（現状のAmazonLinux2だとSSMエージェントバージョンが古いので更新が必要。AMIがもっと最新になることを期待）
- ローカルに勝手にダウンロードされるEC2キーペアを削除する
- AWS上からもEC2キーペアを削除する
- セッションマネージャからEC2にログインし、SSHデーモンなど不要なプロセスを落とす
- SSHポートも当然付与しない

これでIAMロール権限に沿ったAWS作業が可能になります。

## できないこと例
- ファイルアップロードみたいなことはできない。でもgit pullできるようにすればあんまり困らない。
- ~~Ansible等の構成管理ツールは当てられない~~
  - 追記: 最近はSSM + Ansible連携等もできます
python-twitterの関数一覧

# python-twitterの関数一覧メモ
使用したpython-twitterの関数のメモです

- ツイートを投稿

```python
api.PostUpdates("ツイート内容")
```
- ダイレクトメッセージを送信

```python
api.PostDirectMessage("ユーザーID", "DM内容")
```
- ユーザー情報を取得

```python
api.GetUser(screen_name = "スクリーン名")
```
スクリーン名は「@xxxx」

- 自分にメンションの付いているツイートの取得

```python
api.GetReplies()
```

- タイムラインの取得

```python
api.GetUserTimeline("ユーザーID")
```

- ツイート情報を取得

```python
api.GetStatus("ツイートID(status_id)")
```

- フォローしているユーザーを取得

```python
api.GetFriends("ユーザーID")
```
引数がない場合は自分のフォローしているユーザーを返す

- 指定のユーザーをフォローしているユーザーを取得

```python
api.GetFollowers("ユーザーID")
```
引数がない場合は自分をフォローしているユーザーを返す
Liberty経由でWatson APIを呼び出す際SSLエラーの対策


Eclipseのコンソールログから下記エラーが出た際の対策

#前提環境

Liberty with Full Platform導入済み

#エラー
```
[ERROR   ] 
CWPKI0022E: SSL ハンドシェークの失敗: 
SubjectDN CN=*.watsonplatform.net, O=INTERNATIONAL BUSINESS MACHINES CORPORATION, L=Armonk, ST=New York, C=US の署名者がターゲット・ホストから送信されました。 
 SSL 構成別名 defaultSSLConfig にあるローカル・トラストストア 
<root directory>/Liberty_JavaEE7_Full/usr/servers/Server01/resources/security/key.jks にこの署名者を追加する必要がある可能性があります。  
SSL ハンドシェーク例外から送られた拡張エラー・メッセージは次のとおりです: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
```

#解決方法①


最初からLiberty with IBM Java SDK8を導入する。
そうするとそのエラーが出なくなる。

やっぱ入れ直しが時間かかるし面倒だと思う人は次の方法へ。


#解決方法②


・証明書入手
手順参考：https://qiita.com/nenokido2000/items/b36b6e5f0854d7d63ba6
Downloadされた証明書：*watsonplatformnet.cer

・下記コマンド実行
（JAVA EE環境）
```
sudo keytool -import -alias <証明書別名> -keystore <root directory>/Liberty_JavaEE7_Full/usr/servers/Server01/resources/security/key.jks -file <root directory>/Desktop/\*watsonplatformnet.cer
```


場合によってはJava向け下記も実行しておく必要がある
```
sudo keytool -import -alias <証明書別名> -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/security/cacerts -file <root directory>/Desktop/\*watsonplatformnet.cer
```
【GitHubAPI】レビュワーをアサインする方法

githubではプルリクにコードレビュー担当者をアサインする機能があります
これが自動でできたら便利だな、ということでPHPでのAPIの叩き方を調べてみました

使用したAPI↓です
https://developer.github.com/v3/pulls/review_requests/

# サンプルコード

```php5
$url = 'https://api.github.com/repos/オーナー名/プロジェクト名/pulls/' . 'アサインしたいプルリク番号'.'/requested_reviewers?access_token='. 'プルリクの操作権限があるトークン';

// POSTするデータ
$params = array(
    'reviewers' => 'レビュワーのgithubアカウント名',
);

//curl設定
$options = array(
    CURLOPT_URL => $url, // URL
    // User-Agentはなんでもいいっぽい？
    CURLOPT_HTTPHEADER => array('User-Agent: githubアカウント名', 'Content-Type: application/json'), 
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_POST => true,     
    CURLOPT_POSTFIELDS => json_encode($params),
);
        
$ch = curl_init();
curl_setopt_array($ch, $options);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
// エラーのときはmessageになにか入っている
if (isset($response['message'])) {
    // エラー時の処理
}

```
成功すればプルリクがjson形式で返ってきます。
プルリクの画面を見て、レビュワーがアサインされてるか確認してみてください
ラズパイでHelloWorld!

# はじめに
案件でラズパイを使ってBluetooth通信させたりセンサー付けて環境情報取ったりする機会が多くなってきたので備忘録としてラズパイ関連の記事を書いていこうと思います。
![IMG_1580.JPG](https://qiita-image-store.s3.amazonaws.com/0/212518/d4e461e5-04a6-46c5-9a93-ad9879946da1.jpeg)
まずは導入編としてラズパイ上にWebサーバーを立ち上げてPCブラウザからアクセスしてHelloWorld!と表示させるまでの手順です。ラズパイ用の標準OSであるRaspbianのインストールからサーバーのセットアップまで書きました。

# 用意するもの
- Raspberry Pi 3 Model B(またはB+)
- SDカード(8GB以上あると安心)
- 操作用PC(ここではMacを想定)

# ラズパイの初期設定
## Raspbianのインストール
[Raspbianのサイト](https://www.raspberrypi.org/downloads/raspbian/)からRASPBIAN STRETCH LITEのイメージをダウンロードします(GUIは不要なのでここでは軽量版を使います)。

PCにSDカードを挿してイメージを書き込みます。

```bash
diskutil list
sudo diskutil unmountDisk /dev/disk2
sudo dd bs=1m if=/path/to/img of=/dev/disk2
```

## SSHの有効化
デフォルトだとSSHが使えないので使えるようにしておきます。

操作用PCにSDカードのbootボリュームをマウントしてSSH有効化ファイルを作ります。

```bash
cd /Volumes/boot
touch ssh
```

## ラズパイのセットアップ
ラズパイにSDカードを挿して有線LAN、電源をつなぎます。

操作用PCでラズパイのIPを調べます。
ラズパイのMACアドレスは**b8:27:eb**で始まるようです。

```bash
arp -a | grep b8:27:eb
```

上記で出てきたIPアドレスにSSHで接続できればOKです。

```bash
ssh pi@172.17.1.113
# 初期パスワードはraspberryです。
```

## Raspbianの初期設定
*※以降のコマンドはrootに切り替えてから行う想定で書いています。*

ミドルウェアの更新および必要なミドルウェアを適当にインストールします。

```bash
apt-get update
apt-get upgrade -y --fix-missing
apt-get install vim git -y
```

Wi-Fiに繋ぎたい場合はraspi-configの**2 Network Options**でSSID等の登録ができます。

```bash
raspi-config
```

DHCPでIPが変わると面倒なのでIPを固定します。

```bash
# 例
cat << EOS >> /etc/dhcpcd.conf
interface wlan0
static ip_address=172.17.1.113/16
static routers=172.17.0.1
EOS
```

# HelloWorld!する
## Node.jsとnpmのインストール
まずはaptでインストールします。

```bash
apt-get install nodejs npm -y
```

npmのアップデート。

```bash
npm i -g npm
```

Node.jsのバージョン管理としてnを使います。

```bash
npm i -g n
```

Stableバージョンに切り替え。

```bash
n stable
```

apt管理のNode.jsとnpmを削除

```bash
apt-get purge nodejs npm -y
```

## モジュールの初期設定
npmの初期化と[Express](https://www.npmjs.com/package/express)のインストール。

```bash
mkdir -p /usr/local/src/helloworld
cd /usr/local/src/helloworld
npm init -f
npm i express
```

HelloWorld!プログラムを書きます。

```js
// index.js
const app = require('express')();
app.get('/', (req, res) => res.send('HelloWorld!'));
app.listen(80);
```

Webサーバーの起動。

```bash
node .
```

ブラウザからアクセスしてHelloWorld!が表示されればOK。

## プロセスの永続化
Webサーバーのプロセスを常駐させたい場合はNode.jsで書かれた[forever](https://www.npmjs.com/package/forever)というライブラリを使うと楽です。

グローバルインストール。

```bash
npm i -g forever
```

プロセスの起動。

```bash
forever start /usr/local/src/helloworld/index.js
```

以下のようなシェルスクリプト書いてcrontabに登録しておけばプロセス監視もできます。

```bash
#!/bin/bash
process_name=/usr/local/src/helloworld/index.js
check_process_log=/var/log/check-process.log
app_log=/var/log/node/helloworld.log

process_running=$(forever list | grep ${process_name} | wc -l)

if [ ${process_running} = 0 ]; then
  forever -l ${app_log} -o ${app_log} -e ${app_log} -a start ${process_name} > /dev/null 2>&1
  echo "[$(date +%FT%T%:z)] ${process_name} has started." >> ${check_process_log} 2>&1
else
  echo "[$(date +%FT%T%:z)] ${process_name} is already running." >> ${check_process_log} 2>&1
fi
```

# おわりに

ラズパイのセットアップからブラウザでHelloWorld!表示までできたので次回はBluetooth使って色々やって見たいと思います。

**以上**
NASくらべ

#経緯
アレヤコレヤ対策でrobocopyを使ってWindow ServerのファイルをNASにバックアップを取りたいと思ったけど、robocopyが出来るもの出来ないものあったのでメモ
やりたかったrobocopyは

```
robocopy src dst /R:5 /W:5 /MIR /COPYALL /XO /XJD /ZB /EFSRAW
```
ようするに、Windows ACLごとコピーしたい。

#結果

|項目＼メーカー|QNAP|Synology|asustor|
|:--|:--:|:--:|:--:|
|robocopy|出来る|出来ない|出来ない|
|機種名|TS-231P|DS918+|AS6404T|
|エラーメッセージ|－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－|yyyy/mm/dd hh: mm: ss エラー 5 (0x00000005) ファイル属性を変更しています NAS-TARGET-FOLDER アクセスが拒否されました。|yyyy/mm/dd hh: mm: ss エラー 50 (0x00000032) NTFS セキュリティをコピー先ディレクトリにコピーしています NAS-TARGET-FOLDER この要求はサポートされていません。|
|対策|－－－|FastCopy|FastCopy|
AfterEffects 24時間を１秒でカウントするエクスプレッション

#24時間を一秒でカウントさせる。
難しい事ではないですが、あとから使う予定なのでコピペ用にメモしておきます。
一秒間で00：00～23：59をループさせる。

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/178061/9d2512ca-2d87-ade9-a56f-c4799ab750c9.jpeg)


```jsx
var oneDayToHour = 24;
var oneHourToMinute = 60;
var oneDayToMinute = oneDayToHour*oneHourToMinute;

var hourCount = Math.floor(time*oneDayToHour);
var hourModNum = hourCount  % oneDayToHour;
var hour = ('00' + hourModNum ).slice(-2);

var minuteCount = Math.floor(time*oneDayToMinute);
var minuteModNum = minuteCount % oneHourToMinute;
var minute = ('00' + minuteModNum ).slice(-2);

hour+":"+minute
```
EC-CUBE4でURLの/user_dataを変える

`.env`の中の

```bash:.env
#ECCUBE_USER_DATA_ROUTE=user_data
```
のコメント外して好きな文字列に置き換えてキャッシュをクリア。


### [EC-CUBEのカスタマイズはこちら](https://www.xross-cube.com/service/ec-cube%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA)
PHPでSendGridを使ったメール送信サンプル


Webアプリに組み込んで何かをトリガーにして送信…ではなく、例えば何らかのサービスの生存をチェックして、落ちてるときにはメール発報、みたいな使い方をイメージしてます。ちょっと前までだったら、普通に mail() で送ればいいじゃないという話なんだけど昨今の事情を鑑みるとクラウドサーバからメール送信できないとか普通にあるっぽいので。

なお、結論から言うとめちゃくちゃ簡単＆便利。今回は書いてないけど、SendGrid側でどれだけ開封されてるか、とかが確認できるのもナイス。


#準備

事前に https://app.sendgrid.com/settings/api_keys でAPIキーを作成しておく。
作成後に表示されるAPIキーは一度しか表示されないのでこれを大事にとっておいて、以下の内容で.envファイルを作成し、APIキーを記述しておく。

```.env
export SENDGRID_API_KEY='hogehogefugafuga'
```

このファイルを読み込むため、下記コマンドを実行。

```command
source .env
```

念の為、ちゃんと読み込めてるか確認する。

```command
echo $SENDGRID_API_KEY
hogehogefugafuga
```

＼(^o^)／

#インストール

sendgridのパッケージをインストール。

composer のインストールは https://getcomposer.org/download/ こちらから。

```command
composer require sendgrid/sendgrid
```


#PHP側作業
githubにあるサンプルをベースにちょこちょこ修正する。下記は修正前。test.phpという名前で作ってみる。

```test.php
<?php
require 'vendor/autoload.php'; // If you're using Composer (recommended)
$email = new \SendGrid\Mail\Mail();
$email->setFrom("test@example.com", "Example User");
$email->setSubject("Sending with SendGrid is Fun");
$email->addTo("test@example.com", "Example User");
$email->addContent("text/plain", "and easy to do anywhere, even with PHP");
$email->addContent(
    "text/html", "<strong>and easy to do anywhere, even with PHP</strong>"
);
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
try {
    $response = $sendgrid->send($email);
    print $response->statusCode() . "\n";
    print_r($response->headers());
    print $response->body() . "\n";
} catch (Exception $e) {
    echo 'Caught exception: '. $e->getMessage() ."\n";
}
```

でもって動作確認。

```command
php test.php
```

すげー。これだけでメール送れる！めっちゃ簡単！！！

cronとかで回すときは、

```
10 * * * * source path/to/.env ; php test.php
```

のようにして環境変数を使うのが良さそう。
ローカルの差分全部pushする



```bash:push
@echo off
set /p ANS="comment:"

cd C:目的地
git add .
git commit -m %ANS%
git push
exit
```

コメント付きでコミットできます。
コメントを付けるときは""で囲まないと空白が反映されません。
~~branchは知らない~~
Socket.IO でユーザー認証

Socket.IO で接続してきたクライアントが正規ユーザーかどうかの認証を行う。

# 環境

- Node.js: 10.10.0
- Socket.IO: 2.1.1

# middleware について

Socket.IO の [namespace.use(fn)](https://socket.io/docs/server-api/#namespace-use-fn) を使用して、接続してきたソケットをハンドリングするミドルウェアを登録することができる。

```js
io.use((socket, next) => {
  if (socket.request.headers.cookie) return next()
  next(new Error('Authentication error'))
})
```

# サーバー側

[Socket.IO — Client API | Socket.IO](https://socket.io/docs/client-api/#With-query-parameters)


```js
// server-side
const io = require('socket.io')();

// middleware
io.use((socket, next) => {
  let token = socket.handshake.query.token;
  if (isValid(token)) {
    return next();
  }
  return next(new Error('authentication error'));
});

// then
io.on('connection', (socket) => {
  // 認証に失敗した場合 connection イベントは発火しない
  // do something...
});
```

# クライアント側

## 接続

```js
// クライアント
const socket = io('http://localhost', {
  query: {
    token: 'abc'
  }
})
socket.on('connect', () => {
  // 認証に失敗した場合 connect イベントは発火しない
  // do something...
})
```

## トークンの更新

再接続のときにクエリの内容を更新することができる。

```js
socket.on('reconnect_attempt', () => {
  socket.io.opts.query = {
    token: 'def'
  }
})
```
Sassでよく使う関数リスト

#はじめに
**Sassの関数には文字や数値を処理するものが数多く用意されています。**
**今回はその中でも<font color="Salmon">特に使用頻度が高い</font>と思われるものをピックアップしてみました〜**


##使用頻度が高そうな関数(文字・数値系)

```style.scss
.quote {   //" "を付けて出力してくれる関数
  content: quote(ハロー);
}

.unquote {   //" "を外して出力してくれる関数
  content: unquote("ハロー");
}

.abs {   //絶対値を出力してくれる関数
  width: abs(50px - 100px);
}

.ceil {   //数値の切り上げをしてくれる関数
  width: ceil(100px / 3);
}

.floor {   //数値の切り捨てをしてくれる関数
  width: floor(100px / 3);
}

.round {   //四捨五入してくれる関数
  width: round(100px / 3);
}


```


##出力結果

```style.css
@charset "UTF-8";
.quote {
  content: "ハロー";
}

.unquote {
  content: ハロー;
}

.abs {
  width: 50px;
}

.ceil {
  width: 34px;
}

.floor {
  width: 33px;
}

.round {
  width: 33px;
}

```



##使用頻度が高そうな関数(色系)

```style2.scss
.rgba {
  color: rgba(#98ab8e, 0.3);   //16進数渡したカラーコードをry
}

.mix {
  color: mix(#f70000, #0000e2);
}

.lighten {
  color: lighten(#279841, 30%);
}

.darken {
  color: darken(#279841, 30%);
}
```

##出力結果

```style2.css
.rgba {
  color: rgba(152, 171, 142, 0.3);
}

.mix {
  color: #7c0071;
}

.lighten {
  color: #7bdd91;
}

.darken {
  color: #081e0d;
}
```




参考元:Udemy
https://www.udemy.com/sass-for-frontend-engineer/
敷居の低いLAMP構成構築 on GCP (1/2)


GCP上のCentOSに、手軽にLAMP環境を実装する。

#目次
-　環境
-　Apacheの導入


#環境
・GCP上に立てたCent OS

#Apacheの導入
①作成したインスタンスに、ssh接続します。
②Apacheをインストールします。
```ssh:centos
#sudo yum -y install httpd
```