OmniAICreator/Qiita-1.07M huggingface dataset:
【CSS】マウスカーソルを指マークに変更する方法

　一般的なブラウザでは、リンクの上にマウスカーソルを載せると指マークになります。しかし、CSSやJavaScriptなどでボタン的な機能を実装する場合、divやp要素などaタグ以外のHTML要素についてもマウスカーソルを指マークにしたい時があります。
そのため、今回は、CSSでマウスカーソルを指マークに変更する方法について解説します。

# CSSでマウスカーソルを指マークに設定
  CSSでマウスカーソルを指マークに設定するには、「cursor」プロパティで「pointer」を指定します。

```style.css
div {
  cursor:pointer
}
```

IEの独自指定として「hand」というものもありましたが、現在は「pointer」のみの指定で問題ないかと思います。

#　サンプルコード
CSSプロパティ「cursor」を利用した、サンプルコードです。

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div id="pointer">提出</div>
  </body>
</html>
```

```style.css
#pointer {
	width: 200px;
	margin: auto;
  background-color: #fba;
	font-size: 40px;
  text-align:center;
	cursor: pointer;
	border-bottom:4px solid #daa;
}

#pointer:hover {
	opacity:0.6
}
```
![カーソル指マーク.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/d3bb694b-f985-0271-d8a6-881dde310d84.jpeg)

cursorプロパティの値ですが、pointer以外にも色々あるので、場合によって値を変えるとより利便性が増すと思います。
チーミング とは

## 勉強前イメージ

bondingに似たようなやつ

## 調査

### チーミング とは

複数のNICを束ねて帯域を増加させ、NICの冗長化を図り耐障害性を高める技術。
あたかもNICが1つのように扱います。

### チーミングの種類

- フォールトトレランス

一つを稼働系・一つを待機系にして、障害が起こった際に自動的に待機側のNICに切り替わります。
基本的には稼働系がネットワークにつながっています。

- ロードバランシング

通信の負荷を分散することで、耐障害性を持たせる他にも
同時に利用して複数にNICに分けることが出来ます。
複数にNICを使用するので、一つに障害が起こった際でも通信を行うことが出来ます。

- リンクアグリゲーション

複数のNICを使用することによって全体の帯域幅を増加させます。
リンクアグリゲーション内のNICに障害が起こっても他のNICに自動的に切り替えます。

ただし、リンクアグリゲーションでは機器と機器で同じ設定を入れることが必要です。
また、SW間の設定はできないので1第で行う必要があります。

### ボンディングとの違い

Linuxでは `Bondingドライバ` を使用していることから
チーミングのことをbondingと呼びます。

## 勉強後イメージ

bondingの方を先に知ったけど、チーミング技術を使ったbondingなのね。

## 参考

- [チーミングって何？チーミングの種類3つや行う際の注意点を解説！](https://www.fenet.jp/infla/column/technology/228/)
- [teaming](https://www.infraexpert.com/study/etherchannel1.html)
PHP 正規表現を用いて文字列のマッチを判定する

# 目的

- PHPにて正規表現を用いた文字列評価の方法をまとめる

# 情報

- 下記のサービスを用いて動作を確認した。
    - [https://paiza.io/ja](https://paiza.io/ja)

# 方法

- `preg_match()`メソッドを使用する。
- 下記のように記載する。
- 例
    - `preg_match('正規表現', '評価する文字列')`
- 正規表現にマッチしていた場合は1が、マッチしていなかった場合0が返される。
- 具体例
    - 下記を実行した時は1が返される。

        ```php
        <?php

        echo preg_match('/(https?:\/\/[^\s]*)/', 'https://qiita.com/miriwo');
        ```

    - 下記を実行した時は0が返される。

        ```php
        <?php

        echo preg_match('/(https?:\/\/[^\s]*)/', 'test');
        ```
# 参考文献

- [https://www.php.net/manual/ja/function.preg-match.php](https://www.php.net/manual/ja/function.preg-match.php)
RaspberryPi 4B でZoneMinderを使用する Part6…アクセスのブロック

#全体の目次
[目標の設定と環境の準備](https://qiita.com/BUBUBB/items/b7f3eb0e16a1c1a938b2)
[ZoneMinderのインストール](https://qiita.com/BUBUBB/items/bdf6df6b1d0ee1e14bc0)
[ZoneMinderの全般設定](https://qiita.com/BUBUBB/items/9de905615f389fd9ed50)
[カメラの登録](https://qiita.com/BUBUBB/items/f9415bc8bc526d0d84a5)
[パフォーマンスの調整](https://qiita.com/BUBUBB/items/9f98c91479a2ab6d8c0c)
[アクセスのブロック](https://qiita.com/BUBUBB/items/dbc7d59065484cd32476)
[外部からのアクセス](https://qiita.com/BUBUBB/items/99174603530094e5f746)
[ZmNinjyaの使用（未)]()

#このページでやること

Tapoやimouでは、カメラから（おそらく）中国にあるサーバーに対して接続が行われる。Tapo（TP-Link）もImou（Dahua Technology)も信頼できる会社ではあるが、会社が信用できるだけでは納得できない。

ここでは、ネットワークルーターの設定を行い、カメラから外部に対するアクセスを禁止させる。

一般的に、普通のルーターであればデフォルトでは外部（カメラのメーカ）から、カメラに対して接続を開始することはできない。カメラ側からメーカに接続してそこから通信が行われる。そのため、カメラ→メーカへの接続をブロックするだけで十分。


#目次
[ファイアーウォールの設定](#ファイアーウォールの設定)
　[IPアドレスの確認](#ipアドレスの確認)
　[ファイアウオールの登録](#ファイアウオールの登録)
　[ポートの指定について](#ポートの指定について)
　[設定の確認][#設定の確認]

#ファイアーウォールの設定

多くのルーターにはファイアウオール機能が備わっている。ここでは、nuro光のF660Aの設定例を示す。

##IPアドレスの確認
これまでのステップで、カメラのIPアドレスが固定されている。
[RaspberryPi 4B でZoneMinderを使用する Part4…カメラの登録]() 

事前に、カメラのIPアドレスをすべて調べておく。

##ファイアウオールの登録

FT660Aでは、セキュリティ>IPフィルタ>Ipv4フィルタでファイアウォールが指定できる。指定は、カメラからの上りデータフロー（LANからインターネット）の方向のTCPアクセスをすべて禁止する、と指定する。

![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/dfd5974c-8aa2-3ce3-03cd-adb5403c8c8c.png)

|項目|設定値|意味|
|:--|:--|:--|
|有効にする|オン|この設定を有効にする|
|プロトコル|TCP|TCPのコネクションを禁止する。今のところ、UDPなどで通信するカメラを知らないが、TCP AND UDPやANYが指定できる場合それでも良い。（送信元ポート、宛先ポートを指定する場合、TCPにしておく必要がある）|
|名前|任意の名前|わかりやすい名前を付けておく。カメラの設定変更時などは、この設定を「無効」にしたうえで、メーカー提供のアプリケーションを使用する必要がある。その際に、「どれだったけ」とならないように、わかりやすい名前にしておく|
|送信元IPアドレス|カメラのIPアドレス|カメラのIPアドレスを指定する。開始と終了で範囲を指定できることもある。カメラのIPアドレスが連続していれば、ここで範囲を指定することで設定が1回で済む。|
|宛先IPアドレス|空欄|空欄にするとすべての宛先に対する通信が禁止される。特に必要が無ければ空欄にしておく。IPアドレスなどがわかっていれば、ここに接続先のIPアドレスを書いても良い。|
|送信元ポート|検討|状況に応じて検討する|
|宛先ポート|検討|状況に応じて検討する|
|着信インタフェース|LAN|着信をLAN、発信をWANに指定することで、上りデーターフローを指定できる。この指定は各製品のマニュアルを参照する|
|モード|拒否|拒否で良い|

##ポートの指定について

ポートの指定については、いくつかパターンが考えられる。Tp-link TAPOの例で考える。C-100やC-200が、中国のどのサーバーに、どうやってアクセスするか正確にわからない。
そのため、すべての外部通信を遮断する方法が最も高いセキュリティになる。

一方、Raspberry PIを使った監視カメラサーバーでは、ライブビューはサブストリームの低解像度に限定されている。そのため、高解像度のライブビューを家の外（スマホなど）から見るためには、RTSPビュアー[IPCam viewer](https://play.google.com/store/apps/details?id=com.rcreations.ipcamviewer&hl=ja&gl=US)などに対して、外部にrtsp(554)を公開する必要がある。

高いセキュリティが必要な場合、送信元ポート、宛先ポートとも空欄にしておく。外部に対するすべての通信が禁止される。

RTSPアクセスを外部に許す場合、送信元ポート、あて先ポートとも、１～550までを禁止する。これで、TP Linkに対して通信のイニシエーションが出来なくなる。（TP Linkのソフトウェアもカメラを見つけることが出来なくなる）　おそらく、これで十分だと思われるが、未知の方法で通信が行われる可能性も否定できない。

##設定の確認

設定が正しく行われているかは、Wifiをオフにしたスマホで、各カメラの専用ソフトウェア（Tapo ソフトウェアやimou Life）を起動しカメラのライブビューが表示できないことを確認する。また、アプリを再起動してカメラに接続できない（オフライン）状態になっていることを確認する。
![34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/f4edc600-481d-35d9-1fa1-d0b33be2b6f7.png)
【Blender】Blender2.9 水面をノイズテクスチャとバンプで手軽に作る方法

環境メモ
⭐️Mac OS Catalina
⭐️Blender2.94.4

↓↓↓完成内容
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/f59c264c-236f-1b3e-c5f6-fcad9802a3f5.png)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">🌊Blender🌊<br>🌊水面を✨ノイズテクスチャ✨とバンプ💕で手軽に作ってみたよぉ😊<br><br>↓↓作り方<a href="https://t.co/qNlnkkn9Y1">https://t.co/qNlnkkn9Y1</a><a href="https://twitter.com/hashtag/blender?src=hash&amp;ref_src=twsrc%5Etfw">#blender</a> <a href="https://t.co/5yk7YcsOuy">pic.twitter.com/5yk7YcsOuy</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1457800094548328451?ref_src=twsrc%5Etfw">November 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

shading画面を開く
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/d466b57c-1087-a5fd-a524-80fd15bb377c.png)

■ノイズテクスチャを設定する
「追加」-「テクスチャ」-「ノイズテクスチャ」
スケール5.0
細かさ2.0
粗さ0.4

■バンプを設定する
「追加」-「ベクトル」-「バンプ」
強さ0.8

パンプとプリンシプルBSDF
ノーマルで繋ぐ


完成！

水面の色を変えると、こんな感じになる
![スクリーンショット 2021-11-08 22.20.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/b367141e-5aa1-5158-c55f-d02f6c15559b.png)


類似記事
【Blender】Blender2.8で海の波を手軽に作る方法
https://qiita.com/nonkapibara/items/cb1f13c8ddb05bd95d03
Google Blockly環境構築

# Google Blocklyとは

Google BlocklyはGoogleがオープンソースとして提供しているライブラリです。
公式Web Siteは[https://developers.google.com/blockly](https://developers.google.com/blockly)です。
ビジュアルプログラミングとして有名なScratch([https://scratch.mit.edu/](https://scratch.mit.edu/))は実行ファイルを作成しますが、Google Blocklyはソースコードを出力します。
ただし、Google BlocklyはJavaScriptの出力も行えますので、作成したソースコードをブラウザ上で実行することも可能です。


# 環境構築
環境構築といってもnpmに登録されているため、node.js環境があれば特に何もしなくてもすぐに構築できます。


## docker環境構築、起動
私は独立環境が欲しかったため、docker上で環境作成していますが、Windows上のNode.jsでも問題ありません。すでにNode.js環境がある方はこの章はスキップしてください。


### Dockerイメージ構築
最小限のNode.js環境とするため、alpineベースにします。

```dockerfile:Dockerfile
FROM node:16-alpine

WORKDIR /app

RUN apk update && \
    apk add git  && \
    npm install -g npm
```


```docker:docker-compose.yml
version: '3'
services:
  app:
    build: .
    image: nodejs-blockly-image
    volumes:
      - ./app:/app
    ports:
      - "8100:8100"
    tty: true
```

イメージを構築します

```
mkdir app
docker-compose build
docker-compose up -d
```
### Docker起動

構築されたコンテナ名を確認します。

```shell
docker-compose ps
```

確認したコンテナ名でShellを起動します。


```shell
docker exec -it docker_app_1 sh
```


## docker環境構築(2)
Ubuntu環境で実行したときにエラーとなりましたので、Node.jsのバージョンアップの手順を含めた環境構築の方法も記述します。


### Dockerイメージ構築
Ubuntu環境にします。

```dockerfile:Dockerfile
FROM ubuntu:20.04

WORKDIR /app

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt update && apt upgrade
RUN apt install -y npm
RUN apt install -y git
RUN apt install -y curl

```


```docker:docker-compose.yml
version: '3'
services:
  app:
    build: .
    image: nodejs-blockly-image
    volumes:
      - ./app:/app
    ports:
      - "8100:8100"
    tty: true

```

イメージを構築します

```
mkdir app
docker-compose build
docker-compose up -d
```
### Docker起動

構築されたコンテナ名を確認します。

```shell
docker-compose ps
```

確認したコンテナ名でShellを起動します。


```shell
docker exec -it ubuntu_app_1 bash
```

Node.jsのバージョン管理をnvmで行います。


```shell
curl -o - https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
```

Blockly demo実行時にNode.jsのバージョンが12未満の場合にはエラーになりましたので、Node.jsをv12にアップデートします。

```shell
nvm install 12
```



## Blockly環境構築

Node.js環境構築できたら、Blockly環境を構築します。
また、http-serverもインストールしておきます。


```shell
npm install --save blockly
npm install -g http-server
```

### サンプルソースコード実行

githubからサンプルソースコードを取得します。

```shell
git clone https://github.com/google/blockly
```

サンプルソースコードをhttp-server上で実行します。

```shell
cd blockly
http-server -p 8100
```

## ブラウザ表示
上記で指定したポートに接続します。

`http://localhost:8100/demos/`

Blockly > Demosが起動します。
N進数bit全探索

N^M乗の全探索です

```C++
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
int N, M;
int flag[M];
void dfs(int C){
  if (C == M){
   //処理
  }
  rep(i, N){
    flag[C] = i;
    dfs(C + 1);
  }
}
signed main(){
  cin >> N >> M;
  dfs(0);
}

```
Slack ソケットモードの始め方（既存App移行編）

#RTMを使った既存Slack Appを移行したい

Slackを業務で使っているとSlack Botを作りたくなります。実際、どこの会社でも有益なSlack Botが複数活躍しているんじゃないでしょうか。

さて、そのSlack Botを作る際、チャンネルに流れるメッセージを起点にアクションを起こしたいことがありますよね。これにはRTM (Real Time Messaging) APIを使うのが一般的でしたが、RTMを置き換えるものとしてソケットモードというAPIが登場しています。

まだRTMの廃止時期がアナウンスされている状況ではありませんが、いずれRTMが使えなくなることを見越してソケットモードを調べておいた方が良さそうです。

そのような考えから、私はRTMを利用していたSlack Appをソケットモードに対応させました。その際、Slackの管理画面がわかりにくくて難儀したので手順をまとめます。

#Classic Appをアップデートする

実は最近Slack Appの仕組みも新しくなっています。最近のAppはGranular Permissionと呼ばれる細粒度の権限管理が導入されており、よりセキュアになっています。これに対して従来のAppはClassic Appと呼ばれています。

Classic appから新たなAppへの移行は専用の管理画面が提供されています。[Your Apps](https://api.slack.com/apps)から移行したいAppを選んで「Update to Granular Scopes」を選びましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46856/19fa4c84-073a-65fd-eab4-60c43698c745.png" width="75%">

この画面ではAppに与える権限を細かく設定できるので、不要な権限は削ってしまいましょう。権限の説明は[Permission scopes](https://api.slack.com/scopes?filter=granular_bot)に詳しく書いてあります。また、使っているAPIメソッドのドキュメントから必要なScopeを調べることもできます。（例：[reactions\.add](https://api.slack.com/methods/reactions.add)であればreactions:writeスコープが必要だとわかります）

次の画面は自分（またはAppをインストールした人）の権限をBotに渡す設定画面です。私の場合はBotユーザー権限だけで動くAppだったのでここは何も設定しませんでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46856/b8561350-a006-840e-5df4-7fbbaec3aa6d.png" width="75%">

次の画面で最終確認をします。注意書きに「アップデートするとRTM APIは使えなくなるよ」って書いてありますけど、構わずmigrateボタンを押します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46856/89871935-f142-06d3-5955-815628cda3c6.png" width="75%">

これで完成…かと思いきや、Appの再インストールが必要と言われるので、指示に従います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46856/6afdf4bb-2938-e49b-2f91-14003b8d38c4.png" width="75%">

これでAppの移行はできました。ソケットモードの有効化などは新規作成時と一緒なので、「[Slack ソケットモードの最も簡単な始め方](https://qiita.com/seratch/items/1a460c08c3e245b56441)」を参考にしてください。

# Botプログラム自体の移行

Appを更新してしまうとRTMが使えなくなるので、Botプログラムも更新する必要があります。

私の場合、Botプログラムを[slack\-go/slack](https://github.com/slack-go/slack)で記述しており、サンプルを真似る形でソケットモードに対応することができました。また、コードの変更量もそれほど大きくありませんでした。

ただし一点だけ注意点があります。RTMのときと異なり、ソケットモードではメッセージを受け取って3秒以内にackを返す必要があります。この制約があるため、イベントループ内で時間がかかる処理をしてはいけません。前のメッセージの処理に時間を使ってしまい次のメッセージ受け取りを3秒以上行わないようだとSlack側が受け取れなかったと判断し、同じメッセージが再送されてしまいます。結果、Bot側に同じメッセージが複数届くことになり、Botの処理が混乱してしまいます。

同じ理由で、イベントループ内でブロックの可能性があるコード（例：Goならチャンネル書き込み）を書いてもいけません。実は完璧なコードを書くのは意外と大変だという所感です。

（上記はslack-go/slackの実装に特化した問題かもしれません）

#参考記事

- [Slack ソケットモードの最も簡単な始め方 \- Qiita](https://qiita.com/seratch/items/1a460c08c3e245b56441)
- [Slack ソケットモードの最も簡単な始め方 \(Go 編\) \- Qiita](https://qiita.com/seratch/items/c7d9aeb60ead5c126c01)
- [Slack の RTM bot が実質機能しなくなることに合わせて Socket mode に移行する](https://zenn.dev/itkq/articles/1fcd9d8f9ac191)
iPhone用VCFファイル（電話番号一覧 連絡先）を作成する。 旧携帯から抽出したvcfファイルを加工

携帯電話やスマートフォンの連絡先をエクスポートするとvcfの拡張子が付いたテキストファイルが得られる。
ただし、バージョンや方言の問題で、他機種にインポートできないことがある。
ここでは、１．iPhoneでインポートするための最低限の仕様を考察。２．テキストエディタの置換機能で変換するための小技を記述する。
iPhone11,win10,秀丸エディタ
iCloud(ブラウザから）



##機種ごとの電話帳ファイルVCFファイルについて

####２G,３GケータイVCFファイル
マイクロSDカードや赤外通信、USB接続などでデータをエクスポート。

BEGIN:VCARD
VERSION:2.1
N;CHARSET=SHIFT_JIS:私の名前
SOUND;X-IRMC-N;CHARSET=SHIFT_JIS:ﾜﾀｼﾉﾅﾏｴ
TEL;CELL:08012345678
EMAIL;INTERNET:
X-CLASS:PUBLIC
X-GNO:0
X-GN;CHARSET=SHIFT_JIS:
ADR;HOME;CHARSET=SHIFT_JIS;ENCODING=QUOTED-PRINTABLE:;;;;;;
NOTE;CHARSET=SHIFT_JIS;ENCODING=QUOTED-PRINTABLE:
END:VCARD

####iPhoneのVCFファイル
iCloudの連絡先からエクスポート、インポートできる。

BEGIN:VCARD
VERSION:3.0
N:自宅;;;;
FN:自宅
X-PHONETIC-LAST-NAME:じたく
TEL;TYPE=HOME;TYPE=pref;TYPE=VOICE:050 123 4567
PRODID:-//Apple Inc.//iCloud Web Address Book 2201B9//EN
REV:2021-11-06T18:25:24Z
END:VCARD

####最低限の仕様にしたiPhoneのVCFファイル
BEGIN:VCARD
VERSION:3.0
N:自宅
FN:自宅
X-PHONETIC-LAST-NAME:じたく
TEL;TYPE=HOME;TYPE=pref;TYPE=VOICE:0501234567
END:VCARD


TEL;TYPE=HOME;は固定電話,
TEL;TYPE=CELL;だと携帯電話
電話番号の区切りのスペースは無くても大丈夫

X-PHONETIC-LAST-NAME:は無くても大丈夫だが、漢字ではあいうえお順に並ばないので使った方が良い。

##VCFファイルについて（UTF-8形式）
vcfファイルを編集・作成した後文字コードをutf-8にしないと文字化けするので注意。

各連絡先（レコード）はbeginとendではさまれている。複数件数の場合、単純に同じ繰り返しが続く。
BEGIN:VCARD
・・・・・
END:VCARD

VERSION:２．１と３．０があるらしい。

FN:フルネーム　iPhoneでは必須のよう
X-PHONETIC-LAST-NAME:アップルのふりがなの拡張記載らしい。

このあたりの記述は、アップルの方言の記載だと思う。
PRODID:-//Apple Inc.//iCloud Web Address Book 2201B9//EN
REV:2021-11-06T18:25:24Z

CHARSET=SHIFT_JISの記述も不要


##正規表現（検索文字を置換に使う）
ちょっと難しく感じたのが、
N:ネーム１　の記述を以下のように2行にしたかったFN:が必須なのでF:を重複して記載する方針

N:ネーム１
FN:ネーム１
X-PHONETIC-LAST-NAME:アップルのふりがな

正規表現を用いた以下の置換でうまくいった。（円記号は半角に修正のこと）
検索文字列：￥nN:(.+)￥n
置換文字列：￥nN:￥1￥nFN:￥1￥nX-PHONETIC-LAST-NAME:￥n

検索文字列の最初の￥ｎ（改行）が無いとすべての大文字のNを置換してしまうため必要。

変更したくない部分（レコードごとの人名など）を残すために、「タグ付き正規表現」を使う。
秀丸のヘルプから抜粋して引用-------
例えば、「ＡさんはＢさんの友達です」というような文章を、「ＢさんはＡさんの友達です」のように変換したい場合、
検索文字列： (.+)さんは(.+)さんの友達です 
置換文字列： ￥2さんは￥1さんの友達です 
　とすることで、「A」と「B」に相当する部分の入れ替えができます
ここまで引用--------￥記号は半角を使用のこと
一番目のカッコ（　）の中を￥１で覚えておいて、置換の時に使うことが出来る。
LPIC　level1 7日目

#初めに

LPIC試験の勉強をしていて、勉強したものをまとめています。
ご指摘等ございましたらご教授下さい。

#プロセスとジョブ

##プロセスの管理

###プロセスとは?


メモリ上で実行中のプログラムをプロセスと言います。
psコマンドで表示できます。

ps [オプション]

プロセスを起動すると、プロセス毎に固有のID番号が割り当てられます。
これをプロセスID(PID)と言います。

システム上で実行されているプロセスを全て表示するには、auxオプションを付けます。
しかし、psコマンドでは、オプションに「-」を付けません。

###プロセスの表示

プロセスは、実行中の他のプロセスから起動されます。
これをフォークと言います。起動元のプロセスを親プロセス、親プロセスが起動したプロセスを
子プロセスと言います。親子関係はpstreeコマンドを使うとよく分かります。

topコマンドを使うと、プロセス実行状況をモニタリングできます。

###プロセスの終了

プロセスに送る信号をシグナルと言います。
9 KILL 強制終了
15　TERM 終了
18 CONT 再開
19 STOP　一時停止

killコマンドを使います。

kill -[シグナルID] プロセスID
kill -s[シグナル名] プロセスID

killallコマンドを使用するとプロセスIDではなく、プロセス名を指定できます。


##ジョブの管理

###フォアグランドジョブとバックグラウンドジョブ

1つのコマンドを実行すると、そのコマンドから複数のプロセスが起動することがあります。
ユーザー側の処理の単位をジョブと言います。
通常、コマンドライン上でコマンドを処理するとそれが終了するまでは次のコマンドを入力することができません。これがフォアグラウンドジョブです。一方、裏でジョブを実行させることもできます。それをバックグラウンドジョブと言います。これはコマンドラインの末尾に&を付けます。

###ジョブの操作

実行中のジョブはiobsコマンドを実行すると確認できます。
Runningはバックグラウンドで実行中です。また、Stoppedはバックグラウンドで停止中です。
+は直前に実行していたジョブを、-はその前のジョブを表します。
これらのジョブをフォアグラウンドで実行させるには、fgコマンドを使います。

fg [%ジョブID]
%の後はジョブIDだが、%が無いとプロセスIDになります。
フォアグラウンドでジョブが実行されている最中にCtrl+Zキーを押すと、
そのジョブは一時停止状態になります。一時停止中のジョブの実行を
バックグラウンドで再開させるには、bgコマンドを使用します。

bg [%ジョブID]

#ネットワークの利用

## ネットワークの基礎を理解しよう

ネットワークの範囲をネットワークセグメントと言います。

##ネットワークの設定と管理

Linuxでネットワークの設定をするには、コマンドを使って設定する場合と、
設定ファイルに書き込むパターンがあります。


###/etc/hostnameファイル

/etc/hostnameファイルで、ホスト名を設定します。
ホスト名を確認するにはhostnameコマンドを実行します。

###/etc/hostsファイル

このファイルには、IPアドレスとホスト名との対応を記述します。

###/etc/resolv.confファイル

このファイルにはホストが利用するDNSサーバを指定します。
8.8.8.8はGoogleが提供しているパブリックDNSサーバです。

###ネットワークインターフェイスの情報確認

ホストとネットワークの窓口となるのが、ネットワークインタフェースです。
ipはネットワークインターフェイスやルーティングテーブルを管理するコマンドです。
ip address showコマンドを実行するとネットワークのインターフェイスの情報が確認できます。

loはホスト自身を表すローカルループバックインターフェイスです。
これは自分自身を表すインターフェースで、127.0.0.1です。

古いシステムではifconfigコマンドが使われています。
ifconfig [ネットワークインタフェース名]

###ポートの確認

サーバがポートからのデータを待ち受けている状態をポートが開いていると言います。
開いているポートを確認するには、ssコマンドを使用します。

ss [オプション]

古いコマンドでは、netstatコマンドでポートの状態を確認します。

###ルーティングテーブルの確認

routeコマンドを実行すると、ルーティングテーブルが表示されます。
defaultの後はデフォルトゲートウェイです。
これは違うネットワークに接続するために送るものです。

##ネットワークを利用するコマンド

###hostコマンド

これはDNSサーバに問い合わせを行い、指定したホスト名に
対応するIPアドレスを確認できます。

host ホスト名orIPアドレス

###sshコマンド

SSHは、ネットワークを経由した他のホストとの通信を安全に行うプロトコルです。
sshコマンドを使って、安全な遠隔操作ができるようになります。

ssh [ユーザー名@]接続先ホスト名　or IPアドレス

SSHでは、公開認証鍵という、パスワードを使わずに認証を行う仕組みも備えています。
公開認証鍵では、パスワードの代わりに、
公開鍵と秘密鍵という2つの鍵ペアを使って認証します。
なので、パスワードを盗まれても安全です。


###pingコマンド

pingコマンドを使うと、指定したホストに向けてICMPパケットを送信します。
もしホストが動作していなければ反応が返ってきます。

死活監視はコンピュータが動作しているか、エラーを起こしてダウンしているか、
といったコンピュータの動作状況を監視することです。

ping 接続先ホスト名orIPアドレス

Ctrl+Cを押すまでICMPパケットは送信され続けます。

#システムの管理

##ログとログファイル

システムやプログラムの活動状況の記録をログと言います。
ログの多くはログファイルに書き込まれ蓄積されます。

　Linuxには、ログを集約して管理するsyslogという仕組みがあります。
CentOSでは、rsyslogというシステムによってログが収集され、ログファイルに保存されます。
ログファイルは/var/logディレクトリに保存されます。

##システムの状態を確認するコマンド

ログファイル以外にもシステムの状態を確認できる様々なコマンドがあります。
dmesgコマンドを実行すると、システム起動時のメッセージが確認できます。

lastコマンドを実行すると、最近ログインしたユーザーを確認できます。
rebootはシステムの再起動です。

whoコマンドはログイン中のユーザーを確認できます。

また、wコマンドを実行すると、ログイン中のユーザーと実行中のコマンド、
システム情報を確認できます。
Azure Pipelineでデータベース連携テスト用のMySQLを準備する

## Databaseの準備・yml記載例
Azure PipelineのUbuntu 20.04のエージェントには初期状態でMySQLがインストールされているため、起動コマンドの実行のみで利用できます。

``` yml:azure-pipelines.yml(抜粋)
    - script: sudo systemctl start mysql.service
      displayName: 'start MySQL'
```

起動処理後に

- databaseの作成
- databaseのマイグレーション
- テストデータの挿入
- テストの実行

を行うことでデータベース連携テストを実現できます。

またMySQL以外にも

- MongoDB
- PostgreSQL
- sqlite

もエージェントにインストールされているようです。

## その他
Azure pipelineのエージェントプール一覧は[こちら](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml)から確認できます。 
また一覧ページのリンクから各エージェントに含まれているソフトウェアも確認できます。
(例えば、Ubuntu 20.04は[こちら](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md))
AnsibleやTerraform toolも導入されているようなので、Azure Pipelineを用いたインフラ構築にも役立ちそうですね！
Serverless入門で作りたいと思っている簡単なサービス

# 書き始め
まず最初に記事にしてしまえば、やるであろうという願望のもと、書き始めています。

# 目標
AWSの以下のブログから、1日に1度、スクレイピングしてきて、新しいブログが発見できたら、そのブログのタイトルとURLを一緒に自分のアカウントにツイートさせる。

以下のアーキテクチャを目指します。
![Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593337/1c2a8e88-1972-39e8-3bdd-8593148acfa5.png)

# 環境
- MacOS 11.6
- VisualStudio Code
- Python3.9
- Serverless Framework 2.65.0
- エンジニア二年目

# 参考にするサイト
- Tweeter APIの使い方: 

https://qiita.com/bakira/items/00743d10ec42993f85eb

- Scrapy(スクレイピング)の使い方：

https://ai-inter1.com/python-scrapy-for-begginer/

- Serverless Frameworkを使用する際に外部モジュールをインポートする方法：

https://zenn.dev/ryo_kawamata/articles/python-exclude-package-on-serverless-framework

- Serverless Frameworkを使用する際に、Lambda Layerを使用する方法

https://blog.ikedaosushi.com/entry/2019/04/07/012612

- Serverless Frameworkを使用する際に運用上注意すること

https://qiita.com/keitakn/items/22cbc3e00acb79560b87


# 実施する順番
以下の順番で記事を投稿していこうと思います。

1. Serverless Frameworkを用いてLambdaの環境を整える。
2. Lambdaでスクレイピングする。
3. LambdaでSMS Parameter Storeを利用して安全にキーを取得する。
4. LambdaでDynamoDBにデータを投入する。
5. LambdaでDynamoDBにクエリを発行する。
6. LambdaでTwitter APIを動かしてみる。
7. Event Bridgeを利用して、Lambdaを定期実行する。
8. システムアーキテクチャのまとめとServerless Frameworkで実装してみた所管

1, 2は以下。
https://qiita.com/ShiroUz/items/f6586cb2bd408749fce6
インターン日記 #2 ちょっとした学び

今日の業務で結構大事そうな気付きを得たので、昨日#1を書いたばかりですが書き綴ろうと思います。
けっこうだらだらと書いちゃってますが、今日の学びをまとめると
**課題を解決する際はなぜその課題を解決しなくてはいけないのかを常に念頭に置き解決策を捻出するという姿勢が大事**
ということでした。

#今日の業務
今日は社内ツールの仕様設計を考えたり、社長とサービスの解像度を高めるために雑談チックに話したりしていました。
気付きを得たのは社内ツールの仕様設計を考えることにおいてです。衣服をレンタルできるサービスを運営しており、ユーザーがレンタルした衣服を購入することができるのですが、たまに購入した衣服を全部もしくは一部キャンセルしたいと言った要望がユーザーから来ることがあります。

最初に想定されていなかったためか、そのキャンセルはサービス運営側が手動で行われており、データ調整もエンジニアチームが直接データベースをいじって行うようになっていました。(決済は社外サービスを使っているので調整するデータは購入履歴やポイントなど)
それをエンジニアチームではなく運営側が、管理画面で購入履歴やポイントを編集できるようにするという課題がありました。

今日の業務はこの課題に対してどんな解決策を用意するかや仕様、設計を考えることでした。
購入した商品をすべてキャンセルする際には購入履歴を削除したりポイントを引くだけでいいのですが、一部キャンセルする際にはキャンセルしたい商品がいくらで、付与されたポイントがいくらで、と計算してデータを調整する必要があります。
様々な理由でこれをシステムで行うのが難しいらしく(最適な設計をされていたらこの問題は起きなかったのではないかと思います。)、解決策を出す必要がありました。
購入履歴やポイントを運営チームが更新できるようにするという案は手動で計算して調整をするため、データの整合性がとれない可能性があるという問題点から却下。
データの整合性は第一に担保したいので一部キャンセルの場合には、一度すべてをキャンセルして再度購入をしてもらうという方向になりました。
問題はそのキャンセルをユーザーがするか、サービス側がするか。サービス側がするようにすると全キャンセルと購入に時間のロスができてしまうというデメリットやシンプルさからユーザーがキャンセルをするという案でいこうと決めました。

この案で仕様をまとめてリーダーに報告したのですが、結論、この案ではなくサービス側が全キャンセルをする案に決まりました。
そもそもの目的を忘れていました。**そもそも、データ調整をエンジニアチームではなく運営チームができるようにする目的はエンジニアチームがユーザー体験を向上させるためにサービスのさらなる開発をするための時間を増やすことでした。**
僕が考えた案はこの目的を達成するものではなく、エンジニアチームだけでなく運営チームの時間を増やすものでした。現在のリソースを考えるとエンジニアは少ないが運営チームはその2~3倍はいるので、最適な案ではなかったと言えます。もちろんユーザー体験という観点だけにおいては僕が考えた案が最適だと言えるのですが、自分の役割が何を達成するためにあり、それはなぜ達成しないといけないかという目的を忘れてしまっていたことが原因だと考えられます。

まとめると、
**課題を解決する際はなぜその課題を解決しなくてはいけないのかを常に念頭に置き解決策を捻出するという姿勢が大事**
ということです。
目的最適って言葉が共通言語なので、この姿勢は常に持ちたいと思います。
Microsoft ToDoに登録している内容を、Power Automateで定期的にTeamsチャットに飛ばしてリマインドする(目標忘れない用)

## 動機
何かにつけて目標を立てますが、トリ頭なのですぐに忘れてしまいます。。
目標をリマインドして、目標を定期的に確認できるようにして忘れないようにしたかった。

使用サービス

* Power Automate
* Microsoft ToDo（for Business）
* Teams

## 概要
Microsoft ToDoに登録してあるタスク一覧を、平日の９時１５分に通知させるようなものをつくりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/5280f576-0536-1751-4df2-4288549006b7.png)


## 作り方
### 準備
Microsoft ToDoに新しくリストを登録しておく

[Web版](https://to-do.office.com/tasks/)
[Microsoft Store](https://www.microsoft.com/store/productId/9NBLGGH5R558)

### フロー作成
作成メニューから
空白から開始→スケジュール済クラウドフローを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/9518e3f5-4564-3b21-e562-c77b3ccddbc6.png)

名前等をもろもろ入力し、
繰り返し間隔を週に変更します←ここずっと日にしてて平日指定の仕方よくわからなかった
月~金を選択し、作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/b9e73742-a862-57fc-ff14-fa05f5ce3f54.png)

作成したら、一番上のRecurrenceの詳細を開き、
タイムゾーンを日本に変更
時刻を好きな時間に設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/b07bc4c5-1657-335c-809b-130420886858.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/f02b9f44-306f-a360-6277-48752c9c51f8.png)

フォルダー別にTo Doを一覧表示するを選択
作成したリストを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/9959188d-9eb7-5c0b-07a8-e888d5353f7d.png)

タスクを格納するための変数を初期化し、
メッセージの最初に入れる文字を設定。(改行はbrタグでできるそう！)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/0ec92c95-8e65-4cd9-e938-3b13bb29e577.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/34d97bf8-ca47-424e-dd97-32df6d3cd7e9.png)

タスクが完了していないものを取ってきたいので状態で絞ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/8aceb396-56fa-fbe5-0744-d4b2817e0500.png)

状態を選択すると、リストをぐるぐる回して探索するためにApply to eachが自動でついてくれます。

完了はcompletedとなるようなので、completedと一致で条件を追加
いいえ(一致しない)のときにうごくようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/f1523ae5-2f28-eff8-6612-1740c5d9ba66.png)

その後は、先ほど作った変数に、「文字列変数の追加」でタスクの内容をどんどんくっつけていきます
私は、タスクごとに改行、はじめに「・」をつけるようにしました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/edb5116b-3c5d-9971-3073-17e2cf89556a.png)

最後はTeamsにメッセージを飛ばすだけです。
もろもろ設定したら、messageにタスク一覧をくっつけた文字列をドーンします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/f91c8aa2-ddf0-a6c3-c872-dccd1fbb20b0.png)

作成はこれでおわりです。

## テスト
保存したら、右上のテストで確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/491af792-016c-0ca4-c228-7aca5e6b56a6.png)
手動でおｋです。

チャットに目標のものが投稿されれば成功です！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/9478a926-510e-6851-f916-a06c96d4aeb3.png)


## おわり
これできっと、目標、わすれない
社内SEは楽？SESと社内SEを比べてみた

社内SEと聞いてどんなイメージを持つでしょうか？
SESや受託開発などと比べて仕事が楽だというイメージを持つ方も多いかもしれません。

僕はSESから社内SEに転職するまで、社内SEがどんなものなのか具体的にイメージすることができませんでした。
ですが今は社内SEに転職して半年が経って、社内SEとしての仕事にもずいぶん慣れてきました。

そこで今回は、SESと社内SEの両方を経験した立場から、「社内SEは本当に楽なのか」を基準に比べてみたいと思います。
なお、社内SEと言っても会社によって違うこともあると思うので、あくまで僕の環境をもとに比較します。

## システムを納める相手
社内SEがSESや自社開発などと大きく違うのは、システム納める相手が顧客ではなく自分の会社になることです。

社内SEの場合、SESのように契約で納期が決まっているわけではないので、そういう意味では精神的な部分で楽とも言えるかもしれません。
ですが、だからと言ってダラダラ開発していいわけではありません。一つ一つの開発に時間がかかってしまえば、一人の社員としての評価は下がってしまいます。
自分自身の裁量で仕事を進めるということは、それだけの責任も負うということになります。
## 勤怠管理
社内SEになって一番楽だなと感じるのはこの点です。

SESのときは自社と客先の両方に勤務時間の報告をする必要がありましたが、社内SEはとうぜん自社への報告だけです。

また、SESでは客先での作業内容も定期的に自社に報告していましたが、今はその必要もありません。

## 担当業務
SESの場合、参画したプロジェクト内で決められた工程を担当するというパターンが多いです。
社内SEの場合は大まかな担当を持つこともありますが、業務アプリの開発もインフラもセキュリティも全て担当することになります。
僕はまだ開発ベンダーへの発注というのは経験していませんが、社内SEはそういった業務も行う必要があります。

## まとめ
簡単な比較になりましたが、僕がSESと社内SEをどちらも経験してみて感じるのは「精神的な部分では楽」ということです。
SESの頃を振り返ってみると、本来なら受けなくてもいいはずのストレスを感じていました。

社内SEになってからは、適度な緊張感の中で自分の仕事に集中できているのを実感しています。
まだ半年なのでこれからどうなっていくかは分かりませんが、少なくとも労働環境が良くなったのは確実です。

最後に、僕の転職中の体験談や、今の会社に入社した経緯はブログに書いたので、もし社内SEへの転職に興味が沸いたら、覗いてみてください。
→[ドモナのブログ][1]
[1]:https://domona.info/can-change-jobs/
InDesign JavaScript XML 要素の内容を置換

要素の内容を置換するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
このスクリプトを利用して起こった不具合の責任は取れません。
ご了承下さい。

更新 2021/11/08
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "要素の内容を置換";

//スクリプトの動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名）
app.doScript(function(){

    // ダイアログ
    var dialogueFlg = confirm("選択された要素の（子供の要素を含む）内容を「検索と置換」メニューの『正規表現』の入力で置換します。" + "\r\r"
    + "正規表現の例" + "\r"
    + "ストーリーの先頭にある数字と英語の大文字と「-」の文字　(?-m)^[\\d\\u-]+"
    , "", scriptName);

    // Ｎｏの場合
    if (dialogueFlg == false) {

        // スクリプトを終了
        exit();
    }

    // 置換数
    var replaceNumber = 0;

    // 正規表現の検索プロパティのフラグ
    var findGrepPreferencesPropertyFlg = false;

    // 正規表現の検索のプロパティ名の数だけ変数に入れて繰り返す
    for(var findGrepPreferencesProperty in app.findGrepPreferences.properties){

        // 正規表現の検索のプロパティ名が「parent」、「bulletChar」、「numberingRestartPolicies」では無い場合
        if(findGrepPreferencesProperty != "parent" && findGrepPreferencesProperty != "bulletChar" && findGrepPreferencesProperty != "numberingRestartPolicies"){

            // 正規表現の検索のプロパティの内容が「NothingEnum.NOTHING」、「」、「null」ではない場合
            if(app.findGrepPreferences[findGrepPreferencesProperty] != NothingEnum.NOTHING && app.findGrepPreferences[findGrepPreferencesProperty] != "" && app.findGrepPreferences[findGrepPreferencesProperty] != null){

                // 正規表現の検索プロパティのフラグにtrueを入れる
                findGrepPreferencesPropertyFlg = true;

                // 繰り返しを抜ける
                break;
            }
        }
    }

    // 正規表現の検索プロパティのフラグがfalseの場合
    if(findGrepPreferencesPropertyFlg == false){

        // 警告
        alert("「検索と置換」の正規表現の検索に値がありません。");

        // スクリプトを終了
        exit(); 
    }

    // 選択の数だけ繰り返す
    for (var i = 0; i < app.activeDocument.selection.length; i++){

        // 選択がXML要素の場合
        if (app.activeDocument.selection[i].constructor.name == "XMLElement") {

            // 正規表現で置換して置換された数を入れる
            replaceNumber += app.activeDocument.selection[i].changeGrep().length;
        }
    }

    // 結果表示
    alert("置換数 " + replaceNumber, scriptName);

// スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);
~~~
[go環境構築] go get でのTLS handshake error

#はじめに
ローカルでのGo開発環境構築にあたりGo Moduleを利用したいと思っていました。
いろいろと設定を施しgo getで外部モジュール取ろうとした際にTLS Handshakeエラーにぶつかったのでその時の対応を備忘録として残します。
注）開発初心者が初めて構築しようとしているので優しく見てやってください。

## 実施環境
| 項目 | - |
|:-:|:-:|
| OS | Windows10 |
| ターミナル | Git Bash |
| ネット環境 | 社内Network（Proxy経由） |
| Golang Ver. | 1.17.2 |

## エラー内容
下記コマンド実行で``first record does not look like a TLS handshake``のエラーが出ました。
（たまにDockerなどで見ることがあるような・・・）

```bash
$ go get github.com/spiegel-im-spiegel/errs
go get: module github.com/spiegel-im-spiegel/errs: Get "https://proxy.golang.org/github.com/spiegel-im-spiegel/errs/@v/list": proxyconnect tcp: tls: first record does not look like a TLS handshake
```

## 原因
原因としては下記2つありました。
### ①HTTPS_PROXYの変数名に誤りがあった
Go getなどのGoで使われるProxyはbashで設定した内容が使われるため、Bashのグローバル変数にProxyの設定はしたもののどうやら大文字/小文字の変数名定義が誤っており正しく設定できていませんでした。
Bashで使うProxy設定の変数名は**大文字**です。
■BAD
``export https_proxy="https://example.com:8080"``
■GOOD
``export HTTPS_PROXY="https://example.com:8080"``
### ②値が間違っていた（https://~ => http://~）
Dockerでも同じ罠にはまっておきながらまた繰り返しミスをしていました。
HTTPS用プロキシだからと言ってhttps://~と設定してしまいがちですが、
正しくはHTTP用プロキシ同様に**http://~**で設定しましょう。


## おわり
なんとか上記対応でgo getできるようになりました！！
ですがgo getが非推奨になろうとしている中、こんなことをやってるなんて馬鹿げていましたね。
典型02の条件評価・ループをシンプルに

# 問題

((()()))のようなネストとした括弧で文字数が入力と等しいもののリストを辞書順に出力する問題

https://atcoder.jp/contests/typical90/tasks/typical90_b

例:
入力 6
出力 
( ( ( ) ) )
( ( ) ( ) )
( ( ) ) ( )
( ) ( ( ) )
( ) ( ) ( )

## 解１ bit全探索
1から順に全探索する場合、ループカウンタが以下の制約を満たすかチェックする必要がある

`1の数 = 入力の値 / 2`
`入力の値以下の任意の桁に対して「その桁以右の0の数<=1の数」`

反対に、以下は保証されているので調べなくてよい

`括弧の辞書順`

https://twitter.com/e869120/status/1377391097836544001/photo/1

## 解２ 組み合わせ全探索
以下の記事の**next_combination**関数をループ処理に用いた場合、
ループカウンタが以下の制約を満たすかチェックする必要がある
`入力の値以下の任意の桁に対して「その桁以右の0の数<=1の数」`

以下は保証されているので調べなくてよい
`括弧の辞書順`
`1の数 = 入力の値 / 2`

https://qiita.com/drken/items/7c6ff2aa4d8fce1c9361#8-next_combination

## 解３ 条件付組み合わせ探索

上記next_combination関数を応用し、今回の問題にフィットした組み合わせを返す関数を以下のように作る
この関数が返す値は
`1の数 = 入力の値 / 2` かつ `入力の値以下の任意の桁に対して「その桁以右の0の数<=1の数」` を満たす整数で、
入力の整数の次に大きいもの（->`辞書順`）である
したがって、この関数を使うとループカウンタが常に制約を満たすので関数呼び出し元で条件評価をする必要がなくなる

```c++
int next_bracket(int sub){
  int th = 0b1010101010101010101010101010101010;
  int x = sub & th, y = x & -x;
  if(!x)return 0;
  if(!(y>>3))return next_combination(sub);
  int d = (log2(y)-1)/2, ad = sub & (y>>1)*3, cf = sub +(ad & -ad);
  return (-(~sub & cf)& cf) | (((((sub & ~cf)/y)+1)<<d) -1);
}
```
### 解説
```c++
  int th = 0b1010101010101010101010101010101010;
  int x = sub & th, y = x & -x;
  if(!x)return 0;
  if(!(y>>3))return next_combination(sub);
```
厳密な証明はしていないが、引数に対してnext_combination関数を呼び出して得られる次の組み合わせ整数表現が制約を満たさないとき、決まって引数の末尾2桁は`01`つまり( )になっている
引数の末尾2桁が`01`かどうかを知るために、後の処理でも使う`y`に`1010...1010`と引数で共有する一番下の位の`1`を入れ、これをnext_combination関数を使っていいか否かの判断に使っている
末尾が`01`以外（といっても`11`しかないが）の場合、`y`を2,3回右シフトすると`y`つまり`10`は彼方に消えるので4行目が実行される

```c++
  int d = (log2(y)-1)/2, ad = sub & (y>>1)*3, cf = sub +(ad & -ad);
  return (-(~sub & cf)& cf) | (((((sub & ~cf)/y)+1)<<d) -1);
```
`d`は引数末尾に連続している`01`の個数
`cf`は引数末尾の連続した`01`を除いて一番末尾にある`1`を探し当て(`ad&-ad`)、引数にそれを足した値。
`cf`の末尾`01`除く`1`と(返り値`|`の左)、
`sub`に`ad&-ad`を足してなくなった`1`の個数＋`d`だけ右から`1`を詰たもの(返り値`|`の右)の論理和を取ると目当ての組み合わせ整数表現になる

### 補足と注意
一応この関数を使ったループでACは出ましたが、前半部分も後半部分も厳密な証明はしていないので論理的には誤っている可能性があります。
筆者灰Coderですが、初見解法２で20分弱に対して解法３の実装に3時間強かかったので、似たような問題で条件が異なる場合にも使えるような一般性のある解法ではありません。ビット演算に対する相当な慣れがあれば違うのかもしれませんが。
dの計算にlog2関数を使用していますが、yは2の累乗であることが保障されるので右シフトを使ったwhileループや二分探索で計算したほうが早いかもしれません

## 最後に感想
けんちょんさん(作？)のnext_combination関数が大好きなので自分でも似たようなの作りたいだけでやってみました。
条件分岐や他の関数使ってたりビット演算が元と比べて煩雑だったりするので、本家の凄さを改めて感じました。
オサレ度はまだまだですが、ちゃんとAC出るような、思ったような処理を複雑なビット演算を使ってできたので個人的には満足です。
この記事をご覧の皆さんも、ビット探索のループ処理をビット演算を使ってカスタマイズしてみてはいかがでしょうか。
最後までご覧いただきありがとうございました。
Figmaで大きな画像を貼ったら縮小されて困ったときに見る記事

## これは何

- フルサイズのスクリーンショットなど、大きな画像を貼ったら画像が圧縮されてしまいます
- 現寸サイズで貼りたいときに読むための記事です

## 大きなサイズの画像を貼ると何が起こるのか

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/71aad91f-89d0-14b5-6ad7-cb96a9e86c47.gif)

このように、サイズの大きな画像を貼ると画面下部に`image resized`と表示されます。

`Learn more`を踏むと、[Figmaにおいて画像を追加する際のヘルプページ](https://help.figma.com/hc/en-us/articles/360040028034)へ飛びます。

リンク先の文章を抜粋。

> We will downsize any Images with a width or height  larger than 4096 pixels. This will scale the image's original dimensions proportionally, so the longest edge is less than 4096 pixels.

簡単に訳すと

- 幅か高さ、どちらか長い方の辺が4096pxを超えていると縮小する
- 縮小する際は元の比率を維持する

とのことです。

縮小するだけならともかく、このときの縮小のされかたがかなり粗いのが難点。

Figmaによる縮小とPhotoshopでの縮小を比べてみます

| Figmaでの自動縮小 | Photoshopでの手動の縮小 |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/34218ebd-616a-8912-4601-f0d11e1c3a9f.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/41d019dd-b7e5-9f1a-b751-29361c4e14a1.png) |

Photoshopで縮小したものは、小さい文字は潰れて読めないものの全体的な雰囲気は損ねていません。
対してFigmaの縮小はかなりガビガビになっているのが分かるでしょうか。

## 対策

Insert Big Imageというプラグインを使うのが楽です。

https://www.figma.com/community/plugin/799646392992487942

インストールして起動するとこのようなウィンドウが表示されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/3f09a890-107a-fa40-0bd7-baa48213ad18.png)

書いてある通りですが、貼り付けたい画像をドラッグ&ドロップするか、`Choose Image Files`を押して画像ファイルを選択すればOK。

このように、圧縮されない範囲で画像をカットしてグループ化して配置してくれます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/9789c133-809d-371c-9a6c-e90b14b4d263.png)

以上、Figmaで大きな画像を貼ったら縮小されて困ったときに見る記事でした。
仕事の始まりと終わりのショートカット（Git）

ふだん、ショートカットが手癖になっているので、その中身(~/.bashrcのaliasの一部）を記録しておく。

みんな大好きdocker-composeのエイリアスはdc。

```bash:~/.bashrc
alias dc='docker-compose'
``` 

仕事はじめは **gstart** で、リモートリポジトリから最新を引っ張ってきて、今日の日付でcheckoutして、dockerのお仕事用コンテナをupする。一番はじめのgit checkoutは念の為のおまじない。

```bash:~/.bashrc
alias gstart='git checkout target;git pull origin target;git checkout -b test-`date +%Y%m%d`;dc up -d'
``` 
仕事の終わりは**gend**。gitマージして、その日のブランチのcommitコメント編集モードに入る。

```bash:~/.bashrc
alias gend='git checkout target;git merge --squash test-`date +%Y%m%d`;git commit'
``` 

仕事の終わりの流れはこんな感じ。（テストを全部通して、gendしたら、リモートリポジトリにpushする。←じつはテスト全部通しはたまに忘れていきなりgendに入るのでいましめのために書いて置く）。

```bash:~/dev
dc exec {lang} test...
gend
git push origin target
``` 

お疲れさまでした。
M1 MacとIntel Macのバイナリの見分け方とユニバーサルバイナリの作成

Apple M1 CPU と Intel CPU では
CPUアーキテクチャ(命令文やデータ形式)も異なり
バイナリファイル(実行可能なファイル)の中身も別物になる

※M1搭載のMacで従来(Intel CPU搭載Mac)向けのバイナリが実行できるのは
Rosetta 2というアプリケーションでM1向けバイナリに変換したものを実行しているため

また、macOSの実行ファイル形式[Mach-O](https://ja.wikipedia.org/wiki/Mach-O)では複数のアーキテクチャのバイナリを格納することが可能で
複数のアーキテクチャ向けバイナリを格納したバイナリをユニバーサルバイナリと呼んだりする

## バイナリファイルのアーキテクチャを調べる

`file ファイル名` コマンドで調べることができる

```sh:
# Intel CPU向けバイナリの場合
$ file file ./foo/bar/hoge
./foo/bar/hoge: Mach-O 64-bit executable x86_64

# M1 CPU向けバイナリの場合
$ file ./foo/bar/hoge
./foo/bar/hoge: Mach-O 64-bit executable arm64

# ユニバーサルバイナリの場合
file ./foo/bar/hoge
./foo/bar/hoge: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
./foo/bar/hoge (for architecture x86_64):	Mach-O 64-bit executable x86_64
./foo/bar/hoge (for architecture arm64):	Mach-O 64-bit executable arm64
```

## クロスビルド
### clang(C言語)でのバイナリビルド

`--target`オプションで指定する

```sh:例
# M1 CPU向けバイナリビルド
clang -target=arm64-apple-macos12 -o arm64.out main.c

# Intel CPU向けバイナリビルド
clang -target=x86_64-apple-macos12 -o amd64.out main.c
```

### Go言語でのバイナリビルド

環境変数`GOARCH`でアーキテクチャを指定する

```sh:例
# M1 CPU向けバイナリビルド
GOARCH=arm64 go build -o arm64.out main.go

# Intel CPU向けバイナリビルド
GOARCH=amd64 go build -o amd64.out main.go
```

## ユニバーサルバイナリにする

`lipo`コマンドで複数のアーキテクチャのバイナリファイルをまとめて１つのバイナリファイルにする

```sh:例
lipo -create -output universal.out arm64.out amd64.out
```

# 参考

- [Building a Universal macOS Binary | Apple Developer](https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary)
[pytest] monkeypatchを広いスコープで使う

# はじめに
pytestで単体テストを書いているときに以下のようなエラーに遭遇したことはないでしょうか。

```
ScopeMismatch: You tried to access the 'function' scoped fixture 'monkeypatch' with a 'module' scoped request object, involved factories
```

この記事では、このエラーについて解説し解決策を示します。

# エラーの解説
エラーメッセージに書いてある通り、`function`スコープのfixtureである`monkeypatch`をより広い`module`スコープで使おうとしたことによって、スコープがあっていないよ！と言われています。
pytestではfixtureの中で別のfixtureを入力として受け取り、使用することができます。この時気をつけなくてはいけないのは、fixtureの「スコープ」という概念です。スコープには以下の4つがあります[^1]。

- `function`: テストケース毎に実行される（デフォルト）
- `class`: テストケースをまとめたクラス毎に実行される
- `module`: モジュール毎に実行される
- `session`: すべてのテストケースで一回だけ実行される

もちろん、下に行くほどスコープが広いです。

**狭いスコープのfixtureをより広いスコープで使うことはできません。**つまり、`function`スコープのfixtureは`class`以上のスコープを持つfixtureで使うことはできません。
私は、`monkeypatch`を広いスコープで使おうとして、最初に示したエラーにたまに遭遇してしまいます。以下では、そういうシーンでの解決策を示していきます。

# 解決策の前に
まず、`monkeypatch`を広いスコープで使う必要が本当にあるかを考えます。ただ、一回実行すればいいからという理由だけで`class`スコープや`module`スコープにしていないでしょうか。`monkeypatch`の「メソッドや属性を差し替える」という機能は意図しない箇所へ悪影響を及ぼす可能性があるので、できるだけその範囲（スコープ）を狭くする方が安全です。よって、毎回実行する必要がなくても、**基本的には`monkeypatch`はテストケース毎に実行するようにするべきです。**

とはいえ、実行時間などの問題からそうもいかず`monkeypatch`を広いスコープで使わざるを得ない場合もあります。

# 解決策
以下のような`session`スコープ版の`monkeypatch`を自作します。最も広い`session`スコープで作っておけば任意のスコープで使用することができます。

```python:monkeypatch_session.py
import pytest
from _pytest.monkeypatch import MonkeyPatch

@pytest.fixture(scope="session")
def monkeypatch_session():
    mpatch = MonkeyPatch()
    yield mpatch
    mpatch.undo()
```

[ソースコード](https://github.com/pytest-dev/pytest/blob/7037a587111f499c99c004e028f52c14eff936f1/src/_pytest/monkeypatch.py#L29)を読むとわかりますが、`monkeypatch_session`は`monkeypatch`と全く同じ処理をしているので、`monkeypatch`でできることはすべてできます。あとは、`monkeypatch`の代わりに`monkeypatch_session`を使うだけです。

```python
# これはScopeMismatchになる
@pytest.fixture(scope="module")
def module_fixture(monkeypatch):
    monkeypatch.setattr(...)
    ...

# monkeypatchをそのままmonkeypatch_sessionに置き換える
@pytest.fixture(scope="module")
def module_fixture(monkeypatch_session):
    monkeypatch_session.setattr(...)
    ...
```

一応、`MonkeyPatch`をそのまま使うこともできます。

```python
@pytest.fixture(scope="module")
def module_fixture():
    with MonkeyPatch.context() as mp:
        mp.setattr(...)
        ...
        yield
```

# 注意点

- 上にも書いたように、広いスコープで`monkeypatch`を使うのは安全ではない
- `monkeypatch_session`で使用している`MonkeyPatch`はユーザが使うことを意図していない（`_pytest`内にある）ものなので、予告なく変更される可能性がある

以上の注意点を認識して、用法用量を守って正しくお使いください。

[^1]: 実は`module`より広く、`session`より狭い`package`というスコープもあります（[pytestドキュメント](https://docs.pytest.org/en/6.2.x/fixture.html#fixture-scopes)）
一時的なNexus Maven Repository を立てる

環境
---

- OS: Ubuntu 20.04 (Host OS: Hyper-V / Windows 10)
- Docker 20.10.8  > `sudo snap install docker`
- Sonatype Nexus Repository Manager 3.36.0

1. DockerHubからrun
---
https://hub.docker.com/r/sonatype/nexus3

```bash
sudo docker run -d -p 80:8081 --name nexus sonatype/nexus3
```
注意: 永続化していないのでdocker processを削除したら内容は失われる

2. Webでログイン
---
Port: 80
ログイン: admin
初期パスワード: ※以下で確認

```bash
sudo docker exec nexus /bin/cat /nexus-data/admin.password
```

3. リポジトリ作成
---
設定 > Create Repository > maven2(hosted) > リポジトリ名を入力
必要ならanonymous accsess を有効に

例:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285723/30ce0dcd-6c67-15f2-fb18-77be6f11d20a.png)


備考
---
RaspberryPi model 4 で試したものの、linux/arm64/v8 はサポートしないらしい...

```
Unable to find image 'sonatype/nexus3:latest' locally
latest: Pulling from sonatype/nexus3
262268b65bd5: Pull complete
06038631a24a: Pull complete
50539d8bb585: Pull complete
c85fea177c04: Pull complete
6f4fa3a69090: Pull complete
Digest: sha256:f7c805f51a44dc55163dc05525c96dc845c6cff58572c3cc02af00dfb9a111ba
Status: Downloaded newer image for sonatype/nexus3:latest
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
3c82b25c170a3471b1d66c711d381db49163799c6a7646b5cb2b67a10c3f73ea
```
Unity Coroutineを入れ子にした時の実行順

##0.0 はじめに
Coroutine（コルーチン）は実行時間などを制御するためにとても便利な関数ですが、入れ子にした時に（コルーチンの中でコルーチンを呼んだ時に）期待通りの動きにならず少し手間取りました。解決策は単純ですが、ここに備忘録として記載しておきます。



##1.0 期待した動作
コルーチンMainCo()の途中でSubCo()を呼び出し、SubCo()が完了した後、残りのMainCo()を実行する。

**期待した出力：**
メインは 0 回目です
サブは 0 回目です
サブは 1 回目です
サブは 2 回目です
メインは 1 回目です
サブは 0 回目です
サブは 1 回目です
サブは 2 回目です
メインは 2 回目です
サブは 0 回目です
サブは 1 回目です
サブは 2 回目です







## 2.0 正しいコード
yield returnでサブコルーチンを呼び出す。
（実行順が目で追えるように1秒待機しています。）

```C#:CoroutineTest.cs
private void Start() {
    StartCoroutine(MainCo()); // MainCo関数を呼び出し
}

// メインのコルーチン
IEnumerator MainCo() {
    for (int i = 0; i < 3; i++) {
        Debug.Log($"メインは {i} 回目です");
        yield return StartCoroutine(SubCo()); // サブコルーチンを呼び出す
        yield return new WaitForSeconds(1.0f);
    }
}

// サブのコルーチン
IEnumerator SubCo() {
    for (int i = 0; i < 3; i++) {
        Debug.Log($"サブは {i} 回目です");
        yield return new WaitForSeconds(1.0f);
    }
}
```






## 3.0 間違ったコード
サブコルーチンを呼び出す際にyield returnがないためメインが止まらずサブと並行して動作している。

```C#:CoroutineTest.cs
private void Start() {
    StartCoroutine(MainCo()); // MainCo関数を呼び出し
}

// メインのコルーチン
IEnumerator MainCo() {
    for (int i = 0; i < 3; i++) {
        Debug.Log($"メインは {i} 回目です");
        StartCoroutine(SubCo()); // <--ここの部分 
        yield return new WaitForSeconds(1.0f);
    }
}

// サブのコルーチン
IEnumerator SubCo() {
    for (int i = 0; i < 3; i++) {
        Debug.Log($"サブは {i} 回目です");
        yield return new WaitForSeconds(1.0f);
    }
}
```
AppleのATTのせいでソーシャルメディア企業に1兆円の損害が出た件

以下は[App Tracking Transparency has hit social media for $10 billion in lost revenue so far](https://appleinsider.com/articles/21/10/31/social-media-firms-see-10b-cut-in-ad-revenue-due-to-app-tracking-transparency)という記事のざっくり紹介です。


# App Tracking Transparency has hit social media for $10 billion in lost revenue so far

Appleによるプライバシー保護の推進はソーシャルメディア企業に多大なダメージを与えています。
[iOS](https://appleinsider.com/inside/ios)のApp Tracking Transparency機能の影響により、Facebook、Twitter、Snap、YouTubeの広告収入は、2021年下半期には100億ドル近く減少する見込みです。

2021年4月に導入された[App Tracking Transparenc](https://appleinsider.com/articles/21/07/20/how-to-configure-app-tracking-transparency-in-ios-and-ipados)yは、オンラインでの追跡を許可するか、もしくはプライバシーを守るかをユーザが選択できる機能です。
半年経ったいま、このATTは大手ソーシャルメディアの収入に大きな影響を与えています。

広告テクノロジー企業であるLotameが[Financial Timesに語った](https://www.ft.com/content/4c19e387-ee1a-41d8-8dd2-bc6c302ee58e)ところによると、Facebook、Twitter、Snap、YouTubeの第三・第四四半期の広告収入は98億5000万ドルの減収になるということです。

4社のうち、Facebookが最も広告規模が大きいため被害も大きく、その損失は80億ドルを超える模様です。
また[Snap](https://appleinsider.com/articles/21/10/21/snap-stock-plunges-as-apple-privacy-changes-impact-revenue)はスマートフォンに注力しているため、割合として最も落ち込むことになりました。

収入の減少は、ATT導入直後の調査からずっと引き続いています。
7月にはiOSの広告の収益が[15から20%減少した](https://appleinsider.com/articles/21/07/13/app-tracking-transparency-causing-15-to-20-revenue-drop-for-advertisers)と伝えられています。

LotameのCOOであるMike Woosleyによると、広告主はiPhoneに広告を出してもほとんど成果が上がらないと感じており、その理由は[ほとんどのユーザがトラッキングを拒否している](https://appleinsider.com/articles/21/07/27/apple-sees-positive-customer-reaction-to-app-tracking-transparency)からです。
例として男性向け下着ブランドを挙げると、これまでは5ドルで1000人の男性向けに広告を出し、一人の顧客を獲得していました。
「今後は1000人の男性に広告を見せるには、2000人に広告を出さなければなりません。誰が男性で誰が女性かわからなくなったからです。」
結果として、「広告コストは2倍になり、収率は半分になりました。」

トラッキングができなくなったため、企業は新たな広告システムを作り出さなければならなくなりました。
広告コンサルタントであるEric Seufertによると、新たなツールやフレームワークの開発には一年はかかるということです。
「新しいツールは、一般公開するまえに徹底的にテストする必要があります。」

FacebookのCFOであるDavid Wehnerは、ATTを「難題」「予想より少しだけ乱暴だ」と評しました。

Alphabetは[自分だけで十分な個人情報を握っている](https://appleinsider.com/articles/21/10/27/customers-accepting-apples-anti-tracking-having-modest-affect-on-google)ため、ATTの影響をほとんど受けません。

いっぽうAppleは広告業績が改善され、前四半期の収益は183億ドルに成長しました。
この事実をもって、Appleの偽善を指摘する声もあります。

BlueConicのCOOであるCory Munchbachは「これは決して利他的な理由ではない。」と主張しています。
「Appleはプライバシーを広めるという良い仕事をしましたが、しかしお金にならなければこんなことはしないでしょう。」


# コメント欄

「今日見た中で一番良いニュースだった。」
「タイトル間違ってる。正しくは『Appleのおかげで人々は無駄な出費を100億ドル節約できた』。」
「その『損失』が指数的に増加しますように。」
「収益の減少は単に収益の減少であり、損失ではない。」
「最初からトラッキングなんてするべきではなかった。」
「世界的にマイナーなOSのわりに相当な影響力がありますね。いずれAppleを刺す[長ナイフ](https://en.wikipedia.org/wiki/Long_knives)が出てくるに違いない。」
「🥂🍾」


# 感想

この大変なご時世の中、久しぶりの明るいニュースですね。

とはいえFacebookの収入は[四半期で300億ドル](https://jp.techcrunch.com/2021/10/26/2021-10-25-facebook-reports-revenue-miss-plans-to-break-out-ar-vr-top-lines/)とかで、むしろここ数年[増加し続けていた](https://www.itmedia.co.jp/news/articles/2101/28/news066.html)くらいなので、この程度ではかすり傷にしか過ぎません。

そこでATTのようなプライバシー保護をGoogleにも求めたいところなわけですが、Googleはむしろ[どんどん](https://qiita.com/rana_kualu/items/e470f0303e6b3a429c09)[プライバシーを](https://qiita.com/rana_kualu/items/8803f02c72a54f366f2a)[流出させろ](https://qiita.com/rana_kualu/items/2e610c78aa8887ca62bb)という姿勢なのでまあ絶望的ですね。
JavaScriptのthisってなんだ？

#はじめに
この記事は備忘録を兼ね、初学者の方を対象に書いたものです。

内容や表現に誤りがあればご指摘いただけますと幸いです。

#この記事について

JavaScriptを学んでいるとサラッとよく出てくる「this」。
なんとなくは分かるけど、少し正体がつかみにくいですね。

この記事ではそんな「this」の基本、挙動について解説します。

なお、アロー関数の中ではthisの振る舞いがまた変わりますので、
それについては今度別の記事にまとめます。

#そもそも「this」ってなに？
「this」というのはあらかじめ用意されている特別な変数です。
thisは関数の中でのみ使用されます。

ここで一度thisの基本についてざっくり説明すると、
「thisは関数のスコープ内で有効な特別な変数であり、
その関数を保持しているオブジェクトへの参照」
となります。

ちょっとよくわかりませんよね。

すごく大雑把に説明すると、thisは自身を保持している関数の親であるオブジェクトへの参照を持っています。

一応説明しますと、参照を持っているというのは、「このオブジェクトが親だよ！」という情報を持っているということです。

このthisには特徴があります。
呼び出した場所によって挙動が変わっているように見える点です。

そんな摩訶不思議なthisの振る舞いについて、
この記事では大きく4つにパターンを分けて解説します。

早速実際の例を見ていきましょう。

##メソッドの中のthis
おそらくこれが一番わかりやすく、オーソドックスなパターンではないでしょうか。
次のようなパターンですね。

```main.js
const obj = {
  num: 1,
  method: function() {
    console.log(this); //出力{{num: 1, method: ƒ}}
  }
}
obj.method();
```

method()を保持しているobjが参照されていますね。
分かりにくいかもしれませんが{{num: 1, method: ƒ}}はobjオブジェクトの中身です。

##関数の中のthis
正しくは「グローバルスコープで定義された関数」ですね。

グローバルスコープで定義された関数の中のthisはグローバルオブジェクトを参照します。

実際に振る舞いを見てみましょう。

```main.js
function func() {
  console.log(this); //Window...省略
}
func();
```

thisはWindowを参照していますね。

このWindowが「グローバルオブジェクト」と呼ばれるものです。
グローバルオブジェクトというのはざっくり説明すると、
JavaScriptですべての関数や変数、オブジェクトを包み込む最上位のオブジェクトです。

JavaScriptではすべての要素がこのグローバルオブジェクトに格納されています。
グローバルオブジェクトが何なのかは実行する環境によって変わりますが、
ブラウザでは「window」になります。

なんだか難しく感じますが、初めから定義されているだけで普通のオブジェクトだと思ってもらって大丈夫です。

windowという名前のオブジェクトの中にプロパティやメソッドを入れていっているというイメージですね。

つまり次の二つは同じ意味になります。

```main.js
function func() {
  console.log('same');
}

window.func = function() {
  console.log('same');
}

```

こうしてみると、メソッドの中のthisと同じで、関数を保持しているオブジェクトを参照しているだけですね。

違う挙動に見えるだけで、実は同じ挙動ということです。

###コンストラクタ関数の中のthis
次は少々挙動が変わります。
ですが、見慣れた形ですし直感的にわかりやすいかと思います。

newでインスタンスを生成する際、
そのインスタンス自身(新しく作られるオブジェクト自身)がthisにセットされます。

次のような形ですね。

```main.js
function Person(name) {
  this.name = name;
  this.method = function () {
    console.log('hoge');
  };
}

const instance = new Person('taro');

console.log(instance.name); //出力 taro
instance.method(); //出力 hoge


// 例えば上のようインスタンスを生成した場合、下のような意味と捉えてもらうと分かりやすいかもしれません。
instance.name = 'taro';
instance.method = function () {
  console.log('hoge');
};
```

###addEventListenerの中のthis
最後にイベント発生時のthisを見てみましょう。

これも非常に直感的に理解することができます。

addEventListenerの中のthisはイベントの発生元を参照します。

実例を見てみましょう。

```main.js
document.getElementById('hoge').addEventLisetener('click', function() {
  console.log(this); //<button type="button" id="hoge">button</button>
})
```
hogeというidが当てられているボタンを押したときにthisをコンソールに出力するコードです。
イベントのターゲットである#hogeの要素が参照されていますね。


###おわり
今回は以上になります。
冒頭でも書いたように、これがアロー関数になるとまた振る舞いが変わってきます。

それについてはまた別途書こうと思います。

## 参考文献

この記事は以下の情報を参考にして執筆しました。
-開眼！ JavaScript 言語仕様から学ぶJavaScriptの本質 Cody Lindley 著、和田 祐一郎 訳
-JavaScriptの「this」は「4種類」？？ https://qiita.com/takeharu/items/9935ce476a17d6258e27
Unity：タイトル画面でのロードとシーンコントロール


セーブについては[前回](https://qiita.com/DiveMasakazu/items/1e83b37cf7281917d06a)やった。
タイトル画面でロードしてシーンを切り替える、というのをやってみる。
つまりタイトル画面でデータをロードして、他のシーンに値を引き渡す、という事をやるメモ。

[ここ](https://www.sejuku.net/blog/49352)とか見ながらやってみる。

# GUI
シーンの切り替えをやるには複数のシーンが必要なのでとりあえず作成する。
メニュー画面の作りについては[ここ](https://www.create-forever.games/re-judge8/)辺りが詳しそうだけど、
とりあえずお試しなのでUIは普通のボタンを配置
なのと、UIでも[新しいInputSystem](https://light11.hatenadiary.com/entry/2020/08/18/202627)を使ってみたい（上の例だとUIとインプット連携させずに自前処理してるぽい）

単純な操作の場合はEvenSystemを配置するとキーでの自動選択が効くので、ボタンの選択は出来た。Replaceボタンを押すと新しいInputSystemを利用するようになる。

![新しいビットマップ イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/41c02fce-bae1-153e-6e9b-7f099cb31043.png)

あとは実際に選択された時の挙動をスクリプトで書けば良い。
空のオブジェクトを作って、Managerスクリプトを作成。
シーン間のデータをグローバルを使わずに渡す方法は[ここ](https://note.com/suzukijohnp/n/n050aa20a12f1)にあったので従って作成。テストということで、面倒なので同じスクリプトを別シーンのPlayerにセットして使う事にした。

```C#:GameManger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityStandardAssets._2D;

public class GameManager : MonoBehaviour {
    public Vector3 pos;
    public void StartGame() {
        SceneManager.LoadScene("SampleScene");
    }

    public void LoadGame() {
        SaveManager saveManager = new SaveManager();
        string SaveDirPath = Application.persistentDataPath;
        SaveData sdata = saveManager.DataLoad(SaveDirPath, "test.sv");
        if (sdata != null) {
            SceneManager.sceneLoaded += GameSceneLoaded;
            pos = new Vector3(sdata.x, sdata.y, sdata.z);
        }

        SceneManager.LoadScene("SampleScene");
    }

    private void GameSceneLoaded(Scene next, LoadSceneMode mode) {
        var gameManager = GameObject.FindWithTag("Player").GetComponent<GameManager>();

        // データを渡す処理
        gameManager.pos = pos;
        gameManager.LoadedValsSet();

        SceneManager.sceneLoaded -= GameSceneLoaded;
    }

    private void LoadedValsSet() {
        this.transform.position = pos;
    }
}


```

タイトル画面ではボタンにMangarをアタッチした上で、クリック時に自分自身を持ってきて関数選択。
遷移先シーンでは、Playerタグを付けて、このManagerスクリプトをセット。

![新しいビットマップ イメージ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/ef9ad755-0466-3fda-8bfd-0741cedb3eae.png)


これでロードしてデータ（セーブしたプレーヤーの位置）を引き渡すことが出来た。