OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10のPCに分析環境（Python3＋JupyterLab）を作ってみた

# はじめに

前回の記事([Windows10のPCに分析環境（Python3＋Jupyter Notebook）を作ってみた](https://qiita.com/Blaster36/items/bcdb0323865782fdad89))では、Jupyter Notebookを使うところまでを掲載した。
が、どうやらより便利な「Jupyter Lab」なるツールが存在するらしい。
ということで、「Jupyter Lab」を使ってみようと思う。

[GitHub - jupyterlab/jupyterlab: JupyterLab computational environment.](https://github.com/jupyterlab/jupyterlab)
[Project Jupyter | Installing the Jupyter Software](https://jupyter.org/install.html)

## 本稿で紹介すること

- Jupyter Labのインストール
- Webブラウザで起動・表示するまでの環境設定

**ただし、Anacondaは本稿では使わない。便利だけれども。**

## 本稿で紹介しないこと

- Windows10のセットアップ（含むWebブラウザ）　※Windows10 Pro Ver.1909
- Python3のインストール　※Python 3.6.8を使用
- Jupyter Notebookのインストール　※Jupyter Notebook 6.1.0を使用

# では早速、本題

## Jupyter Labのインストール

以下のコマンドを実行するだけ。とても簡単。

```python
$ python -m pip install pip -U
$ python -m pip install jupyterlab
```

以下、職場とか社内ネットワーク（プロキシ環境）向け。

```python
$ python -m pip install pip -U --proxy=http://${ProxyサーバのIPアドレス}:${ProxyサーバのPort番号}/
$ python -m pip install jupyterlab --proxy=http://${ProxyサーバのIPアドレス}:${ProxyサーバのPort番号}/
```

## Webブラウザで起動・表示するまでの環境設定

1. Jupyter Notebookの実行ファイルを探すと、以下。
*C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts*

2. 実行ファイル（jupyter.exe）を右クリックして、デスクトップにショートカットを作成

3. ショートカットのプロパティを開く

4. リンク先の値を編集
変更前：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe notebook %HOME%
変更後：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe lab %HOME%

5. 変更を反映
（「適用」ボタンを押下後、）「OK」ボタンを押下

6. Jupyter Notebookを起動
ショートカットをダブルクリック

![jupyterlab1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/0c2241ad-60fb-99c2-faa3-d32e0e6515c5.png)

画面の左ペインにエクスプローラが表示されていますね、、、
元のJupyter Notebookを使いたい場合は、「Help」メニューから変更できるようです。

![jupyterlab2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/72da7c36-8aca-2355-d2f1-dbf725e00940.png)


# まとめ
Windows10のPCでPython3の使えるJupyert Labを整備。
PostgreSQLコマンド覚書

使っていないとすぐ忘れてしまうPostgreSQLのコマンドをまとめてみました。
チートシートとしてお使いください。

# ログイン
## スーパーユーザーでログイン

新しいユーザーとか作りたいときはこれで一旦ログインします。

```
psql -U postgres
```

## 該当ユーザーでアクセス

```
psql -U gwp -d postgres
```


gwpの部分はユーザー名、postgresの部分はDB名を指定することで、該当の場所にアクセスすることができます。

# DB操作

## DBの作成

gwpという名前で作成

```
create database gwp;
```

削除したい場合はこれ。

```
drop database gwp;
```

## DBの一覧を確認

以下コマンドでDBの一覧を見れます。

```
\l
```

DB接続前なら以下コマンドで一覧を見れます。

```
psql -l
```

## DBを切り替えたい場合

```
\c DB名
```

# ユーザー操作

## ユーザーの作成

gwpというユーザーを作成

```
create user gwp;
```

grantコマンドでユーザーに様々な権限を与えることができる。
以下コマンドですべての権限を与える。

```
grant all privileges on database gwp to gwp;
```

## ユーザー一覧確認

以下コマンドでユーザーリストを取得することができます。

```
\du
```

# テーブル操作

## テーブルの作成
テーブルの定義をします。
postsという名前のテーブルを作成。

```setup.sql
drop table posts;

create table posts (
  id      serial primary key,
  content text,
  author  varchar(255)
);
```

これを書いた後に、`外部ファイルの実行`にあるコマンドを実行します。

以下で、テーブル一覧を見れます。

```
\dt
```

# 外部ファイルの実行
SQL文を外部ファイルに書いて実行する時に使う

postgress起動している状態で実行

```
\i ./setup.sql
```

```
\i ./
```
まで打って、tabを押すと、候補が自動で出てくるので非常に便利。

# 参考

https://qiita.com/wafuwafu13/items/c0cb9599f17179ef1d31
https://qiita.com/H-A-L/items/fe8cb0e0ee0041ff3ceb
https://qiita.com/aosho235/items/c657e2fcd15fa0647471
https://qiita.com/yusk24/items/e102f3660120ff4fa5e0
RDP越しにvscodeを使うとマルチカーソルが一部使えない問題

Windows10でRDP(リモートデスクトップ)越しにvscodeを使っています。大抵の機能は使えるのですがマルチカーソル化がうまくできず悩んでいます。

# 問題
RDP越しでvscodeを使う際`Alt` + `Ctrl` +`Up/Downキー`でマルチカーソル化が使用できません。一方、`Alt` + クリックでは問題なくマルチカーソル化できます。また、RDPを経由せず直接vscodeを使う場合は問題は発生しません。RDPだとAlt` + `Ctrl`が反応しないようです。

# 解決法
RDPの設定を見直したりしたのですが根本的な解決法は見つかりませんでした。なので、マルチカーソル化のショートカットキーを変更することで対応しました。

# ショートカットキー変更方法
1. `Ctrl` + `Shift` + `P`でkeyと入力すると`基本設計:キーボードショートカットを開く`を選ぶ
2. で`cursor`と入力。キーボードショートカット一覧が表示される
2. コマンド名`カーソルを上に挿入`をクリックして`Shift` + `Ctrl` +`Upキー`にショートカットを変更
3. コマンド名`カーソルを下に挿入`をクリックして`Shift` + `Ctrl` +`Downキー`にショートカットを変更

変更するショートカットキーは自分の使いやすい任意のキーで良いです。

|コマンド名|変更前|変更後|
|:-:|:-:|:-:|
|カーソルを上に挿入|`Alt` + `Ctrl` +`Upキー`|`Shift` + `Ctrl` +`Upキー`|
|カーソルを下に挿入|`Alt` + `Ctrl` +`Downキー`|`Shift` + `Ctrl` +`Downキー`|
個人的な CUDA の始め方メモ

# 個人的な CUDA の始め方メモ

最終的な形として
nvcc を動かす

# 環境
CPU : Core i3-9350KF
GPU : Quadro P400
OS : Ubuntu 18.04
nvidia-smi : 450.51.06

(検証のため i7-6700を一部使用）

# 簡単なインストール
まず何も入っていない状態

```
$ nvcc

Command 'nvcc' not found, but can be installed with:

sudo apt install nvidia-cuda-toolkit
```
nvidia-cuda-toolkit を入れます

```
$ sudo apt install nvidia-cuda-toolkit
```

```
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85
```
入ったのは cuda9.1 の模様


```main.cu
#include <stdio.h>

__global__ void hello() {
	printf("Hoge\n");
}

int main() {
	hello<<<1,1>>>();
	cudaDeviceSynchronize();
}
```
```
$ nvcc main.cu
$ ./a.out
Hoge
```
とりあえず動確

# CUDA 11.0
###どうにかして CUDA 11.0 を入手しておく
どういうわけかメインマシンには入っていたので割愛
nvidia-smi 入れるときとか
ubuntu-drivers autoinstall とか
ffmpeg とか入れるときに何かしたかも

## CUDA 11.0 の導入が住んでいるかの確認
```
$ ls /usr/local/ |grep cuda
cuda
cuda-10.2
cuda-11.0
```

## CUDA 11.0 への以降（自己責任で）
```
$ which nvcc
/usr/bin/nvcc

sudo cp /usr/local/cuda-11.0/bin/nvcc /usr/bin/nvcc
```
上書きするぞ

## パスを通す
```
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```
.bashrc に上記を記述 &source

```
nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Thu_Jun_11_22:26:38_PDT_2020
Cuda compilation tools, release 11.0, V11.0.194
Build cuda_11.0_bu.TC445_37.28540450_0
```
CUDA 11 になってる
CSS で作ったバルーンがちらついたときの話

#概要
はてなマークのバルーン（ホバーしたら説明が出てくるあれ）をCSSで実装したのですが、キャッシュを読み込んでから最初のホバーのときになぜかちらついてしまいました。
#背景
会社のアプリケーションのフロントを新しく作り変えるという業務の最中、上記のようなことが起きました。JSを使っているわけでもないので、まったくわかりませんでした。
#解決法
Chromeで検証をしたところ、事前に読み込まれているはずのフォントの設定ファイルが、ホバーした時にもう一度読み込まれているようです。
ヘッダーを確認したところ。同じ記述のあるファイルが2度読み込まれていました。
片方を読み込まないようにしたら無事正しい挙動をしてくれました。
App IdでGrafanaの認証とロールの設定をする

# 目的

過去記事「[App IDでGrafanaの認証をする](https://qiita.com/teruq/items/aa84a42380b1ef7b15b5)」では、GrafanaのGeneric OAuthとIBM Cloud App IDを利用することで認証をしてみました。今回はそのアップデートとして、GrafanaのRoleをApp IDのカスタム属性を使って実現してみます。

# 手順

## App IDのカスタム属性の設定

すでにユーザーは追加済とします。詳細は前回の記事を参照ください。

ユーザー・プロファイルからユーザーを選択し、カスタム属性を追加します。次のように、

```
{
  "grafanaRole": "Admin"
}
```

としてみます。キーは任意です。値はGrafanaのロールに基づき、次のいずれかです。

* Admin
* Editor
* Viewer

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/c40d3b20-01ce-8e23-bb82-5f0c948c3567.png)

## カスタム属性の更新禁止設定

カスタム属性はデフォルトではユーザー権限で更新ができてしまいます。例えば、やり方さえ知っていればEditorロールのユーザーが自分のロールをAdminに自力で更新できてしまいます。それを避けるため、カスタム属性はユーザーは更新できないようにします。

下記画面で、``アプリからのカスタム属性の変更``を``無効``にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/73ef14c7-73a1-edb5-0ff1-1efed0eecfbd.png)

## カスタム属性の確認

curlで確認できます。

```
$ _token=$(curl -s https://jp-tok.appid.cloud.ibm.com/oauth/v4/${tenant_id}/token -d "client_id=${client_id}" -d "client_secret=${client_secret}" -d "username=${username}" -d "password=${password}" -d "grant_type=password" https://jp-tok.appid.cloud.ibm.com/oauth/v4/${tenant_id}/token | jq -r .access_token | tail -1)
$ curl -s https://jp-tok.appid.cloud.ibm.com/api/v1/attributes -H "Authorization: Bearer ${_token}"
{"grafanaRole":"Admin"}
```

## grafana.iniの設定

次のように設定します。ポイントは``api_url``と``role_attribute_path``です。api_urlはGrafanaがカスタム属性を取得するためのエンドポイントです。role_attribute_pathはattributeエンドポイントで得られたJSONのうち、Grafanaのロールを示すキーです。従って、カスタム属性のキーと一致させます。

```grafana.ini
[auth.generic_oauth]
enabled = true
name = App ID # 任意
client_id = ${client_id}
client_secret = ${client_secret}
auth_url = https://jp-tok.appid.cloud.ibm.com/oauth/v4/${tenant_id}/authorization
token_url = https://jp-tok.appid.cloud.ibm.com/oauth/v4/${tenant_id}/token
api_url = https://jp-tok.appid.cloud.ibm.com/api/v1/attributes
role_attribute_path = grafanaRole # カスタム属性のキー
```

## 動作確認

Grafanaを（再）起動し、OAuthでログインします。ユーザーのPreferenceを確認します。次のようにRoleがAdminになっていればOKです。なお、もし設定に失敗している場合、つまりロールの指定に失敗した場合はViewerになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/dc86dc61-d461-3fc4-21c7-fdeb6e44d689.png)

以上
Preztoで自動補完を有効にして色を変える方法

Zsh の自動補完プラグイン [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) が便利そうで使いたいと思いました。
私は [Prezto](https://github.com/sorin-ionescu/prezto) を使っているので、調べたら autosuggestions というモジュールが最初からあったので、そちらを使うことにしました。

## 自動補完を有効にする
autosuggestions を有効にするには、.zpreztorc のモジュールを設定している箇所に 1 行追加するだけでできました。

```zsh:.zpreztorc
# Set the Prezto modules to load (browse modules).
# The order matters.
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'prompt' \
  'autosuggestions'
# ↑これ！
```

これで入力が補完されるようになりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94124/cc0bffb9-9391-f00e-c673-b7a42eea7c5a.gif" width="75%">


## 補完された部分の色を変える
これだけだと補完された部分が、入力した部分と同じ色で分かりづらいので変えたいと思います。
この設定のしかたが分かりづらかったです。
.zpreztorc に以下のコメントがあるので、コメントを外せば何らかの色になるのかと思ったんですが変わりませんでした。

```zsh:.zpreztorc
# Set the query found color.
# zstyle ':prezto:module:autosuggestions:color' found ''
```

zstyle の設定のしかたも調べてみたんですがよくわからない……。
他の設定を読んで分かったんですが、`''` の部分に以下のように色を設定すればいいみたいです。

```zsh:.zpreztorc
# Set the query found color.
zstyle ':prezto:module:autosuggestions:color' found 'fg=white'
```

これで補完された部分が白い文字になるようになりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94124/1d1ba31d-e275-e1f2-766d-71aa80acff40.gif" width="75%">
meta description にREADME のテキストがセットされてしまう現象

先日仕事で Web ページの不具合修正しデプロイ、その日は問題なく終了。そして数日が経ちました。
ある日マーケティングチームから Slack から一報が。

> meta description に変な値が設定されているのですが、確認していただけますか？

さすがに驚いて確認したところ、コンフルエンスの URL が設定されていた…

これは完全に凡ミスで、いくつかの条件が重なって発生した問題です。後述しますが、普通に `create-nuxt-app` を使ってプロジェクトを立ち上げた場合は大丈夫だと思います。

# 状況および事象
まずは各ファイルの設定です。

```js:nuxt.config.js（一部抜粋）
...

  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
         hid: 'description',
         name: 'description',
         content: process.env.npm_package_description  || ''  // ←ここが今回のポイント
     }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },

...
```

```json:package.json（一部抜粋）
{
  "name": "project-name",
  "version": "1.0.0",
  "author": "kkeeth",
  "private": true,

  ...

  （description の設定無し）
```


```md:README.md
# project name

hogehoge
```

この場合、meta description がどうなるかと言うと、タイトル通り README のテキストが設定されます。実際のブラウザのキャプチャがこちら↓↓↓

<img width="1439" alt="check-meta-project.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48034/1dbc2f32-3baa-0d60-56b1-9319edb14ea9.png">

これの修正方法は簡単で、

1. nuxt.config.js に description のデフォルト値を設定する
2. package.json の description を設定する

README は他の値を設定することもありますので、あまりおすすめしません。

# 原因究明

ではこの事象の根本的原因はなんだったのか？


__▼仮説1__
「これは `Nuxt` がデフォルトでこの値を設定している？」
↓
ということで、`Nuxt` の[ソースコード](https://github.com/nuxt/nuxt.js)を読むも原因が分からず…

__▼仮説2__
「いや、確か `Nuxt` は `meta` 情報を [vue-meta](https://vue-meta.nuxtjs.org/) というライブラリで扱ってなかったか？」
↓
ということで、`vue-meta` の[ソースコード](https://github.com/nuxt/vue-meta)を読むも原因が分からず…

ここでハッと気付く…

### 正解
「`process.env.npm_package_description` だから、__npm がデフォルトの値を設定していないか？__」
↓
ということで、[npm 公式サイト](https://docs.npmjs.com/creating-a-package-json-file#default-values-extracted-from-the-current-directory) を見ますと、しっかり書いてありました。。。

> description: info from the README, or an empty string ""

はい。package.json に description がない場合は README から設定する[^1]、なければ空文字列をセットします（実際に動作確認してみました）。[^2] 要は、npm の仕様だったわけです。

### 余談
現在は `create-nuxt-app` でプロジェクトを作成しますと、nuxt.config.js の記述は以下のように npm ではなく package.json の設定を利用するようになっております。

```diff:nuxt.config.js
+ import pkg from './package'

  head: {
-   title: process.env.npm_package_name || '',
+   title: pkg.name,
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
         hid: 'description',
         name: 'description',
-        content: process.env.npm_package_description  || ''
+        content: pkg.description
     }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },
```

[^1]: 厳密には、heading 1 の次の行が設定されます
[^2]: README ファイルが存在しない場合も同様です

したがって、今回の問題はかなりのエッジケースになりますのでご安心ください。

# まとめ
* 公式の CLI のボイラープレートを信じよう
* package.json の `description` はちゃんと書こう

ではでは(=ﾟωﾟ)ﾉ
【HTTP のいろいろ - キャッシュ】Cache-Control ヘッダーの設定方法

### はじめに
HTTPヘッダーのCache-Controlには色々パラメーターがあり、どうやって指定するのか？
この記事でまとめます。

### キャッシュの種類
#### Private キャッシュ VS Shared キャッシュ
キャッシュには様々の種類がありますが、大まかにPrivate キャッシュとShared キャッシュに分類できます。

#### Private キャッシュ
単独のユーザーに利用されるキャッシュ。基本はユーザー使用されるブラウザー側で保持します。
一度ブラウザーキャッシュに保存される内容は、再び訪問（リクエスト）する際、サーバーに再度アクセス必要がなくなります。これである程度サーバーへの負荷を分散できるでしょう。
Cache-Controlヘッダーに関連のパラメーター：private
**主な利用シナリオ**：ウェブページの戻る/進む操作

#### Shared キャシュ
名前の通り、複数ユーザがシェアできるためのレスポンスを保存するキャッシュ。主にプロクシーサーバーで保持します。
Cache-Controlヘッダーに関連のパラメーター：public
**主な利用シナリオ**：ホットリソースを再利用して、ネットワークのトラフィックやオリジナルサーバーへの負荷を減らす

※ 上記ブラウザーキャッシュとプロクシーキャッシュ以外に、ゲートウェイ、CDN、ロードバランサーキャッシュもございます。

### Cache-Control ヘッダー主なパラメータ

#### no-store
キャッシュの中、クライアントのリクエストとサーバーのレスポンスについての内容何も保存しません。毎回必ずオリジナルサーバーにアクセスして、レスポンスをとります。

#### no-cache
キャッシュした内容を渡す前に、オリジナルサーバーに検証します（キャッシュは未だ有効するかどうかを）。

#### max-age
max-ageというパラメータはキャッシュの有効期限と関われます。デフォルト単位は秒です。

**キャッシュの更新**：オリジナルサーバー側のリソースが更新した場合、キャッシュも更新すべきです。HTTPのクライアントサーバープロトコルより、リソースを変更した時にサーバーがキャッシュやクライアントに連絡しませんので。サーバーは、リソースの有効期限を伝えなければなりません。


「リソースが陳腐化していないと考えられる最長期間を表す。。。変更しない予定のアプリケーションのファイルには、たいてい積極的なキャッシュを行います。これは例えば画像、CSS ファイル、JavaScript ファイルといった静的なファイルが含まれます」

max-ageを100に設定した場合は以下の図解の通り、

![HTTPStaleness.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544279/6209e0a1-3b5c-2b12-9457-918e0a68e21c.png)
出所：MDN - HTTP キャッシュ

* Client 1はリクエストする時、未だキャッシュがないため、オリジナルサーバーからのレスポンスはキャッシュに保存され、レスポンスします。
* Client ２は10秒後リクエストする時、キャッシュが未だfreshのため、オリジナルサーバーにアクセスせず、キャッシュからレスポンス内容を取ります。
* Client ３は100秒後リクエストする時、キャッシュがはstale（陳腐化）になったため、 If-None-Match （またはIf-Modified-Since）を付加してリクエストをオリジナルサーバーに転送します。もしキャッシュは新鮮であれば、サーバーは 304 (Not Modified) ヘッダーを返します。要求されたリソースはキャッシュより送信するため、オリジナルサーバー→キャッシュ間の帯域を節約します。

では、これらのパラメータどう設定しますか？
次のフロー図をご参考ください。

### 最適な Cache-Control ポリシーの定義
![http-cache-decision-tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544279/2dcefce3-86ea-d97c-a876-05add1c42716.png)
出所：Google Developers - Web Fundamentals, HTTP Cache

### 具体例
リソースベースのセッティングの考え方を見ていきましょう。
開発用のリソースファイルのHTML、JS、CSS、ImagesなどのCache-Control設定例とその理由：

#### HTML
設定：private, no-cache
意味：単独のユーザーのみに利用され、キャッシュした内容を渡す前に、オリジナルサーバーに検証します。
理由：アプリのプライマリーリソースとして、毎回リクエストの時サーバーに検証する必要があります。

#### JS, CSS, Images
設定：public, max-age=31536000
意味：複数ユーザー利用でき、有効期限は１年間
理由：JS, CSS, Imagesというような静的なファイルはほぼ変更しませんので、直接キャッシュから読み込んでも構いません。


###参考
[1] MDN - [HTTP caching](https://developer.mozilla.org/ja/docs/Web/HTTP/Caching)
[2] Google Web Fundamentals - [HTTP Cache] (https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching)
[3] Google Chrome Developersチャネル - [Caching Headers](https://www.youtube.com/watch?v=aN8wMQVaNvs)
[Unity] Prefabの編集をC#スクリプトで行う 

# 概要

タイトルの通り、Prefabとして固めてあるものをスクリプトで開いて、編集して、保存するための方法を書き記します。

# 方法

```C#
const string PrefabPath = "Assets/Prefabs/Player.prefab";
GameObject player = PrefabUtility.LoadPrefabContents(PrefabPath);

/*
 * 読み込んだPrefabの内容を変更
 */

PrefabUtility.SaveAsPrefabAsset(player, PrefabPath);
PrefabUtility.UnloadPrefabContents(player);
```

## 注意点

* Prefabのパスはプロジェクトフォルダをルートとして指定します
* 拡張子の`.prefab`まで入れないと読み込まれません
* `SaveAsPrefabAsset()`で保存しないと、変更した内容が反映されません
* `UnloadPrefabContents()`でアンロードすることを忘れずに

## 読み込んだ後

```C#
GameObject player = PrefabUtility.LoadPrefabContents(PrefabPath);

int count = player.childCount;  // 子要素の数
for(int i=0; i<count; i++)
{
    GameObject obj = player.GetChild(i);    // 子要素はインデックスで持ってこられる
    
    // なにかコンポーネントを持ってくるときはGetComponent()で
    var cinemachine = path.GetComponent<Cinemachine.CinemachineSmoothPath>();
}
```

UnityEditor上で

* Hierarchyで操作するものは`GameObject`
* Inspectorで操作するものは`Component`

です（ここらへん不安なので信用しないように）。

以上です。

# 参考リンク

* https://light11.hatenadiary.com/entry/2019/01/21/232729
* https://docs.unity3d.com/ja/current/ScriptReference/PrefabUtility.html
6行で UIView を UIImage に変換してサクッと画像を保存する

# はじめに

今回は特定の View を UIImage に変換してフォトライブラリーに保存できるようにします


# 実装

### プロパティを追加

UIView から image を取得するための ExtensionProperty を追加します。

```swift
extension UIView {
    var image: UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        layer.render(in: context)
        let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return capturedImage
    }
}
```

### 画像をフォトライブリーに保存する

毎度おなじみの `UIImageWriteToSavedPhotosAlbum()` で画像が保存できていれば完了です。

```swift
    func saveImage() {
        let image = view.image
        UIImageWriteToSavedPhotosAlbum(image, self, nil, nil)
    }
```
SwiftとFirebaseでSNSアプリNomadを開発する！(第一回)

#対象者

 - プログラミング初心者の方
 - SNSアプリの開発に興味のある方
 - エンジニアを目指している方

#簡単な自己紹介

プログラミングは1年ほど学んでおり、特にSwiftを扱ってきました。
それまでは、プログラミングの存在自体は知っていましたが、たまにHTMLやCSS、WordPressをかじる程度で本格的に勉強してはいませんでした。
そんな自分がiOSアプリを開発し、リリースしたので、開発過程のノウハウを共有していこうと思います。

#アプリ紹介

[『**Nomad**』](https://apps.apple.com/jp/app/id1521126400)


<a href="https://gyazo.com/ebf729d9fbc87a66850b2ae0956aaeb1"><img src="https://i.gyazo.com/ebf729d9fbc87a66850b2ae0956aaeb1.gif" alt="Image from Gyazo" width="310"/></a>

このアプリは、ニュース、音楽、スポーツ、漫画、、、などカテゴリーごとに話したいことを投稿できるようにしています。そしてその投稿に興味を持った人や同じ趣味の人同士が集まってトークするコミュニティアプリです。
コロナウイルスが世界的に流行している現在(2020年)に、多くの人々が外出自粛を余儀なくされており、この外出自粛の影響で精神的にも経済的にも疲弊してしまった人々は多いと聞きます。そして仮にコロナウイルスがおさまったとしても、この生活は続くことが考えられます。そのような状況に苦しむ人々のために、私ができることは何かと考えた結果、このような世界でも簡単に誰かとのつながりを感じられる新しいコミュニティ型のサービスを作ろうと思い、開発しました。


#開発環境

IDE: Xcode 11.5
Lang: Swift5
OS: MacOS(Mojave)


#さいごに

次回以降、実際に開発の方に入っていこうと思います！
もし、「こっちの処理の方が良さそう！」とか「このコードはどうかな？」などご指摘やアドバイスがございましたらその都度アドバイスをしていただけると嬉しいです！
Fabric から Firebase Crashlytics へ移行 

## 概要

Crashlytics で導入していた Fabric SDK が非推奨になった。現在はまだサポートしているが、2020 年 11 月 15 日をもってクラッシュの報告を停止するらしい。つい最近知ったような口ぶりだが、6 月に入った早い段階で既に知っていた issue である。クリティカルな内容ではないし、最悪 11 月までは猶予があると思っていたが、暇だったので~~渋々と~~対応した所存。基本的に公式のドキュメントを参考にすれば問題ないのだが、備忘録として対応内容をまとめておく。なお、今回は Android にのみフォーカスしているため、iOS や Unity の開発者は公式のドキュメントを見たほうが早い。

## 前提条件

各プラグイン及び SDK のバージョンは以下の通り。

- Google Services plugin: 4.2.0
- Firebase Crashlytics plugin: 2.2.0
- Firebase Crashlytics: 17.1.1

また、公式のドキュメントにも記載されている通り、新しい Crashlytics SDK は AndroidX に依存しているため、古いサポートライブラリのプロジェクトでは使えない点に注意。このタイミングで移行してしまうのがおすすめ。

## 変更箇所

### プロジェクトの `build.gradle`

```diff
buildscript {
    repositories {
-       maven { url 'https://maven.fabric.io/public' }
        google()
    }

    dependencies {
        classpath 'com.google.gms:google-services:4.2.0'
-       classpath 'io.fabric.tools:gradle:1.31.2'
+       classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
    }
}
```

Fabric の Maven リポジトリを削除し、Gradle プラグインを Firebase Crashlytics に置き換える。

### アプリの `build.gradle`

```diff
apply plugin: 'com.google.gms.google-services'
- apply plugin: 'io.fabric'
+ apply plugin: 'com.google.firebase.crashlytics'

dependencies {
- implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
+ implementation 'com.google.firebase:firebase-crashlytics:17.1.1'
}
```

Fabric のプラグインを Firebase Crashlytics のプラグインに置き換える。依存関係に Firebase Crashlytics SDK を追加する。

### パッケージ及びクラス名

```diff
- import com.crashlytics.android.Crashlytics
+ import com.google.firebase.crashlytics.FirebaseCrashlytics

- Crashlytics.doSomething()
+ FirebaseCrashlytics.getInstance().doSomething()
```

パッケージが `com.crashlytics.android` から `com.google.firebase.crashlytics` へ変更。機能の呼び出しも `getInstance()` によるシングルトンのインスタンスメソッド経由になる。該当箇所は Android Studio の Replace in Path(⇧⌘R) で一括置換が楽。

### 例外の送信

```diff
try {
    // Do something
} catch (e: Exception) {
-   Crashlytics.logException(e)
+   FirebaseCrashlytics.getInstance().recordException(e)
}
```

特に説明なし。変更理由は `log(String)` と明確な区別をつけたかったから。

### カスタムキー/バリュー

```diff
- Crashlytics.setString("str_key", "str_value")
+ FirebaseCrashlytics.getInstance().setCustomKey("str_key", "str_value")
```

`setXXX()` で Key-Value を設定していたが、全てが `setCustomKey()` へ集約された。

### クラッシュの検証

```diff
- Crashlytics.getInstance().crash()
+ throw RuntimeException()
```

動作確認のため意図的にクラッシュさせるメソッド `crash()` が削除された。

### デバッグ時の挙動

```diff
android {
    buildTypes {
        debug {
-           ext.enableCrashlytics = false
+           firebaseCrashlytics {
+               mappingFileUploadEnabled false
+           }
        }
    }
}
```

デバッグ時に Crashlytics を無効にする `ext.enableCrashlytics` フラグが削除され、`mappingFileUploadEnabled` フラグが追加された。

## その他

```diff
dependencies {
- implementation 'com.google.firebase:firebase-core:17.2.1'
+ implementation 'com.google.firebase:firebase-analytics:17.4.4'
}
```

Firebase Crashlytics 最適化のため、合わせて Google Analytics SDK の導入が推奨されている。既に `firebase-core` を導入してる場合、`firebase-analytics` へ置き換える。

## 参考

- [Upgrade to the Firebase Crashlytics SDK](https://firebase.google.com/docs/crashlytics/upgrade-sdk?platform=android)
Windows10のPCに分析環境（Python3＋Jupyter Notebook）を作ってみた

# はじめに

大学時代からプログラミングには慣れ親しんでいたが、社会人になってからはさっぱり。（Python大好き）
が、世の動向もあってか、ここ最近はAIやブロックチェーンという言葉を業務でよく使うようになってきた。
そのため、自宅のデスクトップPCにAIで主流なPython言語のプログラミング環境を改めて整備することを6月下旬に決意した！

普通にプログラミング環境（IDE）を整備しても面白くないので、データ分析界隈でスタンダードになりつつある、ツール「Jupyter Notebook」を使ってみようと思う。
（職場だと、AzureやAWSのクラウドリソースでJupyter Notebookを起動して一気に処理する、といったことも可能なのだが、個人利用だと難しく。。。）

[Project Jupyter](https://jupyter.org/)

## 本稿で紹介すること

- Jupyter Notebookのインストール
- Webブラウザで起動・表示するまでの環境設定

**ただし、Anacondaは本稿では使わない。便利だけれども。**

## 本稿で紹介しないこと

- Windows10のセットアップ（含むWebブラウザ）　※Windows10 Pro Ver.1909
- Python3のインストール　※Python 3.6.8を使用

# では早速、本題

## Jupyter Notebookのインストール

以下のコマンドを実行するだけ。とても簡単。

```python
$ python -m pip install pip -U
$ python -m pip install jupyter
```

以下、職場とか社内ネットワーク（プロキシ環境）向け。

```python
$ python -m pip install pip -U --proxy=http://${ProxyサーバのIPアドレス}:${ProxyサーバのPort番号}/
$ python -m pip install jupyter --proxy=http://${ProxyサーバのIPアドレス}:${ProxyサーバのPort番号}/
```

## Webブラウザで起動・表示するまでの環境設定

1. Jupyter Notebookの実行ファイルを探すと、以下。
*C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts*

2. 実行ファイル（jupyter.exe）を右クリックして、デスクトップにショートカットを作成

3. ショートカットのプロパティを開く

4. リンク先の値を編集
変更前：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe
変更後：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe notebook

5. 変更を反映
（「適用」ボタンを押下後、）「OK」ボタンを押下

6. Jupyter Notebookを起動
ショートカットをダブルクリック

![jupyter1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/69dbcfe8-fca6-d239-7df6-4f26f17249ba.png)

これだと、実行ファイルのある場所が初期（Home）画面として見えており、カッコ悪い。
というわけで、環境設定を追加。

## Webブラウザで起動・表示するまでの環境設定（追加）

1. 環境変数の追加  
   OS設定で環境変数「HOME」を新たに定義し、その値に初期画面で表示したいフォルダパスを指定。以下のコマンドの実行結果で、表示したいフォルダパスが表示されることが必要。  
   ```  
   > echo %HOME%
   ```  
2. ショートカットのプロパティを開く 

3. リンク先の値を編集 
変更前：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe notebook
変更後：C:\Users\\\${Windowsのログオンユーザ名}\AppData\Roaming\Python\Python36\Scripts\jupyter.exe notebook %HOME%

4. 変更を反映
（「適用」ボタンを押下後、）「OK」ボタンを押下

5. Jupyter Notebookを起動
ショートカットをダブルクリック

![jupyter2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/a119ede2-9e88-7b51-8b9e-fe351e3c0c69.png)

うまくいった！！！
ちゃんと事前にインストールしたPython3（Python 3.6.8）が使えている！！！

![jupyter3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/7c87db95-e346-411c-664b-f1882eca29b9.png)


# まとめ
Windows10のPCでPython3の使えるJupyert Notebookを整備。
これで、学生時代のようにPythonプログラミングを実践するぞ！
Laravelのブログ開発でmarkdown対応させてみた

# はじめに
Laravelを使ってブログを開発している際に見出しや装飾を本文に反映させてみたいな
と思い、markdown対応させてみました。
至らない点がありますが暖かい目でみてやってください。

### 使用するmarkdown
Markdown Extraを使用します。
また、ライブラリは[cebe\markdown](https://github.com/cebe/markdown)を使用します。

### markdown実装
markdownの実装自体は簡単なコードで完了します。

```convertMarkdown.php
 $converter = new \cebe\markdown\MarkdownExtra();
 $String = $converter->parse("# AAA"); // <h1>AAA</h1>
```

### Laravelプロジェクトに組み込む
convertMarkdown.phpで使用したコードをLaravelプロジェクトに組み込みます。
今回はブログでの使用なのでブログの本文が表示される画面で反映させたいので、
記事一覧画面（index.blade.php）と記事詳細画面（show.blade.php）に以下のコードを組み込みます。

```index.blade.php&show.blade.php
<div class="body">
   @php
     $converter = new \cebe\markdown\MarkdownExtra();
     $item->contents = $converter->parse($item->contents);
   @endphp  
   {!! $item->contents !!}
</div>
```

`{!! !!}`でHTMLの要素をそのまま表示させています。（Laravel標準のhtmlspecialcharsを解除）

### 動作確認
#### 記事一覧画面
###### markdown反映前
<img width="1161" alt="スクリーンショット 2020-08-04 19.50.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/fecbb7f4-a2f4-a8cf-2a73-0777508399f4.png">

###### markdown反映後
<img width="1153" alt="スクリーンショット 2020-08-04 19.52.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/8636c2c5-26d6-69e7-87b5-23a32f19e737.png">


####　記事詳細画面
<img width="1115" alt="スクリーンショット 2020-08-04 19.54.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/060d3ef3-9711-06c7-eab5-0d1a83a7f1dd.png">

###### markdown反映後
<img width="1122" alt="スクリーンショット 2020-08-04 19.55.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/ead3946a-a76c-93c3-8f94-064e142e3d8e.png">

### 終わりに
今回はLaravelを使ったブログにmarkdownを反映させる処理を書きました。
view部分にmarkdownの処理を書いたり、共通関数にしなかったりですっきりしたコードではないのですが、ひとまず実現できたのでOKとしています。
この記事に関して何かあればコメントや編集リクエスト投げていただけると幸いです！

### 参考文献
[PHPでMarkdownをいい感じにやる](https://blog.nasbi.jp/programming/php/nice-markdown-on-php/)
[Laravel 5.5 Bladeテンプレート](https://readouble.com/laravel/5.5/ja/blade.html)
Salesforceの関連リストで6つ以上の項目を表示する方法

通常だと、関連リストで6項目以上を関連づけすると、「**6+**」のように表示されてしまいますが、
以下方法で回避できます。

関連リストのあるSalesforce Objectの詳細画面から

 - 設定
 - 編集ページ
 - 関連リストをクリック
 - 右側のスペースの「関連リスト種別」で「拡張リスト」を選択する

以上です。これで最大30行まで表示できるようになります。
ちなみに、デフォルトの関連リストでは、4項目までしか横に表示できませんでしたが、この拡張リストを使えば、横に4項目以上表示することが可能になります。

完全に上位互換なので、拡張リストをデフォルトにしてほしいですね・・・
Laravel Eloquent の SELECT で CONCAT が使いたい

# やりたいこと
Eloquent 取得結果の頭に「'」をつけたい

## やったこと
select する時に、 CONCAT を使用した


fuga テーブルを元に、 hoge  テーブルを JOIN して、 hoge テーブルの tel カラムの頭に「'」を付与する。

```sql
DB::table('fuga')
->select(DB::raw('CONCAT("\'", hoge.tel) AS tel')
->join('hoge', 'hoge.fuga_id', '=', 'fuga.id')
->get()
```

ちゃんと頭に「'」ついてきたよ。

CONCATがうまく使えなくて、Eloquent の取得結果を加工する？ でも元のオブジェクトに戻すにはどうしたらいいの？ と迷走していました。
CONCAT使えて本当に良かった。
モバイルでのモーダル表示時の背景スクロール禁止処理 


以前よりhtml, body への `overflow:hidden;` はiOS Safari(webkit)では効かないため
 主にjQueryで `touchmove` イベントに  `preventDefault();` で対応していたが

```javascript:以前のコード
// スクロール無効
$(window).on('touchmove.noScroll', function(e) {
    e.preventDefault();
});  
// スクロール無効を解除
$(window).off('.noScroll');
```

`iOS 11.3  Safari 11.1`  及び `Chrome 51` 以降は `addEventlistner` の第3引数に　`{ passive: false }`  を渡して対応する必要がある。

```javascript
document.addEventListener('touchmove', function(e) {
    e.preventDefault();
}, { passive: false });
```

```javascript:ex
function scroll_control(e) {
    e.preventDefault();
}
function no_scroll(){
    document.addEventListener("touchmove", scroll_control, {passive: false});
}
function return_scroll(){
    document.removeEventListener('touchmove', scroll_control, {passive: false});
}
```

`preventDefault()` の付け外しは `ex` のように関数化しないとうまくいかなかった。
また'passive' オプションに未対応ブラウザのために `Polyfill` を書く必要がある。

```javascript:polyfill
// Test via a getter in the options object to see if the passive property is accessed
var supportsPassive = false;
try {
  var opts = Object.defineProperty({}, 'passive', {
    get: function() {
      supportsPassive = true;
    }
  });
  window.addEventListener("testPassive", null, opts);
  window.removeEventListener("testPassive", null, opts);
} catch (e) {}

// Use our detect's results. passive applied if supported, capture will be false either way.
elem.addEventListener('touchstart', fn, supportsPassive ? { passive: true } : false); 
```
※ `elem` `fn` の箇所と `{ passive: true }` を適宜変更して使用

## Browser
- webkit
 - https://bugs.webkit.org/show_bug.cgi?id=182521
- chrome
 - https://www.chromestatus.com/features/5745543795965952

## 対応方法の参考リンク
- スクロール禁止が `overflow:hidden` や `preventDefault();` でできないときの対処法
 - https://qiita.com/shge/items/d2ae44621ce2eec183e6
- マウスによるスクロールやスマホのスワイプを制御するjs(passive: false)
 - http://reiwinn-web.net/2018/05/21/%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%84%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%AE%E3%82%B9%E3%83%AF%E3%82%A4%E3%83%97%E3%82%92%E5%88%B6/
- Not working with iOS 11.3 Mobile Safari
 - https://github.com/timruffles/mobile-drag-drop/issues/124
- Can't prevent `touchmove` from scrolling window on iOS 
 - https://stackoverflow.com/questions/49500339/cant-prevent-touchmove-from-scrolling-window-on-ios

## Passive Event Listenersについての参考リンク
- Passive event listeners
 - https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
- Passive Event Listeners によるスクロールの改善
 - https://blog.jxck.io/entries/2016-06-09/passive-event-listeners.html
- Passive Event Listenersのミニマムpolyfillを書いた。
 - https://qiita.com/rukiadia/items/d2e8d5c45dc2fe299552
- addEventListener の第3引数が拡張されてるという話 
 - https://qiita.com/kozy4324/items/85831e2c990d92b8397b
constant force 2Dの解説

今回はPhysics2Dの中にある機能の一つである
「Constant Force2D」について説明しようと思います。

#Constant Force2Dとは？
Constant Force2Dとは、「**`一定の力を与え続ける機能`**」です。
簡単に言えば徐々に加速し続けるような感じです。
ちなみに、constant forceを和訳すると「一定の力」となります。

#Constant Force2Dのそれぞれのパラメータ
![constantForce2d_param.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/35a0a26e-06d4-8ca6-b9ee-d8ec9ebb39f7.png)
Constant Force2Dには「**`Force`**」、「**`Relative Force`**」、「**`Torque`**」という３つのパラメータ、更にforceとrelative forceには「X」と「Y」というパラメータがあります。
それを１つずつ解説していきます。

###・Force
forceは、ワールド座標を基準にしています。
なので、`物体が回ったとしても力が加わる方向は変わったりはしません`。
イメージとしては外部から一方向に押されている感じです。

 X は右に押す力、Y は上に押す力です。
それぞれの力をマイナスの値にすると逆方向に力が加わります。
![torokko_push_pig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/1e56bfd3-967a-3f14-f51b-96b90d920c81.png)Forceのイメージ図

###・Relative Force
forceとの違いはローカル座標を基準にしていることです。
なので、`物体が回ると力が加わる方向が変わります`。
イメージとしてはロケットのエンジンのように物体からエネルギーが放たれて、その反作用で動いている感じです。
![rocket_different_direction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/78e00d2f-887c-54fa-9c8d-b8423896d0b4.png)Relative Forceのイメージ図

###・Torque（トルク）
物体に回転力を加えます。
自転車を想像してください。自転車はペダルをこぐことによってタイヤに回転力が与えられ、前に進むという仕組みになっています。
１つ注意をしておくと、Torqueは反時計回りの方向が正の方向なので、そのまま「100」などの正の値を入れると左に転がって行ってしまいます。なので、右に行かせたい場合はTorqueに「-100」などの負の値を入れてください。

Torqueのイメージ図
![pyoko05_fast.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/377b538c-e166-7321-c0ff-78a8d1dceac5.png)


#Constan Force2Dをスクリプト上で変更する
Constan Force2Dのパラメータをスクリプト上で変更するときの書き方

`this.GetComponent<ConstantForce2D>().force = new Vector2(10, 0);`
`this.GetComponent<ConstantForce2D>().relativeForce = new Vector2(10, 0);`
`this.GetComponent<ConstantForce2D>().torque = -300;`


##終わりに
Constant Force2Dについて日本語でまとめられたものがUnityマニュアル以外見つからなかったのでこのブログを書いてみました。
これからいくつかPhisics2Dの各機能について書いてくつもりなのでよろしくお願いします。

>画像：いらすとや
【Python】Pythonスクリプトで自分がよく使うフレーズのメモ

# 今回の内容
Pythonスクリプトで自分がよく使うフレーズのメモです。
不定期に更新予定。内容が変わる可能性あり。



## 拡張子なしのファイル名を取得
[追記：2021-12-21]
拡張子も使うことが多いので、ファイル名と拡張子を取得。こっちのがわかりやすい。

```
import os
basename,ext = os.path.splitext(os.path.basename(filepath))
```



## コマンドライン引数（追記：2021-12-21）
【参考文献】[ArgumentParserの使い方を簡単にまとめた](https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0)
自分なりに使うものを抽出した。

```
import argparse

def get_args():
    parser = argparse.ArgumentParser('スクリプト説明')
    parser.add_argument('argv', nargs='*', help='引数の説明。必須引数')
    parser.add_argument('-a','--aaa',default='hogehoge', help='ヘルプ')
    parser.add_argument('-b','--bbb',action='store_true')
    return parser.parse_args()

def main():
    args = get_args()
    argv_list = args.argv
    aaa = args.aaa
    bbb = args.bbb

    ## 以下、何かしらの処理

main()
```



## スクリプトのあるディレクトリパスの取得（追記:2022-02-08）

スクリプトファイルを起点とした相対パス指定などに使う。

```
import pathlib
script_dir = pathlib.Path(__file__).resolve().parent
```



## ホームディレクトリ取得（追記：2022-05-31）

```
import os
homedir = os.path.expanduser("~")
```



## テキスト読込・書き込み（追記：2022-05-31）

```
## テキストファイル読み込み
with open('text_file') as f:
    text = f.read()
    text_l = [s.strip() for s in f.readlines()]

## テキストファイル書き込み
with open('text_file', mode='w') as f:
    f.write('文字列')
```



## テキストファイルかどうか判定

```
def is_text_file(file):
    def is_binary_string(Bytes):
        textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
        result = bool(Bytes.translate(None, textchars))
        return result
    result = is_binary_string(open(file, 'rb').read(1024))
    if result:
        return False
    else:
        return True
```



## 外部コマンド実行

```
import subprocess

cmd = "コマンド"
proc = subprocess.run(cmd, shell=True)

## 出力をテキストとしてしゅとく
output = subprocess.run(cmd, shell=True capture_output=True, text=True).stdout
```



## ディレクトリ名、ファイル名、拡張子の取得

```
import pathlib

p_file = pathlib.Path(file)
dirname = p_file.parent
name = p_file.stem
ext = p_file.suffix.lstrip('.')
```



## 一時ディレクトリ

```
import tempfile

with tempfile.TemporaryDirectory() as dname:
```



## タイムスタンプ取得（追記：2021-12-21）

```
import datetime
dt = datetime.datetime.now()
timestamp = dt.strftime('%Y-%m-%d')
```
Androidのキーボード表示非表示を検知する最も簡単な方法（だと思う）

Androidではキーボードの表示/非表示を検知する方法が標準では用意されていないんですよね。。。

実際、ナビゲーションバーを非表示にしておきたい場合など、キーボードが表示されたタイミングを検知したい場合が多々あったため
よい方法はないかとググりました。

Activityの高さの変化などを取得し、キーボードの状態変化を検知する方法等ありますが、
最も簡単な方法かと思われる素敵なライブラリが公開されていたので共有です。

https://github.com/yshrsmz/KeyboardVisibilityEvent

このような素敵なライブラリが埋もれているのは勿体ないのでお勧めです。
Karabiner-ElementsでimportしたEmacs key bindingsを改変してC-iに文節短縮とTabを共存させる

## 実現したいこと
日本語入力中はC-iで文節短縮、それ以外はC-iにTabをキーバインドする。

## 環境
OS: macOS Catalina
キーバインドソフト: Karabiner-Elements
改変元設定ファイル: [Emacs key bindings (rev 12)](https://ke-complex-modifications.pqrs.org/#emacs_key_bindings)
キーボード: Royal Kludge RK71

## 設定方法
### 設定ファイルを開く
ターミナルからKarabinerの設定ファイル格納ディレクトリをopenする。

```zsh
% open ~/.config/karabiner/assets/complex_modifications/
```

インポートしたjsonファイルが入っているので、Emacs key bindingsに対応するjsonを見つけ出す。

### 設定ファイルに追記する
`tab`でファイル内を検索すると2箇所ヒットする。

 - 通常の[control+keys]
 - vscode用の[control+keys]

使用するほうに以下を追記する。

```json:追加文字列
{
  "type": "input_source_unless",
  "input_sources": [
    {
      "language": "ja"
    }
  ]
},
```

追加する位置は以下(‘+’は位置をわかりやすくするために付加しているだけなので取り除く)。

```diff:1595373361.json
 "to": [
   {
     "key_code": "tab"
   }
 ],
 "conditions": [
+  {
+    "type": "input_source_unless",
+    "input_sources": [
+      {
+        "language": "ja"
+      }
+    ]
+  },
   {
     "type": "frontmost_application_unless",
```

条件指定は`input_source_if`で`en`の場合を指定してもよいが、上記のように`input_source_unless`で`ja`でない場合として指定したほうが、より確実性が高いと思われる。

### 状態の確認
Karabiner-EventViewerでちゃんと`input_source`切り替えが発火しているか見る。
IME状態はVariablesタブで確認できる。

## 付記
今回、Qiita初投稿でした。
ふだんは[個人ブログ](https://thanaism.com/)に投稿しています。
Automation Anywhere A2019で新しいウィンドウでウェブページを開く方法

#※こちらの記事の情報は古いですが、アーカイブとしてこのままにしておきます。 現在のAutomation 360(A2019)ですとブラウザアクションにおいても「新しいウィンドウ」で開けるように改善されています。

標準で用意されている**ブラウザ: Webサイトを開く**アクションですと、新しいタブで指定したWebページが開いてしまいます。
新しいウィンドウで開きたい場合、現状、以下のような方法があります。（Google Chromeの例）
アクション側に機能追加されると不要になる情報ですが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/c3ed48cc-e786-cd0e-6c9b-8c5221f65b56.png)
[Docker] Unsupported config option for services service: ‘app’ エラー

docker-compose.yml を書き換えた時にでたエラー



```
Unsupported config option for services service: ‘app’
```




原因として、docker-compose が古いらしい

最新のバージョンに変更する必要がある


```
curl -L “https://github.com/docker/compose/releases/download/バージョン指定/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose

```



最新のバージョンを見るには　[こちらから](https://docs.docker.com/compose/release-notes/)

 
完了:relaxed:

 

参考記事：
https://qiita.com/takepan/items/172302ecb1ead91c0cab
HTML5で正規表現を使わずにバリデーションしよう！（特定の範囲の数字だけ認める）

# この記事でわかること

- n以上の整数だけを認める入力ボックスの実装方法がわかる
- m以下の整数だけを認める入力ボックスの実装方法がわかる

# そもそもバリデーションとは

> 記述に用いた言語の文法や、そのプログラムに要求される仕様（書の記述）に則って正しく記述されているかを検証することを表す。
IT用語辞典 e-Words


# 背景
『グラブルダメージ上限計算機』というものを制作したのですが、その中にはテキストボックスが含まれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/9ceaf571-4b7c-9b6b-8709-971dc96c79ec.png)

```html
<input type="txt" size="8" id="other" value="0"/>%
```


このテキストボックスには本来、**半角で 0以上の整数** を入力してほしいのですが、
例えば数字以外のもの、"hoge"を入力すると意図しない出力（NaN）がなされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/692ab211-188b-465f-25a6-37844b23dc46.png)

**0以上の整数の入力だけを受け付ける入力ボックスを作ろう！**というのが今回の目的です。
しかも**ややこしそうな正規表現は使いたくない**という条件で。

（正規表現は難しくないよ、という意見もあるかもしれませんが、ここでは割愛させてください。）

# 正規表現を使わないで済ませるには

input要素のtype属性をnumberに指定し、
さらにmin属性を使って、その最小値を0にします。
最小値を0以外にしたい場合は、この数値を任意に変更します。

補足として、n以下の数字だけを認めたい！という場合は、min属性をmax属性に置き換えればよいです。

その他、idやsizeなども適宜、変更や追加・削除してください。

```html

<input type="number" size="8" id="other" value="0" min="0" />%
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549712/58a5ecea-fa48-acc3-f7cc-35838db91646.png)

# おわりに（注意書き）

今回取り扱ったものはHTML, CSS, JavaScriptだけで構成されたWebページであるので、
こういったバリデーションで十分なのですが（というかそれしかできなさそう）、

データベースを利用した動的なWebアプリケーションなどの場合、
サーバーサイド側でもバリデーションを実装する必要があります。


自分の想定できる範囲でも、GoogleChromeのデベロッパーツールなどを利用すればバリデーションは解除できますし、
他にバリデーションをかいくぐる手段はたくさんあると思います。

危険！

# 参考

- [正の整数のみのHTML入力（Type = number）](https://www.it-swarm.dev/ja/html/%e6%ad%a3%e3%81%ae%e6%95%b4%e6%95%b0%e3%81%ae%e3%81%bf%e3%81%aehtml%e5%85%a5%e5%8a%9b%ef%bc%88type-number%ef%bc%89/1055450892/)
- [HTML5タグリファレンス] (http://www.htmq.com/html5/input_min.shtml)
シンプルなテーブルcss

今回はvue.js バージョン。

そのままコピペなので、参考程度にどうぞ。

```

<style>

    table.simple {
        border: 1px solid #ededed;
        width: 99%;
        margin: auto;
    }

    table.simple th  {
        padding: 5px;
        border-bottom: 1px solid #ededed;
        background-color: #2cb696;
        color: #fff;
    }

    table.simple td , table.simple th  {
        padding: 5px 15px;
        border-right: 1px solid #ededed;

    }

    table.simple td:last-child ,  table.simple th:last-child  {
        border-right: 0px;
    }

    table.simple tr  {
        border-bottom: 1px solid #ededed;
    }


</style>

<template>

            <div>

                <table class="simple">

                    <tr>
                        <th>入金日</th>
                        <th>売上</th>
                        <th>タイプ</th>
                    </tr>

                    <tr>
                        <td>5月14日</td>
                        <td>3,000円</td>
                        <td>果物</td>
                    </tr>

                    <tr>
                        <td>5月22日</td>
                        <td>5,300円</td>
                        <td>米</td>
                    </tr>

                </table>

            </div>


</template>

```
Anaconda3とVScodeをつかう最初の手順-インストールと環境設定-Windows10 

キノコードさんの動画をみながら設定した記録です
https://www.youtube.com/watch?v=Cs7friXdqdM
VScodeでなくAnacondaにも入っているjupyter Labの立ち上げ方に最初つまづいたのでおまけで最後にメモしました。

# Anacondaインストール

## 1) 公式サイト
https://www.anaconda.com/products/individual
の下の方からダウンロード

## 2)exeファイルを実行してインストール
そのままどんどんすすめてインストールを完了させる

## 3) パスの設定(立ち上げやすくする)
PC内検索（Windows10なら画面左下の検索窓）で
「システム環境変数」
　↓
環境変数のボタンをクリックし、リスト内のPath　の行をクリック
　↓
新規
　↓
c:\Users\自分のフォルダ\Anaconda3
を入力→OKしてウインドウを閉じたらPCを再起動
　↓
再起動したら、コマンドプロンプト(PC内検索で「コマンドプロンプト」で探せる)で
python -V(大文字)
と入力
Anacondaのバージョンが表示されれば環境変数の設定まで全て完了

# VScode(入力用のエディタ-編集アプリ)インストール

## 1) 公式サイト　User Installer 64 bitをダウンロード
https://code.visualstudio.com/Download

exeファイルを実行し、インストールを進める。
完了前の表示設定（チェックボックスが沢山でる）で
「デスクトップにアイコンを表示する」**以外**にチェックしインストール
タスクパーに出ているアイコンを右クリックし、タスクバーに表示させておくと便利

## 2) 拡張機能(日本語表示とPython拡張)

インストール完了後、立ち上げたら左メニューの□がかさなったアイコン「拡張機能」をクリック

### (1)日本語表示にする

拡張機能のウインドウ内の検索窓で
「Japanese Language Pack for Visual Studio Code」と入力
Japaneseだけで候補が出る
　↓
Install(インストール)のボタン(小さい四角)をクリック
インストールの表示が消えたら完了
右下の「Restart Now」を押すか、VScodeを閉じて再起動

### (2)Python拡張機能をインストール
VScodeが再起動したら、また左のメニューから拡張機能を立ち上げ、検索窓に
Pythonと入力、でてきた候補の中から
Python Extension Pack
をクリックし、同じくインストール

### (3)VScodeにAnacondaのパスを設定する(使い始めやすくする)
上のメニューから「ファイル」→ユーザー設定→設定を順に選択
設定のウインドウの上端の検索欄に以下を入力
python.pythonpath
　↓
表示された枠内に自分のpython.exeの場所を入力
例)
C:\Users\自分のユーザーフォルダ名\Anacond3\python.exe
　↓
入力が終わったらVScodeを再起動する(VScodeのウィンドウを閉じて再度起動する)

# jupyter Labの立ち上げ方

Anacondaをインストールすれば自動で入っているjupyter Lab
VScodeでなくjupyter Labで立ち上げる場合、Windowsのコマンドプロンプトからだとうまく立ち上がらないので

PC内検索からPC内の
Anaconda prompt
を探して起動するとうまくいく。
ターミナルでコマンドの標準出力／標準エラー出力をそれぞれ複数ファイルにリダイレクトするfanout.sh

# 動機

あんまり機会／需要はないと思うが、あるコマンドの出力を複数のディレクトリに置きたくなることがあった。
基本的には、`tee`コマンドを使えばいいのだが、標準出力／標準エラー出力を分けたり、さらなる別コマンドにパイプできるように`fanout.sh`としてスクリプト化した。[別記事](https://qiita.com/Nanigashi_Uji/items/1f447416f54cb510cb84)にあるように、`source`しても使えるように実装した。

## ファイル置き場

- [github](https://github.com/nanigashi-uji/fanout_sh)
- [gitlab](https://gitlab.com/nanigashi_uji/fanout_sh)

## 基本的な使い方

```bash:ヘルプ表示
% fanout.sh [options] [-o file] [-e file] [cmd [cmd_options .... ]]
[Options]
           -k      : Keep stdout/stderr (default)
           -d      : No stdout/stderr output
           -a      : append to existing files
           -m      : merge stdout and stderr outputs.
           -o path : file name to dump stdout
           -e path : file name to dump stderr
           -h      : Show Help (this message)
```
コマンドライン引数`cmd [cmd_options]`を実行し、標準出力を`-o`オプション引数で指定されたファイルに、標準エラー出力を`-e`オプションで指定されたファイルに保存する。

`-o`オプションは、`-e`オプションは**複数指定できる**。(これがこのスプリプトのご利益)

コマンドライン引数`cmd [cmd_options]`が指定されなかった場合には、標準入力からの入力を表示する。(つまり`cat`コマンドが呼ばれる。)　

`-o`もしくは`-e`オプションが1つも指定されない場合には、単にコマンドを実行する。

## その他のオプションの紹介

- `-k` :　 実行したコマンドの出力/エラー出力をさらに標準出力(`fd:1`)/標準エラー(`fd:2`)に出力する。（デフォルトの動作）
- `-d` : 　`-o`オプションが指定されていれば、実行したコマンドの出力はファイルにリダイレクトし、このコマンドの標準出力(`fd:1`)には出力しない。`-e`オプションが指定されていれば、実行したコマンドのエラー出力はファイルにリダイレクトし、このコマンドの標準エラー出力(`fd:2`)には出力しない。(`-k`オプションの逆)
- `-m`:  `-o`オプション,`-e`オプションで指定されたファイルに実行したコマンドの出力とエラー出力の両方をまとめてリダイレクトする。
- `-a`: `-o`オプション,`-e`オプションで指定されたファイルに追記する。(`tee -a`,リダイレクション`>>`に相当)

## スクリプトの中身

- 中身は`tee`とリダイレクションをしているだけの`bash`スクリプトである。 エラー出力を`tee`を用いて複数ファイルに保存するため、サブシェルでファイルディスクリプタ複製を行なっている。下記のように

```bash:例
% ((cmd cmd_options | tee o1 | tee o2 ) 3>&2 2>&1 1>&3  | tee e1 | tee e2 ) 3>&2 2>&1 1>&3  1>o0 2>e0
```
とすると、`cmd cmd_options`の実行結果の出力を`o1`,`o2`に出力し、ファイルディスクリプタを切り替えて実行結果のエラー出力を`e1`,`e2`にリダイレクトしたのち、もう一度ファイルディスクリプタを切り替えて元に戻す、といったことを行う。

- `-m`オプションと`-k`オプションが同時に指定された場合には、実行コマンドの出力とエラー出力をまとめて保存しつつ、標準出力(`fd:1`)／標準エラー出力(`fd:2`)にはまとめずに出力／エラー出力をそれぞれ出すようにするため、名前付きパイプを用いている。下記のような例では、`cmd cmd_options` の実行結果の出力とエラー出力を名前付きパイプを用いてそれぞれ標準出力(`fd:1`)、標準エラー出力(`fd:2`)に出力しつつ、実行結果の出力とエラー出力をまとめてファイル`m1`,`m2`にリダイレクトする.

```bash:例
% mkfifo sobuf
% mkfifo sebuf
% cat < sobuf &
% cat < sebuf 2>&1 &
% ((cmd cmd_output | tee sobuf ) 3>&2 2>&1 1>&3  | tee sebuf )  2>&1 | tee m1 > m2 
% rm sobuf sebuf 
```
## 実装

`-d`/`-k`オプションの切り替えなどは`/dev/null`をうまく使えば、スクリプトとしてはもっとシンプルに書けるとは思うが、不必要なリダイレクションは行わないように愚直に場合分けした。
【アルゴリズム】予算

# 問題説明
A社では各部署に必要なモノを支援するため、部署ごとにモノを買うのにいくら必要なのかを調べました。
でも、全体予算は決められているためすべての部署にモノを提供はできません。
それで、最大限に多い部署にモノが買えるようにしようと思っています。

モノを買うときは各部署が申請して金額全部を支援しなければなりません。
例えば1,000円を申請した部署には必ず1,000円を支援すべきであり、1,000より少なくは支援できません。

部署ごとに申請した金額が入っている配列dとbudgetがパラメータとして与えられる場合、最大いくつの部署にモノが支援できるかがreturnされるようにsolutionメソッドを作成してください。


# 条件
- dは部署ごとに申請した金額が入っている配列であり、長さ（全体の部署数）は1以上100以下です。
    - 例）d.length = 2の場合、部署数は2。
    - 例）d[0]= 3の場合、部署1の申請金額は3。
- dの値は部署ごとに申請した金額です。申請金額は1以上、100,000以下の自然数です。
- budgetは予算です。予算は1以上、10,000,000以下の自然数です。

# 入出力の例
| d       |       budget |    result    |
|:-----------------|------------------:|:------------------:|
| [1,3,2,5,4]             |              9 |        3        |
| [2,2,3,3]           |            10 |       4       |


# 解説
※解説は私が作成したコードなので、もっといいアルゴリズム等々ありましたら、共有してください！

```java

import java.util.Arrays;

class Solution {
    public int solution(int[] d, int budget) {
        
        Arrays.sort(d); // 昇順ソート
        
        int cnt = 0; // 支援できる部署のカウンター用
        for (; cnt < d.length; cnt++) {
            budget -= d[cnt]; // 支援するたびに、予算から削減していく
            
            if (budget < 0) break;
        }
        
        return cnt;
    }
}
```
UIDocumentPickerViewControllerで選択ファイルを絞る & iOS14からのUTType

# ユーザーの選択ファイルを限定したい

最近のプロジェクトで端末内の.m4a, .mp3ファイルだけ選択させたい用件があったのでUIDocumentPickerViewControllerでdocumentTypesを指定して実装しました。

その時に__MobileCoreService__の定数を使って処理していたのですが、非推奨の扱いになっていたので合わせて__iOS14以降のUTType__について調べました。

ちなみに非推奨の実装でベータのiOS14のシュミレータで実行してみましたが、ワーニングが出るだけで動作はしていました。

## iOS13までの実装

Xcode 11.5(11E608c)

```swift
import UIKit
// 1. MobileCoreServicesをインポート
import MobileCoreServices

class FileSearchViewController: UIViewController {

    // ~~~ 省略 ~~~
    
    private func showFilePicker() {
        // 2. documentTypesでkUTType~で選択して欲しいファイル形式を指定する
        // iOS14だと　'init(documentTypes:in:)' was deprecated in iOS 14.0と怒られる
        // ここでは選択できるファイルを.m4a, .mp3に限定する
        let picker = UIDocumentPickerViewController(
            documentTypes: [
                String(kUTTypeMPEG4Audio),
                String(kUTTypeMP3)
            ],
            in: .import)
        picker.delegate = self
        self.navigationController?.present(picker, animated: true, completion: nil)
    }
}

extension FileSearchViewController: UIDocumentPickerDelegate {
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        // ファイル選択後に呼ばれる
        // urls.first?.pathExtensionで選択した拡張子が取得できる
        
        if let filePath = urls.first?.description {
            print("ファイルパス:\(filePath)")
        }
    }
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        print("キャンセル")
    }
}
```

選択できるファイルはこちらのUTTypeのContentsから選べます。
[Apple Document: MobileCoreServices/UTType](https://developer.apple.com/documentation/mobilecoreservices/uttype)


## iOS14以降の実装（ベータなので変更になるかもしれません）

主な変更は１と２のimportとUIDocumentPickerViewControllerの呼び出し方とUTTypeの指定です。

Xcode 12.0 beta 3 (12A8169g)

```swift
import UIKit
// 1. UniformTypeIdentifiersをインポート
import UniformTypeIdentifiers

class FileSearchViewController: UIViewController {

    // ~~~ 省略 ~~~
    
    private func showFilePicker() {
        // 2. forOpeningContentTypesでUTTypeで選択して欲しいファイル形式を指定する
        // ここでは選択できるファイルを.m4a, .mp3に限定する
        let picker = UIDocumentPickerViewController(
            forOpeningContentTypes: [
                UTType.mpeg4Audio,
                UTType.mp3
            ],
            asCopy: true)
        picker.delegate = self
        self.navigationController?.present(picker, animated: true, completion: nil)
    }
}

extension FileSearchViewController: UIDocumentPickerDelegate {
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        // ファイル選択後に呼ばれる
        // urls.first?.pathExtensionで選択した拡張子が取得できる
        
        if let filePath = urls.first?.description {
            print("ファイルパス:\(filePath)")
        }
    }
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        print("キャンセル")
    }
}
```

[Apple Document: UniformTypeIdentifiers](https://developer.apple.com/documentation/uniformtypeidentifiers)
P5.js 日本語リファレンス(translate)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の translate 関数を説明します。

## translate() 

### 説明文

表示ウィンドウ内のオブジェクトを移動する量を指定します。 x パラメータは左/右への移動を指定し、y パラメータは上/下への移動を指定します。

変換は累積的であり、関数への後続の呼び出しが効果を累積した後に発生するすべてに適用されます。たとえば、translate(50, 0) を呼び出してから translate(20, 0) を呼び出すことは translate(70, 0) と同じです。 draw() 内でtranslate() が呼び出された場合、ループが再び始まると変換がリセットされます。この関数は push() および pop() を使用してさらに制御できます。

### 構文

translate(x, y, [z])

translate(vector)

### パラメタ

- x
Number：左/右変換

- y
Number：アップ/ダウン変換

- z
Number：順方向/逆方向変換(webglのみ)(オプション)

- vector
p5.Vector：変換するベクトル


### 例1

```javascript
function setup() {
  createCanvas(400, 400);

  stroke("red");
  rect(0, 0, 55, 55);
  
  stroke("green");
  translate(30, 30);
  rect(0, 0, 55, 55);
  
  stroke("blue");
  translate(30, 30);
  rect(0, 0, 55, 55);  
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/PI43OkNFn


### 例2

```javascript
function setup() {
  createCanvas(200, 200);
}

function draw()  {
  background(200);

  rectMode(CENTER);
  translate(width / 2, height / 2);

  // ミリ秒を1000で割った数を角度とし長さ60のベクトルを作成する。
  // (回転する半径が60になる)
  translate(p5.Vector.fromAngle(millis()  / 1000, 60));
  rect(0, 0, 20, 20);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/tVYVP1BjY


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。