OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】電話帳作成問題を解いてみた！

[アウトプットのネタに困ったらこれ！？](https://blog.jnito.com/entry/2019/05/03/121235)
　こちらの記事を参考にして、今回は「電話帳作成問題」を解いてみました。とりあえず「動くだけ」のコードでもいいから、自分で最後まで考えて解きたいという気持ちで望んでいます。初めから効率的なやり方を考えたわけではなく、場当たり的に課題に対処したため、コードとしては不適切な部分があります。ご意見いただけるとありがたいです。


```
#INPUT
['キシモト', 'イトウ', 'ババ', 'カネダ', 'ワダ', 'ハマダ']

#OUTPUT 
[ ['ア', ['イトウ']], ['カ', ['カネダ', 'キシモト']], ['ハ', ['ハマダ', 'ババ']], ['ワ', ['ワダ']] ]

```

　このように、カタカナ文字列の配列を渡すと、ア段の音別にグループ分けした配列を返すプログラムを作成する問題になります。

　コメントを参考にして1部修正して、最終的にこのようなコードになりました。


```ruby
def phone_book(names)
  a = ("ア".."オ").to_a
  ka = ("カ".."ゴ").to_a
  sa = ("サ".."ゾ").to_a
  ta = ("タ".."ド").to_a
  na = ("ナ".."ノ").to_a
  ha = ("ハ".."ポ").to_a
  ma = ("マ".."モ").to_a
  ya = ("ヤ".."ヨ").to_a
  ra = ("ラ".."ロ").to_a
  wa = ("ワ".."ン").to_a

  kana = [a, ka, sa, ta, na, ha, ma, ya, ra, wa]
  kana_row = 'アカサタナハマヤラワ'.chars.map{|c| [c,[]]}

  num = 0
  number_of_names = names.length - 1
  names_array = []
  
  while num <= number_of_names
    first_character = names.slice(num).slice(0)
    kana.map{|row|
      if row.include?(first_character)
        count = 0
        while count <= 9
          if row == kana[count]
            kana_row[count][1].insert(0,names[num])
          end
          count += 1
        end
      end
    }
    num += 1
  end

  kana_row.map{ |row_content|
    if row_content[1][0] != nil
      row_content[1].sort!
      names_array << row_content
    end
  }
  
  p names_array
  
end

names = ['キシモト', 'イトウ', 'ババ', 'カネダ', 'ワダ', 'ハマダ']
phone_book(names)
#実行結果 [["ア", ["イトウ"]], ["カ", ["カネダ", "キシモト"]], ["ハ", ["ハマダ", "ババ"]], ["ワ", ["ワダ"]]]

names = ['フクダ', 'キムラ', 'タナカ', 'ハシモト', 'オカモト', 'ゴトウ']
phone_book(names)
# 実行結果 [["ア", ["オカモト"]], ["カ", ["キムラ", "ゴトウ"]], ["タ", ["タナカ"]], ["ハ", ["ハシモト", "フクダ"]]]

names = ['ワタナベ', 'ヨシダ', 'マツモト', 'ナガタ', 'ドウモト','タチバナ', 'チバ']
phone_book(names)
# 実行結果 [["タ", ["タチバナ", "チバ", "ドウモト"]], ["ナ", ["ナガタ"]], ["マ", ["マツモト"]], ["ヤ", ["ヨシダ"]], ["ワ", ["ワタナベ"]]]

```


<br>



　とりあえず「動くだけ」のコードを書くことができましたが、まだまだ適切なコードであるとは言えません。恥ずかしいコードを晒すことになりましたが、親切にコメントして下さると嬉しいです。

<br>
【Ruby】puts print pメソッドの違い

## はじめに
Rubyの知識を深く学びたい！と思い、『プロを目指す人のためのRuby入門』を使い学習を始めました。新たな学びや気づきをアウトプットします。

今日のテーマは、ターミナルへの出力でよく使われる「puts・printメソッド・pメソッドの違いってなんだろう？」についてです。


## 3つのメソッドを使って出力し違いを比べてみよう

* `puts`を使った出力

```ruby
irb(main):001:0> puts 123
123
=> nil

irb(main):002:0> puts  'abc'
abc
=> nil
```
<br>

* `print`を使った出力

```ruby
irb(main):003:0> print 123
123=> nil

irb(main):004:0> print 'abc'
abc=> nil
```
`puts`と違う点は改行されていない点にあります。

<br>

* `p`を使った出力


```ruby
irb(main):001:0> p 123
123
=> 123

irb(main):002:0> p 'abc'
"abc"
=> "abc"
```

`p`は`puts`のように改行を加えて出力します。
ただし、文字列を出力するとその文字列が `""`で囲まれている点が`puts`と異なります。
また、`p`は引数で渡されたオブジェクトそのものがメソッドの戻り値になります。
<br>
次は、改行文字を含む文字列をそれぞれのメソッドに渡してみます。

```ruby
irb(main):001:0> s = "abc\ndef"
=> "abc\ndef"

irb(main):002:0> puts s
abc
def
=> nil

irb(main):003:0> print s
abc
def=> nil

p s
irb(main):004:0> p s
"abc\ndef"
=> "abc\ndef"

```

`puts`や`print`では文字列が"abc"と"def"の間で改行して出力されます。
一方で`p`では改行文字`\n`が改行文字のまま出力されます。
<br>
## なにが違うのか？
* `puts`と`print`は内部的に、引数で渡されたオブジェクトに対して`to_s`メソッドを呼び出して文字列に変換しています。
<br>
* `p`は`to_s`メソッドではなく、`inspect`メソッドを呼び出しています。
<br>

## 結局どう使い分けるのがいいの？
* `puts`と`print`一般ユーザ向けです。<br>
そしてこの2つのメソッドの違いは改行があるかないか。
<br>
* `p`は開発者向けです。<br>
なぜなら`inspect`メソッドは開発者にとって役立つ情報を返すように実装されているためです。
<br>

## 参考書籍
[プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで](https://www.amazon.co.jp/dp/B077Q8BXHC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
WindowsにHTCondorをインストールしてジョブを実行する（1台）

#はじめに
[HTCondor](https://research.cs.wisc.edu/htcondor/index.html)という計算負荷の高いジョブに特化した計算負荷管理システムがあります。これをWindowsのPCに入れてなんとか計算を分散させたいのですが、公式ページは英語の手順書しかなく、まずインストールと実行で躓いたため、日本語で手順をメモしたいと思います。
#環境
OS : Windows10
HTCondor : 9.1.0
#手順
##インストール
公式ページの[Windows Administrator用のマニュアル](https://htcondor.readthedocs.io/en/latest/getting-htcondor/install-windows-as-administrator.html)を参考に設定していきます。
### msiファイルのダウンロード
[current channel](https://research.cs.wisc.edu/htcondor/tarball/current/)のリンクから最新版の一個前（または二個前）のバージョンを取得します。
最新版は目下開発中（dailyフォルダ）であり、一つか二つ前のバージョンにしか「release」フォルダがないためです。releaseフォルダを探し、Windows用のmsiファイルをダウンロードします。2021/7次点ではreleaseのある最新バージョンは「9.1.0」です。
### msiファイルの実行
管理者権限で実行します。管理者権限でPowerShellを開き、

```PowerShell
msiexec /i condor-9.1.0-Windows-x64.msi
```
を実行するのが安全です。
ここで色々入力項目が出てきますが、これは[公式ページ](https://htcondor.readthedocs.io/en/latest/getting-htcondor/install-windows-as-administrator.html)に従って入力すればOKです。
インストール時に設定した内容は、グローバルな方の設定ファイル`C:¥condor¥condor_config`に保存されています。

### インストール後
公式ページには再起動不要と書いていますが、念のため一度再起動してください。
（私の場合は再起動しないとちゃんと動きませんでした）
再起動が終わったら、環境変数`CONDOR_CONFIG`＝`C:¥condor¥condor_config`を設定します。
ここまで終わったら、管理者権限で実行したPowerShellで、コマンド`condor_status`でエラー無く実行できることを確認します。

## ユーザ設定
Linuxだと必要ないのですが、Windowsの場合はユーザ設定を行わないと、作業用ディレクトリやほかのユーザのジョブの実行ができません。やっていきます。

### condor_creddを起動
それ用の設定ファイルのテンプレート`C:\condor\etc\condor_config.local.credd`の内容をローカルな方の設定ファイル`C:\condor\condor_config.local`にコピーします。
次に、管理者権限でコマンド`condor_restart`を実行し、Condorを再起動します。
タスクマネージャーを開き、`condor_credd application`が起動していることを確認します。

### ユーザの登録
現在のユーザのままPowerShellを開き、コマンド`condor_store_cred add`でユーザを登録します。パスワードを聞かれるので、自分のパスワードを入力します。
成功すればユーザ登録完了です。

##ジョブの実行
実行したいファイルと、実行したいファイルを記述したsubmitファイルの、少なくとも二つが必要です。
公式ページの[クイックスタートガイド](https://htcondor.readthedocs.io/en/latest/users-manual/quick-start-guide.html)に従って書いていきます。
実行するファイルは`sleep.bat`です。これの中身は公式ページ通りでOKです。
submitファイルは`submit.sub`です。これは公式ページの中身に加えて、少し書き加えます。具体的に言うと、下のように、各ファイルは絶対パスで書いた方が安心です。

```sleep.sub
# sleep.sub -- simple sleep job

executable              = C:\Users\<ユーザ名>\...\sleep.bat
log                     = C:\Users\<ユーザ名>\...\sleep.log
output                  = C:\Users\<ユーザ名>\...\outfile.txt
error                   = C:\Users\<ユーザ名>\...\errors.txt
should_transfer_files   = Yes
when_to_transfer_output = ON_EXIT
queue
```
このファイルをPowerShell上でコマンド`condor_submit .\sleep.sub`で実行します。管理者権限PowerShellを使って絶対パスで指定してもいいし、素のPowerShellでもOKなはずです。
上のユーザの登録をしてないといろいろ面倒なことになるので注意です。

#終わりに
本命は複数台のPCでのジョブ実行なのでまだ先は長いです。
今回設定試してみてうまくいった方法を書きましたが、正しいやり方やもっといい方法などあればコメントいただけるとありがたいです。
また、試した設定の中で関係なさそうなものは書かなかったのですが、実は関係あって上記のやり方だけだとうまくいかないよという場合も教えていただけると助かります。
JEDEC作成環境

久しぶりにispLEVER Classicを起動したところ、ライセンス切れでLatticeのサイトを見たところispLEVER Classicはすべて5万円くらいの有料のサブスクリプションになってしまっていました。おそらく2020年の後半くらいからで、たしかLatticeは買収されていて、方針が変わってしまったようです。

DIAMONDはまだfreeでも使えるが同じように1年ごとのライセンスの発行が必要でいつ有料にされてもおかしくない。

個人開発ではライセンスの更新が必要なツールは使わないほうが良いのかもしれない。

しかたが無いので他の方法を探してみました。

GALBlastの人のページに以下があります。

http://www.armory.com/%7Erstevew/Public/Pgmrs/GAL/jedec.htm

Latticeの1996 ISP Encyclopediaには以下のようなツールが記載されています。

* Synario/ABEL from Data I/JEDECO
* CUPL from Logical Devices
* PLDesigner from Minc
* PLD 386+ from OrCAD

おそらくSynarioがLatticeに買収されてisp LEVERになってCUPLはAtmelに買収されたのではないかと思います。

Win CURLはfreeで使えますが、Atmelのデバイスしかサポートされてません。

GALAsmというオープンソースもありましたが、対応しているGALが4種類しかありません。GALAsmはいろいろ派生がありましたが、チップの設定がハードコードされていて、チップの追加が難しいように見えました。

1990年代のDOS上のPLANIIやOPALjrというツールもありました。これらはナショナルセミコンダクターが作っていたものようです。

PLANIIやOPALjrはEQNという文法を使っていて以下のような原始的な規則になっています。

* ;以降はコメント
* {}でくくられたところもコメント
* chipが出てくるまではヘッダー
* @uesはユーザーエレクトリックシグネチャーでほかにも@で始まるいくつかの記述子がある
* equations以下が定義
* =が無い行はピンリスト
* =があるところは定義 
* オペレーターは以下のとおり

```
OPERATOR    EXAMPLE    OPERATION    PRECEDENCE

/          /signal       invert           4 (highest)
!         ! signal       invert           4
*         A * B          and              3
&         A & B          and              3
|         A | B          or               2
+         A + B          or               2
^         A ^ B          xor              1
$         A $ B          xor              1
:+:       A:+:B          xor              1
=         A = B          assignment       0
:=        A:=B           registered
			 assignment       0 (lowest)
```

とりあえずFreeDOSでPLANIIのEQN2JEDを使ってEXAMPLE5.INCをJEDEC作ってgalprogで焼いてみました。

FreeDOS環境があったので、これで使いましたが、DosBoxなどもエミュレーターで使うのが良さそうです。

Windows7でDosBoxを実行してみました。キーボードがJIS配列をサポートしてないので、辛いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/da72e60d-be64-3ad7-af0a-cc17c6415322.png)

せっかくVerilogをちょっと覚えたのに、また別の文法を覚えなければいけません。:(
$ git remote add origin・・・の意味

（手順通りに何気なく入力していたコマンドの意味を理解したので覚書です）

**いつも当たり前に打っていたコマンド**
1.　$ git remote add origin アドレス
2.　$ git push origin master

**今回はこっちで良かった（理由：１回のみのpushなので）**
１.  $ git push アドレス master


**理解したこと**
$ git remote add origin アドレスの意味

・リモートリポジトリ＜＝＝＞ローカルリポジトリ　のやりとりはアドレスの指定が必要。
・やりとりに都度アドレスを指定するは大変なので「origin」という名前に結びつけて、アドレスを毎回書かなくて良くなる
スイフト勉強_演算子優先順位と結合方向

前回演算子には何があるのか見てみましたが、 
多くの演算子がどのような順序で適用されるのか調べようとする。 
四則演算も前からなされるのではなく、乗算と割り算が先に行われるように、スイフトの演算子にも優先順位がある。 
また、演算子が演算する結合方向も指定されているので、同じ優先順位の演算子があれば、 
どの方向からグループを作るかを示している。

####まずはスイフト標準ライブラリの演算子を参考にしてみよう
https://swift.org

https://developer.apple.com/documentation/swift/swift_standard_library/operator_declarations

演算子の優先順位と結合方向についてはわからなかったが、 
演算子の後ろにコロンを付け、続けて書き下ろした演算子優先順位グループを指定したためである。 
スイフト標準ライブラリには様々な優先順位のグループが存在する。 

higherThan、lowerThan、associativity などで優先順位や結合方向などを指定したことが分かる。 
演算子の優先順位が高いほど同じラインの演算子の中から先に処理することになる。 

* スイフトの演算子優先順位と結合方向規則は、Object-C よりはるかに簡単で予測可能である。 しかし、C系言語とスイフト演算子の優先水位や結合方向が全く同じではない。
モーション/顔認識備忘録

モデルという概念がある

ssdMobilenetv1というのを先に読まないと
faceLandmark68Netというのが使えない

68landmarksっていうのはこのライブラリだけじゃなくて顔座標認識では共通の概念っぽい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268835/64a8d667-9621-3be2-da39-d9c60c8a8b65.png)

```
await faceapi.nets.ssdMobilenetv1.loadFromUri('../../face-api.js/weights')
await faceapi.nets.faceLandmark68Net.loadFromUri('../../face-api.js/weights')

const detectionWithLandmarks = await faceapi.detectSingleFace(input).withFaceLandmarks()
```

landmarks.positionに配列で座標（Pointというオブジェクト)が入っている

faceExpressionNet
表情をとるやつ
surprised,disgusted,fearful,sad,angry,happyの6種類

# メリット
jeelizに比べると軽いと感じた
# デメリット
顔の回転は座表から自分で計算しないといけない
母音の認識も自分で計算するしかない
es6 moduleはtypescriptでしか使えないのかもしれない

参考にした記事
https://note.com/npaka
https://qiita.com/sandabu/items/1ffbf6193cabc9b13a7a

# posenet
asciidoctor-pdfで日本語を含むPDFの出力を行う

# はじめに
[2019_09_Asciidocを使っていてせっかくAsciidoctor-PDF環境を構築したのに出力したPDFの日本語が表示されなくて困っている人へ](https://qiita.com/yuyhiraka/items/569dbcfa329c492654c6)　で困っていた人になって動いている環境をそーっとしておいたのですが、再度調べたら本家が対応してくれていたのがわかったので書いておきます。

## さきに結論（いままで使っていた方向け）
`-r asciidoctor-pdf-cjk` に代わって `-a scripts=cjk` を使います。
`asciidoctor-pdf-cjk` はメンテナンス終了なので利用を止めたほうがよいです。asciidoctor-pdf 1.6.0で使うと以下のようにエラーが出ます。

```
asciidoctor: FAILED: 'asciidoctor-pdf-cjk' could not be loaded
```


# インストール手順

```sh
gem install asciidoctor-pdf
```

以上、終了

# 使い方

```sh
$ asciidoctor-pdf -a scripts=cjk -a pdf-theme=default-with-fallback-font <asciidocファイル>
```

デフォルト設定だとこのオプション指定で日本語埋め込みのPDFが作成されます。ただフォールバックの日本語フォントはあまりいけてません。

# フォントカスタマイズなど
で、フォントを入れ替えたいとかになると思います。
本家にも注釈がありますが、`asciidoctor-pdf-cjk-kai_gen_gothic` は今のruby環境では動いてくれないようです。(動作されている方はコメントをいただければ嬉しいです。)
試したところgemのインストールはできましたが、フォントのインストールでエラーになりました。
[asciidoctor-pdfでかっこいいPDFを作る(1)](https://qiita.com/kuboaki/items/67774c5ebd41467b83e2)などを元にフォントのインストールとテーマを作成するのが良いかと思います。
いままで既にフォントやスタイルの指定をされている場合は、オプションがそのまま使用できます。

## docker-asciidoctor はどうか
[Asciidoctor Docker Container](https://github.com/asciidoctor/docker-asciidoctor) はasciidoctor-pdfもサポートしているので、Dockerインストール済みなら、上のgemをインストールせずにいきなりこんな感じでPDFが作れます。

```
docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor-pdf -a scripts=cjk -a pdf-theme=default-with-fallback-font <asciidocファイル>
```

なので、お好きなフォントとテーマをDockerイメージに入れるか、おけばよさそうです。

# メモ
## 動作確認環境
- macOS(Catalina)
    - ruby 2.6.3p62、asciidoctor-pdf 1.6.0
- Ubuntu(18.04)
    - ruby 2.5.1p57、asciidoctor-pdf 1.5.4, asciidoctor-pdf 1.6.0

## asciidoctor-pdf のドキュメントや関連issue
- [Support for Non-Latin Languages](https://github.com/asciidoctor/asciidoctor-pdf#support-for-non-latin-languages)
- [Create a Custom CJK Theme](https://github.com/asciidoctor/asciidoctor-pdf#create-a-custom-cjk-theme)
- [Japanese doesn't show #1472](https://github.com/asciidoctor/asciidoctor-pdf/issues/1472)

## 参考
- [2019_09_Asciidocを使っていてせっかくAsciidoctor-PDF環境を構築したのに出力したPDFの日本語が表示されなくて困っている人へ](https://qiita.com/yuyhiraka/items/569dbcfa329c492654c6)
- [Asciidoc](https://memo.koya-it.com/tools_environment/asciidoc.html)
Railsで架空のCafeのHPを作ってみよう!【5日目】『完全一致の正規表現』編

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

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

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

#5日目の作業内容:round_pushpin:
・deviseの導入

#5日目の躓いた箇所:zap:
**「従業員しかログインできないようにバリデーションを
かけたいけどどうしたらいいだろう？」**

今回はHPを作っているため
従業員しかログインできないように
パスワードにバリデーションをかけたい！

前提としてdeviseを導入し、userモデルを作成しています。

```user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  validates :password,
              format: { with: /??/, allow_blank: true }
end

```

ここのformatの中に書けばいいと思うが
書き方がわからない...。

#結論
答えはシンプルで
\Aと\zで囲えばいいだけ！

```user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  validates :password,
              format: { with: /\Asample\z/, allow_blank: true }
end

```

上記でははsampleという文字列を指定しました。

少し見づらいので分けて書くと
最初の / と最後の / はformatの記法です。
それを\Aと\zで囲み、中に任意の文字列や数字を入れればOKです！
例) / \A "任意の文字列や数字" \z /

この方法で従業員しかログインできないように制限をかけることに成功！
【PHP】strpos関数で文字列が特定の文字を含んでないか調べるときの注意点

##はじめに
strpos関数使って文字列のチェックを行う際に、想定外の挙動になって少しあせったので自戒の念を込めて記事にします。PHPあるあるな内容だと思います。

##strpos関数について簡単に
strposは文字列内の部分文字列が最初に現れる場所を見つけることができます。

もう少し詳しく説明すると、
文字列の中に特定の文字が含まれている場合はその位置の数値
含まれていない場合はfalse
を返します。

公式マニュアル：[PHP: strpos - Manual ](https://www.php.net/manual/ja/function.strpos.php)
※ちなみに本記事の以降の内容はマニュアル内でしっかり言及されていました。みんな、しっかりマニュアル読もうね。

##注意点
- strposを使って、特定の文字を含んでないかをチェックする場合は厳密比較を使う。

厳密比較とは===を使った比較のことです。

反対に、曖昧比較は==を使った比較のことです。
また、`if (!strpos($string ,$findme))`のような書き方も曖昧比較になります。

（この辺について以前にも自戒記事を書いたのでぜひ！）
[【PHP】比較演算子「==」の罠](https://qiita.com/hiro_nr825/items/225e3dc5b8aaa65a6cdc)

曖昧比較の場合は０や'0'もfalse扱いになってしまうため、厳密比較を使わないと検索したい文字が検索対象の文字列の１文字目にあった場合に、falseになってしまいます。

例えば

```php
<?php
$string = 'aiueo';
$findme = 'a';
if (!strpos($string ,$findme)) {
    echo '含まれてないよ';
} else {
    echo '含まれてるよ';
}
```

この場合だと'含まれてないよ'と出力されてしまいます。
検索したい文字列'a'が検索対象の1文字目(0番目)にあるので、
　`strpos($string ,$findme)`の返り値0が曖昧比較によりfalse扱いなることで、このような結果になります。

ですので、===を使って厳密比較することで

```php
<?php
$string = 'aiueo';
$findme = 'a';

if (strpos($string ,$findme) === false) {
    echo '含まれてないよ';
} else {
    echo '含まれてるよ';
}
```
'含まれてるよ'と出力できます。

##さいごに
PHPでは理由がない限り==ではなく===を使うのが一般的ですが、
falseで条件判定したいときに!を使って省略してしまいがちなので気をつけないといけませんね。PHPの比較の曖昧さにはなかなか苦労させられます。
Atcoder ABC209 Python C問題振り返り

#目的

間違えてしまった問題の備忘録的なものを作りたいと思い投稿しました。自分の間違えたコードと、答えを見て修正したコードを載せるようと思っています。反面教師にしてください（笑）
Pythonで競プロを始めた方の役に立てれば幸いです。


#自分の提出(TLEしてしまいました)
```
N = int(input())
C = list(map(int,input().split()))
flg = 10**9 + 7
C1 = sorted(C)
C2 = []
 
for i,j in enumerate(C1):
  C2.append(j-i)
 
ans = 1
for i in C2:
  ans *= i
print(ans%flg)
```



#修正後の提出（AC確認済み）
```
N = int(input())
C = list(map(int, input().split()))
C.sort()
ans=1
 
for i in range(N):
    ans = ans * (C[i] - i) % 1000000007
print(ans)
```

#感想
考え方はあっていたのに悔しいです...
for文を2つ書いているところを、修正後のようにうまく1つにできればよかったようです。解説をみて納得しました。
あと、最後に1000000007で割るのではなく、毎回割ってしまった方が良さげですね。今回の学びです。

このコードの書き方良くないなぁと感じたり、私の認識で間違っているところがあったらどんどん教えていただきたいです。
日本語化済AndroidStudioのMemoryProfilerの致命的エラー

#日本語化済AndrodiStudioでのMemoryProfilerでエラーが発生する
[Pleiades](https://mergedoc.osdn.jp/#pleiades.html#PLUGIN)にてAndroidStudioを日本語化し、Javaでアプリ開発をしていました。

しかし、適当なJavaのアプリを実行してMemoryProfilerを起動し、Memoryをクリックすると、何も表示されません。
よく見ると右下に赤文字で!アイコンが表示されています。
![スクリーンショット 2021-07-12 16.50.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661162/ae7ee2c5-0f27-bfe4-19a1-ba30ea807397.png)

何かしらのエラーが発生している模様。Javaのコードですが、KotlinのNullPointExceptionが発生しています。
![スクリーンショット 2021-07-12 16.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661162/2b63c25c-76ea-466d-b76e-4c493715dcc5.png)

## 環境
* AndroidStudio version4.2.2
* Pleiades ver 2021.06.20

## 解決策
**日本語を解除する**、以上です。以降は日本語化解除の方法についてです。

>出典:　[Android Studio 4.1 の日本語化を解除する（英語に戻す）](https://zesys.net/pc/android/android-studio-cancel-japanese-localization/)

1.Pleuadesの設定ファイルの場所を確認し、「追加されるファイル」(path/studio.vmoption)を開く。（インストールするつもりで再びダウンロードし、setupを起動すれば簡単です。）
2.末尾の以下の2行を#でコメントアウト。

```
-Xverify:none
-javaagent:/Users/FujisawaNoritaka/Library/Application Support/Google/AndroidStudio4.2/jp.sourceforge.mergedoc.pleiades/pleiades.jar
```

3.AndroidStudioを開き直し、英語になっていることを確認

4.適当なJavaのアプリを実行してMemoryProfilerを起動し、Memoryをクリックします。エラーは発生せず、メモリの詳細が確認できます。
![スクリーンショット 2021-07-12 17.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661162/a8b2a3f5-98ef-6e47-a89c-ae29cbd3af95.png)

AndroidStudioは英語で利用したほうが良さげですね。。
TypeScript+Reactで別ファイルのコンポーネントを呼び出す(転何知人T+Rその3)

# [前回](https://qiita.com/botanic7arc/items/d71b292eb5a3c40d23de)までの状態

Hello worldした。

# 復習

ReactDOM.render()は、第一引数の内容(以下、コンポーネントと呼ぶ)を第二引数の描画対象(以下、DOM要素と呼ぶ)に描画している。

# 問題点

今後indexにプログラムを追加していくとファイルが大きくなり、後々困ることになる。そのため、ファイル分割する方法の知識が必要。

# 今回の目的

ReactDOM.render()から別ファイルのコンポーネントを呼び出す。


# 手順

前回使用したプロジェクトフォルダにapp.tsxというファイルを作成する。

```
touch app.tsx
```

内容は以下のように記述する。

``` tsx
const PrintHelloWorld =()=> {
    return (
        <h1>Hello, world!</h1>
    );
}
export {PrintHelloWorld};
```

また、前回使用したindex.htmlを以下のように変更する。

``` tsx
import React from 'react';
import ReactDOM from 'react-dom';
//追加開始
import {PrintHelloWorld} from './app';
//追加終了

ReactDOM.render(  
  //変更開始
  <React.StrictMode>
    <PrintHelloWorld />
  </React.StrictMode>,
  //変更終了
  document.getElementById('root')
);
```

変更したらnpm startでプロジェクト実行。

前回と同様にHello, world!と表示されたら成功。


# 解説

## app.tsx

``` tsx
const PrintHelloWorld =()=> {
    return (
        <h1>Hello, world!</h1>
    );
}
```

関数の形をしたコンポーネント。関数コンポーネントと呼ばれる。アロー関数という書き方で書いている。functionを使用した記法も存在するが、検索してみたところアロー関数を使用したほうがよさそうだったため、アロー関数にしている。
Reactコンポーネントにはパスカルケース(先頭大文字)を使用すると決まっているため、関数名の頭文字は大文字。(小文字にするとエラーになる)

``` tsx
export {PrintHelloWorld};
```
関数コンポーネントを他のファイルで使用するために宣言している。


## index.tsx

``` tsx
import {PrintHelloWorld} from './app';
```
./app(.tsx)からPrintHelloWorldコンポーネントを読み込む。
インポートするファイルのファイル拡張子は不要。


``` tsx
<React.StrictMode>
</React.StrictMode>,
```

潜在的な問題点を洗い出す機能を有効にする。必須ではないが、npx create-react-appした際にデフォルトで記述されていたため追加している。

``` tsx
<PrintHelloWorld />
```

PrintHelloWorldコンポーネントを呼び出している。


## 要約

exportで別のファイルから使用できるように宣言し、importで別ファイルのコンポーネントを読み込み、描写している。

# 次

[関数コンポーネントとクラスコンポーネント](https://qiita.com/botanic7arc/items/4affa706a0e9c95cab54)

# 参考文献
- [一番文句言われなさそうな React コンポーネントの書き方](https://zenn.dev/seya/articles/0317b7a61ee781)
- [なぜ default export を使うべきではないのか？ - LINE ENGINEERING](https://engineering.linecorp.com/ja/blog/you-dont-need-default-export/)
- [[翻訳] Airbnb React/JSX Style Guide - Qiita](https://qiita.com/yamadashy/items/e64762e407b8dd5e0247)
- [【JS】named exportとdefault exportの違いやReactでの使い分け | JavaScriptに関するお知らせ](https://jsnotice.com/posts/2021-01-30/)
- [コンポーネントと props – React](https://ja.reactjs.org/docs/components-and-props.html)
RNA-Seq発現量比較データ作成サービスの使い方3

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2115.html)から移行中です。
元記事：2017/02/08 公開 解析状況の確認方法【RNA-Seq発現量比較データ作成サービス】</font>

[RNA-Seq発現量比較データ作成サービスの使い方1はこちら](https://qiita.com/PictBio/items/ad6d3f895662792e0516)
[RNA-Seq発現量比較データ作成サービスの使い方2はこちら](https://qiita.com/PictBio/items/d60970fcb8d6aa7a2b40)

---

　弊社のサービスであるオンライン解析ツール「RNA-Seq発現量比較データ作成サービス」についてのご利用方法をご説明します。

[RNA-Seq発現量比較データ作成サービスのページ](https://www.pictbio.com/online_rnaseq)

　このページでは”解析状況の確認方法”を掲載いたします。(最終更新日2017/2/10)

#Step1 : 解析一覧の表示
　メニューバーに表示されている「Status」から今までに予約した解析の一覧を見ることができます（解析の予約までのフローはこちら）。

![メニューバー](https://www.pictbio.com/wp-content/uploads/tips/tips1925_1.png)

※メニューバーはログイン中システムのどのページでも表示されます。

#Step2 : 解析の状況を確認する
　解析の一覧からは解析タイトルごとに全体の状況が確認できます。実行状況については「Start（開始時間）」「Complete（終了時間）」「Status」で確認します。

![解析ステータス画面](https://www.pictbio.com/wp-content/uploads/tips/tips1925_2.png)

　予約後に解析が開始されていれば「Start」に日時が表示されます。まだ実行されていない場合は表の左にチェックボックスが表示され、チェックを入れて”Cancellation of the checked analysis”ボタンを押すことで予約をキャンセルすることができます。また、実行時に解析を停止するのには「Stop」に表示されているボタンで行うことができます。

　解析が終了した場合「Complete」に時間が表示されます。「Status」は解析を予約した時点で状態を表す文字が表示されます。それぞれの意味は以下の通りです。

|表示  |内容  |
|---|---|
|RECEIPT  |実行待ち  |
|RUNNING  |実行中  |
|DONE  |完了  |
|CANCEL  |キャンセルまたは停止  |
|ERROR  |エラー  |

#Step3 : 解析の詳細を確認する
　解析の一覧の表の右にある”Detail”ボタンから予約した解析それぞれの詳細が確認できます。左表は解析段階ごとの状況、右表は設定したパラメータが表示されます。

![解析詳細画面](https://www.pictbio.com/wp-content/uploads/tips/tips1925_3.png)

　解析段階は3つに分かれており、表の上から順に実行されていきます。

### 「Quality check」完了時
右表の各サンプルの欄に「QC results」ボタンが表示され、結果をダウンロードすることができます。

###「Mapping」完了時
「Quality check」と同様の箇所に「Mapping results」ボタンが表示され、結果をダウンロードすることができます。

###「Comparing」完了時
表の下に「Download Data Sheet」ボタンから最終結果の表がダウンロードできるようになります。
RNA-Seq発現量比較データ作成サービスの使い方2

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2110.html)から移行中です。
元記事：2017/02/08 公開 データのアップロードから解析まで【RNA-Seq発現量比較データ作成サービス】
</font>

[RNA-Seq発現量比較データ作成サービスの使い方1はこちら](https://qiita.com/PictBio/items/ad6d3f895662792e0516)
[RNA-Seq発現量比較データ作成サービスの使い方3はこちら](https://qiita.com/PictBio/items/2cfd5f3743600d85b093)

---

　弊社のサービスであるオンライン解析ツール「RNA-Seq発現量比較データ作成サービス」についてのご利用方法をご説明します。

[RNA-Seq発現量比較データ作成サービスのページ](https://www.pictbio.com/online_rnaseq)

　このページでは”データのアップロードから解析まで”の方法を掲載いたします。(最終更新日2017/2/10)

#Step1 : メニュー画面
　システムにログイン後はメニュー画面に移動します。メニュー画面からは「File Manager（ファイルアップロード）」「Expression comparison（解析）」の機能に移動できます。

![メニュー画面](https://www.pictbio.com/wp-content/uploads/tips/tips1920_1.png)

#Step2 : ファイルのアップロード
　メニュー画面「File Manager」ボタンから移動します。「Upload your file」ボタンをクリックしてお持ちのFASTQファイル（シーケンサーの出力）をアップロードしてください。
　アップロードはネットワークを介して行っているため、終わるまでは途切れないようお気を付けください。パソコンのスリープ設定を調整することをお勧めいたします。
　「–Uploaded file list–」にあるファイル名とかぶる場合は名前を変更してから行ってください。

![ファイルアップロード画面](https://www.pictbio.com/wp-content/uploads/tips/tips1920_2.png)

#Step3 : 解析の設定
　「Expression comparison」ボタンから移動します。
　解析に名前を付けてください（以前実行した解析の設定をこの名前で呼び出すことができます）。そして、生物種を選択します。現在は以下の種を選択できます。

+ Human
+ Mouse
+ Rat
+ Zebrafish

　シーケンスしたときのアプリケーションに合わせて”Single-end”、”Paired-end”のどちらかを選択します。選択したアプリケーションに応じてサンプルの設定フォームが変化します。変化後のサンプル設定フォームではアップロードしたファイルを選択します。”Paired-end”の場合はペアのファイルを選択し、さらにインサートサイズも設定することができます。

![解析設定画面](https://www.pictbio.com/wp-content/uploads/tips/tips1920_3.png)

　複数のサンプルを設定するときは「+」「-」ボタンでフォームを追加、削除できます。画面左（サンプルナンバーの右）に表示されているものはサンプルグループの増減ができます。画面右（フォーム右）に表示されているものはサンプルグループ内のセットの増減ができます。

#Step4 : 解析の実行
　解析の設定が完了したら「Send to BcMARx」ボタンで設定を送信します。うまく設定できていればそのまま実行され、間違っていればエラー内容が表示されますので調整してください。送信後は画面を閉じても大丈夫です。
RNA-Seq発現量比較データ作成サービスの使い方１


<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2106.html)から移行中です。
元記事：2017/02/08 公開 ご利用申請から利用開始まで【RNA-Seq発現量比較データ作成サービス】
</font>

[RNA-Seq発現量比較データ作成サービスの使い方2はこちら](https://qiita.com/PictBio/items/d60970fcb8d6aa7a2b40)
[RNA-Seq発現量比較データ作成サービスの使い方3はこちら](https://qiita.com/PictBio/items/2cfd5f3743600d85b093)

---

　弊社のサービスであるオンライン解析ツール「RNA-Seq発現量比較データ作成サービス」についてのご利用方法をご説明します。

[RNA-Seq発現量比較データ作成サービスのページ](https://www.pictbio.com/online_rnaseq)

　このページでは”ご利用申請から利用開始まで”の方法を掲載いたします。(最終更新日2017/2/10)

#Step1 : 利用申請
　まずはフォームから申請いたします。必要事項を埋め、「Register」ボタンを押してください。

[利用申請フォーム](https://bcmarx.pictbio.com/userform/userform.action)

![利用申請フォーム](https://www.pictbio.com/wp-content/uploads/tips/tips1915_1.png)

#Step2 : 申請内容の確認
　フォームに記載した内容が設定したメールアドレスにタイトル「BcMARxからのお知らせ」で届きます。もし間違ったアドレスを記載してしまった場合は届きませんので、もう一度「Step1」からお願いします。

#Step3 : サービス担当者から連絡
　弊社のサービス担当から「Step2」のメールに返信の形式で利用に関するご連絡をいたします。

#Step4 : ツールシステムにログイン
　「Step1」で登録したアドレスとPasswordを使用して、システムにログインができます。

[ログインフォーム](https://bcmarx.pictbio.com/login/index)

![ログインフォーム](https://www.pictbio.com/wp-content/uploads/tips/tips1915_2.png)
C#フレームワーク　ASP.NET Core3入門 をやってみた感想と修正



## 修正箇所
### p.179 dotnet-efインストール箇所

```shell
✖️ $ dotnet add package Microsoft.EntityFrameworkCore.Design
◯ $ dotnet add <プロジェクト名> package Microsoft.EntityFrameworkCore.Design
```
※正確にはプロジェクト名を省略してもプロジェクトを探してインストールしてくれるみたいなので人によっては動くと思いますが、自分は動かなかったのでプロジェクト名入れてインストールしました！

```shell
✖️ $ dotnet ef migrations add InitialCreate 
◯ $ dotnet ef migrations add InitialCreate -p <プロジェクト名>
```
※これも同様の内容！

### p.187 MySQLとの接続（リスト4-11）
▼公式ドキュメント　より参照

https://metanit.com/sharp/entityframeworkcore/7.2.php

```C#
▼ ✖️
services.AddDbContext<SampleMVCAppContext>(options =>
    options.UseMySQL(Configuration.GetConnectionString("SampleMVCAppContext")));
);
▼ ◯
services.AddDbContext<SampleMVCAppContext>(options =>
    options.UseMySql(
        "server=127.0.0.1;port=3306;database=<データベース名>;userid=<ユーザー名>;password=<パスワード>",
        new MySqlServerVersion(new Version(8, 0, 11))
    )
);
```

## 実装に詰まった箇所
### p.368「Microsoft.AspNetCore.Authentication.Google」のパッケージ追加
プロジェクト>NuGetパッケージの管理から追加してもダメ。
コマンドからインストールしてもダメ。

```shell
$  dotnet add SampleAuthApp package Microsoft.AspNetCore.Authentication.Google --version 5.0.8
---
error: NU1202: Package Microsoft.AspNetCore.Authentication.Google 5.0.8 is not compatible with netcoreapp3.1 (.NETCoreApp,Version=v3.1). Package Microsoft.AspNetCore.Authentication.Google 5.0.8 supports: net5.0 (.NETCoreApp,Version=v5.0
---
```
みたら笑てしまいますね笑
.NetCoreのバージョンは3.1なのでMicrosoft.AspNetCore.Authentication.Googleも3.〇〇をインストールしてあげれば解決しました。
 


## 実装できなかった箇所
### P262 数字のバリデーションエラーメッセージの日本語化(リスト5-24)
``` C# 
[Display(Name="年齢")]
[Range(0, 200, ErrorMessage = "1から200の間で入力してください")]
public int Age { get; set; }
```

## その他
### dotnet ef コマンドのアップデート
```
The Entity Framework tools version '5.0.4' is older than that of the runtime '5.0.7'. Update the tools for the latest features and bug fixes.
```
と怒られたのでアップデートしましょう。

```shell
#helpでアップデート方法の確認
$ dotnet tool --help
---
Options:
  -h, --help   Show command line help.

Commands:
  install <PACKAGE_ID>     Install global or local tool. Local tools are added to manifest and restored.
  uninstall <PACKAGE_ID>   Uninstall a global tool or local tool.
  update <PACKAGE_ID>      Update a global tool.
  list                     List tools installed globally or locally.
  run <COMMAND_NAME>       Run local tool.
  search <Search Term>     Search dotnet tools in nuget.org
  restore                  Restore tools defined in the local tool manifest.
---

# アップデートの実行
$ dotnet tool update --global dotnet-ef

```
### SQLiteの使い方
1. DB Browser for SQLiteのインストール（https://sqlitebrowser.org/dl/）
1. sollution内で`hogehoge.db`の拡張子の上で右クリック
1. プログラムから開く→DB Browser for SQLie
[Rails]bootstrapでプログレスバーを実装する

##はじめに
今回はbootstrapでプログレスバーの実装に挑戦しました。
bootstrapなんだからコピペで実装できるやろ！っと思ってたんですが、自分が思った通りの表示ができなかったり、追加で指定しないといけないプロパティがあったので簡単ですが、まとめました。

よろしくお願いします。

##プログレスバーの実装

プログレスバーで進捗記録によって今自分が何%の進捗状況なのかわかるような機能を実装したくて挑戦してみました。
↓こんなのを作ろうとしてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/b9b2a64a-7f38-a69b-e2b5-b05c29fd6ed2.png)

もちろんbootstrapを利用しているので非常に簡単に実装できたのですが、少し引っかかりました。
↓こちらのチートシートを利用しました
https://hackerthemes.com/bootstrap-cheatsheet/#progress__height

私は、```progress-bar-with label```というのを使いました。
ソースコードがこちら↓

```erb
<div class="progress">
  <div class="progress-bar" role="progressbar" style="width: 25%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
```

このままコピペしたのですが、全然出てこなかったです。
なんだこりゃと思い検証ツールでブラウザを確認してみると、一応存在はしていました。
横幅が0だったので、これが原因かなと思いまして、CSSでクラス名progressに```width: 80%```を指定してあげたら、ちゃんと表示されるようになりました！

さてここからが、問題でした。
このコードでは25%のプログレスバーしか使えません。要は、styleとaria-valuenowのところに変数を利用し、汎用的に表示させたいということです。

私はdivタグの中でrubyは使えないと勝手に思い込んでいたのでめちゃくちゃ悩みました。
実はdivタグ内でも＜％＝　％＞で囲めば使えるみたいです。

結果このようなコードになりました。↓

```erb
<div class="progress">
  <div class="progress-bar" role="progressbar" aria-valuenow=<%= @progress_percent.to_s %> aria-valuemin="0" aria-valuemax="100" style=<%= "width:" + @progress_percent.to_s + "%;" %>> <%= @progress_percent.floor %>% </div>
</div>
```

すごい変な感じですがこれで表示することができました！
divの中に変数と％を記述することでバーの中に今何%なのか数値を表示させることもできました。

##最後に
実はプログレスバーは何回も失敗して打ちのめされてコード全消しみたいなことをずっとやってました。
今回bootstrapというチート技を使いましたが、実装できてめちゃくちゃ嬉しいです。変数を使って汎用的に使えるようにするのは結果的に少し工夫するだけでできましたが、ここまでたどり着くのは苦労しました 笑
読み取り専用ブックに対してポップアップを出す

ユーザーフォームを適当に投げ込む

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/cc96cac2-cf46-fe5a-c35e-4f5cef50ae73.png)

## ThisWokbook
``` vb
Private Sub Workbook_Open()
  Call BookReadOnlyCheckTest
End Sub
```

## 標準モジュール
``` vb
Option Explicit

Sub BookReadOnlyCheckTest()
    Dim wb  As Workbook
    Dim readOnlyFlg

    Set wb = ActiveWorkbook
    readOnlyFlg = wb.ReadOnly

    If readOnlyFlg = True Then
        Call CallUF
    Else

    End If
End Sub

Sub CallUF()
  Load UF読取専用ポップ
  With UF読取専用ポップ
    .StartUpPosition = 3
    .Show vbModeless
  End With
End Sub
```


## ユーザーフォーム
モジュール名：UF読取専用ポップ

``` vb
Option Explicit

Private Sub UserForm_Initialize()
  Dim wName: wName = ThisWorkbook.Name
  With Label1
    .Caption = wName & "は現在読み取り専用です。" & vbLf & "保存できません。"
    .BackColor = vbYellow
    .Font.Size = 20
    .Width = 400
    .Height = 85
  End With
  With UF読取専用ポップ
    .Caption = "注意"
    .BackColor = vbYellow
    .Width = 400
    .Height = 85
  End With
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        'MsgBox "［閉じる］ボタンを使用してください"
        Cancel = True
    End If
End Sub


```
Swift SDKでスクリプト機能を実行する方法

ニフクラ mobile backendでは各種言語向けにSDKを提供しています。その中で最も新しいSwift SDKについて、その使い方を紹介します。

今回はSwift SDKからNCMBのスクリプト機能を実行する方法を解説します。

## スクリプト機能とは

NCMBのスクリプトは、FaaS（Function as a Service）になります。クラウドにコードをアップロードして、アプリから呼び出せるようになります。Node.jsやRubyが利用できます。


## 実際のコード

今回はGETメソッドでスクリプトを実行してみます。パラメータも `name=NCMB` として送信しています。

```swift
// 呼び出すスクリプトファイルとメソッドを指定
let script = NCMBScript(name: "script.js", method: .get)

// パラメータを用意
var params: Dictionary<String, String> = [:]
params["name"] = "NCMB"
// スクリプトの実行
script.executeInBackground(headers: [:], queries: params, callback: { result in
    switch result {
        case let .success(data):
            // 実行成功時の処理
            print("scriptSample 実行に成功しました:")
            let str: String = String(data: data!, encoding: .utf8)!
            print(str);
        case let .failure(error):
            // 実行失敗時の処理v
            print("scriptSample 実行に失敗しました: \(error)")
            return;
    }
})
```

## スクリプトの内容

アップロードしたスクリプトは次のようなものです。とても簡単なコードです。

```js
module.exports = function(req, res) {
  if (req.query.name) {
    res.send('Hello,' + req.query.name);
  } else {
    res.send('Hello');
  }
}
```

## スクリプト実行時のコード

スクリプトの `script.executeInBackground` は次の3つの引数をとります。

- headers
- queries
- body

それぞれヘッダー、クエリ、ボディ（POST/PUT用）になります。ボディを除けば `Dictionary<String, String>` でデータを設定する形になります。

## 結果の取得

結果はDataとしてくるので、コンバートが必要です。

```swift
let str: String = String(data: data!, encoding: .utf8)!
```

これは単なる文字列なので、JSONとしてパースする処理は別途必要になります。

## まとめ

スクリプト機能を使えばiOSとAndroidアプリの処理を共通化したり、セキュリティキーの隠蔽、ガチャのようなロジックの隠蔽化などが実現できます。アプリ開発時に利用してください。

[スクリプト (Swift) : 基本的な使い方 | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/script/basic_usage_swift.html)
MYSQL まとめ

### macOS に MYSQLをセットアップ
▼参考にした記事

https://kita-note.com/mysql-install-mac


### mysqlへのログイン
```shell
# localhostのMySQLサーバに接続する場合
$ mysql -u [ユーザー名] -p

# 外部MySQLサーバに接続する場合
$ mysql -u [ユーザー名] -p -h [host名] -P [ポート番号]
```

### ログアウト
```shell
mysql > \q
mysql > quit
mysql > exit
```
Swift SDKで位置情報データを保存する方法

ニフクラ mobile backendでは各種言語向けにSDKを提供しています。その中で最も新しい[Swift SDK](https://mbaas.nifcloud.com/doc/current/#/Swift)について、その使い方を紹介します。

今回はデータストアに位置情報データを保存する方法を解説します。

## 実際のコード

実際のコードは次のようになります。データストアのHelloクラスに対して、geoというフィールドで位置情報を保存しています。

```swift
let obj = NCMBObject(className: "Hello") // Helloというクラス名
// 位置情報の定義
var geo: Dictionary<String, Any> = [:]
geo["__type"] = "GeoPoint"
geo["latitude"] = 35.6585805
geo["longitude"] = 139.7454329

obj["geo"] = geo  // ← 位置情報をセット
obj.saveInBackground(callback: { result in
    switch result {
    case .success:
        print(obj.objectId! as String)
    case let .failure(error):
        print(error)
    }
})
```

## データストアで扱える型について

データストアでは次のようなデータ型を扱えます。

- 文字列
- 数値
- 真偽値
- 日付
- オブジェクト（配列含む）
- 位置情報

## 位置情報の型について

位置情報は現時点（1.2.0）のSwift SDKでは専用クラスを提供していません。そのため、Dictionary型を用いています。データは次の3つのプロパティがあります。

| 名称 | 型 | 意味 |
|-----|-----|-----|
| __type | 文字列 | GeoPoint固定 |
| latitude | 数値 | 緯度 |
| longitude | 数値 | 経度 |

`__type` を GeoPoint とすることで、データが位置情報型であることを定義しています。ほかに日付、ポインター、リレーション型の場合に `__type` を利用します（日付型は暗黙的にDate型と相互変換されるので気にする必要はありません）。

## まとめ

将来的に位置情報クラスが追加されるはずですが、今の時点で位置情報をデータストアに保存したい場合には、今回の方法を利用してください。

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)
PostgreSQL interval型の数値だけ欲しい

# PostgreSQL interval型の数値だけ欲しい

interval型では数値と単位が融合して出力されるので単純に数値だけ欲しい場合に困った。
先に自分のメモ的にも使用すると思うので、どうしたかを書いておきます。

```
SELECT EXTRACT(EPOCH FROM (CAST('2021-07-12' AS TIMESTAMP) - CAST('2021-06-01' AS TIMESTAMP))) / (60 * 60 * 24) AS elapsed_days
```


## EXTRACT関数
```
EXTRACT(field FROM source)
```
EXTRACT関数を利用すると、date/timeから年や時間、月、曜日を取得できる。  
EXTRACT関数のfieldにEPOCHを与えると、、、  
date型とtimestamp型の値の場合は、1970-01-01 00:00:00からの秒数を返します(負の数の場合もあり)。  
interval型の値の場合は、インターバルの秒の合計を返す。

```
SELECT EXTRACT(MONTH FROM (CAST('2021-07-12' AS TIMESTAMP)))
/* 7 */

SELECT EXTRACT(EPOCH FROM (CAST('2021-07-12' AS TIMESTAMP)))
/* 1626048000 */

SELECT EXTRACT(EPOCH FROM (CAST('2021-07-12' AS TIMESTAMP) - CAST('2021-07-11' AS TIMESTAMP)))
/* 86400 */

```

## 結論
interval型にEXTRACT(EPOCH FROM source) を使用するとインターバルの秒の合計を返すので、一日の秒数である「60 * 60 * 24」で割れば日にちに単位を直すことが出来る。

## 参考
https://cellbank.nibiohn.go.jp/legacy/information/pc/postgres_man/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT

https://m6u.hatenablog.com/entry/2017/01/12/115633
opencv-vscode-mac-c++ 環境構築　困ったこと

# 環境構築手順
### 1. opencvをインストール

```shell
brew install opencv
```
バージョン確認

```shell
brew list --versions | grep opencv
// => 4.5.3   私の場合
```

### 2. C++のプログラムを用意
```cpp:main.cpp
#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
    cv::Mat img = cv::imread("sample.jpeg");

    cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
    cv::imshow("test", img);
    cv::waitKey(0);
    cv::destroyWindow("test");
    return 0;
}
```

ディレクトリ構造

```
├── main.cpp
└── sample.jpeg
```

適当な画像を用意し上記のディレクトリ構造にした。

### 3. 実行
```shell
g++ main.cpp -o main.out `pkg-config --cflags opencv` `pkg-config --libs opencv` && ./main.out
```

```shell:エラー
Package opencv was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv' found
Package opencv was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv' found
main.cpp:1:10: fatal error: 'opencv2/opencv.hpp' file not found
#include <opencv2/opencv.hpp>
         ^~~~~~~~~~~~~~~~~~~~
1 error generated.
```

あれ、、、インストールしたはずの``opencv``がないと言われている。。。。

# 解決方法
### 1. ``pkgconfig``にコピーする

```shell
sudo cp /usr/local/Cellar/opencv/インストールしたバージョン/lib/pkgconfig/opencv4.pc /usr/local/lib/pkgconfig/opencv.pc
```

```shell:私の場合
sudo cp /usr/local/Cellar/opencv/4.5.3/lib/pkgconfig/opencv4.pc /usr/local/lib/pkgconfig/opencv.pc
```

### 2. 実行

```shell
echo `pkg-config --cflags opencv`
```

```shell
g++ -std=c++11 main.cpp -o main.out `pkg-config --cflags opencv` `pkg-config --libs opencv` && ./main.out
```

# 参考サイト
- [MacでC++からOpenCV4を使う](https://naoyashiga.hatenablog.com/entry/2020/04/12/223441)
- [OpenCVのコンパイルエラー](https://teratail.com/questions/167878)
- [OpenCVを使ったC++コードをコンパイルする（CMake, GCC, pkg-config）](https://qiita.com/kekenonono/items/0fcf042bca2d3d17867a)
再帰問い合わせ・非再帰問い合わせ・反復問い合わせ の違い

## 勉強前イメージ

たしかどこからどこへの問い合わせはこれってのあったような記憶があるけど
覚えてない

## 調査

### 再帰問い合わせ

クライアント から DNSキャッシュサーバ に送られる問い合わせが `再帰問い合わせ` になります。
再帰問い合わせを受け取ったDNSサーバは、名前解決が完了するまで権威サーバをたどり、
結果をクライアントに返します。

### 非再帰問い合わせ

DNSサーバ から 権威サーバ に送られる問い合わせが `非再帰問い合わせ` になります。
非再帰問い合わせを受け取ったDNSサーバは、自分が知ってる情報のみを返します。

### 反復問い合わせ

`非再帰問い合わせ` を上位の権威サーバから下位の権威サーバまで繰り返して問い合わせを行うのが `反復問い合わせ` になります。

### まとめ

- 再帰問い合わせ → クライアントからDNSサーバへの問い合わせ、最終的な答えを返す
- 非再帰問い合わせ → DNSサーバから権威サーバへの問い合わせ、わかる答えだけ返す
- 反復問い合わせ → 非再帰問い合わせを繰り返して行うこと

![12021-07-12 # 再帰問い合わせ・非再帰問い合わせ・反復問い合わせ の違い - diagrams.net - Google Chrome 2021-07-12 11.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/163829b0-9b33-1306-b066-cb4051149730.png)


## 勉強後イメージ

PC→DNSサーバは答えが返ってくるから再帰？
DNS→権威は必ずしも求めてる答えが直で返ってくるとは限らないから非再帰？

## 参考

- [【DNS】再帰問い合わせと反復問い合わせの違い](https://murci.net/archives/1222)
- [「再帰問い合わせ」と「非再帰問い合わせ」の違いを教えてください](https://www.atmarkit.co.jp/ait/articles/1510/28/news013.html)
Table内のTextのイベントで同一行の値操作

タイトルの通り
Table内のテキストの入力値を別のTd要素の値との差分をさらに別のTd要素に表示するというもの
取るに足らない内容ですが、やり方調べるのに少し時間がかかってしまったので記録用に残しておきます。

``` table.html

<table>
  <thead>
    <tr id="head">
      <th>XXX</th>
      <th style="width: 100px;">在庫</th>
      <th style="width: 100px;">使用量</th>
      <th style="width: 100px;">残数</th>
    </tr>
  </thead>
  <colgroup>
    <col style="width: 15%;" />
    <col style="width: 8%;" />
    <col style="width: 8%;" />
    <col style="width: 8%;" />
  </colgroup>
  <tbody>
    <tr id="tr1">
      <th>部品１</th>
      <td>1,500</td>
      <td><input name='textOnTd' type="text" value="1,000"></td>
      <td class="txt_right">0</td>
    </tr>
    <tr id="tr2">
      <th>部品２</th>
      <td>3,000</td>
      <td><input name='textOnTd' type="text" value="1,000"></td>
      <td class="txt_right">0</td>
    </tr>
  </tbody>
</table>

```


``` table.js

  $(function () {
    $("[name^=textOnTd]").on("keydown", function () {
      var use = $(this).closest('tr').find('input[name=textOnTd]').val().replace(/,/g, '');
      var stock = $(this).closest('tr').children("td")[0].innerText.replace(/,/g, '');
      var sum = Number(stock) - Number(use);
      $(this).closest('tr').children("td")[2].innerText = sum.toLocaleString();;
    });
  });

```
初めてのダイクストラ法

はじめてダイクストラ法を学習してプログラムしてみたので覚書として書いています。


早川桃子先生のYouTube
離散数学入門#5: 最短経路問題：ダイクストラ法とワーシャル–フロイド法
https://m.youtube.com/watch?v=e6X2gDTZYCQ
の例題の実装を試みてみました。
実行環境はpaiza.ioです。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3636333537362f62373930623430632d373661662d353337372d633961622d6666303763366162333231392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663576/a83dee0f-2fdc-265a-e81d-f23ce0c56dbf.png)


```python:dijkstra.py
n,m=[int(i) for i in input().split()]
#print(n,m)
a=[]
for i in range(m):
   a.append([int(j) for j in input().split()])
#print(a)
v=[999999]*n
vk=[False]*n
#print(v,vk)
v[0]=0
#print(v,vk)
#j=0
while True:
    v1=999999
    i1=999999
    for i in range(n):
        if v[i]<v1 and vk[i]==False:
            i1=i
            v1=v[i]
    if i1==999999:
        break
    #print(i1,v1)
    vk[i1]=True
    for a1 in a:
        #print(a1)
        if a1[0]==i1:
            v[a1[1]]=min(v[a1[1]],v[i1]+a1[2])
            #print(v,vk)
    #j+=1
print("ans",v,vk)
#print(a)
#後戻り
#print(v[6])
i1=6
rp=[]
rp.append(i1)
#j=0
while True:
    if i1==0:
        break
    for a1 in a:
        if a1[1]==i1:
            #print(a1,v[i1],v[a1[0]])
            if v[i1]-a1[2]==v[a1[0]]:
                #print(a1,v[i1],v[a1[0]]," ",end="")
                i1=a1[0]
                #print(i1)
                rp.append(i1)
                #print(rp)
                #j+=1
                break
print("pass",rp[::-1])
```
【javascript】unshiftが遅い

#遅くなる時
自分用に作った関数のテスト中に、`for`で**10000回**ほど`unshift`を用いて処理した時、明らかに重くなった。


#コード
**case2**のように別の配列を用意して`push`で追加してから反転させて`unshift`すれば
`push`と同程度の処理時間で済む。
大量に処理する時以外は普通に`unshift`を使ったほうが良いと思う。

```javascript:
const n = 10000;

//【case1】
//直接unshift
console.time('unshift');

const base1 = Array(10).fill(0);

for (let i=0; i<n; i++) {
	base1.unshift(i);
}

console.timeEnd('unshift');
//console.log(base1);

//【case2】
//空の配列にpushでまとめた後に反転させてunshift
console.time('push');

const base2 = Array(10).fill(0);

const arr = [];
for (let i=0; i<n; i++) {
	arr.push(i);
}
base2.unshift(...arr.reverse());

console.timeEnd('push');
//console.log(base2);
```
いのべこ夏休みアドベントカレンダー 2021

# はじめに
「いのべこ」とは、[富士通株式会社FSWebユニット（旧富士通システムズウェブテクノロジー）](https://www.fujitsu.com/jp/group/fsweb/)の社内技術コミュニティで、「**イノベ**ーション推進**コ**ミュニティ」が略されたものです。
「いのべこ」の2021年夏企画として「いのべこ夏休みアドベントカレンダー」を企画しました。アドベントカレンダー企画としては４回目となりますが、これまで同様に参加者の皆さんで盛り上げていきましょう！
参考：
[いのべこ（富士通システムズウェブテクノロジー） アドベントカレンダー2020](https://qiita.com/advent-calendar/2020/fsweb)
[いのべこ夏休みアドベントカレンダー 2020](https://qiita.com/jugemsan/items/5761773308fb1df0c23a)
[富士通システムズウェブテクノロジーアドベントカレンダー2019](https://qiita.com/advent-calendar/2019/fsweb)

# ルール
- 参加者：当ユニット社員・派遣社員および富士通グループ社員に限らせて頂きます
- テーマ：「技術」に関することならなんでもOK
- 記事形式：自由です。Qiita、個人ブログ、YouTube、なんでもありです
- Fujitsu Way、Fujitsu Wayのサイトにある「ソーシャルメディアを利用する場合のルールとマナー」の記述を守るようにしましょう
- [Qiitaのガイドライン](https://help.qiita.com/ja/articles/qiita-article-guideline)も目を通しましょう

# 参加登録方法
- 記事の一番末尾にある「...」メニューから**編集リクエストを送る**を選択し、参加したい日付に以下の項目を書いて送ってください
    - 執筆者名（ペンネームでもOKです）
    - タイトル（仮で大丈夫です）
- なるべく早く反映するようにします
- 後からでも修正可能です。同様にご連絡ください
- 毎週水曜日は、当社社員以外の優先枠とします（が、埋まり具合で見直しもあります）

# 記事作成後の登録方法
- **編集リクエスト**で記事のタイトルとURLを送ってください
- （できるだけ）当日までに記事を書いて登録してください

# 技術同人誌を９月に制作します
- 本企画にエントリーした記事を紹介する同人誌を制作、「技術書典」等で頒布致します。
- 記事掲載を承諾して頂けた参加者の方には、掲載のお礼として**３部**差し上げます。

# さいごに
このページの記述は[Unityゆるふわサマーアドベントカレンダー 2019](https://qiita.com/nkjzm/items/7c933bb5c772a0b75512#%E3%83%AB%E3%83%BC%E3%83%AB)を運営された@nkjzmさんの下記記事を参考とさせていただきました。ありがとうございました！
[2年連続で夏のアドカレ運営をやってみての感想 【ゆるふわアドカレ】](http://kohki.hatenablog.jp/entry/yuruhuwa-summary)

# いのべこ夏休みアドベントカレンダー 2021 記事一覧
|Date|記事名|執筆者名|
|:-:|:--|:--|
|8/1(日)|[門前の小僧、Playdateの開発環境を調べる](https://pichi.net/jugemsan/?p=1554)|@jugemsan|
|8/2(月)|募集中||
|8/3(火)|募集中||
|8/4(水)|募集中||
|8/5(木)|[アジャイル開発プロジェクトで<br>色々とインプットしたものをアウトプットします(適宜更新中)](https://www.shotoro.com/entry/2021/08/04/190537)|@hanashun|
|8/6(金)|募集中||
|8/7(土)| [Amazon EventBridgeとは何か](https://qiita.com/ishibashi-futoshi/items/586ebe17b174a478eb6a) | @ishibashi-futoshi |
|8/8(日)|募集中||
|8/9(月)|[初心者がMonacaでiPhoneのアプリを作ってみた](https://qiita.com/eight-cotton/items/301c1f33c73e0fccae44)| @eight-cotton |
|8/10(火)|[AWS Glueのワークフローを触ってみた](https://levia9071.hatenablog.com/draft/entry/_bznBzsh8_m-IyJrPjhfhUYk30w)| @LEViA |
|8/11(水)|[Go \+ MySQL \+ Docker で簡単なWebAPIを作ってみた ](https://qiita.com/George22e/items/50f16782597223bb7885)|@George22e|
|8/12(木)|[keycloak or React or NestJS](https://qiita.com/harimogura/items/d867177e705178d8af06)|@minoru|
|8/13(金)|[初心者がAWS Lambda + Python + LINE BotでWikipediaのタイトルをランダム送信](https://qiita.com/kuwayutal/items/9b3cb66a976eecd24fa4)| @kuwayutal |
|8/14(土)| [Raspberry Piを使用した二酸化炭素濃度による換気扇自動制御をためす](https://qiita.com/mine-t/items/11ae263d9e57663d71c6) | @minegishi |
|8/15(日)| [Asanaの活用事例　～個人タスク管理編～](https://qiita.com/ikedahideya/items/2120983a98b165b9217f) | @ikedahideya |
Couchbase Server クラスター設定解説：Dataサービスの設定（読み込み・書き込みスレッド数）


Couchbase　Serverクラスターでは、ノードごとにデータの読み取りと書き込みのそれぞれに、割り当てるスレッドの数を設定可能です。

最大は64スレッド、最小は4スレッドです。

- **Default** ほとんどのワークロードに適したバランスの取れた値にスレッドの数を設定
- **Disk i/o optimized** ノードの持つCPUコアの数と同じスレッド数を割り当てる
- **Fixed value** プルダウンメニューから選択した固定値を用いる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/52f08f47-3208-6358-6771-8b38062175c9.png)



ハードウェアリソースが十分な場合、多くのスレッドを割り当てることで、パフォーマンスを向上させることができる可能性があります。

データ書き込みの頻度が高いユースケースにおいて、書き込み用スレッドを増やすことによって、性能の最適化を計ることが考えられます。

当然ながら、スレッド数を闇雲に増やせば良いわけではなく、リソースが十全でない場合には、スレッド数の変更によって、システムのパフォーマンスが損なわれる可能性があることに注意が必要です。本番システムでは、事前のテストなしにデフォルトのスレッド割り当て数を変更しないことが肝要です。
Laravel バッチ処理の実行

#プログラムからのバッチ処理実行

Laravel ではバッチ処理を artisan を使用して実行する事が出来ます。
具体的には**cronに実行コマンドを登録する**、**プログラムから実行する**、という方法があるのでこれらのやり方を記します。
※バッチプログラムの追加から登録、実行まで


##バッチ処理プログラムの追加
まずはバッチ処理を記述するファイル(PHPファイル)を以下のコマンドで作成します。

```
$ php artisan make:command BatchTest
Console command created successfully.
```

実行すると ./app/Console/Commands/ 配下に BatchTest,php が作成されます。

```
ls -la ./app/Console/Commands/
-rw-rw-r-- 1 vagrant vagrant    675  7月 12 11:55 BatchTest.php
```

出来上がったファイルを開いてみます

```php:BatchTest.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class BatchTest extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
    }
}
```

こんな感じになっているので、以下の修正をしてみます。

```php:BatchTest.php
    protected $signature = 'testBatch:testDayo';
    protected $description = 'コマンド実行のテストだよ';

    public function handle()
    {
        echo date("YmdHis");
    }

```

\$signature はこのプログラムのサイン？識別子みたいなものです。英数字で指定しましょう。
\$description はこのプログラムの説明文です。日本語でもOKです。
これらは、次の「**バッチ処理の実行**」で確認出来ます。

##バッチ処理の実行
###確認
以下のコマンドを実行します

```
$ php artisan list
```

すると、出力され結果の中に以下のものが含まれています。

```
testBatch
  testBatch:testDayo             コマンド実行のテストだよ
```

先ほど指定した \$signature と \$description が使用されています。
では、次でこのプログラムを実行します。

###実行
以下のコマンドを実行します。

```
$ php artisan testBatch:testDayo
```

`$php artisan` + `$signatureで指定した文字列`　です。

###実行結果

```
$ php artisan testBatch:testDayo
20210712151545
```

以下のコードが実行されました。

```php:BatchTest.php
    public function handle()
    {
        echo date("YmdHis");
    }
```

##cron登録
では、このプログラムは**バッチ**という位置づけなので、cronに登録してみます。
※windowsであればタスクスケジューラー

crontab に以下を追加

```
00 * * * * php artisanまでのパス/artisan testBatch:testDayo
```

これで毎時0分にプログラムが実行されます。

##プログラムから実行
cron からではなくプログラムから実行するためには以下のように記述します。

```php
use Artisan;

～～処理を実行したいところ～～
Artisan::call('testBatch:testDayo');
```

Artisanクラスを使う事でコマンドを記述して実行、とは異なる実装が可能です。
UdemyのDocker講座まとめ

僕が個人的に神と崇める、maximilianさんの講座の復習として、内容を要約します。
主に自分の復習用として、記載しています。


## Images and Containers
- Image
    - Blueprint for containers
        - its consist of  our code and environment
        - multiple layers
        - read-only
    - types of Image
        -  pre-built image ex) docker-hub
        -  custom image
- Containers
    - multiple containers are created by one Image
        - Read-write
- Image Commands
    - docker tag
    - docker images / listing
    - docker iamge inspect / analyzing
    - docker rmi / removing
    - docker push/pull 
    - docker build / making a new Image beased on dockerfile
- Containers commands 
    - docker ps / listing
    - dokcer rm / removing
    - docker create / making a new containers
    - docker run / making a new containers based on Image
    - docker start/stop
【UiPath】設定ファイルのオーバーライド

# はじめに

この投稿は、RPA ツールの UiPath のフロー実装例 の記事です。

この投稿は、UiPathのコミュニティ「UiPath Friends」が企画する「**UiPathブログ発信チャレンジ2021サマー**」の 12日目の投稿になります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427?s=20

# 設定ファイルのオーバーライドとは？

オーバーライド＝「上書き」という意味です。

UiPathでは `設定ファイルをExcelで用意し、処理の最初で値を読み込む` という実装が多いですが、今回はその読み込んだ値を **上書き** して動作させる方法について書きます。簡単に言うと

```
- A）設定ファイル.xlsx　　　　　　：正規の設定ファイル
- B）設定ファイル.override.xlsx　：ローカル実行用の設定ファイル。ファイルがなければ無視
```

という2つのファイルを読み取って、**マージ（※）した設定を使用する**というものです。
　※ AとBで同じ項目名があればBの値で上書きします

この実装には、以下のメリットがあります。

```
　1）開発が楽になる
　　　　Local実行用の設定は「.override.xlsx」に書けば良い
　2）リリース作業が楽になる
　　　　リリース（パブリッシュ）時に設定ファイルを差し替えなくて良い（特にARの場合）
　3）リリース事故が減る
　　　 「本番用」の設定ファイルを誤って修正する事がない
```

デメリットは下記があげられます。

```
　1）仕組みがわからないと混乱する
　2）「本番用」の設定ファイルの修正を忘れてしまうことがある
```

以下で「実装例」で紹介します。

---
参考）システム開発では、この「overrideパターン」を利用した実装があります。異なる環境向けファイルを用意し、上書きマージすることで環境差異を吸収します。
dockerで言えば「docker-compose.override.yml」という「上書き専用ファイル」を読み込む仕様があります。

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

---

# 実装例

以下は、設定ファイルのオーバーライドをする際の実装例です。ReFrameworkで言えば「InitAllSettings.xaml」の処理にあたります。
処理の前半は設定ファイルを読み込み、後半で上書きファイルで内容を上書きしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/7a9e74b0-8578-d44c-1a51-1c5edf4ed4ca.png)

注意点・コメント

```
1）「上書きファイルにしか無い項目」は無視しています。
　　　これは「予期せぬ事故（上書きファイルにだけ項目を追加してしまった）」を防ぐためです。

2）上書きファイルの置き場所は「デスクトップ」にしています。
　　　敢えて「パブリッシュ時に同梱されない場所」を指定し、管理しやすくしています。
```

内容を確認しやすいように、xaml形式に切り出したものを用意しました。

https://github.com/miyag/UiPath.ReusableCode/blob/master/ReadAndOverrideConfig/ReadAndOverrideConfig.xaml

# 終わりに

いかがでしたでしょうか。実装例として役立てば幸いです。

この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。