OmniAICreator/Qiita-1.07M huggingface dataset:
OracleDBでアーカイブ・エラー（ORA-00257）が発生した際の解決法

# 経緯
とある朝、いつものようにOracleDBを利用しているシステムの開発を進めようとしたところ、
以下のようなメッセージが出てきた。

![screenshot1579824739456.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394995/ea33d3f6-ea83-7940-b6f2-1954151db04c.png)

なるほど。なんかわからんけどエラーが発生したようだ。

# 調査
OracleのEnterpriseManagerにアクセスしようとしたところ、見た目は違うが上記と同じエラーメッセージが表示され、ログインすらできない。

調べてみると、今回のエラーは「アーカイブ・ログ」というものが溜まりすぎているのが問題らしい。
社内で聞き取りをしたところ、誰か他の人が**アーカイブ・ログの書き込み設定を無効→有効に変更**していたとのこと。

# 症状の解消手順（暫定対応）
**1. teraterm等でroot権限でログイン**
**2. oracleユーザーに変更**
**3. リカバリマネージャ（RMAN）の起動**
**4. 一定期間(今回は7日間)以上前のアーカイブログを削除**
**5. リカバリマネージャを終了**
**6. oracleユーザーでSQLPlusにログイン**
**7. Oracleインスタンスの起動**
**8. SQLPlusを終了**
**9. リスナコントロールを起動**
**10. リスナを開始**
**11. リスナコントロールを終了**
**12. oracleユーザーからログアウト**
**13. teraterm等を終了**

以下は全て実行するコマンドです。処理結果は記載していません。

```sh
$ su - oracle
$ rman
RMAN> DELETE ARCHIVELOG UNTIL TIME 'sysdate - 7';
RMAN> exit
$ sqlplus [User]/[Password] as sysdba
SQL> startup
SQL> exit
$ lsnrctl
LSNRCTL> start
LSNRCTL> exit
$ exit
```

# 継続的対応
とりあえずOracleは使えるようになったけど、このままだとどうせまた再発するので、アーカイブログを定期的に削除する仕組みを入れることにした。

参考：[アーカイブログの削除方法まとめ（ORA-00257対処方法）](https://www.ashisuto.co.jp/db_blog/article/201803-archive-delete.html)

## 削除バッチ(バッチ？シェル？)の作成

**1. oracleユーザーのホームディレクトリ（今回は`/home/oracle`）直下に、以下の２ファイルを作成する**

```sh:del_arclog.rcv
run{
 # 7日以前を削除
 delete noprompt archivelog until time 'sysdate-7';
 # OSから削除された場合、oracle側も削除する
 crosscheck archivelog all;
 delete expired archivelog all;
}
```

```sh:del_arclog.sh
su -l oracle -c "rman target / @del_arclog.rcv log=del_arclog.log append nocatalog"
```

**2. 上記２ファイルの所有者を、oracleユーザに変更する**
**3. 上記２ファイルに、所有者における実行権限を付与する**
**4. 所有者と権限の設定を確認する**

```sh
$ cd /home/oracle
$ chown oracle:oinstall del_arclog.rcv
$ chown oracle:oinstall del_arclog.sh
$ chmod 744 del_arclog.rcv
$ chmod 744 del_arclog.sh
$ ll
```

▼実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394995/4e189035-a0a7-769d-1655-2c538c2c990a.png)


## crontabにスケジュール登録する

**1. root権限でteraterm等にログイン**
**2. crontabに、指定のスケジュールで`/home/oracle/del_arclog.sh`を実行するように登録**

```sh
$ crontab -e

0 19 * * * /home/oracle/del_arclog.sh   (毎日19時に実行することとした)
```

cronの実行ログは以下のコマンドで確認することができる。

```sh
$ tail -f /var/log/cron
```

## cronのメールスプールを削除する
初期状態では、cronの実行後にrootアカウント宛にメール送信する処理が動く。
が、メール設定をしていない場合にはスプールフォルダにどんどんメールが溜まっていき、
今後はこっちが溢れてしまう。

対策は様々あると思うが、今回は実行結果をメール送信する必要もないが、
メールを送信しない設定に変更するのもちょっと不安なので、
一定期間ごとにスプールのメールを削除する処理を上記同様にcronに登録することにした。


```sh
$ crontab -e

0 19 * * * /home/oracle/del_arclog.sh   (←さっきの)
0 5 * * * cat /dev/null > /var/spool/mail/root  (←今回の。毎朝5時にスプールを上書きする)
```
複数の自動生成されたIDでFirestoreのドキュメントをクエリする

## tl;dr

`.where(firebase.firestore.FieldPath.documentId(), 'in', documentIds)`


## Firestoreで自動生成されたドキュメントIDを使用する動機

FirestoreのドキュメントのIDは規則正しくDocument1, Document2, ...などとふるのではなく、自動生成されたものを使ったほうがよいらしい（[Cloud Firestore のベスト プラクティス](https://firebase.google.com/docs/firestore/best-practices?hl=ja)）。
<img width="854" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152050/5fed4ff1-cfd8-d2f5-111a-c84fc44dc58b.png">

## やりたいこと

**複数のドキュメントを一度にIDで取得したい。** 取得したいドキュメントのIDは自動生成されており、手元にあり、`documentIds`というarrayに入っているとする。


### ひとつのドキュメントの取得はわかる

自動生成されたIDをもつドキュメントでも、一つだけであればかんたんに取得できる。[stack overflow](https://stackoverflow.com/questions/47876754/query-firestore-database-for-document-id)に答えが載っている。
取得したいドキュメントのIDが`"JxiBcP9YflmHbqdC4ndh"`でコレクション名が`"cities"`であるとすると、クエリは

```javascript
db.collection('cities')
  .doc('JxiBcP9YflmHbqdC4ndh')
  .get()
```

とすれば取得できる。問題は取得したいドキュメントが複数ある場合だ。この場合はどうすればいいか？

### 複数ドキュメントの取得（フィールドにもIDが登録されている場合）もわかる

ドキュメント自体に`'doc_id'`などのフィールドがある場合はかんたんにできる。ドキュメントIDでクエリするのではなく、そのフィールドでクエリすればよい。[Cloud Firestore で単純なクエリと複合クエリを実行する(公式ドキュメント)](https://firebase.google.com/docs/firestore/query-data/queries?hl=ja)。`'in'`に関しては日本語版に記載がない…。
[同じページの英語版](https://firebase.google.com/docs/firestore/query-data/queries?hl=en#in_and_array-contains-any)には以下のように記載されている：
<img width="722" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152050/208e3a1f-511c-58ea-3e5a-6f467c25470a.png">


つまり

```javascript
db.collection('cities')
  .where('doc_id', 'in', documentIds)
```

でできる。しかしせっかく自動生成されているのだし、いちいちそれをひとつひとつのドキュメントのフィールドに登録するのも面倒くさく、やりたくない。以下の方法であれば自動生成されているIDでも直接IDでクエリできる。

## 複数ドキュメントの取得(直接IDでクエリする場合)がわからなかった

`firebase.firestore.FieldPath.documentId()`をつかえばよい。

```javascript
import firebase from '@/firebase.js'
db.collection('cities')
  .where(
    firebase.firestore.FieldPath.documentId(),
    'in', 
    documentIds
  )
```
出典はstack overflowの[Query Firebase Firestore documents by the ID](https://stackoverflow.com/questions/48466028/query-firebase-firestore-documents-by-the-id)で、そこでは回答では`1`,`2`,`3`,...とアサインされたIDに対して`<100`という条件でクエリしているが、自動生成されたIDでも使えるし、不等号でなくても`'in'`ももちろん使える。


### 単にドキュメントをちゃんと読めていないだけかもしれない

調べても全然出てこず、やっとstack overflowで答えを見つけたのでこの記事を書いたが、公式ドキュメントのどこかにちゃんと記載されているのかもしれない。その場合はリンクを貼るので教えて下さい。
Rails、PostgreSQL　bundle exec rake db:createコマンドの時のエラー

```
bundle exec rake db:create
```
RailsとPostgreSQLでアプリ作成時、上記のDB作成コマンドでエラーが発生。

```
could not connect to server: No such file or directory 
Is the server running locally and accepting connections 
on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

postgresqlをリスタートすることで解決できました。

```
$ brew services restart postgresql
```
テスト駆動開発をPHPで写経-第2章

PHPで[テスト駆動開発](https://amzn.to/37nji9B)を写経してみたのでその記録です。
本記事では第2章のみ紹介します。

過去記事
- [テスト駆動開発をPHPで写経-第1章 - Qiita](https://qiita.com/jumperson/items/bfab34403afbb02c814a)

# 所感

今回はほぼテキスト通りに行えました

# 実施

Dollarオブジェクトの状態が変わらないことを期待するテストに修正

```diff
diff --git a/tests/MoneyTest.php b/tests/MoneyTest.php
index b753708..d47dc01 100644
--- a/tests/MoneyTest.php
+++ b/tests/MoneyTest.php
@@ -8,7 +8,9 @@ require_once(dirname(__FILE__)."/../src/Dollar.php");
 class MoneyTest extends TestCase {
     public function testMultiplication() {
         $five = new Dollar(5);
-        $five->times(2);
-        $this->assertEquals(10, $five->amount);
+        $product = $five->times(2);
+        $this->assertEquals(10, $product->amount);
+        $product = $five->times(3);
+        $this->assertEquals(15, $product->amount);
     }
 }
```

テスト実行

```
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 18 ms, Memory: 4.00 MB

There was 1 failure:

1) money\MoneyTest::testMultiplication
Failed asserting that null matches expected 10.

/Users/ok/data/projects/tdd-php/tests/MoneyTest.php:12

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
```

状態を変えずに新しいオブジェクトを返すように修正

```diff
diff --git a/src/Dollar.php b/src/Dollar.php
index 8819734..02b1f28 100644
--- a/src/Dollar.php
+++ b/src/Dollar.php
@@ -10,6 +10,6 @@ class Dollar {
     }
 
     function times($multiplier) {
-        $this->amount *= $multiplier;
+        return new Dollar($this->amount * $multiplier);
     }
 }
```

テスト実行

```
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 17 ms, Memory: 4.00 MB

OK (1 test, 2 assertions)
```
Django3でテーブルのカラム(フィールド)名を変更する

# Django3でテーブルのカラム(フィールド)名を変更する方法

pollsアプリの、Questionモデルのpub_dataをpub_dateに変更する。

## 環境

- Python  - 3.6.8
- Django  - 3.0.2
- MySQL   - 8.0.19
- CentOS7.7

## やり方

### 空のマイグレーションファイルを作成

[公式ドキュメント](https://docs.djangoproject.com/en/3.0/topics/migrations/#data-migrations)を参考に、コマンドラインで空のマイグレーションファイルを作成。

```
$ python3 manage.py makemigration --empty [アプリ名]
```
### マイグレーションファイルの編集

すると、アプリ直下のpollsフォルダにマイグレーションファイルが作成される。


```Python:migrations/0002_auto_20200128_0044.py
# Generated by Django 3.0.2 on 2020-01-28 00:44

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('[アプリ名]', '0001_initial'),
    ]

    operations = [
    ]
```

これを以下のように書き換える。

```python:migrations/0002_auto_20200128_0044.py
# Generated by Django 3.0.2 on 2020-01-28 00:44

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('[アプリ名]', '0001_initial'),
    ]

    operations = [
        migrations.RenameField(
            model_name='question', # モデル名
            old_name='pub_data',   # 変更前
            new_name='pub_date'    # 変更後
        )
    ]
```

RenameFieldのところを書き換えれば、カラムやインデックスの追加、削除も同様にできる。詳しくは[公式ドキュメント](https://docs.djangoproject.com/en/3.0/ref/migration-operations/#schema-operations)へ。

### マイグレーションを適用する

最後に、コマンドラインで以下のコマンドを実行して変更を適用する。

```
$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying polls.0002_auto_20200128_0044... OK
```

一応SQL側で確認してみる。

```
mysql> DESC polls_question;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| id            | int          | NO   | PRI | NULL    | auto_increment |
| question_text | varchar(200) | NO   |     | NULL    |                |
| pub_date      | datetime(6)  | NO   |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
```

ちゃんと変わってる:relaxed:

### Django側の修正

model.pyなどのファイルを修正する。

#### 変更前

```Python:model.py
class Question(models.Model):
  question_text = models.CharField(max_length=200)
　# pub_data -> pub_date
  pub_data = models.DateTimeField('data published')

  def __str__(self):
    return self.question_text
```

#### 変更後

```Python:model.py
class Question(models.Model):
  question_text = models.CharField(max_length=200)
  # pub_data -> pub_date
  pub_date = models.DateTimeField('date published')

  def __str__(self):
    return self.question_text
```

## おわり

カラム名を変更する関数名がRenameColumnじゃなくてRenameFieldなのってなんでなんでしょう・・・。

他に良い方法を知ってる方がいましたらご教示ください。
DIコンテナとService Locator

# 本記事について

DIコンテナとService Locatorの違いを整理するために本記事を書きます。
初めに、DIコンテナとService Locatorの説明を行い、その後違いについて説明します。
DIについては [DIを出来る限りシンプルに紹介する - Qiita](https://qiita.com/jumperson/items/b39cc81ada3e57cef6c0) を参照ください。

# DIコンテナとは

DIコンテナはDIで依存性を解決するオブジェクトを管理するオブジェクトです。
ClientクラスがServiceクラスに依存する場合にServiceオブジェクトの登録と提供を行います。

DIコンテナを使用しない場合は以下のようになります。

```kotlin
class Client(private val service: ServiceInterface) {
    fun search(): String {
        return service.request()
    }
}

interface ServiceInterface {
    fun request(): String
}

class Service: ServiceInterface {
    override fun request(): String {
        return "requested"
    }
}

fun main(args: Array<String>) {
    val x = Client(Service()).search()
    println(x)
}
```

DIコンテナを使うとこのようになります。
コンテナの実装は一番簡易な方法を使っています。
コンテナの実装方法はいろいろあるので本記事では省略します。

```kotlin
class Client(private val service: ServiceInterface) {
    fun search(): String {
        return service.request()
    }
}

interface ServiceInterface {
    fun request(): String
}

class Service: ServiceInterface {
    override fun request(): String {
        return "requested"
    }
}

val diContainer = mapOf("s" to Service())

fun main(args: Array<String>) {
    val service = diContainer["s"]!!
    val x = Client(service).search()
    println(x)
}
```

DIコンテナを使用することで複数箇所で依存するオブジェクトを参照するときに同じオブジェクトに依存することができます。

## Service Locatorとは

DIコンテナを使うパターンで誤ってService Locatorになってしまう場合があります。
以下のコードはService Locatorと呼ばれるパターンです。

```kotlin
class Client {
    private val service = diContainer["s"]!!
    fun search(): String {
        return service.request()
    }
}

interface ServiceInterface {
    fun request(): String
}

class Service: ServiceInterface {
    override fun request(): String {
        return "requested"
    }
}

val diContainer = mapOf("s" to Service())

fun main(args: Array<String>) {
    val x = Client().search()
    println(x)
}
```

DIとの違いはClientクラスがDIコンテナに依存しているかどうかです。

## Service Locatorのイマイチな点

Service Locatorのイマイチな点を理解するにはDI導入の流れとクラス図の変化を見ていくとわかりやすいです。

### まずはDIのない設計
![](http://yuml.me/diagram/class/[Application]->[Client],[Client]->[Service])

### DIをするためにInterfaceに依存する設計
![](http://yuml.me/diagram/class/[Application]->[Client],[Client]->[ServiceInterface],[ServiceInterface]^-.-[Service],[Application]->[Service])

これでClientからServiceへの依存がなくなりました

### DIコンテナを使用した設計
![](http://yuml.me/diagram/class/[Application]->[Client],[Client]->[ServiceInterface],[ServiceInterface]^-.-[Service],[Application]->[Service],[Application]->[DICotainer])

### Service Locatorの設計
![](http://yuml.me/diagram/class/[Application]->[Client],[Client]->[ServiceInterface],[ServiceInterface]^-.-[Service],[Application]->[Service],[Application]->[DIContainer],[Client]->[DIContainer])

Service LocatorパターンではClientからServiceへの依存関係をへらすためにDIContainerへの依存関係が増えてしまう点がイマイチな点です。

# DIコンテナのアンチパターン
最後にDIコンテナのアンチパターンについて紹介します。

- Service Locator
    - DIコンテナを使っているつもりがService Locatorになる場合があります
    - 上記の通り依存関係が増えるためアンチパターンにしています
- DIコンテナに登録するオブジェクトがmutable
    - DIコンテナはグローバルオブジェクトと同じためmutableなオブジェクトを登録すると管理が難しくなります
Unityメモ：Microsoft Advertising SDKをUnity上で動かしたい（動かす必要は無くなった）

#Microsoft Advertising は2020/6/1に消えるので皆さんあきらめましょう。
(:3_ヽ)_

[Microsoft Ad Monetization platform shutting down June 1st](https://social.msdn.microsoft.com/Forums/windowsapps/en-US/db8d44cb-1381-47f7-94d3-c6ded3fea36f/microsoft-ad-monetization-platform-shutting-down-june-1st?forum=aiamgr)

##Microsoft Advertising SDKをインストールする
[Microsoft Advertising SDK を使用したアプリでの広告の表示](https://docs.microsoft.com/ja-jp/windows/uwp/monetize/display-ads-in-your-app)

[Unity Ads - Windows Platform](https://forum.unity.com/threads/unity-ads-windows-platform.435998/)

##マイクロソフトがUnity用にWindows Store API プラグインを開発してくれている！
[Unity Plugins - Unity Plugins for Windows Store and Azure](http://microsoft.github.io/unityplugins/)
[microsoft/unityplugins](https://github.com/microsoft/unityplugins)

build.ps1を実行するだけでプラグイン用のパッケージが作成されます。

##PowerShell関連のエラーについて

[PowerShell スクリプトの実行が無効となっている場合の対処法 - カタカタブログ](http://totech.hateblo.jp/entry/2017/09/29/162411)

##nugetが動作しない
https://github.com/NuGet/Home/issues/3975

##サンプル

`Samples\Advertising\VideoAdsSample`にサンプルプロジェクトが吐き出されます。

[初期化や呼び出しなど](http://microsoft.github.io/unityplugins/ads/)

##メモ
[Microsoft Advertising SDK running on Unity without store plugins](https://www.youtube.com/watch?v=6OBZfMKgVhE)
テストのメリットって？

## とある勉強会にて
勉強会で最近気になっていることがあれば教えてください。という優しいお声をいただき「テストコードを書くのって何がメリットですか？」と質問した時のことを書いていきたいと思います。

## テストを書くメリット
<dl>
<dt>仕様書的な役割</dt>
<dd>どういう挙動を期待しているのかテストに書いておくことで、新しくプロジェクトに参加した人も理解しやすい</dd>
<br>
<dt>自分を守るため</dt>
<dd>他者に対して、このプログラムはこのようなテストが通ったという証拠を残せる</dd>
<br>
<dt>複雑な計算</dt>
<dd>テストコードを書いておけば、複雑な計算を検証の度に行う必要がない</dd>
<br>
<dt>自動化、効率化</dt>
<dd>コードにすることで、自動的にテストをしてくれるので効率的</dd>
<br>
<dt>変更に対応しやすい</dt>
<dd>税率変更など、変化があった時にテストを書いていると対応後の検証がしやすい</dd>
<br>
<dt>段階を踏んだ機能</dt>
<dd>例えば3段階あるプログラムで１段階目を修正した時に、テストが全て通れば問題ない等</dd>
<br>
<dt>コードを書き直すタイミング</dt>
<dd>テストがエラーになる際にコードを見直すので書き直すきっかけにつながる</dd>
<br>
<dt>手戻りを減らす</dt>
<dd>この段階まではテストが通ってるから実装できているね、という実証になる</dd>
<br>
<dt>不安を無くす</dt>
<dd>開発者の精神安定剤的な感じ</dd>
<br>
<dt>バージョンアップの時</dt>
<dd>例えばRubyのバージョンを上げて問題なく動くか確かめるとき</dd>
<br>
<dt>綺麗なコードを書けているか</dt>
<dd>綺麗なコードの場合はテストも書きやすい。逆にテストに悩むコードは書き方に問題があるのかもしれない</dd>
<br>
</dl>

先輩方にこんなにたくさんのメリットを教えてもらいました。テスト書きたくなってきたぞ〜！

## TDD(テスト駆動開発)のメリット
TDD（Test-Driven Development: TDD）とは、プログラムを実装する前にテストコードを書き、そのテストが通るように実装・リファクタリングを進める手法です。

<dl>
<br>
<dt>思考の整理ができる</dt>
<dd>思考を整理し、先にアウトプットとしてテストコードを書いた後、インプットとしてプログラムを書く事で自分の中で理解しながら書ける</dd>
<br>
<dt>ゲーム感覚</dt>
<dd>まずテストを書く→通らない、次にプログラムを書く→通るという流れなのでゲームのように楽しみながら書ける</dd>
<br>
</dl>
公衆 Wifi で認証ページへ行けない時の対策

次のようなページが表示されて接続できなかった時の対策です。
![Screenshot_20200128-092204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/00e235ce-a055-3fec-aeec-2994c53e7bfd.png)

次のページにアクセスします。

```text
192.168.8.1
```

Wifi管理者がリダイレクトの設定をすれば解決するのですが、放置されていることがよくあります。

この方法は、次の都市にあるアクセスポイントで確認しました。

```text
埼玉県富士見市
茨城県水戸市
栃木県下野市
栃木県小山市
東京都渋谷区
埼玉県さいたま市
```
MongoDB の dbPath 変更後、`Permission denied: "/path/to/mongod.lock"` を解消する


dbPath 変更後、`Permission denied: "/path/to/mongod.lock"` に悩まされました。権限周りは問題なさそうなのだが。

# MongoDB を停止する

```shell
sudo service mongod stop
```

# データベースの保存先を変更する

```shell
sudo vi /etc/mongod.conf
```

```
#  dbPath: /var/lib/mongodb
  dbPath: /path/to
```

# データベースを移動する

```shell
mv /var/lib/mongodb/ /path/to

sudo chown -R  mongodb /path/to
```

# 一個上のディレクトリに r, x の権限を付与する

```shell
sudo chmod +r /path
sudo chmod +x /path
```

このように**一個上のディレクトリ**に権限を与えたら解決しました。

参考 https://dba.stackexchange.com/questions/254682/permission-denied-on-mongod-lock-despite-it-being-owned-by-mongodb

# MongoDB を開始する

```shell
sudo service mongod start
```

# 環境

- Ubuntu 18.04.3 LTS
- MongoDB 4.0.14
【Ruby on Rails】simple_formatの和訳

単純なフォーマットルールを使用してHTMLに変換されたテキストを返します。 
2つ以上の連続する改行（\n\nまたは\r\n\r\n）は段落と見なされ、`<p>`タグでラップされます。 
1つの改行（\nまたは\r\n）は改行と見なされ、<br/>タグが追加されます。 
このメソッドは、テキストから改行を削除しません。

任意のHTML属性をhtml_optionsに渡すことができます。 これらは作成されたすべての段落に追加されます。

```html
my_text = "Here is some basic text...\n...with a line break."
```

```html
simple_format(my_text)
# => "<p>Here is some basic text...\n<br/>...with a line break.</p>"
```

```html
simple_format(my_text, {}, wrapper_tag: "div")
# => "<div>Here is some basic text...\n<br/>...with a line break.</div>"
```

```html
more_text = "We want to put a paragraph...\n\n...right there."
```

```html
simple_format(more_text)
# => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
```

```html
simple_format("Look ma! A class!", class: 'description')
# => "<p class='description'>Look ma! A class!</p>"
```

```html
simple_format("<blink>Unblinkable.</blink>")
# => "<p>Unblinkable.</p>"
```

```
simple_format("<blink>Blinkable!</blink> It's true.", {}, sanitize: false)
# => "<p><blink>Blinkable!</blink> It's true.</p>"
```
Windowsクライアントでリモートからクライアントにファイル受信をしたいときの対応

#書いてある内容
Windows上のTeratermからリモート側からクライアント側に`scp`でファイルを投げようとしたら`Permission denied(public key)`って言われた時の原因と対策。

#結論
+ コマンドではなくTeraterm自体のSCP機能を使う（Windowsならば）
+ 送信したいファイルの権限や所有者の権限が強い場合にはchmodやchownで変更する

#そもそも、Permission denied(publickey)とは何か
Permission Deniedは何らかの原因でサーバーが接続を拒否してきています。
public key（公開鍵）に問題がある様子。ただ、このエラーの原因はいろいろあるっぽい。

#コマンドではなくTeraterm自体のSCP機能を使用する

|![tera_scp_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541975/61a9b1ca-07fc-03b8-c1c6-322201c1a3a6.jpeg)|
|:-:|

そもそもWindowsOSそのものにはそのままの設定ではLinuxのようにSCPクライアントがないので、上のようにTeratermのSCPクライアントを別途使用して対応するとできるようです。認証情報もログインした際の認証情報をそのまま使っている様子。

##Windows10のOpenSSHを使用する
ただ、Windows10にはOpenSSHクライアントが存在してる様子なので、Windows標準のSSHクライアントを設定することもでき、それでもできる可能性があります（試していません）設定方法は@szlyさんのまとめがわかりやすいので下記に記載

+ [Windows10標準のOpenSSHクライアントを試してみる ＆ 日本語フォルダに注意](https://qiita.com/szly/items/e774961a41895ac50cf4)

#送信したいファイルの権限や所有者の権限が強い場合にはchmodやchownで変更する

##症状
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541975/729c36ea-70f9-694d-7dbc-b2d8e6c7c97f.png)|
|:-:|

通常のテキストファイルを送信する分には使用可能にもかかわらず、EasyRSAなどでクライアント用の認証鍵を作ったのでクライアント送信しようとすると、Teratermのファイル送信機能でもどうしてもうまくいかない。

##原因
`ls -l`で送信したいファイルの状況を見ると、どうやら権限がrootになっている様子。

~~~:ls-l
-rw------- 1 root     root        1696 Jan 27 11:38 authorization.pem
~~~

##解決策
SSHで最初にログインしたユーザーの権限でも使用できるように権限か管理者を変更すると、送信可能です。具体的にはパーミッション（権限）は`chmod`、管理者は`chown`で変更していきます。

###1. chmodで対応する場合

上のケースの対応について考えていきます。ユーザ・グループともにrootが持ってしまっているので、chmodでそれ以外のユーザが読めるようにセットすれば呼び出しが可能です。

下の票を参考に、その他のユーザに対する権限に4を与えてあげます。

|記号|	|数値|対応する権限|
|:-:|:-:|:-:|:-:|
|r|→|4|読み込み可能|
|w|→|2|書き込み可能|
|x|→|1|実行可能|
|-|→|0|権限なし|

~~~:chmod
sudo chmod 604 authorization.pem
~~~

これでダウンロード可能になります。

###2.chownで対応する場合

chownは所有ユーザ・グループを変更するためのコマンドです。
`login-user:login-user`のところで、ユーザ、グループ、の順で指定が可能です。
今回はどちらも変えてしまいます。

~~~:chown
sudo chown login-user:login-user authorization.pem
~~~

この後にTeratermで送信をかけるとうまく送信可能です。
新しい Edge のインストールと日本語

新しい chrome ベースの Edge が利用できるようになりましたので、インストールしてみました。

ダウンロードはこちらから
https://www.microsoft.com/en-us/edge?icid=SMC-IA-4501095


<img width="400" alt="edge01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/90acc3a6-5cd0-6c7f-027d-7ea5f9d31d3e.png">


ライセンス条項の確認をよく読んで、「同意してダウンロード」をクリック。ダウンロードが開始します。

<img width="400" alt="edge04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/58b11194-ca07-6d04-9177-7a9f1ff04d35.png">


インストールが完了すると 新しい Edge が起動し、Welcome 画面が表示されます。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/2de1a180-70d8-cb99-52ec-a02d19bd784e.png">

chrome のブックマークのインポートや新機能の案内が表示されます。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/585b8af1-d35f-8a66-4a48-b3d78235ea6b.png">
<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/9ba0eea5-159f-1e43-36d1-dc56f6c1f032.png">
<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/6c93274b-60e9-5940-6959-37434c7831d3.png">

初めてのインストールだと、英語モードになっています。日本語表示にするため設定を変更します。右上の「・・・」をクリックし、「Settings」をクリックします。さらに左にあるハンバーガーメニューボタン「三」をクリックし、Languages を選択します。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/79a12530-278b-f161-c024-75279bc5e7fc.png">

右上部にある「Add Languages」をクリックすると、中央にダイアログが現れますので、「Japanese 日本語」を探して、チェックを入れ、「Add」ボタンを押します。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/dad9c260-7879-13bc-42ab-06cc2b9367db.png">

Languages に Japanese が追加されました。これを英語より優先するように設定します。Japanese の右のハンバーガーメニューから、「Display Microsoft Edge in this language」にチェックを入れます。また、「Move to the top」をクリックします。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/f9ac36a5-7b80-4d03-1079-770bb3470a79.png">

Japanese の行に「Restart」ボタンが現れますので、クリックします。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/a65dd396-8da7-aacd-05a4-b52a3d2bdbf7.png">

無事、日本語メニューが表示されました。

<img width="400" alt="edge05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177616/3022a238-81e2-9189-9d78-e64b060d6e88.png">
"Error: Could not find the FirebaseUI widget element on the page." の対策。

# 経緯

 - React と Firebase でウェブアプリ開発中
 - [FirebaseUI][1] を使ってログイン機能を実装したい
 - 以下のエラーが発生

[1]:https://firebase.google.com/docs/auth/web/anonymous-auth?hl=ja

```
Error: Could not find the FirebaseUI widget element on the page.
```

ログインページの URL でページを更新するとエラーは出ないのに、React Router で他のページからログインページに飛んでくるとエラーが発生します。。

# 問題のコード

公式サイトに載っているのとほぼ同じ内容のコードです。
エラーでは `ui.start('#firebaseui-auth-container', uiConfig);` で指定している要素が見つからないと言っているようです。

```.jsx
import React from 'react';
import firebase from "firebase/app";
import * as firebaseui from "firebaseui";

export default function TestComponent() {
  const ui = firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(firebase.auth());
  const uiConfig = {
    callbacks: {
      signInSuccessWithAuthResult: function (authResult, redirectUrl) {
        return true;
      },
      uiShown: function () {
        document.getElementById('loader').style.display = 'none';
      }
    },
    signInFlow: 'popup',
    signInSuccessUrl: 'mypage',
      signInOptions: [
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
      ],
    };

  ui.start('#firebaseui-auth-container', uiConfig);

  return (
    <>
      <div id="firebaseui-auth-container"></div>
      <div id="loader">Loading...</div>
    </>
  );
}
```

# 解決策

エラーの内容から `<div id="firebaseui-auth-container"></div>` がレンダリングされる前に `ui.start('#firebaseui-auth-container', uiConfig);` が実行されているようなので、レンダリング後に実行させるように `useEffect` を使います。

```.jsx
import React, { useEffect } from 'react';
import firebase from "firebase/app";
import * as firebaseui from "firebaseui";

export default function TestComponent() {
  useEffect(() => {
    const ui = firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(firebase.auth());
    const uiConfig = {
      callbacks: {
        signInSuccessWithAuthResult: function (authResult, redirectUrl) {
          return true;
        },
        uiShown: function () {
          document.getElementById('loader').style.display = 'none';
        }
      },
      signInFlow: 'popup',
      signInSuccessUrl: 'mypage',
      signInOptions: [
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
      ],
    };
    ui.start('#firebaseui-auth-container', uiConfig);
  });

  return (
    <>
      <div id="firebaseui-auth-container"></div>
      <div id="loader">Loading...</div>
    </>
  );
}
```
FullCalendar イベントを重複させない方法

# はじめに
カレンダー内の赤枠に囲まれたイベントを下のイベントに重ねようとしたときに、禁止マークが出て重ねる事ができないような設定方法についてまとめました。

使用例としては、予約管理システムで時間の重複が許されないようなケースがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/5e5d6d57-76d1-6a2e-3afb-2e0ee79acafb.png)


#### 関連リンク
関連リンクを下記に載せておくので、必要であれば参考にしてください。。

* 【Rails】 5分でFullCalendar実装する方法
    * https://qiita.com/syukan3/items/68280ce4ff45aa336363

# 前提条件

FullCalendarをアプリケーションに実装済みであること。

今回はRailsアプリケーションで実装しています。上記の記事を参考にしてみてください。
Railsを使ったことがない人でも簡単に実装することができますので、この機会にRuby と Railsをインストールして使ってみてください。
※Rails アプリケーション以外でも実装する事ができます。

# 実装
javascript のfullCalendar内に ```eventOverlap: false```を追加するだけで完了です。

```javascript:app/assets/javascripts/application.js
    $('#calendar').fullCalendar({
        // ***省略***

        // month: "月",  agendaWeek: "週", agendaDay: "日"
        // ここ
        eventOverlap: false,

        // ***省略***
```

# まとめ
FullCalendar がとても強力なライブラリとなっているので、爆速で開発を進めたいケースに適用してみてください。

# 参考
* FullCalendar 公式ドキュメント
    * https://fullcalendar.io/

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
MarkdownエディタTyporaの印刷時改ページをちょっと扱いやすくする小技

最強のMarkdownエディタ、Typoraの小技についてです。

Typoraのエクスポート機能を使って、PDFなどを出力するとき、改ページ位置を自分で設定したいことがありますよね？

公式ヘルプの[「Page Breaks」](https://support.typora.io/Page-Breaks/)では、インラインのスタイルシートを使って、改ページ挿入する方法が紹介されています。

```md
<div style="page-break-after:always"></div>
```

しかしこれだと空のブロックなので、プレビューモードでは改ページ位置が見えなくなってしまいます（ただの改行に見えます）。

そこで、プレビュー時には見えるけれど、印刷時には見えなくなる改ページの方法をご紹介します。



## 手順

### 1. カスタムCSSの追加

まず、スタイルシートで、印刷時に非表示になるクラスを追加します。

「設定」→「表示」→「テーマフォルダを開く」のフォルダに、base.user.cssファイルを作りましょう。

カスタムCSSの追加方法について詳しくは、Typoraのヘルプ[「About Themes」](https://support.typora.io/About-Themes/)を参照してください。


```css:base.user.css
@media print{
    .no-print{
        visibility: hidden;
    }
}
```

### 2. Markdown本文に改ページを挿入

本文の改ページしたいところに、この一行をコピペします。「─────改ページ─────」の文字列は、見やすければなんでもOKです。

```md
<div style="page-break-after:always;color:lightgray" class="no-print">─────改ページ─────</div>
```

プレビューモードではこんな表示になります。

![640F5A13-75FB-4EC1-876F-8DEB759717A2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103228/061f50b8-fbd2-012e-fe56-c25ae67b80f2.png)



## 参考ページ

実際適用してみた様子などは、ブログに書いてあるので、興味があれば覗いてみてください👇

 [最強Markdownエディタ「Typora」で改ページを挿入するときの小技―プレビュー時は改ページ箇所を可視化したい―](https://www.creativity-ape.com/entry/2019/11/15/070000)
Androidでsystrace

Androidのsystrace取るのに少しハマったのでメモします。

###### 実行手順
手順は[Android developers](https://developer.android.com/studio/profile/systrace/command-line?hl=ja)に記載されている通りなのですが、pythonは2.7系でないとダメでした。
参考：[Windowsにpythonをインストール](http://yoshihiro-kato.blogspot.com/2017/06/windowspython.html?m=1)

###### 不足パッケージの追加
また、pywin32をインストールしないと下記のエラーとなります。
`ImportError: No module named win32con `

pywin32は下記のコマンドでインストールできます。
`pip install pywin32`

pipはインストールしたpythonのScriptsフォルダ内にあり、pathを通していればそのまま使えます。
ただし、proxy環境では、オプションでproxyを設定する必要があります。
` pip --proxy=xxxx.com:80 install pywin32`
【メモ】JSUG勉強会 2020その1 Spring x Kotlin

[JSUG勉強会 2020その1 Spring x Kotlin](https://jsug.doorkeeper.jp/events/102390
)に出席した際に取ったメモを共有します。

非常に簡易的ですが、少しでも参考になれば幸いです。

# [KotlinでSpring 完全理解ガイド](https://speakerdeck.com/ntaro/kotlindespring-wan-quan-li-jie-gaido-number-jsug) (@ngsw_taro さん)

## XXを使えばKotlinで簡単にSpring開発を始められる
Spring Initializr
Intellij IDEA(有償版)

## Kotlinでもアノテーションを使ってbean登録やハンドラ定義

Kotlinはデフォルトで継承しないため、serviceクラスにopen修飾子をつける必要がある。
がKotlinのallopenプラグインやkotlin-springプラグインを用いれば、自動でopen扱いしてくれる。

ちなみにSpring Initializrで生成したプロジェクトには最初から設定されている。

バリデーションに注意が必要。
Javaの感覚で

```
class Body {
	@NotNull val value: Int
}
```
と書くとバリデーションがかからない。

```
class Body {
	@field:NotNull val value: Int?
}
```

こう書く。

## Kotlin用DSLを使った比較的新しいbean登録やハンドラ定義
Bean Definition DSL
Router DSL

## Linter
ktlint　いわゆるLinter兼Formatter
Gradleプラグインがある。
IntelliJ IDEA用の自動設定もある。


## WebFluxでKotlinのコルーチンが便利
Kotlinにはコルーチンがある。
Reactor対応のライブラリが公式である。

## Ktorがいい感じ
・JetBrains公式
・非常に薄く、余分な機能は3rdパーティー任せ
・DSL
・ノンブロッキング

## KotlinでもJunitを使ったテスト
Kotlin用の拡張関数 expectBodyを使う。
アサーションライブラリはAssertJを使っている。(もちろんKotlin対応)
メソッドチェーンで書いていく感じが気に入っている。

また、assertkが気になっている。

## KotlinでモックするならMockKがいい感じ。
コルーチンの場合も対応。

## おまけ：DBアクセスはどうしているか
JDBCテンプレートを使っている。
生SQLを書いて、クラスに地道にマッピングしている。
exposedもJetBrains製で良さそう。

# [Spring 5.2におけるKotlinサポート](https://www.slideshare.net/HayatoKihara/spring-52kotlin-225154880)(@gumimin さん)

Spring 5.2からSpringの公式ドキュメントにKotlinのコードも追加された。

## Router Functions
従来のアノテーションベースとは異なる新たなルーティング方法
WebFlux.fn → Spring 5から
WebMVC.fn → Spring 5.2から
Functionalなルーティング方法

## MockMvc DSL
以前のメソッドチェーンよりもスッキリしてわかりやすい

## @ConfigurationProperties
複数のプロパティへ一括でバインディング
Relaxed Bindingが効く

Boot 2.2.1から@ConstructorBindingでコンストラクタを通じimmutableで設定値を取得できる。
@Compornent や @EnableAutoConfigurationが必要になった。

## コルーチン対応

コルーチンとは
・処理の中断/再開が容易な計算インスタンス
・計量スレッドみたいなもの
・async/awaitスタイルで記述できる
・スコープの概念により、コルーチン同士の依存関係を管理しやすい
・他のReactive Streamsに準拠したデータ型への変換モジュールが提供されている

WebFluxのコルーチン対応によってReactorではなくコルーチンの型を使用できるようになり、よりKotlinらしく、簡単に並列処理ができるようになった。

Reactiveにプログラミングできるとパフォーマンスがかなりよくなる。

## おまけ
[The State of Kotlin Support in Spring](https://www.youtube.com/watch?v=U4Q13TlAUE8) がオススメ動画

# 感想
KotlinでSpring Bootを書く際の注意点やコツのようなものがかなり学べて良かったです。
自分もSpring Initializrから始めていこうと思います。

また、Web Fluxについて単語は聞いたことがあるレベルだったので、もう少し概念を理解し、実際にJavaでも良いので書いてみようと思いました。

改めまして、登壇者・運営の皆様本当にありがとうございました。
[Rails6.0]rails db:migrateをする際に発生したDirectly inheriting from ActiveRecord::Migration is not supported.の解決法

gemのpaperclipを使うため```rails g paperclip post image   ```を実行してマイグレーションファイルを生成。

その後```rails db:migrate ```したら

```
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

```
というエラーが発生。

以下のサイトを参考にしたところ、

[【rails5.2.0】rails db:migrateをする際に発生したDirectly inheriting from ActiveRecord::Migration is not supported.の対処法について](https://www.for-engineer.life/entry/rails5-migration-error/)

どうやら原因はマイグレーションファイルがrailsのバージョンに対応していないことが原因のようだった。

##解決法

参考サイトではRails5.2の話だったが、6.0でも通用するのか試しにやってみた。

```20200127214811_add_attachment_image_to_posts.rb
class AddAttachmentImageToPosts < ActiveRecord::Migration[6.0] #←[6.0]を追加
  def self.up
    change_table :posts do |t|
      t.attachment :image
    end
  end

  def self.down
    remove_attachment :posts, :image
  end
end
```

これで```rails db:migrate ```をしたら無事成功しました。


##学んだこと

マイグレーションファイルがRailsのバージョンにたいおうしていなかったら、ファイルのクラス部分にバージョンを指定してあげる。
初心者が覚えておくべきLinuxコマンド

IT業界にいる年数はそこそこあるけど、業務はWindows系ばっかりだったので、ほぼLinux触ってこなかったエンジニアが、最近は必要に迫られてLinuxコマンドを叩くようになりました。
特に開発環境構築。
手順のマニュアルにコマンドが列記されていることが多いですが、「シェルを叩く」だけ書いてあったりすると、「シェルを叩くコマンドってなんだっけ？」となったりして困りました。
ですので、この機会に、「最低限、暗記しておくべきコマンド」だと思ったものを記事に残します。

# pwd
現在いるパスを表示する。
`pwd`
GUIに慣れている人間だと、CUIで作業中に迷子になりやすくて、何度もこれを叩くことになります。

# ls
ファイル一覧を表示する。
`ls -[オプション]`
押さえておくべきオプションは以下かと。
- a：隠しファイルを含め、全て表示する
- l：ファイルの詳細も表示する。環境構築時はパーミッションを何度も確認することになる。

# cat
ファイルの中身を表示する。
`cat memo.txt`
とりあえず何が書いてあるのかを確認するのに必要。

# mkdir
フォルダを作成する。
`mkdir work_space`
作業フォルダを作る時に。

# cp
ファイルとかディレクトリのコピー。
見本ファイルが配布されているのを、自分のところにコピーする時に使う。
`cp hoge.txt dir`
このコマンドで「hoge.txtをdirフォルダに移動」となる。
「今いるディレクトリにあるファイル全部コピーする」とか「リネームしてコピーする」という方法もあるので、そういうオプションがあると覚えておいて、最初のうちはぐぐる。
何度もやっているうちに暗記できるようになるので、それまで頑張る！（けど時間が経つと忘れる）。

# touch
ファイルのタイムスタンプ操作だけど、環境構築時は新規にファイル作成時に使う。
`touch hoge.txt`
これでhoge.txtが作られるので、viコマンドで編集していく。

# vi
テキストエディタ起動のコマンド。
`vi hoge.txt`
これでhoge.txtを編集することになりますが、ここからがGUIに慣れた人間が混乱するところ。
コマンド打った直後は閲覧モードなので、いくらキーボードを叩いても編集できない。
なので、ここから編集モードに入らなければいけない。
編集モードに入るにはいくつかキーがあるけど、初心者だったら迷わず`i`をお勧めする。
そして入力が終わったらエスケープキーを押して、`:wq`と入力。
これで「入力した内容を保存して、viから抜ける」となる。
あるいは`:q`ならば、保存しないで終了。
最低限、ここだけ押さえておけば、開発環境構築には足りるはず。

# .(ドット)
ファイルからコマンドを読み込み、実行する。
`. ~/.bash_profile`
最初、ドットが何か分からずに混乱したけど、立派なコマンドです、打ち忘れたらいけない。
開発チームにいる親切な人が組んでくれたシェルスクリプトを実行したり、Linuxを再起動せずに初回起動時のみ読み込まれるファイルを再読み込みさせたりするのに使う。

以上、自分が暗記してなくて苦労したので、最初から覚えておくべきだったなぁと思ったコマンド達でした。
他にも「これは覚えておけ！」というのがありましたら、コメントから教えていただけると嬉しいです。
redirect_toとrenderの違い

初投稿です！
説明が足らないと思いますが、見てください！

#**redirect_toとrenderの違い**



![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538880/dc65bc70-3f55-4381-d01b-c58c62cc9fb2.jpeg)

redirect_toはroutingとcontrollerを通ってviewを表示していますが、renderはいきなりviewを表示させています。
redirect_toでは新たなリクエストがされたのと同じ動きになりますので、controllerを経由してviewが表示されます。
これによって、元のインスタンス変数が上書きされるかどうかが違います。

4行目:redirect_to
6行目:render


```rb

def create
  @group = Group.new (params)
  if @group.save
    redirect_to root_path, notice: "グループが作成されました！"
  else
    render :new
  end
end
```
【可視化】Bar Chart Raceで「あいみょん」を見える化してみた。

## 概要

2019下期あたりから、やたらと賑わっているらしい、
**「Bar Chart Race」でそれっぽく可視化してみた。**めちゃ、面白い！！
時間軸（年／月／…秒、漫画なら巻数とかもありかも）と、その時の値を表現できるグラフです。

![BarChartRace_Aimyon.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/42ebd3a2-9740-05c7-2c4e-0b1b0a21ac2c.gif)
これは**「あいみょん」のBillboard JAPANのストリーミングチャートの順位を1週間単位**で表現してます。




## 利用したサイト
- **flourish**
　　<https://app.flourish.studio/projects>
　　いわゆるBIツールで、Web上でサクサク出来るサイト。無料です。
　　Bar Chart Race以外にも沢山の可視化パターンがあって、おもろいです。

- **Qiita**
　　https://qiita.com/okd46/items/016e84611c89dbcf457a

- **youtube**
　　<https://www.youtube.com/watch?time_continue=297&v=Og847HVwRSI&feature=emb_logo>
　　各種言語の使用率を表現したもの。
　　Javaの勢いがスゴイ！そして、Pythonで拍手しました（笑

## ネタ探し

せっかくやるんだから、何か面白い題材ないかな～って1日探しました。

### データってお金になる！
ここで分かったのは、**統計データって本当に金になるんだ！**ってことです。
政府系のデータ（各都道府県の人口増減とか、訪日旅客者の国別推移とか）はありますが、
エンタメ系ってなかなか統計データは見つかりませんでした。

### Google Dataset Searchはどうだろう？

最近、話題になった「Google Dataset Search」*1で調べたけど、基本は有料でした…。

 *1  機械学習用のデータセットをインターネット上から検索可能
 <https://gigazine.net/news/20200124-google-dataset-search/>

普通のGoogle検索だと、ランキングは出るけど、**あくまでもランキングで、
具体的な数値にはなっていないんです…。**それか、その日の断面の情報のみ、とか。

で、youtubeにネタないかな～って見たら、結構エンタメ系は既にやられてました (*´Д｀)ｱﾜﾜ


### よし、ニッチを攻めよう！

これは、ニッチな領域で攻めるしかない！と思い、少し考えました。

- スラムダンクの山王戦の得点をチャートにしようかな？
　→ 決めた時間が不明…

- ドラゴンボールの戦闘力とか楽しそうかも！
　→ ちょっとインフレしすぎて、意味不明になりそう…

となってくると、何かニッチで良い感じなのないかな～。



## 「あいみょん」いいじゃん！

で、作りました。

- Inputデータ  
  見えない部分は適当に情報補間してます（笑
  <https://seikatsusha-ddm.com/article/09897/>  

　で、順位が高いほどバーの長さを長くしたいので、
　元データを正規化（各値を-115し、未発売は0、まったくDLされてないのは1に）してます。

- TOPの動画と同じです。  
  <https://public.flourish.studio/visualisation/1290534/>

ふむふむ、マリーゴールドの影響力ものすごい！！



## 結論

**人に楽しく見てもらう、って大事。**

で、これをPythonとかでも出来るっぽいので、ちょっと実装してみたい。
「⌥」←この「ン」を左右反転させたような、「リ」を時計回りに90度回転させたような、少し傾いて影がついた立体的な「T」のようなMacの修飾キーって何？

# はじめに

「⌥」←この「ン」を左右反転させたような、「リ」を時計回りに90度回転させたような、少し傾いて影がついた立体的な「T」とも捉えられるMacの修飾キーを明らかにする。

# ズバリ

`option`あるいは`alt`である[^Macのメニューに表示される記号 - Apple サポート]。

完。

# おわりに

ショートカットキーを調べて、いざ試してみようとしたときに「⌥」という記号が何なのかわからないということがあった。キーボードによっては`option`あるいは`alt`キーに「⌥」という記号が書いていないことが原因である。似たような状況の人が、「⌥」が何なのかを把握するために検索することがあるであろう。そのときに、どんなキーワードを検索するのが最適かわからない人が、例えば「修飾キー ン」や「修飾キー リ」と検索した場合に、この記事を見つけ、「⌥」が何なのかを把握する手助けになったら本望である。

# 豆知識

- 「⌥」←この記号は回路図のSPDT（Single-Pole Double-Throw）スイッチが由来であるという説がある[^What is the origin of the Mac's 'option key' symbol (⌥)? - Quora] [^Mac の特殊キー記号の由来 - 情報と音楽]。
- キーボードの印字によっては、少し傾いて影がついた立体的な「T」に見えない。

[^Macのメニューに表示される記号 - Apple サポート]: [Macのメニューに表示される記号 - Apple サポート](https://support.apple.com/ja-jp/guide/mac-help/cpmh0011/10.15/mac/10.15)

[^What is the origin of the Mac's 'option key' symbol (⌥)? - Quora]: [What is the origin of the Mac's 'option key' symbol (⌥)? - Quora](https://www.quora.com/Computer-Keyboards/What-is-the-origin-of-the-Macs-option-key-symbol-%E2%8C%A5)

[^Mac の特殊キー記号の由来 - 情報と音楽]: [Mac の特殊キー記号の由来 - 情報と音楽](http://penguinlab.jp/blog/post/2035)
DynamoDBのチュートリアルを読み解く【1: ストリームが有効になった DynamoDB テーブルを作成する】

# はじめに
DynamoDBについて勉強がてら[チュートリアル](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.Lambda.Tutorial.html)をやろうと思い、ただ実行するだけなのも芸がないのでコマンドのオプションがどういう意味なのか調べながらやりました。
その結果、手順の１つ目（テーブル作成）だけになってしまいましたが……。

（2020/1/29追記：タイトルを修正しました）

# 1-1.テーブル作成コマンド
コマンドはチュートリアルより。

	aws dynamodb create-table \
	    --table-name BarkTable \
    	--attribute-definitions AttributeName=Username,AttributeType=S AttributeName=Timestamp,AttributeType=S \
    	--key-schema AttributeName=Username,KeyType=HASH  AttributeName=Timestamp,KeyType=RANGE \
    	--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
    	--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

# 各オプションについて

## --table-name

- 書式: --table-name (value)
作成するテーブル名を指定。

## --attribute-definitions

- 書式 : --attribute-definitions AttributeName=(Value)

キースキーマを記述する属性の配列。

## --key-schema

- 書式 : --key-schema AttributeName=<value>,KeyType=HASH|RANGE
主キーを構成する属性。
  - AttributeName : 属性名
	- KeyType : キー属性の役割
		- HASH : パーティションキー
		- RANGE : ソートキー
		
## --provisioned-throughput

- 書式 : --provisioned-throughput ReadCapacityUnits=(value),WriteCapacityUnits=(value)
プロビジョニングされたスループット設定。（詳細は後述）
 - ReadCapacityUnits : 読み込みキャパシティユニット(RCU)の数
 - WriteCapacityUnits : 書き込みキャパシティユニット(WCU)の数

## --stream-specification

- 書式 : StreamEnabled=true,StreamViewType=KEYS_ONLY|NEW_IMAGE|OLD_IMAGE|NEW_AND_OLD_IMAGES
- 
テーブルのDynamoDBストリームの設定。

 - StreamEnabled : DynamoDB Streamsを有効にするか無効にするか
 - StreamViewType : テーブルのアイテム変更時にテーブルのストリームに書き込まれる情報。
   - KEYS_ONLY : 変更されたアイテムのキー属性のみ
   - NEW_IMAGE : アイテム全体
   - OLD_IMAGE : 変更される前に表示されていたアイテム全体
   - NEW_AND_OLD_IMAGES : アイテムの新しいアイテム画像と古いアイテム画像の両方

# キャパシティユニットについて
キャパシティユニット（以降CU）が何かを説明する前に、DynamoDBの課金要素を知っておく必要があります。
DynamoDBの課金要素は下記の3つになります。
　① テーブルに対して読み込み/書き込みを行ったデータ量
　② DynamoDBへのデータ保管量
　③ DynamoDBまでのデータ転送量（厳密にはDynamoDB自体の課金ではありませんが）

ざっくり言うと、CUとは「読み込み/書き込みの単位（サイズ）」のことで、
DynamoDBでは1秒間にどれだけ読み書きが発生するかを予め見積もり、その分のCU（読み込みと書き込みそれぞれ）を購入して割り当てる必要があります。
（以降、読み込みCUはRCU、書き込みCUはWCUと記載）

RCUは4KB単位、WCUは1KB単位で計算されます。
つまり、1RCUで4KBのレコード読み込み、1WCUで1KBのレコード書き込みが可能です。
（結果整合性読み込みを行わない場合、1RCUで2回の読み込みが可能）

先述のテーブル作成コマンド内の「ReadCapacityUnits」「WriteCapacityUnits」がそれぞれいくつのCUを割り当てるかを決めるオプションになります。
また、CUは1秒間のキャパシティを決めるものです。今回の場合、1秒間に5RCU/5WCUが割り当てられています。
（ちなみに5というのがデフォルトのようです）

このように予めDynamoDBのキャパシティ（厳密にはスループットかも）を見積もる方式を「プロビジョニングモード」と言います。CU単位ではなくリクエスト回数での課金とする「オンデマンドモード」というのもありますが、料金は前者よりお高くなるようです。

# 参考URL
https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html

https://www.magata.net/memo/index.php?DynamoDB%A4%CE%A5%AD%A5%E3%A5%D1%A5%B7%A5%C6%A5%A3%A5%E6%A5%CB%A5%C3%A5%C8%A4%CB%A4%C4%A4%A4%A4%C6

https://dev.classmethod.jp/cloud/aws/optimize-costs-of-dynamodb/
【jQuery】セレクトボックスから取得した日付を現在と比較する

#はじめに
セレクトボックスから日付を取得し、`現在の日付`と比較していきます。

#参考文献
「jQueryのchange()で値が変更されたら発動」
https://www.flatflag.nir87.com/change-1761
「どうしても「今日の0時」が欲しかった」
https://qiita.com/Bong/items/dc632edb6fe3d44f2d5b

#現在の日付の取得方法
まずは`現在の日付`を取得します。

```javascript:JavaScript
  var current_date = new Date(); //現在時刻の取得
  current_date.setHours(0, 0, 0, 0);  //時間を00:00:00にする
  console.log(current_date); // => Mon Jan 27 2020 00:00:00 GMT+0900 (日本標準時)
```
今回セレクトボックスでは、時間を入力する項目がなく、`00:00:00`で入力されてしまうため
イコールのパターンを再現するために時間を`00:00:00`にします。

#セレクトボックスからの日付取得

最初に年・月・日の３つのセレクトボックスを作成し、各々に`id`を設定していきましょう。

```erb:erb
<div class="form-select-date">
  <%= form.select :date, (1930..Time.now.year).to_a, {selected: hoge}, {id: "year"} %>
  <%= form.select :date, (1..12).to_a, {selected: hoge}, {id: "month"} %>
  <%= form.select :date, (1..31).to_a, {selected: hoge}, {id: "day"} %>
</div>
```

次に、JavaScriptの方でセレクトボックスから値を取得し、`現在の日付`と比較します。
試しに今回は、現在日時と同じ数値を入力してみます。

```javascript:JavaScript
$('.form-select-date').change(function() {   //セレクトボックスを切り替えるたびにvalue値を出力
    var year = $("#year").val();  // year = 2020
    var month = $("#month").val();  // month = 1
    var day = $("#day").val(); // day = 27
    var input_dates  = new Date(year, month, day);
    console.log(input_dates); // => Thu Feb 27 2020 00:00:00 GMT+0900 (日本標準時)
```

`2020年1月27日`と入力したはずなのに、`2月27日`と出力されてしまいますね。。
JavaScriptでは、月が`0~11`となっているため、`1 => Feb`と出力されます。
つまり、`-1`をしてあげないと正しい値にならないということです。

###修正方法
`new Date`の引数部分を以下のように変更してあげましょう！

```javascript:Javascript
 //(中略)
 var input_dates  = new Date(year, month-1, day); //月を-1する
 console.log(input_dates); // => Mon Jan 27 2020 00:00:00 GMT+0900 (日本標準時)
```
これで入力された値を正しく取得することが出来ます！

#比較

現在日時と入力された日時を比較していきます。

```javascript:Javascript
    if (input_dates > current_date) {
      console.log("未来です");
    } else if (input_dates < current_date) {
      console.log("過去です");
    } else {
      console.log("今日です");   // "今日です"が出力される
    }});
```

これで`現在の日付`と、セレクトボックスで`入力された日付`が比較出来ました！


#最後に
月の入力した値がずれたり、**JavaScriptの日付の扱いはクセがある**ので
日付を扱う際には、注意していこうと思います。
Huskyを入れてもgitのhookが動かない

[husky@4.2.1](https://github.com/typicode/husky/tree/v4.2.1) + lint-stagedでpre commit時にprettierを動かそうとしたんだけどうまく動かなかった。

```
$ ls .git/hooks
```
してみてもhookが生成された形跡なし。

## 結論

結論からいうと `ローカルのgitバージョンとhuskyのバージョンの問題` でした。

[husky@4.2.1](https://github.com/typicode/husky/tree/v4.2.1)の対応gitバージョンは
> Verify that your version of Git is >=2.13.0.

ということで2.13.0以上。
対して自分のPCのローカルgitバージョンは2.11.0。

## ローカルgitバージョンを上げずに対応

単純にローカルgitバージョンを上げれば対応できそうだが、チーム開発だと全員のgitバージョン揃えるのもめんどそうなので（gitはそんな頻繁にバージョン上げないだろうし）低いgitバージョンでも動かせるように対応。

```
$ yarn add -D husky@2.7.0
```

これで無事hookが生成されgit@2.11.0でも動くようになりました。
Apache configtestコマンド gracefulコマンド

#はじめに
本番環境でhttpd.confファイルを更新した際に、適応する方法を知らなかったため、手順をメモしておく。

##configtestコマンド
httpd.confファイルを修正すると記述しているファイルが構文エラーを起こしていないかをチェックしたい時
`$ service httpd configtest`でエラーが起きていないかを確認できる

```console
$ service httpd configtest  
Syntax OK
```
上記のように`Syntax OK`と表示されれば構文エラーはない

##gracefulコマンド
本番環境の場合、ユーザーが使用している可能性があるため、Apacheをhttpd.confを適応するために再起s（restartコマンド)することはできない。
そのためhttpd.confファイルを反映させる時は`$ service httpd graceful`で反映させる。Apacheを止めずに設定を反映させることがきるためです。


以上の2つのコマンドを使用することによって本番環境にApacheの設定を安全に適応することができる。
Angularの依存性解決の流れ

AngularはDI（Dependency Injection）の機構を備えており、constructorなどを通じてサービスなどをコンポーネントへ注入することができます。
サービスの`@Injectable`デコレータで`providedIn: 'root'`と書いておけば、もう何も考えることなくconstructorでサービスクラスを指定して利用できる優れモノですが、はたしてAngularはどのようにして注入するものを探してくるのでしょう。

# 注入物は一体どこから来るのか

動作を確認するためにこんな感じのサンプルを用意します。

```
AppModule ─────┐
│ AppComponent │
└─┬────────────┘
  └ ParentModule ─────┐
    │ ParentComponent │
    └─┬───────────────┘
      └ ChildModule ─────┐
        │ ChildComponent │
        └────────────────┘
```

各モジュール、各コンポーネントにはそれぞれプロバイダを持たせ、注入物の出自がわかるようにします。

```typescript:app.module.ts
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, ParentModule],
  providers: [{ provide: AnyService, useValue: { injectLevel: 'root' } }],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

```typescript:app.component.ts
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [
    { provide: AnyService, useValue: { injectLevel: 'root component' } }
  ]
})
export class AppComponent {
  constructor(public anyService: AnyService) {}
}
```

各コンポーネントではconstructorで`anyService`を注入し、`injectLevel`（サービスが提供される階層）をViewに表示させます。

```html:app.component.html
<div>root: {{ anyService.injectLevel }}</div>
<app-parent></app-parent>
```

```html:parent.component.html
<div>parent: {{ anyService.injectLevel }}</div>
<app-child></app-child>
```

結果は以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/83399848-086f-aa66-2a69-2de6bd9f3ed0.png)

当たり前ですね。自身のコンポーネントクラスで欲しいものが提供されているのだから、もちろんそのまま注入されています。
では、ChildComponent -> ParentComponent -> AppComponent と順番にコンポーネントクラスのプロバイダを削除していくとどうなるでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/00adf971-6989-ce77-f522-bfdbd17f7cef.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/982544f4-9e4b-c3ea-7753-53ce789f8b6c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/14ba44da-c72b-7454-54eb-ec4336edf998.png)

自身のコンポーネントクラス内に注入対象が提供されていない場合、Angularは親クラスへ遡ってプロバイダを探します。
rootコンポーネント（ここではAppComponent）まで遡り、なお見つからない場合はrootモジュール（ここではAppModule）を探しに行きます。

ではrootモジュールにもプロバイダがない場合、Angularはエラーを返すのでしょうか？
さらにプロバイダを削除していくと、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/5f7f3a0a-9c55-bd19-b0a7-6b11d14a48c4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/47cb5c2b-dfc7-d14d-900f-5c107f2b1480.png)

rootモジュールにプロバイダがなかった場合、Angularはrootモジュールの`imports`をたどってさらにプロバイダを探します。
rootモジュールが出発点であるため、ParentModule -> ChildModule の順番となっています。
すべてのモジュールを走査してなおプロバイダが見つからない場合、`NullInjector`がエラーを返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460735/e90aa845-035b-daaf-d6d0-d5a86ab53a7a.png)

# まとめ
AngularがDIを要求したクラスから出発して依存性を解決していく流れを追いかけました。

- DIを要求したクラス自身がプロバイダを持っている場合は、それを優先する
- 自身がプロバイダを持っていない場合、先祖をたどってプロバイダを探す
- rootモジュールまで到達したら、importsのモジュールをたどってさらにプロバイダを探す

プロバイダの位置を工夫することによって、DIトークン（ここでは`AnyService`クラス）が同じであっても全く違うものを注入させたり、注入可能な範囲を制限したりすることができます。
ですが、特別な理由がなければ`providedIn: 'root'`でいいんじゃないかと個人的には思います。
お絵かきできるSNSを作りたい！

小生ペンタブ端末が大好きです。
そんな私はADB接続の頃から使っていて、歴代のペンだけで10本以上持ってます。

みなさんペンタブ使ってますか？

アプリ何を使っていますか？
Photoshop？クリスタ？Procreate？

どれも素晴らしい。
だが、私はあえて使いたい。
ブラウザが1番だと！

去年こんな記事を見かけました。
[Web上でお絵描きしやすくなるキャンパスの改善や数字の可読性を向上させるセパレーターなどが含まれるGoogle Chrome 75安定版リリース](https://gigazine.net/news/20190605-google-chrome-75/)

そうです、今こそブラウザー！
ということで、タイトルの通り お絵かきできるSNS を作りたく
すごく今更ではありますががCanvasを使ったiPadで動くSNSサービスを作りたいと思っています。
目指す理想郷はmixi+お絵かきサイト。

次：[お絵かきできるSNSを作りたい！2](https://qiita.com/cardcapt/items/dc7919ad7c06a69cc5cc)
【サルが書く】Laravelでファイルが存在するかを確かめる

うっきょ

ファイルが存在するかを確かめたい。
PHPには[file_exists](https://www.php.net/manual/ja/function.file-exists.php)がありますが、Laravelライクで書いていきたい。
なので、Fileファサードを使用してファイルが存在するかを確かめます。

## 用法

```php
<?php
use Illuminate\Support\Facades\File;

.
.
.

$filepath = '/dir/hoge.txt';

if (\File::exists($filepath)) {
    echo "$filepath が存在します";
} else {
    echo "$filepath は存在しません";
}
```

## 使用場面
使う場面としては `File::delete()` を使用して、ファイルがちゃんと消えているかを確認する際に `File::exists` を使用して、ファイルが消えていることを確認できます。

## 参考資料
http://recipes.laravel.jp/
【Laravel】 ModelクラスからQueryBuilderクラスを分離させる

# 概要
LaravelだとGlobalScopeを作成して、scopeメソッドをModelクラスから分離させることができる。

しかし、Eloquentに依存してしまうため、DBファサード等を使用してQueryBuilderのみを使用する場合に、クエリの分割ができない。

そのため、`Illuminate\Database\Query\Builder` クラスを継承したQueryBuilderクラスを作成し、EloquentからでもQueryBuilderのみでも利用できるようにする。

# 実装
## QueryBuilderクラスの作成

`Illuminate\Database\Query\Builder`したクラスを作成する。

```php

<?php

namespace App\Models\Builder;

use Illuminate\Database\Query\Builder;

class UserBuilder extends Builder
{
    public $from = 'users';

    public function verified()
    {
        return $this->whereNotNull('email_verified_at');
    }
}
```

## EloquentModel修正

EloquentModelで作成したQueryBuilderクラスを呼び出せるようにする。

`Illuminate\Database\Eloquent`クラスの`newBaseQueryBuilder`メソッドをオーバーライドし、先程作成したQueryBuilderクラスを返却するように変更する。

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Builder\UserBuilder;

class User extends Model
{

    /**
     * @return \App\Models\Builder\UserBuilder
     */
    public function newBaseQueryBuilder()
    {
        return new UserBuilder($this->getConnection());
    }
```

## Builderクラスにマクロを定義

`Illuminate\Database\Query\Builder`クラスに、queryメソッドをマクロとして定義する。
queryメソッドでは、コネクションを引数に自身のインスタンス生成し、返却するように修正する。

```php
<?php

namespace App\Providers;

use Illuminate\Database\Query\Builder;
use DB;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Builder::macro('query', function () {
            return new self(DB::connection());
        });
    }
```

# 使用例
## 例1. EloquentModelで使用する場合

scopeメソッドのように利用するだけでOK!

```php
<?php

namespace App\Http\Controllers;

use App\Models\User;

class UserController extends Controller
{
    public function index()
    {
        $users = User::verified()->get();

    }
}
```

## 例2. QueryBuilderのみで使用する場合

queryメソッドを呼んだあとに、チェーンして呼べばOK!

```php
<?php

namespace App\Http\Controllers;

use App\Models\Builder\UserBuilder;

class UserController extends Controller
{
    public function index()
    {
        $users = UserBuilder::query()->verified()->get();

    }
}
```

# まとめ

クエリ生成に関する部分をクラスとして独立させたことで、EloquentでもQueryBuilderでも使用できるようにしました。