OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeでPleasanterとpostgresqlのコンテナ作ってみた

## 経緯
お仕事でPleasanter作成お願いされる事が何回かあったんでdocker初心者だけどdocker-compose.yml作ってみたよ( ˘ω˘ )
備忘録。

## 作ったもの
https://github.com/twintee/pleasanter-docker

pleasanterのベースは公式推奨のcentos7ベースと個人的な好みでdebianベースの２通り作ったよ( ˘ω˘ )

## 前提環境
python3.6系以上
windowsも多分問題ないは。。。ず？(wsl2内のdockerでは動かず。無念。）


## 使い方
* 設定変更
`./.env`
    * **DISTRIBUTION**: pleasanterのベースイメージ。
        * (default) deb -> debian, cent -> centos7
    * **TZ**: timezone。よしなに。(default) Asia/Tokyo
    * **POSTGRES_PORT**: postgres用のポート。(default) 5432
    * **POSTGRES_PASSWORD**: postgres用パスワード。変更不要。任意で。
    * **POSTGRES_MEM**: postgres割り当てメモリ。(default) 1G
    * **PLS_PORT**: pleasanter用ポート。(default)8080
    * **PLS_MEM**: pleasanter割り当てメモリ(default) 1G
* スクリプト実行  
`python3 init.py`
    ボリューム初期化、イメージのビルドしなおすか、コンテナ作成するか聞かれるので適当に`y`で流す。

## やったこと。
参考にしたqiita:
https://qiita.com/ta24toy27/items/986b3057e08f3da2fc06

* 上記から可能な部分のみDockerfile化。
    * パッケージのインストール回り
    * プリザンターのソースzipをimage内で展開  
    ※pleasanterのソース更新は`./pleasanter/pleasanter.zip`を公式ダウンロードzipに差し替え、イメージリビルド想定。

* pleasanterソースのRds.jsonの中身をコンテナの情報を(.envを元に)更新
* pleasanter設定の反映。
* pleasanterのサービスとnginxのサービスを起動。

## 心残り
* サービス起動の兼ね合いで`privileged: true`を外せない。
* pleasanterのソースがzip展開
position:sticky が効かなかった

###起こったこと

HTMLの`<nav>` と　`<aside>` を固定したかった為、CSSで`position:sticky`を設定したがうまく効かなかった。

調べたところ、以下の回答を見つけた。

>the problem you are facing here is, that your section block consumes the full height. so it won't stick, since it is too large to do so. you would need to put a child element inside your section and give that your sticky attributes, to make it work. based on your example, i simply wrapped your 'hi' inside a div.

翻訳
>ここで直面している問題は、セクションブロックが高さ全体を消費することです。大きすぎてくっつかないので、くっつきません。それを機能させるには、セクション内に子要素を配置し、それにスティッキー属性を与える必要があります。あなたの例に基づいて、私は単にあなたの 'hi'をdivの中に包みました。

###対処法
`<nav>` と　`<aside>`に各々子要素を配置したところ、うまく機能した。

```css:style.css
<nav>
      <div class="navigation">
      ...中略
      </div>
</nav>

```
```css:style.css
<aside>
      <div class="asideContainer">
      ...中略
      </div>
</aside>
```




###参考サイト

https://reffect.co.jp/html/css-position-sticky

https://www.asobou.co.jp/blog/web/css-sticky

https://stackoverflow.com/questions/50794795/sticky-position-on-css-grid-items
エラー解決 Did you mean?に惑わされないように

朝活の時、遷移できていたページに遷移できなくなった。
原因はGitHubでブランチを誤って削除してしまったためイチから。

![IMG_8504.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678154/eb0c8a0d-50dd-cf4c-d9cb-5afeb2fa5d2f.jpeg)

上記のエラー文が出てきたがパスは絶対に間違っていないと確信があったので
rails routesでパスの確認。

![IMG_8507.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678154/be1656b5-ea7c-c492-c3ed-402643a18313.jpeg)

案の定パスが消えていたので今朝、朝活でご一緒にさせていただいている方から教えていただいた内容を
無い脳みその記憶を辿ること5分...

先ずコントローラーのにアクションを記述する必要がある。
ここで必要なアクションはnewアクションとcreateアクションなので以下のように記述。

```ruby

class ItemsController < ApplicationController

  def index
  end

  def new
  end

  def create
  end
```

次にルーティングを設定する必要があるのでroutes.rbに以下のように記述。

```ruby
  resources :items, Only: [:new, :create]
```

onlyアクションを使うことでnewアクション、createアクションのルーティングの設定完了。

ターミナルで再度、rails routesを実行すると

```
 new_item GET    /items/new(.:format)                                                                     items#new {:Only=>[:new, :create]}
```

パスが復活！！

なんとか手を動かしながら独力でエラー解決できた！！
(朝活で教えて下さった方の説明が分かりやすかったのが1番)
svnを使用したら、zshにコマンドがないというエラーが出た

自分は特にM1Macを使っているので、ネットによくあるコマンドを使った時によくこの手のエラーに遭遇する。

で、今回は

https://qiita.com/rau/items/1219327df8a9ded494df

この記事をもとに特定のディレクトリから直接ダウンロードしようとしたら、zshでコマンドがないとのこと。

結論、

```
brew install svn
```

で解決。
要するにsvnがインストールされていないわけです。

### 追記

svnはめちゃくちゃ便利。
Githubの特定のディレクトリからコマンド一発でダウンロードできるのはありがたい。。。。
GithubでMergeされたPull Request一覧を作る

# Mergeされたもの一覧を出したい
例えばリリースビルドに入る変更一覧を作成するとき。
例えばなんか挙動おかしいけどあの変更いつ入ったっけ。。？などを確認するとき。
あの地点からこの地点の間で、Mergeされたもの一覧で出せたらと思うことはありませんか？

それ、できます。

# そう。 `git log` コマンドならね。

## やりたいこと
* GitHubのMerge Pull Request一覧を出したい
* 出した一覧をMarkdownリストにして、Github上のリリースに貼り付けたい
* このプロジェクトの場合、branchの命名規則が `issue/{番号}` になっているので、それを一覧に表示してリンクにしたい

### 最終的な完成形

```shell:実行ワンライナー
git log --merges --pretty='format:%s %b' 2.0.0.. | perl -nE 'say "- $1 $2" if $_ =~ /^Merge pull request (#[0-9]+) from yashims\/(.*)$/' | sed 's/issue\/\([0-9]*\)/\[issue\/\1\]\(https:\/\/github.com\/yashims\/sample\/issues\/\1\)/g'
```

```markdown
- #2 [issue/1164](https://github.com/yashims/sample/issues/1) fix: devのドメインを変える
- #4 [issue/1179](https://github.com/yashims/sample/issues/3) グラフ描画ができていないのを修正
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78827/7e501e66-727e-e9b3-fa41-866b9228b2a4.png" width="400px" />

はい。一覧になって、pull-reqへのリンクと、issueへのリンクが出てますね。


#### ワンライナー中の `2.0.0..` を　適宜変えれば、2点間のmerge差分を取れます

* `2.0.0..`: `2.0.0` から `HEAD` の間
* `abcdef..123456`: 2点のコミットハッシュの間
* `origin/2.0.0..origin/2.0.1`: originの特定のタグの間

----

以上！なにかのお役に立てれば幸いです！
C#  OpenDocumentをパワーポイントに変換

<p><strong>OpenDocument（オープンドキュメント）とは、XMLをベースとしたオフィススイート用のファイルフォーマットです。今日はSpire.Presentationという無料のライブラリを使って、OpenDocumentをパワーポイントに変換する方法を紹介します。</strong></p>
<p><strong>下準備</strong></p>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-presentation-for-net-free.html">Free Spire. Presentation</a>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210623/20210623144913.png" alt="f:id:lendoris:20210623144913p:plain" width="554" height="205" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. Presentation.dllを参照に追加してください。</strong></p>
<p><strong>（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Presentation.dll”というようになります。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210623/20210623144922.png" alt="f:id:lendoris:20210623144922p:plain" width="250" height="216" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
```c#
using Spire.Presentation;

namespace odptoPDF
{
    class Program
    {
        static void Main(string[] args)
        {
            //ファイルをロードします。
            Presentation presentation = new Presentation();
            presentation.LoadFromFile("Sample.odp",FileFormat.ODP);

       　　　 // OpenDocumentファイルで保存します。
            presentation.SaveToFile("OdptoPDF.pdf",FileFormat.PDF);

        }
    }
}
```
<h4><strong>実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210623/20210623145009.png" alt="f:id:lendoris:20210623145009p:plain" width="554" height="473" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p> </p>
DXFことはじめ #5

　DXFを扱っていると、エンティティという言葉が頻出します。直訳すると「実体」というような意味になりますが、仕様上で定義されているわけではないこともあり、そのままでは抽象的すぎてよく分かりません。

　なので、勝手に推測してしまうと、エンティティというのは、

* グループコード:0 タイプ（エンティティの始点）
* グループコード:5 エンティティのハンドル値

を持ったセルの集まりと思っておけば問題ないでしょう。

ハンドル値というのは、DXFファイル内のエンティティ間でユニークな64bit値で、多分、実際にはAutoCAD内で使用してるポインタ（のポインタ？）だと思います。

図面上の要素（線分や弧など）は、ENTITIESセクションに、このエンティティという形で保持されます。それ以外にもBLOCKSセクションやTABLESセクションでも使用されていて、R13で追加されたCLASSESセクションやOBJECTSセクション以外（つまりR12以前から使われているセクション）では、基本的なデータ構造となっています。
C# WordをPCLに変換

<p><strong>一般的にはPCLと呼ばれるPrinter Command Languageは、ヒューレットパッカード社によってプリンタプロトコルとして開発されたページ記述言語（PDL）であり、事実上の業界標準となっています。今回はFree Spire.Doc for .NETという無料のライブラリを使って、ただ三行のコードでWordをPCLに変換する方法を紹介します。</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-word-for-net-free.html">Free Spire.Doc for .NET</a>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210623/20210623144444.png" alt="f:id:lendoris:20210623144444p:plain" width="517" height="239" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p> </p>
<p><strong>2. Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいDoc.dllを参照に追加してください。（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Spire.Doc.dll”というようです。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210623/20210623144453.png" alt="f:id:lendoris:20210623144453p:plain" width="274" height="216" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
```C#
using Spire.Doc;

namespace DOCPCL
{
    class Program
    {
        static void Main(string[] args)
        {
            //ファイルをロードします。
            Document doc = new Document();
            doc.LoadFromFile("Sample.docx", FileFormat.Docx2010);

            //PCLファイルで保存します。
            doc.SaveToFile("Result.pcl", FileFormat.PCL);

        }
    }
}
```
<p> </p>
<p><strong> </strong></p>
<p> </p>
<p><strong> </strong></p>
コードが存在する実行ファイル名を知る方法

Visual Studio のテストフレームワークを使っていて、テストコードが存在するモジュールのパスを知りたいことがたまにあって、いつも「どうやるんだっけ？」となるのでメモ。

```unittest.cpp
TEST_CLASS(TestClass)
{
    static void DummyFunction()
    {
    }

    TEST_METHOD(TestMethod)
    {
        HMODULE hModule{};
        GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<PCWSTR>(DummyFunction), &hModule);

        std::vector<wchar_t> filePath(MAX_PATH);
        GetModuleFileName(hModule, filePath.data(), filePath.size());

        Logger::WriteMessage(filePath.data());  // DummyFunction が存在するモジュールのフルパス
    }
};
対策例：startActivityForResult(Intent,int) in Fragment has been deprecated

# 背景
startActivityForResult(Intent,int) での画像選択コードが deprecated と言われるので、修正前後のコード例を残しておく。

# コード

## 修正前

```java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private final static int RESULT_PICK_IMAGEFILE = 1000;

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
        super.onActivityResult(requestCode, resultCode, resultData);

        if (requestCode == RESULT_PICK_IMAGEFILE && resultCode == RESULT_OK) {
            if (resultData != null) {
                Uri uri = resultData.getData();

                // Do something here.
            }
        }
    }

    private void onSelectImage() {

        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);

        startActivityForResult(intent, RESULT_PICK_IMAGEFILE); // deprecated!!
    }
}

```

## 修正後

```java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ActivityResultLauncher<Intent> _launcherSelectSingleImage = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == RESULT_OK) {
                        Intent      resultData = result.getData();
                        if (resultData != null) {
                            Uri uri = resultData.getData();

														// Do something here.
                        }
                    }
                }
            });


    private void onSelectImage() {

        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
        Intent chooserIntent = Intent.createChooser(intent, "単一画像の選択");

        _launcherSelectSingleImage.launch(chooserIntent);
    }
}

```

# 参考リンク

- [android - Java solution for "startActivityForResult(Intent,int) in Fragment has been deprecated" when opening external URL? - Stack Overflow](https://stackoverflow.com/questions/62613424/java-solution-for-startactivityforresultintent-int-in-fragment-has-been-depre)

- [startActivityForResult()とonActivityResult()がDeprecatedになった対処法 / startActivityForResult() and onActivityResult() has Deprecated - Speaker Deck](https://speakerdeck.com/sansanbuildersbox/startactivityforresult-and-onactivityresult-has-deprecated?slide=17)
EC2(Ubuntu)にssh接続失敗した話

デフォルトのユーザー名はec2-userではなくubuntuが正解です。Amazon Linux2とはデフォルトのユーザー名が違うのですね。

[失敗例]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/606223bb-d096-456d-4271-9b620520bdf5.png)

[成功例]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/1852fcdb-f8c6-32c1-9466-98cb4dbae739.png)
機械学習勉強記録 RandomForestClassifier

# 1 RandomForestClassifierとは
RandomForestClassifierとは、複数の決定木を集めたものです。だから森なんですね。
アンサンブル学習と言って、別々の決定木が出した結果を統一させて総合的な分析結果を得ることができるものです。
このサイトがわかりやすかったです。

「cacoo」決定木分析（ディシジョンツリー）とは？概要や活用方法、ランダムフォレストも解説
https://cacoo.com/ja/blog/what-is-decision-tree/

# 2 RandomForestClassifierの実装
データフレーム(df)のデータ部分と目標値部分(column名はClass）をx,tとして、モデルを学習させる時は、このように書きます。

```python
x = df.drop('Class', axis=1).values
t = df['Class'].values
# モデルの定義
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(random_state=0)
model.fit(x, t)
```
そして、学習したモデルをもとに`df_test`の`Class`を推論します。

```python
# 推論
x_test = df_test.drop('Class', axis=1).values
t_test = df_test['Class'].values
y_pred = model.predict(x_test)
```
これで`y_pred`の中に、x,tで学習したモデルによって推論された、`df_test`の`Class`値が入ります。

# 2.1 混合行列を表示する
混合行列を　`sklearn.metrics`を用いて表示します。

```python
from sklearn import metrics

# 混同行列の作成
labels = list(set(t))
c_matrix = metrics.confusion_matrix(t_test, y_pred, labels=labels)

# DataFrameに整形
df_matrix = pd.DataFrame(c_matrix, columns=labels, index=labels)
```

# 2.2 precision, recall, F値を調べる
それぞれのスコアは、`metrics`モジュール内の関数に目標値と予測値を渡すことで確認できます。

```python
precision = metrics.precision_score(t_test, y_pred, average=None)
recall = metrics.recall_score(t_test, y_pred, average=None)
f1_score = metrics.f1_score(t_test, y_pred, average=None)
```
`average=None`と指定することで、それぞれのクラスを正例としたスコアを確認することができます。

# 3 閾値の設定
precision, recall, F値を調整するために、予測確率における分類の閾値を調整します。

```python
y_proba = model.predict_proba(x_test)
```
これで、`x_test`の一つ一つの行に対しての`Class=0`である確率と`Class=1`である確率を求め、`y_proba`に代入します。元のデータにもよりますが、中身はこんな感じです。この例だと1列目の数字が`Class=0`である確率で、2列目の数字が`Class=1`である確率です。

```python
# y_probaを10行目まで表示
print(y_proba[:10])
"""
array([[1.  , 0.  ],
       [1.  , 0.  ],
       [1.  , 0.  ],
       [1.  , 0.  ],
       [1.  , 0.  ],
       [0.97, 0.03],
       [1.  , 0.  ],
       [1.  , 0.  ],
       [1.  , 0.  ],
       [1.  , 0.  ]])
"""
```

そして、この2列目の数字に対して、閾値をもうけ、調整していきます。

```python
# 閾値0.4として、y_probaの2列目が0.4を超える場合、Trueと返す行列をy_predに代入
y_pred  = (y_proba[:,1] > 0.4).astype('i')
# .astype('i')はデータ型をintに変えている。 Falseなら 0, Trueなら 1 に変換する。 
```
こうして閾値を調整して、最終的にprecision, recall, F値を調べます。

```python
# 「t_testに対してのy_predの予測」のrecall, precision, f1score を表示する
print('recall :', metrics.recall_score(t_test, y_pred, average=None))
print('precision :', metrics.precision_score(t_test, y_pred, average=None))
print('f1score :', metrics.f1_score(t_test, y_pred, average=None))
```
これで、求めることができました。
【JavaScript】js-cookieでcookieを操作する

<h2>インストール</h2>
npmを使う場合は、

```terminal:npm
npm i js-cookie
```

yarnを使う場合は、

```terminal:yarn
yarn add js-cookie
```

<h2>使用方法</h2>
使うファイルにimportします。

```react:import
import Cookies from 'js-cookie';
```

<h3>cookieに値を保存</h3>

```react:cookiesに値を保存する
Cookies.set('cookie_name', 'value')

//7日後に有効期限が切れる、vokkiesを保存する
Cookies.set('name', 'value', { expires: 7 })

//pathを指定して、それ以下のpathでのみ有効なcookieを保存する
Cookies.set('name', 'value', { expires: 7, path: '' })
```

<h3>cookieに値を取得する</h3>

```react:cookieに値を取得する
Cookies.get('name') // => 'value'

//cookieで取得できるすべての値を取得する
Cookies.get() // => { name: 'value' }
```

ちなみに、指定したcookieが存在しない場合、undefindedを返します。

```react:cookieで指定した値がない
Cookies.get('hoge') //=> undefined
```

<h3>cookieに値を削除する</h3>

```react:cookieに値を削除する
Cookies.remove('name')
```


<h2>参考</h2>

https://github.com/js-cookie/js-cookie

https://chaika.hatenablog.com/entry/2019/02/05/083000
４つのRPAを動かしてみる（ウロボロス編）

#はじめに
https://qiita.com/etoootak/items/642ab91decdf9889257d
に続いてもう１つ。

WinActorでPower Automate Desktopを起動して、そのPower Automate DesktopからAutomation 360を起動しさらにそこからUiPath起動。
そして、UiPathからWinActorを起動。
でグルグル回る、というのを作ってみました。

#動画
https://youtu.be/pm2OmBJMJiM

#さいごに
これは「４つ同時」に動いていないので問題ないですね。
ただ何の使い道があるのか？？

相手のしっぽから食べていく蛇みたいに、他RPAの最後のBoxから削除するRPAの環を作ろうとしたのですが、これは直ぐに止まってしまうのであきらめました。
機械学習勉強記録 分類の評価方法

# 1 分類の評価方法
分類において、学習雨済みモデルを評価する指標で、代表的なものが以下の4つです。

- Accuracy(正解率)
- Precision(適合率)
- Recall(再現率)
- F1score(F値)

# 2 混合行列
上記の指標を理解するのに、混合行列と呼ばれる表が使用されます。
がんの診断をした結果、それが正しかったかどうかを表した表を例にしてみるとこんな感じになります。(図1）

|図1|
|:-:|
|![スクリーンショット 2021-06-23 11.26.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1456950/9d6e0441-24d2-6efc-7e4c-2c6cbcae0ffb.png)|

- TP (True Positive、真陽性)：予測値を正例として、その予測が正しい場合の数
- FP (False Positive、偽陽性)：予測値を正例として、その予測が誤りの場合の数
- TN (True Negative、真陰性)：予測値を負例として、その予測が正しい場合の数
- FN (False Negative、偽陰性)：予測値を負例として、その予測が誤りの場合の数

# 3 Accuracy(正解率)
Accuracyの式は以下。

```math
Accuracy=\frac{TP+TN}{TP+FP+TN+FN}
```
正しく予測できたものの数を、全ての数で割ると正解率がでてきます。簡単ですね。

# 4 Precision(適合率)
Precisionの式は以下。

```math
Precision=\frac{TP}{TP+FP}
```
正例（がん）と予測したもののうち、本当にがんだった数の割合を表します。
Precisionを高くするということは、誤診を少なくすることを意味します。
これが低いと、「あのお医者さん、めっちゃがんって診断するけど、外れること多いからあんまり当てにならんで。」と言われます。
高いと、「あのお医者さんががんと言ったら、がんだ。間違いない。」と言われます。
がんではない人をがんだと誤診したくないときは、これを高めたほうがいいでしょう。

# 5 Recall(再現率)
Recallの式は以下。

```math
Recall=\frac{TP}{TP+FN}
```
陽性（がんがある人）のうち、がんだと正しく診断された割合を表します。
Recallを高くするということは、がんの人の見落としを少なくすることを意味します。
低いと、「あのがん検診では、健康と言われても本当はがんかもしれないから当てにならんで。」と言われます。
高いと、「あのがん検診では、がんと言われても健康な時もあるし、健康って言われたら大体健康やから安心や。」と言われます。
がんの見逃しをどうしても避けたいとき、これが高いほうがいいでしょう。

# 6 F1score(F値)
F1scoreの式は以下。

```math
F1score=\frac{2\times Recall \times Precision}{Recall + Precision}
```
RecallとPrecisionは、どちらかを上げようとすると、もう一方が下がってしまう関係にあります。
両者のバランスをとるために調和平均で計算される指標がF値です。
laravelのModelでテーブル名は明示したほうが良さそうという話

laravelのリレーションの話

リレーションでuserに関連するuser_informationsを取得したい
リレーションを貼る

```
    public function user_informations()
    {
        return $this->hasOne(UserInformation::class);
    }
```
withメソッドを使おうと思っていたらこんなエラーがでた。

```
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel_local.user_information' doesn't exist (SQL: select * from `user_information` where `user_information`.`user_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
```

テーブルが見つからないらしい。

user_informationを探しているが目的のテーブル名はuser_informationsだ。

その目的のテーブルのもmodelがこれ↓

```
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class UserInformation extends Model
{
    use HasFactory;
}
```

laravelはテーブル名が指定されてない場合model名をスネークケースにして複数形にしたものをテーブル名として取得するが
どうやらまれに複数系を認識できなかったりするらしい。
(informationが普通は不可算名詞でinformationsにはならないから？)

なのでこうする

```
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class UserInformation extends Model
{
    use HasFactory;
    protected $table = 'user_informations';
}
```
protected $table =とすることでテーブル名を明示できる。

これでエラーは解決。

##今日の教訓
たまにmodelがテーブルを認識できないことがあるのでテーブル名は明示したほうがいいのかも。
BTS/ITS はどれを使う？

## はじめに

皆さんは BTS/ITS に何を使っているでしょうか？

- BTS = Bug Tracking System = バグ管理システム
- ITS = Issue Tracking System = 課題管理システム

最近はバグだけを扱う BTS よりも、機能追加などのタスクも含む ITS と呼ばれることが多いようです

私は長らく GitHub の Issues を使ってきました

しかし、社内では他のツールを使っていたりするので、どれを使うべきか、調査してみました

## 比較

Slant にランキングがありました

https://www.slant.co/topics/310/~best-free-bug-tracking-tools-for-programming

Top 8 は以下の通り

- GitLab issues
- GitHub Issues
- Bitbucket's bug tracker
- Redmine
- Phabricator
- Bugs
- Bugs Everywhere
- Mantis BT

ただ、全体的に情報が古いです

GitHub のプライベートリポジトリーの制約や、各種クラウドサービスに関する記述が現在と違うようです

というわけで、使ってみながら比較します

### GitHub & GitLab

https://github.com/

https://about.gitlab.com/

どちらもほぼ同じことができます

- Markdown による記述
- 画像の添付
- Issue　のテンプレート（複数種類）
- Kanban　での可視化、自動移動
- マイルストーンの設定
- PR（コードの変更）との紐付け
- ラベル付け

この辺りはだいたいどのサービスでも同じですね

ただし、入力できる項目に違いがあります

GitHub

![スクリーンショット 2021-06-23 13.13.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6c6ce98d-571f-de6d-6fb9-e4de6ed77cff.png)

GitLab

![スクリーンショット 2021-06-23 13.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d1b3ccb5-f6da-0c46-43b8-fd1efbcb2ac0.png)

GitLab には、 GitHub にはない以下の項目があります

- Weight = 重要さ、難しさ、複雑さ
- Due Date = 期限

GitHub で同じことをしようと思えば、こうなります

- Weight: Label に weight:1 、weight:2 などを作る
- Due Date: マイルストーンに紐付ける、期限毎のラベルを作る

GitHub　はあくまでもバージョン管理がメインなので、この辺りは非常に簡素になっています

### Bitbucket

https://bitbucket.org/product/

Bitbucket を使ってみたら、 `Bitbucket's bug tracker` は `Jira Issues` に統合されていました

Jira は課題管理だけでなく、進捗などのプロジェクト管理全体を行います

グラフなどの可視化が得意で、UIも優れているようです

![スクリーンショット 2021-06-23 13.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/51e54e54-4598-9dfe-5dea-067bab6241d4.png)

プラグインで工数管理もできるようですね

Jira と統合することで、非常に使いやすくなっていると思いますが、、、

Jira はやはり有償なのがネックですね

GitHub Issues との比較が公式サイトに出ています

https://www.atlassian.com/ja/software/jira/comparison/jira-vs-github

１０ユーザーまでなら無償で使えるようですが、小規模だとそこまで要らないんじゃ？というのが正直な感想です

Bitbucket　からだと普通の一覧表示しか見れず、ロードマップや Kanban を見るためには結局 Jira に行かないといけないのもカッコ悪い

### Redmine

https://hosting.redmine.jp/

昔少しだけ使ったことがありますが、今はクラウド版もあるんですね

チケットという形で課題を登録します

チケットには以下の項目があります

- ステータス
- 優先度
- 担当者
- 親チケット
- 開始日
- 期日
- 予定工数
- 進捗率

チケット間で親子関係が作れるあたりが良さそうですね

単なる課題管理ではなくプロジェクト管理のためには予定工数は必須でしょうね

ガントチャートやカレンダーによる可視化も強いです

![スクリーンショット 2021-06-23 12.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d71140c5-2c7a-d1ea-1e58-bb86ef8d0853.png)

![スクリーンショット 2021-06-23 12.44.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/12516e56-6e5e-1025-2be1-247e178b3b93.png)

##　まとめ

BTS/ITS は目的によって使い分ける、もしくは連携させることになると思います

- シンプルに課題管理したい、コードと同じサービスを使いたい
  - GitHub Issues
  - GitLab Issues
- 工数や進捗など、プロジェクト管理全体を統合して使いたい
  - Bitbucket（Jira）
  - Redmine

個人的には GitHub Issues で十分ですが、やはりプロジェクト管理となると、 Jira や Redmine 、 Backlog という選択肢が出てくるかな、と感じました
ソースコードの圧縮


HTMLはmacroで圧縮可能だがrequire cssで{{ standard_header_includes }} に出力されるcssは圧縮できない可能性が高い


## 下記の場合の結果
・HTML部分のみ1行に圧縮される。
・CSSは複数行で出力される


```
{%- macro func_compress() -%}
<p>
  圧縮したいHTMLタグとテキストが入ります
</p>

{% require_css %}
<style>
  .test {
    background-color: red;
    color: red;
    border-color: red;
  }
</style>
{% end_require_css %}
{%- endmacro -%}
{{ func_compress()|cut('\n')|regex_replace(' {2,}', ' ') }}
```
【PowerShell】Set-ExecutionPolicy RemoteSignedしたら、「レジストリ キー 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\Shell Ids\Microsoft.PowerShell' へのアクセスが拒否されました」と怒られた

<h2>症状</h2>
「Set-ExecutionPolicy-RemoteSigned」で実行ポリシーを変更しようとしたところ、下記エラーが発生してしまいました。

```terminal:
> Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy : レジストリ キー 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\Shell
Ids\Microsoft.PowerShell' へのアクセスが拒否されました。 既定 (LocalMachine) のスコープの実行ポ 
リシーを変更するには、[管理者として実行] オプションを使用して Windows PowerShell を起動してくだ 
さい。現在のユーザーの実行ポリシーを変更するには、"Set-ExecutionPolicy -Scope CurrentUser" を実 
行してください。
発生場所 行:1 文字:1
+ Set-ExecutionPolicy RemoteSigned
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (:) [Set-ExecutionPolicy], UnauthorizedAccessE  
   xception
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands  
   .SetExecutionPolicyCommand
```

「既定 (LocalMachine) のスコープの実行ポリシーを変更するには、[管理者として実行] オプションを使用して Windows PowerShell を起動してください。」とあり、既定 (LocalMachine)のスコープで実行をポリシーを変更しようとしても、そんな権限内から、管理者として実行して、権限がある状態で変更してねと言われています。
つまり、顕現不足のエラーです。

念のため、実行ポリシーも確認してみます。

```terminal:実行ポリシーの確認
> Get-ExecutionPolicy
Restricted
```

実行ポリシーがRestricted(すべてのスクリプトが制限される)になっていました。

<h2>解決策</h2>

PowerShell を[管理者として実行する]から起動し、”Set-ExecutionPolicy” することで、実行ポリシーを変更できました。

まず、PowerShellを管理者として実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/36750826-deee-7404-4728-4389d5f27300.png)

PowerShell 画面に、「管理者」と書いてあることを確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/d4603ea7-dcd9-de84-e5d0-4308eeea2bd9.png)

```powershell:Set-ExecutionPolicy
> Set-ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): y
```

これで実行ポリシーが変更されたました。念のため、確認してみます。

```
> Get-ExecutionPolicy
RemoteSigned
```

RemoteSigned( ローカルのファイルは実行可能)になっていることが確認できました。

<h2>参考</h2>

https://cheshire-wara.com/powershell/ps-cmdlets/sequrity/set-executionpolicy/
InDesign スクリプト 変数を削除

変数を削除するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
更新 2021/6/22
*/

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

// スクリプト名
var scriptName = "変数を削除";

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

    // ダイアログ
    var dialogueFlg = confirm("インスタンスを持たないカスタムテキスト変数を削除します。","", scriptName);

    // Noの場合
    if (dialogueFlg == false) {

        // 終了
        exit();
    }

    // 削除した数
    var removeNumber = 0;

    // テキスト変数の数だけ逆に繰り返す
    for(var i = app.activeDocument.textVariables.count() - 1; i >= 0; i--){

        // カスタムテキスト変数の場合
        if(app.activeDocument.textVariables.item(i).variableType == VariableTypes.CUSTOM_TEXT_TYPE){

            // インスタンスがない場合
            if(app.activeDocument.textVariables.item(i).associatedInstances.length == 0){

                // 削除
                app.activeDocument.textVariables.item(i).remove();
                
                // 数を増やす
                removeNumber++;
            }
        }
    }

    // 結果を表示
    alert("削除数 " + removeNumber, scriptName);

//スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);
~~~
「やればできる！」と言われたときだけ「ビビビビビタミン！MATCH」と返すmatch式

# はじめに
こんにちは。先日兄から自動化処理の仕事を受注しました、筆者です :bow:

さて、今回は初のネタ記事です:smile:

でも一応PHP8に触れているので興味持っていただければそれだけでうれしいです:bow:

# MATCHという飲み物を知っていますか？
↓これ

https://www.matchnews.com/

自分は高校生の頃に飲んでいた記憶です。

食堂（購買）横に設置している自販機に夏になる現れる人気(主観)な飲み物です！

私だけですかね、なんか**青春**って感じがします :relaxed:

最近はお笑い芸人の**ティモンディ**の2人がCMをやっていますね！

# match式を知っていますか？
これ↓

https://www.php.net/manual/en/control-structures.match.php

PHP8で追加された、関数ではなく、**式**です！

(コマンドで関数のリファレンス参照しようとして気づきました、、あ、関数じゃないわ、これ :sweat_smile: )

```sh
$ php -v
PHP 8.0.3 (cli) (built: Mar  5 2021 07:54:13) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.3, Copyright (c), by Zend Technologies
$ php --rf match
Exception: Function match() does not exist
```

ざっくり説明すると、厳密なswitch文みたいな感じです。
ただ、使い方によってはあいまい差を持たせることもできます。

## match式のメリット
ざっと思いつくメリットは以下でして、フォールスルーは場合によってはスマート(主観)に書けるケースもあると思っているので、すべてが悪だと私は思っていませんが、バグの温床にもなるので無いと助かります。

1. フォールスルーしない
1. 厳密な比較
1. 返り値がある式

# 本題
ただただ、match式を使いたいだけに、「**やればできる！**」と言われたときだけ「**ビビビビビタミン！MATCH**」と返す**match式**を作ります！

```php
<?php
echo match ($argv[1]) {
    'やればできる！' => "ビビビビビタミン！MATCH\n",
    'なせばなる' => "vitamin\n",
    'うてばひびく' => "ティモンディ\n",
    default => null
};
```

# 実行

```sh
$ php match.php "やればできる！"
ビビビビビタミン！MATCH
$ php match.php "なせばなる"
vitamin
```

# おわりに
**やればできたよ！**

それでは！
【Nuxt】Layoutのsassが子Pageに適用されなくて困ったときのメモ

## TL;DL
> * nuxtでcomponentを利用したlayoutを組んでpageを作成したら、スタイルが適用されなくて困った
> * styleをscopedのまま子ページまで効かせたい
> * deep selector を利用することで解決した

## 環境
* nuxt ^2.15.3
* sass-loader ^10.1.0

## スタイルが効かない
nuxtでWebサービスを作成しているとき、レイアウトに記述したスタイルがページに適用されていないことに気づきました。

一時的に`<style>`の`scoped`を外すことで対応していたのですが、毛色の違う別のレイアウトを用意することになり、本格的に対応が必要になりました。

また、自分の開発形態が特殊で実際のレイアウトは`components`に用意して`layouts`の方から呼び出す形式をとっていました。
以下に簡単なサンプルを用意しています。
> components
> ∟TestLayout.vue
> layouts
> ∟test.vue
> pages
> ∟testPage.vue

```vue
// TestLayout.vue
<template>
  <div>
    <h1>テスト</h1>
    <nuxt-child />
  </div>
</template>

<style lang="scss" scoped>
.hoge {
  color: aqua;
}
</style>
```
```vue
// test.vue
<template>
  <test-layout>
    <Nuxt />
  </test-layout>
</template>

<script>
import TestLayout from '../components/TestLayout'
export default {
  components: {
    TestLayout,
  },
}
</script>
```

```vue
// testPage.vue
<template>
  <div>
    <p class="hoge">コンテンツ！</p>
  </div>
</template>

<script>
export default {
  layout: 'test',
}
</script>
```

TestLayout.vueで定義した`.hoge`クラスをtestPage.vueに適用したいのですが、このままではダメです。

## Deep Selector
詳細は分かりませんが、`scoped`のスタイルを子コンポーネントに及ぼしたい場合に利用できるものみたいです。

書き方としては、`>>>`、`/deep/`、`::v-deep`などがあるみたいですが今回は`::v-deep`を採用しました。

scssなら下記のように囲ってあげるだけで大丈夫です。

```vue
// TestLayout.vue
<template>
  <div>
    <h1>テスト</h1>
    <nuxt-child />
  </div>
</template>

<style lang="scss" scoped>
::v-deep {
  .hoge {
    color: red;
  }
}
</style>
```

## 参考
* [スコープ付き CSS#ディープセレクタ](https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html)
* [Vue.jsでのdeep selectorの書き方](https://qiita.com/h-naito/items/f6ca679276282dce2600)
【ZOHO CRM】数式項目で四捨五入をする方法

## 概要

Zoho CRM の数式項目には、四捨五入をする ROUND 関数がありません。しかし、Floor 関数を利用することで四捨五入が可能です。

## 詳細

項目の中でなにかしらの値を計算し、結果を四捨五入したいことがあると思います。そのような場合、Excel などでは ROUND 関数を使用して四捨五入できますが、Zoho CRM の数式項目の関数には ROUND 関数がありません。しかし、Floor 関数で計算することで代替できます。

## Floor 関数とは

`入力された数字以下で最大の数字を返します。Floor(3.8)は3を、Floor(-3.4)は-4を返します。`

引用元：[数式項目の作成](https://help.zoho.com/portal/ja/kb/crm/customize-crm-account/customizing-fields/articles/%E6%95%B0%E5%BC%8F%E9%A0%85%E7%9B%AE%E3%81%AE%E4%BD%9C%E6%88%90#_1)


## Floor 関数による四捨五入

`123 * 9.876 = 1214.748`を例として紹介します。

● 小数第 1 位で四捨五入

```
Floor(${カスタムタブ.項目A}*${カスタムタブ.項目B}+0.5)
```

`結果：1215`
<br/>
● 小数第 2 位で四捨五入

```
Floor(${カスタムタブ.項目A}*${カスタムタブ.項目B}*10+0.5)/10
```

`結果：1214.7`
<br/>
●1 の位で四捨五入

```
Floor(${カスタムタブ.項目A}*${カスタムタブ.項目B}/10+0.5)*10
```

`結果：1210`


## まとめ

今回は、Floor 関数を利用して四捨五入する方法を紹介しました。数式項目で四捨五入をしたい方の参考になれば幸いです。

<br/>


> いろいろと備忘録として残しておきたいと思いますが、あくまでも備忘録なので、100%正しいとは限らないことご了承ください。
vMotion(Live Migration)/Cold Migrationで利用されるネットワーク

以下の記事に詳細が載っている（2つの記事は同じ内容です）ので、ここではそのまとめだけを列挙したいと思う。

https://core.vmware.com/resource/what-network-used-hot-and-cold-workload-migrations
https://blogs.vmware.com/vsphere/2019/12/hot-and-cold-migrations-which-network-is-used.html


- cold migration: 
    - 移行対象のVMが、移行期間中に**power-off**になっていること。
    - Intel <-> AMD のようにCPUのアーキテクチャーが変わっても良い。
    - **Power-off状態のVMやcloneやsnapshotはcold dataであり、vMotionネットワークを使わない。**もしProvisioningネットワークが構成されていたらそれを優先的に利用し、もしProvisioningネットワークが構成されていない場合はManagementネットワークを利用する。

- hot migration(vMotion):
    -  移行対象のVMが、移行期間中に**power-on**になっていること。一般的にはVMがアプリケーションが利用可能になっている状態。
    -  vMotionは、hot dataとcold dataの２種類のデータを転送する必要がある。
    -  vMotionネットワークが構成されていた場合は、移行中に変更が発生するメモリ状態やデバイス状態やchild delta disksなどのHot dataの移行にはそれを利用する。
    -  **しかし、snapshotやnon-child delta disksやvmx logsはcold dataであるため、vMotionネットワークは利用しない。** これらの移行についてはProvisioningネットワークが構成されていたらそれを優先的に利用し、もしProvisioningネットワークが構成されていない場合はManagementネットワークを利用する。


こちらの[KB59232](https://kb.vmware.com/s/article/59232?lang=ja)にも同様の記載がある。
>vMotion データ フローおよびネットワークの要件
vMotion は、コールド データと ホット データの 2 種類のデータを転送します。コールド データは、vMotion の実行中に変更されない仮想マシンのデータを意味します。仮想マシンのスナップショット、子以外のほとんどの差分ディスク、vmx ログなどが含まれます。ホット データは、vMotion 中に変更される仮想マシン データを意味します。メモリの状態、デバイスの状態、および子のほとんどの差分ディスクなどが含まれます。

>コールド データ転送用の VMKernel ポート
いずれかの VMKernel ポートがプロビジョニング トラフィック用に構成されている場合は、プロビジョニング netstack を設定するか、特定のポートでプロビジョニング トラフィックを有効にすると、コールド データがこのポートを経由するようになります。プロビジョニング トラフィック用に構成されている vmkernel ポートがない場合、コールド データは管理 vmkernel ポートを経由します。

>ホット データ転送用の VMKernel ポート
いずれかの VMKernel ポートが vMotion トラフィック用に構成されている場合は、vMotion netstack を設定するか、特定のポートで vMotion トラフィックを有効にすると、ホット データがこのポートを経由するようになります。vMotion を実行するには、一部の vmkernel ポートを vMotion トラフィック用に構成する必要があります。



#（参考）
IBM CloudのVCSでは、以下のようにProvisioningネットワークは構成されていないので、Cold DataはManagementネットワークを利用する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/27dc35da-dba9-042c-34f3-6a6851bf82db.png)
Swift5でgetterとsetter(計算型プロパティ)についてまとめた

# はじめに
こんにちは@kaneko77です。
`getter`と`setter`についてたまにわかりずらいなと思ってしまう時があった為
調べ直したものをまとめたいと思います。

# getterとsetterについて
この二つを説明するにあたって`計算型プロパティ`という物を説明する必要があります。
計算型プロパティとは **値の参照と更新の機能を手続きで構成するプロパティ**になります。
そして計算型プロパティにはget節とset節というものがありそちらが今回のgetterとsetterになるということです。
**get節が`getter`でset節が`setter`です。**
計算型プロパティは、**値の更新と参照ができるパターン**と**参照だけできるパターン**がの２種類があるということも知って置いてください。
結局のところ、参照した結果の値を計算するのが`get節`で、指定された値を使ってプロパティを表す値を更新する部分が`set節`になるということです。

## 上記のまとめ
`get節`: 参照した結果の値を計算する
`set節`: 指定された値を使ってプロパティを表す値を更新する
`getter`: どういう風に値を取得するのか
`setter`: 値を代入した場合の動き
get節のみの定義でもできる


# 説明
## 基本
以下が計算型プロパティのゲッタとセッタを基本の形でコードを現した物になります。。 

```swift
var プロパティ名: 型 {
    get{
        ....
    }
    set(仮引数){
        ....
    }
}
```
## 仮引数の省略
仮引数は省略可能でその場合は値の取得は`newValue`という変数が使えます。

```swift
var プロパティ名: 型 {
    get{
       ....
    }
    set{
       return newValue 
    }
}
```
## returnの省略
関数と同じなので`return`は省略できます。

```swift
var プロパティ名: 型 {
    get{
       ....
    }
    set{
       newValue 
    }
}
```
## setの省略
プロパティの値を参照するときだけの場合はsetが必要ない為、省略できます。

```swift
var プロパティ名: 型 {
    get{
       ....
    }
}
```

`get`のみの場合さらに省略することができます。
以下もゲッタを使ってるのと同じです。
`get`自体を省略できます。

```swift
var プロパティ名: 型 {
    ....
}
```

# 具体的な利用シーン
それでは書き方として色んな書き方や概念がわかってきたと思うので続いて
じゃー具体的にどういう時に使われるのかというお話になります。
以下がよく使われる例

- 税込み価格・税抜き価格取得したい時
- 入力文字を全部大文字にしたい時

etc..
それでは上記二つを例としてコードで書いてみます。

## 税込み価格・税抜き価格取得したい時
今は税金10%の時代なので1.10でやります。

```swift
var price: Double = 100
var tax: Double {
    get{ 
        price * 1.10
    }
    set{ 
        price = newValue / 1.10
    }
}
price = 1000
// 税込み価格を取得
print(tax) // 1100.0

tax = 1100
// 税抜き価格を取得
print(price) // 999
```
## 入力文字を全部大文字にしたい時
```swift
var inputValue = "test"
var uppercaseValue: String {
    get { inputValue }
    set { inputValue = newValue.uppercased() }
}

uppercaseValue = "hogehoge"
print(uppercaseValue) // HOGEHOGE
```

#終わりに
今回は`getter`と`setter`について共有しました。
プロパティのメリットは外部から参照した時に意図しない変更を加えられなくするところだと思います。
`getter`は対象の値を書き換えたくない時などに使えると思います。
`setter`は何か付け加えた時、例えば名前の先頭文字に全部`mr.`とかつけたいなど**要は値の加工ですね**に使えると思います。
慣れれば割といろんなところに使えると思います。

ここまで読んでいただきありがとうございます。

## 参考にしたサイト
https://qiita.com/nack43/items/5e1d7972ed0b54daeb04
https://www.hfoasi8fje3.work/entry/2018/05/07/002215
【Rails】bundle installができない時の解決方法

超初心者向けです。
gemをインストールする際に`bundle install`を実行した時の、エラーの解決方法を紹介します。

##エラー内容
```ruby:ターミナル
Fetching source index from https://rubygems.org/
Retrying fetcher due to error (2/4):
Bundler::HTTPError Could not fetch specs
from https://rubygems.org/
Retrying fetcher due to error (3/4):
Bundler::HTTPError Could not fetch specs
from https://rubygems.org/
```
bundle install を実行しところ、随分待たされた挙句に上記のエラーが発生。

##試したこと

```
gem update --system
```
私の場合、試してもエラーが発生。
大体は解決するそうですが、、、

##解決方法
PCを再起動、もしくは、通信環境が良いところで再度チャレンジ。
focalboard (mattermost/focalboard)

## 特徴

* 29MB （docker images だと 63.7MB） ととても小さい。
* dockerコンテナはAlpineベースだった。

## 公式HP

https://www.focalboard.com/download/personal-edition/docker/

```sh:
docker run -it -p 80:8000 mattermost/focalboard
```

* データー(sqlite3)
    * /opt/focalboard/focalboard.db
* コンフィグ
    * /opt/focalboard/config.json

* /opt/focalboard/ 以下がアプリケーションディレクトリ。
Excelのvbaから、Outlookを操作して、「分類」を、まとめて設定するやり方です。


Excelのvbaから、Outlookを操作して、
「分類」を、まとめて設定するやり方です。


```vb:code1.bas
Private Sub CommandButton1_Click()

    If MsgBox("Outlookの分類をすべて削除します　（止める場合はキャンセル）", vbOKCancel) = vbOK Then
        Application.Cursor = xlWait
        Call ぜんぶ削除
        Application.Cursor = xlDefault
        MsgBox "削除しました"
    End If

End Sub

Private Sub CommandButton2_Click()

    If MsgBox("Outlookの分類を登録します　（止める場合はキャンセル）", vbOKCancel) = vbOK Then
        Application.Cursor = xlWait
        Call ずんずん追加
        Application.Cursor = xlDefault
        MsgBox "登録しました"
    End If

End Sub
```


設定用のエクセルシートでは、
main0という名のシートを用意し、
１行目から３５行目（※一旦の上限）までに、
１列目：分類名
２列名：色
を入力して、実行する。


```vb:code2.bas
Sub ぜんぶ削除()

    Set myol = CreateObject("Outlook.Application")

    Dim Ns As Outlook.Namespace
    Set Ns = myol.GetNamespace("MAPI")
    Dim olCats As Categories
    Dim olCat As Outlook.Category
    Dim olCatCon As Outlook.CategoryRuleCondition

    For Each olCat In Ns.Categories
        'Debug.Print olCat.Name, olCat.Color
        myol.Session.Categories.Remove (olCat.Name)
    Next

    Set Ns = Nothing
    Set myol = Nothing
End Sub



Sub ずんずん追加()

    Set myol = CreateObject("Outlook.Application")

    Dim Ns As Outlook.Namespace
    Set Ns = myol.GetNamespace("MAPI")
    Dim olCats As Categories
    Dim olCat As Outlook.Category
    Dim olCatCon As Outlook.CategoryRuleCondition

    For i = 1 To 35
        If Sheets("main0").Cells(i, 1).Value <> "" Then
            myol.Session.Categories.Add Sheets("main0").Cells(i, 1).Value, CInt(Sheets("main0").Cells(i, 2).Value)
        End If
    Next

    Set Ns = Nothing
    Set myol = Nothing

End Sub
```

単に参考、色の意味

```vb:color.bas
'olCategoryColorNone	0
'olCategoryColorRed	1
'olCategoryColorOrange	2
'olCategoryColorPeach	3
'olCategoryColorYellow	4
'olCategoryColorGreen	5
'olCategoryColorTeal	6
'olCategoryColorOlive	7
'olCategoryColorBlue	8
'olCategoryColorPurple	9
'olCategoryColorMaroon	10
'olCategoryColorSteel	11
'olCategoryColorDarkSteel	12
'olCategoryColorGray	13
'olCategoryColorDarkGray	14
'olCategoryColorBlack	15
'olCategoryColorDarkRed	16
'olCategoryColorDarkOrange	17
'olCategoryColorDarkPeach	18
'olCategoryColorDarkYellow	19
'olCategoryColorDarkGreen	20
'olCategoryColorDarkTeal	21
'olCategoryColorDarkOlive	22
'olCategoryColorDarkBlue	23
'olCategoryColorDarkPurple	24
'olCategoryColorDarkMaroon	25
```
【nhk.or.jp】番組紹介にあるプレイリストの曲をSpotifyで検索するためのブックマークレット

# はじめに
よくラジオでNHK-FMの音楽番組を聴きます。
先日ふと見ると、過去に放送されたプレイリストがウェブサイトに掲載されていることに気づきました。
その中の気に入った曲をSpotifyのプレイリストに簡単に追加できたら嬉しいかも！
普段Spotifyを使う音楽ファンの私はそう思いました。

皆さんは音楽配信サービスを使っていますか？

そういうわけで今回紹介するのは「楽曲検索用ボタンを追加するブックマークレット」です。

# コード

```js
javascript:(()=>{const r=[],o=document.querySelector(".program-onair-music li"),e=o.innerHTML.split(/<br><br>/);for(const o of e){const e=o.split("<br>");r.push('<a href="//open.spotify.com/search/'+encodeURIComponent(e[0].slice("1","-1")+" "+e[1].replace(/:作曲/,""))+'" style="background-color:#fff;padding:3px" target="_blank">&#x1f3b5;</a> 「'+e[0].slice("1","-1")+"」<br>"+e[1]),e[2]&&r.push("<br>"+e[2]),e[3]&&r.push("<br>"+e[3]),e[4]&&r.push("<br>"+e[4]),r.push("<br><br>")}o.innerHTML=r.join("")})();
```

# 使い方
1. デスクトップでNHKラジオ番組案内の過去の放送（例えば https://www4.nhk.or.jp/jazz/5/ ）を開く。
2. お好みの日付をクリック。
3. ブックマークレットを実行する。
4. プレイリストの各曲の先頭に追加された```♫```をクリックする。

# 解説

上記のコードは以下のコードを圧縮したものです。

```js

(
    () => {
// ---------

const html_data = [];// for update
// playlist
const li = document.querySelector('.program-onair-music li');
const list_item = li.innerHTML.split(/<br><br>/);
for (const elm of list_item) {
    const playlist = elm.split('<br>');
    // playlist[0]: song name
    // playlist[1]: artist name
    // playlist[2]: time
    // playlist[3]: product code

    html_data.push(
        '<a href="//open.spotify.com/search/' + encodeURIComponent(playlist[0].slice('1','-1') + ' ' + playlist[1].replace(/:作曲/, '')) +
        '" style="background-color:#fff;padding:3px" target="_blank">&#x1f3b5;</a> 「' +
        playlist[0].slice('1','-1') + '」<br>' + 
        playlist[1]
    );
    if (playlist[2]) html_data.push('<br>' + playlist[2]);
    if (playlist[3]) html_data.push('<br>' + playlist[3]);
    if (playlist[4]) html_data.push('<br>' + playlist[4]);

    html_data.push('<br><br>');
}

// html update
li.innerHTML = html_data.join('');

// ---------
    }
)();
```

javascriptのコードを見る前に、nhk.or.jp の``html``を確認しときましょう。プレイリストの該当部分はざっと次のようになっています。**「曲名」の先頭に検索用リンクボタン``♫``を追加するのが最終目標**です。


```html
<div class='program-onair-music'>
<ul><li>
「曲名」<br>
アーティスト<br>
演奏時間<br>
音源<br><br>

「曲名」<br>
アーティスト<br>
演奏時間<br>
音源<br><br>

「曲名」<br>
アーティスト<br>
演奏時間<br>
音源<br><br>
...
</li></ul>
</div>
```

１つの\<li\>の中に全曲が記述され、曲と曲は\<br\>を連打して分けられているので、どうにも困ります。
これを踏まえてjavascriptを考えます。ちょっと面倒ですが、この場合\<li\>内の文字列を\<br\>\<br\>で分割し、これをさらに\<br\>で分割すると全ての曲のデータが得られます。以上が**曲情報の取得部分**です。

次に**htmlを組み立てます**。\<li\>内を一度に置換するやり方でいきます。他にいい方法を思いつきません。
予め、置換用htmlを保存する配列html_dataを用意し、次の順番で曲に関するデータを追加していきます。

1. ``♫``（曲名とアーティストで検索するためのリンクを設定している）
2. 「曲名」: playlist[0]
3. アーティスト: playlist[1]
4. 演奏時間: playlist[2]
5. 音源: playlist[3]

元のhtmlに倣って\<br\>を挟みながら、これを全曲分繰り返します（番組によって配列playlistの長さは変わり、その項目も異なります）。最後に配列html_dataの要素を連結して、**現在のプレイリストとまるごと置き換え**て完成です！

# あとがき

一部の番組紹介に関しては明らかにDOMの構成が異なるので、コードの修正が必要です。形式が統一されていないのが残念です。
最近はプレイリストを公開しているFM局が多いです。今度は、そちらの方の攻略を目指したいと思います。

本日もありがとうございました。

# 参考
+ https://qiita.com/embokoir/items/d667a6802105b842fb48
Thread Pool デザインパターン

worker threadsパターンを理解する記念すべき一歩を踏み出したのでメモる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/f733811c-f721-22b7-cb06-e0abd4d57b88.png)

(https://en.wikipedia.org/wiki/Thread_pool より引用)


Worker Thread
Thread Poolは、デザインパターンの一つ。


Thread Poolは以下の役割を持つ
- 複数のWorker Threadを保持する(manageする)



- threadは使い捨てではない
    - taskの実行が終了すると、idle 状態になって待っている
    - これによって、threadを切るときの[|de]construction costをセーブできる
    - threadを多く用意してしまうと、メモリ確保のspace costがかかる
    - context-switchingによるパフォーマンスのペナルティーがかかる



## 実用例

- webサーバー
   - conncetionをpoolする？
   - https://stackoverflow.com/a/18901132
   - circuit breaker パターンもつかってる？ https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern


DBサーバのConnection Pool は、Thread Poolパターンではなく、Object Poolパターンを使っているっぽい..?
でもよく考えると、そもそも、Thread Poolもパターンが、Object Poolパターンの一つなのかも


## (関係ない)メモ

- Pumaはマルチスレッド、Uniconrnはマルチプロセスで動くのが基本。
    - Pumaは [clustered modeを使用すれば、マルチプロセスもいける](https://github.com/puma/puma#clustered-mode)
psycopg2をインストールするまでにやったこと(とりあえずメモ)

pythonとpostgresqlを繋ぐライブラリとしてpsycopgがあるらしいので導入しようとしたが、なかなかインストールに手こずったのでメモ。

最終的にhttps://rikeiblog.com/python-18/　
を参考に、コマンドラインをダウングレードすることでインストールできた。

pip install psycopg2
pip3 install psycopg2を実行するとエラー
ERROR: Command errored out with exit status 1:
     command: /Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/0d/kn7w1rj50mz8s1lpp6tyng2c0000gt/T/pip-install-2rih1wyp/psycopg2_aa03eb35d88c42c2815696730016a56b/setup.py'"'"'; ....

env LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" pip --no-cache install psycopg2
も同じようなエラーが出る

WARNING: You are using pip version 21.1.1; however, version 21.1.2 is available.
You should consider upgrading via the '/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip' command.
みたいなことを言われたので素直に従う


/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip

もう一度以下を打つがエラー
env LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" pip --no-cache install psycopg2

brew install llvm
brew install gcc
をした後にenv LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" pip --no-cache install psycopg2
 
エラー文中の
ld: unsupported tapi file type
でググったところhttps://rikeiblog.com/python-18/　
を見つけコマンドラインをダウングレードすることでインストールできた。
エクセルで、悪さしがちな（他文書などへの）リンク（や名前の定義）をvbaでまとめて消す方法



エクセルで、悪さしがちな
（他文書などへの）リンクをvbaでまとめて消す方法


```vb:del_link.bas
'すべてのリンクを削除する/ リンクの解除
Sub subete_no_link_wo_sakujo()

    For Each ls In ActiveWorkbook.LinkSources
        'Debug.Print ls
        ActiveWorkbook.BreakLink Name:=ls, Type:=xlExcelLinks
    Next

End Sub
```

ちなみに、「消すことができない」リンクは、「名前の定義」に含まれていることが多い。このため、名前の定義をまとめて消すコードは以下。
（名前の定義は、手動でもまとめて消せます。念のため。）


```vb:del_name.bas
Sub 参考_名前の定義の削除()

    For Each n In ActiveWorkbook.Names
        'Debug.Print n
        n.Delete
    Next

End Sub
```
Ubuntu上でNeo4jを触ってみる

https://qiita.com/hoku/items/66ce12e928524d92958a
インストール手順はこちら。
以下は、上記投稿内容のインストールが済んでいる前提となります。

## Neo4j 起動

```
service neo4j start
```

## ブラウザで開く

http://127.0.0.1:7474/browser/
にアクセス。

### 接続情報を入力

「Username」と「Password」の両方に ``` neo4j ``` と入力して「Connect」ボタンを押す。

![Screenshot from 2021-06-21 10-02-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86842/3e61cc64-0613-422f-373d-043fae315602.png)

### 初回パスワード変更

好きなパスワードに変更する。

![Screenshot from 2021-06-21 10-03-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86842/99e1fa22-45a4-ea30-5ceb-806bd6df97f1.png)

### Neo4jが使える状態になった！

![Screenshot from 2021-06-21 10-04-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86842/85c98666-d602-817b-7147-280babe072ff.png)


## Neo4j 停止

```
service neo4j stop
```
インターフェースの多重継承(Java Silver)

# はじめに
Java SE 11 Silver取得に向けて学習中に、練習問題にて出題されたのでまとめてみました。
今回は4パターン紹介します。
継承の仕様(オーバーライド、オーバーロード)を把握していると、より理解しやすいかと思います。
また、共変戻り値に関しましては今回は取り上げませんでした。
※オーバーライド、オーバーロードを理解したい方は [こちらの記事](https://qiita.com/Molly95554907/items/fbcfb68a37b56fde4307) を参照

# パターン１
```java:Interface_A.java
interface Interface_A{
	void test();
}
```
```java:Interface_B.java
interface Interface_B{
	void test();
}
```
```java:Interface_C.java
interface Interface_C extends Interface_A, Interface_B{
	void test();//コンパイル可
}
```
+ 全てのインターフェースが同じシグニチャのメソッドを宣言している場合です。
<br>**CにA Bのtest()をオーバーライドしていることになり、
コンパイル可能です。**

# パターン2
```java:Interface_A.java
interface Interface_A{
	void hoge();
}
```
```java:Interface_B.java
interface Interface_B{
	void test();
}
```
```java:Interface_C.java
interface Interface_C extends Interface_A, Interface_B{
	int test();//コンパイルエラー
    int test(int num);//コンパイル可
}
```
+ １つ目はメソッド名が継承したBと同じかつ、戻り値が違う場合です。
<br>**オーバーライドを宣言していますが、戻り値が一致していないので
コンパイルエラーになります。(共変戻り値であればコンパイル可能)**
+ ２つ目は戻り値、引数が違う場合です。
<br>**メソッド名は同じですが、シグニチャが違うためオーバーロード扱いとなり
コンパイル可能です。**

# パターン3
```java:Interface_A.java
interface Interface_A{
	void test();
}
```
```java:Interface_B.java
interface Interface_B{
	void test();
}
```
```java:Interface_C.java
interface Interface_C extends Interface_A, Interface_B{
	void hoge();//コンパイル可
}
```
+ 継承したインターフェースのメソッドを１つもオーバーライドしていない場合です。
<br>**インターフェース、抽象クラスに継承または実装されたインターフェースのメソッドは、
<br>任意での実装となり、実装しなくても実行可能です。**

# パターン4
```java:Interface_A.java
interface Interface_A{
	void hoge();
}
```
```java:Interface_B.java
interface Interface_B{
	void piyo();
}
```
```java:Interface_C.java
interface Interface_C extends Interface_A, Interface_B{
	void fuga();
}
```
```java:Main.java
class Main implements Interface_C{
	@Override
	public void piyo() {}

	@Override
	public void hoge() {}

	@Override
	public int fuga() {}
}
```
+ 多重継承されたインターフェースをクラスに実装する場合です。
<br>**実装するには、継承元全てのメソッドを実装してあげる必要があります。**

# パターン4ex
```java:Interface_A.java
interface Interface_A{
	void hoge();
}
```
```java:Interface_B.java
interface Interface_B{
	void piyo();
}
```
```java:Interface_C.java
interface Interface_C extends Interface_A, Interface_B{
    default void hoge(){}
    default void piyo(){}
	void fuga();
}
```
```java:Main.java
class Main implements Interface_C{
	@Override
	public int fuga() {}
}
```
多重継承したインターフェースが親インターフェースの実装をdefaultにて行っている場合は
継承先での実装は任意となり、エラーにはなりません。

# 終わりに
人生で初めてブログを書いてみました。
アドバイスや質問がありましたら、よろしくお願いします！

Javaの継承関連やコンスタントプール関連は暗記で網羅するより、しっかりと
仕組みを理解することで様々なパターンに対応できるようになります。
私も試験が間近なので、ニアミスを減らすべく細かな仕様を復習していきたいと思います。

# 追記(2021/06/28)
無事、Java Silver SE11を合格しました。
正当率は84％でした。
まだ研修期間が続いていますので、出来ればGoldにも挑戦してみようと思います。

##参考
[参考書：徹底攻略Java](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=12M0J3Z44IVVP&dchild=1&keywords=java+silver&qid=1624416009&sprefix=java+s%2Caps%2C315&sr=8-1　"黒本")
excelでcsvエクスポートし、pandasで読み込む時


## 通常読み込み
通常、csvファイルは以下のコードで読み込みができる。

```python
import pandas as pd

path = "filename"
data = pd.read_csv(path)
```

しかし、excelからエクスポートしてきたcsvファイルを読み込むと

```python
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x95 in position 0: invalid start byte
```
上のようなエラーが出る。

## 解決方法

以下のコードで読み込むことで、解決できます。

```python
import pandas as pd
import codecs


path = "filename"
with codecs.open(path, "r", "Shift-JIS", "ignore") as file:
    data = pd.read_table(file, delimiter=",")
```