OmniAICreator/Qiita-1.07M huggingface dataset:
競プロ参戦記 #38 Reversi | AGC 31

久しぶりの AGC でしたが、参加しなかったので参戦記ではなく練習記です。

2時間測ってやってみたところ、ぎりぎりB完 + ペナルティ35分なので950位ぐらいでした。(コンテスト時間は160分ですが、いましがたまで120分だと思いこんでいました。)

## 競プロ参戦記

この連載記事では、着手した問題の考察を自分なりに書いていきます。

- 問題の詳細はリンク先を参照してください。
- 前回: [競プロ参戦記 #37 Skyscrapers | CR #545 Div.2 - Qiita](https://qiita.com/vain0x/items/cd075fd5229fa6ec5ef5)

## AtCoder Grand Contest 031

- 問題一覧: https://atcoder.jp/contests/agc031/tasks

## A - Colorful Subsequence

問題概要: 長さ N の文字列 S が与えられる。S の空でない部分列 (区間でなくても可) のうち、文字が重複していないものの個数を mod P で求めよ。(P = 10^9 + 7)

考察:

重複がないという条件を考えると、どの文字を選んだかを記録しなければいけなくて状態数が爆発してしまいます (※誤り)。そのため、重複がある部分列を数えて部分列の総数 (2^N - 1) から引く方向で考えました。

具体例を試しているうちに、文字列はソートしていいことに気づきました。部分列中の文字の順番は「重複があるか」という条件に影響しないからです。

そのため部分列を考える代わりに「各文字種につき、それを何個使うか」を考えればいいです。特に、「2個以上使う」ケースはすべて同様なので掛け算で求まります。

また、各文字種を何個使うかではなく、重複があるかだけを状態に持っておけばいいので、全体としての状態数は O(N) に収まります。そのため、メモ化再帰によって解くことができます。

具体的にはこうです。状態 (i, dup) の意味を、文字種 0..i をそれぞれ何個使うかがすでに決まっていて、少なくとも1種類の文字を2個以上使っているときに dup = true であるということにして、このときの場合の数を dfs(i, dup) と表すことにします。

次の文字種 i を 0 個使うときは dfs(i + 1, dup) 通りです。1 個使うときは、その文字の個数を a とするとき、それをどの位置からとるかの選択肢があって a * dfs(i + 1, dup) 通りになります。2個以上使うときは、文字の選びかたの組み合わせが 2^a - (a + 1) 通りあって、重複が確定するので (2^a - a -1) * dfs(i + 1, true) 通りです。この和が答え。

筆者の回答 (Rust, AC): https://atcoder.jp/contests/agc031/submissions/4606575

反省:

文字列をソートしていいことに気づくのが遅くて、最初の「重複を数える」方針に入り込みすぎていたようです。

公式の解説の解法はもっとスマートです。

メモ化するのを忘れて TLE を1回出しました。

## B - Reversi

問題概要: N 個の石が一列に並んでいる。左から i 個目の石の色は C[i] である。以下の操作を好きな回数だけ繰り返すとき、最終的な石の色の列としてありえるものの個数を mod P で数えよ。

操作: 同じ色の石を2つ選び、その間にあるすべての石の色を選ばれた石と同じ色にする。

考察:

1, 2, 1, 1 のように並んでいるとき、左の3つに対して操作をするのと4つ全体に対して操作をするのでは結果が同じなので、必ず4つ全体で操作することにします。

これは操作範囲を決めるときに両隣に同じ色の石があるかどうかを見て範囲を広げればいいです。

また、区間が重複するような操作は行わないようにしていいです。

こうすると、区間を「石が1つの区間」と「操作によって同色化された区間」の列に分解できます。この列の個数を数えればいいです。

これは DP によってできます。dp[i] を「区間 0..i に対して行う操作がすべて決まっていて、区間i..N については全く操作が行われていない状態」における場合の数とおきます。

また、石 i と同じ色の次の石の位置を next[i] とします。(上述の理由で同じ色が連続しているときは next[i] はその最後尾にします。)

遷移を考えると、操作を行わないケースでの解は dp[i + 1] で、操作を行うケースでは dp[next[i] + 1], dp[next[next[i]] + 1], etc. の総和です。(この総和を実際にループで計算すると TLE したので、メモをとって省略する必要があります。)

初期状態 dp[N] = 1 から後ろ向きに遷移していけば最終的に dp[0] が答えとなります。

筆者の回答 (Rust, AC): https://atcoder.jp/contests/agc031/submissions/4611130

反省:

考察はスムーズに進んだんですが、実装中に3種類のランタイムエラーを起こしてパニックになりました。

- 余りを取るのを忘れてオーバーフロー
- メモ化再帰で書いてスタックオーバーフロー
- 石の色の番号が N (石の個数) を超えないと思い込んでいて、配列の長さが足りなくて範囲外エラー

落ち着こう……

## 今回の教訓

- A: 与えられた列をソートしたら楽になるかも
- B: 何かを数えるときは数えるものと 1:1 に対応するものを頑張って探して、それを代わりに数えるといいかも
- B: 原因が分からない RE が出たときは再現ケースを作るといいかも
Conoha CentOS VPSをL2TP VPNサーバーにする

Conohaで使用しているCentOS7のVPSにL2TP/IPSecでVPN接続できるようにした時のメモです。Conoha標準の（コントロールパネルから設定できる）ファイアウォールではL2TPに必要なポート開放ができないのでこちらを無効（全て許可）にしてCentOS側でfirewalldにて設定します（人生初firewalld）。

# L2TPサーバー
## Conohaのコントロールパネルでプライベートネットワークを追加
必須かどうかわからないですが、L2TP周りの設定にLAN側インターフェイスが必要だろうということでコントロールパネルから追加し。IPアドレス範囲が自宅などのセグメントとかぶらないように192.168.123.0/24などとします。すると192.168.123.1〜192.168.123.254のLANが構築されます。
サーバーにログインし、インターフェイスをeth1として固定IPアドレスを設定するには、/etc/sysconfig/network-scripts/ifcfg-eth1を作成します。

```sh:/etc/sysconfig/network-scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.12.1
NETMASK=255.255.255.0
DEVICE=eth1
ONBOOT=yes
```

## xl2tpdを使用
OpenVPNやSoftEtherを使う方法もあるみたいですが、xl2tpdが機能的に過不足なさそうだったのでチョイス。
こちらのエントリを参考に、サーバー設定周りをすっとばして未設定分のみ実行。
https://qiita.com/yume_yu/items/09f57a8923341c5b2316
ただし、xl2tpd.confとl2tp-ipsec.confのとこで「サーバーのローカルIP」と書いてあるところは実際にはグローバルIPアドレスを指定する必要がありました。

# firewalld 
[こちらのエントリ](https://qiita.com/hana_shin/items/bd9ba363ba06882e1fab)が非常に参考になりました。ありがとうございます。
インストール済みでしたが起動はしてないので起動。

```shell:firewalld起動（2行目で毎回自動起動指定）
# systemctl start firewalld
# systemctl enable firewalld
```

初期状態ではeth0,eth1ともにpubicグループに登録されていたので、eth1は除外するためにinternalへ割当変更。

```shell:eth1をinternalグループに逃がす
firewall-cmd --zone=internal --change-interface=eth1
```

以下、暗黙的にpublicに対する設定になります。sshとdhcp6-clientは標準で有効化されていたので、WebとL2TP/IPSecに必要なもの（下3つ）を追加。

```shell:ルール追加
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=httpd
firewall-cmd --zone=public --add-service=ipsec
firewall-cmd --zone=public --add-port=1701/udp
firewall-cmd --zone=public --add-port=4500/udp
firewall-cmd --add-masquerade
```

あえて一旦--publicをつけないことでオンメモリの一時ルールになるので、動作確認後にまとめて永続化します。

```shell:設定確認(public)
firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: dhcpv6-client ssh http https ipsec
  ports: 1701/udp 4500/udp
  protocols: 
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

追加前はWebにアクセスできなかったのができるようになりました。保存（永続化）します。

```shell:永続化
firewall-cmd --runtime-to-permanent
```

# ログの確認
```shell:firewalldの拒否ログの有効化と無効化
firewall-cmd --set-log-denied all
firewall-cmd --set-log-denied off
```
遺伝的アルゴリズムでOneMax問題を解く

# 遺伝的アルゴリズム

今日は、遺伝的アルゴリズムについて学んだ。

アルゴリズムそのものについては、このスライドが極めてわかりやすかった。
[遺伝的アルゴリズム（Genetic Algorithm）を始めよう！](https://www.slideshare.net/kzokm/genetic-algorithm-41617242)

Hello World 的な Python コード例としては、
[Pythonで遺伝的アルゴリズム](https://qiita.com/KeisukeToyota/items/0f527a72270430017d8d)
が理解しやすかった。

上記２つ記事の著者に多謝。

[Pythonで遺伝的アルゴリズム](https://qiita.com/KeisukeToyota/items/0f527a72270430017d8d)のコードは十分理解しやすかったのだが、さらに自分好みにリファクタリングを加えてみた。

# リファクタリング後のコード

```python
import random
import copy


# パラメータ
gene_length = 10 # 遺伝子長
population_size = 12 # 個体数
n_generations = 20 # 世代数
mutate_rate = 0.2 # 突然変異の確率
elite_rate = 0.3 # エリート選択の割合


def fitness(gene):
    return sum(gene)


# individual は (適応度, 遺伝子）のタプルで表現される
def individual_tuple(gene):
    return (fitness(gene), gene)


def create_individual():
    gene = [random.randint(0,1) for j in range(gene_length)]
    return individual_tuple(gene)


def create_population():
    return [create_individual() for i in range(population_size)]


def evaluate(population):
    population.sort(reverse=True)


def two_point_crossover(parent1, parent2):
    r1, r2 = sorted(random.sample(range(gene_length), 2))
    parent1_gene = parent1[1]
    parent2_gene = parent2[1]
    child_gene = copy.copy(parent1_gene)
    child_gene[r1:r2] = parent2_gene[r1:r2]
    return individual_tuple(child_gene)


def mutate(parent):
    r = random.choice(range(gene_length))
    parent_gene = parent[1]
    child_gene = copy.copy(parent_gene)
    child_gene[r] = 1 if child_gene[r] == 0 else 0
    return individual_tuple(child_gene)


def main():
    # 初期個体生成
    population = create_population()

    for g in range(n_generations):
        # 適応度の降順にソート
        evaluate(population)

        print('Generation: ' + str(g + 1))
        print('Min : {}'.format(population[-1][0]))
        print('Max : {}'.format(population[0][0]))
        print('--------------------------')

        # エリートを選択
        elites = population[:int(population_size * elite_rate)]

        next_population = elites
        while len(next_population) < population_size:
            if random.random() < mutate_rate:
                # 突然変異
                parent = random.choice(elites)
                child = mutate(parent)
            else:
                # 交叉
                parent1, parent2 = random.sample(elites, 2)
                child = two_point_crossover(parent1, parent2)
            next_population.append(child)
        population = next_population

    evaluate(population)
    print('Result : {}'.format(population[0]))


if __name__ == '__main__':
    main()
```

# 感想

遺伝的アルゴリズムは、名前のとおり、生物界の自然選択を模したものなので、原理は理解しやすかった。
ただ、上のコードはあくまでも骨格。
現実の問題（ナップサック問題、巡回セールスマン問題等）を解くためには、遺伝子をどう符号化し、どのように適応度を評価するか、という点が肝だろう。
これについて考えるのが次の課題である。
Lambda@Edge で CloudFront に Basic 認証をかける(ガラケー対応)

## はじめに

今回、AWSのCloudFrontを使用している案件で、検証環境についてのみ`Basic認証`をかけたいという要望があったため対応をしました。

CloudFront環境でBasic認証をかけるにはLambda@Edgeを使用するのがよいそうです。

※Authenticatioヘッダをフォワードするという方法もありますが、キャッシュヒット率が低下するため今回は採用しませんでした。

ググって先人の記事の通りに実施したところ、PCやスマホではうまくいきましたが、ガラケー(フィーチャーフォン)ではうまくいかなかったためコードを少し修正しました。
以外とこの件についてはネット上に情報が少なかったため、メモ書きとして残しておきます。

CloudFrontやLambda@Edgeの詳細については、他の人がいっぱい記事にしているのでここでは省きます。
ここでは`ガラケー対応した部分のみをクローズアップ`します。

## まずやったこと
ググった先人のコードを~~パクって~~インスパイアして設定してみました。

※Basic認証部分のみを抜粋

```javascript

// Require Basic authentication
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
    const body = 'Unauthorized';
    const response = {
        status: '401',
        statusDescription: 'Unauthorized',
        body: body,
        headers: {
            'www-authenticate': [{key: 'WWW-Authenticate', value: 'Basic'}]
        },
    };
    callback(null, response);
}
```

その結果、PCやスマホでは想定通りBasic認証が発動しました。
がしかし、ガラケーで試してみると、

```
このページはエラー(401)により表示することができません。
```

という画面が表示され、Basic認証が発動しませんでした。


## ガラケー対応内容

401ステータスコード自体はガラケーで受け取れているようなので、他に過不足なヘッダー情報があるのかな?
と思い色々調べてみたところ、[wiki](https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC)にこのような例が載っていました。

```http
# 認証が必要であることを示すサーバのレスポンス:
HTTP/1.1 401 Authorization Required
Date: Wed, 11 May 2005 07:50:26 GMT
Server: Apache/1.3.33 (Unix)
WWW-Authenticate: Basic realm="SECRET AREA"
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
```

**『Basic realm』!!**
ApacheでBasic認証の設定をする際も、`Basic realm`を設定必要がありました。
この`Basic realm`を設定することが、Basic認証の正しいお作法なのかもしれない…という推測を立てて、上記Lambda@Edgeのコードを少し修正しました。

```diff
// Require Basic authentication
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
    const body = 'Unauthorized';
    const response = {
        status: '401',
        statusDescription: 'Unauthorized',
        body: body,
        headers: {
-           'www-authenticate': [{key: 'WWW-Authenticate', value: 'Basic'}]
+           'www-authenticate': [{key: 'WWW-Authenticate', value: 'Basic realm="Basic Area"'}]
        },
    };
    callback(null, response);
}
```

このコードを適用してガラケーでアクセスしみると、問題なくガラケーでもBasic認証が発動されました。めでたしめでたし:thumbsup:


## おわりに

このプロジェクトでは、どうしてもガラケー(フィーチャーフォン)を切りたくないらしく、今回のようにガラケーのためだけに必要な対応が他にも多々発生しています。しかもガラケー対応に対するノウハウはなかなかネットにも転がっておらず大変です…

ガラケー対応分として、もっとコストや時間にバッファを積んでおくべきだっと思う今日この頃です:angel:
Santander Value Prediction Challengeのカーネル解説

今回はkaggleの以下のkernelの日本語訳を行います。

https://www.kaggle.com/alexpengxiao/preprocessing-model-averaging-by-xgb-lgb-1-39

# 日本語訳

### 概要

このnotebookでは、データを前処理して 「gradient boosting tree models」に投入して。 public leaderboardで1.39のスコアを獲得。

ワークフローは以下

1.データ前処理 データ前処理の目的はより高いtime/space効率を得るためである。 「定数（?）特徴量の除去」、「重複した特徴量の除去」、「重要でない特徴量」の除去等 ここでのキーは、前処理が精度に影響を与えないことである。

2.特徴量変換 特徴量変換の目的は、データをよく把握する助けになること、そして過学習を防ぐことである。 やったことは ・トレーニングデータとテストデータで分布が異なる特徴量を落とすこと。 ・統計量を特徴量に追加したこと。 ・低次元表現（low-dimensional representation）を特徴量に追加。

3.モデリング Xgboostとlightgbmの2つのモデルを使用した。 最終的な予測のため2つのモデルを平均した。


### ステップ1
トレーニングデータとテストデータをロードします。重複カラムを除去します。 
・最初に重複したカラムを削除 
・次に32桁までに落とした上で重複カラムを削除（ループしながら比較）

### ステップ2
特徴量を重要度で選択する。ランダムフォレスト（回帰？弱識別機？）を使って特徴量の重要度を得る。トップからNUM_OF_FEATURES(=1000)の重要度の特徴量を選択する。 
NUM_OF_FEATURES(=1000)はここではチューニング可能なハイパーパラメータである。

### ステップ3

トレーニングデータとテストデータをKolmogorov–Smirnov検定（コルモゴロフ-スミルノフ検定）で評価します。これは両側検定の帰無仮説で2つの独立したサンプルが同じ分布から抽出されたものかを検定する。異なる分布だった場合はこの特徴量は除去する。（汎用的なモデルにならないため）

THRESHOLD_P_VALUE（P値） と THRESHOLD_STATISTIC(KS統計量) はハイパーパラメータである。

### ステップ4
統計的な特徴量を追加する。さらに低次元表現の特徴量を追加する。

※SparseRandomProjectionは次元削減のアルゴリズム


### ステップ5
クロスバリデーションのメソッドとモデルを定義する。 xgboostとlightgbmを使用する。 ハイパーパラメータはグリッドサーチによって既にチューニングされている。

※注意 AveragingModels(BaseEstimator, RegressorMixin, TransformerMixin)は多重承継している。 2つのモデルを格納しておいて学習させる。 2つのモデルの予測結果の平均を返す。
Java8 リストを結合する

Java8 でリストを結合（マージ）する方法。調べたら３つありました。

```java
import java.util.*;
import java.util.stream.*;

class Main {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("Apple", "Banana", "Ctrus");
        List<String> list2 = Arrays.asList("Drian", "Elderberry");
        
        // (1) http://blog.64p.org/entry/2014/11/21/123447
        List<String> newList1 = Stream.concat(list1.stream(), list2.stream())
                                      .collect(Collectors.toList());
        System.out.println(newList1);
        
        // (2) http://simplesandsamples.com/list-join.java.html
        List<String> newList2 = new ArrayList<>();
        newList2.addAll(list1);
        newList2.addAll(list2);
        System.out.println(newList2);
        
        // (3) https://ja.stackoverflow.com/questions/8232/stream%E3%81%A7%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AE%E7%B5%90%E5%90%88%E3%81%8C%E3%81%97%E3%81%9F%E3%81%84
        List<List<String>> outer = Arrays.asList(list1, list2);
        List<String> newList3 = outer.stream()
            .flatMap(lst -> lst.stream())
            .collect(Collectors.toList());
        System.out.println(newList3);
    }
}
```
max-width と mix-width の使い方

#簡単にいうとこういうことだ！

要素の最大値と最小値を決める

#どんな時に使うか

レスポンシブ（スマホ対応）させるときに使いましょー


#使い方

- **スマホは100%だと調子いいけど、PCで100%はデカすぎるー。**

そんな時は、最大値を決めよう！

  `code`
  width: 100%;
  max-width: 500px;

これで、100%だとしても、500px以上になりません！


- **スマホは50%だときついけど、PCで50%がいいんだよなあ。。**

そんな時は、最小値を決めよう！

  `code`
  width: 50%;
  min-width: 250px;

これで、いくら狭くしても250px以下になりません！
UbuntuでFlaskをService実行する手順

自分用のメモ投稿。Flaskで作成したWeb APIをUbuntu上でバックグラウンドのServiecとして起動する手順。

1. flask.serviceを作成
2. serviceの起動・停止コマンド


## 1. flask.serviceを作成
```bash:terminal
$ nano /lib/systemd/system/flask.service
```

```txt:flask.service
[Unit]
Description=Flask web server

[Install]
WantedBy=multi-user.target

[Service]
User=root
Group=root
PermissionsStartOnly=true
WorkingDirectory=/dir/to/my-script
ExecStart=/bin/bash -c 'python3 -u my-script.py'
Restart=on-failure
RestartSec=10s
RuntimeDirectoryMode=755

```

## 2. serviceの起動・停止コマンド

```bash:terminal
$ sudo service flask start # flaskサービス開始
$ sudo service flask stop # flaskサービス停止
$ sudo service flask restart # flaskサービスRestart
```
$ rails db:migrateできないエラーの原因と解決策

###エラー

MySQLのエラーを解決した後に、```$ rails db:migrate```をしたら、エラーが出た。

```
rails aborted!
Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: YES)
```

###試したこと

新たにテーブルを作成

```
$ db:create:all
```
再度、マイグレートしたら、マイグレートされました。

```
$ rails db:migrate
```




参照記事：https://qiita.com/kawabex/items/d375633a2baddf53377b

###原因

MySQLでは、データベースを作成した時に、テーブルは作られていない。なので、マイグレーション先のテーブルがない。なので、新しくデータベースにテーブルを作成すれば、マイグレーション先が確保される。マイグレーションファイルの送り先のテーブルが確保された状態で、マイグレートすれば、無事、マイグレートされる。

参照記事：https://qiita.com/zeppekipanda/items/9d7ecaff927b68143721
正規表現についての個人的まとめ

#この記事について#
自分の備忘録として、正規表現全般についての自分の考えや調べたことを記載していきます。
ほぼリンク集として使用。
経験が浅いので、間違っていることもあると思いますがご容赦ください。

#小技

| 事項       |       説明|       参照|
|:-----------------|:------------------|:------------------|
|特定の文字より前／特定の文字より後を抜き出す|よけいなものが前についているときに削除するのに便利|[正規表現で特定の文字より前／特定の文字より後を抜き出す](http://straylight-engineer.blogspot.com/2014/01/blog-post.html)
ナビゲーションメニューの項目の中から、現在開いているページに飛ぶためのリンクが消えて、残りの項目だけを表示するようにしたい

##何がしたいか
例えば、ナビゲーションメニューに表示させたいリストが、項目A、項目B、項目C、項目Dの4つあるとします。項目Aのページを開いたときはナビゲーションメニューには項目A以外の3つが表示され、項目Bのページを開いたときはナビゲーションメニューには項目B以外の3つが表示され、・・・ということをしたい。つまり、ナビゲーションメニューの項目の中から、現在開いているページに飛ぶためのリンクが消えて、残りの項目だけを表示するようにしたい。
![sihteicon.png](https://qiita-image-store.s3.amazonaws.com/0/358159/8df32c32-a55a-246c-73f5-d069a8d9b8f2.png)
これを、PHPを使って実装します。

##まず前提として…
ナビゲーションメニューの部分のHTMLは次のような構造です（CSSは省略）。

```html:header.php
<header>
  <nav>
    <!-- ナビゲーションメニューの項目をaタグを使って作成 -->
  </nav>
</header>
```
これを``include``を使って、ヘッダー部分に読み込みます

```php:〇〇.php
<?php include('header.php'); ?>
```

##ナビゲーションメニューをうんぬんかんぬんするPHPのコード
まずは、すべてのコードを載せます。

```php:header.php
<?php
  $navlist = [
    ['href' => 'itemA.php', 'name' => '項目A'],
    ['href' => 'itemB.php', 'name' => '項目B'],
    ['href' => 'itemC.php', 'name' => '項目C'],
    ['href' => 'itemD.php', 'name' => '項目D']
  ];
  $filename = debug_backtrace()[0]["file"];

  switch ($filename) {
    case '・・・/itemA.php':
      array_splice($navlist, 0, 1);
      break;
    case '・・・/itemB.php':
      array_splice($navlist, 1, 1);
      break;
    case '・・・/itemC.php':
      array_splice($navlist, 2, 1);
      break;
    case '・・・/itemD.php':
      array_splice($navlist, 3, 1);
      break;
  }
?>

<header>
  <nav>
    <?php foreach ($navlist as $key => $value) : ?>
      <a href="<?php echo $value['href']; ?>"><?php echo $value['name']; ?></a>
    <?php endforeach; ?>
  </nav>
</header>
```
次に、上のコードをいくつかのパートに分けて、軽く説明していきます。

###ナビゲーションメニューの項目の名前と遷移先のページのパスを配列に格納
```php:PHP
  $navlist = [
    ['href' => 'itemA.php', 'name' => '項目A'],
    ['href' => 'itemB.php', 'name' => '項目B'],
    ['href' => 'itemC.php', 'name' => '項目C'],
    ['href' => 'itemD.php', 'name' => '項目D']
  ];
```
あとで、この配列をループでまわして、navタグの中にaタグ``<a href="〇〇">△△</a>``を作っていきます。``href``キーの値は〇〇に、``name``キーの値は△△に入ります。

###header.phpがどのファイルから呼ばれたのかを取得
```php:PHP
  $filename = debug_backtrace()[0]["file"];
```
ファイルのフルパスを返してくれるとかなんとか。上手く説明できないのでスルー。
[PHP: debug_backtrace - Manual](http://php.net/manual/ja/function.debug-backtrace.php)

###header.phpの呼び出し先によって条件分岐
```php:PHP
  switch ($filename) {
    case '・・・/itemA.php':
      array_splice($navlist, 0, 1);
      break;
    case '・・・/itemB.php':
      array_splice($navlist, 1, 1);
      break;
    case '・・・/itemC.php':
      array_splice($navlist, 2, 1);
      break;
    case '・・・/itemD.php':
      array_splice($navlist, 3, 1);
      break;
  }
```
``$filename``が``・・・/itemA.php``なら（＝header.phpがitemA.phpから呼び出されたのなら）、``$navlist``配列の中の``itemA.php``と関連したデータ（`` ['href' => 'itemA.php', 'name' => '項目A']``）を削除する、というような処理をしています。

この処理を経ることで、配列には、呼び出し先のページ以外のページの情報だけが残ります。

###配列をループ処理してaタグを作成
```php:PHP
    <?php foreach ($navlist as $key => $value) : ?>
      <a href="<?php echo $value['href']; ?>"><?php echo $value['name']; ?></a>
    <?php endforeach; ?>
```
例えば、header.phpがitemA.phpから呼び出されたとしたら、前のswitch文の処理のおかげで、配列からitemA.phpに関するデータは消えました。このループ処理によって、itemB.php・itemC.php・itemD.phpのデータを使ってaタグが作成されます。

これで、ナビゲーションメニューの項目を動的に変化させることができます。

##注意
・PHP初学者なので、説明が間違っているところがあるかもしれません。
・もっとスマートなやり方があればぜひ教えてください。
Flutterで画像背景を設定して透過ヘッダーにする

## レイアウトを作る上で、良く透過ヘッダーが欲しくなるので作成。

Flutterなるものを最近知って遅まきながら色々触っているのでメモ書きをかねて記事作成。 
とりあえず、それっぽいUIと言うことで透過背景の画面がこんな感じにできました。

![with_opacity.png](https://qiita-image-store.s3.amazonaws.com/0/50276/8abbbe9d-4ec4-4ae0-c8ab-c27b5dd83a3e.png)

## ソース

ソースはこんな感じ。

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context)
  {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: Stack(
        children: <Widget>[
          new Container(
            height: double.infinity,
            width: double.infinity,
            decoration:new BoxDecoration(
              image: new DecorationImage(
                image: new AssetImage("assets/background.png"),
                fit: BoxFit.cover,
              ),
            ),
          ),
            Scaffold(
              backgroundColor: Colors.transparent,
              appBar: new AppBar(
                title: const Text("Standard AppBar"),
                backgroundColor: Colors.blue.withOpacity(0.3),
                elevation: 0.0,
              actions: <Widget>[
                IconButton(
                  icon: Icon(Icons.settings),
                  onPressed: () {
                    // Pressed Action
                  },
                ),
                IconButton(
                  icon: Icon(Icons.menu),
                  onPressed: () {
                    // Pressed Action
                  },
                ),
              ],
            ),
            body: new Container(
              color: Colors.transparent,
            ),
          ),
        ],
      )
    );
  }
}
```

## 詳細

まずはStackを使い各要素を重ねるように作成します。

```dart
return new MaterialApp(
  title: 'Flutter Demo',
  home: Stack(
   children: ...
  )
);
```

Stack要素の中に、まずは背景を設定してその上にScaffoldでヘッダーやメニューを配置することで、背景画像の上に透過のヘッダーやボディ要素を設定しています。

```dart
new Container(
  decoration:new BoxDecoration(
    image: new DecorationImage(
      image: new AssetImage("assets/background.png"),
      fit: BoxFit.cover,
    ),
  ),
),
Scaffold(
  ...
)
```

背景画像が見えるようにするには``Colors.transparent``を使ってウィジェットを透過させることで、実現しています。

## 最後

たったこれだけで簡単にそれっぽい画面がAndroidもiOSも作れるのでなかなか便利なFlutter。  
今後も色々試してみようと思います。

---

いろんなレイアウトとか、使い方とかまだまだ日本語記事もすくないので、自分で試した事に関しては、
参考にまとめておくと後で便利そうなので、こんなの作りました。

[https://flutter.ctrnost.com](https://flutter.ctrnost.com)
今後も、レイアウトイメージが浮かんだら、随時更新していきます。
position: fixed;　とは

#positioin: fixed; 簡単にするとこれや！

　　特定の位置に固定すること！

#どんな時に使うか

　スクロールしても変わらないので、headerとかに使いましょー


#こんな書き方もできます
/* header */

.一番上のクラス{
    position: fixed;
    width: 100%;
    background: transparent;
    padding: 15px 0px;
    transition: all 0.5s;
    z-index: 99999;
}

.fixed {
    position: fixed;
    top:0;
    left:0;
    width: 100%;
    background-color: #00967f;
    padding: 0px;
}
PowerShellでwaveファイルを作成したときに、System.IO.BinaryWriter の Write オーバーロードでやらかしたこと

[BinaryWriter Class (System.IO) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.binarywriter?view=netframework-4.7.2)

BinaryWriterは標準ライブラリにあるので、すぐ使えて便利ですが、ミスをしてしまいました。
こんな風に書くと16ビットではなく32ビット書き込まれてしまいました。

```
$bw.Write([int16]2 * 1)
```

そうならないように

```
$bw.Write([int16](2 * 1))
```

括弧でくくっています。

ファイルにwavファイルを書く例

```powershell
. .\wave.ps1; $fs=[System.IO.File]::Create($pwd.Path+"\r.wav"); WriteWave($fs); $fs.Close();
```

```powershell:wave.ps1
function WriteWave(
    [System.IO.Stream]$os
) {
    $bw = [System.IO.BinaryWriter]::new($os)
    $os.Position = 0
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("RIFF"))
    $os.Position = 8
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("WAVE"))
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("fmt "))

    $bw.Write([int32](16))
    $bw.Write([int16](1))
    $bw.Write([int16](1)) # 1モノラル 2ステレオ
    $bw.Write([int32](44100)) # 周波数
    $bw.Write([int32](44100 * 2 * 1)) # 44.1kHz 16bit モノラル

    $bw.Write([int16](2 * 1)) # 括弧ないと32ビット書かれる
    $bw.Write([int16](16))
    $bw.Write([System.Text.Encoding]::ASCII.GetBytes("data"))

    $samples = 44100 * 2; # 周波数 * 秒
    $size = $samples * 1 * 2  # 周波数 * 1モノラル * 16bit
    $bw.Write([int32]($size));

    for ($i = 0; $i -lt $samples; $i += 1) {
        $v = Get-Random -Minimum -32768 -Maximum 32768
        $bw.Write([int16]($v))
    }
    
    $os.Position = 4
    $bw.Write([int32]($os.Length - 8)) # 括弧ないと64ビット書かれる
}
```

waveファイルのフォーマットはこれを参考にしました。
[wav ファイルフォーマット](http://sky.geocities.jp/kmaedam/directx9/waveform.html)

PowerShellでバイナリファイルを扱うとき、BinaryWriterはすぐに使えて便利ですが、書き込まれる長さに注意が必要です。

WriteI16 とか WriteI32 のような
メソッド名と書き込むビット数が一致するメソッドを作るのがありかもしれません。
Python3で行うWebスクレイピング【備忘録】

　Webページの画像やタイトル、文章など特定のデータを抽出する技術のことをWebスクレイピングという。今回、この技術を活用し日経225先物の株価のwebスクレイピングを行う。


##--version
言語:Python 3.7.2
ライブラリ:Requests、BeautifulSoup4、pandas


##Requests
Python3系バージョンのRequestsをインストール後、下記のコマンドにて、webページの全体情報が取得できる。

```python

import requests
r = requests.get('取得したいページのURL’)
```

print()を打ち、カッコ内で取得したい情報を指定することで、特定の情報を表示することができる。




##Beautiful Soup
Requestsで取得したWebページをスクレイピングする。HTMLとXMLのパーサーである為、Requestsと併用することが多い。

```python

import lxml
from bs4 import BeautifulSoup
soup = BeautifulSoup(r.content, "lxml")
# セレクターの使用
print(soup.select("抽出したいデータのXpathかCSSセレクター"))
# h1タグ部分の表示
print(soup.get("h1"))
```

lxmlはC言語の高速実装な解析器で基本的にはhtmlより処理速度が早いらしいので今回はlxml形式で処理する。上記のコマンドで、Webページ内の情報のスクレイピングが可能となる。こちらを使用し、以下で実際にスクレイピングを試みる。




##日経225先物の株価取得

株価の取得からCSV形式のファイル出力までを行う。


```python

#ライブラリのインポート
import lxml
from bs4 import BeautifulSoup
import requests
import pandas as pd
import datetime
```

情報の取得からスクレイピングしたデータの整形と出力まで

```python

#アクセスするURLを変数に格納
url = "URL"

headers={"UserAgent" : "アドレス等"}

#urlにアクセスし、ページ内の情報を取得
r = requests.get(url, timeout=5, headers=headers)

#取得した情報をBeautifulSoupに食わせる
soup = BeautifulSoup(r, "lxml")

#<td>タグの情報をリストとして格納
row_list = soup.find_all('td')
    
# write = CSSセレクターを使って指定した場所を変数に格納
CR = soup.find_all('td')[0].text
HR = soup.find_all('td')[1].text
OR = soup.find_all('td')[2].text
LR = soup.find_all('td')[3].text


#現在日時の取得
now = datetime.datetime.now()
TODAY = now.strftime('%Y:%m:%d')
TIME_NOW = now.strftime('%H:%M:%S')

#取得した株価でDataaFrameオブジェクトの生成
df = pd.DataFrame({"データ取得日" : TODAY,
                  "データ取得日時" : TIME_NOW,
                  "前終値" : CR,
                  "高値" : HR,
                  "初値" : OR,
                  "安値" : LR},
                  index=['i',]
                 ) 


#csvの出力
#df.to_csv("日経225先物.csv", index=False)
df.to_csv("日経225先物.csv",mode='a',index=False, header=False)
```



スクリプトファイルを作成し、定刻にプログラムを実行する。

　
実行すると以下のように情報が取得できる
![2e9e712b0382e13a29543befa159b564.dat.png](https://qiita-image-store.s3.amazonaws.com/0/323243/c9430a18-9296-429f-4c9e-6b7f8f763708.png)




以上


##備考

<h4>・画像の取得

画像データの取得は画像の配置場所のURLを取得してダウンロードすることで可能になる。　

```python

import Requests

#imagesにリストで相対パスを格納
images = []
for tag in sectiosn:
    try:
        images.append(tag.img.get('src'))

    except:
        pass
```



imagesの中身は[images/~img,images/~img,images/~img,images/~img]のようになり、その後for文を使って格納されているすべての画像を保存する。


```python 
 
  i = 0
    for in images:
        re = requests.get('URL' + src)
        with open('画像の配置されているURL', 'wb') as file:
            file.write(re.content)
        i+=1
```

ファイルが出力される

<h4>・JSONデータのスクレイピング

　APIをスクレイピングする場合のデータ形式がJOSNの為、その際に使える手法を以下に記す。Python内でjsonは辞書型のように扱われるのでcontent['キー１']['キー２']というように書いて指定の部分の情報を取り出すことができる。


```python

import json
import requests

url = 'URL'
response = urlrib.request.urlopen(url)
content = json.loads(response.read().decode('utf8'))
print(content["キー１"]["index"]["キー２"])

```
以上

※サイトによってはスクレイピングを禁止している場合があるので注意しなければならない。
[Ruby] 虎太郎の備忘録

Ruby 虎太郎の備忘録
-------------------

## 正規表現

名前付きキャプチャ

```
s = "user_id,bigint,ID; *-1 user_info.id"

# (?<name>pattern)
m = s.match(/^(?<name_p>.+),(?<type>.+),(?<name_l>.+); (?<fkey>[01\*\?\+]-[01\*\?\+] .+)/)
puts "#{m[:name_p]} #{m[:fkey]}"
# => user_id *-1 user_info.id
```

## 配列

select & with_index

```
p [0, 1, 2, 3, 4, 5, 6].select.with_index { |data, index| index.odd? }
  # => [1, 3, 5]
```

2次元配列の初期化

```
# 2次元配列
a = Array.new(4) { Array.new(3){0} }
a[0][0] = 1
a[1][1] = 2
a[2][2] = 3
a[3][0] = 4
  # => [[1, 0, 0], [0, 2, 0], [0, 0, 3], [4, 0, 0]]
p a
```

## 文字列

gsub で複数条件の変更

```
p '111999'.gsub(/1|9/, '1' => '9', '9' => '1')
  # => '999111'
```

scan で特定の文字を抽出

```

p '1111000'.scan(/1/).size
  # => 4
```

## 標準入力

標準入力から値を読み込み配列にセットする

```
# input
# 2
# 1 2 3
# 4 5 6
n = gets.strip.to_i
a = n.times.map { gets.strip.split.map(&:to_i) }
  # => [[1, 2, 3], [4, 5, 6]
```

## ファイル関連

ファイル read

```
File.open(fnm, mode = "r") do |f|
  f.each_line do |line|
    line.strip!
    # somthing todo
  end
end
```

ファイル名（拡張子なし）と拡張子を取得する

```
file_name = "test.txt"
name = File.basename(file_name, ".*")
   #=> "test"
ext = File.extname(file_name) 
  #=> ".txt"
```

## コマンドライン実行時の判定

```
# Ruby
if __FILE__ == $0
  # pass
end

# Python
# if __name__ == '__main__':
#     pass
```

## 資料

- [Rubular|正規表現チェック](https://rubular.com/)
Streamにおけるmapとflatmapの理解へ向けて(1)

# 問い
2つの`Integer`のリストから、
互いの全ての要素の組み合わせから成る`Pair`のリストを生成せよ。

ex.) [1,2,3], [5,6] -> [(1,5),(1,6),(2,5),(2,6),(3,5),(3.6)]

## trial1
なんかmapでいけるかも。

```java
List<Integer> ints1 = Arrays.asList(1,2,3);
List<Integer> ints2 = Arrays.asList(5,6);
ints1.stream()
     .map( i -> ints2.stream().map( j -> Pair.of(i,j)))
     .collect(toList()); 
```
<img src=https://qiita-image-store.s3.amazonaws.com/0/202689/5a34f6ae-78bf-37b0-9ba5-6207f3aec84f.png width=55%>

だめ。
`List<Stream<Pair<Integer, Integer>>`が返される。

そもそも...
Stream.map関数は、型`Function<? super T,? extends R>`を引数にとり、`<R> Stream<R>`を返す。

> <R> Stream<R> map(Function<? super T,? extends R> mapper)
ref. [Stream.map](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-)


なので、入れ子となっているmapは、
`Stream<Pair<Integer, Integer>>`を返し、
その戻り値を受けた大元のmapが、
`Stream<Stream<Pair<Integer, Integer>>>`を返すようになる。

そして、終端操作により、
`List<Stream<Pair<Integer, Integer>>`が最終的に返される。
（終端操作がどのような処理をしているかについては今後...）
 

## そこでflatMap
> flatMapを使うことで、
> Streamの各値を別のStreamで置き換え、
> 生成された全てのStreamは、単一のStreamへ集約されるようになる。
> ref. [Java8 in Action](https://www.manning.com/books/java-8-in-action)


定義によると、
flatMapへ引数で渡している
`Function<? super T,? extends Stream<? extends R>> mapper`の第二引数が、
`? extends Stream<? extends R>`となっており、
戻り値は、
Functionの第二引数のStreamを構成する型Rの`<R> Stream<R>`となっている。

> <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
> ref. [flatMap](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-)

以上を踏まえると、以下のようなコードとなる。

```java
ints1.stream()
     .flatMap( i -> ints2.stream().map( j -> Pair.of(i,j)))
     .collect(toList());
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/202689/65e97a01-f7a4-0e5b-9b7d-f6abf402ec01.png" width=55%>

`flatMap( i -> ints2.stream().map( j -> Pair.of(i,j)))`
によって返される型は、
`Stream<Pair<Integer,Intege>>`で、
終端操作により、`List<Pair<Integer,Integer>>`が返される。


flatMapを使うことで、
trial1で入れ子となっていたStreamをよしなにしてくれる感じになる ^^;（説明雑）
プルダウン抵抗

#はじめに
ロジックICを使用していたところ、条件を満たしていないのにLEDが光っていました。
そこで友人が「プルダウン抵抗」というものを教えてくれました。

#回路図
![プルダウン抵抗IC.png](https://qiita-image-store.s3.amazonaws.com/0/246294/f2f4d1dc-9fa6-aad0-21b8-11b317b6d91c.png)

タクトスイッチの図記号が見当たらなかったので即席で書きました。
左右のプラス、マイナスの線はブレッドボードを意識しました。

こうすることで、条件を満たしていないときはグランドに流れるようになり、安定するようです。

#実際に使ってみる
![IMG_20190316_184233.jpg](https://qiita-image-store.s3.amazonaws.com/0/246294/7194a0f5-783c-710d-ab9b-00659bfaa925.jpeg)
画像のICはTC4081BPです(AND回路)。
まずはプルダウン抵抗を使用していない場合です。
タクトスイッチを押さなくても光ってしまっています。

![IMG_20190316_184205.jpg](https://qiita-image-store.s3.amazonaws.com/0/246294/cb431503-d002-5c5f-c2de-d14a930449d1.jpeg)
プルダウン抵抗を使用した場合です。
タクトスイッチを押していないときは光っていません。

#おわりに
友人に感謝しています。

#日記一覧へ
[ロジックIC日記 一覧](https://qiita.com/C_Assembly/items/fa1e78643e7a52fe9e4b)
MacOSにscala環境を構築します

#sbtのインストール

MacOSでは、Scalaプログラムを手動でコンパイルすることは非常に稀で、sbtという標準的なビルドツールを用いていること多いです。ここでは、まずsbtをインストールします。
Homebrewを用いてsbtをインストルします。

```
brew install sbt
#インストール済の情報
==> Downloading https://github.com/sbt/sbt/releases/download/v1.2.8/sbt-1.2.8.tgz
==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws.com/279553/ae845a00-0be0-11e9-99d2-03a5afa9f1c7?X-Amz-Algorithm=AWS4-HMAC-SHA2
######################################################################## 100.0%
==> Caveats
You can use $SBT_OPTS to pass additional JVM options to sbt.
Project specific options should be placed in .sbtopts in the root of your project.
Global settings should be placed in /usr/local/etc/sbtopts
==> Summary
🍺  /usr/local/Cellar/sbt/1.2.8: 521 files, 50MB, built in 58 seconds
```
- sbtの場所：　/usr/local/Cellar/sbt/1.2.8

#REPLとsbt
これからしばらく、REPL（Read Eval Print Loop）機能と呼ばれる対話的な機能を用いてScalaプログラムを試して見ますが、それは常にsbt consoleコマンドを経由して行います。

```
#sbt consoleを起動
sbt console
scala> println("hello scala!") 
hello scala!
```
ここまでは、scalaのインストールが完了です。

scalaを終了したい場合は、以下のコマンドで

```
scala> :quit
```
[other] ER図の作成

## 概要

erdot を使用した ER図の作成

## 環境

macOS High Sierra: 10.13.6 

## Golang install

```
$ brew install go
・

$ go version
go version go1.12 darwin/amd64
```

## Graphviz install

```
$ brew install graphviz
・

$ echo $?
0

$ dot -V
dot - graphviz version 2.40.1 (20161225.0304)
```

## erdot install

```
$ go get github.com/twinbird/erdot
  # => 出力はなにも出ない。。。

$ echo $?
0

$ ls -ltr
  # go という directory が作成されている
・
drwxr-xr-x    4 hoge  staff     128  3 11 18:42 go

$ find go -name erdot
go/bin/erdot
go/src/github.com/twinbird/erdot

# erdot をパスの通った directory に移動
$ cp -v go/bin/erdot ~/bin


# test
$ mkdir -pv ~/tmp/erdot

$ cat << "EOF" > test.erdot
// estimate print system

# Tables

// master

user (ユーザ情報)
    id (ID) INTEGER PRIMARY KEY
    name (ユーザ名) VARCHAR(100) NOT NULL

employees (従業員)
    id (ID) INTEGER PRIMARY KEY
		user_id (ユーザID) INTEGER NOT NULL
    last_name (姓) VARCHAR(30) NOT NULL
    first_name (姓) VARCHAR(30) NOT NULL

# Relations
employees.user-id 1-1 user.id
EOF

$ erdot system.erdot | dot -Tpng -o output.png
$ open output.png
# => 正しく表示されていることを確認

$ erdot test.erdot | dot -Tpng -o output.png
# => 正しく表示されていることを確認
```

## 資料

- [erdot](https://github.com/twinbird/erdot)
- [The Go Programming Language](https://golang.org/)
- [テキストでER図を作る記法と処理系を作った](https://www.write-ahead-log.net/entry/2017/11/09/224345)
- [テキストデータをグラフ画像に変換するツール「Graphviz」ことはじめ](https://dev.classmethod.jp/tool/graphviz-beginner/)
- [Graphvizとdot言語でグラフを描く方法のまとめ](https://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d)
visual studio のプロジェクトの.vsフォルダがgit addできない

# 症状
以下のログが出力されてgit add コマンドが失敗する

```
error: open("surasura_C#/ConsoleApp1/.vs/ConsoleApp1/v15/Server/sqlite3/db.lock"): Permission denied
error: unable to index file 'surasura_C#/ConsoleApp1/.vs/ConsoleApp1/v15/Server/sqlite3/db.lock'
fatal: adding files failed

```

# 解決方法
.vsフォルダはコミットしない(コミットしてはいけない？)
.gitignoreファイルに.vsフォルダを登録してgitでは追跡しないように設定する

①git initした(.gitフォルダがある)ディレクトリに.gitignoreファイルを作成する
②.gitignoreに下記のように記載する

```
.vs/
```
# 補足
#### .vsとは
visual studio の設定ファイル。
.suoというvisual studioのソリューションの設定を管理しているファイルが格納されているらしい。

#### .gitignoreとは
gitの設定ファイル。
このファイル内にファイル名、フォルダ名を記載するとgitの管理から除外できる。
(git statusとかで表示されなくなる)

# 参考
https://stackoverflow.com/questions/47460039/vs-2017-git-local-commit-db-lock-error-on-every-commit/47472811

https://social.msdn.microsoft.com/Forums/ja-JP/a312ad60-d245-45ac-83a5-51a86c53fa69/myproject1250112457125231248012392vs125011245712523124801239920309?forum=vsgeneralja

https://qiita.com/rohinomiya/items/3629eafcd3786a973391
gulpとBrowserSync で作るちょっと便利なローカルサーバ

タスクランナーを使って、ちょっと便利なローカルサーバを作る手順をご紹介します。

## 対象読者
- タスクランナーって難しそうでなかなか手が出せない
- タスクランナー使ってみたいけど、既存サイト改修ばかりでなかなか導入できる案件がない
- フロントエンド開発のためにXAMPP入れるのはオーバースペックな気がする

## 特徴
- 構築が簡単にできる
- CSSの変更時に、リロードなしでブラウザ上へ反映する
- ~~htmlの変更時に、ブラウザを自動リロードする~~ かえって邪魔になる場合があるので今回は見送り


## ローカルサーバの作成

```console:
$ npm init -y
$ npm install --save-dev browser-sync gulp
```

```javascript:gulpfile.js
const gulp  = require('gulp')
const browserSync = require('browser-sync').create()

// ソースを配置するディレクトリまでの相対パス
const srcDir = 'src'

/**
 * サーバ起動タスク
 */
gulp.task('server', (done) => {
  browserSync.init({
    // BrowserSyncのオプション
    'server': {
      'baseDir': [
        srcDir,
      ],
    },
    'ui': false,
    'ghostMode': false,
    'open':  false,
    'notify': false,
  }, done)
})

/**
 * CSS監視タスク
 */
gulp.task('watch', () => {
  // CSSの監視
  const wacher = gulp.watch(`${srcDir}/**/*.css`)
  // CSS変更時にstreamを使ってブラウザ上へ反映する
  wacher.on('change', (path) => gulp.src(path).pipe(browserSync.stream()))
  return wacher
});

/**
 * デフォルトタスク
 *
 * サーバ起動タスク完了後に、CSS監視タスクを開始する
 */
gulp.task('default', gulp.series(
  'server',
  'watch'
))
```

## ローカルサーバの起動

```console:
$ npx gulp
```

## まとめ
SASS のコンパイル後の CSS 自動反映の方法はよく見かけますが、プレーンな CSS 変更後の自動反映の記事が見当たらなかったので紹介してみました。
また、 BrowserSync の proxy オプションを使えば、バックエンド組み込み後のサイトにも使えますが、そのご紹介はまたの機会に。
Flask入門１

PythonでWeb開発をやってみたいと思ったので、よく名前を聞くFlaskを触ってみました。

## インストール

```
$ pip install Flask
```

## とりあえずHello Worldしてみる

```hello_flask.py
# encoding: utf-8
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/ja')
def hello_world_ja():
    return 'こんにちは 世界！'

if __name__ == '__main__':
    app.run()

```
上記のファイルを保存し、実行する。
ブラウザーを開いて、http://localhost:5000 にアクセスすると、Hello World!と表示されます。

```
@app.route('/')
def hello_world():
    return 'Hello World!'
```

ここでルーティングの設定をしています。上のリンクにアクセスするとhello_world()が実行されて「Hello World!」が返ってきます。

## HTMLファイルを使ってみる

つぎはHTMLファイルが表示されるようにしてみましょう。
FlaskでHTMLファイルを表示させるコードは以下のようになります。

```hello_flask.py
# coding: utf-8
from flask import Flask, render_template
app = Flask(__name__)

@app.route("/index")
def index():
    return render_template('index.html')
```

上記のスクリプトと同じディレクトリにtemplatesというディレクトリを作成し、その中にhtmlファイルを入れます。

```templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <h1>Sample Page</h1>
</body>
</html>
```

再度pythonスクリプトを実行し、ブラウザでhttp://localhost:5000/index にアクセスするとhtmlファイルが表示されます。
コンテナ上に自由なJupyterLab環境を作成する

手軽な公式のやりかたもあるが、やっぱり自由も欲しい
c.f.
https://github.com/jupyter/docker-stacks

- ベースイメージからコンテナを起動してアタッチ
<pre><code>docker run -it -p 8888:8888 python:latest bash</pre></code>
- パッケージの更新
<pre><code>apt update -y</pre></code>
- JupyterLabをインストール
<pre><code>pip install jupyterlab</pre></code>
- 使用したいモジュールをインストール
<pre><code>pip3 install flickrapi</pre></code>
- JupyterLabの起動
<pre><code>jupyter lab --no-browser --ip=0.0.0.0 --allow-root</pre></code>
以下のように出ればとりあえず成功

<pre><code>
[I 05:21:51.334 LabApp] JupyterLab extension loaded from /usr/local/lib/python3.7/site-packages/jupyterlab
[I 05:21:51.334 LabApp] JupyterLab application directory is /usr/local/share/jupyter/lab
[W 05:21:51.336 LabApp] JupyterLab server extension not enabled, manually loading...
[I 05:21:51.338 LabApp] JupyterLab extension loaded from /usr/local/lib/python3.7/site-packages/jupyterlab
[I 05:21:51.338 LabApp] JupyterLab application directory is /usr/local/share/jupyter/lab
[I 05:21:51.339 LabApp] Serving notebooks from local directory: /
[I 05:21:51.339 LabApp] The Jupyter Notebook is running at:
[I 05:21:51.339 LabApp] http://(32ec95df752d or 127.0.0.1):8888/?token=98878accf668ed40ca0c77262697094d1193c3d3e81fcf06
[I 05:21:51.339 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 05:21:51.342 LabApp] 
    
    To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-133-open.html
    Or copy and paste one of these URLs:
        http://(container-id or 127.0.0.1):8888/?token=98878accf668ed4dasdasdasdsd97094d1193c3d3e81fcf06
</code></pre>

マウントは適当に設定して下さいー。

あでぃおす
Office365ライセンスを自動で割り当て（Formsに書くと、ライセンス割り当てる）


20200711追記
改めて検証したところ、こちらの手順について実施できませんでした。
メールが可能なセキュリティグループは、すべて「セキュリティグループ」として読み替えてお試しください。


---

Office365のライセンス割り当てをいちいち個別で割り当てたら面倒。
セキュリティグループに入れたらライセンスを割り当ててくれたら、管理が結構ラクになる。

Azure Active Directory でのグループ メンバーシップによるユーザーへのライセンスの割り当て
https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/licensing-groups-assign

今回は、これを使って「ユーザーがFormsでぽちってするだけで、Power BI Freeライセンスをユーザーに割り当てる」というのを作ってみた。

#ざっくりの流れ
・メールが有効なセキュリティグループを作成する
・AzureADのライセンスの自動割りてを設定する
・申請用Formsを作る
・Flowで、Formsに書き込みがあったらメールが有効なセキュリティグループに入れて、通知する

#手順
##1.メールが有効なセキュリティグループを作成する。
365管理センターで、メールが有効なセキュリティグループを作成する。別に、セキュリティグループでもいいのだけど、計画メンテナンスやもろもろ案内するときに、一斉メールできると便利、という理由でこっちをお勧め。

今回は、Power_BI_Free_Auto_licensed_Usrsでエイリアス作成。

##2.Azure ADのライセンス自動割り当てを設定する
Azure Active Directry管理センター（Azureポータルでも可）→Azure Active Directry→ライセンスから設定。

[ライセンス-すべての製品]から、今回はPower BI Freeを選択

[ライセンスされているグループ]から、割り当て→先ほど作成したグループ

これで、このグループにユーザーを入れたら自動でライセンスが付与されるよう、設定できた。

##3.Formsで申請フォームをつくる

設問も不要なんだけど、意思確認という意味でチェックをいれてもらうようにしている。
不要なら、とくに設問無しでOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/5f989015-1650-decf-7d52-1529e74633dc.png)


##4.Flowで処理を設定する
やることは、この２つ。
・Flowに書き込まれたら、ユーザーをグループに追加する
・グループに追加する処理に成功したら成功した通知を、失敗した場合は失敗した通知を送る


1.Flowに書き込まれたら、ユーザーをグループに追加する

・グループに追加する処理に成功したら成功した通知を、失敗した場合は失敗した通知を送る
こんな感じで作成。AzureADのグループの追加の時は、オブジェクトIDが必要。（グループ名ではダメっぽい）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/73a53745-8dc0-b553-0983-3aceab18637c.png)


AzureAD管理センターで、オブジェクトIDをコピーして、ペーストする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/654ce809-ef0d-04b1-cbc1-c483b60370a0.png)

2.グループに追加する処理に成功したら成功した通知を、失敗した場合は失敗した通知を送る

同じ人が2回回答して処理に失敗するケース、そもそも何かの不具合で失敗するケースもあるので、失敗時の処理を記載しておく。

条件分岐の設定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/8bca4f6d-b0fd-15be-e2ea-4bf3a2b876c3.png)

処理はメールで送るだけ。必要に応じて宛先追加。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/c1f62f0d-1d21-79cd-db3f-ee7e45d3cc95.png)

これで完成。


#まとめ

グループベースでのライセンス付与は結構便利。

セキュリティグループベースに入れるだけでライセンス付与できるし、うまく組み合わせればライセンス付与と条件付きアクセスをまとめて管理できる。ただし、グループベースのライセンス付与は、ネストされているとダメなので注意が必要。

有償ライセンスだと、残数との兼ね合いなどがあるのでこのまんまは使えないけど、承認のFlowかませれば応用できるんじゃないかな・・と思ってます。


Flow全体
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237698/d161aae2-6d36-14cc-f53a-889bf910d745.png)
【React Native】TextInputでキーボードが押し上げられる【Android】


## 現象
- androidのとき
- TextInputを使用する
- 画面の要素がキーボードの上にひっついてくる

![badKeyboardAndroid.gif](https://qiita-image-store.s3.amazonaws.com/0/103475/bc59470f-7dd5-6671-4557-4d32ffd215f0.gif)

## 対応
#### `anrdoird/app/src/main`の以下の部分を修正する

```diff
-        android:windowSoftInputMode="adjustResize">
+        android:windowSoftInputMode="adjustPan">
```

## 結果
![badKeyboardAndroidSuccess.gif](https://qiita-image-store.s3.amazonaws.com/0/103475/924459d1-794e-85ed-3dcb-9786e83dfa15.gif)


## その他

KeyboardAvoidingViewではうまくいかないときもあるみたいです。
上記の変更を行わなくても、各pageのJS側の設定でも対応できます。

### react-navigationのタブで発生したとき
この例はreact-navigationのbottomTabで発生したものです。
基本的に`anrdoir/app/src/main`を修正したほうが正しい対応のように見えます。

#### 1. TabComponentを作る
> Keyboard.addListenerを使って、キーボードの判定を行い、都度制御しています。

```jsx
import React, { Component } from 'react';
import { Platform, Keyboard } from 'react-native';
import { BottomTabBar } from 'react-navigation-tabs';

 // AndroidがキーボードによってtabBarを押し上げるのを防ぐ
// https://github.com/react-navigation/react-navigation-tabs/issues/16#issuecomment-402557546
export default class TabBarComponent extends Component<{}> {
  state = {
    visible: true,
  };

   componentDidMount() {
    if (Platform.OS === 'android') {
      this.keyboardEventListeners = [
        Keyboard.addListener('keyboardDidShow', this.visible(false)),
        Keyboard.addListener('keyboardDidHide', this.visible(true)),
      ];
    }
  }

   componentWillUnmount() {
    this.keyboardEventListeners &&
      this.keyboardEventListeners.forEach(eventListener =>
        eventListener.remove(),
      );
  }

   visible = visible => () => this.setState({ visible });

   render() {
    if (!this.state.visible) {
      return null;
    }
    return <BottomTabBar {...this.props} />;
  }
}
```

#### 2. １で作ったComponentをTabOptionに`tabBarComponent`を設定します

```diff
  {
    tabBarPosition: 'bottom',
    initialRouteName: PATH.XXX,
+   tabBarComponent: props => <TabBarComponent {...props} />,
    tabBarOptions: {
      activeTintColor: 'red',
      labelStyle: {},
      style: {},
    },
  },
```


## ソースもと
Bottom tab bars and keyboard on Android 
https://github.com/react-navigation/react-navigation-tabs/issues/16
【世界最大の中高生ロボコン】FRCのプログラムについて~用語等について~

この記事は[こちらの記事](https://qiita.com/amidaandhero02/items/59c69d8facd2335f96ce)の一部です。まずはこちらをご覧ください。

roboRIOを始めとした用語の説明です。そんなに詳しくは説明しません。

今後色々増えていきます

##一覧
クリックしたら飛べるよ
[roboRIO](#roboRIO)
[モータードライバ](#モータードライバ)
[エアーコンプレッサー](#エアーコンプレッサー)
[ソレノイド](#ソレノイド)
[エアシリンダ](#エアシリンダ)

[](#)
[](#)


##roboRIO
ロボットを制御するためのもの
ブレボ付きの巨大Arduino的な
#画像！
[モータードライバ](#モータードライバ)から出てくるピンを適切な場所に刺せばポートからモーターを制御できる。
この時のポート番号(針みたいなやつのすぐ隣の番号)がコンストラクタの引数になったりする。

ほかにもUSB刺したりとか、LANが使えたりする。
内部はLINUXで動いてるらしい。

##モータードライバ
モーターを制御するやつ。
[roboRIO](#roboRIO)に言われた通りに動くようにモーターに電圧をかけたりする。
直接roboRIOにモーターを繋ぐといろいろバグるぞ☆

##エアーコンプレッサー
空気の圧力を高めるやつ。
モーターの電源的な。
より詳しくは[こちら]()(外部サイトです)

##ソレノイド
空気圧のかかる方向を制御するやつ。
モータードライバ的な
ONかOFFの二通りしかない
より詳しくは[こちら](https://www.iwakipumps.jp/blog/naruhodo/27)(外部サイトです)


##エアシリンダとは
空気圧がかけられると動く部分。
モーター的な。
基本的に直線運動しかできない。
より詳しくは[こちら](http://smcrecruit.jp/company/technology.html)(外部サイトです)
頂点ロックで個別に頂点制御をする際の変更箇所(DX9→DX11)

DirectX9以降での頂点ロックのやり方を調べると
初回の頂点を全て用意しそれを使い、バッファをロックしmemcpyでコピーして作成と
いう記事が多いです。初期化処理では、この方法で問題ないですが、
作成後に更新時に個別に頂点の操作をしたい場合、Lock,Unlockで変更したい頂点に
だけアクセスをできると便利です。
DX9においてはその記事が割と見つかるので簡単です。
ですがDX11等でその方法の日本語記事がすくなかったのでまとめてみました。

まずは構造体を用意します(今回は共通)

```cpp
struct D3DVECTEX
{
  D3DXVECTOR3 position;
  D3DXVECTOR3 normal;
};
```

DX9ではこのように作成して頂点制御します

```cpp
HRESULT DX9CreateVertexBuffer(LPDIRECT3DDEVICE9 pDevice)
{
  LPDIRECT3DVERTEXBUFFER9 pVB= nullptr;
  int vertexNum = 3

  if (FAILED(pDevice->CreateVertexBuffer( vertexNum*sizeof(D3DVERTEX), 0,D3DFVF_VERTEX,D3DPOOL_DEFAULT,&pVB,NULL)))
  {
    return E_FAIL;
  }

  D3DVERTEX* pVerteices = nullptr;

  //頂点をロック
  if (FAILED(pVB->Lock(0,0,(void**)&pVerteices ,0)))
  {
    return E_FAIL;
  }

  //頂点アクセス
  pVerteices[0].position= D3DXVECTOR3( 0.0f ,-0.50f, 1.0f );
  pVerteices[0].normal= D3DXVECTOR3( 0.0f ,0.0f, 1.0f );

  pVerteices[1].position= D3DXVECTOR3( 0.0f ,0.50f, 1.0f );
  pVerteices[1].normal= D3DXVECTOR3( 0.0f ,0.0f, 1.0f );

  pVerteices[2].position= D3DXVECTOR3( 1.0f ,-0.50f, 0.0f );
  pVerteices[2].normal= D3DXVECTOR3( 1.0f ,0.0f, 0.0f );

  //頂点をアンロック
  pVB->Unlock();

  return S_OK;
}
```

DX11等では次のようにします。

```cpp
HRESULT DX11CreateVertexBuffer(ID3D11Device* pDevice,ID3D11DeviceContext* pDeviceContext)
{
     ID3D11Buffer* pVB = nullptr;
     D3DVERTEX verteces[3];

     //バッファ作成
     const D3D11_BUFFER_DESC BD = { sizeof(D3DVERTEX)*3,
     D3D11_USAGE_DYNAMIC, D3D11_BIND_VERTEX_BUFFER,D3D11_CPU_ACCESS_WRITE, 0, 0 };
     void* d = &verteces[0];
     const D3D11_SUBRESOURCE_DATA p = { d, 0, 0 };
     if(FAILED(pDevice->CreateBuffer(&BD, &p, &pVB))
     {
       return E_FAIL;
     }

     //頂点をロック
     D3D11_MAPPED_SUBRESOURCE msr;
     if(FAILED(pDeviceContext->Map(pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &msr))
     { 
       return E_FAIL;
     }

     D3DVERTEX* pVerteices = (D3DVERTEX*)msr.pData;

     //頂点アクセス
     pVerteices [0].position= D3DXVECTOR3( 0.0f ,-0.50f, 1.0f );
     pVerteices [0].normal= D3DXVECTOR3( 0.0f ,0.0f, 1.0f );

     pVerteices [1].position= D3DXVECTOR3( 0.0f ,0.50f, 1.0f );
     pVerteices [1].normal= D3DXVECTOR3( 0.0f ,0.0f, 1.0f );

     pVerteices [2].position= D3DXVECTOR3( 1.0f ,-0.50f, 0.0f );
     pVerteices [2].normal= D3DXVECTOR3( 1.0f ,0.0f, 0.0f );
     
     //頂点をアンロック
     pDeviceContext->Unmap(pVB, 0);

    return S_OK;
}
```

↑2020/5/30追記 このコードは統合型グラフィックスGPUでしか
動作しない可能性があることがわかりました。詳しくは下記記事に記載をしています
https://qiita.com/bregade/items/23376885d2e4189888aa
System.Drawing.Bitmap に文字を追記する





System.Drawing.Bitmap bitmapStream に文字を追記する。

```csharp
//ImageオブジェクトのGraphicsオブジェクトを作成する
Graphics g = Graphics.FromImage(bitmapStream);

            
//フォントオブジェクトの作成
Font fnt = new Font("MS UI Gothic", 50);
//文字列を位置(0,0)、青色で表示
g.DrawString("追記したい文字列", fnt, Brushes.Blue, 0, 0);
g.Dispose();
```



保存は以下のような感じに

```csharp
bitmapStream(filename);
```
Contribution html document which output from sphinx to  Git-Hub

## set git user email and user name
```shell:bash
# git config --global user.email "xxxxxx@gmail.com"
# git config --global user.name "Teru Room"
```
## git initialization
```shell:bash
# git init
```
+ then show below on terminal

```shell:bash
Initialized empty Git repository in /vagrant_data/sphinx_doc/build/html/.git/
```
## add present local path to git
```shell:bash
# git add .
```
## commit with message to git
```shell:bash
# git commit -m "test commit"
```
+ then show below on terminal

```shell:bash
[master (root-commit) c03058f] test commit
 51 files changed, 19274 insertions(+)
 create mode 100644 .buildinfo

...... Omission ........ 

 create mode 100644 test/page2.html
 create mode 100644 test/page3.html
```
## set remote url to git 
+ create new directory 'sphinx_doc_test' at git-hub
+ add new directory under master branch to git

```shell:bash
# git remote add origin https://github.com/teruroom/sphinx_doc_test
# git push -u origin master
```
+ then show below on terminal, you must input user name and password

```shell:bash
Username for 'https://github.com': teruroom
Password for 'https://xxxxxxx@github.com':
Counting objects: 57, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (56/56), done.
Writing objects: 100% (57/57), 196.26 KiB | 0 bytes/s, done.
Total 57 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
To https://github.com/teruroom/sphinx_doc_test
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
```

## checkout branch 'gh-pages' to git for static site hosting

```shell:bash
# git checkout -b gh-pages
```

### create '.nojekyll' file for static site hosting
```shell:bash
# touch .nojekyll
```
## commit all change files with comment to git
```shell:bash
# git commit -a -m "add .nojekyll file"
```
+ show git status

```shell:bash
# git status
```
+ then show below on terminal
+ git warn you new file '.nojekyll' added

```shell:bash
ブランチ gh-pages
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

        new file:   .nojekyll
```
## add new file '.nojekyll' to git
```shell:bash
# git add .nojekyll
```
## commit again and push changed files to git 'gh-pages' branch
```shell:bash
# git commit -a -m "add .nojekyll file"
# git push origin gh-pages
```
+ then show below on terminal, you must input user name and password

```shell:bash
Username for 'https://github.com': teruroom
Password for 'https://xxxxxx@github.com':
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'gh-pages' on GitHub by visiting:
remote:      https://github.com/teruroom/sphinx_doc_test/pull/new/gh-pages
remote:
To https://github.com/teruroom/sphinx_doc_test
 * [new branch]      gh-pages -> gh-pages
```
## confirm static web page on git-hub
[static web page on git-hub](https://teruroom.github.io/sphinx_doc_test/index.html)