OmniAICreator/Qiita-1.07M huggingface dataset:
pythonなどで書かれたファイルをsyntax highlight付きでpdf化

![Bad Request]()
# やりたいこと

`hogehoge.py`のようなソースコードを、syntax highlight付きでpdfファイルに変換

## 経緯
ずぅーっと前に使っていたa2psみたいに

```sh
% cat hogehoge.txt | a2ps | lpr -Pprinter_name
```

てな感じで、お手軽に印刷できるツールをしばらく探していました。
**が、**
これといったツールがみあたらないので、やむなく自作。

pdfファイルを無駄に作成せずにパイプを使ってプリンターに流し込むことを考えたのですが、ちょっと思いつかず。
とりあえず、pdfを出力することにしました。

# 方針

1. コマンド１つでpdfファイルを作成
2. pythonからpandocを呼び出して処理
3. コードには行番号を付加


# 私の環境

## ハードウェア & OS
1. Macbook Pro (13-inch 2019, Four Thunderbolt 3 ports)
2. 2.8GHz Quad Core Intel Core i7
3. RAM 16GB
4. macOS Catalina 10.15.4

## ソフトウェア
1. LuaLaTeX (This is LuaTeX, Version 1.10.0 (TeX Live 2019))
2. pandoc (pandoc 2.2.3.2) 
3. python (Python 3.7.7 (default, Mar 23 2020, 17:31:31))

# ちゃちゃっと作成

ソースを貼っておきます。変なことをしていたり、こうしたらもっと良いよ！
などのご意見を頂ければとおもいます。


```python:code2pdf
#!/usr/bin/env python
import sys
import os
import subprocess

if len(sys.argv) < 2:
    print('Usage: %s FILENAME' % (sys.argv[0]))
    sys.exit()

args = sys.argv
filename = sys.argv[1]
extension = filename.rsplit('.',1)

if extension[1] == 'py':
    LANG = '{.python .numberLines}'
elif extension[1] == 'sh':
    LANG = '{.sh .numberLines}'
elif extension[1] == 'html':
    LANG = '{.html .numberLines}'
elif extension[1] == 'htm':
    LANG = '{.html .numberLines}'
else:
    LANG = ''

f = open(filename)
body = f.read()
f.close()
data_out = '# ' + filename + '\n' + '```'+ LANG +'\n' + body + '\n```'

subprocess.run(['pandoc',\
                '-o',extension[0]+'.pdf',\
                '--pdf-engine=lualatex',\
                '-V', 'documentclass=bxjsarticle',\
                '-V', 'classoption=pandoc,jafont=ipaex',\
                '--highlight-style=kate',\
#                '-H', '~/local/header.tex', # プリアンブルに書き込む
                '-V', 'linestretch:0.75',\
                '-V', 'pagestyle:empty',\
                '-V', 'geometry:top=8truemm',\
                '-V', 'geometry:bottom=12truemm',\
                '-V', 'geometry:left=20truemm',\
                '-V', 'geometry:right=12truemm',\
                '-V', 'papersize=a4',\
                '-V', 'fontsize:9pt'],\
                input=data_out, text=True, encoding='UTF-8')
```
# 使い方

```bash
$ code2pdf hogehoge.py
```

# 仕上がり

上記のコードをpdfにしたものを、スクリーンキャプチャしました。

![スクリーンショット 2020-04-10 7.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191337/5b1b34b5-3275-3961-5b6c-26fbc176ab9b.png)


syntax highlightの色は、変更可能です。

現在利用可能な設定は`--list-highlight-styles`オプションで確認可能です。
私の環境での実行結果は以下のとおりです。

```sh
$ pandoc --list-highlight-styles
pygments
tango
espresso
zenburn
kate
monochrome
breezedark
haddock
```


こちらのページに、色見本があります。

[pandoc_highlight](https://github.com/kaityo256/pandoc_highlight)

あわせてご確認下さい。


# 今後の課題

1. パイプを使って、プリンターに直接流し込み
2. 読みやすくするため、フォントの設定の見直し
DB設計　正規化

#概要

正規化とはDBを設計する際に重要となってくるデータ管理の概念。

DB設計って何？正規化って何？

この記事はそういった方々に対して
また自分の備忘録でもあります。。。

##DB設計とは？

システム開発を行う上で最初にDBの設計を行っていくことで強固なDBを作ろうという理論。

まず、データベースを設計する際に重視される考え方として、

**DOA（データ中心アプローチ）がある**

DOAの考え方として、振る舞いから考えるのではなく、
システムの中で必要なデータからシステム構造を考えていく考え方である。

###なぜ、DOAを採用するべきなのか？

例えば、1000個のデータが既に商品テーブルに保存されているとします。

商品テーブルに商品番号カラムを新たに追加することになりました。

こうなると、1000個のデータを修正する必要が出てきます。

ですが、最初の時点（＝DBを設計する）で修正するのなら、
どちらが少ない労力で作業を済ませられるのかは明白です。

DB設計を行うことでシステムを開発していく上で強固かつ効率的にDBを作成することができます。

##正規化とは何？

設計段階で重複してしまう冗長なデータを排除し、データの一元的な管理を目指す理論。

重複するデータが存在することでDBを変更する必要がある場合、Aは直したのにBは直していなかったなどの不具合を発生させてしまう。

###重複するデータとは何か？

重複するデータとは複数のレコードが同じデータを持っていることを指す。

商品テーブル

| 商品名       |       仕入先 |    仕入先コード    |
|:-----------------|------------------:|------------------:|
| りんご             |              A商会 |        A001        |
| みかん           |            A商会 |       A001       |
| ぶどう            |              B商会 |        A002        |


りんごとみかんの仕入先をA商会からB商会に変更する際、現在のデータベースだと
仕入先と仕入先コードを変更する必要が出てくる。

このような状態ではA商会をB商会に変更したが、仕入先コードの変更を忘れた。
あるいは仕入先コードを変更したが、A商会をB商会に変更することを忘れた。

こういったミスが生じ、DBに矛盾が生じてしまう。

そのため、正規化でテーブルからデータの重複をなくしていく必要がある。

##正規化の段階


正規化には段階があり、
非正規形から第5正規形までの段階が存在する。

この記事では第三正規形までを取り扱います。

**非正規形とは正規化を何も行っていない段階を指す。**

前述したデータの重複を起こす危険があり、DBを管理していく上では不適切。

**第一正規形は一つのカラムに一つのデータが保存されている状態を指す**

一つのカラムに一つのデータが保存されている状態とは、一つのカラムにカンマ区切りやスペースで区切って複数の値が入っていないことを指す。

**第二正規形は完全関数従属で保存されている状態を指す**

そもそも関数従属とは何か？

関数従属とはAの値が決まると、Bの値もわかる関係性を指す。

先ほど、説明に使った商品テーブルで例えると、

| 商品名       |       仕入先 |    仕入先コード    |
|:-----------------|------------------:|------------------:|
| りんご             |              A商会 |        A001        |
| みかん           |            A商会 |       A001       |
| ぶどう            |              B商会 |        A002        |


仕入先が決まれば、仕入先コードも決まる。

この関係性を関数従属という。

そして、完全関数従属は部分関数従属が排除された状態を指す。

部分関数従属とは、キーの一部が主キーに従属した状態を指す。

|仕入伝票| 商品名|注文数|単価 |
|---------:|:--|--:|---:|
|   1        |りんご|  20| 100 |
|  2        | みかん|  100| 100 |
|   3        |ぶどう| 10| 150 |

このテーブルの主キー（レコードを特定するカラム）は仕入伝票と商品名である。

この場合、部分関数従属とは商品名カラムと単価カラムになる。

りんごとわかれば、自然と単価も決まってくるからです。

なので、第二正規形とする場合は

|仕入伝票| 商品名|注文数|
|---------:|:--|--:|
|   1        |りんご|  20|
|  2        | みかん|  100| 
|   3        |ぶどう| 10|


| 商品名|単価 |
|:--|---:|
|りんご| 100 |
| みかん| 100 |
|ぶどう|  150 |


仕入テーブルと商品テーブルを分割し、管理する形式になります。

**第三正規形は推移関数従属を排除したテーブルの状態を指す**

推移関数従属

主キー以外の属性同士で従属関係を持っている状態

|仕入伝票| 仕入先| 仕入先コード|商品名|注文数|
|---------:|:--|--:|--:|--:|
|   1        |A商店|A001|りんご|  20|
|  2        |A商店|A001| みかん|  100| 
|   3        |B商店|A002|ぶどう| 10|


仕入テーブルの主キーは仕入伝票にあたる

しかし、このテーブルでは仕入先と仕入先コードは従属性を持っている。

なので、この場合は

|仕入伝票| 仕入先|商品名|注文数|
|---------:|:--|--:|--:|
|   1        |A商店|りんご|  20|
|  2        |A商店|みかん|  100| 
|   3        |B商店|ぶどう| 10|


|仕入先| 仕入先コード|
|:--|--:|
|A商店|A001|
|B商店|A002|

このように仕入テーブルと仕入先テーブルを分割することで第三正規形となる。


#要約

テーブルの各カラムが依存することでデータの重複が発生してしまう。

そのため。正規化とは主キー以外の依存を排除している。
rails serverでサーバーを起動しようとしたら、Webpacker configuration file not foundエラーが発生した時の対処方法

# rails serverでサーバー起動しようとするとエラーが
サーバーを起動するためにコマンドを実行。

```
$ rails server
```

すると次のエラーが発生。

```
(中略)
Webpacker configuration file not found /Users/ユーザ名/app_name/config/webpacker.yml.
Please run rails webpacker:install 
Error: No such file or directory 
@ rb_sysopen - /Users/ユーザ名/app_name/config/webpacker.yml 
(RuntimeError)
```

# 解決法
最終的にwebpackerをインストールすることで成功しました。
webpackerのインストールには、Node.jsとYarnのインストールが必要で、これらをインストールした上でwebpackerをインストールすると解決します。

まずはGemfileにwebpackerの記述があるか確認。

```:Gemfile
gem 'webpacker', '~> 4.0'
```
bundle installを実行。

```
$ bundle install
```

webpackerをインストールしようとするが、Node.jsが必要だと言われる。

```
$ rails webpacker:install
sh: node: command not found
sh: nodejs: command not found
Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/
```

Node.jsをインストール。

```
$ brew install node
```

webpackerをインストールしようとするが、今度はYarnが必要だと言われる。

```
$ rails webpacker:install
Yarn not installed. 
Please download and install 
Yarn from https://yarnpkg.com/lang/en/docs/install/
```

Yarnをインストール。

```
$ sudo npm install -g yarn
added 1 package in 3.509s
```

念のためYarnのバージョンを確認。

```
$ yarn -v
1.22.4
```

>※ここでエラーが出てきた方はこちらの記事を読んでみてください。
[yarn -v でYarnのバージョンを確認しようとしたら、Error: EACCES: permission denied, open '/Users/ユーザー名/.config/yarn'と出てくる時の対処法](https://qiita.com/yokota02210301/items/293edf9e730f98fe633d)

ちゃんと出てきたので、次はwebpackerのインストール。

```
$ bundle exec rails webpacker:install

（中略）
Webpacker successfully installed 🎉 🍰
```

インストールできたので、改めてサーバーを起動。

```
$ rails s
=> Booting Puma
=> Rails 6.0.2.2 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.3 (ruby 2.6.1-p33), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
```
いけました！

</br>
</br>
</br>
</br>
</br>
---
####参考URL
Rails6でアプリ起動時にWebpacker configuration file not foundエラーが発生した時の対処方法
- https://qiita.com/hasegawa-naoto/items/a2c2900c3f4f05ee3bcb
</br>
</br>
「指定されたパスは存在しません」VMPlayer2.0が開けない場合の対処法

#XP上のVMPlayer2.0.0突然起動不能に
直接exeファイルダブルクリックしても、
同じポップアップが出る
アンインストールして、2.0.1入れ替えても同じエラー。
5.0.1はXPのスペック足りないエラーが出てしまった。
**3.1.5をインストールして、再起動、OK！**
実は何度も繰り返し削除・インストールしました。
**肝心なCentOS5が残っている、良かった！！**
ちなみに、VMPlayerの古いバージョンは下記サイトよりゲットした。
http://www.oldversion.jp/windows/vmware-player/
**以上**
yarn -v でYarnのバージョンを確認しようとしたら、Error: EACCES: permission denied, open '/Users/ユーザー名/.config/yarn'と出てくる時の対処法

# Yarnのバージョンを確認しようとしたらエラーが

バージョンの確認のため、次のコマンドを打ち込む。

```
$ yarn -v
```
すると次のエラーが発生。

```
Error: EACCES: permission denied, open '/Users/ユーザー名/.config/yarn'
    at Object.openSync (fs.js:462:3)
    at readFileSync (fs.js:364:35)
    at /usr/local/lib/node_modules/yarn/lib/cli.js:101331:58
    at Array.map (<anonymous>)
    at parseRcPaths (/usr/local/lib/node_modules/yarn/lib/cli.js:101329:78)
    at Object.findRc (/usr/local/lib/node_modules/yarn/lib/cli.js:101343:10)
    at getRcConfigForCwd (/usr/local/lib/node_modules/yarn/lib/cli.js:56915:74)
    at /usr/local/lib/node_modules/yarn/lib/cli.js:92694:56
    at Generator.next (<anonymous>)
    at step (/usr/local/lib/node_modules/yarn/lib/cli.js:310:30)
```

権限がなくて拒否されていると言われてる。

# 解決法

一旦ホームディレクトリに戻り、.configを確認してみる。

```
$ cd
$ ls -la

（上略）
drwx------   3 root  staff     96  4  8 16:42 .config
（下略）
```

現在のユーザーで.configの権限を持っていないようなので、.configフォルダの所有者を現在のユーザーに変更する。

```
$ sudo chown -R $USER ~/.config/
```

もう一度確認。

```
$ ls -la

（上略）
drwx------   3 ユーザー名  staff     96  4  8 16:42 .config
（下略）
```

rootからユーザー名に変わっているので、大丈夫そう。
アプリのフォルダに戻る。

```
$ cd /アプリのフォルダ
```

今一度Yarnのバージョンを確認。

```
$ yarn -v
1.22.4
```

ちゃんとバージョンが出てきました！

</br>
</br>
</br>
</br>
</br>
---
####参考URL
yarnでエラー
- http://shinriyo.hateblo.jp/entry/2018/02/17/yarn%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC
chown - ファイルの所有者やグループを変更 - Linuxコマンド
- https://webkaru.net/linux/chown-command/
</br>
</br>
Git commit メッセージの変更方法

# 直近のコミットメッセージの変更
```$ git commit --amend -m "変更したいメッセージ"```
だけ。簡単！
# nつ前のコミットメッセージの変更
```$ git rebase -i HEAD~n```
を入力する。
例えば、2つ前のコミットメッセージを変更したい場合は、
```$ git rebase -i HEAD~2```
と入力する。

するとvimエディタが開かれる。
## vimでの操作
### INSERTモードに切り替える
キーボードの```i```キーを入力する。
そうすると、INSERTモード(入力モード)に切り替わる。
### コミットをeditに書き替える
修正したいコミットメッセージの```pick```を```edit```に変更する
### コマンドモードに切り替える
キーボードの```esc```キーを押す。
そうすると、コマンドモードに戻る。
### ファイルを上書き保存し、vimを終了する
キーボードの
```:``` と ```w``` と ```enter```で上書き保存
```:``` と ```q``` と ```enter```でvimエディタを終了する。

## タイムリープして歴史を書き換える
vimを終了した時点で、先ほどeditを指定したコミットのファイルの状況が、コミット完了する直前まで戻っている。
もし、このコミットでの作業ファイルを修正・変更したい場合は、この時点で修正・変更可能。

### Git commitメッセージの変更
```$ git commit --amend -m "変更したいメッセージ"```

これでコミットメッセージが入力したメッセージに変更される。

### 現代に戻る
```$ git rebase --continue```
を入力。

これで、歴史は書き換えられた。
エル・プサイ・コングルゥ（特に意味はない）。

# 参考(というよりほぼ引用)
[Gitのコミットメッセージを後から変更する方法をわかりやすく書いてみた](https://www.granfairs.com/blog/staff/git-commit-fix)
こちらのサイト様の方が図付きでわかりやすいです。
Ruby on Railsのチュートリアル ~第3章ほぼ静的なページの作成~

# はじめに
webアプリケーションを作るための学習記録
（マッチングアプリを作る予定）

こちらのチュートリアルを片っ端から進めていく
【Ruby on Rails チュートリアル】
https://railstutorial.jp/

# 第3章ほぼ静的なページの作成
## まとめ
- 新しいRailsアプリケーションをゼロから作成したのはこれで3度目。今回も必要なgemのインストール、リモートリポジトリへのプッシュ、production環境まで行った
- コントローラを新規作成するためのrailsコマンドはrails generate controller ControllerName アクション名 (省略可)。
- 新しいルーティングはconfig/routes.rbファイルで定義する
- Railsのビューでは、静的HTMLの他にERB (埋め込みRuby: Embedded RuBy) が使える
- 常に自動化テストを使って新機能開発を進めることで、自信を持ってリファクタリングできるようになり、回帰バグも素早くキャッチできるようになる
- テスト駆動開発では「red ・ green ・REFACTOR」サイクルを繰り返す
- Railsのレイアウトでは、アプリケーションのページの共通部分をテンプレートに置くことでコードの重複を解決することができる

## 所感
- 途中でいちいちgitコマンドめんどくさくなったのでシェルスクリプト作った


```bash.easy_push.sh
COMMIT_MESSAGE="commit `date +"%Y/%m/%d %H:%M:%S"`"
git add -A
git commit -am "${COMMIT_MESSAGE}"
git push heroku
```
```
bash /home/ec2-user/environment/sample_app/easy_push.sh
```

- キャメルケースとか、コードの臭いとか、っていう特有の言語、概念、言い回しみたいなの楽しい

- テスト駆動開発ってプロダクトの規模が大きくなったらどうなるんだろう。今はタイトルだけ表示有無をテストしてるけど、他の表示内容全てテストするコード書くのが一般的なのだろうか・・・



## 途中参考にしたページ
- 命名規則「キャメルケース」「スネークケース」「ケバブケース」についてまとめてみました
https://designsupply-web.com/developmentlab/4052/

- テスト駆動開発（TDD）とは？TDDの進め方をステップ毎に解説！
https://www.valtes.co.jp/qbookplus/1069

- コードの臭い
https://ja.wikipedia.org/wiki/コードの臭い


## 使用したコマンド
rails _5.1.6_ new sample_app
bundle install --without production
bundle update
git init
git add -A
git commit -m "Initialize repository"
git status
git add -A
git commit -am "Improve README"
git remote add origin git@github.com:アカウント名/リポジトリ名.git
git push -u origin master

git status
git add -A
git commit -am "Add hello"
heroku create リポジトリ名
git push heroku master

git checkout -b static-pages
git branch

rails generate controller StaticPages home help
git add -A
git commit -m "Add a Static Pages controller"
git push -u origin static-pages

rails generate controller StaticPages home help
rails destroy  controller StaticPages home help

rails generate model User name:string email:string
rails destroy model User

rails db:migrate
rails db:rollback
rails db:migrate VERSION=0

rails test
rails t
touch app/views/static_pages/about.html.erb
mv app/views/layouts/application.html.erb layout_file
mv layout_file app/views/layouts/application.html.erb
rails t

git checkout master
git merge static-pages
git push
rails test
git push heroku

cd ~/sample_app
bundle exec guard init
sudo yum install -y tmux

ps aux
ps aux | grep spring
kill -15 12241
spring stop
pkill -15 -f spring

bundle exec guard
git add -A
git commit -m "Complete advanced setup"
Pythonで毎日AtCoder #30

### はじめに
[前回](https://qiita.com/taxfree_python/items/a38c88be705e62ab7b47)
おすすめの問題があったらコメントやtwitterでリプ飛して欲しいです。
今日で30日です。

### #30
[ABC154-D](https://atcoder.jp/contests/abc154/tasks/abc154_d)

**考えたこと**
素直に連続する$K$個のサイコロの期待値を計算するとTLEしてしまいました。PyPyで提出してもTLEしたので解説を読みました。
累積和を使えば計算量を減らせるのTLEしません。期待値は$\frac{1}{2}(p[i]+1)$で計算することができます。累積和はnumpyを用いて実装します。numpy大好き

```python
import numpy as np
n, k = map(int,input().split())
p = list(map(int,input().split()))

e = [(i+1)/2 for i in p]
e = np.cumsum(e)
e = np.append(0,e)
ans = 0
for i in range(n-k+1):
    ans = max(e[i+k]-e[i],ans)
print(ans)
```
[累積和の詳しい解説](https://qiita.com/drken/items/56a6b68edef8fc605821)

[ABC126-C](https://atcoder.jp/contests/abc126/tasks/abc126_c)

**考えたこと**
for文でサイコロの目ごとに期待値を計算します。もしサイコロの目がK以下ならコイントスします。コイントスする回数をwhileで計算して、$\frac{1}{2}$をカウント乗します。

```python
n, k = map(int,input().split())

ans = 0
for i in range(1,n+1):
    count = 0
    if i < k:
        while i < k:
            i *= 2
            count += 1
    ans += 1/n * (1/2)**count
print(ans)
```

### まとめ
確率とか期待値の問題は苦手なので、数Aの復習しないといけない。ではまた、おやすみなさい。
【学習記録】『HTTPの教科書』第３章〜第５章　読書メモ　〜N予備校の復習を添えて〜

【学習記録】『HTTPの教科書』第２章　読書メモ　〜N予備校の復習を添えて〜( https://qiita.com/Molly95554907/items/284dbc8ebb5c10b10021 )の続き

<h5>第３章</h5>
HTTPでやりとりする情報＝HTTPメッセージと呼ばれる

●HTTPメッセージの構成
・メッセージヘッダ
　　サーバーやクライアントが処理すべき、リクエストやレスポンスが書かれる
・メッセージボディ
　　転送されるべきデータそのもの

●エンコーディング
HTTPデータを転送の際にエンコードすると、転送効率があがる。
エンコーディングという処理をコンピューターで行うため、CPUのリソースはより多く消費する

圧縮して送る、分解して送る、などのエンコーディング処理がある。


<h5>第４章</h5>
HTTPステータスコード

●２００番台
成功！
リクエストが正常に処理された

200 OK:正常処理

204:リクエストは成功したけど返すリソースは無い
206:リクエストは成功したけど返すリソースは一部しか無い

<h6>N予備校　第３章１４項</h6>
```js

'use strict';
const http = require('http');
const server = http.createServer((req, res) => {
  const now = new Date();
  console.info('[' + now + '] Requested by ' + req.connection.remoteAddress);
  res.writeHead(200, {
    'Content-Type': 'text/html; charset=utf-8'
  });
```

nowという変数で定義した中には、「ヘッダに２００を返す」という処理。これは、リクエストは正常に処理されたと示すもの。


●３００番台
リダイレクト
ブラウザ側で何か処理したらリクエストが正常に終了できる

●400番台
クライアントエラー
クライアントが原因でエラーが発生している。

400:Bad Request　リクエストの構文が間違っている
404:Not Found　リクエストしたリソースはサーバーに無い or サーバー側がそのリクエストを拒否したい

<h6>N予備校　第4章2１項</h6>
```js

if (schedule && isMine(req, schedule)) {
      if (parseInt(req.query.edit) === 1) {
        const updatedAt = new Date();
        schedule.update({
          scheduleId: schedule.scheduleId,
          scheduleName: req.body.scheduleName.slice(0, 255) || '（名称未設定）',
          memo: req.body.memo,
          createdBy: req.user.id,
          updatedAt: updatedAt
        }).then((schedule) => {
          // 追加されているかチェック
          const candidateNames = parseCandidateNames(req);
          if (candidateNames) {
            createCandidatesAndRedirect(candidateNames, schedule.scheduleId, res);
          } else {
            res.redirect('/schedules/' + schedule.scheduleId);
          }
        });
      } else {
        const err = new Error('不正なリクエストです');　
        err.status = 400;
        next(err);
      }
    } else {
      const err = new Error('指定された予定がない、または、編集する権限がありません');
      err.status = 404;
      next(err);

    
```
・追加したい候補が存在しない→４00番を返す
・予定が見つからない場合や自分自身の予定ではない場合→404番を返す

●５００番台
サーバーエラー
サーバーが原因でエラーが発生している

<h5>第５章</h5>
●バーチャルホスト
１台で複数ドメインを実現することができる。バーチャルホストを使う。バーチャルソフトを使うと、物理的にはサーバーが一台でも、複数台あるように扱える。

同じIPアドレスで、異なるホスト名やドメイン名を持った複数のウェブサイトを稼働させられる。

●プロキシ
サーバーとクライアントの両方の役割を果たす中継プログラム。
クライアントからのリクエストをサーバーへ送る。
サーバーからのレスポンスをクライアントへ送る。

プロキシが転送することによって、キャッシュを使ったネットワークを効率化できる。webサイトへのアクセスポリシーを遵守させられる。


●ゲートウェイ
ゲートウェイの先にあるサーバーが、HTTPサーバー以外のサービスを提供するサーバーとなる。
クライアントとゲートウェイ間を暗号化することで、通信の安全性を高める。


●キャッシュ
プロキシサーバーや、クライアントのローカルディスクに保存されたリソースのコピー。キャッシュはwebページの情報を保存している。クライアントは何度も同じ情報をリクエストしなくていいので処理が早くなる


＜疑問＞
Cookieとの違いは？
↓
キャッシュはWebページの情報
Cookieはユーザーの情報
を保存している。


<h6>●課題</h6>
結局サーバーって何？物理的にどのような形をしているのか。ローカルホストといえば、サーバー室にあるパソコンが思い浮かぶけど、ネットワーク上にあるサーバーと言われるとイメージがつかない・・・
Vagrantでタイムゾーン設定(CentOS/Debian/Ubuntu)

# TL;DR

[Vagrantfile](https://qiita.com/hkato/items/3437652a38462c670d0a#完成)の例

# 動機

[Packer](https://packer.io)を使い、プロビジョニングに[Ansible](https://www.ansible.com)を使ってVMイメージを作成してみたが、必ずしもそのイメージは自分や日本サイドだけが使うものでなくオフショア開発メンバーにも利用してもらいたいのでタイムゾーン設定は埋め込みたくない。ここだけ外だしにし環境により変更したいなぁと言うのが動機。

# 方法

事前にPacker+Ansible(ここでは触れない)でboxがビルドされてるとして、その先、タイムゾーン設定は動的に行う。
この記事では例示用に[Vagrant Cloud](https://app.vagrantup.com/)にあるboxをそのまま利用する。当然世界中の人たちが利用するものだからUTCで作られたCentOS7, Debian, Ubuntu の公式イメージを利用。

## timedatectl コマンド

Red Hat Enterprise Linux > 7 > システム管理者のガイド > [第3章 日付と時刻の設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-configuring_the_date_and_time)
> timedatectl ユーティリティーは、systemd システムおよびサービスマネージャーの一部として配布されており、システムクロック設定を確認および変更できます。このツールを使用すると、現在の日付および時間の変更、タイムゾーンの設定、リモートサーバーとシステムクロックとの自動同期の有効化が可能になります。

こちらは、Red Hat系/Debian系などSystemdを利用した最近のディストリビューションなら利用可能。いくつかのQiitaなどの記事には`/etc/timezone`を手で変更する手法があるが、今はこちらの利用が良いのではないだろうか？(あくまでもベアメタルやVMでの話、Dockerの場合は通常は変更しない？よね)

```sh
$ sudo timedatectl set-timezone Asia/Tokyo
```

## Vagrant Shell Provisioner

[Shell Provisioner](https://www.vagrantup.com/docs/provisioning/shell.html)

とりあえず、inlineで一行追加で固定でタイムゾーンの設定はできる。

```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.provision "shell", inline: "timedatectl set-timezone Asia/Tokyo"
end
```

このままだとVagrantfileを書き換えてもらう必要あり。

## Rubyでのタイムゾーンの扱い

Vagrantfile自体はRubyなのでホストOSの現在のタイムゾーンを取得する方法がないか？残念ながら`Time.now.zone`では`JST`,`PDT`,`IST`などは取得できるが`Asia/Tokyo`の様な形式では取得できない(RailsのActiveSupportなら扱えそうだが…)。

## 環境変数から

シェル環境ではタイムゾーンの環境変数として`TZ`が利用される。

```sh
$ date
2020年 4月 8日 水曜日 21時54分13秒 JST
$ TZ="UTC" date
2020年 4月 8日 水曜日 12時54分19秒 UTC
$ TZ="America/Los_Angeles" date
2020年 4月 8日 水曜日 05時54分24秒 PDT
```

この値をRubyから利用する。TZ環境変数がない場合として`UTC`にするため三項演算子で、

```sh
$ TZ="Asia/Tokyo" ruby -e 'p ENV["TZ"] ? ENV["TZ"] : "UTC"'
"Asia/Tokyo"
$ ruby -e 'p ENV["TZ"] ? ENV["TZ"] : "UTC"'
"UTC"
```

# 完成

これらを組み合わせて出来上がったVagrantfileがこちら

```ruby
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  #config.vm.box = "debian/buster64"
  #config.vm.box = "ubuntu/bionic64"
  config.vm.provision "shell" do |sh|
    timezone = ENV['TZ'] ? ENV['TZ'] : "UTC"
    sh.inline = "timedatectl set-timezone $1"
    sh.args = timezone
  end
end
```

実際に利用すると、

```sh
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos/7'...
...
...
==> default: Running provisioner: shell...
    default: Running: inline script
$ vagrant ssh
[vagrant@localhost ~]$ date
Wed Apr  8 13:10:42 UTC 2020
[vagrant@localhost ~]$ exit
```
```
$ TZ="Asia/Tokyo" vagrant provision
==> default: Running provisioner: shell...
    default: Running: inline script
$ vagrant ssh
Last login: Wed Apr  8 22:10:40 2020 from 10.0.2.2
[vagrant@localhost ~]$ date
Wed Apr  8 22:11:31 JST 2020
```

`TZ`環境変数を恒久的に設定するなら`.bash_profile`などでexportしておけば、ホストOSとゲストOSで同じタイムゾーンになる。
初心者のKubernetes入門（書籍 Kubernetes 実践入門の写経から学ぶ）Label 編

# 背景
個人的にインフラの知識以上にこれからのアプリケーションが動く環境を作ってデプロイしたりしてこれからの知識を身に着けたい。そしてより一層、自分の知識のアップデートをしたいと思いました。

その中でこの本に出会い、これから少しずつやったことを残し、未来の自分への手紙としてもあり、見つめ直せればと思いました。

# 引用や参考と今回の自分の勉強用の書籍の紹介
[技術評論社『Kubernetes実践入門』のサンプルコード](https://github.com/kubernetes-practical-guide/examples)
[Kubernetes実践入門 プロダクションレディなコンテナ＆アプリケーションの作り方](https://gihyo.jp/book/2019/978-4-297-10438-2)
![](http://image.gihyo.co.jp/assets/images/cover/2019/9784297104382.jpg)


# 実際の学びについて

書籍を読みながら、章ごとに少しずつ進めていきたいと思います。
GitHub のソースコードも使いながら学んで行きたいと思います。

## 勉強開始

ここから Label と Labelセレクタとかを学んでいきます。

- https://github.com/kubernetes-practical-guide/examples/tree/master/ch1.3.3

```yaml:my-pod.yaml
apiVersion: v1
kind: Pod
metadata: # 全てのオブジェクトが共通で持つメタ情報 (1)
  name: my-pod
  namespace: my-namespace
  labels: # Labelの設定 (2)
    environment: production
    release: canary
spec:
  containers: # Podに含むコンテナのリスト (1)
  - name: nginx # コンテナの名前
    image: k8spracticalguide/nginx:1.15.5 # コンテナイメージ
    ports:
    - containerPort: 80
```

```yaml:my-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations: # Annotationの設定 (2)
    prometheus.io/scrape: "true"
    prometheus.io/path: "/metrics"
    prometheus.io/port: "9102"
spec:
  selector:
    app: my-app
  ports:
  - port: 8080
    targetPort: 80
```

### コマンド郡

## Pod のマニュフェストファイルを適用する
```
$ kubectl apply -f my-pod.yaml
```

### namespace を指定して Pod 検索 
```
$ kubectl get pods --namespace=my-namespace
NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          13m
```

### environment ラベルを指定して検索
```
$ kubectl get pods -l environment=production --namespace=my-namespace
NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          11m
```

### environment ラベルを指定して検索（否定したとき）

```
$ kubectl get pods -l environment!=production --namespace=my-namespace
No resources found.
```

### environment ラベルを等価以外で検索
```
$ kubectl get pods -l 'environment in (production)' --namespace=my-namespace
NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          12m
```
> シングルクオート（’）で指定しないといけないっぽい・・・
[Chrome] html/webページで、見えてる範囲だけでなく下まで全部キャプチャする

**もくじ**
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f

# やりたいこと
webページやhtmlの説明資料やユーザーマニュアルを作成している時に、1画面で見えている範囲ではなくページ全体をキャプチャしたいときがある。

これまで1ページで見える範囲をキャプチャして、それを何回も繰り返してつなぎ合わせていたが、それが面倒かつちょっとずれたりして汚いので、全部がキャプチャできる方法があればうれしい。

# やり方
ブラウザ「**google chrome**」の機能の「**Capture full screenshot**」を使う。

- まず、全体をキャプチャしたいページを開く。  
ここでは、下記のページを試しに使う。  
https://qiita.com/tera1707/items/4fda73d86eded283ec4f  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/bae65f11-de64-e996-6b0b-f68c1dd23310.png)
　1画面で見えるのは上記くらい。

- 次に、「**Ctrl+Shift+I**」を押して、chromeのデベロッパーツールを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/1cf89cbb-2712-a848-f803-16b7ddfbf2e5.png)
　こんな感じになる。

- 次に、「**Ctrl+Shift+P**」を押して、詳細機能の入力プロンプトを呼び出し、「**Capture full size screenshot**」と入力し、enterを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/2c2f1430-b8a2-7301-72dd-fcb380f06014.png)
　※「full」と入れたら、候補表示で出てくる。

これで、全体をキャプチャした画像(png)がダウンロードされてくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/598695c4-d9b1-7a97-1133-f661ee693c60.png)

# 参考
ChromeでWEBページ全体をフルスクリーンショット！見ているページの全画面キャプチャー画像をダウンロードする方法
https://requlog.com/self-branding/blog/chrome-full-screen-capture/

クロームだけでなく、firefoxでも同様のことができるらしい
https://requlog.com/self-branding/blog/firefox-full-screen-capture/
Pythonでの共有メモリの実現方法(mmap.mmap)

#1 目的

Pythonコードを実施中に、コード内部の変数を外部からアクセスすることで変更したい。

#2 内容

Pythonコードを実行中に変数aを外部からアクセスし変更したい。下記のように、常にテキストファイル「TEST.txt」の内容を変数aに格納するコード(test1.py)を考える。ここでtest1.pyを実行中にTEST.txtの中身を変更したとしても、test1.py中の変数aの値は更新されない。(変更前のTEST.txtの値のままになってしまう)


![54.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/eaef86ae-254e-a7a7-5837-b2b644677fac.jpeg)

#3 どのようにすればいいか

TEST.txtの内容をメモリに読み出す。test1.pyとtest2.pyはメモリを共有する。test1.pyは変数aにメモリの値を読み出している。test2.pyはメモリの値を変更する。test1.pyを実行すると常にメモリから値を読み取り変数aに格納する。test2.pyを実行すると、メモリの値が変更され、test1.pyはtest2.pyで更新された値を読み出す。

![55.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/45426270-7b54-fc43-e96c-3bc4cf856d6a.jpeg)

![56.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/ae6f3505-aa1c-5f30-267d-5584cc825d83.jpeg)

#4 コード

上記の動作を実現するコードを下記に載せます。
mmap.mmapを使います -> 読み込んだファイルの内容をメモリに格納することができます。

先にtest1.pyを動作させたあとにtest2.pyを駆動してください。

```python:/test1.py

import mmap
with open("example.txt", "r+b") as f:
       #mmap.mmap(fileno, length[, tagname[, access[, offset]]])  指定されたファイルから length バイトをマップする。 
       #length が 0 の場合、マップの最大の長さは現在のファイルサイズになります。
    mm = mmap.mmap(f.fileno(), 0) #ファイルの内容を読み出しmmに書き込む。mmはbitの列"01010101..." //mmap.mmap(fileno, length[, tagname[, access[, offset]]])
    while True:
        mm.seek(0) #メモリmmを頭から読み出し(seek(0))、読み出した値をmmに格納する。
        mode=mm.readline() #メモリmmの内容を変数modeに書き出す。
        print(mode)
```

```python:/test2.py
import mmap

with open("example.txt", "r+b") as f:
#ファイルの内容を読み出しmmに書き込む。mmはbitの列"01010101..."
    mm = mmap.mmap(f.fileno(), 0)  
#メモリmmをb"01"に書き換える。example.txtのデータの長さが2なので書き込むデータの長さも2で指定する。example.txtのデータと違う長さのデータは書き込みできません。
    mm[:] = b"01"  

```

```text:/example.txt
#データは2進数表記してください。メモリに書き込むため
00
```
ssh-agentを使ってgithubへssh接続する

# 経緯
- githubへssh接続をしよう
- パスフレーズの入力がめんどくさい！
- ssh-agent使えばパスフレーズの省略ができるだと...！？

# SSH接続
(githubへの公開鍵の登録は既にすんでいる前提で進めます)
## パスフレーズ無しの場合
パスフレーズが設定されていない場合、sshコマンドを叩くだけで接続できます。

```
-> % ssh git@github.com
PTY allocation request failed on channel 0
Hi xxxx! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
```

## パスフレーズありの場合
パスフレーズが設定されている場合、sshコマンドを叩いたあとにパスフレーズの入力を求められます。もちろん**pullやpushの度に入力**をしなければいけません。

```
-> % ssh git@github.com
Enter passphrase for key '/Users/{username}/.ssh/id_rsa':
```

# ssh-agentの導入
pullやpushの度に長いパスフレーズの入力を求められるのでは生産性が落ちます。そこで登場するのが`ssh-agent`です。
ssh-agentは、秘密鍵とそのパスフレーズを登録しておくことで、必要な時に必要な秘密鍵を復号化して渡してくれるプログラムです。つまり、ssh-agentへ秘密鍵を登録すると、プロセスが生きている間はパスフレーズ無しでssh接続ができるようになります(macの場合は、後述するようにキーチェーンを利用することで永続的にパスフレーズなしで接続することもできます)。

ssh-agentへの登録は`ssh-add`コマンドを利用します。すると、パスフレーズの入力を求められます。

```
-> % ssh-add ~/.ssh/id_rsa
Enter passphrase for /Users/{username}/.ssh/id_rsa:
Identity added: /Users/{username}/.ssh/id_rsa
```
この状態でgithubへ接続すると...

```
-> % ssh git@github.com
PTY allocation request failed on channel 0
Hi xxxx! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
```
無事パスフレーズ無しでgithubへ接続できました！

# おまけ
上記の方法だとssh-agentのプロセスが死ぬと登録されている鍵情報も消えてしまいます。つまり、パソコンを再起動してしまうと、ssh-agentへ登録した鍵情報が消えてしまうということです。
試しにssh-agentをkillしてからssh接続を試みると、再びパスフレーズの入力を促されます。

```
> % ps -x | grep ssh-agent
 1330 ??         0:00.01 /usr/bin/ssh-agent -l
 1437 ttys000    0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox ssh-agent

-> % kill 1330

-> % ssh git@github.com
Enter passphrase for key '/Users/{username}/.ssh/id_rsa':
```
これはこれで、セキュリティ上望ましいのですが、やはりめんどくさい。と、思った方。macであれば鍵情報をキーチェーンへ保存しておくことができます。
やり方は、ssh-addする時に`-K`オプションを指定するだけです。ssh-agentのプロセスが死んでしまった時はssh-addへ`-A`オプションを渡すことでキーチェーンから鍵情報を復元できます。

```
-> % ssh-add -K ~/.ssh/id_rsa
Enter passphrase for /Users/{username}/.ssh/id_rsa:
Identity added: /Users/{username}/.ssh/id_rsa

-> % ssh-add -A
Identity added: /Users/{username}/.ssh/id_rsa
```
また、`~/.ssh/config`へ次のような設定を記しておくことで、キーチェーンへの登録、復元という作業を自動化することもできます！

```~/.ssh/config
Host *
  AddKeysToAgent yes
  UseKeychain yes
```
(2)-4 カメラ回転実験 Input.GetAxis("Mouse X")("Mouse Y")

#Input.GetAxisの("Mouse X")と("Mouse Y")が具体的にどういうものなのかをググったけど、当たり前過ぎて？良い記事が見つけられなかったので実験してみる。

###イメージ
マウスで取得される値は、こんな感じで変わるはず。
![名称未設定 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/90f107b6-2be2-0344-99f9-04281ab54b03.jpeg)

```csharp
    void Update()
    {
            //もしも、右クリック押し中だったら
            if (Input.GetMouseButton(0))
            {
                //"Mouse X"の移動量を変数rotX変数に封じ込める
                float rotX = Input.GetAxis("Mouse X");
                //"Mouse X"の値を「x」座標に代入
                transform.Rotate(rotX, 0.0f , 0.0f);
                Debug.Log(rotX);
            }
    }
```

![名称未設定-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/0af5c99f-5b43-73b0-8c88-68045acc67c9.gif)


むむむ？
左はマイナスで右はプラスだけど
左右に動かすと上下に動くぞ

左右に動かすと、、、マウスのｘ方向（左右）を取得してるのは間違えなさそう
上下に動かしているこの文章を


```csharp
transform.Rotate(rotX, 0.0f , 0.0f);
```

こうなんやろーな

```csharp
transform.Rotate(0.0f, rotX , 0.0f);
```

![名称未設定-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/53a57527-4d04-e282-0eda-4953252be26a.gif)

####Input.GetAxis("Mouse X")で取得したマウスの値は、transform.RotateXY入れ替える。これ重要。。

ちなみに、yも同じことをすると、、、


```csharp
    void Update()
    {
            //もしも、右クリック押し中だったら
            if (Input.GetMouseButton(0))
            {
                float rotY = Input.GetAxis("Mouse Y");
                //"Mouse X"の値を「x」座標に代入
                transform.Rotate(rotY, 0.0f , 0.0f);
            }
    }
```

![名称未設定-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/d19aed2e-6f00-1b70-19e8-f6c466bcf4ef.gif)

いい感じです。
両方、xとyを合体してもいい感じでした。

```csharp
    void Update()
    {
            if (Input.GetMouseButton(0))
            {
                float rotX = Input.GetAxis("Mouse X");
                float rotY = Input.GetAxis("Mouse Y");
                transform.Rotate(rotY, rotX, 0.0f);
            }
    }
```

![名称未設定-5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/35ee2c28-29c4-6c54-8bc7-a893cb4925db.gif)




###まとめ（何を覚えたか？）
・マウスの取得イメージ図は、なんとなく正しかった。
・Input.GetAxis("Mouse X")で取得したマウスの値は、transform.Rotateでxyを入れ替える。
・Update関数で毎回更新で使う。start関数などでは難し。
・動きが早くなりがちなので、変数をかけてあげて使う方がよさそう。
・Windowsでgifを作るのはめんどくさい。
JSのDOMクエリ(XPath, CSSSelector)で、正規表現を使いたい

XPath, CSSSelectorで、DOMをクエリする場合に、クラス名やコンテンツの文字列で検索したい場合が多い。

```js
// xpath
document.evaluate('//dom[ contains(@class, "abc") ]', this, null, 
                  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// css-selector
document.querySelector('a[class*="abc"]');
```

単純なクエリでは問題ないが、正規表現が使えると、圧倒的にクエリの表現力が上がる。

`rexpath`を使うと、XPath, CSSSelectorと正規表現を協調させられる。

```js
/* classが /tr-item\d+_.+/i にマッチする aタグ を取り出す */

// xpath
document.rexpath(['and', '//a', ['@~', 'class', /tr-item\d+_.+/i]]);
// switch to use css-selector
rexpath.use_css_selector();
// css-slector
document.rexpath(['and', 'a', ['@~', 'class', /tr-item\d+_.+/i]]);
```

## やるべきことは手短に

独自のクエリ言語を開発するとか、XPath2.0をwebアセンブリで実現するとか、
まあいろいろやり方があるんだろうけれど。

極力省エネで、合理的に、直交する解決策を考えて実装した。
まあそこそこ便利だったので、記しておく。

## どうするか

拙作のnpmライブラリ、[rexpath](https://www.npmjs.com/package/rexpath) を使う。

https://www.npmjs.com/package/rexpath

既存のXPath, CSSSelector, RegExp を薄くラップしたクエリ言語を定義することで、
最小限のエネルギーでDOMクエリと正規表現を協調させることができる。

クエリを`継続渡し`形式のクロージャにコンパイルすることでバックトラック探索を実現している。

特別なレクサはない。JavaScriptの配列を基本として簡単なクエリ言語を実現している。

## Hello World

chrome devtools consoleなどで、

```js
// jump to qiita
document.location.href = "https://qiita.com";

// unpkgからrexpathをロードする。
var element_script = document.createElement('script');
element_script.src = 'https://unpkg.com/rexpath';
document.head.appendChild(element_script);

// テキトーな例。 class属性が正規表現 /tr-item_.+/i にマッチするaタグを見つけ出して削除する。
var links = document.rexpath_all(['and', '//a', ['@~', 'class', /tr-item_.+/i]]);
links.forEach(link=>link.parentElement.removeChild(link));
```

## 詳細

文法、例など、まだ未整備だが書いてある。

[README.md](https://github.com/fgatherlet/rexpath) を参照のこと。
ローカル環境でSonarqubeを動かすまで

# はじめに
静的解析ツールのSonarQubeをローカルのDocker上で起動させて解析を行うまでの手順となります。

# 前提
DockerとDocker Composeがインストール済みとなります。

# docker-compose.ymlの設定と起動
GitHubに置いてある公式のdocker-compose.ymlをそのまま使用いたします。
https://github.com/SonarSource/docker-sonarqube

docker-compose.ymlが設定してあるディレクトリまで移動してDockerを起動。

```
$ docker-compose up -d
Creating network "sonar_sonarnet" with driver "bridge"
Creating sonar_db_1 ... done
Creating sonar_sonarqube_1 ... done
```

設定を変更していなければ `http://localhost:9000` でSonarQubeが立ち上がります。

# 日本語化
SonarQube自体が英語のため、プラグインを入れて日本語化いたします。
ログインID/PWは初期値がadminとなります。

「setting」の「Marketplace」からJapanese Packをインストールすることで日本語化になります。

<img width="935" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479673/d2896df2-a129-9054-eb0e-99938cf518b4.png">

# 解析実施
解析に必要なsonar-scannerを公式からインストールいたします。
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/

インストール後は解析を行いたいディレクトリで下記コマンドを実施する。

```
$ sonar-scanner -Dsonar.projectKey=myproject -Dsonar.sources=x
```

コマンドを実行すると、自動的に `http://localhost:9000` に結果がアップロードされます。

<img width="590" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479673/8bfa95f1-cc31-9413-dba2-d2851ea7341d.png">
[ Mac OS ] rails installでLibrary not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)が出た時の対処法

#rails installを叩くとエラーが...
railsをインストールしようとコマンドを叩く。

```
$ rails install
```

すると次のエラーが出る。

```
Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
  Referenced from: /usr/local/opt/mysql@5.6/lib/libmysqlclient.18.dylib
  Reason: image not found - /Users/~~/~~/~~/vendor/bundle/ruby/2.5.0/gems/mysql2-0.4.10/lib/mysql2/mysql2.bundle
```

ググって調べて見ると、opensslを再インストールするとか、リンクするとか、rubyを再インストールするとか書いてあった。
しかし、それを試してもうまくいかず。。

# 解決法
私がやったのはとりあえずopensslを再インストール。

```
$ brew install openssl
```
バージョンを確認。

```
$ openssl version
OpenSSL 1.0.2s  28 May 2019
```

opensslのバージョンを切り替え。

```
$ brew switch openssl 1.0.2s
```

rails installを叩く。

```
$ rails install
```

これでいけました！
<br/>
<br/>
<br/>
---
####参考リンク
Railsの環境構築時にLibrary not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)で苦しんだ
- https://qiita.com/yamazaki8934/items/48e65850873f3ecbee26
<br/>
【Flutter】SEをワンショット再生する

# 概要
`audiofileplayer`というパッケージを使い、簡潔に書くことができる

```dart
Audio.load('assets/foo.wav')..play()..dispose();
```

# 手順
## 1. `audiofileplayer`をpubspec.yamlに追加

下記のように追加

```yaml
dependences:
  flutter:
    sdk: flutter
  audiofileplayer:
```

## 2. オーディオファイルを準備

pubspec.yamlに音声ファイルのパスを記述する。場所は`dependences:`ではないことに注意
また、ファイルを一括で読み込む場合はそのファイルを直接含むディレクトリのパスを記述し、最後に`/`を付ける必要がある

```yaml

# ページ下部のflutter:が最上位となっている場所！

flutter:
  #...
  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg
  assets:
    - assets/foo.wav #パスを記述
    - assets/audio/ #複数のファイルを一括で読み込む場合はディレクトリパスの最後に'/'を付ける

```


## 3. 実行する
再生したい場所にこのように書くことで再生することができる

```dart
Audio.load('assets/foo.wav')..play()..dispose();
```


# 最後に
SEをワンショット再生したいだけなとき、何かと再生するまで色々しないといけないことが多いですが、このパッケージ使えば「一行」で済むのですごい楽でした(２つ連なるカスケード記法を一行で書くことにはいろいろ意見がありそうですが）

この記事はワンショット再生について書いているので、あまり詳しくは書きませんでしたが、このパッケージ楽曲再生はもちろんのこと再生中や終了後の処理、再生位置取得、バックグラウンド、ローカルではない場所の楽曲再生など、通常のオーディオパッケージが持つ機能も持っています。(下記、参考文献のリンクから見れます）なので、SE再生用としていれたけど、BGMも欲しくなった時でも十分対応できるかと思います。

なにか誤記等ございましたら、お気軽にお申し付けくださいませ。


# 参考文献
[audiofileplayer | Flutter Package - Dart packages](https://pub.dev/packages/audiofileplayer)
あつ森のバルーン出現タイミング(5n-1)をcronでお知らせする

# はじめに

この記事はcrontab, cronについてあまりご存知ない方で「あつ森のさくらレシピがなかなか集まらないんだけど、、？？」と感じている方向けの記事です。crontab, cronについてご存知の方にとっては当たり前のことを書いています。

# 動機
Switchの「あつまれどうぶつの森」(以下あつ森)をプレイする中で、バルーンから入手できる期間限定のDIYレシピがこのままのペースだと全種類揃わないことに気づきました。
調べてみると `5n-1法` と呼ばれるバルーンの出現タイミングに合わせてバルーン遭遇率を最大化する手法がありました。

### 5n-1法とは
```
風船は建物中に入るとリセットされ、外に出ると[5分，10分…55分]に風船が生成されます。
つまり、最初は建物の中にいて、風船が生成される1分前[4分，9分…59分]に外に出れば、いい感じに風船と出会える。
```
引用元: https://yuushablog.info/atsumori-balloon/

上記を実現するために、毎時4分,9分…59分にお知らせをしてくれる機能が必要でした。
### そうだ、cronを使おう！！


# 手順

1. Terminalを開く。
2. 下記コマンドでcrontabを編集する。

```
crontab -e
```
3. `i` でInsertモードに入り、下記cronの設定を入力する。

```
4-59/5 * * * * say balloon
```
毎時4分,9分…59分に「balloon」という音声が流れる設定。(sayコマンドはMacのみのようです)
「balloon」は適宜好きな言葉に置き換えて下さい。

4. `esc` でInsertモードを抜け、`:wq` で保存、終了する。


## その他設定
- 音声で通知するので、音量は適宜設定して下さい。
- スリープモードに入ると音が鳴らなくなるので、 `システム環境設定` → `省エネルギー` → `ディスプレイをオフにするまでの時間`を長めの設定にしておくと良いでしょう。(Macの場合※OSのバージョンで設定手順は異なる可能性があります)



指定時刻に「balloon」という音声が聞こえたら、動作確認完了です。
建物から出てバルーンを探しましょう！

# 終了する時は
下記コマンドでcrontabの設定を削除する。

```
crontab -r
```

※今回設定したもの以外にもcrontabに設定がある場合は、crontabを編集して今回追加した行のみ削除してください。

#おわりに

今回は、あつ森でレシピを集めるために簡易的にcrontabを使いました。
実際のシステム運用では上記のコマンド等は非推奨のようなので、仕事で使用する場合はお気をつけください。
参考: https://ozuma.hatenablog.jp/entry/20120711/1342014448

では、良い無人島ライフを！！
PHPでフォームから投稿したテキスト文を表示する際に行ったこと

DBから情報を抜き出して掲示板に内容を出力しようとしたらこんなエラーが発生しました。
<img width="434" alt="スクリーンショット 2020-04-08 18.45.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518141/1035b66a-2f20-0da4-e429-7b7b338931da.png">

なんだこれはと思い調べてみると配列関連のエラーだそうで（正直詳しくわかってない）
PHPのために購入したテキスト通りに進めているはずなのにエラーばっかり出るから不親切なテキストですね。

##どうやって解決したのか
そもそもの書き方の問題でした
エラーが起きていた時のコードをうっかりスクショしておくの忘れてしまっていました。申し訳ございません。

```
//$postにDBに格納されている情報を格納
$post = $db->query('SELECT * FROM users JOIN posts ON posts.user_id = users.id');

foreach($post as $posts) {
  print_r(htmlspecialchars($posts['name'] . ":" . $posts['text'], ENT_QUOTES). '<br>');
}
```

これで無事に解決できました。foreachの使い方も改めて勉強できたのでいい感じでした。

foreach（配列が格納されている変数 as 任意の変数名){
  　　//行いたい処理
}

でDB内に格納されている情報を全て出力されるようになります。
シャットダウン.batと再起動.bat


```:シャットダウン.bat
@echo off
SET /P selected="シャットダウンしますか(y/n)？"
if /i "%selected%"=="y" (goto :yes)
if /i "%selected%"=="yes" (goto :yes)
exit 0

:yes
shutdown -s -t 0

exit 0
```

```:再起動.bat
@echo off
SET /P selected="再起動しますか(y/n)？"
if /i "%selected%"=="y" (goto :yes)
if /i "%selected%"=="yes" (goto :yes)
exit 0

:yes
shutdown -r -t 0

exit 0
```
MACでARM系マイコンを開発する方法2

#Introduction
[MACでARM系マイコンを開発する方法1]にて当方が採用した、CrossWorks for ARMの購入手順を紹介した。
今回はアクティベーションから、STM32の開発を始めるに当たっての準備を記述する。

今回の前提条件は購入した後の話が中心ですが、購入前の1ヶ月の評価期間でも参考になる内容。

#インストール
特に難しいことはないでしょう。

#起動
こんな画面が出てくるはず。
![スクリーンショット 2020-04-08 2.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/ccdc279f-3ee0-faf2-69b0-bea0507097f1.png)

#ライセンス認証
[Tools]-[License Manager]と進む
![スクリーンショット 2020-04-08 20.32.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/0fbd53c3-7c61-2002-999a-3d3de3e2cd3b.png)

こんな画面が出てくる
これは当方環境ですでにアクティベーション済みの画面である。
購入を済ませた後であれば、Request~をクリック。
![スクリーンショット 2020-04-08 20.34.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/e7c7c54c-9fdf-0dc9-f2fa-41ef2440fa06.png)

近年よくある、MACアドレスに対してライセンスキーを割り当てる形式である。
パソコンのネットワークIFのMACアドレスを選択し、プロダクトキーを打ち込む。
そうすると、アクティベーションリクエストの文字列が生成される。
これを画面内の[Send e-mail]をクリックするとメーラーが起動して、アクティベーション依頼のメールが自動生成される。
![スクリーンショット 2020-04-08 20.36.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/57e275a2-9d53-f1a7-f819-b375f373cfe2.png)

出た物をそのまま送ればOKである。
リプライが来るまで1営業日くらい。気長に待ちましょう。
返事が来たら、[What do you want do?]の画面に戻って、Activate CrossWorksを実行して、送られてきたアクティベーションキーを打ち込めばおしまい。

#パッケージを入れる
汎用IDEたる部分ですね。STM32以外にも、ARM系のいろんなマイコンがあります。
画面の中に[Packages]と言う区画があり、[Manage Packages]をクリックする
![スクリーンショット 2020-04-08 2.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/9129c769-1477-b6ff-b520-4d5ef122d8f1.png)

クリックするとこんなのが出てくる。
STM32を開発する場合、[STM32 CPU Support Package]を入れる。
![スクリーンショット 2020-04-08 2.16.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/3576d866-eb56-3a45-3f8e-a1abc36269f4.png)

＜注意＞
Nuclepo_Fxxx_Board Support Package
とか
STM32FxDiscovery Support Package
とかボード名のサポートパッケージがありますが、これはおすすめしません。
その中身にボード固有情報を含んでるわけじゃないですし、[STM32 CPU Support Package]は割と頻繁に更新がかかります。
その更新に追従してこないため、ボードサポートパッケージは最新のCPUサポートパッケージだとビルドできないことも・・・。

#開発はじめ
最初の画面に戻って、[Projects]区画から、[Create a new project]をクリック
![スクリーンショット 2020-04-08 2.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/b8966e39-2710-0747-6ab8-50b3f8ba8c9c.png)

プロジェクトのテンプレを選ぶ
これが先の工程でインストールしたパッケージを選ぶこととほぼ同義。
プロジェクトに名前をつけて、保存場所を選ぶ。
STM32系の場合、An executable for~を選択して[Next]
![スクリーンショット 2020-04-08 2.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/a98c83f6-a8da-e0fc-f469-afd010dc47c0.png)

Target Processorを選定。
使いたいマイコンの型番を選ぶ。
![スクリーンショット 2020-04-08 2.19.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/2d3e1ac4-be9d-ff04-3f74-5f933f880220.png)
プロジェクトフォルダに、共有で使ってるライブラリなどを入れたいときはInport all~の所にチェック。
ライブラリに手を加えない人はチェック外したままでOK
![スクリーンショット 2020-04-08 2.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/b8f60b9a-6d34-c3b3-e562-39a2163917cf.png)
[Finish]をクリック
![スクリーンショット 2020-04-08 2.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/fcb6a415-4c39-8530-c3cd-7984ee8b99c2.png)
初期プロジェクトのできあがり。
この画面で試しにビルドしてみて、エラーはでなければとりあえず問題なし。
![スクリーンショット 2020-04-08 2.24.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615272/8595f1f4-d4b0-bfcd-55da-741203a71fbb.png)
初めてのAWS①～AWSの基本を学ぶ～

##はじめに
　仕事でAWSを利用するということで、一通り基本的なことを勉強しました。1年間プログラミングスクールに通ってはいたものの、基本的なスキルしか学習していないため「クラウド」と聞いただけでやや拒否反応がありました。。
　が、そんなことも言ってられないので、自分なりに分かったことをまとめていきたいと思います。

##AWSとは
　まずはAWSの基本的なことをおさらいしたいと思います。

　AWSとは、大手会社Amazonが提供する「クラウドコンピューティングサービス」です。

　「クラウドコンピューティングシステム」とは、企業が活動する上で必要なサーバやメモリ、データベースなどをインターネット上で提供することで、インターネット上で簡単に仮想的なサーバなどを作ることができます。
　
　これにより、物理的なサーバや記憶媒体を準備する必要がなくなり、どのくらいの容量を確保するのか、初期費用に多額の資金が必要になる、などの不安を解消することができます。

　AWSは、クラウドサービスの中でも「クラウドコンピューティングのリーダーシップ」に位置付けられ、様々な開発環境で利用されているサービスなのではないかと思います。

## AWSを利用するメリット
　AWSについて学んだところ、以下の3点が最大のメリットとして挙げられます。

① リソースの柔軟性が高い
② データの信頼性が高い
③ インフラ（サーバやメモリなど）の維持管理が不要

　それぞれについて、詳しく見ていきたいと思います。

①リソースの柔軟性が高い
　サーバを作ろうとした場合、最大どれくらいの容量が必要になり、少なくともどのくらいの容量が必要なのか、足りなくなったらどうしよう・・・など考えることが多いと思います。
　AWSであれば、利用した分だけ料金がかかる従量課金制を採用しており、足りなくなった分・使わない分については自動的にスケールアップ・スケールダウンしてくれます。

② データの信頼性が高い
　Amazonは世界各地にデータセンタがあり、複数のデータセンタでデータを保管しています。
　災害が発生し、ある地域のデータセンタが崩壊してしまったとしても、他の地域のデータセンタにもデータが保管されているのでデータが破損する心配はいりません。

③ インフラ（サーバやメモリなど）の維持管理が不要
　AWSのインフラを使うことになるので、その維持管理が不要になります。何か障害が起きたときはAWSが対応してくれますし、必要なアップデートもAWSが行います。
　常に最新のサービスが提供され、また、世界各地にデータセンサがあるため、グローバル展開も容易になります。

##気を付けること
　ここまで見ると、クラウドの良さがとても伝わると思います。ですが、実際にAWSで仮想ネットワークやサーバーを立てたりした時に感じたのですが、気づかぬ間にインスタンス（）をたくさん作ってしまい、結構驚きました。
　アカウント作成してから1年間は利用料無料だったり、もともと無料枠もあるので、最初のうちは心配いらないと思うのですが、、とはいえ1年の無料期間終了後が少し怖いなぁと思いました。

##まとめ
　クラウドサービスは不明瞭な部分が多いので、そのあたりが少し気になりますが、、　誰でも手軽にインフラを構築することができる点にメリットがあると思います。
　とりあえず、AWSを少しいじってみることで「クラウド」に対する拒否反応が少しなくなってきたので良かったです。！
さくらクラウド別リージョン間でのクローン

# はじめに
さくらクラウドにはサーバをクローンする機能が御座いますが
東京リージョンから石狩リージョンなど、別リージョンにはクローンが出来ません。

そのため別リージョンにサーバのコピーを作成したい場合には、アーカイブを作成する必要が御座います。

# 移行元サーバでアーカイブを作成

アーカイブの作成はサイドメニューの「ストレージ」から「アーカイブ」を選択して追加するか、もしくは「アプライアンス」の「自動バックアップ」から定期的に取得いたします。

<img width="836" alt="アーカイブ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479673/5f4a8ae7-7989-710e-aa57-146307517084.png">

[自動バックアップ](https://manual.sakura.ad.jp/cloud/appliance/autobackup/index.html)
[アーカイブ](https://manual.sakura.ad.jp/cloud/storage/archive.html)

# 移行先サーバで移行元アーカイブを基にアーカイブを作成

移行元サーバで作成したアーカイブを基に新規にアーカイブを作成いたします。
サイドメニューの「ストレージ」から「アーカイブ」を選択して追加する際に
移行元のマイアーカイブを使用することで、別リージョンにもアーカイブのコピーが作成出来ます。

# 移行先サーバでアーカイブを基にサーバ作成

作成したアーカイブを基に今度はサーバを作成いたします。

<img width="816" alt="アーカイブ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479673/391dbc57-e161-43ba-b72e-d446dbddbaa9.png">

直接別リージョンにクローンは出来ませんが、アーカイブを使用することでクローンと同様の事が行えます。
Eclipseに自動にSASSコンパイラーを設定

chocolateyをインストールしていただいて
>https://chocolatey.org/docs/installation

一つのやり方はパワーシェールで
> Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

それで

>choco install sass

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/cb1b2e51-6796-3012-1584-bbccf9d67adb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/50d22bf6-47af-c52e-adff-0eeaf19a87a6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/d130e1bd-ec88-2551-0d9a-6af1f94a703c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/8cf8cf53-639c-7ed2-1af0-dcba0d1343bc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/2f118a24-baff-640d-02fb-099ce3b0c7d7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/846677ab-c7f7-8829-b61b-3181401435c3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546056/45a7fef9-c40f-d5be-9ac7-35acf526de98.png)


.sass ファイルを保存すると自動にコンパイルしてくれる。

以下のエラー出る場合は一旦Eclipseを再起動すれば大丈夫
> 'dart.exe' is not recognized as an internal or external command,
operable program or batch file.

完了。
iNEDI の MATLAB コードを GNU Octave で動かす

機械学習以前のレガシーな超解像変換のひとつ iNEDI を試すのに参照コードが MATLAB で、それを Octave で動かすのに　image パッケージのインストールとロード設定が必要でした。というだけのメモ書きです。

- https://github.com/tecnickcom/inedi

この後、ICBI でも同様の事をしてるのと、ちょっぴり手順を改善したので参考までに。

- ICBI の MATLAB コードを GNU Octave で動かす
   - https://qiita.com/yoya/items/22fe032cb8c43026a3c0

# 準備 

## octave インストール

- Ubuntu だと apt-get install octave liboctave-dev
- macOS は brew install octave で良いでしょう。

## octave forge
image パッケージを入れます。
bwselect 関数を使う為です。

- https://octave.sourceforge.io/packages.php
  - https://octave.sourceforge.io/image/index.html
![スクリーンショット 2020-04-08 20.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/ecc65217-8ee7-83ac-f7c8-9632791005de.png)

```
% octave
GNU Octave, version 4.2.2
(略)
octave:1> ls
LICENSE  README.md  image-2.12.0.tar.gz  inedi.m  inediexample.m  testimage.png
octave:2> pkg install image-2.12.0.tar.gz
octave:3> pkg list
Package Name  | Version | Installation directory
--------------+---------+-----------------------
       image  |  2.12.0 | /home/yoya/octave/image-2.12.0

```

## 追記

tarball を持ってこなくても、以下の命令で良いみたいです。(未確認

```
pkg install -forge image
```

# 変換

- https://github.com/tecnickcom/inedi/blob/master/inediexample.m

pkg load image する事で bwselect 関数が使えるようになります。
なお自分は imshow をコメントアウトして、imwrite をコメントから戻して実行してます。

```
% octave
GNU Octave, version 4.2.2
(略)
octave:1> pkg load image
octave:2> run inediexample.m
iNEDI function by Nicola Asuni.
This is an example script that shows you how to use the inedi.m function.
Please check the documentation inside this file for further information.

[   0.014 sec] LAYER: 01
[   0.015 sec]    ZF: 01
[   0.015 sec]        PHASE: 00
[ 201.778 sec]        PHASE: 01
[ 566.965 sec] END
```

|testimage.png|testimage_inedi.png|
|---|---|
|![testimage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/4d7324f2-bff7-129e-8ef7-3e16fa13988c.png) | ![testimage_inedi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798/ed288f8c-0c5a-6bbd-6cac-feb2f3247a90.png)|


150x150 を 299x299 にするのに 9分半！！！　なかなか重たいアルゴリズムのようです。

# おまけ

image パッケージなしで実行すると、以下のようなエラーが出ます。

```
'bwselect' undefined near line 366 column 44
error: called from
    inedi at line 366 column 42
    inediexample at line 83 column 9
    run at line 86 column 5
```
# 追記

MATLAB (2020年版)で試したところ、76秒でした。7倍以上速い。
思ってた以上に性能違いますね。
Web技術基礎知識メモ1

#用語
####ユーザーインターフェース
コンピューターの機能とユーザーのやり取りの橋渡しをする機能

####API(アプリケーションプログラミングインターフェース)
ユーザーインターフェースに対し、ソフトウェア同士のやりとりをする機能
例)スマートフォンの天気予報アプリ
 (アプリ)   →　アプリが送信した地域情報   →　(Webサーバー)
 (アプリ)   ←  Webサーバーが受け取った地域の天気情報 ←　(Webサーバー)

####プロトコル
ネットワークに接続された機器同士が通信するときのルール
……用途に応じてさまざまなプロトコルが存在　　例)HTTP,SMTP,POP



##TCP/IP
インターネット上のサービスを実現するためのプロトコルの集まり。
スマホ、パソコンやサーバーはすべてTCP/IPに対応している。
4つのレイヤーから構成される。
レイヤー1)ネットワークインターフェース層。ハードウェアに関する規定。プロトコル例)イーサネット、WIFI
レイヤー2)インターネット層。ネットワーク間の通信を規定。プロトコル例)IP
レイヤー3)トランスポート層。データの分割方法を規定。プロトコル例)TCP,UDP
レイヤー4)アプリケーション層。Webブラウザやメールソフトなどのアプリごとのやり取りを規定。プロトコル例)HTTP,SMTP


####TCP
送信側と受信側で互いに送受信に関する確認を取りながら通信を行う。
例)Webサイトやメールなど、データ損失を防ぐことを優先する場合に採用する。

####UDP
送信側と受信側で送受信に関する確認を取らない通信を行う。
例)動画ストリーミングなど、処理速度が求められる時に採用する。

####IPアドレス
インターネットに接続されてたコンピューターに割り当てられた住所

####ポート番号
コンピュータが提供するサービスの種類を規定したもの
例）80番:HTTP

##URL
URLは「スキーム名(プロトコル名)＋ホスト名（ドメイン名）＋ポート番号＋パス名」で成り立つ。

####ドメイン名
接続先のサーバー名

####パス名
接続先のサーバー上のディレクトリやファイルを表す。




#参考文献
Web技術の基本 SBCreative