OmniAICreator/Qiita-1.07M huggingface dataset:
Vue3のscript setupで双方向バインディングを実装する

最近Vue3を触り始めましたが、Vue2の双方向バインディング `.sync` は使用できなくなっていました。
https://v3.ja.vuejs.org/guide/migration/v-model.html#v-model
> 破壊的変更: v-bind の .sync 修飾子とコンポーネントの model オプションは削除され、v-model の引数に置き換えられます。

というわけで、Vue3での記法で動かしてみたのでまとめておきます。

# v-modelを利用したバインディング

Vue3では `v-model` を利用して双方向バインディングを行います。

## 親コンポーネント

親コンポーネントはシンプルです。
今回は親と子の双方向でバインディングする変数を `text` としています。
子コンポーネント `Child` にも、 `v-model="text"` を指定します。

```vue:Parent.vue
<template>
  <p>parent</p>
  <input v-model="text" />

  <!-- 子コンポーネント -->
  <Child v-model="text" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import Child from "@/components/Child.vue";

// 双方向バインディングする変数
const text = ref('');
</script>
```

## 子コンポーネント

子コンポーネントは下記のようになります。
親コンポーネントで `Child` コンポーネントに指定した `v-model="text"` は、`modelValue` として受け取ります。

コンポーネント内では、`computed` プロパティとして利用します。
値に変更があった場合はsetterが呼ばれ、`emit` を通して親コンポーネントの変数 `text` が更新されます。

```vue:Child.vue
<template>
  <p>child</p>
  <input v-model="text" />
</template>

<script setup lang="ts">
import { computed, defineProps, withDefaults, defineEmits } from "vue";

const props = withDefaults(
  defineProps<{
    modelValue: string;
  }>(),
  {
    modelValue: '' // デフォルト値を指定
  }
);

const emit = defineEmits<{
  (e: 'update:modelValue', text: string): string
}>();

const text = computed({
  get: () => props.modelValue,
  set: (value) => { // 値に変更があると呼ばれるsetter
    emit('update:modelValue', value);
  },
});
</script>
```

![binding.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279032/b454aa24-ff2a-f72b-1d07-442327c10db3.gif)


できた！

# v-modelに引数を渡したバインディング
v-modelに引数を指定して変数をバインディングすることもできます。
複数の変数をバインディングしたい場合などに利用できます。

## 親コンポーネント

`<Child v-model:text="text" />` のように子コンポーネントに変数を渡します。

```vue:Parent.vue
<template>
  <p>parent</p>
  <input v-model="text" />

  <Child v-model:text="text" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import Child from "@/components/Child.vue";

const text = ref('');
</script>
```

## 子コンポーネント

子コンポーネントでは `text` Propsで受け取ります。
`v-model` に引数を指定した場合は `modelValue` ではなく引き数名で受け取ることになります。

```vue:Child.vue
<template>
  <p>child</p>
  <input v-model="textComputed" />
</template>

<script setup lang="ts">
import { computed, defineProps, withDefaults, defineEmits } from "vue";

const props = withDefaults(
  defineProps<{
    text: string;
  }>(),
  {
    text: ''
  }
);

const emit = defineEmits<{
  (e: 'update:text', text: string): string
}>();

const textComputed = computed({
  get: () => props.text,
  set: (value) => {
    emit('update:text', value);
  },
});
</script>
```

以上で、「v-modelを利用したバインディング」と同様の動きを実装可能です。
ubuntu20.04におけるowncloudのインストールエラー　クソデカgpg鍵の罠

ubuntu20.04におけるowncloudのインストール
残念ながら私には知識というものがございません。
しかしながら情報共有と、どなたかが記事を作ることへの助力となりますよう。


簡潔：高速：理由説明なしにまいりましょう。



https://github.com/owncloud/core/issues/37779

owncloud公式文書にだまされホイホイついていった方も多いでしょう。
残念ながら上記のようにgpg鍵にエラーが出る。
issueが立つ。
すると鴉が何万羽となく輪を描いて、クソ高い鴟尾のまわりを鼓膜破壊レベルの音量で啼きながら、亜音速で飛びまわる。
（引用:クソデカ羅生門）

上記参考に行きますと、
(もしすでにいろいろやった場合は)過去のリポジトリを削除
https://stackoverflow.com/questions/48402330/malformed-entry-1-in-list-file-etc-apt-sources-list-d-mongodb-list-suite
参考はここ。
さしずめ
> sudo rm /etc/apt/sources.list.d/だまされて入れた鍵の名前
//その後追加。頑張って。
> echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/server:/10/Ubuntu_21.04/ /' | sudo tee /etc/apt/sources.list.d/isv:ownCloud:server:10.list
curl -fsSL https://download.opensuse.org/repositories/isv:ownCloud:server:10/Ubuntu_21.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/isv_ownCloud_server_10.gpg > /dev/null
sudo apt update
sudo apt install owncloud-complete-files

おつかれさまでした？これで終わりかと。
[Nuxt.js]VSCodeでファイル保存時にESlint,Prettierで自動整形する

## 挨拶
Web系エンジニアへの就職に向け学習をしております、ひろやすと申します。
今回の記事は、VSCodeでファイル保存時に保存されたファイルの自動整形を行う方法について調べたので、学習のアウトプットとして投稿しようと思います。

## 前提条件
今回は、Nuxtプロジェクトの自動フォーマットに絞って解説したいと思います。
◆プロジェクトのバージョン
・Nuxt.js（2.15.7）
・ESlint（7.29.0）
・Prettier（2.3.2）

create-nuxt-appでESlintとPrettierを選択したため、.eslintrc.js(ESlintの設定ファイル)や.prettierrc(Prettierの設定ファイル)が自動で作成されています。

```javascript:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: '@babel/eslint-parser',
    requireConfigFile: false
  },
  extends: [
    '@nuxtjs',
    'plugin:nuxt/recommended',
    'prettier' // Prettierとの競合を防ぐため
  ],
  plugins: [
  ],
  // add your custom rules here
  rules: {
    'no-console': 'off', // console.log()の使用を許可する
    'semi': ['error', 'never'] //　文末にセミコロンを付けない
  }
}
```

```:prettierrc
{
  "semi": false, // 文末にセミコロンを付けない
  "singleQuote": true // シングルクォートを使用
}
```

## VSCodeに拡張機能を追加
今回は、VSCodeの拡張機能であるESlintとPrettier-Codeformatterをインストールします。![スクリーンショット 2022-02-19 17.54.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2244078/97ad05f0-a9b5-10b8-f937-15de75e53154.png)
![スクリーンショット 2022-02-19 17.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2244078/86ad186d-57f2-9b4a-ffec-6f56f1120232.png)

## VSCodeのsetting.jsonを編集
ファイル保存時に自動フォーマットするように設定。
```json:setting.json
"editor.formatOnSave": true
```
ファイル保存時にESlintが、対応するファイルをフォーマットする。
```json:setting.json
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}
```
デフォルトのフォーマッターにPrettierを設定。
```json:setting.json
"editor.defaultFormatter": "esbenp.prettier-vscode"
```
VSCodeの拡張機能のVeturを使用している場合は
VeturとESlintの競合を防ぐために下記のコードも追記してください。
```json:setting.json
"vetur.validation.template": false
```
以上の設定をすることでファイルの保存時に自動フォーマットが実行されると思います。
このやり方が正解というわけではなく、一つの例に過ぎないと思います。
もし、もっと良い実装の仕方や間違っている部分がありましたらご指摘いただけたら幸いです。
最後までお読み頂きましてありがとうございます。

## 参考文献

- [Prettier 入門 ～ESLintとの違いを理解して併用する～](https://qiita.com/soarflat/items/06377f3b96964964a65d)

- [VS Codeでprettierの自動フォーマット保存が効かなくなっていた時の対応](https://nobunobu1717.site/?p=1797#VSCodeprettiernode_modulesprettier)

- [microsoft/vscode-eslint](https://github.com/microsoft/vscode-eslint)

- [prettier/prettier-vscode](https://github.com/prettier/prettier-vscode)
【RSpec】raise_error, changeマッチャーを繋げて使いたい


## 例外を投げることを確認しつつ、値が変化することも確認したい

下記のようなクラスがあった時に、
`StandardError`を投げることと、`@num`の値が増えることを確認したい。

```ruby:テスト対象のクラス
class TestTarget
  attr_reader :num

  def initialize
    @num = 0
  end

  def call!
    @num += 1
    raise StandardError
  end
end
```

## マッチャーを繋げない書き方

`raise_error`マッチャーで期待値を確認する**前後の行**で、値の変化を確認するとこうなる。

```ruby
RSpec.describe 'TestTarget#call!' do
  it '例外を投げ、@numの値が増える' do
    t = TestTarget.new

    # expect { t.call! }.to change(t, :num).by(1) のように書きたいけど、
    # 例外が発生するから確認できない。
    expect(t.num).to eq 0
    expect { t.call! }.to raise_error(StandardError)
    expect(t.num).to eq 1
  end
end
```

## マッチャーを繋げる書き方
マッチャーの戻り値に対して`and`や`or`メソッドを繋げることで、
`raise_error`マッチャーの後ろに`change`マッチャーを繋げて書ける。

参考: https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/compound-expectations

```ruby
RSpec.describe 'TestTarget#call!' do
  it '例外を投げ、@numの値が増える' do
    t = TestTarget.new

    # 引数渡しも、ブロック渡しも書ける。
    expect { t.call! }.to raise_error(StandardError).and change(t, :num).by(1)
    # or
    expect { t.call! }.to raise_error(StandardError).and change { t.num }.by(1)
  end
end
```

## changeマッチャーの否定系(not)も確認したい場合

既存マッチャーの否定系を簡単に定義する機能を使って書ける。

参考: https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/define-negated-matcher

```ruby
RSpec.describe 'TestTarget#call!' do
  before do
    # changeマッチャーの否定系を定義
    RSpec::Matchers.define_negated_matcher :not_change, :change
  end

  it '例外を投げ、@numの値が変化しない' do
    t = TestTarget.new

    # 引数渡しも、ブロック渡しも書ける。
    expect { t.call! }.to raise_error(StandardError).and not_change(t, :num)
    # or
    expect { t.call! }.to raise_error(StandardError).and not_change { t.num }
  end
end
```

## 最後に
※ @harashoo さんの[記事](https://qiita.com/harashoo/items/a4f1e01d300b6d329dee)も参考にさせていただきました。ありがとうございます。
※ RSpecのバージョン3.10.0で動作確認を行っています。
Minecraft Preview（統合版ベータテスト）の入手方法

**Minecraft Preview**とは、2021/01/31(現地時間)に発表された、MinecraftBedrockEdition(統合版)のベータテストを発展させたものです[^1]。
今までのベータテストとの違いは、

- リリース版を上書きしない（リリース版と共存可能に）
- iOS端末でも参加可能になった

です。
ベータ版はしばらく維持されるが、いずれプレビュー版のみになる模様です[^2]。
「ベータ版のバージョン＝プレビュー版のバージョン」で基本は同じ挙動をします（確か）。

[^1]: 参考①：https://forest.watch.impress.co.jp/docs/news/1384885.html ②：https://twitter.com/JORAX79/status/1488216779574767617
[^2]: 参考：https://help.minecraft.net/hc/en-us/articles/4423653831821-Minecraft-Preview-FAQ

#インストール方法
##iOS版
TestFlightというベータ版をテストするためのアプリを使用します。
このアプリ、なかなか制限が多いらしく、**招待リンクに対して参加できる人数が限られていたり**（つまり開発者がリンクを公開してから先着順）、テストに入れても**テスト期間が決められていたり**、と少々のハードルがあります。
参加枠の拡張は[Josh Mulanax氏のTwitter](https://twitter.com/JORAX79)で告知されているようなので、**拡張されたらすぐに参加しましょう**。今のところ500人ずつ枠を拡張しているようですが、ざっと確認したところ拡張から24時間後にはすでに上限に達していました。
[招待リンク](https://testflight.apple.com/join/qC1ZnReJ)は枠拡張しても共通のようなので、参加したい方はTwitterと合わせて確認しましょう。

##Windows版
Windowsでは単純で**「Minecraft for Windows」をMicrosoft Storeで購入していれば、自動でライブラリに「Minecraft Preview for Windows」が追加**されるようになっているようです。
[Minecraft Preview - Microsoft Store](https://www.microsoft.com/store/productId/9P5X4QVLC2XR)
このリンクを**Minecraftを持っているMicrosoftアカウントでログインして**読み込むとInstallのボタンが出てきます。
「現在購入できません」「コードの使用」などと出ている場合は、ログインしていないか、Minecraftを持っていないMicrosoftアカウントでログインしている状態です。

#注意点など
##プレビュー版でできないこと
- クロスプラットフォームマルチプレイ
- マーケットプレイス（一部のプラットフォームのみ[^3]）
- Realms、特集サーバー（TheHiveなど）
- 実績解除

はMinecraft Previewでは実行できません。
クロスプラットフォームでないマルチプレイはリリース版と同様に（＝Xboxのフレンドになっていれば）できます。
もちろん同じバージョンのプレビュー版同士です。

[^3]: Windows版ではアクセスできませんでした。WindowsでできないのにiOS版でアクセスできるように思えないんですが、一部のみ、と書いてあるので…。

##ゲームファイル類
※Windows版の場合。
リリース版では
`C:\Users\[user_name]\AppData\Local\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang`
にワールドなどのセーブデータが保存されていますが、プレビュー版は別アプリとして扱われるため、別のフォルダに保存されています。
`C:\Users\[user_name]\AppData\Local\Packages\Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe\LocalState\games\com.mojang`
リリース版のワールドをプレビュー版で使いたい場合はここにデータをコピーする必要があります。

##ドキュメント（アドオンのリファレンス）

https://bedrock.dev/docs/beta/

からベータのドキュメントを読むことができます。
画像合成差分


* 画像単色化
```python
import cv2
import numpy as np

# 画像を読み込む。
img = cv2.imread("b.jpeg")

# グレースケールに変換する。
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2値化する。
thresh, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
print(thresh)

# RGBA に変換する。
rgba = cv2.cvtColor(binary, cv2.COLOR_RGB2RGBA)

# 白 (背景) のアルファチャンネルは0にして、透明にする。
rgba[..., 3] = np.where(np.all(rgba == 255, axis=-1), 0, 255)

# 画像の黒い部分を白に置き換える
black = [0, 0, 0, 255]
blue = [255, 0, 0, 200]
green = [0, 255, 0, 200]
rgba[np.where((rgba == black).all(axis=2))] = green

# アパーチャーサイズ 3, 5, or 7 など 1 より大きい奇数。数値が大きいほどぼかしが出る。
ksize=5
#中央値フィルタ
img_mask = cv2.medianBlur(rgba,ksize)

# 保存する。
cv2.imwrite(r"result2.png", img_mask)
```


* 画像合成
```python
import cv2
import matplotlib.pyplot as plt
import numpy as np

img1 = cv2.imread('result2.png', -1)
img2 = cv2.imread('result.png', -1)

#img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
#img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)

#img1 =cv2.resize(img1,(600,800))
#img2 =cv2.resize(img2,(600,800))

blended = cv2.addWeighted(src1=img1,alpha=0.5,src2=img2,beta=0.3,gamma=0)
# 保存する。
cv2.imwrite(r"blended.jpg", blended)
```

> 参考
[OpenCV 画像の二値化](https://qiita.com/tokkuri/items/ad5e858cbff8159829e9)
[Python/OpenCVで任意色を透過させたpng画像に変換](https://watlab-blog.com/2020/03/08/rgba-png/)
[OpenCVを使って初めての背景透過](https://teratail.com/questions/220574)
[画像のノイズ除去](https://qiita.com/cr-fun/items/916c266ee3e51621ec73)
[Unity]AssetDatabase.LoadAssetAtPathがNullになる時がある問題

# あらすじ
エディタ拡張で，アセットのマテリアルを読みこむ処理がしたかったのだが

```c#
var material = (Material)AssetDatabase.LoadAssetAtPath("Assets/~~~/sample.mat",typeof(Material));
```

これだとmaterialがNull扱いされる事案発生．  

# 解決策
単純に.matを.assetに置換してやればいい

```c#
var material = (Material)AssetDatabase.LoadAssetAtPath("Assets/~~~/sample.asset",typeof(Material));
```

MeshRenderer経由などでマテリアル名を取得すると拡張子は.matだが，どうやらLoadAssetAtPathではエクスプローラーなどで表示される拡張子でないと
ダメっぽい．
んで，これがassetの場合とmatの場合がある...時間があるときにここは調べてみる
【Unity】UniTaskでWeb上の画像を取得してシーンに配置する

# はじめに
画像を取得する方法を調べているときに見つけた公式のUnityWebRequestTextureを使用した画像取得コードをUniTaskに対応させたコードに書き直してみました。

# ソースコード
本スクリプトをボタンにアタッチし、Inspector画面でURIと取得した画像を貼りつけるRawImageを指定すると動作します。

```cs:GetTextureButton.cs
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Threading;

public class GetTextureButton : MonoBehaviour
{

    [SerializeField, Header("反映させたいRawImage")]
    private RawImage _targetImage;

    [SerializeField, Header("取得したい画像URI")]
    private string _uri;

    void Awake()
    {
        var token = this.GetCancellationTokenOnDestroy();
        GetComponent<Button>().onClick.AddListener(() => GetTexture(token).Forget());
    }

    private async UniTaskVoid GetTexture(CancellationToken cancellationToken)
    {
        UnityWebRequest www = UnityWebRequestTexture.GetTexture(_uri);
        await www.SendWebRequest();
        if (www.result != UnityWebRequest.Result.Success)
            Debug.Log(www.error);
        else
            _targetImage.texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
    }
}
```


# ゲーム画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/c64f4f2f-51d4-3ac3-4a73-a19646f5d80e.png)
ボタンを押すとこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/d46d0e84-2f39-8f49-4e09-a08e1cbc4c5a.png)

# 今回のリポジトリ
https://github.com/KazukiKuriyama/UnityHttpRequestSamples

# 余談：URI指定で動画を表示させる方法
何故かこちらはスクリプト不要で簡単に実現できます。※Image側でも簡単にできる方法があればコメントを頂きたいです。
VideoPlayerコンポーネントにURIとは反映対象のRenderTextureを指定するだけみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/c75e84ca-9c9b-4807-2e8c-6df753e3f8ee.png)
Vimの簡易まとめ

# 概要
Vimについて個人的な簡易的まとめです。

# 立ち上げと終了、モード
- 立ち上げ
vim <(new)file_name>

- 終了
:q

- 強制終了
:q!

- モード
  - 閲覧している状態がノーマルモード
  - 「:」でモードの選択
  - escでノーマルモードに戻る

- syntax mode
  - :syntax on
  - :syntax off

- insert mode
i

# 移動
- 行の先頭
0

- 行末
$

- 単語ごとに進む
w

- 単語ごとに戻る
b

- (){}
カーソルを合わせるともう片方の色が変わる
もう片方へ移動するには
%

- 空白行への移動
{ = 上にある次の空白の行へ
} = 下にある次の空白の行へ

- 全画面
ctl + u = 上
ctl + d = 下

- 行指定
:20

- 一番下
ctl + g
mac shift + g

- 一番上
gg

# インサート、保存
- vimで開く
vim <file_name>

- intert mode
i

- normal mode
Esc

- save
:w

- インデント(ノーマルモードで)
`>>` = インデント追加
`<<` = インデント削除

# 設定の変更
- Homeへ移動
cd

- vimで設定ファイルの作成
vim .vimrc

- insert mode
i

- 以下を入力
syntax on
set number
let &t_ti.="\e[1 q"
let &t_SI.="\e[5 q"
let &t_EI.="\e[1 q"
let &t_te.="\e[0 q"

- save
esc
:wq

# 書き込み履歴
- 1つ前へ
u

- 1つ後へ
ctl + r

- 書き込んだ内容を全てキャンセル
:e!

# 削除
- ノーマルモードで

- 1文字ずつ
x

- n文字ずつ
x + n

- 1文字の入れ替え
r + <text>

- 1つの単語を削除
dw

- カーソルの行を削除
dd

- カーソルからn行を削除
dd + n

- カーソルから右を全てを削除
D

- 改行を削除
J

# コピーペースト
- ペースト
p

- 一行を丸ごとコピー
yy
n + yy

- ビジュアルモードへ移行
v
y で反転されて部分をコピー

- クリップボードを参照
:reg
macOS Monterey　バンドルApacheでPHPを使う（PHP-FPM編）

これまでlocalhostで `.php` のファイルを扱っていたけれど、MontereyにしたらブラウザからアクセスしたときにPHPが実行されず、ソースが表示されてしまうようになってしまった、という人向けです。

おそらく一番楽であろう、標準で入っているApache + php-fpmを使う方法をご紹介。mod_phpは使いません。


##Monterey以降バンドルされなくなったPHPをインストール
HomebrewでPHPをインストールする場合。

```sh
brew install php
```
もしHomebrew未導入であれば、https://brew.sh に書いてあるようにして導入してから上記コマンドたたいてください。

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```


なおPHPの公式には「FPM使うには `--enable-fpm` を付けてビルドせよ」と書いてありますが、普通に `brew install php` すればついてきます。


##PHP-FPMを起動

システムのログイン時に自動起動させるために `~/Library/LaunchAgents` にシンボリックリンクを配置します。

```sh
ln -s /usr/local/opt/php/homebrew.mxcl.php.plist ~/Library/LaunchAgents
```

初回は手打ちで立ち上げましょう。

```sh
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.php.plist
```

ステータスを確認します。

```sh
brew services list
```
startedとなっていればOK。

##Apacheの設定
テキストエディタでhttpd.confを編集します。Vimを使う場合。

```sh
vim /private/etc/apache2/httpd.conf
```

エディタが起動しますので、以下の2行のコメント（先頭の `#` ）を外します。

```httpd.conf
LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_fcgi_module libexec/apache2/mod_proxy_fcgi.so
```
Vimでは `/` キーにつづけて検索語を打つと検索できます。ハイライトを消したいときは `:noh` 。
上下左右キーを使って消したい `#` にカーソルをあわせて、 `x` キーで1字消去。

続いて、どこか（最下部にでも）に以下を追記して保存。

```httpd.conf
# php-fpmの設定
<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
```
Vimでは `i` キーで挿入モードになります。 `i` 押してから `⌘+v` すると貼り付けられると思います。
保存するには `esc` で挿入モードを抜けたあとに、 `:wq` （上書き保存）でVimを抜けられます。

編集が終わったらApacheの再起動をします。

```sh
sudo apachectl restart
```

ローカルに配置した `.php` のページで、ソースが表示されずに意図通り実行できたら成功です。


###参考
・Homebrewでインストールしたときのpfp-fpmの.confの場所
　`/usr/local/etc/php/*.*/php-fpm.d/www.conf`
・ログがここに生成される
　`/usr/local/var/log/php-fpm.log`
・せっかくmod_phpではなくfcgiを使うので、MPMはpreforkではなくworkerやeventにするのがおすすめです。
pythonでフロア関数を利用する場合は`//`演算子を使った方が良さそうであるという話(math.floorではなく)

pythonでフロア関数を利用する場合は`math.floor`もしくは`//`演算子を使う方法がある

使ってみた

```python:test.py
import math
x = 12345

print("---")
print(x)
print("---")
print(math.floor(x/10))
print(x//10)

y = 2**56

print("---")
print(y)
print("---")
print(math.floor(y/10))
print(y//10)
```

小さな数値の場合は結果が一致するが、大きな数値の場合は実行すると微妙に結果が違う

```
$ python test.py
---
12345
---
1234
1234
---
72057594037927936
---
7205759403792794
7205759403792793
```

~~`math.floor`の仕様をみると`Python の浮動小数点型は 53 ビット以上の精度をもたない`という事で、16桁を超えるような数値を扱う場合は誤差が出ると思われる。~~

※コメント指摘により修正しました。誤解を招く表現ですみません。
`Python の浮動小数点型は 53 ビット以上の精度をもたない`という事で、`math.floor`の実行前に16桁を超えるような数値を割り算すると誤差が出て思ったような結果にならない事が起こる。
フロア関数を利用する場合は`//`演算子を使った方が良さそうである。

> https://docs.python.org/ja/3/library/math.html#math.trunc
> ceil() 、 floor() 、および modf() 関数については、非常に大きな浮動小数点数が 全て 整数そのものになるということに注意してください。通常、Python の浮動小数点型は 53 ビット以上の精度をもたない (プラットフォームにおける C double 型と同じ) ので、結果的に abs(x) >= 2**52 であるような浮動小数点型 x は小数部分を持たなくなるのです。

## 文字列を操作する場合

```
def myfloor(STR):
    ans = 0
    if 0 <= int(STR) < 10:
        # 1桁の正の数                                                                                                                                                                                    
        ans = 0
    elif -10 < int(STR) < 0:
        # 1桁の負の数                                                                                                                                                                                    
        ans = -1
    elif int(STR) > 0:
        # 2桁以上の正の数                                                                                                                                                                                
        ans = int(STR[:len(STR)-1])
    elif STR[-1] != '0':
        # (最後の桁が0以外の)2桁以上の負の数、floor関数を使った時に-1する必要がある                                                                                                                      
        ans = int(STR[:len(STR)-1])-1
    else:
        # (最後の桁が0の)2桁以上の負の数、floor関数を使った時に-1する必要がない                                                                                                                          
        ans = int(STR[:len(STR)-1])
    return ans

print(myfloor(50))        #5
print(myfloor(234567))    #23456
print(myfloor(-234567))   #-23457
print(myfloor(-(2**56)))  #-7205759403792794
```

# 参考
https://takeg.hatenadiary.jp/entry/2019/09/01/110530

https://docs.python.org/ja/3/library/math.html#math.trunc
JavaScript filter

配列A　={1,2,3,4}
配列A.filter(function(配列A){return 配列A>2})で
filterの中の条件に該当するものを返す。
それによって条件に該当してるものだけの新しい配列を生成する。

配列Aは空ではなく、あらかじめ中身がある前提。
上記の条件だと、2より大きい値のみフィルターされた新しい配列を生成する。
filter後
配列A　={3,4}
pythonで素数判定のためにエラトステネスの篩でテーブルを作る

以下を参考にさせて頂いています。

> [エラトステネスの篩](https://python.ms/eratosthenes)
> 1. 簡単なもの
>
```python
def primes(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = False
    is_prime[1] = False
    for i in range(2, n + 1):
        for j in range(i * 2, n + 1, i):
            is_prime[j] = False
    return [i for i in range(n + 1) if is_prime[i]]
```

以下のような、 n までの素数テーブルを用意するclass(素数であればTrue)を作成する

```python
import math

# n までの素数テーブルを用意するclass(素数であればTrue)
# n-1までの整数が素数かどうかを判定する
class PrimeClass:
    def __init__(self, n):
        self.prime=[True]*(n+1)
        self.prime[0]=False
        self.prime[1]=False
        rangeMax = int(math.sqrt(n))
        for p in range(rangeMax):
            if self.prime[p] == True:
                for i in range(p*p, n+1, p):
                    self.prime[i]=False

    def isPrime(self, val):
        if val >= len(self.prime)-1:
            return None
        return self.prime[val]

Prime = PrimeClass(200)
print(Prime.isPrime(197))
print(Prime.isPrime(198))
print(Prime.isPrime(199))
print(Prime.isPrime(200))
print(Prime.isPrime(202))
print(Prime.isPrime(201))

print("---")
Prime2 = PrimeClass(4)
print(Prime2.isPrime(2))
print(Prime2.isPrime(3))
print(Prime2.isPrime(4))
```

以下の部分が出力される

```shell
$ python test.py
True
False
True
None
None
None
---
True
True
None
```

以上です。

# 参考

[エラトステネスの篩](https://python.ms/eratosthenes)
インデックスの効果が出るケースの検証



##インデックスとは
目的のレコードを効率よく取得するための方法です。
インデックスは探すためのキーとなる値とレコードの場所を示すポイントでできています。

##検証環境
Windows10
SQL Server2019

##検証するケース
この記事では一般的に効果が出ると言われている以下の2ケースを検証します。
・少量データを検索する場合
・インデックスが作られている列のデータの種類が多い場合

##少量データを検索する場合の検証
###検証内容
・レコード数100万件
・実行前にキャッシュクリア
・インデックスあり・なしの状態をそれぞれ5回ずつ実施して、平均値を比較
・それぞれのデータ数が検索でヒットするようなデータを用意(1件、10件、25件、50件、100件、1000件、10000件)

###検証
|検索ヒット数|インデックス|1回目|2回目|3回目|4回目|5回目|平均|改善率|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1件|無|0.162|0.109|0.109|0.140|0.109|0.1258||
|10件|無|0.117|0.109|0.113|0.111|0.108|0.1116||
|25件|無|0.113|0.117|0.130|0.110|0.107|0.1154||
|50件|無|0.127|0.119|0.113|0.138|0.126|0.1246||
|100件|無|0.133|0.114|0.131|0.142|0.132|0.1304||
|1000件|無|0.133|0.131|0.128|0.133|0.137|0.1324||
|10000件|無|0.156|0.153|0.150|0.144|0.143|0.1492||
|1件|有|0.038|0.049|0.047|0.045|0.034|0.0426|66.14%|
|10件|有|0.048|0.048|0.034|0.054|0.050|0.0468|58.06%|
|25件|有|0.052|0.047|0.054|0.057|0.038|0.0496|57.02%|
|  50件|有|0.060|0.046|0.064|0.049|0.062|0.0562|54.90%|
| 100件|有|0.056|0.052|0.068|0.051|0.055|0.0564|56.75%|
|1000件|有|0.084|0.059|0.066|0.075|0.064|0.0696|47.43%|
|10000件|有|0.094|0.104|0.094|0.098|0.113|0.1006|32.57%|

##インデックスが作られている列のデータの種類が多い場合の検証
###検証内容
・レコード数100万件
・実行前にキャッシュクリア
・インデックスなしとありを5回ずつ実施し、平均値を比較
・それぞれのデータ種類数がヒットするようなデータを用意(1種類、10種類、100種類、1000種類、10000種類、100000種類、1000000種類)


###検証
|データ種類数|インデックス|1回目|2回目|3回目|4回目|5回目|平均|改善率|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1種類　(×1000000件) |無|3.523|3.458|3.600|3.524|3.466|3.514||
|1種類　(×1000000件) |有|3.259|3.397|3.384|3.381|3.625|3.409|2.99%|
|10種類　(×100000件) |有|0.395|0.401|0.395|0.388|0.399|0.396|88.74%|
|100種類　(×10000件) |有|0.102|0.099|0.090|0.102|0.087|0.096|97.27%|
|1000種類　(×1000件) |有|0.051|0.057|0.053|0.051|0.052|0.053|98.50%|
|10000種類　(×100件) |有|0.045|0.036|0.072|0.061|0.045|0.052|98.53%|
|100000種類　(×10件) |有|0.020|0.038|0.036|0.041|0.040|0.035|99.00%|
|1000000種類　(×1件)|有|0.032|0.039|0.040|0.020|0.024|0.031|99.12%|

##まとめ
・大量データを検索する場合よりも、少量データを検索する場合の方が効果が高い
・データ種類が少ない項目よりも、多い項目にインデックスを作成する方が効果が高い
・項目数が10種類から効果がかなり大きくなる
pythonで整数値の桁数を求める

pythonで整数値の桁数を求める

log10を使うだけ

※コメントにて、log10は引数によっては浮動小数点演算の精度が結果に影響することもあるので注意が必要だとご指摘を頂きました。桁数が多い場合は追記の部分を参照下さい。


```python
import math

num = 2**53
digits = int(math.log10(num))+1
print(digits) #16
```

## 追記

以下の方がはるかに楽であった。。

> [Pythonで数字の桁数を取得する方法](https://qiita.com/RShirakawa/items/23f8f1d907dc40ebbdd2)
> 数字を文字列に変換して、長さを取得する。
> 負の数の場合、マイナス符号が桁数に入ってしまうので絶対値に変換しておく。
>
> ```
> num = -12345
> num_digits = len(str(abs(num)))     # 一括変換
> print(num_digits)                   # 実行結果 5
> ```


# 参考

https://qiita.com/RShirakawa/items/23f8f1d907dc40ebbdd2

https://www.delftstack.com/ja/howto/python/python-number-of-digits-in-a-number/
環境変数について(初心者)

# 環境変数について

## windows
確認コマンド

```
c:\Windows> set
```

環境変数の中身を確認

```
c:\Windows> echo %OS%
c:\Windows> echo %path%
```

コマンドがどこにあるか確認
Linuxで言うところのwhich

```
c:\Windows>where node
C:\Program Files\nodejs\node.exe

c:\Windows>where npm
C:\Program Files\nodejs\npm
C:\Program Files\nodejs\npm.cmd
```

pathに設定されているディレクトリの中のものはコマンドとして使用できる
(コマンドに該当する実行ファイルなどは必要)

複数のファイルが表示されたらどちらが優先されるのだろうか。
コマンドはどちらも通る様子。。。
N+1問題の直感的理解

# N+1問題
例えば、user(has_many :posts)なるテーブルと、post(belongs_to :user)なるテーブルの二つがあるとする。
userは0個以上のpostを持っていて、postには各userのid(user_id)が必ず対応している。
ここで、各userの持っているpostを取り出し、userの名前(user.name)と、postのタイトル(post.content)を全件表示したいとき、どのようなコードを書けばよいだろうか。

最も分かりやすいのは以下のコードだろう。

```ruby:view
User.all.each do |user|
  user.posts.each do |post|
    puts "#{user.name} / #{post.title}"
  end
end
```
このコードで実行される内容は、

(1). userの情報（user.id,user.name)を取得するために、userテーブルにアクセス
2. id = 1のuserのpostの情報を取得するためにpostテーブルにアクセス
3. id = 2のuserのpostの情報を取得するためにpostテーブルにアクセス
4. id = 3のuserのpostの情報を取得するためにpostテーブルにアクセス
5. id = 4のuserのpostの情報を取得するためにpostテーブルにアクセス


   ...

 n+1. id = nのuserのpostの情報を取得するためにpostテーブルにアクセス

とまあこんな感じで、n+1回の処理が行われることになる。
しかし、n+1回も処理してたら重いし問題だよねということで、このような状況が「N+1問題」と呼ばれる。

# 解決策
以下のようにcontroller内でincludesメソッドを使ってインスタンス変数を定義しておくことは、ポピュラーな解決策の一つ。

```ruby:controller
@users = User.includes(:posts)
```

```ruby:view
@users.each do |user|
  user.posts.each do |post|
    puts "#{user.name} / #{post.title}"
  end
end
```

このコードで実行される処理は

1. userの情報を取得するために、userテーブルにアクセス
2. postの情報を取得するためにpostテーブルにアクセス
3. userのidと、postに関連付けられているuser_idを結びつけてテーブル同士を結合
4. 結合されたテーブルの情報を基にviewにuserの名前とpostのタイトルが表示される

と、テーブルへのアクセスが最初の２回のみに抑えられている。

先程の例との違いは、一回一回データを取りにテーブルを出入りするのではなく、userデータとpostデータ、それぞれ一回でそのテーブルの全てのデータをまとめて取得しておいて、user_idというキーでテーブル同士を結びつけ、順番に表示する点。


また、テーブルをJOINしてから取得する方法も解決策として考えられる。
includeとJOINの違いは、includeがuserのデータと、postのデータをそれぞれ別々に取得して、アプリケーションでそれらを紐づけていくのに対して、JOINの場合はデータを取得する段階で、userとpostを結びつけた状態でデータを取得する。このため、includeの場合は発行されるクエリは２回であるのに対し、JOINの場合は発行するクエリは１回のみ。ただし、データを結びつけた状態で取得するJOINの処理には時間がかかる。

# 参考
https://www.sejuku.net/blog/26168

https://pikawaka.com/rails/includes
request.env["HTTP_USER_AGENT"] について

 request.env["HTTP_USER_AGENT"] というのを実務で見かけてよくわからなかったのでまとめてみようとおもいます。

## 何ができるのか？
結論からいうと、これを使うことでどのブラウザからアクセスしているのか、どのデバイスからアクセスしているのかということがわかるんです。
例えば、
```
request.env["HTTP_USER_AGENT"].include? "Chrome"
```
とすることでユーザーがchromeを使ってアクセスしているのか、ということがわかるんです。
また、
```
request.env["HTTP_USER_AGENT"].include? ('Mobile')
```
とすることで、アクセスしているユーザーの端末はiOSなのかandroidなのかということが分かります。

MobileはiPhoneやiPadなどのapple製品で、androidはその名の通りandroid系です。

自分はまだ経験したことはないですが、OSやブラウザごとに処理を変えたい時に使うものなんだとおもいます。

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考文献】

https://wa3.i-3-i.info/word11027.html

https://qiita.com/_rena_h/items/5c088561363cd8b00332

https://www.cotegg.com/blog/?p=2554

https://wa3.i-3-i.info/word1452.html
Firestoreの特徴的な機能

最近個人開発を始めるなかで、Firestoreを使う機会があったので、今までなんとなくでしか理解できていなかった**Firebase**を勉強してみようということで[実践Firestore](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Firestore-%E6%8A%80%E8%A1%93%E3%81%AE%E6%B3%89%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%EF%BC%88NextPublishing%EF%BC%89-%E7%A6%8F%E7%94%B0-%E9%9B%84%E8%B2%B4-ebook/dp/B0851BGDQG)という本を読み始めたので、簡単にFirestoreの特徴についてまとめてみたいと思います。

# セキュリティルール
Firestoreでは、クライアントから直接データベースへアクセスして読み書きを行います。
セキュリティルールとは、データの機密性と完全性を担保するための記述するものです。
セキュリティルールを記述することで、Firebase上にデプロイすると、記述されたルールに従ってFirestoreへリクエストが行われます。

# リアルタイムリスナー
リアルタイムリスナーは、Firestoreの最新の状態をクライアントに同期するための仕組みです。
これによって、ユーザー間でリアルタイムのデータ共有が可能になります。
また、Firestoreのリアルタイム・リスナーは、ネットワーク切断が起こったときの例外ハンドリングや切断状態から自動で復旧する能力を備えています。
さらに、リアルタイムリスナーは、サーバーサイドで起こったデータの変化を、サーバーサイドからクライアントに向けて通知するので、リアクティブシステムとの親和性が高いのも特徴です。

# オフライン対応
Firebaseでは、不安定なネットワーク下でもアプリケーションを稼働させるための機能を備えています。
Firestoreでは、データの書き込みのオフライン対応としてオペレーション・キューが実装されており、オフライン時に行われた書き込み要求はエラーとならず、キューに蓄積されます。
このような対応力があるので、Firestoreでの書き込み処理がエラーになることは、ほぼほぼありません。

データの読み込みに関しては、オフラインでのデータ永続化の有効・無効を設定できるので、オフラインを有効にするとオンラインの間にFirestoreと読み書きしたデータが透過的にキャッシュされるようになります。
サーバーに接続できない状況でデータの読み取りリクエストを発行すると、キャッシュにあるデータが返却されます。

# 最後に
以上Firestoreの特徴的な機能についてでした。
参考にさせていただいた本が、とても良書でFirestoreを使うなら一読する価値は非常にあると感じました。
また、読み進めたらまとめてみたいと思います。
TPVで確認する方法

さっとTPVでwebsphereのアプリケーションサーバなどのリソースの現在の状態を確認する方法

ロギングしたい方はロギングボタンをクリックしてください！！

左ペインで以下の現行アクティビティーをクリック

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291303/8a7078f2-8157-00f5-ccf5-157b27edf4bc.png)

JVMランタイムにチェックを入れる
※皆さまが見たいところにチェック入れてください。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291303/c4c7d27c-a572-bd60-39c4-4d449db141fe.png)

チェックを入れたらモジュールの表示をクリックする。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291303/a70cdc4e-2ca2-f80f-ce2c-f3ff0eea492f.png)

グラフが表示することを確認する。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291303/88ee88df-c1ec-7ecd-868b-cb6cac28eabe.png)
派生開発における調査プロセス ～開発時に行う調査とは～

派生開発における調査プロセスについて、提言を見つけました。
導入にあたり、特殊なツールを使用するわけでもなく、開発現場で活用しやすい内容だと思えたため、整理して共有させて頂きます。

「調査」というプロセスそのものは、あらゆる業務で必要かと思います。
ここでは派生開発という文脈でそのプロセスを考察し、改善案の導入を試みます。

###参考文献
こちらの論文を拝読しました。
ただし、本記事の内容は論文そのままではなく、少し執筆者個人の見解を混ぜています。
https://www.juse.or.jp/sqip/workshop/report/attachs/2014/sqip6-a.pdf

##背景：不具合分析から見える開発プロセス上の問題点
各開発プロセスにおける不具合の関連、影響は以下のようになっています。
※ここではテスト設計などの工程は含まれていない

（A）変更要求（要求分析）の問題：変更要求を正しく捉えられなかったことに起因する不具合
　　　 不具合発生率：低い
　　　 手戻り工数：小さい
（B）変更内容（仕様設計）の問題：変更仕様を正しく設計できなかったことに起因する不具合
　　　 **不具合発生率：高い**
　　　 **手戻り工数：大きい**
（C）調査方法の問題：変更の影響範囲の特定、変更による影響を正しく洗い出すことができなかったことに起因する不具合
　　　 **不具合発生率：高い**
　　　 **手戻り工数：大きい**
（D）実装の問題：正しく実装できていなかったことに起因する不具合
　　　 不具合発生率：低い
　　　 手戻り工数：小さい

「B」と「C」はともにQCDへ与える影響が大きいようです。
「B」に関しては、派生開発に特化したプロセスであるXDDPによって解消する可能性があります。
そこで今回は「C」を解消するためのプロセスを説明していきます。

#派生開発における調査プロセス上の問題点とそれに対する解決策
派生開発の調査プロセスにおいて、問題点は2つあります。
それぞれ、提言を述べた後に問題点を説明していきます。
　1．調査時のソースコードリーディング（深さ優先探索 vs 幅優先探索）
　2．調査目的の整理、調査結果の記録

##1．調査時のソースコードリーディング（深さ優先探索 vs 幅優先探索）
ソースコードリーディングをする際は、1つの関数を最後まで見てから次の関数を見るべきです。
調査している関数内に新たな関数が現れても、個々の関数ごとに最後まで調査するアプローチです。
つまり以下のようにしましょう。
`ソースコードリーディングは、深さ優先探索ではなく幅優先探索で行う`

これはソースコードリーディングに関する多くの記事で言われていることで、XDDPでも推奨しているアプローチです。
初めから詳細に処理を追っていくアプローチは、あまり効果的ではありません。
※もちろん、既にある程度把握しているソースコードが対象であればこの限りではない

1つの関数毎に処理内容を調査するため、関数の構造図やPADをスムーズに作成できます。
そのため、調査進捗が明確に表現でき、調査の中断/再開や引継ぎが容易になります。

一方、深さ優先探索は、関数が現れるたびにその関数の中に次々と入って調査を行います。
深さ優先探索の問題点を4つ記載します。

###深さ優先探索の問題点
#####問題点1：処理の捉え方による問題
以下2つの探索法は、それぞれ処理の捉え方が異なります。
`A．幅優先探索 ・・・ 処理を構造（面）で捉える`
`B．深さ優先探索 ・・・ 処理を順番（線）で捉える`

このことから、BはAに比べると調査時の視野が狭くなります。
そのため、より効果的な変更箇所が他に存在することに気付けない可能性が高くなってしまいます。

また、Bだと関数群の役割を把握できないため，変更に対する影響箇所の特定が困難になります。
※一般に、機能を実現するのに 10 数個から数 10 個の関数がそれぞれの役割を分担して組み立てられていると言われている

#####問題点2：処理の把握コストに関する問題
深さ優先探索だと、複数の関数を往来するなど、ソースコードを辿ることに時間がかかります。
対象の関数ネストに対して、脳内メモリのスタックを割り当てることになるため、調査時の負荷も大きくなります。

#####問題点3：目的の異なる調査を同時実施することによる問題
変更箇所や方法によって影響を受ける箇所が変わります。
そのため、調査は「変更箇所の特定」⇒「影響を受ける箇所の特定」の順に実施する必要があります。
しかし深さ優先探索での調査では、目的別に調査を区別して実施できません。
そのため、変更箇所が変わった時、それによる影響箇所の変化に気付かず、影響箇所を誤認してしまったり、抜けてしまったりします。

#####問題点4：調査結果に関する問題
深さ優先探索では、調査している関数の中に新たな関数が現れると、その関数の中に入っていくことになります。
そのため、調査時に辿った経路を記録することしかできません。
これでは、調査結果がレビュー時や次の派生開発時にも使えるような調査資料になりません。

##2．調査目的の整理、調査結果の記録
目的が異なる調査を同時に行ってしまうことで、調査結果がQCDに致命的な影響を与えてしまいます。
そこで、目的ごとに調査を3フェーズに分けて行いましょう。
`A．事前調査：システム構造を理解するための調査`
`B．変更箇所特定調査：変更箇所を特定するための調査`
`C．影響調査：影響範囲を特定するための調査`

###A．事前調査
要求内容、そして開発対象システムを理解するために実施します。
予め知っておくべきシステムの構造や動作を把握する調査、調査範囲を決めて調査し、成果物を残します。
この調査では、変更箇所を特定しません。
つまりソースコードの詳細を理解するフェーズではありません。

構造図を作成する際には、1つの関数に対して1分程度の時間となります。
調査対象の関数の数と調査に使える工数から、どの程度の数だけ関数を調査できるかを計算し、調査範囲を決定します。

※1つの関数が大きい場合はより時間がかかるが、それは設計の問題である

###B．変更箇所特定調査
変更要求を実現するために必要な、システムの変更箇所を特定するために実施します。
※XDDPの「スペックアウト」に相当する

ソースコードを追って、詳細を理解しながら変更箇所を探します。

###C．影響調査
システムの変更によって、影響が及ぶ箇所を特定するために実施します。
※XDDPの「スペックアウト」に相当する

変更方法や変更箇所によって影響の内容が変わるため、変更箇所特定調査が完了した後に実施します。

#まとめ
`1．ソースコードリーディングは、深さ優先探索ではなく幅優先探索で行う`
`2．調査は、「事前調査」⇒「変更箇所特定調査」⇒「影響調査」の3フェーズに分けて行う`

ソースコードリーディングの方法論については、別途記事にする予定です。
[Golang] enumを使いたい ~ structでも定数定義できるぞ

元々Javaエンジニアの私ですが、最近Goを趣味で使い始めたのでメモ程度に。
今回はJavaでよく使うenumをGoでもそれっぽく使う方法を残しておきます。

## まずは基本的な使い方
よくGoogleで検索して見かけるやつ

```hoge1.go
package constant

// 自動で採番してくれる
const (
	HOGE1_1_1 = iota // 0
	HOGE1_1_2 =      // 1
	HOGE1_1_3 =      // 2
)

// 1始まりにしたい
const (
	HOGE1_2_1 = 1
	HOGE1_2_2 = 2
	HOGE1_2_3 = 3
)

// 文字列で定義したい
const (
	HOGE1_3_1 = "hoge1"
	HOGE1_3_2 = "hoge2"
	HOGE1_3_3 = "hoge3"
)

// 基本型をベースにした独自の型で定義したい
type HOGE uint8
const (
	HOGE1_4_1 HOGE = 1
	HOGE1_4_2 HOGE = 2
	HOGE1_4_3 HOGE = 3
)
```


大体の定数って数値か文字列のどれかで扱うことが多いので以上のような定数宣言をよく見かける。


## struct（構造体）でも宣言がしたい！ でもうまくいかない。
そう思ってこう書きがちですが...

```hoge2_ng.go
package constant

type Hoge2NG struct {
	Code uint8
	Name string
}

const (
	HOGE2_NG1 = Hoge2NG{Code: 1, Name: "hoge1"}
	HOGE2_NG2 = Hoge2NG{Code: 2, Name: "hoge2"}
	HOGE2_NG3 = Hoge2NG{Code: 3, Name: "hoge3"}
)
```
もちろん、これではダメです。

## ではどうするか？
こうしちゃう!

### 結論

```hoge2_ok.go
package constant

type hoge2OK struct {
	code uint8
	name string
}

var (
	HOGE2_OK1 = hoge2OK{code: 1, name: "hoge1"}
	HOGE2_OK2 = hoge2OK{code: 2, name: "hoge2"}
	HOGE2_OK3 = hoge2OK{code: 3, name: "hoge3"}
)

func (v *hoge2OK) Code() uint8 {
	return v.code
}

func (v *hoge2OK) Name() string {
	return v.name
}

func GetHoge2List() []mobileNetwork {
	list := make([]mobileNetwork, 0)
	list = append(list, HOGE2_OK1)
	list = append(list, HOGE2_OK2)
	list = append(list, HOGE2_OK3)
	return list
}

func GetHoge2Name(code uint8) string {
	list := GetMobileNetworkList()
	for _, v := range list {
		if code == v.code {
			return v.name
		}
	}
	return ""
}
```

### 解説
まずは「定数 = const」という考え方をやめます。
定数をvar(変数)として宣言してしまうことでstructで宣言することが可能になります。
ここでのポイントが、struct宣言の時は外部参照できないように先頭小文字、structのフィールドも先頭小文字で定義します。

``` go
type hoge2OK struct {
	code uint8
	name string
}

var (
	HOGE2_OK1 = hoge2OK{code: 1, name: "hoge1"}
	HOGE2_OK2 = hoge2OK{code: 2, name: "hoge2"}
	HOGE2_OK3 = hoge2OK{code: 3, name: "hoge3"}
)
```

でもこのままだと「codeだけ」「nameだけ」を取得したいといったことができなくなるので、外部からアクセスできる処理を追加します。

```go
func (v *hoge2OK) Code() uint8 {
	return v.code
}

func (v *hoge2OK) Name() string {
	return v.name
}
```
外部から使うときはこうすると各フィールドの値が取得できる。

```main.go
package main

func main() {
	constant.HOGE2_OK1.Code() // uint8(1)
	constant.HOGE2_OK1.Name() // "hoge1"
}
```

<strong>「でもenumのようにリスト取得できないじゃん!!」</strong>

と思ったそこのアナタ。
大変面倒ですがリスト取得用の処理を追加します。

```go
func GetHoge2List() []mobileNetwork {
	list := make([]mobileNetwork, 0)
	list = append(list, HOGE2_OK1)
	list = append(list, HOGE2_OK2)
	list = append(list, HOGE2_OK3)
	return list
}
```

そしてenumでもおまじないのように書かれている、「コードから名称を取得する処理」も一緒に追加。（いらなかったらなくてもOK）
既に追加したリスト取得用処理を使えば簡単にできます。

```go
func GetHoge2Name(code uint8) string {
	list := GetMobileNetworkList()
	for _, v := range list {
		if code == v.code {
			return v.name
		}
	}
	return ""
}
```

### 番外編
Googleで検索かけると「コードから名称を取得する処理」でこんなコードが出てきますが...

```go
func GetHoge2Name(code uint8) string {
	if code == HOGE2_OK1.code {
		return HOGE2_OK1.name
	}
	if code == HOGE2_OK2.code {
		return HOGE2_OK2.name
	}
	if code == HOGE2_OK3.code {
		return HOGE2_OK3.name
	}
	return ""
}
```

事故りそうだしこんなの書きたくない！！
通信：国際規格と関連規格類



<この項は書き書けです。順次追記します。>

# 誤解、偏見、

国際規格で、通信規格、プログラミング言語規格に対する偏った意見は主に3つあるらしい。
しばしば真逆な見解に出くわすことがある。

国際規格が非関税障壁になっている。
未定義、未規定は欠陥である。
正しいことが大事だ。

##  非関税障壁

国際規格は非関税障壁を作らないように、技術仕様議論の出発点として国際合意を成文化したものである。

成文法は、慣習法を超えるものではないことは、しばしば成文法の中に記載している。


権利と義務の前に。仮説（147）

https://qiita.com/kaizen_nagoya/items/47d4e992d0fd340403fd

 国際規格を読む前に
 
 https://qiita.com/kaizen_nagoya/items/3917eb7b7c3a3a3cb4e0

国際規格のNormative Reference

https://qiita.com/kaizen_nagoya/items/b94b6055997119ac2d9a

プログラマが知っているとよいかもしれない法律1000を目標に収集中。

https://qiita.com/kaizen_nagoya/items/eeffde5e7ee049f0adeb

##  技術発展を阻害しない

未定義、未規定が、CPU の発展を阻害しないように積極的に定義しないでいることを、何か定義できないとか、規定できないという不定義、不規定と違う解釈をされていることがある。

C言語：未定義、未規定、処理系定義

https://qiita.com/kaizen_nagoya/items/f416efd38aaaec7f8230

C言語（C++)に対する誤解、曲解、無理解、爽快。

https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

##  正しいことが大事ではなく、時間が間に合うことが大事

国際規定の間に、整合性があるかだけを問題にすることがあるかもしれない。

通信が無限時間後に終了するのは意味があるとは思えない。

正しいことが大事なのではなく、時間内に到達することが大事。


# 国際規格

ISO

IEC

ITU

## 関連規格

IEEE

EIA・TIA

IETF

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
[Unity]実行画面を動画撮影する

#概要
元々はUnity Recorderという名前でしたが、いつの間にかRecorderに名前が変わっていました。実行画面を動画保存できる公式ツールです。
#本文
Window > PackageManagerからRecorderをインストールします。
![スクリーンショット 2022-02-19 22.12.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4c23d4dc-fa00-8733-ffa2-a7e82da1f79d.png)
Window > General > Recorder > Recorder Windowで設定画面を表示します。
![スクリーンショット 2022-02-19 22.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/102a65c9-8d22-9584-b1a1-1b7ff732b04c.png)
Add RecorderからMovieを選びます。
![スクリーンショット 2022-02-19 22.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/fa21d376-fa12-d93f-0f82-2c729c063273.png)
色々設定項目が表示されますが、デフォルトのままでも大丈夫だと思います。START RECORDINGで録画が開始してSTOP RECORDINGで終了します。
デフォルトのままなら、作業中のプロジェクトのRecordingsフォルダ内へ動画ファイルが連番になって保存されていきます。
【重要】Google colabでgdown使用時のエラー

#1.はじめに
　 ディープラーニングの学習済みパラメータなど大容量のファイルをダウンロードするときに、該当ファイルを google drive に保存しておき、共有リンクを使って **gdown** でダウンロードする手法がよく使われます。
　しかし、google colabではこの手法が、2022.2.17頃から正常に動作しなくなり、下記のようなエラーが発生しています。
　最近は、githubに掲載されているリポジトリの多くはgoogle colabの形式でも提供されていて、それらがgdownを使っていると全て影響を受けていると思われます。

```
Access denied with the following error:
 	Cannot retrieve the public link of the file. You may need to change
	the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
	 https://drive.google.com/uc?id=1Yr7KuD959btpmcKGAUsbAk5rPjX2MytK 
```
　
#2.対策
**import gdown** の前に、下記コマンドを追加します。これによって、google colabに最新バージョンのgdownがインストールされ、gdownが正常に動作します。

```python
! pip install --upgrade gdown
```

#3.推定原因
　googleがgoogle driveのダンロードに関して何らかの仕様変更を行なったために、google colabにインストール済みのgdownのバージョンとの互換性がなくなったと思われます。
　google colabにインストールされているgdownを早く最新版にして欲しいところです。googleさん、よろしく！
カラーコーディネーターアドバンスクラス合格体験記

先日カラーコーディネーターアドバンスクラスを受験し、無事合格しましたので、
受験の経緯、試験の概要、実際の私の勉強方法について記録を兼ねて共有できればと思います。
(受験者がそう多くはない資格なので、少しでも参考になれば幸いです)

# 【簡単に自己紹介】
□文系出身、未経験でIT系会社に入社した社会人2年目。
□普段はフロント寄りのシステム開発業務。
□カラーコーディネーターや色彩検定等は勉強したことがなく、知識ゼロ。

# 【受験の経緯】
□UIやUXに関心があり、人の認知の部分に興味を持ったから。
　…現在フロント寄りの業務を担当させていただいており、特にUIの分野に興味がありました。
　　せっかくなら”人の見え方”の部分を少し体系的に学習してみたいと思いました。
□自分の進路に悩んでいるから。
　…今後のキャリアについて自分のありたい姿がイマイチ明確には思い描けていないです。
　　フロント寄りの業務に興味はあるが、それが本当に自分のやりたいことなのかがピンときていないため、自分の適性確認を兼ねてさわりだけでも触れてみようと思いました。

#【試験の概要】
□仕事に役立つ実践的な色彩の知識を学ぶことができる試験。
□スタンダードクラスとアドバンスクラスの2クラスに難易度が分かれている。
□試験時間は90分。
□70/100点が合格ライン。
□受験料は7,700円(税込)。
□試験形式はIBT方式またはCBT方式。(私はCBT方式で受験しました)
(公式サイトは[こちら](https://www.kentei.org/color/))

# 【勉強方法】
#### ひたすら公式テキストを熟読(!?!?!?)
2020年にリニューアルされたばかりとのことで、私の受験時はまだ問題集や過去問集等は販売されていませんでした。
そのため、公式で出ているテキストを徹底的に読み込むスタイルで勉強しました。
アウトプットのチャンスがなかなかなく、やや不安な状態で当日試験に臨みました。
現在は問題集が発売されているようなので、アウトプット用にあるとより安心して受験できるのではないかと思います。

そして肝心のテキストなのですが………とにかく分厚くて読みづらかったです……
色のバランスや見え方等、実践的な内容は読んでいて面白かったのですが、章によっては生物や世界史のような内容がメインで書かれており、個人的にはとっつきにくいものもありました。(そしてそういう章に限ってページ数が多かったり…)
トータルで4周することでなんとか頭には入りましたが、一筋縄ではいかなかったです。(勉強時間としては30時間弱)

# 【試験本番】
□試験申し込み後しばらくして届いたカラーチャートを持ち込みました。(持ち込むことが公式で許可されています)
□4択の選択肢から適切なものを選んでいく形式のため、多少はあやふやでもごり押しは可能でした。(本当はダメだヨ)
□90分の試験時間だが、見直しを含めてもそんなに時間はかかりませんでした。(私は20分くらいで解答完了し退席しました)
□公式テキストの文章の一部がそのまま出題され、虫食い部分を埋めていくタイプの問題が多かったように思います。

# 【最後に】
□直前で詰め込んだこともあり、ギリギリの点数(78点)で合格しました。
□色に関する知識を浅くですが勉強することができ、やってみて非常によかったなと思いました。
 普段の業務ですぐに活かすのは難しいかもですが、ふと町を歩く中でも色に対する見方が変わったように思えてとても楽しいです。また、自分のキャリアを考えるうえでも1つの指標となるような学習だったと思います。
□色彩系の知識がほとんどない方でも、きちんとテキストさえ読み込めば合格は可能かなと思います。
 (私はいきなりアドバンスクラスの勉強をしてやや大変だったので、余裕があればスタンダードクラスから受験してもいいかなと思います。)
Azure AD B2Cでデバイスコードフロー実装のサンプルを紹介

# はじめに

2019 年 8 月に公開された RFC 8628（OAuth 2.0 Device Authorization Grant）、いわゆる『デバイスフロー』（Device Flow）について説明します。


#デバイスコードフローとは

Web ブラウザ非搭載のデバイスや、文字入力が困難なデバイスが API クライアントとなる場合に、
ユーザーの承認に基づいてアクセストークンを発行する認可フローです。
例えば、スマートテレビでNETFLIXなどにログインしようとする際にログインIDやパスワードを求められた際、スマホなどの別の端末で代わりにログインできるフローのことを指します。
図で表すと以下のような形となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517906/d63b59f0-8f54-cb87-eec8-b5afc4c849bd.png)

# 実際に実装してみた
以下githubに上がっているサンプルソースがあったので、Azure ADB2Cと繋げて実装することができます。
https://github.com/ltwlf/azure-ad-b2c-device-flow

シーケンス図がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517906/44cc5d7c-7e5f-042f-7c96-93941a3f3f07.png)


以下、デバイスクライアントから認可サーバーに対してのリクエストとレスポンスをまとめています。
### デバイス認可リクエスト
```
POST /device_authorization
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

client_id=1406020730&scope=example_scope
```
### デバイス認可レスポンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517906/96b6f7dc-1fef-62ee-26a1-523e859e1630.png)
レスポンス例

```
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"device_code": "4e3ac03a-ad18-4f10-973a-535e473245c2", 
"user_code": "487019",
"verification_uri": "http://localhost:7071/api/user_code_get", 
"expires_in": 300
}
```

### トークンリクエスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517906/1d03a0e9-ab36-88f0-6428-9e32d9d2ea5c.png)

リクエスト例

```
POST /token
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

client_id=140612899&grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=993124a9-e905-43b1-b21e-0845a25228a5
```

### トークンレスポンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517906/6dbf4c05-5a82-362b-179f-b6d22bbc6f9f.png)


レスポンス 成功例

```

{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkFVQTV5Uy...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJraWQiOiJiU0NITG1NZGNjMW5fdnlaRXhacjkyakNTTzI3YkdTaX...",
"scope": null
}

```

レスポンス authorization_pending例

```
HTTP/1.1 400 Bad Request
Content-Length: 33
Content-Type: application/json; charset=utf-8
Set-Cookie: ARRAffinity=dd716a6def04e48f4e433f7740cecb7f8a4f1c77d318c5480b769fc5157ad936;Path=/;HttpOnly;Domain=service-device-auth-flow.azurewebsites.net
Date: Wed, 30 Sep 2020 12:37:11 GMT

authorization_pending
```

レスポンス expired_token例

```
HTTP/1.1 400 Bad Request
Content-Length: 13
Content-Type: text/plain; charset=utf-8
Set-Cookie: ARRAffinity=dd716a6def04e48f4e433f7740cecb7f8a4f1c77d318c5480b769fc5157ad936;Path=/;HttpOnly;Domain=service-device-auth-flow.azurewebsites.net
Date: Wed, 30 Sep 2020 12:44:33 GMT

expired_token
```
サンプルのソースにはトークンリクエスト時authorization_pendingとexpired_tokenのどちらかが予期されるエラーコードとして返されます。
authorization_pendingは、ユーザーの承認/否認処理が完了するまでトークンエンドポイントはこのエラーを返し続け、expired_tokenは、その名の通り有効期限が切れた際に返されるエラーです。
よって成功応答を受け取るか、authorization_pending以外のエラーコードを受け取った場合、クライアントアプリからのトークンリクエストは終了します。
jupyterlabの設定

Windows10でjupyterlab環境を構築した際の設定についての備忘

#起動時のデフォルトディレクトリ変更
configファイル生成のため、コマンドプロンプトを起動して下記を実行する。

```
jupyter lab -–generate-config
```
すると、`C:\Users\USERNAME\.jupyter`に`jupyter_lab_config.py`が作成される。
生成されたファイルの900行手前付近の、下記のパラメータを編集すればよい。
文字列の先頭の`r`はraw文字列の利用を宣言するものである。Windowsパス特有の円マークを、エスケープ文字でなく単なる文字として扱うために必要となる。

```config:jupyter_lab_config.py
c.ServerApp.root_dir = r'C:\Users\YOUR\DEVELOP\FOLDER\PATH'
```

#jupyterlab起動ショートカットアイコンの作成
###やりたいこと
これまではjupyterlabを起動するために、毎回コマンドプロンプトを起動して`jupyter lab`と打ち込んで起動していた。まずこれが面倒になってきたので何とかしたいと思った。
また通常だとブラウザの1つのタブとして起動するが、独立したウィンドウで開くことはできないかと考えた。
特に、Chrome独自のショートカット機能「ウィンドウとして開く」が非常に利便性が高く、画面表示をすっきりさせることができるため、うまく連携する方法を考えた。
まとめると、
> デスクトップ上のjupyterlabショートカットをクリックすると、Chrome「ウィンドウとして開く」版のUIで起動できるようにする

ことを実現したい。

###設定
- まず通常通りコマンドプロンプト経由で`jupyter lab`コマンドを実行し、jupyterlabを起動する。
- Chromeの画面右上の3点ボタン設定マークを選択し`その他のツール`->`ウィンドウに名前を付ける`を選択。名前は適当にjupyterlabとする。
- デスクトップにjupyterlabのショートカットアイコンが作成されたことを確認する。
- 下記のように`jupyter_lab_config.py`設定ファイルを編集し、`jupyter lab`コマンド実行後にブラウザを表示しない設定をする。(コメントアウトを外す)
 
```config:jupyter_lab_config.py
c.LabApp.open_browser = False
```
- ショートカットアイコンを右クリックし、プロパティを表示する。そしてリンク先を次のように設定する。

```bat
C:\Windows\System32\cmd.exe /k mode 50, 20 | jupyter lab | "C:\Program Files\Google\Chrome\Application\chrome_proxy.exe"  --profile-directory=Default --app-id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
このうち、

```bat
"C:\Program Files\Google\Chrome\Application\chrome_proxy.exe"  --profile-directory=Default --app-id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
の部分は元から設定されているリンク先の記述であり、

```bat
C:\Windows\System32\cmd.exe /k mode 50, 20 | jupyter lab | 
```
の部分を先頭に追記してあげればよい。
コマンドの意味合いとしては、

1. `cmd.exe`を利用しコマンドを実行する。`/k`は起動元のコマンドプロンプトの画面を閉じないためのオプションである(jupyterlabがエラーを吐いた時等のデバッグ用に念のため表示させておく)。
1. `50, 20`はコマンドプロンプトのウィンドウサイズなのでお好みで。
1. パイプして、`jupyter lab`コマンドを実行。先述のconfig設定のため、この段階ではブラウザ画面は表示されない。
1. ここまででバックグラウンドでjupyterlabが起動した状態となり、最後のパイプでchrome特有の「ウィンドウとして開く」モードで開く形となる

以上の設定で、ショートカットをクリックするだけで簡単に起動するようになった。
Qiita Advent Calendar Online Meetup を見てのまとめと感想 (2022/01/21開催)

### ちょまどさん(息を吐くように記事を書け)
##### 内容
- 記事を書くメリット
    - 恩返し (記事を書き、記事を見て助け合っている)
    - 記憶の定着につながる
    - 自分用メモ
    - ポートフォリオになる
    - 同じ「沼」の人と繋がれる

- 大事なこと
    - **書きたいものを書く**
    - 学び続けることの楽しさと苦しさ

- ちょまどさんが紹介してた記事 (今回の登壇者が書いた記事)
    - [【新人プログラマ応援】学習用のプログラムと仕事で書くプログラムは何が違うか](https://qiita.com/jnchito/items/c9ca22efa270ff1b7f3d)
    - [無職 やめ太郎（本名）](https://qiita.com/Yametaro?page=1)
        - ●歳娘「パパ、〜〜」シリーズ
    - [エラトステネスの篩の活用法を総特集！ 〜 高速素因数分解・メビウスの反転公式 〜](https://qiita.com/drken/items/3beb679e54266f20ab63)

##### 感想
書きたい記事を書くべしとのことだったので、この記事を書いてみた。
(ちょまどさんは、こういう記事を書いて欲しかったわけではないのかもしれないし、そうじゃないかもしれない。。。けども書きたいので書く!)



### スポンサーセッション (twilio)
##### 内容
- TwilioQuestというエンジニア知識が学べるゲームの紹介(無料)
    - 日本語版もある
        - https://www.twilio.com/quest/ja

##### 感想
グラフィックも音楽も好きな系統だし楽しそうなので、やってみる。
(ずっと触ってないpythonとか書き方忘れたので、思い出すのも兼ねて触ってみる)

ゲームもあまり最近できていないのを思い出した。
英語でプレイすれば、遊びながら英語も学べるので、英語でプレイしてみる。

### qiitaについての話
##### 内容
- 物理鈍器(表彰トロフィー)が届くようになった 
    - contributionが高い人に送られる?

## まとめ

- 書くの疲れてしまったので、あと気になる方は是非動画を見てください！
    - (youtubeにアーカイブありました)
        - https://www.youtube.com/watch?v=psMKkDa61_E

## 本当のまとめ
[千代田まどか](https://www.google.com/search?q=%E5%8D%83%E4%BB%A3%E7%94%B0+%E3%81%BE%E3%81%A9%E3%81%8B&rlz=1C5GCEM_en&ei=3pfqYby7PNfAoATgnIugCw&oq=tiyoda+%E3%81%BE%E3%81%A9&gs_lcp=Cgdnd3Mtd2l6EAEYADIHCAAQgAQQBDIHCAAQgAQQBDIHCAAQgAQQBDIGCAAQBBAeMgYIABAEEB4yBggAEAQQHjIGCAAQBBAeMggIABAFEAQQHjoHCAAQRxCwAzoNCAAQgAQQsQMQgwEQBDoLCAAQgAQQsQMQgwE6BggAEAQQAzoKCAAQgAQQsQMQBDoHCAAQsQMQQzoECAAQQzoKCAAQsQMQgwEQQ0oECEEYAEoECEYYAFCJF1iBLmDaRGgBcAJ4AIAB8QGIAeMMkgEGMC4xMC4xmAEAoAEByAEKwAEB&sclient=gws-wiz)さんが可愛かった
Javaのモジュールについてまとめてみた

Javaのモジュールシステムについてまとめてみました。

Java9から実装された機能なのでかなり古いですが、やってみます。

# Javaのモジュールシステムとは

```
・パッケージの依存関係を簡潔に整理させる
・パッケージのアクセスを制御することができる
```

これらの利点を得るためにJava9で実装されたものです。
これにより、不用意に他のプログラムからのアクセスを拒否することができます。そうして
「え、このコード動かして実装してみたら他のところでバグが起きちまった!クソスパゲティーコードが!!!!」
といったことがなくなります。筆者もmoduleではないですが、コードを書いていたら別のところがバグってしまい、「そこにアクセスするんじゃねぇよ」と思った経験があります。
そういたことを防ぐためにあるわけですね。

Java9よりも細かくアクセスできるスコープを設定できます。具体的には

```
・今作業しているモジュールの中でだけpublic
・指定したモジュールに対してだけpublic
・すべてのモジュールに対してpublic
```

ということができます。

そして、Java9ではすべての標準ライブラリもmodule化されています。

# moduleの定義の仕方

```
module モジュール名{
        処理
}
```

## moduleの中に書く内容

この中で、`System.out.println()`とか書いてはいけません。
これをやりたいのであればmoduleではなくインターフェースを使いましょう。
moduleの中に書く内容は、あくまでもパッケージやライブラリを参照させるのか、参照させないのか、はたまた参照するのかなので、それについては今から説明します。

中に各処理としては主に三種類あります

・requires宣言
・requires transitive宣言
・exports宣言

です。
これからそれらについて詳しく解説していきます。

## requires宣言
デフォルトではすべてのmoduleは他のmoduleに対してアクセスする事はできません。
しかし、requires宣言することで、別のmoduleを使用したい時に使用することができるようになります。
書き方としては以下です。

```SampleModule.java
module SampleModule {
    requires java.net.http;
}
```

これで`ava.net.http;`をSampleModulesに依存させることができます。ちなみにこれはHTTPリクエストに対するmoduleです。
ただ、これではmoduleAに対してmoduleBの持っているmodleCを依存させたい場合、moduleAはmoduleCに対して直接requiresを宣言させ無いといけません。
これをしてしまうと、moduleAとmoduleCの関係をmoduleの名前からわかりやすく理解させることが難しくなってしまうし、moduleCだけでは足りなくてmoduleBにもrequires宣言をしないと行けなくて、結果的にコードの全体図が把握できないなどの弊害も出てきてしまいます。

その解決方法を次に解説します。

## requires transitive宣言

こちらを使うことで、moduleAに対してmoduleBを介して、moduleCの内容を参照させる事ができるようになります。

イメージとしては踏み台サーバーのようなものです。

書き方としては以下です

```SampleModules.java
module SampleModule {
    requires transitive java.net.http;
}
```

になります。
先程のrequires宣言にtransitiveをつけるだけです。
こうすることで、先程の問題を解消することができます。
ちなみにこうしてmoduleを介して別のmoduleの内容を参照させることを、

```
推移的な依存関係を宣言する
```

といいます。

そして、ついに最後になった宣言のやり方を解説していきます。

## exports宣言

デフォルトでは、moduleはmoduleの外からはアクセスできない様になってします。
それを、どこまで公開するのかを調整するのが、exports宣言です。

まずはじめに、全体に対して公開するやり方について説明していきたいと思います。

やり方としては、

```SampleModule.java
module SampleModule {
    exports com.example.hoge.huge;
}
```
この`com.example.hoge.huge`の部分を参照させたいmoduleの名前に変えるだけです。
こうすることで、ｍｏｄｕｌｅの外からのアクセスをすべて許可します。

しかし、コーディングのルールによってはすべてのアクセスを許可する場合でもどこからの参照を許可するのかを明示的にしないといけない場合もあると思います。
なので、今からそのアクセスを制限するやり方について説明していきたいと思います。

やり方は以下です。

```SampleModules.java
module SampleModule {
    exports com.example.hoge.huge to aaa, bbb;
}
```

このように、`to`を使ってつなげ、aaaとbbbの部分を指定したいmoduleの名前に変えるだけです。
こうすることで、指定した場所にのみmoduleを公開することができました。

今回は以上になります。
ありがとうございました。