OmniAICreator/Qiita-1.07M huggingface dataset:
Archbangにwineをインストールする

Archbangにwineをインストールする備忘録です。
--
https://qiita.com/syui/items/6d5e7fff23e5915133c6
ほぼ @syui さんの記事の通りなんですが(わかりやすく参考になりました。thanks a lot!)、2点付記します。

```
$ mkdir -p ~/.wine/drive_c/windows/Fonts
$ sudo pacman -S zenity
```

これを行ってください。
タイミングは、

+ mkdirが上の @syui さんの記事の # 文字化けを直す の前
+ zenityのインストールが # フォントを綺麗にする(不要) の後、winetricksのGUI起動前

です。それぞれエラーが出るのでArch使いの方でしたらガイド不要かもと思いつつ。以上です。
ＣでHelloWorld!を出力する


#CでHelloWorld!
###開発環境
- Windows 10
- Visual Studio2019

###Visual Studio Community 2019 をインストールする。
####インストーラをダウンロードする
[公式サイト](https://visualstudio.microsoft.com/ja/downloads/)からインストーラをダウンロードする。
**無料ダウンロード**をクリックすると半自動的にインストーラーがダウンロードされます。
![VS_Site.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/8a3d459a-65ab-527f-c018-21aadb6facc7.png)

####インストーラを実行してインストールする
インストーラが起動したら続行をクリックします。
![VS_installer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/a0dabec8-021f-fc75-10d4-bae879ea2f1a.png)
C++によるデスクトップ環境にチェックを入れて
インストールボタンをクリックし、インストールします。
![VS_installer2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/e5b21114-5ba9-0355-910b-3d19ae63c961.png)
インストールが開始され、イントールが完了したら、PCを再起動をします。

###Visual Studio2019 を起動する
Windowsキーを押下し、Vの位置にあるVisual Studio2019を選択する。
![win.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/79d1963b-e6b3-1b51-92b8-4a9d13d8a022.png)
****
＊起動したらサインインを求められることがあります。
サインインまたは後で行うを選択してください。
**アカウントを作成し、サインインを行うことを推奨します。**
テーマ選択は自由に選んでください。
***

起動したら新しいプロジェクトの作成を選択します。

![vs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/335f8576-8247-7004-3bb7-036ad9e98091.png)

空のプロジェクトを選択し、次へをクリック。
![vs2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/de3fe9dc-e447-4e30-c89e-f77b368a5407.png)

プロジェクト名をProject_Helloとします。（デフォルトでも可）
プロジェクト名を入力したら作成をクリックします。
![vs3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/5ad38c22-01fe-e7b7-ae64-abf119991dff.png)

起動したら「ソースファイル」を右クリックし、追加を選択、新しい項目をクリックします。
![vs4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/ef6a097a-7c9c-bb23-d839-8c55c67ba549.png)

C＋＋ファイルを選択し、名前をHello.cppとして、追加をクリックします。
![vs5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/07c9fe4d-69be-8bd1-297c-f365929e6703.png)

追加できると、Hello.cppが開き記述できるようになります。
![vs6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/981d94e0-aff3-1f20-a716-64c3216cd15f.png)
以下のコードを記述します


```Hello.cpp
#include <stdio.h>

int main() {
	printf("Hello World!");
	return 0;
}
```
記述し終えたら、ローカルWindowsデバッカーで実行します。
![vs7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/61f41bbe-c7ee-57d1-98a2-f739fa03d0d9.png)

するとプロンプトが表示され、実行結果が出力されます。
![vs8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639011/3a98b330-8a97-a5b2-5274-5fd1776b5a9e.png)

以上。
【kintone】標準機能でsinX、cosX、tanXを求める

以前、標準機能で平方根を求める方法について書きました↓が、
https://qiita.com/juri_don/items/dd7b2d6ab4fb045990b6

今回は標準機能で三角関数のフィールドXに角度を入力したら、sinX,cosX,tanXを求める。というアプリを作ってみたいと思います👀！

# kintoneのアプリ上で使う式

テーラー展開という関数を多項式で近似する方法がありまして、
sinX, cosXをx=0のまわりでテーラー展開すると

```math
\sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + ・・・\\

\cos x = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} - \frac{x^6}{6!} + ・・・
```

と近似することができます。

tanX は

```math
\tan x = \frac{\sin x}{\cos x}
```
で求めます。

これらをkintoneの標準機能で計算してみたいと思います。


# フォームの作成

ええと、作るの大変です👀
各フィールドの設定は、下の一覧表通りにやってね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/af4e5b79-e71f-c9dd-88b6-12a2235bc293.png)

| フィールド種類 | フィールド名 | 計算式・初期値|フィールドコード |
|:-:|:-:|:-:|:-:|
| 数値  |  X（度） | 手入力  |Xdo_0  | 
| 計算  |  sinX |X-X3+X5-X7+X9-X11+X13   |  sinX |
|  計算 |  cosX | 1-X2+X4-X6+X8-X10+X12-X14  | cosX  |
|  文字列(1行) | tanX  | IF(cosX<>0,sinX/cosX,"∞") | tanX  | 
|  計算 | X(度）  |  Xdo_0 - ROUNDDOWN(Xdo_0/180)*180 |   Xdo|
| 計算  |X   | Xdo/180*π  |  X |
|  数値 | π  |3.14159265359   | π  |
| 数値  | 2の階乗  |  2 |  f2 |
| 数値  | 3の階乗  |  6 |  f3 |
| 数値  | 4の階乗  |  24 | f4  |
| 数値  | 5の階乗  |  120 | f5  |
| 数値  | 6の階乗  |  720 | f6  |
| 数値  | 7の階乗  |  5040 | f7  |
| 数値  | 8の階乗  |  40320 | f8  |
| 数値  | 9の階乗  | 362880  | f9  |
| 数値  | 10の階乗  |  3628800 | f10  |
| 数値  | 11の階乗  | 39916800  | f11  |
| 数値  | 12の階乗  | 479001600  | f12  |
| 数値  | 13の階乗  |6227020800   | f13  |
| 数値  | 14の階乗  |  87178291200 | f14  |
| 計算  |  x^2/2! |  x^2/f2 |  X2 |
| 計算  |  x^3/3! |  X^3/f3 |  X3 |
| 計算  |  x^4/4! |  X^4/f4 |  X4 |
| 計算  |  x^5/5! |  X^5/f5 |  X5 |
| 計算  |  x^6/6! |  X^6/f6 |  X6 |
| 計算  |  x^7/7! |  X^7/f7 |  X7 |
| 計算  |  x^8/8! |  X^8/f8 |  X8 |
| 計算  |  x^9/9! |  X^9/f9 |  X9 |
| 計算  |  x^10/10! |  X^10/f10 |  X10 |
| 計算  |  x^11/11! |  X^11/f11 |  X11 |
| 計算  |  x^12/12! |  X^12/f12 |  X12 |
| 計算  |  x^13/13! |  X^13/f13 |  X13 |
| 計算  |  x^14/14! |  X^14/f14 |  X14 |

# 試してみる

なんとなく↓このあたりを試してみました。
0度、60度、90度、720度, -135度, 70度

↓こちらで確かめたら大体あっていました。だいたいですが。
https://keisan.casio.jp/exec/system/1260261251

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/dd53ee6e-c124-91d4-4d17-4d441e045cba.png)

# まとめ
無理やり三角関数の計算をしてみました。
これをするくらいなら、素直にJavaScriptを書いたほうが早いし、精度も高いと思います。
しかしどうしても・・・というときはこれで三角関数（近似値）で計算できます👀試してみてね！

では今回はこのへんでﾉｼﾉｼ
【ネットワーク用語】ISDNとは

ISDN(Integrated Service Digital Network)は__[ADSL](https://qiita.com/sasami_dc2/items/5cfb3110dbf1d052519d)__のように電話回線を使用している。しかし、アナログではなくてデジタル回線となる
また、１つの電話番号で2つの回線を利用できる。そのため1つの番号で電話とFAXの同時受信が可能となる。
Java -versionのように、「_」の後の値をWindowsバッチで取得する方法

```bat:sample.bat
@echo off
for /f tokens^=2-5^ delims^=.-_^" %%j in ('java -fullversion 2^>^&1') do set "javaV=%%m"

echo %javaV%
pause
```

####ポイント
Javaのバージョン取得コマンドは何故かエラー出力扱いになる。
target="_blank"にはrel="noopener noreferrer"をつける

忘れがちなのでメモ

```react
<a
  href="https://example.com"
  target="_blank"
  rel="noopener noreferrer"
>
  リンク
</a>
```

Reactでeslintを使ってるなら[react/jsx-no-target-blank](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md)を `error` にする

```.eslintrc.js
module.exports = {
  // ~ 略 ~
  rules: {
    'react/jsx-no-target-blank': 'error',
  }
}
```
個人的phpenv installの備忘録

# システムにPHPを入れたくない！
開発機というかいつも使う環境にシステムのパッケージマネージャでPHPをインストールして、システムを汚染するのは愚の骨頂だと考えているので、できるだけphpenvを使ってユーザランドだけで完結したい。

# phpenvの導入
anyenvで楽をしましょう
https://github.com/anyenv/anyenv

# ビルドに必要なパッケージを追加
Arch Linuxでビルドしようとしたときに無いって言われたので、以下のパッケージを追加しておく

- oniguruma (正規表現系の処理ライブラリ)
- tidy (HTTPのパーサライブライ？)
- libzip (見てわかるとおりzipのライブラリ)


# phpのビルド
開発環境なのでとりあえずdevelopmentで入れる。
あとビルドするときに並列処理をしてもらいたいのでmakeの変数も指定しておく。

```shell
export PHP_BUILD_EXTRA_MAKE_ARGUMENTS="-j $(nproc)"
phpenv install -i development -v [任意のバージョン]
```

# 以上！
いかがでしたか？(←なんか入れなければならない気がした)
秀丸でハマった話（VirtualStore）

OS：Windows10

**C:\Program Files** にあるファイルを秀丸で編集・保存した。
何となくメモ帳で開いたところ、編集前と変わってない。
「えっ？」と思い、秀丸で開くと、ちゃんと編集されている。
色々調べてみると**VirtualStore**というWindowsの仕様。

秀丸はこのVirtualStoreが**デフォルトで有効**になっているので、Program Files配下のファイルを編集しても、実際は
**%LocalAppData%\VirtualStore**
配下のファイルを編集している事になる。
sakuraやメモ帳でProgram Files配下のファイルを開くと、VirtualStoreフォルダは参照しないので、問題なし。

プログラマのかたは特にお気を付けください。。
因みに C:\Windows フォルダでも同じ動きをします。
【PHP】mb_substr()は遅い

# 環境
PHP：7.1.21

#内容
下記のような処理がありました（簡素化してます）。

入力された文字列を、[mb_substr()](https://www.php.net/manual/ja/function.mb-substr) で１文字ずつ切り取ってチェックしていました。
処理速度に問題はありませんでした。

```php
//住所・氏名など
$src = '入力された文字列';

$count = mb_strlen($src);

//１文字ずつチェック
for ($i=0; $i<$count; $i++) {
    $moji = mb_substr($src,$i,1);
}
```

ある日、上記処理に、１００ＫＢ以上の文字列を渡しました。
するとタイムアウトが発生しました。

```php
Fatal error: Maximum execution time of xx seconds exceeded in /foo/bar/xxxx.php on line xxx
```

何でそんなに時間かかるの？ と思いましたが、
原因を推測すると、こういうことなんじゃないかと。

mb_substr() は何かしら文字コード変換をおこなうのですが、
「１文字 切り取って文字コード変換」ではなくて、
「文字列全部をコード変換して、１文字 切り取る」なのでしょう。

つまり、上記処理にマルチバイトの 100,000文字が渡されたら、

>100,000文字 ｘ 100,000ループ ＝ 10,000,000,000文字

１００億文字のコード変換をおこなうことになります（推測ですが）。
（１００億文字は Shift_JIS だと約２０ＧＢかな？）

文字数の２乗に比例して遅くなる計算です。
そりゃタイムアウトになります :sob:

ちなみに上記処理の mb_substr() を [substr()](https://www.php.net/manual/ja/function.substr) にすると、一瞬で完了します。
やはりマルチバイトの処理で時間がかかっているようです。

# さいごに

mb_substr() が遅いというより、私の使い方に問題があるとも言えます。

ちなみに１００ＫＢ以上の文字列を、分割して数回に分けて渡したら、
タイムアウトはしなくなりました。

#参考

[mb_substrが遅い](https://www.cyberbrain.co.jp/news/detail/134/)
複数ファイルを一括読み込み&縦に結合(DataFrame)

# 0:はじめに
業務のデータ分析をする際に、**複数のファイル**を扱うことはありませんか？

例えば、**1年分のデータ**を**(2019_01.csv,2019_02.csv, .. .. ,2019_12.csv)**と１２個のファイルを用意される場合を考えて見てください。

一つずつ読み込み・結合するのは面倒くさいですよね。。

ここで便利なコードを紹介します。
(**今回はカレントディレクトリに複数ファイルがある場合を想定します。**他のディレクトリにある場合は、各々で引数に指定のディレクトリを当てはめて下さい。)


# 1:カレントディレクトリを取得
```py
import os

#カレントディレクトリ取得
current_dir = os.getcwd()
current_dir

#以下のような形でカレントディレクトリを取得できます
>>> /Users/user_name/Date_science
```


```py
#カレントディレクトリ内部のフォルダを取得
os.listdir(current_dir)

#以下のような形でカレントディレクトリ内の全ファイルを取得できます
>>>["2019_01.csv","2019_02.csv","2019_03.csv","2019_04.csv",....,"2019_12.csv"]
```

#2:パスとファイル名を結合
```py
tbl_order_file = os.path.join(current_dir,"2019_*.csv")
tbl_order_file

#ファイル名の「〜月」に当たる部分に「ワイルドカードの*」を指定することで、指定したファイルだけを表示できる。
#詳しくは３で。
>>>/Users/user_name/Date_science/2019_*.csv
```

#3:指定ファイルを抽出
```py
#globモジュールでは、引数に指定されたパターンにマッチするファイルパス名を取得することができる
import glob

tbl_order_files = glob.glob(tbl_order_file)
tbl_order_files

#以下のような形で指定ファイルを一括操作出来ました。
>>>['/Users/user_name/Date_science/2019_01.csv',
 '/Users/user_name/Date_science/2019_02.csv',
 '/Users/user_name/Date_science/2019_03.csv',
..................,
..................,
'/Users/user_name/Date_science/2019_12.csv']
```

#4:データフレーム結合
```py
all_df = pd.DataFrame()

for file in tbl_order_files:
    all_df = pd.read_csv(file)
    print(f"{file}:{len(order_data)}")
    all_df = pd.concat([all_df, order_data],ignore_index = True)

#以下のような形で「どのファイルを」・「データ数」を出力させながら、データフレームを縦に結合させることが出来ます。
>>>
2019_01.csv:233301
2019_02.csv:233260
2019_03.csv:241139
.................,
.................,
2019_12.csv:241135
```

#5:まとめ

```py
import os
import glob

current_dir = os.getcwd()
tbl_order_file = os.path.join(current_dir,"2019_*.csv")
tbl_order_files = glob.glob(tbl_order_file)
all_df = pd.DataFrame()

for file in tbl_order_files:
    all_df = pd.read_csv(file)
    print(f"{file}:{len(order_data)}")
    all_df = pd.concat([all_df, order_data],ignore_index = True)
```
Vue3のテンプレート内でES2020構文が使えない原因

Vue3のテンプレートのコンパイラは、デフォルトでES2020の構文をサポートしています。

にも関わらず、テンプレート内で`Optional chaining`（`?.`）や`nullish coalescing`（`??`）を使うと、
`vue-loader`は以下のメッセージを出力し、コンパイルに失敗します。

```
You may need an additional loader to handle the result of these loaders.
```

これは`vue-cli`などで環境を作成した場合は発生しないので、大抵の人は起きない問題です。

**原因:**

さんざん`vue-loader`や`babel`などを調べましたが、結果としてはこちらの記事を読んで`Webpack`の問題だと分かりました。

[Webpack では JavaScript の新構文を変換なしでバンドルできない](http://var.blog.jp/archives/79738880.html)

**対応:**

Webpack5系にアップデートすることで解決しました。

しかし、`vue-cli`で作成した環境では、Webpack4系だったので、恐らくWebpackがバンドルをする前に変換して対処しているのかなと想像します。
VSCodeでgit ignoreしたファイル検索できるようにする

## git ignore　したファイルが検索できない
dockerをgitで管理している場合、volumes以下のアプリケーションのフォルダはgit ignoreしている場合がある思います。vscodeでいつものように`cmd + P`でアプリケーションのファイル検索をしようとしたところgitignoreしたフォルダ配下のファイルが検索できないことに気付きました。
## 設定を変える
vscodeのsettings画面を開き、検索バーで`search use file`で検索してください。
画像のように`Search: Use Ignore Files`のチェックを外すとgitignoreしたファイルも検索できるようになります。
![スクリーンショット 2021-01-08 10.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501889/92c969ed-da82-192c-30d9-5a5fa23f27c9.png)
WSL上でのRubyMineの設定

# WSL上でのRubyMineの設定

ファイル - 設定 から
言語&フレームワーク
Ruby SDKおよびGem
「+」をクリック
新規リモート
WSL
Linuxディストリビューションを選択
Rubyまたはバージョンマネージャのパス
/home/[ユーザー名]/.rbenv/versions/2.6.6/bin/ruby
【JavaScript】日にちを比較したり、時間や日数の差分を計算する

##はじめに
この記事では、JavaScriptのDateオブジェクトを使って日にちを比較したり時間や日数の差分を表示する方法を説明しています。

##日にちを比較する
Dateオブジェクトは比較演算子「<」「>」などを使って日にちを比較することができます。

```HTML:
    <script>
      var day1 = new Date(2021, 0, 10, 6);
      var day2 = new Date(2021, 0, 17, 6);
      if (day1.getTime() < day2.getTime()) {
        console.log(day2.toLocaleString() + "の方が先の日にちです");
      } else {
        console.log(day1.toLocaleString() + "の方が先の日にちです");
      }
    </script>
    <!-- 出力結果：2021/1/17 6:00:00の方が先の日にちです -->
```

##時間の差分を計算する
次は、経過ミリ秒を使って日にちの差分を計算してみます。

経過ミリ秒はgetTime()メソッドを利用することで取得できます。また、経過ミリ秒は減算演算子「-」を使って計算することができるので2つの日にちの差を出すことができます。

注意すべきことは、それぞれの日にちの経過ミリ秒を単純に引き算をしているので、ミリ秒を時間になおす必要があるという点です。コードは下のようになります。

```HTML
<script>
  /* 日にちオブジェクト①を指定する */
  var date1 = new Date(2021, 0, 10, 6);
  /* 日にちオブジェクト②を指定する */
  var date2 = new Date(2021, 0, 17, 6);
  /* 日にち①と日にち②の差（ミリ秒）を計算する */
  var date_difference = date2.getTime() - date1.getTime();
  /* getTime()メソッドは、1月1日を起点とした経過ミリ秒を取得 */
  var difference_hh = date_difference / (60 * 60 * 1000);
  console.log(date1.toLocaleString() + "と" + date2.toLocaleString() + "の差分は" +
    difference_hh + "時間です");
</script>
<!-- 出力結果:2021/1/10 6:00:00と2021/1/17 6:00:00の差分は168時間です -->
```

##日数の差分を計算する
こちらも先ほどと同様に、経過ミリ秒の差分を計算しミリ秒を日数になおします。コードは下のようになります。

```HTML
<script>
  //日にちオブジェクト①を指定する
  var date1 = new Date(2021, 0, 10, 6);
  //日にちオブジェクト②を指定する
  var date2 = new Date(2021, 0, 17, 6);
  //日にち①と日にち②の差分（ミリ秒）を計算する
  var date_difference = date2.getTime() - date1.getTime();
  var difference_dd = date_difference / (24 * 60 * 60 * 1000);
  console.log(date1.toLocaleString() + "と" + date2.toLocaleString() + "の差分は" +
    difference_dd + "日です");
</script>
<!-- 出力結果：2021/1/10 6:00:00と2021/1/17 6:00:00の差分は7日です -->
```
WSLのディストリビューション設定

# WSL

# ディストリビューション一覧
```ps
wsl -l
```

# ディストリビューションのデフォルトを変更
```ps
wsl -s Ubuntu-20.04
```

# ディストリビューションの確認
```bash
cat /etc/redhat-release
```

```bash
cat /etc/issue
```
Laravel6 独自のリクエストクラスを作成してpostしたらエラーが出た

# 目的

- Laravel6のアプリでバリデーションをリクエストクラスに記載するために独自のリクエストクラスを作成してデータをpostしたらエラーが出たので回避方法をまとめておく

# 環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.11 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.21 for osx10.15 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 情報

- 本エラーはAuthの認証機能を付与しているLaravelアプリだと発生するらしい。例にもれずエラーが出た筆者のアプリもAuthによる認証機能が付与されている。

# 経緯

1. 下記コマンドを実行してリクエストクラスを作成した。

    ```terminal
    $ php artisan make:request ContentRequest
    ```

1. 作成されたリクエストクラスのファイルを下記のように記載した。

    ```アプリ名ディレクトリ/app/Http/Requests/ContentRequest.php
    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class ContentRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return false;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'content' => 'required',
            ];
        }
    }
    ```

1. データがpostされるコントローラのメソッド（アクション）の引数に`ContentRequest $contentRequest`を追加してデータをpostした。

# エラー

- 「403 This action is unauthorized.」というエラーが発生した。

    ![Forbidden.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/97956456-dad6-9567-dad6-8c30cfd567e8.png)

# 解決策

1. 作成したリクエストクラスのauthorize()メソッド内部を下記のように書き換える。

    ```アプリ名ディレクトリ/app/Http/Requests/ContentRequest.php
    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class ContentRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            //下記を修正する
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'content' => 'required',
            ];
        }
    }
    ```
【備忘録】puppeteerでurl取得

ご無沙汰してます。おおのんです。

URL取得する方法メモ。
現在ページのURLと期待値を比較したいけど、どうすれば取得できるのだろう。

```javascript:url取得できない例
let puppeteer = require("puppeteer");
let browser;
let page;

beforeAll(async () => {
  browser = await puppeteer.launch({
    args: ["--disable-web-security"],
    headless: false,
    slowMo: 30
  });
  page = await browser.newPage();
  jest.setTimeout(20000);
});

afterAll(() => {
  browser.close();
});

describe("TEST", () => {
  test("toMypage", async () => {
    //　画面移動
    await page.goto("http://localhost:8000/mypage");
    // マイページへ遷移成功
    await page.waitForTimeout(5000);
    // location.hrefで完全なURL取得できるから、比較する
    await expect(location.href).toEqual("http://localhost:8000/mypage");
    await page.close();
  });
});
```
```:結果
● LOGIN TEST › Login
    expect(received).toEqual(expected) // deep equality
    Expected: "http://localhost:8000/mypage"
    Received: "http://localhost/"
```

・・・アカン。
Received: "http:/localhost/"になる。

こうすると取得できる。

```javascript:取得できる例
// ～略～
　　// location.href => url.path()にする
    await expect(url.path()).toEqual("http://localhost:8000/mypage");
// ～略～
```
```:結果
● LOGIN TEST › Login
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
```
通った～。

<a href="https://github.com/puppeteer/puppeteer/issues/2215">【puppeteer/puppeteer】 how to get current url ? #2215</a>
で既出でした。
ディスクユーティリティで統合できないパーティションを１つにまとめる

USBの外付けHDDのパーティションが２つに別れていて、１つにまとめたかったんですが、ディスクユーティリティで操作できず、調べて解決した方法をメモしておきます。

##環境

OS：macOS High Sierra バージョン10.13.16
USB外付けHDD：IO-DATA 2TB HDD

##やりたいこと、状況説明

そもそもは、macOSをCatalinaにしたくて、timemachineで外付けHDDにバックアップをとりたかったというのがあって、やろうとしたら外付けHDDの大きい方のパーティションを選択できない状態でした。

その外付けHDDは、以前にYosemiteの起動ディスクを作ってあって、30GBと残り全部の２つのパーティションに分けられた状態でした。
timemachineで「ディスクを選択」で利用可能なディスクには、30GBの方しか出てこず、30GBでは当然、容量が足りないのでバックアップできません。

約2TBのパーティションのデータを別のところに移して、ディスクユーティリティで「消去」（macOS拡張ジャーナリング）しても、やはり選択できないため、パーティションを１つにまとめようとしました。

ググって調べて、統合方法は出てきましたが、ディスクユーティリティのバージョンが違うのかグラフ表示じゃないし、ディスクユーティリティで見て２つに別れてしまっているパーティションをどう選択してるのかも、よくわかりませんでした。
外付けHDDをまとめて１つのディスクとして選択できるようなところがなかったんです。
外付けHDDのパーティションを選択しても「パーティション作成」が薄い表示のままで選択できないし。

ということで、ディスクユーティリティを使っては無理なのかなと思って、ターミナルからコマンドで消去する方法を見つけました。

##方法

ターミナルを起動し、下記のコマンドを打ってディスク情報を表示します。


```
$ diskutil list
```

結果はこんな感じです。外付けHDDのみ表示させてます。
約2TBのパーティション名は「2」になってます。
（名前っぽくないのでわかりにくいですが）

```
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *2.0 TB     disk2
   1:                  Apple_HFS Install OS X Yosemite   30.0 GB    disk2s1
   2:                  Apple_HFS 2                       2.0 TB     disk2s2
```

IDENTIFIERのところにあるのがパーティション名で、disk2s1、disk2s2を指定して消去します。

diskutil eraseVolume "Free Space" not diskxxx(←ここにディスク名)

```
$ diskutil eraseVolume "Free Space" not disk2s1
Started erase on disk2s1 Install OS X Yosemite
Unmounting disk
Finished erase on disk2
```

```
$ diskutil list
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *2.0 TB     disk2
   1:                  Apple_HFS 2                       2.0 TB     disk2s2
```
```
$ diskutil eraseVolume "Free Space" not disk2s2
Started erase on disk2s2 2
Unmounting disk
Finished erase on disk2
```
```
$ diskutil list
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *2.0 TB     disk2
```

これでパーティションに分かれてない状態になりました。

ここでディスクユーティリティを起動するとちゃんと2TBで１つのパーティション表示になっています。
このままだとちゃんとフォーマットされた状態じゃないかもしれないので、このパーティションを選択して「消去」（macOS拡張ジャーナリング）しました。

そして、timemachineでディスクを選択すると、ちゃんとこの外付けHDDを選択できました！

ということで、２つのパーティションをを１つにまとめるのは終了です。



ちなみに、diskutilはcommand not foundになってしまって、

```
$ diskutil list
-bash: diskutil: command not found
```

whereisをしたらあったので

```
$ whereis diskutil
/usr/sbin/diskutil
```

```
$ /usr/sbin/diskutil list
```

実際はこんなふうにフルパスで使ってました。
本当はパスを通せばいいと思うんですが、しばらくこういうのやってなくてちょっと面倒なのでとりあえずこれで。

それと１つにまとめた外付けHDDをディスクユーティリティでみて、パーティションを選択しても「パーティション作成」が薄い表示のままで選択できませんでした。
ここはなぜなのかわかりませんが、macOSのバージョンアップが終わればできるようになるかもしれないなと思ってとりあえずこれ以上追求しません。

【追記2021.1.14】
結局この時、外付けHDDを１つのまとまりとして選択できなかったのは、何かしらディスクユーティリティの表示がおかしかったようです。

この後いろいろあった後、High Sierraを再インストールしてディスクユーティリティでみると、外付けHDDを１つのまとまりとして選択できる、１つ上のカテゴリがありました。
macOSが何かしらもうちょっとおかしくなってたのかなと思います。
Rubyの基本

###これからRubyの基本について書いていきます。

まず文字列と数値の違いについて解説していきます。

##文字列
こんにちは　Hello！　今日は　コンニチハ　などの数字以外を文字列といいます。入力する際に
'(シングルクォーテーション)
または
"(ダブルクォーテーション)
で囲みます。

例　"こんにちは"   　 'Hello'

##数値
22、777、8 などの数字のことです。
こちらはシングルクォーテーションやダブルクォーテーションで囲む必要はありません。


##Rubyにおける加減乗除

文字列の場合は　こんにちは　と　太郎さん　をつなげて、　こんにちは太郎さん　としたい時は
"こんにちは" + "太郎さん"　とします

数値の場合は　５と９を足したい時には
5 + 9とすれば良いです

それでは文字列と数値を足したらどうなるのでしょうか？

こんにちは、今日は２４日です。
という文章を足し算で作る際に

"こんにちは、今日は" + 24 + "日です。"

とするとエラーが出てしまいます。
数値と文字列は直接は計算できないためです。

ではどうするのかというと、　to_sメソッド　というものを使って数値を文字列に変換します。

"こんにちは、今日は" + 24.to_s + "日です。" とすれば計算できます。

逆に文字列を数値にしたい場合は　to_iメソッド　を使います。

"500"　シングルクォーテーションやダブルクォーテーションで囲まれていると文字列扱いになってしまうので
数値に変換したい場合は　"500".to_i とします。

今日はここまで、次回はメソッドについて書きます。
RSpec＋Capybara＋selenium＋chromedriverでのテスト

 主にchromedriverの導入に手こずったので記録しておきます。

#Gemfileの設定#

```ruby:Gemfile
group :test do
  gem 'rspec-rails'
  gem 'capybara'
  gem 'selenium-webdriver'
end
```
#chromedriverの導入#
①

```terminal
$ brew install chromedriver 
```

terminalにて 'brew install chromedriver'を実行
注意点：（PCのrootディレクトリーで実行すること）
※which chromedriverにでinstall先が見れる 

②最新版にアップデートする

```terminal
$ brew upgrade chromedriver
```

#chromeをヘッドレスモードで起動するために#

```ruby:spec/rails_helper.rb
RSpec.configure dp |config|
 　#他の記述
  config.before(:each) do |example|
    if example.metadata[:type] == :system
      if example.metadata[:js]
        driven_by :selenium_chrome_headless, screen_size: [1400, 1400]
      else
        driven_by :rack_test
      end
    end
  end
 
  #capybaraを使うための記述
  config.include Capybara::DSL
end
```

#最後に#
こんな記事を書いておいてなんですが、
なぜかわからないがrails_helper.rbに
metadata[:js]にしたらうまく動作しました。

どなたかアドバイスをいただければありがたいです。
Azure functions に CORS 設定を追加する

## 概要

Azure portal 上で以下の設定を行うことで、[クロスオリジンリソース共有 (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) を使用するための `Access-Control-Allow-Origin` ヘッダーを宣言・自動付与できる。

1. Azure portal で CORS 設定する関数アプリを選択する。

1. 左側メニューの [API]タブにある [CORS] を選択する。

1. [CORS] の設定ページ内の[許可される元のドメイン]に、CORS を許可するドメインを入力する。

   - (例) `https://example.com`

## 参考にした資料

- [クロス オリジン リソース共有](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-how-to-use-azure-function-app-settings#cross-origin-resource-sharing)
FirebaseDynamicLinksでコンバージョン、取れてますか？

お客さんがとっても大事にしている「流入元」の計測、Firebaseを使っていればDynamic Linksで計測しているアプリも多いのではないでしょうか？
お手軽に実装できますし、iOSにも対応していてとっても便利！！なのですが、ここ最近挙動が怪しい気がしており、記録しておきます。

## Firebase Dynamic Linksとは
Firebase Dynamic Linksとは、Googleが提供する様々な環境で機能するリンクです。
インストールの有無に関係なく、アプリが未インストールであればストアに誘導し、インストール済みであればリンク先のコンテンツを直接開くことができます。

## コンバージョンの確認方法
ダイナミックリンクに関連するイベントはAndroidは3種類、iOSは2種類です。
イベント名は下記表の通りです。dynamic_link_app_updateはAndroidのみのイベントになります。

| イベント名 | 発生タイミング |
|:--|:--|
|dynamic_link_first_open|ダイナミックリンクを経由して、初回起動の場合|
|dynamic_link_app_open|ダイナミックリンクを経由して、2回目以降の起動の場合|
|dynamic_link_app_update|ダイナミックリンクを経由して、アプリを更新し起動した場合|

コンバージョンを確認するためには、事前にこれらのイベントをコンバージョンに設定しておく必要があります。
ちなみに、初回起動の際に発生するfirst_openですが、dynamic_link_first_openで起動した際もfirst_openは発生します。どちらか一方ではないのでアプリ全体の初回起動のコンバージョンを確認したい場合はfirst_open、ダイナミックリンクの効果を確認したい場合はdynamic_link_first_openと使い分けが可能です。

## ダイナミックリンクの挙動
### 正常時
ダイナミックリンク経由で起動した際は、上記の3つ(iOSは2つ)のイベントが発生すると記述しましたが、Firebaseコンソールには現れない、firebase_campaignというイベントも共に発生します。
firebase_campaignは自動で計測されるイベントの一つで、キャンペーン計測のためのイベントです。参照元やメディアなどのイベントパラメータを持っています。
このfirebase_campaignとダイナミックリンクのイベントのいずれかがセットで発生する、というのが仕様のようです。

### 最近(2021/01)のAndroid
この記事を書いている時点で最新のFirebase Analytics SDK 18.0.0ですが、このバージョンを入れるとなんとダイナミックリンク関連のイベントが発生しません。。結構ハマりました。。コンバージョン云々以前の問題でした。。
下記のようなエラーが出ていました。

```
E/GAv4-SVC: Device AnalyticsService not registered! Hits will not be delivered reliably.
E/FA: Name is reserved. Type, name: event, dynamic_link_app_open
E/FA: Invalid event name. Event will not be logged (FE): dynamic_link_app_open(dynamic_link_app_open)
```

[リリースノート](https://firebase.google.com/support/release-notes/android#analytics_v18-0-0)には、18.0.0の変更点として「下記の予約語を追加しました」とあるのですが、これが何らかの影響を及ぼしていると思われます。
追々修正されるかと思いますので、ダイナミックリンクを使用していて、Analytics SDKを更新・追加する場合には、18.0.0を避けることをお勧めします。一つ前の17.6.0だと正常な挙動をしていましたので、現時点では17.6.0を入れるのがいいかもしれません。

### 最近(2021/01)のiOS
ダイナミックリンクには長いダイナミックリンクと短いダイナミックリンク(短縮URL)がありますが、短いダイナミックリンクの場合のdynamic_link_app_openのコンバージョンにUTMパラメータが反映されません。。全て(not set)になってしまいます。
長いダイナミックリンクだとコンバージョンは設定通りに反映されます。
原因がAnalyticsのSDKにあるのかDynamic LinksのSDKにあるのか特定はしていませんが、この問題についてはFirebaseチームに問い合わせを行い、Firebaseチームで把握済みのバグであるという回答をもらっています。優先度を上げて対応していくけど、入り組んでいてちょっと時間がかかるかも、、ということでした。
ちなみに、SDKのバージョンの組み合わせを変えていろいろ試してみましたが、今のところ正常パターンで動作する組み合わせを見つけられていません。長いダイナミックリンクで代替可能であれば、長いダイナミックリンクを使うのがいいかと思います。

## まとめ
ダイナミックリンク、ちょっと挙動が怪しいのでは、、？？ということで今回この記事をまとめました。皆さんのところはどうですか・・・？
SDKのバージョンによって期待通りに動作したりしなかったりするので、SDKのバージョンを変更する際には想定したイベントが発生するか確認した方が良さそうです！
また修正されたらこちらの記事を更新したいと思います。
【railsチュートリアル】Herokuにデプロイができない/hello,worldからhola,mundoへの変更

#課題

rails６．０版チュートリアル1.5.3の演習問題の１番がうまく解けなかった。

>1.3.4.1と同じ変更を行い、本番アプリでも「hola, mundo!」を表示できるようにしてください。

Herokuにhello,world!アプリをデプロイした後に、hola,mondo!アプリをデプロイし直せという問題です。
私なりにhola,mundo!Herokuアクションを作成し、Herokuにデプロイし直したつもりが、
何度やってもブラウザに表示されるのは「hola,mundo!」ではなく、「hello,world!」となってしまう状況でした。

#私が犯していたミス
Git hubにファイルをアップロードする手順が誤っていた。
私が行った手順は下記の通りです。

①controller作成。holaアクションを追加した。

```application_controller.rb
class ApplicationController < ActionController::Base
  def hello
    render html: "hello,world!"
  end
  
  def hola
    render html: "hola,mundo!"
  end
end
```
②ルーティングを変更。アクションをhelloからholaに変更した。

```routes.rb
Rails.application.routes.draw do
 root 'application#hola'
end
```
③Herokuに新しいアプリケーションを作成する。
Railsアプリケーション専用のサブドメインが作成され、ブラウザで表示ができるようになる。

```
$ heroku create
```

④Herokuにpushする。

```
＄ git push heroku master
```
⑤このコマンドを入力して出てきたURLにアクセスする。

```
$ heroku open
```
以上です。

#解決策
上記の②の手順の後に、下記の手順が足りていなかったです。
git hubへのファイルのアップロードがきちんとできていなかったのが原因でした。

①変更内容をステージングエリアに追加する。

``` 
$ git add.
```
②ローカルリポジトリに追加する。

```
$ git commit
```
③masterブランチにpushする。

```
$ git push origin master
```
↓
「私が犯していたミス」の手順③から⑤まで実行する。

以上で解決することができました。
階層的クラスタリングを実装してみた

* 製造業出身のデータサイエンティストがお送りする記事
* 今回はクラスタリング手法の中で、K-means法を実装しました。

##はじめに
前回、[K-means法](https://qiita.com/DS27/items/8f6e4162dcfeba8bd97b)を実装しましたが、今回は階層的クラスタリング手法を実装してみました。

##階層的クラスタリングとは
階層的クラスタリングとは、最も似ている組み合わせから順番にまとまり（クラスタ）にしていく方法です。

##階層的クラスタリングの実装
pythonのコードは下記の通りです。

```php
# 必要なライブラリーのインストール
import numpy as np
import pandas as pd

# 可視化
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import display
%matplotlib inline
sns.set_style('whitegrid')

# 正規化のためのクラス
from sklearn.preprocessing import StandardScaler

# 階層クラスタリングに必要なものをインポート
from scipy.cluster import hierarchy
```

最初に必要なライブラリーをimportします。
今回もirisのデータを使って実装してみようと思います。

```php
# irisデータ
from sklearn.datasets import load_iris

# データ読み込み
iris = load_iris()
iris.keys()

df_iris = iris.data
df_target = iris.target
target_names = iris.target_names
df_labels = target_names[df_target]

# データの正規化（平均0, 標準偏差1）
scaler = StandardScaler()
df_iris_std = scaler.fit_transform(df_iris)
```

前処理は上記で終了です。
今回はウォード法を用いて階層クラスタリングを実施したいと思います。クラスタ同士の距離の定義の仕方は他にも色々ありますので、データに合わせて適切な手法を選択する必要があります。

```php
# 距離計算
dist = hierarchy.distance.pdist(df_iris_std, metric='euclidean')

# クラスタリング
linkage = hierarchy.linkage(dist, method='ward')

# デンドログラム
fig, ax = plt.subplots(figsize=(5,13))
ax = hierarchy.dendrogram(Z=linkage,
                orientation='right',
                labels=dataset_labels)
fig.show()
```

![ウォード法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743453/4b94ae75-972b-0fad-27d9-6a6d1396e045.png)

##さいごに
最後まで読んで頂き、ありがとうございました。
今回は、階層的クラスタリング法を実装しました。

訂正要望がありましたら、ご連絡頂けますと幸いです。
PyPortfolioOpt（投資ポートフォリオ最適化ライブラリ）インストールエラー解消

PythonライブラリのPyPortfolioOpt（投資ポートフォリオ最適化）をインストールエラーを解消したときのメモ。

PyPortfolioOptを使うと、つみたてNISAやiDeCoなどで各資産（国内株式・国内債券・外国株式・外国債券など）への投資割合を、数理最適化を用いて算出できます。

>[PythonでWealthNaviの最適ポートフォリオをやってみた](https://datacoach.me/data/analysis/python-wealthnavi/)

# 環境
- macOS
- Docker
- Anaconda3

# エラーメッセージ
pipでライブラリをインストールしようとしたらエラー。

```bash
$ pip install PyPorttfolioOpt
```

エラーメッセージ。

```
ERROR: Failed building wheel for scs
Running setup.py clean for scs
Failed to build cvxpy ecos scs
ERROR: Could not build wheels for cvxpy which use PEP 517 and cannot be installed directly
```

# 解決
cvxpy（数理最適化ライブラリ）をインストール。`pip`でインストールしようとしたらエラーだったので、調べた結果、`conda`でインストール。

```bash
conda install -c conda-forge cvxpy
```
文字列の切れ目の一致率の計算【python】

#概要
切れ目の存在する２つの文字列において、切れ目の位置がどの程度一致しているかを計算するプログラムを書きました。
「〇〇で歌ってみた」というジャンルの替え歌において、本来の歌詞の文節の切れ目と替え歌歌詞の単語の切れ目がどの程度一致しているかを調べるために作りました。
#背景
「〇〇で歌ってみた」は特定カテゴリの名詞だけで本来の歌詞の発音を再現するように歌われた替え歌のことです。下図は童謡『ふるさと』の歌詞を駅名に置き換えた「〇〇で歌ってみた」の例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259353/c9f890e1-b72c-28c2-c9d0-6d5d9059130f.png)
「〇〇で歌ってみた」では替え歌歌詞の単語の切れ目と本来の歌詞の文節の切れ目がどちらかというと一致するように作られる傾向があります。理由は定かではありませんが、一つにはそのほうが歌いやすいからという理由が考えられます。いくつかの替え歌において、どの程度一致しているかを調べたくなったので、２つの文章の文節一致率を評価するプログラムを書いてみることにしました。
#解きたい問題
文字列Aと文字列Bが与えられて、２つの文節一致率を求めることが目標です。
##入力
簡単のため、２つの文字列のモウラ数は同じとします。また発音（読み方）と文節（単語）の切れ目は既知とします。発音はカタカナで、文節の切れ目はスラッシュで表記することとします。例えば下記のような文字列を入力として想定します。

* 文字列A(替え歌歌詞):カモメ/カモメ/カグー/ナガノゴリ/サイ/クイ/ツミ/ラット/ウシ/ロバ/ヒョウ/メナダ/アビ
* 文字列B（本来の歌詞)：カゴメ/カゴメ/カゴノ/ナカノ/トリワ/イツ/イツ/デアッタ/ウシロノ/ショウメン/ダアレ

##出力
文字列Aと文字列Bの文節一致率を出力します。
文節一致率は文字列Aの文節の切れ目のうち、文字列Bの文節の切れ目と同じ位置にあるものの割合と定義します。同じ位置であるかどうかは、その文節の切れ目の直前までに存在する文字列のモウラ数で判断します。また文字列の最後は文節の切れ目とはみなしません。例えば先に示したカゴメの例で、文字列Bのうち一致している切れ目をダブルクオテーションで示すと以下になります。

* 文字列A(替え歌歌詞):カモメ"/"カモメ"/"カグー"/"ナガノゴリ/サイ/クイ/ツミ/ラット"/"ウシ/ロバ"/"ヒョウ/メナダ/アビ
* 文字列B（本来の歌詞)：カゴメ/カゴメ/カゴノ/ナカノ/トリワ/イツ/イツ/デアッタ/ウシロノ/ショウメン/ダアレ

文字列Bの文節の切れ目の数(=スラッシュの数)は12で、そのうち文字列Aの文節の切れ目と一致しているものは、5個です。文字数ではなくモウラ数（例えばヒョは２文字ですが、１モウラです）で数えることに注意してください。
#環境
macOS Catalina 10.15.7
python 3.8.0
#コード
与えられた文字列をモウラの単位に分解してから、スラッシュの位置をカウントします。

```Python
import re

#各条件を正規表現で表す
c1 = '[ウクスツヌフムユルグズヅブプヴ][ヮァィェォ]' #ウ段＋「ヮ/ァ/ィ/ェ/ォ」
c2 = '[イキシシニヒミリギジヂビピ][ャュェョ]' #イ段（「イ」を除く）＋「ャ/ュ/ェ/ョ」
c3 = '[テデ][ャィュョ]' #「テ/デ」＋「ャ/ィ/ュ/ョ」
c4 = '[ァ-ヴー]' #カタカナ１文字（長音含む）

cond = '('+c1+'|'+c2+'|'+c3+'|'+c4+')'
re_mora = re.compile(cond)

#カタカナ文字列をモウラ単位に分割したリストを返す
def mora_wakachi(kana_text):
    return re_mora.findall(kana_text)


def phrase_partition_concordance(text1, text2):
  partition = "/"
  #文字列を区切り文字でスプリット
  kana_list1 = text1.split(partition)
  kana_list2 = text2.split(partition)
  #各要素をモウラに分割
  kana_list1 = [mora_wakachi(k) for k in kana_list1]
  kana_list2 = [mora_wakachi(k) for k in kana_list2]

  #text1の文節位置を取得
  partition_position1 = [0]
  for k in kana_list1:
    pos = partition_position1[-1] + len(k)
    partition_position1.append(pos)
  #最初と最後は文節位置から除く
  partition_position1 = partition_position1[1:-1]

  #text2の文節位置を取得
  partition_position2 = [0]
  for k in kana_list2:
    pos = partition_position2[-1] + len(k)
    partition_position2.append(pos)
  #最初と最後は文節位置から除く
  partition_position2 = partition_position2[1:-1]
  
  #text1の文節位置がtext2の文節位置に含まれるかチェック
  same_pos_num = 0
  for p in partition_position1:
    if p in partition_position2:
      same_pos_num += 1
  #text1の文節の切れ目の数
  partition_num = len(partition_position1)
  return same_pos_num / partition_num

text1 = "カモメ/カモメ/カグー/ナガノゴリ/サイ/クイ/ツミ/ラット/ウシ/ロバ/ヒョウ/メナダ/アビ"
text2 = "カゴメ/カゴメ/カゴノ/ナカノ/トリワ/イツ/イツ/デアッタ/ウシロノ/ショウメン/ダアレ"

print(phrase_partition_concordance(text1,text2))
```
Ruby-FFIで可変長配列を持つ構造体を使う、またはビットフィールドを使う方法

https://github.com/ffi/ffi/issues/874

Ruby-FFIで可変長配列(variable length array)を持つ構造体(struct)を使う。またはビットフィールド(bitfields)を使う方法。

公式のGithubのissueで相談したところ、開発者の方から方法を教えてもらったので記録として残します。

> こんにちはRuby-FFI開発者！
>
> 素晴らしい仕事をありがとう。
>
> 質問があります。 可変長配列の構造をRubyコードに変換するにはどうすればよいですか？ 


```c
typedef struct {
	uint32_t capacity;
	int32_t dp_score, dp_max, dp_max2;
	uint32_t n_ambi:30, trans_strand:2;
	uint32_t n_cigar;
	uint32_t cigar[]; # Here
} mm_extra_t;
```

> もう1つ質問があります。
> ruby-ffi wikiを調べたところ、ビットフィールドはサポートされていないと書かれています。 これは今日でも当てはまりますか？ 

Lars Kanisさんによる回答

> ビットフィールド(Bit fields)はサポートされていませんが、単純な整数演算でエミュレートできます。 可変長配列は `struct.pointers` で使用できます。 次のように使用します。 

```ruby
class MmExtra < FFI::Struct
  layout capacity: :uint32,
    dp_score: :int32,
    dp_max: :int32,
    dp_max2: :int32,
    n_ambi_trans_strand: :uint32,
    n_cigar: :uint32
end

n_ambi = 123456
trans_strand = 0x2
cigar = [4,5,6]
s = MmExtra.new(FFI::MemoryPointer.new(MmExtra.size + FFI.type_size(:uint32) * cigar.size))
s[:n_ambi_trans_strand] = n_ambi | (trans_strand << 30)


s[:n_cigar] = cigar.size
s.pointer.put_array_of_uint32(s.size, cigar)

p n_ambi: s[:n_ambi_trans_strand] & ((1 << 30) - 1), trans_strand: (s[:n_ambi_trans_strand] >> 30) & ((1 << 2) - 1) # => {:n_ambi=>123456, :trans_strand=>2}
p s[:n_cigar]  # => 3
p s.pointer.get_array_of_uint32(s.size, 3) # => [4, 5, 6]
p s.pointer.read_bytes(s.pointer.size) # => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xE2\x01\x80\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00"
```

> MmExtraにカスタムメソッドを追加して、フィールドにアクセスし、ビットフィールド演算を実行することもできますよ。

> ありがとうございます。
【自己用メモ】（Ruby）クラス、クラスインスタンス、インスタンス 

# 用語
各種変数・メソッド用語について。
スコープ情報の不足分は後日追記予定。(頭の中整理して書くの疲れるぅ〜。。:joy:)
おかしなところ、お気づきな点等ございましたら、
お手数ですがご指導ご指摘、頂けますと幸いです:hand_splayed_tone2:

```
class A # Aクラス(通常のクラス)
  @@class_variable = "クラス変数"

  # @class_instance_variable = "クラスインスタンス変数"
  # => ここで宣言した場合、「インスタンス変数」ではなく、「クラスインスタンス変数」と見なされる。
  # 「インスタンス変数」と同じプレフィックス(@〜)。

  def initialize # インスタンスメソッド
    @instance_variable = "インスタンス変数"
    puts "#{@instance_variable} at initialize"
  end

  def hoge # インスタンスメソッド
    puts "#{@instance_variable} at xxx"
  end

  def self.fuga # クラスメソッド(定義の方法：特異メソッド方式)
    puts "#{@instance_variable} at yyy"
  end

  class << self # 特異クラス
    def fuga # クラスメソッド(定義の方法：特異クラス方式)
      puts "#{@instance_variable} at yyy"
    end
  end
end

# インスタンスメソッドinitializeからはアクセスできる
instance = A.new # => "インスタンス変数 at initialize" # インスタンス生成

instance.hoge # インスタンスメソッド呼び出し
# インスタンス変数は他のインスタンスメソッドでも使える
instance.hoge # => 'インスタンス変数 at xxx'

A.new.hoge # インスタンスメソッド呼び出し(クラス名.new.インスタンスメソッド名)
A.new.hoge # => 'インスタンス変数 at xxx'

A.fuga # クラスメソッド呼び出し
# クラスメソッドからはインスタンス変数(@〜)は使えない
A.fuga # => nil
```
# 参考記事
:relaxed:
@mogulla3さん
- https://qiita.com/mogulla3/items/cd4d6e188c34c6819709
@tbpgrさん
- https://qiita.com/tbpgr/items/56eb65c0ea5882abbb07
ファイルシステム別の制限事項まとめ

#1.この記事の内容

ファイルシステムの種類とOSとの対応関係及び制限事項を整理します．

ファイルシステムとは，OSが提供する機能の一つで，HDDやUSBメモリ等の記憶装置に保存されたデータの管理や操作に必要な機能です．
フォーマットの際に，FAT32，exFAT，NTFS等が指定できますが，OSごとに対応するフォーマットが異なります．

例えば，FAT32はWindowsやMac，Linux，raspbian等多くのOSが対応している為，FAT32でフォーマットした記憶装置を用いるとパソコン間でデータの受け渡しが可能となります．
ただし，ファイルシステムごとに，1ファイルのサイズ上限や，1フォルダ内に格納可能なファイル数等の制限がある為，注意が必要です．

本記事の調査にあたり参照したサイトは，ページ下部の関連リンクに記載しています．

#2.ファイルシステムの種類とOSとの対応関係一覧

個人的によく使用する，FAT32，exFAT，NTFS，ext4について調査しました．

RW：読み書き可能
RO：読み取りのみ可能
×：非対応

|ファイルシステム|Windows|Mac|Linux|ボリュームサイズ|1ファイルの最大サイズ|1ディレクトリ内の最大ファイル数|
|---|---|---|---|---|---|---|
|FAT32|RW|RW|RW|2TiB<br>※Windowsでは32GiB|4GiB|65,535（※1）|
|exFAT|RW|RW|×|64ZiB|16EiB|2,796,202|
|NTFS|RW|×|×|16EiB|16EiB|4,294,967,295|
|ext4|×|×|RW|1EiB|16TiB|[i-node](https://qiita.com/kamihork/items/fbcd116a631324aae05d#i-node%E3%81%A8%E3%81%AF)に依存|

※1：ファイル名が8.3形式（ファイル名（8文字）.拡張子（3文字））準拠かつルートディレクトリの場合のファイル数．ファイル数が長い場合やサブディレクトリの場合は，ファイル数が抑制される．

|ファイル名の形式|ルートディレクトリ|サブディレクトリ|ファイル名備考|
|---|---|---|---|
|8.3形式|65,535|65,534|大文字と記号のみ12文字まで|
|13文字|65,535÷3→21,845|65,534÷3→21,844|小文字や数字含む13文字の例|
|25文字|65,535÷4→16,383|65,534÷4→16,383|小文字や数字含む25文字の例|

#3.さいごに

RaspberryPi上で[COCOデータセット](https://cocodataset.org/#download)の「2017 Test images [41K/6GB]」を扱おうと，FAT32でフォーマットしたUSBメモリにコピーを試みたところ，下記のエラーが発生し，FAT32の制約事項（1ディレクトリ内のファイル数超過）への該当が判明したことから本調査を行いました．

同様の問題に遭遇した方の参考になれば幸いです．

* Windowsコピーエラー（予期しないエラー，0x80070052）
![Windowsファイルコピーエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983907/adb3f4dd-2bf3-74c1-ce25-d9806bc6dda7.png)

* WSLファイルコピーエラー（"cannot create regular file"）
![WSLファイルコピーエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983907/18ecdac3-4c17-88d9-a760-02d0a55e5f92.png)


#4.関連リンク

* [ファイルシステム（FAT32、FAT16、NTFS、exFAT、HFS、HFS+、APFS）の違いについて](https://www.buffalo.jp/support/faq/detail/1079.html)
* [OSの対応状況](https://www.rescue-center.jp/explanation/filesystem/os.html)
* [Linuxファイルシステムをまとめてみました](https://qiita.com/sion_cojp/items/c8e015db39ddbf43012e)
* [テビバイト](https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%93%E3%83%90%E3%82%A4%E3%83%88)
* [NTFS volとFAT32のディレクトリごとの最大ファイル数](https://qastack.jp/superuser/446282/max-files-per-directory-on-ntfs-vol-vs-fat32)
* [NTFS vs FAT vs exFAT](http://www.ntfs.com/ntfs_vs_fat.htm)
* [Is There a Limit to What a Single Folder or Directory Can Hold?](https://askleo.com/is-there-a-limit-to-what-a-single-folder-or-directory-can-hold/)
* [FAT32のファイルシステムで扱える最大ファイル数は65,535個？21,845個？](http://pentan.info/else/fat32_maxfiles.html)
* [Ubuntuでの1ディレクトリあたりのファイル数上限、容量上限はあるのでしょうか？](https://ja.stackoverflow.com/questions/11794/ubuntu%E3%81%A7%E3%81%AE1%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%82%E3%81%9F%E3%82%8A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%95%B0%E4%B8%8A%E9%99%90-%E5%AE%B9%E9%87%8F%E4%B8%8A%E9%99%90%E3%81%AF%E3%81%82%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B)
* [linux（RHEL・CentOS・Amazon linux 2）のディレクトリの格納ファイル数上限](https://teratail.com/questions/233584)
* [ファイルシステムおよびストレージの制限](https://access.redhat.com/ja/articles/1271503#ext4-7)
* [Linuxのファイルシステムについて](https://qiita.com/kamihork/items/fbcd116a631324aae05d)
JupyterLab 3.0に移行したらjupyter_notebook_config.pyの設定が反映されなくなった話

 本題は__解決方法__まで飛んでください。

# はじめに
2021/1/5、JupyterLab の version 3.0 がリリースされました（記事作成日 2021/1/8）
詳細情報は[ここ](https://jupyterlab.readthedocs.io/en/latest/getting_started/changelog.html)を JupyterLab は私のメインエディタなので、早速使ってみました。
しかし、なにやら jupyter_notebook_config.py の設定が反映されてない様子、なぜ！ 

# 原因調査
Qiitaで解決策を探していたところ、記事が全く無い！ということで公式ドキュメントで解決方法を探っていたところドンピシャの部分を発見。

> __Jupyter Server__
> JupyterLab 3.0 now depends on Jupyter Server, which is a new Jupyter project based on the server portion of the classic Notebook server. See the Migration Guide to migrate custom notebook configuration to Jupyter Server.

> JupyterLab Changelog --v3.0 --User-facing changes --Jupyter Serverより

要するに、Jupyter Server という新しいシステムを使うようにしたからその移行方法を参照してねってことらしい。

# 解決方法
Jupyter Server の[ドキュメント](https://jupyter-server.readthedocs.io/en/latest/?badge=latest)に解決方法がありました。

> To migrate from notebook server to plain jupyter server, follow these steps:

> - Rename your jupyter_notebook_config.py file to jupyter_server_config.py.
> - Rename all c.NotebookApp traits to c.ServerApp.

この２つを変更したら無事動作するようになりました。

# おわりに
JupyterLab 3.0の詳細情報がQiitaにまだ上がってなかったので気まぐれであげてみました。この記事が誰かの役に立てば幸いです。
とあるTomcatプラグインの停止ポート(8081)

# はじめに

久しぶりにあるWebアプリとそこから呼び出される別のWebAPIシステムの改修作業が入ったので、開発環境を立ち上げようとしたらWebアプリが起動しなかったんだぁ。  
~~Docker?何それ美味しいの?~~

# 環境(細かいのは職場のなので不明)

* Webアプリ
  * Spring MVC(非SpringBoot)
  * Gradle
    * [TomcatPlugin](https://github.com/bmuschko/gradle-tomcat-plugin)
* WebAPI
  * SpringBoot

# なにが起きたか

1. WebAPIの実行可能jarをport8081で立ち上げる
  - `java -jar xxx.jar --server.port=8081`
1. Webアプリをgradleタスクから立ち上げる
  - `gradle tomcatRun`
1. 起動しない＼(\^o\^)／

`--trace`をつけて実行するとportが使われている様子

> Address already in use: JVM_Bind

でも`netstat /nao | findstr "8080"`しても該当がない

はて...

# なんだったのか

githubに書いてあるのですが、TomcatPluginではtomcatの停止portとして8081を使用していました。  
WebAPI側を8090に変更したら正常に動きました。

# どうすればすぐに気づけたか

- さっさと詳細なログを出せばよかった
- いきなり`netstat`で8080に絞り込むべきではなかった
  - WebAPIで使用してるポート側からも探すべきだった
静的Webサイト用S3バケットを用意してそのバケットだけに書き込めるアクセスキーを発行する

## bucketを作成

* 例: バケット名 = test.example.com
* 作られたバケットを選んで「Permissions」タブを開く
* Block public access (bucket settings) に全てをOFF
* Access control list (ACL)にてEveryone (public access)にRead権限をつける

## bucketのStatic website hostingを設定

* Static website hosting: Enable
* Hosting type: Host a static website
* Index document: index.html
* Error document: error.html

## route53でウェブサイトエンドポイントに割り当てたいホストを割り当てる

* Aレコードを選ぶ
* Alias to S3 website endpoitを選ぶ
* リージョンとバケットを選ぶ

## IAMを作成

* User name: test.example.com-s3fullaccess
* Access type: Programmatic access
* 権限はなしで一旦作成
* 作成後「Permissions」 -> 「Add inline policy」でJSONタブを開いて以下で設定

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::test.example.com",
                "arn:aws:s3:::test.example.com/*"
            ]
        }
    ]
}
```

## 動作確認

* AWS cliからアップロードできることを確認

```shell
AWS_ACCESS_KEY_ID=XXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXX AWS_DEFAULT_REGION=ap-northeast-1 aws s3 cp test.html s3://test.example.com/
```

* 別のバケットにはアップロードできないことを確認

```shell
AWS_ACCESS_KEY_ID=XXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXX AWS_DEFAULT_REGION=ap-northeast-1 aws s3 cp test.html s3://test2.example.com/
```

* 割り当てたドメイン下で表示できることを確認

http://test.example.com/test.html

* ファイルを削除できることを確認

```
AWS_ACCESS_KEY_ID=XXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXX AWS_DEFAULT_REGION=ap-northeast-1 aws s3 rm s3://test.example.com/test.html
```

## 参考

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/EnableWebsiteHosting.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/IndexDocumentSupport.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy
パソコンの自作って難しいのか？

趣味で宇宙開発を行う団体「[リーマンサット・プロジェクト](https://www.rymansat.com/)」がお送りする新春アドベントカレンダーです。
私は[RSP-01](https://www.rymansat.com/satellites)という超小型人工衛星の地上システムを担当なのだよ実は。


# パソコンの自作って難しいのか？
- そんなことはない。誰でもできる
- 知っておくといい知識


1. マザーボード、CPU、メモリ、HDD(SSD)、キーボード、マウス、モニタがあればいい。
2. Youtubeで組み立てをしている人の動画を見よう。
3. ベアボーンっていうある程度構成が決まったキッドがあるぞ。

## きっかけ

- PCを自作しなくても結構安くなった昨今、なぜ自作をしたくなったのか。
- ベアボーンの性能が良くなった。
- ベアボーンを組んだ状態で売っている店で10万円だったものがパーツを買って組んだらいくらになるのか気になった。

## 今回のパーツ
- asrock X300
![PB060319.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/3a7b6042-39a4-6b13-9f86-8f845fab0dc1.jpeg)
- Memory
![PB060322.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/20a3c731-5b1b-91ea-7d45-346595fd06d1.jpeg)
- SSD m.2 
![PB060324.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/62a484e3-c145-644d-6eac-0ab60019a260.jpeg)
- CPU：ryzen pro 5 4650
![PB060323.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/a889b2d9-fccd-8414-1fd9-a190f899410e.jpeg)
- CPU fan
![PB060320.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/9f2d8dda-7a67-2685-6264-81c9d06ec0f3.jpeg)
- Wifi kit
![IMG_7763.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35048/17aff941-c4a9-d107-6914-37036d6109c7.jpeg)
- USBのポート増設kit

これで大体8万円くらい。
店売りされているものより高性能で且つ2万円も安い。
しかも昔ほどめんどくさくないとなれば、組み立てるしかないでしょ。
パーツ揃えてせーの！って組み立ててゆっくりやっても２時間位。

## ちなみに
- キーボード、マウス、モニタは、家に余っていたものをそのまま利用。

## それでもわからない場合は。
- パーツを買いに行ったときに店員さんに相談しよう。

# リーマンサットに入って活動して思うこと
- いろんな人が居る
- 誰が欠けてもできなかった
- 自分は〜しかできない。ではなくてやろうと思うことが大事。
- 心が折れかけても仲間がいれば大丈夫

## 入ろうかどうしようか悩んでる人へ
- とりあえず参加してみてください
- 出来ることから始めよう
- チャレンジ歓迎
- やりたい、やってみたいっていう気持ちが大事
- パソコンがなくても参加してる人います
- プログラムできなくてもOK
- わからないことは教えてくれます
- いろんな業種の人がいます


次回は、
@ynaoya_swpjtさんの「愛知県で宇宙開発やってます」です。お楽しみに

リーマンサット・プロジェクトは「普通の人が集まって宇宙開発しよう」を合言葉に活動をしている民間団体です。
興味を持たれた方は https://www.rymansat.com/join からお気軽にどうぞ
極座標で等高線図を作成(Contour maps in polar coordinate)

# はじめに
　Pythonで極座標形式の等高線図を描く方法を紹介します．[matplotlibの公式ドキュメント](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.contour.html)を参考にしたので，詳しくはそちらをご覧ください．

　本記事では，描き方の使用例として海の波の様子を表示させます．従って，変数は波の高さ・周波数・波向きの３つです．極座標形式の等高線図の周方向が波向きを，中心からの距離が周波数を，等高線の色が波高さを示します．
# 本編
## 準備
まずはモジュールのインポート

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
```


続いては表示させたいデータをインポート．
本記事では，あらかじめ用意したcsvファイルを読み込みました．ファイルは25行36列のデータです．行は周波数を表し，列は波向きです．

```python
a = pd.read_csv("GA.csv",engine='python',header=None,skiprows=0)
GA =a.values
```

## 極座標等高線図の作成
まずは，周方向と中心からの距離の軸を設定します．

ここで注意したいのが，インポートしたデータの波向きは，0°~350°([0,10,20, ,,, ,340,350])の36列です．しかし，極座標表示させたい場合は，0°~360°([0,10,20, ,,, ,350,360])の37列にする必要があります．

```python
#周方向(波向き[rad])のリスト作成
theta = 2 * np.pi/360*np.arange(0, 370, 10)
#中心からの距離(波周波数[rad/s])のリスト作成
freq=2*np.pi*np.array([0.0445953, 0.0486315, 0.053033, 0.0578329, 0.0630672, 0.0687753, 0.075, 0.0817881, 0.0891906, 0.097263, 0.106066, 0.1156658, 0.1261345, 0.1375506, 0.15, 0.1635762, 0.1783811, 0.194526, 0.2121321,0.2313317, 0.252269, 0.2751013, 0.3000001, 0.3271524, 0.3567623]) 

X, Y = np.meshgrid(theta, freq)

#25行37列の2次元リストを作成 ※360°は0°の値を読み込んでいる事に注意
wavedata=[[float(GA[i,int((j)%36)])for j in range(37)] for i in range(25)]
```

いよいよ描画．
表示させたい2次元データは最大値が4.8なので，np.linspace(0.00, 5.00, 501)のmaxを5にして，同じようにvmax=5としています．
cmapはカラーマップです．色を変えたい場合は[matplotlibの色サンプル](https://matplotlib.org/3.2.1/tutorials/colors/colormaps.html)をご覧ください．

```python
v = np.linspace(0.00, 5.00, 501)
ctf=ax2.contour(X, Y, wavedata,levels=v,cmap=cm.jet,linewidths=0.5,vmax=5)
plt.colorbar(ctf, pad=0.1,orientation="vertical")#カラーバーを横にしたければorientation="horizontal"
ax2.set_theta_zero_location("S")#0°の方角．北はN，南はS，西はW，東はE
ax2.set_theta_direction(1)#時計回りの場合は-1，反時計周りの場合は1
ax2.set_rlabel_position(60)#距離の軸の位置．単位はdeg．
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649674/822da380-32ae-7b05-b36d-569e21cac29e.png)

以上になります．お疲れさまでした．
誤りの指摘や質問等がありましたら，お手数ですがコメントください．
よろしくお願いします．
【Unity】USSファイルはディレクトリ変更、リネームに弱いので注意

**UnityのファイルはGUIDで管理**されているためUnity内でファイル移動、またはファイルのリネームをしても参照が外れず安心ですが**UI Toolkitは例外**です。

## USSファイルは文字列指定

```xml:Sample.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" engine="UnityEngine.UIElements" editor-extension-mode="False">
    <!-- 参照USSを文字列指定 -->
    <Style src="/Assets/_Sample/Uss/Common.uss" />
    <ScreenA name="ScreenA" class="screen">
        <ui:VisualElement name="bg-a" class="screen">
            <ui:Label text="Screen A" display-tooltip-when-elided="True" name="A" class="screen-label" />
        </ui:VisualElement>
    </ScreenA>
</ui:UXML>
```
上記の例ではSample.uxmlが`Common.uss`を参照しているのですが、`<Style src="/Assets/_Sample/Uss/Common.uss" />`といったように文字列で入力することになります。

UXMLはUnityにインポートする時、内部的にはScriptableObjectに変換されますが、ただのテキストファイルです。
**USSへの参照は文字列指定**になります。

## USSのパスが変更されるとどうなるのか？

単純に参照が外れます。
Unityが気を利かせてUSSの参照を追っかけてパスを修正してくれるわけではありません。


## ではどうするか？

**「USSのパスが変わらないように事前に設計する」**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/69fc033e-25a7-add4-da15-05387523e88c.png" width=440 />
僕の中では一旦この構成が良いかなと思ってきています。

- `Uss/Common.uss` 各UXMLで必ず使用する共通USS
- `Uss/各UXML名/Hoge.uss`各UXMLで使用する固有USS

USSファイル、UXMLファイル共に非エンジニアに近いクリエーターが作業することになります。[^1]

[^1]: もちろんUnityエンジニアも作業対象


その際、ファイルアイコンだけではUXMLとUSSの区別がしづらいため、ディレクトリを分けてしまうのが良いかと思っています。

もしくは`ScreenA_UXML`、`CommonUSS`のように、**UXML/USSを認識できるファイル名**にするのも良いかもしれません。

**※実戦投入してみないと何がベストプラクティスなのかはわからないため、あくまで想像の話です**

## まとめ

- 現状のUnityではUSSのファイル移動、リネームにはコストが掛かります
- 無駄な作業が発生しないようにUSSディレクトリ構成を予めFIXさせておきましょう

以上です。
SSH接続しようとしたら空き領域についての警告が出た。

## こんな警告
サーバーにSSH接続しようとしたところ、こんな警告文が出ました。
SSH接続は出来ますが何とも気持ち悪い...

```
ヒアドキュメント用一時ファイルを作成できません: デバイスに空き領域がありません
```

空き領域が無いようなのでdfコマンドで確認すると以下のようになっていました。
使用率が100%になってますね。

```
df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
/dev/mapper/centos-root    14G   14G   36K  100% /
```

## 原因
恐らく負荷テストでリクエストを送りまくったことで、ログファイルがとんでもないサイズになっていると仮説を立てました。
ログファイルを確認したところ、サイズが9GB以上になっています。

```
-rw-rw-r-- 1 hoge hoge 8403185664  1月  8 01:09 production.log
-rw-rw-r-- 1 hoge hoge  991581155  1月  8 01:58 unicorn.stderr.log
```

## 解決
ログファイルに/dev/nullをコピーしてログファイルの中身を空にしました。
これで警告が出なくなったので解決！

```
cp /dev/null production.log
```
```
-rw-rw-r-- 1 hoge hoge 0  1月  8 09:25 production.log
-rw-rw-r-- 1 hoge hoge 0  1月  8 09:26 unicorn.stderr.log
```
## 補足
「ヒアドキュメント用一時ファイルを作成できません: デバイスに空き領域がありません」で調べてみたところ、デプロイやコンパイルが出来なくなったりする事象もあるようです。
サーバー自体の挙動がおかしくなるようなので、事前に何らかの対処が必要ですね。(今回の場合は、古いログを自動で削除するようなスクリプトを書くか、OSやアプリケーションサーバでログを自動削除するような設定をするか...)