OmniAICreator/Qiita-1.07M huggingface dataset:
Python Slack SDK を使って古い投稿を削除する

# Python Slack SDK を選んだ理由
この記事を書いている2021年4月現在、Slack を操作するために Python を使うなら Python Slack SDK が最善ではないかと思います。また変わるかもしれませんが、わざわざ古いものを使うメリットはありません。

https://slack.dev/python-slack-sdk/v3-migration/index.html

Python Slack SDK はドキュメントが非常に充実しています。

https://slack.dev/python-slack-sdk/index.html

また、https://api.slack.com/ にある Python のサンプルコードも Python Slack SDK を使うものになっています。

# やりたいこと
* 古い Slack の投稿を一括削除したい

また、前提条件として次の三つがあります。

* 対象チャンネルの全ての投稿について既に削除権限がある
* 対象チャンネルはあらかじめ特定されている
* 使うのは自分だけ

# コードを書く前の準備
Slack API のトークンを手に入れる必要があります。
古い投稿を削除するので、どれが古いのかを探す権限が必要です。
また、当然に削除権限も必要です。
そうなると、Web API だけ使えれば十分で、User として動けばいいことになります。
必要なメソッドは、

conversations.history
https://api.slack.com/methods/conversations.history

と

chat.delete
https://api.slack.com/methods/chat.delete

だけです。

そして、この二つを使うために必要な権限は、channels:history と chat:write の二つです。

User Token Scopes にこの二つの権限を設定し、ワークスペースにインストールすると、User OAuth Token を入手できます。

# コードを書く
エラー処理やログの記録などは省略しています。必要に応じて追加しましょう。

```python
import os
import time 
from slack_sdk import WebClient

# トークンは環境変数に入れておくものとする
client = WebClient(token=os.environ.get("SLACK_USER_OAUTH_TOKEN"))

# チャンネル ID も実行時に与える方がいいかもしれない
channel_id = "C1234567890"

# 30日よりも古いものを削除する場合
late_ts = str(int(time.time()) - 60 * 60 * 24 * 30)

# 指定したタイムスタンプより古いものだけを取得する
result = client.conversations_history(channel=channel_id, latest=late_ts)
conversation_history = result['messages']
for x in conversation_history:
    client.chat_delete(channel=channel_id, ts=x['ts'])
    print("{} deleted".format(x['ts']))
```

エラー処理を省いたとはいえ、非常に短いコードで済みます。

## 追記: ファイルの削除
[files.list](https://api.slack.com/methods/files.list) と [files.delete](https://api.slack.com/methods/files.delete) を使えば、ほぼ同じ方法で一定の日付より前のファイルを削除することが可能です。タイムスタンプの与えかたが少しだけ違います。
量子コンピュータの基本 - 符号化の種類と量子状態の表し方

## :taurus: この記事の目的

この記事では、量子コンピュータに必要な特有の手続きである**符号化**について解説します。

## :taurus: 符号化とは

量子コンピューター、特に量子コンピューティング技術を機械学習に応用する**量子機械学習**の分野において、実データをどのように量子コンピューターに取り込めば良いか?が問題となります。

結論から言うと、量子コンピューター上で様々な計算を行う最小単位のデータが**量子ビット**であり、古典コンピューター(現在我々が普段使用しているコンピューター)のビットに相当するものですが、この一つ一つの量子ビットに(一定の規則のもと)実データを割り当てる手続きが符号化です。

この割り当ての手続きをイメージで描くと以下のようなイメージとなります。
(あくまでイメージで、正しい符号化ではありません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399135/2f231775-9e45-765d-55ce-decedae99fb5.png)

## :taurus: いろいろな符号化

符号化の手続きにはいろいろな手法があるので、そのいくつかを見てみましょう。

#### (1)計算基底符号化

あるベクトル量または配列の各要素が2進数(0または1)で表されたデータの場合、そのデータをそのまま使用して符号化します。符号化すると以下のような量子状態として表現されます。

＜符号化例＞
　もとのベクトル量(各要素が2進数)
　**(001, 011, 101, ...)**

　　↓

　符号化した量子状態
　**|001 011 101 ...〉**

元のベクトル量の各要素の状態を計算基底状態と呼ぶことから、計算基底符号化と呼ばれます。
一般的に(文字式で)書くと以下のように表現されます。

```math
もとのベクトル量\mathbf{a}\quad\mathbf{a}=(a_1, a_2, a_3, ...)\\
↓(符号化)\\
量子状態\quad|\mathbf{x}〉=|a_1, a_2, a_3, ...〉
```

#### (2)振幅符号化

元のベクトル量を規格化した実数値とし、量子ビットに順番に振幅値として割り当てる方法です。

元のベクトル量に対してまず規格化を行います。ここでの規格化とは合計で1となるように換算することです。
以下のベクトル$\mathbf{x}$に対して規格化すると以下の規格化条件を満たすことになります。

```math
\mathbf{x}=(x_1, x_2,...,x_{2^n})\\
規格化条件\quad\sum_{k=1}^{2^n}|x_k|^2=1
```

量子ビットに順番に振幅値として割り当てると、量子状態は以下となります。

```math
量子状態\quad|\psi_x〉=\sum_{k=1}^{2^n}x_k|k〉
```

さらに、元データが配列(行列)の場合も対応できます。
元データが$2^n$行×$2^n$列の行列Aの場合を考えます。

行列Aのi行j列目の要素を$a_{ij}$とすると量子状態は以下となります。

```math
量子状態\quad |\psi_A〉=\sum_{i=1}^{2^n}\sum_{j=1}^{2^n}a_{ij}|i〉|j〉
```

ただし、以下の規格化条件を満たすものとします。

```math
規格化条件\quad \sum_{i,j}^{}|a_{ij}|^2=1
```

#### (3)量子サンプル状態符号化

確率分布変数$p_i$を用いて状態を表現する方法です。
量子状態は以下のように表されます。

```math
量子状態\quad|\psi〉=\sum_{i=1}^{2^n}\sqrt{p_i}|i〉
```

確率分布変数$p_i$は以下を満たします。

```math
\sum_{i}^{}p_i=1
```

#### (4)ハミルトニアン符号化

ある行列の元データAに対して、以下のような行列Hを定義します。
行列Hはエルミート行列となります。ここで、記号†はエルミート共役です。

```math
H=\begin{pmatrix} 0 & A \\ A^\dagger & 0 \end{pmatrix}
```

さらにHを指数関数化させるとユニタリ行列$e^{-iH}$となります。
このユニタリ演算子を利用し基底ベクトルと掛け合わせることで、量子状態を作ることができます。これらの手続きをハミルトニアン符号化と呼びます(またはハミルトニアン・エンコーディング、行列エンコーディング)。

例えば、ある基底ベクトルを$\mathbf{v}$とすると、量子状態は以下のように表現できます。
ここでtはある量子状態から他の量子状態へ変化する際の時間発展に関する変数です。

```math
量子状態\quad|\psi〉=e^{-iHt}\mathbf{v}
```

## :taurus: 関連情報

:paperclip: 量子コンピュータの基本 - 混合状態と密度行列
https://qiita.com/ttabata/items/b0fd9015f5488c3a07f4

:paperclip: 量子コンピュータの基本 - 量子状態(物理状態)と観測量
https://qiita.com/ttabata/items/71ac0efb8f181871cdcc

:paperclip: 量子コンピュータの基本 - 基底エンコーディングと振幅エンコーディング
https://qiita.com/ttabata/items/69c4156fc5d90bce4405


## :taurus: ご意見など

ご意見、間違い訂正などございましたらお寄せ下さい。
Windows10のコマンドプロンプトで、日本語名のファイルをバッチで名前変更する時の注意点

## はじめに
Windows10のコマンドプロンプトで、日本語名のファイルをバッチで名前変更して、ファイル名の頭に文字列を追加しようとしたところ、文字コードや全角スペースと言った複数の要因が混ざって苦労したので、メモとして書いておく


##環境
Windows10


##日本語のファイル名をバッチで変更する際に注意すべき２点と、その対応方法
１）全角スペース
２）文字コード

全角スペースについては、事前にバッチで、アンダーバーに置き換えて対応する。
文字コードについては、バッチファイルの文字コードをANSI(s-jis)にすることで対応する。
前者のバッチは、見た目は日本語が無いが、全角スペースが入っているため、文字コードは、ANSI(s-jis)にする必要がある。



```rename_space.bat

rem 全角スペース、半角スペースを置き換えるバッチ
rem このファイルの文字コードは、s-jisにする必要がある(メモ帳で、ANSIにしておく）

for %%f in (*.txt) do call :sub "%%f"
exit /b

:sub
set fname=%1
set fname=%fname:　=_%
set fname=%fname: =_%
ren %1 %fname%
goto :EOF
```

これは、
http://qeynos2525.blog.jp/archives/1075301636.html
を参考にした。


##ファイル名の頭に文字を追加する変更バッチ
こちらも、さっきと同じように、文字コードはs-jisにする必要がある。
頭に文字を付ける場合、単純にrenとアスタリスクの組み合わせで変更しようとすると、その部分が上書きされて変換されるので、下のような、冗長なものになってしまっている。

```rename.bat
rem このファイルの文字コードは、s-jisにする必要がある(メモ帳で、ANSIにしておく）

for %%A in (ファイル名*) do ren "%%A" "2021-04-30_%%A"
```
[Django]DjangoでHTMLとViews.pyでデータを受け渡しする (コードのみ)

# 概要
今回は「Django」で「HTML」ファイルと「Views.py」ファイルでデータを受け渡しする方法を見ていきます。

これを学ぶことで、自分の思い通りにデータを扱うことができ、アプリ開発の幅を広げることができます。

ここではコードのみ載せているので、解説が必要な方はぜひ下記の記事を参考にしてください。

[[Django]DjangoでHTMLとViews.pyでデータを受け渡しする](https://www.cardenema.com/?p=613)

中級者向けの知識なので、「Djangoまだ初心者だよ…」という方は以下の記事などを参考にして、基礎部分の知識をつけてから読んでください！

[[Django初心者]DjangoでTodoリストを作成する](https://qiita.com/cardene/items/0c828a304c5360c6cbfd)

早速見ていきましょう！

# こーど
ではコードを見ていきましょう。

```html:入力用.html
.
.
.
<form action="{% url '~' %}" method="post">
    {% csrf_token %}
    <div class="field">
        <label>入力１</label><input type="text" name="nyuryoku1" id="nyuryoku1">
        <label>入力２</label><input type="text" name="nyuryoku2" id="nyuryoku2">
        <label>入力３</label><input type="text" name="nyuryoku3" id="nyuryoku3">
    </div>
    <input type="submit" value="送信">
</form>
.
.
.
```

```python: views.py
def get_nyuuryoku(request):
    message = 'データ受け取ったよ！'
    if request.method == 'POST':
        nyuryoku1 = request.POST['nyuryoku1']
        nyuryoku2 = request.POST['nyuryoku2']
        nyuryoku3 = request.POST['nyuryoku3']

        params = {
            "nyuryoku1": nyuryoku1,
            "nyuryoku2": nyuryoku2,
            "nyuryoku3": nyuryoku3,
            "message": message,
        }

        return render(request, '~', params)
```

```html: 表示用.html
.
.
.
<div class="field">
    <h4>{{ nyuryoku1 }}</h4>
    <h4>{{ nyuryoku2 }}</h4>
    <h4>{{ nyuryoku3 }}</h4>
    <h4>{{ message }}</h4>
</div>
.
.
.
```

# 終わりに
今回はDjango」で「HTML」ファイルと「Views.py」ファイルでデータを受け渡しする方法を見てきました。

具体的に動きを確認できなかったので、わかりにくかったと思います。

今後実際の動きを確認できるようにアップデートしていこうと思うので、待っていてください！


それでは！
Could not find generator '○○:install'.　の解決策 (springの停止)

###はじめに
プログラミング初学者のため、自分の理解できている範囲内で言語化しています。
何か間違っている情報や改善点などありましたら、コメントいただけますと幸いです。🙇‍♂️

#springとは
Springは、アプリケーションをバックグラウンドで実行し続けることで開発をスピードアップする Rails アプリケーションプリローダーです。これは、変更を加えるときにサーバーを再起動する必要がないことを意味します。
引用：https://pleiades.io/help/ruby/spring.html

簡単にいうと、アプリケーションを効率よくスピーディーに動かしてくれる役割をになっている。

注意点として開発環境で使うのはいいが、商用環境で使うのは公式でも推奨されていないそう、、、
実際にspringが原因でエラーになる事例もあるとか、、、

まあ、エラーが出なかったらオールオッケー🏄‍♂️

#Could not find generator '○○:install'.エラー
rspecの導入でテストコード書くためのディレクトリを生成するために

```ターミナル.
% rails g rspec:install
```
を行った際に

```ターミナル.
Running via Spring preloader in process 38602
Could not find generator 'rspec:install'. 
Run `rails generate --help` for more options.
```
とエラーが出た。

#解決策

調べたところ、springを停止することで解決できるみたいなので

```ターミナル.
% spring stop
Spring stopped.
```

spring stopコマンドで停止させて、インストールすることに成功した💪

spring stop してもどこかのタイミングで、すぐ再起動するが、
stopした直後は止まっているので、問題なくinstallできると思う

＊これでもうまくいかない人は、下記の参考文献の1つ目のURLをみて、springの無効化などをお試しください

##補足　（springの再起動）
起動の確認

```ターミナル.
% spring status
Spring is running  など状況が記述される
```
再起動

```ターミナル.
% spring start
--- springが使えるコマンドなどが表示され起動となる ---
```

###参考文献

こちらの文献ではspringについてかなり細かく記載されているので、しっかりと理解した方は、
下記の一つ目のURLをご覧ください↓
url:https://blog.aiampy.net/20191130-ruby-on-rails-stop-spring/

url:https://pleiades.io/help/ruby/spring.html
Redash Python 入門サンプル

```python
data = get_query_result(293)

result = {}

for row in data['rows']:
    add_result_row(result, {'hoge' : row['email']})

add_result_column(result, 'hoge', '', 'string')
```

とてもシンプルに書いた↑

ドキュメントは見つからないので、ここを見るしかなさそう
https://github.com/getredash/redash/blob/master/redash/query_runner/python.py
df コマンドの意図しない改行を防ぐ

# df コマンドとは
サーバのディスク使用率を確認するのに用いられ、
Linux/Unix 系のOSを利用された方なら一度は使ったことのあるコマンドかと思います。

# 今回の問題
df コマンドを発行した場合、ファイルシステム名が長いと改行されることがあります。

コンソールから確認する場合であれば特に気にはならないのですが、
スクリプトなどで表示を加工する場合に改行される場合とされない場合があると非常に厄介です。

# 解決方法
df コマンドには `--portability` というオプションがあり、
これを用いることで改行をせずに表示することができます。

```shell
$ df -Th --portability
```

こうすることで改行される恐怖を感じず、スクリプトを書くことができます。
csvのデータを多次元配列に格納する

## コード

data.csv

```python
A0,B0,C0,D0
A1,B1,C1,D1
A2,B2,C2,D2
A3,B3,C3,D3
A4,B4,C4,D4
A5,B5,C5,D5
```

multi_array.py

```python
path = "data.csv"

data = []

with open(path) as f:
    for line in f:
        line = line.replace('\n','') #末尾の\nの削除
        line = line.split(",") #分割
        data.append(line)
    
print(data)
```

## 結果

```
[['A0', 'B0', 'C0', 'D0'], ['A1', 'B1', 'C1', 'D1'], ['A2', 'B2', 'C2', 'D2'], ['A3', 'B3', 'C3', 'D3'], ['A4', 'B4', 'C4', 'D4'], ['A5', 'B5', 'C5', 'D5']]
```
シェルスクリプト(bash等)の引数解析が究極的に簡単になりました

最近、以前作った [getoptions](https://github.com/ko1nksm/getoptions) の改良をしていました。（以前の記事はこちら）

https://qiita.com/ko1nksm/items/1bcc49bef56a5c245251

**参考** こちらもどうぞ
「[getoptions を使って面倒なシェルスクリプトのオプション解析コードを自動生成しよう！](https://qiita.com/ko1nksm/items/a007c73c549fbd493a17)」

以前のバージョンはシェルスクリプトライブラリとして使い方を想定していたのですが `getopt` や `getopts` の代わりとして外部コマンドとしても使えるようにしました。使い方は簡単で [ここ](https://github.com/ko1nksm/getoptions/releases) から `getoptions` をダウンロードしパスが通ってる場所（`~/bin` や `/usr/local/bin/` など）にインストールするだけです。それだけでもう次のシェルスクリプトが動作します。他に設定ファイルや事前のビルド作業なども不要なので学習曲線は低くメンテナンス性も抜群です。

```sh
#!/bin/sh

VERSION="0.1"

parser_definition() {
  setup   REST help:usage -- "Usage: example.sh [options]... [arguments]..." ''
  msg -- 'Options:'
  flag    FLAG    -f --flag                 -- "takes no arguments"
  param   PARAM   -p --param                -- "takes one argument"
  option  OPTION  -o --option on:"default"  -- "takes one optional argument"
  disp    :usage  -h --help
  disp    VERSION    --version
}

eval "$(getoptions parser_definition) exit 1"

echo "FLAG: $FLAG, PARAM: $PARAM, OPTION: $OPTION"
printf '%s\n' "$@" # rest arguments
```

見ての通り必要なのはサポートするオプションを書いた定義関数のみです。`getoptions` を外部コマンドとして使えるようにしため、シェルスクリプトライブラリの読み込みが不要になりました。さらにオプションを解析する際の定型的なコードも減りたった一行になっています。もうこれ以上減らすことはできないでしょう。

今まで通りのライブラリとしての使い方もさらに便利になっています。ライブラリとして使うと `getoptions` をインストールせずに使えますしオプションパーサーを生成してシェルスクリプトに埋め込むとライブラリすら不要になります。その埋め込み作業もツール（`gengetoptions`）を用意しているので簡単です。

bash だけでなく全ての POSIX シェルに対応していますし、ロングオプションやロングオプションの省略、サブコマンド、ヘルプの自動生成、バリデーション、エラーメッセージのカスタマイズや、オプション指定時に関数を呼び出すなど高度な機能にも対応しています。これからは `getoptions` をインストールするだけで（例えば自分用の）シェルスクリプトをサクッと作れるようになったというわけです。

**ちょっとだけ技術解説**

さてシェルスクリプトに詳しい人であれば、上記のコードを見て珍しいテクニックが使われていることに気づくかもしれません。一つは外部コマンドの `getoptions` からシェル関数 `parser_definition` を呼び出しているということです。シェル関数の `getoptions` あれば同じプロセスのシェル関数を呼び出すのは容易な話ですが、外部コマンドの `getoptions` は別のプロセスであるため呼び出し元シェルスクリプトのシェル関数を呼べるはずがありませんね？ `eval` を使っているところからわかるかもしれませんが、実は外部コマンドの `getoptions` はシェルスクリプトコードを出力します。出力されたシェルスクリプトコードには `getoptions` シェル関数とそれを呼び出すコードが含まれているため、外部コマンドからシェル関数を実行したかのように動作するのです。

もう一つは見慣れない書き方である `eval "$(...) exit 1"` です。最後の `exit 1` はなんなのでしょうか？ 実はこれは `getoptions` がインストールされてない場合に、エラー終了させるためのコードです。シェル関数ライブラリとしての使い方であれば `getoptions` シェル関数が存在すると想定できますが、外部コマンドの場合はインストールしてないかもしれません。その場合は `$(...)` の部分で `getoptions: command not found` を標準エラー出力に出力しつつ空文字となるため `exit 1` が実行されます。もし `getoptions` がインストールされている場合、生成されたシェルスクリプトの最後で `# Do not execute` というコメントを出力します。つなげると `# Do not execute exit 1` となり `exit 1` は実行されないという仕組みです。
WindowsでHHKBをBluetooth認識しないときの解決法

# WindowsでHHKBをBluetooth認識しない

すぐにHHKBを使えなくて困ったので自分用メモ

## 環境
Windows 10
Happy Hacking Keyboard Professional HYBRID Type-S

## 状態
"Fn + q" を押してもペアリングを探知できなかった

## 解決策
接続番号を指定してやる
"Fn + q" を押した後　"Fn + Ctrl + (1－4のどれか)"

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/ec0eef95-e454-0715-0779-55204705c8d6.png)
Raspberry PiのTIPS

１）Buster(Ver.10)にバージョンアップしたらWifiが繋がらなくなった

原因がドライバーがない場合の対処法（Wifi Deviceを接続してVerUpしても導入されない）
以下のようにGitからドライバーを取得しコピーする（コピーした瞬間にifupできるようになる）

 # apt-get install git-core
 # git clone http://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
 # cp linux-firmware/rt2870.bin /lib/firmware/rt2870.bin

※WifiアダプタはWLI-UC-GNMを使用していた場合の話です。

参考にしたサイト：「RaspberryPi2でUSB無線LANモジュールを使う」
https://greenleaf.mydns.jp/pukiwiki/?RaspberryPi2%E3%81%A7USB%E7%84%A1%E7%B7%9ALAN%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%86

※注意：Ver9からVer10は別物で、設定も引き継がないものあると思った方がよいようです

随時追加予定。
メソッド内のストアドプロパティの変更にはmutatingキーワードが必要

```
struct SomeStruct {
    var id: Int
    
    init(id: Int) {
        self.id = id
    }
    
    mutating func someMethod() {
        id = 4
    }
}

var a = SomeStruct(id: 1)
a.someMethod()
a.id // 4
```

構造体のストアドプロパティの変更には再代入を必要とするため、ストアドプロパティの変更を含むメソッドにはmutatingキーワードが必要。

```
struct SomeStruct {
    var id: Int
    
    init(id: Int) {
        self.id = id
    }
    
   func someMethod() {
        id = 4 // mutiaingがついていないのでエラーになる
    }
}
```
PHP クラスについて　::parent  

#::parentは親クラスのプロパティやメソッドにアクセス出来る。

clsass ko extecds oya{}
で継承した親の記述にアクセス可能

例）

```php
<?php 

class oya
{
    public function __construct(){
        echo '親です'."\n";
    }

    public function oya_func(){
        echo '親の関数です'."\n";
    }
}

$oya = new oya();
$oya->oya_func();
//結果
// 親です
// 親の関数です

class ko extends oya
{
  public function __construct()
  {
      echo '子です'."\n";
      parent::__construct();
  }

  public function ko_func(){
      echo '子供の関数です'."\n";
      parent::oya_func();
  }
}

$ko = new ko();
$ko->ko_func();

//結果
// 親です
// 親の関数です
// 子です
// 親です
// 子供の関数です
// 親の関数です
```

上記では子供クラスのコンストラクタと関数にそれぞれ「::parent」を設定している。
これにより子供クラスでコンストラクタと関数がそれぞれ呼び出されると親クラスのメソッドが呼び出されている。
WordPressの記事を予約更新できるプラグイン「PublishPress Revisions」の使い方メモ

WordPressの記事の公開を予約する機能はもともとありますが、記事の一部を決めた時間に予約更新する機能は備わっていなかったので、プラグインを探したところ、見つかりました！

「[PublishPress Revisions](https://ja.wordpress.org/plugins/revisionary/)」

ちゃんと[WordPress.org](https://ja.wordpress.org/)に登録されたプラグインですし、最終更新日も最近で、有効インストール数も5,000以上、レビューの星も4.5で（2021年4月29日現在）ひとまず安心して使えます。
※どこかの野良プラグイン（どこかのブログ記事などでダウンロードして使うプラグイン）は、プラグインの中身を読めない限りセキュリティーホールがあるか分からず危険なので使わないようにしています。

Gutenberg（グーテンベルグ）にも対応していて助かりました。

## 使い方

※2022/05/02 使い方が変わっていたので、編集しました。

参考ページ: [How to Schedule Revisions](https://publishpress.com/knowledge-base/schedule-revisions-future/)

### 1. プラグインをインストール・有効化し、設定画面で「Enable Scheduled Revisions」にチェックが入っているか確認します
ダッシュボードに戻ると、左側のメニューに「リビジョン」が追加されていて、「Revision Queue」（リビジョン一覧）ページへのリンクがあり、Setting（設定画面）のリンクもあります。
![WordPress管理画面リビジョンメニュー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/a8d9e6e0-e72f-0e32-9c13-6de8ec2effd4.png)

おそらく何もしなくても「Enable Scheduled Revisions」にチェックは入っていると思いますが、一応確認
![設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/b05083e2-b8b7-a445-d598-3591fb9e7f6a.png)


### 1. 編集画面で「New Revision」をクリックします

![WordPress編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/fe80ba5e-e2e0-a4d5-68c7-0eae29338291.png)


### 2. 「Edit」をクリックします

![WordPress編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/abf59209-b640-28d9-9bf1-1c1f87d8370f.png)

### 3. 新しい編集画面へ遷移するので、そこで記事を編集。また、公開日を未来に設定し「Preview」をクリックします

![WordPress編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/8b1a8e3b-08af-f121-0439-82aa55f6967e.png)

![WordPress編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/6a0cfb7b-94db-5ba0-de8a-9fa22588d6e5.png)

![WordPress編集画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/a3fbdcfd-bf0d-c7c6-5274-7d7f2555f4f6.png)


### 4.プレビューしてOKだったら「Submit」（送信）をクリックします

![スクリーンショット 2022-05-02 23.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/214c8f6f-e0c0-edb4-e5b2-e7502672975f.png)

### 5. 問題なければ、そのまま「Approve」（承認）をクリックします。

![スクリーンショット 2022-05-02 23.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/7e9b5e2f-1b7f-278a-5147-ba87da6fd01a.png)

※承認しないと時間が来ても公開されないので注意。
リビジョン一覧ページで、最終的にStatusが「Scheduled」になるようにしましょう。
![Revision Queueページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/bd8e402e-3525-0afc-e6a7-55d8e97fc3ee.png)

### 6. リビジョン一覧ページからもリビジョンをApprove（承認）することができるようです

#### 6-1. リビジョン一覧ページで承認
チェックを入れて、
![リビジョン一覧ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/09aa8876-8590-0200-fce0-25957594f63c.png)

承認を選んで「適用」をクリック
![リビジョン一覧ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/d9e73f99-ca9c-c173-89e2-8295ca855695.png)


## ちゃんと設定しても更新されないとき
参考記事: [Troubleshooting the PublishPress Revisions Plugin](https://publishpress.com/knowledge-base/troubleshooting-revisionary/) の「Scheduled revisions are not publishing」
リビジョンメニューにある、Setting（設定）画面で、非同期の更新にチェックが入っていると動かない場合があるそうです。
![Setting画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/da0c8215-93b9-f402-8502-13db96e3663c.png)

また、更新する日時設定を数分後にしても動かないかも？
modalで確認してから、画像を削除する

```web.php
Route::delete('/shop', 'ShopController@delete')->name('delete');
```

```ShopController.php
use Illuminate\Http\Request;
use App\Item;
use Illuminate\Support\Facades\Storage;

class ShopController extends Controller
{
    public function delete(Request $request)
    {
        $deleteItem = Item::find($request->id);
        
        $deletepath = $deleteItem->file_path;

        // データベースのfile_path名は確認していたほうが確実(× 'public/uploads'. )
        Storage::delete('public/' . $deletepath);
        $deleteItem->delete();
        return redirect('/リダイレクト先'); 
    }
}
```
```shop.blade.php
<!-- Bootstrap導入 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Bootstrap Javascript(jQuery含む) -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

@foreach($images as $image)
<!-- </form>はmodalのsubmitの下に記載してある -->
<form action="/shop" method="post">
    @method('delete')
    @csrf
    <!-- nameプロバティとvalueプロパティがポイント -->
    <button type="button" class="buy-confirm btn btn-success" name="id" value="{{ $image->id }}" data-toggle="modal" data-target="#confirm-buy" style="width: 18rem; float: left; margin: 16px;">
        <img src="{{ Storage::url($image->file_path) }}" style="width: 100%;"/>
        <p>{{ $image->file_name }}</p>
    </button>
@endforeach

<!-- Modal -->
@foreach($images as $image)
<div class="modal fade" id="confirm-buy" tabindex="-1" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">確認</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                購入しますか？
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">いいえ</button>
                <!-- 商品imageと同じidを持たせることで、同じvalueを持たせることになる -->
                <button type="submit" class="btn btn-success" id="buybtn" name="id">はい</button>
</form>
            </div>
        </div>
    </div>
</div>
@endforeach

<script>
    $('.buy-confirm').click(function(){
        $('#buybtn').val( $(this).val() );
    });
</script>

```
pipで指定した文字列を含むパッケージをすべて削除する

自分用メモ

pip では```pip uninstall tensorflow*```のようにwildcardが使えなかったから、ワンライナーで書いた。

```pip list | grep tensorflow | awk '{print $1}' | xargs -I{} pip uninstall -y {}
```

tensorflowの部分を任意の文字列に変更してください。
英単語発音。まずは、カナ表記レベルで誤りを認識する。

# 概要
[英単語発音のカナ表記の調べ方](https://qiita.com/enoughspacefor/items/5761e77b7661d1743f64)
にて、
英単語のカナ表示の調べ方を書いた。

実際に調べてみた。

(1)英辞郎( https://eow.alc.co.jp/ )
(2)toPhonetics( https://tophonetics.com/ja/ )
(3)英語→カタカナ変換機( https://www.sljfaq.org/cgi/e2k_ja.cgi )
        ※(( ))付き表記は、スペルを考慮したもの。元のページで、左側（最初）に表示されるもの。
(4)freeenglish.jp( https://freeenglish.jp/pronunciation.html )

# 結果

## 【1】compatibility
(1)コムパティビリティ
(2)[UK]カムˌパタˈビリティ[US]カムˌパタˈビラティ
(3)クンパタビリティ((コンパティビリティー))
(4)カムぱタビラティ

⇒　ここでは、tiを「チ」と発音するのは、なかった。「ティ」か「タ」。

## 【2】describe
(1)ディスクライブ、デスクライブ
(2)[UK][US]ディスˈクライブ
(3)省略
(4)省略

⇒　deは、ディが多い？。(1)では、デにもなっているが。

## 【3】gigantic
(1)ジャイガンティク
(2)省略
(3)省略
(4)省略

⇒　ギじゃなくて、「ジャイ」です。

## 【4】thoroughly
(1)サーロウリィ、サラリィ
(2)省略
(3)省略
(4)省略

⇒　特になし（読み方不確かだったので。。）

## 【5】vehicle
(1)ヴィーイクル、ヴィークル、ヴィヒクル
(2)省略
(3)省略
(4)省略

## 【6】expect
(1)イクスペクトゥ、エクスペクトゥ
(2)省略
(3)イクセプト((エクセプト))
(4)省略

## 【7】effect
(1)イフェクトゥ、エフェクトゥ
(2)[UK][US}イˈフェクト
(3)イフェクト((	エフェクト))
(4)イふェクト


# わかったこと
## 「e」は「イ」かな
expectやeffectより。逆に、「エ」と発音する例は？



# まとめ
とくにありません。
せめて、カタカナレベルぐらいではあわせたいと思い。

# 補足
以下のサイトで引用されていた。貢献してる！
[英語（の発音）。「notice」は「ノーティス」というほど、「イ」は聞こえない。8か所ぐらいのサイトで調べた！](https://fanta-orange-grape.hatenablog.com/entry/2022/05/15/122021)
php $this使い方　cakephpなどフレームワークを使う為の基礎知識

#$thisの基本
$this->hoge;とすることでそのクラス内のプロパティやメソッドへアクセスをする。

例）

```php
<?php 

class like
{
    private $name ='';
    public function setName($name)
    {
        $this->name = $name;
    }

    // この記述では「Unexpected 'Name'.」というエラーが出る。$this->nameとしないと関数外で定義の$nameにアクセス出来ない。
    // public function getName(){
    //     return $name;
    // }
    public function getName(){
        return $this->name;
    }
}

$like = new Like();
$like->setName('甘いもの');
echo $like->getName();

結果
//甘いもの
```

上記ではコメントアウトした関数getNameを使用しても$nameを取得出来ない。
関数内で$nameを定義した場合は可能だが、今回はメソッド$nameにアクセスしたい。
その為$thisを使用したアクセス方法で$nameにセットされた「甘いもの」を取得している。
【Python 3 エンジニア認定基礎試験】エラーと例外　

# はじめに
[PRIME STUDY (プライム・スタディ)](https://study.prime-strategy.co.jp/) python3エンジニア認定試験
模擬試験 第一回 問31の「エラーと例外ーユーザー定義例外」
で勉強になったことをメモ。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [構文エラーと例外](#構文エラーと例外)
1. [31問目](#31問目)
 1. [コード](##コード)
 1. [解説](##解説)
1. [参考文献](#参考文献)

<!-- 各チャプター -->
<a id="#構文エラーと例外"></a>
# 構文エラーと例外
構文エラー:構文の解釈上のエラーで、エラーは検知されたときに出る^マーク前にあることを示している。
例外:構文エラーではないが、エラーとして検知されたもの。必ずしも致命的ではない。

<a id="#31問目"></a>
# 31問目
<a id="##コード"></a>
## コード
```言語名:Python.ipynb
class OurException(Exception): #(1)独自の例外
    pass

def raise_her_exception(a): #(2)
    print(a, "is a")
    raise OurException #raise:指定した例外(ここでは(1))を発生させる※1
    print("easygoing person.")

def func(key: int): #(3)key(int型)を引数とする関数
    try:
        if key == 0:
            raise_her_exception("Saya") #(2)へ→※1のエラーがでる→exceptへ(例外処理)
    except OurException as e:
        print("intelligent")
        raise Exception #raise:指定した例外(ここではException)を発生させる※2
        
key = 0
try:
    func(key) #(3)へ→※2のエラーがでる→exceptへ(例外処理)
except Exception as f:
    print("speedster.")
```
>Saya is a
intelligent
speedster

<a id="##解説"></a>
## 解説
(1)独自の例外
まず、OurExceptionで独自の例外を書きます
(3)key(int型)を引数とする関数
key :intで、型をintに指定(引数が実際にintじゃなくても動く)

**処理**は以下のようになされる。
1. クラスと関数の定義(1),(2),(3)
2. keyの定義
3. func(key)→(3)へ
ここからは上のコードの数を追っていけば流れがわかる。

###**Key**
コードの(2)の`raise OurException`をコメントアウトすると、以下のように出力される
>Saya is a
easygoing person.

ここではraiseがコメントアウトされたため、(3)で記載している「※1のエラーがでる→exceptへ(例外処理)」の流れがなかった。
したがってその次の`except OurException as e:`に行かず、
結果的に`except Exception as f:print("speedster.")`
も処理されなかったわけである。

<a id="#参考文献"></a>
# 参考文献
- [Pythonチュートリアル>>エラーと例外](https://docs.python.org/ja/3/tutorial/errors.html)
- [Pythonチュートリアル 第3版](https://www.amazon.co.jp/Python%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB-%E7%AC%AC3%E7%89%88-Guido-van-Rossum/dp/4873117534)
- [PRIME STUDY](https://study.prime-strategy.co.jp/)
値型と参照型の使い分け


# 値型とは
```
var a = 4.0 // aに4.0が入る
var b = a // bに4.0が入る（aがもつ4.0への参照ではなく、値である4.0が入る）
a.fromSquareRoot()
a // 2.0
b // bはaの変更の影響を受けずに4.0のまま
```

値型とは、インスタンスが値への参照ではなく値そのものを表す型。

# 参照型とは
```
class InBox {
    var value: Int
    
    init(value: Int) {
        self.value = value
    }
}

var a = InBox(value: 1) // aはInbox(value: 1)を参照する
var b = a // bはaと同じインスタンスを参照する

// a.value, b.valueは両方とも１
a.value // 1
b.value // 1

// a.valueを２に変更
a.value = 2

// a.value, b.valueは両方とも２
a.value // 2
b.value // 2
```

参照型とは、インスタンスが値への参照を表す型です。
参照型では一つのインスタンスが複数の変数や定数の間で共有されるので、ある値に対する変更はインスタンスを共有している他の変数や定数にも伝播します。

# 値型と参照型の使い分け

上記を踏まえたそれぞれの性質を考慮すると、**安全にデータを取り扱うためには値型、状態管理などの変更の共有が必要となる範囲には参照型を使用すると良いでしょう。**
【Windows】バッチファイルを作って番号のついた複数のフォルダを自動作成する

バッチファイル（bat）を作るとコマンドプロンプトで行うmkdirなどの作業を効率化できます．
今回は以下のような連続する番号のついた複数のフォルダを作成するバッチファイルを作ってみました．

![一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/f50e307f-4b30-bdbe-0cee-f05cc16778fb.png)
#作り方
1．フォルダを作りたい場所で 「右クリック」 > 「新規作成」 > 「テキストドキュメント」を作成．拡張子を「.bat」にする．

2．拡張子変更後は実行ファイルになっているので，ダブルクリックでは中身が開けない．編集は 「右クリック」 > 「編集」で行う．

3．以下のコードを書いて保存する．

```bat:
@echo off
 
set /p filename="フォルダ名を入力してください："
set /p number="フォルダ数を入力してください："
 
setlocal enabledelayedexpansion
 
for /l %%n in (1,1,%number%) do 
(
  set num=%%n
  mkdir %filename%第!num!回
)
 
endlocal
```


4．保存したバッチファイルをダブルクリックして実行する．以下のような画面が出るので，フォルダ名と数を入力してEnterを押せば作成完了．
![command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459660/1af25025-ed3c-3fbb-3097-b4805a1e241c.png)
コマンドプロンプトで文字化けする場合は，バッチファイルの文字コードを「ANSI」に変えて保存してみてください．
JS~配列処理~

#概要
プログラムの利点は、大量のデータを機械的に処理してくれます。
また、大量のデータを扱うために仕組み化が必要です。データが順番に並んだ配列、名前と値のペアでデータを管理する連想配列があります、この記事では、配列処理について触れています。

```index.js
const fruits = ["リンゴ", "バナナ", "イチゴ", "ブドウ"];
console.log(fruits);

 const fruits = [
   ["リンゴ",450],
   ["バナナ",500],
   ["イチゴ",300],
   ["ブドウ",200]
];

```


#配列宣言
配列とは、０からの順番で並んだデータ構造です。

```index.js
const fruits = ["リンゴ", "バナナ", "イチゴ", "ブドウ"];
console.log(fruits);
console.log(fruits.length);
```
配列のなかにある個々のデータを要素と言います。要素は０から始まります。
配列はArryオブジェクトのインスタンス化されたものです。


![スクリーンショット 2021-04-30 10.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/1d1c664e-80f9-df5b-a76e-7fbaecd4dfab.png)

配列はo番始まりです。これを、index番号、もしくは添字と言います。
lengthとは配列の要素数を表します。このfruitsの中には要素数が４つはいっていることがわかります。
配列の要素数を確認する場合は
lengthプロパティーで要素数を確認することができます。
(*_proto_はJSが内部的に作っているデータなのですが今回は触れません。)

#要素へのアクセス
では、fruitsのデータの要素へアクセスします。
配列名に[]の中に要素番号を入れます、これをindex番号または添字と言います。今回はinde番号で統一します。

```index.js
console.log(fruits[0], fruits[1], fruits[2],fruits[3],fruits[4]);
//リンゴ バナナ イチゴ ブドウ undefined
```
上記のような結果になりました。しかし、配列の4番は存在しないのでundefinedが返ってきます。
しかし、この記述では要素数が増えたときなどに記述が増えてしまいます。

#for文

1つ目の方法は、for文です。
配列のlengthプロパティを使用することで要素数の繰り返し処理を行うことができます。

```index.js
for(let i = 0; i < fruits.length; i++) {
  console.log(`${i}個: ${fruits[i]}`);
}
```
*注意：条件式i < fruit.length。こちらの記述を以下のように変えてみます。

```index.js
for(let i = 0; i <= fruits.length; i++) {
  console.log(`${i}個: ${fruits[i]}`);
}
//0個: リンゴ
// 1個: バナナ
// 2個: イチゴ
// 3個: ブドウ
// 4個: undefined
```

出力結果は4つ目がundefinedとなります。
<=これは要素数4つを含める条件式です。今回の条件式では、iは0番始まりとなります。そこで、0と要素数4を繰り返すと合計5回繰り返すことになります。しかし実質要素数は4つなので5回目の処理のときには値が無いのでundefinedとなります。

#forEach

2つ目の方法は、forEachです。


```index.js
fruits.forEach((fruit,index) => {
 console.log(`${index}個：${fruit}`);
 count ++;
});

console.log(`要素数は${fruits.length}個,繰り返し回数は${count}回`);
//0個：リンゴ
// 1個：バナナ
// 2個：イチゴ
// 3個：ブドウ
// 要素数は4個,繰り返し回数は4回
```
forEachでは、アロー関数を使用します。
今回の処理のでは、引数が2つなのでカンマで区切ります。（）ないの引数に配列要素が1つずつ渡され、処理されていきます。

*アロー関数とは、通常の関数と違い関数名やfunctionをかきません。また引数が1つの場合は()を省略することができます。

```index.js
fruits.forEach(fruit =>{console.log(`${fruit}`);});
```













、
【AWS】VPCとCIDR

#プログラミング勉強日記
2021年4月30日

#VPCとは
　[こちらの記事](https://qiita.com/mzmz__02/items/5d6426918a0fef7bd858)にもある通り、WSクラウドのネットワークからユーザ専用の領域を切り出して作る仮想ネットワーク。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/efeecf0d-479d-f8b3-0aa8-684b565023ad.png)

　AWSクラウドのネットワーク空間に様々なネットワーク機器やネットワークが使われている。その中に自分専用のAWSクラウドを利用する領域としてVPCを設定する。まず、AWSのアカウントを作ったらVPCがデフォルトで設定される。

#CIDRとは
　[こちらの記事](https://qiita.com/mzmz__02/items/6fe022d36f3f9d9193ff)にもある通り、サブネットマスクの値を設定して同じネットワークとして扱うIPアドレスの個数を調整できるIPアドレスの設定方法。

　2進数表記にしたときにサブネットが指定する数が利用できないようにロックされて変更できないようになり、ロックされていない桁分のビット間が有効なIPアドレスとして活用できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/4495f427-e209-995f-3405-1c34f12edf42.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/9ee6c37f-3469-e503-d216-80edc15558d1.png)

#VPCのCIDR
　VPCでは`/16` ~ `/28`のCIDR範囲を指定できる。

　CIDRに`/16`を設定したときに設定可能になるサブネット数とIPアドレス数の組み合わせは、以下の表のようになる。(AWS管理IPの5つを引いたもの)

| サブネットマスク | サブネット数 | サブネット当たりのIPアドレス数 |
|:--:|:--:|:--:|
| /18 | 4 | 16,379 |
| /20 | 16 | 4091 |
| /22 | 64 | 1019 |
| /24 | 256 | 251 |
| /26 | 1,024 | 59 |
| /28 | 4,096 | 11 |

　すでに利用されていて設定できないアドレスもある。`/24`の場合は以下の表のようになる。

| ホストアドレス | 用途 |
|:--:|:--:|
| .0 | ネットワークアドレス |
| .1 | VPCルータ |
| .2 | Amazonが提供するDNSサービス |
| .3 | AWSで予約されているアドレス |
| .255 | ブロードキャストアドレス |
CUDA | 応用編

https://www.gsic.titech.ac.jp/supercon/main/attwiki/index.php?plugin=attach&refer=Supercomputing%20Contest%202013%2FGPU%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%B3%87%E6%96%99&openfile=gpu-prog-2.pdf
##多次元配列についてのテクニック
CPU上では、大域変数として多次元配列を使える
– short int h_array[MAX1][MAX2][MAX3][MAX4];
のように定義できる
###利用方法(1): cudaMallocによる方法
###利用方法(2): __device__による方法
(1) 大域変数の定義に__device__をつけると、GPUメモリ上に確保される
```__device__ int d_array[MAX1][MAX2][MAX3][MAX4];```
(2) ただしこのままだと「CPU側から」コピーできない。
cudaGetSymbolAddressで変換しておく必要あり
例：
```void *d_array_ptr;
cudaGetSymbolAddress(&d_array_ptr, d_array);
cudaMemcpy (d_array_ptr, h_array, sizeof(int)*MAX1*MAX2*MAX3*MAX4, cudaMemcpyHostToDevice);
cudaMemcpy (h_array, d_array_ptr,
 sizeof(int)*MAX1*MAX2*MAX3*MAX4, cudaMemcpuDeviceToHost);```
(3) これなら、GPUカーネル関数内でもd_array[i][j][k][l] のように使えてちょっと便利!

##「コアレスド・アクセス」によるメモリアクセス効率化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650544/cb446040-a036-05b7-9003-74be58c13041.png)

##ifを避ける

##Stream
indesign スクリプト 構造内の要素を選択（選択された属性から）

選択された構造内の属性から要素を選択するスクリプトはこれで良いのかな・・・？

~~~JavaScript
/*
 選択された構造内の属性から要素を選択
 更新 2021/05/18
*/

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

// スクリプト名
var scriptName = "構造内の要素を選択（選択された属性から）";

// 選択されているオブジェクト
var selectobjects = app.activeDocument.selection;

// すべての選択を解除
app.activeDocument.selection = null;

// 選択オブジェクトの数だけ繰り返す
for(var i = 0; i < selectobjects.length; i++){

    // 選択オブジェクトが属性の場合
    if(selectobjects[i].constructor.name == "XMLAttribute"){

        // 親（要素）を選択に追加
        selectobjects[i].parent.select(SelectionOptions.addTo);
    }
}

// 結果表示
alert("選択数 " + app.activeDocument.selection.length,scriptName);
~~~
Githubでのエラー(初心者)

#GitHubのエラー

Githubの操作に慣れるためにファイルに追加変更を記入したところで、基本操作である add, commit, pushを行ったところエラーが出てきた。

**エラーコード**

```
error: failed to push some refs to 'https://github.com/~~~~~'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

自分の中では特に変な操作をした覚えがないのでなんでエラーが出るかわからず、とりあえず
「error: failed to push some refs to」の部分をググった。
検索先のトップに[こちら](https://qiita.com/chiaki-kjwr/items/118a5b3237c78d720582)の記事が出てきた参考にさせてもらったところ、確かに自分もREADMEを操作していたのでエラーの原因はREADMEを操作したことにあると仮定した。
その上で[この記事](https://qiita.com/seri1234/items/e651b3e108a695a92809)を参考にして解決してみた。

解決できた流れとしては

```
git branch --contains #今自分がどのブランチにいるのか確認
↓
master #masterと出たのでとりあえずマスターブランチにいるのかなと考えた

git pull origin master #次にこのコードを記入してみたところ

From https://github.com/~~~~~~~~~
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 README.md | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 README.md
 #上記のコードが出てきたのでとりあえずうまくいったと推測

 #ここで１回GitHubブラウザを確認したがファイルの更新はできていなかった。

git push -u origin master #最後にpushしてみたところターミナルにpushが成功したと出てきた。
```

以上の流れで無事にファイルを変更することができたので一安心できた。

#感想
自分の中ではエラーになるようなことをしたつもりがなくても、想定外のところでエラーが出てきてしまうこともあるので、小さなことでもエラーが出てしまうんだなと認識できた。
Reckitt Benckiserにおける大規模需要予測の実現 (Databricksユースケース)

[Customer Story: RB \- Databricks](https://databricks.com/customers/rb)の翻訳です。

**業種**: 消費財
**ソリューション**: 需要予測
**技術的ユースケース**: データ投入、ETL、機械学習
**地域**: イギリス、ヨーロッパ
**要約**:

- サポートできるビジネス規模が**10倍**に拡大
- 80TBのデータを2TBまで圧縮(**98%**の容量削減)しオペレーションコストを削減
- 24時間x7日稼働のジョブにおけるデータパイプラインを**2倍**に高速化

<iframe width="560" height="315" src="https://www.youtube.com/embed/0fOPWNjdMlM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

数百万もの顧客に消費財サービスを提供する多国籍企業である[Reckitt Benckiser](https://www.reckitt.com/)(RB)は、断絶された多くのパイプラインから提供される異なる種類の大量データを取り扱わなくてはならなかったため、需要予測の複雑性に苦慮していました。今では、Azure DatabricksがRBに統合データプラットフォームを提供することで、データチームはビジネスサイドに機械学習によってサポートされた洞察を提供し、予兆分析、製品配置、ビジネス予測を通じて近隣の雑貨店をサポートしています。

# 課題

RBは60以上の国に製品を配送していました。彼らの主要なマーケットセグメントは、伝統的な取引、近所の雑貨店と呼ばれていました。このマーケットは非常に分散しており、かつ、特にアジア、アフリカ、南米で急増している小さな個人経営のお店でした。これらの市場にサービスを提供するために彼らは、お店のオーナーがそれぞれのマーケット特有の需要に応えるベストな製品を選択するのを支援するために、それぞれの店舗を訪れる16,000人以上の担当者からなるチームを持っていました。

需要予測を改善するために彼らが持っているもっとも重要な資産の一つがデータでした。しかし、RBは断絶された多くのパイプラインから提供される異なる種類の大量データと奮闘していました。よりビジネスを活性化し、お店のオーナーたちが効率的に作業できるようにするために、データから効率的に洞察を得ることが、彼らにとっては非常に困難でした。

- 24時間x7日間稼働し続ける250以上のデータパイプラインから毎日もたらされる2TB以上のデータの処理。
- 内部のビジネスチーム(ファイナンス、セールス、オペレーション)にとっては、POSデータ、eコマースデータ、ニールセン、顧客分析結果などの外部データへのアクセス及び処理が困難だった。
- Hadoopのインフラストラクチャは、複雑、面倒、そしてスケールしにくかった。このレガシーシステムはパフォーマンス面でも課題があったことに加え、新たなデータセットをデプロイするのも難しかった。このため、DevOpsチームは常に監視を行い、問題修正を繰り返すことになり、適切なタイミングで洞察を提供することが難しかった。

# ソリューション

Azure Databricksによって、データチームが迅速に改革を行い、機械学習に支えられた示唆をビジネスサイドに提供でき、かつ、データサイエンスとデータエンジニアリングチームが協働できるスケーラブルな統合データ分析環境がRBにもたらされました。

- 自動化されたクラスター管理機能を持つフルマネージドのプラットフォームにより、インフラストラクチャとオペレーションをシンプルなものにし、スケーラビリティを確保した。
- 複数の言語サポートを持つSSLノートブック環境は、様々なチームがそれぞれ必要な言語を用いつつも、円滑なコラボレーションを可能にした。
- Delta Lakeのネイティブサポートにより、データセットを圧縮することで、多大なるコスト最適化、ストレージ容量の削減を実現した。

# 成果

Databrikcsにより、RBは劇的なパフォーマンス改善、コスト管理の改善を実現し、彼らのビジネス拡大、迅速なる機会創出を可能にした。

- **改善されたコスト最適化**: Delta Lakeを活用することで、彼らのデータを80TBから約2TBまで圧縮し、下流のデータ分析パイプラインを加速しつつも、コスト管理を改善することができた。
- **インサイト提供の時間短縮**: Databricksのパイプライン性能の改善により、24時間7日稼働しているジョブを二倍まで高速化した(全パイプラインの実行に24時間要していたのを13時間まで短縮)。
- **マーケットシェアの拡大**: Databricksのサポートにより、RBはこれまでの10倍以上の顧客をサポートできるようになりました。Databricks導入前は、彼らの最大許容量は約45,000店舗でした。Databricks導入後は、約50万店舗まで急速にスケールしています。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
[Swift] UIKitベースのプロダクトでUIをSwiftUIで開発する

## 課題
- SwiftUIが登場して、２年ぐらい経過している。2年経つが既存のプロダクトでSwiftUIで開発をするといくつかの制約に出会す。特に機能不足、不具合、サポートバージョンなどの問題もあり、UIKitベースで進めることが多い。
しかし、長期的な視点で見るとSwiftUIが開発の中心になっていくことが予想される。今回は既存のプロダクトでUIKitとSwiftUIの共存、少しずつ置き換えるための戦略について考えてみました。

## SwiftUIで実装するメリット
- 日頃の開発でInterface Builderを使っている場合は、コードだけでUIを実装できる
- 宣言的に実装できるのでメンテしやすく、コードの可読性が上がる
- プレビュー機能が使える(UIKitのクラスをWrapすれば同様の機能は使える)

## 実装方法
- UIHostingControllerを使う
- SwiftUIのViewをUIHostingControllerに渡して、Child ViewControllerとして、登録することで表示することができる

```swift
import UIKit
import SwiftUI

final class SampleListDisplayController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        title = "SampleListView(SwiftUI)"
        let hostingController = UIHostingController(rootView: SampleListView())
        addChild(hostingController)
        view.addSubview(hostingController.view)
        hostingController.didMove(toParent: self)
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            hostingController.view.rightAnchor.constraint(equalTo: view.rightAnchor),
            hostingController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            hostingController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
    }
}
```

## 実装 + α
- Mewを使う
    - [Mew](https://github.com/mercari/Mew)を使います
    - Mewを使うことでchild ViewControllerの管理が楽になり、StackViewと合わせて使うとさらにレイアウトが簡単になります。
    - MicroViewControllerとすることで画面の一部のパーツに切り分けることができ、部分的に置き換えることが容易になります
    - UIHostingControllerを継承して、SwiftUIのViewをrootViewに渡すことでSwiftUIのViewを表示できます。そして、MicroViewControllerとして画面に追加することで表示できます。

```swift
import Foundation
import UIKit
import SwiftUI
import Mew

final class BodyViewController: UIHostingController<BodyView>, Instantiatable, Injectable {
    func input(_ input: Input) {}
    typealias Input = Void
    typealias Environment = Void
    private var swiftUIView: BodyView
    var environment: Void
    init(with input: Input, environment: Environment) {
        self.swiftUIView = BodyView()
        super.init(rootView: swiftUIView)
        view.backgroundColor = .clear
    }
    
    @available(*, unavailable)
    @objc required dynamic init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

```

- サンプルコードはこちらです
    - [t-osawa-009/UIKit-SwiftUI](https://github.com/t-osawa-009/UIKit-SwiftUI)

## まとめ
- 今後はSwiftUIのアップデートによって、使いやすくなり、主流になっていくことが予想される。
- Mewのライブラリを使うことで少しずつの置き換えが簡単になります。
- 現状はSwiftUIだけでは実装したい機能を実現するのは大変である。UIKitと組み合わせ、１つの画面の一部を置き換えていくことが現実的なやり方である

## 環境
```
Xcode 12.5
Build version 12E262
Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55)
Target: x86_64-apple-darwin20.3.0
```
Pythonアルゴリズム　約数について

#約数についての考え方
アルゴリズムの学習中にa~bまでの整数の中にcの約数がいくつあるか求めるプログラムを作成するというものが出てきた。

約数を考えるときはcで割った時のあまりが０であることに等しいと考えればいいらしい。
これは前回の記事で表記した素数の考え方に似ているのでこれもパターンとして覚えることにした。

**コード**

```python:Python
count = 0 #cの約数を保存するための変数を作る
for i in range(a, b + 1):  #このfor文でa~bまでの整数を表現してあげる
    if c % i == 0: #iには１個づつa~bの整数が入るので c % iにしてあげることであまりが０と表現してあげる
        count += 1 #if文があることによってこの式が成り立っていればcountの中に整数が１個づつ増えていく
print(count)

#a,b,cには任意の数値を入れる
#a=5, b=14, c=90とすればcount=4となる。
```

#感想
今回学習したことに約数などの数学的な知識をプログラミングの世界で考えた時にどう置き換わるのかまだほとんど理解できていないので、素数、約数とパターンとして覚えたようにこれからもパターンを覚えていきたい。
キャリアチェンジ転職活動中～業務系からゲーム系へ！～

##転職活動
現在業務をしながら転職活動中の身での考えをまとめています。
決して成功した人間の話ではないことは年頭においてください。

キャリアチェンジ転職活動中の皆さん、一緒に頑張りましょう！

また、この記事を見てもっとこういう準備やアプローチがあるといい
という先輩からのコメントもお待ちしています。

###前提として私自身の情報
正社員を6年続けたのち、
派遣に登録して9年（えっそんなに経ってたの・・・）
現在フリーランスで仕事をしています。

こちら蛇足ですが、社会人になってからも、
イラストで副業をしたり（個人でもコミケで同人誌出してました）
コスプレやってその縁でコンパニオンをさせていただいたり
パチンコ屋でアルバイトしてみたり
なんか色々やってみたいことに手を出す人間です。
一貫して言えるのはやっぱりエンターテイメントに関わるのが好きということですね。

###準備
まず履歴書と経歴書を用意するのは当たり前なんですが
転職エージェントにお世話になっていると、添削してもらえます。
とはいえいい年齢ならそれなりの経歴でのそれっぽく書けるものです。
このプロジェクトではどんな業務を担当して
どんな言語やツールを使っていた
どんな経験を積んだ
そのあたりを端的に書いておくのがいいのかなと思ってます。

ゲーム系は成果物も見られます。
ゲームじゃなくても何かしらコツコツ作っている人を見るのだそう。
なので色んなものを作っておくといいし、公開しておくといいのだそう。
やりたいとはいえ、なかなか仕事をしながらって難しいですよね・・・

わたしは副業でイラストもしているのでポートフォリオの準備が
一番の懸念です。時間が足りないですね・・・！！！


###経歴の棚卸
経歴書に書くような内容じゃないな、ということも
書き出しておくことが必要だと感じています。
というのも面接で、
「この案件で作ったツールとはどういったものですか？」
「この案件で特に担当した機能はなんですか？」
といったことを尋ねられるからです。
逆にこの辺りを経歴書につらつら書くと、なかなかウザい経歴書が出来上がり
読む方もしんどいものになってしまうと思っています。
逆に質問する側もついついそこを突いてしまいますよね（笑）

別途用意しておかないといけないのが
必ず質問される、
・これからどうなりたいか
・弊社でどのように活かしていただけるか
に対しての回答です。
自身のキャリアプランが必須になるので、面接が決まるまでにじっくり考えておきます。

###エージェントに登録する
私はこちらを真っ先におこないました。
ひとまずビズリーチに登録して、お声かけていただいたエージェントさんに
詳しくお話を聞く形で一社登録しています。


###応募、からの面接
というところですが。
今のところ面接を何件かしているところで、手応えは半々かなというところ。
即戦力を求める中途採用で中々新しいことをやりたいというのは難しいです。
将来的に希望すればできるよ、というところもあるんですが
そういう場合って大体できないというのが私の経験です。
地方民なので、わざわざ今までと同じような業務を都内に引っ越して
さらに年収が減るってすごく無駄に思うんですよね。

チャレンジしてみたい企業と取引があるだとか
是非やってみて！というところに行きたいなあとは思っています。



##転職支援サイトの紹介
ビズリーチを含めて、登録している転職支援サイトの感想です
####ビズリーチ
ある程度の経歴がある人向けなので、登録時の最初のハードルがやや高いです。
仮入力して途中登録することができないので、時間がある時に登録しないと
再審査の申請など手間がかかります。
なんだかんだ有料プランを使えるチケットをもらえたりしてしばらくは
有料会員と同等の活動ができます。
期限が切れるとお声がかかっても見れないという状態になります（笑）
企業から直接お声もかかるので、自分で交渉などできる人は十分活用できます。
むちゃくちゃエージェントから声かかるのでキリがないんですが
私は具体的に案件を提示してくださった方のお話を伺うことにしました。

####ファミキャリ
ゲーム業界に特化した転職サイトです。
キャリアチェンジには不向きです。
ゲーム業界からゲーム業界への転職のみのようです。
経歴書を見て、ヒアリングもなく「案件はありません」と一蹴してきます。
案件あればご連絡しますと仰っていましたが、まあ二度とないと思います（笑）

####Geekly
キャリアチェンジにも親身に対応してくれます。
ただ沢山の案件に一度に応募するため、
その分お祈りも沢山きます。精神的な強さが必要です。

####PE-BANK
私は個人事業主なのでこちらも利用しています。
フリーの状態ならよさげな案件があればお声かけていただけます。
ただいくつかありますよ、と一覧でいただいたのは一度だけですね。
正社員以上に即戦力として探されている企業さんばかりなので、
新しい技術を勉強したから活用したい！というのには向かないです。


####リクルートエージェント
ハイキャリア向けということでなかなか強い案件を紹介いただけます。
担当さんが能力を買いすぎなのか、無理だろ・・・というところを
気軽にご紹介いただいてしまいます。
無理だろ、は自身がよくわかってる通りですね。
経歴書の添削や面接の対策も丁寧に対応してくださるので
登録していて損はないと思います。

##実際にあった質問集
<details><summary>面接で受けた質問をメモがてら追記していきます</summary>
・他の人からどう見えているか、またそれに関して実際自分ではどうか
・テスト項目は何項目作成したか
・テスト項目を減らす工夫はどのようなことか
・テストの観点を教えてください
・オブジェクト指向のメリットとデメリットはどうお考えですか
・弊社でどのように活躍していただけるか
・どのあたりに住む予定ですか
・希望の年収はどれくらいですか。最低限ほしい額はいくらですか
</details>
m1 Macの環境設定にKarabner-Elementsの必要な項目が表示されなかった場合の対処方法

# MacOS11.3にアップデートしてKarabiner-Elementsをインストール
Karabiber-ElementsがBigSurで挙動に問題があるとのことでインストールしないでいたが、OSアップデートで問題解消されるとのことで早速インストール。
でも、インストラクション通りに行かなかったので対応方法の共有です。
既知の問題についてはKarabinerの公式サイトを御覧ください。
`Notes for Mac computers with Apple Silicon (Apple M1) users`
https://karabiner-elements.pqrs.org/

## Karabiber-Elementsをインストールしても指定された要素がMacOS Preferencesに出てこない場合
https://karabiner-elements.pqrs.org/docs/getting-started/installation/
このページの通りにならず
`セキュリティとプライバシー > プライバシータブ > 左の入力監視`
自分の場合、ここに`karabiner_grabber`が出てこなかった。

# 対処方法
## 一度Karabiner-Elementsを再起動する
普通に再起動しても状況変わらずだったので
`Karabiner-Elements Preferences ＞ Misc ＞ Restart Karabiner-Elements`
これで表示されるようになってキーボードアシスタントが表示された。
![スクリーンショット 2021-04-29 10.47.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/712ca295-f0e1-df8e-a567-9d2a9d680424.png)

## 自分に必要な設定をインポートする

![スクリーンショット 2021-04-29 11.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/5b0c7aeb-1d03-1b78-fd7b-83bfe591cb94.png)
![スクリーンショット 2021-04-29 11.01.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/5b74637f-db7b-07ae-b603-1ecdf6620dce.png)
![screencapture-ke-complex-modifications-pqrs-org-2021-04-29-10_54_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/9c52d58f-1b80-5d7e-dbaf-7013738c0eda.png)

## ルールを設定する
もう一度`complex modificaitions`の`Add rule`をクリック
![スクリーンショット 2021-04-29 11.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/5b0c7aeb-1d03-1b78-fd7b-83bfe591cb94.png)

## 必要なルールを選択して設定完了
![スクリーンショット 2021-04-29 10.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357158/f84dbbaf-12d5-de3c-c2fb-01447cd246af.png)
InDesign スクリプト  構造内の属性を選択（属性名から）

構造の要素の属性名から属性を選択するスクリプトはこれで良いのかな・・・？

~~~JavaScript
/*
 構造内の属性名から属性を選択
 更新 2021/06/09
*/

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

// スクリプト名
var scriptName = "構造内の属性を選択（属性名から）";

// 検索文字を入力
var findGrepText = prompt("構造内の属性名（JavaScriptの正規表現）\r（選択された構造内の属性がある場合はその中から検索）","",scriptName);

// キャンセルされた時の処理
if(findGrepText == null){

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

// エラーが発生した場合の処理
try{

    // 正規表現オブジェクトを作り検索文字に入れる
    findGrepText  = new RegExp(findGrepText);

// エラーの場合
}catch(e){

    // 検索文字にnullを入れる
    findGrepText = null;
}

// 選択されているオブジェクト記憶用
var selectObjects = [];

// 選択が存在しない場合
if(app.activeDocument.selection.length == 0){

    // 構造内のすべての要素を選択する関数を使用
    selectObjects = selectAllAttributes(app.activeDocument.xmlElements,selectObjects);

// 選択が存在する場合
}else{

    // 選択されているオブジェクト
    selectObjects = app.activeDocument.selection;

    // すべての選択を解除
    app.activeDocument.selection = null;
}

// 選択オブジェクトの数だけ繰り返す
for(var i = 0; i < selectObjects.length; i++){

    // 選択オブジェクトが属性の場合
    if(selectObjects[i].constructor.name == "XMLAttribute"){

        // 属性名を検索して引っかかった場合
        if(selectObjects[i].name.match(findGrepText)){

            // 選択に追加
            selectObjects[i].select(SelectionOptions.addTo);
        }
    }
}

// 結果表示
alert("選択数 " + app.activeDocument.selection.length,scriptName);

/* 構造内の全ての属性を選択する為の関数、引数（xmlElements,再帰的処理の為の選択を記憶する配列） */
function selectAllAttributes(hierarchyElements,selectObjects){

    // 要素の数だけ繰り返す
    for (var i = 0; i < hierarchyElements.length; i++) {

        // 要素に子要素が存在するか
        if(hierarchyElements[i].xmlElements.length > 0){

            // 存在する場合再帰的処理
            number = selectAllAttributes(hierarchyElements[i].xmlElements,selectObjects);
        }

        // 属性の数だけ繰り返す
        for (var ii = 0; ii < hierarchyElements[i].xmlAttributes.length; ii++) {

            // 要素を選択を記憶する為の配列に追加
            selectObjects.push(hierarchyElements[i].xmlAttributes[ii]);
        }
    }

    // 選択する為のオブジェクトの値を戻す
    return selectObjects;
}
~~~
[MotionBoard]複数画面表示したい！

カスタマーサクセスにお問い合わせして、解決して頂いた内容の備忘録的な投稿です。
ディスプレイ複数持ちの人から「ボード1を見ながら、ボード2を操作したい」といった要望をうけたのが始まりです。


## 使用環境
・MotionBoard 6.1　オンプレ版
・使ってるブラウザ：GoogleChrome

# 1.やりたかったこと
「1個のログインで（セッション数を増やさずに）、ボード1を表示しながらボード2も表示する」です。
イメージはこんな感じです↓
![画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694397/f9ff3d8c-125f-756b-30ac-d4f5f14d17c1.jpeg)
# 2.方法

**ボタンアイテムのリンク設定を使って、別タブ（新しいウインドウ）で表示を行います。**
※ 表示したいボードの分だけ、ボタンが必要になります。
※「右クリックして、別タブ表示」とかではないです。

**設定手順**
(0). 開きたいボードのURLをひかえておく
(1). ボタンアイテムを作る
(2).［アクション種別］で、［リンク］を選択
(3).［リンク設定］の［リンク設定］ボタンをクリック
(4). 出てきた［リンク追加］ウインドウ内の［URL］に、新しく開きたいボードのURLを入力
(5).［ウィンドウターゲット］で、「新しいウインドウ」を指定
(6). ボタンの体裁を整える


参考のマニュアルです

https://cs.wingarc.com/manual/mb/6.1/ja/UUID-e73492bd-6ccd-756d-6466-f7695782e740.html



上記の方法で作ったリンクボタンをクリックすると、指定したボードをブラウザの別タブで開けます。


# 3.使えそうな場面
・同時に複数ボードを表示したいとき
・違うボードを見たいけど、この瞬間だけ操作状態を保っておきたいとき
・メニューボードのボードリンクさせるボタンをこれにする
・画面を複製したいとき（操作状態は引き継げない）
などなど…

# 4.思ったこと
・セッション数が増えないので、何個も出せてうれしい！
・ただ、何個くらい出しても大丈夫かよくわからないので、出しすぎは注意かも…
・右クリックして、別タブ表示とか出来たらうれしかった…
・ボードの数だけボタンを作る必要がある。
・メニューボード作ったときに使いたいな。
・お問い合わせはどんどん活用したほうがいい


#ユーザーコミュニティ「nest」とMotionBoard Wiki
Motionboardの情報収集にもってこいのコミュニティとサイトです！

https://www.wingarc.com/wug-nest/

https://w.atwiki.jp/motionboard/
【Jest】名前付きインポートしたクラスとそのメソッドをそれぞれモック化する

例として`@slack/webhook`パッケージを使ってslackにメッセージを送るコードをテストする。

```ts
// IncomingWebhookクラスを名前付きインポートして 
import { IncomingWebhook } from '@slack/webhook';

const webHookUrl = 'https://hooks.slack.com/services/~'

// 1. IncomingWebhookをインスタンス化して
const webhook = new IncomingWebhook(webHookUrl);

// 2. sendメソッドで通知を送る
webhook.send({
  text: 'メッセージ内容',
});
```

1,2をテストするために、名前付きインポートしたクラスとsendメソッドをそれぞれモック化する。

```ts
import { IncomingWebhook } from '@slack/webhook';

const mockSend = jest.fn();

jest.mock('@slack/webhook', () => ({
  IncomingWebhook: jest.fn(() => ({ send: mockSend })),
}));

```

下のようなマッチャでテストできる。

```ts
// IncomingWebhookが1回インスタンス化された
expect(IncomingWebhook).toHaveBeenCalledTimes(1);

// sendメソッドが1回実行された
expect(mockSend).toHaveBeenCalledTimes(1);
```

## メソッドだけでいいなら

sendメソッドだけモック化するなら下のようにも書ける

```ts
import { IncomingWebhook } from '@slack/webhook';

const mockSend = jest
  .spyOn(IncomingWebhook.prototype, 'send')
  .mockImplementation();
```
AcrobatReaderインストールしたらChromeになんか勝手に入れられてエラーと毎回でるのをなくしたい


Chromeから削除しているのですが
毎回
ショートカットのリンク先で
「"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chromedata\data08"」
と作成すると上記エラーが出るのがちょっと困りもの(^_^;)

下記の
[chrome 広告 右下　でググると出てきたのですが - Qiita ](https://qiita.com/moitaro/items/ddb9a07e47770098717a)
 ----
Google Chromeの右上のボタンから、設定を選択します。 プライバシーとセキュリティ項目の、「サイトの設定」を選択します。 続いて、「通知」を選択します。 通知を無効にします。
 ----
と同様拡張が増えれば増えるほど余計なことしますね……
昔はシンプルで使いやすかったのにー(T_T)