OmniAICreator/Qiita-1.07M huggingface dataset:
ARFoundation ボールを平面に衝突させる・反射させる

Sphereを作成し、名前をBallに変更する。サイズを調整する
![880EF088-9A3C-4285-AA85-03E2FB32DCA4_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/f55961da-96f9-cd0e-daa4-8b109946fbcb.jpeg)

BallにRigidbodyをつける
![12149691-A9A3-4EA6-9AC6-7862C29F53D8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/cf6eb640-8d6f-5bda-7ae1-7d00e58c3285.jpeg)

```C#:BallThrower
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BallThrower : MonoBehaviour
{
    [SerializeField]
    private GameObject ballPrefab;
    //ボールの速さ
    float shotSpeed = 10.0f;
    void Update()
    {
        //画面がタッチされたら処理を行う
        if (Input.touchCount > 0)
        {
            //画面タッチの情報を取得する
            Touch touch = Input.GetTouch(0);
            //画面タッチの開始時のみ処理を行う
            if (touch.phase == TouchPhase.Began)
            {
                //ボールを生成する
                GameObject ball = Instantiate(ballPrefab, Camera.main.transform);
                //ボールにカメラ前方への速度を与える
                ball.GetComponent<Rigidbody>().velocity
                = Camera.main.transform.forward * shotSpeed;
            }
        }
    }
}
```


Ballをプレハブ化する。Gameobjectを作成し、名前をBallThrowerに変更し、BallTHrowerスクリプトをつける。Ballプレハブをアタッチする。
![D0B2BD02-CDD8-43AD-8E22-BD0BD9CE0E42_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/aafac7bd-26ff-dc1c-1235-5e60c184c88d.jpeg)

※タッチ操作が被っていたのでRayCastスクリプトのチェックを外した
![E6F9696F-76C3-45C1-BF09-0D76A1AA171E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/3a688d63-1791-0f43-8343-f502ebb0f687.jpeg)

ビルドする
Effective Java(第3版) 項目8 ファイナライザとクリーナーを避ける

ファイナライザ、クリーナは一般には不要なため、使用することを避けるべき、という内容です。

# 記載内容
## クリーナー、ファイナライザ共通
### クリーナー、ファイナライザが実行されるまでの時間は予想できない
実行までの時間的な制約がある処理をクリーナー、ファイナライザで行うべきではない。

例えばファイルのクローズをクリーナー、ファイナライザに頼るべきではない。
クリーナー、ファイナライザの実行が遅れると、オープン可能なファイル数の限界に達し、
新しいファイルのオープンでエラーになる可能性がある。

クリーナー、ファイナライザを実装するよりも、
AutoCloseableを実装し、使用側でtry-with-resourcesを使うべきである。

クリーナーの正当な使い方は二つある。

* クローズを呼び忘れた場合の保険
* ネイティブピアの回収

### クリーナー、ファイナライザの実行は言語仕様上は保証されていない
DBのロック開放の様な、永続的な状態の更新をクリーナー、ファイナライザで行うべきではない。

### パフォーマンスの劣化
クリーナー、ファイナライザを使用した場合、GCに関して深刻なパフォーマンスの劣化が発生する。
著者の環境では
クリーナー、ファイナライザ呼び出しと伴うGC処理は50倍程度、
クリーナを保険として使用している場合でも5倍程度遅くなる。

## ファイナライザ
ファイナライザはJava9より非推奨になっており、使用するべきではない。
ファイナライザはセキュリティ問題を抱えており、悪意のあるサブクラスでファイナライザを実装することで、
不正なオブジェクト参照を取得することが可能になる。
これを防ぐには、クラスをfinalにするか、何もしないfinalのファイナライザを書けば良い。

## クリーナー
クリーナーはファイナライザよりは良いが、動作は予想不可能で遅く、また、一般的には使用する必要はない。
クリーナーのAPIは少々扱いづらいが、クラスのpublicのAPIに影響しない。
例として、AutoCloseableを実装したクラスに対して、
クローズ漏れに対する保険としてクリーナーを使用するのは、問題はない。
ただし、クリーナーが確実に実行されるとは限らない。
System.exitや、通常のプログラム終了に対するクリーナーの動作は実装に依存し、
実行は保証されない。

# 考察
かなり以前から、ファイナライザは使うべきではない、というのが一般的だったと思いますが、
非推奨になっており、明確に使うべきではない、という状態になっています。

ただし、代替となるクリーナーも、セキュリティ以外のファイナライザの欠点である

* 実行タイミングが分からない
* 確実に実行されるとは限らない

はそのままですので、やはり確実な後処理には向かないです。

try-with-resourcesを使い、ファイルのオープンのように、使用上限がある重要な資源であれば、
保険でクリーナーを使用する、程度の使い方にとどまるかと思います。
ただし、GCに関するパフォーマンスの問題がありますので、AutoCloseableなクラス全てで
クリーナーを使う、というのは避けるべきかと思います。
rails Dockerfile docker-compose を別pjから移したときにGemfile.lockが原因で起動しなかった

docker-compose.yml、Dockerfileなどを別プロジェクトから移行してきたときに以下のようなエラーが出て起動できなかった。メモ用に

## エラー

```
$ docker-compose up --build
```
を実行したときに以下のようなエラーが出た

```
app_1  | Bundler::GemNotFound: Could not find gem 'mysql2 (>= 0.4.4)' in any of the gem sources listed in your Gemfile.
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/resolver.rb:287:in `block in verify_gemfile_dependencies_are_found!'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/resolver.rb:255:in `each'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/resolver.rb:255:in `verify_gemfile_dependencies_are_found!'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/resolver.rb:49:in `start'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/resolver.rb:22:in `resolve'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/definition.rb:258:in `resolve'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/definition.rb:170:in `specs'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/definition.rb:237:in `specs_for'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/definition.rb:226:in `requested_specs'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:108:in `block in definition_method'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:20:in `setup'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler.rb:107:in `setup'
app_1  |   /usr/local/lib/ruby/2.6.0/bundler/setup.rb:20:in `<top (required)>'
app_1  |   /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
app_1  |   /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
app_1  | bundler: failed to load command: puma (/webapp/vendor/bundle/ruby/2.6.0/bin/puma)
```

## 解決

Gemfile.lockの中身を削除して再度 `docker-compose up --build`を再度実行。
必要に応じてコンテナ内で`bundle install`を実行する
Svelte-kitでSPAモードを有効にする

## 環境

- svelte-kit: 1.0.0-next.99
- adapter-static: 1.0.0-next.8

## TL;DR

[adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static)を使います。

```javascript

import preprocess from 'svelte-preprocess';
import adapter from '@sveltejs/adapter-static';

/** @type {import('@sveltejs/kit').Config} */
export default {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: preprocess(),

    kit: {
        // hydrate the <div id="svelte"> element in src/app.html
        target: '#svelte',
        adapter: adapter({
            fallback: 'index.html',
        }),
        ssr: false,
    },
};


```

## Svelte-kit

Svelte向けのNext.js的なフレームワークは、これまではSapperなるものが主流だったようですが、Svelte-kitなるものに置き換えようと開発中のようです、今はベータ版という位置付け。

このSvelte-kitはデフォルトだとSSRになる訳ですが、シンプルにSPAでやりたい。しかし出始めだけあって情報がなかなかない。うまくいかなくても仕様なのか不具合なのかわからない（でもそれも面白い）。とりあえずStaticなビルドが出来るようになったのでメモしておきます。

## Svelte-kitのadapter

Svelte-kitにはadapterなる概念があり、ホスティング環境に応じてこのadapterを切り替えてビルドすれば、ソースは変えずに複数の環境に対応出来る、という事らしいです（サーバーに依存するSSRならではの対応でしょうか）。

adapterはVercelやNetlifyなどのホスティングサービスから、単純にNode.jsサーバー向けのものなど様々あり、そのなかに``static``なるadapterがあります。名前のとおり静的ホスティング向けのものです。

## adapter-static

https://github.com/sveltejs/kit/tree/master/packages/adapter-static
フォルダの移動・コピー(UiPath)

#フォルダの移動
例えば下図のように、フォルダごと別の場所に移動させたい場合
![移動1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/b9b97b65-09ec-4636-b41e-a7b31b810ec8.jpeg)
「Move File」アクティビティだと、Fileではないので当然エラーになります。
![移動2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/24eba8eb-8ef3-6be7-ace4-82bc0f4fdf8a.jpeg)
そこで、「Invoke Method」アクティビティを使用します。これを使うことで、フォルダの移動が可能になります。
![移動3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/c001afc9-30dc-76be-20a0-69a31636eecd.jpeg)

なお、この方法だと、移動先は新規フォルダのみとなっています。
既存フォルダに移動しようとするとエラーが発生します。
![移動4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/7e7cc68f-34df-5dc8-4bde-7bc00056393a.jpeg)

#フォルダのコピー
フォルダをコピーしたい(=フォルダを移動元・移動先の両方に残したい)場合、「Invoke Code」アクティビティに
【My.Computer.FileSystem.CopyDirectory("コピー元フォルダパス", "コピー先フォルダパス", True)】
と書けばOKです。
![コピー２.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/0431cc7c-2aee-8916-3c15-3299c78bed93.jpeg)
unityのcolliderによる当たり判定について

まず始めに、本記事の情報はunity開始１週間の人が書いているため間違っている可能性大です。
承知の上でよろしければコメントお願いします。
　
　
Unityでは、BoxColliderとRigidbodyを使ってOnTriggerで当たり判定が簡単にできることを知った。
->じゃぁ2Dと3Dでの当たり判定も同様にできるのか?

試したこと： SquareにBoxCollider2D、CubeにBoxColliderを設定し当たり判定をとる
結果　　　： 無理だった

検索した結果、以下の記事で3DモデルにCollider2Dとその逆を試している。
以下の記事に書かれているが、X軸、Y軸方向に回転させなければ破綻しなさそうなことが分かった。
https://nyama41.hatenablog.com/entry/3d_model_2d_collider
https://nyama41.hatenablog.com/entry/2d_map_3d_collider


ここで新たな疑問、Collider2DはZ軸を変えた場合どうなるのか
まずMainCameraがOrtheographicのとき、破綻していない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1448052/8aff0760-a9cd-d8bd-8875-a285167718ae.png)

次にMainCameraをPerspectiveに設定
Game画面ではあたっているが、当たり判定のログが出ていない。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1448052/7283c94c-4430-63ce-b917-a4a25ed3fbd8.png)
さらにずらしたところ当たり判定が出た
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1448052/4baf5672-f57e-e571-600f-3fdd07074ffa.png)
-> よく考えれば当たり前だが、2Dのときの当たり判定はX/Y軸で決まっているみたい
【GAS】フィルタ後のデータを取得して貼り付け

# 前提
GAS(V8)を使用して、スプレッドシートのフィルタ後のデータを取得。その後、別シートに貼り付けする方法を備忘録として記載。

# 手順

```JavaScript
/**
 * Rawシートの最終列に1がセットされているデータのみを抽出してDupliシート(新規作成)に貼り付ける。
 */
function onlyDupliRaw() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ssRaw = ss.getSheetByName('Raw');

  let lastRow = ssRaw.getLastRow();
  let lastCol = ssRaw.getLastColumn();

  // フィルタを設定
  let rule = SpreadsheetApp.newFilterCriteria()
    .whenNumberEqualTo(1) // 数値1と同値を抽出
    .build();
  ssRaw.getDataRange().createFilter().setColumnFilterCriteria(lastCol, rule);

  /**
   * 「Dupli」シートに「Raw」からフィルタ後のデータを張り付ける。
   */
    ss.insertSheet('Dupli');
    const ssDupli = ss.getSheetByName('Dupli');
    
    let spreadsheetId = ss.getId();
    let sheetId = ssDupli.getSheetId();
    
    // フィルタしたデータを「Dupli」シートにペースト
    let url =
      "https://docs.google.com/spreadsheets/d/" +
      spreadsheetId +
      "/gviz/tq?tqx=out:csv&gid=" +
      sheetId +
      "&access_token=" +
      ScriptApp.getOAuthToken(); // API使用のためのOAuth認証
    let res = UrlFetchApp.fetch(url); // HTTPクライアント用のクラス
    let array = Utilities.parseCsv(res.getContentText()); // CSVテキストを二次元配列で取得
    let lastFilterdCol = array[1].length;
    let lastFilterdRow = array.length;

    // 二次元配列arrayをDupliシートに貼り付け
    ssDupli.getRange(1 ,1 ,lastFilterdRow, lastFilterdCol).setValues(array);

}
```

# 補足
isRowHiddenByFilter(rowPosition)メソッドを使用する方法もあるが、スピードの問題から断念。
https://developers.google.com/apps-script/reference/spreadsheet/sheet#isrowhiddenbyfilterrowposition

手順で紹介した方法が早い。
※logtime測定済み。


# 参考
https://teratail.com/questions/220476
https://gist.github.com/tanaikech/053d3ebbe76fa7c0b5e80ea9d6396011
HTMLのアウトライン意識してますか？(HTML何もわからない)

## HTML5以前は主にH要素によってアウトラインが解釈されていました。

```html
<html>
 <body>
 <!-- アウトライン1 -->
  <h1>大見出し</h1>
   <p>文章</p>
    <!-- アウトライン2 -->
    <h2>中見出し</h2>
    <p>文章</p>
     <!-- アウトライン3 -->
     <h3>小見出し</h3>
     <p>文章</p>
     <!-- /アウトライン3 -->
    <!-- /アウトライン2 -->
 <!-- /アウトライン1 -->
 </body>
</html>
```

```
大見出し
L中見出し
 L小見出し
```
## セクショナブル要素によってコーダーが明示的にアウトラインをさ指定できるのでHTML5.0ではセクショニング要素によって明示的にセクショニングがなされれば以下の様にすべてH１でのマークアップが可能になりました。

```html
<html>
 <body>
  <!-- アウトライン1 -->
  <h1>大見出し</h1>
   <p>文章</p>
    <section>
    <!-- アウトライン2 -->
    <h1>中見出し</h1>
    <p>文章</p>
     <section>
     <!-- アウトライン3 -->
     <h1>小見出し</h1>
     <p>文章</p>
     <!-- /アウトライン3 -->
     </section>
    <!-- /アウトライン2 -->
    </section>
   <!-- /アウトライン1 -->
 </body>
</html>
```

### しかし、HTML5.1以降は上のようなマークアップは推奨されず、アウトラインに従ったHeading要素でのマークアップになりました。

```html
<html>
 <body>
  <!-- アウトライン1 -->
  <h1>大見出し</h1>
   <p>文章</p>
    <section>
    <!-- アウトライン2 -->
    <h2>中見出し</h2>
    <p>文章</p>
     <section>
     <!-- アウトライン3 -->
     <h3>小見出し</h3>
     <p>文章</p>
     <!-- /アウトライン3 -->
     </section>
    <!-- /アウトライン2 -->
    </section>
   <!-- /アウトライン1 -->
 </body>
</html>
```

セクショナブル要素は以下の要素です

- body
- nav
- article
- section
- aside
- header
- footer

見出しがあればアウトラインができ、アウトラインがあれば基本的に見出しがあるのが基本です。

## よくある間違い１（セクションに見出しがないよ？）

```html
<!-- 誤 -->
<h1>見出し</h1>
<section>
<p>文章文章</p>
</section>

```


## よくある間違い２（セクショニング要素の無駄な入れ子）
body要素はセクショニング要素です
誤

```html
<!-- 誤 -->
<body>
 <article>
  <h1>見出し</h1>
  <p>文章文章</p>
 </article>
</body>

```

### と、言うのが私のHTML5の大体の認識でした。
が、
nav要素もセクショニング要素ですが、厳格にアウトラインを意識すれば見出しを付ける必要があるとおもいますが、いちいち見出しを用意できない場合もあると思います。また、header要素もセクショニング要素ですが、扱いが微妙なケースがあります。
それでHTML5.2の仕様についてちょっと調べていたのですが、例として出てくるマークアップが、アウトライン構造が微妙なものが数多く出ていました。

いよいよ、私は、
「HTML何もわからない」状態になりました。

そういう時に見るべきは公式ドキュメントです。
公式のドキュメントはこちらです。


>There are currently no known native implementations of the outline algorithm in graphical browsers or assistive technology user agents, although the algorithm is implemented in other software such as conformance checkers and browser extensions. Therefore the outline algorithm cannot be relied upon to convey document structure to users. Authors should use heading rank (h1-h6) to convey document structure.
> https://www.w3.org/TR/html52/sections.html#headings-and-sections

要するに、

「アウトラインのアルゴリズムはこれといって決まってるものはないからあまり信用できんのだよ。だからセクショニング要素に頼らず、アウトライン構造はH要素で作ってね！」
ということだろうか？

<b>なんじゃそりゃ！</b>

まあ、アウトライン？ナニソレオイシイノ？状態でマークアップするよりも、ここまで知った上でアークアップしたほうが良いマークアップになることは確かなようです。
Macのターミナルで％(zhs)から＄(bash)に変更

プログラミング初心者です
##問題

初めてMacのターミナルを開いたら

```
Last login: Wed May  5 23:27:11 on ttys000
***@***************** ~ % 
```

"$"じゃないの？　と思っているところが"%"になっていました

・調べてみるとシェルを変更しなければなりません（Mac OS Catalina以降設定がzashらしいです）
・"%"の人はzhsっていうやつ、 "$"にするのはbashっていうやつに変更します
・システム環境設定でも変更できるみたいなんですが、アカウントが壊れる可能性があるので、ターミナル上で変更します
##解決方法

1 bashなのかzshなのか確認

```
$ echo $SHELL
```
2 変更可能なシェルを確認

```
$ cat /etc/shells
```
3 シェルの変更

```
$ chsh -s /bin/bash
```
4 鍵マークのパスワード入力（打っても鍵マークが動かないが、入力できていてenter押せばOK）
5 再起動

で自分は変更できました
テリトリー管理のベストプラクティス ⇒ 商談へのテリトリーの割り当て

１．ユーザが商談にテリトリーを手動で割り当てられるようにするには、Salesforce システム管理者は何を行う必要がありますか?
２．検索条件に基づく商談テリトリー割り当ては、どのように機能しますか?
３．検索条件に基づく商談テリトリー割り当ては、どのように実行しますか?
４．検索条件に基づくテリトリー割り当てからの手動による除外は、どのように設定しますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/f8151710-8c5d-0b9f-e1c7-93aec0c55d58.png)
mpdの音楽ディレクトリをサーバのディレクトリを対象とする

# 概要
自宅の音楽再生環境にラズパイ4Bに[mpd](https://www.musicpd.org/)をインストールして使用しているが、
ディスク容量の兼ね合いでサーバ上のディレクトリを対象としたい場合がある。
調べてもあまり出てこなかったので備忘録として記載

## 環境
- OS
    - Raspbian GNU/Linux 10 (buster)
- mpd
    - 0.21.5

## 設定方法
- smbで設定する場合、下記の書式でmusic_directoryを記載する
    - `smb://{サーバ名}/{共有フォルダ}`
    - 設定例：
        - music_directory                 "smb://server.local/Music"

## 注意事項
- 公式ドキュメント上、mpdをクラッシュさせる下記のバグがある為、基本的には使用しないでほしいと記載有。
    - https://bugzilla.samba.org/show_bug.cgi?id=11413
- 使用する場合は、自己責任で。

## 参考資料
- [User’s Manual](https://www.musicpd.org/doc/html/user.html)
- [Plugin reference](https://www.musicpd.org/doc/html/plugins.html)
バッチファイルで7z圧縮する（7zipを使用）

Y子です。
今日は、ファイルを7z形式に圧縮してみます。
細かい仕様は、[Zip圧縮のとき](https://qiita.com/koiwaiwaiko/items/516c55bf4f8aeade5eb7 "バッチファイルでzip圧縮する（PowerShellを使用）")を踏襲します。

# 概要
7zipを使って、7z形式に圧縮します。
自動処理の中で使用することを想定します。
7zipの実行ファイルは、通常インストールで配置される`C:\Program Files\7-Zip\7z.exe`を使っています。
_【[確認環境：Windows 10 Home (Bld. 19042.928)](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698 "Windows10のバージョンを確認・表記する")】_

# コード
## (1) 1ファイルを圧縮する

```bat:7zip_compress_s2s.bat
@echo off
setlocal

set exe="C:\Program Files\7-Zip\7z.exe"

rem 引数がない場合は終了する
if "%~1"=="" (echo 引数がありません & pause & exit /b)

rem 圧縮前ファイル
set str_file=%~1

rem 圧縮後ファイル
set str_zipfile=%str_file%.7z

rem zip圧縮実行
call %exe% a "%str_zipfile%" "%str_file%"
echo %str_zipfile%

endlocal
pause
```

```:実行結果
> 7zip_compress_s2s.bat "C:\work dir\test01.txt"
7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21

Scanning the drive:
1 file, 1890 bytes (2 KiB)

Creating archive: C:\work dir\test01.txt.7z

Add new data to archive: 1 file, 1890 bytes (2 KiB)


Files read from disk: 1
Archive size: 165 bytes (1 KiB)
Everything is Ok
C:\work dir\test01.txt.7z
続行するには何かキーを押してください . . .
```

## (2)複数ファイルをひとつに圧縮する

```bat:7zip_compress_m2s.bat
@echo off
setlocal

set exe="C:\Program Files\7-Zip\7z.exe"

rem 日付「20210402」形式
set str_date=%date:~0,4%%date:~5,2%%date:~8%

rem 時刻「094617」形式
set str_time=%time: =0%
set str_time=%str_time:~0,2%%str_time:~3,2%%str_time:~6,2%

rem 圧縮前ファイル(初期化)
set str_file=

rem 圧縮後ファイル
set str_zipfile=%~dp1
set str_zipfile=%str_zipfile%7zfile_%str_date%_%str_time%.7z

rem 引数がない場合は最後に飛んで終了する
if "%~1"=="" (
  goto :label_end
)

rem zip圧縮実行
call %exe% a "%str_zipfile%" %*
echo %str_zipfile%

:label_end
echo 処理を終了しました
endlocal
pause
```

```:実行結果
> 7zip_compress_m2s.bat "C:\work dir\dir1" "C:\work dir\test01.txt" "C:\work dir\test02.txt"

7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21

Scanning the drive:
1 folder, 4 files, 10425 bytes (11 KiB)

Creating archive: C:\work dir\7zfile_20210505_234727.7z

Add new data to archive: 1 folder, 4 files, 10425 bytes (11 KiB)


Files read from disk: 4
Archive size: 5025 bytes (5 KiB)
Everything is Ok
C:\work dir\7zfile_20210505_234727.7z
処理を終了しました
続行するには何かキーを押してください . . .
```

# おわりに
7zipは、zipより圧縮率が高く、アプリとしても完成度が高いので、半ば標準化している感じがしますね。
パスワード付きや自動解凍書庫も、そのうちバッチ化してみたいです。

では！
docker-composeを使ってwordpress を動かす

# はじめに

Wordpressを簡単に動かせたので、メモ。昔、Wordpressを動かすサーバを用意する係になって、古いPCに苦労しながらいろいろインストールして苦労した気が。。。時代は変わり、先ほど、とても簡単にできました。のでメモ。

元ネタは、Docker-compose のquick start です。

https://docs.docker.jp/compose/wordpress.html

環境はWSL2(Windows Subsystem Linux2)です。これまでdocker はインストールされていることが前提です。

https://qiita.com/XPT60/items/ef9fbe82127b5b559b44

# 作業内容

### docker-composeのインストール

ダウンロードして/usr/local/bin/に配置するだけ。

```
登$ sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
[sudo] password for user:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   633  100   633    0     0   2035      0 --:--:-- --:--:-- --:--:--  2035
100 8648k  100 8648k    0     0  5181k      0  0:00:01  0:00:01 --:--:-- 8009k
$ docker-compose --version
docker-compose version 1.16.1, build 6d1ac21
```

### docker-compose の設定ファイルを用意して実行

解説にある通りに、docker-compose.yml を用意する。
データベースのために、volume mount をもったインスタンスを作っているところがポイントらしい。以下、quick start のファイルのコピペです。

```yml:docker-compose.yml
version: '3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
```

### 起動

```
$ docker-compose up -d
```

全て良しなに取り計らってくれて、http://localhost:8000 をブラウザで開いたら、Wordpressが普通に動いていました。めでたしめでたし。pullとかもしていません。

```
$ docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                   NAMES
fbd36b54cdaf   wordpress:latest   "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   0.0.0.0:8000->80/tcp, :::8000->80/tcp   mywordpress_wordpress_1
2ba8c5ed60f0   mysql:5.7          "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   3306/tcp, 33060/tcp                     mywordpress_db_1
```

# おわりに

ここではquick start の動作をなぞっただけだが、時間があればcloud にdeployするところまでやりたかった。あとquick start には Djangoとかあったので、そちらをやるべきだった。

(2021/05/05)
Leafletで、GPSログ(GPX)を地図に表示する。Google マップ、OpenStreetMapなど。

Leafletで、GPSログ(GPX)を地図に表示を試した。

詳細は、以下。
https://2ndart.hatenablog.com/entry/2021/05/05/232759
![20210505230012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374794/890ba2c9-ef21-06f2-99dc-82b9baa28f61.jpeg)
PHP変数の埋め込みかた

# PHP変数の埋め込み方

PHPの文字列に変数を埋め込みたい時はダブルクォーテーションを使います。

```php
<?php
    $a = 1;
      
    echo "{$a}回目です。";
  ?>
```

文字列をシングルクォーテーションで囲むとエラーになりますのでご注意ください。
PyTorchのCrossEntropyLossクラスについて

# はじめに
シングルラベルタスクにおける損失関数としてよく用いられる交差エントロピーですが、`PyTorch`の実装クラスの挙動がややわかりにくいものだったため苦労しました。備忘録を兼ねて記事を書きます。

# 交差エントロピーとは
主にシングルクラスラベルで用いられる損失関数で、以下の数式で定義されます（[PyTorchの公式リファレンス](https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html)）。

```math
loss(x, class) = -log(\frac{exp(x[class])}{\sum_j exp(x[j])}) = -x[class] + log(\sum_j exp(x[j]))
```

交差エントロピー自体の説明については、[この記事](https://qiita.com/kenta1984/items/59a9ef1788e6934fd962)がわかりやすいです。GLUEタスクに代表されるようなシングルラベルタスクにおいては、この交差エントロピー関数を用いると損失が上手に収束して高い精度が達成されます。

# `PyTorch`の`CrossEntropyLoss`クラスについて

`PyTorch`には、`nn`モジュールの中に交差エントロピーの損失関数が用意されています。[PyTorchの公式リファレンス](https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html)によると、使い方は以下の通りです。

```python:PyTorchの公式リファレンスより
>>> from torch import nn
>>> import torch
>>>
>>> loss = nn.CrossEntropyLoss()
>>> input = torch.randn(3, 5, requires_grad=True)
>>> target = torch.empty(3, dtype=torch.long).random_(5)
>>> output = loss(input, target)
>>> output.backward()
```

## ターゲット変数の型について

上述のコードにおいて、入力変数である`input`の型は`Logits`をシグモイド関数に通したものであるため、`float`型と考えて問題ないかと思います。他方、ターゲット変数である`target`の型は`int`型で、変数のインデックスが`1.0`になっているone-hotベクトルがターゲット変数として設定されるようです。つまり、`torch.tensor(0)`は`torch.tensor([1., 0.])`と扱われるようです。

```python:
>>> from torch import nn
>>> import torch
>>>
>>> loss = nn.CrossEntropyLoss()
>>> input = torch.tensor([0.8, 0.1, 0.1]).unsqueeze(0)
>>> target = torch.tensor(0).unsqueeze(0)
>>> output = loss(input, target)
>>> output
tensor(0.6897)
```

`CrossEntropyLoss`クラスの内部で、整数インデックスからone-hotベクトルが生成されているとは思いもよらなかったため、Huggingface inc.のコードを解読している時にハマってしまいました。
他方、マルチラベルタスクで用いられる`BCEWithLogitsLoss`というクラスでは、ターゲット変数に`float`型のmulti-hot型ベクトルを入力する必要があるようです。

# 参考文献

- [PyTorchの公式リファレンス](https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html)
- [交差エントロピー誤差をわかりやすく説明してみる](https://qiita.com/kenta1984/items/59a9ef1788e6934fd962)
配列構文で２つのstyleを適用させる


【１】文章内の標準フォントサイズ　６０px
【２】文字赤背景色青

この２つを配列で適応さえる。

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :style="[styleObject, baseStyles]">HELLO<h1>
</div>
```

```vuejs
  new Vue({
    el: '#app',
    data: {
      styleObject: {
        color: 'red',
        'background-color': 'blue'
        },
      baseStyles: {
      fontSize: '60px'
        }
      }
  })
```

![20210505-231537.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/a643e4f1-c1c7-0ed4-776c-6be895eae95a.png)
機械学習の学習完了をslackに通知したい

## はじめに
機械学習って学習時間長くないですか？
いつ終わるんだろうとか、クラウドの場合は、終了時間を覚えておかないとインスタンスの時間かかって高額の使用量が請求されてしまうなんてこともあると思います。(経験談)

そこで、今回は学習結果と、完了通知をslackに通知します。

## 1. Incoming webhookの利用
まずは、slackとアプリの連携を行いましょう。
Incoming webhookというAPIを使用します。
先人の方がとても細かくまとめてくださっているのでこちらを参考にしました。
そのため、Incomingwebhookの登録方法は省きます。

https://qiita.com/kshibata101/items/0e13c420080a993c5d16

## 2. サンプルコード
こちらです。

```python:notificaton.py
import slackweb
slack = slackweb.Slack(url="Your IncomigWebhooks URL")
slack.notify(text="通知したい文字")
```

## 3．使用方法
学習するモジュール上に先ほどのコードを埋め込みます。
以下はpytorchを想定しています。

```python:train.py
import slackweb
slack = slackweb.Slack(url="Your IncomigWebhooks URL")

def run_training():
    #省略
    for epoch in range(Config.EPOCHS):
        loss, acc = train_fn(model, trainloader, optimizer, scheduler, epoch) 
        torch.save(model.state_dict(),'modelname_epoch.pt')
    slack.notify(text="学習が完了しました")
```

関数化して、リンク先のボタンを追加したコードはこちら。

https://github.com/mizoo-snow21/LearningNotification/blob/main/notification.py

## おわり
いかがでしたでしょうか？
非常に簡単に学習完了通知ができるので、皆さんも是非試してみてください。
よい機械学習ライフを！！
ユーザ登録機能の実装（deviseを使用して説明）インストールからdb作成まで

##はじめに##
deviseを用いてユーザ登録の実装について書かせて頂きます。
自分でもまだまだ理解不十分な所もあるのでアウトプットできればと思います。

##ログイン機能の実装##
TwitterやInstagram、メルカリなど多くのウェブサイトにはログイン機能があります。
ユーザに対してアカウントを作り、ユーザを管理する機能です。

それではまずdeviseのインストールから始めます。

##deviseのインストール##
ログイン機能を実装するにはまず**devise**という**gem**をインストールします。

deviseとはユーザー管理機能を簡単に実装するためのgemの事です。
gemってなんぞや？となるかもしれませんが、今回は割愛させて頂きます。🙇‍♂️

それではインストールします。
GemfileはRailsアプリで利用するgemの一覧を管理するファイルです。
様々な記述がされているのでまずは一番最後の行に記述しましょう。

```Gemfile.
gem 'devise'
```
この時シングルクォーテーション忘れずに記述します。
記述し終えたらターミナルでコマンドを実行します。

```ターミナル.
bundle install
```
これでインストールし終えました。
一旦サーバーを起動させます。理由はインストールしたGemの反映するタイミングが、サーバー起動時だからです。

```ターミナル.
rails s
```
インストールできたかはGemfile.lockで確認できます。
(gemfileのレシートようなものと考えております。)

##devise設定ファイルを作成##
下記のコマンドを実行しましょう。
これは「設定関連に使用するファイル」を自動で生成するコマンドです。

```ターミナル.
rails g devise:install
```

##deviseのUserモデルを作成##
deviseを利用する際には、アカウントを作成するためのUserモデルを新しく作成する必要があります。
作成には通常のモデルの作成方法ではなく、deviseのモデル作成用コマンドでUserモデルを作成します。

アカウントを作成するためのUserモデルを作ります。この中にはアカウント名やemail、passwordなどのデータが入ります。
deviseモデルの作成は通常とはやり方ではありません。

```.rb
#通常のモデル作成の場合(モデル名をuserとする)
rails g model user

#deviseのuserモデル作成の場合
rails d devise user
```
このコマンドでユーザーに関する、モデルやマイグレーション、ルーティングも自動生成されています。

```routes.rb
Rails.application.routes.draw do
  devise_for :users #この行が追加されました
  root to: 'items#index'
end
```

##テーブルの作成##
すでに自動生成されているマイグレーションファイルに内容を記述し、テーブルを作成します。

```db/migrate/20XXXXXXXXX_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

     ##省略


      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end
```
このような感じでマイグレーションファイルがあるかと思います。
5,6行目に注目してください。

```db/migrate/20XXXXXXXXX_devise_create_users.rb
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.string :nickname,           null: false #ニックネームを追加しました 
      t.date   :birth_day,          null: false #誕生日を追加しました
```
デフォルトでメールアドレスとパスワードはあります。
他に名前や誕生日などを追加していく事も可能です。

テーブルが設計できたのでマイグレーションを実行します。

```
rails g migrate
```

| id         | email       | encrypted_password | nickname | birth_day |
|:-----------|------------:|:------------------:|:--------:|:---------:|
|            |             |                    |          |           |

このようなdbが完成しました。
【Css】@keyframesを使ってfade inアニメーションを作ってみた

# 初めに
Cssの@keyframesを使って理解した内容をもとにfade inアニメーションを作ってみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

# 結果物
clickボタンをクリックすると画像がfade inの状態で現れ、再度クリックすると画像が消える。

# htmlを用意する
keyframes_mainというdiv要素の中にkeyframesというid名のimgタグを用意します。画像を表示する予定なので、styleにwidth:300px;を指定しておきます。また、ボタンをクリックした時に、src属性を付与したり外したりするための処理を行うために、同じフォルダ内にkeyframes.jsというjavascriptファイルを配置します。そしてcssはtest.cssという名前のファイルを作成します。

```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="test.css">
  <title>keyframes</title>
</head>

<body>

  <section class="keyframes_section">
    <div class="keyframes_main"><img id="keyframes" style="width:300px;"></div>
  </section>

  <button class="click_button">Click</button>
  <script src="keyframes.js"></script>

</body>

</html>
```

# javascriptファイルの記述
clickボタンをクリックした時に、imgタグのsrc属性に同じフォルダの直下にあるimage.jpgファイルを指定したり、外したりする処理をします。imgタグをgetElementByIdで取得し、src属性がなかった場合はsrc属性にimage.jpgを付け、src属性がある場合にはsrc属性とimageファイルを外します。なた、属性を外す時に画面をリロードし初期化します。

```javascript
"use strict";

const clickButton = document.querySelector(".click_button");
clickButton.addEventListener("click", () => {
  const image = "image.jpg";
  const target = document.getElementById("keyframes");
  if (target.src === "") {
    target.setAttribute("src", image);
  } else {
    target.removeAttribute("src", image);
    location.reload();
  }
});

```

# cssの記述

まず、fadeImgという名前の@keyframesを作成します。0%(初期の状態）にopacityを0にして透明にし、100%（アニメ終了の状態）に向けてopacityを1にして透明だったイメージが現れるようにします。id名がkeyframesのimgタグにanimationと書いてアニメーションを適用します。:の後に先ほど作成したkeyframe名fadeImgを記述し、5sと書いてアニメーションがスタートして終わるまで5秒掛かるように指定します。

```css
.click_button {
  position: absolute;
  right: calc(100% - 380px);
  top: 30px;
}

#keyframes {
  animation: fadeImg 5s;
}

@keyframes fadeImg {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
```

#実行結果
clickボタンをクリックしたら、薄かった花が徐々に現れました。もう一度clickボタンをクリックすれば画像が消えます。

①クリックした直後
![スクリーンショット 2021-05-05 23.01.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/7ec35c31-f7e2-ddcb-38d6-42e2b2444c48.png)
②クリックして2秒後
![スクリーンショット 2021-05-05 23.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/ab378b91-a54d-2c37-eb4c-53a049f5491a.png)
③5秒後の画面
![スクリーンショット 2021-05-05 23.01.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/33739741-7379-8864-998c-5c108c9c66ef.png)


#参考サイト
https://qiita.com/7968/items/1d999354e00db53bcbd8
JDLA_E資格の情報理論

# 自己情報量

情報量は以下のように表現できる。

情報量とは、希少であればあるほど大きくなる。

~~~math
自己情報量 I(x) = -log (P(x)) = log(W(x))\\
自己情報量 I(x) = -log_2 (P(x)) = log_2(W(x)) [bit]\\
自己情報量 I(x) = -log_e (P(x)) = log_e(W(x)) [nat]\\
~~~

# シャノンエントロピー

自己情報量の期待値を表すものがシャノンエントロピーという。
機械学習の際に、シャノンエントロピーが最大になるような値をさがさせるための誤差関数として使うことも可能。

~~~math
シャノンエントロピーH(x) = E(I(x))\\
=-E(log(P(x))\\
=- \sum ( P(x) log(P(x))) \\
~~~

# カルバック・ライブラー　ダイバージェンス

同じ事象、同じ確率変数のはずなのに、実際には違う確率分布を表す２つの事象P、Qがあったとする。この違いを表す手法が、カルバック・ライブラー　ダイバージェンスである。

ダイバージェンスとは、距離という意味あいである。二つの事象の性質としての違いを距離のイメージとしている。

事象P：佐藤さんが１０回コイントスした時の結果（表か裏）
事象Q：田中さんが１０回コイントスした時の結果（何故か毎回表）


~~~math
D_{KL} (P || Q) = E_{x～P} \Biggl[ log \frac{P(x)}{Q(x)}  \Biggr] \\
=E_{x～P} \biggl[ log P(x) - log Q(x) \biggr] \\
= \sum_x P(x)  ( -log(Q(x))) - ( -log(P(x))) \\
= \sum_x P(x) log \frac{P(x)}{Q(x)}
~~~

シャノンエントロピーの形に似ている。

#　交差エントロピー

交差エントロピーは、教師有学習の際に真の確率分布と推定した確率分布の間の誤差関数として使われる。カルバック・ライブラー　ダイバージェンスを利用して、２つの事象の距離が短ければ、上手く推定が出来ているという見方になる。

~~~math
H(P,Q) = H(P) + D_{KL} (P||Q) \\
H(P,Q) = -E_{x～P} log Q(x) = - \sum_x P(x) log Q(x) \\
※H(P) はPのシャノンエントロピー
~~~
Firebase Storageへのグループアクセス制御

# 要件

- Firebase Storageにアップロードされたファイルへのアクセスを特定のグループに限定したい

**条件**

- ユーザは所属グループにファイルを投稿(Firebase Storageにアップロード)
- グループの内部の人間のみが投稿したファイルにアクセス可能
- 所属するグループは同時に複数
- 所属グループは頻繁に変わる

# FirebaseのSecurity Rule

残念ながらFirebase StorageのSecurity RuleはFirestoreのそれに比べるとできることが非常に少ない。Firestoreの場合、Security Ruleからユーザの所属グループやロールを管理したデータベースにアクセスしてその内容と照会することで、柔軟な制御が可能であった。StorageのSecurity RuleからFirestoreにアクセスはできない。

# 解決法

## 1. User Claims

request.auth.token.xxx に任意の情報を付加するCustom Claimsという仕組みがある。adminから追加ができるため、functions等で、ユーザがグループに所属した段階でUser Claims情報(所属グループIDなど)を設定し、Firbase StorgeのSecurity Ruleでそれを参照することで所属グループを信頼性を持って確認できる。

ただ、

- Custom Claimsは反映までに時間がかかる(即時反映ではない). 
- 1000Byteまで
- 頻繁に書き換わる権限に対してCustom Claimsを使うべきでないと中の人も言っている

今回の用途には合わない。

## 2. Metadata

Storage上のファイルには、任意のメタデータを付加することができる。Metadata にアクセスできるユーザの一覧をメタデータに格納して、requst.auth.uidがmetadataに含まれているか確認する

ユーザがグループにJoin/Leave 毎に全ファイルのメタデータを書き換え、全メンバのIDを追加する必要がある。今回の用途では現実的ではない。

## 3. パス自体を推測不可能なものにする

Storageではgetはallow, list操作はdenyすることができる([Security rule version '2'から](https://firebase.google.com/docs/storage/web/list-files)) ため、パスが十分に推測不可能な場合には、パスを知らない人間には実質 read不可 となる。グループに属するユーザにのみパスを配布（FirestoreとそのSeurity Ruleでセキュアに可能）することで実現ができる。

ただし、ユーザがグループを脱退した場合、その時点で存在したファイルには脱退後も引き続きアクセスできてしまう(パスを知っているから)。この条件が許容できる場合のみ適用可能。

**パスの生成/アップロード**

**Option 1 : クライアントでパス生成&アップロード**

一番、帯域・時間がかからない。パス生成はUUID生成ライブラリ等を使う。但し「クライアントは信頼できない」が基本であり、悪意のあるパス、バカチンなパスを生成するクライアントがいる場合を考える必要あり。

**Option 2 : サーバサイドでパス生成＆アップロード**

Functions等をかましてサーバでパス生成アップロードまで含めて実施する。
最もセキュアな気がするが、1 Callで扱えるのは[10MB](https://firebase.google.com/docs/functions/quotas?hl=ja)までのファイルとなる上、ファイルはクライアント→Function->Storageという経路を辿るため、アップロード量が2倍となるため時間がかかる。

**Option 3 : サーバサイドでパス生成、アップロードはクライアント**

サーバサイドで生成したパスを無視するバカチンがいる可能性もある。その意味でOption 1と変わらない。

**Option 4 : サーバサイドでパス生成、アップロードはクライアント, サーバサイドで生成したパスにしかアップロードできない制限付加**

Firebase storageではファイルの上書きが可能である。上書きされた場合、metadataのupdatedフィールドがtrueになるようである。そこで思いつくのが、以下の方法。

- サーバサイドでURL生成
- サーバサイドでURLに対してダミーの小さなファイルをアップロードする
- Security Ruleは metadata.updated == falseの場合のみwrite属性をつける (サーバサイドは特権あるので最初のアップロードも可能). metada.updatedは書き換えできないものなので安全。



## まとめ
「アクセス制御されている」と言い切れない部分があるため、何となく気持ち悪いが、今回の用途では 3. しか選択肢がない。

StorageのSecurity Ruleをもう少し細かく設定できるようにして欲しい。
[Unity] Inspector上でVector3の各成分を(0,1)に制限する


Unityでプロパティの範囲を(0,1)に制限しておきたいとき、floatまたはint値であれば

```
[SerializeField, Range(0f,1f)] float hoge;
```
のようにすることで値を0から1の間に制限することができます。
Vector2/3で同様に
```
[SerializeField, Range(0f,1f)] Vector3 hoge;
```
とすると、Inspector上で ```Use Range with float or int.``` と怒られてしまいます。

そこで、下記のスクリプトを用意し、

```UserAttribute.cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class Clamp01VectorAttribute : PropertyAttribute { }

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(Clamp01VectorAttribute))]
public class Clamp01VectorDrawer : PropertyDrawer
{
    // Necessary since some properties tend to collapse smaller than their content
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return EditorGUI.GetPropertyHeight(property, label, true);
    }

    // Draw a disabled property field
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        switch (property.type)
        {
            case "Vector2":
                property.vector2Value = new Vector2(
                    Mathf.Clamp01(property.vector2Value.x),
                    Mathf.Clamp01(property.vector2Value.y)
                );
                break;
            case "Vector3":
                property.vector3Value = new Vector3(
                    Mathf.Clamp01(property.vector3Value.x),
                    Mathf.Clamp01(property.vector3Value.y),
                    Mathf.Clamp01(property.vector3Value.z)
                );
                break;
        }
        EditorGUI.PropertyField(position, property, label, true);
    }
}
#endif
```

これを適当な場所に保存してから

```
[SerializeField, Clamp01Vector] Vector2 hogeVec = new Vector2(0.5f,1f);
```
のように記述すると、インスペクター上からは(0,1)の範囲しか入力できなくなります。
(0,1)ではなく(min,max)にするには[こちら](https://qiita.com/ELIXIR/items/5e4151f020bec7e1d814)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/6d8a7da5-ee63-588b-8317-7d4af38d462b.png)

余談ですが、エディター拡張をEditorフォルダ外に置く今回のような方法、いろんな記事でちょこちょこ見ていたので今回自分もやってみたのですが、普通にビルドも通りますね。いまさら？
setlockしたプロセスを自動で開放したい話

## はじめに

`cron`でPythonプロセスの自動起動を実装していたときのこと。
定期的にプロセスが止まっていないか確認しつつ、多重起動は防止するような仕組みを以下のように実装しました。

```sh
#!/bin/sh
* * * * * setlock -xn /hoge/huga/locklock.lock /usr/bin/python3 /hoge/huga/pypy.py >> /hoge/huga/loglog.log 2>&1
```

## 問題発生

ところがここで起こった問題が一つ。

`/hoge/huga/pypy.py`が更新される度にプロセスを再起動させたかったのですが、丁度その時にプロセスが起動中だった場合、`/hoge/huga/locklock.lock`はロックされたままなので再起動ができません。

この時、私が起動させていたPythonプログラムは無限ループで起動し続けるプログラムだったので、`/hoge/huga/locklock.lock`のロックに阻まれて再起動ができない！というような状況に陥りました。

## 解決策

再起動前にこんな感じのシェルを実行させることで解決しました。

```sh
$ lslocks | grep /hoge/huga/locklock.lock | awk '{ print "kill -9", $2 }' | sh
```

## 解説

していることは簡単で、以下のような感じです。

#### 1. `lslocks`でロックされているファイルを一覧表示

```sh
$ lslocks

# 出力
# COMMAND           PID  TYPE SIZE MODE  M START END PATH
# ...
# (unknown)        1234 FLOCK      WRITE 0     0   0 /run...
# cron             3932 FLOCK   5B WRITE 0     0   0 /run/crond.pid
# python3          5432 FLOCK      WRITE 0     0   0 /hoge/huga/locklock.lock
# ...
```

#### 2. `grep`で対象のファイルの行を抽出

```sh
$ lslocks | grep /hoge/huga/locklock.lock

# 出力
# python3          5432 FLOCK      WRITE 0     0   0 /hoge/huga/locklock.lock
```

#### 3. `awk`で対象のファイルをロックしているプロセスを削除するコマンドを生成
```sh
$ lslocks | grep /hoge/huga/locklock.lock | awk '{ print "kill -9", $2 }'

# 出力
# kill -9 5432
```

#### 4. `sh`で実行

```sh
$ lslocks | grep /hoge/huga/locklock.lock | awk '{ print "kill -9", $2 }' | sh
```

## おわりに

書くことが思いつかなかったので解決策のシェルを再掲しておきます。

```sh
$ lslocks | grep /hoge/huga/locklock.lock | awk '{ print "kill -9", $2 }' | sh
```
Markdown 書き方Memo

# Markdown記法について
様々なところで使用できる『マークダウン』とは、タイトル・見出しなどの協調や文字の装飾が簡単にできる記法のこと。
「見出し」「段落」「改行」などの構造があることによって文章が読みやすくなり、内容や要件が伝わりやすくなる。

## 書き方１：見出し（タイトルなど）
文頭に**半角シャープ**をつける（※例は全角です）
【 例 】
＃ 大見出し　
＃＃ 中見出し
＃＃＃ 小見出し

【 表示 】![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447486/461ef663-f138-0b13-7b62-4735d281462a.png)

## 書き方２：太文字
太字にしたい文字を**アスタリスク2つ**で囲む（※例は全角です）

【  例  】ここから＊＊太文字＊＊
【 表示 】ここから**太文字**

## 書き方３：打ち消し線
打ち消したい文字を**半角スペース又は改行 ＋ 半角波（~）**で囲む（※例は全角です）

【  例  】ここから　～～打ち消し～～
【 表示 】ここから ~~打消し~~

## 書き方４：箇条書きリスト・番号付きリスト
箇条書きリストは、文頭に**半角アスタリスク ＋ 半角スペース**をつける（※例は全角です）
※箇条下記の一行上は**空白行**をいれておく

【 例 】
＊箇条書き1
＊箇条書き2

【 表示 】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447486/8eee2881-67e8-bea8-e383-1732806364d1.png)

番号付きリストは、文頭に**半角数字 ＋ 半角ドット ＋ 半角スペース**をつける（※例は全角です）
※箇条下記の一行上は**空白行**をいれておく
※後から追加した項目が自動配番されるように、**すべて1.にしておく**

【 例 】
１．　箇条書き1
１．　箇条書き2

【 表示 】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447486/e01db68e-23e6-f2be-01bc-83fa2c05e801.png)

## コード

* 文頭と文末に **バッククオート3つ**
* １行目に **言語 ＋ 半角コロン ＋ ファイル名**
* 上下に **空白行**

【 例 】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447486/df3bf7d2-fc15-17d6-bc2e-9b3fbfd72e54.png)

【 表示 】

```python:manage.py
def main():
  """処理の内容"""
```
gym-super-mario-brosをインストールして動かした際の備忘録

# gym-super-mario-brosのURL
[https://pypi.org/project/gym-super-mario-bros/](https://pypi.org/project/gym-super-mario-bros/)

# インストール

```
pip3 install gym-super-mario-bros
```

# ユーザ操作による実行

```
gym_super_mario_bros -m human
```

# ユーザ操作時のコマンド

```
A 左
D 右
S しゃがむ
O ジャンプ
P ファイヤー（ファイヤマリオの時だけ）
```

# ランダム移動

```
gym_super_mario_bros -m random
```

# ステージ指定（4-2の場合）

```
gym_super_mario_bros -e SuperMarioBros-4-2-v1 -m human
```

引数の意味は以下参照

> Individual Stages
These environments allow a single attempt (life) to make it through a single stage of the game.
Use the template
SuperMarioBros-<world>-<stage>-v<version>
where:
<world> is a number in {1, 2, 3, 4, 5, 6, 7, 8} indicating the world
<stage> is a number in {1, 2, 3, 4} indicating the stage within a world
<version> is a number in {0, 1, 2, 3} specifying the ROM mode to use
0: standard ROM
1: downsampled ROM
2: pixel ROM
3: rectangle ROM
> For example, to play 4-2 on the downsampled ROM, you would use the environment id SuperMarioBros-4-2-v1.

# コマンドラインから実行

以下を参考にさせていただきました
>[9-3. vcoptでスーパーマリオ1-1をクリアする](https://vigne-cla.com/9-3/)

```
sudo apt update
sudo apt install xvfb
pip3 install pyvirtualdisplay
pip3 install matplotlib
sudo apt install imagemagick # gif用
sudo apt install ffmpeg 
```

```python:sample.py
#マリオ関連のimport
import gym_super_mario_bros
from nes_py.wrappers import JoypadSpace
from gym_super_mario_bros.actions import SIMPLE_MOVEMENT
env = gym_super_mario_bros.make('SuperMarioBros-1-1-v0')
env = JoypadSpace(env, SIMPLE_MOVEMENT)

#プロット関連のimport
import matplotlib.pyplot as plt
from matplotlib import animation, rc

#vcopt関連のimport
import numpy as np
import numpy.random as nr
from vcopt import vcopt

#ゲーム環境のリセット
env.reset()

#画像の準備
fig = plt.figure()
ims = []

#繰り返し操作して画面を表示
for i in range(100):
    #0:
    #1:→
    #2:→＋ジャンプ
    #3:→→
    #4:→→＋ジャンプ
    #5:ジャンプ
    #6:←
    command = nr.randint(1, 7)
    state, reward, done, info = env.step(command)

    plt.imshow(env.render(mode='rgb_array'))
    plt.show()
    
    if done == True:
        break
```

実行してマリオがランダムに動いているようにみえればOK

```
python3 sample.py
```

# 参考
[https://qiita.com/hrs1985/items/871ca5d037d73558bfca](https://qiita.com/hrs1985/items/871ca5d037d73558bfca)
[Stable Baselinesを使ってスーパーマリオブラザーズ1-1をクリアするまで](https://yutaroogawa.github.io/pytorch_tutorials_jp/)
[9-3. vcoptでスーパーマリオ1-1をクリアする](https://vigne-cla.com/9-3/)
ARFoundation　平面検知、Rayを飛ばしてキャラを表示させる

GameObjectで名前をCharacterに変更、キャラを子オブジェクトにしてPositionを０にする
![51161C62-57C9-48E6-A45D-73C24D59ECA7_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/9fe464e6-f457-e359-9c3a-c3e2fff02a66.jpeg)

Characterはプレハブ化しておき、ヒエラルキーにあるCharacterは削除する
![298EA4F2-D62D-4106-AF66-1AC059739487_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/8988dea3-aa50-35ca-6100-76e94ad98d7f.jpeg)

ARSessionOriginにARRaycastManagerを追加する
![7A9B890E-D0B8-4ADB-93E7-31ED11115BBD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/084be02f-7fb7-47d8-de9a-225393cabab9.jpeg)

RayCast.csを作成する
![44A39BC7-EC9B-461C-8DE6-60A2D55199A3_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/8334b857-29d2-5393-2f3f-9dbbb22baaa5.jpeg)

```C#:Raycast
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
public class Raycast : MonoBehaviour
{
    //Raycast を実行するためのクラス
    private ARRaycastManager m_RaycastManager;
    //Raycast の結果を格納する List
    private List<ARRaycastHit> hitResults = new List<ARRaycastHit>();
    //キャラクターの Prefab
    [SerializeField]
    private GameObject characterPrefab;
    void Start()
    {
        //GameObject にアタッチされている RaycastManager を取得
        m_RaycastManager = GetComponent<ARRaycastManager>();
    }
    void Update()
    {
        //画面がタッチされたら処理を行う
        if (Input.touchCount > 0)
        {
            //画面タッチの情報を取得する
            Touch touch = Input.GetTouch(0);
            //画面タッチの開始時のみ処理を行う
            if (touch.phase == TouchPhase.Began)
            {
                //タッチした方向に Ray を飛ばし、平面との衝突判定を行う
                if (m_RaycastManager.Raycast(
                touch.position,
                hitResults,
                TrackableType.PlaneWithinPolygon
                ))
                {
                    //最初に交差した平面から姿勢を取得して、GameObject を生成する
                    Pose hitPose = hitResults[0].pose;
                    GameObject character = Instantiate(
                    characterPrefab,
                    hitPose.position,
                    hitPose.rotation
                    );
                }
            }
        }
    }
}
```

AROriginにRayCast.csをアタッチし、Characterをアタッチする
![5ECB3DA5-B237-4336-8B62-1BB0D916C72F.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/f960d5e6-310a-79fe-e02b-7f8d5968351a.jpeg)

ビルドする
コマンドラインをまとめてみた

#本記事
本記事はコマンドラインに関してまとめたものです。
簡単にですがまとめてみましたので、よかったら読んでみてください。

#コマンドラインとは
>キーボードだけを使用して操作する画面、もしくは<font color=red>入力行</font color=red>のこと。

#コマンド

```html:ファイルの作成
touch ファイル名
```

```html:ファイルの中身を表示する
cat ファイル名
ファイルの中身を表示する。
```
```html:ディレクトリ(フォルダ)を作成する
mkdir　ディレクトリ名
```

```html:ディレクトリの移動
cd　移動したいディレクトリ名
```
```html:カレントディレクトリの表示
pwd
```

```html:一階層下のディレクトリの表示
ls　
```

```html:１つ親のディレクトリに移動する
cd ..
```
```html:ファイルを移動させる
mv 移動させるファイルorディレクトリ名 移動先のディレクトリ名
```
```html:ファイル名を変更する
mv 現在のファイルorディレクトリ名 新しいファイルorディレクトリ名
```

```html:ファイルのコピー
cp コピーするファイル名 新しいファイル名
```
```html:ディレクトリのコピー
cp -r コピーするディレクトリ名 新しいディレクトリ名
```

```html:ファイルの削除
rm 削除するファイル名
```

```html:ディレクトリの削除
rm -r 削除するディレクトリ名
```



#引用元

https://wa3.i-3-i.info/word11158.html#:~:text=%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9%EF%BC%88CUI%EF%BC%89%E3%81%AF,%E3%83%9A%E3%83%81%E3%83%9A%E3%83%81%E3%82%84%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%E3%82%89%E3%81%AD%E3%80%82&text=%E3%81%8C%E3%80%8C%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E3%80%8D%E3%81%A7%E3%81%99%E3%80%82
CSSとの連動（bindingで色を変化させる）


【１】

```css
.red {
  color: red;
}

.bg-blue{
  background-color: blue;
}
```

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 class="red bg-blue">HELLO<h1>
```

![20210505-221141.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/d8c8ca81-9d29-bb9f-d460-6647b0c58ead.png)


【２】Viewでtrue or falseで表現

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 v-bind:class="{red: true 'bg-blue': false}">HELLO<h1>
```

もしくは


```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :class="{red: true 'bg-blue': false}">HELLO<h1>
```

＊cssは変わらず
*bg-blueのハイフンを使ったケバブケースについてはシングルコーテーションで囲う

【３】Vueインスタンス内で表現

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :class="{red: isActive, 'bg-blue': !isActive}">HELLO<h1>
```

!isActiveは否定＝falseになる

```vuejs
  new Vue({
    el: '#app',
    data: {
  isActive: true    
      }
  })
```


（４）ボタンで逆にする

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :class="{red: isActive, 'bg-blue': !isActive}">HELLO<h1>
<button @click="isActive=!isActive">切り替え</button>
```

![20210505-222911.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/4663f414-45be-5788-3f73-cfe1f9a4c152.png)

![20210505-222926.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/4ae3b64d-93e3-1afe-661c-03bcf075774c.png)


(5)computedを使用して書く


```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :class="classObject">HELLO<h1>
<button @click="isActive=!isActive">切り替え</button>
```


```vuejs
  new Vue({
    el: '#app',
    data: {
  isActive: true    
      },
      computed: {
         classObject: function() {
            return {
            red: this.isActive,
            'bg-blue': !this.isActive
            }
         }
      }
  })
```


computedからdata{  },にアクセスする際は、isActiveにthis.をつける。

(6)配列を使用して書く

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :class="[color, bg]">HELLO<h1>
```

```vuejs
  new Vue({
    el: '#app',
    data: {
      color: 'red',
      bg: 'bg-blue'
      }
  })
```

![20210505-225347.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/4dfd2d7f-0ea0-d317-7a76-37f009b1853b.png)

(7)styleを使ってかく

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :style="{color: textColor, 'background-color': bgColor}">HELLO<h1>
```


```vuejs
new Vue({
   el: '#app',
    data: {
     textColor: 'red',
      bgColor: 'blue'
     }
})
```

(8)Vueインスタンス内にstyleを書く

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

<div id="app">
<h1 :style="styleObject">HELLO<h1>
```

```vuejs
  new Vue({
    el: '#app',
    data: {
      styleObject: {
        color: 'red',
        'background-color': 'blue'
        }
      }
  })
```
ARFoundation 平面検知を行う

PointCloudの表示
---

ARDefaultPointCloudを追加する
![3718FDCC-3256-401F-A961-7D937048AB1C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/adf30d94-d997-f027-8b10-04638c25353a.jpeg)

AROriginにARPointCloudManagerを追加し、プレハブ化したPointCloudをアタッチする
![74ACB398-805E-41C3-8F63-66785DC50AB4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/e5f6d634-549d-1ad0-4ad7-0f62c024fa0c.jpeg)

Plane検知
---
PointCloudと同様の手順でARDefaultPlaneを追加し、プレハブ化する
![4D743201-7F8C-4A46-8899-D8235AE32DC7_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/ec97048e-2645-ca96-73f3-2f668975c29b.jpeg)

AROriginにARPlaneManagerを追加し、ARdefailtPlaneをアタッチする
![A6AD9DF8-7298-4C31-B9DF-8B7658BC22C8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/b71cea6e-7eb8-473c-a8ea-2e93fcf000fa.jpeg)
サーバーサイドの役割

**先輩エンジニアにサーバーサイドの役割をわかりやすく教えてもらったので、メモ**

背景：
初めてサーバーサイドに触れる（apiを作成する）ことになったので、
サーバーサイドの全体像を掴むために先輩に質問した。

この記事の対象者：
    - **サーバーサイドの実装経験がない人**
    - **SQLを少しでも触ったことがある人**

**サーバーサイドの役割は大きく分けて4つ**
---
- **データベース制御**
    - SQL実行
        - 指示されたデータにアクセス（テーブル×行×列）
    - 命令を実行
        - create（生成）
        - read（読み取り）
        - update（更新）
        - delete（削除）
    - フォーマッティング（データ形式をフロントで扱いやすいように整形する）
        - json（keyとvalueを持つ配列の形）
        - xml
- **セキュリティが必要な情報の保持**
    - 個人情報
- **重い処理（クライアントサイドのコンピュータにとって負担がかかりすぎる処理）**
    - ゲームの判定
    - OGP作成
- **即時実行する処理（スピーディーに実行しなくてはいけない割りに重い処理）**
    - ページビュー時のレコメンド系の処理
atomのpdf-viewでpdfが見れないときの解決(?)策

# 背景
atomの`pdf-view`を使ってLaTeXで作成したpdfなどを表示しているが，ここ数週間(2021/04中旬～下旬)でpdfが表示されなくなった．より正確に言えば，pdfファイル用のタブは作成されるが，中身が表示されない状態．
ちなみに，デスクトップとノートの2台とも同じ現象(2台ともwin10)だった．

# 解決策
以下のサイトに書いてあった方法を試した結果，改善した．
https://www.reddit.com/r/Atom/comments/mtuqu4/pdfview_stopped_working/

## `pdf-view`のライブラリをいじる
どこまでいじっていいものなのか知らないが，`.atom/packages/pdf-view/lib/pdf-editor-view.js`のファイルを開き，以下のように16行目の後ろに追加する．

```js:pdf-editor-view.js
let {exec, execFile} = require('child_process');  // 16行目
PDFJS.disableWorker = true; // これを追加
```

# 原因・理由
何もわかっていません．ご存知の方いらっしゃいましたらコメントいただけると幸いです．

# 追記
他の方の解決法
https://qiita.com/HESORIDER/items/1664a71ea92ac4484db7