OmniAICreator/Qiita-1.07M huggingface dataset:
ruby文字列の定数とfreeze

# 定数

## 定義

アルファベット大文字 ([A-Z]) で始まる識別子は定数です。

## 実験その1

### 実行結果
```
[27] pry(main)> HOGE = 'hoge'
=> "hoge"
[28] pry(main)> HOGE = "foo"
(pry):28: warning: already initialized constant HOGE
(pry):27: warning: previous definition of HOGE was here
=> "foo"
[29] pry(main)> HOGE
=> "foo"
```

### 結論
一度定義された定数に再び代入を行おうとすると警告メッセージが出ます。代入することは成功になります。


## 実験その2

### 実行結果
```
[30] pry(main)> HOGE = 'hoge'
(pry):30: warning: already initialized constant HOGE
(pry):28: warning: previous definition of HOGE was here
=> "hoge"
[31] pry(main)> HOGE.gsub!('h', 'f')
=> "foge"
[32] pry(main)> HOGE
=> "foge"
```

### 結論
破壊的なメソッドを呼び出すと警告メッセージが出せずに成功になりました。

# freeze

## 定義

オブジェクトを凍結（内容の変更を禁止）します。

## 実験その1

### 実行結果
```
[34] pry(main)> hoge = 'hoge'.freeze
=> "hoge"
[35] pry(main)> hoge = 'foo'
=> "foo"
[36] pry(main)> hoge
=> "foo"
```

### 結論
一度凍結された文字列の変数に再び代入を行おうとすると警告メッセージが出せずに成功になりました。

## 実験その2

### 実行結果
```
[37] pry(main)> hoge = 'hoge'.freeze
=> "hoge"
[38] pry(main)> hoge.gsub!('h', 'f')
RuntimeError: can't modify frozen String
from (pry):38:in `gsub!'
[39] pry(main)> hoge
=> "hoge"
```

### 結論
破壊的なメソッドを呼び出すとエラーになりました。

# 組み合わせると

## 実験その1

### 実行結果
```
irb(main):001:0> HOGE = 'hoge'.freeze
=> "hoge"
irb(main):002:0> HOGE = 'foo'
(irb):2: warning: already initialized constant HOGE
(irb):1: warning: previous definition of HOGE was here
=> "foo"
irb(main):003:0> HOGE
=> "foo"
```

### 結論
定数と同じく、一度定義された定数に再び代入を行おうとすると警告メッセージが出ます。代入することは成功になります。

## 実験その2

### 実行結果
```
irb(main):001:0> HOGE = 'hoge'.freeze
=> "hoge"
irb(main):002:0> HOGE.gsub!('h', 'f')
RuntimeError: can't modify frozen String
	from (irb):2:in `gsub!'
	from (irb):2
	from /Users/longlong.li/.rbenv/versions/2.3.0/bin/irb:11:in `<main>'
irb(main):003:0> HOGE
=> "hoge"
```

### 結論
freezeと同じく、破壊的なメソッドを呼び出すとエラーになりました。

# まとめ

rubyはパフォーマンスが良くないという指摘がよくあると思うけど、普段の実装でさらにコードのパフォーマンスを注意しなければいけない。
ref:
https://www.educba.com/javascript-vs-ruby/
https://www.techmagic.co/blog/nodejs-vs-ruby-on-rails/

## 定数のメリット

```
irb(main):001:0> HOGE = 'hoge'
=> "hoge"
irb(main):002:0> HOGE.object_id
=> 70133661978580
irb(main):003:0> 'hoge'.object_id
=> 70133661959980
irb(main):004:0> 'hoge'.object_id
=> 70133579010700
irb(main):005:0> HOGE.object_id
=> 70133661978580
irb(main):006:0> HOGE.object_id
=> 70133661978580
```

文字列を何回呼び出すと新しいアドレスにスペースを開けてobjectを作ります。
定数の場合は、同じアドレスの値を参照する。変数の場合も同じ。

## freezeのメリット

定数を定義された場合は、再び代入する際はwarnningがあるけど、破壊的なメソッドを呼び出したら、何の提示出て来ない。定数を固定するためにfreezeで強制的に文字列を凍結した方がいいと思います。

```
irb(main):001:0> HOGE = 'hoge'.freeze
=> "hoge"
irb(main):002:0> HOGE.object_id
=> 70152318756020
irb(main):003:0> HOGE.gsub!('h', 'f')
RuntimeError: can't modify frozen String
	from (irb):3:in `gsub!'
	from (irb):3
	from /Users/longlong.li/.rbenv/versions/2.3.0/bin/irb:11:in `<main>'
irb(main):004:0> HOGE.object_id
=> 70152318756020
irb(main):005:0> HOGE = 'hoge'.freeze
(irb):5: warning: already initialized constant HOGE
(irb):1: warning: previous definition of HOGE was here
=> "hoge"
irb(main):006:0> HOGE.object_id
=> 70152318756020
```

# Tips

Ruby 2.x. から下記の一行をファィルの頭で記入すると、静的な文字列は自動的に凍結されます。
```
# frozen_string_literal: true
```
都度`.freeze`を追加する必要はなくなって、結構便利です。
縦向きのYoutube動画をいい感じに埋め込むには？

# はじめに
イメージはこんなんです！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">aspect-ratio: 16 / 9;<br>こんな便利なcss、いつからあったねんw<br><br>いい感じに埋め込める！<a href="https://t.co/BU6FvV63HZ">https://t.co/BU6FvV63HZ</a> <a href="https://t.co/b2ON8YskHk">pic.twitter.com/b2ON8YskHk</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1502226653426388997?ref_src=twsrc%5Etfw">March 11, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Youtubeの埋め込み方でいい感じにレスポンシブ対応させる記事を見てると、大体が横向き動画のパターンだったので、、、:sweat_smile:

**「あれ？縦向きの動画はどうするんや？？」**
と思ったので、調べた結果をまとめます！

# パターン１aspect-ratio を使った方法
`aspect-ratio`はIEやアップデートされていないSafariなどでは使用できないらしいので、要注意です！
横向き動画は`aspect-ratio: 16 / 9;`なので、単純に`9 / 16`と逆にすればOKですw
これだけで縦向き動画がレスポンシブで埋め込めます！便利〜〜

```html
   <div class="video">
        <iframe
          width="100%"
          height="100%"
          src="https://www.youtube.com/embed/bWEN90ssyMU"
          title="YouTube video player"
          frameborder="0"
          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
          allowfullscreen
        ></iframe>
      </div>
```

```css
.video {
  width: 100%;
  aspect-ratio: 9 / 16;
}

.video iframe {
  width: 100%;
  height: 100%;
}
```

# パターン２padding-top を使った方法
**※HTMLに変化はありません**

>なぜ padding-top が 56.25% なのか？
padding-top の％指定は、要素の横幅に対する割合で計算されます。
例を挙げると、横幅 100px の要素に対して、padding-top を 50% に指定した場合、100px の 50% 分なので、padding-top は 50px になります。
今回の埋め込み動画の場合は、縦横比が 16:9 となっていることが多いです。
56.25% という数値は、9 / 16 = 56.25 から算出されています。横幅 16 に対して縦幅が 9 になるように計算されるので、要素の width が可変した分、縦幅もぴったり 16:9 の割合で可変してくれます。

`9 / 16 = 56.25`なので、この計算式を逆にして`16 / 9 = 1.7777~`なので**padding-topは170%**になります！

```css
.video {
  position: relative;
  height: 0;
  // padding: 30px 0 56.25%; これが横向き！
  padding: 30px 0 170%;
  overflow: hidden;
}

.video iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
```

# 参考

https://hirashimatakumi.com/blog/6601.html

https://www.white-space.work/make-responsive-iframe-using-css/
AWS LambdaでS3イベントが発火しない

# はじめに
S3のアップロードイベントでAWS Lambdaを動かす、あるあるな構成でシステムを構築したところ、Lambdaが起動しない事態に直面しました。

# 結論
イベント設定のプレフィックスに不要な半角スペースが入っていた。

# コメント
動かないときはすべてを疑うとよいです。当たり前ですが。  
私恥ずかしながらAWSは3年くらい携わってますが、ハマりました。  
イベント設定するときに、マネジメントコンソールのS3の上のリンクみたいなところをコピってペーストしてたのですが、それがいけませんでした。  
Lambdaの画面からイベント詳細確認しても、ぱっと見正しい（半角スペース入っていない）ように見えるんです。厄介。  
ググっても結論にたどり着けなかったので今回記事にしておきました。  
参考になった方、何かしらの反応いただけると嬉しいです（笑）
Azure DevOps Pipeline で Azure Functions v2 をビルドする

Azure DevOps Pipeline で利用されるイメージから .NET 2.1 が削除された。

https://github.com/actions/virtual-environments/issues/4871

古い Azure Functions v2 プロジェクトなどでは、[.NET Core 2.1が必要](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-dotnet-class-library?tabs=v2%2Ccmd#supported-versions)となるので、今まで [DotNetCoreCLI@2](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops) の タスクの `build` コマンドでビルドできていたものがビルドできなくなる可能性がある。

テンプレートから選択できる Azure Functions for .NET のパイプラインを利用している場合などに影響がでる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/8d7c23f2-f0da-2077-4b68-6a38df5269ef.png)

特定の .NET SDK を利用するには [UseDotNet@2](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops) タスクを利用して必要な .NET SDK を事前にインストールしておく必要がある。



```
pool:
  name: Azure Pipelines
steps:
- task: UseDotNet@2
  displayName: 'Use .NET Core sdk 2.1.x'
  inputs:
    version: 2.1.x

- task: DotNetCoreCLI@2
  displayName: 'Build project'
  inputs:
    projects: '**/*.csproj'
    arguments: '--output publish_output --configuration Release'

- task: ArchiveFiles@2
  displayName: 'Archive files'
  inputs:
    rootFolderOrFile: 'publish_output/'
    includeRootFolder: false

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'
```
パスワードのテストでHash::check()がtrueを返し続けた件。


```
$this->assertTrue(Hash::check($password, User::latest()->first()->password));
```

なぜ？あぜ？と思ったが、原因は、

```
User::latest()->first()->password;
```
で、最後のレコードが取れていないことが原因だった。というのもテストでは複数のレコードにおいてcreate_atの時間が同じになるので、結果、一番最初のレコードが取れてきてしまっていた。

で、解決策はこれ。

```
$this->assertTrue(Hash::check($password, User::all()->last()->password));
```
これで、最後のレコードのパスワードがとれるようになった。めでたしめでたし。
Amazon Linux 2 Arm64 に docker-compose をインストールし実行するとワーニングとエラーが出る

## 現象
Amazon Linux 2 に docker-compose をインストールして実行すると以下のようなワーニングとエラーが出る。


```
$ docker-compose
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
standard_init_linux.go:228: exec user process caused: exec format error
```

## 原因
[公式ドキュメントのコンテナとしてのインストール](https://docs.docker.jp/compose/install.html#install-as-a-container)の手順で docker-compose をインストールした場合にこのエラーが出ます。

## 対応方法
[こちら](https://github.com/docker/compose/releases)から docker-compose-linux-aarch64 のバイナリーをダウンロードしてインストールしましょう。
Composerとは

ライブラリ依存管理ツール。
PHPで開発するにあたって、便利なライブラリやフレームワークをまとめてインストールできる。
よって、開発者がひとつひとつインストールしなくても、同じ環境を再現できる。

# インストール方法
ターミナルからDownload Composerのコマンドを入力
https://getcomposer.org/download/

# 実行パスが通るように`composer.phar`を移動する
`ほにゃららパスcomposer`とかかなくても`composer`で実行できるよう移動する
`sudo mv composer.phar /usr/local/bin/composer`

# 動作確認
`composer -V`

# 補足
インストールするライブラリたちは`composer.json`の記述する

# 参考サイト
https://hirooooo-lab.com/development/install-composer/
親のViewModelを参照する方法

# はじめに
ViewPagerを使っていると、Pager内の画面と親のFragmentでやりとりを行い、何かしらのアクションを起こしたい、ってことありますよね
最近ではViewModelを通して親子でやり取りするようなやり方が主流な気がしますが、Pager内のFragmentで親のViewModelを取得する方法を簡単に残しておこうと思います。

# ViewModelの取得方法
取得方法は非常に簡単です。

```
private val parentViewModel by viewModels<TestViewModel>({ requireParentFragment() })
```
以上です。
基本的なViewModelの取得方法にrequireParentFragmentを指定するだけになります。
上記で親のViewModelを取得可能です、あとはLiveData等を使って親Fragmentへ通知したりする形になるかと思います。

# さいごに
親のViewModelを取得するのは簡単なのですが、ViewPagerを使うと双方の関係性が複雑になりがちなので、あらかじめしっかり設計しておく必要はあると思います。
特にViewPagerを使用する想定の画面が複数あると最初の画面をベースに作るケースが多いので、最初ほどしっかり考えてから実装しておきたいですね。
Pythonでtifから複数枚の画像を保存する方法


TIFF形式に含まれる複数の画像を一枚一枚取り出して保存する方法を扱います．

```python
import cv2
from tifffile import TiffFile
import numpy as np

tifpath = "./hoge.tif" # tifファイルのパス
imgpath = "./folder/" # 画像ファイルを保存したいフォルダのパス

with TiffFile(tifpath) as tif:
    mmap = tif.asarray(out="memmap")

# 最初の画像から順番に保存
for i in range(len(mmap)):
	img = np.asarray(mmap[i])
	img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
	#4ケタの0埋めでファイル名をつける
	cv2.imwrite("{0:s}{1:04d}.png".format(imgpath, i+1),img) #"png"は適宜変更 
```

以上です．
レジストラロック ってなに？

## 勉強前イメージ

移行する時に使用をロックする？

## 調査

### レジストラロック とは

ドメインロックとも呼ばれています。
各 [レジストラ](https://qiita.com/miyuki_samitani/items/ac8bf32554872a701735) で行っている機能で
不正にレジストラ(ドメインを登録する事業者)の変更(移管)を防止するために管理事業者でロックをし
レジストラ変更が第三者の手によって行えないようにするもののことを指します。

基本的には他社への移転を行う際しかレジストラロックの解除ができないので
解約手続きを行ってからロック解除できることが多いです。

移管というのは、レジストラに申請を行うのですが、移管申請は誰でも行うことが出来ます。
一応ドメインの所有者が承認した状態で移行を行うことが出来ますが、メール等と乗っ取られてしまっていると
移管申請も突破されてしまいます。
そのためドメインロックを行うと不正な移管を防ぐことが出来ます。

## 勉強後イメージ

なるほど・・・乗っ取られると移管まで出来てしまうのか....

## 参考

- [ドメインロック（レジストラロック、トランスファーロック）とは？](https://rs.fitallright.com/domain-lock/)
- [レジストラロック](https://www.xserver.ne.jp/manual/man_domain_register_lock.php)
Amazon Linux 2 64 ビット (Arm)でcurlを使ったdocker composeのインストールができないとき

## 現象
Amazon Linux 2 64 ビット (Arm)のEC2インスタンス上で、公式ドキュメントの https://docs.docker.jp/compose/install.html#linux-compose に記載のcurlを使ってdocker composeをインストールすると、実行時に以下のエラーが出る

```shell
$ docker-compose
/usr/local/bin/docker-compose: 行 1: Not: コマンドが見つかりません
```

## 原因
curlコマンドの内容がarm64に対応していないバージョンであることが原因。本記事を書いている時点ではcurlに記載のdocker composeのバージョンは1.16.1であり、そのバージョンにはarm64対応のバイナリーがないためにダウンロードが失敗する。

## 解決方法
https://github.com/docker/compose/releases の Assets に記載のリンクから目的のバイナリーを手動でダウンロードする。

もしくは、curlにURLを指定してダウンロードする。下記の例は現時点での最新版のバージョンをダウンロードしてインストールする。

```
sudo curl -L https://github.com/docker/compose/releases/download/v2.3.3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

```
【Swift】他アプリからファイルを受け取る

# 備忘録

iOS15

### 受け取るファイルの拡張子を指定
![スクリーンショット 2022-03-11 17.27.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219469/2d6dd473-b89a-47c5-f954-a686a4e0ca08.png)


```swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        if let url = connectionOptions.urlContexts.first?.url {
            save(url)
        }
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else {
            return
        }
        save(url)
    }
    
    private func save(_ url: URL) {
        //urlを使ってローカルへコピー
    }
    
}

```
GitHub のリポジトリのコピー

samplea のリポジトリーを sampleb に移す例です。

ソースのリポジトリー
　https://github.com/samplea/test01.git

ターゲットのリポジトリー
https://github.com/sampleb/test01.git

　ターゲットは、空のリポジトリーを事前に作成します。

ブランチも含めて、リポジトリーをローカルにコピーします。

```bash
git clone --bare https://github.com/samplea/test01.git
```

ブランチも含めて、リポジトリーを　アップロードします。

```bash
cd test01.git
git push --mirror https://github.com/sampleb/test01.git
```

## エラー対策 ##

次のようなエラーが出た場合

```text
 ! [remote rejected] main (refusing to delete the current branch: refs/heads/main)
error: failed to push some refs to 'https://github.com/sampleb/test01.git'
```

ターゲットのリポジトリーで　デフォールトのブランチを main から master に変更します。
そして、もう一度

```text
git push --mirror https://github.com/sampleb/test01.git
```
PHP final定義

# finalメソッド・final定数
PHPにおいて、finalで定義されたメソッドや定数は子クラスから上書きできない。

```php
<?php
class BaseClass
{
  final function hoge()
  {
    // 処理
  }
}

class ChildClass extends BaseClass
{
  public function hoge() 
  {
    // 上書き処理
  }
}

// Results in Fatal error: Cannot override final method
// finalメソッドを上書きできない
```

# finalクラス
final定義されたクラスは継承することができなくなる。

```php
final class HogeClass
{
  // クラス内容
}

class ChildClass extends HogeClass
{
  // クラス内容
}

// Results in Fatal error: Class ChildClass may not inherit from final class (HogeClass)
// finalクラスは継承できない
```

# 参考
[PHP: finalキーワード](https://www.php.net/manual/ja/language.oop5.final.php)
VBA Worksheet_Changeイベントの制御

エクセルのワークシートでChangeイベント利用時に、セルの値を変更する場合のイベント整理方法

# Worksheet_Change
```
Public Const flg_Cancel_chgEvent as Boolean
'------------------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
    If flg_Cancel_chgEvent = True Then GoTo finaly_
finaly_:
End Sub
```



# セルの値の書き換え処理の前後
~~~
　flg_Cancel_chgEvent = True:    Me.Unprotect
  Target.Offset(1, 0).Value = "↑ 未登録"
　flg_Cancel_chgEvent = False:    Me.Protect
~~~


# 注意点

イベントキャンセル、プロテクトon は抜け漏れがでやすい
→　セルの値の変更前後に、この処理を入れること
    ~~親プロセス~~
    子プロセスに逐一書く
Vuetifyのrulesで引数を設定する

Vuetifyのv-text-fieldなどでrulesに設定する関数は通常引数を与えることはできないが、**ルール関数を返す関数**を設定することで引数を与えることができる。
```vue
<template>
  <div>
    <!--10以上の数値を入力するフィールド-->
    <v-text-field
      :rules="[ruleMoreThan('10')]" />
    <!--20以上の数値を入力するフィールド-->
    <v-text-field
      :rules="[ruleMoreThan('20')]" />
  </div>
</template>

```

Scriptの記述。
```TypeScript
const ruleMoreThan = (baseNumber: string) => {
  return (value: string) => 
    Number(value) > Number(baseNumber) || `${baseNumber}以上の数値を入力してください`
}
```
HITRANデータベースのAPIであるHAPIを使用した放射スペクトルの計算

# HAPIとは
[HITRANonline: HAPI](https://hitran.org/hapi/)
HITRANという大気中の光の透過と放射をシミュレーションに必要な分光学的パラメータのデータベースを取り扱うためのAPIです．Pythonで記述されているスクリプトをダウンロードもしくはpipでインストールすることによりローカル環境で使用することができます．
HAPIの主な機能は以下の通りです．

1. line-by-lineデータをオンラインのHITRANデータベースからダウンロード
2. 圧力，温度，光学的な経路の長さを考慮した高分解能のスペクトルのシミュレーション
3. 実験装置の分解能を考慮したスペクトルへの補正

以下の種類のスペクトルについて計算可能です．

1. 吸収係数
2. 吸収スペクトル
3. 遷移スペクトル
4. 放射スペクトル

@alphya さんにより吸収係数の計算についての[記事](https://qiita.com/alphya/items/794b1e792469274d7561)を書かれています．この記事では，HAPIを用いて放射スペクトルの計算および実験データの再現についてまとめます．

# データのダウンロード
HAPIの公式サイトの[リンク](https://hitran.org/static/hapi/hapi.py)より，Pythonスクリプトをダウンロードして，計算を実行するフォルダに置いておきます．スクリプトを実行できる環境で以下のコードでinportします．コードではついでに以下で使用するモジュールをinportしています．

```Python
from hapi import *

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

```

以下のコードでHITRANからデータを取得します．詳細はHAPIの[マニュアル](https://hitran.org/static/hapi/hapi_manual.pdf)を参考にしていただくことにして，今回は水のデータを取得しています．`fetch`の4番目と3番目の引数は取得するデータの波数の範囲を指定しています．今回は200 nmから1000 nmまでの波長のスペクトルのデータを取得したいので，10000 cm-1から50000 cm-1の波数の範囲を与えています．

```Python
db_begin('data')
fetch('H2O', 1, 1, 10000, 50000)
```

# 放射スペクトルの計算

以下の`absorptionCoefficient_Lorentz`で吸収係数の計算を行い，その計算結果をもとに`radianceSpectrum`で放射スペクトルの計算を行っています．`radianceSpectrum`ではパラメーターとして温度と光路の長さを与えることができます．nuが波数，coefが吸収係数，radiが放射スペクトルのndarrayを返しています．

```Python
nu, coef = absorptionCoefficient_Lorentz(SourceTables='H2O', HITRAN_units=False)
nu, radi = radianceSpectrum(nu, coef, Environment={'T': 1500.0, 'l': 100.0})
plt.plot(nu, radi)
```

プロットされた結果は以下の通りです．波数の小さい=波長の長い光ほど高い強度で発行していることがわかります．

![radi_nu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/12f1f390-c57b-d728-7386-da794d0ae2b2.png)

# 波長への変換

得られた結果は波数[cm-1]に対するスペクトルのデータであるので，これを波長[nm]に対するデータに変換します．

```Python
wave_length = np.divide(1.0, nu*1e2)*1e9
plt.plot(wave_length, radi)
```

以下のプロットより，高い波長になるほど発光強度が増加している確からしい結果が得られました．

![radi_wave_length.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/debf1485-ee78-3950-6d46-f79cee90baee.png)

# 実験結果への合わせこみ

分光器などを用いた実験結果との比較を行う際には，装置の分解能を考慮する必要があります．HAPIでは`convolveSpectrum`という関数を用いてこれを行う事が出来ます．詳しいオプションについてはHAPIのマニュアルを確認してみてください．ここではスリットファンクションにガウシアンを，分解能を0.5として設定しています．注意点としては，`convovleSpectrum`を行うと波数nuのサンプルが引数に与えたものから変化するので，wave_lengthもそれをもとにもう一度変換する必要があります．

```Python
nu_, radi_, i1, i2, slit = convolveSpectrum(nu, radi, SlitFunction=SLIT_GAUSSIAN, Resolution=0.5)
wave_length_ = np.divide(1.0, nu_*1e2)*1e9
plt.plot(wave_length_, radi_, label='convolved')
```
以下が実行後のプロットですが，ピークの現れ方が変化したことがわかります．ここからは自分の実験データと見比べながら各パラメータを合わせこんでみてください．

![radi_wave_length_convovled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/fefff096-a83e-7127-d345-b3744f1d85d8.png)
Dockerでスクレイピング環境構築

自分1人では、環境をサクッと構築しスクレイピングしていましたが、メンバー間で共有したいときに面倒だったのでDockerで再現しました。
GoではHTMLの操作に、Agoutiを使用。
HTML解析には、goqueryを使っています。

# サンプルコード
```go:main.go
package main

import (
	"log"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/sclevine/agouti"
)

func main() {
	log.Println("処理開始...")

	// ChromeDriver
	driver := agouti.ChromeDriver(
		agouti.ChromeOptions("args", []string{
			"--headless",
			"--window-size=1280,800",
		}),
		agouti.Debug,
	)

	if err := driver.Start(); err != nil {
		log.Fatalln("Chromeドライバ起動に失敗しました。")
	}
	defer driver.Stop()

	page, err := driver.NewPage(agouti.Browser("chrome"))
	if err != nil {
		log.Fatalln("Chromeでページを生成できませんでした。")
	}

	if err := page.Navigate("https://example.com"); err != nil {
		log.Fatalln("該当ページに遷移できませんでした。")
	}

	getAll, err := page.HTML()
	if err != nil {
		log.Fatalln("遷移後のHTML(一覧)取得失敗しました。")
	}
	readerGetAll := strings.NewReader(getAll)
	contentDom, _ := goquery.NewDocumentFromReader(readerGetAll)
	
	if seeText := contentDom.Find("#header > h1 > span").Text(); seeText != "xxxxxx" {
		log.Fatalln("対象の文字列はありませんでした。")
	}

	log.Println("正常に処理が終了しました。処理を終了します。")
}

```

```:Dockerfile
FROM ubuntu:latest

RUN apt update &&\
    apt install -y wget curl unzip make tzdata software-properties-common

RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \
    && curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip \
    && unzip /tmp/chromedriver_linux64.zip \
    && mv chromedriver /usr/local/bin/

RUN add-apt-repository ppa:longsleep/golang-backports \
    && apt install -y golang-1.17

ENV TZ=Asia/Tokyo

ENV GO111MODULE=on
ENV GOPATH=$HOME/go
ENV PATH=$PATH:$GOPATH/bin

WORKDIR /go/src
```

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

services:
  sgo:
    container_name: sgo
    build: .
    tty: true
    ports:
      - 3030:3030
    volumes:
      - ./:/go/src
```
【PostgreSQL】PostgreSQLのサイレントインストール（Windows）

# はじめに
プロジェクトメンバにPostgreSQLのインストールを依頼する際、 ~~猿~~ 誰がやっても同じ結果になるようにするべく、サイレントインストールを行うバッチファイルを作りました。

# 方法
以下のHPを参考にしました。
[Silent Install](https://silentinstallhq.com/postgresql-12-silent-install-how-to-guide/)

PostgreSQLのバージョンは14.2で、Windows10のマシンにインストールすることを想定して作りました。
実際のコマンドは以下になります。

` postgresql-14.2-1-windows-x64.exe --mode unattended --unattendedmodeui none --prefix "C:\Program Files\PostgreSQL\14" --enable-components server,pgAdmin,stackbuilder,commandlinetools --datadir "C:\Program Files\PostgreSQL\14\data" --superpassword [パスワード] --serverport 5432 --locale C `

※細かい設定内容などは、上記に挙げたHPを参照してみてください。


# やってみてわかったこと
何人かに試してもらったところ、うまくインストールできなかった人がでてきました。
なぜだろうと思い調べてみたところ、インストールの過程でbatファイルが呼ばれるところがあり、そこでセキュリティソフトでブロックされていたようでした。

こちらについては今後どのようにするか検討して、ブラッシュアップして使いやすくしていきたいです。
Kotlin DSLでSpigot/Paperプラグインをビルドする

初投稿です。おねがいします。
Paper-APIのバージョンは1.18.xです。(ほかのバージョンでもちょっと変えればできると思います)
Kotlin DSLを使ってビルドしているSpigot/Paperプラグインの例が少なかったので。
Spigot-APIを使う場合は逐次読み替えてください。

## 新規プロジェクト作成

新規プロジェクト作成の画面を開いて、Gradleを選択します。Kotlin DSLのGradleのテンプレートがないので、[Minecraft Devプラグイン](https://mcdev.io/)は使いません。([Issue](https://github.com/minecraft-dev/MinecraftDev/pull/1033)によると対応しようとしてるものの遅れている？らしい)

![Image from Gyazo](https://i.gyazo.com/8308108f42b613606b8781921e3cee54.png)

上の図のように`Java`と`Kotlin DSL ビルドスクリプト`にチェックを入れてください。プラグインをKotlinで書きたい人は`Kotlin/JVM`にもチェックを入れてください。`プロジェクトSDK`は使いたいAPIに合ったJDKを選択しましょう。

![Image from Gyazo](https://i.gyazo.com/08534344cf0fd08b5e56befed2c727f3.png)

ここらへんは普通にやってください。なんでもいいです。

完了を押すとプロジェクトが出来上がってビルドが始まります。最初はGradleのデーモンを起動するまで長いので待ちましょう。

## ビルド周りを書き換える

ビルドが終わるとシンタックスハイライトされたビルドスクリプトが表示されます。このビルドスクリプト(build.gradle.kts)をいじってAPIが使えるようにしていきましょう。

```kotlin:build.gradle.kts
plugins {
    java
}

group = "com.github.jin-ini" // ここは指定したgroup id
version = "1.0-SNAPSHOT" // ここは指定したversion

repositories {
    mavenCentral()
}

// 以降のテスト関連のところ(junit系)は使わなければ消してしまっていいです。
dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

tasks.getByName<Test>("test") {
    useJUnitPlatform()
}
```

このままではFat Jarをビルドすることができないのでプラグインを入れていきます。また、同時にPaper-APIも使えるようにしていき、ついでにtoolchainで指定してビルドするようにします。

```diff_kotlin:build.gradle.kts
plugins {
    java
+   id("com.github.johnrengelman.shadow") version "7.1.2"
}

group = "com.github.jin-ini"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
+   maven { url = uri("https://papermc.io/repo/repository/maven-public/") } // PaperのMavenリポジトリ
}

dependencies {
+   compileOnly("io.papermc.paper:paper-api:1.18.1-R0.1-SNAPSHOT") // Paper-API
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

+ java {
+     toolchain.languageVersion.set(JavaLanguageVersion.of(17))
+ }

tasks.getByName<Test>("test") {
    useJUnitPlatform()
}
```

Gradleのバージョンが古いものになっていることがあるので最新を指定しましょう。最新リリースは[公式サイト](https://gradle.org/releases/)から確認してください。

```diff_properties:gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
- distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+ distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
```

Gradleをデーモン化していちいち起動を待たなくていいようにします。プロジェクト直下に以下のファイルを作成してください。

```properties:gradle.properties
org.gradle.daemon=true
```

ここまででPaperのプラグインをKotlin DSLでビルドする準備が完了しました。あとは実行構成から`gradle shadowJar`を実行すると`build/libs/`に`プロジェクト名-all.jar`ができます。

## おわり

正直まだまだ初心者なのでこれがベストプラクティスではないと思います。いろいろ試行錯誤してみてください。あとよい方法があったらぜひ教えてください。
Install make & docker & docker-compose on linux

```
# docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

sudo apt install docker-ce make -y

# docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```
Monacaで使えるFramework7 × NCMBのベースアプリを作りました

Monacaで公開されているFramework7テンプレートはv6.0.11や5系で古くなっているので、[オリジナルのテンプレートを作成しました](https://github.com/NCMBMania/MonacaFramework7Base/)。執筆時点での最新版、6.3.16を利用しています。

テンプレートにはニフクラ mobile backendのJavaScript SDKも入れてあります。Monacaアプリ開発に役立ててください。

## 使い方

Monacaのインポートにて、下記URLを指定してください。

```
https://github.com/NCMBMania/MonacaFramework7Base/archive/refs/heads/main.zip
```

Monaca上で利用しているところを動画（アニメーションGIF）で紹介します。

![MonacaBase (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/efeb0e20-67c0-3d29-e063-834561a57434.gif)


## ライブラリのバージョン

- Framework7: 6.3.16
- NCMB JavaScript SDK: 3.1.3

## NCMBの初期化

NCMBの初期化処理は実行済みです（`js/app.js` にて）。ただしアプリケーションキー、クライアントキーは書き換えてください。

`js/config.json` を開くと、次のようになっています。

```json
{
	"applicationKey": "YOUR_APPLICATION_KEY",
	"clientKey": "YOUR_CLIENT_KEY"
}
```

この `YOUR_APPLICATION_KEY` と `YOUR_CLIENT_KEY` を書き換えてください。

## Framework7の使い方

[公式ドキュメント](https://framework7.io/docs/)または[日本語ドキュメント](https://framework7.jp/docs/)を参照してください。Vanilla JSはもちろん、VueやReact、Svelteでも利用できます。UIコンポーネントが多いので、凝ったUIでなければFramework7だけで十分開発可能です。

## ライセンス

テンプレート、Framework7はMIT Licenseになります。NCMB JavaScript SDKはApache License 2.0になります。

[NCMBMania/MonacaFramework7Base: Monaca × Framework7 × NCMBのベースアプリです。](https://github.com/NCMBMania/MonacaFramework7Base/)
Array.someで引数を渡したい


javascriptのArray.someで引数を渡して判定したときのメモ。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some

someを実行する配列がObjectの配列だったりすると、callback関数内での判定の際に複数の値をチェックしたくなると思います。
以下のようにコールバック関数の引数に`this`を入れてあげれば、それを使える。

```typescript
function filterFunc(this:Obj1, element:Obj2){
  //判定処理
}

obj2Array.some(filterFunc, obj1);

```

MDNには以下のようにあって、`thisArg`をどうやって使えばよいかわからなかったのでメモ。

>thisArg 引数が some() に与えられると、それがコールバックのの this として使用されます。それ以外は、undefined 値が this として使用されるでしょう。 callback が最終的に見ることができる this の値は、関数から見た this の決定に関する一般的なルールによって決定されます。
kicadで作った基板をPCBgogoで注文してみた

<h2>基板を出力</h2>
出来上がったPCBデータをこちらのサイトを参考にさせて頂き、出力する。

https://www.kicad.xyz/data-output/

<h2>ファイル作成</h2>
出来上がったファイルを圧縮する。
以下のファイルが出来上がると思うが、今回裏面の
「シルク」と「ペースト」が無いため「B_SilkS」「B_Paste」ファイルは無い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/e2e37372-12ef-76b5-91a2-9b8b17587f03.png)

<h2>BOM作成</h2>
基板に実装するパーツのBOMを作成する。
今回は、PCBgogoの「BOMの例」にあるフォーマットを使用した。
ちなみにPCBgogoの調達部品は、Digikeyを使用しているみたいなので、
部品はDigikeyで構成した。

<h2>部品の座標データ作成</h2>
基板に実装するバーツの位置を示した、座標データを作成します。


1、フットプリントと位置情報のファイルを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/88f07d52-5651-86b7-9897-a3da9dc08670.png)

2、フォーマット「CSV」単位「mm」ファイル「前面と裏面で別ファイル」を選択し、
　　座標ファイルを生成ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/017e0ca9-f3f9-8550-4fc1-837e4f1ca944.png)


<h2>PCBに注文</h2>
サイトから必要な情報を入力し、カートに追加すると、
「ガーバーデータを入稿」「BOMを入稿」「座標データを入稿」をする画面に移行する。

「ガーバーデータを入稿」では、先程のzipファイルをアップロードする
「BOMを入稿」では、PCBgogo指定のEXCELファイルを使用。
「座標データを投稿」では、先程作成した座標データを使用。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/1cc7a5f3-6d2f-267f-c214-cc892c9cd2d7.png)

全て入稿が完了したら確認を押して下さい。
その後PCBgogoがデータをチェックして問題なければ支払いを完了させて下さい。
Qiitaのはじめかた（アカウント作成から記事投稿まで）

# Qiitaのはじめかた

はじめまして、るん です。
この度初めてQiitaに登録を行い、記事を投稿するので、自分の覚書用にまとめました。
どなたかの参考になれば幸いです。

# 目次
[アカウント作成](#アカウント作成)
[記事の投稿](#記事の投稿)
[難しかったこと](#難しかったこと)


## アカウント作成
1. Qiitaのホームページにアクセスする。→[Qiitaのホームページ](http://qiita.com "Qiita Home")
2. 画面右上の「ユーザー登録」をクリックする。
![Inkedimage17_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/2a43dbe6-2d4d-a8b6-f6dd-f10eee80e667.jpeg)

3. 登録する方法を選ぶ。
ちなみに私はGoogleアカウントで登録しました。
<img width="500" alt="image4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/3b86c2f0-ac85-ec90-60fc-05ff9d483c5f.png">

4. メールアドレスなどの登録を終えたら、興味のあるタグやユーザーのフォローを行って完了。
ちなみにフォローしたタグはこのようにプロフィールに表示されるようです。
<img width="300" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/e76b35ed-90d7-a41e-d4d7-29032a4e9de6.png">


## 記事の投稿
さっそく記事の投稿をしようと思います。

1. Qiitaのヘッダー右上にある「投稿する」ボタンをクリックし、「記事」を選択する。

    <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/0a538e04-88ee-881d-fe66-f94345550a35.png">

::: note info
メールアドレス認証が済んでいない場合は 設定画面に遷移するので、
案内に従ってメールアドレスの認証をしましょう
:::



2.画面が切り替わったら記事を作成する。
  左側に本文を記載すると、右側にプレビューが表示される。
<img width="700" alt="image22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/8cb2a48d-af34-4690-c797-f0875f5d6e71.png">

3.記事を書き終えたら右下の「Qiitaに投稿」をクリックする。
![image23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/c3bf2b84-6796-e561-05da-351b6cd363fe.png)

## 難しかったこと
上記手順を踏んでみて、アカウント作成はさくっと終わりましたが、
記事の作成が思ったより難しく感じました。
特にMarkdownに慣れておらず、想定の3倍くらい時間がかかりました。

基本的な書き方は[「Markdown記法 チートシート」](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)という公式の記事にまとまっています。
(投稿画面にある「？」をクリックしても見ることができます)

また、Qiitaでは他の人が書いた記事のMarkdownを見ることができるので、
そちらを参考にするのもいいかもしれませんね。
<img width="300" alt="image25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580785/f6889884-2a99-1871-3b64-225216e3d827.png">


初めての投稿でわかりにくいところもあったかと思いますが、
どなたかの参考になれば幸いです。
利用頻度が多いコマンドのべスト10を表示

## 環境
Ubuntu20.4

## コマンド
```
history | cut -d ' ' -f 4 | sort | uniq -c | sort -nr | head -n 10
```

## 解説
**cut**はCSVの行を抜き出すコマンド。**history**で表示される情報は、半角スペースで区切られているため、**オプションd**で半角スペースを指定する。コマンドが表示される行は4カラム目に相当するので、**オプションf 4**を指定する。

そして、その結果を文字列のまま**sort**する。**uniq**は重複行を削除するコマンド。**オプションc**を指定することで、行の頻出回数を表示する。

次に、頻出回数順で更に**sort**する。**オプションn**は数値でソートするという意味。**オプションr**は降順でソートするという意味。そして最後に、**head**で出力する行数を指定する。**オプションn 10**を指定することで、ベスト１０に絞り込むことができる。
【Docker】Dockerとは

改めて**Docker**とは何か簡単にメモしておく。

# Dockerとは
**Docker**とは、軽量なコンテナ型の仮想環境を管理してくれるオープンソースソフトウェア。
この仮想環境は仮想マシンのようにOS上に別のOSを作成し、その上で仮想環境を作成してアプリを動かすのではなく、**Docker**はゲストOSを作成することなくアプリを動かすことができる。ここで、**Docker**で出てくる用語を少しまとめておく。

**【Dockerイメージ】**
**コンテナ**を作成するためのテンプレート。
これには、アプリケーションの実行に必要なミドルウェアなどの設定やコマンドがひとまとめになっている。

**【コンテナ】**
**Dockerイメージ**をもとに作られたWebサーバやデータベースサーバなどが動作する仮想環境のこと。

**【Dockerサーバー】**
**コンテナ**と**Dockerイメージ**を管理するサーバのこと。

# Dockerのメリット
**Docker**のメリットは他にもあるが、2点挙げておく。
## 誰でも同じ環境が作成できる
**Docker**ではミドルウェアのインストールや各種環境設定をコード化できる。そのため、**Docker**エンジンをインストールしてあれば、アプリの**Dockerイメージ**から**コンテナ**を作成するだけで環境構築が行えるため、同じ条件でローカル環境を構築することができる。これにより、開発環境では動作し、本番環境で動作しないような状況を減らすことができる。また、インフラ環境をコード化しているため、配布や共有がしやすい。

## 軽量でシンプル
**Dockerコンテナ**は軽量なため、処理の遅延を気にせずに作業を行える。
また、**コンテナ**はメモリやディスクの消費量を減らして仮想化することができる。
[Android]AVDManager操作時に"The selected AVD is currently running in the Emulator."と言われた時の対処法


# 概要
Android開発をしていて、エミュレータのデータやエミュレータ自体を消去したいときなどにAVDマネージャーを操作しようとすると以下のようなエラーが出ることがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/03394cc4-baff-1766-5c27-56204a69af34.png)

PCを再起動したりするとうまくいくが、再起動せずとも解決できる方法があるので紹介する。

# 方法
## **.lockと名のつくファイルを全て消す**
コマンド
```
rm ~/.android/avd/your_emulator/*.lock
```

`your_emulator`に入れるemulatorの名前はlsで確認できる
```
ls ~/.android/avd/
```
例
上記の実行結果が以下だった場合
```
Pixel_5_API_32.avd	Pixel_5_API_32.ini
```

削除コマンド
```
rm ~/.android/avd/Pixel_5_API_32.avd/*.lock
```

実行後、もう一度wipe dataを試みると、以下のように消せるようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/9bf8a2a4-7e42-584b-6eb6-da3193489080.png)

# 参考
- [Can't Delete AVD from AVD Manager in Android Studio](https://stackoverflow.com/questions/27005819/cant-delete-avd-from-avd-manager-in-android-studio)
- [AVD Managerからエミュレーターが立ち上がらなかったときの対処方法。”.lock”フォルダを削除](https://e-yota.com/webservice/post-2476/)
rails db:migrateを実行した時に出たエラーを解決した話

# はじめに
１月〜プログラミングスクールで学習しています。
これから平日は~3/25まで毎日何かしらアウトプットのため投稿を続ける予定です。
今回は rails db:migrateコマンドを実行した際に出たエラーについて書きます。
※Ruby2.6.5の環境を使用し学習しています。

# 問題
rails db:migrateコマンドを実行すると下記エラーが出ました。
ただ、思い当たる節が合ったためすぐに解決することができました。
```:ターミナル
% rails db:migrate
== 20220310072650 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0159s
-- add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
```

# 解決
database.ymlのエンコードがutf8になっていないことに気付き修正しました。
```:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8 #utf8mb4から修正
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock
```
その後、rails db:resetコマンド実行し、無事マイグレートが完了しました。
```:ターミナル
% rails db:migrate:reset
Dropped database 'pfc_control_development'
Dropped database 'pfc_control_test'
Created database 'pfc_control_development'
Created database 'pfc_control_test'
== 20220310072650 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0134s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0136s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0171s
== 20220310072650 DeviseCreateUsers: migrated (0.0443s) =======================
```
encodingに関しては忘れそうなのでメモ程度ですが残しておきます。
それでは〜:beginner:
JS7® JOCコックピット LDAP(AD)連携 記事公開

JS7® V.2.2.2よりLDAPのサポートが追加されました。
弊社山下が連携方法記事を公開しましたのでお試しください。

https://qiita.com/Yoshitami/items/d891936095b1877dd93d
コードレビューではなくモブプログラミングをください

## 初めに

この記事はSvaťa Šimara氏の「[Don’t do Code Review, try Mob instead](https://medium.com/verotel/dont-do-code-review-try-mob-instead-82149ef035df)」の翻訳です。筆者はかなり濃密なモブプログラミングをされており、事例として大変興味深いです。

モブプログラミングは開発手法の一つです。用量用法を守って正しくお使いください。

## コードレビューの欠点

- 長いフィードバックループ
- 待ち時間
- 様々な未完了タスク
- 文字によるコミュニケーションは時間がかかる、マジで

> 私のプログラミングの一日はたいていこうだ。「コード書く -> レビューに送る」 今は？ ああ…またタスクだ。まあこれは簡単だから次のやつ行こう。そんな時に限って急なレビューが入って、しばらく待って、自分でレビューして…ようやっと2番目のタスクのレビューだよ！　いや、それには反対だよ、ちゃんと返答しなきゃ…小一時間かけて論点をまとめたけど、次の日に同僚からもらった返事はOKの一言だった。え、そんだけ？！

コードレビューの最も顕著な問題は、それが難しい質問・回答の非同期のキャッチボールというところだ。非効率的なうえに、関わっている人がイライラしてくる。

別のやり方として、コードレビューをなる早で行うことが挙げられる。自分がこのアプローチをとるとき、1週間まるまるコードレビューに費やすことになる。これは大げさな話ではない。コードレビューを増やすほど、受ける質問の量も増える。これもまたイライラする。

## コードレビューの狙い

コードレビューの長所って何だろう？

- 知識の共有
- 責任の共有
- コードストラクチャの改善
- 学習

良いコードレビューはこう言った部分をカバーしている。でもコードレビューは手段なのだから、より良い方法があれば、コードレビューをする必要は無い。

## モブプログラミング

[モブプログラミング](https://en.wikipedia.org/wiki/Mob_programming)とはチームが一丸となって同じ時間に同じスクリーンに集まるということだ。もしくは、自分の場合だが、リモートで画面をシェアすることもある。
自分の場合4人組で働いていて、1日5~6時間ほどモブをやる。まずタスクを決めて、着手可能になった段階でセッションを回していく。

セッションでは一人のドライバーがタイプやクリックをし、もう一人ナビゲーターがドライバーに何をするか指示を出す。残り二人はそれを注意深く聞き、ナビゲーターが間違った方向に進んでしまった時だけ介入する。ナビゲーターは3分間で…たった3分だけで、ローテーションを回す。

ローテーションしたら今度はドライバーがナビゲーターになる。次の手順が分かるからだ。先ほどのナビゲーターは休み、その他(mob)のどちらかがドライバーになる。そしてまた3分後に役割交代をしていって…

この通り、ローテーションは激務だ。常に注意力が要求され、うっかりすると自分がナビゲートする番に、何をすればいいか分からなくなってしまう。

仕事の質を保つため我々はよくコーヒー／トイレ休憩を入れるし、もちろん昼食はゆっくり休む。

## コードレビューの目的は達成される

**知識の共有**は即達成できる。メンバー全員で精神的なプロセスを取り、何故、何が行われたのか分かる。
**責任の共有**は、個人的な意見ではあるが満たされる。自分は、我々がなしたこと全てに責任を持ち、いつだって「反対」とか「もっと良いやり方がある」と言える。
**コードの構造**は全員納得できるので、チーム全員ができる最良のコードが一貫性を持ってできる。
**学習**も…これまたあっさりと(instant)、しかし濃密に(intense)できる。ナビゲーターが良ければ、何をすればいいか言うだけでなく、どうすれば効率よく出来るかも伝わる。自分の場合、毎日ベターなソフトウェアアーキテクチャーや、テスト方法、IDEの効率的な使い方などが学べる…これもナビゲーターが自分の知らないことを知っている(なおかつ教えてくれる)からだ。
全体的に、モブプログラミングはコードレビューの上位互換だ。しかもキャッチボールのイライラが無いと来ている。

## モブプロって効率悪い…

そんなふうに考えていた時期が俺にもありました…始めてから数週間の間は。

それはチームを立ち上げるときやメンバーの言語やツールに関する経験が浅いときに当てはまる。この時期はモブプロはほぼ学習になる。

でも最初の数週間を耐えればすべてが変わってくる。

ほぼ毎日、自分ひとりだったら解決に1時間(下手したら数時間)かかる問題に出くわす。しかし我々は4人いるので、たいていの場合簡単なやり方を知っている人がいるものだ。同僚も同じ経験をしたと言っていた。自分では何をすれば分からなかったが、すぐに分かる人が誰かしらいるのだ。

メンバーはそれぞれ違う分野の専門家でもある。DBに強い人がいれば、使っているフレームワークを熟知している人や、例えば決断力に優れている人がいる。ナビゲーターが詰まった時は、この「専門家」が障害物を取り除いてくれる。それもすぐにだ。

## モブるのに必要なこと

モブプログラミングは万人向けではない。

まず、(リモートでも何でもいいから)時間を共有できなければ機能しない。

**モブるにはにはコミュニケーションスキルが必須だ。受動的攻撃心、ないし横柄さはお呼びでない。同僚よりもあなたが優れていることを誇示したいのであれば、モブには不適格だ。**[^1]

[^1]: 原文のトップハイライト。

モブるには忍耐と経緯が必要だ。なぜなら誰もがいつでもコンディション万全という訳ではないからだ。問題解決を急いでいて、なおかつ同僚を先導/指導する気が無いのであれば、モブプロは成り立たない。同僚が向上せず、チームが育たないからだ。

**必要なことは以上だ。**(リモートであっても)同じ時を過ごし、我慢強く、新しい方法に興味を持って、同僚も似たような視野に立っていれば、**モブプロはいいぞ！**

## モブプロ対コードレビュー

モブプロとコードレビューは月とスッポンだ。

コードレビュー形式では、問題解決に数時間は取られたのち、解決策をコードレビューに送り、さらに待って、レビュアーの変更点の指示が来て、自分のコード変更点について申し開きをすることが多い。2～5日後に自分のコードをマージする準備が整ったと思ったら、競合を解決しなきゃならないと来た！

モブプログラミングにそんなのはない。

- 試行錯誤はメンバーの経験で抑えられる
- 待ち時間無し
- 即座の議論・コード変更
- マージ競合削減

モブプロにはさらに利点がある。自分にとって特に大事なのは同僚との仲が良くなることだ。プログラマーも社会的動物だし、その点モブプロは本当に助けになる。

まとめるとモブプログラミングはフィードバックループを大幅短縮できて、素晴らしい成果が挙げられる。
【mysql】初心者向けいろいろ

ほぼ自分用備忘録です。
詳しい説明は参考URLを見てね。

# 取り出したい系（抽出）
### ・ユニークな値を取り出したい。 DISTINCT
参考：https://www.dbonline.jp/mysql/select/index13.html
```sql:DISTINCT
SELECT DISTINCT col_name from table_name;
```
### ・条件に一致した行だけ欲しい。WHERE
参考：https://www.sejuku.net/blog/51583
```sql:WHERE
SELECT * FROM table1 WHERE col_name = 'hoge';
```
### ・どれかに一致した行だけ欲しい。WHERE IN()
参考：https://www.dbonline.jp/mysql/select/index6.html
```sql:WHERE IN ()
SELECT * FROM table_name
WHERE name in ('スライム', 'ドラキー', 'ももんじゃ');
```
### ・ANDとOR両方使いたいよ。(col1 = 'a' OR col1 = 'b') AND col2 = 0
参考：https://kino-code.com/sql13/
```sql:AND OR
SELECT * FROM table_name
WHERE (name = 'スライム' OR name = 'ドラキー') AND address = 'トラペッタ';
```
### ・あいまい検索したいよ。LIKE
参考：https://qiita.com/chihiro/items/46da8571d4cf37d3123c
```sql:LIKE
SELECT * FROM  WHERE name LIKE 'スラ%';
SELECT * FROM  WHERE name LIKE '%イム';
```

### ・IDをKeyにした配列がほしいよ。
参考：https://qiita.com/mpyw/items/d52351bd1a8068344cc2


# 入れたい系（挿入）
### ・データを挿入したいよ。INSERT INTO
参考：https://www.dbonline.jp/mysql/insert/index1.html
```sql:INSERT INTO
INSERT INTO table_name (col1, col2) VALUES ('a', 'b');
```
### ・複数レコード挿入。(col1,col2) VALUES (1,'a'),(2,'b')...
参考：https://johobase.com/multiple-insert-sql/
```sql:VALUES
INSERT INTO table_name
(number, name, datetime)
VALUES
(1, 'a', '2022-01-01'),
(2, 'b', '2022-01-02'),
(3, 'c', '2022-01-03');
```


# 変更したい系（更新）
### ・テーブルのすべてのレコードの任意列に値を設定したい。UPDATE
```sql:UPSATE
UPDATE table_name SET col_name = 0;
```
### ・条件に合ったレコードを変更したい。UPDATE＋WHERE
参考：https://style.potepan.com/articles/23919.html
```sql:UPDATE+WHERE
UPDATE table_name
SET
col1 = 0, col2 = 0	
WHERE
col1 = 1 AND col2 = 2;
```
### ・複数列を変更（更新）したい。CASE ~ END, CASE ~ END...
参考：https://blog.trippyboy.com/2014/mysql/mysql%ef%bc%91%e3%82%af%e3%82%a8%e3%83%aa%e3%83%bc%e3%81%a7%e8%a4%87%e6%95%b0%e3%83%ac%e3%82%b3%e3%83%bc%e3%83%89%e3%81%aeupdate%e3%80%81%e3%81%95%e3%82%89%e3%81%ab%e3%81%afupdate%e3%81%a8insert/2/
```sql:CASE
UPDATE table_name SET 
monster = CASE
WHEN number = 1 THEN 'スライム'
WHEN number = 2 THEN 'ドラキー'
WHEN number = 3 THEN 'ももんじゃ'
END,
hp = CASE
WHEN number = 1 THEN 8
WHEN number = 2 THEN 10
WHEN number = 3 THEN 12
END;
```
### ・連番を振りなおしたいよ。SET @ ~~
参考：https://qiita.com/MochiMochiChip/items/f05bc3fc9612b94f8004
```sql:SET @
SET @cnt_i:=0;
UPDATE table_name SET number = (@cnt_i := @cnt_i + 1 );
```


# テーブルを操作したい系（操作）
### ・テーブルのレコードを全削除したい。 TRUNCATE
参考：https://johobase.com/truncate-table-sql/#TRUNCATE_TABLE
```sql:TRUNCATE
TRUNCATE TABLE table_name;
```
### ・テーブルをコピーしたいけどデータはいらない。CREATE TABLE ~ LIKE
参考：https://www.dbonline.jp/mysql/table/index15.html
```sql:CREATE TABLE ~ LIKE
CREATE TABLE new_table LIKE table_name;
```
Flutterの環境構築（MacOS編）

macOSでのインストール

①公式ページからZipファイルをダウンロード
https://docs.flutter.dev/get-started/install/macos

②アンジップする
```
cd ~/development
unzip ~/Downloads/flutter_macos_2.10.3-stable.zip
```

③パスを通す
```
 export PATH="$PATH:`pwd`/flutter/bin"
```

④ドクターコマンドを実行（必要環境の診断をしてくれるよ）
```
 flutter doctor
```

⑤出力みながらAndroidStudioとXcodeの環境を整える

Androidのコマンドラインツールがないよと出たら
下記をみながらAndroidStudioのSDKManagerからインストール
https://developer.android.com/studio/command-line?hl=ja

最終的に下記のような出力になればOK！
```
flutter doctor     
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.3, on macOS 11.6.1 20G224 darwin-x64, locale
    ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] VS Code (version 1.65.0)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

• No issues found!
```
二つのテーブルから検索する機能を実装しました。

# 今回はarticlsテーブルとresolutionsテーブルから検索するコードを掲載します。
1.アソシエーションの状況
[![Image from Gyazo](https://i.gyazo.com/0e3e19e1a852b80c094822158698bfc8.png)](https://gyazo.com/0e3e19e1a852b80c094822158698bfc8)
２.ルーティングの設定
```routes.rb
Rails.application.routes.draw do
  devise_for :users 
  root to: 'users#index'
  resources :resolutions 
    
  resources :articles
  resources :users do
    collection do
      get 'search'
    end
  end
end
```
3.コントローラーの記述
```users_controller.rb
lass UsersController < ApplicationController

  def index
    @resolutions = Resolution.includes(:user).order('created_at DESC')
    @articles = Article.includes(:user).order('created_at DESC')
  end

  def show
    @user = User.find(params[:id])
    @resolutions = @user.resolutions.order('created_at DESC')
    @articles = @user.articles.order('created_at DESC')
  end

  def search
    @resolutions = Resolution.search(params[:keyword])
    @articles = Article.search(params[:keyword])
  end

end
```
4.モデルの記述
```article.rb
class Article < ApplicationRecord
  validates :title,   presence: true
  validates :content, presence: true
  belongs_to :user

  def self.search(search)
    if search != ''
      Article.where('title LIKE(?)', "%#{search}%")
    else
      Article.all
    end
  end
end
```
```resolution.rb
class Resolution < ApplicationRecord
  validates :erroe_message, presence: true
  validates :language, presence: true
  validates :status, presence: true
  validates :code, presence: true
  validates :cauce, presence: true
  belongs_to :user

  def self.search(search)
    if search != ''
      Resolution.where('erroe_message LIKE(?) OR status LIKE(?)', "%#{search}%", "%#{search}%")
    else
      Resolution.all
    end
  end
end
```
5.htmlの記述
- トップ画面（検索画面がある画面）

```users/index.html.erb
<%= form_with(url: search_users_path, local: true, method: :get, class: "search-form") do |form| %>
   <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
   <%= form.submit "検索", class: "search-btn" %>
<% end %>
```
- 検索結果画面
```users/serch.html.erb
<div class="contents row">
<div class="title-name">検索結果</div>
  <% @resolutions.each do |resolution| %>
    <%= render partial: "resolutions/resolution", locals: { resolution: resolution } %>
  <% end %>
   <% @articles.each do |article| %>
    <%= render partial: "articles/article", locals: { article: article } %>
  <% end %>
</div>
```
## 結論
今回はこのコードの記述でなんとか実装することができました。
どちらとも紐づいているuserを活用することでうまく実装できました。
ドットインストールでCSS セレクター編をやってみた

# ドットインストールのCSS セレクター編です
要点をまとめて見たので後で振り返り用としておきます

### 基本セレクターの種類
- 要素型セレクター　h1
- classセレクター　.info
- idセレクター　#ok
- 属性セレクター　href
- 全称セレクター　* (全ての要素)
:::note
- class 属性の値は複数付ける事が出来る
:::

#### 属性セレクター
- 存在の有無 [ ]
- 完全一致 [xxx="zzz"]
- 前方一致 [xxx^="zzz"]
- 後方一致 #

### 基本セレクターの種類
- 要素型セレクター　h1
- classセレクター　.info
- idセレクター　#ok
- 属性セレクター　href
- 全称セレクター　* (全ての要素)

- class 属性の値は複数付ける事が出来る

#### 属性セレクター

- 存在の有無 [ ]
- 完全一致 [xxx="zzz"]
- 前方一致 [xxx^="zzz"]
- 後方一致 [xxx$="zzz"]
- 部分一致 [xxx*="zzz"]

#### セレクターの組み合わせ
- a, b    = aとb
- a.b     = aであってかつbである
- a > b   = aの直下の階層にあるb
- a b     = aの下の階層にあるb全て
- a + b   = aの直後にあるb
`<h1>Title</h1>`
`<p>Hello. Hello.</p><!-- h1要素の直後にあるp要素 -->`
`<p>Hello. Hello.</p><!-- p要素の直後にあるp要素 -->`
`<p>Hello. Hello.</p><!-- p要素の直後にあるp要素 -->`

#### 詳細度の仕組み
スコアによって優先度が決まる(1>3)
1. id
2. class, 属性, 擬似クラス
3. 要素, 疑似要素
:::note
スコア/優先度が同じだった場合、後から書いた方が適応される
:::
:::note alert
詳細度よりも優先される書き方がある
1. style属性に直接書いてしまう方法
2. CSSに!importantと書いた場合(最優先される)
※2を使用すると優先度が分かりづらくなるのでなるべく使用しないほうが良い
:::
【PHP】ファイル操作系いろいろ

# basename() ファイルパスからファイル名を取得する。
参考：http://www.openreference.org/articles/view/496
```php:basename
basename( "/tmp/file/hoge.txt" );          // => "hoge.txt"
basename( "/tmp/file/hoge.txt", ".txt" );  // => "hoge"
basename( "/tmp/file/ );                   // => "file"
```
# rename() ファイルを移動する。
参考：https://www.flatflag.nir87.com/copy-895
```
dir
 ├─ tmp
 │   └─ hoge.txt =>これをfileに移動したい。
 └─ file
```

```php:rename
rename('tmp/hoge.txt', 'file/hoge.txt');
```

# unlink() ファイルを削除する。
参考：https://www.sejuku.net/blog/25804
```php:unlink
unlink('tmp/hoge.txt'); // => 削除成功でTRUE、失敗でFALSEを返す。
```

メモ代わりに使用しているので増えるかもです。
テストの7原則について

# テスト7原則について

## はじめに
テストについて勉強しています。テストを行う上で原則があったことが発見だったのでまとめたいと思います。

## 原則1：テストは欠陥があることは示せるが、欠陥が無いことは示せない
テストにより、ソフトウェアに残る未検出欠陥の数を減らせるが、欠陥が見つからないとしても、正しさの証明にはならない。

## 原則2：全数テストは不可能である
全てをテストすること（入力と事前条件の全組み合わせ）は、ごく単純なソフトウェア以外では非現実的である。全数テストの代わりに、リスク分析、テスト技法、および優先度によりテストに欠ける労力を集中すべきである。

## 原則3：早期テストで時間とコスト節約
早い段階で結果を見つけるために、静的テスト活動と動的テスト活動の両方をソフトウェアテスト開発ライフサイクルのなるべく早い時期に開始すべきである。早期テストは、シフトレフトとも呼ばれる。ソフトウェア開発ライフサイクルの早い時期にテストを行うことより、コストを低減または削減することができる。

## 原則4:欠陥の偏在
リリース前のテストで見つかる欠陥や運用時の故障の大部分は、特定の少数モジュールに集中する。テストの労力を集中させるために、欠陥の偏在を予測し、テストや運用での実際の観察結果に基づいてリスク分析を行う。

## 原則5: 殺虫剤のパラドックスにご用心
同じテストを何度も繰り返すと、最終的にはそのテストでは新しい欠陥を見つけられなくなる。
この「殺虫剤のパラドックス」を回避するため、テストデータを定期的に見直して、改定したり新規にテストを作成する必要がある（殺虫剤を繰り返し使用すると効果が低減する）。ただし、自動化されたりリグレッションテストの場合は、同じテストを繰り返すことでリグレッションが低減しているという有益な結果を示すことができる。

## 原則6:テストは状況次第
状況が異なれば、テストの方法も変わる。例えば、安全性が重要な産業制御ソフトウェアのテストは、eコマースモバイルアプリケーションのテストとは異なる。また、アジャイルプロジェクトとシーケンシャルライフサイクルプロジェクトでは、テストの実行方法が異なる。

## 原則7: 「バグゼロ」の落とし穴
テスト担当者は可能なテスト全てを実行でき、可能性のある欠陥全てを検出できると期待する組織があるが、原則2と原則1により、これは不可能となる。また、大量の欠陥を検出して修正するだけでシステム、ユーザーのニーズや期待を満たさないシステム、またはその他の競合システムに比べて劣るシステムが構築されることがある。

## まとめ
テスト7原則
・原則1:テストは欠陥があることは示せるが、欠陥が無いことは示せない。
・原則2:全数テストは不可能
・原則3:早期テストは不可能
・原則4:　欠陥の偏在
・原則5: 殺虫剤のパラドックスにご用心
・原則6:テストは状況次第
・原則7: 「バグゼロ」の落とし穴
テストの原則について

# はじめに

業務でテストについて学ぶ機会があったので、アウトプットしていきたいと思います。QAエンジニアとはなんなのか。その原則はどのようなものがあるのかを書いていきます。

## QAエンジニアとは
QA（Quality Assurance）には「品質保証」という意味があります。
つまりQAエンジニアとは、システム・アプリケーション・サービスなどの製品の品質保証のために、テスト工程での動作チェックや、製品の品質管理を担当するエンジニアのことを指します。

QAエンジニアの仕事は、ただ単に不具合の有無や、使用に沿った動作をするかを確認するだけではありません。動作や仕様の確認に加え、「ユーザーが使いやすい製品になっているか」「イレギュラーな操作をした場合でも動作に問題がないか」という視点でのチェックも行ないます。


## QAエンジニアとテストエンジニアの違い
QAエンジニアとはよく似た職種がテストエンジニアになります。
テストエンジニアは、開発途中の製品に対して、プログラムが正常に動作するか、不具合がないかのテストを実施します。
QAエンジニアは、完成した製品が使用に沿っているか、ユーザが使用できる状態になっているかの確認を主に担当します。製品状態をチェックするだけでなく、テスト結果の分析や開発者へのフィードバックも行います。
QAエンジニアとテストエンジニアは異なる職種ですが、業務内容が似ているため、それぞれを区別していない企業も存在します。

## 品質保証テストの設計、計画
製品の品質を保証するために、どのようなテストが必要かを決め、テストの実施計画を立てます。品質水準は数値で明確に定義しておく必要があります。
QAエンジニアのテスト工程は、製品リリースが間近に迫っていることが多いため、スケジュール管理も非常に重要な業務です。関係部署とのスケジュール調整をし、スムーズにテストを終了できるように工程管理をする必要があります。
テストの設計・計画が適切に組まれていない場合は、本来実施すべきテストが漏れていたり、あとになって再テストが必要になったりする可能性もあります。

## まとめ
勉強すればするほどテストの奥深さや大切さがわかりました。
Vuexとbootstrap-vueを組み合わせた実装

# Vuexとbootstrap-vueを組み合わせた実装

忘れ内容にメモ

## store作成
まず、Vuexでstoreを作成

```javascript:store/sample.ts
export const state = () => ({
  id: '',
  name: ''
})

export State = {
  id: string
  name: string
}

export const mutations = {
  changeId(state: State, value: string) {
    state.id = value
  },
  changeName(state: State, value: string) {
    state.name = value
  },
}
```

## computedでgetterとsetter

```javascript: index.vue
  computed: {
    id: {
      get () {
        return this.$store.state.sample.id
      },
      set (val) {
        this.id(val)
      }
    },
    name: {
      get () {
        return this.$store.state.sample.name
      },
      set (val) {
        this.name(val)
      }
    }
```

computedで定義したものを後は `b-form-input` などのmodelに渡すだけ

## vee-validateなどを使用した場合(pug)

```javascript
validation-observer(ref="observer" v-slot="{ handleSubmit, invalid }")
  b-form(@submit.prevent="handleSubmit(onSubmit)")
    validation-provider(
      name="id"
      v-slot="{ errors, valid, validated }"
    )
      b-form-input(
        v-model="id"
        :state="validated ? valid : null"
      )
      b-form-invalid-feedback {{ errors[0] }}
```