OmniAICreator/Qiita-1.07M huggingface dataset:
【CakePHP3】クエリービルダーで英数字の文字列を数字を先、英語を後の昇順に並べるクエリ文を書く

良いタイトルが浮かばなかった！笑
ただただ困ってる方の検索に引っかかってくれたらという思いです・・・

タイトルだけだと良く分からないと思うのでご説明します。
まず、以下のような数字が登録されたデータベースのテーブルがあるとします。

|No.|
|:--|
|Z12|
|BB01|
|A02|
|A01|
|3|
|H01|
|1|
|AA02|
|2|

上記を以下のような数字が先、英語が後の昇順(ASC順)で表示させるリストが欲しいとします。

|No.|
|:--|
|1|
|2|
|3|
|A01|
|A02|
|H01|
|Z12|
|AA02|
|BB01|

と、こんな感じに並べたいとします。
とりあえず欲しい結果が伝わったと願って、その場合のクエリ文をお伝えします。

``````PHP:NumbersController.php
public function numbersList {
 $query = $this->Numbers->find()->order([LENGTH('number'),'number']);
}
```

こんな感じです〜。
参考になれば幸いです！
Synology NAS DS218+ 奮戦記

#DS-218+
SynologyのNASと格闘している。
なにせ、これまで何の情報もなく、手探りで進めてきたから。

先に結論を言うと、NASについているDOCKERを動かすことはあきらめた。
幸いながらNASには、仮想環境を作るアプリがあり、
そのチュートリアルを見つけることが出来たからである。

#仮想環境
思えばDockerコンテナが出てくる前の、
クラウド技術は、VMwareによる仮想マシンである。

https://www.itmedia.co.jp/enterprise/articles/1612/19/news041.html

素人ITエンジニアによくある間違いは、
過去の経緯を知らず、最新の技術を使おうとすることである。

急がば回れというが、もっと手前の技術で出来ることがある。

先人に見習いながら、そういう熟成したものを
使いこなす方が、手っ取り早い場合があるのである。

#How to install Ubuntu on Synology 

そんな訳で海外のページを写経してみる。
https://blog.pavelsklenar.com/how-to-install-ubuntu-on-synology/

Linuxを選んだところまではすんなり行けたが、
途中でメモリが足りないことが発覚

<details><summary>一般的な設定</summary>
ステップ3は一般的な設定に関連しています。お気づきのように、あなたは新しい仮想マシンを作成しているので、CPU(2)、RAM(3)、ビデオカード(3)などを割り当てる必要があります。割り当てられた RAM の数は使用可能なメモリに関連していますが、DSM システムはその実行にもメモリを必要とするため、NAS に合計 4 GB がある場合に 4 台の仮想マシン (4 x 1 GB) を数えることはできないことを知っておく必要があります。<br><br>実際には、正確には1つの仮想マシンがあなたによって割り当てられたメモリに加えて256MB + 80MB（ハイパーバイジングのためのリソース）を消費します。各VMは256MBを必要とし、各vCPUは80MBを必要とします）なので、仮想マシンに割り当てられた1GBは合計で1360MBを必要とします。</details>

仕方がなく、他の記事を見ると８Ｇを増設できたとのこと
詳細はここ
https://arakoki70.com/?p=2478

とりあえず、自宅のメモリを探したが、
PC用メモリ 2GB PC2-6400S-666-12は
型番が合わないようだ・・・

がっくし

#やっとこさ
　追加内容がありメモする。

* NASへのメモリ増強。Ｂログ見て８Ｇを追加した。
→　最初、メモリの差しかたが甘く、認識されなくて焦る。
（中古メモリのため別ＰＣで動作まで確認）

* NASの仮想PCを無事に起動し、UBUNTUをインストール。
→少しもっさりしているが、これはＤＳＭ経由のため
（UBUNTUはリナックスの使い方メインと、投資アプリの常時稼働のために構築している。同じく、今後は家庭内LANの中核的なサーバーの位置付けとする。）
だいたい、NASの24時間稼働においては、ＰＣ電気代も馬鹿にならない

* GDP P2 MAX バッテリ＋ＡＣアダプタ到着するが、GDP pocket2と間違えて手配
→　返品対応してくれるかメール中（無理だったら、かなり痛い出費である）
（ちなみに、なぜ今の段階でGDP P2 MAXを復活させたかというと、メインはYoutube動画の文字お越し用で使いたかったからで、ＩＴ関係の動画まとめノートを作る）
（ちゃんと内容書いておかないと、あとで目的を見失うことが多いから）
Python 3.10 からは inspect.signature() が返す形が typing.get_type_hints() ベースになる模様です

今日気づいたのですが、Python 3.10 の inspect モジュールでは `typing.get_type_hints()` を使って型を解釈するようになりました。該当のコミットは[こちら](https://github.com/python/cpython/commit/044a1048ca93d466965afc027b91a5a9eb9ce23c#diff-b89cd06e4637abacb73f2500301ff979a67ad7ecbfa7cf151c7243715898d7ea
)です。

これは Python 3.10 からデフォルトで有効になるアノテーションの遅延評価に関連する修正のようです。`obj.__annotations__` に詰まっている型アノテーション情報が文字列となるので、`typing.get_type_hints()` に任せるのが適当であるという判断でしょう。
この変更により、単に `obj.__annotations__` を参照していた `inspect.signature()` の型情報が、もう一歩踏み込んだ解析結果に切り替わるということになります。

たとえば、Python 3.9 では次の `hello()` 関数の引数 `name` は `str` 型と扱われています。

```python
$ python3.9
Python 3.9.0 (default, Oct 24 2020, 15:41:29)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: str = None):
...     print("Hello ", name)
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: str = None)>
```

一方、Python 3.10 (開発中)では `Optional[str]` 型とみなされます。デフォルト引数が `None` であることを見て、より適した型を返すようになっているわけです。

```python
$ python3.10
Python 3.10.0a1+ (heads/master:805ef73, Oct 24 2020, 15:07:19)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: str = None):
...     print("Hello ", name)
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: Optional[str] = None)>
```

ちなみに、実行時に名前解決ができない場合(`typing.TYPE_CHECKING` で実行時は import していない場合など) はこれまで通り `obj.__signature__` を参照するため、アノテーションによっては解釈結果が変化します。

```python
$ python3.10
Python 3.10.0a1+ (heads/master:805ef73, Oct 24 2020, 15:07:19)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello(name: Unknown, age: int = None): pass
...
>>> import inspect
>>> inspect.signature(hello)
<Signature (name: 'Unknown', age: 'int' = None)>
```

このケースでは `Unknown` 型が解決できないため、引数 `age` の型は `Optional[int]` ではなく、単なる `int` になります。
ボタンデザインがスマホでうまく表示されない時の対処法

## スマホで見るとボタン表示が変！？

表題のとおり、bootstrap4を使っていた時に起こった問題についてメモ書き。

EC2にデプロイして、ほっとひと安心していたのもつかの間。

PCから開いたら問題ないのに、スマホから開くとボタンのデザインがおかしい。

## 実際の画面

![PCで表示したボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513114/3437828a-3afb-e3ce-c64a-25ee137aebe6.png)
（PCからの表示）

![スマホで表示したボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513114/66c2ef9a-2d9f-2073-84d5-9fbec1d72ff4.jpeg)
（スマホからの表示）

__何か白いのが出てる！__

# コード画面

```
.button#dropdown1.btn aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" type="button"
  i.user-icon.fas.fa-user-circle.fa-3x
.dropdown-menu aria-labelledby="dropdown1"
  - if user_signed_in?
    li = link_to 'マイプロフィール', user_path(current_user), class: 'text-dark font-weight-bold dropdown-item bg-light'
    li = link_to 'プロフィール編集',"/users/edit", class: 'text-dark font-weight-bold dropdown-item bg-light'
    li = link_to 'ログアウト',"/users/sign_out", method: :delete, class: 'text-dark font-weight-bold dropdown-item bg-light'
  - else
    li = link_to 'ログイン',"/users/sign_in", class: 'text-dark font-weight-bold dropdown-item bg-light'
    li = link_to '新規登録',"/users/sign_up", class: 'text-dark font-weight-bold dropdown-item bg-light'
```

## 原因と対策

調べてみると、iOSのデフォルトスタイルが悪さをしていることが分かった。このスタイルの適用を外す必要がある。

CSSで該当する要素に指定をかける。今回の場合だとbtn要素の#dropdown1に記述を追加する。

```css
div#dropdown1 {
  -webkit-appearance: none;
}
```

これでサーバーにデプロイし、表示を確認。

![修正されたボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513114/b8288eaf-bd0f-5485-07ce-391453d3e1a0.jpeg)

直った！

## まとめ

OSの違いで生じる問題なので、今後も同様のトラブルが出てきた時に使っていきたい。
「差分取得」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

DBのデータとExcelシート内の既存のデータを比較し、Excelシート内に存在しないレコードを取得します。

1. 「Microsoft SQL Server Management Studio」にて、現在のテーブルのデータを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/bce89474-2f74-d5ae-87ac-18efe11c0cb6.png)

2. 今、Excel上に、テーブルのデータが2行存在しています。ですが、データベースには3行のデータがあり、データベースとExcel上のデータに差異があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/982868a9-cb88-00e5-f8b0-b27d50dba977.png)

3. Excelの「アドイン」タブにある「DBUpdateTool」の「差分取得」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/8984ebfc-08fb-5fd1-df39-a909325cf51f.png)

4. 処理が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/5557913d-de8f-1899-e366-c56fc0d018a6.png)

5. 「Microsoft SQL Management Studio」で事前に確認したテーブルのデータが、Excel上に表示されています。ご覧の通り、Excelのデータが2行から3行に増えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/03af01d3-3221-e05f-2942-bda5dbfabd85.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/8b2bd5c9-7455-c0f1-d9f6-818624c16f0d.png)
dockerコンテナからホストにファイルをコピーする（docker cp)

# コマンド
```console
docker cp <コンテナIDまたはコンテナ名>:コピーしたいファイルのパス コピー先パス
```

でコピーできる。
[レファレンスはこちら。](http://docs.docker.jp/v1.9/engine/reference/commandline/cp.html)

# 実例
dockerでoracleを動かしていて、接続情報を確認したくなったので、tnsnames.oraをコピーする。

```console:コンテナID指定の場合
# コンテナID調べる(CONTAINER ID)
$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                 PORTS                                            NAMES
d3e6c3fd1a85        oracle/database:19.3.0-ee   "/bin/sh -c 'exec $O…"   2 hours ago         Up 2 hours (healthy)   0.0.0.0:1521->1521/tcp, 0.0.0.0:5500->5500/tcp   orcl

# コピーする
$ docker cp d3e6c3fd1a85:/opt/oracle/oradata/dbconfig/ORCLCDB/tnsnames.ora ./

# コピーできたか確認
$ find tnsnames.ora
tnsnames.ora
```

```console:コンテナ名指定の場合
# コンテナ名を調べる(NAMES)　
$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                 PORTS                                            NAMES
d3e6c3fd1a85        oracle/database:19.3.0-ee   "/bin/sh -c 'exec $O…"   2 hours ago         Up 2 hours (healthy)   0.0.0.0:1521->1521/tcp, 0.0.0.0:5500->5500/tcp   orcl

# コピーする
$ docker cp orcl:/opt/oracle/oradata/dbconfig/ORCLCDB/tnsnames.ora ./

# コピーできたか確認
$ find tnsnames.ora
tnsnames.ora
```

# 環境情報

```console
$ docker version
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 16:58:31 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H2
```

# 参考
- [Dockerでホストとコンテナ間でのファイルコピー](https://qiita.com/gologo13/items/7e4e404af80377b48fd5)
- [Dockerコンテナからホストへファイルをコピーする](https://qiita.com/RyotaIshii/items/25beeafaa836b4f4819c)
- [DockerでMacにOracle 19cをインストールして開発環境を構築する](https://qiita.com/alashino/items/41b5957cd864bbcc6ef8)
volatilityの作法 その20

#概要

volatilityの作法、調べてみた。

#コンピュータウイルスの定義。

経済産業省が告示した「コンピュータウイルス対策基準」においては、コンピュータウイルスの定義

##第三者のプログラムやデータベースに対して意図的に何らかの被害を及ぼすように作られたプログラムであり、次の機能を一つ以上有するもの。

- 自己伝染機能
自らの機能によって、他のプログラムに自らをコピーし、又は、システム機能を利用して、自らを他のシステムにコピーすることにより、 他のシステムに伝染する機能。

- 潜伏機能
発病するための特定時刻、一定時間、処理回数等の条件を記憶させて、条件が満たされるまで症状を出さない機能。

- 発病機能
プログラムやデータ等のファイルの破壊を行ったり、コンピュータに異常な動作をさせる等の機能。

具体的に、
プログラムに寄生する極めて小さなプログラムであり、
自分自身を勝手に他のプログラムファイルにコピーする事により増殖し、
コンピュータウイルス自身にあらかじめ用意されていた内容により、
予期されない動作を起こす事を目的とした特異なプログラムです。

#想定される侵入経路
- メール経由 
- WEB経由 
- 脆弱性があるOSやアプリケーション 
- 外部メディア経由（USB・DVD等）
- ファイル共有ソフト
- スマートフォンの接続

#ウイルスの種類

- プログラムファイル感染型
最も基 本 的なウイルスプログラムでD O S 上のプログラムファイルに感染。
EXEファイルやCOMファイル

- システムプログラム感染型
ＯＳ（オペレーティングシステム）が起動する為に必要なプログラムに感染。
SYSファイルなど

- マクロ型
マクロ機能を持ったアプリケーションのデータファイルに感染。
Microsoft Word、Microsoft Excel、Microsoft Power Point、Microsoft Access（Microsoft Office製品）

- Java・ActiveX型
ブラウザーを介して被害を及ぼす。
Microsoft Internet Explorer

- ダイレクトアクション型
通常ウイルスに感染するには、添付ファイルを実行したり、ダウンロードしたファイルをダブルクリックする必要などがあるが、この場合はブラウザやOSなどのセキュリティホールを利用し、クリックすることなく自動的に感染させる。

#検出手法

- コンペア法
ウイルスの感染が疑わしい対象(検査対象)と安全な場所に保管してあるその対象の原本を比較し、異なっていれば感染を検出する場合をこの手法に分類する。

- パターンマッチング法
「パターンデータ」「ウイルスパターン」「パターンファイル」「ウイルス定義ファイル」等を用いて、何らかの特徴的なコードをパターンとしてウイルス検査対象と比較することで検出する場合をこの手法に分類する。
また、特徴的なコードの定義には、ファイル名、メール送受信者の名前やアドレス、送信経路情報、メールメッセージの表題、テキスト文章、バイナリ情報等も含めて考え、それらの登録情報(パターン)と検査対象の情報との比較による検出についても同手法によるものとする。

- チェックサム法/インテグリティチェック法
検査対象に対して別途ウイルスではないことを保証する情報を付加し、保証がないか無効であることで検出する場合をこの手法に分類する。
代表的な保証方法には「チェックサム」「ディジタル署名」等がある。

- ヒューリスティック法
ウイルスのとるであろう動作を事前に登録しておき、検査対象コードに含まれる一連の動作と比較して検出する場合をこの手法に分類する。
「動作の特徴コード」を検出に用いているかどうかが分類の大きな尺度となる。

- ビヘイビア法
ウイルスの実際の感染・発病動作を監視して検出する場合をこの手法に分類する。
感染・発病動作として「書込み動作」「複製動作」「破壊動作」等の動作そのものの異常を検知する場合だけでなく、感染・発病動作によって起こる環境の様々な変化を検知することによる場合もこの手法に分類する。
例えば、「例外ポート通信・不完パケット・通信量の異常増加・エラー量の異常増加」「送信時データと受信時データの量的変化・質的変化」等がそれにあたる。


以上。
C#　例外処理(Try-Catch)がないところで出るエラーを全て一纏めにキャッチする

C#でtry-catchが記載されていない箇所でエラーが起きても
アプリが落ちないようにする。

C#では、
「Application.ThreadException」イベントが
用意されている。

使い方
Program.cs(コピペ用)

    static class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.ThreadException += Application_ThreadException;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message);
        }
    }

画像
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123307/da9c9b8b-ce8c-4af9-6c18-6053f93ca345.png)




参考資料：
■適切に処理されなかった例外をキャッチするには？
　https://www.atmarkit.co.jp/ait/articles/0507/01/news134.html
【Kotlin】KFunctionから定義元objectのinstanceを取得する

# やりたいこと
`KFunction`が渡された時、その定義元が`object`であれば、その`instance`を取得します。
ただし、今回紹介する方法でトップレベル関数を処理すると`java.lang.UnsupportedOperationException`になるため注意が必要です。

# やり方
以下のように、`KFunction`から`javaMethod`を経由することで取得できます。
もう少し素直な取得方法が無いものか確認しましたが、`Kotlin 1.4.10`時点では`KFunction`に`declaringClass`のようなプロパティは無く、無理そうでした。

```kotlin
object Foo {
    fun function(i: Int) = i.toString() 
}

val function: KFunction<String> = (Foo)::function
val instance: Foo = function.javaMethod!!.declaringClass.kotlin.objectInstance as Foo
```
Laravel-Excelのインストールにおけるエラーを解消する

# なにがあったか

[公式](https://docs.laravel-excel.com/3.1/getting-started/installation.html)の手順通りにインストールしているはずが、いくつかのエラー（主に関連するライブラリ）に見舞われた。

## インストール

開発環境が **Laravel ver5.5.49** であるため、[公式](https://github.com/maatwebsite/Laravel-Excel)を参考に**バージョン3.0**を導入（PHPのメモリ制限に引っかかるためリミットをなんとかしている）

```terminal
$ COMPOSER_MEMORY_LIMIT=-1 composer require maatwebsite/excel:3.0
```

インストールが

```terminal
killed
```

で終わっているのに気づかず次の手順に進んだりするとハマる（自分）。
――で、これはどうもDockerのメモリが足りないらしいので、自分はDocker DesktopのPerformanceからメモリを4GBまで増やした。

## エラー

Excelファイルをダウンロードする実装自体は上記の手順でできてしまうが（スミマセン、うろ覚え）、このあとなんらかの事情で `composer install` を打った際に

```terminal
  Problem 1
    - phpoffice/phpspreadsheet 1.15.0 requires ext-gd * -> the requested PHP extension gd is missing from your system.
    - phpoffice/phpspreadsheet 1.15.0 requires ext-gd * -> the requested PHP extension gd is missing from your system.
    - Installation request for phpoffice/phpspreadsheet 1.15.0 -> satisfiable by phpoffice/
```

こういった『**関連するライブラリがない**』というエラーが次々に出てくる。ゴチャゴチャと関連するライブラリを順番にインストールしていったが、最終的に『**Laravelのバージョンが合わん**』と言われてしまった。すでにスタートしている開発環境でそれをやるのはわりとめんどくさいので困った。

## 解決

```terminal
$ COMPOSER_MEMORY_LIMIT=-1 composer require maatwebsite/excel:3.*
```

バージョンの指定をやや緩くしたら解決した。
関連するライブラリをインストールしなければいけない点は同じだが、少なくとも「Laravelのバージョンが」と言われることはなくなって解決した（開発環境によっては違うポイントでエラーにハマる可能性はある）。

## 雑感

`3.0` はダメなのに `3.*` だとOKなのはなんでだろう🤔
バージョンアップでLaravelのバージョン依存が緩和されたのかな。。
【SwiftUI】ScrollViewのScrollsToTopを無効にする方法

#ScrollsToTopとは
ScrollViewが表示されている状態でStatusBar（一番上の時刻やバッテリー残量が表示されている部分）をタップすると自動で一番上までスクロールしてくれる機能。

デフォルトではオンになっている。
#無効にする方法
`UIScrollView.appearance().scrollsToTop = false`を記述する。

例:

```swift
ScrollView {
  ...
}.onAppear {
  UIScrollView.appearance().scrollsToTop = false
}
[RuboCop]警告を無効化する方法

#RuboCopに怒られすぎて嫌になってませんか？
「ここはしょうがないだろ！」と言いながらどうにか頑張って怒られないようにする経験が誰しもがあるかと思います。
そこで、警告を無効化するための方法を紹介します。
使いすぎてもRuboCopの意味がなくなるので注意ですが、使いどころを見極めて活用してみましょう！

##無効化する方法
####指定範囲の全ての警告を無効化したい場合

```ruby

# rubocop:disable all

〜ここに処理を記述〜

# rubocop:enable all
```

####指定範囲の特定の警告を無効化したい場合

```ruby

# rubocop:disable Style/LineLength, Style/StringLiterals

〜ここに処理を記述〜

# rubocop:enable Style/LineLength, Style/StringLiterals
```

####単一行の全ての警告を無効化したい場合

```ruby

for x in (0..19) # rubocop:disable all
```

####単一行の特定の警告を無効化したい場合

```ruby

for x in (0..19) # rubocop:disable Style/AvoidFor
```
フォーム入力の結果を表示する方法

はじめて記事を書かせていただきます
プログラミングの学習をはじめて、１ヶ月の初心者です

ruby on railsでfurimaアプリを作成しています
ユーザー登録をして、商品を出品し、他のユーザーが購入すると、取引が完了する流れです

現段階の仕様では、ユーザーの出品商品の入力が終わると、topページに移動するようにしています

```ruby
def create
  @item = Item.new(item_params)
  if @item.valid?
     @item.save
     return redirect_to root_path #topページに戻る
  else
    render :new
  end
end
```
＊itemsテーブルに出品商品の情報が登録されます

ここで「商品の出品が完了しました」と表示されるページを追加し、topページへクリックで戻るようにする方法を検討しています

- コントローラーに、パスを記述する方法でやってみる

まず、結果表示のHTML文書を作成（kanryouとする）
routesファイルに記述

```ruby
resources :items  do
  resources :orders, only: [:index, :create]
  member do
    get 'kanryou'
  end
end
```
コントローラーに記述

```ruby
def create
  @item = Item.new(item_params)
  if @item.valid?
     @item.save
     return redirect_to kanryou_item_path(@item.id)
  else
     render :new
  end
end
```

以上でうまくいきました

参考にさせていただきました
https://qiita.com/imayasu/items/19f43a5726ed2170f611
[Rails]変換・検証・検索するためのメソッドまとめ

# 変換系のメソッド

####to_h
ハッシュに変換するメソッド。

####to_a
配列に変換するメソッド。

####to_s
文字列に変換するメソッド。

####to_i
数値に変換するメソッド。

####to_sym
シンボルを返すメソッド。

####encode
文字列の文字コードを変換する。

```
文字列.encode('UTF-8')
```

####gsub
特定の文字を別の文字へ置換したり、正規表現を用いて該当箇所を置換したり削除したりできる。

```
文字列.gsub(置換したい文字列, 置換後の文字列)

文字列.gsub(/正規表現/, 正規表現に該当した箇所を置換した後の文字列)
```

####compact
nilの要素を取り除いた配列を新しく生成して返します。

```ruby

a = [1, nil, 'abc', false]
b = a.compact
b #=> [1, 'abc', false]
```

####join
配列要素を指定したもので区切ることができるメソッド。

```ruby

p ["apple", "orange", "lemon"].join(',') #=> "apple,orange,lemon"
```

####each_slice
ある要素数ごとに分割したい場合に使う。

```ruby

[1..10].each_slice(2) do |num|
  puts num
end
#=> [1,2,3,4,5],[6,7,8,9,10]
```

# 検証系のメソッド

####request.post(patch,get,delete)?
リクエストの種類がpost(patch,get,delete)かどうかを検証している。

####valid?
バリデーションを実行した結果、エラーが無ければtrue、あればfalseを返す。

####invalid?
バリデーションを実行した結果、エラーが無ければfalse、あればtrueを返す。

####present?
値があればtrue、なければfalseを返す。

####nil?
nilの場合のみtrue、それ以外はfalseを返す。

####empty?
空の文字列や配列の場合にtrue、それ以外はfalseを返す。(nilに使うとエラーになる。)

####blank?
nilか空の場合はtrue、それ以外はfalseを返す。

####zero?
中身が0(無いか)を調べるメソッド。文字列やtrue&false以外に使える。

####any?
中身が存在する際にtrueを返すメソッド。一件だけ検索するので高速処理。2つ目と3つ目は同義。

```ruby

Sample.where(name: "侍1").any?
#=> true

Sample.any? do | sample |
  sample.name == "侍1"
end
#=> true

Sample.any? { | sample | sample.name == "侍1" }
#=> true
```

####yes?
ユーザーがyesといった場合にtrueを返す。

```ruby

freeze! if yes?("Should I freeze the latest Rails?")

list << '土曜日' if holiday_saturday&.yes?
```

# 検索系のメソッド

####pluck
テーブルから指定したカラムの配列をデータ型で返す。

```ruby

Product.pluck(:id)
```

####map
各要素へ順に処理を実行してくれるメソッド。

```ruby

配列変数.map {|変数名| 具体的な処理 }

array = ["a", "b", "c"]
array = array.map {|item|  item.upcase } #=>["A", "B", "C"]
```


####detect
各要素をブロックで評価し「真(true)」となる要素の最初の1件を返す。findメソッド的なやつ。

```ruby

array = [1, 2, 3, 1, 2, 3]
detect = array.detect {|v| v==1 } #=>1
```
QiskitのシミュレータでGPUを使ってみる．

Google colabで実行．GPUもGoogle colabで使えるものを使用．
## install
```python
!pip install qiskit
!pip install qiskit-aer-gpu
```
## import とversion確認
```python
import qiskit
from qiskit import  *
qiskit.__version__
#0.16.0
```
```python
qiskit.__qiskit_version__
#{'qiskit': '0.23.0',
# 'qiskit-aer': '0.7.0',
# 'qiskit-aqua': '0.8.0',
# 'qiskit-ibmq-provider': '0.11.0',
# 'qiskit-ignis': '0.5.0',
# 'qiskit-terra': '0.16.0'}
```

## 好きな回路を作る
```python
n_qubit = 12
circ = QuantumCircuit(n_qubit)
for i_qubit in range(n_qubit):
  circ.ry(np.pi/8, i_qubit)
  circ.rz(np.pi/8, i_qubit)
  circ.ry(np.pi/8, i_qubit)
  circ.rz(np.pi/8, i_qubit)
  if i_qubit <= n_qubit-2:
    circ.cx(i_qubit, i_qubit+1)
```

## シミュレータの設定，ここでGPUも指定する
```python
%%time
from qiskit import Aer
backend = Aer.get_backend('statevector_simulator')
#GPUありの時
backend_options = {"method": "statevector_gpu"}
#GPUなしの時
# backend_options = {"method": "statevector"}
job = execute(circ, backend, backend_options=backend_options)
result = job.result()
outputstate = result.get_statevector(circ, decimals=3)
```
時間計測の結果

- GPUなし: `CPU times: user 10.4 ms, sys: 0 ns, total: 10.4 ms Wall time: 10.2 ms`
- GPUあり: `CPU times: user 9.84 ms, sys: 944 µs, total: 10.8 ms Wall time: 10.7 ms`

あまり結果に差がない．回路が単純すぎで並列化の利点を生かせていない？

## `n_qubit` 12 → 24に変更
- GPUなし: `CPU times: user 1.52 s, sys: 48.3 ms, total: 1.57 s Wall time: 797 ms`
- GPUあり: `CPU times: user 131 ms, sys: 14.9 ms, total: 146 ms Wall time: 146 ms`

GPUの効果が見られた．

## 注意: `backend_options`
なんかもうすぐ使えなくなるらしい．どう変更すればいいのか教えてください．

追記: 
変更方法が見つかったので，載せておきます．
https://zenn.dev/nucl_quantum/articles/5312ddd558793572919c
obnizの初期化をやったのでメモ

# 初期化は最強
obnizの初期化方法
https://obniz.com/ja/doc/reference/board-1y/obnizos

# 困ったこと
いつもの環境と違ったから設定を再度しないといけない。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日は会社でやってるから、WiFi環境がいつもと違う。。<br>obnizの設定からだ。。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a></p>&mdash; heihei (@heihei15408697) <a href="https://twitter.com/heihei15408697/status/1319854440019496961?ref_src=twsrc%5Etfw">October 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

WiFiを選びなおしてパスワードを入れたら、下記のエラー。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">wifi設定したら、なんかよく分からんエラー。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/2rBxpucWwG">pic.twitter.com/2rBxpucWwG</a></p>&mdash; heihei (@heihei15408697) <a href="https://twitter.com/heihei15408697/status/1319857821584740353?ref_src=twsrc%5Etfw">October 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

よく分からなかったので、obnizの設定を初期化。
https://obniz.com/ja/doc/reference/board-1y/obnizos

再度、パスワード入れなおしたら、うまくいった！
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">よし、今からだ！<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://t.co/fhdouU2KnA">pic.twitter.com/fhdouU2KnA</a></p>&mdash; heihei (@heihei15408697) <a href="https://twitter.com/heihei15408697/status/1319863641101881345?ref_src=twsrc%5Etfw">October 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

やっぱり、初期化最強！！！！！
Laravel-Excelでbladeのテンプレートを使って複数シートで作成する

# 概要

**いろんな事務所に所属するバンドのデータを取得。bladeにテンプレートを作り、事務所ごとのデータをExcelファイルでダウンロードする**というパターンを想定して実装する。テーブルはbladeにてテンプレートを作る。

Laravel-Excelのインストールの手順などは省く。
bladeでテンプレートを作って出力する方法は下記を参考。

**Laravel-excel で帳票を出力する**
<https://qiita.com/ShibuyaKosuke/items/7e5e99c51546a578d97b>

## 複数ファイルは出せないのか

最初はダウンロードする処理を `foreach` で回して事務所ごとにファイルをダウンロードする処理をすればいいだろうと安易に考えていたが、どうも**それはできない**ようで（ダウンロードする処理で `return` しなければならないため）、ファイルはひとつだが事務所ごとに**複数シート**で分けるということにした。
**Laravel-Excel** を使って複数シートでダウンロードする方法は[公式サイト](https://docs.laravel-excel.com/3.1/exports/multiple-sheets.html)も含めて探せばいくつか見つかるが、bladeでテンプレートを作って出力するパターンのものは工夫して作らなければならなかった。

## 必要なファイル

以下4点のファイルを用意すれば作ることができる。
ディレクトリやファイル名は任意。
テンプレートとなるbladeは割愛する。

```php:bandController.php
public function export()
{
// 中略

// 複数シートでのダウンロード
$view = \view('band_information.export')
    ->with('offices', $offices);
return (new MultiBookExport($view))->download("band_info.xlsx");
}
```

```php:BandInfosExport.php
<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class BandInfosExport implements WithMultipleSheets
{
    use Exportable;

    private $view;
    
    public function __construct(View $view)
    {
        $this->view = $view;
    }

    public function sheets(): array
    {
        $sheets = [];
        $i = 1;

        // 事務所数
        $count = count($this->view->offices);

        // 事務所の数だけシートを作る
        foreach ($this->view->offices as $office) {
            
            $sheets[] = new BandInfosSheet($office);
            
            if ($i === $count) {
                return $sheets;
            }
            $i++;
        }
    }
}
```

```php
<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithTitle;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;

class BandInfosSheet implements FromView, WithTitle
{
    private $office;

    public function __construct($office)
    {
        $this->office = $office; 
    }

    public function view(): View
    {
        // 事務所に所属するバンドのデータをbladeのテンプレートに渡す
        return \view('band_information.export')
            ->with('informations', $this->office['band_informations']);        
    }

    public function title(): string
    {
        // シート名となる事務所名を取得
        return $this->office->name;
    }
}
```
さまざまなマイグレーション操作を使いこなす

##マイグレーションの適用を理解しよう
１．「マイグレーション」ファイルを作成し、RubyでDBの構造（スキーマ）を変更するコードを記述
２．作成した「マイグレーション」ファイルをrails db:migrateコマンドを使ってデータベースに適用する(migrateする)。

```terminal
$ rails db:migrate
```
マイグレーションファイルの更新・変更・削除はコマンドを実行しないと適用されない。

##マイグレーションの上げ下げ
マイグレーションを適用する　＝　**上げ**
適用を取り消す　＝　**下げ**

##schema.rb
Railsは現在のデータベース構造をdb/schema.rbに自動出力します。
マイグレーションのを適用したり外したりすると自動的に出力され、また

```terminal
db:schema.rb:dump
```
で手動出力する事も可能
QUERY関数で「年月ごと」に集計したい

# 「月ごと」には出せた

過去に書いた [QUERY関数で「月ごと」に集計したい](https://qiita.com/sakaimo/items/4a501b12a07718085e6d) の記事で下記のように「月ごと」に出すことに成功しました。
![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/69da5c18-8da8-9b5a-cbf5-b920a2eee6b8.png)


# 今回の課題

それはそれとして、新たに下記のような元データ(左の表)の場合、「月ごと」で集計すると右の表のようになります。

![q3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/cfa7c366-5016-8ddf-6c8c-1656c8fb0c4c.png)

D1セルに下記の式が入っています。

```
=query(A:B,"select month(A)+1, sum(B) where A is not null group by month(A)+1 label month(A)+1 '月', sum(B) '合計'",1)
```

**2020年**10月と**2021年**10月は、どちらも「10月」なので合算されちゃいます。

**年を超えた月ごとの合計や平均を調べたいときはこれで問題ないのですが、「年月ごとの推移」を見たいときはこれじゃダメです。**


# これでどうだろう。

![q4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/2b974006-d443-aa88-e148-8a40bbf7d342.png)

↑ これだと「年月ごと」に集計することができました。やったね。

元データ(A,B列)はそのままで、C列に「年月」を表示する列を追加しました。

**(X) C2セルには下記の式が入っています。**
`TEXT(A2:A,"yyyymm")` がポイントで、TEXT関数で年月の情報を表示しています。

```
=ARRAYFORMULA(If(A2:A<>"",TEXT(A2:A,"yyyymm"),""))
```

↑ ここまでできちゃえばA,B,C列でやりたいことができます。


**(Y) E1セルには下記の式が入っています。**

```
=query(A:C,"select C, sum(B) where A is not null group by C label C '年月', sum(B) '合計'",1)
```

# とはいえ

なんかこう、「C列に追加する」っていうのがイケてない気がするんですよね。
これってQuery関数一発で表示させることができるのでしょうか。
できるよ！という方、ぜひコメントで教えてください！！

# 一発でできたよ！

投稿直後に **データ範囲を読み込むときに年月を連結しちゃう** 案をいただきました。
ありがとうございます！！

`ARRAY_CONSTRAIN` なんて使ったことなかったよ！！

```
=query(
  ARRAY_CONSTRAIN(
    ARRAYFORMULA({YEAR(A:A) & RIGHT("0" & MONTH(A:A), 2), B:B}),
    COUNTA(A:A),
    2
  ),
  "select Col1, sum(Col2) 
  group by Col1 
  label Col1 '年月', sum(Col2) '合計'",
  1
)
```

`=query(範囲, query文)` の構文において、「範囲」の時点でほしいテーブルを生成しておけばいい、ってことか。。。天才かよ。


# 追記(2022-12-23)

コメント欄にとてもいいアイディアを頂いたので、そのアイディアを使ったやり方を [このコメント](https://qiita.com/sakaimo/items/3ba584afee391c2ff7d1#comment-30acf673f6ddbc5e8142) に投稿しました。
git merge --no-ffするとcommitする。

##当たり前のこと

```git merge --no-ff```はmerge commitを明示的に行うコマンドなので、
commit画面が出てくるのは当たり前のこと。
それで良い。この動作が正常。
要はmerge.ff=falseしてると起こる。

##記事のターゲット

・gitについてよくわからないけど、とりあえず使っていけばなんとかなるかな、と考えている人。
・先輩がなんとなくやっているから、そういう設定にした、なんかワンラインで書く時にcommit画面出てきてめんどくさいな、と思っている人。

##環境

```bash
$ git config -l
alias.ci=commit
alias.st=status
alias.br=branch
alias.co=checkout
merge.ff=false
pull.ff=only
```
(不要の部分は削除した。)

##git mergeには大きく２種類ある。
コンフリクトや３ウェイマージ周りの話はしません。
要は、多くの場合、mergeをする場合、事足りるのでデフォルトがFAST-FORWARDの設定になっている。
が、多くの諸先輩方は、```git merge --abort```などでcommit後に前バージョンに戻りたい事柄が多かったか、それでトラブったケースがあるので経験談からとりあえず```--no-ff```しとけという話。
（やってみればわかると思うけど）

### FAST-FORWARD MERGE
直訳：[早送りマージ](https://git-scm.com/docs/git-merge#_fast_forward_merge)

詳細は上記本家リンクに任せるとして、重要なのは下記かなと。

・特別な設定がない場合、```git merge -```にて選択される手法はこっち。
・マージされたブランチにマッチするようにブランチポインタを更新するだけで、マージコミットは作成しません。
・できない場合 (マージされた履歴が現在の履歴の子孫ではない場合)、マージコミットを作成します。
・この動作は、--no-ffオプションで抑制でき、すべての場合にマージコミットを作成します。

### TRUE MERGE
直訳：[真のマージ](https://git-scm.com/docs/git-merge#_true_merge)

詳細は上記本家リンク
・マージされるブランチは、両方を親として持つマージコミットによって結合される。
・マージされるすべてのブランチからの変更を調整するマージされたバージョンがコミットHEADされる。
・複雑な競合が発生したマージを試みて、最初からやり直したい場合は、```git merge --abort```で回復できる。（らしい）

##回避方法
何もむずかしくない、```git merge - -m 'message'```するだけ。

ワンラインサンプル

```bash
$ git co - && git merge - -m 'merge branch into main' && push origin HEAD
```
### コメント
先達は偉大だ。
基本的には特にこだわりはなくオススメ設定を受け入れさせてもらっている。
それでもなんでだろ？と思ったことはちゃんと調べていきたいと思います。

### References
[Git公式ドキュメント](https://git-scm.com/doc)
[gitのmerge --no-ff のススメ](https://qiita.com/nog/items/c79469afbf3e632f10a1)
[Github]開発時によく使うコマンドまとめ

# ブランチの作り方

```

$ git checkout develop

$ git checkout -b 作成するブランチ名

$ git push -u origin 作成したブランチ名
```

# プルリクエスト作成方法

1.以下のコマンドを実行する。

```

$ git add .

$ git commit -m "コミット内容"

$ git push origin develop
```

2.右上の緑色のCompare & pull requestボタンをクリック。

3.プルリクエスト内容を記入する。

4.どのブランチからどのブランチにpull requestするかを確認する。

-例-
developブランチからsampleブランチへのpull request

sample ... develop

5.「Create pull request」ボタンを押して、Pull Requestを作成。


# 最新情報をローカルに反映させたい時
1.commit、pushまで終わらせた状態で以下のコマンドを実行する。

```

git checkout develop

git pull origin develop

git checkout 開発用ブランチ

git merge origin develop
```

2.もし、コンフリクトが発生した場合は、以下を実行する。

```

# コンフリクト内容を解消した上で、、
$ git add .

$ git commit -m "コミット内容"

$ git push origin 開発用ブランチ

$ git merge origin develop
```


# ローカルをリモートに合わせたい時(強制的に)

```ruby

# リモートの最新を取ってくる
$ git fetch origin

# ローカルのmainを、リモート追跡のmainに強制的に合わせる
$ git reset --hard origin/main
```

# commitを取り消したい

- --soft
 - ワーキング、ステージングはそのままにコミットのみ取り消す
- --hard
 - ワーキング、ステージング、コミットをすべて取り消す

```ruby

# 直前のcommitの取り消し
$ git reset --hard HEAD^

# n個前のcommitの取り消し
$ git reset ---hard HEAD~n
```

# resetの取り消し

```ruby

# ログを出す
$ git reflog

# 任意のところでリセットする
$ git reset --hard HEAD@{1}
```

# ログの確認

```ruby

# HEAD やブランチ先端の動きの履歴
$ git reflog

# ブランチの指定も可能
$ git reflog ブランチ名

# commit履歴
$ git log

# ブランチの指定も可能
$ git log ブランチ名
```
【Ruby on Rails】javascriptのお手軽スクロールアニメーション（ScrollReveal.js使用）

# 目標
![scroll.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/2584261a-4351-e482-2c82-e99039e2dcd8.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# ScrollReveal.jsとは
https://scrollrevealjs.org/
こちらが公式サイトにはなります。
```ScrollReveal is a JavaScript library for easily animating elements as they enter/leave the viewport.```
ScrollRevealは、要素がビューポートに出入りするときに要素を簡単にアニメーション化するためのJavaScriptライブラリです。
※google翻訳 

# 流れ
1 ScrollReveal.jsを導入する
2 viewの編集
3 jsファイルの編集

# ScrollReveal.jsを導入する

①CDNで読み込む場合（おすすめ）
application.html.erbのhead内に
```<script src="https://unpkg.com/scrollreveal">```
この一行を追加し、ScrollReveal.jsを使用できるようにします。

```erb:app/views/layouts/application.html.erb
<head>
  <title>Ddtt</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  <script src="https://unpkg.com/scrollreveal"></script>
</head>
```

②ファイルをダウンロードする場合
https://github.com/jlmakes/scrollreveal
こちらからzipファイルダウンロードするし、中にある「scrollreveal.min.js」を
app/assets/javascripts内に保存します。
その後、```<script src="/js/scrollreveal.min.js"></script>```
こちらをhead内または表示ファイルの一番上に追加してください。

# view,CSSの編集
説明のため、html内にcssを記述します。

```erb:app/views/homes/top.html.erb
<div class="page">
  <span>スクロールしてください</span>
</div>

<div class="page">
  <div class="box"></div>
</div>

<style>
.page {
  position: relative;
  height: 100vh;
}
.box {
  width: 500px;
  height: 200px;
  background-color: red;
}
</style>
```



# jsファイルの編集
こちらが基本の形。

```js:app/asstes/javascripts/application.js
$(function(){
  ScrollReveal().reveal('.box');
});
```
基本形だとこのようになります。
![画面収録 2020-10-23 20.11.11.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/bbc1319e-0d4f-a8aa-3fab-4169df74ce1d.gif)
gif画像にした分表示がかなり早くなっていますが、
ご覧の通りあまりアニメーションがあるかどうかは確認しにくいです。
したがってオプションを付けていきます。

目標にある動画の記述。

```js:app/asstes/javascripts/application.js
$(function(){
  ScrollReveal().reveal('.box', { 
    duration: 2000, 
    scale: 4,
    reset: false
  });
});
```

このようにオプションを追加することも可能です。
今回使用したオプションは

- duration：アニメーションの完了にかかる時間
- scale：表示される前の要素のサイズ
- reset：viewportを離れる時に初期化された位置に戻る要素を有効/無効にする

その他にも様々なオプションが用意されているため、
興味のある方は公式サイトをご覧ください。
https://scrollrevealjs.org/api/delay.html

# まとめ
ほとんどの有名サイトにはなにかしらのアニメーションが付与されており、
今から作成する場合は必須になっていると思います。
ただし、上記を活用すれば数分で導入できるのでおすすめです」。


またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork
AternosからConohaにマイクラのワールドを移行する方法

マイクラのサーバーを無料のAtenosから有料VPSのConohaに乗り換えた際に、データ移行で詰まったところがありました。
同じように苦労される方のために乗り越えた内容をここに記します。
# 前提
- Minecraft JAVAアプリケーションイメージを用いてマイクラサーバーを構築している
- VPSサーバーにSFTP接続できる
- VPSサーバーにSSH接続できる

# おおまかなやり方
1. Aternosからバックアップを取得
    1. バックアップ -> ダウンロード
    1. 入手したファイルを解凍
1. Conohaで立てたマイクラ用サーバーにSFTP接続
    1. `/opt/minecraft_server/wold` を削除
    2. 先程入手した`world`ファイルを`/opt/minecraft_server`にアップロード
1. **ディレクトリの権限を変更する←ポイント**
    1. rootユーザーでSSH接続
    2. `/opt/minecraft_server/wold`の所有権を`minecraft`に変更。以下のコマンドを実行する
        3. `chown -R minecraft:minecraft /opt/minecraft_server/world`
1. サーバーを再起動する

# ポイント
Conohaでマイクラサーバーを構築する際にイメージを用いると、`minecraft`ユーザーによりマイクラ関連のファイルが作成されます。しかしConohaからは`minecraft`ユーザーのパスワードは我々には提供されないので、`root`ユーザーでデータのアップロードをすることになると思われます。

そうすると`root`ユーザーでworldをアップロードすることになり、マイクラ実行の際に使われる`minecraft`ユーザーからは参照できなくなってしまい、ゲームをする時にエラーとなってしまいます。

なので`chown`コマンドでファイルを`minecraft`ユーザーの所有物にして、読み込みを正常に行わせます。
テストの組み合わせを洗い出す

テストの組み合わせを洗い出すプログラムを書いてみました。
テストケースを削らせてもらえないストイックな現場にいる人に役立つかもしれません。

# テストの組み合わせ
例えば、性別「男・女」、職業「学生・会社員・その他」の場合、組み合わせは 2 * 3 = 6 通りになります。下表の組み合わせです。

|性別|職業|
|---|---|
|男|学生|
|男|会社員|
|男|その他|
|女|学生|
|女|会社員|
|女|その他|

これくらいだとすぐに書き出せるのですが、パラメータが増えて組み合わせが100通り、200通りにもなった場合、書き出すのが困難になってきます（面倒だし、頭が混乱してくる）
面倒なので、テストケースを削りたくなってきますが、削る基準を考えるのも面倒ですし、ストイックな現場だと100、200程度なら全部やれと言われるでしょう。

# プログラム
そういうときにテストケースを洗い出すプログラムがあれば便利です。
以下、例として、プリンタの詳細設定の組み合わせを出力するプログラムを書いてみます。
<code>combination</code>関数が組み合わせを出力するプログラムになっています。
HTMLファイルとして保存して、ブラウザで開くと、実行できます。

```html:combination.html
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Combination</title>
  <script>
    var p1 = ['Letter', 'A4'];
    var p2 = ['1', '2', '4', '6', '9', '16'];
    var p3 = ['既定', 'なし', '最小', 'カスタム'];
    var p4 = ['既定', 'カスタム'];
    var p5 = ['ヘッダーとフッター', '背景のグラフィック'];
    
    var resultBuffer = '';

    combination(p1, p2, p3, p4, p5);

    function combination() {
      combinationInternal(arguments, 0, arguments[0], '');
      document.write('<pre>' + resultBuffer + '</pre>')
    }

    function combinationInternal(allParams, idx, params, result) {
      for (var i = 0; i < params.length; i++) {
        if (allParams.length - 1 === idx) {
          resultBuffer += (result + params[i] + '\r\n');
        } else {
          combinationInternal(allParams, idx + 1, allParams[idx + 1], result + (params[i] + '\t'));
        }
      }
    }
  </script>
</head>
<body>
</body>
</html>
```

# 実行結果

実行結果は以下になります。
長いので、途中から省略していますが、2 * 6 * 4 * 2 * 2 = 192パターン出力されます。

```none:実行結果
Letter	1	既定	既定	ヘッダーとフッター
Letter	1	既定	既定	背景のグラフィック
Letter	1	既定	カスタム	ヘッダーとフッター
Letter	1	既定	カスタム	背景のグラフィック
Letter	1	なし	既定	ヘッダーとフッター
Letter	1	なし	既定	背景のグラフィック
Letter	1	なし	カスタム	ヘッダーとフッター
Letter	1	なし	カスタム	背景のグラフィック
Letter	1	最小	既定	ヘッダーとフッター
・・・・・・・・・・（省略）・・・・・・・・・・
```
【備忘録】 PATH 関連知識　

# PATHを通す時に、毎回ググってることを列挙

- 「~」 <br> ホームディレクトリを示す
- 「/」 pathの先頭 <br>  ルートディレクトリを示す

## 永続的にPATHを反映させるためには？
自分が利用しているシェルの適当なプロファイル（.zshrc）に定義を追加する。

``` :.zshrc
export PATH=$PATH:追加したいコマンドのパス（絶対パス、環境変数＄HOMEからのパスなど）
```

##　Tips

基本知識が網羅できる[サイト](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)。


### echo
定義されているpathを確認

```
echo $PATH
```

### which
コマンドの実際の格納先

```
which ls
```
### シェルの種類確認

```
echo $SHELL
```

# 今後も整備していく予定
すぐ忘れるからアウトプットしておく。
AWS EC2のRHEL8でTomcatの自動起動を設定する

#Tomcatのインストールはできたけど・・・
自動起動の設定がなかなかうまくいかなかった。最終的にうまくいった方法を書いておきます。

OS：Red Hat Enterprise Linux release 8.2 (Ootpa)
Tomcat：Apache Tomcat 8.5.58

＜説明すること＞
①Tomcatのインストール手順
②自動起動設定

#①Tomcatのインストール手順

/user/local/tomcatにインストールしました

```Bash
#wgetとJavaのインストール
$sudo yum install -y wget 
$sudo yum install -y java-1.8.0-openjdk

$sudo useradd -s /sbin/nologin tomcat
$sudo wget http://ftp.riken.jp/net/apache/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat-8.5.58.tar.gz
$sudo tar -xzvf ~/apache-tomcat-8.5.58.tar.gz
$sudo mv ~/apache-tomcat-8.5.58 /usr/local/tomcat
$sudo chown -R tomcat:tomcat /usr/local/tomcat

#環境変数の設定
$sudo echo "JRE_HOME=/usr/lib/jvm/jre" >>/etc/profile
$sudo echo "CATALINA_HOME=/usr/local/tomcat" >>/etc/profile
$sudo echo "export JRE_HOME CATALINA_HOME" >>/etc/profile
$sudo source /etc/profile

```

#②自動起動の設定

tomcat.serviceを設定します。

```Bash
$ sudo vi /etc/systemd/system/tomcat.service
```

tomcat.serviceの中身は下記のように設定します。

```:tomcat.service
[Unit]
Description=Apache Tomcat 8.5.58
ConditionPathExists=/usr/local/tomcat

[Service]
User=root
Group=root
Type=oneshot
PIDFile=/usr/local/tomcat/tomcat.pid

ExecStart=/bin/bash /usr/local/tomcat/bin/startup.sh
ExecStop= /bin/bash /usr/local/tomcat/bin/shutdown.sh

Restart=no
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

Tomcat.serviceを自動起動設定に入れます。

```Bash
$ sudo systemctl daemon-reload
$ sudo systemctl list-unit-files --type=service | grep tomcat
 tomcat.service                             enabled
$ sudo systemctl enable tomcat
```

出来た！

```Bash
$ sudo systemctl start tomcat
$ sudo systemctl status tomcat
● tomcat.service - Apache Tomcat 8.5.58
   Loaded: loaded (/etc/systemd/system/tomcat.service; enabled; vendor preset: >
   Active: active (exited) since Fri 2020-10-23 14:30:25 UTC; 13h ago
  Process: 5636 ExecStop=/bin/bash /usr/local/tomcat/bin/shutdown.sh (code=exit>
  Process: 5667 ExecStart=/bin/bash /usr/local/tomcat/bin/startup.sh (code=exit>
 Main PID: 5667 (code=exited, status=0/SUCCESS)
    Tasks: 28 (limit: 4855)
   Memory: 134.4M
   CGroup: /system.slice/tomcat.service
           mq5681 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomc>

Oct 23 14:30:25 ip-172-31-37-53.ap-northeast-1.compute.internal systemd[1]: Sto>
Oct 23 14:30:25 ip-172-31-37-53.ap-northeast-1.compute.internal systemd[1]: Sta>
Oct 23 14:30:25 ip-172-31-37-53.ap-northeast-1.compute.internal bash[5667]: Tom>
Oct 23 14:30:25 ip-172-31-37-53.ap-northeast-1.compute.internal systemd[1]: Sta
```

他の方のご説明通りUser、GroupをTomcatに設定してみるもどうしてもうまくいかず（Permission Deniedを突破できなかった）・・・やむなく、良くないのはわかりつつもrootに設定してみたらできました。
[vscode]Rest-Clientのエラー Header name must be a valid HTTP token ["{"] の解決

VSCODEのエクステンション、REST Clientを使っていたら、↓のようなエラーが・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/df687f36-0805-3031-4704-2ea2ba64d5d2.png)

他の箇所でPOSTのリクエストを設定した時は大丈夫だったのに、なんで!?と思ったら、
エクステンションの設定的に、**ヘッダー設定とJSON**の間に空行を入れる必要があった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/444a4e4d-9c92-5dd2-ebac-891fe51f839d.png)

参考資料:https://github.com/Huachao/vscode-restclient/issues/430
C言語+MPIのtips（MPI_Scatter）

MPI_Scatterは「あるプロセスが持つデータを，等分して，各々のプロセスに配分する関数」。

【目的】 
あるプロセスに存在する要素数10の配列 arr を３つずつ各々のプロセスに配分することで MPI_Scatter の機能を知る。

【使用するもの】 
open-mpi

【環境】 
$ mpicc —version 
Apple clang version 11.0.3 (clang-1103.0.32.29) 
 Target: x86_64-apple-darwin19.6.0  
Thread model: posix  
InstalledDir: /Library/Developer/CommandLineTools/usr/bin 

【方法】

```c:Scatter.c 
#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>

#define N 3

int main(int argc, char **argv){
        int my_rank, num_proc;
        int i, div[N];
        int *arr;

        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

        if(my_rank==0){
             arr=(int *)malloc(10*sizeof(int));
             if (arr==NULL){
                printf("arr\n");
                return 1;
             }

             for(i=0;i<10;i++)       arr[i] = i;
        }

        MPI_Scatter(arr, N, MPI_INT, div, N, MPI_INT, 0, MPI_COMM_WORLD);
        printf("my_rank = %d, div[0]= %d, div[1]= %d, div[2]= %d\n", my_rank, div[0],div[1],div[2]);
        if(my_rank==0)  free(arr);        

MPI_Finalize();
return 0;
}

```

【結果】
mpicc コマンドでコンパイル、mpirun コマンドでプロセス数を２にして実行。

```
$ mpicc Scatter.c
$ mpirun -np 2 ./a.out
my_rank = 0, div[0]= 0, div[1]= 1, div[2]= 2
my_rank = 1, div[0]= 3, div[1]= 4, div[2]= 5
```

【考察（何が起きたのか）】 
まずプロセス０と１でそれぞれ div[0]、div[1]、div[2]が生成される。次にプロセス０でarr[0]からarr[9]までがメモリ割り当てされる。for文によって arr[0]=0、arr[1]=1、・・・、arr[9]=9 が格納される。

MPI_Scatterによって「arr」が送信される。「N」個ずつのデータに分割される。データの型は整数（int）「MPI_INT」である。各々のプロセスの「div」がその「N」個の整数型（int）「MPI_INT」のデータを受信する。送信元はプロセス「０」である。

つまり
arr[0]=0、arr[1]=1、・・・、arr[9]=9（at プロセス０）から
at プロセス０　div[0]=arr[0]=0、div[1]=arr[1]=1、div[2]=arr[2]=2 
 at プロセス１　div[0]=arr[3]=3、div[1]=arr[4]=4、div[2]=arr[5]=5
となる。

それぞれのプロセスでdivが表示されて終了。free(arr)でプロセス０のメモリを解放。

【参考】
「mpi 並列プログラミング」と検索すると、より正確でより情報量の多い資料が見つかります。
plantFEMでMPIとOpenMPを一緒に使えるようになりました。

2020.10.24アップデートから、MPIとOpenMPを一緒に使えるようになりました。
端的には、以下のコードが動きます。

```Fortran
program doTest
    ! OpenMPの使用を宣言
    !$use omp_lib

    ! plantFEMの中にMPIのラッパーがあります。
    use plantFEM

    implicit none
    
    ! MPIのラッパーを起動
    type(MPI_) :: mpid

    ! サンプルで作るベクトルの大きさ(rank)
    integer,parameter :: N = 10000
    integer i, a(N),nthreads,myid

    ! MPIを開始。以下、mpid%end()までがプロセスごとに並列に実行されます（プロセス数2）
    call mpid%start()
    print *, "Running MPI with OpenMP"

    ! OpenMPによる自動並列化を開始、各プロセスごとに最大4スレッドを立ち上げて並列化します。
    !$omp parallel num_threads(4)

    ! OpenMPによるスレッド数の取得
    nthreads = omp_get_num_threads()

    ! OpenMPによるスレッドIDの取得
    myid = omp_get_thread_num()

    ! プロセス数、プロセスID、プロセスあたりのスレッド数、スレッドIDを出力
    print *, "nprocess :",trim(str(mpid%petot))," myrank :",trim(str(mpid%myrank)), &
        " nthreads : " ,trim(str(nthreads)), " myid :",trim(str(myid))

    ! ベクトルa(:)に代入
    do i=1,N
        a(i) = i
    end do

    ! 成分をそれぞれ2倍にする
    do i=1,N
        a(i) = a(i)*2
    enddo

    !ここまでがOpenMPによる並列化
    !$omp end parallel
    
    ! mpiを終了
    call mpid%end()

end program

```

plantFEMでは実行時のプロセス数を以下のように設定できます。

```shell_session

./plantfem cpu-core

>>> cpu-core
Current num of cpu-core is :: 1 
Please input num of cpu-core
2
Current num of cpu-core is :: 2 

```

以下では、2つのプロセスのそれぞれで、最大4つのスレッドを動かして並列化しています。
手元の環境では、以下のような出力が得られます。

```
 Number of Core is            2
 Running MPI with OpenMP
 Number of Core is            2
 Running MPI with OpenMP
 nprocess :2 myrank :0 nthreads : 4 myid :3
 nprocess :2 myrank :0 nthreads : 4 myid :3
 nprocess :2 myrank :1 nthreads : 4 myid :2
 nprocess :2 myrank :1 nthreads : 4 myid :2
 nprocess :2 myrank :0 nthreads : 4 myid :3
 nprocess :2 myrank :0 nthreads : 4 myid :3
 nprocess :2 myrank :1 nthreads : 4 myid :3
 nprocess :2 myrank :1 nthreads : 4 myid :3
  ############################################ 
  Number of cores         ::             2
  ############################################ 
  Computation time (sec.) ::     1.8069430000000001E-003
  Computation time (sec.) ::     1.8069430000000001E-003

```

逆に、4プロセスで2スレッドを動かすと、

```
num of process :: 4
 Number of Core is            4
 Running MPI with OpenMP
 Number of Core is            4
 Running MPI with OpenMP
 Number of Core is            4
 Running MPI with OpenMP
 nprocess :4 myrank :1 nthreads : 2 myid :1
 nprocess :4 myrank :2 nthreads : 2 myid :1
 Number of Core is            4
 Running MPI with OpenMP
 nprocess :4 myrank :1 nthreads : 2 myid :1
 nprocess :4 myrank :3 nthreads : 2 myid :1
 nprocess :4 myrank :3 nthreads : 2 myid :1
 nprocess :4 myrank :0 nthreads : 2 myid :1
 nprocess :4 myrank :2 nthreads : 2 myid :1
 nprocess :4 myrank :0 nthreads : 2 myid :1
  ############################################ 
  Number of cores         ::             4
  ############################################ 
  Computation time (sec.) ::     1.8983343999999999E-002
  Computation time (sec.) ::     1.8983343999999999E-002
  Computation time (sec.) ::     1.8983343999999999E-002
  Computation time (sec.) ::     1.8983343999999999E-002
```

スレッド2つもいらんわ！っていうことでmyidは1のみを使っていますね。
今後、ソルバと組み合わせて使ってみたいと思います。
［CentOS8］javacコマンドが使えなかったのでjavaの開発環境をインストール

javaコマンドは元からバージョン1.8のものが入っていて使えたのだが、コンパイルができなかった。

まずはopenjdkをインストール。

```bash

# su
# yum -y install java-14-openjdk-devel
```

これだけでjavacが使えるようになった。javacの本体を探してみると

```bash

# which javac
/usr/bin/javac
```

`/usr/bin/javac`の本体は`/usr/lib/jvm/java-14-openjdk-14.0.2.12-1.rolling.el8.x86_64/bin/javac`。
パスが通っている`/usr/bin/`にシンボリックリンクが自動作成されたというわけだ。

次はjavaコマンドをバージョンアップする。javaコマンドがどこにあるか探してみると

```bash

# which java
/usr/bin/java
```

これも実体は別にあるはずで、

```bash

# ll /usr/bin/java
lrwxrwxrwx. 1 root root 22 10月 24 11:28 /usr/bin/java -> /etc/alternatives/java
# ll /etc/alternatives/java
lrwxrwxrwx. 1 root root 73 10月 24 11:28 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.265.b01-0.el8_2.x86_64/jre/bin/java
```

なるほど。`/etc/alternatives/java`のリンク先を変更すれば良さそうである。
しかしどこを選べば良いのだろう。javaコマンドを探してみる。

```bash

# ll /usr/lib/jvm/*/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/java-14-openjdk-14.0.2.12-1.rolling.el8.x86_64/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/java-14-openjdk/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/java-14/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/java-openjdk/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/java/bin/java
-rwxr-xr-x. 1 root root 11680  9月 10 01:49 /usr/lib/jvm/jre-1.8.0-openjdk-1.8.0.265.b01-0.el8_2.x86_64/bin/java
-rwxr-xr-x. 1 root root 11680  9月 10 01:49 /usr/lib/jvm/jre-1.8.0-openjdk/bin/java
-rwxr-xr-x. 1 root root 11680  9月 10 01:49 /usr/lib/jvm/jre-1.8.0/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/jre-14-openjdk-14.0.2.12-1.rolling.el8.x86_64/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/jre-14-openjdk/bin/java
-rwxr-xr-x. 1 root root 16056  7月 23 21:21 /usr/lib/jvm/jre-14/bin/java
-rwxr-xr-x. 1 root root 11680  9月 10 01:49 /usr/lib/jvm/jre-openjdk/bin/java
-rwxr-xr-x. 1 root root 11680  9月 10 01:49 /usr/lib/jvm/jre/bin/java
```

どれにすれば良いか分からないから、とりあえず`/usr/lib/jvm/java-14-openjdk/bin/java`にする。

```bash

# ln -fs /usr/lib/jvm/java-14-openjdk/bin/java /etc/alternatives/java
```

これでjavaで書いたプログラムを動かせるようになった。以上。
文字列を代入する時に改行やタブをたくさん入れたい時の小技


```
for 変数 in 開始値 ... 終了値 {
                            // ステートメント
                        }
```

こういう文字列を変数に代入して出力したい時、
![スクリーンショット 2020-10-24 12.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332381/82ae5ee8-33a2-f235-6afc-419e79967a38.png)
こんな風に書いてました。醜い・・・。

![スクリーンショット 2020-10-24 12.04.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332381/ffd5ef71-eb19-7e1e-4791-118e885d1909.png)
こっちの方がソースコードがみやすいですね。

```
let string = """
             ここに入れたい文字列をかく。
　　　　　　　　　　　　こんな風にタブ入力が可能になる。
　　　 ここにかくことはできない。"""の後以降にかけば認識される。
　　　　　　　　"""
```
Rails  投稿とユーザーの紐付け

# はじめに
今、メモアプリを開発をしています。
全てのメモの一覧が表示されてしまうのですが、どうにか
メモ一覧ページにログインユーザーのメモのみの一覧を表示したいです。

今回はそれについて学習していきます。

# メモとユーザーの紐付け

まず、各投稿が誰がしたのかを判別するためにnotesテーブル（投稿系のテーブル）に、user_idというカラムをたす。

```
class CreateNotes < ActiveRecord::Migration[5.2]
  def change
    create_table :notes do |t|
      t.text :title
      t.integer :user_id
      t.integer :category_id
      t.text :explanation

      t.timestamps
    end
  end
end
```

```
$ rails db:migrate:reset
```

#メモに投稿したユーザーのidを保存

投稿を保存する際に、先ほど追加したuser_idカラムにも情報を入れる。
[buildメソッドについて](https://qiita.com/mat827/items/c66e0a32a1f1285bdc34)

```notes.controller.rb
def create
    @note = current_user.notes.build(note_params)
    @note.save
    redirect_to notes_path
  end
```

# メモ一覧ページにユーザーの投稿をのみを表示する。

```
 <div class='container'>
   <div class='row'>
    <h2>メモ一覧</h2>
    <table class='table'>
      <thead>
        <tr>
          <th>タイトル</th>
          <th>カテゴリー</th>
        </tr>
      </thead>
      <tbody>

        <% @notes.each do |note| %>
        <% if user_signed_in? && current_user.id == note.user_id %>   #ここを追加
        <tr>
          <td>
            <%= link_to note_path(note) do %>
              <%= note.title %>
            <% end %>
          </td>
          <td><%= note.category.name %></td>
        </tr>
        <% end %>
        <% end %>
      </tbody>
    </table>
   </div>
 </div>

```
メモ一覧のeach文（繰り返し）の中に記述。

```
<% if user_signed_in? && current_user.id == note.user_id %> 
```
この記述でログインしているユーザなのか？とログインユーザーのidとメモを投稿したユーザのidが同じか見ている。

trueなら表示される！
これで大丈夫だと思います！


# 最後に
説明が分かりにくいと思いますが何かの参考になれば幸いです。
また、間違っているところがあればご教授いただけるとありがたいです。
Ruby buildメソッド

# buildメソッド
親モデルに属する子モデルのインスタンスを新たに生成したい場合に使うメソッド。
（親モデルと子モデルは、アソシエーション設定あり）
外部キーに値が入った状態でインスタンスが生成できる。

ユーザーに紐づくメモインスタンスを生成したい場合
※UserモデルとNoteモデルは、１対多のアソシエーションを設定しているとします。

```note.controller.rb
 @note = current_user.notes.build(note_params)  ## 親モデル.子モデル.buildという形式
```
生成されるコメントインスタンスの中身
＊pry-byebugで@noteインスタンスの中身を確認

```
 @note
 id: nil,
 title: "aaa",
 user_id: 2,
 category_id: 1,
 explanation: "ppppp",
 created_at: nil,
 updated_at: nil 
```

user_idに値が入っています。