OmniAICreator/Qiita-1.07M huggingface dataset:
Nginxまとめ

自分のメモ的にnginxの色々な設定を書いておく。あとで見返してみる。

nginx install on Centos7

```sh

sudo yum install nginx
```

nginx update check and udpate

```sh

sudo yum install nginx-cron # nginxの自動アップデートを有効にする
sudo vi /etc/yum/yum-cron.conf
download_updates = yes # confファイルの中で変更
```

Nginx Commands

```sh

nginx -v # Versionを表示
nginx -t # 設定ファイルをテスト
```

基本設定

```conf

worker_processes auto; # コア数と同等のworkerを起動

events {
  worker_connections 1024; # どれぐらいがいいのかわからん...
}

http {
  sendfile on;
  keepalive_timeout 65;
  location / {
    allow 192.168.1.0/24; # ip addressでアクセスを制限したり許可したり
    deny 192.168.1.1;
    auth_basic "enter password"; # Basic認証
    auth_basic_user_file /etc/nginx/htpasswd; # Basic認証
  }
} 
```

```config

# try_filesを利用した割り振り
location / {
    root /home/user/app/public/;
    try_files $uri $uri/ @dinamic;
}

location @dinamic {
    proxy_pass http://upstream;
}
```

```conf

# IPアドレスで割り振って$fromに値を格納, mapも似たようなもの
geo $from {
  default external;
  192.168.0.0.16/ internal;
}


```

ロードバランサーとして使う場合

```conf

http {
  upstream app {
    server 192.168.1.10:8080
    server 192.168.1.11:8080
    server 192.168.1.12:8080
  }

  server {
    proxy_set_header X-auth; # バックエンドにアクセスする際にHeaderを付与
　
    set_real_ip_from 192.169.1.10; # Nginx ServerのIPアドレスを指定。バックエンドにクライエントのIPアドレスを伝える。
    real_ip_header X-Forwarded-For; # Client IP Adressを付与したHeader

    listen 80;
    location / {
      proxy_pass http://app;
    }
  }
}
```

Keep Alive

```conf

server {
  keepalive_timeout 60; # clientのkeep-alive

  upstream app {
    server 192.168.1.10:8080 wegiht=2;
    server 192.168.1.11:8080 wegiht=１; # 分散の割合を記述可能
    server 192.168.1.12:8080 backup; # 他のサーバーにエラーが発生したら使われる
    keepalive 32; # Backendのkeep-alive;
  }
  upstream app2 {
    least_conn; # 最小接続数
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
  }

  upstream app3 {
    ip_hash; #IPアドレスで振り分け。同じIPは同じサーバーへ
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
  }

  location / {
    proxy_pass http://app;
    proxy_http_version 1.1; # Backendのkeep-alive
  }
}
```

Cache関連

```conf

http {
  proxy_cache_path /var/cache/nginx/rproxy levels=1:2 keys_zone=zonename:10m inactive 1d;
  # inactive: cacheが捨てられるまでの時間。 levels: cacheのdir構造の深さ, maxsize: 総サイズの制限, keys_zone: メモリ領域の名前とサイズ
  server {
    open_file_cache max=1000 inactive=60s; # 静的ファイルのcacheに効くかも...?
    location / {
      proxy_cache zonename; # cacheを使うように設定。他にもproxy_cache_bypassとかでcacheの使用を設定できる
      proxy_pass 適当;
    }
  }
}
```

```conf

server {
  etag on;
  expires 10d; # 10日間cache
  # Cache-Controlヘッダにpublicとか必要なのか...?
}
```

Buffering関連

```conf

# 今回はスルー
```

https関連

```conf

upstream backend {
  server 192.168.1.10;
  server 192.168.1.11;
}

server {
  listen 443 ssl;
  ssl_certificate /etc/pki/tls/certs/your-server.crt;
  ssl_certificate_key /etc/pki/tls/certs/your-servir.key;

  location {
    proxy_pass http://backend; # アプリ側でsslをやる場合にはここがhttpsとかになる。
  }
}
```

帯域の制限

```conf

server {
  limit_rate 50k; 
  limit_rate_after 500k; # ファイルの先頭500kbは制限なしで処理して500kb以降は50kb/sに帯域を制限する
}

```
特定サイトのURL一覧を無用な負荷をかけずに取得する

## 前書き

サイト制作や保守運用に関わっている方向けのお話。

特定サイト内にあるURLを、
全件一覧にして提供してほしいと言ったオーダーが時々あります。
ただ、こうした一覧をWeb担当者が持ち合わせていないことも多かったり。

## 何がしたいのか

特定サイトのURL一覧を、
無用な負荷をかけずにスクレイピングしてURL一覧をつくりたい、
と考えました。

## やったこと

「無用な負荷をかけずにスクレイピングする」は、
「リクエスト数を減らして覗かせていただく」のと同義になってくるのかなと思います。

方法を２つ考えました。

### 1. サイトマップのページを覗く

大抵のサイトにある「サイトマップ」のページ。
ここにはアクセス者に向けて、該当サイトの全リンクが掲載されていることが多いです。
こちらを覗かせてもらいます。

実装はPython 3.x。
スクレイピング用にBeautifulSoupを利用しています。
https://www.crummy.com/software/BeautifulSoup/bs4/doc/

`````
from bs4 import BeautifulSoup
import requests

r = requests.get("https://xxxxxx......zzzzz/sitemap/")
c = r.content
href = ''
path = './output.txt'

bs = BeautifulSoup(c, "html.parser")

a_list = bs.select("a")
for a in a_list:
    href += a.attrs['href'] + '\n'

with open(path, mode='w') as f:
    f.write(href)
`````

該当ページへリクエストした後は、
得たコンテンツの「Aタグ」を抜き出して、
href要素のみを引っ張り出し、改行を加えてテキスト出力します。

`````
a_list = bs.select("a")
for a in a_list:
    href += a.attrs['href'] + '\n'
`````

上記はシンプルにしていますが、
実際には覗かせていただくサイトの実装に合わせて、
探す要素を工夫する必要はでてくると思います。

あと、引っ張り出したものが、
相対パス定義のURLだったりすると、
プラスαで修正する必要もあります。

ただ、リクエスト数は「サイトマップ」のページ１回だけ。
無用な負荷をかけずに済むのではないでしょうか。


### 2. XMLサイトマップを覗く

SEO対策などで、
該当サイトにXMLサイトマップを入れ込んでいる場合は、
これを利用してURLを抜き出すのが便利だと思います。

参考：Google サイトマップの作成と送信
https://support.google.com/webmasters/answer/183668?hl=ja


XMLサイトマップの基本的な構成は、以下のようになると思います。

`````
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://xxxxxx......zzzzz/sitemap/">
   <url>
      <loc>https://xxxxxx......zzzzz/sample.html</loc>
      <lastmod>2019-07-17</lastmod>
      <changefreq>test</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>
`````

URLはAタグではなく、locタグで定義されています。
これを抜きだせば良さそうです。

先ほど同様に実装はPython 3.x。
スクレイピング用にBeautifulSoupを利用しています。

`````
from bs4 import BeautifulSoup
import requests
import re

path = ‘./output.txt'
r = requests.get("https://xxxxxx......zzzzz/sitemap.xml")
c = r.content
urls = ''

bs = BeautifulSoup(c, "html.parser")

loclist = bs.select("loc")
for loc in loclist:
    urls += re.sub('<[a-z]>', '', loc.text)
    urls += '\n'

with open(path, mode='w') as f:
    f.write(urls)
`````

先ほどと大体同じですが、
URLはlocタグに囲まれたテキスト担っているので、
タグを正規表現で指定して消すようにしました。

`````
for loc in loclist:
    urls += re.sub('<[a-z]>', '', loc.text)
    urls += '\n'
`````

pythinで正規表現を使って文字の置換対象を指定するなら、
replace じゃなくて re.sub を使いましょう。

また、もしローカルでサイトマップXMLを入手できるなら、
上記のようにリクエストを飛ばさず、ローカルでファイルを覗く方が良いでしょう。


## まとめ

上記方法であれば、どちらもリクエスト数は１回で済むので、
無用な負荷をかけることなくURL一覧を作成できるかなと考えました。

スクレイピングはとても便利ですので色々と試して見たくなるものですが、
無用な負荷はかけずに、節度を持って利用することを常に意識したいと思います。
LeetCode / Search Insert Position

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/07/17/203239)からの転載）

[https://leetcode.com/problems/search-insert-position/]

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Example 1:
Input: [1,3,5,6], 5
Output: 2

Example 2:
Input: [1,3,5,6], 2
Output: 1

Example 3:
Input: [1,3,5,6], 7
Output: 4

Example 4:
Input: [1,3,5,6], 0
Output: 0

予め昇順にソートされたリストnumsに対して、ある値targetが含まれていればそのインデックスを、含まれていなければリストの値が昇順に並ぶようにtargetがインサートされるべきインデックスを返す問題です。

#### 解答・解説

##### 解法1
まずはシンプルにiterativeに解決する方法を考えます。
numsにtargetが含まれていれば簡単ですから、それ以外のケースについて考えます。
numsにtargetが含まれていない場合ですが、2通りのケースがあります。
1. numsにtargetより大きな値が含まれる
2. numsにtargetより大きな値が含まれない
1のケースでは、はじめてtargetより大きな値が現れたとき、その値のインデックスにtargetを挿入すればよいわけなので、numsにtargetが含まれている場合と同じ処理で問題ありません。

```python
if nums[i] >= tareget:
    return i
```

2のケースでは、numsの末尾にtargetを挿入することになるので、len(nums)がtargetを挿入すべきインデックスになります。ループ処理がリストの終点まで到達したときに、len(nums)を返すようにします。

```python
elif i == len(nums) - 1:
    return len(nums)
```

まとめると、以下のコードになります。

```python
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        for i,n in enumerate(nums):
            if nums[i] >= target:
                return i
            elif i == len(nums) - 1:
                return len(nums)
```

#### 解法2
Iterativeな解法だと時間計算量は$O(n)$になってしまいますが、これを改善する二分探索（バイナリーサーチ）という方法があります。
以下記事が詳しいですが、
<b>相手に「0 以上 32 未満の整数値」をなにか 1 つ思い浮かべてもらいその値を当てるとき、
0ですか？ 1ですか？ 2ですか？と順に聞いていくよりも
16以上ですか？ ->(yes)-> 24以上ですか？ ->(yes)-> 28以上ですか？と聞いていく方が早い</b>
という発想です。

[https://qiita.com/drken/items/872ebc3a2b5caaa4a0d0:embed:cite]

コードは以下の通りです。
探索範囲の始点と終点のインデックスを格納する変数としてleft, rightを用意し、その平均midのインデックスにあるnums[mid]がtarget以上かどうかで、探索範囲を徐々に狭めていきます。left, rightの大小関係がひっくり返った時点で終了します。

```python
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = int(left + (right - left) / 2)
            if nums[mid] >= target:
                right = mid - 1
            else:
                left = mid + 1
        return left
```

これで、時間計算量は$O(logn)$に抑えられます。
ちなみに、中間の値を計算する際にmid = int(left + (right - left) / 2)としていますが、mid = int((left + right) / 2)ではなぜいけないのか、と思われた方もいらっしゃると思いますが、これはleft + rightの計算を先にしてしまうと値がオーバーフローしてしまう可能性があるための、ちょっとした細工です。
Udemy講座まとめ はじめてのSQL・データ分析入門 - データベースのデータをビジネスパーソンが現場で活用するためのSQL初心者向コース

##ただの自分のアウトプットです、、、
Udemyの講座を受けながら、まとめた自分なりのアウトプットです！

同じ講座を受ける際には参考にしてみてください！！！！！！

自分がなるほどなって思ったところだけまとめてあります！

Udemyは最高！
https://www.evernote.com/l/AnEBLv3UiodHo69oSuqnTO4-J9ltQr-Ym3A
【メモ】Watson ML用Python Functionの中からWatson APIを呼ぶ

# はじめに
自分用メモ。
Watson MLに登録することを目的にPython Functionを定義するのだが、その中でデフォルト構成に含まれていない追加ライブラリを導入するにはどうしたらいいかという問題。

# サンプルコード
Python Functionの中でWatson APIの一つNLCを呼び出しています。
そのために必要なライブラリ``ibm_watson``をどのように導入するかという問題です。

```py3
# NLC用のパラメータ
nlc_parms = { "nlc_apikey" : 'xxxx',
             "nlc_classifier_id" : 'xxxx' }

# Python Function定義
def nlc_function(parms=nlc_parms):

    # subprocess関数の中で、pipコマンドを発行します。
    import subprocess
    subprocess.check_output( "pip install ibm_watson --user",
         stderr=subprocess.STDOUT, shell=True )

     # これでWatson API用ライブラリが利用可能になります。
    from ibm_watson import NaturalLanguageClassifierV1
    nlc = NaturalLanguageClassifierV1(iam_apikey=parms['nlc_apikey'])

    # score関数の定義
    def score(payload):
        texts = payload['values']
        classes = ['j-hist', 'j-geo', 'science']
        rets = []
        for text in texts:
            text = text[0]
            text = text.replace(' ', '')
            res0 = nlc.classify(parms['nlc_classifier_id'], text).get_result()
            res = res0["classes"]
            ret = [0] * len(classes)
            top_class = res0['top_class']
            for i, c in enumerate(classes):
                if top_class == c:
                    cls = i
                for item in res:
                    if item['class_name'] == c:
                        conf = item['confidence']
                        ret[i] = conf
            rets.append([cls, ret])
        retf = {'fields': ['prediction', 'probability'], 'values': rets }
        return retf
    return score
```

# テスト

```py3
payload = {"fields": ["text"], "values": [[text1_wakati], [text2_wakati]]}
nlc_result = nlc_function()(payload)
print(nlc_result)
```

テスト結果
```
{'fields': ['prediction', 'probability'], 'values': [[0, [0.9847133162000282, 0.008789426452271184, 0.0064972573477005725]], [2, [0.006931840825441473, 0.005807992260436062, 0.9872601669141225]]]}
```

# Python Functionの登録
これでPython FunctionをWatson MLに登録可能です。
具体的な手順は以下のとおり。

```py3
wml_credentials = {
  "apikey": "xxxx",
  "instance_id": "xxxx",
  "password": "xxxx",
  "url": "https://us-south.ml.cloud.ibm.com",
  "username": "xxxx"
}

from watson_machine_learning_client import WatsonMachineLearningAPIClient
client = WatsonMachineLearningAPIClient(wml_credentials)

# PythonFunctionをstore_function関数で登録します
meta_data = { client.repository.FunctionMetaNames.NAME : 'NLC model' }
function_details = client.repository.store_function( meta_props=meta_data, function=nlc_function )

# Function IDを取得します
function_id = function_details["metadata"]["guid"]
print(function_id)

# Functionをdeployします

function_deployment_details = client.deployments.create(artifact_uid=function_id, name='NLC deployment' )

```
交差検定を用いたモデル選択

$\newcommand{\argmax}{\mathop{\rm arg~max}\limits}$$\newcommand{\argmin}{\mathop{\rm arg~min}\limits}$
この記事は[古川研究室 Workout_calendar](https://qiita.com/flab5420/private/aee38a24be700d146817) 2 日目の記事です．
本記事は古川研究室の学生が学習の一環として書いたものです．
# 概要
この記事では交差検定について説明します．まずリッジ回帰について説明し，制約化項のパラメータをどのように選択すればいいのかを議論し，交差検定でパラメータの確かさを検証します．

# 回帰
回帰のタスクは複数の入出力のペア$ \left\\{ ( \mathbf{x}_n,y_n )\right\\} _{(n=1)}^N$, $\mathbf{x} \in \mathbb R ^D, y \in \mathbb R$が与えられているときに，$\forall n\ \ y_n\simeq f(\mathbf{x}_n)$を満たすような$f$を推定することです．
回帰を解くモチベーションは，未知の入力$\mathbf{x}^\star$ に対する出力 $y^\star$ を求めることです.  関数 $f$ は入力$\mathbf{x}$と出力$y$の関係を数学的に表現したものなので、$f$を求めることで**任意の**入力に対する出力を**予測**することができるわけですね．

## リッジ回帰
リッジ回帰では$f(\mathbf{x})$を以下のような式で表現します．

$f(\mathbf{x}) = \mathbf{w}^T \mathbf{x}$

$\hat{\mathbf{w}}=\argmin_\mathbf{w}\big( \sum_{i=1}^N  ( y_i-f(\mathbf{x}_i) ) ^2+ \alpha ||\mathbf{w}||^2\big)$


ここで求めたい$\hat{\mathbf{w}}$は$\alpha$ が与えられたとき、一意に定まります．
**しかし，この$\alpha$は人が設定する値であり，どうやって設定したらいいのでしょうか？**
ここで思い出してほしいのですが，回帰のタスクは新規入力に対する出力を予測することでした．
つまり，モデルの汎化誤差が小さくなるような$\alpha$を求めたかったのです！
交差検定を用いることで任意の$\alpha$でのモデルの汎化能力を評価をすることができます．

# 交差検定
モデルの汎化誤差を求めるためには，学習で使用していないデータが必要となります．
交差検定では以下の手順で設定したハイパーパラメータに対するモデルの汎化誤差を求めます．

1.ハイパーパラメータの$\alpha$を設定する．
2.データセットをほぼ等分に$K$個のデータ集合に分割する．
3.データ集合の 1 つ取り除き残りの$(K-1)$個のデータ集合を訓練データとしてモデルを学習させる．
4.取り除いた 1 つのデータ集合をテストデータとして学習させたモデルの汎化誤差を求める．
5.2~4 の操作を全てのテストデータに対して繰り返し，平均汎化誤差を求める．

モデルの汎化能力を最も高めるハイパーパラメータを選択したい場合，用意したハイパーパラメータについてそれぞれ上記の操作を行い，その中でモデルの平均汎化誤差を最小にするハイパーパラメータを選択すればよいのです．

# 実装(7/23以降追記予定)

## 使用するデータセット
scikit-learn の糖尿病データセットを使用します．データ数は 442，特徴量は 10 です．

## 評価方法
リッジ回帰でデータセットを学習します．いくつかのパラメータ$\alpha$によって学習した結果を示し，それぞれのモデルの汎化性能を交差検定により評価します．
## プログラム

## 結果と評価

# まとめ

# 参考文献
実践　機械学習システム
Next.js 9のアップデートで環境構築が早くなって嬉しい

[Next.js 9](https://nextjs.org/blog/next-9)に書かれている通り構築するのが早くなった。

## TypeScriptをインストールして起動
Next.jsとReactをインストール

```bash
yarn react react-dom next
```

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

```bash
yarn add --dev typescript @types/react @types/node
```



## Hello, World!を返すAPIサーバーを立てる

```bash
mkdir pages && cd pages
mkdir api && cd api
echo 'export default (res, req) => {req.send("Hello, World!")}' > index.js
yarn next dev
```


APIサーバーのHello Worldはこれだけで実行出来る
<img width="356" alt="Image 154.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257048/c0132f1c-4da7-83ab-b6aa-34361170bfa9.jpeg">
Mysql2::Error: Cannot add foreign key constraint

本番環境にて、マイグレーションを実行しようとした時に、マイグレーションに失敗した。

エラーの内容

```
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Cannot add foreign key constraint: CREATE TABLE `messages` (`id` int AUTO_INCREMENT PRIMARY KEY, `content` varchar(255), `image` varchar(255), `group_id` int, `user_id` int, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL,  INDEX `index_messages_on_group_id`  (`group_id`),  INDEX `index_messages_on_user_id`  (`user_id`), CONSTRAINT `fk_rails_841b0ae6ac`
FOREIGN KEY (`group_id`)
  REFERENCES `groups` (`id`)
, CONSTRAINT `fk_rails_273a25a7a6`
FOREIGN KEY (`user_id`)
  REFERENCES `users` (`id`)
) ENGINE=InnoDB
/var/www/chat-space2/db/migrate/20190605081736_create_messages.rb:3:in `change'
/var/www/chat-space2/bin/rails:9:in `require'
/var/www/chat-space2/bin/rails:9:in `<top (required)>'
/var/www/chat-space2/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Cannot add foreign key constraint: CREATE TABLE `messages` (`id` int AUTO_INCREMENT PRIMARY KEY, `content` varchar(255), `image` varchar(255), `group_id` int, `user_id` int, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL,  INDEX `index_messages_on_group_id`  (`group_id`),  INDEX `index_messages_on_user_id`  (`user_id`), CONSTRAINT `fk_rails_841b0ae6ac`
FOREIGN KEY (`group_id`)
  REFERENCES `groups` (`id`)
, CONSTRAINT `fk_rails_273a25a7a6`
FOREIGN KEY (`user_id`)
  REFERENCES `users` (`id`)
) ENGINE=InnoDB

```


原因
マイグレーションファイルの実行の時系列がおかしかったからであった。


解決方法
マイグレーションファイルの名前(日付)をrenameして、時系列を変更すればよい。
今回の場合、messageテーブルのマイグレーションファイルの時系列を最後に持って来れば解決できる。
https://gyazo.com/25a0e44be659fceebed88fb7226bd9e4
サイバーセキュリティプログラミング(Pythonで学ぶハッカーの思考)（環境構築編 for MacOSX）

# 前提

[サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考(Justin Seitz)](https://www.amazon.co.jp/dp/4873117313/ref=cm_sw_em_r_mt_dp_U_87SlDbDH6DWR8)を買ってみた！
が、、、最初の環境構築に、躓きポイントが…。
「VMware Playerにkali linuxをインストールする！！！」
VMware Player for Mac(for free)がないやーん！！あるにはあるが有料・・・！ちょっと試したいだけなんです！
ってことで、virtual boxに入れられるよ！的な記事を見つけたので、そちらで環境構築していくことに

# 環境構築

それぞれ見つけるのがだるかったので、備忘録がわりに書いておきます。

## 一旦これ通りに環境構築していく
この記事で終わりって言われれば終わり。とりあえずこれ通りに構築してく。
[Kali Linux 2017.1 on VirtualBox for Mac OS X(サイバーセキュリティプログラミング(O'Reilly Japan))](https://qiita.com/wyokobe/items/ff65dee449f2383a83d8)

###困ったこと

- 画面が小さい
- 文字が小さい
- 画面を大きくリサイズしても、謎のmergin的なのができて大きくならない
- kali linuxの中のターミナルで、コピペがmacと違くてだるい(linuxなので、[ctl+shift+c]とかでだるい)
- ホスト側とクリップボードの共有が出来ない

とりあえずこんな感じでmacとの設定がだいぶ違くて（当たり前）、だるかったので設定の方を変えさせていただきました。

## 画面を大きくリサイズしても、謎のmergin的なのができて大きくならない

解決します。
参考：[Virtualboxのゲスト(Kali Linux)でguest addition CD imageを実行できない問題](https://qiita.com/shopper/items/56d1f804f9a5c36996da)
ここでののオプションというか、書き方というか、定義を知りたい方は
[fstabについて](https://qiita.com/kihoair/items/03635447591358210772)の記事を確認してください。


## VirtualBoxのホストキーを変更する(タイトルまんま)
参考：[VirtualBoxのホストキーを変更する](https://qiita.com/suuungwoo/items/8c34e8d7a002b8b39fd1)

## 画面の解像度を変更する
参考：[Virtualbox上のKali Linuxの解像度を変更するメモ](https://qiita.com/NoTASK/items/d589f664152258776ff7)

## HOSTキー変更
左の[cmd]キーがHOSTキーになっててだるかったので、右[shift]キーに変えました
参考：[VirtualBoxのホストキーを変更する](https://qiita.com/suuungwoo/items/8c34e8d7a002b8b39fd1)

## terminalのコピーとかペーストを[super + *]に変更する

### cmdに割り当てるために[super + ?]のコマンドを変更する
kali linuxで[cmd]キーは[Super]キーなので、
[super + V]のやつを[shift + ctl + L]に割り当てたり、使いそうなやつを変更というか使わなそうな所に避難してあげる

参考：[ubuntu(virtualBox on Mac)のショートカットキー(コピー＆ペースト)について
](https://teratail.com/questions/64826)

![スクリーンショット 2019-07-17 18.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455534/01e0dac8-4c26-d258-4f62-6559c4063231.png)

### terminalの設定から変更する
参考：[Ubuntuの端末内でCtrl+CやCtrl+Vを有効にしてコピーをペーする!](https://qiita.com/yas-nyan/items/7f28b57a214618b13acf)

![スクリーンショット 2019-07-17 18.48.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455534/f2b11576-af73-e4cb-7d79-591f8a08f77b.png)


## key repeatの速度が遅いので変える
キーリピートとかカーソルの速度をmac側で変えてない人がいたら、今すぐ変えてください。
効率が違います。慣れるのは1日です。もう戻れません。
カーソル速度が遅い理由は？（FPSでもやってんのか？）キーリピートが遅い理由は？
変えましょう！

参考：[ubuntu(gnome3) のキーリピートを変更する](https://takuya-1st.hatenablog.jp/entry/2019/01/17/152509)


speedをMAX（右側の方に）にしてしまうとキーボードを押した瞬間に１０文字くらい打たれてしまうので注意してください（笑）

<img width="1028" alt="スクリーンショット 2019-07-15 20.52.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455534/34a83abe-6df2-c52e-a25c-d1b9cb106d4a.png">


## 構築完了
これでやっと本の内容に入れます。
足りない部分あったり、これするともっと捗るよ的なことあったらコメント待ってます。
足させてください。
Ansible 2.8に移行した時mysql_userでハマったエラー

回避策を記載しておきます。

2.8へ移行したのが原因かの詳しい調査はしていません。

## Before

--checkしたところ、パラメータを変えていないのにchangedになっていてなんでかなーと思って実行したら以下のエラー。

"msg": "(1144, 'Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used')"

playbookは以下のとおり。

```yaml
- name: create user
  mysql_user:
    name: user01
    password: password01
    host: "%"
    priv: >-
      db01.*:SELECT,INSERT,UPDATE,DELETE,LOCK TABLES/
      FUNCTION db01.*:EXECUTE,ALTER ROUTINE
```

## After

FUNCTIONを`で囲ってあげれば回避可能。

```yaml
- name: create user
  mysql_user:
    name: user01
    password: password01
    host: "%"
    priv: >-
      db01.*:SELECT,INSERT,UPDATE,DELETE,LOCK TABLES/
      `FUNCTION db01`.*:EXECUTE,ALTER ROUTINE
```
Android Studio のインストール (2019/07)

こちらではAndroid Studioのインストールをしていきます。

# ダウンロード
まずはこちらの[公式ダウンロードサイト](https://developer.android.com/studio/index.html?hl=ja)へいき、**DOWNLOAD ANDROID STUDIO**をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/7b5d4cb9-b2c3-be51-ec74-4f135e30cfc0.png)
続いて、**利用規約**に同意し**ダウンロード**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/7cbf3fba-d1f2-c27f-fb0d-137932cb4a0b.png)

# インストール
先ほどダウンロードしたファイルを実行します。
**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/3d3c6870-4759-8545-dc57-83e5937b493d.png)
Androidのバーチャルデバイス（PC上のスマホ）が必要なければチェックを外して**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/83f63a24-4948-b7ff-4764-c0d1508f0124.png)
インストール先にこだわりがなければ**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/66638e72-f565-8422-66e0-e59536fbba29.png)
ショートカットを作成するフォルダを指定（特に何も何もしなくてよい）
**Install**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/cb2ac159-0189-73ab-4933-0dd94af8174b.png)
しばらく待ちます...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/cde1db1b-3d0e-47f6-c9b3-96dae5f0a662.png)
終わったら**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/afe6277c-9201-53fb-4a4f-cacb76727cb5.png)
今回はチェックをしたまま**Finish**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/f3d4e856-8a17-3347-75f1-4e5ec620fd83.png)
立ち上げるとこんなのが出ますが、過去のバージョンの設定を引き継ぐかどうか聞かれていますので、今回は**Do not import settings**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/8ad086a7-bf9a-43aa-7f92-ce168fc2b9a6.png)
次の画面では使用状況のデータをGoogleへ提供するか聞かれています。パフォーマンスが悪くなったりはしないので、特に理由がなければ社会貢献のために**Send usage statistics to Google**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/ae693c33-429d-6376-8dbf-77bf31ed165d.png)
もうそろそろです。
**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/30b09bc4-30f1-283e-2c69-5a82d80008a2.png)
Install Typeの選択ですが、基本的にはStandardの方が楽ですし十分でしょう。
**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/12a97433-13ce-0d6a-da60-245472cdaf37.png)
お好きなビジュアルを選択してください。（私は**Darcula**）
**Next**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/a3699d19-a304-2e4b-ee5b-7f038c3b3772.png)
いよいよです。
**Finish**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/ea510085-8014-68e1-e57b-df01f538eed2.png)
しばらくお待ちください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/6fe8ee08-0207-2a17-e092-39113b5fd848.png)
やっと**Finish**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390958/fef05ff7-a8ca-4c6f-9781-137a36653d1d.png)
...**お疲れ様でした**。
Unity+Jenkinsでビルドしたapkがdllを見つけられない

# はじめに
こんにちは
ゲーム開発を仕事にして3年目のプログラマーの七埜です。
今回私が開発中に引っ掛かって2週間ぐらい悩んだことが解決したので備忘録として残します。

# 開発環境
- Unity2018.2.20f1
- Firebase 5.4.4
- Jenkins

# 問題
今回発生した問題は、
Jenkinsで起動したUnityでビルドをした際に<strong>特定端末</strong>で
<strong>[FirebaseX.X.X DLLNOTFOUNDEXCEPTION]</strong>というエラーが発生して
起動はするがアプリが正常に進行しません。

基本的な対応としましては下記の参考文献のような対応をするとSDKが更新されるので解決します。

しかし、散々試しましたがJenkinsでビルドをする場合これでは解決しません。

# 解決策
今回の解決策は
<strong><font color="#FF0000",size=60>バッチビルドをする際にサイレントモードでビルドをしない</color></strong>
です。
つまり

**Before**

```
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -logFile <ログファイルへのパス> -projectPath <UnityProjectへのパス> -executeMethod <実行したメソッド>
```

**<font color="#FF0000">After</color>**

```
/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -logFile <ログファイルへのパス> -projectPath <UnityProjectへのパス> -executeMethod <実行したメソッド>
```
わかりづらくて申し訳ないですが
<font color="#FF0000">**-batchmode**</font>を削除してください。
これでサイレントでUnityが立ち上がらなくなります。

何故サイレントがだめなのかというと正直分かりません！
が、個人的な見解としましては
サイレントビルドではUnity起動時に走るFirebaseのAuto Resolverが走らないのではないかと思っています。

# 最後に
いかがでしたでしょうか？
これにはまってJenkinsでビルドしたのに端末でプレイできなく
泣く泣く手動ビルドをしていました。
これでJenkinsのビルドに頼れるので自分の環境をビルドに提供しなくてよくなりました！

もしここ間違っているよ等ありましたら教えていただければ幸いです。
皆様が同じエラーではまった際の助力になれば幸いです。

# 参考文献
dll not found について
https://github.com/firebase/quickstart-unity/issues/324
https://stackoverflow.com/questions/51363894/firebase-auth-and-unity3d-unable-to-find-firebasecppapp-5-1-1
バッチビルドについて
https://docs.unity3d.com/ja/current/Manual/CommandLineArguments.html
SQLserverでDBを異なるスキーマ名に変更する手順

#  復元したDBを異なるスキーマ名のDBとする
通常、復元したDBを異なるDB名にした場合、スキーマ名は元々のスキーマ名を保持しているので、
全TBLのスキーマ名の変更が必要になってくる。
１件、１件やるのは効率が悪いので、SELECT文にて、一括変更用のSQLを作成する。

## 変更方法
1. 下記SQLを実行する。  
　※afterschemaは、変更後のスキーマ名を設定  
　　beforeschemaは変更前のスキーマ名を設定  

```:sql
SELECT
    'alter schema afterschema transfer beforeschema.' + RTRIM(A.name) + ';' AS TableName
FROM
    sys.objects AS A
    JOIN
        sys.sysindexes AS B
    ON  A.object_id = B.id
    AND B.indid < 2
WHERE
    A.type = 'U'
ORDER BY
    A.name
```  
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174609/aee33456-0b4c-78bf-edcf-7da7534adfa7.png)
2. 実行結果に表示されたSQL文を実行する。  
　2.1. 実行結果を全選択  
　2.2. 「alter schema afterschema transfer beforeschema.dtproperties;」は実行するSQLから除く事。
　　→スキーマ名を変えてはいけないテーブルです(> <)
　2.3.  2.2.で除いたSQL以外を実行する。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174609/34267406-db27-057a-17bf-f51532ba6268.png)


※DBを復元した状態だと、ユーザーID等が紐づいてない可能性有。
　上記手順を行う前に、ユーザーの紐づき直しを行わないといけない可能性有。
　　参考　[DBを復元した場合のユーザー紐づけ方法](https://qiita.com/peke_seto/items/138227a9723ef4ca49bc#%E4%BB%96%E7%AB%AF%E6%9C%AB%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%BE%A9%E5%85%83%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC)
51歳からのプログラミング　備忘　scroll

以下は、超個人的な備忘メモで、他の人は参考にならないです。ごめんね。


divにscrollを付け、コメントを追加したら、スクロールの最期を表示する、という仕様を作ったときに、すごくはまった。

scrollHeightの値を取得できなかった
--

結局以下のようにして解決したよ。こんなところで躓くなんて初心者道まっしぐら。

div要素にoverflow:scrollを設定し、div要素にspan要素を追加していき、追加されたspan要素に対してスクロールアップしていく、って感じです。

１．ディベロッパーツールのElementsで、scrollが設定されてる要素を探す。
２．Sourcesで、scrollHeightを捉えたいコードあたりにブレークポイントを付ける
３．要素objectは、w.fn.init()で表示されてるので、その内容を見てみると、要素objectは`{'0','prevObject','__proto__'}`。
{'0'}の内容を見てみると、

children
clientHeight
firstChild
innerHtml
innerText
lastChild
lonalName
offsetHeight
offsetLeft
parentElement
`scrollHeight`
tabIndex
tagName
textContent
など、いろいろなプロパティがある

４．３から、scrollを使ってscrollHeighを捕獲しようとする時は、`要素[0].scrollHeight`で取得すればいい。

５．けれどね、scrollHeightを捕獲するときでね、`要素[0]`が存在しないときに、scrollHeightを捕獲しに行くと、コードが止まってしまう。

６．なので、コードが止まらないよう条件分岐する

```js
if(element.length){
   h = element[0].scrollHeight;
   element.parent().scrollTop(h);
}
```

僕が今回とってもはまった原因は、
・　scrollを設定した要素を、適切に捕捉できなかった
・　scrollを設定した要素（親要素）で、scrollHeightを取得しようとした
　（親要素[0]にもscrollHeightがあるが、なんだか取得できなかった）
・　要素[0].scrollHeightをしたが、要素[0]が存在しなかった
そんなこんなで時間かけました

誰のお役にも立たないメモですみません。超個人的メモとして。
ズンドコキヨシ.php


```php:zundokokiyoshi.php
$zundoko = ['ズン','ドコ'];
$kiyoshi = "";
while (true) {
    $kiyoshi .= $zundoko[random_int(0,2)%2];
    if(preg_match("/ズンズンズンズンドコ$/",$kiyoshi)) {
        print($kiyoshi."キ・ヨ・シ！");
        break;
    }
}
```
Keynote『このオブジェクトは、マスタースライドでのみ編集できます。』といわれたときの対応方法

## 症状
自作したテンプレートでスライドを作ろうと思い、テキストエリアをクリックすると『このオブジェクトは、マスタースライドでのみ編集できます。』と出てきて文言が編集できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/72f67b9d-3bac-170b-fa9a-49fb6ad82374.png)

## 解決方法
マスタースライドを編集 → 編集可能にしたいテキストエリアを選択 → サイドバーの『スタイル』を選択 → 『テキストプレースホルダして定義』にチェックをつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/4db8c81d-0aa1-f97e-df3a-131ab0d67991.png)

## おまけ
Keynoteで自作のテンプレートを作成する方法については[『既存テーマはイケてない!?Keynoteでテーマ(テンプレート)を自作してみよう!』](https://nishinatoshiharu.com/create-keynote-theme/)で紹介していますので、興味のある方はぜひご覧になってください！
ファイルのダウンロードが完了するまでWebDriverを待機させるには

　ファイルのダウンロードが終わるまで待機して、ダウンロードが完了したら次の操作を行うスクリプトを書こうとしたのですが、WebDriverにはダウンロード完了まで待ってくれる機能は用意されていません。
　それを解決するのに、Watchdogを利用したら？みたいな記事もあったのですが、普通にWebDriverWaitでカスタム待機条件を作ればいいんじゃないかと思うので、そのように実装してみました。

　なお、ダウンロード時にダイアログが出ないことが前提で話を進めていますので、Firefoxを使っている場合はプロファイルをいじる必要があると思います。
　このあたりの記事を参考にすると幸せになれるかも……
http://tbpgr.hatenablog.com/entry/20140203/1391431135
https://developer.mozilla.org/ja/docs/Download_Manager_preferences

　さて、非公式リファレンスにカスタム待機条件を実装する方法が書いてあったので、そちらを参考にしながら書いてみます。
https://kurozumi.github.io/selenium-python/waits.html

```python:custom_expected_conditions.py
import os

class file_existed(object):

    def __init__(self, path):
        self.path = path

    def __call__(self, driver):
        # 指定したファイルパスが存在していたら待機を抜ける
        if os.path.isfile(self.path):
            return driver
        else:
            return False
```

　どうも、一定期間ごとに```__call__```が呼ばれるみたいです。引数driverにはwebdriverオブジェクトが渡されます。指定した条件に合致して待機から抜けるときにはdriverを返して、条件に合致せず、まだ待機する場合はFalseを返すように実装すれば動きます。

　先程作ったクラスの使い方は以下のとおりです。

```python
import os
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import custom_expected_conditions

# WebDriverWaitにはdriverと最大待機時間(秒)を渡す
WebDriverWait(driver, 10).until(
    custom_expected_conditions.file_existed(FILE_DIR + os.sep + "filename.hoge")
)
```

　なお、```__init__```は```__call__```で使う値を格納するときぐらいにしか使わないので、```__call__```さえしっかり実装されていれば動くみたいです。

　ですので、以下のようなてきとう実装でも動きます。

```python:custom_expected_conditions.py
import random

class itsuka_nukeru(object):
    def __init__(self):
        pass

    def __call__(self, driver):
        if random.randint(1, 10) > 5:
            return driver
        else:
            return False
```

　driverとFalseさえ返せれば、副作用盛りだくさんなクラスを作ったってWebDriverさんには怒られないですぜ！！まぁレビュアー様はどうしようもないので付け届けでも送っとけばいいんじゃないですかね( ﾟДﾟ)y─┛~~
Cognosで改ページを利用したグラフレポートの作成例

##はじめに
グラフレポートを作成している時に、製品ラインごとに表示を切り替えて、配下の製品タイプの数値をグラフで確認したいといった要件に対応できるのがグラフに設定する改ページの設定です。
この改ページの設定ですがリストより少しクセがあるので改ページを設定したグラフレポートの作成手順を紹介します。


##やりたいこと
グラフに改ページを設定し、ページを送るたびにグラフに出力される製品タイプの情報が、製品ライン単位で切り替わるレポートを作成したい。
ポイントは、「グラフに表示する粒度より1つ上のレベルで改ページを設定すること」となります。
(1ページ目、製品ライン：アウトドア用保護用品 に属する製品タイプの情報が表示)
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/221fb2b4-21db-3e6b-6bde-b269acda9c16.jpeg)

(2ページ目、製品ライン：キャンプ用品 に属する製品タイプの情報が表示)
![WS000010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/8e4b8d79-3e8c-1065-bba5-aca8ed39ffd1.jpeg)


##手順
※Cognosのサンプルデータを使用してレポートを作成しています。使用しているネームスペースは、GOデータウェアハウス(クエリー) > 販売とマーケティング(クエリー) > 販売(クエリー) になります。

1. ページに視覚化を配置し、「グラフ」を選択します。今回は「クラスター折れ線グラフ」を選択して「OK」をクリックします。
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/7d6313c6-7607-acb3-fba5-0e1cb571440f.jpeg)


2. 折れ線グラフにデータアイテムを配置していきます。
デフォルトの数値データ(Y軸)：<総利益>
データ系列(主軸)：<製品ライン><製品タイプ>
カテゴリー(X軸)：<年>
※ ポイントは、データ系列に「製品ライン」(改ページの区切りとしたい項目)に「製品タイプ」(グラフに表示する系列)をネストさせて配置するところです。
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/2186ae06-e2e7-a579-fa52-92fe13e646cb.jpeg)

3. 製品ラインを選択した状態で「セクション/セクション解除」アイコンをクリックし、「マスター/詳細を使用した改ページを設定」をクリックします。
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/203facf9-164f-44ad-59b3-3f9cd0a01f4a.jpeg)
既存のページ・セットを置き換えるか聞かれたら「OK」をクリックします。
新しいページが、"製品ライン"の各値について表示されます。のメッセージが表示されたら「OK」をクリックします。


4. 製品ラインを選択した状態で「セクション/セクション解除」アイコンをクリックし、「セクション/セクション解除」をクリックします。
![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/b20ac805-029a-008d-b194-71ff2cdde658.jpeg)

5. 基本的には上記手順で作業完了になります
![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/6fd902b0-8363-4d23-0db3-6a3c3906197c.jpeg)


6. 製品ラインに対してソートを指定したい場合は、クエリー内で事前ソート定義を実施しておく必要があります。
![WS000013.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/90f05e34-9bba-c71f-a63e-f965cbbaaacf.jpeg)

7. その他のグラフの項目に関しては、通常の設定と同様にグラフ上からソートの設定が可能です。
![WS000008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/4f7fabd9-ffd2-609c-a9c9-27fe4cdbcb33.jpeg)



##Excel出力時に最大の恩恵が
このレポートを作っていて何が一番嬉しいかと言うと、Excelに出力した時ではないでしょうか。
グラフで指定した改ページの場所でシートを分割してExcelを出力してくれます。
![WS000011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/bb35d304-bc9f-289c-e411-e4133d219e0b.jpeg)

![WS000012.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146283/712cf0d1-b582-0559-a36c-5dfed2f39811.jpeg)


##自己学習記事一覧

Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト
https://qiita.com/shinyama/items/95885c7246dc413b6448
【swift】Error: Could not build Objective-C module "[ライブラリ名]" の直し方

#1. 概要
xcodeでswiftファイルをコンパイルするとき、"Error: Could not build Objective-C module "[ライブラリ名]""が表示されてしまう場合の対処法です。
筆者は解決策その２で直りました。

#2. 解決策その１　キャッシュの削除
1. Xcodeを閉じる。
2. ~/Library/Developer/Xcode/DerivedData にある該当プロジェクトのテンポラリーファイルをフォルダごと削除する。フォルダ名は「[プロジェクト名]-[ランダムな文字列]」となっており、複数ある場合は全て削除する。
3. プロジェクトフォルダにある[プロジェクト名].xcworkspaceのファイルを削除する。
4. プロジェクトフォルダにあるPodfile.lock とPodsフォルダを削除する
5. プロジェクトのあるディレクトリで"pod install"を実行する。
6. [プロジェクト名].xcworkspace のファイルが新しく生成するので、これを開いて実行する。


#3. 解決策その２　スキームの選択
1. アプリのタブの Product > Scheme で[ライブラリ名]が表示されていることを確認。
2. 表示されていない場合は、"Manege Schemes"をクリックし、表示したいライブラリにチェックをつける。
3. Product > Scheme で[ライブラリ名]をクリックする。
4. [Command] + [B]で正しくビルドされることを確認する。

#4. 参考
[Error: Could not build Objective-C module 'Firebase'](https://stackoverflow.com/questions/41709912/error-could-not-build-objective-c-module-firebase)
JDLA Deep Learning for GENERAL 2019#2合格体験記

# JDLA Deep Learning for GENERAL 2019#2合格体験記
2019年7月6日(土)に受験して何とか合格出来ましたので今後受験する人たちのためになれば幸いです。
## ＜2019年 第2回G検定（ジェネラリスト検定）概要＞
名称　　：JDLA Deep Learning for GENERAL 2019 #2
概要　　：ディープラーニングを事業に活かすための知識を有しているかを検定する
受験資格：制限なし
試験概要：120分、小問226問の知識問題（多肢選択式）、オンライン実施（自宅受験）
出題問題：シラバスより出題（推薦図書あり）
受験料　：一般：12,960円（税込）、学生：5,400円（税込）
試験日　：2019年7月6日（土）13:00より120分間
申込期間：2019年5月31日（金）13:00 ～ 2019年6月28日（金）23:59
申込　　：G検定受験サイト（https://www.jdla-exam.org/d/）からのお申し込み（クレジットカードまたはコンビニ決済）

2019年7月6日(土)に実施したG検定は、総受験者数5,143名中合格者数3,672名と70%の合格率でした。依然として得点および合格ラインは開示されませんでした。
## 使用テキスト
1. 「深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト」
前半部分は、AIの歴史などが記載されておりどんどん読み進めて行けますが途中から数式が出てきて後半は初学者にはきつい内容になってきます。　

1. 「徹底攻略 ディープラーニングG検定 ジェネラリスト問題集」
いきなりこの問題集から初めても当然なにも解けないため回答集をみながら覚えていきます。
非常にわかりやすい解説のため公式テキストよりかは理解が進むので問題集を先に１度読んでから公式テキストを読むのがいいかもしれません。

1. 「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」
ディープラーニングの理論を理解して覚える人にはお勧めだけど結構読破に時間がかかるため余裕があれば読むくらいの程度です。

1. 「AI白書2019」 単行本
内容は、面白いけどなかなか進まない。ほぼ１日かけて斜め読みしてどこに何が書かれているかを知る程度でよい。

1. Study-aiの模擬試験(http://study-ai.com/generalist/) 
実際に同じ問題数と試験時間が表示されるので何度も実施して時間感覚を養い間違ったところを出来るまで確認する。
## 学習方法
私は、AIに関しては初学者のため試験日の２ヶ月前から勉強を開始しました。
5/6-5/24
あまり本腰が入らず公式テキストを通勤途中に読むだけ
5/24-5/25
土日を利用して模擬試験をやってみる。
当然２時間の時間内では解けずしかも正解率５割も満たない。焦りだしネットで合格体験記を読みあさる。

https://qiita.com/m2u/items/548bd59634bbf403cccf

上記出題問題をうまくまとめているサイトがありこれを読み出題傾向を整理しついでにExcel表に書き写した。
5/27-6/7
問題集を通勤途中に読破する。わからない用語や模擬テストにも出題されていた用語は、Excel表にあいうえお順とアルファベット順に記載して別シートには人物別に関連記事を記載した。
6/8-6/9
問題集の最後の問題を２時間時間を計ってやってみるがやはり時間内に終わらず正解率も50％に満たない。回答を覚える。
6/10-6/21
通勤途中でまた公式テストを読み始める。
家で模擬テストを時間を計らず何回も解いて正解率が100%になるまで実施した。
6/24
問題集の巻末の問題を２時間計ってやってみる。
計算問題が軒並み解けないし理解できないため公式と解き方を紙にまとめた。
6/25-7/5
AI白書を斜め読みし自動車やロボットや国別のトレンドや有名な団体の動きなどをExcelにまとめた。後はまた問題集をもう1周読む。
## 試験のための準備
* 前日にwindowsUpdateを実施しておき終了したら試験サイトにアクセスして異常がないかを確認
* 予備のPCを用意しておく
* 自宅での受験のためインタフォーンの電源はOFF,携帯もマナーモードにする
* ノートPCに外付けのディスプレイを接続しあんちょこのExcelとググり用のブラウザを起動
* マウスの電池も新しいのに交換
* PCの周りには参考書や公式や図を描いた紙を見やすい位置に置き計算用の電卓と紙とペンも用意

## いざ試験
12:50から開始できるのでアンケートに回答をしてから試験実施
最初の数問は、優しい問題が続き得点が加算されていくのを心地よく感じる。だんだん深い質問になりチェックが入る。チェックが多いと何をチェックした忘れてしまうためそんなに多くはチェックできない。
後半長い文章を４つ読んでの回答が続く。
遭遇したこともない用語がいくつか続くのでチェックして先に進む。
１０分残して全ての回答を終えたのでチェックの問題に取り組む。
遭遇したこともない用語をググり始める。なかなか検索がヒットしない（汗）
ヒットしないうちに自然終了となった。
## まとめ
感触としては７割以上８割未満の出来でした。
1問30秒なため考え込んでしまったらとりあえず何かを答えといてからチェックを入れるようにすることと覚えられないものは紙に書いて見えるところに置くことです。
時間がかかりそうな計算は捨てましょう。
Sequel Pro のフォントサイズ変更、フォント種別変更

# こんな症状に効果があります
- SequelPro便利だけど「l(エル)」と「I(アイ)」の区別がつかない
- 高解像度で見ると文字小さい！

<img width="411" alt="スクリーンショット 2019-07-17 17.58.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/04c8385f-160e-25ac-8f4a-11662b55bf83.png">


# やり方
環境設定 > テーブル > 内容ビューのフォント > 選択

これで幸せになれます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/8ff64509-3a37-a378-0adb-dbcd01a21372.png)

# おすすめ
Menlo,Monacoあたりがおすすめです

<img width="76" alt="スクリーンショット 2019-07-17 18.02.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/a283701f-c8a7-1ed8-8225-39fcb786eb83.png">

# 役に立ったらいいねお願いします！🌟
pandasでインデックスとは別のカラムに連番を振る

# 概要
pandasで1始まりの連番を作成、列に反映する。

# 背景
pandasのデータフレームをexcelやcsvで書きだす際、以下の問題点があった。

**問題点**

- indexではカラム名がつかない！
- 0始まりで、1始まりではない！

解決策として、**'No'という名前で1始まりの連番カラム**を作成する。

# コード

pandas.RangeIndexで1始まりの連番を作成、それを'No'という列に反映する。
その後、csvファイルとして出力する。

```Python3:serial_num.py
import pandas as pd

# データフレームを作成
d = {'A': ['apple_01', 'apple_02'], 'B': ['banana_01', 'banana_02']}
df = pd.DataFrame(data=d)

# pandasでインデックスとは別の行に連番を振る
serial_num = pd.RangeIndex(start=1, stop=len(df.index) + 1, step=1)
df['No'] = serial_num

# 並び替えを行う
df = df.loc[:, ['No', 'A', 'B']]

# 出力
print(df)
df.to_csv(index=False)

#　結果
# 
# - df
#    No         A          B
# 0   1  apple_01  banana_01
# 1   2  apple_02  banana_02
# 
# - csv
#  No         A          B
#   1  apple_01  banana_01
#   2  apple_02  banana_02

```
Coral USBアクセラレータを使ったRaspberry Pi 4での物体検出



Coral USBアクセラレータを使用したSSDオブジェクト検出はRaspberry Pi 3で実行されていましたが、パフォーマンスは期待外れでした。RaspberryPi 4で何が起こるのか興味がありました。

![微信截图_20190717164646.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/3ba98062-1228-6dba-5333-85543de64f70.png)

これがテスト用rt-aiデザインです。 UVCCamとMediaView SPEはUbuntuデスクトップ上で、CoralSSD SPEはRaspberry Pi 4上で実行されています。1280 x 720フレームで12fpsというかなりの性能を発揮しています。 いくつかの愚かな画像の読み込みコードに）。 1つのCPUコアの使用率は約93％で、これはPython SPEには十分に公平です。 私はこのSPEのC ++版がまたかなり速いだろうと確信しています。
![pi4coral.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/b15b1784-bcca-ff24-1b8c-352ef746f688.jpeg)

###### Google Coral USB accelerator代理店，開発者はここで購入できます： https://store.gravitylink.com


Pi 4はRaspbian Busterを必要とし、それは現時点ではedgetpu_apiツールキットでサポートされていないPython 3.7に付属しているので、これを実行するのは面白かったです。


元のブログ記事を書いた後、実際にedgetpu_apiインストールをPython 3.7で動作するように変換することは簡単であることを発見しました。 virtualenvやPython 3.5のことを何もせずに、install.sh（Pi 4を認識しsudoのバグを修正するために下記のように修正されたもの）を実行して以下のコマンドを入力するだけです。

``` 
cd /usr/local/lib/python3.7/dist-packages/edgetpu/swig
sudo cp _edgetpu_cpp_wrapper.cpython-35m-arm-linux-gnueabihf.so _edgetpu_cpp_wrapper.cpython-37m-arm-linux-gnueabihf.so
```

必要なのは、Pythonのバージョンと一致するように正しく名前が付けられた.soファイルだけであることがわかりました。 とにかく、あなたがPython 3.5のルートに行きたいのなら…


ARMライブラリのPythonライブラリはPython 3.5用にのみコンパイルされています。 そのため、Python 3.5はPython 3.7と同時にインストールする必要があります。 これを行うには、GZippedのソースを[ここ](https://www.python.org/downloads/release/python-357/)からダウンロードし、次のように展開してビルドします。

``` 
tar xzf Python-3.5.7.tgz
cd Python-3.5.7
sudo apt-get install libssl-dev
./configure --enable-optimizations
sudo make -j4 altinstall
virtualenv --python=python3.5 venv
source venv/bin/activate
```

これらすべての結果、Python 3.5が仮想環境で利用可能になるはずです。 インストールが必要な特定のパッケージは、必要に応じてpip3.5を使用してインストールする必要があります。 厄介なことに、私はインストールが何らかの理由でうまくいかなかったことを知り（インポート時に依存関係が欠けていた）、私はこのコマンドを使わなければなりませんでした：

``` 
pip3.5 install numpy --upgrade --no-binary :all:
```

これでedgetpu_apiをインストールする時が来ました。これは基本的にここの指示に従った場合です。 ただし、install.shには小さなバグがあり、Pi 4も認識されません。

59行目の後にこれを追加して、install 4を修正してPi 4を認識させます。

```
elif [[ "${MODEL}" == "Raspberry Pi 4 Model B Rev"* ]]; then
    info "Recognized as Raspberry Pi 4 B."
    LIBEDGETPU_SUFFIX=arm32
    HOST_GNU_TYPE=arm-linux-gnueabihf
```

それが追加されたら、128行目に行き、それを次のように置き換えます。

```
sudo udevadm control --reload-rules && sudo udevadm trigger
```

オリジナルは2番目のsudoがありません。 それが完了したら、コーラルUSBアクセラレータは鳥分類器の例を実行することができるはずです。
仮想環境の中でLaravelを動かすと、ページが表示されず接続が拒否される

## 環境
Ubuntu 16.04.5 LTS (Xenial Xerus)
Laravel Framework 5.6.26
 
## 状況
UbuntuでLaravelの環境構築して、Laravelのコマンドが使える状態にまでいったが、
「php artisan serve」のコマンドを入力したら、
「Laravel development server started」
とは出力されるが、ブラウザ見るとページは表示はされない。(このサイトにはアクセスできません。接続が拒否されましたと表示されます。)

## 解決策
UbuntuでPHP単体を動かす方法は知っていたので、それを参考にしてみた。

まず、IPを確認

```
ifconfig | grep "inet addr:"
```

このコマンドで、僕はIPが4つほど表示されたので、PHPが動く適切なIPをメモ。

次に、php artisan serveを行う(IP指定も)

```
php artisan serve --host 先ほどのIP
```

これでうまくいった。



##まとめ
仮想環境でIPを指定せずに「php artisan serve」のみをすると何かしらのIPが動くが、
そのIPではPHPの環境構築は行っていないので、何も表示されなかった。

つまり、PHPの環境構築をしたIPを指定する必要がある。

仮想環境ではなくMacとかWindows単体で使う場合には普通はIP一個のはずなので、
「php artisan serve」の後にIPを指定する必要はなかった。
そういえば、gitでpushするときも複数のブランチ作ったらブランチ名指定しなきゃいけなくなるのと同じだった。
今回は仮想環境を使っており複数のIPが存在するので、指定する必要がある。
Gitのマージ操作

開発では最終的に**master**ブランチにマージする。

現在のブランチは以下の通り

```text:terminal
/Users/sf213471118/git/test
$ git branch
* master
  practice
```
現在、それぞれのブランチには以下のものが格納されている

| Branch| File1 | File2 |
|:-----------:|:------------:|:------------:|
| master | README.md | - |
| practice | README.md | div.md |

これを以下のようにしたい


| Branch| File1 | File2 |
|:-----------:|:------------:|:------------:|
| master | README.md | div.md |

マージする際には

```
$ git merge <Subject file>
```
とするだけでマージされる。あとは`add`して`commit`すれば完了。

実際にやってみる。


```text:terminal
/Users/sf213471118/git/test
$ git checkout master          /* masterブランチに移動 */
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git branch   /* 移動確認 */
* master
  practice
$ git merge practice           /* masterにマージ */
Updating 0226a43..c44954c
Fast-forward
 div.md | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 div.md
$ ls                           /* masterブランチの中を確認 */
README.md	div.md
```

あとは`add`して`commit`して`push`して終わり

```text:terminal
/Users/sf213471118/git/test
$ git add -A                              /* add */
$ git commit -m "merge from practice"     /* commit */
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
$ git push origin master                  /* push */
Total 0 (delta 0), reused 0 (delta 0)
remote: detect-secrets-stream (beta) ver=252-281d7c3a32923b0277f57f164c55764676echrud FAQ: xxxx
remote: 
remote: Successfully send push metadata.
remote: Push info collect pre-receive hook finished within 3 seconds.
To xxxx:sf213471118/test.git
   0326b84..c43955a  master -> master

```

GitHub上で確認して完了
ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる～ユーザー参照画面の作成～

この記事の関連記事となります。
[ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる](https://qiita.com/mikansei-lab/items/d7e0074df89f508e8c96)

---

## はじめに

ユーザー参照画面を作成して、Userテーブルのデータを1件画面に表示してみます。次のようなイメージです。

|||
|:--|:--|
|ID|1|
|氏名|山田　太郎|
|メールアドレス|taro.yamada@example.com|

## 手順

 1. コントローラーを編集します
 2. 参照画面を作成します

### 1. コントローラを編集します

コントローラーを編集します。
`User::find($id)`とすることで主キーを条件に1レコードだけ取得することができます。

```php:app/Http/Controllers/UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UserController extends Controller
{
    // 参照ページ表示
    public function show(Request $request, $id)
    {
      // ID(主キー)を条件にユーザを取得します
      $user = User::find($id);
      //
      $errors = array();
      // 参照画面へユーザを渡します
      return view('users.show', ['user' => $user, 'errors' => $errors]);
    }
}
```

### 2. 参照画面を作成します

参照画面を作成します。コントローラから渡してきたデータは`{{ $user->id }}`のように参照できます。
その他のhtmlコードについては割愛します。

```html:resources/views/users/show.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <form>
        <div class="form-group">
          <label class="control-label">ID</label>
          <input class="form-control-plaintext" type="text" value="{{ $user->id }}" readonly>
        </div>
        <div class="form-group">
          <label>氏名</label>
          <input class="form-control-plaintext" type="text" value="{{ $user->name }}" readonly>
        </div>
        <div class="form-group">
          <label>メールアドレス</label>
          <input class="form-control-plaintext" type="email" value="{{ $user->email }}" readonly>
        </div>
        <div class="form-group">
          <label>作成日時</label>
          <input class="form-control-plaintext" type="text" value="{{ $user->created_at }}" readonly>
        </div>
        <div class="form-group">
          <label>更新日時</label>
          <input class="form-control-plaintext" type="text" value="{{ $user->updated_at }}" readonly>
        </div>
        <a class="btn btn-secondary" href="/users">一覧へ</a>
      </form>
    </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </body>
</html>
```

## 参考
Cognos Analytics ダッシュボードの基本操作

#ダッシュボードの基本操作を学ぶ
簡易な操作でダッシュボードが作成できる、「ダッシュボード」の機能で、図のようなクロス集計にデータを入れて出力する手順を学びます。
<img width="887" alt="013.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/2588f1bf-57f2-abcb-f53f-ebc4d8ed5f0f.png">

#手順
ダッシュボードの起動は、「新規」から「ダッシュボード」。
<img width="148" alt="001.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/339055e3-0a55-fccb-ece9-db17f633ebaf.png">

基本はこの真っ白なテンプレートを選択し「OK」で良い。
<img width="960" alt="002.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8dae1020-2198-c617-5507-34557775bfa4.png">

赤枠の「ソースの選択」または「＋」ボタンを選択。
<img width="633" alt="003.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/72878f5e-5b44-0900-e43e-7550888d2112.png">

チーム・コンテンツ > サンプル > モデル > GO データウェアハウス(クエリー)を選択し「追加」。
<img width="397" alt="004.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/f0b322d3-c6a5-20ca-f155-d19ee5f71b3f.png">

左端の帯の「ソース」アイコンを選択すると、パッケージの中身が見える。
<img width="660" alt="005.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/f70b52a7-2fd5-c006-e669-47c40a371372.png">

「視覚化」アイコンを選択すると、図のように各種グラフのサムネイルが表示される。
「クロス集計」を図のようにキャンバスにドラッグ&ドロップする。
<img width="640" alt="006.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/d4ea56bf-ce56-028c-8635-92c9872c6e14.png">

図のように、列に「時間」の下の「年」を、行に「製品」の下の「製品ライン」を、値に「販売の実状」の下の「数量」を置く。
<img width="960" alt="007.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/5681ea3b-74a6-fac6-22f5-9fa55cae8def.png">

既にクロス集計がデータ入りで表示されているが、この状態は編集用のモードなので、右上の赤枠の「省略」アイコンを選択。
<img width="701" alt="008.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/097884b6-cec6-a9b9-e85b-0b5cfc85eecb.png">

この様な表示となる。
クロス集計が横に切れてて見にくいので、右下の赤枠の位置をつかみ、右に引っ張りサイズ調整する。
<img width="775" alt="009.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/b259e796-caa9-58b0-99b2-1055b252534e.png">

サイズは良いが、配置場所をもっと左に寄せたいので、赤枠の位置をつかんで左に移動する。
<img width="960" alt="010.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/dc4cea63-a0d1-6ad0-37bd-daede49c5759.png">

ダッシュボードを保存する。
「D1.Dashboard」という名称で保存。
<img width="953" alt="012.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8e769e8c-5ab2-9351-a155-c1d0510c7351.png">


#自己学習記事一覧
**Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト**
https://qiita.com/shinyama/items/95885c7246dc413b6448
CAKEPHP3でPhpSpreadsheet使う

## テンプレートファイルを読み込んでエクセルファイルを出力する

```php
<?php
namespace App\Controller;

use App\Controller\AppController;

use Cake\Event\Event;
use Zend\Diactoros\Stream;
use Cake\Http\CallbackStream;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;

/**
 * Excels Controller
 *
 *
 * @method \App\Model\Entity\Excel[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class ExcelsController extends AppController
{
    /**
     * Index method
     *
     * @return \Cake\Http\Response|void
     */
    public function print()
    {
        // ファイル読込
        $inputFileName = ROOT . DS . 'uploadfiles' . DS . 'sheet' . DS . 'hoge.xlsx';
        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
        
        // 選択されているシートを取得
        $sheet = $spreadsheet->getActiveSheet();
        // 書き込み
        $sheet->setCellValue('A1', 'A1に書き込み');

        // コールバックをストリーム化
        $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
        $stream = new CallbackStream(function () use ($writer) {
            $writer->save('php://output');
        });

        // ファイルを出力
        $response = $this->response
            ->withHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            ->withHeader('Content-Disposition', 'attachment;filename="hoge.xlsx"')
            ->withHeader('Cache-Control', 'max-age=0')
            ->withBody($stream);

        return $response;
    }
}
```
githubのコマンド備忘録

## Githubのコマンド一覧
Githubを使っているときに、いろいろとコマンドを忘れてしまったときのための備忘録です。

## コミットログの整理
`commit`を雑にしてしまっていませんか？その場はとりあえずpushできればいいやくらいのノリでcommitしてしまいがちですが、後から見た時に何もわからなくなってしまいます。
commitする際のポイントなどをまとめました。

- k
- k



#### ・いらないファイルをローカルで消したときにそれをリモートでも反映させたい

```
git rm (-r) いらないファイル　（フォルダの時は -r オプションをつけてあげましょう。）

git commit -m "remove files" 

git push origin (local-branch):(remote-branch)
```

#### ・非公開のレポジトリを pip install したい
公開鍵の登録は済ませておきましょう。

```
pip install git+ssh://git@github.com/(package-name).git@branch/subbranch
```
git@ を忘れてしまうとエラーになるので注意が必要です。