OmniAICreator/Qiita-1.07M huggingface dataset:
SPAのサイトでChartbeatにPVを送信する方法。

通常は、GTMの「pageview」イベントをトリガーにして、ChartbeatにPVを送信する。

メディアサイト「WWD JAPAN.com （ https://www.wwdjapan.com/ ） 」は、SPA（シングルページアプリケーション）のため、通常のGTMの「pageview」では、PVをChartbeatに正確に送信できなかった。

この設定でうまくいった。

GTM、SPAでのChartbeatへのPV送信設定は、以下の通り

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41550/a284c334-5cc4-ee7b-b0cd-6022ca535687.png)


## 「loadPage （datalayerでのイベントpush） 」

SPAページの初期ロード完了トリガー（SPAでは初回1回のみサーバーからHTMLを受け取る。 WWD JAPAN.comでは、SPAでのHTML生成完了後、タイトルなどがHTMLで準備できたタイミングでトリガーしている。）

初回のロード時のみ、Chartbeat SDKのロードと、PV送信を行う。

Chartbeat Load SDK and Send PV


```html

<script type='text/javascript'>
    (function() {
        /** CONFIGURATION START **/
        var _sf_async_config = window._sf_async_config = (window._sf_async_config || {});

        _sf_async_config.uid = << UID >>;
        _sf_async_config.domain = '<< サイトドメイン >>'; //
        _sf_async_config.flickerControl = false;
        _sf_async_config.useCanonical = false;
        _sf_async_config.useCanonicalDomain = true;
        _sf_async_config.sections = '<< セクション名 >>'; 
        _sf_async_config.authors = '<< 著者名 >>';
        /** CONFIGURATION END **/
        function loadChartbeat() {
            var e = document.createElement('script');
            var n = document.getElementsByTagName('script')[0];
            e.type = 'text/javascript';
            e.async = true;
            e.src = '//static.chartbeat.com/js/chartbeat.js';
            n.parentNode.insertBefore(e, n);
        }
        loadChartbeat();
     })();
</script>
<script async src="//static.chartbeat.com/js/chartbeat_mab.js"></script>
```

## 「change （datalayerでのイベントpush） 」

SPAでのページ遷移は、サーバーを経由しないため、GTMのpageviewイベントはトリガーされない。

SPAでは、ページ遷移は、URLの変化を元に、サーバーのAPIをコールして、情報を取得して、ページを再描画している。そのため、URL変更され、ページが再描画されタイトルなどがHTMLで準備できたタイミングでトリガーしている。

すでに、Chartbeat SDKのロードは完了しているため、PV送信のみを行う。

**Chartbeatでは、Javascriptで動的に生成されたページの回遊時、「Virtual Page」という仕組みを利用してPVを送信する必要がある。**

Chartbeat Send PV

```html
<script>
var sendChartbeat = function (count){
	try {
		if (window.pSUPERFLY) {
			pSUPERFLY.virtualPage({
				sections:'<< セクション名 >>',
				authors:'<< 著者名 >>',
				path:'{{Page Path}}',
				title:'{{Page Title}}'
			});
		} else {
			if(count > 0){
				setTimeout(function () {
					sendChartbeat( count - 1 )
				}, 500)
			}
		}
	} catch (e) {
		//
	}
}
sendChartbeat(10)


</script>
```


## まとめ

WWD JAPAN.comは、SPA構成になっている。

タイトル、本文などが空のHTMLをロードして、javascriptからAPIを呼んでページの情報を取得してHTMLを作成する。

SSRで、タイトルなどが入ったHTMLを返すようにしているが、たまに、SSRが失敗してタイトルが空のHTMLが返却される場合がある。

GTMのall pageviewのタイミングだと、うまくタイトルが送信できないことがあるので、HTMLが完成したタイミングで、loadPageイベントを発行して、そのloadPageをトリガーにしてChartbeat Load SDK and Send PVタグを発行

一度ページをロードすると、サイト内の回遊時、サーバーからHTMLをダウンロードしない。
URLが切り替わるタイミングでchangePageイベントを発行して、そのchangePageをトリガーにしてChartbeat Send PVタグを発行

最初のページのロードは、SDKのロードと、PV送信
Chartbeat Load SDK and Send PV

次のページからは、PV送信のみ
Chartbeat Send PV
GitHub上にあるRパッケージのオフラインインストール

素人の備忘録。
Windowsでのみ確認。

#動機
オフラインのPCにRのパッケージを、依存しているパッケージも含めてインストールしたい。
CRAN上にあるパッケージであれば、`miniCRAN`パッケージを使う方法が知られている。

```r:miniCRAN.r
# 必要パッケージの読込
library(miniCRAN)

# ワーキングディレクトリの設定
setwd("C:/Users/hoge/Downloads/R")

# 調べたいパッケージ一覧
pkgname <- c(
    "xxxx",
    "yyyy",
    "zzzz"
)

# 使用したいパッケージに紐付いているパッケージの探索
pkgs <- pkgDep(pkgname)

# ワーキングディレクトリ直下のpkgsフォルダにパッケージダウンロード
download.packages(pkgs, destdir = "pkgs", type = "win.binary")
```

[参考：R オフラインでのパッケージインストール](https://qiita.com/daifuku_mochi2/items/33f8525cdac1cc775c5f "R オフラインでのパッケージインストール")

ところが、世の中にはGitHub上にあってCRANにはないパッケージも存在する。
例えば、`aaaa/bbbb`パッケージを、依存しているパッケージも含めてインストールしたい。
前提として、`aaaa/bbbb`パッケージが依存しているパッケージは、全てCRAN上にあるとする。

#解決策
以下をオンラインPCで行い、ダウンロードしたパッケージ一式をオフラインPCのRにインストールする。

1. `aaaa/bbbb`パッケージをオンラインPCのRにインストールし、`bbbb.zip`に圧縮
2. `aaaa/bbbb`パッケージが直接依存しているCRAN上のパッケージを確認し、Windows用zipをダウンロード
3. 直接依存しているパッケージが依存しているCRAN上のパッケージを確認し、Windows用zipをダウンロード
4. 1～3のzipファイルをオフラインPCへ

1～3部分は以下のとおり行った。

```r:miniCRAN_GitHub.r
# 必要パッケージの読込
library(miniCRAN)
library(devtools)
library(tools)

# ダウンロード先の設定
dow <- "C:/Users/hoge/Downloads/R/"
# サブディレクトリ名
subd <- "pkgs/"

# インストールするリポジトリ名
repo <- "aaaa/bbbb"
# /以降がパッケージ名
pkgname <- substr(repo, regexpr("/", repo) + 1, nchar(repo))

# Githubからインストール
install_github(repo)

# インストールされたパッケージをzipに圧縮してサブディレクトリに置く
setwd(.libPaths())
zip(paste0(dow, subd, pkgname, ".zip"), pkgname)

# 依存しているパッケージの探索
## CRANパッケージ一覧にリポジトリを追加
pdb <- addPackageListingGithub(pdb = available.packages(), repo)
## 直接的な依存パッケージを確認
base_pkgs <- package_dependencies(packages = pkgname, pdb, which = "Depends")[[1]]
## 直接的な依存パッケージが依存しているパッケージを確認
pkgs <- pkgDep(base_pkgs)

# ダウンロード先をワーキングディレクトリとして設定
setwd(dow)
# ワーキングディレクトリ直下のサブディレクトリに依存パッケージをダウンロード
download.packages(pkgs, destdir = subd, type = "win.binary")
```

#補足
GitHub上のパッケージに依存しているGitHub上のパッケージがあったらどうしようかと考えたが、そのようなパッケージが見つからず検証できなかった。
その時に考えよう。
Leetcode #102: Binary Tree Level Order Traversal

```swift
func levelOrder(_ root: TreeNode?) -> [[Int]] {
    var answer = [[Int]]()
    if root != nil {
        var stack = [root!]
        while !stack.isEmpty {
            answer += [stack.map { $0.val }]
            var tmp = [TreeNode]()
            for node in stack {
                if let leftNode = node.left {
                    tmp.append(leftNode)
                }
                if let rightNode = node.right {
                    tmp.append(rightNode)
                }
            }
            stack = tmp
        }
        return answer
    } else {
        return []
    }
}
```
CentOS7.5にPostgreSQL10をインストールする方法

CentOS7.5にPostgreSQL10をインストール、初期設定するまでのやり方を紹介します。

## PostgreSQL10をインストールする
### リポジトリを追加
始めにPostgreSQL10のリポジトリを追加します。

```bash
$ sudo rpm -Uvh https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm
```

他のバージョンを追加したい場合はこちらからリポジトリのURLを確認できます。

[PostgreSQL: Linux downloads (Red Hat family)](https://www.postgresql.org/download/linux/redhat/)

### インストール
下記コマンドを実行します。

```bash
$ sudo yum install -y --enablerepo=pgdg10 postgresql10 postgresql10-server
# 確認
$ psql --version
psql (PostgreSQL) 10.5
```

インストールが完了したら起動しましょう。

```bash
$ sudo systemctl start postgresql-10
Job for postgresql-10.service failed because the control process exited with error code. See "systemctl status postgresql-10.service" and "journalctl -xe" for details.
```

失敗しましたね。。。

原因を調べてみると

```bash
$ sudo tail -n 50 /var/log/message
Sep  3 11:54:48 192-0-2-58  systemd: Starting PostgreSQL 10 database server...
Sep  3 11:54:48 192-0-2-58 postgresql-10-check-db-dir: "/var/lib/pgsql/10/data/" is missing or empty.
Sep  3 11:54:48 192-0-2-58 postgresql-10-check-db-dir: Use "/usr/pgsql-10/bin/postgresql-10-setup initdb" to initialize the database cluster.
Sep  3 11:54:48 192-0-2-58 postgresql-10-check-db-dir: See /usr/share/doc/postgresql10-10.5/README.rpm-dist for more information.
Sep  3 11:54:48 192-0-2-58 systemd: postgresql-10.service: control process exited, code=exited status=1
Sep  3 11:54:48 192-0-2-58 systemd: Failed to start PostgreSQL 10 database server.
Sep  3 11:54:48 192-0-2-58 systemd: Unit postgresql-10.service entered failed state.
Sep  3 11:54:48 192-0-2-58 systemd: postgresql-10.service failed.
```

DBクラスタを初期化しろってことなので、下記コマンドを実行しリトライします。

```bash
$ sudo /usr/pgsql-10/bin/postgresql-10-setup initdb
Initializing database ... OK

# リトライ
$ sudo systemctl start postgresql-10
```

無事に起動しました。

## 初期設定
### パスワード設定
まずpostgresユーザのパスワードを設定します。

```bash
# インストール時に追加されているpostgresユーザに切り替え
$ sudo su - postgres

# PostgreSQLに接続
-bash-4.2$ psql
psql (10.5)
Type "help" for help.

# パスワード変更
postgres=\# alter role postgres with password 'パスワード';
ALTER ROLE

# 接続を解除
postgres=# \q
-bash-4.2$ exit
logout
```

### アクセス設定
各ユーザにパスワード認証でログインできるよう設定を変更します。

```bash
# rootユーザに切り替え
$ sudo su -

# 設定ファイルを編集
$ vim /var/lib/pgsql/10/data/pg_hba.conf
# 下記のように変更 
local   all             all                                     password
# IPv4 local connections:
host    all             all             127.0.0.1/32            password
# IPv6 local connections:
host    all             all             ::1/128                 password

# 再起動
$ sudo systemctl restart postgresql-10
```

パスワード認証でログインできることを確認します。

```bash
$ psql -U postgres
Password for user postgres: # 設定したパスワードを入力
psql (10.5)
Type "help" for help.

postgres=#
```

無事にパスワードが通って接続できましたね。

### 自動起動
サーバ起動時にPostgreSQLが自動起動するように設定します。

```bash
$ sudo systemctl enable postgresql-10
```
Leetcode #101: Symmetric Tree

Recursive solution: two tree are a mirror reflection of each other, if
1. Their roots have the same value
2. The right subtree is the mirror reflection of the left subtree

Time complexity: O(n), because we traverse the entire input tree once, where n is the number of nodes.

Space complexity: The number of recursive calls is bound by the height of the tree. In the worst case, the tree is linear and the height is in O(n)

```swift
func isSymmetric(_ root: TreeNode?) -> Bool {
    return isMirror(node1: root, node2: root)
}

func isMirror(node1: TreeNode?, node2: TreeNode?) -> Bool {
    if node1 == nil && node2 == nil {
        return true
    } else if node1 == nil || node2 == nil {
        return false
    } else {
        return node1!.val == node2!.val && 
               isMirror(node1: node1!.left, node2: node2!.right) &&
               isMirror(node1: node1!.right, node2: node2!.left)
    }
}
```

Iterative solution:

Time Complexity: O(n), because we traverse the entire input tree once, where n is the number of nodes.

Space Complexity: There is additional space required for the search queue. In the worst case, we have to insert O(n) nodes.

```swift
func isSymmetric(_ root: TreeNode?) -> Bool {
    var queue = [TreeNode?]()
    queue.append(root)
    queue.append(root)
    while !queue.isEmpty {
        let node1 = queue.remove(at: 0)
        let node2 = queue.remove(at: 0)
        if node1 == nil && node2 == nil {
            continue
        }
        if node1 == nil || node2 == nil {
            return false
        }
        if node1!.val != node2!.val {
            return false
        }
        queue.append(node1!.left)
        queue.append(node2!.right)
        queue.append(node1!.right)
        queue.append(node2!.left)
    }
    return true
}
```
Mac OSXのカラーパレットのクレヨンのカラーパレット

自分で使う用のメモ

- `#000000`リコリス
- `#212121`リード
- `#424242`タングステン
- `#5E5E5E`アイアン
- `#797979`スチール 
- `#919191`スズ 
- `#929292`ニッケル 
- `#A9A9A9`アルミニウム 
- `#C0C0C0`マグネシウム 
- `#D6D6D6`シルバー
- `#EBEBEB`マーキュリー
- `#FFFFFF`スノー

<br>

- `#941100`トウガラシ
- `#945200`モカ
- `#929000`アスパラガス
- `#4F8F00`シダ
- `#008F00`クローバー
- `#009051`コケ
- `#009193`ティール
- `#005493`オーシャン
- `#011993`ミッドナイト
- `#531B93`ナス
- `#942193`プラム
- `#941751`マロン

<br>

- `#FF2600`サクランボ
- `#FF9300`タンジェリン
- `#FFFB00`レモン
- `#8EFA00`ライム
- `#00F900`スプリング
- `#00FA92`シーフォーム
- `#00FDFF`ターコイズ
- `#0096FF`アクア
- `#0433FF`ブルーベリー
- `#9437FF`グレープ
- `#FF40FF`マゼンタ
- `#FF2F92`ストロベリー

<br>

- `#FF7E79`サーモン
- `#FFD479`マスクメロン
- `#FFFC79`バナナ
- `#D4FB79`ハチミツ
- `#73FA79`フローラ
- `#73FCD6`スピンドリフト
- `#73FDFF`アイス
- `#76D6FF`スカイ
- `#7A81FF`ラン
- `#D783FF`ラベンダー
- `#FF85FF`バブルガム
- `#FF8AD8`カーネーション
Mac環境のphp.iniを修正する方法

ある日Mac環境でPHPを使ったCLIツールを実行したところ、メモリ不足でエラーとなりました。

「とりあえず`php.ini`を修正して乗り切るか」と思い下記コマンドを実行してファイルを探してみました。

```bash
$ php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)
```

あれ・・・？ない？？

CentOSでは大体`/etc/php.ini`にあるのでgrepしてみましょう。

```bash
$ ls /etc | grep php.ini
php.ini.default
php.ini.default-previous
```

`php.ini`はないけど、それっぽいファイルがありますね。

コレ系のファイルは**「コピーして使いましょう」**というのがいつものパターンなのでそれでやってみます。

```bash
$ sudo cp /etc/php.ini.default /etc/php.ini
$ sudo chmod 644 /etc/php.ini

# 認識されているか確認
$ php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         /etc/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

$ sudo vim /etc/php.ini
# PHPの設定を修正
```

メモリの上限を増やし、CLIツールを実行したところ今度は正常に処理されました。

Mac環境でPHPの設定を変えたいって方は上記の方法を試してみてください。
Minecraft BE ScriptingAPI 第3回講座

# 【Minecraft BE】の ScriptingAPI開発講座(3)

今回は、AndroidのBlockLauncherを使って、開発をしていきましょう！

## 注意
ScriptingAPIは現段階でWindows10にしか対応していません。
Android,iOS,XboxOne,Swicthでは開発できません。(AndroidはBlockLauncherという外部ツールを使えばできます)

## 開発環境
- Android Oreo(8.0) Minecraft BE ver 1.11.1
- BlockLauncher

## AndroidでのScriptingAPI
先程も言っているとおりAndroidでScriptingAPIを使う場合はBlockLauncherが必要です。
[DLはこちらから](https://play.google.com/store/apps/details?id=net.zhuoweizhang.mcpelauncher)
有料版もありますが、無料版と変わりはないので、無料版で大丈夫です。

というわけで、いつもの、やっておきましょう。

```JavaScript:client.js
const clientSystem = client.registerSystem(0, 0);
//おまじないみたいな

clientSystem.initialize = function () {
//最初に一回実行される
    this.listenForEvent("minecraft:client_entered_world", (eventData) => this.enterWorld());
    //アロー関数、minecraft:client_entered_worldでワールドに参加したときに実行される
};

clientSystem.enterWorld = function() {
//先のアロー関数で呼び出したやーつ
    this.broadcastEvent("minecraft:display_chat_event", "HelloWorld");
    //チャットにHelloWorldと出力
};
```
はい、パート1のコピペです。

これをbehaviorに入れて、BlockLauncherからMinecraftを起動します。

とりあえず実行結果
![Screenshot_20190428-145052.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266165/61b27dc2-8417-4810-0732-15d2293f815f.jpeg)

簡単に出来ちゃいましたね。
そうなんです、windows10とやっていることは変わりません。ただ書いてワールドに入るだけ、いやぁBlockLauncher神かな( 'ω')?

次回は何をしようかな( 'ω')

[次回](https://qiita.com/Button/items/6a2b2e6448b5513aff6f)
環境変数を自動切り替えできるdirenvを使ってみる

direnvは**ディレクトリに応じて自動で環境変数を設定してくれるツール**です。

今までpythonやnode.jsのCLIツールを作るときは**dotenv**という類似ツールを使っていましたが、プログラム上で環境変数を記載した設定ファイル読み込む必要があり煩わしさがありました。

direnvはカレントディレクトリに設定ファイルを置くだけで自動的に環境変数を読み込んでくれ、より使い勝手が良さそうなので試してみることにします。

## インストール方法
macOSにてHomeBrewを利用している場合は、次のコマンドでインストールできます。

```bash
$ brew install direnv
```

その他のLinux環境にインストールする場合はこちら。

```bash
$ git clone https://github.com/direnv/direnv
$ cd direnv
$ sudo make install
```

インストールが完了した後は自動で読み込むための設定として、`~/.bashrc`に設定を追記します。
※zshやfish等を利用している場合は、それぞれ読み替えてください。

```bash
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$ echo 'export EDITOR="/usr/bin/vim"' >> ~/.bashrc
```

設定が完了したら再読込を行います。

```bash
$ source ~/.bashrc
```

上手くインストールできているか確認してみます。

```bash
$ direnv version
2.19.1
```

direnvについてもっと詳しく知りたい方はGitHubをご覧ください。

[direnv/direnv](https://github.com/direnv/direnv)

## 使い方

環境変数を設定したい開発環境のディレクトリに移動します。

```bash
$ cd ~/my-app/
```

`direnv edit ディレクトリ`コマンドを実行すると設定ファイルを編集するためエディタが起動します。
今回はこのディレクトリ以下に`TEST_TOKEN`という環境変数を追加してみます。

```bash
$ direnv edit .
# vimが起動するので環境変数を入力 
# ex. export TEST_TOKEN=1234567890
# 入力後、エディタを閉じる
direnv: loading .envrc
direnv: export +TEST_TOKEN
```

追加した`TEST_TOKEN`が環境変数として確認できるか確かめてみましょう。

```bash
$ env | grep TEST
TEST_TOKEN=1234567890
```

設定ファイルがあるディレクトリ外に移動すると自動的に読み込みが解除されます。

```bash
$ cd ..
direnv: unloading
$ env | grep TEST
# 出力なし
```

逆に設定ファイルがあるディレクトリに移動すると自動的に読み込まれます。

```bash
$ cd my-app/
direnv: loading .envrc
direnv: export +TEST_TOKEN
$ env | grep TEST
TEST_TOKEN=1234567890
```

設定ファイルは`.envrc`というファイル名で作成されます。

**重要な設定情報をGitHub等に公開しないように.envrcファイルは.gitignoreでコミット対象外にしておきましょう。**

ちなみに直接ファイルを修正することも可能です。

```bash
$ vim .envrc
# 下記を追加して保存
# export TEST2=abcde
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
```

エラーとなるのでメッセージに従ってコマンドを実行すると正常に読み込まれるようになります。

```bash
$ direnv allow
direnv: loading .envrc
direnv: export +TEST2 +TEST_TOKEN

$ env | grep TEST
TEST_TOKEN=123456789
TEST2=abcde
```
controllerに記載している内容をmodelに移動させる

コントローラーのみに
記載(元のプログラム)

```ruby:C/controller.rb
if A || B
 p @C
end
```

モデルに記載するパターン

```ruby:〇〇_controller.rb
if @〇〇.sample
 p @C
end
```

```ruby:〇〇model/〇〇.rb
def sample
 A || B
end
```
この2パターンは同じ処理になる。
Java経験者がRuby(rails)を習得する際のチートシート

###<font color="MediumSlateBlue">※随時更新していく用</font>

#対象読者
・ぼく
・JavaやC#経験者

#経緯〜Railsチュートリアル情報量膨大すぎ問題〜
・ものすごい情報量ですごいと思いつつ情報量多すぎて上から順にやっていたら(業務やりながらだと)終わらない。
・すでに似たような記事はあるけど自分の言葉で「これはJavaでいう~」という辞書的なモノを作ろう、と決意


#以下、辞書です
・※厳密にはイコールではないのだろうけども、強いて言えばコレかな、の感覚で載せている感は多少あります。
・※習得中の身のため「その理解は間違っている」というものがあれば指摘して頂きたいです。
・現段階でボリュームが少ないためruby固有の概念も載っけています。


## - initialize
・イニシャライズメソッド(インスタンスを生成するときに最初に呼び出されるメソッド)
・**javaでいうコンストラクタ**
・<font color="Coral">**test.rb参照**</font>
## - attr_accessor
・アクセサメソッド
・**java(Spring)でいうlombok(getter/setterをクラス内で定義するためのライブラリに含まれるやつ）**
・**インスタンス変数を定義するためのもの**
・<font color="Coral">**test.rb参照**</font>
## - self
・~~tいろんな意味で使用される~~
・何がselfになるのか、はselfが使われる場所によって異なる
・クラス内部の変数やメソッドを明示するときに使用（**クラス変数は後述の@@を使用する**）
・attr_accessorで指定したフィールドを指定
・メソッドの呼び出し元を現すことも（**test.rb**でいうところの`description`メソッド
・**javaでいうthis**
・<font color="Coral">**test.rb参照**</font>

```test.rb

class Car
  # オブジェクトの変数（値）
  # type(車の種類),weight(重量),user(使用者)
  attr_accessor :type,:weight,:user

  # 初期化用の特別なメソッド
  def initialize
    self.type = 'SUV'
    self.weight = 2500
  end

  # オブジェクトのメソッド（処理）
  def description(user)
    puts "こんにちは#{user},この車のタイプは#{type},重量は#{power}です。"
  end
end

#インスタンスを生成し変数に代入する
Car_A = Car.new

Car_A.description('ぼく')

p Car_A

```

## - @（アットマーク）
・インスタンス変数につけるやつ
・javaのインスタンス変数※1）と同意
※1)...インスタンスに関連付けられたフィールド変数のことで、「new」で生成された個々のインスタンスが持つ変数
・<font color="MediumSpringGreen">**test2.rb参照**</font>※こんな風に書いてもいいよ


```test2.rb

class Car
  # オブジェクトの変数（値）
  # type(車の種類),weight(重量),user(使用者)
  attr_accessor :type,:weight,:user

  # 初期化用の特別なメソッド
  def initialize
    @type = 'SUV'
    @weight = 2500
  end

  # オブジェクトのメソッド（処理）
  def description(user)
    puts "こんにちは#{user},この車のタイプは#{@type},重量は#{@power}です。"
  end
end

#インスタンスを生成し変数に代入する
Car_A = Car.new

Car_A.description('ぼく')

p Car_A

```

## - @@（アットマーク二つ）
・クラス変数につけるやつ
・クラス内、インスタンス内で使用できる
・値は共有される
・<font color="RoyalBlue">**test3.rb参照**</font>

```test3.rb

class Test
  @@class_var = 0

  def foo
    @@class_var += 1
    p @@class_var
  end

  def self.hoge
    @@class_var += 1
    p @@class_var
  end
end

test = Test.new

# 同一のインスタンス内で値は共有される
test.foo # => 1
test.foo # => 2

# インスタンスが異なっても、値は共有されている
test2 = Foo.new
test2.foo # => 3

# クラスメソッドからもアクセスできるかつ、値も共有されている
Test.hoge # => 4

```

## - require

・javaでいうimport...と書きたかったが、実際にはrequireの方が自由度が高そう（以下リンクを参照）
・[【Ruby】Ruby の require はJavaとは違うよ](http://sekai.hateblo.jp/entry/2013/09/13/212938)

## - モジュール

・コレはJavaでいう、が見つからなかった。。。

- **クラスとの違い**
 - インスタンスを生成することができない。
 - 継承することができない。

- **用途**
 - 名前空間（メソッドの一意性の確保...ライブラリ取り込み等でメソッド名の重複を防ぐため）
 - Mix-in（モジュールにメソッドをまとめてincludeして使う)
cloud9をdockerで導入し、NginXでリバースプロキシをかけてサブディレクトリでアクセスする

## 前提

1. `docker`、`docker-compose`はインストールされているものとします。
2. 作業フォルダとファイル構成は以下ファイルツリーの通りです。
3. <a href="#docker-compose.yml">`docker-compose.yml`</a>、<a href="#nginx.conf">`config/nginx.conf`</a>は下記の通りあらかじめ用意しておきます。

```:ファイルツリー
workdir
│ └ docker-compose.yml
│
└─config
  └─ nginx.conf
```
<a href="#docker_compose.yml"></a>

```docker-compose.yml
version: '2'

services:
  nginx-proxy:
    container_name: nginx
    image: nginx
    prots:
      - 80:80
    volumes:
      - ./config/nginx.conf:/etc/nginx/conf.d/default.conf
    links:
      - c9:c9

c9:
  container_name: c9
  image: sshinya/alpine-cloud9
  environment:
    USERNAME: user # 任意のBASIC認証ユーザ名
    PASSWORD: pass # 任意のBASIC認証パスワード
```
<a href="#nginx.conf"></a>

```nginx:config/nginx.conf
server {
  listen 80;
  server_name _;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  location /c9/ {
    rewrite /c9/(.*)$ /$1 break;
    proxy_pass http://c9:8080;
  }

  location ~ /(configs/|static/|vfs/|_ping)(.*)$ {  # _pingの後ろに'/'は無いよ！
    proxy_pass http://c9:8080$request_body;
  }
}
```

## コンテナの作成

```sh
cd workdir
sudo docker-compose up -d
```

`nginx`コンテナと`c9`(cloud9)コンテナが作成され、バックグラウンドで起動します。

`http://<物理サーバIP>/c9/ide.html`にアクセスするとcloud9が起動します。
`<物理サーバIP>`は`192.168.0.32`など、適宜インストールしたサーバのものと読み替えてください。

## おわりに

VPSのWebシェルを利用しているため、コピペが簡単にできず手打ちで記事を書きました。
おそらくtypoのひとつやふたつあると思われますので、動かない等不具合がありましたら、編集リクエストまたはコメントでお知らせください。
k8sのServiceでLoadBalancerをAWSのACMでSSLにする

# 背景

デプロイしたAppなどのEndpointをHTTPSにしたい

# SSL設定する前

access -(http)-> my-service (80) -(http)-> MyApp (9376)

```
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
```

# ACMを使ってSSLにする場合

access -(https)-> my-service (443) -(http)-> MyApp (9376)

```
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: <arn of the ACM>
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
 
spec:
  ports:
  - protocol: TCP
    port: 443
    targetPort: 9376
```


# 参照

https://kubernetes.io/docs/concepts/services-networking/service/#ssl-support-on-aws
エンジニアがキャリア形成を考えるためにおすすめな情報、書籍

どこで働くのか、技術をどこで活かすのか考えたときに、
どの業界で働くのかなどを考えるのに良いと思ったのを自分用にまとめておきます


## 書籍
・転職の思考法
・お金の流れで読む　日本と世界の未来
世界的投資家は予見する

## Net
・FINDY
https://findy-code.io/engineer-lab/company-github-contribution
メルマガでは具体的な企業名も踏まえて
有益な情報を流してくれるので結構おすすめ。
Python3で正規表現を行ったのでまとめ

#正規表現まとめ
Pythonでの文字列検索で正規表現を使いました。何度も調べていたのでまとめ。(自分用です)
##正規表現

| 記号 | 意味 | 例 | 解説 |
|:-:|:-:|:-:|:-:|
|^   |行頭   |^A   |1文字目がAである   |
|^   |文字クラス内で使用すると否定   |[^0-3]   |0123以外   |
|$   |行末   |$A   |最後の文字がAである   |
|.   |任意の1文字   |^.A   |2文字目がAである   |
|*   |0回以上の繰り返し   |[01]*   |-   |
|+   |1回以上の繰り返し   |[01]+   |-   |
|?   |0または1回の繰り返し   |[01]?   |-   |
|{n}   |n回の繰り返し   |[01]{n}   |nは数値   |
|{n,}   |n回以上の繰り返し   |[01]{n,}   |nは数値   |
|{n,m}  |n回からm回の繰り返し   |[01]{n,m}   |nは数値   |
|\   |メタ文字のエスケープ   |\\.   |「.」を意味する   |

##これらを使用して文字列の検索をしてみる。
reモジュールをインポート

```
inport re
```

2文字目がAであるか確認します。

```
ptr="^.A"
com_ptr=re.compile(ptr)    #検索パターンの文字列をコンパイルする
res=com_ptr.search("AABC") #"AABC"の2文字目がAであるか検索
if res==None:              #searchは文字列が存在しない場合の戻り値がNone
    print("2文字目はAではありません")
else:
    print("2文字目はAです")
```

##検索に使用するメソッドまとめ
検索するパターンcom_ptrが"B"、検索対象文字列value_strが"ABCDEFG"とした場合

| メソッド | 内容 | 戻り値 |
|:-:|:-:|:-:|
|com_ptr.search(value_str,開始位置,終了位置)|最も長いパターン文字列の位置を返す|<_sre.SRE_Match object; span=(1, 2), match='B'>|
|com_ptr.match(value_str,開始位置,終了位置)|先頭部分のみ検索   |この例では1文字目がAではないのでNone|
|com_ptr.sub(置換後文字列,value_str)|-   |-   |

以上です。
まだ使いこなせていないので、間違っている部分があれば教えて下さい。
画像ぷかぷかバウンド

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265805/a09ab508-3653-8c0b-38c8-3ba2f2f2192a.gif)


画像をぷかぷかバウンドさせたい


```index.html

      <div class = "ball-wrapper">
          <div class="ball"><img src = "images/image.jpg"></div>
      </div>
```

```style.css



 img {
  margin-left: 10%;
  border-radius: 50%;   /*角丸半径を50%にする(=円形にする)*/ 
  width:  250px;       /* ※縦横を同値に */
  height: 250px;       /* ※縦横を同値に */
  position: absolute;
  -webkit-animation: jump 1s infinite;
  -moz-animation: jump 1s infinite;
  animation: jump 5s infinite;  /* ※落下時間 */
}



/**
 *  animation
 */

@-webkit-keyframes jump {
    0% {
  top: 510px;
  -webkit-animation-timing-function: ease-in;
    }
    40% {}
    50% {
  top: 600px;
  /*height: 120px;*/
  background-color: yellow;
  -webkit-animtion-timing-function: ease-out;
    }
    100% {
  top: 510px;
  -webkit-animation-timing-function: ease-in;
    }
}

@-moz-keyframes jump {
    0% {
  top: 0;
  -moz-animation-timing-function: ease-in;
    }
    40% {}
    50% {
  top: 35px;
  height: 120px;
  -moz-animtion-timing-function: ease-out;
    }
    100% {
  top: 0;
  -moz-animation-timing-function: ease-in;
    }
}

```


参照：　http://tmlife.net/web/css3/css3-3d-ball-bound.html
SORACOM ひげボタンが届いたのでGWの自由研究をしてみた。

区役の草刈りが終わって帰宅したらSORACOM LTE-M Button Plusが届いてた。
なので、GWの自由研究開始。

![IMG_9857.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/fa5bf969-9502-f976-5f53-0c7d8e895f71.jpeg)
接点のヒゲがついてます。
ボタン本体にはそれを接続するコネクタが。


![IMG_9860.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/9aa2f3d2-d5d4-ca57-658d-fcee98f6ad04.jpeg)
単4電池挿入してボタンをポチッとな。



![IMG_9861.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/867d3f89-5da1-70ea-2d24-bc07058f2353.jpeg)
LEDが無事にグリーンに点灯。


![スクリーンショット 2019-04-28 13.22.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/60bf054d-d3b5-bc12-9100-6998cfbbd579.png)
最初は取り敢えずHarvestの設定だけをしたグループに所属させる。

![スクリーンショット 2019-04-28 13.22.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/34dab1df-947d-0dfc-0771-1f764af2d48b.png)
なんか、ゴニョゴニョっとしたデータが飛んできてるのがわかります。

![スクリーンショット 2019-04-28 13.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/99fb2e11-9994-fc21-3f47-26abc5ff033f.png)
ゴニョゴニョ部分をわかるようにするため、
バイナリパーサをONにして@buttonを設定。

![スクリーンショット 2019-04-28 13.24.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/fd51efc3-f79c-ce3c-8c7e-81553ef5311b.png)
Harvestを設定。

![スクリーンショット 2019-04-28 13.25.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/f38412ea-2401-fa07-c9ae-a9fe7cc7e56b.png)
再度ボタンをポチッと押すと送信されたデータを見ることができます。
LTE-M Button Enterpriseと同様にSingle、Duble、Longのクリックを識別できます。

次に接点のテスト

![IMG_9862.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/3938963d-2d7f-7da2-bbf5-02907ed8f13f.jpeg)
ボタン本体のコネクタ

![IMG_9865.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/e6e9232e-b9ad-8b6f-ddc6-b8fc8c9f4c54.jpeg)
ヒゲを接続。


![IMG_9866.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/9fbd034d-6ad3-4f88-6bae-092c17fdcae2.jpeg)
ヒゲの先端部分をショートさせると


![スクリーンショット 2019-04-28 13.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/c957b7aa-e8c7-7ac3-2513-1e59fd2d4ab5.png)
このようにデータが上がってきました！

![スクリーンショット 2019-04-28 13.32.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123239/8e7eadb0-4f2f-b943-7919-7f1bef087863.png)
接点を接触させっぱなしにするとLong
接点を一瞬だけ触れさせるとSingle
接点を2回ちょんちょんと接触させるとDouble
と、ボタンと同じ様に反応してくれました。

接点の接触方法はLongだけかなと思っていたのですが、SingleとDoubleの区別ができるのは嬉しいポイント。

取り急ぎ、今日はここまで。
あとで何か追記するかも。
lint, prettier導入編（mac）

## lint導入

### lintってなに？

文法チェック用のプログラムです。
エラーの発生を防いだり、バグの原因となるような記述をチェックしたりできます。

#### どんな種類があるのか

特にフロントよりのことをすることが多いので、関連したものを抜粋します。

| lintツール名       | 対象ファイル       | 参考URL       |
|:-----------------|:------------------|:------------------|
|htmlhint             |             htmlファイル| https://www.npmjs.com/package/htmlhint|
|stylelint            |             cssファイル | https://www.npmjs.com/package/stylelint|
|eslint            |             jsファイル | https://www.npmjs.com/package/eslint|


#### どんな特徴があるのか

前述の通り、**エラーやバグを未然に防げます。**
かなり厳密なチェックが行われるため、例えばセミコロンを省略しないようにするというようなルールを設定すると、セミコロンを全て書かない限り、警告は消えません。

また、それに付随してどういったエラーや警告が発生しているのかも表示してくれるため、**エラーの原因が把握しやすい**です。
（例えば、XX行目にセミコロンが抜けているなどですね。）

ルールを設定すると、というような記載もしましたが、その他にも**独自のルールを設定できます。**
それにより、プロジェクト毎のルールなども追加でき、より完成度の高いコーディングができます。


### lintツールのインストール

※npmを用いてインストールします。
※ローカルにインストールしますので、対象のプロジェクトまで移動した後、実行ください。

package.jsonが存在しない場合は、以下のコマンドにて作成してください。

```sh
npm init -y
```


#### htmlhintのインストール
 
```sh
npm i -D htmlhint
```

lintの実行は、`npx htmlhint ファイルパス or ディレクトリパス`です。

#### stylelintのインストール

```sh
npm i -D stylelint
```

続いてルールセットのインストールを行います。
特にこだわりなどがなければ、スタンダードで大丈夫だと思います。

```sh
npm i -D stylelint-config-standard
```

インストールは完了しましたので、このルールを適用します。
適用方法として、今回はpackage.jsonに追記します。
（その他、.stylelintrcに追記などありますが、下手にファイルを作成せずともよい方法を採用しました。）

以下のように追記できればOKです。

```sh
  "devDependencies": {
    "stylelint": "^10.0.1",
    "stylelint-config-standard": "^18.3.0"
  },
  "stylelint": {
          "extends": "stylelint-config-standard"
  }
```

lintの実行は、`npx stylelint ファイルパス or ディレクトリパス`です。


#### eslintのインストール

```sh
npm i -D eslint
```

初期設定として以下のコマンドを実行し、プロジェクトに沿うようにQAにお答えください。

```sh
npx eslint --init
```

lintの実行は、`npx eslint ファイルパス or ディレクトリパス`です。

## Prettier導入

### Prettierってなに？
インデントの数やスペースの位置などを自動整形するツールです。

### Prettierのインストール

以下でインストールします。

```sh
npm i -D prettier
```

`npx prettier ファイル名`で整形が実行されます。
ただ、このままでは単純に整形後の状態が確認できるだけなので、整形後の状態をファイルに上書きするようにオプションを追加します。

```sh
npx prettier --write ファイル名
```

`--write`は上書き保存用のオプションです。
bit全探索 AtCoderでよく見かける書き方

全部分集合を列挙します。

```Rust
fn main() {
    let v = vec!["A", "B", "C", "D"];
    // 1 << d := pow(2, d)
    for i in 0..1 << v.len() { // -- (1)
        print!("{{");
        for j in 0..v.len() {
            // iのj番目ビットが立っているか -> jがiに含まれるか
            if (1 << j) & i == 0 { // -- (2)
            // 又は if i >> j & 1 { 
                print!("{}", v[j]);
            }
        }
        print!("\n");
    }
}

/*
{ABCD
{BCD
{ACD
{CD
{ABD
{BD
{AD
{D
{ABC
{BC
{AC
{C
{AB
{B
{A
{
*/
```

上記の(2)は

```c++
 if i >> j & 1 {
```

と書くことができます。この場合(1)の部分を

```c++
for i in 1..1 << v.len() {
```

とすることで空集合を含まないようにすることができます。

# 参考
[ビット演算 (bit 演算) の使い方を総特集！ 〜 マスクビットから bit DP まで 〜
](https://qiita.com/drken/items/7c6ff2aa4d8fce1c9361)
git diffの結果をpandasのDataFrameを加工する

### 目的
とあるリポジトリからtag間のgit diffの結果を取得し、変更行数の統計情報を取りたい
コマンドでフィルタして取得してもよいのだけれどPandas DataFrameで加工したい

### コマンド
jupyter notebookで以下実行
!付きで実行した結果の標準出力はIPython.utils.text.SListで取得できる。
今回の場合は
'<更新行>\t<削除行>\t<パス>'
の形式になっているので

~~~
diff = !git diff --numstat tag1..tag2
df = pd.DataFrame(list(map(lambda x:x.split('\t'),diff)
~~~

あとは、<パス>でフィルタしたり、DataFrameで統計取ったり煮るなり焼くなり。
Android ripple effect（Custom View）

＜目的＞
　釦とかタップしたときに、どこをタップ中なのか明確にわかるようにする。

＜方法＞
　正直いろいろある。
　　案１．XMLにタップ時の挙動を定義する。
　　　https://qiita.com/ujikawa1026/items/a79d418b70d88d1d69ba
　　案２．「material ripple」っていうAPIを使う。
　　　別サイト：https://github.com/balysv/material-ripple

＜前提＞
　俺、ロジックで色、フォント、サイズをデザインしているんだ。
　XML（案１）なんて固定なものじゃなく、自由（案２）に設定したい。
　というか、独自で背景色、色、フォント、サイズ等の設定もってるからXMLよりそっちがいい。

＜難点＞
　１．対象のビューが非表示(Invisibility)、存在しない(Gone)の場合、
　　　ripple effect（のビュー）が残存する。
　２．簡単にメソッド内で定義したいんだよね…。
　　　→findViewByIDで検索したViewを毎回コール・・・！？（面倒）
＜解決＞
　・カスタムビュー・・・！

```java:yourCustomView.java
    // 難点１．の解決策
    @Override
    public void setVisibility(int visibility){
        // タップしたときにこのビューが無効（[invisibility]or[GONE]）
        // にもかかわらず設定できるのを防止する。
        super.setVisibility(visibility);
        if(getParent() instanceof MaterialRippleLayout){
            ((MaterialRippleLayout) getParent()).setVisibility(visibility);
        }
    }

    // 難点２．の解決策
    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        switch (visibility){
            // ビューが表示中の時に動的に変更
            case VISIBLE:MaterialRippleLayout.on(changedView)
                            .rippleColor(Color.GREEN)
                            .rippleAlpha(0.5f)
                            .rippleOverlay(true)
                            .rippleHover(true)
                            .rippleDuration(100)
                            .create();
                break;
            // 何もしない。
            case INVISIBLE:
                break;
        }
    }
```
以上、よろしくお願いいたします。
Pythonのselfとかinitを理解する

本投稿のモチベーションとして、これまで2年ほどPythonを使って色々やった中で、未だにselfとかinitという構文を理解し使いこなせていない事に気後れを感じており、GWの10連休を利用して学習を進めようというものである。

#Pythonにおけるクラスの理解
Pythonではクラスという機能を利用してより便利に関数を取り扱うことが出来る。
普通に関数を書くと下記のような記述となるが、

```python:function.py
def some_function(something):
    print(something)
```
クラスを利用した場合、次のような記述となる。

```python:function_class.py
class some_class:
    def __init__(self,something):
        self.something = something
        
    def some_function(self):
        print(self.something)
```
クラス構造を用いる理由は、主に大規模なソフトウェアの構築の際の効率化にあるらしく、小規模なコードであれば普通に関数だけ書いていくやり方でも混乱は起きない模様。参考までにどのような場合でクラスの活用が有効かを調べたところ、[こちら](https://teratail.com/questions/10814)には、次のメリットの記載があり。
・グローバル変数を無くし、すべての変数を何らかのスコープに属させる
・処理を効率的に使い回す
・一つの処理は一つの箇所に実装し、修正箇所を最小化する
・関数実行中に、関数自身が再度呼び出される場合の対処

##クラスとインスタンス
こちらの記事にもあるように、Pythonのクラス構造はインスタンスの生成により、その処理を実行することが出来る。
[Pythonでクラスのインスタンスの生成と初期化](https://uxmilk.jp/39906)
インスタンスは英語でinstance(=例、事例)であり、次のコードの変数aの部分がインスタンスになる。先ほどのコードのクラス（some_class）のインスタンスを生成している。

```python:instance.py
a = some_class("some_value")
```
インスタンスを生成することで、クラスの中で記述した関数を呼び出すことが出来る。まとめて書くと次の通り。

```python:function_class.py
class some_class:
    def __init__(self,something):
        self.something = something
        
    def some_function(self):
        print(self.something)
a = some_class("some_value")
a.some_function()
#関数としてprintを用いているのでsome_valueを返す
```


##クラスとメソッド
クラスの中で記述される関数をメソッドと呼ぶ。クラス内で複数のメソッドを定義することも可能。

```python:method.py
class some_class:
    def __init__(self,something):
        self.something = something
        
    def some_function1(self):#メソッド1
        print(self.something)

    def some_function2(self):#メソッド2
        return self.something
```
##selfの役割
これまでのクラスの中で用いられたselfについて調べると「インスタンス自身」、「その時点の自分」、「メソッドの仮引数」など様々な呼び方があるが、クラス構造を取る際の定型の構文として覚えておけば良さそう。

#initの理解
selfと並んでクラス構造の中に登場したinitについては、[こちら](https://ct-innovation01.xyz/DL-Freetime/python01/)には下記の説明がある。
・コンストラクタと呼ばれる初期化のための関数（メソッド）
・インスタンス化を行う時に必ず最初に呼び出される特殊な関数（メソッド）
・オブジェクト生成（インスタンスを生成）のついでにデータの初期化を行うもの

```python:constructor.py
class some_class:
    def __init__(self,something):#constructor
        self.something = something
```

クラス構造で情報を保持するための重要な構文なので外せない、と覚えておけば良さそう。この構文により、オブジェクト生成時の情報の追加が簡潔に記述出来る。
例えば複数の情報を変数とするクラス構文での処理を行いたい場合は次のような記述になる。

```python:sample.py
class my_status:
    def __init__(self,age,name,height,weight):
        self.age = age
        self.name = name
        self.height = height
        self.weight = weight
 
    def print_name(self):
        print(self.name)
        
    def print_age(self):
        print(self.age)
    
    def print_height(self):
        print(self.height)
    
    def print_weight(self):
        print(self.weight)

a = my_status(34,"yamada",170,78)#34才、山田さん、170cm、78kgという情報を追加してオブジェクト生成
```
#終わりに
これまでインスタンス化、オブジェクトなど馴染みのない単語から敬遠していたself、initについても、自分で調べてまとめて見ると何となく理解することが出来たので、まだよく理解できない場合は自分でまとめて見ると良いかと思う。
さくっとAndroidアプリでAppIndexingに対応するには！

# 概要

概要は[こちら](https://developers.google.com/app-indexing/)を参照していただくと早いです。
要は検索窓にキーワードを入力した、あるいは検索を実行した際のキーワードとアプリを紐付けする技術です。

# 用語

*クローラー*
検索エンジンがWebサイトの情報を取得する際に、クローラーがWebサーバから情報を取得します。また、AppIndexingAPIの通信内容やアプリ内のManifestファイルもクロール対象になります。

*Schema.org*
検索エンジンがWebサイトの内容を解析しやすくするためのマークアップ技術です。

*Search Console*
Webサイトの検索結果を運用管理するツール。（昔はGoogle ウェブマスターツールという名前のツールでした）

*rotots.txt*
検索エンジンがWebサイト内のどの部分の情報を取得するかを確認するファイルです。

*noindex.xml*
検索エンジンがAndroidアプリ内のどの部分の情報を取得しないかを確認するファイルです。

# 実装方法
実装方法の詳細は[こちら](https://developers.google.com/app-indexing/introduction)を参照すると早いです。

## AndroidManifest.xmlに以下を追加
- AppIndexingのライブラリを追加
- URLスキーマの記述を追加

## プログラムの以下の部分を追加・修正
- 各画面にURLとURIのリンクを埋め込む
- アプリがURLスキームから起動できるようにする修正

## 注意点
- APIのoutLinkの項目は非推奨となりましたので、今後は設定しない方がよいでしょう。
- APIにDescriptionという項目が存在するが、設定する方法がドキュメントに記述されていない。また、設定しているアプリも見つからない。

# 確認方法
## Indexされた情報を確認する
下記のコマンドをコンソールから入力するとAppIndexingAPIのログを確認することができます。
実際にアプリを動かしてコンソールにログが表示されればIndexingが成功したことになります。
実際に検索結果に反映されるかどうかはクローラーに依存します。
### ログレベルを変更する
`adb shell setprop log.tag.AppIndexApi VERBOSE`
### Indexされたログを表示する
`adb logcat -v time -s AppIndexApi:V` 

# 知見

1. サジェストはAppIndexing APIで設定されたタイトルを元に表示されている様子。
1. Googleの検索結果に反映される情報はサイトマップ・アプリAPI・HTMLメタ情報・AndroidManifestファイル等を元に表示されている様子。
【備忘録】さくらVPS+CentOS7でsudoコマンドを使えるようにする方法

##現状

さくらVPS+CentOS7でサーバを構築する際にソフトウェアのアップデートをしようとした。
`sudo yum update`コマンドを入力したが以下のメッセージが出て実行できなかった

```
$ sudo yum update
[sudo] password for daichang: 
daichang is not in the sudoers file.  This incident will be reported.
$ 
```

##解決策
###①rootユーザになる

```
$ su - root
Password: 
# 
```

###②`visudo`を実行しファイル内に `ユーザ名  ALL=(ALL)  ALL` を付け加える

```
# visudo

## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root        ALL=(ALL)       ALL
daichang    ALL=(ALL)       ALL
```

※ /etc/sudoersを書き換えればいいらしいが、rootユーザにも書き込み権限がないためらしい。

##参考サイト

[さくらVPS+CentOS：自分をsudoユーザに追加してみた](https://suin.io/473)
for 3

```shell

#include <stdio.h>

#define LINE 9
#define ROW 9

int main(void) {
	int n, i;

	
	/*titleの表示*/
	printf("*　*　*　九九の表　*　*　*\n   |   1  2  3  4  5  6  7  8  9\n---------------------------------\n");

		for (n = 1; n <= LINE; n++) {
			printf(" %d | ", n);
			for (i = 1; i <= ROW; i++) {
				printf("%3d", n * i);
			}
			printf("\n");
		}
	return 0;
}
if 3

```shell

#include <stdio.h>
int main(void) {
	int i, amari;

	for (i = 100; i >= 1; i--) {
		amari = 100 % i;
		if (amari == 0) {
			printf("100は %d で割り切れる\n",i);
		}
	}
	return 0;
}
ElixirでPaizaのD問題

# ElixirでPaizaのD問題を解いてみた
実際に提出したコードと問題番号を公開したいところなのだけど、Paizaは解法の公開を禁じているので、類題を作問してその解答を載せていく。

##2倍にせよ
整数が入力されるので2倍して表示しなさい。

```
a = IO.read(:stdio, :line)
b = String.trim(a)
IO.puts String.to_integer(b) * 2 
```

初めてElixirで解いた問題。何もわからないところからスタートしたので、20分ぐらいかかってしまった。
Elixirは引数の括弧を省略できるのだが、省略した場合、1行に複数の処理を書く方法がわからない。

##0をN回表示せよ
0をN回表示しなさい。

```
count = String.to_integer(String.trim(IO.read(:stdio, :line))) 

defmodule My do
  def loop(0) do
  end

  def loop(times) do
    IO.write "0"
    loop(times - 1)
  end
end

My.loop count
```

Elixirにはループが存在しないので、かわりに再帰を使うらしい。うまくライブラリ化すれば再帰は意識しなくてよいかも？

##XをPに置換せよ。

2文字の文字列（例：XX、SS）が入力されるので、1文字目がXだった場合はPに置換して出力せよ。

```
str = IO.read(:stdio, :line)

if (String.at str, 0) == "X" do
  IO.write "P"
else
  IO.write String.at str, 0
end
IO.write String.at str, 1
```
はじめてのあっとこーだー @scala

プログラミングコンテスト界の Hello World こと、
[A - Welcome to AtCoder](https://language-test-201603.contest.atcoder.jp/tasks/practice_1)
なんですが。

Scalaの解答例をそのまま paiza.io に入れてみたところ、

```
warning: there were three deprecation warnings (since 2.11.0); re-run with -deprecation for details
one warning found
```

というワーニングメッセージが出ました。
どうやら `readInt` とか `readLine` が deprecation な模様。

```scala

object Main extends App{
    import scala.io.StdIn.readLine

    val Array(a) = readLine split " " map(_.toInt)
    val Array(b, c) = readLine split " " map(_.toInt)
    val Array(s) = readLine split " "

    println(a+b+c + " " + s)
}
```

値が1個なのにsplitとか入ってておかしいですが、とりあえずワーニングは出なくなったので、メモ。
if ①

```shell

#include<stdio.h>

int main (void) {
	char kamoku;
	int ten;

	printf("科目を入力してください(k:国語　s:数学) > "); //
	scanf("%c", &kamoku);
	printf("点数を入力してください > ");
	scanf("%d", &ten);

	if (kamoku == 'k') {
		if (ten >= 73 && ten <= 100) {
			printf("国語の点数は平均点以上です");
		}
		else if (ten <= 0 && ten < 73) {
			printf("国語の点数は平均点以下です");
		}

		else {
			printf("点数の入力エラーです");
		}
	}
	else if (kamoku == 's') {
		if (ten >= 61 && ten <= 100) {
			printf("数学の点数は平均点以上です");
		}
		else if (ten >= 0 && ten < 61) {
			printf("数学の点数は平均点未満です");
		}
		else {
			printf("点数の入力エラーです");
		}

	}
	else {
		printf("科目の入力エラーです");


	}
	return 0;
}
HTML&CSSの学習記録１

##日付
４月２６日、２８日（時間：７６分　Togglで管理）

##教材
progate:HTML & CSS 学習コース 初級編 1〜13

分からないときは下記を参考にしました
[mdn html](https://developer.mozilla.org/ja/docs/Web/HTML)
[mdn css](https://developer.mozilla.org/ja/docs/Web/CSS)

## 感想
ドットインストールですでに講座を終えていたからついていけたが、何も知らない状態でやっていたら挫折していたと思う

## 気になったこと
同じコードをATOMに引き写して確認していた時、プレビューどおりにならなかった（レッスン１３）

リストとタイトルの下に空白が出現（コードは下記）

```html:index.html
      <div class="header-logo">
        XXXXX
      </div>

      <!-- <div>要素を追加し、「header-list」というclassをつけてください -->
      <div class="header-list">
        <ul>
          <li>1</li>
          <li>2</li>
          <li>3</li>
        </ul>
      </div>
```
XXXXX
→この空白が謎←
li1
li2
li3

検証するとulのmarginと判明

とりあえず下記のコードで対処

```css:stylesheet.css
ul{
  margin-top: -6px;
}
```
きれいな対処方法かはわからないが、同じようになった
印刷・PDF出力のCSSを書いたときの知見まとめ

## 経緯

オープンソースなタイムトラッキングアプリ「[Hackaru](https://www.hackaru.app)」 を開発しているのですが、レポート画面を印刷したり、PDF出力したいといったフィードバックを多くいただきました。
そこで今回は、印刷フォーマットを整えるCSSについていくつか纏めてみました。

## Before
何も設定せずにレポート画面を印刷した画面が以下です。
いい感じに崩れていますね。ここから直していきたいと思います。
![Reports_before-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407015/ca71fd75-cc1f-a415-57da-8862ec240168.png)


## mediaで印刷専用レイアウトを作成する

`@media print` を使って印刷専用のCSSを記述してあげます。
CSSなので `display: none;` などを使えば非表示にしたりしなかったりできます。

特に文字色については、薄い色を使っていると紙面では見づらいため、
濃いめの色(#000)に設定してあげると良さげです。

```css

/** 通常のCSS */
body {
  color: #555;
}
.menu {
  display: block;
}
...
/** 印刷用のCSS */
@media print {
  body {
    color: #000;
  }
  .menu {
    display: none;
  }
}
```

## 背景色を表示する

インク節約のためか、デフォルトでは背景色(background-color)は表示されないようになっています。
そのため、`print-color-adjust` で背景色が表示されるように設定してあげます。

```css
@media print {
  .logo {
    background-color: #000;
    -webkit-print-color-adjust: exact; /** for Safari, Chrome */
    print-color-adjust: exact; /** for Firefox */
  }
}
```

## After

CSSだけでここまで綺麗にレイアウトできました。素晴らしいですね。

![Reports_before-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407015/63689de9-151c-7f2b-01e1-d56b92356abe.png)

## 参考文献
- https://developer.mozilla.org/ja/docs/Web/CSS/color-adjust
- https://webtan.impress.co.jp/e/2015/07/28/20508
今年の言語はRust その４０

# 今年の言語はRust その４０

Rustを学びます

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル(英語)
https://doc.rust-lang.org/book/


## 実行環境

```sh
$ cargo -V
cargo 1.33.0 (f099fe94b 2019-02-12)

$ rustup -V
rustup 1.17.0 (069c88ed6 2019-03-05)

$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

$  cat /proc/version
Linux version 4.14.97-74.72.amzn1.x86_64 (mockbuild@gobi-build-64002) 
(gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC)) 
#1 SMP Tue Feb 5 20:59:30 UTC 2019

$ uname -a
Linux ip-10-100-0-8 4.14.97-74.72.amzn1.x86_64 
#1 SMP Tue Feb 5 20:59:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/\*release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Amazon Linux AMI release 2018.03

```

## 14 CargoとCrates.ioについてより詳しく

__Cargo__ の様々な機能を紹介

その他詳細はドキュメントを参照されたし

[Introduction - The Cargo Book](https://doc.rust-lang.org/cargo/)

### 14.1 リリースプロファイルでビルドをする

cargo buildには__dev__と__release__の2種類のプロファイルが用いられている。


```rust
$ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 1.55s

$ cargo build --release
    Finished release [optimized] target(s) in 0.37s
```

例えば、Cargo.tomlにて、デフォルトでコンパイラの最適化度合いが制御されている

デフォルト値は記述されていないが、以下のように設定し、上書き可能である。

```rust
[profile.dev]
opt-level = 1

[profile.release]
opt-level = 3
```

>設定の選択肢と各プロファイルのデフォルト設定の一覧は、[Cargoのドキュメンテーション](https://doc.rust-lang.org/cargo/)を参照されたし。


イエス！
アプリダウンロードボタンを作る

AppleStoreやGooglePlayににリンク貼る

LinkMakerでアプリを検索
https://linkmaker.itunes.apple.com/ja-jp

アクセスしてきたデバイスで挙動を変えられるMobileDetect
https://github.com/serbanghita/Mobile-Detect

以下コード

```php:sample.php
<?php 
require_once 'Mobile_Detect.php';
?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>software download sample</title>
</head>
<body>
    <?php
      $detect = new Mobile_Detect;
      if( $detect->isiOS()){
        echo '<a href="https://itunes.apple.com/jp/app/%E3%82%A2%E3%82%A4%E3%83%89%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E3%82%B7%E3%83%B3%E3%83%87%E3%83%AC%E3%83%A9%E3%82%AC%E3%83%BC%E3%83%AB%E3%82%BA-%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%88%E3%82%B9%E3%83%86%E3%83%BC%E3%82%B8/id1016318735?mt=8" 
        style="display:inline-block;overflow:hidden;background:url(https://linkmaker.itunes.apple.com/ja-jp/badge-lrg.svg?releaseDate=2015-09-10&kind=iossoftware&bubble=ios_apps) no-repeat;width:135px;height:40px;"></a>';

      } else {
        echo '<a href="https://itunes.apple.com/jp/app/%E3%82%A2%E3%82%A4%E3%83%89%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E3%82%B7%E3%83%B3%E3%83%87%E3%83%AC%E3%83%A9%E3%82%AC%E3%83%BC%E3%83%AB%E3%82%BA-%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%88%E3%82%B9%E3%83%86%E3%83%BC%E3%82%B8/id1016318735?mt=8" 
        style="display:inline-block;overflow:hidden;background:url(https://linkmaker.itunes.apple.com/ja-jp/badge-lrg.svg?releaseDate=2015-09-10&kind=iossoftware&bubble=ios_apps) no-repeat;width:135px;height:40px;"></a>';
      }
    ?>
</body>
</html>
```
Serverless Next.jsをCloud Functionsにデプロイする

Next.jsとFirebaseで個人開発をしています。その際にNext.jsのexamplesを見ると従来のserver modeでの例はありましたが、Next.js 8で追加されたserverlessモードの例はなくちょっと困ったので、記事に残しておきます。

## Serverless Next.js

https://nextjs.org/blog/next-8#serverless-nextjs

next.config.jsに`target: 'serverless'`を指定すると有効になる。

ページ単位でビルドされ`.next/serverless/pages`以下に出力される。

```公式ページの例
pages/index.js => .next/serverless/pages/index.js
```

例えばNode.jsのhttpモジュールを使った際のコードは次のようになる。（公式サイトの例より）

```公式ページの例
const http = require('http')
const page = require('./.next/serverless/about.js')
const server = new http.Server((req, res) => page.render(req, res))
server.listen(3000, () => console.log('Listening on http://localhost:3000'))
```

## Cloud Functions

以上のことを抑えてCloud Functions形式のコードを書くと次のようになる。
ビルド後のパスを指定して各ファイルごとにexportするのがポイント。

```
const onRequest = require('firebase-functions').https.onRequest

const index = require('./next/serverless/pages/index')
const about = require('./next/serverless/pages/about')

exports.index = onRequest((req, res) => index.render(req, res))
exports.about = onRequest((req, res) => about.render(req, res))
```

## 参考
https://nextjs.org/blog/next-8#serverless-nextjs
Ajax理解に必要な知識　集めました

いろいろな記事を読んだついでに備忘録

要約読んでざっくり理解した上で読んでから最後にもう一度要約を
読んだらわかりやすいかもしれません。

#要約　Ajax
①ページ上でなにかする（クリック、送信ボタンを押す等）
②サーバーに対してリクエスト送信　（非同期通信）
③ほしい情報、返ってくるレスポンスの情報を指定してリクエスト
④サーバーで受け取った情報を処理
⑤サーバーの処理中もクライアントは操作を継続できる（非同期通信）
⑥処理結果をJSONやXMLなどの形式で応答（データのやり取りをしやすい形に変換してやり取り）
⑦受診したレスポンスを受けて、DOM（ページの見た目を変える操作のこと）でページを更新
⑧更新のあった部分だけを書き換えるため、ページの移動はなし。
これがAjaxの動きの流れ



#Ajaxとは
「Asynchronous JavaScript + XML」の略
Asynchronous　= 非同期
JavaScriptとXMLを使って非同期にサーバとの間の非同期に通信を行うこと
##XMLとは
「Extensible Markup Language」の略　拡張可能なマークアップ言語という意味。

XMLは、文章の見た目や構造を記述するためのマークアップ言語の一種です。
主にデータのやりとりや管理を簡単にする目的で使われ、記述形式がわかりやすいという特徴があります。

一方、HTMLも XML と同じマークアップ言語のひとつです。
####HTMLとの違い
HTMLとは「Hyper Text Markup Language」の略です。Webページを記述するための表示用言語で、XMLと同じく文章中の文字列をタグで挟むことで、Webページに装飾を施すのが目的です。簡単にいうと、人間に情報をわかりやすく表示するための言語といえます。

一方のXMLは、データ記述用の言語です。文書中のデータをわかりやすくしたり、データを交換したりできます。マシンに情報をわかりやすく、効率よく伝えるための言語といっても良いでしょう。

##Javascriptとは
「JavaScript」とは、動的なWebページを作成する事のできるプログラミング言語です。 通常はブラウザー上で実行されます。 JavaScriptを使うと、ユーザーのアクションに応じたコンテンツの表示の他、ブラウザー上で表示される地図やグラフィックアニメーションなども表示する事ができます。
要はページに動きをもたせる事ができます。

##非同期通信とは
ネットワークなどでつながれているコンピュータ間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式。 同期通信はデータ通信のリクエストを出してからレスポンスが来るまでほかの処理を行わずにレスポンスを待ち続けるが、非同期通信ではレスポンスを待っている間にほかの処理を行える。

#ここまでの要約
いちいち通信しなくてもDBとのやり取りだけで必要な処理を行えるということです。
画面の移動なしにデータを表示、変化させることが可能になります。
Google Map使っているときに縮尺変えるたびにブラウザがページの移動をしていたら
面倒臭いですよね
それをて手っ取り早く行えるのが　非同期通信です。

#Ajaxはどうやって動いているの？
XMLHttpRequest
JavaScript
DOM
XML
上④つの機能をあわせてAjaxが成り立っています。
説明は書きを御覧ください。

##XMLHttpRequest
説明①
クライアントとサーバーの間でデータを伝送するための機能をクライアント側で提供する API です。ページ全体を再読み込みすることなく、URLからデータを読み出す簡単な方法を提供します。このAPIによって、ユーザの作業を中断させることなくWebページの一部を更新することができます。

説明②
Ajax (非同期通信) に使われる組み込みオブジェクトのこと.XHR を使うとサーバから受信済みの web ページから、さらにサーバへ通信リクエストを送ることができるようになる.

##Javascriptとは
「JavaScript」とは、動的なWebページを作成する事のできるプログラミング言語です。 通常はブラウザー上で実行されます。 JavaScriptを使うと、ユーザーのアクションに応じたコンテンツの表示の他、ブラウザー上で表示される地図やグラフィックアニメーションなども表示する事ができます。
要はページに動きをもたせる事ができます。

##Json
JavaScript Object Notationの略。
軽量のデータ交換フォーマットで、人間にとって読み書きが容易で、マシンにとっても簡単にパースや生成を行なえる形式です。

##DOM
DOM（Document Object Model）とは、xmlやhtmlの各要素、たとえば<p>とか<img>とかそういった類の要素にアクセスする仕組みのことです。このDOMを操作することによって、要素の値をダイレクトに操作できます。

#要約　Ajax
①ページ上でなにかする（クリック、送信ボタンを押す等）
②サーバーに対してリクエスト送信　（非同期通信）
③ほしい情報、返ってくるレスポンスの情報を指定してリクエスト
④サーバーで受け取った情報を処理
⑤サーバーの処理中もクライアントは操作を継続できる（非同期通信）
⑥処理結果をJSONやXMLなどの形式で応答（データのやり取りをしやすい形に変換してやり取り）
⑦受診したレスポンスを受けて、DOM（ページの見た目を変える操作のこと）でページを更新
⑧更新のあった部分だけを書き換えるため、ページの移動はなし。
これがAjaxの動きの流れ

いろいろな用語がでてきて理解しづらいと思いますが
一つずつ噛み砕いて理解していきましょう。

#引用させていただきましたリンク
https://qiita.com/hisamura333/items/e3ea6ae549eb09b7efb9
https://hnavi.co.jp/knowledge/blog/xml/
http://proengineer.internous.co.jp/content/columnfeature/11532
https://www.atmarkit.co.jp/aig/07wcr/hidouki.html
http://piyo-js.com/05/dom.html
インフラの勉強前に押さえておきたい最低限の基礎知識①〜初心者向け〜

## 概要
この記事はインフラ周りの勉強をする際に、どんなことを知っていなければならないのかについて、概要のみをざーーくりとまとめたものです。
次回以降の記事は（書くとしたら）、今回の内容について少し踏み込んだ内容を行って行きます。

目次

- コンピューターネットワークとは
- ネットワークの種類



## インターネットとは
コンピューター同士で通信のやりとりができるような状態にある時、それらのコンピューターは同一のコンピューターネットワークに属していると言えます。

世界で最大のコンピューターネットワークがインターネットです。

## サーバーとクライアントの違い
ネットワークに属するコンピューターはサーバーとクライアントの２種類に分けられます。

サーバー・・・なんらかのサービスなどを返すコンピューター
クライアント・・・サービスへのリクエストを行うコンピューター

## コンピュータネットワークの構成
コンピュータ間で通信が行われる時、たくさんの処理が行われます。
その処理を機能ごとに以下のようにグループ化されています。

（TCP/IP参照モデル）
①アプリケーション層
②トランスポート層
③インターネット層
④ネットワークインターフェース層

の４つです。

#### アプリケーション層
実際のサービス機能を提供する部分。

ウェブアプリケーションでいうと、URLを送ったり、リクエストを受けて特定のページを返す機能などがこの部分にあたります。


#### トランスポート層
データを『正しく』宛先に渡すためのルールについて定めた部分。

データの再送などもこの階層が行います。

#### インターネット層
コンピューターのアドレスを使用して、データを輸送することについて定めた部分

#### ネットワークインターフェース層
物理的に繋がっているネットワークの次の場所まで届けることを定めている部分。
ルーターからルーターなどまでのみを考える部分。

## プロトコルとは

簡単にいうとルールです。

コンピュータ間で通信をする際に、このルールにしたがって、こういう形でデータを送ってくれなどの取り決めがあり、プロトコルと読んでいます。

英語と日本語でそれぞれが話しても、お互いに理解できませんよね。

なので、こういう文法でこういう単語を使って通信するよっていうルールを前提に、コンピューターは通信をします。

HTTPS、sshなど様々なプロトコルが存在します。

## インターネットのプロトコル
TCP/IPと呼ばれるHTTPやIPなどを含めたプロトコル群を使用しています。

これらはOSなどの違いを超えて取り決められています。




#### 参考文献
https://wa3.i-3-i.info/word11093.html
https://www.amazon.co.jp/dp/4797396075/