OmniAICreator/Qiita-1.07M huggingface dataset:
ArduinoUno: シリアルモニタを使う

Arduino のシリアルモニタを使う方法です。
こちらのプログラムを改造しました。
[Arduino: LCD モジュールを使う](https://qiita.com/ekzemplaro/items/e11fdbce6d7c2ff74b51)

```text:greetings/greetings.ino
#include "rgb_lcd.h"

rgb_lcd lcd;
int count = 0;

void setup() {
	lcd.begin(16,2);
	lcd.setRGB(0, 255, 255);
  Serial.begin(9600);
  Serial.println("*** start ***");

}

void loop() {
    lcd.setCursor(0,0);
    lcd.print ("Good Morning!  ");
    Serial.println("AAA " + String(count));
    delay(2000);
    count++;
    lcd.setCursor(0,0);
    lcd.print ("Good Afternoon!  ");
    Serial.println("BBB " + String(count));
    delay(2000);
    count++;
    lcd.setCursor(0,0);
    lcd.print ("Good Evening!  ");
    Serial.println("CCC " + String(count));
    delay(2000);
    count++;
}
```

Arduino IDE で
ツール -> シリアルモニタで、シリアルモニタが表示されます。
>ボーレートは 9600 です。

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ba52ce3d-4295-be8b-c6b0-98356e69d311.png)


次のエラーが出た場合は、

>```text
ボード/dev/ttyACM0は利用できません
シリアルポート「/dev/ttyACM0」を開く際にエラーが発生しました。
```

パーミッションを変更して下さい。

>```bash
sudo chmod 777 /dev/ttyACM0
```
(定積分)「(Youtube)【中学入試】10秒以内に暗算で解きたい面積問題！」をwolframalphaとsympyでやってみたい

オリジナルリンク

https://www.youtube.com/watch?v=B9pOQr5IpEk

成蹊中学 2020年度入学試験問題（第1回）算数 問題2 ⑸
オリジナルは、1辺が12cmの正方形です

https://www.seikei.ac.jp/jsh/upload/j_2020sansu1.pdf#page=5

#wolframalphaで

#### 〇足し算で

https://www.wolframalpha.com/input/?i=2*2%2B3.14*2*2%2F4&lang=ja

結果:
7.14

####〇引き算で

https://www.wolframalpha.com/input/?i=4*4-4*2%2F2*2-%284*4-3.14*2*2%29%2F4&lang=ja

結果:
7.14

#### 〇「積分xが0から2」と「積分xが2から4」の合計

円弧のy計算

https://ja.wolframalpha.com/input/?i=solve%28%28x-2%29%5E2%2B%28y-2%29%5E2%3D2%5E2%2Cy%29

円弧のy計算結果:
y = sqrt(-(x - 4) x) + 2


https://ja.wolframalpha.com/input/?i=integrate%282*x-0.5*x%2C%28x%2C0%2C2%29%29%2Bintegrate%28sqrt%28-%28x+-+4%29+*x%29+%2B+2-0.5*x%2C%28x%2C2%2C4%29%29


面積計算結果:
integral_0^2 (2 x - 0.5 x) dx + integral_2^4 (sqrt(-(x - 4) x) + 2 - 0.5 x) dx = 7.14159

#### 〇原点から円弧までの長さで、極方程式の積分
原点から円弧中心で半分の面積×2
「積分1/2*r*(r*dΘ)」と「2辺とその間でない角が与えられた場合」

https://ja.wolframalpha.com/input/?i=1%2F2*integrate%28%282*sqrt%282%29*cos%28t%29%2Bsqrt%282%5E2-%282*sqrt%282%29*sin%28t%29%29%5E2%29%29%5E2%2C%28t%2C0%2Cpi*45%2F180-atn%282%2F4%29%29%29*2

計算結果:
integral_0^(π/4 - tan^(-1)(1/2)) (2 sqrt(2) cos(t) + sqrt(4 - 8 sin^2(t)))^2 dt = 4 + π≈7.1416



####〇原点から円弧までの長さで、極方程式の積分
角度atn(2/4)から(pi/2-atn(2/4))まで積分。2つに分ける必要がありませんでした。


https://ja.wolframalpha.com/input/?i=1%2F2*integrate%28%282*sqrt%282%29*cos%28t-pi%2F4%29%2Bsqrt%282%5E2-%282*sqrt%282%29*sin%28t-pi%2F4%29%29%5E2%29%29%5E2%2C%28t%2Catn%282%2F4%29%2Cpi%2F2-atn%282%2F4%29%29%29

定積分:
1/2 integral_tan^(-1)(1/2)^(π/2 - tan^(-1)(1/2)) (2 sqrt(2) cos(π/4 - t) + sqrt(4 - 8 sin^2(π/4 - t)))^2 dt = 4 + π≈7.1416



# sympyで

#### 〇「積分xが0から2」と「積分xが2から4」の合計
```python
from sympy import *
import time
var("x y r")
start = time.time()
f=solve((x-2)**2+(y-2)**2-2**2,y)
myKekka = integrate(2*x-0.5*x,(x,0,2))+integrate(f[1]-0.5*x,(x,2,4))
print("#積分結果",myKekka)
print("#積分結果 {:.5f}".format(float(myKekka)))
print("#積分時間 {:.0f}".format(time.time() - start) + "秒")
#積分結果 pi + 4.0
#積分結果 7.14159
#積分時間 4秒
```

#### × (sympy)原点から円弧までの長さで、極方程式の積分
wolframalphaで結果がでましたが、10分たっても
sympyで結果がでませんでした。


```python
from sympy import *
import time
var("t")
start = time.time()
myKekka = 1/2*integrate((2*sqrt(2.0)*cos(t)+sqrt(2.0**2-(2.0*sqrt(2.0)*sin(t))**2))**2,(t,0,pi*45/180-atan(2/4)))*2
print("#積分結果",myKekka)
print("#積分結果 {:.5f}".format(float(myKekka)))
print("#積分時間 {:.0f}".format(time.time() - start) + "秒")
```


#参考
https://manabitimes.jp/math/824

2辺とその間でない角が与えられた場合

http://www.ftext.org/text/subsubsection/1061
【PHP8.1】finalクラス定数が作れるようになる

クラス定数は上書き可能です。

```php
class FOO{
    public const HOGE = 1;
}

class BAR extends FOO{
    public const HOGE = 2;
}

var_dump(BAR::HOGE); // 2
```

定数なのに上書き可能とはこれ如何に。

クラス定数ではない通常の定数は当然ですが上書きできません。

```php
const HOGE = 1;
const HOGE = 2; // E_WARNING

echo HOGE; // 1
```

エラーではなくE_WARNING止まりってのはよくわかりませんが、ともかく値は変更できていません。
定数は上書きできないのにクラス定数は上書きできるというのはよくわかりませんね。

まあ、実は他の言語もだいたいこんな仕様だったりするのですが。

```java:Java
class A{
    static int num=0;
}

class B extends A{
    static int num=10;
}
```

そんなわけで絶対に上書きされたくないクラス定数を、PHP8.1から書けるようになります。

```php
class FOO{
    final public const HOGE = 1;
}
```

えっpublicより前に置くのかよ。
まあ順番以外はJavaの`static final`とだいたい同じです。

ということで以下は[Final class constants](https://wiki.php.net/rfc/final_class_const)のRFCの日本語訳です。


# PHP RFC: Final class constants

## Introduction

現在のところ、クラス定数は常に子クラスによってオーバーライド可能です。
このため幾つかの問題が発生します。

まず、遅延静的束縛において、PHPエンジンはクラス定数の参照を最適化できません。
このため、`static::FOO`や`$this::FOO`において`FOO`がオーバーライドされているという悲観的可能性を常に考えなければなりません。

さらに重要な問題としては、クラス定数が一意である保証がされないことです。
クラス内で常に`self::FOO`で参照していたとしても、子クラスがその値を変更することを妨げることはできません。

クラス定数にfinal修飾子を適用することができれば、子クラスが値を上書きできないようにするという意図が明白になります。

ちなみにインターフェイス定数は既にfinalです。

```php
interface I
{
    public const X = "i";
}
 
class C implements I
{
    public const X = "bar";
}
 
// Fatal error: Cannot inherit previously-inherited or override constant X from interface I
```

ところが、中間クラスを噛ませるとオーバーライド可能になってしまうという不整合があります。

```php
interface I
{
    public const X = "i";
}
 
class C implements I
{
}
 
class D extends C 
{
    public const X = "d";
}
 
// エラー出ない
```

## Proposal

クラス定数にfinal修飾子を適用可能にします。
これにより、クラス定数のオーバーライドを禁止することができます。

```php
class Foo
{
    final public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
}
 
// Fatal error: Bar::X cannot override final constant Foo::X
```

また、インターフェイス定数はデフォルトではオーバーライド可能になり、final修飾子を適用することでオーバーライド禁止になります。

```php
interface I
{
    public const X = "i";
    final public const Y = "i";
}

class C implements I
{
    public const X = "c"; // OK
    public const Y = "c"; // NG
}

// Fatal error: C::Y cannot override final constant I::Y
```

## Reflection

定数がfinalであるかどうかを調べる`ReflectionClassConstant::isFinal()`メソッドが追加されます。


## Backward Incompatible Changes

後方互換性のない変更はありません。

## Vote

投票数の2/3の賛成で受理されます。

本RFCは2021/05/19から2021/06/02にかけて投票が行われ、賛成29反対4の賛成多数で可決されました。
PHP8.1で導入されます。


# 感想

これまでfinalはクラスとメソッドにしか書けず、プロパティや定数には書けませんでした。
PHP8.1からは定数にも書けるようになります。
プロパティには引き続き書くことができませんが、こちらは[readonly](https://qiita.com/rana_kualu/items/ae96400a0a6981eca64a)がちょうどいい代替になるでしょう。

しかし順番は絶対`public final const HOGE = 1;`のほうがいいと思うんだけどどうなんだろう。

他言語に合わせるとすれば`public const final HOGE = 1;`ですが、PHPではconstに型宣言を書けないので、finalの位置が居心地悪くなってしまいます。
`public const final int HOGE = 1;`と書ければ最も自然、というか他言語と同じ順番なので楽なのですけどね。

まあともかく、これでようやく変更されないことが保証されたクラス定数を作ることができるようになりました。
削除をクリックしたらしたら確認ダイアログを出す方法

#はじめに

![スクリーンショット 2021-07-19 19.51.24（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/d6dded5f-62b8-3f55-d843-b12cde7f400d.png)

削除ボタンをクリックしたらいきなり削除されるのではなく上記のような確認ダイアログを表示させるようにしたいと思いました。

めちゃくちゃ簡単でした！

#記述の仕方

```erb
<%= link_to(model_path(model.id), method: :delete, data: { confirm: '削除しますか'} ) %>
```

```erb
data: { confirm: '削除しますか'}
```
これを記述すれば確認ダイアログが表示されます。

今日は短めな投稿になりました。
しかし使える機能だと思い、アウトプットしました！
.gitignore_globalを使うのをやめてデフォルトの置き場に戻す方法

Macのフォルダやファイルに関するmeta情報が格納されている.DS_Storeという名前のファイルをMac全体でgit管理から外すために
[.gitignoreで.DS_Storeを削除しよう](https://qiita.com/takashimelon/items/def769aaaa1d41cc44d4)
を参考に~/.gitignore_globalを作成したのですが、
[~/.gitignore_global を指定するのをやめ、デフォルトの置き場に置こう](https://zenn.dev/qnighy/articles/1a756f2857dc20)
という記事を見かけてデフォルトの~/.config/git/ignore を使うように変更しようとした時に、既に作ってしまった ~/.gitignore_global をどうすれば良いか少し悩んだのでメモ。

###~/.gitignore_global を削除し.gitconfigを編集

ターミナルから削除もしくはfinderで「command」＋「shift」＋「.」 で隠しファイルを表示して~/.gitignore_globalをゴミ箱に入れて、~/.gitconfigの[core]以下のexcludesfileの行を削除するだけでok

```diff:.gitconfig
 [core]
-    excludesfile = ~/.gitignore_global
```

[core]に書いていたのがこれだけだったので[core]の行ごと消してよかったのかもしれませんが、残して試したらちゃんと動作したので念の為残しました。

ちなみにデフォルトの~/.config/git/ignore を使って.DS_Storeを無視する方法は [Git でグローバルな .gitignore を作成する](https://qiita.com/takuya0301/items/29187aa088d04cf92659) の「~/.config/git/ignore に設定する」のところを参考にしました。
【IE対応】テキストの末尾を「…」省略できるline-clampを簡単に実現する

テキストの末尾を行数を指定して「…」省略できるline-clampを使ってみたものの
IEには非対応だったので、jQueryを使ってIE対応してみました。

CSS

```
/* 行数指定部分 PC2行表示*/
.block-item-comment {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
/* 行数指定部分 SP3行表示*/
@media screen and (max-width: 700px){
	.block-item-comment {
	   -webkit-line-clamp: 3;
	}
}
```


まず、以下から、clamp.jsダウンロード

https://github.com/josephschmitt/Clamp.js

サンプルコード

```
<script src="../clamp.js"></script>
<script>
var header = document.getElementsByTagName('body')[0].getElementsByTagName('h1')[0];
$clamp(header, {clamp: 1, useNativeClamp: false});
</script>
```
＊＊＊＊


JS

```
jQuery(function ($) {
  if($(".block-item-comment").length > 0){
    $(".block-item-comment").each(function(i, elem) {
      $clamp(elem, {clamp: 2})
      console.log(elem)
    });
  }
});
```


参考URL：https://blog.webico.work/css-line-clamp#UAIE11
プログラマーの仕事とは(未経験エンジニア必読❗️)

# この記事の概要
最初プログラマーってコードを書いているのがほとんどのイメージでしたが、
別にそうではないです。自分は上流工程は経験していませんが、
現役のCTOの方から教わったことを説明してみます。

こちらのメンターの方です。

https://wonderful-wife.net/w_code/

# プログラマーの仕事とは？
プログラマーの仕事はコードを書くだけが仕事ではありません。
受託開発企業を想定して書きます。

こちらは***要件定義***です。どんなサービス、アプリケーションにしたいかヒアリングします。
```
1 クライアントから何が欲しいかヒアリング
```

こちらは***基本設計、詳細設計***です。スターウォーズで言うとこのデススターの設計図みたいなイメージで、アプリケーションの概要を書いていきます。
```
2 どう作るか調査設計すること
```
こちらは***製造、テストのフェーズです。世間一般のプログラミングはここがイメージ***されます。
Rubyで言うとこの***RSpecのテストコードを書くときもこのフェーズ***です。
```
3 コードを書く
```
お客様にこういうものを作りましたと納品する時に使いますし、コードのロジックなどを書いたりする時にもドキュメントを書きます。***プログラマーはドキュメントを書くことにも慣れておく***必要があります。
```
4 ドキュメントを書く
```
***特に言語化スキルが大切***です。実務をやっていて痛感しました。
***相手の状況などを想像し必要な情報をまとめて伝えること***も大切ですし、
***今自分何をしたいのか、何をやっているのかを把握するにも言語化***が必要です。

これだけを見るとただコードを書いていればいいわけではないですよね。

# 読んで欲しい記事
よかったらこちらの記事も読んでみてください。

https://qiita.com/Hashimoto-Noriaki/items/46be6a1202503dc4f99e

https://qiita.com/Hashimoto-Noriaki/items/f47e8e997c3d788dac05
[Rails] ActiveStrageの画像の保存先をAmazon S3にする①~IAMユーザーの作成~

##はじめに
RailsアプリケーションでActiveStrageに保存する画像をAWSが提供するS3に保存させる方法を記述したいともいます。
よろしくお願いします。



##IAMユーザーを作成
AWSのアカウント登録が完了しており、ルートユーザーがある状態から始めます。

まずは権限を制限させたIAMユーザーを作成します。
AWSにサインインしたら、検索フォームに「IAM」と打ち込みIAMをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/a8416ce3-17e3-46d8-56af-f446c8e0bb9c.png)

クリックすると「ユーザー」というリンクがあるのでそれをクリック。
ページ遷移後、ユーザーを追加というボタンがあるのでクリック。

1ページ目
ユーザー名を適当に決めます。自由に決めて結構です。役割がわかりやすい名前にするといいかなと思います。
アクセスの種類というところで、 「プログラムによるアクセス」というチェックボックスにチェックを入れて、次のステップをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/2f832600-fdfb-cc63-c277-edb9d81a5a1d.png)

2ページ目
「既存のポリシーを直接アタッチ」を選択。
「AmazonS3FullAccess」というポリシーにチェックを入れて、次のステップをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/e5b6af0b-3d48-8f4c-a360-91bb879be9b6.png)


3ページ目のタグの追加というページは何も入力せずに、次のステップをクリック。
4ページ目も確認できたらすることはないのでユーザー作成をクリック。

5ページ目
.csvのダウンロードをクリックして```new_user_credentials.csv```というファイルがダウンロードされたのを確認して、閉じるを押します。

完了したら、作成したユーザーをクリックして
認証情報をクリック→コンソールのパスワードの管理というところをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/7af215b6-9ffe-09a7-d91a-25c57e00eac2.png)

そしたら、コンソールへのアクセスを有効化を選択。
自動生成パスワードを選択。適用。

するとまた、.csvダウンロードが出てくるのでクリックしてダウンロード。
すると登録したIAMユーザー名_credentials.csvというファイルがダウンロードされます。

このファイルには登録したIAMとしてログインする時に必要になる情報が記載されています。
早速、そのファイルを開き「Console login link」と書いてるところのURLをクリックします。
そのさきでユーザー名、パスワードをそのファイルに記載されている通り入力するとログインできるはずです。

正常にAWSのサイトへログインできればIAMユーザーの作成が完了です。
GCP内のコンテナイメージを高速ダウンロードする手順

#GCP内のコンテナイメージを高速ダウンロードする手順
Google Cloud Platform の「Container Registry」に保存されている非公開のコンテナイメージを自分のローカルパソコンに高速でダウンロードする方法をメモしておきます。
コンテナイメージをネット上で公開せずに、別の開発者の方に渡す際に利用できる方法かと思います。

Google Cloud Shellにある「cloudshell download」でダウンロードする手順を試しましたが500MBで30分以上かかってイライラしたので、別の方法がないか模索している内に見つけた手順です。

※ダウンロードしたファイルの整合性などは未確認ですので自己責任でお願いします。

#GCPコンソールで対象コンテナイメージの「pullコマンド」をコピーしてくる
```
docker pull gcr.io/project-name001/cont-img-manage-pilot:latest
```

#GCPコンソール画面の右上にあるCloud ShellアイコンをクリックしCloud Shellを起動
先ほどコピーしたPullコマンドを実行。

```
MyAccountName@cloudshell:~$ docker images
```

取得したコンテナイメージを確認。

```
REPOSITORY                                        TAG       IMAGE ID       CREATED        SIZE
gcr.io/project-name001/cont-img-manage-pilot   latest    ee67c3b1f999   5 months ago   1.27GB
```

# コンテナイメージの保存
取得したコンテナイメージは、Cloud Shell用の一時的な仮想VMのどこかに保存されているので、これをtar形式で保存？書き出し？を行う。
自分のルートディレクトリに保存、1.27GBもあるので数秒かかる。

```
MyAccountName@cloudshell:~$ docker save gcr.io/project-name001/cont-img-manage-pilot:latest -o cont-img-manage-pilot.tar
```

# 一時的なHTTPサーバーで公開してダウンロード
このファイルを一時的なHTTPサーバーで公開してダウンロードさせる。

##一時的なHTTPサーバーで公開するディレクトリをtmp配下に作成して移動

```
MyAccountName@cloudshell:~$ cd `mktemp -d`
```

##公開ディレクトリに対象ファイルを移動させる

```
MyAccountName@cloudshell:/tmp/tmp.GPPKd6UX8R$ cp -Rp /home/MyAccountName/cont-img-manage-pilot.tar ./
```

##一時的なHTTPサーバーを起動させる

```
MyAccountName@cloudshell:/tmp/tmp.GPPKd6UX8R$ python -m SimpleHTTPServer 8080
```

問題無く起動すると下記の様な表示がでてくる。

```
********************************************************************************
Python 2 is deprecated. Upgrade to Python 3 as soon as possible.
See https://cloud.google.com/python/docs/python2-sunset

To suppress this warning, create an empty ~/.cloudshell/no-python-warning file.
The command will automatically proceed in  seconds or on any key.
********************************************************************************
Serving HTTP on 0.0.0.0 port 8080 ...
```

Cloud Shellは現状のまま置いておいて、自分アイコンの左２個隣りの「ウェブプレビュー」アイコンからクリック
「ポート8080でプレビュー」をクリックするとウェブページが開く

この様な感じでダウンロードが可能になる。
ダウンロードが完了したらCloud Shellで「Ctrl + c」でHTTPサーバーを終了させる

1.27GBを約10分ほどでダウンロードできたので、そこそこ良い方法なのかもしれない。
※ダウンロードしたファイルの整合性などは未確認ですので自己責任でお願いします。
PWAでバックグラウンドに回ったことを検知する方法

PWAでバックグラウンドに回ったことを検知する方法になります。

## PWAでバックグラウンドに回ったことを検知する方法

```javascript
if (window.matchMedia('(display-mode: standalone)').matches) {
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') {
     console.log('PWAでバックグラウンドに回りました')
     /* PWAでバックグラウンドに回った時に実行する処理を記述 */
    }
  })
}
```

## 解説

### PWAの判定について
PWAの判定は`matchMedia`でおこなっています。
manifest.jsonで設定したディスプレイモードによって変わります。

```javascript
window.matchMedia('(display-mode: fullscreen)')
```

```javascript
window.matchMedia('(display-mode: minimal-ui)')
```
https://developer.mozilla.org/ja/docs/Web/Manifest/display

https://developer.mozilla.org/ja/docs/Web/API/Window/matchMedia

### バックグラウンドに回ったかの判定について
バックグラウンドに回ったかの判定は`visibilitychange`でおこなっています。

```javascript
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
   console.log('バックグラウンドに回りました')
  }
})
```

https://developer.mozilla.org/ja/docs/Web/API/Page_Visibility_API

https://developer.mozilla.org/ja/docs/Web/API/Document/visibilityState
WSL の git

Ubuntu 20.04LTS
WSLでも基本変わらないはず。
keyはwindowsホスト側に存在するので、これを一緒に使いたい。

接続できないことを確認。

```Terminal
ssh -T git@github.com
The authenticity of host 'github.com (52.192.72.89)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```

これはgithubのホストの確認なので、[ここ](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints)と一致していたら yes を押す。


```Terminal
yes
Warning: Permanently added 'github.com,52.69.186.44' (RSA) to the list of known hosts.
git@github.com: Permission denied (publickey).
```

何も設定していないのでアクセスはできない。
keuの設定をする。

`~/.ssh/config`で設定。
windows は `/mnt/c/`以下にマウントされているので、共通して使える。

```Terminal
$ more config
Host github.com
     User KojiKobayashi
     IdentityFile /mnt/c/Users/k.kobayashi/(ppkへのパス)
```

User は登録emailでもいいみたい。
もう一回確認。

```Terminal
$ ssh -T git@github.com
Warning: Permanently added the RSA host key for IP address '52.192.72.89' to the list of known hosts.
Enter passphrase for key '/mnt/c/Users/k.kobayashi/(ppkへのパス)':
Hi KojiKobayashi! You've successfully authenticated, but GitHub does not provide shell access.
```

追記
いつのまにか key が使えなくなった

```Terminal
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for '/mnt/c/Users/キーのパス' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/mnt/c/Users/キーのパス": bad permissions
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
```

しょうがないのでキーをlinux側にコピーしてpermission変更(600)
[Vue]一度だけしか実行しないbeforeEachを登録する[Nuxt]

VueRouterでページ遷移に処理をフックする際に利用するbeforeEachで一回だけしか実行しない処理を登録するにはどうしたら良いでしょう？
答えは簡単で、beforeEachで関数を登録すると、その返り値はその関数を解除するための関数が返されます。

```js
const unregister = router.beforeEach(() => {
  console.log('一回だけ・・・')
  unregister()
})
```

これで自分自身を登録しつつ、実行された場合に登録解除されて次回以降の遷移では実行されません。
おしまい

https://github.com/vuejs/vue-router/commit/77314888bdacb2dc55d7e387f6c98946cb189bc9
Azure Functionsの関数内でJSTの時刻を取得する

# はじめに
Azure Functionsはデフォルトの状態だと関数内でシステム時刻を取得した場合UTCで表示されます。
JSTで表示したいため時刻をJSTで取得するようにします。

以下のコードを実行して確認してみます。
スタックは`PowerShell Core`です。

```powershell
Write-Information "Timezone test:$(Get-Date)"
```

デフォルトだとこうなります。
左の列の`timestamp`と違う時刻で表示されてますね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/cd12e682-16a7-5d1e-8077-02d78857455f.png" width = 90%>


# 設定
JST表示にするためAzure Functionsの`構成`でアプリケーション設定を追加します。
名前：WEBSITE_TIME_ZONE
値：Tokyo Standard Time

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/05c3b6d1-f3b3-ddad-bd89-75ddf0ef96e6.png" width=90%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/acf790fa-1857-11d5-59ed-225c4d4ff6b6.png" width=90%>
忘れずに保存します。
保存するとAzure Functionsは再起動します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/7c37110e-ec3e-29bb-8b0c-197ace3ba5e7.png" width=90%>


設定は以上です。

# 確認
設定追加後に実行してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604991/65a2d3e3-604e-bf26-c702-cc1d3a6a501a.png" width=90%>

無事JSTで表示されました。
方式設計項目サンプル

方式設計項目サンプル

1 はじめに
    1.1 更新履歴
    1.2 本書の目的
    1.3 ドキュメント体系
    1.4 用語の定義
    1.5 プロジェクト体制
    1.6 基本設計範囲
2 システム設計
    2.1 システム概要
    2.2 システム構成
    2.3 機器一覧
    2.4 機器緒元
    2.5 回線一覧
    2.6 ソフトウェア一覧
×3 物理設計
×    3.1 物理構成図(WAN)
×    3.2 物理構成図(LAN)
×    3.3 フロア図
×    3.4 ラック収容設計
×    3.5 電源収容設計
×    3.6 ポート収容設計
×    3.7 インターフェース設計
×    3.8 ケーブル設計
4 クラウド環境設計
×    4.1 仮想ネットワーク設計
×    4.2 仮想ロードバランサ設定
    4.3 仮想サーバインスタンス設計
    4.4 仮想ストレージ設計
5 論理設計
    5.1 ネットワーク設計
        5.1.1 ホスト名設計
        5.1.2 論理構成図
×        5.1.3 VLAN設計
×        5.1.4 IPアドレス設計
×        5.1.5 ルーティング設計
×        5.1.6 アドレス変換(NAT/NAPT)設計
×        5.1.7 トラフィック制御設計
×            5.1.7.1 優先制御
×            5.1.7.2 帯域制御
△        5.1.8 トラフィックフロー設計
    5.2 サーバ設計
        5.2.1 Windows
            5.2.1.1 時刻と言語
            5.2.1.2 ディスク構成
            5.2.1.3 パーティション構成
            5.2.1.4 役割と機能
×        5.2.2 RHEL
×            5.2.2.1 時刻と言語
×            5.2.2.2 ディスク構成
×            5.2.2.3 パーティション構成
×            5.2.2.4 パッケージ
6 インフラ機能設計
×    6.1 ロードバランサ設計
×        6.1.1 機能概要
×        6.1.2 対象機器一覧
×        6.1.3 負荷分散対象
×        6.1.4 負荷分散方式
×        6.1.5 ヘルスチェック方式
×        6.1.6 パーシステンス方式
×    6.2 UTM設計
×        6.2.1 機能概要
×        6.2.2 ゾーン設計
×        6.2.3 ポリシー設計
×        6.2.4 オブジェクト設計
×        6.2.4.1 オブジェクト一覧
×        6.2.5 IPS/IDS設計
×        6.2.6 アンチウイルス設計
×        6.2.7 スパイウェア設計
×        6.2.8 ファイルブロッキング設計
    6.3 Web設計
□        6.3.1 機能概要
□        6.3.2 公開Web設計
□        6.3.3 内部Web設計
×    6.4 SMTP設計
×        6.4.1 機能概要
×        6.4.2 外部SMTP
×        6.4.3 内部SMTP
×        6.4.4 メール配送制御
    6.5 DNS設計
        6.5.1 機能概要
        6.5.2 コンテンツDNS
        6.5.3 キャッシュDNS
7 可用性設計
×    7.1 基本方針
×    7.2 ネットワーク機器
×    7.3 サーバ機器
×    7.4 ストレージ機器
×    7.5 ネットワーク
8 性能設計
×    8.1 ネットワーク機器
    8.2 サーバ機器
    8.3 ストレージ機器
9 拡張性設計
    9.1 物理拡張性
×        9.1.1 回線帯域
×        9.1.2 WANルータ
×        9.1.3 拠点L3SW
        9.1.4 サーバ
×    9.2 論理拡張性
×        9.2.1 VLAN
×        9.2.2 IPアドレス
10 セキュリティ設計
×    10.1 脆弱性対策
×    10.2 マルウェア対策
×    10.3 アクセス制御
×    10.4 データ暗号化
11 管理機能設計
    11.1 アカウント設計
◎    11.2 リモートアクセス設計
◎    11.3 時刻同期設計
◎    11.4 名前解決設計
    11.5 ログ設計
◎    11.6 SNMP設計
12 保守運用設計
    12.1 保守運用業務一覧
        12.1.1 定常業務
        12.1.2 非定常業務
    12.2 監視設計
        12.2.1 基本方針
        12.2.2 監視対象
        12.2.3 監視項目
    12.3 バックアップ・リストア設計
        12.3.1 基本方針
        12.3.2 バックアップ
        12.3.2.1 バックアップ対象
        12.3.2.2 バックアップ方式
        12.3.2.3 バックアップポリシー
        12.3.3 リストア
        12.3.3.1 リストア基本方針
        12.3.3.2 リストア方式
    12.4 障害対応設計
        12.4.1 基本方針
        12.4.2 対応契機
        12.4.3 切り分け
        12.4.4 対応内容
セレクトボックスを選択後、自動でサブミット(送信)する方法

この記事では、
**セレクトボックスを選択後、自動でサブミット(送信)する方法**
について解説していきます。

具体例としては、記事の並び替えなどに使うことができます。

![auto_select_submit.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/833332/2b7c6d29-2def-9710-c7e0-55412769bc90.gif)
<a href="https://muscle-meal-recipes.com/">https://muscle-meal-recipes.com/</a>

##前提
- HTMLのformでセレクトボックスを作成できる。
- JavaScript(jQuery)の環境が整っている

##実装

```html
<form id="submit_form">
  <select id="submit_item">
    <option value="人気順">人気順</option>
    <option value="新しい順">新しい順</option>
    <option value="古い順">古い順</option>
  </select>
</form>

<script>
  $(function(){
    $("#submit_item").change(function(){
      $("#submit_form").submit();
    });
  });
</script>
```

簡単に解説すると、
idが`submit_item`のoptionが変更すると、
idが`submit_form`のフォームがsubmitする。
というスクリプトです。


##まとめ
今回は、
**セレクトボックスを選択後、自動でサブミット(送信)する方法**
について解説しました。

是非参考にしていただければと思います！
Databricks(Spark）のPythonにてNot Null制約が設定されているカラム情報を取得する方法

## 概要
Databricks(Spark）のPythonにてNot Null制約が設定されているカラム情報を取得する方法を共有します。
`dataframe.schema.jsonValue()`により取得するスキーマ情報を整形します。

詳細は下記のGithub pagesのページをご確認ください。

https://manabian-.github.io/databricks_tecks_for_qiita/#get_not_null_columns_info/get_not_null_columns_info.html

コードを実行したい方は、下記のdbcファイルを取り込んでください。

```URL
https://github.com/manabian-/databricks_tecks_for_qiita/blob/main/tecks/get_not_null_columns_info/dbc/get_not_null_columns_info.dbc
```

## 環境
databricks runtime: 8.3.x-cpu-ml-scala2.12
Python  version:    3.8.8
pyspark version:    3.1.2.dev0

## 手順
### 事前準備
サンプルのデータフレームを作成します。

```python
from pyspark.sql.types import *
 
schema = StructType([
    StructField('address', StringType(), False),
    StructField('personal_name', StructType([
       StructField('firstname', StringType(), False),
       StructField('detail', StructType([
               StructField('AAAA', StringType(), False),
               StructField('AAAA_detail', StructType([
                   StructField('AAAA', StringType(), False),
               ])),
           ])),
       ])),
       StructField('hobbies', ArrayType(StringType()), False),
       StructField('properties', MapType(StringType(),StringType()), False)
    ])
 
 
emptyRDD = sc.emptyRDD()
df = spark.createDataFrame(emptyRDD,schema)
 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/82ae0ba6-dcbc-d3f3-4d17-badc24d32e88.png)

### 関数を定義
 
```python
def get_defination(schema, prefix=''):
    fields = schema['fields']
    list_definations=[]
    prefix = prefix+'.' if prefix !='' else ''
    for field in fields:
        if type(field['type']) is dict:
            if field['type']['type'] == 'struct':
                list_definations.extend(get_defination(field['type'], prefix+field['name']))
            else:
                field["name"]=prefix + field["name"]
                list_definations.append(field)
        else:
            field["name"]=prefix + field["name"]
            list_definations.append(field)
    return list_definations

def get_not_null_columns_info(schema_dict):
    allcols = get_defination(schema_dict)
    return list(filter(lambda col: col["nullable"]==False, allcols))
```

### 階層をフラットにしたDDLの辞書型変数を取得

```python
## dict形式のddl文を取得
schema_dict = df.schema.jsonValue()
print(schema_dict)
type(schema_dict)

schema_list = get_not_null_columns_info(schema_dict)


```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ef24d147-cdf8-4a13-511e-b8a6e60ee160.png)

### 階層をフラットにしたカラムのリスト型変数を取得

```python
# カラム名のリストを取得
not_null_columns_list = [l.get('name') for l in schema_list]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/c8df6550-29f4-1809-be34-3e59375abef3.png)
【react-router-dom】現在のページのURLを参照できるuseLocationをざっくり紹介【React】

<h2>useLocation</h2>
SPAアプリを開発している過程で、URLが変わったかどうかを判定したいときや、シンプルに現在のURLを参照したい場面があると思います。

そんなときに使えるのが、useLocationです。

現在のURLを返してくれるhookで、URLが変更されるたびに新たにURLを返してくれます。

<h2>実装方法</h2>
こちらがuseLocationの実装例です。<a href="https://reactrouter.com/web/api/Hooks/uselocation">公式ドキュメント</a>よりお借りしました。

ここではuseEffectでlocationを指定して、ページが変わった時にuseEffect内の処理が走るようになっています。
また、useEffect内ではlocation.pathnameで現在のURLを取得しています。

```react:
import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Switch,
  useLocation
} from "react-router-dom";

function usePageViews() {
  let location = useLocation();
  React.useEffect(() => {
    ga.send(["pageview", location.pathname]);
  }, [location]);
}

function App() {
  usePageViews();
  return <Switch>...</Switch>;
}

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  node
);
```

<h2>参考</h2>

https://reactrouter.com/web/example/url-params

https://qiita.com/ozaki25/items/bb0eb273611eebc603dd
jsPsychで出力されたCSVファイルの文字化けのなおしかた

jsPsychでは、

```javascript
jsPsych.data.get().localSave('csv','mydata.csv');
```

のように記述するとデータをCSVファイルで保存することができます。
ただし、CSVファイルに日本語が含まれていたときには、たぶん文字化けします。

文字化けの解消方法は次の通りです。

# WINDOWS

1. エクセルを立ち上げる
2. 「データ」タブ→「外部データの取り込み」→「テキストファイル」を選択する。または、「データの取得」→「ファイルから」→「テキストまたはCSVから」
3. ファイルを選択
4. 文字の種類（元のファイル）で「Unicode(UTF-8)」を選択
5. 区切り文字で「カンマ（コンマ）」を選んで「読み込み」をクリック

![mojibake1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495823/62311102-715a-c097-1413-a747e08820ca.png)

![mojibake2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495823/df7c09ad-8342-5fa6-e525-0c233db4d408.png)

# MAC
Numbersアプリでは文字化けを起こさないようです。Numbersから、エクセルファイルを書き出すのが簡単です。

以下の情報は古いですが、残しておきます。

1. ダウンロードしたファイルを右クリック → このアプリケーションで開く → テキストエディット
2. ファイル　→　複製
3. ファイル　→　保存
4. 「標準テキストのエンコーディング」で、「日本語（Shift JIS）」を選択
5. ファイルの名前は自由につけて大丈夫ですが、最後に「.csv」をつけること。
6. 保存したファイルをエクセルで開く（通常はファイルをダブルクリックすればOK）
Google アナリティクスの導入

▪️ Google アナリティクスとは
Googleが提供しているWeb解析ツールの事で、自分のサイトにどれだけの人が訪れてどれだけの人がサイトを閲覧しているかを分析してく入れるもの。

↓
そしてgoogleアナリティクスをサイト内に組み込む事によってサイトの状況を把握でき、サイト改善にも繋がる。

▪️ 書き方と導入

書き方と導入方法については下記のサイトを参考に実践して見てください。

https://dekiru.net/article/18635
毎回ログインするの面倒だから自動でログインをできるようにした SBI証券編

# はじめに
こんにちは。リモート会議の時に限って、近所のワンちゃんが吠え始めます、筆者です :sob:

さて、以下記事で扱ったサービスがちょっとマイナーだったので、今回はみんな大好き**SBI証券**で行こうと思います :muscle: 

https://qiita.com/akitkat/items/e436bed2ca4cfc4ca4ae

# 使用するもの
以下拡張機能です。
こちらは、**任意のJavaScript**を実行できる拡張機能です。
ドメインなどのフィルタもできるがいいところ！

https://chrome.google.com/webstore/detail/scriptautorunner/gpgjofmpmjjopcogjgdldidobhmjmdbm?hl=ja

## 使い方
以下記事が参考になりました :bow:

https://qiita.com/itaya/items/36ed8b890c87ac47d9d3

# 実践
今回は**SBI証券**のログインを自動化します

https://www.sbisec.co.jp/

**ScriptAutoRunner**にスクリプト追加します。
前提として、ブラウザが`ログインID`と`パスワード`を覚えているため、`ログインボタンを押す処理`だけを実装します。

```js
(() => {
  if (location.href == 'https://www.sbisec.co.jp/ETGate') {
    document.querySelector("#SUBAREA01 > form > div > div > div > p.sb-position-c > a > input").click()
  } 
})()
```

上記でselectorは、以下スクリーンショットのように、Devtoolsから取得しています。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/7af36963-2e89-fcda-71bc-14511de648be.png)


これで、**SBI証券**にアクセスした際に自動でログインするようになりました！

# おわりに
自動でログインは便利ですが、自己責任で実装をお願います:bow:

それでは！
AWS関連で困った時の参考URL

AWSで自身が頻繁に使うサイトを載せておきます


#codeDeploy関連
[Amazon Linux または RHEL 用の CodeDeploy エージェントをインストール]
(https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/coでdedeploy-agent-operations-install-linux.html)
用途：Amazon LinuxでCodeDeployする際の、codeDeloyエージェントをインストールする方法

[チュートリアル: Amazon EC2 インスタンス（Amazon Linux または Red Hat エンタープライズ Linux および Linux、macOS、UNIX）に WordPress](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorials-wordpress.html)
用途：Ec2にcodeDeployを用いて、Wordpressを入れる方法（コマンド確認用）

#AWS Cli関連
[設定ファイルと認証情報ファイルの設定]
(https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)
用途：コマンドラインで、EC2からコマンドを叩く際に、どのIAMで認証するかの設定の確認

[Installing, updating, and uninstalling the AWS CLI version 2 on Linux]
(https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html)
用途：AWS CLIのインストール or ver2へのUPDATE方法


#code関連
gitHubがPriveteの場合、CodePipelineのブランチ設定が認識しない

#ECS関連
[プライベートレジストリの認証]
(https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/registry_auth.html)
[リポジトリの作成]
(https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/repository-create.html)
[Docker イメージをプッシュする]
(https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html)
用途：ローカルのdockerファイルをECSへpushする時の公式手順

#その他
[AWS サービスエンドポイント]
(https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html)
用途：AWSのサービスエンドポイントの一覧（よく忘れるので、、）

今は公式のみ
随時必要と感じたのは、こちらに記載する
ネットワーク関係（L2,L3）あたりの監視を調べるときに参考になったコマンド

 traceroute
あるホストからホストまでのネットワーク経路をリスト表示する、監視するサーバーから監視対象の機器までのそもそものルーティングを調べるのに使えた
snmpwalk
ある機器に対してsnmpで得られる情報を調べることができる。snmpで監視する場合は監視の設定をする前にこちらで値が取得できることを確認


参考
https://www.atmarkit.co.jp/ait/articles/0108/30/news003.html

https://qiita.com/hana_shin/items/856529cdab1b46668fc2
Railsで架空のCafeのHPを作ってみよう!【8日目】『ActiveStorageと複数のテーブル』編

#概要
基本Railsの記法に則り書いていきます！
１から全ての説明ではなく
その中であれ？どうやるの？と
疑問に思った点や実装に困った箇所を
ピックアップして紹介していきます♩

#設定と準備
・Rails
・HTML
・CSS
・Javascript(jQuery)

↑上記の言語とフレームワークを使い
架空(自分で考えたテキトーなもの)のCafeの
HPを作っていこうと思います！

#8日目の作業内容:round_pushpin:
・定義したインスタンスを使いビューを作成

#8日目の気になった箇所:zap:
ActiveStorageを使い画像の保存を行いたいけど
複数のテーブルで画像を保存する場合、
何か記述を変えないといけないポイントはあるのだろうか？

#仮説:pushpin:
ActiveStorage自体1つのテーブルのような役割を果たすので、
そこに紐付けるために何か別の記述を加える必要があるのではないかと思う。

#結論:star:
1つのテーブルの時の記述と同じように
画像を保存したい他のテーブルでも記述すれば問題なし！

```news.rb
class News < ApplicationRecord
  has_one_attached :image
end
```

```menu.rb
class Menu < ApplicationRecord
  has_one_attached :image
end
```

このようにそれぞれのモデルで同じように
アソシエーションを記述してあげれば大丈夫です！

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678155/567ef364-d3ac-df51-c00b-3bba99fde8be.png)

Sequel Proを確認すると
record_typeのところで自分の作成したモデルに紐付き
保存されていることが確認できます。
勝手に仕分けしてくれるので優秀ですね！ありがとう！
Ansible Tips: assertモジュールにて成功時にも評価式を表示させる例

備忘

assertモジュールでは、評価結果が成功時には評価式が表示されず、Ansible logからは成功した状態であるということのエビデンスとして使用しにくい。

# 成功時にも評価式を表示させる例

評価式をloopとして回し、loop labelから評価式をログに残すことが可能。

```yaml:tasks
- name: asserts for some tests
  assert:
    that:
    - "{{ item }}"
    success_msg: 'Passed: {{ item }}'
    fail_msg: 'FAILED: {{ item }}'
  register: r
  ignore_errors: true                   # summaryを出力させる為、failedでも継続
  loop:                                 # 評価式のlist
  - 1 == 1
  - "'a' in ['a','b']"
  - ansible_distribution in ['AIX']     # <= fail
  - ansible_distribution in ['MacOSX']  # <= success

- name: summary of asserts              # サマリー出力
  debug: var=r.results|map(attribute='msg')|list

- assert:　　　　　　　　　　　　　　　　　　 # 上のassertでfailedがあった場合に停止
    that:
    - "{{ r is not failed }}"

```

# 実行結果

```
TASK [ansible-assert : asserts for some tests that=['{{ item }}'], success_msg=Passed: {{ item }}, fail_msg=FAILED: {{ item }}] ***
ok: [localhost] => (item=1 == 1) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "1 == 1",
    "msg": "Passed: 1 == 1"
}
ok: [localhost] => (item='a' in ['a','b']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "'a' in ['a','b']",
    "msg": "Passed: 'a' in ['a','b']"
}
failed: [localhost] (item=ansible_distribution in ['AIX']) => {
    "ansible_loop_var": "item",
    "assertion": "ansible_distribution in ['AIX']",
    "changed": false,
    "evaluated_to": false,
    "item": "ansible_distribution in ['AIX']",
    "msg": "FAILED: ansible_distribution in ['AIX']"
}
ok: [localhost] => (item=ansible_distribution in ['MacOSX']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "ansible_distribution in ['MacOSX']",
    "msg": "Passed: ansible_distribution in ['MacOSX']"
}
...ignoring

TASK [ansible-assert : summary of asserts var=r.results|map(attribute='msg')|list] *************************
ok: [localhost] => {
    "r.results|map(attribute='msg')|list": [
        "Passed: 1 == 1",
        "Passed: 'a' in ['a','b']",
        "FAILED: ansible_distribution in ['AIX']",
        "Passed: ansible_distribution in ['MacOSX']"
    ]
}

TASK [ansible-assert : assert that=['{{ r is not failed }}']] **********************************************
fatal: [localhost]: FAILED! => {
    "assertion": false,
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"

```
seeds.rbの管理者情報がheroku本番環境に反映されない（Active adminで管理者画面導入時）

## 概要
acitive adminを導入するとseeds.rbに自動でプログラムが組み込まれる。

```ruby
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
```

`if Rails.env.development?`　は開発環境の場合のみ実行するという内容である
よって削除し、再デプロイ。`heroku run rails db:seed` を実行し解決。


## 事象概要

本番環境にてseeds.rbファイルが反映されない。

## 発生原因

`incident_app/db/seeds.rb`　ファイルのプログラムに`if Rails.env.development?`が入っていたため。

```ruby
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
```

## 対処概要

- `incident_app/db/seeds.rb`　ファイルから`if Rails.env.development?`　を削除

```ruby
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password')
```

- `GitHub`にプッシュ

```ruby
git add .
git commit -m "本番環境にseeds.rbを反映するよう変更"
git push origin HEAD
```

- heroku gitにプッシュ

```ruby
git push heroku master
```

- herokuにseeds.rbファイルを反映

```ruby
heroku run rails db:seed -a herokuに設定しているアプリ名
```

これで解決するはずです。
Vue3 で contenteditable な要素を v-model でバインドする

# はじめに
基本的には[以前書いた記事](https://qiita.com/soumi/items/7d6d2e8c5616ccbdc665)を `Vue3` 化したものですが、以下の2点手を入れています。

- `placeholder` に対応
- 更新時に余計な空白を削除

# TL;DR;

出来上がりのコードはこちら。

```vue
<template lang="pug">
.text-input(
  ref = "input"
  :contenteditable = "true"
  @input = "update"
  @focus = "focus"
  @blur = "blur"
)
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, watch } from "@vue/runtime-core";

export default defineComponent({
  name: "MultilineInput",
  props: {
    modelValue: String,
  },
  emits: {
    "update:modelValue": null,
  },
  setup(props, ctx) {
    const input = ref<HTMLElement>();
    const focusIn = ref<boolean>();

    const updateValue = () => {
      if (!focusIn.value) {
        let t = "";
        if (props.modelValue) {
          const elem: string[] = props.modelValue.split("\n");
          for (const e of elem) {
            t += "<div>" + (e !== "" ? e : "<br>") + "</div>";
          }
        }
        if (input.value) input.value.innerHTML = t;
      }
    };

    watch(() => props.modelValue, updateValue);

    const update = (e: Event) => {
      const target: HTMLElement = e.target as HTMLElement;
      const breakdown = target.innerHTML
        .replaceAll("<div><br></div>", "\n")
        .replaceAll("<div>", "\n")
        .replaceAll("</div>", "")
        .replaceAll("<br>", "\n").\
        .replaceAll(/<("[^"]*"|'[^']*'|[^'">])*>/g, "");
      ctx.emit("update:modelValue", breakdown);
    };

    const focus = () => {
      focusIn.value = true;
    };

    const blur = () => {
      focusIn.value = false;
    };

    onMounted(() => {
      updateValue();
    });

    return {
      input,
      update,
      focus,
      blur,
    };
  },
});
</script>

<style lang="stylus">
[contenteditable=true]:empty:before
  content: attr(placeholder);
  pointer-events: none;
  display: block; /* For Firefox */
  color rgba(255, 255, 255, 0.5)
</style>
```

# 改良点

## placeholderに対応

こちらの記事で一発対応できました。

http://kachibito.net/css/placeholder-for-contenteditable-without-javascript

以前は無かった `style` タグの中に該当するコードを書いています。

## 更新時に余計な空白を削除

久々に使って悩んだのですが、`contenteditable` 内で `Enter` を入れると、

```html
<div><br></div>
```
といった要素が挿入されます。(`shift + Enter` なら `<br>` のみ)
以前の記事では `innerText` で取ってきた値をそのまま使用していたのですが、この状態では余分な改行コードが入った `string` が取得されます。
ここを、`innerHTML` で取得した値から **力業で** 正しい値を抜き出すように変更しました。

## 入り込んだHTMLコードを削除(追記 2021/10/19)

運用中、なぜか `<span style="font-size:12pt">やっほー</span>` みたいな文字列が入ってきてしまった事があったので、これも **力業で** ねじ伏せます。

```ts
        .replaceAll(/<("[^"]*"|'[^']*'|[^'">])*>/g, "");
```

# おわりに

正しい値を取得するところでかなり無理やりな事をしており、きれいな実装とは言えませんが、この記事が同じ事でお困りの方の一助になれれば幸いです。
Apexトリガのベストプラクティス

# Apexトリガ
- クラスのベストプラクティスはトリガーにも適用される
- 入力規則とワークフロールールが要件を満たせない場合にトリガを使用する
- オブジェクトごとに単一のトリガー
- トリガー本体にロジックを書かないこと。
  その代わり、Trigger.new、Tigger.old、Tigger.newMapまたはTigger.oldMapは静的メソッドに渡される。
  （例外として、isInsert、isUpdateなどをチェックすることによって、異なる静的メソッドを異なるイベントに対して呼び出す必要がある場合のみロジックを書く）
- すべてのトリガーが一括設計パターンを使用する
- トリガーに静的なブール値を定義し、初期値をセットしてその後条件チェックするなど再帰的な使い方をやめる
- ガバナ制限を回避するには、Limit.getLimitメソッドを使用する
- トリガーから複数のメソッドを直接呼び出す場合は、同じトリガーレコードセットに対して複数回繰り返すことによってスクリプトステートメントの量が増える可能性があるため、注意が必要
wwwありのURLに転送【Cloudflare移管済ドメイン】

:::note info
Cloudflareに移管済みのドメイン（your-domain.com）に
アクセスされた際にサブドメイン（www.your-domain.com）に転送します
:::

## 忙しいあなたに

1. [ダッシュボードページ](https://dash.cloudflare.com/)を開く
1. 設定したい移管済みドメインページを開く
1. "ルール" > "ページルールを作成"
1. URL が一致する場合 -> "your-domain.com*"
1. "URLの転送" -> "301 - 永久リダイレクト"
1. その後の設定は: -> "https://www.your-domain.com$1"
1. "保存してデプロイする"

おしまい。

## そもそもwwwに転送すると良いことあるの？

結論から言うと、あります。ただどちらの言い分もあるため、閲覧者の判断に任せます。参考までに[2021年のさくらインターネットの見解](https://www.sakura.ne.jp/column/rs/domain-www-iru/)によると、DNSの仕様によってネイキッドドメイン（wwwなしの取得ドメイン）の利用を受け付けていない場合があるようです。したがって、ドメイン名を直接指定するのではなく、何らかのサブドメインを利用する事が推奨されています。Googleもトップページにサブドメインを利用しています（www.google.com）。


ルール設定の詳細については[Cloudflare公式ページ](https://blog.cloudflare.com/introducing-pagerules-url-forwarding/)をご覧ください。サブドメインへの転送方法（*や$1指定をすることで全て該当するURLにアクセスのあった場合に全てリダイレクト）について説明されています。

:::note warn
至らない部分がある場合は、是非お気軽にコメントいただけると幸いです。
:::
Slack Workflow Builderを用いた社内アンケートのとり方

はじめまして。DMM.com プラットフォーム事業本部の門脇です。
初めて投稿させていただきます。
今回は、Slack Workflow Builderを用いた社内アンケートを取得する取り組みについて紹介させていただきます。

# なぜやるのか
チームの業務の1つに、DMM.comで事業を作っていく社内の人達向けに、プラットフォーム機能導入時における質問の窓口対応（コンサルティング）があります。

こういった活動は、なかなか適切な指標が設けづらく、どのように業務改善をしていけばいいのかが見えづらい部分があります。

そのため私達は、実際に私達と接点を持った方に、窓口対応がどうだったかの評価をアンケートを通じて、収集して業務改善に活用しております。

# どうやるのか
社内では、チャットツールとしてSlackを使っており、窓口用に専用チャンネルを設けています。
そのため、アンケート送信/回答の収集もSlackで行っています。
また最終的なデータはGoogle Sheetsに集約して分析しています。

## 概要図
GAS と Slack Workflow Builderを使っています。
簡単な設定作業とスクリプトで完結できるのがおすすめポイントです。
![survey-flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780140/6af6732d-dac7-7466-4dff-a88e2b072a3b.png)


## 具体的な方法
### 問い合わせの収集
* 問い合わせフォームを統一するため、[Slack Workflow Builder](https://slack.com/help/articles/360035692513-Guide-to-Workflow-Builder) を使っています
* 問い合わせ内容は、[Google Apps Script（GAS）](https://developers.google.com/apps-script) を使って、Google Sheets に保存しています
* ※ Workflow Builder からの投稿は、Google Sheetsに書き込みできますが、Workflow Builder経由じゃない問い合わせもたまにあるため、GAS で [Slack API](https://api.slack.com/methods/channels.history) を使って取り込みをしています
* ※ 運用イメージは、 [こちらの記事](https://inside.dmm.com/entry/2020/01/06/tako-operational-efficiency) が参考になるかと思います

### アンケートの送信
* Google Sheets の問い合わせデータで対応が完了したものを抽出して、翌営業日に問い合わせ者に Slack Workflow Builder Webhook を使ってアンケートを送信しています

### 補足
#### アンケート送信制御
* 社内の人とはいえ、問い合わせ毎に毎回アンケートを送るのを避けるために、アンケート送信履歴を Google Sheets 上に保存しておき、一定間隔が空かないとアンケートは送信しないようにしています

## 回答率を上げるための工夫
### Slack上でアンケート回答を完結させる
Workflow Builder を使う前は、Google Forms を使っておりましたが、やはり画面遷移を伴う Google Forms より Workflow Builder の方が約1.3倍ほど回答率が高い結果となりました。

### アンケート送信日時の調整
アンケート送信日時は、12時30分頃にしています。以前はコアタイム開始の11時にしていたのですが、チームでの朝会を行っている方も多そうだったため、比較的社内でMTGが少なそうな時間にしております。こちらも若干ではありますが、送信時間の変更後は回答率が上昇しました。

# 取り組みをはじめて良かった点
実際に生の声をいただくことで、私達に期待されていることと提供している価値のズレがあることに気づくことができました。  
またこれは意図していなかったことではありますが、非常にありがたいことに感謝の声をいただくことも多く、問い合わせ対応のモチベーションアップにもなりました。
（チームでは、「もっと早く,正確な回答を」という意識になっていると思います）

# 最後に
Slack Workflow Builderを用いた社内アンケートの取得方法をご紹介させていただきました。  
アンケートの取得方法は、様々な方法があると思いますので、状況に応じて選択していただければよいのかなと思っています。  

ただ実際にアンケートを取って思ったことは、聞いて分かることは聞いたほうが早いということです。チームで考えるのももちろん必要ではあると思いますが、それだけでは限界がありますし、また実際に接点を持ったことがある方から生の声をもらったほうがより効果の高い改善が見つかることもあるかと思います。  

ぜひ私達と同じように社内に向けて活動している方で、業務改善に悩んでいる方の参考になれば幸いです。
Laravelプロジェクトをcloneした後、「500 Server Error」が表示される


#原因
環境構築時に.envファイルが作成されていなかったことでした。

#前提
Laravelで作成されたアプリケーションには.envファイルが必要です。
.envファイルはアプリケーションが実行されるときの環境ごとの設定値を持ちます。

引用：[Laravel 7.x 設定](https://readouble.com/laravel/7.x/ja/configuration.html)
>新たにLaravelをインストールすると、アプリケーションのルートディレクトリには、.env.exampleファイルが含まれています。ComposerによりLaravelをインストールした場合は自動的に、このファイルは.envにコピーされます。Composerを使わずにインストールした場合は、コピーしてください。

Composerを使ってインストールしたので、.envができている想定でしたが今回は作られていませんでした...。
.gitignoreに「.env」が設定されてしまっていたから？

#今回の事象
1. composer installコマンドの実行時に.env.exampleをコピーした.envが作成されなかった。
1. 上記のせいでphp artisan key:generateコマンドが実行されず、アプリケーションキーに文字列が設定されていなかった。


#対処
上記の作業を手で行う。

```php
// .env.exampleファイルをコピーして.envファイルを作成する
cp .env.example .env

// .envファイルのAPP_KEYにランダムな文字列を設定する
php artisan key:generate
```

#確認

```php:.env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:<ここに文字列が設定されていればOK！>
APP_DEBUG=true
APP_URL=http://localhost
```

無事に接続できました。

#参考
https://stackoverflow.com/questions/55706113/server-error-500-when-accessing-laravel-5-8
WindowsとMac間でzipファイルを解凍する

#はじめに
Windowsで作成されたzipファイルをMacで解凍しようとした際、
解凍は成功するが、中身のファイルに問題があるということを経験したので備忘録として残しておきます。

#実行環境
- OS : macOS Big Sur
- zipファイル解凍 : アーカイブユーティリティ（標準アプリ）

#原因
WindowsとMacがファイル圧縮時に使用する文字エンコードの違いで文字化けが起きてしまっていた。

- Windows  
> `UTF-8`
ASCIIと同じ文字は1バイト、その他の文字については2～6バイトを用いて世界中の文字を表現する文字符号化形式

- Mac
> `Shift-JIS`
JIS漢字コード体系を変換したものであり、英数カナ（1バイト系文字）コードと混在しても区別できる

#解決方法
今回は２つの方法をご紹介します。  

① 解凍ソフトを用いてzipファイルを解凍する
② ターミナルでコマンドを使用してzipファイルを解凍する

##① 解凍ソフトを用いてzipファイルを解凍する

**The Unarchiver**
Mac App Storeでも人気があり、既にダウンロードされている方も多いかもしれません。
[ダウンロードはこちらから](https://apps.apple.com/jp/app/the-unarchiver/id425424353?mt=12)

![The Unarchiver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/9f906d87-133b-49c7-88a1-c7088f7740bd.png)

> The Unarchiverは展開するアーカイブでエンコードされているファイル名を検出して、正しく処理するので、ファイル名を文字化けさせることなく世界のどこからきたファイルでも開くことができます。

上記の通り、文字化けさせることなくファイルを開くことが可能です。

- フォルダ展開先を変更したい場合  
アプリケーション「The Unarchiver」→「環境設定」→「展開」
![The Unarchiver_環境設定（展開）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/db2d2a56-6d6d-f649-9da8-c127a83b94d1.png)

「アーカイブの展開先」から展開先に指定したい場所を選択する
（デフォルトは「アーカイブと同じフォルダ」）


##② ターミナルでコマンドを使用してzipファイルを解凍する

ターミナルを起動し「unzip」コマンドを実行する。

- コマンド実行例

```
unzip ~/Desktop/xxx.zip
```
※「xxx」はzipファイル名を指定する

#参考サイト
- [WindowsとMac間でzipファイルを文字化けせずに解凍する方法](https://togeonet.co.jp/post-2466)
- [zipファイルをunzipコマンドで展開する方法
（macOS）](https://www.screen.co.jp/ga_product/sento/support/QA/sol_006.html)
/optへhomebrewをインストールする

[brew公式](https://brew.sh/index_ja)

## アンインストール

```zsh
 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
```

## /opt/homebrewへのインストール

```zsh
cd /opt
sudo mkdir homebrew
sudo chown ${USER}:staff homebrew
```

```zsh
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
```

## ~/.zshrcへ以下を追記
export PATH=$PATH:/opt/homebrew/bin
export HOMEBREW_CACHE=/opt/homebrew/cache

## 本文中のコマンドライン簡易解説
```zsh
sudo chown ${USER}:staff homebrew
```
chownはchange ownerの略です
\${USER}で、$USERがそこに入ります
chown 所有者:グループ名 という書き方で、フォルダの所有者を所有者に、グループをstaffにします。homebrewを/usr/local/binに入れるなら必要ない話です
staffは、グループのパーミッションで、adminの反対です。

## 参考

https://qiita.com/usamik26/items/601f5612bd3f8a21cc41

https://qiita.com/haruf/items/39f4851c005e68af38a8

https://www.webdesignleaves.com/pr/plugins/mac_terminal_basics_01.html
【Rails】APIにCORS設定する手順

##はじめに
RailsをAPIサーバとして使用することが多いと思います。
その場合ビュー(**V**)の役割であるReact等を用いたフロントエンド側サーバ(Node.js)から、Railsにリクエストを投げることになりますが、その際に避けて通れないRails側でのCORS設定の手順を自分用にまとめました。


## 手順
① **gemfileに "rack-cors"を記述し、$ bundle install を実行**

```Gemfile
# 以下の文をGemfileに追記
gem 'rack-cors'
```

 →bundle installを実行すると、config/initialize配下にcors.rbファイルが生成されます。



② **作成されたcors.rbに、以下のコードを記述**

(ⅰ) 全てのオリジンを許可する場合

```cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :patch, :put]
    credentials: true # cokkieを利用する場合のみ記述
  end
end
```

(ⅱ) 特定のオリジンのみ許可する場合  (例. 'localhost:3000'のみを許可)

```cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:3000' # 許可させたいオリジン名を記述 (これは'localhost:3000'の場合の例)
    resource '*', headers: :any, methods: [:get, :post, :patch, :put]
    credentials: true # cokkieを利用する場合のみ記述
  end
end
```
ArduinoUno: 光センサ・モジュールを使う

Arduino の光センサ・モジュールを使う方法です。
>A0 に 光センサ・モジュール
>I2C に Grove-LCD RGB Backlight v4.0
>を接続します。
![IMG_20210719_154849.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/06c6ee65-99b3-bee2-a825-204cbbad0d15.jpeg)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/bd28db0c-49fd-c843-30f6-9ba6c26a4d22.png)

```text:light/light.ino
#include "rgb_lcd.h"
rgb_lcd lcd;

int val = 0;

void setup() {
	lcd.begin(16,2);
	lcd.setRGB(0, 255, 255);
}

void loop() {
    val = analogRead(A0);
    lcd.setCursor(0,0);
    lcd.print ("val = " + String(val) + "      ");
    delay(500);   
}
```
[Docker] mssql-server-linuxのイメージがdocker hubから無くなっていた。

普段SQL Server使う機会が滅多にないので、全然情報追えてなかったです。
保守してるサービスを久しぶりに立ち上げたら動かなかったのでメモメモ。

エラー文はこんな感じでした。

```
$ docker-compose up -d

Pulling sqlserver (microsoft/mssql-server-linux:2017-latest)...
ERROR: pull access denied for microsoft/mssql-server-linux, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
```

SQL serverのイメージなくなるとかあるの？
docker loginの方かなと思いながらとりあえず調べてみることに。

元のdocker-compose.yamlの記述はこんな感じ。

```yaml
version: '2'
services:
  sqlserver:
    image: microsoft/mssql-server-linux:2017-latest
```

2017なので、ちょっとバージョンが古い気もするが一旦気にしないことに。
docker hubみてみると、microsoft/mssql-server-linuxがない。

Microsoft SQL Serverで調べてみたら

```
docker pull mcr.microsoft.com/mssql/server:2017-latest
```
となっていました。

docker hubの説明に、
Official images for Microsoft SQL Server on Linux for Docker Engine.とあるので、
多分使えそうだなと思い、試してみることに。

docker-compose.yamlを書き換えます。

```yaml
version: '2'
services:
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2017-latest
```

これで動きました。

docker imageの置き場所変えたみたいです。
いつからなんだろう。

mcr.microsoft.com/mssql/serverと記載のあるドキュメントの日付が2021/06/11で、
それよりは前っぽいですね。

[Quickstart: Run SQL Server container images with Docker](https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-2017&pivots=cs1-bash)
Rails consoleでrake taskを呼び出す

デバッグやバッチ処理内でRake taskを呼び出したいときの対応

```ruby
Rails.application.load_tasks
Rake::Task['my_task'].execute
# 引数を渡す
Rake::Task['my_task'].execute('arg_string')
Rake::Task['my_task'].execute(hoge: 'moge')
```

`my_task` には `hoge:moge` など `rake hoge:moge` と指定する名前が入ります。
他サンプルだと `require 'rake'` しているものもありますが `rails c` で入っている分には不要でした。


https://stackoverflow.com/questions/4826951/how-to-run-rake-tasks-from-console


---

※こちらの記事は自ブログからの転載です

https://akinov.hatenablog.com/entry/2021/07/19/150011
【Ruby】roundメソッドなど小数点の四捨五入について

#はじめに
今回は、小数点の四捨五入などを行うroundメソッドを始めとしたものを紹介していきます。
round以外にも小数点の切り上げや切り下げも合わせて書いていきます。

#小数第N位で四捨五入する
##roundメソッド
roundメソッドは、引数に小数点以下の桁数を入力すると、それより下の桁を四捨五入してくれます。
実行例が以下になっています。

```ruby
123.456.round
=> 123
# 小数第1位を四捨五入しているので、123が表示される。

123.456.round(1)
=> 123.5
# 引数で小数第1位を指定しているため、第2位の5を四捨五入して繰り上げ。

123.4599.round(3)
=> 123.46
# あくまで四捨五入するだけなので、0を補填しない
```

#小数第N位で切り捨て
##floorメソッド
こちらは引数で指定した桁数で切り捨てするメソッドです。
実行例が以下になっています。

```ruby
123.456.floor
=> 123
# 小数点を切り捨てする。

123.456.floor(1)
=> 123.4
# 引数で小数第1位を指定しているため、第2位から切り捨てする。

123.45678.floor(3)
=> 123.456
```

#少数第N位で切り上げ
##ceilメソッド
最後は切り上げのメソッドです。
引数の指定方法は上記2つと同じです。
こちらも実行例が以下になっています。

```ruby
123.456.ceil
=> 124
# 小数点を切り上げする。

123.456.ceil(1)
=> 123.5
# 引数で小数第1位を指定しているため、第2位から切り上げする。

123.123456.ceil(3)
=> 123.124
```

#まとめ
**少数の四捨五入には、roundメソッド。
切り捨てには、floorメソッド。
切り上げのには、ceilメソッド。**

非常にシンプルですね！
**引数で指定した値の1つ下の桁を操作するってことを覚えておくことがミソなんですかね。**

以上です。
読んでいただき、ありがとうございました！