OmniAICreator/Qiita-1.07M huggingface dataset:
IBM i (旧AS400）の自己学習メモ　コマンド／ツール／運用　IBM Navigator for iを使う

# 自己学習メモインデックス

[IBM i (旧AS400）の自己学習メモ　インデックス](https://qiita.com/You_name_is_YU/items/3964849e7803c8eaf767)

# 概要

ベル・データ株式会社が主催している[IBM i Forum 2020　～「攻め」に転じるプラットフォームの活かし方 ～](https://www.belldata.com/event/seminar/ibmi-forum2020.html)に参加したのですが、その講演でとても多くの有益な情報を収集することができました。

その中でPUB400.comでも利用可能だった`IBM Navigator for i`について、使ってみた際のメモがてら記事にまとめてみました。（ただのエビデンスのような内容になるかもしれませんがご容赦ください。）

# IBM Navigator for i とは

IBMの公式に以下のような内容で説明されておりました。
https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzat10/rzatgdirectoroverview.htm

> IBM® Navigator for i は、IBM i を管理するための主要タスクを実行できる Web コンソール・インターフェースです。 IBM Navigator for i では、 System i® ナビゲーター Windows クライアント・アプリケーションで利用可能な大半のタスクがサポートされます。 ただし、Windows クライアント・アプリケーションと異なり、 IBM Navigator for i を使用するためにワークステーションに何もインストールする必要はありません。 Web アプリケーションは、基本の IBM i オペレーティング・システムに含まれ、 ブラウザーで http://systemName:2001 を指すだけで簡単にアクセスすることができます。

# IBM Navigator for i で PUB400.com にアクセスする

以下のURLにアクセスします。
http://pub400.com:2001/

そうすると、PUB400.comの挙動としては以下のURLにリダイレクトしました。
http://pub400.com:2004/ibm/console/logon.jsp

<img width="1043" alt="スクリーンショット 2020-07-08 7.50.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/68e0c066-e8bf-5f4f-4191-70a5263d7f2b.png">

普段ACSのエミュレータからAS400にアクセスする際に利用しているIDとパスワードでログインすることができます。
ログインすると次のような画面が表示されます。
<img width="1320" alt="スクリーンショット 2020-07-08 7.53.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/7d3813f2-9bad-749d-ada6-d91a0a7cd90e.png">

# 少し触ってみる

System i ナビゲーターは使ったことがあり、利用するシーンとしてはスプールを印刷せずにPDFやテキストで取得して、確認したい場合に使ったりするぐらいです。
なのでどのように活用するのかよく分かってはいないんですが、適当に触ってみた感じをメモに残します。

## プリンター出力をPDF出力してみる

<img width="1320" alt="スクリーンショット 2020-07-08 8.10.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/d7899280-97c2-9315-88ea-81a958e5f4e2.png">
<img width="1320" alt="スクリーンショット 2020-07-08 8.10.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/a0f7a6a3-0e35-b991-d005-dd80105e9e11.png">

System i ナビゲーターの時も、PDFにすると文字化けするので、テキスト出力して確認したりしてたんだよなー。
PDFが文字化けしない方法ってあるんだろうか。。

## オブジェクトの操作権限を設定

適当にメニューを開いていって気になったところを触ってみました。
`セキュリティー` -> `オブジェクト許可の変更` の機能で `/QSYS.LIB/YAMAGUCHI1.LIB/***`で指定したオブジェクトに対し、誰にどんな権限を与えるのかを細かく設定できるようです。
たぶん、Oracleのロールのようなものを作って、そのロールに対して、ReadとかWriteとかの権限を与えるようなイメージのことができるんだと思います。

<img width="1320" alt="スクリーンショット 2020-07-08 8.04.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/810cbe8c-897f-3d39-ce69-b1b835728c02.png">

## 5250エミュレータをWeb画面で操作

IBM Navigator for iでは、5250エミュレータの画面をそのままWeb画面で操作することが可能となっています。
システム -> エミュレーション -> 5250
にアクセスすると、操作可能です。

<img width="886" alt="スクリーンショット 2020-07-09 7.53.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/48b8b42f-4cfb-9176-1549-8bee5442c6d3.png">
<img width="886" alt="スクリーンショット 2020-07-09 7.54.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/a2ce0e34-f74c-c242-6249-169146691558.png">
<img width="886" alt="スクリーンショット 2020-07-09 7.54.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/949bf8d7-0b56-052b-e90e-039a77793b9a.png">
ioストリーム

```py
import io


with open('/tmp/a.txt', 'w') as f:
    f.write('text text')

with open('/tmp/a.txt', 'r') as f:
    print(f.read())

f = io.StringIO()
f.write('string io test')
f.seek(0)
print(f.read())
```
実行結果：

```txt
text text
string io test
```
GitHubのプロフィール機能 🎉🎉

# はじめに

https://github.com/Ganariya/

Githubにて、ベータ版の機能である自分のアカウントページにプロフィールに関するREADME.mdを設定できるようになりました＞＜
これまでインターンとかでエントリーシート出すときにいちいちQiita, Qrunch, hatena, github, 個人ブログなど全部書いてましたが、これ一個に済むようになりそうです（やったね）

<img width="978" alt="スクリーンショット 2020-07-08 7.57.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/b425628a-5819-f190-55d5-aa4110ba66f1.png">


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GitHub のプロフィールページを愉快な感じにした！<a href="https://t.co/3cQZjCOQBy">https://t.co/3cQZjCOQBy</a> <a href="https://t.co/Pf2PTOwy3x">pic.twitter.com/Pf2PTOwy3x</a></p>&mdash; Ryo Suzuki (@Reputeless) <a href="https://twitter.com/Reputeless/status/1279421579152125954?ref_src=twsrc%5Etfw">July 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

知ったきっかけはSiv3D作者さんの上記のツイートです。

# How to do

https://github.com/Ganariya/Ganariya

自分の名前のリポジトリを作ると、このリポジトリのREADME.mdがアカウントページでも表示されるようになります。多分Publicでないと駄目です。

#  懸念点

どうやら現在普通に相対リンクで画像リンクをはると、アカウントページで読み込めないことがあります。

例えば、
https://github.com/Ganariya/Ganariya のREADME.mdで

```markdown
<img src="ganariya.png">
</img>
```

とすると、Ganariya/Ganariyaのリポジトリページでは画像を表示できますがGanariyaのアカウントページでは時たま表示できないことがあります。

そのため、srcのリンクに関しては、今の段階では直リンクを貼ったほうがおそらくいいです。
初心者が絶対分かるRequestsでスクレイピングする基本まとめ【Python】

## Requestsの基本
### import
```
import requests
```
必ずこのインポートが必要になります。

### Webサイトからソースを取得する
- GETメソッドで取得する
- POSTメソッドで取得する

この2つを覚えておけば良いでしょう。
#### GETメソッドで取得する（requests.get）
```
import requests

url = 'https://www.yahoo.co.jp/'
response = requests.get(url)
print(response) # →<Response [200]>

html = response.text
print(html) # →HTMLソースの文字列
```
requests.get(url)の返り値はHTTPのステータスコードです。
成功していれば、200が返ってきます。

response.textで求めているHTMLソースの文字列を取得することができます。

#### POSTメソッドで取得する（requests.post）
POSTメソッドでないと求めているソースが手に入らないことがあります。

```
data =  {'username':'tarouyamada', 'password':'4r8q99fiad'}

response = requests.post(url, data=data)
```
これでリクエストボディーを含めた上でリクエストを送ることができます。

#### リクエストヘッダーを付与する方法
```
headers = {'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', 
'accept': 'application/json'}

response = requests.get(url, headers=headers)
```
これでリクエストヘッダーが付与された状態でリクエストを送ることができます。
get,postで書き方は共通です。

#### 画像を取得する
.contentを使えばバイナリデータを取得できます。
画像もバイナリデータの1種です。

```
response = requests.get(url)

img_data = response.content

print(img_data)
#b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x03\x02\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\n\x07\x07\x06\x08\x0c\n\x0………

print(type(img_data))
# <class 'bytes'>

```
- 出力されるのはbytes型

##### 画像の保存

- ちなみに取得した画像データを保存したい時
    - バイナリファイルの読み書きなので'b'をつける

```
with open('test.jpg', 'wb') as f:
    f.write(response.content)

```

#### パラメータの指定

```
params = {'q':'qiita', 'date':'2020-7-3'}

response = requests.get(url, params=params)

```

#### レスポンスヘッダーを見る

- content-typeあたりはテキストなのか、jsonなのか、imageなのかあたりの判定に使えそう

```
response = requests.get(
    'https://www.pakutaso.com/shared/img/thumb/nekocyan458A3541_TP_V.jpg')

print(response.headers)

# {'Server': 'nginx', 'Date': 'Tue, 07 Jul 2020 22:39:37 GMT', 'Content-Type': 'image/jpeg', 'Content-Length': '239027', 'Last-Modified': 'Sun, 05 Jul 2020 01:51:48 GMT', 'Connection': 'keep-alive', 'ETag': '"5f013234-3a5b3"', 'Expires': 'Thu, 06 Aug 2020 22:39:37 GMT', 'Cache-Control': 'max-age=2592000', 'X-Powered-By': 'PleskLin', 'Strict-Transport-Security': 'max-age=31536000;  includeSubDomains; preload', 'Accept-Ranges': 'bytes'}
```

#### リダイレクトがあった場合
リダイレクト先のレスポンスを取得する

リダイレクト途中の履歴を使いたければ.historyを使う


#### エンコーディングの確認

```
response = requests.get(
    'https://qiita.com/')

print(response.encoding)

# utf-8
```

#### jsonデータを取得する
- response.json()で辞書型で取得することができる

```
response = requests.get(url)

json_dict = response.json()

```
Dockerってなに？

#はじめに
僕自身「Dockerってよく聞くけどなんのこと？」状態だったので気になって調べてみました。
#仮想化とは
Dockerに触れる前に必要な知識として仮想化について簡単に説明します。
仮想化とは物理的な1台のサーバー上で、複数の仮想的なサーバー（仮想サーバー）を運用することを「サーバーの仮想化」といいます。

簡単に例えると、windowsのpcで　macのosを使えるようになりますよ　みたいな

#Docker
Dockerはこの仮想化を実現するための技術の一つです。

従来の仮想化技術(ホスト型 、 ハイパーバイザー型)では
１つのアプリケーションを起動するのに、１つのosを立ち上げていたため、起動に時間がかかるなどのデメリットがありました。

~従来イメージ~
>A家の中にもうひとつ別のB家を建てて、B家のキッチンで料理する

ですがDockerはアプリケーション単位で仮想環境を切り替えるので従来のデメリットを打ち消すことができます。

~Dockerイメージ~
>A家の中にもうひとつ新しいキッチンを作り料理する

#Dockerのメリット
　　①環境構築が簡単
　　②立ち上げ速度がはやい
　　③ハードウェアの資源削減
などが挙げられます。

#まとめ
仮想の中での話なのでイメージしづらいですね。
今後もDockerが普及し続けることが予想されますのでしっかり理解していきたいですね。
atCoder 173 Python (A~D)

# 総括
A,B,Dは解けましたがCは解法が分かったところで時間切れです。
初の4完達成ならず。

#問題
https://atcoder.jp/contests/abc173/tasks/abc173_a

# A. Payment
##### 回答
```python

import math
N = int(input())

m = math.ceil(N / 1000)
answer = m * 1000 - N
print(answer)
```
書くだけ。

# B. Judge Status Summary
##### 回答
```python

results = {'AC': 0, 'WA': 0, 'TLE': 0, 'RE': 0}
N = int(input())
for _ in range(N):
    result = input()
    results[result] += 1

for k, v in results.items():
    print(k, 'x', v)
```
これも書くだけ。

# C. H and V
##### 回答
```python

import itertools
import numpy as np

H, W, K = map(int, input().split())

temp = []
for _ in range(H):
    C = list(input())
    A = [c.replace('.', '0') for c in C]
    A = [a.replace('#', '1') for a in A]
    A = list(map(lambda x: int(x), A))
    temp.append(A)

C = np.array(temp)

count = 0
l = [0, 1]
wide = itertools.product(l, repeat=W)
for w in wide:
    hight = itertools.product(l, repeat=H)
    for h in hight:
        copy_C = C.copy()
        for num, i in enumerate(w):
            if i == 1:
                copy_C[:, num-1] = 0
            for num2, j in enumerate(h):
                if j == 1:
                    copy_C[num2-1, :] = 0
        if copy_C.sum() == K:
            count += 1

print(count)
```
制限時間内に解けず。
考え方はすぐにわかったのですが実装にしきれず時間切れ。
翌日落ち着いてやったら解けました。
forループが4重となってしまいやや汚いコードですが。

要は```numpy```で```'.'```を```0```、 ```'#'```を```1```に変換して```0,1```の行列にします。そして、行列の```sum()```が```K```になれば```count```を増やすという方針です。

赤に塗るのは結局、白に塗る(=行列要素を0にする)と同じなので、numpyのスライスで実現できそうです。

あとは、```H x W```の行と列それぞれについて、赤に塗る(行列要素を0にする)か塗らないかの2択を全通り考えます。

塗るか塗らないかの二択なので```0,1```でフラグを立てます。これを生成するのが```itertools.product````です。


まとめると

- まずは```0,1```のnumpy行列に変換
- 行と列それぞれで```itertools.product````で塗る塗らないのフラグを立てる
-  塗る場合はnumpyスライスで0に変換
- 合計してKに等しい場合はcountを1増やす

で完了です。
時間内に解きたかった。


# D. Chat in a Circle
##### 回答

```python

import numpy as np

N = int(input())
A = list(map(int, input().split()))

A = sorted(A, reverse=True)
A = np.array(A)

if N % 2 == 0:
    # 偶数の場合
    end = (N - 2) // 2
    answer = A[0] + (A[1:end+1] * 2).sum()
else:
    # 奇数の場合
    end = (N - 2) // 2
    answer = A[0] + (A[1:end+1] * 2).sum() + A[end+1]

print(answer)

```

Dの割には簡単でした。
具体例を5つくらい考えてみると法則性が見えてきます。

方針は

- 大きい順に訪れるのが最適
- この場合1番最初の数字は1回しか使われない
- 2番目以降の数字は2回使われるはず
- 2番目以降の数字が2回使われるということは、最後に使われる数字はだいたい```(N - 2) / 2```と予想できます
- 2で割るということは偶数と奇数で場合分けが必要です
- 偶数の場合は調整なし、奇数の場合は最後の数字だけ1回使います

これをコードに落としたのが回答です。
vistaでquartus その19

#概要

vistaでquartusやってみた。
polyphonyで俺CPU書いてみた。

#環境

windows vista 32bit
quartus ii v13.0
polyphony v0.3.6
ep2c5t144ボード

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0bfa93dc-70b3-b94f-009d-03d043f03769.png)


![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/edd70cc5-b3d7-0124-5d0d-7c102d46d345.png)


#サンプルコード


```
module test2(input clk, input rst, output tx);
	wire [7:0] data;
	wire start;
	tx2 tx2(.clk(clk), .rst(rst), .start(start), .data(data), .tx(tx), .busy(busy), .get(get));
	mpu_m m(.clk(clk), .rst(rst), .data(data), .start(start));
endmodule
```

以上。
windowsでiverilog その45

#概要

windowsでiverilogやってみた。
polyphonyでcpu書いてみる。

#サンプルコード


```
from polyphony import testbench, module, is_worker_running, rule
from polyphony.io import Port
from polyphony.typing import uint8
from polyphony.timing import clksleep

@module
class mpu:
	def __init__(self):
		self.out = Port(uint8, 'out')
		self.append_worker(self.worker)
	def worker(self):
		rom = [
			0x8000,  #r0set  0   0
			0xd000,  #r0save  0  1
			       #loop:
			0xc000,  #r0load  0  2
			0x841a,  #r1set  26  3
			0x6100,  #r0  <  r1  4
			0x5090,  #if  pass   5
			0xc000,  #r0load  0  6
			0x8461,  #r1set  97  7
			0x0100,  #r0  +  r1  8
			0xa000,  #r0out      9
			0xc000,  #r0load  0  10
			0x8401,  #r1set  1   11
			0x0100,  #r0  +  r1  12
			0xd000,  #r0save  0  14
			0x4002,  #jp  loop   15
			0x400f, #pass:       16
		]
		ram = [0] * 8
		reg = [0] * 4
		pc = 0
		while is_worker_running():
			with rule(scheduling = 'pipeline'):
				while pc < 100:
					ins = rom[pc]
					pc = pc + 1
					op = (ins >> 14) & 0x3
					funct = (ins >> 12) & 0x3
					a = (ins >> 10) & 0x3
					b = (ins >> 8) & 0x3
					data = ins & 0xff
					addr = ins & 0xff
					if op == 0:
						if funct == 0:
							reg[a] = reg[a] + reg[b]
						elif funct == 1:
							reg[a] = reg[a] - reg[b]
						elif funct == 2:
							reg[a] = reg[a] * reg[b]
						elif funct == 3:
							reg[a] = reg[a] / reg[b]
						else:
							pc = 100
					elif op == 1:
						if funct == 0:
							pc = addr
						elif funct == 1:
							if (reg[a] == 0):
								pc = addr
						elif funct == 2:
							reg[a] = reg[a] < reg[b]
						elif funct == 3:
							reg[a] = reg[a] % reg[b]
						else:
							pc = 100
					elif op == 2:
						if funct == 0:
							reg[a] = data
						elif funct == 1:
							reg[a] = reg[b] + data
						elif funct == 2:
							self.out(reg[a])
							print(reg[a])
						elif funct == 3:
							self.out(data)
						else:
							pc = 100
					elif op == 3:
						if funct == 0:
							reg[a] = ram[addr]
						elif funct == 1:
							ram[addr] = reg[a]
						else:
							pc = 100
					else:
						pc = 100

m = mpu()

@testbench
def test(m):
	clksleep(120)
	print("ok")

test(m)




```

#python実行結果


```

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
ok
121
122


```

以上。
html2canvasを試す

HTML の Element を画像に変換するライブラリ html2canvas を試しました。Chrome では良好ですが、Firefox では文字のサイズが変わってレイアウトが崩れるようです。

<p class="codepen" data-height="310" data-theme-id="light" data-default-tab="result" data-user="7shi" data-slug-hash="NWxYOMm" style="height: 310px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Test: html2canvas">
  <span>See the Pen <a href="https://codepen.io/7shi/pen/NWxYOMm">
  Test: html2canvas</a> by 七誌 (<a href="https://codepen.io/7shi">@7shi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

↑ 左が撮影元の Element、右がそれを画像化したものです。内容はデザインでよく使われる [lorem ipsum](https://ja.wikipedia.org/wiki/Lorem_ipsum) と呼ばれるダミーテキストで、意味はありません。

シリーズの記事です。

1. [dom-to-imageを試す](https://qiita.com/7shi/items/771069479b91797b1fd6)
1. html2canvasを試す ← 今回の記事
1. [複数の画像を生成してローカルに保存](https://qiita.com/7shi/items/9d27e1a4911626e1fb8b)

# html2canvas

公式: <http://html2canvas.hertzen.com/>

驚異的な力技で実装されているようです。

* [動的コンテンツを画像化できるJSライブラリ "html2canvas" を使おう - KAYAC engineers' blog](https://techblog.kayac.com/html2canvas)

> `html2canvas`は、WebページのDOMやCSSを読み込み、その結果を元に解釈した結果をCanvasエレメント上に描画するライブラリです。 すなわち、実際にスクリーンショットを撮っているわけではなく、挙動としてはレンダリングエンジンに近いです。 （CSSの解釈はなんと1つ1つ実装されているので、作者は本当にすごいと思います）

# 利用方法

自前でどこかに置かなくても、[jsDelivr](https://www.jsdelivr.com/) 経由で参照できます。

```html
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.5/dist/html2canvas.min.js"></script>
```

README のサンプルコードを元に async/await で書き換えます。

```javascript
(async () => {
  dst.appendChild(await html2canvas(src));
})();
```

# 動作結果

この記事の冒頭に貼ったサンプルのスクリーンショットを見ます。

Chrome では上に少し余白ができますが、文字のサイズはそのままで画像化されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32057/2f0bd7cb-fa8c-05bf-0e63-13bd02d72192.png)
Firefox では文字のサイズが変わってしまうため、単語間のスペースが潰れたり文字が重なったりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32057/383565a5-563d-8ae1-8fc9-9e7e7683a853.png)
撮影対象がブラウザに依存するのでなければ、Chrome で利用するのが無難なようです。

※ 手動ですが Firefox で Element を画像化する方法は[前回の記事](https://qiita.com/7shi/items/771069479b91797b1fd6)を参照してください。

# 参考

以下の記事では CDN にあるバージョンは古いとありますが、jsDelivr では npm に登録されている最新版が利用できます。

* [【2019年度版】JavaScriptでhtmlを画像化する方法(html2canvasの使い方) | ワクベク](https://wakubeku.com/?p=175)
Laravel $loop変数のプロパティと実行結果


`foeach`の$loop変数のプロパティ

| $loop ループ変数       |       プロパティ | 
|:-----------------|------------------:|
| index            |      インデックス番号 | 
| iteration        |  繰り返し数(1スタート) |
| remaining        |      残っている要素数 |
| count            |          配列の総数 |
| first            |        最初の項目か |
| last             |        最後の項目か |
| even             |          偶数回目か |
| odd              |          奇数回目か |
| depth            |         入れ子レベル |
| parent           | 親のループ変数(ネストの入れ子の場合) |

## サンプル

Controller

```php:ViewController.php
public function foreach_loop()
{
  return view('view.foreach_loop', [
     'weeks' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
  ]);
}
```

bladeテンプレート

```php:foreach_loop.blade.php
<table class="table">
<tr>
  <th>value</th>
  <th>index</th>
  <th>iteration</th>
  <th>count</th>
  <th>first</th>
  <th>last</th>
  <th>even</th>
  <th>odd</th>
  <th>depth</th>
</tr>
@foreach($weeks as $week)
<tr>
  <td>{{ $week }}</td>
  <td>{{ $loop->index }}</td>
  <td>{{ $loop->iteration }}</td>
  <td>{{ $loop->count }}</td>
  <td>{{ $loop->first }}</td>
  <td>{{ $loop->last }}</td>
  <td>{{ $loop->even }}</td>
  <td>{{ $loop->odd }}</td>
  <td>{{ $loop->depth }}</td>
</tr>
@endforeach
</table>
```

## 実行結果

![Screen Shot 0032-07-08 at 5.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482880/217e8c77-373d-5080-32dc-b01519c92825.png)
pytube3を使って、Youtubeの動画をダウンロードする方法

## 環境
OS: mac os x 10.15.5
python: 3.8.0
pythonバージョン管理: pyenv

## pytube3とは
[pytube](https://github.com/nficano/pytube)はyoutubeの動画をダウンロードするpythonライブラリです。
googleさんは[youtube Data API](https://developers.google.com/youtube/v3/getting-started?hl=ja)を公開しておりますので、ビジネスなどでyoutubeの動画のダウンロード機能を使う場合は、pytubeは使わないことをおすすめします。

pytubeはあくまで、私的で非営利な活動で、過度なリクエストを送らない程度にお使いください。


## pytube3をインストール
python3 をお使いの場合は、pytube3をインストールしてください。

```
pip install pytube3
```

python2 をお使いの場合は、pytubeをインストールしてください。

```bash

pip install pytube
```

## 動画リンクを挿入したcsvファイルを用意

```csv:youtube_links.csv
https://www.youtube.com/watch?v=-VoogELsBms
https://www.youtube.com/watch?v=cN1qnAx8tqg
```


## インストールを行うソースコード

```python:main.py
import csv
from pytube import YouTube


def download(url, index):
    yt = YouTube(url)
    print(str(index) + "番目の動画をダウンロードします。")
    yt.streams.filter(progressive=True, file_extension='mp4').order_by(
        'resolution').desc().first().download('./news', str(index))


with open('youtube_links.csv') as f:
    reader = csv.reader(f)
    for index, row in enumerate(reader):
        url = row[0]
        print("start download")
        download(url, index)
        print("completed download")

```

## 実行

```
$ python main.py
```

githubにソースコードを載せておきます。
https://github.com/SeiyaTakahashi/pytube3-project
UE4のAIControllerクラスを触ってみた

## はじめに
現在制作しているゲームにAI(？)のような機能が必要になってきたので、UE4の機能として提供されているAIControllerについて調べてみたのでまとめ

## AIControllerを使用するにあたって必要なもの
### AIController
- 後述するBlackBoardとBehaviorTreeを関連付け、パラメータのセット等をおこなうクラス
- `Get/Set Value as (型)`ノードを使用してBlackBoardが保持する変数の値を取得・設定する
  - `BlackBoardComponent`が所有するノード
  - `Key Name`にBlackBoardが保持するKeyの文字列を指定する

### BlackBoard
- AIの行動基準となるパラメータを保持するクラス
- Keyとして名前と型を持つ

### BehaviorTree
- AIの行動ロジックを組むクラス
- 関連付けされたBlackBoardからパメータの参照等をおこなう

### BTTTaskBluePrintBase派生のクラスたち(自作タスク)
- AIへの行動モジュールを自作したもの
- BlackBoardKeySelector型を経由して値を取得・設定する
  - `Get/Set BlackboardValue as (型)`を使用
    - BehaviorTreeが所有するノード

## 躓きポイント
BehaviorTreeのMoveToタスクを使用する際には、対象のPawnをCharacterクラス派生にするかFloatingPawnMovement等のPawnMovementComponent派生のコンポーネントを付与している必要がある。
これをしなかったためにMoveToタスクが正しく挙動しなくて小一時間悩んだ

## 参考にしたページ
[【UE4 AI入門】簡単なNPCの作成から学ぶUE4のAI | UnrealEngineDrive](https://hahanha-create.com/2020/01/11/%E3%80%90ue4-ai%E5%85%A5%E9%96%80%E3%80%91%E7%B0%A1%E5%8D%98%E3%81%AAnpc%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6ue4%E3%81%AEai/)
「WebShellQuickScanner」Linuxサーバの指定フォルダーのPHPファイル中に、WebShellと高リスクファイルを速いて探し出すのクイックチェックツール,そして、検査結果をTelegramにプッシュする。

## 「WebShellQuickScanner」とは

「WebShellQuickScanner」は、Linuxサーバの指定フォルダーのPHPファイル中に、WebShellと高リスクファイルを速いて探し出すのクイックチェックツール,そして、検査結果をTelegramにプッシュする。

「Telegram」はTelegram Messenger LLPが開発するインスタントメッセージシステムである。詳細は[こちら(Telegram - ウィキペディア)](https://ja.wikipedia.org/wiki/Telegram)をクリックしてください。

**この記事は、日本語の使用ドキュメントとして発表されます。**

## 「WebShellQuickScanner」プロジェクトのリポジトリ

**Github: [DeepSkyFire/WebShellQuickScanner](https://github.com/DeepSkyFire/WebShellQuickScanner)**

## 「WebShellQuickScanner」について

Linuxサーバの指定フォルダーのPHPファイル中に、WebShellと高リスクファイルを速いて探し出すのクイックチェックツール,そして、検査結果をTelegramにプッシュする。

**しかし、検出されたファイルは削除されません。だから、これらのファイルをどうするかはあなた自分自身を決断するです。**

## 「WebShellQuickScanner」にクイックスタート

- **「WebShellQuickScanner」のダウンロード**

        wget --no-check-certificate https://raw.githubusercontent.com/DeepSkyFire/WebShellQuickScanner/master/src/WebShellScanner.sh && chmod +x WebShellScanner.sh

- **クイックチェックをスタート**

        bash WebShellScanner.sh -p /data/www-data(ターゲットフォルダーを指定する)

## 「WebShellQuickScanner」の使用方法の詳細

- **必要の依存関係**

もし、検査結果をTelegramにプッシュしての機能を利用するためには、OSにcURLをインストールするは必要があります。

- **検査結果をTelegramにプッシュする**

この機能を利用するためには、まず、Telegramで`@BotFather`に新しいBOTを申し込みします。そして、Telegramで`@userinfobot`を使って、自分のアカウントのCHAT_IDを確認してください。

**注意! 現在、Telegramでは、メッセージに送信できる最大文字数を制限するようになりました。最大文字数は4096文字。もし検査結果の文字数が4096文字を超えると送信失敗となります。その以後、私は新しいプッシュ方法を更新する予定です。***

- **ホスト名(Host Name)について**

ホスト名を自分で指定することができます。ホスト名を指定しない場合、スクリプトは自動的にOSからデフォルトのホスト名を読み込みます。

- **ログファイルの保存について**

ログファイルをサーバー中に保存したい場合は、以下の設定のような設定しましょう：

    bash WebShellScanner.sh -p /data/www-data -l /home/wwwwlogs

**注意! ログ保存フォルダーのアドレスの末尾に「/」記号を書かないでください。**

- **フルデモ**

もし、あなたは「/data/www-data」フォルダーを検査し、ログファイルを「/home/wwwlogs」フォルダーに保存し、そして、「MyServer1」のホスト名を指定した、検査結果をTelegramにプッシュするの場合は、以下の設定にような設定しましょう：

        bash WebShellScanner.sh -p /data/www-data -t TELEGRAM_BOT_TOKEN -c TELEGRAM_CHAT_ID -n MyServer1 -l /home/wwwwlogs

- **ヘルプメッセージを表示する**

        bash WebShellScanner.sh -h

- **定期点検**

Linux OSから`crontab -e`を使って、スキャンタスクを設定します。

例：

        15 4 * * * "/root"/WebShellScanner.sh -p "/data/www-data" -t "TELEGRAM_BOT_TOKEN" -c "TELEGRAM_CHAT_ID" -n "MyServer1" -l "/home/wwwlogs" > /dev/null

上記の例では、１日１回、午前４時１５分にスキャンタスクが実行される。

## パラメータ(変数)の説明

    WebShellScanner.sh [-h] [-p <ターゲットフォルダー>] [-t <TELEGRAM BOT TOKEN>] [-c <TELEGRAM CHAT ID>] [-n <ホスト名>] [-l <ログファイルの保存フォルダー>]

**使用可能なパラメータ：**

    -h ヘルプメッセージを表示する. オプションパラメータ(変数).

    -p <ターゲットフォルダー> 検査したいなフォルダー.

    -t <TELEGRAM BOT TOKEN> Telegram Bot Token. オプションパラメータ(変数).

    -c <TELEGRAM CHAT ID> Telegram Chat id. オプションパラメータ(変数).

    -n <HostName> カスタムホスト名. オプションパラメータ(変数).

    -l <ログファイルの保存フォルダー> ログファイルの保存フォルダー(ログ保存フォルダーのアドレスの末尾に「/」記号を書かないでください). オプションパラメータ(変数).

## オープンソースライセンス

- **[GPLv3（GNU General Public License v3.0）](https://github.com/DeepSkyFire/WebShellQuickScanner/blob/master/LICENSE)**
様々なおみくじゲーム

# はじめに
pythonを用いるとrandomやif,else,乱数など様々な方法でおみくじを作ることができる。今回は最終制作物ということでいろいろな方法でおみくじを作ることにした。


#一番シンプルなおみくじ

```omikuzi.py
import random

destiny = ['大吉','中吉','小吉','吉','凶','大凶']

print(random.choice(destiny))
```

これはランダムを用いておみくじを作った。ランダムを使うことで、リストの中からランダムに選択してくれるプログラムを組むことができる。
**デメリットとしては、大吉や大凶などのレア度を再現することができない。
簡単に大吉が出てしまい、面白くない**

#確率を操作できるおみくじ
```omikuzi.py
print("1~60までの数字を入力してね")

number = input()

if 0 <= int(number) <= 3:
    print("大吉")

elif 4 <= int(number) <= 10:
    print("中吉")

elif 11 <= int(number) <= 20:
    print("小吉")

elif 21 <= int(number) <= 40:
    print("吉")

elif 41 <= int(number) <= 55: 
    print("凶")

elif 56 <= int(number) <= 60:
    print("大凶")

else:
    print("die")
```

ここで使われるifはその後に続く条件式が成立するならばその後に続く処理を行うという事である。elifはelse ifの短縮である。
elseはifが存在しないときにelseの処理を行う。
これらのことより、条件分岐を行った。
**この方法を使うことで、大吉や大凶の出現の確率を極端に低くできることや、小吉などの真ん中らへんのものの出現確率を高くすることができる。**


#tkinterのおみくじ
```omikuzi.py

import tkinter.messagebox as mb
import tkinter as tk
import random
      

a = tk.Tk()
a.title("おみくじゲーム")
a.geometry("400x250")


b = tk.Label(text="クリックしてね")
b.pack()

kekka = [["大吉"], ["宝くじを今すぐ買うべき！！"], ["吉", "良いことあるよ！"],["小吉", "きょうの夜ご飯は大好物！"],
["凶", "今日は失敗続きの一日に"],["大凶", "今日は外に出ちゃダメ。何が起こるかわからない"]
]    
def botan():
    c = random.randrange(len(kekka))
    r = kekka
    mb.showinfo(r[0], r[1])

bota = tk.Button(text ="おみくじを引く",width =40, height = 10, command = botan)
bota.pack()

a.mainloop()
```
乱数を使うことでランダムなおみくじを作成した。
ボタンを押した後の結果を複数用意した。



#実行結果
<img width="960" alt="2020-07-08 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638201/6683264c-875f-194e-1c8b-e0da2228e5f7.png">

<img width="960" alt="2020-07-08 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638201/de3d56af-bf67-a211-89f4-b01e7fdd2e33.png">


#感想
記事を参考にしたのでスムーズにできた。個人的には確率を自分で決めることができるおみくじが1番良いと思いました。次は自分で１から作りたいと思いました。
































#参考にした記事

>[Tkinterで作るおみくじ＋α](https://qiita.com/FangJoker7714/items/f31656d3f5be4755b1a9)
[Pythontkinterの使い方入門おみくじアプリを作ってみる](https://python-introduction.com/?p=1221)
ReactとFlaskをつなげる

create-react-appで作ったフロントとFlaskで作ったAPIをつなげる(サーバーをふたつ立ち上げる必要をなくす)方法の備忘録です。

こちらの動画を参考にさせていただきました。
[Serving React with a Flask Backend](https://www.youtube.com/watch?v=YW8VG_U-m48)

# 前提
ツリー構造はこんな感じ。

```
react-flask-app/
├─Flask-Backend
|   ├─static
|   ├─templates
|   └─app.py
└─React-Frontend
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
```

app.pyはこんな感じ。

```python:app.py
from flask import Flask, render_template

app = Flask(__name__)

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

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

# Webpack解放

```:webpackの設定を弄れるようにする
$ cd React-Frontend
$ yarn eject
$ Are you sure you want to eject? This action is permanent. (y/N) y
```

React-Frontendフォルダの下にconfigフォルダが追加されます。

```
react-flask-app/
├─Flask-Backend
|   ├─static
|   ├─templates
|   └─app.py
└─React-Frontend
    ├─config
    |   └─jest
    |       ├─env.js
    |       ├─paths.js
    |       ├─webpack.config.js
    |       └─webpackDevServer.config.js
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
```

paths.js内で、buildフォルダを作成する場所のパスを`build`から`Flask-Backend/static/react`に変更します。

```javascript:paths.js
(省略)
module.exports = {
    (省略)
    appBuild: resolveApp('../Flask-Backend/static/react'),
    (省略)
}
```

webpack.config.js内で、`static/js/[name].[chunkhash:8].js` -> `js/[name].[chunkhash:8].js`のように、ファイル名のパスが`static/`から始まっているところを全て消します。
次に、HtmlWebpackPluginオブジェクト内にfilenameを追加し、Flask-Backendフォルダのtemplatesフォルダ下にindex.htmlをビルドするよう指定します。

```javascript:webpack.config.js
(省略)
plugins: [
    new HtmlWebpackPlugin(
        Object.assign(
            {},
            {
                inject: true,
                template: paths.appHtml,
                filename: '../../templates/index.html' <-- 追加
            },
            (省略)
        )
    )
]
```

package.json内にhomepageの項目を追加し、buildフォルダ(ここではreactフォルダ)を指定します。

```json:package.json
{
    "homepage": "/static/react",
}
```

# ビルドして立ち上げる

`yarn build`でビルドします。staticフォルダとtemplatesフォルダの下にビルド後のファイルが追加されます。

```
react-flask-app/
├─Flask-Backend
|   ├─static
|   |    └─react
|   |        ├─css
|   |        └─js
|   ├─templates
|   |    └─index.html
|   └─app.py
└─React-Frontend
    ├─config
    |   └─jest
    |       ├─env.js
    |       ├─paths.js
    |       ├─webpack.config.js
    |       └─webpackDevServer.config.js
    ├─public
    ├─src
    ├─package.json
    └─yarn.lock
```

```:Flaskアプリを立ち上げる
$ cd Flask-Backend
$ python app.py
```

http://localhost:5000/ にアクセスします。

以上。


# 追記: ejectしない方法
`yarn eject`してwebpackの設定を弄らずともつなげられるようです。

React-Frontendに移動します。
`yarn build`します。
React-Frontend内にbuildフォルダが追加されます。
app.py内でstaticフォルダとtemplatesフォルダのパスを指定します。

```python:app.py
from flask import Flask, render_template

app = Flask(__name__, static_folder='../React-Frontend/build/static',
template_folder='../React-Frontend/build')

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

if __name__ == '__main__':
    app.run()
```
javaスクしてると

他の言語も、
もうちょっと
頭を柔軟にしてもとおもうけど、
　javascriptがインタープリタだから
　そんなの他のコンパイラー言語には、無理やろって

　でも、セミコンパイラーのjavaが横目で見てるんだが。。ｗｗ
Pythonでの引数渡し便利技（タプル、辞書型）

#Pythonで関数に引数を渡すときの便利技
仮に文字列を送るとして、関数に引数を送る際に
変数、タプル型、辞書型で受けとらせる方法が以下の通り。

```Python:function.py
# ****************
# *  2020.07.08
# *   ProOJI
# ****************


def menu(food, *args, **kwargs):
    print(food)
    # タプル
    print(args)
    print('args[0] = ' + args[0])
    print('args[1] = ' + args[1])
    # 辞書型
    print(kwargs)
    # KeyとValueを分けて出力も可能
    for k,v in kwargs.items():
        print('Key is '+k+'. Value is '+v+ '.')


menu('Apple', 'Banana', 'Orange', entree='Beef', drink='Beer')

```
初めの引数`'Apple'`は関数`menu`の`food`で受け取るので

```Python
    print(food) # 出力：Apple
```
となります。
次は関数`menu`側にアスタリスク１つ付いた`*args`があります。
これは複数の引数をタプルで受け取ります。以下の通りです。

```Python
    print(args) # 出力：('Banana', 'Orange')
```
タプルは配列のように扱うこともできますので
以下のように値を拾うことも可能です。

```Python
    print('args[0] = ' + args[0])
    # 出力：args[0] = Banana
    print('args[1] = ' + args[1])
    # 出力：args[1] = Orange
```
最後に関数`menu`側にアスタリスク2つ付いた`**kwargs`がありますが
これは辞書型で受け取ることができます。
引数として`entree='Beef', drink='Beer'`を送っていますが
`Key"entree"： Value"Beef"`
`Key"drink"： Value"Beer"`という形式の辞書型で受け取ります。
結果、普通に`print()`で出力すると

```Python:
print(kwargs) # 出力：{'entree': 'Beef', 'drink': 'Beer'}
```
となりますが、`for k,v in kwargs.items():`によりそれぞれを取得して

```Python:
    for k,v in kwargs.items():
        print('Key is '+k+'. Value is '+v+ '.')
    # 出力
    # Key is entree. Value is Beef.
    # Key is drink. Value is Beer.
```
とすることもできます。
#まとめ
関数の値渡しの方法は様々で工夫次第で便利に活用できます。
様々なフレームワークやライブラリと併せて使用するPythonですが
基本を抑えておきたいと思います。
【R】エリアごとに集計-エリア単位

#時間ループ

#エリアごと総和を読み込み
data<-エリア総和データ

list<-sort(data$area)

total_list<-data.table()

for(area in list){

tmp<-data[data$area==area,]
write.csv(tmp,時間_エリア.csv)

sum<-sum(tmp$time)
length<-length(tmp$area)

area_tmp<-data.table(area)
sum_tmp<-data.table(sum)
length_tmp<-data.table(lemgth)

tmp_data<-cbind(area_tmp,sum_tmp,length)

}

total_table<-rbind(total_tmp,tmp_data)

write.csv(total_table,
Snowflake に試験的にデータを入れるときは TRANSIENT  にしてストレージ課金を減らそう

# 概要

試験的にデータを出し入れ（`CREATE TABLE` や `DROP TABLE` を繰り返すイメージ)すると、裏ではFail-safeのストレージ課金が作ったデータ×7日間分発生して死ぬ。（死ぬわけではないけど、試験的にデータを入れているだけのときに操作ミスで消しちゃいましたとかが大きな問題になることはない）

# どうするの？

このFail-safe課金を避けるには `CREATE TABLE` のときに `TEMPORARY` または `TRANSIENT` を指定しましょう。

このとき `TEMPORARY` だとセッションが終わると削除されます。
`TRANSIENT` ならドロップするか障害で失われるまでは削除されません。


参考
- https://docs.snowflake.com/ja/user-guide/data-failsafe.html
- https://docs.snowflake.com/ja/user-guide/data-cdp-storage-costs.html
- https://docs.snowflake.com/ja/sql-reference/sql/create-table.html
【R】データの紐づけ

#時間ループ

#エリアデータ
時刻→ID→エリア

result→match 読み込み

id_list<-match$id

area<-data.table()

for (id in id_list){

data<-対象月読み込み
ext_data<-data[data$id==id,]
area<-rbind(area,ext_data)

}

area_bind<-cbind(id_list,area)
write.csv(area_bind,result/time_sum/match/時刻.csv)
SQLアンチパターン　ID Required

# ID Required

どのテーブルにも「id」という名前の主キーが必要という考えに起因したアンチパターン。

## そもそも主キーって？

データ行を一意であると識別するためのキー。
「PRIMARY KEY」とも呼ばれている。

主キーにはNULLは許容されておらず、格納されるデータが一意である必要がある。

主キーにはどのカラムを選択しても理論上は問題ないが***一意である***ことが条件であるため「名前」や「メールアドレス」のような重複する可能性のあるカラムを主キーに設定するべきではない。

# ID Requiredの何がいけないのか？

以下のような中間テーブルがあったとする。
このテーブルでは書籍を管理するための「book_id」とその書籍の解説を管理するための「description_id」が格納されている。

## パターン１

このテーブルでは１つの書籍に対して１つの解説として組み合わせが一意となるようにデータを格納したい。

|物理名|主キー|
|:---|:---:|
|id|◯|
|book_id||
|description_id||

上記の構成だと以下のように主キーの重複はないが「book_id」と「description_id」の組み合わせが重複するデータが入ってしまう可能性がある。

|id|book_id|description_id|
|:---|:---|:--|
|1|1|1|
|2|<font color="Red">**2**</font>|<font color="Red">**2**</font>|
|3|<font color="Red">**2**</font>|<font color="Red">**2**</font>|

## パターン２

[パターン１](#パターン１)の重複を踏まえて以下のように「book_id」と「description_id」に「UNIQUE KEY」を設定すれば組み合わせの重複を防ぐことができた。

|物理名|主キー|ユニークキー|
|:---|:---:|:---:|
|id|◯||
|book_id||◯|
|description_id||◯|

ん.....？

パターン２では「book_id」と「description_id」にユニークキーを設定することで重複を防ぐことができた。
なら「id」ってなんのためにあるの.....？

## パターン３

このパターンでは「description」が同テーブルに格納されています。
このテーブルでも同様に、書籍の重複がないように「UNIQUE KEY」を設定しています。

|物理名|主キー|ユニークキー|
|:---|:---:|:---:|
|id|◯||
|book_id||◯|
|description|||

このパターンでは「book_id」に「UNIQUE KEY」が設定されており自然キーとして使用できる。
そのため、「book_id」を主キーに設定すれば「id」列はやはり不要となる。

# ではどうしたら良いのか

前提として主キー、及びユニークなフィールドがないとレコードの特定ができず重複したデータを複数格納してしまうことがあります。

[そもそも主キーって？](#そもそも主キーって)の項目でも記載しましたが***格納されるデータが一意である***必要があり、主キーを設定することでテーブル内の全ての行が一意であることを保証してくれる。

また外部キーからの参照によりテーブルとテーブルの関連付けを行うため重要である。

再び[そもそも主キーって？](#そもそも主キーって)の項目した内容ではあるが、主キーにはどのカラムを選択しても理論上は問題ないが***一意である***ことが条件であるため「名前」や「メールアドレス」のような重複する可能性のあるカラムを主キーに設定するべきではない。

## それを踏まえてどうしたら良いのか

[パターン２](#パターン２)のような場合ではid列が使用されずに無駄な列になってしまうため複合主キーを使用する方法などがあります。

中間テーブルなどの場合は組み合わせによって***一意である***ことが担保されるため無駄な列ができない。

[パターン３](#パターン３)の場合は主キー列以外にユニークなキーがあり自然キーとして使用できるため、その場合は自然キーを主キーとして設定することで無駄な列を排除することもできる。

# まとめ

アンチパターンとならないために。

自然キーや複合キーを活用することで一意であることも保証した上で冗長なキーの作成を減らすことができる。

フレームワークなどによっては「id」列を持つことで利用できる機能等もあるため、一概にアンチパターンを排除すべきではない場合もある。

# 次回

Keyless Entry

# 参考文献

[SQLアンチパターン](
https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892/ref=sr_1_1?adgrpid=104444684056&dchild=1&gclid=CjwKCAjw4_H6BRALEiwAvgfzqy-f83NTsyQkauo7gn6ysgAPmJvKyvuI5FaXFnxFmhVfCzCRRACsaBoCY-oQAvD_BwE&hvadid=447984765572&hvdev=c&hvlocphy=1009332&hvnetw=g&hvqmt=e&hvrand=13417269104929133208&hvtargid=kwd-335484809678&hydadcr=27264_11561110&jp-ad-ap=0&keywords=sql%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&qid=1599934568&sr=8-1&tag=googhydr-22)

![参考文献.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/b46d45ab-75ec-a620-eeb2-a422f6b1e659.jpeg)
ラズベリーパイを起動したらやるべき３つの事

#はじめに
前回の記事ではラズパイのOSをSDカードに書き込む事を取り上げました。なので、今回の記事では僕がラズパイを使っていて不便だと感じた問題を調べて解決したのでそれを共有したいと思います。ラズパイを手に入れたは良いが、何をやれば良いのか分からないという人、ラズパイで日本語入力て結局どうやるのと思っている人は最後まで見て行って下さい。(今回参考にしたサイトのリンクは最後の方に貼って置きますので良かったら見て下さい)
#ラズビアンのシステム更新をするには？
はじめにラズベリーパイを起動した時に聞かれた中でシステムを更新するか聞かれたと思いますが、要はその時にやったシステム更新をコマンドでやるということです。それではやって行きましょう。

まずは**LXTermi**を起動して下さい(ターミナルは左端から数えて四番目にあります)。そうしたら

```terminal
pi@raspberrypi:~ $ 
```
と表示されるはずなのでそこにまず**sudo apt update**とこんな感じに打ち込みますEnterを押します

```terminal
pi@raspberrypi:~ $ sudo apt update
```
そうするとラズベリーパイがなんかいろいろやってくれるので、はじめにターミナルが起動した時のように文字が打ち込めるようになるまで放置して下さい(更新によってはメッチャ時間がかかるので注意)。処理が終わりましたら、次は**sudo apt update**これを打ち込んでEnterを押して下さい。これも更新がなけれはすぎに終わりますが、環境によっては時間がかかります。たまにターミナルにこの処理を続けるかと聞かれることがあるので、その時は**y**と入力してEnterを押して下さい。そしたらまたターミナルに文字を入力できるようになるまで待機して下さい。あとは**sudo apt dist-upgrade**を入力して実行したら、処理が終わるまで待ってログアウトから**reboot**を選択するか、ターミナルに下のように入力し実行するだけで完了です。

```terminal
pi@raspberrypi:~ $ sudo reboot
```
#日本語入力をしたいんだ！！
今度は日本語入力をする為のソフトをターミナルを通じてインストールなどを行います。はじめに先程と同じく**LXTermi**を起動して下さい。そうしたら、下のような画面が出るので、

```terminal
pi@raspberrypi:~ $ 
```
そこに**sudo apt install ibus-mozc**と入力して実行してください

```terminal
pi@raspberrypi:~ $ sudo apt install ibus-mozc
```
実行している最中、システム更新の時と同じようにプロセスを続けて良いか聞かれるのでその時は**ｙ**と入力してEnterを押して下さい。そして文字が打てるようになるまで放置する。プロセスが終了したら再起動をして下さい。最後に右端から五番目の入力モードをクリックして**日本語-Mozc**を選択すれば普通に日本語入力をする事ができます。
#Python3どこ行った？
これは僕個人の問題になってしまうかもしれませんが、そもそも僕がラズパイを買った理由がpythonをやりたくて買ったのに入ってなくて慌てて探しました(笑)。表示されていないアプリを表示させるのは実は簡単で、まず左上の端にあるラズベリーパイのマークをクリックして設定の**Main　Menu Editor**を開いて下さい。アプリ内に表示される追加したいアプリを探してチェックを入れるだけで終了です。僕もこの方法でPythonを表示させることができました。
##IDLEが選択肢なかったら
[https://qiita.com/nokomilk_fish/items/34c2ff77dff71c645d43#comment-5fa59b61a4dc77030cb0](https://qiita.com/nokomilk_fish/items/34c2ff77dff71c645d43#comment-5fa59b61a4dc77030cb0)
こちらの記事を参考にして下さい。
#さいごに
今回参考にしたサイトはこれです。
[https://www.youtube.com/watch?v=R1Zn31cVgn4](https://www.youtube.com/watch?v=R1Zn31cVgn4)

最後まで見てくれてありがとう。これからはラズパイ関連の記事も書いていく予定なのでよかったらフォローして下さい。もし間違いを見つけたら気軽にコメントで教えて下さい。前回の記事ですよけれ一緒に読んで下さい。
[ラズビアンを確実にインストールする方法](https://qiita.com/lat-uni/items/d43c085988c87aeea3e8)
embulk-output-bigqueryプラグインでBQの4GB制限に引っ掛かる場合の対処方法

# TL;DR

以下、いずれかで対処する:

1. BigQueryに読み込むファイル形式を非圧縮形式にする。これで5TBまで行ける
2. 1ファイルあたり4GB以下になるように、ファイルの分割数を上げる

# 背景

BigQueryにCSV, JSONデータを読み込む際、最大ファイルサイズに関して以下の制限がある:

- 圧縮形式 ... 4GBまで
- 非圧縮形式 ... 5TBまで

参照: https://cloud.google.com/bigquery/quotas?hl=ja#load_jobs

この制限を越えると下のようなエラーが出る:

```
2020-07-07 07:28:13.136 +0000 [ERROR] (Ruby-1-Thread-2: /root/.embulk/lib/gems/gems/embulk
-output-bigquery-0.6.4/lib/embulk/output/bigquery/bigquery_client.rb:152): embulk-output-b
igquery: failed during waiting a Load job, get_job(my-project, embulk_load_job_7
d68ce22-a9e5-4799-8f5c-f331eab4277e), errors:[{:reason=>"invalid", :message=>"Error while 
reading data, error message: The options set for reading CSV prevent BigQuery from splitti
ng files to read in parallel, and at least one of the files is larger than the maximum all
owed size when files cannot be split. Size is: 5077619708. Max allowed size is: 4294967296
."}]
```

※↑画面に収まるように改行しているが、実際には1行のエラー

[embulk-output-bigquery](https://github.com/embulk/embulk-output-bigquery)プラグインでは、2015年4月からファイルサイズが4GB以下になるように分割する対応をするイシューが積まれている。[^1]
…が、BQ側で非圧縮時の制限が大きく引き上げられたので、今後も対応される可能性は低いのではないだろうか。

ネットで検索して見つかるembulk-output-bigqueryプラグインの利用例だと、圧縮ファイル形式を使っているものが多い気がするので、初心者はハマりやすいと思う。（私もハマった。）

# 動作確認環境

- Embulk v0.10.5
- embulk-output-bigquery v0.6.4

# 対処法
## BigQueryに読み込むファイル形式を非圧縮形式にする

例えば以下のように設定する:

```YAML
out:
  type: bigquery
  mode: replace
  auth_method: service_account
  json_keyfile: example/your-project-000.json
  dataset: your_dataset_name
  table: your_table_name
  source_format: CSV # or NEWLINE_DELIMITED_JSON
  auto_create_dataset: true
  auto_create_table: true
  schema_file: example/schema.json
```

NOTE:

- `compression` オプション値はデフォルトで `"NONE"` （非圧縮）である

## 1ファイルあたり4GB以下になるように、ファイルの分割数を上げる

これはEmbulkの[Local Executorプラグイン](https://www.embulk.org/docs/built-in.html#local-executor-plugin)のオプションで設定できる。

例:

```YAML
exec:
  max_threads: 10
  min_output_tasks: 10
```

この設定で、ファイルを10分割してBQに送信することができた。
たぶん、分割数については `min_output_tasks` の設定だけでいいのだと思う。

# まとめ

embulk-output-bigqueryプラグイン利用時に、BigQueryの4GBファイルサイズ制限に引っ掛かる場合の対処方法について述べた。

1番めに挙げた方法の方が汎用的だと思うが、データの転送量をなるべく抑えたいとか、ローカルのストレージの消費を抑えたいという場合には、2番めの方法がよいのではないだろうか。

以上。

# 脚注

[^1]: [Split file each 4GB for BigQuery Quota Policy · Issue #6 · embulk/embulk-output-bigquery](https://github.com/embulk/embulk-output-bigquery/issues/6)
【R】リストの総和


#時間ループ
繰り返し処理
time_table<-data.table()

#Matchリストのループ
list<-read.csv(Match)
for(id in list$id){

data<-id file(duration/id.csv)
time_sum<-(time<-data$time)

id<-data.table(id)
sum<-data.table(sum)

tmp_sum_table<-cbind<-(is,sum)
time_table<-rbind(time_table,tmp_sum_table)
}

write.csv(time_table,result/time/match/時刻.csv)
src/client/app と src/client/theme-default のつなぎ込み


## はじめに

* バージョン ... 0.4.1
* SHA-1 ハッシュ ... 582c5255e25e923d0ed7750dba1e830793e15a82

1. [VitePress のディレクトリ構成](https://qiita.com/domodomodomo/items/1048f51d98ab5fd52d12)
2. [src/client/app と src/client/theme-default のつなぎ込み <-- いまココです。](https://qiita.com/domodomodomo/items/49b1944f09f8f9f57519)
3. [Markdown ファイルと src/client/app, Vue インスタンス本体のつなぎ込み](https://qiita.com/domodomodomo/items/f44bf1f49cff511890c7)
4. [Vite と VitePress のつなぎ込み](https://qiita.com/domodomodomo/items/c3b828bf9f7cb7e9a18f)
  1. [dev 編](https://qiita.com/domodomodomo/items/aea100ae69344d6dcc39)
  2. build 編(未着手)

## 1. 概要

createApp を使い Vue インスタンスを作成しています。createApp, Vue 3 の API 変更の経緯は以下の資料に詳しいです。

* [rfcs/active-rfcs/0009-global-api-change.md - vuejs/rfcs](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0009-global-api-change.md)
* [Vue 3 Tutorial (for Vue 2 Users)](https://vuejsdevelopers.com/2020/03/16/vue-js-tutorial/)

## 2. コード

Vue インスタンスを生成している createApp 関数を、ざっくり抜粋します。この createApp 関数は、ルータの箇所でもう少し詳しく見て行きます。

```/src/client/app/index.ts
import { createApp as createClientApp, createSSRApp, ref, readonly } from 'vue'


// ... 中略


export function createApp() {

  // ... 中略

  //
  // ここで Vue のインスタンスを生成しています。
  // またテーマと Vue のインスタンスがつなぎこまれていることもわかります。
  //
  const app =
    process.env.NODE_ENV === 'production'
      ? createSSRApp(Theme.Layout)
      : createClientApp(Theme.Layout)


  // ... 中略

  // Content には Vue コンポーネントに変換されたマークダウンファイルが
  // 入っています。詳細は、router の箇所で詳述します。
  app.component('Content', Content)
  
  // ... 中略

  //
  // enhanceApp を設定しています。
  //
  if (Theme.enhanceApp) {
    Theme.enhanceApp({
      app,
      router,
      siteData: siteDataRef
    })
  }

  // app だけではなく router も返しています。
  // router はルータの箇所で詳述します。
  return { app, router }
}

// inBrowser は dev の場合、有効になります。
// dev の場合は、ここでマウントしています。
// build の場合は、確認中です。
if (inBrowser) {
  const { app, router } = createApp()
  // wait unitl page component is fetched before mounting
  router.go().then(() => {
    app.mount('#app')
  })
}
```

* [vuejs/vitepress - /src/client/app/index.ts](https://github.com/vuejs/vitepress/blob/582c5255e25e923d0ed7750dba1e830793e15a82/src/client/app/index.ts)

## おわりに
以上になります。ありがとうございました。次は、以下の記事になります。ルータの実装を見て行きます。

* [Markdown ファイルと src/client/app, Vue インスタンス本体のつなぎ込み](https://qiita.com/domodomodomo/items/f44bf1f49cff511890c7)
Overload は 型安全を破壊する[Typescript]

# Typescript の型安全
型安全にコードをかけるというのが Typescript のいちばんの強みと言っても過言ではないかと思います。
例外として、 `any` や `as` を使うと型安全が失われてしまうというのもよく聞く話ではないでしょうか。

# 例外はまだある
ただし、例外はそれだけではなく **Overload の機構も型安全を破壊することがあります**。(他にもまだあるのかもしれない)
知っていれば簡単な話だと思うのですが、知らなければ思わぬところで転んでしまうことがあるかもしれないなと感じたので、記事として残しておきます。

# Typescript の Overload

Typescript にも Overload の仕組みが存在しており、通常の関数やコンストラクタ等で使用することができます。

```ts

// 引数なしだと string 型
function safeFunc(): string;
// number 型の引数を渡すと number 型
function safeFunc(n: number): number;
// 二つの型情報を満たす実装
function safeFunc(n?: number): number | string {
  return n ?? 'string';
}
it('n', () => {
  const number = safeFunc(10.1);
  expect(typeof number === 'number');
  expect(number).toBe(10.1);
  expect(number.toFixed()).toBe('10');
});
it('undefined', () => {
  const string = safeFunc();
  expect(typeof string === 'string');
  expect(string).toBe('string');
  expect(string.length).toBe(6);
});
```

<img width="748" alt="Screen Shot 2020-07-08 at 0.03.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252342/b11bbae3-2834-e30e-8054-37150de59197.png">
<img width="673" alt="Screen Shot 2020-07-08 at 0.03.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252342/e4944d47-7e4c-d959-cba0-04aafc29fb3a.png">
型も効いていて、いい感じですね。

# 型安全が破壊される場合

Overload が見ているのはあくまでも型情報だけで、実装から型が推論されるわけではありません。
**Overload を行う場合、型の整合性は実装側で担保する必要があります。**

最終的に実装を含んだ関数と返り値の型情報が異なっている場合は通常通り検証されますが、Overload で使われた型情報まではカバーされないのです。

**結果、「Typescript は型安全〜」と思って、気を抜いてOverload を使うと、簡単に型安全が破壊されます。**


Overload に用いる型情報は先ほどと同じですが、実装を少し変えて、型安全が破壊されるコードを書いてみます。

```ts
// 引数なしだと string 型
function unsafeFunc(): string;
// number 型の引数を渡すと number 型
function unsafeFunc(n: number): number;
// 二つの型情報を満たす実装
function unsafeFunc(n?: number): number | string {
  // 実際には、number 型の引数を渡すと string 型 が返る
  if (n) return n.toString();
  // 実際には、引数なしだと number 型 が返る
  return 0;
}
it('n', () => {
  const number = unsafeFunc(10.1);
  expect(typeof number === 'string');
  expect(number).toBe('10.1');
  expect(() => number.toFixed()).toThrowError(TypeError);
});
it('n', () => {
  const string = unsafeFunc();
  expect(typeof string === 'number');
  expect(string).toBe(0);
  expect(string.length).toBeUndefined();
  expect(() => string.trim()).toThrowError(TypeError);
});
```

<img width="772" alt="Screen Shot 2020-07-08 at 0.16.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252342/909148bd-34d6-b99e-054a-19224c44d64e.png">
<img width="677" alt="Screen Shot 2020-07-08 at 0.16.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252342/6985cc51-ca7f-79b2-a350-4958e0a9f222.png">

型情報は Overload で指定したものが返るため、型情報とテストの内容はちぐはぐですが、テストはこのまま通過します。

# Overload は使わない or 必要最低限に
`any` は危険だって話はよく聞くんですが、 **Overload** のことは、検索しても言及しているところが特に見つからなかったため、「これも危ないのでは？」と書いてみました。(`as` もそこそこ危ない)
少し強めの言葉を使っていると思うのですが、この記事になにか変なところや間違いなどがあればコメントお願いしたいです。

アロー関数を使う理由がまた一つ増えた。(アロー関数の方が何かと厳密な気がする)
WindowsのVSCodeで__m256d型のインデックスアクセスにenumを使うと怒られる

# TL;DR

* WindowsのC/C++拡張が入ったVSCodeで`_m256d`型の変数にenumでインデックスアクセスすると、「これらのオペランドと一致する演算子 "[]" はありません -- オペランドの型: __m256d [ enum <unnamed> ]」というエラーが表示される
* 解決するには、`.vscode/c_cpp_properties.json`の`compilerPath`をデフォルトの`/usr/bin/g++`から適切なもの、例えば`c:/MingW/bin/g++`に変える。

# 現象

こんなコードを書く。

```cpp
#include <iostream>
#include <x86intrin.h>
enum { X, Y, Z };

int main() {
  int a[] = {0.0, 1.0, 2.0, 3.0};
  std::cout << a[X] << std::endl;
  std::cout << a[Y] << std::endl;

  __m256d v = _mm256_set_pd(0.0, 1.0, 2.0, 3.0);
  std::cout << v[X] << std::endl;
  std::cout << v[Y] << std::endl;
}
```

`enum`で座標軸を表現し、それで`int a[]`や、`__m256d v`にインデックスアクセスをしている。

このうち、`int a[]`のインデックスにenumを使っても文句は言われないのだが、`__m256d v`のインデックスアクセスのところで「これらのオペランドと一致する演算子 "[]" はありません -- オペランドの型: __m256d [ enum <unnamed> ]」と文句を言われてしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/c5033f41-4fac-81b3-50c5-3cc811f1acc5.png)

しかし、WSLやMinGWのg++でコンパイルしてもそんなことは言われず、いったい誰がこのエラーを吐いているのかよくわからない。enumに明示的にint型を指定したり、`X=0`などと値を代入してもダメだった。

# 回避方法

VSCodeの右下にあるWin32をクリックして現れるメニューの「構成の編集 (JSON)」を選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/e92abb21-dbcd-65dc-88db-eac37fc580c8.png)

すると、`.vscode/c_cpp_properties.json`が編集できるので、その`compilerPath`を、別のコンパイラ、例えば`c:/MingW/bin/g++`に変える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/369d0e29-2e8e-5564-e3fa-237301992917.png)

すると、エラーが消える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/93d905df-49af-7754-9270-f1ffce563fb8.png)

# まとめ

`__m256d`にenumでインデックスアクセスするという、極めてニッチなコードにVSCodeが怒る件について対応した。結局VSCodeがデフォルトで参照する`/usr/bin/gcc`や`usr/bin/g++`の実体が何かよくわからなかったのだが(cpptools?)、いずれにせよ別のコンパイラを指定することでエラーが消えた。何しろSIMD化とかするとこの手のコードが大量に発生するのだが、VSCodeが大量のエラーで真っ赤になるのが鬱陶しかったのでなおってよかった。
jupyter notebook でコマンドを実行する方法

jupyter notebookでコマンドを実行するには先頭に`!`をつけることでできます。

```
!ls

!pwd
```

google の[colab](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)でも同じように実行できるので、画像の転送し、画像の有無など`!ls`で確認できます。
Mac OSにpyenvをHomebrewを使ってインストールしたけど、pythonのバージョンが切り替わらないときの対処法

## 問題
mac osでHomebrew(パッケージ管理ツール)を使って、pyenvをインストールし、pythonのバージョンをglobalに設定してみたけど、pythonのバージョンが切り替わらない。


```shell

$ brew install pyenv # pyenvのインストール
$ pyenv install 3.8.0 # pythonのバージョンのインストール
$ pyenv global 3.8.0 # pythonのバージョンをglobalに設定
$ python -V # バージョンを確認
2.7.7 # デフォルトのバージョンと変わらない問題

```


## 解決法
ホームディレクトリの`.bash_profile`または`.zshrc`にeval "$(pyenv init -)"を加え、`source`コマンドで適応させる

```
$ vim .zshrc
$ source .zshrc
```
mysqlclientをpip installできないときの対処法



## 環境
```
macOS Catalina 10.15.5
pipenv 2020.6.2
Homebrew 2.4.3
```

## エラー
mysqlclientをインストールしようとすると、長い長いエラーメッセージが出てきてインストールできませんでした。
※ pipenv でインストールしていますが、pipでバージョン指定ナシでも同様の現象があるようでした。
※ Catalinaにアップグレードしたら起こったという情報もありました。

```
$ pipenv install mysqlclient==1.4.6

...
ERROR: Couldn't install package: mysqlclient
```

## こうしたらいけた

mysql-connector-cをインストール

```sh
$ brew install mysql-connector-c
```

opensslのパッケージ情報を表示

```sh
$ brew info openssl

openssl@1.1: stable 1.1.1g (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
/usr/local/Cellar/openssl@1.1/1.1.1g (8,059 files, 18MB)
  Poured from bottle on 2020-05-03 at 16:19:23
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl@1.1.rb
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> /Users/あなたのホームディレクトリ/.bash_profile

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"

==> Analytics
install: 583,299 (30 days), 2,291,367 (90 days), 6,244,922 (365 days)
install-on-request: 72,656 (30 days), 337,989 (90 days), 825,813 (365 days)
build-error: 0 (30 days)
```

上記コマンドで表示される以下の3つを実行
※ 環境によって異なります.


```
  $ echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> /Users/あなたのホームディレクトリ/.bash_profile
```

```
  $ export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
```

```
  $ export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
```


## 参照
https://stackoverflow.com/questions/35190465/virtualenvpython3-4-pip-install-mysqlclient-error